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