更新计费失败状态,新增销售价和产品价未匹配的错误信息,调整相关代码逻辑以支持新的状态处理。

This commit is contained in:
wuweihua
2026-10-27 15:24:16 +08:00
parent 0ba975656b
commit 4d4065b9e9
14 changed files with 189 additions and 68 deletions
@@ -420,8 +420,9 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
boolean productExcludedBySetProducts = false;
boolean attemptedPriceMatch = false;
boolean anyZoneRequired = false;
// Highest specificity among soft-failable misses: WEIGHT(3) > COUNTRY(2) > PRODUCT(1).
int missCode = 0;
// Sales miss: WEIGHT(3) > COUNTRY(2) > PRODUCT(1). Catalog miss: 25 > 24 > 23.
int salesMissCode = 0;
int catalogMissCode = 0;
// Match version by exact bill datetime (effective_time / expire_time), not end-of-day.
Date asOf = bizDate != null ? bizDate : new Date();
for (PrcCustomerPriceSet bind : binds)
@@ -467,7 +468,7 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
if (anyProducts != null && !anyProducts.isEmpty())
{
productExcludedBySetProducts = true;
missCode = Math.max(missCode, BillBillingFailStatus.PRODUCT.getCode());
salesMissCode = Math.max(salesMissCode, BillBillingFailStatus.PRODUCT.getCode());
continue;
}
}
@@ -497,23 +498,26 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
productCode, productName, cc, cn, zone.zoneCode, weight, bizDate);
if (hit != null)
{
// Billing requires product catalog price (产品价); package hit alone is not enough.
if (request instanceof TmsPriceBillRequest && !hasProductCatalogPrice(catalog))
{
missCode = Math.max(missCode,
diagnoseCatalogMiss(productCode, cc, cn, zone.zoneCode, bizDate));
continue;
}
// Temporarily skip product-catalog (产品价) soft-fail; sales package hit is enough.
// if (request instanceof TmsPriceBillRequest && !hasProductCatalogPrice(catalog))
// {
// catalogMissCode = Math.max(catalogMissCode,
// diagnoseCatalogMiss(productCode, cc, cn, zone.zoneCode, bizDate));
// continue;
// }
stampRequestMeta(request, hit);
return hit;
}
missCode = Math.max(missCode, diagnoseFixedMiss(version.getPsvId(), productCode, cc, cn, zone.zoneCode));
salesMissCode = Math.max(salesMissCode,
diagnoseFixedMiss(version.getPsvId(), productCode, cc, cn, zone.zoneCode));
}
else if (TYPE_DISCOUNT.equals(setType))
{
// DISCOUNT still needs catalog as base rate; do not soft-fail as 产品价未匹配 for now.
if (!hasProductCatalogPrice(catalog))
{
missCode = Math.max(missCode, diagnoseCatalogMiss(productCode, cc, cn, zone.zoneCode, bizDate));
// catalogMissCode = Math.max(catalogMissCode,
// diagnoseCatalogMiss(productCode, cc, cn, zone.zoneCode, bizDate));
continue;
}
TmsPriceQuoteResult hit = tryDiscount(bind, set, version, catalog, productCode, productName, weight, bizDate);
@@ -523,7 +527,7 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
return hit;
}
// Discount detail missing for product (or invalid discount) after catalog hit.
missCode = Math.max(missCode, BillBillingFailStatus.PRODUCT.getCode());
salesMissCode = Math.max(salesMissCode, BillBillingFailStatus.PRODUCT.getCode());
}
}
@@ -536,8 +540,10 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
}
if (!attemptedPriceMatch && productExcludedBySetProducts)
{
missCode = Math.max(missCode, BillBillingFailStatus.PRODUCT.getCode());
salesMissCode = Math.max(salesMissCode, BillBillingFailStatus.PRODUCT.getCode());
}
// Prefer product-catalog miss when present (sales may already have hit).
int missCode = catalogMissCode > 0 ? catalogMissCode : salesMissCode;
if (request instanceof TmsPriceBillRequest && BillBillingFailStatus.isFail(Integer.valueOf(missCode)))
{
return buildBillingMissResult(request, productCode, productName, countryCode, countryName,
@@ -591,27 +597,27 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
}
/**
* Diagnose catalog miss for DISCOUNT base price.
* Diagnose product-catalog (产品价) miss: product absent -> 23; country/zone -> 24; else weight -> 25.
*/
private int diagnoseCatalogMiss(String productCode, String countryCode, String countryName,
String zoneCode, Date bizDate)
{
if (StringUtils.isEmpty(productCode))
{
return BillBillingFailStatus.PRODUCT.getCode();
return BillBillingFailStatus.CATALOG_PRODUCT.getCode();
}
int byProduct = productCountryMapper.countByProduct(productCode, bizDate);
if (byProduct <= 0)
{
return BillBillingFailStatus.PRODUCT.getCode();
return BillBillingFailStatus.CATALOG_PRODUCT.getCode();
}
int byCountry = productCountryMapper.countByProductCountryZone(
productCode, countryCode, countryName, zoneCode, bizDate);
if (byCountry <= 0)
{
return BillBillingFailStatus.COUNTRY.getCode();
return BillBillingFailStatus.CATALOG_COUNTRY.getCode();
}
return BillBillingFailStatus.WEIGHT.getCode();
return BillBillingFailStatus.CATALOG_WEIGHT.getCode();
}
/**
@@ -675,6 +681,18 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
{
return MessageUtils.message("price.bill.billingFail.weight");
}
if (missCode == BillBillingFailStatus.CATALOG_PRODUCT.getCode())
{
return MessageUtils.message("price.bill.billingFail.catalogProduct");
}
if (missCode == BillBillingFailStatus.CATALOG_COUNTRY.getCode())
{
return MessageUtils.message("price.bill.billingFail.catalogCountry");
}
if (missCode == BillBillingFailStatus.CATALOG_WEIGHT.getCode())
{
return MessageUtils.message("price.bill.billingFail.catalogWeight");
}
return MessageUtils.message("price.bill.packagePriceNotHit");
}
@@ -239,9 +239,12 @@ public final class OrderBillExportSupport
switch (status.intValue())
{
case 0: return "计费成功";
case 1: return "未匹配产品";
case 2: return "未匹配国家";
case 3: return "未匹配重量段";
case 1: return "销售价未匹配产品";
case 2: return "销售价未匹配国家";
case 3: return "销售价未匹配重量段";
case 23: return "产品价未匹配产品";
case 24: return "产品价未匹配国家";
case 25: return "产品价未匹配重量段";
case 4: return "未绑定套餐";
case 5: return "无生效套餐版本";
case 6: return "已生成应收账单";