diff --git a/docs/mes-delivery-fields-20260908.md b/docs/mes-delivery-fields-20260908.md new file mode 100644 index 0000000..b94aba6 --- /dev/null +++ b/docs/mes-delivery-fields-20260908.md @@ -0,0 +1,15 @@ +# MES 配送申请字段 + +`insertDeliveryApplication` 的出库配送申请(deliveryDirection=0)保存 `deliveryPoint`,供 WMS 显示配送地点;`requiredTm` 是需求具体时间,为 null、空串或空白时兼容旧字段 `requireTime`;`isExpedited` 为 1(加急)或 0(正常)。以上信息保存至出库单主表,随原有归档流程进入历史表。 + +例如同一申请可传 `deliveryPoint="哈镘"`、`requiredTm="2026-09-08 15:30:00"`、`isExpedited=1`。旧 MES 请求未传新增信息时仍可接收。 + +先对共享数据库执行 `sql/20260908_order_management_fields.sql`,再发布 INTERFACE 和配套 WMS。两个仓库提供相同脚本,只需执行一次。迁移补齐业务表和历史表的新增字段,检查新增列的位置/类型与总列数,失败回滚。历史单据以前没有保存的配送地点不会自动补出。 + +使用 Java 8 构建。离线回归不启动应用、不连接数据库或 MES: + +```text +mvn -B -pl ruoyi-admin -am -Dtest=DeliveryApplicationPortServiceTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +WMS 的展示、回传状态、托盘码和入库历史查询说明见配套 WMS 的 `docs/order-management-20260908.md`。 diff --git a/ruoyi-admin/src/main/java/com/ruoyi/project/out/outStock/domain/OutStockout.java b/ruoyi-admin/src/main/java/com/ruoyi/project/out/outStock/domain/OutStockout.java index ed84741..f50cc7b 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/project/out/outStock/domain/OutStockout.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/project/out/outStock/domain/OutStockout.java @@ -107,6 +107,21 @@ public class OutStockout extends BaseEntity @Excel(name = "需求时间") private String requireTime; + /** 是否加急:1 加急,0 正常 */ + private Integer isExpedited; + + /** MES 分配的配送地点 */ + @Excel(name = "配送地点") + private String deliveryPoint; + + public String getDeliveryPoint() { + return deliveryPoint; + } + + public void setDeliveryPoint(String deliveryPoint) { + this.deliveryPoint = deliveryPoint; + } + public String getKdNum() { return kdNum; } @@ -337,6 +352,14 @@ public class OutStockout extends BaseEntity this.requireTime = requireTime; } + public Integer getIsExpedited() { + return isExpedited; + } + + public void setIsExpedited(Integer isExpedited) { + this.isExpedited = isExpedited; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @@ -357,6 +380,7 @@ public class OutStockout extends BaseEntity .append("finishDate", getFinishDate()) .append("FID", getFID()) .append("erpStockoutId", getErpStockoutId()) + .append("isExpedited", getIsExpedited()) .toString(); } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/port/domain/DeliveryApplicationMsg.java b/ruoyi-admin/src/main/java/com/ruoyi/web/port/domain/DeliveryApplicationMsg.java index c50aa53..951464f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/port/domain/DeliveryApplicationMsg.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/port/domain/DeliveryApplicationMsg.java @@ -32,6 +32,10 @@ public class DeliveryApplicationMsg { private String requester; @Excel(name = "需求时间") private String requireTime; + @Excel(name = "需求时间") + private String requiredTm; + @Excel(name = "是否加急") + private Integer isExpedited; private String org; @@ -67,6 +71,22 @@ public class DeliveryApplicationMsg { this.requireTime = requireTime; } + public String getRequiredTm() { + return requiredTm; + } + + public void setRequiredTm(String requiredTm) { + this.requiredTm = requiredTm; + } + + public Integer getIsExpedited() { + return isExpedited; + } + + public void setIsExpedited(Integer isExpedited) { + this.isExpedited = isExpedited; + } + @Excel(name = "条码集合") private List detailList; @@ -176,6 +196,8 @@ public class DeliveryApplicationMsg { ", preparationCode='" + preparationCode + '\'' + ", requester='" + requester + '\'' + ", requireTime='" + requireTime + '\'' + + ", requiredTm='" + requiredTm + '\'' + + ", isExpedited=" + isExpedited + ", org='" + org + '\'' + ", detailList=" + detailList + '}'; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/port/service/impl/PortServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/web/port/service/impl/PortServiceImpl.java index f8e7ab2..4cf10f5 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/port/service/impl/PortServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/port/service/impl/PortServiceImpl.java @@ -1572,8 +1572,14 @@ public class PortServiceImpl implements PortService { outStockout.setErpStockoutId(deliveryApplicationMsg.getCode()); // 新加字段 领料人 outStockout.setRequester(deliveryApplicationMsg.getRequester()); + outStockout.setDeliveryPoint(deliveryApplicationMsg.getDeliveryPoint()); // 新加字段 需求时间 - outStockout.setRequireTime(deliveryApplicationMsg.getRequireTime()); + String requiredTm = deliveryApplicationMsg.getRequiredTm(); + if (requiredTm == null || requiredTm.trim().isEmpty()) { + requiredTm = deliveryApplicationMsg.getRequireTime(); + } + outStockout.setRequireTime(requiredTm); + outStockout.setIsExpedited(deliveryApplicationMsg.getIsExpedited()); outStockoutMapper.insertOutStockout(outStockout); OutStockoutDetail outStockoutDetail = new OutStockoutDetail(); outStockoutDetail.setStockoutDetailId(jobId + "-1"); diff --git a/ruoyi-admin/src/main/resources/mapper/out/OutStockoutMapper.xml b/ruoyi-admin/src/main/resources/mapper/out/OutStockoutMapper.xml index f5b1010..d3f82b8 100644 --- a/ruoyi-admin/src/main/resources/mapper/out/OutStockoutMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/out/OutStockoutMapper.xml @@ -29,10 +29,12 @@ + + - select stockout_guid, stockout_id, out_type, create_date, department_no, customer_no, create_man_id, status, stockout_source, warehouse_id, class_now_id, exit_id, car_number, FID, erp_stockout_id,bar_code_list,tray_code_list,org,task_id,kd_num,requester,require_time from out_stockout + select stockout_guid, stockout_id, out_type, create_date, department_no, customer_no, create_man_id, status, stockout_source, warehouse_id, class_now_id, exit_id, car_number, FID, erp_stockout_id,bar_code_list,tray_code_list,org,task_id,kd_num,requester,require_time,is_expedited,time_ship_plan,delivery_point from out_stockout - \ No newline at end of file + diff --git a/ruoyi-admin/src/test/java/com/ruoyi/web/port/DeliveryApplicationPortServiceTest.java b/ruoyi-admin/src/test/java/com/ruoyi/web/port/DeliveryApplicationPortServiceTest.java new file mode 100644 index 0000000..3df2758 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/web/port/DeliveryApplicationPortServiceTest.java @@ -0,0 +1,46 @@ +package com.ruoyi.web.port; + +import com.alibaba.fastjson.JSON; +import com.ruoyi.project.bas.basJobId.service.IBasJobIdService; +import com.ruoyi.project.out.outStock.domain.OutStockout; +import com.ruoyi.project.out.outStock.mapper.OutStockoutMapper; +import com.ruoyi.project.out.outStockDetail.mapper.OutStockoutDetailMapper; +import com.ruoyi.web.port.domain.DeliveryApplicationMsg; +import com.ruoyi.web.port.service.impl.PortServiceImpl; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.springframework.test.util.ReflectionTestUtils; +import java.util.Collections; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +/** No Spring context, network, scheduler or database: capture the actual persistence boundary. */ +class DeliveryApplicationPortServiceTest { + @Test + void preservesMesDeliveryMetadataAndLegacyTime() { + for (String required : new String[]{"2026-09-08 15:30:00", "", " ", null}) { + PortServiceImpl service = new PortServiceImpl(); + IBasJobIdService ids = mock(IBasJobIdService.class); + OutStockoutMapper orders = mock(OutStockoutMapper.class); + ReflectionTestUtils.setField(service, "basJobIdService", ids); + ReflectionTestUtils.setField(service, "outStockoutMapper", orders); + ReflectionTestUtils.setField(service, "outStockoutDetailMapper", mock(OutStockoutDetailMapper.class)); + when(ids.getJobId("CK")).thenReturn("CK-TEST"); + DeliveryApplicationMsg msg = JSON.parseObject("{\"deliveryDirection\":\"0\"," + + "\"code\":\"MES-001\",\"deliveryPoint\":\"哈镘\",\"qtyPlan\":1.25," + + "\"requester\":\"叫料人\",\"isExpedited\":1,\"requireTime\":\"2026-09-08 16:00:00\"}", + DeliveryApplicationMsg.class); + msg.setRequiredTm(required); + assertEquals(0, service.insertDeliveryApplication(Collections.singletonList(msg)).getCode()); + ArgumentCaptor captured = ArgumentCaptor.forClass(OutStockout.class); + verify(orders).insertOutStockout(captured.capture()); + OutStockout row = captured.getValue(); + assertEquals("哈镘", row.getDeliveryPoint()); + assertEquals("叫料人", row.getRequester()); + assertEquals(Integer.valueOf(1), row.getIsExpedited()); + assertEquals("MES-001", row.getErpStockoutId()); + assertEquals(required == null || required.trim().isEmpty() ? "2026-09-08 16:00:00" : required, + row.getRequireTime()); + } + } +} diff --git a/sql/20260908_order_management_fields.sql b/sql/20260908_order_management_fields.sql new file mode 100644 index 0000000..e97057b --- /dev/null +++ b/sql/20260908_order_management_fields.sql @@ -0,0 +1,49 @@ +-- WMS / INTERFACE 共用数据库;先执行此脚本,再发布两个应用。 +-- 幂等执行。归档存储过程使用 INSERT ... SELECT *,新增列必须在两表相同位置且类型一致。 +SET XACT_ABORT ON; +BEGIN TRY + BEGIN TRANSACTION; + IF OBJECT_ID(N'dbo.out_stockout', N'U') IS NULL + OR OBJECT_ID(N'dbo.out_stockout_finish', N'U') IS NULL + THROW 51000, N'缺少出库业务表或历史表,请核对目标数据库', 1; + + IF COL_LENGTH(N'dbo.out_stockout', N'is_expedited') IS NULL + ALTER TABLE dbo.out_stockout ADD is_expedited int NULL; + IF COL_LENGTH(N'dbo.out_stockout_finish', N'is_expedited') IS NULL + ALTER TABLE dbo.out_stockout_finish ADD is_expedited int NULL; + + IF COL_LENGTH(N'dbo.out_stockout', N'delivery_point') IS NULL + ALTER TABLE dbo.out_stockout ADD delivery_point nvarchar(100) NULL; + IF COL_LENGTH(N'dbo.out_stockout_finish', N'delivery_point') IS NULL + ALTER TABLE dbo.out_stockout_finish ADD delivery_point nvarchar(100) NULL; + + -- 不移动/重建现有列;只验证本次字段的归档位置及总列数,不改动旧字段映射。 + IF (SELECT COUNT(*) FROM sys.columns WHERE object_id = OBJECT_ID(N'dbo.out_stockout')) + <> (SELECT COUNT(*) FROM sys.columns WHERE object_id = OBJECT_ID(N'dbo.out_stockout_finish')) + THROW 51001, N'业务表与历史表列数不同,已回滚;请核对归档映射', 1; + + IF EXISTS ( + SELECT 1 + FROM ( + SELECT ROW_NUMBER() OVER (ORDER BY column_id) AS ordinal, name, + system_type_id, max_length, precision, scale + FROM sys.columns WHERE object_id = OBJECT_ID(N'dbo.out_stockout') + ) a + FULL JOIN ( + SELECT ROW_NUMBER() OVER (ORDER BY column_id) AS ordinal, name, + system_type_id, max_length, precision, scale + FROM sys.columns WHERE object_id = OBJECT_ID(N'dbo.out_stockout_finish') + ) h ON a.ordinal = h.ordinal + WHERE (a.name IN (N'is_expedited', N'delivery_point') OR h.name IN (N'is_expedited', N'delivery_point')) + AND (a.name IS NULL OR h.name IS NULL OR a.name <> h.name + OR a.system_type_id <> h.system_type_id OR a.max_length <> h.max_length + OR a.precision <> h.precision OR a.scale <> h.scale) + ) + THROW 51001, N'新增字段在业务表与历史表中的位置或类型不同,已回滚;请核对归档映射', 1; + + COMMIT TRANSACTION; +END TRY +BEGIN CATCH + IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION; + THROW; +END CATCH;