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