fwq
2024-09-03 ffe822f1a94bb0f2fbc589a99e8b9c538a73a934
其-卡包订单结账-优化逻辑
2个文件已修改
189 ■■■■■ 已修改文件
phi_platform_common/src/main/java/com/hx/phip/tool/user/UserCardTool.java 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
phi_platform_user/src/main/java/com/hx/phip/service/init/impl/OrderInitServiceImpl.java 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
phi_platform_common/src/main/java/com/hx/phip/tool/user/UserCardTool.java
@@ -556,7 +556,7 @@
    /**
     * 卡包权益支付过的数据
     * 卡包权益支付过的数据-剔除退款的数据
     */
    public static List<UserCardPay> getCardBagEquityMoney(String cardEquityId, CardEquity cardEquity, CommonService commonService) {
        SqlSentence sqlSentence = new SqlSentence();
@@ -570,12 +570,21 @@
        sql.append(" SELECT SUM(u.actualTotal) AS actualTotal,SUM(u.deductionMoney) AS deductionMoney,u.numberNo  ");
        sql.append(" FROM user_card_pay AS u  ");
        sql.append(" JOIN orders_total AS ot ON ot.id = u.orderId");
        sql.append(" WHERE ot.isDel = #{m.isDel} AND ot.cardEquityId = #{m.cardEquityId} ");
        //卡包要么全退,要么不退
        sql.append(" AND ot.payStatus = 3 AND ot.refundStatus = -1 ");
        sql.append(" GROUP BY ot.numberNo  ");
        sql.append(" WHERE u.isDel = #{m.isDel} AND u.cardEquityId = #{m.cardEquityId} ");
        //卡包要么全退,要么不退,这里查未退款的
        sql.append(" AND ot.isDel = #{m.isDel} AND ot.payStatus = 3 AND ot.refundStatus = -1 ");
        sql.append(" GROUP BY u.numberNo  ");
        sqlSentence.sqlSentence(sql.toString(), values);
        return commonService.selectList(UserCardPayMapper.class, sqlSentence);
    }
    /**获取卡项权益的条目数量*/
    public static List<CardItemInfo> getCardInfoList(String cardEquityId,CommonService commonService){
        SqlSentence sqlSentence = new SqlSentence();
        Map<String,Object> values = new HashMap<>();
        values.put("cardEquityId",cardEquityId);
        sqlSentence.sqlSentence("SELECT * FROM card_item_info WHERE isDel = 0 AND cardEquityId = #{m.cardEquityId}",values);
        return commonService.selectList(CardItemInfoMapper.class,sqlSentence);
    }
}
phi_platform_user/src/main/java/com/hx/phip/service/init/impl/OrderInitServiceImpl.java
@@ -1524,7 +1524,7 @@
        //获取用户卡项
        UserCard userCard = userCardMapper.selectOneByKey(orderItem.getUserCardId());
        if (userCard == null) {
            logger.info("未找到用户的卡项!!!!!!!!!!!!!"+orderItem.getUserCardId());
            logger.info("!!!!!!!未找到用户的卡项!!!!!!!!"+JSON.toJSONString(orderItem));
            return;
        }
        SqlSentence sqlSentence = new SqlSentence();
