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