Commit c264d53b by 杨浩

配送员 - 退货单 - 确认

parent 9280ccd4
...@@ -95,6 +95,7 @@ ErrorCode PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED = new ErrorCode(1_030_101_00 ...@@ -95,6 +95,7 @@ ErrorCode PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED = new ErrorCode(1_030_101_00
ErrorCode SALE_RETURN_NOT_APPROVE = new ErrorCode(1_020_203_006, "销售退货单未审核,无法操作"); ErrorCode SALE_RETURN_NOT_APPROVE = new ErrorCode(1_020_203_006, "销售退货单未审核,无法操作");
ErrorCode SALE_RETURN_FAIL_REFUND_PRICE_EXCEED = new ErrorCode(1_020_203_007, "退款金额({})超过销售退货单总金额({})"); ErrorCode SALE_RETURN_FAIL_REFUND_PRICE_EXCEED = new ErrorCode(1_020_203_007, "退款金额({})超过销售退货单总金额({})");
ErrorCode SALE_RETURN_PROCESS_FAIL_EXISTS_REFUND = new ErrorCode(1_020_203_008, "反审核失败,已存在对应的退款单"); ErrorCode SALE_RETURN_PROCESS_FAIL_EXISTS_REFUND = new ErrorCode(1_020_203_008, "反审核失败,已存在对应的退款单");
ErrorCode SALERETURN_ERROR_ORDER_ITEM = new ErrorCode(1_020_203_009, "订单子项异常");
// ========== ERP 仓库 1-030-400-000 ========== // ========== ERP 仓库 1-030-400-000 ==========
ErrorCode WAREHOUSE_NOT_EXISTS = new ErrorCode(1_030_400_000, "仓库不存在"); ErrorCode WAREHOUSE_NOT_EXISTS = new ErrorCode(1_030_400_000, "仓库不存在");
......
...@@ -5,6 +5,7 @@ import cn.iocoder.foodnexus.module.erp.controller.admin.sale.vo.returns.ErpSaleR ...@@ -5,6 +5,7 @@ import cn.iocoder.foodnexus.module.erp.controller.admin.sale.vo.returns.ErpSaleR
import cn.iocoder.foodnexus.module.erp.controller.admin.sale.vo.returns.ErpSaleReturnSaveReqVO; import cn.iocoder.foodnexus.module.erp.controller.admin.sale.vo.returns.ErpSaleReturnSaveReqVO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.sale.ErpSaleReturnDO; import cn.iocoder.foodnexus.module.erp.dal.dataobject.sale.ErpSaleReturnDO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.sale.ErpSaleReturnItemDO; import cn.iocoder.foodnexus.module.erp.dal.dataobject.sale.ErpSaleReturnItemDO;
import cn.iocoder.foodnexus.module.order.dto.DeliveryOrderUpdateReqVO;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import java.math.BigDecimal; import java.math.BigDecimal;
...@@ -108,4 +109,6 @@ public interface ErpSaleReturnService { ...@@ -108,4 +109,6 @@ public interface ErpSaleReturnService {
void accept(Long id, Long deliveryStaffId); void accept(Long id, Long deliveryStaffId);
void delivery(Long id, Long deliveryStaffId); void delivery(Long id, Long deliveryStaffId);
void arrival(DeliveryOrderUpdateReqVO reqVO, Long aLong);
} }
\ No newline at end of file
...@@ -8,6 +8,7 @@ import cn.iocoder.foodnexus.framework.common.util.CommonUtil; ...@@ -8,6 +8,7 @@ import cn.iocoder.foodnexus.framework.common.util.CommonUtil;
import cn.iocoder.foodnexus.framework.common.util.object.BeanUtils; import cn.iocoder.foodnexus.framework.common.util.object.BeanUtils;
import cn.iocoder.foodnexus.framework.redis.utils.RedisUtils; import cn.iocoder.foodnexus.framework.redis.utils.RedisUtils;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.purchase.ErpPurchaseReturnDO; import cn.iocoder.foodnexus.module.erp.dal.dataobject.purchase.ErpPurchaseReturnDO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.sale.ErpSaleOutDO;
import cn.iocoder.foodnexus.module.erp.dal.mysql.purchase.ErpPurchaseReturnMapper; import cn.iocoder.foodnexus.module.erp.dal.mysql.purchase.ErpPurchaseReturnMapper;
import cn.iocoder.foodnexus.module.erp.dal.mysql.sale.ErpSaleOrderMapper; import cn.iocoder.foodnexus.module.erp.dal.mysql.sale.ErpSaleOrderMapper;
import cn.iocoder.foodnexus.module.erp.enums.SaleOrderPickUpStatus; import cn.iocoder.foodnexus.module.erp.enums.SaleOrderPickUpStatus;
...@@ -30,6 +31,9 @@ import cn.iocoder.foodnexus.module.erp.service.finance.ErpAccountService; ...@@ -30,6 +31,9 @@ import cn.iocoder.foodnexus.module.erp.service.finance.ErpAccountService;
import cn.iocoder.foodnexus.module.erp.service.purchase.ErpPurchaseReturnService; import cn.iocoder.foodnexus.module.erp.service.purchase.ErpPurchaseReturnService;
import cn.iocoder.foodnexus.module.erp.service.stock.ErpStockRecordService; import cn.iocoder.foodnexus.module.erp.service.stock.ErpStockRecordService;
import cn.iocoder.foodnexus.module.erp.service.stock.bo.ErpStockRecordCreateReqBO; import cn.iocoder.foodnexus.module.erp.service.stock.bo.ErpStockRecordCreateReqBO;
import cn.iocoder.foodnexus.module.order.api.CustomerOrderApi;
import cn.iocoder.foodnexus.module.order.dto.CustomerOrderItemDTO;
import cn.iocoder.foodnexus.module.order.dto.DeliveryOrderUpdateReqVO;
import cn.iocoder.foodnexus.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.foodnexus.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.foodnexus.module.product.service.spu.ProductSpuService; import cn.iocoder.foodnexus.module.product.service.spu.ProductSpuService;
import cn.iocoder.foodnexus.module.system.api.user.AdminUserApi; import cn.iocoder.foodnexus.module.system.api.user.AdminUserApi;
...@@ -97,6 +101,9 @@ public class ErpSaleReturnServiceImpl implements ErpSaleReturnService { ...@@ -97,6 +101,9 @@ public class ErpSaleReturnServiceImpl implements ErpSaleReturnService {
@Autowired @Autowired
private ErpPurchaseOrderItemMapper purchaseOrderItemMapper; private ErpPurchaseOrderItemMapper purchaseOrderItemMapper;
@Autowired
private CustomerOrderApi customerOrderApi;
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Long createSaleReturn(ErpSaleReturnSaveReqVO createReqVO) { public Long createSaleReturn(ErpSaleReturnSaveReqVO createReqVO) {
...@@ -214,14 +221,15 @@ public class ErpSaleReturnServiceImpl implements ErpSaleReturnService { ...@@ -214,14 +221,15 @@ public class ErpSaleReturnServiceImpl implements ErpSaleReturnService {
// 3. 变更库存 // 3. 变更库存
List<ErpSaleReturnItemDO> saleReturnItems = saleReturnItemMapper.selectListByReturnId(id); List<ErpSaleReturnItemDO> saleReturnItems = saleReturnItemMapper.selectListByReturnId(id);
Integer bizType = approve ? ErpStockRecordBizTypeEnum.SALE_RETURN.getType() // TODO 退款确认后才进行库存变更
/*Integer bizType = approve ? ErpStockRecordBizTypeEnum.SALE_RETURN.getType()
: ErpStockRecordBizTypeEnum.SALE_RETURN_CANCEL.getType(); : ErpStockRecordBizTypeEnum.SALE_RETURN_CANCEL.getType();
saleReturnItems.forEach(saleReturnItem -> { saleReturnItems.forEach(saleReturnItem -> {
Integer count = approve ? saleReturnItem.getCount() : - saleReturnItem.getCount(); Integer count = approve ? saleReturnItem.getCount() : - saleReturnItem.getCount();
stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO( stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
saleReturnItem.getProductId(), saleReturnItem.getWarehouseId(), BigDecimal.valueOf(count), saleReturnItem.getProductId(), saleReturnItem.getWarehouseId(), BigDecimal.valueOf(count),
bizType, saleReturnItem.getReturnId(), saleReturnItem.getId(), saleReturn.getNo())); bizType, saleReturnItem.getReturnId(), saleReturnItem.getId(), saleReturn.getNo()));
}); });*/
// 将订单根据供应商拆分成采购退货单 // 将订单根据供应商拆分成采购退货单
Map<Long, List<ErpSaleReturnItemDO>> returnItemMap = CommonUtil.listConvertListMap(saleReturnItems, ErpSaleReturnItemDO::getSupplierId); Map<Long, List<ErpSaleReturnItemDO>> returnItemMap = CommonUtil.listConvertListMap(saleReturnItems, ErpSaleReturnItemDO::getSupplierId);
...@@ -473,4 +481,72 @@ public class ErpSaleReturnServiceImpl implements ErpSaleReturnService { ...@@ -473,4 +481,72 @@ public class ErpSaleReturnServiceImpl implements ErpSaleReturnService {
} }
} }
@Override
@Transactional(rollbackFor = Exception.class)
public void arrival(DeliveryOrderUpdateReqVO reqVO, Long deliveryStaffId) {
Long orderId = reqVO.getId();
ErpSaleReturnDO saleReturn = saleReturnMapper.selectOne(Wrappers.<ErpSaleReturnDO>lambdaQuery()
.eq(ErpSaleReturnDO::getCustomerOrderId, orderId)
.last("LIMIT 1"));
if (CommonUtil.isEmpty(saleReturn)) {
throw exception(SALE_RETURN_NO_EXISTS);
}
ErpSaleOrderDO saleOrder = saleOrderService.validateSaleOrder(saleReturn.getOrderId());
if (!SaleOrderPickUpStatus.RETURNS_STAFF_ALREADY.equals(saleOrder.getPickUpStatus())) {
throw exception(SALE_ORDER_PICKUP_STATUS_FAIL);
}
String key = String.format(SALE_ORDER_LOCK, saleOrder.getId());
RedisUtils.tryLockRds(key);
try {
// 更新退货单和销售订单的状态
saleOrderMapper.update(Wrappers.<ErpSaleOrderDO>lambdaUpdate()
.set(ErpSaleOrderDO::getPickUpStatus, RETURNS_FINISH.getType())
.eq(ErpSaleOrderDO::getId, saleOrder.getId()));
saleReturnMapper.update(Wrappers.<ErpSaleReturnDO>lambdaUpdate()
.set(ErpSaleReturnDO::getDeliveryTime, LocalDateTime.now())
.set(ErpSaleReturnDO::getReturnsStatus, RETURNS_FINISH.getType())
.eq(ErpSaleReturnDO::getId, saleReturn.getId()));
purchaseReturnMapper.update(Wrappers.<ErpPurchaseReturnDO>lambdaUpdate()
.set(ErpPurchaseReturnDO::getReturnsStatus, RETURNS_FINISH.getType())
.set(ErpPurchaseReturnDO::getSaleOrderId, saleOrder.getId()));
List<CustomerOrderItemDTO> customerORderItems = customerOrderApi.queryItemsByOrderId(orderId);
Map<Long, CustomerOrderItemDTO> customerOrderItemMap = CommonUtil.listConvertMap(customerORderItems, CustomerOrderItemDTO::getId);
List<CustomerOrderItemDTO> updateItems = new ArrayList<>();
for (DeliveryOrderUpdateReqVO.DeliveryOrderUpdateItems item : reqVO.getOrderItems()) {
Long orderItemId = item.getId();
Integer returnsCount = item.getSignedQuantity();
if (!customerOrderItemMap.containsKey(orderItemId)) {
throw exception(SALERETURN_ERROR_ORDER_ITEM);
}
CustomerOrderItemDTO orderItem = customerOrderItemMap.get(orderItemId);
CustomerOrderItemDTO updateItem = new CustomerOrderItemDTO();
updateItem.setId(orderItem.getId());
updateItem.setReturnsQuantity(returnsCount);
updateItem.setReturnsTotal(returnsCount * orderItem.getOrderItemPrice());
updateItems.add(updateItem);
}
customerOrderApi.updateItems(updateItems);
// 3. 变更库存
List<ErpSaleReturnItemDO> saleReturnItems = saleReturnItemMapper.selectListByReturnId(saleReturn.getId());
Integer bizType = ErpStockRecordBizTypeEnum.SALE_RETURN.getType();
saleReturnItems.forEach(saleReturnItem -> {
Integer count = saleReturnItem.getCount();
stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
saleReturnItem.getProductId(), saleReturnItem.getWarehouseId(), BigDecimal.valueOf(count),
bizType, saleReturnItem.getReturnId(), saleReturnItem.getId(), saleReturn.getNo()));
});
} finally {
RedisUtils.unLockRds(key);
}
}
} }
...@@ -25,4 +25,6 @@ public interface CustomerOrderApi { ...@@ -25,4 +25,6 @@ public interface CustomerOrderApi {
Map<Long, CustomerOrderDTO> getOrderMap(Collection<Long> orderIds); Map<Long, CustomerOrderDTO> getOrderMap(Collection<Long> orderIds);
List<CustomerOrderItemDTO> queryItemsByIds(Collection<Long> orderItems); List<CustomerOrderItemDTO> queryItemsByIds(Collection<Long> orderItems);
void updateItems(List<CustomerOrderItemDTO> updateItems);
} }
...@@ -3,6 +3,8 @@ package cn.iocoder.foodnexus.module.order.dto; ...@@ -3,6 +3,8 @@ package cn.iocoder.foodnexus.module.order.dto;
import cn.iocoder.foodnexus.module.product.api.dto.ProductInfo; import cn.iocoder.foodnexus.module.product.api.dto.ProductInfo;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal;
/** /**
* @author : yanghao * @author : yanghao
* create at: 2025/9/22 15:36 * create at: 2025/9/22 15:36
...@@ -56,6 +58,14 @@ public class CustomerOrderItemDTO { ...@@ -56,6 +58,14 @@ public class CustomerOrderItemDTO {
*/ */
private Integer orderItemQuantity; private Integer orderItemQuantity;
/** /**
* 市场价,单位使用:分
*/
private Integer marketPrice;
/**
* 下浮率(%)
*/
private BigDecimal discount;
/**
* 签收数量 * 签收数量
*/ */
private Integer signedQuantity; private Integer signedQuantity;
...@@ -71,4 +81,14 @@ public class CustomerOrderItemDTO { ...@@ -71,4 +81,14 @@ public class CustomerOrderItemDTO {
* 客户下单备注 * 客户下单备注
*/ */
private String customerRemark; private String customerRemark;
/**
* 退货数量
*/
private Integer returnsQuantity;
/**
* 退货总价,单位:分
*/
private Integer returnsTotal;
} }
...@@ -83,29 +83,12 @@ public class DeliverySaleReturnController { ...@@ -83,29 +83,12 @@ public class DeliverySaleReturnController {
return success(result); return success(result);
} }
/*@PostMapping("/accept")
@Operation(summary = "确认接单")
@Parameter(name = "id", description = "配送单id(deliveryInfo.id)", required = true)
public CommonResult<Boolean> accept(@RequestParam("id") Long id) {
saleReturnService.accept(id, deliveryStaffApi.queryStaffIdByUserId(getLoginUserId()));
return success(Boolean.TRUE);
}
// 退货订单
@PostMapping("/delivery")
@Operation(summary = "确认取货")
@Parameter(name = "id", description = "配送单id(deliveryInfo.id)", required = true)
public CommonResult<Boolean> delivery(@RequestParam("id") Long id) {
saleReturnService.delivery(id, deliveryStaffApi.queryStaffIdByUserId(getLoginUserId()));
return success(Boolean.TRUE);
}*/
// 订单到货 - 运营后台 // 订单到货 - 运营后台
/*@PostMapping("/arrival") @PostMapping("/arrival")
@Operation(summary = "订单到货") @Operation(summary = "订单到货")
public CommonResult<Boolean> arrival(@RequestBody @Valid DeliveryOrderUpdateReqVO reqVO) { public CommonResult<Boolean> arrival(@RequestBody @Valid DeliveryOrderUpdateReqVO reqVO) {
saleReturnService.arrival(reqVO, deliveryStaffApi.queryStaffIdByUserId(getLoginUserId())); saleReturnService.arrival(reqVO, deliveryStaffApi.queryStaffIdByUserId(getLoginUserId()));
return success(Boolean.TRUE); return success(Boolean.TRUE);
}*/ }
} }
...@@ -794,4 +794,11 @@ public class CustomerOrderServiceImpl implements CustomerOrderService, CustomerO ...@@ -794,4 +794,11 @@ public class CustomerOrderServiceImpl implements CustomerOrderService, CustomerO
return BeanUtils.toBean(customerOrderItemMapper.selectByIds(orderItems), CustomerOrderItemDTO.class); return BeanUtils.toBean(customerOrderItemMapper.selectByIds(orderItems), CustomerOrderItemDTO.class);
} }
@Override
public void updateItems(List<CustomerOrderItemDTO> updateItems) {
if (CommonUtil.isNotEmpty(updateItems)) {
customerOrderItemMapper.updateById(BeanUtils.toBean(updateItems, CustomerOrderItemDO.class));
}
}
} }
\ No newline at end of file
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