Commit 573a79cad6851cc7b8a36bad99824d3242339238

Authored by YunaiV
1 parent f9396302

✨ ERP:增加 ERP 调拨单的实现 100%

yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java
@@ -40,9 +40,17 @@ public interface ErrorCodeConstants { @@ -40,9 +40,17 @@ public interface ErrorCodeConstants {
40 ErrorCode STOCK_OUT_NO_EXISTS = new ErrorCode(1_030_402_004, "生成出库单失败,请重新提交"); 40 ErrorCode STOCK_OUT_NO_EXISTS = new ErrorCode(1_030_402_004, "生成出库单失败,请重新提交");
41 ErrorCode STOCK_OUT_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_402_005, "其它出库单({})已审核,无法修改"); 41 ErrorCode STOCK_OUT_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_402_005, "其它出库单({})已审核,无法修改");
42 42
  43 + // ========== ERP 其它出库单 1-030-403-000 ==========
  44 + ErrorCode STOCK_MOVE_NOT_EXISTS = new ErrorCode(1_030_402_000, "库存调拨单不存在");
  45 + ErrorCode STOCK_MOVE_DELETE_FAIL_APPROVE = new ErrorCode(1_030_402_001, "库存调拨单({})已审核,无法删除");
  46 + ErrorCode STOCK_MOVE_PROCESS_FAIL = new ErrorCode(1_030_402_002, "反审核失败,只有已审核的出库单才能反审核");
  47 + ErrorCode STOCK_MOVE_APPROVE_FAIL = new ErrorCode(1_030_402_003, "审核失败,只有未审核的出库单才能审核");
  48 + ErrorCode STOCK_MOVE_NO_EXISTS = new ErrorCode(1_030_402_004, "生成调拨号失败,请重新提交");
  49 + ErrorCode STOCK_MOVE_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_402_005, "库存调拨单({})已审核,无法修改");
  50 +
43 // ========== ERP 产品库存 1-030-403-000 ========== 51 // ========== ERP 产品库存 1-030-403-000 ==========
44 - ErrorCode STOCK_COUNT_NEGATIVE = new ErrorCode(1_030_403_000, "操作失败,产品当前库存:{},小于变更数量:{}");  
45 - ErrorCode STOCK_COUNT_NEGATIVE2 = new ErrorCode(1_030_403_000, "操作失败,库存不足"); 52 + ErrorCode STOCK_COUNT_NEGATIVE = new ErrorCode(1_030_403_000, "操作失败,产品({})所在仓库({})的库存:{},小于变更数量:{}");
  53 + ErrorCode STOCK_COUNT_NEGATIVE2 = new ErrorCode(1_030_403_000, "操作失败,产品({})所在仓库({})的库存不足");
46 54
47 // ========== ERP 产品 1-030-500-000 ========== 55 // ========== ERP 产品 1-030-500-000 ==========
48 ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_030_500_000, "产品不存在"); 56 ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_030_500_000, "产品不存在");
yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockRecordBizTypeEnum.java
@@ -20,6 +20,11 @@ public enum ErpStockRecordBizTypeEnum implements IntArrayValuable { @@ -20,6 +20,11 @@ public enum ErpStockRecordBizTypeEnum implements IntArrayValuable {
20 20
21 OTHER_OUT(20, "其它出库"), 21 OTHER_OUT(20, "其它出库"),
22 OTHER_OUT_CANCEL(21, "其它出库(作废)"), 22 OTHER_OUT_CANCEL(21, "其它出库(作废)"),
  23 +
  24 + MOVE_IN(30, "调拨入库"),
  25 + MOVE_IN_CANCEL(31, "调拨入库(作废)"),
  26 + MOVE_OUT(32, "调拨出库"),
  27 + MOVE_OUT_CANCEL(33, "调拨出库(作废)"),
23 ; 28 ;
24 29
25 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErpStockRecordBizTypeEnum::getType).toArray(); 30 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErpStockRecordBizTypeEnum::getType).toArray();
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveSaveReqVO.java
1 package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move; 1 package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move;
2 2
  3 +import cn.hutool.core.util.ObjectUtil;
  4 +import com.fasterxml.jackson.annotation.JsonIgnore;
