Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. # MTMS (FPSMS) ↔ M18 資料對照手冊
  2. 本文件說明 **MTMS / FPSMS** 與 **M18** 之間的主檔與交易對應、同步方向,以及已知陷阱。
  3. | 區塊 | 維護方式 |
  4. |------|----------|
  5. | 本手冊(說明、流程、陷阱) | **人手**維護 |
  6. | [`docs/generated/`](./generated/) 對照表 | **腳本產生**(見下方) |
  7. 重新產生自動表(改完 enum / mapping 後請跑):
  8. ```bash
  9. python scripts/generate_m18_mapping_docs.py
  10. ```
  11. 匯出 **Word / Excel**(給非技術閱讀;需已安裝 `python-docx`、`openpyxl`):
  12. ```bash
  13. pip install python-docx openpyxl
  14. python scripts/export_m18_mapping_office.py
  15. ```
  16. 產出:
  17. - `docs/exports/MTMS_M18_DATA_MAPPING.docx`
  18. - `docs/exports/MTMS_M18_DATA_MAPPING.xlsx`
  19. ---
  20. ## 1. 系統與名詞
  21. | 名稱 | 說明 |
  22. |------|------|
  23. | **MTMS / FPSMS** | 本後端 `FPSMS-backend` + 前端 `FPSMS-frontend` |
  24. | **M18** | 外部 ERP/主檔與採購/送貨來源系統 |
  25. | **Pull** | M18 → MTMS(product / vendor / unit / currency / BOM / business unit / PO / DO) |
  26. | **Push** | MTMS → M18(例如 GRN、BOM for shop) |
  27. 設定入口:`m18/M18Config.kt`(`m18.config.*`)、scheduler 見 `application.yml` / `application-prod.yml`(`scheduler.m18Sync`、`scheduler.m18Grn`)。
  28. 主程式目錄:`src/main/java/com/ffii/fpsms/m18/`。
  29. ---
  30. ## 2. Master API 類型(`StSearchType`)
  31. 完整表見自動產生檔:
  32. → **[generated/m18-stsearch-types.md](./generated/m18-stsearch-types.md)**
  33. 摘要:
  34. | M18 `stSearch` | MTMS 落點 |
  35. |----------------|-----------|
  36. | `pro` | `items` |
  37. | `ven` | `shop`(`type=supplier`) |
  38. | `virDept` | `shop`(`type=shop`) |
  39. | `unit` | `uom_conversion`(+ cunit) |
  40. | `cur` | `currency` |
  41. | `udfbomforshop` | `bom` / materials |
  42. 實作:`M18MasterDataService`。
  43. ---
  44. ## 3. 貨品類型(最常查)
  45. ### 3.1 同步規則(自動表)
  46. → **[generated/m18-item-type-mapping.md](./generated/m18-item-type-mapping.md)**
  47. 程式:`M18MasterDataService.saveProduct` / `saveProducts` 依 `pro.udfProducttype`:
  48. ```text
  49. Consumable Material → consumables
  50. Non-consumable Material → non-consumables
  51. Product → fg
  52. WIP → sfg
  53. Item → item
  54. (其他,含 CMB) → mat ← default
  55. ```
  56. Enum 定義:`modules/master/web/models/NewItemRequest.kt`(`ItemType`、`M18ItemType`)。
  57. ### 3.2 UI 顯示(存貨)
  58. 存貨 Type 欄:`t(itemType)`,翻譯在 `FPSMS-frontend/src/i18n/zh/inventory.json`。
  59. | `items.type` | 存貨頁(zh) |
  60. |--------------|--------------|
  61. | `mat` | 原料 |
  62. | `fg` | 成品 |
  63. | `sfg` / `wip` | 半成品 |
  64. | `consumables` / `cmb` | 消耗品 |
  65. | `non-consumables` / `nm` | 非消耗品/雜項 |
  66. > 系統 **沒有**「產品」這個 `items.type`。M18 的 **Product** 對應 MTMS **`fg`(成品)**。
  67. ### 3.3 可手動改嗎?
  68. 可以:Settings → Items → Edit → Type(`ProductDetails.tsx`:`fg` / `wip` / `mat` / `cmb` / `nm`)。
  69. 注意:之後若再跑 **product sync**,type 會依 M18 `udfProducttype` **覆寫**(含再次落到 `mat`)。
  70. ### 3.4 已知陷阱:`CMB`
  71. M18 實務上可出現 `"udfProducttype": "CMB"`(例如蔗糖水 `MG1852`)。
  72. - `"CMB"` ≠ `"Consumable Material"`
  73. - 也不等於前端的 `cmb`
  74. - → sync 走 **else → `mat`** → 存貨顯示 **原料**
  75. 若要顯示消耗品:需改 mapping(例如把 `CMB` 對到 `consumables`),或在 M18 改成已支援的字串;僅手動改 MTMS 可能被下次 sync 蓋掉。
  76. ---
  77. ## 4. 供應商與店鋪
  78. | 方向 | M18 | MTMS |
  79. |------|-----|------|
  80. | Pull vendors | `ven` | `shop`,`ShopType.SUPPLIER`(`supplier`) |
  81. | Pull business units | `virDept` | `shop`,`ShopType.SHOP`(`shop`) |
  82. 鍵:`shop.m18Id`、`shop.code`。名稱優先 `descZhTW` → `descZhCN` → `desc`。
  83. `ShopType`:`modules/master/enums/ShopType.kt`。
  84. ---
  85. ## 5. 單位(UoM)
  86. | M18 | MTMS |
  87. |-----|------|
  88. | Unit master (`unit`) | `uom_conversion`(`code`、`udfudesc`、`udfShortDesc`、`m18Id`…) |
  89. | Cunit 明細 | `M18CunitService.replaceForUnit` |
  90. Item 級採購/庫存/銷售單位在 sync product price 時寫入 `item_uom`(見 `M18MasterDataService` product 區塊)。
  91. PO/DO 行常同時保留:
  92. | 欄位 | 意義 |
  93. |------|------|
  94. | `qty` / `uomId` | MTMS 業務單位(例如採購單位換算後) |
  95. | `qtyM18` / `uomIdM18` | M18 原始單位數量 |
  96. PO 換算邏輯見 `M18PurchaseOrderService`(`convertQtyToPurchaseQty`)。
  97. ---
  98. ## 6. 貨幣、BOM
  99. | M18 | MTMS | Service |
  100. |-----|------|---------|
  101. | Currency | `currency` | `saveCurrencies` |
  102. | BOM (`udfbomforshop`) | `bom` / `bom_material` | `saveBoms` |
  103. Shop BOM **回寫** M18:`M18BomForShopService`(push)。
  104. ---
  105. ## 7. 交易文件(摘要)
  106. | 文件 | 方向 | MTMS 主表 | 筆記 |
  107. |------|------|-----------|------|
  108. | PO | M18 → MTMS | `purchase_order` / `purchase_order_line` | `m18Id` / data log;qty 可能換算 |
  109. | DO | M18 → MTMS | `delivery_order` / `delivery_order_line` | 含 `qtyM18`、`uomIdM18` |
  110. | GRN | MTMS → M18 | stock-in → M18 GRN API | 部分 `m18CreatedUId` **不送** GRN(見下) |
  111. ### GRN 略過規則
  112. `m18/M18GrnRules.kt`:
  113. | M18 PO `createUid` | 備註 | 行為 |
  114. |--------------------|------|------|
  115. | `2569` | legato | 不 post GRN |
  116. | `2676` | xtech | 不 post GRN |
  117. ---
  118. ## 8. Config 鍵(對照時常用)
  119. 見 `M18Config` / `application-*.yml`:
  120. - `m18.config.seriesId.pp|pf|sc|se|sf|sr`
  121. - `m18.config.beId.pp|pf|toa`
  122. - `m18.config.supplier-not.material-po`
  123. - `m18.config.supplier.shop-po` / `oem-po`
  124. - `scheduler.m18Sync.enabled`
  125. - `scheduler.m18Grn.createEnabled`
  126. ---
  127. ## 9. 驗證用 SQL 範例
  128. ```sql
  129. -- 某貨品目前 type(決定存貨顯示)
  130. SELECT code, name, type, m18Id, m18LastModifyDate
  131. FROM items
  132. WHERE deleted = 0 AND code = 'MG1852';
  133. -- 統計 type 分佈
  134. SELECT type, COUNT(*) AS cnt
  135. FROM items
  136. WHERE deleted = 0
  137. GROUP BY type
  138. ORDER BY cnt DESC;
  139. ```
  140. 若 M18 回傳 `udfProducttype` 可與上表比對;對不上表中「exact string」者皆會變 `mat`。
  141. ---
  142. ## 10. 維護約定
  143. 1. **改 mapping**:先改 Kotlin enum / `when`,再跑 `python scripts/generate_m18_mapping_docs.py`,把 `docs/generated/*` 一併 commit。
  144. 2. **改說明/陷阱**:只改本檔,勿手改 `docs/generated/`。
  145. 3. **給營運/開會用**:跑 `python scripts/export_m18_mapping_office.py`,打開 `docs/exports/*.docx` / `*.xlsx`。
  146. 4. **新發現的 M18 值**(如新的 `udfProducttype`):記入 generated 腳本的 `KNOWN_UNMAPPED_M18_VALUES`,或補正式 mapping 後重生。
  147. 5. PR 若動到 `NewItemRequest.kt` / `M18MasterDataService` product type 分支,review 應檢查 generated docs 是否已更新。
  148. ---
  149. ## 11. 相關程式索引
  150. | 主題 | 路徑 |
  151. |------|------|
  152. | Item / M18 type enums | `modules/master/web/models/NewItemRequest.kt` |
  153. | Product sync | `m18/service/M18MasterDataService.kt` |
  154. | StSearch | `m18/model/M18MasterDataRequest.kt` |
  155. | Shop type | `modules/master/enums/ShopType.kt` |
  156. | GRN skip | `m18/M18GrnRules.kt` |
  157. | PO sync | `m18/service/M18PurchaseOrderService.kt` |
  158. | DO sync | `m18/service/M18DeliveryOrderService.kt` |
  159. | BOM→M18 | `m18/service/M18BomForShopService.kt` |
  160. | 存貨 Type 顯示 | `InventoryTable.tsx` + `i18n/zh/inventory.json` |
  161. | 物品 Type 下拉 | `CreateItem/ProductDetails.tsx` |