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