Phase 3 — 加值中心上傳(TXT+sFTP)與進階控管
最後更新:2026-10-14(零稅率開立:通關方式、零稅率原因、上傳 TXT)
加值中心:汎宇(sFTP+MIG 4.1 中介 TXT+ACK XML)
對象:產品/顧問/開發
索引:AR 進度 · 藍圖 §5 Phase 3
1. 目標
- 上傳(文件 1):依 MIG 4.1 中介文字檔說明 將銷項主檔+明細組成 TXT,經 sFTP 上傳至汎宇。
- 結果(文件 2):依 汎宇 ACK 回覆檔案說明 自 sFTP 下載 ACK XML,解析後更新 上傳狀態/錯誤訊息,完成作廢閘道所需之 上傳成功。
- 進階控管(後續):發票本鎖定/盤點、權限、欄位精簡(§10)。
- 零稅率開立:課稅別為零稅率時,通關方式註記與零稅率原因必填,寫入主檔並帶入上傳 TXT(已實作)。零稅率銷售額合計已有。零稅率清單 PDF 仍屬加購 Phase 5。
不在 Phase 3:加購 Phase 4–7(含零稅率清單 PDF)、營業稅 TXT/T02(vat-filing-status)、進項上傳。
2. 現況基線(Phase 1/7)
| 項目 | 現況 |
|---|---|
| 主檔上傳狀態 | 待上傳/上傳中/上傳失敗/上傳成功/不上傳(PCE_LIB_AR_UploadStatus.js) |
| 開立 | vacUpload=T → 待上傳;否則 不上傳 |
| 作廢 | 非不上傳者 → 待上傳(作廢訊息待送);作廢前須 上傳成功 或 不上傳 |
| 缺口 | 無 TXT 組檔、sFTP、ACK 抓取 |
欄位對照:PCE 銷項欄位對照 — MIG 4.1 中介文字檔(匯出層 @|@|、INVTEXT_… 不進 CR)。
3. 整合方式(已定案)
| 決策 | 內容 |
|---|---|
| 文件 1 | 電子發票B2BB2C中介文字檔MIG4.1說明.pdf → 組 TXT、上傳 |
| 文件 2 | 汎宇ACK回覆檔案說明.pdf → 抓 ACK、更新結果 |
| 傳輸 | sFTP |
| 上傳拆分 | 兩支 MR:開立上傳、作廢上傳(佇列 action=issue/void) |
| 結果抓取 | 第三支 MR(或排程 SS):ACK 輪詢/下載(與開立/作廢上傳分離) |
| 連線設定 | 僅 模組通用系統設定(TEST/PRODUCTION 各一筆,Account ID mapping) |
4. 架構概覽
flowchart TB
subgraph upIssue [開立上傳 MR]
Q1[queue action=issue]
T1[PCE_LIB_AR_VacTxtPayload]
SF1[sFTP 上傳目錄]
Q1 --> T1 --> SF1
end
subgraph upVoid [作廢上傳 MR]
Q2[queue action=void]
T2[PCE_LIB_AR_VacTxtPayload]
SF2[sFTP 上傳目錄]
Q2 --> T2 --> SF2
end
subgraph ack [ACK 抓取 MR]
SF3[sFTP ACK 目錄]
P[PCE_LIB_AR_VacAckParser]
SF3 --> P
end
MS[modsys sFTP 設定] --> SF1
MS --> SF2
MS --> SF3
SF1 --> WAIT[主檔 上傳中 + log 出站檔名]
SF2 --> WAIT
P --> ST[上傳成功 / 上傳失敗 + error_msg]流程圖原文
觸發
- 開立/背景開立/作廢成功 → 寫入 upload_queue(不阻塞原 transaction)。
- 排程:Issue MR、Void MR、Ack MR 各自獨立部署。
- Suitelet 監控:查詢 queue/log、手動重試 enqueue(Phase 3A 末或 3B)。
5. 建議 SDF/程式元件
5.1 模組通用系統設定(sFTP)
| 規劃 scriptid | 用途 |
|---|---|
custrecord_pce_modsys_vac_sftp_host | 主機(正式 sftp.einvoice.com.tw、測試 sftp-t.einvoice.com.tw) |
custrecord_pce_modsys_vac_sftp_user | 使用者名稱(種子 53530703) |
custrecord_pce_modsys_vac_sftp_hostkey | HostKey 指紋(安裝後空白,取得後再填) |
custrecord_pce_modsys_vac_sftp_port | Port(預設 22) |
custrecord_pce_modsys_vac_sftp_path_up | 上傳遠端目錄(INVTEXT 出站) |
custrecord_pce_modsys_vac_sftp_path_ack | ACK 下載目錄 |
custrecord_pce_modsys_vac_sftp_path_done | 已處理 ACK 搬移目錄(選填) |
custrecord_pce_modsys_vac_sftp_enabled | 啟用自動上傳/抓 ACK |
modsys 不含密碼:PCE_LIB_ModuleSettings.getVacSftpSettingsByAccountId() 只回 host/user/hostKey/path 等;passwordGuid 不進 CR。
5.1.1 sFTP 密碼:passwordGuid(每支 MR 各一組)
NetSuite N/sftp 的 passwordGuid 須來自 Credential Field(或同等機制),且該欄位的 restrictToScriptIds 必須包含「正在呼叫 sftp.createConnection 的那支 script id」(並 restrictToDomains 含汎宇 host)。因此:
| 規則 | 說明 |
|---|---|
| 一 script 一 GUID | 開立上傳 MR、作廢上傳 MR、Ack MR 為 **三支不同 customscript_* → 帳上需 三組 Credential/三個 passwordGuid**,不可共用同一 GUID 跨 script 呼叫。 |
| 汎宇端仍可同一密碼 | 若汎宇只提供一組 sFTP 帳密,可在 NetSuite 建立三次 Credential(三個 GUID),內容皆指向同一密碼,但各自 restrict 到對應 MR script id。 |
| LIB 不持有 GUID | PCE_LIB_AR_VacSftpClient.js 的 createConnection({ passwordGuid, … }) 由 MR 透過 PCE_LIB_ModuleSettings.resolveVacSftpPasswordGuid 解析後傳入。 |
modsys 欄位(建議,TEST/PRODUCTION 各填一組)
| modsys 欄位 | MR script id | 用途 |
|---|---|---|
custrecord_pce_modsys_vac_guid_iss | customscript_pce_mr_ar_vac_upl_issue | 開立 INVTEXT 上傳 |
custrecord_pce_modsys_vac_guid_void | customscript_pce_mr_ar_vac_upl_void | 作廢 INVTEXT 上傳 |
custrecord_pce_modsys_vac_guid_ack | customscript_pce_mr_ar_vac_ack | Ack 下載 |
後備:各 MR Script Parameter(modsys 空白時沿用)
| MR script id | custscript_* 參數 id |
|---|---|
| Issue | custscript_pce_vac_sftp_guid_issue |
| Void | custscript_pce_vac_sftp_guid_void |
| Ack | custscript_pce_vac_sftp_guid_ack |
設定方式(帳上):依 SFTP Authentication 建立 Credential 取得 passwordGuid(三支 MR 各一 GUID,restrictToScriptIds 對應上表);優先貼到 modsys 通用設定(依 Account mapping 的 TEST/PRODUCTION 列)。domain 限 sftp-t.einvoice.com.tw/sftp.einvoice.com.tw。HostKey 仍填 modsys custrecord_pce_modsys_vac_sftp_hostkey。
帳內輔助工具(選用):Suitelet customscript_pce_sl_sftp_conn — 建立 GUID、查 Host Key、試連下載;步驟見 sFTP 建置說明。
5.1.2 遠端目錄(測試區實測 2026-10-05)
| modsys 欄位 | 測試區 sftp-t.einvoice.com.tw 建議 | N/sftp 用法 |
|---|---|---|
path_up | /(留空=upload 不帶 directory,等同登入根目錄) | connection.upload({ file, replaceExisting: true }) |
path_ack | ACK 或 ACK/ | download({ directory: 'ACK/', filename }) |
| (慣例,可不另建 CR) | 索引 ACK/list/list.txt | 先下載 list,再依每行檔名下載 XML |
path_done | 選填;實測環境可 下載後刪遠端(舊 GV bundle 作法) | removeFile 或搬移至 done 目錄 |
正式區 sftp.einvoice.com.tw 的 path_up/path_ack 已於 2026-10-07 通過。TEST/PRODUCTION 可沿用與測試區相同的相對路徑(/、ACK/)。
5.1.3 環境/帳上設定
| 項目 | 狀態 |
|---|---|
| HostKey 指紋 | 帳上連線測試已通過(2026-10-07),代表目前使用的 HostKey 可連線。測試 host RSA SHA256 範例:G6St9PmPB1JsKNKeSFF9hkjT/vYtMu1Rj0sfuSPgihg |
path_up/path_ack | 測試區見 §5.1.2;正式區路徑已通過(2026-10-07) |
| 加值中心 sFTP 連線 | 已通過(2026-10-07)。主機、埠、HostKey 與帳密可建立連線 |
| 三支 MR 各一 passwordGuid | 已通過(2026-10-07)。開立/作廢/Ack 三欄 GUID 已可使用 |
| MR 排程 | 已通過(2026-10-07) |
| 開立上傳 → ACK | 已通過(2026-10-07)。作廢上傳 → ACK 不在本次範圍 |
5.2 佇列與紀錄
| 規劃 record | 用途 |
|---|---|
customrecord_pce_ar_upload_queue | ar_invoice、action(issue/void)、status、outbound_txt_name、requestId |
customrecord_pce_ar_upload_log | 出站 sFTP/入站 ACK 摘要、CLOB、關聯 queue。留存檔案指向檔案櫃的上傳 TXT 或下載 ACK |
ACK 處理後另可寫 ack_log 列(或併入 upload_log,direction=inbound)。
去重(已實作):同一 ar_invoice+action 若已有 queue 狀態 pending/processing/outbound,enqueue 回傳既有列 id,不重複建列。Ack 成功/失敗時將對應 processing/outbound 列更新為 done/failed,並寫入 inbound log(含 queue 參照)。
Ack idempotency(已實作):upload_log.custrecord_pce_ar_upllog_ack_file 存遠端 ACK 檔名;Ack MR 已處理者略過。處理後 path_done 有值則上傳至 done 目錄再刪 ACK 目錄檔;否則僅刪除遠端 ACK 檔。
5.3 三支 Map/Reduce
| Script(草案) | 檔案 | 職責 |
|---|---|---|
customscript_pce_mr_ar_vac_upl_issue | PCE_MR_AR_VacUploadIssue.js | 待上傳+已開立+vacUpload → 組 TXT → sFTP 上傳 → 上傳中 |
customscript_pce_mr_ar_vac_upl_void | PCE_MR_AR_VacUploadVoid.js | 待上傳+已作廢+vacUpload → 作廢 TXT → sFTP 上傳 → 上傳中 |
customscript_pce_mr_ar_vac_ack | PCE_MR_AR_VacAckPoll.js | 下載 ACK/list/list.txt → 下載 ACK/ 內 ACK01 等 XML → 解析 → 對應主檔 → 上傳成功/上傳失敗 |
各 MR 部署須含 專用 passwordGuid Script Parameter(§5.1.1)、Audience(allemployees/allroles 等,見 repo 部署規則)。
共用 LIB:
| LIB | 職責 |
|---|---|
PCE_LIB_AR_VacTxtPayload.js | CR → MIG 列(I/ID/A/AD);檔名 INVTEXT_{賣方統編}_{YYMMDDHHMMSS}.txt |
PCE_LIB_AR_VacSftpClient.js | 連線、上傳、下載、搬檔 |
PCE_LIB_AR_VacAckParser.js | UecML / ElcInvData → 結構化結果 |
PCE_LIB_AR_VacUploadQueue.js | enqueue、與 PCE_LIB_AR_UploadStatus 協調 |
6. 子階段與驗收
| 子階段 | 範圍 | 驗收 |
|---|---|---|
| 3A | modsys、queue/log、Issue MR、TXT、sFTP 出站 | 待上傳 → 上傳中+出站 log |
| 3A+ | Ack MR、狀態碼對照 | 上傳中 → 上傳成功/失敗;作廢閘道可過 |
| 3B | Void MR、作廢 TXT | 作廢後待上傳 → ACK 成功 |
| 3C | 發票本鎖定/盤點 | 見 §10 |
| 3D | 權限、smoke | 部署 Audience、測試清單 |
Checklist
最後核對:2026-10-07(三支 GUID、正式區路徑、MR 排程、開立上傳→ACK ✅;作廢上傳 E2E 仍 ⬜)
總覽
| 子階段 | 程式/SDF | 帳上驗收 | 備註 |
|---|---|---|---|
| 3A | ✅ 完成 | ✅ | modsys、queue/log、Issue MR;sFTP 連線、三支 GUID、正式區路徑、開立上傳 已通過 |
| 3A+ | ✅ 完成 | ✅ | Ack MR;開立上傳 → ACK 已通過 |
| 3B | ✅ 完成 | 🔶 | Void MR、錯誤重送、監控已交付;排程已通過;作廢上傳 → ACK 端到端仍 ⬜ |
| 3C | ⬜ 未開始 | — | 發票本鎖定/盤點(§10) |
| 3D | 🔶 部分 | ⬜ | Suitelet/MR Audience XML 已寫;缺 customrole 矩陣與 正式 smoke 簽核表 |
一句結論:3A~3B 程式面可視為交付。帳上 sFTP 連線、三支 GUID、正式區路徑、MR 排程、開立上傳→ACK 已通過。Phase 3 結案仍取決於 作廢上傳→ACK、Ack list 篩選(§8.3)、3C、3D。零稅率開立已完成。
已完成(程式/文件)
基線(Phase 1/7,Phase 3 前置)
| 項目 | 狀態 |
|---|---|
主檔上傳狀態、開立→待上傳/不上傳、作廢上傳閘道(PCE_LIB_AR_UploadStatus) | ✅ |
交易發票狀態/錯誤訊息(custbody_pce_ar_error_msg、上傳失敗文案) | ✅ |
| 開立/背景開立成功後 enqueue Issue 上傳 | ✅ |
3A — 出站
| 項目 | 狀態 |
|---|---|
modsys sFTP 欄位(含 port)、啟用、三支 GUID、custform_pce_modsys 分組 | ✅ |
upload_queue/upload_log、去重 enqueue | ✅ |
VacTxtPayload/VacSftpClient/VacUploadQueue/VacUploadOutbound/VacUploadBatch | ✅ |
Issue MR(customscript_pce_mr_ar_vac_upl_issue) | ✅ |
| §7.4 同賣方統編不可混檔;每一筆主檔一個 INVTEXT | ✅ |
3A+ — ACK
| 項目 | 狀態 |
|---|---|
Ack MR(customscript_pce_mr_ar_vac_ack)、list.txt→XML | ✅ |
VacAckParser/VacAckApply/VacAckIdempotency(含 path_done/刪遠端) | ✅ |
狀態碼:C 成功、E9001–3 與其餘→失敗、S0002 忽略 | ✅ |
3B — 作廢與營運 UI
| 項目 | 狀態 |
|---|---|
| Void MR、作廢後 enqueue void | ✅ |
§9.3 上傳錯誤 Suitelet(UploadErrorsSearch、查詢、重送 enqueue) | ✅ |
§9.3 Bootstrap+PceFilterCollapse(UploadErrorsHtml、Portal embed) | ✅ |
| 上傳監控 Suitelet(queue/上傳中/log,唯讀) | ✅ |
上傳監控 Bootstrap(UploadMonitorHtml) | ✅ |
| 加值中心上傳冒煙 Suitelet、加值中心上傳 — 帳上冒煙(E2E) | ✅ |
Center/Portal/Workbench 入口;本機 test:ar-vac-、test:ar-upload- | ✅ |
帳上已驗
| 項目 | 狀態 |
|---|---|
| 加值中心 sFTP 連線測試(主機、埠、HostKey、帳密) | ✅ 2026-10-07 |
| 三支 MR passwordGuid(開立/作廢/Ack) | ✅ 2026-10-07 |
正式區 path_up/path_ack | ✅ 2026-10-07 |
| Issue/Void/Ack MR 排程 | ✅ 2026-10-07 |
| 開立上傳 → ACK | ✅ 2026-10-07 |
未完成
帳上必做(3A~3B 驗收門檻)
| 項目 | 狀態 | 說明 |
|---|---|---|
| 作廢上傳 → ACK | ⬜ | 開立上傳 → ACK 已通過;作廢管線端到端尚未納入本次驗收 |
void 後交易 submitFields | ⬜ | §9.1 待帳上驗證 |
| 一筆一個 INVTEXT | ✅ | 同統編不再合成一檔;各筆檔名時間逐秒錯開 |
規格 vs 實作落差
| 項目 | 規格 | 現況 |
|---|---|---|
Ack list.txt 篩選 | §8.3 依統編 | 只下載檔名統編屬於啟用中營業人的列,再取前 N 筆;其餘不下載、不搬移、不刪除。未再依日期篩 |
| 監控頁手動 enqueue | 架構圖「監控+重試」 | ✅ 產品分工:監控唯讀;重送走 上傳錯誤清單(§9.3) |
| 上傳中逾時/重送策略 | §8.3 產品另定 | 未實作 |
| MIG 4.1 全欄位 | PDF 完整對照 | sample/單元測試有;汎宇帳上逐欄待驗 |
| 零稅率開立 | 課稅別為零稅率時,通關方式、零稅率原因必填並進 TXT | 一般開立確認頁收集;背景自動開立不收集。寫入主檔並進 TXT(I27、I56)。清單 PDF 仍屬 Phase 5 |
3C/3D
| 項目 | 狀態 |
|---|---|
| 發票本鎖定、盤點/未使用區間匯出(§10) | ⬜ |
| 專用角色、Phase 3 smoke 簽核清單 | ⬜ |
建議優先順序
- 作廢上傳 → ACK:作廢後 Void MR → ACK;失敗走錯誤清單重送。
- 留證:冒煙
?action=json存結果檔(含 uploadLogUrl/queueUrl/arInvoiceUrl)。 - Ack list 變大時:實作 §8.3 統編/日期篩選。
- 作廢 void 後狀態:實際 void 一筆確認交易欄位回寫。
- 3D:角色矩陣 + 固定 smoke 步驟。
- 3C:與申報前控管一併排程(非上傳管線阻塞)。
7. MIG 4.1 中介 TXT(文件 1 — 上傳)
權威來源:電子發票B2BB2C中介文字檔MIG4.1說明.pdf(repo 內與汎宇提供之 sFTP 參考文件 1 同系)。
7.1 檔案與編碼
| 項目 | 規格(摘要) | ||
|---|---|---|---|
| 檔名前綴 | INVTEXT_ + 賣方統編 + _ + 組檔當下台灣時間 YYMMDDHHMMSS | ||
| 實作檔名 | INVTEXT_23997652_261019214605.txt。每一筆主檔一個檔。同一秒多筆時,檔名時間逐筆加 1 秒,避免覆蓋。MIG 訊息與憑證號碼在檔案內容,不進檔名 | ||
| 列分隔 | 欄位 **`@ | @ | `** |
| 列尾 | CRLF(0d0a) | ||
| 編碼 | UTF-8(折讓範例可能含 BOM;實作時須與 PDF 一致) | ||
| 資料列 | I/ID(發票表頭/表身);A/AD(折讓表頭/表身) |
本 repo 範例:docs/samples/vac-sftp/。
7.2 與 PCE 資料
- 來源:
customrecord_pce_ar_invoice+customrecord_pce_ar_invoice_line。 - 對照:PCE 銷項欄位對照 — MIG 4.1 中介文字檔;
custrecord_pce_ar_mig_msg(如開立 F0401、折讓 G0401 等)與doc_kind/作廢欄位。 - Issue MR:
doc_kind=invoice、已開立、35-07+vacUpload等(背景開立已固定)。 - Void MR:已作廢、MIG 作廢/註銷訊息列(
void_date/void_time/void_reason)。作廢訊息在檔案內容;檔名與開立相同,用統編與組檔時間。
7.3 出站後狀態
- sFTP 上傳成功:主檔 → 上傳中;queue 記 outbound_txt_name;不直接標上傳成功(成功以 ACK 為準)。
- sFTP 失敗:→ 上傳失敗、
upload_error_msg寫傳輸錯誤。
7.4 出站分檔(賣方統編)
同一個 INVTEXT 檔案內只能含同一賣方統編(MIG/汎宇限制)。實作時:
- 組檔前依 賣方統編(PCE 營業人/主檔
custrecord_pce_ar_seller_tax_id或對應 MIG 賣方欄)分組,只為了確認檔內統編,以及同一統編共用一次 sFTP 連線。 - 每一筆銷項主檔一個
.txt。不可把多張發票或折讓合成一個檔,也不可把 A 公司與 B 公司列混在同一檔。 - Issue/Void MR 對每一筆呼叫
buildIssueOutboundText/buildVoidOutboundText後各自上傳。queue 的outbound_txt_name記該筆檔名。 - 檔名仍是
INVTEXT_{統編}_{YYMMDDHHMMSS}.txt(台灣時間)。同一秒有多筆時,時間逐筆加 1 秒。
8. 汎宇 ACK XML(文件 2 — 結果)
權威來源:汎宇ACK回覆檔案說明.pdf(已納入 docs/reference/)。
8.1 檔名與位置
| 項目 | 觀察(測試環境) |
|---|---|
| ACK 檔名樣式 | ACK01_{賣方統編}_{時間戳}-{UUID}.xml。list 也可能列出 E0501_ 等財政部下載檔(配號);沒有 StatusCode 時略過,不更新上傳狀態 |
| 索引 | {path_ack}/list/list.txt(每行一檔名,無路徑) |
| XML 存放 | modsys path_ack(測試區 ACK/,與上傳根目錄 / 分開) |
| 處理後 | 僅本帳啟用中營業人統編的檔可搬至 path_done 或刪除;其他統編維持遠端原狀 |
範例:docs/samples/vac-sftp/ack/。
8.2 XML 結構(摘要)
根元素 UecML 可含多筆 ElcInvData。Ack MR 會逐筆回寫,不會只留第一筆。每一筆欄位:
| 元素 | 說明 |
|---|---|
FileName | 平台端對應檔名(例 F0401_{統編}_{MessageNo}_{序號}.xml) |
StatusCode | 結果碼(例 S0002=汎宇解析成功;C 等見 PDF 完整表) |
StatusDesc | 說明文字 |
MessageType | MIG 訊息類型(例 F0401) |
MessageNo | 發票號碼(或折讓單號;與主檔 custrecord_pce_ar_invoice_no/allowance_no 對應) |
MessageDate | 訊息日期 YYYYMMDD |
ServerDt | 平台時間 |
8.3 Ack MR 邏輯
- 讀取本帳啟用中營業人統編(
customrecord_pce_business_info)。一筆都沒有時不連線。 - sFTP 下載
ACK/list/list.txt(directory=ACK/list/)。檔名第二段統編須屬於這些營業人,才列入待處理;其他統編、或檔名沒有 8 碼統編的列不下載、不搬移、不刪除。符合的列再取前 N 筆,並略過 idempotency 已處理檔。 - 下載
ACK/{檔名}(含 **ACK01_*.xml** 等);處理完可刪除或搬移遠端檔。 PCE_LIB_AR_VacAckParser解析。同一個 XML 裡的每個ElcInvData各成一筆。- 每一筆以
MessageNo(+必要時MessageType/日期)對應 upload_queue/銷項主檔(狀態 上傳中)。 - 依 StatusCode(§8.4 產品定案)更新該筆主檔;錯誤文字一律用
StatusDesc。 - 每一筆寫 upload_log(遠端檔名相同,之後輪詢會略過整份),並把整份 ACK 存進檔案櫃 PCE 加值中心交換檔,掛在留存檔案。同一檔每一筆都套用後才搬移遠端檔。上傳 TXT 也在上傳成功後以同樣方式留存。
PCE_LIB_AR_VacAckParser 對主檔狀態(摘要)
StatusCode === 'C' → 上傳成功(大平台已上傳成功),清空 upload_error_msg StatusCode in E9001,E9002,E9003 → 上傳失敗,upload_error_msg = StatusDesc StatusCode === 'S0002' → 不更新主檔上傳狀態(忽略) 其他 StatusCode → 上傳失敗(大平台回傳錯誤),upload_error_msg = StatusDesc
未收到 ACK:維持 上傳中;監控 Suitelet 可顯示逾時;可設定重送策略(產品另定)。
8.4 StatusCode 對照表(產品定案 2026-10-04)
| StatusCode | 意義 | 主檔 upload_status | upload_error_msg |
|---|---|---|---|
C | 大平台上傳成功 | → 上傳成功 | 清空 |
E9001、E9002、E9003 | 上傳失敗(汎宇定義之失敗碼) | → 上傳失敗 | StatusDesc |
S0002 | 中繼狀態(例如「大平台傳送中」) | 不變(忽略,不當成功) | 不強制更新 |
| 其餘 | 大平台回傳之錯誤 | → 上傳失敗 | StatusDesc |
補充:ACK PDF 仍可對照完整碼表;實作與驗收以本表為準。
作廢閘道:僅在 ACK 判為 C → 上傳成功 後,才與現行 uploadStatusAllowsVoid 一致(與 不上傳 並列可作廢)。
9. 狀態機(端到端)
主檔 上傳狀態 代表「目前這張單最新一則訊息」的進度:銷項狀態 已開立 → 開立訊息;已作廢 → 作廢訊息。主檔清單不新增值。
9.1 主檔與交易對照
主檔變更時,所有來源交易(合併開立時為多張 Invoice)同步回寫 custbody_pce_ar_inv_status。
| 事件 | 主檔銷項狀態 | 主檔上傳狀態 | 交易 custbody_pce_ar_inv_status |
|---|---|---|---|
開立、vacUpload=T | 已開立 | 待上傳 | 已開立等待上傳 |
| 開立、不上傳 | 已開立 | 不上傳 | 已開立,不透過NS上傳 |
| 開立上傳 MR 送出 | 已開立 | 上傳中 | 已開立上傳中 |
| sFTP 失敗或 ACK 失敗碼 | 已開立 | 上傳失敗 | 已開立但上傳失敗,請確認錯誤訊息 |
ACK C | 已開立 | 上傳成功 | 已開立且已成功上傳大平台 |
| 作廢(原為上傳成功) | 已作廢 | 待上傳 | 已作廢等待上傳 |
| 作廢(原為不上傳) | 已作廢 | 不上傳 | 已作廢,不透過NS上傳 |
| 作廢上傳 MR 送出 | 已作廢 | 上傳中 | 已作廢上傳中 |
| sFTP 失敗或 ACK 失敗碼 | 已作廢 | 上傳失敗 | 已作廢但上傳失敗,請確認錯誤訊息 |
ACK C | 已作廢 | 上傳成功 | 已作廢且已成功上傳大平台 |
ACK S0002 | 不變 | 不變(上傳中) | 不變 |
作廢換開 當下清空來源單據的號碼、狀態、錯誤訊息與鎖定,不套用上表的作廢列,也不 void 交易。舊發票的作廢上傳進度只看主檔。作廢與作廢換開在主檔改為待上傳時都會排入作廢上傳佇列。作廢換開的上傳中、ACK 與重送都只更新主檔。
待帳上驗證:「作廢」模式以 transaction.void 作廢 NetSuite 交易後,Phase 3 是否仍能對已作廢交易 submitFields 回寫狀態。
9.1.1 交易錯誤訊息(custbody_pce_ar_error_msg)
交易表身單一欄位 發票錯誤訊息(Long Text、唯讀、銷項 PCE 分頁),合併兩種失敗來源,使用者在 Invoice/Credit Memo/Customer Deposit 上即可看到原因,不必再開主檔。
| 來源 | 寫入時機 | 內容 | 交易狀態同時為 | 清空時機 |
|---|---|---|---|---|
| 背景自動開立(已交付) | 背景 MR 開立失敗 | 背景自動開立失敗:{原因} | 空白(已解鎖,可修正後重開) | 再次排入背景開立、開立成功、Make Copy、作廢換開 |
| 加值中心上傳(Phase 3) | sFTP 失敗或 ACK 失敗碼 | 與主檔 upload_error_msg 相同(StatusDesc 或傳輸錯誤) | 已開立/已作廢但上傳失敗,請確認錯誤訊息 | 上傳錯誤清單改回待上傳、ACK C |
合併開立時,主檔的上傳錯誤同步寫入所有來源交易。
9.2 作廢閘道
維持現行 uploadStatusAllowsVoid:僅 上傳成功 或 不上傳 可作廢。開立上傳失敗的發票不可作廢,只能修正後重送(產品定案 2026-10-04)。
9.3 上傳錯誤清單與重送(Suitelet)
開立上傳與作廢上傳失敗的唯一出路是重送,不另開作廢路徑。
| 項目 | 規格 |
|---|---|
| 頁面 | Suitelet「上傳錯誤」(Portal → 加值中心;customscript_pce_sl_ar_upload_err)。監控為同組的上傳監控 |
| 清單條件 | 主檔上傳狀態 = 上傳失敗(含已開立、已作廢) |
| 查詢條件 | 營業人統編、發票/折讓期別、憑證種類、訊息類別(開立/作廢) |
| 顯示欄位 | 發票/折讓單號、憑證種類、訊息類別、日期、客戶、錯誤訊息(upload_error_msg)、最後一次上傳時間、主檔連結、來源交易連結 |
| 動作 | 勾選後 改回待上傳(可多筆);寫入 upload_log(操作者、時間、原錯誤訊息) |
| 改回後 | 主檔上傳狀態 → 待上傳、清空 upload_error_msg;交易回到 已開立等待上傳 或 已作廢等待上傳,並清空交易 發票錯誤訊息;下一輪上傳 MR 重新組檔 |
| 權限 | 依部署 Audience;之後 3D 收斂角色 |
修正資料(例如客戶統編、品名)在主檔或來源交易上進行;清單頁只負責顯示錯誤與重送,不提供欄位編輯。
實作(2026-10-05):PCE_LIB_AR_UploadErrorsSearch+PCE_LIB_AR_UploadErrorsRequest+PCE_LIB_AR_UploadErrorsHtml(Bootstrap、PceFilterCollapse、Portal embed);期別篩選依憑證日期換算財政部雙月區間;最後上傳時間取該主檔最新一筆 upload_log;進頁預設列出失敗主檔(可再按查詢套用篩選);npm run test:ar-upload-errors-search。
10. 發票本進階控管(Phase 3C — 概要)
藍圖原項:多本、鎖定、盤點。實作時擴充 PCE_LIB_AR_BookAllocate 拒絕鎖定本取號;Suitelet 匯出未使用區間。細節另開 PR。
11. 測試與範例
| 資源 | 路徑 |
|---|---|
| 出站 TXT 範例 | docs/samples/vac-sftp/inbound-txt/ |
| ACK 範例 | docs/samples/vac-sftp/ack/ |
| 欄位 | PCE 銷項欄位對照 — MIG 4.1 中介文字檔 |
npm run test:ar-vac-txt # 草案:Payload 對照 sample npm run test:ar-vac-ack-parser # 草案:解析 sample XML npm run validate:sdf-ids
帳上測試:須連 upload_log/queue id(比照 AP write log 規則)。直接開 加值中心上傳冒煙 Suitelet(不在 Portal 側欄;加值中心上傳 — 帳上冒煙(E2E))。
12. 相關文件
| 文件 | 用途 |
|---|---|
| MIG 4.1 PDF | TXT 組檔(文件 1) |
| ACK PDF | 結果解析(文件 2) |
| PCE 銷項欄位對照 — MIG 4.1 中介文字檔 | CR ↔ MIG |
| 銷項背景自動開立發票(Phase 7) | 背景開立待上傳量 |
| 換加值中心 — 修改範圍 | 換另一家加值中心時要改的分層 |
13. 變更紀錄
| 日期 | 摘要 |
|---|---|
| 2026-10-07 | 三支 GUID、正式區路徑、MR 排程、開立上傳→ACK 先標通過;作廢上傳→ACK 仍待驗 |
| 2026-10-07 | 加值中心 sFTP 連線測試已通過 |
| 2026-10-04 | 初版:TXT+sFTP、開立/作廢兩 MR、modsys |
| 2026-10-04 | 對齊汎宇文件 1/2:MIG TXT、ACK01 XML、第三支 Ack MR;範例入 docs/samples/vac-sftp/ |
| 2026-10-04 | ACK:C=上傳成功;E9001–3 失敗;S0002 忽略;出站依賣方統編分檔 |
| 2026-10-04 | §9:主檔/交易狀態對照(交易清單新增作廢上傳三值);上傳失敗不可作廢,只能經「上傳錯誤清單」重送 |
| 2026-10-04 | §9.1.1:交易 發票錯誤訊息(custbody_pce_ar_error_msg)合併背景開立失敗與上傳失敗;失敗/成功狀態文字改為「已開立但上傳失敗,請確認錯誤訊息」等 |
| 2026-10-05 | §5.1.1:三支 MR 各一 passwordGuid(restrictToScriptIds);§5.1.2 測試區路徑 /、ACK/、ACK/list/list.txt;Ack 流程對齊 list 索引 |
| 2026-10-05 | 新增 §Checklist:3A~3D 完成/未完成、帳上驗收、建議優先順序 |
| 2026-10-05 | §Checklist 核對:3A~3B 程式 ✅;§9.3/監控 Bootstrap;modsys port;帳上 E2E 仍 ⬜ |