package com.hx.phip.service.init.impl;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONObject;
|
import com.hx.common.service.CommonService;
|
import com.hx.exception.TipsException;
|
import com.hx.mybatisTool.SqlSentence;
|
import com.hx.phiappt.common.ConsumePayConstants;
|
import com.hx.phiappt.common.OrderItemConstants;
|
import com.hx.phiappt.common.OrderTotalConstants;
|
import com.hx.phiappt.common.PayMethodTypeConstants;
|
import com.hx.phiappt.constants.tool.exception.ExceptionTool;
|
import com.hx.phiappt.dao.mapper.*;
|
import com.hx.phiappt.model.cardItem.CardEquity;
|
import com.hx.phiappt.model.cardItem.CardItem;
|
import com.hx.phiappt.model.cardItem.CardItemInfo;
|
import com.hx.phiappt.model.consume.ConsumePay;
|
import com.hx.phiappt.model.consume.ConsumePayItem;
|
import com.hx.phiappt.model.consume.ConsumePayItemSon;
|
import com.hx.phiappt.model.coupon.CouponOrderDiscountLog;
|
import com.hx.phiappt.model.order.OrderItem;
|
import com.hx.phiappt.model.order.OrderItemSon;
|
import com.hx.phiappt.model.order.OrdersTotal;
|
import com.hx.phiappt.model.user.UserCard;
|
import com.hx.phiappt.model.user.UserCardPay;
|
import com.hx.phiappt.model.user.UserProjectItem;
|
import com.hx.phiappt.tool.project.ProjectIntegralCashTool;
|
import com.hx.phiappt.vo.payMethod.PayMethodVo;
|
import com.hx.phip.config.CustomParameter;
|
import com.hx.phip.service.init.OrderInitService;
|
import com.hx.phip.tool.deduction.UserDeductionSingleTool;
|
import com.hx.phip.tool.user.UserCardTool;
|
import com.hx.phip.vo.init.OrderCarryVo;
|
import com.hx.phip.vo.user.UserCardItemInfoVo;
|
import com.hx.util.StringUtils;
|
import com.hz.his.vo.project.IntegralCashVo;
|
import com.hz.his.vo.project.SkuDeductionVo;
|
import com.platform.exception.PlatTipsException;
|
import com.platform.resultTool.PlatformCode;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.BeanUtils;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import javax.annotation.Resource;
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
@Transactional
|
@Service
|
public class OrderInitServiceImpl implements OrderInitService {
|
|
/**log4j日志*/
|
private static final Logger logger = LoggerFactory.getLogger(OrderInitService.class.getName());
|
|
|
@Resource
|
private OrdersTotalMapper ordersTotalMapper;
|
@Resource
|
private OrderItemMapper orderItemMapper;
|
@Resource
|
private OrderItemSonMapper orderItemSonMapper;
|
@Resource
|
private OrderInfoMapper orderInfoMapper;
|
@Resource
|
private ConsumePayMapper consumePayMapper;
|
@Resource
|
private CouponOrderDiscountLogMapper couponOrderDiscountLogMapper;
|
@Resource
|
private ConsumePayItemMapper consumePayItemMapper;
|
@Resource
|
private ConsumePayItemSonMapper consumePayItemSonMapper;
|
@Resource
|
private UserProjectItemMapper userProjectItemMapper;
|
@Resource
|
private UserCardMapper userCardMapper;
|
@Resource
|
private CardItemMapper cardItemMapper;
|
@Resource
|
private CardItemInfoMapper cardItemInfoMapper;
|
@Resource
|
private CommonService commonService;
|
@Resource
|
private CustomParameter customParameter;
|
@Resource
|
private RefundMapper refundMapper;
|
|
/**重新算订单数据
|
* @param canIntegralCashIdList 可以使用积分结账的商品
|
* @param orderId 订单标识
|
* @param updateUserProject 是否更新用户项目新
|
* @param updateStatus 是否更新订单状态(只能结账使用)
|
* @param appId 结账平台appId
|
*/
|
@Override
|
public void initOrder(List<String> canIntegralCashIdList,String orderId, String appId, boolean updateUserProject, Boolean updateStatus) {
|
OrdersTotal ordersTotal = ordersTotalMapper.selectOneByKey(orderId);
|
if(ordersTotal == null){
|
throw new TipsException("未找到订单信息:"+orderId);
|
}
|
|
//因为事务的问题,需要判断状态
|
if(ordersTotal.getPayStatus() != OrderTotalConstants.PAY_STATUS_SUC
|
&& ordersTotal.getPayStatus() != OrderTotalConstants.PAY_STATUS_PART){
|
int whileNum = 0;
|
while (whileNum<100){
|
//重新拿取
|
ordersTotal = ordersTotalMapper.selectOneByKey(orderId);
|
if(ordersTotal.getPayStatus() == OrderTotalConstants.PAY_STATUS_SUC
|
|| ordersTotal.getPayStatus() == OrderTotalConstants.PAY_STATUS_PART){
|
//符合条件,跳出校验
|
break;
|
}
|
try{
|
//睡眠3秒钟
|
Thread.sleep(2000);
|
}catch (Exception ignored){
|
|
}
|
whileNum++;
|
}
|
}
|
|
SqlSentence sqlSentence = new SqlSentence();
|
Map<String,Object> values = new HashMap<>();
|
|
//获取支付信息,获取有支付方式
|
values.put("orderId",ordersTotal.getId());
|
sqlSentence.sqlSentence("SELECT * FROM consume_pay WHERE isDel = 0 AND orderId = #{m.orderId} AND actualTotal > 0 ORDER BY actualTotal ASC",values);
|
List<ConsumePay> consumePayList = consumePayMapper.selectList(sqlSentence);
|
|
//保存总单信息
|
OrderCarryVo orderCarryVo = orderHandle(ordersTotal,consumePayList,updateStatus);
|
//处理一级子单
|
orderItemHandle(canIntegralCashIdList,ordersTotal,orderCarryVo,updateUserProject,appId);
|
|
//处理积分支付方式---------------------------------------------------------------------
|
//-----2023-11-10屏蔽不使用
|
/*values.put("numberNo", PAY_INTEGRAL);
|
sqlSentence.sqlSentence("SELECT * FROM consume_pay WHERE isDel != 1 and numberNo = #{m.numberNo} AND orderId = #{m.orderId} AND actualTotal > 0 ORDER BY actualTotal ASC",values);
|
consumePayList = consumePayMapper.selectList(sqlSentence);
|
if(consumePayList != null && consumePayList.size() > 0){
|
handleOrderRecalculatePayPoints(ordersTotal, consumePayList);
|
}*/
|
}
|
|
/**总单信息处理*/
|
private OrderCarryVo orderHandle(OrdersTotal ordersTotal,List<ConsumePay> consumePayList,Boolean updateStatus){
|
|
OrderCarryVo orderCarryVo = new OrderCarryVo();
|
orderCarryVo.setConsumePayList(consumePayList);
|
|
SqlSentence sqlSentence = new SqlSentence();
|
Map<String,Object> values = new HashMap<>();
|
|
/////查询优惠记录,计算优惠金额
|
//设置初始值
|
ordersTotal.setCouponTotal(BigDecimal.ZERO);
|
values.put("orderId",ordersTotal.getId());
|
sqlSentence.sqlSentence("SELECT * FROM coupon_order_discount_log WHERE isDel = 0 AND orderId = #{m.orderId}",values);
|
List<CouponOrderDiscountLog> couponLogList = couponOrderDiscountLogMapper.selectList(sqlSentence);
|
if(couponLogList.size()>0){
|
ordersTotal.setCouponTotal(BigDecimal.ZERO);
|
for(CouponOrderDiscountLog couponLog:couponLogList){
|
ordersTotal.setCouponTotal(ordersTotal.getCouponTotal().add(couponLog.getDiscountTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
}
|
|
//处理初始优惠福利金额(开单时已存储,结账直接取值,不会更新)
|
if(ordersTotal.getPreferentialTotal() == null){
|
ordersTotal.setPreferentialTotal(BigDecimal.ZERO);
|
}
|
|
//初始优惠总金额 = 优惠券金额 + 优惠福利总金额
|
ordersTotal.setDiscountPrice(ordersTotal.getCouponTotal().add(ordersTotal.getPreferentialTotal()).setScale(2, RoundingMode.HALF_UP));
|
|
//设置相应的应付金额
|
ordersTotal.setShouldTotal(ordersTotal.getTotal());
|
|
//应付金额减去活动规则优惠总金额
|
if(ordersTotal.getActivityTotal() != null){
|
ordersTotal.setShouldTotal(ordersTotal.getShouldTotal().subtract(ordersTotal.getActivityTotal()));
|
}
|
|
//应付金额减去优惠金额
|
// ordersTotal.setShouldTotal(ordersTotal.getShouldTotal().subtract(ordersTotal.getCouponTotal()).setScale(2, RoundingMode.HALF_UP));
|
ordersTotal.setShouldTotal(ordersTotal.getShouldTotal().subtract(ordersTotal.getDiscountPrice()).setScale(2, RoundingMode.HALF_UP));
|
|
|
//有负数的就存0
|
if(ordersTotal.getShouldTotal().compareTo(BigDecimal.ZERO) < 0){
|
ordersTotal.setShouldTotal(BigDecimal.ZERO);
|
}
|
|
//////计算支付总金额
|
//设置初始值
|
ordersTotal.setPayIncrement(BigDecimal.ZERO);
|
ordersTotal.setPayRecharge(BigDecimal.ZERO);
|
ordersTotal.setPayTotal(BigDecimal.ZERO);
|
ordersTotal.setActualTotal(BigDecimal.ZERO);
|
ordersTotal.setActualTotalPoints(BigDecimal.ZERO);
|
ordersTotal.setIntegralDeduction(BigDecimal.ZERO);
|
ordersTotal.setIntegralCash(BigDecimal.ZERO);
|
for(ConsumePay consumePay:consumePayList){
|
|
if(PayMethodTypeConstants.PAY_INTEGRAL.equals(consumePay.getNumberNo())){
|
//积分
|
ordersTotal.setActualTotalPoints(ordersTotal.getActualTotalPoints().add(consumePay.getActualTotal()));
|
orderCarryVo.getConsumePayIntegralList().add(consumePay);
|
}else if(PayMethodTypeConstants.PAY_INTEGRAL_CASH.equals(consumePay.getNumberNo())){
|
//积分抵扣现金
|
ordersTotal.setIntegralCash(ordersTotal.getIntegralCash().add(consumePay.getActualTotal()));
|
ordersTotal.setIntegralDeduction(ordersTotal.getIntegralDeduction().add(consumePay.getDeductionMoney()));
|
//加进去已支付积分
|
ordersTotal.setActualTotalPoints(ordersTotal.getActualTotalPoints().add(consumePay.getDeductionMoney()));
|
orderCarryVo.getConsumePayMoneyList().add(consumePay);
|
}else{
|
if(PayMethodTypeConstants.PAY_ADD_FUND.equals(consumePay.getNumberNo())){
|
//增值金
|
ordersTotal.setPayIncrement(ordersTotal.getPayIncrement().add(consumePay.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
}else if(PayMethodTypeConstants.PAY_STORED.equals(consumePay.getNumberNo())){
|
//储值金
|
ordersTotal.setPayRecharge(ordersTotal.getPayRecharge().add(consumePay.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
} else{
|
//其他金额
|
ordersTotal.setPayTotal(ordersTotal.getPayTotal().add(consumePay.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
//现金金额
|
if(consumePay.getIsMoneyPay().equals(ConsumePay.YES)){
|
orderCarryVo.setCashTotal(orderCarryVo.getCashTotal().add(consumePay.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
|
//划扣金额
|
if(consumePay.getIsExecute().equals(ConsumePay.YES)){
|
orderCarryVo.setExecuteTotal(orderCarryVo.getExecuteTotal().add(consumePay.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
|
orderCarryVo.getConsumePayMoneyList().add(consumePay);
|
//已付金额计算
|
ordersTotal.setActualTotal(ordersTotal.getActualTotal().add(consumePay.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
|
}
|
|
//订单信息更新
|
values.clear();
|
values.put("id",ordersTotal.getId());
|
//values.put("shouldTotal",ordersTotal.getShouldTotal());
|
values.put("actualTotal",ordersTotal.getActualTotal());
|
values.put("payTotal",ordersTotal.getPayTotal());
|
values.put("payRecharge",ordersTotal.getPayRecharge());
|
values.put("payIncrement",ordersTotal.getPayIncrement());
|
values.put("couponTotal",ordersTotal.getCouponTotal());
|
values.put("discountPrice", ordersTotal.getDiscountPrice());
|
values.put("actualTotalPoints",ordersTotal.getActualTotalPoints());
|
values.put("integralCash",ordersTotal.getIntegralCash());
|
values.put("integralDeduction",ordersTotal.getIntegralDeduction());
|
|
StringBuilder sql = new StringBuilder();
|
sql.append("actualTotal = #{m.actualTotal},payTotal = #{m.payTotal},payRecharge = #{m.payRecharge}");
|
sql.append(" ,couponTotal = #{m.couponTotal}, discountPrice = #{m.discountPrice} ");
|
sql.append(" ,payIncrement = #{m.payIncrement},actualTotalPoints = #{m.actualTotalPoints}");
|
sql.append(" ,integralCash = #{m.integralCash},integralDeduction = #{m.integralDeduction} ");
|
|
if(updateStatus != null &&updateStatus){
|
if(OrderTotalConstants.TYPE_CARD_BAG.equals(ordersTotal.getType())) {
|
//卡包抵扣不对比金额
|
values.put("payStatus",OrderTotalConstants.PAY_STATUS_SUC);
|
values.put("status",OrderTotalConstants.STATUS_PAY);
|
sql.append(",payStatus = #{m.payStatus},status = #{m.status}");
|
}else {
|
if(ordersTotal.getActualTotal().compareTo(ordersTotal.getShouldTotal().subtract(ordersTotal.getIntegralCash())) == 0
|
&& ordersTotal.getActualTotalPoints().compareTo(ordersTotal.getShouldTotalPoints()) == 0){
|
values.put("payStatus",OrderTotalConstants.PAY_STATUS_SUC);
|
values.put("status",OrderTotalConstants.STATUS_PAY);
|
sql.append(",payStatus = #{m.payStatus},status = #{m.status}");
|
}else if(ordersTotal.getActualTotal().compareTo(ordersTotal.getShouldTotal().subtract(ordersTotal.getIntegralCash())) < 0){
|
values.put("payStatus",OrderTotalConstants.PAY_STATUS_PART);
|
values.put("status",OrderTotalConstants.STATUS_ARREARS);
|
sql.append(",payStatus = #{m.payStatus},status = #{m.status}");
|
}
|
}
|
}
|
sql.append(" WHERE id = #{m.id}");
|
|
sqlSentence.sqlUpdate(sql.toString(),values);
|
if(ordersTotalMapper.updateWhere(sqlSentence) != 1){
|
throw new TipsException("变更订单信息出错!");
|
}
|
|
//订单详情信息更新
|
values.clear();
|
values.put("orderId",ordersTotal.getId());
|
values.put("snapPayTotal",orderCarryVo.getCashTotal());
|
values.put("snapExecuteTotal",orderCarryVo.getExecuteTotal());
|
sqlSentence.sqlUpdate("snapPayTotal = #{m.snapPayTotal},snapExecuteTotal = #{m.snapExecuteTotal}" +
|
" WHERE orderId = #{m.orderId}",values);
|
if(orderInfoMapper.updateWhere(sqlSentence) != 1){
|
throw new TipsException("变更订单信息出错[012]!");
|
}
|
|
return orderCarryVo;
|
}
|
|
/**一级子单信息处理*/
|
private void orderItemHandle(List<String> canIntegralCashIdList,OrdersTotal ordersTotal,OrderCarryVo orderCarryVo,boolean updateUserProject,String appId){
|
SqlSentence sqlSentence = new SqlSentence();
|
Map<String,Object> values = new HashMap<>();
|
|
//先删除平摊支付记录
|
values.put("orderId",ordersTotal.getId());
|
sqlSentence.sqlWhere("orderId = #{m.orderId}",values);
|
consumePayItemMapper.deleteWhere(sqlSentence);
|
|
//先删除平摊支付记录
|
values.clear();
|
values.put("orderId",ordersTotal.getId());
|
sqlSentence.sqlWhere("orderId = #{m.orderId}",values);
|
consumePayItemSonMapper.deleteWhere(sqlSentence);
|
|
//获取订单的所有一级子单
|
values.clear();
|
values.put("orderId",ordersTotal.getId());
|
sqlSentence.sqlSentence("SELECT * FROM order_item WHERE isDel = 0 AND orderId = #{m.orderId}",values);
|
List<OrderItem> orderItemList = orderItemMapper.selectList(sqlSentence);
|
if(orderItemList.size() == 0){
|
return;
|
}
|
|
//金额处理
|
moneyOneHandle(canIntegralCashIdList,ordersTotal,orderCarryVo,orderItemList,appId);
|
//积分处理
|
integralOneHandle(ordersTotal,orderCarryVo,orderItemList);
|
|
UserProjectItem userProjectItem;
|
for(OrderItem orderItem:orderItemList){
|
//按比例算出抵扣的积分
|
if (ordersTotal.getIntegralCash().compareTo(BigDecimal.ZERO) != 0){
|
orderItem.setIntegralDeduction(orderItem.getIntegralCash().multiply(ordersTotal.getIntegralDeduction())
|
.divide(ordersTotal.getIntegralCash(),2,RoundingMode.HALF_UP));
|
}else {
|
orderItem.setIntegralDeduction(BigDecimal.ZERO);
|
}
|
//已支付积分
|
orderItem.setActualTotalPoints(orderItem.getActualTotalPoints().add(orderItem.getIntegralDeduction()).setScale(2, RoundingMode.HALF_UP));
|
|
//更新一级子单信息
|
values.clear();
|
values.put("id",orderItem.getId());
|
values.put("couponTotal",orderItem.getCouponTotal());
|
values.put("discountPrice",orderItem.getDiscountPrice());
|
values.put("actualTotal",orderItem.getActualTotal());
|
values.put("noDeductionAmount",orderItem.getNoDeductionAmount());
|
values.put("payTotal",orderItem.getPayTotal());
|
values.put("payRecharge",orderItem.getPayRecharge());
|
values.put("payIncrement",orderItem.getPayIncrement());
|
values.put("snapPayTotal",orderItem.getSnapPayTotal());
|
values.put("userPaidTotal",orderItem.getUserPaidTotal());
|
values.put("actualTotalPoints",orderItem.getActualTotalPoints());
|
values.put("integralCash",orderItem.getIntegralCash());
|
values.put("integralDeduction",orderItem.getIntegralDeduction());
|
sqlSentence.sqlUpdate("couponTotal = #{m.couponTotal},discountPrice = #{m.discountPrice},actualTotal = #{m.actualTotal},noDeductionAmount = #{m.noDeductionAmount}" +
|
",payTotal = #{m.payTotal},payRecharge = #{m.payRecharge},payIncrement = #{m.payIncrement},snapPayTotal = #{m.snapPayTotal}" +
|
",userPaidTotal = #{m.userPaidTotal},actualTotalPoints = #{m.actualTotalPoints},integralDeduction = #{m.integralDeduction}" +
|
" ,integralCash = #{m.integralCash} WHERE id = #{m.id}",values);
|
orderItemMapper.updateWhere(sqlSentence);
|
|
////用户项目处理
|
if(OrderItemConstants.TYPE_PROJECT.equals(orderItem.getType())){
|
if(updateUserProject){
|
//根据用户项目获取疗程数
|
userProjectItem = getUserProjectItem(orderItem.getId(),ordersTotal.getUserId());
|
updateUserProject(userProjectItem,orderItem.getTotal(),orderItem.getActualTotal(),orderItem.getOriPrice()
|
,orderItem.getCurPrice(),orderItem.getBuyNum(),orderItem.getNoDeductionAmount(),orderItem.getUsedTotal(),null);
|
}
|
}else{
|
//子订单处理
|
orderItemSonHandle(ordersTotal,orderItem,updateUserProject);
|
}
|
}
|
}
|
|
/**一级订单金额处理*/
|
private void moneyOneHandle(List<String> canIntegralCashIdList,OrdersTotal ordersTotal,OrderCarryVo orderCarryVo,List<OrderItem> orderItemList,String appId){
|
// 总的积分抵扣现金-现金
|
BigDecimal integralCash = ordersTotal.getIntegralCash();
|
// 总的积分抵扣现金-积分
|
BigDecimal integralDeduction = ordersTotal.getIntegralDeduction();
|
// 储值金
|
BigDecimal sysStoreTotal = ordersTotal.getPayRecharge() == null ? BigDecimal.ZERO : ordersTotal.getPayRecharge();
|
// 增值金
|
BigDecimal sysIncrementTotal = ordersTotal.getPayIncrement() == null ? BigDecimal.ZERO : ordersTotal.getPayIncrement();
|
logger.info("一级订单金额处理。总单可分配抵扣现金{},抵扣支付积分{},储值金{},增值金{},可分配金额的商品标识{},"
|
,integralCash,integralDeduction,sysStoreTotal,sysIncrementTotal,JSON.toJSONString(canIntegralCashIdList));
|
//sku标识,最大数据
|
Map<String, SkuDeductionVo> skuDeductionVoMap = null;
|
SkuDeductionVo skuDeductionVo = null;
|
SkuDeductionVo orderItemDeductionVo = null;
|
// 一级子单总的最大可抵扣现金金额
|
BigDecimal totalDeductionMoney = BigDecimal.ZERO;
|
//如果含积分抵扣现金,校验数据
|
if (integralCash.compareTo(BigDecimal.ZERO) > 0 || integralDeduction.compareTo(BigDecimal.ZERO) > 0){
|
//获取每个SKU最大抵扣数据
|
skuDeductionVoMap = handlerDeductionMoneyMap(canIntegralCashIdList,orderItemList,integralCash,integralDeduction,appId);
|
}
|
|
//【注意】实际订单总价(减去优惠福利的金额)
|
BigDecimal realTotal = ordersTotal.getTotal().subtract(ordersTotal.getPreferentialTotal()).setScale(2, RoundingMode.HALF_UP);
|
|
//【注意】遍历处理对应子单的total - preferentialTotal = 实际总价,才能重新排序计算
|
for(OrderItem orderItem : orderItemList){
|
orderItem.setTotal(orderItem.getTotal().subtract(orderItem.getPreferentialTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
|
//-----四舍五入的原因,先排序,先算小的,再算大的,因为如果除不尽,那么都会进1分,那么就导致了后面的如果刚刚好,而前面的多扣了一分,导致会少钱
|
orderItemList = orderItemList.stream().sorted(Comparator.comparing(OrderItem::getTotal))
|
.collect(Collectors.toList());
|
/////开始其他金额的运算
|
//剩余可分配优惠金额
|
BigDecimal shareCouponTotal = ordersTotal.getCouponTotal();
|
//剩余可分配的活动优惠金额
|
BigDecimal shareActivityTotal = BigDecimal.ZERO;
|
if(ordersTotal.getActivityTotal() != null){
|
shareActivityTotal = ordersTotal.getActivityTotal();
|
}
|
|
//占比
|
BigDecimal proportion;
|
OrderItem orderItem;
|
//子订单剩余应付金额,分配支付记录用到
|
BigDecimal surplusTotal;
|
for(int i=0;i<orderItemList.size();i++) {
|
orderItem = orderItemList.get(i);
|
|
//赋值计算
|
orderItem.setActualTotal(orderItem.getTotal());
|
|
//计算比例
|
if (realTotal.compareTo(BigDecimal.ZERO) > 0) {
|
proportion = orderItem.getTotal().divide(realTotal, 15, RoundingMode.HALF_UP);
|
} else {
|
proportion = BigDecimal.ZERO;
|
}
|
|
//////平摊优惠券和活动金额,先处理活动金额,在处理优惠金额
|
if (i == orderItemList.size() - 1) {
|
//活动
|
orderItem.setActivityPrice(shareActivityTotal);
|
//优惠券
|
orderItem.setCouponTotal(shareCouponTotal);
|
} else {
|
orderItem.setActivityPrice(ordersTotal.getActivityTotal().multiply(proportion).setScale(2, RoundingMode.UP));
|
if (shareActivityTotal.compareTo(orderItem.getActivityPrice()) < 0) {
|
//判断分配的活动金额是不是大于剩下的
|
orderItem.setActivityPrice(shareActivityTotal);
|
}
|
//优惠券,四舍五入规则,有余数都进一分钱
|
orderItem.setCouponTotal(ordersTotal.getCouponTotal().multiply(proportion).setScale(2, RoundingMode.UP));
|
if (shareCouponTotal.compareTo(orderItem.getCouponTotal()) < 0) {
|
//判断分配的优惠金额是不是大于剩下的
|
orderItem.setCouponTotal(shareCouponTotal);
|
}
|
}
|
//判断分配的【活动金额】是不是大过优惠前小计
|
if (orderItem.getActualTotal().compareTo(orderItem.getActivityPrice()) < 0) {
|
orderItem.setActivityPrice(orderItem.getActualTotal());
|
}
|
orderItem.setActualTotal(orderItem.getActualTotal().subtract(orderItem.getActivityPrice()));
|
|
//判断分配的【优惠金额】是不是大过优惠前小计
|
if (orderItem.getActualTotal().compareTo(orderItem.getCouponTotal()) < 0) {
|
orderItem.setCouponTotal(orderItem.getActualTotal());
|
}
|
orderItem.setActualTotal(orderItem.getActualTotal().subtract(orderItem.getCouponTotal()));
|
|
//减去已分配的活动优惠金额
|
shareActivityTotal = shareActivityTotal.subtract(orderItem.getActivityPrice());
|
//减去已分配的优惠券金额
|
shareCouponTotal = shareCouponTotal.subtract(orderItem.getCouponTotal());
|
|
//优惠金额 = 优惠券金额 + 优惠福利金额
|
orderItem.setDiscountPrice(orderItem.getCouponTotal().add(orderItem.getPreferentialTotal()));
|
|
//计算优惠后小计金额
|
if (orderItem.getActualTotal().compareTo(BigDecimal.ZERO) < 0) {
|
orderItem.setActualTotal(BigDecimal.ZERO);
|
}
|
|
|
//按商品金额比例分摊抵扣的金额计算
|
if (skuDeductionVoMap != null && skuDeductionVoMap.size() > 0){
|
skuDeductionVo = skuDeductionVoMap.get(orderItem.getCommonId());
|
|
//计算出每个子单最大可抵扣掉的现金(后续根据这个比例计算)
|
orderItemDeductionVo = new SkuDeductionVo();
|
orderItemDeductionVo.setSkuId(skuDeductionVo.getSkuId());
|
orderItemDeductionVo.setMaxCash(skuDeductionVo.getMaxCash());
|
orderItemDeductionVo.setMaxIntegralCash(skuDeductionVo.getMaxIntegralCash());
|
orderItemDeductionVo.setSkuPrice(orderItem.getTotal());
|
orderItemDeductionVo.setBuyNum(orderItem.getBuyNum());
|
orderItemDeductionVo.handlerMoney();
|
skuDeductionVoMap.put(orderItem.getCommonId(),orderItemDeductionVo);
|
//总抵扣金额
|
totalDeductionMoney = totalDeductionMoney.add(orderItemDeductionVo.getSkuMaxCash());
|
}
|
}
|
|
// 先计算子单分配抵扣金额,返回 (总单-抵扣的金额 = 剩余的金额)
|
logger.info("orderItemList顺序:"+JSON.toJSONString(orderItemList));
|
BigDecimal actualTotal = handlerDeductionMoney(totalDeductionMoney,skuDeductionVoMap,ordersTotal,orderItemList);
|
logger.info("抵扣分配后剩余actualTotal:"+actualTotal);
|
// 循环子单,生成支付记录
|
for (int i = 0; i < orderItemList.size(); i++) {
|
orderItem = orderItemList.get(i);
|
orderItem.setConsumePayItemList(new ArrayList<>());
|
orderItem.setConsumePayMoneyItemList(new ArrayList<>());
|
|
//重新算一遍比例,更准确
|
if (actualTotal.compareTo(BigDecimal.ZERO) > 0) {
|
proportion = (orderItem.getActualTotal().subtract(orderItem.getIntegralCash())).divide(actualTotal, 15, RoundingMode.HALF_UP);
|
}else {
|
proportion = BigDecimal.ZERO;
|
}
|
|
////////平摊支付记录,注意除不尽的问题
|
surplusTotal = orderItem.getActualTotal().subtract(orderItem.getIntegralCash());
|
logger.info("子单{},占比{},平摊应付{}",orderItem.getId(),proportion,surplusTotal);
|
if (surplusTotal.compareTo(BigDecimal.ZERO) < 0){
|
throw new TipsException("金额分配错误");
|
}
|
//设置初始化值
|
orderItem.setPayTotal(BigDecimal.ZERO);
|
orderItem.setUserPaidTotal(BigDecimal.ZERO);
|
orderItem.setSnapPayTotal(BigDecimal.ZERO);
|
orderItem.setNoDeductionAmount(BigDecimal.ZERO);
|
orderItem.setPayIncrement(BigDecimal.ZERO);
|
orderItem.setPayRecharge(BigDecimal.ZERO);
|
ConsumePay consumePay;
|
for (int j = 0; j < orderCarryVo.getConsumePayMoneyList().size(); j++) {
|
consumePay = orderCarryVo.getConsumePayMoneyList().get(j);
|
logger.info("支付方式:"+JSON.toJSONString(consumePay));
|
if (!PayMethodTypeConstants.PAY_INTEGRAL_CASH.equals(consumePay.getNumberNo())){
|
if (consumePay.getpTotal().compareTo(BigDecimal.ZERO) <= 0 || surplusTotal.compareTo(BigDecimal.ZERO) <= 0) {
|
continue;
|
}
|
//生成子单的支付记录
|
ConsumePayItem consumePayItem = new ConsumePayItem();
|
BeanUtils.copyProperties(consumePay, consumePayItem);
|
consumePayItem.setType(ConsumePayItem.TYPE_ORDER_ITEM);
|
consumePayItem.setTypeId(orderItem.getId());
|
consumePayItem.setConsumePayId(consumePay.getId());
|
//计算支付方式的金额/积分
|
if (i == orderItemList.size() - 1) {
|
//最后一个子单,把剩下未分配的支付方式金额全部放进去
|
consumePayItem.setActualTotal(consumePay.getpTotal());
|
} else {
|
if (j == orderCarryVo.getConsumePayMoneyList().size() - 1) {
|
//支付方式的最后一个,把剩下未分配的应付金额全部放进去
|
consumePayItem.setActualTotal(surplusTotal);
|
} else {
|
////四舍五入规则,有余数都进一分钱
|
consumePayItem.setActualTotal(consumePay.getActualTotal().multiply(proportion).setScale(2, RoundingMode.UP));
|
}
|
}
|
|
//如果分配的金额/积分比剩余的积分多,那么就用剩余的金额/积分
|
if (consumePay.getpTotal().compareTo(consumePayItem.getActualTotal()) < 0) {
|
consumePayItem.setActualTotal(consumePay.getpTotal());
|
}
|
|
//如果分配的金额比剩余应付金额多,那就就用剩余应付金额
|
if (surplusTotal.compareTo(consumePayItem.getActualTotal()) < 0) {
|
consumePayItem.setActualTotal(surplusTotal);
|
}
|
//计算剩余可分配的金额
|
consumePay.setpTotal(consumePay.getpTotal().subtract(consumePayItem.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
//计算剩余的应付金额
|
surplusTotal = surplusTotal.subtract(consumePayItem.getActualTotal()).setScale(2, RoundingMode.HALF_UP);
|
|
|
if (PayMethodTypeConstants.PAY_ADD_FUND.equals(consumePayItem.getNumberNo())) {
|
//增值金
|
orderItem.setPayIncrement(orderItem.getPayIncrement().add(consumePayItem.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
} else if (PayMethodTypeConstants.PAY_STORED.equals(consumePayItem.getNumberNo())) {
|
//储值金
|
orderItem.setPayRecharge(orderItem.getPayRecharge().add(consumePayItem.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
} else {
|
//其他金额
|
orderItem.setPayTotal(orderItem.getPayTotal().add(consumePayItem.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
|
//现金金额
|
if (consumePayItem.getIsMoneyPay().equals(ConsumePay.YES)) {
|
orderItem.setSnapPayTotal(orderItem.getSnapPayTotal().add(consumePayItem.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
//划扣金额
|
if (consumePayItem.getIsExecute().equals(ConsumePay.YES)) {
|
orderItem.setNoDeductionAmount(orderItem.getNoDeductionAmount().add(consumePayItem.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
//支付总金额
|
orderItem.setUserPaidTotal(orderItem.getUserPaidTotal().add(consumePayItem.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
|
//保存平摊支付方式
|
consumePayItemMapper.insert(consumePayItem);
|
//设置未分配金额
|
consumePayItem.setpTotal(consumePayItem.getActualTotal());
|
orderItem.getConsumePayItemList().add(consumePayItem);
|
orderItem.getConsumePayMoneyItemList().add(consumePayItem);
|
} else {
|
//处理积分抵扣现金支付方式
|
if (orderItem.getIntegralCash().compareTo(BigDecimal.ZERO) <= 0){
|
continue;
|
}
|
orderItem.setIntegralDeduction(orderItem.getIntegralCash().multiply(integralDeduction).divide(integralCash,2,RoundingMode.HALF_UP));
|
//生成子单的支付记录
|
ConsumePayItem consumePayItem = new ConsumePayItem();
|
consumePayItem.setNumberNo(consumePay.getNumberNo());
|
consumePayItem.setName(consumePay.getName());
|
consumePayItem.setActualTotal(orderItem.getIntegralCash());
|
consumePayItem.setDeductionType(ConsumePayConstants.DEDUCTION_INTEGRAL_CASH);
|
consumePayItem.setDeductionMoney(orderItem.getIntegralDeduction());
|
consumePayItem.setIsMoneyPay(consumePay.getIsMoneyPay());
|
consumePayItem.setIsExecute(consumePay.getIsExecute());
|
consumePayItem.setIsPay(consumePay.getIsPay());
|
consumePayItem.setPaymentMethodId(consumePay.getPaymentMethodId());
|
consumePayItem.setType(ConsumePayItem.TYPE_ORDER_ITEM);
|
consumePayItem.setTypeId(orderItem.getId());
|
consumePayItem.setOrderId(ordersTotal.getId());
|
consumePayItem.setReConsumeId(consumePay.getReConsumeId());
|
consumePayItem.setConsumePayId(consumePay.getId());
|
//保存平摊支付方式
|
consumePayItemMapper.insert(consumePayItem);
|
//现金金额
|
if (consumePayItem.getIsMoneyPay().equals(ConsumePay.YES)) {
|
orderItem.setSnapPayTotal(orderItem.getSnapPayTotal().add(consumePayItem.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
//划扣金额
|
if (consumePayItem.getIsExecute().equals(ConsumePay.YES)) {
|
orderItem.setNoDeductionAmount(orderItem.getNoDeductionAmount().add(consumePayItem.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
//设置未分配金额
|
consumePayItem.setpTotal(consumePayItem.getActualTotal());
|
//全部支付
|
orderItem.getConsumePayItemList().add(consumePayItem);
|
//金额支付
|
orderItem.getConsumePayMoneyItemList().add(consumePayItem);
|
}
|
}
|
//支付方式进行升序排序,避免循环支付方式的时候最后一个可分配0元,从而导致算子单最后一个的时候没有钱算了
|
orderCarryVo.setConsumePayMoneyList(orderCarryVo.getConsumePayMoneyList().stream().sorted(Comparator.comparing(ConsumePay::getpTotal))
|
.collect(Collectors.toList()));
|
}
|
}
|
|
/**
|
* 获取积分抵扣现金配置
|
* @param canIntegralCashIdList 可抵扣的商品标识
|
* @return 每张子单抵扣金额数据
|
* */
|
private Map<String, SkuDeductionVo> handlerDeductionMoneyMap(List<String> canIntegralCashIdList
|
,List<OrderItem> orderItemList, BigDecimal integralCash, BigDecimal integralDeduction,String appId) {
|
//积分抵扣现金配置
|
IntegralCashVo integralCashVo = null;
|
//sku标识,最大可抵扣现金
|
Map<String, BigDecimal> skuCashMap = null;
|
Map<String, SkuDeductionVo> skuDeductionVoMap = null;
|
SkuDeductionVo skuDeductionVo = null;
|
try {
|
integralCashVo = ProjectIntegralCashTool.getIntegralCashRate(
|
orderItemList.stream().map(OrderItem::getCommonId).collect(Collectors.toList())
|
, appId, customParameter.getIntegralCashKey(), commonService);
|
}catch (Exception e){
|
logger.error("获取积分抵扣现金配置失败"+ ExceptionTool.getExceptionInfo(e));
|
throw new PlatTipsException(PlatformCode.ERROR_TIPS,"【积分抵扣现金】金额错误【04】");
|
}
|
if (integralCashVo == null){
|
throw new PlatTipsException(PlatformCode.ERROR_TIPS,"【积分抵扣现金】金额错误【05】");
|
}
|
//判断比例是否变更
|
BigDecimal oldRate = integralDeduction.divide(integralCash, 2, RoundingMode.HALF_UP);
|
BigDecimal newRate = integralCashVo.getIntegral().divide(integralCashVo.getCash(), 2, RoundingMode.HALF_UP);
|
logger.info("子单判断,抵扣(积分):{},抵扣(现金):{},抵扣比例(oldRate):{},当前抵扣配置:{},当前比例(newRate):{}"
|
,integralDeduction,integralCash, oldRate, JSON.toJSONString(integralCashVo),newRate);
|
if (oldRate.compareTo(newRate) != 0){
|
throw new PlatTipsException(PlatformCode.ERROR_TIPS,"【积分抵扣现金】金额错误【06】");
|
}
|
skuCashMap = getSkuCashByItemList(canIntegralCashIdList,orderItemList, integralCashVo);
|
if (skuCashMap.size() > 0){
|
skuDeductionVoMap = new HashMap<>();
|
for (Map.Entry<String, BigDecimal> entry : skuCashMap.entrySet()) {
|
skuDeductionVo = new SkuDeductionVo();
|
skuDeductionVo.setSkuId(entry.getKey());
|
skuDeductionVo.setMaxCash(entry.getValue());
|
skuDeductionVo.setMaxIntegralCash(integralCashVo.getIntegral()
|
.multiply(entry.getValue()).divide(integralCashVo.getCash(),0,RoundingMode.DOWN));
|
skuDeductionVoMap.put(entry.getKey(), skuDeductionVo);
|
}
|
}
|
return skuDeductionVoMap;
|
}
|
|
/**
|
* 分配一级子单抵扣金额,方法计算同艾芯荟payDataHandle方法
|
* @param totalDeductionMoney 一级子单总的最大可抵扣现金金额
|
* @param skuDeductionVoMap 每张子单抵扣金额数据
|
* @param orderItemList 要分配的子单
|
* */
|
private BigDecimal handlerDeductionMoney(BigDecimal totalDeductionMoney, Map<String, SkuDeductionVo> skuDeductionVoMap
|
,OrdersTotal ordersTotal,List<OrderItem> orderItemList) {
|
//总的应付
|
logger.info("金额{},优惠券金额{}",ordersTotal.getTotal(),ordersTotal.getCouponTotal());
|
BigDecimal actualTotal = ordersTotal.getTotal().subtract(ordersTotal.getCouponTotal());
|
logger.info("初始应付:"+actualTotal);
|
//总的要抵扣的现金
|
BigDecimal integralCash = ordersTotal.getIntegralCash();
|
if (totalDeductionMoney.compareTo(BigDecimal.ZERO) < 0){
|
throw new TipsException("【积分抵扣现金】金额错误【0888】");
|
}
|
logger.info("积分抵扣数据总:{},map:{}", totalDeductionMoney, JSONObject.toJSONString(skuDeductionVoMap));
|
//排序
|
orderItemList = orderItemList.stream().sorted(Comparator.comparing(OrderItem::getTotal)).collect(Collectors.toList());
|
//校验抵扣金额
|
if (totalDeductionMoney.compareTo(BigDecimal.ZERO) > 0 && skuDeductionVoMap != null) {
|
SkuDeductionVo orderItemDeductionVo = null;
|
OrderItem orderItem = null;
|
//判断前端传值
|
if (totalDeductionMoney.compareTo(integralCash) < 0) {
|
throw new TipsException("【积分抵扣现金】金额错误【07】");
|
}
|
// 已分配的金额
|
BigDecimal totalDeductionMoneySum = BigDecimal.ZERO;
|
// 递归分配数据到每个子单,做死循环处理
|
int forNum = 0;
|
while (totalDeductionMoneySum.compareTo(integralCash) < 0) {
|
if (forNum == 100){
|
throw new TipsException("积分抵扣现金,金额错误【100100】");
|
}
|
// 分摊比例 按照项目数量来分 子单三张,一个买了3个项目,一个买了1个项目,一个买了3个项目 这个时候就是 /7
|
BigDecimal numRate = BigDecimal.ONE;
|
// 要分摊的总购买数量
|
Integer totalBuyNum = skuDeductionVoMap.values().stream().map(a -> a.getBuyNum() == null ? 0 : a.getBuyNum()).reduce(Integer::sum).orElse(0);
|
int size = skuDeductionVoMap.size();
|
logger.info("要循环的子订单最大可抵扣现金Map:" + JSON.toJSONString(skuDeductionVoMap));
|
logger.info("要分摊的总数量{},要循环的次数{}", totalBuyNum, size);
|
if (size <= 0) {
|
break;
|
}
|
//计数位标
|
int index = 1;
|
for (int i = 0; i < orderItemList.size(); i++) {
|
orderItem = orderItemList.get(i);
|
orderItemDeductionVo = skuDeductionVoMap.get(orderItem.getCommonId());
|
if (orderItemDeductionVo == null){
|
logger.info("当前子单已分配完,不参与数量分配");
|
index += 1;
|
continue;
|
}
|
if (index == orderItemList.size()) {
|
orderItemDeductionVo.setSkuNumRate(numRate);
|
} else {
|
orderItemDeductionVo.handlerNum(totalBuyNum);
|
}
|
numRate = numRate.subtract(orderItemDeductionVo.getSkuNumRate()).setScale(2, RoundingMode.HALF_UP);
|
logger.info("循环分摊次数占比位标:{},分摊的比率{},分摊后剩余比率:{}", index, orderItemDeductionVo.getSkuNumRate(), numRate);
|
index += 1;
|
}
|
|
// 剩余总的要分配的金额(用于x比例)
|
BigDecimal itemTotalMoneySum = integralCash.subtract(totalDeductionMoneySum);
|
// 剩余总的要分配的金额(用于计算剩余的)
|
BigDecimal totalMoneySum = integralCash.subtract(totalDeductionMoneySum);
|
logger.info("已分配的总金额:{},当前循环剩余总的要分配的金额:{}:", totalDeductionMoneySum, totalMoneySum);
|
for (int i = 0; i < orderItemList.size(); i++) {
|
orderItem = orderItemList.get(i);
|
logger.info("{}分配前,分配了的金额:{}", orderItem.getId(), orderItem.getIntegralCash());
|
orderItemDeductionVo = skuDeductionVoMap.get(orderItem.getCommonId());
|
//如果满了被排除了,则直接到下个子单
|
if (orderItemDeductionVo == null) {
|
logger.info("{}已分配满金额",orderItem.getId());
|
continue;
|
}
|
BigDecimal addMoney = null;
|
//计算分配的按实际要抵扣的金额计算:【抵扣金额x子单数量占比】 < 【最大可抵扣】,则可以全部抵扣,计算还能分配的数据;否则最大就是【最大可抵扣】,多余的往下匀,加回剩余数量
|
BigDecimal reteMoney = itemTotalMoneySum.multiply(orderItemDeductionVo.getSkuNumRate()).setScale(2, RoundingMode.UP);
|
logger.info("子单数量占比算出的分配金额:{},剩余总的可分配金额:{}", reteMoney, totalMoneySum);
|
// 最后一个
|
if (size == 1) {
|
addMoney = reteMoney;
|
} else {
|
logger.info("子单数量占比算出的分配金额:{},子单最大可分配金额:{},子单剩余可分配金额{}", reteMoney, orderItemDeductionVo.getSkuMaxCash(), orderItemDeductionVo.getCash());
|
if (reteMoney.compareTo(orderItemDeductionVo.getCash()) < 0) {
|
// 剩余可分配足够,则分配数量占比金额
|
addMoney = reteMoney;
|
} else {
|
addMoney = orderItemDeductionVo.getCash();
|
}
|
}
|
if (orderItem.getIntegralCash().add(addMoney).compareTo(orderItem.getActualTotal()) > 0){
|
addMoney = orderItem.getActualTotal().subtract(orderItem.getIntegralCash());
|
}
|
//如果要分配的大于剩余的,用剩余的
|
if (totalMoneySum.compareTo(addMoney) < 0){
|
addMoney = totalMoneySum;
|
}
|
totalMoneySum = totalMoneySum.subtract(addMoney);
|
//分配金额
|
orderItem.setIntegralCash(orderItem.getIntegralCash().add(addMoney));
|
totalDeductionMoneySum = totalDeductionMoneySum.add(addMoney);
|
actualTotal = actualTotal.subtract(addMoney);
|
logger.info("循环计算应付:"+actualTotal);
|
//计算剩余可分配
|
orderItemDeductionVo.handlerCash(orderItem.getIntegralCash());
|
logger.info("{}分配后,分配了的金额:{},剩余可分配金额{}", orderItem.getId(), orderItem.getIntegralCash(), orderItemDeductionVo.getCash());
|
if (orderItem.getIntegralCash().compareTo(orderItem.getActualTotal()) == 0 ||
|
orderItemDeductionVo.getCash().compareTo(BigDecimal.ZERO) <= 0) {
|
logger.info("{}分配完金额,剔除", orderItem.getId());
|
skuDeductionVoMap.remove(orderItem.getCommonId());
|
}
|
}
|
forNum += 1;
|
}
|
if (totalDeductionMoneySum.compareTo(integralCash) != 0) {
|
logger.info("积分抵扣现金金额错误,错误代码【08】,计算分配的金额:{},支付抵扣金额{}", totalDeductionMoneySum, integralCash);
|
throw new TipsException("积分抵扣现金金额错误,错误代码【08】");
|
}
|
}
|
logger.info("orderItemList"+JSON.toJSONString(orderItemList));
|
return actualTotal;
|
}
|
|
/**一级订单积分处理*/
|
private void integralOneHandle(OrdersTotal ordersTotal,OrderCarryVo orderCarryVo,List<OrderItem> orderItemList){
|
|
//-----四舍五入的原因,先排序,先算小的,再算大的,因为如果除不尽,那么都会进1积分,那么就导致了后面的如果刚刚好,而前面的多扣了一积分,导致会少积分
|
orderItemList = orderItemList.stream().sorted(Comparator.comparing(OrderItem::getTotalPoints))
|
.collect(Collectors.toList());
|
|
//占比
|
BigDecimal proportion;
|
OrderItem orderItem;
|
//子订单剩余应付积分,分配支付记录用到
|
BigDecimal surplusIntegral;
|
for(int i=0;i<orderItemList.size();i++) {
|
orderItem = orderItemList.get(i);
|
orderItem.setConsumePayIntegralItemList(new ArrayList<>());
|
|
//赋值计算
|
orderItem.setShouldTotalPoints(orderItem.getTotalPoints());
|
|
//计算比例
|
if (ordersTotal.getShouldTotalPoints().compareTo(BigDecimal.ZERO) > 0) {
|
proportion = orderItem.getShouldTotalPoints().divide(ordersTotal.getShouldTotalPoints(), 15, RoundingMode.HALF_UP);
|
} else {
|
proportion = BigDecimal.ZERO;
|
}
|
|
////////平摊支付记录,注意除不尽的问题
|
surplusIntegral = orderItem.getShouldTotalPoints();
|
//设置初始化值
|
orderItem.setActualTotalPoints(BigDecimal.ZERO);
|
ConsumePay consumePay;
|
for (int j = 0; j < orderCarryVo.getConsumePayIntegralList().size(); j++) {
|
consumePay = orderCarryVo.getConsumePayIntegralList().get(j);
|
|
if (consumePay.getpTotal().compareTo(BigDecimal.ZERO) <= 0
|
|| surplusIntegral.compareTo(BigDecimal.ZERO) <= 0) {
|
continue;
|
}
|
//生成子单的支付记录
|
ConsumePayItem consumePayItem = new ConsumePayItem();
|
BeanUtils.copyProperties(consumePay, consumePayItem);
|
consumePayItem.setType(ConsumePayItem.TYPE_ORDER_ITEM);
|
consumePayItem.setTypeId(orderItem.getId());
|
consumePayItem.setConsumePayId(consumePay.getId());
|
//计算支付方式的积分
|
if (i == orderItemList.size() - 1) {
|
//最后一个子单,把剩下未分配的支付方式金额全部放进去
|
consumePayItem.setActualTotal(consumePay.getpTotal());
|
} else {
|
if (j == orderCarryVo.getConsumePayIntegralList().size() - 1) {
|
//支付方式的最后一个,把剩下未分配的应付积分全部放进去
|
consumePayItem.setActualTotal(surplusIntegral);
|
} else {
|
////四舍五入规则,有余数都进一积分
|
consumePayItem.setActualTotal(consumePayItem.getActualTotal().multiply(proportion).setScale(0, RoundingMode.UP));
|
}
|
}
|
|
//如果分配的积分比剩余的积分多,那么就用剩余的金额/积分
|
if (consumePay.getpTotal().compareTo(consumePayItem.getActualTotal()) < 0) {
|
consumePayItem.setActualTotal(consumePay.getpTotal());
|
}
|
|
//如果分配的金额比剩余应付金额多,那就就用剩余应付金额
|
if (surplusIntegral.compareTo(consumePayItem.getActualTotal()) < 0) {
|
consumePayItem.setActualTotal(surplusIntegral);
|
}
|
//计算剩余的应付金额
|
surplusIntegral = surplusIntegral.subtract(consumePayItem.getActualTotal()).setScale(2, RoundingMode.HALF_UP);
|
|
//支付总积分
|
orderItem.setActualTotalPoints(orderItem.getActualTotalPoints().add(consumePayItem.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
|
//计算剩余可分配的积分
|
consumePay.setpTotal(consumePay.getpTotal().subtract(consumePayItem.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
|
//保存平摊支付方式
|
consumePayItemMapper.insert(consumePayItem);
|
//设置未分配积分
|
consumePayItem.setpTotal(consumePayItem.getActualTotal());
|
orderItem.getConsumePayItemList().add(consumePayItem);
|
orderItem.getConsumePayIntegralItemList().add(consumePayItem);
|
|
}
|
//支付方式进行升序排序,避免循环支付方式的时候最后一个可分配0积分,从而导致算子单最后一个的时候没有钱算了
|
orderCarryVo.setConsumePayIntegralList(orderCarryVo.getConsumePayIntegralList().stream().sorted(Comparator.comparing(ConsumePay::getpTotal))
|
.collect(Collectors.toList()));
|
}
|
}
|
|
/**二级子单信息处理*/
|
private void orderItemSonHandle(OrdersTotal ordersTotal,OrderItem orderItem,boolean updateUserProject){
|
|
if(orderItem.getConsumePayItemList() == null){
|
orderItem.setConsumePayItemList(new ArrayList<>());
|
}
|
if(orderItem.getConsumePayMoneyItemList() == null){
|
orderItem.setConsumePayMoneyItemList(new ArrayList<>());
|
}
|
if(orderItem.getConsumePayIntegralItemList() == null){
|
orderItem.setConsumePayIntegralItemList(new ArrayList<>());
|
}
|
|
SqlSentence sqlSentence = new SqlSentence();
|
Map<String,Object> values = new HashMap<>();
|
|
//获取二级子订单
|
values.put("orderItemId",orderItem.getId());
|
sqlSentence.sqlSentence("SELECT * FROM order_item_source WHERE isDel = 0 AND orderItemId = #{m.orderItemId}",values);
|
List<OrderItemSon> orderItemSonList = orderItemSonMapper.selectList(sqlSentence);
|
if(orderItemSonList.size() == 0){
|
return;
|
}
|
|
if (OrderItemConstants.TYPE_PROMOTION.equals(orderItem.getType())) {
|
//促销处理
|
twoHandle(ordersTotal,orderItem,orderItemSonList,updateUserProject);
|
}else if(OrderItemConstants.CARD_BAG.equals(orderItem.getType())) {
|
//卡项处理
|
//cardBagTwohandle(ordersTotal,orderItem,orderItemSonList,updateUserProject);
|
//卡项处理-含商品处理版本
|
cardBagTwoHandle(ordersTotal,orderItem,orderItemSonList,updateUserProject);
|
}
|
}
|
|
/**二级订单处理-常规处理*/
|
private void twoHandle(OrdersTotal ordersTotal,OrderItem orderItem,List<OrderItemSon> orderItemSonList,boolean updateUserProject){
|
SqlSentence sqlSentence = new SqlSentence();
|
Map<String,Object> values = new HashMap<>();
|
sqlSentence.setM(values);
|
|
//金额处理
|
moneyTwoHandle(orderItem,orderItemSonList);
|
//积分处理
|
integralTwoHandle(orderItem,orderItemSonList);
|
|
UserProjectItem userProjectItem;
|
for(OrderItemSon orderItemSon:orderItemSonList){
|
if (orderItemSon.getIntegralCash().compareTo(BigDecimal.ZERO) != 0){
|
orderItemSon.setIntegralDeduction(orderItemSon.getIntegralCash().multiply(ordersTotal.getIntegralDeduction())
|
.divide(ordersTotal.getIntegralCash(),2,RoundingMode.HALF_UP));
|
}else {
|
orderItemSon.setIntegralDeduction(BigDecimal.ZERO);
|
}
|
//已支付数据
|
orderItemSon.setActualTotalPoints(orderItemSon.getActualTotalPoints().add(orderItemSon.getIntegralDeduction()).setScale(2, RoundingMode.HALF_UP));
|
|
//变更
|
values.clear();
|
values.put("actualTotal", orderItemSon.getActualTotal());
|
values.put("discountPrice", orderItemSon.getDiscountPrice());
|
values.put("couponTotal", orderItemSon.getCouponTotal());
|
values.put("preferentialTotal", orderItemSon.getPreferentialTotal());
|
values.put("payTotal", orderItemSon.getPayTotal());
|
values.put("payRecharge", orderItemSon.getPayRecharge());
|
values.put("payIncrement", orderItemSon.getPayIncrement());
|
values.put("snapPayTotal", orderItemSon.getSnapPayTotal());
|
values.put("noDeductionAmount", orderItemSon.getNoDeductionAmount());
|
values.put("actualTotalPoints", orderItemSon.getActualTotalPoints());
|
values.put("id", orderItemSon.getId());
|
values.put("integralCash", orderItemSon.getIntegralCash());
|
values.put("integralDeduction", orderItemSon.getIntegralDeduction());
|
sqlSentence.setSqlSentence("actualTotal=#{m.actualTotal},noDeductionAmount=#{m.noDeductionAmount}" +
|
",discountPrice=#{m.discountPrice},couponTotal=#{m.couponTotal},preferentialTotal=#{m.preferentialTotal}" +
|
",payTotal=#{m.payTotal},payRecharge=#{m.payRecharge},payIncrement=#{m.payIncrement},snapPayTotal=#{m.snapPayTotal}" +
|
",actualTotalPoints = #{m.actualTotalPoints},integralDeduction = #{m.integralDeduction},integralCash = #{m.integralCash}" +
|
" WHERE id=#{m.id}");
|
orderItemSonMapper.updateWhere(sqlSentence);
|
|
//用户项目
|
if (OrderItemConstants.TYPE_PROJECT.equals(orderItemSon.getType())) {
|
if(updateUserProject){
|
//获取用户项目
|
userProjectItem = getUserProjectItem(orderItemSon.getId(), ordersTotal.getUserId());
|
updateUserProject(userProjectItem, orderItemSon.getTotal(), orderItemSon.getActualTotal(), orderItemSon.getOriPrice()
|
, orderItemSon.getCurPrice(), orderItemSon.getBuyNum(), orderItemSon.getNoDeductionAmount(), orderItemSon.getUsedTotal()
|
, null);
|
}
|
|
}
|
}
|
}
|
|
/**二级订单金额处理-常规处理*/
|
private void moneyTwoHandle(OrderItem orderItem,List<OrderItemSon> orderItemSonList){
|
/////因为要判断最后一个原因,四舍五入的原因,先排序,先算小的,再算大的,因为如果除不尽,那么都会进1分,那么就导致了后面的如果刚刚好,而前面的多扣了一分,导致会少钱
|
orderItemSonList = orderItemSonList.stream().sorted(Comparator.comparing(OrderItemSon::getTotal))
|
.collect(Collectors.toList());
|
//比例
|
BigDecimal rateCash = orderItem.getIntegralCash();
|
BigDecimal rateDeduction = orderItem.getIntegralDeduction();
|
logger.info("处理二级子单,对应一级子单{},现金{},积分{}",JSON.toJSONString(orderItem),rateCash,rateDeduction);
|
//剩余可分配的活动优惠金额
|
BigDecimal shareActivityTotal = BigDecimal.ZERO;
|
//剩余未分配优惠券金额
|
BigDecimal shareCouponTotal = orderItem.getCouponTotal();
|
//剩余未分配优惠福利金额
|
BigDecimal sharePreferentialTotalTotal = orderItem.getPreferentialTotal();
|
|
if(orderItem.getActivityPrice() != null){
|
shareActivityTotal = orderItem.getActivityPrice();
|
}
|
//占比
|
BigDecimal proportion = null;
|
//数量占比
|
BigDecimal numProportion = null;;
|
OrderItemSon orderItemSon;
|
//子订单剩余应付金额
|
BigDecimal surplusTotal;
|
//二级子订单购买数量
|
Integer totalBuyNum = orderItemSonList.stream().map(a -> a.getBuyNum() == null ? 0 : a.getBuyNum()).reduce(Integer::sum).orElse(0);
|
logger.info("处理二级子单,购买总数量"+totalBuyNum);
|
//抵扣支付方式
|
List<ConsumePayItem> dkList = null;
|
for(int i = 0;i<orderItemSonList.size();i++) {
|
orderItemSon = orderItemSonList.get(i);
|
//先赋值
|
orderItemSon.setActualTotal(orderItemSon.getTotal());
|
|
//处理促销,将促销的项目生成未划扣记录,商品生成提货单,增值金、储值金、积分给用户添加上
|
//计算二级子单的金额占比
|
if (orderItem.getTotal().compareTo(BigDecimal.ZERO) > 0) {
|
proportion = orderItemSon.getTotal().divide(orderItem.getTotal(), 15, RoundingMode.HALF_UP);
|
} else {
|
proportion = BigDecimal.ZERO;
|
}
|
|
//活动优惠金额和优惠券金额
|
//二级子订单优惠券抵扣金额=二级子订单售价 * 一级子订单优惠券占比,如果是最后一次那么就用优惠券总金额-已分摊总金额
|
if (i == orderItemSonList.size() - 1) {
|
orderItemSon.setActivityPrice(shareActivityTotal);
|
orderItemSon.setCouponTotal(shareCouponTotal);
|
orderItemSon.setPreferentialTotal(sharePreferentialTotalTotal);
|
} else {
|
//【活动优惠金额】四舍五入规则,有余数都进一分钱
|
orderItemSon.setActivityPrice(orderItem.getActivityPrice().multiply(proportion).setScale(2, RoundingMode.UP));
|
if (shareActivityTotal.compareTo(orderItemSon.getActivityPrice()) < 0) {
|
//分配的的优惠金额如果大于剩余未分配优惠金额
|
orderItemSon.setActivityPrice(shareActivityTotal);
|
}
|
|
//【优惠券金额】四舍五入规则,有余数都进一分钱
|
orderItemSon.setCouponTotal(orderItem.getCouponTotal().multiply(proportion).setScale(2, RoundingMode.UP));
|
if (shareCouponTotal.compareTo(orderItemSon.getCouponTotal()) < 0) {
|
//分配的的优惠金额如果大于剩余未分配优惠金额
|
orderItemSon.setCouponTotal(shareCouponTotal);
|
}
|
|
//【优惠福利金额】四舍五入规则,有余数都进一分钱
|
orderItemSon.setPreferentialTotal(orderItem.getPreferentialTotal().multiply(proportion).setScale(2, RoundingMode.UP));
|
if (sharePreferentialTotalTotal.compareTo(orderItemSon.getPreferentialTotal()) < 0) {
|
//分配的的优惠金额如果大于剩余未分配优惠金额
|
orderItemSon.setPreferentialTotal(sharePreferentialTotalTotal);
|
}
|
|
}
|
|
//【活动优惠金额】分配的的优惠金额如果大于优惠前小计
|
if (orderItemSon.getActualTotal().compareTo(orderItemSon.getActivityPrice()) < 0) {
|
orderItemSon.setActivityPrice(orderItemSon.getActualTotal());
|
}
|
//优惠后小计
|
orderItemSon.setActualTotal(orderItemSon.getActualTotal().subtract(orderItemSon.getActivityPrice()));
|
|
//【优惠券金额】分配的的优惠金额如果大于优惠前小计
|
if (orderItemSon.getActualTotal().compareTo(orderItemSon.getCouponTotal()) < 0) {
|
orderItemSon.setCouponTotal(orderItemSon.getActualTotal());
|
}
|
//优惠后小计
|
orderItemSon.setActualTotal(orderItemSon.getActualTotal().subtract(orderItemSon.getCouponTotal()));
|
|
//【优惠福利金额】分配的的优惠金额如果大于优惠前小计
|
if (orderItemSon.getActualTotal().compareTo(orderItemSon.getPreferentialTotal()) < 0) {
|
orderItemSon.setPreferentialTotal(orderItemSon.getActualTotal());
|
}
|
orderItemSon.setActualTotal(orderItemSon.getActualTotal().subtract(orderItemSon.getPreferentialTotal()));
|
|
//总优惠金额 = 优惠券金额 + 优惠福利金额
|
orderItemSon.setDiscountPrice(orderItemSon.getCouponTotal().add(orderItemSon.getPreferentialTotal()));
|
|
//已分配的活动金额
|
shareActivityTotal = shareActivityTotal.subtract(orderItemSon.getActivityPrice());
|
//已分配的优惠金额
|
shareCouponTotal = shareCouponTotal.subtract(orderItemSon.getCouponTotal());
|
//已分配的优惠福利金额
|
sharePreferentialTotalTotal = sharePreferentialTotalTotal.subtract(orderItemSon.getPreferentialTotal());
|
|
//应付金额如果是负数变0
|
if (orderItemSon.getActualTotal().compareTo(BigDecimal.ZERO) < 0) {
|
orderItemSon.setActualTotal(BigDecimal.ZERO);
|
}
|
}
|
|
//一级子单剩余应付
|
BigDecimal actualTotal = orderItem.getActualTotal();
|
//剩余未分配抵扣金额金额
|
BigDecimal integralCash = orderItem.getIntegralCash();
|
int num = 10;
|
while (integralCash.compareTo(BigDecimal.ZERO) > 0){
|
if (num > 100){
|
logger.info("剩余分配的金额::::::"+integralCash);
|
throw new TipsException("金额分配错误");
|
}
|
logger.info("剩余分配金额:"+integralCash);
|
BigDecimal addMoney = BigDecimal.ZERO;
|
for(int i = 0;i<orderItemSonList.size();i++) {
|
orderItemSon = orderItemSonList.get(i);
|
if ((orderItemSon.getActualTotal().subtract(orderItemSon.getIntegralCash())).compareTo(BigDecimal.ZERO) == 0){
|
continue;
|
}
|
if (totalBuyNum > 0){
|
numProportion = new BigDecimal(orderItemSon.getBuyNum()).divide(new BigDecimal(totalBuyNum), 15, RoundingMode.HALF_UP);
|
}else {
|
numProportion = BigDecimal.ZERO;
|
}
|
if (i == orderItemSonList.size() - 1) {
|
addMoney = integralCash;
|
} else {
|
//四舍五入规则,有余数都进一分钱
|
addMoney = orderItem.getIntegralCash().multiply(numProportion).setScale(2, RoundingMode.UP);
|
if (integralCash.compareTo(addMoney) < 0) {
|
//分配的的金额如果大于剩余未分配金额
|
addMoney = integralCash;
|
}
|
}
|
logger.info("当前应付{},已分配抵扣{},要加的钱{}",orderItemSon.getActualTotal(),orderItemSon.getIntegralCash(),addMoney);
|
//如果按数量分配的抵扣金额大于应付 则用应付
|
if (orderItemSon.getActualTotal().compareTo(orderItemSon.getIntegralCash().add(addMoney)) < 0){
|
addMoney = orderItemSon.getActualTotal().subtract(orderItemSon.getIntegralCash());
|
}
|
logger.info("实际加的钱{}:",addMoney);
|
orderItemSon.setIntegralCash(orderItemSon.getIntegralCash().add(addMoney));
|
//已分配的抵扣金额
|
integralCash = integralCash.subtract(addMoney);
|
actualTotal = actualTotal.subtract(addMoney);
|
}
|
num +=1;
|
}
|
|
for(int i = 0;i<orderItemSonList.size();i++) {
|
orderItemSon = orderItemSonList.get(i);
|
logger.info("分配完抵扣金额的orderItemSon:"+JSON.toJSONString(orderItemSon));
|
ConsumePayItem payItem;
|
//先计算抵扣的数据,再分摊
|
dkList = orderItem.getConsumePayMoneyItemList().stream().filter(a
|
-> a.getNumberNo().equals(PayMethodTypeConstants.PAY_INTEGRAL_CASH)).collect(Collectors.toList());
|
if (dkList.size() > 0){
|
payItem = dkList.get(0);
|
logger.info("积分抵扣的数据:"+JSON.toJSONString(payItem));
|
if (orderItemSon.getIntegralCash().compareTo(BigDecimal.ZERO) > 0){
|
//处理积分抵扣现金支付方式
|
orderItemSon.setIntegralDeduction(orderItemSon.getIntegralCash().multiply(rateDeduction).divide(rateCash,2,RoundingMode.HALF_UP));
|
//处理积分抵扣现金支付方式,生成子单的支付记录
|
ConsumePayItemSon consumePayItemSon = new ConsumePayItemSon();
|
consumePayItemSon.setNumberNo(payItem.getNumberNo());
|
consumePayItemSon.setName(payItem.getName());
|
consumePayItemSon.setActualTotal(orderItemSon.getIntegralCash());
|
consumePayItemSon.setDeductionType(ConsumePayConstants.DEDUCTION_INTEGRAL_CASH);
|
consumePayItemSon.setDeductionMoney(orderItemSon.getIntegralDeduction());
|
consumePayItemSon.setIsMoneyPay(payItem.getIsMoneyPay());
|
consumePayItemSon.setIsExecute(payItem.getIsExecute());
|
consumePayItemSon.setIsPay(payItem.getIsPay());
|
consumePayItemSon.setPaymentMethodId(payItem.getPaymentMethodId());
|
consumePayItemSon.setType(ConsumePayItem.TYPE_ORDER_ITEM_SON);
|
consumePayItemSon.setTypeId(orderItemSon.getId());
|
consumePayItemSon.setOrderId(orderItem.getOrderId());
|
consumePayItemSon.setOrderItemId(orderItem.getId());
|
consumePayItemSon.setReConsumeId(payItem.getReConsumeId());
|
consumePayItemSon.setConsumePayItemId(payItem.getId());
|
consumePayItemSon.setConsumePayId(payItem.getConsumePayId());
|
//保存平摊支付方式
|
consumePayItemSonMapper.insert(consumePayItemSon);
|
//现金金额
|
if (consumePayItemSon.getIsMoneyPay().equals(ConsumePay.YES)) {
|
orderItemSon.setSnapPayTotal(orderItemSon.getSnapPayTotal().add(consumePayItemSon.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
//划扣金额
|
if (consumePayItemSon.getIsExecute().equals(ConsumePay.YES)) {
|
orderItemSon.setNoDeductionAmount(orderItemSon.getNoDeductionAmount().add(consumePayItemSon.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
}
|
}
|
|
////////平摊支付记录
|
surplusTotal = orderItemSon.getActualTotal().subtract(orderItemSon.getIntegralCash());
|
logger.info("二级子单,应付:{},抵扣:{},活动:{},优惠:{}",surplusTotal,orderItemSon.getIntegralCash(),orderItemSon.getActivityPrice(),orderItemSon.getDiscountPrice());
|
if (surplusTotal.compareTo(BigDecimal.ZERO) < 0){
|
throw new TipsException("抵扣金额分配错误[071]");
|
}
|
|
//重新算一遍比例,更准确
|
if (actualTotal.compareTo(BigDecimal.ZERO) > 0) {
|
proportion = (orderItemSon.getActualTotal().subtract(orderItemSon.getIntegralCash())).divide(actualTotal, 15, RoundingMode.HALF_UP);
|
}else {
|
proportion = BigDecimal.ZERO;
|
}
|
//设置初始化值
|
orderItemSon.setPayTotal(BigDecimal.ZERO);
|
orderItemSon.setPayIncrement(BigDecimal.ZERO);
|
orderItemSon.setPayRecharge(BigDecimal.ZERO);
|
orderItemSon.setSnapPayTotal(BigDecimal.ZERO);
|
orderItemSon.setNoDeductionAmount(BigDecimal.ZERO);
|
for (int j = 0; j < orderItem.getConsumePayMoneyItemList().size(); j++) {
|
payItem = orderItem.getConsumePayMoneyItemList().get(j);
|
if (payItem.getNumberNo().equals(PayMethodTypeConstants.PAY_INTEGRAL_CASH)){
|
continue;
|
}
|
if (payItem.getpTotal().compareTo(BigDecimal.ZERO) <= 0
|
|| surplusTotal.compareTo(BigDecimal.ZERO) <= 0) {
|
continue;
|
}
|
//生成二级单的支付记录
|
ConsumePayItemSon consumePayItemSon = new ConsumePayItemSon();
|
BeanUtils.copyProperties(payItem, consumePayItemSon);
|
consumePayItemSon.setType(ConsumePayItem.TYPE_ORDER_ITEM_SON);
|
consumePayItemSon.setTypeId(orderItemSon.getId());
|
consumePayItemSon.setConsumePayId(payItem.getConsumePayId());
|
consumePayItemSon.setConsumePayItemId(consumePayItemSon.getId());
|
//填充关联订单
|
consumePayItemSon.setOrderId(orderItem.getOrderId());
|
consumePayItemSon.setOrderItemId(orderItem.getId());
|
//计算支付方式的金额/积分
|
if (i == orderItemSonList.size() - 1) {
|
//最后一个子单,把剩下未分配的支付方式金额放进去
|
consumePayItemSon.setActualTotal(payItem.getpTotal());
|
} else {
|
if (j == orderItem.getConsumePayMoneyItemList().size() - 1) {
|
//支付方式的最后一个,把剩下未分配的应付金额全部放进去
|
consumePayItemSon.setActualTotal(surplusTotal);
|
} else {
|
//四舍五入规则,有余数都进一分钱
|
consumePayItemSon.setActualTotal(payItem.getActualTotal().multiply(proportion).setScale(2, RoundingMode.UP));
|
}
|
}
|
|
//如果分配的金额/积分比剩余的积分多,那么就用剩余的金额/积分
|
if (payItem.getpTotal().compareTo(consumePayItemSon.getActualTotal()) < 0) {
|
consumePayItemSon.setActualTotal(payItem.getpTotal());
|
}
|
////支付方式问题,积分也算钱
|
////金额计算
|
//如果分配的积分比剩余应付积分多,那就就用剩余应付积分
|
if (surplusTotal.compareTo(consumePayItemSon.getActualTotal()) < 0) {
|
consumePayItemSon.setActualTotal(surplusTotal);
|
}
|
//计算剩余可分配的金额
|
payItem.setpTotal(payItem.getpTotal().subtract(consumePayItemSon.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
//计算剩余的应付金额
|
surplusTotal = surplusTotal.subtract(consumePayItemSon.getActualTotal()).setScale(2, RoundingMode.HALF_UP);
|
|
if (PayMethodTypeConstants.PAY_ADD_FUND.equals(consumePayItemSon.getNumberNo())) {
|
//增值金
|
orderItemSon.setPayIncrement(orderItemSon.getPayIncrement().add(consumePayItemSon.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
} else if (PayMethodTypeConstants.PAY_STORED.equals(consumePayItemSon.getNumberNo())) {
|
//储值金
|
orderItemSon.setPayRecharge(orderItemSon.getPayRecharge().add(consumePayItemSon.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
} else {
|
//其他金额
|
orderItemSon.setPayTotal(orderItemSon.getPayTotal().add(consumePayItemSon.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
//现金金额
|
if (consumePayItemSon.getIsMoneyPay().equals(ConsumePay.YES)) {
|
orderItemSon.setSnapPayTotal(orderItemSon.getSnapPayTotal().add(consumePayItemSon.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
//划扣金额
|
if (consumePayItemSon.getIsExecute().equals(ConsumePay.YES)) {
|
orderItemSon.setNoDeductionAmount(orderItemSon.getNoDeductionAmount().add(consumePayItemSon.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
}
|
|
consumePayItemSonMapper.insert(consumePayItemSon);
|
|
}
|
}
|
|
|
}
|
|
/**二级订单积分处理-常规处理*/
|
private void integralTwoHandle(OrderItem orderItem,List<OrderItemSon> orderItemSonList){
|
/////因为要判断最后一个原因,四舍五入的原因,先排序,先算小的,再算大的,因为如果除不尽,那么都会进1积分,那么就导致了后面的如果刚刚好,而前面的多扣了一积分,导致会少积分
|
orderItemSonList = orderItemSonList.stream().sorted(Comparator.comparing(OrderItemSon::getTotalPoints))
|
.collect(Collectors.toList());
|
|
//占比
|
BigDecimal proportion;
|
OrderItemSon orderItemSon;
|
//子订单剩余应付金额
|
BigDecimal surplusIntegral;
|
for(int i = 0;i<orderItemSonList.size();i++) {
|
orderItemSon = orderItemSonList.get(i);
|
|
//先赋值
|
orderItemSon.setShouldTotalPoints(orderItemSon.getTotalPoints());
|
|
//重比例,更准确
|
if (orderItem.getShouldTotalPoints().compareTo(BigDecimal.ZERO) > 0) {
|
proportion = orderItemSon.getShouldTotalPoints().divide(orderItem.getShouldTotalPoints(), 15, RoundingMode.HALF_UP);
|
}else{
|
proportion = BigDecimal.ZERO;
|
}
|
|
////////平摊支付记录
|
surplusIntegral = orderItemSon.getShouldTotalPoints();
|
//设置初始化值
|
orderItemSon.setActualTotalPoints(BigDecimal.ZERO);
|
ConsumePayItem payItem;
|
for (int j = 0; j < orderItem.getConsumePayIntegralItemList().size(); j++) {
|
payItem = orderItem.getConsumePayIntegralItemList().get(j);
|
if (payItem.getpTotal().compareTo(BigDecimal.ZERO) <= 0
|
|| surplusIntegral.compareTo(BigDecimal.ZERO) <= 0) {
|
continue;
|
}
|
//生成二级单的支付记录
|
ConsumePayItemSon consumePayItemSon = new ConsumePayItemSon();
|
BeanUtils.copyProperties(payItem, consumePayItemSon);
|
consumePayItemSon.setType(ConsumePayItem.TYPE_ORDER_ITEM_SON);
|
consumePayItemSon.setTypeId(orderItemSon.getId());
|
consumePayItemSon.setConsumePayId(payItem.getConsumePayId());
|
consumePayItemSon.setConsumePayItemId(consumePayItemSon.getId());
|
//计算支付方式的积分
|
if (i == orderItemSonList.size() - 1) {
|
//最后一个子单,把剩下未分配的支付方式积分放进去
|
consumePayItemSon.setActualTotal(payItem.getpTotal());
|
} else {
|
if (j == orderItem.getConsumePayMoneyItemList().size() - 1) {
|
//支付方式的最后一个,把剩下未分配的应付积分全部放进去
|
consumePayItemSon.setActualTotal(surplusIntegral);
|
} else {
|
//四舍五入规则,有余数都进一积分
|
consumePayItemSon.setActualTotal(payItem.getActualTotal().multiply(proportion).setScale(0, RoundingMode.UP));
|
}
|
}
|
|
//如果分配的积分比剩余的积分多,那么就用剩余的积分
|
if (payItem.getpTotal().compareTo(consumePayItemSon.getActualTotal()) < 0) {
|
consumePayItemSon.setActualTotal(payItem.getpTotal());
|
}
|
////支付方式问题,积分也算钱
|
////金额计算
|
//如果分配的积分比剩余应付积分多,那就就用剩余应付积分
|
if (surplusIntegral.compareTo(consumePayItemSon.getActualTotal()) < 0) {
|
consumePayItemSon.setActualTotal(surplusIntegral);
|
}
|
//计算剩余可分配的金额
|
payItem.setpTotal(payItem.getpTotal().subtract(consumePayItemSon.getActualTotal()).setScale(2, RoundingMode.HALF_UP));
|
//计算剩余的应付金额
|
surplusIntegral = surplusIntegral.subtract(consumePayItemSon.getActualTotal()).setScale(2, RoundingMode.HALF_UP);
|
|
//积分处理
|
orderItemSon.setActualTotalPoints(orderItemSon.getActualTotalPoints().add(consumePayItemSon.getActualTotal()));
|
|
consumePayItemSonMapper.insert(consumePayItemSon);
|
}
|
}
|
}
|
|
/**二级订单积分处理-卡包处理*/
|
private void cardBagTwohandle(OrdersTotal ordersTotal,OrderItem orderItem,List<OrderItemSon> orderItemSonList,boolean updateUserProject){
|
|
/////因为要判断最后一个原因,四舍五入的原因,先排序,先算小的,再算大的,因为如果除不尽,那么都会进1分,那么就导致了后面的如果刚刚好,而前面的多扣了一分,导致会少钱
|
orderItemSonList = orderItemSonList.stream().sorted(Comparator.comparing(OrderItemSon::getTotal))
|
.collect(Collectors.toList());
|
|
SqlSentence sqlSentence = new SqlSentence();
|
Map<String,Object> values = new HashMap<>();
|
|
//占比
|
BigDecimal proportion;
|
UserProjectItem userProjectItem;
|
OrderItemSon orderItemSon;
|
UserCard userCard;
|
OrderItem orderItemBuy;
|
CardItem cardItem;
|
CardItemInfo cardItemInfo;
|
BigDecimal sumCardBagMoney;
|
BigDecimal curPrice;
|
for (OrderItemSon itemSon : orderItemSonList) {
|
orderItemSon = itemSon;
|
|
//先赋值
|
orderItemSon.setActualTotal(orderItemSon.getTotal());
|
|
//不是项目不处理
|
if (!OrderItemConstants.TYPE_PROJECT.equals(orderItemSon.getType())) {
|
continue;
|
}
|
|
orderItemSon.setNoDeductionAmount(BigDecimal.ZERO);
|
|
//获取用户卡项
|
userCard = userCardMapper.selectOneByKey(orderItem.getUserCardId());
|
if (userCard == null) {
|
continue;
|
}
|
if (StringUtils.noNull(userCard.getSourceId())) {
|
orderItemBuy = orderItemMapper.selectOneByKey(userCard.getSourceId());
|
} else {
|
//获取当时购买这个卡包的订单子单
|
values.clear();
|
values.put("orderId", userCard.getOrderId());
|
values.put("commonId", userCard.getCardItemId());
|
sqlSentence.sqlSentence("SELECT * FROM order_item WHERE isDel = 0 AND orderId = #{m.orderId} AND commonId = #{m.commonId} LIMIT 1", values);
|
orderItemBuy = orderItemMapper.selectOne(sqlSentence);
|
if (orderItemBuy != null) {
|
//更新用户项目关联的订单
|
values.put("sourceType", UserCard.SOURCE_TYPE_ORDER_ONE);
|
values.put("sourceId", orderItemBuy.getId());
|
values.put("id", userCard.getId());
|
sqlSentence.sqlUpdate("sourceType = #{m.sourceType},sourceId = #{m.sourceId} WHERE id = #{m.id}", values);
|
userCardMapper.updateWhere(sqlSentence);
|
}
|
}
|
|
if (orderItemBuy == null) {
|
continue;
|
}
|
if (orderItemBuy.getNoDeductionAmount() == null) {
|
orderItemBuy.setNoDeductionAmount(BigDecimal.ZERO);
|
}
|
|
//获取卡项
|
cardItem = cardItemMapper.selectOneByKey(userCard.getCardItemId());
|
if (cardItem == null) {
|
continue;
|
}
|
|
///////二级子订单是项目
|
////划扣金额算法:
|
//1.获取购买卡项时候订单分配的可划扣金额
|
//2.根据卡包对应的卡项,算当前抵扣次数分摊的抵扣金额,再根据抵扣金额去和总平摊金额进行求比例
|
//3.根据比例乘以[1]的可划扣金额得出当前可划扣金额
|
//查询卡项明细
|
cardItemInfo = cardItemInfoMapper.selectOneByKey(orderItemSon.getCardItemInfoId());
|
if (cardItemInfo == null) {
|
continue;
|
}
|
//获取单次价格金额
|
curPrice = UserCardTool.countOneMoney(cardItemInfo);
|
int deductionNun;
|
if (cardItemInfo.getEveryDrawNum() != null && cardItemInfo.getEveryDrawNum() > 0) {
|
deductionNun = orderItemSon.getBuyNum() * cardItemInfo.getEveryDrawNum();
|
} else {
|
deductionNun = orderItemSon.getBuyNum();
|
}
|
//计算抵扣总的分摊明细
|
sumCardBagMoney = curPrice.multiply(BigDecimal.valueOf(deductionNun).setScale(2, RoundingMode.DOWN));
|
|
//算比例
|
if (cardItem.getTotal() != null && cardItem.getTotal().compareTo(BigDecimal.ZERO) > 0) {
|
proportion = sumCardBagMoney.divide(cardItem.getTotal(), 15, RoundingMode.HALF_UP);
|
} else {
|
proportion = BigDecimal.ZERO;
|
}
|
|
//计算单张卡的划扣金额
|
if (orderItemBuy.getBuyNum() > 0) {
|
orderItemBuy.setNoDeductionAmount(orderItemBuy.getNoDeductionAmount().divide(BigDecimal.valueOf(orderItemBuy.getBuyNum()), 15, RoundingMode.HALF_UP));
|
} else {
|
orderItemBuy.setNoDeductionAmount(BigDecimal.ZERO);
|
}
|
orderItemSon.setNoDeductionAmount(orderItemBuy.getNoDeductionAmount().multiply(proportion).setScale(2, RoundingMode.DOWN));
|
|
//更新信息
|
values.clear();
|
values.put("noDeductionAmount", orderItemSon.getNoDeductionAmount());
|
values.put("id", orderItemSon.getId());
|
sqlSentence.sqlUpdate("noDeductionAmount = #{m.noDeductionAmount} WHERE id = #{m.id}", values);
|
orderItemSonMapper.updateWhere(sqlSentence);
|
|
//更新信息
|
values.clear();
|
values.put("noDeductionAmount", orderItemSon.getNoDeductionAmount());
|
values.put("id", orderItem.getId());
|
sqlSentence.sqlUpdate("noDeductionAmount = #{m.noDeductionAmount} WHERE id = #{m.id}", values);
|
orderItemMapper.updateWhere(sqlSentence);
|
//用户项目
|
if (OrderItemConstants.TYPE_PROJECT.equals(orderItemSon.getType())) {
|
if (updateUserProject) {
|
//根据用户项目获取疗程数
|
userProjectItem = getUserProjectItem(orderItemSon.getId(), ordersTotal.getUserId());
|
//更新用户项目
|
updateUserProject(userProjectItem, sumCardBagMoney, sumCardBagMoney, curPrice, curPrice, orderItemSon.getBuyNum()
|
, orderItemSon.getNoDeductionAmount(), orderItemSon.getUsedTotal(), null);
|
}
|
}
|
}
|
}
|
|
/**二级订单积分处理-卡包处理-含商品处理版本*/
|
private void cardBagTwoHandle(OrdersTotal ordersTotal,OrderItem orderItem,List<OrderItemSon> orderItemSonList,boolean updateUserProject){
|
//获取用户卡项
|
UserCard userCard = userCardMapper.selectOneByKey(orderItem.getUserCardId());
|
if (userCard == null) {
|
logger.info("!!!!!!!未找到用户的卡项!!!!!!!!"+JSON.toJSONString(orderItem));
|
return;
|
}
|
SqlSentence sqlSentence = new SqlSentence();
|
Map<String, Object> values = new HashMap<>();
|
//当时买卡的订单
|
OrderItem orderItemBuy = null;
|
if (StringUtils.noNull(userCard.getSourceId())) {
|
orderItemBuy = orderItemMapper.selectOneByKey(userCard.getSourceId());
|
} else {
|
//获取当时购买这个卡包的订单子单
|
values.put("orderId", userCard.getOrderId());
|
values.put("commonId", userCard.getCardItemId());
|
sqlSentence.sqlSentence("SELECT * FROM order_item WHERE isDel = 0 AND orderId = #{m.orderId} AND commonId = #{m.commonId} LIMIT 1", values);
|
orderItemBuy = orderItemMapper.selectOne(sqlSentence);
|
if (orderItemBuy != null) {
|
//更新关联信息
|
values.put("sourceType", UserCard.SOURCE_TYPE_ORDER_ONE);
|
values.put("sourceId", orderItemBuy.getId());
|
values.put("id", userCard.getId());
|
sqlSentence.sqlUpdate("sourceType = #{m.sourceType},sourceId = #{m.sourceId} WHERE id = #{m.id}", values);
|
if (userCardMapper.updateWhere(sqlSentence) != 1){
|
throw new TipsException("获取购买卡项订单数据失败[01],请联系管理员");
|
}
|
}
|
}
|
if (orderItemBuy == null) {
|
throw new TipsException("获取购买卡项订单数据失败[02],请联系管理员");
|
}
|
//获取卡项配置
|
CardItem cardItem = cardItemMapper.selectOneByKey(orderItemBuy.getCommonId());
|
if (cardItem == null) {
|
throw new TipsException("获取购买卡项订单数据失败[03],请联系管理员");
|
}
|
//买卡子单支付总数据
|
List<PayMethodVo> groupByNumberNoList = refundMapper.getConsumePayOneGroupByNumberNo(orderItemBuy.getId());
|
Map<String, PayMethodVo> groupByNumberNoMap = new HashMap<>();
|
for (PayMethodVo payMethodVo : groupByNumberNoList) {
|
//要注意可能买多张
|
payMethodVo.setPayTotal(payMethodVo.getPayTotal().divide(new BigDecimal(orderItemBuy.getBuyNum()),2,RoundingMode.HALF_UP));
|
payMethodVo.setDeductionMoney(payMethodVo.getDeductionMoney().divide(new BigDecimal(orderItemBuy.getBuyNum()),2,RoundingMode.HALF_UP));
|
groupByNumberNoMap.put(payMethodVo.getNumberNo(), payMethodVo);
|
}
|
logger.info("买卡子单,支付数据总和:"+JSON.toJSONString(groupByNumberNoMap));
|
//子单支付方式数据
|
values.put("typeId", orderItemBuy.getId());
|
sqlSentence.sqlSentence("SELECT * FROM consume_pay_item WHERE isDel = 0 AND typeId = #{m.typeId} ",values);
|
List<ConsumePayItem> consumePayItemList = commonService.selectList(ConsumePayItemMapper.class,sqlSentence);
|
for (ConsumePayItem consumePayItemVo : consumePayItemList) {
|
//要注意可能买多张
|
consumePayItemVo.setActualTotal(consumePayItemVo.getActualTotal().divide(new BigDecimal(orderItemBuy.getBuyNum()),2,RoundingMode.HALF_UP));
|
consumePayItemVo.setDeductionMoney(consumePayItemVo.getDeductionMoney().divide(new BigDecimal(orderItemBuy.getBuyNum()),2,RoundingMode.HALF_UP));
|
}
|
logger.info("买卡子单,单卡的支付方式:"+JSON.toJSONString(consumePayItemList));
|
|
//卡项权益,支付方式编号,支付方式数据
|
Map<String, Map<String, ConsumePayItem>> cardEquityMethodMap = new HashMap<>();
|
Map<String, ConsumePayItem> methodMap = null;
|
ConsumePayItem consumePayItem = null;
|
//每个权益的总金额数据
|
Map<String,CardEquity> cardEquityMapTotal = new HashMap<>();
|
CardEquity cardEquity = null;
|
//权益标识,是否是全部使用完,通过判断条目的最终剩余次数来看是不是最后一个
|
Map<String, Boolean> cardEquityNumMap = new HashMap<>();
|
//每个权益的金额数据(方法内部已排序,金额字段在shareMoney)
|
List<CardEquity> cardEquityMoneyList = UserCardTool.getCardEquityMoneyList(null, cardItem, commonService);
|
for (int i = 0; i < cardEquityMoneyList.size(); i++) {
|
cardEquity = cardEquityMoneyList.get(i);
|
cardEquityMapTotal.put(cardEquity.getId(), cardEquity);
|
//每个权益的占比,如果是最后一个则占剩余的
|
BigDecimal rate = null;
|
if (i != cardEquityMoneyList.size() - 1) {
|
rate = cardEquity.getShareMoney().divide(cardItem.getTotal(), 20, RoundingMode.HALF_UP);
|
}
|
logger.info("权益:{},权益占比卡项金额比例:{}",cardEquity.getId(),rate);
|
//权益Map
|
methodMap = cardEquityMethodMap.get(cardEquity.getId());
|
if (methodMap == null) {
|
methodMap = new HashMap<>();
|
}
|
//循环买卡的支付方式,封装每个权益的分配支付方式金额
|
for (ConsumePayItem consumePayItemVo : consumePayItemList) {
|
//获取该支付方式的总额
|
PayMethodVo payMethodVo = groupByNumberNoMap.get(consumePayItemVo.getNumberNo());
|
logger.info("循环:{},支付方式:{}",cardEquity.getId(),consumePayItemVo.getNumberNo());
|
logger.info("支付金额:{},抵扣金额:{}",consumePayItemVo.getActualTotal(),consumePayItemVo.getDeductionMoney());
|
logger.info("总额:{},总抵扣金额:{}",payMethodVo.getPayTotal(),payMethodVo.getDeductionMoney());
|
|
//计算当前要分摊的金额
|
BigDecimal actualTotal = BigDecimal.ZERO;
|
BigDecimal deductionMoney = BigDecimal.ZERO;
|
if (rate != null) {
|
actualTotal = consumePayItemVo.getActualTotal().multiply(rate).setScale(2, RoundingMode.DOWN);
|
deductionMoney = consumePayItemVo.getDeductionMoney().multiply(rate).setScale(2, RoundingMode.DOWN);
|
} else {
|
//最后一个拿剩余的
|
actualTotal = payMethodVo.getPayTotal();
|
deductionMoney = payMethodVo.getDeductionMoney();
|
}
|
logger.info("比例:{},分配金额:{},抵扣金额:{}",rate,actualTotal,deductionMoney);
|
|
//减去分配的金额
|
payMethodVo.setPayTotal(payMethodVo.getPayTotal().subtract(actualTotal));
|
payMethodVo.setDeductionMoney(payMethodVo.getDeductionMoney().subtract(deductionMoney));
|
if (payMethodVo.getPayTotal().compareTo(BigDecimal.ZERO) < 0) {
|
throw new RuntimeException("卡包金额分配错误[0223]");
|
}
|
if (payMethodVo.getDeductionMoney().compareTo(BigDecimal.ZERO) < 0) {
|
throw new RuntimeException("卡包抵扣金额分配错误[0223]");
|
}
|
//更新map总剩余金额
|
groupByNumberNoMap.put(payMethodVo.getNumberNo(), payMethodVo);
|
|
|
//封装每个权益的支付方式
|
consumePayItem = methodMap.get(consumePayItemVo.getNumberNo());
|
if (consumePayItem == null) {
|
consumePayItem = new ConsumePayItem();
|
BeanUtils.copyProperties(consumePayItemVo,consumePayItem);
|
consumePayItem.setActualTotal(BigDecimal.ZERO);
|
consumePayItem.setDeductionMoney(BigDecimal.ZERO);
|
}
|
consumePayItem.actualTotalAdd(actualTotal);
|
consumePayItem.deductionMoneyAdd(deductionMoney);
|
methodMap.put(consumePayItemVo.getNumberNo(), consumePayItem);
|
}
|
cardEquityMethodMap.put(cardEquity.getId(), methodMap);
|
|
//查询用户的卡项对应的这个权益,是否使用完
|
cardEquityNumMap.put(cardEquity.getId(),true);
|
List<CardItemInfo> cardInfoList = UserCardTool.getCardInfoList(cardEquity.getId(), commonService);
|
if (cardInfoList != null && cardInfoList.size() > 0){
|
for (CardItemInfo cardItemInfo : cardInfoList) {
|
//获取这个条目剩余的次数
|
UserCardItemInfoVo userCardItemInfoVo = UserCardTool.getSurplusNumber(userCard, cardItemInfo, null, commonService);
|
logger.info("权益{},条目:{},剩余:{}",cardEquity.getId(),cardItemInfo.getId(),userCardItemInfoVo.getSurplusNum());
|
if (userCardItemInfoVo.getSurplusNum() != null && userCardItemInfoVo.getSurplusNum() > 0){
|
cardEquityNumMap.put(cardEquity.getId(),false);
|
break;
|
}
|
}
|
logger.info("权益:{},是否是最后一个:{}",cardEquity.getId(),cardEquityNumMap.get(cardEquity.getId()));
|
}
|
}
|
|
logger.info("-----计算条目金额------");
|
//这一步算出当前卡包购买的权益下,每个条目应分摊的金额(算出占比权益)
|
//权益标识,开卡选择的条目标识,条目数据
|
Map<String, Map<String,CardItemInfo>> cardEquityMap = new HashMap<>();
|
Map<String,CardItemInfo> cardItemInfoMap = null;
|
CardItemInfo cardItemInfo = null;
|
for (OrderItemSon itemSon : orderItemSonList) {
|
//获取卡项的条目
|
cardItemInfo = cardItemInfoMapper.selectOneByKey(itemSon.getCardItemInfoId());
|
if (cardItemInfo == null){
|
continue;
|
}
|
//条目数量
|
int deductionNun;
|
if (cardItemInfo.getEveryDrawNum() != null && cardItemInfo.getEveryDrawNum() > 0) {
|
deductionNun = itemSon.getBuyNum() * cardItemInfo.getEveryDrawNum();
|
} else {
|
deductionNun = itemSon.getBuyNum();
|
}
|
//这次购买的金额(规则:单次x数量)
|
BigDecimal infoShareMoney = UserCardTool.countOneMoney(cardItemInfo).multiply(new BigDecimal(deductionNun)).setScale(2, RoundingMode.DOWN);
|
cardItemInfo.setInfoShareMoney(infoShareMoney);
|
itemSon.setInfoShareMoney(infoShareMoney);
|
logger.info("权益{},条目:{},条目总次数金额:{}",itemSon.getCardEquityId(),cardItemInfo.getId(),infoShareMoney);
|
//按照权益进行分组
|
cardItemInfoMap = cardEquityMap.get(itemSon.getCardEquityId());
|
if (cardItemInfoMap == null) {
|
cardItemInfoMap = new HashMap<>();
|
}
|
cardItemInfoMap.put(itemSon.getCardItemInfoId(), cardItemInfo);
|
cardEquityMap.put(itemSon.getCardEquityId(), cardItemInfoMap);
|
}
|
logger.info("-----计算已使用金额------");
|
//到这一步的时候,用户卡项使用记录会有记录,拿到每个权益已经使用了的金额
|
//权益标识,支付方式编号,已购买数据
|
Map<String, Map<String, ConsumePayItem>> cardEquityMapUsedTotal = new HashMap<>();
|
Map<String, ConsumePayItem> usedCardEqu = null;
|
List<UserCardPay> cardBagEquityMoney = null;
|
for (Map.Entry<String, CardEquity> stringCardEquityEntry : cardEquityMapTotal.entrySet()) {
|
cardEquity = stringCardEquityEntry.getValue();
|
cardBagEquityMoney = UserCardTool.getCardBagEquityMoney(null, cardEquity, commonService);
|
methodMap = cardEquityMapUsedTotal.get(cardEquity.getId());
|
if (methodMap == null){
|
methodMap = new HashMap<>();
|
}
|
if (cardBagEquityMoney != null && cardBagEquityMoney.size() > 0){
|
for (UserCardPay userCardPay : cardBagEquityMoney) {
|
consumePayItem = methodMap.get(userCardPay.getNumberNo());
|
if (consumePayItem == null){
|
consumePayItem = new ConsumePayItem();
|
consumePayItem.setNumberNo(userCardPay.getNumberNo());
|
consumePayItem.setActualTotal(BigDecimal.ZERO);
|
consumePayItem.setDeductionMoney(BigDecimal.ZERO);
|
}
|
consumePayItem.actualTotalAdd(userCardPay.getActualTotal());
|
consumePayItem.deductionMoneyAdd(userCardPay.getDeductionMoney());
|
methodMap.put(userCardPay.getNumberNo(),consumePayItem);
|
logger.info("权益:{},已用支付:{},已用金额:{},已用抵扣金额:{}",cardEquity.getId(),userCardPay.getNumberNo()
|
,userCardPay.getActualTotal(),userCardPay.getDeductionMoney());
|
}
|
}
|
cardEquityMapUsedTotal.put(cardEquity.getId(),methodMap);
|
}
|
|
//到这里才是真正算这次卡包开单分配的钱
|
//按权益分组
|
Map<String,List<OrderItemSon>> cardItemInfoListMap = orderItemSonList.stream().collect(Collectors.groupingBy(OrderItemSon::getCardEquityId));
|
for (Map.Entry<String, List<OrderItemSon>> entry : cardItemInfoListMap.entrySet()) {
|
//这个权益的数据
|
cardEquity = cardEquityMapTotal.get(entry.getKey());
|
//这个权益的总支付金额数据
|
methodMap = cardEquityMethodMap.get(entry.getKey());
|
//这个权益已使用了的支付金额数据
|
usedCardEqu = cardEquityMapUsedTotal.get(entry.getKey());
|
|
//这个权益下的购买的条目数据
|
cardItemInfoMap = cardEquityMap.get(entry.getKey());
|
//当前结账权益已分配的金额(单前的卡包单可能会有同一个权益不同条目)
|
Map<String,ConsumePayItem> usedMap = new HashMap<>();
|
//这个权益下购买的条目,按金额排序
|
List<OrderItemSon> infoList = entry.getValue().stream().sorted(Comparator.comparing(OrderItemSon::getInfoShareMoney)).collect(Collectors.toList());
|
for (int i = 0; i < infoList.size(); i++) {
|
OrderItemSon orderItemSon = infoList.get(i);
|
//条目的数据
|
cardItemInfo = cardItemInfoMap.get(orderItemSon.getCardItemInfoId());
|
//条目要更新的未执行金额
|
BigDecimal totalNoDeductionMoney = BigDecimal.ZERO;
|
//条目占比权益
|
BigDecimal proportion = null;
|
//这次购买,权益次数已用完,需要直接扣完
|
if (cardEquityNumMap.get(entry.getKey())){
|
//不是最后一个则按比例
|
if (i != infoList.size()-1){
|
proportion = cardItemInfo.getInfoShareMoney().divide(cardEquity.getShareMoney(), 20, RoundingMode.HALF_UP);
|
}
|
}else {
|
//不是最后一个则按比例
|
proportion = cardItemInfo.getInfoShareMoney().divide(cardEquity.getShareMoney(), 20, RoundingMode.HALF_UP);
|
}
|
logger.info("权益:{},条目:{},占比权益:{}",cardEquity.getId(),cardItemInfo.getId(),proportion);
|
|
//权益占比卡项支付方式的数据
|
for (Map.Entry<String, ConsumePayItem> payItemEntry : methodMap.entrySet()) {
|
UserCardPay userCardPay = new UserCardPay();
|
//当前订单数据
|
userCardPay.setOrderId(orderItemSon.getOrderId());
|
userCardPay.setOrderItemId(orderItemSon.getOrderItemId());
|
userCardPay.setOrderItemSonId(orderItemSon.getId());
|
userCardPay.setCardEquityId(orderItemSon.getCardEquityId());
|
userCardPay.setCardItemInfoId(orderItemSon.getCardItemInfoId());
|
userCardPay.setGoodsId(orderItemSon.getGoodsId());
|
userCardPay.setGoodsNo(orderItemSon.getGoodsNo());
|
userCardPay.setGoodsName(orderItemSon.getGoodsName());
|
userCardPay.setUsedOne(orderItemSon.getUsedOne());
|
userCardPay.setUsedTotal(orderItemSon.getUsedTotal());
|
|
//权益的支付方式
|
ConsumePayItem value = payItemEntry.getValue();
|
logger.info("{},--------循环支付方式-----",payItemEntry.getKey());
|
logger.info("权益分配金额:{},抵扣:{}",value.getActualTotal(),value.getDeductionMoney());
|
//存储买卡的支付数据
|
userCardPay.setConsumePayItemId(value.getId());
|
userCardPay.setPaymentMethodId(value.getPaymentMethodId());
|
userCardPay.setNumberNo(value.getNumberNo());
|
userCardPay.setName(value.getName());
|
userCardPay.setIsMoneyPay(value.getIsMoneyPay());
|
userCardPay.setIsExecute(value.getIsExecute());
|
userCardPay.setIsPay(value.getIsPay());
|
userCardPay.setDeductionType(value.getDeductionType());
|
//当前卡包单下权益已经分配了的数据
|
ConsumePayItem usedItem = usedMap.get(value.getNumberNo());
|
if (usedItem == null){
|
usedItem = new ConsumePayItem();
|
usedItem.setActualTotal(BigDecimal.ZERO);
|
usedItem.setDeductionMoney(BigDecimal.ZERO);
|
}
|
logger.info("当前其它权益已分金额:{},抵扣:{}",usedItem.getActualTotal(),usedItem.getDeductionMoney());
|
//分摊买卡的支付数据
|
BigDecimal actualTotal = BigDecimal.ZERO;
|
BigDecimal deductionMoney = BigDecimal.ZERO;
|
if (proportion != null){
|
//按比例分配
|
actualTotal = value.getActualTotal().multiply(proportion).setScale(2,RoundingMode.DOWN);
|
deductionMoney = value.getDeductionMoney().multiply(proportion).setScale(2,RoundingMode.DOWN);
|
}else {
|
//分配剩余的钱
|
//减去当前结账的钱
|
actualTotal = value.getActualTotal().subtract(usedItem.getActualTotal());
|
deductionMoney = value.getDeductionMoney().subtract(usedItem.getDeductionMoney());
|
logger.info("减去当前其它权益金额:{},抵扣:{}",actualTotal,deductionMoney);
|
//减去以前使用的
|
if (usedCardEqu != null){
|
ConsumePayItem usedPayItem = usedCardEqu.get(value.getNumberNo());
|
if (usedPayItem != null){
|
logger.info("以前权益已分金额:{},抵扣:{}",usedPayItem.getActualTotal(),usedPayItem.getDeductionMoney());
|
actualTotal = actualTotal.subtract(usedPayItem.getActualTotal());
|
deductionMoney = deductionMoney.subtract(usedPayItem.getDeductionMoney());
|
logger.info("减去以前权益金额:{},抵扣:{}",actualTotal,deductionMoney);
|
}
|
}
|
}
|
logger.info("最终分配给条目的金额:{},抵扣:{}",actualTotal,deductionMoney);
|
if (actualTotal.compareTo(BigDecimal.ZERO) < 0){
|
throw new TipsException("卡项金额分配错误[011]");
|
}
|
if (deductionMoney.compareTo(BigDecimal.ZERO) < 0){
|
throw new TipsException("卡项金额分配错误[012]");
|
}
|
//叠加已分配的钱
|
usedItem.actualTotalAdd(actualTotal);
|
usedItem.deductionMoneyAdd(deductionMoney);
|
usedMap.put(value.getNumberNo(),usedItem);
|
|
//设置分配的钱
|
userCardPay.setActualTotal(actualTotal);
|
userCardPay.setDeductionMoney(deductionMoney);
|
//可划扣金额
|
if (userCardPay.getIsExecute() != null && userCardPay.getIsExecute() == 1){
|
userCardPay.setNoDeductionAmount(userCardPay.getActualTotal());
|
totalNoDeductionMoney = totalNoDeductionMoney.add(userCardPay.getNoDeductionAmount());
|
}
|
//存储当前买卡的分摊数据
|
commonService.insert(UserCardPayMapper.class,userCardPay);
|
}
|
//更新二级子单信息
|
values.clear();
|
values.put("noDeductionAmount", totalNoDeductionMoney);
|
values.put("id", orderItemSon.getId());
|
sqlSentence.sqlUpdate("noDeductionAmount = #{m.noDeductionAmount} WHERE id = #{m.id}", values);
|
orderItemSonMapper.updateWhere(sqlSentence);
|
//更新一级子单信息
|
values.clear();
|
values.put("noDeductionAmount", totalNoDeductionMoney);
|
values.put("id", orderItem.getId());
|
sqlSentence.sqlUpdate("noDeductionAmount = noDeductionAmount + #{m.noDeductionAmount} WHERE id = #{m.id}", values);
|
orderItemMapper.updateWhere(sqlSentence);
|
//用户项目
|
if (OrderItemConstants.TYPE_PROJECT.equals(orderItemSon.getType())) {
|
//更新用户项目
|
if (updateUserProject) {
|
//根据用户项目获取疗程数
|
updateUserProject(getUserProjectItem(orderItemSon.getId(), ordersTotal.getUserId())
|
, orderItemSon.getTotal(), orderItemSon.getActualTotal(), orderItemSon.getOriPrice()
|
, orderItemSon.getCurPrice(), orderItemSon.getBuyNum(), totalNoDeductionMoney
|
, orderItemSon.getUsedTotal(), null);
|
}
|
}
|
}
|
}
|
}
|
|
|
/**更新用户项目数据*/
|
private void updateUserProject(UserProjectItem userProjectItem,BigDecimal total,BigDecimal actualTotal,BigDecimal oriPrice
|
,BigDecimal curPrice,int buyNum,BigDecimal deductionTotalAmount,int usedTotal,Integer transferNum){
|
|
//没有找到就跳出
|
if(userProjectItem == null){
|
return;
|
}
|
SqlSentence sqlSentence = new SqlSentence();
|
Map<String,Object> values = new HashMap<>();
|
StringBuilder sql = new StringBuilder();
|
|
//总疗程数
|
userProjectItem.setUsedTotal(usedTotal);
|
|
userProjectItem.setBuyNum(buyNum);
|
|
//计算单次疗程金额
|
BigDecimal oneTotal = BigDecimal.ZERO;
|
if(userProjectItem.getUsedTotal() > 0){
|
oneTotal = deductionTotalAmount.divide(new BigDecimal(userProjectItem.getUsedTotal()),15,RoundingMode.HALF_UP);
|
}
|
|
//未划扣总金额
|
BigDecimal noDeductionTotal = oneTotal.multiply(BigDecimal.valueOf(userProjectItem.getNotUsedNum())).setScale(2,RoundingMode.HALF_UP);
|
//已使用总金额
|
BigDecimal useDeductionTotal = deductionTotalAmount.subtract(noDeductionTotal);
|
|
values.put("id",userProjectItem.getId());
|
values.put("userId",userProjectItem.getUserId());
|
values.put("total",total);
|
values.put("actualTotal",actualTotal);
|
values.put("oriPrice",oriPrice);
|
values.put("curPrice",curPrice);
|
values.put("buyNum",buyNum);
|
values.put("usedTotal",usedTotal);
|
sql.append(" total = #{m.total},actualTotal = #{m.actualTotal},oriPrice = #{m.oriPrice},curPrice = #{m.curPrice},buyNum = #{m.buyNum},usedTotal = #{m.usedTotal}");
|
//其他金额变更
|
if(deductionTotalAmount.compareTo(userProjectItem.getDeductionTotalAmount()) != 0){
|
//总划扣金额有变化
|
values.put("deductionTotalAmount",deductionTotalAmount);
|
values.put("useDeductionAmount",useDeductionTotal);
|
values.put("noDeductionAmount",noDeductionTotal);
|
sql.append(",deductionTotalAmount = #{m.deductionTotalAmount},useDeductionAmount = #{m.useDeductionAmount},noDeductionAmount = #{m.noDeductionAmount}");
|
}
|
|
if(transferNum != null){
|
values.put("transferNum",transferNum);
|
sql.append(",transferNum = #{m.transferNum}");
|
}
|
sql.append(" WHERE id = #{m.id} AND isTransfer = 0");
|
sqlSentence.sqlUpdate( sql.toString(),values);
|
if(userProjectItemMapper.updateWhere(sqlSentence) > 1){
|
throw new TipsException("更新主用户项目不是一条!");
|
}
|
|
//--领建订单初始化会跑这个程序,转增的项目,新系统不会有转增来跑初始化订单的程序,做了转增的判断,是不做初始化订单的程序
|
/* values.put("commonId",userProjectItem.getCommonId());
|
values.put("oneTotal", oneTotal);
|
logger.info("标记:更新处理对应用户项目,以防后面出错可回溯,commonId:{}", userProjectItem.getCommonId());
|
sqlSentence.sqlUpdate(" total = #{m.total},actualTotal = #{m.actualTotal},oriPrice = #{m.oriPrice},curPrice = #{m.curPrice}" +
|
",deductionTotalAmount = (#{m.oneTotal}*usedTotal),noDeductionAmount = (#{m.oneTotal}*notUsedNum)" +
|
" WHERE commonId = #{m.commonId} AND isTransfer = 1 and isDel = 0 ",values);
|
userProjectItemMapper.updateWhere(sqlSentence);*/
|
|
try{
|
//计算划扣金额
|
if(deductionTotalAmount.compareTo(userProjectItem.getDeductionTotalAmount()) != 0){
|
BigDecimal deductionAmount = oneTotal.multiply(BigDecimal.valueOf(userProjectItem.getUsedNum())).setScale(2,RoundingMode.HALF_UP);
|
if(deductionAmount.compareTo(useDeductionTotal) > 0){
|
deductionAmount = useDeductionTotal;
|
}
|
UserDeductionSingleTool.initDeductionMoney(userProjectItem.getId(),userProjectItem.getUsedNum(),deductionAmount,commonService);
|
}
|
}catch (Exception e){
|
//初始化
|
logger.error("初始化订单-初始化划扣记录金额出错",e);
|
}
|
|
}
|
|
/**获取用户项目-主关联那条*/
|
private UserProjectItem getUserProjectItem(String orderItemId,String userId){
|
SqlSentence sqlSentence = new SqlSentence();
|
Map<String,Object> values = new HashMap<>();
|
|
values.put("commonId",orderItemId);
|
values.put("userId",userId);
|
sqlSentence.sqlSentence("SELECT * FROM user_project_item WHERE isDel = 0 AND commonId = #{m.commonId} AND isTransfer = 0",values);
|
return userProjectItemMapper.selectOne(sqlSentence);
|
}
|
|
/** 处理重新算订单已支付积分 */
|
private void handleOrderRecalculatePayPoints(OrdersTotal ordersTotal, List<ConsumePay> consumePayList){
|
//遍历累加已支付积分
|
BigDecimal actualTotalPoints = BigDecimal.ZERO;
|
for(ConsumePay consumePay : consumePayList){
|
actualTotalPoints = actualTotalPoints.add(consumePay.getActualTotal());
|
}
|
|
SqlSentence sqlSentence = new SqlSentence();
|
Map<String,Object> values = new HashMap<>();
|
sqlSentence.setM(values);
|
|
//更新总订单已支付积分
|
values.put("orderId",ordersTotal.getId());
|
values.put("actualTotalPoints",ordersTotal.getActualTotalPoints());
|
sqlSentence.sqlUpdate(" actualTotalPoints = #{m.actualTotalPoints} WHERE id = #{m.orderId} ",values);
|
ordersTotalMapper.updateWhere(sqlSentence);
|
|
//先删除平摊的积分支付记录
|
values.clear();
|
values.put("orderId",ordersTotal.getId());
|
values.put("numberNo", PayMethodTypeConstants.PAY_INTEGRAL);
|
sqlSentence.sqlWhere("orderId = #{m.orderId} and numberNo = #{m.numberNo} ",values);
|
consumePayItemMapper.deleteWhere(sqlSentence);
|
|
//获取订单的所有一级子单
|
values.clear();
|
values.put("orderId", ordersTotal.getId());
|
sqlSentence.sqlSentence("SELECT * FROM order_item WHERE isDel = 0 AND orderId = #{m.orderId}",values);
|
List<OrderItem> orderItemList = orderItemMapper.selectList(sqlSentence);
|
if(orderItemList.size() == 0){
|
return;
|
}
|
|
/////四舍五入的原因,先排序,先算小的,再算大的,因为如果除不尽,那么都会进1分,那么就导致了后面的如果刚刚好,而前面的多扣了一分,导致会少钱
|
orderItemList = orderItemList.stream().sorted(Comparator.comparing(OrderItem::getTotalPoints)).collect(Collectors.toList());
|
|
//占比
|
BigDecimal proportion;
|
OrderItem orderItem;
|
ConsumePay consumePay;
|
ConsumePayItem consumePayItem;
|
//子订单剩余应付积分,分配支付记录用到
|
BigDecimal surplusIntegral;
|
for(int i = 0; i < orderItemList.size(); i++){
|
orderItem = orderItemList.get(i);
|
//计算比例
|
if(actualTotalPoints.compareTo(BigDecimal.ZERO) > 0){
|
proportion = orderItem.getTotalPoints().divide(actualTotalPoints,15, RoundingMode.HALF_UP);
|
}else{
|
proportion = BigDecimal.ZERO;
|
}
|
|
//根据比例算出子单应付总积分
|
orderItem.setActualTotalPoints(actualTotalPoints.multiply(proportion).setScale(2,RoundingMode.UP));
|
surplusIntegral = orderItem.getActualTotalPoints();
|
//遍历支付方式
|
for(int j = 0;j < consumePayList.size();j++){
|
consumePay = consumePayList.get(j);
|
if(consumePay.getpTotal().compareTo(BigDecimal.ZERO) <= 0
|
|| surplusIntegral.compareTo(BigDecimal.ZERO) <= 0){
|
continue;
|
}
|
|
//生成子单的支付记录
|
consumePayItem = new ConsumePayItem();
|
BeanUtils.copyProperties(consumePay,consumePayItem);
|
consumePayItem.setType(ConsumePayItem.TYPE_ORDER_ITEM);
|
consumePayItem.setTypeId(orderItem.getId());
|
consumePayItem.setConsumePayId(consumePay.getId());
|
|
if(i == orderItemList.size() - 1) {
|
//最后一个子单,把剩下未分配的支付方式金额全部放进去
|
consumePayItem.setActualTotal(consumePay.getpTotal());
|
}else{
|
if(j == consumePayList.size() - 1){
|
consumePayItem.setActualTotal(surplusIntegral);
|
}else{
|
////四舍五入规则,有余数都进一分钱
|
consumePayItem.setActualTotal(consumePay.getActualTotal().multiply(proportion).setScale(2,RoundingMode.UP));
|
}
|
}
|
|
//如果分配的积分比剩余应付积分多,那就就用剩余应付积分
|
if(surplusIntegral.compareTo(consumePayItem.getActualTotal()) < 0){
|
consumePayItem.setActualTotal(surplusIntegral);
|
}
|
//计算剩余的应付积分
|
surplusIntegral = surplusIntegral.subtract(consumePayItem.getActualTotal());
|
//计算剩余可分配的金额/积分
|
consumePay.setpTotal(consumePay.getpTotal().subtract(consumePayItem.getActualTotal()).setScale(2,RoundingMode.HALF_UP));
|
//保存平摊支付方式
|
consumePayItemMapper.insert(consumePayItem);
|
}
|
|
//更新一级子单信息
|
values.clear();
|
values.put("id",orderItem.getId());
|
values.put("actualTotalPoints",orderItem.getActualTotalPoints());
|
sqlSentence.sqlUpdate(" actualTotalPoints = #{m.actualTotalPoints} WHERE id = #{m.id}",values);
|
orderItemMapper.updateWhere(sqlSentence);
|
|
}
|
|
}
|
|
/**
|
* 获取每个SKU可抵扣金额最大值
|
* @return 键:skuId 值:最大积分数
|
* */
|
public static Map<String, BigDecimal> getSkuCashByItemList(List<String> canIntegralCashIdList,List<OrderItem> orderItemList,IntegralCashVo integralCashVo) {
|
//最大可抵扣现金返回数据
|
Map<String,BigDecimal> returnMap = new HashMap<>();
|
Map<String, BigDecimal> skuMaxRateMap = null;
|
if (integralCashVo != null && integralCashVo.getSkuMaxRateMap() != null) {
|
skuMaxRateMap = integralCashVo.getSkuMaxRateMap();
|
}
|
if (skuMaxRateMap == null){
|
logger.error("转换获取的sku最大抵扣数据失败" + JSON.toJSONString(integralCashVo));
|
return returnMap;
|
}
|
//处理每个SKU的金额
|
for (OrderItem orderItem : orderItemList) {
|
//默认赋值
|
returnMap.put(orderItem.getCommonId(),BigDecimal.ZERO);
|
if (canIntegralCashIdList != null && canIntegralCashIdList.contains(orderItem.getCommonId())){
|
returnMap.put(orderItem.getCommonId(),handlerCash(orderItem, integralCashVo, skuMaxRateMap.get(orderItem.getCommonId())));
|
}
|
}
|
logger.info("一级子单最大抵扣金额数值returnMap:"+JSON.toJSONString(returnMap));
|
return returnMap;
|
}
|
/**
|
* 计算可抵扣积分最大数值-算法同艾芯荟handlerIntegral
|
* @param integralCashVo 积分/现金数值
|
* @param rate sku的最大抵扣比率
|
*/
|
private static BigDecimal handlerCash(OrderItem orderItem, IntegralCashVo integralCashVo, BigDecimal rate) {
|
//积分配置数据为空
|
if (integralCashVo == null){
|
logger.info(orderItem.getCommonId()+",配置信息为空,抵扣数据默认给0");
|
return BigDecimal.ZERO;
|
}
|
//比率为空或者最大抵扣为0
|
if (rate == null || rate.compareTo(BigDecimal.ZERO) <= 0) {
|
logger.info(orderItem.getCommonId()+",配置的抵扣比率为0或者无,抵扣数据默认给0");
|
return BigDecimal.ZERO;
|
}
|
//配置信息出现错误的0,不处理,返回0
|
if (integralCashVo.getCash().compareTo(BigDecimal.ZERO) == 0) {
|
logger.info(orderItem.getCommonId()+",抵扣比率的现金设置为0,抵扣数据默认给0");
|
return BigDecimal.ZERO;
|
}
|
//算出最小积分
|
BigDecimal minIntegral = integralCashVo.getIntegral().divide(integralCashVo.getCash(), 0, RoundingMode.UP);
|
logger.info("当前比率下的最小抵扣1元所需要的积分是:"+minIntegral);
|
BigDecimal curPrice = orderItem.getProPrice();
|
logger.info(orderItem.getCommonId()+",SKU金额{},比例{}",curPrice,rate);
|
//积分保留整数,舍去多余的数据
|
curPrice = curPrice.multiply(rate).multiply(integralCashVo.getIntegral()).divide(integralCashVo.getCash(), 0, RoundingMode.DOWN);
|
logger.info(orderItem.getCommonId()+",SKU最大抵扣积分:" + curPrice);
|
//如果不够最小积分,则抵扣的现金为0
|
if (curPrice.compareTo(minIntegral) < 0){
|
curPrice = BigDecimal.ZERO;
|
}else {
|
//现金保留两位,舍去多余的数据
|
curPrice = curPrice.multiply(integralCashVo.getCash()).divide(integralCashVo.getIntegral(), 2, RoundingMode.DOWN);
|
}
|
logger.info(orderItem.getCommonId()+",SKU最大抵扣金额:" + curPrice);
|
return curPrice;
|
}
|
|
}
|