增加产品价编辑

This commit is contained in:
wuweihua
2026-11-02 09:00:38 +08:00
parent d185995dc7
commit 9d4dbdcbe6
10 changed files with 169 additions and 14 deletions
@@ -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,
@@ -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)
{
@@ -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;
}