增加代码检测,和映射
This commit is contained in:
+277
@@ -0,0 +1,277 @@
|
||||
package com.bms.price.domain.vo;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Order-source product vs customer package comparison result.
|
||||
*/
|
||||
public class TabOrderProductCheckResult implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private long orderTotal;
|
||||
private int scannedOrders;
|
||||
private int distinctOrderProducts;
|
||||
private int packageProductCount;
|
||||
private int matchedCount;
|
||||
private int missingCount;
|
||||
private String asOfTime;
|
||||
private boolean truncated;
|
||||
private List<PackageProductRow> packageProducts = new ArrayList<PackageProductRow>();
|
||||
private List<OrderProductRow> orderProducts = new ArrayList<OrderProductRow>();
|
||||
private List<OrderProductRow> missingProducts = new ArrayList<OrderProductRow>();
|
||||
|
||||
public long getOrderTotal()
|
||||
{
|
||||
return orderTotal;
|
||||
}
|
||||
|
||||
public void setOrderTotal(long orderTotal)
|
||||
{
|
||||
this.orderTotal = orderTotal;
|
||||
}
|
||||
|
||||
public int getScannedOrders()
|
||||
{
|
||||
return scannedOrders;
|
||||
}
|
||||
|
||||
public void setScannedOrders(int scannedOrders)
|
||||
{
|
||||
this.scannedOrders = scannedOrders;
|
||||
}
|
||||
|
||||
public int getDistinctOrderProducts()
|
||||
{
|
||||
return distinctOrderProducts;
|
||||
}
|
||||
|
||||
public void setDistinctOrderProducts(int distinctOrderProducts)
|
||||
{
|
||||
this.distinctOrderProducts = distinctOrderProducts;
|
||||
}
|
||||
|
||||
public int getPackageProductCount()
|
||||
{
|
||||
return packageProductCount;
|
||||
}
|
||||
|
||||
public void setPackageProductCount(int packageProductCount)
|
||||
{
|
||||
this.packageProductCount = packageProductCount;
|
||||
}
|
||||
|
||||
public int getMatchedCount()
|
||||
{
|
||||
return matchedCount;
|
||||
}
|
||||
|
||||
public void setMatchedCount(int matchedCount)
|
||||
{
|
||||
this.matchedCount = matchedCount;
|
||||
}
|
||||
|
||||
public int getMissingCount()
|
||||
{
|
||||
return missingCount;
|
||||
}
|
||||
|
||||
public void setMissingCount(int missingCount)
|
||||
{
|
||||
this.missingCount = missingCount;
|
||||
}
|
||||
|
||||
public String getAsOfTime()
|
||||
{
|
||||
return asOfTime;
|
||||
}
|
||||
|
||||
public void setAsOfTime(String asOfTime)
|
||||
{
|
||||
this.asOfTime = asOfTime;
|
||||
}
|
||||
|
||||
public boolean isTruncated()
|
||||
{
|
||||
return truncated;
|
||||
}
|
||||
|
||||
public void setTruncated(boolean truncated)
|
||||
{
|
||||
this.truncated = truncated;
|
||||
}
|
||||
|
||||
public List<PackageProductRow> getPackageProducts()
|
||||
{
|
||||
return packageProducts;
|
||||
}
|
||||
|
||||
public void setPackageProducts(List<PackageProductRow> packageProducts)
|
||||
{
|
||||
this.packageProducts = packageProducts;
|
||||
}
|
||||
|
||||
public List<OrderProductRow> getOrderProducts()
|
||||
{
|
||||
return orderProducts;
|
||||
}
|
||||
|
||||
public void setOrderProducts(List<OrderProductRow> orderProducts)
|
||||
{
|
||||
this.orderProducts = orderProducts;
|
||||
}
|
||||
|
||||
public List<OrderProductRow> getMissingProducts()
|
||||
{
|
||||
return missingProducts;
|
||||
}
|
||||
|
||||
public void setMissingProducts(List<OrderProductRow> missingProducts)
|
||||
{
|
||||
this.missingProducts = missingProducts;
|
||||
}
|
||||
|
||||
public static class PackageProductRow implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String customerCode;
|
||||
private String productCode;
|
||||
private String productName;
|
||||
|
||||
public String getCustomerCode()
|
||||
{
|
||||
return customerCode;
|
||||
}
|
||||
|
||||
public void setCustomerCode(String customerCode)
|
||||
{
|
||||
this.customerCode = customerCode;
|
||||
}
|
||||
|
||||
public String getProductCode()
|
||||
{
|
||||
return productCode;
|
||||
}
|
||||
|
||||
public void setProductCode(String productCode)
|
||||
{
|
||||
this.productCode = productCode;
|
||||
}
|
||||
|
||||
public String getProductName()
|
||||
{
|
||||
return productName;
|
||||
}
|
||||
|
||||
public void setProductName(String productName)
|
||||
{
|
||||
this.productName = productName;
|
||||
}
|
||||
}
|
||||
|
||||
public static class OrderProductRow implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String customerCode;
|
||||
private String upstreamCode;
|
||||
private String productName;
|
||||
private String mappedCode;
|
||||
private boolean inPackage;
|
||||
private boolean mappedInPackage;
|
||||
private boolean covered;
|
||||
private int orderCount;
|
||||
private List<String> sampleOrderIds = new ArrayList<String>();
|
||||
|
||||
public String getCustomerCode()
|
||||
{
|
||||
return customerCode;
|
||||
}
|
||||
|
||||
public void setCustomerCode(String customerCode)
|
||||
{
|
||||
this.customerCode = customerCode;
|
||||
}
|
||||
|
||||
public String getUpstreamCode()
|
||||
{
|
||||
return upstreamCode;
|
||||
}
|
||||
|
||||
public void setUpstreamCode(String upstreamCode)
|
||||
{
|
||||
this.upstreamCode = upstreamCode;
|
||||
}
|
||||
|
||||
public String getProductName()
|
||||
{
|
||||
return productName;
|
||||
}
|
||||
|
||||
public void setProductName(String productName)
|
||||
{
|
||||
this.productName = productName;
|
||||
}
|
||||
|
||||
public String getMappedCode()
|
||||
{
|
||||
return mappedCode;
|
||||
}
|
||||
|
||||
public void setMappedCode(String mappedCode)
|
||||
{
|
||||
this.mappedCode = mappedCode;
|
||||
}
|
||||
|
||||
public boolean isInPackage()
|
||||
{
|
||||
return inPackage;
|
||||
}
|
||||
|
||||
public void setInPackage(boolean inPackage)
|
||||
{
|
||||
this.inPackage = inPackage;
|
||||
}
|
||||
|
||||
public boolean isMappedInPackage()
|
||||
{
|
||||
return mappedInPackage;
|
||||
}
|
||||
|
||||
public void setMappedInPackage(boolean mappedInPackage)
|
||||
{
|
||||
this.mappedInPackage = mappedInPackage;
|
||||
}
|
||||
|
||||
public boolean isCovered()
|
||||
{
|
||||
return covered;
|
||||
}
|
||||
|
||||
public void setCovered(boolean covered)
|
||||
{
|
||||
this.covered = covered;
|
||||
}
|
||||
|
||||
public int getOrderCount()
|
||||
{
|
||||
return orderCount;
|
||||
}
|
||||
|
||||
public void setOrderCount(int orderCount)
|
||||
{
|
||||
this.orderCount = orderCount;
|
||||
}
|
||||
|
||||
public List<String> getSampleOrderIds()
|
||||
{
|
||||
return sampleOrderIds;
|
||||
}
|
||||
|
||||
public void setSampleOrderIds(List<String> sampleOrderIds)
|
||||
{
|
||||
this.sampleOrderIds = sampleOrderIds;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,4 +27,9 @@ public interface OracleUpstreamOrderMapper
|
||||
@Param("query") TabOrderMonitorQuery query,
|
||||
@Param("startRow") long startRow,
|
||||
@Param("endRow") long endRow);
|
||||
|
||||
/** Distinct product codes for product-vs-package check (grouped, no pagination). */
|
||||
List<Map<String, Object>> selectTabOrderProductCodes(
|
||||
@Param("orderTable") String orderTable,
|
||||
@Param("query") TabOrderMonitorQuery query);
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ public class OracleOrderBillMapper
|
||||
{
|
||||
product = defaultProductCode;
|
||||
}
|
||||
// Keep upstream product code; package miss then maps via product_code_mapping in doQuote.
|
||||
req.setProductCode(product);
|
||||
req.setCountryCode(firstStr(row, "COUNTRY"));
|
||||
String countryName = firstStr(row, "COUNTRY_NAME", "COUNTRY_EINGTH_NAME", "COUNTRY");
|
||||
|
||||
@@ -55,6 +55,32 @@ public class TabOrderMonitorService
|
||||
}
|
||||
}
|
||||
|
||||
@DataSource(DataSourceType.SLAVE)
|
||||
public List<Map<String, Object>> selectDistinctProductCodes(TabOrderMonitorQuery query)
|
||||
{
|
||||
validate(query);
|
||||
String table = resolveTable();
|
||||
try
|
||||
{
|
||||
PageHelper.clearPage();
|
||||
long t0 = System.currentTimeMillis();
|
||||
List<Map<String, Object>> rows = oracleUpstreamOrderMapper.selectTabOrderProductCodes(table, query);
|
||||
log.info("oracle tab_order product codes customerSize={} begin={} end={} groups={} costMs={}",
|
||||
query.getCustomerCodes() == null ? 0 : query.getCustomerCodes().size(),
|
||||
query.getBeginTime(), query.getEndTime(),
|
||||
rows == null ? 0 : rows.size(), System.currentTimeMillis() - t0);
|
||||
return rows == null ? Collections.emptyList() : rows;
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
throw new ServiceException("Oracle TAB_ORDER product codes failed: " + e.getMessage());
|
||||
}
|
||||
finally
|
||||
{
|
||||
PageHelper.clearPage();
|
||||
}
|
||||
}
|
||||
|
||||
@DataSource(DataSourceType.SLAVE)
|
||||
public List<TabOrderMonitorVo> selectPage(TabOrderMonitorQuery query, int pageNum, int pageSize)
|
||||
{
|
||||
|
||||
+284
@@ -0,0 +1,284 @@
|
||||
package com.bms.price.oracle;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.bms.common.utils.StringUtils;
|
||||
import com.bms.price.domain.PrcPriceSetProduct;
|
||||
import com.bms.price.domain.vo.TabOrderMonitorQuery;
|
||||
import com.bms.price.domain.vo.TabOrderProductCheckResult;
|
||||
import com.bms.price.domain.vo.TabOrderProductCheckResult.OrderProductRow;
|
||||
import com.bms.price.domain.vo.TabOrderProductCheckResult.PackageProductRow;
|
||||
import com.bms.price.service.ITmsPriceQuoteService;
|
||||
import com.bms.system.service.IBmsProductCodeMappingService;
|
||||
|
||||
/**
|
||||
* Compare distinct TAB_ORDER product codes against customer package products.
|
||||
*/
|
||||
@Service
|
||||
public class TabOrderProductCheckService
|
||||
{
|
||||
@Autowired
|
||||
private TabOrderMonitorService tabOrderMonitorService;
|
||||
|
||||
@Autowired
|
||||
private ITmsPriceQuoteService tmsPriceQuoteService;
|
||||
|
||||
@Autowired
|
||||
private IBmsProductCodeMappingService productCodeMappingService;
|
||||
|
||||
public TabOrderProductCheckResult check(TabOrderMonitorQuery query)
|
||||
{
|
||||
Date asOf = resolveAsOf(query);
|
||||
TabOrderProductCheckResult result = new TabOrderProductCheckResult();
|
||||
result.setAsOfTime(formatAsOf(asOf));
|
||||
result.setTruncated(false);
|
||||
|
||||
List<Map<String, Object>> groups = tabOrderMonitorService.selectDistinctProductCodes(query);
|
||||
if (groups == null || groups.isEmpty())
|
||||
{
|
||||
result.setOrderTotal(0L);
|
||||
result.setScannedOrders(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
long orderTotal = 0L;
|
||||
Set<String> customerCodes = new HashSet<String>();
|
||||
List<OrderProductRow> orderProducts = new ArrayList<OrderProductRow>();
|
||||
List<OrderProductRow> missingProducts = new ArrayList<OrderProductRow>();
|
||||
|
||||
for (Map<String, Object> g : groups)
|
||||
{
|
||||
String customerCode = trim(str(g, "CUSTOMER_CODE"));
|
||||
String productCode = trim(str(g, "PRODUCT_CODE"));
|
||||
if (StringUtils.isEmpty(customerCode) || StringUtils.isEmpty(productCode))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
customerCodes.add(customerCode);
|
||||
orderTotal += longValue(g, "ORDER_COUNT");
|
||||
}
|
||||
|
||||
Map<String, Set<String>> packageCodeByCustomer = new HashMap<String, Set<String>>();
|
||||
List<PackageProductRow> packageRows = new ArrayList<PackageProductRow>();
|
||||
for (String customerCode : customerCodes)
|
||||
{
|
||||
List<PrcPriceSetProduct> products = tmsPriceQuoteService.listAllBoundPackageProducts(customerCode, asOf);
|
||||
Set<String> codes = new HashSet<String>();
|
||||
if (products != null)
|
||||
{
|
||||
for (PrcPriceSetProduct p : products)
|
||||
{
|
||||
if (p == null || StringUtils.isEmpty(p.getProductCode()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String code = p.getProductCode().trim();
|
||||
String upper = code.toUpperCase(Locale.ROOT);
|
||||
if (!codes.add(upper))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
PackageProductRow pr = new PackageProductRow();
|
||||
pr.setCustomerCode(customerCode);
|
||||
pr.setProductCode(code);
|
||||
pr.setProductName(trim(p.getProductName()));
|
||||
packageRows.add(pr);
|
||||
}
|
||||
}
|
||||
packageCodeByCustomer.put(customerCode, codes);
|
||||
}
|
||||
packageRows.sort(Comparator
|
||||
.comparing(PackageProductRow::getCustomerCode, nullSafe())
|
||||
.thenComparing(PackageProductRow::getProductCode, nullSafe()));
|
||||
|
||||
int matched = 0;
|
||||
for (Map<String, Object> g : groups)
|
||||
{
|
||||
String customerCode = trim(str(g, "CUSTOMER_CODE"));
|
||||
String productCode = trim(str(g, "PRODUCT_CODE"));
|
||||
if (StringUtils.isEmpty(customerCode) || StringUtils.isEmpty(productCode))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Set<String> pkg = packageCodeByCustomer.get(customerCode);
|
||||
if (pkg == null)
|
||||
{
|
||||
pkg = Collections.emptySet();
|
||||
}
|
||||
boolean inPackage = pkg.contains(productCode.toUpperCase(Locale.ROOT));
|
||||
String mappedCode = resolveMappedIfDifferent(productCode);
|
||||
boolean mappedInPackage = false;
|
||||
if (StringUtils.isNotEmpty(mappedCode))
|
||||
{
|
||||
mappedInPackage = pkg.contains(mappedCode.toUpperCase(Locale.ROOT));
|
||||
}
|
||||
boolean covered = inPackage || mappedInPackage;
|
||||
|
||||
OrderProductRow row = new OrderProductRow();
|
||||
row.setCustomerCode(customerCode);
|
||||
row.setUpstreamCode(productCode);
|
||||
row.setProductName(trim(str(g, "PRODUCT_NAME")));
|
||||
row.setMappedCode(mappedCode);
|
||||
row.setInPackage(inPackage);
|
||||
row.setMappedInPackage(mappedInPackage);
|
||||
row.setCovered(covered);
|
||||
row.setOrderCount((int) Math.min(Integer.MAX_VALUE, longValue(g, "ORDER_COUNT")));
|
||||
orderProducts.add(row);
|
||||
if (covered)
|
||||
{
|
||||
matched++;
|
||||
}
|
||||
else
|
||||
{
|
||||
missingProducts.add(row);
|
||||
}
|
||||
}
|
||||
|
||||
orderProducts.sort(Comparator
|
||||
.comparing(OrderProductRow::isCovered)
|
||||
.thenComparing(OrderProductRow::getCustomerCode, nullSafe())
|
||||
.thenComparing(OrderProductRow::getUpstreamCode, nullSafe()));
|
||||
missingProducts.sort(Comparator
|
||||
.comparing(OrderProductRow::getCustomerCode, nullSafe())
|
||||
.thenComparing(OrderProductRow::getUpstreamCode, nullSafe()));
|
||||
|
||||
result.setOrderTotal(orderTotal);
|
||||
result.setScannedOrders((int) Math.min(Integer.MAX_VALUE, orderTotal));
|
||||
result.setDistinctOrderProducts(orderProducts.size());
|
||||
result.setPackageProductCount(packageRows.size());
|
||||
result.setMatchedCount(matched);
|
||||
result.setMissingCount(missingProducts.size());
|
||||
result.setPackageProducts(packageRows);
|
||||
result.setOrderProducts(orderProducts);
|
||||
result.setMissingProducts(missingProducts);
|
||||
return result;
|
||||
}
|
||||
|
||||
private String resolveMappedIfDifferent(String upstreamCode)
|
||||
{
|
||||
if (productCodeMappingService == null || StringUtils.isEmpty(upstreamCode))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String mapped = productCodeMappingService.resolveBmsProductCode(upstreamCode);
|
||||
if (StringUtils.isEmpty(mapped) || mapped.equalsIgnoreCase(upstreamCode.trim()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return mapped.trim();
|
||||
}
|
||||
|
||||
private static Date resolveAsOf(TabOrderMonitorQuery query)
|
||||
{
|
||||
String raw = query == null ? null : query.getEndTime();
|
||||
if (StringUtils.isEmpty(raw) && query != null)
|
||||
{
|
||||
raw = query.getBeginTime();
|
||||
}
|
||||
Date parsed = parseDateTime(raw);
|
||||
return parsed != null ? parsed : new Date();
|
||||
}
|
||||
|
||||
private static Date parseDateTime(String raw)
|
||||
{
|
||||
if (StringUtils.isEmpty(raw))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String s = raw.trim().replace('T', ' ');
|
||||
try
|
||||
{
|
||||
if (s.length() >= 19)
|
||||
{
|
||||
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(s.substring(0, 19));
|
||||
}
|
||||
if (s.length() >= 10)
|
||||
{
|
||||
return new SimpleDateFormat("yyyy-MM-dd").parse(s.substring(0, 10));
|
||||
}
|
||||
}
|
||||
catch (ParseException ignore)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String formatAsOf(Date asOf)
|
||||
{
|
||||
if (asOf == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(asOf);
|
||||
}
|
||||
|
||||
private static String trim(String s)
|
||||
{
|
||||
return StringUtils.isEmpty(s) ? null : s.trim();
|
||||
}
|
||||
|
||||
private static Comparator<String> nullSafe()
|
||||
{
|
||||
return Comparator.nullsFirst(String.CASE_INSENSITIVE_ORDER);
|
||||
}
|
||||
|
||||
private static String str(Map<String, Object> row, String key)
|
||||
{
|
||||
Object v = value(row, key);
|
||||
return v == null ? null : String.valueOf(v).trim();
|
||||
}
|
||||
|
||||
private static long longValue(Map<String, Object> row, String key)
|
||||
{
|
||||
Object v = value(row, key);
|
||||
if (v == null)
|
||||
{
|
||||
return 0L;
|
||||
}
|
||||
if (v instanceof Number)
|
||||
{
|
||||
return ((Number) v).longValue();
|
||||
}
|
||||
try
|
||||
{
|
||||
return Long.parseLong(String.valueOf(v).trim());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
private static Object value(Map<String, Object> row, String key)
|
||||
{
|
||||
if (row == null || key == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (row.containsKey(key))
|
||||
{
|
||||
return row.get(key);
|
||||
}
|
||||
for (Map.Entry<String, Object> e : row.entrySet())
|
||||
{
|
||||
if (e.getKey() != null && e.getKey().equalsIgnoreCase(key))
|
||||
{
|
||||
return e.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -36,4 +36,11 @@ public interface ITmsPriceQuoteService
|
||||
* @param bizDate optional; default today (same as-of window as quote)
|
||||
*/
|
||||
List<PrcPriceSetProduct> listBoundPackageProducts(String customerCode, Date bizDate);
|
||||
|
||||
/**
|
||||
* Union of products from all effective bound packages (for order-source product check).
|
||||
* @param customerCode required
|
||||
* @param bizDate optional; default today
|
||||
*/
|
||||
List<PrcPriceSetProduct> listAllBoundPackageProducts(String customerCode, Date bizDate);
|
||||
}
|
||||
|
||||
+87
@@ -9,6 +9,7 @@ import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -57,6 +58,7 @@ import com.bms.price.search.EsBizLogSupport;
|
||||
import com.bms.price.search.EsLogType;
|
||||
import com.bms.price.search.IBillSearchStore;
|
||||
import com.bms.price.service.ITmsPriceQuoteService;
|
||||
import com.bms.system.service.IBmsProductCodeMappingService;
|
||||
|
||||
/**
|
||||
* Shared quote/bill calc: customer bind + package version by bizDate (version effective_time).
|
||||
@@ -103,6 +105,9 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
|
||||
@Autowired
|
||||
private BmsProductMapper productMapper;
|
||||
|
||||
@Autowired(required = false)
|
||||
private IBmsProductCodeMappingService productCodeMappingService;
|
||||
|
||||
@Autowired
|
||||
private PrcSurchargeRelMapper surchargeRelMapper;
|
||||
|
||||
@@ -261,6 +266,52 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PrcPriceSetProduct> listAllBoundPackageProducts(String customerCode, Date bizDate)
|
||||
{
|
||||
if (StringUtils.isEmpty(customerCode))
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<PrcCustomerPriceSet> binds = customerPriceSetMapper.selectEffectiveByCustomerCode(customerCode.trim());
|
||||
if (binds == null || binds.isEmpty())
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Date asOf = bizDate != null ? bizDate : new Date();
|
||||
Map<String, PrcPriceSetProduct> byCode = new LinkedHashMap<String, PrcPriceSetProduct>();
|
||||
for (PrcCustomerPriceSet bind : binds)
|
||||
{
|
||||
if (bind == null || bind.getPriceSetId() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
PrcPriceSet set = priceSetMapper.selectPrcPriceSetHeaderById(bind.getPriceSetId());
|
||||
if (set == null || !"E".equals(set.getStatus()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
List<PrcPriceSetProduct> products = loadProductsForPackage(set.getPriceSetId(), asOf);
|
||||
if (products == null || products.isEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (PrcPriceSetProduct p : products)
|
||||
{
|
||||
if (p == null || StringUtils.isEmpty(p.getProductCode()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String key = p.getProductCode().trim().toUpperCase(Locale.ROOT);
|
||||
if (!byCode.containsKey(key))
|
||||
{
|
||||
byCode.put(key, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ArrayList<PrcPriceSetProduct>(byCode.values());
|
||||
}
|
||||
|
||||
/** Prefer version active at asOf; else latest version that has set-product rows. */
|
||||
private List<PrcPriceSetProduct> loadProductsForPackage(Long priceSetId, Date asOf)
|
||||
{
|
||||
@@ -373,6 +424,25 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
|
||||
|
||||
PrcPriceSetProduct setProduct = resolveSetProduct(version.getPsvId(), productCode);
|
||||
if (setProduct == null)
|
||||
{
|
||||
// Package has no this product: try product_code_mapping (upstream -> BMS).
|
||||
String mappedCode = resolveMappedProductCode(productCode);
|
||||
if (mappedCode != null)
|
||||
{
|
||||
setProduct = resolveSetProduct(version.getPsvId(), mappedCode);
|
||||
if (setProduct != null)
|
||||
{
|
||||
productCode = mappedCode;
|
||||
request.setProductCode(mappedCode);
|
||||
String mappedName = resolveProductName(mappedCode, bizDate);
|
||||
if (StringUtils.isNotEmpty(mappedName))
|
||||
{
|
||||
productName = mappedName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (setProduct == null)
|
||||
{
|
||||
PrcPriceSetProduct probe = new PrcPriceSetProduct();
|
||||
probe.setPsvId(version.getPsvId());
|
||||
@@ -470,6 +540,23 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
|
||||
return setProductMapper.selectByPsvIdAndCode(psvId, productCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return mapped BMS product code only when mapping exists and differs from upstream code.
|
||||
*/
|
||||
private String resolveMappedProductCode(String upstreamCode)
|
||||
{
|
||||
if (productCodeMappingService == null || StringUtils.isEmpty(upstreamCode))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String mapped = productCodeMappingService.resolveBmsProductCode(upstreamCode);
|
||||
if (StringUtils.isEmpty(mapped) || mapped.equalsIgnoreCase(upstreamCode.trim()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return mapped.trim();
|
||||
}
|
||||
|
||||
private static final class ZoneResolve
|
||||
{
|
||||
private boolean required;
|
||||
|
||||
Reference in New Issue
Block a user