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 52 @Schema(description = "库存编号", example = "1024")
53 53 private Long inventoryId;
54 54  
55   - @Schema(description = "库存明细编号", example = "1024")
56   - private Long inventoryDetailId;
57   -
58 55 @Schema(description = "批号", example = "B202605110001")
59 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 26 @Schema(description = "库存编号", example = "1024")
27 27 private Long inventoryId;
28 28  
29   - @Schema(description = "库存明细编号", example = "1024")
30   - private Long inventoryDetailId;
31   -
32 29 @Schema(description = "批号", example = "B202605110001")
33 30 @Size(max = 64, message = "批号长度不能超过 64 个字符")
34 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 61 @Schema(description = "目标库区名称", example = "上海库区01")
62 62 private String targetAreaName;
63 63  
64   - @Schema(description = "库存明细编号", example = "1024")
65   - private Long inventoryDetailId;
66   -
67 64 @Schema(description = "批号", example = "B202605110001")
68 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 26 @Schema(description = "目标库区编号", example = "2048")
27 27 private Long targetAreaId;
28 28  
29   - @Schema(description = "库存明细编号", example = "1024")
30   - private Long inventoryDetailId;
31   -
32 29 @Schema(description = "批号", example = "B202605110001")
33 30 @Size(max = 64, message = "批号长度不能超过 64 个字符")
34 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 49 @Schema(description = "库区名称", example = "北京库区01")
50 50 private String areaName;
51 51  
52   - @Schema(description = "库存明细编号", example = "1024")
53   - private Long inventoryDetailId;
54   -
55 52 @Schema(description = "批号", example = "B202605110001")
56 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 23 @Schema(description = "库区编号", example = "1024")
24 24 private Long areaId;
25 25  
26   - @Schema(description = "库存明细编号", example = "1024")
27   - private Long inventoryDetailId;
28   -
29 26 @Schema(description = "批号", example = "B202605110001")
30 27 @Size(max = 64, message = "批号长度不能超过 64 个字符")
31 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 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 4 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDO;
5   -import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDetailDO;
6 5 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;
7 6 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseAreaDO;
8 7 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseDO;
... ... @@ -74,12 +73,6 @@ public class WmsCheckOrderDetailDO extends BaseDO {
74 73 * 关联 {@link WmsInventoryDO#getId()}
75 74 */
76 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 1 package cn.iocoder.yudao.module.wms.dal.dataobject.order.movement;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4   -import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDetailDO;
5 4 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;
6 5 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseAreaDO;
7 6 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseDO;
... ... @@ -67,12 +66,6 @@ public class WmsMovementOrderDetailDO extends BaseDO {
67 66 * 关联 {@link WmsWarehouseAreaDO#getId()}
68 67 */
69 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 1 package cn.iocoder.yudao.module.wms.dal.dataobject.order.shipment;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4   -import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDetailDO;
5 4 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;
6 5 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseAreaDO;
7 6 import cn.iocoder.yudao.module.wms.dal.dataobject.md.warehouse.WmsWarehouseDO;
... ... @@ -67,12 +66,6 @@ public class WmsShipmentOrderDetailDO extends BaseDO {
67 66 * 关联 {@link WmsWarehouseAreaDO#getId()}
68 67 */
69 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 94 // ========== WMS 库存 1-060-300-000 ==========
95 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 4 import org.springframework.boot.context.properties.ConfigurationProperties;
5 5 import org.springframework.validation.annotation.Validated;
6 6  
7   -import jakarta.validation.constraints.AssertTrue;
8 7 import jakarta.validation.constraints.NotNull;
9 8  
10 9 /**
... ... @@ -23,25 +22,8 @@ public class WmsProperties {
23 22 @NotNull(message = "是否启用库区模式不能为空")
24 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 25 public boolean isAreaEnabled() {
35 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 7 import cn.iocoder.yudao.framework.common.exception.ServiceException;
8 8 import cn.iocoder.yudao.framework.common.pojo.PageResult;
9 9 import cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.WmsInventoryPageReqVO;
10   -import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDetailDO;
11 10 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDO;
12 11 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryHistoryDO;
13 12 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO;
14 13 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;
15 14 import cn.iocoder.yudao.module.wms.dal.mysql.inventory.WmsInventoryMapper;
16   -import cn.iocoder.yudao.module.wms.framework.config.WmsProperties;
17 15 import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryChangeReqDTO;
18 16 import cn.iocoder.yudao.module.wms.service.md.item.WmsItemService;
19 17 import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService;
... ... @@ -26,7 +24,6 @@ import org.springframework.validation.annotation.Validated;
26 24  
27 25 import java.math.BigDecimal;
28 26 import java.util.ArrayList;
29   -import java.util.Collections;
30 27 import java.util.IdentityHashMap;
31 28 import java.util.List;
32 29 import java.util.Map;
... ... @@ -50,8 +47,6 @@ public class WmsInventoryServiceImpl implements WmsInventoryService {
50 47 private WmsInventoryMapper inventoryMapper;
51 48  
52 49 @Resource
53   - private WmsInventoryDetailService inventoryDetailService;
54   - @Resource
55 50 private WmsInventoryHistoryService inventoryHistoryService;
56 51  
57 52 @Resource
... ... @@ -59,9 +54,6 @@ public class WmsInventoryServiceImpl implements WmsInventoryService {
59 54 @Resource
60 55 private WmsItemService itemService;
61 56  
62   - @Resource
63   - private WmsProperties wmsProperties;
64   -
65 57 @Override
66 58 public PageResult<WmsInventoryDO> getInventoryPage(WmsInventoryPageReqVO pageReqVO) {
67 59 if (StrUtil.equals(WmsInventoryPageReqVO.TYPE_WAREHOUSE, pageReqVO.getType())) {
... ... @@ -85,29 +77,11 @@ public class WmsInventoryServiceImpl implements WmsInventoryService {
85 77 // 1. 补齐并锁定本次涉及的库存余额行,再计算库存变更
86 78 Map<WmsInventoryChangeReqDTO.Item, Tuple> resultMap = changeInventoryList(reqDTO.getItems());
87 79  
88   - // 2.1 构建库存流水与批次库存明细
89   - boolean batchEnabled = wmsProperties.isBatchEnabled();
  80 + // 2. 批量写入库存流水
90 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 82 for (WmsInventoryChangeReqDTO.Item item : reqDTO.getItems()) {
94 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 85 inventoryHistoryService.createInventoryHistoryList(histories);
112 86 }
113 87  
... ... @@ -225,17 +199,6 @@ public class WmsInventoryServiceImpl implements WmsInventoryService {
225 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 202 private static WmsInventoryDO findInventory(List<WmsInventoryDO> inventories, WmsInventoryChangeReqDTO.Item item) {
240 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 54 */
55 55 private Long areaId;
56 56 /**
57   - * 库存明细编号
58   - */
59   - private Long inventoryDetailId;
60   - /**
61 57 * 变更数量
62 58 */
63 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 183 /**
184 184 * 盘点盘库单对应库存。
185 185 *
186   - * 盘库只对盈亏数量生成库存变更:实盘数量大于账面数量时增加库存,反之扣减库存;批次模式下,扣减库存会使用
187   - * inventoryDetailId 扣减对应库存明细的剩余数量。
  186 + * 盘库只对盈亏数量生成库存变更:实盘数量大于账面数量时增加库存,反之扣减库存,批次字段随库存流水记录。
188 187 *
189 188 * @param order 盘库单
190 189 * @param details 盘库单明细列表
... ... @@ -198,9 +197,6 @@ public class WmsCheckOrderServiceImpl implements WmsCheckOrderService {
198 197 }
199 198 WmsInventoryChangeReqDTO.Item item = BeanUtils.toBean(detail, WmsInventoryChangeReqDTO.Item.class)
200 199 .setQuantity(differenceQuantity);
201   - if (differenceQuantity.compareTo(BigDecimal.ZERO) > 0) {
202   - item.setInventoryDetailId(null);
203   - }
204 200 items.add(item);
205 201 }
206 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 190 /**
191 191 * 移动移库单对应库存。
192 192 *
193   - * 移库会生成两条库存变更:来源仓库扣减库存,目标仓库增加库存;批次模式下,来源库存明细用
194   - * inventoryDetailId 扣减剩余数量,目标仓库生成新的库存明细。
  193 + * 移库会生成两条库存变更:来源仓库扣减库存,目标仓库增加库存,批次字段随库存流水记录。
195 194 *
196 195 * @param order 移库单
197 196 * @param details 移库单明细列表
... ... @@ -204,7 +203,7 @@ public class WmsMovementOrderServiceImpl implements WmsMovementOrderService {
204 203 .setQuantity(detail.getQuantity().negate()));
205 204 items.add(BeanUtils.toBean(detail, WmsInventoryChangeReqDTO.Item.class)
206 205 .setWarehouseId(detail.getTargetWarehouseId()).setAreaId(detail.getTargetAreaId())
207   - .setInventoryDetailId(null).setQuantity(detail.getQuantity()));
  206 + .setQuantity(detail.getQuantity()));
208 207 }
209 208 inventoryService.changeInventory(new WmsInventoryChangeReqDTO()
210 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 189 /**
190 190 * 增加入库单对应库存。
191 191 *
192   - * 入库在库存变更模型中使用正数数量;批次模式下,会根据入库明细生成新的库存明细。
  192 + * 入库在库存变更模型中使用正数数量,批次字段随库存流水记录。
193 193 *
194 194 * @param order 入库单
195 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 190 /**
191 191 * 扣减出库单对应库存。
192 192 *
193   - * 出库在库存变更模型中使用负数数量;批次模式下,明细里的 inventoryDetailId 会用于扣减对应库存明细的剩余数量。
  193 + * 出库在库存变更模型中使用负数数量,批次字段随库存流水记录。
194 194 *
195 195 * @param order 出库单
196 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 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
5 5 import cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.WmsInventoryPageReqVO;
6   -import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDetailDO;
7 6 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryHistoryDO;
8 7 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDO;
9 8 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO;
10   -import cn.iocoder.yudao.module.wms.dal.mysql.inventory.WmsInventoryDetailMapper;
11 9 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;
12 10 import cn.iocoder.yudao.module.wms.dal.mysql.inventory.WmsInventoryHistoryMapper;
13 11 import cn.iocoder.yudao.module.wms.dal.mysql.inventory.WmsInventoryMapper;
14 12 import cn.iocoder.yudao.module.wms.dal.mysql.md.item.WmsItemMapper;
15 13 import cn.iocoder.yudao.module.wms.dal.mysql.md.item.WmsItemSkuMapper;
16 14 import cn.iocoder.yudao.module.wms.enums.inventory.WmsInventoryOrderTypeEnum;
17   -import cn.iocoder.yudao.module.wms.framework.config.WmsProperties;
18 15 import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryChangeReqDTO;
19 16 import cn.iocoder.yudao.module.wms.service.md.item.WmsItemService;
20 17 import cn.iocoder.yudao.module.wms.service.md.item.WmsItemSkuService;
... ... @@ -30,14 +27,12 @@ import java.util.Comparator;
30 27 import java.util.List;
31 28  
32 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 30 import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.INVENTORY_QUANTITY_NOT_ENOUGH;
35 31 import static org.junit.jupiter.api.Assertions.assertEquals;
36 32 import static org.junit.jupiter.api.Assertions.assertNotNull;
37 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 36 public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
42 37  
43 38 @Resource
... ... @@ -46,15 +41,11 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
46 41 @Resource
47 42 private WmsInventoryMapper inventoryMapper;
48 43 @Resource
49   - private WmsInventoryDetailMapper inventoryDetailMapper;
50   - @Resource
51 44 private WmsInventoryHistoryMapper inventoryHistoryMapper;
52 45 @Resource
53 46 private WmsItemMapper itemMapper;
54 47 @Resource
55 48 private WmsItemSkuMapper skuMapper;
56   - @Resource
57   - private WmsProperties wmsProperties;
58 49  
59 50 @MockitoBean
60 51 private WmsItemSkuService itemSkuService;
... ... @@ -64,7 +55,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
64 55 @Test
65 56 public void testChangeInventory_createInventory() {
66 57 // mock 数据
67   - wmsProperties.setBatchEnable(false);
68 58 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
69 59 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
70 60 WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "5.00");
... ... @@ -93,7 +83,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
93 83 @Test
94 84 public void testChangeInventory_updateInventory() {
95 85 // mock 数据
96   - wmsProperties.setBatchEnable(false);
97 86 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
98 87 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
99 88 inventoryMapper.insert(createInventory(sku.getId(), 100L, 1001L, "2.00"));
... ... @@ -118,7 +107,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
118 107 @Test
119 108 public void testChangeInventory_sameInventoryKeyKeepItemGranularity() {
120 109 // mock 数据
121   - wmsProperties.setBatchEnable(false);
122 110 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
123 111 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
124 112 WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "5.00");
... ... @@ -154,7 +142,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
154 142 @Test
155 143 public void testChangeInventory_sameExistingInventoryKeyKeepItemGranularity() {
156 144 // mock 数据
157   - wmsProperties.setBatchEnable(false);
158 145 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
159 146 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
160 147 inventoryMapper.insert(createInventory(sku.getId(), 100L, 1001L, "2.00"));
... ... @@ -191,7 +178,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
191 178 @Test
192 179 public void testChangeInventory_multipleInventoryKeysKeepItemGranularity() {
193 180 // mock 数据
194   - wmsProperties.setBatchEnable(false);
195 181 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
196 182 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
197 183 WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "5.00");
... ... @@ -240,7 +226,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
240 226 @Test
241 227 public void testChangeInventory_quantityNotEnough() {
242 228 // mock 数据
243   - wmsProperties.setBatchEnable(false);
244 229 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
245 230 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
246 231 inventoryMapper.insert(createInventory(sku.getId(), 100L, 1001L, "2.00"));
... ... @@ -255,7 +240,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
255 240 @Test
256 241 public void testChangeInventory_quantityNotEnoughWithoutInventory() {
257 242 // mock 数据
258   - wmsProperties.setBatchEnable(false);
259 243 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
260 244 WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
261 245 WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "-3.00");
... ... @@ -268,58 +252,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
268 252 }
269 253  
270 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 255 public void testGetInventoryPage_groupByWarehouse() {
324 256 // mock 数据
325 257 WmsItemDO item = createItem("ITEM-001", "红富士苹果");
... ... @@ -419,17 +351,6 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
419 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 354 private static WmsInventoryChangeReqDTO createChangeReq(Long skuId, Long warehouseId, Long areaId, String quantity) {
434 355 return new WmsInventoryChangeReqDTO()
435 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 61 // mock 数据
62 62 Long warehouseId = 100L;
63 63 Long skuId = 200L;
64   - Long inventoryDetailId = 300L;
65 64 WmsShipmentOrderDO order = createShipmentOrder(warehouseId);
66 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 69 shipmentOrderService.completeShipmentOrder(order.getId());
... ... @@ -84,7 +82,6 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest {
84 82 assertEquals(1, inventoryReqDTO.getItems().size());
85 83 assertEquals(skuId, inventoryReqDTO.getItems().get(0).getSkuId());
86 84 assertEquals(warehouseId, inventoryReqDTO.getItems().get(0).getWarehouseId());
87   - assertEquals(inventoryDetailId, inventoryReqDTO.getItems().get(0).getInventoryDetailId());
88 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 102 // mock 数据
106 103 WmsShipmentOrderDO order = createShipmentOrder(100L);
107 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 108 assertServiceException(() -> shipmentOrderService.completeShipmentOrder(order.getId()),
... ... @@ -134,7 +131,7 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest {
134 131 // mock 数据
135 132 WmsShipmentOrderDO order = createShipmentOrder(100L).setStatus(WmsOrderStatusEnum.CANCELED.getStatus());
136 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 137 shipmentOrderService.deleteShipmentOrder(order.getId());
... ... @@ -167,13 +164,12 @@ public class WmsShipmentOrderServiceImplTest extends BaseDbUnitTest {
167 164 }
168 165  
169 166 private static WmsShipmentOrderDetailDO createShipmentOrderDetail(Long orderId, Long skuId, Long warehouseId,
170   - Long areaId, Long inventoryDetailId) {
  167 + Long areaId) {
171 168 return WmsShipmentOrderDetailDO.builder()
172 169 .orderId(orderId)
173 170 .skuId(skuId)
174 171 .warehouseId(warehouseId)
175 172 .areaId(areaId)
176   - .inventoryDetailId(inventoryDetailId)
177 173 .quantity(new BigDecimal("2.00"))
178 174 .amount(new BigDecimal("20.00"))
179 175 .build();
... ...
yudao-module-wms/src/test/resources/sql/clean.sql
... ... @@ -3,7 +3,6 @@ DELETE FROM &quot;wms_shipment_order&quot;;
3 3 DELETE FROM "wms_receipt_order_detail";
4 4 DELETE FROM "wms_receipt_order";
5 5 DELETE FROM "wms_inventory_history";
6   -DELETE FROM "wms_inventory_detail";
7 6 DELETE FROM "wms_inventory";
8 7 DELETE FROM "wms_item_sku";
9 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 54 CONSTRAINT "uk_wms_inventory_sku_warehouse_area" UNIQUE ("sku_id", "warehouse_id", "area_id", "tenant_id", "deleted")
55 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 57 CREATE TABLE IF NOT EXISTS "wms_inventory_history" (
82 58 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
83 59 "warehouse_id" bigint NOT NULL,
... ... @@ -173,7 +149,6 @@ CREATE TABLE IF NOT EXISTS &quot;wms_shipment_order_detail&quot; (
173 149 "sku_id" bigint NOT NULL,
174 150 "warehouse_id" bigint NOT NULL,
175 151 "area_id" bigint NOT NULL DEFAULT '0',
176   - "inventory_detail_id" bigint DEFAULT NULL,
177 152 "batch_no" varchar(64) DEFAULT NULL,
178 153 "production_date" timestamp DEFAULT NULL,
179 154 "expiration_date" timestamp DEFAULT NULL,
... ...