工單新增

wo.create
POST JSON 同步 ERP → MES

1. 基本資訊

項目說明
API 中文名稱工單新增(製令資料新增)
API 英文名稱Work Order Create
API Codewo.create
案號0189142
REST EndpointPOST /ESB/API/upModetail
呼叫方向ERP → MES
呼叫時機ERP 開立新工單後,同步至 MES
主要業務情境ERP 產生製令後,將工單資訊推送至 MES,MES 建立對應的製令、批次及製程記錄
Request 格式JSON (Content-Type: application/json)
同步/非同步同步呼叫
交易控管需要(setAutoCommit(false) + transactionCommit())
呼叫方向說明
此 API 為 ERP → MES 單向推送,由 ERP 主動呼叫 MES 介面新增工單資料。

2. 業務流程

ERP 系統 MES 系統 1. 開立工單 (wo.create) 2. 驗證資料 (WoCreate) 3. 新增製令 (MODETAIL) 4. 建立批次 (LOT) 5. 初始化 (製程) initOpRealRun_SftBommf() initProcessTime() → SFT_OP_REALRUN 初始化 程式位置: WoCreate.java → RegularESB.upModetail() → ESBapi.java:975-1007
程式碼對應
  • API 入口: WoCreate.java (SFT_ERPIntegrate)
  • 核心邏輯: RegularESB.upModetail() (SFT_dataImport)
  • SQL 執行: ESBapi.java:975-1007 (KMI_Restful)
  • 製程初始化: dataMantain.initOpRealRun_SftBommf()

3. Request 規格

傳輸格式: JSON
Content-Type: application/json

3.1 外層結構

欄位型別必填說明
CompanyIDstringY公司代號
OperationTypeintY操作類型(1=新增)
contentarrayY工單資料陣列

3.2 content 陣列內容

欄位型別長度必填說明MES 欄位
wo_nostring40Y製令編號(單別-單號)CMOID
item_nostring40Y品號ITEMID
unit_nostring10Y單位代號UNIT
plan_date_sstring19Y預計開工日(yyyy-MM-dd HH:mm:ss)PLANPROCESSST
plan_date_estring19Y預計完工日(yyyy-MM-dd HH:mm:ss)DUEDATETIME
wo_qtydecimal-Y預計產量QTY / PLANRELEASEQTY
so_nostring40N訂單單號DOID
so_seqstring10N訂單項次SEQUENCE
factory_nostring10Y廠別代號FACTORYID
warehouse_nostring10N庫別代號WAREHOUSEID
remarkstring500N備註DESCRIPTION
prioritystring1N優先級(1=急料,0=否)MO032

4. Response 規格

欄位型別說明
codestring200=成功,500=失敗
msgstring處理結果訊息(成功時回傳製令編號)
queryarray查詢結果(通常為空陣列)

成功行為

5. 檢核規則

#檢核項目規則錯誤代碼
1製令編號重複CMOID 不可重複存在於 MODETAILJS_0126_00061
2品號存在ITEMID 必須存在於 ITEM 表JS_0096_00058
3單位存在unit_no 必須存在於 UnitBasisJS_0016_00134
4廠別存在factory_no 必須存在於 FACTORYJS_0016_00115
5庫別存在warehouse_no(若有值)必須存在於 WAREHOUSEJS_0135_00036
6數量檢核wo_qty 必須大於 0-

6. 錯誤代碼

代碼訊息說明
JS_0126_00061製令編號已存在,無法進行新增CMOID 重複
JS_0096_00058此品號不存在ITEM 表無此品號
JS_0016_00134單位不存在,請確認UnitBasis 無此單位
JS_0016_00115廠別代號不存在FACTORY 無此廠別
JS_0135_00036此庫別代號不存在WAREHOUSE 無此庫別
remind_001資料已存在重複新增

7. JSON 範例

Request

{
  "CompanyID": "COMP01",
  "OperationType": 1,
  "content": [{
    "wo_no": "5101-20260319001",
    "item_no": "FG-A001-001",
    "unit_no": "PCS",
    "plan_date_s": "2026-03-19 08:00:00",
    "plan_date_e": "2026-03-20 17:00:00",
    "wo_qty": 1000,
    "so_no": "SO20260301001",
    "so_seq": "001",
    "factory_no": "P001",
    "warehouse_no": "FG01",
    "remark": "急單",
    "priority": "1"
  }]
}

