Commit a1d2f849a6dfd5cd772ab70213bdb084de8a4208

Authored by YunaiV
1 parent 45dcdb11

feat(wms):减法,去掉 detail 表,和 mes 更对齐

Showing 29 changed files with 11 additions and 898 deletions
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/inventory/WmsInventoryDetailController.java deleted
1 -package cn.iocoder.yudao.module.wms.controller.admin.inventory;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
5 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
6 -import cn.iocoder.yudao.framework.common.util.collection.MapUtils;  
7 -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;  
8 -import cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.detail.WmsInventoryDetailPageReqVO;  
9 -import cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.detail.WmsInventoryDetailRespVO;  
10 -import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDetailDO;  
11 -import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO;  
12 -import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;  
13 -import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseAreaDO;  
14 -import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseDO;  
15 -import cn.iocoder.yudao.module.wms.framework.config.WmsProperties;  
16 -import cn.iocoder.yudao.module.wms.service.inventory.WmsInventoryDetailService;  
17 -import cn.iocoder.yudao.module.wms.service.md.item.WmsItemService;  
18 -import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService;  
19 -import cn.iocoder.yudao.module.wms.service.md.warehouse.WmsWarehouseAreaService;  
20 -import cn.iocoder.yudao.module.wms.service.md.warehouse.WmsWarehouseService;  
21 -import io.swagger.v3.oas.annotations.Operation;  
22 -import io.swagger.v3.oas.annotations.tags.Tag;  
23 -import jakarta.annotation.Resource;  
24 -import jakarta.validation.Valid;  
25 -import org.springframework.security.access.prepost.PreAuthorize;  
26 -import org.springframework.validation.annotation.Validated;  
27 -import org.springframework.web.bind.annotation.GetMapping;  
28 -import org.springframework.web.bind.annotation.RequestMapping;  
29 -import org.springframework.web.bind.annotation.RestController;  
30 -  
31 -import java.util.Collections;  
32 -import java.util.List;  
33 -import java.util.Map;  
34 -  
35 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
36 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;  
37 -  
38 -@Tag(name = "管理后台 - WMS 库存明细")  
39 -@RestController  
40 -@RequestMapping("/wms/inventory-detail")  
41 -@Validated  
42 -public class WmsInventoryDetailController {  
43 -  
44 - @Resource  
45 - private WmsInventoryDetailService inventoryDetailService;  
46 - @Resource  
47 - private WmsItemService itemService;  
48 - @Resource  
49 - private WmsItemSkuService itemSkuService;  
50 - @Resource  
51 - private WmsWarehouseService warehouseService;  
52 - @Resource  
53 - private WmsWarehouseAreaService warehouseAreaService;  
54 - @Resource  
55 - private WmsProperties wmsProperties;  
56 -  
57 - @GetMapping("/page")  
58 - @Operation(summary = "获得库存明细分页")  
59 - @PreAuthorize("@ss.hasPermission('wms:inventory-detail:query')")  
60 - public CommonResult<PageResult<WmsInventoryDetailRespVO>> getInventoryDetailPage(  
61 - @Valid WmsInventoryDetailPageReqVO pageReqVO) {  
62 - PageResult<WmsInventoryDetailDO> pageResult = inventoryDetailService.getInventoryDetailPage(pageReqVO);  
63 - return success(new PageResult<>(buildInventoryDetailRespVOList(pageResult.getList()), pageResult.getTotal()));  
64 - }  
65 -  
66 - // ==================== 拼接 VO ====================  
67 -  
68 - private List<WmsInventoryDetailRespVO> buildInventoryDetailRespVOList(List<WmsInventoryDetailDO> list) {  
69 - if (CollUtil.isEmpty(list)) {  
70 - return Collections.emptyList();  
71 - }  
72 - Map<Long, WmsItemSkuDO> skuMap = itemSkuService.getItemSkuMap(convertSet(list, WmsInventoryDetailDO::getSkuId));  
73 - Map<Long, WmsItemDO> itemMap = itemService.getItemMap(convertSet(skuMap.values(), WmsItemSkuDO::getItemId));  
74 - Map<Long, WmsWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(  
75 - convertSet(list, WmsInventoryDetailDO::getWarehouseId));  
76 - Map<Long, WmsWarehouseAreaDO> areaMap = wmsProperties.isAreaEnabled()  
77 - ? warehouseAreaService.getWarehouseAreaMap(convertSet(list, WmsInventoryDetailDO::getAreaId))  
78 - : Collections.emptyMap();  
79 - return BeanUtils.toBean(list, WmsInventoryDetailRespVO.class, vo -> {  
80 - MapUtils.findAndThen(skuMap, vo.getSkuId(), sku -> {  
81 - vo.setSkuCode(sku.getCode()).setSkuName(sku.getName()).setItemId(sku.getItemId());  
82 - MapUtils.findAndThen(itemMap, sku.getItemId(), item -> vo.setItemCode(item.getCode())  
83 - .setItemName(item.getName()).setUnit(item.getUnit()));  
84 - });  
85 - MapUtils.findAndThen(warehouseMap, vo.getWarehouseId(), warehouse -> vo.setWarehouseName(warehouse.getName()));  
86 - MapUtils.findAndThen(areaMap, vo.getAreaId(), area -> vo.setAreaName(area.getName()));  
87 - });  
88 - }  
89 -  
90 -}  
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/inventory/vo/detail/WmsInventoryDetailPageReqVO.java deleted
1 -package cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.detail;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
4 -import io.swagger.v3.oas.annotations.media.Schema;  
5 -import lombok.Data;  
6 -import lombok.EqualsAndHashCode;  
7 -import lombok.ToString;  
8 -import org.springframework.format.annotation.DateTimeFormat;  
9 -  
10 -import java.math.BigDecimal;  
11 -import java.time.LocalDateTime;  
12 -  
13 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
14 -  
15 -@Schema(description = "管理后台 - WMS 库存明细分页 Request VO")  
16 -@Data  
17 -@EqualsAndHashCode(callSuper = true)  
18 -@ToString(callSuper = true)  
19 -public class WmsInventoryDetailPageReqVO extends PageParam {  
20 -  
21 - /**  
22 - * 按仓库库区维度统计  
23 - */  
24 - public static final String TYPE_WAREHOUSE = "warehouse";  
25 - /**  
26 - * 按商品维度统计  
27 - */  
28 - public static final String TYPE_ITEM = "item";  
29 -  
30 - @Schema(description = "统计维度", example = "warehouse")  
31 - private String type;  
32 -  
33 - @Schema(description = "商品编号", example = "ITEM001")  
34 - private String itemCode;  
35 -  
36 - @Schema(description = "商品名称", example = "红富士苹果")  
37 - private String itemName;  
38 -  
39 - @Schema(description = "商品 SKU 编号", example = "1024")  
40 - private Long skuId;  
41 -  
42 - @Schema(description = "规格编号", example = "SKU001")  
43 - private String skuCode;  
44 -  
45 - @Schema(description = "规格名称", example = "10kg 箱装")  
46 - private String skuName;  
47 -  
48 - @Schema(description = "仓库编号", example = "2048")  
49 - private Long warehouseId;  
50 -  
51 - @Schema(description = "库区编号", example = "4096")  
52 - private Long areaId;  
53 -  
54 - @Schema(description = "批号", example = "BATCH001")  
55 - private String batchNo;  
56 -  
57 - @Schema(description = "最小剩余库存数量", example = "0.01")  
58 - private BigDecimal minRemainQuantity;  
59 -  
60 - @Schema(description = "距离过期天数", example = "30")  
61 - private Integer daysToExpires;  
62 -  
63 - @Schema(description = "创建时间")  
64 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
65 - private LocalDateTime[] createTime;  
66 -  
67 -}  
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/inventory/vo/detail/WmsInventoryDetailRespVO.java deleted
1 -package cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.detail;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import lombok.Data;  
5 -  
6 -import java.math.BigDecimal;  
7 -import java.time.LocalDateTime;  
8 -  
9 -@Schema(description = "管理后台 - WMS 库存明细 Response VO")  
10 -@Data  
11 -public class WmsInventoryDetailRespVO {  
12 -  
13 - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")  
14 - private Long id;  
15 -  
16 - @Schema(description = "商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")  
17 - private Long itemId;  
18 - @Schema(description = "商品编码", example = "ITEM001")  
19 - private String itemCode;  
20 - @Schema(description = "商品名称", example = "红富士苹果")  
21 - private String itemName;  
22 - @Schema(description = "商品单位", example = "箱")  
23 - private String unit;  
24 -  
25 - @Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4096")  
26 - private Long skuId;  
27 - @Schema(description = "规格编号", example = "SKU001")  
28 - private String skuCode;  
29 - @Schema(description = "规格名称", example = "10kg 箱装")  
30 - private String skuName;  
31 -  
32 - @Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8192")  
33 - private Long warehouseId;  
34 - @Schema(description = "仓库名称", example = "成品仓")  
35 - private String warehouseName;  
36 - @Schema(description = "库区编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")  
37 - private Long areaId;  
38 - @Schema(description = "库区名称", example = "A 区")  
39 - private String areaName;  
40 -  
41 - @Schema(description = "数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")  
42 - private BigDecimal quantity;  
43 - @Schema(description = "剩余数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "60.00")  
44 - private BigDecimal remainQuantity;  
45 - @Schema(description = "批号", example = "BATCH001")  
46 - private String batchNo;  
47 - @Schema(description = "生产日期")  
48 - private LocalDateTime productionDate;  
49 - @Schema(description = "过期日期")  
50 - private LocalDateTime expirationDate;  
51 - @Schema(description = "金额", example = "1000.00")  
52 - private BigDecimal amount;  
53 - @Schema(description = "备注", example = "备注")  
54 - private String remark;  
55 -  
56 - @Schema(description = "操作单编号", example = "1024")  
57 - private Long orderId;  
58 - @Schema(description = "操作单号", example = "RK202605110001")  
59 - private String orderNo;  
60 - @Schema(description = "操作类型", example = "1")  
61 - private Integer orderType;  
62 - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)  
63 - private LocalDateTime createTime;  
64 -  
65 -}  
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/check/vo/detail/WmsCheckOrderDetailRespVO.java
@@ -52,9 +52,6 @@ public class WmsCheckOrderDetailRespVO { @@ -52,9 +52,6 @@ public class WmsCheckOrderDetailRespVO {
52 @Schema(description = "库存编号", example = "1024") 52 @Schema(description = "库存编号", example = "1024")
53 private Long inventoryId; 53 private Long inventoryId;
54 54
55 - @Schema(description = "库存明细编号", example = "1024")  
56 - private Long inventoryDetailId;  
57 -  
58 @Schema(description = "批号", example = "B202605110001") 55 @Schema(description = "批号", example = "B202605110001")
59 private String batchNo; 56 private String batchNo;
60 57
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/check/vo/detail/WmsCheckOrderDetailSaveReqVO.java
@@ -26,9 +26,6 @@ public class WmsCheckOrderDetailSaveReqVO { @@ -26,9 +26,6 @@ public class WmsCheckOrderDetailSaveReqVO {
26 @Schema(description = "库存编号", example = "1024") 26 @Schema(description = "库存编号", example = "1024")
27 private Long inventoryId; 27 private Long inventoryId;
28 28
29 - @Schema(description = "库存明细编号", example = "1024")  
30 - private Long inventoryDetailId;  
31 -  
32 @Schema(description = "批号", example = "B202605110001") 29 @Schema(description = "批号", example = "B202605110001")
33 @Size(max = 64, message = "批号长度不能超过 64 个字符") 30 @Size(max = 64, message = "批号长度不能超过 64 个字符")
34 private String batchNo; 31 private String batchNo;
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/movement/vo/detail/WmsMovementOrderDetailRespVO.java
@@ -61,9 +61,6 @@ public class WmsMovementOrderDetailRespVO { @@ -61,9 +61,6 @@ public class WmsMovementOrderDetailRespVO {
61 @Schema(description = "目标库区名称", example = "上海库区01") 61 @Schema(description = "目标库区名称", example = "上海库区01")
62 private String targetAreaName; 62 private String targetAreaName;
63 63
64 - @Schema(description = "库存明细编号", example = "1024")  
65 - private Long inventoryDetailId;  
66 -  
67 @Schema(description = "批号", example = "B202605110001") 64 @Schema(description = "批号", example = "B202605110001")
68 private String batchNo; 65 private String batchNo;
69 66
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/movement/vo/detail/WmsMovementOrderDetailSaveReqVO.java
@@ -26,9 +26,6 @@ public class WmsMovementOrderDetailSaveReqVO { @@ -26,9 +26,6 @@ public class WmsMovementOrderDetailSaveReqVO {
26 @Schema(description = "目标库区编号", example = "2048") 26 @Schema(description = "目标库区编号", example = "2048")
27 private Long targetAreaId; 27 private Long targetAreaId;
28 28
29 - @Schema(description = "库存明细编号", example = "1024")  
30 - private Long inventoryDetailId;  
31 -  
32 @Schema(description = "批号", example = "B202605110001") 29 @Schema(description = "批号", example = "B202605110001")
33 @Size(max = 64, message = "批号长度不能超过 64 个字符") 30 @Size(max = 64, message = "批号长度不能超过 64 个字符")
34 private String batchNo; 31 private String batchNo;
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/shipment/vo/detail/WmsShipmentOrderDetailRespVO.java
@@ -49,9 +49,6 @@ public class WmsShipmentOrderDetailRespVO { @@ -49,9 +49,6 @@ public class WmsShipmentOrderDetailRespVO {
49 @Schema(description = "库区名称", example = "北京库区01") 49 @Schema(description = "库区名称", example = "北京库区01")
50 private String areaName; 50 private String areaName;
51 51
52 - @Schema(description = "库存明细编号", example = "1024")  
53 - private Long inventoryDetailId;  
54 -  
55 @Schema(description = "批号", example = "B202605110001") 52 @Schema(description = "批号", example = "B202605110001")
56 private String batchNo; 53 private String batchNo;
57 54
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/controller/admin/order/shipment/vo/detail/WmsShipmentOrderDetailSaveReqVO.java
@@ -23,9 +23,6 @@ public class WmsShipmentOrderDetailSaveReqVO { @@ -23,9 +23,6 @@ public class WmsShipmentOrderDetailSaveReqVO {
23 @Schema(description = "库区编号", example = "1024") 23 @Schema(description = "库区编号", example = "1024")
24 private Long areaId; 24 private Long areaId;
25 25
26 - @Schema(description = "库存明细编号", example = "1024")  
27 - private Long inventoryDetailId;  
28 -  
29 @Schema(description = "批号", example = "B202605110001") 26 @Schema(description = "批号", example = "B202605110001")
30 @Size(max = 64, message = "批号长度不能超过 64 个字符") 27 @Size(max = 64, message = "批号长度不能超过 64 个字符")
31 private String batchNo; 28 private String batchNo;
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/inventory/WmsInventoryDetailDO.java deleted
1 -package cn.iocoder.yudao.module.wms.dal.dataobject.inventory;  
2 -  
3 -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;  
4 -import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;  
5 -import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseAreaDO;  
6 -import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseDO;  
7 -import cn.iocoder.yudao.module.wms.enums.inventory.WmsInventoryOrderTypeEnum;  
8 -import com.baomidou.mybatisplus.annotation.KeySequence;  
9 -import com.baomidou.mybatisplus.annotation.TableId;  
10 -import com.baomidou.mybatisplus.annotation.TableName;  
11 -import lombok.*;  
12 -  
13 -import java.math.BigDecimal;  
14 -import java.time.LocalDateTime;  
15 -  
16 -/**  
17 - * WMS 库存明细 DO  
18 - * <p>  
19 - * 记录可用库存明细余额,用于按库区、批次、效期扣减库存。  
20 - * 库存操作流水见 {@link WmsInventoryHistoryDO}。  
21 - *  
22 - * @author 芋道源码  
23 - */  
24 -@TableName("wms_inventory_detail")  
25 -@KeySequence("wms_inventory_detail_seq")  
26 -@Data  
27 -@EqualsAndHashCode(callSuper = true)  
28 -@ToString(callSuper = true)  
29 -@Builder  
30 -@NoArgsConstructor  
31 -@AllArgsConstructor  
32 -public class WmsInventoryDetailDO extends BaseDO {  
33 -  
34 - /**  
35 - * 主键编号  
36 - */  
37 - @TableId  
38 - private Long id;  
39 -  
40 - // ========= 库存维度相关字段 =========  
41 -  
42 - /**  
43 - * 商品 SKU 编号  
44 - *  
45 - * 关联 {@link WmsItemSkuDO#getId()}  
46 - */  
47 - private Long skuId;  
48 - /**  
49 - * 仓库编号  
50 - *  
51 - * 关联 {@link WmsWarehouseDO#getId()}  
52 - */  
53 - private Long warehouseId;  
54 - /**  
55 - * 库区编号  
56 - *  
57 - * 关联 {@link WmsWarehouseAreaDO#getId()}  
58 - */  
59 - private Long areaId;  
60 - /**  
61 - * 数量  
62 - */  
63 - private BigDecimal quantity;  
64 - /**  
65 - * 剩余数量  
66 - */  
67 - private BigDecimal remainQuantity;  
68 -  
69 - // ========= 批次效期相关字段 =========  
70 -  
71 - /**  
72 - * 批号  
73 - */  
74 - private String batchNo;  
75 - /**  
76 - * 生产日期  
77 - */  
78 - private LocalDateTime productionDate;  
79 - /**  
80 - * 过期日期  
81 - */  
82 - private LocalDateTime expirationDate;  
83 -  
84 - // ========= 金额备注相关字段 =========  
85 -  
86 - /**  
87 - * 金额(小计、非单价)  
88 - */  
89 - private BigDecimal amount;  
90 - /**  
91 - * 备注  
92 - */  
93 - private String remark;  
94 -  
95 - // ========= 来源单据相关字段 =========  
96 -  
97 - /**  
98 - * 操作单编号  
99 - *  
100 - * 关联来源单据的主键编号,单据类型见 {@link #orderType}  
101 - */  
102 - private Long orderId;  
103 - /**  
104 - * 操作单号  
105 - *  
106 - * 关联来源单据的单号,单据类型见 {@link #orderType}  
107 - */  
108 - private String orderNo;  
109 - /**  
110 - * 操作类型  
111 - *  
112 - * 枚举 {@link WmsInventoryOrderTypeEnum#getType()}  
113 - */  
114 - private Integer orderType;  
115 -  
116 -}  
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/order/check/WmsCheckOrderDetailDO.java
@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.wms.dal.dataobject.order.check; @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.wms.dal.dataobject.order.check;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDO; 4 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDO;
5 -import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDetailDO;  
6 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO; 5 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;
7 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseAreaDO; 6 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseAreaDO;
8 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseDO; 7 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseDO;
@@ -74,12 +73,6 @@ public class WmsCheckOrderDetailDO extends BaseDO { @@ -74,12 +73,6 @@ public class WmsCheckOrderDetailDO extends BaseDO {
74 * 关联 {@link WmsInventoryDO#getId()} 73 * 关联 {@link WmsInventoryDO#getId()}
75 */ 74 */
76 private Long inventoryId; 75 private Long inventoryId;
77 - /**  
78 - * 库存明细编号  
79 - *  
80 - * 关联 {@link WmsInventoryDetailDO#getId()}  
81 - */  
82 - private Long inventoryDetailId;  
83 76
84 // ========= 批次效期字段 ========= 77 // ========= 批次效期字段 =========
85 78
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/order/movement/WmsMovementOrderDetailDO.java
1 package cn.iocoder.yudao.module.wms.dal.dataobject.order.movement; 1 package cn.iocoder.yudao.module.wms.dal.dataobject.order.movement;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 -import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDetailDO;  
5 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO; 4 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;
6 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseAreaDO; 5 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseAreaDO;
7 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseDO; 6 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseDO;
@@ -67,12 +66,6 @@ public class WmsMovementOrderDetailDO extends BaseDO { @@ -67,12 +66,6 @@ public class WmsMovementOrderDetailDO extends BaseDO {
67 * 关联 {@link WmsWarehouseAreaDO#getId()} 66 * 关联 {@link WmsWarehouseAreaDO#getId()}
68 */ 67 */
69 private Long sourceAreaId; 68 private Long sourceAreaId;
70 - /**  
71 - * 库存明细编号  
72 - *  
73 - * 关联 {@link WmsInventoryDetailDO#getId()}  
74 - */  
75 - private Long inventoryDetailId;  
76 69
77 // ========= 目标仓库库区字段 ========= 70 // ========= 目标仓库库区字段 =========
78 71
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/dataobject/order/shipment/WmsShipmentOrderDetailDO.java
1 package cn.iocoder.yudao.module.wms.dal.dataobject.order.shipment; 1 package cn.iocoder.yudao.module.wms.dal.dataobject.order.shipment;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 -import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDetailDO;  
5 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO; 4 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;
6 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseAreaDO; 5 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseAreaDO;
7 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseDO; 6 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseDO;
@@ -67,12 +66,6 @@ public class WmsShipmentOrderDetailDO extends BaseDO { @@ -67,12 +66,6 @@ public class WmsShipmentOrderDetailDO extends BaseDO {
67 * 关联 {@link WmsWarehouseAreaDO#getId()} 66 * 关联 {@link WmsWarehouseAreaDO#getId()}
68 */ 67 */
69 private Long areaId; 68 private Long areaId;
70 - /**  
71 - * 库存明细编号  
72 - *  
73 - * 关联 {@link WmsInventoryDetailDO#getId()}  
74 - */  
75 - private Long inventoryDetailId;  
76 69
77 // ========= 批次效期字段 ========= 70 // ========= 批次效期字段 =========
78 71
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/inventory/WmsInventoryDetailMapper.java deleted
1 -package cn.iocoder.yudao.module.wms.dal.mysql.inventory;  
2 -  
3 -import cn.hutool.core.util.StrUtil;  
4 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
5 -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;  
6 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;  
7 -import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;  
8 -import cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.detail.WmsInventoryDetailPageReqVO;  
9 -import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDetailDO;  
10 -import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO;  
11 -import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;  
12 -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;  
13 -import org.apache.ibatis.annotations.Mapper;  
14 -  
15 -import java.math.BigDecimal;  
16 -import java.time.LocalDate;  
17 -import java.time.LocalDateTime;  
18 -import java.time.LocalTime;  
19 -import java.util.Collection;  
20 -import java.util.List;  
21 -  
22 -/**  
23 - * WMS 库存明细 Mapper  
24 - *  
25 - * @author 芋道源码  
26 - */  
27 -@Mapper  
28 -public interface WmsInventoryDetailMapper extends BaseMapperX<WmsInventoryDetailDO> {  
29 -  
30 - default PageResult<WmsInventoryDetailDO> selectPage(WmsInventoryDetailPageReqVO reqVO) {  
31 - MPJLambdaWrapperX<WmsInventoryDetailDO> query = new MPJLambdaWrapperX<WmsInventoryDetailDO>()  
32 - .selectAll(WmsInventoryDetailDO.class)  
33 - .innerJoin(WmsItemSkuDO.class, WmsItemSkuDO::getId, WmsInventoryDetailDO::getSkuId)  
34 - .innerJoin(WmsItemDO.class, WmsItemDO::getId, WmsItemSkuDO::getItemId)  
35 - .likeIfPresent(WmsItemDO::getCode, reqVO.getItemCode())  
36 - .likeIfPresent(WmsItemDO::getName, reqVO.getItemName())  
37 - .eqIfPresent(WmsInventoryDetailDO::getSkuId, reqVO.getSkuId())  
38 - .likeIfPresent(WmsItemSkuDO::getCode, reqVO.getSkuCode())  
39 - .likeIfPresent(WmsItemSkuDO::getName, reqVO.getSkuName())  
40 - .eqIfPresent(WmsInventoryDetailDO::getWarehouseId, reqVO.getWarehouseId())  
41 - .eqIfPresent(WmsInventoryDetailDO::getAreaId, reqVO.getAreaId())  
42 - .likeIfPresent(WmsInventoryDetailDO::getBatchNo, reqVO.getBatchNo())  
43 - .geIfPresent(WmsInventoryDetailDO::getRemainQuantity, reqVO.getMinRemainQuantity())  
44 - .betweenIfPresent(WmsInventoryDetailDO::getCreateTime, reqVO.getCreateTime());  
45 - appendDaysToExpiresQuery(query, reqVO.getDaysToExpires());  
46 - appendDimensionOrder(query, reqVO.getType());  
47 - return selectJoinPage(reqVO, WmsInventoryDetailDO.class, query);  
48 - }  
49 -  
50 - static void appendDaysToExpiresQuery(MPJLambdaWrapperX<WmsInventoryDetailDO> query, Integer daysToExpires) {  
51 - if (daysToExpires == null) {  
52 - return;  
53 - }  
54 - LocalDateTime startTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);  
55 - query.geIfPresent(WmsInventoryDetailDO::getExpirationDate, startTime)  
56 - .leIfPresent(WmsInventoryDetailDO::getExpirationDate, startTime.plusDays(daysToExpires));  
57 - }  
58 -  
59 - static void appendDimensionOrder(MPJLambdaWrapperX<WmsInventoryDetailDO> query, String type) {  
60 - if (StrUtil.equals(WmsInventoryDetailPageReqVO.TYPE_WAREHOUSE, type)) {  
61 - query.orderByAsc(WmsInventoryDetailDO::getWarehouseId)  
62 - .orderByAsc(WmsInventoryDetailDO::getAreaId)  
63 - .orderByAsc(WmsItemSkuDO::getItemId)  
64 - .orderByAsc(WmsInventoryDetailDO::getSkuId)  
65 - .orderByAsc(WmsInventoryDetailDO::getId);  
66 - return;  
67 - }  
68 - if (StrUtil.equals(WmsInventoryDetailPageReqVO.TYPE_ITEM, type)) {  
69 - query.orderByAsc(WmsItemSkuDO::getItemId)  
70 - .orderByAsc(WmsInventoryDetailDO::getSkuId)  
71 - .orderByAsc(WmsInventoryDetailDO::getWarehouseId)  
72 - .orderByAsc(WmsInventoryDetailDO::getAreaId)  
73 - .orderByAsc(WmsInventoryDetailDO::getId);  
74 - return;  
75 - }  
76 - throw new IllegalArgumentException("未知库存明细统计维度:" + type);  
77 - }  
78 -  
79 - default WmsInventoryDetailDO selectByIdForUpdate(Long id) {  
80 - return selectOneForUpdate(WmsInventoryDetailDO::getId, id);  
81 - }  
82 -  
83 - default List<WmsInventoryDetailDO> selectListByIdsForUpdate(Collection<Long> ids) {  
84 - return selectList(new LambdaQueryWrapperX<WmsInventoryDetailDO>()  
85 - .in(WmsInventoryDetailDO::getId, ids)  
86 - .orderByAsc(WmsInventoryDetailDO::getId)  
87 - .last("FOR UPDATE"));  
88 - }  
89 -  
90 - /**  
91 - * 增量更新库存明细剩余数量  
92 - *  
93 - * @param id 库存明细编号  
94 - * @param quantity 变更数量  
95 - * @return 更新行数  
96 - */  
97 - @SuppressWarnings("UnusedReturnValue")  
98 - default int updateRemainQuantityIncr(Long id, BigDecimal quantity) {  
99 - return update(null, new LambdaUpdateWrapper<WmsInventoryDetailDO>()  
100 - .eq(WmsInventoryDetailDO::getId, id)  
101 - .setSql("remain_quantity = remain_quantity + (" + quantity + ")"));  
102 - }  
103 -  
104 -}  
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/enums/ErrorCodeConstants.java
@@ -94,7 +94,5 @@ public interface ErrorCodeConstants { @@ -94,7 +94,5 @@ public interface ErrorCodeConstants {
94 // ========== WMS 库存 1-060-300-000 ========== 94 // ========== WMS 库存 1-060-300-000 ==========
95 ErrorCode INVENTORY_QUANTITY_NOT_ENOUGH = new ErrorCode(1_060_300_000, 95 ErrorCode INVENTORY_QUANTITY_NOT_ENOUGH = new ErrorCode(1_060_300_000,
96 "库存不足,商品:{},商品规格:{},仓库:{},库区:{},当前库存:{},变更数量:{}"); 96 "库存不足,商品:{},商品规格:{},仓库:{},库区:{},当前库存:{},变更数量:{}");
97 - ErrorCode INVENTORY_DETAIL_NOT_EXISTS = new ErrorCode(1_060_300_001, "库存明细不存在");  
98 - ErrorCode INVENTORY_DETAIL_REMAIN_QUANTITY_NOT_ENOUGH = new ErrorCode(1_060_300_002, "库存明细剩余数量不足,当前剩余:{},出库数量:{}");  
99 97
100 } 98 }
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/framework/config/WmsProperties.java
@@ -4,7 +4,6 @@ import lombok.Data; @@ -4,7 +4,6 @@ import lombok.Data;
4 import org.springframework.boot.context.properties.ConfigurationProperties; 4 import org.springframework.boot.context.properties.ConfigurationProperties;
5 import org.springframework.validation.annotation.Validated; 5 import org.springframework.validation.annotation.Validated;
6 6
7 -import jakarta.validation.constraints.AssertTrue;  
8 import jakarta.validation.constraints.NotNull; 7 import jakarta.validation.constraints.NotNull;
9 8
10 /** 9 /**
@@ -23,25 +22,8 @@ public class WmsProperties { @@ -23,25 +22,8 @@ public class WmsProperties {
23 @NotNull(message = "是否启用库区模式不能为空") 22 @NotNull(message = "是否启用库区模式不能为空")
24 private Boolean areaEnable = true; 23 private Boolean areaEnable = true;
25 24
26 - /**  
27 - * 是否启用批次/效期/库存明细模式  
28 - *  
29 - * 依赖 {@link #areaEnable} 为 true  
30 - */  
31 - @NotNull(message = "是否启用批次/效期/库存明细模式不能为空")  
32 - private Boolean batchEnable = true;  
33 -  
34 public boolean isAreaEnabled() { 25 public boolean isAreaEnabled() {
35 return Boolean.TRUE.equals(areaEnable); 26 return Boolean.TRUE.equals(areaEnable);
36 } 27 }
37 28
38 - public boolean isBatchEnabled() {  
39 - return Boolean.TRUE.equals(batchEnable);  
40 - }  
41 -  
42 - @AssertTrue(message = "WMS 批次/效期模式依赖库区模式,请先开启 yudao.wms.area-enable")  
43 - public boolean isBatchDependsOnAreaValid() {  
44 - return !isBatchEnabled() || isAreaEnabled();  
45 - }  
46 -  
47 } 29 }
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/inventory/WmsInventoryDetailService.java deleted
1 -package cn.iocoder.yudao.module.wms.service.inventory;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
4 -import cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.detail.WmsInventoryDetailPageReqVO;  
5 -import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDetailDO;  
6 -import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryChangeReqDTO;  
7 -  
8 -import java.util.List;  
9 -  
10 -/**  
11 - * WMS 库存明细 Service 接口  
12 - *  
13 - * @author 芋道源码  
14 - */  
15 -public interface WmsInventoryDetailService {  
16 -  
17 - /**  
18 - * 获得库存明细分页  
19 - *  
20 - * @param pageReqVO 分页查询  
21 - * @return 库存明细分页  
22 - */  
23 - PageResult<WmsInventoryDetailDO> getInventoryDetailPage(WmsInventoryDetailPageReqVO pageReqVO);  
24 -  
25 - /**  
26 - * 创建库存明细列表  
27 - *  
28 - * @param list 库存明细列表  
29 - */  
30 - void createInventoryDetailList(List<WmsInventoryDetailDO> list);  
31 -  
32 - /**  
33 - * 扣减库存明细剩余数量  
34 - *  
35 - * @param items 库存变更明细列表  
36 - */  
37 - void decreaseInventoryDetailList(List<WmsInventoryChangeReqDTO.Item> items);  
38 -  
39 -}  
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/inventory/WmsInventoryDetailServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.wms.service.inventory;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.hutool.core.util.ObjectUtil;  
5 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
6 -import cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.detail.WmsInventoryDetailPageReqVO;  
7 -import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDetailDO;  
8 -import cn.iocoder.yudao.module.wms.dal.mysql.inventory.WmsInventoryDetailMapper;  
9 -import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryChangeReqDTO;  
10 -import jakarta.annotation.Resource;  
11 -import org.springframework.stereotype.Service;  
12 -import org.springframework.transaction.annotation.Transactional;  
13 -import org.springframework.validation.annotation.Validated;  
14 -  
15 -import java.math.BigDecimal;  
16 -import java.util.Comparator;  
17 -import java.util.LinkedHashMap;  
18 -import java.util.List;  
19 -import java.util.Map;  
20 -import java.util.stream.Collectors;  
21 -  
22 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
23 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;  
24 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;  
25 -import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.INVENTORY_DETAIL_NOT_EXISTS;  
26 -import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.INVENTORY_DETAIL_REMAIN_QUANTITY_NOT_ENOUGH;  
27 -  
28 -/**  
29 - * WMS 库存明细 Service 实现类  
30 - *  
31 - * @author 芋道源码  
32 - */  
33 -@Service  
34 -@Validated  
35 -public class WmsInventoryDetailServiceImpl implements WmsInventoryDetailService {  
36 -  
37 - @Resource  
38 - private WmsInventoryDetailMapper inventoryDetailMapper;  
39 -  
40 - @Override  
41 - public PageResult<WmsInventoryDetailDO> getInventoryDetailPage(WmsInventoryDetailPageReqVO pageReqVO) {  
42 - return inventoryDetailMapper.selectPage(pageReqVO);  
43 - }  
44 -  
45 - @Override  
46 - @Transactional(rollbackFor = Exception.class)  
47 - public void createInventoryDetailList(List<WmsInventoryDetailDO> list) {  
48 - if (CollUtil.isEmpty(list)) {  
49 - return;  
50 - }  
51 - inventoryDetailMapper.insertBatch(list);  
52 - }  
53 -  
54 - // DONE @AI:加锁,也按照 inventory 做法;一批直接加锁;避免按照顺序,多个明细交叉拿锁,导致死锁  
55 - // 批量扣减库存明细:先一次性锁定相关明细,再在内存合并扣减数量后统一校验与更新。  
56 - @Override  
57 - @Transactional(rollbackFor = Exception.class)  
58 - public void decreaseInventoryDetailList(List<WmsInventoryChangeReqDTO.Item> items) {  
59 - if (CollUtil.isEmpty(items)) {  
60 - return;  
61 - }  
62 - if (items.stream().anyMatch(item -> item.getInventoryDetailId() == null)) {  
63 - throw exception(INVENTORY_DETAIL_NOT_EXISTS);  
64 - }  
65 - List<WmsInventoryChangeReqDTO.Item> sortedItems = items.stream()  
66 - .sorted(Comparator.comparing(WmsInventoryChangeReqDTO.Item::getInventoryDetailId))  
67 - .collect(Collectors.toList());  
68 -  
69 - // 1. 批量锁定本次涉及的库存明细行,避免逐条加锁时不同事务交叉等待  
70 - Map<Long, WmsInventoryDetailDO> detailMap = convertMap(inventoryDetailMapper.selectListByIdsForUpdate(  
71 - convertSet(sortedItems, WmsInventoryChangeReqDTO.Item::getInventoryDetailId)),  
72 - WmsInventoryDetailDO::getId);  
73 -  
74 - // 2. 校验库存明细归属,并合并相同库存明细的扣减数量  
75 - Map<Long, BigDecimal> decreaseQuantityMap = new LinkedHashMap<>();  
76 - for (WmsInventoryChangeReqDTO.Item item : sortedItems) {  
77 - WmsInventoryDetailDO detail = detailMap.get(item.getInventoryDetailId());  
78 - if (detail == null  
79 - || ObjectUtil.notEqual(detail.getSkuId(), item.getSkuId())  
80 - || ObjectUtil.notEqual(detail.getWarehouseId(), item.getWarehouseId())  
81 - || ObjectUtil.notEqual(detail.getAreaId(), item.getAreaId())) {  
82 - throw exception(INVENTORY_DETAIL_NOT_EXISTS);  
83 - }  
84 - decreaseQuantityMap.merge(detail.getId(), item.getQuantity().abs(), BigDecimal::add);  
85 - }  
86 -  
87 - // 3. 校验并扣减库存明细剩余数量  
88 - for (Map.Entry<Long, BigDecimal> entry : decreaseQuantityMap.entrySet()) {  
89 - WmsInventoryDetailDO detail = detailMap.get(entry.getKey());  
90 - BigDecimal decreaseQuantity = entry.getValue();  
91 - if (detail.getRemainQuantity().compareTo(decreaseQuantity) < 0) {  
92 - throw exception(INVENTORY_DETAIL_REMAIN_QUANTITY_NOT_ENOUGH,  
93 - detail.getRemainQuantity(), decreaseQuantity);  
94 - }  
95 - inventoryDetailMapper.updateRemainQuantityIncr(detail.getId(), decreaseQuantity.negate());  
96 - }  
97 - }  
98 -  
99 -}  
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/inventory/WmsInventoryServiceImpl.java
@@ -7,13 +7,11 @@ import cn.hutool.core.util.StrUtil; @@ -7,13 +7,11 @@ import cn.hutool.core.util.StrUtil;
7 import cn.iocoder.yudao.framework.common.exception.ServiceException; 7 import cn.iocoder.yudao.framework.common.exception.ServiceException;
8 import cn.iocoder.yudao.framework.common.pojo.PageResult; 8 import cn.iocoder.yudao.framework.common.pojo.PageResult;
9 import cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.WmsInventoryPageReqVO; 9 import cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.WmsInventoryPageReqVO;
10 -import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDetailDO;  
11 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDO; 10 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDO;
12 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryHistoryDO; 11 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryHistoryDO;
13 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO; 12 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO;
14 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO; 13 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;
15 import cn.iocoder.yudao.module.wms.dal.mysql.inventory.WmsInventoryMapper; 14 import cn.iocoder.yudao.module.wms.dal.mysql.inventory.WmsInventoryMapper;
16 -import cn.iocoder.yudao.module.wms.framework.config.WmsProperties;  
17 import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryChangeReqDTO; 15 import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryChangeReqDTO;
18 import cn.iocoder.yudao.module.wms.service.md.item.WmsItemService; 16 import cn.iocoder.yudao.module.wms.service.md.item.WmsItemService;
19 import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService; 17 import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService;
@@ -26,7 +24,6 @@ import org.springframework.validation.annotation.Validated; @@ -26,7 +24,6 @@ import org.springframework.validation.annotation.Validated;
26 24
27 import java.math.BigDecimal; 25 import java.math.BigDecimal;
28 import java.util.ArrayList; 26 import java.util.ArrayList;
29 -import java.util.Collections;  
30 import java.util.IdentityHashMap; 27 import java.util.IdentityHashMap;
31 import java.util.List; 28 import java.util.List;
32 import java.util.Map; 29 import java.util.Map;
@@ -50,8 +47,6 @@ public class WmsInventoryServiceImpl implements WmsInventoryService { @@ -50,8 +47,6 @@ public class WmsInventoryServiceImpl implements WmsInventoryService {
50 private WmsInventoryMapper inventoryMapper; 47 private WmsInventoryMapper inventoryMapper;
51 48
52 @Resource 49 @Resource
53 - private WmsInventoryDetailService inventoryDetailService;  
54 - @Resource  
55 private WmsInventoryHistoryService inventoryHistoryService; 50 private WmsInventoryHistoryService inventoryHistoryService;
56 51
57 @Resource 52 @Resource
@@ -59,9 +54,6 @@ public class WmsInventoryServiceImpl implements WmsInventoryService { @@ -59,9 +54,6 @@ public class WmsInventoryServiceImpl implements WmsInventoryService {
59 @Resource 54 @Resource
60 private WmsItemService itemService; 55 private WmsItemService itemService;
61 56
62 - @Resource  
63 - private WmsProperties wmsProperties;  
64 -  
65 @Override 57 @Override
66 public PageResult<WmsInventoryDO> getInventoryPage(WmsInventoryPageReqVO pageReqVO) { 58 public PageResult<WmsInventoryDO> getInventoryPage(WmsInventoryPageReqVO pageReqVO) {
67 if (StrUtil.equals(WmsInventoryPageReqVO.TYPE_WAREHOUSE, pageReqVO.getType())) { 59 if (StrUtil.equals(WmsInventoryPageReqVO.TYPE_WAREHOUSE, pageReqVO.getType())) {
@@ -85,29 +77,11 @@ public class WmsInventoryServiceImpl implements WmsInventoryService { @@ -85,29 +77,11 @@ public class WmsInventoryServiceImpl implements WmsInventoryService {
85 // 1. 补齐并锁定本次涉及的库存余额行,再计算库存变更 77 // 1. 补齐并锁定本次涉及的库存余额行,再计算库存变更
86 Map<WmsInventoryChangeReqDTO.Item, Tuple> resultMap = changeInventoryList(reqDTO.getItems()); 78 Map<WmsInventoryChangeReqDTO.Item, Tuple> resultMap = changeInventoryList(reqDTO.getItems());
87 79
88 - // 2.1 构建库存流水与批次库存明细  
89 - boolean batchEnabled = wmsProperties.isBatchEnabled(); 80 + // 2. 批量写入库存流水
90 List<WmsInventoryHistoryDO> histories = new ArrayList<>(reqDTO.getItems().size()); 81 List<WmsInventoryHistoryDO> histories = new ArrayList<>(reqDTO.getItems().size());
91 - List<WmsInventoryDetailDO> increaseDetails = batchEnabled ? new ArrayList<>(reqDTO.getItems().size()) : Collections.emptyList();  
92 - List<WmsInventoryChangeReqDTO.Item> decreaseItems = batchEnabled ? new ArrayList<>(reqDTO.getItems().size()) : Collections.emptyList();  
93 for (WmsInventoryChangeReqDTO.Item item : reqDTO.getItems()) { 82 for (WmsInventoryChangeReqDTO.Item item : reqDTO.getItems()) {
94 histories.add(buildInventoryHistory(reqDTO, item, resultMap.get(item))); 83 histories.add(buildInventoryHistory(reqDTO, item, resultMap.get(item)));
95 - if (!batchEnabled) {  
96 - continue;  
97 - }  
98 - if (item.getQuantity().compareTo(BigDecimal.ZERO) > 0) {  
99 - increaseDetails.add(buildInventoryDetail(reqDTO, item));  
100 - } else {  
101 - decreaseItems.add(item);  
102 - }  
103 - }  
104 -  
105 - // 2.2.1 扣减已有批次库存明细,再写入新增批次库存明细  
106 - if (batchEnabled) {  
107 - inventoryDetailService.decreaseInventoryDetailList(decreaseItems);  
108 - inventoryDetailService.createInventoryDetailList(increaseDetails);  
109 } 84 }
110 - // 2.2.2 批量写入库存流水  
111 inventoryHistoryService.createInventoryHistoryList(histories); 85 inventoryHistoryService.createInventoryHistoryList(histories);
112 } 86 }
113 87
@@ -225,17 +199,6 @@ public class WmsInventoryServiceImpl implements WmsInventoryService { @@ -225,17 +199,6 @@ public class WmsInventoryServiceImpl implements WmsInventoryService {
225 .setOrderId(reqDTO.getOrderId()).setOrderNo(reqDTO.getOrderNo()).setOrderType(reqDTO.getOrderType()); 199 .setOrderId(reqDTO.getOrderId()).setOrderNo(reqDTO.getOrderNo()).setOrderType(reqDTO.getOrderType());
226 } 200 }
227 201
228 - private WmsInventoryDetailDO buildInventoryDetail(WmsInventoryChangeReqDTO reqDTO,  
229 - WmsInventoryChangeReqDTO.Item item) {  
230 - return new WmsInventoryDetailDO()  
231 - .setSkuId(item.getSkuId()).setWarehouseId(item.getWarehouseId()).setAreaId(item.getAreaId())  
232 - .setQuantity(item.getQuantity()).setRemainQuantity(item.getQuantity())  
233 - .setBatchNo(item.getBatchNo()).setProductionDate(item.getProductionDate())  
234 - .setExpirationDate(item.getExpirationDate())  
235 - .setAmount(item.getAmount()).setRemark(item.getRemark())  
236 - .setOrderId(reqDTO.getOrderId()).setOrderNo(reqDTO.getOrderNo()).setOrderType(reqDTO.getOrderType());  
237 - }  
238 -  
239 private static WmsInventoryDO findInventory(List<WmsInventoryDO> inventories, WmsInventoryChangeReqDTO.Item item) { 202 private static WmsInventoryDO findInventory(List<WmsInventoryDO> inventories, WmsInventoryChangeReqDTO.Item item) {
240 return CollUtil.findOne(inventories, inventory -> isSameInventory(inventory, item)); 203 return CollUtil.findOne(inventories, inventory -> isSameInventory(inventory, item));
241 } 204 }
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/inventory/dto/WmsInventoryChangeReqDTO.java
@@ -54,10 +54,6 @@ public class WmsInventoryChangeReqDTO { @@ -54,10 +54,6 @@ public class WmsInventoryChangeReqDTO {
54 */ 54 */
55 private Long areaId; 55 private Long areaId;
56 /** 56 /**
57 - * 库存明细编号  
58 - */  
59 - private Long inventoryDetailId;  
60 - /**  
61 * 变更数量 57 * 变更数量
62 */ 58 */
63 private BigDecimal quantity; 59 private BigDecimal quantity;
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/check/WmsCheckOrderServiceImpl.java
@@ -183,8 +183,7 @@ public class WmsCheckOrderServiceImpl implements WmsCheckOrderService { @@ -183,8 +183,7 @@ public class WmsCheckOrderServiceImpl implements WmsCheckOrderService {
183 /** 183 /**
184 * 盘点盘库单对应库存。 184 * 盘点盘库单对应库存。
185 * 185 *
186 - * 盘库只对盈亏数量生成库存变更:实盘数量大于账面数量时增加库存,反之扣减库存;批次模式下,扣减库存会使用  
187 - * inventoryDetailId 扣减对应库存明细的剩余数量。 186 + * 盘库只对盈亏数量生成库存变更:实盘数量大于账面数量时增加库存,反之扣减库存,批次字段随库存流水记录。
188 * 187 *
189 * @param order 盘库单 188 * @param order 盘库单
190 * @param details 盘库单明细列表 189 * @param details 盘库单明细列表
@@ -198,9 +197,6 @@ public class WmsCheckOrderServiceImpl implements WmsCheckOrderService { @@ -198,9 +197,6 @@ public class WmsCheckOrderServiceImpl implements WmsCheckOrderService {
198 } 197 }
199 WmsInventoryChangeReqDTO.Item item = BeanUtils.toBean(detail, WmsInventoryChangeReqDTO.Item.class) 198 WmsInventoryChangeReqDTO.Item item = BeanUtils.toBean(detail, WmsInventoryChangeReqDTO.Item.class)
200 .setQuantity(differenceQuantity); 199 .setQuantity(differenceQuantity);
201 - if (differenceQuantity.compareTo(BigDecimal.ZERO) > 0) {  
202 - item.setInventoryDetailId(null);  
203 - }  
204 items.add(item); 200 items.add(item);
205 } 201 }
206 inventoryService.changeInventory(new WmsInventoryChangeReqDTO() 202 inventoryService.changeInventory(new WmsInventoryChangeReqDTO()
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/movement/WmsMovementOrderServiceImpl.java
@@ -190,8 +190,7 @@ public class WmsMovementOrderServiceImpl implements WmsMovementOrderService { @@ -190,8 +190,7 @@ public class WmsMovementOrderServiceImpl implements WmsMovementOrderService {
190 /** 190 /**
191 * 移动移库单对应库存。 191 * 移动移库单对应库存。
192 * 192 *
193 - * 移库会生成两条库存变更:来源仓库扣减库存,目标仓库增加库存;批次模式下,来源库存明细用  
194 - * inventoryDetailId 扣减剩余数量,目标仓库生成新的库存明细。 193 + * 移库会生成两条库存变更:来源仓库扣减库存,目标仓库增加库存,批次字段随库存流水记录。
195 * 194 *
196 * @param order 移库单 195 * @param order 移库单
197 * @param details 移库单明细列表 196 * @param details 移库单明细列表
@@ -204,7 +203,7 @@ public class WmsMovementOrderServiceImpl implements WmsMovementOrderService { @@ -204,7 +203,7 @@ public class WmsMovementOrderServiceImpl implements WmsMovementOrderService {
204 .setQuantity(detail.getQuantity().negate())); 203 .setQuantity(detail.getQuantity().negate()));
205 items.add(BeanUtils.toBean(detail, WmsInventoryChangeReqDTO.Item.class) 204 items.add(BeanUtils.toBean(detail, WmsInventoryChangeReqDTO.Item.class)
206 .setWarehouseId(detail.getTargetWarehouseId()).setAreaId(detail.getTargetAreaId()) 205 .setWarehouseId(detail.getTargetWarehouseId()).setAreaId(detail.getTargetAreaId())
207 - .setInventoryDetailId(null).setQuantity(detail.getQuantity())); 206 + .setQuantity(detail.getQuantity()));
208 } 207 }
209 inventoryService.changeInventory(new WmsInventoryChangeReqDTO() 208 inventoryService.changeInventory(new WmsInventoryChangeReqDTO()
210 .setOrderId(order.getId()).setOrderNo(order.getNo()) 209 .setOrderId(order.getId()).setOrderNo(order.getNo())
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/receipt/WmsReceiptOrderServiceImpl.java
@@ -189,7 +189,7 @@ public class WmsReceiptOrderServiceImpl implements WmsReceiptOrderService { @@ -189,7 +189,7 @@ public class WmsReceiptOrderServiceImpl implements WmsReceiptOrderService {
189 /** 189 /**
190 * 增加入库单对应库存。 190 * 增加入库单对应库存。
191 * 191 *
192 - * 入库在库存变更模型中使用正数数量;批次模式下,会根据入库明细生成新的库存明细。 192 + * 入库在库存变更模型中使用正数数量,批次字段随库存流水记录。
193 * 193 *
194 * @param order 入库单 194 * @param order 入库单
195 * @param details 入库单明细列表 195 * @param details 入库单明细列表
yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/service/order/shipment/WmsShipmentOrderServiceImpl.java
@@ -190,7 +190,7 @@ public class WmsShipmentOrderServiceImpl implements WmsShipmentOrderService { @@ -190,7 +190,7 @@ public class WmsShipmentOrderServiceImpl implements WmsShipmentOrderService {
190 /** 190 /**
191 * 扣减出库单对应库存。 191 * 扣减出库单对应库存。
192 * 192 *
193 - * 出库在库存变更模型中使用负数数量;批次模式下,明细里的 inventoryDetailId 会用于扣减对应库存明细的剩余数量。 193 + * 出库在库存变更模型中使用负数数量,批次字段随库存流水记录。
194 * 194 *
195 * @param order 出库单 195 * @param order 出库单
196 * @param details 出库单明细列表 196 * @param details 出库单明细列表
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/inventory/WmsInventoryDetailServiceImplTest.java deleted
1 -package cn.iocoder.yudao.module.wms.service.inventory;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
4 -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;  
5 -import cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.detail.WmsInventoryDetailPageReqVO;  
6 -import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDetailDO;  
7 -import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO;  
8 -import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;  
9 -import cn.iocoder.yudao.module.wms.dal.mysql.inventory.WmsInventoryDetailMapper;  
10 -import cn.iocoder.yudao.module.wms.dal.mysql.md.item.WmsItemMapper;  
11 -import cn.iocoder.yudao.module.wms.dal.mysql.md.item.WmsItemSkuMapper;  
12 -import jakarta.annotation.Resource;  
13 -import org.junit.jupiter.api.Test;  
14 -import org.springframework.context.annotation.Import;  
15 -  
16 -import java.math.BigDecimal;  
17 -import java.time.LocalDate;  
18 -import java.time.LocalDateTime;  
19 -import java.time.LocalTime;  
20 -  
21 -import static org.junit.jupiter.api.Assertions.assertEquals;  
22 -  
23 -@Import(WmsInventoryDetailServiceImpl.class)  
24 -public class WmsInventoryDetailServiceImplTest extends BaseDbUnitTest {  
25 -  
26 - @Resource  
27 - private WmsInventoryDetailServiceImpl inventoryDetailService;  
28 -  
29 - @Resource  
30 - private WmsInventoryDetailMapper inventoryDetailMapper;  
31 - @Resource  
32 - private WmsItemMapper itemMapper;  
33 - @Resource  
34 - private WmsItemSkuMapper skuMapper;  
35 -  
36 - @Test  
37 - public void testGetInventoryDetailPage_daysToExpires() {  
38 - // mock 数据  
39 - WmsItemDO item = createItem("ITEM-001", "红富士苹果");  
40 - WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");  
41 - WmsInventoryDetailDO dbDetail = createInventoryDetail(sku.getId(), 100L, 1001L, "10.00",  
42 - LocalDateTime.of(LocalDate.now().plusDays(10), LocalTime.MIN));  
43 - inventoryDetailMapper.insert(dbDetail);  
44 - inventoryDetailMapper.insert(createInventoryDetail(sku.getId(), 100L, 1002L, "20.00",  
45 - LocalDateTime.of(LocalDate.now().plusDays(40), LocalTime.MIN)));  
46 - // 准备参数  
47 - WmsInventoryDetailPageReqVO reqVO = new WmsInventoryDetailPageReqVO();  
48 - reqVO.setType(WmsInventoryDetailPageReqVO.TYPE_WAREHOUSE);  
49 - reqVO.setDaysToExpires(30);  
50 -  
51 - // 调用  
52 - PageResult<WmsInventoryDetailDO> pageResult = inventoryDetailService.getInventoryDetailPage(reqVO);  
53 - // 断言  
54 - assertEquals(1, pageResult.getTotal());  
55 - assertEquals(1, pageResult.getList().size());  
56 - assertEquals(dbDetail.getId(), pageResult.getList().get(0).getId());  
57 - }  
58 -  
59 - private WmsItemDO createItem(String code, String name) {  
60 - WmsItemDO item = WmsItemDO.builder()  
61 - .code(code)  
62 - .name(name)  
63 - .unit("箱")  
64 - .categoryId(1L)  
65 - .build();  
66 - itemMapper.insert(item);  
67 - return item;  
68 - }  
69 -  
70 - private WmsItemSkuDO createSku(Long itemId, String code, String name) {  
71 - WmsItemSkuDO sku = WmsItemSkuDO.builder()  
72 - .itemId(itemId)  
73 - .code(code)  
74 - .name(name)  
75 - .barCode("69010001")  
76 - .build();  
77 - skuMapper.insert(sku);  
78 - return sku;  
79 - }  
80 -  
81 - private static WmsInventoryDetailDO createInventoryDetail(Long skuId, Long warehouseId, Long areaId,  
82 - String quantity, LocalDateTime expirationDate) {  
83 - return WmsInventoryDetailDO.builder()  
84 - .skuId(skuId)  
85 - .warehouseId(warehouseId)  
86 - .areaId(areaId)  
87 - .quantity(new BigDecimal(quantity))  
88 - .remainQuantity(new BigDecimal(quantity))  
89 - .expirationDate(expirationDate)  
90 - .build();  
91 - }  
92 -  
93 -}  
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/inventory/WmsInventoryServiceImplTest.java
@@ -3,18 +3,15 @@ package cn.iocoder.yudao.module.wms.service.inventory; @@ -3,18 +3,15 @@ package cn.iocoder.yudao.module.wms.service.inventory;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; 4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
5 import cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.WmsInventoryPageReqVO; 5 import cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.WmsInventoryPageReqVO;
6 -import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDetailDO;  
7 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryHistoryDO; 6 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryHistoryDO;
8 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDO; 7 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDO;
9 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO; 8 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO;
10 -import cn.iocoder.yudao.module.wms.dal.mysql.inventory.WmsInventoryDetailMapper;  
11 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO; 9 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;
12 import cn.iocoder.yudao.module.wms.dal.mysql.inventory.WmsInventoryHistoryMapper; 10 import cn.iocoder.yudao.module.wms.dal.mysql.inventory.WmsInventoryHistoryMapper;
13 import cn.iocoder.yudao.module.wms.dal.mysql.inventory.WmsInventoryMapper; 11 import cn.iocoder.yudao.module.wms.dal.mysql.inventory.WmsInventoryMapper;
14 import cn.iocoder.yudao.module.wms.dal.mysql.md.item.WmsItemMapper; 12 import cn.iocoder.yudao.module.wms.dal.mysql.md.item.WmsItemMapper;
15 import cn.iocoder.yudao.module.wms.dal.mysql.md.item.WmsItemSkuMapper; 13 import cn.iocoder.yudao.module.wms.dal.mysql.md.item.WmsItemSkuMapper;
16 import cn.iocoder.yudao.module.wms.enums.inventory.WmsInventoryOrderTypeEnum; 14 import cn.iocoder.yudao.module.wms.enums.inventory.WmsInventoryOrderTypeEnum;
17 -import cn.iocoder.yudao.module.wms.framework.config.WmsProperties;  
18 import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryChangeReqDTO; 15 import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryChangeReqDTO;
19 import cn.iocoder.yudao.module.wms.service.md.item.WmsItemService; 16 import cn.iocoder.yudao.module.wms.service.md.item.WmsItemService;
20 import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService; 17 import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService;
@@ -30,14 +27,12 @@ import java.util.Comparator; @@ -30,14 +27,12 @@ import java.util.Comparator;
30 import java.util.List; 27 import java.util.List;
31 28
32 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; 29 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
33 -import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.INVENTORY_DETAIL_REMAIN_QUANTITY_NOT_ENOUGH;  
34 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.INVENTORY_QUANTITY_NOT_ENOUGH; 30 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.INVENTORY_QUANTITY_NOT_ENOUGH;
35 import static org.junit.jupiter.api.Assertions.assertEquals; 31 import static org.junit.jupiter.api.Assertions.assertEquals;
36 import static org.junit.jupiter.api.Assertions.assertNotNull; 32 import static org.junit.jupiter.api.Assertions.assertNotNull;
37 import static org.mockito.Mockito.when; 33 import static org.mockito.Mockito.when;
38 34
39 -@Import({WmsInventoryServiceImpl.class, WmsInventoryDetailServiceImpl.class, WmsInventoryHistoryServiceImpl.class,  
40 - WmsProperties.class}) 35 +@Import({WmsInventoryServiceImpl.class, WmsInventoryHistoryServiceImpl.class})
41 public class WmsInventoryServiceImplTest extends BaseDbUnitTest { 36 public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
42 37
43 @Resource 38 @Resource
@@ -46,15 +41,11 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest { @@ -46,15 +41,11 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
46 @Resource 41 @Resource
47 private WmsInventoryMapper inventoryMapper; 42 private WmsInventoryMapper inventoryMapper;
48 @Resource 43 @Resource
49 - private WmsInventoryDetailMapper inventoryDetailMapper;  
50 - @Resource  
51 private WmsInventoryHistoryMapper inventoryHistoryMapper; 44 private WmsInventoryHistoryMapper inventoryHistoryMapper;
52 @Resource 45 @Resource
53 private WmsItemMapper itemMapper; 46 private WmsItemMapper itemMapper;
54 @Resource 47 @Resource
55 private WmsItemSkuMapper skuMapper; 48 private WmsItemSkuMapper skuMapper;
56 - @Resource  
57 - private WmsProperties wmsProperties;  
58 49
59 @MockitoBean 50 @MockitoBean
60 private WmsItemSkuService itemSkuService; 51 private WmsItemSkuService itemSkuService;
@@ -64,7 +55,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest { @@ -64,7 +55,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
64 @Test 55 @Test
65 public void testChangeInventory_createInventory() { 56 public void testChangeInventory_createInventory() {
66 // mock 数据 57 // mock 数据
67 - wmsProperties.setBatchEnable(false);  
68 WmsItemDO item = createItem("ITEM-001", "红富士苹果"); 58 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
69 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装"); 59 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
70 WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "5.00"); 60 WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "5.00");
@@ -93,7 +83,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest { @@ -93,7 +83,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
93 @Test 83 @Test
94 public void testChangeInventory_updateInventory() { 84 public void testChangeInventory_updateInventory() {
95 // mock 数据 85 // mock 数据
96 - wmsProperties.setBatchEnable(false);  
97 WmsItemDO item = createItem("ITEM-001", "红富士苹果"); 86 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
98 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装"); 87 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
99 inventoryMapper.insert(createInventory(sku.getId(), 100L, 1001L, "2.00")); 88 inventoryMapper.insert(createInventory(sku.getId(), 100L, 1001L, "2.00"));
@@ -118,7 +107,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest { @@ -118,7 +107,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
118 @Test 107 @Test
119 public void testChangeInventory_sameInventoryKeyKeepItemGranularity() { 108 public void testChangeInventory_sameInventoryKeyKeepItemGranularity() {
120 // mock 数据 109 // mock 数据
121 - wmsProperties.setBatchEnable(false);  
122 WmsItemDO item = createItem("ITEM-001", "红富士苹果"); 110 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
123 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装"); 111 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
124 WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "5.00"); 112 WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "5.00");
@@ -154,7 +142,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest { @@ -154,7 +142,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
154 @Test 142 @Test
155 public void testChangeInventory_sameExistingInventoryKeyKeepItemGranularity() { 143 public void testChangeInventory_sameExistingInventoryKeyKeepItemGranularity() {
156 // mock 数据 144 // mock 数据
157 - wmsProperties.setBatchEnable(false);  
158 WmsItemDO item = createItem("ITEM-001", "红富士苹果"); 145 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
159 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装"); 146 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
160 inventoryMapper.insert(createInventory(sku.getId(), 100L, 1001L, "2.00")); 147 inventoryMapper.insert(createInventory(sku.getId(), 100L, 1001L, "2.00"));
@@ -191,7 +178,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest { @@ -191,7 +178,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
191 @Test 178 @Test
192 public void testChangeInventory_multipleInventoryKeysKeepItemGranularity() { 179 public void testChangeInventory_multipleInventoryKeysKeepItemGranularity() {
193 // mock 数据 180 // mock 数据
194 - wmsProperties.setBatchEnable(false);  
195 WmsItemDO item = createItem("ITEM-001", "红富士苹果"); 181 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
196 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装"); 182 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
197 WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "5.00"); 183 WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "5.00");
@@ -240,7 +226,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest { @@ -240,7 +226,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
240 @Test 226 @Test
241 public void testChangeInventory_quantityNotEnough() { 227 public void testChangeInventory_quantityNotEnough() {
242 // mock 数据 228 // mock 数据
243 - wmsProperties.setBatchEnable(false);  
244 WmsItemDO item = createItem("ITEM-001", "红富士苹果"); 229 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
245 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装"); 230 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
246 inventoryMapper.insert(createInventory(sku.getId(), 100L, 1001L, "2.00")); 231 inventoryMapper.insert(createInventory(sku.getId(), 100L, 1001L, "2.00"));
@@ -255,7 +240,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest { @@ -255,7 +240,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
255 @Test 240 @Test
256 public void testChangeInventory_quantityNotEnoughWithoutInventory() { 241 public void testChangeInventory_quantityNotEnoughWithoutInventory() {
257 // mock 数据 242 // mock 数据
258 - wmsProperties.setBatchEnable(false);  
259 WmsItemDO item = createItem("ITEM-001", "红富士苹果"); 243 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
260 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装"); 244 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
261 WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "-3.00"); 245 WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "-3.00");
@@ -268,58 +252,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest { @@ -268,58 +252,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
268 } 252 }
269 253
270 @Test 254 @Test
271 - public void testChangeInventory_decreaseInventoryDetail() {  
272 - // mock 数据  
273 - wmsProperties.setBatchEnable(true);  
274 - WmsItemDO item = createItem("ITEM-001", "红富士苹果");  
275 - WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");  
276 - inventoryMapper.insert(createInventory(sku.getId(), 100L, 1001L, "10.00"));  
277 - WmsInventoryDetailDO detail = createInventoryDetail(sku.getId(), 100L, 1001L, "5.00");  
278 - inventoryDetailMapper.insert(detail);  
279 - WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "-3.00");  
280 - reqDTO.getItems().get(0).setInventoryDetailId(detail.getId());  
281 -  
282 - // 调用  
283 - inventoryService.changeInventory(reqDTO);  
284 -  
285 - // 断言:库存余额  
286 - WmsInventoryDO inventory = inventoryMapper.selectBySkuIdAndWarehouseIdAndAreaId(sku.getId(), 100L, 1001L);  
287 - assertEquals(0, new BigDecimal("7.00").compareTo(inventory.getQuantity()));  
288 - // 断言:库存明细  
289 - WmsInventoryDetailDO dbDetail = inventoryDetailMapper.selectById(detail.getId());  
290 - assertEquals(0, new BigDecimal("2.00").compareTo(dbDetail.getRemainQuantity()));  
291 - // 断言:库存流水  
292 - List<WmsInventoryHistoryDO> histories = inventoryHistoryMapper.selectList();  
293 - assertEquals(1, histories.size());  
294 - assertEquals(0, new BigDecimal("-3.00").compareTo(histories.get(0).getQuantity()));  
295 - }  
296 -  
297 - @Test  
298 - public void testChangeInventory_decreaseInventoryDetailRemainQuantityNotEnough() {  
299 - // mock 数据  
300 - wmsProperties.setBatchEnable(true);  
301 - WmsItemDO item = createItem("ITEM-001", "红富士苹果");  
302 - WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");  
303 - inventoryMapper.insert(createInventory(sku.getId(), 100L, 1001L, "10.00"));  
304 - WmsInventoryDetailDO detail = createInventoryDetail(sku.getId(), 100L, 1001L, "5.00");  
305 - inventoryDetailMapper.insert(detail);  
306 - WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "-3.00");  
307 - reqDTO.getItems().get(0).setInventoryDetailId(detail.getId());  
308 - List<WmsInventoryChangeReqDTO.Item> items = new ArrayList<>(reqDTO.getItems());  
309 - items.add(new WmsInventoryChangeReqDTO.Item()  
310 - .setSkuId(sku.getId())  
311 - .setWarehouseId(100L)  
312 - .setAreaId(1001L)  
313 - .setInventoryDetailId(detail.getId())  
314 - .setQuantity(new BigDecimal("-3.00")));  
315 - reqDTO.setItems(items);  
316 -  
317 - // 调用,并断言:相同库存明细会合并后校验  
318 - assertServiceException(() -> inventoryService.changeInventory(reqDTO),  
319 - INVENTORY_DETAIL_REMAIN_QUANTITY_NOT_ENOUGH, new BigDecimal("5.000000"), new BigDecimal("6.00"));  
320 - }  
321 -  
322 - @Test  
323 public void testGetInventoryPage_groupByWarehouse() { 255 public void testGetInventoryPage_groupByWarehouse() {
324 // mock 数据 256 // mock 数据
325 WmsItemDO item = createItem("ITEM-001", "红富士苹果"); 257 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
@@ -419,17 +351,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest { @@ -419,17 +351,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
419 .build(); 351 .build();
420 } 352 }
421 353
422 - private static WmsInventoryDetailDO createInventoryDetail(Long skuId, Long warehouseId, Long areaId,  
423 - String remainQuantity) {  
424 - return WmsInventoryDetailDO.builder()  
425 - .skuId(skuId)  
426 - .warehouseId(warehouseId)  
427 - .areaId(areaId)  
428 - .quantity(new BigDecimal(remainQuantity))  
429 - .remainQuantity(new BigDecimal(remainQuantity))  
430 - .build();  
431 - }  
432 -  
433 private static WmsInventoryChangeReqDTO createChangeReq(Long skuId, Long warehouseId, Long areaId, String quantity) { 354 private static WmsInventoryChangeReqDTO createChangeReq(Long skuId, Long warehouseId, Long areaId, String quantity) {
434 return new WmsInventoryChangeReqDTO() 355 return new WmsInventoryChangeReqDTO()
435 .setOrderId(1L) 356 .setOrderId(1L)
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/order/shipment/WmsShipmentOrderServiceImplTest.java
@@ -61,11 +61,9 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest { @@ -61,11 +61,9 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest {
61 // mock 数据 61 // mock 数据
62 Long warehouseId = 100L; 62 Long warehouseId = 100L;
63 Long skuId = 200L; 63 Long skuId = 200L;
64 - Long inventoryDetailId = 300L;  
65 WmsShipmentOrderDO order = createShipmentOrder(warehouseId); 64 WmsShipmentOrderDO order = createShipmentOrder(warehouseId);
66 shipmentOrderMapper.insert(order); 65 shipmentOrderMapper.insert(order);
67 - shipmentOrderDetailMapper.insert(createShipmentOrderDetail(order.getId(), skuId, warehouseId, 400L,  
68 - inventoryDetailId)); 66 + shipmentOrderDetailMapper.insert(createShipmentOrderDetail(order.getId(), skuId, warehouseId, 400L));
69 67
70 // 调用 68 // 调用
71 shipmentOrderService.completeShipmentOrder(order.getId()); 69 shipmentOrderService.completeShipmentOrder(order.getId());
@@ -84,7 +82,6 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest { @@ -84,7 +82,6 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest {
84 assertEquals(1, inventoryReqDTO.getItems().size()); 82 assertEquals(1, inventoryReqDTO.getItems().size());
85 assertEquals(skuId, inventoryReqDTO.getItems().get(0).getSkuId()); 83 assertEquals(skuId, inventoryReqDTO.getItems().get(0).getSkuId());
86 assertEquals(warehouseId, inventoryReqDTO.getItems().get(0).getWarehouseId()); 84 assertEquals(warehouseId, inventoryReqDTO.getItems().get(0).getWarehouseId());
87 - assertEquals(inventoryDetailId, inventoryReqDTO.getItems().get(0).getInventoryDetailId());  
88 assertEquals(0, new BigDecimal("-2.00").compareTo(inventoryReqDTO.getItems().get(0).getQuantity())); 85 assertEquals(0, new BigDecimal("-2.00").compareTo(inventoryReqDTO.getItems().get(0).getQuantity()));
89 } 86 }
90 87
@@ -105,7 +102,7 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest { @@ -105,7 +102,7 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest {
105 // mock 数据 102 // mock 数据
106 WmsShipmentOrderDO order = createShipmentOrder(100L); 103 WmsShipmentOrderDO order = createShipmentOrder(100L);
107 shipmentOrderMapper.insert(order); 104 shipmentOrderMapper.insert(order);
108 - shipmentOrderDetailMapper.insert(createShipmentOrderDetail(order.getId(), 200L, 100L, 0L, null)); 105 + shipmentOrderDetailMapper.insert(createShipmentOrderDetail(order.getId(), 200L, 100L, 0L));
109 106
110 // 调用,并断言 107 // 调用,并断言
111 assertServiceException(() -> shipmentOrderService.completeShipmentOrder(order.getId()), 108 assertServiceException(() -> shipmentOrderService.completeShipmentOrder(order.getId()),
@@ -134,7 +131,7 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest { @@ -134,7 +131,7 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest {
134 // mock 数据 131 // mock 数据
135 WmsShipmentOrderDO order = createShipmentOrder(100L).setStatus(WmsOrderStatusEnum.CANCELED.getStatus()); 132 WmsShipmentOrderDO order = createShipmentOrder(100L).setStatus(WmsOrderStatusEnum.CANCELED.getStatus());
136 shipmentOrderMapper.insert(order); 133 shipmentOrderMapper.insert(order);
137 - shipmentOrderDetailMapper.insert(createShipmentOrderDetail(order.getId(), 200L, 100L, 300L, null)); 134 + shipmentOrderDetailMapper.insert(createShipmentOrderDetail(order.getId(), 200L, 100L, 300L));
138 135
139 // 调用 136 // 调用
140 shipmentOrderService.deleteShipmentOrder(order.getId()); 137 shipmentOrderService.deleteShipmentOrder(order.getId());
@@ -167,13 +164,12 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest { @@ -167,13 +164,12 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest {
167 } 164 }
168 165
169 private static WmsShipmentOrderDetailDO createShipmentOrderDetail(Long orderId, Long skuId, Long warehouseId, 166 private static WmsShipmentOrderDetailDO createShipmentOrderDetail(Long orderId, Long skuId, Long warehouseId,
170 - Long areaId, Long inventoryDetailId) { 167 + Long areaId) {
171 return WmsShipmentOrderDetailDO.builder() 168 return WmsShipmentOrderDetailDO.builder()
172 .orderId(orderId) 169 .orderId(orderId)
173 .skuId(skuId) 170 .skuId(skuId)
174 .warehouseId(warehouseId) 171 .warehouseId(warehouseId)
175 .areaId(areaId) 172 .areaId(areaId)
176 - .inventoryDetailId(inventoryDetailId)  
177 .quantity(new BigDecimal("2.00")) 173 .quantity(new BigDecimal("2.00"))
178 .amount(new BigDecimal("20.00")) 174 .amount(new BigDecimal("20.00"))
179 .build(); 175 .build();
yudao-module-wms/src/test/resources/sql/clean.sql
@@ -3,7 +3,6 @@ DELETE FROM &quot;wms_shipment_order&quot;; @@ -3,7 +3,6 @@ DELETE FROM &quot;wms_shipment_order&quot;;
3 DELETE FROM "wms_receipt_order_detail"; 3 DELETE FROM "wms_receipt_order_detail";
4 DELETE FROM "wms_receipt_order"; 4 DELETE FROM "wms_receipt_order";
5 DELETE FROM "wms_inventory_history"; 5 DELETE FROM "wms_inventory_history";
6 -DELETE FROM "wms_inventory_detail";  
7 DELETE FROM "wms_inventory"; 6 DELETE FROM "wms_inventory";
8 DELETE FROM "wms_item_sku"; 7 DELETE FROM "wms_item_sku";
9 DELETE FROM "wms_item"; 8 DELETE FROM "wms_item";
yudao-module-wms/src/test/resources/sql/create_tables.sql
@@ -54,30 +54,6 @@ CREATE TABLE IF NOT EXISTS &quot;wms_inventory&quot; ( @@ -54,30 +54,6 @@ CREATE TABLE IF NOT EXISTS &quot;wms_inventory&quot; (
54 CONSTRAINT "uk_wms_inventory_sku_warehouse_area" UNIQUE ("sku_id", "warehouse_id", "area_id", "tenant_id", "deleted") 54 CONSTRAINT "uk_wms_inventory_sku_warehouse_area" UNIQUE ("sku_id", "warehouse_id", "area_id", "tenant_id", "deleted")
55 ) COMMENT 'WMS 库存表'; 55 ) COMMENT 'WMS 库存表';
56 56
57 -CREATE TABLE IF NOT EXISTS "wms_inventory_detail" (  
58 - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,  
59 - "sku_id" bigint NOT NULL,  
60 - "warehouse_id" bigint NOT NULL,  
61 - "area_id" bigint NOT NULL DEFAULT '0',  
62 - "quantity" decimal(24, 6) NOT NULL DEFAULT '0',  
63 - "remain_quantity" decimal(24, 6) NOT NULL DEFAULT '0',  
64 - "batch_no" varchar(64) DEFAULT NULL,  
65 - "production_date" timestamp DEFAULT NULL,  
66 - "expiration_date" timestamp DEFAULT NULL,  
67 - "amount" decimal(24, 6) DEFAULT NULL,  
68 - "remark" varchar(255) DEFAULT NULL,  
69 - "order_id" bigint DEFAULT NULL,  
70 - "order_no" varchar(64) DEFAULT NULL,  
71 - "order_type" tinyint DEFAULT NULL,  
72 - "creator" varchar(64) DEFAULT '',  
73 - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
74 - "updater" varchar(64) DEFAULT '',  
75 - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
76 - "deleted" bit NOT NULL DEFAULT FALSE,  
77 - "tenant_id" bigint NOT NULL DEFAULT '0',  
78 - PRIMARY KEY ("id")  
79 -) COMMENT 'WMS 库存明细表';  
80 -  
81 CREATE TABLE IF NOT EXISTS "wms_inventory_history" ( 57 CREATE TABLE IF NOT EXISTS "wms_inventory_history" (
82 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, 58 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
83 "warehouse_id" bigint NOT NULL, 59 "warehouse_id" bigint NOT NULL,
@@ -173,7 +149,6 @@ CREATE TABLE IF NOT EXISTS &quot;wms_shipment_order_detail&quot; ( @@ -173,7 +149,6 @@ CREATE TABLE IF NOT EXISTS &quot;wms_shipment_order_detail&quot; (
173 "sku_id" bigint NOT NULL, 149 "sku_id" bigint NOT NULL,
174 "warehouse_id" bigint NOT NULL, 150 "warehouse_id" bigint NOT NULL,
175 "area_id" bigint NOT NULL DEFAULT '0', 151 "area_id" bigint NOT NULL DEFAULT '0',
176 - "inventory_detail_id" bigint DEFAULT NULL,  
177 "batch_no" varchar(64) DEFAULT NULL, 152 "batch_no" varchar(64) DEFAULT NULL,
178 "production_date" timestamp DEFAULT NULL, 153 "production_date" timestamp DEFAULT NULL,
179 "expiration_date" timestamp DEFAULT NULL, 154 "expiration_date" timestamp DEFAULT NULL,