diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockPageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockPageReqVO.java index 81d3392..b5a18ac 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockPageReqVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockPageReqVO.java @@ -12,6 +12,18 @@ import lombok.ToString; @ToString(callSuper = true) public class MesWmMaterialStockPageReqVO extends PageParam { + /** + * 虚拟仓过滤模式 - 排除虚拟仓 + */ + public static final String VIRTUAL_FILTER_EXCLUDE = "exclude"; + /** + * 虚拟仓过滤模式 - 只看虚拟仓 + */ + public static final String VIRTUAL_FILTER_ONLY = "only"; + + @Schema(description = "虚拟仓过滤模式", example = "exclude") + private String virtualFilter; + @Schema(description = "物料分类编号", example = "1") private Long itemTypeId; diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java index b082308..2810c05 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java @@ -21,8 +21,9 @@ public interface MesWmMaterialStockMapper extends BaseMapperX selectPage(MesWmMaterialStockPageReqVO reqVO, Collection itemTypeIds, - Collection itemIds) { - return selectPage(reqVO, new LambdaQueryWrapperX() + Collection itemIds, + Long virtualWarehouseId) { + LambdaQueryWrapperX wrapper = new LambdaQueryWrapperX() .inIfPresent(MesWmMaterialStockDO::getItemTypeId, itemTypeIds) .inIfPresent(MesWmMaterialStockDO::getItemId, itemIds) .likeIfPresent(MesWmMaterialStockDO::getBatchCode, reqVO.getBatchCode()) @@ -31,9 +32,18 @@ public interface MesWmMaterialStockMapper extends BaseMapperX + * 覆盖:selectListByLineId、selectListBySalesId、deleteByLineId、deleteBySalesId + */ +public class MesWmProductSalesDetailMapperTest extends BaseDbUnitTest { + + @Resource + private MesWmProductSalesDetailMapper detailMapper; + + // ==================== 辅助方法 ==================== + + /** + * 创建明细 DO,固定 BigDecimal 精度为 2 位,避免 H2 decimal(14,2) 精度不匹配 + */ + private MesWmProductSalesDetailDO createDetailPojo(Consumer consumer) { + return randomPojo(MesWmProductSalesDetailDO.class, o -> { + o.setQuantity(new BigDecimal("10.00")); + consumer.accept(o); + }); + } + + // ==================== selectListByLineId ==================== + + @Test + public void testSelectListByLineId_match() { + Long lineId = 100L; + MesWmProductSalesDetailDO match = createDetailPojo(o -> { + o.setLineId(lineId); + o.setSalesId(1L); + }); + detailMapper.insert(match); + // 插入另一条不同 lineId 的记录,不应被返回 + detailMapper.insert(cloneIgnoreId(match, o -> o.setLineId(999L))); + + List result = detailMapper.selectListByLineId(lineId); + + assertEquals(1, result.size()); + assertPojoEquals(match, result.get(0)); + } + + @Test + public void testSelectListByLineId_multipleRows() { + Long lineId = 200L; + MesWmProductSalesDetailDO detail1 = createDetailPojo(o -> { + o.setLineId(lineId); + o.setSalesId(2L); + }); + MesWmProductSalesDetailDO detail2 = createDetailPojo(o -> { + o.setLineId(lineId); + o.setSalesId(2L); + }); + detailMapper.insert(detail1); + detailMapper.insert(detail2); + + List result = detailMapper.selectListByLineId(lineId); + + assertEquals(2, result.size()); + } + + @Test + public void testSelectListByLineId_noMatch() { + MesWmProductSalesDetailDO detail = createDetailPojo(o -> { + o.setLineId(300L); + o.setSalesId(3L); + }); + detailMapper.insert(detail); + + List result = detailMapper.selectListByLineId(999L); + + assertTrue(result.isEmpty()); + } + + // ==================== selectListBySalesId ==================== + + @Test + public void testSelectListBySalesId_match() { + Long salesId = 10L; + MesWmProductSalesDetailDO match = createDetailPojo(o -> { + o.setSalesId(salesId); + o.setLineId(1L); + }); + detailMapper.insert(match); + // 插入另一条不同 salesId 的记录 + detailMapper.insert(cloneIgnoreId(match, o -> o.setSalesId(888L))); + + List result = detailMapper.selectListBySalesId(salesId); + + assertEquals(1, result.size()); + assertPojoEquals(match, result.get(0)); + } + + @Test + public void testSelectListBySalesId_multipleRows() { + Long salesId = 20L; + MesWmProductSalesDetailDO detail1 = createDetailPojo(o -> { + o.setSalesId(salesId); + o.setLineId(11L); + }); + MesWmProductSalesDetailDO detail2 = createDetailPojo(o -> { + o.setSalesId(salesId); + o.setLineId(12L); + }); + detailMapper.insert(detail1); + detailMapper.insert(detail2); + + List result = detailMapper.selectListBySalesId(salesId); + + assertEquals(2, result.size()); + } + + @Test + public void testSelectListBySalesId_noMatch() { + MesWmProductSalesDetailDO detail = createDetailPojo(o -> { + o.setSalesId(30L); + o.setLineId(2L); + }); + detailMapper.insert(detail); + + List result = detailMapper.selectListBySalesId(9999L); + + assertTrue(result.isEmpty()); + } + + // ==================== deleteByLineId ==================== + + @Test + public void testDeleteByLineId_deletesOnlyTargetLine() { + Long lineId = 400L; + MesWmProductSalesDetailDO toDelete = createDetailPojo(o -> { + o.setLineId(lineId); + o.setSalesId(4L); + }); + MesWmProductSalesDetailDO toKeep = createDetailPojo(o -> { + o.setLineId(500L); + o.setSalesId(4L); + }); + detailMapper.insert(toDelete); + detailMapper.insert(toKeep); + + detailMapper.deleteByLineId(lineId); + + // lineId=400 的记录已被逻辑删除 + List deletedResult = detailMapper.selectListByLineId(lineId); + assertTrue(deletedResult.isEmpty(), "lineId=400 的记录应被删除"); + + // lineId=500 的记录保留 + List keptResult = detailMapper.selectListByLineId(500L); + assertEquals(1, keptResult.size()); + } + + @Test + public void testDeleteByLineId_multipleRows() { + Long lineId = 600L; + detailMapper.insert(createDetailPojo(o -> { o.setLineId(lineId); o.setSalesId(5L); })); + detailMapper.insert(createDetailPojo(o -> { o.setLineId(lineId); o.setSalesId(5L); })); + + detailMapper.deleteByLineId(lineId); + + List result = detailMapper.selectListByLineId(lineId); + assertTrue(result.isEmpty(), "同 lineId 下的所有记录均应被删除"); + } + + // ==================== deleteBySalesId ==================== + + @Test + public void testDeleteBySalesId_deletesOnlyTargetSales() { + Long salesId = 700L; + MesWmProductSalesDetailDO toDelete = createDetailPojo(o -> { + o.setSalesId(salesId); + o.setLineId(6L); + }); + MesWmProductSalesDetailDO toKeep = createDetailPojo(o -> { + o.setSalesId(800L); + o.setLineId(7L); + }); + detailMapper.insert(toDelete); + detailMapper.insert(toKeep); + + detailMapper.deleteBySalesId(salesId); + + // salesId=700 的记录已被逻辑删除 + List deletedResult = detailMapper.selectListBySalesId(salesId); + assertTrue(deletedResult.isEmpty(), "salesId=700 的记录应被删除"); + + // salesId=800 的记录保留 + List keptResult = detailMapper.selectListBySalesId(800L); + assertEquals(1, keptResult.size()); + } + + @Test + public void testDeleteBySalesId_multipleRows() { + Long salesId = 900L; + detailMapper.insert(createDetailPojo(o -> { o.setSalesId(salesId); o.setLineId(8L); })); + detailMapper.insert(createDetailPojo(o -> { o.setSalesId(salesId); o.setLineId(9L); })); + detailMapper.insert(createDetailPojo(o -> { o.setSalesId(salesId); o.setLineId(10L); })); + + detailMapper.deleteBySalesId(salesId); + + List result = detailMapper.selectListBySalesId(salesId); + assertTrue(result.isEmpty(), "同 salesId 下的所有记录均应被删除"); + } + +} diff --git a/yudao-module-mes/src/test/resources/sql/create_tables.sql b/yudao-module-mes/src/test/resources/sql/create_tables.sql index 1f3674c..49805d6 100644 --- a/yudao-module-mes/src/test/resources/sql/create_tables.sql +++ b/yudao-module-mes/src/test/resources/sql/create_tables.sql @@ -678,3 +678,28 @@ CREATE TABLE IF NOT EXISTS "mes_pro_route_process" ( "tenant_id" bigint NOT NULL DEFAULT 0, PRIMARY KEY ("id") ); + +-- ---------------------------- +-- MES 销售出库明细 +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "mes_wm_product_sales_detail" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "line_id" bigint NOT NULL, + "sales_id" bigint NOT NULL, + "item_id" bigint NOT NULL, + "quantity" decimal(14,2) DEFAULT NULL, + "material_stock_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, + "remark" varchar(500) DEFAULT NULL, + "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") +);