@@ -1540,23 +1540,25 @@
            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 (userCardMapper.updateWhere(sqlSentence) != 1){
                    throw new TipsException("获取购买卡项订单数据失败[01],请联系管理员");
                }
            }
        }
        if (orderItemBuy == null) {
            throw new TipsException("获取购买卡项订单数据失败[01],请联系管理员");
            throw new TipsException("获取购买卡项订单数据失败[02],请联系管理员");
        }
        //获取卡项配置
        CardItem cardItem = cardItemMapper.selectOneByKey(orderItemBuy.getCommonId());
        if (cardItem == null) {
            throw new TipsException("获取购买卡项订单数据失败[02],请联系管理员");
            throw new TipsException("获取购买卡项订单数据失败[03],请联系管理员");
        }
        //子单支付总数据
        //买卡子单支付总数据
        List<PayMethodVo> groupByNumberNoList = refundMapper.getConsumePayOneGroupByNumberNo(orderItemBuy.getId());
        Map<String, PayMethodVo> groupByNumberNoMap = new HashMap<>();
        for (PayMethodVo payMethodVo : groupByNumberNoList) {
@@ -1565,13 +1567,17 @@
            payMethodVo.setDeductionMoney(payMethodVo.getDeductionMoney().divide(new BigDecimal(orderItemBuy.getBuyNum()),2,RoundingMode.HALF_UP));
            groupByNumberNoMap.put(payMethodVo.getNumberNo(), payMethodVo);
        }
        logger.info("买卡子单,支付数据总和:"+JSON.toJSONString(groupByNumberNoMap));
        //子单支付方式数据
        List<ConsumePayItem> consumePayItemList = refundMapper.selectConsumePayOneList(orderItemBuy.getId());
        values.put("typeId", orderItemBuy.getId());
        sqlSentence.sqlSentence("SELECT * FROM consume_pay_item WHERE isDel = 0 AND typeId = #{m.typeId} ",values);
        List<ConsumePayItem> consumePayItemList = commonService.selectList(ConsumePayItemMapper.class,sqlSentence);
        for (ConsumePayItem consumePayItemVo : consumePayItemList) {
            //要注意可能买多张
            consumePayItemVo.setActualTotal(consumePayItemVo.getActualTotal().divide(new BigDecimal(orderItemBuy.getBuyNum()),2,RoundingMode.HALF_UP));
            consumePayItemVo.setDeductionMoney(consumePayItemVo.getDeductionMoney().divide(new BigDecimal(orderItemBuy.getBuyNum()),2,RoundingMode.HALF_UP));
        }
        logger.info("买卡子单,单卡的支付方式:"+JSON.toJSONString(consumePayItemList));
        //卡项权益,支付方式编号,支付方式数据
        Map<String, Map<String, ConsumePayItem>> cardEquityMethodMap = new HashMap<>();
