chenjiahe
2024-03-01 cfedbfad423aa6fd758da748967122819b1787e2
提交 | 用户 | 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         //爆款活动规则退款,暂时不屏蔽保存提示
C 192         activityPageGiveIncrease(ordersTotal,refundRecord,operationId,0,commonService);
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 operationId 操作人标识
906      * @param circulateNum 避免死循环,调用的时候传0
907      * @param commonService 映射
908      */
909     public static void activityPageGiveIncrease(OrdersTotal ordersTotal,RefundRecord refundRecord,String operationId,int circulateNum,CommonService commonService){
910
911         if(circulateNum > 1){
912             return;
913         }
914         if(ordersTotal.getActivityPageType() != OrderTotalConstants.ACTIVITY_TYPE_BURST){
915             return;
916         }
917         //订单取消状态才处理
cfedbf 918         if(ordersTotal.getRefundStatus() != OrderTotalConstants.STATUS_REFUND_FINSH){
ba0b13 919             return;
C 920         }
921
922         //查找领取记录释放存在
923         //领取记录是否已领取
d3fb23 924         UserMoneyUnclaimed userMoneyUnclaimed = OrderTool.getActivityGive(ordersTotal,commonService);
ba0b13 925         if(userMoneyUnclaimed == null){
C 926             return;
927         }
cfedbf 928         SqlSentence sqlSentence = new SqlSentence();
C 929         Map<String,Object> values = new HashMap<>();
930
931         //-----生成一条记录,可以回溯
932         RefundUserAssets refundUserAssets;
933         //生成记录
934         refundUserAssets = new RefundUserAssets();
935         //设置未102是当前的记录类型
936         refundUserAssets.setIsDel(102);
937         refundUserAssets.setType(userMoneyUnclaimed.getOperationReason());
938         refundUserAssets.setStatus(RefundUserAssets.STATUS_NORMAL);
939         refundUserAssets.setAmountType(userMoneyUnclaimed.getFundType());
940         refundUserAssets.setAmount(userMoneyUnclaimed.getOpNumber().negate());
941         refundUserAssets.setOperatorId(refundRecord.getOperatorId());
942         refundUserAssets.setOperatorNo(refundRecord.getOperatorNo());
943         refundUserAssets.setOperatorName(refundRecord.getOperatorName());
944         refundUserAssets.setOrderId(refundRecord.getOrderId());
945         refundUserAssets.setRefundRecordId(refundRecord.getId());
946         refundUserAssets.setUserMoneyUnclaimedId(userMoneyUnclaimed.getId());
947         refundUserAssets.setUserId(userMoneyUnclaimed.getUserId());
ba0b13 948
C 949         if(userMoneyUnclaimed.getStatus() == UserMoneyUnclaimed.STATUS_SUCCEED){
950             //已领取,那么就扣回来
951             if(userMoneyUnclaimed.getOpNumber().compareTo(BigDecimal.ZERO) < 1){
952                 return;
953             }
cfedbf 954             refundUserAssets.setAmountStatus(RefundUserAssets.AMOUNT_STATUS_NORMAL);
ba0b13 955             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 956                     ,ordersTotal.getId(),ordersTotal.getActivityPageCode(),null,commonService);
957         }else{
d3fb23 958             if(!UserMoneyUnclaimed.YES.equals(userMoneyUnclaimed.getIsValid())){
C 959                return;
960             }
cfedbf 961             refundUserAssets.setAmountStatus(RefundUserAssets.AMOUNT_STATUS_NOT_RECEIVE);
ba0b13 962             //没有领取就作废
C 963             values.put("id",userMoneyUnclaimed.getId());
964             values.put("isValid",UserMoneyUnclaimed.NO);
965             values.put("status",UserMoneyUnclaimed.STATUS_WAI);
966             sqlSentence.sqlWhere("isValid = #{m.isValid} WHERE id = #{m.id} AND status = #{m.status}",values);
967             if(commonService.updateWhere(UserMoneyUnclaimedMapper.class,sqlSentence) != 1){
968                 circulateNum++;
969                 activityPageGiveIncrease(ordersTotal,refundRecord,operationId,circulateNum,commonService);
970             }
971         }
cfedbf 972         //保存记录,正常扣减和未领取才去保存这个记录
C 973         commonService.insert(RefundUserAssetsMapper.class,refundUserAssets);
974
975         //查看是否有第二张订单符合
976         values.clear();
977         values.put("status",OrderTotalConstants.STATUS_CANCEL);
978         values.put("payStatus",OrderTotalConstants.PAY_STATUS_SUC);
979         values.put("id",ordersTotal.getId());
980         values.put("activityPageType",ordersTotal.getActivityPageType());
981         values.put("activityPageCode",ordersTotal.getActivityPageCode());
982         sqlSentence.sqlSentence("SELECT * FROM orders_total WHERE isDel = 0 AND status != #{m.status} AND payStatus = #{m.payStatus}" +
983                 " AND id != #{m.id} AND activityPageType = #{m.activityPageType} AND activityPageCode = #{m.activityPageCode} ORDER BY createTime ASC LIMIT 1",values);
984         OrdersTotal ordersTotal1 = commonService.selectOne(OrdersTotalMapper.class,sqlSentence);
985         if(ordersTotal1 != null){
986             Integer opType = BaseEntity.NO;
987             if(userMoneyUnclaimed.getStatus() == UserMoneyUnclaimed.STATUS_SUCCEED){
988                 opType = BaseEntity.YES;
989             }
990             //增值金到账处理
991             UserMoneyUtil.setUserMoneyHandle(userMoneyUnclaimed.getUserId(), UserMoneyUnclaimed.FUND_TYPE_VALUE_ADDED_FUND,userMoneyUnclaimed.getOpNumber(),opType, OperationReasonConstants.OP_REASON_INVITE_ORDER,userMoneyUnclaimed.getOriginSubject(),userMoneyUnclaimed.getRemarks(),userMoneyUnclaimed.getOperatorId()
992                     ,ordersTotal1.getId(),ordersTotal.getActivityPageCode(),userMoneyUnclaimed.getMoneyRuleId(),commonService);
993         }
ba0b13 994
C 995     }
996
ae6ff7 997     /**
C 998      * 退款-处理活动规则增值金和积分
999      */
1000     private static void handActivityRule(CommonService commonService, String operationId, String operationNme, SqlSentence sqlSentence,
1001                                          Map<String, Object> map, RefundRecord refundRecord, OrdersTotal ordersTotal, OrderInfo orderInfo) {
1002         if(orderInfo!=null && StringUtils.noNull(orderInfo.getActivityId())){
1003             ActivityRule activityRule=commonService.selectOneByKeyBlob(ActivityRuleMapper.class,orderInfo.getActivityId());
1004             if(activityRule!=null){
1005                 map.put("activityRuleId",activityRule.getId());
1006                 map.put("type", ActivityAction.TYPE_INTEGRAL);
1007                 map.put("type1",ActivityAction.TYPE_VALUEADDEDFUND);
1008                 map.put("type2",ActivityAction.TYPE_COUPON);
e9e32c 1009                 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 1010                 List<ActivityAction> activityActions = commonService.selectList(ActivityActionMapper.class, sqlSentence);
C 1011                 if(activityActions!=null && activityActions.size()>0){
1012                     for (ActivityAction activityAction : activityActions) {
1013                         if(ActivityAction.TYPE_INTEGRAL.equals(activityAction.getType())){
1014                             //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1015                             if(new BigDecimal(activityAction.getWorth()).negate().compareTo(BigDecimal.ZERO)!=0){
1016                                 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);
1017                             }
1018                         }else if(ActivityAction.TYPE_VALUEADDEDFUND.equals(activityAction.getType())){
1019                             //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1020                             if(new BigDecimal(activityAction.getWorth()).negate().compareTo(BigDecimal.ZERO)!=0){
1021                                 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);
1022                             }
1023                         }else if(ActivityAction.TYPE_COUPON.equals(activityAction.getType())){
1024                             map.put("oldValidState",BaseEntity.YES);
1025                             map.put("newValidState",BaseEntity.NO);
1026                             map.put("couponId",activityAction.getCrmCouponId());
1027                             map.put("commonId",ordersTotal.getId());
e9e32c 1028                             sqlSentence.sqlSentence(" validState=#{m.newValidState} where couponId=#{m.couponId} and commonId=#{m.commonId} and validState=#{m.oldValidState} ",map);
ae6ff7 1029                             commonService.updateWhere(CouponNumberMapper.class,sqlSentence);
C 1030                         }
1031                     }
1032                 }
1033             }
1034         }
1035
1036     }
a1c527 1037
C 1038     /**退款-处理普通订单信息(比如:项目、促销、卡项)
1039      * @param refundCarryVo 全局携带参数结构
1040      * @param operationId 操作人标识
1041      * @param refundRecord 退款总标识
1042      * @param ordersTotal 订单
1043      * @param commonService 映射
1044      * @return 全局携带参数结构
ae6ff7 1045      */
c0efa2 1046     public static RefundCarryVo numberOfRefunds(RefundCarryVo refundCarryVo,String operationId, RefundRecord refundRecord
C 1047             ,OrdersTotal ordersTotal,CommonService commonService,DeductionSingleService deductionSingleService) {
ae6ff7 1048
C 1049         SqlSentence sqlSentence = new SqlSentence();
1050         Map<String, Object> map = new HashMap<>();
1051
1052         //获取退款子单
1053         map.put("refundRecordId",refundRecord.getId());
a1c527 1054         sqlSentence.sqlSentence("SELECT * FROM refund_record_item WHERE isDel = 0 AND refundRecordId = #{m.refundRecordId}",map);
ae6ff7 1055         List<RefundRecordItem> refundRecordItems =commonService.selectList(RefundRecordItemMapper.class,sqlSentence);
a1c527 1056         if(refundRecordItems == null || refundRecordItems.size() == 0){
ae6ff7 1057             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到退款子订单信息");
C 1058         }
1059
1869f3 1060         //根据支付记录总表的标识来整合已退的金额,key值:支付记录总表标识,value:金额数据
C 1061         Map<String,RefundRecordConsumePay> refundRecordConsumePayMap = new HashMap<>();
1062         RefundRecordConsumePay refundRecordConsumePay;
ae6ff7 1063
C 1064         for (RefundRecordItem refundRecordItem: refundRecordItems) {
1869f3 1065             //初始化总结构携带参数
C 1066             refundCarryVo.setRefundConsumePayList(new ArrayList<>());
1067             refundCarryVo.setDeductionTotal(BigDecimal.ZERO);
1068             refundCarryVo.setCashTotal(BigDecimal.ZERO);
2a45d4 1069             refundCarryVo.setDeductionTotalUser(BigDecimal.ZERO);
99213f 1070             refundCarryVo.setCashPurenessTotal(BigDecimal.ZERO);
C 1071             refundCarryVo.setRechargeTotal(BigDecimal.ZERO);
1072             refundCarryVo.setIntegralTotal(BigDecimal.ZERO);
1073             refundCarryVo.setIncrementTotal(BigDecimal.ZERO);
1074             refundCarryVo.setRefundTotal(BigDecimal.ZERO);
510678 1075             //商品类型判断
ae6ff7 1076             switch (refundRecordItem.getType()){
C 1077                 case OrderItemConstants.TYPE_RETAIL:
1869f3 1078                     refundCarryVo = handRefundRerail(refundRecord,refundRecordItem,refundCarryVo,commonService);
ae6ff7 1079                     break;
C 1080                 case OrderItemConstants.TYPE_DRUG:
1869f3 1081                     refundCarryVo = handRefundRerail(refundRecord,refundRecordItem,refundCarryVo,commonService);
ae6ff7 1082                     break;
C 1083                 case OrderItemConstants.TYPE_PROJECT:
e2a6c2 1084                     refundCarryVo = handRefundNoExecution(refundRecord,refundRecordItem,refundCarryVo,commonService,deductionSingleService);
ae6ff7 1085                     break;
C 1086                 case OrderItemConstants.TYPE_PROMOTION:
e2a6c2 1087                     refundCarryVo = handRefundPromotion(operationId, refundRecord, ordersTotal,refundRecordItem,refundCarryVo,commonService,deductionSingleService);
ae6ff7 1088                     break;
C 1089                 case OrderItemConstants.TYPE_CARD:
1869f3 1090                     refundCarryVo = handRefundCard(refundRecord,refundRecordItem,refundCarryVo,commonService);
ae6ff7 1091                     break;
C 1092                 case OrderItemConstants.CARD_BAG:
e2a6c2 1093                     refundCarryVo = handRefundPromotion(operationId, refundRecord, ordersTotal,refundRecordItem,refundCarryVo,commonService,deductionSingleService);
ae6ff7 1094                     break;
89b4d7 1095                 case OrderItemConstants.TYPE_COUPON:
F 1096                     refundCarryVo = handRefundRerail(refundRecord,refundRecordItem,refundCarryVo,commonService);
1097                     break;
e065e7 1098                 default:
C 1099                     //其他
1100                     refundCarryVo = handRefundRerail(refundRecord,refundRecordItem,refundCarryVo,commonService);
1101                     break;
ae6ff7 1102             }
1869f3 1103
C 1104             //遍历叠加支付方式记录的退款金额
1105             for(RefundRecordConsumePay re:refundCarryVo.getRefundConsumePayList()){
2a45d4 1106                 refundRecordConsumePay = refundRecordConsumePayMap.computeIfAbsent(re.getConsumePayId(),k->new RefundRecordConsumePay(BigDecimal.ZERO,re.getNumberNo(),re.getName(),re.getIsMoneyPay(),re.getIsExecute(),re.getConsumePayId()));
1869f3 1107                 refundRecordConsumePay.setRefundTotal(refundRecordConsumePay.getRefundTotal().add(re.getRefundTotal()));
C 1108             }
ae6ff7 1109         }
1869f3 1110
C 1111         //转载返回支付方式记录的退款金额
1112         List<RefundRecordConsumePay> refundRecordConsumePayList = new ArrayList<>();
1113         for (Map.Entry<String, RefundRecordConsumePay> entry : refundRecordConsumePayMap.entrySet()) {
1114             refundRecordConsumePayList.add(entry.getValue());
a1c527 1115         }
C 1116
1117         //校验金额是不是已经分配完
1118         for(RefundRecordMethod refundRecordMethod:refundCarryVo.getRefundRecordMethodList()){
1119             if(refundRecordMethod.getpTotal().compareTo(BigDecimal.ZERO) > 0){
1120                 throw new TipsException("退款金额分配错误!");
1121             }
1869f3 1122         }
C 1123
1124         refundCarryVo.setRefundConsumePayList(refundRecordConsumePayList);
1125         return refundCarryVo;
ae6ff7 1126     }
C 1127
1128     /**
1129      * 退款一级是商品
1130      * @param refundRecord 退款总信息
1131      * @param refundRecordItem 退款子单
1132      * @param commonService 映射
1133      */
1869f3 1134     private static RefundCarryVo handRefundRerail(RefundRecord refundRecord, RefundRecordItem refundRecordItem
C 1135             , RefundCarryVo refundCarryVo, CommonService commonService) {
ae6ff7 1136
C 1137         //判断操作完了去修改子订单状态
1138         OrderItem orderItem=commonService.selectOneByKey(OrderItemMapper.class,refundRecordItem.getOrderItemId());
1139         if (orderItem==null){
1140             throw new PlatTipsException(PlatformCode.ERROR_PARAMETER_NULL,"未找到子订单信息");
1141         }
1142         //剩余可退款数量
1143         Integer surplusNum = orderItem.getBuyNum()-orderItem.getHasReNum();
1144         if(refundRecordItem.getRefundNum() > surplusNum){
1145             throw new TipsException("退款数量不能大于可退款数量!");
1146         }
1147
1148         //变更退款子项信息
a1c527 1149         int refundStatus;
ae6ff7 1150         if (surplusNum.equals(refundRecordItem.getRefundNum())){
1869f3 1151             refundStatus = OrderTotalConstants.STATUS_REFUND_FINSH;
ae6ff7 1152         }else{
1869f3 1153             refundStatus = OrderTotalConstants.STATUS_REFUND_PART;
ae6ff7 1154         }
C 1155
1156         //退款方式处理
99213f 1157         refundCarryVo = refundRecordMotnedItemHandle(refundRecord,refundRecordItem,refundCarryVo,commonService);
C 1158
1159         //更新子订单信息
1160         updateOrderItemOne(orderItem,refundStatus,refundCarryVo,refundRecordItem.getRefundNum(),commonService);
1161
1162         return refundCarryVo;
ae6ff7 1163     }
C 1164
1165     /**
1166      * 退款-处理未执行划扣   项目类型
a1c527 1167      * @param refundRecord 退款总记录
C 1168      * @param refundRecordItem 退款一级子记录
ae6ff7 1169      */
1869f3 1170     private static RefundCarryVo handRefundNoExecution(RefundRecord refundRecord, RefundRecordItem refundRecordItem
e2a6c2 1171             ,RefundCarryVo refundCarryVo,CommonService commonService,DeductionSingleService deductionSingleService) {
ae6ff7 1172
C 1173         //找到子单
1174         OrderItem orderItem=commonService.selectOneByKey(OrderItemMapper.class,refundRecordItem.getOrderItemId());
1175         if (orderItem==null){
1176             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到子订单信息");
1177         }
a1c527 1178
C 1179         SqlSentence sqlSentence = new SqlSentence();
1180         Map<String, Object> map = new HashMap<>();
1181
c40d5d 1182         //先作废划扣,不然数量对不上
4215f9 1183         deductionCancel(refundRecord,refundRecordItem.getId(),commonService,deductionSingleService);
ae6ff7 1184
C 1185         //找到用户项目
1186         map.put("commonId",refundRecordItem.getOrderItemId());
1187         sqlSentence.sqlSentence("select * from user_project_item where isDel = 0 and commonId = #{m.commonId} and isTransfer = 0",map);
1188         UserProjectItem userProjectItem =commonService.selectOne(UserProjectItemMapper.class,sqlSentence);
1189         if (userProjectItem == null) {
1190             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到用户子项项目信息");
1191         }
1192
1193         if(userProjectItem.getNotUsedNum() < refundRecordItem.getRefundNum()){
1194             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款次数大于可退次数!");
1195         }
1196
1197         //用户项目操作
1869f3 1198         UserProjectDeductionVo  userProjectDeductionVo = UserProjectTool.userProjectDeduction(userProjectItem,UserProjectUsedCon.USED_METHOD_ORDER_REFUND,UserProjectUsedCon.USED_TYPE_DEDUCTION,null
ae6ff7 1199                 ,refundRecordItem.getId(),refundRecordItem.getRefundNum(),refundRecord.getOperatorAppId(),refundRecord.getOperatorAppName(),refundRecord.getRefundShopId(),refundRecord.getRefundShopName(),"员工备注:"+refundRecord.getRemarks()+"|用户备注:"+refundRecord.getRefundReason(),commonService);
2a45d4 1200
C 1201         refundCarryVo.setDeductionTotalUser(userProjectDeductionVo.getDeductionTotal());
ae6ff7 1202
C 1203         //计算子单是否还有剩余的可扣疗程数
1204         int surplusNum = orderItem.getUsedTotal()-orderItem.getHasReNum();
1205         if(refundRecordItem.getRefundNum() > surplusNum){
1206             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款次数大于子单可退次数[54]!");
1207         }
1208
a1c527 1209         int refundStatus;
ae6ff7 1210         if(refundRecordItem.getRefundNum() == surplusNum){
C 1211             refundStatus=OrderTotalConstants.STATUS_REFUND_FINSH;
1212         }else{
1213             refundStatus=OrderTotalConstants.STATUS_REFUND_PART;
1214         }
1215
1216         //退款方式处理
99213f 1217         refundCarryVo = refundRecordMotnedItemHandle(refundRecord,refundRecordItem,refundCarryVo,commonService);
C 1218
1219         //更新子订单信息
1220         updateOrderItemOne(orderItem,refundStatus,refundCarryVo,refundRecordItem.getRefundNum(),commonService);
1221
1222         return refundCarryVo;
ae6ff7 1223     }
C 1224
a1c527 1225     /**退款-处理卡项
C 1226      * @param refundRecord 退款总记录
1227      * @param refundRecordItem 退款一级记录
1228      * @param refundCarryVo 全局携带参数结构
1229      * @param commonService 映射
1230      * @return 全局携带参数结构
ae6ff7 1231      */
1869f3 1232     public static RefundCarryVo handRefundCard(RefundRecord refundRecord, RefundRecordItem refundRecordItem,RefundCarryVo refundCarryVo,CommonService commonService) {
ae6ff7 1233
C 1234         //判断操作完了去修改子订单状态
1235         OrderItem orderItem=commonService.selectOneByKey(OrderItemMapper.class,refundRecordItem.getOrderItemId());
1236         if (orderItem==null){
1869f3 1237             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到子订单信息");
ae6ff7 1238         }
C 1239         Integer surplusNum = orderItem.getBuyNum() - orderItem.getHasReNum();
1240         if(refundRecordItem.getRefundNum() > surplusNum){
1241             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款作废卡包提示:没有找到对应的卡包可退[020]");
1242         }
1243
1244         //找到可退款卡包
160c33 1245         List<UserCard> userCardList = PartialRefundUtil.getRefundCard(orderItem.getId(),UserProjectConstants.EFF_STATUS_YES,commonService);
ae6ff7 1246         if(refundRecordItem.getRefundNum() > userCardList.size()){
C 1247             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款作废卡包提示:没有找到对应的卡包可退[021]");
1248         }
1249
a1c527 1250         SqlSentence sqlSentence = new SqlSentence();
C 1251         Map<String, Object> map = new HashMap<>();
1252
1869f3 1253         //变更卡项状态
ae6ff7 1254         UserCard userCard;
1869f3 1255         RefundRecordCard refundRecordCard;
ae6ff7 1256         for (int i = 0; i < refundRecordItem.getRefundNum(); i++) {
C 1257             userCard= userCardList.get(i);
1258             map.put("id",userCard.getId());
ea2ceb 1259             map.put("statusOld", UserCard.TYPE_NO_USED);
ae6ff7 1260             map.put("effectiveStatus", UserProjectConstants.EFF_STATUS_CANCEL);
2e8393 1261             map.put("oldEffectiveStatus", UserProjectConstants.EFF_STATUS_YES);
ea2ceb 1262             sqlSentence.sqlSentence(" effectiveStatus=#{m.effectiveStatus} WHERE id = #{m.id} AND effectiveStatus = #{m.oldEffectiveStatus} AND status = #{m.statusOld}",map);
2e8393 1263             if(commonService.updateWhere(UserCardMapper.class,sqlSentence) != 1){
C 1264                 throw new TipsException("用户卡包状态已发生变化,请重试!");
1265             }
1869f3 1266
C 1267             //生成退款关联
1268             refundRecordCard = new RefundRecordCard();
1269             refundRecordCard.setUserCardId(userCard.getId());
1270             refundRecordCard.setRefundRecordId(refundRecord.getId());
1271             refundRecordCard.setRefundRecordItemId(refundRecordItem.getId());
a1c527 1272             commonService.insert(RefundRecordCardMapper.class,refundRecordCard);
ae6ff7 1273         }
C 1274
a1c527 1275         int refundStatus;
ea4351 1276         //卡项的,不管有没有退数量,只要走进这里,都是部分退或者全部退,可能有卡项部分退
ae6ff7 1277         if (surplusNum.equals(refundRecordItem.getRefundNum())){
1869f3 1278             refundStatus =  OrderTotalConstants.STATUS_REFUND_FINSH;
ae6ff7 1279         }else {
1869f3 1280             refundStatus =  OrderTotalConstants.STATUS_REFUND_PART;
ae6ff7 1281         }
ea4351 1282
ae6ff7 1283         //退款方式处理
99213f 1284         refundCarryVo = refundRecordMotnedItemHandle(refundRecord,refundRecordItem,refundCarryVo,commonService);
C 1285
1286         //更新子订单信息
1287         updateOrderItemOne(orderItem,refundStatus,refundCarryVo,refundRecordItem.getRefundNum(),commonService);
ea4351 1288
C 1289         //--卡项部分退处理
3badb7 1290         if(RefundSoruceConstants.TYPE_SOURCE_USER_CARD.equals(refundRecord.getSourceAssistantType())){
ea4351 1291             CardRefundTool.realRefund(refundRecord,refundRecordItem,refundCarryVo,commonService);
C 1292         }
1293
1869f3 1294         return refundCarryVo;
ae6ff7 1295     }
C 1296
a1c527 1297     /**退款-处理卡包
ae6ff7 1298      */
1869f3 1299     public static void handCardBag(String operationId,RefundRecord refundRecord, OrdersTotal ordersTotal
C 1300             ,RefundRecordItem refundRecordItem,RefundCarryVo refundCarryVo,CommonService commonService) {
ae6ff7 1301
a1c527 1302         //查看订单信息
C 1303         OrderItem orderItem=commonService.selectOneByKey(OrderItemMapper.class,refundRecordItem.getOrderItemId());
1304         if(orderItem == null ){
1305             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到子订单信息!");
1306         }
1307
ae6ff7 1308         SqlSentence sqlSentence = new SqlSentence();
C 1309         Map<String, Object> map = new HashMap<>();
1310
1311         map.put("refundRecordItemId",refundRecordItem.getId());
a1c527 1312         sqlSentence.sqlSentence("select * from refund_record_item_source where refundRecordItemId =#{m.refundRecordItemId}",map);
ae6ff7 1313         List<RefundRecordItemSource> sons = commonService.selectList(RefundRecordItemSourceMapper.class, sqlSentence);
C 1314         if(sons.size() == 0 ){
1315             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到子订单信息[015]!");
1316         }
1317
1318         for (RefundRecordItemSource son : sons) {
1869f3 1319             refundCarryVo.setRefundConsumePayList(new ArrayList<>());
C 1320             refundCarryVo.setDeductionTotal(BigDecimal.ZERO);
1321             refundCarryVo.setCashTotal(BigDecimal.ZERO);
ae6ff7 1322             switch (GroupTypeEnum.getCode(son.getType())){
C 1323                 case PROJECT:
1869f3 1324                     //handRefundNoSonExecution(refundRecord,son,refundCarryVo,commonService);
ae6ff7 1325                     break;
C 1326                 case RETAIL:
1869f3 1327                     //handRefundSonRerail(refundRecord,son,refundCarryVo,commonService );
C 1328                     //deleteUserCardUsed(sqlSentence,map,ordersTotal,commonService,son,orderItem);
ae6ff7 1329                     break;
C 1330                 case INCREMENT:
1331                     //增值金
1332                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1333                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
1334                         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);
1335                     }
1336                     break;
1337                 case STORED:
1338                     //储值金额
1339                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1340                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
1341                         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);
1342                     }
1343                     break;
1344                 case INTEGRAL:
1345                     //积分
1346                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1347                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
1348                         UserMoneyUtil.setNewUserMoneyUnclaimed(refundRecord.getUserId(),refundRecord.getRemarks(),"审核通过退款:促销赠送积分扣减",operationId,refundRecord.getOrderId(),ordersTotal.getAppIdCode(),refundRecord.getId(),son.getRealRefundTotal().negate(), UserMoneyUnclaimed.FUND_TYPE_INTEGRAL,OperationReasonConstants.OP_REASON_RECHARGE_REFUND,commonService,UserMoneyUnclaimed.YES);
1349                     }
1350                     break;
1351             }
1352         }
1353
1354         //更改二级子订单退款状态
1355         map.put("orderItemId",orderItem.getId());
1356         sqlSentence.setSqlSentence("select * from order_item_source WHERE  orderItemId=#{m.orderItemId} and isDel=0");
1357         List<OrderItemSon> orderItemSonList=commonService.selectList(OrderItemSonMapper.class,sqlSentence);
1358
a1c527 1359         List<Integer> collect = orderItemSonList.stream().map(OrderItemSon::getRefundStatus).collect(Collectors.toList());
ae6ff7 1360         if(collect.contains(OrderTotalConstants.STATUS_REFUND_PART)){
C 1361             orderItem.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
1362             orderItem.setReTotal(orderItemSonList.stream().map(OrderItemSon::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
1363         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE) && collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
1364             orderItem.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
1365             orderItem.setReTotal(orderItemSonList.stream().map(OrderItemSon::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
1366         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE)){
1367             orderItem.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
1368         }else  if (collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
1369             orderItem.setRefundStatus(OrderTotalConstants.STATUS_REFUND_FINSH);
1370             orderItem.setReTotal(orderItemSonList.stream().map(OrderItemSon::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
1371             orderItem.setHasReNum(orderItem.getBuyNum());
1372         }else {
1373             orderItem.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
1374         }
1375
1376         commonService.updateAll(OrderItemMapper.class,orderItem);
1377     }
1378
a1c527 1379     /**退款需要删除用户卡包使用记录
b91aa3 1380      * @param userCardId 用户卡包
a1c527 1381      * @param cardItemInfoId 卡包的卡项子项
C 1382      * @param sourceId 卡包使用记录来源标识
e9e32c 1383      * @param orderId 卡包使用记录来源总表标识
a1c527 1384      * @param refundNum 退款数量
C 1385      * @param commonService 映射
ae6ff7 1386      */
b91aa3 1387     public static void deleteUserCardUsed(String userCardId,String cardItemInfoId,String sourceId,String orderId,Integer refundNum
a1c527 1388             ,CommonService commonService){
1869f3 1389
a1c527 1390         //查出用户,commonId:卡项的组合项标识
C 1391         CardItemInfo cardItemInfo=commonService.selectOneByKey(CardItemInfoMapper.class,cardItemInfoId);
1392         if(cardItemInfo ==null){
b91aa3 1393             logger.error("未找到该卡包的组合项-卡包退款失败,userCardId:{},cardItemInfoId:{},sourceId:{},orderId:{},refundNum:{}",userCardId,cardItemInfoId,sourceId,orderId,refundNum);
a1c527 1394             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到该卡包的组合项");
C 1395         }
1396
1397         //获取权益类型
1398         CardEquity cardEquity = commonService.selectOneByKey(CardEquityMapper.class,cardItemInfo.getCardEquityId());
1399         if(cardEquity == null){
b91aa3 1400             logger.error("未找到该卡包的组合项权益类型-卡包退款失败,userCardId:{},cardItemInfoId:{},sourceId:{},orderId:{},refundNum:{}",userCardId,cardItemInfoId,sourceId,orderId,refundNum);
a1c527 1401             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到该卡包的组合项权益类型");
e9e32c 1402         }
C 1403
1404         SqlSentence sqlSentence = new SqlSentence();
1405         Map<String,Object> map = new HashMap<>();
1406
1407         //获取使用记录
1408         map.put("cardItemInfoId",cardItemInfoId);
1409         map.put("sourceId",sourceId);
b91aa3 1410         map.put("userCardId",userCardId);
ea4351 1411         map.put("sourceType",UserCardUsed.SOURCE_TYPE_ORDER_ITEM_TWO);
b91aa3 1412         sqlSentence.sqlSentence(" SELECT * FROM user_card_used WHERE isDel = 0 AND userCardId = #{m.userCardId}" +
ea4351 1413                 " AND cardItemInfoId = #{m.cardItemInfoId} AND sourceId = #{m.sourceId} AND sourceType = #{m.sourceType}",map);
e9e32c 1414         List<UserCardUsed> userCardUsedList = commonService.selectList(UserCardUsedMapper.class,sqlSentence);
C 1415
1416         //因为之前的使用记录有些没有关联到订单,所以找不到
1417         if(userCardUsedList == null || userCardUsedList.size() == 0){
1418             map.clear();
1419             map.put("cardItemInfoId",cardItemInfoId);
b91aa3 1420             map.put("userCardId",userCardId);
C 1421             map.put("orderId",orderId);
ea4351 1422             map.put("sourceType",UserCardUsed.SOURCE_TYPE_ORDER_ITEM_TWO);
C 1423             sqlSentence.sqlSentence(" SELECT * FROM user_card_used WHERE isDel = 0 AND sourceType = #{m.sourceType} AND userCardId = #{m.userCardId}" +
b91aa3 1424                     " AND cardItemInfoId = #{m.cardItemInfoId} AND orderId = #{m.orderId} AND sourceId IS NULL",map);
e9e32c 1425             userCardUsedList = commonService.selectList(UserCardUsedMapper.class,sqlSentence);
b91aa3 1426             if(userCardUsedList.size() == 0){
ea4351 1427                 sqlSentence.sqlSentence(" SELECT * FROM user_card_used WHERE isDel = 0 AND sourceType = #{m.sourceType} AND userCardId = #{m.userCardId}" +
b91aa3 1428                         " AND cardItemInfoId = #{m.cardItemInfoId} AND sourceId IS NULL",map);
C 1429                 userCardUsedList = commonService.selectList(UserCardUsedMapper.class,sqlSentence);
1430             }
a1c527 1431         }
C 1432
a88f94 1433         //获取总使用数量
C 1434         int usedNum = 0;
1435         for(UserCardUsed userCardUsed:userCardUsedList){
1436             usedNum = usedNum+userCardUsed.getUsedNum();
a1c527 1437         }
C 1438
1439         //计算退回的卡次
a88f94 1440         int returnNum = UserCardTool.countUsedNumber(refundNum,cardItemInfo,cardEquity);
a1c527 1441
a88f94 1442         if(returnNum > usedNum){
2b1cfa 1443             logger.error("卡包可退数量错误-卡包退款失败,查询语句:{},传入参数:{}",sqlSentence.getSqlSentence(), JSON.toJSONString(sqlSentence.getM()));
a88f94 1444             logger.error("卡包可退数量错误-卡包退款失败,userCardId:{},cardItemInfoId:{},sourceId:{},orderId:{},refundNum:{},returnNum:{},usedNum:{}",userCardId,cardItemInfoId,sourceId,orderId,refundNum,returnNum,usedNum);
1869f3 1445             throw new TipsException("卡包可退数量错误!");
C 1446         }
1447
e9e32c 1448         //已经操作数量
a88f94 1449         int opNum = returnNum;
e9e32c 1450         StringBuilder sql;
1869f3 1451         for(UserCardUsed userCardUsed:userCardUsedList){
1d573f 1452             //判断是否够了,跳出循环
a88f94 1453             if(opNum <= 0){
1d573f 1454                 break;
C 1455             }
a88f94 1456             if(userCardUsed.getUsedNum() <= 0){
C 1457                 continue;
1458             }
e9e32c 1459             map.clear();
a88f94 1460             sql = new StringBuilder();
1869f3 1461             map.put("id",userCardUsed.getId());
a88f94 1462             map.put("usedNumOld",userCardUsed.getUsedNum());
C 1463             if(opNum >= userCardUsed.getUsedNum()){
1464                 map.put("isDel",UserCardUsed.YES);
1465                 map.put("countNum",userCardUsed.getUsedNum());
1466                 opNum = opNum - userCardUsed.getUsedNum();
1467             }else{
1468                 map.put("isDel",UserCardUsed.NO);
1469                 map.put("countNum",opNum);
1470                 opNum = 0;
1471             }
1472             sql.append("isDel = #{m.isDel}");
1473             sql.append(",usedNum =  usedNum - #{m.countNum}");
1474             sql.append(",cancelNum =  cancelNum + #{m.countNum}");
e9e32c 1475             if(StringUtils.isEmpty(userCardUsed.getOrderId())){
C 1476                 sql.append(",orderId = #{m.orderId}");
1477                 map.put("orderId",orderId);
1478             }
1479             if(StringUtils.isEmpty(userCardUsed.getSourceId())){
1480                 sql.append(",sourceId = #{m.sourceId}");
1481                 map.put("sourceId",sourceId);
1482             }
a88f94 1483             sql.append(" WHERE id = #{m.id} AND isDel = 0 AND usedNum = #{m.usedNumOld}");
e9e32c 1484             sqlSentence.sqlUpdate(sql.toString(),map);
a88f94 1485             if(commonService.updateWhere(UserCardUsedMapper.class,sqlSentence)!=1){
db3dfa 1486                 throw new TipsException("卡包使用记录已发生变化,请重试!");
a88f94 1487             }
1869f3 1488         }
a88f94 1489         if(opNum != 0){
b91aa3 1490             logger.error("卡包回退数量错误-卡包退款失败,userCardId:{},cardItemInfoId:{},sourceId:{},orderId:{},refundNum:{},returnNum:{},opNum:{}",userCardId,cardItemInfoId,sourceId,orderId,refundNum,returnNum,opNum);
a1c527 1491             throw new TipsException("卡包回退数量错误!");
1869f3 1492         }
ae6ff7 1493     }
1869f3 1494
a1c527 1495     /**退款-处理促销
C 1496      * @param operationId 操作人标识
1497      * @param refundRecord 退款总记录
1498      * @param ordersTotal 订单
1499      * @param refundRecordItem 退款一级记录
1500      * @param refundCarryVo 全局携带参数结构
1501      * @param commonService 映射
1502      * @return 全局携带参数结构
ae6ff7 1503      */
1869f3 1504     private static RefundCarryVo handRefundPromotion(String operationId, RefundRecord refundRecord, OrdersTotal ordersTotal
e2a6c2 1505             , RefundRecordItem refundRecordItem,RefundCarryVo refundCarryVo,CommonService commonService,DeductionSingleService deductionSingleService) {
ae6ff7 1506
C 1507         //查看订单信息
1869f3 1508         OrderItem orderItem = commonService.selectOneByKey(OrderItemMapper.class,refundRecordItem.getOrderItemId());
ae6ff7 1509         if(orderItem == null ){
C 1510             throw new PlatTipsException(PlatformCode.ERROR_PARAMETER_NULL,"未找到子订单信息[84]!");
1511         }
1512
a1c527 1513         SqlSentence sqlSentence = new SqlSentence();
C 1514         Map<String, Object> map = new HashMap<>();
1515
ae6ff7 1516         //获取退款二级单
C 1517         map.put("refundRecordItemId",refundRecordItem.getId());
a1c527 1518         sqlSentence.sqlSentence("select * from refund_record_item_source where isDel = 0 AND refundRecordItemId = #{m.refundRecordItemId}",map);
ae6ff7 1519         List<RefundRecordItemSource> sons = commonService.selectList(RefundRecordItemSourceMapper.class, sqlSentence);
C 1520
1869f3 1521         //根据支付记录总表的标识来整合已退的金额,key值:支付记录总表标识,value:金额数据
C 1522         Map<String,RefundRecordConsumePay> refundRecordConsumePayMap = new HashMap<>();
1523         RefundRecordConsumePay refundRecordConsumePay;
1524         //计算本次退款方式的划扣金额
1525         BigDecimal deductionTotal = BigDecimal.ZERO;
2a45d4 1526         //分配的用户项目划扣金额
C 1527         BigDecimal deductionTotalUser = BigDecimal.ZERO;
99213f 1528         //计算本次退款方式的现金金额
C 1529         BigDecimal cashTotal = BigDecimal.ZERO;
1530         //退款现金总金额(元,不包含退到储值金的)
e490fa 1531         BigDecimal cashPurenessTotal = BigDecimal.ZERO;
99213f 1532         //退款储值金总金额(元)
e490fa 1533          BigDecimal rechargeTotal = BigDecimal.ZERO;
99213f 1534         //退款增值金总金额(元)
e490fa 1535         BigDecimal incrementTotal = BigDecimal.ZERO;
99213f 1536         //退款积分
e490fa 1537         BigDecimal integralTotal = BigDecimal.ZERO;
99213f 1538         //退款总金额(元)
e490fa 1539         BigDecimal refundTotal = BigDecimal.ZERO;
1869f3 1540
C 1541         for (RefundRecordItemSource son : sons) {
1542             //初始化总结构携带参数
1543             refundCarryVo.setRefundConsumePayList(new ArrayList<>());
1544             refundCarryVo.setDeductionTotal(BigDecimal.ZERO);
1545             refundCarryVo.setCashTotal(BigDecimal.ZERO);
2a45d4 1546             refundCarryVo.setDeductionTotalUser(BigDecimal.ZERO);
99213f 1547             refundCarryVo.setDeductionTotalUser(BigDecimal.ZERO);
C 1548             refundCarryVo.setCashPurenessTotal(BigDecimal.ZERO);
1549             refundCarryVo.setRechargeTotal(BigDecimal.ZERO);
1550             refundCarryVo.setIntegralTotal(BigDecimal.ZERO);
1551             refundCarryVo.setIncrementTotal(BigDecimal.ZERO);
1552             refundCarryVo.setRefundTotal(BigDecimal.ZERO);
1869f3 1553             switch (GroupTypeEnum.getCode(son.getType())){
C 1554                 case PROJECT:
e2a6c2 1555                     refundCarryVo = handRefundNoSonExecution(refundRecord,refundRecordItem,son,refundCarryVo,orderItem.getUserCardId(),commonService,deductionSingleService);
1869f3 1556                     break;
C 1557                 case RETAIL:
b91aa3 1558                     refundCarryVo = handRefundSonRerail(refundRecord,refundRecordItem,son,refundCarryVo,orderItem.getUserCardId(),commonService);
1869f3 1559                     break;
C 1560                 case INCREMENT:
1561                     //增值金
1562                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1563                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
1564                         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);
1565                     }
1566                     break;
1567                 case STORED:
1568                     //储值金额
1569                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1570                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
1571                         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);
1572                     }
1573                     break;
1574                 case INTEGRAL:
1575                     //积分
1576                     //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1577                     if(son.getRealRefundTotal().negate().compareTo(BigDecimal.ZERO)!=0){
1578                         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);
1579                     }
1580                     break;
e065e7 1581                 default:
C 1582                     //其他
1583                     refundCarryVo = handRefundSonRerail(refundRecord,refundRecordItem,son,refundCarryVo,orderItem.getUserCardId(),commonService);
1584                     break;
1869f3 1585             }
C 1586             deductionTotal = deductionTotal.add(refundCarryVo.getDeductionTotal());
2a45d4 1587             deductionTotalUser = deductionTotalUser.add(refundCarryVo.getDeductionTotalUser());
e490fa 1588             cashTotal = cashTotal.add(refundCarryVo.getCashTotal());
99213f 1589             cashPurenessTotal = cashPurenessTotal.add(refundCarryVo.getCashPurenessTotal());
C 1590             rechargeTotal = rechargeTotal.add(refundCarryVo.getRechargeTotal());
1591             incrementTotal = incrementTotal.add(refundCarryVo.getIncrementTotal());
1592             integralTotal = integralTotal.add(refundCarryVo.getIntegralTotal());
1593             refundTotal = refundTotal.add(refundCarryVo.getRefundTotal());
1869f3 1594             //遍历叠加支付方式记录的退款金额
C 1595             for(RefundRecordConsumePay re:refundCarryVo.getRefundConsumePayList()){
2a45d4 1596                 refundRecordConsumePay = refundRecordConsumePayMap.computeIfAbsent(re.getConsumePayId(),k->new RefundRecordConsumePay(BigDecimal.ZERO,re.getNumberNo(),re.getName(),re.getIsMoneyPay(),re.getIsExecute(),re.getConsumePayId()));
1869f3 1597                 refundRecordConsumePay.setRefundTotal(refundRecordConsumePay.getRefundTotal().add(re.getRefundTotal()));
ae6ff7 1598             }
C 1599         }
1600
1869f3 1601         //转载返回支付方式记录的退款金额
C 1602         List<RefundRecordConsumePay> refundRecordConsumePayList = new ArrayList<>();
1603         for (Map.Entry<String, RefundRecordConsumePay> entry : refundRecordConsumePayMap.entrySet()) {
1604             refundRecordConsumePayList.add(entry.getValue());
1605         }
e490fa 1606         refundCarryVo.setRefundConsumePayList(refundRecordConsumePayList);
1869f3 1607         refundCarryVo.setDeductionTotal(deductionTotal);
2a45d4 1608         refundCarryVo.setDeductionTotalUser(deductionTotalUser);
e490fa 1609         refundCarryVo.setCashTotal(cashTotal);
99213f 1610         refundCarryVo.setCashPurenessTotal(cashPurenessTotal);
C 1611         refundCarryVo.setRechargeTotal(rechargeTotal);
1612         refundCarryVo.setIncrementTotal(incrementTotal);
e490fa 1613         refundCarryVo.setIntegralTotal(integralTotal);
99213f 1614         refundCarryVo.setRefundTotal(refundTotal);
2a45d4 1615
C 1616         //更新退款子单
99213f 1617         updateRefundItem(refundCarryVo,refundRecordItem.getId(),commonService);
ae6ff7 1618
1869f3 1619         //获取其子项
ae6ff7 1620         map.put("orderItemId",orderItem.getId());
e9e32c 1621         sqlSentence.sqlSentence("select refundStatus from order_item_source WHERE orderItemId=#{m.orderItemId} and isDel=0",map);
ae6ff7 1622         List<OrderItemSon> orderItemSonList=commonService.selectList(OrderItemSonMapper.class,sqlSentence);
a1c527 1623         int refundStatus;
1869f3 1624         Integer refundNum = 0;
a1c527 1625         List<Integer> collect = orderItemSonList.stream().map(OrderItemSon::getRefundStatus).collect(Collectors.toList());
1869f3 1626
ae6ff7 1627         if(collect.contains(OrderTotalConstants.STATUS_REFUND_PART)){
1869f3 1628             refundStatus = OrderTotalConstants.STATUS_REFUND_PART;
ae6ff7 1629         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE)){
1869f3 1630             if(collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
C 1631                 refundStatus = OrderTotalConstants.STATUS_REFUND_PART;
1632             }else{
1633                 refundStatus = OrderTotalConstants.STATUS_REFUND_NONE;
1634             }
ae6ff7 1635         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
1869f3 1636             refundStatus = OrderTotalConstants.STATUS_REFUND_FINSH;
C 1637             refundNum = orderItem.getBuyNum();
ae6ff7 1638         }else {
1869f3 1639             refundStatus = OrderTotalConstants.STATUS_REFUND_NONE;
ae6ff7 1640         }
C 1641
1869f3 1642         //更新子订单信息
99213f 1643         updateOrderItemOne(orderItem,refundStatus,refundCarryVo,refundNum,commonService);
1869f3 1644
C 1645         return refundCarryVo;
ae6ff7 1646     }
C 1647
1869f3 1648     /**退款-处理二级子订单未执行划扣   项目类型
a1c527 1649      * @param refundRecord 退款总记录
C 1650      * @param refundRecordItem 退款一级子单
1651      * @param refundRecordItemSource  退款二级子单
1652      * @param refundCarryVo 全局携带参数接口
1653      * @param commonService 映射
ae6ff7 1654      */
1869f3 1655     private static RefundCarryVo handRefundNoSonExecution(RefundRecord refundRecord,RefundRecordItem refundRecordItem, RefundRecordItemSource refundRecordItemSource
e2a6c2 1656             ,RefundCarryVo refundCarryVo,String userCardId,CommonService commonService,DeductionSingleService deductionSingleService) {
ae6ff7 1657
C 1658         //判断操作完了去修改子订单状态
510678 1659         OrderItemSon orderItemSon = commonService.selectOneByKey(OrderItemSonMapper.class,refundRecordItemSource.getOrderItemSonId());
ae6ff7 1660         if (orderItemSon==null){
510678 1661             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到二级子订单信息[02]");
ae6ff7 1662         }
e2a6c2 1663
C 1664         //先作废划扣,不然数量对不上
4215f9 1665         deductionCancel(refundRecord,refundRecordItemSource.getId(),commonService,deductionSingleService);
ae6ff7 1666
C 1667         UserProjectItem userProjectItem = getUserProject(orderItemSon.getId(),commonService);
1668         if(userProjectItem == null){
510678 1669             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"用户项目获取失败[06]!");
ae6ff7 1670         }
C 1671         if(userProjectItem.getNotUsedNum()<refundRecordItemSource.getRefundNum()){
1672             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款次数大于可退次数[83]!");
1673         }
1674
1675         //计算子单是否还有剩余的可扣疗程数
1676         int surplusNum = orderItemSon.getUsedTotal() - orderItemSon.getHasReNum();
1677         if(refundRecordItemSource.getRefundNum() > surplusNum){
510678 1678             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款次数大于可退次数[56]!");
ae6ff7 1679         }
C 1680
1869f3 1681         //处理用户项目,减去用户项目数量
C 1682         UserProjectDeductionVo userProjectDeductionVo= UserProjectTool.userProjectDeduction(userProjectItem,UserProjectUsedCon.USED_METHOD_ORDER_REFUND,UserProjectUsedCon.USED_TYPE_DEDUCTION,null
ae6ff7 1683                 ,refundRecordItemSource.getId(),refundRecordItemSource.getRefundNum(),refundRecord.getOperatorAppId(),refundRecord.getOperatorAppName(),refundRecord.getRefundShopId(),refundRecord.getRefundShopName(),"员工备注:"+refundRecord.getRemarks()+"|用户备注:"+refundRecord.getRefundReason(),commonService);
2a45d4 1684
C 1685         refundCarryVo.setDeductionTotalUser(userProjectDeductionVo.getDeductionTotal());
ae6ff7 1686
a1c527 1687         int refundStatus;
ae6ff7 1688         if(surplusNum == refundRecordItemSource.getRefundNum()){
C 1689             refundStatus=OrderTotalConstants.STATUS_REFUND_FINSH;
1690         }else{
1691             refundStatus=OrderTotalConstants.STATUS_REFUND_PART;
1692         }
1693
1869f3 1694         //处理退款支付方式
99213f 1695         refundCarryVo = refundRecordMotnedItemTwoHandle(refundRecord,refundRecordItemSource,refundCarryVo,commonService);
C 1696         //更新子单信息
1697         updateOrderItemTwo(orderItemSon,refundStatus,refundCarryVo,refundRecordItemSource.getRefundNum(),commonService);
1869f3 1698
C 1699         if(refundRecordItem.getType().equals(OrderItemConstants.CARD_BAG)){
1700             //是卡包的,刪除卡包使用
b91aa3 1701             deleteUserCardUsed(userCardId,orderItemSon.getCardItemInfoId(),orderItemSon.getId(),orderItemSon.getOrderId(),refundRecordItemSource.getRefundNum(),commonService);
ae6ff7 1702         }
C 1703
1869f3 1704         return refundCarryVo;
ae6ff7 1705     }
1869f3 1706
C 1707     /**退款二级是商品
a1c527 1708      * @param refundRecord 退款总记录
C 1709      * @param refundRecordItem 退款一级子单
1710      * @param refundRecordItemSource  退款二级子单
1711      * @param refundCarryVo 全局携带参数结构
1712      * @param commonService 映射
1713      * @return 全局携带参数结构
ae6ff7 1714      */
a1c527 1715     private static RefundCarryVo handRefundSonRerail(RefundRecord refundRecord,RefundRecordItem refundRecordItem, RefundRecordItemSource refundRecordItemSource
b91aa3 1716             ,RefundCarryVo refundCarryVo,String userCardId,CommonService commonService) {
ae6ff7 1717
C 1718         //判断操作完了去修改子订单状态
1869f3 1719         OrderItemSon orderItemSon=commonService.selectOneByKey(OrderItemSonMapper.class,refundRecordItemSource.getOrderItemSonId());
C 1720         if (orderItemSon==null){
ae6ff7 1721             throw new PlatTipsException(PlatformCode.ERROR_PARAMETER_NULL,"未找到二级子订单信息");
C 1722         }
1723
1869f3 1724         //计算子单是否还有剩余的可扣疗程数
C 1725         int surplusNum = orderItemSon.getBuyNum() - orderItemSon.getHasReNum();
1726         if(refundRecordItemSource.getRefundNum() > surplusNum){
1727             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款次数大于可退次数[84]!");
ae6ff7 1728         }
C 1729
a1c527 1730         int refundStatus;
1869f3 1731         if(surplusNum == refundRecordItemSource.getRefundNum()){
C 1732             refundStatus=OrderTotalConstants.STATUS_REFUND_FINSH;
1733         }else{
1734             refundStatus=OrderTotalConstants.STATUS_REFUND_PART;
1735         }
1736
1737         //处理退款支付方式
99213f 1738         refundCarryVo = refundRecordMotnedItemTwoHandle(refundRecord,refundRecordItemSource,refundCarryVo,commonService);
C 1739
e490fa 1740         //子单信息处理
99213f 1741         updateOrderItemTwo(orderItemSon,refundStatus,refundCarryVo,refundRecordItemSource.getRefundNum(),commonService);
a1c527 1742
C 1743         if(refundRecordItem.getType().equals(OrderItemConstants.CARD_BAG)){
1744             //是卡包的,刪除卡包使用
b91aa3 1745             deleteUserCardUsed(userCardId,orderItemSon.getCardItemInfoId(),orderItemSon.getId(),orderItemSon.getOrderId(),refundRecordItemSource.getRefundNum(),commonService);
a1c527 1746         }
1869f3 1747
C 1748         return refundCarryVo;
1749     }
1750
1751     /**更新订单一级子单的信息
1752      * @param orderItem 订单子单
1753      * @param refundStatus 退款状态
99213f 1754      * @param refundCarryVo 传参
160c33 1755      * @param refundNum 退款数量 正负数
1869f3 1756      * @param commonService 映射
C 1757      */
99213f 1758     public static void updateOrderItemOne(OrderItem orderItem,Integer refundStatus,RefundCarryVo refundCarryVo,Integer refundNum
1869f3 1759             ,CommonService commonService){
C 1760         SqlSentence sqlSentence = new SqlSentence();
1761         Map<String,Object> values = new HashMap<>();
1762
510678 1763         values.put("id", orderItem.getId());
1869f3 1764         values.put("refundStatus", refundStatus);
C 1765         values.put("oldHasReNum",orderItem.getHasReNum());
99213f 1766         values.put("refundNum",refundNum);
568375 1767         values.put("reTotal",refundCarryVo.getRefundTotal());
99213f 1768         values.put("reIntegralTotal",refundCarryVo.getIntegralTotal());
C 1769         values.put("reCashTotal",refundCarryVo.getCashTotal());
1770         values.put("reCashPurenessTotal",refundCarryVo.getCashPurenessTotal());
1771         values.put("reRechargeTotal",refundCarryVo.getRechargeTotal());
1772         values.put("reIncrementTotal",refundCarryVo.getIncrementTotal());
568375 1773         sqlSentence.sqlUpdate(" refundStatus=#{m.refundStatus},reTotal=reTotal+#{m.reTotal},hasReNum=hasReNum+#{m.refundNum}" +
e490fa 1774                 ",reIntegralTotal = reIntegralTotal+#{m.reIntegralTotal},reCashTotal = reCashTotal+#{m.reCashTotal},reCashPurenessTotal = reCashPurenessTotal+#{m.reCashPurenessTotal}" +
C 1775                 ",reRechargeTotal = reRechargeTotal+#{m.reRechargeTotal},reIncrementTotal = reIncrementTotal+#{m.reIncrementTotal}" +
510678 1776                 " WHERE isDel = 0 AND id = #{m.id} AND hasReNum = #{m.oldHasReNum}",values);
1869f3 1777         if(commonService.updateWhere(OrderItemMapper.class,sqlSentence) != 1){
C 1778             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"当前订单信息已发生变化,请重试[012]!");
1779         }
1780     }
1781
1782     /**更新订单二级子单的信息
1783      * @param orderItemSon 订单子单
1784      * @param refundStatus 退款状态
99213f 1785      * @param refundCarryVo 传参
1869f3 1786      * @param refundNum 退款数量
C 1787      * @param commonService 映射
1788      */
99213f 1789     public static void updateOrderItemTwo(OrderItemSon orderItemSon,Integer refundStatus,RefundCarryVo refundCarryVo,Integer refundNum
1869f3 1790             ,CommonService commonService){
C 1791         SqlSentence sqlSentence = new SqlSentence();
1792         Map<String,Object> values = new HashMap<>();
1793
1794         values.put("id", orderItemSon.getId());
1795         values.put("refundStatus", refundStatus);
1796         values.put("oldHasReNum",orderItemSon.getHasReNum());
568375 1797         values.put("reTotal",refundCarryVo.getRefundTotal());
99213f 1798         values.put("refundNum",refundNum);
C 1799         values.put("reIntegralTotal",refundCarryVo.getIntegralTotal());
1800         values.put("reCashTotal",refundCarryVo.getCashTotal());
1801         values.put("reCashPurenessTotal",refundCarryVo.getCashPurenessTotal());
1802         values.put("reRechargeTotal",refundCarryVo.getRechargeTotal());
1803         values.put("reIncrementTotal",refundCarryVo.getIncrementTotal());
568375 1804         sqlSentence.sqlUpdate(" refundStatus = #{m.refundStatus},reTotal=reTotal+#{m.reTotal},hasReNum=hasReNum+#{m.refundNum}" +
e490fa 1805                 ",reIntegralTotal = reIntegralTotal+#{m.reIntegralTotal},reCashTotal = reCashTotal+#{m.reCashTotal},reCashPurenessTotal = reCashPurenessTotal+#{m.reCashPurenessTotal}" +
C 1806                 ",reRechargeTotal = reRechargeTotal+#{m.reRechargeTotal},reIncrementTotal = reIncrementTotal+#{m.reIncrementTotal}" +
1869f3 1807                 " where isDel=0 AND id = #{m.id} AND hasReNum = #{m.oldHasReNum}",values);
C 1808         if(commonService.updateWhere(OrderItemSonMapper.class,sqlSentence) != 1){
1809             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"当前订单信息已发生变化,请重试[012]!");
1810         }
1811     }
1812
a1c527 1813     /**获取订单一级子单的支付方式记录
C 1814      * @param orderItemId 订单一级子单标识
1815      * @param commonService 映射
1816      * @return 订单一级子单的支付方式记录
1869f3 1817      */
C 1818     public static List<ConsumePayItem> getOrderItemOneConsumePay(String orderItemId,CommonService commonService){
1819
1820         SqlSentence sqlSentence = new SqlSentence();
1821         Map<String,Object> values = new HashMap<>();
1822
1823         //获取子单的支付方式,一级子单支付记录,计算可退款金额
1824         values.put("typeId",orderItemId);
1825         sqlSentence.sqlSentence("SELECT * FROM consume_pay_item WHERE isDel = 0 AND typeId = #{m.typeId}",values);
2a45d4 1826         return commonService.selectList(ConsumePayItemMapper.class,sqlSentence);
1869f3 1827     }
C 1828
a1c527 1829     /**获取订单二级子单的支付方式记录
C 1830      * @param orderItemId 订单一级子单标识
1831      * @param commonService 映射
1832      * @return 订单二级子单的支付方式记录
1869f3 1833      */
C 1834     public static List<ConsumePayItem> getOrderItemTwoConsumePay(String orderItemId,CommonService commonService){
1835
1836         SqlSentence sqlSentence = new SqlSentence();
1837         Map<String,Object> values = new HashMap<>();
1838
1839         //获取子单的支付方式,一级子单支付记录,计算可退款金额
1840         values.put("typeId",orderItemId);
1841         sqlSentence.sqlSentence("SELECT * FROM consume_pay_item_son WHERE isDel = 0 AND typeId = #{m.typeId}",values);
2a45d4 1842         List<ConsumePayItemSon> consumePayItemSonList = commonService.selectList(ConsumePayItemSonMapper.class,sqlSentence);
C 1843         List<ConsumePayItem> consumePayItemList = new ArrayList<>();
1844         ConsumePayItem consumePayItem;
1845         for(ConsumePayItemSon consumePayItemSon:consumePayItemSonList){
1846             consumePayItem = new ConsumePayItem();
1847             BeanUtils.copyProperties(consumePayItemSon,consumePayItem);
1848             consumePayItemList.add(consumePayItem);
1849         }
1850         return consumePayItemList;
ae6ff7 1851     }
C 1852
1853     /**保存退款方式和支付方式关联
1854      * @param refundTotal 退款金额
1855      * @param commonType 子单级别,可空
1856      * @param commonId 子单标识,可空
1857      * @param orderId  总单标识
1858      * @param numberNo 支付方式编号
1859      * @param name 支付方式名称
1860      * @param consumePayId 支付方式记录标识
1861      * @param refundMethodId 退款方式标识
1862      * @param refundRecordItemId 退款子记录标识,可空
1863      * @param refundRecordId 退款总记录标识
1864      * @param commonService 映射
1865      * @return 返回关联记录
1866      */
1867     public static RefundRecordConsumePay insertRefundRecordConsumePay(BigDecimal refundTotal, String commonType, String commonId, String orderId
2a45d4 1868             , String numberNo,String name,Integer isMoneyPay,Integer isExecute, String consumePayId, String refundMethodId,String refundRecordItemId,String refundRecordId,CommonService commonService){
ae6ff7 1869         //生成关联记录
C 1870         RefundRecordConsumePay refundRecordConsumePay = new RefundRecordConsumePay();
1871         refundRecordConsumePay.setRefundTotal(refundTotal);
1872         refundRecordConsumePay.setCommonType(commonType);
1873         refundRecordConsumePay.setCommonId(commonId);
1874         refundRecordConsumePay.setOrderId(orderId);
1875         refundRecordConsumePay.setName(name);
1876         refundRecordConsumePay.setNumberNo(numberNo);
2a45d4 1877         refundRecordConsumePay.setIsMoneyPay(isMoneyPay);
C 1878         refundRecordConsumePay.setIsExecute(isExecute);
ae6ff7 1879         refundRecordConsumePay.setConsumePayId(consumePayId);
C 1880         refundRecordConsumePay.setRefundMethodId(refundMethodId);
1881         refundRecordConsumePay.setRefundRecordItemId(refundRecordItemId);
1882         refundRecordConsumePay.setRefundRecordId(refundRecordId);
1883         commonService.insert(RefundRecordConsumePayMapper.class,refundRecordConsumePay);
1884         return refundRecordConsumePay;
1885     }
1886
1887     /**获取可退款的用户卡项
1888      * @param sourceId 订单子单标识
1889      * @return 可退款的用户卡项
1890      */
160c33 1891     public static List<UserCard> getRefundCard(String sourceId,int effectiveStatus,CommonService commonService){
ae6ff7 1892         SqlSentence sqlSentence = new SqlSentence();
C 1893         Map<String,Object> sqlMap = new HashMap<>();
1894         //获取用户卡项
1895         sqlMap.put("sourceId",sourceId);
1896         sqlMap.put("status",UserCard.TYPE_NO_USED);
160c33 1897         sqlMap.put("effectiveStatus",effectiveStatus);
ae6ff7 1898         sqlSentence.sqlSentence("SELECT * FROM user_card WHERE isDel = 0 AND sourceId = #{m.sourceId} AND status = #{m.status}" +
C 1899                 " AND effectiveStatus = #{m.effectiveStatus} AND turnAddId IS NULL",sqlMap);
949373 1900         List<UserCard> userCardList = commonService.selectList(UserCardMapper.class,sqlSentence);
C 1901         if(userCardList.size() == 0){
1902             return userCardList;
1903         }
ea4351 1904
949373 1905         //获取已经部分退的用户卡包数量
ea4351 1906         List<RefundRecordItem> refundRecordItemList = CardRefundTool.findRefundUserCard(sourceId,null,commonService);
949373 1907         //过滤掉没有使用但有部分退款
C 1908         if(refundRecordItemList.size() == 0){
1909             return userCardList;
1910         }
1911
1912         Map<String,UserCard> userCardMap = new HashMap<>();
1913         for(UserCard userCard:userCardList){
1914             userCardMap.put(userCard.getId(),userCard);
1915         }
1916         //去除掉参与部分退款的用户卡包
1917         for(RefundRecordItem refundRecordItem:refundRecordItemList){
1918             userCardMap.remove(refundRecordItem.getUserCardId());
1919         }
1920
1921         userCardList = new ArrayList<>();
ea4351 1922         List<UserCardUsed> userCardUsedList;
949373 1923         for (Map.Entry<String,UserCard> entry : userCardMap.entrySet()) {
ea4351 1924             //获取使用记录,如果有使用记录,那么就跳过
C 1925             userCardUsedList = UserCardTool.getUsedRecord(entry.getValue().getId(),null,null,commonService);
1926             if(userCardUsedList.size() > 0){
1927                 continue;
1928             }
949373 1929             userCardList.add(entry.getValue());
C 1930         }
1931
1932         return userCardList;
ae6ff7 1933
C 1934     }
1935
1936     /**获取用户项目*/
1937     public static UserProjectItem getUserProject(String commonId,CommonService commonService){
1938         SqlSentence sqlSentence = new SqlSentence();
1939         Map<String, Object> map = new HashMap<>();
1940
1941         map.put("commonId",commonId);
1942         sqlSentence.sqlSentence("select * from user_project_item where isDel=0 and commonId=#{m.commonId} and isTransfer = 0",map);
a1c527 1943         return commonService.selectOne(UserProjectItemMapper.class,sqlSentence);
dd4c9b 1944     }
C 1945
e2a6c2 1946     /**作废划扣记录
C 1947      * @param refundRecordItemId 退款子记录标识(RefundRecordItem/RefundRecordItemSource)
4215f9 1948      * @param refundRecord 退款总记录
e2a6c2 1949      * @param commonService 映射
C 1950      * @param deductionSingleService 映射
1951      */
4215f9 1952     public static void deductionCancel(RefundRecord refundRecord,String refundRecordItemId, CommonService commonService, DeductionSingleService deductionSingleService){
e2a6c2 1953
C 1954         SqlSentence sqlSentence = new SqlSentence();
1955         Map<String,Object> values = new HashMap<>();
1956
1957         values.put("refundRecordItemId",refundRecordItemId);
1958         sqlSentence.sqlSentence("SELECT * FROM refund_deduction_cancel WHERE isDel = 0 AND refundRecordItemId = #{m.refundRecordItemId}",values);
1959         List<RefundDeductionCancel> refundDeductionCancelList = commonService.selectList(RefundDeductionCancelMapper.class,sqlSentence);
1960
a88f0b 1961         //变更状态
C 1962         values.put("status",RefundDeductionCancel.STATUS_CANCEL);
1963         values.put("statusNot",RefundDeductionCancel.STATUS_NOT);
1964         sqlSentence.sqlUpdate("status = #{m.status} WHERE id = #{m.id} AND status = #{m.statusNot}",values);
1965
e2a6c2 1966         //开始作废划扣
C 1967         DeductionDto deductionDto;
1968         for(RefundDeductionCancel refundDeductionCancel:refundDeductionCancelList){
a88f0b 1969             if(refundDeductionCancel.getStatus() == RefundDeductionCancel.STATUS_CANCEL){
C 1970                 continue;
1971             }
e2a6c2 1972             deductionDto = new DeductionDto();
C 1973             deductionDto.setDeductionSingleId(refundDeductionCancel.getDeductionSingleId());
4215f9 1974             deductionDto.setOperatorId(refundRecord.getOperatorId());
C 1975             deductionSingleService.deleteOne(deductionDto,refundRecord.getOperatorAppId(),refundRecord.getOperatorAppName(),DeductionSingleConstants.STATUS_RESCINDED, BaseEntity.NO);
a88f0b 1976
C 1977             //变更状态
1978             values.put("id",refundDeductionCancel.getId());
1979             if(commonService.updateWhere(RefundDeductionCancelMapper.class,sqlSentence) != 1){
1980                 throw new TipsException("作废划扣记录失败");
1981             }
e2a6c2 1982         }
C 1983     }
1984
ae6ff7 1985 }