Compare commits
2 Commits
5ba4f1fdb3
...
1cf4a55ea1
| Author | SHA1 | Date | |
|---|---|---|---|
| 1cf4a55ea1 | |||
| 56beeacbfe |
15
docs/mes-delivery-fields-20260908.md
Normal file
15
docs/mes-delivery-fields-20260908.md
Normal file
@@ -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`。
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
# Interface and WMS Field Expansion Implementation Plan
|
||||||
|
|
||||||
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
|
**Goal:** Persist and display the requested delivery, completion, and sales-shipment fields across FT363-INTERFACE and FT363-WMS.
|
||||||
|
|
||||||
|
**Architecture:** Extend the existing port DTOs and service-to-domain mappings in FT363-INTERFACE, add nullable SQL Server columns and MyBatis mappings, then extend the existing WMS domain/query/table definitions. `requiredTm` reuses the existing `require_time` column for backward compatibility.
|
||||||
|
|
||||||
|
**Tech Stack:** Java 8, Spring Boot 2.5, MyBatis XML, SQL Server, Thymeleaf, Bootstrap Table, JUnit.
|
||||||
|
|
||||||
|
## Global Constraints
|
||||||
|
|
||||||
|
- Preserve unrelated dirty-worktree changes.
|
||||||
|
- New database columns are nullable and migrations are idempotent.
|
||||||
|
- Keep existing endpoint response codes and transaction boundaries unchanged.
|
||||||
|
- Use exact API property names: `requiredTm`, `isExpedited`, `effectiveDate`, `expirationDate`, `oaProductShipNum`.
|
||||||
|
|
||||||
|
### Task 1: Add failing contract and mapping tests
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `FT363-INTERFACE/ruoyi-admin/src/test/java/com/ruoyi/web/port/FieldExpansionContractTest.java`
|
||||||
|
|
||||||
|
**Interfaces:**
|
||||||
|
- Consumes the three request DTOs and their detail DTO.
|
||||||
|
- Produces executable assertions for JSON binding and mapping source expectations.
|
||||||
|
|
||||||
|
- [ ] **Step 1: Write failing tests** for JSON binding of all five exact names and for the new persistence properties.
|
||||||
|
- [ ] **Step 2: Run `mvn -pl ruoyi-admin -Dtest=FieldExpansionContractTest test`** and confirm failure because the properties do not yet exist.
|
||||||
|
|
||||||
|
### Task 2: Extend FT363-INTERFACE DTOs and persistence mapping
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-admin/src/main/java/com/ruoyi/web/port/domain/DeliveryApplicationMsg.java`
|
||||||
|
- Modify: `ruoyi-admin/src/main/java/com/ruoyi/web/port/domain/CompletionRecordDetailMsg.java`
|
||||||
|
- Modify: `ruoyi-admin/src/main/java/com/ruoyi/web/port/domain/GoodsSaleSendMsg.java`
|
||||||
|
- Modify: `ruoyi-admin/src/main/java/com/ruoyi/project/out/outStock/domain/OutStockout.java`
|
||||||
|
- Modify: `ruoyi-admin/src/main/java/com/ruoyi/project/in/stockindetail/domain/StockinDetail.java`
|
||||||
|
- Modify: `ruoyi-admin/src/main/java/com/ruoyi/project/out/outStockDetail/domain/OutStockoutDetail.java`
|
||||||
|
- Modify: `ruoyi-admin/src/main/resources/mapper/out/OutStockoutMapper.xml`
|
||||||
|
- Modify: `ruoyi-admin/src/main/resources/mapper/in/StockinDetailMapper.xml`
|
||||||
|
- Modify: `ruoyi-admin/src/main/resources/mapper/out/OutStockoutDetailMapper.xml`
|
||||||
|
- Modify: `ruoyi-admin/src/main/java/com/ruoyi/web/port/service/impl/PortServiceImpl.java`
|
||||||
|
|
||||||
|
- [ ] **Step 1:** Add DTO getters/setters using exact JSON names, retaining `requireTime` compatibility through an alias or equivalent setter.
|
||||||
|
- [ ] **Step 2:** Add nullable persistence properties and MyBatis result/select/insert mappings for `is_expedited`, `effective_date`, `expiration_date`, and `oa_product_ship_num`; map `requiredTm` to `requireTime`.
|
||||||
|
- [ ] **Step 3:** Map values in the three existing service methods without changing transaction or response behavior.
|
||||||
|
- [ ] **Step 4:** Run the focused contract tests and confirm they pass.
|
||||||
|
|
||||||
|
### Task 3: Add idempotent SQL migration scripts
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `FT363-INTERFACE/sql/20260721_add_mes_field_expansion.sql`
|
||||||
|
- Create: `FT363-WMS/sql/20260721_add_mes_field_expansion.sql`
|
||||||
|
|
||||||
|
- [ ] **Step 1:** Add `COL_LENGTH` guarded `ALTER TABLE` statements for `out_stockout.is_expedited`, `in_stockin_detail.effective_date`, `in_stockin_detail.expiration_date`, and `out_stockout_detail.oa_product_ship_num`.
|
||||||
|
- [ ] **Step 2:** Verify each statement is valid SQL Server syntax and can run repeatedly without attempting a duplicate column.
|
||||||
|
|
||||||
|
### Task 4: Display fields in FT363-WMS
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `ruoyi-admin/src/main/java/com/ruoyi/project/out/outStock/domain/OutStockout.java`
|
||||||
|
- Modify: `ruoyi-admin/src/main/resources/mapper/out/OutStockoutMapper.xml`
|
||||||
|
- Modify: `ruoyi-admin/src/main/resources/templates/out/stockout.html`
|
||||||
|
- Modify: `ruoyi-admin/src/main/java/com/ruoyi/project/in/stockindetail/domain/StockinDetail.java`
|
||||||
|
- Modify: `ruoyi-admin/src/main/resources/mapper/in/StockinDetailMapper.xml`
|
||||||
|
- Modify: `ruoyi-admin/src/main/resources/templates/in/stockin/stockinManage.html`
|
||||||
|
- Modify: `ruoyi-admin/src/main/java/com/ruoyi/project/out/outStockDetail/domain/OutStockoutDetail.java`
|
||||||
|
- Modify: `ruoyi-admin/src/main/resources/mapper/out/OutStockoutDetailMapper.xml`
|
||||||
|
- Modify: `ruoyi-admin/src/main/resources/templates/out/stockout.html`
|
||||||
|
|
||||||
|
- [ ] **Step 1:** Add the new result/select mappings and domain getters/setters in WMS.
|
||||||
|
- [ ] **Step 2:** Add visible Bootstrap Table columns with Chinese labels and a `0`/`1` formatter for expedited status.
|
||||||
|
- [ ] **Step 3:** Run static field/column checks and compile WMS.
|
||||||
|
|
||||||
|
### Task 5: Full verification
|
||||||
|
|
||||||
|
- [ ] **Step 1:** Run `mvn -pl ruoyi-admin -DskipTests compile` in FT363-INTERFACE.
|
||||||
|
- [ ] **Step 2:** Run focused and existing tests that do not require unavailable external databases.
|
||||||
|
- [ ] **Step 3:** Run `mvn -pl ruoyi-admin -DskipTests compile` in FT363-WMS.
|
||||||
|
- [ ] **Step 4:** Review `git diff` and `git status` in both repositories to ensure only scoped files changed.
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# Interface and WMS Field Expansion Design
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
Extend three MES-to-WMS contracts without changing their existing business flow:
|
||||||
|
|
||||||
|
- `getDeliveryApplicationMsg`: accept `requiredTm` and `isExpedited`.
|
||||||
|
- `getCompletionRecordMsg`: accept `effectiveDate` and `expirationDate` on each detail.
|
||||||
|
- `getGoodsSaleSendMsg`: accept `oaProductShipNum`.
|
||||||
|
|
||||||
|
The existing `out_stockout.require_time` column is retained as the persistence target for the new API property `requiredTm`; the legacy API property `requireTime` remains accepted for compatibility where practical.
|
||||||
|
|
||||||
|
## Data Flow
|
||||||
|
|
||||||
|
`PortController` deserializes the request DTOs. `PortServiceImpl` maps DTO values into the existing WMS domain objects and MyBatis insert statements. WMS list/detail queries map the new columns into domain properties and Thymeleaf Bootstrap Table definitions display them.
|
||||||
|
|
||||||
|
Field ownership:
|
||||||
|
|
||||||
|
| API field | Domain/table | Physical column | WMS view |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `requiredTm` | `OutStockout` / `out_stockout` | existing `require_time` | 出库主表需求时间 |
|
||||||
|
| `isExpedited` | `OutStockout` / `out_stockout` | new `is_expedited` | 出库主表是否加急 |
|
||||||
|
| `effectiveDate` | `StockinDetail` / `in_stockin_detail` | new `effective_date` | 入库明细生效日期 |
|
||||||
|
| `expirationDate` | `StockinDetail` / `in_stockin_detail` | new `expiration_date` | 入库明细失效日期 |
|
||||||
|
| `oaProductShipNum` | `OutStockoutDetail` / `out_stockout_detail` | new `oa_product_ship_num` | 出库明细 OA 产品发货流水号 |
|
||||||
|
|
||||||
|
## Database Migration
|
||||||
|
|
||||||
|
Provide an idempotent SQL Server script under `sql/` which uses `COL_LENGTH` checks before adding the four missing runtime columns and their `_finish` archive-table counterparts. The existing `require_time` column is not duplicated. New columns are nullable so older interface payloads and existing rows remain valid; matching archive columns preserve the existing `select *` archive procedures.
|
||||||
|
|
||||||
|
## Compatibility and Errors
|
||||||
|
|
||||||
|
Missing new fields are accepted as `null`/empty values and do not change existing insert behavior. `isExpedited` uses integer values `0` and `1` when supplied. Existing transaction and response handling remain unchanged.
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
- DTO JSON binding tests assert the exact camel-case API names.
|
||||||
|
- Mapper XML checks assert every new property is present in result, select, insert, and value mappings where applicable.
|
||||||
|
- Service tests assert the three mapping paths copy values into persistence objects.
|
||||||
|
- Maven tests/compilation run for both projects where the local environment permits.
|
||||||
|
- Static checks verify WMS table columns use the exact new property names and Chinese labels.
|
||||||
@@ -107,6 +107,21 @@ public class OutStockout extends BaseEntity
|
|||||||
@Excel(name = "需求时间")
|
@Excel(name = "需求时间")
|
||||||
private String requireTime;
|
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() {
|
public String getKdNum() {
|
||||||
return kdNum;
|
return kdNum;
|
||||||
}
|
}
|
||||||
@@ -337,6 +352,14 @@ public class OutStockout extends BaseEntity
|
|||||||
this.requireTime = requireTime;
|
this.requireTime = requireTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getIsExpedited() {
|
||||||
|
return isExpedited;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsExpedited(Integer isExpedited) {
|
||||||
|
this.isExpedited = isExpedited;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
@@ -357,6 +380,7 @@ public class OutStockout extends BaseEntity
|
|||||||
.append("finishDate", getFinishDate())
|
.append("finishDate", getFinishDate())
|
||||||
.append("FID", getFID())
|
.append("FID", getFID())
|
||||||
.append("erpStockoutId", getErpStockoutId())
|
.append("erpStockoutId", getErpStockoutId())
|
||||||
|
.append("isExpedited", getIsExpedited())
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ public class DeliveryApplicationMsg {
|
|||||||
private String requester;
|
private String requester;
|
||||||
@Excel(name = "需求时间")
|
@Excel(name = "需求时间")
|
||||||
private String requireTime;
|
private String requireTime;
|
||||||
|
@Excel(name = "需求时间")
|
||||||
|
private String requiredTm;
|
||||||
|
@Excel(name = "是否加急")
|
||||||
|
private Integer isExpedited;
|
||||||
|
|
||||||
private String org;
|
private String org;
|
||||||
|
|
||||||
@@ -67,6 +71,22 @@ public class DeliveryApplicationMsg {
|
|||||||
this.requireTime = requireTime;
|
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 = "条码集合")
|
@Excel(name = "条码集合")
|
||||||
private List<BarCodeDetail> detailList;
|
private List<BarCodeDetail> detailList;
|
||||||
|
|
||||||
@@ -176,6 +196,8 @@ public class DeliveryApplicationMsg {
|
|||||||
", preparationCode='" + preparationCode + '\'' +
|
", preparationCode='" + preparationCode + '\'' +
|
||||||
", requester='" + requester + '\'' +
|
", requester='" + requester + '\'' +
|
||||||
", requireTime='" + requireTime + '\'' +
|
", requireTime='" + requireTime + '\'' +
|
||||||
|
", requiredTm='" + requiredTm + '\'' +
|
||||||
|
", isExpedited=" + isExpedited +
|
||||||
", org='" + org + '\'' +
|
", org='" + org + '\'' +
|
||||||
", detailList=" + detailList +
|
", detailList=" + detailList +
|
||||||
'}';
|
'}';
|
||||||
|
|||||||
@@ -1572,8 +1572,14 @@ public class PortServiceImpl implements PortService {
|
|||||||
outStockout.setErpStockoutId(deliveryApplicationMsg.getCode());
|
outStockout.setErpStockoutId(deliveryApplicationMsg.getCode());
|
||||||
// 新加字段 领料人
|
// 新加字段 领料人
|
||||||
outStockout.setRequester(deliveryApplicationMsg.getRequester());
|
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);
|
outStockoutMapper.insertOutStockout(outStockout);
|
||||||
OutStockoutDetail outStockoutDetail = new OutStockoutDetail();
|
OutStockoutDetail outStockoutDetail = new OutStockoutDetail();
|
||||||
outStockoutDetail.setStockoutDetailId(jobId + "-1");
|
outStockoutDetail.setStockoutDetailId(jobId + "-1");
|
||||||
|
|||||||
@@ -29,10 +29,12 @@
|
|||||||
<result property="kdNum" column="kd_num" />
|
<result property="kdNum" column="kd_num" />
|
||||||
<result property="requester" column="requester" />
|
<result property="requester" column="requester" />
|
||||||
<result property="requireTime" column="require_time" />
|
<result property="requireTime" column="require_time" />
|
||||||
|
<result property="isExpedited" column="is_expedited" />
|
||||||
|
<result property="deliveryPoint" column="delivery_point"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectOutStockoutVo">
|
<sql id="selectOutStockoutVo">
|
||||||
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
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectOutStockoutList" parameterType="OutStockout" resultMap="OutStockoutResult">
|
<select id="selectOutStockoutList" parameterType="OutStockout" resultMap="OutStockoutResult">
|
||||||
@@ -93,6 +95,8 @@
|
|||||||
<if test="taskId != null">task_id,</if>
|
<if test="taskId != null">task_id,</if>
|
||||||
<if test="requester != null">requester,</if>
|
<if test="requester != null">requester,</if>
|
||||||
<if test="requireTime != null">require_time,</if>
|
<if test="requireTime != null">require_time,</if>
|
||||||
|
<if test="isExpedited != null">is_expedited,</if>
|
||||||
|
<if test="deliveryPoint != null">delivery_point,</if>
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
|
||||||
@@ -121,6 +125,8 @@
|
|||||||
<if test="taskId != null">#{taskId},</if>
|
<if test="taskId != null">#{taskId},</if>
|
||||||
<if test="requester != null">#{requester},</if>
|
<if test="requester != null">#{requester},</if>
|
||||||
<if test="requireTime != null">#{requireTime},</if>
|
<if test="requireTime != null">#{requireTime},</if>
|
||||||
|
<if test="isExpedited != null">#{isExpedited},</if>
|
||||||
|
<if test="deliveryPoint != null">#{deliveryPoint},</if>
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
@@ -142,6 +148,11 @@
|
|||||||
|
|
||||||
<if test="FID != null">FID = #{FID},</if>
|
<if test="FID != null">FID = #{FID},</if>
|
||||||
<if test="erpStockoutId != null">erp_stockout_id = #{erpStockoutId},</if>
|
<if test="erpStockoutId != null">erp_stockout_id = #{erpStockoutId},</if>
|
||||||
|
<if test="isExpedited != null">is_expedited = #{isExpedited},</if>
|
||||||
|
<if test="deliveryPoint != null">delivery_point = #{deliveryPoint},</if>
|
||||||
|
<if test="timeShipPlan != null">time_ship_plan = #{timeShipPlan},</if>
|
||||||
|
<if test="requester != null">requester = #{requester},</if>
|
||||||
|
<if test="requireTime != null">require_time = #{requireTime},</if>
|
||||||
</trim>
|
</trim>
|
||||||
where stockout_guid = #{stockoutGuid}
|
where stockout_guid = #{stockoutGuid}
|
||||||
</update>
|
</update>
|
||||||
@@ -179,4 +190,4 @@
|
|||||||
where stockout_id = #{fillNo}
|
where stockout_id = #{fillNo}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@@ -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<OutStockout> 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
49
sql/20260908_order_management_fields.sql
Normal file
49
sql/20260908_order_management_fields.sql
Normal file
@@ -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;
|
||||||
Reference in New Issue
Block a user