Commit eba504d0bf5657aee84da5fc36edc71a3d3ac4bc
1 parent
d15470ef
feat(wms):补充 inventory 相关的单测
Showing
4 changed files
with
182 additions
and
2 deletions
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
yudao-module-wms/src/test/resources/sql/create_tables.sql
| ... | ... | @@ -50,7 +50,8 @@ CREATE TABLE IF NOT EXISTS "wms_inventory" ( |
| 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 "wms_inventory_detail" ( |
| 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 入库单明细表'; | ... | ... |