Commit 86d760fdb1593fdd591aa5447cc75058f0681e03

Authored by YunaiV
1 parent fe38e4fd

feat(wms):减法,去掉批次号等字段

Showing 29 changed files with 939 additions and 231 deletions
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/inventory/vo/history/WmsInventoryHistoryRespVO.java
... ... @@ -40,12 +40,6 @@ public class WmsInventoryHistoryRespVO {
40 40 private BigDecimal beforeQuantity;
41 41 @Schema(description = "变化后库存数量", example = "100.00")
42 42 private BigDecimal afterQuantity;
43   - @Schema(description = "批号", example = "BATCH001")
44   - private String batchNo;
45   - @Schema(description = "生产日期")
46   - private LocalDateTime productionDate;
47   - @Schema(description = "过期日期")
48   - private LocalDateTime expirationDate;
49 43 @Schema(description = "金额", example = "1000.00")
50 44 private BigDecimal amount;
51 45 @Schema(description = "备注", example = "备注")
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/check/vo/detail/WmsCheckOrderDetailRespVO.java
... ... @@ -46,15 +46,6 @@ public class WmsCheckOrderDetailRespVO {
46 46 @Schema(description = "库存编号", example = "1024")
47 47 private Long inventoryId;
48 48  
49   - @Schema(description = "批号", example = "B202605110001")
50   - private String batchNo;
51   -
52   - @Schema(description = "生产日期")
53   - private LocalDateTime productionDate;
54   -
55   - @Schema(description = "过期日期")
56   - private LocalDateTime expirationDate;
57   -
58 49 @Schema(description = "入库时间")
59 50 private LocalDateTime receiptTime;
60 51  
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/check/vo/detail/WmsCheckOrderDetailSaveReqVO.java
... ... @@ -23,16 +23,6 @@ public class WmsCheckOrderDetailSaveReqVO {
23 23 @Schema(description = "库存编号", example = "1024")
24 24 private Long inventoryId;
25 25  
26   - @Schema(description = "批号", example = "B202605110001")
27   - @Size(max = 64, message = "批号长度不能超过 64 个字符")
28   - private String batchNo;
29   -
30   - @Schema(description = "生产日期")
31   - private LocalDateTime productionDate;
32   -
33   - @Schema(description = "过期日期")
34   - private LocalDateTime expirationDate;
35   -
36 26 @Schema(description = "入库时间")
37 27 private LocalDateTime receiptTime;
38 28  
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/movement/vo/detail/WmsMovementOrderDetailRespVO.java
... ... @@ -49,15 +49,6 @@ public class WmsMovementOrderDetailRespVO {
49 49 @Schema(description = "目标仓库名称", example = "上海仓")
50 50 private String targetWarehouseName;
51 51  
52   - @Schema(description = "批号", example = "B202605110001")
53   - private String batchNo;
54   -
55   - @Schema(description = "生产日期")
56   - private LocalDateTime productionDate;
57   -
58   - @Schema(description = "过期日期")
59   - private LocalDateTime expirationDate;
60   -
61 52 @Schema(description = "移库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
62 53 private BigDecimal quantity;
63 54  
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/movement/vo/detail/WmsMovementOrderDetailSaveReqVO.java
... ... @@ -7,7 +7,6 @@ import jakarta.validation.constraints.Size;
7 7 import lombok.Data;
8 8  
9 9 import java.math.BigDecimal;
10   -import java.time.LocalDateTime;
11 10  
12 11 @Schema(description = "管理后台 - WMS 移库单明细保存 Request VO")
13 12 @Data
... ... @@ -20,16 +19,6 @@ public class WmsMovementOrderDetailSaveReqVO {
20 19 @NotNull(message = "SKU 不能为空")
21 20 private Long skuId;
22 21  
23   - @Schema(description = "批号", example = "B202605110001")
24   - @Size(max = 64, message = "批号长度不能超过 64 个字符")
25   - private String batchNo;
26   -
27   - @Schema(description = "生产日期")
28   - private LocalDateTime productionDate;
29   -
30   - @Schema(description = "过期日期")
31   - private LocalDateTime expirationDate;
32   -
33 22 @Schema(description = "移库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
34 23 @NotNull(message = "移库数量不能为空")
35 24 @DecimalMin(value = "0", inclusive = false, message = "移库数量必须大于 0")
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/receipt/vo/detail/WmsReceiptOrderDetailRespVO.java
... ... @@ -43,15 +43,6 @@ public class WmsReceiptOrderDetailRespVO {
43 43 @Schema(description = "仓库名称", example = "北京仓")
44 44 private String warehouseName;
45 45  
46   - @Schema(description = "批号", example = "B202605110001")
47   - private String batchNo;
48   -
49   - @Schema(description = "生产日期")
50   - private LocalDateTime productionDate;
51   -
52   - @Schema(description = "过期日期")
53   - private LocalDateTime expirationDate;
54   -
55 46 @Schema(description = "入库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
56 47 private BigDecimal quantity;
57 48  
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/receipt/vo/detail/WmsReceiptOrderDetailSaveReqVO.java
... ... @@ -7,7 +7,6 @@ import jakarta.validation.constraints.Size;
7 7 import lombok.Data;
8 8  
9 9 import java.math.BigDecimal;
10   -import java.time.LocalDateTime;
11 10  
12 11 @Schema(description = "管理后台 - WMS 入库单明细保存 Request VO")
13 12 @Data
... ... @@ -20,16 +19,6 @@ public class WmsReceiptOrderDetailSaveReqVO {
20 19 @NotNull(message = "SKU 不能为空")
21 20 private Long skuId;
22 21  
23   - @Schema(description = "批号", example = "B202605110001")
24   - @Size(max = 64, message = "批号长度不能超过 64 个字符")
25   - private String batchNo;
26   -
27   - @Schema(description = "生产日期")
28   - private LocalDateTime productionDate;
29   -
30   - @Schema(description = "过期日期")
31   - private LocalDateTime expirationDate;
32   -
33 22 @Schema(description = "入库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
34 23 @NotNull(message = "入库数量不能为空")
35 24 @DecimalMin(value = "0", inclusive = false, message = "入库数量必须大于 0")
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/shipment/vo/detail/WmsShipmentOrderDetailRespVO.java
... ... @@ -43,15 +43,6 @@ public class WmsShipmentOrderDetailRespVO {
43 43 @Schema(description = "仓库名称", example = "北京仓")
44 44 private String warehouseName;
45 45  
46   - @Schema(description = "批号", example = "B202605110001")
47   - private String batchNo;
48   -
49   - @Schema(description = "生产日期")
50   - private LocalDateTime productionDate;
51   -
52   - @Schema(description = "过期日期")
53   - private LocalDateTime expirationDate;
54   -
55 46 @Schema(description = "出库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
56 47 private BigDecimal quantity;
57 48  
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/shipment/vo/detail/WmsShipmentOrderDetailSaveReqVO.java
... ... @@ -7,7 +7,6 @@ import jakarta.validation.constraints.Size;
7 7 import lombok.Data;
8 8  
9 9 import java.math.BigDecimal;
10   -import java.time.LocalDateTime;
11 10  
12 11 @Schema(description = "管理后台 - WMS 出库单明细保存 Request VO")
13 12 @Data
... ... @@ -20,16 +19,6 @@ public class WmsShipmentOrderDetailSaveReqVO {
20 19 @NotNull(message = "SKU 不能为空")
21 20 private Long skuId;
22 21  
23   - @Schema(description = "批号", example = "B202605110001")
24   - @Size(max = 64, message = "批号长度不能超过 64 个字符")
25   - private String batchNo;
26   -
27   - @Schema(description = "生产日期")
28   - private LocalDateTime productionDate;
29   -
30   - @Schema(description = "过期日期")
31   - private LocalDateTime expirationDate;
32   -
33 22 @Schema(description = "出库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
34 23 @NotNull(message = "出库数量不能为空")
35 24 @DecimalMin(value = "0", inclusive = false, message = "出库数量必须大于 0")
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/inventory/WmsInventoryHistoryDO.java
... ... @@ -10,7 +10,6 @@ import com.baomidou.mybatisplus.annotation.TableName;
10 10 import lombok.*;
11 11  
12 12 import java.math.BigDecimal;
13   -import java.time.LocalDateTime;
14 13  
15 14 /**
16 15 * WMS 库存流水 DO
... ... @@ -60,21 +59,6 @@ public class WmsInventoryHistoryDO extends BaseDO {
60 59 */
61 60 private BigDecimal afterQuantity;
62 61  
63   - // ========= 批次效期相关字段 =========
64   -
65   - /**
66   - * 批号
67   - */
68   - private String batchNo;
69   - /**
70   - * 生产日期
71   - */
72   - private LocalDateTime productionDate;
73   - /**
74   - * 过期日期
75   - */
76   - private LocalDateTime expirationDate;
77   -
78 62 // ========= 金额备注相关字段 =========
79 63  
80 64 /**
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/order/check/WmsCheckOrderDetailDO.java
... ... @@ -67,20 +67,6 @@ public class WmsCheckOrderDetailDO extends BaseDO {
67 67 */
68 68 private Long inventoryId;
69 69  
70   - // ========= 批次效期字段 =========
71   -
72   - /**
73   - * 批号
74   - */
75   - private String batchNo;
76   - /**
77   - * 生产日期
78   - */
79   - private LocalDateTime productionDate;
80   - /**
81   - * 过期日期
82   - */
83   - private LocalDateTime expirationDate;
84 70 /**
85 71 * 入库时间
86 72 */
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/order/movement/WmsMovementOrderDetailDO.java
... ... @@ -9,7 +9,6 @@ import com.baomidou.mybatisplus.annotation.TableName;
9 9 import lombok.*;
10 10  
11 11 import java.math.BigDecimal;
12   -import java.time.LocalDateTime;
13 12  
14 13 /**
15 14 * WMS 移库单明细 DO
... ... @@ -69,21 +68,6 @@ public class WmsMovementOrderDetailDO extends BaseDO {
69 68 */
70 69 private Long targetWarehouseId;
71 70  
72   - // ========= 批次效期字段 =========
73   -
74   - /**
75   - * 批号
76   - */
77   - private String batchNo;
78   - /**
79   - * 生产日期
80   - */
81   - private LocalDateTime productionDate;
82   - /**
83   - * 过期日期
84   - */
85   - private LocalDateTime expirationDate;
86   -
87 71 // ========= 汇总金额字段 =========
88 72  
89 73 /**
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/order/receipt/WmsReceiptOrderDetailDO.java
... ... @@ -9,7 +9,6 @@ import com.baomidou.mybatisplus.annotation.TableName;
9 9 import lombok.*;
10 10  
11 11 import java.math.BigDecimal;
12   -import java.time.LocalDateTime;
13 12  
14 13 /**
15 14 * WMS 入库单明细 DO
... ... @@ -60,21 +59,6 @@ public class WmsReceiptOrderDetailDO extends BaseDO {
60 59 */
61 60 private Long warehouseId;
62 61  
63   - // ========= 批次效期字段 =========
64   -
65   - /**
66   - * 批号
67   - */
68   - private String batchNo;
69   - /**
70   - * 生产日期
71   - */
72   - private LocalDateTime productionDate;
73   - /**
74   - * 过期日期
75   - */
76   - private LocalDateTime expirationDate;
77   -
78 62 // ========= 汇总金额字段 =========
79 63  
80 64 /**
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/order/shipment/WmsShipmentOrderDetailDO.java
... ... @@ -9,7 +9,6 @@ import com.baomidou.mybatisplus.annotation.TableName;
9 9 import lombok.*;
10 10  
11 11 import java.math.BigDecimal;
12   -import java.time.LocalDateTime;
13 12  
14 13 /**
15 14 * WMS 出库单明细 DO
... ... @@ -60,21 +59,6 @@ public class WmsShipmentOrderDetailDO extends BaseDO {
60 59 */
61 60 private Long warehouseId;
62 61  
63   - // ========= 批次效期字段 =========
64   -
65   - /**
66   - * 批号
67   - */
68   - private String batchNo;
69   - /**
70   - * 生产日期
71   - */
72   - private LocalDateTime productionDate;
73   - /**
74   - * 过期日期
75   - */
76   - private LocalDateTime expirationDate;
77   -
78 62 // ========= 汇总金额字段 =========
79 63  
80 64 /**
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/framework/config/package-info.java deleted
1   -/**
2   - * WMS 模块配置
3   - */
4   -package cn.iocoder.yudao.module.wms.framework.config;
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/inventory/WmsInventoryServiceImpl.java
... ... @@ -121,50 +121,50 @@ public class WmsInventoryServiceImpl implements WmsInventoryService {
121 121 }
122 122  
123 123 private List<WmsInventoryDO> getOrCreateInventoryList(List<WmsInventoryChangeReqDTO.Item> items) {
124   - // 先按库存维度在内存去重,避免同一批明细重复查询或重复补行。
125   - List<WmsInventoryDO> inventoryKeyList = new ArrayList<>(items.size());
  124 + // 1.1 先按库存维度在内存去重,避免同一批明细重复查询或重复补行
  125 + List<WmsInventoryDO> inventoryDimensions = new ArrayList<>(items.size());
126 126 for (WmsInventoryChangeReqDTO.Item item : items) {
127   - if (findInventory(inventoryKeyList, item) == null) {
128   - inventoryKeyList.add(new WmsInventoryDO().setSkuId(item.getSkuId())
  127 + if (findInventory(inventoryDimensions, item) == null) {
  128 + inventoryDimensions.add(new WmsInventoryDO().setSkuId(item.getSkuId())
129 129 .setWarehouseId(item.getWarehouseId()));
130 130 }
131 131 }
132   -
133   - // 批量查询已存在的库存行;这里不加锁,后续统一按库存 ID 批量加锁。
134   - List<WmsInventoryDO> inventories = inventoryMapper.selectListByKeys(inventoryKeyList);
135   -
136   - // 对比库存维度,找出数据库中还不存在的库存行,再按唯一索引兜底补齐。
137   - List<WmsInventoryDO> missingInventoryList = new ArrayList<>(inventoryKeyList.size());
138   - for (WmsInventoryDO inventoryKey : inventoryKeyList) {
139   - if (findInventory(inventories, inventoryKey) == null) {
140   - missingInventoryList.add(inventoryKey);
  132 + // 1.2 批量查询已存在的库存行(这里不加锁,后续统一按库存 ID 批量加锁)
  133 + List<WmsInventoryDO> inventories = inventoryMapper.selectListByKeys(inventoryDimensions);
  134 +
  135 + // 2.1 对比库存维度,找出数据库中还不存在的库存行
  136 + List<WmsInventoryDO> missingInventories = new ArrayList<>(inventoryDimensions.size());
  137 + for (WmsInventoryDO inventoryDimension : inventoryDimensions) {
  138 + if (findInventory(inventories, inventoryDimension) == null) {
  139 + missingInventories.add(inventoryDimension);
141 140 }
142 141 }
143   - if (CollUtil.isEmpty(missingInventoryList)) {
  142 + // 2.2 如果库存行都已存在,直接返回待加锁库存列表
  143 + if (CollUtil.isEmpty(missingInventories)) {
144 144 return inventories;
145 145 }
146   -
147   - inventories.addAll(createMissingInventoryList(missingInventoryList));
  146 + // 2.3 对缺失库存行执行创建;并发冲突时,内部会按唯一索引回查已创建的库存行
  147 + inventories.addAll(createMissingInventoryList(missingInventories));
148 148 return inventories;
149 149 }
150 150  
151   - private List<WmsInventoryDO> createMissingInventoryList(List<WmsInventoryDO> missingInventoryList) {
  151 + private List<WmsInventoryDO> createMissingInventoryList(List<WmsInventoryDO> missingInventories) {
152 152 // 优先批量插入缺失库存行;并发唯一键冲突时,再逐个插入并回查冲突行。
153   - List<WmsInventoryDO> newInventoryList = convertList(missingInventoryList, missingInventory ->
  153 + List<WmsInventoryDO> newInventories = convertList(missingInventories, missingInventory ->
154 154 new WmsInventoryDO().setSkuId(missingInventory.getSkuId()).setWarehouseId(missingInventory.getWarehouseId())
155 155 .setQuantity(BigDecimal.ZERO));
156 156 try {
157   - inventoryMapper.insertBatch(newInventoryList);
158   - return newInventoryList;
  157 + inventoryMapper.insertBatch(newInventories);
  158 + return newInventories;
159 159 } catch (DuplicateKeyException ex) {
160 160 // 并发事务可能已经补齐部分库存行,降级为逐个插入并回查唯一键冲突的行。
161   - log.warn("[createMissingInventoryList][missingInventoryList({}) 批量插入库存行冲突,降级为逐个插入]",
162   - missingInventoryList, ex);
  161 + log.warn("[createMissingInventoryList][missingInventories({}) 批量插入库存行冲突,降级为逐个插入]",
  162 + missingInventories, ex);
163 163 }
164 164  
165 165 // 批量插入失败后逐条补齐;单条唯一键冲突时,回查并使用并发事务创建的库存行。
166   - List<WmsInventoryDO> resultList = new ArrayList<>(missingInventoryList.size());
167   - for (WmsInventoryDO missingInventory : missingInventoryList) {
  166 + List<WmsInventoryDO> createdInventories = new ArrayList<>(missingInventories.size());
  167 + for (WmsInventoryDO missingInventory : missingInventories) {
168 168 WmsInventoryDO inventory = new WmsInventoryDO().setSkuId(missingInventory.getSkuId())
169 169 .setWarehouseId(missingInventory.getWarehouseId())
170 170 .setQuantity(BigDecimal.ZERO);
... ... @@ -178,9 +178,9 @@ public class WmsInventoryServiceImpl implements WmsInventoryService {
178 178 throw ex;
179 179 }
180 180 }
181   - resultList.add(inventory);
  181 + createdInventories.add(inventory);
182 182 }
183   - return resultList;
  183 + return createdInventories;
184 184 }
185 185  
186 186 private WmsInventoryHistoryDO buildInventoryHistory(WmsInventoryChangeReqDTO reqDTO,
... ... @@ -189,8 +189,6 @@ public class WmsInventoryServiceImpl implements WmsInventoryService {
189 189 return new WmsInventoryHistoryDO()
190 190 .setWarehouseId(item.getWarehouseId()).setSkuId(item.getSkuId())
191 191 .setQuantity(item.getQuantity()).setBeforeQuantity(result.get(0)).setAfterQuantity(result.get(1))
192   - .setBatchNo(item.getBatchNo()).setProductionDate(item.getProductionDate())
193   - .setExpirationDate(item.getExpirationDate())
194 192 .setAmount(item.getAmount()).setRemark(item.getRemark())
195 193 .setOrderId(reqDTO.getOrderId()).setOrderNo(reqDTO.getOrderNo()).setOrderType(reqDTO.getOrderType());
196 194 }
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/inventory/dto/WmsInventoryChangeReqDTO.java
... ... @@ -4,7 +4,6 @@ import cn.iocoder.yudao.module.wms.enums.inventory.WmsInventoryOrderTypeEnum;
4 4 import lombok.Data;
5 5  
6 6 import java.math.BigDecimal;
7   -import java.time.LocalDateTime;
8 7 import java.util.List;
9 8  
10 9 /**
... ... @@ -54,21 +53,6 @@ public class WmsInventoryChangeReqDTO {
54 53 */
55 54 private BigDecimal quantity;
56 55  
57   - // ========= 批次效期相关字段 =========
58   -
59   - /**
60   - * 批号
61   - */
62   - private String batchNo;
63   - /**
64   - * 生产日期
65   - */
66   - private LocalDateTime productionDate;
67   - /**
68   - * 过期日期
69   - */
70   - private LocalDateTime expirationDate;
71   -
72 56 // ========= 金额备注相关字段 =========
73 57  
74 58 /**
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/check/WmsCheckOrderServiceImpl.java
1 1 package cn.iocoder.yudao.module.wms.service.order.check;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.hutool.core.util.ObjectUtil;
4 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
... ... @@ -171,9 +172,7 @@ public class WmsCheckOrderServiceImpl implements WmsCheckOrderService {
171 172 }
172 173  
173 174 /**
174   - * 盘点盘库单对应库存。
175   - *
176   - * 盘库只对盈亏数量生成库存变更:实盘数量大于账面数量时增加库存,反之扣减库存,批次字段随库存流水记录。
  175 + * 盘点盘库单对应库存
177 176 *
178 177 * @param order 盘库单
179 178 * @param details 盘库单明细列表
... ... @@ -189,6 +188,9 @@ public class WmsCheckOrderServiceImpl implements WmsCheckOrderService {
189 188 .setQuantity(differenceQuantity);
190 189 items.add(item);
191 190 }
  191 + if (CollUtil.isEmpty(items)) {
  192 + return;
  193 + }
192 194 inventoryService.changeInventory(new WmsInventoryChangeReqDTO()
193 195 .setOrderId(order.getId()).setOrderNo(order.getNo())
194 196 .setOrderType(WmsInventoryOrderTypeEnum.CHECK.getType()).setItems(items));
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/movement/WmsMovementOrderServiceImpl.java
... ... @@ -175,9 +175,7 @@ public class WmsMovementOrderServiceImpl implements WmsMovementOrderService {
175 175 }
176 176  
177 177 /**
178   - * 移动移库单对应库存。
179   - *
180   - * 移库会生成两条库存变更:来源仓库扣减库存,目标仓库增加库存,批次字段随库存流水记录。
  178 + * 移动移库单对应库存
181 179 *
182 180 * @param order 移库单
183 181 * @param details 移库单明细列表
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/receipt/WmsReceiptOrderServiceImpl.java
... ... @@ -184,7 +184,7 @@ public class WmsReceiptOrderServiceImpl implements WmsReceiptOrderService {
184 184 /**
185 185 * 增加入库单对应库存。
186 186 *
187   - * 入库在库存变更模型中使用正数数量,批次字段随库存流水记录。
  187 + * 入库在库存变更模型中使用正数数量。
188 188 *
189 189 * @param order 入库单
190 190 * @param details 入库单明细列表
... ...
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/shipment/WmsShipmentOrderServiceImpl.java
... ... @@ -183,9 +183,7 @@ public class WmsShipmentOrderServiceImpl implements WmsShipmentOrderService {
183 183 }
184 184  
185 185 /**
186   - * 扣减出库单对应库存。
187   - *
188   - * 出库在库存变更模型中使用负数数量,批次字段随库存流水记录。
  186 + * 扣减出库单对应库存
189 187 *
190 188 * @param order 出库单
191 189 * @param details 出库单明细列表
... ...
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/inventory/WmsInventoryServiceImplTest.java
... ... @@ -30,6 +30,7 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServic
30 30 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.INVENTORY_QUANTITY_NOT_ENOUGH;
31 31 import static org.junit.jupiter.api.Assertions.assertEquals;
32 32 import static org.junit.jupiter.api.Assertions.assertNotNull;
  33 +import static org.junit.jupiter.api.Assertions.assertNull;
33 34 import static org.mockito.Mockito.when;
34 35  
35 36 @Import({WmsInventoryServiceImpl.class, WmsInventoryHistoryServiceImpl.class})
... ... @@ -230,6 +231,10 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
230 231 // 调用,并断言
231 232 assertServiceException(() -> inventoryService.changeInventory(reqDTO), INVENTORY_QUANTITY_NOT_ENOUGH,
232 233 item.getName(), sku.getName(), 100L, new BigDecimal("2.000000"), new BigDecimal("-3.00"));
  234 + WmsInventoryDO inventory = inventoryMapper.selectBySkuIdAndWarehouseId(sku.getId(), 100L);
  235 + assertNotNull(inventory);
  236 + assertEquals(0, new BigDecimal("2.00").compareTo(inventory.getQuantity()));
  237 + assertEquals(0L, inventoryHistoryMapper.selectCount());
233 238 }
234 239  
235 240 @Test
... ... @@ -243,7 +248,32 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
243 248 // 调用,并断言
244 249 assertServiceException(() -> inventoryService.changeInventory(reqDTO), INVENTORY_QUANTITY_NOT_ENOUGH,
245 250 item.getName(), sku.getName(), 100L, BigDecimal.ZERO.setScale(6), new BigDecimal("-3.00"));
246   - assertEquals(0, inventoryMapper.selectCount());
  251 + assertEquals(0L, inventoryMapper.selectCount());
  252 + assertEquals(0L, inventoryHistoryMapper.selectCount());
  253 + }
  254 +
  255 + @Test
  256 + public void testChangeInventory_quantityNotEnoughRollbackCreatedInventories() {
  257 + // mock 数据
  258 + WmsItemDO item = createItem("ITEM-001", "红富士苹果");
  259 + WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
  260 + WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, "5.00");
  261 + List<WmsInventoryChangeReqDTO.Item> items = new ArrayList<>(reqDTO.getItems());
  262 + items.add(new WmsInventoryChangeReqDTO.Item()
  263 + .setSkuId(sku.getId())
  264 + .setWarehouseId(200L)
  265 + .setQuantity(new BigDecimal("-1.00"))
  266 + .setAmount(new BigDecimal("20.00"))
  267 + .setRemark("测试出库"));
  268 + reqDTO.setItems(items);
  269 + mockItemSkuAndItem(item, sku);
  270 +
  271 + // 调用,并断言:第二条明细库存不足,事务回滚前面补齐的库存行
  272 + assertServiceException(() -> inventoryService.changeInventory(reqDTO), INVENTORY_QUANTITY_NOT_ENOUGH,
  273 + item.getName(), sku.getName(), 200L, BigDecimal.ZERO.setScale(6), new BigDecimal("-1.00"));
  274 + assertNull(inventoryMapper.selectBySkuIdAndWarehouseId(sku.getId(), 100L));
  275 + assertNull(inventoryMapper.selectBySkuIdAndWarehouseId(sku.getId(), 200L));
  276 + assertEquals(0L, inventoryHistoryMapper.selectCount());
247 277 }
248 278  
249 279 @Test
... ...
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/check/WmsCheckOrderDetailServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.wms.service.order.check;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  4 +import cn.iocoder.yudao.module.wms.controller.admin.order.check.vo.detail.WmsCheckOrderDetailSaveReqVO;
  5 +import cn.iocoder.yudao.module.wms.controller.admin.order.check.vo.order.WmsCheckOrderSaveReqVO;
  6 +import cn.iocoder.yudao.module.wms.dal.dataobject.order.check.WmsCheckOrderDetailDO;
  7 +import cn.iocoder.yudao.module.wms.dal.mysql.order.check.WmsCheckOrderDetailMapper;
  8 +import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService;
  9 +import jakarta.annotation.Resource;
  10 +import org.junit.jupiter.api.Test;
  11 +import org.springframework.context.annotation.Import;
  12 +import org.springframework.test.context.bean.override.mockito.MockitoBean;
  13 +
  14 +import java.math.BigDecimal;
  15 +import java.util.Arrays;
  16 +import java.util.List;
  17 +
  18 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  19 +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_DETAIL_NOT_EXISTS;
  20 +import static org.junit.jupiter.api.Assertions.assertEquals;
  21 +import static org.junit.jupiter.api.Assertions.assertNotNull;
  22 +import static org.junit.jupiter.api.Assertions.assertNull;
  23 +
  24 +@Import(WmsCheckOrderDetailServiceImpl.class)
  25 +public class WmsCheckOrderDetailServiceImplTest extends BaseDbUnitTest {
  26 +
  27 + @Resource
  28 + private WmsCheckOrderDetailServiceImpl checkOrderDetailService;
  29 +
  30 + @Resource
  31 + private WmsCheckOrderDetailMapper checkOrderDetailMapper;
  32 +
  33 + @MockitoBean
  34 + private WmsItemSkuService itemSkuService;
  35 +
  36 + @Test
  37 + public void testCreateCheckOrderDetailList_success() {
  38 + // mock 数据
  39 + Long orderId = 10L;
  40 + WmsCheckOrderSaveReqVO reqVO = createCheckOrderReqVO(
  41 + createCheckOrderDetailReqVO(null, 1001L, "10.00", "9.00"),
  42 + createCheckOrderDetailReqVO(null, 1002L, "20.00", "21.00"));
  43 +
  44 + // 调用
  45 + checkOrderDetailService.createCheckOrderDetailList(orderId, reqVO);
  46 +
  47 + // 断言
  48 + List<WmsCheckOrderDetailDO> details = checkOrderDetailMapper.selectListByOrderId(orderId);
  49 + assertEquals(2, details.size());
  50 + assertEquals(orderId, details.get(0).getOrderId());
  51 + assertEquals(orderId, details.get(1).getOrderId());
  52 + assertEquals(100L, details.get(0).getWarehouseId());
  53 + }
  54 +
  55 + @Test
  56 + public void testCreateCheckOrderDetailList_ignoreId() {
  57 + // mock 数据
  58 + WmsCheckOrderSaveReqVO reqVO = createCheckOrderReqVO(
  59 + createCheckOrderDetailReqVO(999L, 1001L, "10.00", "9.00"));
  60 +
  61 + // 调用
  62 + checkOrderDetailService.createCheckOrderDetailList(10L, reqVO);
  63 +
  64 + // 断言
  65 + List<WmsCheckOrderDetailDO> details = checkOrderDetailMapper.selectListByOrderId(10L);
  66 + assertEquals(1, details.size());
  67 + assertNotNull(details.get(0).getId());
  68 + assertEquals(1001L, details.get(0).getSkuId());
  69 + }
  70 +
  71 + @Test
  72 + public void testUpdateCheckOrderDetailList_diff() {
  73 + // mock 数据
  74 + Long orderId = 10L;
  75 + WmsCheckOrderDetailDO detail01 = createCheckOrderDetail(orderId, 1001L, "10.00", "9.00");
  76 + WmsCheckOrderDetailDO detail02 = createCheckOrderDetail(orderId, 1002L, "20.00", "21.00");
  77 + checkOrderDetailMapper.insert(detail01);
  78 + checkOrderDetailMapper.insert(detail02);
  79 + WmsCheckOrderSaveReqVO reqVO = createCheckOrderReqVO(
  80 + createCheckOrderDetailReqVO(detail01.getId(), 2001L, "11.00", "8.00"),
  81 + createCheckOrderDetailReqVO(null, 2002L, "22.00", "25.00"));
  82 +
  83 + // 调用
  84 + checkOrderDetailService.updateCheckOrderDetailList(orderId, reqVO);
  85 +
  86 + // 断言:修改
  87 + WmsCheckOrderDetailDO dbUpdateDetail = checkOrderDetailMapper.selectById(detail01.getId());
  88 + assertNotNull(dbUpdateDetail);
  89 + assertEquals(orderId, dbUpdateDetail.getOrderId());
  90 + assertEquals(2001L, dbUpdateDetail.getSkuId());
  91 + assertEquals(0, new BigDecimal("11.00").compareTo(dbUpdateDetail.getQuantity()));
  92 + assertEquals(0, new BigDecimal("8.00").compareTo(dbUpdateDetail.getCheckQuantity()));
  93 + assertEquals(100L, dbUpdateDetail.getWarehouseId());
  94 + // 断言:新增
  95 + List<WmsCheckOrderDetailDO> details = checkOrderDetailMapper.selectListByOrderId(orderId);
  96 + assertEquals(2, details.size());
  97 + WmsCheckOrderDetailDO dbCreateDetail = details.stream()
  98 + .filter(detail -> Long.valueOf(2002L).equals(detail.getSkuId()))
  99 + .findFirst().orElse(null);
  100 + assertNotNull(dbCreateDetail);
  101 + assertEquals(orderId, dbCreateDetail.getOrderId());
  102 + assertEquals(0, new BigDecimal("22.00").compareTo(dbCreateDetail.getQuantity()));
  103 + assertEquals(0, new BigDecimal("25.00").compareTo(dbCreateDetail.getCheckQuantity()));
  104 + // 断言:删除
  105 + assertNull(checkOrderDetailMapper.selectById(detail02.getId()));
  106 + }
  107 +
  108 + @Test
  109 + public void testUpdateCheckOrderDetailList_detailNotExists() {
  110 + // mock 数据
  111 + WmsCheckOrderSaveReqVO reqVO = createCheckOrderReqVO(
  112 + createCheckOrderDetailReqVO(999L, 1001L, "10.00", "9.00"));
  113 +
  114 + // 调用,并断言
  115 + assertServiceException(() -> checkOrderDetailService.updateCheckOrderDetailList(10L, reqVO),
  116 + CHECK_ORDER_DETAIL_NOT_EXISTS);
  117 + }
  118 +
  119 + private static WmsCheckOrderSaveReqVO createCheckOrderReqVO(WmsCheckOrderDetailSaveReqVO... details) {
  120 + WmsCheckOrderSaveReqVO reqVO = new WmsCheckOrderSaveReqVO();
  121 + reqVO.setWarehouseId(100L);
  122 + reqVO.setDetails(Arrays.asList(details));
  123 + return reqVO;
  124 + }
  125 +
  126 + private static WmsCheckOrderDetailSaveReqVO createCheckOrderDetailReqVO(Long id, Long skuId,
  127 + String quantity, String checkQuantity) {
  128 + WmsCheckOrderDetailSaveReqVO reqVO = new WmsCheckOrderDetailSaveReqVO();
  129 + reqVO.setId(id);
  130 + reqVO.setSkuId(skuId);
  131 + reqVO.setInventoryId(300L);
  132 + reqVO.setQuantity(new BigDecimal(quantity));
  133 + reqVO.setCheckQuantity(new BigDecimal(checkQuantity));
  134 + reqVO.setAmount(new BigDecimal("100.00"));
  135 + return reqVO;
  136 + }
  137 +
  138 + private static WmsCheckOrderDetailDO createCheckOrderDetail(Long orderId, Long skuId,
  139 + String quantity, String checkQuantity) {
  140 + return WmsCheckOrderDetailDO.builder()
  141 + .orderId(orderId)
  142 + .skuId(skuId)
  143 + .warehouseId(100L)
  144 + .inventoryId(300L)
  145 + .quantity(new BigDecimal(quantity))
  146 + .checkQuantity(new BigDecimal(checkQuantity))
  147 + .amount(new BigDecimal("100.00"))
  148 + .build();
  149 + }
  150 +
  151 +}
... ...
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/check/WmsCheckOrderServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.wms.service.order.check;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  4 +import cn.iocoder.yudao.module.wms.dal.dataobject.order.check.WmsCheckOrderDO;
  5 +import cn.iocoder.yudao.module.wms.dal.dataobject.order.check.WmsCheckOrderDetailDO;
  6 +import cn.iocoder.yudao.module.wms.dal.mysql.order.check.WmsCheckOrderDetailMapper;
  7 +import cn.iocoder.yudao.module.wms.dal.mysql.order.check.WmsCheckOrderMapper;
  8 +import cn.iocoder.yudao.module.wms.enums.inventory.WmsInventoryOrderTypeEnum;
  9 +import cn.iocoder.yudao.module.wms.enums.order.WmsOrderStatusEnum;
  10 +import cn.iocoder.yudao.module.wms.service.inventory.WmsInventoryService;
  11 +import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryChangeReqDTO;
  12 +import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService;
  13 +import cn.iocoder.yudao.module.wms.service.md.warehouse.WmsWarehouseService;
  14 +import jakarta.annotation.Resource;
  15 +import org.junit.jupiter.api.Test;
  16 +import org.mockito.ArgumentCaptor;
  17 +import org.springframework.context.annotation.Import;
  18 +import org.springframework.test.context.bean.override.mockito.MockitoBean;
  19 +
  20 +import java.math.BigDecimal;
  21 +
  22 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  23 +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_DETAIL_REQUIRED;
  24 +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.CHECK_ORDER_STATUS_NOT_DELETABLE;
  25 +import static org.junit.jupiter.api.Assertions.assertEquals;
  26 +import static org.junit.jupiter.api.Assertions.assertNotNull;
  27 +import static org.junit.jupiter.api.Assertions.assertNull;
  28 +import static org.mockito.ArgumentMatchers.any;
  29 +import static org.mockito.Mockito.never;
  30 +import static org.mockito.Mockito.verify;
  31 +
  32 +@Import({WmsCheckOrderServiceImpl.class, WmsCheckOrderDetailServiceImpl.class})
  33 +public class WmsCheckOrderServiceImplTest extends BaseDbUnitTest {
  34 +
  35 + @Resource
  36 + private WmsCheckOrderServiceImpl checkOrderService;
  37 +
  38 + @Resource
  39 + private WmsCheckOrderMapper checkOrderMapper;
  40 + @Resource
  41 + private WmsCheckOrderDetailMapper checkOrderDetailMapper;
  42 +
  43 + @MockitoBean
  44 + private WmsWarehouseService warehouseService;
  45 + @MockitoBean
  46 + private WmsItemSkuService itemSkuService;
  47 + @MockitoBean
  48 + private WmsInventoryService inventoryService;
  49 +
  50 + @Test
  51 + public void testCompleteCheckOrder_success() {
  52 + // mock 数据
  53 + Long warehouseId = 100L;
  54 + Long skuId = 200L;
  55 + WmsCheckOrderDO order = createCheckOrder(warehouseId);
  56 + checkOrderMapper.insert(order);
  57 + checkOrderDetailMapper.insert(createCheckOrderDetail(order.getId(), skuId, warehouseId,
  58 + "10.00", "7.00"));
  59 +
  60 + // 调用
  61 + checkOrderService.completeCheckOrder(order.getId());
  62 +
  63 + // 断言:盘库单
  64 + WmsCheckOrderDO dbOrder = checkOrderMapper.selectById(order.getId());
  65 + assertNotNull(dbOrder);
  66 + assertEquals(WmsOrderStatusEnum.FINISHED.getStatus(), dbOrder.getStatus());
  67 + // 断言:库存变更
  68 + ArgumentCaptor<WmsInventoryChangeReqDTO> captor = ArgumentCaptor.forClass(WmsInventoryChangeReqDTO.class);
  69 + verify(inventoryService).changeInventory(captor.capture());
  70 + WmsInventoryChangeReqDTO inventoryReqDTO = captor.getValue();
  71 + assertEquals(order.getId(), inventoryReqDTO.getOrderId());
  72 + assertEquals(order.getNo(), inventoryReqDTO.getOrderNo());
  73 + assertEquals(WmsInventoryOrderTypeEnum.CHECK.getType(), inventoryReqDTO.getOrderType());
  74 + assertEquals(1, inventoryReqDTO.getItems().size());
  75 + assertEquals(skuId, inventoryReqDTO.getItems().get(0).getSkuId());
  76 + assertEquals(warehouseId, inventoryReqDTO.getItems().get(0).getWarehouseId());
  77 + assertEquals(0, new BigDecimal("-3.00").compareTo(inventoryReqDTO.getItems().get(0).getQuantity()));
  78 + }
  79 +
  80 + @Test
  81 + public void testCompleteCheckOrder_zeroDifference() {
  82 + // mock 数据
  83 + WmsCheckOrderDO order = createCheckOrder(100L);
  84 + checkOrderMapper.insert(order);
  85 + checkOrderDetailMapper.insert(createCheckOrderDetail(order.getId(), 200L, 100L,
  86 + "10.00", "10.00"));
  87 +
  88 + // 调用
  89 + checkOrderService.completeCheckOrder(order.getId());
  90 +
  91 + // 断言
  92 + WmsCheckOrderDO dbOrder = checkOrderMapper.selectById(order.getId());
  93 + assertNotNull(dbOrder);
  94 + assertEquals(WmsOrderStatusEnum.FINISHED.getStatus(), dbOrder.getStatus());
  95 + verify(inventoryService, never()).changeInventory(any());
  96 + }
  97 +
  98 + @Test
  99 + public void testCompleteCheckOrder_detailRequired() {
  100 + // mock 数据
  101 + WmsCheckOrderDO order = createCheckOrder(100L);
  102 + checkOrderMapper.insert(order);
  103 +
  104 + // 调用,并断言
  105 + assertServiceException(() -> checkOrderService.completeCheckOrder(order.getId()),
  106 + CHECK_ORDER_DETAIL_REQUIRED);
  107 + verify(inventoryService, never()).changeInventory(any());
  108 + }
  109 +
  110 + @Test
  111 + public void testCancelCheckOrder_success() {
  112 + // mock 数据
  113 + WmsCheckOrderDO order = createCheckOrder(100L);
  114 + checkOrderMapper.insert(order);
  115 +
  116 + // 调用
  117 + checkOrderService.cancelCheckOrder(order.getId());
  118 +
  119 + // 断言
  120 + WmsCheckOrderDO dbOrder = checkOrderMapper.selectById(order.getId());
  121 + assertNotNull(dbOrder);
  122 + assertEquals(WmsOrderStatusEnum.CANCELED.getStatus(), dbOrder.getStatus());
  123 + verify(inventoryService, never()).changeInventory(any());
  124 + }
  125 +
  126 + @Test
  127 + public void testDeleteCheckOrder_canceled() {
  128 + // mock 数据
  129 + WmsCheckOrderDO order = createCheckOrder(100L).setStatus(WmsOrderStatusEnum.CANCELED.getStatus());
  130 + checkOrderMapper.insert(order);
  131 + checkOrderDetailMapper.insert(createCheckOrderDetail(order.getId(), 200L, 100L,
  132 + "10.00", "8.00"));
  133 +
  134 + // 调用
  135 + checkOrderService.deleteCheckOrder(order.getId());
  136 +
  137 + // 断言
  138 + assertNull(checkOrderMapper.selectById(order.getId()));
  139 + assertEquals(0, checkOrderDetailMapper.selectListByOrderId(order.getId()).size());
  140 + }
  141 +
  142 + @Test
  143 + public void testDeleteCheckOrder_finished() {
  144 + // mock 数据
  145 + WmsCheckOrderDO order = createCheckOrder(100L).setStatus(WmsOrderStatusEnum.FINISHED.getStatus());
  146 + checkOrderMapper.insert(order);
  147 +
  148 + // 调用,并断言
  149 + assertServiceException(() -> checkOrderService.deleteCheckOrder(order.getId()),
  150 + CHECK_ORDER_STATUS_NOT_DELETABLE);
  151 + }
  152 +
  153 + private static WmsCheckOrderDO createCheckOrder(Long warehouseId) {
  154 + return new WmsCheckOrderDO()
  155 + .setNo("PK202605120001")
  156 + .setStatus(WmsOrderStatusEnum.PREPARE.getStatus())
  157 + .setWarehouseId(warehouseId)
  158 + .setTotalQuantity(new BigDecimal("-3.00"))
  159 + .setTotalAmount(new BigDecimal("30.00"));
  160 + }
  161 +
  162 + private static WmsCheckOrderDetailDO createCheckOrderDetail(Long orderId, Long skuId, Long warehouseId,
  163 + String quantity, String checkQuantity) {
  164 + return WmsCheckOrderDetailDO.builder()
  165 + .orderId(orderId)
  166 + .skuId(skuId)
  167 + .warehouseId(warehouseId)
  168 + .inventoryId(300L)
  169 + .quantity(new BigDecimal(quantity))
  170 + .checkQuantity(new BigDecimal(checkQuantity))
  171 + .amount(new BigDecimal("30.00"))
  172 + .build();
  173 + }
  174 +
  175 +}
... ...
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/movement/WmsMovementOrderDetailServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.wms.service.order.movement;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  4 +import cn.iocoder.yudao.module.wms.controller.admin.order.movement.vo.detail.WmsMovementOrderDetailSaveReqVO;
  5 +import cn.iocoder.yudao.module.wms.controller.admin.order.movement.vo.order.WmsMovementOrderSaveReqVO;
  6 +import cn.iocoder.yudao.module.wms.dal.dataobject.order.movement.WmsMovementOrderDetailDO;
  7 +import cn.iocoder.yudao.module.wms.dal.mysql.order.movement.WmsMovementOrderDetailMapper;
  8 +import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService;
  9 +import jakarta.annotation.Resource;
  10 +import org.junit.jupiter.api.Test;
  11 +import org.springframework.context.annotation.Import;
  12 +import org.springframework.test.context.bean.override.mockito.MockitoBean;
  13 +
  14 +import java.math.BigDecimal;
  15 +import java.util.Arrays;
  16 +import java.util.List;
  17 +
  18 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  19 +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.MOVEMENT_ORDER_DETAIL_NOT_EXISTS;
  20 +import static org.junit.jupiter.api.Assertions.assertEquals;
  21 +import static org.junit.jupiter.api.Assertions.assertNotNull;
  22 +import static org.junit.jupiter.api.Assertions.assertNull;
  23 +
  24 +@Import(WmsMovementOrderDetailServiceImpl.class)
  25 +public class WmsMovementOrderDetailServiceImplTest extends BaseDbUnitTest {
  26 +
  27 + @Resource
  28 + private WmsMovementOrderDetailServiceImpl movementOrderDetailService;
  29 +
  30 + @Resource
  31 + private WmsMovementOrderDetailMapper movementOrderDetailMapper;
  32 +
  33 + @MockitoBean
  34 + private WmsItemSkuService itemSkuService;
  35 +
  36 + @Test
  37 + public void testCreateMovementOrderDetailList_success() {
  38 + // mock 数据
  39 + Long orderId = 10L;
  40 + WmsMovementOrderSaveReqVO reqVO = createMovementOrderReqVO(
  41 + createMovementOrderDetailReqVO(null, 1001L, "1.00"),
  42 + createMovementOrderDetailReqVO(null, 1002L, "2.00"));
  43 +
  44 + // 调用
  45 + movementOrderDetailService.createMovementOrderDetailList(orderId, reqVO);
  46 +
  47 + // 断言
  48 + List<WmsMovementOrderDetailDO> details = movementOrderDetailMapper.selectListByOrderId(orderId);
  49 + assertEquals(2, details.size());
  50 + assertEquals(orderId, details.get(0).getOrderId());
  51 + assertEquals(orderId, details.get(1).getOrderId());
  52 + assertEquals(100L, details.get(0).getSourceWarehouseId());
  53 + assertEquals(200L, details.get(0).getTargetWarehouseId());
  54 + }
  55 +
  56 + @Test
  57 + public void testCreateMovementOrderDetailList_ignoreId() {
  58 + // mock 数据
  59 + WmsMovementOrderSaveReqVO reqVO = createMovementOrderReqVO(
  60 + createMovementOrderDetailReqVO(999L, 1001L, "1.00"));
  61 +
  62 + // 调用
  63 + movementOrderDetailService.createMovementOrderDetailList(10L, reqVO);
  64 +
  65 + // 断言
  66 + List<WmsMovementOrderDetailDO> details = movementOrderDetailMapper.selectListByOrderId(10L);
  67 + assertEquals(1, details.size());
  68 + assertNotNull(details.get(0).getId());
  69 + assertEquals(1001L, details.get(0).getSkuId());
  70 + }
  71 +
  72 + @Test
  73 + public void testUpdateMovementOrderDetailList_diff() {
  74 + // mock 数据
  75 + Long orderId = 10L;
  76 + WmsMovementOrderDetailDO detail01 = createMovementOrderDetail(orderId, 1001L, "1.00");
  77 + WmsMovementOrderDetailDO detail02 = createMovementOrderDetail(orderId, 1002L, "2.00");
  78 + movementOrderDetailMapper.insert(detail01);
  79 + movementOrderDetailMapper.insert(detail02);
  80 + WmsMovementOrderSaveReqVO reqVO = createMovementOrderReqVO(
  81 + createMovementOrderDetailReqVO(detail01.getId(), 2001L, "11.00"),
  82 + createMovementOrderDetailReqVO(null, 2002L, "22.00"));
  83 +
  84 + // 调用
  85 + movementOrderDetailService.updateMovementOrderDetailList(orderId, reqVO);
  86 +
  87 + // 断言:修改
  88 + WmsMovementOrderDetailDO dbUpdateDetail = movementOrderDetailMapper.selectById(detail01.getId());
  89 + assertNotNull(dbUpdateDetail);
  90 + assertEquals(orderId, dbUpdateDetail.getOrderId());
  91 + assertEquals(2001L, dbUpdateDetail.getSkuId());
  92 + assertEquals(0, new BigDecimal("11.00").compareTo(dbUpdateDetail.getQuantity()));
  93 + assertEquals(100L, dbUpdateDetail.getSourceWarehouseId());
  94 + assertEquals(200L, dbUpdateDetail.getTargetWarehouseId());
  95 + // 断言:新增
  96 + List<WmsMovementOrderDetailDO> details = movementOrderDetailMapper.selectListByOrderId(orderId);
  97 + assertEquals(2, details.size());
  98 + WmsMovementOrderDetailDO dbCreateDetail = details.stream()
  99 + .filter(detail -> Long.valueOf(2002L).equals(detail.getSkuId()))
  100 + .findFirst().orElse(null);
  101 + assertNotNull(dbCreateDetail);
  102 + assertEquals(orderId, dbCreateDetail.getOrderId());
  103 + assertEquals(0, new BigDecimal("22.00").compareTo(dbCreateDetail.getQuantity()));
  104 + // 断言:删除
  105 + assertNull(movementOrderDetailMapper.selectById(detail02.getId()));
  106 + }
  107 +
  108 + @Test
  109 + public void testUpdateMovementOrderDetailList_detailNotExists() {
  110 + // mock 数据
  111 + WmsMovementOrderSaveReqVO reqVO = createMovementOrderReqVO(
  112 + createMovementOrderDetailReqVO(999L, 1001L, "1.00"));
  113 +
  114 + // 调用,并断言
  115 + assertServiceException(() -> movementOrderDetailService.updateMovementOrderDetailList(10L, reqVO),
  116 + MOVEMENT_ORDER_DETAIL_NOT_EXISTS);
  117 + }
  118 +
  119 + private static WmsMovementOrderSaveReqVO createMovementOrderReqVO(WmsMovementOrderDetailSaveReqVO... details) {
  120 + WmsMovementOrderSaveReqVO reqVO = new WmsMovementOrderSaveReqVO();
  121 + reqVO.setSourceWarehouseId(100L);
  122 + reqVO.setTargetWarehouseId(200L);
  123 + reqVO.setDetails(Arrays.asList(details));
  124 + return reqVO;
  125 + }
  126 +
  127 + private static WmsMovementOrderDetailSaveReqVO createMovementOrderDetailReqVO(Long id, Long skuId, String quantity) {
  128 + WmsMovementOrderDetailSaveReqVO reqVO = new WmsMovementOrderDetailSaveReqVO();
  129 + reqVO.setId(id);
  130 + reqVO.setSkuId(skuId);
  131 + reqVO.setQuantity(new BigDecimal(quantity));
  132 + reqVO.setAmount(new BigDecimal("100.00"));
  133 + return reqVO;
  134 + }
  135 +
  136 + private static WmsMovementOrderDetailDO createMovementOrderDetail(Long orderId, Long skuId, String quantity) {
  137 + return WmsMovementOrderDetailDO.builder()
  138 + .orderId(orderId)
  139 + .skuId(skuId)
  140 + .sourceWarehouseId(100L)
  141 + .targetWarehouseId(200L)
  142 + .quantity(new BigDecimal(quantity))
  143 + .amount(new BigDecimal("100.00"))
  144 + .build();
  145 + }
  146 +
  147 +}
... ...
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/movement/WmsMovementOrderServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.wms.service.order.movement;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  4 +import cn.iocoder.yudao.module.wms.controller.admin.order.movement.vo.order.WmsMovementOrderSaveReqVO;
  5 +import cn.iocoder.yudao.module.wms.dal.dataobject.order.movement.WmsMovementOrderDO;
  6 +import cn.iocoder.yudao.module.wms.dal.dataobject.order.movement.WmsMovementOrderDetailDO;
  7 +import cn.iocoder.yudao.module.wms.dal.mysql.order.movement.WmsMovementOrderDetailMapper;
  8 +import cn.iocoder.yudao.module.wms.dal.mysql.order.movement.WmsMovementOrderMapper;
  9 +import cn.iocoder.yudao.module.wms.enums.inventory.WmsInventoryOrderTypeEnum;
  10 +import cn.iocoder.yudao.module.wms.enums.order.WmsOrderStatusEnum;
  11 +import cn.iocoder.yudao.module.wms.service.inventory.WmsInventoryService;
  12 +import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryChangeReqDTO;
  13 +import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService;
  14 +import cn.iocoder.yudao.module.wms.service.md.warehouse.WmsWarehouseService;
  15 +import jakarta.annotation.Resource;
  16 +import org.junit.jupiter.api.Test;
  17 +import org.mockito.ArgumentCaptor;
  18 +import org.springframework.context.annotation.Import;
  19 +import org.springframework.test.context.bean.override.mockito.MockitoBean;
  20 +
  21 +import java.math.BigDecimal;
  22 +
  23 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  24 +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.MOVEMENT_ORDER_DETAIL_REQUIRED;
  25 +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.MOVEMENT_ORDER_STATUS_NOT_DELETABLE;
  26 +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.MOVEMENT_ORDER_WAREHOUSE_SAME;
  27 +import static org.junit.jupiter.api.Assertions.assertEquals;
  28 +import static org.junit.jupiter.api.Assertions.assertNotNull;
  29 +import static org.junit.jupiter.api.Assertions.assertNull;
  30 +import static org.mockito.ArgumentMatchers.any;
  31 +import static org.mockito.Mockito.never;
  32 +import static org.mockito.Mockito.verify;
  33 +
  34 +@Import({WmsMovementOrderServiceImpl.class, WmsMovementOrderDetailServiceImpl.class})
  35 +public class WmsMovementOrderServiceImplTest extends BaseDbUnitTest {
  36 +
  37 + @Resource
  38 + private WmsMovementOrderServiceImpl movementOrderService;
  39 +
  40 + @Resource
  41 + private WmsMovementOrderMapper movementOrderMapper;
  42 + @Resource
  43 + private WmsMovementOrderDetailMapper movementOrderDetailMapper;
  44 +
  45 + @MockitoBean
  46 + private WmsWarehouseService warehouseService;
  47 + @MockitoBean
  48 + private WmsItemSkuService itemSkuService;
  49 + @MockitoBean
  50 + private WmsInventoryService inventoryService;
  51 +
  52 + @Test
  53 + public void testCompleteMovementOrder_success() {
  54 + // mock 数据
  55 + Long sourceWarehouseId = 100L;
  56 + Long targetWarehouseId = 200L;
  57 + Long skuId = 300L;
  58 + WmsMovementOrderDO order = createMovementOrder(sourceWarehouseId, targetWarehouseId);
  59 + movementOrderMapper.insert(order);
  60 + movementOrderDetailMapper.insert(createMovementOrderDetail(order.getId(), skuId,
  61 + sourceWarehouseId, targetWarehouseId));
  62 +
  63 + // 调用
  64 + movementOrderService.completeMovementOrder(order.getId());
  65 +
  66 + // 断言:移库单
  67 + WmsMovementOrderDO dbOrder = movementOrderMapper.selectById(order.getId());
  68 + assertNotNull(dbOrder);
  69 + assertEquals(WmsOrderStatusEnum.FINISHED.getStatus(), dbOrder.getStatus());
  70 + // 断言:库存变更
  71 + ArgumentCaptor<WmsInventoryChangeReqDTO> captor = ArgumentCaptor.forClass(WmsInventoryChangeReqDTO.class);
  72 + verify(inventoryService).changeInventory(captor.capture());
  73 + WmsInventoryChangeReqDTO inventoryReqDTO = captor.getValue();
  74 + assertEquals(order.getId(), inventoryReqDTO.getOrderId());
  75 + assertEquals(order.getNo(), inventoryReqDTO.getOrderNo());
  76 + assertEquals(WmsInventoryOrderTypeEnum.MOVEMENT.getType(), inventoryReqDTO.getOrderType());
  77 + assertEquals(2, inventoryReqDTO.getItems().size());
  78 + assertEquals(skuId, inventoryReqDTO.getItems().get(0).getSkuId());
  79 + assertEquals(sourceWarehouseId, inventoryReqDTO.getItems().get(0).getWarehouseId());
  80 + assertEquals(0, new BigDecimal("-2.00").compareTo(inventoryReqDTO.getItems().get(0).getQuantity()));
  81 + assertEquals(skuId, inventoryReqDTO.getItems().get(1).getSkuId());
  82 + assertEquals(targetWarehouseId, inventoryReqDTO.getItems().get(1).getWarehouseId());
  83 + assertEquals(0, new BigDecimal("2.00").compareTo(inventoryReqDTO.getItems().get(1).getQuantity()));
  84 + }
  85 +
  86 + @Test
  87 + public void testCompleteMovementOrder_detailRequired() {
  88 + // mock 数据
  89 + WmsMovementOrderDO order = createMovementOrder(100L, 200L);
  90 + movementOrderMapper.insert(order);
  91 +
  92 + // 调用,并断言
  93 + assertServiceException(() -> movementOrderService.completeMovementOrder(order.getId()),
  94 + MOVEMENT_ORDER_DETAIL_REQUIRED);
  95 + verify(inventoryService, never()).changeInventory(any());
  96 + }
  97 +
  98 + @Test
  99 + public void testCreateMovementOrder_sameWarehouse() {
  100 + // 准备参数
  101 + WmsMovementOrderSaveReqVO reqVO = createMovementOrderReqVO(100L, 100L);
  102 +
  103 + // 调用,并断言
  104 + assertServiceException(() -> movementOrderService.createMovementOrder(reqVO), MOVEMENT_ORDER_WAREHOUSE_SAME);
  105 + verify(inventoryService, never()).changeInventory(any());
  106 + }
  107 +
  108 + @Test
  109 + public void testCancelMovementOrder_success() {
  110 + // mock 数据
  111 + WmsMovementOrderDO order = createMovementOrder(100L, 200L);
  112 + movementOrderMapper.insert(order);
  113 +
  114 + // 调用
  115 + movementOrderService.cancelMovementOrder(order.getId());
  116 +
  117 + // 断言
  118 + WmsMovementOrderDO dbOrder = movementOrderMapper.selectById(order.getId());
  119 + assertNotNull(dbOrder);
  120 + assertEquals(WmsOrderStatusEnum.CANCELED.getStatus(), dbOrder.getStatus());
  121 + verify(inventoryService, never()).changeInventory(any());
  122 + }
  123 +
  124 + @Test
  125 + public void testDeleteMovementOrder_canceled() {
  126 + // mock 数据
  127 + WmsMovementOrderDO order = createMovementOrder(100L, 200L).setStatus(WmsOrderStatusEnum.CANCELED.getStatus());
  128 + movementOrderMapper.insert(order);
  129 + movementOrderDetailMapper.insert(createMovementOrderDetail(order.getId(), 300L, 100L, 200L));
  130 +
  131 + // 调用
  132 + movementOrderService.deleteMovementOrder(order.getId());
  133 +
  134 + // 断言
  135 + assertNull(movementOrderMapper.selectById(order.getId()));
  136 + assertEquals(0, movementOrderDetailMapper.selectListByOrderId(order.getId()).size());
  137 + }
  138 +
  139 + @Test
  140 + public void testDeleteMovementOrder_finished() {
  141 + // mock 数据
  142 + WmsMovementOrderDO order = createMovementOrder(100L, 200L).setStatus(WmsOrderStatusEnum.FINISHED.getStatus());
  143 + movementOrderMapper.insert(order);
  144 +
  145 + // 调用,并断言
  146 + assertServiceException(() -> movementOrderService.deleteMovementOrder(order.getId()),
  147 + MOVEMENT_ORDER_STATUS_NOT_DELETABLE);
  148 + }
  149 +
  150 + private static WmsMovementOrderDO createMovementOrder(Long sourceWarehouseId, Long targetWarehouseId) {
  151 + return new WmsMovementOrderDO()
  152 + .setNo("YK202605120001")
  153 + .setStatus(WmsOrderStatusEnum.PREPARE.getStatus())
  154 + .setSourceWarehouseId(sourceWarehouseId)
  155 + .setTargetWarehouseId(targetWarehouseId)
  156 + .setTotalQuantity(new BigDecimal("2.00"))
  157 + .setTotalAmount(new BigDecimal("20.00"));
  158 + }
  159 +
  160 + private static WmsMovementOrderDetailDO createMovementOrderDetail(Long orderId, Long skuId,
  161 + Long sourceWarehouseId, Long targetWarehouseId) {
  162 + return WmsMovementOrderDetailDO.builder()
  163 + .orderId(orderId)
  164 + .skuId(skuId)
  165 + .sourceWarehouseId(sourceWarehouseId)
  166 + .targetWarehouseId(targetWarehouseId)
  167 + .quantity(new BigDecimal("2.00"))
  168 + .amount(new BigDecimal("20.00"))
  169 + .build();
  170 + }
  171 +
  172 + private static WmsMovementOrderSaveReqVO createMovementOrderReqVO(Long sourceWarehouseId, Long targetWarehouseId) {
  173 + WmsMovementOrderSaveReqVO reqVO = new WmsMovementOrderSaveReqVO();
  174 + reqVO.setNo("YK202605120001");
  175 + reqVO.setSourceWarehouseId(sourceWarehouseId);
  176 + reqVO.setTargetWarehouseId(targetWarehouseId);
  177 + reqVO.setTotalQuantity(new BigDecimal("2.00"));
  178 + reqVO.setTotalAmount(new BigDecimal("20.00"));
  179 + return reqVO;
  180 + }
  181 +
  182 +}
... ...
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/shipment/WmsShipmentOrderDetailServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.wms.service.order.shipment;
  2 +
  3 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  4 +import cn.iocoder.yudao.module.wms.controller.admin.order.shipment.vo.detail.WmsShipmentOrderDetailSaveReqVO;
  5 +import cn.iocoder.yudao.module.wms.controller.admin.order.shipment.vo.order.WmsShipmentOrderSaveReqVO;
  6 +import cn.iocoder.yudao.module.wms.dal.dataobject.order.shipment.WmsShipmentOrderDetailDO;
  7 +import cn.iocoder.yudao.module.wms.dal.mysql.order.shipment.WmsShipmentOrderDetailMapper;
  8 +import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService;
  9 +import jakarta.annotation.Resource;
  10 +import org.junit.jupiter.api.Test;
  11 +import org.springframework.context.annotation.Import;
  12 +import org.springframework.test.context.bean.override.mockito.MockitoBean;
  13 +
  14 +import java.math.BigDecimal;
  15 +import java.util.Arrays;
  16 +import java.util.List;
  17 +
  18 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  19 +import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.SHIPMENT_ORDER_DETAIL_NOT_EXISTS;
  20 +import static org.junit.jupiter.api.Assertions.assertEquals;
  21 +import static org.junit.jupiter.api.Assertions.assertNotNull;
  22 +import static org.junit.jupiter.api.Assertions.assertNull;
  23 +
  24 +@Import(WmsShipmentOrderDetailServiceImpl.class)
  25 +public class WmsShipmentOrderDetailServiceImplTest extends BaseDbUnitTest {
  26 +
  27 + @Resource
  28 + private WmsShipmentOrderDetailServiceImpl shipmentOrderDetailService;
  29 +
  30 + @Resource
  31 + private WmsShipmentOrderDetailMapper shipmentOrderDetailMapper;
  32 +
  33 + @MockitoBean
  34 + private WmsItemSkuService itemSkuService;
  35 +
  36 + @Test
  37 + public void testCreateShipmentOrderDetailList_success() {
  38 + // mock 数据
  39 + Long orderId = 10L;
  40 + WmsShipmentOrderSaveReqVO reqVO = createShipmentOrderReqVO(
  41 + createShipmentOrderDetailReqVO(null, 1001L, "1.00"),
  42 + createShipmentOrderDetailReqVO(null, 1002L, "2.00"));
  43 +
  44 + // 调用
  45 + shipmentOrderDetailService.createShipmentOrderDetailList(orderId, reqVO);
  46 +
  47 + // 断言
  48 + List<WmsShipmentOrderDetailDO> details = shipmentOrderDetailMapper.selectListByOrderId(orderId);
  49 + assertEquals(2, details.size());
  50 + assertEquals(orderId, details.get(0).getOrderId());
  51 + assertEquals(orderId, details.get(1).getOrderId());
  52 + assertEquals(100L, details.get(0).getWarehouseId());
  53 + }
  54 +
  55 + @Test
  56 + public void testCreateShipmentOrderDetailList_ignoreId() {
  57 + // mock 数据
  58 + WmsShipmentOrderSaveReqVO reqVO = createShipmentOrderReqVO(
  59 + createShipmentOrderDetailReqVO(999L, 1001L, "1.00"));
  60 +
  61 + // 调用
  62 + shipmentOrderDetailService.createShipmentOrderDetailList(10L, reqVO);
  63 +
  64 + // 断言
  65 + List<WmsShipmentOrderDetailDO> details = shipmentOrderDetailMapper.selectListByOrderId(10L);
  66 + assertEquals(1, details.size());
  67 + assertNotNull(details.get(0).getId());
  68 + assertEquals(1001L, details.get(0).getSkuId());
  69 + }
  70 +
  71 + @Test
  72 + public void testUpdateShipmentOrderDetailList_diff() {
  73 + // mock 数据
  74 + Long orderId = 10L;
  75 + WmsShipmentOrderDetailDO detail01 = createShipmentOrderDetail(orderId, 1001L, "1.00");
  76 + WmsShipmentOrderDetailDO detail02 = createShipmentOrderDetail(orderId, 1002L, "2.00");
  77 + shipmentOrderDetailMapper.insert(detail01);
  78 + shipmentOrderDetailMapper.insert(detail02);
  79 + WmsShipmentOrderSaveReqVO reqVO = createShipmentOrderReqVO(
  80 + createShipmentOrderDetailReqVO(detail01.getId(), 2001L, "11.00"),
  81 + createShipmentOrderDetailReqVO(null, 2002L, "22.00"));
  82 +
  83 + // 调用
  84 + shipmentOrderDetailService.updateShipmentOrderDetailList(orderId, reqVO);
  85 +
  86 + // 断言:修改
  87 + WmsShipmentOrderDetailDO dbUpdateDetail = shipmentOrderDetailMapper.selectById(detail01.getId());
  88 + assertNotNull(dbUpdateDetail);
  89 + assertEquals(orderId, dbUpdateDetail.getOrderId());
  90 + assertEquals(2001L, dbUpdateDetail.getSkuId());
  91 + assertEquals(0, new BigDecimal("11.00").compareTo(dbUpdateDetail.getQuantity()));
  92 + // 断言:新增
  93 + List<WmsShipmentOrderDetailDO> details = shipmentOrderDetailMapper.selectListByOrderId(orderId);
  94 + assertEquals(2, details.size());
  95 + WmsShipmentOrderDetailDO dbCreateDetail = details.stream()
  96 + .filter(detail -> Long.valueOf(2002L).equals(detail.getSkuId()))
  97 + .findFirst().orElse(null);
  98 + assertNotNull(dbCreateDetail);
  99 + assertEquals(orderId, dbCreateDetail.getOrderId());
  100 + assertEquals(0, new BigDecimal("22.00").compareTo(dbCreateDetail.getQuantity()));
  101 + // 断言:删除
  102 + assertNull(shipmentOrderDetailMapper.selectById(detail02.getId()));
  103 + }
  104 +
  105 + @Test
  106 + public void testUpdateShipmentOrderDetailList_detailNotExists() {
  107 + // mock 数据
  108 + WmsShipmentOrderSaveReqVO reqVO = createShipmentOrderReqVO(
  109 + createShipmentOrderDetailReqVO(999L, 1001L, "1.00"));
  110 +
  111 + // 调用,并断言
  112 + assertServiceException(() -> shipmentOrderDetailService.updateShipmentOrderDetailList(10L, reqVO),
  113 + SHIPMENT_ORDER_DETAIL_NOT_EXISTS);
  114 + }
  115 +
  116 + private static WmsShipmentOrderSaveReqVO createShipmentOrderReqVO(WmsShipmentOrderDetailSaveReqVO... details) {
  117 + WmsShipmentOrderSaveReqVO reqVO = new WmsShipmentOrderSaveReqVO();
  118 + reqVO.setWarehouseId(100L);
  119 + reqVO.setDetails(Arrays.asList(details));
  120 + return reqVO;
  121 + }
  122 +
  123 + private static WmsShipmentOrderDetailSaveReqVO createShipmentOrderDetailReqVO(Long id, Long skuId, String quantity) {
  124 + WmsShipmentOrderDetailSaveReqVO reqVO = new WmsShipmentOrderDetailSaveReqVO();
  125 + reqVO.setId(id);
  126 + reqVO.setSkuId(skuId);
  127 + reqVO.setQuantity(new BigDecimal(quantity));
  128 + reqVO.setAmount(new BigDecimal("100.00"));
  129 + return reqVO;
  130 + }
  131 +
  132 + private static WmsShipmentOrderDetailDO createShipmentOrderDetail(Long orderId, Long skuId, String quantity) {
  133 + return WmsShipmentOrderDetailDO.builder()
  134 + .orderId(orderId)
  135 + .skuId(skuId)
  136 + .warehouseId(100L)
  137 + .quantity(new BigDecimal(quantity))
  138 + .amount(new BigDecimal("100.00"))
  139 + .build();
  140 + }
  141 +
  142 +}
... ...
yudao-module-wms/src/test/resources/sql/clean.sql
  1 +DELETE FROM "wms_check_order_detail";
  2 +DELETE FROM "wms_check_order";
  3 +DELETE FROM "wms_movement_order_detail";
  4 +DELETE FROM "wms_movement_order";
1 5 DELETE FROM "wms_shipment_order_detail";
2 6 DELETE FROM "wms_shipment_order";
3 7 DELETE FROM "wms_receipt_order_detail";
... ...
yudao-module-wms/src/test/resources/sql/create_tables.sql
... ... @@ -60,9 +60,6 @@ CREATE TABLE IF NOT EXISTS &quot;wms_inventory_history&quot; (
60 60 "quantity" decimal(24, 6) NOT NULL DEFAULT '0',
61 61 "before_quantity" decimal(24, 6) DEFAULT NULL,
62 62 "after_quantity" decimal(24, 6) DEFAULT NULL,
63   - "batch_no" varchar(64) DEFAULT NULL,
64   - "production_date" timestamp DEFAULT NULL,
65   - "expiration_date" timestamp DEFAULT NULL,
66 63 "amount" decimal(24, 6) DEFAULT NULL,
67 64 "remark" varchar(255) DEFAULT NULL,
68 65 "order_id" bigint DEFAULT NULL,
... ... @@ -103,9 +100,6 @@ CREATE TABLE IF NOT EXISTS &quot;wms_receipt_order_detail&quot; (
103 100 "order_id" bigint NOT NULL,
104 101 "sku_id" bigint NOT NULL,
105 102 "warehouse_id" bigint NOT NULL,
106   - "batch_no" varchar(64) DEFAULT NULL,
107   - "production_date" timestamp DEFAULT NULL,
108   - "expiration_date" timestamp DEFAULT NULL,
109 103 "quantity" decimal(20, 2) NOT NULL DEFAULT '0',
110 104 "amount" decimal(10, 2) DEFAULT NULL,
111 105 "creator" varchar(64) DEFAULT '',
... ... @@ -143,9 +137,6 @@ CREATE TABLE IF NOT EXISTS &quot;wms_shipment_order_detail&quot; (
143 137 "order_id" bigint NOT NULL,
144 138 "sku_id" bigint NOT NULL,
145 139 "warehouse_id" bigint NOT NULL,
146   - "batch_no" varchar(64) DEFAULT NULL,
147   - "production_date" timestamp DEFAULT NULL,
148   - "expiration_date" timestamp DEFAULT NULL,
149 140 "quantity" decimal(20, 2) NOT NULL DEFAULT '0',
150 141 "amount" decimal(10, 2) DEFAULT NULL,
151 142 "creator" varchar(64) DEFAULT '',
... ... @@ -156,3 +147,76 @@ CREATE TABLE IF NOT EXISTS &quot;wms_shipment_order_detail&quot; (
156 147 "tenant_id" bigint NOT NULL DEFAULT '0',
157 148 PRIMARY KEY ("id")
158 149 ) COMMENT 'WMS 出库单明细表';
  150 +
  151 +CREATE TABLE IF NOT EXISTS "wms_movement_order" (
  152 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  153 + "no" varchar(64) NOT NULL,
  154 + "status" int NOT NULL DEFAULT '0',
  155 + "remark" varchar(255) DEFAULT NULL,
  156 + "source_warehouse_id" bigint NOT NULL,
  157 + "target_warehouse_id" bigint NOT NULL,
  158 + "total_quantity" decimal(20, 2) NOT NULL DEFAULT '0',
  159 + "total_amount" decimal(10, 2) DEFAULT NULL,
  160 + "creator" varchar(64) DEFAULT '',
  161 + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  162 + "updater" varchar(64) DEFAULT '',
  163 + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  164 + "deleted" bit NOT NULL DEFAULT FALSE,
  165 + "tenant_id" bigint NOT NULL DEFAULT '0',
  166 + PRIMARY KEY ("id")
  167 +) COMMENT 'WMS 移库单表';
  168 +
  169 +CREATE TABLE IF NOT EXISTS "wms_movement_order_detail" (
  170 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  171 + "remark" varchar(255) DEFAULT NULL,
  172 + "order_id" bigint NOT NULL,
  173 + "sku_id" bigint NOT NULL,
  174 + "source_warehouse_id" bigint NOT NULL,
  175 + "target_warehouse_id" bigint NOT NULL,
  176 + "quantity" decimal(20, 2) NOT NULL DEFAULT '0',
  177 + "amount" decimal(10, 2) DEFAULT NULL,
  178 + "creator" varchar(64) DEFAULT '',
  179 + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  180 + "updater" varchar(64) DEFAULT '',
  181 + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  182 + "deleted" bit NOT NULL DEFAULT FALSE,
  183 + "tenant_id" bigint NOT NULL DEFAULT '0',
  184 + PRIMARY KEY ("id")
  185 +) COMMENT 'WMS 移库单明细表';
  186 +
  187 +CREATE TABLE IF NOT EXISTS "wms_check_order" (
  188 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  189 + "no" varchar(64) NOT NULL,
  190 + "status" int NOT NULL DEFAULT '0',
  191 + "remark" varchar(255) DEFAULT NULL,
  192 + "warehouse_id" bigint NOT NULL,
  193 + "total_quantity" decimal(20, 2) NOT NULL DEFAULT '0',
  194 + "total_amount" decimal(10, 2) DEFAULT NULL,
  195 + "creator" varchar(64) DEFAULT '',
  196 + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  197 + "updater" varchar(64) DEFAULT '',
  198 + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  199 + "deleted" bit NOT NULL DEFAULT FALSE,
  200 + "tenant_id" bigint NOT NULL DEFAULT '0',
  201 + PRIMARY KEY ("id")
  202 +) COMMENT 'WMS 盘库单表';
  203 +
  204 +CREATE TABLE IF NOT EXISTS "wms_check_order_detail" (
  205 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  206 + "remark" varchar(255) DEFAULT NULL,
  207 + "order_id" bigint NOT NULL,
  208 + "sku_id" bigint NOT NULL,
  209 + "warehouse_id" bigint NOT NULL,
  210 + "inventory_id" bigint DEFAULT NULL,
  211 + "receipt_time" timestamp DEFAULT NULL,
  212 + "quantity" decimal(20, 2) NOT NULL DEFAULT '0',
  213 + "check_quantity" decimal(20, 2) NOT NULL DEFAULT '0',
  214 + "amount" decimal(10, 2) DEFAULT NULL,
  215 + "creator" varchar(64) DEFAULT '',
  216 + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  217 + "updater" varchar(64) DEFAULT '',
  218 + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  219 + "deleted" bit NOT NULL DEFAULT FALSE,
  220 + "tenant_id" bigint NOT NULL DEFAULT '0',
  221 + PRIMARY KEY ("id")
  222 +) COMMENT 'WMS 盘库单明细表';
... ...