Response (成功)

{
  "code": "200",
  "msg": "[\"5101-20260319001\"]",
  "query": []
}

Response (失敗 - 製令已存在)

{
  "code": "500",
  "msg": "JS_0126_00061",
  "query": []
}

8. 相關資料表

8.1 MODETAIL(製令主檔)

欄位類型說明
CMOIDNVARCHAR(40)PK: 製令編號(單別-單號)
MO004NVARCHAR(10)製令單別
MO005NVARCHAR(20)製令單號
ITEMIDNVARCHAR(40)品號
QTYFLOAT預計產量
PLANRELEASEQTYFLOAT預計發放量
RELEASEDQTYFLOAT已發放量
STATUSINT狀態(1=未生產 2=生產中 99=結案 100=取消)
PLANPROCESSSTDATETIME預計開工日
DUEDATETIMEDATETIME預計完工日
FLAGINT版本號

8.2 LOT(批次記錄)

欄位類型說明
IDNVARCHAR(40)PK: 批次編號(通常=CMOID)
MOIDNVARCHAR(40)FK: 製令編號
TYPEINT批次類型(1=計劃批)
LOTSIZEFLOAT批次數量(待發放量)
STATUSINT狀態(0=待發放 1=已發放)
LOCATIONNVARCHAR(20)位置(通常='release')

9. 資料庫更新 SQL

9.1 檢查製令是否存在

-- 新增前檢查,若存在則拋出 JS_0126_00061
SELECT COUNT(1) FROM MODETAIL WHERE CMOID = N'{wo_no}'

9.2 INSERT MODETAIL(新增製令主檔)

INSERT INTO MODETAIL (
    CMOID, MO004, MO005, ITEMID, MO021, MO022, UNIT,
    PLANPROCESSST, DUEDATETIME, QTY, STATUS, DOID,
    SEQUENCE, FACTORYID, WAREHOUSEID, DESCRIPTION,
    MO008, MO012, MO016, MO032, PLANRELEASEQTY,
    FLAG, LASTMAINTAINUSER, LASTMAINTAINDATETIME
) VALUES (
    :CMOID,              -- 製令編號 (單別-單號)
    :MO004,              -- 製令單別
    :MO005,              -- 製令單號
    :ITEMID,             -- 品號
    :MO021,              -- 品名
    :MO022,              -- 規格
    :UNIT,               -- 單位
    :PLANPROCESSST,      -- 預計開工日
    :DUEDATETIME,        -- 預計完工日
    :QTY,                -- 預計產量
    1,                   -- STATUS = 1 (未生產)
    :DOID,               -- 訂單單號
    :SEQUENCE,           -- 訂單項次
    :FACTORYID,          -- 廠別代號
    :WAREHOUSEID,        -- 庫別代號
    :DESCRIPTION,        -- 備註
    1,                   -- MO008 = 1
    :MO012,              -- 開單日期
    0,                   -- MO016 = 0
    :MO032,              -- 優先級 (1=急料)
    :QTY,                -- 預計發放量 = 預計產量
    1,                   -- FLAG 版本號
    :userid,
    N'{當前時間}'
)

9.3 INSERT LOT(新增批次記錄)

INSERT INTO LOT (
    ID, TYPE, MOID, ITEMID, LOTSIZE, STATUS, UNIT,
    QTYPER, LOCATION, ERP_OPSEQ, ERP_OPID, ERP_WSID,
    LOT004, PKQTY, PKQTYPER, LOT007, LOT011,
    LASTMAINTAINUSER, LASTMAINTAINDATETIME
) VALUES (
    :CMOID,              -- 批次編號 = 製令編號
    1,                   -- TYPE = 1 (計劃批)
    :CMOID,              -- MOID = 製令編號
    :ITEMID,             -- 品號
    :QTY,                -- LOTSIZE = 預計產量
    0,                   -- STATUS = 0 (待發放)
    :UNIT,               -- 單位
    1,                   -- QTYPER = 1
    'release',           -- LOCATION = 'release'
    '', '', '',          -- ERP 製程欄位 (空)
    1, 0, 0,             -- LOT004, PKQTY, PKQTYPER
    '0', 'N',            -- LOT007, LOT011
    :userid,
    N'{當前時間}'
)

