diff --git a/bms-back/bms-admin/src/main/resources/i18n/messages.properties b/bms-back/bms-admin/src/main/resources/i18n/messages.properties index a9d029e2..14ecda1e 100644 --- a/bms-back/bms-admin/src/main/resources/i18n/messages.properties +++ b/bms-back/bms-admin/src/main/resources/i18n/messages.properties @@ -153,9 +153,6 @@ price.quote.noCustomerPackage=客户未绑定套餐,无法试算 price.quote.noActivePackageVersion=计费日无生效套餐版本,无法试算 price.quote.quoteIdRequired=报价ID为空 price.quote.hitCustomerFixedPackageDetail=命中客户套餐固定价格明细 -price.quote.packageZonePriceNotHit=已匹配分区,但套餐版本无该分区/重量段价格 -price.quote.packagePriceNotHit=套餐版本无匹配的国家/重量段价格 -price.quote.productNotInPackage=产品不在客户套餐版本中,无法试算 # receivable bill price.bill.orderNoRequired=订单号为空 @@ -166,9 +163,6 @@ price.bill.alreadyInArBill=订单{0}已生成应收账单,作废后方可重 price.bill.bizDateRequired=业务日期为空 price.bill.noCustomerPackage=客户未绑定套餐,无法计费 price.bill.noActivePackageVersion=计费日无生效套餐版本,无法计费 -price.bill.packageZonePriceNotHit=已匹配分区,但套餐版本无该分区/重量段价格 -price.bill.packagePriceNotHit=套餐版本无匹配的国家/重量段价格 -price.bill.productNotInPackage=产品不在客户套餐版本中,无法计费 price.bill.fee.scIdRequired=附加费不能为空 price.bill.fee.surchargeNotFound=附加费配置不存在或已停用 price.bill.fee.notFound=费用明细不存在 diff --git a/bms-back/bms-system/src/main/java/com/bms/price/domain/vo/TmsPriceQuoteResult.java b/bms-back/bms-system/src/main/java/com/bms/price/domain/vo/TmsPriceQuoteResult.java index 6ac2818d..3b0cde48 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/domain/vo/TmsPriceQuoteResult.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/domain/vo/TmsPriceQuoteResult.java @@ -8,7 +8,7 @@ import lombok.Data; /** * TMS freight quote response. - * matchSource: PACKAGE_FIXED / PACKAGE_DISCOUNT + * matchSource: PACKAGE_FIXED / PACKAGE_DISCOUNT / PRODUCT_DEFAULT */ @Data public class TmsPriceQuoteResult implements Serializable diff --git a/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcPriceSetDetailMapper.java b/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcPriceSetDetailMapper.java index 015a4edb..808dd931 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcPriceSetDetailMapper.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcPriceSetDetailMapper.java @@ -54,10 +54,7 @@ public interface PrcPriceSetDetailMapper @Param("priceSetId") Long priceSetId, @Param("psvId") Long psvId); - /** - * FIXED match on package snapshot: product + country + zone + weight band. - * Does not depend on live product_country.detail_id. - */ + /** FIXED: product + country + zone + productCountryId / weight; optional psvId scopes to version */ public PrcPriceSetDetail selectFixedMatch( @Param("priceSetId") Long priceSetId, @Param("psvId") Long psvId, @@ -65,14 +62,8 @@ public interface PrcPriceSetDetailMapper @Param("countryCode") String countryCode, @Param("countryName") String countryName, @Param("zoneCode") String zoneCode, - @Param("weight") BigDecimal weight); - - /** Count version details that have zone for product + country (postcode gate). */ - public int countZonedByPsvProductCountry( - @Param("psvId") Long psvId, - @Param("productCode") String productCode, - @Param("countryCode") String countryCode, - @Param("countryName") String countryName); + @Param("productCountryId") Long productCountryId, + @Param("weightLabel") String weightLabel); /** DISCOUNT by product; optional psvId scopes to version */ public PrcPriceSetDetail selectDiscountMatch( diff --git a/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcQuoteMapper.java b/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcQuoteMapper.java index 22d81c03..2fea3249 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcQuoteMapper.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcQuoteMapper.java @@ -16,8 +16,6 @@ public interface PrcQuoteMapper public int insertPrcQuote(PrcQuote quote); - public int deletePrcQuoteById(String quoteId); - public int updateQuoteAmounts(@Param("quoteId") String quoteId, @Param("surchargeAmount") BigDecimal surchargeAmount, @Param("payableTotal") BigDecimal payableTotal, diff --git a/bms-back/bms-system/src/main/java/com/bms/price/service/IPrcOrderBillService.java b/bms-back/bms-system/src/main/java/com/bms/price/service/IPrcOrderBillService.java index e7cfaaff..74b74860 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/service/IPrcOrderBillService.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/service/IPrcOrderBillService.java @@ -9,7 +9,7 @@ import com.bms.price.domain.vo.TmsPriceBillRequest; import com.bms.price.domain.vo.TmsPriceQuoteResult; import com.bms.price.domain.vo.TmsOrderBillStatusResult; -/** Order billing: persist prc_order_bill + prc_income_bill/+fee. Payable (prc_pay_bill/+fee) skipped for now. */ +/** 订单计费:落库 prc_order_bill + prc_income_bill/+fee + prc_pay_bill/+fee。 */ public interface IPrcOrderBillService { TmsPriceQuoteResult bill(TmsPriceBillRequest request); diff --git a/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcOrderBillServiceImpl.java b/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcOrderBillServiceImpl.java index 941092d2..1de8a0c0 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcOrderBillServiceImpl.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcOrderBillServiceImpl.java @@ -890,8 +890,7 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService { orderBillMapper.updatePrcOrderBill(bill); incomeBillFeeMapper.deleteByBillId(bill.getBillId()); - // Payable not in scope yet: skip prc_pay_bill_fee cleanup/write. - // payBillFeeMapper.deleteByBillId(bill.getBillId()); + payBillFeeMapper.deleteByBillId(bill.getBillId()); } PrcIncomeBill incomeBill = persistIncomeBill(bill, result); List fees = toFeeRows(bill.getBillId(), @@ -901,14 +900,13 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService incomeBillFeeMapper.insertBatch(fees); } orderBillMapper.refreshArBillStatusByBillIds(Arrays.asList(bill.getBillId())); - // Payable not in scope yet: do not write prc_pay_bill / prc_pay_bill_fee. - // PrcPayBill payBill = persistPayBill(bill, result); - // List payFees = toPayFeeRows(bill.getBillId(), - // payBill == null ? null : payBill.getPayBillId(), result); - // if (!payFees.isEmpty()) - // { - // payBillFeeMapper.insertBatch(payFees); - // } + PrcPayBill payBill = persistPayBill(bill, result); + List payFees = toPayFeeRows(bill.getBillId(), + payBill == null ? null : payBill.getPayBillId(), result); + if (!payFees.isEmpty()) + { + payBillFeeMapper.insertBatch(payFees); + } String requestJson = toRequestJson(request); persistBillExt(bill, request.getUpstreamRow()); result.setRequestJson(requestJson); diff --git a/bms-back/bms-system/src/main/java/com/bms/price/service/impl/TmsPriceQuoteServiceImpl.java b/bms-back/bms-system/src/main/java/com/bms/price/service/impl/TmsPriceQuoteServiceImpl.java index e2b5e1c2..a21c181b 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/service/impl/TmsPriceQuoteServiceImpl.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/service/impl/TmsPriceQuoteServiceImpl.java @@ -60,9 +60,7 @@ import com.bms.price.service.ITmsPriceQuoteService; /** * Shared quote/bill calc: customer bind + package version by bizDate (version effective_time). * Bind pr_begindate/pr_enddate is not used for billing time gate. - * Sales price comes from package snapshot only (FIXED detail / DISCOUNT on catalog base). - * No bind / no active version / package miss: quote and bill both fail hard (no PRODUCT_DEFAULT). - * product_country is only for product_amount/cost and DISCOUNT freight base. + * No bind / no active version at bill time: quote and bill both fail hard (no PRODUCT_DEFAULT). * * @author bms */ @@ -73,6 +71,7 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService private static final String TYPE_DISCOUNT = "DISCOUNT"; private static final String SRC_FIXED = "PACKAGE_FIXED"; private static final String SRC_DISCOUNT = "PACKAGE_DISCOUNT"; + private static final String SRC_DEFAULT = "PRODUCT_DEFAULT"; private static final String FEE_BASIC = "BASIC_FREIGHT"; private static final String FEE_REG = "REGISTRATION_FEE"; @@ -147,27 +146,18 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService PrcQuote cached = quoteMapper.selectPrcQuoteByKey(quoteKey); if (cached != null) { - // Legacy PRODUCT_DEFAULT (or no package stamp) must be recomputed after package-snapshot pricing. - if (isStaleCachedQuote(cached)) + List fees = quoteFeeMapper.selectByQuoteId(cached.getQuoteId()); + if (!isStaleSurchargeFees(fees)) { - quoteFeeMapper.deleteByQuoteId(cached.getQuoteId()); - quoteMapper.deletePrcQuoteById(cached.getQuoteId()); - } - else - { - List fees = quoteFeeMapper.selectByQuoteId(cached.getQuoteId()); - if (!isStaleSurchargeFees(fees)) - { - return toResult(cached, fees, true); - } - TmsPriceQuoteResult refreshed = doQuote(request, bizDate); - applySurchargesAndFees(refreshed); - replaceQuoteFees(cached.getQuoteId(), refreshed); - refreshed.setQuoteId(cached.getQuoteId()); - refreshed.setFromCache(false); - billSearchStore.save(EsLogType.QUOTE, cached.getQuoteId(), toEsRequest(request), toEsResponse(refreshed)); - return refreshed; + return toResult(cached, fees, true); } + TmsPriceQuoteResult refreshed = doQuote(request, bizDate); + applySurchargesAndFees(refreshed); + replaceQuoteFees(cached.getQuoteId(), refreshed); + refreshed.setQuoteId(cached.getQuoteId()); + refreshed.setFromCache(false); + billSearchStore.save(EsLogType.QUOTE, cached.getQuoteId(), toEsRequest(request), toEsResponse(refreshed)); + return refreshed; } TmsPriceQuoteResult result = doQuote(request, bizDate); @@ -176,23 +166,6 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService return result; } - /** - * Cached quotes from pre-package-snapshot logic (PRODUCT_DEFAULT / missing package id) - * must not be reused after billing rules changed. - */ - private boolean isStaleCachedQuote(PrcQuote cached) - { - if (cached == null) - { - return true; - } - if ("PRODUCT_DEFAULT".equalsIgnoreCase(cached.getMatchSource())) - { - return true; - } - return cached.getPriceSetId() == null; - } - @Override public TmsPriceQuoteResult calculate(TmsPriceQuoteRequest request) { @@ -330,201 +303,41 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService } // Charge weight keeps 3 decimals; freight unit price keeps 2 (see buildFromRates). BigDecimal weight = request.getWeight().setScale(3, RoundingMode.HALF_UP); + String destPostcode = emptyToNull(request.getDestPostcode()); - String productName = resolveProductName(productCode, bizDate); - - List binds; - if (StringUtils.isNotEmpty(request.getCustomerCode())) + String zoneCode = null; + PrcZone resolvedZone = null; + int zonedCount = productCountryMapper.countZonedByProductCountry( + productCode, countryCode, countryName, bizDate); + if (zonedCount > 0) { - binds = customerPriceSetMapper.selectEffectiveByCustomerCode(request.getCustomerCode()); - } - else - { - binds = customerPriceSetMapper.selectEffectiveByCustomer(request.getCustomerId()); - } - if (binds == null || binds.isEmpty()) - { - String msgKey = request instanceof TmsPriceBillRequest - ? "price.bill.noCustomerPackage" - : "price.quote.noCustomerPackage"; - throw new ServiceException(MessageUtils.message(msgKey)); - } - - boolean anyActiveVersion = false; - boolean productExcludedBySetProducts = false; - boolean attemptedPriceMatch = false; - boolean anyZoneRequired = false; - Date asOf = endOfDay(bizDate); - for (PrcCustomerPriceSet bind : binds) - { - PrcPriceSet set = priceSetMapper.selectPrcPriceSetById(bind.getPriceSetId()); - if (set == null || !"E".equals(set.getStatus())) + if (StringUtils.isEmpty(destPostcode)) { - continue; + throw new ServiceException(MessageUtils.message("price.quote.postcodeRequired")); } - // Temporal gate: prc_price_set_version.effective_time / expire_time (not bind pr_begindate) - PrcPriceSetVersion version = versionMapper.selectActiveByPriceSetAt(set.getPriceSetId(), asOf); - if (version == null || version.getPsvId() == null) + String iso2 = resolveCountryIso2(productCode, countryCode, countryName); + if (StringUtils.isEmpty(iso2)) { - continue; + throw new ServiceException(MessageUtils.message("price.quote.countryRequired")); } - anyActiveVersion = true; - - PrcPriceSetProduct setProduct = resolveSetProduct(version.getPsvId(), productCode); - if (setProduct == null) + resolvedZone = zoneDetailMapper.selectZoneByCountryPostcode(iso2, normalizePostcode(destPostcode)); + if (resolvedZone == null || StringUtils.isEmpty(resolvedZone.getZoneCode())) { - PrcPriceSetProduct probe = new PrcPriceSetProduct(); - probe.setPsvId(version.getPsvId()); - List anyProducts = setProductMapper.selectPrcPriceSetProductList(probe); - if (anyProducts != null && !anyProducts.isEmpty()) - { - productExcludedBySetProducts = true; - continue; - } + throw new ServiceException(MessageUtils.message("price.quote.postcodeZoneNotFound")); } - attemptedPriceMatch = true; - if (setProduct != null && StringUtils.isNotEmpty(setProduct.getProductName())) + zoneCode = resolvedZone.getZoneCode(); + if (countryCode == null) { - productName = setProduct.getProductName(); - } - - String setType = StringUtils.isEmpty(set.getSetType()) ? TYPE_FIXED : set.getSetType(); - String cc = countryCode; - String cn = countryName; - ZoneResolve zone = resolveZone(setType, version.getPsvId(), productCode, cc, cn, destPostcode, bizDate); - if (zone.required) - { - anyZoneRequired = true; - } - if (zone.countryCode != null) - { - cc = zone.countryCode; - } - BmsProductCountry catalog = softMatchCatalog(productCode, cc, cn, zone.zoneCode, weight, bizDate, zone.zone); - - if (TYPE_FIXED.equals(setType)) - { - TmsPriceQuoteResult hit = tryFixed(bind, set, version, catalog, zone.zone, - productCode, productName, cc, cn, zone.zoneCode, weight); - if (hit != null) - { - stampRequestMeta(request, hit); - return hit; - } - } - else if (TYPE_DISCOUNT.equals(setType)) - { - if (catalog == null) - { - continue; - } - TmsPriceQuoteResult hit = tryDiscount(bind, set, version, catalog, productCode, productName, weight); - if (hit != null) - { - stampRequestMeta(request, hit); - return hit; - } + countryCode = iso2; } } - if (!anyActiveVersion) - { - String msgKey = request instanceof TmsPriceBillRequest - ? "price.bill.noActivePackageVersion" - : "price.quote.noActivePackageVersion"; - throw new ServiceException(MessageUtils.message(msgKey)); - } - if (!attemptedPriceMatch && productExcludedBySetProducts) - { - String msgKey = request instanceof TmsPriceBillRequest - ? "price.bill.productNotInPackage" - : "price.quote.productNotInPackage"; - throw new ServiceException(MessageUtils.message(msgKey)); - } - String missKey; - if (anyZoneRequired) - { - missKey = request instanceof TmsPriceBillRequest - ? "price.bill.packageZonePriceNotHit" - : "price.quote.packageZonePriceNotHit"; - } - else - { - missKey = request instanceof TmsPriceBillRequest - ? "price.bill.packagePriceNotHit" - : "price.quote.packagePriceNotHit"; - } - throw new ServiceException(MessageUtils.message(missKey)); - } - - /** - * Soft lookup of package product row; null when version has no such product. - */ - private PrcPriceSetProduct resolveSetProduct(Long psvId, String productCode) - { - if (psvId == null || StringUtils.isEmpty(productCode)) - { - return null; - } - return setProductMapper.selectByPsvIdAndCode(psvId, productCode); - } - - private static final class ZoneResolve - { - private boolean required; - private String zoneCode; - private String countryCode; - private PrcZone zone; - } - - private ZoneResolve resolveZone(String setType, Long psvId, String productCode, - String countryCode, String countryName, String destPostcode, Date bizDate) - { - ZoneResolve out = new ZoneResolve(); - int zonedCount; - if (TYPE_FIXED.equals(setType)) - { - zonedCount = detailMapper.countZonedByPsvProductCountry(psvId, productCode, countryCode, countryName); - } - else - { - zonedCount = productCountryMapper.countZonedByProductCountry( - productCode, countryCode, countryName, bizDate); - } - if (zonedCount <= 0) - { - return out; - } - out.required = true; - if (StringUtils.isEmpty(destPostcode)) - { - throw new ServiceException(MessageUtils.message("price.quote.postcodeRequired")); - } - String iso2 = resolveCountryIso2(productCode, countryCode, countryName); - if (StringUtils.isEmpty(iso2)) - { - throw new ServiceException(MessageUtils.message("price.quote.countryRequired")); - } - PrcZone resolvedZone = zoneDetailMapper.selectZoneByCountryPostcode(iso2, normalizePostcode(destPostcode)); - if (resolvedZone == null || StringUtils.isEmpty(resolvedZone.getZoneCode())) - { - throw new ServiceException(MessageUtils.message("price.quote.postcodeZoneNotFound")); - } - out.zone = resolvedZone; - out.zoneCode = resolvedZone.getZoneCode(); - out.countryCode = iso2; - return out; - } - - /** Catalog match for product_amount / DISCOUNT base; null is allowed for FIXED sales. */ - private BmsProductCountry softMatchCatalog(String productCode, String countryCode, String countryName, - String zoneCode, BigDecimal weight, Date bizDate, PrcZone resolvedZone) - { BmsProductCountry base = productCountryMapper.selectMatchByProductCountryWeight( productCode, countryCode, countryName, zoneCode, weight, bizDate); if (base == null) { - return null; + throw new ServiceException(MessageUtils.message( + zonedCount > 0 ? "price.quote.zonePriceNotHit" : "price.quote.priceNotHit")); } if (resolvedZone != null) { @@ -541,7 +354,81 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService base.setZoneName(resolvedZone.getZoneName()); } } - return base; + + String productName = resolveProductName(productCode, bizDate); + List binds; + if (StringUtils.isNotEmpty(request.getCustomerCode())) + { + binds = customerPriceSetMapper.selectEffectiveByCustomerCode(request.getCustomerCode()); + } + else + { + binds = customerPriceSetMapper.selectEffectiveByCustomer(request.getCustomerId()); + } + + boolean anyActiveVersion = false; + if (binds != null) + { + Date asOf = endOfDay(bizDate); + for (PrcCustomerPriceSet bind : binds) + { + PrcPriceSet set = priceSetMapper.selectPrcPriceSetById(bind.getPriceSetId()); + if (set == null || !"E".equals(set.getStatus())) + { + continue; + } + // Temporal gate: prc_price_set_version.effective_time / expire_time (not bind pr_begindate) + PrcPriceSetVersion version = versionMapper.selectActiveByPriceSetAt(set.getPriceSetId(), asOf); + if (version == null || version.getPsvId() == null) + { + continue; + } + anyActiveVersion = true; + String setType = StringUtils.isEmpty(set.getSetType()) ? TYPE_FIXED : set.getSetType(); + if (TYPE_FIXED.equals(setType)) + { + TmsPriceQuoteResult hit = tryFixed(bind, set, version, base, productCode, productName, weight); + if (hit != null) + { + stampRequestMeta(request, hit); + return hit; + } + } + else if (TYPE_DISCOUNT.equals(setType)) + { + TmsPriceQuoteResult hit = tryDiscount(bind, set, version, base, productCode, productName, weight); + if (hit != null) + { + stampRequestMeta(request, hit); + return hit; + } + } + } + } + + // No bind, or bind exists but no version effective at bill time. + if (binds == null || binds.isEmpty() || !anyActiveVersion) + { + String msgKey; + if (binds == null || binds.isEmpty()) + { + msgKey = request instanceof TmsPriceBillRequest + ? "price.bill.noCustomerPackage" + : "price.quote.noCustomerPackage"; + } + else + { + msgKey = request instanceof TmsPriceBillRequest + ? "price.bill.noActivePackageVersion" + : "price.quote.noActivePackageVersion"; + } + throw new ServiceException(MessageUtils.message(msgKey)); + } + + TmsPriceQuoteResult fallback = buildDefault(request.getCustomerId(), base, productCode, productName, weight, + MessageUtils.message("price.quote.noCustomerPackageOverride")); + stampRequestMeta(request, fallback); + return fallback; } private void stampRequestMeta(TmsPriceQuoteRequest request, TmsPriceQuoteResult result) @@ -689,8 +576,7 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService } private TmsPriceQuoteResult tryFixed(PrcCustomerPriceSet bind, PrcPriceSet set, PrcPriceSetVersion version, - BmsProductCountry catalog, PrcZone resolvedZone, String productCode, String productName, - String countryCode, String countryName, String zoneCode, BigDecimal weight) + BmsProductCountry base, String productCode, String productName, BigDecimal weight) { Long psvId = version.getPsvId(); int detailCount = detailMapper.countByPsvId(psvId); @@ -702,7 +588,9 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService PrcPriceSetDetail detail = detailMapper.selectFixedMatch( set.getPriceSetId(), psvId, productCode, - countryCode, countryName, zoneCode, weight); + base.getCountryCode(), base.getCountryName(), base.getZoneCode(), + base.getDetailId(), + formatWeightLabel(base.getWeightMin(), base.getWeightMax())); if (detail == null) { return null; @@ -711,10 +599,22 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService { return null; } - TmsPriceQuoteResult r = buildFromPackageDetail(SRC_FIXED, detail, catalog, resolvedZone, - productCode, productName, weight, detail.getFvValue(), null, null, detail.getFvRegistrationFee()); + TmsPriceQuoteResult r = buildFromRates(SRC_FIXED, detail.getFvValue(), null, null, + detail.getFvRegistrationFee(), base, productCode, productName, weight, detail.getRoundMode()); fillPackage(r, bind, set); stampVersion(r, version, detail.getPsdId()); + if (StringUtils.isNotEmpty(detail.getProductName())) + { + r.setProductName(detail.getProductName()); + } + if (StringUtils.isNotEmpty(detail.getWeightLabel())) + { + r.setWeightLabel(detail.getWeightLabel()); + } + if (detail.getProductCountryId() != null) + { + r.setProductCountryId(detail.getProductCountryId()); + } r.setMatchMessage(MessageUtils.message("price.quote.hitCustomerFixedPackageDetail") + " [" + (version.getVersionNo() == null ? ("psv=" + psvId) : version.getVersionNo()) + "]"); r.setCustomerId(bind.getCustomerId()); @@ -729,10 +629,9 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService BigDecimal discount = set.getDefaultDiscount(); String roundMode = null; Long psdId = null; - PrcPriceSetDetail detail = null; if (detailCount > 0) { - detail = detailMapper.selectDiscountMatch(set.getPriceSetId(), psvId, productCode); + PrcPriceSetDetail detail = detailMapper.selectDiscountMatch(set.getPriceSetId(), psvId, productCode); if (detail == null) { return null; @@ -780,105 +679,17 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService result.setPsdId(psdId); } - /** - * FIXED sales from package detail snapshot; catalog only fills product_amount / cost. - */ - private TmsPriceQuoteResult buildFromPackageDetail(String source, PrcPriceSetDetail detail, - BmsProductCountry catalog, PrcZone resolvedZone, String productCode, String productName, - BigDecimal weight, BigDecimal freightRate, BigDecimal baseFreightRate, BigDecimal discountPercent, - BigDecimal registrationFee) + private TmsPriceQuoteResult buildDefault(Long customerId, BmsProductCountry base, + String productCode, String productName, BigDecimal weight, String message) { - if (freightRate == null) + if (base.getFreightPrice() == null || base.getRegistrationFee() == null) { - throw new ServiceException(MessageUtils.message("price.quote.freightMissing3")); + throw new ServiceException(MessageUtils.message("price.quote.freightMissing2")); } - if (registrationFee == null) - { - registrationFee = BigDecimal.ZERO; - } - String roundMode = detail == null ? null : detail.getRoundMode(); - RoundingMode rm = resolveRoundingMode(roundMode); - String mode = normalizeRoundMode(roundMode); - weight = weight.setScale(3, RoundingMode.HALF_UP); - freightRate = freightRate.setScale(2, rm); - if (baseFreightRate != null) - { - baseFreightRate = baseFreightRate.setScale(2, rm); - } - registrationFee = registrationFee.setScale(2, rm); - BigDecimal freightAmount = freightRate.multiply(weight).setScale(2, rm); - BigDecimal payable = freightAmount.add(registrationFee).setScale(2, rm); - - TmsPriceQuoteResult r = new TmsPriceQuoteResult(); - r.setMatchSource(source); - r.setProductCode(productCode); - if (detail != null && StringUtils.isNotEmpty(detail.getProductName())) - { - r.setProductName(detail.getProductName()); - } - else - { - r.setProductName(productName); - } - if (detail != null) - { - r.setCountryCode(detail.getCountryCode()); - r.setCountryName(detail.getCountryName()); - r.setZoneId(detail.getZoneId()); - r.setZoneCode(detail.getZoneCode()); - r.setZoneName(detail.getZoneName()); - r.setWeightMin(detail.getWeightMin()); - r.setWeightMax(detail.getWeightMax()); - if (StringUtils.isNotEmpty(detail.getWeightLabel())) - { - r.setWeightLabel(detail.getWeightLabel()); - } - else - { - r.setWeightLabel(formatWeightLabel(detail.getWeightMin(), detail.getWeightMax())); - } - r.setProductCountryId(detail.getProductCountryId()); - r.setEffectiveDate(detail.getEffectiveDate()); - } - if (resolvedZone != null) - { - if (r.getZoneId() == null) - { - r.setZoneId(resolvedZone.getZoneId()); - } - if (StringUtils.isEmpty(r.getZoneCode())) - { - r.setZoneCode(resolvedZone.getZoneCode()); - } - if (StringUtils.isEmpty(r.getZoneName())) - { - r.setZoneName(resolvedZone.getZoneName()); - } - } - if (catalog != null) - { - if (r.getProductCountryId() == null) - { - r.setProductCountryId(catalog.getDetailId()); - } - if (r.getEffectiveDate() == null) - { - r.setEffectiveDate(catalog.getEffectiveDate()); - } - } - r.setWeight(weight); - r.setChargeWeight(weight); - r.setFreightRate(freightRate); - r.setBaseFreightRate(baseFreightRate); - r.setDiscountPercent(discountPercent); - r.setRegistrationFee(registrationFee); - r.setFreightAmount(freightAmount); - r.setSurchargeAmount(BigDecimal.ZERO); - r.setPayableTotal(payable); - r.setCurrency("CNY"); - r.setRoundMode(mode); - r.setFromCache(false); - fillProductAmountAndPay(r, catalog, weight, rm, mode); + TmsPriceQuoteResult r = buildFromRates(SRC_DEFAULT, base.getFreightPrice(), null, null, + base.getRegistrationFee(), base, productCode, productName, weight, null); + r.setCustomerId(customerId); + r.setMatchMessage(message); return r; } @@ -1016,29 +827,22 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService { return matched; } - boolean packageHit = SRC_FIXED.equals(result.getMatchSource()) || SRC_DISCOUNT.equals(result.getMatchSource()); - // Package sales use version surcharge snapshot only (empty snapshot = no surcharge). - if (packageHit) + if (result.getPsdId() != null) { - if (result.getPsdId() == null) - { - return matched; - } List snaps = versionSurchargeMapper.selectByPsdIds(Collections.singletonList(result.getPsdId())); - if (snaps == null || snaps.isEmpty()) + if (snaps != null && !snaps.isEmpty()) { + for (PrcPriceSetVersionSurcharge snap : snaps) + { + PrcSurchargeRel rel = toRelFromVersionSnap(snap); + if (surchargeApplies(rel, result)) + { + matched.add(rel); + } + } return matched; } - for (PrcPriceSetVersionSurcharge snap : snaps) - { - PrcSurchargeRel rel = toRelFromVersionSnap(snap); - if (surchargeApplies(rel, result)) - { - matched.add(rel); - } - } - return matched; } PrcSurchargeRel query = new PrcSurchargeRel(); query.setProductCode(result.getProductCode()); diff --git a/bms-back/bms-system/src/main/resources/mapper/price/PrcPriceSetDetailMapper.xml b/bms-back/bms-system/src/main/resources/mapper/price/PrcPriceSetDetailMapper.xml index 9cc331ab..6457acc9 100644 --- a/bms-back/bms-system/src/main/resources/mapper/price/PrcPriceSetDetailMapper.xml +++ b/bms-back/bms-system/src/main/resources/mapper/price/PrcPriceSetDetailMapper.xml @@ -328,52 +328,39 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and psv_id = #{psvId} and product_code = #{productCode} - - - and upper(ifnull(country_code,'')) = upper(#{countryCode}) - - - and country_name = #{countryName} - - - and 1 = 0 - - - - - and upper(ifnull(zone_code,'')) = upper(#{zoneCode}) - - - and (zone_code is null or zone_code = '') - - - and weight_min <= #{weight} - and weight_max >= #{weight} + and ( + + product_country_id = #{productCountryId} + or + + ( + + + upper(ifnull(country_code,'')) = upper(#{countryCode}) + + + country_name = #{countryName} + + + 1 = 0 + + + + and (zone_code is null or upper(zone_code) = upper(#{zoneCode})) + + + and (weight_label is null or weight_label = #{weightLabel} or weight_label like concat('%', #{weightLabel}, '%')) + + ) + ) order by - weight_min asc, + case when #{productCountryId} is not null and product_country_id = #{productCountryId} then 0 else 1 end, + case when #{zoneCode} is not null and upper(ifnull(zone_code,'')) = upper(#{zoneCode}) then 0 else 1 end, + case when zone_code is null then 1 else 0 end, psd_id asc limit 1 - -