记得上下班打卡 | git大法好,push需谨慎

Commit ee504be7 authored by wangyifan's avatar wangyifan

商品退款功能改造

parent 65b4df16
package com.liquidnet.service.goblin.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data
public class GoblinStoreOrderRefundParam {
@ApiModelProperty(value = "订单id")
@NotNull(message = "订单id不能为空")
private String orderId;
@ApiModelProperty(value = "退款orderSkuId列表[发货后可选;不传为整单退款;发货前强制整单退款]")
private List<String> orderSkuIds;
@ApiModelProperty(value = "退款原因")
private String reason;
@ApiModelProperty(value = "详细描述")
private String describes;
}
......@@ -3,10 +3,8 @@ package com.liquidnet.service.goblin.service.manage;
import com.github.pagehelper.PageInfo;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.vo.GoblinBackOrderDetailsVo;
import com.liquidnet.service.goblin.dto.vo.GoblinBackOrderVo;
import com.liquidnet.service.goblin.dto.vo.GoblinStoreBackOrderListVo;
import com.liquidnet.service.goblin.dto.vo.GoblinStoreOrderListVo;
import com.liquidnet.service.goblin.param.RefundCallbackParam;
import com.liquidnet.service.goblin.param.GoblinStoreOrderRefundParam;
import java.math.BigDecimal;
......@@ -28,5 +26,7 @@ public interface IGoblinStoreBackOrderService {
ResponseDto<Boolean> refusedRefund(String backOrderId);
ResponseDto<Boolean> refundOrder(GoblinStoreOrderRefundParam param);
ResponseDto<Boolean> changeSkuRefund(String backOrderId, BigDecimal refundPrice, String orderSkuId);
}
......@@ -4,12 +4,9 @@ import com.github.pagehelper.PageInfo;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.vo.GoblinBackOrderDetailsVo;
import com.liquidnet.service.goblin.dto.vo.GoblinBackOrderVo;
import com.liquidnet.service.goblin.dto.vo.GoblinStoreBackOrderListVo;
import com.liquidnet.service.goblin.dto.vo.GoblinStoreOrderListVo;
import com.liquidnet.service.goblin.param.RefundCallbackParam;
import com.liquidnet.service.goblin.param.GoblinStoreOrderRefundParam;
import com.liquidnet.service.goblin.service.manage.IGoblinStoreBackOrderService;
import com.liquidnet.service.goblin.service.manage.IGoblinStoreOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
......@@ -83,6 +80,12 @@ public class GoblinStoreBackOrderController {
return goblinStoreBackOrderService.refusedRefund(backOrderId);
}
@ApiOperation(value = "发起退款")
@PostMapping(value = "refund")
public ResponseDto<Boolean> refundOrder(@RequestBody @Valid GoblinStoreOrderRefundParam param) {
return goblinStoreBackOrderService.refundOrder(param);
}
@ApiOperation(value = "修改金额")
@ApiImplicitParams({
@ApiImplicitParam(type = "form", required = true, dataType = "String", name = "backOrderId", value = "订单id"),
......
package com.liquidnet.service.goblin.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Joiner;
import com.liquidnet.commons.lang.util.*;
......@@ -11,20 +9,20 @@ import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.candy.constant.CandyRedisConst;
import com.liquidnet.service.candy.dto.CandyUserCouponBasicDto;
import com.liquidnet.service.dragon.constant.DragonConstant;
import com.liquidnet.service.goblin.constant.GoblinStatusConst;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.goblin.entity.GoblinBackOrder;
import com.liquidnet.service.goblin.entity.GoblinBackOrderLog;
import com.liquidnet.service.goblin.entity.GoblinStoreOrder;
import com.liquidnet.service.goblin.param.GoblinAppOrderRefundParam;
import com.liquidnet.service.goblin.service.IGoblinOrderAppService;
import com.liquidnet.service.goblin.service.impl.helper.GoblinRefundHelper;
import com.liquidnet.service.goblin.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
......@@ -33,7 +31,8 @@ import java.util.List;
import java.util.Objects;
import java.util.stream.IntStream;
import static com.liquidnet.commons.lang.util.DateUtil.*;
import static com.liquidnet.commons.lang.util.DateUtil.DTF_YMD_HMS;
import static com.liquidnet.commons.lang.util.DateUtil.getNowTime;
@Service
......@@ -48,6 +47,8 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
QueueUtils queueUtils;
@Autowired
GoblinOrderUtils orderUtils;
@Autowired
GoblinRefundHelper refundHelper;
@Override
......@@ -245,7 +246,7 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
public ResponseDto<Boolean> applyRefund(GoblinAppOrderRefundParam param) {
LinkedList<String> sqls = CollectionUtil.linkedListString();
sqls.add(SqlMapping.get("goblin_order.user.applyRefund"));
sqls.add(SqlMapping.get("goblin_order.user.applyRefundAuto"));
sqls.add(SqlMapping.get("goblin_order.store.orderStatus"));
sqls.add(SqlMapping.get("goblin_order.store.orderSkuStatus"));
sqls.add(SqlMapping.get("goblin_order.store.refundLog"));
......@@ -261,6 +262,9 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
LocalDateTime now = LocalDateTime.now();
String nowStr = DateUtil.getNowTime();
GoblinStoreOrderVo orderVo = redisUtils.getGoblinOrder(param.getOrderId());
if (orderVo == null) {
return ResponseDto.failure("不可操作");
}
// if (!orderVo.getUserId().equals(uid)) {
// return ResponseDto.failure("无权操作");
// }
......@@ -268,13 +272,13 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
List<String> backOrderIds = redisUtils.getBackOrderByOrderId(param.getOrderId());
for (String backOrderId : backOrderIds) {
GoblinBackOrderVo backOrderVo = redisUtils.getBackOrderVo(backOrderId);
if (!(backOrderVo.getStatus().equals(GoblinStatusConst.Status.ORDER_BACK_STATUS_3.getValue()) || backOrderVo.getStatus().equals(GoblinStatusConst.Status.ORDER_BACK_STATUS_5.getValue()) || backOrderVo.getStatus().equals(GoblinStatusConst.Status.ORDER_BACK_STATUS_9.getValue()))) {
if (backOrderVo != null && !GoblinRefundHelper.isBackOrderFinished(backOrderVo.getStatus())) {
return ResponseDto.failure("申请失败");
}
}
if (!(orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_2.getValue() ||
// orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_3.getValue() ||
orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_3.getValue() ||
orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_4.getValue())) {
return ResponseDto.failure("不可操作");
}
......@@ -308,30 +312,33 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
backOrder.setStatus(GoblinStatusConst.Status.ORDER_BACK_STATUS_1.getValue());
backOrder.setCreatedAt(now);
if (orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_2.getValue()) {//未发货
backOrder.setRealBackPrice(orderVo.getPriceActual());
backOrder.setBackPriceExpress(orderVo.getPriceExpress());
if (StringUtil.isNotBlank(param.getOrderSkuId())) {
return ResponseDto.failure("发货前仅支持整单退款");
}
backOrder.setBackPriceExpress(orderVo.getPriceExpress() == null ? BigDecimal.ZERO : orderVo.getPriceExpress());
backOrder.setReason(param.getReason());
backOrder.setPics(param.getPics());
backOrder.setDescribes(param.getDescribes());
backOrder.setStatus(GoblinStatusConst.Status.ORDER_BACK_STATUS_0.getValue());
backOrder.setAuditAt(now);
backOrder.setSkuIdNums(Joiner.on(",").join(orderVo.getOrderSkuVoIds()));
} else if (orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_4.getValue()) {//已完成
} else if (orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_3.getValue() ||
orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_4.getValue()) {//已发货/已完成
if (StringUtil.isNotBlank(param.getOrderSkuId())) {
GoblinOrderSkuVo orderSkuVo = redisUtils.getGoblinOrderSkuVo(param.getOrderSkuId());
if (orderVo.getPriceRefund().add(orderSkuVo.getSkuPriceActual()).add(orderVo.getPriceExpress()).compareTo(orderVo.getPriceActual()) >= 0) {
backOrder.setRealBackPrice(orderSkuVo.getSkuPriceActual().add(orderVo.getPriceExpress()));
backOrder.setBackPriceExpress(orderVo.getPriceExpress());
} else {
backOrder.setRealBackPrice(orderSkuVo.getSkuPriceActual());
backOrder.setBackPriceExpress(BigDecimal.ZERO);
if (orderSkuVo == null || !orderVo.getOrderId().equals(orderSkuVo.getOrderId())) {
return ResponseDto.failure("不存在");
}
BigDecimal applyingRefundPrice = mongoUtils.getRefundOrderSkuVoPriceBySkuId(orderSkuVo.getOrderSkuId());
backOrder.setRealBackPrice(GoblinRefundHelper.remainRefundPrice(orderSkuVo, applyingRefundPrice));
backOrder.setBackPriceExpress(BigDecimal.ZERO);
} else {
backOrder.setRealBackPrice(orderVo.getPriceActual());
backOrder.setBackPriceExpress(orderVo.getPriceExpress());
backOrder.setBackPriceExpress(BigDecimal.ZERO);
}
backOrder.setReason(param.getReason());
backOrder.setPics(param.getPics());
backOrder.setDescribes(param.getDescribes());
backOrder.setType(param.getRefundType());
backOrder.setType(param.getRefundType() == null ? GoblinStatusConst.Type.BACK_TYPE_1.getValue() : param.getRefundType());
backOrder.setSkuIdNums(param.getOrderSkuId());
} else {
return ResponseDto.failure("不可申请");
......@@ -340,11 +347,12 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
BeanUtils.copyProperties(backOrder, vo);
vo.setCreatedAt(nowStr);
List<GoblinBackOrderSkuVo> orderSkuVoList = ObjectUtil.goblinBackOrderSkuVoArrayList();
BigDecimal skuRefundPrice = BigDecimal.ZERO;
if (orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_2.getValue()) {
//订单状态修改
// orderVo.setStatus(GoblinStatusConst.Status.ORDER_STATUS_61.getValue());
orderStatus.add(new Object[]{
orderVo.getStatus(), orderVo.getZhengzaiStatus(),now,
orderVo.getStatus(), orderVo.getZhengzaiStatus(), now,
orderVo.getOrderId(), now, now
});
for (String orderSkuId : orderVo.getOrderSkuVoIds()) {
......@@ -359,7 +367,13 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
backOrderSkuVo.setSkuPic(orderSkuVo.getSkuImage());
backOrderSkuVo.setSkuName(orderSkuVo.getSkuName());
backOrderSkuVo.setSkuSpecs(orderSkuVo.getSkuSpecs());
backOrderSkuVo.setRefundPrice(orderSkuVo.getSkuPriceActual());
BigDecimal applyingRefundPrice = mongoUtils.getRefundOrderSkuVoPriceBySkuId(orderSkuId);
BigDecimal refundPrice = GoblinRefundHelper.remainRefundPrice(orderSkuVo, applyingRefundPrice);
if (refundPrice.compareTo(BigDecimal.ZERO) <= 0) {
return ResponseDto.failure("退款价格超过商品可退价格");
}
skuRefundPrice = skuRefundPrice.add(refundPrice);
backOrderSkuVo.setRefundPrice(refundPrice);
backOrderSkuVo.setCreatedAt(nowStr);
orderSkuVoList.add(backOrderSkuVo);
backOrderLog(orderVo, orderSkuVo, now);
......@@ -372,9 +386,13 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
orderSkuVo.getOrderSkuId(), now, now
});
}
} else if (orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_4.getValue()) {
if (param.getOrderSkuId() != null) {
} else if (orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_3.getValue() ||
orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_4.getValue()) {
if (StringUtil.isNotBlank(param.getOrderSkuId())) {
GoblinOrderSkuVo orderSkuVo = redisUtils.getGoblinOrderSkuVo(param.getOrderSkuId());
if (orderSkuVo == null || !orderVo.getOrderId().equals(orderSkuVo.getOrderId())) {
return ResponseDto.failure("不存在");
}
if (Objects.equals(orderSkuVo.getSkuType(), 2)) {// 券类商品-校验发放的券是否已使用
// 券类商品默认一个商品对应一个券,下单只可购买一张
String ucKey = CandyRedisConst.BASIC_USER_COUPON.concat(orderVo.getUserId());
......@@ -403,7 +421,13 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
backOrderSkuVo.setSkuId(orderSkuVo.getSkuId());
backOrderSkuVo.setSkuPic(orderSkuVo.getSkuImage());
backOrderSkuVo.setSkuName(orderSkuVo.getSkuName());
backOrderSkuVo.setRefundPrice(orderSkuVo.getSkuPriceActual());
BigDecimal applyingRefundPrice = mongoUtils.getRefundOrderSkuVoPriceBySkuId(param.getOrderSkuId());
BigDecimal refundPrice = GoblinRefundHelper.remainRefundPrice(orderSkuVo, applyingRefundPrice);
if (refundPrice.compareTo(BigDecimal.ZERO) <= 0) {
return ResponseDto.failure("退款价格超过商品可退价格");
}
skuRefundPrice = skuRefundPrice.add(refundPrice);
backOrderSkuVo.setRefundPrice(refundPrice);
backOrderSkuVo.setSkuSpecs(orderSkuVo.getSkuSpecs());
backOrderSkuVo.setCreatedAt(nowStr);
backOrderSkuVo.setSkuType(orderSkuVo.getSkuType());
......@@ -448,7 +472,13 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
backOrderSkuVo.setSkuName(orderSkuVo.getSkuName());
backOrderSkuVo.setSkuSpecs(orderSkuVo.getSkuSpecs());
backOrderSkuVo.setSkuPic(orderSkuVo.getSkuImage());
backOrderSkuVo.setRefundPrice(orderSkuVo.getSkuPriceActual());
BigDecimal applyingRefundPrice = mongoUtils.getRefundOrderSkuVoPriceBySkuId(orderSkuId);
BigDecimal refundPrice = GoblinRefundHelper.remainRefundPrice(orderSkuVo, applyingRefundPrice);
if (refundPrice.compareTo(BigDecimal.ZERO) <= 0) {
return ResponseDto.failure("退款价格超过商品可退价格");
}
skuRefundPrice = skuRefundPrice.add(refundPrice);
backOrderSkuVo.setRefundPrice(refundPrice);
backOrderSkuVo.setCreatedAt(nowStr);
backOrderSkuVo.setSkuType(orderSkuVo.getSkuType());
orderSkuVoList.add(backOrderSkuVo);
......@@ -466,12 +496,43 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
} else {
return ResponseDto.failure("不可申请");
}
if (skuRefundPrice.compareTo(BigDecimal.ZERO) <= 0) {
return ResponseDto.failure("退款价格超过商品可退价格");
}
if (StringUtil.isBlank(backOrder.getSkuIdNums())) {
List<String> refundOrderSkuIds = new LinkedList<>();
for (GoblinBackOrderSkuVo backOrderSkuVo : orderSkuVoList) {
refundOrderSkuIds.add(backOrderSkuVo.getOrderSkuId());
}
backOrder.setSkuIdNums(Joiner.on(",").join(refundOrderSkuIds));
}
if (orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_2.getValue()) {
backOrder.setRealBackPrice(GoblinRefundHelper.beforeShipRefundPrice(skuRefundPrice, backOrder.getBackPriceExpress()));
} else {
backOrder.setRealBackPrice(skuRefundPrice);
backOrder.setBackPriceExpress(BigDecimal.ZERO);
}
vo.setRealBackPrice(backOrder.getRealBackPrice());
vo.setBackPriceExpress(backOrder.getBackPriceExpress());
vo.setStatus(backOrder.getStatus());
vo.setAuditAt(backOrder.getAuditAt() == null ? null : nowStr);
vo.setBackOrderSkuVos(orderSkuVoList);
//添加日志
GoblinBackOrderLog backOrderLog = initBackLog(param.getOrderId(), uid, now);
backOrderLog.setStatus(GoblinStatusConst.Status.ORDER_LOG_STATUS_21.getValue());
backOrderLog.setOperationType(GoblinStatusConst.Type.OPERATION_TYPE_1.getValue());
backOrderLog.setMessage("用户发起发起:" + JsonUtils.toJson(param));
if (orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_2.getValue()) {
String returnString = refundHelper.initRefund(orderVo, backOrder.getRealBackPrice(), backOrder.getBackCode());
if (!refundHelper.isRefundSuccess(returnString)) {
String message = refundHelper.getRefundMessage(returnString);
backOrder.setStatus(GoblinStatusConst.Status.ORDER_BACK_STATUS_10.getValue());
backOrder.setErrorReason("失败原因:" + message);
vo.setStatus(backOrder.getStatus());
vo.setErrorReason(backOrder.getErrorReason());
log.error("REFUND DATA = " + returnString);
}
}
//redis
redisUtils.setBackOrderVo(backOrder.getBackOrderId(), vo);
redisUtils.setGoblinOrder(orderVo.getOrderId(), orderVo);
......@@ -485,7 +546,8 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
backOrder.getOrderCode(), backOrder.getStoreId(), backOrder.getUserId(),
backOrder.getSkuIdNums(), backOrder.getType(), backOrder.getReason(),
backOrder.getDescribes(), backOrder.getRealBackPrice(), backOrder.getBackPriceExpress(), backOrder.getStatus(),
backOrder.getLogisCompanyName(), backOrder.getMailNo(), backOrder.getPics(), backOrder.getCreatedAt()
backOrder.getLogisCompanyName(), backOrder.getMailNo(), backOrder.getPics(), backOrder.getCreatedAt(),
backOrder.getAuditAt(), backOrder.getErrorReason()
});
//添加日志
refundLog.add(new Object[]{
......@@ -493,6 +555,14 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
backOrderLog.getMessage(), backOrderLog.getOperationName(), backOrderLog.getStatus(), now
});
queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_USER_ORDER_OPERA.getKey(), SqlMapping.gets(sqls, applyRefund, orderStatus, orderSkuStatus, refundLog, updateCandyUserCouponObjs));
if (orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_2.getValue()) {
if (backOrder.getStatus() == GoblinStatusConst.Status.ORDER_BACK_STATUS_10.getValue()) {
return ResponseDto.failure("退款失败:" + backOrder.getErrorReason());
}
if (DragonConstant.REFUND_TYPE_MICROPAY_ALIPAY.equals(orderVo.getPaymentType())) {
refundHelper.alipayCallBack(orderVo, backOrder.getBackCode());
}
}
return ResponseDto.success();
}
......@@ -789,10 +859,11 @@ public class GoblinOrderAppServiceImpl implements IGoblinOrderAppService {
} catch (Exception e) {
e.printStackTrace();
}
} else if (orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_4.getValue()) {
} else if (orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_3.getValue()
|| orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_4.getValue()) {
if (StringUtil.isBlank(orderVo.getDeliveryTime())) {
canRefundTimeDateTime = LocalDateTime.parse(orderVo.getPayTime(), DTF_YMD_HMS).plusDays(7);
}else {
} else {
canRefundTimeDateTime = LocalDateTime.parse(orderVo.getDeliveryTime(), DTF_YMD_HMS).plusDays(7);
}
}
......
package com.liquidnet.service.goblin.service.impl.helper;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.HttpUtil;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.goblin.dto.vo.GoblinBackOrderSkuVo;
import com.liquidnet.service.goblin.dto.vo.GoblinOrderSkuVo;
import com.liquidnet.service.goblin.dto.vo.GoblinStoreOrderVo;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import java.math.BigDecimal;
import java.util.HashMap;
@Component
@Slf4j
public class GoblinRefundHelper {
@Autowired
private GoblinRedisUtils redisUtils;
@Value("${liquidnet.service.order.url-pay.goblinRefundUrl}")
private String synUrl;
@Value("${liquidnet.service.dragon.urls.refundApply}")
private String refundApply;
@Value("${liquidnet.service.order.url-pay.goblinRefundUrl}")
private String goblinRefundUrl;
@Value("${liquidnet.service.dragon.urls.refundResult}")
private String refundApplyCallBack;
public static BigDecimal remainRefundPrice(GoblinOrderSkuVo orderSkuVo, BigDecimal applyingRefundPrice) {
BigDecimal priceActual = nullToZero(orderSkuVo.getSkuPriceActual());
BigDecimal priceRefund = nullToZero(orderSkuVo.getPriceRefund());
BigDecimal applying = nullToZero(applyingRefundPrice);
BigDecimal remain = priceActual.subtract(priceRefund).subtract(applying);
return remain.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : remain;
}
public static BigDecimal beforeShipRefundPrice(BigDecimal skuRefundPrice, BigDecimal priceExpress) {
return nullToZero(skuRefundPrice).add(nullToZero(priceExpress));
}
public static GoblinBackOrderSkuVo buildBackOrderSkuVo(GoblinOrderSkuVo orderSkuVo, BigDecimal refundPrice, String nowStr) {
GoblinBackOrderSkuVo backOrderSkuVo = GoblinBackOrderSkuVo.getNew();
backOrderSkuVo.setOrderSkuId(orderSkuVo.getOrderSkuId());
backOrderSkuVo.setSpuId(orderSkuVo.getSpuId());
backOrderSkuVo.setSpuName(orderSkuVo.getSpuName());
backOrderSkuVo.setSkuId(orderSkuVo.getSkuId());
backOrderSkuVo.setSkuName(orderSkuVo.getSkuName());
backOrderSkuVo.setRefundPrice(refundPrice);
backOrderSkuVo.setSkuSpecs(orderSkuVo.getSkuSpecs());
backOrderSkuVo.setCreatedAt(nowStr);
backOrderSkuVo.setSkuPic(orderSkuVo.getSkuImage());
backOrderSkuVo.setSkuType(orderSkuVo.getSkuType());
return backOrderSkuVo;
}
public static boolean isBackOrderFinished(Integer status) {
return status != null && (status == 2 || status == 3 || status == 5 || status == 8 || status == 9 || status == 10 || status == 11);
}
public static boolean isUnshippedSku(GoblinOrderSkuVo orderSkuVo) {
return orderSkuVo != null && orderSkuVo.getStatus() == 2;
}
public static boolean isShippedSku(GoblinOrderSkuVo orderSkuVo) {
if (orderSkuVo == null) {
return false;
}
return orderSkuVo.getStatus() == 3 || orderSkuVo.getStatus() == 4;
}
public String initRefund(GoblinStoreOrderVo orderVo, BigDecimal price, String refundCode) {
MultiValueMap<String, String> params = CollectionUtil.linkedMultiValueMapStringString();
params.add("code", orderVo.getPayCode());
params.add("notifyUrl", synUrl);
params.add("orderCode", orderVo.getMasterOrderCode());
params.add("orderRefundCode", refundCode);
params.add("paymentId", orderVo.getPaymentId());
params.add("paymentType", orderVo.getPaymentType());
params.add("price", String.valueOf(price));
params.add("priceTotal", String.valueOf(getMasterOrderActualPrice(orderVo)));
params.add("reason", "按需退款");
MultiValueMap<String, String> headers = CollectionUtil.linkedMultiValueMapStringString();
headers.add("Accept", "application/json;charset=UTF-8");
String returnString = HttpUtil.post(refundApply, params, headers);
log.debug("REFUND DATA = " + returnString);
return returnString;
}
public String alipayCallBack(GoblinStoreOrderVo orderVo, String refundCode) {
MultiValueMap<String, String> params = CollectionUtil.linkedMultiValueMapStringString();
params.add("callBackUrl", goblinRefundUrl);
params.add("orderCode", orderVo.getMasterOrderCode());
params.add("orderRefundCode", refundCode);
params.add("paymentId", orderVo.getPaymentId());
MultiValueMap<String, String> headers = CollectionUtil.linkedMultiValueMapStringString();
headers.add("Accept", "application/json;charset=UTF-8");
log.debug("REFUND CALLBACK params = " + params);
String returnString = HttpUtil.post(refundApplyCallBack, params, headers);
log.debug("REFUND CALLBACK DATA = " + returnString);
return returnString;
}
public boolean isRefundSuccess(String returnString) {
HashMap hashMapResult = JsonUtils.fromJson(returnString, HashMap.class);
Boolean success = (Boolean) hashMapResult.get("success");
return Boolean.TRUE.equals(success);
}
public String getRefundMessage(String returnString) {
HashMap hashMapResult = JsonUtils.fromJson(returnString, HashMap.class);
String message = (String) hashMapResult.get("message");
return message == null ? "" : message;
}
private BigDecimal getMasterOrderActualPrice(GoblinStoreOrderVo orderVo) {
BigDecimal totalPrice = BigDecimal.ZERO;
String[] orderIds = redisUtils.getMasterCode(orderVo.getMasterOrderCode());
if (orderIds == null || orderIds.length == 0) {
return nullToZero(orderVo.getPriceActual());
}
for (String orderId : orderIds) {
GoblinStoreOrderVo vo = redisUtils.getGoblinOrder(orderId);
if (vo != null) {
totalPrice = totalPrice.add(nullToZero(vo.getPriceActual()));
}
}
return totalPrice.compareTo(BigDecimal.ZERO) > 0 ? totalPrice : nullToZero(orderVo.getPriceActual());
}
private static BigDecimal nullToZero(BigDecimal value) {
return value == null ? BigDecimal.ZERO : value;
}
}
......@@ -10,7 +10,10 @@ import com.liquidnet.service.candy.dto.CandyUserCouponBasicDto;
import com.liquidnet.service.dragon.constant.DragonConstant;
import com.liquidnet.service.goblin.constant.GoblinStatusConst;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.goblin.entity.GoblinBackOrder;
import com.liquidnet.service.goblin.entity.GoblinBackOrderLog;
import com.liquidnet.service.goblin.param.GoblinStoreOrderRefundParam;
import com.liquidnet.service.goblin.service.impl.helper.GoblinRefundHelper;
import com.liquidnet.service.goblin.service.manage.IGoblinStoreBackOrderService;
import com.liquidnet.service.goblin.util.GoblinMongoUtils;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
......@@ -19,14 +22,11 @@ import com.liquidnet.service.goblin.util.QueueUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.*;
import java.util.stream.IntStream;
@Service
......@@ -39,14 +39,8 @@ public class GoblinStoreBackOrderServiceImpl implements IGoblinStoreBackOrderSer
GoblinMongoUtils mongoUtils;
@Autowired
QueueUtils queueUtils;
@Value("${liquidnet.service.order.url-pay.goblinRefundUrl}")
private String synUrl;
@Value("${liquidnet.service.dragon.urls.refundApply}")
private String refundApply;
@Value("${liquidnet.service.order.url-pay.goblinRefundUrl}")
private String goblinRefundUrl;
@Value("${liquidnet.service.dragon.urls.refundResult}")
private String refundApplyCallBack;
@Autowired
GoblinRefundHelper refundHelper;
@Override
public ResponseDto<PageInfo<GoblinStoreBackOrderListVo>> orderBackList(Integer page, String orderBackCode, Integer type, String cst, String cet, String orderCode, String spuName, Integer status) {
......@@ -163,9 +157,19 @@ public class GoblinStoreBackOrderServiceImpl implements IGoblinStoreBackOrderSer
return ResponseDto.failure("无法查看");
}
GoblinBackOrderVo backOrderVo = redisUtils.getBackOrderVo(backOrderId);
if(backOrderVo.getStatus().equals(GoblinStatusConst.Status.ORDER_BACK_STATUS_0.getValue())){
if (backOrderVo == null) {
return ResponseDto.failure("不存在");
}
GoblinStoreOrderVo orderVo = redisUtils.getGoblinOrder(backOrderVo.getOrderId());
if (orderVo == null || !storeInfoVo.getStoreId().equals(orderVo.getStoreId())) {
return ResponseDto.failure("无法查看");
}
if (backOrderVo.getStatus().equals(GoblinStatusConst.Status.ORDER_BACK_STATUS_0.getValue())) {
return ResponseDto.failure("已经发起");
}
if (!backOrderVo.getStatus().equals(GoblinStatusConst.Status.ORDER_BACK_STATUS_1.getValue())) {
return ResponseDto.failure("不可操作");
}
backOrderVo.setStatus(GoblinStatusConst.Status.ORDER_BACK_STATUS_0.getValue());
backOrderVo.setAuditAt(nowStr);
//添加日志
......@@ -174,11 +178,9 @@ public class GoblinStoreBackOrderServiceImpl implements IGoblinStoreBackOrderSer
backOrderLog.setOperationType(GoblinStatusConst.Type.OPERATION_TYPE_2.getValue());
backOrderLog.setMessage("商户退款-同意退款:backOrderId=[" + backOrderId + "]");
//调用退款
GoblinStoreOrderVo orderVo = redisUtils.getGoblinOrder(backOrderVo.getOrderId());
String returnString = initRefund(orderVo, backOrderVo.getRealBackPrice(), backOrderVo.getBackCode());
HashMap hashMapResult = JsonUtils.fromJson(returnString, HashMap.class);
Boolean success = (Boolean) hashMapResult.get("success");
String message = (String) hashMapResult.get("message");
String returnString = refundHelper.initRefund(orderVo, backOrderVo.getRealBackPrice(), backOrderVo.getBackCode());
Boolean success = refundHelper.isRefundSuccess(returnString);
String message = refundHelper.getRefundMessage(returnString);
if (!success) {
backOrderVo.setStatus(GoblinStatusConst.Status.ORDER_BACK_STATUS_10.getValue());
backOrderVo.setErrorReason("失败原因:" + message);
......@@ -205,8 +207,8 @@ public class GoblinStoreBackOrderServiceImpl implements IGoblinStoreBackOrderSer
)
);
if (success) {
if (orderVo.getPaymentType().equals(DragonConstant.REFUND_TYPE_MICROPAY_ALIPAY)) {
alipayCallBack(orderVo, backOrderVo.getBackCode());
if (DragonConstant.REFUND_TYPE_MICROPAY_ALIPAY.equals(orderVo.getPaymentType())) {
refundHelper.alipayCallBack(orderVo, backOrderVo.getBackCode());
}
return ResponseDto.success();
}
......@@ -280,6 +282,40 @@ public class GoblinStoreBackOrderServiceImpl implements IGoblinStoreBackOrderSer
return ResponseDto.success();
}
@Override
public ResponseDto<Boolean> refundOrder(GoblinStoreOrderRefundParam param) {
String uid = CurrentUtil.getCurrentUid();
LocalDateTime now = LocalDateTime.now();
String nowStr = DateUtil.getNowTime();
GoblinStoreInfoVo storeInfoVo = redisUtils.getStoreInfoVoByUid(uid);
if (storeInfoVo == null) {
return ResponseDto.failure("无法查看");
}
GoblinStoreOrderVo orderVo = redisUtils.getGoblinOrder(param.getOrderId());
if (orderVo == null || !storeInfoVo.getStoreId().equals(orderVo.getStoreId())) {
return ResponseDto.failure("无法查看");
}
if (!orderVo.getMixId().isEmpty()) {
return ResponseDto.failure("组合购商品暂不支持退款");
}
if (hasProcessingBackOrder(orderVo.getOrderId())) {
return ResponseDto.failure("已有退款处理中");
}
List<GoblinOrderSkuVo> orderSkuVos = getOrderSkuVos(orderVo);
boolean beforeShip = orderSkuVos.stream().allMatch(GoblinRefundHelper::isUnshippedSku);
boolean canRefund = beforeShip || orderSkuVos.stream().anyMatch(GoblinRefundHelper::isShippedSku);
if (!canRefund) {
return ResponseDto.failure("不可退款");
}
List<GoblinOrderSkuVo> refundSkuVos = beforeShip ? orderSkuVos : getSelectedOrderSkuVos(orderVo, orderSkuVos, param.getOrderSkuIds());
if (refundSkuVos.isEmpty()) {
return ResponseDto.failure("请选择退款商品");
}
return createStoreRefundOrder(orderVo, refundSkuVos, beforeShip, param, uid, now, nowStr);
}
@Override
public ResponseDto<Boolean> changeSkuRefund(String backOrderId, BigDecimal refundPrice, String orderSkuId) {
String uid = CurrentUtil.getCurrentUid();
......@@ -326,6 +362,171 @@ public class GoblinStoreBackOrderServiceImpl implements IGoblinStoreBackOrderSer
return ResponseDto.success();
}
private boolean hasProcessingBackOrder(String orderId) {
List<String> backOrderIds = redisUtils.getBackOrderByOrderId(orderId);
for (String backOrderId : backOrderIds) {
GoblinBackOrderVo backOrderVo = redisUtils.getBackOrderVo(backOrderId);
if (backOrderVo != null && !GoblinRefundHelper.isBackOrderFinished(backOrderVo.getStatus())) {
return true;
}
}
return false;
}
private List<GoblinOrderSkuVo> getOrderSkuVos(GoblinStoreOrderVo orderVo) {
List<GoblinOrderSkuVo> orderSkuVos = new ArrayList<>();
for (String orderSkuId : orderVo.getOrderSkuVoIds()) {
GoblinOrderSkuVo orderSkuVo = redisUtils.getGoblinOrderSkuVo(orderSkuId);
if (orderSkuVo != null) {
orderSkuVos.add(orderSkuVo);
}
}
return orderSkuVos;
}
private List<GoblinOrderSkuVo> getSelectedOrderSkuVos(GoblinStoreOrderVo orderVo, List<GoblinOrderSkuVo> orderSkuVos, List<String> orderSkuIds) {
if (orderSkuIds == null || orderSkuIds.isEmpty()) {
return orderSkuVos;
}
Set<String> orderSkuIdSet = new HashSet<>(orderVo.getOrderSkuVoIds());
Set<String> selectedIdSet = new HashSet<>(orderSkuIds);
List<GoblinOrderSkuVo> selectedSkuVos = new ArrayList<>();
for (String orderSkuId : selectedIdSet) {
if (!orderSkuIdSet.contains(orderSkuId)) {
return new ArrayList<>();
}
}
for (GoblinOrderSkuVo orderSkuVo : orderSkuVos) {
if (selectedIdSet.contains(orderSkuVo.getOrderSkuId())) {
selectedSkuVos.add(orderSkuVo);
}
}
return selectedSkuVos;
}
private ResponseDto<Boolean> createStoreRefundOrder(GoblinStoreOrderVo orderVo, List<GoblinOrderSkuVo> refundSkuVos,
boolean beforeShip, GoblinStoreOrderRefundParam param,
String uid, LocalDateTime now, String nowStr) {
BigDecimal skuRefundPrice = BigDecimal.ZERO;
List<String> orderSkuIds = new ArrayList<>();
List<GoblinBackOrderSkuVo> backOrderSkuVos = ObjectUtil.goblinBackOrderSkuVoArrayList();
boolean selectAll = param.getOrderSkuIds() == null || param.getOrderSkuIds().isEmpty();
for (GoblinOrderSkuVo orderSkuVo : refundSkuVos) {
BigDecimal applyingRefundPrice = mongoUtils.getRefundOrderSkuVoPriceBySkuId(orderSkuVo.getOrderSkuId());
BigDecimal refundPrice = GoblinRefundHelper.remainRefundPrice(orderSkuVo, applyingRefundPrice);
if (refundPrice.compareTo(BigDecimal.ZERO) <= 0) {
if (!beforeShip && selectAll) {
continue;
}
return ResponseDto.failure("退款价格超过商品可退价格");
}
skuRefundPrice = skuRefundPrice.add(refundPrice);
orderSkuIds.add(orderSkuVo.getOrderSkuId());
backOrderSkuVos.add(GoblinRefundHelper.buildBackOrderSkuVo(orderSkuVo, refundPrice, nowStr));
}
if (backOrderSkuVos.isEmpty()) {
return ResponseDto.failure("退款价格超过商品可退价格");
}
BigDecimal backPriceExpress = beforeShip && orderVo.getPriceExpress() != null ? orderVo.getPriceExpress() : BigDecimal.ZERO;
BigDecimal realBackPrice = beforeShip ? GoblinRefundHelper.beforeShipRefundPrice(skuRefundPrice, backPriceExpress) : skuRefundPrice;
int backOrderStatus = beforeShip ? GoblinStatusConst.Status.ORDER_BACK_STATUS_0.getValue() : GoblinStatusConst.Status.ORDER_BACK_STATUS_1.getValue();
String refundCode = IDGenerator.storeRefundCode(orderVo.getMasterOrderCode());
GoblinBackOrder backOrder = GoblinBackOrder.getNew();
backOrder.setBackOrderId(IDGenerator.nextTimeId2());
backOrder.setBackCode(refundCode);
backOrder.setOrderId(orderVo.getOrderId());
backOrder.setOrderCode(orderVo.getOrderCode());
backOrder.setStoreId(orderVo.getStoreId());
backOrder.setUserId(orderVo.getUserId());
backOrder.setSkuIdNums(String.join(",", orderSkuIds));
backOrder.setType(GoblinStatusConst.Type.BACK_TYPE_1.getValue());
backOrder.setReason(StringUtil.isBlank(param.getReason()) ? GoblinStatusConst.Type.BACK_REASON_TYPE_8.getDesc() : param.getReason());
backOrder.setDescribes(StringUtil.isBlank(param.getDescribes()) ? "店铺退款" : param.getDescribes());
backOrder.setRealBackPrice(realBackPrice);
backOrder.setBackPriceExpress(backPriceExpress);
backOrder.setStatus(backOrderStatus);
backOrder.setCreatedAt(now);
if (beforeShip) {
backOrder.setAuditAt(now);
}
GoblinBackOrderVo backOrderVo = GoblinBackOrderVo.getNew();
BeanUtils.copyProperties(backOrder, backOrderVo);
backOrderVo.setCreatedAt(nowStr);
backOrderVo.setAuditAt(beforeShip ? nowStr : null);
backOrderVo.setBackPriceExpress(backPriceExpress);
backOrderVo.setBackOrderSkuVos(backOrderSkuVos);
GoblinBackOrderLog backOrderLog = initBackLog(backOrder.getBackOrderId(), uid, now);
backOrderLog.setStatus(beforeShip ? GoblinStatusConst.Status.ORDER_LOG_STATUS_22.getValue() : GoblinStatusConst.Status.ORDER_LOG_STATUS_20.getValue());
backOrderLog.setOperationType(GoblinStatusConst.Type.OPERATION_TYPE_2.getValue());
backOrderLog.setMessage("商户发起退款:orderSkuIds=[" + backOrder.getSkuIdNums() + "],refundPrice=[" + realBackPrice + "],[refundCode=" + refundCode + "]");
if (beforeShip) {
String returnString = refundHelper.initRefund(orderVo, realBackPrice, refundCode);
if (!refundHelper.isRefundSuccess(returnString)) {
backOrderVo.setStatus(GoblinStatusConst.Status.ORDER_BACK_STATUS_10.getValue());
backOrderVo.setErrorReason("失败原因:" + refundHelper.getRefundMessage(returnString));
backOrder.setStatus(backOrderVo.getStatus());
backOrder.setErrorReason(backOrderVo.getErrorReason());
log.error("REFUND DATA = " + returnString);
}
}
saveStoreRefundOrder(orderVo, refundSkuVos, backOrder, backOrderVo, backOrderLog, now);
if (beforeShip && GoblinStatusConst.Status.ORDER_BACK_STATUS_0.getValue() == backOrderVo.getStatus()
&& DragonConstant.REFUND_TYPE_MICROPAY_ALIPAY.equals(orderVo.getPaymentType())) {
refundHelper.alipayCallBack(orderVo, refundCode);
}
return backOrderVo.getStatus() == GoblinStatusConst.Status.ORDER_BACK_STATUS_10.getValue()
? ResponseDto.failure("退款失败:" + backOrderVo.getErrorReason())
: ResponseDto.success();
}
private void saveStoreRefundOrder(GoblinStoreOrderVo orderVo, List<GoblinOrderSkuVo> refundSkuVos,
GoblinBackOrder backOrder, GoblinBackOrderVo backOrderVo,
GoblinBackOrderLog backOrderLog, LocalDateTime now) {
LinkedList<String> sqls = CollectionUtil.linkedListString();
sqls.add(SqlMapping.get("goblin_order.store.backOrderWithExpress"));
sqls.add(SqlMapping.get("goblin_order.store.orderSkuStatus"));
sqls.add(SqlMapping.get("goblin_order.store.refundLog"));
LinkedList<Object[]> backOrderSql = CollectionUtil.linkedListObjectArr();
LinkedList<Object[]> orderSkuStatusSql = CollectionUtil.linkedListObjectArr();
LinkedList<Object[]> refundLogSql = CollectionUtil.linkedListObjectArr();
backOrderSql.add(new Object[]{
backOrder.getBackOrderId(), backOrder.getBackCode(), backOrder.getOrderId(),
backOrder.getOrderCode(), backOrder.getStoreId(), backOrder.getUserId(),
backOrder.getSkuIdNums(), backOrder.getType(), backOrder.getReason(),
backOrder.getDescribes(), backOrder.getRealBackPrice(), backOrder.getBackPriceExpress(),
backOrder.getStatus(), backOrder.getPics(), backOrder.getCreatedAt(),
backOrder.getAuditAt(), backOrder.getErrorReason()
});
for (GoblinOrderSkuVo orderSkuVo : refundSkuVos) {
orderSkuVo.setStatus(GoblinStatusConst.Status.ORDER_STATUS_61.getValue());
redisUtils.setGoblinOrderSku(orderSkuVo.getOrderSkuId(), orderSkuVo);
mongoUtils.updateGoblinOrderSkuVo(orderSkuVo.getOrderSkuId(), orderSkuVo);
orderSkuStatusSql.add(new Object[]{
orderSkuVo.getStatus(), now,
orderSkuVo.getOrderSkuId(), now, now
});
}
refundLogSql.add(new Object[]{
backOrderLog.getBackOrderLogId(), backOrderLog.getBackOrderId(), backOrderLog.getOperationType(),
backOrderLog.getMessage(), backOrderLog.getOperationName(), backOrderLog.getStatus(), now
});
redisUtils.setBackOrderVo(backOrderVo.getBackOrderId(), backOrderVo);
redisUtils.addBackOrderByOrderId(orderVo.getOrderId(), backOrderVo.getBackOrderId());
mongoUtils.insertGoblinBackOrderVo(backOrderVo);
queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_STORE_ORDER_OPERA.getKey(),
SqlMapping.gets(sqls, backOrderSql, orderSkuStatusSql, refundLogSql));
}
private GoblinBackOrderLog initBackLog(String orderId, String uid, LocalDateTime now) {
GoblinBackOrderLog log = GoblinBackOrderLog.getNew();
log.setBackOrderId(orderId);
......@@ -334,42 +535,4 @@ public class GoblinStoreBackOrderServiceImpl implements IGoblinStoreBackOrderSer
log.setCreatedAt(now);
return log;
}
private String initRefund(GoblinStoreOrderVo orderVo, BigDecimal price, String refundCode) {
MultiValueMap<String, String> params = CollectionUtil.linkedMultiValueMapStringString();
params.add("code", orderVo.getPayCode());
params.add("notifyUrl", synUrl);
params.add("orderCode", orderVo.getMasterOrderCode());
params.add("orderRefundCode", refundCode);
params.add("paymentId", orderVo.getPaymentId());
params.add("paymentType", orderVo.getPaymentType());
params.add("price", String.valueOf(price));
BigDecimal totalPrice = BigDecimal.ZERO;
String[] orderIds = redisUtils.getMasterCode(orderVo.getMasterOrderCode());
for (String orderId : orderIds) {
GoblinStoreOrderVo vo = redisUtils.getGoblinOrder(orderId);
totalPrice = totalPrice.add(vo.getPriceActual());
}
params.add("priceTotal", String.valueOf(totalPrice));
params.add("reason", "按需退款");
MultiValueMap<String, String> headers = CollectionUtil.linkedMultiValueMapStringString();
headers.add("Accept", "application/json;charset=UTF-8");
String returnString = HttpUtil.post(refundApply, params, headers);
log.debug("REFUND DATA = " + returnString);
return returnString;
}
private String alipayCallBack(GoblinStoreOrderVo orderVo, String refundCode) {
MultiValueMap<String, String> params = CollectionUtil.linkedMultiValueMapStringString();
params.add("callBackUrl", goblinRefundUrl);
params.add("orderCode", orderVo.getMasterOrderCode());
params.add("orderRefundCode", refundCode);
params.add("paymentId", orderVo.getPaymentId());
MultiValueMap<String, String> headers = CollectionUtil.linkedMultiValueMapStringString();
headers.add("Accept", "application/json;charset=UTF-8");
log.debug("REFUND CALLBACK params = " + params);
String returnString = HttpUtil.post(refundApplyCallBack, params, headers);
log.debug("REFUND CALLBACK DATA = " + returnString);
return returnString;
}
}
......@@ -1711,6 +1711,21 @@ public class GoblinMongoUtils {
return refundPrice;
}
// 获取指定子单已成功或进行中的退款金额;新退款链路需要精确到当前 orderSkuId,避免多子单退款单被重复累计。
public BigDecimal getRefundOrderSkuVoPriceBySkuId(String orderSkuId) {
BigDecimal refundPrice = BigDecimal.ZERO;
List<GoblinBackOrderVo> backOrderVos = mongoTemplate.find(Query.query(Criteria.where("backOrderSkuVos.orderSkuId").is(orderSkuId).and("status").nin(3, 5, 9, 10, 11)),
GoblinBackOrderVo.class, GoblinBackOrderVo.class.getSimpleName());
for (GoblinBackOrderVo vo : backOrderVos) {
for (GoblinBackOrderSkuVo orderSkuVo : vo.getBackOrderSkuVos()) {
if (orderSkuId.equals(orderSkuVo.getOrderSkuId())) {
refundPrice = refundPrice.add(orderSkuVo.getRefundPrice());
}
}
}
return refundPrice;
}
//根据spuId查询活动id
public List<String> getMarketIdListBySpuId(String spuId) {
Query query = Query.query(Criteria.where("marketId").ne(null).and("spuId").regex(spuId.concat(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue()).concat(".*")));
......
......@@ -129,6 +129,7 @@ goblin_order.store.log=INSERT INTO goblin_order_operation_log (`order_log_id`,`o
goblin_order.store.refundLog=INSERT INTO goblin_back_order_log (`back_order_log_id`,`back_order_id`,`operation_type`,`message`,`operation_name`,`status`,`created_at`) VALUES(?,?,?,?,?,?,?)
goblin_order.store.orderExpressPrice=UPDATE goblin_store_order SET price_total =? , price_modify = ? ,price_voucher = ? , price_actual = ? ,price_express = ? , updated_at = ? WHERE order_id = ? and (updated_at <= ? or created_at = ? or updated_at is null)
goblin_order.store.backOrder=INSERT INTO goblin_back_order (`back_order_id`,`back_code`,`order_id`,`order_code`,`store_id`,`user_id`,`sku_id_nums`,`type`,`reason`,`describes`,`real_back_price`,`status`,`created_at`,`audit_at`,`error_reason`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
goblin_order.store.backOrderWithExpress=INSERT INTO goblin_back_order (`back_order_id`,`back_code`,`order_id`,`order_code`,`store_id`,`user_id`,`sku_id_nums`,`type`,`reason`,`describes`,`real_back_price`,`back_price_express`,`status`,`pics`,`created_at`,`audit_at`,`error_reason`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
goblin_order.store.changeExpress=UPDATE goblin_back_order SET real_back_price = ? ,back_price_express = ? updated_at = ? WHERE back_order_id = ? and (updated_at <= ? or created_at = ? or updated_at is null)
goblin_order.store.changeSku=UPDATE goblin_back_order SET real_back_price = ? , updated_at = ? WHERE back_order_id = ? and (updated_at <= ? or created_at = ? or updated_at is null)
goblin_order.store.backOrderStatus=UPDATE goblin_back_order SET status = ? , refuse_at=?,refuse_size=?,updated_at = ? WHERE back_order_id = ? and (updated_at <= ? or created_at = ? or updated_at is null)
......@@ -137,6 +138,7 @@ goblin_order.store.orderStatus.time=UPDATE goblin_store_order SET status = ? ,zh
goblin_order.store.applyRefund=UPDATE goblin_back_order SET status = ? ,reason=?,audit_at=?, updated_at = ? WHERE back_order_id = ? and (updated_at <= ? or created_at = ? or updated_at is null)
#---- \u7528\u6237\u8BA2\u5355\u64CD\u4F5C
goblin_order.user.applyRefund=INSERT INTO goblin_back_order (`back_order_id`,`back_code`,`order_id`,`order_code`,`store_id`,`user_id`,`sku_id_nums`,`type`,`reason`,`describes`,`real_back_price`,`back_price_express`,`status`,`logis_company_name`,`mail_no`,`pics`,`created_at`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
goblin_order.user.applyRefundAuto=INSERT INTO goblin_back_order (`back_order_id`,`back_code`,`order_id`,`order_code`,`store_id`,`user_id`,`sku_id_nums`,`type`,`reason`,`describes`,`real_back_price`,`back_price_express`,`status`,`logis_company_name`,`mail_no`,`pics`,`created_at`,`audit_at`,`error_reason`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
goblin_order.user.againRefund=UPDATE goblin_back_order SET status = ? , describes = ? , pics = ? , reason = ? , type = ?, updated_at=? where back_order_id=?
#---- \u8D2D\u7269\u8F66\u64CD\u4F5C
goblin_shop.cart.delete=UPDATE goblin_shopping_cart set del_tag=? where user_id=? and sku_id=?
......
package com.liquidnet.service.goblin.test;
import com.liquidnet.service.goblin.dto.vo.GoblinOrderSkuVo;
import com.liquidnet.service.goblin.service.impl.helper.GoblinRefundHelper;
import org.junit.Assert;
import org.junit.Test;
import java.math.BigDecimal;
public class GoblinRefundHelperTest {
@Test
public void remainRefundPriceSubtractsRefundedAndApplyingAmount() {
GoblinOrderSkuVo skuVo = new GoblinOrderSkuVo();
skuVo.setSkuPriceActual(new BigDecimal("100.00"));
skuVo.setPriceRefund(new BigDecimal("30.00"));
BigDecimal remain = GoblinRefundHelper.remainRefundPrice(skuVo, new BigDecimal("20.00"));
Assert.assertEquals(0, new BigDecimal("50.00").compareTo(remain));
}
@Test
public void remainRefundPriceNeverReturnsNegativeAmount() {
GoblinOrderSkuVo skuVo = new GoblinOrderSkuVo();
skuVo.setSkuPriceActual(new BigDecimal("10.00"));
skuVo.setPriceRefund(new BigDecimal("8.00"));
BigDecimal remain = GoblinRefundHelper.remainRefundPrice(skuVo, new BigDecimal("5.00"));
Assert.assertEquals(0, BigDecimal.ZERO.compareTo(remain));
}
@Test
public void beforeShipRefundIncludesExpressFee() {
BigDecimal refundPrice = GoblinRefundHelper.beforeShipRefundPrice(new BigDecimal("80.00"), new BigDecimal("12.00"));
Assert.assertEquals(0, new BigDecimal("92.00").compareTo(refundPrice));
}
}
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