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.ConsumePayCard; 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.model.warehouse.PickUpGoodItem; 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 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 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 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 consumePayList,Boolean updateStatus){ OrderCarryVo orderCarryVo = new OrderCarryVo(); orderCarryVo.setConsumePayList(consumePayList); SqlSentence sqlSentence = new SqlSentence(); Map 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 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 canIntegralCashIdList,OrdersTotal ordersTotal,OrderCarryVo orderCarryVo,boolean updateUserProject,String appId){ SqlSentence sqlSentence = new SqlSentence(); Map 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 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); } } //提货单金额处理 pickUpOrderHandle(ordersTotal,orderItemList); } /**关联提货单数据处理*/ private void pickUpOrderHandle(OrdersTotal ordersTotal, List orderItemList) { if (orderItemList == null || orderItemList.size() == 0) { return; } SqlSentence sqlSentence = new SqlSentence(); Map sqlMap = new HashMap<>(); sqlMap.put("orderId", ordersTotal.getId()); StringBuilder sql = new StringBuilder(); sql.append(" SELECT * FROM pick_up_good_item AS i "); sql.append(" JOIN pick_up_good AS p ON p.id = i.pickUpGoodId "); sql.append(" WHERE p.isDel = 0 AND i.isDel = 0 AND p.commonId = #{m.orderId} "); sqlSentence.sqlSentence(sql.toString(), sqlMap); List pickUpGoodItemList = commonService.selectList(PickUpGoodItemMapper.class, sqlSentence); if (pickUpGoodItemList == null || pickUpGoodItemList.size() < 1) { return; } //耗材标识,数据 Map pickUpGoodItemMap = new HashMap<>(); for (PickUpGoodItem pickUpGoodItem : pickUpGoodItemList) { pickUpGoodItemMap.put(pickUpGoodItem.getConsumablesId(), pickUpGoodItem); } for (OrderItem orderItem : orderItemList) { //商品直接来 if (OrderItemConstants.TYPE_RETAIL.equals(orderItem.getType())) { PickUpGoodItem pickUpGoodItem = pickUpGoodItemMap.get(orderItem.getCommonId()); if (pickUpGoodItem == null) { continue; } //查询这个子单分到的钱 sqlMap.put("typeId", orderItem.getId()); sqlSentence.sqlSentence("SELECT SUM(actualTotal) AS actualTotal FROM consume_pay_item WHERE isDel = 0 AND typeId = #{m.typeId} ", sqlMap); ConsumePayItem consumePayItem = commonService.selectOne(ConsumePayItemMapper.class, sqlSentence); sqlMap.put("orderPrice", consumePayItem == null ? BigDecimal.ZERO : consumePayItem.getActualTotal()); sqlMap.put("id", pickUpGoodItem.getId()); sqlSentence.sqlSentence("orderPrice = #{m.orderPrice} WHERE id = #{m.id}", sqlMap); if (commonService.updateWhere(PickUpGoodItemMapper.class, sqlSentence) != 1) { throw new TipsException("处理提货单金额信息错误"); } } else { if (OrderItemConstants.TYPE_PROMOTION.equals(orderItem.getType()) || OrderItemConstants.CARD_BAG.equals(orderItem.getType())) { //促销和卡包查询二级子单 sqlMap.put("orderItemId", orderItem.getId()); sqlSentence.sqlSentence("SELECT * FROM order_item_source WHERE isDel = 0 AND orderItemId = #{m.orderItemId}", sqlMap); List orderItemSonList = orderItemSonMapper.selectList(sqlSentence); if (orderItemSonList == null || orderItemSonList.size() < 1) { continue; } for (OrderItemSon orderItemSon : orderItemSonList) { PickUpGoodItem pickUpGoodItem = pickUpGoodItemMap.get(orderItemSon.getGoodsId()); if (pickUpGoodItem == null) { continue; } //促销 if (OrderItemConstants.TYPE_PROMOTION.equals(orderItem.getType())) { //查询这个子单分到的钱 sqlMap.put("typeId", orderItemSon.getId()); sqlSentence.sqlSentence("SELECT SUM(actualTotal) AS actualTotal FROM consume_pay_item_son WHERE isDel = 0 AND typeId = #{m.typeId} ", sqlMap); ConsumePayItemSon consumePayItemSon = commonService.selectOne(ConsumePayItemSonMapper.class, sqlSentence); sqlMap.put("orderPrice", consumePayItemSon == null ? BigDecimal.ZERO : consumePayItemSon.getActualTotal()); } else if (OrderItemConstants.CARD_BAG.equals(orderItem.getType())) { //查询这个卡包单分到的钱 sqlMap.put("orderPrice", UserCardTool.orderItemSonMoney(orderItemSon.getId(), commonService)); } sqlMap.put("id", pickUpGoodItem.getId()); sqlSentence.sqlSentence("orderPrice = #{m.orderPrice} WHERE id = #{m.id}", sqlMap); if (commonService.updateWhere(PickUpGoodItemMapper.class, sqlSentence) != 1) { throw new TipsException("处理提货单金额信息错误"); } } } } } } /**一级订单金额处理*/ private void moneyOneHandle(List canIntegralCashIdList,OrdersTotal ordersTotal,OrderCarryVo orderCarryVo,List 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 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 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 handlerDeductionMoneyMap(List canIntegralCashIdList ,List orderItemList, BigDecimal integralCash, BigDecimal integralDeduction,String appId) { //积分抵扣现金配置 IntegralCashVo integralCashVo = null; //sku标识,最大可抵扣现金 Map skuCashMap = null; Map 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 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 skuDeductionVoMap ,OrdersTotal ordersTotal,List 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 orderItemList){ //-----四舍五入的原因,先排序,先算小的,再算大的,因为如果除不尽,那么都会进1积分,那么就导致了后面的如果刚刚好,而前面的多扣了一积分,导致会少积分 orderItemList = orderItemList.stream().sorted(Comparator.comparing(OrderItem::getTotalPoints)) .collect(Collectors.toList()); //占比 BigDecimal proportion; OrderItem orderItem; //子订单剩余应付积分,分配支付记录用到 BigDecimal surplusIntegral; for(int i=0;i()); //赋值计算 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 values = new HashMap<>(); //获取二级子订单 values.put("orderItemId",orderItem.getId()); sqlSentence.sqlSentence("SELECT * FROM order_item_source WHERE isDel = 0 AND orderItemId = #{m.orderItemId}",values); List 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 orderItemSonList,boolean updateUserProject){ SqlSentence sqlSentence = new SqlSentence(); Map 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 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 dkList = null; for(int i = 0;i 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 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 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 orderItemSonList){ /////因为要判断最后一个原因,四舍五入的原因,先排序,先算小的,再算大的,因为如果除不尽,那么都会进1积分,那么就导致了后面的如果刚刚好,而前面的多扣了一积分,导致会少积分 orderItemSonList = orderItemSonList.stream().sorted(Comparator.comparing(OrderItemSon::getTotalPoints)) .collect(Collectors.toList()); //占比 BigDecimal proportion; OrderItemSon orderItemSon; //子订单剩余应付金额 BigDecimal surplusIntegral; for(int i = 0;i 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 orderItemSonList,boolean updateUserProject){ /////因为要判断最后一个原因,四舍五入的原因,先排序,先算小的,再算大的,因为如果除不尽,那么都会进1分,那么就导致了后面的如果刚刚好,而前面的多扣了一分,导致会少钱 orderItemSonList = orderItemSonList.stream().sorted(Comparator.comparing(OrderItemSon::getTotal)) .collect(Collectors.toList()); SqlSentence sqlSentence = new SqlSentence(); Map 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 orderItemSonList,boolean updateUserProject){ //获取用户卡项 UserCard userCard = userCardMapper.selectOneByKey(orderItem.getUserCardId()); if (userCard == null) { logger.info("!!!!!!!未找到用户的卡项!!!!!!!!"+JSON.toJSONString(orderItem)); return; } SqlSentence sqlSentence = new SqlSentence(); Map 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],请联系管理员"); } //子单支付方式数据 values.put("typeId", orderItemBuy.getId()); sqlSentence.sqlSentence("SELECT * FROM consume_pay_item WHERE isDel = 0 AND typeId = #{m.typeId} ",values); List consumePayItemList = commonService.selectList(ConsumePayItemMapper.class,sqlSentence); Map consumePayItemMap = new HashMap<>(); consumePayItemList.forEach(consumePayItem -> consumePayItemMap.put(consumePayItem.getId(),consumePayItem)); logger.info("买卡子单,单卡的支付方式:"+JSON.toJSONString(consumePayItemMap)); //1.获取分摊的卡项数据<卡项,支付项标识,数据> Map> buyTotalMap = UserCardTool.getCardBuyMoneyByItemId(orderItemBuy.getId(), commonService); logger.info("获取分摊的卡项数据:"+JSON.toJSONString(buyTotalMap)); //1.获取当前卡分配的金额数据<支付项标识,卡项数据> Map cardBuyMoneyMap = getUserCardMoneyMap(buyTotalMap,userCard,orderItemBuy,consumePayItemList); //2.获取分摊的权益数据<权益标识,支付项标识,数据> Map> buyEquMap = UserCardTool.getCardDetailBuyMoneyByItemId(userCard.getId(),ConsumePayCard.TYPE_EQU, commonService); logger.info("获取分摊的权益数据:"+JSON.toJSONString(buyEquMap)); //2.获取当前权益分配的金额数据<权益标识,支付项标识,权益数据> Map> cardEquBuyMoneyMap = getUserCardEquMoneyMap(buyEquMap,cardBuyMoneyMap,cardItem,orderItemSonList); //3.获取分摊的条目数据<条目标识,支付项标识,数据> Map> buyInfoMap = UserCardTool.getCardDetailBuyMoneyByItemId(userCard.getId(),ConsumePayCard.TYPE_INFO, commonService); logger.info("获取分摊的条目数据:"+JSON.toJSONString(buyInfoMap)); //3.获取当前条目分配的金额数据<表目标识,支付项标识,条目数据> Map> cardInfoBuyMoneyMap = getUserCardInfoMoneyMap(buyInfoMap,cardEquBuyMoneyMap,orderItemSonList); //到这里才是真正算这次卡包开单分配的钱 //按权益分组 Map> cardItemInfoListMap = orderItemSonList.stream().collect(Collectors.groupingBy(OrderItemSon::getCardEquityId)); for (Map.Entry> entry : cardItemInfoListMap.entrySet()) { //这个权益信息 CardEquity cardEquity = commonService.selectOneByKey(CardEquityMapper.class,entry.getKey()); //这个权益下购买的条目,按金额排序 List infoList = entry.getValue().stream().sorted(Comparator.comparing(OrderItemSon::getInfoShareMoney)).collect(Collectors.toList()); //这个权益下使用过的数据<条目,支付项,数据> Map> usedMoneyMap = UserCardTool.getCardBagUseList(entry.getKey(), null, commonService); Map usedNumMap = new HashMap<>(); for (Map.Entry> mapEntry : usedMoneyMap.entrySet()) { CardItemInfo cardItemInfo = commonService.selectOneByKey(CardItemInfoMapper.class,mapEntry.getKey()); for (Map.Entry itemEntry : mapEntry.getValue().entrySet()) { UserCardPay userCardPay = usedNumMap.get(mapEntry.getKey()); if (userCardPay == null){ userCardPay = new UserCardPay(); } OrderItem usedItem = commonService.selectOneByKey(OrderItemMapper.class,itemEntry.getValue().getOrderItemId()); if (cardEquity.getEquityType().equals(CardEquity.EQUITY_TYPE_TIME_CARD)){ userCardPay.pNumAdd(usedItem.getBuyNum() * cardItemInfo.getEveryDrawNum()); userCardPay.setNowByNum(orderItem.getBuyNum() * cardItemInfo.getEveryDrawNum()); userCardPay.setTotalNum(cardEquity.getValue()); }else { userCardPay.pNumAdd(usedItem.getBuyNum()); userCardPay.setNowByNum(orderItem.getBuyNum()); userCardPay.setTotalNum(cardItemInfo.getMaxNum()); } usedNumMap.put(mapEntry.getKey(),userCardPay); } } for (int i = 0; i < infoList.size(); i++) { OrderItemSon orderItemSon = infoList.get(i); CardItemInfo cardItemInfo = commonService.selectOneByKey(CardItemInfoMapper.class,orderItemSon.getCardItemInfoId()); //条目OCC数据 Map infoMap = cardInfoBuyMoneyMap.get(orderItemSon.getCardItemInfoId()); //是否最后的数量 UserCardPay usedUserCardPay = usedNumMap.get(orderItemSon.getCardItemInfoId()); usedUserCardPay.handlerLast(); logger.info("条目:{},是否最后:{}",orderItemSon.getCardItemInfoId(),usedUserCardPay.getIsLast()); //使用过的金额 Map usedInfoMoneyMap = usedMoneyMap.get(orderItemSon.getCardItemInfoId()); logger.info("条目:{},使用过的金额:{}",orderItemSon.getCardItemInfoId(),JSON.toJSONString(usedInfoMoneyMap)); //总的可执行金额 BigDecimal totalNoDeductionMoney = BigDecimal.ZERO; for (Map.Entry payItemEntry : consumePayItemMap.entrySet()) { UserCardPay userCardPay = new UserCardPay(); //当前订单数据 userCardPay.setOrderId(orderItemSon.getOrderId()); userCardPay.setOrderItemId(orderItemSon.getOrderItemId()); userCardPay.setOrderItemSonId(orderItemSon.getId()); userCardPay.setUserCardId(orderItem.getUserCardId()); 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()); //存储买卡的支付数据 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()); //OCC数据 ConsumePayCard occPayCard = infoMap.get(value.getId()); logger.info("支付方式OCC分配金额:{},抵扣金额:{}",occPayCard.getActualTotal(),occPayCard.getDeductionMoney()); //当前卡包单分配的金额 if (usedUserCardPay.getIsLast()){ UserCardPay usedMoney = usedInfoMoneyMap.get(value.getId()); userCardPay.setActualTotal(occPayCard.getActualTotal().subtract(usedMoney.getActualTotal())); userCardPay.setDeductionMoney(occPayCard.getDeductionMoney().subtract(usedMoney.getDeductionMoney())); }else { if (cardEquity.getEquityType().equals(CardEquity.EQUITY_TYPE_TIME_CARD)){ //次卡 每次抵扣的OCCx抵扣次数 int num = orderItemSon.getBuyNum() * cardItemInfo.getEveryDrawNum(); userCardPay.setActualTotal(occPayCard.getActualTotal().multiply(new BigDecimal(num)).setScale(2, RoundingMode.DOWN)); userCardPay.setDeductionMoney(occPayCard.getDeductionMoney().multiply(new BigDecimal(num)).setScale(2, RoundingMode.DOWN)); }else{ //N选M和固定项目 按数量比例 BigDecimal rate = new BigDecimal(orderItemSon.getBuyNum()).divide(new BigDecimal(cardItemInfo.getMaxNum()),2, RoundingMode.HALF_UP); userCardPay.setActualTotal(occPayCard.getActualTotal().multiply(rate).setScale(2, RoundingMode.DOWN)); userCardPay.setDeductionMoney(occPayCard.getDeductionMoney().multiply(rate).setScale(2, RoundingMode.DOWN)); } } if (userCardPay.getActualTotal().compareTo(BigDecimal.ZERO) <= 0){ throw new RuntimeException("卡包金额分配错误[0223]"); } if (userCardPay.getDeductionMoney().compareTo(BigDecimal.ZERO) <= 0){ throw new RuntimeException("卡包抵扣金额分配错误[0223]"); } //可划扣金额 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); } } } } } /** * 处理条目分配OCC金额数据 * * @param buyInfoMap 已经分配的条目数据 * @param cardEquBuyMoneyMap 分配的卡项金额数据 * @param orderItemSonList 购买子单数据 */ private Map> getUserCardInfoMoneyMap(Map> buyInfoMap , Map> cardEquBuyMoneyMap, List orderItemSonList) { //返回数据 Map> returnDataMap = new HashMap<>(); Map returnItemMap = null; //条目标识,条目数据 Map infoDataMap = null; //权益分组后的购买条目 List groupSonList = null; //算出已经分配的条目的总额 Map payTotalMap = null; //按权益分组 Map> groupMap = orderItemSonList.stream().collect(Collectors.groupingBy(OrderItemSon::getCardEquityId)); for (Map.Entry> equEntry : groupMap.entrySet()) { //权益 CardEquity cardEquity = commonService.selectOneByKey(CardEquityMapper.class, equEntry.getKey()); //查询权益下所有的条目数据 infoDataMap = new HashMap<>(); List cardInfoList = UserCardTool.getCardInfoList(equEntry.getKey(), commonService); for (CardItemInfo cardItemInfo : cardInfoList) { infoDataMap.put(cardItemInfo.getId(),cardItemInfo); //固定项目叠加金额 if (cardEquity.getEquityType().equals(CardEquity.EQUITY_TYPE_PROJECT)){ cardEquity.setShareMoney(cardEquity.getShareMoney().add(cardItemInfo.getShareMoney())); } } //权益分摊好的金额数据 Map equBuyMap = cardEquBuyMoneyMap.get(cardEquity.getId()); //排序要购买的条目数据 groupSonList = equEntry.getValue(); for (OrderItemSon orderItemSon : groupSonList) { CardItemInfo cardItemInfo = infoDataMap.get(orderItemSon.getCardItemInfoId()); orderItemSon.setInfoShareMoney(cardItemInfo.getShareMoney() == null ? cardItemInfo.getEveryShareMoney() : cardItemInfo.getShareMoney()); if (orderItemSon.getInfoShareMoney() == null){ orderItemSon.setInfoShareMoney(BigDecimal.ZERO); } } groupSonList = groupSonList.stream().sorted(Comparator.comparing(OrderItemSon::getInfoShareMoney)).collect(Collectors.toList()); //算出已经分配的条目的总额 payTotalMap = new HashMap<>(); ConsumePayCard useValue = null; for (Map.Entry> entry : buyInfoMap.entrySet()) { for (Map.Entry itemEntry : entry.getValue().entrySet()) { useValue = payTotalMap.get(itemEntry.getKey()); if (useValue == null) { useValue = new ConsumePayCard(); } useValue.actualTotalAdd(itemEntry.getValue().getActualTotal()); useValue.deductionMoneyAdd(itemEntry.getValue().getDeductionMoney()); payTotalMap.put(itemEntry.getKey(), useValue); } } //此次是否买完了最后的条目种类 boolean isLast = false; if (cardEquity.getEquityType().equals(CardEquity.EQUITY_TYPE_PROJECT) || cardEquity.getEquityType().equals(CardEquity.EQUITY_TYPE_N_M)){ //条目数据,未购买过的 Map noBuyMap = new HashMap<>(); for (CardItemInfo cardItemInfo : cardInfoList) { if (buyInfoMap.get(cardItemInfo.getId()) == null) { noBuyMap.put(cardItemInfo.getId(), cardItemInfo); } } List infoIdList = orderItemSonList.stream().map(OrderItemSon::getCardItemInfoId).collect(Collectors.toList()); for (String infoId : infoIdList) { noBuyMap.remove(infoId); } isLast = noBuyMap.size() == 0; } for (int i = 0; i < groupSonList.size(); i++) { OrderItemSon orderItemSon = groupSonList.get(i); //子单条目数据 CardItemInfo cardItemInfo = infoDataMap.get(orderItemSon.getId()); //返回数据 returnItemMap = returnDataMap.get(orderItemSon.getCardItemInfoId()); if (returnItemMap == null){ returnItemMap = new HashMap<>(); } //未分配过,获取权益下的条目数据 if (buyInfoMap.get(orderItemSon.getCardItemInfoId()) == null){ for (Map.Entry cardEntry : equBuyMap.entrySet()) { ConsumePayCard consumePayCard = cardEntry.getValue(); //新增 ConsumePayCard addValue = new ConsumePayCard(); addValue.setConsumePayItemId(consumePayCard.getConsumePayItemId()); addValue.setPaymentMethodId(consumePayCard.getPaymentMethodId()); addValue.setNumberNo(consumePayCard.getNumberNo()); addValue.setName(consumePayCard.getName()); addValue.setCommonType(ConsumePayCard.TYPE_INFO); addValue.setCommonId(cardItemInfo.getId()); addValue.setUserCardId(consumePayCard.getUserCardId()); addValue.setOrderItemId(consumePayCard.getOrderItemId()); addValue.setOrderId(consumePayCard.getOrderId()); addValue.setDeductionType(consumePayCard.getDeductionType()); //获取使用了的总额,权益金额减去使用的总额 useValue = payTotalMap.get(consumePayCard.getConsumePayItemId()); //条目分摊的钱看权益的类型 if (cardEquity.getEquityType().equals(CardEquity.EQUITY_TYPE_PROJECT)){ //权益是固定项目,那么直接按金额占比分配,注意最后一个条目 if (isLast && i == groupSonList.size() - 1) { addValue.setActualTotal(consumePayCard.getActualTotal().subtract(useValue.getActualTotal())); addValue.setDeductionMoney(consumePayCard.getDeductionMoney().subtract(useValue.getDeductionMoney())); } else { //条目占比权益的 BigDecimal rate = cardItemInfo.getShareMoney().divide(cardEquity.getShareMoney(), 30, RoundingMode.HALF_UP); addValue.setActualTotal(consumePayCard.getActualTotal().multiply(rate).setScale(2, RoundingMode.HALF_UP)); addValue.setDeductionMoney(consumePayCard.getDeductionMoney().multiply(rate).setScale(2, RoundingMode.HALF_UP)); } }else if (cardEquity.getEquityType().equals(CardEquity.EQUITY_TYPE_N_M)){ //权益是N选M,那么每次选的那个按金额占比分配,注意最后一个M if (isLast && i == groupSonList.size() - 1) { addValue.setActualTotal(consumePayCard.getActualTotal().subtract(useValue.getActualTotal())); addValue.setDeductionMoney(consumePayCard.getDeductionMoney().subtract(useValue.getDeductionMoney())); } else { //分成N份,每份都相同 addValue.setActualTotal(consumePayCard.getActualTotal().divide(new BigDecimal(cardEquity.getValue()), 2, RoundingMode.DOWN)); addValue.setDeductionMoney(consumePayCard.getDeductionMoney().divide(new BigDecimal(cardEquity.getValue()), 2, RoundingMode.DOWN)); } }else if (cardEquity.getEquityType().equals(CardEquity.EQUITY_TYPE_TIME_CARD)){ //权益是次卡,默认就是平均分配(只是计算的时候,需要看是否次数用完) addValue.setActualTotal(consumePayCard.getActualTotal().divide(new BigDecimal(cardEquity.getValue()), 2, RoundingMode.DOWN)); addValue.setDeductionMoney(consumePayCard.getDeductionMoney().divide(new BigDecimal(cardEquity.getValue()), 2, RoundingMode.DOWN)); } commonService.insert(ConsumePayCardMapper.class, addValue); returnItemMap.put(consumePayCard.getConsumePayItemId(), addValue); } }else { //分配过了 returnItemMap.putAll(buyInfoMap.get(orderItemSon.getCardItemInfoId())); } returnDataMap.put(cardItemInfo.getId(), returnItemMap); } } return returnDataMap; } /** * 处理权益分配OCC金额数据 * * @param buyEquMap 已经分配的权益数据 * @param consumePayCardMap 分配的卡项金额数据 * @param cardItem 卡项数据 * @param orderItemSonList 购买子单数据 */ private Map> getUserCardEquMoneyMap(Map> buyEquMap , Map consumePayCardMap, CardItem cardItem, List orderItemSonList) { //每个权益的金额数据(方法内部已排序,金额字段在shareMoney) List cardEquityMoneyList = UserCardTool.getCardEquityMoneyList(null, cardItem, commonService); //权益数据,未购买过的 Map noBuyMap = new HashMap<>(); for (CardEquity cardEquity : cardEquityMoneyList) { if (buyEquMap.get(cardEquity.getId()) == null) { noBuyMap.put(cardEquity.getId(), cardEquity); } } //算出已经分配的权益的总额 Map payTotalMap = new HashMap<>(); ConsumePayCard useValue = null; for (Map.Entry> entry : buyEquMap.entrySet()) { for (Map.Entry itemEntry : entry.getValue().entrySet()) { useValue = payTotalMap.get(itemEntry.getKey()); if (useValue == null) { useValue = new ConsumePayCard(); } useValue.actualTotalAdd(itemEntry.getValue().getActualTotal()); useValue.deductionMoneyAdd(itemEntry.getValue().getDeductionMoney()); payTotalMap.put(itemEntry.getKey(), useValue); } } //购买的权益标识 List buyEquList = orderItemSonList.stream().map(OrderItemSon::getCardEquityId).collect(Collectors.toList()); //剔除不是这次购买的 cardEquityMoneyList.removeIf(cardEquity -> !buyEquList.contains(cardEquity.getId())); cardEquityMoneyList = cardEquityMoneyList.stream().sorted(Comparator.comparing(CardEquity::getShareMoney)).collect(Collectors.toList()); for (String equId : buyEquList) { noBuyMap.remove(equId); } //此次是否买完了最后的权益 boolean isLast = noBuyMap.size() == 0; //返回数据 Map> returnDataMap = new HashMap<>(); Map returnItemMap = null; for (Map.Entry cardEntry : consumePayCardMap.entrySet()) { //卡项分摊的金额 ConsumePayCard consumePayCard = cardEntry.getValue(); //权益 CardEquity cardEquity = null; //新增分配数据 ConsumePayCard addValue = null; for (int i = 0; i < cardEquityMoneyList.size(); i++) { cardEquity = cardEquityMoneyList.get(i); returnItemMap = returnDataMap.get(cardEquity.getId()); if (returnItemMap == null) { returnItemMap = new HashMap<>(); } if (buyEquMap.get(cardEquity.getId()) == null) { //没有这个权益的OCC数据 addValue = new ConsumePayCard(); addValue.setConsumePayItemId(consumePayCard.getConsumePayItemId()); addValue.setPaymentMethodId(consumePayCard.getPaymentMethodId()); addValue.setNumberNo(consumePayCard.getNumberNo()); addValue.setName(consumePayCard.getName()); addValue.setCommonType(ConsumePayCard.TYPE_EQU); addValue.setCommonId(cardEquity.getId()); addValue.setUserCardId(consumePayCard.getUserCardId()); addValue.setOrderItemId(consumePayCard.getOrderItemId()); addValue.setOrderId(consumePayCard.getOrderId()); addValue.setDeductionType(consumePayCard.getDeductionType()); //获取使用了的总额 useValue = payTotalMap.get(consumePayCard.getConsumePayItemId()); if (isLast && i == cardEquityMoneyList.size() - 1) { addValue.setActualTotal(consumePayCard.getActualTotal().subtract(useValue.getActualTotal())); addValue.setDeductionMoney(consumePayCard.getDeductionMoney().subtract(useValue.getDeductionMoney())); } else { //权益占比卡项的 BigDecimal rate = cardEquity.getShareMoney().divide(cardItem.getTotal(), 30, RoundingMode.HALF_UP); addValue.setActualTotal(consumePayCard.getActualTotal().multiply(rate).setScale(2, RoundingMode.HALF_UP)); addValue.setDeductionMoney(consumePayCard.getDeductionMoney().multiply(rate).setScale(2, RoundingMode.HALF_UP)); } commonService.insert(ConsumePayCardMapper.class, addValue); returnItemMap.put(consumePayCard.getConsumePayItemId(), addValue); } else { returnItemMap.putAll(buyEquMap.get(cardEquity.getId())); } returnDataMap.put(cardEquity.getId(), returnItemMap); } } return returnDataMap; } /** * 处理卡项分配OCC金额数据 * * @param buyTotalMap 分配的卡项金额数据 * @param userCard 客户卡项 * @param orderItemBuy 客户卡项来源子单 * @param consumePayItemList 子项支付数据 */ private Map getUserCardMoneyMap(Map> buyTotalMap , UserCard userCard, OrderItem orderItemBuy, List consumePayItemList) { //是否用剩余全部:未分配过这个卡+判断是不是最后的(已分配的数量+当前 = 购买数量) boolean useRemain = false; if (buyTotalMap.get(userCard.getId()) == null && orderItemBuy.getBuyNum() == (buyTotalMap.keySet().size() + 1)) { useRemain = true; } //这张卡分配的金额数据,优先拿之前分配好的 Map cardBuyMoneyMap = buyTotalMap.get(userCard.getId()); if (cardBuyMoneyMap == null) { //未分配过,进行金额分配 cardBuyMoneyMap = new HashMap<>(); //算出已经分配的总的 Map payTotalMap = new HashMap<>(); ConsumePayCard useValue = null; for (Map.Entry> entry : buyTotalMap.entrySet()) { for (Map.Entry itemEntry : entry.getValue().entrySet()) { useValue = payTotalMap.get(itemEntry.getKey()); if (useValue == null) { useValue = new ConsumePayCard(); } useValue.actualTotalAdd(itemEntry.getValue().getActualTotal()); useValue.deductionMoneyAdd(itemEntry.getValue().getDeductionMoney()); payTotalMap.put(itemEntry.getKey(), useValue); } } //新增分配数据 ConsumePayCard addValue = null; for (ConsumePayItem consumePayItem : consumePayItemList) { addValue = new ConsumePayCard(); addValue.setConsumePayItemId(consumePayItem.getId()); addValue.setPaymentMethodId(consumePayItem.getPaymentMethodId()); addValue.setNumberNo(consumePayItem.getNumberNo()); addValue.setName(consumePayItem.getName()); addValue.setCommonType(ConsumePayCard.TYPE_CARD); addValue.setCommonId(userCard.getId()); addValue.setUserCardId(userCard.getId()); addValue.setOrderItemId(orderItemBuy.getId()); addValue.setOrderId(orderItemBuy.getOrderId()); addValue.setDeductionType(consumePayItem.getDeductionType()); //获取使用了的总额 useValue = payTotalMap.get(consumePayItem.getId()); if (useRemain) { addValue.setActualTotal(consumePayItem.getActualTotal().subtract(useValue.getActualTotal())); addValue.setDeductionMoney(consumePayItem.getDeductionMoney().subtract(useValue.getDeductionMoney())); } else { if (consumePayItem.getActualTotal().compareTo(BigDecimal.ZERO) == 0) { addValue.setActualTotal(BigDecimal.ZERO); } else { addValue.setActualTotal(consumePayItem.getActualTotal().divide(new BigDecimal(orderItemBuy.getBuyNum()), 2, RoundingMode.DOWN)); } if (consumePayItem.getDeductionMoney().compareTo(BigDecimal.ZERO) == 0) { addValue.setDeductionMoney(BigDecimal.ZERO); } else { addValue.setDeductionMoney(consumePayItem.getDeductionMoney().divide(new BigDecimal(orderItemBuy.getBuyNum()), 2, RoundingMode.DOWN)); } } commonService.insert(ConsumePayCardMapper.class, addValue); cardBuyMoneyMap.put(consumePayItem.getId(), addValue); } } return cardBuyMoneyMap; } /**更新用户项目数据*/ 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 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 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 consumePayList){ //遍历累加已支付积分 BigDecimal actualTotalPoints = BigDecimal.ZERO; for(ConsumePay consumePay : consumePayList){ actualTotalPoints = actualTotalPoints.add(consumePay.getActualTotal()); } SqlSentence sqlSentence = new SqlSentence(); Map 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 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 getSkuCashByItemList(List canIntegralCashIdList,List orderItemList,IntegralCashVo integralCashVo) { //最大可抵扣现金返回数据 Map returnMap = new HashMap<>(); Map 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; } }