@@ -1580,7 +1586,9 @@
        //每个权益的总金额数据
        Map<String,CardEquity> cardEquityMapTotal = new HashMap<>();
        CardEquity cardEquity = null;
        //每个权益的金额数据
        //权益标识,是否是全部使用完,通过判断条目的最终剩余次数来看是不是最后一个
        Map<String, Boolean> cardEquityNumMap = new HashMap<>();
        //每个权益的金额数据(方法内部已排序,金额字段在shareMoney)
        List<CardEquity> cardEquityMoneyList = UserCardTool.getCardEquityMoneyList(null, cardItem, commonService);
        for (int i = 0; i < cardEquityMoneyList.size(); i++) {
            cardEquity = cardEquityMoneyList.get(i);
@@ -1596,10 +1604,13 @@
            if (methodMap == null) {
                methodMap = new HashMap<>();
            }
            //循环买卡的支付方式,封装每个权益的分配支付方式金额
            for (ConsumePayItem consumePayItemVo : consumePayItemList) {
                //获取该支付方式的总额
                PayMethodVo payMethodVo = groupByNumberNoMap.get(consumePayItemVo.getNumberNo());
                logger.info("循环买卡子单的支付方式{}:,对应的总金额:{}"+JSON.toJSONString(consumePayItemVo),JSON.toJSONString(payMethodVo));
                logger.info("循环:{},支付方式:{}",cardEquity.getId(),consumePayItemVo.getNumberNo());
                logger.info("支付金额:{},抵扣金额:{}",consumePayItemVo.getActualTotal(),consumePayItemVo.getDeductionMoney());
                logger.info("总额:{},总抵扣金额:{}",payMethodVo.getPayTotal(),payMethodVo.getDeductionMoney());
                //计算当前要分摊的金额
                BigDecimal actualTotal = BigDecimal.ZERO;
@@ -1612,6 +1623,8 @@
                    actualTotal = payMethodVo.getPayTotal();
                    deductionMoney = payMethodVo.getDeductionMoney();
                }
                logger.info("比例:{},分配金额:{},抵扣金额:{}",rate,actualTotal,deductionMoney);
                //减去分配的金额
                payMethodVo.setPayTotal(payMethodVo.getPayTotal().subtract(actualTotal));
                payMethodVo.setDeductionMoney(payMethodVo.getDeductionMoney().subtract(deductionMoney));
@@ -1621,28 +1634,47 @@
                if (payMethodVo.getDeductionMoney().compareTo(BigDecimal.ZERO) < 0) {
                    throw new RuntimeException("卡包抵扣金额分配错误[0223]");
                }
                //更新map总剩余金额
                groupByNumberNoMap.put(payMethodVo.getNumberNo(), payMethodVo);
                //封装每个权益的支付方式
                consumePayItem = methodMap.get(consumePayItemVo.getNumberNo());
                if (consumePayItem == null) {
                    consumePayItem = consumePayItemVo;
                    consumePayItem = new ConsumePayItem();
                    BeanUtils.copyProperties(consumePayItemVo,consumePayItem);
                    consumePayItem.setActualTotal(BigDecimal.ZERO);
                    consumePayItem.setDeductionMoney(BigDecimal.ZERO);
                }
                consumePayItem.actualTotalAdd(actualTotal);
                consumePayItem.deductionMoneyAdd(deductionMoney);
                methodMap.put(consumePayItemVo.getNumberNo(), consumePayItem);
            }
            cardEquityMethodMap.put(cardEquity.getId(), methodMap);
            //查询用户的卡项对应的这个权益,是否使用完
            cardEquityNumMap.put(cardEquity.getId(),true);
            List<CardItemInfo> cardInfoList = UserCardTool.getCardInfoList(cardEquity.getId(), commonService);
            if (cardInfoList != null && cardInfoList.size() > 0){
                for (CardItemInfo cardItemInfo : cardInfoList) {
                    //获取这个条目剩余的次数
                    UserCardItemInfoVo userCardItemInfoVo = UserCardTool.getSurplusNumber(userCard, cardItemInfo, null, commonService);
                    logger.info("权益{},条目:{},剩余:{}",cardEquity.getId(),cardItemInfo.getId(),userCardItemInfoVo.getSurplusNum());
                    if (userCardItemInfoVo.getSurplusNum() != null && userCardItemInfoVo.getSurplusNum() > 0){
                        cardEquityNumMap.put(cardEquity.getId(),false);
                        break;
                    }
                }
                logger.info("权益:{},是否是最后一个:{}",cardEquity.getId(),cardEquityNumMap.get(cardEquity.getId()));
            }
        }
        logger.info("-----计算条目金额------");
        //这一步算出当前卡包购买的权益下,每个条目应分摊的金额(算出占比权益)
        //权益标识,开卡选择的条目标识,条目数据
        Map<String, Map<String,CardItemInfo>> cardEquityMap = new HashMap<>();
        Map<String,CardItemInfo> cardItemInfoMap = null;
        CardItemInfo cardItemInfo = null;
        //权益标识,是否是全部使用完,通过判断条目的最终剩余次数来看是不是最后一个
        Map<String, Boolean> cardEquityNumMap = new HashMap<>();
        for (OrderItemSon itemSon : orderItemSonList) {
            //获取卡项的条目
            cardItemInfo = cardItemInfoMapper.selectOneByKey(itemSon.getCardItemInfoId());
@@ -1656,11 +1688,11 @@
            } else {
                deductionNun = itemSon.getBuyNum();
            }
            //这次购买的金额(用于分配金额时排序,规则:用单次x数量)
            BigDecimal infoShareMoney = UserCardTool.countOneMoney(cardItemInfo).multiply(new BigDecimal(deductionNun).setScale(2, RoundingMode.DOWN));
            //这次购买的金额(规则:单次x数量)
            BigDecimal infoShareMoney = UserCardTool.countOneMoney(cardItemInfo).multiply(new BigDecimal(deductionNun)).setScale(2, RoundingMode.DOWN);
            cardItemInfo.setInfoShareMoney(infoShareMoney);
            itemSon.setInfoShareMoney(infoShareMoney);
            logger.info("条目:{},条目总次数金额:{}",cardItemInfo.getId(),infoShareMoney);
            logger.info("权益{},条目:{},条目总次数金额:{}",itemSon.getCardEquityId(),cardItemInfo.getId(),infoShareMoney);
            //按照权益进行分组
            cardItemInfoMap = cardEquityMap.get(itemSon.getCardEquityId());
            if (cardItemInfoMap == null) {
@@ -1668,28 +1700,17 @@
            }
            cardItemInfoMap.put(itemSon.getCardItemInfoId(), cardItemInfo);
            cardEquityMap.put(itemSon.getCardEquityId(), cardItemInfoMap);
            //是否使用完这个权益
            Boolean eqBoolean = cardEquityNumMap.get(itemSon.getCardEquityId());
            if (eqBoolean == null){
                eqBoolean = true;
            }
            //获取这个条目剩余的次数
            UserCardItemInfoVo userCardItemInfoVo = UserCardTool.getSurplusNumber(userCard, cardItemInfo, null, commonService);
            if (userCardItemInfoVo.getSurplusNum() != null && userCardItemInfoVo.getSurplusNum() > 0){
                eqBoolean = false;
            }
            logger.info("条目:{},剩余:{},判断权益是否是最后一个:{}",cardItemInfo.getId(),userCardItemInfoVo.getSurplusNum(),eqBoolean);
            cardEquityNumMap.put(itemSon.getCardEquityId(),eqBoolean);
        }
        //到这一步的时候,用户卡项使用记录会有记录
        //每个权益已经使用了的金额
        logger.info("-----计算已使用金额------");
        //到这一步的时候,用户卡项使用记录会有记录,拿到每个权益已经使用了的金额
        //权益标识,支付方式编号,已购买数据
        Map<String, Map<String, ConsumePayItem>> cardEquityMapUsedTotal = new HashMap<>();
        Map<String, ConsumePayItem> usedCardEqu = null;
        List<UserCardPay> cardBagEquityMoney = null;
        for (Map.Entry<String, CardEquity> stringCardEquityEntry : cardEquityMapTotal.entrySet()) {
            cardEquity = stringCardEquityEntry.getValue();
            List<UserCardPay> cardBagEquityMoney = UserCardTool.getCardBagEquityMoney(null, cardEquity, commonService);
            methodMap = cardEquityMapUsedTotal.get(cardEquity.getCardItemId());
            cardBagEquityMoney = UserCardTool.getCardBagEquityMoney(null, cardEquity, commonService);
            methodMap = cardEquityMapUsedTotal.get(cardEquity.getId());
            if (methodMap == null){
                methodMap = new HashMap<>();
            }
@@ -1702,15 +1723,17 @@
                        consumePayItem.setActualTotal(BigDecimal.ZERO);
                        consumePayItem.setDeductionMoney(BigDecimal.ZERO);
                    }
                    consumePayItem.deductionMoneyAdd(userCardPay.getDeductionMoney());
                    consumePayItem.actualTotalAdd(userCardPay.getActualTotal());
                    consumePayItem.deductionMoneyAdd(userCardPay.getDeductionMoney());
                    methodMap.put(userCardPay.getNumberNo(),consumePayItem);
                    logger.info("权益:{},已用支付:{},已用金额:{},已用抵扣金额:{}",cardEquity.getId(),userCardPay.getNumberNo()
                            ,userCardPay.getActualTotal(),userCardPay.getDeductionMoney());
                }
            }
            cardEquityMapUsedTotal.put(cardEquity.getCardItemId(),methodMap);
            cardEquityMapUsedTotal.put(cardEquity.getId(),methodMap);
        }
        logger.info("卡项权益已经使用了的金额:{}",JSON.toJSONString(cardEquityMapUsedTotal));
        //到这里才是真正算这次卡包开单分配的钱
        //按权益分组
        Map<String,List<OrderItemSon>> cardItemInfoListMap = orderItemSonList.stream().collect(Collectors.groupingBy(OrderItemSon::getCardEquityId));
        for (Map.Entry<String, List<OrderItemSon>> entry : cardItemInfoListMap.entrySet()) {
@@ -1718,10 +1741,13 @@
            cardEquity = cardEquityMapTotal.get(entry.getKey());
            //这个权益的总支付金额数据
            methodMap = cardEquityMethodMap.get(entry.getKey());
            //这个权益已使用支付金额数据
            Map<String, ConsumePayItem> usedCardEqu = cardEquityMapUsedTotal.get(entry.getKey());
            //这个权益的条目数据
            //这个权益已使用了的支付金额数据
            usedCardEqu = cardEquityMapUsedTotal.get(entry.getKey());
            //这个权益下的购买的条目数据
            cardItemInfoMap = cardEquityMap.get(entry.getKey());
            //当前结账权益已分配的金额(单前的卡包单可能会有同一个权益不同条目)
            Map<String,ConsumePayItem> usedMap = new HashMap<>();
            //这个权益下购买的条目,按金额排序
            List<OrderItemSon> infoList = entry.getValue().stream().sorted(Comparator.comparing(OrderItemSon::getInfoShareMoney)).collect(Collectors.toList());
            for (int i = 0; i < infoList.size(); i++) {
@@ -1732,17 +1758,19 @@
                BigDecimal totalNoDeductionMoney = BigDecimal.ZERO;
                //条目占比权益
                BigDecimal proportion = null;
                //这次购买,权益次数已用完
                //这次购买,权益次数已用完,需要直接扣完
                if (cardEquityNumMap.get(entry.getKey())){
                    //权益次数用完,需要直接扣完
                    //不是最后一个则按比例
                    if (i != infoList.size()-1){
                        proportion = cardItemInfo.getInfoShareMoney().divide(cardEquity.getShareMoney(), 20, RoundingMode.HALF_UP);
                    }
                }else {
                    //不是最后一个则按比例
                    proportion = cardItemInfo.getInfoShareMoney().divide(cardEquity.getShareMoney(), 20, RoundingMode.HALF_UP);
                }
                logger.info("条目:{},占比权益:{}",cardItemInfo.getId(),proportion);
                //循环支付方式
                logger.info("权益:{},条目:{},占比权益:{}",cardEquity.getId(),cardItemInfo.getId(),proportion);
                //权益占比卡项支付方式的数据
                for (Map.Entry<String, ConsumePayItem> payItemEntry : methodMap.entrySet()) {
                    UserCardPay userCardPay = new UserCardPay();
                    //当前订单数据
@@ -1759,6 +1787,8 @@
                    //权益的支付方式
                    ConsumePayItem value = payItemEntry.getValue();
                    logger.info("{},--------循环支付方式-----",payItemEntry.getKey());
                    logger.info("权益分配金额:{},抵扣:{}",value.getActualTotal(),value.getDeductionMoney());
                    //存储买卡的支付数据
                    userCardPay.setConsumePayItemId(value.getId());
                    userCardPay.setPaymentMethodId(value.getPaymentMethodId());
@@ -1768,19 +1798,51 @@
                    userCardPay.setIsExecute(value.getIsExecute());
                    userCardPay.setIsPay(value.getIsPay());
                    userCardPay.setDeductionType(value.getDeductionType());
                    //当前卡包单下权益已经分配了的数据
                    ConsumePayItem usedItem = usedMap.get(value.getNumberNo());
                    if (usedItem == null){
                        usedItem = new ConsumePayItem();
                        usedItem.setActualTotal(BigDecimal.ZERO);
                        usedItem.setDeductionMoney(BigDecimal.ZERO);
                    }
                    logger.info("当前其它权益已分金额:{},抵扣:{}",usedItem.getActualTotal(),usedItem.getDeductionMoney());
                    //分摊买卡的支付数据
                    BigDecimal actualTotal = BigDecimal.ZERO;
                    BigDecimal deductionMoney = BigDecimal.ZERO;
                    if (proportion != null){
                        //按比例分配
                        actualTotal = value.getActualTotal().multiply(proportion).setScale(2,RoundingMode.HALF_UP);
                        deductionMoney = value.getDeductionMoney().multiply(proportion).setScale(2,RoundingMode.HALF_UP);
                        actualTotal = value.getActualTotal().multiply(proportion).setScale(2,RoundingMode.DOWN);
                        deductionMoney = value.getDeductionMoney().multiply(proportion).setScale(2,RoundingMode.DOWN);
                    }else {
                        //分配剩余的钱
                        ConsumePayItem usedPayItem = usedCardEqu.get(value.getNumberNo());
                        actualTotal = value.getActualTotal().subtract(usedPayItem.getActualTotal());
                        deductionMoney = value.getDeductionMoney().subtract(usedPayItem.getDeductionMoney());
                        //减去当前结账的钱
                        actualTotal = value.getActualTotal().subtract(usedItem.getActualTotal());
                        deductionMoney = value.getDeductionMoney().subtract(usedItem.getDeductionMoney());
                        logger.info("减去当前其它权益金额:{},抵扣:{}",actualTotal,deductionMoney);
                        //减去以前使用的
                        if (usedCardEqu != null){
                            ConsumePayItem usedPayItem = usedCardEqu.get(value.getNumberNo());
                            if (usedPayItem != null){
                                logger.info("以前权益已分金额:{},抵扣:{}",usedPayItem.getActualTotal(),usedPayItem.getDeductionMoney());
                                actualTotal = actualTotal.subtract(usedPayItem.getActualTotal());
                                deductionMoney = deductionMoney.subtract(usedPayItem.getDeductionMoney());
                                logger.info("减去以前权益金额:{},抵扣:{}",actualTotal,deductionMoney);
                            }
                        }
                    }
                    logger.info("最终分配给条目的金额:{},抵扣:{}",actualTotal,deductionMoney);
                    if (actualTotal.compareTo(BigDecimal.ZERO) < 0){
                        throw new TipsException("卡项金额分配错误[011]");
                    }
                    if (deductionMoney.compareTo(BigDecimal.ZERO) < 0){
                        throw new TipsException("卡项金额分配错误[012]");
                    }
                    //叠加已分配的钱
                    usedItem.actualTotalAdd(actualTotal);
                    usedItem.deductionMoneyAdd(deductionMoney);
                    usedMap.put(value.getNumberNo(),usedItem);
                    //设置分配的钱
                    userCardPay.setActualTotal(actualTotal);
                    userCardPay.setDeductionMoney(deductionMoney);
                    //可划扣金额
@@ -1805,13 +1867,13 @@
                orderItemMapper.updateWhere(sqlSentence);
                //用户项目
                if (OrderItemConstants.TYPE_PROJECT.equals(orderItemSon.getType())) {
                    //更新用户项目
                    if (updateUserProject) {
                        //根据用户项目获取疗程数
                        UserProjectItem userProjectItem = getUserProjectItem(orderItemSon.getId(), ordersTotal.getUserId());
                        //更新用户项目
                        updateUserProject(userProjectItem, orderItemSon.getTotal(), orderItemSon.getActualTotal()
                                , orderItemSon.getOriPrice(), orderItemSon.getCurPrice(), orderItemSon.getBuyNum()
                                , totalNoDeductionMoney, orderItemSon.getUsedTotal(), null);
                        updateUserProject(getUserProjectItem(orderItemSon.getId(), ordersTotal.getUserId())
                                , orderItemSon.getTotal(), orderItemSon.getActualTotal(), orderItemSon.getOriPrice()
                                , orderItemSon.getCurPrice(), orderItemSon.getBuyNum(), totalNoDeductionMoney
                                , orderItemSon.getUsedTotal(), null);
                    }
                }
            }