Commit eba504d0bf5657aee84da5fc36edc71a3d3ac4bc

Authored by YunaiV
1 parent d15470ef

feat(wms):补充 inventory 相关的单测

yudao-module-wms/src/main/java/cn/iocoder/yudao/module/wms/dal/mysql/inventory/WmsInventoryMapper.java
... ... @@ -8,8 +8,11 @@ import cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.WmsInventoryPag
8 8 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDO;
9 9 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO;
10 10 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;
  11 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
11 12 import org.apache.ibatis.annotations.Mapper;
12 13  
  14 +import java.math.BigDecimal;
  15 +
13 16 /**
14 17 * WMS 库存 Mapper
15 18 *
... ... @@ -63,6 +66,32 @@ public interface WmsInventoryMapper extends BaseMapperX<WmsInventoryDO> {
63 66 return selectCount(WmsInventoryDO::getSkuId, skuId);
64 67 }
65 68  
  69 + default WmsInventoryDO selectBySkuIdAndWarehouseIdAndAreaId(Long skuId, Long warehouseId, Long areaId) {
  70 + return selectOne(WmsInventoryDO::getSkuId, skuId,
  71 + WmsInventoryDO::getWarehouseId, warehouseId,
  72 + WmsInventoryDO::getAreaId, areaId);
  73 + }
  74 +
  75 + default WmsInventoryDO selectBySkuIdAndWarehouseIdAndAreaIdForUpdate(Long skuId, Long warehouseId, Long areaId) {
  76 + return selectOneForUpdate(WmsInventoryDO::getSkuId, skuId,
  77 + WmsInventoryDO::getWarehouseId, warehouseId,
  78 + WmsInventoryDO::getAreaId, areaId);
  79 + }
  80 +
  81 + /**
  82 + * 增量更新库存数量
  83 + *
  84 + * @param id 库存编号
  85 + * @param quantity 变更数量
  86 + * @return 更新行数
  87 + */
  88 + @SuppressWarnings("UnusedReturnValue")
  89 + default int updateQuantity(Long id, BigDecimal quantity) {
  90 + return update(null, new LambdaUpdateWrapper<WmsInventoryDO>()
  91 + .eq(WmsInventoryDO::getId, id)
  92 + .setSql("quantity = quantity + (" + quantity + ")"));
  93 + }
  94 +