3 import io.swagger.v3.oas.annotations.media.Schema; 5 import io.swagger.v3.oas.annotations.media.Schema;
4 import jakarta.validation.Valid; 6 import jakarta.validation.Valid;
  7 +import jakarta.validation.constraints.AssertTrue;
5 import jakarta.validation.constraints.NotEmpty; 8 import jakarta.validation.constraints.NotEmpty;
6 import jakarta.validation.constraints.NotNull; 9 import jakarta.validation.constraints.NotNull;
7 import lombok.Data; 10 import lombok.Data;
@@ -63,6 +66,12 @@ public class ErpStockMoveSaveReqVO { @@ -63,6 +66,12 @@ public class ErpStockMoveSaveReqVO {
63 @Schema(description = "备注", example = "随便") 66 @Schema(description = "备注", example = "随便")
64 private String remark; 67 private String remark;
65 68
  69 + @AssertTrue(message = "调出、调仓仓库不能相同")
  70 + @JsonIgnore
  71 + public boolean isWarehouseValid() {
  72 + return ObjectUtil.notEqual(fromWarehouseId, toWarehouseId);
  73 + }
  74 +
66 } 75 }
67 76
68 } 77 }
69 \ No newline at end of file 78 \ No newline at end of file
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockMoveDO.java
@@ -14,8 +14,8 @@ import java.time.LocalDateTime; @@ -14,8 +14,8 @@ import java.time.LocalDateTime;
14 * 14 *
15 * @author 芋道源码 15 * @author 芋道源码
16 */ 16 */
17 -@TableName("erp_stock_in")  
18 -@KeySequence("erp_stock_in_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 17 +@TableName("erp_stock_move")
  18 +@KeySequence("erp_stock_move_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
19 @Data 19 @Data
20 @EqualsAndHashCode(callSuper = true) 20 @EqualsAndHashCode(callSuper = true)
21 @ToString(callSuper = true) 21 @ToString(callSuper = true)
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockMoveItemDO.java
@@ -14,8 +14,8 @@ import java.math.BigDecimal; @@ -14,8 +14,8 @@ import java.math.BigDecimal;
14 * 14 *
15 * @author 芋道源码 15 * @author 芋道源码
16 */ 16 */
17 -@TableName("erp_stock_in_item")  
18 -@KeySequence("erp_stock_in_item_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 17 +@TableName("erp_stock_move_item")
  18 +@KeySequence("erp_stock_move_item_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
19 @Data 19 @Data
20 @EqualsAndHashCode(callSuper = true) 20 @EqualsAndHashCode(callSuper = true)
21 @ToString(callSuper = true) 21 @ToString(callSuper = true)
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/redis/no/ErpNoRedisDAO.java
@@ -28,6 +28,11 @@ public class ErpNoRedisDAO { @@ -28,6 +28,11 @@ public class ErpNoRedisDAO {
28 */ 28 */
29 public static final String STOCK_OUT_NO_PREFIX = "QCKD"; 29 public static final String STOCK_OUT_NO_PREFIX = "QCKD";
30 30
  31 + /**
  32 + * 库存调拨 {@link cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveDO}
  33 + */
  34 + public static final String STOCK_MOVE_NO_PREFIX = "QCDB";
  35 +
31 @Resource 36 @Resource
32 private StringRedisTemplate stringRedisTemplate; 37 private StringRedisTemplate stringRedisTemplate;
33 38
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockInServiceImpl.java
@@ -66,7 +66,7 @@ public class ErpStockInServiceImpl implements ErpStockInService { @@ -66,7 +66,7 @@ public class ErpStockInServiceImpl implements ErpStockInService {
66 List<ErpStockInItemDO> stockInItems = validateStockInItems(createReqVO.getItems()); 66 List<ErpStockInItemDO> stockInItems = validateStockInItems(createReqVO.getItems());
67 // 1.2 校验供应商 67 // 1.2 校验供应商
68 supplierService.validateSupplier(createReqVO.getSupplierId()); 68 supplierService.validateSupplier(createReqVO.getSupplierId());
69 - // 1.3 69 + // 1.3 生成入库单号,并校验唯一性
70 String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_IN_NO_PREFIX); 70 String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_IN_NO_PREFIX);
71 if (stockInMapper.selectByNo(no) != null) { 71 if (stockInMapper.selectByNo(no) != null) {
72 throw exception(STOCK_IN_NO_EXISTS); 72 throw exception(STOCK_IN_NO_EXISTS);
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockMoveServiceImpl.java
@@ -15,7 +15,7 @@ import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO; @@ -15,7 +15,7 @@ import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
15 import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; 15 import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
16 import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum; 16 import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum;
17 import cn.iocoder.yudao.module.erp.service.product.ErpProductService; 17 import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
18 -import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService; 18 +import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO;
19 import jakarta.annotation.Resource; 19 import jakarta.annotation.Resource;
20 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
21 import org.springframework.transaction.annotation.Transactional; 21 import org.springframework.transaction.annotation.Transactional;
@@ -26,6 +26,7 @@ import java.util.Collection; @@ -26,6 +26,7 @@ import java.util.Collection;
26 import java.util.Collections; 26 import java.util.Collections;
27 import java.util.List; 27 import java.util.List;
28 import java.util.Map; 28 import java.util.Map;
  29 +import java.util.stream.Stream;
29 30
30 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 31 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
31 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; 32 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
@@ -55,8 +56,6 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService { @@ -55,8 +56,6 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService {
55 @Resource 56 @Resource
56 private ErpWarehouseService warehouseService; 57 private ErpWarehouseService warehouseService;
57 @Resource 58 @Resource
58 - private ErpCustomerService customerService;  
59 - @Resource  
60 private ErpStockRecordService stockRecordService; 59 private ErpStockRecordService stockRecordService;
61 60
62 @Override 61 @Override
@@ -64,12 +63,10 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService { @@ -64,12 +63,10 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService {
64 public Long createStockMove(ErpStockMoveSaveReqVO createReqVO) { 63 public Long createStockMove(ErpStockMoveSaveReqVO createReqVO) {
65 // 1.1 校验出库项的有效性 64 // 1.1 校验出库项的有效性
66 List<ErpStockMoveItemDO> stockMoveItems = validateStockMoveItems(createReqVO.getItems()); 65 List<ErpStockMoveItemDO> stockMoveItems = validateStockMoveItems(createReqVO.getItems());
67 - // 1.2 校验客户  
68 - customerService.validateCustomer(createReqVO.getCustomerId());  
69 - // 1.3  
70 - String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_OUT_NO_PREFIX); 66 + // 1.2 生成调拨单号,并校验唯一性
  67 + String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_MOVE_NO_PREFIX);
71 if (stockMoveMapper.selectByNo(no) != null) { 68 if (stockMoveMapper.selectByNo(no) != null) {
72 - throw exception(STOCK_OUT_NO_EXISTS); 69 + throw exception(STOCK_MOVE_NO_EXISTS);
73 } 70 }
74 71
75 // 2.1 插入出库单 72 // 2.1 插入出库单
@@ -90,11 +87,9 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService { @@ -90,11 +87,9 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService {
90 // 1.1 校验存在 87 // 1.1 校验存在
91 ErpStockMoveDO stockMove = validateStockMoveExists(updateReqVO.getId()); 88 ErpStockMoveDO stockMove = validateStockMoveExists(updateReqVO.getId());
92 if (ErpAuditStatus.APPROVE.getStatus().equals(stockMove.getStatus())) { 89 if (ErpAuditStatus.APPROVE.getStatus().equals(stockMove.getStatus())) {
93 - throw exception(STOCK_OUT_UPDATE_FAIL_APPROVE, stockMove.getNo()); 90 + throw exception(STOCK_MOVE_UPDATE_FAIL_APPROVE, stockMove.getNo());
94 } 91 }
95 - // 1.2 校验客户  
96 - customerService.validateCustomer(updateReqVO.getCustomerId());  
97 - // 1.3 校验出库项的有效性 92 + // 1.2 校验出库项的有效性
98 List<ErpStockMoveItemDO> stockMoveItems = validateStockMoveItems(updateReqVO.getItems()); 93 List<ErpStockMoveItemDO> stockMoveItems = validateStockMoveItems(updateReqVO.getItems());
99 94
100 // 2.1 更新出库单 95 // 2.1 更新出库单
@@ -114,26 +109,31 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService { @@ -114,26 +109,31 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService {
114 ErpStockMoveDO stockMove = validateStockMoveExists(id); 109 ErpStockMoveDO stockMove = validateStockMoveExists(id);
115 // 1.2 校验状态 110 // 1.2 校验状态
116 if (stockMove.getStatus().equals(status)) { 111 if (stockMove.getStatus().equals(status)) {
117 - throw exception(approve ? STOCK_OUT_APPROVE_FAIL : STOCK_OUT_PROCESS_FAIL); 112 + throw exception(approve ? STOCK_MOVE_APPROVE_FAIL : STOCK_MOVE_PROCESS_FAIL);
118 } 113 }
119 114
120 // 2. 更新状态 115 // 2. 更新状态
121 int updateCount = stockMoveMapper.updateByIdAndStatus(id, stockMove.getStatus(), 116 int updateCount = stockMoveMapper.updateByIdAndStatus(id, stockMove.getStatus(),
122 new ErpStockMoveDO().setStatus(status)); 117 new ErpStockMoveDO().setStatus(status));
123 if (updateCount == 0) { 118 if (updateCount == 0) {
124 - throw exception(approve ? STOCK_OUT_APPROVE_FAIL : STOCK_OUT_PROCESS_FAIL); 119 + throw exception(approve ? STOCK_MOVE_APPROVE_FAIL : STOCK_MOVE_PROCESS_FAIL);
125 } 120 }
126 121
127 // 3. 变更库存 122 // 3. 变更库存
128 List<ErpStockMoveItemDO> stockMoveItems = stockMoveItemMapper.selectListByMoveId(id); 123 List<ErpStockMoveItemDO> stockMoveItems = stockMoveItemMapper.selectListByMoveId(id);
129 - Integer bizType = approve ? ErpStockRecordBizTypeEnum.OTHER_OUT.getType()  
130 - : ErpStockRecordBizTypeEnum.OTHER_OUT_CANCEL.getType(); 124 + Integer fromBizType = approve ? ErpStockRecordBizTypeEnum.MOVE_OUT.getType()
  125 + : ErpStockRecordBizTypeEnum.MOVE_OUT_CANCEL.getType();
  126 + Integer toBizType = approve ? ErpStockRecordBizTypeEnum.MOVE_IN.getType()
  127 + : ErpStockRecordBizTypeEnum.MOVE_IN_CANCEL.getType();
131 stockMoveItems.forEach(stockMoveItem -> { 128 stockMoveItems.forEach(stockMoveItem -> {
132 - BigDecimal count = approve ? stockMoveItem.getCount() : stockMoveItem.getCount().negate();  
133 - // TODO 芋艿:稍后搞  
134 -// stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(  
135 -// stockMoveItem.getProductId(), stockMoveItem.getWarehouseId(), count,  
136 -// bizType, stockMoveItem.getMoveId(), stockMoveItem.getId(), stockMove.getNo())); 129 + BigDecimal fromCount = approve ? stockMoveItem.getCount().negate() : stockMoveItem.getCount();
  130 + BigDecimal toCount = approve ? stockMoveItem.getCount() : stockMoveItem.getCount().negate();
  131 + stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
  132 + stockMoveItem.getProductId(), stockMoveItem.getFromWarehouseId(), fromCount,
  133 + fromBizType, stockMoveItem.getMoveId(), stockMoveItem.getId(), stockMove.getNo()));
  134 + stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
  135 + stockMoveItem.getProductId(), stockMoveItem.getToWarehouseId(), toCount,
  136 + toBizType, stockMoveItem.getMoveId(), stockMoveItem.getId(), stockMove.getNo()));
137 }); 137 });
138 } 138 }
139 139
@@ -143,8 +143,8 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService { @@ -143,8 +143,8 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService {
143 convertSet(list, ErpStockMoveSaveReqVO.Item::getProductId)); 143 convertSet(list, ErpStockMoveSaveReqVO.Item::getProductId));
144 Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId); 144 Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId);
145 // 1.2 校验仓库存在 145 // 1.2 校验仓库存在
146 - // TODO 芋艿:稍后搞  
147 -// warehouseService.validWarehouseList(convertSet(list, ErpStockMoveSaveReqVO.Item::getWarehouseId)); 146 + warehouseService.validWarehouseList(convertSetByFlatMap(list,
  147 + item -> Stream.of(item.getFromWarehouseId(), item.getToWarehouseId())));
148 // 2. 转化为 ErpStockMoveItemDO 列表 148 // 2. 转化为 ErpStockMoveItemDO 列表
149 return convertList(list, o -> BeanUtils.toBean(o, ErpStockMoveItemDO.class, item -> item 149 return convertList(list, o -> BeanUtils.toBean(o, ErpStockMoveItemDO.class, item -> item
150 .setProductUnitId(productMap.get(item.getProductId()).getUnitId()) 150 .setProductUnitId(productMap.get(item.getProductId()).getUnitId())
@@ -180,7 +180,7 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService { @@ -180,7 +180,7 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService {
180 } 180 }
181 stockMoves.forEach(stockMove -> { 181 stockMoves.forEach(stockMove -> {
182 if (ErpAuditStatus.APPROVE.getStatus().equals(stockMove.getStatus())) { 182 if (ErpAuditStatus.APPROVE.getStatus().equals(stockMove.getStatus())) {
183 - throw exception(STOCK_OUT_DELETE_FAIL_APPROVE, stockMove.getNo()); 183 + throw exception(STOCK_MOVE_DELETE_FAIL_APPROVE, stockMove.getNo());
184 } 184 }
185 }); 185 });
186 186
@@ -196,7 +196,7 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService { @@ -196,7 +196,7 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService {
196 private ErpStockMoveDO validateStockMoveExists(Long id) { 196 private ErpStockMoveDO validateStockMoveExists(Long id) {
197 ErpStockMoveDO stockMove = stockMoveMapper.selectById(id); 197 ErpStockMoveDO stockMove = stockMoveMapper.selectById(id);
198 if (stockMove == null) { 198 if (stockMove == null) {
199 - throw exception(STOCK_OUT_NOT_EXISTS); 199 + throw exception(STOCK_MOVE_NOT_EXISTS);
200 } 200 }
201 return stockMove; 201 return stockMove;
202 } 202 }
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockOutServiceImpl.java
@@ -67,7 +67,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { @@ -67,7 +67,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
67 List<ErpStockOutItemDO> stockOutItems = validateStockOutItems(createReqVO.getItems()); 67 List<ErpStockOutItemDO> stockOutItems = validateStockOutItems(createReqVO.getItems());
68 // 1.2 校验客户 68 // 1.2 校验客户
69 customerService.validateCustomer(createReqVO.getCustomerId()); 69 customerService.validateCustomer(createReqVO.getCustomerId());
70 - // 1.3 70 + // 1.3 生成出库单号,并校验唯一性
71 String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_OUT_NO_PREFIX); 71 String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_OUT_NO_PREFIX);
72 if (stockOutMapper.selectByNo(no) != null) { 72 if (stockOutMapper.selectByNo(no) != null) {
73 throw exception(STOCK_OUT_NO_EXISTS); 73 throw exception(STOCK_OUT_NO_EXISTS);
@@ -130,7 +130,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { @@ -130,7 +130,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
130 Integer bizType = approve ? ErpStockRecordBizTypeEnum.OTHER_OUT.getType() 130 Integer bizType = approve ? ErpStockRecordBizTypeEnum.OTHER_OUT.getType()
131 : ErpStockRecordBizTypeEnum.OTHER_OUT_CANCEL.getType(); 131 : ErpStockRecordBizTypeEnum.OTHER_OUT_CANCEL.getType();
132 stockOutItems.forEach(stockOutItem -> { 132 stockOutItems.forEach(stockOutItem -> {
133 - BigDecimal count = approve ? stockOutItem.getCount() : stockOutItem.getCount().negate(); 133 + BigDecimal count = approve ? stockOutItem.getCount().negate() : stockOutItem.getCount();
134 stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO( 134 stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
135 stockOutItem.getProductId(), stockOutItem.getWarehouseId(), count, 135 stockOutItem.getProductId(), stockOutItem.getWarehouseId(), count,
136 bizType, stockOutItem.getOutId(), stockOutItem.getId(), stockOut.getNo())); 136 bizType, stockOutItem.getOutId(), stockOutItem.getId(), stockOut.getNo()));
yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockServiceImpl.java
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO; 4 import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO;
5 import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; 5 import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
6 import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMapper; 6 import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMapper;
  7 +import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
7 import jakarta.annotation.Resource; 8 import jakarta.annotation.Resource;
8 import org.springframework.stereotype.Service; 9 import org.springframework.stereotype.Service;
9 import org.springframework.validation.annotation.Validated; 10 import org.springframework.validation.annotation.Validated;
@@ -31,6 +32,11 @@ public class ErpStockServiceImpl implements ErpStockService { @@ -31,6 +32,11 @@ public class ErpStockServiceImpl implements ErpStockService {
31 private static final Boolean NEGATIVE_STOCK_COUNT_ENABLE = false; 32 private static final Boolean NEGATIVE_STOCK_COUNT_ENABLE = false;
32 33
33 @Resource 34 @Resource
  35 + private ErpProductService productService;
  36 + @Resource
  37 + private ErpWarehouseService warehouseService;
  38 +
  39 + @Resource
34 private ErpStockMapper stockMapper; 40 private ErpStockMapper stockMapper;
35 41
36 @Override 42 @Override
@@ -58,13 +64,16 @@ public class ErpStockServiceImpl implements ErpStockService { @@ -58,13 +64,16 @@ public class ErpStockServiceImpl implements ErpStockService {
58 } 64 }
59 // 1.2 校验库存是否充足 65 // 1.2 校验库存是否充足
60 if (!NEGATIVE_STOCK_COUNT_ENABLE && stock.getCount().add(count).compareTo(BigDecimal.ZERO) < 0) { 66 if (!NEGATIVE_STOCK_COUNT_ENABLE && stock.getCount().add(count).compareTo(BigDecimal.ZERO) < 0) {
61 - throw exception(STOCK_COUNT_NEGATIVE, stock.getCount(), count); 67 + throw exception(STOCK_COUNT_NEGATIVE, productService.getProduct(productId).getName(),
  68 + warehouseService.getWarehouse(warehouseId).getName(), stock.getCount(), count);
62 } 69 }
63 70
64 // 2. 库存变更 71 // 2. 库存变更
65 int updateCount = stockMapper.updateCountIncrement(stock.getId(), count, NEGATIVE_STOCK_COUNT_ENABLE); 72 int updateCount = stockMapper.updateCountIncrement(stock.getId(), count, NEGATIVE_STOCK_COUNT_ENABLE);
66 if (updateCount == 0) { 73 if (updateCount == 0) {
67 - throw exception(STOCK_COUNT_NEGATIVE2); // 此时不好去查询最新库存,所以直接抛出该提示,不提供具体库存数字 74 + // 此时不好去查询最新库存,所以直接抛出该提示,不提供具体库存数字
  75 + throw exception(STOCK_COUNT_NEGATIVE2, productService.getProduct(productId).getName(),
  76 + warehouseService.getWarehouse(warehouseId).getName());
68 } 77 }
69 78
70 // 3. 返回最新库存 79 // 3. 返回最新库存