增加产品价编辑
This commit is contained in:
@@ -116,6 +116,17 @@ public interface BmsProductCountryMapper
|
||||
@Param("weight") BigDecimal weight,
|
||||
@Param("bizDate") Date bizDate);
|
||||
|
||||
/**
|
||||
* Lowest PRODUCT catalog weight band for product/country/zone (ignore weight).
|
||||
* Used when charge weight is below the minimum band.
|
||||
*/
|
||||
public BmsProductCountry selectMinBandByProductCountry(
|
||||
@Param("productCode") String productCode,
|
||||
@Param("countryCode") String countryCode,
|
||||
@Param("countryName") String countryName,
|
||||
@Param("zoneCode") String zoneCode,
|
||||
@Param("bizDate") Date bizDate);
|
||||
|
||||
/** Count product-country rows that have a zone for this product+country+bizDate */
|
||||
public int countZonedByProductCountry(
|
||||
@Param("productCode") String productCode,
|
||||
|
||||
@@ -71,6 +71,17 @@ public interface PrcPriceSetDetailMapper
|
||||
@Param("zoneCode") String zoneCode,
|
||||
@Param("weight") BigDecimal weight);
|
||||
|
||||
/**
|
||||
* Lowest FIXED weight band for product/country/zone (ignore weight).
|
||||
* Used when charge weight is below the minimum band.
|
||||
*/
|
||||
public PrcPriceSetDetail selectFixedMinBand(
|
||||
@Param("psvId") Long psvId,
|
||||
@Param("productCode") String productCode,
|
||||
@Param("countryCode") String countryCode,
|
||||
@Param("countryName") String countryName,
|
||||
@Param("zoneCode") String zoneCode);
|
||||
|
||||
public int countZonedByPsvProductCountry(
|
||||
@Param("psvId") Long psvId,
|
||||
@Param("productCode") String productCode,
|
||||
|
||||
+75
-6
@@ -520,13 +520,28 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
|
||||
else if (TYPE_DISCOUNT.equals(setType))
|
||||
{
|
||||
// DISCOUNT still needs catalog as base rate; do not soft-fail as 产品价未匹配 for now.
|
||||
if (!hasProductCatalogPrice(catalog))
|
||||
BmsProductCountry discCatalog = catalog;
|
||||
BigDecimal discWeight = weight;
|
||||
if (!hasProductCatalogPrice(discCatalog))
|
||||
{
|
||||
// Below min catalog band: snap charge weight to lowest band min.
|
||||
BigDecimal snapped = snapWeightToCatalogMinBand(
|
||||
productCode, cc, cn, zone.zoneCode, weight, bizDate);
|
||||
if (snapped != null)
|
||||
{
|
||||
discWeight = snapped;
|
||||
discCatalog = softMatchCatalog(
|
||||
productCode, cc, cn, zone.zoneCode, discWeight, bizDate, zone.zone);
|
||||
}
|
||||
}
|
||||
if (!hasProductCatalogPrice(discCatalog))
|
||||
{
|
||||
// catalogMissCode = Math.max(catalogMissCode,
|
||||
// diagnoseCatalogMiss(productCode, cc, cn, zone.zoneCode, bizDate));
|
||||
continue;
|
||||
}
|
||||
TmsPriceQuoteResult hit = tryDiscount(bind, set, version, catalog, productCode, productName, weight, bizDate);
|
||||
TmsPriceQuoteResult hit = tryDiscount(bind, set, version, discCatalog,
|
||||
productCode, productName, discWeight, bizDate);
|
||||
if (hit != null)
|
||||
{
|
||||
stampRequestMeta(request, hit);
|
||||
@@ -971,6 +986,21 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
|
||||
PrcPriceSetDetail detail = detailMapper.selectFixedMatch(
|
||||
psvId, productCode,
|
||||
countryCode, countryName, zoneCode, weight);
|
||||
BigDecimal billWeight = weight;
|
||||
boolean snappedToMinBand = false;
|
||||
// Miss: if charge weight is below the lowest band, bill at that band's weight_min.
|
||||
if (detail == null)
|
||||
{
|
||||
PrcPriceSetDetail minBand = detailMapper.selectFixedMinBand(
|
||||
psvId, productCode, countryCode, countryName, zoneCode);
|
||||
if (minBand != null && minBand.getWeightMin() != null
|
||||
&& weight.compareTo(minBand.getWeightMin()) < 0)
|
||||
{
|
||||
detail = minBand;
|
||||
billWeight = minBand.getWeightMin().setScale(3, RoundingMode.HALF_UP);
|
||||
snappedToMinBand = true;
|
||||
}
|
||||
}
|
||||
if (detail == null)
|
||||
{
|
||||
return null;
|
||||
@@ -979,16 +1009,55 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
|
||||
{
|
||||
return null;
|
||||
}
|
||||
TmsPriceQuoteResult r = buildFromPackageDetail(SRC_FIXED, detail, catalog, resolvedZone,
|
||||
productCode, productName, weight, detail.getFvValue(), null, null, detail.getFvRegistrationFee(), bizDate);
|
||||
BmsProductCountry useCatalog = catalog;
|
||||
if (snappedToMinBand)
|
||||
{
|
||||
BmsProductCountry rematched = softMatchCatalog(
|
||||
productCode, countryCode, countryName, zoneCode, billWeight, bizDate, resolvedZone);
|
||||
if (hasProductCatalogPrice(rematched))
|
||||
{
|
||||
useCatalog = rematched;
|
||||
}
|
||||
}
|
||||
TmsPriceQuoteResult r = buildFromPackageDetail(SRC_FIXED, detail, useCatalog, resolvedZone,
|
||||
productCode, productName, billWeight, detail.getFvValue(), null, null, detail.getFvRegistrationFee(), bizDate);
|
||||
fillPackage(r, bind, set);
|
||||
stampVersion(r, version, detail.getPsdId());
|
||||
r.setMatchMessage(MessageUtils.message("price.quote.hitCustomerFixedPackageDetail")
|
||||
+ " [" + (version.getVersionNo() == null ? ("psv=" + psvId) : version.getVersionNo()) + "]");
|
||||
String verLabel = version.getVersionNo() == null ? ("psv=" + psvId) : version.getVersionNo();
|
||||
String msg = MessageUtils.message("price.quote.hitCustomerFixedPackageDetail") + " [" + verLabel + "]";
|
||||
if (snappedToMinBand)
|
||||
{
|
||||
msg = msg + "; chargeWeight raised to min band " + billWeight.toPlainString();
|
||||
}
|
||||
r.setMatchMessage(msg);
|
||||
r.setCustomerId(bind.getCustomerId());
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* When weight misses catalog bands but is below the lowest band, return that band's weight_min.
|
||||
* Otherwise null (caller keeps original miss).
|
||||
*/
|
||||
private BigDecimal snapWeightToCatalogMinBand(String productCode, String countryCode, String countryName,
|
||||
String zoneCode, BigDecimal weight, Date bizDate)
|
||||
{
|
||||
if (weight == null || StringUtils.isEmpty(productCode))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
BmsProductCountry minBand = productCountryMapper.selectMinBandByProductCountry(
|
||||
productCode, countryCode, countryName, zoneCode, bizDate);
|
||||
if (minBand == null || minBand.getWeightMin() == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (weight.compareTo(minBand.getWeightMin()) < 0)
|
||||
{
|
||||
return minBand.getWeightMin().setScale(3, RoundingMode.HALF_UP);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private TmsPriceQuoteResult tryDiscount(PrcCustomerPriceSet bind, PrcPriceSet set, PrcPriceSetVersion version,
|
||||
BmsProductCountry base, String productCode, String productName, BigDecimal weight, Date bizDate)
|
||||
{
|
||||
|
||||
+4
-4
@@ -446,8 +446,7 @@ public class CatalogVersionSupport
|
||||
}
|
||||
|
||||
/**
|
||||
* Catalog version that can accept preview apply / Excel attach / edit.
|
||||
* Same as sales force-edit: draft, pending, and effect are writable.
|
||||
* Catalog force-edit: draft, pending, effect, and expired are writable.
|
||||
*/
|
||||
public PrcPriceSetVersion requireEditableCatalogVersion(Long psvId, String priceType)
|
||||
{
|
||||
@@ -467,9 +466,10 @@ public class CatalogVersionSupport
|
||||
}
|
||||
if (!STATUS_DRAFT.equals(ver.getStatus())
|
||||
&& !STATUS_PENDING.equals(ver.getStatus())
|
||||
&& !STATUS_EFFECT.equals(ver.getStatus()))
|
||||
&& !STATUS_EFFECT.equals(ver.getStatus())
|
||||
&& !STATUS_EXPIRED.equals(ver.getStatus()))
|
||||
{
|
||||
throw new ServiceException("仅草稿、待生效或已生效版本可以编辑");
|
||||
throw new ServiceException("仅草稿、待生效、已生效或已失效版本可以编辑");
|
||||
}
|
||||
return ver;
|
||||
}
|
||||
|
||||
@@ -357,6 +357,36 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
<select id="selectMinBandByProductCountry" resultMap="BmsProductCountryResult">
|
||||
<include refid="selectVo"/>
|
||||
where c.price_type = 'PRODUCT'
|
||||
and ifnull(c.is_del, '0') = '0'
|
||||
and c.product_code = #{productCode}
|
||||
and c.weight_min is not null
|
||||
<include refid="catalogBizWindow"/>
|
||||
<choose>
|
||||
<when test="countryCode != null and countryCode != ''">
|
||||
and upper(c.country_code) = upper(#{countryCode})
|
||||
</when>
|
||||
<when test="countryName != null and countryName != ''">
|
||||
and c.country_name = #{countryName}
|
||||
</when>
|
||||
<otherwise>
|
||||
and 1 = 0
|
||||
</otherwise>
|
||||
</choose>
|
||||
<choose>
|
||||
<when test="zoneCode != null and zoneCode != ''">
|
||||
and upper(ifnull(c.zone_code,'')) = upper(#{zoneCode})
|
||||
</when>
|
||||
<otherwise>
|
||||
and (c.zone_code is null or c.zone_code = '')
|
||||
</otherwise>
|
||||
</choose>
|
||||
order by v.effective_time desc, c.weight_min asc, c.psd_id asc
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
<select id="countZonedByProductCountry" resultType="int">
|
||||
select count(1)
|
||||
from prc_price_set_detail c
|
||||
|
||||
@@ -490,6 +490,35 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
<select id="selectFixedMinBand" resultMap="PrcPriceSetDetailResult">
|
||||
<include refid="selectPrcPriceSetDetailVo"/>
|
||||
where psv_id = #{psvId}
|
||||
and ifnull(is_del, '0') = '0'
|
||||
and product_code = #{productCode}
|
||||
and weight_min is not null
|
||||
<choose>
|
||||
<when test="countryCode != null and countryCode != ''">
|
||||
and upper(ifnull(country_code,'')) = upper(#{countryCode})
|
||||
</when>
|
||||
<when test="countryName != null and countryName != ''">
|
||||
and country_name = #{countryName}
|
||||
</when>
|
||||
<otherwise>
|
||||
and 1 = 0
|
||||
</otherwise>
|
||||
</choose>
|
||||
<choose>
|
||||
<when test="zoneCode != null and zoneCode != ''">
|
||||
and upper(ifnull(zone_code,'')) = upper(#{zoneCode})
|
||||
</when>
|
||||
<otherwise>
|
||||
and (zone_code is null or zone_code = '')
|
||||
</otherwise>
|
||||
</choose>
|
||||
order by weight_min asc, psd_id asc
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
<select id="countZonedByPsvProductCountry" resultType="int">
|
||||
select count(1)
|
||||
from prc_price_set_detail
|
||||
|
||||
@@ -81,6 +81,7 @@ import {
|
||||
isDraftVersion,
|
||||
isPendingVersion,
|
||||
isEffectVersion,
|
||||
isExpiredVersion,
|
||||
isPriceEditableVersion
|
||||
} from '@/views/price/set/utils/priceSet'
|
||||
import { checkPermi } from '@/utils/permission'
|
||||
@@ -152,8 +153,8 @@ const filteredVersions = computed(() => {
|
||||
|
||||
function showEditButton(row) {
|
||||
if (!checkPermi([props.editPerm])) return false
|
||||
// Align with sales force-edit: draft / pending / effect can edit
|
||||
return isPriceEditableVersion(row) || isEffectVersion(row)
|
||||
// draft / pending / effect / expired can edit
|
||||
return isPriceEditableVersion(row) || isEffectVersion(row) || isExpiredVersion(row)
|
||||
}
|
||||
|
||||
function isRemoving(row) {
|
||||
|
||||
@@ -51,7 +51,7 @@ import { listProduct, listProductVersions, activateProductVersion, deleteProduct
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const alertTitle = "按版本管理产品价(与套餐版本一致)。点击版本可查看产品与明细;待生效(含草稿)可编辑、启动或硬删;已生效可软删(上一版自动恢复生效并清空失效时间)。建价请点「新建产品价格」。"
|
||||
const alertTitle = "按版本管理产品价(与套餐版本一致)。点击版本可查看产品与明细;待生效(含草稿)可编辑、启动或硬删;已生效、已失效可编辑;已生效可软删(上一版自动恢复生效并清空失效时间)。建价请点「新建产品价格」。"
|
||||
const verTitle = '产品价版本'
|
||||
const createLabel = '新建产品价格'
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ import { listRedline, listRedlineVersions, activateRedlineVersion, deleteRedline
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const alertTitle = "按版本管理红线价(与套餐版本一致)。点击版本可查看产品与明细;待生效(含草稿)可编辑、启动或硬删;已生效可软删(上一版自动恢复生效并清空失效时间)。建价请点「新建红线价」。"
|
||||
const alertTitle = "按版本管理红线价(与套餐版本一致)。点击版本可查看产品与明细;待生效(含草稿)可编辑、启动或硬删;已生效、已失效可编辑;已生效可软删(上一版自动恢复生效并清空失效时间)。建价请点「新建红线价」。"
|
||||
const verTitle = '红线价版本'
|
||||
const createLabel = '新建红线价'
|
||||
|
||||
|
||||
@@ -105,6 +105,10 @@ export function isEffectVersion(row) {
|
||||
return !!row && String(row.status) === VER_STATUS.EFFECT
|
||||
}
|
||||
|
||||
export function isExpiredVersion(row) {
|
||||
return !!row && String(row.status) === VER_STATUS.EXPIRED
|
||||
}
|
||||
|
||||
/** Draft or pending: may continue editing price details */
|
||||
export function isPriceEditableVersion(row) {
|
||||
return isDraftVersion(row) || isPendingVersion(row)
|
||||
|
||||
Reference in New Issue
Block a user