66 95 private static void appendDimensionOrder(MPJLambdaWrapperX<WmsInventoryDO> query, String type) {
67 96 if (StrUtil.equals(WmsInventoryPageReqVO.TYPE_WAREHOUSE, type)) {
68 97 query.orderByAsc(WmsInventoryDO::getWarehouseId)
... ...
yudao-module-wms/src/test/java/cn/iocoder/yudao/module/wms/service/inventory/WmsInventoryServiceImplTest.java
... ... @@ -3,21 +3,29 @@ 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.WmsInventoryHistoryDO;
6 7 import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.WmsInventoryDO;
7 8 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemDO;
8 9 import cn.iocoder.yudao.module.wms.dal.dataobject.md.item.WmsItemSkuDO;
  10 +import cn.iocoder.yudao.module.wms.dal.mysql.inventory.WmsInventoryHistoryMapper;
9 11 import cn.iocoder.yudao.module.wms.dal.mysql.inventory.WmsInventoryMapper;
10 12 import cn.iocoder.yudao.module.wms.dal.mysql.md.item.WmsItemMapper;
11 13 import cn.iocoder.yudao.module.wms.dal.mysql.md.item.WmsItemSkuMapper;
  14 +import cn.iocoder.yudao.module.wms.enums.inventory.WmsInventoryOrderTypeEnum;
  15 +import cn.iocoder.yudao.module.wms.framework.config.WmsProperties;
  16 +import cn.iocoder.yudao.module.wms.service.inventory.dto.WmsInventoryChangeReqDTO;
12 17 import jakarta.annotation.Resource;
13 18 import org.junit.jupiter.api.Test;
14 19 import org.springframework.context.annotation.Import;
15 20  
16 21 import java.math.BigDecimal;
  22 +import java.util.List;
17 23  
18 24 import static org.junit.jupiter.api.Assertions.assertEquals;
  25 +import static org.junit.jupiter.api.Assertions.assertNotNull;
19 26  
20   -@Import(WmsInventoryServiceImpl.class)
  27 +@Import({WmsInventoryServiceImpl.class, WmsInventoryDetailServiceImpl.class, WmsInventoryHistoryServiceImpl.class,
  28 + WmsProperties.class})
21 29 public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
22 30  
23 31 @Resource
... ... @@ -26,9 +34,67 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
26 34 @Resource
27 35 private WmsInventoryMapper inventoryMapper;
28 36 @Resource
  37 + private WmsInventoryHistoryMapper inventoryHistoryMapper;
  38 + @Resource
29 39 private WmsItemMapper itemMapper;
30 40 @Resource
31 41 private WmsItemSkuMapper skuMapper;
  42 + @Resource
  43 + private WmsProperties wmsProperties;
  44 +
  45 + @Test
  46 + public void testChangeInventory_createInventory() {
  47 + // mock 数据
  48 + wmsProperties.setBatchEnable(false);
  49 + WmsItemDO item = createItem("ITEM-001", "红富士苹果");
  50 + WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
  51 + WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "5.00");
  52 +
  53 + // 调用
  54 + inventoryService.changeInventory(reqDTO);
  55 +
  56 + // 断言:库存余额
  57 + WmsInventoryDO inventory = inventoryMapper.selectBySkuIdAndWarehouseIdAndAreaId(sku.getId(), 100L, 1001L);
  58 + assertNotNull(inventory);
  59 + assertEquals(0, new BigDecimal("5.00").compareTo(inventory.getQuantity()));
  60 + // 断言:库存流水
  61 + List<WmsInventoryHistoryDO> histories = inventoryHistoryMapper.selectList();
  62 + assertEquals(1, histories.size());
  63 + WmsInventoryHistoryDO history = histories.get(0);
  64 + assertEquals(sku.getId(), history.getSkuId());
  65 + assertEquals(100L, history.getWarehouseId());
  66 + assertEquals(1001L, history.getAreaId());
  67 + assertEquals(0, BigDecimal.ZERO.compareTo(history.getBeforeQuantity()));
  68 + assertEquals(0, new BigDecimal("5.00").compareTo(history.getAfterQuantity()));
  69 + assertEquals(reqDTO.getOrderId(), history.getOrderId());
  70 + assertEquals(reqDTO.getOrderNo(), history.getOrderNo());
  71 + assertEquals(reqDTO.getOrderType(), history.getOrderType());
  72 + }
  73 +
  74 + @Test
  75 + public void testChangeInventory_updateInventory() {
  76 + // mock 数据
  77 + wmsProperties.setBatchEnable(false);
  78 + WmsItemDO item = createItem("ITEM-001", "红富士苹果");
  79 + WmsItemSkuDO sku = createSku(item.getId(), "SKU-001", "10kg 箱装");
  80 + inventoryMapper.insert(createInventory(sku.getId(), 100L, 1001L, "2.00"));
  81 + WmsInventoryChangeReqDTO reqDTO = createChangeReq(sku.getId(), 100L, 1001L, "3.00");
  82 +
  83 + // 调用
  84 + inventoryService.changeInventory(reqDTO);
  85 +
  86 + // 断言:库存余额
  87 + WmsInventoryDO inventory = inventoryMapper.selectBySkuIdAndWarehouseIdAndAreaId(sku.getId(), 100L, 1001L);
  88 + assertNotNull(inventory);
  89 + assertEquals(0, new BigDecimal("5.00").compareTo(inventory.getQuantity()));
  90 + // 断言:库存流水
  91 + List<WmsInventoryHistoryDO> histories = inventoryHistoryMapper.selectList();
  92 + assertEquals(1, histories.size());
  93 + WmsInventoryHistoryDO history = histories.get(0);
  94 + assertEquals(0, new BigDecimal("2.00").compareTo(history.getBeforeQuantity()));
  95 + assertEquals(0, new BigDecimal("5.00").compareTo(history.getAfterQuantity()));
  96 + assertEquals(0, new BigDecimal("3.00").compareTo(history.getQuantity()));
  97 + }
32 98  
33 99 @Test
34 100 public void testGetInventoryPage_groupByWarehouse() {
... ... @@ -125,4 +191,18 @@ public class WmsInventoryServiceImplTest extends BaseDbUnitTest {
125 191 .build();
126 192 }
127 193  
  194 + private static WmsInventoryChangeReqDTO createChangeReq(Long skuId, Long warehouseId, Long areaId, String quantity) {
  195 + return new WmsInventoryChangeReqDTO()
  196 + .setOrderId(1L)
  197 + .setOrderNo("RK202605120001")
  198 + .setOrderType(WmsInventoryOrderTypeEnum.RECEIPT.getType())
  199 + .setItems(List.of(new WmsInventoryChangeReqDTO.Item()
  200 + .setSkuId(skuId)
  201 + .setWarehouseId(warehouseId)
  202 + .setAreaId(areaId)
  203 + .setQuantity(new BigDecimal(quantity))
  204 + .setAmount(new BigDecimal("100.00"))
  205 + .setRemark("测试入库")));
  206 + }
  207 +
128 208 }
... ...
yudao-module-wms/src/test/resources/sql/clean.sql
  1 +DELETE FROM "wms_receipt_order_detail";
  2 +DELETE FROM "wms_receipt_order";
  3 +DELETE FROM "wms_inventory_history";
1 4 DELETE FROM "wms_inventory_detail";
2 5 DELETE FROM "wms_inventory";
3 6 DELETE FROM "wms_item_sku";
... ...
yudao-module-wms/src/test/resources/sql/create_tables.sql
... ... @@ -50,7 +50,8 @@ CREATE TABLE IF NOT EXISTS &quot;wms_inventory&quot; (
50 50 "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
51 51 "deleted" bit NOT NULL DEFAULT FALSE,
52 52 "tenant_id" bigint NOT NULL DEFAULT '0',
53   - PRIMARY KEY ("id")
  53 + PRIMARY KEY ("id"),
  54 + CONSTRAINT "uk_wms_inventory_sku_warehouse_area" UNIQUE ("sku_id", "warehouse_id", "area_id", "tenant_id", "deleted")
54 55 ) COMMENT 'WMS 库存表';
55 56  
56 57 CREATE TABLE IF NOT EXISTS "wms_inventory_detail" (
... ... @@ -76,3 +77,70 @@ CREATE TABLE IF NOT EXISTS &quot;wms_inventory_detail&quot; (
76 77 "tenant_id" bigint NOT NULL DEFAULT '0',
77 78 PRIMARY KEY ("id")
78 79 ) COMMENT 'WMS 库存明细表';
  80 +
  81 +CREATE TABLE IF NOT EXISTS "wms_inventory_history" (
  82 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  83 + "warehouse_id" bigint NOT NULL,
  84 + "area_id" bigint NOT NULL DEFAULT '0',
  85 + "sku_id" bigint NOT NULL,
  86 + "quantity" decimal(24, 6) NOT NULL DEFAULT '0',
  87 + "before_quantity" decimal(24, 6) DEFAULT NULL,
  88 + "after_quantity" decimal(24, 6) DEFAULT NULL,
  89 + "batch_no" varchar(64) DEFAULT NULL,
  90 + "production_date" timestamp DEFAULT NULL,
  91 + "expiration_date" timestamp DEFAULT NULL,
  92 + "amount" decimal(24, 6) DEFAULT NULL,
  93 + "remark" varchar(255) DEFAULT NULL,
  94 + "order_id" bigint DEFAULT NULL,
  95 + "order_no" varchar(64) DEFAULT NULL,
  96 + "order_type" tinyint DEFAULT NULL,
  97 + "creator" varchar(64) DEFAULT '',
  98 + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  99 + "updater" varchar(64) DEFAULT '',
  100 + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  101 + "deleted" bit NOT NULL DEFAULT FALSE,
  102 + "tenant_id" bigint NOT NULL DEFAULT '0',
  103 + PRIMARY KEY ("id")
  104 +) COMMENT 'WMS 库存流水表';
  105 +
  106 +CREATE TABLE IF NOT EXISTS "wms_receipt_order" (
  107 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  108 + "no" varchar(64) NOT NULL,
  109 + "type" tinyint NOT NULL,
  110 + "status" tinyint NOT NULL DEFAULT '0',
  111 + "biz_order_no" varchar(64) DEFAULT NULL,
  112 + "merchant_id" bigint DEFAULT NULL,
  113 + "remark" varchar(255) DEFAULT NULL,
  114 + "warehouse_id" bigint NOT NULL,
  115 + "area_id" bigint NOT NULL DEFAULT '0',
  116 + "total_quantity" decimal(20, 2) NOT NULL DEFAULT '0',
  117 + "total_amount" decimal(10, 2) DEFAULT NULL,
  118 + "creator" varchar(64) DEFAULT '',
  119 + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  120 + "updater" varchar(64) DEFAULT '',
  121 + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  122 + "deleted" bit NOT NULL DEFAULT FALSE,
  123 + "tenant_id" bigint NOT NULL DEFAULT '0',
  124 + PRIMARY KEY ("id")
  125 +) COMMENT 'WMS 入库单表';
  126 +
  127 +CREATE TABLE IF NOT EXISTS "wms_receipt_order_detail" (
  128 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  129 + "remark" varchar(255) DEFAULT NULL,
  130 + "order_id" bigint NOT NULL,
  131 + "sku_id" bigint NOT NULL,
  132 + "warehouse_id" bigint NOT NULL,
  133 + "area_id" bigint NOT NULL DEFAULT '0',
  134 + "batch_no" varchar(64) DEFAULT NULL,
  135 + "production_date" timestamp DEFAULT NULL,
  136 + "expiration_date" timestamp DEFAULT NULL,
  137 + "quantity" decimal(20, 2) NOT NULL DEFAULT '0',
  138 + "amount" decimal(10, 2) DEFAULT NULL,
  139 + "creator" varchar(64) DEFAULT '',
  140 + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  141 + "updater" varchar(64) DEFAULT '',
  142 + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  143 + "deleted" bit NOT NULL DEFAULT FALSE,
  144 + "tenant_id" bigint NOT NULL DEFAULT '0',
  145 + PRIMARY KEY ("id")
  146 +) COMMENT 'WMS 入库单明细表';
... ...