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