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