package com.hx.phip.service.order.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.hx.common.service.CommonService; import com.hx.exception.TipsException; import com.hx.mybatisTool.SqlSentence; import com.hx.phiappt.common.*; import com.hx.phiappt.constants.tool.PerformanceInfoTool; import com.hx.phiappt.constants.tool.TimerHandleTool; import com.hx.phiappt.constants.tool.clubEquity.ClubEquityTool; import com.hx.phiappt.model.*; import com.hx.phiappt.model.activity.ActivityAction; import com.hx.phiappt.model.activity.ActivityRule; import com.hx.phiappt.model.consume.ConsumeNotify; import com.hx.phiappt.model.consume.ConsumePay; import com.hx.phiappt.model.coupon.CouponOrderDiscountLog; import com.hx.phiappt.model.order.*; import com.hx.phiappt.model.performance.PerformanceInfo; import com.hx.phiappt.model.refund.*; import com.hx.phiappt.model.user.UserCard; import com.hx.phiappt.model.user.UserProjectItem; import com.hx.phiappt.model.userMoney.UserMoneyUnclaimed; import com.hx.phiappt.vo.refund.RefundCashItemVo; import com.hx.phiappt.vo.refund.RefundCashVo; import com.hx.phip.config.BotoxClubConfig; import com.hx.phip.config.CustomParameter; import com.hx.phip.dao.mapper.*; import com.hx.phip.service.CreateNoService; import com.hx.phip.service.PaymentMethodService; import com.hx.phip.service.consume.ConsumeNotifyRefundService; import com.hx.phip.service.deduction.DeductionSingleService; import com.hx.phip.service.order.OrderRefundService; import com.hx.phip.service.refund.RefundRecordItemService; import com.hx.phip.service.refund.RefundRecordMethodService; import com.hx.phip.service.refund.RefundRecordService; import com.hx.phip.service.userLevel.UserLevelRuleService; import com.hx.phip.tool.CreateNo; import com.hx.phip.tool.deduction.DeductionSingleTool; import com.hx.phip.tool.payment.ConsumeTool; import com.hx.phip.tool.refund.OrderRefundCancelTool; import com.hx.phip.tool.refund.PartialRefundUtil; import com.hx.phip.tool.refund.PaymentCountTool; import com.hx.phip.tool.refund.RefundTool; import com.hx.phip.util.api.*; import com.hx.phip.vo.order.payment.PayMethodVo; import com.hx.phip.vo.order.refund.DistributionRedundMethodVo; import com.hx.phip.vo.order.refund.DistributionRedundVo; import com.hx.resultTool.Result; import com.hx.util.StringUtils; import com.hz.crm.dto.order.refund.RefundAmountModelDto; import com.hz.crm.dto.order.refund.RefundDto; import com.hz.crm.dto.order.refund.RefundReturnDto; import com.hz.crm.feign.FOderService; import com.hz.his.dto.aduit.AduitDto; import com.hz.his.dto.marketing.OrderPartRefundDto; import com.hz.his.dto.marketing.PartRefundPayDto; import com.hz.his.dto.marketing.RefundProjectDto; import com.hz.his.dto.order.*; import com.hz.his.feign.service.dcp.SUserTagInfoService; import com.hz.his.feign.service.marketing.MOrderService; import com.hz.his.vo.order.refund.RefundCancelVo; import com.hz.his.vo.order.refund.RefundDeductionCancelVo; import com.hz.pay.feign.centre.refund.FRefundService; import com.platform.entity.ThirtApplication; import com.platform.exception.PlatTipsException; import com.platform.resultTool.PlatformCode; import com.platform.resultTool.PlatformResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.stream.Collectors; /** * @author CJH * 重构与2023-03-20 */ @Transactional @Service public class OrderRefundServiceImpl implements OrderRefundService { /**log4j日志*/ private static final Logger logger = LoggerFactory.getLogger(OrderRefundServiceImpl.class.getName()); @Resource private OrdersTotalMapper ordersTotalMapper; @Resource private OrderItemMapper orderItemMapper; @Resource private RefundRecordMapper refundRecordMapper; @Resource private OrderItemSonMapper orderItemSonMapper; @Resource private ConsumeNotifyRefundService consumeNotifyRefundService; @Resource private UserLevelRuleService userLevelRuleService; @Resource private CommonService commonService; @Resource private FOderService fOderService; @Resource private SystemParameterMapper systemParameterMapper; @Resource private RefundRecordService refundRecordService; @Resource private PaymentMethodService paymentMethodService; @Resource private RefundRecordMethodService refundRecordMethodService; @Resource private RefundRecordItemService refundRecordItemService; @Resource private RefundRecordItemSourceMapper refundRecordItemSourceMapper; @Resource private CustomParameter customParameter; @Resource private MOrderService mOrderService; @Resource private CouponOrderDiscountLogMapper couponOrderDiscountLogMapper; @Resource private RefundRecordCouponMapper refundRecordCouponMapper; @Resource private CardEquityMapper cardEquityMapper; @Resource private RefundMapper refundMapper; @Resource private CreateNoService createNoService; @Resource private FRefundService fRefundService; @Resource private DeductionSingleService deductionSingleService; @Resource private SUserTagInfoService sUserTagInfoService; @Resource private BotoxClubConfig botoxClubConfig; /** * 获取退款页面详情 * @param ordersTotal 订单 * @return 可退款数量详情 */ @Override public List> refundDetails(OrdersTotal ordersTotal) { SqlSentence sqlSentence = new SqlSentence(); Map sqlMap = new HashMap<>(); sqlSentence.setM(sqlMap); sqlMap.put("isDel", BaseEntity.NO); sqlMap.put("orderId", ordersTotal.getId()); //一级子订单 sqlSentence.sqlSentence("SELECT * FROM order_item WHERE orderId = #{m.orderId} AND isDel = #{m.isDel}",sqlMap); List orderItemList = orderItemMapper.selectList(sqlSentence); List> orderItems = new ArrayList<>(); for (OrderItem orderItem : orderItemList) { //判断这个项目能不能显示处理 switch (orderItem.getType()) { case OrderItemConstants.TYPE_PROJECT: handleOrderItemIsProject(orderItems,orderItem); break; case OrderItemConstants.TYPE_RETAIL: handleOrderItemIsRetail(orderItems,orderItem); break; case OrderItemConstants.TYPE_DRUG: handleOrderItemIsRetail(orderItems, orderItem); break; case OrderItemConstants.TYPE_CARD: handleOrderItemIsCard(orderItems, orderItem); break; case OrderItemConstants.TYPE_PROMOTION: handleOrderItemIsPromotion(orderItems, orderItem); break; case OrderItemConstants.CARD_BAG: handleOrderItemIsCardBag(orderItems, orderItem); break; case OrderItemConstants.TYPE_COUPON: handleOrderItemIsRetail(orderItems,orderItem); break; default: break; } } return orderItems; } /** * 处理一级是项目的 */ public void handleOrderItemIsProject(List> orderItems, OrderItem orderItem) { //获取用户项目 UserProjectItem userProjectItem = PartialRefundUtil.getUserProject(orderItem.getId(),commonService); if(userProjectItem == null){ throw new TipsException("用户项目获取失败!"); } orderItems.add(itemRefandDataPackage(orderItem,null,userProjectItem,null)); } /**订单子项退款信息封装*/ public Map itemRefandDataPackage(OrderItem orderItem,OrderItemSon orderItemSon,UserProjectItem userProjectItem,List userCardList){ Map itemData = new HashMap<>(); if(orderItemSon != null){ itemData.put("id",orderItemSon.getId()); itemData.put("type",orderItemSon.getType()); itemData.put("goodsName",orderItemSon.getGoodsName()); itemData.put("curPrice",orderItemSon.getCurPrice()); itemData.put("specs",orderItemSon.getSpecs()); itemData.put("buyNum",orderItemSon.getBuyNum()); itemData.put("hasReNum",orderItemSon.getHasReNum()); itemData.put("notUsedNum",orderItemSon.getBuyNum()-orderItemSon.getHasReNum()); }else{ itemData.put("id",orderItem.getId()); itemData.put("type",orderItem.getType()); itemData.put("goodsName",orderItem.getGoodsName()); itemData.put("curPrice",orderItem.getCurPrice()); itemData.put("specs",orderItem.getSpecs()); itemData.put("buyNum",orderItem.getBuyNum()); itemData.put("hasReNum",orderItem.getHasReNum()); itemData.put("notUsedNum",orderItem.getBuyNum()-orderItem.getHasReNum()); } if(userProjectItem != null){ itemData.put("notUsedNum",userProjectItem.getNotUsedNum()); } if(userCardList != null){ itemData.put("notUsedNum",userCardList.size()); } return itemData; } /** * 处理一级是商品的 */ public void handleOrderItemIsRetail(List> orderItems, OrderItem orderItem) { orderItems.add(itemRefandDataPackage(orderItem,null,null,null)); } /** * 处理一级是卡项的 */ public void handleOrderItemIsCard(List> orderItems,OrderItem orderItem) { SqlSentence sqlSentence = new SqlSentence(); Map sqlMap = new HashMap<>(); //获取用户卡项 List userCardList = PartialRefundUtil.getRefundCard(orderItem.getId(),UserProjectConstants.EFF_STATUS_YES,commonService); //信息封装 Map itemData = itemRefandDataPackage(orderItem,null,null,userCardList); //获取卡项的详细条目 sqlMap.put("commonId",orderItem.getCommonId()); sqlSentence.sqlSentence(" SELECT groupName,shareMoney FROM card_equity WHERE cardItemId = #{m.commonId} ",sqlMap); List> cardEquitys = cardEquityMapper.selectListMap(sqlSentence); itemData.put("list", cardEquitys); orderItems.add(itemData); } /** * 处理一级是促销的 */ public void handleOrderItemIsPromotion(List> orderItems, OrderItem orderItem) { SqlSentence sqlSentence = new SqlSentence(); Map sqlMap = new HashMap<>(); //封装参数 Map itemData = itemRefandDataPackage(orderItem,null,null,null); //获取二级子订单 sqlMap.put("orderItemId", orderItem.getId()); sqlSentence.sqlSentence("SELECT * FROM order_item_source WHERE orderItemId = #{m.orderItemId} AND isDel = 0 ",sqlMap); List orderItemSonList = orderItemSonMapper.selectList(sqlSentence); if (orderItemSonList == null) { return; } List> promotionList = new ArrayList<>(); for (OrderItemSon orderItemSon : orderItemSonList) { //判断这个项目能不能显示处理 switch (orderItemSon.getType()) { case OrderGoodsConstants.TYPE_PROJECT: handleOrderItemSonIsProject(promotionList, orderItemSon); break; case OrderItemConstants.TYPE_RETAIL: handleOrderItemSonIsRetail(promotionList, orderItemSon); break; default: break; } } itemData.put("list", promotionList); orderItems.add(itemData); } /** * 处理一级是卡包 */ public void handleOrderItemIsCardBag(List> orderItems, OrderItem orderItem) { SqlSentence sqlSentence = new SqlSentence(); Map sqlMap = new HashMap<>(); Map itemData = itemRefandDataPackage(orderItem,null,null,null); //二级子订单 sqlMap.put("orderItemId", orderItem.getId()); sqlSentence.sqlSentence("SELECT * FROM order_item_source WHERE orderItemId= #{m.orderItemId} and isDel = 0 ",sqlMap); List orderItemSonList = orderItemSonMapper.selectList(sqlSentence); if (orderItemSonList == null) { return; } List> promotionList = new ArrayList<>(); for (OrderItemSon orderItemSon : orderItemSonList) { //判断这个项目能不能显示处理 switch (orderItemSon.getType()) { case OrderGoodsConstants.TYPE_PROJECT: handleOrderItemSonIsProject(promotionList, orderItemSon); break; case OrderItemConstants.TYPE_RETAIL: handleOrderItemSonIsRetail(promotionList, orderItemSon); break; default: break; } } itemData.put("list", promotionList); orderItems.add(itemData); } /** * 处理二级是项目的 */ public void handleOrderItemSonIsProject(List> promotionList, OrderItemSon orderItemSon) { //获取用户项目 UserProjectItem userProjectItem = PartialRefundUtil.getUserProject(orderItemSon.getId(),commonService); if(userProjectItem == null){ throw new TipsException("用户项目获取失败[24]!"); } Map itemData = itemRefandDataPackage(null,orderItemSon,userProjectItem,null); promotionList.add(itemData); } /** * 处理二级是商品的 */ public void handleOrderItemSonIsRetail(List> promotionList, OrderItemSon orderItemSon) { promotionList.add(itemRefandDataPackage(null,orderItemSon,null,null)); } /** * 退款选择退款数量组装金额信息,退款里面这个非常重要 * @param orderRefundDto 退款数量信息 * @return 退款金额信息 */ @Override public OrderRefundDto nextStep(OrdersTotal ordersTotal,OrderRefundDto orderRefundDto) { logger.info("退款选择退款数量组装金额信息入参:{}", JSON.toJSONString(orderRefundDto)); //子单退款 List refundList = orderRefundDto.getRefundList(); //支付方式退款数据整合 List refundPayMethods = new ArrayList<>(); //可退款总金额 BigDecimal totalAmount = BigDecimal.ZERO; //可退款总积分 BigDecimal totalIntegral = BigDecimal.ZERO; if (OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())) { ///////充值订单退款 refundPayMethods = rechargeRefundWay(ordersTotal); for (OrderPayMethodDto orderPayMethodDto : refundPayMethods) { if(PayMethodTypeConstants.PAY_INTEGRAL.equals(orderPayMethodDto.getPayMethodNo())){ totalIntegral = totalIntegral.add(orderPayMethodDto.getPayTotal()); }else{ totalAmount = totalAmount.add(orderPayMethodDto.getPayTotal()).setScale(2,RoundingMode.HALF_UP); } } }else{ //////其他订单类型 //整合支付方式退款金额 Map orderPayMethodDtoMap = new HashMap<>(); OrderPayMethodDto orderPayMethodDto; DistributionRedundVo distributionRedundVo; OrderItem orderItem; //计算每个条目需要退多少钱 for (OrderItemRefundDto orderItemRefundDto : refundList) { if(StringUtils.isEmpty(orderItemRefundDto.getOrderItemId())){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款项标识必填"); } orderItem = orderItemMapper.selectOneByKey(orderItemRefundDto.getOrderItemId()); if (orderItem == null) { throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款项标识错误"); } if(!orderItem.getOrderId().equals(ordersTotal.getId())){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到退款项[012]"); } //判断这个项目能不能显示处理 switch (orderItem.getType()) { case OrderItemConstants.TYPE_PROJECT: distributionRedundVo = itemOneRefund(orderItem,orderItemRefundDto); break; case OrderItemConstants.TYPE_RETAIL: distributionRedundVo = itemOneRefund(orderItem,orderItemRefundDto); break; case OrderItemConstants.TYPE_DRUG: distributionRedundVo = itemOneRefund(orderItem,orderItemRefundDto); break; case OrderItemConstants.TYPE_CARD: distributionRedundVo = itemOneRefund(orderItem,orderItemRefundDto); break; case OrderItemConstants.TYPE_PROMOTION: distributionRedundVo = nextStepIsPromotion(orderItem,orderItemRefundDto); break; case OrderItemConstants.CARD_BAG: distributionRedundVo = nextStepIsPromotion(orderItem,orderItemRefundDto); break; case OrderItemConstants.TYPE_COUPON: distributionRedundVo = itemOneRefund(orderItem,orderItemRefundDto); break; default: throw new TipsException("未知商品类型[008]!"); } //数据填充 orderItemRefundDto.setApproveRefundTotal(distributionRedundVo.getRefundTotal()); orderItemRefundDto.setType(distributionRedundVo.getGoodsType()); orderItemRefundDto.setGoodsName(distributionRedundVo.getGoodsName()); //可退款金额计算 totalAmount = totalAmount.add(distributionRedundVo.getRefundTotal()).setScale(2,RoundingMode.HALF_UP); //可退款积分计算 totalIntegral = totalIntegral.add(distributionRedundVo.getRefundIntegral()); //整合可退款方式金额 for(DistributionRedundMethodVo refundPaymentMethodVo:distributionRedundVo.getDistributionRedundMethodVoList()){ orderPayMethodDto = orderPayMethodDtoMap.computeIfAbsent(refundPaymentMethodVo.getNumberNo(), k->new OrderPayMethodDto(refundPaymentMethodVo.getNumberNo(),refundPaymentMethodVo.getName(),BigDecimal.ZERO,refundPaymentMethodVo.getIsMoneyPay(),refundPaymentMethodVo.getIsExecute())); orderPayMethodDto.setPayTotal(orderPayMethodDto.getPayTotal().add(refundPaymentMethodVo.getRefundTotal()).setScale(2,RoundingMode.HALF_UP)); } } for(Map.Entry entry : orderPayMethodDtoMap.entrySet()) { refundPayMethods.add(entry.getValue()); } } //支付方式 orderRefundDto.setPayMethodList(refundPayMethods); //可退总金额 orderRefundDto.setTotalAmount(totalAmount); //可退总积分 orderRefundDto.setTotalIntegral(totalIntegral); //优惠券 List couponList = nextStepIsCoupon(ordersTotal.getId()); orderRefundDto.setPayCouponList(couponList); return orderRefundDto; } /**获取充值单的退款方式金额*/ public List rechargeRefundWay(OrdersTotal ordersTotal){ //获取总支付方式 List payMethodVoList = refundMapper.getConsumePayGroupByNumberNo(ordersTotal.getId()); List consumeList = new ArrayList<>(); OrderPayMethodDto orderPayMethodDto; //充值订单只能全退 for (PayMethodVo payMethodVo:payMethodVoList) { //支付方式可退金额 orderPayMethodDto=new OrderPayMethodDto(); orderPayMethodDto.setPayMethodNo(payMethodVo.getNumberNo()); orderPayMethodDto.setPayMethodName(payMethodVo.getName()); orderPayMethodDto.setRefundNumberNo(payMethodVo.getNumberNo()); orderPayMethodDto.setRefundNumberName(payMethodVo.getName()); orderPayMethodDto.setPayTotal(payMethodVo.getSurplusTotal()); orderPayMethodDto.setMoney(orderPayMethodDto.getPayTotal()); consumeList.add(orderPayMethodDto); } return consumeList; } /** * 判断是否有使用优惠卷 */ public List nextStepIsCoupon(String orderId) { SqlSentence sqlSentence = new SqlSentence(); Map sqlMap = new HashMap<>(); sqlMap.put("isDel", BaseEntity.NO); sqlMap.put("orderId", orderId); sqlMap.put("status", BaseEntity.NO); sqlSentence.sqlSentence("SELECT id,title FROM coupon_order_discount_log WHERE orderId=#{m.orderId} AND status = #{m.status} AND isDel= #{m.isDel} ",sqlMap); List couponOrderDiscountLogs = couponOrderDiscountLogMapper.selectList(sqlSentence); //拼接返回参数 List consumeList=new ArrayList<>(); OrderCouponRefunDto orderCouponRefunDto; for (CouponOrderDiscountLog couponOrderDiscountLog : couponOrderDiscountLogs) { orderCouponRefunDto=new OrderCouponRefunDto(); orderCouponRefunDto.setOrderCouponId(couponOrderDiscountLog.getId()); orderCouponRefunDto.setOrderCouponTitle(couponOrderDiscountLog.getTitle()); consumeList.add(orderCouponRefunDto); } return consumeList; } /** * 一级子单计算可退款金额 * @param orderItemRefundDto 封装的方法 * @return 退款金额 */ public DistributionRedundVo itemOneRefund(OrderItem orderItem,OrderItemRefundDto orderItemRefundDto) { if(orderItemRefundDto.getRefundNum() == null) { throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请填写退款数量!"); } if(orderItemRefundDto.getRefundNum() < 1) { throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款数量不能小于1"); } ////算数量,退款用 //总数量 Integer buyNum; //剩余数量 Integer surplusNum; if(OrderItemConstants.TYPE_PROJECT.equals(orderItem.getType())){ //////项目 UserProjectItem userProjectItem = PartialRefundUtil.getUserProject(orderItem.getId(),commonService); if(userProjectItem == null){ throw new TipsException("用户项目获取失败!"); } buyNum = userProjectItem.getUsedTotal(); surplusNum = userProjectItem.getNotUsedNum(); //加上划扣的数量 List refundDeductionCancelList = DeductionSingleTool.countDeductionData(userProjectItem.getId(),orderItemRefundDto.getRefundDeductionCancelList(),commonService); orderItemRefundDto.setRefundDeductionCancelList(refundDeductionCancelList); for(RefundDeductionCancelVo refundDeductionCancelVo:refundDeductionCancelList){ surplusNum = surplusNum+refundDeductionCancelVo.getNum(); } if(orderItemRefundDto.getRefundNum() > surplusNum){ throw new TipsException("退款数量与可退数量不符[01]!"); } //替换成子单的剩余数量 surplusNum = orderItem.getUsedTotal() - orderItem.getHasReNum(); }else if(OrderItemConstants.TYPE_CARD.equals(orderItem.getType())){ ///////卡项 //获取可退款的卡项次数 List userCardList = PartialRefundUtil.getRefundCard(orderItem.getId(),UserProjectConstants.EFF_STATUS_YES,commonService); buyNum = orderItem.getBuyNum(); surplusNum = userCardList.size(); if(orderItemRefundDto.getRefundNum() > surplusNum){ throw new TipsException("退款数量与可退数量不符[02]!"); } //替换成子单的剩余数量,2023-06-15因为做用户卡包退款原因,先屏掉这个 //surplusNum = orderItem.getBuyNum() - orderItem.getHasReNum(); }else{ buyNum = orderItem.getBuyNum(); //替换成子单的剩余数量 surplusNum = orderItem.getBuyNum() - orderItem.getHasReNum(); } if(orderItemRefundDto.getRefundNum() > surplusNum){ throw new TipsException("退款数量与可退数量不符[03]!"); } //获取该子单的支付方式,相同的支付方式求和返回 List payMethodVoList = refundMapper.getConsumePayOneGroupByNumberNo(orderItem.getId()); //获取该子单已退的总金额 RefundRecordItem refundRecordItem = RefundTool.getOneAlreadyRefundTotal(orderItem.getId(),orderItem.getType(),commonService); //计算退款方式金额 DistributionRedundVo distributionRedundVo = PaymentCountTool.countMakeWay(orderItem.getId(),orderItem.getActualTotal(),refundRecordItem.getOccupyRefundTotal() ,refundRecordItem.getOccupyRefundIntegral(),buyNum,surplusNum,null,orderItemRefundDto.getRefundNum(),payMethodVoList,commonService); distributionRedundVo.setGoodsType(orderItem.getType()); distributionRedundVo.setGoodsName(orderItem.getGoodsName()); return distributionRedundVo; } /** * 二级子单计算可退款金额 * @param orderItemSourceRefundDto 封装的方法 * @return 退款金额 */ public DistributionRedundVo itemTwoRefund(OrderItemSon orderItemSon,OrderItemSourceRefundDto orderItemSourceRefundDto) { if(orderItemSourceRefundDto.getRefundNum() == null) { throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请填写退款数量!"); } if(orderItemSourceRefundDto.getRefundNum() < 1) { throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款数量不能小于1"); } ////算数量 //总数量 Integer buyNum; //剩余数量 Integer surplusNum; UserProjectItem userProjectItem; if(OrderItemConstants.TYPE_PROJECT.equals(orderItemSon.getType())){ //获取用户项目 userProjectItem = PartialRefundUtil.getUserProject(orderItemSon.getId(),commonService); if(userProjectItem == null){ throw new TipsException("用户项目获取失败!"); } buyNum = userProjectItem.getUsedTotal(); surplusNum = userProjectItem.getNotUsedNum(); //加上划扣的数量 List refundDeductionCancelList = DeductionSingleTool.countDeductionData(userProjectItem.getId(),orderItemSourceRefundDto.getRefundDeductionCancelList(),commonService); orderItemSourceRefundDto.setRefundDeductionCancelList(refundDeductionCancelList); for(RefundDeductionCancelVo refundDeductionCancelVo:refundDeductionCancelList){ surplusNum = surplusNum+refundDeductionCancelVo.getNum(); } if(orderItemSourceRefundDto.getRefundNum() > surplusNum){ throw new TipsException("退款数量与可退数量不符[04]!"); } //替换成子单 surplusNum = orderItemSon.getUsedTotal() - orderItemSon.getHasReNum(); }else{ buyNum = orderItemSon.getBuyNum(); surplusNum = orderItemSon.getBuyNum() - orderItemSon.getHasReNum(); } if(orderItemSourceRefundDto.getRefundNum() > surplusNum){ throw new TipsException("退款数量与可退数量不符[05]!"); } //获取该子单的支付方式,相同的支付方式算和返回 List payMethodVoList = refundMapper.getConsumePayTwoGroupByNumberNo(orderItemSon.getId()); //获取该子单已退的总金额 RefundRecordItemSource refundRecordItemSource = RefundTool.getTwoAlreadyRefundTotal(orderItemSon.getId(),commonService); //计算退款方式金额 DistributionRedundVo distributionRedundVo = PaymentCountTool.countMakeWay(orderItemSon.getId(),orderItemSon.getActualTotal(),refundRecordItemSource.getOccupyRefundTotal() ,refundRecordItemSource.getOccupyRefundIntegral(),buyNum,surplusNum,null,orderItemSourceRefundDto.getRefundNum(),payMethodVoList,commonService); distributionRedundVo.setGoodsType(orderItemSon.getType()); distributionRedundVo.setGoodsName(orderItemSon.getGoodsName()); return distributionRedundVo; } /** * 一级是促销 */ public DistributionRedundVo nextStepIsPromotion(OrderItem orderItem,OrderItemRefundDto orderItemRefundDto) { List orderItemSourceRefundDtos = orderItemRefundDto.getOrderItemSourceRefundDtos(); if (orderItemSourceRefundDtos == null) { throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款数量不能小于1"); } //2022-12-29 荣爷说因为优惠卷超过了金额,数据库是负数,所以退款取0 if(orderItem.getActualTotal().compareTo(BigDecimal.ZERO)<1){ orderItem.setActualTotal(BigDecimal.ZERO); } //返回结构 DistributionRedundVo distributionRedundVo = new DistributionRedundVo(); //整合当前一级子单的退款金额数据,key值:支付方式编号 Map refundPaymentMethodVoMap = new HashMap<>(); DistributionRedundMethodVo refundPaymentMethodVo; DistributionRedundVo distributionRedundVoSon; for (OrderItemSourceRefundDto orderItemSourceRefundDto : orderItemSourceRefundDtos) { if(StringUtils.isEmpty(orderItemSourceRefundDto.getOrderItemSonId())){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款项标识必填[54]"); } OrderItemSon orderItemSon = orderItemSonMapper.selectOneByKey(orderItemSourceRefundDto.getOrderItemSonId()); if (orderItemSon == null) { throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款项标识错误[54]"); } if (!orderItemSon.getOrderItemId().equals(orderItem.getId())) { throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到退款项[54]"); } switch (orderItemSon.getType()) { case OrderGoodsConstants.TYPE_PROJECT: distributionRedundVoSon = itemTwoRefund(orderItemSon,orderItemSourceRefundDto); break; case OrderItemConstants.TYPE_RETAIL: distributionRedundVoSon = itemTwoRefund(orderItemSon,orderItemSourceRefundDto); break; case OrderItemConstants.TYPE_DRUG: distributionRedundVoSon = itemTwoRefund(orderItemSon,orderItemSourceRefundDto); break; default: throw new TipsException("未知商品类型[098]!"); } //数据填充 orderItemSourceRefundDto.setType(distributionRedundVoSon.getGoodsType()); orderItemSourceRefundDto.setGoodsName(distributionRedundVoSon.getGoodsName()); orderItemSourceRefundDto.setApproveRefundTotal(distributionRedundVoSon.getRefundTotal()); //返回结构金额填充 distributionRedundVo.setRefundTotal(distributionRedundVo.getRefundTotal().add(distributionRedundVoSon.getRefundTotal()).setScale(2,RoundingMode.HALF_UP)); distributionRedundVo.setRefundCash(distributionRedundVo.getRefundCash().add(distributionRedundVoSon.getRefundCash()).setScale(2,RoundingMode.HALF_UP)); distributionRedundVo.setRefundExecute(distributionRedundVo.getRefundExecute().add(distributionRedundVoSon.getRefundExecute()).setScale(2,RoundingMode.HALF_UP)); //整合退款金额 for(DistributionRedundMethodVo paymentMethodVo:distributionRedundVoSon.getDistributionRedundMethodVoList()){ //整合金额,上级用到 refundPaymentMethodVo = refundPaymentMethodVoMap.computeIfAbsent(paymentMethodVo.getNumberNo() ,k-> new DistributionRedundMethodVo(paymentMethodVo.getNumberNo(),paymentMethodVo.getName(),BigDecimal.ZERO,paymentMethodVo.getIsMoneyPay(),paymentMethodVo.getIsExecute())); refundPaymentMethodVo.setRefundTotal(refundPaymentMethodVo.getRefundTotal().add(paymentMethodVo.getRefundTotal()).setScale(2,RoundingMode.HALF_UP)); } } //返回结构数据填充 distributionRedundVo.setGoodsName(orderItem.getGoodsName()); distributionRedundVo.setGoodsType(orderItem.getType()); //整合退款金额的数据 List distributionPayList = new ArrayList<>(); for(Map.Entry entry : refundPaymentMethodVoMap.entrySet()){ distributionPayList.add(entry.getValue()); } distributionRedundVo.setDistributionRedundMethodVoList(distributionPayList); return distributionRedundVo; } /** * 确认退款处理退款逻辑 * @param orderRefundDto 退款数据结构 * @return 结构 */ @Override public PlatformResult partRefund(OrdersTotal ordersTotal, OrderRefundDto orderRefundDto, ThirtApplication thirtApplication) { logger.info("退款打印参数:{}", JSON.toJSONString(orderRefundDto)); if(OrderTotalConstants.PAY_STATUS_SUC != ordersTotal.getPayStatus()){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"订单未支付!"); } if(OrderTotalConstants.STATUS_PAY != ordersTotal.getStatus() && OrderTotalConstants.STATUS_WAIT_RECEIVE != ordersTotal.getStatus() && OrderTotalConstants.STATUS_DONE != ordersTotal.getStatus()){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"订单不是已支付状态!"); } if(OrderTotalConstants.STATUS_REFUND_NONE != ordersTotal.getRefundStatus() && OrderTotalConstants.STATUS_REFUND_PART != ordersTotal.getRefundStatus()){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"订单退款状态不正确!"); } //先优先改成申请退款中 SqlSentence sqlSentence = new SqlSentence(); Map map=new HashMap<>(); map.put("refundStatus",OrderTotalConstants.STATUS_REFUND_APPLY); map.put("isSyncOrder", BaseEntity.NO); map.put("id",ordersTotal.getId()); sqlSentence.sqlSentence(" refundStatus=#{m.refundStatus},isSyncOrder=#{m.isSyncOrder} WHERE id=#{m.id} AND refundStatus IN('"+OrderTotalConstants.STATUS_REFUND_NONE+"','"+OrderTotalConstants.STATUS_REFUND_PART+"') ",map); if(ordersTotalMapper.updateWhere(sqlSentence) != 1){ throw new TipsException("操作失败,当前订单退款状态不能再次发起退款!"); } //校验参数和获取系统参数,非常重要 orderRefundDto = parameterVerification(ordersTotal,orderRefundDto); return handlePartRefund(ordersTotal,orderRefundDto,thirtApplication); } /** * 退款校验参数,拼接参数 */ @Override public OrderRefundDto parameterVerification(OrdersTotal ordersTotal, OrderRefundDto orderRefundDto){ if(orderRefundDto.getRefundPayMethod() == null){ throw new TipsException("退款方式结构不能空"); } //怕被获取到项目信息收到被改了项目价格,重新去获取一下项目价格 orderRefundDto = nextStep(ordersTotal,orderRefundDto); //可退款支付格式,key值:支付编号 Map orderPayMethodDtoMap = new HashMap<>(); for (OrderPayMethodDto orderPayMethodDto : orderRefundDto.getPayMethodList()) { orderPayMethodDtoMap.put(orderPayMethodDto.getPayMethodNo(),orderPayMethodDto); } //填写退款的总金额 BigDecimal refundTotal = BigDecimal.ZERO; //校验金额 OrderPayMethodDto payMethodDto; //遍历系统获取到的可退款方式 OrderPayMethodDto orderPayMethodDto; for (int i = orderRefundDto.getRefundPayMethod().size()-1; i>=0 ;i--) { orderPayMethodDto = orderRefundDto.getRefundPayMethod().get(i); //获取是传值过来的金额数据 payMethodDto = orderPayMethodDtoMap.get(orderPayMethodDto.getPayMethodNo()); if(payMethodDto == null){ throw new TipsException("未找到["+orderPayMethodDto.getPayMethodName()+"]支付方式!"); } //判断退款方式 PaymentMethod refundMethod = paymentMethodService.selectNumberNoUncheckUp(orderPayMethodDto.getRefundNumberNo()); if(refundMethod==null){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到该转换方式:"+orderPayMethodDto.getRefundNumberName()+"["+orderPayMethodDto.getRefundNumberNo()+"]"); } if(orderPayMethodDto.getMoney() == null){ throw new TipsException("["+orderPayMethodDto.getPayMethodName()+"]退款金额必填!"); } if(orderPayMethodDto.getMoney().compareTo(BigDecimal.ZERO) < 0){ throw new TipsException("["+orderPayMethodDto.getPayMethodName()+"]退款金额错误!"); } if (orderPayMethodDto.getMoney().compareTo(payMethodDto.getPayTotal()) > 0){ throw new TipsException("当前退款方式["+orderPayMethodDto.getPayMethodName()+"]金额超出可退金额!"); } //退款金额是0元,去掉退款方式 if(orderPayMethodDto.getMoney().compareTo(BigDecimal.ZERO) == 0){ orderRefundDto.getRefundPayMethod().remove(i); } //特殊的退款判断 RefundTool.paymemtCheck(orderPayMethodDto.getPayMethodNo(),orderPayMethodDto.getRefundNumberNo()); orderPayMethodDto.setPayMethodName(payMethodDto.getPayMethodName()); orderPayMethodDto.setPayMethodNo(payMethodDto.getPayMethodNo()); orderPayMethodDto.setPayTotal(payMethodDto.getPayTotal()); refundTotal = refundTotal.add(orderPayMethodDto.getMoney()).setScale(2,RoundingMode.HALF_UP); } orderRefundDto.setRefundTotal(refundTotal); if(orderRefundDto.getRefundTotal().compareTo(orderRefundDto.getTotalAmount()) > 0){ throw new TipsException("退款金额不能大于可退金额[004]!"); } return orderRefundDto; } /** * 处理退款详情 */ public PlatformResult handlePartRefund(OrdersTotal ordersTotal,OrderRefundDto orderRefundDto,ThirtApplication thirtApplication){ //订单节点日志 OrdersNodeLog ordersNodeLog = new OrdersNodeLog(); StringBuilder orderNodeBuilder = new StringBuilder(); orderNodeBuilder.append("开始退款"); orderNodeBuilder.append("-本次退款项目总金额:").append(orderRefundDto.getTotalAmount()).append(",客户选的退款方式总金额:").append(orderRefundDto.getRefundTotal()); Map operator = ApiOrderUtil.getOperator(commonService, orderRefundDto.getOperatorId());//获取操作人信息 SqlSentence sqlSentence = new SqlSentence(); Map map=new HashMap<>(); sqlSentence.setM(map); //退款总记录 orderNodeBuilder.append("-处理退款总记录"); //保存退款信息,不是真正的退款,提前扣减用户资金 RefundRecord refundRecord = insertRefundInfo(orderRefundDto,ordersTotal,orderNodeBuilder,thirtApplication); //判断已支付订单是否需要营销助手审批 //记录取消日志 CancelOrder cancelOrder = handleCancelOrder(ordersTotal,orderRefundDto); if (orderRefundDto.getIsApproval().equals(BaseEntity.YES)){ //调用审批功能 return handleApproval(ordersNodeLog,orderNodeBuilder,ordersTotal,cancelOrder,refundRecord); } //这里开始真正的退款到用户账户的 Map refund = handleRefundOrder(operator,refundRecord,ordersTotal,ordersNodeLog,orderNodeBuilder,cancelOrder); return PlatformResult.success(refund); } /**保存退款信息 * 保存退款信息,并没有真正退款 */ @Override public RefundRecord insertRefundInfo(OrderRefundDto orderRefundDto, OrdersTotal ordersTotal , StringBuilder orderNodeBuilder, ThirtApplication thirtApplication){ //操作人 Employee employee = commonService.selectOneByKey(EmployeeMapper.class,orderRefundDto.getOperatorId()); if(employee == null){ throw new TipsException("操作人标识错误!"); } if(!OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){ if(orderRefundDto.getRefundList()== null || orderRefundDto.getRefundList().size() == 0){ throw new TipsException("退款子项不能为空!"); } } ///////退款总表数据填充 //生成退款编号 String totalCode = createNoService.createNo("R",System.currentTimeMillis()+"",8); RefundRecord refundRecord=new RefundRecord(totalCode,ordersTotal.getShopId(),ordersTotal.getShopName(),orderRefundDto.getRefundTotal() , RefundStatus.STATUS_APPLY_REFUND,0, RefundSoruceConstants.TYPE_SOURCE_ORDER,orderRefundDto.getRemarks(),ordersTotal.getId(),ordersTotal.getUserId()); //操作人信息 refundRecord.setOperatorType(RefundRecord.OPERATOR_TYPE_EMPLOYEE); refundRecord.setOperatorId(employee.getId()); refundRecord.setOperatorNo(employee.getEmployeeNo()); refundRecord.setOperatorName(employee.getCnName()); refundRecord.setRefundOperationType(orderRefundDto.getRefundOperationType()); /////退款的备注 refundRecord.setRemarks(orderRefundDto.getRemarks()); refundRecord.setRefundReason(orderRefundDto.getRefundReason()); refundRecord.setOperatorAppId(thirtApplication.getAppId()); refundRecord.setOperatorAppCode(thirtApplication.getAppIdCode()); refundRecord.setOperatorAppName(thirtApplication.getName()); refundRecordService.insert(refundRecord); //退款方式处理 if(orderRefundDto.getRefundPayMethod() !=null && orderRefundDto.getRefundPayMethod().size() > 0){ handleRefundPayMethod(orderRefundDto,orderNodeBuilder,ordersTotal,refundRecord); } //退款的子项处理 if(orderRefundDto.getRefundList()!=null && orderRefundDto.getRefundList().size()>0){ insertRefundRecordItem(orderRefundDto,orderNodeBuilder,refundRecord); } //回退的优惠卷处理 if(orderRefundDto.getCouponList() != null && orderRefundDto.getCouponList().size()>0){ handleOrderCouponRefunDto(orderRefundDto.getCouponList(),orderNodeBuilder,ordersTotal,refundRecord); } //*******扣减赠送的账户资金,如果订单有老带新的赠送规则,那么如果申请退款,就优先把老带新的退回来***** //获取老带新记录 oldBlingNewRefund(refundRecord,orderNodeBuilder,commonService); //判断是否是充值订单,是的话先冻结储值金,就是扣掉,审批通过就不处理储值金了,不通过还原资金 if(OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){ OrderRefundCancelTool.rechargeHandle(ordersTotal,refundRecord,OrderRefundCancelTool.OPT_TYPE_EXECUTE,"申请退款",orderNodeBuilder,commonService); } //活动处理 OrderRefundCancelTool.activityRuleHandle(ordersTotal,refundRecord,OrderRefundCancelTool.OPT_TYPE_EXECUTE,"申请退款",orderNodeBuilder,commonService); return refundRecord; } /**老带新的订单退款,佣金处理*/ public void oldBlingNewRefund(RefundRecord refundRecord,StringBuilder orderNodeBuilder,CommonService commonService){ SqlSentence sqlSentence = new SqlSentence(); Map values = new HashMap<>(); //查找老带新记录,未删除且有效的,没有退回的 values.put("operationReason",OperationReasonConstants.OP_REASON_BRING_NEW_USER_GIFT); values.put("orderId",refundRecord.getOrderId()); sqlSentence.sqlSentence("SELECT * FROM user_money_unclaimed mu WHERE mu.isDel = 0 AND mu.isValid = 1 AND mu.operationReason = #{m.operationReason}" + " AND mu.orderId = #{m.orderId} AND NOT EXISTS(SELECT * FROM refund_user_assets rua WHERE rua.isDel = 0 AND rua.status = 1" + " AND rua.amountStatus IN (1,3) AND rua.userMoneyUnclaimedId = mu.id)",values); List userMoneyUnclaimedList = commonService.selectList(UserMoneyUnclaimedMapper.class,sqlSentence); RefundUserAssets refundUserAssets; UserMoney userMoney; User user; BigDecimal amount; for (UserMoneyUnclaimed userMoneyUnclaimed:userMoneyUnclaimedList){ amount = BigDecimal.ZERO; //生成记录 refundUserAssets = new RefundUserAssets(); refundUserAssets.setType(userMoneyUnclaimed.getOperationReason()); refundUserAssets.setStatus(RefundUserAssets.STATUS_NORMAL); refundUserAssets.setAmountType(userMoneyUnclaimed.getFundType()); refundUserAssets.setAmount(userMoneyUnclaimed.getOpNumber().negate()); refundUserAssets.setOperatorId(refundRecord.getOperatorId()); refundUserAssets.setOperatorNo(refundRecord.getOperatorNo()); refundUserAssets.setOperatorName(refundRecord.getOperatorName()); refundUserAssets.setOrderId(refundRecord.getOrderId()); refundUserAssets.setRefundRecordId(refundRecord.getId()); refundUserAssets.setUserMoneyUnclaimedId(userMoneyUnclaimed.getId()); refundUserAssets.setUserId(userMoneyUnclaimed.getUserId()); user = commonService.selectOneByKey(UserMapper.class,refundUserAssets.getUserId()); orderNodeBuilder.append("-退款处理老带新,扣减用户:").append(user.getName()).append(",CIQ:").append(user.getCIQ()).append(","); orderNodeBuilder.append(RefundUserAssets.amountTypeName(refundUserAssets.getAmountType())).append(refundUserAssets.getAmount()); if(userMoneyUnclaimed.getStatus() == UserMoneyUnclaimed.STATUS_WAI){ refundUserAssets.setAmountStatus(RefundUserAssets.AMOUNT_STATUS_NOT_RECEIVE); //用户未领取,那么直接作废,作废是逻辑删除 values.put("id",userMoneyUnclaimed.getId()); values.put("status",UserMoneyUnclaimed.STATUS_WAI); sqlSentence.sqlUpdate("isDel = 1,isValid = 0 WHERE id = #{m.id} AND isDel = 0 AND isValid = 1 AND status = #{m.status}",values); if(commonService.updateWhere(UserMoneyUnclaimedMapper.class,sqlSentence) != 1){ throw new TipsException("老带新资产记录状态已变化!"); } orderNodeBuilder.append(",用户未领取,作废领取记录"); }else if(userMoneyUnclaimed.getStatus() == UserMoneyUnclaimed.STATUS_SUCCEED){ //用户已经领取了,那么要扣掉,但是,要先判断用户是否够,如果不够,那么也生成记录,显示未操作资金 values.clear(); values.put("userId",userMoneyUnclaimed.getUserId()); sqlSentence.sqlSentence("SELECT * FROM user_money WHERE isDel = 0 AND userId = #{m.userId}",values); userMoney = commonService.selectOne(UserMoneyMapper.class,sqlSentence); if(userMoneyUnclaimed.getFundType() == UserMoneyUnclaimed.FUND_TYPE_STORED_VALUE_FUND){ //储值金 if(userMoney.getStoredValueFund() != null){ amount = new BigDecimal(userMoney.getStoredValueFund()); } }else if(userMoneyUnclaimed.getFundType() == UserMoneyUnclaimed.FUND_TYPE_VALUE_ADDED_FUND){ //增值金 if(userMoney.getValueAddedFund() != null){ amount = new BigDecimal(userMoney.getValueAddedFund()); } }else if(userMoneyUnclaimed.getFundType() == UserMoneyUnclaimed.FUND_TYPE_INTEGRAL){ //预定金 if(userMoney.getDeposit() != null){ amount = new BigDecimal(userMoney.getDeposit()); } }else if(userMoneyUnclaimed.getFundType() == UserMoneyUnclaimed.FUND_TYPE_DEPOSIT){ //积分 if(userMoney.getIntegral() != null){ amount = new BigDecimal(userMoney.getIntegral()); } }else{ throw new TipsException("老带新资产记录金额类型未知!"); } if(amount.compareTo(refundUserAssets.getAmount().negate()) >= 0){ //用户资产够减 orderNodeBuilder.append(",扣减成功"); refundUserAssets.setAmountStatus(RefundUserAssets.AMOUNT_STATUS_NORMAL); }else { orderNodeBuilder.append(",余额不足,扣减失败"); //用户资产不够减 refundUserAssets.setAmountStatus(RefundUserAssets.AMOUNT_STATUS_NOT); } }else{ throw new TipsException("老带新资产记录状态错误!"); } if(refundUserAssets.getAmountStatus() == RefundUserAssets.AMOUNT_STATUS_NORMAL || refundUserAssets.getAmountStatus() == RefundUserAssets.AMOUNT_STATUS_NOT_RECEIVE ){ //保存记录,正常扣减和未领取才去保存这个记录 commonService.insert(RefundUserAssetsMapper.class,refundUserAssets); } //用户资金操作 if(refundUserAssets.getAmountStatus() == RefundUserAssets.AMOUNT_STATUS_NORMAL){ UserMoneyUtil.setNewUserMoneyUnclaimed(refundUserAssets.getUserId(),refundRecord.getRemarks(),"退款:老带新资金回退",refundUserAssets.getOperatorId() ,refundRecord.getOrderId(),refundRecord.getOperatorAppCode(),refundUserAssets.getId(),refundUserAssets.getAmount(),refundUserAssets.getAmountType() ,OperationReasonConstants.OP_REASON_BRING_NEW_USER_GIFT_RETRUN,commonService,UserMoneyUnclaimed.YES); } } } /**老带新的订单退款不通过或者作废,佣金处理*/ public void oldBlingNewRefundFail(RefundRecord refundRecord,StringBuilder orderNodeBuilder,CommonService commonService) { ////订单退款状态是没有退款才退回 //获取回退记录 SqlSentence sqlSentence = new SqlSentence(); Map values = new HashMap<>(); values.put("orderId",refundRecord.getOrderId()); 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); List refundUserAssetsList = commonService.selectList(RefundUserAssetsMapper.class,sqlSentence); User user; for(RefundUserAssets refundUserAssets:refundUserAssetsList){ user = commonService.selectOneByKey(UserMapper.class,refundUserAssets.getUserId()); orderNodeBuilder.append("-退款处理老带新,回退资金到用户:").append(user.getName()).append(",CIQ:").append(user.getCIQ()).append(","); orderNodeBuilder.append(RefundUserAssets.amountTypeName(refundUserAssets.getAmountType())).append(refundUserAssets.getAmount()); //是否有扣减用户资产 if(refundUserAssets.getAmountStatus() == RefundUserAssets.AMOUNT_STATUS_NORMAL){ orderNodeBuilder.append(",增加成功"); UserMoneyUtil.setNewUserMoneyUnclaimed(refundUserAssets.getUserId(),refundRecord.getRemarks(),"退款作废:老带新资金回退作废",refundUserAssets.getOperatorId() ,refundRecord.getOrderId(),refundRecord.getOperatorAppCode(),refundUserAssets.getId(),refundUserAssets.getAmount().negate(),refundUserAssets.getAmountType() ,OperationReasonConstants.OP_REASON_BRING_NEW_USER_GIFT_RETRU_CANCEL,commonService,UserMoneyUnclaimed.YES); }else if(refundUserAssets.getAmountStatus() == RefundUserAssets.AMOUNT_STATUS_NOT_RECEIVE){ //用户未领取记录,还原 orderNodeBuilder.append(",用户未领取,作废的领取记录还原"); values.clear(); values.put("id",refundUserAssets.getUserMoneyUnclaimedId()); values.put("status",UserMoneyUnclaimed.STATUS_WAI); sqlSentence.sqlUpdate("isDel = 0,isValid = 1 WHERE id = #{m.id} AND isDel = 1 AND isValid = 0 AND status = #{m.status}",values); if(commonService.updateWhere(UserMoneyUnclaimedMapper.class,sqlSentence) != 1){ throw new TipsException("老带新资产记录状态已变化[作废]!"); } } //记录作废 values.clear(); values.put("id",refundUserAssets.getId()); values.put("status",RefundUserAssets.STATUS_CANCEL); values.put("oldStatus",RefundUserAssets.STATUS_NORMAL); sqlSentence.sqlSentence("status = #{m.status} WHERE id = #{m.id} AND status = #{m.oldStatus}",values); if(commonService.updateWhere(RefundUserAssetsMapper.class,sqlSentence) != 1){ throw new TipsException("老带新资产退款记录状态已变化[作废]!"); } } } /** * 退款-处理活动规则增值金和积分 * @param commonService 映射对象 * @param operationId 操作人标识 * @param operationNme 操作人名称 * @param sqlSentence 映射对象 * @param map 映射对象 * @param refundRecord 退款记录 * @param ordersTotal 订单 * @param optType 操作:"0"减 1加 */ private static void handActivityRule(CommonService commonService, String operationId, String operationNme, SqlSentence sqlSentence, Map map, RefundRecord refundRecord, OrdersTotal ordersTotal, OrderInfo orderInfo,int optType) { if(orderInfo!=null && StringUtils.noNull(orderInfo.getActivityId())){ ActivityRule activityRule=commonService.selectOneByKeyBlob(ActivityRuleMapper.class,orderInfo.getActivityId()); if(activityRule!=null){ map.put("activityRuleId",activityRule.getId()); map.put("type", ActivityAction.TYPE_INTEGRAL); map.put("type1",ActivityAction.TYPE_VALUEADDEDFUND); map.put("type2",ActivityAction.TYPE_COUPON); 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); List activityActions = commonService.selectList(ActivityActionMapper.class, sqlSentence); if(activityActions!=null && activityActions.size()>0){ for (ActivityAction activityAction : activityActions) { if(ActivityAction.TYPE_INTEGRAL.equals(activityAction.getType())){ //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0 if(new BigDecimal(activityAction.getWorth()).negate().compareTo(BigDecimal.ZERO)!=0){ 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); } }else if(ActivityAction.TYPE_VALUEADDEDFUND.equals(activityAction.getType())){ //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0 if(new BigDecimal(activityAction.getWorth()).negate().compareTo(BigDecimal.ZERO)!=0){ 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); } }else if(ActivityAction.TYPE_COUPON.equals(activityAction.getType())){ map.put("oldValidState",optType==0?BaseEntity.YES:BaseEntity.NO); map.put("newValidState",optType==0?BaseEntity.NO:BaseEntity.YES); map.put("couponId",activityAction.getCrmCouponId()); map.put("commonId",ordersTotal.getId()); sqlSentence.sqlSentence(" validState=#{m.newValidState} where couponId=#{m.couponId} and commonId=#{m.commonId} and validState=#{m.oldValidState} ",map); commonService.updateWhere(CouponNumberMapper.class,sqlSentence); } } } } } } /** * 对接审批 */ public PlatformResult handleApproval(OrdersNodeLog ordersNodeLog,StringBuilder orderNodeBuilder,OrdersTotal ordersTotal,CancelOrder cancelOrder,RefundRecord refundRecord){ orderNodeBuilder.append("-退款需要审批,开始对接营销中心"); OrderPartRefundDto orderPartRefundDto=new OrderPartRefundDto(); OrdersTotalDto ordersTotalDto=new OrdersTotalDto(); BeanUtils.copyProperties(ordersTotal, ordersTotalDto); orderPartRefundDto.setOrdersTotalDto(ordersTotalDto);//填充主订单信息 //填充操作人,用户的基本信息 orderPartRefundDto.setOrdersTotalDto(ordersTotalDto); orderPartRefundDto.setOperatorId(cancelOrder.getOperatorId()); orderPartRefundDto.setOpName(cancelOrder.getOperatorName()); orderPartRefundDto.setShopId(cancelOrder.getShopId()); orderPartRefundDto.setShopName(cancelOrder.getShopName()); orderPartRefundDto.setRoleId(cancelOrder.getRoleId()); orderPartRefundDto.setRoleUniqueStr(cancelOrder.getRoleStr()); if(StringUtils.noNull(refundRecord.getRemarks())){ orderPartRefundDto.setRemark(refundRecord.getRemarks()); }else{ orderPartRefundDto.setRemark(cancelOrder.getOperatorName()+"退款,订单号:"+ordersTotal.getOrderNo()); } orderPartRefundDto.setUserId(ordersTotal.getUserId()); //本次退款金额 orderPartRefundDto.setRefundTotal(refundRecord.getRefundTotal()); //------本次退款支付方式 SqlSentence sqlSentence = new SqlSentence(); Map map=new HashMap<>(); map.put("refundRecordId", refundRecord.getId()); sqlSentence.sqlSentence("SELECT refundNumberNo AS payMethodNo,refundName AS payMethodName,actualTotal as refundMoney,refundRecordId as payMethodId FROM refund_record_method " + " WHERE refundRecordId=#{m.refundRecordId} ",map); List> refundMethodList = commonService.selectListMap(RefundRecordMethodMapper.class,sqlSentence); if(refundMethodList!=null && refundMethodList.size()!=0){ JSONArray refundMethodArray=new JSONArray(); refundMethodArray.addAll(refundMethodList); List partRefundPayDtoList=refundMethodArray.toJavaList(PartRefundPayDto.class); orderPartRefundDto.setPartRefundPayDtoList(partRefundPayDtoList); } //-----本次退款项目 //退款一级项目 sqlSentence.sqlSentence("SELECT type AS projectType, commonId AS projectId, goodsNo AS projectNo, goodsName AS projectName, refundNum AS refundNum " + " FROM refund_record_item WHERE refundRecordId=#{m.refundRecordId} AND refundNum>0",map); List> refundRecordItemList = commonService.selectListMap(RefundRecordItemMapper.class,sqlSentence); JSONArray refundProjectDtoArray=new JSONArray(); if(refundRecordItemList!=null && refundRecordItemList.size()!=0){ refundProjectDtoArray.addAll(refundRecordItemList); } //退款二级项目 sqlSentence.sqlSentence("SELECT type AS projectType, commonId AS projectId, goodsNo AS projectNo, goodsName AS projectName, refundNum AS refundNum " + " FROM refund_record_item_source WHERE refundRecordId=#{m.refundRecordId} AND refundNum>0",map); List> refundRecordItemSourceList = commonService.selectListMap(RefundRecordItemSourceMapper.class,sqlSentence); if(refundRecordItemSourceList!=null && refundRecordItemSourceList.size()!=0){ refundProjectDtoArray.addAll(refundRecordItemSourceList); } if(refundProjectDtoArray.size()>0){ List refundProjectDtoList=refundProjectDtoArray.toJavaList(RefundProjectDto.class); orderPartRefundDto.setRefundProjectDtoList(refundProjectDtoList); } logger.info("调用营销中心审批退款入参:{}",JSONObject.toJSONString(orderPartRefundDto)); Result result= mOrderService.applyPartRefund(orderPartRefundDto); // Result result= JSONObject.parseObject("{\"code\":\"100\",\"msg\":\"SUCCESS\",\"data\":{\"applyId\":\"6204eb10753511ed90ed525400b8510a\"}}",Result.class); logger.info("调用营销中心审批退款返回:{}",JSONObject.toJSONString(result)); if (result != null) { result.checkTips(); JSONObject object = JSONObject.parseObject(JSONObject.toJSONString(result.getData())); if(!object.isEmpty()){ String applyId = object.getString("applyId"); cancelOrder.setApplyId(applyId); cancelOrder.setRefundRecordId(refundRecord.getId()); commonService.updateAll(CancelOrderMapper.class,cancelOrder); ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_APPLY); commonService.updateAll(OrdersTotalMapper.class,ordersTotal); // logger.info("调用营销中心成功,订单开始审核"); orderNodeBuilder.append("-调用营销中心成功,订单开始审核"); ordersNodeLog.setCommonType(OrdersNodeLog.TYPE_COMMON_ORDER_REFUND); ordersNodeLog.setContent(orderNodeBuilder.toString()); ordersNodeLog.setOrderId(ordersTotal.getId()); commonService.insert(OrdersNodeLogMapper.class,ordersNodeLog); orderNodeBuilder.append("-调用营销中心成功,订单开始审核"); return PlatformResult.success("订单正在审核中"); }else{ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请求营销助手审批接口报错,data返回为空!"); } } else { throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请求营销助手审批接口报错,返回为空!"); } } /** * 记录退款订单记录日志 */ @Override public CancelOrder handleCancelOrder(OrdersTotal ordersTotal, OrderRefundDto orderRefundDto){ //记录取消日志 CancelOrder cancelOrder=new CancelOrder(); cancelOrder.setOrderId(ordersTotal.getId()); if(StringUtils.noNull(orderRefundDto.getOperatorId())){ Employee employee = commonService.selectOneByKey(EmployeeMapper.class,orderRefundDto.getOperatorId()); if(employee==null){ throw new TipsException("操作人标识错误!"); } cancelOrder.setOperatorId(employee.getId()); cancelOrder.setOperatorName(employee.getCnName()); } if(StringUtils.noNull(orderRefundDto.getRoleId())){ EmployeeRole employeeRole=commonService.selectOneByKey(EmployeeRoleMapper.class,orderRefundDto.getRoleId()); if(employeeRole==null){ throw new TipsException("操作角色标识错误!"); } cancelOrder.setRoleId(employeeRole.getRoleTypeId()); cancelOrder.setRoleStr(employeeRole.getRoleUniqueStr()); Shop shop=commonService.selectOneByKey(ShopMapper.class,employeeRole.getShopId()); if(shop==null){ cancelOrder.setShopId(employeeRole.getShopId()); cancelOrder.setShopName("找不到对应的门店"); }else { cancelOrder.setShopId(shop.getId()); cancelOrder.setShopName(shop.getName()); } } cancelOrder.setIsApproval(orderRefundDto.getIsApproval()); cancelOrder.setIsRefund(orderRefundDto.getIsRefund()); cancelOrder.setPlatformSource(orderRefundDto.getPlatformSource()); commonService.insert(CancelOrderMapper.class,cancelOrder); return cancelOrder; } /** * 处理退款方式记录表 */ public List handleRefundPayMethod(OrderRefundDto orderRefundDto,StringBuilder orderNodeBuilder,OrdersTotal ordersTotal,RefundRecord refundRecord){ orderNodeBuilder.append("-记录退款方式:"); //获取订单可退款方式,就是支付方式总表的信息,已经支付编号求和 List payMethodVoList = refundMapper.getConsumePayGroupByNumberNo(ordersTotal.getId()); //用map装载,后面根据支付编号直接获取便可 Map payMethodVoMap = payMethodVoList.stream().collect(Collectors.toMap(PayMethodVo::getNumberNo,(a) -> a)); List refundRecordMethodList = new ArrayList<>(); PayMethodVo payMethodVo; RefundRecordMethod refundRecordMethod; for (OrderPayMethodDto orderPayMethodDto : orderRefundDto.getRefundPayMethod()) { payMethodVo = payMethodVoMap.get(orderPayMethodDto.getPayMethodNo()); //判断是不是在支付方式里面的 if (payMethodVo == null){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"可退支付方式未找到:"+orderPayMethodDto.getPayMethodName()+"["+orderPayMethodDto.getPayMethodNo()+"]"); } //判断支付方式 PaymentMethod payMethod = paymentMethodService.selectNumberNoUncheckUp(orderPayMethodDto.getPayMethodNo()); if(payMethod == null){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到对应的支付:"+orderPayMethodDto.getPayMethodName()+"["+orderPayMethodDto.getPayMethodNo()+"]"); } //判断退款方式 PaymentMethod refundMethod = paymentMethodService.selectNumberNoUncheckUp(orderPayMethodDto.getRefundNumberNo()); if(refundMethod==null){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到退款方式:"+orderPayMethodDto.getRefundNumberName()+"["+orderPayMethodDto.getRefundNumberNo()+"]"); } if(orderPayMethodDto.getMoney() == null){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请填写退款方式["+orderPayMethodDto.getPayMethodName()+"["+orderPayMethodDto.getPayMethodNo()+"]"+"]金额"); } //判断金额 if(payMethodVo.getSurplusTotal().compareTo(orderPayMethodDto.getMoney()) < 0){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款金额错误:"+orderPayMethodDto.getPayMethodName()+"["+orderPayMethodDto.getPayMethodNo()+"]"); } ////退款方式数据填充 refundRecordMethod = new RefundRecordMethod(); refundRecordMethod.setType(refundRecord.getSourceType()); refundRecordMethod.setActualTotal(orderPayMethodDto.getMoney()); //支付方式信息 refundRecordMethod.setNumberNo(payMethod.getNumberNo()); refundRecordMethod.setPaymentMethodId(payMethod.getId()); refundRecordMethod.setName(payMethod.getName()); refundRecordMethod.setIsMoneyPay(payMethodVo.getIsMoneyPay()); refundRecordMethod.setIsExecute(payMethodVo.getIsExecute()); //退款方式信息 refundRecordMethod.setRefundNumberNo(refundMethod.getNumberNo()); refundRecordMethod.setRefundName(refundMethod.getName()); refundRecordMethod.setRefundMethodId(refundMethod.getId()); refundRecordMethod.setIsMoneyPayRefund(refundMethod.getIsMoneyPay()); refundRecordMethod.setIsExecuteRefund(refundMethod.getIsExecute()); refundRecordMethod.setRefundRecordId(refundRecord.getId()); refundRecordMethod.setOrderId(ordersTotal.getId()); refundRecordMethod.setRemarks(orderPayMethodDto.getRemarks()); refundRecordMethodService.insert(refundRecordMethod); refundRecordMethodList.add(refundRecordMethod); } return refundRecordMethodList; } /** * 退款记录子项 */ public void insertRefundRecordItem(OrderRefundDto orderRefundDto,StringBuilder orderNodeBuilder,RefundRecord refundRecord){ orderNodeBuilder.append("-记录退款详情"); //计算金额占比,客户选择退款总金额和可退总金额占比 BigDecimal percentage; if(orderRefundDto.getTotalAmount().compareTo(BigDecimal.ZERO) < 1){ percentage = BigDecimal.ZERO; }else { percentage = orderRefundDto.getRefundTotal().divide(orderRefundDto.getTotalAmount(),15,RoundingMode.HALF_UP); } //总退款金额,用于后面计算分摊金额 BigDecimal refundTotal = refundRecord.getRefundTotal(); //后面设计分配金额问题,要进行升序排序,避免到最后不够 List refundList = orderRefundDto.getRefundList(); refundList = refundList.stream().sorted(Comparator.comparing(OrderItemRefundDto::getApproveRefundTotal)).collect(Collectors.toList()); /////引用参数 RefundRecordItem refundRecordItem; OrderItemRefundDto orderItemRefundDto; OrderItem orderItem; for(int i = 0;i < refundList.size();i++){ orderItemRefundDto = refundList.get(i); orderItem = orderItemMapper.selectOneByKey(orderItemRefundDto.getOrderItemId()); if(orderItem == null){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"子订单标识错误!"); } //////数据填充 refundRecordItem = new RefundRecordItem(); refundRecordItem.setType(orderItem.getType()); refundRecordItem.setGoodsNo(orderItem.getGoodsNo()); refundRecordItem.setGoodsName(orderItem.getGoodsName()); refundRecordItem.setSpecs(orderItem.getSpecs()); refundRecordItem.setCommonId(orderItem.getCommonId()); if(PartialRefundUtil.CONTAIN_SON_TYPE_SET.contains(orderItem.getType())){ refundRecordItem.setRefundNum(0); }else{ refundRecordItem.setRefundNum(orderItemRefundDto.getRefundNum()); } refundRecordItem.setRefundRecordId(refundRecord.getId()); refundRecordItem.setOrderItemId(orderItem.getId()); refundRecordItem.setOccupyRefundTotal(orderItemRefundDto.getApproveRefundTotal()); ////退款备注 if(StringUtils.isEmpty(orderItemRefundDto.getRemarks())){ orderItemRefundDto.setRemarks(refundRecord.getRemarks()); } if(StringUtils.isEmpty(orderItemRefundDto.getRefundReason())){ orderItemRefundDto.setRefundReason(orderItemRefundDto.getRefundReason()); } refundRecordItem.setRemarks(orderItemRefundDto.getRemarks()); refundRecordItem.setRefundReason(orderItemRefundDto.getRefundReason()); //////////分配退款金额 if(i == refundList.size()-1){ refundRecordItem.setRefundMoney(refundTotal); }else{ refundRecordItem.setRefundMoney(orderItemRefundDto.getApproveRefundTotal().multiply(percentage).setScale(2,RoundingMode.UP)); } if(refundRecordItem.getRefundMoney().compareTo(orderItemRefundDto.getApproveRefundTotal()) > 0){ refundRecordItem.setRefundMoney(orderItemRefundDto.getApproveRefundTotal()); } //判断与未分配剩余金额 if(refundRecordItem.getRefundMoney().compareTo(refundTotal) > 0){ refundRecordItem.setRefundMoney(refundTotal); } refundRecordItem.setRealRefundNum(refundRecordItem.getRefundNum()); refundRecordItem.setRealRefundTotal(refundRecordItem.getRefundMoney()); refundRecordItemService.insert(refundRecordItem); if(OrderItemConstants.TYPE_PROJECT.equals(refundRecordItem.getType())){ //存储划扣信息 RefundTool.insertDeductionData(refundRecord.getId(),refundRecord.getOrderId(),refundRecordItem.getId(),orderItemRefundDto.getRefundDeductionCancelList(),commonService); } //减去已经分配的退款金额 refundTotal = refundTotal.subtract(refundRecordItem.getRefundMoney()).setScale(2,RoundingMode.HALF_UP); if(PartialRefundUtil.CONTAIN_SON_TYPE_SET.contains(orderItem.getType())){ //子单子项处理 insertRefundRecordItemTwo(refundRecordItem,refundRecord,orderItemRefundDto.getOrderItemSourceRefundDtos()); } //虚拟商品退款时需校验一下,对应关联的优惠券码有没有被使用或 if(OrderItemConstants.TYPE_COUPON.equals(orderItem.getType())){ OrderVirtualGoodsUtil.orderApplyRefundHandle(commonService, orderItem, orderItemRefundDto.getRefundNum(), refundRecord.getOperatorId(), refundRecord.getOperatorName(), "p-his申请订单退款作废"); } } if(refundTotal.compareTo(BigDecimal.ZERO) > 0){ throw new TipsException("退款金额分配错误[01]!"); } } /**二级子单处理*/ public void insertRefundRecordItemTwo(RefundRecordItem recordItem,RefundRecord refundRecord,List orderItemSourceRefundDtos){ if(orderItemSourceRefundDtos == null || orderItemSourceRefundDtos.size() == 0){ return; } //计算占比 BigDecimal percentage; if(recordItem.getOccupyRefundTotal().compareTo(BigDecimal.ZERO) > 0){ percentage = recordItem.getRefundMoney().divide(recordItem.getOccupyRefundTotal(),15,RoundingMode.HALF_UP); }else{ percentage = BigDecimal.ZERO; } //进行升序排序,避免后面不够 orderItemSourceRefundDtos = orderItemSourceRefundDtos.stream().sorted(Comparator.comparing(OrderItemSourceRefundDto::getApproveRefundTotal)).collect(Collectors.toList()); //退款总金额 BigDecimal refundTotal = recordItem.getRefundMoney(); OrderItemSon orderItemSon; OrderItemSourceRefundDto orderItemSourceRefundDto; RefundRecordItemSource refundRecordItemSource; for(int i = 0;i 0){ refundRecordItemSource.setRefundMoney(orderItemSourceRefundDto.getApproveRefundTotal()); } if(refundRecordItemSource.getRefundMoney().compareTo(refundTotal) > 0){ refundRecordItemSource.setRefundMoney(refundTotal); } refundRecordItemSource.setRealRefundNum(refundRecordItemSource.getRefundNum()); refundRecordItemSource.setRealRefundTotal(refundRecordItemSource.getRefundMoney()); refundRecordItemSourceMapper.insert(refundRecordItemSource); if(OrderItemConstants.TYPE_PROJECT.equals(refundRecordItemSource.getType())){ //存储划扣信息 RefundTool.insertDeductionData(refundRecord.getId(),refundRecord.getOrderId(),refundRecordItemSource.getId(),orderItemSourceRefundDto.getRefundDeductionCancelList(),commonService); } //减去已经分配退款金额 refundTotal = refundTotal.subtract(refundRecordItemSource.getRefundMoney()).setScale(2,RoundingMode.HALF_UP); } if(refundTotal.compareTo(BigDecimal.ZERO) > 0){ throw new TipsException("退款金额分配错误[02]!"); } } /** * 记录退款记录优惠卷 */ public void handleOrderCouponRefunDto(List couponList,StringBuilder orderNodeBuilder,OrdersTotal ordersTotal,RefundRecord refundRecord){ CouponOrderDiscountLog couponOrderDiscountLog; RefundRecordCoupon refundRecordCoupon; orderNodeBuilder.append("-处理退款优惠卷"); for (OrderCouponRefunDto orderCouponRefunDto : couponList) { couponOrderDiscountLog=couponOrderDiscountLogMapper.selectOneByKey(orderCouponRefunDto.getOrderCouponId()); if( couponOrderDiscountLog == null){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"订单优惠卷标识不正确"); } refundRecordCoupon=new RefundRecordCoupon(ordersTotal.getId(),refundRecord.getId(),ordersTotal.getUserId(),1,1,couponOrderDiscountLog.getId(), couponOrderDiscountLog.getCouponId(),couponOrderDiscountLog.getTitle(),couponOrderDiscountLog.getCouponNumberId()); refundRecordCouponMapper.insert(refundRecordCoupon); } } /**真正退款,是对钱和状态的回退到账开始操作 * 进行退款操作,退款用户项目,商品,促销,卡项,卡包 */ @Override public Map handleRefundOrder(Map operator,RefundRecord refundRecord,OrdersTotal ordersTotal ,OrdersNodeLog ordersNodeLog,StringBuilder orderNodeBuilder,CancelOrder cancelOrder ){ String operationId=operator.get("operatorId"); String operatorName=operator.get("operatorName"); orderNodeBuilder.append("-处理退款支付方式,用户待执行项目"); //处理主业务 ordersTotal = PartialRefundUtil.refundProcess(commonService,deductionSingleService, operationId, operatorName, refundRecord.getId()); //返回数据 Map data=new HashMap<>(); data.put("refundRecordId",refundRecord.getId()); data.put("refundRecordCode",refundRecord.getCode()); //处理次业务,报错不影响主业务 refundRecord = refundRecordService.selectOneByKey(refundRecord.getId()); //用户升降级(调用航爷) 金额=用户支付的实付现金金额(不包含储值金) SqlSentence sqlSentence = new SqlSentence(); Map map=new HashMap<>(); sqlSentence.setM(map); //退款成功 map.put("refundRecordId", refundRecord.getId()); 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 " + "WHERE rrm.refundRecordId=#{m.refundRecordId} and pm.isMoneyPay=1",map); Map totalMap =commonService.selectOneMap(RefundRecordMethodMapper.class,sqlSentence); BigDecimal total=new BigDecimal(String.valueOf(totalMap.get("total"))) ; if(BigDecimal.ZERO.compareTo(total) < 0){ try { orderNodeBuilder.append("-开始处理用户升降级,金额:").append(total.negate()); UserLevelUtil.refund(userLevelRuleService, ordersTotal.getUserId(),ordersTotal.getId(),total.negate(),ordersTotal.getAppIdCode()); orderNodeBuilder.append("-处理用户升降级成功"); }catch (Exception e){ String snapshot="处理用户升降级失败"; orderNodeBuilder.append("-处理用户升降级失败,异常原因:").append(e.getMessage()); logger.error("处理用户升降级失败:" + e.getMessage()); //发送企业微信通知给工作人员 SendNoticeUtil.failOrderSendNotice(ordersTotal,e.getMessage(),snapshot,commonService,customParameter); } } //记录操作日志 orderNodeBuilder.append("-记录操作日志"); StringBuffer stringBuffer = new StringBuffer("操作人:"+operator.get("operatorName")+",进行退款"); OrderLog orderLog=new OrderLog(ordersTotal.getId(), OrderLogConstants.LOG_TYPE_REFUND,stringBuffer.toString() ,operator.get("operatorName"),operator.get("operatorId"),OrderTotalConstants.STATUS_CANCEL); commonService.insert(OrderLogMapper.class,orderLog); orderNodeBuilder.append("-结束处理退款"); ordersNodeLog.setCommonType(OrdersNodeLog.TYPE_COMMON_ORDER_REFUND); ordersNodeLog.setContent(orderNodeBuilder.toString()); ordersNodeLog.setOrderId(ordersTotal.getId()); commonService.insert(OrdersNodeLogMapper.class,ordersNodeLog); //第三方最后执行 if(CancelOrderDto.HIS_ASSISTANT.equals(cancelOrder.getPlatformSource())){ //如果是his自动处理退款单原路退回 //CRM的操作也在这里 hisAssistantNoteList(ordersTotal,refundRecord,operationId,orderNodeBuilder); } //撤销【保妥适会员】标签 ClubEquityTool.refundCancelLabel(commonService,sUserTagInfoService,ordersTotal,botoxClubConfig.getLabelTypeNo(),botoxClubConfig.getLabelNo()); return data; } /** * his助手原路退回退款单 */ public void hisAssistantNoteList(OrdersTotal ordersTotal,RefundRecord refundRecord,String operationId,StringBuilder orderNodeBuilder){ OrderRefundNoteListDto orderRefundNoteListDto=new OrderRefundNoteListDto(); orderRefundNoteListDto.setOperationId(operationId); orderRefundNoteListDto.setOrderId(ordersTotal.getId()); //获取退款信息 SqlSentence sqlSentence = new SqlSentence(); Map map=new HashMap<>(); //获取总退款方式 map.put("refundRecordId",refundRecord.getId()); sqlSentence.sqlSentence("SELECT * FROM refund_record_method WHERE isDel = 0 AND refundRecordId = #{m.refundRecordId}",map); List refundRecordMethodList = commonService.selectList(RefundRecordMethodMapper.class,sqlSentence); if(refundRecordMethodList.size() == 0){ return; } //组装数据,只有现金才生成 List orderRefundNoteDtos=new ArrayList<>(); OrderRefundNoteDto orderRefundNoteDto; for (RefundRecordMethod refundRecordMethod : refundRecordMethodList) { //是现金 if(!refundRecordMethod.getIsMoneyPay().equals(BaseEntity.YES)){ continue; } orderRefundNoteDto = new OrderRefundNoteDto(); //退款,是否原路退回 if(refundRecordMethod.getNumberNo().equals(refundRecordMethod.getRefundNumberNo())){ orderRefundNoteDto.setRefundroute(1); }else{ orderRefundNoteDto.setRefundroute(0); } orderRefundNoteDto.setRefundRecordMethodId(refundRecordMethod.getId()); orderRefundNoteDto.setPaymentTotal(refundRecordMethod.getActualTotal()); orderRefundNoteDto.setPaymentNumberNo(refundRecordMethod.getNumberNo()); orderRefundNoteDto.setPaymentName(refundRecordMethod.getName()); orderRefundNoteDto.setRefundNumberNo(refundRecordMethod.getRefundNumberNo()); orderRefundNoteDto.setRefundName(refundRecordMethod.getRefundName()); orderRefundNoteDtos.add(orderRefundNoteDto); } orderRefundNoteListDto.setOrderRefundNoteDtos(orderRefundNoteDtos); noteConfirm(orderRefundNoteListDto, ordersTotal,refundRecord,orderNodeBuilder); } public void noteConfirm(OrderRefundNoteListDto orderRefundNoteListDto,OrdersTotal ordersTotal,RefundRecord refundRecord ,StringBuilder orderNodeBuilder) { logger.info("退款单确认打印参数:{}",JSON.toJSONString(orderRefundNoteListDto)); Map operator = ApiOrderUtil.getOperator(commonService, orderRefundNoteListDto.getOperationId());//获取操作人信息 String operatorId= operator.get("operatorId"); String operatorName= operator.get("operatorName"); SqlSentence sqlSentence = new SqlSentence(); Map map=new HashMap<>(); sqlSentence.setM(map); List orderRefundNoteDtos=orderRefundNoteListDto.getOrderRefundNoteDtos(); if(orderRefundNoteDtos == null || orderRefundNoteDtos.size() == 0){ return; } if("crm".equals(ordersTotal.getAppIdCode())){ //CRM退款 handleCrmRefundOrder(orderRefundNoteDtos,ordersTotal,refundRecord,operatorId,operatorName,orderNodeBuilder); }else { RefundCashVo refundCashVo = new RefundCashVo(); refundCashVo.setOrderId(ordersTotal.getId()); refundCashVo.setRemark(refundRecord.getRemarks()); List refundCashItemVoList = new ArrayList<>(); RefundCashItemVo refundCashItemVo; for (OrderRefundNoteDto orderRefundNoteDto : orderRefundNoteDtos) { if(BaseEntity.YES.equals(orderRefundNoteDto.getRefundroute())){ refundCashItemVo = new RefundCashItemVo(); refundCashItemVo.setPaymentNo(orderRefundNoteDto.getRefundNumberNo()); refundCashItemVo.setRefundTotal(orderRefundNoteDto.getPaymentTotal()); refundCashItemVo.setRefundRecordId(refundRecord.getId()); refundCashItemVo.setRefundRecordMethodId(orderRefundNoteDto.getRefundRecordMethodId()); refundCashItemVoList.add(refundCashItemVo); } } refundCashVo.setRefundCashItemVoList(refundCashItemVoList); logger.info("支付退款-ordersTotal.getAppIdCode():{}",ordersTotal.getAppIdCode()); logger.info("支付退款-refundCashVo:{}",JSON.toJSONString(refundCashVo)); //开始退款 2023-09-06暂时屏蔽线上退款 //refundCash(refundRecord.getId(),refundCashVo); } //记录操作日志 StringBuffer stringBuffer=new StringBuffer("操作人:"+operator.get("operatorName")+",已支付订单现金支付退款:"); OrderLog orderLog=new OrderLog(ordersTotal.getId(),OrderLogConstants.LOG_TYPE_CANCEL_ORDER,stringBuffer.toString() ,operator.get("operatorName"),operator.get("operatorId"),OrderTotalConstants.STATUS_CANCEL); commonService.insert(OrderLogMapper.class,orderLog); } /**处理crm退款*/ public void handleCrmRefundOrder(List orderRefundNoteDtos,OrdersTotal ordersTotal,RefundRecord refundRecord ,String operatorId, String operatorName,StringBuilder orderNodeBuilder){ SqlSentence sqlSentence = new SqlSentence(); Map map=new HashMap<>(); sqlSentence.setM(map); //待确认 BigDecimal crmAmount = orderRefundNoteDtos.stream().filter(item->RefundNote.ORIGINAL_ROAD.equals(item.getRefundroute())).map(o->o.getPaymentTotal()) .reduce(BigDecimal.ZERO,BigDecimal::add); List amountModelList=new ArrayList<>(); RefundAmountModelDto refundAmountModelDto; for (OrderRefundNoteDto orderRefundNoteDto : orderRefundNoteDtos) { if(RefundNote.ORIGINAL_ROAD.equals(orderRefundNoteDto.getRefundroute())){ refundAmountModelDto=new RefundAmountModelDto(); refundAmountModelDto.setRefundType(PayMethodTypeConstants.PAY_CRM_WX.equals(orderRefundNoteDto.getRefundNumberNo()) ?0:1); refundAmountModelDto.setAmountTotal(orderRefundNoteDto.getPaymentTotal()); amountModelList.add(refundAmountModelDto); } } logger.info("退款金额:{}",crmAmount); if(0 < crmAmount.compareTo(BigDecimal.ZERO)){ RefundDto refundDto=new RefundDto(); refundDto.setRefundOrderType(0); refundDto.setOrderId(ordersTotal.getId()); refundDto.setRefundType(0); refundDto.setRefundAmountTotal(crmAmount); refundDto.setRefundRecharge(new BigDecimal(0)); refundDto.setRefundIncrement(new BigDecimal(0)); refundDto.setRefundIntegral(new BigDecimal(0)); refundDto.setIsWholeOrder(0); refundDto.setRemarks("phis退款单退款,订单号:"+ordersTotal.getOrderNo()); refundDto.setAmountModelList(amountModelList); refundDto.setOperatorId(operatorId); refundDto.setOperatorName(operatorName); if(OrderTotalConstants.STATUS_REFUND_FINSH==ordersTotal.getRefundStatus() && OrderTotalConstants.STATUS_CANCEL == ordersTotal.getStatus()){ //全部退款完成则取消订单 refundDto.setIsCancelOrder(BaseEntity.YES); } logger.info("调用crm退款入参:{}",JSONObject.toJSONString(refundDto)); Result result= fOderService.refundOrder(refundDto);; logger.info("调用crm退款返回:{}",JSONObject.toJSONString(result)); if (result != null) { result.checkTips(); if("100".equals(result.getCode())){ RefundReturnDto refundReturnDto=JSON.parseObject(JSONObject.toJSONString(result.getData()),RefundReturnDto.class); if (RefundReturnDto.REFUND_STATUS_SUECCESS == refundReturnDto.getRefundStatus()){ orderNodeBuilder.append("-调用CRM退款金额:"+crmAmount+",返回成功返回流水号:"+refundReturnDto.getRefundNo()+",json:"+result); logger.info("crm退款成功进行下面操作"); }else { //throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请求crm退款接口报错,退款失败!退款状态不是成功状态"); if (!StringUtils.isEmpty(refundReturnDto.getTisMsg())){ if (refundReturnDto.getTisMsg().contains("商户账户可退款金额不足")){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"非常抱歉,当前公司财务账号金额不足无法进行退款,请稍后再试。如急需退款,请退[储值金] 在走oa申请线下退款。"); }else { throw new PlatTipsException(PlatformCode.ERROR_TIPS,refundReturnDto.getTisMsg()); } }else { throw new PlatTipsException(PlatformCode.ERROR_TIPS,"退款失败,请联系管理人员处理!"); } } //生成CRM回执记录 createCrmRefundReceipt(refundReturnDto,refundRecord,commonService); }else{ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请求crm退款接口报错,接口返回错误!:code不是100"); } } else { throw new PlatTipsException(PlatformCode.ERROR_TIPS,"请求crm退款接口报错,返回为空!"); } } try{ //退款成功发送企业微信给订单开单人 JSONObject object = new JSONObject(); object.put("abnormal","订单退款成功,现金支付资产已退回!"); object.put("orderNo",ordersTotal.getOrderNo()); User user=commonService.selectOneByKeyBlob(UserMapper.class,ordersTotal.getUserId()); object.put("userName",user==null?"":user.getName()); object.put("notificationSubject", NotificationLog.NOTIFICATION_SUBJECT_REFUND_NOTE_PHISKIN_SUC_NOTICE); SendNoticeUtil.successOrderSendNotice(commonService, customParameter, ordersTotal,object); }catch (Exception e){ logger.error("退款成功发送企业微信给订单开单人错误:",e); } } /** * 生成CRM退款回执 * @param refundReturnDto crm退款返回总结构 * @param refundRecord 退款总单 * @param commonService 映射 */ public static void createCrmRefundReceipt(RefundReturnDto refundReturnDto,RefundRecord refundRecord,CommonService commonService){ try{ if (RefundReturnDto.REFUND_STATUS_SUECCESS==refundReturnDto.getRefundStatus() ||RefundReturnDto.REFUND_STATUS_PART==refundReturnDto.getRefundStatus()){ StringBuilder crmReturnData = new StringBuilder(); crmReturnData.append("

【CRM退款】

"); crmReturnData.append("

CRM退款流水号:").append(refundReturnDto.getRefundNo()).append("

"); crmReturnData.append("

已退款总金额:"); crmReturnData.append(refundReturnDto.getRefundTotal()); crmReturnData.append(";"); crmReturnData.append("已退款其他金额:"); crmReturnData.append(refundReturnDto.getRefundAmountTotal()); crmReturnData.append(";"); crmReturnData.append("已退款储值金:"); crmReturnData.append(refundReturnDto.getRefundRecharge()); crmReturnData.append(";"); crmReturnData.append("已退款增值金:"); crmReturnData.append(refundReturnDto.getRefundIncrement()); crmReturnData.append(";"); crmReturnData.append("已退款积分:"); crmReturnData.append(refundReturnDto.getRefundIntegral()); crmReturnData.append("

"); crmReturnData.append("

退款方式:

"); if(refundReturnDto.getRefundAmountModelDtoList() != null && refundReturnDto.getRefundAmountModelDtoList().size() > 0){ for(RefundAmountModelDto refundAmountModelDto1:refundReturnDto.getRefundAmountModelDtoList()){ crmReturnData.append("

"); switch (refundAmountModelDto1.getRefundType()){ case RefundAmountModelDto.REFUND_TYPE_WX: crmReturnData.append("微信[CRM]:").append(refundAmountModelDto1.getAmountTotal()); break; case RefundAmountModelDto.REFUND_TYPE_ZFB: crmReturnData.append("支付宝[CRM]:").append(refundAmountModelDto1.getAmountTotal()); break; default: crmReturnData.append("[").append(refundAmountModelDto1.getRefundType()).append("]"); crmReturnData.append("未知方式[CRM]:").append(refundAmountModelDto1.getAmountTotal()); } crmReturnData.append("

"); } } RefundRecordReceipt refundRecordReceipt = new RefundRecordReceipt(); refundRecordReceipt.setReceiptSource(RefundRecordReceipt.RECEIPT_SOURCE_CRM); refundRecordReceipt.setReceiptSourceNo(refundReturnDto.getRefundNo()); refundRecordReceipt.setReceiptSourceData(JSON.toJSONString(refundReturnDto)); refundRecordReceipt.setReceiptType(RefundRecordReceipt.RECEIPT_TYPE_REFUND); refundRecordReceipt.setRemarks(crmReturnData.toString()); refundRecordReceipt.setOperatorId(refundRecord.getOperatorId()); refundRecordReceipt.setOperatorNo(refundRecord.getOperatorNo()); refundRecordReceipt.setOperatorName(refundRecord.getOperatorName()); refundRecordReceipt.setRefundRecordId(refundRecord.getId()); commonService.insert(RefundRecordReceiptMapper.class,refundRecordReceipt); } }catch (Exception e){ logger.error("退款生成CRM回执报错:{}",e); } } /** * 营销中心回调审批处理接口 * @param aduitDto * @return */ @Override public PlatformResult partRefundApproval(AduitDto aduitDto) { logger.info("营销中心审批退款入参:{}",JSON.toJSONString(aduitDto)); SqlSentence sqlSentence = new SqlSentence(); Map map=new HashMap<>(); sqlSentence.setM(map); map.put("applyId",aduitDto.getApplyId()); sqlSentence.sqlSentence("SELECT * FROM cancel_order WHERE applyId=#{m.applyId} and isDel=0 ",map); CancelOrder cancelOrder=commonService.selectOne(CancelOrderMapper.class,sqlSentence); if( cancelOrder == null ){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到该审核标识"); } if(!CancelOrder.PENDING.equals(cancelOrder.getApprovalstatus())){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"该条审核标识已经处理过了,不要重复提交"); } Map operator=new HashMap<>(); operator.put("operatorId",cancelOrder.getOperatorId()); operator.put("operatorName",cancelOrder.getOperatorName()); //先判断项目的状态是否存在 OrdersTotal ordersTotal= ordersTotalMapper.selectOneByKey(cancelOrder.getOrderId()); if(ordersTotal==null){ logger.info("取消订单流程:未找到总订单信息!订单id:{}",cancelOrder.getOrderId()); return PlatformResult.failure(PlatformCode.ERROR_TIPS,"取消订单流程:未找到总订单信息!"); } cancelOrder.setExamEmplId(aduitDto.getExamEmplId()); cancelOrder.setExamEmplName(aduitDto.getExamEmplName()); //获取退款记录 RefundRecord refundRecord = commonService.selectOneByKey(RefundRecordMapper.class,cancelOrder.getRefundRecordId()); if(refundRecord==null){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"未找到该审核的退款记录"); } //订单节点日志 OrdersNodeLog ordersNodeLog = new OrdersNodeLog(); StringBuilder orderNodeBuilder = new StringBuilder(); if(BaseEntity.NO.equals(aduitDto.getType())){ orderNodeBuilder.append("审核不通过"); orderNodeBuilder.append("-最后审核人:").append(aduitDto.getExamEmplName()); //审核不通过 map.put("id",cancelOrder.getId()); map.put("approvalstatus",CancelOrder.FAIL); map.put("approvalstatusOld",CancelOrder.PENDING); map.put("editTime",new Date()); sqlSentence.sqlUpdate("approvalstatus = #{m.approvalstatus},editTime = #{m.editTime} WHERE id = #{m.id} AND approvalstatus = #{m.approvalstatusOld}",map); if(commonService.updateWhere(CancelOrderMapper.class,sqlSentence)!=1){ throw new TipsException("审核失败,审核状态已变更!"); } //更改总订单退款状态 map.put("orderId",ordersTotal.getId()); sqlSentence.sqlSentence("select * from order_item WHERE orderId=#{m.orderId} and isDel=0",map); List orderItemList=commonService.selectList(OrderItemMapper.class,sqlSentence); List collect = orderItemList.stream().map(OrderItem::getRefundStatus).collect(Collectors.toList()); if(collect.contains(OrderTotalConstants.STATUS_REFUND_PART)){ ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART); }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE) && collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){ ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART); }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE)){ ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE); }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){ ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_FINSH); }else { ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE); } map.put("refundStatus",ordersTotal.getRefundStatus()); map.put("id",ordersTotal.getId()); sqlSentence.sqlSentence(" refundStatus=#{m.refundStatus} WHERE id=#{m.id} ",map); ordersTotalMapper.updateWhere(sqlSentence); //退款单信息变更 map.put("id",refundRecord.getId()); map.put("refundStatus",RefundStatus.STATUS_INVALID_REFUND); map.put("refundStatusOld",RefundStatus.STATUS_APPLY_REFUND); map.put("editTime",new Date()); sqlSentence.sqlUpdate("refundStatus = #{m.refundStatus},editTime = #{m.editTime} WHERE id = #{m.id} AND refundStatus = #{m.refundStatusOld}",map); if(commonService.updateWhere(RefundRecordMapper.class,sqlSentence) != 1){ throw new TipsException("审核失败,退款单状态已发生变更!"); } //先赋值该作废操作人,后面会用到,注意,这里不存储 refundRecord.setInvalidId(refundRecord.getOperatorId()); refundRecord.setInvalidName(refundRecord.getInvalidName()); refundRecord.setInvalidNo(refundRecord.getOperatorNo()); refundRecord.setInvalidAppId(refundRecord.getOperatorAppId()); refundRecord.setInvalidAppName(refundRecord.getOperatorAppName()); //处理老带新的佣金,没有退款才退 if(ordersTotal.getRefundStatus() == OrderTotalConstants.STATUS_REFUND_NONE){ oldBlingNewRefundFail(refundRecord,orderNodeBuilder,commonService); } //拒绝审批需要还原回去储值金 //判断是否是充值订单,是的话需要把前面预扣的还原 if(OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){ //判断金额不等于0,才执行操作,不然操作余额的时候会爆操作数量或金额不能为0 //充值金额 OrderRefundCancelTool.rechargeHandle(ordersTotal,refundRecord,OrderRefundCancelTool.OPT_TYPE_CANCEL,"拒绝审批",orderNodeBuilder,commonService); } //活动规则退款处理 OrderRefundCancelTool.activityRuleHandle(ordersTotal,refundRecord,OrderRefundCancelTool.OPT_TYPE_CANCEL,"拒绝审批",orderNodeBuilder,commonService); ordersNodeLog.setCommonType(OrdersNodeLog.TYPE_COMMON_ORDER_REFUND); ordersNodeLog.setContent(orderNodeBuilder.toString()); ordersNodeLog.setOrderId(ordersTotal.getId()); commonService.insert(OrdersNodeLogMapper.class,ordersNodeLog); return PlatformResult.success("拒绝取消审核通过"); } cancelOrder.setEditTime(new Date()); cancelOrder.setApprovalstatus(CancelOrder.SUCCESS); commonService.updateAll(CancelOrderMapper.class,cancelOrder); orderNodeBuilder.append("审核通过,开始处理退款"); Maprefund =handleRefundOrder(operator,refundRecord,ordersTotal,ordersNodeLog,orderNodeBuilder,cancelOrder); return PlatformResult.success(refund); } /** * 全部退款处理退款逻辑 * @param orderRefundDto 退款信息 * @return 结果 */ @Override public PlatformResult wholeRefund(OrderRefundDto orderRefundDto,ThirtApplication thirtApplication) { OrdersTotal ordersTotal = ordersTotalMapper.selectOneByKey(orderRefundDto.getOrderId()); OrderRefundDto parameter = getWholeRefundInfo(orderRefundDto, ordersTotal); //调用退款处理退款逻辑 return partRefund(ordersTotal,parameter,thirtApplication); } /** 获取全部退款的详细信息 */ @Override public OrderRefundDto getWholeRefundInfo(OrderRefundDto orderRefundDto, OrdersTotal ordersTotal){ if(ordersTotal == null){ ordersTotal = ordersTotalMapper.selectOneByKey(orderRefundDto.getOrderId()); } //获取该笔订单的项目详情 List> refundDetails=refundDetails(ordersTotal); // 退款信息集合 List refundList=new ArrayList<>(); //退款二级子订单信息集合 List orderItemSourceRefundDtos; List> refundSonDetails; OrderItemRefundDto orderItemRefundDto; OrderItemSourceRefundDto orderItemSourceRefundDto; for (Map refundDetail : refundDetails) { orderItemRefundDto = new OrderItemRefundDto(); orderItemRefundDto.setOrderItemId(String.valueOf(refundDetail.get("id"))); orderItemRefundDto.setType(String.valueOf(refundDetail.get("type"))); ////退款备注 orderItemRefundDto.setRemarks(orderRefundDto.getRemarks()); orderItemRefundDto.setRefundReason(orderRefundDto.getRefundReason()); if(OrderItemConstants.TYPE_PROMOTION.equals(orderItemRefundDto.getType()) || OrderItemConstants.CARD_BAG.equals(orderItemRefundDto.getType())){ orderItemRefundDto.setRefundNum(0); refundSonDetails= (List>) refundDetail.get("list"); orderItemSourceRefundDtos=new ArrayList<>(); for (Map refundSonDetail : refundSonDetails) { orderItemSourceRefundDto=new OrderItemSourceRefundDto(); orderItemSourceRefundDto.setOrderItemSonId(String.valueOf(refundSonDetail.get("id"))); orderItemSourceRefundDto.setType(String.valueOf(refundSonDetail.get("type"))); orderItemSourceRefundDto.setRefundNum(Integer.parseInt(String.valueOf(refundSonDetail.get("notUsedNum")))); if(OrderItemConstants.TYPE_PROJECT.equals(orderItemRefundDto.getType()) && BaseEntity.YES.equals(orderRefundDto.getDeductionCancel())){ orderItemSourceRefundDto.setRefundDeductionCancelList((List) refundSonDetail.get("deductionList")); if(orderItemSourceRefundDto.getRefundDeductionCancelList() != null){ for(RefundDeductionCancelVo refundDeductionCancelVo:orderItemSourceRefundDto.getRefundDeductionCancelList()){ orderItemSourceRefundDto.setRefundNum(orderItemSourceRefundDto.getRefundNum()+refundDeductionCancelVo.getNum()); } } } //退款备注 orderItemSourceRefundDto.setRemarks(orderRefundDto.getRemarks()); orderItemSourceRefundDto.setRefundReason(orderRefundDto.getRefundReason()); orderItemSourceRefundDtos.add(orderItemSourceRefundDto); } orderItemRefundDto.setOrderItemSourceRefundDtos(orderItemSourceRefundDtos); }else{ orderItemRefundDto.setRefundNum(Integer.parseInt(refundDetail.get("notUsedNum").toString()) ); if(OrderItemConstants.TYPE_PROJECT.equals(orderItemRefundDto.getType()) && BaseEntity.YES.equals(orderRefundDto.getDeductionCancel())){ orderItemRefundDto.setRefundDeductionCancelList((List) refundDetail.get("deductionList")); if(orderItemRefundDto.getRefundDeductionCancelList() != null){ for(RefundDeductionCancelVo refundDeductionCancelVo:orderItemRefundDto.getRefundDeductionCancelList()){ orderItemRefundDto.setRefundNum(orderItemRefundDto.getRefundNum()+refundDeductionCancelVo.getNum()); } } } } refundList.add(orderItemRefundDto); } orderRefundDto.setRefundList(refundList); //获取退款资金信息 OrderRefundDto parameter= nextStep(ordersTotal,orderRefundDto); parameter.setOperatorId(orderRefundDto.getOperatorId()); parameter.setIsRefund(orderRefundDto.getIsRefund()); parameter.setIsApproval(orderRefundDto.getIsApproval()); parameter.setRoleId(orderRefundDto.getRoleId()); parameter.setPlatformSource(orderRefundDto.getPlatformSource()); parameter.setRefundOperationType(BaseEntity.NO); parameter.setRemarks(orderRefundDto.getRemarks()); parameter.setRefundReason(orderRefundDto.getRefundReason()); parameter.setCouponList(parameter.getPayCouponList()); //退款金额 List refundPayMethodList = parameter.getPayMethodList(); for(OrderPayMethodDto orderPayMethodDto:refundPayMethodList){ orderPayMethodDto.setRefundNumberNo(orderPayMethodDto.getPayMethodNo()); orderPayMethodDto.setRefundNumberName(orderPayMethodDto.getPayMethodName()); orderPayMethodDto.setMoney(orderPayMethodDto.getPayTotal()); } parameter.setRefundPayMethod(refundPayMethodList); //卡包订单是没有金额退回去的,跳过 if(!OrderTotalConstants.TYPE_CARD_BAG.equals(ordersTotal.getType())){ if(parameter.getTotalAmount().compareTo(ordersTotal.getActualTotal()) != 0){ throw new TipsException("退款金额与订单总金额不符!"); } /*if(parameter.getTotalIntegral().compareTo(ordersTotal.getActualTotalPoints()) != 0){ throw new TipsException("退款积分与订单总积分不符!"); }*/ } return parameter; } /** * 伪造退款处理退款逻辑 * @param orderRefundDto 退款信息 * @return 结果 */ @Override public PlatformResult forgePartRefund(OrderRefundDto orderRefundDto) { logger.info("退款打印参数:{}", JSON.toJSONString(orderRefundDto)); //先判断项目的状态是否存在 OrdersTotal ordersTotal=null; try { ordersTotal=ordersTotalMapper.selectOneByKey(orderRefundDto.getOrderId()); if(ordersTotal==null){ logger.info("取消订单流程:未找到总订单信息!订单id:{}",orderRefundDto.getOrderId()); return PlatformResult.failure(PlatformCode.ERROR_TIPS,"取消订单流程:未找到总订单信息!"); } }catch (Exception e){ logger.info("取消订单流程:根据订单id查询多条总订单信息!订单id:{}",orderRefundDto.getOrderId()); return PlatformResult.failure(PlatformCode.ERROR_TIPS,"取消订单流程:根据订单id查询多条总订单信息!"); } if(!(OrderTotalConstants.STATUS_REFUND_NONE==ordersTotal.getRefundStatus()) && !(OrderTotalConstants.STATUS_REFUND_PART==ordersTotal.getRefundStatus())){ throw new TipsException("订单标识错误,订单退款状态不正确!"); } // orderRefundDto=parameterVerification(orderRefundDto); return handleforgePartRefund(ordersTotal,orderRefundDto); } /** * 伪造处理退款详情 */ public PlatformResult handleforgePartRefund(OrdersTotal ordersTotal,OrderRefundDto orderRefundDto){ //订单节点日志 OrdersNodeLog ordersNodeLog = new OrdersNodeLog(); StringBuilder orderNodeBuilder = new StringBuilder(); orderNodeBuilder.append("开始退款(WZ)"); // 获取退款方式,退款项目,退款优惠卷 List refundPayMethod=orderRefundDto.getRefundPayMethod(); List refundList=orderRefundDto.getRefundList(); List couponList=orderRefundDto.getCouponList(); //客户选的退款方式总金额 BigDecimal sumMoney=refundPayMethod.stream().map(OrderPayMethodDto::getMoney).reduce(BigDecimal.ZERO,BigDecimal::add); //本次退款总金额 BigDecimal refundSumMoney=refundList.stream().map(OrderItemRefundDto::getRefundMoney).reduce(BigDecimal.ZERO,BigDecimal::add); if(!OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){ if(sumMoney.compareTo(refundSumMoney) > 0){ throw new TipsException("退款金额不能大于可退金额!"); } orderNodeBuilder.append("-本次退款项目总金额:").append(refundSumMoney).append(",客户选的退款方式总金额:").append(sumMoney); }else { orderNodeBuilder.append("-本次退款项目总金额:").append(ordersTotal.getActualTotal()).append(",客户选的退款方式总金额:").append(sumMoney); } Map operator = ApiOrderUtil.getOperator(commonService, orderRefundDto.getOperatorId());//获取操作人信息 SqlSentence sqlSentence = new SqlSentence(); Map map=new HashMap<>(); sqlSentence.setM(map); //退款总记录 orderNodeBuilder.append("-处理退款总记录"); String totalCode = CreateNo.createTimeNo(systemParameterMapper, "R", 8, "yyyyMMddHHmmss");//总订单编号 RefundRecord refundRecord=new RefundRecord(totalCode,ordersTotal.getShopId(),ordersTotal.getShopName(),sumMoney, RefundStatus.STATUS_APPLY_REFUND,0, RefundSoruceConstants.TYPE_SOURCE_ORDER,"phis退款",ordersTotal.getId(),ordersTotal.getUserId()); refundRecord.setOperatorType(RefundRecord.OPERATOR_TYPE_EMPLOYEE); Employee employee = commonService.selectOneByKey(EmployeeMapper.class,orderRefundDto.getOperatorId()); refundRecord.setOperatorId(employee.getId()); refundRecord.setRefundOperationType(orderRefundDto.getRefundOperationType()); refundRecord.setOperatorName(employee.getCnName()); refundRecordService.insert(refundRecord); if(refundPayMethod.size()>0){ //处理退款方式记录表 handleRefundPayMethod(orderRefundDto,orderNodeBuilder,ordersTotal,refundRecord); } if(couponList!=null && couponList.size()>0){ //处理优惠卷 handleOrderCouponRefunDto(couponList,orderNodeBuilder,ordersTotal,refundRecord); } try{ orderNodeBuilder.append("-开始记录收入确认表"); PerformanceInfoTool.handRefundPerformanceInfo(commonService,refundRecord); orderNodeBuilder.append("-记录收入确认表成功"); }catch (Exception e){ orderNodeBuilder.append("-记录收入确认表失败"); logger.info("记录收入确认表,异常:{}",e.getMessage(),e); // 添加错误日志 PerformanceInfoTool.addErrorLog(commonService, refundRecord.getId(), PerformanceInfo.ASSOCIATION_TYPE_GOODS_REFUND, e.getMessage()); } //记录操作日志 orderNodeBuilder.append("-记录操作日志"); StringBuffer stringBuffer=new StringBuffer("操作人:"+operator.get("operatorName")+",进行退款(WZ)"); OrderLog orderLog=new OrderLog(ordersTotal.getId(), OrderLogConstants.LOG_TYPE_REFUND,stringBuffer.toString() ,operator.get("operatorName"),operator.get("operatorId"),OrderTotalConstants.STATUS_CANCEL); commonService.insert(OrderLogMapper.class,orderLog); orderNodeBuilder.append("-结束处理退款"); ordersNodeLog.setCommonType(OrdersNodeLog.TYPE_COMMON_ORDER_REFUND); ordersNodeLog.setContent(orderNodeBuilder.toString()); ordersNodeLog.setOrderId(ordersTotal.getId()); commonService.insert(OrdersNodeLogMapper.class,ordersNodeLog); return PlatformResult.success("成功"); } /** * 根据订单 重新绑定订单退款状态 * */ @Override public void verifyOrderRefundStatus(OrdersTotal ordersTotalDto) { SqlSentence sqlSentence = new SqlSentence(); Map sqlMap = new HashMap<>(); sqlSentence.setM(sqlMap); sqlMap.put("isDel", BaseEntity.NO); sqlMap.put("orderId", ordersTotalDto.getId()); sqlMap.put("type", OrderItemConstants.TYPE_PROJECT); sqlSentence.sqlSentence("SELECT * FROM orders_total WHERE  id = #{m.orderId} and isDel = #{m.isDel} ",sqlMap); OrdersTotal ordersTotal = ordersTotalMapper.selectOne(sqlSentence); if(ordersTotal==null){ throw new TipsException("订单标识错误,找不到订单!"); } //查询二级订单 sqlSentence.sqlSentence("SELECT * FROM order_item_source WHERE  orderId = #{m.orderId} and type = #{m.type} and isDel = #{m.isDel} ",sqlMap); List orderItemSonList=orderItemSonMapper.selectList(sqlSentence); if(orderItemSonList!=null && orderItemSonList.size()>0){ int oldRefundStatus; int newRefundStatus; UserProjectItem userProjectItem; for (OrderItemSon orderItemSon : orderItemSonList) { if(OrderTotalConstants.STATUS_REFUND_FINSH==orderItemSon.getRefundStatus()){ oldRefundStatus=OrderTotalConstants.STATUS_REFUND_FINSH; userProjectItem = PartialRefundUtil.getUserProject(orderItemSon.getId(),commonService); if(userProjectItem.getNotUsedNum()>0){ newRefundStatus=OrderTotalConstants.STATUS_REFUND_PART; }else { newRefundStatus=oldRefundStatus; } if(newRefundStatus!=oldRefundStatus){ sqlMap.put("refundStatus", newRefundStatus); sqlMap.put("id", orderItemSon.getId()); sqlSentence.sqlSentence(" refundStatus = #{m.refundStatus} WHERE id = #{m.id} ",sqlMap); orderItemSonMapper.updateWhere(sqlSentence); sqlMap.put("refundStatus", newRefundStatus); sqlMap.put("id", orderItemSon.getOrderItemId()); sqlSentence.sqlSentence(" refundStatus = #{m.refundStatus} WHERE id = #{m.id} ",sqlMap); orderItemMapper.updateWhere(sqlSentence); } } } } //查询二级订单 sqlSentence.sqlSentence("SELECT * FROM order_item WHERE  orderId = #{m.orderId} and type = #{m.type} and isDel = #{m.isDel} ",sqlMap); List orderItemList=orderItemMapper.selectList(sqlSentence); if(orderItemList!=null && orderItemList.size()>0){ int oldRefundStatus; int newRefundStatus; UserProjectItem userProjectItem; for (OrderItem orderItem : orderItemList) { oldRefundStatus=OrderTotalConstants.STATUS_REFUND_FINSH; userProjectItem = PartialRefundUtil.getUserProject(orderItem.getId(),commonService); if(userProjectItem.getNotUsedNum()>0){ newRefundStatus=OrderTotalConstants.STATUS_REFUND_PART; }else { newRefundStatus=oldRefundStatus; } if(newRefundStatus!=oldRefundStatus){ sqlMap.put("refundStatus", newRefundStatus); sqlMap.put("id", orderItem.getId()); sqlSentence.sqlSentence(" refundStatus = #{m.refundStatus} WHERE id = #{m.id} ",sqlMap); orderItemMapper.updateWhere(sqlSentence); } } } sqlMap.put("orderId",ordersTotal.getId()); sqlSentence.sqlSentence("select * from order_item WHERE orderId=#{m.orderId} and isDel=0",sqlMap); List orderItems=commonService.selectList(OrderItemMapper.class,sqlSentence); List collect = orderItems.stream().map(OrderItem::getRefundStatus).collect(Collectors.toList()); if(collect.contains(OrderTotalConstants.STATUS_REFUND_PART)){ ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART); ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY); }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE) && collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){ ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART); ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY); }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE)){ ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE); ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY); }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){ ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_FINSH); ordersTotal.setStatus(OrderTotalConstants.STATUS_CANCEL); }else { ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE); ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY); } ordersTotal.setEditTime(new Date()); commonService.updateAll(OrdersTotalMapper.class,ordersTotal); } /**作废退款*/ @Override public void refundCancel(RefundCancelVo refundCancelVo, RefundRecord refundRecord,Employee employee,EmployeeRole employeeRole , ThirtApplication thirtApplication) { //判断退款单状态 if(refundRecord.getRefundStatus() != RefundStatus.STATUS_SUCC_REFUND){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"操作失败,退款单状态错误!"); } //获取订单信息 OrdersTotal ordersTotal = ordersTotalMapper.selectOneByKey(refundRecord.getOrderId()); if(ordersTotal == null){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"操作失败,获取订单信息失败!"); } //检查升单关联逻辑 cancelRefundCheckRiseOrder(ordersTotal); SqlSentence sqlSentence = new SqlSentence(); Map values = new HashMap<>(); StringBuilder sql = new StringBuilder(); //如果是线上退款,那么就不给作废 values.put("refundRecordId",refundRecord.getId()); sqlSentence.sqlSentence(" isDel = 0 AND refundRecordId = #{m.refundRecordId}",values); if(commonService.selectCount(RefundCashMapper.class,sqlSentence) > 0){ throw new TipsException("该退款记录含线上退款,不能作废!"); } //填充数据,后面会用到 refundRecord.setInvalidType(RefundRecord.OPERATOR_TYPE_EMPLOYEE); refundRecord.setInvalidRemarks(refundCancelVo.getRemarks()); //****更新退款单信息,更新完退款单再去做剩下的操作 values.put("refundStatus",RefundStatus.STATUS_REFUND_CANCEL); values.put("refundStatusOld",RefundStatus.STATUS_SUCC_REFUND); values.put("id",refundRecord.getId()); values.put("invalidTime",new Date()); values.put("invalidType",RefundRecord.OPERATOR_TYPE_EMPLOYEE); values.put("invalidRemarks",refundCancelVo.getRemarks()); sql.append("refundStatus = #{m.refundStatus},invalidTime = #{m.invalidTime},invalidRemarks = #{m.invalidRemarks},invalidType = #{m.invalidType}"); if(employee != null){ refundRecord.setInvalidId(employee.getId()); refundRecord.setInvalidNo(employee.getEmployeeNo()); refundRecord.setInvalidName(employee.getCnName()); values.put("invalidId",employee.getId()); values.put("invalidNo",employee.getEmployeeNo()); values.put("invalidName",employee.getCnName()); sql.append(",invalidId = #{m.invalidId},invalidNo = #{m.invalidNo},invalidName = #{m.invalidName}"); } if(employeeRole != null){ refundRecord.setInvalidRoleNo(employeeRole.getRoleUniqueStr()); refundRecord.setInvalidRoleName(employeeRole.getRoleName()); values.put("invalidRoleNo",employeeRole.getRoleUniqueStr()); values.put("invalidRoleName",employeeRole.getRoleName()); sql.append(",invalidRoleNo = #{m.invalidRoleNo},invalidRoleName = #{m.invalidRoleName}"); } if(thirtApplication != null){ refundRecord.setInvalidAppId(thirtApplication.getAppId()); refundRecord.setInvalidAppCode(thirtApplication.getAppIdCode()); refundRecord.setInvalidAppName(thirtApplication.getName()); values.put("invalidAppId",thirtApplication.getAppId()); values.put("invalidAppCode",thirtApplication.getAppIdCode()); values.put("invalidAppName",thirtApplication.getName()); sql.append(",invalidAppId = #{m.invalidAppId},invalidAppCode = #{m.invalidAppCode},invalidAppName = #{m.invalidAppName}"); } sql.append(" WHERE id = #{m.id} AND refundStatus = #{m.refundStatusOld}"); sqlSentence.sqlUpdate(sql.toString(),values); if(refundRecordMapper.updateWhere(sqlSentence) != 1){ throw new PlatTipsException(PlatformCode.ERROR_TIPS,"操作失败,退款单状态已发生变化!"); } //订单系统日志 StringBuilder orderNodeBuilder = new StringBuilder(); orderNodeBuilder.append("开始作废退款"); //判断订单类型 if(OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){ //充值订单 OrderRefundCancelTool.rechargeHandle(ordersTotal,refundRecord,OrderRefundCancelTool.OPT_TYPE_CANCEL,"作废退款",orderNodeBuilder,commonService); }else{ //处理子单 OrderRefundCancelTool.refundRecordItemHandle(ordersTotal,refundRecord,commonService); } //处理订单活动 OrderRefundCancelTool.activityRuleHandle(ordersTotal,refundRecord,OrderRefundCancelTool.OPT_TYPE_CANCEL,"作废退款",orderNodeBuilder,commonService); //处理订单优惠券 OrderRefundCancelTool.handCoupon(ordersTotal,refundRecord,orderNodeBuilder,commonService); //处理总退款方式 List refundRecordMethodList= OrderRefundCancelTool.refundRecordMotnedHandle(refundRecord,ordersTotal,orderNodeBuilder,commonService); //操作的现金金额 BigDecimal cashTotal = BigDecimal.ZERO; for(RefundRecordMethod refundRecordMethod:refundRecordMethodList){ if(refundRecordMethod.getIsMoneyPay().equals(RefundRecordMethod.YES)){ cashTotal = cashTotal.add(refundRecordMethod.getActualTotal()); } } //报错订单系统日志 //****更改总订单退款状态 values.clear(); values.put("orderId",ordersTotal.getId()); sqlSentence.sqlSentence("select * from order_item WHERE orderId=#{m.orderId} and isDel=0",values); List orderItemList=commonService.selectList(OrderItemMapper.class,sqlSentence); int oldStatus = ordersTotal.getStatus(); values.clear(); values.put("oldStatus",ordersTotal.getStatus()); values.put("oldRefundStatus",ordersTotal.getRefundStatus()); List collect = orderItemList.stream().map(OrderItem::getRefundStatus).collect(Collectors.toList()); if(collect.contains(OrderTotalConstants.STATUS_REFUND_PART)){ ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY); ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART); ordersTotal.setReTotal(orderItemList.stream().map(OrderItem::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add)); }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE) && collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){ ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART); ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY); ordersTotal.setReTotal(orderItemList.stream().map(OrderItem::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add)); }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_NONE)){ ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE); ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY); ordersTotal.setReTotal(BigDecimal.ZERO); }else if (collect.contains(OrderTotalConstants.STATUS_REFUND_FINSH)){ ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_FINSH); ordersTotal.setStatus(OrderTotalConstants.STATUS_CANCEL); ordersTotal.setReTotal(orderItemList.stream().map(OrderItem::getReTotal).reduce(BigDecimal.ZERO,BigDecimal::add)); }else { if(OrderTotalConstants.TYPE_RECHARGE.equals(ordersTotal.getType())){ if(ordersTotal.getReTotal().compareTo(refundRecord.getRefundTotal()) == 0){ ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE); ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY); ordersTotal.setReTotal(ordersTotal.getReTotal().subtract(refundRecord.getRefundTotal())); }else if(ordersTotal.getReTotal().compareTo(refundRecord.getRefundTotal()) > 0){ ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_PART); ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY); ordersTotal.setReTotal(ordersTotal.getReTotal().subtract(refundRecord.getRefundTotal())); } }else{ ordersTotal.setRefundStatus(OrderTotalConstants.STATUS_REFUND_NONE); ordersTotal.setStatus(OrderTotalConstants.STATUS_PAY); ordersTotal.setReTotal(ordersTotal.getReTotal().subtract(refundRecord.getRefundTotal())); } } ordersTotal.setIsSyncOrder(BaseEntity.NO); values.put("isSyncOrder",BaseEntity.NO); values.put("status",ordersTotal.getStatus()); values.put("refundStatus",ordersTotal.getRefundStatus()); values.put("reTotal",ordersTotal.getReTotal()); values.put("id",ordersTotal.getId()); sqlSentence.sqlUpdate("isSyncOrder = #{m.isSyncOrder},status = #{m.status},refundStatus = #{m.refundStatus},reTotal = #{m.reTotal}" + " WHERE id = #{m.id} AND status = #{m.oldStatus} AND refundStatus = #{m.oldRefundStatus}",values); if(commonService.updateWhere(OrdersTotalMapper.class,sqlSentence) != 1){ throw new TipsException("作废失败,订单状态已发生改变!"); } //初始化初复诊信息 if(OrderTotalConstants.STATUS_CANCEL == oldStatus && oldStatus != ordersTotal.getStatus()){ // OrderUtil.reCalcOrderBothTheOneData(commonService, VisitRecordMapper.class,null,ordersTotal.getUserId(), BaseEntity.NO); // 处理方法调整 TimerHandleTool.addTask(commonService, TimerHandleItem.TYPE_RECALC_ORDER_BOTH, ordersTotal.getUserId(), null); } //额外的操作,升降级,收入确认表 additionalOperate(userLevelRuleService, ordersTotal,refundRecord,cashTotal,orderNodeBuilder,customParameter,commonService); //记录日志(处理到具体节点(成功和失败)) OrdersNodeLog ordersNodeLog = new OrdersNodeLog(); orderNodeBuilder.append("-作废退款单结束"); ordersNodeLog.setCommonType(OrdersNodeLog.TYPE_COMMON_ORDER_REFUND_CANCEL); ordersNodeLog.setContent(orderNodeBuilder.toString()); ordersNodeLog.setOrderId(ordersTotal.getId()); commonService.insert(OrdersNodeLogMapper.class,ordersNodeLog); } /**额外操作,不影响主流程*/ public static void additionalOperate(UserLevelRuleService userLevelRuleService, OrdersTotal ordersTotal,RefundRecord refundRecord,BigDecimal total,StringBuilder orderNodeBuilder,CustomParameter customParameter,CommonService commonService){ if(BigDecimal.ZERO.compareTo(total) < 0){ try { orderNodeBuilder.append("-开始处理作废退款用户升降级,金额:").append(total); // 把原退款撤销返回金额为正所以是升级 UserLevelUtil.order(userLevelRuleService, ordersTotal.getUserId(),ordersTotal.getId(),total,refundRecord.getInvalidAppCode()==null?"phiskin":refundRecord.getInvalidAppCode()); orderNodeBuilder.append("-处理作废退款用户升降级成功"); }catch (Exception e){ String snapshot="处理作废退款用户升降级失败"; orderNodeBuilder.append("-处理作废退款用户升降级失败,异常原因:").append(e.getMessage()); logger.error("处理作废退款用户升降级失败:" + e.getMessage()); //发送企业微信通知给工作人员 SendNoticeUtil.failOrderSendNotice(ordersTotal,e.getMessage(),snapshot,commonService,customParameter); } } try{ orderNodeBuilder.append("-开始记录收入确认表"); PerformanceInfoTool.refundCancelPerformanceInfo(commonService,refundRecord); orderNodeBuilder.append("-记录收入确认表成功"); }catch (Exception e){ orderNodeBuilder.append("-记录收入确认表失败"); logger.info("记录收入确认表,异常:{}",e.getMessage(),e); // 添加错误日志 PerformanceInfoTool.addErrorLog(commonService, refundRecord.getId(), PerformanceInfo.ASSOCIATION_TYPE_GOODS_REFUND, e.getMessage()); } } /**退现金到用户 * 不是原路退,不执行第三方支付退款,直接跳过 * @param refundCashVo 退款信息 */ private synchronized void refundCash(String refundRecordId,RefundCashVo refundCashVo){ if(refundCashVo.getRefundCashItemVoList() == null || refundCashVo.getRefundCashItemVoList().size() == 0){ return; } //--合并同一个的退款支付方式 //装载退款金额,key值:支付编码,value值:退款金额 Map refundMap = new HashMap<>(); BigDecimal refundTotal; for(RefundCashItemVo refundCashItemVo:refundCashVo.getRefundCashItemVoList()){ refundTotal = refundMap.computeIfAbsent(refundCashItemVo.getPaymentNo(),k->BigDecimal.ZERO); refundTotal = refundTotal.add(refundCashItemVo.getRefundTotal()); refundMap.put(refundCashItemVo.getPaymentNo(),refundTotal); } SqlSentence sqlSentence = new SqlSentence(); Map values = new HashMap<>(); //--获取已经退款的记录 values.put("refundRecordId",refundRecordId); sqlSentence.sqlSentence("SELECT * FROM refund_cash WHERE isDel = 0 AND refundRecordId = #{m.refundRecordId}",values); List refundCashList = commonService.selectList(RefundCashMapper.class,sqlSentence); //装载已退款的金额,key值:支付编码,value值:退款金额 Map realRefundMap = new HashMap<>(); BigDecimal consumeRefundTotal; for(RefundCash refundCash:refundCashList){ consumeRefundTotal = realRefundMap.computeIfAbsent(refundCash.getPaymentNo(),k->BigDecimal.ZERO); consumeRefundTotal = consumeRefundTotal.add(refundCash.getRefundTotal()); realRefundMap.put(refundCash.getPaymentNo(),consumeRefundTotal); } List consumeNotifyList; String refundNo; BigDecimal consumeTotal; int refundStatus; for (Map.Entry entry : refundMap.entrySet()) { refundTotal = entry.getValue(); if(refundTotal.compareTo(BigDecimal.ZERO) < 1){ continue; } //--获取支付信息(回调),计算可退款的金额 //初始化可退金额 consumeTotal = BigDecimal.ZERO; consumeNotifyList = ConsumeTool.selectList(refundCashVo.getOrderId(),entry.getKey(),null,commonService); for(ConsumeNotify consumeNotify:consumeNotifyList){ //计算总可退款金额 consumeTotal = consumeTotal.add(consumeNotify.getPayAmount()).subtract(consumeNotify.getRefundTotal()); } //--避免多退,要减去已退款 consumeRefundTotal = realRefundMap.computeIfAbsent(entry.getKey(),k->BigDecimal.ZERO); refundTotal = refundTotal.subtract(consumeRefundTotal); if(refundTotal.compareTo(BigDecimal.ZERO) < 1){ continue; } if(refundTotal.compareTo(consumeTotal) > 0){ //总退款金额比可退金额大,那么就不执行 logger.error("第三方退款失败,退款金额比可退金额大,退款金额:{};可退基恩:{}",refundTotal,consumeTotal); continue; } for(ConsumeNotify consumeNotify:consumeNotifyList){ if(refundTotal.compareTo(BigDecimal.ZERO) < 1){ //退完,那么就跳出循环 continue; } if(consumeNotify.getRefundStatus() == ConsumeNotify.REFUND_STATUS_ALL){ //没有可退金额,那么跳出循环 continue; } //计算可退金额 consumeTotal = consumeNotify.getPayAmount().subtract(consumeNotify.getRefundTotal()); if(consumeTotal.compareTo(BigDecimal.ZERO) < 1){ //没有可退金额,那么跳出循环 continue; } refundStatus = ConsumeNotify.REFUND_STATUS_ALL; if(consumeTotal.compareTo(refundTotal) > 0){ //可退金额比剩下要退的金额大 refundStatus = ConsumeNotify.REFUND_STATUS_PART; consumeTotal = refundTotal; } //生成退款单号 refundNo = createNoService.createNo("RF",String.valueOf(System.currentTimeMillis()),6); try { //服务商退款,生成退款记录 consumeNotifyRefundService.consumeNotifyRefund(consumeNotify,refundStatus,consumeTotal,refundNo,refundRecordId); }catch (Exception e){ logger.error("第三方退款失败,错误信息:",e); } //已经退的跳过 refundTotal = refundTotal.subtract(consumeTotal); } } } /** 作废退款校验升单逻辑 */ public void cancelRefundCheckRiseOrder(OrdersTotal ordersTotal) { if(OrderTotalConstants.ADD_WAY_RISE.equals(ordersTotal.getAddWay())){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "作废退款失败,升单订单暂时不可作废退款!"); } SqlSentence sqlSentence = new SqlSentence(); Map values = new HashMap<>(); sqlSentence.setM(values); StringBuilder sql = new StringBuilder(); //查询有关联升单,且升单的订单已支付,未全部退款的 values.put("orderId", ordersTotal.getId()); values.put("payStatus", OrderTotalConstants.PAY_STATUS_SUC); values.put("refundStatus", OrderTotalConstants.STATUS_REFUND_FINSH); sql.append(" select count(1) from order_rise r ") .append(" join orders_total t on t.id = r.orderId ") .append(" where r.isDel = 0 and r.assocOrderId = #{m.orderId} ") .append(" and t.payStatus = #{m.payStatus} "); sqlSentence.setSqlSentence(sql.toString()); if(commonService.selectCountSql(sqlSentence) > 0){ throw new TipsException("作废退款失败,当前订单已被升单关联,暂时不可作废退款!"); } } /** 作废退款校验升单逻辑V2 */ public void cancelRefundCheckRiseOrderV2(OrdersTotal ordersTotal) { SqlSentence sqlSentence = new SqlSentence(); Map values = new HashMap<>(); sqlSentence.setM(values); StringBuilder sql = new StringBuilder(); //查询有关联升单,且升单的订单已支付,未全部退款的 values.put("orderId", ordersTotal.getId()); values.put("payStatus", OrderTotalConstants.PAY_STATUS_SUC); values.put("refundStatus", OrderTotalConstants.STATUS_REFUND_FINSH); sql.append(" select t.id, t.orderNo from order_rise r ") .append(" join orders_total t on t.id = r.orderId ") .append(" where r.isDel = 0 and r.assocOrderId = #{m.orderId} ") .append(" and t.payStatus = #{m.payStatus} and t.refundStatus != #{m.refundStatus} limit 1 "); sqlSentence.setSqlSentence(sql.toString()); OrdersTotal riseOrder = commonService.selectOne(OrdersTotalMapper.class, sqlSentence); if(riseOrder != null){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "作废退款失败,当前订单已被升单关联,请先退款升单的订单[" + riseOrder.getOrderNo() + "]!"); } //查询是否有被关联的升单订单最新退款成功的退款记录下的退款方式记录 sql.setLength(0); values.clear(); values.put("orderId", ordersTotal.getId()); values.put("refundStatus", RefundStatus.STATUS_SUCC_REFUND); sql.append(" select m.* from refund_record_method m ") .append(" where m.isDel = 0 and m.refundRecordId = ( ") .append(" select r.id from refund_record r ") .append(" join orders_total ot on ot.id = r.orderId ") .append(" join order_rise ri on ri.orderId = r.orderId ") .append(" where r.isDel = 0 and r.refundStatus = #{m.refundStatus} and ri.assocOrderId = #{m.orderId} ") .append(" order by r.createTime desc limit 1 ") .append(" ) "); sqlSentence.setSqlSentence(sql.toString()); List methodList = commonService.selectList(RefundRecordMethodMapper.class, sqlSentence); if(methodList != null && methodList.size() > 0){ //遍历存储累加相同的退款方式 Map refundMethodMap = new HashMap<>(); for(RefundRecordMethod recordMethod : methodList){ if(refundMethodMap.containsKey(recordMethod.getRefundNumberNo())){ refundMethodMap.put(recordMethod.getRefundNumberNo(), refundMethodMap.get(recordMethod.getRefundNumberNo()).add(recordMethod.getRealRefundTotal())); }else{ refundMethodMap.put(recordMethod.getRefundNumberNo(), recordMethod.getRealRefundTotal()); } } logger.info("退款方式Map:{}", refundMethodMap.entrySet()); //查询订单支付方式 sqlSentence.setSqlSentence(" select * from consume_pay where isDel = 0 and orderId = #{m.orderId} "); List consumePayList = commonService.selectList(ConsumePayMapper.class, sqlSentence); if(consumePayList == null || consumePayList.size() < 1){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "作废退款失败,找不到订单支付方式记录!"); } //遍历判断最新的升单退款方式是否都和原订单支付方式对的上 BigDecimal refundMoney; for(ConsumePay consumePay : consumePayList){ refundMoney = refundMethodMap.get(consumePay.getNumberNo()); if(refundMoney == null){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "作废退款失败,当前订单支付时有["+consumePay.getName()+"],关联的升单退款方式没有!"); } if(refundMoney.compareTo(consumePay.getActualTotal()) == -1){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "作废退款失败,,当前订单["+consumePay.getName()+"]支付金额和关联的升单退款金额不一致!"); } } } //--------------------------------------------------------------------------------- //判断如果是升单的订单,作废退款时,判断原订单是否已退款(正常原订单是退款,且作废退款不可能成功的) if(OrderTotalConstants.ADD_WAY_RISE.equals(ordersTotal.getAddWay())){ sql.setLength(0); values.put("orderId", ordersTotal.getId()); values.put("payStatus", OrderTotalConstants.PAY_STATUS_SUC); values.put("refundStatus", OrderTotalConstants.STATUS_REFUND_FINSH); sql.append(" SELECT COUNT(1) FROM orders_total ") .append(" WHERE isDel = 0 and payStatus = #{m.payStatus} and refundStatus != #{m.refundStatus} ") .append(" and id in ( ") .append(" select assocOrderId from order_rise where isDel = 0 and orderId = #{m.orderId} ") .append(" ) "); sqlSentence.setSqlSentence(sql.toString()); if(commonService.selectCountSql(sqlSentence) > 0){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "作废退款失败,当前订单升单时关联的原订单未全部退款,请先退款关联的原订单!"); } //查询原订单退款方式和支付方式是否一致,不一致不给退款 sql.setLength(0); sql.append(" elect count(1) from refund_record_method m ") .append(" where m.isDel = 0 and (m.numberNo != refundNumberNo or actualTotal != realRefundTotal) ") .append(" and m.refundRecordId in ( ") .append(" select r.id from refund_record r ") .append(" join order_rise ri on ri.orderId = r.orderId ") .append(" where r.isDel = 0 and r.refundStatus = 2 and ri.isDel = 0 and ri.orderId = #{m.orderId} "); sqlSentence.setSqlSentence(sql.toString()); if(commonService.selectCountSql(sqlSentence) > 0){ throw new PlatTipsException(PlatformCode.ERROR_TIPS, "作废退款失败,当前订单升单时关联的原订单退款方式或金额不一致!"); } } } }