ソースを参照

✨ feat(stock): 添加虚拟仓过滤功能

新增虚拟仓过滤模式,支持排除虚拟仓和仅查看虚拟仓的选项。更新相关请求对象和数据查询逻辑,以便后端处理虚拟仓的过滤需求。
YunaiV 2 ヶ月 前
コミット
03b421a862

+ 1 - 0
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java

@@ -92,6 +92,7 @@ public class MesWmMaterialStockServiceImpl implements MesWmMaterialStockService
             MesWmWarehouseDO virtualWarehouse = warehouseService.getWarehouseByCode(
                     MesWmWarehouseDO.WIP_VIRTUAL_WAREHOUSE);
             Assert.notNull(virtualWarehouse, "虚拟仓库(WIP_VIRTUAL_WAREHOUSE)不存在");
+            virtualWarehouseId = virtualWarehouse.getId();
         }
 
         // 2. 分页查询

+ 110 - 0
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImplTest.java

@@ -0,0 +1,110 @@
+package cn.iocoder.yudao.module.mes.service.wm.materialstock;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
+import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockPageReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
+import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockMapper;
+import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
+import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemTypeService;
+import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
+import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService;
+import jakarta.annotation.Resource;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.function.Consumer;
+
+import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.when;
+
+/**
+ * {@link MesWmMaterialStockServiceImpl} 的单元测试
+ *
+ * @author 芋道源码
+ */
+@Import(MesWmMaterialStockServiceImpl.class)
+public class MesWmMaterialStockServiceImplTest extends BaseDbUnitTest {
+
+    @Resource
+    private MesWmMaterialStockServiceImpl materialStockService;
+
+    @Resource
+    private MesWmMaterialStockMapper materialStockMapper;
+
+    @MockitoBean
+    private MesMdItemService itemService;
+    @MockitoBean
+    private MesMdItemTypeService itemTypeService;
+    @MockitoBean
+    private MesWmWarehouseAreaService areaService;
+    @MockitoBean
+    private MesWmWarehouseService warehouseService;
+
+    @Test
+    public void testGetMaterialStockPage_virtualFilterOnly() {
+        // 准备数据:虚拟仓库存 + 普通仓库存
+        Long virtualWarehouseId = 100L;
+        Long normalWarehouseId = 200L;
+        MesWmMaterialStockDO virtualStock = createMaterialStockPojo(o -> o.setWarehouseId(virtualWarehouseId));
+        MesWmMaterialStockDO normalStock = createMaterialStockPojo(o -> o.setWarehouseId(normalWarehouseId));
+        materialStockMapper.insert(virtualStock);
+        materialStockMapper.insert(normalStock);
+        mockVirtualWarehouse(virtualWarehouseId);
+
+        // 调用:只看虚拟仓
+        MesWmMaterialStockPageReqVO reqVO = new MesWmMaterialStockPageReqVO();
+        reqVO.setVirtualFilter(MesWmMaterialStockPageReqVO.VIRTUAL_FILTER_ONLY);
+        PageResult<MesWmMaterialStockDO> result = materialStockService.getMaterialStockPage(reqVO);
+
+        // 断言:只返回虚拟仓库存,且 total 与列表一致
+        assertEquals(1, result.getTotal());
+        assertEquals(1, result.getList().size());
+        assertEquals(virtualStock.getId(), result.getList().get(0).getId());
+    }
+
+    @Test
+    public void testGetMaterialStockPage_virtualFilterExclude() {
+        // 准备数据:虚拟仓库存 + 普通仓库存
+        Long virtualWarehouseId = 100L;
+        Long normalWarehouseId = 200L;
+        MesWmMaterialStockDO virtualStock = createMaterialStockPojo(o -> o.setWarehouseId(virtualWarehouseId));
+        MesWmMaterialStockDO normalStock = createMaterialStockPojo(o -> o.setWarehouseId(normalWarehouseId));
+        materialStockMapper.insert(virtualStock);
+        materialStockMapper.insert(normalStock);
+        mockVirtualWarehouse(virtualWarehouseId);
+
+        // 调用:排除虚拟仓
+        MesWmMaterialStockPageReqVO reqVO = new MesWmMaterialStockPageReqVO();
+        reqVO.setVirtualFilter(MesWmMaterialStockPageReqVO.VIRTUAL_FILTER_EXCLUDE);
+        PageResult<MesWmMaterialStockDO> result = materialStockService.getMaterialStockPage(reqVO);
+
+        // 断言:只返回普通仓库存,且 total 与列表一致
+        assertEquals(1, result.getTotal());
+        assertEquals(1, result.getList().size());
+        assertEquals(normalStock.getId(), result.getList().get(0).getId());
+    }
+
+    private MesWmMaterialStockDO createMaterialStockPojo(Consumer<MesWmMaterialStockDO> consumer) {
+        return randomPojo(MesWmMaterialStockDO.class, o -> {
+            o.setQuantity(new BigDecimal("10.00"));
+            o.setReceiptTime(LocalDateTime.of(2026, 1, 1, 0, 0));
+            o.setFrozen(false);
+            o.setDeleted(false);
+            consumer.accept(o);
+        });
+    }
+
+    private void mockVirtualWarehouse(Long virtualWarehouseId) {
+        MesWmWarehouseDO virtualWarehouse = new MesWmWarehouseDO();
+        virtualWarehouse.setId(virtualWarehouseId);
+        when(warehouseService.getWarehouseByCode(MesWmWarehouseDO.WIP_VIRTUAL_WAREHOUSE))
+                .thenReturn(virtualWarehouse);
+    }
+
+}

+ 1 - 0
yudao-module-mes/src/test/resources/sql/clean.sql

@@ -13,5 +13,6 @@ DELETE FROM "mes_wm_item_receipt";
 DELETE FROM "mes_wm_item_receipt_line";
 DELETE FROM "mes_wm_item_receipt_detail";
 DELETE FROM "mes_wm_batch";
+DELETE FROM "mes_wm_material_stock";
 DELETE FROM "mes_pro_task";
 DELETE FROM "mes_pro_route_process";

+ 25 - 0
yudao-module-mes/src/test/resources/sql/create_tables.sql

@@ -619,6 +619,31 @@ CREATE TABLE IF NOT EXISTS "mes_wm_batch" (
     PRIMARY KEY ("id")
 );
 
+-- ----------------------------
+-- MES 库存台账
+-- ----------------------------
+CREATE TABLE IF NOT EXISTS "mes_wm_material_stock" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "quantity" decimal(14,2) DEFAULT NULL,
+    "receipt_time" timestamp DEFAULT NULL,
+    "vendor_id" bigint DEFAULT NULL,
+    "item_type_id" bigint DEFAULT NULL,
+    "item_id" bigint DEFAULT NULL,
+    "batch_id" bigint DEFAULT NULL,
+    "batch_code" varchar(255) DEFAULT NULL,
+    "warehouse_id" bigint DEFAULT NULL,
+    "location_id" bigint DEFAULT NULL,
+    "area_id" bigint DEFAULT NULL,
+    "frozen" bit DEFAULT FALSE,
+    "creator" varchar(64) DEFAULT '',
+    "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar(64) DEFAULT '',
+    "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    "tenant_id" bigint NOT NULL DEFAULT 0,
+    PRIMARY KEY ("id")
+);
+
 -- ----------------------------
 -- MES 生产任务
 -- ----------------------------