chenjiahe
2023-03-31 1869f358a6aaccf4e4f76df73f10ef5e1e5d8313
提交 | 用户 | age
1869f3 1 package com.hx.phip.util.api;
ae6ff7 2
C 3 import com.hx.common.service.CommonService;
4 import com.hx.exception.TipsException;
5 import com.hx.mybatisTool.SqlSentence;
6 import com.hx.phiappt.common.*;
7 import com.hx.phiappt.constants.enums.GroupTypeEnum;
8 import com.hx.phiappt.constants.tool.RefundToolUtil;
9 import com.hx.phiappt.model.BaseEntity;
10 import com.hx.phiappt.model.UserMoney;
11 import com.hx.phiappt.model.activity.ActivityAction;
12 import com.hx.phiappt.model.activity.ActivityRule;
13 import com.hx.phiappt.model.consume.ConsumePay;
14 import com.hx.phiappt.model.consume.ConsumePayItem;
15 import com.hx.phiappt.model.coupon.CouponNumber;
16 import com.hx.phiappt.model.coupon.CouponOrderDiscountLog;
17 import com.hx.phiappt.model.order.*;
18 import com.hx.phiappt.model.refund.*;
19 import com.hx.phiappt.model.user.UserCard;
20 import com.hx.phiappt.model.user.UserCardUsed;
21 import com.hx.phiappt.model.user.UserProjectItem;
22 import com.hx.phiappt.model.userMoney.UserMoneyUnclaimed;
23 import com.hx.phip.config.CustomParameter;
24 import com.hx.phip.dao.mapper.*;
25 import com.hx.phip.tool.user.UserProjectTool;
1869f3 26 import com.hx.phip.vo.order.refund.RefundCarryVo;
C 27 import com.hx.phip.vo.user.UserProjectDeductionVo;
ae6ff7 28 import com.hx.util.StringUtils;
C 29 import com.platform.exception.PlatTipsException;
30 import com.platform.resultTool.PlatformCode;
31
32 import java.math.BigDecimal;
33 import java.math.RoundingMode;
34 import java.util.*;
35 import java.util.stream.Collectors;
36
37 /**
38  * @Author
39  */
40 public class PartialRefundUtil {
41
42     /**领建优惠券标识*/
43     public static final String HIS_COUPON_CODE = "his_coupon_code";
44
45     /**
46      * 退款总流程工具
47      * @param commonService
48      * @param operationId
49      * @param operationNme
50      * @param refundId
51      */
52     public static OrdersTotal refundProcess(CommonService commonService, String operationId, String operationNme, String refundId, CustomParameter customParameter) {
53
54         RefundRecord refundRecord = commonService.selectOneByKeyBlob(RefundRecordMapper.class,refundId);
55         if(refundRecord ==null){
56             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"找不到该退款信息!");
57         }
58
59         SqlSentence sqlSentence = new SqlSentence();
60         Map<String,Object> values = new HashMap<>();
61
62         //退款总订单状态变更
63         values.clear();
64         values.put("refundStatus", RefundStatus.STATUS_SUCC_REFUND);
65         values.put("oldRefundStatus", RefundStatus.STATUS_APPLY_REFUND);
66         values.put("isDel", BaseEntity.NO);
67         values.put("id",refundRecord.getId());
68         sqlSentence.setSqlSentence(" refundStatus=#{m.refundStatus} WHERE id = #{m.refundId} AND isDel=#{m.isDel} AND refundStatus = #{m.oldRefundStatus}");
69         if(commonService.updateWhere(RefundRecordMapper.class,sqlSentence) != 1){
70             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"操作失败,退款单状态已改变!");
71         }
72
73         //回去订单信息
74         OrdersTotal ordersTotal = commonService.selectOneByKeyBlob(OrdersTotalMapper.class,refundRecord.getOrderId());
75         if(ordersTotal == null ){
76             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到订单信息!");
77         }
78
79         //查询用户是否有账户信息,退款需要处理资金
80         values.put("userId",refundRecord.getUserId());
81         sqlSentence.setSqlSentence("SELECT * FROM user_money WHERE  userId=#{m.userId} AND isDel=0");
82         UserMoney userMoney=commonService.selectOne(UserMoneyMapper.class,sqlSentence);
83         if(userMoney==null){
84             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到该用户的资金信息");
85         }
1869f3 86
C 87         //获取总退款方式
88         values.put("refundRecordId",refundRecord.getId());
89         sqlSentence.sqlSentence("SELECT * FROM refund_record_method WHERE isDel = 0 AND refundRecordId = #{m.refundRecordId}",values);
90         List<RefundRecordMethod> refundRecordMethodList = commonService.selectList(RefundRecordMethodMapper.class,sqlSentence);
91
92         //全程使用携带参数对象
93         RefundCarryVo refundCarryVo = new RefundCarryVo();
94         refundCarryVo.setRefundRecordMethodList(refundRecordMethodList);
ae6ff7 95
C 96         //处理优惠券
97         handCoupon(refundRecord,commonService);
98         //处理总退款方式数据
99         refundRecordMotnedHandle(operationId,operationNme,refundRecord,ordersTotal,commonService);
100         //子单退款项处理
101         numberOfRefunds(operationId, operationNme, refundRecord,ordersTotal,customParameter,commonService);
102
103         if(OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){
104             //充值订单需要把充值的储值金 拿回来   因为储值金需要开单来处理,所以不需要增加日志
105             //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
106             if(ordersTotal.getActualTotal().compareTo(BigDecimal.ZERO)!=0){
107                 //交给审批前操作
108              /*   UserMoneyUtil.setNewUserMoneyUnclaimed(refundRecord.getUserId(),refundRecord.getRemarks(),"审核通过退款:支付方式储值金额退回",operationId,refundRecord.getOrderId(),appIdCode,refundRecord.getId(),new BigDecimal(String.valueOf(ordersTotal.getTotal())).negate(), UserMoneyUnclaimed.FUND_TYPE_STORED_VALUE_FUND, OperationReasonConstants.OP_REASON_RECHARGE_REFUND,commonService,UserMoneyUnclaimed.NO);
109                 OrderLog orderLog = RefundToolUtil.setOrderLog(refundRecord, operationId, operationNme, "储值金客户退回金额:"+ordersTotal.getTotal(), 0, OrderLogConstants.LOG_TYPE_REFUND);
110                 commonService.insert(OrderLogMapper.class,orderLog);*/
111                 //活动规则退款处理
112                 // handActivityRule(commonService, operationId, operationNme, sqlSentence, map, refundRecord,ordersTotal,orderInfo);
113             }
114         }
115
116
117         //更改总订单退款状态
118         values.clear();
119         values.put("orderId",ordersTotal.getId());
120         sqlSentence.setSqlSentence("select * from order_item WHERE  orderId=#{m.orderId} and isDel=0");
121         List<OrderItem> orderItemList=commonService.selectList(OrderItemMapper.class,sqlSentence);
122
123         List<Integer> collect = orderItemList.stream().map(o -> o.getRefundStatus()).collect(Collectors.toList());
124         if(collect.contains(OrderTotalConstants.STATUS_REFUND_PART)){
125             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
126             ordersTotal.setReTotal(orderItemList.stream().map(OrderItem::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
127         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE) && collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
128             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
129             ordersTotal.setReTotal(orderItemList.stream().map(OrderItem::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
130         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE)){
131             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
132         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
133             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_FINSH);
134             ordersTotal.setStatus(OrderTotalConstants.STATUS_CANCEL);
135             ordersTotal.setReTotal(orderItemList.stream().map(OrderItem::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
136         }else {
137             if(OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){
138                 if(ordersTotal.getActualTotal().compareTo(refundRecord.getRefundTotal()) <= 0){
139                     ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_FINSH);
140                 }else{
141                     ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
142                 }
143             }else{
144                 ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
145             }
146         }
147         ordersTotal.setIsSyncOrder(BaseEntity.NO);
148         ordersTotal.setEditTime(new Date());
149         commonService.updateAll(OrdersTotalMapper.class,ordersTotal);
150         return ordersTotal;
151     }
152
153     /**处理总退款方式数据*/
154     public static void refundRecordMotnedHandle(String operationId,String operationNme,RefundRecord refundRecord,OrdersTotal ordersTotal,CommonService commonService){
155         SqlSentence sqlSentence = new SqlSentence();
156         Map<String,Object> map = new HashMap<>();
157
158         //获取总退款方式
159         map.put("refundRecordId",refundRecord.getId());
160         sqlSentence.sqlSentence("SELECT * FROM refund_record_method WHERE isDel = 0 AND refundRecordId = #{m.refundRecordId}",map);
161         List<RefundRecordMethod> refundRecordMethodList = commonService.selectList(RefundRecordMethodMapper.class,sqlSentence);
162
163
164         //退款方式总金额
165         BigDecimal mothedTotal;
166         //支付方式扣减金额
167         BigDecimal mothedCutTotal;
168
169         //引用对象
170         List<ConsumePay> consumePayList;
171         for(RefundRecordMethod refundRecordMethod:refundRecordMethodList){
172             mothedTotal = refundRecordMethod.getActualTotal();
173             if(PayMethodTypeConstants.PAY_STORED.equals(refundRecordMethod.getRefundNumberNo())){
174                 //储值金额 
175                 //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
176                 if(refundRecordMethod.getActualTotal().compareTo(BigDecimal.ZERO)>0){
177                     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);
178                     OrderLog orderLog = RefundToolUtil.setOrderLog(refundRecord, operationId, operationNme, refundRecordMethod.getName()+"退款金额:"+refundRecordMethod.getActualTotal(), 0, OrderLogConstants.LOG_TYPE_REFUND);
179                     commonService.insert(OrderLogMapper.class,orderLog);
180                 }
181             }else if(PayMethodTypeConstants.PAY_ADD_FUND.equals(refundRecordMethod.getRefundNumberNo())){
182                 //增值金
183                 //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
184                 if(refundRecordMethod.getActualTotal().compareTo(BigDecimal.ZERO)!=0){
185                     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);
186                     OrderLog orderLog = RefundToolUtil.setOrderLog(refundRecord,operationId,operationNme,refundRecordMethod.getName(),0, OrderLogConstants.LOG_TYPE_REFUND);
187                     commonService.insert(OrderLogMapper.class,orderLog);
188                 }
189             }else if(PayMethodTypeConstants.PAY_INTEGRAL.equals(refundRecordMethod.getRefundNumberNo())){
190                 //积分
191                 //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
192                 if(refundRecordMethod.getActualTotal().compareTo(BigDecimal.ZERO)!=0){
193                     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);
194                     OrderLog orderLog = RefundToolUtil.setOrderLog(refundRecord,operationId,operationNme,refundRecordMethod.getName()+"退款金额:"+refundRecordMethod.getActualTotal(),0, OrderLogConstants.LOG_TYPE_REFUND);
195                     commonService.insert(OrderLogMapper.class,orderLog);
196                 }
197             }else {
198                 //现金支付
199                 if(refundRecordMethod.getActualTotal().compareTo(BigDecimal.ZERO)<1){
200                     continue;
201                 }
202                 OrderLog orderLog = RefundToolUtil.setOrderLog(refundRecord,operationId,operationNme,refundRecordMethod.getName()+"退款金额:"+refundRecordMethod.getActualTotal(),0, OrderLogConstants.LOG_TYPE_REFUND);
203                 orderLog.setOrderId(ordersTotal.getId());
204                 commonService.insert(OrderLogMapper.class,orderLog);
205
206                 //现金支付需要创建创建退款单进行退款
207                 RefundNote refundNote = new RefundNote(refundRecordMethod.getActualTotal(), refundRecordMethod.getNumberNo(),refundRecordMethod.getName(),ordersTotal.getId(),refundRecord.getUserId());
208                 refundNote.setRefundRecordId(refundRecord.getId());
209                 commonService.insert(RefundNoteMapper.class,refundNote);
210             }
211             //修改实际退款金额
212             map.put("realRefundTotal",refundRecordMethod.getActualTotal());
213             map.put("id",refundRecordMethod.getId());
214             sqlSentence.sqlUpdate(" realRefundTotal=realRefundTotal + #{m.realRefundTotal} where id = #{m.id}",map);
215             if(commonService.updateWhere(RefundRecordMethodMapper.class,sqlSentence) != 1){
216                 throw new TipsException("更新退款方式信息错误[001]");
217             }
218
219             //获取支付方式
220             map.put("orderId",refundRecord.getOrderId());
221             map.put("numberNo",refundRecordMethod.getNumberNo());
222             sqlSentence.sqlSentence("SELECT *,ROUND(actualTotal-refundTotal,2) AS pTotal FROM consume_pay WHERE isDel = 0 AND orderId = #{m.orderId} AND numberNo = #{m.numberNo} ORDER BY pTotal ASC",map);
223             consumePayList = commonService.selectList(ConsumePayMapper.class,sqlSentence);
224             for(ConsumePay consumePay:consumePayList){
225                 if(consumePay.getpTotal().compareTo(BigDecimal.ZERO) < 1){
226                     continue;
227                 }
228                 //计算扣减金额
229                 if(consumePay.getpTotal().compareTo(mothedTotal) > 0){
230                     mothedCutTotal = mothedTotal;
231                 }else{
232                     mothedCutTotal = consumePay.getpTotal();
233                 }
234
235                 //更新支付记录退款信息
236                 map.clear();
237                 map.put("refundTotal",mothedCutTotal);
238                 map.put("id",consumePay.getId());
239                 sqlSentence.sqlUpdate("refundTotal = refundTotal + #{m.refundTotal} WHERE id = #{m.id} AND actualTotal >= refundTotal + #{m.refundTotal}",map);
240                 if(commonService.updateWhere(ConsumePayMapper.class,sqlSentence) != 1){
241                     throw new TipsException("退款金额错误!");
242                 }
243
244                 //生成关联记录
245                 insertRefundRecordConsumePay(mothedCutTotal,null,null,refundRecord.getOrderId(),consumePay.getNumberNo()
246                         ,consumePay.getName(),consumePay.getId(),refundRecord.getId(),refundRecordMethod.getId(),commonService);
247
248                 //计算未分配金额
249                 mothedTotal = mothedTotal.subtract(mothedCutTotal).setScale(2, RoundingMode.HALF_UP);
250                 //已经分配完成,跳出循环
251                 if(mothedTotal.compareTo(BigDecimal.ZERO) < 1){
252                     //跳出循环
253                     break;
254                 }
255             }
256             //判断退款金额是否已经全部分配
257             if(mothedTotal.compareTo(BigDecimal.ZERO) > 0){
258                 throw new TipsException("退款金额错误[426]!");
259             }
260         }
261     }
262
1869f3 263     /**处理一级子退款方式数据
C 264      * @param deductionTotalUser 用户项目被扣减的划扣金额,可空
265      * @param refundRecord 退款记录总表
266      * @param refundRecordItem 退款记录子表
267      * @param refundCarryVo 总携带参数结构
268      * @param commonService 映射
269      * @return 总携带参数结构
270      */
271     public static RefundCarryVo refundRecordMotnedItemHandle(BigDecimal deductionTotalUser,RefundRecord refundRecord,RefundRecordItem refundRecordItem
272             ,RefundCarryVo refundCarryVo,CommonService commonService){
273
274         //装载支付方式退款信息
275         refundCarryVo.setRefundConsumePayList(new ArrayList<>());
276         //没有退款方式,跳过当前处理
277         if(refundCarryVo.getRefundRecordMethodList().size() == 0){
278             return refundCarryVo;
279         }
ae6ff7 280
C 281         SqlSentence sqlSentence = new SqlSentence();
282         Map<String,Object> values = new HashMap<>();
283
1869f3 284         //支付方式占比
C 285         BigDecimal payMothedPercentage;
286         //计算退款方式的占比
287         if(refundRecord.getRefundTotal().compareTo(BigDecimal.ZERO) > 0){
288             payMothedPercentage = refundRecordItem.getRefundMoney().divide(refundRecord.getRefundTotal(),15,RoundingMode.HALF_UP);
289         }else{
290             payMothedPercentage = BigDecimal.ZERO;
ae6ff7 291         }
C 292
1869f3 293         //处理退款方式
C 294         refundCarryVo = insertRefundItemMothed(refundRecordItem.getId(),refundRecordItem.getRefundMoney(),payMothedPercentage,OrderSourceConstans.TYPE_PROJECT
295                 ,refundRecordItem.getOrderItemId(),refundCarryVo,refundRecord,commonService);
ae6ff7 296
1869f3 297         //更新现金和划扣金额保存
C 298         values.put("deductionTotal",refundCarryVo.getDeductionTotal());
299         values.put("deductionTotalUser",deductionTotalUser==null?BigDecimal.ZERO:deductionTotalUser);
300         values.put("cashTotal",refundCarryVo.getCashTotal());
301         values.put("id",refundRecordItem.getId());
302         sqlSentence.sqlUpdate("deductionTotal = #{m.deductionTotal},deductionTotalUser = #{m.deductionTotalUser},cashTotal = #{m.cashTotal} WHERE id = #{m.id}",values);
303         if(commonService.updateWhere(RefundRecordItemMapper.class,sqlSentence) != 1){
304             throw new TipsException("更新退款子项信息失败!");
305         }
306
307         return refundCarryVo;
308     }
309
310     /**处理二级子退款方式数据
311      * @param deductionTotalUser 用户项目被扣减的划扣金额
312      * @param refundRecord  退款记录总表
313      * @param refundRecordItemSource 退款记录子表
314      * @param refundCarryVo 总携带参数结构
315      * @param commonService 映射
316      * @return 总携带参数结构
317      */
318     public static RefundCarryVo refundRecordMotnedItemTwoHandle(BigDecimal deductionTotalUser,RefundRecord refundRecord,RefundRecordItemSource refundRecordItemSource
319             ,RefundCarryVo refundCarryVo,CommonService commonService){
320
321         //装载支付方式退款信息
322         refundCarryVo.setRefundConsumePayList(new ArrayList<>());
323         //没有退款方式,跳过当前处理
324         if(refundCarryVo.getRefundRecordMethodList().size() == 0){
325             return refundCarryVo;
326         }
327
328         SqlSentence sqlSentence = new SqlSentence();
329         Map<String,Object> values = new HashMap<>();
330
331         //支付方式占比
332         BigDecimal payMothedPercentage;
333         //计算退款方式的占比
334         if(refundRecord.getRefundTotal().compareTo(BigDecimal.ZERO) > 0){
335             payMothedPercentage = refundRecordItemSource.getRefundMoney().divide(refundRecord.getRefundTotal(),15,RoundingMode.HALF_UP);
336         }else{
337             payMothedPercentage = BigDecimal.ZERO;
338         }
339
340         //处理退款方式
341         refundCarryVo = insertRefundItemMothed(refundRecordItemSource.getId(),refundRecordItemSource.getRefundMoney(),payMothedPercentage,OrderSourceConstans.TYPE_RETAIL
342                 ,refundRecordItemSource.getOrderItemSonId(),refundCarryVo,refundRecord,commonService);
343
344         values.put("deductionTotal",refundCarryVo.getDeductionTotal());
345         values.put("deductionTotalUser",deductionTotalUser==null?BigDecimal.ZERO:deductionTotalUser);
346         values.put("cashTotal",refundCarryVo.getCashTotal());
347         values.put("id",refundRecordItemSource.getId());
348         sqlSentence.sqlUpdate("deductionTotal = #{m.deductionTotal},deductionTotalUser = #{m.deductionTotalUser},cashTotal = #{m.cashTotal} WHERE id = #{m.id}",values);
349         if(commonService.updateWhere(RefundRecordItemSourceMapper.class,sqlSentence) != 1){
350             throw new TipsException("更新退款子项信息失败[94]!");
351         }
352
353         return refundCarryVo;
354     }
355
356     /**退款子单退款方式处理保存
357      * @param refundItemId 退款子单标识
358      * @param refundItemTotal 退款子单实际需要退款总金额
359      * @param payMothedPercentage 支付方式占比
360      * @param orderItemType 订单子单级别
361      * @param orderItemId 订单子单标识
362      * @param refundCarryVo 总结构对象
363      * @param refundRecord 退款总记录
364      * @param commonService 映射
365      * @return 总结构对象
366      */
367     public static RefundCarryVo insertRefundItemMothed(String refundItemId,BigDecimal refundItemTotal,BigDecimal payMothedPercentage,String orderItemType
368             ,String orderItemId,RefundCarryVo refundCarryVo,RefundRecord refundRecord,CommonService commonService){
369
370         //总退款方式金额数据
371         List<RefundRecordMethod> refundRecordMethodList = refundCarryVo.getRefundRecordMethodList();
372         //进行升序排序,避免后面不够分配
373         refundRecordMethodList = refundRecordMethodList.stream().sorted(Comparator.comparing(RefundRecordMethod::getpTotal)).collect(Collectors.toList());
374
375         //获取子单的支付方式,子单支付记录,计算可退款金额
376         List<ConsumePayItem> consumePayItemList;
377         if(OrderSourceConstans.TYPE_PROJECT.equals(orderItemType)){
378             consumePayItemList = getOrderItemOneConsumePay(orderItemId,commonService);
379         }else{
380             consumePayItemList = getOrderItemTwoConsumePay(orderItemId,commonService);
381         }
382
383         ////存储支付方式编号的可退款金额,根据支付编号求和,后面的判断会用到,key值:支付编号,value:可退金额
384         Map<String,BigDecimal> noMap = new HashMap<>();
385         BigDecimal surplusTotal;
386         ////存储支付方式编号的支付方式记录,根据支付编号整合,后面的判断会用到,key值:支付编号,value:支付记录集合
387         Map<String,List<ConsumePayItem>> noPayItemMap = new HashMap<>();
388         List<ConsumePayItem> noPayItemList;
389
390         ////////填充支付方式记录的退款金额,计算剩余可退金额,支付方式记录的退款金额需要去查询计算获取
ae6ff7 391         //获取已经退款的退款方式金额,根据支付方式记录的标识求和返回
1869f3 392         List<RefundRecordConsumePay> refundRecordConsumePayList = getRefundRecordConsumePay(orderItemId,null,false,true,commonService);
C 393         //转化成map,可以根据支付方式记录的标识直接获取到数据
ae6ff7 394         Map<String, RefundRecordConsumePay> refundRecordConsumePayMap = refundRecordConsumePayList.stream().collect(
C 395                 Collectors.toMap(RefundRecordConsumePay::getConsumePayId,(a) -> a));
396         RefundRecordConsumePay refundRecordConsumePay;
397         for(ConsumePayItem consumePayItem:consumePayItemList){
398             refundRecordConsumePay = refundRecordConsumePayMap.get(consumePayItem.getConsumePayId());
399             if(refundRecordConsumePay != null){
400                 //已退款金额
401                 consumePayItem.setRefundTotal(refundRecordConsumePay.getRefundTotal());
402                 //可退款金额
403                 consumePayItem.setpTotal(consumePayItem.getpTotal().subtract(refundRecordConsumePay.getRefundTotal()).setScale(2,RoundingMode.HALF_UP));
404             }
1869f3 405             //计算每个支付编码可退款金额
C 406             surplusTotal = noMap.computeIfAbsent(consumePayItem.getNumberNo(),k->BigDecimal.ZERO);
407             surplusTotal = surplusTotal.add(consumePayItem.getpTotal()).setScale(2,RoundingMode.HALF_UP);
408             noMap.put(consumePayItem.getNumberNo(),surplusTotal);
ae6ff7 409
1869f3 410         }
ae6ff7 411         //进行升序排序,避免后面不够分配
1869f3 412         consumePayItemList = consumePayItemList.stream().sorted(Comparator.comparing(ConsumePayItem::getpTotal)).collect(Collectors.toList());
C 413         for(ConsumePayItem consumePayItem:consumePayItemList){
414             //支付编码集合整合
415             noPayItemList = noPayItemMap.computeIfAbsent(consumePayItem.getNumberNo(),k->new ArrayList<>());
416             noPayItemList.add(consumePayItem);
417         }
ae6ff7 418
1869f3 419         List<RefundRecordConsumePay> refundConsumePayList = new ArrayList<>();
C 420
421         ////引用对象
ae6ff7 422         RefundRecordItemMethod refundRecordItemMethod;
1869f3 423         RefundRecordMethod refundRecordMethod;
C 424         //需要退的退款编号金额
425         BigDecimal mothedTotal;
426         //支付编号分配的退款金额
427         BigDecimal mothedCutTotal;
428         //分配的划扣金额总和
429         BigDecimal deductionTotal = BigDecimal.ZERO;
430         //分配的现金金额总和
431         BigDecimal cashTotal = BigDecimal.ZERO;
ae6ff7 432
1869f3 433         ////退款方式金额分配
C 434         for(int i = 0;i <refundRecordMethodList.size();i++){
435             refundRecordMethod = refundRecordMethodList.get(i);
436
437             ////子项退款方式填充
438             refundRecordItemMethod = new RefundRecordItemMethod();
439             refundRecordItemMethod.setNumberNo(refundRecordMethod.getNumberNo());
440             refundRecordItemMethod.setName(refundRecordMethod.getName());
441             //支付方式
442             refundRecordItemMethod.setPaymentMethodId(refundRecordMethod.getPaymentMethodId());
443             refundRecordItemMethod.setIsMoneyPay(refundRecordMethod.getIsMoneyPay());
444             refundRecordItemMethod.setIsExecute(refundRecordMethod.getIsExecute());
445             refundRecordItemMethod.setIsPay(refundRecordMethod.getIsPay());
446             //退款方式
447             refundRecordItemMethod.setRefundNumberNo(refundRecordMethod.getRefundNumberNo());
448             refundRecordItemMethod.setRefundName(refundRecordMethod.getRefundName());
449             refundRecordItemMethod.setRefundMethodId(refundRecordMethod.getRefundMethodId());
450
451             //计算退款方式的金额
452             if(i == refundRecordMethodList.size()-1){
453                 ////最后一个
454                 refundRecordItemMethod.setActualTotal(refundItemTotal);
455             }else {
456                 ////不是最后一个
457                 refundRecordItemMethod.setActualTotal(refundRecordMethod.getActualTotal().multiply(payMothedPercentage).setScale(2,RoundingMode.UP));
ae6ff7 458             }
1869f3 459             //判断与剩余的未分配退款方式金额
C 460             if (refundRecordItemMethod.getActualTotal().compareTo(refundRecordMethod.getpTotal()) > 0){
461                 refundRecordItemMethod.setActualTotal(refundRecordMethod.getpTotal());
462             }
463             //判断与剩下的未分配金额校验
464             if(refundRecordItemMethod.getActualTotal().compareTo(refundItemTotal) > 0){
465                 refundRecordItemMethod.setActualTotal(refundItemTotal);
466             }
467             //可支付方式可退款金额
468             surplusTotal = noMap.computeIfAbsent(refundRecordItemMethod.getNumberNo(),k-> BigDecimal.ZERO);
469             if(refundRecordItemMethod.getActualTotal().compareTo(surplusTotal) > 0){
470                 refundRecordItemMethod.setActualTotal(surplusTotal);
471             }
ae6ff7 472
1869f3 473             refundRecordItemMethod.setCommonType(orderItemType);
C 474             refundRecordItemMethod.setCommonId(orderItemId);
475             refundRecordItemMethod.setOrderId(refundRecordMethod.getOrderId());
476             refundRecordItemMethod.setRefundRecordItemId(refundItemId);
477             refundRecordItemMethod.setRefundRecordId(refundRecord.getId());
478             commonService.insert(RefundRecordItemMethodMapper.class,refundRecordItemMethod);
ae6ff7 479
1869f3 480             //减去已经分配的退款方式金额
C 481             refundRecordMethod.setpTotal(refundRecordMethod.getpTotal().subtract(refundRecordItemMethod.getActualTotal()).setScale(2,RoundingMode.HALF_UP));
482             //减去已经分配的退款金额
483             refundItemTotal = refundItemTotal.subtract(refundRecordItemMethod.getActualTotal()).setScale(2,RoundingMode.HALF_UP);
484             //减去已经分配的可退款金额
485             surplusTotal = surplusTotal.subtract(refundRecordItemMethod.getActualTotal()).setScale(2,RoundingMode.HALF_UP);
486             noMap.put(refundRecordItemMethod.getNumberNo(),surplusTotal);
ae6ff7 487
1869f3 488             ///////生成关联支付方式记录和退款方式关联
C 489             noPayItemList = noPayItemMap.computeIfAbsent(refundRecordItemMethod.getNumberNo(),k->new ArrayList<>());
ae6ff7 490             mothedTotal = refundRecordItemMethod.getActualTotal();
1869f3 491             for(ConsumePayItem consumePayItem:noPayItemList){
ae6ff7 492                 if(consumePayItem.getpTotal().compareTo(BigDecimal.ZERO) < 1){
C 493                     continue;
494                 }
495                 //计算扣减金额
496                 if(consumePayItem.getpTotal().compareTo(mothedTotal) > 0){
497                     mothedCutTotal = mothedTotal;
498                 }else{
499                     mothedCutTotal = consumePayItem.getpTotal();
500                 }
501
502                 //划扣金额
503                 if(consumePayItem.getIsMoneyPay().equals(ConsumePayItem.YES)){
504                     deductionTotal = deductionTotal.add(mothedCutTotal).setScale(2,RoundingMode.HALF_UP);
505                 }
1869f3 506                 //现金金额
ae6ff7 507                 if(consumePayItem.getIsExecute().equals(ConsumePayItem.YES)){
C 508                     cashTotal = cashTotal.add(mothedCutTotal).setScale(2,RoundingMode.HALF_UP);
509                 }
510
511                 //生成关联记录
512                 refundRecordConsumePay = insertRefundRecordConsumePay(mothedCutTotal,refundRecordItemMethod.getCommonType(),refundRecordItemMethod.getCommonId(),refundRecord.getOrderId(),consumePayItem.getNumberNo()
1869f3 513                         ,consumePayItem.getName(),consumePayItem.getConsumePayId(),refundRecordItemMethod.getId(),refundItemId,refundRecord.getId(),commonService);
C 514                 refundConsumePayList.add(refundRecordConsumePay);
ae6ff7 515
1869f3 516                 //支付方式记录减掉已经分配退款方式金额
C 517                 consumePayItem.setpTotal(consumePayItem.getpTotal().subtract(mothedCutTotal).setScale(2,RoundingMode.HALF_UP));
518                 //减掉已经分配退款方式金额
ae6ff7 519                 mothedTotal = mothedTotal.subtract(mothedCutTotal).setScale(2, RoundingMode.HALF_UP);
1869f3 520                 //分配完成,跳出循环
ae6ff7 521                 if(mothedTotal.compareTo(BigDecimal.ZERO) < 1){
C 522                     //跳出循环
523                     break;
524                 }
525             }
526         }
1869f3 527         //判断是否已经分配完
C 528         if(refundItemTotal.compareTo(BigDecimal.ZERO) > 0){
529             throw new TipsException("分配退款金额错误["+orderItemType+"]");
ae6ff7 530         }
1869f3 531
C 532         refundCarryVo.setDeductionTotal(deductionTotal);
533         refundCarryVo.setCashTotal(cashTotal);
534         refundCarryVo.setRefundConsumePayList(refundConsumePayList);
535
536         return refundCarryVo;
ae6ff7 537     }
C 538
539
540     /**
541      * 退款-处理优惠券
542      * @param refundRecord 退款总数据
543      * @param commonService 映射
544      */
545     public static void handCoupon(RefundRecord refundRecord,CommonService commonService) {
546         SqlSentence sqlSentence = new SqlSentence();
547         Map<String, Object> map = new HashMap<>();
548
549         //回去回退优惠券
550         map.put("refundRecordId",refundRecord.getId());
551         sqlSentence.setSqlSentence("select * from refund_record_coupon where refundRecordId=#{m.refundRecordId} and isDel=0 ");
552         List<RefundRecordCoupon> refundRecordCouponList=commonService.selectList(RefundRecordCouponMapper.class,sqlSentence);
553
554         //退款成功
555         CouponOrderDiscountLog couponOrderDiscountLog=null;
556         for (RefundRecordCoupon refundRecordCoupon : refundRecordCouponList) {
557
558             //变更订单优惠券记录状态
559             map.clear();
560             map.put("status", BaseEntity.YES);
561             map.put("id", refundRecordCoupon.getCouponOrderId());
562             sqlSentence.setSqlSentence("status=#{m.status} WHERE id = #{m.id}  ");
563             if(commonService.updateWhere(CouponOrderDiscountLogMapper.class,sqlSentence) != 1){
564                 throw new TipsException("优惠券回退失败!");
565             }
566
567             //领建优惠券跳过回退
568             if(HIS_COUPON_CODE.equals(couponOrderDiscountLog.getCouponNumberId())){
569                 continue;
570             }
571
572             //优惠券状态变化
573             map.put("isUse", BaseEntity.NO);
574             map.put("useTime", null);
575             map.put("useType", CouponNumber.USE_TYPE_UNKNOW);
576             map.put("id", couponOrderDiscountLog.getCouponNumberId());
577             sqlSentence.setSqlSentence("  isUse=#{m.isUse},useTime=#{m.useTime},useType=#{m.useType},isUse=#{m.isUse} WHERE id = #{m.id}  ");
578             if(commonService.updateWhere(CouponNumberMapper.class,sqlSentence) != 1){
579                 throw new TipsException("优惠券回退失败[67]!");
580             }
581         }
582     }
583
584     /**
585      * 退款-处理活动规则增值金和积分
586      * @param commonService
587      * @param operationId
588      * @param operationNme
589      * @param sqlSentence
590      * @param map
591      * @param refundRecord
592      * @param ordersTotal
593      */
594     private static void handActivityRule(CommonService commonService, String operationId, String operationNme, SqlSentence sqlSentence,
595                                          Map<String, Object> map, RefundRecord refundRecord, OrdersTotal ordersTotal, OrderInfo orderInfo) {
596         if(orderInfo!=null && StringUtils.noNull(orderInfo.getActivityId())){
597             ActivityRule activityRule=commonService.selectOneByKeyBlob(ActivityRuleMapper.class,orderInfo.getActivityId());
598             if(activityRule!=null){
599                 map.put("activityRuleId",activityRule.getId());
600                 map.put("type", ActivityAction.TYPE_INTEGRAL);
601                 map.put("type1",ActivityAction.TYPE_VALUEADDEDFUND);
602                 map.put("type2",ActivityAction.TYPE_COUPON);
603                 sqlSentence.setSqlSentence("select * from activity_action where activityRuleId=#{m.activityRuleId} and (type=#{m.type} or type=#{m.type1} or type=#{m.type2}) and isDel=0");
604                 List<ActivityAction> activityActions = commonService.selectList(ActivityActionMapper.class, sqlSentence);
605                 if(activityActions!=null && activityActions.size()>0){
606                     for (ActivityAction activityAction : activityActions) {
607                         if(ActivityAction.TYPE_INTEGRAL.equals(activityAction.getType())){
608                             //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
609                             if(new BigDecimal(activityAction.getWorth()).negate().compareTo(BigDecimal.ZERO)!=0){
610                                 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);
611                             }
612                         }else if(ActivityAction.TYPE_VALUEADDEDFUND.equals(activityAction.getType())){
613                             //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
614                             if(new BigDecimal(activityAction.getWorth()).negate().compareTo(BigDecimal.ZERO)!=0){
615                                 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);
616                             }
617                         }else if(ActivityAction.TYPE_COUPON.equals(activityAction.getType())){
618                             map.put("oldValidState",BaseEntity.YES);
619                             map.put("newValidState",BaseEntity.NO);
620                             map.put("couponId",activityAction.getCrmCouponId());
621                             map.put("commonId",ordersTotal.getId());
622                             sqlSentence.setSqlSentence(" validState=#{m.newValidState} where couponId=#{m.couponId} and commonId=#{m.commonId} and validState=#{m.oldValidState} ");
623                             commonService.updateWhere(CouponNumberMapper.class,sqlSentence);
624                         }
625                     }
626                 }
627             }
628         }
629
630     }
631     /**
632      * 退款-处理普通订单信息(比如:项目、促销、卡项)
633      * @param operationId     操作人标识
634      * @param operationNme    操作人名
635      * @param refundRecord
636      * @param commonService
637      */
1869f3 638     public static RefundCarryVo numberOfRefunds(RefundCarryVo refundCarryVo,String operationId, String operationNme, RefundRecord refundRecord,OrdersTotal ordersTotal,CustomParameter customParameter,CommonService commonService) {
ae6ff7 639
C 640         SqlSentence sqlSentence = new SqlSentence();
641         Map<String, Object> map = new HashMap<>();
642
643         //获取退款子单
644         map.clear();
645         map.put("refundRecordId",refundRecord.getId());
646         sqlSentence.setSqlSentence("SELECT * FROM refund_record_item WHERE isDel = 0 AND refundRecordId = #{m.refundRecordId}");
647         List<RefundRecordItem> refundRecordItems =commonService.selectList(RefundRecordItemMapper.class,sqlSentence);
648         if(refundRecordItems==null && refundRecordItems.size()==0){
649             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到退款子订单信息");
650         }
651
1869f3 652         //根据支付记录总表的标识来整合已退的金额,key值:支付记录总表标识,value:金额数据
C 653         Map<String,RefundRecordConsumePay> refundRecordConsumePayMap = new HashMap<>();
654         RefundRecordConsumePay refundRecordConsumePay;
ae6ff7 655
C 656         for (RefundRecordItem refundRecordItem: refundRecordItems) {
1869f3 657             //初始化总结构携带参数
C 658             refundCarryVo.setRefundConsumePayList(new ArrayList<>());
659             refundCarryVo.setDeductionTotal(BigDecimal.ZERO);
660             refundCarryVo.setCashTotal(BigDecimal.ZERO);
661
ae6ff7 662             switch (refundRecordItem.getType()){
C 663                 case OrderItemConstants.TYPE_RETAIL:
1869f3 664                     refundCarryVo = handRefundRerail(refundRecord,refundRecordItem,refundCarryVo,commonService);
ae6ff7 665                     break;
C 666                 case OrderItemConstants.TYPE_DRUG:
1869f3 667                     refundCarryVo = handRefundRerail(refundRecord,refundRecordItem,refundCarryVo,commonService);
ae6ff7 668                     break;
C 669                 case OrderItemConstants.TYPE_PROJECT:
1869f3 670                     refundCarryVo = handRefundNoExecution(refundRecord,refundRecordItem,refundCarryVo,commonService);
ae6ff7 671                     break;
C 672                 case OrderItemConstants.TYPE_PROMOTION:
1869f3 673                     refundCarryVo = handRefundPromotion(operationId, refundRecord, ordersTotal,refundRecordItem,refundCarryVo,commonService);
ae6ff7 674                     break;
C 675                 case OrderItemConstants.TYPE_CARD:
1869f3 676                     refundCarryVo = handRefundCard(refundRecord,refundRecordItem,refundCarryVo,commonService);
ae6ff7 677                     break;
C 678                 case OrderItemConstants.CARD_BAG:
1869f3 679                     refundCarryVo = handRefundPromotion(operationId, refundRecord, ordersTotal,refundRecordItem,refundCarryVo,commonService);
C 680                     //refundCarryVo = handCardBag(commonService, operationId, operationNme, sqlSentence, map, refundRecord,ordersTotal,refundRecordItem,customParameter);
ae6ff7 681                     break;
C 682                 default:break;
683             }
1869f3 684
C 685             //遍历叠加支付方式记录的退款金额
686             for(RefundRecordConsumePay re:refundCarryVo.getRefundConsumePayList()){
687                 refundRecordConsumePay = refundRecordConsumePayMap.computeIfAbsent(re.getConsumePayId(),k->new RefundRecordConsumePay(BigDecimal.ZERO,re.getNumberNo(),re.getConsumePayId()));
688                 refundRecordConsumePay.setRefundTotal(refundRecordConsumePay.getRefundTotal().add(re.getRefundTotal()));
689             }
ae6ff7 690         }
1869f3 691
C 692         //转载返回支付方式记录的退款金额
693         List<RefundRecordConsumePay> refundRecordConsumePayList = new ArrayList<>();
694         for (Map.Entry<String, RefundRecordConsumePay> entry : refundRecordConsumePayMap.entrySet()) {
695             refundRecordConsumePayList.add(entry.getValue());
696         }
697
698         refundCarryVo.setRefundConsumePayList(refundRecordConsumePayList);
699         return refundCarryVo;
ae6ff7 700     }
C 701
702     /**
703      * 退款一级是商品
704      * @param refundRecord 退款总信息
705      * @param refundRecordItem 退款子单
706      * @param commonService 映射
707      */
1869f3 708     private static RefundCarryVo handRefundRerail(RefundRecord refundRecord, RefundRecordItem refundRecordItem
C 709             , RefundCarryVo refundCarryVo, CommonService commonService) {
ae6ff7 710
C 711         //判断操作完了去修改子订单状态
712         OrderItem orderItem=commonService.selectOneByKey(OrderItemMapper.class,refundRecordItem.getOrderItemId());
713         if (orderItem==null){
714             throw new PlatTipsException(PlatformCode.ERROR_PARAMETER_NULL,"未找到子订单信息");
715         }
716         //剩余可退款数量
717         Integer surplusNum = orderItem.getBuyNum()-orderItem.getHasReNum();
718         if(refundRecordItem.getRefundNum() > surplusNum){
719             throw new TipsException("退款数量不能大于可退款数量!");
720         }
721
722         //变更退款子项信息
1869f3 723         Integer refundStatus;
ae6ff7 724         if (surplusNum.equals(refundRecordItem.getRefundNum())){
1869f3 725             refundStatus = OrderTotalConstants.STATUS_REFUND_FINSH;
ae6ff7 726         }else{
1869f3 727             refundStatus = OrderTotalConstants.STATUS_REFUND_PART;
ae6ff7 728         }
C 729
1869f3 730         //更新子订单信息
C 731         updateOrderItemOne(orderItem,refundStatus,refundRecordItem.getRefundMoney(),refundRecordItem.getRefundNum(),commonService);
732
ae6ff7 733         //退款方式处理
1869f3 734         return refundRecordMotnedItemHandle(null,refundRecord,refundRecordItem,refundCarryVo,commonService);
ae6ff7 735     }
C 736
737     /**
738      * 退款-处理未执行划扣   项目类型
739      * @param refundRecord
740      * @param refundRecordItem
741      */
1869f3 742     private static RefundCarryVo handRefundNoExecution(RefundRecord refundRecord, RefundRecordItem refundRecordItem
C 743             ,RefundCarryVo refundCarryVo,CommonService commonService) {
ae6ff7 744         SqlSentence sqlSentence = new SqlSentence();
C 745         Map<String, Object> map = new HashMap<>();
746
747         //找到子单
748         OrderItem orderItem=commonService.selectOneByKey(OrderItemMapper.class,refundRecordItem.getOrderItemId());
749         if (orderItem==null){
750             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到子订单信息");
751         }
752         //找到用户项目
753         map.clear();
754         map.put("commonId",refundRecordItem.getOrderItemId());
755         sqlSentence.sqlSentence("select * from user_project_item where isDel = 0 and commonId = #{m.commonId} and isTransfer = 0",map);
756         UserProjectItem userProjectItem =commonService.selectOne(UserProjectItemMapper.class,sqlSentence);
757         if (userProjectItem == null) {
758             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到用户子项项目信息");
759         }
760
761         if(userProjectItem.getNotUsedNum() < refundRecordItem.getRefundNum()){
762             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款次数大于可退次数!");
763         }
764
765         //用户项目操作
1869f3 766         UserProjectDeductionVo  userProjectDeductionVo = UserProjectTool.userProjectDeduction(userProjectItem,UserProjectUsedCon.USED_METHOD_ORDER_REFUND,UserProjectUsedCon.USED_TYPE_DEDUCTION,null
ae6ff7 767                 ,refundRecordItem.getId(),refundRecordItem.getRefundNum(),refundRecord.getOperatorAppId(),refundRecord.getOperatorAppName(),refundRecord.getRefundShopId(),refundRecord.getRefundShopName(),"员工备注:"+refundRecord.getRemarks()+"|用户备注:"+refundRecord.getRefundReason(),commonService);
C 768
769         //计算子单是否还有剩余的可扣疗程数
770         int surplusNum = orderItem.getUsedTotal()-orderItem.getHasReNum();
771         if(refundRecordItem.getRefundNum() > surplusNum){
772             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款次数大于子单可退次数[54]!");
773         }
774
775         Integer refundStatus;
776         if(refundRecordItem.getRefundNum() == surplusNum){
777             refundStatus=OrderTotalConstants.STATUS_REFUND_FINSH;
778         }else{
779             refundStatus=OrderTotalConstants.STATUS_REFUND_PART;
780         }
781
1869f3 782         //更新子订单信息
C 783         updateOrderItemOne(orderItem,refundStatus,refundRecordItem.getRefundMoney(),refundRecordItem.getRefundNum(),commonService);
ae6ff7 784
C 785         //退款方式处理
1869f3 786         return refundRecordMotnedItemHandle(userProjectDeductionVo.getDeductionTotal(),refundRecord,refundRecordItem,refundCarryVo,commonService);
ae6ff7 787     }
C 788
789     /**
790      * 退款-处理卡项
791      * @param commonService
792      * @param refundRecord
793      * @param refundRecordItem
794      */
1869f3 795     public static RefundCarryVo handRefundCard(RefundRecord refundRecord, RefundRecordItem refundRecordItem,RefundCarryVo refundCarryVo,CommonService commonService) {
ae6ff7 796
C 797         SqlSentence sqlSentence = new SqlSentence();
798         Map<String, Object> map = new HashMap<>();
799
800         //判断操作完了去修改子订单状态
801         OrderItem orderItem=commonService.selectOneByKey(OrderItemMapper.class,refundRecordItem.getOrderItemId());
802         if (orderItem==null){
1869f3 803             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到子订单信息");
ae6ff7 804         }
C 805         Integer surplusNum = orderItem.getBuyNum() - orderItem.getHasReNum();
806         if(refundRecordItem.getRefundNum() > surplusNum){
807             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款作废卡包提示:没有找到对应的卡包可退[020]");
808         }
809
810         //找到可退款卡包
811         List<UserCard> userCardList = PartialRefundUtil.getRefundCard(orderItem.getId(),commonService);
812         if(refundRecordItem.getRefundNum() > userCardList.size()){
813             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款作废卡包提示:没有找到对应的卡包可退[021]");
814         }
815
1869f3 816         //变更卡项状态
ae6ff7 817         UserCard userCard;
1869f3 818         RefundRecordCard refundRecordCard;
ae6ff7 819         for (int i = 0; i < refundRecordItem.getRefundNum(); i++) {
C 820             userCard= userCardList.get(i);
821             map.put("id",userCard.getId());
822             map.put("effectiveStatus", UserProjectConstants.EFF_STATUS_CANCEL);
1869f3 823             sqlSentence.setSqlSentence(" effectiveStatus=#{m.effectiveStatus} where id = #{m.id} ");
ae6ff7 824             commonService.updateWhere(UserCardMapper.class,sqlSentence);
1869f3 825
C 826             //生成退款关联
827             refundRecordCard = new RefundRecordCard();
828             refundRecordCard.setUserCardId(userCard.getId());
829             refundRecordCard.setRefundRecordId(refundRecord.getId());
830             refundRecordCard.setRefundRecordItemId(refundRecordItem.getId());
831
832             退款卡包关联保存
ae6ff7 833         }
C 834
1869f3 835         Integer refundStatus;
ae6ff7 836         if (surplusNum.equals(refundRecordItem.getRefundNum())){
1869f3 837             refundStatus =  OrderTotalConstants.STATUS_REFUND_FINSH;
ae6ff7 838         }else {
1869f3 839             refundStatus =  OrderTotalConstants.STATUS_REFUND_PART;
C 840
ae6ff7 841         }
1869f3 842         //更新子订单信息
C 843         updateOrderItemOne(orderItem,refundStatus,refundRecordItem.getRefundMoney(),refundRecordItem.getRefundNum(),commonService);
ae6ff7 844
C 845         //退款方式处理
1869f3 846         refundCarryVo = refundRecordMotnedItemHandle(null,refundRecord,refundRecordItem,refundCarryVo,commonService);
C 847         return refundCarryVo;
ae6ff7 848     }
C 849
850     /**
851      * 退款-处理卡包
852      * @param commonService
853      * @param operationId
854      * @param refundRecord
855      * @param ordersTotal
856      * @param refundRecordItem
857      */
1869f3 858     public static void handCardBag(String operationId,RefundRecord refundRecord, OrdersTotal ordersTotal
C 859             ,RefundRecordItem refundRecordItem,RefundCarryVo refundCarryVo,CommonService commonService) {
ae6ff7 860
C 861         SqlSentence sqlSentence = new SqlSentence();
862         Map<String, Object> map = new HashMap<>();
863
864         //查看订单信息
865         OrderItem orderItem=commonService.selectOneByKey(OrderItemMapper.class,refundRecordItem.getOrderItemId());
866         if(orderItem==null ){
867             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到子订单信息!");
868         }
869         map.put("refundRecordItemId",refundRecordItem.getId());
870         sqlSentence.setSqlSentence("select * from refund_record_item_source where refundRecordItemId =#{m.refundRecordItemId}");
871         List<RefundRecordItemSource> sons = commonService.selectList(RefundRecordItemSourceMapper.class, sqlSentence);
872         if(sons.size() == 0 ){
873             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到子订单信息[015]!");
874         }
875
876         for (RefundRecordItemSource son : sons) {
1869f3 877             refundCarryVo.setRefundConsumePayList(new ArrayList<>());
C 878             refundCarryVo.setDeductionTotal(BigDecimal.ZERO);
879             refundCarryVo.setCashTotal(BigDecimal.ZERO);
ae6ff7 880             switch (GroupTypeEnum.getCode(son.getType())){
C 881                 case PROJECT:
1869f3 882                     //handRefundNoSonExecution(refundRecord,son,refundCarryVo,commonService);
ae6ff7 883                     break;
C 884                 case RETAIL:
1869f3 885                     //handRefundSonRerail(refundRecord,son,refundCarryVo,commonService );
C 886                     //deleteUserCardUsed(sqlSentence,map,ordersTotal,commonService,son,orderItem);
ae6ff7 887                     break;
C 888                 case INCREMENT:
889                     //增值金
890                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
891                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
892                         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);
893                     }
894                     break;
895                 case STORED:
896                     //储值金额
897                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
898                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
899                         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);
900                     }
901                     break;
902                 case INTEGRAL:
903                     //积分
904                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
905                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
906                         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);
907                     }
908                     break;
909             }
910         }
911
912         //更改二级子订单退款状态
913
914         map.put("orderItemId",orderItem.getId());
915         sqlSentence.setSqlSentence("select * from order_item_source WHERE  orderItemId=#{m.orderItemId} and isDel=0");
916         List<OrderItemSon> orderItemSonList=commonService.selectList(OrderItemSonMapper.class,sqlSentence);
917
918         List<Integer> collect = orderItemSonList.stream().map(o -> o.getRefundStatus()).collect(Collectors.toList());
919         if(collect.contains(OrderTotalConstants.STATUS_REFUND_PART)){
920             orderItem.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
921             orderItem.setReTotal(orderItemSonList.stream().map(OrderItemSon::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
922         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE) && collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
923             orderItem.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
924             orderItem.setReTotal(orderItemSonList.stream().map(OrderItemSon::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
925         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE)){
926             orderItem.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
927         }else  if (collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
928             orderItem.setRefundStatus(OrderTotalConstants.STATUS_REFUND_FINSH);
929             orderItem.setReTotal(orderItemSonList.stream().map(OrderItemSon::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
930             orderItem.setHasReNum(orderItem.getBuyNum());
931         }else {
932             orderItem.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
933         }
934
935         commonService.updateAll(OrderItemMapper.class,orderItem);
936     }
937
938     /**
939      * 退款需要删除用户卡包使用记录
940      * @param commonService
941      */
1869f3 942     public static void deleteUserCardUsed(String cardItemInfoId,String sourceId,Integer hasReNum,CommonService commonService){
ae6ff7 943
C 944         SqlSentence sqlSentence = new SqlSentence();
1869f3 945         Map<String,Object> map = new HashMap<>();
ae6ff7 946
1869f3 947         //获取使用记录
C 948         map.put("cardItemInfoId",cardItemInfoId);
949         map.put("sourceId",sourceId);
950         sqlSentence.setSqlSentence(" SELECT * FROM user_card_used WHERE isDel = 0" +
951                 " AND cardItemInfoId = #{m.cardItemInfoId} AND sourceId = #{m.sourceId}");
952         List<UserCardUsed> userCardUsedList = commonService.selectList(UserCardUsedMapper.class,sqlSentence);
953
954         if(hasReNum > userCardUsedList.size()){
955             throw new TipsException("卡包可退数量错误!");
956         }
957
958         int opNum = 0;
959         sqlSentence.sqlUpdate("isDel = 1 WHERE id = #{m.id} AND isDel = 0",map);
960         for(UserCardUsed userCardUsed:userCardUsedList){
961             map.put("id",userCardUsed.getId());
962             opNum = opNum+commonService.updateWhere(UserCardUsedMapper.class,sqlSentence);
963         }
964         if(opNum != hasReNum){
965             throw new TipsException("卡包回退错误!");
966         }
967
ae6ff7 968     }
1869f3 969
ae6ff7 970     /**
C 971      * 退款-处理促销
972      * @param commonService
973      * @param operationId
974      * @param refundRecord
975      * @param ordersTotal
1869f3 976      * @param refundRecordItem
ae6ff7 977      */
1869f3 978     private static RefundCarryVo handRefundPromotion(String operationId, RefundRecord refundRecord, OrdersTotal ordersTotal
C 979             , RefundRecordItem refundRecordItem,RefundCarryVo refundCarryVo,CommonService commonService) {
ae6ff7 980         SqlSentence sqlSentence = new SqlSentence();
C 981         Map<String, Object> map = new HashMap<>();
982
983         //查看订单信息
1869f3 984         OrderItem orderItem = commonService.selectOneByKey(OrderItemMapper.class,refundRecordItem.getOrderItemId());
ae6ff7 985         if(orderItem == null ){
C 986             throw new PlatTipsException(PlatformCode.ERROR_PARAMETER_NULL,"未找到子订单信息[84]!");
987         }
988
989         //获取退款二级单
990         map.put("refundRecordItemId",refundRecordItem.getId());
991         sqlSentence.setSqlSentence("select * from refund_record_item_source where isDel = 0 AND refundRecordItemId = #{m.refundRecordItemId}");
992         List<RefundRecordItemSource> sons = commonService.selectList(RefundRecordItemSourceMapper.class, sqlSentence);
993
1869f3 994         //根据支付记录总表的标识来整合已退的金额,key值:支付记录总表标识,value:金额数据
C 995         Map<String,RefundRecordConsumePay> refundRecordConsumePayMap = new HashMap<>();
996         RefundRecordConsumePay refundRecordConsumePay;
997         //计算本次退款方式的划扣金额
998         BigDecimal deductionTotal = BigDecimal.ZERO;
999         //计算本次退款方式的现金金额
1000         BigDecimal cashTotal = BigDecimal.ZERO;
1001
1002         for (RefundRecordItemSource son : sons) {
1003             //初始化总结构携带参数
1004             refundCarryVo.setRefundConsumePayList(new ArrayList<>());
1005             refundCarryVo.setDeductionTotal(BigDecimal.ZERO);
1006             refundCarryVo.setCashTotal(BigDecimal.ZERO);
1007             switch (GroupTypeEnum.getCode(son.getType())){
1008                 case PROJECT:
1009                     refundCarryVo = handRefundNoSonExecution(refundRecord,refundRecordItem,son,refundCarryVo,commonService);
1010                     break;
1011                 case RETAIL:
1012                     refundCarryVo = handRefundSonRerail(refundRecord,son,refundCarryVo,commonService);
1013                     if(refundRecordItem.getType().equals(OrderItemConstants.CARD_BAG)){
1014                         //是卡包的,刪除卡包使用
1015                         deleteUserCardUsed(orderItem.getUserCardId(),commonService);
1016                     }
1017                     break;
1018                 case INCREMENT:
1019                     //增值金
1020                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1021                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
1022                         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);
1023                     }
1024                     break;
1025                 case STORED:
1026                     //储值金额
1027                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1028                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
1029                         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);
1030                     }
1031                     break;
1032                 case INTEGRAL:
1033                     //积分
1034                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1035                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
1036                         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);
1037                     }
1038                     break;
1039             }
1040             deductionTotal = deductionTotal.add(refundCarryVo.getDeductionTotal());
1041             cashTotal = cashTotal.add(refundCarryVo.getCashTotal());
1042             //遍历叠加支付方式记录的退款金额
1043             for(RefundRecordConsumePay re:refundCarryVo.getRefundConsumePayList()){
1044                 refundRecordConsumePay = refundRecordConsumePayMap.computeIfAbsent(re.getConsumePayId(),k->new RefundRecordConsumePay(BigDecimal.ZERO,re.getNumberNo(),re.getConsumePayId()));
1045                 refundRecordConsumePay.setRefundTotal(refundRecordConsumePay.getRefundTotal().add(re.getRefundTotal()));
ae6ff7 1046             }
C 1047         }
1048
1869f3 1049         //转载返回支付方式记录的退款金额
C 1050         List<RefundRecordConsumePay> refundRecordConsumePayList = new ArrayList<>();
1051         for (Map.Entry<String, RefundRecordConsumePay> entry : refundRecordConsumePayMap.entrySet()) {
1052             refundRecordConsumePayList.add(entry.getValue());
1053         }
1054         refundCarryVo.setCashTotal(cashTotal);
1055         refundCarryVo.setDeductionTotal(deductionTotal);
1056         refundCarryVo.setRefundConsumePayList(refundRecordConsumePayList);
ae6ff7 1057
1869f3 1058         //获取其子项
ae6ff7 1059         map.put("orderItemId",orderItem.getId());
1869f3 1060         sqlSentence.setSqlSentence("select refundStatus from order_item_source WHERE orderItemId=#{m.orderItemId} and isDel=0");
ae6ff7 1061         List<OrderItemSon> orderItemSonList=commonService.selectList(OrderItemSonMapper.class,sqlSentence);
1869f3 1062         Integer refundStatus;
C 1063         Integer refundNum = 0;
ae6ff7 1064         List<Integer> collect = orderItemSonList.stream().map(o -> o.getRefundStatus()).collect(Collectors.toList());
1869f3 1065
ae6ff7 1066         if(collect.contains(OrderTotalConstants.STATUS_REFUND_PART)){
1869f3 1067             refundStatus = OrderTotalConstants.STATUS_REFUND_PART;
ae6ff7 1068         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE)){
1869f3 1069             if(collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
C 1070                 refundStatus = OrderTotalConstants.STATUS_REFUND_PART;
1071             }else{
1072                 refundStatus = OrderTotalConstants.STATUS_REFUND_NONE;
1073             }
ae6ff7 1074         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
1869f3 1075             refundStatus = OrderTotalConstants.STATUS_REFUND_FINSH;
C 1076             refundNum = orderItem.getBuyNum();
ae6ff7 1077         }else {
1869f3 1078             refundStatus = OrderTotalConstants.STATUS_REFUND_NONE;
ae6ff7 1079         }
C 1080
1869f3 1081         //更新子订单信息
C 1082         updateOrderItemOne(orderItem,refundStatus,refundRecordItem.getRefundMoney(),refundNum,commonService);
1083
1084         return refundCarryVo;
ae6ff7 1085     }
C 1086
1869f3 1087     /**退款-处理二级子订单未执行划扣   项目类型
ae6ff7 1088      * @param refundRecord
1869f3 1089      * @param refundRecordItemSource
C 1090      * @param refundCarryVo
1091      * @param commonService
ae6ff7 1092      */
1869f3 1093     private static RefundCarryVo handRefundNoSonExecution(RefundRecord refundRecord,RefundRecordItem refundRecordItem, RefundRecordItemSource refundRecordItemSource
C 1094             ,RefundCarryVo refundCarryVo,CommonService commonService) {
ae6ff7 1095
C 1096         //判断操作完了去修改子订单状态
1097         OrderItemSon orderItemSon=commonService.selectOneByKey(OrderItemSonMapper.class,refundRecordItemSource.getOrderItemSonId());
1098         if (orderItemSon==null){
1099             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到二级子订单信息");
1100         }
1101
1102         UserProjectItem userProjectItem = getUserProject(orderItemSon.getId(),commonService);
1103         if(userProjectItem == null){
1104             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"用户项目获取失败!");
1105         }
1106         if(userProjectItem.getNotUsedNum()<refundRecordItemSource.getRefundNum()){
1107             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款次数大于可退次数[83]!");
1108         }
1109
1110         //计算子单是否还有剩余的可扣疗程数
1111         int surplusNum = orderItemSon.getUsedTotal() - orderItemSon.getHasReNum();
1112         if(refundRecordItemSource.getRefundNum() > surplusNum){
1113             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款次数大于可退次数[84]!");
1114         }
1115
1869f3 1116         //处理用户项目,减去用户项目数量
C 1117         UserProjectDeductionVo userProjectDeductionVo= UserProjectTool.userProjectDeduction(userProjectItem,UserProjectUsedCon.USED_METHOD_ORDER_REFUND,UserProjectUsedCon.USED_TYPE_DEDUCTION,null
ae6ff7 1118                 ,refundRecordItemSource.getId(),refundRecordItemSource.getRefundNum(),refundRecord.getOperatorAppId(),refundRecord.getOperatorAppName(),refundRecord.getRefundShopId(),refundRecord.getRefundShopName(),"员工备注:"+refundRecord.getRemarks()+"|用户备注:"+refundRecord.getRefundReason(),commonService);
C 1119
1120         Integer refundStatus;
1121         if(surplusNum == refundRecordItemSource.getRefundNum()){
1122             refundStatus=OrderTotalConstants.STATUS_REFUND_FINSH;
1123         }else{
1124             refundStatus=OrderTotalConstants.STATUS_REFUND_PART;
1125         }
1126
1869f3 1127         //更新子单信息
C 1128         updateOrderItemTwo(orderItemSon,refundStatus,refundRecordItemSource.getRefundMoney(),refundRecordItemSource.getRefundNum(),commonService);
1129
1130         //处理退款支付方式
1131         refundCarryVo = refundRecordMotnedItemTwoHandle(userProjectDeductionVo.getDeductionTotal(),refundRecord,refundRecordItemSource,refundCarryVo,commonService);
1132
1133         if(refundRecordItem.getType().equals(OrderItemConstants.CARD_BAG)){
1134             //是卡包的,刪除卡包使用
1135             deleteUserCardUsed(orderItemSon.getCardItemInfoId(),orderItemSon.getId(),refundRecordItemSource.getRefundNum(),commonService);
ae6ff7 1136         }
C 1137
1869f3 1138         return refundCarryVo;
ae6ff7 1139     }
1869f3 1140
C 1141     /**退款二级是商品
ae6ff7 1142      * @param refundRecord
1869f3 1143      * @param refundRecordItemSource
C 1144      * @param refundCarryVo
1145      * @param commonService
1146      * @return
ae6ff7 1147      */
1869f3 1148     private static RefundCarryVo handRefundSonRerail(RefundRecord refundRecord, RefundRecordItemSource refundRecordItemSource
C 1149             ,RefundCarryVo refundCarryVo,CommonService commonService) {
ae6ff7 1150
C 1151         //判断操作完了去修改子订单状态
1869f3 1152         OrderItemSon orderItemSon=commonService.selectOneByKey(OrderItemSonMapper.class,refundRecordItemSource.getOrderItemSonId());
C 1153         if (orderItemSon==null){
ae6ff7 1154             throw new PlatTipsException(PlatformCode.ERROR_PARAMETER_NULL,"未找到二级子订单信息");
C 1155         }
1156
1869f3 1157         //计算子单是否还有剩余的可扣疗程数
C 1158         int surplusNum = orderItemSon.getBuyNum() - orderItemSon.getHasReNum();
1159         if(refundRecordItemSource.getRefundNum() > surplusNum){
1160             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款次数大于可退次数[84]!");
ae6ff7 1161         }
C 1162
1869f3 1163         Integer refundStatus;
C 1164         if(surplusNum == refundRecordItemSource.getRefundNum()){
1165             refundStatus=OrderTotalConstants.STATUS_REFUND_FINSH;
1166         }else{
1167             refundStatus=OrderTotalConstants.STATUS_REFUND_PART;
1168         }
1169
1170         updateOrderItemTwo(orderItemSon,refundStatus,refundRecordItemSource.getRefundMoney(),refundRecordItemSource.getRefundNum(),commonService);
1171
1172         //处理退款支付方式
1173         refundCarryVo = refundRecordMotnedItemTwoHandle(null,refundRecord,refundRecordItemSource,refundCarryVo,commonService);
1174
1175         return refundCarryVo;
1176     }
1177
1178     /**更新订单一级子单的信息
1179      * @param orderItem 订单子单
1180      * @param refundStatus 退款状态
1181      * @param refundTotal 退款金额
1182      * @param refundNum 退款数量
1183      * @param commonService 映射
1184      */
1185     public static void updateOrderItemOne(OrderItem orderItem,Integer refundStatus,BigDecimal refundTotal,Integer refundNum
1186             ,CommonService commonService){
1187         SqlSentence sqlSentence = new SqlSentence();
1188         Map<String,Object> values = new HashMap<>();
1189
1190         values.put("orderItemId", orderItem.getId());
1191         values.put("refundStatus", refundStatus);
1192         values.put("refundTotal",refundTotal);
1193         values.put("refundNum",refundNum);
1194         values.put("oldHasReNum",orderItem.getHasReNum());
1195         sqlSentence.sqlUpdate(" refundStatus=#{m.refundStatus},reTotal=reTotal+#{m.refundTotal},hasReNum=hasReNum+#{m.refundNum}" +
1196                 " where isDel=0 AND id=#{m.orderItemId} AND hasReNum = #{m.oldHasReNum}",values);
1197         if(commonService.updateWhere(OrderItemMapper.class,sqlSentence) != 1){
1198             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"当前订单信息已发生变化,请重试[012]!");
1199         }
1200     }
1201
1202     /**更新订单二级子单的信息
1203      * @param orderItemSon 订单子单
1204      * @param refundStatus 退款状态
1205      * @param refundTotal 退款金额
1206      * @param refundNum 退款数量
1207      * @param commonService 映射
1208      */
1209     public static void updateOrderItemTwo(OrderItemSon orderItemSon,Integer refundStatus,BigDecimal refundTotal,Integer refundNum
1210             ,CommonService commonService){
1211         SqlSentence sqlSentence = new SqlSentence();
1212         Map<String,Object> values = new HashMap<>();
1213
1214         values.put("id", orderItemSon.getId());
1215         values.put("refundStatus", refundStatus);
1216         values.put("refundTotal",refundTotal);
1217         values.put("refundNum",refundNum);
1218         values.put("oldHasReNum",orderItemSon.getHasReNum());
1219         sqlSentence.sqlUpdate(" refundStatus=#{m.refundStatus},reTotal=reTotal+#{m.refundTotal},hasReNum=hasReNum+#{m.refundNum}" +
1220                 " where isDel=0 AND id = #{m.id} AND hasReNum = #{m.oldHasReNum}",values);
1221         if(commonService.updateWhere(OrderItemSonMapper.class,sqlSentence) != 1){
1222             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"当前订单信息已发生变化,请重试[012]!");
1223         }
1224     }
1225
1226     /**
1227      * 获取订单一级子单的支付方式记录
1228      * @param orderItemId
1229      * @param commonService
1230      * @return
1231      */
1232     public static List<ConsumePayItem> getOrderItemOneConsumePay(String orderItemId,CommonService commonService){
1233
1234         SqlSentence sqlSentence = new SqlSentence();
1235         Map<String,Object> values = new HashMap<>();
1236
1237         //获取子单的支付方式,一级子单支付记录,计算可退款金额
1238         values.clear();
1239         values.put("typeId",orderItemId);
1240         sqlSentence.sqlSentence("SELECT * FROM consume_pay_item WHERE isDel = 0 AND typeId = #{m.typeId}",values);
1241         return commonService.selectList(ConsumePayMapper.class,sqlSentence);
1242     }
1243
1244     /**
1245      * 获取订单二级级子单的支付方式记录
1246      * @param orderItemId
1247      * @param commonService
1248      * @return
1249      */
1250     public static List<ConsumePayItem> getOrderItemTwoConsumePay(String orderItemId,CommonService commonService){
1251
1252         SqlSentence sqlSentence = new SqlSentence();
1253         Map<String,Object> values = new HashMap<>();
1254
1255         //获取子单的支付方式,一级子单支付记录,计算可退款金额
1256         values.clear();
1257         values.put("typeId",orderItemId);
1258         sqlSentence.sqlSentence("SELECT * FROM consume_pay_item_son WHERE isDel = 0 AND typeId = #{m.typeId}",values);
1259         return commonService.selectList(ConsumePayMapper.class,sqlSentence);
ae6ff7 1260     }
C 1261
1262     /**获取已退款方式金额,根据支付方式编号求和返回
1263      * 注意:groupByONumberNo和groupByConsumePayId不能同时使用
1264      * @param itemId 子单标识
1265      * @param refundRecordItemId 退款子单标识
1266      * @param groupByONumberNo 根据支付方式编号求和
1267      * @param groupByConsumePayId 根据支付方式记录标识求和
1268      * @param commonService 映射
1269      * @return 返回已退款方式金额集合
1270      */
1271     public static List<RefundRecordConsumePay> getRefundRecordConsumePay(String itemId,String refundRecordItemId,boolean groupByONumberNo
1272             ,boolean groupByConsumePayId,CommonService commonService){
1273         SqlSentence sqlSentence = new SqlSentence();
1274         Map<String,Object> values = new HashMap<>();
1275         StringBuilder sql = new StringBuilder();
1276
1277         sql.append("SELECT");
1278         if(groupByONumberNo){
1279             sql.append(" numberNo,");
1280         }
1281         if(groupByConsumePayId){
1282             sql.append(" consumePayId,");
1283         }
1284         sql.append("SUM(refundTotal) AS refundTotal FROM refund_record_consume_pay a");
1285         sql.append(" JOIN refund_record rr ON rr.isDel = 0 AND rr.status = #{status}");
1286         sql.append("  WHERE a.isDel = 0");
1287         if(StringUtils.noNull(itemId)){
1288             sql.append("  AND a.commonId = #{m.commonId}");
1289         }
1290         if(StringUtils.noNull(refundRecordItemId)){
1291             sql.append("  AND a.refundRecordItemId = #{m.refundRecordItemId}");
1292         }
1293         if(groupByONumberNo){
1294             sql.append(" GROUP BY a.numberNo");
1295         }
1296         if(groupByConsumePayId){
1297             sql.append(" GROUP BY a.consumePayId");
1298         }
1299         //获取已退款的支付方式
1300         values.put("commonId",itemId);
1301         values.put("status", RefundStatus.STATUS_SUCC_REFUND);
1302         sqlSentence.sqlSentence(sql.toString(),values);
1303         return commonService.selectList(RefundRecordConsumePayMapper.class,sqlSentence);
1304     }
1305
1306     /**保存退款方式和支付方式关联
1307      * @param refundTotal 退款金额
1308      * @param commonType 子单级别,可空
1309      * @param commonId 子单标识,可空
1310      * @param orderId  总单标识
1311      * @param numberNo 支付方式编号
1312      * @param name 支付方式名称
1313      * @param consumePayId 支付方式记录标识
1314      * @param refundMethodId 退款方式标识
1315      * @param refundRecordItemId 退款子记录标识,可空
1316      * @param refundRecordId 退款总记录标识
1317      * @param commonService 映射
1318      * @return 返回关联记录
1319      */
1320     public static RefundRecordConsumePay insertRefundRecordConsumePay(BigDecimal refundTotal, String commonType, String commonId, String orderId
1321             , String numberNo,String name, String consumePayId, String refundMethodId,String refundRecordItemId,String refundRecordId,CommonService commonService){
1322         //生成关联记录
1323         RefundRecordConsumePay refundRecordConsumePay = new RefundRecordConsumePay();
1324         refundRecordConsumePay.setRefundTotal(refundTotal);
1325         refundRecordConsumePay.setCommonType(commonType);
1326         refundRecordConsumePay.setCommonId(commonId);
1327         refundRecordConsumePay.setOrderId(orderId);
1328         refundRecordConsumePay.setName(name);
1329         refundRecordConsumePay.setNumberNo(numberNo);
1330         refundRecordConsumePay.setConsumePayId(consumePayId);
1331         refundRecordConsumePay.setRefundMethodId(refundMethodId);
1332         refundRecordConsumePay.setRefundRecordItemId(refundRecordItemId);
1333         refundRecordConsumePay.setRefundRecordId(refundRecordId);
1334         commonService.insert(RefundRecordConsumePayMapper.class,refundRecordConsumePay);
1335         return refundRecordConsumePay;
1336     }
1337
1338     /**获取可退款的用户卡项
1339      * @param sourceId 订单子单标识
1340      * @return 可退款的用户卡项
1341      */
1342     public static List<UserCard> getRefundCard(String sourceId,CommonService commonService){
1343         SqlSentence sqlSentence = new SqlSentence();
1344         Map<String,Object> sqlMap = new HashMap<>();
1345         //获取用户卡项
1346         sqlMap.put("sourceId",sourceId);
1347         sqlMap.put("status",UserCard.TYPE_NO_USED);
1348         sqlMap.put("effectiveStatus",UserProjectConstants.EFF_STATUS_YES);
1349         sqlSentence.sqlSentence("SELECT * FROM user_card WHERE isDel = 0 AND sourceId = #{m.sourceId} AND status = #{m.status}" +
1350                 " AND effectiveStatus = #{m.effectiveStatus} AND turnAddId IS NULL",sqlMap);
1351         return commonService.selectList(UserCardMapper.class,sqlSentence);
1352
1353     }
1354
1355     /**获取用户项目*/
1356     public static UserProjectItem getUserProject(String commonId,CommonService commonService){
1357         SqlSentence sqlSentence = new SqlSentence();
1358         Map<String, Object> map = new HashMap<>();
1359
1360         map.clear();
1361         map.put("commonId",commonId);
1362         sqlSentence.sqlSentence("select * from user_project_item where isDel=0 and commonId=#{m.commonId} and isTransfer = 0",map);
1363         UserProjectItem userProjectItem =commonService.selectOne(UserProjectItemMapper.class,sqlSentence);
1364         return userProjectItem;
1365     }
1366
1367 }