9.4 初始化製程 SFT_OP_REALRUN(從 SFT_BOMMF 讀取)

-- 檢查品號是否有標準途程
SELECT ME007 FROM SFT_BOMME, MODETAIL, ITEM
WHERE ITEM.ID = MODETAIL.ITEMID
  AND CMOID = N'{wo_no}'
  AND RTRIM(ME001) = ITEM.STDROUTEITEMID
  AND RTRIM(ME002) = ITEM.STDROUTEID

-- 若有途程,先刪除再新增
DELETE SFT_OP_REALRUN WHERE ID = N'{wo_no}'

-- 從 SFT_BOMMF 複製製程資料
INSERT INTO SFT_OP_REALRUN (
    ID, SEQUENCE, OPID, OPDESCRIPTION,
    ARRIVEQTY, OUTQTY, REWORKQTY, DEFECTQTY,
    ERP_OPSEQ, PERLOTWORKTIME, STANDARDEQWORKTIME, STANDARDMANWORKTIME,
    ERP_OPID, ERP_WSID, ERP_FIXEDLEADTIME, ERP_TRANSQTY, ...
)
SELECT
    CMOID,                          -- ID = 製令編號
    0,                              -- SEQUENCE = 0
    RTRIM(MF004)+'---'+RTRIM(MF006), -- OPID = 製程+工作站
    MF008,                          -- OPDESCRIPTION = 製程說明
    0, 0, 0, 0,                     -- 數量欄位初始化為 0
    RTRIM(MF003),                   -- ERP_OPSEQ = 製程序
    MF019,                          -- PERLOTWORKTIME = 每批工時
    ...
FROM SFT_BOMMF, MODETAIL, ITEM
WHERE ITEM.ID = MODETAIL.ITEMID
  AND CMOID = N'{wo_no}'
  AND RTRIM(MF001) = ITEM.STDROUTEITEMID
  AND RTRIM(MF002) = ITEM.STDROUTEID

9.5 初始化前後道關聯 SFT_OP_BACK_RUN(若有網狀途程)

-- 若 ME007='Y'(有網狀途程),建立前後道關聯
DELETE SFT_OP_BACK_RUN WHERE SOB001 = N'{wo_no}'

INSERT INTO SFT_OP_BACK_RUN (
    SOB001, SOB002, SOB003, SOB004, SOB005, SOB007, SOB008
)
SELECT
    N'{wo_no}',     -- SOB001 = 製令編號
    MFL003,         -- SOB002 = 製程序
    MFL004,         -- SOB003 = 製程代號
    MFL005,         -- SOB004 = 前道製程序
    MFL006,         -- SOB005 = 前道製程代號
    MFL008,         -- SOB007 = 工作站代號
    MFL009          -- SOB008 = 前道工作站代號
FROM SFT_BOMMF_LINE
JOIN SFT_BOMME ON ME001 = MFL001 AND ME002 = MFL002
WHERE MFL001 = :MF001 AND MFL002 = :MF002 AND MES004 = 'Y'

-- 更新 SFT_OP_REALRUN 的前道製程欄位
UPDATE SFT_OP_REALRUN SET
    OR002 = CASE ... END,  -- 前道製程序
    OR003 = CASE ... END,  -- 前道製程代號
    OR004 = CASE ... END   -- 前道工作站代號
WHERE ID = N'{wo_no}' AND SEQUENCE = 0

9.6 更新製令途程標記

-- 標記製令是否有網狀途程
UPDATE MODETAIL SET
    MO040 = CASE WHEN ME007 = 'Y' THEN 'Y' ELSE 'N' END,
    STDROUTEITEMID = :STDROUTEITEMID,  -- 若有標準途程則更新
    STDROUTEID = :STDROUTEID
WHERE CMOID = N'{wo_no}'

9.7 計算製程時間

-- 若製令有預計發放時間,推算各製程預計開工/完工日
dataMantain.initProcessTime(companyID, CMOID)

