chenjiahe
2023-04-02 2a45d42cebd76d0f0add392c0e06d2cbbb36c63f
提交 | 用户 | age
a1c527 1 package com.hx.phip.tool.refund;
4df03d 2
ae6ff7 3 import com.hx.common.service.CommonService;
4df03d 4 import com.hx.exception.TipsException;
ae6ff7 5 import com.hx.phiappt.model.refund.RefundRecordConsumePay;
4df03d 6 import com.hx.phip.vo.order.payment.PayMethodVo;
C 7 import com.hx.phip.vo.order.refund.DistributionRedundMethodVo;
8 import com.hx.phip.vo.order.refund.DistributionRedundVo;
9
10 import java.math.BigDecimal;
11 import java.math.RoundingMode;
12 import java.util.ArrayList;
13 import java.util.Comparator;
14 import java.util.List;
ae6ff7 15 import java.util.Map;
4df03d 16 import java.util.stream.Collectors;
C 17
18 /**计算支付方式金额
19  * @author CJH
20  */
21 public class PaymentCountTool {
22
23     /**计算支付方式的金额
ae6ff7 24      * @param itemId 子单方式
4df03d 25      * @param total 总金额
C 26      * @param realRefundTotal 已退总金额
27      * @param sum 购买总数量
28      * @param surplusNum 剩余数量
1869f3 29      * @param refundTotal 计算总金额,空值自动计算
C 30      * @param refundNum 计算数量
4df03d 31      * @param payMethodVoList 支付方式,查询consumePay子类
C 32      * @return 参数结构
33      */
ae6ff7 34     public static DistributionRedundVo countMakeWay(String itemId, BigDecimal total, BigDecimal realRefundTotal, Integer sum, Integer surplusNum
1869f3 35             , BigDecimal refundTotal,Integer refundNum, List<PayMethodVo> payMethodVoList, CommonService commonService){
4df03d 36
C 37         if(surplusNum == null){
38             throw new TipsException("可退款数量不能为空!");
39         }
1869f3 40         if(refundNum == null){
4df03d 41             throw new TipsException("退款数量不能为空!");
C 42         }
43
44         //创建返回结构
45         DistributionRedundVo distributionRedundVo = new DistributionRedundVo();
46
47         //退款数量占总数占比计算
1869f3 48         BigDecimal scale = BigDecimal.valueOf(refundNum).divide(BigDecimal.valueOf(sum),15, RoundingMode.HALF_UP);
ae6ff7 49         //剩余可退款金额
C 50         BigDecimal surplusTotal = total.subtract(realRefundTotal).setScale(2,RoundingMode.HALF_UP);
2a45d4 51         System.out.println("realRefundTotal:"+realRefundTotal);
C 52         System.out.println("surplusTotal:"+surplusTotal);
ae6ff7 53         //算出本次要退款金额
1869f3 54         if(refundTotal == null){
C 55             if(surplusNum.equals(refundNum)) {
56                 //最后退款数量
ae6ff7 57                 refundTotal = surplusTotal;
1869f3 58             }else{
C 59                 //不是最后退款数量,根据退款数量占比来算退款金额
60                 refundTotal = total.multiply(scale).setScale(2,RoundingMode.HALF_UP);
61                 if(refundTotal.compareTo(surplusTotal) > 0){
62                     refundTotal = surplusTotal;
63                 }
ae6ff7 64             }
4df03d 65         }
2a45d4 66         System.out.println("refundTotal:"+refundTotal);
4df03d 67         //转载分配好的支付方式和金额
C 68         List<DistributionRedundMethodVo> distributionPayList = new ArrayList<>();
69         if(payMethodVoList != null && payMethodVoList.size() > 0){
ae6ff7 70
C 71             //获取已退款的支付方式金额
72             List<RefundRecordConsumePay> refundRecordConsumePayList = PartialRefundUtil.getRefundRecordConsumePay(itemId,null,true,false,commonService);
73
74             ///////把已退款的金额注入进去
75             //转化为map,下面注入退款金额用到
76             Map<String, PayMethodVo> payMethodVoMap = payMethodVoList.stream().collect(Collectors.toMap(PayMethodVo::getNumberNo,(a) -> a));
77             PayMethodVo payMethodVo;
78             for(RefundRecordConsumePay refundRecordConsumePay:refundRecordConsumePayList){
79                 payMethodVo = payMethodVoMap.get(refundRecordConsumePay.getNumberNo());
80                 if(payMethodVo != null){
81                     //已退款金额
82                     payMethodVo.setRefundTotal(payMethodVo.getRefundTotal().add(refundRecordConsumePay.getRefundTotal()).setScale(2,RoundingMode.HALF_UP));
83                     //剩余未退款金额
84                     payMethodVo.setSurplusTotal(payMethodVo.getSurplusTotal().subtract(refundRecordConsumePay.getRefundTotal()).setScale(2,RoundingMode.HALF_UP));
85                 }
86             }
87
4df03d 88             //支付方式进行升序排序,避免循环支付方式的时候最后一个可分配0元,从而导致算子单最后一个的时候没有钱算了
C 89             payMethodVoList = payMethodVoList.stream().sorted(Comparator.comparing(PayMethodVo::getSurplusTotal)).collect(Collectors.toList());
90
91             DistributionRedundMethodVo distributionPay;
ae6ff7 92
4df03d 93             for(int i = 0;i<payMethodVoList.size();i++){
C 94                 payMethodVo = payMethodVoList.get(i);
95                 //赋值
96                 distributionPay = new DistributionRedundMethodVo();
97                 distributionPay.setName(payMethodVo.getName());
98                 distributionPay.setNumberNo(payMethodVo.getNumberNo());
99                 distributionPay.setIsMoneyPay(payMethodVo.getIsMoneyPay());
100                 distributionPay.setIsExecute(payMethodVo.getIsExecute());
101
1869f3 102                 if(surplusNum.equals(refundNum)){
4df03d 103                     ////是退款最后的数量
C 104                     distributionPay.setRefundTotal(payMethodVo.getSurplusTotal());
105                 }else{
106                     ////不是最后退款的数量
107                     if(i == payMethodVoList.size()-1){
108                         ////是最后一个循环
109                         distributionPay.setRefundTotal(refundTotal);
110                     }else{
111                         ////不是最后一个循环
112                         //如果第三位小数有余数,那么就进1分钱
113                         distributionPay.setRefundTotal(payMethodVo.getPayTotal().multiply(scale).setScale(2,RoundingMode.UP));
114                     }
1869f3 115                 }
C 116                 //判断与剩余金额对比
117                 if(distributionPay.getRefundTotal().compareTo(payMethodVo.getSurplusTotal()) > 0){
118                     distributionPay.setRefundTotal(payMethodVo.getSurplusTotal());
4df03d 119                 }
C 120                 if(distributionPay.getRefundTotal().compareTo(refundTotal) > 0){
121                     distributionPay.setRefundTotal(refundTotal);
122                 }
123                 //计算剩余要分配的退款金额
124                 refundTotal  = refundTotal.subtract(distributionPay.getRefundTotal()).setScale(2,RoundingMode.HALF_UP);
125                 //存储封装好的对象
126                 distributionPayList.add(distributionPay);
127
128                 ////返回的其他金额计算
129                 //退款总金额计算
130                 distributionRedundVo.setRefundTotal(distributionRedundVo.getRefundTotal().add(distributionPay.getRefundTotal()).setScale(2,RoundingMode.HALF_UP));
131                 if(distributionPay.getIsMoneyPay() ==  DistributionRedundMethodVo.NUM_1){
132                     //现金金额
133                     distributionRedundVo.setRefundCash(distributionRedundVo.getRefundCash().add(distributionPay.getRefundTotal()).setScale(2,RoundingMode.HALF_UP));
134                 }
135                 if(distributionPay.getIsExecute() ==  DistributionRedundMethodVo.NUM_1){
136                     //划扣金额
137                     distributionRedundVo.setRefundExecute(distributionRedundVo.getRefundExecute().add(distributionPay.getRefundTotal()).setScale(2,RoundingMode.HALF_UP));
138                 }
139             }
140         }
141         distributionRedundVo.setDistributionRedundMethodVoList(distributionPayList);
142
143         return distributionRedundVo;
144     }
145
146 }