Commit 7f24c264 by box

券包订单退款审核

parent f2ea2732
package cn.freemud.management.service.handle;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.management.entities.dto.request.order.OrderManagerRequest;
import cn.freemud.management.entities.dto.response.coupon.CouponBaseResponse;
import cn.freemud.management.enums.ResponseResult;
import cn.freemud.management.thirdparty.CouponOnlineClient;
import cn.freemud.management.thirdparty.request.coupon.BatchCouponDiscardReq;
import cn.freemud.management.thirdparty.request.coupon.CouponUnFreezeReq;
import cn.freemud.management.util.ResponseUtil;
import com.alibaba.fastjson.JSONObject;
import com.freemud.application.sdk.api.log.ApiLog;
import com.freemud.application.sdk.api.ordercenter.entities.v1.OrderBeanV1;
import com.freemud.application.sdk.api.ordercenter.enums.BizTypeEnum;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.OrderSettlementResp;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* © All rights Reserved
*
* @author wénkǎi.zhāng 2024-01-02
* @since 1.0
*/
@Component
@RequiredArgsConstructor
public class OrderCouponHandle {
@Value("${coupon.partner.id:1983}")
private String couponPartnerId;
private final CouponQueryHandle couponQueryHandle;
private final CouponOnlineClient couponOnlineClient;
public BaseResponse discardOrderCoupon(String partnerId, OrderBeanV1 orderBean) {
if (BizTypeEnum.SALE_COUPON.getBizType().equals(orderBean.getBizType())) {
List<String> couponCodes = Optional.ofNullable(orderBean.getOrderSettlementDetailList()).orElse(new ArrayList<>()).stream()
// 216 = 买券订单的券信息
.filter(dto -> Objects.equals(216, dto.getSettlementType()) && StringUtils.isNotBlank(dto.getExternalObjectId()))
.map(OrderSettlementResp::getExternalObjectId)
.collect(Collectors.toList());
if (couponCodes.isEmpty()) {
return ResponseUtil.error(ResponseResult.SYSTEM_ERROR.getCode(), "订单中优惠券数据为空。");
}
// 校验券状态是否已被使用
if (couponQueryHandle.isCouponUsed(partnerId, couponCodes)) {
return ResponseUtil.error(ResponseResult.SYSTEM_ERROR.getCode(), "作废优惠券失败,部分券已被使用。");
}
BatchCouponDiscardReq discardReq = new BatchCouponDiscardReq();
discardReq.setCoupons(couponCodes.stream().map(code -> {
return new BatchCouponDiscardReq.CouponInfo(){{
setCode(code);
setMemberId(orderBean.getUserId());
}};
}).collect(Collectors.toList()));
discardReq.setPartnerId(partnerId);
discardReq.setProviderId(couponPartnerId);
discardReq.setCancelReason("券包订单退款");
CouponBaseResponse<Object> discardResp = couponOnlineClient.batchDiscard(discardReq);
if (!Objects.equals(discardResp.getStatusCode(), 100)) {
return ResponseUtil.error(ResponseResult.SYSTEM_ERROR.getCode(), "作废优惠券失败");
}
}
return ResponseUtil.success();
}
public void unfreezeOrderCoupon(String partnerId, OrderBeanV1 orderBean) {
if (BizTypeEnum.SALE_COUPON.getBizType().equals(orderBean.getBizType())) {
List<String> couponCodes = Optional.ofNullable(orderBean.getOrderSettlementDetailList()).orElse(new ArrayList<>()).stream()
// 216 = 买券订单的券信息
.filter(dto -> Objects.equals(216, dto.getSettlementType()) && StringUtils.isNotBlank(dto.getExternalObjectId()))
.map(OrderSettlementResp::getExternalObjectId)
.collect(Collectors.toList());
if (!couponCodes.isEmpty()) {
CouponUnFreezeReq unFreezeReq = new CouponUnFreezeReq();
unFreezeReq.setCoupons(couponCodes.stream().map(code -> {
return new CouponUnFreezeReq.CouponInfo(){{
setCode(code);
setMemberId(orderBean.getUserId());
}};
}).collect(Collectors.toList()));
unFreezeReq.setPartnerId(partnerId);
CouponBaseResponse<Object> unfreezeResp = couponOnlineClient.unfreeze(unFreezeReq);
if (!Objects.equals(unfreezeResp.getStatusCode(), 100)) {
ApiLog.warnMessage("refundReject 解冻券失败:{}", JSONObject.toJSONString(unfreezeResp));
}
}
}
}
}
package cn.freemud.management.service.impl;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.management.adapter.OrderCancelReqAdapter;
import cn.freemud.management.constant.ResponseCodeConstant;
import cn.freemud.management.entities.dto.request.console.*;
import cn.freemud.management.entities.dto.request.order.OrderManagerRequest;
import cn.freemud.management.entities.dto.request.order.RefundSuccessCallbackVo;
import cn.freemud.management.entities.dto.response.coupon.CouponBaseResponse;
import cn.freemud.management.entities.dto.response.order.OrderManagerResponse;
import cn.freemud.management.entities.dto.response.pay.PayRefundResponse;
import cn.freemud.management.enums.OperateType;
import cn.freemud.management.enums.*;
import cn.freemud.management.handler.AssisantApplicationHandler;
import cn.freemud.management.enums.ResponseResult;
import cn.freemud.management.service.OrderBaseService;
import cn.freemud.management.service.OrderManagerService;
import cn.freemud.management.service.handle.*;
import cn.freemud.management.thirdparty.ConsoleApiClient;
import cn.freemud.management.thirdparty.CouponOnlineClient;
import cn.freemud.management.thirdparty.OrderCallbackClient;
import cn.freemud.management.thirdparty.request.coupon.BatchCouponDiscardReq;
import cn.freemud.management.thirdparty.request.coupon.CouponUnFreezeReq;
import cn.freemud.management.service.handle.OrderCouponHandle;
import cn.freemud.management.service.handle.PaymentHandle;
import cn.freemud.management.service.handle.SaasOrderHandle;
import cn.freemud.management.service.handle.StockHandle;
import cn.freemud.management.util.ResponseUtil;
import com.alibaba.fastjson.JSONObject;
import com.freemud.application.sdk.api.log.ApiLog;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.ordercenter.config.OrderCenterProperties;
import com.freemud.application.sdk.api.ordercenter.entities.v1.OrderBeanV1;
import com.freemud.application.sdk.api.ordercenter.entities.vo.OrderCallBackRequestVo;
import com.freemud.application.sdk.api.ordercenter.enums.*;
import com.freemud.application.sdk.api.ordercenter.enums.orderv1.OrderSourceV1;
import com.freemud.application.sdk.api.ordercenter.enums.orderv1.OrderStatusV1;
import com.freemud.application.sdk.api.ordercenter.request.AfterSalesRefundFailReq;
import com.freemud.application.sdk.api.ordercenter.request.OrderCancelReq;
import com.freemud.application.sdk.api.ordercenter.request.OrderExpressReq;
import com.freemud.application.sdk.api.ordercenter.request.OrderExtInfoDto;
import com.freemud.application.sdk.api.ordercenter.response.OrderBaseResp;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.AfterSalesOrderResp;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.OrderSettlementResp;
import com.freemud.application.sdk.api.ordercenter.service.OrderSdkService;
import com.freemud.application.sdk.api.service.EmailAlertService;
import com.freemud.application.sdk.api.storecenter.service.StoreCenterService;
import com.freemud.sdk.api.assortment.order.enums.PayRefundStatus;
import com.freemud.sdk.api.assortment.order.response.order.QueryOrderByIdResponse;
import com.freemud.sdk.api.assortment.order.response.order.QueryOrdersResponse;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.Objects;
import java.util.UUID;
import static cn.freemud.management.enums.OperateType.ORDER_AGREE_REFUND;
......@@ -69,15 +40,24 @@ import static cn.freemud.management.enums.OperateType.ORDER_AGREE_REFUND;
* 注意:本内容仅限于上海非码科技内部传阅,禁止外泄以及用于其他的商业目
*/
@Service
public class SaleCouponOrderMangerServiceImpl extends SaasOrderMangerServiceImpl {
public class SaleCouponOrderMangerServiceImpl implements OrderManagerService {
@Autowired
private OrderCouponHandle orderCouponHandle;
@Autowired
private SaasOrderHandle saasOrderHandle;
@Autowired
private CouponOnlineClient couponOnlineClient;
private OrderBaseService orderBaseService;
@Autowired
private CouponQueryHandle couponQueryHandle;
private PaymentHandle paymentHandle;
@Autowired
private StockHandle stockHandle;
@Autowired
private OrderSdkService orderSdkService;
@Value("${coupon.partner.id:1983}")
private String couponPartnerId;
/**
* 同意退款
......@@ -89,37 +69,37 @@ public class SaleCouponOrderMangerServiceImpl extends SaasOrderMangerServiceImpl
@Override
public BaseResponse<OrderManagerResponse> orderAgreeRefund(OrderManagerRequest request, OrderBeanV1 orderBean) {
// 退款前先作废券
if (BizTypeEnum.SALE_COUPON.getBizType().equals(orderBean.getBizType())) {
List<String> couponCodes = Optional.ofNullable(orderBean.getOrderSettlementDetailList()).orElse(new ArrayList<>()).stream()
// 216 = 买券订单的券信息
.filter(dto -> Objects.equals(216, dto.getSettlementType()) && StringUtils.isNotBlank(dto.getExternalObjectId()))
.map(OrderSettlementResp::getExternalObjectId)
.collect(Collectors.toList());
// 校验券状态是否已被使用
if (couponQueryHandle.isCouponUsed(request.getPartnerId(), couponCodes)) {
return ResponseUtil.error(ResponseResult.SYSTEM_ERROR.getCode(), "作废优惠券失败,部分券已被使用。");
}
BatchCouponDiscardReq discardReq = new BatchCouponDiscardReq();
discardReq.setCoupons(couponCodes.stream().map(code -> {
return new BatchCouponDiscardReq.CouponInfo(){{
setCode(code);
setMemberId(orderBean.getUserId());
}};
}).collect(Collectors.toList()));
discardReq.setPartnerId(request.getPartnerId());
discardReq.setProviderId(couponPartnerId);
discardReq.setCancelReason("券包订单退款");
CouponBaseResponse<Object> discardResp = couponOnlineClient.batchDiscard(discardReq);
if (!Objects.equals(discardResp.getStatusCode(), 100)) {
return ResponseUtil.error(ResponseResult.SYSTEM_ERROR.getCode(), "作废优惠券失败");
}
BaseResponse response = orderCouponHandle.discardOrderCoupon(request.getPartnerId(), orderBean);
if (!isSuccess(response)) {
return response;
}
// 执行退款
return super.orderAgreeRefund(request, orderBean);
// 支付退款 包括线上小程序付款的订单,订单宝其他支付方式收款(汇来米,收钱吧,现金,其他)老板通发起退款
PayRefundResponse refundResponse = this.payRefundCommon(request, orderBean);
// 退款异常
if (refundResponse.getPayRefundStatus().getCode().compareTo(PayRefundStatus.COMPATIBILITY_STATUS.getCode()) == 0) {
return ResponseUtil.error(refundResponse.getResult());
}
//退款失败终止下面的退款流程
if (refundResponse.getPayRefundStatus().getCode().compareTo(PayRefundStatus.FAIL.getCode()) == 0) {
return ResponseUtil.error(ResponseResult.REFUND_FAIL.getCode(), refundResponse.getMessage());
}
//订单同意退款
saasOrderHandle.refundAgree(request, refundResponse, orderBean);
// 推送pos、微信消息中心
orderBaseService.sendMessage(orderBean, ORDER_AGREE_REFUND, request.getReason());
// 退款冲正发送消息队列(部分退款不进行冲正)
if (!refundResponse.getPartRefund()) {
// todo 可以考虑基于订单回调异步实现
stockHandle.revert(request, orderBean);
}
if (refundResponse.getPayRefundStatus().getCode().compareTo(PayRefundStatus.RUNNING.getCode()) == 0) {
return ResponseUtil.error(ResponseResult.REFUND_FAIL.getCode(), refundResponse.getMessage());
}
return ResponseUtil.success();
}
/**
......@@ -131,34 +111,64 @@ public class SaleCouponOrderMangerServiceImpl extends SaasOrderMangerServiceImpl
*/
@Override
public BaseResponse<OrderManagerResponse> orderRejectRefund(OrderManagerRequest request, OrderBeanV1 orderBean) {
BaseResponse<OrderManagerResponse> response = super.orderRejectRefund(request, orderBean);
//拒绝退款
BaseResponse response = saasOrderHandle.refundReject(request, orderBean);
if (!isSuccess(response)) {
return response;
}
// 推送pos、微信消息中心
orderBaseService.sendMessage(orderBean, OperateType.ORDER_REJECT_REFUND, request.getReason());
// 拒绝后解冻券
try {
if (BizTypeEnum.SALE_COUPON.getBizType().equals(orderBean.getBizType())) {
List<String> couponCodes = Optional.ofNullable(orderBean.getOrderSettlementDetailList()).orElse(new ArrayList<>()).stream()
// 216 = 买券订单的券信息
.filter(dto -> Objects.equals(216, dto.getSettlementType()) && StringUtils.isNotBlank(dto.getExternalObjectId()))
.map(OrderSettlementResp::getExternalObjectId)
.collect(Collectors.toList());
if (!couponCodes.isEmpty()) {
CouponUnFreezeReq unFreezeReq = new CouponUnFreezeReq();
unFreezeReq.setCoupons(couponCodes.stream().map(code -> {
return new CouponUnFreezeReq.CouponInfo(){{
setCode(code);
setMemberId(orderBean.getUserId());
}};
}).collect(Collectors.toList()));
unFreezeReq.setPartnerId(request.getPartnerId());
CouponBaseResponse<Object> unfreezeResp = couponOnlineClient.unfreeze(unFreezeReq);
if (!Objects.equals(unfreezeResp.getStatusCode(), 100)) {
ApiLog.warnMessage("refundReject 解冻券失败:{}", JSONObject.toJSONString(unfreezeResp));
}
}
}
orderCouponHandle.unfreezeOrderCoupon(request.getPartnerId(), orderBean);
} catch (Exception e) {
ApiLog.warnMessage("refundReject 解冻券异常.error orderCode={}, ex:{}", request.getOrderId(), e.getMessage());
}
return response;
return ResponseUtil.success();
}
/**
* 拒单退款、同意退款、取消订单退款
* 小程序点餐订单退款,无单收银退款,订单宝扫码付、其他支付方式收款(汇来米,收钱吧,现金,其他)等有支付流水等退款
*/
private PayRefundResponse payRefundCommon(OrderManagerRequest request, OrderBeanV1 orderBean) {
if (orderBean.getAmount() == 0) {
// 0元订单
PayRefundResponse refundResponse = new PayRefundResponse();
refundResponse.setRefundId(UUID.randomUUID().toString().replaceAll("-", ""));
refundResponse.setPayRefundStatus(PayRefundStatus.SUCCESS);
refundResponse.setMessage(PayRefundStatus.SUCCESS.getDesc());
return refundResponse;
}
PayRefundResponse refundResponse = paymentHandle.getCommonPayRefundResponse(request, orderBean);
// 同意退款退款失败记录到订单售后单
if (orderBean.getAfterSalesOrderResp() != null && Objects.equals(PayRefundStatus.FAIL.getCode(), refundResponse.getPayRefundStatus().getCode())) {
AfterSalesRefundFailReq refundFailReq = this.getAfterSalesRefundFailReq(orderBean,
request.getOperator(),
request.getOperationClient(),
refundResponse.getMessage());
orderSdkService.refundFail(refundFailReq, LogThreadLocal.getTrackingNo());
}
return refundResponse;
}
private AfterSalesRefundFailReq getAfterSalesRefundFailReq(OrderBeanV1 orderBean, String operator, Integer operationClient, String refundFailReason) {
AfterSalesRefundFailReq refundFailReq = new AfterSalesRefundFailReq();
refundFailReq.setOrderCode(orderBean.getOid());
refundFailReq.setPartnerId(orderBean.getCompanyId());
refundFailReq.setRefundFailReason(refundFailReason);
refundFailReq.setAfterSalesCode(orderBean.getAfterSalesOrderResp().getAfterSalesCode());
refundFailReq.setOperationClient(operationClient);
refundFailReq.setOperator(operator);
return refundFailReq;
}
private boolean isSuccess(BaseResponse response) {
return Objects.equals("100", response.getCode());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment