退款 扣除库存校验
This commit is contained in:
@@ -2,7 +2,6 @@ package com.czg.mq;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.exceptions.ExceptionUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.czg.config.RabbitConstants;
|
||||
import com.czg.order.entity.MqLog;
|
||||
@@ -71,10 +70,10 @@ public class OrderMqListener {
|
||||
public void orderStockRecover(String orderId) {
|
||||
long startTime = DateUtil.date().getTime();
|
||||
log.info("接收到订单取消恢复库存消息:{}", orderId);
|
||||
MqLog mqLog = new MqLog().setQueue(RabbitConstants.Queue.ORDER_CANCEL_QUEUE).setMsg(orderId).setType("orderStockRecover").setPlat("java.order").setCreateTime(DateUtil.date().toLocalDateTime());
|
||||
try {
|
||||
orderInfoRpcService.orderCancelCallback(Long.valueOf(orderId));
|
||||
} catch (Exception e) {
|
||||
MqLog mqLog = new MqLog().setQueue(RabbitConstants.Queue.ORDER_CANCEL_QUEUE).setMsg(orderId).setType("orderStockRecover").setPlat("java.order").setCreateTime(DateUtil.date().toLocalDateTime());
|
||||
log.error("订单取消恢复库存失败", e);
|
||||
String errorInfo = ExceptionUtil.stacktraceToString(e);
|
||||
mqLog.setErrInfo(errorInfo);
|
||||
@@ -88,11 +87,10 @@ public class OrderMqListener {
|
||||
public void orderStockReturn(String jsonObjStr) {
|
||||
long startTime = DateUtil.date().getTime();
|
||||
log.info("接收到订单退款返还库存消息:{}", jsonObjStr);
|
||||
MqLog mqLog = new MqLog().setQueue(RabbitConstants.Queue.ORDER_REFUND_QUEUE).setMsg(jsonObjStr).setType("orderStockReturn").setPlat("java.order").setCreateTime(DateUtil.date().toLocalDateTime());
|
||||
try {
|
||||
JSONObject data = JSON.parseObject(jsonObjStr);
|
||||
orderInfoRpcService.orderRefundCallback(data);
|
||||
orderInfoRpcService.orderRefundCallback(JSONObject.parseObject(jsonObjStr));
|
||||
} catch (Exception e) {
|
||||
MqLog mqLog = new MqLog().setQueue(RabbitConstants.Queue.ORDER_REFUND_QUEUE).setMsg(jsonObjStr).setType("orderStockReturn").setPlat("java.order").setCreateTime(DateUtil.date().toLocalDateTime());
|
||||
log.error("订单退款返还库存失败", e);
|
||||
String errorInfo = ExceptionUtil.stacktraceToString(e);
|
||||
mqLog.setErrInfo(errorInfo);
|
||||
|
||||
@@ -54,6 +54,10 @@ public class OrderInfoRefundDTO implements Serializable {
|
||||
* 是否打印退菜/退款票
|
||||
*/
|
||||
private boolean print;
|
||||
/**
|
||||
* 是否退库存
|
||||
*/
|
||||
private boolean refundStock;
|
||||
|
||||
private String refundReason;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.czg.order.service;
|
||||
|
||||
import cn.hutool.core.exceptions.ValidateException;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.czg.account.entity.ShopInfo;
|
||||
import com.czg.exception.CzgException;
|
||||
import com.czg.exception.OrderCancelException;
|
||||
import com.czg.exception.OrderValidateException;
|
||||
@@ -21,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 订单表 服务层。
|
||||
@@ -73,4 +75,9 @@ public interface OrderInfoCustomService {
|
||||
|
||||
Boolean upOrderDetail(Long shopId, OrderDetailStatusDTO detailStatusDTO);
|
||||
|
||||
|
||||
/**
|
||||
* 退单库存问题
|
||||
*/
|
||||
void refundStock(ShopInfo shopInfo, Long orderId, Map<Long,BigDecimal> products, boolean refundStock);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.czg.product.service;
|
||||
|
||||
import com.czg.product.vo.ProductStockVO;
|
||||
import com.czg.product.vo.ProductVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 商品RPC远程调用服务接口
|
||||
@@ -20,24 +20,23 @@ public interface ProductRpcService {
|
||||
* @param orderId 订单ID
|
||||
* @param dataList 库存扣减数据
|
||||
*/
|
||||
void paySuccessSubtractStock(Long shopId, Long orderId, List<Map<String, Object>> dataList);
|
||||
void paySuccessSubtractStock(Long shopId, Long orderId, List<ProductStockVO> dataList);
|
||||
|
||||
/**
|
||||
* 订单取消后恢复库存
|
||||
*
|
||||
* @param shopId 店铺id
|
||||
* @param orderId 订单ID
|
||||
* @param dataList 库存恢复数据
|
||||
*/
|
||||
void orderCancelRecoverStock(Long shopId, Long orderId, List<Map<String, Object>> dataList);
|
||||
void orderCancelRecoverStock(Long shopId, Long orderId, List<ProductStockVO> list);
|
||||
|
||||
/**
|
||||
* 订单退菜或退款后回退库存
|
||||
* @param shopId 店铺id
|
||||
* @param orderId 订单ID
|
||||
* @param dataList 库存恢复数据
|
||||
* @param list 库存恢复数据
|
||||
*/
|
||||
void orderRefundReturnStock(Long shopId, Long orderId, List<Map<String, Object>> dataList);
|
||||
void orderRefundReturnStock(Long shopId, Long orderId, List<ProductStockVO> list);
|
||||
|
||||
List<ProductVO> listAndLowPrice(Long shopId, List<Long> productIds);
|
||||
|
||||
|
||||
@@ -43,8 +43,12 @@ import com.czg.order.enums.PayEnums;
|
||||
import com.czg.order.service.*;
|
||||
import com.czg.order.vo.*;
|
||||
import com.czg.pay.PayNotifyRespDTO;
|
||||
import com.czg.product.entity.Product;
|
||||
import com.czg.product.entity.ShopProdCategory;
|
||||
import com.czg.product.service.ProductRpcService;
|
||||
import com.czg.product.service.ProductService;
|
||||
import com.czg.product.service.ShopProdCategoryService;
|
||||
import com.czg.product.vo.ProductStockVO;
|
||||
import com.czg.resp.CzgResult;
|
||||
import com.czg.sa.StpKit;
|
||||
import com.czg.service.RedisService;
|
||||
@@ -107,6 +111,8 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService {
|
||||
@DubboReference
|
||||
private ProductService productService;
|
||||
@DubboReference
|
||||
private ShopProdCategoryService shopProdCategoryService;
|
||||
@DubboReference
|
||||
private ProductRpcService productRpcService;
|
||||
@DubboReference
|
||||
private ShopInfoService shopInfoService;
|
||||
@@ -1696,13 +1702,13 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService {
|
||||
return true;
|
||||
}
|
||||
List<OrderDetail> details = orderDetailService.list(QueryWrapper.create().eq(OrderDetail::getOrderId, orderId).eq(OrderDetail::getPlaceNum, placeNum));
|
||||
List<Map<String, Object>> dataList = new ArrayList<>();
|
||||
List<ProductStockVO> listStock = new ArrayList<>();
|
||||
for (OrderDetail detail : details) {
|
||||
dataList.add(Map.of("productId", detail.getProductId(), "number", NumberUtil.sub(detail.getNum(), detail.getReturnNum())));
|
||||
listStock.add(new ProductStockVO(detail.getProductId(), NumberUtil.sub(detail.getNum(), detail.getReturnNum())));
|
||||
}
|
||||
orderDetailService.remove(new QueryWrapper().eq(OrderDetail::getOrderId, orderId).eq(OrderDetail::getPlaceNum, placeNum));
|
||||
if (CollUtil.isNotEmpty(dataList)) {
|
||||
productRpcService.orderCancelRecoverStock(shopId, orderId, dataList);
|
||||
if (CollUtil.isNotEmpty(listStock)) {
|
||||
productRpcService.orderCancelRecoverStock(shopId, orderId, listStock);
|
||||
}
|
||||
List<OrderDetail> list = orderDetailService.queryChain().eq(OrderDetail::getOrderId, orderId).eq(OrderDetail::getShopId, shopId).list();
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
@@ -1828,4 +1834,48 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService {
|
||||
rabbitPublisher.sendOrderDetailStatusMsg(shopId.toString(), "bc");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 退单库存问题
|
||||
* 1退菜退库存 2仅退菜不退库存 3每次询问-退菜后弹窗提示1
|
||||
*/
|
||||
@Override
|
||||
public void refundStock(ShopInfo shopInfo, Long orderId, Map<Long, BigDecimal> products, boolean refundStock) {
|
||||
List<Product> list = productService.list(new QueryWrapper().select(Product::getId, Product::getCategoryId, Product::getRefundMode)
|
||||
.eq(Product::getShopId, shopInfo.getId())
|
||||
.in(Product::getId, products.keySet()));
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return;
|
||||
}
|
||||
List<ProductStockVO> resultProduct = new ArrayList<>();
|
||||
HashMap<Long, Integer> categoryMap = new HashMap<>();
|
||||
for (Product product : list) {
|
||||
Integer refundMode;
|
||||
if (shopInfo.getRefundMode().equals(1)) {
|
||||
//分类
|
||||
if (!categoryMap.containsKey(product.getCategoryId())) {
|
||||
refundMode = shopProdCategoryService.getOneAs(new QueryWrapper().select(ShopProdCategory::getRefundMode)
|
||||
.eq(ShopProdCategory::getShopId, shopInfo.getId()).eq(ShopProdCategory::getId, product.getCategoryId()), Integer.class);
|
||||
categoryMap.put(product.getCategoryId(), refundMode);
|
||||
} else {
|
||||
refundMode = categoryMap.get(product.getCategoryId());
|
||||
}
|
||||
} else if (shopInfo.getRefundMode().equals(2)) {
|
||||
//单商品
|
||||
refundMode = product.getRefundMode();
|
||||
} else {
|
||||
log.error("退菜模式错误 店铺{},退款模式{},商品Id{}分类Id{}", shopInfo.getShopName(), shopInfo.getRefundMode(), product.getId(), product.getCategoryId());
|
||||
throw new CzgException("退菜模式错误");
|
||||
}
|
||||
if (refundMode.equals(1)) {
|
||||
resultProduct.add(new ProductStockVO(product.getId(), products.get(product.getId())));
|
||||
} else if (refundMode.equals(3) && refundStock) {
|
||||
resultProduct.add(new ProductStockVO(product.getId(), products.get(product.getId())));
|
||||
}
|
||||
}
|
||||
if (CollUtil.isNotEmpty(resultProduct)) {
|
||||
rabbitPublisher.sendOrderRefundMsg(JSONObject.toJSONString(Map.of("orderId", orderId, "returnProList", resultProduct)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.czg.order.entity.OrderDetail;
|
||||
import com.czg.order.entity.OrderInfo;
|
||||
import com.czg.order.service.OrderInfoRpcService;
|
||||
import com.czg.product.service.ProductRpcService;
|
||||
import com.czg.product.vo.ProductStockVO;
|
||||
import com.czg.service.market.mapper.OrderInfoMapper;
|
||||
import com.czg.service.order.mapper.OrderDetailMapper;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
@@ -95,12 +96,12 @@ public class OrderInfoRpcServiceImpl implements OrderInfoRpcService {
|
||||
}
|
||||
Long shopId = orderInfo.getShopId();
|
||||
// 封装扣减库存数据
|
||||
List<Map<String, Object>> dataList = new ArrayList<>();
|
||||
List<ProductStockVO> dataList = new ArrayList<>();
|
||||
for (OrderDetail orderDetail : detailList) {
|
||||
Long productId = orderDetail.getProductId();
|
||||
BigDecimal num = orderDetail.getNum();
|
||||
BigDecimal refundNum = orderDetail.getRefundNum();
|
||||
dataList.add(Map.of("productId", productId, "number", NumberUtil.sub(num, refundNum)));
|
||||
dataList.add(new ProductStockVO(productId, NumberUtil.sub(num, refundNum)));
|
||||
}
|
||||
try {
|
||||
// 调用商品服务扣减库存
|
||||
@@ -127,12 +128,12 @@ public class OrderInfoRpcServiceImpl implements OrderInfoRpcService {
|
||||
throw new CzgException("该订单下不存在商品");
|
||||
}
|
||||
// 封装扣减库存数据
|
||||
List<Map<String, Object>> dataList = new ArrayList<>();
|
||||
List<ProductStockVO> dataList = new ArrayList<>();
|
||||
for (OrderDetail orderDetail : detailList) {
|
||||
Long productId = orderDetail.getProductId();
|
||||
BigDecimal num = orderDetail.getNum();
|
||||
BigDecimal refundNum = orderDetail.getRefundNum();
|
||||
dataList.add(Map.of("productId", productId, "number", NumberUtil.sub(num, refundNum)));
|
||||
dataList.add(new ProductStockVO(productId, NumberUtil.sub(num, refundNum)));
|
||||
}
|
||||
try {
|
||||
// 调用商品服务扣减库存
|
||||
@@ -145,7 +146,6 @@ public class OrderInfoRpcServiceImpl implements OrderInfoRpcService {
|
||||
|
||||
@Override
|
||||
public void orderRefundCallback(JSONObject data) {
|
||||
log.info(">>>>>>>>>>>>>>>>>:入参:{}", data.toJSONString());
|
||||
Long orderId = data.getLong("orderId");
|
||||
// 订单取消后商品库存恢复,耗材恢复,流水记录
|
||||
OrderInfo orderInfo = orderInfoMapper.selectOneById(orderId);
|
||||
@@ -157,13 +157,7 @@ public class OrderInfoRpcServiceImpl implements OrderInfoRpcService {
|
||||
if (CollUtil.isEmpty(detailList)) {
|
||||
throw new CzgException("该订单下不存在商品");
|
||||
}
|
||||
JSONObject obj = data.getJSONObject("returnProMap");
|
||||
Set<String> keys = obj.keySet();
|
||||
// 封装扣减库存数据
|
||||
List<Map<String, Object>> dataList = new ArrayList<>();
|
||||
for (String key : keys) {
|
||||
dataList.add(Map.of("productId", key, "number", obj.getBigDecimal(key)));
|
||||
}
|
||||
List<ProductStockVO> dataList = data.getList("returnProList", ProductStockVO.class);
|
||||
try {
|
||||
// 调用商品服务回退库存
|
||||
productRpcService.orderRefundReturnStock(orderInfo.getShopId(), orderId, dataList);
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
package com.czg.service.order.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.crypto.digest.MD5;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.czg.PayCst;
|
||||
import com.czg.account.dto.shopuser.ShopUserMoneyEditDTO;
|
||||
import com.czg.account.entity.ShopInfo;
|
||||
@@ -383,7 +381,7 @@ public class OrderPayServiceImpl implements OrderPayService {
|
||||
}
|
||||
boolean isFirstRefund = orderInfo.getRefundAmount().compareTo(BigDecimal.ZERO) == 0;
|
||||
ShopInfo shopInfo = shopInfoService.getById(orderInfo.getShopId());
|
||||
Map<String, BigDecimal> returnProMap = new HashMap<>();
|
||||
Map<Long,BigDecimal> productStockMap = new HashMap<>();
|
||||
boolean isPay = true;
|
||||
String refPayOrderNo = "REFO" + IdUtil.getSnowflakeNextId();
|
||||
if (orderInfo.getStatus().equals(OrderStatusEnums.UNPAID.getCode())) {
|
||||
@@ -443,7 +441,7 @@ public class OrderPayServiceImpl implements OrderPayService {
|
||||
}
|
||||
orderDetailService.updateById(orderDetail);
|
||||
if (orderDetail.getProductId() != null && orderDetail.getProductId() > 0) {
|
||||
returnProMap.put(Convert.toStr(orderDetail.getProductId()), refundDetail.getNum());
|
||||
productStockMap.put(orderDetail.getProductId(), refundDetail.getNum());
|
||||
}
|
||||
}
|
||||
long count = orderDetailService.count(QueryWrapper.create().eq(OrderDetail::getOrderId, orderInfo.getId())
|
||||
@@ -461,14 +459,14 @@ public class OrderPayServiceImpl implements OrderPayService {
|
||||
for (OrderDetail orderDetail : orderDetails) {
|
||||
if (isPay) {
|
||||
if (orderDetail.getProductId() != null && orderDetail.getProductId() > 0) {
|
||||
returnProMap.put(Convert.toStr(orderDetail.getProductId()), orderDetail.getNum().subtract(orderDetail.getReturnNum()).subtract(orderDetail.getRefundNum()));
|
||||
productStockMap.put(orderDetail.getProductId(), orderDetail.getNum().subtract(orderDetail.getReturnNum()).subtract(orderDetail.getRefundNum()));
|
||||
}
|
||||
orderDetail.setReturnAmount(orderDetail.getPayAmount());
|
||||
orderDetail.setRefundNum(orderDetail.getNum().subtract(orderDetail.getReturnNum()));
|
||||
orderDetail.setStatus(OrderStatusEnums.REFUND.getCode());
|
||||
} else {
|
||||
if (orderDetail.getProductId() != null && orderDetail.getProductId() > 0) {
|
||||
returnProMap.put(Convert.toStr(orderDetail.getProductId()), orderDetail.getNum().subtract(orderDetail.getReturnNum()));
|
||||
productStockMap.put(orderDetail.getProductId(), orderDetail.getNum().subtract(orderDetail.getReturnNum()));
|
||||
}
|
||||
orderDetail.setReturnNum(orderDetail.getNum());
|
||||
orderDetail.setStatus(OrderStatusEnums.CANCELLED.getCode());
|
||||
@@ -519,9 +517,8 @@ public class OrderPayServiceImpl implements OrderPayService {
|
||||
, param.getRefundReason(), orderInfo.getRefundType(), orderInfo, param.getRefundDetails());
|
||||
}
|
||||
//退款返还库存
|
||||
if (!returnProMap.isEmpty()) {
|
||||
//TODO 退款 商品退不退的 校验
|
||||
rabbitPublisher.sendOrderRefundMsg(JSONObject.toJSONString(Map.of("orderId", orderInfo.getId(), "returnProMap", returnProMap)));
|
||||
if (!productStockMap.isEmpty()) {
|
||||
orderInfoCustomService.refundStock(shopInfo, orderInfo.getId(), productStockMap, param.isRefundStock());
|
||||
}
|
||||
refundOrderAfter(orderInfo.getId(), orderInfo.getShopId(), orderInfo.getUserId(), orderInfo.getOrderNo(),
|
||||
orderInfo.getPointsNum(), isFirstRefund, orderInfo.getStatus().equals(OrderStatusEnums.REFUND.getCode()));
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.czg.service.product.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.czg.product.enums.InOutItemEnum;
|
||||
import com.czg.product.enums.InOutTypeEnum;
|
||||
import com.czg.product.service.ProductRpcService;
|
||||
@@ -16,7 +14,6 @@ import org.apache.dubbo.config.annotation.DubboService;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.czg.constant.CacheConstant.ADMIN_CLIENT_PRODUCT_LIST;
|
||||
|
||||
@@ -39,32 +36,20 @@ public class ProductRpcServiceImpl implements ProductRpcService {
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void paySuccessSubtractStock(Long shopId, Long orderId, List<Map<String, Object>> dataList) {
|
||||
List<ProductStockVO> list = BeanUtil.copyToList(dataList, ProductStockVO.class);
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return;
|
||||
}
|
||||
public void paySuccessSubtractStock(Long shopId, Long orderId, List<ProductStockVO> list) {
|
||||
productService.consStockByProduct(shopId, InOutTypeEnum.OUT, InOutItemEnum.ORDER_OUT, list, orderId, "订单消费");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void orderCancelRecoverStock(Long shopId, Long orderId, List<Map<String, Object>> dataList) {
|
||||
List<ProductStockVO> list = BeanUtil.copyToList(dataList, ProductStockVO.class);
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return;
|
||||
}
|
||||
public void orderCancelRecoverStock(Long shopId, Long orderId, List<ProductStockVO> list) {
|
||||
productService.consStockByProduct(shopId, InOutTypeEnum.IN, InOutItemEnum.ORDER_IN, list, orderId, "订单取消/过期返还库存");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void orderRefundReturnStock(Long shopId, Long orderId, List<Map<String, Object>> dataList) {
|
||||
List<ProductStockVO> list = BeanUtil.copyToList(dataList, ProductStockVO.class);
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return;
|
||||
}
|
||||
public void orderRefundReturnStock(Long shopId, Long orderId, List<ProductStockVO> list) {
|
||||
productService.consStockByProduct(shopId, InOutTypeEnum.IN, InOutItemEnum.ORDER_IN, list, orderId, "订单退菜/退款返还库存");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user