ANDRU-PC\Andru
2023-10-08 572fd8325c78965f462cc19847033dac86fc5be6
提交 | 用户 | age
4dc6e5 1 package com.hx.phip.service.order.impl;
Z 2
3 import com.alibaba.fastjson.JSON;
42a0e7 4 import com.alibaba.fastjson.JSONArray;
9d4e6f 5 import com.alibaba.fastjson.JSONObject;
4dc6e5 6 import com.hx.common.service.CommonService;
a2fbbf 7 import com.hx.exception.TipsException;
4dc6e5 8 import com.hx.mybatisTool.SqlSentence;
f13adb 9 import com.hx.phiappt.common.*;
575cd4 10 import com.hx.phiappt.constants.tool.PerformanceInfoTool;
9198b5 11 import com.hx.phiappt.constants.tool.TimerHandleTool;
f23452 12 import com.hx.phiappt.constants.tool.clubEquity.ClubEquityTool;
9d4e6f 13 import com.hx.phiappt.model.*;
edf5ea 14 import com.hx.phiappt.model.activity.ActivityAction;
Z 15 import com.hx.phiappt.model.activity.ActivityRule;
e3b9cc 16 import com.hx.phiappt.model.consume.ConsumeNotify;
e118d7 17 import com.hx.phiappt.model.consume.ConsumePay;
c38ec7 18 import com.hx.phiappt.model.coupon.CouponOrderDiscountLog;
46bedb 19 import com.hx.phiappt.model.order.*;
071df8 20 import com.hx.phiappt.model.performance.PerformanceInfo;
36bc5e 21 import com.hx.phiappt.model.refund.*;
a2fbbf 22 import com.hx.phiappt.model.user.UserCard;
431d07 23 import com.hx.phiappt.model.user.UserProjectItem;
c9e2be 24 import com.hx.phiappt.model.userMoney.UserMoneyUnclaimed;
e3b9cc 25 import com.hx.phiappt.vo.refund.RefundCashItemVo;
C 26 import com.hx.phiappt.vo.refund.RefundCashVo;
f23452 27 import com.hx.phip.config.BotoxClubConfig;
4dc6e5 28 import com.hx.phip.config.CustomParameter;
Z 29 import com.hx.phip.dao.mapper.*;
4df03d 30 import com.hx.phip.service.CreateNoService;
4dc6e5 31 import com.hx.phip.service.PaymentMethodService;
7c75e2 32 import com.hx.phip.service.consume.ConsumeNotifyRefundService;
e2a6c2 33 import com.hx.phip.service.deduction.DeductionSingleService;
4dc6e5 34 import com.hx.phip.service.order.OrderRefundService;
Z 35 import com.hx.phip.service.refund.RefundRecordItemService;
36 import com.hx.phip.service.refund.RefundRecordMethodService;
37 import com.hx.phip.service.refund.RefundRecordService;
26ebce 38 import com.hx.phip.service.userLevel.UserLevelRuleService;
4dc6e5 39 import com.hx.phip.tool.CreateNo;
c40d5d 40 import com.hx.phip.tool.deduction.DeductionSingleTool;
e3b9cc 41 import com.hx.phip.tool.payment.ConsumeTool;
fd7281 42 import com.hx.phip.tool.refund.OrderRefundCancelTool;
a1c527 43 import com.hx.phip.tool.refund.PartialRefundUtil;
C 44 import com.hx.phip.tool.refund.PaymentCountTool;
a036dc 45 import com.hx.phip.tool.refund.RefundTool;
253802 46 import com.hx.phip.util.api.*;
4df03d 47 import com.hx.phip.vo.order.payment.PayMethodVo;
C 48 import com.hx.phip.vo.order.refund.DistributionRedundMethodVo;
49 import com.hx.phip.vo.order.refund.DistributionRedundVo;
9d4e6f 50 import com.hx.resultTool.Result;
4dc6e5 51 import com.hx.util.StringUtils;
254bde 52 import com.hz.crm.dto.order.refund.RefundAmountModelDto;
Z 53 import com.hz.crm.dto.order.refund.RefundDto;
54 import com.hz.crm.dto.order.refund.RefundReturnDto;
4dc6e5 55 import com.hz.crm.feign.FOderService;
b9b969 56 import com.hz.his.dto.aduit.AduitDto;
42a0e7 57 import com.hz.his.dto.marketing.OrderPartRefundDto;
Z 58 import com.hz.his.dto.marketing.PartRefundPayDto;
59 import com.hz.his.dto.marketing.RefundProjectDto;
c38ec7 60 import com.hz.his.dto.order.*;
f23452 61 import com.hz.his.feign.service.dcp.SUserTagInfoService;
4dc6e5 62 import com.hz.his.feign.service.marketing.MOrderService;
fd7281 63 import com.hz.his.vo.order.refund.RefundCancelVo;
c40d5d 64 import com.hz.his.vo.order.refund.RefundDeductionCancelVo;
e3b9cc 65 import com.hz.pay.feign.centre.refund.FRefundService;
4df03d 66 import com.platform.entity.ThirtApplication;
4dc6e5 67 import com.platform.exception.PlatTipsException;
Z 68 import com.platform.resultTool.PlatformCode;
69 import com.platform.resultTool.PlatformResult;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
9d4e6f 72 import org.springframework.beans.BeanUtils;
4dc6e5 73 import org.springframework.stereotype.Service;
Z 74 import org.springframework.transaction.annotation.Transactional;
75
76 import javax.annotation.Resource;
77 import java.math.BigDecimal;
118d96 78 import java.math.RoundingMode;
25d452 79 import java.util.*;
da4ad2 80 import java.util.stream.Collectors;
4dc6e5 81
Z 82 /**
832331 83  * @author  CJH
4df03d 84  * 重构与2023-03-20
4dc6e5 85  */
Z 86 @Transactional
87 @Service
88 public class OrderRefundServiceImpl implements OrderRefundService {
89
4df03d 90     /**log4j日志*/
C 91     private static final Logger logger = LoggerFactory.getLogger(OrderRefundServiceImpl.class.getName());
4dc6e5 92     @Resource
Z 93     private OrdersTotalMapper ordersTotalMapper;
94     @Resource
95     private OrderItemMapper orderItemMapper;
fd7281 96     @Resource
C 97     private RefundRecordMapper refundRecordMapper;
4dc6e5 98     @Resource
Z 99     private OrderItemSonMapper orderItemSonMapper;
100     @Resource
7c75e2 101     private ConsumeNotifyRefundService consumeNotifyRefundService;
26ebce 102     @Resource
A 103     private UserLevelRuleService userLevelRuleService;
4dc6e5 104
Z 105     @Resource
106     private CommonService commonService;
107
108     @Resource
109     private FOderService fOderService;
110
111     @Resource
112     private SystemParameterMapper systemParameterMapper;
113     @Resource
114     private RefundRecordService refundRecordService;
115     @Resource
116     private PaymentMethodService paymentMethodService;
117     @Resource
118     private RefundRecordMethodService refundRecordMethodService;
119     @Resource
120     private RefundRecordItemService refundRecordItemService;
121     @Resource
cd66da 122     private RefundRecordItemSourceMapper refundRecordItemSourceMapper;
Z 123     @Resource
4dc6e5 124     private CustomParameter customParameter;
Z 125     @Resource
126     private MOrderService mOrderService;
c38ec7 127
Z 128     @Resource
129     private CouponOrderDiscountLogMapper couponOrderDiscountLogMapper;
36bc5e 130     @Resource
Z 131     private RefundRecordCouponMapper refundRecordCouponMapper;
a2fbbf 132     @Resource
Z 133     private CardEquityMapper cardEquityMapper;
95147d 134     @Resource
4df03d 135     private RefundMapper refundMapper;
C 136     @Resource
137     private CreateNoService createNoService;
e3b9cc 138     @Resource
C 139     private FRefundService fRefundService;
e2a6c2 140     @Resource
C 141     private DeductionSingleService deductionSingleService;
f23452 142     @Resource
W 143     private SUserTagInfoService sUserTagInfoService;
144     @Resource
145     private BotoxClubConfig botoxClubConfig;
118d96 146
a2fbbf 147     /**
Z 148      * 获取退款页面详情
118d96 149      * @param ordersTotal 订单
4df03d 150      * @return 可退款数量详情
a2fbbf 151      */
Z 152     @Override
118d96 153     public List<Map<String, Object>> refundDetails(OrdersTotal ordersTotal) {
ae6ff7 154
a2fbbf 155         SqlSentence sqlSentence = new SqlSentence();
Z 156         Map<String, Object> sqlMap = new HashMap<>();
157         sqlSentence.setM(sqlMap);
118d96 158
a2fbbf 159         sqlMap.put("isDel", BaseEntity.NO);
118d96 160         sqlMap.put("orderId", ordersTotal.getId());
a2fbbf 161         //一级子订单
ae6ff7 162         sqlSentence.sqlSentence("SELECT * FROM order_item WHERE  orderId = #{m.orderId} AND isDel = #{m.isDel}",sqlMap);
a2fbbf 163         List<OrderItem> orderItemList = orderItemMapper.selectList(sqlSentence);
Z 164
165         List<Map<String, Object>> orderItems = new ArrayList<>();
166
167         for (OrderItem orderItem : orderItemList) {
168             //判断这个项目能不能显示处理
169             switch (orderItem.getType()) {
170                 case OrderItemConstants.TYPE_PROJECT:
4df03d 171                     handleOrderItemIsProject(orderItems,orderItem);
a2fbbf 172                     break;
Z 173                 case OrderItemConstants.TYPE_RETAIL:
4df03d 174                     handleOrderItemIsRetail(orderItems,orderItem);
a2fbbf 175                     break;
55dbe8 176                 case OrderItemConstants.TYPE_DRUG:
4df03d 177                     handleOrderItemIsRetail(orderItems, orderItem);
55dbe8 178                     break;
a2fbbf 179                 case OrderItemConstants.TYPE_CARD:
4df03d 180                     handleOrderItemIsCard(orderItems, orderItem);
a2fbbf 181                     break;
Z 182                 case OrderItemConstants.TYPE_PROMOTION:
4df03d 183                     handleOrderItemIsPromotion(orderItems, orderItem);
a2fbbf 184                     break;
Z 185                 case OrderItemConstants.CARD_BAG:
4df03d 186                     handleOrderItemIsCardBag(orderItems, orderItem);
89b4d7 187                     break;
F 188                 case OrderItemConstants.TYPE_COUPON:
189                     handleOrderItemIsRetail(orderItems,orderItem);
a2fbbf 190                     break;
Z 191                 default:
192                     break;
193             }
194         }
195         return orderItems;
196     }
da4ad2 197     /**
Z 198      * 处理一级是项目的
199      */
4df03d 200     public void handleOrderItemIsProject(List<Map<String, Object>> orderItems, OrderItem orderItem) {
118d96 201         //获取用户项目
ae6ff7 202         UserProjectItem userProjectItem = PartialRefundUtil.getUserProject(orderItem.getId(),commonService);
118d96 203         if(userProjectItem == null){
C 204             throw new TipsException("用户项目获取失败!");
a2fbbf 205         }
118d96 206
C 207         orderItems.add(itemRefandDataPackage(orderItem,null,userProjectItem,null));
208     }
209
210     /**订单子项退款信息封装*/
211     public Map<String,Object> itemRefandDataPackage(OrderItem orderItem,OrderItemSon orderItemSon,UserProjectItem userProjectItem,List<UserCard> userCardList){
212
213         Map<String,Object> itemData = new HashMap<>();
214         if(orderItemSon != null){
215             itemData.put("id",orderItemSon.getId());
216             itemData.put("type",orderItemSon.getType());
217             itemData.put("goodsName",orderItemSon.getGoodsName());
218             itemData.put("curPrice",orderItemSon.getCurPrice());
219             itemData.put("specs",orderItemSon.getSpecs());
220             itemData.put("buyNum",orderItemSon.getBuyNum());
221             itemData.put("hasReNum",orderItemSon.getHasReNum());
222             itemData.put("notUsedNum",orderItemSon.getBuyNum()-orderItemSon.getHasReNum());
223         }else{
224             itemData.put("id",orderItem.getId());
225             itemData.put("type",orderItem.getType());
226             itemData.put("goodsName",orderItem.getGoodsName());
227             itemData.put("curPrice",orderItem.getCurPrice());
228             itemData.put("specs",orderItem.getSpecs());
229             itemData.put("buyNum",orderItem.getBuyNum());
230             itemData.put("hasReNum",orderItem.getHasReNum());
231             itemData.put("notUsedNum",orderItem.getBuyNum()-orderItem.getHasReNum());
a2fbbf 232         }
118d96 233
C 234         if(userProjectItem != null){
235             itemData.put("notUsedNum",userProjectItem.getNotUsedNum());
a2fbbf 236         }
118d96 237         if(userCardList != null){
C 238             itemData.put("notUsedNum",userCardList.size());
a2fbbf 239         }
118d96 240         return itemData;
a2fbbf 241     }
Z 242
da4ad2 243     /**
Z 244      * 处理一级是商品的
245      */
4df03d 246     public void handleOrderItemIsRetail(List<Map<String, Object>> orderItems, OrderItem orderItem) {
118d96 247         orderItems.add(itemRefandDataPackage(orderItem,null,null,null));
a2fbbf 248     }
Z 249
da4ad2 250     /**
Z 251      * 处理一级是卡项的
252      */
4df03d 253     public void handleOrderItemIsCard(List<Map<String, Object>> orderItems,OrderItem orderItem) {
C 254
255         SqlSentence sqlSentence = new SqlSentence();
256         Map<String,Object> sqlMap = new HashMap<>();
a2fbbf 257
118d96 258         //获取用户卡项
160c33 259         List<UserCard> userCardList = PartialRefundUtil.getRefundCard(orderItem.getId(),UserProjectConstants.EFF_STATUS_YES,commonService);
a2fbbf 260
118d96 261         //信息封装
C 262         Map<String,Object> itemData = itemRefandDataPackage(orderItem,null,null,userCardList);
a2fbbf 263
ae6ff7 264         //获取卡项的详细条目
118d96 265         sqlMap.put("commonId",orderItem.getCommonId());
4df03d 266         sqlSentence.sqlSentence(" SELECT groupName,shareMoney FROM card_equity WHERE cardItemId = #{m.commonId} ",sqlMap);
118d96 267         List<Map<String, Object>> cardEquitys = cardEquityMapper.selectListMap(sqlSentence);
ae6ff7 268
118d96 269         itemData.put("list", cardEquitys);
C 270         orderItems.add(itemData);
a2fbbf 271
Z 272     }
273
da4ad2 274     /**
Z 275      * 处理一级是促销的
276      */
4df03d 277     public void handleOrderItemIsPromotion(List<Map<String, Object>> orderItems, OrderItem orderItem) {
a2fbbf 278
4df03d 279         SqlSentence sqlSentence = new SqlSentence();
C 280         Map<String,Object> sqlMap = new HashMap<>();
281
282         //封装参数
118d96 283         Map<String,Object> itemData = itemRefandDataPackage(orderItem,null,null,null);
a2fbbf 284
118d96 285         //获取二级子订单
a2fbbf 286         sqlMap.put("orderItemId", orderItem.getId());
4df03d 287         sqlSentence.sqlSentence("SELECT * FROM order_item_source WHERE orderItemId = #{m.orderItemId} AND isDel = 0 ",sqlMap);
a2fbbf 288         List<OrderItemSon> orderItemSonList = orderItemSonMapper.selectList(sqlSentence);
Z 289         if (orderItemSonList == null) {
290             return;
291         }
118d96 292
a2fbbf 293         List<Map<String, Object>> promotionList = new ArrayList<>();
Z 294
295         for (OrderItemSon orderItemSon : orderItemSonList) {
296             //判断这个项目能不能显示处理
297             switch (orderItemSon.getType()) {
298                 case OrderGoodsConstants.TYPE_PROJECT:
4df03d 299                     handleOrderItemSonIsProject(promotionList, orderItemSon);
a2fbbf 300                     break;
c02e62 301                 case OrderItemConstants.TYPE_RETAIL:
4df03d 302                     handleOrderItemSonIsRetail(promotionList, orderItemSon);
a2fbbf 303                     break;
Z 304                 default:
305                     break;
306             }
307         }
308
118d96 309         itemData.put("list", promotionList);
C 310         orderItems.add(itemData);
a2fbbf 311     }
da4ad2 312     /**
Z 313      * 处理一级是卡包
314      */
4df03d 315     public void handleOrderItemIsCardBag(List<Map<String, Object>> orderItems, OrderItem orderItem) {
C 316         SqlSentence sqlSentence = new SqlSentence();
317         Map<String,Object> sqlMap = new HashMap<>();
a2fbbf 318
118d96 319         Map<String,Object> itemData = itemRefandDataPackage(orderItem,null,null,null);
a2fbbf 320
Z 321         //二级子订单
322         sqlMap.put("orderItemId", orderItem.getId());
4df03d 323         sqlSentence.sqlSentence("SELECT * FROM order_item_source WHERE orderItemId= #{m.orderItemId} and  isDel = 0 ",sqlMap);
a2fbbf 324         List<OrderItemSon> orderItemSonList = orderItemSonMapper.selectList(sqlSentence);
Z 325         if (orderItemSonList == null) {
326             return;
327         }
328         List<Map<String, Object>> promotionList = new ArrayList<>();
329
330         for (OrderItemSon orderItemSon : orderItemSonList) {
331             //判断这个项目能不能显示处理
332             switch (orderItemSon.getType()) {
333                 case OrderGoodsConstants.TYPE_PROJECT:
4df03d 334                     handleOrderItemSonIsProject(promotionList, orderItemSon);
a2fbbf 335                     break;
c02e62 336                 case OrderItemConstants.TYPE_RETAIL:
4df03d 337                     handleOrderItemSonIsRetail(promotionList, orderItemSon);
a2fbbf 338                     break;
Z 339                 default:
340                     break;
341             }
342         }
343
118d96 344         itemData.put("list", promotionList);
C 345         orderItems.add(itemData);
a2fbbf 346     }
Z 347
da4ad2 348     /**
Z 349      * 处理二级是项目的
350      */
4df03d 351     public void handleOrderItemSonIsProject(List<Map<String, Object>> promotionList, OrderItemSon orderItemSon) {
C 352
118d96 353         //获取用户项目
ae6ff7 354         UserProjectItem userProjectItem = PartialRefundUtil.getUserProject(orderItemSon.getId(),commonService);
118d96 355         if(userProjectItem == null){
ae6ff7 356             throw new TipsException("用户项目获取失败[24]!");
118d96 357         }
C 358         Map<String,Object> itemData = itemRefandDataPackage(null,orderItemSon,userProjectItem,null);
a2fbbf 359
118d96 360         promotionList.add(itemData);
a2fbbf 361     }
Z 362
da4ad2 363
Z 364     /**
365      * 处理二级是商品的
366      */
4df03d 367     public void handleOrderItemSonIsRetail(List<Map<String, Object>> promotionList, OrderItemSon orderItemSon) {
118d96 368         promotionList.add(itemRefandDataPackage(null,orderItemSon,null,null));
a2fbbf 369     }
Z 370
371     /**
ae6ff7 372      * 退款选择退款数量组装金额信息,退款里面这个非常重要
4df03d 373      * @param orderRefundDto 退款数量信息
C 374      * @return 退款金额信息
a2fbbf 375      */
Z 376     @Override
118d96 377     public OrderRefundDto nextStep(OrdersTotal ordersTotal,OrderRefundDto orderRefundDto) {
25d452 378         logger.info("退款选择退款数量组装金额信息入参:{}", JSON.toJSONString(orderRefundDto));
a2fbbf 379
c04e8a 380         //子单退款
C 381         List<OrderItemRefundDto> refundList = orderRefundDto.getRefundList();
382         //支付方式退款数据整合
383         List<OrderPayMethodDto> refundPayMethods = new ArrayList<>();
a036dc 384         //可退款总金额
a2fbbf 385         BigDecimal totalAmount = BigDecimal.ZERO;
a036dc 386         //可退款总积分
C 387         BigDecimal totalIntegral = BigDecimal.ZERO;
a2fbbf 388
c04e8a 389         if (OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())) {
C 390             ///////充值订单退款
8b5222 391             refundPayMethods = rechargeRefundWay(ordersTotal);
C 392             for (OrderPayMethodDto orderPayMethodDto : refundPayMethods) {
a036dc 393                 if(PayMethodTypeConstants.PAY_INTEGRAL.equals(orderPayMethodDto.getPayMethodNo())){
C 394                     totalIntegral = totalIntegral.add(orderPayMethodDto.getPayTotal());
395                 }else{
396                     totalAmount = totalAmount.add(orderPayMethodDto.getPayTotal()).setScale(2,RoundingMode.HALF_UP);
397                 }
8b5222 398             }
c04e8a 399         }else{
C 400             //////其他订单类型
401             //整合支付方式退款金额
402             Map<String,OrderPayMethodDto> orderPayMethodDtoMap = new HashMap<>();
403             OrderPayMethodDto orderPayMethodDto;
118d96 404
4df03d 405             DistributionRedundVo distributionRedundVo;
C 406             OrderItem orderItem;
89b4d7 407
c04e8a 408             //计算每个条目需要退多少钱
C 409             for (OrderItemRefundDto orderItemRefundDto : refundList) {
4df03d 410                 if(StringUtils.isEmpty(orderItemRefundDto.getOrderItemId())){
C 411                     throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款项标识必填");
412                 }
413                 orderItem = orderItemMapper.selectOneByKey(orderItemRefundDto.getOrderItemId());
414                 if (orderItem == null) {
415                     throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款项标识错误");
416                 }
417                 if(!orderItem.getOrderId().equals(ordersTotal.getId())){
418                     throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到退款项[012]");
419                 }
2a45d4 420
c04e8a 421                 //判断这个项目能不能显示处理
4df03d 422                 switch (orderItem.getType()) {
c04e8a 423                     case OrderItemConstants.TYPE_PROJECT:
4df03d 424                         distributionRedundVo = itemOneRefund(orderItem,orderItemRefundDto);
c04e8a 425                         break;
C 426                     case OrderItemConstants.TYPE_RETAIL:
4df03d 427                         distributionRedundVo = itemOneRefund(orderItem,orderItemRefundDto);
c04e8a 428                         break;
C 429                     case OrderItemConstants.TYPE_DRUG:
4df03d 430                         distributionRedundVo = itemOneRefund(orderItem,orderItemRefundDto);
c04e8a 431                         break;
C 432                     case OrderItemConstants.TYPE_CARD:
4df03d 433                         distributionRedundVo = itemOneRefund(orderItem,orderItemRefundDto);
c04e8a 434                         break;
C 435                     case OrderItemConstants.TYPE_PROMOTION:
4df03d 436                         distributionRedundVo = nextStepIsPromotion(orderItem,orderItemRefundDto);
c04e8a 437                         break;
C 438                     case OrderItemConstants.CARD_BAG:
4df03d 439                         distributionRedundVo = nextStepIsPromotion(orderItem,orderItemRefundDto);
89b4d7 440                         break;
20d569 441                     case OrderItemConstants.TYPE_COUPON:
89b4d7 442                         distributionRedundVo = itemOneRefund(orderItem,orderItemRefundDto);
c04e8a 443                         break;
C 444                     default:
4df03d 445                         throw new TipsException("未知商品类型[008]!");
c04e8a 446                 }
4df03d 447
C 448                 //数据填充
449                 orderItemRefundDto.setApproveRefundTotal(distributionRedundVo.getRefundTotal());
450                 orderItemRefundDto.setType(distributionRedundVo.getGoodsType());
451                 orderItemRefundDto.setGoodsName(distributionRedundVo.getGoodsName());
452
a036dc 453                 //可退款金额计算
4df03d 454                 totalAmount = totalAmount.add(distributionRedundVo.getRefundTotal()).setScale(2,RoundingMode.HALF_UP);
a036dc 455                 //可退款积分计算
C 456                 totalIntegral = totalIntegral.add(distributionRedundVo.getRefundIntegral());
4df03d 457
C 458                 //整合可退款方式金额
459                 for(DistributionRedundMethodVo refundPaymentMethodVo:distributionRedundVo.getDistributionRedundMethodVoList()){
c04e8a 460                     orderPayMethodDto = orderPayMethodDtoMap.computeIfAbsent(refundPaymentMethodVo.getNumberNo(),
4df03d 461                             k->new OrderPayMethodDto(refundPaymentMethodVo.getNumberNo(),refundPaymentMethodVo.getName(),BigDecimal.ZERO,refundPaymentMethodVo.getIsMoneyPay(),refundPaymentMethodVo.getIsExecute()));
c04e8a 462                     orderPayMethodDto.setPayTotal(orderPayMethodDto.getPayTotal().add(refundPaymentMethodVo.getRefundTotal()).setScale(2,RoundingMode.HALF_UP));
C 463                 }
464             }
465
466             for(Map.Entry<String, OrderPayMethodDto> entry : orderPayMethodDtoMap.entrySet()) {
467                 refundPayMethods.add(entry.getValue());
c9e2be 468             }
a2fbbf 469         }
c9e2be 470
c04e8a 471         //支付方式
ae6ff7 472         orderRefundDto.setPayMethodList(refundPayMethods);
7f9228 473         //可退总金额
ae6ff7 474         orderRefundDto.setTotalAmount(totalAmount);
a036dc 475         //可退总积分
C 476         orderRefundDto.setTotalIntegral(totalIntegral);
7f9228 477         //优惠券
C 478         List<OrderCouponRefunDto> couponList = nextStepIsCoupon(ordersTotal.getId());
479         orderRefundDto.setPayCouponList(couponList);
480
ae6ff7 481         return orderRefundDto;
a2fbbf 482     }
da4ad2 483
c04e8a 484     /**获取充值单的退款方式金额*/
8b5222 485     public List<OrderPayMethodDto> rechargeRefundWay(OrdersTotal ordersTotal){
c9e2be 486
ae6ff7 487         //获取总支付方式
2a45d4 488         List<PayMethodVo> payMethodVoList = refundMapper.getConsumePayGroupByNumberNo(ordersTotal.getId());
542dc1 489
c04e8a 490         List<OrderPayMethodDto> consumeList = new ArrayList<>();
da4ad2 491         OrderPayMethodDto orderPayMethodDto;
c04e8a 492         //充值订单只能全退
ae6ff7 493         for (PayMethodVo payMethodVo:payMethodVoList) {
542dc1 494             //支付方式可退金额
da4ad2 495             orderPayMethodDto=new OrderPayMethodDto();
ae6ff7 496             orderPayMethodDto.setPayMethodNo(payMethodVo.getNumberNo());
C 497             orderPayMethodDto.setPayMethodName(payMethodVo.getName());
498             orderPayMethodDto.setRefundNumberNo(payMethodVo.getNumberNo());
499             orderPayMethodDto.setRefundNumberName(payMethodVo.getName());
500             orderPayMethodDto.setPayTotal(payMethodVo.getSurplusTotal());
da4ad2 501             orderPayMethodDto.setMoney(orderPayMethodDto.getPayTotal());
Z 502             consumeList.add(orderPayMethodDto);
254bde 503         }
542dc1 504         return consumeList;
a2fbbf 505     }
c04e8a 506
da4ad2 507     /**
Z 508      * 判断是否有使用优惠卷
509      */
510     public List<OrderCouponRefunDto> nextStepIsCoupon(String orderId) {
a2fbbf 511         SqlSentence sqlSentence = new SqlSentence();
Z 512         Map<String, Object> sqlMap = new HashMap<>();
4df03d 513
a2fbbf 514         sqlMap.put("isDel", BaseEntity.NO);
Z 515         sqlMap.put("orderId", orderId);
7f9228 516         sqlMap.put("status", BaseEntity.NO);
C 517         sqlSentence.sqlSentence("SELECT id,title FROM coupon_order_discount_log WHERE orderId=#{m.orderId} AND status = #{m.status} AND isDel=  #{m.isDel} ",sqlMap);
da4ad2 518         List<CouponOrderDiscountLog> couponOrderDiscountLogs = couponOrderDiscountLogMapper.selectList(sqlSentence);
Z 519         //拼接返回参数
520         List<OrderCouponRefunDto> consumeList=new ArrayList<>();
521         OrderCouponRefunDto orderCouponRefunDto;
522         for (CouponOrderDiscountLog couponOrderDiscountLog : couponOrderDiscountLogs) {
523             orderCouponRefunDto=new OrderCouponRefunDto();
524             orderCouponRefunDto.setOrderCouponId(couponOrderDiscountLog.getId());
525             orderCouponRefunDto.setOrderCouponTitle(couponOrderDiscountLog.getTitle());
526             consumeList.add(orderCouponRefunDto);
527         }
528
529         return consumeList;
a2fbbf 530     }
Z 531
da4ad2 532     /**
c04e8a 533      * 一级子单计算可退款金额
C 534      * @param orderItemRefundDto 封装的方法
535      * @return 退款金额
da4ad2 536      */
4df03d 537     public DistributionRedundVo itemOneRefund(OrderItem orderItem,OrderItemRefundDto orderItemRefundDto) {
c04e8a 538
C 539         if(orderItemRefundDto.getRefundNum() == null) {
540             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请填写退款数量!");
541         }
542         if(orderItemRefundDto.getRefundNum() < 1) {
542dc1 543             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款数量不能小于1");
c04e8a 544         }
C 545
546         ////算数量,退款用
547         //总数量
548         Integer buyNum;
549         //剩余数量
550         Integer surplusNum;
551
4df03d 552         if(OrderItemConstants.TYPE_PROJECT.equals(orderItem.getType())){
c04e8a 553             //////项目
ae6ff7 554             UserProjectItem userProjectItem = PartialRefundUtil.getUserProject(orderItem.getId(),commonService);
c04e8a 555             if(userProjectItem == null){
C 556                 throw new TipsException("用户项目获取失败!");
557             }
558             buyNum = userProjectItem.getUsedTotal();
559             surplusNum = userProjectItem.getNotUsedNum();
c40d5d 560             //加上划扣的数量
C 561             List<RefundDeductionCancelVo> refundDeductionCancelList = DeductionSingleTool.countDeductionData(userProjectItem.getId(),orderItemRefundDto.getRefundDeductionCancelList(),commonService);
562             orderItemRefundDto.setRefundDeductionCancelList(refundDeductionCancelList);
563             for(RefundDeductionCancelVo refundDeductionCancelVo:refundDeductionCancelList){
564                 surplusNum = surplusNum+refundDeductionCancelVo.getNum();
565             }
4df03d 566             if(orderItemRefundDto.getRefundNum() > surplusNum){
5fc368 567                 throw new TipsException("退款数量与可退数量不符[01]!");
4df03d 568             }
C 569             //替换成子单的剩余数量
570             surplusNum = orderItem.getUsedTotal() - orderItem.getHasReNum();
571         }else if(OrderItemConstants.TYPE_CARD.equals(orderItem.getType())){
c04e8a 572             ///////卡项
C 573             //获取可退款的卡项次数
160c33 574             List<UserCard> userCardList = PartialRefundUtil.getRefundCard(orderItem.getId(),UserProjectConstants.EFF_STATUS_YES,commonService);
c04e8a 575             buyNum = orderItem.getBuyNum();
C 576             surplusNum = userCardList.size();
1da3b3 577             if(orderItemRefundDto.getRefundNum() > surplusNum){
5fc368 578                 throw new TipsException("退款数量与可退数量不符[02]!");
1da3b3 579             }
949373 580             //替换成子单的剩余数量,2023-06-15因为做用户卡包退款原因,先屏掉这个
C 581             //surplusNum = orderItem.getBuyNum() - orderItem.getHasReNum();
118d96 582         }else{
c04e8a 583             buyNum = orderItem.getBuyNum();
1da3b3 584             //替换成子单的剩余数量
c04e8a 585             surplusNum = orderItem.getBuyNum() - orderItem.getHasReNum();
C 586         }
587         if(orderItemRefundDto.getRefundNum() > surplusNum){
5fc368 588             throw new TipsException("退款数量与可退数量不符[03]!");
118d96 589         }
2a0d69 590
ae6ff7 591         //获取该子单的支付方式,相同的支付方式求和返回
2a45d4 592         List<PayMethodVo> payMethodVoList = refundMapper.getConsumePayOneGroupByNumberNo(orderItem.getId());
c04e8a 593
dd4c9b 594         //获取该子单已退的总金额
a036dc 595         RefundRecordItem refundRecordItem = RefundTool.getOneAlreadyRefundTotal(orderItem.getId(),orderItem.getType(),commonService);
c04e8a 596
4df03d 597         //计算退款方式金额
a036dc 598         DistributionRedundVo distributionRedundVo = PaymentCountTool.countMakeWay(orderItem.getId(),orderItem.getActualTotal(),refundRecordItem.getOccupyRefundTotal()
C 599                 ,refundRecordItem.getOccupyRefundIntegral(),buyNum,surplusNum,null,orderItemRefundDto.getRefundNum(),payMethodVoList,commonService);
1869f3 600
4df03d 601         distributionRedundVo.setGoodsType(orderItem.getType());
C 602         distributionRedundVo.setGoodsName(orderItem.getGoodsName());
c04e8a 603
4df03d 604         return distributionRedundVo;
a2fbbf 605     }
Z 606
dd4c9b 607
da4ad2 608     /**
c04e8a 609      * 二级子单计算可退款金额
C 610      * @param orderItemSourceRefundDto 封装的方法
611      * @return 退款金额
da4ad2 612      */
4215f9 613     public DistributionRedundVo itemTwoRefund(OrderItemSon orderItemSon,OrderItemSourceRefundDto orderItemSourceRefundDto) {
c04e8a 614
C 615         if(orderItemSourceRefundDto.getRefundNum() == null) {
616             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请填写退款数量!");
617         }
618         if(orderItemSourceRefundDto.getRefundNum() < 1) {
542dc1 619             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款数量不能小于1");
a2fbbf 620         }
Z 621
1da3b3 622         ////算数量
C 623         //总数量
624         Integer buyNum;
625         //剩余数量
626         Integer surplusNum;
118d96 627
a036dc 628         UserProjectItem userProjectItem;
4215f9 629         if(OrderItemConstants.TYPE_PROJECT.equals(orderItemSon.getType())){
c04e8a 630             //获取用户项目
ae6ff7 631             userProjectItem = PartialRefundUtil.getUserProject(orderItemSon.getId(),commonService);
c04e8a 632             if(userProjectItem == null){
C 633                 throw new TipsException("用户项目获取失败!");
634             }
635             buyNum = userProjectItem.getUsedTotal();
636             surplusNum = userProjectItem.getNotUsedNum();
c40d5d 637             //加上划扣的数量
C 638             List<RefundDeductionCancelVo> refundDeductionCancelList = DeductionSingleTool.countDeductionData(userProjectItem.getId(),orderItemSourceRefundDto.getRefundDeductionCancelList(),commonService);
639             orderItemSourceRefundDto.setRefundDeductionCancelList(refundDeductionCancelList);
640             for(RefundDeductionCancelVo refundDeductionCancelVo:refundDeductionCancelList){
641                 surplusNum = surplusNum+refundDeductionCancelVo.getNum();
642             }
1da3b3 643             if(orderItemSourceRefundDto.getRefundNum() > surplusNum){
5fc368 644                 throw new TipsException("退款数量与可退数量不符[04]!");
c04e8a 645             }
1da3b3 646             //替换成子单
C 647             surplusNum = orderItemSon.getUsedTotal() - orderItemSon.getHasReNum();
648         }else{
649             buyNum = orderItemSon.getBuyNum();
650             surplusNum = orderItemSon.getBuyNum() - orderItemSon.getHasReNum();
c04e8a 651         }
1da3b3 652
c04e8a 653         if(orderItemSourceRefundDto.getRefundNum() > surplusNum){
5fc368 654             throw new TipsException("退款数量与可退数量不符[05]!");
c04e8a 655         }
C 656
657         //获取该子单的支付方式,相同的支付方式算和返回
2a45d4 658         List<PayMethodVo> payMethodVoList = refundMapper.getConsumePayTwoGroupByNumberNo(orderItemSon.getId());
c04e8a 659
a036dc 660         //获取该子单已退的总金额
8eea74 661         RefundRecordItemSource refundRecordItemSource = RefundTool.getTwoAlreadyRefundTotal(orderItemSon.getId(),commonService);
a036dc 662
4df03d 663         //计算退款方式金额
a036dc 664         DistributionRedundVo distributionRedundVo = PaymentCountTool.countMakeWay(orderItemSon.getId(),orderItemSon.getActualTotal(),refundRecordItemSource.getOccupyRefundTotal()
C 665                 ,refundRecordItemSource.getOccupyRefundIntegral(),buyNum,surplusNum,null,orderItemSourceRefundDto.getRefundNum(),payMethodVoList,commonService);
666
4df03d 667         distributionRedundVo.setGoodsType(orderItemSon.getType());
C 668         distributionRedundVo.setGoodsName(orderItemSon.getGoodsName());
669         return distributionRedundVo;
a2fbbf 670     }
Z 671
da4ad2 672     /**
Z 673      * 一级是促销
674      */
4df03d 675     public DistributionRedundVo nextStepIsPromotion(OrderItem orderItem,OrderItemRefundDto orderItemRefundDto) {
c04e8a 676
a2fbbf 677         List<OrderItemSourceRefundDto> orderItemSourceRefundDtos = orderItemRefundDto.getOrderItemSourceRefundDtos();
Z 678         if (orderItemSourceRefundDtos == null) {
542dc1 679             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款数量不能小于1");
d1b8f5 680         }
c04e8a 681
d1b8f5 682         //2022-12-29 荣爷说因为优惠卷超过了金额,数据库是负数,所以退款取0
Z 683         if(orderItem.getActualTotal().compareTo(BigDecimal.ZERO)<1){
684             orderItem.setActualTotal(BigDecimal.ZERO);
a2fbbf 685         }
Z 686
4df03d 687         //返回结构
C 688         DistributionRedundVo distributionRedundVo = new DistributionRedundVo();
c04e8a 689
4df03d 690         //整合当前一级子单的退款金额数据,key值:支付方式编号
C 691         Map<String,DistributionRedundMethodVo> refundPaymentMethodVoMap = new HashMap<>();
692         DistributionRedundMethodVo refundPaymentMethodVo;
693
694         DistributionRedundVo distributionRedundVoSon;
a2fbbf 695         for (OrderItemSourceRefundDto orderItemSourceRefundDto : orderItemSourceRefundDtos) {
4df03d 696             if(StringUtils.isEmpty(orderItemSourceRefundDto.getOrderItemSonId())){
C 697                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款项标识必填[54]");
a2fbbf 698             }
c04e8a 699
4df03d 700             OrderItemSon orderItemSon = orderItemSonMapper.selectOneByKey(orderItemSourceRefundDto.getOrderItemSonId());
C 701             if (orderItemSon == null) {
702                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款项标识错误[54]");
703             }
704
705             if (!orderItemSon.getOrderItemId().equals(orderItem.getId())) {
706                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到退款项[54]");
707             }
708
709             switch (orderItemSon.getType()) {
710                 case OrderGoodsConstants.TYPE_PROJECT:
4215f9 711                     distributionRedundVoSon = itemTwoRefund(orderItemSon,orderItemSourceRefundDto);
4df03d 712                     break;
C 713                 case OrderItemConstants.TYPE_RETAIL:
4215f9 714                     distributionRedundVoSon = itemTwoRefund(orderItemSon,orderItemSourceRefundDto);
4df03d 715                     break;
C 716                 case OrderItemConstants.TYPE_DRUG:
4215f9 717                     distributionRedundVoSon = itemTwoRefund(orderItemSon,orderItemSourceRefundDto);
4df03d 718                     break;
C 719                 default:
720                     throw new TipsException("未知商品类型[098]!");
721             }
722
723             //数据填充
724             orderItemSourceRefundDto.setType(distributionRedundVoSon.getGoodsType());
725             orderItemSourceRefundDto.setGoodsName(distributionRedundVoSon.getGoodsName());
726             orderItemSourceRefundDto.setApproveRefundTotal(distributionRedundVoSon.getRefundTotal());
727
728             //返回结构金额填充
729             distributionRedundVo.setRefundTotal(distributionRedundVo.getRefundTotal().add(distributionRedundVoSon.getRefundTotal()).setScale(2,RoundingMode.HALF_UP));
730             distributionRedundVo.setRefundCash(distributionRedundVo.getRefundCash().add(distributionRedundVoSon.getRefundCash()).setScale(2,RoundingMode.HALF_UP));
731             distributionRedundVo.setRefundExecute(distributionRedundVo.getRefundExecute().add(distributionRedundVoSon.getRefundExecute()).setScale(2,RoundingMode.HALF_UP));
732
c04e8a 733             //整合退款金额
4df03d 734             for(DistributionRedundMethodVo paymentMethodVo:distributionRedundVoSon.getDistributionRedundMethodVoList()){
c04e8a 735                 //整合金额,上级用到
C 736                 refundPaymentMethodVo = refundPaymentMethodVoMap.computeIfAbsent(paymentMethodVo.getNumberNo()
4df03d 737                         ,k-> new DistributionRedundMethodVo(paymentMethodVo.getNumberNo(),paymentMethodVo.getName(),BigDecimal.ZERO,paymentMethodVo.getIsMoneyPay(),paymentMethodVo.getIsExecute()));
c04e8a 738                 refundPaymentMethodVo.setRefundTotal(refundPaymentMethodVo.getRefundTotal().add(paymentMethodVo.getRefundTotal()).setScale(2,RoundingMode.HALF_UP));
C 739             }
740
a2fbbf 741         }
4df03d 742
C 743         //返回结构数据填充
744         distributionRedundVo.setGoodsName(orderItem.getGoodsName());
745         distributionRedundVo.setGoodsType(orderItem.getType());
a2fbbf 746
c04e8a 747         //整合退款金额的数据
4df03d 748         List<DistributionRedundMethodVo> distributionPayList = new ArrayList<>();
C 749         for(Map.Entry<String,DistributionRedundMethodVo> entry : refundPaymentMethodVoMap.entrySet()){
c04e8a 750             distributionPayList.add(entry.getValue());
C 751         }
4df03d 752         distributionRedundVo.setDistributionRedundMethodVoList(distributionPayList);
c04e8a 753
4df03d 754         return distributionRedundVo;
a2fbbf 755     }
Z 756
757     /**
25d452 758      * 确认退款处理退款逻辑
478fa9 759      * @param orderRefundDto 退款数据结构
C 760      * @return 结构
a2fbbf 761      */
4dc6e5 762     @Override
4df03d 763     public PlatformResult partRefund(OrdersTotal ordersTotal, OrderRefundDto orderRefundDto, ThirtApplication thirtApplication) {
25d452 764         logger.info("退款打印参数:{}", JSON.toJSONString(orderRefundDto));
c04e8a 765
C 766         if(OrderTotalConstants.PAY_STATUS_SUC != ordersTotal.getPayStatus()){
767             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"订单未支付!");
768         }
769         if(OrderTotalConstants.STATUS_PAY != ordersTotal.getStatus()
770                 && OrderTotalConstants.STATUS_WAIT_RECEIVE != ordersTotal.getStatus()
771                 && OrderTotalConstants.STATUS_DONE != ordersTotal.getStatus()){
772             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"订单不是已支付状态!");
4dc6e5 773         }
da4ad2 774
c04e8a 775         if(OrderTotalConstants.STATUS_REFUND_NONE != ordersTotal.getRefundStatus() &&
C 776                 OrderTotalConstants.STATUS_REFUND_PART != ordersTotal.getRefundStatus()){
777             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"订单退款状态不正确!");
da4ad2 778         }
c04e8a 779
C 780         //先优先改成申请退款中
da4ad2 781         SqlSentence sqlSentence = new SqlSentence();
Z 782         Map<String,Object> map=new HashMap<>();
4df03d 783
da4ad2 784         map.put("refundStatus",OrderTotalConstants.STATUS_REFUND_APPLY);
0a9391 785         map.put("isSyncOrder", BaseEntity.NO);
da4ad2 786         map.put("id",ordersTotal.getId());
4df03d 787         sqlSentence.sqlSentence(" refundStatus=#{m.refundStatus},isSyncOrder=#{m.isSyncOrder}  WHERE id=#{m.id}   AND refundStatus IN('"+OrderTotalConstants.STATUS_REFUND_NONE+"','"+OrderTotalConstants.STATUS_REFUND_PART+"')  ",map);
C 788         if(ordersTotalMapper.updateWhere(sqlSentence) != 1){
789             throw new TipsException("操作失败,当前订单退款状态不能再次发起退款!");
5425ba 790         }
4dc6e5 791
ae6ff7 792         //校验参数和获取系统参数,非常重要
4df03d 793         orderRefundDto = parameterVerification(ordersTotal,orderRefundDto);
4dc6e5 794
4df03d 795         return handlePartRefund(ordersTotal,orderRefundDto,thirtApplication);
4dc6e5 796     }
4df03d 797
da4ad2 798     /**
832331 799      * 退款校验参数,拼接参数
da4ad2 800      */
832331 801     @Override
C 802     public OrderRefundDto  parameterVerification(OrdersTotal ordersTotal, OrderRefundDto orderRefundDto){
2a45d4 803
C 804         if(orderRefundDto.getRefundPayMethod() == null){
805             throw new TipsException("退款方式结构不能空");
806         }
c04e8a 807
da4ad2 808         //怕被获取到项目信息收到被改了项目价格,重新去获取一下项目价格
4df03d 809         orderRefundDto =  nextStep(ordersTotal,orderRefundDto);
b9b969 810
8b5222 811         //可退款支付格式,key值:支付编号
4df03d 812         Map<String,OrderPayMethodDto> orderPayMethodDtoMap = new HashMap<>();
8b5222 813         for (OrderPayMethodDto orderPayMethodDto : orderRefundDto.getPayMethodList()) {
4df03d 814             orderPayMethodDtoMap.put(orderPayMethodDto.getPayMethodNo(),orderPayMethodDto);
da4ad2 815         }
4df03d 816
C 817         //填写退款的总金额
818         BigDecimal refundTotal = BigDecimal.ZERO;
819
820         //校验金额
821         OrderPayMethodDto payMethodDto;
822         //遍历系统获取到的可退款方式
8b5222 823         OrderPayMethodDto orderPayMethodDto;
C 824         for (int i = orderRefundDto.getRefundPayMethod().size()-1; i>=0 ;i--) {
825             orderPayMethodDto = orderRefundDto.getRefundPayMethod().get(i);
4df03d 826             //获取是传值过来的金额数据
C 827             payMethodDto = orderPayMethodDtoMap.get(orderPayMethodDto.getPayMethodNo());
828             if(payMethodDto == null){
829                 throw new TipsException("未找到["+orderPayMethodDto.getPayMethodName()+"]支付方式!");
830             }
ae6ff7 831             //判断退款方式
8b5222 832             PaymentMethod refundMethod = paymentMethodService.selectNumberNoUncheckUp(orderPayMethodDto.getRefundNumberNo());
ae6ff7 833             if(refundMethod==null){
C 834                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到该转换方式:"+orderPayMethodDto.getRefundNumberName()+"["+orderPayMethodDto.getRefundNumberNo()+"]");
835             }
8b5222 836             if(orderPayMethodDto.getMoney() == null){
4df03d 837                 throw new TipsException("["+orderPayMethodDto.getPayMethodName()+"]退款金额必填!");
C 838             }
8b5222 839             if(orderPayMethodDto.getMoney().compareTo(BigDecimal.ZERO) < 0){
4df03d 840                 throw new TipsException("["+orderPayMethodDto.getPayMethodName()+"]退款金额错误!");
C 841             }
8b5222 842             if (orderPayMethodDto.getMoney().compareTo(payMethodDto.getPayTotal()) > 0){
4df03d 843                 throw new TipsException("当前退款方式["+orderPayMethodDto.getPayMethodName()+"]金额超出可退金额!");
C 844             }
8b5222 845             //退款金额是0元,去掉退款方式
C 846             if(orderPayMethodDto.getMoney().compareTo(BigDecimal.ZERO) == 0){
847                 orderRefundDto.getRefundPayMethod().remove(i);
848             }
29ff38 849
C 850             //特殊的退款判断
d0ca72 851             RefundTool.paymemtCheck(orderPayMethodDto.getPayMethodNo(),orderPayMethodDto.getRefundNumberNo());
29ff38 852
8b5222 853             orderPayMethodDto.setPayMethodName(payMethodDto.getPayMethodName());
C 854             orderPayMethodDto.setPayMethodNo(payMethodDto.getPayMethodNo());
855             orderPayMethodDto.setPayTotal(payMethodDto.getPayTotal());
4df03d 856
8b5222 857             refundTotal = refundTotal.add(orderPayMethodDto.getMoney()).setScale(2,RoundingMode.HALF_UP);
4df03d 858
C 859         }
860         orderRefundDto.setRefundTotal(refundTotal);
861
862         if(orderRefundDto.getRefundTotal().compareTo(orderRefundDto.getTotalAmount()) > 0){
8b5222 863             throw new TipsException("退款金额不能大于可退金额[004]!");
4df03d 864         }
da4ad2 865
Z 866         return orderRefundDto;
867     }
868
869     /**
870      * 处理退款详情
871      */
4df03d 872     public PlatformResult handlePartRefund(OrdersTotal ordersTotal,OrderRefundDto orderRefundDto,ThirtApplication thirtApplication){
46bedb 873
Z 874         //订单节点日志
875         OrdersNodeLog ordersNodeLog = new OrdersNodeLog();
876         StringBuilder orderNodeBuilder = new StringBuilder();
877
04ce22 878         orderNodeBuilder.append("开始退款");
478fa9 879         orderNodeBuilder.append("-本次退款项目总金额:").append(orderRefundDto.getTotalAmount()).append(",客户选的退款方式总金额:").append(orderRefundDto.getRefundTotal());
da4ad2 880
4dc6e5 881         Map<String, String> operator = ApiOrderUtil.getOperator(commonService, orderRefundDto.getOperatorId());//获取操作人信息
Z 882         SqlSentence sqlSentence = new SqlSentence();
883         Map<String,Object> map=new HashMap<>();
884         sqlSentence.setM(map);
885         //退款总记录
46bedb 886         orderNodeBuilder.append("-处理退款总记录");
8eb9e6 887
fd7281 888         //保存退款信息,不是真正的退款,提前扣减用户资金
4df03d 889         RefundRecord refundRecord = insertRefundInfo(orderRefundDto,ordersTotal,orderNodeBuilder,thirtApplication);
c38ec7 890
9d4e6f 891         //判断已支付订单是否需要营销助手审批
Z 892         //记录取消日志
4df03d 893         CancelOrder cancelOrder = handleCancelOrder(ordersTotal,orderRefundDto);
9d4e6f 894
4df03d 895         if (orderRefundDto.getIsApproval().equals(BaseEntity.YES)){
4ebb90 896             //调用审批功能
4df03d 897             return handleApproval(ordersNodeLog,orderNodeBuilder,ordersTotal,cancelOrder,refundRecord);
9d4e6f 898         }
4df03d 899
C 900         //这里开始真正的退款到用户账户的
901         Map<String, Object> refund = handleRefundOrder(operator,refundRecord,ordersTotal,ordersNodeLog,orderNodeBuilder,cancelOrder);
9d4e6f 902         return PlatformResult.success(refund);
4df03d 903     }
C 904
905     /**保存退款信息
906      * 保存退款信息,并没有真正退款
907      */
832331 908     @Override
C 909     public RefundRecord insertRefundInfo(OrderRefundDto orderRefundDto, OrdersTotal ordersTotal
910             , StringBuilder orderNodeBuilder, ThirtApplication thirtApplication){
510678 911
C 912         //操作人
913         Employee employee = commonService.selectOneByKey(EmployeeMapper.class,orderRefundDto.getOperatorId());
914         if(employee == null){
915             throw new TipsException("操作人标识错误!");
c40d5d 916         }
C 917
918         if(!OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){
160d9e 919             if(orderRefundDto.getRefundList()== null || orderRefundDto.getRefundList().size() == 0){
C 920                 throw new TipsException("退款子项不能为空!");
c40d5d 921             }
510678 922         }
4df03d 923
C 924         ///////退款总表数据填充
925         //生成退款编号
926         String totalCode = createNoService.createNo("R",System.currentTimeMillis()+"",8);
927         RefundRecord refundRecord=new RefundRecord(totalCode,ordersTotal.getShopId(),ordersTotal.getShopName(),orderRefundDto.getRefundTotal()
928                 , RefundStatus.STATUS_APPLY_REFUND,0, RefundSoruceConstants.TYPE_SOURCE_ORDER,orderRefundDto.getRemarks(),ordersTotal.getId(),ordersTotal.getUserId());
510678 929         //操作人信息
4df03d 930         refundRecord.setOperatorType(RefundRecord.OPERATOR_TYPE_EMPLOYEE);
C 931         refundRecord.setOperatorId(employee.getId());
510678 932         refundRecord.setOperatorNo(employee.getEmployeeNo());
4df03d 933         refundRecord.setOperatorName(employee.getCnName());
510678 934
C 935         refundRecord.setRefundOperationType(orderRefundDto.getRefundOperationType());
4df03d 936         /////退款的备注
C 937         refundRecord.setRemarks(orderRefundDto.getRemarks());
938         refundRecord.setRefundReason(orderRefundDto.getRefundReason());
939         refundRecord.setOperatorAppId(thirtApplication.getAppId());
940         refundRecord.setOperatorAppCode(thirtApplication.getAppIdCode());
941         refundRecord.setOperatorAppName(thirtApplication.getName());
942         refundRecordService.insert(refundRecord);
943
944         //退款方式处理
ae6ff7 945         if(orderRefundDto.getRefundPayMethod() !=null && orderRefundDto.getRefundPayMethod().size() > 0){
510678 946             handleRefundPayMethod(orderRefundDto,orderNodeBuilder,ordersTotal,refundRecord);
4df03d 947         }
C 948
949         //退款的子项处理
950         if(orderRefundDto.getRefundList()!=null && orderRefundDto.getRefundList().size()>0){
510678 951             insertRefundRecordItem(orderRefundDto,orderNodeBuilder,refundRecord);
4df03d 952         }
C 953         //回退的优惠卷处理
954         if(orderRefundDto.getCouponList() != null && orderRefundDto.getCouponList().size()>0){
955             handleOrderCouponRefunDto(orderRefundDto.getCouponList(),orderNodeBuilder,ordersTotal,refundRecord);
956         }
957
160383 958         //*******扣减赠送的账户资金,如果订单有老带新的赠送规则,那么如果申请退款,就优先把老带新的退回来*****
C 959         //获取老带新记录
960         oldBlingNewRefund(refundRecord,orderNodeBuilder,commonService);
4ebb90 961
C 962         //判断是否是充值订单,是的话先冻结储值金,就是扣掉,审批通过就不处理储值金了,不通过还原资金
963         if(OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){
b3fdea 964             OrderRefundCancelTool.rechargeHandle(ordersTotal,refundRecord,OrderRefundCancelTool.OPT_TYPE_EXECUTE,"申请退款",orderNodeBuilder,commonService);
4ebb90 965         }
C 966         //活动处理
b3fdea 967         OrderRefundCancelTool.activityRuleHandle(ordersTotal,refundRecord,OrderRefundCancelTool.OPT_TYPE_EXECUTE,"申请退款",orderNodeBuilder,commonService);
160383 968
4df03d 969         return refundRecord;
edf5ea 970     }
Z 971
160383 972     /**老带新的订单退款,佣金处理*/
C 973     public void oldBlingNewRefund(RefundRecord refundRecord,StringBuilder orderNodeBuilder,CommonService commonService){
974
975         SqlSentence sqlSentence = new SqlSentence();
976         Map<String,Object> values = new HashMap<>();
977
978         //查找老带新记录,未删除且有效的,没有退回的
979         values.put("operationReason",OperationReasonConstants.OP_REASON_BRING_NEW_USER_GIFT);
980         values.put("orderId",refundRecord.getOrderId());
981         sqlSentence.sqlSentence("SELECT * FROM user_money_unclaimed mu WHERE mu.isDel = 0 AND mu.isValid = 1 AND mu.operationReason = #{m.operationReason}" +
982                 " AND mu.orderId = #{m.orderId} AND NOT EXISTS(SELECT * FROM refund_user_assets rua WHERE rua.isDel = 0 AND rua.status = 1" +
983                 " AND rua.amountStatus IN (1,3) AND rua.userMoneyUnclaimedId = mu.id)",values);
984         List<UserMoneyUnclaimed> userMoneyUnclaimedList = commonService.selectList(UserMoneyUnclaimedMapper.class,sqlSentence);
985         RefundUserAssets refundUserAssets;
986         UserMoney userMoney;
987         User user;
988         BigDecimal amount;
989         for (UserMoneyUnclaimed userMoneyUnclaimed:userMoneyUnclaimedList){
990             amount = BigDecimal.ZERO;
991             //生成记录
992             refundUserAssets = new RefundUserAssets();
993             refundUserAssets.setType(userMoneyUnclaimed.getOperationReason());
994             refundUserAssets.setStatus(RefundUserAssets.STATUS_NORMAL);
995             refundUserAssets.setAmountType(userMoneyUnclaimed.getFundType());
fd7281 996             refundUserAssets.setAmount(userMoneyUnclaimed.getOpNumber().negate());
160383 997             refundUserAssets.setOperatorId(refundRecord.getOperatorId());
C 998             refundUserAssets.setOperatorNo(refundRecord.getOperatorNo());
999             refundUserAssets.setOperatorName(refundRecord.getOperatorName());
1000             refundUserAssets.setOrderId(refundRecord.getOrderId());
1001             refundUserAssets.setRefundRecordId(refundRecord.getId());
1002             refundUserAssets.setUserMoneyUnclaimedId(userMoneyUnclaimed.getId());
1003             refundUserAssets.setUserId(userMoneyUnclaimed.getUserId());
1004
1005             user = commonService.selectOneByKey(UserMapper.class,refundUserAssets.getUserId());
1006             orderNodeBuilder.append("-退款处理老带新,扣减用户:").append(user.getName()).append(",CIQ:").append(user.getCIQ()).append(",");
1007             orderNodeBuilder.append(RefundUserAssets.amountTypeName(refundUserAssets.getAmountType())).append(refundUserAssets.getAmount());
1008             if(userMoneyUnclaimed.getStatus() == UserMoneyUnclaimed.STATUS_WAI){
1009                 refundUserAssets.setAmountStatus(RefundUserAssets.AMOUNT_STATUS_NOT_RECEIVE);
1010                 //用户未领取,那么直接作废,作废是逻辑删除
1011                 values.put("id",userMoneyUnclaimed.getId());
1012                 values.put("status",UserMoneyUnclaimed.STATUS_WAI);
1013                 sqlSentence.sqlUpdate("isDel = 1,isValid = 0 WHERE id = #{m.id} AND isDel = 0 AND isValid = 1 AND status = #{m.status}",values);
1014                 if(commonService.updateWhere(UserMoneyUnclaimedMapper.class,sqlSentence) != 1){
1015                     throw new TipsException("老带新资产记录状态已变化!");
1016                 }
1017
1018                 orderNodeBuilder.append(",用户未领取,作废领取记录");
1019             }else if(userMoneyUnclaimed.getStatus() == UserMoneyUnclaimed.STATUS_SUCCEED){
1020                 //用户已经领取了,那么要扣掉,但是,要先判断用户是否够,如果不够,那么也生成记录,显示未操作资金
1021                 values.clear();
1022                 values.put("userId",userMoneyUnclaimed.getUserId());
1023                 sqlSentence.sqlSentence("SELECT * FROM user_money WHERE isDel = 0 AND userId = #{m.userId}",values);
1024                 userMoney = commonService.selectOne(UserMoneyMapper.class,sqlSentence);
1025                 if(userMoneyUnclaimed.getFundType() == UserMoneyUnclaimed.FUND_TYPE_STORED_VALUE_FUND){
1026                     //储值金
1027                     if(userMoney.getStoredValueFund() != null){
1028                         amount = new BigDecimal(userMoney.getStoredValueFund());
1029                     }
1030                 }else if(userMoneyUnclaimed.getFundType() == UserMoneyUnclaimed.FUND_TYPE_VALUE_ADDED_FUND){
1031                     //增值金
1032                     if(userMoney.getValueAddedFund() != null){
1033                         amount = new BigDecimal(userMoney.getValueAddedFund());
1034                     }
1035                 }else if(userMoneyUnclaimed.getFundType() == UserMoneyUnclaimed.FUND_TYPE_INTEGRAL){
1036                     //预定金
1037                     if(userMoney.getDeposit() != null){
1038                         amount = new BigDecimal(userMoney.getDeposit());
1039                     }
1040                 }else if(userMoneyUnclaimed.getFundType() == UserMoneyUnclaimed.FUND_TYPE_DEPOSIT){
1041                     //积分
1042                     if(userMoney.getIntegral() != null){
1043                         amount = new BigDecimal(userMoney.getIntegral());
1044                     }
1045                 }else{
1046                     throw new TipsException("老带新资产记录金额类型未知!");
1047                 }
599080 1048                 if(amount.compareTo(refundUserAssets.getAmount().negate()) >= 0){
160383 1049                     //用户资产够减
C 1050                     orderNodeBuilder.append(",扣减成功");
1051                     refundUserAssets.setAmountStatus(RefundUserAssets.AMOUNT_STATUS_NORMAL);
1052                 }else {
1053                     orderNodeBuilder.append(",余额不足,扣减失败");
1054                     //用户资产不够减
1055                     refundUserAssets.setAmountStatus(RefundUserAssets.AMOUNT_STATUS_NOT);
1056                 }
1057             }else{
1058                 throw new TipsException("老带新资产记录状态错误!");
1059             }
1060
1061             if(refundUserAssets.getAmountStatus() == RefundUserAssets.AMOUNT_STATUS_NORMAL
1062                     || refundUserAssets.getAmountStatus() == RefundUserAssets.AMOUNT_STATUS_NOT_RECEIVE ){
1063                 //保存记录,正常扣减和未领取才去保存这个记录
1064                 commonService.insert(RefundUserAssetsMapper.class,refundUserAssets);
1065             }
1066
1067             //用户资金操作
1068             if(refundUserAssets.getAmountStatus() == RefundUserAssets.AMOUNT_STATUS_NORMAL){
1069                 UserMoneyUtil.setNewUserMoneyUnclaimed(refundUserAssets.getUserId(),refundRecord.getRemarks(),"退款:老带新资金回退",refundUserAssets.getOperatorId()
fd7281 1070                         ,refundRecord.getOrderId(),refundRecord.getOperatorAppCode(),refundUserAssets.getId(),refundUserAssets.getAmount(),refundUserAssets.getAmountType()
160383 1071                         ,OperationReasonConstants.OP_REASON_BRING_NEW_USER_GIFT_RETRUN,commonService,UserMoneyUnclaimed.YES);
C 1072             }
1073
1074         }
1075
1076     }
1077
1078     /**老带新的订单退款不通过或者作废,佣金处理*/
1079     public void oldBlingNewRefundFail(RefundRecord refundRecord,StringBuilder orderNodeBuilder,CommonService commonService) {
1080
1081         ////订单退款状态是没有退款才退回
1082         //获取回退记录
1083         SqlSentence sqlSentence = new SqlSentence();
1084         Map<String,Object> values = new HashMap<>();
1085         values.put("orderId",refundRecord.getOrderId());
1086         sqlSentence.sqlSentence("SELECT * FROM refund_user_assets rua WHERE rua.isDel = 0 AND rua.status = 1 AND rua.amountStatus IN(1,3) AND rua.orderId = #{m.orderId}",values);
1087         List<RefundUserAssets> refundUserAssetsList = commonService.selectList(RefundUserAssetsMapper.class,sqlSentence);
1088
1089         User user;
1090         for(RefundUserAssets refundUserAssets:refundUserAssetsList){
1091
1092             user = commonService.selectOneByKey(UserMapper.class,refundUserAssets.getUserId());
1093             orderNodeBuilder.append("-退款处理老带新,回退资金到用户:").append(user.getName()).append(",CIQ:").append(user.getCIQ()).append(",");
1094             orderNodeBuilder.append(RefundUserAssets.amountTypeName(refundUserAssets.getAmountType())).append(refundUserAssets.getAmount());
1095
1096             //是否有扣减用户资产
1097             if(refundUserAssets.getAmountStatus() == RefundUserAssets.AMOUNT_STATUS_NORMAL){
1098                 orderNodeBuilder.append(",增加成功");
1099                 UserMoneyUtil.setNewUserMoneyUnclaimed(refundUserAssets.getUserId(),refundRecord.getRemarks(),"退款作废:老带新资金回退作废",refundUserAssets.getOperatorId()
fd7281 1100                         ,refundRecord.getOrderId(),refundRecord.getOperatorAppCode(),refundUserAssets.getId(),refundUserAssets.getAmount().negate(),refundUserAssets.getAmountType()
160383 1101                         ,OperationReasonConstants.OP_REASON_BRING_NEW_USER_GIFT_RETRU_CANCEL,commonService,UserMoneyUnclaimed.YES);
C 1102             }else if(refundUserAssets.getAmountStatus() == RefundUserAssets.AMOUNT_STATUS_NOT_RECEIVE){
1103                 //用户未领取记录,还原
1104                 orderNodeBuilder.append(",用户未领取,作废的领取记录还原");
1105                 values.clear();
1106                 values.put("id",refundUserAssets.getUserMoneyUnclaimedId());
1107                 values.put("status",UserMoneyUnclaimed.STATUS_WAI);
1108                 sqlSentence.sqlUpdate("isDel = 0,isValid = 1 WHERE id = #{m.id} AND isDel = 1 AND isValid = 0 AND status = #{m.status}",values);
1109                 if(commonService.updateWhere(UserMoneyUnclaimedMapper.class,sqlSentence) != 1){
1110                     throw new TipsException("老带新资产记录状态已变化[作废]!");
1111                 }
1112             }
66d1dc 1113
C 1114             //记录作废
1115             values.clear();
1116             values.put("id",refundUserAssets.getId());
1117             values.put("status",RefundUserAssets.STATUS_CANCEL);
1118             values.put("oldStatus",RefundUserAssets.STATUS_NORMAL);
1119             sqlSentence.sqlSentence("status = #{m.status} WHERE id = #{m.id} AND status = #{m.oldStatus}",values);
1120             if(commonService.updateWhere(RefundUserAssetsMapper.class,sqlSentence) != 1){
1121                 throw new TipsException("老带新资产退款记录状态已变化[作废]!");
1122             }
160383 1123         }
C 1124
1125     }
1126
1127         /**
1128          * 退款-处理活动规则增值金和积分
1129          * @param commonService 映射对象
1130          * @param operationId 操作人标识
1131          * @param operationNme 操作人名称
1132          * @param sqlSentence 映射对象
1133          * @param map 映射对象
1134          * @param refundRecord 退款记录
1135          * @param ordersTotal 订单
1136          * @param optType 操作:"0"减 1加
1137          */
edf5ea 1138     private static void handActivityRule(CommonService commonService, String operationId, String operationNme, SqlSentence sqlSentence,
Z 1139                                          Map<String, Object> map, RefundRecord refundRecord, OrdersTotal ordersTotal, OrderInfo orderInfo,int optType) {
1140         if(orderInfo!=null && StringUtils.noNull(orderInfo.getActivityId())){
1141             ActivityRule activityRule=commonService.selectOneByKeyBlob(ActivityRuleMapper.class,orderInfo.getActivityId());
1142             if(activityRule!=null){
1143                 map.put("activityRuleId",activityRule.getId());
1144                 map.put("type", ActivityAction.TYPE_INTEGRAL);
1145                 map.put("type1",ActivityAction.TYPE_VALUEADDEDFUND);
1146                 map.put("type2",ActivityAction.TYPE_COUPON);
4df03d 1147                 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);
edf5ea 1148                 List<ActivityAction> activityActions = commonService.selectList(ActivityActionMapper.class, sqlSentence);
Z 1149                 if(activityActions!=null && activityActions.size()>0){
1150                     for (ActivityAction activityAction : activityActions) {
1151                         if(ActivityAction.TYPE_INTEGRAL.equals(activityAction.getType())){
1152                             //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1153                             if(new BigDecimal(activityAction.getWorth()).negate().compareTo(BigDecimal.ZERO)!=0){
1154                                 UserMoneyUtil.setNewUserMoneyUnclaimed(refundRecord.getUserId(),refundRecord.getRemarks(),optType==0?"充值单:"+ordersTotal.getOrderNo()+" 申请退款,预扣除活动规则赠送储值金金额:"+activityAction.getWorth():"充值单:"+ordersTotal.getOrderNo()+" 申请退款,拒绝审批,返还赠送储值金预扣除金额:"+activityAction.getWorth(),operationId,refundRecord.getOrderId(),ordersTotal.getAppIdCode(),refundRecord.getId(),optType==0?new BigDecimal(activityAction.getWorth()).negate():new BigDecimal(activityAction.getWorth()), UserMoneyUnclaimed.FUND_TYPE_INTEGRAL,OperationReasonConstants.OP_REASON_RECHARGE_REFUND,commonService,UserMoneyUnclaimed.YES);
1155                             }
1156                         }else if(ActivityAction.TYPE_VALUEADDEDFUND.equals(activityAction.getType())){
1157                             //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
1158                             if(new BigDecimal(activityAction.getWorth()).negate().compareTo(BigDecimal.ZERO)!=0){
1159                                 UserMoneyUtil.setNewUserMoneyUnclaimed(refundRecord.getUserId(),refundRecord.getRemarks(),optType==0?"充值单:"+ordersTotal.getOrderNo()+" 申请退款,预扣除活动规则赠送增值金金额:"+activityAction.getWorth():"充值单:"+ordersTotal.getOrderNo()+" 申请退款,拒绝审批,返还赠送增值金预扣除金额:"+activityAction.getWorth(),operationId,refundRecord.getOrderId(),ordersTotal.getAppIdCode(),refundRecord.getId(),optType==0?new BigDecimal(activityAction.getWorth()).negate():new BigDecimal(activityAction.getWorth()), UserMoneyUnclaimed.FUND_TYPE_VALUE_ADDED_FUND,OperationReasonConstants.OP_REASON_RECHARGE_REFUND,commonService,UserMoneyUnclaimed.YES);
1160                             }
1161                         }else if(ActivityAction.TYPE_COUPON.equals(activityAction.getType())){
1162                             map.put("oldValidState",optType==0?BaseEntity.YES:BaseEntity.NO);
1163                             map.put("newValidState",optType==0?BaseEntity.NO:BaseEntity.YES);
1164                             map.put("couponId",activityAction.getCrmCouponId());
1165                             map.put("commonId",ordersTotal.getId());
4df03d 1166                             sqlSentence.sqlSentence(" validState=#{m.newValidState} where couponId=#{m.couponId} and commonId=#{m.commonId} and validState=#{m.oldValidState} ",map);
edf5ea 1167                             commonService.updateWhere(CouponNumberMapper.class,sqlSentence);
Z 1168                         }
1169                     }
1170                 }
1171             }
1172         }
9d4e6f 1173     }
4df03d 1174
da4ad2 1175     /**
Z 1176      * 对接审批
1177      */
42a0e7 1178     public PlatformResult handleApproval(OrdersNodeLog ordersNodeLog,StringBuilder orderNodeBuilder,OrdersTotal ordersTotal,CancelOrder cancelOrder,RefundRecord refundRecord){
25d452 1179         orderNodeBuilder.append("-退款需要审批,开始对接营销中心");
42a0e7 1180
Z 1181
1182         OrderPartRefundDto orderPartRefundDto=new OrderPartRefundDto();
1183         OrdersTotalDto ordersTotalDto=new OrdersTotalDto();
1184         BeanUtils.copyProperties(ordersTotal, ordersTotalDto);
1185
1186         orderPartRefundDto.setOrdersTotalDto(ordersTotalDto);//填充主订单信息
1187
1188
1189         //填充操作人,用户的基本信息
1190         orderPartRefundDto.setOrdersTotalDto(ordersTotalDto);
1191         orderPartRefundDto.setOperatorId(cancelOrder.getOperatorId());
1192         orderPartRefundDto.setOpName(cancelOrder.getOperatorName());
1193         orderPartRefundDto.setShopId(cancelOrder.getShopId());
1194         orderPartRefundDto.setShopName(cancelOrder.getShopName());
1195         orderPartRefundDto.setRoleId(cancelOrder.getRoleId());
1196         orderPartRefundDto.setRoleUniqueStr(cancelOrder.getRoleStr());
117ee9 1197         if(StringUtils.noNull(refundRecord.getRemarks())){
C 1198             orderPartRefundDto.setRemark(refundRecord.getRemarks());
1199         }else{
1200             orderPartRefundDto.setRemark(cancelOrder.getOperatorName()+"退款,订单号:"+ordersTotal.getOrderNo());
1201         }
1202
42a0e7 1203         orderPartRefundDto.setUserId(ordersTotal.getUserId());
Z 1204
1205         //本次退款金额
1206         orderPartRefundDto.setRefundTotal(refundRecord.getRefundTotal());
1207
832331 1208         //------本次退款支付方式
42a0e7 1209         SqlSentence sqlSentence = new SqlSentence();
Z 1210         Map<String,Object> map=new HashMap<>();
4df03d 1211
42a0e7 1212         map.put("refundRecordId", refundRecord.getId());
4df03d 1213         sqlSentence.sqlSentence("SELECT refundNumberNo AS payMethodNo,refundName AS payMethodName,actualTotal as refundMoney,refundRecordId as payMethodId FROM refund_record_method " +
C 1214                 " WHERE refundRecordId=#{m.refundRecordId} ",map);
42a0e7 1215         List<Map<String, Object>> refundMethodList = commonService.selectListMap(RefundRecordMethodMapper.class,sqlSentence);
Z 1216         if(refundMethodList!=null && refundMethodList.size()!=0){
1217             JSONArray refundMethodArray=new JSONArray();
1218             refundMethodArray.addAll(refundMethodList);
1219             List<PartRefundPayDto> partRefundPayDtoList=refundMethodArray.toJavaList(PartRefundPayDto.class);
1220             orderPartRefundDto.setPartRefundPayDtoList(partRefundPayDtoList);
1221         }
832331 1222         //-----本次退款项目
42a0e7 1223         //退款一级项目
4df03d 1224         sqlSentence.sqlSentence("SELECT type AS projectType, commonId AS projectId, goodsNo AS projectNo, goodsName AS projectName, refundNum AS refundNum  " +
C 1225                 " FROM refund_record_item WHERE refundRecordId=#{m.refundRecordId} AND refundNum>0",map);
42a0e7 1226         List<Map<String, Object>> refundRecordItemList = commonService.selectListMap(RefundRecordItemMapper.class,sqlSentence);
Z 1227         JSONArray refundProjectDtoArray=new JSONArray();
1228         if(refundRecordItemList!=null && refundRecordItemList.size()!=0){
1229             refundProjectDtoArray.addAll(refundRecordItemList);
1230         }
1231         //退款二级项目
4df03d 1232         sqlSentence.sqlSentence("SELECT type AS projectType, commonId AS projectId, goodsNo AS projectNo, goodsName AS projectName, refundNum AS refundNum " +
C 1233                 " FROM refund_record_item_source   WHERE refundRecordId=#{m.refundRecordId} AND refundNum>0",map);
42a0e7 1234         List<Map<String, Object>> refundRecordItemSourceList = commonService.selectListMap(RefundRecordItemSourceMapper.class,sqlSentence);
Z 1235         if(refundRecordItemSourceList!=null && refundRecordItemSourceList.size()!=0){
1236             refundProjectDtoArray.addAll(refundRecordItemSourceList);
1237         }
1238         if(refundProjectDtoArray.size()>0){
1239             List<RefundProjectDto> refundProjectDtoList=refundProjectDtoArray.toJavaList(RefundProjectDto.class);
1240             orderPartRefundDto.setRefundProjectDtoList(refundProjectDtoList);
1241         }
1242
1243
25d452 1244         logger.info("调用营销中心审批退款入参:{}",JSONObject.toJSONString(orderPartRefundDto));
909b33 1245         Result result= mOrderService.applyPartRefund(orderPartRefundDto);
Z 1246 //        Result result= JSONObject.parseObject("{\"code\":\"100\",\"msg\":\"SUCCESS\",\"data\":{\"applyId\":\"6204eb10753511ed90ed525400b8510a\"}}",Result.class);
25d452 1247         logger.info("调用营销中心审批退款返回:{}",JSONObject.toJSONString(result));
42a0e7 1248         if (result != null) {
Z 1249             result.checkTips();
1250             JSONObject object = JSONObject.parseObject(JSONObject.toJSONString(result.getData()));
1251             if(!object.isEmpty()){
1252                 String applyId = object.getString("applyId");
1253                 cancelOrder.setApplyId(applyId);
b9b969 1254                 cancelOrder.setRefundRecordId(refundRecord.getId());
42a0e7 1255                 commonService.updateAll(CancelOrderMapper.class,cancelOrder);
Z 1256
542dc1 1257                 ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_APPLY);
42a0e7 1258                 commonService.updateAll(OrdersTotalMapper.class,ordersTotal);
Z 1259
5425ba 1260 //                logger.info("调用营销中心成功,订单开始审核");
Z 1261                 orderNodeBuilder.append("-调用营销中心成功,订单开始审核");
42a0e7 1262                 ordersNodeLog.setCommonType(OrdersNodeLog.TYPE_COMMON_ORDER_REFUND);
Z 1263                 ordersNodeLog.setContent(orderNodeBuilder.toString());
1264                 ordersNodeLog.setOrderId(ordersTotal.getId());
1265                 commonService.insert(OrdersNodeLogMapper.class,ordersNodeLog);
1266
1267                 orderNodeBuilder.append("-调用营销中心成功,订单开始审核");
1268
1269                 return PlatformResult.success("订单正在审核中");
1270             }else{
1271                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请求营销助手审批接口报错,data返回为空!");
1272             }
1273         } else {
1274             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请求营销助手审批接口报错,返回为空!");
1275         }
1276     }
1277
da4ad2 1278     /**
Z 1279      * 记录退款订单记录日志
1280      */
832331 1281     @Override
C 1282     public CancelOrder handleCancelOrder(OrdersTotal ordersTotal, OrderRefundDto orderRefundDto){
9d4e6f 1283         //记录取消日志
Z 1284         CancelOrder cancelOrder=new CancelOrder();
1285         cancelOrder.setOrderId(ordersTotal.getId());
2a45d4 1286         if(StringUtils.noNull(orderRefundDto.getOperatorId())){
C 1287             Employee employee = commonService.selectOneByKey(EmployeeMapper.class,orderRefundDto.getOperatorId());
1288             if(employee==null){
1289                 throw new TipsException("操作人标识错误!");
1290             }
9d4e6f 1291             cancelOrder.setOperatorId(employee.getId());
Z 1292             cancelOrder.setOperatorName(employee.getCnName());
1293         }
1294
2a45d4 1295         if(StringUtils.noNull(orderRefundDto.getRoleId())){
C 1296             EmployeeRole employeeRole=commonService.selectOneByKey(EmployeeRoleMapper.class,orderRefundDto.getRoleId());
1297             if(employeeRole==null){
1298                 throw new TipsException("操作角色标识错误!");
1299             }
9d4e6f 1300             cancelOrder.setRoleId(employeeRole.getRoleTypeId());
Z 1301             cancelOrder.setRoleStr(employeeRole.getRoleUniqueStr());
1302             Shop shop=commonService.selectOneByKey(ShopMapper.class,employeeRole.getShopId());
1303             if(shop==null){
1304                 cancelOrder.setShopId(employeeRole.getShopId());
1305                 cancelOrder.setShopName("找不到对应的门店");
1306             }else {
1307                 cancelOrder.setShopId(shop.getId());
1308                 cancelOrder.setShopName(shop.getName());
1309             }
1310         }
2a45d4 1311
9d4e6f 1312         cancelOrder.setIsApproval(orderRefundDto.getIsApproval());
Z 1313         cancelOrder.setIsRefund(orderRefundDto.getIsRefund());
1314         cancelOrder.setPlatformSource(orderRefundDto.getPlatformSource());
1315         commonService.insert(CancelOrderMapper.class,cancelOrder);
1316
1317         return cancelOrder;
1318     }
e3fa0c 1319
da4ad2 1320     /**
Z 1321      * 处理退款方式记录表
1322      */
4df03d 1323     public List<RefundRecordMethod> handleRefundPayMethod(OrderRefundDto orderRefundDto,StringBuilder orderNodeBuilder,OrdersTotal ordersTotal,RefundRecord refundRecord){
69ed11 1324         orderNodeBuilder.append("-记录退款方式:");
e3fa0c 1325
510678 1326         //获取订单可退款方式,就是支付方式总表的信息,已经支付编号求和
2a45d4 1327         List<PayMethodVo> payMethodVoList = refundMapper.getConsumePayGroupByNumberNo(ordersTotal.getId());
e3fa0c 1328
510678 1329         //用map装载,后面根据支付编号直接获取便可
C 1330         Map<String, PayMethodVo> payMethodVoMap = payMethodVoList.stream().collect(Collectors.toMap(PayMethodVo::getNumberNo,(a) -> a));
e3fa0c 1331
4df03d 1332         List<RefundRecordMethod> refundRecordMethodList = new ArrayList<>();
e3fa0c 1333
4df03d 1334         PayMethodVo payMethodVo;
510678 1335         RefundRecordMethod refundRecordMethod;
4df03d 1336         for (OrderPayMethodDto orderPayMethodDto : orderRefundDto.getRefundPayMethod()) {
e3fa0c 1337
4df03d 1338             payMethodVo = payMethodVoMap.get(orderPayMethodDto.getPayMethodNo());
C 1339             //判断是不是在支付方式里面的
1340             if (payMethodVo == null){
510678 1341                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"可退支付方式未找到:"+orderPayMethodDto.getPayMethodName()+"["+orderPayMethodDto.getPayMethodNo()+"]");
da4ad2 1342             }
ae6ff7 1343             //判断支付方式
4df03d 1344             PaymentMethod payMethod = paymentMethodService.selectNumberNoUncheckUp(orderPayMethodDto.getPayMethodNo());
C 1345             if(payMethod == null){
1346                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到对应的支付:"+orderPayMethodDto.getPayMethodName()+"["+orderPayMethodDto.getPayMethodNo()+"]");
e3fa0c 1347             }
4df03d 1348             //判断退款方式
C 1349             PaymentMethod refundMethod = paymentMethodService.selectNumberNoUncheckUp(orderPayMethodDto.getRefundNumberNo());
e3fa0c 1350             if(refundMethod==null){
ae6ff7 1351                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到退款方式:"+orderPayMethodDto.getRefundNumberName()+"["+orderPayMethodDto.getRefundNumberNo()+"]");
4df03d 1352             }
C 1353             if(orderPayMethodDto.getMoney() == null){
ae6ff7 1354                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请填写退款方式["+orderPayMethodDto.getPayMethodName()+"["+orderPayMethodDto.getPayMethodNo()+"]"+"]金额");
C 1355             }
1356             //判断金额
1357             if(payMethodVo.getSurplusTotal().compareTo(orderPayMethodDto.getMoney()) < 0){
1358                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款金额错误:"+orderPayMethodDto.getPayMethodName()+"["+orderPayMethodDto.getPayMethodNo()+"]");
e3fa0c 1359             }
da4ad2 1360
510678 1361             ////退款方式数据填充
4df03d 1362             refundRecordMethod = new RefundRecordMethod();
ae6ff7 1363             refundRecordMethod.setType(refundRecord.getSourceType());
510678 1364             refundRecordMethod.setActualTotal(orderPayMethodDto.getMoney());
C 1365             //支付方式信息
4df03d 1366             refundRecordMethod.setNumberNo(payMethod.getNumberNo());
C 1367             refundRecordMethod.setPaymentMethodId(payMethod.getId());
1368             refundRecordMethod.setName(payMethod.getName());
1369             refundRecordMethod.setIsMoneyPay(payMethodVo.getIsMoneyPay());
1370             refundRecordMethod.setIsExecute(payMethodVo.getIsExecute());
510678 1371             //退款方式信息
4df03d 1372             refundRecordMethod.setRefundNumberNo(refundMethod.getNumberNo());
C 1373             refundRecordMethod.setRefundName(refundMethod.getName());
1374             refundRecordMethod.setRefundMethodId(refundMethod.getId());
510678 1375
4df03d 1376             refundRecordMethod.setIsMoneyPayRefund(refundMethod.getIsMoneyPay());
C 1377             refundRecordMethod.setIsExecuteRefund(refundMethod.getIsExecute());
2a45d4 1378             refundRecordMethod.setRefundRecordId(refundRecord.getId());
C 1379             refundRecordMethod.setOrderId(ordersTotal.getId());
473d29 1380             refundRecordMethod.setRemarks(orderPayMethodDto.getRemarks());
4df03d 1381
C 1382             refundRecordMethodService.insert(refundRecordMethod);
1383             refundRecordMethodList.add(refundRecordMethod);
e3fa0c 1384         }
4df03d 1385         return refundRecordMethodList;
e3fa0c 1386     }
4df03d 1387
da4ad2 1388     /**
Z 1389      * 退款记录子项
1390      */
510678 1391     public void insertRefundRecordItem(OrderRefundDto orderRefundDto,StringBuilder orderNodeBuilder,RefundRecord refundRecord){
e3fa0c 1392
431d07 1393         orderNodeBuilder.append("-记录退款详情");
542dc1 1394
ae6ff7 1395         //计算金额占比,客户选择退款总金额和可退总金额占比
4df03d 1396         BigDecimal percentage;
C 1397         if(orderRefundDto.getTotalAmount().compareTo(BigDecimal.ZERO) < 1){
1398             percentage = BigDecimal.ZERO;
1399         }else {
1400             percentage = orderRefundDto.getRefundTotal().divide(orderRefundDto.getTotalAmount(),15,RoundingMode.HALF_UP);
1401         }
542dc1 1402
ae6ff7 1403         //总退款金额,用于后面计算分摊金额
4df03d 1404         BigDecimal refundTotal = refundRecord.getRefundTotal();
C 1405
ae6ff7 1406         //后面设计分配金额问题,要进行升序排序,避免到最后不够
C 1407         List<OrderItemRefundDto> refundList = orderRefundDto.getRefundList();
1408         refundList = refundList.stream().sorted(Comparator.comparing(OrderItemRefundDto::getApproveRefundTotal)).collect(Collectors.toList());
4df03d 1409
C 1410         /////引用参数
1411         RefundRecordItem refundRecordItem;
de3024 1412         OrderItemRefundDto orderItemRefundDto;
4df03d 1413         OrderItem orderItem;
ae6ff7 1414         for(int i = 0;i < refundList.size();i++){
C 1415             orderItemRefundDto = refundList.get(i);
de3024 1416
4df03d 1417             orderItem = orderItemMapper.selectOneByKey(orderItemRefundDto.getOrderItemId());
C 1418             if(orderItem == null){
1419                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"子订单标识错误!");
de3024 1420             }
Z 1421
4df03d 1422             //////数据填充
C 1423             refundRecordItem = new RefundRecordItem();
1424             refundRecordItem.setType(orderItem.getType());
1425             refundRecordItem.setGoodsNo(orderItem.getGoodsNo());
2a45d4 1426             refundRecordItem.setGoodsName(orderItem.getGoodsName());
4df03d 1427             refundRecordItem.setSpecs(orderItem.getSpecs());
C 1428             refundRecordItem.setCommonId(orderItem.getCommonId());
2a45d4 1429             if(PartialRefundUtil.CONTAIN_SON_TYPE_SET.contains(orderItem.getType())){
C 1430                 refundRecordItem.setRefundNum(0);
1431             }else{
1432                 refundRecordItem.setRefundNum(orderItemRefundDto.getRefundNum());
1433             }
4df03d 1434             refundRecordItem.setRefundRecordId(refundRecord.getId());
C 1435             refundRecordItem.setOrderItemId(orderItem.getId());
1436             refundRecordItem.setOccupyRefundTotal(orderItemRefundDto.getApproveRefundTotal());
77f162 1437             ////退款备注
C 1438             if(StringUtils.isEmpty(orderItemRefundDto.getRemarks())){
1439                 orderItemRefundDto.setRemarks(refundRecord.getRemarks());
1440             }
1441             if(StringUtils.isEmpty(orderItemRefundDto.getRefundReason())){
2a45d4 1442                 orderItemRefundDto.setRefundReason(orderItemRefundDto.getRefundReason());
77f162 1443             }
8eb9e6 1444             refundRecordItem.setRemarks(orderItemRefundDto.getRemarks());
C 1445             refundRecordItem.setRefundReason(orderItemRefundDto.getRefundReason());
4df03d 1446
ae6ff7 1447             //////////分配退款金额
C 1448             if(i == refundList.size()-1){
4df03d 1449                 refundRecordItem.setRefundMoney(refundTotal);
C 1450             }else{
1451                 refundRecordItem.setRefundMoney(orderItemRefundDto.getApproveRefundTotal().multiply(percentage).setScale(2,RoundingMode.UP));
1452             }
1453             if(refundRecordItem.getRefundMoney().compareTo(orderItemRefundDto.getApproveRefundTotal()) > 0){
1454                 refundRecordItem.setRefundMoney(orderItemRefundDto.getApproveRefundTotal());
1455             }
ae6ff7 1456             //判断与未分配剩余金额
4df03d 1457             if(refundRecordItem.getRefundMoney().compareTo(refundTotal) > 0){
C 1458                 refundRecordItem.setRefundMoney(refundTotal);
1459             }
2a45d4 1460
C 1461             refundRecordItem.setRealRefundNum(refundRecordItem.getRefundNum());
01fbcb 1462             refundRecordItem.setRealRefundTotal(refundRecordItem.getRefundMoney());
2a45d4 1463
da4ad2 1464             refundRecordItemService.insert(refundRecordItem);
c40d5d 1465
C 1466             if(OrderItemConstants.TYPE_PROJECT.equals(refundRecordItem.getType())){
1467                 //存储划扣信息
1468                 RefundTool.insertDeductionData(refundRecord.getId(),refundRecord.getOrderId(),refundRecordItem.getId(),orderItemRefundDto.getRefundDeductionCancelList(),commonService);
1469             }
1470
510678 1471             //减去已经分配的退款金额
ae6ff7 1472             refundTotal = refundTotal.subtract(refundRecordItem.getRefundMoney()).setScale(2,RoundingMode.HALF_UP);
2a45d4 1473             if(PartialRefundUtil.CONTAIN_SON_TYPE_SET.contains(orderItem.getType())){
C 1474                 //子单子项处理
1475                 insertRefundRecordItemTwo(refundRecordItem,refundRecord,orderItemRefundDto.getOrderItemSourceRefundDtos());
1476             }
12025c 1477
253802 1478             //虚拟商品退款时需校验一下,对应关联的优惠券码有没有被使用或
20d569 1479             if(OrderItemConstants.TYPE_COUPON.equals(orderItem.getType())){
F 1480                 OrderVirtualGoodsUtil.orderApplyRefundHandle(commonService, orderItem, orderItemRefundDto.getRefundNum(), refundRecord.getOperatorId(), refundRecord.getOperatorName(), "p-his申请订单退款作废");
12025c 1481             }
e3fa0c 1482         }
4df03d 1483
1869f3 1484         if(refundTotal.compareTo(BigDecimal.ZERO) > 0){
C 1485             throw new TipsException("退款金额分配错误[01]!");
1486         }
1487
e3fa0c 1488     }
da4ad2 1489
4df03d 1490     /**二级子单处理*/
1869f3 1491     public void insertRefundRecordItemTwo(RefundRecordItem recordItem,RefundRecord refundRecord,List<OrderItemSourceRefundDto> orderItemSourceRefundDtos){
4df03d 1492         if(orderItemSourceRefundDtos == null || orderItemSourceRefundDtos.size() == 0){
da4ad2 1493             return;
Z 1494         }
ae6ff7 1495
C 1496         //计算占比
1497         BigDecimal percentage;
1498         if(recordItem.getOccupyRefundTotal().compareTo(BigDecimal.ZERO) > 0){
1499             percentage = recordItem.getRefundMoney().divide(recordItem.getOccupyRefundTotal(),15,RoundingMode.HALF_UP);
1500         }else{
1501             percentage = BigDecimal.ZERO;
1502         }
1503
1504         //进行升序排序,避免后面不够
1505         orderItemSourceRefundDtos = orderItemSourceRefundDtos.stream().sorted(Comparator.comparing(OrderItemSourceRefundDto::getApproveRefundTotal)).collect(Collectors.toList());
431d07 1506
4df03d 1507         //退款总金额
C 1508         BigDecimal refundTotal = recordItem.getRefundMoney();
da4ad2 1509
4df03d 1510         OrderItemSon orderItemSon;
C 1511         OrderItemSourceRefundDto orderItemSourceRefundDto;
1512         RefundRecordItemSource refundRecordItemSource;
1869f3 1513
4df03d 1514         for(int i = 0;i<orderItemSourceRefundDtos.size();i++){
C 1515             orderItemSourceRefundDto = orderItemSourceRefundDtos.get(i);
da4ad2 1516
4df03d 1517             orderItemSon = orderItemSonMapper.selectOneByKey(orderItemSourceRefundDto.getOrderItemSonId());
C 1518             if(orderItemSon == null){
1519                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"子订单标识错误[024]!");
1520             }
da4ad2 1521
4df03d 1522             //////数据填充
C 1523             refundRecordItemSource = new RefundRecordItemSource();
1524             refundRecordItemSource.setType(orderItemSon.getType());
1525             refundRecordItemSource.setGoodsNo(orderItemSon.getGoodsNo());
2a45d4 1526             refundRecordItemSource.setGoodsName(orderItemSon.getGoodsName());
4df03d 1527             refundRecordItemSource.setSpecs(orderItemSon.getSpecs());
C 1528             refundRecordItemSource.setCommonId(orderItemSon.getGoodsId());
1529             refundRecordItemSource.setRefundNum(orderItemSourceRefundDto.getRefundNum());
2a45d4 1530             refundRecordItemSource.setRefundRecordId(refundRecord.getId());
4df03d 1531             refundRecordItemSource.setOrderItemSonId(orderItemSon.getId());
C 1532             refundRecordItemSource.setOccupyRefundTotal(orderItemSourceRefundDto.getApproveRefundTotal());
2a45d4 1533             refundRecordItemSource.setRefundRecordItemId(recordItem.getId());
4df03d 1534             ////退款备注
C 1535             if(StringUtils.isEmpty(orderItemSourceRefundDto.getRemarks())){
1536                 orderItemSourceRefundDto.setRemarks(refundRecord.getRemarks());
1537             }
1538             if(StringUtils.isEmpty(orderItemSourceRefundDto.getRefundReason())){
2a45d4 1539                 orderItemSourceRefundDto.setRefundReason(refundRecord.getRefundReason());
4df03d 1540             }
C 1541             refundRecordItemSource.setRemarks(orderItemSourceRefundDto.getRemarks());
1542             refundRecordItemSource.setRefundReason(orderItemSourceRefundDto.getRefundReason());
da4ad2 1543
4df03d 1544             //计算退款金额
C 1545             if(i == orderItemSourceRefundDtos.size()-1){
1546                 refundRecordItemSource.setRefundMoney(refundTotal);
1547             }else{
1548                 refundRecordItemSource.setRefundMoney(orderItemSourceRefundDto.getApproveRefundTotal().multiply(percentage).setScale(2,RoundingMode.UP));
1549             }
1550             if(refundRecordItemSource.getRefundMoney().compareTo(orderItemSourceRefundDto.getApproveRefundTotal()) > 0){
1551                 refundRecordItemSource.setRefundMoney(orderItemSourceRefundDto.getApproveRefundTotal());
1552             }
1553             if(refundRecordItemSource.getRefundMoney().compareTo(refundTotal) > 0){
1554                 refundRecordItemSource.setRefundMoney(refundTotal);
1555             }
2a45d4 1556
C 1557             refundRecordItemSource.setRealRefundNum(refundRecordItemSource.getRefundNum());
1558             refundRecordItemSource.setRealRefundTotal(refundRecordItemSource.getRefundMoney());
1559
4df03d 1560             refundRecordItemSourceMapper.insert(refundRecordItemSource);
c40d5d 1561
C 1562             if(OrderItemConstants.TYPE_PROJECT.equals(refundRecordItemSource.getType())){
1563                 //存储划扣信息
1564                 RefundTool.insertDeductionData(refundRecord.getId(),refundRecord.getOrderId(),refundRecordItemSource.getId(),orderItemSourceRefundDto.getRefundDeductionCancelList(),commonService);
1565             }
1566
ae6ff7 1567             //减去已经分配退款金额
C 1568             refundTotal = refundTotal.subtract(refundRecordItemSource.getRefundMoney()).setScale(2,RoundingMode.HALF_UP);
1869f3 1569         }
b2b4a4 1570
1869f3 1571         if(refundTotal.compareTo(BigDecimal.ZERO) > 0){
C 1572             throw new TipsException("退款金额分配错误[02]!");
431d07 1573         }
da4ad2 1574
431d07 1575     }
e3fa0c 1576
da4ad2 1577     /**
Z 1578      * 记录退款记录优惠卷
1579      */
e3fa0c 1580     public void handleOrderCouponRefunDto(List<OrderCouponRefunDto> couponList,StringBuilder orderNodeBuilder,OrdersTotal ordersTotal,RefundRecord refundRecord){
510678 1581         CouponOrderDiscountLog couponOrderDiscountLog;
C 1582         RefundRecordCoupon refundRecordCoupon;
e3fa0c 1583         orderNodeBuilder.append("-处理退款优惠卷");
Z 1584         for (OrderCouponRefunDto orderCouponRefunDto : couponList) {
1585             couponOrderDiscountLog=couponOrderDiscountLogMapper.selectOneByKey(orderCouponRefunDto.getOrderCouponId());
510678 1586             if( couponOrderDiscountLog == null){
4df03d 1587                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"订单优惠卷标识不正确");
e3fa0c 1588             }
Z 1589             refundRecordCoupon=new  RefundRecordCoupon(ordersTotal.getId(),refundRecord.getId(),ordersTotal.getUserId(),1,1,couponOrderDiscountLog.getId(),
1590                     couponOrderDiscountLog.getCouponId(),couponOrderDiscountLog.getTitle(),couponOrderDiscountLog.getCouponNumberId());
1591             refundRecordCouponMapper.insert(refundRecordCoupon);
1592         }
1593     }
1594
1595
1596
4df03d 1597     /**真正退款,是对钱和状态的回退到账开始操作
da4ad2 1598      * 进行退款操作,退款用户项目,商品,促销,卡项,卡包
Z 1599      */
3badb7 1600     @Override
a1c527 1601     public Map<String,Object> handleRefundOrder(Map<String, String> operator,RefundRecord refundRecord,OrdersTotal ordersTotal
C 1602             ,OrdersNodeLog ordersNodeLog,StringBuilder orderNodeBuilder,CancelOrder cancelOrder ){
c04e8a 1603
4dc6e5 1604         String operationId=operator.get("operatorId");
Z 1605         String operatorName=operator.get("operatorName");
c04e8a 1606
46bedb 1607         orderNodeBuilder.append("-处理退款支付方式,用户待执行项目");
e2a6c2 1608
ae6ff7 1609         //处理主业务
e2a6c2 1610         ordersTotal =  PartialRefundUtil.refundProcess(commonService,deductionSingleService, operationId, operatorName, refundRecord.getId());
c04e8a 1611
4dc6e5 1612         //返回数据
Z 1613         Map<String,Object> data=new HashMap<>();
1614         data.put("refundRecordId",refundRecord.getId());
1615         data.put("refundRecordCode",refundRecord.getCode());
16790d 1616
da4ad2 1617         //处理次业务,报错不影响主业务
ae6ff7 1618         refundRecord = refundRecordService.selectOneByKey(refundRecord.getId());
C 1619
478fa9 1620         //用户升降级(调用航爷) 金额=用户支付的实付现金金额(不包含储值金)
f13adb 1621         SqlSentence sqlSentence = new SqlSentence();
Z 1622         Map<String,Object> map=new HashMap<>();
1623         sqlSentence.setM(map);
1624         //退款成功
1625         map.put("refundRecordId", refundRecord.getId());
4df03d 1626         sqlSentence.sqlSentence("SELECT CAST(COALESCE(sum(rrm.realRefundTotal),0) as  DECIMAL(11,2))  as total FROM refund_record_method rrm LEFT JOIN payment_method pm ON pm.numberNo=rrm.refundNumberNo " +
C 1627                 "WHERE rrm.refundRecordId=#{m.refundRecordId} and pm.isMoneyPay=1",map);
f13adb 1628         Map<String,Object> totalMap =commonService.selectOneMap(RefundRecordMethodMapper.class,sqlSentence);
Z 1629         BigDecimal total=new BigDecimal(String.valueOf(totalMap.get("total"))) ;
1630         if(BigDecimal.ZERO.compareTo(total) < 0){
1631             try {
2a45d4 1632                 orderNodeBuilder.append("-开始处理用户升降级,金额:").append(total.negate());
26ebce 1633                 UserLevelUtil.refund(userLevelRuleService, ordersTotal.getUserId(),ordersTotal.getId(),total.negate(),ordersTotal.getAppIdCode());
16790d 1634                 orderNodeBuilder.append("-处理用户升降级成功");
f13adb 1635             }catch (Exception e){
Z 1636                 String snapshot="处理用户升降级失败";
2a45d4 1637                 orderNodeBuilder.append("-处理用户升降级失败,异常原因:").append(e.getMessage());
f13adb 1638                 logger.error("处理用户升降级失败:" + e.getMessage());
Z 1639                 //发送企业微信通知给工作人员
1640                 SendNoticeUtil.failOrderSendNotice(ordersTotal,e.getMessage(),snapshot,commonService,customParameter);
1641             }
1642         }
edf5ea 1643
46bedb 1644         //记录操作日志
Z 1645         orderNodeBuilder.append("-记录操作日志");
478fa9 1646         StringBuffer stringBuffer = new StringBuffer("操作人:"+operator.get("operatorName")+",进行退款");
46bedb 1647         OrderLog orderLog=new OrderLog(ordersTotal.getId(), OrderLogConstants.LOG_TYPE_REFUND,stringBuffer.toString()
Z 1648                 ,operator.get("operatorName"),operator.get("operatorId"),OrderTotalConstants.STATUS_CANCEL);
1649         commonService.insert(OrderLogMapper.class,orderLog);
1650
1651         orderNodeBuilder.append("-结束处理退款");
1652         ordersNodeLog.setCommonType(OrdersNodeLog.TYPE_COMMON_ORDER_REFUND);
1653         ordersNodeLog.setContent(orderNodeBuilder.toString());
1654         ordersNodeLog.setOrderId(ordersTotal.getId());
1655         commonService.insert(OrdersNodeLogMapper.class,ordersNodeLog);
1656
260188 1657         //第三方最后执行
C 1658         if(CancelOrderDto.HIS_ASSISTANT.equals(cancelOrder.getPlatformSource())){
1659             //如果是his自动处理退款单原路退回
1660             //CRM的操作也在这里
1661             hisAssistantNoteList(ordersTotal,refundRecord,operationId,orderNodeBuilder);
1662         }
1663
f23452 1664         //撤销【保妥适会员】标签
W 1665         ClubEquityTool.refundCancelLabel(commonService,sUserTagInfoService,ordersTotal,botoxClubConfig.getLabelTypeNo(),botoxClubConfig.getLabelNo());
1666
4dc6e5 1667         return data;
c38ec7 1668     }
277835 1669     /**
Z 1670      * his助手原路退回退款单
1671      */
7d7f9e 1672     public void hisAssistantNoteList(OrdersTotal ordersTotal,RefundRecord refundRecord,String operationId,StringBuilder orderNodeBuilder){
5c26f4 1673         OrderRefundNoteListDto orderRefundNoteListDto=new OrderRefundNoteListDto();
W 1674         orderRefundNoteListDto.setOperationId(operationId);
1675         orderRefundNoteListDto.setOrderId(ordersTotal.getId());
a0d15f 1676
f3ff4e 1677         //获取退款信息
277835 1678         SqlSentence sqlSentence = new SqlSentence();
Z 1679         Map<String,Object> map=new HashMap<>();
f3ff4e 1680
C 1681         //获取总退款方式
7d7f9e 1682         map.put("refundRecordId",refundRecord.getId());
f3ff4e 1683         sqlSentence.sqlSentence("SELECT * FROM refund_record_method WHERE isDel = 0 AND refundRecordId = #{m.refundRecordId}",map);
C 1684         List<RefundRecordMethod> refundRecordMethodList = commonService.selectList(RefundRecordMethodMapper.class,sqlSentence);
1685         if(refundRecordMethodList.size() == 0){
277835 1686             return;
Z 1687         }
1688
f3ff4e 1689         //组装数据,只有现金才生成
277835 1690         List<OrderRefundNoteDto> orderRefundNoteDtos=new ArrayList<>();
Z 1691         OrderRefundNoteDto orderRefundNoteDto;
f3ff4e 1692         for (RefundRecordMethod refundRecordMethod : refundRecordMethodList) {
C 1693             //是现金
f3a00b 1694             if(!refundRecordMethod.getIsMoneyPay().equals(BaseEntity.YES)){
f3ff4e 1695                 continue;
260188 1696             }
f3ff4e 1697             orderRefundNoteDto = new OrderRefundNoteDto();
C 1698             //退款,是否原路退回
1699             if(refundRecordMethod.getNumberNo().equals(refundRecordMethod.getRefundNumberNo())){
1700
260188 1701                 orderRefundNoteDto.setRefundroute(1);
C 1702             }else{
1703                 orderRefundNoteDto.setRefundroute(0);
1704             }
f3ff4e 1705             orderRefundNoteDto.setRefundRecordMethodId(refundRecordMethod.getId());
C 1706             orderRefundNoteDto.setPaymentTotal(refundRecordMethod.getActualTotal());
1707             orderRefundNoteDto.setPaymentNumberNo(refundRecordMethod.getNumberNo());
1708             orderRefundNoteDto.setPaymentName(refundRecordMethod.getName());
1709             orderRefundNoteDto.setRefundNumberNo(refundRecordMethod.getRefundNumberNo());
1710             orderRefundNoteDto.setRefundName(refundRecordMethod.getRefundName());
277835 1711             orderRefundNoteDtos.add(orderRefundNoteDto);
Z 1712         }
1713         orderRefundNoteListDto.setOrderRefundNoteDtos(orderRefundNoteDtos);
1714
7d7f9e 1715         noteConfirm(orderRefundNoteListDto, ordersTotal,refundRecord,orderNodeBuilder);
254bde 1716     }
4df03d 1717
f3ff4e 1718     public void noteConfirm(OrderRefundNoteListDto orderRefundNoteListDto,OrdersTotal ordersTotal,RefundRecord refundRecord
7d7f9e 1719             ,StringBuilder orderNodeBuilder) {
260188 1720         logger.info("退款单确认打印参数:{}",JSON.toJSONString(orderRefundNoteListDto));
254bde 1721         Map<String, String> operator = ApiOrderUtil.getOperator(commonService, orderRefundNoteListDto.getOperationId());//获取操作人信息
Z 1722         String operatorId= operator.get("operatorId");
1723         String operatorName=  operator.get("operatorName");
1724
1725
1726         SqlSentence sqlSentence = new SqlSentence();
1727         Map<String,Object> map=new HashMap<>();
1728         sqlSentence.setM(map);
1729
1730         List<OrderRefundNoteDto> orderRefundNoteDtos=orderRefundNoteListDto.getOrderRefundNoteDtos();
f3ff4e 1731         if(orderRefundNoteDtos == null || orderRefundNoteDtos.size() == 0){
C 1732             return;
1733         }
254bde 1734         if("crm".equals(ordersTotal.getAppIdCode())){
4df03d 1735             //CRM退款
7d7f9e 1736             handleCrmRefundOrder(orderRefundNoteDtos,ordersTotal,refundRecord,operatorId,operatorName,orderNodeBuilder);
254bde 1737         }else {
f3ff4e 1738             RefundCashVo refundCashVo = new RefundCashVo();
C 1739             refundCashVo.setOrderId(ordersTotal.getId());
1740             refundCashVo.setRemark(refundRecord.getRemarks());
1741             List<RefundCashItemVo> refundCashItemVoList = new ArrayList<>();
1742             RefundCashItemVo refundCashItemVo;
254bde 1743             for (OrderRefundNoteDto orderRefundNoteDto : orderRefundNoteDtos) {
f3ff4e 1744                 if(BaseEntity.YES.equals(orderRefundNoteDto.getRefundroute())){
C 1745                     refundCashItemVo = new RefundCashItemVo();
1746                     refundCashItemVo.setPaymentNo(orderRefundNoteDto.getRefundNumberNo());
1747                     refundCashItemVo.setRefundTotal(orderRefundNoteDto.getPaymentTotal());
1748                     refundCashItemVo.setRefundRecordId(refundRecord.getId());
1749                     refundCashItemVo.setRefundRecordMethodId(orderRefundNoteDto.getRefundRecordMethodId());
1750                     refundCashItemVoList.add(refundCashItemVo);
1751                 }
254bde 1752             }
f3ff4e 1753             refundCashVo.setRefundCashItemVoList(refundCashItemVoList);
88585a 1754             logger.info("支付退款-ordersTotal.getAppIdCode():{}",ordersTotal.getAppIdCode());
C 1755             logger.info("支付退款-refundCashVo:{}",JSON.toJSONString(refundCashVo));
50ba2e 1756             //开始退款 2023-09-06暂时屏蔽线上退款
C 1757             //refundCash(refundRecord.getId(),refundCashVo);
254bde 1758         }
Z 1759
1760         //记录操作日志
1761         StringBuffer stringBuffer=new StringBuffer("操作人:"+operator.get("operatorName")+",已支付订单现金支付退款:");
1762         OrderLog orderLog=new OrderLog(ordersTotal.getId(),OrderLogConstants.LOG_TYPE_CANCEL_ORDER,stringBuffer.toString()
1763                 ,operator.get("operatorName"),operator.get("operatorId"),OrderTotalConstants.STATUS_CANCEL);
1764         commonService.insert(OrderLogMapper.class,orderLog);
1765
1766     }
4df03d 1767     /**处理crm退款*/
7d7f9e 1768     public void handleCrmRefundOrder(List<OrderRefundNoteDto> orderRefundNoteDtos,OrdersTotal ordersTotal,RefundRecord refundRecord
C 1769             ,String operatorId, String operatorName,StringBuilder orderNodeBuilder){
254bde 1770         SqlSentence sqlSentence = new SqlSentence();
Z 1771         Map<String,Object> map=new HashMap<>();
1772         sqlSentence.setM(map);
1773
1774         //待确认
1775         BigDecimal crmAmount = orderRefundNoteDtos.stream().filter(item->RefundNote.ORIGINAL_ROAD.equals(item.getRefundroute())).map(o->o.getPaymentTotal())
1776                 .reduce(BigDecimal.ZERO,BigDecimal::add);
1777         List<RefundAmountModelDto> amountModelList=new ArrayList<>();
1778         RefundAmountModelDto refundAmountModelDto;
1779         for (OrderRefundNoteDto orderRefundNoteDto : orderRefundNoteDtos) {
1780             if(RefundNote.ORIGINAL_ROAD.equals(orderRefundNoteDto.getRefundroute())){
1781                 refundAmountModelDto=new RefundAmountModelDto();
260188 1782                 refundAmountModelDto.setRefundType(PayMethodTypeConstants.PAY_CRM_WX.equals(orderRefundNoteDto.getRefundNumberNo()) ?0:1);
254bde 1783                 refundAmountModelDto.setAmountTotal(orderRefundNoteDto.getPaymentTotal());
Z 1784                 amountModelList.add(refundAmountModelDto);
1785             }
1786         }
1787         logger.info("退款金额:{}",crmAmount);
832331 1788         if(0 < crmAmount.compareTo(BigDecimal.ZERO)){
254bde 1789             RefundDto refundDto=new RefundDto();
Z 1790             refundDto.setRefundOrderType(0);
1791             refundDto.setOrderId(ordersTotal.getId());
1792             refundDto.setRefundType(0);
1793             refundDto.setRefundAmountTotal(crmAmount);
1794             refundDto.setRefundRecharge(new BigDecimal(0));
1795             refundDto.setRefundIncrement(new BigDecimal(0));
1796             refundDto.setRefundIntegral(new BigDecimal(0));
1797             refundDto.setIsWholeOrder(0);
1798             refundDto.setRemarks("phis退款单退款,订单号:"+ordersTotal.getOrderNo());
1799             refundDto.setAmountModelList(amountModelList);
ed65d6 1800             refundDto.setOperatorId(operatorId);
W 1801             refundDto.setOperatorName(operatorName);
1802             if(OrderTotalConstants.STATUS_REFUND_FINSH==ordersTotal.getRefundStatus() &&
1803                     OrderTotalConstants.STATUS_CANCEL == ordersTotal.getStatus()){
af0ab2 1804                 //全部退款完成则取消订单
W 1805                 refundDto.setIsCancelOrder(BaseEntity.YES);
1806             }
1807
254bde 1808             logger.info("调用crm退款入参:{}",JSONObject.toJSONString(refundDto));
Z 1809             Result result= fOderService.refundOrder(refundDto);;
1810             logger.info("调用crm退款返回:{}",JSONObject.toJSONString(result));
1811             if (result != null) {
1812                 result.checkTips();
edf5ea 1813                 if("100".equals(result.getCode())){
254bde 1814                     RefundReturnDto refundReturnDto=JSON.parseObject(JSONObject.toJSONString(result.getData()),RefundReturnDto.class);
7d7f9e 1815                     if (RefundReturnDto.REFUND_STATUS_SUECCESS == refundReturnDto.getRefundStatus()){
edf5ea 1816                         orderNodeBuilder.append("-调用CRM退款金额:"+crmAmount+",返回成功返回流水号:"+refundReturnDto.getRefundNo()+",json:"+result);
254bde 1817                         logger.info("crm退款成功进行下面操作");
Z 1818                     }else {
5a8c60 1819                         //throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请求crm退款接口报错,退款失败!退款状态不是成功状态");
49b035 1820                         if (!StringUtils.isEmpty(refundReturnDto.getTisMsg())){
W 1821                             if (refundReturnDto.getTisMsg().contains("商户账户可退款金额不足")){
1822                                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"非常抱歉,当前公司财务账号金额不足无法进行退款,请稍后再试。如急需退款,请退[储值金] 在走oa申请线下退款。");
1823                             }else {
1824                                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,refundReturnDto.getTisMsg());
1825                             }
1826
1827                         }else {
1828                             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款失败,请联系管理人员处理!");
1829                         }
254bde 1830                     }
d095b1 1831                     //生成CRM回执记录
C 1832                     createCrmRefundReceipt(refundReturnDto,refundRecord,commonService);
254bde 1833                 }else{
55dbe8 1834                     throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请求crm退款接口报错,接口返回错误!:code不是100");
254bde 1835                 }
Z 1836             } else {
1837                 throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请求crm退款接口报错,返回为空!");
1838             }
1839
1840         }
edf5ea 1841
f3ff4e 1842         try{
C 1843             //退款成功发送企业微信给订单开单人
1844             JSONObject object = new JSONObject();
1845             object.put("abnormal","订单退款成功,现金支付资产已退回!");
1846             object.put("orderNo",ordersTotal.getOrderNo());
1847             User user=commonService.selectOneByKeyBlob(UserMapper.class,ordersTotal.getUserId());
1848             object.put("userName",user==null?"":user.getName());
1849             object.put("notificationSubject", NotificationLog.NOTIFICATION_SUBJECT_REFUND_NOTE_PHISKIN_SUC_NOTICE);
1850             SendNoticeUtil.successOrderSendNotice(commonService, customParameter, ordersTotal,object);
1851         }catch (Exception e){
1852             logger.error("退款成功发送企业微信给订单开单人错误:",e);
254bde 1853         }
277835 1854     }
9d4e6f 1855
e3fa0c 1856     /**
d095b1 1857      * 生成CRM退款回执
C 1858      * @param refundReturnDto crm退款返回总结构
1859      * @param refundRecord 退款总单
1860      * @param commonService 映射
1861      */
1862     public static void createCrmRefundReceipt(RefundReturnDto refundReturnDto,RefundRecord refundRecord,CommonService commonService){
1863         try{
1864             if (RefundReturnDto.REFUND_STATUS_SUECCESS==refundReturnDto.getRefundStatus()
1865                     ||RefundReturnDto.REFUND_STATUS_PART==refundReturnDto.getRefundStatus()){
1866                 StringBuilder crmReturnData = new StringBuilder();
1867                 crmReturnData.append("<p>【CRM退款】</p>");
1868                 crmReturnData.append("<p>CRM退款流水号:").append(refundReturnDto.getRefundNo()).append("</p>");
1869                 crmReturnData.append("<p>已退款总金额:");
1870                 crmReturnData.append(refundReturnDto.getRefundTotal());
1871                 crmReturnData.append(";");
ac3d6e 1872                 crmReturnData.append("已退款其他金额:");
C 1873                 crmReturnData.append(refundReturnDto.getRefundAmountTotal());
1874                 crmReturnData.append(";");
d095b1 1875                 crmReturnData.append("已退款储值金:");
C 1876                 crmReturnData.append(refundReturnDto.getRefundRecharge());
1877                 crmReturnData.append(";");
1878                 crmReturnData.append("已退款增值金:");
1879                 crmReturnData.append(refundReturnDto.getRefundIncrement());
1880                 crmReturnData.append(";");
1881                 crmReturnData.append("已退款积分:");
1882                 crmReturnData.append(refundReturnDto.getRefundIntegral());
1883                 crmReturnData.append("</p>");
1884                 crmReturnData.append("<p>退款方式:</p>");
1885                 if(refundReturnDto.getRefundAmountModelDtoList() != null && refundReturnDto.getRefundAmountModelDtoList().size() > 0){
1886                     for(RefundAmountModelDto refundAmountModelDto1:refundReturnDto.getRefundAmountModelDtoList()){
1887                         crmReturnData.append("<p>");
1888                         switch (refundAmountModelDto1.getRefundType()){
1889                             case RefundAmountModelDto.REFUND_TYPE_WX:
1890                                 crmReturnData.append("微信[CRM]:").append(refundAmountModelDto1.getAmountTotal());
1891                                 break;
1892                             case RefundAmountModelDto.REFUND_TYPE_ZFB:
1893                                 crmReturnData.append("支付宝[CRM]:").append(refundAmountModelDto1.getAmountTotal());
1894                                 break;
1895                             default:
1896                                 crmReturnData.append("[").append(refundAmountModelDto1.getRefundType()).append("]");
1897                                 crmReturnData.append("未知方式[CRM]:").append(refundAmountModelDto1.getAmountTotal());
1898                         }
1899                         crmReturnData.append("</p>");
1900                     }
1901                 }
1902                 RefundRecordReceipt refundRecordReceipt = new RefundRecordReceipt();
a2bbf7 1903                 refundRecordReceipt.setReceiptSource(RefundRecordReceipt.RECEIPT_SOURCE_CRM);
C 1904                 refundRecordReceipt.setReceiptSourceNo(refundReturnDto.getRefundNo());
1905                 refundRecordReceipt.setReceiptSourceData(JSON.toJSONString(refundReturnDto));
d095b1 1906                 refundRecordReceipt.setReceiptType(RefundRecordReceipt.RECEIPT_TYPE_REFUND);
C 1907                 refundRecordReceipt.setRemarks(crmReturnData.toString());
1908                 refundRecordReceipt.setOperatorId(refundRecord.getOperatorId());
1909                 refundRecordReceipt.setOperatorNo(refundRecord.getOperatorNo());
1910                 refundRecordReceipt.setOperatorName(refundRecord.getOperatorName());
1911                 refundRecordReceipt.setRefundRecordId(refundRecord.getId());
1912                 commonService.insert(RefundRecordReceiptMapper.class,refundRecordReceipt);
1913             }
1914         }catch (Exception e){
1915             logger.error("退款生成CRM回执报错:{}",e);
1916         }
1917     }
1918
1919     /**
e3fa0c 1920      * 营销中心回调审批处理接口
Z 1921      * @param aduitDto
1922      * @return
1923      */
b9b969 1924     @Override
Z 1925     public PlatformResult partRefundApproval(AduitDto aduitDto) {
25d452 1926         logger.info("营销中心审批退款入参:{}",JSON.toJSONString(aduitDto));
b9b969 1927         SqlSentence sqlSentence = new SqlSentence();
Z 1928         Map<String,Object> map=new HashMap<>();
1929         sqlSentence.setM(map);
1930         map.put("applyId",aduitDto.getApplyId());
4df03d 1931         sqlSentence.sqlSentence("SELECT * FROM cancel_order WHERE applyId=#{m.applyId} and isDel=0 ",map);
b9b969 1932         CancelOrder cancelOrder=commonService.selectOne(CancelOrderMapper.class,sqlSentence);
61a0db 1933         if( cancelOrder == null ){
b9b969 1934             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到该审核标识");
Z 1935         }
c04e8a 1936         if(!CancelOrder.PENDING.equals(cancelOrder.getApprovalstatus())){
79f8fb 1937             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"该条审核标识已经处理过了,不要重复提交");
Z 1938         }
1939
edf5ea 1940         Map<String, String> operator=new HashMap<>();
Z 1941         operator.put("operatorId",cancelOrder.getOperatorId());
1942         operator.put("operatorName",cancelOrder.getOperatorName());
1943
b9b969 1944         //先判断项目的状态是否存在
c04e8a 1945         OrdersTotal ordersTotal= ordersTotalMapper.selectOneByKey(cancelOrder.getOrderId());
C 1946         if(ordersTotal==null){
1947             logger.info("取消订单流程:未找到总订单信息!订单id:{}",cancelOrder.getOrderId());
1948             return PlatformResult.failure(PlatformCode.ERROR_TIPS,"取消订单流程:未找到总订单信息!");
b9b969 1949         }
c04e8a 1950         
b9b969 1951         cancelOrder.setExamEmplId(aduitDto.getExamEmplId());
Z 1952         cancelOrder.setExamEmplName(aduitDto.getExamEmplName());
1953
c04e8a 1954         //获取退款记录
C 1955         RefundRecord refundRecord = commonService.selectOneByKey(RefundRecordMapper.class,cancelOrder.getRefundRecordId());
97a5fc 1956         if(refundRecord==null){
25d452 1957             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到该审核的退款记录");
97a5fc 1958         }
Z 1959
160383 1960         //订单节点日志
C 1961         OrdersNodeLog ordersNodeLog = new OrdersNodeLog();
1962         StringBuilder orderNodeBuilder = new StringBuilder();
1963
c04e8a 1964         if(BaseEntity.NO.equals(aduitDto.getType())){
160383 1965
C 1966             orderNodeBuilder.append("审核不通过");
1967             orderNodeBuilder.append("-最后审核人:").append(aduitDto.getExamEmplName());
1968
c04e8a 1969             //审核不通过
3badb7 1970             map.put("id",cancelOrder.getId());
C 1971             map.put("approvalstatus",CancelOrder.FAIL);
1972             map.put("approvalstatusOld",CancelOrder.PENDING);
1973             map.put("editTime",new Date());
1974             sqlSentence.sqlUpdate("approvalstatus = #{m.approvalstatus},editTime = #{m.editTime} WHERE id = #{m.id} AND approvalstatus = #{m.approvalstatusOld}",map);
1975             if(commonService.updateWhere(CancelOrderMapper.class,sqlSentence)!=1){
1976                 throw new TipsException("审核失败,审核状态已变更!");
1977             }
909b33 1978
df3f90 1979             //更改总订单退款状态
Z 1980             map.put("orderId",ordersTotal.getId());
4df03d 1981             sqlSentence.sqlSentence("select * from order_item WHERE  orderId=#{m.orderId} and isDel=0",map);
df3f90 1982             List<OrderItem> orderItemList=commonService.selectList(OrderItemMapper.class,sqlSentence);
Z 1983
832331 1984             List<Integer> collect = orderItemList.stream().map(OrderItem::getRefundStatus).collect(Collectors.toList());
df3f90 1985             if(collect.contains(OrderTotalConstants.STATUS_REFUND_PART)){
Z 1986                 ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
c04e8a 1987             }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE)
C 1988                     && collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
df3f90 1989                 ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
Z 1990             }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE)){
1991                 ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
c9f92c 1992             }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
df3f90 1993                 ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_FINSH);
c9f92c 1994             }else {
Z 1995                 ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
df3f90 1996             }
Z 1997
1998             map.put("refundStatus",ordersTotal.getRefundStatus());
909b33 1999             map.put("id",ordersTotal.getId());
4df03d 2000             sqlSentence.sqlSentence(" refundStatus=#{m.refundStatus}  WHERE id=#{m.id}  ",map);
909b33 2001             ordersTotalMapper.updateWhere(sqlSentence);
Z 2002
3badb7 2003             //退款单信息变更
C 2004             map.put("id",refundRecord.getId());
2005             map.put("refundStatus",RefundStatus.STATUS_INVALID_REFUND);
2006             map.put("refundStatusOld",RefundStatus.STATUS_APPLY_REFUND);
2007             map.put("editTime",new Date());
2008             sqlSentence.sqlUpdate("refundStatus = #{m.refundStatus},editTime = #{m.editTime} WHERE id = #{m.id} AND refundStatus = #{m.refundStatusOld}",map);
2009             if(commonService.updateWhere(RefundRecordMapper.class,sqlSentence) != 1){
2010                 throw new TipsException("审核失败,退款单状态已发生变更!");
2011             }
f5e288 2012
C 2013             //先赋值该作废操作人,后面会用到,注意,这里不存储
2014             refundRecord.setInvalidId(refundRecord.getOperatorId());
2015             refundRecord.setInvalidName(refundRecord.getInvalidName());
2016             refundRecord.setInvalidNo(refundRecord.getOperatorNo());
2017             refundRecord.setInvalidAppId(refundRecord.getOperatorAppId());
2018             refundRecord.setInvalidAppName(refundRecord.getOperatorAppName());
2019
160383 2020             //处理老带新的佣金,没有退款才退
C 2021             if(ordersTotal.getRefundStatus() == OrderTotalConstants.STATUS_REFUND_NONE){
2022                 oldBlingNewRefundFail(refundRecord,orderNodeBuilder,commonService);
2023             }
2024
edf5ea 2025             //拒绝审批需要还原回去储值金
Z 2026             //判断是否是充值订单,是的话需要把前面预扣的还原
bf63c3 2027             if(OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){
edf5ea 2028                 //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0
f5e288 2029                 //充值金额
b3fdea 2030                 OrderRefundCancelTool.rechargeHandle(ordersTotal,refundRecord,OrderRefundCancelTool.OPT_TYPE_CANCEL,"拒绝审批",orderNodeBuilder,commonService);
edf5ea 2031             }
f5e288 2032             //活动规则退款处理
b3fdea 2033             OrderRefundCancelTool.activityRuleHandle(ordersTotal,refundRecord,OrderRefundCancelTool.OPT_TYPE_CANCEL,"拒绝审批",orderNodeBuilder,commonService);
edf5ea 2034
160383 2035             ordersNodeLog.setCommonType(OrdersNodeLog.TYPE_COMMON_ORDER_REFUND);
C 2036             ordersNodeLog.setContent(orderNodeBuilder.toString());
2037             ordersNodeLog.setOrderId(ordersTotal.getId());
2038             commonService.insert(OrdersNodeLogMapper.class,ordersNodeLog);
2039
2040
b9b969 2041             return PlatformResult.success("拒绝取消审核通过");
Z 2042         }
c04e8a 2043
C 2044         cancelOrder.setEditTime(new Date());
2045         cancelOrder.setApprovalstatus(CancelOrder.SUCCESS);
2046         commonService.updateAll(CancelOrderMapper.class,cancelOrder);
97a5fc 2047
b9b969 2048         orderNodeBuilder.append("审核通过,开始处理退款");
Z 2049
edf5ea 2050
277835 2051         Map<String, Object>refund =handleRefundOrder(operator,refundRecord,ordersTotal,ordersNodeLog,orderNodeBuilder,cancelOrder);
b9b969 2052         return PlatformResult.success(refund);
Z 2053     }
df3f90 2054
Z 2055
97a5fc 2056     /**
Z 2057      * 全部退款处理退款逻辑
832331 2058      * @param orderRefundDto 退款信息
C 2059      * @return 结果
97a5fc 2060      */
Z 2061     @Override
4df03d 2062     public PlatformResult wholeRefund(OrderRefundDto orderRefundDto,ThirtApplication thirtApplication) {
97a5fc 2063
118d96 2064         OrdersTotal ordersTotal = ordersTotalMapper.selectOneByKey(orderRefundDto.getOrderId());
C 2065
d68a60 2066         OrderRefundDto parameter = getWholeRefundInfo(orderRefundDto, ordersTotal);
F 2067
2068         //调用退款处理退款逻辑
2069         return partRefund(ordersTotal,parameter,thirtApplication);
2070     }
2071
2072     /** 获取全部退款的详细信息 */
832331 2073     @Override
d68a60 2074     public OrderRefundDto getWholeRefundInfo(OrderRefundDto orderRefundDto, OrdersTotal ordersTotal){
F 2075         if(ordersTotal == null){
2076             ordersTotal = ordersTotalMapper.selectOneByKey(orderRefundDto.getOrderId());
2077         }
2078
97a5fc 2079         //获取该笔订单的项目详情
118d96 2080         List<Map<String, Object>> refundDetails=refundDetails(ordersTotal);
2e8393 2081
97a5fc 2082         // 退款信息集合
Z 2083         List<OrderItemRefundDto> refundList=new ArrayList<>();
2084         //退款二级子订单信息集合
2085         List<OrderItemSourceRefundDto> orderItemSourceRefundDtos;
2086         List<Map<String, Object>> refundSonDetails;
2087
2088         OrderItemRefundDto orderItemRefundDto;
2089         OrderItemSourceRefundDto orderItemSourceRefundDto;
2090         for (Map<String, Object> refundDetail : refundDetails) {
2e8393 2091             orderItemRefundDto = new OrderItemRefundDto();
97a5fc 2092             orderItemRefundDto.setOrderItemId(String.valueOf(refundDetail.get("id")));
Z 2093             orderItemRefundDto.setType(String.valueOf(refundDetail.get("type")));
2094
8eb9e6 2095             ////退款备注
C 2096             orderItemRefundDto.setRemarks(orderRefundDto.getRemarks());
2097             orderItemRefundDto.setRefundReason(orderRefundDto.getRefundReason());
2098
2e8393 2099             if(OrderItemConstants.TYPE_PROMOTION.equals(orderItemRefundDto.getType())
C 2100                     || OrderItemConstants.CARD_BAG.equals(orderItemRefundDto.getType())){
97a5fc 2101                 orderItemRefundDto.setRefundNum(0);
Z 2102                 refundSonDetails= (List<Map<String, Object>>) refundDetail.get("list");
2103                 orderItemSourceRefundDtos=new ArrayList<>();
2104                 for (Map<String, Object> refundSonDetail : refundSonDetails) {
2105                     orderItemSourceRefundDto=new OrderItemSourceRefundDto();
2106                     orderItemSourceRefundDto.setOrderItemSonId(String.valueOf(refundSonDetail.get("id")));
2107                     orderItemSourceRefundDto.setType(String.valueOf(refundSonDetail.get("type")));
2108                     orderItemSourceRefundDto.setRefundNum(Integer.parseInt(String.valueOf(refundSonDetail.get("notUsedNum"))));
8eb9e6 2109
e2a6c2 2110                     if(OrderItemConstants.TYPE_PROJECT.equals(orderItemRefundDto.getType()) && BaseEntity.YES.equals(orderRefundDto.getDeductionCancel())){
C 2111                         orderItemSourceRefundDto.setRefundDeductionCancelList((List<RefundDeductionCancelVo>) refundSonDetail.get("deductionList"));
2112                         if(orderItemSourceRefundDto.getRefundDeductionCancelList() != null){
2113                             for(RefundDeductionCancelVo refundDeductionCancelVo:orderItemSourceRefundDto.getRefundDeductionCancelList()){
2114                                 orderItemSourceRefundDto.setRefundNum(orderItemSourceRefundDto.getRefundNum()+refundDeductionCancelVo.getNum());
2115                             }
2116                         }
2117                     }
2118
8eb9e6 2119                     //退款备注
C 2120                     orderItemSourceRefundDto.setRemarks(orderRefundDto.getRemarks());
2121                     orderItemSourceRefundDto.setRefundReason(orderRefundDto.getRefundReason());
2122
97a5fc 2123                     orderItemSourceRefundDtos.add(orderItemSourceRefundDto);
Z 2124                 }
2125                 orderItemRefundDto.setOrderItemSourceRefundDtos(orderItemSourceRefundDtos);
e2a6c2 2126             }else{
97a5fc 2127                 orderItemRefundDto.setRefundNum(Integer.parseInt(refundDetail.get("notUsedNum").toString()) );
e2a6c2 2128
C 2129                 if(OrderItemConstants.TYPE_PROJECT.equals(orderItemRefundDto.getType()) && BaseEntity.YES.equals(orderRefundDto.getDeductionCancel())){
2130                     orderItemRefundDto.setRefundDeductionCancelList((List<RefundDeductionCancelVo>) refundDetail.get("deductionList"));
2131                     if(orderItemRefundDto.getRefundDeductionCancelList() != null){
2132                         for(RefundDeductionCancelVo refundDeductionCancelVo:orderItemRefundDto.getRefundDeductionCancelList()){
2133                             orderItemRefundDto.setRefundNum(orderItemRefundDto.getRefundNum()+refundDeductionCancelVo.getNum());
2134                         }
2135                     }
2136                 }
97a5fc 2137             }
Z 2138             refundList.add(orderItemRefundDto);
2139         }
2140         orderRefundDto.setRefundList(refundList);
2141
2142         //获取退款资金信息
118d96 2143         OrderRefundDto  parameter= nextStep(ordersTotal,orderRefundDto);
97a5fc 2144
Z 2145         parameter.setOperatorId(orderRefundDto.getOperatorId());
2146         parameter.setIsRefund(orderRefundDto.getIsRefund());
2147         parameter.setIsApproval(orderRefundDto.getIsApproval());
2148         parameter.setRoleId(orderRefundDto.getRoleId());
2149         parameter.setPlatformSource(orderRefundDto.getPlatformSource());
04ce22 2150         parameter.setRefundOperationType(BaseEntity.NO);
f19292 2151         parameter.setRemarks(orderRefundDto.getRemarks());
F 2152         parameter.setRefundReason(orderRefundDto.getRefundReason());
7f9228 2153         parameter.setCouponList(parameter.getPayCouponList());
2e8393 2154
C 2155         //退款金额
2156         List<OrderPayMethodDto> refundPayMethodList = parameter.getPayMethodList();
2157         for(OrderPayMethodDto orderPayMethodDto:refundPayMethodList){
2158             orderPayMethodDto.setRefundNumberNo(orderPayMethodDto.getPayMethodNo());
2159             orderPayMethodDto.setRefundNumberName(orderPayMethodDto.getPayMethodName());
2160             orderPayMethodDto.setMoney(orderPayMethodDto.getPayTotal());
2161         }
2162
d993aa 2163         parameter.setRefundPayMethod(refundPayMethodList);
C 2164
1eccbb 2165         //卡包订单是没有金额退回去的,跳过
49891d 2166         if(!OrderTotalConstants.TYPE_CARD_BAG.equals(ordersTotal.getType())){
C 2167             if(parameter.getTotalAmount().compareTo(ordersTotal.getActualTotal()) != 0){
2168                 throw new TipsException("退款金额与订单总金额不符!");
2169             }
1eccbb 2170             /*if(parameter.getTotalIntegral().compareTo(ordersTotal.getActualTotalPoints()) != 0){
49891d 2171                 throw new TipsException("退款积分与订单总积分不符!");
1eccbb 2172             }*/
e2a6c2 2173         }
C 2174
d68a60 2175         return parameter;
97a5fc 2176     }
b9b969 2177
250fca 2178     /**
25d452 2179      * 伪造退款处理退款逻辑
832331 2180      * @param orderRefundDto 退款信息
C 2181      * @return 结果
250fca 2182      */
Z 2183     @Override
2184     public PlatformResult forgePartRefund(OrderRefundDto orderRefundDto) {
25d452 2185         logger.info("退款打印参数:{}", JSON.toJSONString(orderRefundDto));
250fca 2186         //先判断项目的状态是否存在
Z 2187         OrdersTotal ordersTotal=null;
2188         try {
2189             ordersTotal=ordersTotalMapper.selectOneByKey(orderRefundDto.getOrderId());
2190             if(ordersTotal==null){
2191                 logger.info("取消订单流程:未找到总订单信息!订单id:{}",orderRefundDto.getOrderId());
2192                 return PlatformResult.failure(PlatformCode.ERROR_TIPS,"取消订单流程:未找到总订单信息!");
2193             }
2194         }catch (Exception e){
2195             logger.info("取消订单流程:根据订单id查询多条总订单信息!订单id:{}",orderRefundDto.getOrderId());
2196             return PlatformResult.failure(PlatformCode.ERROR_TIPS,"取消订单流程:根据订单id查询多条总订单信息!");
2197         }
2198
2199         if(!(OrderTotalConstants.STATUS_REFUND_NONE==ordersTotal.getRefundStatus()) &&
2200                 !(OrderTotalConstants.STATUS_REFUND_PART==ordersTotal.getRefundStatus())){
2201             throw new TipsException("订单标识错误,订单退款状态不正确!");
2202         }
2203
2204 //        orderRefundDto=parameterVerification(orderRefundDto);
2205
2206         return handleforgePartRefund(ordersTotal,orderRefundDto);
2207
2208     }
2209
892b96 2210
Z 2211
250fca 2212     /**
Z 2213      * 伪造处理退款详情
2214      */
2215     public PlatformResult  handleforgePartRefund(OrdersTotal ordersTotal,OrderRefundDto orderRefundDto){
2216
2217         //订单节点日志
2218         OrdersNodeLog ordersNodeLog = new OrdersNodeLog();
2219         StringBuilder orderNodeBuilder = new StringBuilder();
2220
86bf93 2221         orderNodeBuilder.append("开始退款(WZ)");
250fca 2222
Z 2223         // 获取退款方式,退款项目,退款优惠卷
2224         List<OrderPayMethodDto> refundPayMethod=orderRefundDto.getRefundPayMethod();
2225         List<OrderItemRefundDto> refundList=orderRefundDto.getRefundList();
2226         List<OrderCouponRefunDto> couponList=orderRefundDto.getCouponList();
2227
2228         //客户选的退款方式总金额
2229         BigDecimal sumMoney=refundPayMethod.stream().map(OrderPayMethodDto::getMoney).reduce(BigDecimal.ZERO,BigDecimal::add);
2230         //本次退款总金额
2231         BigDecimal refundSumMoney=refundList.stream().map(OrderItemRefundDto::getRefundMoney).reduce(BigDecimal.ZERO,BigDecimal::add);
2232
2233         if(!OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){
832331 2234             if(sumMoney.compareTo(refundSumMoney) > 0){
250fca 2235                 throw new TipsException("退款金额不能大于可退金额!");
Z 2236             }
832331 2237             orderNodeBuilder.append("-本次退款项目总金额:").append(refundSumMoney).append(",客户选的退款方式总金额:").append(sumMoney);
250fca 2238         }else {
832331 2239             orderNodeBuilder.append("-本次退款项目总金额:").append(ordersTotal.getActualTotal()).append(",客户选的退款方式总金额:").append(sumMoney);
250fca 2240         }
Z 2241
2242         Map<String, String> operator = ApiOrderUtil.getOperator(commonService, orderRefundDto.getOperatorId());//获取操作人信息
2243         SqlSentence sqlSentence = new SqlSentence();
2244         Map<String,Object> map=new HashMap<>();
2245         sqlSentence.setM(map);
2246
2247         //退款总记录
2248         orderNodeBuilder.append("-处理退款总记录");
2249         String totalCode = CreateNo.createTimeNo(systemParameterMapper, "R", 8, "yyyyMMddHHmmss");//总订单编号
25d452 2250         RefundRecord refundRecord=new RefundRecord(totalCode,ordersTotal.getShopId(),ordersTotal.getShopName(),sumMoney, RefundStatus.STATUS_APPLY_REFUND,0, RefundSoruceConstants.TYPE_SOURCE_ORDER,"phis退款",ordersTotal.getId(),ordersTotal.getUserId());
250fca 2251         refundRecord.setOperatorType(RefundRecord.OPERATOR_TYPE_EMPLOYEE);
Z 2252         Employee employee = commonService.selectOneByKey(EmployeeMapper.class,orderRefundDto.getOperatorId());
2253         refundRecord.setOperatorId(employee.getId());
2254         refundRecord.setRefundOperationType(orderRefundDto.getRefundOperationType());
2255         refundRecord.setOperatorName(employee.getCnName());
2256         refundRecordService.insert(refundRecord);
2257
832331 2258         if(refundPayMethod.size()>0){
250fca 2259             //处理退款方式记录表
4df03d 2260             handleRefundPayMethod(orderRefundDto,orderNodeBuilder,ordersTotal,refundRecord);
250fca 2261         }
Z 2262         if(couponList!=null && couponList.size()>0){
2263             //处理优惠卷
2264             handleOrderCouponRefunDto(couponList,orderNodeBuilder,ordersTotal,refundRecord);
2265         }
2266         try{
2267             orderNodeBuilder.append("-开始记录收入确认表");
2268             PerformanceInfoTool.handRefundPerformanceInfo(commonService,refundRecord);
2269             orderNodeBuilder.append("-记录收入确认表成功");
2270         }catch (Exception e){
2271             orderNodeBuilder.append("-记录收入确认表失败");
2272             logger.info("记录收入确认表,异常:{}",e.getMessage(),e);
071df8 2273             // 添加错误日志
A 2274             PerformanceInfoTool.addErrorLog(commonService, refundRecord.getId(), PerformanceInfo.ASSOCIATION_TYPE_GOODS_REFUND, e.getMessage());
250fca 2275         }
Z 2276         //记录操作日志
2277         orderNodeBuilder.append("-记录操作日志");
86bf93 2278         StringBuffer stringBuffer=new StringBuffer("操作人:"+operator.get("operatorName")+",进行退款(WZ)");
250fca 2279         OrderLog orderLog=new OrderLog(ordersTotal.getId(), OrderLogConstants.LOG_TYPE_REFUND,stringBuffer.toString()
Z 2280                 ,operator.get("operatorName"),operator.get("operatorId"),OrderTotalConstants.STATUS_CANCEL);
2281         commonService.insert(OrderLogMapper.class,orderLog);
2282
2283         orderNodeBuilder.append("-结束处理退款");
2284         ordersNodeLog.setCommonType(OrdersNodeLog.TYPE_COMMON_ORDER_REFUND);
2285         ordersNodeLog.setContent(orderNodeBuilder.toString());
2286         ordersNodeLog.setOrderId(ordersTotal.getId());
2287         commonService.insert(OrdersNodeLogMapper.class,ordersNodeLog);
2288
2289         return PlatformResult.success("成功");
2290     }
2291
892b96 2292     /**
Z 2293      * 根据订单 重新绑定订单退款状态
2294      *
2295      */
2296     @Override
2297     public void verifyOrderRefundStatus(OrdersTotal ordersTotalDto) {
2298         SqlSentence sqlSentence = new SqlSentence();
2299         Map<String, Object> sqlMap = new HashMap<>();
2300         sqlSentence.setM(sqlMap);
2301         sqlMap.put("isDel", BaseEntity.NO);
2302         sqlMap.put("orderId", ordersTotalDto.getId());
2303         sqlMap.put("type", OrderItemConstants.TYPE_PROJECT);
2304
4df03d 2305         sqlSentence.sqlSentence("SELECT * FROM  orders_total   WHERE  id = #{m.orderId}  and  isDel = #{m.isDel} ",sqlMap);
892b96 2306         OrdersTotal ordersTotal = ordersTotalMapper.selectOne(sqlSentence);
Z 2307         if(ordersTotal==null){
2308             throw new TipsException("订单标识错误,找不到订单!");
2309         }
2310         //查询二级订单
4df03d 2311         sqlSentence.sqlSentence("SELECT * FROM  order_item_source   WHERE  orderId = #{m.orderId}  and  type = #{m.type}  and  isDel = #{m.isDel} ",sqlMap);
892b96 2312         List<OrderItemSon> orderItemSonList=orderItemSonMapper.selectList(sqlSentence);
Z 2313
2314
2315         if(orderItemSonList!=null && orderItemSonList.size()>0){
2316             int oldRefundStatus;
2317             int newRefundStatus;
2318             UserProjectItem userProjectItem;
2319             for (OrderItemSon orderItemSon : orderItemSonList) {
2320                 if(OrderTotalConstants.STATUS_REFUND_FINSH==orderItemSon.getRefundStatus()){
2321                     oldRefundStatus=OrderTotalConstants.STATUS_REFUND_FINSH;
2322
ae6ff7 2323                     userProjectItem = PartialRefundUtil.getUserProject(orderItemSon.getId(),commonService);
892b96 2324
Z 2325                     if(userProjectItem.getNotUsedNum()>0){
2326                         newRefundStatus=OrderTotalConstants.STATUS_REFUND_PART;
2327                     }else {
2328                         newRefundStatus=oldRefundStatus;
2329                     }
2330
2331                     if(newRefundStatus!=oldRefundStatus){
2332                         sqlMap.put("refundStatus", newRefundStatus);
2333                         sqlMap.put("id", orderItemSon.getId());
4df03d 2334                         sqlSentence.sqlSentence(" refundStatus = #{m.refundStatus} WHERE id = #{m.id}  ",sqlMap);
892b96 2335                         orderItemSonMapper.updateWhere(sqlSentence);
Z 2336
2337                         sqlMap.put("refundStatus", newRefundStatus);
2338                         sqlMap.put("id", orderItemSon.getOrderItemId());
4df03d 2339                         sqlSentence.sqlSentence(" refundStatus = #{m.refundStatus} WHERE id = #{m.id}  ",sqlMap);
892b96 2340                         orderItemMapper.updateWhere(sqlSentence);
Z 2341                     }
2342
2343                 }
2344             }
2345             
2346         }
2347
2348         //查询二级订单
4df03d 2349         sqlSentence.sqlSentence("SELECT * FROM  order_item   WHERE  orderId = #{m.orderId}  and  type = #{m.type}  and  isDel = #{m.isDel} ",sqlMap);
892b96 2350         List<OrderItem> orderItemList=orderItemMapper.selectList(sqlSentence);
Z 2351         if(orderItemList!=null && orderItemList.size()>0){
2352             int oldRefundStatus;
2353             int newRefundStatus;
2354             UserProjectItem userProjectItem;
2355             for (OrderItem orderItem : orderItemList) {
2356                 oldRefundStatus=OrderTotalConstants.STATUS_REFUND_FINSH;
2357
ae6ff7 2358                 userProjectItem = PartialRefundUtil.getUserProject(orderItem.getId(),commonService);
892b96 2359
Z 2360                 if(userProjectItem.getNotUsedNum()>0){
2361                     newRefundStatus=OrderTotalConstants.STATUS_REFUND_PART;
2362                 }else {
2363                     newRefundStatus=oldRefundStatus;
2364                 }
2365
2366                 if(newRefundStatus!=oldRefundStatus){
2367                     sqlMap.put("refundStatus", newRefundStatus);
2368                     sqlMap.put("id", orderItem.getId());
4df03d 2369                     sqlSentence.sqlSentence(" refundStatus = #{m.refundStatus} WHERE id = #{m.id}  ",sqlMap);
892b96 2370                     orderItemMapper.updateWhere(sqlSentence);
Z 2371                 }
2372
2373             }
2374         }
2375
2376
2377         sqlMap.put("orderId",ordersTotal.getId());
4df03d 2378         sqlSentence.sqlSentence("select * from order_item WHERE  orderId=#{m.orderId} and isDel=0",sqlMap);
892b96 2379         List<OrderItem> orderItems=commonService.selectList(OrderItemMapper.class,sqlSentence);
Z 2380
832331 2381         List<Integer> collect = orderItems.stream().map(OrderItem::getRefundStatus).collect(Collectors.toList());
892b96 2382         if(collect.contains(OrderTotalConstants.STATUS_REFUND_PART)){
Z 2383             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
215be3 2384             ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY);
892b96 2385         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE) && collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
Z 2386             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
215be3 2387             ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY);
892b96 2388         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE)){
Z 2389             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
215be3 2390             ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY);
892b96 2391         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
Z 2392             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_FINSH);
2393             ordersTotal.setStatus(OrderTotalConstants.STATUS_CANCEL);
2394         }else {
2395             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
215be3 2396             ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY);
892b96 2397         }
Z 2398         ordersTotal.setEditTime(new Date());
2399         commonService.updateAll(OrdersTotalMapper.class,ordersTotal);
2400     }
2401
fd7281 2402     /**作废退款*/
C 2403     @Override
2404     public void refundCancel(RefundCancelVo refundCancelVo, RefundRecord refundRecord,Employee employee,EmployeeRole employeeRole
2405             , ThirtApplication thirtApplication) {
2406
2407         //判断退款单状态
2408         if(refundRecord.getRefundStatus() != RefundStatus.STATUS_SUCC_REFUND){
2409             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"操作失败,退款单状态错误!");
2410         }
2411
2412         //获取订单信息
2413         OrdersTotal ordersTotal = ordersTotalMapper.selectOneByKey(refundRecord.getOrderId());
2414         if(ordersTotal == null){
2415             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"操作失败,获取订单信息失败!");
2416         }
2417
da6435 2418         //检查升单关联逻辑
befece 2419         cancelRefundCheckRiseOrder(ordersTotal);
da6435 2420
fd7281 2421         SqlSentence sqlSentence = new SqlSentence();
C 2422         Map<String,Object> values = new HashMap<>();
2423         StringBuilder sql = new StringBuilder();
2424
478fa9 2425         //如果是线上退款,那么就不给作废
C 2426         values.put("refundRecordId",refundRecord.getId());
2427         sqlSentence.sqlSentence(" isDel = 0 AND refundRecordId = #{m.refundRecordId}",values);
2428         if(commonService.selectCount(RefundCashMapper.class,sqlSentence) > 0){
2429             throw new TipsException("该退款记录含线上退款,不能作废!");
2430         }
da6435 2431
fd7281 2432         //填充数据,后面会用到
C 2433         refundRecord.setInvalidType(RefundRecord.OPERATOR_TYPE_EMPLOYEE);
2434         refundRecord.setInvalidRemarks(refundCancelVo.getRemarks());
2435
2436         //****更新退款单信息,更新完退款单再去做剩下的操作
2437         values.put("refundStatus",RefundStatus.STATUS_REFUND_CANCEL);
2438         values.put("refundStatusOld",RefundStatus.STATUS_SUCC_REFUND);
2439         values.put("id",refundRecord.getId());
2440         values.put("invalidTime",new Date());
2441         values.put("invalidType",RefundRecord.OPERATOR_TYPE_EMPLOYEE);
2442         values.put("invalidRemarks",refundCancelVo.getRemarks());
2443         sql.append("refundStatus = #{m.refundStatus},invalidTime = #{m.invalidTime},invalidRemarks = #{m.invalidRemarks},invalidType = #{m.invalidType}");
2444
2445         if(employee != null){
2446             refundRecord.setInvalidId(employee.getId());
2447             refundRecord.setInvalidNo(employee.getEmployeeNo());
2448             refundRecord.setInvalidName(employee.getCnName());
2449             values.put("invalidId",employee.getId());
2450             values.put("invalidNo",employee.getEmployeeNo());
2451             values.put("invalidName",employee.getCnName());
2452             sql.append(",invalidId = #{m.invalidId},invalidNo = #{m.invalidNo},invalidName = #{m.invalidName}");
2453         }
2454         if(employeeRole != null){
2455             refundRecord.setInvalidRoleNo(employeeRole.getRoleUniqueStr());
2456             refundRecord.setInvalidRoleName(employeeRole.getRoleName());
2457             values.put("invalidRoleNo",employeeRole.getRoleUniqueStr());
2458             values.put("invalidRoleName",employeeRole.getRoleName());
2459             sql.append(",invalidRoleNo = #{m.invalidRoleNo},invalidRoleName = #{m.invalidRoleName}");
2460         }
2461         if(thirtApplication != null){
2462             refundRecord.setInvalidAppId(thirtApplication.getAppId());
2463             refundRecord.setInvalidAppCode(thirtApplication.getAppIdCode());
2464             refundRecord.setInvalidAppName(thirtApplication.getName());
2465             values.put("invalidAppId",thirtApplication.getAppId());
2466             values.put("invalidAppCode",thirtApplication.getAppIdCode());
2467             values.put("invalidAppName",thirtApplication.getName());
2468             sql.append(",invalidAppId = #{m.invalidAppId},invalidAppCode = #{m.invalidAppCode},invalidAppName = #{m.invalidAppName}");
2469         }
2470         sql.append(" WHERE id = #{m.id} AND refundStatus = #{m.refundStatusOld}");
2471         sqlSentence.sqlUpdate(sql.toString(),values);
2472         if(refundRecordMapper.updateWhere(sqlSentence) != 1){
2473             throw new PlatTipsException(PlatformCode.ERROR_TIPS,"操作失败,退款单状态已发生变化!");
2474         }
2475
b3fdea 2476         //订单系统日志
C 2477         StringBuilder orderNodeBuilder = new StringBuilder();
2478         orderNodeBuilder.append("开始作废退款");
2479
fd7281 2480         //判断订单类型
C 2481         if(OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){
2482             //充值订单
b3fdea 2483             OrderRefundCancelTool.rechargeHandle(ordersTotal,refundRecord,OrderRefundCancelTool.OPT_TYPE_CANCEL,"作废退款",orderNodeBuilder,commonService);
fd7281 2484         }else{
160c33 2485             //处理子单
C 2486             OrderRefundCancelTool.refundRecordItemHandle(ordersTotal,refundRecord,commonService);
fd7281 2487         }
C 2488
160c33 2489         //处理订单活动
b3fdea 2490         OrderRefundCancelTool.activityRuleHandle(ordersTotal,refundRecord,OrderRefundCancelTool.OPT_TYPE_CANCEL,"作废退款",orderNodeBuilder,commonService);
160c33 2491         //处理订单优惠券
b3fdea 2492         OrderRefundCancelTool.handCoupon(ordersTotal,refundRecord,orderNodeBuilder,commonService);
4ebb90 2493         //处理总退款方式
b3fdea 2494         List<RefundRecordMethod> refundRecordMethodList= OrderRefundCancelTool.refundRecordMotnedHandle(refundRecord,ordersTotal,orderNodeBuilder,commonService);
C 2495
2496         //操作的现金金额
2497         BigDecimal cashTotal = BigDecimal.ZERO;
2498         for(RefundRecordMethod refundRecordMethod:refundRecordMethodList){
2499             if(refundRecordMethod.getIsMoneyPay().equals(RefundRecordMethod.YES)){
2500                 cashTotal = cashTotal.add(refundRecordMethod.getActualTotal());
2501             }
2502         }
2503
2504         //报错订单系统日志
fd7281 2505
160c33 2506         //****更改总订单退款状态
C 2507         values.clear();
2508         values.put("orderId",ordersTotal.getId());
2509         sqlSentence.sqlSentence("select * from order_item WHERE orderId=#{m.orderId} and isDel=0",values);
2510         List<OrderItem> orderItemList=commonService.selectList(OrderItemMapper.class,sqlSentence);
2511
7c2538 2512         int oldStatus = ordersTotal.getStatus();
160c33 2513         values.clear();
C 2514         values.put("oldStatus",ordersTotal.getStatus());
2515         values.put("oldRefundStatus",ordersTotal.getRefundStatus());
2516
2517         List<Integer> collect = orderItemList.stream().map(OrderItem::getRefundStatus).collect(Collectors.toList());
2518         if(collect.contains(OrderTotalConstants.STATUS_REFUND_PART)){
2519             ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY);
2520             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
2521             ordersTotal.setReTotal(orderItemList.stream().map(OrderItem::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
2522         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE) && collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
2523             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
2524             ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY);
2525             ordersTotal.setReTotal(orderItemList.stream().map(OrderItem::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
2526         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE)){
2527             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
2528             ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY);
2529             ordersTotal.setReTotal(BigDecimal.ZERO);
2530         }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){
2531             ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_FINSH);
2532             ordersTotal.setStatus(OrderTotalConstants.STATUS_CANCEL);
2533             ordersTotal.setReTotal(orderItemList.stream().map(OrderItem::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add));
2534         }else {
2535             if(OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){
2536                 if(ordersTotal.getReTotal().compareTo(refundRecord.getRefundTotal()) == 0){
2537                     ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
2538                     ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY);
2539                     ordersTotal.setReTotal(ordersTotal.getReTotal().subtract(refundRecord.getRefundTotal()));
2540                 }else if(ordersTotal.getReTotal().compareTo(refundRecord.getRefundTotal()) > 0){
2541                     ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART);
2542                     ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY);
2543                     ordersTotal.setReTotal(ordersTotal.getReTotal().subtract(refundRecord.getRefundTotal()));
2544                 }
2545             }else{
2546                 ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE);
2547                 ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY);
2548                 ordersTotal.setReTotal(ordersTotal.getReTotal().subtract(refundRecord.getRefundTotal()));
2549             }
2550         }
2551         ordersTotal.setIsSyncOrder(BaseEntity.NO);
2552
2553         values.put("isSyncOrder",BaseEntity.NO);
2554         values.put("status",ordersTotal.getStatus());
2555         values.put("refundStatus",ordersTotal.getRefundStatus());
2556         values.put("reTotal",ordersTotal.getReTotal());
2557         values.put("id",ordersTotal.getId());
2558         sqlSentence.sqlUpdate("isSyncOrder = #{m.isSyncOrder},status = #{m.status},refundStatus = #{m.refundStatus},reTotal = #{m.reTotal}" +
2559                 " WHERE id = #{m.id} AND status = #{m.oldStatus} AND refundStatus = #{m.oldRefundStatus}",values);
2560         if(commonService.updateWhere(OrdersTotalMapper.class,sqlSentence) != 1){
2561             throw new TipsException("作废失败,订单状态已发生改变!");
2562         }
fd7281 2563
7c2538 2564         //初始化初复诊信息
C 2565         if(OrderTotalConstants.STATUS_CANCEL == oldStatus
2566                 && oldStatus != ordersTotal.getStatus()){
6ed28c 2567             // OrderUtil.reCalcOrderBothTheOneData(commonService, VisitRecordMapper.class,null,ordersTotal.getUserId(), BaseEntity.NO);
A 2568             // 处理方法调整
572fd8 2569             TimerHandleTool.addTask(commonService, TimerHandleItem.TYPE_RECALC_ORDER_BOTH, ordersTotal.getUserId(), null);
7c2538 2570         }
C 2571
b3fdea 2572         //额外的操作,升降级,收入确认表
26ebce 2573         additionalOperate(userLevelRuleService, ordersTotal,refundRecord,cashTotal,orderNodeBuilder,customParameter,commonService);
b3fdea 2574
C 2575         //记录日志(处理到具体节点(成功和失败))
2576         OrdersNodeLog ordersNodeLog = new OrdersNodeLog();
2577         orderNodeBuilder.append("-作废退款单结束");
2578         ordersNodeLog.setCommonType(OrdersNodeLog.TYPE_COMMON_ORDER_REFUND_CANCEL);
2579         ordersNodeLog.setContent(orderNodeBuilder.toString());
2580         ordersNodeLog.setOrderId(ordersTotal.getId());
2581         commonService.insert(OrdersNodeLogMapper.class,ordersNodeLog);
2582
2583     }
2584
2585     /**额外操作,不影响主流程*/
26ebce 2586     public static void additionalOperate(UserLevelRuleService userLevelRuleService, OrdersTotal ordersTotal,RefundRecord refundRecord,BigDecimal total,StringBuilder orderNodeBuilder,CustomParameter customParameter,CommonService commonService){
b3fdea 2587         if(BigDecimal.ZERO.compareTo(total) < 0){
C 2588             try {
2910fd 2589                 orderNodeBuilder.append("-开始处理作废退款用户升降级,金额:").append(total);
A 2590                 // 把原退款撤销返回金额为正所以是升级
2591                 UserLevelUtil.order(userLevelRuleService, ordersTotal.getUserId(),ordersTotal.getId(),total,refundRecord.getInvalidAppCode()==null?"phiskin":refundRecord.getInvalidAppCode());
2592                 orderNodeBuilder.append("-处理作废退款用户升降级成功");
b3fdea 2593             }catch (Exception e){
2910fd 2594                 String snapshot="处理作废退款用户升降级失败";
A 2595                 orderNodeBuilder.append("-处理作废退款用户升降级失败,异常原因:").append(e.getMessage());
2596                 logger.error("处理作废退款用户升降级失败:" + e.getMessage());
b3fdea 2597                 //发送企业微信通知给工作人员
C 2598                 SendNoticeUtil.failOrderSendNotice(ordersTotal,e.getMessage(),snapshot,commonService,customParameter);
2599             }
2600         }
2601         try{
2602             orderNodeBuilder.append("-开始记录收入确认表");
2603             PerformanceInfoTool.refundCancelPerformanceInfo(commonService,refundRecord);
2604             orderNodeBuilder.append("-记录收入确认表成功");
2605         }catch (Exception e){
2606             orderNodeBuilder.append("-记录收入确认表失败");
2607             logger.info("记录收入确认表,异常:{}",e.getMessage(),e);
2608             // 添加错误日志
2609             PerformanceInfoTool.addErrorLog(commonService, refundRecord.getId(), PerformanceInfo.ASSOCIATION_TYPE_GOODS_REFUND, e.getMessage());
2610         }
fd7281 2611     }
C 2612
e3b9cc 2613
C 2614     /**退现金到用户
2615      * 不是原路退,不执行第三方支付退款,直接跳过
2616      * @param refundCashVo 退款信息
2617      */
2618     private synchronized void refundCash(String refundRecordId,RefundCashVo refundCashVo){
2619         if(refundCashVo.getRefundCashItemVoList() == null || refundCashVo.getRefundCashItemVoList().size() == 0){
2620             return;
2621         }
2622
999c98 2623         //--合并同一个的退款支付方式
C 2624         //装载退款金额,key值:支付编码,value值:退款金额
e3b9cc 2625         Map<String,BigDecimal> refundMap = new HashMap<>();
C 2626         BigDecimal refundTotal;
2627         for(RefundCashItemVo refundCashItemVo:refundCashVo.getRefundCashItemVoList()){
2628             refundTotal = refundMap.computeIfAbsent(refundCashItemVo.getPaymentNo(),k->BigDecimal.ZERO);
2629             refundTotal = refundTotal.add(refundCashItemVo.getRefundTotal());
2630             refundMap.put(refundCashItemVo.getPaymentNo(),refundTotal);
2631         }
2632
999c98 2633
C 2634         SqlSentence sqlSentence = new SqlSentence();
2635         Map<String,Object> values = new HashMap<>();
2636
2637         //--获取已经退款的记录
2638         values.put("refundRecordId",refundRecordId);
2639         sqlSentence.sqlSentence("SELECT * FROM refund_cash WHERE isDel = 0 AND refundRecordId = #{m.refundRecordId}",values);
2640         List<RefundCash> refundCashList = commonService.selectList(RefundCashMapper.class,sqlSentence);
2641         //装载已退款的金额,key值:支付编码,value值:退款金额
2642         Map<String,BigDecimal> realRefundMap = new HashMap<>();
2643         BigDecimal consumeRefundTotal;
2644         for(RefundCash refundCash:refundCashList){
2645             consumeRefundTotal = realRefundMap.computeIfAbsent(refundCash.getPaymentNo(),k->BigDecimal.ZERO);
2646             consumeRefundTotal = consumeRefundTotal.add(refundCash.getRefundTotal());
2647             realRefundMap.put(refundCash.getPaymentNo(),consumeRefundTotal);
2648         }
2649
e3b9cc 2650         List<ConsumeNotify> consumeNotifyList;
C 2651         String refundNo;
2652         BigDecimal consumeTotal;
2653         int refundStatus;
2654         for (Map.Entry<String, BigDecimal> entry : refundMap.entrySet()) {
2655             refundTotal = entry.getValue();
2656             if(refundTotal.compareTo(BigDecimal.ZERO) < 1){
2657                 continue;
2658             }
2659
999c98 2660             //--获取支付信息(回调),计算可退款的金额
e3b9cc 2661             //初始化可退金额
C 2662             consumeTotal = BigDecimal.ZERO;
2663             consumeNotifyList = ConsumeTool.selectList(refundCashVo.getOrderId(),entry.getKey(),null,commonService);
2664             for(ConsumeNotify consumeNotify:consumeNotifyList){
2665                 //计算总可退款金额
2666                 consumeTotal = consumeTotal.add(consumeNotify.getPayAmount()).subtract(consumeNotify.getRefundTotal());
f3ff4e 2667             }
C 2668
999c98 2669             //--避免多退,要减去已退款
C 2670             consumeRefundTotal = realRefundMap.computeIfAbsent(entry.getKey(),k->BigDecimal.ZERO);
f3ff4e 2671             refundTotal = refundTotal.subtract(consumeRefundTotal);
C 2672             if(refundTotal.compareTo(BigDecimal.ZERO) < 1){
2673                 continue;
e3b9cc 2674             }
C 2675
2676             if(refundTotal.compareTo(consumeTotal) > 0){
2677                 //总退款金额比可退金额大,那么就不执行
798ce2 2678                 logger.error("第三方退款失败,退款金额比可退金额大,退款金额:{};可退基恩:{}",refundTotal,consumeTotal);
e3b9cc 2679                 continue;
C 2680             }
2681             for(ConsumeNotify consumeNotify:consumeNotifyList){
2682                 if(refundTotal.compareTo(BigDecimal.ZERO) < 1){
2683                     //退完,那么就跳出循环
2684                     continue;
2685                 }
2686                 if(consumeNotify.getRefundStatus() == ConsumeNotify.REFUND_STATUS_ALL){
2687                     //没有可退金额,那么跳出循环
2688                     continue;
2689                 }
2690                 //计算可退金额
2691                 consumeTotal = consumeNotify.getPayAmount().subtract(consumeNotify.getRefundTotal());
2692                 if(consumeTotal.compareTo(BigDecimal.ZERO) < 1){
2693                     //没有可退金额,那么跳出循环
2694                     continue;
2695                 }
2696                 refundStatus = ConsumeNotify.REFUND_STATUS_ALL;
2697                 if(consumeTotal.compareTo(refundTotal) > 0){
2698                     //可退金额比剩下要退的金额大
2699                     refundStatus = ConsumeNotify.REFUND_STATUS_PART;
2700                     consumeTotal = refundTotal;
2701                 }
2702                 //生成退款单号
2703                 refundNo = createNoService.createNo("RF",String.valueOf(System.currentTimeMillis()),6);
2704                 try {
7c75e2 2705                     //服务商退款,生成退款记录
C 2706                     consumeNotifyRefundService.consumeNotifyRefund(consumeNotify,refundStatus,consumeTotal,refundNo,refundRecordId);
e3b9cc 2707                 }catch (Exception e){
f3ff4e 2708                     logger.error("第三方退款失败,错误信息:",e);
e3b9cc 2709                 }
7c75e2 2710                 //已经退的跳过
C 2711                 refundTotal = refundTotal.subtract(consumeTotal);
e3b9cc 2712             }
C 2713         }
2714     }
2715
befece 2716     /** 作废退款校验升单逻辑 */
F 2717     public void cancelRefundCheckRiseOrder(OrdersTotal ordersTotal) {
44a123 2718         if(OrderTotalConstants.ADD_WAY_RISE.equals(ordersTotal.getAddWay())){
F 2719             throw new PlatTipsException(PlatformCode.ERROR_TIPS, "作废退款失败,升单订单暂时不可作废退款!");
2720         }
2721
2722         SqlSentence sqlSentence = new SqlSentence();
2723         Map<String,Object> values = new HashMap<>();
2724         sqlSentence.setM(values);
2725         StringBuilder sql = new StringBuilder();
2726
2727         //查询有关联升单,且升单的订单已支付,未全部退款的
2728         values.put("orderId", ordersTotal.getId());
2729         values.put("payStatus", OrderTotalConstants.PAY_STATUS_SUC);
2730         values.put("refundStatus", OrderTotalConstants.STATUS_REFUND_FINSH);
2731         sql.append(" select count(1) from order_rise r  ")
2732                 .append(" join orders_total t on t.id = r.orderId ")
2733                 .append(" where r.isDel = 0 and r.assocOrderId = #{m.orderId} ")
2734                 .append(" and t.payStatus = #{m.payStatus}  ");
2735         sqlSentence.setSqlSentence(sql.toString());
2736         if(commonService.selectCountSql(sqlSentence) > 0){
2737             throw new TipsException("作废退款失败,当前订单已被升单关联,暂时不可作废退款!");
2738         }
2739
2740     }
2741
2742     /** 作废退款校验升单逻辑V2 */
2743     public void cancelRefundCheckRiseOrderV2(OrdersTotal ordersTotal) {
2744
befece 2745         SqlSentence sqlSentence = new SqlSentence();
F 2746         Map<String,Object> values = new HashMap<>();
2747         sqlSentence.setM(values);
2748         StringBuilder sql = new StringBuilder();
2749
2750         //查询有关联升单,且升单的订单已支付,未全部退款的
34c581 2751         values.put("orderId", ordersTotal.getId());
befece 2752         values.put("payStatus", OrderTotalConstants.PAY_STATUS_SUC);
F 2753         values.put("refundStatus", OrderTotalConstants.STATUS_REFUND_FINSH);
e118d7 2754         sql.append(" select t.id, t.orderNo from order_rise r  ")
befece 2755                 .append(" join orders_total t on t.id = r.orderId ")
34c581 2756                 .append(" where r.isDel = 0 and r.assocOrderId = #{m.orderId} ")
e118d7 2757                 .append(" and t.payStatus = #{m.payStatus} and t.refundStatus != #{m.refundStatus} limit 1 ");
befece 2758         sqlSentence.setSqlSentence(sql.toString());
e118d7 2759         OrdersTotal riseOrder = commonService.selectOne(OrdersTotalMapper.class, sqlSentence);
F 2760         if(riseOrder != null){
2761             throw new PlatTipsException(PlatformCode.ERROR_TIPS, "作废退款失败,当前订单已被升单关联,请先退款升单的订单[" + riseOrder.getOrderNo() + "]!");
befece 2762         }
34c581 2763
e118d7 2764         //查询是否有被关联的升单订单最新退款成功的退款记录下的退款方式记录
F 2765         sql.setLength(0);
2766         values.clear();
2767         values.put("orderId", ordersTotal.getId());
2768         values.put("refundStatus", RefundStatus.STATUS_SUCC_REFUND);
44a123 2769         sql.append(" select m.* from refund_record_method m  ")
F 2770                 .append(" where m.isDel = 0 and m.refundRecordId = ( ")
e118d7 2771                 .append(" select r.id from refund_record r ")
F 2772                 .append(" join orders_total ot on ot.id = r.orderId ")
2773                 .append(" join order_rise ri on ri.orderId = r.orderId ")
2774                 .append(" where r.isDel = 0 and r.refundStatus = #{m.refundStatus} and ri.assocOrderId = #{m.orderId} ")
2775                 .append(" order by r.createTime desc limit 1 ")
2776                 .append(" ) ");
44a123 2777         sqlSentence.setSqlSentence(sql.toString());
e118d7 2778         List<RefundRecordMethod> methodList = commonService.selectList(RefundRecordMethodMapper.class, sqlSentence);
F 2779         if(methodList != null && methodList.size() > 0){
2780             //遍历存储累加相同的退款方式
2781             Map<String, BigDecimal> refundMethodMap = new HashMap<>();
2782             for(RefundRecordMethod recordMethod : methodList){
2783                 if(refundMethodMap.containsKey(recordMethod.getRefundNumberNo())){
2784                     refundMethodMap.put(recordMethod.getRefundNumberNo(), refundMethodMap.get(recordMethod.getRefundNumberNo()).add(recordMethod.getRealRefundTotal()));
2785                 }else{
2786                     refundMethodMap.put(recordMethod.getRefundNumberNo(), recordMethod.getRealRefundTotal());
2787                 }
2788             }
44a123 2789             logger.info("退款方式Map:{}", refundMethodMap.entrySet());
e118d7 2790             //查询订单支付方式
F 2791             sqlSentence.setSqlSentence(" select * from consume_pay where isDel = 0 and orderId = #{m.orderId} ");
2792             List<ConsumePay> consumePayList = commonService.selectList(ConsumePayMapper.class, sqlSentence);
2793             if(consumePayList == null || consumePayList.size() < 1){
2794                 throw new PlatTipsException(PlatformCode.ERROR_TIPS, "作废退款失败,找不到订单支付方式记录!");
2795             }
2796
2797             //遍历判断最新的升单退款方式是否都和原订单支付方式对的上
2798             BigDecimal refundMoney;
44a123 2799             for(ConsumePay consumePay : consumePayList){
e118d7 2800                 refundMoney = refundMethodMap.get(consumePay.getNumberNo());
F 2801                 if(refundMoney == null){
2802                     throw new PlatTipsException(PlatformCode.ERROR_TIPS, "作废退款失败,当前订单支付时有["+consumePay.getName()+"],关联的升单退款方式没有!");
2803                 }
2804                 if(refundMoney.compareTo(consumePay.getActualTotal()) == -1){
2805                     throw new PlatTipsException(PlatformCode.ERROR_TIPS, "作废退款失败,,当前订单["+consumePay.getName()+"]支付金额和关联的升单退款金额不一致!");
2806                 }
2807             }
2808         }
2809
44a123 2810         //---------------------------------------------------------------------------------
F 2811
2812
2813
2814         //判断如果是升单的订单,作废退款时,判断原订单是否已退款(正常原订单是退款,且作废退款不可能成功的)
2815         if(OrderTotalConstants.ADD_WAY_RISE.equals(ordersTotal.getAddWay())){
2816             sql.setLength(0);
2817             values.put("orderId", ordersTotal.getId());
2818             values.put("payStatus", OrderTotalConstants.PAY_STATUS_SUC);
2819             values.put("refundStatus", OrderTotalConstants.STATUS_REFUND_FINSH);
2820             sql.append(" SELECT COUNT(1) FROM orders_total ")
2821                     .append(" WHERE isDel = 0 and payStatus = #{m.payStatus} and refundStatus != #{m.refundStatus}  ")
2822                     .append(" and id in (  ")
2823                     .append(" select assocOrderId from order_rise where isDel = 0 and orderId = #{m.orderId} ")
2824                     .append(" ) ");
2825             sqlSentence.setSqlSentence(sql.toString());
2826             if(commonService.selectCountSql(sqlSentence) > 0){
2827                 throw new PlatTipsException(PlatformCode.ERROR_TIPS, "作废退款失败,当前订单升单时关联的原订单未全部退款,请先退款关联的原订单!");
2828             }
2829
2830             //查询原订单退款方式和支付方式是否一致,不一致不给退款
2831             sql.setLength(0);
2832             sql.append(" elect count(1) from refund_record_method m  ")
2833                     .append(" where m.isDel = 0 and (m.numberNo != refundNumberNo or actualTotal != realRefundTotal)  ")
2834                     .append(" and m.refundRecordId in ( ")
2835                     .append(" select r.id from refund_record r ")
2836                     .append(" join order_rise ri on ri.orderId = r.orderId ")
2837                     .append(" where r.isDel = 0 and r.refundStatus = 2 and ri.isDel = 0 and ri.orderId = #{m.orderId} ");
2838             sqlSentence.setSqlSentence(sql.toString());
2839             if(commonService.selectCountSql(sqlSentence) > 0){
2840                 throw new PlatTipsException(PlatformCode.ERROR_TIPS, "作废退款失败,当前订单升单时关联的原订单退款方式或金额不一致!");
2841             }
2842         }
befece 2843     }
44a123 2844
F 2845
4dc6e5 2846 }