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