package biz.policy.rule;
|
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.util.Collection;
|
import java.util.HashMap;
|
|
import biz.policy.OrderLineType;
|
import biz.policy.price.PackagePolicy;
|
import biz.policy.price.PolicyBucket;
|
import foundation.dao.DataPackage;
|
import foundation.dao.DataSource;
|
import foundation.dao.DataWriter;
|
import foundation.data.entity.Entity;
|
import foundation.data.entity.EntitySet;
|
import foundation.data.entity.Filter;
|
import foundation.data.entity.OrderBy;
|
import foundation.data.object.DataObject;
|
import foundation.data.object.EntitySaver;
|
import foundation.persist.NamedSQL;
|
import foundation.util.Util;
|
|
public class OrderCalculator {
|
|
public static String Field_Header_BU_ID = "bu_id";
|
public static String Field_Header_Amt_List = "amt_list";
|
public static String Field_Header_Amt_AfterOnsite = "amt_after_onsite";
|
public static String Field_Header_Amt_Onsite= "amt_onsite";
|
public static String Field_Header_Amt_Rebate = "amt_rebate";
|
public static String Field_Header_Amt_Net = "amt_net";
|
|
public static String Field_Header_Amt_OnsiteQty= "amt_onsite_qty";
|
public static String Field_Header_Amt_OnsitePrice = "amt_onsite_price";
|
public static String Field_Header_Amt_OncePrice = "amt_once_price";
|
public static String Field_Header_Amt_OnceQty = "amt_once_qty";
|
|
public static String Field_Header_Qty_Total= "qty_total";
|
public static String Field_Header_Qty_List = "qty_list";
|
public static String Field_Header_Qty_Discount = "qty_discount";
|
public static String Field_Header_Qty_Onsite = "qty_onsite";
|
public static String Field_Header_Qty_Rebate = "qty_rebate";
|
public static String Field_Header_Discount_Id = "discount_policy_id";
|
public static String Field_Header_Discount_Code = "discount_policy_code";
|
public static String Field_Header_Discount_Name = "discount_policy_name";
|
public static String Field_Header_Whole_Rate = "whole_rate";
|
|
public static String Field_Detail_TypeCode = "type_code";
|
public static String Field_Detail_Is_Discount = "is_discount";
|
public static String Field_Detail_Price_List = "price_list";
|
public static String Field_Detail_Price_Working = "price";
|
public static String Field_Detail_SKU_ID = "sku_id";
|
public static String Field_Detail_Product_ID = "product_id";
|
public static String Field_Detail_Qty = "qty";
|
public static String Field_Detail_Qty_List = "qty_list";
|
public static String Field_Detail_Qty_Discount = "qty_discount";
|
public static String Field_Detail_Qty_Onsite = "qty_onsite";
|
public static String Field_Detail_Qty_Rebate = "qty_rebate";
|
public static String Field_Detail_Qty_Price = "qty_price";
|
public static String Field_Detail_Amt_List = "amt_List";
|
public static String Field_Detail_Amt_AfterDiscount = "amt_after_discount";
|
public static String Field_Detail_Amt_Discount = "amt_discount";
|
public static String Field_Detail_Amt_Rebate = "amt_rebate";
|
public static String Field_Detail_Amt_Net = "amt_net";
|
public static String Field_Detail_Amt_List_Close = "amt_list_close";
|
public static String Field_Detail_Amt_Net_Close = "amt_net_close";
|
public static String Field_Detail_Amt_Rebate_Close = "amt_rebate_close";
|
public static String Field_Detail_Qty_Close = "qty_close";
|
public static String Field_Detail_Qty_Rebate_Close = "qty_rebate_close";
|
public static String Field_Detail_RecordId = "record_id";
|
public static String Field_Detail_RecordDetailId = "record_detail_id";
|
public static String Field_Detail_Amt_Formula = "amt_formula";
|
|
public static String Field_RebateDetail_Amt = "amt";
|
|
public static BigDecimal Rate_Ceiling = BigDecimal.valueOf(1000000);
|
|
protected DataWriter dataWriter;
|
protected Entity master;
|
protected EntitySet details;
|
protected EntitySet rebates;
|
protected EntitySet qtyRebates;
|
protected boolean calculated;
|
|
// totalAmt(折扣前金额) = netAmt(折扣后金额) + onsiteAmt(即时折扣额) + rebateAmt(买赠池金额)
|
private BigDecimal listAmt;
|
private BigDecimal afterOnsiteAmt;
|
private BigDecimal onsiteAmt;
|
private BigDecimal rebateAmt;
|
private BigDecimal netAmt;
|
|
// totalQty(总数量) = standardQty(共价数量) + priceQty(优惠价数量) + rebateQty(买赠数量) + onsiteQty(即时买赠数量 + 一次性买赠数量)
|
private BigDecimal totalQty;
|
private BigDecimal listQty;
|
private BigDecimal discountQty;
|
private BigDecimal priceQty;
|
private BigDecimal onsiteQty;
|
private BigDecimal rebateQty;
|
|
// discountAmt = onsiteQtyAmt(即时买赠数量金额) + onsitePriceAmt (即时优惠价格金额) + oncePriceAmt (一次性优惠价格金额)
|
private BigDecimal onsiteQtyAmt;
|
private BigDecimal onsitePriceAmt;
|
private BigDecimal oncePriceAmt;
|
private OnsiteRecords onsiteRecords;
|
private OnsiteRecords onceRecords;
|
|
// packageQty
|
private HashMap<String, PackagePolicy> packages;
|
// wholeRate
|
private BigDecimal wholeRate;
|
|
public OrderCalculator(DataWriter dataWriter) {
|
this.dataWriter = dataWriter;
|
this.calculated = false;
|
this.onsiteRecords = new OnsiteRecords();
|
this.onceRecords = new OnsiteRecords();
|
}
|
|
public void exec() {
|
if (calculated) {
|
return;
|
}
|
|
synchronized (this) {
|
if (calculated) {
|
return;
|
}
|
|
//1. 计算明细行数量、单价、金额、套包
|
doCalculateQtyAndAmt();
|
|
//2. 整单折扣
|
calculatorDiscountLevel();
|
|
//3. 计算折扣池(票折)总金额
|
doCalculateHeaderRebate();
|
|
//4. 计算折扣池(票折)行金额
|
doCalculateLineRebate();
|
|
//4. 将计算结果设置到订单头上(不更新数据库)
|
setHeaderValues();
|
|
//5.
|
calculated = true;
|
}
|
}
|
|
private void doCalculateQtyAndAmt() {
|
//1. 初始化汇总数据
|
listAmt = BigDecimal.ZERO;
|
afterOnsiteAmt = BigDecimal.ZERO;
|
onsiteAmt = BigDecimal.ZERO;
|
netAmt = BigDecimal.ZERO;
|
|
onsiteQtyAmt = BigDecimal.ZERO;
|
onsitePriceAmt = BigDecimal.ZERO;
|
oncePriceAmt = BigDecimal.ZERO;
|
|
totalQty = BigDecimal.ZERO;
|
listQty = BigDecimal.ZERO;
|
discountQty = BigDecimal.ZERO;
|
priceQty = BigDecimal.ZERO;
|
onsiteQty = BigDecimal.ZERO;
|
rebateQty = BigDecimal.ZERO;
|
packages = new HashMap<String, PackagePolicy>();
|
|
if (details == null || details.isEmpty()) {
|
return;
|
}
|
|
//2. 遍历行计算数量、金额
|
String customerId = master.getString("customer_id");
|
|
for (Entity entity: details) {
|
doCalculateOneLineQtyAndAmt(customerId, entity);
|
}
|
|
//3. 计算即时优惠金额
|
onsiteAmt = listAmt.subtract(afterOnsiteAmt);
|
|
//4. 计算折扣数量
|
discountQty = onsiteQty.add(rebateQty);
|
|
//5. 计算套包数量
|
calculatePackagesQty();
|
|
}
|
|
private void doCalculateOneLineQtyAndAmt(String customerId, Entity entity) {
|
StringBuffer amtFormulaBuffer = new StringBuffer("(");
|
OrderLineType lineType = OrderLineType.parse(entity.getString(Field_Detail_TypeCode));
|
boolean isDiscount = entity.getBoolean(Field_Detail_Is_Discount, false);
|
|
//1. 重新获取价格
|
String skuId = entity.getString(Field_Detail_SKU_ID);
|
String productId = entity.getString(Field_Detail_Product_ID);
|
String buId = master.getString(Field_Header_BU_ID);
|
String productKey = buId + "-" + productId + "-" + skuId;
|
|
BigDecimal listPrice = getListPrice(customerId, productKey);
|
if (OrderLineType.OncePrice == lineType) {
|
listPrice = entity.getBigDecimal(Field_Detail_Price_Working, BigDecimal.ZERO);
|
}
|
else if (OrderLineType.Package == lineType) {
|
listPrice = getListPrice(null, skuId);
|
}
|
|
// BigDecimal listPrice = entity.getBigDecimal(Field_Detail_Price_List, BigDecimal.ZERO);
|
|
//2. 单价与数量
|
BigDecimal lineQty = entity.getBigDecimal(Field_Detail_Qty, BigDecimal.ZERO);
|
BigDecimal discountQty = entity.getBigDecimal("qty_discount", BigDecimal.ZERO);
|
BigDecimal workingPrice = entity.getBigDecimal(Field_Detail_Price_Working, BigDecimal.ZERO);
|
|
String packageId = entity.getString(Field_Detail_RecordId);
|
String packageDetailId = entity.getString(Field_Detail_RecordDetailId);
|
PackagePolicy policy = loadToProductPackage(packageId, packageDetailId, discountQty.intValue());
|
|
if (!Util.isEmpty(packageDetailId) && policy == null) {
|
lineType = OrderLineType.ListPrice;
|
entity.set(Field_Detail_TypeCode, OrderLineType.ListPrice);
|
entity.set(Field_Detail_RecordId, "");
|
entity.set(Field_Detail_RecordDetailId, "");
|
}
|
|
BigDecimal lineListAmt = listPrice.multiply(lineQty);
|
String defaultFormula = lineQty + "[行数量]*" + listPrice + "[公价]";
|
entity.set(Field_Detail_Price_List, listPrice);
|
entity.set(Field_Detail_Amt_List, lineListAmt);
|
|
//3. 根据类型进行汇总
|
if (OrderLineType.ListPrice == lineType) {
|
entity.set(Field_Detail_Amt_AfterDiscount, lineListAmt);
|
entity.set(Field_Detail_Amt_Discount, BigDecimal.ZERO);
|
entity.set(Field_Detail_Amt_Rebate, BigDecimal.ZERO);
|
entity.set(Field_Detail_Amt_Net, lineListAmt);
|
|
entity.set(Field_Detail_Qty_List, lineQty);
|
entity.set(Field_Detail_Qty_Discount, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_Onsite, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_Rebate, BigDecimal.ZERO);
|
|
listQty = listQty.add(lineQty);
|
afterOnsiteAmt = afterOnsiteAmt.add(lineListAmt);
|
amtFormulaBuffer.append(defaultFormula);
|
}
|
else if (OrderLineType.OnsiteQty == lineType) {
|
entity.set(Field_Detail_Amt_AfterDiscount, BigDecimal.ZERO);
|
entity.set(Field_Detail_Amt_Discount, lineListAmt);
|
entity.set(Field_Detail_Amt_Rebate, BigDecimal.ZERO);
|
entity.set(Field_Detail_Amt_Net, BigDecimal.ZERO);
|
|
entity.set(Field_Detail_Qty_List, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_Discount, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_Onsite, lineQty);
|
entity.set(Field_Detail_Qty_Rebate, BigDecimal.ZERO);
|
|
onsiteQtyAmt = onsiteQtyAmt.add(lineListAmt);
|
onsiteQty = onsiteQty.add(lineQty);
|
amtFormulaBuffer.append(lineQty + "[行数量]*0[即时买赠]");
|
}
|
else if (OrderLineType.OnceQty == lineType) {
|
entity.set(Field_Detail_Amt_AfterDiscount, BigDecimal.ZERO);
|
entity.set(Field_Detail_Amt_Discount, lineListAmt);
|
entity.set(Field_Detail_Amt_Rebate, BigDecimal.ZERO);
|
entity.set(Field_Detail_Amt_Net, BigDecimal.ZERO);
|
|
entity.set(Field_Detail_Qty_List, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_Discount, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_Onsite, lineQty);
|
entity.set(Field_Detail_Qty_Rebate, BigDecimal.ZERO);
|
|
onsiteQtyAmt = onsiteQtyAmt.add(lineListAmt);
|
onsiteQty = onsiteQty.add(lineQty);
|
amtFormulaBuffer.append(lineQty + "[行数量]*0[一次性买赠]");
|
}
|
else if (OrderLineType.RebateQty == lineType) {
|
entity.set(Field_Detail_Amt_AfterDiscount, BigDecimal.ZERO);
|
entity.set(Field_Detail_Amt_Discount, BigDecimal.ZERO);
|
entity.set(Field_Detail_Amt_Rebate, BigDecimal.ZERO);
|
entity.set(Field_Detail_Amt_Net, BigDecimal.ZERO);
|
|
entity.set(Field_Detail_Qty_List, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_Discount, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_Onsite, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_Rebate, lineQty);
|
|
rebateQty = rebateQty.add(lineQty);
|
qtyRebates.append(entity);
|
amtFormulaBuffer.append(lineQty + "[行数量]*0[买赠奖励]");
|
}
|
else if (OrderLineType.Package == lineType) {
|
workingPrice = getListPrice(policy, customerId, productKey);
|
BigDecimal lineAfterDiscountAmt = workingPrice.multiply(lineQty);
|
BigDecimal lineDiscountAmt = lineListAmt.subtract(lineAfterDiscountAmt);
|
|
entity.set(Field_Detail_Price_Working, workingPrice);
|
entity.set(Field_Detail_Amt_List, lineListAmt);
|
|
entity.set(Field_Detail_Amt_AfterDiscount, lineAfterDiscountAmt);
|
entity.set(Field_Detail_Amt_Discount, lineDiscountAmt);
|
entity.set(Field_Detail_Amt_Rebate, BigDecimal.ZERO);
|
entity.set(Field_Detail_Amt_Net, lineAfterDiscountAmt);
|
|
entity.set(Field_Detail_Qty_List, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_Discount, lineQty);
|
entity.set(Field_Detail_Qty_Price, discountQty);
|
entity.set(Field_Detail_Qty_Onsite, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_Rebate, BigDecimal.ZERO);
|
|
onsitePriceAmt = onsitePriceAmt.add(lineDiscountAmt);
|
afterOnsiteAmt = afterOnsiteAmt.add(lineAfterDiscountAmt);
|
priceQty = priceQty.add(lineQty);
|
amtFormulaBuffer.append(lineQty + "[行数量]*" + workingPrice + "[套包价格]");
|
}
|
else if (OrderLineType.RebateAmt == lineType) {
|
|
}
|
else if (OrderLineType.Customize == lineType) {
|
listPrice = entity.getBigDecimal(Field_Detail_Price_Working, BigDecimal.ZERO);
|
lineListAmt = listPrice.multiply(lineQty);
|
|
entity.set(Field_Detail_Price_List, listPrice);
|
entity.set(Field_Detail_Amt_List, lineListAmt);
|
|
entity.set(Field_Detail_Amt_AfterDiscount, lineListAmt);
|
entity.set(Field_Detail_Amt_Discount, BigDecimal.ZERO);
|
entity.set(Field_Detail_Amt_Rebate, BigDecimal.ZERO);
|
entity.set(Field_Detail_Amt_Net, lineListAmt);
|
|
entity.set(Field_Detail_Qty_List, lineQty);
|
entity.set(Field_Detail_Qty_Discount, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_Onsite, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_Rebate, BigDecimal.ZERO);
|
|
listQty = listQty.add(lineQty);
|
afterOnsiteAmt = afterOnsiteAmt.add(lineListAmt);
|
amtFormulaBuffer.append(lineQty + "[行数量]*" + workingPrice + "[自定义价格]");
|
}
|
else if (OrderLineType.OnsitePrice == lineType) {
|
BigDecimal lineAfterDiscountAmt = workingPrice.multiply(lineQty);
|
BigDecimal lineDiscountAmt = lineListAmt.subtract(lineAfterDiscountAmt);
|
|
if (isDiscount) {
|
onsitePriceAmt = onsitePriceAmt.add(lineDiscountAmt);
|
priceQty = priceQty.add(lineQty);
|
}
|
else {
|
entity.set(Field_Detail_Amt_List, lineListAmt);
|
listQty = listQty.add(lineQty);
|
}
|
|
entity.set(Field_Detail_Amt_Net, lineAfterDiscountAmt);
|
entity.set(Field_Detail_Amt_AfterDiscount, lineAfterDiscountAmt);
|
entity.set(Field_Detail_Amt_Discount, lineDiscountAmt);
|
entity.set(Field_Detail_Amt_Rebate, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_List, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_Discount, lineQty);
|
entity.set(Field_Detail_Qty_Price, discountQty);
|
entity.set(Field_Detail_Qty_Onsite, BigDecimal.ZERO);
|
entity.set(Field_Detail_Qty_Rebate, BigDecimal.ZERO);
|
|
discountQty = discountQty.add(lineQty);
|
afterOnsiteAmt = afterOnsiteAmt.add(lineAfterDiscountAmt);
|
amtFormulaBuffer.append(lineQty + "[行数量]*" + workingPrice + "[" + lineType.getName() + "]");
|
}
|
|
totalQty = totalQty.add(lineQty);
|
listAmt = listAmt.add(lineListAmt);
|
onsiteAmt = listAmt.subtract(afterOnsiteAmt);
|
|
amtFormulaBuffer.append(")");
|
entity.set(Field_Detail_Amt_Formula, amtFormulaBuffer.toString());
|
}
|
|
private void calculatePackagesQty() {
|
Collection<PackagePolicy> packagePolicyList = packages.values();
|
for (PackagePolicy onePackage : packagePolicyList) {
|
onePackage.calculateQty();
|
}
|
}
|
|
private PackagePolicy loadToProductPackage(String packageId, String packageDetailId, int qty) {
|
// 检查当前套包是否存在
|
PolicyBucket policyBucket = PolicyBucket.getInstance();
|
PackagePolicy packagePolicy = policyBucket.getPackagePolicy(packageId);
|
if (packagePolicy == null) {
|
return null;
|
}
|
|
PackagePolicy policy = packages.get(packageId);
|
|
if (policy == null) {
|
policy = new PackagePolicy(packageId);
|
}
|
|
policy.loadOnePackageLine(packageDetailId, qty);
|
packages.put(packageId, policy);
|
|
return packagePolicy;
|
}
|
|
private void doCalculateHeaderRebate() {
|
//1.
|
rebateAmt = BigDecimal.ZERO;
|
|
if (rebates == null || rebates.isEmpty()) {
|
netAmt = afterOnsiteAmt.subtract(rebateAmt);
|
return;
|
}
|
|
for (Entity entity: rebates) {
|
BigDecimal value = entity.getBigDecimal(Field_RebateDetail_Amt, BigDecimal.ZERO);
|
rebateAmt = rebateAmt.add(value);
|
}
|
|
//2.
|
netAmt = afterOnsiteAmt.subtract(rebateAmt);
|
}
|
|
private void doCalculateLineRebate() {
|
if (afterOnsiteAmt.compareTo(BigDecimal.ZERO) == 0 || details == null || details.isEmpty()) {
|
return;
|
}
|
|
int max = details.size() - 1;
|
|
BigDecimal rate = divide(rebateAmt, afterOnsiteAmt);
|
|
//3. 将票折金额分摊到明细行
|
BigDecimal remainRebateAmt = rebateAmt;
|
BigDecimal lineAfterDiscountAmt = BigDecimal.ZERO;
|
BigDecimal lineRebateAmt = BigDecimal.ZERO;
|
BigDecimal lineNetAmt = BigDecimal.ZERO;
|
String amtFormula;
|
|
//3.1 除最后一行外,其他行进行分摊(RealAmt与分摊率相乘)
|
for (int i = 0; i < max; i++) {
|
Entity entity = details.getEntity(i);
|
amtFormula = entity.getString(Field_Detail_Amt_Formula);
|
lineAfterDiscountAmt = entity.getBigDecimal(Field_Detail_Amt_AfterDiscount, BigDecimal.ZERO);
|
lineRebateAmt = lineAfterDiscountAmt.multiply(rate).setScale(2, RoundingMode.HALF_UP);
|
lineNetAmt = lineAfterDiscountAmt.subtract(lineRebateAmt);
|
|
entity.set(Field_Detail_Amt_Rebate, lineRebateAmt);
|
entity.set(Field_Detail_Amt_Net, lineNetAmt);
|
|
remainRebateAmt = remainRebateAmt.subtract(lineRebateAmt);
|
|
if (OnsiteRecord.isOnsiteLine(entity)) {
|
onsiteRecords.load(entity);
|
}
|
|
if (OnsiteRecord.isOnceLine(entity)) {
|
onceRecords.load(entity);
|
}
|
|
entity.set(Field_Detail_Amt_Formula, amtFormula + "-" + lineRebateAmt + "[积分奖励分摊])");
|
}
|
|
//3.2 最后一行,用减法取剩余
|
Entity entity = details.getEntity(max);
|
lineAfterDiscountAmt = entity.getBigDecimal(Field_Detail_Amt_AfterDiscount, BigDecimal.ZERO);
|
lineRebateAmt = remainRebateAmt;
|
lineNetAmt = lineAfterDiscountAmt.subtract(lineRebateAmt);
|
amtFormula = entity.getString(Field_Detail_Amt_Formula);
|
|
if (OnsiteRecord.isOnsiteLine(entity)) {
|
onsiteRecords.load(entity);
|
}
|
|
if (OnsiteRecord.isOnceLine(entity)) {
|
onceRecords.load(entity);
|
}
|
|
entity.set(Field_Detail_Amt_Rebate, lineRebateAmt);
|
entity.set(Field_Detail_Amt_Net, lineNetAmt);
|
entity.set(Field_Detail_Amt_Formula, amtFormula + "-" + lineRebateAmt + "[积分奖励分摊])");
|
}
|
|
private void calculatorDiscountLevel() {
|
wholeRate = BigDecimal.ONE;
|
BigDecimal lineAfterDiscountAmt = BigDecimal.ZERO;
|
BigDecimal lineNetAmt = BigDecimal.ZERO;
|
BigDecimal lineWholeRateAmt = BigDecimal.ZERO;
|
BigDecimal lineDiscountAmt = BigDecimal.ZERO;
|
|
try {
|
DataObject dataObject = DataObject.getInstance("agm_policy_whole");
|
Filter filter = new Filter();
|
filter.add("state_code", "Open");
|
filter.add("range_low", "<=", String.valueOf(afterOnsiteAmt));
|
filter.add("bu_id", master.getString("bu_id"));
|
filter.add("company_id", master.getString("company_id"));
|
|
EntitySet entitySet = dataObject.getTableEntitySet(filter, new OrderBy("range_low desc"));
|
|
if (entitySet.size() == 0) {
|
return ;
|
}
|
|
Entity wholeRateEntity = entitySet.getEntity(0);
|
wholeRate = wholeRateEntity.getBigDecimal("discount_rate");
|
master.set(Field_Header_Discount_Id, wholeRateEntity.getString("id"));
|
master.set(Field_Header_Discount_Code, wholeRateEntity.getString("policy_no"));
|
master.set(Field_Header_Discount_Name, wholeRateEntity.getString("policy_name"));
|
master.set(Field_Header_Whole_Rate, wholeRate);
|
}catch (Exception e) {
|
e.printStackTrace();
|
return ;
|
}
|
|
for (Entity entity : details) {
|
String amtFormula = entity.getString(Field_Detail_Amt_Formula);
|
lineAfterDiscountAmt = entity.getBigDecimal(Field_Detail_Amt_AfterDiscount, BigDecimal.ZERO);
|
lineDiscountAmt = entity.getBigDecimal(Field_Detail_Amt_Discount, BigDecimal.ZERO);
|
lineWholeRateAmt = lineAfterDiscountAmt.multiply(BigDecimal.ONE.subtract(wholeRate));
|
lineNetAmt = lineAfterDiscountAmt.multiply(wholeRate).setScale(2, RoundingMode.HALF_UP);
|
|
entity.set(Field_Detail_Amt_AfterDiscount, lineNetAmt);
|
entity.set(Field_Detail_Amt_Discount, lineDiscountAmt.add(lineWholeRateAmt));
|
entity.set(Field_Detail_Amt_Net, lineNetAmt);
|
entity.set(Field_Detail_Amt_Formula, "(" + amtFormula + "*" + wholeRate + "[整单折扣])");
|
}
|
|
afterOnsiteAmt = afterOnsiteAmt.multiply(wholeRate);
|
netAmt = afterOnsiteAmt;
|
}
|
|
public boolean setDataPackage(DataPackage dataPackage, DataSource... dataSource) {
|
//1.
|
if (dataPackage == null) {
|
dataWriter.reportOneError("setDataPackage", "无法获取订单");
|
return false;
|
}
|
|
//2.
|
master = dataPackage.getMasterEntity(dataSource);
|
if (master == null || master.isEmpty()) {
|
dataWriter.reportOneError("setDataPackage", "订单头为空");
|
return false;
|
}
|
|
//3.
|
details = dataPackage.getItemEntitySet("so_order_detail", dataSource);
|
if (details == null || details.isEmpty()) {
|
dataWriter.reportOneError("setDataPackage", "订单明细为空");
|
return false;
|
}
|
|
//4.
|
rebates = dataPackage.getItemEntitySet("so_order_detail_rebate", dataSource);
|
|
//5.
|
qtyRebates = new EntitySet(details.getEntityMeta());
|
return true;
|
}
|
|
private void setHeaderValues() {
|
master.set(Field_Header_Amt_List, listAmt);
|
master.set(Field_Header_Amt_AfterOnsite, afterOnsiteAmt);
|
master.set(Field_Header_Amt_Onsite, onsiteAmt);
|
master.set(Field_Header_Amt_Rebate, rebateAmt);
|
master.set(Field_Header_Amt_Net, netAmt);
|
|
master.set(Field_Header_Qty_Total, totalQty);
|
master.set(Field_Header_Qty_List, listQty);
|
master.set(Field_Header_Qty_Discount, discountQty);
|
master.set(Field_Header_Qty_Rebate, rebateQty);
|
master.set(Field_Header_Qty_Onsite, onsiteQty);
|
}
|
|
public boolean saveToDB(DataWriter dataWriter) throws Exception {
|
String orderId = master.getId();
|
String orderNo = master.getString("code");
|
|
//1. 保存订单头
|
DataObject dataObject = DataObject.getInstance("so_order");
|
EntitySaver saver = dataObject.createEntitySaver(master);
|
|
saver.set(Field_Header_Amt_List, listAmt);
|
saver.set(Field_Header_Amt_AfterOnsite, afterOnsiteAmt);
|
saver.set(Field_Header_Amt_Onsite, onsiteAmt);
|
saver.set(Field_Header_Amt_Rebate, rebateAmt);
|
saver.set(Field_Header_Amt_Net, netAmt);
|
|
saver.set(Field_Header_Qty_Total, totalQty);
|
saver.set(Field_Header_Qty_List, listQty);
|
saver.set(Field_Header_Qty_Discount, discountQty);
|
saver.set(Field_Header_Qty_Rebate, rebateQty);
|
saver.set(Field_Header_Discount_Id, master.getString(Field_Header_Discount_Id));
|
saver.set(Field_Header_Discount_Code, master.getString(Field_Header_Discount_Code));
|
saver.set(Field_Header_Discount_Name, master.getString(Field_Header_Discount_Name));
|
saver.set(Field_Header_Whole_Rate, wholeRate);
|
|
saver.update();
|
|
//2. 保存订单明细
|
dataObject = DataObject.getInstance("so_order_detail");
|
|
for (Entity entity: details) {
|
saver = dataObject.createEntitySaver(entity);
|
|
saver.set(Field_Detail_Price_List, entity.getValue(Field_Detail_Price_List));
|
saver.set(Field_Detail_Amt_List, entity.getValue(Field_Detail_Amt_List));
|
saver.set(Field_Detail_Amt_AfterDiscount, entity.getValue(Field_Detail_Amt_AfterDiscount));
|
saver.set(Field_Detail_Amt_Discount, entity.getValue(Field_Detail_Amt_Discount));
|
saver.set(Field_Detail_Amt_Rebate, entity.getValue(Field_Detail_Amt_Rebate));
|
saver.set(Field_Detail_Amt_Net, entity.getValue(Field_Detail_Amt_Net));
|
|
saver.set(Field_Detail_Qty_List, entity.getValue(Field_Detail_Qty_List));
|
saver.set(Field_Detail_Qty_Discount, entity.getValue(Field_Detail_Qty_Discount));
|
saver.set(Field_Detail_Qty_Onsite, entity.getValue(Field_Detail_Qty_Onsite));
|
saver.set(Field_Detail_Qty_Rebate, entity.getValue(Field_Detail_Qty_Rebate));
|
|
saver.set(Field_Detail_Amt_List_Close, BigDecimal.ZERO);
|
saver.set(Field_Detail_Amt_Rebate_Close, BigDecimal.ZERO);
|
saver.set(Field_Detail_Amt_Net_Close, BigDecimal.ZERO);
|
saver.set(Field_Detail_Qty_Close, BigDecimal.ZERO);
|
saver.set(Field_Detail_Qty_Rebate_Close, BigDecimal.ZERO);
|
saver.set(Field_Detail_Amt_Formula, entity.getValue(Field_Detail_Amt_Formula));
|
saver.set(Field_Detail_TypeCode, entity.getString(Field_Detail_TypeCode));
|
saver.set(Field_Detail_RecordId, entity.getString(Field_Detail_RecordId));
|
saver.set(Field_Detail_RecordDetailId, entity.getString(Field_Detail_RecordDetailId));
|
|
saver.update();
|
|
// 一次性政策消耗
|
DataObject recordObject;
|
String recordId = entity.getString("record_id");
|
OrderLineType lineType = OrderLineType.parse(entity.getString(Field_Detail_TypeCode));
|
|
if (OrderLineType.OncePrice == lineType) {
|
recordObject = DataObject.getInstance("md_prod_price_detail");
|
}
|
else if (OrderLineType.OnceQty == lineType) {
|
recordObject = DataObject.getInstance("agm_record");
|
}
|
else {
|
continue;
|
}
|
|
Entity recordEntity = recordObject.getTableEntity(recordId);
|
String usedOrderId = recordEntity.getString("order_id");
|
|
if ((usedOrderId != null) && (!orderId.equals(usedOrderId))) {
|
dataWriter.reportOneError("onceRecordUsed", "一次型政策【" + recordEntity.getString("record_no")+ "】已使用");
|
return false;
|
}
|
|
saver = recordObject.createEntitySaver(recordId);
|
saver.set("order_id", orderId);
|
saver.set("order_no", orderNo);
|
saver.update();
|
}
|
|
//3. 刷新明细 SKU NCC ID
|
String id = master.getId();
|
|
NamedSQL namedSQL = NamedSQL.getInstance("updateOrderDetailNCId");
|
namedSQL.setParam("orderId", id);
|
namedSQL.execute();
|
|
return true;
|
}
|
|
public static BigDecimal divide(BigDecimal one, BigDecimal another, int scale) {
|
if (one == null) {
|
return BigDecimal.ZERO;
|
}
|
|
if (another == null || BigDecimal.ZERO.compareTo(another) == 0) {
|
if (one.compareTo(BigDecimal.ZERO) > 0) {
|
return Rate_Ceiling;
|
}
|
|
return BigDecimal.ZERO;
|
}
|
|
return one.divide(another, scale, RoundingMode.HALF_UP);
|
}
|
|
public static BigDecimal divide(BigDecimal one, BigDecimal another) {
|
return divide(one, another, 4);
|
}
|
|
private BigDecimal getListPrice(String customerId, String productKey) {
|
PolicyBucket policyBucket = PolicyBucket.getInstance();
|
BigDecimal result = policyBucket.getOnePrice(customerId, productKey);
|
|
return result;
|
}
|
|
private BigDecimal getListPrice(PackagePolicy policy, String customerId, String productKey) {
|
PolicyBucket policyBucket = PolicyBucket.getInstance();
|
BigDecimal result = policyBucket.getOnePrice(policy, customerId, productKey);
|
|
return result;
|
}
|
|
public BigDecimal getListAmt() {
|
return listAmt;
|
}
|
|
public BigDecimal getAfterOnsiteAmt() {
|
return afterOnsiteAmt;
|
}
|
|
public BigDecimal getOnsiteAmt() {
|
return onsiteAmt;
|
}
|
|
public BigDecimal getRebateAmt() {
|
return rebateAmt;
|
}
|
|
public BigDecimal getNetAmt() {
|
return netAmt;
|
}
|
|
public BigDecimal getTotalQty() {
|
return totalQty;
|
}
|
|
public BigDecimal getListQty() {
|
return listQty;
|
}
|
|
public BigDecimal getDiscountQty() {
|
return discountQty;
|
}
|
|
public BigDecimal getOnsiteQty() {
|
return onsiteQty;
|
}
|
|
public BigDecimal getRebateQty() {
|
return rebateQty;
|
}
|
|
public BigDecimal getOnsitePriceAmt() {
|
return onsitePriceAmt;
|
}
|
|
public BigDecimal getOnsiteQtyAmt() {
|
return onsiteQtyAmt;
|
}
|
|
public BigDecimal getOncePriceAmt() {
|
return oncePriceAmt;
|
}
|
|
public OnsiteRecords getOnsiteRecords() {
|
return onsiteRecords;
|
}
|
|
public OnsiteRecords getOnceRecords() {
|
return onceRecords;
|
}
|
|
public EntitySet getRebates() {
|
return rebates;
|
}
|
|
public EntitySet getQtyRebates() {
|
return qtyRebates;
|
}
|
|
public HashMap<String, PackagePolicy> getPackages() {
|
return packages;
|
}
|
}
|