chenjiahe
2023-08-14 f3ff4ed544dab12f9471a738e106379a466bb5e2
提交 | 用户 | age
a1c527 1 package com.hx.phip.tool.refund;
ae6ff7 2
2b1cfa 3 import com.alibaba.fastjson.JSON;
ae6ff7 4 import com.hx.common.service.CommonService;
C 5 import com.hx.exception.TipsException;
6 import com.hx.mybatisTool.SqlSentence;
7 import com.hx.phiappt.common.*;
8 import com.hx.phiappt.constants.enums.GroupTypeEnum;
9 import com.hx.phiappt.constants.tool.RefundToolUtil;
7c2538 10 import com.hx.phiappt.constants.tool.order.OrderUtil;
ae6ff7 11 import com.hx.phiappt.model.BaseEntity;
C 12 import com.hx.phiappt.model.UserMoney;
13 import com.hx.phiappt.model.activity.ActivityAction;
14 import com.hx.phiappt.model.activity.ActivityRule;
a1c527 15 import com.hx.phiappt.model.cardItem.CardEquity;
C 16 import com.hx.phiappt.model.cardItem.CardItemInfo;
ae6ff7 17 import com.hx.phiappt.model.consume.ConsumePay;
C 18 import com.hx.phiappt.model.consume.ConsumePayItem;
2a45d4 19 import com.hx.phiappt.model.consume.ConsumePayItemSon;
ae6ff7 20 import com.hx.phiappt.model.coupon.CouponNumber;
C 21 import com.hx.phiappt.model.coupon.CouponOrderDiscountLog;
22 import com.hx.phiappt.model.order.*;
23 import com.hx.phiappt.model.refund.*;
24 import com.hx.phiappt.model.user.UserCard;
25 import com.hx.phiappt.model.user.UserCardUsed;
26 import com.hx.phiappt.model.user.UserProjectItem;
27 import com.hx.phiappt.model.userMoney.UserMoneyUnclaimed;
28 import com.hx.phip.dao.mapper.*;
b91aa3 29 import com.hx.phip.service.order.impl.OrderRefundServiceImpl;
a88f94 30 import com.hx.phip.tool.user.UserCardTool;
ae6ff7 31 import com.hx.phip.tool.user.UserProjectTool;
a1c527 32 import com.hx.phip.util.api.UserMoneyUtil;
1869f3 33 import com.hx.phip.vo.order.refund.RefundCarryVo;
C 34 import com.hx.phip.vo.user.UserProjectDeductionVo;
ae6ff7 35 import com.hx.util.StringUtils;
C 36 import com.platform.exception.PlatTipsException;
37 import com.platform.resultTool.PlatformCode;
b91aa3 38 import org.slf4j.Logger;
C 39 import org.slf4j.LoggerFactory;
2a45d4 40 import org.springframework.beans.BeanUtils;
ae6ff7 41
C 42 import java.math.BigDecimal;
43 import java.math.RoundingMode;
44 import java.util.*;
45 import java.util.stream.Collectors;
46
47 /**
48  * @Author
49  */
50 public class PartialRefundUtil {
b91aa3 51
C 52     /**log4j日志*/
53     private static final Logger logger = LoggerFactory.getLogger(OrderRefundServiceImpl.class.getName());
ae6ff7 54
2a45d4 55     /**有子项退款的类型*/
C 56     public static Set<String> CONTAIN_SON_TYPE_SET;
57
ae6ff7 58     /**领建优惠券标识*/
C 59     public static final String HIS_COUPON_CODE = "his_coupon_code";
2a45d4 60
C 61     static {
62         CONTAIN_SON_TYPE_SET = new HashSet<>();
63         CONTAIN_SON_TYPE_SET.add(OrderItemConstants.TYPE_PROMOTION);
64         CONTAIN_SON_TYPE_SET.add(OrderItemConstants.CARD_BAG);
65     }
ae6ff7 66
C 67     /**
68      * 退款总流程工具
a1c527 69      * @param commonService 映射
C 70      * @param operationId 操作人标识
71      * @param operationNme 操作人名称
72      * @param refundId 退款总单标识
ae6ff7 73      */
a1c527 74     public static OrdersTotal refundProcess(CommonService commonService, String operationId, String operationNme, String refundId) {
ae6ff7 75
C 76         RefundRecord refundRecord = commonService.selectOneByKeyBlob(RefundRecordMapper.class,refundId);
77         if(refundRecord ==null){
78             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"找不到该退款信息!");
79         }
80
81         SqlSentence sqlSentence = new SqlSentence();
82         Map<String,Object> values = new HashMap<>();
83
84         //退款总订单状态变更
85         values.put("refundStatus", RefundStatus.STATUS_SUCC_REFUND);
86         values.put("oldRefundStatus", RefundStatus.STATUS_APPLY_REFUND);
2a45d4 87         values.put("refundTotal", refundRecord.getRefundTotal());
ecdbf6 88         values.put("createTime", new Date());
ae6ff7 89         values.put("isDel", BaseEntity.NO);
C 90         values.put("id",refundRecord.getId());
ecdbf6 91         sqlSentence.sqlSentence(" refundTotal = #{m.refundTotal},refundStatus=#{m.refundStatus},createTime = #{m.createTime} WHERE id = #{m.id} AND isDel=#{m.isDel} AND refundStatus = #{m.oldRefundStatus}",values);
ae6ff7 92         if(commonService.updateWhere(RefundRecordMapper.class,sqlSentence) != 1){
C 93             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"操作失败,退款单状态已改变!");
94         }
95
510678 96         //获取订单信息
ae6ff7 97         OrdersTotal ordersTotal = commonService.selectOneByKeyBlob(OrdersTotalMapper.class,refundRecord.getOrderId());
C 98         if(ordersTotal == null ){
99             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到订单信息!");
100         }
101
102         //查询用户是否有账户信息,退款需要处理资金
a1c527 103         values.clear();
ae6ff7 104         values.put("userId",refundRecord.getUserId());
e9e32c 105         sqlSentence.sqlSentence("SELECT * FROM user_money WHERE  userId=#{m.userId} AND isDel=0",values);
ae6ff7 106         UserMoney userMoney=commonService.selectOne(UserMoneyMapper.class,sqlSentence);
C 107         if(userMoney==null){
108             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到该用户的资金信息");
109         }
1869f3 110
C 111         //获取总退款方式
112         values.put("refundRecordId",refundRecord.getId());
113         sqlSentence.sqlSentence("SELECT * FROM refund_record_method WHERE isDel = 0 AND refundRecordId = #{m.refundRecordId}",values);
114         List<RefundRecordMethod> refundRecordMethodList = commonService.selectList(RefundRecordMethodMapper.class,sqlSentence);
115
116         //全程使用携带参数对象
117         RefundCarryVo refundCarryVo = new RefundCarryVo();
118         refundCarryVo.setRefundRecordMethodList(refundRecordMethodList);
ae6ff7 119
C 120         if(OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){
a1c527 121             //处理支付方式和退款方式关联
C 122             refundCarryVo = rechargeRefundMothedHandle(refundCarryVo,refundRecord,commonService);
123         }else{
124             //子单退款项处理
125             refundCarryVo = numberOfRefunds(refundCarryVo,operationId, refundRecord,ordersTotal,commonService);
ae6ff7 126         }
a1c527 127         //处理优惠券
C 128         handCoupon(refundRecord,commonService);
129         //处理总退款方式数据
130         refundCarryVo = refundRecordMotnedHandle(refundCarryVo,operationId,operationNme,refundRecord,ordersTotal,commonService);
ae6ff7 131
C 132         //更改总订单退款状态
133         values.clear();
134         values.put("orderId",ordersTotal.getId());
e9e32c 135         sqlSentence.sqlSentence("select * from order_item WHERE  orderId=#{m.orderId} and isDel=0",values);
ae6ff7 136         List<OrderItem> orderItemList=commonService.selectList(OrderItemMapper.class,sqlSentence);
C 137
f72f73 138         values.clear();
C 139         values.put("oldStatus",ordersTotal.getStatus());
140         values.put("oldRefundStatus",ordersTotal.getRefundStatus());
141
a1c527 142         List<Integer> collect = orderItemList.stream().map(OrderItem::getRefundStatus).collect(Collectors.toList());
ae6ff7 143         if(collect.contains(OrderTotalConstants.STATUS_REFUND_PART)){
C 144             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
145             ordersTotal.setReTotal(orderItemList.stream().map(OrderItem::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
146         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE) && collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
147             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
148             ordersTotal.setReTotal(orderItemList.stream().map(OrderItem::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
149         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE)){
150             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
151         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
152             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_FINSH);
153             ordersTotal.setStatus(OrderTotalConstants.STATUS_CANCEL);
154             ordersTotal.setReTotal(orderItemList.stream().map(OrderItem::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
155         }else {
156             if(OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){
157                 if(ordersTotal.getActualTotal().compareTo(refundRecord.getRefundTotal()) <= 0){
158                     ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_FINSH);
f72f73 159                     ordersTotal.setStatus(OrderTotalConstants.STATUS_CANCEL);
C 160                     ordersTotal.setReTotal(ordersTotal.getReTotal().add(refundRecord.getRefundTotal()));
ae6ff7 161                 }else{
C 162                     ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
f72f73 163                     ordersTotal.setReTotal(ordersTotal.getReTotal().add(refundRecord.getRefundTotal()));
ae6ff7 164                 }
C 165             }else{
166                 ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
167             }
168         }
169         ordersTotal.setIsSyncOrder(BaseEntity.NO);
f72f73 170
C 171         values.put("isSyncOrder",BaseEntity.NO);
172         values.put("status",ordersTotal.getStatus());
173         values.put("refundStatus",ordersTotal.getRefundStatus());
174         values.put("reTotal",ordersTotal.getReTotal());
175         values.put("id",ordersTotal.getId());
176         sqlSentence.sqlUpdate("isSyncOrder = #{m.isSyncOrder},status = #{m.status},refundStatus = #{m.refundStatus},reTotal = #{m.reTotal}" +
177                 " WHERE id = #{m.id} AND status = #{m.oldStatus} AND refundStatus = #{m.oldRefundStatus}",values);
178         if(commonService.updateWhere(OrdersTotalMapper.class,sqlSentence) != 1){
179             throw new TipsException("操作失败,订单状态已发生改变!");
180         }
7c2538 181
C 182         //初始化初复诊信息
183         if(OrderTotalConstants.STATUS_CANCEL == ordersTotal.getStatus()){
6ed28c 184             // OrderUtil.reCalcOrderBothTheOneData(commonService, VisitRecordMapper.class,null,ordersTotal.getUserId(), BaseEntity.NO);
A 185             // 处理方法调整
186             OrderUtil.reCalcOrderBothTheOneTask(commonService, ordersTotal.getUserId());
7c2538 187         }
C 188
ae6ff7 189         return ordersTotal;
C 190     }
191
192     /**处理总退款方式数据*/
a1c527 193     public static RefundCarryVo refundRecordMotnedHandle(RefundCarryVo refundCarryVo,String operationId,String operationNme
C 194             ,RefundRecord refundRecord,OrdersTotal ordersTotal,CommonService commonService){
ae6ff7 195         SqlSentence sqlSentence = new SqlSentence();
C 196         Map<String,Object> map = new HashMap<>();
197
198         //获取总退款方式
a1c527 199         List<RefundRecordMethod> refundRecordMethodList = refundCarryVo.getRefundRecordMethodList();
2a45d4 200         //退款的支付方式记录数据
a1c527 201         List<RefundRecordConsumePay> refundConsumePayList = refundCarryVo.getRefundConsumePayList();
2a45d4 202         //通过支付编号,装载分组好支付方式记录,key值:支付方式编号,value:支付方式记录集合
a1c527 203         Map<String,List<RefundRecordConsumePay>> refundConsumePayMap= new HashMap<>();
C 204         List<RefundRecordConsumePay> refundRecordConsumePays;
205         for(RefundRecordConsumePay refundRecordConsumePay:refundConsumePayList){
206             refundRecordConsumePays = refundConsumePayMap.computeIfAbsent(refundRecordConsumePay.getNumberNo(),k->new ArrayList<>());
207             refundRecordConsumePays.add(refundRecordConsumePay);
208         }
ae6ff7 209
a1c527 210         List<RefundRecordConsumePay> refundRecordConsumePayList = new ArrayList<>();
C 211         RefundRecordConsumePay refundRecordConsumePay1;
ae6ff7 212
C 213         for(RefundRecordMethod refundRecordMethod:refundRecordMethodList){
8b5222 214             if(refundRecordMethod.getActualTotal().compareTo(BigDecimal.ZERO) < 1){
C 215                 continue;
216             }
2a45d4 217             //判断是否已经被分配完
a1c527 218             if(refundRecordMethod.getpTotal().compareTo(BigDecimal.ZERO) > 0){
C 219                 throw new TipsException("退款错误[20]!");
220             }
221             refundRecordConsumePays = refundConsumePayMap.get(refundRecordMethod.getNumberNo());
222             if(refundRecordConsumePays == null){
223                 throw new TipsException("退款错误[21]!");
224             }
225             for(RefundRecordConsumePay refundRecordConsumePay:refundRecordConsumePays){
226                 //更新支付记录退款信息
227                 map.clear();
228                 map.put("refundTotal",refundRecordConsumePay.getRefundTotal());
229                 map.put("id",refundRecordConsumePay.getConsumePayId());
230                 sqlSentence.sqlUpdate("refundTotal = refundTotal + #{m.refundTotal} WHERE id = #{m.id} AND actualTotal >= refundTotal + #{m.refundTotal}",map);
231                 if(commonService.updateWhere(ConsumePayMapper.class,sqlSentence) != 1){
232                     throw new TipsException("退款金额错误[33]!");
233                 }
234
235                 //生成关联记录
236                 refundRecordConsumePay1 = insertRefundRecordConsumePay(refundRecordConsumePay.getRefundTotal(),null,null,refundRecord.getOrderId(),refundRecordConsumePay.getNumberNo()
2a45d4 237                         ,refundRecordConsumePay.getName(),refundRecordConsumePay.getIsMoneyPay(),refundRecordConsumePay.getIsExecute(),refundRecordConsumePay.getConsumePayId(),refundRecordMethod.getId(),null,refundRecord.getId(),commonService);
a1c527 238                 refundRecordConsumePayList.add(refundRecordConsumePay1);
C 239             }
240             //修改实际退款金额
241             map.put("realRefundTotal",refundRecordMethod.getActualTotal());
242             map.put("id",refundRecordMethod.getId());
243             sqlSentence.sqlUpdate(" realRefundTotal = realRefundTotal + #{m.realRefundTotal} where id = #{m.id}",map);
244             if(commonService.updateWhere(RefundRecordMethodMapper.class,sqlSentence) != 1){
245                 throw new TipsException("更新退款方式信息错误[001]");
246             }
247
248         }
249         refundCarryVo.setRefundConsumePayList(refundRecordConsumePayList);
250
251         //处理回退到账
252         for(RefundRecordMethod refundRecordMethod:refundRecordMethodList){
ae6ff7 253             if(PayMethodTypeConstants.PAY_STORED.equals(refundRecordMethod.getRefundNumberNo())){
C 254                 //储值金额 
255                 //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
256                 if(refundRecordMethod.getActualTotal().compareTo(BigDecimal.ZERO)>0){
257                     UserMoneyUtil.setNewUserMoneyUnclaimed(ordersTotal.getPayUserId()==null?ordersTotal.getUserId():ordersTotal.getPayUserId(),refundRecord.getRemarks(),"审核通过退款:支付方式储值金额退回",operationId,refundRecord.getOrderId(),refundRecord.getOperatorAppCode(),refundRecord.getId(),refundRecordMethod.getActualTotal(), UserMoneyUnclaimed.FUND_TYPE_STORED_VALUE_FUND, OperationReasonConstants.OP_REASON_RECHARGE_REFUND,commonService,UserMoneyUnclaimed.NO);
258                     OrderLog orderLog = RefundToolUtil.setOrderLog(refundRecord, operationId, operationNme, refundRecordMethod.getName()+"退款金额:"+refundRecordMethod.getActualTotal(), 0, OrderLogConstants.LOG_TYPE_REFUND);
259                     commonService.insert(OrderLogMapper.class,orderLog);
260                 }
261             }else if(PayMethodTypeConstants.PAY_ADD_FUND.equals(refundRecordMethod.getRefundNumberNo())){
262                 //增值金
263                 //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
264                 if(refundRecordMethod.getActualTotal().compareTo(BigDecimal.ZERO)!=0){
265                     UserMoneyUtil.setNewUserMoneyUnclaimed(ordersTotal.getPayUserId()==null?ordersTotal.getUserId():ordersTotal.getPayUserId(),refundRecord.getRemarks(),"审核通过退款:支付方式增值金退回",operationId,refundRecord.getOrderId(),refundRecord.getOperatorAppCode(),refundRecord.getId(),refundRecordMethod.getActualTotal(), UserMoneyUnclaimed.FUND_TYPE_VALUE_ADDED_FUND, OperationReasonConstants.OP_REASON_RECHARGE_REFUND,commonService,UserMoneyUnclaimed.YES);
266                     OrderLog orderLog = RefundToolUtil.setOrderLog(refundRecord,operationId,operationNme,refundRecordMethod.getName(),0, OrderLogConstants.LOG_TYPE_REFUND);
267                     commonService.insert(OrderLogMapper.class,orderLog);
268                 }
269             }else if(PayMethodTypeConstants.PAY_INTEGRAL.equals(refundRecordMethod.getRefundNumberNo())){
270                 //积分
271                 //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
272                 if(refundRecordMethod.getActualTotal().compareTo(BigDecimal.ZERO)!=0){
273                     UserMoneyUtil.setNewUserMoneyUnclaimed(ordersTotal.getPayUserId()==null?ordersTotal.getUserId():ordersTotal.getPayUserId(),refundRecord.getRemarks(),"审核通过退款:支付方式积分退回",operationId,refundRecord.getOrderId(),refundRecord.getOperatorAppCode(),refundRecord.getId(),refundRecordMethod.getActualTotal(), UserMoneyUnclaimed.FUND_TYPE_INTEGRAL,OperationReasonConstants.OP_REASON_RECHARGE_REFUND,commonService,UserMoneyUnclaimed.YES);
274                     OrderLog orderLog = RefundToolUtil.setOrderLog(refundRecord,operationId,operationNme,refundRecordMethod.getName()+"退款金额:"+refundRecordMethod.getActualTotal(),0, OrderLogConstants.LOG_TYPE_REFUND);
275                     commonService.insert(OrderLogMapper.class,orderLog);
276                 }
277             }else {
278                 //现金支付
279                 if(refundRecordMethod.getActualTotal().compareTo(BigDecimal.ZERO)<1){
280                     continue;
281                 }
282                 OrderLog orderLog = RefundToolUtil.setOrderLog(refundRecord,operationId,operationNme,refundRecordMethod.getName()+"退款金额:"+refundRecordMethod.getActualTotal(),0, OrderLogConstants.LOG_TYPE_REFUND);
283                 orderLog.setOrderId(ordersTotal.getId());
284                 commonService.insert(OrderLogMapper.class,orderLog);
285             }
a1c527 286         }
C 287         return refundCarryVo;
288     }
289
290     /**充值订单退款方式的支付方式记录处理*/
291     public static RefundCarryVo rechargeRefundMothedHandle(RefundCarryVo refundCarryVo,RefundRecord refundRecord,CommonService commonService){
292
293         SqlSentence sqlSentence = new SqlSentence();
294         Map<String,Object> map = new HashMap<>();
295
296         List<RefundRecordMethod> refundRecordMethodList = refundCarryVo.getRefundRecordMethodList();
297
510678 298         //装载分配好的支付方式记录的金额数据
a1c527 299         List<RefundRecordConsumePay> refundConsumePayList = new ArrayList<>();
C 300         RefundRecordConsumePay refundRecordConsumePay;
301
510678 302         ///////获取订单支付方式记录
C 303         map.put("orderId",refundRecord.getOrderId());
304         sqlSentence.sqlSentence("SELECT *,ROUND(actualTotal-refundTotal,2) AS pTotal FROM consume_pay WHERE isDel = 0 AND orderId = #{m.orderId} ORDER BY pTotal ASC",map);
305         List<ConsumePay> consumePayList = commonService.selectList(ConsumePayMapper.class,sqlSentence);
306         //根据支付编号进行区分,key值:支付编号
307         Map<String,List<ConsumePay>> consumePayMap = new HashMap<>();
308         List<ConsumePay> consumePays;
309         for(ConsumePay consumePay:consumePayList){
310             consumePays = consumePayMap.computeIfAbsent(consumePay.getNumberNo(),k->new ArrayList<>());
311             consumePays.add(consumePay);
312         }
313
314         ////引用对象
315         //退款方式的金额
a1c527 316         BigDecimal mothedTotal;
510678 317         //分配支付方式金额
a1c527 318         BigDecimal mothedCutTotal;
C 319         for(RefundRecordMethod refundRecordMethod:refundRecordMethodList){
510678 320             if(refundRecordMethod.getActualTotal().compareTo(BigDecimal.ZERO) < 1){
C 321                 continue;
322             }
a1c527 323             mothedTotal = refundRecordMethod.getActualTotal();
510678 324             consumePays = consumePayMap.get(refundRecordMethod.getNumberNo());
C 325             if(consumePays == null){
326                 throw new TipsException("没有找到该支付记录:"+refundRecordMethod.getName()+"["+refundRecordMethod.getNumberNo()+"]");
327             }
328             for(ConsumePay consumePay:consumePays){
ae6ff7 329                 if(consumePay.getpTotal().compareTo(BigDecimal.ZERO) < 1){
C 330                     continue;
331                 }
332                 //计算扣减金额
333                 if(consumePay.getpTotal().compareTo(mothedTotal) > 0){
334                     mothedCutTotal = mothedTotal;
335                 }else{
336                     mothedCutTotal = consumePay.getpTotal();
337                 }
a1c527 338                 //减去已经分配的金额
ae6ff7 339                 mothedTotal = mothedTotal.subtract(mothedCutTotal).setScale(2, RoundingMode.HALF_UP);
a1c527 340
C 341                 refundRecordConsumePay = new RefundRecordConsumePay();
342                 refundRecordConsumePay.setNumberNo(consumePay.getNumberNo());
343                 refundRecordConsumePay.setName(consumePay.getName());
344                 refundRecordConsumePay.setRefundTotal(mothedCutTotal);
345                 refundRecordConsumePay.setConsumePayId(consumePay.getId());
8b5222 346                 refundRecordConsumePay.setIsMoneyPay(consumePay.getIsMoneyPay());
C 347                 refundRecordConsumePay.setIsExecute(consumePay.getIsPay());
a1c527 348                 refundConsumePayList.add(refundRecordConsumePay);
C 349
ae6ff7 350                 //已经分配完成,跳出循环
C 351                 if(mothedTotal.compareTo(BigDecimal.ZERO) < 1){
352                     //跳出循环
353                     break;
354                 }
355             }
356             //判断退款金额是否已经全部分配
357             if(mothedTotal.compareTo(BigDecimal.ZERO) > 0){
358                 throw new TipsException("退款金额错误[426]!");
359             }
a1c527 360             refundRecordMethod.setpTotal(BigDecimal.ZERO);
ae6ff7 361         }
a1c527 362         refundCarryVo.setRefundConsumePayList(refundConsumePayList);
C 363         return refundCarryVo;
ae6ff7 364     }
C 365
1869f3 366     /**处理一级子退款方式数据
C 367      * @param deductionTotalUser 用户项目被扣减的划扣金额,可空
368      * @param refundRecord 退款记录总表
369      * @param refundRecordItem 退款记录子表
370      * @param refundCarryVo 总携带参数结构
371      * @param commonService 映射
372      * @return 总携带参数结构
373      */
374     public static RefundCarryVo refundRecordMotnedItemHandle(BigDecimal deductionTotalUser,RefundRecord refundRecord,RefundRecordItem refundRecordItem
375             ,RefundCarryVo refundCarryVo,CommonService commonService){
376
510678 377         //没有退款方式,跳过当前处理,因为这里是处理退款方式金额的,如果没有退款金额,那么可以跳过该环节
1869f3 378         if(refundCarryVo.getRefundRecordMethodList().size() == 0){
C 379             return refundCarryVo;
380         }
381         //支付方式占比
382         BigDecimal payMothedPercentage;
383         //计算退款方式的占比
384         if(refundRecord.getRefundTotal().compareTo(BigDecimal.ZERO) > 0){
385             payMothedPercentage = refundRecordItem.getRefundMoney().divide(refundRecord.getRefundTotal(),15,RoundingMode.HALF_UP);
386         }else{
387             payMothedPercentage = BigDecimal.ZERO;
ae6ff7 388         }
C 389
1869f3 390         //处理退款方式
C 391         refundCarryVo = insertRefundItemMothed(refundRecordItem.getId(),refundRecordItem.getRefundMoney(),payMothedPercentage,OrderSourceConstans.TYPE_PROJECT
392                 ,refundRecordItem.getOrderItemId(),refundCarryVo,refundRecord,commonService);
a1c527 393
2a45d4 394         //更新退款子单
C 395         updateRefundItem(refundCarryVo.getDeductionTotal(),refundCarryVo.getCashTotal(),deductionTotalUser
396                 ,refundRecordItem.getId(),commonService);
397
398         return refundCarryVo;
399     }
400
401     /**更新退款一级子单的信息
402      * @param deductionTotal 退款方式的划扣金额
403      * @param cashTotal 退款方式的现金金额
404      * @param deductionTotalUser 用户项目的划扣金额
405      * @param refundItemId 退款记录一级子单标识
406      * @param commonService 映射
407      */
408     public static void updateRefundItem(BigDecimal deductionTotal,BigDecimal cashTotal,BigDecimal deductionTotalUser
409             ,String refundItemId,CommonService commonService){
a1c527 410         SqlSentence sqlSentence = new SqlSentence();
C 411         Map<String,Object> values = new HashMap<>();
ae6ff7 412
510678 413         //更新退款子单的信息,更新现金和划扣金额保存
2a45d4 414         values.put("deductionTotal",deductionTotal);
1869f3 415         values.put("deductionTotalUser",deductionTotalUser==null?BigDecimal.ZERO:deductionTotalUser);
2a45d4 416         values.put("cashTotal",cashTotal);
C 417         values.put("id",refundItemId);
1869f3 418         sqlSentence.sqlUpdate("deductionTotal = #{m.deductionTotal},deductionTotalUser = #{m.deductionTotalUser},cashTotal = #{m.cashTotal} WHERE id = #{m.id}",values);
C 419         if(commonService.updateWhere(RefundRecordItemMapper.class,sqlSentence) != 1){
420             throw new TipsException("更新退款子项信息失败!");
421         }
422     }
423
424     /**处理二级子退款方式数据
425      * @param deductionTotalUser 用户项目被扣减的划扣金额
426      * @param refundRecord  退款记录总表
427      * @param refundRecordItemSource 退款记录子表
428      * @param refundCarryVo 总携带参数结构
429      * @param commonService 映射
430      * @return 总携带参数结构
431      */
432     public static RefundCarryVo refundRecordMotnedItemTwoHandle(BigDecimal deductionTotalUser,RefundRecord refundRecord,RefundRecordItemSource refundRecordItemSource
433             ,RefundCarryVo refundCarryVo,CommonService commonService){
434
435         //装载支付方式退款信息
436         refundCarryVo.setRefundConsumePayList(new ArrayList<>());
437         //没有退款方式,跳过当前处理
438         if(refundCarryVo.getRefundRecordMethodList().size() == 0){
439             return refundCarryVo;
440         }
441
442         SqlSentence sqlSentence = new SqlSentence();
443         Map<String,Object> values = new HashMap<>();
444
445         //支付方式占比
446         BigDecimal payMothedPercentage;
447         //计算退款方式的占比
448         if(refundRecord.getRefundTotal().compareTo(BigDecimal.ZERO) > 0){
449             payMothedPercentage = refundRecordItemSource.getRefundMoney().divide(refundRecord.getRefundTotal(),15,RoundingMode.HALF_UP);
450         }else{
451             payMothedPercentage = BigDecimal.ZERO;
452         }
453
454         //处理退款方式
455         refundCarryVo = insertRefundItemMothed(refundRecordItemSource.getId(),refundRecordItemSource.getRefundMoney(),payMothedPercentage,OrderSourceConstans.TYPE_RETAIL
456                 ,refundRecordItemSource.getOrderItemSonId(),refundCarryVo,refundRecord,commonService);
457
458         values.put("deductionTotal",refundCarryVo.getDeductionTotal());
459         values.put("deductionTotalUser",deductionTotalUser==null?BigDecimal.ZERO:deductionTotalUser);
460         values.put("cashTotal",refundCarryVo.getCashTotal());
461         values.put("id",refundRecordItemSource.getId());
462         sqlSentence.sqlUpdate("deductionTotal = #{m.deductionTotal},deductionTotalUser = #{m.deductionTotalUser},cashTotal = #{m.cashTotal} WHERE id = #{m.id}",values);
463         if(commonService.updateWhere(RefundRecordItemSourceMapper.class,sqlSentence) != 1){
464             throw new TipsException("更新退款子项信息失败[94]!");
465         }
466
467         return refundCarryVo;
468     }
469
470     /**退款子单退款方式处理保存
471      * @param refundItemId 退款子单标识
472      * @param refundItemTotal 退款子单实际需要退款总金额
473      * @param payMothedPercentage 支付方式占比
474      * @param orderItemType 订单子单级别
475      * @param orderItemId 订单子单标识
476      * @param refundCarryVo 总结构对象
477      * @param refundRecord 退款总记录
478      * @param commonService 映射
479      * @return 总结构对象
480      */
481     public static RefundCarryVo insertRefundItemMothed(String refundItemId,BigDecimal refundItemTotal,BigDecimal payMothedPercentage,String orderItemType
482             ,String orderItemId,RefundCarryVo refundCarryVo,RefundRecord refundRecord,CommonService commonService){
483
484         //总退款方式金额数据
485         List<RefundRecordMethod> refundRecordMethodList = refundCarryVo.getRefundRecordMethodList();
a57453 486         //进行升序排序,避免后面不够分配
C 487         refundRecordMethodList = refundRecordMethodList.stream().sorted(Comparator.comparing(RefundRecordMethod::getpTotal)).collect(Collectors.toList());
1869f3 488
510678 489         //获取子单的支付方式记录,计算可退款金额
1869f3 490         List<ConsumePayItem> consumePayItemList;
C 491         if(OrderSourceConstans.TYPE_PROJECT.equals(orderItemType)){
510678 492             //一级订单
1869f3 493             consumePayItemList = getOrderItemOneConsumePay(orderItemId,commonService);
C 494         }else{
510678 495             //二级订单
1869f3 496             consumePayItemList = getOrderItemTwoConsumePay(orderItemId,commonService);
C 497         }
498
510678 499         ////存储支付方式编号的可退款金额,根据支付编号求和,后面的业务判断会用到,key值:支付编号,value:可退金额
1869f3 500         Map<String,BigDecimal> noMap = new HashMap<>();
C 501         BigDecimal surplusTotal;
510678 502         ////存储支付方式编号的支付方式记录,根据支付编号整合,后面的业务会用到,key值:支付编号,value:支付记录集合
1869f3 503         Map<String,List<ConsumePayItem>> noPayItemMap = new HashMap<>();
C 504         List<ConsumePayItem> noPayItemList;
505
506         ////////填充支付方式记录的退款金额,计算剩余可退金额,支付方式记录的退款金额需要去查询计算获取
510678 507         //获取订单子单已经退款的退款方式金额,根据支付方式记录的标识求和返回
a036dc 508         List<RefundRecordConsumePay> refundRecordConsumePayList = RefundTool.getRefundRecordConsumePay(orderItemId,null,false,true,commonService);
1869f3 509         //转化成map,可以根据支付方式记录的标识直接获取到数据
ae6ff7 510         Map<String, RefundRecordConsumePay> refundRecordConsumePayMap = refundRecordConsumePayList.stream().collect(
C 511                 Collectors.toMap(RefundRecordConsumePay::getConsumePayId,(a) -> a));
512         RefundRecordConsumePay refundRecordConsumePay;
513         for(ConsumePayItem consumePayItem:consumePayItemList){
514             refundRecordConsumePay = refundRecordConsumePayMap.get(consumePayItem.getConsumePayId());
515             if(refundRecordConsumePay != null){
516                 //已退款金额
517                 consumePayItem.setRefundTotal(refundRecordConsumePay.getRefundTotal());
518                 //可退款金额
519                 consumePayItem.setpTotal(consumePayItem.getpTotal().subtract(refundRecordConsumePay.getRefundTotal()).setScale(2,RoundingMode.HALF_UP));
520             }
1869f3 521             //计算每个支付编码可退款金额
C 522             surplusTotal = noMap.computeIfAbsent(consumePayItem.getNumberNo(),k->BigDecimal.ZERO);
523             surplusTotal = surplusTotal.add(consumePayItem.getpTotal()).setScale(2,RoundingMode.HALF_UP);
524             noMap.put(consumePayItem.getNumberNo(),surplusTotal);
ae6ff7 525
1869f3 526             //支付编码集合整合
C 527             noPayItemList = noPayItemMap.computeIfAbsent(consumePayItem.getNumberNo(),k->new ArrayList<>());
528             noPayItemList.add(consumePayItem);
529         }
ae6ff7 530
1869f3 531         List<RefundRecordConsumePay> refundConsumePayList = new ArrayList<>();
C 532
533         ////引用对象
ae6ff7 534         RefundRecordItemMethod refundRecordItemMethod;
1869f3 535         RefundRecordMethod refundRecordMethod;
C 536         //需要退的退款编号金额
537         BigDecimal mothedTotal;
538         //支付编号分配的退款金额
539         BigDecimal mothedCutTotal;
540         //分配的划扣金额总和
541         BigDecimal deductionTotal = BigDecimal.ZERO;
542         //分配的现金金额总和
543         BigDecimal cashTotal = BigDecimal.ZERO;
ae6ff7 544
d96661 545         //装载已经分配的退款金额记录,key值:总退款方式记录标识
C 546         Map<String,RefundRecordItemMethod> refundRecordItemMethodMap = new HashMap<>();
1869f3 547         ////退款方式金额分配
d96661 548         for(int i = 0;i <refundRecordMethodList.size();i++) {
1869f3 549             refundRecordMethod = refundRecordMethodList.get(i);
C 550
551             ////子项退款方式填充
552             refundRecordItemMethod = new RefundRecordItemMethod();
553             refundRecordItemMethod.setNumberNo(refundRecordMethod.getNumberNo());
554             refundRecordItemMethod.setName(refundRecordMethod.getName());
555             //支付方式
556             refundRecordItemMethod.setPaymentMethodId(refundRecordMethod.getPaymentMethodId());
557             refundRecordItemMethod.setIsMoneyPay(refundRecordMethod.getIsMoneyPay());
558             refundRecordItemMethod.setIsExecute(refundRecordMethod.getIsExecute());
559             refundRecordItemMethod.setIsPay(refundRecordMethod.getIsPay());
560             //退款方式
561             refundRecordItemMethod.setRefundNumberNo(refundRecordMethod.getRefundNumberNo());
562             refundRecordItemMethod.setRefundName(refundRecordMethod.getRefundName());
563             refundRecordItemMethod.setRefundMethodId(refundRecordMethod.getRefundMethodId());
9cff8d 564             refundRecordItemMethod.setIsMoneyPayRefund(refundRecordMethod.getIsMoneyPayRefund());
C 565             refundRecordItemMethod.setIsExecuteRefund(refundRecordMethod.getIsExecuteRefund());
1869f3 566
C 567             //计算退款方式的金额
d96661 568             if (i == refundRecordMethodList.size() - 1) {
1869f3 569                 ////最后一个
C 570                 refundRecordItemMethod.setActualTotal(refundItemTotal);
d96661 571             } else {
1869f3 572                 ////不是最后一个
d96661 573                 refundRecordItemMethod.setActualTotal(refundRecordMethod.getActualTotal().multiply(payMothedPercentage).setScale(2, RoundingMode.UP));
ae6ff7 574             }
1869f3 575             //判断与剩余的未分配退款方式金额
d96661 576             if (refundRecordItemMethod.getActualTotal().compareTo(refundRecordMethod.getpTotal()) > 0) {
1869f3 577                 refundRecordItemMethod.setActualTotal(refundRecordMethod.getpTotal());
C 578             }
579             //判断与剩下的未分配金额校验
d96661 580             if (refundRecordItemMethod.getActualTotal().compareTo(refundItemTotal) > 0) {
1869f3 581                 refundRecordItemMethod.setActualTotal(refundItemTotal);
C 582             }
583             //可支付方式可退款金额
d96661 584             surplusTotal = noMap.computeIfAbsent(refundRecordItemMethod.getNumberNo(), k -> BigDecimal.ZERO);
C 585             if (refundRecordItemMethod.getActualTotal().compareTo(surplusTotal) > 0) {
1869f3 586                 refundRecordItemMethod.setActualTotal(surplusTotal);
C 587             }
ae6ff7 588
2a45d4 589             refundRecordItemMethod.setRealRefundTotal(refundRecordItemMethod.getActualTotal());
1869f3 590             refundRecordItemMethod.setCommonType(orderItemType);
C 591             refundRecordItemMethod.setCommonId(orderItemId);
592             refundRecordItemMethod.setOrderId(refundRecordMethod.getOrderId());
593             refundRecordItemMethod.setRefundRecordItemId(refundItemId);
594             refundRecordItemMethod.setRefundRecordId(refundRecord.getId());
9cff8d 595             refundRecordItemMethod.setRefundRecordMethodId(refundRecordMethod.getId());
d96661 596
a57453 597             refundRecordItemMethodMap.put(refundRecordMethod.getId(),refundRecordItemMethod);
ae6ff7 598
1869f3 599             //减去已经分配的退款方式金额
C 600             refundRecordMethod.setpTotal(refundRecordMethod.getpTotal().subtract(refundRecordItemMethod.getActualTotal()).setScale(2,RoundingMode.HALF_UP));
601             //减去已经分配的退款金额
602             refundItemTotal = refundItemTotal.subtract(refundRecordItemMethod.getActualTotal()).setScale(2,RoundingMode.HALF_UP);
603             //减去已经分配的可退款金额
604             surplusTotal = surplusTotal.subtract(refundRecordItemMethod.getActualTotal()).setScale(2,RoundingMode.HALF_UP);
605             noMap.put(refundRecordItemMethod.getNumberNo(),surplusTotal);
d96661 606
C 607         }
608
609         //没有分配完,再分配
610         if(refundItemTotal.compareTo(BigDecimal.ZERO) > 0){
aeb85f 611             logger.info("没有分配完refundRecordMethodList{}:,未分配金额:{}",JSON.toJSONString(refundRecordMethodList),refundItemTotal);
C 612             BigDecimal frontMoney;
613             while (refundItemTotal.compareTo(BigDecimal.ZERO) > 0){
614                 //循环前的金额赋值
615                 frontMoney = refundItemTotal;
616                 refundItemTotal = redistributionRefundMoney(refundItemTotal,refundRecordMethodList,refundRecordItemMethodMap,noMap);
617                 //避免死循环,如果金额不再分配,那么就跳出循环
618                 if(frontMoney.compareTo(refundItemTotal) == 0){
d96661 619                     break;
C 620                 }
621             }
622         }
623         //判断是否已经分配完
624         if(refundItemTotal.compareTo(BigDecimal.ZERO) > 0){
a57453 625             logger.error("refundRecordMethodList{}:",JSON.toJSONString(refundRecordMethodList));
d96661 626             logger.error("分配退款金额错误:{},剩余未分配金额:{},支付方式:{}",refundItemId,refundItemTotal,JSON.toJSONString(consumePayItemList));
C 627             throw new TipsException("分配退款金额错误["+orderItemType+"]");
628         }
629
ea4351 630         List<RefundRecordItemMethod> refundRecordItemMethodList = new ArrayList<>();
a57453 631         //保存数据
C 632         for(Map.Entry<String, RefundRecordItemMethod> entry : refundRecordItemMethodMap.entrySet()) {
ea4351 633             refundRecordItemMethod = entry.getValue();
C 634             commonService.insert(RefundRecordItemMethodMapper.class,refundRecordItemMethod);
635             refundRecordItemMethodList.add(refundRecordItemMethod);
a57453 636         }
C 637
d96661 638         ////退款方式金额分配
C 639         for(int i = 0;i <refundRecordMethodList.size();i++){
640             refundRecordMethod = refundRecordMethodList.get(i);
641
642             ////子项退款方式填充
643             //获取分配的退款方式记录
644             refundRecordItemMethod = refundRecordItemMethodMap.get(refundRecordMethod.getId());
ae6ff7 645
1869f3 646             ///////生成关联支付方式记录和退款方式关联
510678 647             //根据支付编号获取支付方式记录
1869f3 648             noPayItemList = noPayItemMap.computeIfAbsent(refundRecordItemMethod.getNumberNo(),k->new ArrayList<>());
510678 649             //进行升序排序,避免后面不够分配
C 650             noPayItemList = noPayItemList.stream().sorted(Comparator.comparing(ConsumePayItem::getpTotal)).collect(Collectors.toList());
ae6ff7 651             mothedTotal = refundRecordItemMethod.getActualTotal();
1869f3 652             for(ConsumePayItem consumePayItem:noPayItemList){
ae6ff7 653                 if(consumePayItem.getpTotal().compareTo(BigDecimal.ZERO) < 1){
C 654                     continue;
655                 }
656                 //计算扣减金额
657                 if(consumePayItem.getpTotal().compareTo(mothedTotal) > 0){
658                     mothedCutTotal = mothedTotal;
659                 }else{
660                     mothedCutTotal = consumePayItem.getpTotal();
661                 }
662
084cb8 663                 //现金金额
ae6ff7 664                 if(consumePayItem.getIsMoneyPay().equals(ConsumePayItem.YES)){
2a45d4 665                     cashTotal = cashTotal.add(mothedCutTotal).setScale(2,RoundingMode.HALF_UP);
ae6ff7 666                 }
084cb8 667                 //划扣金额
ae6ff7 668                 if(consumePayItem.getIsExecute().equals(ConsumePayItem.YES)){
2a45d4 669                     deductionTotal = deductionTotal.add(mothedCutTotal).setScale(2,RoundingMode.HALF_UP);
ae6ff7 670                 }
C 671
672                 //生成关联记录
673                 refundRecordConsumePay = insertRefundRecordConsumePay(mothedCutTotal,refundRecordItemMethod.getCommonType(),refundRecordItemMethod.getCommonId(),refundRecord.getOrderId(),consumePayItem.getNumberNo()
2a45d4 674                         ,consumePayItem.getName(),consumePayItem.getIsMoneyPay(),consumePayItem.getIsExecute(),consumePayItem.getConsumePayId(),refundRecordItemMethod.getId(),refundItemId,refundRecord.getId(),commonService);
1869f3 675                 refundConsumePayList.add(refundRecordConsumePay);
ae6ff7 676
1869f3 677                 //支付方式记录减掉已经分配退款方式金额
C 678                 consumePayItem.setpTotal(consumePayItem.getpTotal().subtract(mothedCutTotal).setScale(2,RoundingMode.HALF_UP));
679                 //减掉已经分配退款方式金额
ae6ff7 680                 mothedTotal = mothedTotal.subtract(mothedCutTotal).setScale(2, RoundingMode.HALF_UP);
1869f3 681                 //分配完成,跳出循环
ae6ff7 682                 if(mothedTotal.compareTo(BigDecimal.ZERO) < 1){
C 683                     //跳出循环
684                     break;
685                 }
686             }
d96661 687             if(mothedTotal.compareTo(BigDecimal.ZERO) != 0){
C 688                 logger.error("分配退款金额错误[14]:{},剩余未分配金额:{},支付方式:{}",refundItemId,refundItemTotal,JSON.toJSONString(consumePayItemList));
689                 throw new TipsException("分配退款金额错误[14]:"+orderItemType);
690             }
ae6ff7 691         }
1869f3 692
C 693         refundCarryVo.setDeductionTotal(deductionTotal);
694         refundCarryVo.setCashTotal(cashTotal);
695         refundCarryVo.setRefundConsumePayList(refundConsumePayList);
ea4351 696         refundCarryVo.setRefundRecordItemMethodList(refundRecordItemMethodList);
1869f3 697
C 698         return refundCarryVo;
ae6ff7 699     }
C 700
aeb85f 701     /**重新分配未分配完的金额*/
C 702     public static BigDecimal redistributionRefundMoney(BigDecimal refundItemTotal, List<RefundRecordMethod> refundRecordMethodList, Map<String, RefundRecordItemMethod> refundRecordItemMethodMap
703             , Map<String, BigDecimal> noMap){
704         //每次1分钱
705         BigDecimal money = new BigDecimal("0.01");
706         RefundRecordMethod refundRecordMethod;
707         RefundRecordItemMethod refundRecordItemMethod;
708         BigDecimal surplusTotal;
709         for(int i = 0;i <refundRecordMethodList.size();i++){
710             refundRecordMethod = refundRecordMethodList.get(i);
711             if(refundRecordMethod.getpTotal().compareTo(BigDecimal.ZERO) <= 0){
712                 continue;
713             }
714             //获取分配的退款方式记录
715             refundRecordItemMethod = refundRecordItemMethodMap.get(refundRecordMethod.getId());
716
717             //可支付方式可退款金额
718             surplusTotal = noMap.computeIfAbsent(refundRecordItemMethod.getNumberNo(),k-> BigDecimal.ZERO);
719             if(surplusTotal.compareTo(BigDecimal.ZERO) <= 0){
720                 continue;
721             }
722
723             //判断与剩余的未分配退款方式金额
724             if (money.compareTo(refundRecordMethod.getpTotal()) > 0){
725                 money = refundRecordMethod.getpTotal();
726             }
727             //判断与剩下的未分配金额校验
728             if(money.compareTo(refundItemTotal) > 0){
729                 money = refundItemTotal;
730             }
731             if(money.compareTo(surplusTotal) > 0){
732                 money = surplusTotal;
733             }
734
735             //减去已经分配的退款方式金额
736             refundRecordMethod.setpTotal(refundRecordMethod.getpTotal().subtract(money));
737             //减去已经分配的退款金额
738             refundItemTotal = refundItemTotal.subtract(money);
739             //减去已经分配的可退款金额
740             surplusTotal = surplusTotal.subtract(money);
741             noMap.put(refundRecordItemMethod.getNumberNo(),surplusTotal);
742             //叠加到分配的退款方式记录
743             refundRecordItemMethod.setActualTotal(refundRecordItemMethod.getActualTotal().add(money));
744             if(refundItemTotal.compareTo(BigDecimal.ZERO) < 1){
745                 break;
746             }
747         }
748         return refundItemTotal;
749     }
750
751
ae6ff7 752
C 753     /**
754      * 退款-处理优惠券
755      * @param refundRecord 退款总数据
756      * @param commonService 映射
757      */
758     public static void handCoupon(RefundRecord refundRecord,CommonService commonService) {
759         SqlSentence sqlSentence = new SqlSentence();
760         Map<String, Object> map = new HashMap<>();
761
762         //回去回退优惠券
763         map.put("refundRecordId",refundRecord.getId());
a1c527 764         sqlSentence.sqlSentence("select * from refund_record_coupon where refundRecordId=#{m.refundRecordId} and isDel=0 ",map);
ae6ff7 765         List<RefundRecordCoupon> refundRecordCouponList=commonService.selectList(RefundRecordCouponMapper.class,sqlSentence);
C 766
767         //退款成功
a1c527 768         CouponOrderDiscountLog couponOrderDiscountLog;
ae6ff7 769         for (RefundRecordCoupon refundRecordCoupon : refundRecordCouponList) {
a1c527 770
C 771             couponOrderDiscountLog=commonService.selectOneByKey(CouponOrderDiscountLogMapper.class,refundRecordCoupon.getCouponOrderId());
772             if(couponOrderDiscountLog==null){
773                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"订单优惠卷标识不正确");
774             }
ae6ff7 775
C 776             //变更订单优惠券记录状态
777             map.clear();
778             map.put("status", BaseEntity.YES);
61a0db 779             map.put("oldStatus", BaseEntity.NO);
a1c527 780             map.put("id", couponOrderDiscountLog.getId());
1f66d3 781             sqlSentence.sqlSentence("status = #{m.status}, editTime = now() WHERE id = #{m.id} AND status = #{m.oldStatus}",map);
ae6ff7 782             if(commonService.updateWhere(CouponOrderDiscountLogMapper.class,sqlSentence) != 1){
C 783                 throw new TipsException("优惠券回退失败!");
784             }
785
786             //领建优惠券跳过回退
787             if(HIS_COUPON_CODE.equals(couponOrderDiscountLog.getCouponNumberId())){
788                 continue;
789             }
790
791             //优惠券状态变化
792             map.put("isUse", BaseEntity.NO);
160c33 793             map.put("isUseOld", BaseEntity.YES);
ae6ff7 794             map.put("useTime", null);
C 795             map.put("useType", CouponNumber.USE_TYPE_UNKNOW);
796             map.put("id", couponOrderDiscountLog.getCouponNumberId());
160c33 797             sqlSentence.sqlSentence("  isUse=#{m.isUse},useTime=#{m.useTime},useType=#{m.useType},isUse=#{m.isUse} WHERE id = #{m.id} AND isUse = #{m.isUseOld}",map);
ae6ff7 798             if(commonService.updateWhere(CouponNumberMapper.class,sqlSentence) != 1){
C 799                 throw new TipsException("优惠券回退失败[67]!");
800             }
801         }
802     }
803
804     /**
805      * 退款-处理活动规则增值金和积分
806      */
807     private static void handActivityRule(CommonService commonService, String operationId, String operationNme, SqlSentence sqlSentence,
808                                          Map<String, Object> map, RefundRecord refundRecord, OrdersTotal ordersTotal, OrderInfo orderInfo) {
809         if(orderInfo!=null && StringUtils.noNull(orderInfo.getActivityId())){
810             ActivityRule activityRule=commonService.selectOneByKeyBlob(ActivityRuleMapper.class,orderInfo.getActivityId());
811             if(activityRule!=null){
812                 map.put("activityRuleId",activityRule.getId());
813                 map.put("type", ActivityAction.TYPE_INTEGRAL);
814                 map.put("type1",ActivityAction.TYPE_VALUEADDEDFUND);
815                 map.put("type2",ActivityAction.TYPE_COUPON);
e9e32c 816                 sqlSentence.sqlSentence("select * from activity_action where activityRuleId=#{m.activityRuleId} and (type=#{m.type} or type=#{m.type1} or type=#{m.type2}) and isDel=0",map);
ae6ff7 817                 List<ActivityAction> activityActions = commonService.selectList(ActivityActionMapper.class, sqlSentence);
C 818                 if(activityActions!=null && activityActions.size()>0){
819                     for (ActivityAction activityAction : activityActions) {
820                         if(ActivityAction.TYPE_INTEGRAL.equals(activityAction.getType())){
821                             //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
822                             if(new BigDecimal(activityAction.getWorth()).negate().compareTo(BigDecimal.ZERO)!=0){
823                                 UserMoneyUtil.setNewUserMoneyUnclaimed(refundRecord.getUserId(),refundRecord.getRemarks(),"退款扣减活动规则赠送积分",operationId,refundRecord.getOrderId(),ordersTotal.getAppIdCode(),refundRecord.getId(),new BigDecimal(activityAction.getWorth()).negate(), UserMoneyUnclaimed.FUND_TYPE_INTEGRAL,OperationReasonConstants.OP_REASON_RECHARGE_REFUND,commonService,UserMoneyUnclaimed.YES);
824                             }
825                         }else if(ActivityAction.TYPE_VALUEADDEDFUND.equals(activityAction.getType())){
826                             //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
827                             if(new BigDecimal(activityAction.getWorth()).negate().compareTo(BigDecimal.ZERO)!=0){
828                                 UserMoneyUtil.setNewUserMoneyUnclaimed(refundRecord.getUserId(),refundRecord.getRemarks(),"退款扣减活动规则赠送增值金",operationId,refundRecord.getOrderId(),ordersTotal.getAppIdCode(),refundRecord.getId(),new BigDecimal(activityAction.getWorth()).negate(), UserMoneyUnclaimed.FUND_TYPE_VALUE_ADDED_FUND,OperationReasonConstants.OP_REASON_RECHARGE_REFUND,commonService,UserMoneyUnclaimed.YES);
829                             }
830                         }else if(ActivityAction.TYPE_COUPON.equals(activityAction.getType())){
831                             map.put("oldValidState",BaseEntity.YES);
832                             map.put("newValidState",BaseEntity.NO);
833                             map.put("couponId",activityAction.getCrmCouponId());
834                             map.put("commonId",ordersTotal.getId());
e9e32c 835                             sqlSentence.sqlSentence(" validState=#{m.newValidState} where couponId=#{m.couponId} and commonId=#{m.commonId} and validState=#{m.oldValidState} ",map);
ae6ff7 836                             commonService.updateWhere(CouponNumberMapper.class,sqlSentence);
C 837                         }
838                     }
839                 }
840             }
841         }
842
843     }
a1c527 844
C 845     /**退款-处理普通订单信息(比如:项目、促销、卡项)
846      * @param refundCarryVo 全局携带参数结构
847      * @param operationId 操作人标识
848      * @param refundRecord 退款总标识
849      * @param ordersTotal 订单
850      * @param commonService 映射
851      * @return 全局携带参数结构
ae6ff7 852      */
a1c527 853     public static RefundCarryVo numberOfRefunds(RefundCarryVo refundCarryVo,String operationId, RefundRecord refundRecord,OrdersTotal ordersTotal,CommonService commonService) {
ae6ff7 854
C 855         SqlSentence sqlSentence = new SqlSentence();
856         Map<String, Object> map = new HashMap<>();
857
858         //获取退款子单
859         map.put("refundRecordId",refundRecord.getId());
a1c527 860         sqlSentence.sqlSentence("SELECT * FROM refund_record_item WHERE isDel = 0 AND refundRecordId = #{m.refundRecordId}",map);
ae6ff7 861         List<RefundRecordItem> refundRecordItems =commonService.selectList(RefundRecordItemMapper.class,sqlSentence);
a1c527 862         if(refundRecordItems == null || refundRecordItems.size() == 0){
ae6ff7 863             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到退款子订单信息");
C 864         }
865
1869f3 866         //根据支付记录总表的标识来整合已退的金额,key值:支付记录总表标识,value:金额数据
C 867         Map<String,RefundRecordConsumePay> refundRecordConsumePayMap = new HashMap<>();
868         RefundRecordConsumePay refundRecordConsumePay;
ae6ff7 869
C 870         for (RefundRecordItem refundRecordItem: refundRecordItems) {
1869f3 871             //初始化总结构携带参数
C 872             refundCarryVo.setRefundConsumePayList(new ArrayList<>());
873             refundCarryVo.setDeductionTotal(BigDecimal.ZERO);
874             refundCarryVo.setCashTotal(BigDecimal.ZERO);
2a45d4 875             refundCarryVo.setDeductionTotalUser(BigDecimal.ZERO);
510678 876             //商品类型判断
ae6ff7 877             switch (refundRecordItem.getType()){
C 878                 case OrderItemConstants.TYPE_RETAIL:
1869f3 879                     refundCarryVo = handRefundRerail(refundRecord,refundRecordItem,refundCarryVo,commonService);
ae6ff7 880                     break;
C 881                 case OrderItemConstants.TYPE_DRUG:
1869f3 882                     refundCarryVo = handRefundRerail(refundRecord,refundRecordItem,refundCarryVo,commonService);
ae6ff7 883                     break;
C 884                 case OrderItemConstants.TYPE_PROJECT:
1869f3 885                     refundCarryVo = handRefundNoExecution(refundRecord,refundRecordItem,refundCarryVo,commonService);
ae6ff7 886                     break;
C 887                 case OrderItemConstants.TYPE_PROMOTION:
1869f3 888                     refundCarryVo = handRefundPromotion(operationId, refundRecord, ordersTotal,refundRecordItem,refundCarryVo,commonService);
ae6ff7 889                     break;
C 890                 case OrderItemConstants.TYPE_CARD:
1869f3 891                     refundCarryVo = handRefundCard(refundRecord,refundRecordItem,refundCarryVo,commonService);
ae6ff7 892                     break;
C 893                 case OrderItemConstants.CARD_BAG:
1869f3 894                     refundCarryVo = handRefundPromotion(operationId, refundRecord, ordersTotal,refundRecordItem,refundCarryVo,commonService);
ae6ff7 895                     break;
89b4d7 896                 case OrderItemConstants.TYPE_COUPON:
F 897                     refundCarryVo = handRefundRerail(refundRecord,refundRecordItem,refundCarryVo,commonService);
898                     break;
ae6ff7 899                 default:break;
C 900             }
1869f3 901
C 902             //遍历叠加支付方式记录的退款金额
903             for(RefundRecordConsumePay re:refundCarryVo.getRefundConsumePayList()){
2a45d4 904                 refundRecordConsumePay = refundRecordConsumePayMap.computeIfAbsent(re.getConsumePayId(),k->new RefundRecordConsumePay(BigDecimal.ZERO,re.getNumberNo(),re.getName(),re.getIsMoneyPay(),re.getIsExecute(),re.getConsumePayId()));
1869f3 905                 refundRecordConsumePay.setRefundTotal(refundRecordConsumePay.getRefundTotal().add(re.getRefundTotal()));
C 906             }
ae6ff7 907         }
1869f3 908
C 909         //转载返回支付方式记录的退款金额
910         List<RefundRecordConsumePay> refundRecordConsumePayList = new ArrayList<>();
911         for (Map.Entry<String, RefundRecordConsumePay> entry : refundRecordConsumePayMap.entrySet()) {
912             refundRecordConsumePayList.add(entry.getValue());
a1c527 913         }
C 914
915         //校验金额是不是已经分配完
916         for(RefundRecordMethod refundRecordMethod:refundCarryVo.getRefundRecordMethodList()){
917             if(refundRecordMethod.getpTotal().compareTo(BigDecimal.ZERO) > 0){
918                 throw new TipsException("退款金额分配错误!");
919             }
1869f3 920         }
C 921
922         refundCarryVo.setRefundConsumePayList(refundRecordConsumePayList);
923         return refundCarryVo;
ae6ff7 924     }
C 925
926     /**
927      * 退款一级是商品
928      * @param refundRecord 退款总信息
929      * @param refundRecordItem 退款子单
930      * @param commonService 映射
931      */
1869f3 932     private static RefundCarryVo handRefundRerail(RefundRecord refundRecord, RefundRecordItem refundRecordItem
C 933             , RefundCarryVo refundCarryVo, CommonService commonService) {
ae6ff7 934
C 935         //判断操作完了去修改子订单状态
936         OrderItem orderItem=commonService.selectOneByKey(OrderItemMapper.class,refundRecordItem.getOrderItemId());
937         if (orderItem==null){
938             throw new PlatTipsException(PlatformCode.ERROR_PARAMETER_NULL,"未找到子订单信息");
939         }
940         //剩余可退款数量
941         Integer surplusNum = orderItem.getBuyNum()-orderItem.getHasReNum();
942         if(refundRecordItem.getRefundNum() > surplusNum){
943             throw new TipsException("退款数量不能大于可退款数量!");
944         }
945
946         //变更退款子项信息
a1c527 947         int refundStatus;
ae6ff7 948         if (surplusNum.equals(refundRecordItem.getRefundNum())){
1869f3 949             refundStatus = OrderTotalConstants.STATUS_REFUND_FINSH;
ae6ff7 950         }else{
1869f3 951             refundStatus = OrderTotalConstants.STATUS_REFUND_PART;
ae6ff7 952         }
C 953
1869f3 954         //更新子订单信息
C 955         updateOrderItemOne(orderItem,refundStatus,refundRecordItem.getRefundMoney(),refundRecordItem.getRefundNum(),commonService);
956
ae6ff7 957         //退款方式处理
1869f3 958         return refundRecordMotnedItemHandle(null,refundRecord,refundRecordItem,refundCarryVo,commonService);
ae6ff7 959     }
C 960
961     /**
962      * 退款-处理未执行划扣   项目类型
a1c527 963      * @param refundRecord 退款总记录
C 964      * @param refundRecordItem 退款一级子记录
ae6ff7 965      */
1869f3 966     private static RefundCarryVo handRefundNoExecution(RefundRecord refundRecord, RefundRecordItem refundRecordItem
C 967             ,RefundCarryVo refundCarryVo,CommonService commonService) {
ae6ff7 968
C 969         //找到子单
970         OrderItem orderItem=commonService.selectOneByKey(OrderItemMapper.class,refundRecordItem.getOrderItemId());
971         if (orderItem==null){
972             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到子订单信息");
973         }
a1c527 974
C 975         SqlSentence sqlSentence = new SqlSentence();
976         Map<String, Object> map = new HashMap<>();
977
ae6ff7 978         //找到用户项目
C 979         map.put("commonId",refundRecordItem.getOrderItemId());
980         sqlSentence.sqlSentence("select * from user_project_item where isDel = 0 and commonId = #{m.commonId} and isTransfer = 0",map);
981         UserProjectItem userProjectItem =commonService.selectOne(UserProjectItemMapper.class,sqlSentence);
982         if (userProjectItem == null) {
983             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到用户子项项目信息");
984         }
985
986         if(userProjectItem.getNotUsedNum() < refundRecordItem.getRefundNum()){
987             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款次数大于可退次数!");
988         }
989
990         //用户项目操作
1869f3 991         UserProjectDeductionVo  userProjectDeductionVo = UserProjectTool.userProjectDeduction(userProjectItem,UserProjectUsedCon.USED_METHOD_ORDER_REFUND,UserProjectUsedCon.USED_TYPE_DEDUCTION,null
ae6ff7 992                 ,refundRecordItem.getId(),refundRecordItem.getRefundNum(),refundRecord.getOperatorAppId(),refundRecord.getOperatorAppName(),refundRecord.getRefundShopId(),refundRecord.getRefundShopName(),"员工备注:"+refundRecord.getRemarks()+"|用户备注:"+refundRecord.getRefundReason(),commonService);
2a45d4 993
C 994         refundCarryVo.setDeductionTotalUser(userProjectDeductionVo.getDeductionTotal());
ae6ff7 995
C 996         //计算子单是否还有剩余的可扣疗程数
997         int surplusNum = orderItem.getUsedTotal()-orderItem.getHasReNum();
998         if(refundRecordItem.getRefundNum() > surplusNum){
999             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款次数大于子单可退次数[54]!");
1000         }
1001
a1c527 1002         int refundStatus;
ae6ff7 1003         if(refundRecordItem.getRefundNum() == surplusNum){
C 1004             refundStatus=OrderTotalConstants.STATUS_REFUND_FINSH;
1005         }else{
1006             refundStatus=OrderTotalConstants.STATUS_REFUND_PART;
1007         }
1008
1869f3 1009         //更新子订单信息
C 1010         updateOrderItemOne(orderItem,refundStatus,refundRecordItem.getRefundMoney(),refundRecordItem.getRefundNum(),commonService);
ae6ff7 1011
C 1012         //退款方式处理
1869f3 1013         return refundRecordMotnedItemHandle(userProjectDeductionVo.getDeductionTotal(),refundRecord,refundRecordItem,refundCarryVo,commonService);
ae6ff7 1014     }
C 1015
a1c527 1016     /**退款-处理卡项
C 1017      * @param refundRecord 退款总记录
1018      * @param refundRecordItem 退款一级记录
1019      * @param refundCarryVo 全局携带参数结构
1020      * @param commonService 映射
1021      * @return 全局携带参数结构
ae6ff7 1022      */
1869f3 1023     public static RefundCarryVo handRefundCard(RefundRecord refundRecord, RefundRecordItem refundRecordItem,RefundCarryVo refundCarryVo,CommonService commonService) {
ae6ff7 1024
C 1025         //判断操作完了去修改子订单状态
1026         OrderItem orderItem=commonService.selectOneByKey(OrderItemMapper.class,refundRecordItem.getOrderItemId());
1027         if (orderItem==null){
1869f3 1028             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到子订单信息");
ae6ff7 1029         }
C 1030         Integer surplusNum = orderItem.getBuyNum() - orderItem.getHasReNum();
1031         if(refundRecordItem.getRefundNum() > surplusNum){
1032             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款作废卡包提示:没有找到对应的卡包可退[020]");
1033         }
1034
1035         //找到可退款卡包
160c33 1036         List<UserCard> userCardList = PartialRefundUtil.getRefundCard(orderItem.getId(),UserProjectConstants.EFF_STATUS_YES,commonService);
ae6ff7 1037         if(refundRecordItem.getRefundNum() > userCardList.size()){
C 1038             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款作废卡包提示:没有找到对应的卡包可退[021]");
1039         }
1040
a1c527 1041         SqlSentence sqlSentence = new SqlSentence();
C 1042         Map<String, Object> map = new HashMap<>();
1043
1869f3 1044         //变更卡项状态
ae6ff7 1045         UserCard userCard;
1869f3 1046         RefundRecordCard refundRecordCard;
ae6ff7 1047         for (int i = 0; i < refundRecordItem.getRefundNum(); i++) {
C 1048             userCard= userCardList.get(i);
1049             map.put("id",userCard.getId());
ea2ceb 1050             map.put("statusOld", UserCard.TYPE_NO_USED);
ae6ff7 1051             map.put("effectiveStatus", UserProjectConstants.EFF_STATUS_CANCEL);
2e8393 1052             map.put("oldEffectiveStatus", UserProjectConstants.EFF_STATUS_YES);
ea2ceb 1053             sqlSentence.sqlSentence(" effectiveStatus=#{m.effectiveStatus} WHERE id = #{m.id} AND effectiveStatus = #{m.oldEffectiveStatus} AND status = #{m.statusOld}",map);
2e8393 1054             if(commonService.updateWhere(UserCardMapper.class,sqlSentence) != 1){
C 1055                 throw new TipsException("用户卡包状态已发生变化,请重试!");
1056             }
1869f3 1057
C 1058             //生成退款关联
1059             refundRecordCard = new RefundRecordCard();
1060             refundRecordCard.setUserCardId(userCard.getId());
1061             refundRecordCard.setRefundRecordId(refundRecord.getId());
1062             refundRecordCard.setRefundRecordItemId(refundRecordItem.getId());
a1c527 1063             commonService.insert(RefundRecordCardMapper.class,refundRecordCard);
ae6ff7 1064         }
C 1065
a1c527 1066         int refundStatus;
ea4351 1067         //卡项的,不管有没有退数量,只要走进这里,都是部分退或者全部退,可能有卡项部分退
ae6ff7 1068         if (surplusNum.equals(refundRecordItem.getRefundNum())){
1869f3 1069             refundStatus =  OrderTotalConstants.STATUS_REFUND_FINSH;
ae6ff7 1070         }else {
1869f3 1071             refundStatus =  OrderTotalConstants.STATUS_REFUND_PART;
ae6ff7 1072         }
ea4351 1073
1869f3 1074         //更新子订单信息
C 1075         updateOrderItemOne(orderItem,refundStatus,refundRecordItem.getRefundMoney(),refundRecordItem.getRefundNum(),commonService);
ae6ff7 1076
C 1077         //退款方式处理
1869f3 1078         refundCarryVo = refundRecordMotnedItemHandle(null,refundRecord,refundRecordItem,refundCarryVo,commonService);
ea4351 1079
C 1080         //--卡项部分退处理
3badb7 1081         if(RefundSoruceConstants.TYPE_SOURCE_USER_CARD.equals(refundRecord.getSourceAssistantType())){
ea4351 1082             CardRefundTool.realRefund(refundRecord,refundRecordItem,refundCarryVo,commonService);
C 1083         }
1084
1869f3 1085         return refundCarryVo;
ae6ff7 1086     }
C 1087
a1c527 1088     /**退款-处理卡包
ae6ff7 1089      */
1869f3 1090     public static void handCardBag(String operationId,RefundRecord refundRecord, OrdersTotal ordersTotal
C 1091             ,RefundRecordItem refundRecordItem,RefundCarryVo refundCarryVo,CommonService commonService) {
ae6ff7 1092
a1c527 1093         //查看订单信息
C 1094         OrderItem orderItem=commonService.selectOneByKey(OrderItemMapper.class,refundRecordItem.getOrderItemId());
1095         if(orderItem == null ){
1096             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到子订单信息!");
1097         }
1098
ae6ff7 1099         SqlSentence sqlSentence = new SqlSentence();
C 1100         Map<String, Object> map = new HashMap<>();
1101
1102         map.put("refundRecordItemId",refundRecordItem.getId());
a1c527 1103         sqlSentence.sqlSentence("select * from refund_record_item_source where refundRecordItemId =#{m.refundRecordItemId}",map);
ae6ff7 1104         List<RefundRecordItemSource> sons = commonService.selectList(RefundRecordItemSourceMapper.class, sqlSentence);
C 1105         if(sons.size() == 0 ){
1106             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到子订单信息[015]!");
1107         }
1108
1109         for (RefundRecordItemSource son : sons) {
1869f3 1110             refundCarryVo.setRefundConsumePayList(new ArrayList<>());
C 1111             refundCarryVo.setDeductionTotal(BigDecimal.ZERO);
1112             refundCarryVo.setCashTotal(BigDecimal.ZERO);
ae6ff7 1113             switch (GroupTypeEnum.getCode(son.getType())){
C 1114                 case PROJECT:
1869f3 1115                     //handRefundNoSonExecution(refundRecord,son,refundCarryVo,commonService);
ae6ff7 1116                     break;
C 1117                 case RETAIL:
1869f3 1118                     //handRefundSonRerail(refundRecord,son,refundCarryVo,commonService );
C 1119                     //deleteUserCardUsed(sqlSentence,map,ordersTotal,commonService,son,orderItem);
ae6ff7 1120                     break;
C 1121                 case INCREMENT:
1122                     //增值金
1123                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1124                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
1125                         UserMoneyUtil.setNewUserMoneyUnclaimed(refundRecord.getUserId(),refundRecord.getRemarks(),"审核通过退款:促销赠送增值金扣减",operationId,refundRecord.getOrderId(),ordersTotal.getAppIdCode(),refundRecord.getId(),son.getRealRefundTotal().negate(), UserMoneyUnclaimed.FUND_TYPE_VALUE_ADDED_FUND, OperationReasonConstants.OP_REASON_RECHARGE_REFUND,commonService,UserMoneyUnclaimed.YES);
1126                     }
1127                     break;
1128                 case STORED:
1129                     //储值金额
1130                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1131                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
1132                         UserMoneyUtil.setNewUserMoneyUnclaimed(refundRecord.getUserId(),refundRecord.getRemarks(),"审核通过退款:促销赠送储值金额扣减",operationId,refundRecord.getOrderId(),ordersTotal.getAppIdCode(),refundRecord.getId(),son.getRealRefundTotal().negate(), UserMoneyUnclaimed.FUND_TYPE_STORED_VALUE_FUND, OperationReasonConstants.OP_REASON_RECHARGE_REFUND,commonService,UserMoneyUnclaimed.NO);
1133                     }
1134                     break;
1135                 case INTEGRAL:
1136                     //积分
1137                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1138                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
1139                         UserMoneyUtil.setNewUserMoneyUnclaimed(refundRecord.getUserId(),refundRecord.getRemarks(),"审核通过退款:促销赠送积分扣减",operationId,refundRecord.getOrderId(),ordersTotal.getAppIdCode(),refundRecord.getId(),son.getRealRefundTotal().negate(), UserMoneyUnclaimed.FUND_TYPE_INTEGRAL,OperationReasonConstants.OP_REASON_RECHARGE_REFUND,commonService,UserMoneyUnclaimed.YES);
1140                     }
1141                     break;
1142             }
1143         }
1144
1145         //更改二级子订单退款状态
1146         map.put("orderItemId",orderItem.getId());
1147         sqlSentence.setSqlSentence("select * from order_item_source WHERE  orderItemId=#{m.orderItemId} and isDel=0");
1148         List<OrderItemSon> orderItemSonList=commonService.selectList(OrderItemSonMapper.class,sqlSentence);
1149
a1c527 1150         List<Integer> collect = orderItemSonList.stream().map(OrderItemSon::getRefundStatus).collect(Collectors.toList());
ae6ff7 1151         if(collect.contains(OrderTotalConstants.STATUS_REFUND_PART)){
C 1152             orderItem.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
1153             orderItem.setReTotal(orderItemSonList.stream().map(OrderItemSon::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
1154         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE) && collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
1155             orderItem.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
1156             orderItem.setReTotal(orderItemSonList.stream().map(OrderItemSon::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
1157         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE)){
1158             orderItem.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
1159         }else  if (collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
1160             orderItem.setRefundStatus(OrderTotalConstants.STATUS_REFUND_FINSH);
1161             orderItem.setReTotal(orderItemSonList.stream().map(OrderItemSon::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
1162             orderItem.setHasReNum(orderItem.getBuyNum());
1163         }else {
1164             orderItem.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
1165         }
1166
1167         commonService.updateAll(OrderItemMapper.class,orderItem);
1168     }
1169
a1c527 1170     /**退款需要删除用户卡包使用记录
b91aa3 1171      * @param userCardId 用户卡包
a1c527 1172      * @param cardItemInfoId 卡包的卡项子项
C 1173      * @param sourceId 卡包使用记录来源标识
e9e32c 1174      * @param orderId 卡包使用记录来源总表标识
a1c527 1175      * @param refundNum 退款数量
C 1176      * @param commonService 映射
ae6ff7 1177      */
b91aa3 1178     public static void deleteUserCardUsed(String userCardId,String cardItemInfoId,String sourceId,String orderId,Integer refundNum
a1c527 1179             ,CommonService commonService){
1869f3 1180
a1c527 1181         //查出用户,commonId:卡项的组合项标识
C 1182         CardItemInfo cardItemInfo=commonService.selectOneByKey(CardItemInfoMapper.class,cardItemInfoId);
1183         if(cardItemInfo ==null){
b91aa3 1184             logger.error("未找到该卡包的组合项-卡包退款失败,userCardId:{},cardItemInfoId:{},sourceId:{},orderId:{},refundNum:{}",userCardId,cardItemInfoId,sourceId,orderId,refundNum);
a1c527 1185             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到该卡包的组合项");
C 1186         }
1187
1188         //获取权益类型
1189         CardEquity cardEquity = commonService.selectOneByKey(CardEquityMapper.class,cardItemInfo.getCardEquityId());
1190         if(cardEquity == null){
b91aa3 1191             logger.error("未找到该卡包的组合项权益类型-卡包退款失败,userCardId:{},cardItemInfoId:{},sourceId:{},orderId:{},refundNum:{}",userCardId,cardItemInfoId,sourceId,orderId,refundNum);
a1c527 1192             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到该卡包的组合项权益类型");
e9e32c 1193         }
C 1194
1195         SqlSentence sqlSentence = new SqlSentence();
1196         Map<String,Object> map = new HashMap<>();
1197
1198         //获取使用记录
1199         map.put("cardItemInfoId",cardItemInfoId);
1200         map.put("sourceId",sourceId);
b91aa3 1201         map.put("userCardId",userCardId);
ea4351 1202         map.put("sourceType",UserCardUsed.SOURCE_TYPE_ORDER_ITEM_TWO);
b91aa3 1203         sqlSentence.sqlSentence(" SELECT * FROM user_card_used WHERE isDel = 0 AND userCardId = #{m.userCardId}" +
ea4351 1204                 " AND cardItemInfoId = #{m.cardItemInfoId} AND sourceId = #{m.sourceId} AND sourceType = #{m.sourceType}",map);
e9e32c 1205         List<UserCardUsed> userCardUsedList = commonService.selectList(UserCardUsedMapper.class,sqlSentence);
C 1206
1207         //因为之前的使用记录有些没有关联到订单,所以找不到
1208         if(userCardUsedList == null || userCardUsedList.size() == 0){
1209             map.clear();
1210             map.put("cardItemInfoId",cardItemInfoId);
b91aa3 1211             map.put("userCardId",userCardId);
C 1212             map.put("orderId",orderId);
ea4351 1213             map.put("sourceType",UserCardUsed.SOURCE_TYPE_ORDER_ITEM_TWO);
C 1214             sqlSentence.sqlSentence(" SELECT * FROM user_card_used WHERE isDel = 0 AND sourceType = #{m.sourceType} AND userCardId = #{m.userCardId}" +
b91aa3 1215                     " AND cardItemInfoId = #{m.cardItemInfoId} AND orderId = #{m.orderId} AND sourceId IS NULL",map);
e9e32c 1216             userCardUsedList = commonService.selectList(UserCardUsedMapper.class,sqlSentence);
b91aa3 1217             if(userCardUsedList.size() == 0){
ea4351 1218                 sqlSentence.sqlSentence(" SELECT * FROM user_card_used WHERE isDel = 0 AND sourceType = #{m.sourceType} AND userCardId = #{m.userCardId}" +
b91aa3 1219                         " AND cardItemInfoId = #{m.cardItemInfoId} AND sourceId IS NULL",map);
C 1220                 userCardUsedList = commonService.selectList(UserCardUsedMapper.class,sqlSentence);
1221             }
a1c527 1222         }
C 1223
a88f94 1224         //获取总使用数量
C 1225         int usedNum = 0;
1226         for(UserCardUsed userCardUsed:userCardUsedList){
1227             usedNum = usedNum+userCardUsed.getUsedNum();
a1c527 1228         }
C 1229
1230         //计算退回的卡次
a88f94 1231         int returnNum = UserCardTool.countUsedNumber(refundNum,cardItemInfo,cardEquity);
a1c527 1232
a88f94 1233         if(returnNum > usedNum){
2b1cfa 1234             logger.error("卡包可退数量错误-卡包退款失败,查询语句:{},传入参数:{}",sqlSentence.getSqlSentence(), JSON.toJSONString(sqlSentence.getM()));
a88f94 1235             logger.error("卡包可退数量错误-卡包退款失败,userCardId:{},cardItemInfoId:{},sourceId:{},orderId:{},refundNum:{},returnNum:{},usedNum:{}",userCardId,cardItemInfoId,sourceId,orderId,refundNum,returnNum,usedNum);
1869f3 1236             throw new TipsException("卡包可退数量错误!");
C 1237         }
1238
e9e32c 1239         //已经操作数量
a88f94 1240         int opNum = returnNum;
e9e32c 1241         StringBuilder sql;
1869f3 1242         for(UserCardUsed userCardUsed:userCardUsedList){
1d573f 1243             //判断是否够了,跳出循环
a88f94 1244             if(opNum <= 0){
1d573f 1245                 break;
C 1246             }
a88f94 1247             if(userCardUsed.getUsedNum() <= 0){
C 1248                 continue;
1249             }
e9e32c 1250             map.clear();
a88f94 1251             sql = new StringBuilder();
1869f3 1252             map.put("id",userCardUsed.getId());
a88f94 1253             map.put("usedNumOld",userCardUsed.getUsedNum());
C 1254             if(opNum >= userCardUsed.getUsedNum()){
1255                 map.put("isDel",UserCardUsed.YES);
1256                 map.put("countNum",userCardUsed.getUsedNum());
1257                 opNum = opNum - userCardUsed.getUsedNum();
1258             }else{
1259                 map.put("isDel",UserCardUsed.NO);
1260                 map.put("countNum",opNum);
1261                 opNum = 0;
1262             }
1263             sql.append("isDel = #{m.isDel}");
1264             sql.append(",usedNum =  usedNum - #{m.countNum}");
1265             sql.append(",cancelNum =  cancelNum + #{m.countNum}");
e9e32c 1266             if(StringUtils.isEmpty(userCardUsed.getOrderId())){
C 1267                 sql.append(",orderId = #{m.orderId}");
1268                 map.put("orderId",orderId);
1269             }
1270             if(StringUtils.isEmpty(userCardUsed.getSourceId())){
1271                 sql.append(",sourceId = #{m.sourceId}");
1272                 map.put("sourceId",sourceId);
1273             }
a88f94 1274             sql.append(" WHERE id = #{m.id} AND isDel = 0 AND usedNum = #{m.usedNumOld}");
e9e32c 1275             sqlSentence.sqlUpdate(sql.toString(),map);
a88f94 1276             if(commonService.updateWhere(UserCardUsedMapper.class,sqlSentence)!=1){
db3dfa 1277                 throw new TipsException("卡包使用记录已发生变化,请重试!");
a88f94 1278             }
1869f3 1279         }
a88f94 1280         if(opNum != 0){
b91aa3 1281             logger.error("卡包回退数量错误-卡包退款失败,userCardId:{},cardItemInfoId:{},sourceId:{},orderId:{},refundNum:{},returnNum:{},opNum:{}",userCardId,cardItemInfoId,sourceId,orderId,refundNum,returnNum,opNum);
a1c527 1282             throw new TipsException("卡包回退数量错误!");
1869f3 1283         }
ae6ff7 1284     }
1869f3 1285
a1c527 1286     /**退款-处理促销
C 1287      * @param operationId 操作人标识
1288      * @param refundRecord 退款总记录
1289      * @param ordersTotal 订单
1290      * @param refundRecordItem 退款一级记录
1291      * @param refundCarryVo 全局携带参数结构
1292      * @param commonService 映射
1293      * @return 全局携带参数结构
ae6ff7 1294      */
1869f3 1295     private static RefundCarryVo handRefundPromotion(String operationId, RefundRecord refundRecord, OrdersTotal ordersTotal
C 1296             , RefundRecordItem refundRecordItem,RefundCarryVo refundCarryVo,CommonService commonService) {
ae6ff7 1297
C 1298         //查看订单信息
1869f3 1299         OrderItem orderItem = commonService.selectOneByKey(OrderItemMapper.class,refundRecordItem.getOrderItemId());
ae6ff7 1300         if(orderItem == null ){
C 1301             throw new PlatTipsException(PlatformCode.ERROR_PARAMETER_NULL,"未找到子订单信息[84]!");
1302         }
1303
a1c527 1304         SqlSentence sqlSentence = new SqlSentence();
C 1305         Map<String, Object> map = new HashMap<>();
1306
ae6ff7 1307         //获取退款二级单
C 1308         map.put("refundRecordItemId",refundRecordItem.getId());
a1c527 1309         sqlSentence.sqlSentence("select * from refund_record_item_source where isDel = 0 AND refundRecordItemId = #{m.refundRecordItemId}",map);
ae6ff7 1310         List<RefundRecordItemSource> sons = commonService.selectList(RefundRecordItemSourceMapper.class, sqlSentence);
C 1311
1869f3 1312         //根据支付记录总表的标识来整合已退的金额,key值:支付记录总表标识,value:金额数据
C 1313         Map<String,RefundRecordConsumePay> refundRecordConsumePayMap = new HashMap<>();
1314         RefundRecordConsumePay refundRecordConsumePay;
1315         //计算本次退款方式的划扣金额
1316         BigDecimal deductionTotal = BigDecimal.ZERO;
1317         //计算本次退款方式的现金金额
1318         BigDecimal cashTotal = BigDecimal.ZERO;
2a45d4 1319         //分配的用户项目划扣金额
C 1320         BigDecimal deductionTotalUser = BigDecimal.ZERO;
1869f3 1321
C 1322         for (RefundRecordItemSource son : sons) {
1323             //初始化总结构携带参数
1324             refundCarryVo.setRefundConsumePayList(new ArrayList<>());
1325             refundCarryVo.setDeductionTotal(BigDecimal.ZERO);
1326             refundCarryVo.setCashTotal(BigDecimal.ZERO);
2a45d4 1327             refundCarryVo.setDeductionTotalUser(BigDecimal.ZERO);
1869f3 1328             switch (GroupTypeEnum.getCode(son.getType())){
C 1329                 case PROJECT:
b91aa3 1330                     refundCarryVo = handRefundNoSonExecution(refundRecord,refundRecordItem,son,refundCarryVo,orderItem.getUserCardId(),commonService);
1869f3 1331                     break;
C 1332                 case RETAIL:
b91aa3 1333                     refundCarryVo = handRefundSonRerail(refundRecord,refundRecordItem,son,refundCarryVo,orderItem.getUserCardId(),commonService);
1869f3 1334                     break;
C 1335                 case INCREMENT:
1336                     //增值金
1337                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1338                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
1339                         UserMoneyUtil.setNewUserMoneyUnclaimed(refundRecord.getUserId(),refundRecord.getRemarks(),"审核通过退款:促销赠送增值金扣减",operationId,refundRecord.getOrderId(),ordersTotal.getAppIdCode(),refundRecord.getId(),son.getRealRefundTotal().negate(), UserMoneyUnclaimed.FUND_TYPE_VALUE_ADDED_FUND, OperationReasonConstants.OP_REASON_RECHARGE_REFUND,commonService,UserMoneyUnclaimed.YES);
1340                     }
1341                     break;
1342                 case STORED:
1343                     //储值金额
1344                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1345                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
1346                         UserMoneyUtil.setNewUserMoneyUnclaimed(refundRecord.getUserId(),refundRecord.getRemarks(),"审核通过退款:促销赠送储值金额扣减",operationId,refundRecord.getOrderId(),ordersTotal.getAppIdCode(),refundRecord.getId(),son.getRealRefundTotal().negate(), UserMoneyUnclaimed.FUND_TYPE_STORED_VALUE_FUND, OperationReasonConstants.OP_REASON_RECHARGE_REFUND,commonService,UserMoneyUnclaimed.NO);
1347                     }
1348                     break;
1349                 case INTEGRAL:
1350                     //积分
1351                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1352                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
1353                         UserMoneyUtil.setNewUserMoneyUnclaimed(refundRecord.getUserId(),refundRecord.getRemarks(),"审核通过退款:促销赠送积分扣减",operationId,refundRecord.getOrderId(),ordersTotal.getAppIdCode(),refundRecord.getId(),son.getRealRefundTotal().negate(), UserMoneyUnclaimed.FUND_TYPE_INTEGRAL,OperationReasonConstants.OP_REASON_RECHARGE_REFUND,commonService,UserMoneyUnclaimed.YES);
1354                     }
1355                     break;
1356             }
1357             deductionTotal = deductionTotal.add(refundCarryVo.getDeductionTotal());
1358             cashTotal = cashTotal.add(refundCarryVo.getCashTotal());
2a45d4 1359             deductionTotalUser = deductionTotalUser.add(refundCarryVo.getDeductionTotalUser());
1869f3 1360             //遍历叠加支付方式记录的退款金额
C 1361             for(RefundRecordConsumePay re:refundCarryVo.getRefundConsumePayList()){
2a45d4 1362                 refundRecordConsumePay = refundRecordConsumePayMap.computeIfAbsent(re.getConsumePayId(),k->new RefundRecordConsumePay(BigDecimal.ZERO,re.getNumberNo(),re.getName(),re.getIsMoneyPay(),re.getIsExecute(),re.getConsumePayId()));
1869f3 1363                 refundRecordConsumePay.setRefundTotal(refundRecordConsumePay.getRefundTotal().add(re.getRefundTotal()));
ae6ff7 1364             }
C 1365         }
1366
1869f3 1367         //转载返回支付方式记录的退款金额
C 1368         List<RefundRecordConsumePay> refundRecordConsumePayList = new ArrayList<>();
1369         for (Map.Entry<String, RefundRecordConsumePay> entry : refundRecordConsumePayMap.entrySet()) {
1370             refundRecordConsumePayList.add(entry.getValue());
1371         }
1372         refundCarryVo.setCashTotal(cashTotal);
1373         refundCarryVo.setDeductionTotal(deductionTotal);
2a45d4 1374         refundCarryVo.setDeductionTotalUser(deductionTotalUser);
1869f3 1375         refundCarryVo.setRefundConsumePayList(refundRecordConsumePayList);
2a45d4 1376
C 1377         //更新退款子单
1378         updateRefundItem(refundCarryVo.getDeductionTotal(),refundCarryVo.getCashTotal(),refundCarryVo.getDeductionTotalUser()
1379                 ,refundRecordItem.getId(),commonService);
ae6ff7 1380
1869f3 1381         //获取其子项
ae6ff7 1382         map.put("orderItemId",orderItem.getId());
e9e32c 1383         sqlSentence.sqlSentence("select refundStatus from order_item_source WHERE orderItemId=#{m.orderItemId} and isDel=0",map);
ae6ff7 1384         List<OrderItemSon> orderItemSonList=commonService.selectList(OrderItemSonMapper.class,sqlSentence);
a1c527 1385         int refundStatus;
1869f3 1386         Integer refundNum = 0;
a1c527 1387         List<Integer> collect = orderItemSonList.stream().map(OrderItemSon::getRefundStatus).collect(Collectors.toList());
1869f3 1388
ae6ff7 1389         if(collect.contains(OrderTotalConstants.STATUS_REFUND_PART)){
1869f3 1390             refundStatus = OrderTotalConstants.STATUS_REFUND_PART;
ae6ff7 1391         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE)){
1869f3 1392             if(collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
C 1393                 refundStatus = OrderTotalConstants.STATUS_REFUND_PART;
1394             }else{
1395                 refundStatus = OrderTotalConstants.STATUS_REFUND_NONE;
1396             }
ae6ff7 1397         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
1869f3 1398             refundStatus = OrderTotalConstants.STATUS_REFUND_FINSH;
C 1399             refundNum = orderItem.getBuyNum();
ae6ff7 1400         }else {
1869f3 1401             refundStatus = OrderTotalConstants.STATUS_REFUND_NONE;
ae6ff7 1402         }
C 1403
1869f3 1404         //更新子订单信息
C 1405         updateOrderItemOne(orderItem,refundStatus,refundRecordItem.getRefundMoney(),refundNum,commonService);
1406
1407         return refundCarryVo;
ae6ff7 1408     }
C 1409
1869f3 1410     /**退款-处理二级子订单未执行划扣   项目类型
a1c527 1411      * @param refundRecord 退款总记录
C 1412      * @param refundRecordItem 退款一级子单
1413      * @param refundRecordItemSource  退款二级子单
1414      * @param refundCarryVo 全局携带参数接口
1415      * @param commonService 映射
ae6ff7 1416      */
1869f3 1417     private static RefundCarryVo handRefundNoSonExecution(RefundRecord refundRecord,RefundRecordItem refundRecordItem, RefundRecordItemSource refundRecordItemSource
b91aa3 1418             ,RefundCarryVo refundCarryVo,String userCardId,CommonService commonService) {
ae6ff7 1419
C 1420         //判断操作完了去修改子订单状态
510678 1421         OrderItemSon orderItemSon = commonService.selectOneByKey(OrderItemSonMapper.class,refundRecordItemSource.getOrderItemSonId());
ae6ff7 1422         if (orderItemSon==null){
510678 1423             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到二级子订单信息[02]");
ae6ff7 1424         }
C 1425
1426         UserProjectItem userProjectItem = getUserProject(orderItemSon.getId(),commonService);
1427         if(userProjectItem == null){
510678 1428             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"用户项目获取失败[06]!");
ae6ff7 1429         }
C 1430         if(userProjectItem.getNotUsedNum()<refundRecordItemSource.getRefundNum()){
1431             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款次数大于可退次数[83]!");
1432         }
1433
1434         //计算子单是否还有剩余的可扣疗程数
1435         int surplusNum = orderItemSon.getUsedTotal() - orderItemSon.getHasReNum();
1436         if(refundRecordItemSource.getRefundNum() > surplusNum){
510678 1437             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款次数大于可退次数[56]!");
ae6ff7 1438         }
C 1439
1869f3 1440         //处理用户项目,减去用户项目数量
C 1441         UserProjectDeductionVo userProjectDeductionVo= UserProjectTool.userProjectDeduction(userProjectItem,UserProjectUsedCon.USED_METHOD_ORDER_REFUND,UserProjectUsedCon.USED_TYPE_DEDUCTION,null
ae6ff7 1442                 ,refundRecordItemSource.getId(),refundRecordItemSource.getRefundNum(),refundRecord.getOperatorAppId(),refundRecord.getOperatorAppName(),refundRecord.getRefundShopId(),refundRecord.getRefundShopName(),"员工备注:"+refundRecord.getRemarks()+"|用户备注:"+refundRecord.getRefundReason(),commonService);
2a45d4 1443
C 1444         refundCarryVo.setDeductionTotalUser(userProjectDeductionVo.getDeductionTotal());
ae6ff7 1445
a1c527 1446         int refundStatus;
ae6ff7 1447         if(surplusNum == refundRecordItemSource.getRefundNum()){
C 1448             refundStatus=OrderTotalConstants.STATUS_REFUND_FINSH;
1449         }else{
1450             refundStatus=OrderTotalConstants.STATUS_REFUND_PART;
1451         }
1452
1869f3 1453         //更新子单信息
C 1454         updateOrderItemTwo(orderItemSon,refundStatus,refundRecordItemSource.getRefundMoney(),refundRecordItemSource.getRefundNum(),commonService);
1455
1456         //处理退款支付方式
1457         refundCarryVo = refundRecordMotnedItemTwoHandle(userProjectDeductionVo.getDeductionTotal(),refundRecord,refundRecordItemSource,refundCarryVo,commonService);
1458
1459         if(refundRecordItem.getType().equals(OrderItemConstants.CARD_BAG)){
1460             //是卡包的,刪除卡包使用
b91aa3 1461             deleteUserCardUsed(userCardId,orderItemSon.getCardItemInfoId(),orderItemSon.getId(),orderItemSon.getOrderId(),refundRecordItemSource.getRefundNum(),commonService);
ae6ff7 1462         }
C 1463
1869f3 1464         return refundCarryVo;
ae6ff7 1465     }
1869f3 1466
C 1467     /**退款二级是商品
a1c527 1468      * @param refundRecord 退款总记录
C 1469      * @param refundRecordItem 退款一级子单
1470      * @param refundRecordItemSource  退款二级子单
1471      * @param refundCarryVo 全局携带参数结构
1472      * @param commonService 映射
1473      * @return 全局携带参数结构
ae6ff7 1474      */
a1c527 1475     private static RefundCarryVo handRefundSonRerail(RefundRecord refundRecord,RefundRecordItem refundRecordItem, RefundRecordItemSource refundRecordItemSource
b91aa3 1476             ,RefundCarryVo refundCarryVo,String userCardId,CommonService commonService) {
ae6ff7 1477
C 1478         //判断操作完了去修改子订单状态
1869f3 1479         OrderItemSon orderItemSon=commonService.selectOneByKey(OrderItemSonMapper.class,refundRecordItemSource.getOrderItemSonId());
C 1480         if (orderItemSon==null){
ae6ff7 1481             throw new PlatTipsException(PlatformCode.ERROR_PARAMETER_NULL,"未找到二级子订单信息");
C 1482         }
1483
1869f3 1484         //计算子单是否还有剩余的可扣疗程数
C 1485         int surplusNum = orderItemSon.getBuyNum() - orderItemSon.getHasReNum();
1486         if(refundRecordItemSource.getRefundNum() > surplusNum){
1487             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款次数大于可退次数[84]!");
ae6ff7 1488         }
C 1489
a1c527 1490         int refundStatus;
1869f3 1491         if(surplusNum == refundRecordItemSource.getRefundNum()){
C 1492             refundStatus=OrderTotalConstants.STATUS_REFUND_FINSH;
1493         }else{
1494             refundStatus=OrderTotalConstants.STATUS_REFUND_PART;
1495         }
1496
1497         updateOrderItemTwo(orderItemSon,refundStatus,refundRecordItemSource.getRefundMoney(),refundRecordItemSource.getRefundNum(),commonService);
1498
1499         //处理退款支付方式
1500         refundCarryVo = refundRecordMotnedItemTwoHandle(null,refundRecord,refundRecordItemSource,refundCarryVo,commonService);
a1c527 1501
C 1502         if(refundRecordItem.getType().equals(OrderItemConstants.CARD_BAG)){
1503             //是卡包的,刪除卡包使用
b91aa3 1504             deleteUserCardUsed(userCardId,orderItemSon.getCardItemInfoId(),orderItemSon.getId(),orderItemSon.getOrderId(),refundRecordItemSource.getRefundNum(),commonService);
a1c527 1505         }
1869f3 1506
C 1507         return refundCarryVo;
1508     }
1509
1510     /**更新订单一级子单的信息
1511      * @param orderItem 订单子单
1512      * @param refundStatus 退款状态
160c33 1513      * @param refundTotal 退款金额,正负数
C 1514      * @param refundNum 退款数量 正负数
1869f3 1515      * @param commonService 映射
C 1516      */
1517     public static void updateOrderItemOne(OrderItem orderItem,Integer refundStatus,BigDecimal refundTotal,Integer refundNum
1518             ,CommonService commonService){
1519         SqlSentence sqlSentence = new SqlSentence();
1520         Map<String,Object> values = new HashMap<>();
1521
510678 1522         values.put("id", orderItem.getId());
1869f3 1523         values.put("refundStatus", refundStatus);
C 1524         values.put("refundTotal",refundTotal);
1525         values.put("refundNum",refundNum);
1526         values.put("oldHasReNum",orderItem.getHasReNum());
1527         sqlSentence.sqlUpdate(" refundStatus=#{m.refundStatus},reTotal=reTotal+#{m.refundTotal},hasReNum=hasReNum+#{m.refundNum}" +
510678 1528                 " WHERE isDel = 0 AND id = #{m.id} AND hasReNum = #{m.oldHasReNum}",values);
1869f3 1529         if(commonService.updateWhere(OrderItemMapper.class,sqlSentence) != 1){
C 1530             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"当前订单信息已发生变化,请重试[012]!");
1531         }
1532     }
1533
1534     /**更新订单二级子单的信息
1535      * @param orderItemSon 订单子单
1536      * @param refundStatus 退款状态
1537      * @param refundTotal 退款金额
1538      * @param refundNum 退款数量
1539      * @param commonService 映射
1540      */
1541     public static void updateOrderItemTwo(OrderItemSon orderItemSon,Integer refundStatus,BigDecimal refundTotal,Integer refundNum
1542             ,CommonService commonService){
1543         SqlSentence sqlSentence = new SqlSentence();
1544         Map<String,Object> values = new HashMap<>();
1545
1546         values.put("id", orderItemSon.getId());
1547         values.put("refundStatus", refundStatus);
1548         values.put("refundTotal",refundTotal);
1549         values.put("refundNum",refundNum);
1550         values.put("oldHasReNum",orderItemSon.getHasReNum());
510678 1551         sqlSentence.sqlUpdate(" refundStatus = #{m.refundStatus},reTotal=reTotal+#{m.refundTotal},hasReNum=hasReNum+#{m.refundNum}" +
1869f3 1552                 " where isDel=0 AND id = #{m.id} AND hasReNum = #{m.oldHasReNum}",values);
C 1553         if(commonService.updateWhere(OrderItemSonMapper.class,sqlSentence) != 1){
1554             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"当前订单信息已发生变化,请重试[012]!");
1555         }
1556     }
1557
a1c527 1558     /**获取订单一级子单的支付方式记录
C 1559      * @param orderItemId 订单一级子单标识
1560      * @param commonService 映射
1561      * @return 订单一级子单的支付方式记录
1869f3 1562      */
C 1563     public static List<ConsumePayItem> getOrderItemOneConsumePay(String orderItemId,CommonService commonService){
1564
1565         SqlSentence sqlSentence = new SqlSentence();
1566         Map<String,Object> values = new HashMap<>();
1567
1568         //获取子单的支付方式,一级子单支付记录,计算可退款金额
1569         values.put("typeId",orderItemId);
1570         sqlSentence.sqlSentence("SELECT * FROM consume_pay_item WHERE isDel = 0 AND typeId = #{m.typeId}",values);
2a45d4 1571         return commonService.selectList(ConsumePayItemMapper.class,sqlSentence);
1869f3 1572     }
C 1573
a1c527 1574     /**获取订单二级子单的支付方式记录
C 1575      * @param orderItemId 订单一级子单标识
1576      * @param commonService 映射
1577      * @return 订单二级子单的支付方式记录
1869f3 1578      */
C 1579     public static List<ConsumePayItem> getOrderItemTwoConsumePay(String orderItemId,CommonService commonService){
1580
1581         SqlSentence sqlSentence = new SqlSentence();
1582         Map<String,Object> values = new HashMap<>();
1583
1584         //获取子单的支付方式,一级子单支付记录,计算可退款金额
1585         values.put("typeId",orderItemId);
1586         sqlSentence.sqlSentence("SELECT * FROM consume_pay_item_son WHERE isDel = 0 AND typeId = #{m.typeId}",values);
2a45d4 1587         List<ConsumePayItemSon> consumePayItemSonList = commonService.selectList(ConsumePayItemSonMapper.class,sqlSentence);
C 1588         List<ConsumePayItem> consumePayItemList = new ArrayList<>();
1589         ConsumePayItem consumePayItem;
1590         for(ConsumePayItemSon consumePayItemSon:consumePayItemSonList){
1591             consumePayItem = new ConsumePayItem();
1592             BeanUtils.copyProperties(consumePayItemSon,consumePayItem);
1593             consumePayItemList.add(consumePayItem);
1594         }
1595         return consumePayItemList;
ae6ff7 1596     }
C 1597
1598     /**保存退款方式和支付方式关联
1599      * @param refundTotal 退款金额
1600      * @param commonType 子单级别,可空
1601      * @param commonId 子单标识,可空
1602      * @param orderId  总单标识
1603      * @param numberNo 支付方式编号
1604      * @param name 支付方式名称
1605      * @param consumePayId 支付方式记录标识
1606      * @param refundMethodId 退款方式标识
1607      * @param refundRecordItemId 退款子记录标识,可空
1608      * @param refundRecordId 退款总记录标识
1609      * @param commonService 映射
1610      * @return 返回关联记录
1611      */
1612     public static RefundRecordConsumePay insertRefundRecordConsumePay(BigDecimal refundTotal, String commonType, String commonId, String orderId
2a45d4 1613             , String numberNo,String name,Integer isMoneyPay,Integer isExecute, String consumePayId, String refundMethodId,String refundRecordItemId,String refundRecordId,CommonService commonService){
ae6ff7 1614         //生成关联记录
C 1615         RefundRecordConsumePay refundRecordConsumePay = new RefundRecordConsumePay();
1616         refundRecordConsumePay.setRefundTotal(refundTotal);
1617         refundRecordConsumePay.setCommonType(commonType);
1618         refundRecordConsumePay.setCommonId(commonId);
1619         refundRecordConsumePay.setOrderId(orderId);
1620         refundRecordConsumePay.setName(name);
1621         refundRecordConsumePay.setNumberNo(numberNo);
2a45d4 1622         refundRecordConsumePay.setIsMoneyPay(isMoneyPay);
C 1623         refundRecordConsumePay.setIsExecute(isExecute);
ae6ff7 1624         refundRecordConsumePay.setConsumePayId(consumePayId);
C 1625         refundRecordConsumePay.setRefundMethodId(refundMethodId);
1626         refundRecordConsumePay.setRefundRecordItemId(refundRecordItemId);
1627         refundRecordConsumePay.setRefundRecordId(refundRecordId);
1628         commonService.insert(RefundRecordConsumePayMapper.class,refundRecordConsumePay);
1629         return refundRecordConsumePay;
1630     }
1631
1632     /**获取可退款的用户卡项
1633      * @param sourceId 订单子单标识
1634      * @return 可退款的用户卡项
1635      */
160c33 1636     public static List<UserCard> getRefundCard(String sourceId,int effectiveStatus,CommonService commonService){
ae6ff7 1637         SqlSentence sqlSentence = new SqlSentence();
C 1638         Map<String,Object> sqlMap = new HashMap<>();
1639         //获取用户卡项
1640         sqlMap.put("sourceId",sourceId);
1641         sqlMap.put("status",UserCard.TYPE_NO_USED);
160c33 1642         sqlMap.put("effectiveStatus",effectiveStatus);
ae6ff7 1643         sqlSentence.sqlSentence("SELECT * FROM user_card WHERE isDel = 0 AND sourceId = #{m.sourceId} AND status = #{m.status}" +
C 1644                 " AND effectiveStatus = #{m.effectiveStatus} AND turnAddId IS NULL",sqlMap);
949373 1645         List<UserCard> userCardList = commonService.selectList(UserCardMapper.class,sqlSentence);
C 1646         if(userCardList.size() == 0){
1647             return userCardList;
1648         }
ea4351 1649
949373 1650         //获取已经部分退的用户卡包数量
ea4351 1651         List<RefundRecordItem> refundRecordItemList = CardRefundTool.findRefundUserCard(sourceId,null,commonService);
949373 1652         //过滤掉没有使用但有部分退款
C 1653         if(refundRecordItemList.size() == 0){
1654             return userCardList;
1655         }
1656
1657         Map<String,UserCard> userCardMap = new HashMap<>();
1658         for(UserCard userCard:userCardList){
1659             userCardMap.put(userCard.getId(),userCard);
1660         }
1661         //去除掉参与部分退款的用户卡包
1662         for(RefundRecordItem refundRecordItem:refundRecordItemList){
1663             userCardMap.remove(refundRecordItem.getUserCardId());
1664         }
1665
1666         userCardList = new ArrayList<>();
ea4351 1667         List<UserCardUsed> userCardUsedList;
949373 1668         for (Map.Entry<String,UserCard> entry : userCardMap.entrySet()) {
ea4351 1669             //获取使用记录,如果有使用记录,那么就跳过
C 1670             userCardUsedList = UserCardTool.getUsedRecord(entry.getValue().getId(),null,null,commonService);
1671             if(userCardUsedList.size() > 0){
1672                 continue;
1673             }
949373 1674             userCardList.add(entry.getValue());
C 1675         }
1676
1677         return userCardList;
ae6ff7 1678
C 1679     }
1680
1681     /**获取用户项目*/
1682     public static UserProjectItem getUserProject(String commonId,CommonService commonService){
1683         SqlSentence sqlSentence = new SqlSentence();
1684         Map<String, Object> map = new HashMap<>();
1685
1686         map.put("commonId",commonId);
1687         sqlSentence.sqlSentence("select * from user_project_item where isDel=0 and commonId=#{m.commonId} and isTransfer = 0",map);
a1c527 1688         return commonService.selectOne(UserProjectItemMapper.class,sqlSentence);
dd4c9b 1689     }
C 1690
ae6ff7 1691 }