-- 最後重算所有製程
SFT_OP_REALRUN.sqlUpdate_RecalculateAll("insertMODETAIL")
新增工單影響的資料表清單
資料表操作說明
MODETAILINSERT製令主檔
LOTINSERT批次記錄
SFT_OP_REALRUNDELETE + INSERT製程實績(從 SFT_BOMMF 複製)
SFT_OP_BACK_RUNDELETE + INSERT前後道製程關聯(網狀途程)
程式位置
SQL 執行:ESBapi.java:1007-1046
製程初始化:dataMantain.initOpRealRun_SftBommf()
前後道關聯:UpdateData.InsertOpBackRun()

9.8 更新 material_requisition(工單用料維護單身)

相關聯的 API:upMaterial
ERP 開立工單後,可能會同時呼叫 upMaterial API 來同步工單用料資料至 material_requisition 表。
-- API Endpoint: POST /ESB/API/upMaterial
-- 1. 先寫入 order_material 表(原始用料訂單資料)
SELECT COUNT(1) FROM order_material
WHERE material_requisition = N'{material_requisition}'
  AND material_number = N'{material_number}'
  AND serial_number = N'{serial_number}'
-- count > 0 → UPDATE, count = 0 → INSERT

-- INSERT order_material
INSERT INTO order_material (
    material_requisition, material_number, serial_number,
    material_id, material_quantity, craftsmanship,
    batch_number, category, order_number, type,
    batch_description, om01, om02, om03, om04
) VALUES (
    :material_requisition, :material_number, :serial_number,
    :material_id, :material_quantity, :craftsmanship,
    :batch_number, :category, :order_number, :type,
    :batch_description, N'{當前時間}', :om02, :om03, :om04
)

-- 2. 合併相同 品號+工藝+工作站+物料批號+工單編號 的資料後,寫入 material_requisition
SELECT COUNT(1) FROM material_requisition
WHERE modetail_cmoid = N'{工單編號}'
  AND material_id = N'{物料編號}'
  AND opid = N'{製程代號}'
  AND erp_wsid = N'{工作站代號}'
  AND material_batch = N'{物料批號}'
  AND (remark IS NULL OR remark = '')
-- count > 0 → UPDATE(累加領料量), count = 0 → INSERT

-- INSERT material_requisition(新增用料記錄)
INSERT INTO material_requisition (
    serial, modetail_cmoid, material_id,
    opid, erp_wsid, material_batch,
    withdrawn_quantity, mr01
) VALUES (
    :serial,              -- 流水號 (MAX(serial) + 1)
    :modetail_cmoid,      -- 工單編號 (category-order_number)
    :material_id,         -- 物料編號
    :opid,                -- 製程代號
    :erp_wsid,            -- 工作站代號
    :material_batch,      -- 物料批號
    :withdrawn_quantity,  -- 實際領料量
    N'{當前時間}'          -- mr01
)

-- UPDATE material_requisition(累加領料量)
UPDATE material_requisition SET
    withdrawn_quantity = withdrawn_quantity + :新增領料量
WHERE modetail_cmoid = N'{工單編號}'
  AND material_id = N'{物料編號}'
  AND opid = N'{製程代號}'
  AND erp_wsid = N'{工作站代號}'
  AND material_batch = N'{物料批號}'
  AND (remark IS NULL OR remark = '')

material_requisition 表結構

欄位類型說明
serialINT流水號
modetail_cmoidNVARCHAR(40)工單編號
material_idNVARCHAR(40)物料編號
opidNVARCHAR(20)製程代號
erp_wsidNVARCHAR(20)工作站代號
material_batchNVARCHAR(40)物料批號
demand_quantityFLOAT需求數量
withdrawn_quantityFLOAT實際領料量
remarkNVARCHAR(500)備註
mr01DATETIME建立時間
新增工單影響的資料表清單(完整)
資料表操作說明API
MODETAILINSERT製令主檔wo.create
LOTINSERT批次記錄wo.create
SFT_OP_REALRUNDELETE + INSERT製程實績(從 SFT_BOMMF 複製)wo.create
SFT_OP_BACK_RUNDELETE + INSERT前後道製程關聯(網狀途程)wo.create
order_materialINSERT/UPDATE用料訂單資料upMaterial
material_requisitionINSERT/UPDATE工單用料維護單身upMaterial
程式位置
wo.create SQL 執行:ESBapi.java:1007-1046
製程初始化:dataMantain.initOpRealRun_SftBommf()
前後道關聯:UpdateData.InsertOpBackRun()
用料資料同步:ESBapi.java:1252-1394 (upMaterial)