修改紀錄
每次新增功能、變更、刪除、Breaking Changes 的時間軸。共 464 篇。
📅 2026 年 9 月 (63 篇)
-
09-14 h-ui-tweaks-exce-inout ▸
2026-09-14 庫存單據版面微調、庫存查詢條件、例外出入庫查詢改版
單據畫面
- 加工單:「對帳期間」標籤改為「帳款期別」。
- 損耗單:「倉單號」標籤改為「耗料單號」。
- 出入庫單:交易部門下方新增幣別/匯率;快遞號碼上方新增稅別(含稅別名稱)、發票日期/發票號碼、發票金額/稅額、CINO/報單號碼,版面同加工單。上下一筆時稅別名稱自動帶出。
庫存查詢條件
- 期初期末查詢(INVBK1):「倉庫」改「起訖倉庫」;起始值/截止值改為「起 始 值」「截 止 值」;抬頭列改與標籤同色;品號範圍/群組範圍移到起訖倉庫下方;「集團代號」改「群組代號」且不再被截斷。
- 庫存查詢(INVSTK):
- 條件列改為只顯示目前查詢別對應的那一列。
- 「出貨通知」查詢別恢復可用,改以出通單號查詢;未填單號會提示。
- 「倉庫」改「隸屬倉庫」;單一倉庫欄移除,固定查全部倉庫(原預設 PR)。
- 「依批號分組」改「依批號彙總」;「不含直接進口訂單」勾選移除(仍維持排除)。
- 「銷售訂單號」改「訂單編號」。
例外出入庫查詢
- 倉庫勾選表自查詢條件搬到主畫面,與結果表左右並排,中間分隔條可拖曳;頁籤移除。
- ALL 列預設勾選。勾選決定查詢範圍;查詢後點選左表某一倉庫,右表只顯示該倉庫,不必重查(可用「依選取倉庫篩選顯示」關閉)。
- 勾選框改為檢視模式直接點選,不再出現編輯框造成外觀跑掉。
- 條件面板只留單據別、起訖日期、成本匯率表(高度隨筆數自動延伸)與兩行說明。
-
09-14 h-manual-screenshots-and-fixes ▸
2026-09-14 庫存管理手冊全面更新,並修掉拍圖時撞到的三個問題
使用者看得到的變化
1. 庫存管理手冊 17 頁重寫並接上實機截圖。
原本手冊多數頁面是照舊程式寫的,欄位名還是英文(Prefix、SKU、Quantity Query…),
加工單那一頁寫的甚至是另一支程式;出入庫查詢被標成「尚未實作」但其實早就能用。
這次以現行畫面為準全部修訂,並在示範帳套拍了 38 張截圖接進去。
還有 4 張因程式或資料因素暫時拍不到,頁面上保留「需補截圖」標示。
2. 盤點單「產生盤點卡」的條件視窗改成中文。
以前按盤點單主檔旁的
新增開出的條件視窗整窗都是英文(DocumentDate/Warehouse/Filter…,還有拼錯的字),現在全部是中文,日期欄位叫製單日期,與主檔一致。
3. 不良處理單「真因分析」下拉有選項了。
以前這個下拉永遠是空的,按
產生只會提示「請先選擇真因分析」,等於功能不能用。原因是摘要檔裡「真因分析」這個類別(C274)從來沒有登錄選項。
這次補了三個示範選項(尺寸不良/材質不良/組裝不良,各附檢測項目範本),
客戶可以到「摘要檔維護」自行增修。朝陽帳套連對應的檢視與登錄都一併補上。
另外修正
產生帶入明細時只比對摘要文字、沒限定類別的問題,避免別的類別有同名摘要時抓錯。4. 倉庫表「批次關帳」按查詢不再跳系統錯誤框。
以前開「倉庫結帳」視窗按
查詢會跳「程式:STKBAS_1 / Cannot find table 0.」。原因是結帳前的成本稽核用到的檢視、15 支稽核程序與派發登錄在客戶帳套裡都不存在,
程式又沒有防呆。這次補上物件與登錄,並在程式端加防呆:查不到資料時回空清單,不再炸。
稽核程序本身原本引用舊版英文欄位結構,在中文帳套一定跑不動;同日已全部改寫成使用
帳套的中文檢視與資料表(
sql/h-stkbas-audit-procs-zh-20260914.sql),16 項稽核在三個開發帳套都能執行。其中「費用是否計入成本」(K-020-007)因中文帳套沒有對應欄位,
目前一律視為通過,待確認對應方式後再補。
部署注意
- 兩支新的 SQL 要跑在各帳套:
sql/h-c274-真因分析-20260914.sql(每個帳套)、
sql/h-stkbas-audit-objects-20260914b.sql(每個帳套,先建表/檢視/種子)→sql/h-stkbas-audit-procs-zh-20260914.sql(每個帳套,中文版稽核程序)+sql/h-stkbas-procparam-20260914.sql(各 log 庫)。- 跑完真因分析種子後,使用者要重新登入才會看到下拉選項。
- 兩支新的 SQL 要跑在各帳套:
-
09-14 browse-default-conditions ▸
2026-09-14 清單瀏覽的「預設條件」全面修好,並補給原本沒有的程式
使用者看得到的變化
1. 預設條件下拉不再是空的。
以前開清單瀏覽/明細瀏覽時,「預設條件」下拉有時只有一個
Not Set,條件列也空白,按「查詢」等於整張表撈出來——資料量大的單據(出貨單、出入庫單)會轉很久甚至逾時。
現在系統會替每一支「可以瀏覽」的程式準備一組預設條件,開窗就帶好。
2. 預設的期間是「當月 1 號 ~ 今天」。
有交易日期/單據日期的單據,預設條件是該日期欄「介於 當月 1 號 到 今天」。
要看更早的資料,把日期改掉再按查詢即可,跟以前一樣。
沒有日期欄的主檔類程式(客戶資料表、庫存主檔、會計科目表…),預設條件維持「全部」的語意,
只是改成走得動索引的寫法。
3. 朝陽帳套的預設條件從此會出現。
朝陽的自訂條件資料在前一次系統改版時沒有完整轉過來,導致每一支程式的預設條件都找不到,
而且條件的運算子(等於/介於/包含…)對應到了錯的意思。這次一併修好:
以前存在系統裡的那些自訂查詢條件(例如「訂單明細-未出貨查詢」「進貨暫收單-待驗查詢」)
會重新出現在下拉裡,語意也對回來了。
4. 原本「有條件、但等於沒篩」的預設條件,也補上當月期間。
有些程式的預設條件內容是「單號 不包含 QWERT」「交易部門 開始於 空白」這類寫法——
看起來有條件,實際上等於整張表撈出來,按查詢一樣會轉很久
(實機遇到的:進貨單「全部資料查詢」、出入庫單「交易部門」、應收票據的「收票庫存 CE/託收 CB 查詢」)。
這次替整組都沒有日期條件的預設條件各加一列該單據的日期欄「介於 當月 1 號 到 今天」,
原本的條件一列都不動,只是多一列期間。
已經有日期條件的(包含那些寫死成 2020/01/01~9999/12/20 的)一律不動。
條件列已經滿 5 列的組沒辦法再加(面板只有 5 列),會列在部署腳本的驗證清單裡。
注意事項
- 這批要先更新程式再更新資料。 預設的期間用了一個新的關鍵字
#ThisMonth,
舊版程式看不懂,會把它當成一般文字去查而查不到資料。
部署順序:先發版、各站台更新完程式,才跑補預設條件的資料腳本。
- 自訂條件是登入時才載入的。 資料更新後,使用者要重新登入才會看到新的預設條件。
- 原本建好的預設條件一列都不會被改掉或刪掉;只有「完全沒有預設條件」會整組新建,
「整組都沒有日期條件」會多加一列期間。
- 查詢/統計/分析/儀表板類的程式(例如帳齡表、票齡分析、各式儀表板)不在這次範圍,
它們用的是自己的查詢條件面板,沒有清單瀏覽的預設條件。
相關
- 運算子代碼對照:ADR-0001
- 部署腳本(依序):
sql/zcond-sync-fix-20260914.sql(第一段,可先跑)、
sql/zcond-defaults-20260914.sql(第二段,要等程式更新完才跑)、sql/zcond-defaults-date-line-20260914.sql(第三段,同樣要等程式更新完才跑) - 這批要先更新程式再更新資料。 預設的期間用了一個新的關鍵字
-
09-13 virtual-bin-parameter-chinese-key ▸
2026-09-13 倉同儲=N 的虛擬儲位參數改中文 key,空白不再擋存檔
變動
- 倉庫表(SPLACE/GSPLACE)在「倉同儲=N」時自動補的入庫/出貨虛擬儲位,前綴改讀系統參數「入庫虛擬儲位」「出貨虛擬儲位」(原本讀數字參數 3023/3026;3023 已被「出入庫查詢-鋼瓶進出預設查詢品號」使用,3026 從未登錄)。
- 進貨單/總務進貨單存檔時「不可手動輸入虛擬儲位」的檢查、採購進貨轉入、揀貨轉出貨、訂單轉出貨,一律改讀同兩個參數。出入庫單維持 VFP 的 7017。
- 參數空白時不擋存檔(維持舊行為:不補虛擬儲位列、不做關鍵字檢查);參數有值但「值-隸屬倉庫」超過 10 字才擋,並提示到系統參數維護修改。
部署
- 各帳套跑
sql/prgpar-virtual-bin-chinese-keys-20260913.sql(補登兩列、值留空),再到「系統參數維護」填值;填完重新登入生效。
-
09-13 cy-inventory-column-variants ▸
2026-09-13 庫存單據:朝陽帳套隱藏該帳套沒有的欄位
朝陽帳套(朝陽電裝)的資料庫沒有下列欄位,但畫面是兩家共用的,所以這些欄位在朝陽端一直是空白、
填了也存不進去,而且每次開窗都會跳出一個「檢查結果」提示視窗。本次改為在朝陽帳套下直接不顯示這些欄位。
程式 朝陽端不再顯示的欄位 進貨單 交易條件、報單日期、起運點、信用狀號碼、進項發票;明細表的「不良原因碼」欄;費用表的「已轉帳款」欄 加工單 發票金額 出入庫單 快遞號碼;明細表的「內容」欄 出貨單 集團公司、CINO;明細表的「單重」欄 耗料單 其他摘要、發票金額 - 禾久帳套(禾久貿易)畫面與行為完全不變,上述欄位照常顯示與存檔。
- 朝陽端開窗時不再跳出「檢查結果:XAML綁定有、SQL欄位沒有」的提示視窗。
- 隱藏是程式端處理,朝陽的資料庫沒有任何變動;既有資料不受影響。
- 明細表欄位若之前有存過「記憶格式」,朝陽端該欄會自動略過,其餘欄寬與排序照舊。
-
09-12 trrama-totals-recalc ▸
2026-09-12 進貨單主檔彙總欄修正
- 進貨單載入或切換單據時,原幣應收付、總本幣未稅、本幣應收付重新由明細算出(VFP 同公式:原幣應收付=進貨明細原幣未稅合計依稅率含稅;總本幣未稅=依匯率換算;本幣應收付=總本幣未稅+稅額)。
- 產值百分比隨之恢復顯示(分母總本幣未稅先前永遠為 0)。
- 改匯率、稅別、稅額或明細原幣未稅時即時重算。
- 關稅欄仍為明細關稅分攤合計;舊單據若當年關稅稅率為 0,該欄本來就是 0,不屬此次修正。
- 進貨單:右側加總金額改成「金額彙總」區塊(含費用合計),欄名改為原幣未稅合計/原幣含稅合計/本幣未稅合計/本幣含稅合計/關稅分攤合計/其他分攤合計/費用合計/進貨成本/費用率;新增未稅合計兩欄。
- 出貨單:同進貨單做法——右側改成「金額彙總」區塊(原幣未稅合計/原幣含稅合計/本幣未稅合計/本幣含稅合計/費用合計),並補上載入與明細變動時的重算(先前四個合計永遠 0)。
-
09-12 trlost-code-description-columns ▸
2026-09-12 不良品單(TRLOST)/出入庫單(TRLIMA)/生產日報(WKDAY)異常原因/處理方式/不良類別/不良原因欄改為「說明顯示、下拉選代碼」
使用者可見變動
- 不良品單、出入庫單明細原本的「異常原因碼+異常原因」「重工代號+重工」「不良類別碼+不良類別」「不良原因碼+不良原因」四組各兩欄,合併成四欄:異常原因、處理方式、不良類別、不良原因。
- 格子平時只顯示說明文字;點進去編輯時下拉列出「代碼:說明」,選了以後格子回到只顯示說明。
- 「重工代號/重工」欄改名為「處理方式」(與資料欄位「處理方式碼」一致)。
- 生產日報明細的「不良類別碼+不良類別」「不良原因碼+不良原因」「重工代號+重工」三組同樣合併成三欄:不良類別、不良原因、處理方式。
- 出入庫單四欄維持「特殊修改」鎖定時唯讀。
- 修正:不良品單、出入庫單原本的說明欄(異常原因/重工/不良類別/不良原因)開單載入時是空白、要重新選過才會出現;現在載入即依代碼帶出說明。
- 交易別碼欄的下拉同日一併修正:原本編輯時下拉也只顯示說明,現在列「代碼:說明」。
- 修正:交易別碼欄格子空白(禾久耗料單 MP 單回報)。明細的代碼(UM/PD/IN)不在該單別目前的下拉選項(PA…SS)裡,原本靠下拉清單查說明就查不到。現在格子改查全量交易別表,全量也沒有就顯示原代碼,不再留白;下拉仍只列該單別允許的選項。
技術備註
- 新增共用欄
TsGridViewCodeDescriptionColumn(TsControl):格子顯示說明、下拉顯示代碼:說明,清單來源走TableAlias(CMB_ 對照表)或ItemsSourceBinding;綁定欄是數值型時自動掛NumericCodeToStringConverter,因為表格元件的 lookup 要求兩邊型別一致,否則格子永遠空白。
TsGridViewTransactionCodeColumn改為繼承上述共用欄,只保留「沒給清單時用本機 tritem1 全量對照」的預設。
- 翻譯檔
Trlost.json/Trlima.json/Wkday.json:新增「處理方式」,移除不再使用的舊表頭鍵。
- 出入庫單的不良原因對照表沿用原本的 C246(不良品單/生產日報是 C219)。
- 生產日報 VM 原本在換筆後回填
XxxItem給說明欄用的段落已移除(改由欄自行 lookup)。
- runtime 未驗(只過建置+smoke)。
-
09-12 status-bar-and-dead-buttons ▸
2026-09-12 狀態列訊息恢復顯示、數處按下就出錯的功能修好
- 畫面下方狀態列的進度訊息恢復顯示。先前這些訊息被寫到一個沒有接上畫面的地方,等於寫了也看不到;
現在一律寫進真正的狀態列。受影響的功能:成本計算與總帳成本計算(各階段進度「1.清除成本資料」~
「7.計算品號轉撥」)、庫存帳齡查詢、材料分析查詢、訂單與生產分析查詢、總務成本轉入、總務進貨(重新
計算數量)、廠商/委外達成率、進貨地點維護、品號輸入檢核的錯誤提示。
- 下列操作先前按下去會直接跳出系統錯誤,現已修正:
- 庫存管理-進貨單維護「重新計算數量」。
- 代號欄旁的「搜尋」放大鏡按鈕(共用控件,全系統各畫面皆適用)。
- 客戶/廠商/部門代號查詢視窗。
- 系統管理者專用的欄位順序(TabIndex)檢視工具、開發用測試面板。
- 部分彈窗改用自己設定的視窗大小:共 21 支彈窗(進貨轉出貨、提單匯入、揀貨報表、成本計算、
分割採購單、EDI 匯出、批次輸入、傳票控制…)。原本程式裡「把彈窗放大成主畫面大小」的那段設定
從來沒有生效過,因此實際看到的大小與先前相同,不是行為變更。
- 彈窗改由目前主視窗當父視窗,關閉主畫面時不會再留下孤立的彈窗。
以上皆為既有缺陷修正,沒有任何資料或設定需要調整。
2026-09-13 追加:庫存/總務單據的關帳日期檢查恢復生效
庫存單據(進貨、出貨、借出、加工、耗料、盤點等)與總務庫存單據存檔、修改時的「已關帳不得修改或刪除」用戶端檢查,因為呼叫的預存程序
TWORK_CLOSEDATE從來不存在,一直沒有生效。現已在帳套建立這支預存程序(內容同原本的DARB_CLOSEDATE_KC)並登錄到 log 庫。> 需要各帳套跑
sql/twork-closedate-20260913.sql(csa 庫建 SP、log 庫登錄)。生效後,交易日期落在已關帳期間的單據會被擋下,這是原本設計的行為。2026-09-13 追加:例外出入庫查詢的成本匯率開窗自動帶入
條件面板的「成本匯率」表原本全是 0,不先手填按查詢就被「請輸入正確之匯率」擋下。現在開窗時自動帶入當日的賣出匯率(與生產計劃單、營運預測相同),仍可逐格修改。
2026-09-13 追加:下拉選單的空白項不再顯示成「0:」
出貨單、出入庫單的「運送方式」,進貨單的「交易條件」等下拉,第一項(代號 0、說明沒填的那筆)原本顯示成孤零零的
0:。現在這種項目一律整項顯示空白,等同「不選」,選它存進去的值仍是 0。規則為全系統通用:說明空白,且代號空白或全部是 0 → 整項顯示空白;代號有值但說明沒填(例如
RC)仍照常顯示代號。2026-09-13 追加:出貨單瀏覽預設條件、瀏覽查詢失敗訊息、出入庫申請儲位欄、朝陽工作流程註記
- 出貨單明細瀏覽的預設條件「出貨日期查詢」改成最近三個月(原本沒有日期界限,資料量大時查詢逾時)。需各禾久帳套跑
sql/zcond-trsama-browse-default-3months-20260913.sql,重新登入生效。
- 瀏覽查詢失敗時主畫面狀態列只顯示簡短訊息,不再把整段程式錯誤內容印在畫面上。
- 出入庫申請的明細表格補上「倉儲代號」欄(倉庫的倉同儲設為 N 時必填,原本畫面上無處可填)。
- 朝陽帳套補上工作流程註記用的預存程序與檢視(
sql/cy-twork-wkflow-getnotes-20260913.sql),工作流程頁籤不再回錯。
-
09-12 splace-labels-and-dropdowns ▸
2026-09-12 倉庫表(SPLACE)欄位名稱調整、是否可用/倉庫類型改下拉
使用者可見變動
- 標籤「倉庫」改為「隸屬倉庫」、「說明」改為「倉庫說明」,與資料欄位名一致。
- 「是否可用」由輸入 0/1 的數字框改為下拉「是/否」。
- 「倉庫類型」由輸入數字的框改為下拉,選項列「代碼:說明」:1 真實倉庫、2 現場倉、3 外包倉(0 不列;既有值 0 的倉庫下拉顯示空白)。
- 新增時預設:是否可用=是、倉庫類型=1 真實倉庫(既有值 0 的倉庫下拉仍顯示空白)。
- 「檢查負數」與「倉庫類型」位置對調:第 1 列為 隸屬倉庫/是否可用/倉庫類型/單一儲位/成本計算順序/開立日期,第 2 列為 倉庫說明/檢查負數/顯示順序/結帳日期。Tab 鍵順序改為依列由左到右,唯讀的開立日期/結帳日期不進 Tab。
技術備註
- 新增
Common/TsEnum/WarehouseTypeEnum.cs(WarehouseTypeEnumSet)集中定義三個選項;翻譯檔Common/Lang/Xaml/WarehouseTypeEnum.json。
- 使用者實機看過後裁決 0 不列(2026-09-12)。1 的文字是推斷值:Invrec3y 把 0/1 歸為「倉庫」、2 為現場倉、3 為外包倉;禾久 SP
DARB_LOG_WKPAPERA_TO_PD以倉庫分類碼=1判定生產部門的「真實倉庫」。要改文字只改該檔。
- 是否可用走
YesNoComboBox+ByteYesNoConverter(同總務倉庫表 Gsplace)。禾久有一筆倉庫「8.禾久」的可用值是 2,下拉會顯示「是」,再存檔會寫回 1。
- 倉庫類型
SelectedValue綁 byte 欄位,經NumericCodeToStringConverter對上字串 Code。
- 翻譯檔
Splace.json:加「倉庫說明」,刪「倉庫」「說明」;「隸屬倉庫」走 Shared 共用鍵。
- 總務倉庫表(Gsplace)的倉庫分類碼仍是數字框,未動。
- 倉庫類型下拉已由使用者實機確認顯示;其餘欄位未逐一確認。
-
09-12 master-datacontext-currentitem ▸
2026-09-12 單據主檔區綁定寫法統一
- 31 支單據畫面的主檔區改用與範本一致的
MasterData.GridView.CurrentItem綁定(原本用MasterItem)。使用者操作行為不變。
- 未動:12 支沒有掛在任何畫面樣板上的舊檔(Trsama_old、Trrama_zd 等)與兩支自有主檔屬性的畫面(工作流程、紀錄)。
- 31 支單據畫面的主檔區改用與範本一致的
-
09-12 grid-column-width-batch ▸
2026-09-12 表格欄寬全面補齊
- 全系統 352 支畫面、約 8,700 個表格欄位統一給定固定寬度:原本「依表頭自動」或未設定的欄改為依表頭字數計算,中文四個字以上的欄至少 100。
- 名稱/說明類欄至少 150,單號/代號類至少 120,數值類至少 90,日期類 90。
- 既有已手動設定寬度的欄只在低於表頭需要時拉高,其餘不動。
- 13 支畫面因當時另有進行中的修改先跳過(帳款票據查詢、收付款查詢、客戶分頁、生產計劃單等),之後再補。
- 使用者曾用「記憶格式」存過版型的表格,仍以存下來的寬度為準。
-
09-11 trrama-trsama-browse-print ▸
進貨單/出貨單分析報表改到明細瀏覽的列印面板
摘要
進貨單(TRRAMA)與出貨單(TRSAMA)的 14 張分析報表,從原本的「分析報表」彈窗搬到明細瀏覽頁的列印面板,印的是您在瀏覽頁查出來的那份結果。
原本的做法要在彈窗裡重新輸入一次交易日期與廠商/客戶區間,印出來的資料與您剛剛在瀏覽畫面上篩選的結果無關;對照舊系統後確認那組功能本來就是掛在明細瀏覽面板上的。詳見 ADR-0157。
變更
- 進貨單(TRRAMA)、出貨單(TRSAMA) 主檔畫面單號旁的「分析報表」按鈕移除,原本的分析報表彈窗一併移除。
- 改到明細瀏覽 → 列印面板:查詢完直接在列印清單挑報表預覽/列印。
- 進貨 6 張:進貨明細表(廠商別/產品別/日期別),各有「含金額」版本。
- 出貨 8 張:出退貨明細表(客戶別/產品別/日期別/單號別),各有「含金額」版本。
- 報表沿用您在瀏覽頁下的查詢條件,不必再輸入一次;報表頁首會印出該組條件。
- 報表種類決定排序(廠商+品號+日期/品號+廠商+日期/日期+廠商+單號/單號+序號),與舊系統一致。
使用時的注意事項
- 列印前要先在明細瀏覽頁按過查詢;報表印的就是那次查詢的範圍。
- 分析報表的資料來源與瀏覽畫面的欄位不完全相同。若您用了報表資料來源沒有的欄位當查詢條件,該條件會被略過(其餘條件照常套用),並在報表頁首的條件文字尾端標示「(略過:欄位名)」。
不受影響
- 進貨單/出貨單本身的列印頁(進貨單、出貨單等單據報表)完全不變。
- 明細瀏覽的查詢、欄位與匯出 Excel 不變。
- 其他程式的瀏覽頁列印行為不變。
-
09-11 trlost-trwkma-invoice-fields ▸
2026-09-11 耗料單/加工單主檔欄位調整
耗料單(TRLOST)
- 標籤「倉庫」改為「隸屬倉庫」、「前綴」改為「單別」、「注意事項」改為「其他摘要」。
- 隸屬倉庫、單別、交易部門三個輸入框寬度統一為 90。
- 幣別/匯率下方新增發票日期、發票號碼、發票金額、稅額四個欄位(對應 trwkma 既有欄位)。
- 相關單號移到主檔區最右欄。
加工單(TRWKMA)
- 稅額同列補上原本缺少的「發票金額」欄位。
多語言
Common/Lang/Xaml/Trlost.json、Trwkma.json補齊上述新 key 的四語翻譯。
第二批(同日追加)
- 耗料單:單別下拉框加寬到 160(原 90 會把「MP:生產…」裁掉)。
- 耗料單、加工單:中欄改成四欄格線,發票號碼/稅額/匯率的標籤與輸入框上下對齊。
- 加工單:標籤「倉庫選擇」改「隸屬倉庫」、「執行表單」改「單別」;隸屬倉庫輸入框寬 90。
- 進貨單、出貨單、出入庫單:隸屬倉庫輸入框寬 90;標籤「序號前置碼」/「前綴」改「單別」;出貨單「倉庫」改「隸屬倉庫」。
- 對應翻譯檔(Trrama/Trsama/Trinout/Trwkma)同步改 key。
- 耗料單:盤點單號(含盤點退料、PB→PA 鈕)自備註區搬到右欄相關單號下方。
- 耗料單:倉單號/幣別/匯率/稅額標籤改成與加工單相同的等寬排版(「倉 單 號」「幣 別」「匯 率」「稅 額」),翻譯 key 同步。
- 耗料單、加工單:明細「交易別碼」格子點下去炸「RadComboBoxItem 樣式套到 ComboBoxItem」——編輯模板由原生 ComboBox 改為 TsComboBox。
- 耗料單:交易備註搬到中欄發票金額下方;新增轉入備註、轉出備註(唯讀,轉單寫入,照進貨單);備註區只留其他摘要。
- 耗料單:其他摘要搬到交易部門下方,兩行高(50)、寬 302(=倉單號 150+單號 120+各自邊距),右緣對齊單號框;原備註區整段移除。
- 耗料單明細:「交易說明」欄併入「交易別碼」欄——格子顯示說明(交易事項),進編輯下拉列出「代碼 說明」;換選後說明同步更新。
- 出入庫單:「倉庫」改「隸屬倉庫」、「前綴」改「單別」(單別標籤邊距改 1);拿掉公司代碼欄位(新增時系統固定給 1)。
- 進貨單:「倉單號」改「進貨單號」;單別標籤邊距改 1。
- 出入庫單、出貨單:「暫收備註」改「交易備註」;出入庫單「追蹤號碼」改「快遞號碼」。
- 進貨單:兩個明細表格之間加可拖曳分隔線;中欄重排為第一列稅別、第二列發票日期/發票號碼、第三列發票金額/稅額。
- 出入庫單:倉儲調撥、物料調撥、撿貨調整三顆鈕先隱藏;其餘功能鈕群靠主檔區最右;快遞號碼移到交易備註上方,轉入備註、轉出備註移到交易備註下方。
- 出入庫單:借出查詢、Excel 匯入明細移到功能鈕群最下面。
- 出入庫單明細:補回交易別碼、派工單PKID、訂單PKID、其他資料1、其他資料2、單位成本、成本、轉入單PKID、轉入單號、沖回數量十欄;「例外代號」改「例外出入」並改成格子顯示說明、下拉列代碼+說明,原獨立的「例外」說明欄併入。
- 出貨單:先拿掉「單據類別」下拉;中欄重排為第一列稅別、第二列發票日期/發票號碼、第三列發票金額/稅額(同進貨單)。
- 出貨單:「業務員代號」標籤改「業務員」。
-
09-11 trlima-buttons-b ▸
出入庫單:補回「取批號」、虛擬儲位調撥、送樣轉 EO、出通轉調撥,以及朝陽的「不良轉入」
日期:2026-09-11
影響程式:出入庫單(TRLIMA,H 庫存管理)
接續同日第一批(
2026-09-11-trlima-buttons-a),這次把舊版(VFP)出入庫單剩下的四顆「開視窗挑資料」的鈕,以及朝陽帳套的【不良轉入】補齊。
> 這七個功能只在禾久帳套顯示(【Excel匯入明細】【帶入申請單】【出通反調撥】
> 【虛擬儲位調撥】【送樣轉EO】【出通轉調撥】與明細列的【取批號】)。
> 它們在舊版也只存在於禾久版,而且用到的資料表在朝陽帳套本來就沒有(製通單沒有批號欄、
> 沒有送樣單、料件沒有成箱領料量),所以在朝陽帳套整組隱藏不顯示。
> 反過來,下面第 3 點的【不良轉入】只在朝陽帳套出現。
使用者看得到的變化
1. 明細每一列多了【取批號】按鈕
新增/修改/複製新增狀態下,明細表格的「批號別」欄前面多一欄【取批號】,每列一顆鈕
(瀏覽狀態與「特殊修改」狀態下這顆鈕不能按)。
按下去會開「品名調撥單勾選視窗」:
- 上方輸入製通單號(或批號)後按查詢;輸入純數字時當成製通單的內部編號查,
否則同時比對製通單號與批號。
- 表格列出該製通單的各個途程:製通單號/批號/途程序號/工程代號/工程簡稱/現有數量/
品號/品名/批號別/單位/製通單pkid。每個途程會出現兩列——一列是正常工程代號、
一列是工程代號 XXX 的「不良品」;最後再加一列不帶數量的「不良品」彙總列。
- 勾一列(勾選是單選,勾新的會自動取消舊的)後按【確定】,會把那列的
批號別/批號/工程代號/途程序號/品號/單位填回剛才那一列明細,
數量填成負數(和舊版一樣,這張單是把料從製令批號調出來)。
2. 新增出入庫單時多了三顆帶料的鈕
在【申請單號】那一區下面,新增狀態下可用:
【虛擬儲位調撥】
查「入庫虛擬儲位」(系統參數 7017)上還有數量的所有品項,開勾選視窗(預設全部勾選,
可用【勾選全部】/【全部不選】),按【確定】後:
- 單別切成 SS(調撥)、倉庫與主檔交易部門切成該儲位的隸屬倉庫、申請日期帶今天。
- 明細逐列帶入品號/單位/數量(=現有數量)/轉出倉儲=虛擬儲位,
轉入倉儲留白由使用者自己填。
- 虛擬儲位上沒有任何數量時,只會提示「入庫虛擬儲位無資料」,不開視窗。
【送樣轉EO】
查所有已審核、未結案、而且還沒交清的送樣單明細,開勾選視窗,按【確定】後:
- 單別切成 EO(例外出庫)、倉庫切成備料倉庫(參數 8003)、主檔交易部門帶業務部門(參數 5005)、
申請日期帶今天。
- 明細逐列帶入品號/單位/數量=送樣數量−已交數量,並記住來源送樣單明細,
存檔後才算得回送樣單的已交數量。
【出通轉調撥】
開視窗後在視窗裡輸入出通單號再按查詢(和前兩顆不同,來源資料是在視窗裡查的):
- 上表列出該出通單裡還沒調撥完、還沒出貨完、未結案的明細;備註自動組成「客戶簡稱---單號」。
已經有製通單號的列數量會帶 0(等於不轉,按確定時會被濾掉)。
- 下表列出 MRP 倉庫(參數 7009)底下、這些品號還有庫存的儲位,含原有庫存量/ABC 分類/
儲位/包裝量/成箱領料量/安全庫存。下表只顯示上表目前選取那一列的品號(和舊版一樣,
點上表換一列,下表就跟著換)。在上表點一列、再按下表那一列的【選用】鈕,
就會把該儲位填進上表的「轉出倉儲」(舊版是雙擊,新版改成明確的按鈕)。
- 還沒輸入出通單號就按查詢,會提示「請輸入出通單號」。
- 按【確定】後:單別切成 SS、倉庫切成備料倉庫、主檔交易部門帶調入倉庫(參數 3021)、
申請日期帶今天、暫收備註帶出通單號;明細逐列帶入品號/單位/數量/
轉入倉儲=調入儲位(參數 3022)/轉出倉儲(上表指定的)/備註,並記住來源出通單明細。
- 零數處理:轉出儲位在倉儲設定的備註裡標了「成箱」的,會依該品號的「成箱領料量」
算出湊整所需的差額;差額大於 0 且有設定零數儲位(參數 3019)時,會自動多一列——
同品號、數量=零數、轉入倉儲=零數儲位。這一列刻意不記來源出通單,所以不會回扣出通單的調撥數量
(和舊版一樣)。
> 三顆鈕都只有在「新增」狀態才能用;在瀏覽或修改狀態下按,會提示
> 「只有在新增狀態才能使用這個功能」。
>
> 另外,這幾顆鈕(含第一批的【帶入申請單】【出通反調撥】)都會把單別換成 SS 或 EO。
> 若該帳套的交易事項表沒有登錄這個單別,現在會直接提示
> 「交易事項表沒有登錄 XX 單別,無法帶入」並停住,不會像以前那樣帶完資料、存檔時才配不到單號。
3. 朝陽帳套的【不良轉入】可以用了
「其他功能」裡的【不良轉入】原本按下去沒反應(第一批的說明裡列為另案處理),這次補上。
按下去會開「不良轉待核報倉及報廢倉視窗」:
- 上方條件:來源交易日期起訖(預設當月 1 日到今天);以及要寫進新單的交易日期、
報廢單交易部門(必填)、交易備註。
- 按查詢後,「資料」分頁列出報廢倉裡待轉出倉還是空白的不良品——包含報廢倉的 SS 調撥單
與報廢倉的 NA 不良退庫單兩種來源(「來源別」欄可以看出是哪一種);
「無法轉單」分頁列出同條件下正被別人修改中的資料與修改人員。
- 勾選要轉的列(有【全部選擇】/【全部不選】)後按儲存,會依不良原因碼一次產生兩張入庫單:
- 不良原因碼 1、8、9 → 一張 SS 調撥單,交易部門「待核報」,轉出倉儲「報廢倉」、轉入倉儲「待核報」。
- 其餘不良原因碼 → 一張 NB 報廢單,交易部門=你輸入的報廢單交易部門,
轉出倉儲「報廢倉」、轉入倉儲留白。
- 兩邊都沒有資料的那一張就不會產生。
- 轉出來的單據,明細序號會在新單裡重新編號(001 起);要追來源請看該列記住的來源單據關聯,
不要用序號對照(勾選的列可能來自多張來源單,照抄來源序號會重複)。
- 存檔後畫面會自動跳到轉出來的單據。
- 存檔前的檢查:交易日期不可空白、不可小於等於關帳日期、報廢單交易部門不可空白、至少要勾一列。
> 這個功能只有朝陽帳套的權限設定裡有「不良轉入」標籤,其他帳套不會出現。
給系統管理者的備註
新出現的系統參數依賴(都在「程式參數」裡設定):
參數 用途 7017 入庫虛擬儲位(虛擬儲位調撥的轉出儲位;第一批的出通反調撥也用它) 8003 備料倉庫(送樣轉 EO、出通轉調撥的隸屬倉庫) 5005 業務部門(送樣轉 EO 的交易部門) 3021 調入倉庫(出通轉調撥的交易部門) 3022 調入儲位(出通轉調撥的轉入倉儲) 3019 零數儲位(沒設定就不做零數拆列) 7009 MRP 倉庫(出通轉調撥下方庫存表只列這個倉庫底下的儲位) 沒設定的參數會讓對應欄位留白或該段功能不動作,不會報錯。
- 不良轉入(朝陽):轉單前會先確認交易事項表有登錄 SS(待核報)與 NB(報廢)單別,沒有就提示不轉,避免配不到單號。
-
09-11 trlima-buttons-a ▸
出入庫單:補回「特殊修改」、Excel 匯入明細、帶入申請單、出通反調撥四個功能
日期:2026-09-11
影響程式:出入庫單(TRLIMA,H 庫存管理)
舊版(VFP)出入庫單上有一批鈕在改版時沒有跟著移植過來,這次先補第一批。
使用者看得到的變化
1. 「特殊修改」按了會有反應了
畫面下方「其他功能」裡的【特殊修改】原本按下去完全沒動作。現在按了會進入特殊修改狀態:
- 這個狀態是給「已經存檔、但一般修改會被擋住」的單據用的——例如由盤點單或調撥申請單轉來的
出入庫單,平常按修改會跳「本單據由…轉來,不得修改」,走特殊修改就可以進去。
- 進去之後明細只有「備註」可以改,其他欄位(品號、數量、倉儲、各種代號…)全部鎖住;
主檔欄位預設也全部鎖住,只有權限設定裡「特修改欄位」有列出來的欄位才打得開。
- 要用這個功能,使用者的權限設定必須有「特殊修改」這個其他功能標籤(禾久帳套本來就有)。
2. 新增出入庫單時多了【Excel匯入明細】
在【借出查詢】旁邊。按下去會跳出選檔視窗(預設開在
C:\轉EDI資料、預設檔名TRLI.XLS,可以自己挑別的檔,
.xls/.xlsx都讀得到),選好之後照固定欄位順序把整份明細一次帶進來:Excel 欄 帶到明細的欄位 第 2 欄 品號(會自動帶出品名) 第 4 欄 批號別 第 5 欄 批號 第 7 欄 途程序號 第 8 欄 工程代號 第 10 欄 數量 第 11 欄 交易別碼 第 12 欄 轉入倉儲 第 13 欄 轉出倉儲 第 14 欄 備註 第 1 列當標題列不讀,從第 2 列開始;讀到品號空白的那一列就停。第 1、3、6、9 欄
(倉儲代號/品名/批號C/工程簡稱)不讀,跟舊版一樣。匯入的資料會先填進明細裡品號空白的列,
不夠才新增列。
3. 新增出入庫單時可以直接打申請單號帶資料
新增狀態下,畫面右側多了「申請單號」欄和【帶入申請單】鈕。打上調撥申請單號後按鈕:
- 查這張申請單裡還沒結案、而且申請量大於核發量的明細;查不到會提示「無此申請單號 或均已核發」。
- 查到就把單別切成 SS(調撥)、倉庫切成申請單的隸屬倉庫,主檔的交易部門帶申請部門、
申請日期帶申請單日期、暫收備註填成「申請單號○○○:申請原因」。
- 明細逐列帶入品號、單位、數量=申請量−核發量、轉入/轉出倉儲、交易別碼,
並記住來源申請單的明細(之後核發量才算得回去)。
- 帶完申請單號欄會自動清空。
4. 新增出入庫單時可以做「出通反調撥」(回沖)
同一區多了「回沖單號」欄和【出通反調撥】鈕。打上先前那張出通轉調撥的單號後按鈕:
- 查該單裡還沒沖回完的出通調撥明細;查不到會提示「無資料」。
- 查到就把單別切成 SS、倉庫切成來源單的交易部門,主檔交易部門帶來源單的隸屬倉庫、
申請日期帶今天、暫收備註填成「回沖:單號,倉單號」。
- 明細逐列反向帶入:數量=原數量−已沖回數量,轉出倉儲=原本的轉入倉儲,
轉入倉儲=系統參數設定的入庫虛擬儲位(參數 7017),並標記成回沖列,
存檔後會回沖原本那張單的數量。
- 帶完回沖單號欄會自動清空。
> 【Excel匯入明細】【帶入申請單】【出通反調撥】三個功能都只有在「新增」狀態才能用
> (和舊版一樣);在瀏覽或修改狀態下按,會提示「只有在新增狀態才能使用這個功能」。
其他
- 清掉兩個從來沒接到畫面上的無效指令(拆列出貨、倉儲調撥轉窗),對使用者沒有影響。
- 朝陽帳套的【不良轉入】仍然沒有作用:它要開的是舊版的「不良轉入」挑單視窗,該視窗還沒移植,
另案處理。
-
09-11 transaction-code-column-unified ▸
2026-09-11 交易別碼欄全系統統一顯示
- 所有表格的「交易別碼」欄(32 欄,涵蓋庫存、總務、帳款、EIS 查詢、銀行對帳)統一改為:格子顯示交易說明文字;可編輯的欄進編輯時下拉列出「代碼 說明」;唯讀與查詢型表格只顯示說明。
- 原本另外一欄的「交易說明/交易事項」(耗料單、加工單、耗料查詢、銀行對帳查詢)併入交易別碼欄,不再重複顯示。
- 查詢型表格的說明由本機交易別對照表反查,不必改查詢程序。
- 例外:庫存簿(Invbk2)的交易別碼字串本來就含說明,維持原樣。
- 欄寬統一 120。
-
09-11 other-button-audit-workflow-bridge ▸
2026-09-11 審核/流程鈕接回舊權限表的「快速審核/工作流程」
使用者可見變動
- 審核鈕、流程鈕出現了:以前在舊系統其他功能鈕有「快速審核」「工作流程」權限的人,新系統右側面板現在直接看到整合的「審核」「流程」鈕;原本那兩顆多出來的「快速審核」「工作流程」其他功能鈕不再顯示。
- 權限以其他功能勾選為準:程式在權限表有登「快速審核」或「工作流程」的,就看該格「可否其他N」;權限表的「可否審核」「可否流程」對這些程式暫時不生效(並行期結束後搬遷資料再恢復)。
- 查詢視窗的流程鈕開始看權限:以前只要有簽核樣板就能按,現在還要有流程權限(口徑同主畫面)。朝陽有 1114 列使用者×程式會因此收掉流程鈕(舊系統本來就沒給)。
- CI(出貨通知)其他功能鈕改照名稱對應:「拆單」開訂單轉出貨通知;「報關單」「調撥指示」新版尚未提供,鈕顯示為停用(「報關單」以前按下去其實是開「併入既有出貨通知」,屬接錯線)。
相關
- ADR 0156
- 程式:
LogicBll/銜接/LegacyOtherButtonBridge.cs、ViewModel/Ade/AdePermissionViewModel.cs、ViewModel/Control/PageParts/ActionPanelViewModel.cs、ViewModel/E.Order/CiViewModel.cs、ViewModel/Control/QueryPanelViewModel.cs
- 測試:
LogicBllTests/銜接/LegacyOtherButtonBridgeTests.cs
-
09-11 fixlist-0910 ▸
2026-09-10 修改清單:報表分客戶顯示、請購轉採購/訂單轉出貨接回、PAYPDT 卡頓、廠商資料版面等
日期:2026-09-11
影響程式:列印頁(全系)、廠商資料表(SPDATA)、採購單→請購轉採購(PPTOPU)、出貨單→訂單轉出貨(ODTOSA)、採購資料查詢(PURCHQUERY)、進貨轉應付(PAYPDT)/出貨轉應收(RECEPDT)、沖帳(RPFZERO)、費用科目表(GRPMACCL)、其他應收付(OTHERRP)、客戶資料表(CUDATA)、供應商協同回覆審閱(POCOLLABRPY)、所有單據的操作按鈕列、15 支轉單視窗
> 本批全部 尚未實機驗證(建置+smoke 測試通過)。
使用者看得到的變化
1. 列印頁的報表清單:禾久版與朝陽版分開排
同一支程式若同時有禾久版與朝陽版報表,現在會把「本帳套的版本+通用報表」排前面,另一家的排後面並加註
【朝陽版】或【禾久版】,序號重編;預設選中的第一張一定是本帳套的版本。判定靠報表檔命名(
_cy/Cy/Nogi)。另外,程式端已登錄的報表不再與資料庫
_rptdat同編號的列重複顯示(朝陽應付列印清單原本會多出 6 筆重複、其中一筆點了「檔案不存在」)。2. 應付列印:預覽視窗標題與匯出檔名不再一律「ApPrint_cy」
原幣/本幣等六張報表的檔案內部名稱都寫成 ApPrint_cy,預覽標題與 PDF/Excel 檔名因此看起來像選錯報表。已改成各自的報表名。
3. 廠商資料表(基本資料1 分頁)
「會計與採購條件」區塊併入「基本資料」區塊:收付款廠商緊接在廠商名稱下一列,其後依序是供應項目、科目代號、稅別/帳款起始日/收付條件號、等級/交易條件/付款方式碼、關係人/付款日遇假日提前。
帳款起始日(廠商、客戶、其他應收付三處)個位數時右側不再多一格空白。
4. 採購單「請購轉採購」與出貨單「訂單轉出貨」
按下去不再出現「沒有 TWORK_TUR_PPTOPU/TWORK_TUR_ODTOSA」。這兩支預存程序從來不存在,現改接資料庫實際有的版本。
> 需要在各帳套的 log 庫跑
sql/proc-param-tur-pptopu1-odtosa-20260911.sql,否則轉單查詢會靜默沒資料。> 訂單轉出貨的畫面與資料欄位仍是舊英文版,接回後仍可能空白,待另案整支中文化。
5. 轉單視窗大小
15 支原本固定 1200×560(或 800×560)的轉單視窗改為跟著主視窗大小(主視窗減 100)。
6. 採購資料查詢
採購單號變成可點的連結,點下開採購單並定位到該張單。
7. 進貨轉應付(PAYPDT)/出貨轉應收(RECEPDT)
- 視窗標題改中文:「進貨轉應付帳款」「出貨轉應收帳款」。
- 儲存成功訊息改中文,「開始單號:」「截止單號:」等長對齊。
- 主檔的「選擇」按鈕按下後,下方明細會跟著切到那一筆。
- 明細多的單據切換/勾選明顯卡頓已改善(合併模式下原本每一筆明細各重算一次整張帳款)。
- 疊在同一位置的兩顆「全選」鈕只留一顆。
8. 沖帳(RPFZERO)
灰色底色拿掉;列選取後淡綠底不再配白字(字回黑色)。同一問題的共用樣式一併修,其他用綠底標示選取列的畫面也受惠。
9. 操作按鈕列的「審核」「流程」鈕
改成依程式決定顯示:有審核權限且主檔有「已審核」欄才顯示審核鈕;有流程權限且該單據別有簽核樣板才顯示流程鈕(客戶變體程式查不到樣板時退回查基底單據別)。
新增/修改狀態下這兩顆鈕一律收起,儲存/取消不會被它們蓋住;存檔完成後它們才出現,配合既有的 400 毫秒防連點守門,儲存連按兩下不再直接送審。
10. 費用科目表
借貸別改成一般下拉(借方/貸方),不再是代號+說明的組合框。
11. 供應商協同回覆審閱
選單改掛「Y.新功能測試」Y-07。
> 需要各帳套跑
sql/pocollabrpy-menu-seed-y07-20260911.sql(朝陽庫缺登錄工具會被擋下)。部署提醒
sql/opendbf-sk-spdata-cudata-data-y-20260911.sql:SK_SPDATA/SK_CUDATA 改為整包下載(含資料=Y),使用者重新登入後生效。
- FastReport 六張 Apprint frx 已同步到報表資料夾。
12. 庫存單據搜尋區多了「倉庫」「單別」(同日追加)
借出、進貨、出貨、工單、耗用、異常領料六支單據的搜尋區改用庫存版:倉庫、單別、倉單號排在同一列;開窗時單別預設第一個(依交易事項表的排列順序排)、倉庫預設該單別在交易事項表設定的預設倉庫;上下一筆/搜尋只在該倉庫與單別內;把欄位清空=不過濾。倉庫與單別都有選時,搜尋只打流水號會自動補上前面的倉庫+單別。新增時會把選的倉庫與單別帶進新單(異常領料除外,維持原本的帶法)。
14. 下拉選單的空白項不再顯示「:」(同日追加)
共用的下拉項目樣板改成代號空白時不畫冒號,各程式下拉的空白預設項不再出現孤零零的「:」。
13. 出貨單「訂單轉出貨」整支中文化(同日追加)
畫面全部改中文,資料欄位對上實際的預存程序,原本查得到卻一片空白的問題解掉;並補回前一版遷移時漏掉的「庫存彙總」「庫存明細」「採購未入/訂單未交」三張表與「挑選」鈕(倉同儲=N 的倉庫要靠它填轉出倉儲才存得了檔)。
第二輪再對照 VFP 表單原碼逐項對齊:抬頭用詞全照原版、補回超交檢查、倉庫與儲位檢查、倉同儲的倉庫取法、客戶帶幣別與出貨倉庫、換幣別重算匯率、十一個原本沒寫進出貨單的欄位(聯絡人、交易備註、其他摘要、付款方式碼、預訂交期、備註、客戶訂單號、客訂單序號、單重、客廠品號等)。「交期不同」欄原版因判斷順序寫錯永遠是否,本次改成有效判斷並照原版紅底標示。
另依裁決:轉單存檔成功後會問「是否列印出貨單」,選是直接進出貨單列印頁;畫面上沒作用的「單據分類」下拉拿掉;含稅單價沿用訂單上的值;倉同儲為 Y 時轉出倉儲欄唯讀;出貨數量大於零的列以淡綠底標示,改數量會即時更新。
-
09-11 actionpanel-audit-workflow-visibility ▸
2026-09-11 操作列審核/流程鈕顯示規則簡化
- 審核鈕與流程鈕的顯示/隱藏只看編輯態:按新增/修改進入編輯時收起(讓位給儲存/取消),離開編輯即顯示。
- 沒有審核權限或流程權限時,按鈕改為顯示但停用(灰掉),不再整顆消失。
- 拿掉「主檔沒有已審核欄就藏審核鈕」與「單據別沒有流程樣板就藏流程鈕」兩條判斷,各程式的操作列版位固定一致。
-
09-09 prodplanm-add-permission-and-ui ▸
生產計劃單:可以新增了,查詢/客戶設定鈕改成圖示鈕,審核欄位顯示調整
日期:2026-09-09
影響程式:生產計劃單(PRODPLANM,子系統 Y「新功能測試」Y-06)
使用者看得到的變化
1. 「新增」可以按了
原本按新增會被擋(或整顆鈕是灰的)。原因是這支程式登錄時,權限是從唯讀的「生產計劃查詢」
整列複製過來的,新增/修改/刪除三個權限旗標都是關的。已補上,現在可以正常新增、修改、刪除。
因為【客戶設定】【查詢】兩顆重算鈕本來就只在「新增」狀態才開放,這個問題連帶讓那兩顆鈕
永遠是灰的——權限補好之後,按新增就會亮起來。
> 需要跑
sql/prodplanm-permission-fix-20260909.sql(每個帳套各跑一次)。2. 【客戶設定】【查詢】改成圖示鈕
兩顆鈕原本只有文字、又小又不顯眼,容易被當成沒有這個功能。現在改成和系統其他操作鈕一樣的
「圖示+文字」樣式(查詢是放大鏡、客戶設定是齒輪),並加上滑鼠提示:滑過灰掉的鈕會顯示
「重算只在新增狀態可用」,說明為什麼不能按。
3. 成本匯率表會自動撐滿左側剩下的高度
原本固定最高 220 像素,畫面再大也不會變高,幣別多的時候要捲動才看得完。
現在會自動展開到左欄剩下的空間。
4. 審核欄位顯示調整
- 主檔上的「審核人員」「審核日期」原本只有兩個沒有標題的框,分不出哪個是哪個;
現在各自補上欄位名稱,審核日期也改成日期欄位格式顯示。
- 畫面右上角原本還會再重複顯示一次「已審核」和一顆展開審核資料的圓鈕,本程式已隱藏,
審核狀態一律看主檔上那一組。(其他程式不受影響。)
技術備註
- 右上角審核區塊的隱藏是「程式自己選擇加入」:ViewModel 實作
ViewModel.Control.PageParts.IExtensionPanelApprovalHidden才會隱藏,預設仍然顯示。---
同日第二批
5. 存檔後明細(客戶設定/訂單預示預估/生產計畫/使用量)會不見 —— 已修
存檔會成功、也真的寫進資料庫,但四張明細的「歸屬單號」欄(linkid)停在 0,變成沒有主人的孤兒列;
而畫面載入明細是「找 linkid 等於這張單」的資料,所以下次開這張單四個分頁全空。
原因:這四張明細不是用表格手動一列一列新增的(那條路框架會自動接歸屬),而是【客戶設定】【查詢】
兩顆鈕算出來整批塞進去的,歸屬欄沒人接。現已在存檔前統一接上。
> 已經存壞的單(明細在資料庫裡但 linkid=0)救不回原本的歸屬,建議重存一張新的;
> 舊的孤兒列可另行清理(見技術備註)。
6. pkid 搬到主檔
單號、單據日期同一列後面加上 pkid(唯讀)。畫面右上角原本顯示 pkid 與已審核的小面板,本程式整組隱藏。
7. 成本匯率表左右也會撐滿
原本固定 240 寬,比上面的欄位區窄一截;現在跟著左欄寬度伸縮,「成本匯率」欄吃剩下的寬度。
技術備註(第二批)
ProdplanmSave.HandleDataBeforeEndEdit統一接 d1~d4 的 linkid(照PerdataSave.cs:70模式);
新增時主檔 pkid=-1 哨兵值,子列一起帶 -1,上傳鏈 remap 才會命中。
這是 2026-07-16 zcond 事故的同一顆雷(memory
zcond-linkid-orphan-incident)。- 右上角面板隱藏改用
ViewModel.Control.PageParts.IExtensionPanelHidden(宣告式、預設仍顯示,其他程式不受影響)。
- 孤兒列清理(未執行,需確認):
DELETE FROM twork_eis_productiond1 WHERE linkid = 0;(d2/d3/d4 同)—— dev 庫目前 648/32972/32798/72842 列。---
同日第三批
8. 樞紐分析(比照「生產計劃查詢」)
生產計劃單也有樞紐分析了:明細分頁上方多一列「樞紐下拉+樞紐分析表鈕」,
按下去會用和查詢那支同一份 Excel 範本(生產計劃查詢樞紐分析表.xlsx)開出樞紐,
表一=生產計畫、表二=使用量,彙總口徑與查詢那支完全一致。
- 沒有生產計畫資料時按樞紐鈕會提示「無資料」。
- 需要跑
sql/prodplanm-pivot-register-20260909.sql(每個帳套各跑一次),跑完要重新登入才看得到。
9. 孤兒明細已清理(開發資料庫)
第 5 點造成的無主明細列已備份後刪除(
*_bak_20260909):648/32972/32798/72842 列。2026-09-02 那張舊單的明細未受影響。存壞的那張空殼單(PP20260909001)建議直接刪掉重存。
技術備註(第三批)
- 兩張樞紐資料表的組裝抽成共用的
LogicBll/M.EIS/ProductionPlan/ProductionPlanPivotBuilder.cs,「生產計劃查詢」與「生產計劃單」共用一份 —— 欄名與欄序是 Excel 範本的 ODBC 契約,
兩支各留一份會默默走鐘。
- 單據型版面(
ErpProgramLayout)沒有框架提供的樞紐選擇器(那是查詢型版面才建的),
改由
ProdplanmViewModel自建PivotSelector1ViewModel掛在頁面上,不動框架版面。- 表名沿用
TWORK_QRY_PRODUCTIONPLAN(+_USAGE00):Excel 範本的連線照表名綁死,換名會失敗。
---
修正:左欄把明細擠掉(第三批的後遺症)
成本匯率表改成「左右撐滿」之後,左欄變成會無限往右長、把右邊的明細表格擠掉。
已修正:左欄現在最寬 620,超過就不再長,明細維持原本的空間。
---
同日第四批:條件改存 JSON、成本條件加類別
10. 「刪除數量為 0」改成勾選框
原本是「是/否」下拉,現在是一個勾選框,勾了就代表要刪掉數量為零的資料。
11. 查詢條件改用 JSON 儲存
單據上的整組查詢條件(資料別、起訖日期、截止報價日期、刪除數量為零、預估百分比、成本條件表)
現在整包存成一欄 JSON。好處是以後要加新的查詢條件,不必再改資料表結構、也不必每個帳套各跑一次腳本。
> 起訖日期、截止報價日期、刪除數量為零 這幾欄仍會同步寫回原本的欄位,清單瀏覽與「載入歷史單」的清單靠它們顯示。
12. 「成本匯率」改名「成本條件」,多一個「類別」欄
- 類別可選「匯率」或「原物料」。
- 匯率列的行為和原本的成本匯率完全一樣(計算會用)。
- 原物料列這一版只做輸入與保存,不參與計算。
- 新增單據時可以自己加列;瀏覽既有單時不開放加列。
13. 舊單據的匯率不再保留
2026-09-09 之前存的生產計劃單,成本匯率是存在舊格式欄位裡的,該欄位已隨這次改版移除。
開啟舊單時條件仍看得到(日期那幾欄還在),但成本條件表會改帶當日匯率。這是刻意的取捨。
技術備註(第四批)
- 新增
Common/Model/M.EIS/生產計劃單條件.cs(生產計劃單條件+生產計劃成本條件+成本條件類別)。
- 主檔
匯率資料(VFPData XML)→條件資料(JSON,Newtonsoft);
Twork_eis_vw_productionmSource新增To條件JSON()/From條件JSON()/Get匯率列()。Get匯率列()只放行類別=匯率的列:ProductionPlanBll會ToDictionary(幣別),
原物料列混進去同幣別會撞 key 直接炸。
- 「生產計劃查詢」的
ProductionPlanDocumentBll一併改寫 JSON,兩支程式格式一致。
- DB:
sql/prodplanm-conditions-json-20260909.sql(加條件資料、DROP匯率資料、
sp_refreshview兩個 view)。必須配合發版,否則舊程式找不到欄位會存檔失敗。---
修正:下拉選單空白項顯示成一個孤零零的「:」
代號與說明都空白的下拉項(例如「不指定」那一列),會顯示成一個冒號。
2026-09-06 已針對共用基底修過一次,但四個衍生的下拉型別自己覆寫了顯示方式、沒帶到那次的修正:
客戶/廠商別、借貸別、科目類別、待辦工作別。這次一併改走同一個共用寫法,空白項就是空白。
-
09-09 nogi-warehouse-inbound-forms ▸
禾久:其他入庫單/借入單改用專屬套印格式(2026-09-09)
使用者看得到的變動
適用對象:禾久帳套。(其他客戶的入庫單列印完全不受影響。)
入出庫作業(TRLIMA)的列印頁,第一個選項「入庫單」以前不論哪一種單別都印同一張 A4 版面。
現在改成依單號前置碼自動挑對應的格式,與舊系統一致:
單別前置碼 印出來的表單 紙張 調撥出倉單(SS) 調撥出倉單 中一刀 借出還入單(LI) 借入單(新) 中一刀 其他(例外入庫單、盤點調整單、報廢單、模具出入庫單、借出單…共 14 種) 其他入庫單(新) 中一刀 兩張新表單都是印在預先印好格線的表單紙上(中一刀點陣紙,9.5 吋 × 5.5 吋),
每頁固定 10 筆明細、右上角印「頁次/總頁次」,最後一頁才印交易備註。
新表單會多印的內容
以前的版面沒有、新表單會印出來的欄位:統一編號、送貨地點、聯絡人。
其中「送貨地點」的組法與舊系統相同——客戶有填送貨地點就印送貨地點,沒有就印公司地址;廠商一律印公司地址。
電話/傳真的來源調整
入庫單上的電話/傳真以前分別取自不同的地方(電話取客戶/廠商共用檔、傳真只取客戶主檔),
造成廠商的單子會印出空白或不正確的傳真。現在統一改成:客戶取客戶主檔、廠商取廠商主檔,與舊系統一致。
> ⚠️ 這會讓部分單據上的電話/傳真與改版前不同(以廠商為交易對象的單據影響最大)。
照舊系統維持空白的兩處
- 「其他備註」欄:舊系統的資料表就沒有這個欄位,一直是空白,本次照舊不填。
- 借入單的「例外出入原因」欄:舊系統自 2018/07/23 起就不印這一欄(原本印的是來源借出單號),本次照舊留白。
要恢復印來源單號需要另外評估(資料表目前也沒有存這個欄位)。
需要注意
- 第一次列印請先對位:兩張表單的紙張尺寸是依版面推算的,實際上機列印時請先用一張紙試印、確認格線對得上,
必要時再微調印表機的起始位置。
- 電話/傳真來源的調整需要一併更新資料庫(隨本次版本部署)。
-
09-09 nogi-shipping-forms ▸
禾久:出貨單改用專屬套印格式(四種版本)(2026-09-09)
使用者看得到的變動
適用對象:禾久帳套。(其他客戶的出貨單列印完全不受影響。)
出貨作業(TRSAMA)的列印頁,以前只有一個「出貨單」選項、印一張 A4 版面。
現在改成四個選項,與舊系統一致:
列印頁上的選項 金額欄位 出貨數量 出貨單(整數) 印 整數 出貨單(3位小數) 印 小數三位 出貨單(不含金額/整數) 不印(單價、金額、貨款小計、稅額、合計金額都不出現) 整數 出貨單(不含金額/3位小數) 不印 小數三位 四張都是印在預先印好格線的表單紙上(中一刀點陣紙,9.5 吋 × 5.5 吋)。
「不含金額」那兩張是給不希望對方看到單價的場合(例如送貨簽收聯)用的。
版面行為(與舊系統相同)
- 每頁固定 10 筆明細,右上角印「頁次/總頁次」;不足 10 筆的部分留白。
- 出貨單/出貨退回單:同一張表單依單據性質自動切換標題,不必分開選。
- 出貨退回單的數量與金額印負數;但「今日歸還」的鋼瓶借出列照樣印正數。
- 貨款小計、稅額、合計金額、發票號碼、交易備註只印在最後一頁。
- 箱數:品號有設外箱包裝量時印
( 箱數 ),沒設就留白。
- 項次是整張單跨頁連號;序號為
A00的列不印項次、其他A開頭的列印序號原值(借出未還)。
- 借出提醒:該單只要有一筆借出明細,交易備註最後會自動加上
「(借出之鋼瓶及其他物品須歸還,若遺失需照價賠償 !)」。
- 運送方式有填時,會加印在交易備註的第一行。
- 倉單號含「禾久科技倉」時縮寫成「禾久科」(原字串太長印不下)。
照舊系統維持空白的一處
- 「規格」欄:舊系統在列印程序裡就把這十個欄位固定清成空白(原始碼註解寫「禾久不要規格」),
本次照舊不填。要改成印規格只需調整程式一行,但屬於行為變更,需要另外確認。
需要注意
- 第一次列印請先對位:紙張尺寸(241 × 140 mm)是依版面推算的,實際上機列印時請先試印一張、
確認格線對得上,必要時再微調印表機的起始位置。
- 列印不會再自動遞增「理貨人員」:舊系統每列印一次會把理貨人員改寫成「使用者--次數」並累加,
新版不做這個寫回動作(列印是唯讀動作)。需要記錄列印次數請另外提出。
- 本次不需要調整資料庫(現有的出貨單查詢程序已涵蓋全部欄位)。
-
09-09 grid-excel-import-seek-validation ▸
2026-09-09 表格「從 Excel 匯入」會檢查代號、並自動帶出名稱
變動內容
明細表格右鍵的「從 Excel 匯入」,過去只檢查欄位型別(例如日期欄填了文字)。這次補上兩件事:
1. 代號不存在會擋下來
Excel 裡填的客戶代號、廠商代號、品號、員工編號、部門代號等需要查主檔的欄位,匯入前會先確認代號真的存在。只要有一筆查不到,整批就不匯入,並列出問題所在:
匯入已中止,下列資料無法填入(請修正 Excel 後重新匯入): Excel 第 5 列「品號」:資料不存在(值:A0012X) Excel 第 9 列「部門代號」:資料不存在(值:ZZ)行為與手動在格子裡打錯代號被擋下來一致,也維持原本「全部成功才匯入、不會匯入一半」的規則。
空白、
MISC以及系統佔位符(如#I#)不做檢查,與手動輸入相同。2. 名稱、簡稱會自動帶出來
以往匯入後,品名、廠商簡稱、部門名稱這類「跟著代號帶出來」的欄位是空白的,得再逐列點一次才會出現。現在匯入完成時就會一併帶出,與手動輸入代號後離開格子的結果相同。
代號存在但主檔沒有對應名稱時,該欄留白,不會因此中止匯入。
3. 匯入的資料接在既有明細後面
以往匯入會從表格第一列開始覆寫,既有的明細列會被匯入的資料蓋掉。現在匯入的資料一律接在既有明細之後,原本的列不受影響。
影響範圍
- 一般明細表格的右鍵「從 Excel 匯入」。
- 總帳傳票(SLIY)等自備匯入功能的畫面不受影響,規則與原本完全相同。
- 少數會依單據交易別動態切換查詢對象的欄位,維持原本行為(不做代號檢查),名稱一樣會帶出。
使用者需要做什麼
不需要調整既有的 Excel 檔。若匯入時出現「資料不存在」,請依訊息指出的列號與欄位修正代號後重新匯入。
-
09-08 salema-cy-remove-other-amount ▸
朝陽出貨通知單移除「其他金額」欄
日期:2026-09-08
影響對象:朝陽(SALEMA_CY,出貨通知單)
變更內容
出貨通知單(朝陽版)明細表格移除「其他金額」欄。
原因
朝陽帳套的出貨通知單明細(
salede/vw_salede)本來就沒有「其他金額」這個欄位,朝陽版舊系統的畫面也沒有這一欄——它是禾久版才有的欄位。
2026-08-04 建立朝陽變體畫面時採「原樣複製禾久畫面」,這一欄跟著被複製過來,
結果是欄位在畫面上永遠空白,使用者填了也存不進去(上傳時會依實際資料表結構丟棄)。
使用者可見的差異
- 出貨通知單明細表格少一欄「其他金額」(原本永遠空白)。
- 金額計算不變:金額=數量 × 單價(原本朝陽的「其他金額」恆為 0,本來就沒有參與計算)。
- 禾久版出貨通知單完全不受影響,「其他金額」欄照舊。
備註
若使用者曾對這張表格按過右鍵「記憶格式」,第一次開啟時仍會套用舊版型;
版型內找不到的欄位會被略過,不影響其他欄位。
-
09-08 prodplanm-document-program ▸
2026-09-08 新增「生產計劃單」程式(新功能測試 Y-06),生產計劃可以修改了
使用者看得到的變動
新程式:生產計劃單(主選單 →「新功能測試」→ Y-06)
生產計劃查詢存下來的計劃單,過去只能查閱、載入、整張刪除,數字動不了。現在多一支「生產計劃單」程式,用一般單據的方式維護它:
- 新增:輸入查詢條件 → 按
客戶設定帶出客戶清單 → 按查詢算出訂單預示預估/生產計畫/使用量三張明細 → 微調數字 →存檔(系統配PP開頭的單號)。
- 修改:翻到任一張舊單,改上面的數值後存檔。
- 刪除:整張單連同四張明細一併刪除。
- 支援上一筆/下一筆、清單瀏覽、審核欄位。
可以改的欄位:客戶設定的預估起訖與百分比、訂單預示預估的訂單數量/預訂交期/單價、生產計畫的數量/日期/內外單位工時/備註。使用量(機種別) 整張唯讀(它是生產計畫 × BOM 展開的結果,一張單動輒數萬列);四張明細都不能手動增列或刪列。
修改狀態下
客戶設定/查詢兩顆鈕會變灰——重算等於整批換掉明細,要換一批資料請開一張新單。生產計劃查詢(M-20)維持原樣
即時查詢、金流預測分頁、存成生產計劃單、歷史單分頁全部照舊,兩支程式共用同一批資料與同一組 PP 單號。金流預測只在查詢那支,因為它是用「當下」的票據與帳款算的,不屬於某一張單的內容。
收付條件號/預收日(預付日)開始存進資料庫
這幾欄 2026-09-04 起就顯示在畫面上,但先前只是算給畫面看、沒有存檔,載入舊單時一片空白。現在會隨單存下來。
- 影響分頁:訂單預示及預估(收付條件號、預收日)、生產計畫(同)、使用量(機種別)(收付條件號、預付日)。
- 2026-09-08 之前存的舊單這幾欄仍是空白,屬正常;重新產生一張新單即可。
- 修改預訂交期/日期時,預收日不會自動重算,維持存檔當下的值。
需要做的事
- 資料庫要跑
sql/prodplanm-deploy-20260908.sql(加欄位+登錄新程式+補權限)再跑sql/prodplanm-move-to-subsystem-y-20260908.sql(掛到新功能測試 Y-06)。禾久庫已完成。
- 跑完要重新登入 ERP,選單是登入當下取得的。
- 權限沿用「生產計劃查詢」:原本看得到查詢的使用者,自動拿到生產計劃單的權限。
- 這是新功能,依慣例先放「新功能測試」子系統,穩定後再搬到 M.主管資訊。
已知限制
- 資料別(訂單/製通單)與預估百分比是產生資料時的條件,不隨單儲存,載入舊單時回到預設值。
- 朝陽帳套目前選單裡沒有生產計劃查詢,因此也還沒登錄生產計劃單。
- 新增:輸入查詢條件 → 按
-
09-08 print-nodata-sql-error ▸
2026-09-08 報表「無資料可列印」之後不再跳 SQL 錯誤訊息
症狀
在有列印頁的程式按
預覽/列印/Excel時,如果該報表在目前條件下查無資料,畫面會連續跳兩個訊息框:1.
無資料可列印!(正常,這是應該出現的提示)2.
Error Report Handle: SQL logic errorno such table: <報表資料表名>(不該出現,使用者會以為系統壞掉)實測環境:銷項發票 →
列印→ 選「三聯式發票、電子計算機發票」→預覽,該期別沒有 31 類發票時必現。原因
列印流程在資料匯出這一步,插件回報「沒有資料」時只顯示提示訊息,卻沒有中止流程,後面照樣去載入報表範本;但報表要讀的暫存資料表根本沒有建立,於是又跳出一個資料庫層的錯誤訊息。
修正
沒有資料時直接中止列印流程,只保留「無資料可列印!」一個提示。此問題影響所有走列印頁的報表(不限發票模組),修正後一併解除。
影響範圍
- 使用者可見行為:查無資料時少跳一個錯誤訊息框,其餘不變。
- 有資料時的列印/預覽/匯出行為完全不變。
-
09-08 invoice-transfer-nodata-and-report-gate ▸
2026-09-08 發票轉檔沒資料時不再跳系統錯誤;統一發票/折讓單報表改以資料表判定
一、轉檔沒資料時跳「系統錯誤 Cannot find table 0.」
症狀:在進項發票按
轉入(進貨單轉進項發票)、或在銷項退回按轉入(應收帳款轉銷貨退回及折讓),若該期別沒有可轉的資料,按儲存會跳出紅色的> 系統錯誤 程式:TKTURNR Cannot find table 0.
原因:查不到資料時程式沒有先擋下來,直接去取查詢結果的第一張資料表。
修正:改成正常提示「無資料!!!」。銷項發票的轉入(應收帳款轉統一發票)原本就是對的,不受影響。
二、統一發票與電子發票折讓單的報表清單以「帳套有沒有這些資料」判定
症狀:統一發票列印與電子發票折讓單列印兩頁,在某些環境下報表清單是空的,連
預覽/列印按鈕都不出現。原因:原本以公司簡稱字串判斷要不要登錄這幾張報表。只要公司簡稱與寫死的值不一致(例如更名、或另開一個同樣有發票資料的帳套),整組報表就會無聲消失。
修正:改成判斷該帳套是否建有存證發票/折讓單的資料表。沒有這些資料表的帳套(例如未使用存證發票功能者)行為不變,仍然看不到這幾張報表。
三、401 申報書/媒體申報檔存錯位置
症狀:401 申報書按
轉申報檔、媒體申報按轉檔/零稅率轉檔時,訊息顯示的路徑是C:\Temps401_12345678.tet——檔案被寫到 C 磁碟根目錄、而不是暫存資料夾裡面,檔名還黏著資料夾名稱。原因:組路徑時把資料夾與檔名直接相接,中間少了分隔符號。
修正:三處改用標準的路徑組法,現在一律寫進系統暫存目錄(預設
C:\Temps)下,訊息顯示的也是正確的完整路徑。原本誤存在 C 磁碟根目錄的舊檔案可自行刪除。影響範圍
- 一、二為錯誤處理與判定條件的修正,正常有資料的流程完全不變。
- 三只改檔案存放位置,申報檔的內容格式完全不變;已在報稅前取過檔的使用者,請改到
C:\Temps底下取新檔。
-
09-08 cy-userguide-chinese-and-register ▸
朝陽:操作引導欄名中文化並開通
日期:2026-09-08
影響對象:朝陽(USERGUIDE 操作引導)
變更內容
1. 朝陽的操作引導兩張資料表欄位名稱由英文改為中文(與禾久一致),共 30 個欄位。
2. 朝陽補上「操作引導」的單據登錄,這個功能原本在朝陽沒有登錄過。
原因
操作引導在朝陽是舊版英文欄位名稱,而程式讀的是中文欄位名稱,等於這個功能在朝陽從來讀不到任何資料;
單據登錄也一直缺一筆,功能等於沒開。禾久側早已是中文欄位、也有登錄,本次是把朝陽補齊到同一狀態。
使用者可見的差異
- 朝陽可以開始使用「操作引導」:在支援面板為各程式建立說明文件與附件。
- 原有的 1 筆舊資料保留,不受影響。
- 禾久不受任何影響。
部署
sql/cy-userguide-chinese-rename-20260908.sql(可重複執行)。本機朝陽模擬庫已執行並驗證通過;朝陽正式機尚未執行。
-
09-08 aproj-column-naming-unify ▸
專案資料:欄位名稱統一
日期:2026-09-08
影響對象:全部客戶(專案資料 APROJ)
變更內容
專案資料的兩個欄位改名,兩邊客戶統一成同一組名稱:
原本(禾久等) 改為 地點 專案地點 保留款比率 保留款比例 朝陽本來就是新名稱,不受影響。
原因
同一個欄位在不同客戶的資料庫裡叫不同名字,程式只認得其中一種,導致另一邊的畫面欄位讀不到值。
本次統一採用「專案地點/保留款比例」這組較清楚的名稱。
使用者可見的差異
- 專案資料畫面上的「地點」標籤改為「專案地點」。
- 兩張表原本都沒有資料,改名不影響任何既有資料。
部署
sql/aproj-rename-to-cy-naming-20260908.sql(每個帳套各跑一次,可重複執行)。資料庫與程式必須同時上線,只更新其中一邊會讓該欄位空白。
本機 7 個帳套庫已執行並驗證通過;正式機尚未執行。
-
09-07 visit-route-lab-shots ▸
2026-09-07 拜訪行程規劃:實機驗證與截圖、兩處畫面修正
使用者可見變動
- 行程規劃在 lab 示範環境實機走完整流程(定位、無法定位手動點選、上移、AI 建議與採納、回填、拜訪單回看),手冊與案例書補上 11 張實機截圖,案例書 PDF 重出。
- 修正:按「上移」「下移」時序號欄沒有跟著列移動(列換了、數字還是舊的)。
- 修正:AI 建議區塊的理由文字不換行、要左右捲動;改為自動換行並加高到 260px。
-
09-07 twork-moverec-viewkey ▸
2026-09-07 導覽(第一筆/最後一筆/上下一筆)表頭與明細對不上:TWORK_MOVEREC 修正
適用:所有帳套共用同一支導覽 SP。使用者 09-07 裁決禾久、朝陽正式機一起部署。
症狀
- TAG進貨單按「第一筆」,表頭是進貨單 RC2600001,明細卻是出入庫單 GD2600001 的(使用者 09-07 回報)。
- 同一根因在 TAG出入庫單按「最後一筆」也中;按「下一筆」跨過最後一筆時會出現「沒有表頭卻有別張單的明細」。
- 進貨單/出入庫單/出貨單三支程式共用同一張主表,其他帳套只是單號前置碼剛好排得開才沒被看到。
根因與修法
- 表頭從程式的主表 view(有單據別條件)取第一筆,但明細用來對應的主鍵是從共用主表(沒有單據別條件)另外取的,兩邊排序取到不同張單。
- 修正後明細主鍵一律從與表頭相同的來源取,PKID/定位(SEEK)分支也同源化,行為不變。
部署
- TAG 帳套:
sql/sh03a/sh03a-twork-moverec-viewkey-fix-20260907.sql(可重跑)。dev TAG 庫已跑,七種導覽情境比對表頭 pkid=明細 linkid 全部通過。
- 禾久/朝陽:
sql/twork-moverec-viewkey-fix-20260907.sql(通用版,SQL 2008 相容,每個 csa 帳套庫各跑一次,已修過會自動跳過)。dev 兩庫各跑兩次(第二次跳過)驗過,進貨單/出入庫單/出貨單 第一筆/最後一筆 表頭與明細相符。正式機由使用者執行。
-
09-07 tag-owner-dashboard ▸
2026-09-07 SH03A TAG:業主儀表板「TAG追蹤儀表板」放進公司儀表板
適用:SH03A TAG 專案帳套。其他帳套沒有這些卡片與儀表板,不受影響。
使用者可見變動
- TAG業主 子系統多一支「公司儀表板」(排最後)。開啟後選「C0001 TAG追蹤儀表板」,兩頁:
- 總覽:本期進貨標籤數、本期領用標籤數、在廠標籤庫存、工班在手標籤四顆數字;各倉標籤庫存、各水泥廠進貨數、各工班領用數、施工地址 Top10 四張圖。
- 趨勢與明細:每月進貨數、每月領用數折線;最近領用紀錄(日期、單號、工班、TAG ID、施工地址、掃描時間、GPS)與最近進貨標籤明細兩張表。
- 上方「期間」條件套用到進貨/領用類磚;庫存三張看的是現況不受期間影響。
- 每張圖點下去跳到 TAG進貨單/TAG出入庫單 的清單瀏覽帶條件。
- 資料照登入身分過濾:水泥廠主管若開同一張板,只看得到自己廠與底下工班。
- 挑卡視窗多「TAG追蹤」分類 12 張卡,可自組個人版。
資料庫
sql/sh03a/sh03a-tag-owner-dashboard-20260907.sql(由gen-tag-dashboard-sql.py從tag-dashboard-cards.json產生):查詢程序TWORK_QRY_TAGSTOCK(各倉標籤庫存+單位類型)與 log 庫登錄、12 張卡片、儀表板 C0001、選單搬移與業主權限。dev 已跑,驗收 8/8。
sh03a-tag-menu-roles-20260906.sql/sh03a-tag-menu-order-20260907.sql同步納入公司儀表板(T-10)。
順帶修正
- TAG進貨單「清單瀏覽」原本任何條件都會報「無法繫結多重部分識別碼」:08-30 新寫的進貨清單查詢程序把查詢包成子查詢,吃不下條件欄位自帶的表別名。已改成自動去掉別名,並補上 TAG ID/手持機兩欄(
sql/twork-bd-wrapped-prefix-fix-20260907.sql,同批修到出貨/採購/廠商報價三支)。禾久、朝陽正式機同樣有此問題,待裁決是否部署。
09-07 續:施工位置地圖
- 新磚型「地圖」(見
2026-09-07-dashboard-map-tile.md);總覽頁改放「施工位置地圖」,各廠進貨/各工班領用移到第二頁。
-
09-07 io-round2-invoice-l3-fixes ▸
2026-09-07 帳款/票據第二輪實測修正+發票管理靜態稽核修正
帳款/票據(I/O 模組)
- 費用申請(PAYAPPLY)加明細列後存檔失敗(訊息「An error occurred while saving the entity changes」):新增時程式把明細 pkid 顯式重編 1..20,與明細表格右鍵「新增數筆」交給資料庫產生的序號撞鍵。移除該段重編;明細 pkid 一律由系統產生。
- 預估資金表(BANKFCST)單號被覆寫:存檔時程式把單號改成「日期+帳戶代號」,新增時伺服器會蓋回流水號所以看不出來,但修改後假單號(例:
2026/12/31#01)直接落地,之後同日期再新增會撞唯一索引「資料重複」。移除覆寫;單號一律為系統依預估日期派的流水號(yyyyMMdd加三碼序號)。既有資料庫中單號含「/」的舊資料屬歷史污染,需另行清理。
- 手冊
O-Check/bankfcst.md原寫「單號=日期+帳戶代號、同日同帳戶會覆寫同一張」與實際不符,已更正。
發票管理(P 模組)
- 401申報書(TICK401)從選單消失:程式鍵未登錄於程式鍵清單,選單啟動時被「隱藏未實作程式」過濾器移除。補上程式鍵;同時把 401申報書 原本誤用的「申報資料轉檔(TUTAX)」程式鍵改回自己的鍵,兩支程式的權限、翻譯與表格版型記憶不再互相覆蓋。
- 存證折讓發票(TICKA_DISC):明細「品號」欄綁到不存在的屬性導致永遠空白且品名不自動帶出,改綁正確屬性;「全選」「取消全選」兩顆鈕命令名不一致成死鈕,已對齊。
- 進項發票/銷項發票/銷項退回/存證發票/存證折讓發票 五張明細表格補掛標準表格樣式,待刪列會顯示紅字提示(與其他模組一致)。
發票管理(實機資料輸入抓到的)
- 進項發票/銷項退回的新增彈窗下拉全空(公司代碼、憑證類別、類別、課稅別,新增筆數也不顯示):彈窗畫面改成 TsView 後仍用舊的
ElementName=Window綁定,綁不到任何元素。改綁View。
- 銷項發票/進項發票/銷項退回/存證折讓發票存檔即「The given key … was not present in the dictionary」:存檔類向框架索取明細集合時用了基底型別,程式登錄的是衍生型別,字典查不到。四支改用登錄的型別,存檔恢復正常。
- 彈窗式新增(進項/銷退/存證發票)關閉彈窗後多彈一個「系統錯誤」:主畫面的新增回呼以「失敗+空訊息」表示「不進新增模式」,框架卻把空訊息補成假的系統錯誤。框架改成有訊息才顯示;資料早已寫入,只是訊息誤導。
- 銷項退回彈窗「客戶」欄輸入客戶代號彈「資料不存在」:欄位掛的是廠商查詢樣式,後端本來就查客廠合一的檢視表,改成客廠查詢樣式。
- 存證折讓發票:明細驗證與折讓金額加總的條件寫反(只處理被標刪的空列,真資料列從不驗、金額恆 0),已對齊 VFP 的 ELSE 分支;明細「品號」欄改走
品號Binding(原本覆寫 mapped 屬性並在 setter 取 Context,資料物化時 Context 尚未注入,存檔與取消都會 NullReference);課稅別為空的列不再在算稅時炸掉。
- 同一期別/憑證類別的第二張進項或銷退發票存不進去(唯一索引重複)、401申報書與存證折讓查不到公司資料、客廠資料查詢恆空:程式向資料庫查詢時用的是程式端類別名稱(
Twork_inv_vw_*、Twork_sys_vw_codata、Twork_sys_vw_cusp),資料庫沒有這些物件(朝陽雖有前兩者但是英文欄名舊檢視表),派發器靜默回空,程式便把既有期別當成新單。改查實際資料表(tickr_m/tickr_d/ticks_d/ticksr_m/ticksr_d/codata)與vwseek_cusp。
框架(所有主檔程式)
- 存檔撞唯一索引時的訊息:原本原樣顯示派發器回傳的「NG ,2441 ,無法以唯一索引 'IX_bank_1' 在物件 'dbo.bank' 中插入重複的索引鍵資料列…」。現改為「資料重複,無法存檔:1103(追蹤號 2441)」,括號內是重複的鍵值,追蹤號可回查記錄庫。其他錯誤訊息維持原樣。
發票管理新增/補齊功能
- 存證作廢發票(TICKA_VOID,禾久):原本只有資料表與選單、程式未實作而被選單隱藏,現補齊主檔畫面(買方代號查詢自動帶統編/名稱/地址,賣方資料由公司主檔帶入,作廢日期預設現在時間,發票作業別 CAN,含核准文號),新增/修改/刪除全循環實機驗過。
- 零稅率主檔「轉入」、存證發票「轉應收」「轉出貨」「批量匯出」四個視窗:原為舊式獨立視窗,按下即「Exception has been thrown by the target of an invocation」;改為內嵌式視窗,四支都能正常開啟與離開。
發票管理報表(第一批 5 張)
- 零稅率主檔「營業人申報適用零稅率銷售額清單」(Tick3a)、進項發票「進項稅額憑證」「進項退貨憑證」(Tickra/Tickrb,列印條件新增 8 種憑證類別選項)、銷項退回「銷項退回憑證」(Ticksr,新增列印條件頁)、留抵稅額「留抵稅額表」(Tickmin,瀏覽列印)。原本這些程式的列印鈕會亮但沒有任何報表可選;零稅率主檔與進項發票的舊列印頁原為無法運作的殘留頁,已改造成可用。
- 第二批:銷項發票「三聯式統一發票明細表」「二聯式統一發票明細表」「三聯式收銀機統一發票明細表」「發票明細表」(Tick1a/Tick2a/Tick1b/Ticksdtl,新增列印條件頁:期別+4 種報表選擇;前三張為稅局固定格位套印,每 50 張一頁)。
- 第三批:申報書備註「申報書備註表」(Tother,瀏覽列印)、401申報書「營業人銷售額與稅額申報書(401)」(Tick401a,查詢後可直接列印整頁式申報書,只做 A4)。
- 第四批(禾久):銷貨發票(存證發票)新增列印條件頁,五張報表「統一發票」(套印,明細超過 10 筆自動併成合併品名一列)、「銷項發票明細表」(依客戶+日期區間)、「銷項發票品項明細表」(超過 10 筆的發票)、「電子發票證明聯」及「續頁」。統一發票的紙張尺寸為推算值(210×121 mm 零邊界),實機第一次列印請先對位。
- 第五批(禾久):存證折讓發票新增列印條件頁(起迄折讓單號),報表「營業人銷貨退回、進貨退出或折讓證明單」(Ticka_disc,A5 橫,每張一頁、5 格位)。至此發票管理 VFP 現行 17 張報表全部移植完成。
-
09-07 dashboard-map-tile ▸
2026-09-07 自訂儀表板新增「地圖」磚型(GPS 落點)
適用:所有帳套的自訂儀表板/儀表板設計;SH03A TAG 的「TAG追蹤儀表板」總覽頁已放一張「施工位置地圖」。
使用者可見變動
- 儀表板設計的磚型別多一種「地圖」:指定資料集裡的緯度欄、經度欄,選擇性指定標籤欄(標記標題)與顯示欄位(點標記的氣泡內容)。每一列資料一個標記,沒有座標(空白、0,0、超出範圍)的列不畫,磚上會註明略過幾列。
- 地圖底圖與拜訪行程規劃相同(免金鑰的開放圖磚,可用帳套參數
GEO_TILE_STYLE換樣式),會自動縮放到涵蓋所有標記;點標記看氣泡,氣泡裡「看明細」跳該程式的清單瀏覽帶標籤值當條件。
- 需要連網才有底圖;離線或列印(PDF)時該磚改顯示標記清單(標籤+座標)。匯出 Excel/PPT 時地圖磚匯出成一點一列的表格。
- TAG追蹤儀表板:總覽頁下半改為「施工位置地圖」(左)+「施工地址 Top10」(右);各廠進貨、各工班領用兩張柱狀移到第二頁與趨勢圖同列。
程式
LogicBll/M.EIS/Dashboard/:DashboardDefinition(型別 地圖、磚定義 緯度欄/經度欄/標籤欄)、DashboardRenderModel(MapData/MapPoint)、DashboardAggregator.Map、DashboardQueryEngine(地圖分支、圖磚樣式讀GeoSettingsLoader)、DashboardHtmlWriter(地圖內容、MapLibre 資源)、DashboardHtmlCss、DashboardHtmlScript.MapInit。
ViewModel/A.SystemData/DashboardcfgItems.cs/DashboardcfgViewModel.cs(驗證)、TsERP/A.SystemData/儀表板設計.xaml(第 9 列三個欄位)、Common/Lang/Xaml/Dashboardcfg.json。
- 測試:
LogicBllTests/Dashboard/DashboardMapTileTests.cs。
- TAG 卡片
GTRLIMA_TAG_施工位置地圖(sql/sh03a/tag-dashboard-cards.json)與sh03a-tag-owner-dashboard-20260907.sql重產。
同日:儀表板換螢幕不再重排(使用者「儀表板照 1920 設計」)
- 原本畫面列數依視窗高度算,跟設計列數不同就把整張板重新流排(2560 螢幕上四顆 KPI 會疊成一直排、磚亂跑)。
- 改為:列數只會比設計多、不會少,磚永遠停在設計器/存檔的位置;大螢幕多出來的列留空,小螢幕列數不夠就在格區內上下捲。
- 拖曳改成「放哪裡就是哪裡」(使用者同日裁決):列數固定的板拖完、改大小後不再自動左吸/上吸壓實,磚停在放下的格子;壓到同尺寸的一顆就兩顆互換,壓到不同尺寸就把對方往右推;拖曳途中經過的磚不會被順手推走(每一步從拖曳前的狀態算)。存檔端同步不再壓實。列數 0 的舊版儀表板維持原本「往下推+上吸」。
同日:鑽取回來全部「載入中」修正
- 從任何磚鑽取到清單瀏覽再回到儀表板,離開超過幾秒時所有磚都顯示「載入中」。原因是逐步顯示模式下畫面骨架與磚內容分開送,回來時只重灌了骨架。現在回到頁面會自動把版面與全部磚補回,不重新查詢。
-
09-06 visitroute-tgos-attribution ▸
2026-09-06 拜訪行程規劃:定位服務標示
- 行程規劃視窗的地圖下方新增「定位服務:內政部全國門牌地址定位服務(TGOS)」連結,點擊以系統瀏覽器開啟 https://www.tgos.tw。地圖右下角的版權列同步加上 TGOS 連結。
- 這是介接內政部定位服務的使用規定要求(互惠條款),不論目前設定的定位供應商為何都會顯示。
-
09-06 visit-route-ui-speed ▸
2026-09-06 拜訪行程規劃:地址定位補強、上移下移即時、狀態列顯示進度
使用者可見變動
- 地址定位查得到了:客戶主檔地址前面帶郵遞區號(「231新北市…」)或含「巷/弄」時,以前會顯示「查不到這個地址」。現在自動去掉郵遞區號與括號備註,查不到時逐階退到「巷」「路/段」層級再查。免費定位服務只有路名精度,門牌精度要等內政部 TGOS 服務接上。
- 上移/下移立刻反應:按下去列馬上交換、序號重編、選取跟著走;各段里程與過路費在狀態列顯示「順序已變更,重新計算中…」後幾秒內更新。連按多次只重算一次。
- 狀態列顯示進度:第一次開窗要逐站定位(外部服務限每秒一次),狀態列會顯示「定位中 3/7:客戶名」「計算路線中(7 站)…」,不再只有「計算中…」。
- 拜訪日期、業務員、總里程、總車程、總國道里程、過路費估算改為唯讀輸入框樣式(可選取複製)。
- 「重新計算」「上移」「下移」三顆按鈕拿掉圖示,只留文字。
-
09-06 visit-route-schedule ▸
2026-09-06 拜訪行程規劃:每站預計到達/離開時程
使用者可見變動
- 行程表新增「預計到達」「預計離開」兩欄;視窗上方新增「出發時間」欄(預設 08:30,可改後按重新計算)。
- 時程由程式推算,不是 AI 給的:到達=上一站離開+該段車程;離開=到達與該站起始時間取較晚者再加停留;停留=拜訪單有填截止時間就停到截止時間,沒填用預設 60 分鐘。終點只有到達。
- 採納 AI 建議順序時,AI 的「建議出發時間」自動帶入出發時間欄,時程隨重算更新。
- 新增系統參數(
_prgpar,都可不設):GEO_DEPART_TIME預設出發時間(HH:mm,預設 08:30)、GEO_STAY_MINUTES預設停留分鐘(預設 60)。
- 時程超過 24:00 會直接顯示 25:10 這類數字,不繞回隔天,讓人看得出當天排不完。
-
09-06 visit-query-window ▸
2026-09-06 拜訪查詢視窗調整
- 拜訪查詢視窗尺寸:從固定 1200×560 改為跟著主視窗(長寬各減 100),四個分頁的表格不再擠在小視窗裡。
- 查詢鈕文字:共用查詢鈕在查不到翻譯時原本顯示英文「Query」,改為顯示「查詢」(全系統共用控件,各查詢畫面一併受益)。
- 表格右鍵「全部勾選/取消勾選」:以前只在單據新增/修改狀態才能按,查詢類視窗(如拜訪查詢的「選取」欄)永遠灰掉;現在只要該格的勾選框本身可以點,右鍵全勾/全取消就可以用。
- 共用按鈕英文殘留一併清掉:離開鈕、儲存/確認/取消樣式、底部操作列的儲存/取消/離開/列印,翻譯查不到時原本顯示 Exit/Save/Confirm/Cancel/Print,全部改為中文;確認鈕的翻譯鍵也由英文 Confirm 改為「確認」。
- 下拉空白項顯示成「:」:代號與說明都空白的下拉項目(預設空白選項)原本會顯示一個冒號,現在顯示空白;語言、分錄範本等自組顯示文字的下拉一併修正。
-
09-06 tag-stock-detail ▸
2026-09-06 SH03A TAG:G倉庫表新增「TAG明細」子查詢
適用:SH03A TAG 專案帳套(
_prgpar參數MENU_STYLE=TAG)。其他帳套看不到這顆按鈕、雙擊也沒有動作,行為不變。使用者可見變動
- G倉庫表主檔區「數量查詢」右邊多一顆 TAG明細。按下開彈窗,列出這座倉庫(工班)進出過的每一支 TAG:交易日期、單據(進貨/出入庫)、單號、交易事項、方向(轉入/轉出)、轉入/轉出倉儲、品號、批號、數量、TAG ID、手持機、掃描時間、GPS 緯度/經度、施工地址、交易部門與部門名稱。
- 先按「數量查詢」再在右側數量表格點選一列(或直接雙擊該列),TAG明細會帶入那一列的倉儲與品號,只看那個品號的 TAG。
- 彈窗上方可改 品號、填 TAG ID(包含)、施工地址(包含)再按查詢縮小範圍;右側顯示筆數。
- 資料照登入身分過濾:工班只看得到自己的列,水泥廠看得到自己與底下工班,業主看全部(與 RLS 規則相同)。
程式
LogicBll/C.GeneralAffair/Gsplace/GsplaceBll.cs:GetTagDetail/BuildTagDetailCondition;TagStockDetailPoco.cs。
ViewModel/C.GeneralAffair/TagStockDetailViewModel.cs(彈窗)、GsplaceViewModel.cs(IsTagSite/SelectedQuantity/TagDetailCommand/OpenTagDetail)。
TsERP/C.GeneralAffair/TagStockDetail.xaml、Gsplace.xaml(按鈕、數量表格SelectedItem+雙擊)、App.xamlDataTemplate。
Common/Lang/Xaml/Gsplace.json(TAG明細/TAG ID/施工地址/查詢/返回/筆數)、Gsplace_tag.json(彈窗表格欄名)。
資料庫
sql/sh03a/sh03a-tag-stock-detail-qry-20260906.sql:TAG 庫TWORK_QRY_TAGSTK(@倉儲代號, @查詢條件)+log 庫proc_param。dev 已跑,驗收 4/4。
-
09-06 io-module-fulltest-fixes ▸
2026-09-06 帳款管理/銀行票據全測修正
Hyper-V lab 對 I.帳款管理、O.銀行票據 兩模組做「全按鈕掃描」與「資料輸入」實機測試後修正的四件事。
使用者可見的變動
1. 瀏覽列印頁沒查詢就按 Excel 不再跳「系統錯誤」(銀行帳戶/應收票據/應付票據/預估資金表/廠商帳戶表等主檔程式)。原本會出現 NullReference 的系統錯誤視窗,現在與「預覽」一致,顯示「沒資料」。
2. 廠商帳戶表按「新增」不再立刻彈「資料不存在」。主鍵欄(廠商代號)掛了廠商查詢樣式,新增列的預設值
+++會被拿去做存在檢查;現在+++視為佔位值不檢查。應收票據等程式「複製」時的同一類提示也一併消失。3. 財務單明細「交易別」下拉可以編輯了。原本一進儲存格編輯就跳「無法將 ComboBoxItem 樣式套用到 RadComboBoxItem」的系統錯誤,連帶品號、品名等欄位彈「Textbox沒有設定」。
4. 客戶應收查詢/廠商應付查詢的「年度統計表」月份表頭恢復顯示月份(08月、09月……),不再停在 C01~C12。
6. 應付帳款/應收帳款/費用申請/收款單/付款單/費用科目表的明細表格補上 DataManager 綁定(10 張表格),右鍵「新增列」與「從 Excel 匯入」走框架正規路徑,與財務傳票單一致。
5. 付款單/收款單「轉傳票」在合併轉參數(2035)未設為 Y 的帳套不再跳「找不到預存程序」。付款單一律走合併轉程序(與舊版一致);收款單只有參數明確為 N 時才走分開轉程序,參數未設視同合併轉。朝陽模擬帳套實測抓到。
改動檔案
ViewModel/Browse/ErpBrowseBaseViewModel.cs:GenerateExcel對未查詢(DataView 為 null)與 0 筆的情況顯示「沒資料」。
TsControl/ControlValidation/TsSearchRule.cs:IsPlaceholder把新增哨兵+++視為佔位值。
TsERP/O.CAandCL/Ftrlima.xaml:交易別下拉欄拿掉不相容的ItemContainerStyle。
TsControl/Localization/HeaderLocalization.cs:表頭有 binding 的欄跳過翻譯,保留程式自己給的動態表頭。
TsERP/I.ARAP/Paymnt.xaml、Receive.xaml、Payapply.xaml、Rsheet.xaml(3 張)、Psheet.xaml(3 張)、Grpmaccl.xaml:明細TsRadGridView補DataManager="{Binding DetailData / Detail1Data / Detail2Data}"。
LogicBll/I.ARAP/RpshtToSliyBll.cs、TsErp.Common.Core/DataBaseObjectEnum/Procedure.cs:轉傳票程序選擇對齊舊版(付款單一律合併轉;收款單 2035=N 才走分開轉,並改用實際存在的程序名)。
測試
- 禾久 29 支、朝陽 26 支全按鈕掃描(導覽/瀏覽/查詢/歷程/工作流程/列印預覽與 Excel/複製/修改/新增/其他功能鈕/說明)零崩潰。
- 16 支主檔程式新增→存檔→修改→第二筆→刪除,測試資料留在模擬庫(單號日期 20260906)。
- 修正後在 lab VM 重驗:Excel 改顯示沒資料、廠商帳戶表新增無提示、財務單交易別可選、月份表頭正常。
-
09-05 tag-rls-application-name ▸
2026-09-05 SH03A TAG:資料列權限(RLS)掛上單據表;登入身分帶進資料庫連線
適用:SH03A TAG 專案。其他客戶帳套只有連線字串多了
Application Name(顯示在資料庫連線監看中),行為不變。使用者可見變動(TAG 專案)
- 看得到的單據依身分過濾:業主看全部;水泥廠看自己倉的所有進貨與領用單、以及底下工班的庫存;工班只看交易部門是自己的領用單與自己倉的庫存。TAG進貨單、TAG出入庫單、G倉庫表數量查詢、清單瀏覽全部套用。
- 跨部門寫入被擋:直接對資料庫寫別人部門的單會被拒絕;程式內存檔照常(工班存自己的領用單、批號回查與庫存扣轉都正常)。
- 2026-09-05 之前的舊版程式連 TAG 庫會看不到任何單據(沒帶身分),要更新到含本次改動的版本。
程式
- 連線字串附
Application Name=TsERP|<登入代號>(DataBaseParameter.SessionUser,登入成功時由UserBll設定)。決策見 ADR 0149。
資料庫
sql/sh03a/sh03a-tag-rls-docs-20260905.sql:述詞函數 4 支、原則掛trgama/trgade/ginvstk、STATE=ON;log 庫DARB_LOG包TAG_RLS_BYPASS。冪等。
驗證
- 資料庫端 11 種身分矩陣、lab VM 工班帳號登入 ERP 端到端(詳見
sql/sh03a/README.mdRLS 節與 ADR 0149)。
-
09-05 tag-gps-columns ▸
2026-09-05 TAG 進貨單/出入庫單:GPS、施工地址、掃描時間各自落欄;SH03A 組織種子
適用:SH03A TAG 專案(
darbtagcsa1)。其他客戶帳套畫面與資料庫零變動。使用者可見變動
- TAG進貨單(C-071)/TAG出入庫單(C-081)明細:手持機 LOG 匯入後,原本擠在「備註」裡的「掃描時間 GPS 地址」拆成四個獨立欄位:
掃描時間、GPS緯度、GPS經度、施工地址,排在「手持機」之後。備註只剩解析不出來的原始字串(例如手持機沒定位到的 GPS 文字),正常情況為空。
- 備註欄寬由 420 收到 200。
- 瀏覽清單(清單瀏覽)同步看得到四欄;09-06 起查詢條件也能選掃描時間、GPS、施工地址(TAG ID 原本就可選)。
資料庫
sql/sh03a/sh03a-tag-patch-trgade-gps-20260905.sql:trgade加GPS緯度 DECIMAL(9,6)、GPS經度 DECIMAL(9,6)、施工地址 NVARCHAR(200)、掃描時間 DATETIME(皆可空);vw_gtrrade、DARB_BD_GTRLIST、TWORK_BD_GTRRADE補回四欄。冪等;跑完gen-schema-sync追 nogi 之後要再跑一次。
sql/sh03a/sh03a-tag-org-seed-20260905.sql:業主 1+水泥廠 5(A1~A5)+每廠 3 工班(2 自有+1 外包,dept.製程別='外包'),每單位一個倉庫/儲位與測試帳號(密碼同 CMSA)。
程式
- 共用
Twork_gen_vw_gtrsadeModel/Twork_gen_vw_gtrsadeSource多四個可空屬性(ADR-0050 union Source 做法,同「時間/時間單位」CY 專屬欄先例)。其他帳套載入留空、上傳時被取交集丟棄;本機快取把 NULL 補成 0/1900-01-01 的哨兵值在 Source getter 還原成 null,不會被寫回。
TagLogParser新增ParseGps(拆緯經度,0,0 與超出範圍視為無效)與ParseScannedAt。單元測試LogicBllTests/C.GeneralAffair/TagLogParserTests.cs。
未驗
- runtime 未開窗驗(lab VM 的
tag-e2e.ps1S/T/L 段待跑)。
- TAG進貨單(C-071)/TAG出入庫單(C-081)明細:手持機 LOG 匯入後,原本擠在「備註」裡的「掃描時間 GPS 地址」拆成四個獨立欄位:
-
09-05 seek-textbox-uppercase-by-param ▸
2026-09-05 定位搜尋欄自動轉大寫改由系統參數 22 控制
- 行為:定位搜尋欄(上一筆/下一筆旁的代號定位欄)輸入英文原本寫死一律轉大寫;現改成與主鍵欄一致,依系統程式參數
22(代號是否區分大小寫)決定——設Y不轉換、其餘一律轉大寫。既有帳套參數 22 多為未設定或非 Y,行為不變。
- 手冊:基本畫面介紹「其他小規則」補參數說明;系統程式參數頁的「被全系統取用」表補
22一列;共用控制項首頁欄位標籤節補主鍵欄轉大寫規則。
- 行為:定位搜尋欄(上一筆/下一筆旁的代號定位欄)輸入英文原本寫死一律轉大寫;現改成與主鍵欄一致,依系統程式參數
-
09-05 license-heartbeat ▸
2026-09-05 中央授權檢查(登入/排程/自動化)
摘要
TsERP 登入成功後會向中央伺服器確認該公司的授權狀態與到期日;排程服務與自動化任務執行前也會確認。授權逾期超過寬限期、被暫停,或本機尚未設定授權金鑰時,無法登入。
變更
- 登入後多一次授權查詢(逾時 10 秒),連不上中央時改用本機上一次的授權紀錄,因此正常客戶離線也不受影響。
- 到期前 30 天起,登入後提示剩餘天數;逾期後 60 天寬限期內仍可使用並提示;超過寬限期擋登入。
- 授權預設為滾動模式:客戶端每次連上中央,到期日自動延到 90 天後;只有被中央改為暫停時才會擋。按年授權的客戶可改為固定到期日模式。
- 排程服務的
--update子命令不受授權限制,其餘子命令與每輪排程受限制。
Breaking Changes
- 每台客戶端必須讀得到 API 金鑰,否則更新後無法登入。金鑰二擇一設定,發版前逐家確認:
- 該機的
%ProgramData%\TsERP\appsettings.local.json的ExternalDataApi:ApiKey(單機測試/臨時覆寫用,優先採用);- 或該帳套
_prgpar的LICENSE_APIKEY(項目 90101)——一個帳套設一次,全公司的客戶端都讀得到,幾百台不必逐台改檔。Migration Notes
1. 中央庫跑
sql/license-central-schema-20260905.sql(建表、SP、授權給 YYAPI、種子既有客戶一年)。2. Function App YYAPI 新增設定
LICENSE_SIGNING_KEY,並 push TSAPI master 部署新端點。3. 逐家設定金鑰,再發 ERP 版:在客戶的每個帳套庫(
darb<客戶>csa1、csa2…)跑sql/prgpar-license-apikey-20260905.sql(腳本最上方先填入該客戶的金鑰;朝陽的_prgpar.參數只有 30 字,腳本會自動加寬到 200)。少數需要用別把金鑰的機器,另外在該機的appsettings.local.json填ExternalDataApi:ApiKey(本機優先)。4. 停用某客戶:改
extdata.api_client_license的狀態為suspended;恢復改回active(滾動模式下下次心跳自動展期)。按年授權改模式='fixed'並填到期日。範例語句在腳本第 6 節。 -
09-05 d-grid-datamanager-and-testpanel-date ▸
2026-09-05 工程資料明細表格「新增列」修復+測試面板日期欄修正
使用者可見變動
- 工程代號表/BOM表/模具資料表(含朝陽 BOM 變體)的明細表格:右鍵「新增列」原本沒有反應(框架在表格未綁資料管理器時無聲跳過),現已補綁,可正常新增明細列。
- 測試控制面板(管理員功能):日期欄改依控件身分產生測試日期,不再對字串型日期欄填入文字造成「請輸入正確的日期格式」。
影響檔案
TsERP/D.Bom/Procnos.xaml、Bom.xaml、Mold.xaml、Bom_cy.xaml:明細TsRadGridView補DataManager="{Binding DetailData…}"(8 張)。
TsERP/TestAutomation/TestControlPanelWindow.xaml.cs:GenerateValue加forceDate(主檔TsDateTextBoxV2/grid 日期欄)。
驗證
- 禾久 lab VM 測試面板實跑:工程代號表 2 張、BOM 表 2 張、模具 2 張明細 grid 皆「新增列 20→40」並填值成功;庫存主檔/模具資料表日期欄由假失敗轉為成功。
- 朝陽變體
Bom_cy只驗建置(朝陽 lab 的測試選單需 ADMIN 帳號,待處理)。
-
09-05 controls-color-legend ▸
2026-09-05 手冊:資料表格與欄位標籤的顏色說明
- 資料表格頁新增「顏色代表什麼」一節:欄位標題灰色=不可編輯;資料列左側紅色指示條=待刪除、深灰=不可編輯;整列淡綠底=選取中、整列紅底=檢核未通過。
- 共用控制項首頁新增「欄位標籤的顏色」一節:紅=必填、藍=主鍵、灰=系統產生、深綠=唯讀、黑=一般,附「你該怎麼做」欄。
- 兩頁互相連結;補拍截圖三張登記在各頁「需補截圖清單」。
-
09-05 casebook-numbering ▸
2026-09-05 案例書:每篇加「章-序」編號,新案例接在章末
- 24 篇案例全部加上「章-序」編號(例:
2-5 誰看得到誰的資料,用一張關係表講清楚),同時出現在左側導覽、各篇標題、首頁卡片與 PDF 目錄/內頁,四處一致。
- 編號規則:新案例一律接在該章最後、拿下一個序號,既有編號不重排——序號越大越新,看編號就分得出哪些是後來加的。
- 依此規則把〈自動化與流程〉章內兩篇後加的案例移到章末:
2-5 誰看得到誰的資料(08-14 加)、2-6 主管派拜訪任務(09-03 加)。
- 修正〈誰看得到誰的資料〉一篇原本漏掛在導覽(左側看不到、PDF 也沒收進去)。
- 首頁卡片編號改由各卡片明寫(原為 CSS 自動計數),與導覽順序不會再各走各的。
- PDF 重新產出(
tools/case-book-pdf/build.py改為章-序編號)。
- 24 篇案例全部加上「章-序」編號(例:
-
09-04 testpanel-grid-autoadd-and-zero-db-gate ▸
2026-09-04 測試控制面板:明細表格自動新增列填值;零號資料庫閘門改回只有零號庫能清資料
零號資料庫:只有零號庫可以清掉 SQL 資料(使用者裁決)
- 8 月 26 日為了讓
darbnogicsa1(禾久開發庫)也能跑三方對照,把它加進了TestAutomation:ZeroDatabases,等於同時開放「全部執行」對它清表/匯入。今天改回:設定檔只留darbnogicsa5、darbdemocsa1兩個零號庫。
- 閘門多一道硬性規則:
SourceDatabase(1 號庫、匯入樣本的來源)就算被列進零號庫清單也一律不通過,理由寫成「是 1 號庫(樣本來源),不得當零號庫清資料」。以後手改設定檔也開不回去。
- 不受影響的功能:「掃描欄位」「建立對照」「前置作業報告」「模擬輸入」「完整循環」都不走這道閘門,在任何帳套庫照常可用;只有「全部執行」(含步驟 1 清表、步驟 9 匯入)被擋。
- 同日追加(使用者裁決「一定要避免 darbnogicsa1~5 被 TRUNCATE 這種危險指令」):零號庫改成命名鐵律——只有庫名以
csa0結尾(darb<客戶>csa0)的庫才算零號庫。darbnogicsa1~csa5、csa_zt、加日期的備份庫、darbdemocsa1不論設定檔怎麼寫都一律禁止清表/匯入;設定檔ZeroDatabases只能在 csa0 之內再縮小,現在只列darbnogicsa0。
- 兩層都擋:閘門判定(「全部執行」按鈕)擋一次;真正送 SQL 的清表/匯入方法自己再查一次庫名,不合規直接丟例外、連線都不開。
- 目前伺服器上還沒有
darbnogicsa0,所以「全部執行」在任何環境都會被擋,直到建好零號庫(從 csa1 還原一份、加對應的 log 庫與登入環境)。
明細表格(RadGridView)要能自動新增值
- 以前掃描只認主檔區的輸入控件,單據下方的明細表格完全不在欄位清單裡,模擬輸入與完整循環從來不會碰明細。
- 現在掃描會把每張明細表格的可編輯欄逐欄列進欄位清單:欄位名稱顯示為「表格名稱.欄位」(表格沒有 x:Name 時用來源類別名),控件型別顯示
TsRadGridView欄,DB 欄與長度看該欄綁的來源屬性(品號Binding這類前端包裝屬性會對到真欄位);長度以零號庫的子表結構為準(多張子表都有同名欄時不猜)。
- 模擬輸入時,同一輪第一次碰到某張表格就自動新增一列(走的是表格自己「新增列」按鈕那條路,一次加一批列、測試值填第一列),之後該表格的各欄都寫進那一列;每輪重跑會再新增新的一列。
- 填值後回讀來源屬性比對,型別轉不過、setter 拒收、來源值沒變都如實記失敗;非增刪修模式下明細欄預設「略過」,表格關閉新增(
CanAddNewRecords/CanUserInsertRows關閉、非一般型、沒綁DataManager)會在清單標「不可新增列」並在 log 說明。
- 完整循環:新增階段會連明細一起填;「修改」階段仍只改主檔的 3 個字串欄(明細不再加列)。規格自動測試步驟 4(5) 的結果多一段「子表 xxx=N 筆」佐證明細真的存進去。
- 已知限制:明細填值不經表格的儲存格編輯器,欄位的離開儲存格連動(帶品名、算金額)不會觸發,交給存檔驗證;主檔逐欄核對仍只對主表。
- 實機驗證(2026-09-04,Hyper-V lab VM LAB-NOGI-01、禾久庫、G 進貨單):掃描列出
detailDataGrid22 欄+detail1DataGrid10 欄;新增後模擬輸入 log「新增列:detailDataGrid 明細 20→40 列」「新增列:detail1DataGrid 明細 0→20 列」,明細 32 欄全部填值成功、0 失敗(主檔+明細共 47 欄);畫面上明細第 0021 列與費用表第一列看得到填入的值;按取消可正常離開編輯。觀察到費用表的幣別/匯率被程式自己的連動改回 TWD/1.0000,這是程式行為不是治具問題。
- 8 月 26 日為了讓
-
09-04 tag-issue-gtrlima-tag ▸
---
title: TAG出入庫單(工班領用)與總務進貨/出入庫單畫面調整
date: 2026-09-04
---
2026-09-04 TAG出入庫單(工班領用)與總務進貨/出入庫單畫面調整
新功能
- TAG出入庫單(C-081,GTRLIMA_TAG):SH03A 水泥廠 TAG 專案的工班領用作業。變體自 C-08 G出入庫單,走 GD 總務調撥單:每個工班在 G倉庫表建成一個倉庫/儲位,匯入手持機 LOG 後每支 TAG 一列(品號 TAG01、數量 1、轉出倉儲=單頭倉庫、轉入倉儲=工班),單頭交易部門=工班;一張單只對一個工班。存檔時批號依 TAG ID 對回進貨批,倉庫該批減、工班倉同批加。只在 TAG 庫登錄(
sql/sh03a/sh03a-gtrlima-tag-register-20260904.sql+觸發器補丁sh03a-tag-patch-trgade-outbound-lot-20260904.sql)。
使用者可見變動(全帳套)
- 總務單據統一:G進貨單/TAG進貨單/G出入庫單/TAG出入庫單/G出貨單 倉單號欄 150、單號欄 120、倉庫欄 90、「前綴」/「前置碼」標籤改「單別」且下拉加寬(146);G申請單「序號前置碼」標籤同改「單別」;G出入庫單/TAG出入庫單/G出貨單/G暫收單/G需求單 畫面拿掉「公司代碼」欄(值仍由新增預設 1 寫入,資料不變)。
- G出入庫單 新增預設單別 GD 總務調撥單、G進貨單/TAG進貨單 新增預設單別 RC 總務進貨單——只在該帳套交易事項表真的有該碼時才預設,沒有就維持空白讓使用者自選。
- G倉庫表(C-11)/倉庫表(H):「數量查詢」按鈕改靠左。
- G出入庫單/TAG出入庫單 明細「交易別碼」改成下拉選單(還原 VFP grid 的 sqlcombo):清單依單頭單別在交易事項表的「交易別選項」決定(例:GD 總務調撥單→SS;M1 車輛保養→M1~M5),單別改變時清單跟著換;選項空白時退預設交易別,都空白才列全部。舊單若有不在選項內的交易別碼仍會顯示。
- G出入庫單/TAG出入庫單 倉單號欄寬改成與 TAG進貨單相同(150)。
修正
- G出入庫單/TAG出入庫單 新增存檔後找不到自己(上下一筆顯示沒有資料):新增時漏設單據別,存成空白被檢視表濾掉,已補預設「2」。
- 進出庫單「新增」後下方面板變空白:程式切到「動態查詢」頁籤,但各帳套沒設定 MoverecProcedure 導致該頁籤隱藏。現在依原設計接通:上下一筆時一併回傳本單品號的各倉儲/批號現有數量,「庫存查詢」頁籤顯示(依明細選到的品號過濾,新增時改品號會即時查),並提供「挑選」把倉儲與批號帶回明細。適用 G出入庫單/TAG出入庫單/G出貨單/G進貨單/TAG進貨單,以及庫存模組的領退料、生產入庫、進貨、出貨、委外五支。需部署
sql/stock-query-moverec-20260904.sql(兩支新 SP、_sheetno 設定、TWORK_MOVEREC 移除多餘的查庫存尾段、log 庫登錄)。
- 代號欄的搜尋視窗(例:轉入倉儲查倉儲)文字發糊:另開的彈窗沒有套主視窗的文字渲染設定,改在彈窗基底統一設定,所有搜尋/選取類彈窗一起變清晰。
- TAG進貨單/TAG出入庫單 匯入超過 20 支時,追加列的序號位數與框架預生列不一致(6 位 vs 4 位)導致排序錯亂,改為沿用程式的序號位數。
備註
- TAG 庫倉庫的「批號管制」不可設「是」:批號由存檔觸發器回填,設「是」會在存檔前被擋。
- TAG出入庫單(C-081,GTRLIMA_TAG):SH03A 水泥廠 TAG 專案的工班領用作業。變體自 C-08 G出入庫單,走 GD 總務調撥單:每個工班在 G倉庫表建成一個倉庫/儲位,匯入手持機 LOG 後每支 TAG 一列(品號 TAG01、數量 1、轉出倉儲=單頭倉庫、轉入倉儲=工班),單頭交易部門=工班;一張單只對一個工班。存檔時批號依 TAG ID 對回進貨批,倉庫該批減、工班倉同批加。只在 TAG 庫登錄(
-
09-04 prodplan-payterm-columns ▸
2026-09-04 生產計劃查詢:明細列加「收付條件號」與「預收日/預付日」
使用者可見變動
- 訂單、預示及預估 分頁加兩欄:收付條件號、預收日(放在「單價」之前)。
- 收付條件號:訂單與預估列取訂單單頭的收付條件(單頭沒設才退回客戶主檔);預示列取客戶主檔。
- 預收日:依收付條件+帳款起始日+預訂交期推算出的到期日。
- 生產計畫 分頁加兩欄:收付條件號(客戶主檔)、預收日(基準日=該列日期)。
- 使用量(機種別) 分頁加兩欄:收付條件號(廠商主檔)、預付日(基準日=該列日期)。
- 條件查不到、算不出日期或該列沒有基準日時,欄位留白。
- 金流預測分頁的「計劃預測」層改為沿用明細列上的預收日/預付日(同一個到期日口徑,數字不變;差別在於現在畫面上追得到來源)。列上留白的才照舊退回以預訂交期/需求日期當現金日,並在備註標「(無條件設定)」。
- 載入歷史單時,這三欄會用當下的收付條件重新算一次填回畫面(不隨單存檔)。金流預測分頁維持原規則:載入歷史單不重算、清空並顯示提示。
部署
- 禾久:
sql/prodplan-payterm-20260904-nogi.sql
- 朝陽:
sql/prodplan-payterm-20260904-cy.sql
- ⚠️ 朝陽正式機若已有自訂版本的
TWORK_QRY_PRODUCTIONPLAN,先比對OBJECT_DEFINITION再補欄,不要直接覆蓋(本機開發庫darbcycsa1從來沒有這支 SP,該檔本體是照禾久版寫的)。- 兩檔都是 ALTER(不存在時自動先建空殼),參數個數不變,
proc_param不用動。
- 跑法:
sqlcmd -S <伺服器> -d <帳套庫> -E -f 65001 -i <檔案>;跑完實查OBJECT_DEFINITION含「收付條件號」。
不動
- 三張明細的實體表(
twork_eis_productiond2/d3/d4)沒有加欄位,存生產計劃單時不寫這三欄。
- 金流預測分頁的欄位與圖表口徑不變(票據/帳款/在途採購三層完全沒動)。
- 獨立的「金流預測」程式(FLOWCAST)與「營運預測模擬」不受影響。
-
09-04 bom-sku-list-template ▸
2026-09-04 BOM 查詢「Excel取品號」新增「取得範本」按鈕
摘要
用途表(BOM_PURP)、最低階用料(BOM_BOTM)、階層式製程表(BOM_HIER)與成本表(BOM_COST)的 Excel 品號清單查詢,原本只有「匯入」沒有「範本」,使用者要自己猜欄位順序(A=序號、B=客戶代號、C=客戶簡稱、D=客戶品號、E=品號、F=查詢數量)。本次在匯入鈕旁加一顆
取得範本,一鍵產出空白範本。變更
- 四支條件面板新增
取得範本按鈕:開存檔視窗(預設C:\TEMPS\泛用取品號.xlsx,也可存.xls),產出「標題列+一筆示範資料」的空白範本,存完詢問是否立即開啟。示範列品號為SAMPLE-001,填資料時覆蓋或刪除即可;沒改就直接匯入,示範列會被略過並提示「Excel 內無品號資料」。
- 範本欄序與匯入讀取邏輯共用同一份定義(
SkuListExcel.TemplateHeaders),產出的檔案可直接由Excel取品號讀回(單元測試SkuListExcelTemplateTests往返驗證 .xlsx/.xls)。
- 多語言:
Bom_purp/Bom_botm/Bom_hier/Bom_cost四個翻譯檔補取得範本key;前三支同時補上 09-01 改版後漏補的Excel取品號、取得的條件兩個 key。
Excel取品號選檔視窗預設改.xlsx(C:\TEMPS\泛用取品號.xlsx),.xls仍可從篩選切換;取消選檔=不匯入、不提示、條件不變(使用者裁決)。
- 自訂條件沒設定就不查(BOM_PURP/BOM_BOTM/BOM_HIER):自訂條件模式下條件列全空就按查詢,原本會因條件空白退回「''~'zzz'」整個 BOM 全展開(朝陽跑 5 分鐘逾時);現在改為以訊息框提示「尚未設定自訂條件」並不執行查詢;Excel 模式沒匯入就查同樣改成訊息框提示(不再走例外路徑)。
- 自訂條件改走標準瀏覽流程、先以該單據別取得預設條件:欄位清單與「預設條件」下拉改由本程式的單據別(如
BOM_PURP)+瀏覽辨識碼 D 讀取自訂條件設定(twork_sys_zcond_field/zcond_category/zcond_define),有登錄就用登錄的欄位並在開窗時載入第一組預設條件;沒登錄(目前三支皆未登錄)則退回品號主檔 invent 欄位(排除與 bom_m 同名的稽核欄,避免 BOM_BOTM 的 SP JOIN 時欄名模稜兩可)、下拉顯示「Not Set」、條件列空白。要讓某支有預設條件,到自訂條件維護程式以該單據別登錄 invent 的欄位即可。提示不查時會清掉上一次的查詢結果。
Breaking Changes
- 無。
Migration Notes
- 無 DB 變更。
- 四支條件面板新增
-
09-04 bankacqry-default-3months ▸
---
title: 帳戶存提查詢起始日期預設最近三個月的 1 號
date: 2026-09-04
---
2026-09-04 帳戶存提查詢起始日期預設最近三個月的 1 號
使用者可見變動
- 帳戶存提查詢(O 模組):開啟時「立帳日期」起始日不再是空白(等於查全部歷史),改預設為今天往前推三個月那個月的 1 日(例:9 月 4 日開啟預設 6 月 1 日);截止日維持本月底。要看更早的資料自行改起始日即可。與票據查詢類「最近三個月」的預設原則一致。
-
09-03 manual-remove-telerik ▸
2026-09-03 使用手冊網站移除第三方元件品牌名
使用者可見變動
- 手冊 22 頁的「Telerik 內建匯出」「Telerik 資料表格」「RadGridView/RadDiagram/RadCartesianChart/RadWindow」等字樣,一律改為「資料表格」「流程圖」「折線圖」「視窗」等中性用語;產品簡介的技術棧改寫為「.NET 8 + WPF」「WPF + Material Design」。
docs/decisions/(ADR)與docs/changelog/改以mkdocs.yml的exclude_docs排除,不再建進手冊網站,站內搜尋也搜不到。檔案仍保留在 repo 供開發者閱讀。
- 手冊頁面原本連到 ADR/changelog 的 21 個連結(10 頁)改為純文字「ADR 00NN」,不再是超連結。
驗證
mkdocs build --strict通過;輸出目錄無 decisions/changelog;全站 grep「telerik」0 檔。
-
09-03 io-reports-round3 ▸
2026-09-03 帳款/票據報表第三輪逐張實機與三處修正
使用者可見變動
- 瀏覽列印自動全選:主檔型程式(銀行帳戶、應收票據、應付票據、廠商帳戶表、預估資金表等)按列印進到瀏覽頁、按查詢載入後,會自動勾選全部資料再列印。先前只有在資料庫報表登錄表有列時才會自動勾選,新版報表登錄改寫在程式裡後這條永遠不成立,使用者按預覽一律得到「沒資料」。
- 客戶應收查詢/廠商應付查詢:查詢還沒跑完(或還沒查)就按報表預覽,改顯示標準「沒資料」,不再跳「Error Report Handle: Object reference not set」。
- 費用申請(朝陽等客戶庫):選單「費用申請」可以正常開啟。客戶庫選單登的是舊鍵 PAYAPPLY,程式鍵維持 PAYAPPLY_KC,登入時自動改寫,不必改客戶資料庫。
資料庫(朝陽)
sql/cy-rec-qry0-sync-20260903.sql:朝陽的 DARB_QRY_REC_QRY0 同步成禾久版(三個結果集)。朝陽舊版只回兩個結果集,客戶應收查詢查不出資料、年度應收統計表印不出。dev 模擬庫已套,正式機待部署批。
-
09-03 io-report-rulings ▸
2026-09-03 帳款/票據報表小裁決落地
- CHKRECQRY 應收票據查詢:排序預設由「收付款日期」改為「到期日」,對齊 VFP
chkrecqry開窗預設(報表種類=3)。CHKPAYQRY 應付票據查詢維持「收付款日期」。
- BANKFXR 銀行往來:O140-2「銀行餘額表」(Bankfxr1)改為朝陽專屬——禾久版 SP 不回傳銀行名稱/本幣小計,在禾久會印成銀行名稱空白、%全 0 的半殘表,故不列入禾久報表清單。
- PAYMNTPQ 應付列印:舊 7 張(Apprint1/1local/2/2local/3/3_cy/4)由標楷體改細明體 house style(標題 14pt 粗體、內文 9pt),列印資訊統一為右上「列印日期/列印人員/第 x 頁 / 共 y 頁」(FastReport repo)。
- 裁決「維持現狀」:Arsummarycy 上期結欠/Ardetailtick 上期未收印 0、Checkrecqry3 未兌現填實值——口徑不再更動。
- CHKRECQRY 應收票據查詢:排序預設由「收付款日期」改為「到期日」,對齊 VFP
-
09-03 install-customer-local-copy-aspnetcore ▸
2026-09-03 客戶端安裝腳本:安裝檔改本機執行+一併安裝 ASP.NET Core Runtime
適用:
deploy/install-customer.ps1(GPO/手動佈署 TsERP 到客戶機器)。變更
1. 安裝檔一律先複製到本機再執行(
%TEMP%\TsERP-install\)。之前直接從網路分享(尤其\\<IP>\deploy)啟動 .NET Runtime、SQLite ODBC、TsERP Setup 時,Windows 會跳出看不見的「開啟檔案 - 安全性警告」,整個安裝流程停住不動。2.
-InstallDotnetRuntime現在同時安裝 .NET Desktop Runtime 與 ASP.NET Core Runtime。佈署包(-Source)要放兩支同版安裝檔:windowsdesktop-runtime-8.0.x-win-x64.exe與aspnetcore-runtime-8.0.x-win-x64.exe。只放 Desktop 時 Setup 會自己上網抓「最新」的 ASP.NET Core,版本一不同步程式就開不起來(訊息「必須安裝或更新 .NET」),安裝也會多等 30 秒才結束。對使用者的影響
- 全新機器從零安裝:Config 階段約 10 秒、Install 階段約 10 秒,裝完直接可開。
- 已裝好的機器不受影響;重跑腳本會偵測到 runtime 已存在而跳過。
驗證
Hyper-V 全新 Windows 11 25H2(繁中)虛擬機從零跑完整鏈:設定→runtime→靜默安裝→開程式→登入→開五支程式,全部通過。
-
09-03 i-module-rp-union ▸
2026-09-03 帳款單據(rp_m/rp_d/rpsht_m)兩庫聯集——朝陽載入炸債結案
背景:朝陽(CY)帳套的
rp_m多了進口採購/報關 8 欄,程式端 Source 沒有 → 應付/應收帳款、對帳單導覽到真資料即SQL logic error: table … has no column named …(memoryi-module-cy-load-crash-20260810)。依 ADR-0050 兩庫聯集模式補齊(skilldual-db-union-sync)。- Twork_arp_vw_rp_m:Model+Source 補
invoice_no/inv_date/due_date/inv_amount/報單號碼/快遞號碼/報單日期/報關金額(base table 欄,走上傳);Source 另補 view-only收付款日期(TsSkipCheck,不上傳)。
- Twork_arp_vw_rp_d:補
原單價。
- Twork_arp_vw_rpsht_m:補 view-only
廠付款條件。
- 朝陽 view 落後 4 欄:新增部署腳本
sql/cy-rpsht-view-backfill-20260903.sql(vw_rpsht_m.建檔日期、vw_rpsht_d.分類索引4/單別3/單號3);devdarbcycsa1已跑並實查 4/4,正式機併入部署批。
- 裁決不動:禾久 view 多出的 18 欄(
部門名稱/客戶簡稱等)在朝陽接受空白;客付款條件兩庫語意不同(禾久=付款條件代號、朝陽=條件說明)維持各自原樣。
- 使用者可見變化:朝陽帳套 PAYMNT/RECEIVE/RSHEET/PSHEET 導覽真資料不再彈 SQL logic error;禾久無變化。
同日 runtime 走訪連帶修正(朝陽 dev 逐張預覽 PAYMNT 5/5、RECEIVE 3/3、PSHEET 3/3、RSHEET 5/5)
- 應付帳款單 Paymnt1/Paymnt5(朝陽)「Error Report Handle: String cannot be converted to Int16」:朝陽
rp_d.單價別是 nvarchar(30)、禾久是 tinyint,報表 POCORpt_I010_ApReportPoco.單價別宣告 short,DataTableToList直接 SetValue 不轉型即炸。改 string(frx 未印此欄;Paymnt1-4.frx 的 Column DataType 同步改 String)。
- 收款單 Rsheet1 頁首「收款日期」恆空白、「匯率」恆 0.00(兩帳套都中、自移植以來):插件
Rsheet1.cs組明細列時從沒回填主檔的 收付款日期/匯率,補上。同張明細列DataBand加CanGrow,長科目名稱折行不再被裁半截。
- 銷貨退回暨折讓單 Receive2/電子發票折讓單 Paymnt4 發票日期空白時整張印不出:
ToInt32(Substring(發票日期,0,4))-1911改 C# 三元守空值(report-layout 必死清單 #20 模式)。
- 治具:
c-print-e2e.ps1加-PrintQuery(RSHEET/PSHEET 型列印頁要先按「查詢」勾主檔才有資料;之前跑出的「沒資料」×5 是治具沒按查詢,非缺陷)。
- Twork_arp_vw_rp_m:Model+Source 補
-
09-03 casebook-visit-task-case ▸
2026-09-03 案例書新增〈主管派拜訪任務,業務在拜訪單一鍵回報〉
案例書「自動化與流程」章節新增第 24 篇,把 2026-08-28 上線的拜訪任務回報(排程事件派工 → 行事曆 → 拜訪單相關任務分頁回報 → 主管待辦)寫成行銷案例。
使用者可見變動
- 新頁
docs/case-studies/visit-task-report.md:場景(口頭交代與 Excel 追蹤表兩邊對不上)、現況(任務排進行事曆、從拜訪單按回報)、實際跑一遍(課長派工 5 步+業務回報 5 步)、四則提示(待辦內容即拜訪單/負責人填下屬/每月預設展開五年/行事曆新增事件)、效益表。重要度 ★★★★☆、更新日期 2026-08。
- 首頁卡片、資料夾導覽(
.nav.yml)與整本 PDF 目錄(tools/docs-pdf/manifests/case-studies.json)同步加入,排在〈單據線上送簽〉之後。
- 三張圖皆為實機截圖(Hyper-V lab VM
LAB-DEMO-01連 DEMO 展示庫,UIA 腳本走完整條流程後截取):images/visit-task-assign.png(新增事件視窗)、images/visit-task-report.png(拜訪單相關任務分頁+事件進度回報視窗+右側行事曆)、images/visit-task-reported.png(回報後的已回報列)。去識別化:DEMO 庫登入者姓名改「王志明」、業務員姓名與角落公司簡稱以影像後製改為「林佳蓉」/「岩月」。
- 整本案例書 PDF(
assets/Darbware-ERP-case-book.pdf)重出。
不寫進案例的內容(刻意)
- 行事曆事件卡
開單(從事件直接開拜訪單)與 Line 通知:尚未提供。
- 拜訪行程規劃(地圖/路線/過路費):程式已入庫但 runtime 未驗,暫不入案例。
- 新頁
-
09-01 testpanel-codesearch-and-c-labels ▸
2026-09-01 測試控制面板認得代號查詢控件;總務單據標籤去冒號、日期欄寬度回歸樣式
測試控制面板:廠商代號/收付條件/稅別這類欄位掃得到了
- 廠商代號、收付條件、稅別、客戶代號、部門、科目、群組、專案、業務員、銀行帳號等「代號查詢」控件(
VendorSearch/PaymentTermSearch/TaxTypeSearch/CustomerSearch/DeptSearch/GLAccountSearch/GroupSearch/ProjectSearch/SalesRepSearch/BankAccountSearch)以前掃描時只抓到控件內層的文字框,來源被解成控件自己的Code,欄位清單看不到正確欄名,三方對照也把這些 DB 欄誤報成「無UI」(總務進貨單 GTRRAMA 實測)。
- 現在掃描直接認得整個控件:欄位清單顯示綁定的來源屬性(如
廠商代號Binding/收付條件號/稅別)、控件種類顯示VendorSearch等;三方對照能對到 DB 欄。
- 模擬輸入/完整循環對這類欄位的填值直接寫進控件的代號值(不經內層文字框,避免查無代號時彈出訊息框卡住整輪),所以「帶簡稱」不會觸發、代號是否存在交給存檔驗證。自產值仍是「欄名.長度」格式,欄位清單備註會提醒「存檔前請改填存在的代號」(既有限制不變)。
- 綁
XXXBinding前端包裝屬性的欄位(如廠商代號Binding),欄位清單的「DB欄」與零號庫逐欄核對現在會對到真欄位廠商代號,不再固定回「資料表無此欄」。
- 「前綴」等下拉型代號控件(
TsDocumentPrefix/TsFinanceType/TsCobLanguage)同樣改在外層辨識:欄位清單顯示綁定的來源屬性(如序號前置碼)與控件種類,測試值取下拉清單第一個選項(清單為空時標「無可選項,不支援設值」),填值只挑清單內存在的值。
- 填值後多一道「回讀比對」:把來源屬性的值讀回來與測試值比(字串不分大小寫、日期比到日、數字比數值),不符就記「來源值未更新」而不是成功——避免 binding 沒開
ValidatesOnExceptions時存檔驗證擋下卻記成填值成功。
- 實機驗證(2026-09-01,GTRRAMA 三方對照報告修前→修後):廠商代號/收付條件號/稅別/序號前置碼 由「無UI」→「三方齊」;整張表 三方齊 64→68、無UI 28→24、UI無來源 9→1、問題 42→38。
- 畫面上直接放的代號查詢文字框(
TsSearchTextBox)在模擬輸入填值當下暫時不做「資料不存在」檢查(填完即還原),不會再因自產代號查無而跳出訊息框卡住整輪。
全系統欄位標籤去掉冒號(含總務四支)
- 使用者裁決:標籤一律不帶冒號(半形「:」與全形「:」都算)。本次機械式清掉 45 支 XAML、465 個
DisplayMeta[…:]標籤鍵(含FallbackValue的冒號),涵蓋總務(GTRRAMA/GPURCH/GTRLIMA/GPPURCH)、發票 P 模組全系(Tick401/Ticka/Ticks/Tickr…)、帳款(Arclaim/Rfe/Rpdef)、生產(Wkday/Pdtinf/Wkpaper)、品管(Purama/Twrama/Wkrama)等。
- 多語言翻譯檔
Common/Lang/Xaml/*.json同步改鍵:52 檔、485 個鍵去冒號改名、34 個已有無冒號版的重複鍵刪除,各語言譯文尾端冒號一併拿掉;改前有翻譯的鍵改後全部仍查得到(0 流失),切換語言不受影響。
- 只動
DisplayMeta[…]標籤鍵;表格欄位標題(grid Header)不在範圍內。
- 寫死字串的標籤(
Content="xxx:"/Text="xxx:")另掃 405 處:192 處在 XML 註解內不動、7 處純符號分隔(時間:等)保留、其餘 206 處/14 支去掉冒號——這 14 支全是無畫面引用的舊檔(Invent_zd、Payapply_zd、Trrama_zd…)、TsControl 內容控件與測試面板本身,沒有可到達畫面需要再包多語言。
總務報價單(GSPPDT):活動起始日/活動截止日寬度回歸控件預設
- 這兩個日期欄原本寫死
Width=120,蓋掉了日期控件依格式自動給寬的機制;已移除,寬度與其他日期欄一致(短日期 90)。
- 廠商代號、收付條件、稅別、客戶代號、部門、科目、群組、專案、業務員、銀行帳號等「代號查詢」控件(
-
09-01 gtrrama-tag ▸
2026-09-01 TAG 專屬進貨單(TAG進貨單/GTRRAMA_TAG):匯入TAG 按鈕移到畫面上
新程式:TAG進貨單(C.總務管理 → C-071)
- SH03A 水泥廠 TAG 標籤追蹤系統新增一支專屬的總務進貨單 TAG進貨單(程式鍵
GTRRAMA_TAG),畫面與存檔規則沿用 G進貨單(GTRRAMA),差異只有兩處:
1. 主檔區右上角多一顆「匯入TAG」按鈕——手持機 LOG(CSV)匯入 TAG 明細,一列一支 TAG,一張進貨單=一個批次。按鈕只在按下「新增」後可按(使用者裁決:一張新進貨單=一個 TAG 批次;修改既有單據不開放匯入)。
2. 明細表格把 TAG ID(原「其他資料1」)、手持機(原「其他資料2」)、批號別、批號 四欄移到「品名」後面,TAG 唯一碼一開單就看得到(原本排在第 25 欄之後)。
- 原本掛在 G進貨單「其他功能 → 匯入TAG」的擴充鈕已拿掉(TAG 庫的權限表本來就沒設這顆,從未出現過);G進貨單本身行為不變。
- 登錄方式:直接登進 TAG 庫的
_menum/_menud/_sheetno/prgsct1/瀏覽條件設定(複製 GTRRAMA 的列改鍵),不走登入時的程式分流;部署腳本sql/sh03a/sh03a-gtrrama-tag-register-20260901.sql(含還原腳本),只有 TAG 庫需要。
- TAG 版的擴充鈕(採購轉單/送修轉入/工作流程/快速審核)一律不開放。
順帶修掉的母版問題(L4 實測抓到)
- 前綴(序號前置碼)下拉一直是空的:總務進貨單/出入庫單/出貨單與庫存的進貨/領料/生產/出貨/委外單,新增時前綴下拉都沒有選項,新單被「請輸入[序號前置碼]」擋住存不了。根因是程式拿程式鍵去比對交易事項表的「單據別」,但該欄存的是「1.總務進貨」「A.進貨」這種群組名(VFP 的 d_單據別)。現在改成程式鍵→群組對照(總務三支對 1/2/3,庫存五支照 VFP 原始碼對 A~E),前綴與交易別下拉都會正確列出。已直接登程式鍵的資料庫不受影響(等值比對優先)。
- 匯入 TAG 的明細序號從 000001 起:新增時框架會先預生 20 列空白列,匯入改成先填這些空白列、填完才追加,不再從 000021 起跳。
- G進貨單新增時漏設「單據別=1」:存出的單在進貨單 view(只看單據別 1)裡找不到自己,存檔後單頭停在「+++」、要重開才看得到;已在新增預設值補上(出貨單本來就有設 3)。
- TAG 庫的配批號程序原本拿「轉入單pkid」當批號(那是採購轉單來源,匯入 TAG 的列恆為 0,永遠配不到);改為單頭 pkid(
sql/sh03a/sh03a-tag-patch-trgade-lot-20260901.sql,只有 TAG 庫)。
- 前綴/公司代碼/語言版本三種下拉(2026-09-02 使用者裁決)改成與傳票「傳票種類」下拉同款:單一下拉直接顯示「代號:名稱」、寬度隨內容,拿掉舊的自訂項目樣式與旁邊的說明文字框。舊樣式有兩個毛病:選定後收合框顯示「…」;且樣式宣告的控件型別不對,清單一有項目、一展開就跳「系統錯誤」視窗(語言版本/公司代碼下拉是潛雷,前綴修好後才引爆)。
- 匯入列的 linkid 在存檔前由存檔邏輯統一接到主檔(自製產生列不走 grid 標準新增,原本存進資料庫變孤兒、重載後消失、也配不到批號)。
驗證
- 建置 0 error;HarnessSmokeTests+ProgramClassRouterTests 62/62 通過;部署腳本在
darbtagcsa1冪等與從零單趟皆 7/7 OK。
- L4 runtime(三輪 UIA 實測,
.claude/tmp/gtrrama-tag-l4-report.md):開窗、新增後才可按、前綴 RC/RD/MG、匯入 5 支(重複略過 1)、序號 0001–0005、存檔回填倉單號、DB 明細 linkid/批號別 TG/批號=單頭 pkid/單據別 1、重開載回 5 列、母版 G進貨單無回歸——全部通過。未驗:庫存按批次累進(測試庫 ginvstk 無資料)。
- SH03A 水泥廠 TAG 標籤追蹤系統新增一支專屬的總務進貨單 TAG進貨單(程式鍵
-
09-01 gsppdt-price ▸
2026-09-01 總務查價(廠商比價表)補回:新建 SP `TWORK_BIZ_GSPPDT`
- 總務請購單(GREQMA/GPPURCH)、總務採購單(GPURCH)、廠商報價(GSPPDT)的「查價/廠商比價表」原本在任何帳套都是整排空白、沒有錯誤:程式端派發的 SP
TWORK_BIZ_GSPPDT從來只存在於英文 schema 帳套,中文帳套(禾久/朝陽)沒有這支 SP、派發器也沒登錄,查詢被靜默略過。
- 現在新建中文版
TWORK_BIZ_GSPPDT(sql/twork-biz-gsppdt-20260901-ssms.sql,執行器-run.ps1):形狀照採購模組同功能DARB_BIZ_SPPDT,回兩個結果集——採購單歷史(gpurchm/gpurch)與廠商報價(gsppdma/gsppdt,只取已審核)。查詢別 1=各廠商最新一筆(報價另依活動起迄日包含查詢日者優先);查詢別 2=同一廠商各取最新 20 筆。
- 比價表欄位對齊採購模組:報價類型/廠商代號/廠商簡稱/廠商品號/品號/單號(新增)/報價日期/幣別/單價/傳回/單位/數量(新增)/最低採購量/備註;原「生效日期」欄拿掉(中文帳套報價明細沒有此欄)。來源類別文字由
1.Purchasing/2.Quotation改為1.採購/2.報價(系統參數 6006 依前綴挑價來源的行為不變)。
- 部署:每個帳套跑
sql/twork-biz-gsppdt-20260901-run.ps1 -Csa <csa庫> -Log <log庫>(csa 建 SP+log 登錄 proc_param param_qty=4);未跑前比價表維持空白(不炸)。dev 禾久/朝陽與正式機皆已部署(2026-09-01)。
同日:比價表「單號」可點(總務+採購兩張)
- 總務(GREQMA/GPPURCH/GPURCH/GSPPDT)與採購(PPURCH/PURCH/SPPDT)的比價表,「單號」欄變成藍字底線超連結,單擊依該列「報價類型」分流:
1.採購開對應採購單(總務→G採購單、採購→採購單)、2.報價開對應廠商報價(總務→G廠商報價、採購→廠商報價)。右側「歷史單價」頁與下方比價表都有。
- 跳轉後按左下「返回」回到原來那張單(例:G廠商報價 SG2600002 → 點 PN2600004 開 G採購單 → 返回回到 SG2600002)。⚠️ 已知限制:來源與目標是同一支程式時(在 G採購單裡點另一張採購單號),「返回」回不到原單——這是框架同程式切頁不推歷史的既有行為,非本次新增。
- 沒權限開目標程式時點下去會出訊息;解不出目標的列維持一般文字(不會出現點不動的藍字)。
- 品號欄同樣是超連結:總務比價表開 G庫存主檔、採購比價表開庫存主檔,返回回原單。品號/單號欄加寬(140/120),不再截字。
- 總務請購單(GREQMA/GPPURCH)、總務採購單(GPURCH)、廠商報價(GSPPDT)的「查價/廠商比價表」原本在任何帳套都是整排空白、沒有錯誤:程式端派發的 SP
📅 2026 年 8 月 (124 篇)
-
08-31 test-panel-merged-report ▸
2026-08-31 測試控制面板:前置作業報告與三方對照合併成一份
- 規格自動測試的「① 前置作業報告」與三方對照的「匯出 HTML」原本各出一個檔(
<程式>-前置作業-<時戳>.html、<程式>-trisource.html),現在合併成一份C:\temps\TestAutomation\<程式>-前置作業.html(一支程式一份、只留最新,列印日期在報告內)。
- 報告段落:一、主資料表及相關聯之資料表 → 二、資料結構及索引 → 三、三方對照(SQL 欄位/本地類別/畫面 UI) → 四、VFP 專案程式內容。三方對照的「VFP 驗證」欄直接跳到同一份報告第四段的程式碼錨點,不再跨檔連結。
- 三處入口都出同一種檔:規格分頁「① 前置作業報告」(會先建立對照再出檔)、「▶ 全部執行」的步驟 0、三方對照分頁的「匯出報告(併入前置作業報告)」。
- 尚未建立對照時報告照出,第三段只寫一句提示;前置作業步驟結果有問題筆數時記「人工」(同步驟 0 的口徑)。
同日:自動測試值改成「欄名+點+長度」
- 掃描欄位時字串欄的自動測試值不再是「測試HHmmss」,改為欄位名稱+「.」補滿+欄位長度,剛好填滿欄位:備註 nvarchar(5) →
備註..5、客戶名稱 nvarchar(10) →客戶名稱....10;Memo 欄用「Memo字數」設定;長度未知時只填欄名。
- 規格自動測試的「輸滿欄位長度」與修改階段同一格式(修改值=
改備註.5,仍維持長度)。
- 重掃只帶回使用者親手改過的值,沒改過的自動值會依零號庫實際欄長重算。
- 規格自動測試的「① 前置作業報告」與三方對照的「匯出 HTML」原本各出一個檔(
-
08-30 ginvent-dynamic-tabs-and-browse-grid-format ▸
2026-08-30 G庫存主檔分頁改版+瀏覽表格版型存檔修復
G庫存主檔(GINVENT)分頁改成與庫存主檔(INVENT)相同的動態分頁
- 「基本」分頁抽成獨立畫面
GinventTab1,右側「自定義」分類改成與 INVENT 相同的群組框版面(上緣對齊主檔欄位、「分類內容」改為下拉欄可直接選群組定義的內容)。
- 「統計」分頁改共用 INVENT 的統計畫面:按鈕由「顯示」改為「檢視」、數值加千分位。
- ⚠️ 目前
twork_sys_statistics_definition只有 CUSTOMER/INVENT_BS/SPDATA 三種分類的定義,沒有 GINVENT,所以 G庫存主檔 的統計分頁目前是空清單(改版前也是空的)。要不要補 GINVENT 的統計定義待裁決。- 切分頁時不再在除錯輸出洗版
System.Windows.Data Error: 23/7(原因:VM 的TabSelectedItem型別與畫面的靜態分頁不合,切分頁也一直觸發不了查詢分頁的自動查詢)。
- 編輯狀態下統計/出貨/廠商報價/採購/進貨分頁會一併停用並跳回「基本」,行為與 INVENT 一致。
瀏覽表格(查詢畫面的資料表格)版型從來存不起來——已修
- 症狀:查詢類畫面(如 G庫存主檔 的廠商報價分頁、各瀏覽視窗)的表格欄寬/欄序/隱藏,切畫面後不保留;右鍵「記憶格式」也存不成功(DebugLog:
SaveSessionFormat failed for GSPPDTbrow: Type: TsControl.QueryTemplate.InventQuery is not included in the AllowedTypes collection)。
- 根因:Telerik 版型序列化的自訂屬性提供者只登錄在基底表格型別,瀏覽用的衍生表格型別解析不到,退回預設序列化 200 多條屬性而中斷。
- 修法:表格建構時以實際型別自我登錄;已加 smoke test 守門。
G庫存主檔 統計分頁補上 GINVENT 定義(同日第二批)
- 新增子程序
TWORK_STATISTIC_GINVENT與 8 列定義(sql/ginvent-statistics-definition-20260830.sql,可重跑、SQL 2008 可跑):
最新報價單價/最新未結案採購單/最新進貨單號/最新進貨單價/本月・本年・去年進貨額/最新出貨單號。
資料來源是 G 系列表(gsppdma/gsppdt、gpurchm/gpurch、trgama/trgade)。
- 與 INVENT 的差異:G 版「最新報價單價」不限已審核(禾久 gsppdma 67 筆只有 2 筆已審核)。
- 同時修好 G庫存主檔 三個查詢分頁「按查詢永遠空白、沒有任何錯誤訊息」的一串既有缺口(每一條都實測過):
1. 出貨/進貨分頁指向不存在的
DARB_BD_TRGAMA→ 改DARB_BD_GTRSADE/DARB_BD_GTRRADE,並登錄到twork_sys_viewlist(dispatcher 沒登錄就回空)。2. 出貨/進貨分頁的程式類別
TRGAMA不是真程式(權限表零使用者)→ 沒瀏覽權限、查詢一開頭就跳出;改GTRSAMA/GTRRAMA。3. 交易別碼清單為空(禾久 tritem1 沒有 RA-/SA- 分類)時字串切割丟例外 → 補製造版本來就有的
if (tri.Any())守衛。4. G 的瀏覽 proc 是 inline join,條件欄位
品號/廠商代號/客戶代號與pkid_m不加別名會「模稜兩可」/「無效欄名」→ GA 條件全部加別名;統計「檢視」條件改a.pkid/A.pkid。5. 廠商報價分頁原本查的是製造版 sppdt → 改走
DARB_BD_GSPPDT(gsppdma/gsppdt)。- 分頁順序改為 基本/統計/廠商報價/採購/進貨/出貨;右上 pkid/已審核 面板改走框架擴充面板(統計等分頁會收合,與 INVENT 一致)。
- 已部署:開發機 darbnogicsa1、darbcycsa1(朝陽模擬庫另補跑 08-12 的父程序腳本才有 NavigatePkid 欄)。正式機待跑。
統計分頁「內容」欄的數值列看起來空白——已修(INVENT/G庫存主檔 共用畫面)
- 症狀:統計分頁的單價/金額列看似沒有值,單號列正常。
- 根因:
InventStatistics.xaml左側面板最寬 300px,「內容」欄自動撐到 238px 後,靠右對齊的數字全排到可視區外(要拉水平捲軸才看得到);靠左的單號從欄首開始所以看得到。不是權限問題(實查 CMSA 對 G 程式的可否看單價本來就是 1)。
- 修法:面板放寬到 480px、「內容」欄上限 240px。
G庫存主檔 查詢分頁/統計「檢視」改走新的 TWORK_BD_G* 瀏覽程序(全部用 pkid_m)
- 新增
TWORK_BD_GSPPDT/TWORK_BD_GPURCH/TWORK_BD_GTRRADE/TWORK_BD_GTRSADE(sql/ginvent-query-procs-twork-20260830.sql):內容包成子查詢再接條件,
pkid_m/pkid與不加別名的欄位都能用;進貨那支直接用基礎表(朝陽沒有 vwbd_gtrrade 也能跑)。原DARB_BD_G*不動。- 登錄:
twork_sys_viewlist(查詢分頁 dispatcher)與_sheetno.QueryProcedure(GSPPDT/GPURCH 由 DARB_BD_G* 改指新程序,GTRRAMA/GTRSAMA 原本空白)。
- 統計「檢視」條件統一
pkid_m=…(與 INVENT 一致);程式端 GA 條件的別名全部拿掉。
- 執行順序:先
ginvent-statistics-definition-20260830.sql,再本檔(本檔會重寫 TWORK_STATISTIC_GINVENT)。正式機待跑。
- 「基本」分頁抽成獨立畫面
-
08-28 visit-task-report ▸
2026-08-28 拜訪任務回報(第一批):排程事件派任務、拜訪單回報
主管在「排程事件(專案)」派「客戶拜訪」任務給下屬,下屬拜訪完在「拜訪單」回寫進度並通知主管,主管點待辦直接開啟該張拜訪單。
!!! note "最終樣貌以本頁最後一節為準"
當天依使用者回饋改版四次。回報入口最後定案在拜訪單下方面板「相關任務」分頁的
回報鈕(不是工具列按鈕),詳見文末下午第三補與下午第四補。以下先記錄當初的第一批內容;文中的「來源任務」分頁與已關聯狀態均為當時名稱,現已改為 相關任務 與已回報。使用者可見變動
排程事件(專案)EVENTPROJECT
- 新增事件範本視窗(
批次新增用,右側行事曆的新增事件也是同一個視窗)的「明細」群組最下方多兩個欄位:
- 任務類型:下拉,選項來自新設定表
twork_sys_tasktype(禾久種子一筆「客戶拜訪」)。選定後自動把 單據別 填成對應程式(客戶拜訪 →VISIT),並把 對象 欄切換成該類型的查詢窗(客戶拜訪 → 客戶主檔)。- 對象:代號查詢欄(可打
[]?開窗),右側唯讀顯示「代號 名稱」;離開欄位後把代號換成內部識別存進事件的 對象id。- 任務類型與「自動化參數」的執行項目互斥:選任務類型會清掉執行項目與自動執行;選執行項目會清掉任務類型與對象。
- 明細資料表格多兩欄:任務類型、對象(顯示反查後的名稱)。
拜訪單 VISIT
- 下方面板新增 來源任務 分頁:列出這張拜訪單已關聯的排程事件(狀態
已關聯),以及登入者名下尚未回報、單據別為VISIT的任務(對象與本單受訪客戶相同者標同客戶)。欄位:導航(跳到該事件所屬專案)/狀態/預定時間/說明/任務類型/對象/進度/已完成/專案。換筆自動重撈。
- 其他功能新增
回報任務(在既有的查詢旁,權限的其他2)。只能在瀏覽狀態、已存檔的拜訪單上使用,編輯中或新單會提示。
- 回報拜訪任務視窗:上半為候選任務清單,依「已關聯 → 同客戶 → 預定時間離拜訪日期最近」排序,第一筆為系統建議且預設已選;下半為 進度(預設 100)、標記完成(預設勾)、通知人員(預設帶專案負責人,有
負責人鈕可重帶)、通知方式(預設待辦事項)、內容(預設「(今天) 已完成拜訪 客戶代號 客戶簡稱,詳見拜訪單 單號。」,可改)。
- 按
回報依序執行:寫進度/通知人員到事件(進度 ≥ 100 會標完成)→ 勾了標記完成則標完成(完成時間由系統寫)→ 有通知人員就開一筆待辦,待辦掛在這張拜訪單上,主管點待辦直接開拜訪單 → 拜訪單記住來源事件。
修正
- 行事曆事件卡
報告按鈕的進度與通知人員先前從未寫進資料庫,已修正。
- 下方面板「其他查詢」分頁現在會顯示各自真正的名稱。
資料表變更
物件 變更 twork_sys_tasktype新增設定表:任務類型清單(禾久種子一筆「客戶拜訪」) 排程事件明細 新增 任務類型、對象id 欄位 拜訪單 新增 來源事件id 欄位(使用者看不到,供「來源任務」分頁判斷已關聯) 部署
腳本 對象 sql/visit-task-report-nogi-20260828.sql禾久各帳套(事件端 + 拜訪單端) sql/visit-task-report-cy-eventpart-20260828.sql朝陽只跑事件端(朝陽沒有拜訪單) - 權限:腳本已把
VISIT的其他1說明=查詢、其他2說明=回報任務、可否其他2=1 設好,不需手動調整。
Breaking Changes
無。既有事件與拜訪單不受影響:沒有任務類型的事件行為完全不變,
回報任務是新增的功能鈕。尚未提供(第二批)
- ~~拜訪單的工作流程送簽。~~ → 同日的工作流程視窗改版已讓沒有樣板的單據(含拜訪單)用
自訂流程送簽。
- 行事曆事件卡的
開單(從事件直接開拜訪單)。
相關文件
2026-08-28 下午補記(UIA 實機驗證後)
- 整條流程已在禾久模擬環境以 UIA 腳本實機走完(派工→事件 grid→拜訪單→回報→待辦→來源任務分頁顯示「已關聯」)。
- 拜訪單資料表另加五個工作流程欄(聯絡單id/工作流程/審核人員/審核日期/已審核):任何被待辦指到的單據,系統都會回寫這五欄(非簽核流程「已審核」寫空白,不會鎖單),缺欄會讓「回報任務」開不了待辦。
vw_visit同步帶出這些欄位(ALTER VIEW,原有授權保留)。
- 順帶修正:行事曆事件卡「報告」按鈕以前連待辦都開不出來(程式錯誤),已修。
下午第二補(使用者實機回饋)
- 回報視窗:「內容」改成真正的多行框(原本是一條浮在中間的單行框);「標記完成」移到最前面,勾了進度自動 100、進度改到 100 以下自動取消勾選;「負責人」鈕加寬不再截字。
- 右側行事曆事件卡:四顆鈕改為「導航/報告」上列、「附件/執行」下列(執行與報告換位)。
下午第三補(依使用者回饋改版)
本次把回報入口從工具列移進分頁,並讓拜訪單與行事曆共用同一個回報視窗:
1. 拜訪單工具列不再有
回報任務延伸功能鈕(其他功能2 已移除),VISIT權限的可否其他2不必再開啟。2. 回報改在「來源任務」分頁裡按
回報:分頁第一欄由原本的導航改名為回報,每一列一顆鈕;按下開啟的是與行事曆事件卡報告同一個視窗——標題「事件進度回報」,欄位為項目進度/通知人員/通知方式/通知帳號/內容,下方通知送出、離開關閉。原本的「回報拜訪任務」專用視窗(含候選任務清單、標記完成勾選框)已取消。3. 從拜訪單開窗會預填:項目進度=
100、內容=「已完成拜訪 客戶代號 客戶簡稱,詳見拜訪單 單號」、通知人員=該事件所屬專案的負責人。按通知後:事件進度回寫並標記完成 → 開一筆待辦給通知人員(待辦掛在這張拜訪單上,點開就是拜訪單)→ 拜訪單記住來源事件,分頁狀態變已關聯。4. 回報條件不變:只能在瀏覽狀態、已存檔的拜訪單上回報,編輯中或未存檔會提示。「來源任務」分頁仍列出已關聯的事件與登入者名下未完成的客戶拜訪任務(狀態欄:
已關聯/同客戶/空白)。5. 分頁裡不再有
導航:要打開事件本身,請從行事曆事件卡按導航(或直接開排程事件(專案))。6. 行事曆事件卡:四顆鈕為「導航/報告」上列、「附件/執行」下列;
報告開啟的視窗標題改為 事件進度回報,關閉鈕文字為離開。7. 新增事件視窗:標題改為 新增事件;版面改成左欄「明細」、右欄上「通知」下「自動化參數」,中間分隔線可拖曳;說明移到 對象 下面;選定對象後系統自動把「代號 名稱」帶到說明最前面(改選對象只替換開頭那段,使用者自己打的字不動)。
下午第四補(依使用者裁決再調整)
1. 分頁改名:拜訪單下方面板的 來源任務 分頁改名為 相關任務(功能不變)。
2. 狀態值改名:該分頁的狀態欄
已關聯改為已回報(意思不變=這張拜訪單回報過的那筆事件)。另外兩種值同客戶與空白不變。3. 回報視窗多一顆
完成鈕:位於項目進度輸入框左邊,按下把進度一鍵設為100,不必手打(多數回報都是「做完了」)。行事曆事件卡按報告開的是同一個視窗,同樣有這顆鈕。4. 通知方式下拉整理:
待辦事項在第一個、滑鼠停在下拉上的提示清單照代碼排;待辦事項 + Line因 Line 通道尚未提供先隱藏(代碼 1 保留,舊資料照常顯示)。選項內容、代碼與既有資料不變,新增事件的預設值仍是待辦事項。選待辦事項 + Email時,通知帳號會自動帶入通知人員的 email(先填人員再改方式也會補帶);只走待辦事項時通知帳號用不到,留空是正常的。5. 待辦點開看得到拜訪單內容:回報開出的待辦,收件人點開後「內容」區會顯示這張拜訪單的欄位(拜訪單號、拜訪日期、拜訪主旨、受訪代號、客戶簡稱、業務員、部門、起訖時間、受訪人員、拜訪內容、附件及備註、里程數、過路費)。這靠部署腳本新建的
vwcommpr_visit檢視與_sheetno.聯絡單view登錄;沒跑到那段的環境,待辦點開只有主旨、內容一片空白(回報與跳轉功能本身不受影響)。| 物件 | 變更 |
|---|---|
|
vwcommpr_visit| 新增檢視:待辦「內容」區要顯示的拜訪單欄位(單一主表、無明細) ||
_sheetno(單據別設定) |VISIT的 聯絡單view 登錄為vwcommpr_visit|部署腳本同
sql/visit-task-report-nogi-20260828.sql(已含這段;朝陽沒有拜訪單,不適用)。工作流程視窗改版(同日)
單據工具列
工作流程(送簽)視窗依使用者裁決改版,影響所有會送簽的單據,不只拜訪單。完整操作見工作流程派送。1. 不再跳「沒有發行者」:關卡裡沒有發行列時,系統自動補一列 發行(處理人=登入者、狀態已完成),面板照常開啟、照常送簽。原本的「沒有發行者,請檢查工作流程表是否有設定錯誤」提示不會再出現。
2. 流程樣板下拉最後永遠多一項
自訂流程(樣板號顯示CUSTOM)。選它時清單只有一列發行,其餘關卡由使用者在關卡資料表格按右鍵新增數筆自己加:處理事項可選(通知/確認/承認/初審/複審/核定)、處理人用放大鏡挑、審核順序照加入順序。單據別沒有任何流程樣板時(例如拜訪單),下拉就只有自訂流程且預設選中,可以直接送簽。3. 選一般樣板時:樣板帶出來的關卡仍不能改;但可以按右鍵
新增數筆補通知人員——新增列的處理事項固定 通知、排在流程最後,只要選處理人。4. 儲存(送簽)前檢查:除發行以外的每一關都要有處理人,否則提示「關卡 00X 尚未指定處理人」並擋下存檔。
5. 下方面板「工作流程」分頁(流程圖):只畫真正送簽的流程。被回報/行事曆
報告通知過的單,那些通知待辦改列在流程圖下方的 通知紀錄(N) 清單(日期、主旨、通知給誰、狀態),不再一條條畫成「發行→通知」;還沒送簽時顯示 尚未送簽。分頁標題的筆數:有流程算關卡數,只有通知算張數。6. 被通知過的單現在可以正常送簽(改版前會被當成已送簽而整個面板唯讀)。此項靠部署腳本
sql/wkflow-getnotes-skip-notify-20260828.sql;沒跑到的環境仍會唯讀。腳本 對象 sql/wkflow-getnotes-skip-notify-20260828.sql各帳套(讓通知類聯絡單不被當成已送簽) - 新增事件範本視窗(
-
08-27 seek-tooltip-pdf-pageno-faq-red ▸
2026-08-27 定位搜尋欄加提示、手冊 PDF 加頁次、常見問題問句改紅字
使用者可見的變動
1. 定位搜尋欄(導覽列中間的輸入欄)永遠有提示
改前:
TsSeekTextBox的 ToolTip 直接綁TsSeekTextBoxViewModel.ToolTip,而該值是從 DB 撈該程式的查詢清單說明——沒有設定查詢清單的程式就是空字串,整個欄位完全沒有任何提示,
使用者不會知道這欄還能打
;、[、]、?。改後:滑鼠停在欄位上一定看得到輸入規則:
- 輸入代號後按 Enter 定位到該筆
- 代號後面加分號(;) 再按 Enter,定位到符合的最後一筆
- 輸入
[、]或?可開啟查詢視窗挑選 ← 只有該程式有設定查詢清單時才列出(沒設定時打這些符號本來就沒反應,列出來會誤導)
- 輸入的英文字母會自動轉成大寫
該程式有設定查詢清單時,原本的清單說明接在提示後面(空一行隔開),資訊不會少。
實作:
ViewModel/Control/TsSeekTextBoxViewModel.cs新增SeekToolTip(原ToolTip不動,因為
HaveSQLSeekData是靠它是否為空來判斷有無查詢清單,動了會讓[/?誤以為有窗可開);TsControl/Themes/TsTextBoxGeneric.xaml的TsSeekTextBox樣式改綁SeekToolTip。提示文字走
DisplayMeta[中文],未翻譯時顯示中文原文。已知限制:提示文字在 VM 建構時決定,切換語言後要重開該程式才會換語言。
2. 手冊匯出的 PDF 每頁加頁次
頁尾中央顯示「第 N 頁 / 共 M 頁」,封面不加,頁碼=PDF 實體頁次(與檢視器頁碼一致,方便對照)。
Chrome 的
--print-to-pdf只能全有全無地開預設頁首頁尾(會夾帶file:///路徑),CSS 的
@pagemargin box(@bottom-center)Chrome 也不支援 → 改在產出後用 PyMuPDF 蓋上去(
tools/docs-pdf/export-pdf.py的stamp_page_numbers)。字型用微軟正黑體並做子集化——MuPDF 內建的
china-t會把數字排成全形、字距很醜,而不子集化會讓 PDF 暴增 13MB。manifest 可用
"page_number_footer": false關掉。3. 常見問題的每一題問句改紅字
??? question的問句在網頁與 PDF 都改用紅色(#b42318;深色主題用#f08a7a),章節標題「常見問題」維持原色。全手冊 391 個檔、2172 題一次套用(純 CSS,不動 md 內容)。
- 網頁:
docs/stylesheets/extra.css新增--ts-question色票與規則。
- PDF:
tools/docs-pdf/export-pdf.py的列印 CSS 加.admonition.question標題色(左側線也一併改紅)。
相關說明調整
docs/getting-started/index.md「查詢視窗不是每支程式都有」那段原本寫「有設定的程式,把滑鼠停在輸入欄上會顯示提示文字」,配合第 1 項改成「一定會顯示輸入規則,有設定查詢清單時再附上符號與查詢內容」。
-
08-27 manual-grid-term-rename ▸
2026-08-27 手冊用語統一:格線 → 資料表格;標準功能視窗分區圖第 4 項框線對齊
使用者可見的變動
1. 手冊用語統一
終端使用者手冊(
docs/)中原本用來指稱畫面上多筆資料表格(TsRadGridView)的「格線」,一律改為「資料表格」,共 209 個檔案、984 處。
- 連帶調整的標題與錨點:
基本畫面介紹的## 格線(表格)通用操作→## 資料表格通用操作,
內文連結
#格線表格通用操作→#資料表格通用操作(同步改,連結未失效)。- 原本重複語意的「表格(格線)」一律收斂成「資料表格」。
- 未改動:
docs/changelog/、docs/decisions/(歷史紀錄,保留當時用語)。
docs/_guide/writing-guide.md已加入用語規定,新頁面不得再寫「格線」。共用控制項頁面的標題也一併對齊:表格(TsRadGridView)→ 資料表格(TsRadGridView)
(頁面標題、H1、
controls/.nav.yml導覽名稱與 8 處連結文字,共 11 處)。2. 標準功能視窗分區圖修正
docs/getting-started/images/standard-form-layout.png:- 第 4 項(資料導覽列)的橘色框線原本沒有對齊——框線畫在導覽列下緣的狀態列上,
上緣橫線還橫切過「傳票號碼」欄、「歷程」選項與換頁按鈕。現已重畫成貼齊導覽列本身的
上下分隔線(y=1308/y=1347),涵蓋定位搜尋欄到
說明鈕,編號圓標同步移到框的左側中央。- 被舊框線蓋掉的畫面像素,改由同一次截圖的未標註版本
images/main-window.png還原
(兩張圖除標註外逐像素相同,只差最上方 22 列)。
- 圖內圖例第 3 項文字同步改為「明細(單身)資料表格」。
3. 清掉已補齊的截圖提示
手冊頁尾的截圖提示區塊,凡是「截圖已經補齊」的一律移除,只留下真正還沒拍的:
- 移除整個區塊 20 支:4 支只寫「本頁截圖已補齊」的
截圖說明
(
getting-started/的 index/browse/list-browse/print),以及 16 支所列截圖全部已存在且已嵌進頁面的
需補截圖清單(
_infodb、datatpl、language-switch、zcond、bom_botm、bom_chk1、culbl、otherrp、prepaid、commpr、nouse、px_qry、bank、bankday、bankfcst、checkqry)。- 只刪已補齊的那幾條、清單保留並重新編號 25 支:共 29 條(含
pur_qry3那條)。
- 判定條件:該
.png檔實際存在於該頁的images/且頁面內真的有引用;
只有檔案、頁面沒引用的不算補齊,提示保留。
- 刻意保留:
M-EIS/customdash.md的customdash-export-html-select.png
(提示本身註明「需重拍」,仍是待辦);以及
尚無截圖/無需補截圖/截圖來源這幾種非待辦性質的說明區塊。
- 連帶調整的標題與錨點:
-
08-27 extdata-physical-tables ▸
2026-08-27 外部資料改存資料庫:EXTDATA 加車輛公會統計、月報改讀 DB
程式:外部資料擷取(L.聯絡傳訊 ›
L-090)、業務儀表板/業務課報告表(E.營業收款 ›SALESDASH)、排程任務ExternalDataFetch。設計取捨見 ADR 0145。車輛公會(TTVMA)統計與金屬行情原本只落地成檔案,這次改成同時寫進資料庫(集中自動化庫的
twork_auto_ttvma/twork_auto_metalprice兩張表)。原始檔照舊落地保留,可以繼續拿來跟公會網站對帳。外部資料擷取(EXTDATA)
- 查詢條件新增 車輛別:
全部/汽車/機車,決定下面「車輛公會統計」要看哪一種。
- 查詢結果新增 「車輛公會統計」 表格(資料月份/車輛別/銷售別/期別/規格/廠牌/數量),一列一個數字,可直接排序、複製、匯出。
- 金屬行情改讀資料庫(以前是讀當期落地的 JSON 檔):換一台電腦、換一個人查,看到的都是同一份資料;查得到的期間也不再受「這台機器有沒有抓過那個月」限制。
- 本期還沒有公會資料時,自動改顯示表內最新的月份,並在底部訊息列註明「顯示 2026-07(本期尚無資料)」,不會給一張空白表讓人以為壞了。
- 勾「順便取得最新資料」查詢時,抓完會一併寫進資料庫,訊息列附上入庫筆數(例如「TTVMA_QTA1 入庫 234 筆(新增 234/更新 0)」)。本期已有而被跳過的來源也會補入庫——檔在本機不代表已經進表。
- 若資料庫端還沒部署好,訊息列會明說 「查詢派發失敗(proc 未部署或跨庫權限鏈未開,不是查無資料)」 並標紅,不會被誤讀成查無資料。
業務儀表板(SALESDASH)
- 按
立即擷取後,狀態文字會附上入庫筆數(不只是「抓到檔案了」)。
- KPI 卡與趨勢圖的內部命名由「訂單」改為「銷售」(各月銷售趨勢、本月銷售金額)。銷售數字自 2026-08-06 起本來就取自出貨單,這次把畫面上殘留的「訂單」字樣一併改掉,避免誤會。
業務課報告表(月報)
- TTVMA 資料改讀資料庫,不再於產生報告表時另外連一次公會網站下載、另外解析一次。少一次下載,產生速度變快,也不會再出現「儀表板抓到了、月報卻說沒有」的落差。
- 檢核模式的 「汽車TTVMA原始」/「機車TTVMA原始」兩個分頁改由資料庫重建公會版面:版面(標題、直排標籤、廠牌兩列表頭、合計欄、%欄、% 列、備註)與原本貼上去的公會表格一致,數字經真檔逐格比對完全相同。
- 百分比一律重新計算並顯示兩位小數;數量欄顯示千分位。
- 已知差異(刻意):直排標籤的字數與位置略有不同(原檔「去年同期銷售」6 字、重建為「去年同期」置中);公會逐月手打的臨時附註不保留(例如「\*三陽工業產銷統計資料彙整中」),要看原文請開落地的原始 xls;原檔自己算錯的格(
#DIV/0!)在重建版會變成 0。- 範本模式的表頭標題由「(預訂交期)」改為「(交易日期)」——口徑本來就是出貨單的交易日期,標題跟上。
排程
- 排程任務
ExternalDataFetch(單據別SALESDASH)新增參數FullHistory,預設false:
-
false(平時):只解析並更新最近的月份(表內最大月份的前一個月起)——公會會在月中回頭修正上個月數字,所以固定多重抓一個月。-
true:TTVMA 全歷史重載(現有落地檔含 2002-08 起共 288 個月,汽車約 6.7 萬列/機車約 21.8 萬列)。首次啟用時跑一次即可,之後改回false。- 其餘參數(
Sources/RootDir/Period/Force)與行為不變;任一來源入庫失敗會讓該次排程記為失敗(F),其他來源照做。
!!! warning "全歷史首載會很重"
全歷史一次寫入約 44 MB 的派發稽核紀錄(
log_sys_skd),請安排在離峰時段跑,且只跑一次。部署
- 集中自動化庫(
darb<客戶>auto1):跑sql/extdata-table-deploy-20260827.sql— 建 2 張表與 5 支 proc(TWORK_SKD_EXTDATA_TTVMA_UPS/_METAL_UPS/_TTVMA_QRY/_METAL_QRY/_TTVMA_MON),冪等可重跑。
- 各 log 庫(log1~log5):跑
sql/extdata-procparam-log-20260827.sql登錄proc_param。沒跑的話畫面會顯示「查詢派發失敗」。
- 兩支腳本用 sqlcmd 執行都要加
-f 65001(含中文、UTF-8 無 BOM),跑完看腳本最後的驗證結果。
- 正式機部署前先實查該機 auto1 的相容等級:腳本用到
OPENJSON,需 ≥ 130(SQL Server 2016 以上);不足時腳本會直接中止,不會建到一半。
- 朝陽(CY)本次不部署:其正式機為 SQL 2008,沒有
OPENJSON。
- 需要新版程式(
TsERP.exe/AutoPilot.dll)。
狀態
建置 0 error;單元測試通過(含 288 張真實工作表全數解析成功、版面重建真檔逐格比對數值格 0 筆不一致)。runtime 未驗——實際打到集中自動化庫的端到端(proc_param 登錄、跨庫權限鏈、大量 JSON 吞吐、EXTDATA 新表格開窗)尚未執行。
- 查詢條件新增 車輛別:
-
08-26 sliy-report-repeat-header ▸
---
title: 傳票報表跨頁每頁重印傳票號碼與欄位標題
date: 2026-08-26
---
傳票報表跨頁每頁重印傳票號碼與欄位標題
使用者可見變動
- 傳票列印(
Sliy/A5 版Sliy_a5/英文版Sliy_e/簽核版SliyApprove)一張傳票明細超過一頁時,第二頁起也會印出傳票號碼、傳票日期與欄位標題列(科目代號/科目名稱/摘要/部門別/借方金額/貸方金額)。過去只有第一頁有,續頁直接從明細列開始。
- 做法:四支
.frx的傳票GroupHeaderBand加RepeatOnEveryPage="true";每張傳票另起新頁(StartNewPage)的行為不變。
驗證
離線渲染治具(
.claude/skills/vfp-report-to-fastreport/references/frxrender/)以 45 行假傳票渲染四支報表,第 2 頁皆有傳票號碼/日期/欄位標題;REPORTSROOT\Reports部署副本已同步。ERP 內實印未驗。同日另一筆:BOM 流程圖「材料流向圖」右欄(製程/半成品/成品)改左緣對齊,垂直主幹改用固定 X 的自訂接點維持直線;按「左右相反」時改右緣對齊。
- 傳票列印(
-
08-26 secret-other-function-save ▸
---
title: 密碼權限表「其他功能」勾選改了存不進去
date: 2026-08-26
---
密碼權限表「其他功能」勾選改了存不進去
使用者可見變動
- 密碼權限表(
SECRET)右側「其他功能」表格勾選/取消「是否允許」後按儲存,現在會真的寫進prgsct1的可否其他N(說明文字其他N說明同修)。過去畫面看起來改了,存檔後重開又變回原值。
- 根因:存檔前的寫回(
Twork_sys_vw_prgsct1Source.SetOtherFunctionPermission)用舊英文屬性名AllowExtendedFunction{N}/DescriptionOfExtendedFunction{N}反射找欄位,屬性早已中文化成可否其他{N}/其他{N}說明,反射查無屬性就靜默跳過,勾選從來沒進 Model。改為中文名後與讀取端(ActionPanelViewModel)一致。
驗證
LogicBllTests/A.SystemData/SecretOtherFunctionTests.cs三支迴歸測試(勾選寫回/說明寫回/取消勾選寫回)+HarnessSmokeTests8 支全過;Model 用dotnet build、測試專案用 MSBuild 建置皆 0 錯誤。ERP 內開窗實存未驗。 - 密碼權限表(
-
08-26 pk-m-transfer-window ▸
---
title: 朝陽 PACKING LIST「修增」「標籤新增」轉單視窗(PK_M)
date: 2026-08-26
---
朝陽 PACKING LIST「修增」「標籤新增」轉單視窗(PK_M)
使用者可見變動(朝陽)
- 其他功能新增「修增」(對已選裝箱單追加明細)與「標籤新增」(新建裝箱單),共用 VFP 子表單 PK_M 的「PACKING新增視窗」:輸入 CI No./出通單號(
SL開頭查出通單、否則查 CI,並擋已有裝箱單的單號)+起始/截止箱號+前置文字+箱子品號+箱重/單箱毛重;查詢帶出明細(含出通單數量/已包數量/待包數量,靠pkde.交易單pkid控管重複裝箱);逐列按「增加」累加包數/尾數(尾數改為剩餘量,VFP 算成超出量是 bug);超量列變綠;儲存自己完成交易(標籤新增連 pkma 一起建),存檔後自動預覽側嘜貼紙再問「新增記錄已儲存,是否繼續新增 ?」,關窗後主畫面跳到新單(pkid 回 0 時改 SEEK cino)。
- 其他裁決落地:修增反查客戶 salema 查無改查 ci_m;查詢鈕以程式碼為準;CI 路徑放行碼表照抄 salema;grid2「無法轉單」拿掉三個恆 0 欄;
包裝量_包=0時「增加」只累加包數(照 VFP)。
- 依賴:
darbcylog1.proc_param補DARB_TUR_PK_M_CI(sql/proc-param-pk-m-ci-cy.sql,dev 已套、正式機待跑,未跑 CI 路徑靜默回空)。
- 已知限制:側嘜自動預覽的取數條件(報表端
CyOrderReportCondition.CiNoRange)只吃 cino 起訖、不吃前置文字/箱號區間 ⇒ 印整張 CI 的側嘜而非本次區間(D3 半套,報表端另案)。
驗證
單元測試 30(增加公式含 D2 反例/小計/超量/序號/五條存檔驗證)+smoke;MSBuild 0 error;VFP 133 元素差集 0。朝陽 dev UIA:修增開窗自動查詢(cino/箱號/前置文字/客戶帶入)、增加累加包數、取消釋放放行碼後離開;標籤新增端到端:
SL202600442→查詢 2 列→增加→儲存(毛重必填擋下→補後成功)→pkma新增、pkde1 列且交易單pkid有值、序號00101=VFP 公式→側嘜預覽Pkmark1開啟→「是否繼續新增」否→主畫面跳到新單→放行碼釋放(測試單已清)。審查修正(08-26):修增存檔後不再誤用 SaveMessage 的 pkid(會導到不存在的單、繼續新增會掛錯單)→ 只有標籤新增取新 pkid、修增沿用既有;manager 註冊改快取;視窗 X 關閉也釋放放行碼(IDisposable);查詢鈕版面獨立一欄。複驗:修增追加端到端(SE-2026000347→8 列、新列linkid掛原單、交易單pkid有值、不多生 pkma、主畫面停在原單、側嘜預覽+繼續新增);X 關窗→放行碼 0→可立即重開。未驗:包裝量_包>0的拆列、CI 路徑實資料、正式機。 - 其他功能新增「修增」(對已選裝箱單追加明細)與「標籤新增」(新建裝箱單),共用 VFP 子表單 PK_M 的「PACKING新增視窗」:輸入 CI No./出通單號(
-
08-26 pk-e3-merge-query-view ▸
---
title: 朝陽 PACKING LIST「合併」視窗(PK_E3)——先開放查詢顯示,合併存檔延後
date: 2026-08-26
---
朝陽 PACKING LIST「合併」視窗(PK_E3)——查詢顯示(6A)
使用者可見變動(朝陽)
- 其他功能新增「合併」:「PACKING合併視窗」依客戶代號+製表起訖日(預設帶目前單的客戶與製表日期)查多張裝箱單明細,可勾選列(全部選擇/全部不選),被其他人鎖住的列列在「無法轉單」;查詢會取放行碼鎖住相關單據,取消/離開/視窗 X 都會釋放。
- 合併存檔本輪不開放:儲存鈕停用並提示「合併存檔尚未開放(待裁決)」;
AllowSave也恆擋。原因:朝陽 VFP 現場的合併allowsave整段被註解、關窗不回單號,等於本來就不能用;要復活哪一版演算法(新開 SL 出通單/原單如何處理/分組鍵/箱號重排…)待使用者裁決後做 6B(使用者 2026-08-25 裁決)。
- 查詢條件擋門(VFP 沒有):客戶代號必填、製表起訖日必填且起≤訖。
驗證
單元測試 16(條件驗證各分支/勾選統計)+smoke 24/24;MSBuild 0 error;VFP 77 元素差集 0。朝陽 dev UIA:開窗預設值、查詢 2026 年 A07 得 33 列、放行碼 125 列鎖定、儲存鈕停用、X 關窗後放行碼歸零、主畫面不動。未驗:「無法轉單」grid 有資料的情境、全部選擇/不選、正式機。
-
08-26 pk-1-pallet-window ▸
---
title: 朝陽 PACKING LIST「設定棧板」視窗(PK_1)
date: 2026-08-26
---
朝陽 PACKING LIST「設定棧板」視窗(PK_1)
使用者可見變動(朝陽)
- 其他功能新增「設定棧板」(VFP 子表單 PK_1):按下後主畫面進編輯態、開「設定棧板」視窗——上方輸入格逐列填 起始棧板號/起始箱號/截止箱號/棧板別(初值自現有明細帶入),中間彙總各棧板總箱數,下方明細列被棧板區間完整接手者整列綠底;「重新計算反綠」強制重算;儲存→依棧板設定重建整組明細(原列刪、新列序號 001 起重編,重用重排序號規則)→回主畫面存檔;離開→主畫面取消編輯。
- 裁決落地:棧板別寫獨立
棧板別欄(pl_meas尺寸字串不動);棧板毛重=毛重+10;淨重/毛重四捨五入 2 位;VFP 死碼allowsave不搬;存檔前若有明細列未被任何棧板區間接手,先跳 YesNo「有 N 列未指派棧板,將被刪除」(VFP 是靜默刪)。
- 注意:存檔會經主畫面
PkSave/Pk_cySave的既有檢查——朝陽明細沒有單價欄,每次設定棧板存檔都會先問「明細有 N 列單價為 0,是否繼續存檔?」(08-25 匯入 CI 裁決的提示同一道),選否=不存並自動取消編輯。若嫌吵可裁決只在匯入 CI 路徑提示。
驗證
單元測試 22(區間攤平/覆蓋/重疊/未接手清單/序號/棧板別欄/毛重+10/捨入)+回歸 44/44;MSBuild 0 error。朝陽 dev UIA:閘門→進編輯態→開窗(初值自明細、全綠、彙總 1/12・2/12・3/15、總箱數 39)→重新計算→儲存進主畫面 Save→單價 0 提示選否→存檔取消→主畫面回瀏覽態、DB 明細 7 列不變。未驗:C5 未接手提示(UIA 改不到輸入格)、實際存檔重建寫入、200 列空白列效能。
-
08-26 p-control-chart-author-formula ▸
---
title: 工程P管制圖 Excel 樣板「作成」欄改照現場公式
date: 2026-08-26
---
工程P管制圖 Excel 樣板「作成」欄改照現場公式
使用者可見變動(朝陽,主管資訊→不良期間統計→工程P管制圖→Excel)
- 產出的 P 管制圖工作表「作成」欄,改為依查詢的起始部門自動帶班別負責人+當天日期(H1/H2→陳素枝、H3~H5→孔淑芳、H8→蔡佳珍、M1/M2→吳書萍、M3~M7→束燕霞、R1→徐秀珍),與現場 2025-09-09 的
P管制圖新版.xlsx一致(使用者 2026-08-26 裁決)。原本 ERP 內嵌版帶的是登入者(輸入人員)。
- 其他欄位、圖表、每 30 筆一張圖的產生邏輯不變;不再需要桌面的
P管制圖.exe/CyP管制圖新.exe(ERP 端本來就已內建產圖)。
- 人名硬編在樣板公式裡(照現場做法);換人要改
Common/Excel/ExcelTemplate/P管制圖新版.xlsx的sheet2!N2。
驗證
只改
sheet2!N2公式(直接改 xlsx XML、圖表與其他部件逐項 hash 不變);openpyxl 讀回公式正確、圖表 1 張仍在。runtime 未驗(需 Excel Interop 開圖,待實機按一次 Excel 鈕看作成欄)。備份:.claude/tmp/backup-20260826-pctl/。 - 產出的 P 管制圖工作表「作成」欄,改為依查詢的起始部門自動帶班別負責人+當天日期(H1/H2→陳素枝、H3~H5→孔淑芳、H8→蔡佳珍、M1/M2→吳書萍、M3~M7→束燕霞、R1→徐秀珍),與現場 2025-09-09 的
-
08-26 inventory-health-fixes ▸
2026-08-26 庫存管理模組體檢修正(出貨單費用分頁/耗料單⇄加工單導覽/盤點單導覽/進貨單死欄)
來源:H.庫存管理 16 支 UIA 實機體檢(禾久模擬庫),例外堆疊對回程式碼後逐項修正。
使用者可見變動
程式 修正前 修正後 出貨單 TRSAMA 導覽到末筆或切「費用」分頁跳「Cannot create a DbSet for Twork_stk_vw_trsafeeSource」 正常導覽;費用分頁可開 耗料單 TRLOST/加工單 TRWKMA 同一次登入先開耗料單再開加工單,按上一筆跳「UNIQUE constraint failed: Trwkma.pkid」 兩支各用自己的本機暫存表,互不干擾 盤點單 INVREC 導覽末筆跳「The input string '' was not in a correct format」 正常導覽;抽盤數/複盤數空白視為 0 進貨單 TRRAMA 主檔「分攤完成」欄永遠空白(綁到不存在的欄位) 移除該欄 出貨單 費用分頁 欄位屬性全英文(LineNo_/ImportCostCode/…) 屬性改中文(序號/費用代碼/費用說明/科目代號/客廠部代號/幣別/匯率/原幣未稅/本幣未稅/費用備註/出貨單序號/發票號碼/數量/單位/單價/轉帳款數量/轉出備註/客廠部簡稱/科目名稱),畫面文字不變 2026-08-27 追加:進程式的「檢查結果」(XAML 綁定有、SQL 欄位沒有)
程式 修正前清單 處理 全部 H 程式 Code檢查器誤判: TsDocumentPrefix沒進控件對照表,遞迴走進樣板把內部{Binding Code}當主檔欄位 → 對照表補上進貨單/出入庫單/出貨單 SKU、AmountWithoutTax、Warehouse、Quantity、OtherAmount、ProjectCode檢查器誤判: XxxBinding剝掉字尾後找不到就報 → 改為退回原路徑找,NotMapped/TsSkipCheck 視為存在進貨單 初品單號、初品變更(朝陽專有 view 欄)、是否為成本/進貨單序號/發票號碼/轉出備註…(費用分頁 7+1 欄,7/23 裁決保留)Source 標 [TsSkipCheck](附註明)出貨單 費用格 19 欄 檢查器改由 grid 的 DataManager<T>綁定解析 T(原本拿明細 trsade 型別去找、永遠缺欄);trsafee 全部標[TsSkipCheck](無 server 表)出貨單 ProjectCode/ProjectName/ShipToAddress/TrlimaPkid/員工編號/EmployeeName真死綁定:Source 與兩庫 vw_trsama/vw_trsade皆無 → 移除主檔「專案代號」「送貨地址」「揀貨單ID」三組控件與明細「員工編號/員工姓名」兩欄複驗:進貨單/耗料單/出貨單開窗不再出現「檢查結果」;HarnessSmokeTests 18/18。
2026-08-27 追加:英文 `*Binding` 屬性中文化+「其他查詢」分頁英文表頭中文化
- H 模組六個 Source 的 16 個英文顯示/計算屬性改中文(
WarehouseBinding→隸屬倉庫Binding、CurrencyBinding→幣別Binding、ForeignExchangeRateBinding→匯率Binding、SKUBinding→品號Binding、QuantityBinding→數量Binding、OtherAmountBinding→其他金額Binding、UnitPriceBinding→單價Binding、AmountWithoutTaxBinding→本幣未稅Binding、ImportCostCodeBinding→費用代碼Binding、TotalQuantity/TotalAmountBinding→總數量/總金額Binding),XAML/VM/Bll 引用連動;同名屬性在其他模組的 Source 不在本次範圍。
- 順帶修兩個既有死綁定:
Ratosa.xaml品號/單價欄(原綁SKUBinding/UnitPriceBinding,Source 從無此名)、TrramaAllocation.xaml數量欄(原綁QuantityBinding)。
- ⚠️ 這些欄沒明寫
UniqueName,Telerik 以綁定路徑當鍵:曾按「記憶格式」存過版型的使用者,該欄會回到預設寬度/順序(不崩)。
- 「其他查詢」分頁(SpecialQuery)grid 表頭原為英文字面值(Transaction Code/SourceBin/Lot Num…),改為中文字面值並補
Common/Lang/Xaml/*.json翻譯 key:TrsamaPickingSpecialQuery/TrramaAllocationSpecialQuery/TrramaAPSpecialQuery/StockQuery/Trapply_qSpecialQuery/TrlimaPickingControl/WktompPickingControl/PickingControl(C.總務的 G* 同款不在本次)。
- 「其他查詢」分頁 grid 的欄位綁定原本是英文屬性名而 Source/POCO 早已中文化 → 格子從來空白:89 個綁定接回中文屬性(TrsamaPicking 10/TrramaAllocation 5/TrramaAP 8/StockQuery 4/TrlimaPicking 9/WktompPicking 8/PickingControl 9;同款順修 GtrramaAllocation 5/GtrramaAP 8/SpdataContact 19/WarrantyContent 4),反射驗證 142/142;
PickingControl.xaml的PickedQuanatity拼錯一併修。對照表.claude/tmp/specialquery-binding-fix-report.md。
- 表頭修兩個翻錯:TrramaAP「相關單號」→「參考單號」(綁 參考單號)、「原幣到期金額」→「原幣應收付」(綁 原幣應收付),Shared.json key 同步改名。
- 08-27 續:其餘「其他查詢」表頭 71 筆中文化(廠商聯絡/保固/總務 Gtrapply_q/GUnitPrice/GtrramaAP/GtrramaAllocation/PageHeader/CustomerQuery),Shared.json 補 25 key;Skype/Facebook/pkid 保留。
TWORK_QRY_TRRAMAAPQUERY改寫中文 schema 版並部署(sql/trramaap-query-deploy-20260827.sql,禾久/朝陽 dev 已跑+proc_param 登錄;正式機已跑(2026-08-27));TsControl/Layout/PickingControlDatagrid.xaml/.cs死檔刪除。
- (上列缺口已於 08-27 處理:proc 部署、死檔刪除、兩支表頭中文化。)
2026-08-27 追加:H-15 出入庫查詢 INVBK2 整支移植
- 新程式
INVBK2(禾久選單 H-15 原指向未移植程式,點了跳「程式鍵無法解析」):條件面板(年度月份/起迄倉庫+所有倉庫/起迄品號/不分儲位/不分工程/不分批號/期末不為0)、分頁 1「出入庫查詢」(排序方式 5 選 1、報表選擇彙總/明細、只顯示入出庫數不符;彙總 25 欄+明細 13 欄)、分頁 2「鋼瓶進出查詢」(起迄日期/查詢品號/起迄倉庫;7 欄+17 欄),Excel 匯出;資料走DARB_QRY_INVBK2(派發器 proc_param 已登錄),期初/入庫/出庫/期末/平均量/庫存月數等彙總在 Bll 以 LINQ 實作,逐段對 VFP。
- 新增
LogicBll/H.Inventory/Invbk2/(9 檔)、Invbk2ViewModel/Invbk2ConditionViewModel、Invbk2.xaml/Invbk2Condition.xaml、Common/Lang/Xaml/Invbk2.json;接點ProgramClass.INVBK2、Procedure.DARB_QRY_INVBK2、App.xaml DataTemplate ×2、DIExtension。
- 驗證:對比表
.claude/tmp/invbk2-compare-20260827.mdVFP 185 元素差集 0;單元測試 23/23、真資料對照 3/3(期末恆等式 851 列全過、明細合計與 SP 一致);UIA 禾久開窗查詢:分頁 1 彙總 52 列+明細連動正常,分頁 2 查詢正常。
- 裁決落地(2026-08-27):D3 所有倉庫顯示;D4 入出庫不符=群組 SUM(入庫)≠SUM(出庫);D5 品別/群組代號/說明/單重補值、新增備註/現有數量/總重量移除;D6 新 SP
TWORK_QRY_INVBK2(不動DARB_QRY_INVBK2)回資料別 出貨/加工/其他,sql/twork-qry-invbk2-deploy-20260827.sql(含 proc_param 與_prgpar3023 預設鋼瓶品號)禾久 dev 已跑實查;D7 明細「單號/倉單號」超連結依序號前置碼(lcl_tritem,退路表 RA→進貨單…)跳對應單據並 Seek(GridViewHyperLink新增 InventoryDocumentPrefix 模式,5,592 單號離線路由零錯);D8 分頁 2 預設品號改讀_prgpar3023;D9 明細關聯鍵套用不分儲位/工程/批號替換。UIA 複驗:資料別顯示、超連結點擊跳出入庫單並載入該單。正式機(禾久)已跑(2026-08-27);朝陽無 INVBK2 不裝。
技術
Model/LocalDbContext.cs:補DbSet<Twork_stk_vw_trsafeeSource> Trsafee;formStagingTypes加TrlostTrwkma/TrlostTrwkde。
Model/Source/H.Inventory/TrlostFormStagingSources.cs(新):TRLOST 主檔/明細 staging 薄殼,作法同 rp/zcond/trgama 系。TrlostViewModel、TrlostSave/Edit/Delete改註冊衍生類;Trlost_sBll自有 manager 續用 base。
Twork_stk_vw_invrecdModel/Source:抽盤數/複盤數改string(DB 兩庫皆 nvarchar(24)),*Binding仍為 decimal 供數值欄綁定與差異計算。
Twork_stk_vw_trsafeeModel/Source:屬性中文化+補無參建構子+ImportCostCodeCobPoco/本幣未稅Binding標[NotMapped];Trsama.xaml費用 grid、TrsamaViewModel、TrsamaSave/Delete連動。
Trrama.xaml:移除「分攤完成」標籤與唯讀框(CompletedAllocation無來源)。
TsControl/CheckSqlField.cs:對照表補TsDocumentPrefix;XxxBinding剝字尾失敗退回原路徑;CheckField.SourceType由 grid 的 DataManager 綁定解析,無結果集的 grid 也能依 TsSkipCheck/NotMapped 判定。
LogicBllTests/Harness/HarnessSmokeTests.cs:LocalDbContextEntityTypes()改為連 EF model(OnModelCreating 註冊的 staging 殼)一起讀;baseline 移除 14 筆殼類歷史欠帳。
資料表 ↔ 類別比對(H 模組,禾久+朝陽聯集)
_menum(SCX_STK)→_sheetno全部 18 個 view/table 逐一比對:DB 有、Source 無=0;Source 多出的欄位皆為計算欄(trrade/trsade 代工單價系列、trrama/trsama 合計欄)或 2026-07-23 裁決保留的 trrafee 費用欄。報告:.claude/tmp/h-db-source-compare-20260826.txt。英文殘留:trrama.invoice、trsama/trlima.cino是 DB 本身的英文欄名,保留;EDI/BOL 系 Source(Trsama_bol 等)屬 B2B 交換格式,未動。未處理(待裁決)
- H-15 出入庫查詢
INVBK2:整支未移植,選單為死項;VFP 原碼.claude/tmp/scx_stk/invbk2.prg,需另開移植案。
- H-CY1 廠商庫存表
INV_SP:朝陽專屬程式,禾久畫面出現是 dev-programs.json 開發注入,非客戶問題。
驗證
MSBuild TsERP 0 error;HarnessSmokeTests+DerivedSourceDataManagerTests 18/18;UIA 實機:禾久 H 模組 16 支 sweep(導覽+分頁)零錯誤彈窗、朝陽 11 支 sweep 零錯誤;針對性複驗(
h-verify2.ps1):出貨單四向導覽、盤點單四向導覽、耗料單→加工單→耗料單交叉導覽皆無例外,debuglog 無新增例外。 - H 模組六個 Source 的 16 個英文顯示/計算屬性改中文(
-
08-26 dashboard-progress-streaming ▸
---
title: 儀表板查詢進度條、取消與逐步顯示
date: 2026-08-26
---
儀表板查詢進度條、取消與逐步顯示
使用者可見變動
- 查詢自訂儀表板(含公司/部門/個人)時,畫面先出現版面骨架(每張磚位置、大小、標題都在,內容顯示「載入中…」),資料集每查完一個,依賴它的磚就一批亮起來,不再整頁等到最後。
- 條件面板與儀表板頁頂各有一條進度條+文字:「查詢中 3/8:訂單管理 訂單日期 2025/01/01~2026/08/31(已 4.2 秒)」,步數=實際要打的資料集數(同源合併後)+彙總+渲染。
- 頁頂進度條旁有「取消」:按下不再打後面的資料集,畫面保留上一次結果(條件面板在查詢中會被框架整片停用,所以鈕放在頁面上)。
- 查詢進行中暫不接受磚的鑽取/連動篩選(避免與背景查詢互搶),完成後恢復。
- 靜態匯出 HTML/PDF/排程寄送/設計器預覽維持原本一次渲染,不受影響。
驗證
LogicBll/ViewModel/TsERP 建置 0 error;新增 10 條測試(進度總數、取消後不再打 DB、串流分批、前期依賴、串流結果=一次查詢結果、骨架不打 DB 且磚位一致);全套 1993/1993。runtime 未驗(骨架→亮磚→取消的實際體感由使用者自測)。
-
08-26 dashboard-3tier-myzone ▸
---
title: 儀表板分公司/部門/個人+卡片權限+主選單「個人專區」
date: 2026-08-26
---
儀表板分公司/部門/個人+卡片權限+主選單「個人專區」
使用者可見變動
- 主選單多一個子系統「個人專區」(S):放「個人儀表板」(S-01)與「排程事件」(S-02,自 L.聯絡傳訊移入);權限與其他子系統相同(程式權限表)。「密碼及我的最愛設定」存檔不再洗掉我的最愛 8~10。
- 個人儀表板:第一次開啟自動建立一張空白的個人儀表板並跳出挑卡視窗,之後可隨時按條件面板的「挑選卡片」把卡片庫的卡加進來(進個人版面,可拖排、儲存版面);挑卡視窗的「分類」篩選移到第二排。個人板不限列數:橫向放哪裡就是哪裡,縱向維持既有的上吸(上方沒磚會貼上去)。
- 新子系統「新功能測試」(Y):測試中/新加的功能先集中在這裡——目前放 自訂儀表板(Y-01,原 M-D5)、儀表板設計(Y-02,原 A-155)、公司儀表板(Y-03)、部門儀表板(Y-04);主選單子系統區第三列多一顆鈕。個人儀表板在 S 個人專區。三支儀表板畫面同「自訂儀表板」,下拉只列該類型;舊 M-D5 自訂儀表板改為三類總覽。既有 D0001~D0007 歸「公司」。
- 可見規則:公司板全公司可見(仍受各磚程式瀏覽權);部門板本部門/子部門成員可見;個人板只有本人看得到(既有自建板若之前靠主管關係分享,部署後將縮成只本人;要分享請改成部門板)。
- 儀表板設計:新增「類型」欄(預設個人);選「部門」時使用部門自動帶本人部門且唯讀;「公司」只有系統管理者(Admin)可新增/修改/刪除,非 Admin 看不到公司選項。
- 權限設定新分頁「儀表板卡片」:對選定使用者列出全部卡片,取消勾選=該人看不到這張卡(該磚在儀表板隱藏並自動補位,狀態列提示「有 N 個磚因無卡片權限未顯示」;「新增卡片」也挑不到);有全選/全不選/從其他使用者複製;本分頁自帶儲存鈕。預設全部可看。
- 依賴:
sql/dashboard-3tier-20260826.sql+sql/dashboard-s-subsystem-20260826.sql+sql/subsystem-y-testing-20260826.sql(禾久五帳套)/各自-cy.sql(朝陽,SQL2008 相容)——dev 已跑,正式機待跑;未跑則新選單與 S 子系統不存在。
驗證
TsERP MSBuild 0 error;LogicBllTests 331/331(smoke 含表名 20 字守門);dev 三庫 SQL 冪等跑兩次、實查物件全在;L4 UIA 三輪(CMSA,dev darbnogicsa1):個人專區 S 子系統清單、三入口類型篩選、公司板 Admin 閘與非 Admin 擋存、卡片黑名單(磚隱藏壓實+提醒列、挑卡不列、全選/取消/複製、存 0 列)、首開空白個人板+自動挑卡+挑卡出資料存版面、同名去重、Row 4 版面,全過;修掉 Row4 擠版/複製撞唯一索引(取樣口徑)/全選鈕樣式共用 UIElement 空白/非 Admin 類型欄空白/清單重覆列/欄寬/空板列數 0 疊欄/首開查詢緒。第四輪:子系統下拉「S.個人專區」、鈕「個人專區」過。已知未修(待裁決):空白個人板挑進的磚在畫面上疊在最左欄——既有版面 reflow(
findSlotRight填滿整欄才換欄)的行為,改動會影響所有儀表板各解析度重排。未驗:朝陽庫與正式機、headless 排程、多使用者跨帳號、挑卡視窗分類過濾。 -
08-25 xaml-hardcoded-text-i18n-batch ▸
2026-08-25 56 支畫面寫死文字改走翻譯檔
使用者可見變動
切換語言(英/日/越)時,下列畫面原本固定顯示中文(或英文)的標籤、按鈕、提示文字,現在會跟著語言切換:
- EIS/預測家族:金流預測(含條件)、營運預測模擬(含條件)、生產計劃查詢(含條件)、每日報表(Daily)、Itemship、庫存樞紐條件、自訂查詢面板(條件/匯出選擇/彙整列印選擇/匯出項目設置)、自訂儀表板條件
- 系統設定:儀表板設計、自訂面板配置、系統設定頁(SettingView)、登入頁的 Windows 驗證勾選
- 各模組零星標籤:Ormast_s、拜訪查詢、採購查詢條件、Ginvent/Ginvrecm/Gpurch/Gtrlima/Ginvbook 條件、BOM 流程圖、Ci_m1、廠商統計、Cupdma_cy、達交率列印、送貨地址、預示樞紐輸入、SPEVA 列印、庫齡(含條件)、ARAP 查詢(含條件)、移動成本、專案成本、信件搜尋(含條件)、Trlost/Trsama/Trlima/Bol/Inv_sp、Abook1 條件、Ticka_m、MRP 條件、Pdtinf、Invstk 條件、TableSchema/TableSetting 條件/Library 查詢條件
- 原本英文介面的畫面(Ormast_s、Daily、SettingView 的 Save/Exit)改為依語言顯示,中文語系下會看到中文。
- 標籤尾隨的冒號一律拿掉(與其他頁面一致)。
翻譯來源:
Common/Lang/Xaml/*.json新增 26 檔、追加 24 檔,共約 480 個 key;英/日/越譯文為機器初稿,發現不妥可直接改 JSON 不必動程式。未變
- 系統外殼(ERPSystemContainerView 頁籤、主選單 MenuView)走另一套固定屬性翻譯,本次未動。
- 報表預覽視窗、Doc Explorer、關於我、測試面板等 Window 型視窗本次未動。
- 已無人引用的舊變體畫面(
*_zd/*_US/*_old/日期戳版)未動。
-
08-25 spdata-abook2-tab ▸
2026-08-25 廠商資料表(SPDATA)新增「索引分類帳」分頁
使用者可見變動
- 廠商資料表多一個「索引分類帳」分頁,位置在「信件搜尋」之前。行為與客戶資料表的同名分頁一致:
- 只有具備 ABOOK2(索引分類帳)瀏覽權限的使用者看得到這個分頁。
- 切入分頁自動帶入條件:索引種類=客戶或廠商代號、索引起迄=目前廠商代號、期間預設當月;不自動查詢,按「查詢」才查。
- 廠商代號空白(新增中/沒有資料)按查詢會提示「廠商代號空白,無法查詢索引分類帳」並不查;索引被清空時自動補回目前廠商再查。
- 客戶資料表的索引分類帳分頁行為不變(實作改為兩邊共用同一套)。
技術備註
- 共用基底
ViewModel/N.GeneralLedger/Abook2HostViewModel;CudataAbook2HostViewModel/SpdataAbook2HostViewModel只提供代號。
- App.xaml 版面抽成
Abook2HostTemplate共用,兩個型別各掛一個 DataTemplate。
- Lang:
Spdata.json/Cudata.json補「索引分類帳」key。
-
08-25 pk-public-fixes ▸
---
title: PACKING LIST 兩家共用修正:單箱材積漏除 1000000、匯入鈕派發靜默失效
date: 2026-08-25
not_in_nav: true
---
PACKING LIST 兩家共用修正
適用:所有中文 schema 帳套(禾久、朝陽…)。
1. 單箱材積算成 100 萬倍(`Twork_ord_vw_pkdeSource.SetVolume()`)
- 問題:公版手改箱長/箱寬/箱高時的材積公式漏了
/1000000(公分→立方公尺),算出的立方呎是正確值的 10^6 倍並寫進pkde.單箱材積。
- 證據:禾久與朝陽 VFP 原碼皆有
/1000000;朝陽 DB 實資料 5/5 筆吻合帶除法算式;同 repo 姊妹程式 RTAXMA(RtaxdeSource)同式本就帶除法。
- 修正:補
/ 1000000m(一行);測試對點 100×100×116→40.97、120×100×102→43.23、500×600×500→5297.21。
- 歷史資料:禾久
pkde箱長>0 為 0 筆、朝陽資料為 VFP 寫入——dev 庫無需回補;正式機若有人用新版手改過尺寸,單箱材積可能是錯值,需抽查。
2. 匯入鈕(出通單/CI)從未能用(`Twork_qry_pk`)
- 問題:派發
TWORK_QRY_PK(四庫皆無此 SP、proc_param 未登錄→派發器靜默不執行);POCO 英文屬性對不上中文欄;型別錯配會丟例外;讀Tables[1]對朝陽 1 表形狀越界;查詢別寫死 11 而朝陽 SP 只有 1/2。兩家的DARB_QRY_PK是兩支不同 SP(禾久:查詢別 11 回 2 表;朝陽:1 出通單/2 CI 各回 1 表)。
- 修正:派發名改
DARB_QRY_PK;依回傳表數判形狀(0 表才 fallback 查詢別 2);POCO 中文化+型別對 SP;SetData只覆寫 SP 有回的欄(不洗使用者已填值);meas 取紙箱尺寸(朝陽)。測試 15 案。
- 使用者可見:禾久/朝陽的「匯入」開始有資料(原本恆空)。
- 未驗:runtime 兩家皆未開窗按匯入;正式機 SP 版本與 proc_param 需抽查(
darbcmacsa1只有查詢別 1、darbzdcsa1無此 SP)。
3. 匯入的尾數箱毛重偏高(`Twork_qry_pk.GetPkde`)
- 問題:尾數箱(不足一整箱的最後一列)的單箱毛重用了整箱列的淨重+箱重,而非尾數箱自己的淨重+箱重(禾久 VFP :1956/朝陽 :2520 都是後者)。例:整箱淨重 7/毛重 7.8、尾數 500 件淨重 3.5 → 應為 4.3,修前算 7.8。
- 修正:一行改用尾數列淨重(
GetPkde依賴 Source 的 Context 反查,無法純單元測試;證據為兩家 VFP 原碼,runtime 未驗)。
4. 存檔時 CI單號 重複檢查(`PkSave.AllowSave`)
- 問題:VFP 兩家 cino 控件都有
is_noduplicate="pkma",新版只有輸入側框架檢查(該欄被編輯過才觸發;複製新增沿用原 cino、匯入帶值都不經過),存檔側沒有背書。朝陽側 WP3 已先補在Pk_cySave。
- 修正:上提到公版
PkSave.AllowSave,兩家同套;同 cino 且不同 pkid 存在時擋下「CI單號 資料重複」。
相關:changelog
2026-08-25-pk-cy-screen-fork.md、memoryorder-module-union-align。 - 問題:公版手改箱長/箱寬/箱高時的材積公式漏了
-
08-25 pk-e-check-window-and-extend-button-fix ▸
---
title: 朝陽變體程式其他功能鈕消失修復+裝箱單「查核」視窗
date: 2026-08-25
---
朝陽變體程式其他功能鈕消失修復+裝箱單「查核」視窗
使用者可見變動
兩家共用(框架)
- 朝陽所有走變體鍵的程式(訂單管理/出貨通知單/客戶報價單/PACKING LIST/客戶資料表/BOM…)右側「其他功能」鈕整排消失 的問題修復:登入時權限列被改寫成變體鍵(
PK→PK_CY)後,其他N說明字典用原鍵查不到 ⇒ 一顆鈕都不建。現在變體鍵查不到會退回母鍵(LogicBll/銜接/ExtendFunctionKeyResolver)。朝陽 dev 實測 PACKING LIST 重新出現 修增/查核/合併/標籤新增/設定棧板/其他報表/條碼 七顆(未實作的呈灰色停用)。順帶補上原本漏抄的「其他9說明」。
- 禾久不受影響(不走變體鍵)。
朝陽 PACKING LIST(Pk_cy)
- 新增其他功能「查核」(VFP 子表單 PK_E):唯讀彈窗「出貨查核視窗」,依品號並排 PK 數量(單箱數量×箱數彙總)與出貨倉單數量,多加「差異」欄(非零紅字)。每次查詢先清空(修 VFP 連按累加);一張 CI 對到多張倉單時全部合併;出貨倉單號/CI單號可手改。
- 已知限制:
SE-新制單號自動帶出貨倉單號在 dev 資料上幾乎全空(pkde.交易單pkid多為 0),要在朝陽正式機再驗;目前多靠手 key 倉單號。
驗證
單元測試 23/23(含 ExtendFunctionKeyResolver 4、PkCyCheckRules 11、smoke 8);MSBuild 0 error;朝陽 dev UIA:開窗→按查核→查詢→連按不累加→離開,全過(
.claude/tmp/pk-e-verify-log.txt);fresh-context 對抗審查 🔴1(BasedOn)🟡4 🟢4 已處理或記錄。 - 朝陽所有走變體鍵的程式(訂單管理/出貨通知單/客戶報價單/PACKING LIST/客戶資料表/BOM…)右側「其他功能」鈕整排消失 的問題修復:登入時權限列被改寫成變體鍵(
-
08-25 pk-cy-screen-fork ▸
---
title: 朝陽 PACKING LIST(Pk_cy)畫面對齊朝陽 VFP:欄位/計算鈕/重排序號/cino 反查/匯入
date: 2026-08-25
not_in_nav: true
---
朝陽 PACKING LIST(Pk_cy)畫面對齊朝陽 VFP
適用:朝陽(CY)帳套
PK_CY。禾久與其他帳套畫面不受影響(共用Pk.xaml/PkSave未動;PkEdit只抽 virtual 掛點)。ADR 0142 第二支。使用者可見變動(朝陽)
畫面(原本是禾久版複本)
- 移除 15 項朝陽沒有的欄位/按鈕:主檔 ci日期、轉退稅註記(朝陽 DB 無欄)、幣別、總金額、後置文字、起始箱號、「依序號排箱號」鈕;明細 不足箱、後置文字、包裝量_箱(朝陽 DB 無欄)、數量、單價、毛重、淨重、材積、廠商代號、交易單pkid、庫存單箱數量。
- 補回明細 5 欄:棧板長/棧板寬/棧板高/棧板別/單板材積;明細 36 欄改照朝陽 VFP 欄序,固定欄寬。
- 明細新增兩顆計算鈕欄:「計算材積」(箱長×箱寬×箱高 → 單箱材積,立方呎)、「計算單板材積」(棧板尺寸 → 單板材積+棧板尺寸字串);只在新增/修改/複製模式可按。
- 截止棧板號輸入後自動算棧板數(截止−起始+1,照 VFP 不防呆)。
- 箱長/箱寬/箱高改為純輸入(照朝陽 VFP:只有按鈕才重算材積,不再每次改尺寸自動算)。
- 修改閘門:朝陽不檢查「轉退稅註記」(朝陽 VFP 無此檢查、DB 無此欄;原公版會靜默空轉)。
行為對齊(WP3/WP4)
- 重排序號鈕(依前置文字/起始棧板號/起始箱號/客戶訂單號)、cino 三段反查帶值(含 POLARIS→商品名稱、A07→前置文字 CY)、cino 重複檢查。
- 匯入鈕改成兩顆(照朝陽 VFP):「匯入出通單」(以 CI單號 欄的值當出貨通知單號查 salema)與「匯入CI」(查 ci_m/ci_d,並帶入 ci_m 的頁首備註/頁尾備註/正嘜);兩顆只在新增態且 CI單號 非空可按。
- 匯入明細照朝陽規則展開:單箱數量=包裝量_箱(0 時改用 包裝量)、MEAS=紙箱尺寸、合約號碼=reqno(CI 為空)、尾數箱序號續編不加 'A'(訂單量不足一箱時整箱列仍佔一個序號,照 VFP 留空號)、商品名稱為 POLARIS 時箱號從同年度最大截止箱號續編、匯入後補 20 列空白列供手動輸入(存檔時空品號列自動略過)。
- 匯入後右側總箱數/總淨重/總毛重/總材積/總數量立即重算。
- 查無時提示「查無此出貨通知單號碼 !!!」/「查無此CI號碼 !!!」;派發失敗(SP 未部署等)改跳「匯入失敗:…」而非靜默無反應。
- 匯入 CI 帶不到單價(朝陽 SP 不回):存檔時若有明細單價為 0,跳「明細有 N 列單價為 0(序號…),是否繼續存檔?」確認,選否則不存檔(畫面無單價欄,故為確認而非擋死)。
- 與 VFP 刻意不同(皆 VFP 殘值,禾久 VFP 與公版皆已改):整箱列數量=單箱數量×箱數(VFP 為總數量,與尾數列相加會超量);尾數列淨重/毛重=該列單箱值(VFP 沿用整箱列的值);匯入後不清空畫面前置文字。
兩家共用修正(同日另列)
- 公版
SetVolume()漏/1000000(手改箱尺寸時單箱材積 100 萬倍)已修——見2026-08-25-pk-public-fixes.md。
- PACKING LIST 匯入鈕
TWORK_QRY_PK派發靜默失效已修——同上。
本輪不做(停放)
- 條碼檢查兩分頁(page4/page5):朝陽 dev 庫缺
混板棧板號欄,待正式機 DDL 確認。
- 五支子表單(修增/標籤新增/查核/合併/設定棧板/條碼):VFP .scx 原始碼待匯出。
- 表頭字面(
長/寬/高(箱;棧板)、備註(交貨地點)、合約號碼(BIT,REQNO))暫維持新版,改 JSON 顯示值即可。
- 單價 0 確認選「否」後,改顯示「存檔已取消(明細單價為 0)」(原本會把提問原句再彈一次,08-25 朝陽 dev 實測抓到後修正)。
- 新增態右側五項合計(總箱數/總淨重/總毛重/總材積/總數量)改為歸零(原本停在上一張單的數字;公版
PkViewModel.AfterAddNew補Refresh(),禾久一併受惠,純顯示不進 DB)。
- 明細「品號」欄寬 125→150、「客戶品號」140→180(原寬度會把
36100-A5L-1002-A1靜默截成…-A;pkde 客戶品號 >16 字者 619/44882 筆)。
驗證狀態
建置 0 error;單元測試全綠(PkCy 六組+PkQry+smoke 87/87);各工作包 fresh-context 綁定核對+對抗審查。
2026-08-25 朝陽 dev(darbcycsa1)UIA runtime 驗訖兩輪(腳本
.claude/tmp/pk-cy-verify.ps1,logpk-cy-verify-log*.txt,截圖shots/pkcy*):開窗、既有單載入(A07 前置文字 CY、棧板欄、計算欄)、錯誤 cino 擋下、出通單/CI 反查帶客戶、匯入出通單(2 筆展開 3 列+20 空白列,總箱數 17/總數量 6300)、匯入CI(ci_m 三備註帶入、2 列)、重排序號、重複 cino 存檔擋下、單價 0 YesNo 選否不存、取消復原;DB pkma 筆數前後不變。第三輪(修正後)加驗:新增態合計歸零、客戶品號完整顯示、grid 內填箱長寬高按「計算材積」→單箱材積 2.12(總材積同步)、填棧板長寬高按「計算單板材積」→單板材積 34.96/棧板尺寸 110*100*90、匯入列右半欄(訂單編號 CO2026400178/預訂交期 2026/04/22)。fresh-context 審查報告
.claude/tmp/pk-cy-runtime-review-20260825.md(15 項通過、🟡3 已修/已補驗、🟢2 為共用控件既有行為另案)。未驗:實際存檔寫入(兩道閘門皆擋下、刻意未寫庫)、POLARIS 續號(dev 無樣本)、棧板數(截止棧板號未填)、禾久側公版匯入(禾久 dev 無 ci_m 明細與 pkma 資料)、朝陽正式機(SP 欄位型別存證仍待做)。
-
08-25 pk-barcode-window-and-tabs ▸
---
title: 朝陽 PACKING LIST 條碼檢查視窗+兩個條碼分頁(CyPdfCheck 內建化)
date: 2026-08-25
---
朝陽 PACKING LIST 條碼檢查視窗+兩個條碼分頁
使用者可見變動(朝陽)
- 主畫面明細改成三個分頁:明細/條碼檢查/混板條碼檢查(後兩者為
pkbarcode1唯讀呈現,對應 VFP page4/page5)。明細分頁內容與欄位設定完全不變。
- 其他功能新增「條碼」(VFP 子表單 PK_BARCODE):檢查條碼視窗——公司選擇(YMMC/TYM/YJBM/YJBM更新側嘜/YMMC混板側嘜)、混板棧板號(預設帶明細的棧板號 CSV)、「手動掃描」產生預期 P/K/V/S/Q 五段條碼清單(已存過批次則載入既有批次)、掃描槍逐槍檢核(行位/內容錯誤訊息照 VFP 原句)、五段全對
檢查=OK、全選/取消全選、儲存(只存勾選列、整批同一唯一碼;trigger 自動汰換同 CI 舊批次)。
- 「選PDF」改為 ERP 內建:選標籤 PDF → 逐頁抽內嵌圖 → 解 CODE128(品號)/CODE39(P/K/V/S/Q)→ 直接餵進清單。不再需要
C:\TEMPS\CYPDFCHECK\Cypdfcheck.EXE與 DBF。
- 混板路徑需
pkbarcode1.混板棧板號 nvarchar(100)(sql/pkbarcode1-add-mixed-pallet-cy.sql,dev 已套;正式機待跑)。
- 裁決:0 筆勾選存檔擋下「未勾選任何條碼列,無法存檔 !!!」(VFP 會清空舊批次);公司選擇 4 箱號恆 0 照抄(程式註 TODO);全選/取消全選在產生清單後可用。
驗證
單元測試 47/47(規則 R-1~R-4 逐條具名案例+PDF 解碼分類)+PkCy 回歸 92/92;MSBuild 0 error。朝陽 dev UIA:三分頁(
SE-20260002925 列 OK)、開窗、手動掃描載入 25 列、模擬五槍掃描、取消全選→儲存被擋零寫入、全選存檔整批汰換(trigger 生效、筆數不變、唯一碼更新)、離開。未驗:真實標籤 PDF 解碼、真掃描槍、混板(公司選擇 5)實資料、正式機。- 修正:套
BtnSelectAll/BtnUnselectAll樣式的鈕在本彈窗不可見(功能正常),改自組 Image+文字;該樣式在其他頁面(Odtosl/Ci_m1/DeletePassNumber)是否同樣不可見待查。
- 對抗審查修正(08-26):勾選欄可手動點(grid 整張 IsReadOnly 改逐欄);五段碼生成前照 VFP cursor 欄寬截斷(P/K/Q 15、客訂單箱號 20、SRNO 21、品號 30,+8 測試;
pk_p1列印端是否同寬待確認);裝箱明細補回DARB_RPT_PK的 cudata/invent/codata 過濾語意(EXISTS 版,dev 44,872 筆與 SP 一致);產生清單後焦點回掃描框;新增態兩個條碼分頁清空;無單據(Empty)時按條碼/查核改跳「尚未選擇單號」訊息;單箱數量 numeric 改四捨五入。UIA 複驗:勾選單擊 On→Off、焦點在掃描框、新增態分頁 0 列、0 筆存檔擋下。
- 待裁決:VFP 第二段 SCAN 的
前置文字memvar 殘留(整張單 S 段用最後一列的前置文字)新版改逐列用自己的;grid 表頭沿用 VFP 英文字面(P_CODE 等)。
- 主畫面明細改成三個分頁:明細/條碼檢查/混板條碼檢查(後兩者為
-
08-25 invent-statistics-i18n-and-todolist-header ▸
2026-08-25 庫存主檔統計分頁文字補翻譯+待辦清單「核准」欄改「審核」
使用者可見變動
- 庫存主檔(INVENT)→ 統計分頁:表格內「檢視」按鈕與「內容」欄超連結的提示文字「開啟對應程式並跳到這一筆」原本寫死中文,切換語言不會跟著變;現在改走翻譯檔(
Shared.json_Common新增「開啟對應程式並跳到這一筆」一組四語)。客戶資料表(CUDATA)統計分頁同一句提示文字一併改走翻譯。
- 待辦清單(TODOLIST):五個分頁(本人/代理人/直接下屬/間接下屬/已審核查詢)表格的「核准」欄表頭一律改名「審核」,與旁邊的「快速審核」欄及審核視窗名稱一致。翻譯檔
TodoList.json已有「審核」條目,各語言顯示不變。
範圍
TsERP/D.Bom/InventStatistics.xaml、TsERP/E.Order/CudataStatistics.xaml、TsERP/Z.System/TodoList.xaml、Common/Lang/Xaml/Shared.json。
- 沒有動資料表、沒有動行為;純顯示文字。
- 庫存主檔(INVENT)→ 統計分頁:表格內「檢視」按鈕與「內容」欄超連結的提示文字「開啟對應程式並跳到這一筆」原本寫死中文,切換語言不會跟著變;現在改走翻譯檔(
-
08-25 invent-drawing-to-engineering-tab ▸
2026-08-25 庫存主檔(INVENT):工程圖檔搬到「工程」分頁、取消圖片預覽、開檔超連結加權限閘
使用者可見變動
- 「基本」分頁的「圖檔」群組:只剩「圖檔名稱」與產品圖預覽;原本並排的「工程圖檔」欄與工程圖預覽(圖片/PDF 檢視器)已移除。
- 「工程」分頁的「工程文件」群組:最下方新增「工程圖檔」欄(路徑選檔框,與原本同一個欄位、存檔行為不變:選本機檔會複製進數位圖庫
Drawing資料夾、存相對路徑)。
- 「開啟圖檔」超連結:在工程圖檔欄右側,只有權限表(
_menu使用者權限列)「備註」欄含「工程圖檔」字樣的使用者才看得到;點了用系統預設程式開啟圖檔。沒有此備註的使用者仍看得到、改得了路徑欄,但沒有開檔連結、在唯讀狀態雙擊路徑欄也不會開檔(控件新增AllowOpenFile屬性;其他頁面預設不變)。
- 工程圖檔不再做圖片/PDF 內嵌預覽(使用者裁決)。
- 開檔方式改變(全系通用):所有「開檔案」的超連結——雙擊路徑欄、「開啟圖檔」連結、BOM 流程圖卡片開圖/影片、數位圖書館檔案總管開檔、圖書館/聯絡單附件開啟、庫存主檔(E)附件、郵件範本附件、外部資料檔案——一律先把檔案整個讀進記憶體、寫到本機
C:\Temps\OpenFile\<檔名>_<雜湊>.<副檔名>再開啟副本。原檔(網路圖庫)不會被外部程式鎖住,開啟後在程式裡改到的是副本;同一檔重開不重複落地;每次開檔前自動清掉該資料夾內前一天以前的副本(當天的保留)。
影響範圍
- 只影響公版
INVENT畫面(InventTab1/InventTab2);Invent_prime/Invent_zd/Invent_bs變體本來就沒有工程圖檔欄,不受影響。
- 資料表、view、存檔邏輯(
InventSave)皆未變。
設定方式
- 要讓某使用者看得到「開啟圖檔」連結:在該使用者 INVENT 的權限列「備註」欄加上
工程圖檔(與既有「真實成本」「單價」等備註開關同一機制,可並列)。
-
08-25 grid-auto-datetime-format ▸
2026-08-25 表格自動產生欄:日期時間統一顯示 yyyy/MM/dd HH:mm:ss
使用者可見變動
- 所有自動產生欄位的表格(資料瀏覽器、清單瀏覽、查詢結果等
AutoGenerateColumns的畫面),DateTime 型別欄一律顯示yyyy/MM/dd HH:mm:ss、置中。原本沒有指定格式,交給系統文化預設,會出現「2026/8/25 下午 03:00:00」這類不齊的寫法。
- 各維護程式 XAML 明寫的日期欄(
TsGridViewDataDateColumn,預設yyyy/MM/dd)不變(使用者裁決:只調自動產生欄)。
技術備註
TsControl/TsTelerik/TsRadGridHelper.ApplyColumnStyle新增 DateTime/DateTime? 分支,格式常數AutoDateTimeFormat。
- 欄寬仍由版型存檔/Auto 決定;帶秒後約需 150px,若某瀏覽窗已「記憶格式」存了舊欄寬,需重設一次。
- 所有自動產生欄位的表格(資料瀏覽器、清單瀏覽、查詢結果等
-
08-25 dashboard-table-amount-local-currency-decimals ▸
2026-08-25 自訂儀表板:表格磚金額欄改依本國幣小數位顯示
使用者可見變動
- 自訂儀表板(DASHBOARD)表格磚的金額欄(單價/金額/本幣/未稅/含稅/成本/價/amount/price,或設計者在磚上指定的「金額欄」)改依本國幣的小數位顯示——台幣為 0 位。原本照資料庫欄位的小數位,
numeric(18,4)的金額會印出 4 位小數。
- 數量、重量等非金額欄不變,仍照資料庫小數位。
- 查不到本國幣小數位(幣別主檔沒該幣別)時維持原行為。
- KPI 卡與圖表磚不在此次範圍(KPI 沿用磚設定的小數位)。
技術備註
DashboardAggregator.Table新多載帶isAmountColumn+金額小數位;顯示字串新多載帶固定小數位。舊多載行為不變。
DashboardQueryEngine:Lazy<int?>一次查OpenDbfTable.GetDecimalPlaces(Env.LocalCurrency);測試建構子為 null。
- 金額欄判斷共用
DashboardPermissionGate.IsAmountColumn(與看單價遮蔽同一套)。
- 自訂儀表板(DASHBOARD)表格磚的金額欄(單價/金額/本幣/未稅/含稅/成本/價/amount/price,或設計者在磚上指定的「金額欄」)改依本國幣的小數位顯示——台幣為 0 位。原本照資料庫欄位的小數位,
-
08-25 dashboard-remove-dept-card ▸
2026-08-25 儀表板卡片庫移除「部門受訂金額佔比」
使用者可見變動
- 自訂儀表板/儀表板設計的挑卡清單不再有訂單類卡片「部門受訂金額佔比」(
ORMAST_部門受訂佔比)。卡片庫由 204 張變 203 張。
- 已放進個人版面的該卡(若有)會因卡片定義不存在而不再顯示;公版 D0001~D0007 本來就沒放這張卡。
原因
該卡是
vwbd_ormast.業務部門欄的唯一用途;正式機部署時決定不修改共用檢視vwbd_ormast,改為直接拿掉卡片。範圍
LogicBll/M.EIS/Dashboard/Cards/ORMAST.json(刪一張卡)、sql/dashboard-cards-deploy-20260820(-cy).sql(種子重產)。
- 新增
sql/ormast-dept-card-remove-20260825.sql:刪卡片列+把曾加過業務部門欄的vwbd_ormast還原成原始定義(正式機不需要)。
sql/ormast-view-add-dept-20260821(-cy).sql作廢。
- 自訂儀表板/儀表板設計的挑卡清單不再有訂單類卡片「部門受訂金額佔比」(
-
08-25 dashboard-hscroll-fixed-bottom ▸
2026-08-25 自訂儀表板(DASHBOARD):水平卷軸固定在視窗最下面
使用者可見變動
- 互動模式(ERP 內檢視/編輯)的磁貼格區改為自己捲動:欄數超過視窗寬時,水平卷軸永遠貼在視窗底部,不必先把頁面捲到最底才摸得到;頁首、工具列、分頁列固定不動。
- 舊版「不限列數」的儀表板改在格區內縱向捲動(原本整頁捲)。
- 列數自動推算時預留一條水平卷軸的高度,欄數超寬時不會多出一條小小的垂直卷軸。
- 匯出 HTML(靜態)、行動版與列印/PDF 版面不受影響。
技術備註
DashboardHtmlWriter在<body>加穩定的data-shell屬性(data-mode會被setMode改成 view/edit,不能當 CSS 鉤子)。
DashboardHtmlCss:body[data-shell="interactive"]→.wrap → .page-host → .page撐滿 100vh 的 flex 鏈,.grid{flex:1;min-height:0;overflow:auto};@media print全數還原成 block/auto。
DashboardHtmlScript.fitUnit:可用高度- 18。
- 驗證:LogicBllTests Dashboard 全組+smoke 284/284;Chrome 以模擬 900×520 視窗實看,水平卷軸貼底、頁首固定。
-
08-25 cusp-price-dispatch-fix ▸
---
title: 客戶單價查詢(Twork_biz_cusp_price)派發修復:查詢價格/自動帶價不再靜默回空
date: 2026-08-25
not_in_nav: true
---
客戶單價查詢派發修復
適用:所有中文 schema 帳套(禾久、朝陽…)。受影響功能:客戶報價單「查詢價格」側邊面板(公版)、RATOSA/TRSAMA 自動帶價、預示表樞紐輸入/年度預估的品號帶價。
問題
Twork_biz_cusp_price整支經派發器呼叫TWORK_BIZ_CUST_UNITPRICE,但中文帳套的 SP 叫DARB_BIZ_CUST_UNITPRICE(TWORK_版只存在振德的英文 schema 帳套)。派發器DARB_LOG_SYS_EXEC查proc_param查無登錄就靜默不執行,回空、不報錯;加上 POCO 屬性是英文名而 SP 回中文欄名,即使登錄了也整排空白。結果:上述功能在中文帳套從來沒有帶出過價格。修正
- 派發名改
DARB_BIZ_CUST_UNITPRICE(兩客戶 log 庫已登錄,qty=4,參數序 @查詢別/@客戶代號/@品號/@日期)。
- 三個查詢別 POCO 屬性改中文=SP 欄名(補 匯率單號/單重/最低訂單量),並以
[TsColumnName("英文欄名")]備援英文 schema。
- 查詢別 4 依回傳表數判形狀:禾久 2 表(訂單最新+報價全部)、朝陽 1 表(只含報價),不寫死帳套。
- 9 個呼叫端與
CupdmaSpecialQuery.xaml15 欄同步改中文屬性名;行為不變。
- 測試
CuspPriceTests14 案(假連線、走真實產品方法)。
使用者可見變動
禾久/朝陽帳套的「查詢價格」側邊面板與自動帶價功能開始有資料(原本恆空)。
停放(待裁決)
1. 禾久帳套 SP 無查詢別 5/6 分支:RATOSA/TRSAMA 走查詢別 5 的自動帶價在禾久仍回空(SP 層缺口,非程式)。要補分支屬業務裁決。
2. runtime:禾久 CUPDMA「查詢價格」側邊面板 2026-08-25 實機驗訖(QN20260040 → 訂單最新 1 筆+報價 3 筆,修復前恆空);RATOSA/TRSAMA 帶價尚未開窗驗。
3. 禾久 SP 查詢別 5/6 已照朝陽版補入(
sql/darb-biz-cust-unitprice-add-qt56-20260825-nogi.sql,dev 實查訖;-nogi-prod.sql正式機待跑)。注意 5/6 照朝陽帶已審核='Y',禾久未審核報價(dev 516 筆)不會被自動帶價——若要放寬需另開新檔。(振德環保帳套為英文 schema,本系統派發器寫死
DARB_LOG_SYS_EXEC,振德在派發器層本就不可達且會明確報錯——本次改名與它無關,不列風險。)相關:memory
cusp-price-dispatch-silent-empty、dispatched-proc-param-qty-gotcha。 - 派發名改
-
08-25 cupdma-cy-screen-fork ▸
---
title: 朝陽客戶報價單(Cupdma_cy)畫面對齊朝陽 VFP:比價表/歷史報價/回傳/From Excel
date: 2026-08-25
not_in_nav: true
---
朝陽客戶報價單(Cupdma_cy)畫面對齊朝陽 VFP
適用:朝陽(CY)帳套的客戶報價單
CUPDMA_CY。禾久與其他帳套畫面不受影響(共用Cupdma.xaml/CupdmaSave未動;CupdmaViewModel只加 virtual 掛點)。ADR 0142。使用者可見變動
畫面(原本是禾久版複本)
- 移除 14 項朝陽沒有的欄位:主檔 業務員編號、製表人員、叫修單號、活動起始日、活動截止日、預計結案日、實際結案日(朝陽 DB 無欄)、報價別、報價備註;明細 中文描述、規格、客戶價(朝陽 DB 無欄)、金額。
- 報價人員還原為獨立欄(原被併成業務員查詢的附屬描述);補回 聯絡單id(唯讀)。
- 明細 23 欄欄序改照朝陽 VFP(客戶品號移到第 2 欄…共 16 位變動,欄位集合不變);全部欄位固定欄寬(依 DB 實測長度)。
- 新版側邊「取價」分頁移除,改為畫面內 客戶比價表 grid2(照 VFP 欄序,含「回傳」鈕欄)。
客戶比價表(grid2)
- 「查詢價格」列出其他客戶對同品號的已審核報價(本客戶排除),附 類別=2.報價、本國報價(單價×匯率,本位幣小數位)。
- 「回傳」:品號與幣別都相符才把該列的客戶品號與單價填回明細列,不符提示「品號或幣別不合」。
歷史報價分頁
- 瀏覽單據時自動列出本客戶各品號的全部歷史報價(一次批查整單,同客戶連續換單不重查);編輯時選品號/換列即同步顯示該品號歷史。
- 查到資料才展開分頁;新增單據時清空。
- 不會自動覆寫明細單價(VFP 該段 2016 年已註解)。
行為對齊(WP4)
- 客戶品號反查加生效/失效日期篩選與擋下(客戶代號空/查無)。
- 品號欄「待補」淺紫底。
- 「From Excel」匯入:檔案選擇對話框(預設
C:\轉EDI資料),17 欄對映、序號重編、空列優先覆寫、匯入後品號補值/失效清空;匯入期間不逐列彈窗。
- 編輯模式自動切到歷史報價分頁(VFP changeopmode)。
部署
無 SQL 部署(所用 SP 皆已登錄)。程式隨下次發版。
刻意偏離 VFP(請過目)
- 客戶品號對照全部失效時照 VFP
GO BOTTOM仍帶出最後一筆品號、不擋不提示不轉紫底(只有「查無」才擋)——是否改成「全失效視同查無」待裁決。
- From Excel 匯入前新增「客戶代號必填」擋下(VFP 無;無客戶代號無法反查)。
- 客戶品號反查失敗不扣住焦點(WPF 無等價機制),改以紫底提示;歷史報價分頁查到才展開;匯入數量四捨五入(VFP 語意)而非截斷。
已知未做/停放
- 聯絡單id 顯示口徑(07-22 曾裁決訂單「系統欄移除」,朝陽 VFP 報價單有此欄——暫照 VFP 顯示)。
- CY 正式機
DARB_BIZ_CUST_UNITPRICE查詢別 4 版本需與 dev 同(dev 回單一 result set)。
- 集中式審核是否回寫
cupdma.已審核='Y'——否則比價表與歷史報價恆空(不報錯)。
- 另案線上缺陷:
Twork_biz_cusp_price走未登錄 proc → 禾久 RATOSA/TRSAMA 自動帶價、公版 CUPDMA 查詢價格靜默回空(memorycusp-price-dispatch-silent-empty)。
驗證狀態
建置 0 error;單元測試 100/100;四個工作包各經 fresh-context 綁定核對+對抗審查並修正。
朝陽模擬實機(2026-08-25)驗訖:開窗、主檔(客戶名稱全名/報價人員/聯絡單id/殘留欄消失)、明細 23 欄 VFP 欄序、歷史報價分頁自動展開有資料、客戶比價表(排除本客戶)有資料。未驗:回傳鈕回填、編輯態流程、From Excel、客戶品號反查/紫底——清單見
.claude/tmp/cupdma-cy-fork-plan-20260825.md。 -
08-25 cudata-abook2-blank-customer-guard ▸
2026-08-25 客戶資料表(CUDATA)索引分類帳分頁:客戶代號空白不能查
使用者可見變動
- 客戶資料表「索引分類帳」分頁按「查詢」時,若目前客戶代號空白(例如新增中尚未輸入代號、或目前沒有任何客戶資料),會跳出「客戶代號空白,無法查詢索引分類帳」並不執行查詢。
- 若條件面板的索引起迄被清空,按查詢時會自動補回目前客戶代號再查,不會變成查全部客戶。
動機
索引範圍跟著客戶代號走;代號空白=索引空白=查全部客戶的分類帳,既慢又越權。
-
08-24 prodplan-save-document ▸
2026-08-24 生產計劃查詢:存成生產計劃單+歷史單分頁
程式:生產計劃查詢(M.主管資訊 ›
PRODUCTIONPLAN)。設計取捨見 ADR 0140。使用者可見變動
- 結果區頂端新增「備註」欄與「存成生產計劃單」鈕:按下後把這次查詢的條件、匯率表、客戶設定、訂單預示預估、生產計畫、使用量存成一張單據,單號格式
PP20260824001(PP+日期+3 碼流水),存好後彈出單號。查詢本身不會自動存,要留版本才按。
- 新增「歷史單」分頁:依單據日期起訖(預設近一年)列出已存的生產計劃單(單號、條件、備註、筆數、輸入人員),每列可「載入」或「刪除」。
- 載入歷史單後,畫面上方顯示「目前顯示:歷史單 PPxxxxxxxx」,條件與匯率表一併還原;金流預測分頁清空並提示「歷史單不重算」(它是當下帳款快照的計算,不屬於計畫)。重新按查詢即回到即時模式。
- 沒有查詢結果時按存檔會被擋下並提示先查詢。
部署
- 開發庫(nogi/cy 本機)已跑
sql/prodplan-save-deploy-20260824.sql(五張表+view、_sheetno修正、_tableseq、清單瀏覽三要件),可重跑。
- 正式機另出
sql/prodplan-save-deploy-20260824-cy-prod.sql(SQL 2008 相容),未執行。跑完要重新登入 ERP(_sheetno登入時載入)。
- 表名維持
twork_eis_productionm/d1~d4(21/22 字):這批表原本會被框架取號/配號鏈(DARB_LOG_BB_1_1等)的 20 字表名參數截斷成twork_eis_production、存檔報「無效的物件名稱」;08-24 曾暫時改名t_eis_production*迴避,08-25 二次裁決改回原名,改由框架 SP 本身把表名參數加寬到 60(tools/widen-tablename-params.ps1)解決截斷。部署前置條件:該庫須先跑過加寬腳本。五個 view 名twork_eis_vw_production*全程不變。
狀態
建置+單元測試通過;2026-08-25 於 nogi 模擬庫開窗實測六項通過(存檔
PP20260825001/連存002遞增/載入還原/刪除連刪四張明細/空結果被擋/樞紐鈕正常)。已知:nogi 一次存 29,276 筆訂單+29,102 筆計畫+62,834 筆使用量約 22~24 秒,逼近 30 秒逾時線,朝陽資料量未測;來源缺交期的列(本次 d3 63 列/d4 36 列)會被框架存成存檔當天日期。 - 結果區頂端新增「備註」欄與「存成生產計劃單」鈕:按下後把這次查詢的條件、匯率表、客戶設定、訂單預示預估、生產計畫、使用量存成一張單據,單號格式
-
08-24 ormast-cy-screen-fork-preord-compare ▸
---
title: 朝陽訂單管理(Ormast_cy)畫面對齊朝陽 VFP+預示比對整套上線
date: 2026-08-24
not_in_nav: true
---
朝陽訂單管理(Ormast_cy)畫面對齊朝陽 VFP+預示比對整套上線
適用:朝陽(CY)帳套的訂單管理系統
ORMAST_CY。禾久與其他帳套畫面不受影響(共用Ormast.xaml未動)。使用者可見變動
畫面(原本顯示的是禾久版畫面,現改為朝陽版)
- 移除 31 項朝陽 VFP 沒有的欄位/按鈕:主檔 訂單別、集團公司/代號/簡稱、報價單號、收付條件、稅別、交易條件、業務員編號、聯絡人、本幣未稅、「採購單收件匣」「匯入採購單」鈕;明細 顏色、折扣率、本幣未稅、客訂單序號、預計出貨日、廠商代號、建議採購量/交期/售價、請購數量、是否採購、是否核發、製程別、採購別、客戶交期、訂單分類、交期變更、營業確認、出貨別、分批交貨。
- 補回主檔欄:預示單號、流程樣板號、交易方式、數量總額(明細數量合計,即時更新)。
- 補回明細欄(共 38 欄,與 VFP 相同):客戶訂單號、Request #、庫存管制、停用、停用日期、預訂完工日、最低訂單量、輸入日期、輸入人員、舊製造交期、製造交期(回覆日期,唯讀)、預示比對、預示資料、回覆、比對說明1、比對說明2、查聯絡單(按鈕欄)。
- 明細列樣式:單價 ≤ 0 淺綠底;預示比對含 NG 紅字粗體;有聯絡單的列序號紅字粗體;待刪列紅底(既有)。
- 新增「聯絡單」分頁(查到聯絡單才展開),列上聯絡單號可點選開啟聯絡單。
預示比對(朝陽核心功能,新版首次提供)
- 主檔「預示單號」輸入離焦即檢核:需先填客戶代號;單號不存在或客戶不符→提示並清空;為該客戶最新預示單號時僅提示、仍可存。
- 頁內「預示比對」鈕:任何模式可按(瀏覽模式當試算)。依預示單明細按品號計算「最後預示日=最大預訂交期+5 工作日」,逐列算扣抵前/後「交期(含)前/交期後至最後預示日」小計,寫入 預示比對(
A/B→C/D,扣抵後交期前不足加註 NG)、比對說明1/2、預示資料(同品號共用)。
- 存檔時自動重算預示比對(預示單號空白則靜默略過);存檔時明細交期 ≥ 客戶預示交期僅提示不擋。
- 瀏覽模式按預示比對後自動匯出 Excel「單一訂單預示比對」(17 欄固定序,含回覆欄)至
C:\Temps\TmpExcel\。
- 頁內「XLS 回覆」鈕(瀏覽模式):讀回同名 Excel 的第 17 欄「回覆」,依明細 pkid 回填後自動存檔;檔案不屬於本張訂單、無可用回覆、pkid 對不到皆有提示。
其他行為對齊朝陽 VFP
- 客戶品號輸入離焦:檢核客戶代號/預訂交期必填,依客戶產品表帶出品號、包裝量,再帶客戶單價;已有製通單號且改值會提示。
- 「批次搜尋單價」鈕(編輯模式):依客戶單價表回填全部明細單價。
- 「更新出貨」鈕(僅特殊修改):依出貨資料重算已交數量。
- 「搜尋聯絡單」鈕(瀏覽模式):列出本單相關聯絡單並標記明細列。
- 出通單數量、製通單號欄改為可點選超連結,直接開啟出貨通知單/製造通知單(全系統 2026-08-14 裁決:單擊超連結取代 VFP 雙擊)。
- 製通單號在「特殊修改」模式可編輯(其他模式唯讀);新增明細列即帶入主檔客戶訂單號;「特殊修改」其他鈕改為就地特殊修改(原誤開信用審核視窗)。
部署
- CY 正式機 log 庫需跑
sql/ormast-cy-find-commpr-procparam-20260824.sql(登錄DARB_QRY_FIND_COMMPR到派發器參數表;冪等、含庫別守門;SQL 2008 相容)。未跑時「搜尋聯絡單/查聯絡單」靜默查無資料。
- 程式隨下次發版。
已知未做(停放,待裁決或待素材)
- 其他鈕「出貨」(朝陽版 ORMAST_S)、「改交期」(ORMAST_F):VFP 原始碼未提供。
- 存檔自動產生聯絡單(VFP U_COMMREXTEND):新版無對應機制。
- 庫存查詢「庫存量」口徑(VFP 只算 STOCKA/STOCKM 倉)。
- XLS 回覆鈕未接「可其他6」權限(ORMAST_CY 借用 ORMAST 權限列,槽位對不上)。
- 明細表頭字面「出貨日/金額」維持「預訂交期/原幣未稅」。
驗證狀態
建置 0 error;單元測試 64+ 案(比對引擎、Excel 讀寫、顯示欄規則、訂單工具);四個工作包各經 fresh-context 綁定核對+對抗審查並修正。runtime 未驗(開發機無朝陽資料)——實機驗證清單見
.claude/tmp/ormast-cy-fork-plan-20260824.md。 -
08-24 mailsearch-query-via-dispatch ▸
信件搜尋:查詢改走 LOG_SYS_SKD 派發(2026-08-24)
變動
「信件搜尋」(L-091)的讀取面全部改走派發器(使用者 2026-08-24 裁決「查詢也要走 log、不可直連」):
搜尋信件、信箱帳號清單、重建歸戶的既有信件讀取,改經
Log_Sys_Skd_Exec→集中自動化庫(darb*auto1)的
DARB_GETDATA4,與行事曆「查看執行結果」同一條路。使用者可見的差異:
- 按「查詢」後 log_sys_skd 會留下派發紀錄(先前直連 SQL、無紀錄)。
- 全文檢索失敗的降級訊息改為「全文檢索查詢失敗(詳見 DebugLog),已降級為 LIKE 搜尋…」
——派發器吞例外,桌面拿不到原始錯誤碼,詳細原因要查 DebugLog。
- 桌面登入不再需要 auto1 庫的直連授權即可查詢(寫入面例外,見下)。
尚未改走派發(待裁決另案)
信箱帳號「啟用/停用/刪除」與「重建歸戶」的寫入仍是直連 auto1——派發是查詢 SP,
寫入要新建專用 SP 並逐客戶部署(auto1 SP+log 庫 proc_param 登錄)。權限閘雙條件不變。
技術備註
- 零新 SQL 物件:
DARB_GETDATA4(動態SELECT 欄位 FROM 表 WHERE 條件)以
「TOP 放欄位串/ORDER BY 接條件尾/JOIN・OUTER APPLY 塞表名(實測 ≤250 字<參數上限 500)」
表達原本的查詢形狀;條件走派發器
@param2 nvarchar(MAX)。- 派發 SQL 無法參數化:關鍵字、使用者代號、日期一律經
字面()(單引號跳脫)/
跳脫Like()(萬用字元)併入字串;日期用 ISO 8601 字面值不受語系影響。- 主要改動:
ViewModel/L.Communication/MailSearchQuery.cs(建構子新增 IDatabaseConnection)。
- 三種查詢形狀(CONTAINS+日期、客廠部過濾、LIKE+排除詞)已在 darbcyauto1 以
GETDATA4 實跑驗證。
-
08-23 invent-procno-media-fields ▸
品號主檔加「工程圖檔」、工程代號表加「工程影片」
- 日期:2026-08-23
- 影響範圍:庫存主檔(D-01)、工程代號表(D-03);CY 客戶需求
變動
- 庫存主檔:圖檔區塊新增「工程圖檔」欄位(路徑選擇框),對應
invent.工程圖檔 nvarchar(100)。
- 工程代號表:圖檔名稱旁新增「工程影片」欄位(路徑選擇框),對應
procno.工程影片 nvarchar(100)。
- 兩欄存檔行為與既有「圖檔名稱」相同:選本機檔案時自動複製進數位圖庫
(invent → Image 目錄、procno → Processing 目錄),DB 存相對路徑;
複製失敗(圖庫不可達)會擋存並顯示原因。
資料庫
sql/invent-procno-media-cols-20260823-cy.sql(朝陽;正式機已部署)
sql/invent-procno-media-cols-20260823.sql(darbnogi 測試庫;nogi1/nogi5 已跑)
- 兩支皆冪等、含驗證區;一併把
vw_invent/vw_brow_invent/vw_procno補欄,
並修正
vw_procno被 SSMS 檢視設計器展開造成的別名錯位風險(ALTER 回procno.*標準版)。 -
08-23 dashboard-sql-dataset-disabled ▸
儀表板 SQL 型資料集停用
- 日期:2026-08-23
- 影響範圍:儀表板設計(A-155)、自訂儀表板(M-D5)
變動
- 儀表板資料集的「SQL」種類停用:設計器的種類下拉不再提供 SQL,SQL 陳述式欄位一併移除。
- 既有含 SQL 型資料集的儀表板定義仍可開啟,但查詢時該資料集回報
「SQL 型資料集已停用:請改用 SP 型(DARB_BD_* 預存程序)或清單瀏覽」;存檔前驗證會直接擋下。
原因
正式環境的資料庫連線帳號只進得了 log 庫,公司庫查詢一律經 dispatcher
(
DARB_LOG_SYS_EXEC提權路由)。自訂 SELECT 直連公司庫在此安全模型下必然被拒(runtime 實測「無法存取資料庫」);開提權派發 SP 讓任意 SELECT
通過的安全代價不划算,故裁決停用。需要自訂查詢的場景請改走:
1. SP 型:包成
DARB_BD_*預存程序並登錄proc_param(參數慣例[編號, 查詢條件])。2. 清單瀏覽:掛
_sheetno.QueryProcedure。3. 查詢程式型:寄生既有 M 模組查詢程式。
-
08-21 mail-sync-now-button ▸
信件搜尋:新增「立即同步」按鈕(2026-08-21)
變動
「信件搜尋」(L-091)頂部按鈕列新增 立即同步(在「重建歸戶」左邊,每個使用者都能按)。
按下後系統把最近一筆已到期的信件同步(MailSync)排程事件重新排入執行佇列,
伺服器上的排程器約 5 分鐘內會抓一次新信;完成後重按「查詢」即可看到最新信件。
行為細節
- 同步不在使用者的電腦上執行——憑證金鑰只在排程主機,按鈕只是「送指令到伺服器」。
- 事件正在執行中(10 分鐘內開始)→ 提示「正在執行中」,不重複排入。
- 事件已在等待佇列 → 提示「已在等待執行」,不重複排入。
- 找不到已審核的 MailSync 排程事件、或預定時間都在未來 → 紅字提示原因
(需先在「排程事件(專案)」建立並審核事件)。
- 觸發成功的訊息會帶出上次完成時間。
技術備註
- 零新 SQL 物件:讀事件走
DARB_GETDATA4派發查twork_vw_calendarevent;
清狀態走既有
TWORK_SKD_UPDATE_EVENT_STATUS(清已完成時連是否停用一起清,事件因此重新符合
TWORK_SKD_GET_PENDING_AUTOEXEC的撿選條件)。- 判定邏輯:
LogicBll/MailSearch/MailSyncTrigger.cs(純函式,MailSyncTriggerTests8 案)。
- 延遲上限=排程器的工作排程間隔(建議 5 分鐘)。
-
08-21 dashboard-usability ▸
2026-08-21 自訂儀表板:連動篩選可視化、版面不限高、查詢合併、匯出改進
連動篩選看得出誰有被篩
- 篩選作用中時,資料沒有同名欄(沒被篩到、仍顯示全量)的卡片會淡化並在標題列標「未套用篩選」;發起篩選的來源卡框線點亮。
- 能發起連動篩選的卡片(柱狀/折線/圓餅且有分組欄)標題列有漏斗小圖示。
- 修正:KPI 的前期比較值現在也套同一個連動篩選(原本主值被篩、比較值全量,增減%失真)。
版面
- 公版七張儀表板(D0001~D0007)列數改 0=不限高,改為縱向捲動;「一頁填滿」改為在儀表板設計把列數設回正數即可。
- D0001 首頁移除「每日受訂金額」卡(月趨勢/每月柱狀已足),客戶Top10 補滿右半。卡片庫仍保留該卡,可自行加回。
- 佈署腳本不再清除個人版面與自建儀表板(2026-08-20 首發已清過,重佈署只 UPSERT 公版)。
查詢次數
- 引擎新增同源日期範圍合併:同一(單據別|View)之下的多個純日期區間條件(本期/KPI 前期/當月/全年/同比疊線)合併成一次涵蓋全範圍的查詢,各卡在記憶體切自己的範圍。原本一個單據別家族開一次儀表板要打約 7 次查詢,現在 1~2 次。
- 條件不是純日期區間、或有卡用「統計」集的資料集不合併,照原路查,行為不變。
匯出
- 「匯出HTML」改輸出互動版:分頁 tab、版面與畫面一致(原本靜態版分頁會不見);排程出圖仍走靜態版不受影響。
- 匯出完成後自動用預設瀏覽器開啟。
儀表板設計(第二輪,同日)
- 挑卡改勾選:「可用卡片」清單最前面新增「加入」勾選欄,單擊即勾——勾=加進儀表板、取消勾=移除(原「加入」按鈕移除);勾完右側預覽自動更新。
- 選卡即看範例:在可用卡片清單點選任一張卡,右側立即渲染該卡的假資料範例(不動設計中的定義、不可拖排)。
- 預覽不再綁編輯模式:瀏覽狀態也能按「預覽」「檢查」(拖排仍限編輯狀態)。
- 分頁標題改為直接在版面分頁的清單格子內修改(原下方「分頁屬性」區移除)。
- 設計器內所有小按鈕移除圖示、只留文字。
- 「儀表板卡片」維護程式(A-156)移除(使用者裁決):卡片庫改以版控 JSON+種子 SQL 維護;選單與權限清除 SQL=
sql/dashboard-card-remove-program-20260821.sql(已跑 nogi1/5)。卡片資料表、_sheetno 登錄與挑卡彈窗都保留。
自訂查詢面板 × 儀表板整併(2026-08-22)
- 顯示項目可轉儀表板卡片:「匯出內容設置」每列新增「轉成卡片」鈕——選中的圖表/表格顯示項目一鍵轉成卡片(分類「自訂查詢」)寫進卡片庫,之後儀表板設計與檢視端「新增卡片」都挑得到。逐欄展開(寬轉長)模式不可轉,會提示原因。
- 磚新增「計算欄」:兩欄運算的衍生欄(差異/比率等,語意同自訂查詢),表格可入欄位清單、圖表可入序列、KPI 可當數值欄(前期比較同步套用)。
- 磚新增「多欄序列」:一欄一序列(柱/折),多個數值欄同圖對照,序列名可用欄位別名改。
- 表格磚新增「隱藏零值」:整列數值皆 0 不顯示、單一 0 顯示空白(語意同自訂查詢匯出)。
- 匯出HTML 可附帶儀表板:匯出選擇彈窗新增「附帶儀表板」勾選區——勾選的儀表板以「指標摘要一頁+一磚一頁」接在查詢頁後面,同一份 HTML/PPT、同一組風格;期間跟著面板的目標月份。
-
08-20 dashboard-card-library ▸
2026-08-20 自訂儀表板改成「挑卡片」:卡片庫、設計器卡片分頁、檢視端新增卡片
使用者可見變動
儀表板設計(`A-155`)
- 新增
卡片分頁,而且是打開就在的第一個分頁。左邊列可挑的卡片(分類/標題/單據別/型別/預設尺寸/說明,可用分類下拉篩選),按加入就多一塊磚;右邊列已加入的卡片,可移除/上移/下移。
- 加入卡片時系統自動帶進它需要的資料來源,同一組條件的卡片自動共用一次查詢。
參數/資料集/磚三個分頁改成進階設定,預設隱藏——左上角勾進階設定才會出現。版面分頁維持顯示。
- 新增一張儀表板時預設:版面 14×5、一個「主頁」分頁、不顯示進階設定。
自訂儀表板(`M-D5`)
- 編輯版面模式的工具列多一顆
新增卡片:開挑卡視窗(可複選、可依分類篩選)→ 確定後畫面重查並停在編輯模式,新卡片就在版面上,拖到想要的位置後按儲存版面才會保留。
- 挑卡清單只列「你有瀏覽權限、該程式有掛清單瀏覽查詢、而且這張儀表板上還沒有」的卡片。
還原預設會連同自己加的卡片一起收掉。
內建卡片(20 張)
單據別 張數 內容 ORMAST 訂單 9 本期受訂金額/受訂筆數/未交數量合計(KPI)、客戶 Top10(柱)、每日受訂・月受訂趨勢(折線)、業務佔比(餅)、未交明細・客戶統計(表格) SLIY 總帳 6 本期借方・貸方總額(KPI)、科目 Top10(柱)、每日傳票金額(折線)、部門佔比(餅)、傳票明細(表格) TRSAMA 出貨 5 本期出貨金額(KPI)、客戶・品號 Top10(柱)、每日出貨(折線)、出貨明細(表格) > TRSAMA 目前不會出現在挑卡清單:
_sheetno尚未登錄QueryProcedure(DARB_BD_TRSAMA已存在),補登錄後即可挑選。開發者
- 契約:
DashboardCard(代號/單據別/標題/分類/說明/資料集/磚/預設尺寸/允許尺寸/參數)、DashboardTileDef.卡片代號、DashboardLayout.額外卡片。
- 卡片庫
LogicBll/M.EIS/Dashboard/Cards/DashboardCardLibrary.cs:
- 從內嵌資源
Cards/*.json載入(csproj 萬用字元,新增卡片檔不必改 csproj),處理程序內只載一次;單一檔 JSON 壞掉只記DebugLog並跳過該檔。-
ForUser(IAppContext):功能權限(走DashboardPermissionGate,含ProgramClassRouter.ApplyCompanyOverride變體解析)+ 清單瀏覽型必須有_sheetno.QueryProcedure。-
Materialize(代號清單, def):資料集依「單據別+種類+條件+ViewNo/SP/SQL/分組+前期」簽章去重(ds_<單據別>_<n>,既有同簽章直接沿用),磚id=卡片代號;已存在的 id 跳過。攤出去的是深複製,不會污染共用單例。-
Validate():代號唯一、單據別/標題非空、磚型別合法、條件 token 只能用DashboardTokenResolver.內建Token(鑽取額外允許{分類})。- 引擎:
DashboardQueryEngine.併入額外卡片(def, personalLayout)(public static)在權限閘之前把個人版面的額外卡片攤進 def 的副本;原 def 不動,攤出來的磚照樣過權限閘。
- 版面修正:
DashboardLayout.Normalize對「沒座標但有指定尺寸」的磚改成沿用該尺寸(原本無條件給「中」,卡片的預設尺寸會被默默吃掉)。
- 檢視端:
DashboardViewModel用_待加卡片(尚未存檔)+_額外卡片(本次生效)兩份狀態;儲存版面時把額外卡片補回Normalize產出的新版面(Normalize 不帶這欄,漏了會存完就消失)。
- 新增卡片的做法:見 skill
dashboard-card(含references/card-template.json逐欄說明)。
追加(同日):卡片庫進資料庫,卡片有編號與單據別
使用者可見變動
- 卡片定義從「只在程式裡」改成存在資料庫
twork_sys_dashboardcard:每張卡有 卡片代號(編號) 與 單據別,另有標題/分類/說明與 停用 欄。
- 效果:卡片清單可以查、可以個別停用、可以由客戶端調整(不必改程式);資料庫還沒有卡片資料時,系統自動使用程式內建的 20 張,不會出錯也不會空白。
- 部署或調整卡片後要重新登入 ERP 才會生效(卡片於登入後首次讀取時快取)。
開發者
- 表
dbo.twork_sys_dashboardcard(單據別路由鍵DASHBOARDCARD):卡片代號(UNIQUE, nvarchar40)/單據別/標題/分類/說明/卡片JSON(nvarchar max, 整份DashboardCard)/停用+標準共有欄位;pkid非 IDENTITY。_sheetno(編碼欄位=卡片代號)與_tableseq(seqval 種子後校正為 MAX(pkid))同檔登錄。
- 來源優先序:DB 是 runtime 權威(同
卡片代號蓋掉內嵌、DB 獨有的直接多出來、停用='Y'不列);內嵌Cards/*.json是版控源頭與後備(表不存在/連線失敗/0 列 → 退內嵌,只記DebugLog,不丟例外)。表上的卡片代號/單據別/標題/分類/說明覆蓋卡片JSON內同名欄。
- 讀取:
DashboardCardLibrary.For(IAppContext)走通用查詢 SPDARB_GETDATA4(不必新增 SP、不必登proc_param),每個連線字串快取一份,ClearCache()可清;Default會優先給最近一次以 context 載入的合併結果。DashboardQueryEngine.Run改用For(_context),headless 排程出圖同樣吃得到 DB 卡片。單列 JSON 壞掉只跳過該列。
- 種子工具
tools/gen-dashboard-card-seed.ps1:讀Cards/*.json→ 產#dashcardseed種子 SQL(-Apply直接寫回部署檔的GENERATED-SEED標記區)。JSON 以括號配對掃描原文抽出(不重新序列化),輸出不含時間戳、重跑位元組相同。
- 部署
sql/dashboard-cards-deploy-20260820.sql(NOGI 五帳套)/-cy.sql(朝陽 darbcycsa1):建表+_sheetno/_tableseq+20 張 UPSERT,整檔一次跑;重跑印「新增 0 張、更新 0 張」;不動既有列的停用。
- Model/Source:
Common/Model/M.EIS/DashboardCardModel.cs、Model/Source/M.EIS/DashboardCardSource.cs、LocalDbContext.Twork_sys_dashboardcard(供之後的卡片維護 UI 走標準上傳)。
追加的相關檔案
- 新增:
sql/dashboard-cards-deploy-20260820.sql、sql/dashboard-cards-deploy-20260820-cy.sql、sql/_gen/dashboard-card-seed.sql、tools/gen-dashboard-card-seed.ps1、Common/Model/M.EIS/DashboardCardModel.cs、Model/Source/M.EIS/DashboardCardSource.cs
- 修改:
LogicBll/M.EIS/Dashboard/Cards/DashboardCardLibrary.cs、LogicBll/M.EIS/Dashboard/DashboardQueryEngine.cs、Model/LocalDbContext.cs、LogicBllTests/Dashboard/DashboardCardLibraryTests.cs、.claude/skills/dashboard-card/SKILL.md、docs/M-EIS/dashboard.md
相關檔案
- 新增:
LogicBll/M.EIS/Dashboard/Cards/(DashboardCardLibrary.cs、ORMAST.json、SLIY.json、TRSAMA.json)
- 新增:
ViewModel/M.EIS/Dashboard/DashboardCardPickerViewModel.cs、TsERP/M.EIS/儀表板挑卡.xaml(.cs)
- 新增:
LogicBllTests/Dashboard/DashboardCardLibraryTests.cs(21 項)、.claude/skills/dashboard-card/
- 修改:
LogicBll.csproj(EmbeddedResource)、DashboardQueryEngine.cs、DashboardHtmlWriter.cs(工具列addCard)、DashboardMessageRouter.cs(DashboardWebCommand.AddCard)、DashboardViewModel.cs、DashboardcfgViewModel.cs、DashboardcfgItems.cs、TsERP/A.SystemData/儀表板設計.xaml、TsERP/App.xaml、Common/ProgramClass.cs(DASHBOARDCARDPICK)、Common/Lang/Xaml/Dashboardcfg.json+新增Dashboardcardpick.json、LogicBll/M.EIS/Dashboard/DashboardDefinition.cs(Normalize 尺寸)
- 新增
-
08-19 tshtmlview-webview2-wrapper ▸
2026-08-19 共用 HTML 顯示控件 TsHtmlView;郵件內容預覽修復
使用者可見變動
- 寄送 Email 視窗的「檢視內容」(SendEmail → 內容預覽)以前開出來是空白(HTML→XAML 轉換器早已拆除),現在正常顯示郵件 HTML;預覽視窗加大為 900×700,標題「內容預覽」。
- 預覽內容不執行 JavaScript、頁內連結改用系統瀏覽器開啟(郵件屬不信任內容)。
- 沒裝 Microsoft Edge WebView2 Runtime 的電腦不會閃退:顯示提示文字+純文字版內容。
開發者
新增
TsControl/Html/TsHtmlView.cs(xmlns:html="clr-namespace:TsControl.Html;assembly=TsControl"),之後要顯示 HTML 一律用它,不要再直接放WebView2:屬性/成員 用途 HtmlHTML 字串(NavigateToString) Source網址瀏覽模式 IsScriptEnabled(預設 false)要互動才開,只對自家產生的頁面開 OpenLinksExternally(預設 true)Html 模式下 http/https/mailto 連結走系統瀏覽器 MessageCommand/WebMessageReceived頁面 window.chrome.webview.postMessage(obj)→ C#(JSON 字串)ExecuteScriptAsync/PostMessageC# → 頁面 TsHtmlView.IsRuntimeAvailable/UserDataFolderRuntime 偵測;資料夾固定 %LocalAppData%\TsERP\WebView2(整個 app 共用一個 Environment)內建:宿主視窗 Closed 立刻 Dispose、Unloaded 3 秒後仍離場才 Dispose(ContentWindow 內容暫離視覺樹不會誤殺)、Dispose 後再 Loaded 自動重建並重套 Html;alert/confirm、DevTools、瀏覽器快捷鍵、縮放關閉。
離線 WPF 探針驗過:渲染中文、頁面 postMessage 進 C#、C# ExecuteScript 取值、無 Runtime 時降級純文字(四項皆有截圖/log)。
相關檔案
TsControl/Html/TsHtmlView.cs(新增)
TsControl/Content/ViewHtml.xaml、ViewModel/Control/Content/ViewHtmlViewModel.cs(RichTextBox → TsHtmlView;RichText改名Html)
- 未遷移:
TsERP/AIQuery/ChatAgentView.xaml仍直接用 WebView2(可運作,之後要改再換)
-
08-19 test-panel-trisource ▸
2026-08-19 測試控制面板:三方對照(SQL 欄位/本地類別/畫面 UI)
- 測試控制面板新增「三方對照」分頁:對目前開啟的程式,分別抓
_sheetno主表+子表的sys.columns、程式已註冊的 Source 類別屬性、畫面控件與明細表格欄的綁定,合成一張對照表。
- 狀態分類:三方齊/DB 有類別沒有/類別有沒畫面/畫面綁到不存在的屬性/類別有 DB 沒有/畫面綁非資料來源;框架共用欄(pkid、輸入人員、工作流程、審核…)不算缺漏。
- 「只看問題」篩選+「匯出 HTML」(與前置作業報告同目錄,檔名
<程式>-trisource.html,只留最新)。
- 規格自動測試「全部執行」在閘門通過後自動先建對照,記為步驟 0;發現缺漏只記「人工」,不阻擋後續步驟。
2026-08-20 前置作業報告:VFP 原始碼結構化
- 前置作業報告第三段改成 VFP 大綱:業務屬性表(主子表別名、鍵欄、瀏覽型別…)、版面屬性收合、方法目錄依控件分組可點跳、每個方法可摺疊(allowsave/Init/Valid/LostFocus 等測試相關預設展開),行號為原檔行號。
- 找檔改為只用禾久版(排除
*_cy資料夾),帶家族檔(_bd/_brow),整包 vcx(如 scx_acc 內 30 支程式)經vfpcode/index.json或自動掃DEFINE CLASS找到。
- 三方對照多「VFP 驗證」欄:欄位在 VFP 有 Valid/LostFocus 等事件就列出並超連結到前置報告的該段程式碼。
- 客戶端沒有 vfpcode 資料夾時改讀隨程式發佈的
TestAutomation/vfpcode.zip(建置時自動打包,約 1.6MB)。
- 測試控制面板新增「三方對照」分頁:對目前開啟的程式,分別抓
-
08-19 eventproject-work-permission ▸
2026-08-19 排程事件(專案)接工作權限 MY_SCOPE
使用者可見變動
- 排程事件(專案)EVENTPROJECT 開窗、上下一筆、放大鏡查詢、直接輸入項目編號,只列出負責人在你的工作權限範圍內的專案:
本人/代理/直接下屬/間接下屬/部門成員(與待辦事項同一組關係,ADR 0132 決策 4)。
- 負責人空白的專案視為公用,人人可見。
- 負責人
ADMIN/SYSTEM的系統排程專案(FXRATE/MAILSYNC/PURCH/MOLD-CHK…)只有系統管理員(secret1.管制系統含 admin,同程式內IsAdmin())看得到;系統管理員看得到全部專案。(同日修正:初版曾把非員工代號一律公開,使用者實測後收窄。)
- 之前:任何有 L-050 功能權限的人都看得到全公司所有專案(含別人的個人事件專案)。
部署(每個 csa 帳套庫各跑一次,先有 `TWORK_FN_MY_SCOPE`)
sqlcmd -S <server> -d <csa庫> -E -f 65001 -i sql/TWORK_FN_EVENT_SCOPE.sql缺函式時桌面版一開 EVENTPROJECT 會跳 SQL 錯誤(找不到
dbo.TWORK_FN_EVENT_SCOPE),不是靜默空白。相關檔案
sql/TWORK_FN_EVENT_SCOPE.sql(新增 iTVF,SQL2008 相容、冪等)
ViewModel/L.Communication/EventProjectViewModel.cs(FilterCondition)
docs/L-Communication/eventproject.md(前置需求補工作權限說明)
-
08-19 custom-dashboard-v2 ▸
2026-08-19 新增「自訂儀表板」與「儀表板設計」兩支程式(可自己定義內容的磁貼式儀表板)
使用者可見變動
兩支新程式
程式 位置 做什麼 自訂儀表板( M-D5)M 主管資訊 選一張儀表板、填期間與部門,按 查詢就把磚(KPI/柱狀/折線/圓餅/表格)畫成一頁儀表板設計( A-155)A 系統資料 定義儀表板內容:參數、資料集、磚、預設版面、匯出風格 - 磚的資料來源是各程式既有的「清單瀏覽」查詢:在設計時挑一個單據別,條件可用
{起日}/{迄日}/{年月}/{部門}/{使用者}等 token,查詢時才代換成條件面板上填的值。另可用預存程序或自訂 SQL 當來源。
- KPI 磚可開前期比較(差額/百分比、可設定「增加為好」或「減少為好」)。
- 點磚可鑽取:帶著該磚的條件切到對應單據別的清單瀏覽,落地看明細。
磁貼版面與個人版面
- 版面是 12 欄磁貼格線,磚有 小/中/寬/大 四種尺寸。
- 按
編輯版面進入編輯模式:拖曳磚調整位置,右鍵或磚上的尺寸鈕改大小、隱藏鈕收起磚;鍵盤Ctrl+方向鍵移動一格、Ctrl+1~4換小/中/寬/大、Esc取消。
- 按
儲存版面存成你自己的版面(不影響別人,也不動設計者的預設版面);按還原預設刪掉個人版面回到設計者的排法。
- 設計者之後新增的磚會自動追加到個人版面尾端,不會因為你存過版面就看不到。
分頁與 Full HD 版面(2026-08-20 追加)
- 儀表板可分多個分頁(畫面上方 tab;設計器
版面分頁維護標題、磚屬性指定所在頁;檢視端右鍵移到分頁 ▸、Ctrl+PageUp/PageDown切頁)。
- 每頁固定 欄數 × 列數(新儀表板預設 14×5=Full HD 扣掉行事曆與下方面板剛好一頁不捲動;舊儀表板沿用 12 欄、自動套 5 列);放不下的磚自動順延下一頁;匯出 PDF 一頁一張。
- 修正:圓餅只有單一分類時整塊空白;分類值空白時顯示「(空白)」。
匯出與外觀
匯出HTML:把目前這一頁存成一個自包含的網頁檔(無工具列、可離線開、可轉寄)。
匯出行動版:產生手機直立閱讀的單欄卡片流網頁檔(檔名尾_mobile)。
匯出PDF:把同一份版面產生 A3 橫式 PDF(欄數 ≤8 時 A4 橫式;深色風格會先問是否改用列印友善)。需要本機已安裝 Microsoft Edge WebView2 Runtime。
- 排程自動寄送:行事曆事件
單據別 = DASHBOARD、執行方法 = DashboardDeck,headless 產出 HTML/行動版/Excel 後以附件寄出(排程端不支援 PDF);字典登錄腳本sql/dashboard-autopilotmethod-register.sql。
- 右上角風格下拉可即時換配色(典雅簡報(預設)/簡潔商務/列印友善/深色簡報/賽博龐克,與
匯出HTML共用同一組風格)。
權限
- 儀表板的可見範圍與「自訂查詢面板」相同:本人、你代理的人、你的下屬、使用部門相符者建立的儀表板才會出現在下拉中;只有建立者本人能修改或刪除。
- 磚所屬單據別你沒有瀏覽權限時,該磚不顯示(版面會自動往上壓實,不留空洞);沒有「看單價」權限時,金額類 KPI 磚不顯示、表格的金額欄顯示
—。
一般使用者不會遇到、但會影響上線的事
- 兩支程式需要系統管理者先在資料庫部署三支 SQL(依序
sql/dashboard-deploy.sql→sql/dashboard-sheetno-tableseq-register.sql→sql/dashboard-register-program.sql;朝陽環境用同名-cy版),跑完要重新登入 ERP 才會生效。未部署時程式開得起來,但儀表板下拉載入會提示 SP 未部署。
- 只有
_sheetno掛了清單瀏覽查詢(QueryProcedure)的程式才會出現在設計器的單據別下拉。想用的程式沒出現時,要先替該程式掛上清單瀏覽查詢。
開發者
- 新增
LogicBll/M.EIS/Dashboard/:DashboardDefinition(定義 JSON POCO+DashboardLayout.Normalize/Compact)、DashboardTokenResolver、DashboardSqlGuard、DashboardDataSetRunner、DashboardAggregator、DashboardPermissionGate、DashboardQueryEngine、DashboardRenderModel、DashboardHtmlWriter(互動/靜態/行動三模式)、DashboardConfigBll。
- 資料集走輕型 DataTable 路徑(
SheetNoMethod.GetQueryProcedure→Log_Sys_Exec(TWORK_BD_VIEWLIST)),不寄生查詢 ViewModel、不寫 SQLite、無 STA 依賴;同源多磚共用一次查詢。
HtmlDeckWriter.BuildRootCss抽成共用DeckThemeCss;DeckChartSvg新增ChartRenderOptions多載、sparkline、<title>與data-cat/data-ser(舊呼叫端輸出逐位元不變,golden 測試已比對)。
TsControl/Html/TsHtmlView.cs新增能力:ContentLoaded事件/IsContentLoaded、PostMessage 未載入時先排隊(首包不再靜默丟棄)、PrintToPdfAsync(path, landscape, paper)、AreDevToolsEnabled(預設 false)。
- 新表
twork_sys_dashboard(DASHBOARDCFG,編碼欄位pkid)、twork_sys_dashboardlayout(DASHBOARD);新 SPTWORK_DASHBOARD_QRY(TWORK_FN_MY_SCOPE六種關係)、TWORK_DASHBOARD_LAYOUT_QRY;LocalDbContext加Twork_sys_dashboard/Twork_sys_dashboardlayout兩個 DbSet。
- 登錄:
Common/ProgramClass.cs加DASHBOARD/DASHBOARDCFG;App.xaml三個 DataTemplate;DIExtension加AddScoped<DashboardConditionViewModel>()。
相關檔案
- 新增:
LogicBll/M.EIS/Dashboard/*、ViewModel/M.EIS/Dashboard/*、ViewModel/A.SystemData/DashboardcfgViewModel.cs+DashboardcfgItems.cs、TsERP/M.EIS/自訂儀表板.xaml+自訂儀表板Condition.xaml、TsERP/A.SystemData/儀表板設計.xaml
- 修改:
TsControl/Html/TsHtmlView.cs、LogicBll/CommonSystem/Reporting/DeckChartSvg.cs、HtmlDeckWriter.cs、Model/LocalDbContext.cs、Common/ProgramClass.cs、TsERP/App.xaml、TsERP/DIExtension.cs
- SQL:
sql/dashboard-deploy.sql、sql/dashboard-sheetno-tableseq-register.sql、sql/dashboard-register-program.sql(各有-cy版)
2026-08-20 追加:唯一代號與螢幕版頁尾
- 儀表板代號(儀表板設計)與配置代號(自訂面板配置):兩支設計程式的主檔各加一個全公司唯一的代號欄位。新增時系統自動給
D0001/C0001起跳的流水,可自行改成好記的代號(最長 20 字,存檔時轉大寫);代號重複會存不進去並提示改代號。
- 導覽/定位改用代號:上一筆下一筆的排序、查詢定位(
_sheetno.編碼欄位)都從pkid換成代號,清單依代號排序。
- 選單下拉顯示「代號 名稱」:自訂儀表板與自訂查詢面板的條件面板下拉改為可輸入,直接打代號就能篩選。
- 排程可用代號指定儀表板:
DashboardDeck參數新增儀表板代號,與儀表板pkid二擇一(兩個都填時 pkid 優先)。建議改用代號——pkid 是各資料庫各自配的流水號,換帳套就對不上。
- 螢幕檢視不再顯示頁尾:互動模式(畫面上看的那份)拿掉底部「公司名/資料時間/共 N 磚 N 頁」那一列,版面高度全留給磚;匯出的 HTML/PDF/行動版仍保留頁尾(列印與轉寄需要)。條件字條上的資料時間不受影響,照常顯示。
- 系統管理者:要跑兩支新 SQL ——
sql/dashboard-add-code-20260820.sql、sql/customdash-add-code-20260820.sql(朝陽用同名-cy版)。既有資料會自動回填代號(D/C+ pkid 補零四位),跑完要重新登入 ERP 才吃得到新的編碼欄位。
- 磚的資料來源是各程式既有的「清單瀏覽」查詢:在設計時挑一個單據別,條件可用
-
08-19 calendar-add-event ▸
2026-08-19 右側行事曆新增「新增事件」按鈕
使用者可見變動
- 右側行事曆的「事件/佈局/新增事件」列移到「個人/部門/公司」篩選列上方,並多一顆 新增事件。
- 按下直接開「新增事件」視窗(不跳轉到排程事件程式),預設:預定時間=行事曆目前選取日 09:00、只執行一次、擁有者=個人(本人)、通知方式=待辦事項。
- 按「返回」即背景存檔並刷新行事曆,事件立刻出現在當日清單:
- 個人事件統一掛在「項目編號=使用者代號」的排程事件專案下:已存在 → 直接追加一筆事件明細(序號接續);不存在 → 自動建立專案(項目編號/負責人=使用者代號、項目名稱=「姓名+個人事件」、已審核=Y)連同事件一起寫入。
- 之後可從事件的「導航」進排程事件程式檢視/修改該專案。
相關檔案
ViewModel/MainWindowPage/CalendarPageViewModel.cs(AddEventCommand)
LogicBll/Calendar/CalendarBll.cs(FindProjectPkidBy項目編號/SavePersonalEvent 背景存檔)
TsControl/Calendar/RightSideCalendar.xaml、Common/Lang/Xaml/Eventproject.json
-
08-19 bom-gridsplitter ▸
2026-08-19 BOM 表:明細之間加可拖曳分隔線
使用者可見變動
- BOM 表(Bom):材料明細與製程明細之間多一條分隔線,滑鼠拖曳可調整上下兩張表格的高度比例(上表至少 80px、下表至少 60px)。
- BOM 表(朝陽版 Bom_cy):材料/製程/產品治具表三張之間各一條分隔線,同樣可拖曳。
- 分隔線樣式沿用系統既有
GridSplitterHorizontalStyle(與信件搜尋、待辦清單相同)。
相關檔案
TsERP/D.Bom/Bom.xaml、TsERP/D.Bom/Bom_cy.xaml
-
08-18 otherrp-report ▸
2026-08-18 其他應收付(OTHERRP)新增列印:I100-1 其他應收付單
背景
2026-08-18 帳款報表盤點列出四支「手冊寫了列印、卻一張報表都沒有」的帳款程式,
OTHERRP 是第一支補上的。VFP 原版沒有專屬 frx(
browsetype=I10B走瀏覽型列印),所以這張是全新設計,版面比照同為 rp_m 單據的暫付申請單(Temporary),欄位取自 Otherrp 表單畫面上的所有欄位。
使用者可見變動
- 其他應收付(I-100)工具列的
列印現在會開出其他應收付單列印頁(財務單號起訖,預設帶目前單據),
報表清單有
I100-1 其他應收付單(A4 直式、一張單一頁,含核准/財務/部門主管/經辦簽核欄)。- 修前:按列印只會退回瀏覽頁(VM 沒實作
IPrintViewModel)。
實作(零 DB 部署)
層 檔案 說明 Model Model/Rpt/Rpt_I100_OtherrpReportPoco.cs中文屬性名=SQLite 欄名=frx Column; GetDescription()補付款方式/收付條件說明/使用部門簡稱/進銷分類名稱/未沖金額Model Model/ReportBll.GetOtherrpReport走既有 SP DARB_RPT_PREPAID(SELECT a.* FROM vw_rp_m依條件,rp_m 系共用),不新增 SPPlugin TworkReportPluginOfficial/I.ARAP/Otherrp.cs類名=報表名稱;條件=財務單號 between 起訖 AND 程式類別='H'ViewModel ViewModel/I.ARAP/OtherrpPrintViewModel.cs、OtherrpViewModel加IPrintViewModelIPrintSource.GetReports()登錄 I100-1/Otherrp/rpt_i100_otherrp_report1,免_rptdatCommon ProgramClass.OTHERRPPRINT、Lang/Xaml/OtherrpPrintPage.jsonTsERP I.ARAP/OtherrpPrintPage.xaml(.cs)、App.xamlDataTemplate版面同 TemporaryPrintPage frx C:\Users\momo1\source\repos\FastReport\Otherrp.frx(版控)+C:\dglibrary\REPORTSROOT\Reports\Otherrp.frx(部署)手工版面(非 VFP 轉換器產物);其他客戶要另外把 frx 放進他們的 REPORTSROOT Test LogicBllTests/I.ARAP/Otherrp_ReportTemplateTests.csfrx 表名=VM 登錄、frx Column ⊆ POCO 匯出欄、STA Prepare 有頁;設 OTHERRP_PREVIEW_DIR可另存 PNG 人眼檢查Docs docs/I-ARAP/otherrpprintpage.md(新)、otherrp.md列印節、index.md列印頁表驗證
- ✅ MSBuild
TsERP.csproj/LogicBllTests.csproj0 error。
- ✅
Otherrp_ReportTemplateTests、ReportRegistrationConsistencyTests(2)、HarnessSmokeTests(8)全過。
- ✅ 版面以樣本資料輸出 PNG 人眼檢查(
C:\temps\otherrp-preview\Otherrp.png):表頭/框線表格/簽核欄排版正常,數字靠右兩位小數。
- ✅ DB 端實跑
EXEC DARB_RPT_PREPAID 2, N'財務單號 between ''9B-20260706001'' and ''9B-20260714001'' AND 程式類別=''H'''
於 darbnogicsa1 撈到 3 筆 9B 單據,欄位齊全(
說明可為 NULL,dt.ToList 同 Temporary 路徑處理)。- 🔴 未驗:app 內實際按列印→預覽(需 CMSA 密碼做 UIA 登入,本輪無法取得)。路徑與 Prepaid→Temporary 完全同構,
但上線前請人工點一次:其他應收付 → 任一筆 → 列印 → 預覽,確認
I100-1出現且有資料。剩餘三支(仍無報表,需規格)
ARCLAIM(應收索賠扣款單)、RFE(費用申請單)、COMMISSION(業務員佣金)——皆無 VFP 對版且無現成 SP,欄位取捨待業主確認。同日追加:其他應收付表單版面重排+暫付申請單防壓到右側面板
TsERP/I.ARAP/Otherrp.xaml從單一大 Grid 改為 GroupBox 分區(單據資訊/申請資訊/基本資料/金額/帳款與付款/備註),
版型比照暫付申請單
Temporary.xaml;所有 binding 與x:Name與舊版逐一比對相同(差集為零)。Common/Lang/Xaml/Otherrp.json補區塊標題與 進銷分類/關係人/受款人/付款條件 key。
- 兩支表單(Otherrp/Temporary)根 StackPanel 右側留 230px:框架的
FinancialExtensionPanel(pkid/相關單號/傳票號碼/已審核/審核日期)
是疊在同一區塊的 overlay,滿版 GroupBox 會壓到它——使用者實機回報後修正。
- ✅
--screenshot模式實拍兩支(CMSA 登入):分區排版正常、右側面板不再被壓;截圖已更新到
docs/I-ARAP/images/otherrp-step1.png、prepaid-step1.png。 - 其他應收付(I-100)工具列的
-
08-18 manual-split-browse-listbrowse-print ▸
2026-08-18 手冊:基本畫面介紹的瀏覽/清單瀏覽/列印拆成三頁
- 拆頁:原
docs/getting-started/browse-print.md(瀏覽、清單瀏覽與列印畫面)拆為三個獨立頁面:
-
browse.md瀏覽畫面(畫面組成、條件區與按鈕列、操作步驟)-
list-browse.md清單瀏覽畫面(與瀏覽的差別、統計格線/樞紐選欄、操作步驟)-
print.md列印畫面與報表預覽(兩種進入路徑、列印控制列、新增操作步驟、報表預覽視窗)- 條件區與按鈕列的完整說明只留在瀏覽頁,清單瀏覽與列印頁以連結指回;常見問題依主題分配到各頁,跨頁問題(瀏覽 vs 清單瀏覽、按列印跑到瀏覽畫面)兩邊都保留一份並互連。
- 同步更新:
docs/getting-started/.nav.yml導覽順序(瀏覽 → 清單瀏覽 → 列印 → 行事曆)、index.md工具列按鈕表與相關功能連結、tools/docs-pdf/manifests/basic-only.jsonPDF 章節清單。
- 截圖檔名與內容不變,無需重拍。
同日補充:定位搜尋欄(導覽列中間輸入欄)功能說明
docs/getting-started/index.md原「代號搜尋欄」段落改寫為「定位搜尋欄(導覽列中間的輸入欄)」,依TsSeekTextBox與TWORK_MOVEREC實作補齊:代號+Enter 定位開頭相符的第一筆、代號;定位開頭相符的最後一筆、打字中輸入[/]/?開查詢視窗(僅限有設定查詢清單的程式,滑鼠停留有提示)、.PKID依內部主鍵 PKID 定位;另補自動大寫、離開欄位即定位、PageUp/PageDown 與 Ctrl 組合快捷鍵、帳款類「財務類別」與庫存類「倉庫/單據類別」附加欄位。
- 拆頁:原
-
08-18 mail-search-tab-cudata-spdata ▸
---
title: 客戶資料表/廠商資料表新增「信件搜尋」分頁
date: 2026-08-18
---
客戶資料表、廠商資料表多一個「信件搜尋」分頁
使用者看得到的變化
位置 改版前 改版後 客戶資料表(CUDATA)分頁列 最後一頁是「索引分類帳」 後面多一頁「信件搜尋」 廠商資料表(SPDATA)分頁列 最後一頁是「加工資料」 後面多一頁「信件搜尋」 切入該分頁 — 自動把目前這筆客戶/廠商代號帶進條件面板的「客廠部代號」並立刻查詢,直接看到這家的往來信件(近 3 個月、上限 200 封,同信件搜尋主程式) 上下一筆換客戶/廠商 — 再切回分頁時重新帶入新代號並重查 條件面板 — 與信件搜尋主程式同一套(日期/客廠部代號/關鍵字/AI 用問的),可自行改條件後按旁邊「查詢」鈕重查 誰看得到
跟索引分類帳分頁一樣走權限閘:使用者要有「信件搜尋(MAILSEARCH)」的瀏覽權限,分頁才會出現;沒權限的人畫面完全不變。
做法(給維護者)
寄生整支 MAILSEARCH,完全比照 CUDATA 索引分類帳分頁寄生 ABOOK2 的做法(ADR 0115):
- 新增
ViewModel/L.Communication/MailsearchHostViewModel.cs(ITabQueryadapter,CUDATA/SPDATA 共用,建構子收「取當前代號」委派);lazyProgramNavigator.CreateHostedQueryProgram("MAILSEARCH")自己一個 DI scope。
CudataViewModel/SpdataViewModel:權限閘掛分頁+Dispose釋放 scope;換筆時既有的AfterMoverRecord→ResetQueryState()機制照舊生效。
TsERP/App.xaml:MailsearchHostViewModel的 DataTemplate(條件在上+查詢鈕、結果在下),條件與主畫面靠既有隱式 DataTemplate 渲染。
- 與索引分類帳的一處刻意差異:切入即自動查詢(信件查詢便宜、有筆數上限與權限閘;帶了代號不查等於白切分頁)。
- Lang:
Common/Lang/Xaml/Cudata.json、Spdata.json補「信件搜尋」四語 key。
驗證狀態
- 建置 TsERP.csproj 0 error;HarnessSmokeTests 8/8。
- runtime 未驗(需 CMSA 密碼做 UIA 登入;待實機切分頁看:分頁出現、代號自動帶入、結果格有信、換筆重查)。
- 新增
-
08-18 fxrate-cosmos-query-retry ▸
2026-08-18 匯率排程:Cosmos 查詢暫時性失敗改原地重試
- 現象:worker 每輪第一個資料庫跑「每日匯率查詢」時,KeyVault/Auth 冷啟動的暫時性錯誤被
TsAPI.GetFXRateFromAzureCosmos吞成「查詢失敗」佔位列,任務再把它當「工作日查無資料」記F(失敗不重試),該日匯率就沒寫;後面的資料庫通道已暖全部成功(2026-08-17 實際發生於 pkid 1715)。
- 修法(
AutoPilot/Bcurrenm_FxRate.cs):偵測到「查詢失敗」佔位列即視為暫時性失敗,原地重試最多 3 次、間隔 30 秒;仍失敗才回F,訊息改為「Cosmos 查詢失敗(API/金鑰暫時性錯誤,已重試 3 次仍失敗,詳見 DebugLog)」,與真正的「Cosmos 查無 {日期} 匯率資料」分開。
- 既有失敗事件重跑:
F不會自動重撿,需手動清狀態(實體表在 csa1 庫):
UPDATE twork_skd_eventitem SET 已完成 = '', 執行開始時間 = NULL WHERE 說明 = N'每日匯率查詢' AND 已完成 = 'F';worker 下一輪即重跑;同日已有匯率單會自動跳過,不會重複寫入。
- 需重新發版 SchedulerWorker(sched-prod 通道)才生效。
- 現象:worker 每輪第一個資料庫跑「每日匯率查詢」時,KeyVault/Auth 冷啟動的暫時性錯誤被
-
08-18 cy-order-reports ▸
朝陽 E.訂單管理:全模組報表接入(69 張)
2026-08-17~18。把朝陽(CY)E.訂單管理整個模組的 VFP 報表移植到 FastReport 並接上列印管線。
此前這個模組一張報表都印不出來——連列印頁與 ProgramClass 都不存在。
使用者看得到的變化
10 支程式的列印按鈕現在會出現報表清單可選:
程式 報表數 內容 客戶資料表 CUDATA 2 客戶資料表、客戶要員資料表 客單品報價 CUQT 1 報價單 客戶產品表 CUINVE 1 客戶產品表 客戶報價單 CUPDMA 3 客戶報價單、明細表(客戶排序)、明細表(品號排序) 訂單管理 ORMAST 13 訂單、訂單(含金額)、兩張橫式、ARCTIC CAT/YMTT/JAM/SOJITZ 嘜頭、客供品表等 PACKING LIST PK 37 裝箱單、發票,及 WARN/POLARIS/AGCO/ANTUNG/HONDA/致勝/山葉興業/石川島 各家標籤 預示表 PREORD 3 明細表、彙總表、彙總表(原始數量及金額) 產銷表 PDTSAL 2 產銷計畫表、產銷計畫表(金額) 年度預估 ESTSAL 1 年度預估表 出貨通知單 SALEMA 3 正常報表、外銷報表、彙總報表 CI 2 CI、CI(無合約號碼) 條件面板一律改成 GroupBox「列印條件」+一列一條件的排法(照 GSLIYPRINT)。
做法上的幾個決定
報表清單走內建
IPrintSource,不寫客戶庫的_rptdat。兩個客戶庫(darbcycsa1/darbnogicsa1)的
_rptdat都沒有這些程式的登錄列,靠登錄資料就得每個客戶端各補一次;而且
_rptdat是用主程式 ProgramClass 名去查的,CY 變體(如 CUINVE_CY)本來就查不到。改走程式內建清單兩個問題一起解。條碼改用 FastReport 的
BarcodeObject,不依賴條碼字型。VFP 有兩種畫法:早期用 Code39 字型(TextObject + Font="3 of 9 Barcode"),2019/02 起部分改用 FoxBarcode 產圖(空 PictureObject)。
兩種都換成
BarcodeObject,字串格式沿用 VFP 的*<前綴><值>*。列印主機不必再裝條碼字型。列印後處理照搬
frxprint.prg。先前以為 SP 回什麼報表就印什麼,實際上 VFP 取數後還會建 cursor 算小計、做樞紐、展開箱號。
這些邏輯在
C:\darb_fox\CY\APJX_BASIC\CY\PRGS\frxprint.prg,已移植進各*ReportBuilder。修掉的既有問題
標籤與正嘜的出貨城市、嘜頭、港口全是空的。 三個問題疊在一起:
①
ShippingCity參數存在,但沒有任何 PK 外掛把它轉給 builder,AGCO/HONDA/ARCTIC 標籤的出貨城市與DEST條碼永遠空白;② 列印頁根本沒有可以填的欄位;
③ 嘜頭與港口在 VFP 是各報表寫死或由「山葉興業別/ANTUNG 別」optiongroup 決定(
scx_ordp_cy.prg3247/3723/5376 三段),新版完全沒實作。已補:
PkReportBuilder.CityOf/YamahaMark/AntungMark,八張標籤各自接上;新增YamahaType/AntungType兩個列印參數;PkPrint.xaml加一個「標籤選項」區塊(出貨城市、出貨客戶、山葉興業別、ANTUNG 別,後兩者用下拉、選項文字照 VFP 的 Caption)。山葉興業別 嘜頭/港口 ANTUNG 別 嘜頭/港口 1 YMES/BARCELONA 1 SAIMA ANTUNG/LA SPEZIA 2 YMME/ROTTERDAM 2 DMT ANTUNG/LAEMCHABANG 3 YMDB/SANTOS 4 YMMC/ATLANTA PK_ADJ AD/(無港口) 5 YMME/RTM PK_ADVN ADVN/HAIPHONG 6 YMRE/MILANO 7 TYM/BANGKOK 8 YJBM/ATLANTA 棧板標籤印不出棧板號。
ExpandPallets要求截止棧板號 >= 起始棧板號才展開,但實測pkde有棧板號的 11,690 筆裡有 11,688 筆的截止棧板號是 0——實務上起始棧板號就是該列的棧板號,截止欄不填。等於對所有真實資料都不展開。已改成截止沒填時當單一棧板處理,並補上整板彙總的棧板淨重/棧板內數量(SP 只回單箱值)。客供品表拿錯結果集。
BuildCustomerSupplied讀Tables[2]當組件展開表,但實測DARB_RPT_ORMAST的 T2 是「訂單聯絡單」,組件展開是 T3 而且只有查詢別 19 才回(Custom(2) 只回三個結果集)。原本這張報表在任何情況下都印不出東西。已補GetOrmastReportDataSet(int queryType, ...)多載並改讀 T3。Cuqtlst 的客戶簡稱/備註(原列為做不了)。
DARB_RPT_CUQT只回客戶代號,兩欄都來自cudata;改成在外掛反查(CyOrderReportLookup.Customers),不動 SP。Salema/Salema3 的配件(原列為做不了)。VFP
salema_p是逐一品號呼叫DARB_BIZ_BOMBOTTOM展 BOM、取配件='Y'的子件品號用換行串起來,只有第 1 張與第 4 張要印。已照樣移植;同品號+同交易日期只展一次,展 BOM 失敗時該格留白、不讓整張單印不出來。POCO 另補了不印在版面上的交易日期——那是展 BOM 的基準日參數。ANTUNG 棧板標籤(Pk_Antung1)的混板樞紐(原列為未實作)。原本誤用通用的
PalletLabel形狀(照棧板號展開),但版面要的是「一板一列+板上客戶品號樞紐成 1~5 組」。新增AntungPallet形狀:先把明細照起訖箱號展成一箱一列,再依起始棧板號彙總,棧板淨重/棧板毛重為該板所有箱子的單箱重量總和,品號依序填進五組欄位(超過五種照 VFP 一樣捨去,版面只有五組)。驗證:反射呼叫出貨的
PkReportBuilder.BuildAntungPallets(不在治具重寫),28 個棧板的箱數、淨重、毛重、五組品號樞紐全部與獨立算出的答案相符。棧板攤重未移植 VFP 2020 年加的重分配那段——它參照一個名為棧板重量的 memvar,新版 SP 沒有對應欄位(該段迴圈在 VFP 裡其實也退化成「直接等於那個 memvar」)。PK 家族 22 張一取真資料就炸(
包裝量型別)。DARB_RPT_PK的包裝量回 decimal,POCO 宣告成 int;DataTableToList是直接SetValue不做轉換,於是整個 PACKING LIST 家族在真實資料下丟Decimal cannot be converted to Int32。已改成跟 SP 一致的 decimal,七張範本的欄位型別一併對齊。(其他系列 SP 的同名欄回 int,型別不一致是來源就有的。)20 處運算式沒有外框,會把程式碼原字印在紙上。 FastReport 只對整段包在
[ ]內的 Text 求值;沒包外框時只代換裡面的[表.欄],其餘照原樣印出。實際印出來長這樣:(string.IsNullOrEmpty() ? 242749 : ) ← 應該印 242749 ('+幣別+') ← 應該印 (TWD)涉及 14 張(Ci、Ci_1、Pk2advn、Pkciadvn、Pkmark1、Pk_Advn、Pk_Agcoplt、Pk_Antung1、Pk_Hondaplt、Ymes、Ymes1、Ymes_Atlanta1、Ymes_Atlanta2ymmc、Ymes_Atlanta2ymmc_A4)。其中 Pk2advn/Pkciadvn 的 TEL/FAX 行還有引號沒跳脫,XML 屬性在
+""那裡就被截斷,後半段整個遺失。轉檔器留下的死欄位宣告。 Ci/Ci_1 的
F/T/NOT(VFP 的.F./.T.被當成欄名)、單價遮罩(VFP 表單變數),Pk2/Pk2pal 的' '(空白字面值)。留著不會壞,但會讓三方名單比對永遠有雜訊,已清掉。PACKING LIST 的 MEAS 型別錯誤。
meas/pl_meas是外箱與棧板的尺寸字串(例91*66*37),POCO 卻宣告成
decimal,一取數就FormatException。已改成string,Pk2/Pk2advn/Pk2pal/Pkplt四張範本的欄位型別一併對齊。數值型的材積另有 SP 的
單箱材積/單板材積,目前沒有報表綁。最後一批把 VFP 原始碼印在紙上的欄位。 11 處:星號截斷(外掛已在建資料時截好,改直接綁欄位)、
Ordwarn2 取客戶品號空白後 3 碼、致勝箱號/棧板號的
RIGHT(STR(1000+號,4),n),以及下面兩個框架函式。全庫掃描後 VFP 專有函式殘留為 0。
金額大寫(CI 的
金額描述)已補上。 原本列為做不了——後來在 CY 的PRGS/util2010.prg找到U_VATOSTR/U_ONESTR/U_TWOSTR的完整定義,已 1:1 移植成CyOrderReportCondition.AmountInWords()(含一億上限與「AND CENT ONE/AND CENTS xx」的角分寫法);幣別英文名照 VFP 的
U_CURRNM改讀bcurren。Pk2pal的板箱數描述(TWO PALLETS THREE CARTONS ONLY.)同源,一併補上。CI 單價的顯示格式。 VFP 是
U_ROUNDTrimEnd(m.單價遮罩, 單價, .F., .T.),但單價遮罩是 VFP表單變數、SP 不回——版面上是幽靈欄位。改成外掛算好的
單價顯示(去尾隨 0:0.5000→0.5)。版面上殘留的 VFP 函式。 轉檔器把 VFP 的運算式原樣搬進 frx,
ALLTRIM()/LEFT()/RIGHT()/SPACE()/IIF()/CTOD()/U_MDY()在 FastReport 都不存在,會印出字面字串或編譯失敗。已全部改寫成 C#:取字串一律夾在
[0, 實際長度]之間(VFP 越界回空字串,C# 會丟例外),英文日期(Aug. 20,2025/August 20,2025)改由外掛的
CyOrderReportCondition.EnglishDate()算好成欄位,不在版面上截字串。運算式沒有外框會印出原文。 frx 的
Text只有整段包在[ ]內才會求值,[表.欄].ToUpper()這種「欄位有框、方法呼叫在框外」的寫法會原字印出.ToUpper()。判準是括號配對而非長相:首個
[的配對]落在字串結尾=整段已是運算式(不可再包),否則才需要補外框。混排型(
[本幣][IIf(…)]※)與已完整型([IIf(…)])都不能包——包了會讓外層當運算式、內層當字串,編譯直接掛掉。
報表 POCO 用英文屬性名會整片空白。
Rpt_E040_CuinveReportPoco與Rpt_E050_CupdmaReportPoco原本是英文屬性名(CustomerCode、SKU…),而報表 SP 回的是中文欄名;
DataTableToList只比對屬性名/[TsColumnName],一欄都對不上 → 印出「筆數正確但每格全空」的報表。CY 線已全面改中文屬性名。
frx 綁到不存在的欄位。 新寫的檢查器比對「frx 引用的欄位」vs「POCO 實際屬性」,發現先前每支報表幾乎都有懸空引用:
_pageno/_PAGETOTAL(VFP 頁碼變數,改綁[Page#]/[TotalPages#])、pub_公司名稱(改綁[CompanyName])、是否SI(SP 欄名小寫,用TsColumnName對映)、以及各種需要外掛補算的欄位。現已全數對齊。客戶產品表漏了品號區間。 VFP
cuinve_p的自訂條件是「客戶代號 BETWEEN … AND 品號 BETWEEN …」兩段,新版只做了客戶代號那段,VM/plugin SQL/XAML 三處都補回。
客戶報價單的
HaveReportData()擋掉明細表。 原本無條件要求「報價單號起訖都有值」,選客戶條件時永遠印不出來;改成依條件別判斷。
金額大寫:修掉舊版的十萬位漏字
移植時逐位對照發現舊版 VFP 本身有 bug:它把金額切成「百萬(2位)/十萬(1位)/千(2位)/百(1位)/個位(2位)」,
THOUSAND只掛在「千位那兩碼」上,所以十萬位有值、千位是00時整個字會消失。影響 x00,000~x00,999 這段,而這是印在出口 CI/INVOICE 上的金額文字。
2026-08-18 裁決:改成正確英文(不沿用舊版行為)。改法是換成標準的三位一組,
順便把舊版遺留的連續空白與
ONLY.前的多餘空白收乾淨。金額 舊版 VFP 新版 100,000 ONE HUNDRED ONLY.ONE HUNDRED THOUSAND ONLY.200,000 TWO HUNDRED ONLY.TWO HUNDRED THOUSAND ONLY.900,500 NINE HUNDRED FIVE HUNDRED ONLY.NINE HUNDRED THOUSAND FIVE HUNDRED ONLY.20 TWENTY ONLY.(兩個空白)TWENTY ONLY.0 ONLY.ZERO ONLY.123,456 正確 不變 驗證:以反射直接呼叫已編譯的
AmountInWords(),19 組邊界值全數符合預期(含百萬進位、角分的
AND CENT ONE/AND CENTS xx兩種寫法)。沿用舊版的部分:一億上限。金額超過 99,999,999.99 仍回舊版那句中文提示
「待轉換數字大於 1億,無法轉換成文字顯示」——這是舊版取位法留下的限制,本次未一併放寬。
覆蓋率:對照 VFP 原始碼盤過
把
vfpcode/scx_ordp_cy.prg裡所有L_FRXNAME=/L_報表名稱=的值抽出來當母體,套上四個改名(PK_致勝1/2→Pk_Win1/2、ORMASTCY_客供品→Ormastcy_Csp、CUPDMA→Cupdma_cy)後比對:張數 VFP 訂單管理會印的報表 68 已移植 67 未移植 1(PI) 另外多做 2(YMES1/YMES3) YMES1/YMES3 沒有出現在字面清單裡,是因為 VFP 用
L_FRXNAME=IIF(INLIST(山葉興業別,4,7,8),'YMES3','YMES1')動態選的,兩支 frx 都實際存在於C:\darb_fox\CY\REPORTS\,所以要做。已知未完成
- PI:朝陽端沒有
PI.frx,也沒有DARB_RPT_PI,做不了。
- 報表版面:轉檔器產出的是草稿,欄寬與對齊未經人眼校對。
驗證
- 範本健檢:69/69 通過(離線渲染治具,走完整 SP→POCO→SQLite→frx Prepare)。
- 真實資料對映檢查:69 張全部用真資料走一次
DataTableToList,66 張完全乾淨;剩下 3 張(Cudata 6 欄、Cudatadtl 2 欄、Ormast1 的建議售價)已用 SQL 證實是來源資料本身全空(cudata 那 6 欄 102 筆全空、ordetl.建議售價48 萬筆全為 0),不是程式問題。
- 逐欄核對(真實資料)5 張,四個 Builder 家族各有代表:
- ORMASTCY(訂單單據,OrmastReportBuilder)
- Ordcat2(ARCTIC CAT 條碼側嘜,OrdmarkReportBuilder):通訊錄地址、5 組 Code39、MM-DD-YY 交期
- Pk2(PACKING LIST,PkReportBuilder):8 張單的列數/數量/箱數/淨重/毛重與 SQL 逐張相符
- Preord2(樞紐,PreordReportBuilder):分桶總計 0/50458/51229 與獨立 SQL 完全一致,114 組交叉比對全中
- Ci(商業發票):1166 張全部的列數/數量/金額與 SQL 相符;金額大寫、幣別英文名、單價去尾零、英文日期都實際印在版面上驗過
- 金額大寫另以反射直接呼叫已編譯的
AmountInWords(),19 組邊界值全對。
- ANTUNG 棧板樞紐以反射呼叫出貨的
BuildAntungPallets,28 個棧板全數相符。
- 標籤/正嘜 43 張逐欄檢查:治具用
DispatchProxy動態實作IAppContext,直接呼叫每支外掛真正的GetReportSource(不是複本),再逐一確認版面綁的欄位有值。
結果 28 張完全乾淨;其餘 15 張的空白欄位逐一追過來源,分別是來源資料稀疏(
合約號碼全庫 533/44882、REQNO全庫 937/483821、出船日/到達日/前置文字)、版面刻意留白(POLARIS 地址的LINE03/05/06),或該板品號種類不足五種(客戶品號4/5)。仍未定案 2 處:
Pkplt的箱號與Ymes3的箱號C——棧板標籤上要印哪一箱的箱號,VFP 的 cursor 同時帶了棧板號與箱號,但選哪一箱沒有明確規則,沒有猜。- 既有報表回歸:非訂單模組的 247 張 frx 與版控 HEAD 逐張比對渲染結果,回歸 0 支。
仍未做
- 69 張都沒有從 TsERP 視窗實際列印過(全部走離線治具)。
- 版面美觀(欄寬、對齊)未經人眼校對。
相關檔案
- 報表範本:
repos/FastReport/*.frx,部署副本C:\dglibrary\REPORTSROOT\Reports\
- 報表 POCO:
Model/Rpt/Rpt_E0*ReportPoco.cs(15 個)
- 匯出外掛:
TworkReportPluginOfficial/(69 支 + 4 個共用 Builder)
- 取數:
Model/ReportBll.cs、Model/ReportBll.CyOrder.cs
- 列印頁:
ViewModel/E.Order/*PrintViewModel.cs、TsERP/E.Order/*Print.xaml
- VFP 來源:
vfpcode/scx_ordp_cy.prg、C:\darb_fox\CY\APJX_BASIC\CY\PRGS\frxprint.prg、C:\darb_fox\CY\REPORTS\*.frx
- PI:朝陽端沒有
-
08-18 arap-report-fixes ▸
2026-08-18 帳款管理報表:收款單列印頁修復+直式報表指錯修正
背景
盤點「帳款管理(I)報表有沒有缺」時,先做了三份比對:
① 手冊 features 寫「列印」的程式 vs VM 實際的報表登錄;
② VFP 帳款列印庫
scx_arpp用到的報表名(GRPMACCL/PAYAPPL1-2/PAYMNTA5/PREPAID/PSHEETD 系/RPSHTD 系/RSHEET 系/PSHETM3 系/PAY4…)vs V2 已登錄;
③
C:\dglibrary\REPORTSROOT\Reports\*.frxvs V2 程式碼裡的報表名稱。結論:帳款模組沒有「該有卻整張不存在」的報表,但有兩個真缺陷(本次修)與四支沒有任何報表來源的程式(待裁決)。
使用者可見變動
1. 收款單列印頁(RSHEETPRINT)從「一開就跳系統錯誤」變成可用。
TsERP/I.ARAP/RsheetPrintPage.xaml的「選擇」欄是 TsDataGrid 時代殘留的 WPFDataGridTemplateColumn,卻放在 TelerikTsRadGridView.Columns裡。build 全綠、XAML 也載得起來,但模板實體化(ApplyTemplate → Measure)時丟
The value "System.Windows.Controls.DataGridTemplateColumn" is not of type "Telerik.Windows.Controls.GridViewColumn",整頁毀掉;而且每個 render pass 重丟一次,2026-08-18 當天的 debuglog 被灌到 62MB。
改用
tsRadGridViewColumn:TsGridViewCheckBoxColumn(同A.SystemData/Secret.xaml慣例)。2. 「直式收款沖帳表」以前會印出橫式。
RsheetPrintViewModel.GetReports()最後兩筆(直式收款沖帳表、直式收款沖帳表(含沖帳明細))的
報表名稱被整段複製成Rsheet2(橫式),報表編號也都是 I050-2。Rsheet4.frx/Rsheet5.frx(皆為直式,無Landscape屬性)與對應插件早就存在,只是沒人指到。已改為 Rsheet4/Rsheet5、編號 I050-4/I050-5。
兩支新的守門測試
LogicBllTests/Harness/HarnessSmokeTests.TsRadGridView內不得殘留WPF的DataGrid欄型別
—— 掃 XAML:檔案含 TsRadGridView 且有未註解的
<DataGrid*Column就紅。第 1 條的那類崩窗以後 build 期就抓到。LogicBllTests/Reporting/ReportRegistrationConsistencyTests
-
每個登錄的報表名稱都要有對應的frx(列印時才跳「檔案不存在」的那類)-
同一報表名稱不得登成不同抬頭(第 2 條那類複製貼上錯誤)兩支都用 allowlist 明列既有債,只擋新增的違規。
順手盤到、本次未修的既有債(allowlist 內)
類型 項目 症狀 登錄了但沒有 frx Pur_qry21~Pur_qry24(G.採購)、Qc_qry21/Qc_qry22(J.品管)選這幾張列印會跳檔案不存在 同名不同抬頭 Trlimatl/Trradtl/Trradea/Trsadetl/Trwkmatl(H.庫存)、Sliy(N.總帳)可能是同一張換排序(無害),也可能同第 2 條那樣指錯,需逐張確認 sqlite 表名與 frx 不符 Abook11~Abook17(登rpt_n100_abook2_report1、frx 用rpt_n080_abook1_report*)、Trial2需確認是否印得出資料 仍然「沒有任何報表」的四支帳款程式(需要規格才能做)
OTHERRP(其他應收付)、ARCLAIM(應收索賠扣款單)、RFE(費用申請單)、COMMISSION(業務員佣金計算)—— 手冊 features 都寫了「列印」,但:
- VFP 沒有對應報表:
scx_arpp的報表清單裡沒有它們;名字接近的tother.frx其實是營業稅申報書、
commpr.frx是內部聯絡單,都不是這四支的。- VFP 也沒有 OTHERRP/CLAIM 以外的原程式:
scx_arp有 OTHERRP(代收付主檔,browsetype=I10B=走瀏覽型列印,
無專屬 frx)、
scx_ord有 CLAIM(索賠單主檔);RFE(rfem/rfed)與COMMISSION(salescommission_history*)在 VFP 完全不存在,屬 V2 新設計。
- 報表 SP 部分現成:
DARB_RPT_RP(rp_m,可供 OTHERRP)、DARB_RPT_PAYAPPLY、DARB_RPT_PREPAID
等已在庫;
索賠/佣金沒有對應 SP。也就是這四張要做就是全新版面設計(欄位取捨需業主確認),不是移植,因此本次不動。
驗證
- ✅ MSBuild 0 error;
HarnessSmokeTests8 支(含新加那支)與ReportRegistrationConsistencyTests2 支全過。
- ✅ runtime 實測(CMSA 登入 localhost darbnogicsa1):收款單 → 前往最後一筆 → 列印,
列印頁正常開啟(修前是系統錯誤),「選擇」欄渲染正常並帶入單號 R5-20180920001;
頁內查詢撈到該筆(483,000)並自動勾選;報表清單五張齊全,第 4、5 張標題為直式版;
按預覽成功產出「報表預覽 Rsheet1」真實資料報表(PDF 存
C:\temps\rsheet-preview\Rsheet1.pdf,直式 210×297mm)。
- 🔴 未驗:Rsheet4/Rsheet5 的實際渲染。那兩張要靠列印頁的自訂清單選第 4/5 項才會產生所需的
4 組 SQLite 表,而該清單不是標準控件、UIA 點不到;離線渲染因缺
_1/_11/_111表而失敗。建議上線前人工點一次第 4 項預覽確認是直式(frx 本身無
Landscape屬性,Rsheet2 有,故版面差異可確定)。 -
08-18 ar-writeoff-tutorial ▸
2026-08-18 手冊新增「應收帳款沖帳教材」情境頁
背景
舊系統(VFP)時代有一份《應收帳款沖帳說明.xlsx》教材:兩條主流程(收客戶票據/銀行電匯不知匯款客戶)+ 11 個示例,
內容幾乎全是舊畫面截圖。使用者希望新系統手冊也有一份對應教材。新頁以新系統程式(Receive/Rsheet/RpfZero)
逐情境改寫,情境編號與舊版一致。
使用者可見變動
- 手冊
I 帳款管理新增頁 應收帳款沖帳教材(docs/I-ARAP/ar-writeoff-tutorial.md),模組首頁多一個提示框指過去;
.nav.yml由gen-doc-nav.py重新產生。- 頁內含「與舊版的差異」對照表,明列新版沒有的東西(見下)。
改寫時查證到的新舊差異(供後續是否補功能參考)
舊版行為 新版現況 證據 收款單 工作流程鈕通知出納/會計收款單無此鈕;轉傳票參數字串 RsheetToSliy-NO-WKFLOWViewModel/I.ARAP/Rsheet/RsheetViewModel.cs:436、Rsheet.xaml無 TsButton沖帳視窗「超收貨款」幣別/金額欄 XAML 整段註解掉;Bll 仍有 OverCharge()但無入口TsERP/Other/RpfZero.xaml:992-997、StrikeEntryBll.cs:194-221減項帳款列反綠 只以「加減別」 +/-表示;底色僅粉紅(有聯絡單)/紅(NoSliy)RpfZero.xaml:250-287暫收單 修改客戶存檔後自動產生收款單並進沖帳同日補齊: ReceiveViewModel.CreateTemporaryReceiptRsheetAndStrike以 ItemsBindingManager 建收款單(收付款別 R、沖帳方式 3、無明細)→HyperLinkWithPkid(RSHEET)→RsheetViewModel.ExtendedFunction1()開沖帳;動手前先檢查 RSHEET 權限/收款單畫面不在編輯中/今天未被 2033 關帳(對齊 VFP 的前置擋門,避免留孤兒收款單);VFP 原碼vfpcode/scx_arp/receive_utf8.prg:3136-3178。runtime 未驗ViewModel/I.ARAP/ReceiveViewModel.cs沖帳視窗分錄格線「財務單ID」雙擊跳帳款 沖帳視窗無超連結;收款單畫面的傳票分錄格線有 Rsheet.xaml:630-638,706-713已確認可行(DB 查證):沖帳 SP
DARB_TUR_RPFZERO以收款單的客戶代號+廠商代號(含廠商代號1/2)同時撈 rp_m → 應收應付互抵成立;DARB_TGR_RPSHT_D對單別2 ∈ (71,24,25,29) AND 單號2='NEW'的分錄自動 INSERT rp_m → 轉預收/暫收會自動立帳款單。待辦
- 10 張截圖待以測試資料操作後補拍(頁尾「需補截圖清單」)。
- 「修改客戶→自動收款單→沖帳」新流程 runtime 未驗(本機庫無未沖暫收單),需走一次批次電匯→暫收→修改客戶端到端。
- 手冊
-
08-18 ar-writeoff-runtime-fixes ▸
2026-08-18 應收沖帳實測:收款單「沖帳」開窗即崩等 19 處修復+全系統其他功能鈕改照標籤
背景
為了驗證新寫的應收帳款沖帳教材,在模擬環境(darbnogicsa1)用 UIA 腳本實際走了
示例 1(本幣支票直接沖帳)與示例 8(批次電匯 → 暫收 → 修改客戶 → 自動建收款單開沖帳)。兩條流程一路踩到 8 個 bug,
其中兩個是 6 月重構留下、會讓收款單按「沖帳」必崩的 regression。全部修完後兩條流程端到端走通,截圖已進教材。
使用者可見變動(修前 → 修後)
# 畫面 修前 修後 根因與修法 1 收款單 › 沖帳一按就跳「Exception has been thrown by the target of an invocation」 正常開沖帳視窗 Rp_mForRPFZero建構式 6/4 改成base()後沒設Context,單據分類setter 用Context.DisplayNameService→ NRE。建構式補SetContext(context)(LogicBll/Other/RpfZero/Rp_mForRPFZero.cs)2 收款單 › 沖帳過了 #1 後跳「StaticResourceExtension 行號 243」 正常 RpfZero.xaml6/2 轉 RadGridView 時把RowStyle="{StaticResource RpfZeroRow}"寫在 attribute,但RpfZeroRow定義在同元素自己的Resources裡(forward reference)。改成<TsRadGridView.RowStyle>property element 放在 Resources 之後3 收款單右側六顆功能鈕 按「批次電匯」跑轉傳票、按「轉傳票」進特殊修改、「特殊修改」灰掉 各鈕做自己的事 鈕的標籤來自權限表 prgsct1.其他N說明(=VFPCMDELSE1~7順序:沖帳/取消沖帳/批次電匯/轉傳票/工作流程/特殊修改/轉票據),C# 卻把 3/4/5 寫成 轉傳票/特殊修改/批次電匯。RsheetViewModel改成IOther1,2,3,4,6:EF3 批次電匯、EF4 轉傳票、EF6 特殊修改;其他 5 工作流程與 7 轉票據不實作(鈕呈灰色)4 應收帳款右側功能鈕 按「修改客戶」進特殊修改、按「批改客戶」才是修改客戶 「修改客戶」=修改客戶 同上根因(權限表 4=修改客戶、5=批改客戶)。 ReceiveViewModel改成IOther1,2,3,4,8:EF4 修改客戶、EF8 特殊修改(禾久權限表順序)。⚠️ 特殊修改在各客戶權限表位置不同(禾久 8、朝陽 6),朝陽待裁決5 收款單 › 批次電匯 開窗只顯示 ViewModel.Other.Rsht_inputViewModel文字,且格線沒有欄位正常視窗(收款註記/迴轉分錄方式/收款日期/幣別/匯率/客戶/銀行帳號+序號/摘要/金額格線) Rsht_input.xaml還是TsWindow、VM 已改走 ContentWindow → 沒 DataTemplate;欄位在「刪真死綁定」時被砍光沒補中文欄。轉成TsView+App.xamlDataTemplate+補 摘要/金額 欄;VM 補Title6 批次電匯 › 儲存 「系統錯誤 程式:RSHEET Object reference not set」 存檔成功、產生收款單並跳到該單 Rsht_inputBll.Save走舊AdeUploadBll.UpdateData(object[]),內部xmlSource從未建立 →UploadNRE。改走 ItemsBindingManager+UploadToSql(adeupload-to-itembinding 模式,獨立 StagingScope)7 應收帳款 › 修改客戶 「Constructor on type TsERP.Other.ChangeNo not found」;修掉後再跳「Value cannot be null (name)」;再修掉後靜默失敗 開「更改暫收客戶」視窗、存檔、自動建收款單並開沖帳 (a) 已廢棄的 WindowHelper.OpenWindow→ 改ContentWindowService.ShowContentWindow(new ChangeNoViewModel(…,2,this));(b)ChangeNoViewModel用ProgramHelper.GetList拿主檔,DataManager 系 VM 沒覆寫GetBindingSourcesPropertyName→ 補GetMasterList()先讀MasterData.ObservableCollection;(c)ReceiveSave.AllowSave對暫收單也要求交易日期(VFP 不檢查;trigger 建的暫收單交易日期空)→ 25 豁免;存檔失敗改成有訊息8 沖帳視窗 › 自動沖帳有負數列(暫收/折讓/退貨)時只把負數列沖掉,正數列一毛不分配 負數沖完後把差額由上而下分到正數列 (a) 沖負數後沒同步 VM 的 Difference(拿到舊值);(b) 找「餘額剛好等於差額」那筆時沒排除負數列,剛沖掉的暫收列本身就命中、而MasterApply對負數列不動作。AutoStrikeRegionViewModel.AutoStrikeExecute先CalculateBalanceCurrencyAmount()再只在+列找9 收款單/批次電匯的「收款別/迴轉分錄方式」 顯示英文 Direct Balance/Make Temporary Receipts After Balance直接沖帳/沖帳後做暫收/暫收沖帳/預收/其他 新增 Common/Lang/Xaml/RSheetReverseEntryMethodEnum.json另外實測確認:參數 2042=Y 時沖帳存檔後出納傳票號/沖帳傳票號自動帶出(示例 1);批次電匯存檔的沖帳分錄與 trigger 建立的暫收單(
25-…)皆正確;修改客戶存檔後自動建收款單(R3-…、收款別 3)→ 跳到收款單 → 開沖帳視窗,帳款格線含暫收(−)列。第二輪(同日稍晚):其他功能鈕改「照標籤」+示例 2~B 全部實測
使用者裁決「都要實測,程式要統一」後把剩下的示例全走過(示例 2/3/4/5/6/7/9/A/B,各截一張進教材),再修:
# 畫面 修前 → 修後 修法 10 所有程式的右側其他功能鈕 照 IOther{N}索引接動作,權限表順序各客戶不同就接錯 → 新增IOtherByName(標籤→動作字典),ActionPanelViewModel優先用它、找不到才退回索引;RsheetViewModel/ReceiveViewModel改實作IOtherByName,一份程式禾久/朝陽通用(朝陽「特殊修改」在其他 6 也對得到)ViewModel/Interface/IOtherByName.cs、ActionPanelViewModel.CreateOtherButtonViewModels11 應收帳款 › 新增 一律「資料重複」存不了:主鍵驗證拿佔位鍵 +++去查 DB,而 nogirp_m殘留一筆 2024 年鍵值真的是+++的孤兒列PrimaryKeyValidateViewModel.CheckPrimaryKey對+++直接放行12 應收帳款 22 折讓 原幣應收付用「原幣稅額」算(300)、本幣用稅額(315)對不上 ReceiveSave:22 折讓原幣=本幣=發票金額+稅額(同 VFP)13 沖帳視窗表頭「沖帳匯率」 改了不會重算票據/電匯分錄列本幣、也不會帶到同幣別帳款列 → 外幣票據永遠差一截 RpfZeroViewModel.StrikeForeignExchangeRatesetter:重算UseStrikeForeignExchangeRate的分錄列、把同幣別帳款列的沖帳匯率同步並重算匯兌損益14 應收帳款 › 特殊修改 改「收款客戶」會連「出貨客戶」一起改(VFP 不會;轉傳票客戶就跑掉) ReceiveEdit.AfterSpecialEdit關NeedUpdateCustVendCode(同PaymntEdit)15 應收帳款 › 修改客戶 存檔後畫面停在假編輯狀態(存取消亮、其他灰) 直接呼叫 Save()/Cancel()後補InEditingLayoutHandle()實測確認可行:外幣票據沖同幣別帳款自動產生兌換收益列(示例 2);跨幣別靠各帳款列自己的沖帳匯率(匯率表依收款日期)換算,表頭「差額」是原幣直接相減、跨幣別要看最下方本幣差額(示例 3/9);退回/折讓/折扣三種減項
自動沖帳一次吃掉(示例 4~6);互抵(示例 7);轉預收→自動建 24 預收單→再沖出貨(示例 A);特殊修改改收款客戶後出現在另一客戶的沖帳格線(示例 B)。第三輪:其餘四項全修+全系統其他功能鈕批次改「照標籤」
# 範圍 修前 → 修後 修法 16 所有還走舊 AdeUploadBll.UpdateData(object[])的存檔(舊TransferBll41 支轉單、BatchAddBll3 支、CommprNoteBll)2 月起 Add/Edit 改用 xmlSource後,這幾個反射入口沒把結果塞回 → 存檔 NREAdeUploadBll.UpdateData/UpdateDataWithModel三個入口把UseRefrectionToCreateUploadData結果指給xmlSource(一處修、全部恢復;runtime 未逐一驗)17 沖帳視窗載入途中例外 DARB_TUR_RPFZERO已寫的 zpermit 沒人清 → 之後每張都「均已鎖住」RpfZeroTransfer.Transfer對TransferHandle包 try/catch →RpfZeroBll.ReleasePassNumber()再 rethrow18 收款單/付款單票據與電匯列的幣別欄 選外幣匯率停在 1;就算抓到也是賣價 (a) Rsheet.xaml/Psheet.xaml幣別欄加ExchangeRateType="Accounting"(原預設關稅匯率表沒資料);(b)RsheetViewModel收款日期改變時把日期推到票據列(CollectionOrPaymentDate);(c)Twork_BLRateBll/ModelHelper.GetAccountingFxRate傳給DARB_BLRATE的 @買賣別 改成 N'買'/N'賣'(原本傳 enum 代碼 1/2,SP 永遠落到賣價——全系統幣別下拉帶出的匯率因此從賣價變成買價,是全域行為變更)19 全系統其他功能鈕 57 支 VM 走 IOther{N}索引派 4 個 agent 三方對照(VFP CMDELSEn.Caption/兩家權限表標籤/C# 方法內容):44 支改IOtherByName,13 支跳過(兩家權限表都無標籤:AUDIT 以外的 FIELDCOMPARE/BCURRENM/RMA/COMMISSION/COMPLAIN/REPAIR/COST/ACCL/BANK/TRRAFEEPRIME/JOBCODE;CI/CUDATA 方法內容與標籤全對不上,不猜、維持原狀待裁決)。批次中發現原本就照索引接錯的:WKDAY、PPURCH、PURCH、TRLOST(5/6/7 整組旋轉)、GPURCH、GSPLACE、GTRRAMA、INVENT、SALEMA、TICKA、TICKSR、ACCEXP、ASSET、SLIY、PAYAPPLY_KC、TRRAMA——即客戶按某顆鈕實際跑的是別的動作兩家標籤對照表存
.claude/tmp/other-button-labels-20260818.json(prgsct1 其他1~8,nogi/cy)。改「照標籤」後:字典沒放的標籤(C# 未實作)與客戶自行改字的標籤會呈灰/無動作,比接錯動作安全;TwramaViewModel/WkramaViewModel的ProgramClass誤寫成PURAMA(權限表 TWRAMA/WKRAMA 各自有「轉單」標籤),agent 兩個鍵都放了先不死鈕,ProgramClass 本身待另案修。沒修(記下來)
RpfZero沖帳視窗關閉後主視窗標題殘留「收付款沖帳畫面」;沖帳視窗客戶簡稱欄空白(名稱反查空表通案)。
- 批次電匯轉暫收時,每張暫收單的備註都用最後一筆匯款摘要(
RpfZeroTransfer取lastItem.票據備註)。
- 「工作流程」其他 5:VFP 建「收款單通知」聯絡單;新版走共用工作流程頁籤,未另做。
- 沖帳視窗表頭「差額」跨幣別時是原幣直接相減(看最下方本幣差額)。
- CI/CUDATA 的其他功能鈕方法內容與權限表標籤全對不上(疑複製貼上/美規功能),維持原索引,待裁決;TWRAMA/WKRAMA VM 的 ProgramClass 誤為 PURAMA 待修。
- 舊
AdeUploadBll.UpdateData(object[])路徑修復僅程式面,41 支舊轉單未逐一 runtime 驗。
驗證
- MSBuild ViewModel/LogicBll/LogicBllTests 0 error(TsERP.csproj 因另一 session 進行中的 TworkReportPluginOfficial 改動暫時建不過,以 ViewModel/LogicBll dll 覆蓋輸出目錄實測);HarnessSmokeTests 8/8。
- runtime:示例 1~B 全部端到端走過(教材 16 張截圖 step1–16)。
- 測試單留在 darbnogicsa1(收款單 R1/R2/R3-2026081800x、R1-2026080300x;帳款 21/22/26-20260818001、19-2026080300x、24-…、25-…;12-20260715014 的收款客戶被改成 +5CA01)。
-
08-17 qry-salpx-cstk-port ▸
2026-08-17 銷售單價異動記錄(QRY_SALPX_CSTK)自 VFP 客製庫移植
背景
選單點「銷售單價異動記錄」(M-120)與「客戶代料查詢」(M-130)都彈「無法建立ViewModel」。
真因在
C:\temps\debuglog\<date>.txt:[ResolveErpViewModelType] 解析不到:className=[Qry_salpx_cstkViewModel] PrgClassVCX=[SCX_DCST] ProgramClass=[QRY_SALPX_CSTK] [ResolveErpViewModelType] 解析不到:className=[Qry_custkp_cstkViewModel] PrgClassVCX=[SCX_DCST] ProgramClass=[QRY_CUSTKP_CSTK]不是 DI 漏註冊,是這兩支 V2 從未實作——
Common/ProgramClass.cs只登了空鍵(commitc7ea7525「ProgramClass 查詢程式登錄」為程式對照表補的代號),沒有 VM/XAML/BLL。手冊兩頁都寫
status: planned。本次先移植 QRY_SALPX_CSTK(使用者裁決順序),QRY_CUSTKP_CSTK 仍待做。舊碼不在
vfpcode/(那裡只有.prg),而是客製類別庫C:\DARB_FOX\ASMBLY\VCXS\scx_dcst.vcx(同支也在
NOGIHISA\VCXS\)裡的表單類別qry_salpx_cstk,繼承sql_qrya;程式碼在同名.vctmemo 檔(Big5)。
使用者可見變動
- 主管資訊 銷售單價異動記錄(M-120) 可以開了,條件只有品號起訖(截止預設
zzzz)。
- 畫面三塊、上下連動:品號清單 → 報價歷史(每張報價單一列、報價項目金額橫展 10 欄)→ 廠商代工報價。
- 報價歷史的項目 1~10 欄標題=該品號實際的報價項目名稱,隨選取品號切換。
- 手冊頁
docs/M-EIS/qry_salpx_cstk.md由「規劃中」改寫為實作版(status: beta),
M-EIS index 的
_CSTK段落同步改。與舊版的差異(刻意)
1. 沒有項目的欄位隱藏,不像舊版留一排空白表頭的空欄。
2.
HEADER01~HEADER10的覆寫錯位不照抄:舊碼 `REPLACE HEADER01 WITH M.HEADER01, HEADER02 WITHM.HEADER02, HEADER01 WITH M.HEADER03, HEADER03 WITH M.HEADER01…` 把 HEADER01 寫三次、02/03 錯接,
是舊版既有缺陷(只影響舊版那張 FRX 報表,畫面表頭走
更換抬頭方法不受影響)。新版按正確語意逐欄對應。若使用者反映舊報表表頭本來就長那樣,再議。
3. 報表拆成兩張:舊版一張 FRX
ORDQRY_CSTK用 relation 把三個 grid 串在同一張卡上印;新版拆成 M120-1 客戶產品銷售單價異動紀錄卡(品號群組+報價歷史,項目名印在群組表頭當欄標題)
與 M120-2 客戶產品廠商代工報價表。Excel 匯出走既有匯出機制,未特別處理。
沿用舊版的行為(有意保留)
- 只撈
已審核='Y',畫面不開放此開關。
- 品號清單同品號只留一列,取查詢結果的最後一筆。
- 報價項目超過 10 個時,第 11 個之後金額不併入任何欄、不進小計(舊註解:「超過就是異常」)。
- 機台噸數=第一個加工項目(序號 001)名稱含「壓鑄」時,項目名去掉「壓鑄-」。
改動清單
檔案 內容 LogicBll/M.EIS/銷售單價異動記錄/QueryParameters+4 個 Source+Bll(新增 6 檔) Common/DataBaseObjectEnum/Procedure.cs加 DARB_QRY_ORDQRY_CSTK、DARB_QRY_單品報價歷史ViewModel/M.EIS/Qry_salpx_cstk{,Condition}ViewModel.cs主 VM(選取連動+項目表頭)與條件 VM TsERP/M.EIS/銷售單價異動記錄{,Condition}.xaml(.cs)三格線畫面與條件面板 TsERP/App.xaml兩個 DataTemplate TsERP/DIExtension.csAddScoped<Qry_salpx_cstkConditionViewModel>()(漏了即「無法建立ViewModel」)Common/Lang/Xaml/Qry_salpx_cstk{,Condition}.json表頭與標籤四語 LogicBllTests/M.EIS/銷售單價異動記錄Tests.cs8 個純邏輯測試(樞紐/抬頭編號/噸數/10 欄上限/預設值) LogicBllTests/M.EIS/Qry_salpx_cstk_DispatcherIntegrationTests.cs4 個整合測試:兩支 SP 的 proc_param 登錄+經 dispatcher 實跑的結果集數與欄位名(欄位一變就紅) Model/Rpt/Rpt_M120_SalpxCstkReportPoco{1,2}.cs兩張報表的 POCO(屬性名=中文;SQLite 欄名直接等於屬性名,見 memory report-sqlite-no-translate-chinese-poco) TworkReportPluginOfficial/Qry_salpx_cstk{1,2}.cs兩支 IExportReportPlugin(類名=報表名稱;插件名稱留空時以報表名稱解析) ViewModel/M.EIS/Qry_salpx_cstkViewModel.cs實作 IPrintSource.GetReports()+GetReportParameters()+HaveReportData()Qry_salpx_cstk{1,2}.frx報表範本:版控來源 C:\Users\momo1\source\repos\FastReport\,部署複本C:\dglibrary\REPORTSROOT\Reports\LogicBllTests/M.EIS/Qry_cstk_ReportTemplateTests.cs四張報表共用的範本測試(frx 表名/欄位 vs POCO/能否 Prepare) 資料來源
兩支 SP 都已存在於
darbnogicsa1與darbasmblycsa1,並登錄在darbnogilog1.proc_param(
databaseid=C、param_qty=2),本次不需要跑任何 SQL:DARB_QRY_ORDQRY_CSTK(@查詢別=1, @查詢條件)→ 3 個結果集:品號主表/廠商報價/品號製程(第 3 集舊版也沒用)。
⚠️ 這支的
OBJECT_DEFINITION顯示的建立名稱是DARB_QRY_CUQTQRY_CSTK(曾被sp_rename改名),別誤認找錯物件。DARB_QRY_單品報價歷史(@查詢別=1, @查詢條件)→ 1 個結果集(cuqtd1 原料 UNION ALL cuqtd2 加工)。
一個差點踩到的坑:`序號` 有尾隨空白
SP 對 cuqtd1 的列輸出字面值
'000',對 cuqtd2 的列輸出加工序號。實際資料(darbcycsa1,14198 筆)的
加工序號/材料序號是 char(6) 補空白('001 '),VFP 的序號='001'在SET EXACT OFF下照樣命中;C# 端必須
Trim()後比對,直接== "001"會全部落空、單重/材料單價/噸數永遠空白。本版已 Trim。
⚠️
darbdemocsa1的 5 筆是造出來的示範資料,序號長成'000010'/'0000000010',不代表正式格式,別照它調程式。
驗證
- ✅ MSBuild:
TsERP.csproj全綠 0 error(含 XAML 編譯)。因使用者的 TsERP.exe 正在執行、bin 被鎖,
改用
-p:OutputPath=C:\temps\build-salpx\out\導向別處編譯。- ✅ 新增 8 個單元測試+4 個整合測試全過(整合測試證明 dispatcher 路徑通、
@result=OK、
三個/一個結果集的欄位名與 Source 完全對齊);
HarnessSmokeTests7 支全過;LogicBllTests全套 1158 支僅 1 失敗,是既有的
PocollabOverdueAlertTests.掃描並通知_依發送人分組寄信_fallback_抑制重跑不重複(綁 dev 資料,與本次無關)。- 🔴 runtime 未驗:① TsERP.exe 執行中無法覆蓋 bin;② 本機
darbnogicsa1/darbasmblycsa1的
cuqtm都是 0 筆(只有darbcycsa1有 14215 筆,但朝陽庫沒有這兩支 SP),沒有可驗證輸出的資料。上線前需在有報價資料的環境開窗實測:三塊格線內容、項目欄標題隨品號切換、噸數帶出。
2026-08-17 runtime 實測(CMSA 登入 localhost/darbnogicsa1「模擬環境」)
用
TsERP.exe --screenshot <清單>批次模式導覽+UIA 驅動,實機確認:- ✅ 兩支都開得起來——登入時的選單掃描(debuglog
[ResolveErpViewModelType] 解析不到那批)
已不再出現
Qry_salpx_cstkViewModel/Qry_custkp_cstkViewModel(同日 16:19 還在),「無法建立ViewModel」不再發生。
- ✅ 條件面板與預設值正確落地:SALPX=品號
空白~zzzz;CUSTKP=客戶/品號空白~zzzzzz、
交易日期
2014/12/01~2026/08/17、依客戶區間篩選已勾。- ✅ 格線與欄標題正確(SALPX 三塊、CUSTKP 兩塊);沒有項目的項目1~10 欄如預期隱藏。
- ✅ 兩支的列印面板都列出各自兩張報表(IPrintSource 登錄生效),附 預覽/列印/Excel。
- ✅ 實際按
查詢走完整 dispatcher→SP 路徑,無任何錯誤框、debuglog 無例外堆疊;
結果 0 筆(該庫
cuqtm0 筆、bom_d.備料倉庫非客戶代號,屬預期)。- ✅ 0 筆時按
預覽→ 乾淨的「沒資料」提示(HaveReportData 守門有效),不崩。
- 🔴 仍未驗:有資料時的數字與報表版面。本機所有可登入的庫都沒有這兩支的資料,
必須在「BOM 備料倉庫填客戶代號、有已審核客戶單品報價」的環境(亮群)對帳。
報表版面已另以合成資料 PDF 驗過(
Qry_cstk_ReportTemplateTests+ 四張 PDF)。順帶:同批次掃了 M+I 兩子系統共 57 支(35 OK/22 FAIL=CMSA 在此庫無權限或該 doc id 非真 ProgramClass),
無新的開窗即崩;截圖存
C:\temps\smoke-20260817\。 - 主管資訊 銷售單價異動記錄(M-120) 可以開了,條件只有品號起訖(截止預設
-
08-17 qry-custkp-cstk-port ▸
2026-08-17 客戶代料查詢(QRY_CUSTKP_CSTK)自 VFP 客製庫移植
接續同日 銷售單價異動記錄移植,把
_CSTK客製系列第二支(也是「無法建立ViewModel」兩支中的另一支)補完。舊碼同樣在
C:\DARB_FOX\ASMBLY\VCXS\scx_dcst.vcx的表單類別qry_custkp_cstk(繼承sql_qrya)。使用者可見變動
- 主管資訊 客戶代料查詢(M-130) 可以開了。條件:客戶起訖、品號起訖、交易日期起訖、
依客戶區間篩選(=舊版條件別 1/2)。- 畫面上下兩塊、上下連動:代料庫存統計(料號×客戶:前期庫存/調整/入庫/出庫/結存)
→ 進出料明細(首列「期初」,其後逐列累計結存)。
- 手冊頁
docs/M-EIS/qry_custkp_cstk.md由「規劃中」改寫為實作版(status: beta),
M-EIS index 同步改為「可用」。
與舊版的差異(刻意)
1. 拿掉客戶 A0055(墩豐)的小數位特例:舊碼
IF m.客戶代號='A0055' → ROUND(...,3) ELSE ROUND(...,4),2026-08-17 使用者裁決一律 4 位。該客戶的重量會與舊系統差第 4 位,屬預期差異
(記憶:
custkp-cstk-no-customer-special-case)。2. 不做舊版那些「算了卻被丟掉」的欄位:舊碼算
隸屬倉庫(查 #depotno)、倉儲代號、入庫數量、出庫數量,但CUSTKP_CSTKD的 CREATE CURSOR 沒有這些欄位,INSERT FROM MEMVAR時全部被靜默丟棄。本版一併不做(SP 第 5、6 集因此也不取用)。3. 報表已移植:舊版
CUSTKM/CUSTKD兩張 VFP FRX 改成 FastReportM130-1 客戶材料歷史庫存統計表(報表尾合計)與 M130-2 客戶進出料庫存明細表
(料號×客戶群組、群組尾小計、保留舊版四個簽章欄)。舊版「報表選擇」單選鈕不再需要——
兩張報表在列印面板各自一列。Excel 匯出走既有機制,未特別處理。
沿用舊版的行為(有意保留)
- 代料關係認定:
bom_d.備料倉庫 = cudata.客戶代號(SP 內 INNER JOIN),料號=客供料、
組件編號=用掉它的成品。
- 重量:材料本身的進出直接取數量;組件的進出=
數量 × 單重(四捨五入 4 位)。
AA開頭單號=盤點調整(VFPIF 單號='AA',SET EXACT OFF 下是前綴比對 → C# 用StartsWith)。
- 期初列:交易日期填
' 期 初',靠前導空白在索引
(
料號+客戶代號+交易日期+交易別碼,見PRGS/opendbf.prg的 CREATE CURSOR)裡排在所有日期之前;本版以序數排序重現,明細第一列即期初。
- 組件的進出不再比對倉儲=客戶(只比品號=組件編號),與原料段不同。舊版如此,照舊以免結存對不上舊報表。
- 沒有本期明細的主表列不插期初列,結存=前期庫存。
- 起始日期預設
2014/12/01(舊版 Init 寫死的開帳日)。SP 內另有保護:起始日早於
stkbas.開帳月份會被拉到開帳次月 1 日。⚠️ 這個預設值等於「從開帳查起」,資料量大時查詢會久。改動清單
檔案 內容 LogicBll/M.EIS/客戶代料查詢/QueryParameters+6 個 Source(代料組件/期初成本/前期異動/本期交易/主表/明細)+Bll(新增 8 檔) Common/DataBaseObjectEnum/Procedure.cs加 DARB_QRY_CUSTKP_CSTKViewModel/M.EIS/Qry_custkp_cstk{,Condition}ViewModel.cs主 VM(主表選取→明細)與條件 VM TsERP/M.EIS/客戶代料查詢{,Condition}.xaml(.cs)兩格線畫面與條件面板 TsERP/App.xaml/TsERP/DIExtension.cs兩個 DataTemplate; AddScoped<Qry_custkp_cstkConditionViewModel>()Common/Lang/Xaml/Qry_custkp_cstk{,Condition}.json表頭與標籤四語 LogicBllTests/M.EIS/客戶代料查詢Tests.cs10 個純邏輯測試 LogicBllTests/M.EIS/Qry_custkp_cstk_DispatcherIntegrationTests.cs2 個整合測試(proc_param 登錄+6 結果集欄位) Model/Rpt/Rpt_M130_CustkpCstkReportPoco{1,2}.cs兩張報表的 POCO TworkReportPluginOfficial/Qry_custkp_cstk{1,2}.cs兩支 IExportReportPlugin ViewModel/M.EIS/Qry_custkp_cstkViewModel.cs實作 IPrintSource+報表資料轉換Qry_custkp_cstk{1,2}.frx報表範本:版控來源 C:\Users\momo1\source\repos\FastReport\,部署複本C:\dglibrary\REPORTSROOT\Reports\資料來源
DARB_QRY_CUSTKP_CSTK已存在於darbnogicsa1/darbasmblycsa1,且登錄在darbnogilog1.proc_param(databaseid=C、param_qty=4)。本次不需要跑任何 SQL。回 6 個結果集:① 期初成本(costm/costd 期末數)② 前期異動(成本截止日~起始日,六段 UNION)
③ 本期交易明細(起始~截止日)④
#partno(料號×客戶×組件)⑤#itemno⑥#depotno。⚠️ 參數順序:SP 宣告是
(@pc_品號條件, @pc_客戶條件, @pc_起始日期, @pc_截止日期),但舊版傳的是 (客戶條件, 品號條件, 起始, 截止)。兩者都只是 WHERE 片段、在 SP 內以
AND串接,順序顛倒不影響結果。本版照舊版順序傳,
Bll.取得SQL資料()有註解說明,不要「順手改正」。驗證
- ✅ MSBuild
TsERP.csproj0 error(含 XAML)。TsERP.exe 執行中鎖住 bin,改用
-p:OutputPath=C:\temps\build-salpx\out\。- ✅ 10 個單元測試+2 個整合測試全過;
HarnessSmokeTests7 支全過。
- 🔴 runtime 未驗,且本機不可能驗:
bom_d.備料倉庫在darbnogicsa1(1555 筆)與
darbasmblycsa1(18412 筆)存的是倉庫名稱(「1.可用倉」、「1.禾久」)而非客戶代號,INNER JOIN cudata全部落空 → SP 六個結果集都 0 筆。這支客製程式只有在「BOM 備料倉庫填客戶代號」的環境才有資料。上線前必須在該環境實測:
兩塊格線內容、期初列、逐列結存、AA 調整單歸屬、與舊系統的數字對帳(注意 A0055 第 4 位差異)。
2026-08-17 runtime 實測(CMSA 登入 localhost/darbnogicsa1「模擬環境」)
用
TsERP.exe --screenshot <清單>批次模式導覽+UIA 驅動,實機確認:- ✅ 兩支都開得起來——登入時的選單掃描(debuglog
[ResolveErpViewModelType] 解析不到那批)
已不再出現
Qry_salpx_cstkViewModel/Qry_custkp_cstkViewModel(同日 16:19 還在),「無法建立ViewModel」不再發生。
- ✅ 條件面板與預設值正確落地:SALPX=品號
空白~zzzz;CUSTKP=客戶/品號空白~zzzzzz、
交易日期
2014/12/01~2026/08/17、依客戶區間篩選已勾。- ✅ 格線與欄標題正確(SALPX 三塊、CUSTKP 兩塊);沒有項目的項目1~10 欄如預期隱藏。
- ✅ 兩支的列印面板都列出各自兩張報表(IPrintSource 登錄生效),附 預覽/列印/Excel。
- ✅ 實際按
查詢走完整 dispatcher→SP 路徑,無任何錯誤框、debuglog 無例外堆疊;
結果 0 筆(該庫
cuqtm0 筆、bom_d.備料倉庫非客戶代號,屬預期)。- ✅ 0 筆時按
預覽→ 乾淨的「沒資料」提示(HaveReportData 守門有效),不崩。
- 🔴 仍未驗:有資料時的數字與報表版面。本機所有可登入的庫都沒有這兩支的資料,
必須在「BOM 備料倉庫填客戶代號、有已審核客戶單品報價」的環境(亮群)對帳。
報表版面已另以合成資料 PDF 驗過(
Qry_cstk_ReportTemplateTests+ 四張 PDF)。順帶:同批次掃了 M+I 兩子系統共 57 支(35 OK/22 FAIL=CMSA 在此庫無權限或該 doc id 非真 ProgramClass),
無新的開窗即崩;截圖存
C:\temps\smoke-20260817\。 -
08-17 mail-search-custvend ▸
---
title: 信件搜尋歸戶擴充到廠商(客戶代號 → 客廠部代號 + 分類)
date: 2026-08-17
---
信件搜尋:歸戶不再只認客戶,廠商來信也歸得了戶
使用者看得到的變化
位置 改版前 改版後 查詢條件面板 「客戶代號」,seek 只查得到客戶( CustomerSearch/cudata)「客廠部代號」,seek 一格同時查得到客戶/廠商/部門( CuspSearch/vwseek_cusp)結果格 一欄「歸戶客戶代號」 兩欄:「歸戶分類」(顯示 客戶/廠商/部門,不是 C/S/D 原碼)+「歸戶代號」 重建歸戶訊息 「客戶 email 來源 N 筆」 「客戶/廠商 email 來源 N 筆」 AI「用問的」 只聽得懂客戶(「大同寄來的信」) 客戶與廠商都聽得懂(「某某供應商的交期信」也解析得出對象) AI 工具 search_mailcustomer_code只吃客戶代號customer_code客戶或廠商代號都吃;回傳多一個「分類」欄告訴模型比中的是哪一種歸戶來源多了兩張表:原本只讀
cudata(客戶主檔)+cudata_1(客戶聯絡人),現在加上
spdata(廠商主檔)+spdata_1(廠商聯絡人)。實查
darbnogicsa1:spdata215 筆有 email、spdata_1600 筆有 email(
spdata_1.linkid → spdata.pkid實測 600/600 全部 join 得到),資料是齊的。既有的歸戶資料不受影響:本機 13 筆既有歸戶列全部來自客戶主檔,migration 由
DEFAULT 'C'自動補上分類,一筆都沒有刪、沒有改代號。
> ⚠️ 舊資料不會自動長出廠商歸戶。歸戶只在「同步當下對本輪抓回來的信」做一次;
> 要讓既有的信也比對廠商 email,請在信件搜尋畫面按一次「重建歸戶」(冪等、可重按、只動自己名下的信箱)。
查詢語意:為什麼只有一格,不分客戶/廠商兩欄
使用者裁決:條件只給單一「客廠部代號」欄。
實查
darbnogicsa1,cudata.客戶代號與spdata.廠商代號的撞號筆數 0——拆兩格只會多一個要填對格子的負擔,得不到任何精確度。
真的撞號時,兩邊的信都會回來(SQL 只比代號、不比分類),由結果格的「歸戶分類」欄分辨。
同理,AI 工具的
customer_code也不分兩個參數:模型不必先猜「使用者講的是客戶還是廠商」。為什麼用 `cusp` 的分類碼,而不自創一套代碼
帳套庫本來就有
cusp(客戶/廠商/部門綜合表,實查 5779 筆),欄位就叫
分類/客廠部代號/客廠部簡稱/客廠部名稱,分類的值域是 C=客戶(4859)/S=廠商(892)/D=部門(28)。沿用它的三個理由:
1. 不會出現「同一個概念兩套代碼」。系統其他地方(seek、報表、查詢)講的分類就是這一套,
信件搜尋自創
CUST/VEND只會讓人日後對不上。2. 畫面直接有現成資產:
CuspSearch樣式(ProgramClass=CUSP/ExistTable=vwseek_cusp/SeekCondition=客廠部代號)已經存在,條件欄換個 Style 就好,不必新增任何 seek 定義或字典。3. AI 公司名反查一次到位:
查詢客廠部改查cusp,一句查詢就涵蓋客戶+廠商+部門,不必先猜對象種類再決定查哪張表。
cusp沒有 email 欄,所以歸戶的 email 來源仍然各自讀cudata/cudata_1/spdata/spdata_1;只有「名稱 → 代號」的反查走
cusp。這是既有 ADR 0128 的語意擴充(歸戶對象從「客戶」放寬成「客廠部」),比對規則、權限閘、
200 筆上限、公用網域排除全部沒動,不另開 ADR。
Schema 變更
darb*auto1.dbo.twork_skd_mailcust:項目 改版前 改版後 欄位 客戶代號 nvarchar客廠部代號 nvarchar(改名,sp_rename)欄位 — 分類 char(1) NOT NULL DEFAULT 'C'(新增;既有列自動補 C)唯一鍵 UQ(郵件pkid, 帳套庫名, 客戶代號)UQ(郵件pkid, 帳套庫名, 分類, 客廠部代號)索引 IX_..._查詢(帳套庫名, 客戶代號) INCLUDE(郵件pkid)IX_..._查詢(帳套庫名, 客廠部代號) INCLUDE(郵件pkid, 分類)唯一鍵一定要含分類:少了它,客戶 A001 已歸戶時,廠商 A001 會被
IF NOT EXISTS誤判成「已存在」而永遠寫不進去(靜默漏歸戶)。
索引的前導欄刻意不含分類——查詢條件只比代號,分類只需要進
INCLUDE供顯示。部署步驟
1. 先確認
sql/mail-search-deploy-20260811.sql(四張 mail 表的母本)已經跑過。2. 跑
sql/mail-search-custvend-20260817.sql(目標庫darbnogiauto1):```powershell
sqlcmd -S <伺服器> -E -d darbnogiauto1 -f 65001 -i sql\mail-search-custvend-20260817.sql
```
⚠️ 檔案是 UTF-8 無 BOM 含中文,
-f 65001不可省(少了它會靜默漏建物件卻回 exit 0)。跑完看檔尾驗證段實查
sys.columns/sys.indexes的輸出,不要只看 exit code。本檔冪等,重跑安全(第二次執行不做任何事)。
3. 發布桌面端(含
ViewModel/TsERP)與 worker(AutoPilot)——程式與 SQL 要一起上:新版程式查的是
客廠部代號,SQL 沒跑會撞「無效的資料行名稱」。4. 請使用者在信件搜尋畫面按一次「重建歸戶」,把既有的信補上廠商歸戶。
CY(朝陽)/SQL 2008 注意事項
- 字串代換
darbnogiauto1→darbcyauto1另存後再跑。
- migration 已避開 2016+ 專屬語法:沒有用
DROP INDEX IF EXISTS/DROP CONSTRAINT IF EXISTS
(改用
IF EXISTS (SELECT 1 FROM sys.indexes …)的舊寫法)、沒有THROW/OFFSET FETCH。sp_rename … 'COLUMN'與「加 NOT NULL 欄位帶 DEFAULT」在 2008 都可用(2008 會實際改寫資料頁而非 metadata-only,13 筆的量無感)。
順手修掉的既有缺陷
「重建歸戶」的訊息會顯示錯誤的(甚至負數的)新增筆數:
IF NOT EXISTS … INSERT在冪等 no-op 時ExecuteNonQuery回的是 -1 不是 0(2026-08-17 實測),舊寫法直接累加。已補上
> 0守門(同步端MailSyncService本來就有這道,只有桌面端漏了)。 - 字串代換
-
08-17 cudatalimit-wire-up ▸
2026-08-17 客戶信用額度設定(CUDATALIMIT)接上資料表,畫面不再報欄位對不上
使用者看得到的變化
- 信用額度設定終於能用:先前一開窗就跳「XAML 綁定有、SQL 欄位沒有」,單身(各客戶額度)永遠是空的,
新增時單號也編不出來。原因是程式沿用舊 VFP 的資料表設定,撈到的是舊版單一表
cudatam,而新版畫面要的是「一張生效日期單管多客戶」的主檔+單身兩張表。現在已指向正確的資料表。
- 單號格式:新增單時自動編為
CL+ 西元年 + 5 碼流水(例:CL202600001)。
- 欄位名稱:主檔左上的「設定日期」改稱建檔日期(與資料庫欄位一致,仍是新增時自動帶今天、唯讀)。
單身的「上次額度」「最新額度」顯示文字不變。
- 客戶資料表的「Credit limit」查詢頁同步修好:先前客戶名稱/最新額度/前次額度抓不到值(空白或 0),
現在會正常顯示。
注意
- 新版寫入的是新資料表,與舊 VFP 系統的信用額度資料不互通;舊系統維護的既有資料不會出現在新版畫面,
舊系統本身也照常可用(設定沒有被改動)。舊資料經裁決不搬移,新版從零開始建立。
- 選單與權限設定不需要調整(仍掛在原本的「信用額度」項目上)。
技術決策見 ADR
0137-cudatalimit-program-key-split。 -
08-16 spdata-remark-selfdefined-layout ▸
2026-08-16 廠商資料表:備註與自定義改成右欄上下疊放(比照客戶資料表)
摘要
廠商資料表(
SPDATA)基本資料分頁的版面比照 2026-08-12 客戶資料表(CUDATA)改版:「備註」由左欄底部搬到右欄上方並隨視窗展開,「自定義」移到其下方並固定高度。
變更
TsERP/G.Purchasing/SpdataTab1.xaml:- 左欄由 6 個 GroupBox 縮為 5 個(基本資料/地址資訊/聯絡與通訊/負責人與聯絡人/會計與採購條件),
原本墊在最下面的「備註」群組移出。
- 右欄由單一「自定義」群組改成三列 Grid:**頂端 50 空白/備註(
*)/自定義(Auto)**。
- 備註:拿掉固定
Height="80",改成上下左右 Stretch,吃掉右欄扣掉自定義後的所有空間,並加
TextWrapping="WrapWithOverflow"。- 自定義:格線固定
Height="200"(標題列+約 6 列資料,超過捲動);「分類」欄由
SizeToHeader改Width="150",「內容」欄改Width="*"+MinWidth="300",跟著視窗寬度展開。欄的 CellTemplate/CellEditTemplate(下拉可編輯)維持原樣。
- 頂端 50 的空白列沿用改版前自定義群組的
Margin="2,55,2,2":框架的ExtensionPanel(右上角 pkid/已審核)是疊在程式內容之上的 overlay,備註滿版延展後上緣會頂到它。
- 資料繫結未動:備註仍綁主檔
備註,自定義格線仍是ItemsSource="{Binding Detail1}"、
設定鈕仍走SelfDefinedCommand。同步更新
docs/G-Purchasing/spdata.md中「自定義(右上格線)」的位置描述。未套用
Spdata_US/Spdata20230829/SpdataOldd三支變體/舊版畫面版面結構不同(非分頁式),本次未動。Breaking Changes
- 無。純版面調整,未動資料或存檔邏輯。
待驗
- runtime 未驗:需開 SPDATA 確認 ①備註框隨視窗寬度變寬、輸入與捲動正常
②自定義只顯示約 6 列、內容欄跟著變寬且下拉可編輯 ③「設定」按鈕在編輯狀態下仍可按
④備註上緣沒有被右上角 pkid/已審核面板蓋住。
-
08-16 mail-search-multikeyword-and-ai ▸
2026-08-16 信件搜尋:多關鍵字語法、內建同義詞、AI「用問的」、查無結果 AI 同義詞補救
使用者可見變動
1. 關鍵字欄支援多關鍵字語法
「信件搜尋」條件面板的關鍵字欄不再只能填單一詞,支援以下語法(可混用):
語法 意思 範例 空白分隔 且(AND) 報價 交期→ 同時含「報價」與「交期」大寫 OR(前後夾空白)或 報價 OR 訂單→ 含「報價」或「訂單」-詞(減號緊貼詞首)排除 報價 -取消→ 含「報價」但不含「取消」"片語"(雙引號)連續片語(不拆詞、不展開同義詞) "報價單編號"→ 完整比對這串文字三者可混合使用,例如
報價 OR 訂單 交期 -取消表示「(報價 或 訂單)且 交期,但排除含取消的信」。畸形輸入(孤立的OR、落單的引號、連續空白等)一律當成一般文字比對,不會顯示錯誤或查詢失敗。2. 內建同義詞(「含同義詞」核取方塊)
關鍵字欄旁新增「含同義詞」核取方塊,預設勾選。勾選時,查「報價」也會一併比對「報價單」「估價單」「quotation」「quote」「RFQ」等同義詞;涵蓋交期、訂單、發票、出貨、付款、對帳、退貨、規格、樣品、價格、折扣、庫存、催貨、不良、合約、包裝、運費、型錄、驗收等 20 組常見商務詞,中英文互查。這套字典是固定內建的,不呼叫 AI、不需要網路連線。
"片語"(雙引號)內的詞不會展開同義詞——片語比對的是完整字串,展開同義詞會破壞片語語意。3. 新增「用問的」:AI 把一句話翻成查詢條件
條件面板最上方新增「用問的」文字框,可以直接打一句口語化的描述,例如:
- 「上個月大同寄來關於交期的信」
- 「找報價 OR 估價相關、不要取消的信」
- 「今年跟甲山公司往來的信」
按查詢後,系統會先呼叫 AI 把這句話解析成客戶代號、關鍵字、起訖日期等條件,回填到畫面上的對應欄位(使用者看得到、也能再手動調整),接著才照原本那套查詢邏輯撈信——AI 只負責翻譯條件,不負責也看不到任何信件內容。
- 公司名只有在客戶主檔剛好比對到 1 筆時才會自動代入客戶代號;找不到或有多筆同名時,系統會改把公司名併入關鍵字比對,並在訊息列說明原因,不會亂猜代號。
- 相對日期(上個月、本週、今年等)由 AI 依系統當下日期換算成絕對日期。
- 「用問的」欄留空=完全不觸發 AI,查詢行為與加這個功能之前完全一樣。
- 若系統尚未設定 AI 金鑰(
_prgparCLAUDE_API_KEY),訊息列會說明「AI 解析停用」,並直接用畫面上現有的條件查詢——不會擋住查詢。AI 解析逾時(30 秒)或回應無法解析時同樣會退回用畫面條件查詢,並在訊息列說明原因。
4. 查無結果時的 AI 同義詞補救
當關鍵字查詢結果 0 筆、且 AI 可用時,系統會自動再呼叫一次 AI,找出該關鍵字的同義詞、近義詞與英文對應詞,與原詞一起重查一次(只做這一輪,不會反覆擴展)。若重查有結果,訊息列會顯示「原條件查無結果,已用 AI 擴展同義詞:報價單/quotation/估價單」;若擴展後仍是 0 筆,或 AI 呼叫本身失敗,維持原本「查無符合的信件」的訊息,不會額外打擾。
相容性
- 資料庫不需要部署任何 SQL——本次全部是查詢端邏輯與 UI 條件欄變動,沒有新表、沒有欄位異動。
- 原本的關鍵字查詢、日期區間查詢、客戶代號過濾行為完全不變;「用問的」欄留空時查詢流程與本次改版前一致。
- 新增的兩處 AI 呼叫(用問的解析、同義詞補救)都在背景執行緒進行,逾時/例外不會讓查詢卡住或失敗。
相關
- 手冊:信件搜尋
-
08-16 mail-sa-keyfile-dpapi ▸
2026-08-16 信件同步:服務帳戶改走金鑰檔+DPAPI 機器綁定,新增兩支 CLI
適用對象:部署/IT 人員(端使用者操作不變)。
為什麼改
免金鑰(signJwt)模式導入隔天同步就中斷:
invalid_grant / reauth related error (invalid_rapt)。那不是設定壞掉——免金鑰用的是排程主機上某個真人的 ADC 憑證,受 Google Workspace「Cloud 工作階段控制」管,
預設 16 小時就要求重新驗證。開發機能手動重登,無人值守的排程不行。
改成服務帳戶金鑰檔(機器身分,不會過期),長期保管問題用 DPAPI 補。詳見 ADR 0133 的 2026-08-16 修訂段。
新增的 CLI 子命令(`TsERP.SchedulerWorker.exe`)
命令 用途 --mail-sync [初次同步天數=90] [單次上限=500]立即抓一輪信進索引。只做信件同步,不會觸發其他到期排程事件(本機模擬庫有數十筆會真的寄信的事件)。不做客戶歸戶——歸戶需要完整 AppContext,請走排程事件 Mail_Sync--mail-sa-protect <明文金鑰路徑> [輸出路徑]把服務帳戶 JSON 金鑰轉成機器綁定密文(DPAPI, LocalMachine)。不覆蓋、不刪原檔;轉完會印出後續四步行為變更
- 金鑰檔可以是明文 JSON 或 DPAPI 密文,程式依標頭
TSERP-DPAPI-V1:自動判別,兩種都收(既有部署不必一次全換)。
- 讀金鑰檔遇到權限不足時,訊息從 .NET 原文
Access to the path ... is denied換成中文指引:印出目前執行身分,並給三條解法(以系統管理員身分執行/排程改用 SYSTEM/icacls授權,含可直接複製的指令)。
起因是實際踩到:帳號屬於 Administrators 群組還不夠,未提權的視窗拿到的是 UAC 過濾權杖,該群組在權杖裡是停用的。
- DPAPI 密文解不開時(換機器/重灌/從別台複製過來)訊息會直接說明那是設計如此,並指出要用原始 JSON 在該機器重轉。
部署注意
- 不能在一台機器轉好密文再發給客戶:密文綁機器。流程是「明文帶到目標機器 → 在那台機器上
--mail-sa-protect→ 鎖 ACL → 改設定 → 驗證 → 刪明文」。
- 原始 JSON 金鑰要另外保存(密碼管理器):換機時密文救不回來。
- 切到金鑰檔時必須刪掉
MailSearch:Gmail:ServiceAccountEmail,否則程式仍以免金鑰為準(安全預設,兩鍵並存時不退回較弱的一邊)。
- 換憑證路線不必重設 admin.google.com 的網域全域委派(同一個服務帳戶、同一組用戶端 ID 與範圍)。
完整步驟:
deploy/mail-gmail-service-account-runbook.md - 金鑰檔可以是明文 JSON 或 DPAPI 密文,程式依標頭
-
08-15 sliybrowd-grid-hyperlink ▸
會計日記帳:代號欄與單號欄加上超連結
2026-08-15
使用者可見的變動
會計日記帳(傳票查詢,
SLIYBROWD,N-070)的表格中,下列欄位變成藍字加底線,單擊即可跳到對應的主檔或單據;跳過去之後按「返回」會回到日記帳查詢頁,不是回主選單。
欄位 點下去開啟 傳票號碼 傳票輸入(SLIY) 科目代號 會計科目主檔(ACCL) 項目代號 會計項目主檔(ACCITEM) 部門代號 部門主檔(DEPT) 客廠代號 依該列分類:客戶→客戶資料(CUDATA)、廠商→廠商資料(SPDATA)、部門→部門主檔(DEPT) 員工編號 人事資料(PERDATA) 專案代號 專案主檔(APROJ) 單號1/單號2
單號1/單號2 也可以點了。目標單據看單號本身的長相決定(不是看旁邊的「單別」欄):
單號長相 點下去開啟 P開頭+純數字(例P20180430002)付款單(PSHEET) R開頭(例R1-20180503001)收款單(RSHEET) XX-開頭 → 前兩碼查財務單據定義(RPDEF)的財務類別,看它的程式類別:程式類別 R(例 12-、19-)應收帳款(RECEIVE) 程式類別 P(例 51-~55-、61-)應付帳款(PAYMNT) 程式類別 A( 83-費用申請、AJ-費用分攤)費用申請單(PAYAPPLY_KC) 程式類別 S( 82-暫付申請)暫付申請單(PREPAID) 其餘程式類別或查無(例 92-、9B-、BE-、B4-)其他應收付/代收付主檔(OTHERRP) 其他長相 不給連結(維持黑字) 統一發票號碼不會變成連結。 單號2 有很大一部分(本機模擬庫 77,202 列)存的是統一發票號碼,
長相像
AA 05461I0503、VK05002556、PU05784617、AJ18528467或純數字。若只照「P 開頭就是付款單、AJ 開頭就是費用申請單」的字面規則,這些發票號碼會被誤判成單據、
開出空白畫面。因此規則多加了長相檢查(
P之後必須全是數字、XX-的第 3 碼必須是連字號),真正的單號一定符合、發票號碼一個都不符合。
> 少數例外:來源單據已被刪除、只在傳票上留下單號的舊資料(模擬庫 122,892 種單號裡有 22 種),
> 點下去會開啟正確的程式但查不到資料。這是資料本身的問題,不是連結壞掉。
共通行為
對應不到程式的資料,該格一律維持一般黑字、不可點——畫面上是藍字的就一定點得動,
不會出現「看起來能點、點了沒反應」的情形。
欄寬
表格 48 個欄位的寬度全部明訂(原本多數欄位沒設、由系統自動撐開,畫面每次載入寬窄不一)。
取法是「表頭放得下」與「實際資料放得下」取大者;名稱/簡稱類欄位(科目名稱、項目名稱、
客廠簡稱等)以常用長度為準而不是遷就極少數的超長資料。
> 若你先前在這張表格按過右鍵的「記憶格式」,系統會沿用你存下來的欄寬,看不到這次的調整;
> 想套用新寬度就重新調整後再按一次「記憶格式」。表頭左上角點兩下仍可依內容自動調整欄寬。
其他
- 沒有權限開啟目標程式時,會出現提示訊息而不是靜默無反應。
- 欄位的排序、篩選與版型存檔行為不受影響。
修正:客廠代號點下去顯示「沒權限進行操作」
症狀:客廠代號欄位,分類是「廠商」的那些列點下去一律跳「沒權限進行操作」
(分類是「客戶」的可以正常開啟)。
原因:廠商資料表在多數客戶的權限表登的是舊系統鍵
SPDATA1,新版程式鍵是SPDATA,登入時會做一次改寫;但這條改寫原本綁在公司名稱含「禾久」的條件上,
模擬環境的公司名稱改成別的名字之後就失效了,導致所有跳廠商資料表的超連結都變成沒權限。
修正:改寫規則改成不分公司一律套用(實查六顆客戶資料庫,
SPDATA1與SPDATA從不並存)。已經直接登
SPDATA的客戶不受影響。除了本次的超連結,其他會跳廠商資料表的欄位一併恢復。備註
本次同時把 2026-08-14 瀏覽查詢單號超連結的儲存格模板配方抽成共用程式碼,
兩處共用同一份實作,行為與外觀一致。
-
08-15 radgridview-scrollmode-realtime ▸
2026-08-15 表格捲動改回即時捲動(修正切換視窗後水平捲軸卡死)
使用者看得到的變動
全系統所有資料表格的捲動行為改回「即時捲動」:拖曳捲軸時,畫面內容會跟著同步移動。
在此之前(2026-08-05 起),拖曳捲軸時畫面內容是靜止的,只有放開滑鼠後才跳到新位置,並且拖曳中會顯示一個小型位置提示框。該提示框一併消失。
修正的問題
會計日記帳(SLIYBROWD)等表格,把水平捲軸拖到右側欄位後,切換到其他程式或網頁再切回 ERP,水平捲軸就會失效:
- 捲軸拉桿拉得動,但畫面內容不跟著捲
- 放開滑鼠也不會跳到新位置
- 必須重新查詢一次才恢復正常
- 不是每次都發生
原因是先前為了效能改用的「延遲捲動」模式,只在放開捲軸拉桿的那一刻才套用捲動位置;一旦拖曳過程被切換視窗打斷,該訊號沒有送達,表格就停在「拖曳中」的狀態,之後怎麼拉都不會生效。改回即時捲動後,每次捲動立即生效,不存在這種待套用的中間狀態。
影響範圍
全系統 1660 個表格(750 個畫面)與 9 個瀏覽查詢表格。沒有任何畫面單獨覆寫此設定,因此一次全部生效。
已知取捨
2026-08-05 改為延遲捲動原本是為了改善「排程事件維護(EVENTPROJECT)」上萬筆明細的捲動流暢度。改回即時捲動後,該畫面在極大筆數下捲動可能再度變得較不流暢。這是刻意的取捨——捲動變鈍是效能問題,捲軸卡死是功能故障,後者優先。
若該畫面確實受影響,後續會從減輕明細列儲存格的繪製成本著手,而不是單獨把該畫面改回延遲捲動(那等於把此故障留在該畫面)。
-
08-15 prodplan-excel-pivot ▸
生產計劃查詢:補回 Excel 樞紐分析表(與 VFP 舊版相同版型)
2026-08-15
使用者可見的變動
生產計劃查詢(
PRODUCTIONPLAN,M-20)畫面新增 「樞紐分析表」下拉與按鈕。這組控件本來就是框架的既有功能,只是這支程式從未登錄樞紐版型,所以一直是隱藏狀態。本次登錄後即會顯示。
操作方式:
1. 設定查詢條件後按
查詢,等結果出來。2. 在「樞紐分析表」下拉選擇
生產計劃查詢樞紐分析表。3. 按下樞紐分析表按鈕,系統會產生 Excel 檔並直接開啟。
產出的 Excel 內含 5 個樞紐頁,版型與 VFP 舊版相同:
- 生產計劃
- 使用量(機種別)
- 使用量(部番別)
- 內工時
- 外工時
各頁的欄位配置、小計方式沿用 2017 年的舊版型檔,與 VFP 舊版一致。
!!! warning "樞紐的工時口徑與畫面欄位不同"
樞紐分析表的內工時/外工時採 VFP 舊版口徑:
數量 × 單位工時(不除以 60),與畫面上同名欄位(有除以 60)相差 60 倍。
這是刻意的設定,目的是讓樞紐數字能與 VFP 舊報表對得起來。
請勿把畫面數字與樞紐數字直接並排比對。
!!! note "驗證狀態"
本次變動已通過建置,但尚未經實機(runtime)驗證。首次在客戶端使用前請先實測一輪,
特別是下方三項環境條件與樞紐欄位是否正確對應。
需要的環境條件
要讓樞紐分析表能正常開啟,用戶端需具備:
項目 說明 SQLite3 ODBC 驅動 Excel 範本的樞紐連線靠它讀取報表資料庫,未安裝時開檔會無法取得資料 Excel 信任位置 需將 C:\Temps\Template\Pivot\加入 Excel 的信任位置,否則資料連線會被 Excel 擋下範本檔部署 生產計劃查詢樞紐分析表.xlsx需部署到REPORTSROOT\Template\(Template 根目錄,不放子資料夾)需要執行的 SQL
sql/prodplan-pivot-register-20260815.sql未執行此腳本前,樞紐分析表下拉與按鈕不會出現。 腳本的作用是在
twork_sys_pivotlst登錄本程式的樞紐版型。相容性
- 只新增
twork_sys_pivotlst的登錄列,不改任何既有表結構。
- 其他程式的樞紐分析表功能完全不受影響(本次未修改樞紐框架)。
- 生產計劃查詢的查詢條件、查詢結果、既有分頁與列印行為皆不變。
已知限制
- 朝陽端不會出現樞紐按鈕:朝陽資料庫的權限表沒有登錄本程式,程式本身即不可用,樞紐也不會出現。是否補上待裁決。
相關
- 決策:ADR 0134
- 手冊:生產計劃查詢
-
08-15 mail-gmail-service-account ▸
2026-08-15 信件搜尋:Gmail 信箱可改用「服務帳戶」由管理員一次授權
使用者可見變動
- 信箱帳號新增第四種類型
GMAILSA(Google Workspace 服務帳戶+網域全域委派)。既有IMAP/GRAPH/GMAIL行為完全不變。
- 選用
GMAILSA時,信箱本人不必做任何事:不必產應用程式密碼、不必開瀏覽器點同意。授權由 Workspace 超級管理員在 Google 管理主控台對服務帳戶做一次網域全域委派,之後同網域任何信箱都可同步;管理者只需登錄「要同步哪些信箱」。
- 信箱帳號管理分頁的「類型」欄會顯示
GMAILSA。
- 手冊:信件搜尋 步驟⑤ 新增「公司有多個 Gmail 信箱要同步」設定說明與指令。
管理者操作(排程主機)
TsERP.SchedulerWorker.exe --mail-sa-check [要試模擬的信箱] ← 新增;逐關驗設定並印出要貼進管理主控台的用戶端 ID 與授權範圍 TsERP.SchedulerWorker.exe --mail-acct-add <使用者代號> <信箱名稱> <信箱地址> GMAILSA [歸屬帳套] TsERP.SchedulerWorker.exe --mail-test <帳號pkid> <關鍵字>憑證有兩種模式,設定鍵擇一填進
%ProgramData%\TsERP\Scheduler\appsettings.local.json:// 方式 A:免金鑰(建議)——不下載任何金鑰,由 IAM 代簽 { "MailSearch": { "Gmail": { "ServiceAccountEmail": "<名稱>@<專案>.iam.gserviceaccount.com" } } } // 方式 B:金鑰檔——機構政策允許建立服務帳戶金鑰時才可用 { "MailSearch": { "Gmail": { "ServiceAccountKeyFile": "C:\\ProgramData\\TsERP\\Scheduler\\gmail-sa.json" } } }多數 Google 機構已預設禁止建立服務帳戶金鑰(組織政策
iam.managed.disableServiceAccountKeyCreation),這時只有方式 A 可行。方式 A 另需:呼叫者身分具備該服務帳戶的roles/iam.serviceAccountTokenCreator、專案啟用 IAM Service Account Credentials API、排程主機執行過一次gcloud auth application-default login。--mail-sa-check會逐關回報:① 設定 ② 呼叫者身分 ③ 服務帳戶唯一 ID ④ signJwt 權限 ⑤ 網域全域委派是否生效(給信箱參數時)。授權範圍固定唯讀
https://www.googleapis.com/auth/gmail.readonly——系統永遠不會寫入或刪除信件。GMAILSA帳號不需要也不能用--mail-link授權;誤用會被擋下並指到正確的步驟。相容性
- 資料庫不需要部署任何 SQL(
類型欄無 CHECK 約束,新值直接可存)。
- 既有信箱帳號不受影響;要改用服務帳戶的信箱,新增一筆
GMAILSA帳號並停用舊帳號即可(已同步的信件索引仍可搜尋)。
相關
- 決策:ADR 0133
- 前次變動:2026-08-12 信件搜尋
- 信箱帳號新增第四種類型
-
08-15 mail-body-html-to-text ▸
2026-08-15 信件搜尋:內文與摘要不再夾帶 HTML/CSS
使用者可見變動
- 信件搜尋清單的摘要欄、以及下方內文預覽,不再出現
<p style="…">、table, td { color:#000000; }、@media (max-width: 480px) { … }這類 HTML 標籤與樣式表殘留,只顯示信件的實際文字。
- 段落換行、清單、表格列改成正常換行,不再整封信黏成一行;
、零寬空白等隱形字元統一成一般空白。
- 搜尋品質連帶改善:那些樣式表文字原本會進全文索引,搜「table」「color」之類的常見字會撈出一堆不相干的信;現在不會了。
修了什麼
三支收信轉接器(IMAP/Microsoft 365/Gmail)原本各有一份「移除標籤 + 還原實體」的剝殼函式,三份都有同樣三個洞:
1.
<style>/<script>只移掉標籤,裡面的 CSS/JS 文字整段留下2. 還原 HTML 實體排在移除標籤之後 → 原文若是跳脫過的
<p style=…>,還原後就以字面形式留在內文3.
<br>/</p>等區塊界線沒轉成換行實作收斂成單一支
MailHtmlToText(LogicBll/MailSearch/),並在入庫前再過一次當最後一道閘 —— 因為有寄件端會把跳脫過的 HTML 直接塞進 text/plain 分段,那條路徑會繞過轉接器的剝殼。另外處理「沒有標籤包著的裸 CSS」:實測有寄件端(Vercel)的純文字分段裡直接塞整包樣式表,沒有 HTML 可剖。改用逐行掃描辨識樣式表區塊,且連續三個以上區塊才刪除,避免誤殺正常內容裡偶爾出現的大括號;選擇器限定 ASCII 字元,中文內文不可能被當成樣式表。
既有資料怎麼辦
修正只影響之後同步進來的信。原始 HTML 沒有保留,既有信件要乾淨的內文必須重新同步(刪掉該信箱的索引與同步游標後重跑)。本機開發庫已重抓 43 封驗證完畢;正式環境尚未部署,無既有資料問題。
驗證
MailHtmlToTextTests23 項(CSS 區塊、跳脫 HTML、跨行選擇器、@media巢狀、程式碼片段不可誤殺、中文內文不可誤殺、冪等、空值)
- 真信箱重抓 43 封:內文與摘要對 9 種 HTML/CSS 特徵字串比對,命中 0 筆,正文完整保留
相關
- 信件搜尋清單的摘要欄、以及下方內文預覽,不再出現
-
08-15 acc-query-hyperlinks ▸
會計查詢類程式補上超連結
2026-08-15
延續同日「會計日記帳(SLIYBROWD)代號欄與單號欄加上超連結」,把同一套超連結補到其餘會計查詢程式。
外觀與行為完全一致:藍字加底線、單擊跳轉、跳過去之後按「返回」回到原本的查詢畫面;
對應不到程式的資料維持一般黑字不可點。
哪些畫面、哪些欄位
程式 加上超連結的欄位 明細分類帳(ABOOK1)下方明細 傳票號碼、科目代號、項目編號、部門代號、客廠代號、員工編號、專案代號、單號1、單號2、單號3 分類索引分類帳(ABOOK2)下方明細 同上 試算表(TRIAL)兩張表格 科目代號 資產負債表(BALANCE)兩張表格 科目代號 損益表(INCOME)科目明細表格 科目代號 跳轉目標與日記帳相同:傳票號碼→傳票輸入、科目代號→會計科目主檔、項目編號→會計項目主檔、
部門代號→部門主檔、員工編號→人事資料、專案代號→專案主檔;
客廠代號依該列分類跳客戶資料/廠商資料/部門主檔;
單號1/2/3 依單號長相跳付款單/收款單/應收帳款/應付帳款/費用申請單/暫付申請單/其他應收付
(規則見
2026-08-15-sliybrowd-grid-hyperlink.md)。沒有加的地方與原因
- 明細分類帳、分類索引分類帳「上方的科目彙總表格」:那張表點一下的既有意義是「選這個科目、看它的明細」,
改成超連結會變成點一下就跳走,把原本的操作弄壞。
- 常用分錄(GSLIY)、傳票年度表(SLIYYEAR)、預算表(BUDGET):這三支是輸入用的畫面不是查詢,
儲存格要能點進去編輯,加超連結會擋住輸入。
- 常用分錄的客廠代號:該畫面的資料來源沒有帶「分類」欄,無法判斷要跳客戶還是廠商,
硬跳會有一半跳錯,因此不做。
- 資產負債表/損益表的「彙總科目」欄:那是合計用的科目代號,與同列的「科目代號」重複,
且不保證每個值都對得到科目主檔,暫不做。
備註
明細分類帳原本沒有把「分類」欄帶進畫面資料,客廠代號無從判斷要跳哪一支;
本次補上(資料庫端本來就有回傳這個欄位,不需要重新部署任何 SQL)。
-
08-14 work-permission-unification ▸
2026-08-14 工作權限統一入口
對應 ADR 0132。
使用者看得到的變化
待辦事項與簽核
離職員工的待辦不再出現在主管/代理人的清單上。 過去只要組織關係還掛著,離職者手上未結案的單仍會出現在主管的「直接下屬/間接下屬」分頁、或代理人的「代理人」分頁。現在一律依員工資料的離職日期過濾。
實測影響(朝陽資料):44 位處理人中有 5 組人員別組合的筆數變少,全部來自離職者,最大一筆是某位代理人的清單從 6 筆變 0 筆——那 6 筆都屬於一位 2023 年離職的同仁。
主管的下屬全部失效時,「直接下屬」分頁不再顯示自己的單。 舊版在這個情況下會把主管自己當成下屬回傳,導致他在下屬分頁看到自己的待辦。現在正確顯示為空白。
上下位關聯(A-050)
新增「部門主管」類別。 類別碼 7,上位選部門、下位選該部門的主管(可多人)。設定後,該主管在待辦的「直接下屬」分頁會看到所屬部門及其所有子部門全體在職成員的待辦。
這是唯一上位與下位來自不同主檔的類別:上位查部門資料、下位查員工資料。
生效起始日/生效截止日改為可編輯。 過去這兩欄在畫面上是唯讀的,只能請維護者從資料庫改。現在可以直接在明細列填寫,用來表達「這個代理只在某段期間有效」「這位下屬從某天起才歸我管」。
- 兩欄留空 = 永久生效
- 只填起始日 = 從該日起生效,之後永久有效
- 只填截止日 = 立即生效,到該日為止
- 已過截止日的關係會自動失效,不必手動刪除
自訂查詢面板(CUSTOMDASH)
離職者的配置不再透過下屬/代理關係被帶出來。 可見範圍的其他規則(本人、代理、下屬、本部門、子部門)維持不變。實測禾久資料:可見列數 60 → 59,唯一減少的一筆屬於離職同仁。
沒有變的
- 功能權限(哪支程式能開、能不能列印)完全沒動。
- 代理的範圍維持不變:代理某人只看得到那個人本人的資料,不含他的下屬、部門、或他代理的對象。
- 待辦的四個分頁、分頁裡的欄位、快速核准與審核視窗都沒有改。
- 已審核查詢不受影響(它依「誰實際處理的」判斷,與組織關係無關)。
- 同部門之間在 CUSTOMDASH 仍然互看得到配置——那是「發佈給部門」的共享語意,與待辦的「主管看底下的人」是兩回事。
給維護者
- 待辦查詢改走新的預存程序
TWORK_WKFLOW_TODO;舊的DARB_WKFLOW_TODO原封不動保留。
- 升級順序:資料庫物件必須全部部署完成,才能發布新版桌面程式。任一資料庫缺少新物件或
proc_param登錄,該公司的待辦會顯示空白且不跳錯誤。
- 要使用「部門主管」功能,需先在上下位關聯建立類別 7 的資料;未建立前該功能不生效,其他行為不受影響。
-
08-14 wkpaper-query-chinese-columns ▸
2026-08-14 委外工令查詢改用中文欄名(原本整個分頁不能用)
使用者看得到的變動
庫存資料查詢的「委外工令」分頁:
- 按查詢不再報錯。改版前這個分頁一按查詢就回「無效的資料行名稱 'WorkOrderDate'」——
程式送出的欄名是英文(
WorkOrderDate/ProductionDepartmentCode/IsClosed/Quantity/TempReceivingQuantity),而資料庫的
wkpaper表與vwbd_wkpaper檢視早已中文化,欄名根本不存在。- 「只顯示未結案」可以用了:條件改成「是否結案 ≠ Y 且 數量 > 已交數量」。
- 表格多一欄「是否結案」(過濾條件需要,順帶顯示)。
- 單號欄(派工單號)現在是藍字底線超連結,點下去直接開製令程式(WKPAPER)並跳到該筆。
這是 2026-08-14 瀏覽查詢單號超連結(見同日另一篇 changelog)的一部分,原本因為欄名對不上而沒有出現。
- 日期欄原本空值會顯示
1900/01/01,現在顯示空白。
資料庫變更(要部署)
sql/vwbd-wkpaper-add-isclosed-20260814.sql:1.
vwbd_wkpaper加「是否結案」欄。不能拿既有的「結案日期」代替——實測 darbnogicsa1 的 13,556 筆製令中,
「是否結案 ≠ Y 卻有結案日期」有 6,263 筆,兩者不等價;
而「已結案但數量 > 暫收數量」也有 694 筆,所以也不能只靠數量判斷。
2. 四個日期欄(下單日期/預訂開始日/預訂完成日/結案日期)的
CONVERT(datetime, …, 111)加上
ISDATE防呆。原本只要有一筆日期字串不合法,整批查詢就會爆「將 nvarchar 資料類型轉換成 datetime 資料類型時,產生超出範圍的值」——
開發庫就有一筆(派工單號 N11011307,預訂完成日
0211/02/10,民國年沒轉西元)。髒資料本身沒有動(正確值要業務判斷),只讓查詢不再整批陣亡。
部署範圍:各客戶帳套庫與正式機。語法為 SQL2008 相容(未用
TRY_CONVERT)。追加:wkpaper 家族全面中文化(同日第二階段)
上面那節只修好「委外工令查詢」這條路徑。經裁決後把整個製令資料層一起中文化:
Twork_pdt_vw_wkpaper/wkpaperd/wkpapers/wkpapera/wkpapernp/wkpaperq
6 支 Source 與 6 支 Model 的屬性名由英文改為中文(例:
WorkOrderNo→派工單號),與
trwkma等既有中文 Source 的慣例一致。欄位對照表:.claude/tmp/wkpaper-chinese-rename-map.md。- 連動修正 15 個 C# 消費端(
Updt_wkpaper/WkpaperSave/WkdaySave/WktompBll/Ngtrna1Bll等)。
- XAML binding:
Wkpaper.xaml、Wkday.xaml、Ngtrna.xaml(Tab1)。
使用者可見的影響:製令主檔(WKPAPER)、生產日報(WKDAY)、不良品退回(NGTRNA)
這三支程式的欄位過去與資料庫欄名對不上(載入靜默讀不到值),本次修正後才有機會正常顯示與存檔。
這三支尚未實機驗證——見下節。
已知遺留問題(未處理)
Model/Source/F.Production/Twork_pdt_vw_wkpaperSource.cs的 **59 個[TsColumnName]欄名,在
vw_wkpaper裡一個都不存在**(DB 全中文、C# 全英文)。WkpaperViewModel(製令主檔 WKPAPER)用的就是這支 Source,其他 18 個檔也引用它。本次只修「委外工令查詢分頁」這條路徑,這支 Source 與製令程式本體未動、未查證。
-
08-14 ui-design-rules-and-date-width ▸
---
not_in_nav: true
---
2026-08-14 UI 設計守則上線+日期欄寬度回歸預設
使用者可見的變動
1. 日期欄寬度統一(35 支畫面、72 處)
表單上的日期輸入欄不再各自寫死寬度,改由控件樣式依日期格式自動決定:
日期格式(MaskInfo) 寬度 年/月/日(ShortDate,最常見) 90 年月日時分(ShortDateTime) 162 年月(YearAndMonth) 66 月日(MonthAndDate) 50 年(Year) 42 先前有 72 處寫死成
100(少數120),比標準寬 10~30px,且換日期格式時不會跟著調整。這次全部移除,寬度一律回歸樣式預設。影響的畫面(依模組):
- H.庫存(16 支):不良品入庫、庫存異動分析、耗用單轉生產、領料轉出貨、備料轉領料、入庫單、調撥單、庫存帳簿與其查詢條件、庫存狀況查詢條件、生產入庫、製令領料 等
- E.訂單(6 支):客戶產品報價(含朝陽版)、訂單審核、信用額度審核、客戶信用資料、訂單查詢
- M.主管資訊(2 支):每日營運、出貨明細查詢條件
- P.發票(3 支):發票應收、出口發票、出貨發票
- C.總務(2 支):物品帳簿查詢條件、請購轉領料
- I.帳款(2 支):其他應收付、收款單列印
- F.生產/D.BOM/Q.固資/其他(4 支):製令資訊、母件成本、財產主檔、應收批次輸入
畫面上的差別是日期欄略微變窄並與其他表單一致,輸入行為、格式、驗證都沒有改變。
未變動:簽核展開區與簽核彈窗的唯讀日期(共 3 處)仍維持 100,因為它們在共用控件樣式內、影響所有帶簽核區的表單,留待單獨評估。
2. 表格欄位標題的多語言修復(2 支畫面)
參數設定(Para)、採購單拆分(Posplit) 的表格欄位標題(共 10 欄)原本綁在多語言字典上,實際上不會生效,而且在以英文/日文/越南文啟動時,該欄可能永久卡在錯誤語言、之後切語言都不會更新。改回中文字面值後,四語翻譯照常由語言檔提供。
中文環境下的顯示結果沒有變化。
內部變動(不影響使用者)
- 新增
.claude/rules/ui-design.md:UI 設計守則(版面骨架、控件選型、色票與字級、數值日期格式、按鈕、彈窗、表格、開窗即崩清單、驗收分層),並掛進CLAUDE.md與maintenance.md的制度索引,標示「每次動 XAML 前」讀取。
- 修正
.claude/skills/tspage-to-tsview/skill.md:階段 C 的「表格欄位標題包多語言 binding」教法已被 2026-07-14 的
xaml-label-to-displaymeta/references/grid-header-localization.md推翻,但該 skill 未同步更正,會持續產生上述缺陷。已更正四處並標註原因。驗證
- MSBuild(TsERP.csproj,Debug):0 error
- HarnessSmokeTests:7/7 通過
- 殘留掃描:表格標題綁 binding 者 0 處;日期欄寫死
Width="100"僅剩刻意保留的共用控件 3 處
- runtime 未驗:72 處日期欄與 2 支表格標題皆未開窗實測
-
08-14 browse-grid-docno-hyperlink ▸
2026-08-14 瀏覽查詢的單號可以直接點開單據
使用者看得到的變動
庫存資料查詢(INVENT)與客戶資料表(CUDATA)等瀏覽型查詢的結果表格中,代表單號的那一欄
(例:庫存異動的「倉單號」、銷售訂單的「訂單編號」、採購的「採購單號」、抱怨單的「單號」)
現在顯示成藍字加底線的超連結,單擊即可開啟該單據所屬的程式並跳到該筆資料。
- 跳過去之後按「返回」會回到原本的查詢畫面(不是回主選單)。
- 沒有該程式瀏覽權限時,點了會出現權限訊息、不跳轉。
- 只有單號欄變成連結,其他欄位外觀與行為不變;排序、篩選、欄寬版型存檔一律照舊。
生效範圍(凡是有指定單號欄位的瀏覽查詢都自動生效,各程式不需個別修改):
畫面 連結欄 開啟的程式 庫存資料查詢 — 庫存異動 倉單號 TRWKMA 庫存資料查詢 — 客戶報價/訂單/出貨 報價單號/訂單編號/倉單號 CUPDMA/ORMAST/TRSAMA 庫存資料查詢 — 廠商報價/採購/進貨/委外工令 報價單號/採購單號/倉單號/WorkOrderNo SPPDT/PURCH/TRRAMA/WKPAPER 同上(總務版變體) 採購單號/倉單號 GPURCH/TRGAMA 客戶資料表 — 抱怨單/拜訪單/叫修單/保固卡/報價單 單號/拜訪單號/叫修單號/保固卡號/報價單號 CMPLAIN/VISIT/REPAIR/INVENT1/CUQT 為什麼
這個行為在舊版表格控件(TsDataGrid)時代就存在,換成 Telerik RadGridView 後隨著欄位產生器改寫被停用,
各程式端設定的「單號欄是哪一欄、要開哪支程式」變成沒有作用的設定值。本次把最後一段接回來。
技術重點
TsControl/TsTelerik/TsBrowseRadGridView.cs:欄位自動產生時,若欄名等於NavigateKeyFieldName
且
NavigateProgramClass有值,就給該欄一個超連結 CellTemplate;點擊走框架的IHyperLink.HyperLinkWithKeyFieldValue(含權限檢查與ProgramClassRouter變體解析)。Common/Interface/IHyperLink.cs/ViewModel/PageControl/HyperLink.cs:
HyperLinkWithKeyFieldValue加上選用的ExecuteDelegate參數,才能傳MustReturnPriorPage(返回上一頁)。- CellTemplate 用
FrameworkElementFactory組TextBlock > Hyperlink > Run;
點擊改走
Command+CommandParameter,不能用FrameworkElementFactory.AddHandler(Hyperlink.ClickEvent, …)——離線 WPF 探針實測對 content element 不生效(掛了等於死鈕)。
- 底線靠
TextOptions.TextFormattingMode="Ideal",display mode 下底線會消失。
-
08-13 todolist-subject-card-polish ▸
2026-08-13 待辦清單主旨卡片:字級階層、版面比例與配色定案
摘要
TODOLIST 待辦清單下半部的主旨卡片(主旨列+附件/工作流程+單據內容)做了一輪實機調整:字級拉出階層、卡片高度與內部比例重配、主旨列改成「白底粗色帶」配色。五個分頁(本人/代理人/直接下屬/間接下屬/已審核查詢)共用同一份樣式與模板,一次生效。
變更(`TsERP/Z.System/TodoList.xaml`)
字級階層
元素 之前 現在 主旨本文 16 20 主旨小標「主旨」 11 16 附件/工作流程小標 13 15 主旨是本區主角,字級刻意做成 主旨本文 > 主旨小標 > 附件/工作流程小標。
主旨本文不再是輸入框
由唯讀
TsTextBox(仍有框線、游標、可選取的輸入框外觀)改為純文字TsTextBlock:單行不換行、超長以「…」截斷,完整內容留在 ToolTip。版面
- 下方主旨卡片由
2*(佔全高 2/3)改為Height="2.2*" MaxHeight="750" MinHeight="240",外加Margin="2":視窗夠高時最多 750px,不夠高就跟著縮。
- 中途曾寫成固定
750px,但固定像素列在視窗變矮時仍照配,超出部分直接被裁掉,被裁的正是卡片底部的單據內容表格(實機發現)。改成星號+MaxHeight才會自適應。- 上方待辦清單那列補
MinHeight="200",避免卡片把清單壓到看不見。
- 卡片內「附件/工作流程」與「單據內容」由 1:1 改為 1:1.6,並各給邊界:附件/工作流程
MaxHeight="300" MinHeight="60"(視窗拉高時多出的空間全給單據內容,縮視窗時先讓位)、單據內容MinHeight="100"。
- 卡片外框由
#E3E7EC改深一階的#BFCBDA;內部不再切小卡 —— 曾給附件/工作流程加 1px 框+淺灰底,實機看是「卡中卡」、線太多反而雜,改回 Transparent 無框,整區只留最外層一張卡片,內部靠小標題與 grid 自身格線分區。
主旨列配色(比稿定案 C「白底粗色帶」)
主旨列不上底色,範圍改由色帶與底線界定:
元素 值 列底 #FFFFFF左側粗帶 #2F62A8藏青,6px下緣線 #2F62A8藏青,2px小標 #2F62A8(原#7A879A灰藍太淡)本文 #16202E(原#232A33)藏青取自
TsERP/Themes/DashboardTheme.xaml的企業配色定案 A 主色(Ts.Dash.Series1Color),與四支儀表板同一套色票。比稿過程另試過「藏青橫幅反白字」與「淡藏青底深字」兩案,未採用。卡片內的藍收斂成單一
#2F62A8:附件/工作流程小標(原#4A5666)與其前方小色塊(原#3D5A80)一併改用同色,階層改由字級撐(主旨本文 20 > 主旨小標 16 > 附件/工作流程 15)。三個相近但不同的藍並存正是「顏色看起來不一樣」的來源。分隔軸(GridSplitter)
TsControl/Themes/TsStyles.xaml的GridSplitterHorizontalStyle/GridSplitterVerticalStyle(全 App 共用,另有 Recepdt/Record/WorkflowView/權限設定/不良期間統計/TrlimaPickingControl 在用):原本是 50px 的白+#A0A0A0雙細線畫在系統控制項底色上,淺色畫面幾乎隱形。改為「軌道+握把」:6px 軌道(#EEF1F5底+#D8DEE7界線)+中央 44px 圓角握把(#8894A6);滑鼠移入軌道轉#DCE6F4、握把轉藏青#2F62A8,拖曳中再深一階;指標SizeNS/SizeWE。小字模糊
根元素補
UseLayoutRounding="True"、TextOptions.TextFormattingMode="Display"、TextOptions.TextRenderingMode="ClearType"。WPF 預設的Ideal模式為排版精度保留次像素字距,中文小字落在非整數像素上就會糊;Display模式把字圖對齊整數像素。目前只加在本檔,未推廣到TsView基底。2026-08-14 收尾:色票升 token、文字算繪上移基底
色碼改走共用 token
TsControl/Themes/ShareResource.xaml新增一組語意 token(依.claude/rules/ui-design.md第 4 節「頁面內零寫死色碼」):token 值 用途 AccentBrush#2F62A8企業主色藏青(同 Ts.Dash.Series1Color;DashboardTheme 只給儀表板 merge,一般畫面拿不到,故另立同值 token)AccentPressedBrush#24518F按下/拖曳中 AccentTintBrush#DCE6F4hover 淡底 AccentTintStrongBrush#C9DAF0拖曳中淡底 CardBackgroundBrush#FFFFFF卡片/面板底 CardEdgeBrush#BFCBDA卡片外緣 CardLineBrush#E3E7EC卡片內部細線 TextStrongBrush#16202E標題與重點值 MutedTextBrush#8894A6次要文字/握把 BadgeBackgroundBrush#46586F徽章底 SplitterTrackBrush/SplitterEdgeBrush#EEF1F5/#D8DEE7分隔軸軌道與界線 TodoList.xaml的 8 個本地色票與 GridSplitter 樣式的 7 個寫死色碼全部改為引用上表;兩檔的非註解區已無#RRGGBB。文字算繪上移到 `TsView` 基底
原本只加在
TodoList.xaml根元素的三個設定,移到TsControl/TsView.cs建構式(UseLayoutRounding+TextFormattingMode.Display+TextRenderingMode.ClearType),全 App 的TsView頁面一體生效,小字(尤其中文)不再發糊。個別頁面若需要Ideal模式可自行覆寫。已知地雷(寫進 XAML 註解)
卡片外框不可掛
DropShadowEffect或任何Effect。 WPF 只要父層有 Effect,整個子樹改走 bitmap effect 管線渲染、ClearType 失效,卡片內所有文字與格線都會變模糊。本次曾用陰影做「浮起」效果,實機確認會糊字後移除;要做層次請用邊框色階,不要用陰影。Breaking Changes
無。純視覺調整,資料繫結與行為不變。
- 下方主旨卡片由
-
08-13 repair-visit-cmplain-fillrate-fixes ▸
2026-08-13 客反應主檔/拜訪單/抱怨單/達成率/INVENTQUERY 修正
使用者實機測試回報的五項,一次修完。
客反應主檔(REPAIR)
- 服務人員可以編輯,也可以用搜尋:原本是唯讀。改成可輸入的搜尋欄,按
[開人事檔搜尋視窗,
存的是員工編號(2026-08-13 使用者裁決),右邊唯讀框顯示反查到的姓名。
- 舊資料 3965 筆存的是姓名(舊語意,0 筆對得到員工編號)。使用者裁決 舊單不轉檔、維持原樣:
開舊單時代號框仍顯示姓名、右邊姓名框空白,不擋開啟也不擋存檔(
CheckDataExist=False)。日後若要強制只收員工編號,把該屬性拿掉即可。
- 註:
perdata同名有兩組編號(公司代碼 0 的舊短碼/公司代碼 1 的新長碼),3939 筆會對到兩人,所以自動轉檔本來就需要先裁決取哪一組。
- 客戶名稱會顯示了:原本客戶代號有值、客戶簡稱永遠空白。根因見下方「名稱反查」。
拜訪單(VISIT)
- 受訪代號/業務員編號/業務部門代號旁的名稱會帶出來了(客戶簡稱、業務員姓名、部門簡稱)。
兩個成因疊在一起:資料表這三欄是
nchar(10),值帶尾隨空白,字典比對必落空;客戶與業務員的seek 資料本機是空的(見下)。
名稱反查(影響全系統,ADR 0131)
GetCustomerName/GetSalesmenName只查登入時下載的本機 seek 表,但客戶/業務員這兩張在系統設定裡是「不含資料」(大表不整包下載),所以本機恆空 → 這兩個方法對任何代號都回空字串,畫面靜默空白。
現在改成:本機查不到就向資料庫補查並快取(客戶單筆補查、累積 20 家改整批;業務員小表整批補一次)。
代號一律先去掉尾隨空白。全系統靠這兩個方法補名稱的地方(51 處)都會跟著恢復顯示。
抱怨單(CMPLAIN)
- 公司代碼欄從畫面拿掉(比照達成率 2026-08-07 的裁決)。存檔時若沒有值自動補 1
(既有 87 筆抱怨單全部是 1),不再跳「請先輸入公司代碼」。
- 單號規則不變(仍是 公司代碼 1 碼 + 年度月份 + 流水)。
- 客戶資料(CUDATA)的「抱怨單」瀏覽分頁不受影響,仍會顯示公司代碼欄。
達成率(FILLRATE)
- 類別下拉會正確顯示 C:客戶/S:廠商 了。資料表
類別是char(10),讀回來是'C ',
和下拉選項的代號
"C"比不上,選項就落空、看起來像沒設定。品號主檔等查詢分頁(INVENTQUERY)
- 從統計資料按「檢視」進來時,不再顯示「查詢」鈕(條件是唯讀的、資料已載入,按了沒作用)。
- 該模式下的唯讀「查詢條件」框加寬(300 → 700),長條件字串不用擠成好幾行。
- 一般查詢模式的版面與行為不變。
代理/管轄關係表(BOR)
- 類別碼下拉改成中文、且只用一個欄位顯示。原本是「左邊小下拉選代碼 1~6 + 右邊唯讀說明框」兩個欄位,
且說明顯示的是英文列舉名(
Substitute/Department…)——因為BorClassEnum從來沒有翻譯檔。- 新增
Common/Lang/Xaml/BorClassEnum.json:代理人/管轄人員/管轄部門/管轄客戶/管轄廠商/工作中心
(前三與工作中心沿用資料庫既有用詞;客戶、廠商兩項是新訂用詞)。
- 落庫的
bor_m.類別說明欄改由 ViewModel 在編輯狀態寫入,瀏覽切換記錄時不再寫(原本每切一筆就把
記錄弄髒、還會寫進英文字串)。
抱怨單版面(追加)
- 第一列(單號/年度月份/鍵值)改成水平堆疊,標籤與輸入框永遠貼在一起。原本每格各佔一個 auto 欄,
第二列備註的固定寬度會把多出來的寬度攤到這些欄,公司代碼拿掉後標籤就被推離輸入框。
影響範圍
Cmplain.xaml、Repair.xaml、Bor.xaml、TsStyles.xaml(InventQuery 樣板)、RepairViewModel、BorViewModel、CmplainSave、DescriptionHelper、OpenDbfTable、Twork_ord_vw_visitSource、Twork_ord_vw_fillratemSource、新增Common/Lang/Xaml/BorClassEnum.json。不需要跑任何 SQL 佈署。
- 服務人員可以編輯,也可以用搜尋:原本是唯讀。改成可輸入的搜尋欄,按
-
08-13 radgridview-persistence-and-cmb280 ▸
2026-08-13 grid 版型存檔修復、選取 NRE 修復、cmb_280 登錄
摘要
修掉兩個潛伏在
TsRadGridView的問題(「記憶格式」其實一直存不起來、切選取偶發跳例外),並補上cmb_280(金額欄位控制)的_opendbf登錄,消除 log 反覆出現的no such table: CMB_280。三項都不是 08-12/08-13 那批新功能造成的,是既有問題今天被 log 翻出來。變更
1. 「記憶格式」與切畫面版型暫存,實際上一直存檔失敗
TsControl/TsTelerik/TsRadGridView.cs- 症狀:debug log 反覆出現
SaveSessionFormat failed for <grid>: Type: ... is not included in the AllowedTypes collection of the PersistenceManager.(08-06 的 log 就有,非新問題)。使用者端表現為:調好欄寬/欄序/隱藏欄後按「記憶格式」,下次開啟又回到原樣;切到別支程式再切回來,臨時調整也沒保留。
- 根因(兩個,會交替發生):
1.
GetPersistenceManager()只呼叫AllowGridViewControls(),那是放行 Telerik 原生RadGridView;本專案所有 grid 都是衍生的TsRadGridView/TsBrowseRadGridView,衍生型別不在放行名單內,Save 時撞自己的型別而整份中斷。2. 長在
InventQuery查詢樣板裡的 grid(庫存查詢、CUDATA 各瀏覽分頁等),TemplatedParent的值是外層InventQuery控件;PersistenceManager 預設會序列化 UIElement 型別的屬性,於是連父控件一起序列化而撞牆。- 修法:
AllowTypes加入GetType()、TsRadGridView、TsBrowseRadGridView;序列化選項新增^TemplatedParent$的 Except(父控件本來就不該進版型)。
1b. 「記憶格式」新增儲存結果提示
TsControl/TsTelerik/TsRadGridView.cs— 右鍵「記憶格式」原本按下去毫無回饋,成功失敗都一樣安靜(正是上一節那個 bug 長期沒被發現的原因)。改為:- 成功 → 提示「版型已儲存。」
- 失敗(序列化中斷或 SQL 上傳失敗)→ 提示「版型儲存失敗,請洽系統管理員。」並把細節寫進 debug log
Serialize()改為回傳bool(沿用SaveFormatToSql既有的成功與否回傳值)。訊息文字走既有的L()語言服務,key 為Msg_FormatSaved/Msg_FormatSaveFailed,查無翻譯時以繁中字面 fallback。2. grid 換選取時偶發 `NullReferenceException`
TsControl/TsTelerik/TsRadGridView.cs—OnSelectedItemChanged狀態列的「第幾筆 / 共幾筆」直接用
Context.NotificationService,而Context是反查根 ViewModel 取得的(ViewHelper.GetRootViewModel(this)?.Context),在拆畫面、尚未掛進視覺樹、或反查不到根 VM 的宿主中會是null→ 換選取即 NRE。改成取不到就跳過(狀態列筆數只是輔助資訊)。此段程式自 2026-03 就在,屬潛伏問題。3. `cmb_280`(金額欄位控制)沒有登錄 `_opendbf`
sql/opendbf-register-cmb280-20260813.sql(新增)- 症狀:log 反覆出現
no such table: CMB_280與opendbf not found CMB_280(來源LogicBll/Price/PriceHelper.cs:151)。
- 根因:View
vwcmb280_金額欄位控制早就存在,但沒登錄進_opendbf,登入時不會下載成本機 SQLite 表 → 取表必失敗。與 2026-06 的cmb_283客戶等級同一類問題。
- 腳本:禾久 csa1~5 + demo 庫一次跑完,冪等可重跑;View 缺席才建(既存不動),登錄用
NOT EXISTS;相容 SQL2008,換掉庫名清單即可用於其他客戶庫。
行為
- 「記憶格式」與切畫面的版型暫存,這次起才真的會存。舊的版型 SQL 可能是空的或殘缺,第一次開啟回到預設欄寬屬正常,以「重新記憶一次後能否留住」為準。
cmb_280登錄後是一張空表:摘要檔(smemsm.類別編號 = 'C280')目前 0 筆,PriceHelper 拿到空清單=不管制任何金額欄位,與登錄前的實際行為相同,差別只在不再噴錯。要真的啟用金額欄位管制,需到摘要檔(SMEMS)維護 C280 類別的欄位清單。
- 使用者端要重新登入才會重新下載 SQLite 暫存表,
CMB_280的錯誤訊息才會消失。
部署狀態
- 本機(localhost):
darbnogicsa1/darbnogicsa5/darbdemocsa1已跑,驗證區view280=1 / reg280=1全 OK;重跑一次確認冪等。
- 未跑:禾久正式機、朝陽(
darbcycsa1,連 View 都沒有,本腳本會自動建)、kc / cma / asmbly 各庫。
- 症狀:debug log 反覆出現
-
08-13 customdash-export-style ▸
2026-08-13 自訂查詢面板:匯出HTML 新增「匯出風格」選項
摘要
自訂查詢面板(
CUSTOMDASH)按匯出HTML後跳出的「匯出HTML — 選擇顯示項目」視窗,在勾選清單下方新增一個
匯出風格下拉,右邊顯示所選風格的一行說明。風格只換外觀(配色/字型/圖表用色),匯出的內容、頁數與數字不變。
使用者可見變動
- 「匯出HTML — 選擇顯示項目」視窗多了
匯出風格下拉(位置在顯示項目清單與隱藏零值之間)。
- 可選五種風格,下拉順序即下表順序:
匯出風格 外觀與適用場合 典雅簡報(預設) teal 強調色+襯線數字+米白紙感,對外簡報式月報;與本次改版前的外觀完全相同 簡潔商務(藍灰無襯線) 深藍灰、全無襯線、細線條,中性企業報告風 列印友善(黑白省墨) 白底黑字、去底色與陰影、圖表走灰階,要列印或轉存 PDF 時用 深色簡報(投影用) 深底淺字,投影機/大螢幕會議播放用;不適合列印 賽博龐克(霓虹深色) 深藍黑底+青紫霓虹、等寬數字,展示或內部玩味用;不適合列印 - 風格不記憶(使用者裁決):每次開啟這個視窗都回到「典雅簡報」,要換風格當次重選。
- 排程自動匯出不受影響:行事曆排程事件產出的檔案沒有互動視窗,一律使用預設的「典雅簡報」。
- 不選風格時輸出與改版前逐字相同,既有配置與既有流程無須調整。
追加(同日第二輪):一併產出 PowerPoint、負數紅字
> 本節記錄的是第二輪當時的狀態。PowerPoint 產出已於同日第三輪改版,
> 現行行為(勾選框文字、封面、自動分頁、圖表資料表)以文末的
> 追加(同日第三輪)為準。
一併產出 PowerPoint(新增勾選框)
- 「匯出HTML — 選擇顯示項目」視窗在
隱藏零值下方新增勾選框
一併產出 PowerPoint(圖表頁為佔位,表格頁完整),預設不勾。- 不勾=維持現行,只產出一個
.html;勾了=同一個資料夾多產一個同檔名的.pptx,
套用與 HTML 同一種匯出風格。
- 限制(誠實說明):PPT 的圖表頁目前只有一行佔位文字、不會畫出真的圖表;
表格頁則是完整的 PowerPoint 原生表格(可在 PowerPoint 內直接編輯)。
因此此選項適合「把表格拿去 PowerPoint 繼續編輯」,不適合直接當簡報播放。
- 此勾選與
匯出風格一樣不記憶,每次開窗都回到未勾;產出的.pptx不會自動開啟
(自動開啟的仍只有 HTML),完成訊息會列出 HTML 與 PPT 兩個路徑。
負數紅字(HTML 與 PPT 表格皆適用)
- 匯出的表格中,數值為負的儲存格改以紅字顯示;每種匯出風格各有自己的紅
(深色風格用亮紅、
列印友善(黑白省墨)用深紅)。- 規則:只看值的正負、不看欄名(差異/金額/數量等一體適用);合計列同樣適用;
0 與正數不標;負號本身保留,故黑白列印或複製貼上仍看得出正負。
附帶修正
- 直條圖遇到負值時,柱子改由零基線往下長並標出數值;先前負值的柱子畫不出來,
畫面上只剩一個浮著的數字。有正有負時會多畫一條零基線。
手冊
docs/M-EIS/customdash.md:步驟⑥ 匯出 HTML 加入匯出風格步驟、新增
「選哪一種匯出風格」對照表與「風格不會被記住」警示、補欄位說明與兩則 FAQ。
第二輪追加:步驟⑥ 增列
一併產出 PowerPoint步驟與產出說明、新增「一併產出 PowerPoint」小節(含佔位限制警示)與「負數怎麼呈現」備註、
欄位說明表補一列、再補三則 FAQ。
docs/case-studies/customdash.md:「實際跑一遍」第 7 步補上可選匯出風格(一句話);
第二輪未再更動(案例書刻意維持精簡)。
- 需補截圖:
customdash-export-html-select.png需重拍(需含匯出風格下拉與
一併產出 PowerPoint勾選框)、customdash-export-style-dropdown.png、customdash-export-style-print.png、customdash-export-negative-red.png、customdash-export-ppt-table-page.png、customdash-export-ppt-chart-placeholder.png。(PPT 兩張的檔名與內容已於第三輪調整,以下方第三輪清單為準。)
追加(同日第三輪):PowerPoint 產出改版
PPT 產出器整個改寫。第二輪的「圖表只放一行文字、表格頁完整」已不適用,現行行為如下。
修正:表格超出投影片範圍(使用者回報「PPT 有問題」的實際成因)
- 先前表格不會分頁,資料列一多就整塊畫出投影片外——例如 74 列的表格約是投影片高度的四倍,
開啟後只看得到最上面十幾列,其餘內容在畫布外看不到。
- 現在自動分頁:一張投影片最多 13 筆資料列(加表頭共 14 列),超過的部分接續到下一張,
每張重畫表頭,第 2 張起標題後面加「(續)」,合計列與備註只出現在該項目的最後一張。
因此 PPT 的投影片張數可能多於 HTML 的頁數。
新增:封面頁
.pptx第 1 張是封面,比照 HTML 版:公司名稱、簡報標題、期間(年月)、副標與產生時間。
變更:圖表項目改輸出「圖表資料表」
- 圖表項目不再是佔位文字,改成輸出可編輯的原生資料表:
圓餅圖 →
項目/數值/占比三欄;直條圖、折線圖 →項目欄+每個資料數列各一欄。- 限制(誠實說明):PPT 裡不會有真的圖形(原生圖表尚未實作),圖表項目一律以資料表呈現。
要有圖的成品仍請用匯出的 HTML,或在 PowerPoint 中依資料表自行插入圖表。
其他
- 勾選框文字改為
一併產出 PowerPoint(圖表項目會轉成資料表)(原為「圖表頁為佔位,表格頁完整」)。
- 表格改用整頁寬度(不再留半頁給圖表)。
隱藏零值在 PPT 端同樣生效(整列為 0 不輸出、單格 0 留白;圖表資料表的占比欄不受影響);
負數紅字同樣套用。
- 未變動:預設不勾、不記憶、
.pptx與 HTML 同檔名同資料夾、PPT 不會自動開啟。
手冊
docs/M-EIS/customdash.md:步驟⑥ 第 5 點與「一併產出 PowerPoint」小節全面改寫
(封面/自動分頁與「(續)」/圖表資料表/PPT 無圖形的限制)、欄位說明表該列更新、
「彙整列印與匯出 HTML 差在哪」比較表的產出/圖表/選項三列更新、
FAQ「圖表那幾頁只有一行字」改寫為「圖表變成一張表」並新增一則「被拆成好幾張投影片、(續)」。
- 需補截圖(取代第二輪 PPT 兩張):
customdash-export-ppt-cover-page.png(封面,或分頁後標題帶「(續)」的表格投影片)、
customdash-export-ppt-chart-datatable.png(圓餅圖轉成的項目/數值/占比資料表投影片)。其餘四張(
customdash-export-html-select.png重拍、customdash-export-style-dropdown.png、customdash-export-style-print.png、customdash-export-negative-red.png)維持第二輪清單。 - 「匯出HTML — 選擇顯示項目」視窗多了
-
08-13 cudata-cuqt-tab ▸
2026-08-13 客戶資料表新增「客戶單品報價」瀏覽分頁
摘要
客戶資料表(
CUDATA)再加一個瀏覽分頁:客戶單品報價(CUQT/朝陽變體CUQT_CY),做法與 08-10 那四個分頁(產品序號表/客反應主檔/拜訪單/抱怨單)完全相同:
切入自動以當前客戶查詢,報價單號可點跳轉原程式。
項目 內容 分頁位置 排在「客戶報價」之後、「訂單」之前(同屬報價類單據) 條件欄位 報價日期、品號、客戶代號(日期預設全部,比照其他新分頁) 跳轉鍵 報價單號 權限閘 CUQT的檢視權限;經ProgramClassRouter.ResolveNavigable解析變體,朝陽自動對到CUQT_CY品號條件實際比對的是
cuqtm.成品號碼(面板標題仍為品號)——cuqtm 沒有「品號」欄,成品號碼就是報價品項的品號(朝陽 14,215 筆中 14,176 筆有值)。
DB 佈署
sql/cudata-cuqt-tab-browse-20260813.sql:vwbd_cuqtview +DARB_BD_CUQTSP+
twork_sys_viewlist登錄(三樣缺一不可,少了登錄查詢會不報錯地回 0 rows 0 columns)。- view 欄位只取
cuqtm在禾久/朝陽兩庫都有的欄位(交集 45 欄中挑 28 欄),
故同一份腳本兩庫通用;禾久獨有的 報價類別/有效期限/已審核 與朝陽獨有的
單品報價別/美元匯率/日圓匯率/模費轉訂單 都不進瀏覽 view。
- 語法用
DROP + CREATE(非CREATE OR ALTER),朝陽正式機 SQL2008 SP3 也能跑。
- 模擬庫 darbnogicsa1 與 darbcycsa1 都已跑並實測:以
TWORK_BD_VIEWLIST打同一條路徑,
禾久 0 筆(cuqtm 無資料,屬正常)/朝陽 14,212 筆、29 欄。兩邊正式機都未跑。
正式機部署(禾久 csa1~5 整併版)
前後三支腳本(08-10 browse/08-12 viewlist 登錄/08-13 cuqt)已整併成一支
sql/cudata-tabs-deploy-nogi-20260813.sql,正式機只要跑這支:- 一次做完
darbnogicsa1~darbnogicsa5:每庫 4 個 view、4 支 SP、5 筆twork_sys_viewlist登錄
(
vwbd_cmplain/DARB_BD_CMPLAIN是既存物件,只補登錄不重建)。- 物件定義只寫一次,用
庫名.sys.sp_executesql進各庫 context 建立;
缺席的帳套、缺底層表的帳套自動跳過並印訊息,不中斷後續帳套。
- 冪等(view/SP 一律 DROP+CREATE、登錄用 NOT EXISTS),語法相容 SQL2008。
- 檔尾有驗證區,列出每庫的 view/SP/登錄筆數與 OK/★不完整★。
- 執行:
sqlcmd -S <server> -E -f 65001 -i sql\cudata-tabs-deploy-nogi-20260813.sql(不要加-b)。
localhost 實跑驗證:對
darbnogicsa1與darbnogicsa5連跑兩遍,兩遍都是 5/5/5 且計數不變(冪等);darbnogicsa5是從零建起的樣本,五支 ViewNo 都以TWORK_BD_VIEWLIST實測回得到欄位(0 筆是因為該帳套 invent1/repair/visit/cmplain_m/cuqtm 本來就沒資料)。
朝陽(
darbcycsa1)另跑:把整併檔的庫名清單換掉即可,該庫只有cuqtm,其餘三組會自動跳過。待驗
- runtime 未驗:需開 CUDATA 確認分頁出現在客戶報價之後、切入自動帶當前客戶、
報價單號跳轉、編輯狀態鎖定。
- 分頁 Header 的 DisplayMeta key「客戶單品報價」未進
Common/Lang/Xaml/Cudata.json,
現靠 fallback 顯示中文(與 08-10 四個分頁相同狀態)。
- 已知邊緣(與其他分頁同):品號上界取
invent的 MAX(品號),若報價品號不在品號主檔且
字典序更大會被濾掉;朝陽現況實測 0 筆會被濾掉。
- view 欄位只取
-
08-13 combobox-clearbinding-failfast-fix ▸
2026-08-13 下拉控件:拿掉 coerce 內拆綁定的作法(CUPDMA 幣別 FailFast 閃退根因)
摘要
TsComboBox(全 app 每個下拉、含TsCurrency幣別欄)在「ItemsSource 被綁定推成 null」時,原本會在 CoerceValueCallback 內呼叫
BindingOperations.ClearBinding拆掉 SelectedValue/SelectedItem 的雙向綁定。這是 CUPDMA 幣別機率性閃退(
ExecutionEngineException/WPF FailFast)的根因,而且會讓那個下拉從此不再跟 ViewModel 連動。改成不動任何 binding 的作法。
症狀與證據
- 使用者從客戶資料表統計資料超連結跳到 CUPDMA、再按返回時整個進程掛掉。
堆疊:
Twork_ord_vw_cupdmaSource.幣別.set → OnPropertyChanged → UiNotifyMarshal.Raise → [WPF 內部] → ExecutionEngineException。C:\temps\debuglog\2026-08-13.txt崩潰前最後一筆正是
[幣別Probe] CoerceItemsSource detach: type=TsCurrency name=currencyTextBox ... DataContext=Twork_ord_vw_cupdmaSource。- 當天 log 沒有任何
[UiNotifyMarshal] off-UI-thread,代表這次不是跨執行緒 raise
——2026-08-10 那層轉送不是完整解法。
根因
ClearBinding跑在DependencyObject.UpdateEffectiveValue內部(coerce 階段)。在屬性更新進行到一半時去動 binding/weak-event 結構,會讓 WPF 內部狀態不一致,
之後任何一次 PropertyChanged 走訪監聽清單就 FailFast——「當下弄髒、稍後才炸」正好解釋了
先前調查「機率性、重現不了競態」的現象。
變更
TsControl/TsComboBox.cs:- 移除
DetachWritableBindings/DetachWritableBinding(ClearBinding 那條路整段砍掉)。
- 主防線:
CoerceItemsSource改成——目前有選取值時,不接受 ItemsSource 變 null,維持原本的清單。
清單不變 null,
Selector就不會連鎖清空選取,TwoWay 綁定自然不會把空值寫回來源。沒有選取值時照常放行(不影響單純清空下拉的用法)。
- 舊值不能用
GetValue讀:實測ItemsSource在自己的 coerce 裡GetValue已回傳新值(null),舊寫法的
cb.ItemsSource != null判斷其實永遠不成立。改用_lastItemsSource記住最後一份非 null 清單。- 第二道防線:
SelectedValue/SelectedItem的 coerce,在 ItemsSource 本來就是 null 時擋下清空。
覆寫時串接基底既有的 coerce(Telerik 可能也有一份,直接覆寫會把它換掉)。
TsControl/CombineComboBox/TsCurrency.cs:Currency是本控件自己的雙向 DP,不在上面兩個之列,先前那版拆綁定的修法沒有涵蓋它
(log 可見
old=[TWD] new=[] VM=null仍會寫回來源)。補上同判準的 coerce。驗證
寫了離線 WPF 探針(
TsControl.dll+ TsERP bin 依賴,不需登入 app)比對修正前後。關鍵:必須用「綁定把清單推成 null」重現——直接寫
cb.ItemsSource = null走的是 ItemsControl 的CLR setter(內部改叫
ClearValue),那條路根本不會呼叫 coerce,跟 app 的路徑不是同一件事。檢查項 修正前 修正後 來源欄位沒被清空 PASS PASS SelectedValue 保住原值 FAIL(變空) PASS binding 還在(沒被 ClearBinding 拆掉) FAIL PASS 清單回來後選新值仍會寫回來源 FAIL(選了不存檔!) PASS 沒有選取值時 ItemsSource 可正常設 null PASS PASS 清單還在時清空要放行(不過度攔截) PASS PASS TsCurrency:來源/Currency/binding 三項 PASS / PASS / PASS PASS 修正前那條 「清單回來後選新值仍會寫回來源」FAIL 是意外收穫:綁定被拆掉之後,
使用者重新選一個幣別根本不會寫回 ViewModel——等於選了不存檔。這個副作用一併解決。
建置 0 error、
HarnessSmokeTests7/7。Breaking Changes
- 行為變更:有選取值時,把 ItemsSource 綁定推成 null 不再清空下拉清單(維持原清單)。
沒有選取值時行為不變。這比原本「永久拆掉綁定」的副作用小得多。
Runtime 實測(2026-08-13 02:18~02:22,UIA 自動化 + 看圖判讀)
實機重跑原本的閃退路徑,全數通過:
項目 結果 客戶資料表統計資料 →「最新報價單」超連結 開到客戶報價單 QN20260032、pkid 2,089(與 SQL 驗證的 NavigatePkid 一致) 按返回 不再閃退(進程存活),且正確回到客戶資料表(返回上一頁) 回來後基本資料的幣別欄 仍是 TWD(資料沒被洗掉) 新守門是否真的作用 log 有 4 筆 [幣別Probe] 擋下 ItemsSource 變 null,其中一筆正是崩潰堆疊裡那個控件(type=TsCurrency name=currencyTextBox DataContext=Twork_ord_vw_cupdmaSource)舊的危險路徑 重建後 CoerceItemsSource detach0 筆待驗
- 「重新選幣別會寫回 ViewModel」只在離線探針驗過(PASS),實機沒測——要進編輯狀態才試得到,
避免污染模擬庫資料所以沒做。
TsComboBox/TsCurrency內的[幣別Probe]診斷 log 保留(只在真的擋下時寫一筆,
訊息已改成「擋下 ItemsSource 變 null」),實機確認穩定後可整批移除。
-
08-13 casebook-meta-tweaks ▸
2026-08-13 案例書:自訂查詢面板篇改名升星、資訊列改兩排
- 〈常用查詢,拼成自己的儀表板〉改名為〈常用查詢拼成一頁,月份報表一次產出〉:標題改以「整批換月 + 彙整列印 = 一次產出整份月報」為賣點;案例書首頁卡片標題與說明、以及其他篇的交互連結文字同步更新。
- 該篇重要度由 ★★★★☆ 調為 ★★★★★。
- 22 篇開頭的資訊列改成兩排顯示:第一排「案例主角 | 模組」,第二排「更新日期 | 重要度」,長列不再擠成一行。
-
08-12 wkflowt-placeholder-input-and-endofprocessing-display ▸
2026-08-12 工作流程樣板:處理部門可輸入佔位符 + 流程結束欄正確顯示
摘要
修掉工作流程樣板(
WKFLOWT)明細的兩個問題:處理部門欄打不進#I#這類系統佔位符,以及流程結束欄在非編輯狀態不顯示「核准/結束」文字。
變更
- 查詢欄(seek)驗證放行
#…#佔位符(TsControl/ControlValidation/TsSearchRule.cs):
凡是頭尾都是
#、長度 ≥3 的值(#I#、#D#…)視為系統佔位符,不做主檔存在檢查,與既有的
MISC例外同一層。原本這類值會被判「資料不存在」,跳警告且ValidationRule 失敗時來源屬性根本不會被寫回,等於完全打不進去。
- 只認頭尾皆
#的形式,避免把#TWD(Ftrlima 幣別品號)這種真實代號一起放行。- 此規則是全系統共用的 seek 驗證,套用範圍包含
WKFLOWT與WorkflowView的處理部門欄。- 流程結束欄改為顯示文字(
TsERP/A.SystemData/Wkflowt.xaml):
補上
DisplayMemberPath="Description"並移除該欄的ItemTemplate。Telerik
GridViewComboBoxColumn的**非編輯儲存格是純 TextBlock,靠DisplayMemberPath把代號轉成文字**,
ItemTemplate只作用在下拉編輯器;兩者不併用(編輯器互斥)。- 流程結束載入值去尾隨空白(
Model/Source/A.SystemData/Wkflowt/Twork_sys_vw_wkflowt_dSource.cs):
DB 欄位是
char(6),實際存的是"A ";下拉用SelectedValueMemberPath="Code"拿
"A "比"A"永遠比不到,導致整格空白、進編輯也選不到項目。setter 收斂成純代號(存回
char欄位時 SQL Server 自行補滿)。- 流程結束下拉補空白項(
ViewModel/A.SystemData/WkflowtViewModel.cs):
共用列舉只有
A/Y,選過就清不掉;本表單的下拉來源最前面補一個空白項,讓通知/確認/承認這類不結束流程的關卡可以選回空白。
(另建 List,不動
EnumManager的共用清單。)- 寄Email/是否執行程式改用
TsGridViewCheckBoxColumn(TsERP/A.SystemData/Wkflowt.xaml):
原本是
TsGridViewDataColumn+CellTemplate內自刻CheckBox,改成框架的核取欄(
DataMemberBinding帶YesNoConverter,寫法對齊Eventproject.xaml)。附帶修掉一個問題:自刻的 CheckBox 沒有綁編輯狀態,瀏覽狀態下照樣點得動;
框架欄會自動把
IsEnabled綁到表單的ViewModelStatus.Status,非編輯狀態不可勾。使用者可見行為
- 處理部門欄現在可直接鍵入
#I#(送簽時換成當下登入者)等#…#佔位符,不再跳「資料不存在」。
非佔位符的一般部門代號仍照舊驗證存在。
- 明細的流程結束欄在非編輯狀態會顯示「核准/結束」,不再是空白;下拉選項改顯示描述文字
(原本是「碼:描述」),並多一個空白選項可把已選的核准/結束清掉。
- 寄Email/是否執行程式兩欄外觀不變(仍是核取方塊),但在瀏覽狀態下不再能勾動,
要先按新增/修改進入編輯狀態。
Breaking Changes
- 無。DB 結構與存值格式不變。
待驗
- runtime 未驗:修改當下使用者的 TsERP 仍在執行中(舊版 DLL),需重開
A-070 工作流程樣板
實測「輸入
#I#可存檔」與「流程結束欄顯示核准/結束」。 - 查詢欄(seek)驗證放行
-
08-12 todolist-column-cleanup-and-chinese-fallback ▸
2026-08-12 待辦清單:清掉代號欄與技術欄、欄名調整、FallbackValue 改中文、流程結束顯示描述、單據內容數值靠右
摘要
待辦清單(
TODOLIST)五個分頁(本人/代理人/直接下屬/間接下屬/已審核查詢)的主清單拿掉重複的代號欄與技術欄,調整兩個欄位名稱,並把畫面上所有
DisplayMeta綁定的FallbackValue由英文改成中文。刪除
五個分頁的待辦主清單各移除下列欄位(內層的附件/流程子表格不受影響,它們自己的「序號」保留):
欄位 綁定 移除理由 序號 LineNo_流程關卡序號,使用者用不到 狀態碼 StatusCode旁邊已有「狀態」( DisplayStatus)顯示中文項目代號 JobCode旁邊已有「處理事項」( DisplayJobName)顯示中文其他單據id OtherDocID技術欄 pkid_m / pkid pkid_m/pkid技術欄 被刪的欄位中有
x:Name的四個(LineNo_Column/StatusCodeColumn/JobCodeColumn/OtherDocIDColumn)已全 repo 確認無任何 C# 引用。變更
- 欄位改名(全分頁一致,含內層流程子表格):
- 「設定狀態」→ 「狀態」
- 「實處人編號」→ 「實際處理人編號」(與旁邊的「實際處理人」對齊)
FallbackValue一律改中文,取值來自Common/Lang/Xaml/Todolist.json的繁中譯文,
確保未載到語言檔時顯示的字與切語言後一致:
| DisplayMeta key | 原 FallbackValue | 現 FallbackValue |
|---|---|---|
| Self | Self | 本人 |
| Substitute | Substitute | 代理人 |
| DirectReport | DirectReport | 直接下屬 |
| IndirectReport | IndirectReport | 間接下屬 |
| AuditedQuery | AuditedQuery | 已審核查詢 |
| Subject | Subject | 主旨 |
| 附件 | Attachment | 附件 |
| Workflow | Workflow | 工作流程 |
| BeginningDate / EndingDate | 同名英文 | 起始日期/截止日期 |
| SelfAudit / SubstituteAudit | 同名英文 | 本人審核/代理人審核 |
| Both | Both | 兩者皆是 |
- 流程結束改顯示描述(
LogicBll/Workflow/TodoListPoco.cs、TsERP/Z.System/TodoList.xaml):
五個分頁的流程結束欄原本直接顯示代號
A/Y。新增DisplayEndOfProcessing(比照既有的DisplayJobName/DisplayStatus慣例,於SetDisplayDescription()一併填入),欄位改綁它,顯示「核准」/「結束」。來源欄位是 char 會補尾隨空白,比對代號前先
Trim();空白或查無對應者顯示空白(查無時退回顯示原代號,不會吃掉資料)。
- 單據內容(XML 轉表格)數值欄靠右對齊 + 千分位(
TsERP/Z.System/TodoList.xaml.cs):
自動產生欄位的處理改呼叫全系統共用的
TsRadGridHelper.ApplyColumnStyle(與瀏覽表格同一套),並修掉原本兩個會讓樣式套不上的問題:
1. 綁
DataTable時e.ItemPropertyInfo可能為 null,原本直接取.Name會 NRE;現在改用
e.Column.UniqueName,型別則回頭問DataColumn.DataType。2. 格式字串原本是裸的
"N2",Telerik 要的是複合格式"{0:N2}"。涵蓋的數值型別也從 int/double/decimal 擴大到含 long、float 與各自的 nullable。
Breaking Changes
- 無。純畫面欄位增刪與文字,未動資料與邏輯。
待驗
- runtime 未驗:需開 TODOLIST 逐分頁確認欄位、欄寬與分頁標題。
-
08-12 todolist-chinese-binding-and-subject-restyle ▸
2026-08-12 待辦清單:綁定全面中文化、主旨區改版、分頁筆數改圓角徽章
摘要
待辦清單(
TODOLIST)三件事:畫面綁定與底層屬性名全面中文化(順手修好三個一直空白的附件欄)、下方主旨區改成卡片式版面、分頁標題的資料筆數改成圓角徽章。
變更
1. 綁定中文化(139 處)
TsERP/Z.System/TodoList.xaml的所有DataMemberBinding由英文屬性改綁中文屬性
(
NotesNo→聯絡單號、HandlerCode→處理人編號、StartDate→開始日…)。保留英文的只有四種:
DisplayStatus/DisplayJobName/DisplayEndOfProcessing(顯示用衍生屬性,比照
Source類既有慣例)與系統欄linkid。- 對應的底層屬性同步改名:
LogicBll/Workflow/TodoListPoco.cs、
ViewModel/Other/TodoList/WorkflowStep.cs,新名一律取自該屬性原本的[TsColumnName]值。對映不受影響——
Common/Context/ContextPocoExtensions.cs的GetPropertyDic先比屬性名、比不到才比
[TsColumnName],改名後對映到同一個 DataTable 欄位。ProgramClass例外處理:它被ITodoList與IAutoPilotPoco兩個介面要求。
改成可寫的
單據別(供 XAML 綁定與資料對映)+保留唯讀轉接public string ProgramClass => 單據別;滿足介面與既有 C# 呼叫端。其餘被介面綁死的成員(
ViewXML/DocNo/CreatePDF/Method/Parameter/OtherDocID)維持英文。- 連動修正的呼叫端:
WorkflowApproveBll.BuildCommpr2Model、WorkflowApprovalViewModel、
TodoListPerson、TodoListCommand。2. 修好三個一直空白的附件欄(順手抓到的 bug)
四個分頁的附件子表格原本綁
LineNo_/Attachment/IsLoaded/Tag,但資料來源
Twork_com_vw_commpr_1Source的屬性是序號/附件/載入/標籤——綁錯的欄位不會 build error,只會永遠空白。本次一併改綁中文屬性後才會有值。
3. DisplayMeta key 由英文改中文
DisplayMetaDicViewModel的索引子在查無 key 時回傳 key 本身,所以英文 key一旦查不到譯文,畫面就直接顯示
Self/Subject/Workflow這些英文字,XAML 的
FallbackValue根本不會被觸發(binding 是成功的)。本次把 12 個 key 改成中文(
DisplayMeta[本人]、DisplayMeta[主旨]、DisplayMeta[工作流程]…),最壞情況顯示的也是中文。
Common/Lang/Xaml/Todolist.json早已英文/中文雙鍵、四語譯文相同,改 key 不影響切語言;順手把
主旨這筆的英文譯文由NotesSubject修正回Subject。4. 主旨區改版
- 外框由純黑 1px 直角框改成白底圓角卡片(
#C9D3E2淺灰藍框線)。
- 主旨列改成淺底橫幅+左側藏青色條(
#1F3864),標題字級由 18 收斂為 14 SemiBold。
- 主旨內容由固定寬 528 的唯讀輸入框改成滿版顯示,套用框架既有的
TsTextBoxAsTextBlockStyle(看起來像文字、仍可選取複製),並加上 ToolTip 顯示完整主旨。- 附件/工作流程加上小標題(藏青短色條+標題文字),五個分頁一致
(直接下屬/間接下屬/已審核查詢三個分頁原本沒有附件標題,本次補上)。
5. 分頁資料筆數改圓角徽章
分頁標題右側的筆數原本是
TsControl共用的Count樣式(紅底白字方塊,直角、貼著標題)。改成本檔自訂的圓角膠囊(
CountBadge/CountBadgeText:#D93025底、8px 圓角、最小寬 18、11pt SemiBold、與標題間距 7)。顯示/隱藏邏輯不變(仍綁
CountVisibility,0 筆不顯示)。TsControl的Count樣式本來就只有這支程式在用,本次未刪除、僅不再引用。6. 工作流程審核視窗(`WORKFLOWAPPROVAL`)比例與最小尺寸
從待辦清單按「核准」開的審核視窗原本比例失衡:版面最外層是
auto/*/auto/auto/auto/*六列,**最後一列(按鈕區)也是
***,又搭配isSizeToContent: true——星號列在 SizeToContent 下塌成最小高度,結果是意見列表被壓扁、按鈕上下留一大片空白。
- 版面重排(
TsERP/Other/WorkFlowApproval.xaml):改成Auto/*(MinHeight 160)/Auto/Auto/Auto五列,
只有意見列表吃剩餘高度;按鈕列改
Auto並靠右對齊、上方加一條細分隔線(原本兩顆鈕靠
Margin="50,0,0,0"硬撐間距,改成 16)。- 意見列表加白底圓角卡片外框;「審核意見」欄由固定 300 改成
Width="*"+MinWidth="300",跟著視窗延展。
- 表單區兩列(審核別/審核意見)標籤用
SharedSizeGroup對齊,審核意見輸入框由固定 300 改成滿版延展,
審核別由 80 放寬到 160。
- DisplayMeta key 由英文改中文(
CommentList→意見列表、ApproveType→審核別、ApproveComment→審核意見),
原因同第 3 點;
Common/Lang/Xaml/WorkflowApproval.json本來就是雙鍵,切語言不受影響。- 視窗尺寸:
WorkflowApprovalViewModel.Parameter由isSizeToContent: true改成固定起始
860×620,並設最小 700×540。為此
ContentWindowParameter新增選用的minWidth/minHeight參數(預設 0 = 不設限,其餘所有彈窗行為不變),由
ContentWindow在建構時套到視窗上。7. 程式容器右側面板:工作流程分頁改用狀態圓點
右側支援面板(
TsControl/PageParts/SupportPanel.xaml)的分頁標題原本一律在標題後面加紅字筆數「(N)」。工作流程分頁改成狀態圓點,附件等其他分頁維持顯示筆數(兩種提示不併存):
狀況 標題顯示 這支程式沒有工作流程(或當筆沒有關卡資料) 空白,不顯示任何提示 有工作流程、關卡都處理完了 灰點( #9E9E9E)有工作流程、還有關卡沒處理完 紅點( #E53935)- 「沒處理完」的判準沿用
WorkflowTabViewModel.ApproveExecute既有的前關卡檢查:
完成率 != 100 且 處理事項碼 > 1(處理事項碼 1 是通知類關卡,不需審核,不算未完成)。- 實作:
ITabViewModel/TabViewModel新增StatusDot(列舉None/Normal/Alert)、
StatusDotToolTip與ShowDataCount;基底一律None=維持原本顯示筆數的行為,只有
WorkflowTabViewModel覆寫。滑鼠移到圓點上會顯示「工作流程尚未處理完成/已處理完成」。8. 工作流程面板:圖像/表格對調、改名、卡片可點擊審核
TsControl/PageParts/SupportParts/WorkflowView.xaml:- 順序對調:原本第一個分頁是表格、第二個是圖像;改成圖在前、表在後——
打開就看到流程全貌,要看欄位細節才切第二頁。
- 改名:「圖像」→ 「流程圖」、「表格」→ 「關卡明細」。
(「圖像」容易被讀成附圖/影像;「表格」只描述了呈現方式沒說內容。)
- 流程樣板資訊(
WorkflowTemplateDisplay,樣板號:流程說明)跟著移到第一個分頁的標題後面,
否則對調後預設看不到。
- 流程圖的卡片可直接點擊審核:每張關卡卡片包成
Button,
Command綁ItemsControl的DataContext.ApproveCommand——與「關卡明細」分頁那顆審核鈕同一條命令,前關卡未審/後關卡已審/通知關卡已完成等既有檢查全部沿用,不另寫一套。
按鈕用只有
ContentPresenter的自訂Template,避免套上主題按鈕外觀把卡片樣式蓋掉;滑鼠移上去換游標、卡片外框轉藏青色當可點擊提示,並附「按一下審核這個關卡」的 ToolTip。
9. 第二輪外觀調整(同日追加:降彩度、放大筆數、單據內容 0 留白)
使用者回饋「主旨看起來奇怪、顏色太鮮豔、分頁數字太小、審核視窗的儲存/取消鈕跟別的視窗不一樣」,同日再修一輪:
- 主旨列版面由「標籤:值」橫排改成小標題在上、主旨本文在下的堆疊:
上排 11px 灰藍小標題(
主旨),下排 16px Medium 深墨字的主旨本文,左側只留一條 2px 重點色細線(原本是 4px 飽和藏青色條+淺藍底橫幅)。
- 配色全面降彩度,改走同一套石板藍:重點色
#1F3864→#3D5A80、框線#C9D3E2→#E3E7EC、
主旨列底色
#EEF2F8→#FAFBFC、主旨本文#232A33。WorkFlowApproval.xaml的ApprovalAccent/ApprovalLine同步換成同兩個值,兩個畫面是同一套視覺。- 分頁筆數徽章:字級 11→14、膠囊 16 高→22 高(最小寬 18→24),底色由鮮紅
#D93025
改為同色系深石板
#46586F——放大後仍不刺眼。- 主旨列樣板收斂成一份:五個分頁原本各自複製一段 23 行的主旨列 XAML,改成共用
SubjectHeaderTemplate(ControlTemplate+ContentControl),日後改樣式只要改一處。- 單據內容表格(viewxml 攤平的自動欄位)數值欄 0 一律留白:
TodoList.xaml.cs加ApplyZeroAsBlankFormat,用自訂格式的第三段(正;負;零)留空。只影響這張表格,全系統共用的
TsRadGridHelper.ApplyColumnStyle未改,其他瀏覽表格照舊顯示 0。- 審核視窗的儲存/取消鈕:拿掉自訂的
Height=40/MinWidth=110/Margin=16,
尺寸間距一律回歸
BtnSave/BtnCancel樣式(比照Ormast_s、BOLImport等既有視窗)。原本
MinWidth=110搭配樣式的HorizontalContentAlignment=Left,會把圖示+文字擠在按鈕左半邊,看起來就跟系統其他儲存/取消鈕不一樣。
Breaking Changes
- 無。DB 結構、SP、資料對映結果均未變動;屬性改名是純程式內部重構,已全 repo 掃過呼叫端。
ContentWindowParameter是新增選用參數,既有呼叫端不受影響。待驗
- runtime 未驗:需開
TODOLIST逐分頁確認
①主旨區版面與主旨文字有值 ②附件子表格的序號/附件/載入/標籤四欄有值
③分頁筆數徽章外觀與 0 筆時隱藏 ④五個分頁欄位都有資料(中文綁定沒漏)。
- 第二輪追加待驗:⑤主旨列新版堆疊版面與降彩度配色 ⑥筆數徽章放大後的視覺
⑦單據內容表格的 0 是否確實留白(只對數值型欄位有效;若 viewxml 該欄是字串型,
「0」仍會顯示,屆時要改走 CellTemplate)⑧審核視窗儲存/取消鈕與其他視窗一致。
- 建置(
TsERP.csproj,VS MSBuild)0 error、HarnessSmokeTests7/7 通過。
-
08-12 myfavorite-order-fix ▸
2026-08-12 我的最愛:程式沒有照使用者排定的順序顯示
摘要
點「我的最愛」開出來的程式按鈕,順序不是使用者在設定裡排的順序,而是權限表的原始順序。
根因
LogicBll/Login/UserBll.cs的GetNavigateProgramParameters:.Where(a => selector(a) && a.CpuIDIsValid()) .OrderBy(selector) // ← 排序鍵是那個 bool 條件本身selector是Func<PermissionTable, bool>的篩選條件,經過Where之後每一列都是true,所以
OrderBy排的是一個常數,等於完全沒作用(LINQ 的 OrderBy 是穩定排序,維持原順序)。我的最愛的順序其實存在權限表的
我的最愛1~我的最愛5欄位裡(
ChangePasswordAndMyFavoriteViewModel寫入(i+1).ToString("D2")="01"、"02"…),但這個值從來沒被拿來排序過。
變更
GetNavigateProgramParameters新增選用參數orderKeySelector(Func<PermissionTable, string>):
- 不傳(其餘所有呼叫端)= 不排序,維持權限表原順序——與修正前的實際行為完全相同
(原本那行 OrderBy 本來就沒有作用)。
- 有傳=依該欄排序。數字優先:能
int.TryParse的用數字排,避免舊資料沒補零時"1" < "10" < "2"的字串排序錯誤;轉不動的排最後、再照字串排。ViewModel/MenuViewModel.cs的GetFavoritePrograms傳入對應的我的最愛N欄當排序鍵。
- 介面
Common/Environment/IUser.cs與五個實作端(測試用 context ×3、ImporterUser、SchedulerUser)
同步加上該選用參數。
使用者可見行為
- 我的最愛 1~5 的程式按鈕,現在照設定畫面裡排的先後順序顯示。
- 其他用到同一支方法的地方(子系統選單、行事曆、EVENTPROJECT 入口、單一程式導覽)行為不變。
Breaking Changes
- 無。新增的是選用參數,既有呼叫端不必改也不受影響。
待驗
- runtime 未驗:需登入後到設定裡排一組我的最愛(刻意排成非程式代號順序),再點我的最愛確認按鈕順序一致。
- 註:
TsERP.sln整包建置有一個與本次無關的既有錯誤——UnitTest1是 .NET Framework 4.8 專案,
參考了 net8.0-windows 的 Common/LogicBll。本次改動的專案(TsERP/LogicBllTests/AccDbfImporter/
SchedulerWorker/SchedulerWorker.Tests)逐一建置皆通過。
-
08-12 mail-search ▸
2026-08-12 信件搜尋(客戶歸戶+AI 搜信)
新增
- 信件搜尋視窗(L.Communication → 信件搜尋):以客戶代號/關鍵字/日期範圍搜尋
已同步的公司信箱信件,含內文預覽與「信箱帳號」管理分頁(啟用/停用/刪除、
同步狀態與錯誤顯示)。只能看到自己名下、且歸屬本帳套的信箱。
- AI 工具
search_mail:AI 助理可用自然語言搜信(「朝陽最近抱怨交期的信」),
支援關鍵字全文檢索(主旨/內文/附件檔名)、客戶歸戶過濾、寄件人、日期範圍。
- 排程任務 Mail_Sync:增量同步啟用中信箱的新信進集中索引,並自動比對各帳套
客戶主檔(cudata/cudata_1 的 email 與網域)歸戶到客戶代號。頻率依排程事件設定
(種子
sql/mailsync-event-seed-20260812.sql為每日 07:30,用 EVENTPROJECT 大量新增展開)。- worker 子命令:
--mail-keygen(產加密金鑰)、--mail-acct-add(新增信箱帳號,
密碼互動輸入不落 shell 歷史;尾端可指定歸屬帳套,省略自動推導)、
--mail-test(連線與搜尋測試)。行為說明
- 信件內容預設會提供給 AI 回答;管理者可用
AI_MAIL_CONTENT_TO_MODEL=N
(_prgpar 或環境變數)關閉,關閉後 AI 只拿得到筆數/寄件人/日期等中繼資料。
- Gmail/M365 信箱:可走 IMAP+應用程式密碼,或官方 OAuth 轉接器(M365 Graph/Gmail API,
--mail-link授權;需管理者一次性完成 Azure/Google 應用程式註冊,指引見指令輸出)。部署(每家公司一次)
1.
sql/mail-search-deploy-20260811.sql跑在該公司 SQL Server(建四張表+全文檢索+foxlog/foxai 授權;冪等可重跑;CY 需字串代換 darbcyauto1 並確認 FTS 元件)。
2.
sql/mailsearch-menu-seed-20260811.sql(選單)。3. worker 機器
appsettings.local.json設MailSearch:CredentialKey(--mail-keygen產生),並以
--mail-acct-add登錄信箱。 -
08-12 inventquery-remove-query-type-radios ▸
2026-08-12 品號/客戶/廠商查詢頁:拿掉「預設/自定義」切換,檢視模式只留查詢條件
摘要
InventQuery查詢版面(品號主檔、客戶資料、廠商資料、總務品號等程式的各個查詢分頁共用同一份樣板)拿掉最上方的「預設/自定義」兩顆單選鈕;統計資料按「檢視」帶條件進來時,
條件面板整塊收起來,只顯示那筆統計定義的查詢條件,標籤由「自定義」改成「查詢條件」。
變更
1. 拿掉「預設/自定義」單選鈕
TsControl/Themes/TsStyles.xaml的InventQueryControlTemplate第一列原本是兩顆單選鈕(另有一顆
Quarter早已註解掉)。查詢別不再由使用者切換:- 一般查詢一律
Default(走條件面板)。
- 統計資料的「檢視」「開啟」由
InventSpecialQueryViewModel.DisplayCommand/NaivigateCommand
(客戶端為
CudataSpecialQueryViewModel)直接把QueryType設成SelfDefined,行為不變。- 切到別筆主檔時
AfterMoverRecord會呼叫ResetQueryState()把查詢別復原成Default,
所以拿掉單選鈕不會讓分頁卡在自定義狀態。
第一列的
RowDefinition保留(auto,沒有內容即 0 高度),其餘各列Grid.Row不變。2. 檢視模式只顯示查詢條件
InventQueryViewModel新增ConditionVisibility,與既有的SelfDefinedVisibility在QueryTypesetter 中一起設定,兩者互斥:查詢別 條件面板 查詢條件(唯讀) Default(一般查詢)顯示 隱藏 SelfDefined(統計資料檢視)隱藏(本次改動) 顯示 理由:
SelfDefined時查詢條件來自統計定義的QueryCondition,條件面板改了也不影響結果(
Query()只取SelfDefinedCondition),留著只會誤導。3. 標籤「自定義」改「查詢條件」
同一份樣板中唯讀條件框的標籤
DisplayMeta[自定義]→DisplayMeta[查詢條件]。(
InventTab1.xaml/CudataTab1.xaml/SpdataTab1.xaml主檔頁的「自定義分類」是另一個功能,未動。)Breaking Changes
- 使用者不能再手動把查詢分頁切成「自定義」——原本切過去也只會看到一個唯讀條件框,
沒有輸入自定義條件的入口,實際等於沒有用途。
待驗
- runtime 未驗:需開品號主檔/客戶資料/廠商資料的查詢分頁確認
①上方單選鈕已消失、條件面板位置沒有多出空白列 ②統計資料按「檢視」後只看到「查詢條件」唯讀框
③切換主檔筆數後查詢分頁回到條件面板。
- 建置:
TsControl.csproj、ViewModel.csproj皆 exit 0。
- 一般查詢一律
-
08-12 cudata-tab-order-and-remark-layout ▸
2026-08-12 客戶資料表:應收帳款分頁移到出貨之後、自定義移到備註下方
摘要
客戶資料表(
CUDATA)兩處版面調整:分頁順序照單據流程排、基本資料的「備註」與「自定義」改成上下疊放並隨視窗寬度展開。變更
1. 分頁順序
ViewModel/E.Order/CudataViewModel.cs:「應收帳款」由統計資料之後移到「出貨」之後。新順序=基本資料/財務/其他/統計資料/客戶報價/訂單/出貨/應收帳款/產品序號表/
客反應主檔/拜訪單/抱怨單/索引分類帳(=報價→訂單→出貨→應收的單據流程順序)。
- 各分頁原本的檢視權限判斷(應收帳款需
RECEIVE檢視權)原樣保留。
- 程式內只有
Tabs[0](基本資料)用到寫死索引,搬動不影響選取邏輯。
Cudata_cyViewModel繼承CudataViewModel,朝陽變體同步套用。
2. 基本資料分頁:備註/自定義版面
TsERP/E.Order/CudataTab1.xaml:- Master 區原本是三欄(左:欄位群組|中:備註|右:自定義),改成兩欄:
左邊欄位群組不變,**右欄改成
*寬度,內含上下兩塊:上=備註、下=自定義**。- 備註:拿掉固定
Width="300"/Height="576",改成上下左右都 Stretch,
吃掉右欄扣掉自定義之後的所有空間(
TsTextBox預設樣式是靠左,所以顯式加HorizontalAlignment="Stretch")。- 自定義:改成固定高度
200(標題列+約 6 列資料,超過捲動);
「分類內容」欄由固定
Width="300"改成Width="*"+MinWidth="300",跟著視窗寬度展開。- 右欄整塊維持總高
576(與左側欄位區齊高)。外層 Row 是Auto,不給高度整塊會塌成內容最小高。
- 右欄頂端空出 55px:框架的
ExtensionPanel(右上角 pkid/已審核)是疊在程式內容之上的
overlay——
TsControl/Layout/ErpProgramLayout.xaml讓Content直接ColumnSpan="2",面板另外蓋在右上角。備註改成滿版延展後上緣會頂到它,所以在容器最上面加一列 55 高的空白讓開
(這個 55 沿用改版前自定義群組原本的
Margin="2,55,2,2")。備註因此從面板下方開始、往下吃滿到自定義為止。Breaking Changes
- 無。純版面與分頁順序調整,未動資料或存檔邏輯。
待驗
- runtime 未驗:需開 CUDATA 確認
①分頁順序 ②備註框有沒有隨視窗寬度變寬、輸入與捲動正常
③自定義只顯示約 6 列、分類內容欄跟著變寬 ④「設定」按鈕在編輯狀態下仍可按。
- 各分頁原本的檢視權限判斷(應收帳款需
-
08-12 cudata-statistics-content-hyperlink ▸
2026-08-12 統計資料:超連結改做在「內容」欄,直接開對應程式(客戶/廠商/品號)
摘要
「統計資料」面板:拿掉獨立的「超連結」按鈕欄,改成把超連結做在「內容」欄本身——
能定位到單一單據的列用藍字加底線顯示,按下去開對應的 ERP 程式並跳到那一筆。
共 8 個統計資料格都做了:客戶資料表(CUDATA)/廠商資料(SPDATA)/品號(INVENT_BS)三支主畫面,
加上 5 支把統計格內嵌在主畫面的舊版/變體頁面。
「檢視」/「顯示」/「Display」按鈕欄一律移到第一欄(8 個格子統一)。
變更
畫面(`TsERP/E.Order/CudataStatistics.xaml`)
- 欄位順序由
超連結 | 項目 | 內容 | 檢視改為檢視 | 項目 | 內容(檢視與超連結對調,超連結併入內容)。
- 「內容」欄兩種樣態,由 Poco 的
NavigateVisibility/PlainVisibility互斥切換:
- 可定位(最新報價單、最新訂單):
Hyperlink,藍字#0563C1+ 底線,ToolTip「開啟對應程式並跳到這一筆」。
- 區間彙總(本月/本年/去年金額):維持一般文字,不做超連結。
跳轉行為(`ViewModel/E.Order/Cudata/CudataSpecialQueryViewModel.cs`)
- 原本「超連結」是切到客戶資料表自己的查詢分頁並帶條件查詢;該用途已由「檢視」(在右半邊 inline 顯示)取代,本次移除。
- 改走框架的
IHyperLink.HyperLinkWithPkid(程式代號, pkid, 返回上一頁):
權限檢查、變體解析(
INVENT→INVENT_BS)、目標程式不在目前子系統時自動加入、切頁,全部沿用框架既有邏輯。- 目標程式取自定義表既有的
PermissionProgramClass欄(實查 CUSTOMER 八列為 CUPDMA/ORMAST/TRSAMA),不需新增欄位。
- 跳過去之後「返回」回到上一頁(客戶資料表)。為此
IHyperLink補上MustReturnPriorPage
——該方法本來就存在於實作類別,只是沒列進介面(既有的
TodoListHyperLink行為相同但命名綁待辦)。資料(`sql/statistics-definition-navigate-pkid-20260812.sql`)
TWORK_STATISTIC_DEFINITION(父):#stats新增NavigatePkid INT NULL,INSERT改顯式欄位清單
(原本是位置式,加欄容易錯位)。
TWORK_STATISTIC_CUSTOMER(子):「最新訂單」「最新報價單」兩個分支填入該單據 pkid;其餘分支維持 NULL。
- 為什麼不解析既有的
QueryCondition:那欄是「檢視」用的 SQL where 條件(單據列剛好長成pkid_m=NNN),
讓它兼差當導航參數等於一欄兩用途,日後改一邊會靜默弄壞另一邊。
Model/Statistic_definitionPoco.cs補PermissionProgramClass、NavigatePkid與衍生的
CanNavigate/NavigateVisibility/PlainVisibility。廠商資料(SPDATA)與品號(INVENT_BS)
同一套做法套到另外兩個統計資料面板:
TsERP/G.Purchasing/SpdataStatistics.xaml、TsERP/D.Bom/InventStatistics.xaml、ViewModel/G.Purchasing/SpdataSpecialQueryViewModel.cs、ViewModel/D.Bom/Invent/InventSpecialQueryViewModel.cs。欄位順序也跟著改成
檢視 | 項目 | 內容,與客戶資料表一致。sql/statistics-definition-navigate-pkid-vendor-invent-20260812.sql補兩支子程序的NavigatePkid:分類 有超連結的列 廠商(VENDOR/SPDATA) 最新報價單號、最新未結案採購單、最新進貨單號 品號(INVENT) 最新報價單價、最新未結案採購單、最新進貨單號、最新出貨單號、最新銷售訂單、最新進貨單價、最新銷售單價 品號兩列的重點:「最新進貨單價」「最新銷售單價」的
QueryCondition是pkid=<明細 pkid>(trrade/trsade 的明細列),不是主檔。導航要開的是整張單,所以
NavigatePkid取主檔a.pkid,QueryCondition原樣不動(它還要給「檢視」做明細層查詢)。——這正是當初決定另開一欄、不解析
QueryCondition的價值所在。內嵌統計格的舊版/變體畫面(5 支)
Ginvent.xaml/Invent_prime.xaml/Invent_zd.xaml/Spdata20230829.xaml/Spdata_US.xaml把統計格內嵌在主畫面,綁的是同一顆
BtnCommand。命令語意換掉後不一起改,那顆按鈕在彙總列會變成按了沒反應的死鈕,因此一併套用同樣的模式:「內容」欄改成可點的超連結、獨立的「超連結」/「Navigate」欄整欄刪除,
「顯示」/「Display」欄原樣保留。各檔原本「內容」欄用的 Converter 照該檔既有寫法保留
(例:
Invent_zd.xaml的DynamicConverter)。已知既有差異(未統一,維持原樣):
Invent_prime.xaml的按鈕欄本來就沒有CellStyle="{StaticResource ButtonCell}",與其他檔不同。底線不見的修正(2026-08-13 實機回報)
超連結是藍字但沒有底線。根因是既知問題:**WPF
TextFormattingMode=Display配新細明體(MingLiU)不渲染
TextDecorations**(Foreground 等其他設定正常,所以症狀就是「藍字沒底線」),全 app 字型是 MingLiU,儲存格繼承 Display 模式。
沿用
TsTextBoxGeneric.xaml/V2Generic.xaml對IsHyperLink欄位早就採用的 workaround:在放
Hyperlink的那個TextBlock上加TextOptions.TextFormattingMode="Ideal"(8 個統計格都加)。只有超連結那格切 Ideal(字略柔但有底線),同一格的一般文字仍是 Display 銳利點陣。
Breaking Changes
- 無資料結構變更(只動兩支預存程序內部的暫存表與輸出欄位)。
- 行為變更一項:「超連結」不再是切到客戶資料表內部分頁,而是開真正的程式(依裁決)。
部署
sql/statistics-definition-navigate-pkid-20260812.sql需在每個客戶資料庫各跑一次
(darbnogicsa1/darbcycsa1/各 csa1~4)。以 SqlClient/SSMS 等 Unicode 連線執行,勿用預設 codepage 的 sqlcmd。
- 朝陽正式機為 SQL 2008,本檔只用 2008 既有語法。
- 開發機
darbnogicsa1已部署並實跑驗證:最新報價單/最新訂單兩列NavigatePkid有值,六筆金額列為 NULL。
待驗
- runtime 未驗:需開 CUDATA →統計資料,確認
①「內容」欄兩列是藍字底線、其餘是一般文字 ②點下去有開到 CUPDMA/ORMAST 且停在正確單據
③返回鍵會回到客戶資料表 ④「檢視」仍正常。
- 已知風險:
Hyperlink放在 RadGridView 的 CellTemplate 內,點擊事件是否會被格線的選取邏輯吃掉,只有實機點得出來。
- 欄位順序由
-
08-12 bomflow-hide-flowchart-rename-diagram ▸
BOM 流程圖製程表:停用表格版流程圖、圖形分頁改名「展開圖」、修正列印圖形誤判
日期:2026-08-12
程式:
D-110 流程圖製程表(BOM_FLOW)使用者看得到的變動
- 「流程圖」分頁(90 欄表格版)隱藏。右側分頁剩四個:
製程明細/多階材料用量清單/展開圖/材料流向圖。
- 條件區「計算流程圖」勾選隱藏。查詢條件現在只剩
起訖品號與去除重複組件編號;不再計算 90 欄矩陣,查詢速度變快。
- 「流程圖圖形」分頁改名為「展開圖」(內容與操作完全不變;四語系同步)。該分頁
列印圖形/匯出圖檔的預設檔名/列印工作名稱改為BOM展開圖_<查詢組件號>。
- D110-1「產品流程圖」報表下架。它的資料來源是表格版流程圖,勾選拿掉後必然無資料,因此一併停用(報表檔案保留,日後可復活)。
- 「製程明細」數字欄靠右對齊、小數位統一:
數量/損耗率/標準工時/整備工時/移轉天數五欄改為靠右對齊並固定小數位——數量 6 位(BOM 用量精度,與已隱藏的表格版一致)、其餘四欄 2 位;值為 0 的格子留白不印,與系統其他數字欄一致。
匯出圖檔存完自動開啟:兩個圖形分頁按匯出圖檔存檔後,直接用系統預設看圖程式把圖打開,不再只跳一個「圖檔已匯出:路徑」的訊息要人自己去找檔案。(沒有關聯的看圖程式時,仍退回顯示路徑訊息。)
修正
- 按
列印圖形/匯出圖檔誤報「目前沒有可列印/可匯出的圖形內容」:圖面明明有節點卻被擋下。原因是計算圖形範圍時掃的是RadDiagram.Items,而本畫面兩張圖都以 GraphSource 資料繫結,此時該集合不會放進生成出來的節點與連線,永遠掃到 0 個。改為掃Shapes/Connections(與本畫面排版程式一致),Items僅作為非資料繫結情境的保底。兩個圖形分頁的列印與匯出都適用。
需要注意
- 需要把流程結構逐欄貼到 Excel 的使用者,表格版已無入口;請改用
展開圖/材料流向圖的匯出圖檔。若確有需要,可反映後復原(見 ADR 0129)。
- 「流程圖」分頁(90 欄表格版)隱藏。右側分頁剩四個:
-
08-11 manual-calendar-customdash-acc-case ▸
2026-08-11 手冊:行事曆面板頁+自訂查詢重寫+案例書會計篇與過時修正
新增
- 基本畫面介紹新頁「右側行事曆面板」(
getting-started/calendar-panel.md):開關、月曆圓點、擁有者篩選、事件卡操作、日期欄雙擊跳轉,與排程專案互連。
- 案例書新篇「月結後的十二張財務報表,拼成一頁」(
case-studies/acc-customdash.md,財報與總帳群組):會計課用自訂查詢面板裝整包月結報表的場景案例,素材取自實際配置(12 格:資產負債表+損益表×2+自訂財報×9)。實機截圖待拍(已登記)。
改寫
- M-EIS 自訂查詢面板手冊頁全檔重寫(205→363 行):修正三處與現行程式不符的舊敘述——①組配置功能 2026-07-14 起已移至獨立程式「自訂面板配置」(A 系統資料),面板只負責載入與執行;②「彙整匯出」已改名「匯出HTML」且只產出一個 HTML 檔;③匯出勾選的是顯示項目並有「隱藏零值」選項。補整批換月規則對照表、彙整列印 vs 匯出 HTML 比較、從零建配置流程、FAQ 擴充至 13 題。
- 案例書同步清過時:customdash 篇改寫為「組配置/用配置兩支程式」敘事;mobile-dashboard(案例+手冊)、scheduled-report 的存配置說法改指「自訂面板配置」;browse-condition 運算子名稱正名;bom-flow 分頁名對齊現行畫面(製程明細/多階材料用量清單)。
- 財報總帳群組互連:gldash、acc-selfrpt、customdash 各補連結至新會計篇。
實機截圖(同日補齊)
- DEMO 展示環境實拍 18 張並嵌入:會計案例 3 張(面板全貌/整批換月/彙整列印+29 頁 PDF 預覽拼圖)、自訂查詢手冊 11 張(含匯出 HTML 成品封面與內容頁)、行事曆面板全貌、日期欄雙擊跳行事曆 2 張(文字框+格線)。
- 「日期欄按兩下跳行事曆」功能於實拍中完成 runtime 驗證:文字框(編輯狀態)與 Telerik 格線日期欄雙擊皆正確跳轉並選中該日。
- 案例書 PDF 重出:131 頁、零切圖(
assets/Darbware-ERP-case-book.pdf)。
備註
- 全案例書真實公司名清查歸零(禾久/台賓/可俐明/裕隆);demo 庫同步清理 acc_rptm 報表名稱×3 與科目 1287(達興→乙川)。
- demo 庫「財務報表」配置修正:營業毛利表格改掛實際存在的
IS-A定義(原 GM01 為空號)、FEE-05~08 補自訂標題(倉儲組/運輸組/財務部/總管理部);dev 模擬庫 GM01 同步修正(使用者裁決)。
- 基本畫面介紹新頁「右側行事曆面板」(
-
08-11 manual-basic-font12-transfer-in ▸
2026-08-11 手冊基本畫面介紹:字級下限 12pt+轉單按鈕更名「轉單-轉入」+新增瀏覽/清單瀏覽/列印畫面頁
變更內容
- 新增「瀏覽、清單瀏覽與列印畫面」頁(
docs/getting-started/browse-print.md):介紹工具列瀏覽/清單瀏覽/列印三顆鈕切換的共通畫面——瀏覽畫面(唯讀單據清單+條件區+查詢/定位/返回)、清單瀏覽畫面(明細層級專屬查詢+統計格線+樞紐選欄;舊稱「明細瀏覽」僅以別名搭橋一次)、列印畫面與報表預覽視窗(兩種進入路徑、列印控制列四鈕、預覽視窗完整工具列)。內容依程式碼逐行查證撰寫;5 張截圖待補(列於頁尾需補截圖清單)。index.md按鈕一覽表三列與相關功能同步加連結;新增docs/getting-started/.nav.yml固定章內順序。
- PDF 匯出占位防護(
tools/docs-pdf/export-pdf.py):引用的圖檔尚不存在時,改輸出「(截圖待補)」虛線框占位,不再出破圖;圖補上後重匯自動恢復。
- 五張畫面截圖補齊(同日稍晚):瀏覽畫面全景/條件區近照/清單瀏覽(以訂單管理示範,含中文統計格線)/列印勾選模式(以客戶資料表示範)/報表預覽視窗(以傳票示範)。全部以 DEMO 展示環境實機拍攝(去識別化資料)。PDF 重匯後 35 頁、無占位框。
- 轉單按鈕名稱修正(
docs/getting-started/index.md):資料操作工具列按鈕一覽表的「轉單-轉出」改為「轉單-轉入」,功能說明同步改為「開啟轉單作業,由上一站單據轉入資料產生目前單據」。與程式畫面實際圖示(轉單-轉入00.png)一致;程式內部權限鍵仍為「轉單-轉出」,不影響權限設定。
- 手冊網站字級下限 12pt(
docs/stylesheets/extra.css):Material 主題預設表格與提示框字級 0.64rem(約 9.6pt),拉齊到與內文相同的 0.8rem(16px ≈ 12pt)。全站生效(基本畫面介紹頁以表格為主,受益最大)。
- PDF 匯出字級下限 12pt:
-
tools/docs-pdf/manifests/basic-only.json加font_scale: 1.27——內文 10.5→13.3pt、表格 9.5→12.1pt,全書最小字級 ≥12pt(PyMuPDF 實測 12.1pt)。-
tools/docs-pdf/export-pdf.py版式 CSS 加td code { font-size: 1em }:表格內 code(按鈕名稱等)不再對已是最小字級的表格文字打折(原 0.92em 會做出 11.1pt 的字)。一併移除
tools/docs-pdf/manifests/basic-and-gl.json(基本+總帳合訂本,首發用)已不再使用,刪除;現行 manifest 為 basic-only / case-studies / system-overview 三本。
- 新增「瀏覽、清單瀏覽與列印畫面」頁(
-
08-11 date-doubleclick-calendar ▸
2026-08-11 日期欄位按兩下 → 右側行事曆跳到該日期
變動
- TsDateTextBoxV2(含格線編輯模式的 TsDateTextBoxV2InColumn):在日期文字框上按兩下滑鼠左鍵,主畫面最右邊的行事曆會自動開啟(若未開)並跳到該日期。
- TsGridViewDataDateColumn(Telerik 格線日期欄,全系統 400+ 處)與 TsDateColumnV2(舊 TsDataGrid 日期欄):瀏覽狀態按兩下日期儲存格,同樣跳到該日期。
行為細節
- 日期解析不出來(空值、遮罩未填滿、亂輸入年份 1900~2100 之外)→ 不動作。
- 民國年顯示格式(yyy/MM/dd)會自動 +1911 轉回西元再導航。
- 時間、單月、單年、發票期別等沒有「日」概念的遮罩不導航。
- 在 ContentWindow 等非主容器的視窗內按兩下 → 無反應(右側行事曆只存在於主容器)。
- 格線儲存格按兩下仍會照原行為進入編輯模式,行事曆跳轉是加掛的,不影響既有操作。
技術備註
- 共用入口
TsControl/Calendar/CalendarDateNavigator.cs;面板開啟與跳日期走MainWindowBtnCalendarViewModel.ShowDate()(刻意不走Show()/Refresh(),避免 force 重載目前月份與目標月份載入賽跑)。
- TsDateTextBoxV2 用
AddHandler(PreviewMouseDoubleClickEvent, …, handledEventsToo: true):基底 TsTextBox 在非唯讀時會把 double-click 事件設成 Handled(HyperLink 流程),一般MouseDoubleClick訂閱收不到。
-
08-11 browse-query-error-surfacing ▸
2026-08-11 瀏覽/清單瀏覽查詢失敗不再靜默+統計格線重複欄修復
變更內容
- 清單瀏覽統計格線重複欄修復(
TsControl/TsTelerik/TsBrowseRadGridView.cs、ViewModel/Control/TsBrowseDataGridViewModel.cs):查詢後下方統計格線(及主格線)可能出現同名兩欄、一欄有值一欄空白。成因:查詢前生成的「只有表頭沒 binding」占位欄在兩種路徑下沒被清掉——①ClearColumn一次性旗標第二次設 true 時 DP 值未變、清欄回呼不觸發;②視圖重建瞬間 DataContext 未接上又補生一批占位欄。修法:占位欄登記造冊、自動生成真欄時整批拆除兜底;VM 旗標通知 true 後回推 false 讓下次能再觸發。已在「查詢→返回→再進」重現路徑 runtime 驗證無重複。
- 清單瀏覽查詢失敗會提示了(
ViewModel/Browse/ErpPivotQueryViewModel.cs):查詢在 SQL 端整批失敗時(例如條件欄位與明細瀏覽檢視不相符),底層拿不到任何結果集、過去畫面完全沒反應(不彈窗、狀態列停留舊訊息)。現在會彈出「查詢沒有取得任何結果,可能是查詢條件欄位與明細瀏覽檢視(某某檢視)不相符」訊息,同步寫入狀態列與 DebugLog(含實際組出的查詢條件)。
- 查詢例外補彈窗(
ViewModel/Browse/BrowseControlViewModel.cs):瀏覽/清單瀏覽的查詢例外原本只寫狀態列與 DebugLog,現在同時彈出「查詢失敗:訊息」對話框。
技術備註(吞錯鏈路)
SQL 錯誤 →
SQLiteCreator.InsertOne對GetSchemaTable()==null靜默回 null →QueryAndStatistics回空清單 →ErpPivotQueryViewModel.Query空清單直接 return(連狀態列都不更新)。本次在最外層補提示,SQLiteCreator共用面廣(combobox 快取等)未動。已知關聯問題(另案處理)
- 訂單管理(ORMAST)清單瀏覽的條件欄位組(zcond
E06D,程式別註記為「出通單明細瀏覽」)與vwbd_ormast欄位不相符(單號 vs 訂單編號、交易日期 vs 受訂日期),且zcond_field.欄位type全空導致型別驗證失效——修法(改 zcond 資料 vs 改 view 別名)待裁決。
- 清單瀏覽統計格線重複欄修復(
-
08-10 weakevent-crossthread-failfast-fix ▸
修復:機率性整程式閃退(跨執行緒 PropertyChanged 撞 WPF WeakEvent 表)
- 日期:2026-08-10
- 影響範圍:全系統(所有表單/查詢畫面共用的資料物件基底)
使用者可見變化
- 修復「操作到一半整個程式無預警關閉」的機率性閃退。已知重現場景:
- 客戶報價單(E-04)載入資料時約 2/3 機率閃退(朝陽實測)。
- 客戶資料表(E-01)切「索引分類帳」分頁約 1/3 機率閃退回登入。
- 同一根因可能造成其他畫面偶發的無預警關閉,皆一併修復。
技術說明
WPF 的 WeakEventTable(
PropertyChangedEventManager)不是執行緒安全:任何在非 UI執行緒 raise 的
PropertyChanged/ErrorsChanged,只要畫面有 binding 監聽,就會與UI 執行緒併發存取同一張監聽表,機率性觸發
Environment.FailFast直接殺進程(事件檢視器堆疊:
set_幣別 → SourceBase.OnPropertyChanged → WeakEventManager+ListenerList.DeliverEvent → Environment.FailFast)。修法(框架級,非個別程式 hack):
- 新增
Common/Context/UiNotifyMarshal.cs:App 啟動時記下 UI 執行緒的
SynchronizationContext;ContextBasePoco.OnPropertyChanged、ValidViewModelBase.OnErrorsChanged、SourceBase的ErrorsChangedraise在非 UI 執行緒時改
Post回 UI 執行緒,同執行緒維持同步 raise 不變。- 用
Post(非同步)而非Send:UI 執行緒存在GetAwaiter().GetResult()
阻塞等待背景工作的呼叫點,
Send會死鎖。- headless 場景(AutoPilot/SchedulerWorker/測試)不安裝轉送器,行為完全不變。
對抗審查後的強化(同日第二輪)
Raise()單一入口:狀態一次快照(消除判斷與轉送間的 TOCTOU);posted handler 包
try/catch+DebugLog(例外不再變成 Dispatcher 未處理例外彈窗)。
- 補覆蓋自行實作 INotifyPropertyChanged 的高風險類:
NotificationService(IsBusy 常被
背景設定)、
CudataStatistics、ViewModelStatus/SearchWindowViewModelStatus。- 偵測性紀錄:非 UI 執行緒的 raise(前 10 次含堆疊)與
ListenerHelper監聽註冊落在
非 UI 執行緒時,寫入
C:\temps\debuglog\——用來在實機上指認殘餘的背景執行緒來源。驗證
LogicBllTests/Harness/UiNotifyMarshalTests.cs六條單元測試(未安裝直接 raise/同執行緒
同步/跨執行緒走 Post/SourceBase 屬性+NeedDelete 連鎖順序/ErrorsChanged 轉送/
handler 例外不上拋)+既有 HarnessSmokeTests 全過(13/13)。
- 朝陽模擬庫 runtime:CUPDMA 兩批共 32 輪導覽載入零閃退(原 bug 每次載入約 2/3 機率)、
幣別/匯率/明細欄位顯示正常;禾久模擬庫 CUDATA 切「索引分類帳」分頁 15 輪零閃退
(原約 1/3 機率)。
- 誠實註記:本日 runtime 各輪的偵測紀錄均未觸發(=當日操作未重現背景執行緒競態;
機率性 bug 的觸發依賴時機與資料)。修法在單元測試層證實正確攔截跨執行緒 raise;
若實機再出現同族閃退,debuglog 會留下來源堆疊供追查。
已知未涵蓋(記錄於 memory)
- WeakEvent「監聽註冊」路徑(
ListenerHelper)與 ObservableCollection 集合變動未 marshal,
目前僅偵測紀錄;另有約 40 個自行實作 INotifyPropertyChanged 的小型類未導向轉送器。
Bom_costBll的Parallel.ForEach若對已綁定畫面的 Source 批次設值,可能灌爆
Dispatcher 佇列(有 handler 才會發生),待實測。
-
08-10 test-control-panel ▸
2026-08-10 測試控制面板(Testing 選單)
變動
主畫面 Testing 選單(僅管理者可見)新增「測試控制面板」:對目前開啟的單據程式做半自動 runtime 測試。
- 掃描欄位:列出目前程式畫面的輸入欄位(TextBox 家族、代號下拉、一般下拉),唯讀/停用欄位預設略過;自動產生測試值(字串=「測試」+時間戳、數值=小亂數、日期=今天,皆尊重 MaxLength),執行前可逐欄修改。
- 模擬輸入:逐欄聚焦→填值→更新 binding→延遲(間隔可調,預設 300ms),看得到像使用者逐格打字的過程;填值後檢查 binding 驗證錯誤,不假報成功。
- 獨立按鈕:新增/模擬輸入/存檔/修改/刪除,每步以可觀測狀態(編輯模式、Pkid)回報真實成敗。
- 完整循環:一鍵「新增→填值→存檔→修改→改 3 個字串欄→存檔→刪除」,只動自己建的那筆;每步狀態閘不符即中止並提示手動清場,刪除前重驗目標程式未被切走、刪除後以正向導覽驗證該筆確實消失。
- 存檔/刪除若彈確認視窗,由操作者手動按(設計內行為,工具不代按)。
注意
- 入口在
ERPSystemContainerViewTesting 選單,權限沿用既有TestVisibility(admin)。
- 下拉欄位自動挑第一個有效選項;業務上不合法的組合仍需人工改值後再存。
- 焦點連動(LostFocus 帶簡稱等)於非作用中視窗的行為尚未實測,填值迴圈前會先啟動主視窗並於 log 註明。
-
08-10 speva-vendor-evaluation-port ▸
2026-08-10 新程式:廠商評鑑表 SPEVA(G-05,朝陽)
摘要
朝陽獨有的 VFP 廠商評鑑表整支移植到 V2(ADR 0127)。原本點選 G-05 會「程式鍵無法解析」,現為完整可用的表單程式。
功能
- 主檔:年度月份(9999/99,必填、不可重複);明細:每廠商一列 26 欄(分項評分、分類加總、總分、交貨/延納件數、延納率、評鑑結果等)。
- 分項評分上限即時驗證(品質1≤10、品質2≤25、品質3≤10、交期1~3≤10、交期4≤5、協調性1≤3、協調性2≤2、協調性3≤5),輸入即重算分類和與總分;交貨/延納件數輸入即重算延納率。
- 新增模式「查詢」鈕=產生評鑑資料:讀
C:\轉EDI資料\廠商評鑑表.DBF(缺檔顯示「請先轉廠商延納資料 !!!」)與廠商品質表.DBF(缺檔視同無扣分),對 spdata 廠商類別 1~9 每廠商一列帶預設配分,套交貨/延納件數、品質與成績表扣分、延納率回扣交期1。
- 存檔:年度月份必填;全明細重算總分;廠商代號空或交貨件數=0 的列自動剔除(皆 VFP 原規則)。
朝陽模擬庫實測(e2e)
開窗、載入 2026/03 歷史資料(廠商簡稱 lookup 正常)、查詢鈕缺檔擋下、以測試 DBF 產生→存檔→重載→刪除全流程驗證:001 測試廠商 品質1=8.5(10−扣1.5)、成績表=4.5、交期1=8(10−延納率20%×0.1)、總分=96 與手算一致;剔除規則正確(僅交貨>0 的 2 列入庫);刪除後資料庫回到基線。實測中抓到並修復「產生明細 linkid=0 孤兒」(SaveBll 自接 linkid,PerdataSave 同款)。
未包含
- 「更新帳款」鈕與 SPEVA_1 表單(VFP 端 2018 年起即停用之 dead code,不移植)。
- ~~報表 SPEVA_P~~ → 2026-08-10 同日補完(兩張 FastReport,走 IPrintViewModel 專屬列印頁+
code-defined 報表清單,不建 _rptdat;詳
2026-08-10-speva-reports.md)。- ~~終端使用者手冊頁~~ → 2026-08-10 同日補完(
docs/G-Purchasing/speva.md)。
- VFP 端另有 speva1a/speva2/speva3.frx 三張報表未移植(不在本次範圍)。
-
08-10 speva-reports ▸
新增:廠商評鑑表兩張報表(SPEVA_P 移植)
- 日期:2026-08-10
- 影響範圍:朝陽 廠商評鑑表(G-05);接續同日
2026-08-10-speva-vendor-evaluation-port.md
使用者可見變化
- 廠商評鑑表新增列印功能:點列印圖示進入專屬列印頁,兩張報表可選(預覽/列印/匯出):
1. 朝陽協力廠商評核成績通知(G050-1)——一廠商一頁,含近三個月分數、獎懲方式全文、
等級說明表;發給協力廠商的通知單。印本月分數前必須先存檔(三個月一律回 DB 讀)。
2. 年月份廠商評核統計表(G050-2)——全廠商統計清單,含每列部品標示、表尾合計與簽核欄;
取畫面明細(未存檔也可印)。
技術說明
- VFP
speva.frx/speva1.frx(DBF 格式)→ FastReport.frxXML×2+報表 POCO×2(中文屬性,
與 frx 欄位名逐一對齊)+
SpevaReportBll(資料組裝;合計欄 C# 端預算,規避 FastReport2026.1.6
Sum()CS0103)+plugin×2+SpevaReportPrintViewModel/SpevaPrint.xaml。- 報表清單走 code-defined
GetReports(),不建_rptdat(使用者裁決;全系統除 PAYMNTPQ
外皆走 code 路線,兩邊同時登錄會在列印面板重複)→ 正式機部署=發版+複製兩個 .frx 到
C:\dglibrary\REPORTSROOT\Reports\,零 DB 部署。通知單.部品來源=spdata.廠商類別去前綴;產生對象=廠商類別 1~8。
Runtime 驗證中抓到並修復的缺陷(朝陽模擬實測)
1. 預覽 no such table:初版把報表掛在
IPrintSource而未實作IPrintViewModel→列印圖示 fallback 進瀏覽面板,
IsBrowseQuery=true只建帶_1/_2後綴的表、plugin 分支不執行。修=改走
IPrintViewModel+SpevaReportPrintViewModel(同 BOR/FILLRATE 慣例)。UX 註記:列印圖示現在進專屬列印頁,不是瀏覽面板。
2. 通知單每廠商多 2 頁空白:band 垂直(1072>1062)與水平(760>733.2)雙軸溢出
A4 可印範圍,各多印 1 頁。修=邊距 8→5mm+band 寬 750+內容垂直壓 88px;
修正後 52 頁(原 155)。統計表同類水平溢出一併修。
3. 列印頁顯示 raw 類名:漏註冊 print VM 的 DataTemplate。修=
SpevaPrint.xaml+App.xaml DataTemplate。
驗證
- 建置 0 error+HarnessSmokeTests 全過;frx↔POCO 欄位三方比對 26/26+23/23。
- 朝陽模擬 runtime:通知單預覽 52 頁版面正確(001/003/007 連續、無空白頁);
統計表 2 頁(分組列示、合計 1,977、簽核欄);列印頁乾淨無類名。
未包含/已知事項
- VFP 端
speva1a/speva2/speva3.frx三張未移植(不在本次範圍)。
TsERP.G.Purchasing.G.Purchasingnamespace 重複為 8/10 移植時既有,牽動 App.xaml
三處綁定,另案 rename。
- 實體印表機輸出未測(僅預覽)。
-
08-10 fillrate-ui-and-linkid-fix ▸
2026-08-10 達成率(FILLRATE)介面調整與存檔明細消失修復
變動
- 類別改為下拉選單:原本唯讀文字框+「C:客戶,S:廠商」提示文字,改為 TsComboBox 下拉(C:客戶/S:廠商),選項值仍落庫單一字元。
- 移除「輸入日期」欄位:主檔區不再顯示輸入日期(系統欄位,仍照常落庫)。
- 新增時自動帶本月:按新增後「年度月份」自動填當前年月(原本要手動輸入)。
- 明細日期欄寬:固定 90。
Bug 修復:存檔後明細整批消失
計算鈕產生的明細列走
DetailData.AddItem不經 AddBll,linkid 一直是 0(孤兒明細),存檔後重新載入時 master 掛不到任何明細,看起來就是「明細被清空」。
修法照 PerdataSave / ZcondSave / SpevaSave 同款:
FillrateSave.HandleDataBeforeEndEdit存檔當下統一把全部明細的 linkid 接上 master pkid(
LogicBll/Ade/E.Order/FillrateSave.cs)。驗證
- MSBuild TsERP.csproj 0 error;HarnessSmokeTests 7/7 通過。
- runtime 未驗(開窗操作、存檔重載明細留存待實測)。
-
08-10 cudata-four-tabs-and-browse-thousand-sep ▸
2026-08-10 客戶資料表四個新分頁+瀏覽查詢數字千分位
客戶資料表(CUDATA)新增四個分頁
在既有「客戶報價/訂單/出貨」之後新增四個瀏覽分頁,切入自動以當前客戶查詢,
單號可點跳轉原程式:
分頁 來源程式 條件欄位 產品序號表 INVENT1 購買日期、品號、客戶代號 客反應主檔 REPAIR 叫修日期、品號、客戶代號 拜訪單 VISIT 拜訪日期、受訪代號 抱怨單 CMPLAIN 日期、客戶代號 - 日期預設全部(不限近三個月,使用者裁決)。
- 權限照既有分頁慣例:無對應程式的瀏覽權限,分頁不出現。
- 編輯狀態中分頁鎖定,與訂單/出貨分頁行為一致。
DB 佈署:
sql/cudata-four-tabs-browse-20260810.sql(vwbd_invent1/vwbd_repair/vwbd_visit三 view + DARB_BD_INVENT1/REPAIR/VISIT 三 SP;DARB_BD_CMPLAIN 既存)。
模擬庫 darbnogicsa1 已跑並實查驗訖;正式機未跑。語法需 SQL2016 SP1+。
2026-08-12 補:`twork_sys_viewlist` 登錄(缺這一步四個分頁查詢永遠空白)
查詢實際走
DARB_LOG_SYS_EXEC → TWORK_BD_VIEWLIST(@Language,@ViewNo,@Condition,@GroupBy),而
TWORK_BD_VIEWLIST是用 @ViewNo 去twork_sys_viewlist查出要執行的 SP。四個新分頁的 ViewNo(
DARB_BD_INVENT1/REPAIR/VISIT/CMPLAIN)當初沒登錄,查表落空 →
@Procedure為 NULL → 組出 NULL 動態 SQL → 不報錯、回 0 rows 0 columns,畫面上就是四個分頁查了永遠空白且沒有任何錯誤訊息(08-10 當時只單獨測 SP,測不到這一層)。
補上
sql/cudata-four-tabs-viewlist-register-20260812.sql(四筆登錄,可重複執行)。模擬庫 darbnogicsa1 已跑並以
TWORK_BD_VIEWLIST實測:登錄前四支全 0 rows 0 cols、登錄後 CMPLAIN 16/INVENT1 4/REPAIR 3978/VISIT 27938 筆。正式機兩支腳本都還沒跑。
瀏覽查詢 grid 數字千分位
所有走
TsBrowseRadGridView的瀏覽/查詢畫面(InventQuery 系列、Trwkma、客戶資料各瀏覽分頁等),數字欄位補上千分位格式:整數 N0、小數依 DB scale(查不到比照 N2),對齊維護程式
TsGridViewDataNumericColumn 的既有規範(
TsControl/TsTelerik/TsRadGridHelper.cs)。已知邊緣:純代號型數字欄(公司代碼等)也會套千分位;先全上,實測礙眼再加排除清單。
-
08-10 bomflow-print-and-tabs ▸
BOM 流程分析:新增列印功能+分頁調整
日期:2026-08-10
模組:D. BOM(BOM 流程分析,D-11)
新增
- 流程圖列印(FastReport):主工具列的列印功能啟用,印出「產品流程圖」A3 橫式報表——20 欄流程矩陣、製程站別加方框標示,版面對齊 VFP 舊版(bomf22)。頁首帶公司名稱、查詢品號/品名與頁碼。
- 本次僅提供 A3 單張版;舊版的 A4 三段式與圖片式報表未移植,如有需要另行提出。
- 流程超過 20 欄的部分不列印(與舊版行為相同),過深的 BOM 建議改用圖形分頁匯出。
- 圖形分頁列印/匯出:「流程圖圖形」與「材料流向圖」分頁工具列各新增兩鈕:
- 「列印圖形」:整張圖自動縮放至單頁列印(大型 BOM 也能完整印出)。
- 「匯出圖檔」:將整張圖(不受目前縮放/平移影響)存成 PNG 圖檔,預設檔名帶查詢組件號。
變更
- 「製程明細表」分頁隱藏(資料與樹狀分頁相同,減少重複);開窗預設落在樹狀分頁。
- 樹狀分頁名稱由「製程明細(樹狀)」改為「製程明細」。
部署備註
- 報表範本
Bomflow1.frx需存在於C:\dglibrary\REPORTSROOT\Reports\(開發機已佈署;客戶端隨報表佈署程序發佈)。
-
08-10 bom-cy-proctool-variant ▸
新增:朝陽 BOM 表治具子表(BOM_CY 變體)
- 日期:2026-08-10
- 影響範圍:朝陽 BOM 表(D-04);禾久/其他客戶不受影響
使用者可見變化
- 朝陽開「BOM表」不再跳「SQL 有本地 ViewModel 沒有」檢查警告窗。
- 表單新增第三個明細區「治具」(製程表下方):途程序號/序號/治具品號/自訂欄位1/自訂欄位2,
顯示該 BOM 版本(依 linkid 歸屬)的治具清單——治具資料首次進入 V2 畫面。
- 禾久 BOM 表版面與行為完全不變(母版零改動)。
技術說明
兩庫
_sheetno的 BOM 子表3 本就不同表:禾久=secsou(替換來源)、朝陽=proctool(治具)。V2 只實作 secsou,朝陽 SP 回傳治具結果集對不到本地表 → 警告+資料丟棄。
照客戶變體機制(ADR 0123/0125)新增 BOM_CY:
ProctoolModel/ProctoolSource(無 view 直讀表)、LocalDbContext.DbSet Proctool(屬性名=server 表名)、Router 三表(CompanyOverrides/VariantGroups/VariantStagingAlias)、
Bom_cyViewModel : BomViewModel(加註冊 proctool manager)、Bom_cySave : BomSave(治具列 stamp 組件編號+治具品號空白標刪,照 VFP)、Bom_cy.xaml+DataTemplate+Lang/Xaml/Bom_cy.json。驗證
- 建置 0 error;HarnessSmokeTests 7/7;ProgramClassRouterTests 46/46(含新增 6 條)。
- 朝陽模擬 runtime:選單開 BOM=變體、零警告窗;ZYZ008*05G 治具 2 筆與 DB linkid 過濾完全一致;
seek HJA-0101*00G 治具 22 筆組(含自訂欄位值)顯示正常。
- 禾久模擬 runtime:BOM 開母版(無治具區)、載入正常、零彈窗=無回歸。
- 治具的新增/修改/刪除存檔動作未實測(僅驗載入與顯示;Save 邏輯照母版模式靜態核對過)。
存檔實測與修復(同日第二輪,朝陽模擬 e2e)
存檔實測抓到並修復四個缺陷(全部 runtime 驗證):
1. CheckSqlField 診斷器位置誤報:進「修改」把第 i 個結果集對第 i 個 manager,
變體多掛 manager 即錯位誤報。修=
GetClassType改「server 表名對 EF 實體表名優先(含 staging 衍生類 base 走訪)、位置 fallback」(
TsControl/CheckSqlField.cs)。2. 治具 grid 缺
DataManager綁定:右鍵「新增數筆」NRE。修=Bom_cy.xaml補DataManager="{Binding Detail3Data}"。(母版 BOM 的 bom_d/proces grid 也未綁=母版加列功能既有缺口,未在本次範圍。)
3. 朝陽存檔被生產轉入倉必填擋死:CY bom_m 無此欄。修=
BomSave.AllowSave加TableHasColumngate(照 OrmastSave 慣例,非公司分支;禾久必填行為不變)。4. 治具存檔 XML 被靜默丟棄(最關鍵):
AdeUploadBll.Upload以「位置」把_tablesName[i]配GetXmls()[i];變體原本保留 secsou(第 4 manager)再加 proctool(第 5)→ proctool 的 XML 配到空表名直接丟棄。修=母版
BomViewModel抽RegisterDetail3()虛擬掛勾(公版=secsou)、BomSave抽HandleDetail3()掛勾,BOM_CY 覆寫改註冊/處理 proctool——變體不再註冊 secsou,proctool 落第 4 位對齊表序
(ADR 0125 virtual 掛勾模式)。
驗證:smoke+Router+UiNotifyMarshal 測試 59/59;朝陽 e2e=治具列右鍵新增→填值→存檔
→DB 實查寫入(含稽核欄)→清空治具品號→存檔→DB 實查刪除、編輯鎖正常釋放(zpermit 0);
禾久回歸=開窗/載入/進編輯(secsou 路徑)/取消零錯誤。附帶修:測試中發現殺進程會留
zpermit 殘留鎖(測試環境自清,非產品缺陷)。
治具顯示比 VFP 少(同日第三輪,使用者回報)
- 症狀:同一組件 VFP 治具列比 V2 多(例:ZYZ008*05G VFP 5 筆、V2 只 2 筆)。
- 根因:朝陽
_sheetno的 BOM 列「關聯欄位」為空 →TWORK_MOVEREC走 linkid 分支撈子表;
proctool 有 5,553 筆 VFP 時代孤兒 linkid(設變改版後原 bom_m pkid 已刪)被過濾掉。
VFP 治具按 組件編號 撈(無 linkid 概念);禾久同列本來就設
關聯欄位=組件編號。- 修法:
sql/bom-sheetno-relation-key-cy-20260810.sql把朝陽補成組件編號。影響面實查:
bom_m 組件編號零重複、bom_d/proces 零孤兒 → 對 bom_d/proces 載入完全不變,
只讓治具歷史列重新顯示(=VFP 行為)。
- 驗證:模擬庫已跑+實查;SP 重執行治具 2→5 筆;畫面實測 5 筆全顯示。正式機待跑。
-
08-09 scx-ord-pur-union-cy ▸
2026-08-09 E.訂單/G.採購 兩庫聯集同步+朝陽全程式實測
延續同日 D.工程資料的做法(見
2026-08-09-scx-eng-union-cy.md),對 E(SCX_ORD)與 G(SCX_PUR)做禾久∪朝陽欄位聯集與朝陽模擬庫逐支實測。變更
- E.Order:零程式碼變更——12 個有表單據別重新逐欄比對後,先前訂單治理(ADR 0113、CUDATA/CUQT 專項比對)已完整涵蓋兩庫聯集,無缺口。
- G.Purchasing 聯集補欄(8 檔):spdata(採購備註/折讓單+view-only 代工廠商號)、sppdtm(流程樣板號+view-only 其他加成)、sppdtd(代工廠商號+view-only 代工廠商/關稅等費用/含關稅單價)、purch(初品單號/初品變更/初物合格日)。PPURCH/purchm 已齊未動。
- LocalDbContext:補
Sppdtm/SppdtdDbSet(G-02 廠商報價單載入崩真因)+兩 Source 無參建構子+ 8 個*Binding包裝屬性補[NotMapped](smoke ratchet 攔到的 materialize 洗資料雷)。
朝陽實測結果(18 支)
- ✅ 開窗全過、零載入崩潰:E 全部 12 支(選單無 PI)+ G-01/03/04(載入實資料目視驗證:ORMAST、CUPDMA、PACKING LIST、SPDATA、PPURCH、PURCH)。
- 🔴 E-04 客戶報價單機率性閃退(複測 3 次中 2 次):
Twork_ord_vw_cupdmaSource.set_幣別→SourceBase.OnPropertyChanged→ WPFWeakEventManager.DeliverEvent→Environment.FailFast。既有框架級執行緒問題(與「CUDATA 切分頁 1/3 閃退」疑同根因),非本輪改動造成,待專案修復。
- 🟡 G-02 廠商報價單:崩潰已修,但載入任一筆後表單維持空白且無錯誤訊息,待查(嫌疑與 sppdt 衍生欄 材料單價 回填邏輯或 CY 缺欄有關)。
- 🟡 G-05 廠商評鑑表(SPEVA):朝陽獨有程式(speva_m/speva_d 只在朝陽庫),V2 無實作 →「程式鍵無法解析」,待裁決(實作或自朝陽選單下架,同 INVGRPM 先例)。
- 🟡 反向差異(XAML 綁定有、朝陽 DB 沒有 → 欄位空白+存檔風險):CUPDMA 中文描述/規格/客戶價、SALEMA 其他金額、PK 不足箱/後置文字/包裝量_箱、SPPDT 廠牌、PPURCH 7 欄、PURCH 6 欄。
Migration
程式端無需手動 migration(SQLite staging 自動跟上)。朝陽正式機部署清單不變(INVGRPM SQL 見 D 模組 changelog)。
明細:
.claude/tmp/scx-ord-union-apply-report.md、.claude/tmp/scx-pur-union-apply-report.md、.claude/tmp/scx-ord-pur-union-columns-20260809.txt。 -
08-09 scx-eng-union-cy ▸
2026-08-09 D.工程資料(SCX_ENG)兩庫聯集同步+朝陽端修復
摘要
朝陽(darbcycsa1)實測 D.工程資料全模組後,依「兩庫聯集」裁決把 Model/Source 欄位補齊到禾久 ∪ 朝陽聯集,並修復三類問題:
1. 載入即炸:朝陽 DB 有、本地 Model 沒有的欄位,會在載入資料塞本地 SQLite staging 時炸(實測 D-01 庫存主檔
invent.委外材料費、D-04 BOM表bom_m.類別)。2. DbSet 漏註冊:
Twork_bom_vw_moldmnoSource/moldctrlSource/prochistSource未註冊 LocalDbContext,D-08 模具資料表載入即崩(D-03 工程代號表為潛在同類)。3. D-05 產品分群碼(INVGRPM):V2 無對應 ViewModel,點選即「無法建立ViewModel」且錯誤框擋死視窗 → 朝陽選單先下架。
變更
- Model 補欄(base table 聯集):
Twork_bom_vw_bom_mModel(類別)、Twork_bom_vw_procesModel(改善前工時/改善後工時/備料工時)、Twork_bom_vw_inventModel(14 欄,含委外材料費/委外加工費/hf/送樣目的/送樣區分/合格日期/預導入日/延遲原因/初品管制/模具圖號/客供品備註等)、Twork_bom_vw_moldModel(已歸還/管制比率)。
- Source 補欄(view 聯集):bom_m、bom_d、proces、invent、mold 五支 Source 加委派屬性;view-only JOIN 欄(invent 的 廠商代號/廠商簡稱/市購品/現有數量 等)以私有欄位承接、不進 Model(照 ADR 0050 慣例)。
- LocalDbContext:D.BOM 區補
Moldmno/Moldctrl/Prochist三個 DbSet;三個 Source 類補無參建構子。
- DB(朝陽):
sql/invgrpm-menu-remove-cy-20260809.sql自_menum移除 INVGRPM(模擬庫已執行;朝陽正式機待跑,檔內含還原 INSERT)。
- itemspec/moldmno/moldctrl/procno/procno1/prochist/wkcent 比對後聯集已齊、未改動。
不在本輪範圍(待裁決)
- BOM 子表3 兩庫綁不同表(禾久
secsou替換來源/朝陽proctool治具)=客戶變體議題,未動。
- 命名漂移欄位並存未合併(hsf/hf、英文品名/英文描述、模具編號/模具圖號)。
- procno1「檢查基準」兩庫長度不一(NOGI 60/CY 90),暫維持 60。
Migration
- 程式端無需手動 migration:本機 SQLite staging 由 EnsureCreated/LocalDbService 補欄機制自動跟上。
- 朝陽正式機部署時需跑
sql/invgrpm-menu-remove-cy-20260809.sql(sqlcmd 加-f 65001,跑完實查 SELECT 應 0 筆)。
比對明細:
.claude/tmp/dbmodel-compare-scx-eng-cy-report.md(差異盤點)、.claude/tmp/scx-eng-union-apply-report.md(套用明細)、.claude/tmp/scx-eng-union-columns-20260809.txt(兩庫欄位原始資料)。 - Model 補欄(base table 聯集):
-
08-07 visit-fillrate-gap-fixes ▸
2026-08-07 拜訪單查詢窗接通+達成率行為補齊(含件數恆 0 根因修復)
使用者可見變動
拜訪單(E-20)
- 查詢窗四個分頁(日報/週報/里程/客戶)正式可用:查詢視窗原本從未接上 ViewModel,開出來四個分頁全空;已接通。
- 查詢鈕入口需 DB 補按鈕文字才會出現:執行
sql/visit-query-button-caption-20260807.sql(補 prgsct1.其他1說明=「查詢」,同 VFP 原版)。
- 新增拜訪單時自動帶入業務員編號(以登入者姓名查業務員檔,同 VFP)。
- 查詢功能掛「可否其他1」權限檢查(同 VFP;現行全使用者皆有權限)。
達成率(E-19)
- 計算件數恆 0 的根因修復:客戶達成率計算的資料對映(英文屬性 vs SP 中文欄名)自移植起全數落空,計算結果永遠是 0;已補
[TsColumnName]對映(DARB_QRY_ORMAST 查詢別 7 兩結果集)。
- 明細新增「星期」唯讀欄(由日期推算;「週末且 0 件自動剔除」的存檔規則從此看得見依據)。
- 表頭新增「修改資料保留日期」:修改模式重算時,保留日期(含)以前的件數與已填原因沿用舊值,不再被重算洗掉(同 VFP 2022/02/11 行為)。
- 計算鈕連按不再使明細列翻倍(改「不足才補列」,新增與修改模式一致)。
- 計算前檢查類別必填;公司代碼依 2026-08-07 裁決不上畫面,內部自動帶值、存檔不因此擋單。
- 複製單據時單號同樣自動重組(原僅新增會重組)。
驗證
- 建置 0 error(Model/LogicBll/ViewModel/TsERP);HarnessSmokeTests 7/7。
- 實機(darbnogicsa1、CMSA):達成率末筆載入——星期欄正確、保留日期欄在位、歷史明細正常;拜訪單表單與自動帶入路徑建置後開窗正常。
- 未驗:計算鈕端到端(需修改模式實按;POCO 對映已與 SP 定義逐欄核對);查詢窗四分頁實查(待 prgsct1 SQL 執行後入口才會出現);禾久以外公司別的業務員帶入分支。
拜訪查詢窗開窗鏈修復(同日第二波,實機逐層揪出)
點「查詢」後實測連環爆三層、逐層修復,最終改走標準模態:
1.
WindowName.salesOrder前綴寫TsERP.E.SalesOrder.,實際命名空間是TsERP.E.Order.(10 個視窗逐一驗證)→ 修常數;受影響同族:Ci_m1(CI 帶入出貨單挑單)、Odtosl(訂單轉出貨)、Sample1、Ormast_s、OrderDuplicate、OrderApprove、PreordPivotInput 等——這些彈窗自框架遷移起就開不了。2.
WindowHelper.OpenWindow將實例硬轉System.Windows.Window,但 TsWindow 繼承 Telerik RadWindow → InvalidCastException;補 RadWindow 分支+owner null-safe+LastOpenedInstance屬性(PreordViewModel 讀 DataContext 改走它)。3. RadWindow 路徑開出來整窗黑屏(無視覺樹)→ 依 repo 標準(window-to-tsview skill:WindowHelper.OpenWindow 已廢棄)將 Visit_q 轉為 TsView+
ERPProgramContentWindowViewModel+ContentWindowService.ShowContentWindow,新增 ProgramClass.VISIT_Q 與 App.xaml DataTemplate。實機驗證:拜訪查詢窗開啟成功——四分頁(日報/週報/里程/客戶)、條件欄、Query/離開鈕、格線完整渲染;主表單關窗後 Renew 載入真資料(N0000001)。日報 Query 以 CMSA 查回 0 筆,高度疑為查詢 VM 的「主管」權限閘(非主管只看自己的業務員編號,CMSA 非業務員)——需業務員帳號實測,列未驗。
遺留同族債:Ci_m1/Odtosl/Sample1/Ormast_s/OrderDuplicate/OrderApprove/PreordPivotInput 仍走廢棄 WindowHelper+TsWindow(現況:名稱已修可解析、RadWindow 分支可開但黑屏風險同 Visit_q)——應逐支照 window-to-tsview skill 轉 ContentWindow,另案排程。
達成率報表上線(同日第三波)——達成率 % 首次可見
- 新增「業務部客戶交貨達成統計表」(Fillrate1.frx,E190-1):印當前單據——逐日件數+星期+原因、
每週小計列(Σ訂單件數)、TOTAL 列印出達成率 %((訂單件數−未達成件數)×100÷訂單件數,同 VFP)。
- 入口:達成率程式 → 印表機鈕 → 程式列印頁(預覽/列印/Excel)。
- 管線:
Fillrate1.frx(reporepos\FastReport\+已部署 REPORTSROOT)+Rpt_E190_FillrateReportPoco
+plugin
Fillrate1+FillrateReportPrintViewModel(IPrintSource;FillrateViewModel 掛 IPrintViewModel)+ProgramClass.FILLRATE_P+FillratePrint 檢視。
- 實機驗證:真資料(1C2026/06)預覽整頁渲染——週小計 999/806/797/839/354、TOTAL 3,795 件・未達成 4・99.89%、簽核欄齊。
- 附註:print VM 類名取 FillrateReportPrintViewModel(避開 G/F 既有 FillRatePrintViewModel 大小寫撞名);
瀏覽列印路(瀏覽勾選→列印)本報表不支援(資料需計算欄,瀏覽複製路徑產不出 %),照程式列印入口使用。
8 彈窗批次轉 ContentWindow(同日第四波)
Ci_m1(CI 帶入出貨單挑單)、Odtosl(訂單轉出貨)、Odtosladdi、Sample1、Ormast_s、OrderDuplicate(訂單複製,
順修 Parameter 恆 null 舊 bug)、OrderApprove、PreordPivotInput(預示樞紐輸入)自廢棄 WindowHelper 路轉
ContentWindowService 標準模態——這些彈窗自框架遷移起即開不了。建置 0 error、smoke 7/7;
runtime 僅 Visit_q 同模式實機驗證通過,8 支逐一實測待辦(含 Ci_m1 Return 帶回、OrderDuplicate 批次不關窗行為)。
待部署
sql/visit-query-button-caption-20260807.sql(模擬庫與正式庫各跑一次,冪等)。
C:\dglibrary\REPORTSROOT\Reports\Fillrate1.frx(本機已放;其他機器照 frx 部署慣例複製)。
-
08-07 manual-gap-fill ▸
2026-08-07 使用手冊缺口補齊(16 項)
新增頁面(9 頁)
- M 主管資訊:經營儀表板(EISDASH)、行動儀表板、營運預測模擬(OPERATIONFORECAST)
- N 總帳:總帳儀表板(GLDASH)
- E 營業收款:業務儀表板/業務課報告表產生(SALESDASH)
- A 系統:單據匯出/匯入(tsdoc.json 交換檔)、介面語言切換
- G 採購付款:採購未納明細通知
- H 庫存:安全庫存檢查通知
改寫過時內容(5 頁)
- 生產計劃查詢:改為 2026-06-25 拆分後的四分頁現況,加「產能負荷/庫存缺口/模擬插單已移至營運預測模擬」導引
- 階層式製程表(bom_hier):由「與流程圖製程表併版」改寫為獨立程式現況
- 流程圖製程表(Bom_flow):頁籤清單與查詢條件更新至現況
- 查詢條件運算子:改為 ADR 0091 型別自動過濾的現行行為,補各型別可用運算子對照表
- 警示規則維護:警示類型由「四種」修正並擴充為 11 種(含第二批:呆滯庫存、客戶退票、採購逾期未交、委外派工逾期、排程健康、郵件佇列堆積)
既有頁補節(2 頁)
- 客戶資料表:補「查工商登記」與「索引分類帳分頁」兩節
- 廠商基本資料:補「查工商登記」節
各模組 index 清單與左側導覽已同步更新。新頁所需截圖已在各頁列出待補清單。
-
08-07 casebook-v2 ▸
2026-08-07 案例書 v2:內文加厚、實機圖換裝、岩月世界觀
- 22 篇全數加厚(約 1.7~2 倍):每篇新增「導入前情境」「實際跑一遍」(編號操作步驟)與「效益量化」段落。
- 每篇加上「更新日期」與「重要度」:見各篇開頭的資訊列;日期取自對應功能最近一次的修改紀錄。
- 本公司範例名改為「岩月」(原「達備實業」全數更換),客戶/廠商維持虛構名。
- 5 張示意圖換成實機截圖:經營儀表板、金流預測、總帳儀表板、業務課報告表、單據匯出選單;圖說標示已同步改為「實機截圖」。
- 依實機行為修正多處敘述:金流預測改為兩個分頁、產能負荷等分頁歸屬改為營運預測模擬、總帳儀表板期間為本年度視角、業務課報告表以「報告月份」欄指定月份、模擬插單重算範圍為缺口與資金。
- 案例書 PDF 重新匯出(約 120 頁)。
-
08-07 alertrule-types-and-hints ▸
2026-08-07 警示類型下拉補齊與提示字串修正
- 警示規則維護:警示類型下拉由 4 種補齊為 11 種(首批五種+第二批六種:呆滯庫存、客戶退票、採購逾期未交、委外派工逾期、排程健康、郵件佇列堆積),與警示 SP 部署清單一致。
- 生產計劃查詢:條件面板「步驟③」提示仍列已移走的「原物料用量」分頁,改為現行四分頁並指引負荷/缺口/模擬至「營運預測模擬」。
-
08-06 ttvma-latest-sheet ▸
業務課報告表:TTVMA 汽機車資料改抓目標月份(原本一直是 2002 年最舊那期)
日期:2026-08-06
影響範圍:業務儀表板(SALESDash)業務課報告表產生(檢核模式與範本模式)、AutoPilot 排程版
現象
匯出的業務課報告表裡,TTVMA 汽機車公會的市場資料(原始頁、市佔率、解析結果)一直是最舊的資料(2002 年 8 月),不是最新公布的月份。
原因
公會下載檔是「一個月一張工作表、舊在前」的整包歷史檔(實測 287 張,民國 91 年 8 月排到 115 年 6 月),程式取第一張工作表(
Worksheets[0])=最舊的 2002-08。順藤摸瓜另修兩個解析錯誤(新舊版面皆會踩到):
- 汽車表:表頭本身有縱向「合計」欄,找「合計列」會先咬到表頭,內銷讀到空值、外銷讀到去年同期內銷。
- 機車表:真實版面是單一廠牌欄組+「本期小計」列,原程式假設的「當月/累計並排雙欄組」從未存在——當月解析失敗、累計永遠沒有資料。
修正後行為
- 依報告目標月份挑對應工作表(表名「{民國年}{中文月}份」);目標月尚未公布(公會每月 10~18 日才出上月數據)時自動退最近一期,並在警告區註明採用期別。
- 汽車/機車當月台數照正確的小計列解析;山葉的鍵名統一為「台灣山葉」(表頭儲存格只寫「山葉」,不統一會讓市佔率/趨勢圖整欄變 0)。
- 機車「累計」改為同年 1 月~採用月逐月加總(公會檔沒有現成累計表);缺月會警告並跳過。
- 範本模式的趨勢圖改填「資料真正所屬的月欄」(例:8 月產報告採 6 月數據就填 6 月欄,不再把 6 月數字寫進 8 月欄)。
驗證
- 單元測試:表名解析、挑表情境(命中/退期/退檔尾)。
- 真檔測試:對 2026-08-05 下載的原始檔跑挑表+解析,數字與 Excel 獨立讀出的定值比對(裕隆內銷 1,545、國瑞外銷 2,434、三陽內銷 26,200、光陽外銷 14,543)。
- 完整報告產生(連 DB 端到端)尚未實跑,請下次產生時核對檢核模式各分頁。
-
08-06 sqledit-blank-forms-fix ▸
2026-08-06 修復:拜訪單/客反應主檔等 20 支表單開窗空白、達成率開成錯誤程式
使用者可見變動
- 拜訪單(E-20)、客反應主檔(E-17)開窗不再空白:表單欄位正常顯示。受同一問題影響的還有 18 支仍使用舊式
SqlEdit包裝的表單(WarrantyCard、Shiptoaddress、Tick3、Tickmin、Ticka_rej、Ticka_voidrp、Tother、Arclaim、Commission、Commissionformula、Rfe、Rpdef、SpdataOldd、Purch_US、Trrafeeprime、PrimeEDI810、Jobcode、Income_ade),一併恢復顯示。
- 達成率(E-19)開窗內容修正:原本會開到美版 M.EIS 每日達交查詢的殘影(畫面只有一行類別全名文字),現在正確開啟 E.Order 達成率表單(單號/類別/年度月份/計算/明細)。
根因
1.
TsControl.SqlEdit的靜態建構子自 repo 建立起即覆寫DefaultStyleKey指向自身,但主題檔從未提供對應的預設 Style/ControlTemplate → 沒有 template 的 templated control 完全不產生視覺樹,仍用<TsControl:SqlEdit>包裝的 20 支表單開窗一律整面空白(框架外圍的導覽列/附件區正常,故不報錯、不易察覺)。2.
ProgramNavigator.ResolveErpViewModelType以大小寫不敏感比對解析 VM 型別,FILLRATE同時命中ViewModel.E.Order.FillrateViewModel與ViewModel.M.EIS.Daily.FillRateViewModel,由GetTypes()順序決定誰贏,實測開到後者且其無 DataTemplate → 畫面只剩型別全名。修正
TsControl/Themes/TsLayout.xaml:補基底SqlEdit預設樣式(Border+ContentPresenter;pkid/已審核由外層 ErpProgramLayout 右欄顯示,不重複)。
ViewModel/ProgramNavigator.cs:VM 型別解析改「先精確同名、落空才退大小寫不敏感」,多重命中時記 DebugLog。
驗證
- MSBuild TsERP 0 error;HarnessSmokeTests 5/5。
- 實機(darbnogicsa1、CMSA):拜訪單/達成率/客反應主檔三支開窗截圖驗證表單完整渲染;對照組客戶資料表正常。
- 其餘 17 支受影響表單未逐支開窗,屬同一機制修復,待順機驗證。
- 拜訪單(E-20)、客反應主檔(E-17)開窗不再空白:表單欄位正常顯示。受同一問題影響的還有 18 支仍使用舊式
-
08-06 salesreport-shipment-source ▸
業務課報告表:銷售額改以出貨單為準+月份彙總獨立分頁
日期:2026-08-06
影響範圍:業務儀表板(SALESDASH)KPI 與業務課報告表產生(檢核模式/範本模式)、AutoPilot 排程版
變更(使用者裁決)
1. 銷售資料來源:訂單 → 出貨單。原本抓訂單(ORMAST、依預訂交期分月),改抓出貨單(TRSAMA、依交易日期分月),金額用本幣未稅。出貨退回(SB)以負數計入,合計即淨銷售額。
2. 檢核模式新增獨立分頁「月份彙總」:全客戶每月合計(PCS/LOT/金額 × 1~12 月+合計)單獨一頁;「客戶月彙總」頁不再重複放全客戶合計列,只留各客戶。
3. 明細分頁改名「出貨明細」,欄位改為:客戶、客戶(正規化)、交易日期、單號、客戶品號、品號、品名、數量、單價、金額、備註。
4. 儀表板文字連動:KPI 卡「本月訂單金額」→「本月銷售金額」、圖表「各月訂單金額」→「各月銷售金額」、客戶 Top 15 欄頭「訂單金額」→「銷售金額」。
驗證
- 本機資料庫實跑新查詢路徑(DARB_BD_TRSAMA),欄位與資料量確認正常(2026 年 2.4 萬筆出貨明細)。
- 檢核模式往返測試(產檔→重匯入逐分頁核對)通過。
- 真 DB 端到端請從 SALESDASH 重新產生一次核對。
-
08-06 casebook-pdf-img-fix-cycle-pages ▸
2026-08-06 案例書 PDF 圖片不再被分頁切開+系統總覽新增 7 條循環完整說明頁
變更內容
- 案例書 PDF 圖片切頁修復:
tools/docs-pdf/export-pdf.py的 print CSS 補上圖片防拆頁規則——圖片一律break-inside: avoid(頁尾擠不下就整張推到下一頁)、圖與同段圖說(<p><img><em>圖說</em></p>慣例)綁定同一頁;圖高上限 230mm,超過一頁高的直式截圖(如行動儀表板手機畫面)等比縮進單頁而非被裁切。案例書 PDF 已重出(74 頁、25 圖,逐頁掃描確認零切圖)。規則為全域 CSS,之後所有以 export-pdf.py 產生的手冊 PDF 一併受惠。
- 系統總覽新增循環子頁 ×7(
docs/system-overview/cycle-01-sales.md~cycle-07-support.md):每條營運循環一頁完整說明——mermaid 流程總覽、逐節點「每一站在做什麼」(含對應手冊頁連結)、參與模組、該循環的報表與自動化、延伸閱讀(連案例書)。支援循環(07)內含總務/人事薪資/固定資產/品質/主管決策五條子流程各一節(各配小流程圖)。總覽頁 7 張循環卡片各加「完整說明 →」連結;docs/system-overview/.nav.yml控制側欄順序;extra.css補.ts-so-more樣式(含深色模式)。
- 系統總覽 PDF:7 條循環說明另出整本 PDF(
docs/system-overview/assets/Darbware-ERP-system-overview.pdf,27 頁,含封面/目錄/mermaid 流程圖,字級同案例書 1.2 倍);產生 manifesttools/docs-pdf/manifests/system-overview.json。總覽頁營運循環區塊末加「下載營運循環完整說明 PDF →」連結。
- PDF 內文字級調至 14pt:案例書與系統總覽兩份 manifest 的
font_scale1.2 → 1.3333(內文 10.5pt 基準 × 1.3333 ≈ 14pt,標題表格等比放大);案例書 74 → 77 頁。
- PDF 內部連結平板相容:Chrome 印出的目錄/章節連結是 named destination 型態,桌機閱讀器可點、多數平板檢視器(iOS 預覽、雲端硬碟預覽等)不支援。
export-pdf.py加後處理:印完以 PyMuPDF 把 named destination 攤平成明確頁碼跳轉(GoTo),兩本 PDF 已重出套用。
動機
案例書 PDF 對外交付時,多張截圖被 A4 分頁攔腰切開,觀感不佳。系統總覽原本每條循環只有卡片上三兩句描述,潛在客戶想了解「這條循環系統到底怎麼串」沒有下一層內容可看;補上每循環一頁的完整說明,讓總覽頁從「目錄」升級成「可以往下讀」的導覽入口。
- 案例書 PDF 圖片切頁修復:
-
08-06 bomflow-material-flow-tab ▸
流程圖製程表:新增「材料流向圖」分頁
日期:2026-08-06
影響範圍:流程圖製程表(BOM_FLOW,D-11)
新增內容
「流程圖圖形」之後新增最後一個分頁「材料流向圖」,同一份 BOM 資料換一種閱讀版面:
- 第一排(最上):全部原物料(BOM 中沒有下階的物料)由左而右排開。
- 最右一欄:加工(製程)與半成品(有下階的物料)由上往下排,順序即生產順序(下階製程在上、上階在下)。
- 右下角:成品(查詢組件)收在右欄最後。
- 連線為投入到產出的方向,且會經過製程節點:每個物料接到它投入的那道製程(BOM 明細的途程序號對應),接點在製程節點左側;製程依序串接、最後一道進半成品/成品;物料途程序號空白或對不到時進第一道製程;該階沒有製程時物料才直連上階。(08-06 兩修:初版的線從物料直跳上階沒經過製程;二版一律接第一道製程、未依途程對應)
- 第一排原物料的左右順序照「接入工序在右欄的高度」排(接早工序的料在左),減少連線交叉。
- 工具列提供 放大/縮小/自動縮放/重新排版;拖曳空白處平移、滾輪縮放,操作與流程圖圖形分頁相同。
已知呈現特性(待實機過目定奪)
- 同一原物料被多個半成品使用時,第一排會各出現一個框(沿用流程圖圖形「一筆 BOM 一個框」的呈現,每框帶各自用量);若希望一料一框請反映。
- 原物料很多時第一排會很寬,可用「自動縮放」整張檢視。
驗證
- 建置 0 錯誤;FlowDiagramBuilder 單元測試 16/16(含新增反向連線測試)+ Harness smoke 全過。
- runtime 未驗:尚未實機開窗確認版面與連線繞線視覺,請開 BOM_FLOW 切到最後分頁查一筆多層 BOM 核對。
-
08-05 skd-notify-todo ▸
2026-08-05 排程事件通知:改送「待辦事項」(新增通知方式「僅待辦事項」)
背景
排程事件(排程事件專案/個人事件)的「通知方式」下拉一直寫著「待辦事項 + Email」、「待辦事項 + Line」,但實際上系統只會寄 Email——待辦事項從來沒有真的送出過。而多數使用者要的其實是待辦清單通知:待辦認的是員工編號,不必維護每個人的 email。
改了什麼
1. 到通知時間會收到待辦清單通知(所有排程事件都適用)
只要事件列有填「通知人員」,時間一到就會在該人員的待辦清單出現一筆通知,主旨為「通知- 項目名稱」,內容是事件的項目名稱、預定時間與說明。點待辦會跳回事件對應的程式(事件沒填單據別時跳「排程事件專案」)。
這是通知線的共通行為,不分通知方式——既有的 Email 事件只要有填通知人員,除了信之外也會多收到待辦。多位通知人員(以逗號/分號/空白分隔)會各開一筆。
2. 通知方式多一個「僅待辦事項」,而且是新增時的預設值
「通知方式」下拉的第一個選項改為 「待辦事項」(僅待辦事項):只送待辦、不寄信、不發 Line,所以不需要通知帳號。新增事件時預設就是它。
原本的「待辦事項 + Email」「待辦事項 + Line」兩個選項與其資料值都沒有變動,既有事件的行為維持原樣。
3. Email 改成「有填通知帳號才寄」
以前系統只撿「通知帳號有值」的事件來處理,等於沒填 email 的事件連待辦都拿不到。現在改成:有通知人員或有通知帳號都會被處理;寄信只在「通知方式=待辦事項 + Email 且通知帳號有值」時才做。
4. 通知結果的判定
- 待辦全部開成功 → 事件標記為已通知。
- 待辦開成功、但信沒寄出去 → 仍標記為已通知(信件失敗會記在排程記錄裡)。這是刻意的:若標成失敗,下一輪重跑會讓已經收到待辦的人再收一次重複的待辦。
- 有任何一筆待辦沒開成功 → 標記為失敗,下一輪重試(同列已成功的人可能會收到重複待辦,屬已知限制)。
- 只寄信、沒有通知人員的事件,寄信失敗仍標記為失敗並重試(與以往相同)。
部署時需要做(管理者)
排程取件的預存程序條件有調整,不跑就收不到待辦(只填通知人員、沒填通知帳號的事件會被濾掉):
- 腳本:
sql/skd-notify-todo-sp-20260805.sql
- 逐一執行於:
darbnogiauto1~darbnogiauto5、darbcyauto1(朝陽,SQL 2008 相容)
- 執行後照腳本內的查詢實查確認已更新
另需更新排程 worker(Darbware Scheduler)到含本次修改的版本。
-
08-05 salesreport-raw-mode ▸
2026-08-05 業務課報告表:新增檢核模式(暫為預設)
變更內容
- 業務課報告表產生(SALESDASH「產生報告表」按鈕、AutoPilot
Ormast_SalesMonthlyReport)暫時不再填寫範本,改產「原始資料檔」:C:\temps\業務課報告表\{年}-{月}業務課報告表-原始資料.xlsx。
- 原始資料檔為全新 Excel,各分頁直接呈現系統抓到的資料,供人工檢核:
- 訂單明細:整年訂單逐筆(含客戶正規化前後對照)
- 客戶月彙總:每客戶 × 月的 PCS / LOT / 金額
- 汽車TTVMA原始 / 機車TTVMA原始:下載的公會月報整張原樣
- 汽車解析結果 / 機車解析當月 / 機車解析累計:程式從公會月報解析出的各廠內外銷台數
- 警告:產生過程的警告訊息
- 範本模式未移除:
SalesMonthlyReportOptions.UseTemplate = true即切回原本的範本填寫輸出;資料檢核確認無誤後將恢復。
動機
範本輸出(樞紐、圖表、彙總頁)難以直接核對「系統抓到的資料對不對」;先以原始資料檔驗證資料正確性,再回頭出正式版面。
- 業務課報告表產生(SALESDASH「產生報告表」按鈕、AutoPilot
-
08-05 casebook-fonts-deidentify-overview ▸
2026-08-05 案例書字級加大+截圖去識別化+新增「系統總覽」頁
變更內容
- 案例書字級加大(以 A4 列印與 8 吋平板閱讀為基準):
- PDF:
tools/docs-pdf/export-pdf.py新增 manifest 選項font_scale(等比放大所有 pt 字級,預設 1.0 不影響既有手冊 PDF);案例書 manifest(tools/docs-pdf/manifests/case-studies.json,新檔)設 1.2——內文 10.5→12.6pt、表格 9.5→11.4pt。案例書 PDF 改由 export-pdf.py 產生(Learn 式極簡版式,取代舊書封版腳本)。- 網頁:
docs/stylesheets/extra.css書封卡片字級整體上調(標題 0.82→0.92rem、說明 0.68→0.78rem、導言 0.86→0.94rem 等)。- 案例編號改分類編號:由無編號改為「章-序」(1-1、3-2…)。網頁以 CSS counter 自動編(新增案例自動續號);PDF 由
number_pagesmanifest 選項在目錄與各篇標題加號。
- 截圖全面去識別化:26 張插圖審計後,15 張含識別資訊(公司名、真實客戶/廠商/品牌名)+2 張半遮罩不全,全部精修為虛構名(公司統一「達備實業股份有限公司/DARBWARE INDUSTRIAL」、客戶廠商用天干系虛構名、品牌改甲型/乙型);未被引用且含真實客戶資料的
cudata-base.png下架。原圖備份.claude/tmp/backup-20260805-casebook-images/。
- 新增「系統總覽」頁(
docs/system-overview/):涵蓋 20 個模組地圖、377 支程式(手冊收錄口徑)、249 張報表(報表產生器登錄數)、7 條營運循環(銷售收款/採購付款/生產/庫存/總帳結帳/票據/支援循環)。入口站頂層 nav 在「案例書」後新增「系統總覽」(tools/release-notes/templates/_layout.html);Validate-SystemMap.ps1與Parse-SystemMap.ps1的 excludeFolders 同步加入system-overview(並補齊兩檔原本不同步的getting-started/case-studies)。
動機
案例書要對外給潛在客戶看:字級以紙本與平板閱讀為準放大;插圖不得出現任何真實公司/客戶資訊;「系統總覽」補上「這套系統整體涵蓋什麼」的入口敘事(模組、報表量、營運循環),與逐案例敘事的案例書互補。
-
08-04 fxrate-auto-restore ▸
2026-08-04 匯率自動更新恢復(排程任務修復)
背景
系統本來每個工作日會自動把台灣銀行牌告匯率寫進匯率主檔(B2- 開頭的每日單據,19 個幣別),2026/06/26 之後停了——舊伺服器(SERVER2)上的排程不再執行。雲端的匯率來源(每天 16:00 抓台銀牌告)一直正常,只是沒有東西把它寫回 ERP。
修了什麼
排程任務「取得匯率」(BCURRENM/FxRate)移到新排程機制(Darbware Scheduler worker)上執行,過程中修好三個問題:
1. 抓不到匯率時不再寫入垃圾資料:來源查詢失敗或該日無牌告(假日)時,任務會明確回報而不是塞一筆「查詢失敗」或空白的匯率單。工作日抓不到會標成失敗,排程清單看得見(避免再次無聲斷更一個月)。
2. worker 環境補齊:新排程 worker 先前無法執行這支任務(缺 Azure 連線註冊與本機暫存資料庫初始化),已補上。
3. 明細關聯修正:主檔與明細的關聯(linkid)漏接導致寫入被資料庫擋下,已比照手動新增的做法修正。
已在模擬環境端到端驗證:worker 撿到排程事件 → 從雲端取得 2026/08/03 台銀牌告 → 寫入匯率主檔
B2-20260803001(19 個幣別,USD 買 32.43/賣 32.53)→ 事件標記完成。要讓它每天自動跑,還需要(部署時)
1. 正式機更新 worker(Velopack 通道發版;設定檔已含新的 FxRateCosmos 區段,隨版更新)。
2. 在 EVENTPROJECT 建每日循環事件:
- 單據別:
BCURRENM、執行方法:FxRate- 參數:
{"BankAbbr":"TW","Date":"{d}"}({d}會自動代入預定日期)- 預定時間:建議每天 17:00 以後(雲端來源 16:00 更新);設「是否自動執行=是、執行後完成=是」
- 週六日可照排:任務內建週末防呆,週六日會直接回報完成、不寫入匯率(同日補充,見下)
3. 補回 6/27 起缺的歷史匯率:可手動對缺的日期各執行一次(同一任務改 Date 參數),或由開發批次補。
同日補充(下午)
- 雲端來源查證:逐日實查雲端匯率庫,6/27 起缺口期間資料全在(含週末,週末沿用週五牌價),可完整回補。
- 週末防呆:實查歷史匯率單口徑為「平日(含國定假日)每日一筆、週六日不寫」。因雲端週末也有資料,靠「查無資料」擋不住,任務改為週六日主動跳過(回報完成、不寫入),與歷史口徑一致。已實測驗證。
- 模擬環境缺口已回補:6/29–7/31 共 25 個工作日全數補齊(B2-20260629001…B2-20260731001,各 19 幣別),抽驗匯率與雲端一致。正式環境需在 worker 發版後照同法回補。
- 重複日期防呆:任務執行前先查該日期是否已有會計類匯率單,已有就跳過(回報完成、不重複寫入)。擋事件重建、手動重跑、回補與每日排程重疊時寫出同日第二張單。已實測驗證。
- 移除「使用年度月份更新」按鈕(排程事件專案/個人事件兩處):該按鈕的搬移邏輯算完不寫回,按了沒有任何效果(已知限制),且對帶參數的自動執行事件即使修好也會重抓舊日期,故直接下架。要調整既有事件請用「批次新增」重新展開或在格線手動修改。
-
08-04 cy-variants-batch2 ▸
2026-08-04 朝陽專屬版本擴大到 8 支程式(ADR 0125)
朝陽帳套的下列程式改用朝陽專屬版本:訂單管理、出貨通知單、客戶資料、裝箱單、產銷表、
客戶產品報價(加上先前已做的客單品報價、客戶產品表、CI 發票,共 8 支)。
使用者操作與畫面不變——選單點進去看到的還是同一支程式,差別在於朝陽與禾久的存檔規則現在各自獨立,
往後調整其中一家的規則不會影響另一家。朝陽維持既有行為(例:客戶資料的幣別可不填、
已出貨的出通單不得修改、產銷表新增時自動組單號),禾久同樣維持原本行為。
一併修正
- 客戶資料的「客戶報價」「訂單」兩個分頁在朝陽帳套會消失——起因是程式用舊的程式代號查權限,
而朝陽已改用專屬版本的代號。已改為查不到時自動改用專屬版本的代號再查一次。
- 移除程式中對「鈞寶」的判斷共 15 處。這些判斷因公司簡稱設定為「鈞寶電子」而從未生效,
鈞寶帳套的行為沒有任何改變。
-
08-04 cy-order-rulings-group2 ▸
2026-08-04 訂單模組裁決清單第二組:11 題定案實作(朝陽對齊舊系統)
延續 8/3 朝陽訂單模組存檔稽核,第二組 12 題經使用者問答裁決後全數落地
(裁決總表見開發側
.claude/tmp/cy-order-rulings-for-user.md;題 15 裁定維持現狀故無程式變動)。朝陽行為集中在各
_cy變體類,禾久行為不變(下列標「兩家」者除外)。朝陽(CY)行為變更
- 訂單管理:公司代碼不再必填(舊單可改);幣別空白改為自動補本幣+匯率設 1(不再擋存);
存檔時數量 0 或品號空白的明細列自動刪除;新增訂單自動帶單號前置碼 CO
(查證:資料庫編碼設定的 CO 因「前置欄位=2」實際不生效,須由程式寫入)。
- 出通單:數量 0 明細列存檔自動刪除。
- 客戶資料:聯絡人「人員別」空白的列存檔自動刪除(即使已填姓名,與舊系統一致)。
- 客戶報價單:材料明細數量 0、加工明細加工時間 0 的列存檔自動刪除;
加工頁「加工金額」手動修改後離開欄位會依公式回算(與舊系統一致)。
- 報價單(CUPDMA):客戶代號改為無條件必填;新增時不再自動塞「報價別=1」
(與既有 2680 張報價別空白的舊單口徑一致)。
- 預示訂單:存檔時若明細含「Y舊品」停用品號,彙整跳一則提醒(不擋存檔)。
- 商業發票:明細「產品描述」改帶客戶品號+品名(客戶認得的名字,帶入前須先輸入客戶代號與結關日期)。
兩家共同變更
- 商業發票:存檔時所有明細金額依當前數量×單價重算一次(挑訂單/挑出通帶入後改匯率、
幣別不再停在舊值);主檔「正嘜」改帶該客戶上一張商業發票的正嘜(不再抓客戶主檔麥頭)。
- 客戶產品資料:存檔不再回頭把空白「生效日期」填成今天(避免舊資料被整批改日期);
改為新增明細列當下自動帶今天。
- 底層修正:變體程式(朝陽 8 支
_CY)上傳/取號/刪除走的單據別鍵改為自動轉成資料庫實際
存在的鍵——修正變體程式新增單據時取號可能整段不執行的問題。
驗證狀態
建置 0 錯誤、煙霧與路由測試 69/69 通過、fresh-context 對抗審查揪出 3 處問題已修
(明細擋刪與自動刪的順序、生效日期誤在載入時回填、舊品判準改前綴比對)。
runtime 未驗:朝陽模擬機實機存檔/新增取號 CO/禾久側三條共同變更,待後續實測。
-
08-04 currency-decimal-places ▸
2026-08-04 外幣單據金額改依幣別表的小數位數(ADR 0124)
商業發票(CI)與出貨通知單(出通單) 的明細金額,計算時的小數位數改為依「幣別表」設定,
不再固定算到小數 2 位。
以朝陽為例,幣別表設定為 USD 3 位、JPY 4 位、CNY 3 位、TWD 0 位——單價 0.056 的品項數量 1 時,
金額由原本的 0.06 變成 0.056。
適用兩家客戶。既有單據的金額不會被自動重算,只有使用者實際編輯該列(數量/單價/其他金額)時
才會依新規則重新計算。若某幣別要固定算到 2 位,請直接把幣別表該幣別的小數位數設為 2。
-
08-03 memory-usage-reduction ▸
2026-08-03 降低程式運行時記憶體用量
一批針對長時間使用下記憶體越用越多的修正。多數改動使用者無感(只是變省),以下列出會被注意到的部分。
使用者可見的變化
appsettings.local.json改完要重啟程式才生效:原本程式會即時監看設定檔變動,現改為啟動時讀取一次(省下常駐的檔案監看資源)。改本機設定後請重開 TsERP。
- 關閉 AI 助理(圖表對話)視窗會確實釋放瀏覽器元件:原本關窗後背景會殘留
msedgewebview2.exe子程序,現在關窗即回收。
- 「擴充功能」面板上的「+」圖示改用內建向量圖形繪製,外觀相同——這讓程式可以移除一整包只為了這顆圖示而載入的圖示套件(約 9.5 MB)。
內部修正(無操作面變化)
- 關閉分頁/登出時,開過的程式所持有的本機資料庫連線與暫存資源會確實釋放(原本要等下次載入或程式結束)。
- 自訂版面配置(CUSTOMDASH)關閉時釋放所有 tile 的查詢資源與暫存資料庫檔。
- 行事曆的月份快取加上限(保留最近 12 個月)。
- Email 列印的報表物件用完即釋放。
- 外部資料擷取/業務課月報下載大檔改為串流直接落地,不再整份讀進記憶體(下載行為、檔名、內容完全不變)。
- 移除 .NET 8 下已無作用的舊版
App.config。
備註
- 「開過的程式保留在記憶體直到關閉分頁」的既有行為維持不變(經評估後決定不做自動淘汰)。
- 本批不含任何資料庫或部署變更,更新程式即生效。
-
08-03 headless-safety ▸
2026-08-03 TsMsgBox headless 防護+LanguageService 除役
TsMsgBox(訊息對話框)headless 防護
排程/背景 worker/單元測試等無 WPF 視窗環境呼叫到訊息對話框時,原本會當機
(NullReferenceException)或永遠卡住等人按鈕。現改為:寫入 DebugLog 後回安全預設值——
資訊型(OK)照常放行;確認型一律回否定(是/否→否、確定/取消→取消),
絕不在無人看見時默認執行刪除等破壞性操作。一般視窗操作完全不受影響。
另修正兩個未經 UI 執行緒防護的呼叫路徑與 MainWindow 尚未就緒時指派 Owner 的潛在當機。
LanguageService 除役(ADR 0122)
翻譯字典機制移除(它從登入起就是空的,所有查詢都只回原文);翻譯統一走 DisplayMeta
(
Lang/Xaml/*.json)。既有 542 個呼叫點行為逐位不變(有單元測試把關)。使用者無感。 -
08-03 cy-order-save-fixes ▸
2026-08-03 訂單模組存檔驗證修正(朝陽相容 17 條)
朝陽(CY)帳套 runtime 驗證與 11 支存檔邏輯稽核後的整批修正。多數修正只影響朝陽/鈞寶帳套;下列三條同時改變禾久行為,特別留意:
影響禾久的行為變更
1. 客戶預示訂單(PREORD):明細「原預訂交期」不再必填。此檢查為新版自創(禾久與朝陽 VFP 皆無此規則),會擋下批次補充產生的空白列。
2. 客戶產品報價(CUPDMA):「最低毛利率不得 ≤0」改為僅在新增/複製時檢查(原本修改既有單也擋;VFP 原設計為欄位級檢查)。
3. 客戶產品報價(CUPDMA):明細(品號×數量)重複改為提示不阻擋(禾久 VFP 原本也只提示;原新版誤升為擋存檔)。
朝陽/鈞寶帳套修正(禾久行為不變)
- 訂單(ORMAST):明細「預訂交期」不再必填;明細「客戶訂單號」只在空白時帶入單頭值(不再整批覆寫)。
- 報價單(CUQT):無「報價類別」欄的帳套跳過類別相關必填(原本恆判 C 類→客戶代號 100% 必填擋死);「模具組數」不再被明細筆數覆寫(朝陽為手輸欄,模具分攤費分母)。
- 客戶資料(CUDATA):「幣別必填」「統一編號 8 碼」朝陽豁免(禾久保留);「送貨地點」不再於公司地點空白時被洗成空白(雙客戶修正)。
- 產銷明細表(PDTSAL):朝陽新增/複製時自動組單號=年度+月份(2 位)+版次(對齊 VFP,原本被「請輸入單號」擋死)。
- 年度預估(ESTSAL):複製新增也會重組單號(原漏判,複製單號會殘留「原單號\*」)。
- 出貨通知單(SALEMA):修改閘改為「明細有累計出貨數>0 → 不得修改」(原誤用禾久的轉出備註規則,雙向錯)。
- CI 發票:明細金額小數位朝陽一律 2 位(對齊 VFP 2020/07/08 業務裁決;禾久維持幣別查表)。
- 客戶產品資料(CUINVE):禁止刪除僅套朝陽/鈞寶(原誤套全客戶,禾久失去刪除功能)。
- 裝箱單(PK):「ci日期」必填改依欄位存在(朝陽無此欄)。
- 客戶產品報價(CUPDMA):「業務員編號」必填改依欄位存在(朝陽無此欄)。
其他
- 年度預估(ESTSAL)朝陽既有單修改存檔被「請輸入分類」擋死已修(實機驗出):
分類↔年預估分類鏡射 setter 在載入時被另一庫缺欄的預設值洗掉已載入值;改為空值不得覆蓋另一側。實測修改存檔通過且 DB 分類保留。
- CI/PK 左下鍵值搜尋標籤由英文欄名「cino」改顯示「CI單號」(兩段修正:多語言檔補 cino 鍵+鍵值標籤改走 DisplayMeta 查表——原走的 LanguageService 字典自登入起即為空,查什麼都回原文)。
- CUINVE 畫面右上 pkid/已審核 疊層不再壓到明細表頭。
- 存檔層 TableHasColumn 帳套 schema 查詢失敗時寫入 DebugLog(原本靜默跳過,禾久必填檢查被關閉時無從察覺)。
稽核與修正證據:
.claude/tmp/cy-order-save-audit.md(116 條逐條驗證)、.claude/tmp/cy-order-verify-findings.md。 -
08-03 cuqt-cy-variant ▸
2026-08-03 朝陽「客單品報價」改用專屬版面(ADR 0123)
使用者可見變動(朝陽/鈞寶帳套)
- 客單品報價(E-03):改為朝陽專屬版面。移除該公司資料庫中不存在、因此永遠空白的欄位
(報價類別、報價人員、材質、圖檔名稱、模穴數、生產機器、注意事項、模具摘要、最低訂單量、有效期限等),
補上朝陽專屬的單品報價別、美元匯率、日圓匯率、模費轉訂單;加工明細表改為朝陽實際使用的
費率(分)/加工金額/裸價模具費/模具費(原治具費、費率、參考加工費等移除)。版面順序向舊系統靠攏。
- 出入庫申請(H-05):改開朝陽專屬版本(此為 2026-06 既有設計,因程式缺陷一直未生效,本次一併修好)。
禾久等其他客戶完全不受影響(廠商資料表、採購資料查詢等既有分流已實機複驗)。
一併修正的問題
- 變體版程式原本查詢任何單號都回「沒資料」(查詢預存程序拿不到設定,靜默回空)。
- 開發機上分流永遠不生效,導致變體無法從選單進入。
- 同時開啟變體與共用版時會跳「UNIQUE constraint failed」錯誤。
-
08-02 metal-price-source ▸
2026-08-02 外部資料擷取改成查詢(L.聯絡傳訊),新增銅/鋁行情
位置與操作方式改變
- 程式從 A.系統資料 搬到 L.聯絡傳訊(L-090)「外部資料擷取」。
- 改成查詢型程式:按查詢=列出已經抓回來的資料(不連外網,很快)。
- 查詢條件(由上到下):
- 期別:看哪一個月的資料。
- 來源:可勾選的清單(一次可看多個);一個都不勾=全部來源,下方會顯示「全部來源/已選 N 個來源」。
- 順便取得最新資料:預設不勾。勾了才會連線去抓一次再列出來。
- 強制重抓:本期已有也重新下載(只有在勾了「順便取得最新資料」時才能勾)。
- 查詢結果分兩區,哪一區有資料就顯示哪一區:
- 金屬行情:日期/金屬/名稱/交易所/報價單位/收盤價/漲跌/漲跌%/開高低/成交量。
- 已抓回的檔案:來源/抓取時間/檔案大小/檔名(滑上去看完整路徑),可按「開啟資料夾」直接開檔案總管。
- 底部一行摘要:行情幾筆、檔案幾個、最近一次擷取時間。
新來源:基本金屬行情(銅/鋁)
- 涵蓋 銅、鋁、鉛、鋅、鎳、錫、鋁合金、鋼鐵 等的收盤行情,交易所含 LME/SHFE/COMEX。
- 存檔位置:
C:\dglibrary\ExternalData\METALPRICE\yyyy-MM\<抓取時間>-metalprice-yyyyMMdd.json
- 這個來源存的是整理好的表格資料(不是網頁原始碼),Excel/程式都能直接讀。
- 可以每天抓:其他來源是「本期已抓過就跳過」,行情來源每天算一次新的,同一個月裡每天各留一份,回頭查得到當時的價格。
- 抓不到或網站改版時會標成失敗並附原因,不會存一個空檔讓人誤以為有資料。
可以放進自訂版面配置
因為改成查詢型程式,登錄後它會自動出現在「自訂面板配置」的查詢程式清單,可以當看板的一塊使用(看板上會顯示這支的條件區與查詢結果,所以「順便取得最新資料」在看板上也控制得到)。
啟用方式
- 要跑一次 SQL:
sql/register-extdata-program.sql,在每一家的資料庫各跑一次(登錄選單 L-090 + 複製權限;不建任何資料表)。沒跑的話程式在,但選單看不到。
- 用 sqlcmd 跑要加
-f 65001(檔案含中文、UTF-8 無 BOM),跑完看腳本最後的驗證結果。- 需要新版程式(
TsERP.exe/AutoPilot.dll)。
- 排程任務(ExternalDataFetch)行為不變,也會抓金屬行情。
備註
- 來源清單由程式提供,畫面上不做設定;要新增其他來源(例如壓鑄公會)請洽開發。判斷與取捨見
docs/decisions/0120、0121。
- 行情資料來源為公開網頁轉載的交易所報價,供內部參考用;若要作為對外報價依據,建議另行取得交易所授權資料。
📅 2026 年 7 月 (79 篇)
-
07-31 external-data-container ▸
2026-07-31 外部資料擷取獨立成程式
新程式:外部資料擷取(A.系統資料|A-160)
把外部資料來源集中到一支程式管理,車輛公會只是其中一個來源。
- 來源清單:一列一個來源,顯示分類、代碼、名稱、最近一次的狀態/抓取時間/檔案大小/訊息(滑到訊息欄可看來源網址與完整存檔路徑)。
- 勾選要抓的來源 → 按「擷取選取」;另有「全選/全不選」。可搭配「強制重抓」(本期已有也重新下載)。上方「期別」決定存進哪個分月資料夾。
- 「開啟資料夾」直接在檔案總管開啟抓下來的檔。
- 來源清單由程式提供,畫面上不做設定;要新增一家公會請洽開發(見
docs/decisions/0120-external-data-builtin-only.md)。
業務儀表板:外部資料改成用勾的
- 「外部資料擷取」區塊上方多了來源勾選,只顯示勾起來的來源;「立即擷取」也只跑勾起來的。
- 選擇會記住,下次開窗沿用(記在本機使用者設定,不影響別人)。
啟用方式
- 要跑一次 SQL:
sql/register-extdata-program.sql,在每一家的資料庫各跑一次(登錄選單 A-160 + 複製權限;不建任何資料表)。沒跑的話程式在,但選單看不到。
- 用 sqlcmd 跑要加
-f 65001(檔案含中文、UTF-8 無 BOM),跑完看腳本最後的驗證結果。- 需要新版程式(
TsERP.exe/AutoPilot.dll)。
- 排程任務(ExternalDataFetch)行為不變。
-
07-30 external-data-fetch ▸
2026-07-30 外部資料擷取(車輛公會統計檔自動下載)
新功能
- 新增「外部資料擷取」排程任務(AutoPilot
ExternalDataFetch):自動到台灣區車輛工業同業公會(TTVMA)統計頁抓當期統計檔並存到本機,目前兩個來源:
-
TTVMA_QTA1=汽車當月銷售統計-
TTVMA_TTA1=機車當月及累計銷售統計- 原始檔存放:
C:\dglibrary\ExternalData\<來源代碼>\yyyy-MM\<抓取時間戳>-<原檔名>。同一期多次抓取各留一份不覆蓋(公會月中會修正數據重上檔,留舊檔才查得出當時報表的數字來源)。
- 每次執行寫一份紀錄到
C:\dglibrary\ExternalData\_log\:帶時間戳的fetch-*.json+固定檔名的latest.json(含來源、實際下載 URL、存檔路徑、檔案大小、實際檔案格式、耗時、成功/跳過/失敗)。
- 同一期同一個 URL 已經抓過就跳過,不重複下載(每個檔 2~5 MB)。要重抓把參數
Force設true。
- 抓不到會分辨原因:
NotFound=公會網站連得上但該期檔案還沒公布或版面改了;Failed=連線或存檔失敗。多個來源其中一個掛掉不影響其他來源。
業務儀表板新增「外部資料擷取」區塊
- 業務儀表板(E-05)底部新增一區,顯示最近一次擷取結果(不論是排程跑的還是手動跑的,看的都是同一份紀錄):每個來源一列,含狀態、抓取時間、檔案大小、實際格式、訊息;滑到「訊息」欄會顯示該檔的完整存檔路徑。
- 狀態一眼分辨:綠色=已擷取/本期已有;紅色=來源無此期或失敗。
- 「立即擷取」按鈕:不必等排程,當場抓一輪(期別跟著上方選的報告月份)。旁邊「強制重抓」勾選=本期已有也重新下載。
- 「開啟資料夾」按鈕:直接在檔案總管開啟抓下來的檔案。
- 「存放位置」可改(預設
C:\dglibrary\ExternalData);改了之後上方顯示的就是該位置的紀錄。
- 按上方「重新整理」時,這一區也會跟著重讀。
啟用方式
- 排程參數:
Sources(空白=全部來源,或填TTVMA_QTA1,TTVMA_TTA1)、RootDir、Period(預設{-d1}=上個月,決定分月資料夾)、Force。
- 建議排程時間:每月 18~20 日。公會通常在每月 10~18 日才公布上月數據。
- 需要新版
AutoPilot.dll(沿用 SchedulerWorker 現行更新機制發佈);不需要跑任何 SQL、不動資料庫。
備註
- 這支只負責「把檔案抓回來存好」,不解析檔案內容。業務課報告表的行為完全沒變(它仍然自己連線抓取),日後才會改成讀這裡存下來的檔。
- 抓取邏輯與後續解析拆開的原因與取捨見
docs/decisions/0118-external-data-fetch-module.md。
- 新增「外部資料擷取」排程任務(AutoPilot
-
07-28 purch-undeliv-filter-update ▸
採購未納自動寄信:查詢條件修訂+改以 vwbd_purch 為底
日期:2026-07-28
變更
「採購未納自動寄信」(TWORK_SKD1_PURCH_UNDELIV)同日兩波修訂:
1. 拿掉起始日期下限:原本只列「預訂交期在今天往前 14 天以內」的單(2026-07-24 裁決,排除陳年呆單);本次取消,逾期單不再受兩週限制。
2. 新增「採購別 ≠ 3」排除:採購別為 3 的採購單不列入。
3. 查詢改以 vwbd_purch 為底(推翻 2026-07-25「不共用 vwbd_purch」裁決):未交/入庫/暫收待驗量改用表頭「已交數量」口徑、庫存量改用「可用倉現有數量」,與統計定義(BI 查詢)數字一致。管制說明欄 vwbd_purch 沒有,以 pkid join 回 purch 補齊。缺廠商/品號主檔的單不再列出(vwbd_purch 為 INNER JOIN)。
4. 加「未交數量 > 0」門檻:dev 實測若只用原「數量>(暫收−ng)」條件,會混入 14,252 筆已全數入庫但表頭暫收=0 的舊單(報表顯示未交=0);加此條後剩 109 筆真未納。
5. Excel 附件數量欄顯示格式調整:零顯示空白、不帶小數(千分位保留)。
兩庫 vwbd_purch 定義不同(2026-07-28 實查發現;裁決=view 不動、SP 各自適配)
- NOGI 版 view:未交數量=數量−已交、無管制說明欄、日期為字串 → SP 以 pkid join 回 purch 補管制說明,假未納守門用「未交數量>0」。
- CY 版 view:未交數量=數量−(暫收−ng)、自帶管制說明、日期為 datetime → SP 直接取 view 欄位,日期轉回 'yyyy/MM/dd' 字串輸出,假未納守門用「數量−入庫數量>0」。
- 兩庫「未交數量」欄的語意自此不同(各自沿用該庫 BI 查詢既有口徑)。
影響
- NOGI dev 實測:65 →(拿掉日期下限後 14,361)→ vwbd 底+未交>0 後 109 筆,最早交期 2020/08/17。庫存量欄改可用倉口徑後 NOGI 樣本全為 0(原全倉合計口徑會有值)——屬口徑變更非 bug。
- CY 版另加交期下限 2016/01/01(使用者手動調整入冊;原本只排除空日期成的 1900-01-01)。CY 模擬實測:3,272 筆(2016 門檻切掉 2010~2014 的 148 筆陳年孤兒單;2015~2025 間本無未納單),最早交期 2026/03/26;管制說明/庫存量欄有值(CY 可用倉 view 有維護);採購別=3 於 CY 實有 93 筆主檔會被排除。NOGI 版無此下限(NOGI 最早真未納為 2020/08/17,2016 門檻在 NOGI 為無作用)。
- 部署檔(新檔,不動已跑過的舊部署檔;同日稍早的
purch-undeliv-filter-update-20260728*.sql已被下列取代):
- NOGI:
sql/purch-undeliv-vwbd-20260728.sql(已於 dev darbnogicsa1 部署+實跑驗證)- CY:
sql/purch-undeliv-vwbd-20260728-cy-sql2008.sql(SQL2008 相容版,已於本機 CY 模擬庫部署+實跑驗證;正式機待部署) -
07-28 eventproject-batch-edit ▸
排程事件(專案)新增「批次修改」+按鈕調整
日期:2026-07-28
程式:L-050 排程事件(專案)(EVENTPROJECT)
變動內容
- 明細格線新增多選能力(Shift/Ctrl 點選可一次選多列)。
- 主檔按鈕區新增
批次修改按鈕:
1. 編輯狀態下,先在明細格線選取要修改的事件列(未選或只選一列時,會詢問是否套用到全部事件)。
2. 開窗時自動把第一筆目標列的現值帶入各欄位當預設值(套用勾選保持未勾)。
3. 視窗中勾選要套用的欄位並填新值——只有勾選的欄位會被覆蓋,未勾選的欄位保持各列原值。
4. 可批次套用的欄位:是否停用、已完成、是否通知、通知方式、通知人員、是否自動執行、執行後完成、參數。
5. 套用到全部時,已完成的事件不會被修改(視窗畫面上有紅字提示)。
6. 按確定後套用到所有目標列,再按
儲存寫回。- 套用通知方式或通知人員時,各列的通知帳號會自動依「通知人員+通知方式」重算(Email 取員工 email、Line 取 Line 帳號,多人以逗號串接),行為與範本展開時一致。
- 按鈕文字與順序調整:
大量新增更名為批次新增;按鈕順序改為批次新增→批次修改→使用年度月份更新(移到最後)。
背景
範本一次展開成上百筆明細列後,先前要調整共通屬性(換通知人、改排程參數、整批停用等)只能逐列手動修改;既有的「使用年度月份更新」按鈕另有已知限制(算完不寫回),未在本次處理範圍。
-
07-26 purch-undeliv-history-table ▸
2026-07-26 採購未納·每次查出結果留存歷史表
新功能
- 「採購未納自動寄信」排程每次執行時,把該次查出的完整明細(18 欄)整批留一份到歷史表
twork_auto_purchundelivhistory(集中自動化庫,比照安全庫存twork_auto_safetystockhistory的做法)。每一筆以執行時間+執行guid(與當次寄出的信共用同一 guid,可對帳)+序號標記,之後可依 guid 撈「某一次跑的全部明細」、或依執行時間做跨月/跨年查詢比對。
- 保留策略:全部累積不清(同安全庫存歷史)。
- 心跳跑(當日無未納明細)不寫歷史——與安全庫存「0 筆不留」一致。
- 排程事件回寫(與安全庫存對齊):每次執行把
執行guid+結果表寫回該排程事件列,之後可從行事曆/排程事件畫面的「結果檢視」直接重開該次查出的明細。
啟用方式
- 跑
sql/purch-undeliv-history-deploy.sql(在自動化庫建歷史表+寫入 SPTWORK_AUTO_PURCHUNDELIV_HIST、在 log 庫登錄 proc_param)。NOGI 目標庫darbnogiauto1/darbnogilog1;CY 版把庫名代換成darbcyauto1/darbcylog1後跑(腳本檔頭有說明)。
- 部署後需搭配新版
AutoPilot.dll(採購未納任務改為每次執行順帶寫歷史)——沿用 SchedulerWorker 現行更新機制發佈。
- 既有查詢 SP
TWORK_SKD1_PURCH_UNDELIV不變,寄信/待辦行為不受影響。
備註(部署踩雷)
- 排程派發器的
proc_param.datafunc欄是nvarchar(30),SP 名超過 30 字會被靜默截斷、登錄失敗,導致該任務排程實跑時歷史寫不進去且不報錯(build/smoke 都測不到)。本次 SP 名取 28 字即為此故;日後新增走 SKD 派發器的 SP,名稱一律 ≤30 字。
- 「採購未納自動寄信」排程每次執行時,把該次查出的完整明細(18 欄)整批留一份到歷史表
-
07-24 purchquery-crash-and-blank-fix ▸
2026-07-24 採購查詢(採購資料查詢)修復:開窗即崩 + 查詢結果空白
使用者可見變動
- 採購付款 → 採購資料查詢(G-05)現在可正常開啟並查詢。此前點選該程式會跳「Object reference not set to an instance of an object」錯誤、完全打不開(自 2026-07-15 該程式改用畫面下方標準查詢面板後即如此)。
- 修復後:開窗顯示採購明細查詢表格與查詢條件面板(廠商、品號、採購日期、預訂交期、僅未交、含金額),按查詢即列出符合條件的採購單明細(採購別、採購單號、廠商、品號、品名、數量、單位、已交數量、幣別、交期、匯率等)。
- 「含金額」未勾選時單價與金額欄維持空白(依權限隱藏金額,行為不變)。
- 表格欄位標題改為中文(原為英文 Purchasing Type / Purchase Order No…):採購別、採購單號、序號、採購日期、廠商代號、廠商簡稱、品號、品名、數量、單位、已交數量、單價、本幣未稅、幣別、預訂交期、匯率、備註、請購單號、請購單序號、噸數。
- 查詢條件區標籤改為中文(原為 Vendor / SKU / PurchaseOrderDate / ETA / Only Undelivered / Amount Included):廠商代號、品號、採購日期、預訂交期、僅未交、含金額。
技術摘要(純程式碼修復,不動資料庫)
1. 程式鍵對照:
ProgramClassRouter新增全客戶通用對照QRY_PUR_CSTK → PURCHQUERY(各客戶選單資料庫仍登舊 VFP 鍵,但新版程式鍵為 PURCHQUERY,登入時於記憶體導向,不改 DB)。2. 導航防呆與解析:
ProgramNavigator.CanSwitch補 null 防護(未登錄的舊鍵改為提示而非崩潰);ViewModel 型別解析改為大小寫不敏感,讓駝峰命名的 ViewModel(如PurchQueryViewModel)能被正確解析。3. 欄位對映:採購查詢結果 POCO 補上
[TsColumnName]中文欄位對映,修正「查得到筆數卻整格空白」。驗證
- 建置通過;
ProgramClassRouter單元測試 + Harness smoke 全數通過(21 passed)。
- Runtime 於禾久(localhost)以 CMSA 實測:採購資料查詢開窗無崩潰、查詢列出 34 筆(12 頁)採購明細、各欄位正確顯示。
- 同模組其餘 5 支(廠商資料表、廠商報價單、採購單、請購單、供應商協同回覆審閱)實測皆正常開窗。
備註
- 全客戶通用對照假設「各客戶選單資料庫皆以
QRY_PUR_CSTK登此程式」;若某客戶已直接登PURCHQUERY,登入改寫有重複防護不會產生重複選單。
-
07-23 purch-undeliv-daily-mail ▸
2026-07-23 採購未納每日自動寄信
新功能
- 新增排程任務「採購未納自動寄信」(單據別 PURCHQUERY/執行方法 UndeliveredMail):依預訂交期抓「已逾期+未來 3 個上班日內」(上班日依工作日曆 wkcald,區間內假日交期照列)的未結案採購明細,每日自動寄信。
- 信件內容:HTML 表格本文(18 欄:預訂交期、採購日期、廠商代號、廠商簡稱、採購單號、品號、品名、採購數量、未交數量、暫收數量、入庫數量、暫收待驗量、ng數量、ng退貨量、暫收區ng量、庫存量、管制說明、備註)+同內容 Excel 附件。排序:預訂交期→廠商代號。本文最多列最急的前 200 筆(超過時標註「其餘 N 筆詳見附件」);Excel 附件永遠是完整清單。
- 寄出時自動建一筆待辦事項通知承辦人(承辦人=排程事件「通知人員」欄的帳號;主畫面待辦清單紅點提醒)。待辦點開時,在明細區以表格顯示當日全部未納明細(18 欄;數量欄靠右對齊並帶千分位)。
- 抓取範圍優化:只看「主檔與明細都未結案、預訂交期在今天前兩週到未來 3 個工作天之間」的單,把陳年逾期呆單排除,實際筆數大幅收斂(測試環境 1.4 萬→數十筆)。
- 查無資料的日子照寄「本日無未納明細」心跳信(無附件、不建待辦)。
啟用方式
1. 跑
sql/purch-undeliv-mail-deploy.sql(建查詢 SP、登錄 proc_param、種一筆單次測試事件)。2. 把測試事件的收件人(參數 JSON)與通知人員兩處占位符換成實值——沒換之前任務會擋下不寄。
3. 正式每日排程:到「排程事件·專案」(EVENTPROJECT) 用「大量新增」建日期類別=每天、08:00 的事件(系統一次展開至計算截止日,預設 +5 年)。
修正
SqlBI/TWORK_SKD_GET_PENDING_AUTOEXEC.sql對齊實際部署版本(補回「只撿已到時間事件」的過濾條件,repo 檔原先漏了)。
- 排程 Worker(SchedulerWorker)每輪執行時自動開/關一筆 logbook 排程 session:修正排程任務要「建待辦事項」時被存檔閘擋下(NOT LOGON)的問題——這同時讓供應商協同的待辦通知在排程端可用。查詢 SP 依指示命名為
TWORK_SKD1_PURCH_UNDELIV。
-
07-23 cudata-abook2-tab ▸
客戶資料表新增「索引分類帳」分頁
- 日期:2026-07-23
- 模組:E.訂單/客戶資料表(CUDATA)、N.總帳(ABOOK2)
變更內容
- 客戶資料表新增索引分類帳分頁:切入即自動以「索引種類=客戶或廠商代號、
範圍=目前這家客戶、期間=當月」查詢並顯示該客戶的分類帳;條件面板完整開放,
期間/科目/索引都可自行調整重查,六種報表列印照 ABOOK2 原樣可用。
- 權限:需有 N-100 索引分類帳(ABOOK2)的瀏覽權限,無權限者看不到此分頁
(與財務/應收帳款等分頁同規則)。
- 在客戶主檔換筆(上下一筆/查詢別家)後再切入此分頁,會自動改帶新客戶重查。
注意
- 分頁預設期間為「當月」:客戶當月無往來時查詢結果為空,屬正常,調整期間即可。
-
07-23 acc-rpt-simulate-sql ▸
2026-07-23 ACC_RPT「模擬表預覽」改走資料庫端展開(DARB_QRY_ACC_RPT_VIRTUAL)
變動
- 模擬表預覽改為執行資料庫既有預存程序
DARB_QRY_ACC_RPT_VIRTUAL(正式端沿用多年的展開邏輯)。
- 新增「模擬表預覽(C#)」按鈕(同日追加):保留原程式端展開供對照——以畫面當下(含未存檔)的明細公式展開,
ACC_SCAN含分類標頭/縮排/位數上限,ACC_BSCE也展開;輸出 列號/序號/抬頭/公式/列印碼 五欄。
- 以「已存檔」的明細公式為準:按下按鈕時查的是資料庫裡存好的公式列——尚未存檔的新增/修改不會反映在預覽裡,請先存檔再模擬。
- 結果視窗改列出完整明細欄位(報表編號/名稱/序號/科目名稱/公式/列印碼…等),
ACC_SCAN列逐科目展開、序號自動遞增插列;其餘列照存檔內容原樣列出。
- 提示訊息與按鈕 tooltip 同步更新(四語)。
影響範圍
- ACC_RPT 報表公式設定畫面的「模擬表預覽」按鈕。公式檢查按鈕不變。
- 兩鈕展開樣式不同:資料庫端(模擬表預覽)為「逐科目平鋪」(抬頭依 ACC_SCAN 第 4 參數:1=科目名稱、2=代號、3=代號+名稱),不含大/中/小分類標頭、縮排與位數上限(第 5 參數)併入規則,
ACC_BSCE不展開、以已存檔為準;程式端(模擬表預覽(C#))與實際查詢(ACC_SELFRPT)同規則、吃畫面當下內容。
- 模擬表預覽改為執行資料庫既有預存程序
-
07-22 title-app-version ▸
2026-07-22 主視窗標題顯示程式版本號
使用者可見變動
- 主視窗標題列現在會顯示程式版本號,格式如
Darbware ERP V1.0.26 Version:2026/07/21 09:00 ...。
- 版本號從程式一啟動就顯示(登入前即可見),不必等進入任何作業畫面。
- 這個
V1.0.26就是 Velopack 發版的版號——回報問題或確認更新是否生效時,看標題即可,不必再找安裝資料夾。
- 原有的
Version:2026/07/21 09:00日期字串保留不變:那是與資料庫端比對的版本閘門(DB 參數 90007),與發版版號是兩回事。
技術面
TsERP/TsERP.csproj:新增<Version>$(VelopackVersion)</Version>,讓組件版本(AssemblyVersion / FileVersion / InformationalVersion)與release-velopack.ps1自增的VelopackVersion同源;發版腳本本身零改動。
ViewModel/PageControl/MainWindow/MainWindowViewModel.cs:新增GetAppVersion()讀取 entry assembly 的AssemblyInformationalVersion(砍掉 SourceLink 附加的+commit hash),_Title初始值與SetTitle皆帶V{版號}。
- 注意
EnvironmentSetting.Version(日期字串)格式不可改:GetSqlData.cs以DateTime.TryParse拿它與 DB 參數 90007 比對擋舊版登入,Sql.cs亦以@programVersion送進 SP。
- 主視窗標題列現在會顯示程式版本號,格式如
-
07-22 ormast-union-darbedittool ▸
2026-07-22 訂單(ORMAST)欄位對齊資料庫與 Darbedittool 下架
使用者可見變動
- 訂單畫面欄位正名:「訂單號碼」改為「訂單編號」(label 與資料綁定,對齊資料庫實欄);「倉庫」改用「倉儲代號」。付款方式下拉與專案代號區塊(資料庫已無對應欄)自畫面移除。
- 存檔檢查改照 VFP 原版:必填=公司代碼、受訂日期、客戶代號、集團代號(僅禾久,朝陽自動跳過)、倉儲代號、幣別。明細每列必填預訂交期;單頭客戶訂單號自動帶入明細;修改已回覆交期的明細會自動寫入修改註記與原品號/原數量/原單位/原預訂交期(僅禾久)。
- 移除美版檢查:業務員佣金 100% 檢查、Customer PO 重複檢查、信用檢查、運費/毛利警示不再出現。
- Darbedittool(eBay/Amazon/Walmart 訂單匯入)下架:功能移除,訂單畫面「其他2」按鈕轉灰色。
- POINBOUND 修正:匯入訂單後現在會正確顯示配到的訂單編號(原本反查用了不存在的欄名,永遠空白)。
- 訂單畫面「其他N」按鈕標籤校正(原整組與程式行為錯位):其他1=毛利核準、其他4=訂單複製、其他5=特殊修改;其他2/3/6/7 停用清空。「快速審核」按鈕移除(審核已內建於標準流程;連帶美版「訂單信用審核」視窗無入口)。DB 端跑
sql/ormast-othern-labels-20260722.sql(每帳套一次)。
Migration
無 DB 變更。程式端刪除的欄位本來就不存在於任何現役客戶庫。
詳細決策見 ADR 0112。
-
07-22 order-module-union-align ▸
2026-07-22 訂單管理模組整批聯集瘦身(使用者可見變動)
照 ORMAST 那套(ADR 0112→0113)把訂單管理 22 支程式做完兩庫聯集瘦身+VFP 存檔檢查對齊。使用者看得到的變動:
畫面欄位移除(皆為輸入後永不落庫的死欄位)
- CI 商業發票:EDI/追蹤欄區塊(追蹤號碼、提單號、SCAC、Carrier、Ship/Est Date、Receive ID、Create 856/810)與 ShipTo/BillTo 地址區塊整塊移除;明細「需求單號」欄移除。
- SALEMA 出貨通知:主檔「送貨地址」輸入框移除。
- CUPDMA 客戶報價:「生效日期」「專案代號/專案名稱」欄位移除。
- FILLRATE 達成率:「建檔日期」欄位、明細「備註」欄移除。
行為修正
- CI:稅別欄原本綁到不存在的舊欄(輸入不會儲存),現在正確落庫(禾久)。
- CUPDMA(禾久):新報價單取號前置碼修正回 QN(正式報價)/QC(其他報價),與歷史單號一致;原誤發 QT。
- CUDATA 客戶資料:幣別改為必填(原自動帶本幣);統一編號有值時檢查 8 碼;聯絡人列僅在「人員別與姓名皆空」才自動剔除(原僅看姓名,會誤刪);分類列僅在「分類與分類內容皆空」才剔除。
- PREORD 預示訂單:新增時寫入建檔日期;匯率<=0 自動補 1。
- FILLRATE:類別/公司代碼改必填;新增時單號自動組碼;週六日且訂單件數 0 的明細列存檔時自動剔除。
- ESTSAL 年度預估(朝陽):修正存檔恆被「年預估分類未輸入」擋下的問題(朝陽改驗「分類」並自動組單號)。
Runtime 驗證尚未執行,逐支清單見
.claude/tmp/order-align-progress.md。 -
07-19 po-ack-acknowledgment ▸
2026-07-19 — 採購單簽章回執:供應商回覆交期(雙向閉環)
摘要
把採購單簽章 PDF 迴圈補成雙向閉環:供應商匯入採購單後,可簽一份採購單簽章回執
(接受 / 調整交期 / 拒接)寄回買方;買方在採購協同回覆審閱(
POCOLLABRPY)匯入回執、驗章後,照既有流程套用交期回採購單。回執落進與 Phase 7 token 回覆同一張 reply 表,套用邏輯完全重用。
新增
- 供應商可回覆買方:於「採購協同收件」(
POINBOUND)匯入採購單後,按「回覆買方」,
選擇接受 / 調整交期(逐行填新交期、數量、備註)/ 拒接並附整單備註 → 簽章後產出回執 PDF
自動寄回買方。
- 買方可匯入簽章回執:於採購協同回覆審閱(
POCOLLABRPY)動作列新增「匯入簽章回執」按鈕,
選回執 PDF → 驗章通過後落入回覆清單,照原有「套用交期」把交期寫回採購單(更新預訂交期、
發送狀態、開待辦),與供應商臨時連結回覆走同一套審閱套用流程。
- 同一份回執重複匯入會被擋(防重放)。
- 回執明細以「單號 + 序號」自動對應採購明細;對不上的行仍會落入審閱清單供人工檢視。
變更
- 採購單簽章資料新增買方回覆信箱:送出採購單時,payload 加入採購員(採購單輸入人員)的
email,供應商回執自動寄回該信箱。此信箱只寫進簽章資料、不印在採購單報表上(人看報表不露信箱),
且受簽章保護、防竄改。
刪除
無
Breaking Changes
無:採購單簽章 PDF 的資料格式(payload)新增
buyerEmail欄位向後相容,既有已簽章文件仍可驗章;回執落入既有回覆表,不影響原有的臨時連結回覆流程。
前置設定(使用者需先完成)
回執為 B2B 全迴圈延伸,沿用簽章 PDF 的既有前置(見 2026-07-18 採購單簽章 PDF):
1. 產生機構簽章金鑰:買賣雙方各自跑簽章金鑰向導產生正式金鑰。
2. 設定往來對象公鑰(
POKEYCP):買方需匯入供應商公鑰卡才驗得了回執的章。3. 回覆信箱來源:採購員(採購單輸入人員)需於
perdata維護 email,回執才寄得回本人。!!! warning "尚未 runtime 驗證"
本次交付建置與單元測試全綠(供應商端回執組裝、買方端驗章落表、既有套用交期回歸測試皆通過),
但供應商真簽章產回執 PDF、寄信,以及買方真驗章匯入、套用交期回採購單等 runtime 全鏈尚未實機驗證;
「匯入簽章回執」按鈕的多語系文字尚未建立(有預設中文,不影響功能)。上線前請先完成前置設定並實機測試。
相關 ADR
- 供應商可回覆買方:於「採購協同收件」(
-
07-18 po-signed-pdf ▸
2026-07-18 — 採購單簽章 PDF:給供應商的 B2B 雙向迴圈
摘要
把採購單接進既有簽章 PDF 系統,做成 B2B 雙向迴圈:買方送出簽章採購單 PDF → 供應商收下驗章
→ 匯入自家系統自動建立銷貨訂單。沿用既有 RSA-3072 簽章、PDF/A-3 內嵌與公鑰配對機制。
新增
- 採購單可列印/預覽:補完採購單報表(含單價、原幣未稅、合計),可從採購單列印/預覽出圖。
- 供應商協同信可附上採購單簽章 PDF:協同信寄出時附帶已簽章的採購單 PDF,供應商端可驗章確認來源與內容未遭竄改。
- 「採購協同收件」功能(
POINBOUND):供應商匯入已簽章採購單 PDF → 驗章通過後自動建立銷貨訂單(ORMAST)。
- 依採購單上的買方統一編號自動對應客戶代號(查無客戶檔則擋下,提示先建檔)。
- 同一份採購單重複匯入會被擋(防重放),並回報既有訂單號。
變更
- 採購單報表資料對映修正:原報表因欄位對映問題無法正常顯示,本次修正後欄位正常帶值。
- 供應商協同信改為「先產簽章 PDF 附件、失敗則回退純連結信」——產 PDF 失敗不影響協同連結寄達。
刪除
無
Breaking Changes
無:採購單簽章 PDF 的資料格式(payload)新增欄位一律向後相容,既有已簽章文件仍可驗章。
前置設定(使用者需先完成)
此功能為 B2B 全迴圈,上線前需先備妥簽章金鑰與往來對象公鑰:
1. 產生機構簽章金鑰:跑簽章金鑰向導產生正式金鑰(未產生時送出端會提示「金鑰未建立」,不會建立錯誤 PDF)。
2. 設定往來對象公鑰(
POKEYCP):於「往來對象公鑰」維護匯入供應商/客戶的公鑰卡,收件端才驗得了章。3. 部署資料庫物件:對各目標 DB 執行
sql/pocollab-inbound-doc-deploy.sql(建收件防重放表twork_com_inbound_doc+_sheetno/_tableseq登錄)。!!! warning "尚未 runtime 驗證"
本次交付建置與單元測試全綠,但送出端 headless 渲染 PDF、真簽章、供應商端真驗章匯入 ORMAST 等
runtime 流程尚未實機驗證;正式機資料庫物件尚未部署。上線前請先完成前置設定並實機測試。
相關 ADR
-
07-18 po-signed-pdf-encryption ▸
2026-07-18 採購協同:採購單完整文件加密
摘要
採購協同送出簽章採購單時,新增「完整加密文件」選項——採購單整份加密,只有指定供應商用 TsERP
能打開,email 途中、郵件伺服器、誤收者都讀不到金額。簽章(防偽 / 防竄改)不變,加密是再加一層。
新增
- 發送方式三選一:PURCH 發送供應商協同時可選 ① 一般簽章 PDF ② 完整加密文件
③ 只要供應商回覆交期(純連結、不附檔)。
- 完整加密:採購單整份簽章 PDF 加密成
.poenc檔隨信寄出,只有指定供應商用 TsERP 匯入才解得開;
金額照留在文件內(整份都是密文)。
- 收件端支援加密檔:供應商在「採購協同收件」(POINBOUND)可匯入
.poenc,系統自動用自己的
私鑰解密還原文件、驗章後建立訂單;既有明文
.pdf簽章檔照常匯入。- 機構金鑰備份 / 還原:金鑰向導可把機構金鑰備份成密碼保護檔並在換機 / 重建時還原
(加密私鑰一旦遺失,先前收到的加密單將永久打不開,故務必備份)。
變更
- 買賣雙方識別改帶統編 + 完整公司名稱:國外客戶(無統一編號)可改用公司名稱對映,
收件匯入建訂單時客戶對映改為「統編優先、公司名稱後備」。
- 金鑰輪替保留舊金鑰:重新產生機構金鑰時保留舊私鑰於本機,以便解開先前收到的加密單;
向導提醒改為「新公鑰卡須重新交付往來對象配對」。
刪除
- 無。
Breaking Changes
- 無(既有明文簽章 PDF、純連結協同均照常運作;加密是新增選項,非取代)。
Migration Notes
- 發送方式欄:各資料庫需執行
sql/pocollab-portal-deploy.sql的 Phase F2 段
(為
sent表加發送方式欄)。dev(csa1 / csa5)已完成;正式機(csa2/3/4 及其他客戶庫)待部署。- 雙向公鑰配對:要送「完整加密文件」給某供應商,須先在 POKEYCP 匯入該對象的公鑰卡;
買方自身也要把新公鑰卡交付往來對象配對。POKEYCP 選單權限掛載與
_sheetno重登為前置。- 未配對到對方公鑰時,系統會自動改送「未加密簽章 PDF」並於發送結果訊息提醒。
已知限制 / 未驗
- 金鑰向導開窗互動、端到端加密收送(
.poenc→ email → 匯入解密驗章)、跨客戶機的憑證庫行為
尚未實機驗證(金鑰解密 / 備份還原 / 輪替已於本開發機憑證庫以整合測試驗過)。
- 目前採單一金鑰雙用途(簽章 + 解密),簽 / 密金鑰分離列為日後強化選項。
-
07-17 pocollab-generalize ▸
2026-07-17 供應商協同入口廣義化
摘要
供應商回覆表單全新設計(手機優先、繁體中文),並讓協同追蹤機制脫離採購單、支援任意單據別與
客戶/廠商雙類別。承辦人拉回回覆後,左側待辦事項會出現通知,套用或忽略即自動消失。
新增
- 供應商回覆表單全新設計:手機優先版面、繁體中文介面,提供確認、逐項調整、
拒接三種回覆動作,並顯示回覆期限。表單仍不顯示金額。
- 承辦人待辦通知:供應商回覆拉回後,承辦人左側「待辦事項」出現「供應商回覆」通知;
承辦人套用或忽略該回覆後,通知自動消失。
變更
- (內部)協同追蹤表廣義化:追蹤欄位由採購專用改為通用——單號、單據別、
客戶廠商代號、類別(客戶/廠商)等欄位,讓同一套協同流程可套用到採購單以外的單據別。
刪除
- 無。
Breaking Changes
- 無面向使用者的破壞性變更。內部追蹤表欄位改名(採購單號→單號、供應商統編→統一編號等)
以冪等 migration 處理,見 Migration Notes。
Migration Notes
- 正式機部署執行
sql/pocollab-portal-deploy.sql(含追蹤表欄位改名/新增的冪等 migration,
可重複執行)。worker 端與表單端契約 v2 已同步佈署。
已知限制
- 套用交期寫回明細目前僅支援採購單(PURCH);其他單據別可讀取/回覆,但套用交期寫回會被
擋下,待該單據別補寫回支援後再開放(見 ADR 0106)。
-
07-17 genaffair-view-wiring-dbset-backfill ▸
2026-07-17 總務模組畫面接線修復+12 個資料型別註冊補齊
使用者可見變動
- G庫存主檔(GINVENT)可以正常使用了:先前開窗只顯示一行類別名稱(畫面空白)、按上下筆會跳「Cannot create a DbSet」或「Object reference not set」錯誤;現在開窗後點「基本」分頁即可正常瀏覽與導覽資料。
- 已知小瑕疵:開窗當下不會自動選中「基本」分頁,需手動點一下(待後續修正)。
- 總務模組其餘程式(G廠商報價、G採購單、G出入庫單、G出貨單、領料、倉庫表等 8 支)畫面已接上:先前一律顯示空白+類別名稱。其中仍使用舊版表格元件的程式(如 G廠商報價)開窗會出現「Exception has been thrown by the target of an invocation」錯誤視窗——這是既有的舊表格元件問題,待表格元件升級(dg-to-radgrid)後解除。
- 修復 12 個單據型別的本機資料庫註冊(GPURCH、GSPLACE、PPURCH、PURAMA/TWRAMA/WKRAMA、SALEMA、SAMPLE):這些單據相關畫面先前導覽即崩潰;同時依兩客戶庫(鈞寶/朝陽)欄位聯集補齊資料欄位與共用審核欄。
技術摘要
1.
Model/LocalDbContext.cs新增 12 個 DbSet(C.總務/E.訂單/G.採購/新增 J.品質區);smoke baseline 由 126 收緊至 112。2.
TsERP/App.xaml補 C.GeneralAffair 8 支隱式 DataTemplate(該模組原本零接線)。3.
GinventViewModel.TabSelectedItem加 null 防護(Tabs集合從未初始化,靜態分頁 XAML 與動態分頁 VM 的 fork 斷裂)。4. 14 個 Source 拿掉
(IAppContext context)建構子改無參(EF materialize 需求),呼叫端連動修改(含Gstkbas_1TmpPoco、Sample1Source衍生類: base())。Migration
無需資料庫變更。本機 SQLite 由
EnsureCreated自動重建新表。 -
07-16 sliy-balance-remove-accitem-link ▸
2026-07-16 傳票「未沖帳款查詢」暫時下架;項目編號表「項目分類」標籤可跳摘要檔
傳票(SLIY):未沖帳款查詢暫時下架
- 右側支援面板的「其他查詢」頁籤(未沖帳款查詢/挑款)暫時移除,新增傳票時也不再自動切到該頁。
- 屬暫時下架(2026-07-16 裁決):
SliyViewModel移除ISpecialQuery介面;要恢復把介面加回並還原建構子的SpecialQueryContent與AfterAddNew的切頁呼叫即可,SliyBalanceViewModel本體未刪。
- 手冊
docs/N-GeneralLedger/sliy.md已同步移除對應段落與截圖佔位。
項目編號表(ACCITEM):「項目分類」標籤加超連結
- 「項目分類」標籤改用
TsNavigateLabel(比照群組表 GRPM 分類標籤既有模式):雙擊標籤跳轉摘要檔(SMEMS)並定位到C227類別,方便直接維護項目分類選項。
-
07-16 purch-ui-adjust ▸
PURCH 採購單畫面調整
日期:2026-07-16
變更內容
- 表頭版面:唯讀欄位(輸入人員、總數量、原幣金額、本幣金額)移到「是否結案」下方集中顯示,標籤顏色統一為系統產生欄顏色;傳真日期移至左欄補位。
- 發送供應商協同按鈕:從採購單號旁移到表頭最右側,獨立成一個直欄與其他欄位區塊並排。
- 運送方式:表頭與明細表格內的下拉選單改為只顯示名稱(原先為代號+名稱兩欄併排),上下兩處樣式一致。
- 明細表格「結案」「須否成績表」勾選欄經查與增刪修狀態本來就同步(EF 變更追蹤保證),行為不變。
- 本幣金額改顯示本幣合計:原先與原幣金額綁同一個合計值(兩欄永遠同數字),現改為各自加總明細的原幣未稅/本幣未稅。
影響範圍
僅 PURCH 畫面呈現;共用下拉控件新增的「只顯示名稱」模式為選用(預設關閉),其他程式不受影響。
-
07-16 dash-history-retention ▸
行動儀表板網站:歷史報表保留+多公司發布專案參數
日期:2026-07-16
變更內容
每次發布保留歷史(原本只留最新一份)
主管行動儀表板網站(Cloudflare Pages,
tserp-dash)原本每次排程發布會整站替換,只看得到最新一期報表。現在:- 每次發布時,來源檔會先累積到發布機的歷史夾(
%ProgramData%\TsERP\dash-archive\<專案名>\,檔名含期間,同一期重發覆蓋不重複),再連同全部歷史一起上傳。
- 首頁不變:打開網站仍直接是最新一期報表,右下角多一顆「🗂 歷史報表」浮動按鈕。
- 點入
history.html是各期清單(最新置頂,附產出時間),點任一期可看當期完整報表。
- 佔位頁模式(
-Placeholder,事故蓋台用)不帶歷史;本機歷史夾不受影響,下次真實發布即還原。
多公司:排程參數可指定發布專案
排程任務
Customdash_ScheduledDeck新增參數「發布專案」:- 空白=預設
tserp-dash(現行行為不變,既有排程事件不用改)。
- 填專案名=發布到該 Cloudflare Pages 專案(一家公司一個專案、各掛各的 Access 白名單);歷史夾也按專案名分開。
- 新公司啟用前置:在 Cloudflare 建同名 Pages 專案、掛 Access(**必須含
<專案>.pages.dev與*.<專案>.pages.dev兩筆**,缺一即漏)、無痕實測被擋後才發真實數據。
影響範圍
tools/dash-publish.ps1:新增-ArchiveDir參數;dist 打包邏輯改為「最新 index.html+歷史檔+history.html」。
AutoPilot/Customdash_ScheduledDeck.cs:DefaultParameter加「發布專案」,TryPublishMobile帶入-ProjectName。
- 既有排程事件參數不需調整;下次日報發布起自動開始累積歷史。
- 每次發布時,來源檔會先累積到發布機的歷史夾(
-
07-16 canswitch-allow-validation-errors ▸
2026-07-16 表單有驗證錯誤時允許切換其他程式
使用者可見變動
- 表單欄位有紅框(驗證錯誤)時,現在可以直接切換到其他程式。以前只要目前畫面有任何欄位驗證錯誤,點選單裡的任何程式都沒有反應、也沒有任何提示,體感像系統當掉;打單打到一半想切去別支程式查資料會被卡住。
- 切換後資料不會遺失:切走再切回來,打到一半的內容與紅框都還在(程式畫面有快取)。
- 資料正確性不受影響:存檔時仍會完整驗證,有錯誤的資料照樣存不進去。
(此變更取代 2026-07-15 changelog 中「表單有欄位驗證錯誤時切換其他程式被擋的行為維持不變」的敘述——2026-07-16 裁決改為放行。)
技術面
ViewModel/ProgramNavigator.cs:CanSwitch移除第一段「目前畫面有驗證錯誤 → 對所有目標程式回 false」的檢查。
TsERP/ScreenshotAutomation/ScreenshotRunner.cs:同步更新引用該行為的註解(批次截圖仍以權限存在性判定,避免建 VM 失敗跳錯誤窗打斷批次)。
-
07-16 acc-scan-depth-cap ▸
2026-07-16 ACC_SCAN 新增「展開位數上限」(第 5 參數)
變動
ACC_SCAN新增第 5 參數=展開位數上限:ACC_SCAN('目標','範圍別','範圍內容',抬頭,位數上限)。控制逐科目展開時「列到科目代號幾碼為止」,省略=4(多數帳套的明細科目層級)。
- 逐科目展開的結構(大/中/小分類標頭、層級縮排、每科目一列)維持不變。
- 代號長度超過上限的子科目不各自成列,金額由其較短碼的母科目那一列以
%前綴合計併入——母科目公式自動變成ACC_xxx('代號%')(例:ACC_IS('1101%')涵蓋 1101 及其所有子科目);母科目底下無更深子科目時公式不帶%。- 母子科目同時成列不重複計數:母科目與其子科目都在上限內、都成列時(如統制科目 110 與 4 碼 1101 並存),母列只計自身與「未各自成列的子科目」,不用
110%吞掉已成列的 1101;保證每個科目金額在整份展開中恰被計入一列。- 孤兒保底:超過上限、但沒有可併入的短碼母科目(母科目不在掃描範圍內)的子科目,仍個別列出,金額不漏。
- 要展更細:把第 5 參數調大,例如
ACC_SCAN('IS','L','營業費用',1,6)會把 6 碼子科目也各自列出。
R範圍別一樣套用位數上限規則(平鋪、不補分類標頭)。
- 參數檢查:第 5 參數若填非正整數(含 0、負數、非數字),公式檢查會報「錯誤」級(第5參數展開位數須為正整數)。
- 兩種引號寫法(各自引號
('IS','L','營業費用',1,6)與一組引號("IS,L,營業費用,1,6"))都支援;減項(公式前加-)維持整段以減項計入。
影響範圍
自訂財務報表(ACC_SELFRPT)查詢與 ACC_RPT「模擬表預覽」中的
ACC_SCAN展開結果。既有寫ACC_SCAN的報表列不需改設定——省略第 5 參數者一律套預設 4 碼上限(子科目金額併入母科目列);要維持逐科目展到更深,補上第 5 參數即可。 -
07-16 acc-formula-wildcard ▸
2026-07-16 自訂財報公式新增「含子科目」寫法(前綴 %)
使用者可見變動
- 自訂財報(Acc_selfrpt)的算值公式,科目參數多了一種「含子科目」寫法:在科目代號後面加
%。例如ACC_IS('1101%')會加總所有以1101開頭的科目——含母科目1101本身與其下所有子科目(110101、110102…)。
- 適用四個算金額的函式:
ACC_IS、ACC_ISA、ACC_BS、ACC_SC。
- 解決的痛點:母科目底下掛子科目、明細金額都記在子科目上時,舊的單一代號寫法
'1101'是完全比對、算不到子科目,使用者得手動湊一段區間才行;現在寫'1101%'一次到位。
- 既有寫法行為完全不變:單一代號
'1101'仍是完全比對(不含子科目)、區間'1101~1199'仍照起迄加總。
!!! warning "
%要放結尾、且是整段前綴比對"%只能放在科目代號最後面當前綴合計,不是萬用字元。前綴是整段比對:'1101%'不會把1102算進來;要同時涵蓋1101與1102,請用共同母層前綴'110%'或區間'1101~1102'。技術面
LogicBll/N.GeneralLedger/Util_Acc.cs:新增ParseGLAccountRangehelper 統一解析科目參數(單一代號/區間/%前綴),四支函式改呼叫它。前綴模式把「迄值」定為三個資料來源(TmpSliySum/TmpSliyyear/TmpBudget)中最大的同前綴科目代號,讓既有的string.Compare起迄過濾天然涵蓋所有子科目;幣別/部門/借貸/預算/期初等其餘分支一行未動。
- 之所以選
%而非*:公式引擎AccSelfReportEvaluateBll.DecodeFormula會對原始公式字串以運算子(+ - * /)切割,引號內的*會被誤當乘號切壞公式;%不在運算子集合,安全。
LogicBll/N.GeneralLedger/Acc_selfrpt/AccFormulaChecker.cs:公式檢查的科目存在性驗證同步支援%前綴(改用StartsWith判定),查無時沿用原警告訊息。
- 自訂財報(Acc_selfrpt)的算值公式,科目參數多了一種「含子科目」寫法:在科目代號後面加
-
07-15 customdashcfg-ui-tweaks ▸
2026-07-15 自訂面板配置(CUSTOMDASHCFG)操作性調整
變動內容
- 查詢清單可直接拖曳排序:在「自訂面板配置」的查詢清單內按住項目上下拖曳即可調整順序(=看板查詢與匯出的排序);原本的「上移/下移」按鈕保留。
- 彙整列印報表下拉改顯示中文報表名稱:原本顯示報表檔名(如
Balance1),改顯示報表抬頭(如「資產負債表」)。查詢清單項目下方與看板側「已選報表」的顯示同步改為中文;舊配置沒存過中文抬頭時仍顯示檔名,重選一次報表即更新。
- 版面精簡:拿掉配置表單外圍的「配置」群組框。
- 匯出項目分頁文字放大(字級 12 → 14),並將分頁與面板內控件統一為 Ts 系列控件(TsTabControl/TsLabel/TsTextBlock/TsComboBox/TsTextBox)。
相容性
- 配置 JSON 新增選填欄位
報表抬頭(僅供顯示;彙整列印比對仍用報表編號),舊配置照常讀取,無需轉檔。
- 修正開窗時右上稽核面板的綁定錯誤:
twork_sys_customdashconfig補上標準審核五欄(聯絡單id/工作流程/審核人員/審核日期/已審核)。部署需先跑sql/customdashconfig-add-audit-columns.sql再更新程式(dev 已跑;正式機待跑)。
-
07-15 customdash-export-company-name ▸
2026-07-15 自訂查詢面板匯出 HTML 標題改用公司名稱
變動
- 自訂查詢面板「匯出HTML」與排程報表產出的封面/瀏覽器標題,原本固定顯示「禾久」,改為讀系統設定的公司名稱(公司基本資料 codata 的公司名稱欄)。
- 平台層
DeckExportOptions.公司名預設值不再寫死客戶名,未帶入時留空,避免其他客戶匯出印成禾久。
影響範圍
自訂查詢面板匯出 HTML、排程報表(ScheduledDeck)各格式輸出、行動版儀表板 HTML。
-
07-15 crash-recovery-and-open-check ▸
2026-07-15 崩潰復原改進與全程式開窗體檢
使用者可見變動
- 程式畫面崩潰不再拖垮整個系統:某支程式開啟時若持續發生錯誤(例如畫面元件載入失敗),以前會連跳數次錯誤視窗後整個 ERP 自動關閉;現在改為:第一次只提示錯誤,若同一錯誤重複發生,系統自動把壞掉的畫面清空,其他程式照常使用。
- 「系統錯誤」視窗現在會顯示是哪支程式發生錯誤(內文第一行「程式:XXX」)。以前錯誤訊息可能在切換到下一支程式時才彈出,容易誤判是新程式的問題。
- 表單有欄位驗證錯誤時切換其他程式被擋的行為維持不變;但程式畫面「建立失敗」的殘留狀態不再令所有程式都無法切換。
追加(同日晚間):舊頁面批次修復
- 18 支原本打不開的程式恢復可用:傳票(SLIY)、客戶資料(CUDATA)、財產目錄(ASSET)、銀行資料(BANK)、發票系列(TICKMIN/TICK3/TUTAX)、MRP、庫存查詢(INVSTK/INVBK1)等。成因為三層歷史問題疊加:舊 TsPage 頁面進不了新容器、查詢條件元件未註冊、畫面模板未登記。
- 44 支舊 TsPage 頁面完成 TsView 遷移;15 支確認尚未移植(薪資、成本、群組維護等,屬移植待辦非故障)。
技術面
TsERP/App.xaml.cs:全域例外處理改「重發才復原」策略(ADR-0103)。
ViewModel/ProgramNavigator.cs:CanSwitch對半毀 context 加 null 防護。
TsERP/ScreenshotAutomation/ScreenshotRunner.cs:批次截圖模式強化(單支 45 秒逾時、結果逐筆落檔、登入等待 60 分、權限判定去污染)。
- 全程式開窗體檢結果與後續修復清單:
.claude/tmp/opencheck-20260715/REPORT.md。
追加(深夜):查詢條件面板統一
- 15 支查詢程式的查詢條件改到畫面下方的標準查詢區(原本各自畫在畫面上方):總務入庫帳簿、營業稅媒體申報(401)、MRP、庫存查詢、庫存帳簿、庫齡、樞紐、預測、FillRate、Itemship、AR/AP 查詢、採購查詢、表格設定等。條件內容與預設值不變。
- 這批程式先前無法開窗的問題一併解決;排程報表現在能正確記住這些程式的查詢條件(ADR-0105)。
-
07-15 calendar-dot-permission ▸
2026-07-15 行事曆圓點尊重權限
變動內容
- 主視窗右側行事曆的日期圓點(提示當天有事件)改為只統計使用者有權限看的事件。修正前:非管理員雖然在下方清單看不到「系統」類事件,但只有系統事件的日期仍會畫圓點,等於洩漏了看不到的資料存在。
- 「今天沒有事件」與「已被篩選隱藏」的判斷同步改用權限過濾後的事件,無權限的事件不再被當成「被篩選隱藏」。
- 「個人/部門/公司」勾選是暫時的顯示篩選,行為不變:取消勾選只影響下方清單,圓點照常顯示。
-
07-15 alert-sources-batch2 ▸
2026-07-15 主動警示第二批:六個新警示源+信件風格統一
新增警示源(warning 信件,於「警示規則」程式啟用與設定門檻)
警示類型 內容 預設門檻 採購逾期未交(PO_OVERDUE) 未結案採購單,預訂交期逾期且尚有未交量,按廠商彙整通知採購 逾期 3 天 委外逾期未交(WK_OVERDUE) 未結案委外派工單,預訂完成日逾期且尚有未交量 逾期 3 天 呆滯庫存(STAGNANT_STOCK) 有庫存但長期無任何出入庫異動的品項(含從無異動紀錄者) 180 天、明細列前 200 筆 退票警示(CHECK_BOUNCE) 收票發生退票(已兌退票/未兌退票/票貼退票)即時通知財務 回看 7 天 排程健康監控(SKD_HEALTH) 排程執行失敗或執行中卡死,通知系統管理員 回看 24 小時、卡死 60 分鐘 郵件佇列監控(MAILQ_STUCK) 通知信死信/滯留/卡鎖,通知系統管理員 滯留 2 小時 - 全部沿用警示框架(ADR 0092):規則表門檻 JSON、收件人設定、重複警示抑制。
- 新規則預設停用,需在警示規則程式逐項啟用並填收件人。
- 排程掛載:行事曆事件設「執行方法+Dispatcher=SKD」即可定時觸發(同安全庫存警示作法)。
信件風格統一
- 所有系統警示信改用同一套版面(深藍表頭、紅色警示強調、統一字體字級);風格集中於
資料庫函數
TWORK_FN_HTML_STYLE,日後調整一處生效(ADR 0104)。- 朝陽「送樣未合格通知」信件由無樣式舊版改為標準版面(內容欄位不變)。
部署注意(正式機)
1. 先跑
sql/html-fn-deploy.sql(風格函數,警示 SP 相依它)。2. 再跑各警示源 deploy:
po-overdue、wk-overdue、stagnant-stock、check-bounce、skd-health、mailq-stuck,以及 refit 後的ar-overdue-deploy、check-due-deploy。3. CY 另跑
cy-sample-notify-restyle-deploy.sql(送樣通知改版)。4. 皆需
sqlcmd -f 65001(含中文),跑完看各檔結尾驗證區。 -
07-15 acc-scan-lineno-headers ▸
2026-07-15 ACC_SCAN 展開補序號/分類標頭縮排/模擬表列號修正
變動
- ACC_SCAN 展開列帶序號:展開出來的每一列序號=母公式列序號+子流水(如
000005-01),在模擬表預覽與查詢結果中可直接看出該列由哪條掃描公式產生。純顯示用,不寫回報表設定。
- L/M/S 掃描自動產生分類標頭與縮排:依大/中/小分類補純文字標頭列(無公式),縮排比照 ACC_BSCE——大分類 0 格、中分類 2 格、小分類 4 格、科目列 6 格。R(科目範圍)掃描維持平鋪不變。
- 模擬表預覽列號修正:原本列號出現 1、10、11、2 跳著排——根因是
_sheetno的 ACC_RPT 序號長度登記為 0,列號完全不補零,格線字串排序就亂了。現列號寬度至少取總列數位數,保證等寬可排序。
- 模擬順序修正:新增尚未存檔的公式列(序號空白)原會排到模擬結果最前面,改排最後(與存檔後被編到尾端一致)。
影響範圍
自訂財務報表(ACC_RPT 維護的「模擬表預覽」按鈕)與 ACC_SELFRPT 查詢的 ACC_SCAN 展開結果。既有報表不需改設定。
- ACC_SCAN 展開列帶序號:展開出來的每一列序號=母公式列序號+子流水(如
-
07-14 workflow-approval-fix ▸
2026-07-14 簽核流程修復(送簽通知、核准生效、退件回上一關)
行為修復(原本壞掉、現在會動的)
- 核准真正生效:按「同意」後,關卡完成率確實更新、全部關卡完成時來源單據會蓋上
審核章(已審核=Y)並鎖定不可修改。(修復前核准只在畫面上看起來成功,後端從未寫入。)
- 代理人可以簽核:有被設定為代理人(組織代理關係)的使用者,現在可以代處理人核准;
修復前代理判定永遠失敗、只有本人能簽。
- 取消流程生效:取消後流程正確結案。
行為變更
- 退件改為「退回上一關」:在第 N 關按退件,流程回到第 N-1 關重新簽核(退件說明會記錄);
在第一關退件則整個流程退回發行者重新開始。修復前退件一律整個流程重來。
- 簽核通知改走郵件佇列:送簽、核准(通知下一關)、退件三種事件都會發信通知對應處理人,
由排程服務統一寄送(含失敗重試);寄信失敗不影響簽核動作本身。
- 待簽清單預設範圍:預設只列「本人+代理」的待辦;查看下屬待辦的分頁仍在,
但簽核動作僅限本人與代理人。
- 送簽通知改為單一來源(存檔成功後發),修正同一位簽核人收到兩封送簽通知的問題。
-
07-14 supplier-collaboration-portal ▸
2026-07-14 供應商協同入口(採購單交期回覆)
新增
- 發送供應商協同:採購單(PURCH)新增「發送供應商協同」按鈕,對當前採購單產生一次性
安全連結、寄信給供應商。供應商用手機或電腦開連結,即可看到採購單明細(品項、數量、需求交期;
不含單價與金額)並回覆:一鍵確認訂單、逐行調整交期(可含數量)、或拒接並附備註。
- 供應商回覆審閱(POCOLLABRPY,掛在採購模組):採購人員檢視供應商回覆,逐行對照原交期與
供應商回覆的新交期,決定「套用交期到採購單」或「忽略」。套用後才會更新採購單的預訂交期並留下紀錄;
系統不會自動改單。
- 逾期未回提醒:供應商在期限(預設發送後 14 天、到期前 3 天起)內未回覆,系統會寄信提醒
當初發送的採購人員(一天一封彙整)。此提醒預設關閉,由警示規則啟用。
安全與行為
- 供應商連結有 14 天效期、可撤銷;重新發送會使舊連結失效。
- 連結本身即權限(無需帳號密碼),請勿轉發給非供應商。
- 入口只顯示該採購單的明細,不顯示任何金額;供應商無法看到其他採購單或其他供應商的資料。
- 供應商的回覆為「快照」,採購人員審閱後手動套用,不即時改動採購單。
-
07-14 mobile-dashboard ▸
2026-07-14 主管行動端儀表板(排程寄送行動版 + 受控網址)
新增
- 行動版報表格式
HTMLMOBILE:排程報表(行事曆事件Customdash_ScheduledDeck)的
「格式」參數新增
HTMLMOBILE(別名MOBILE),產出手機直立可讀的卡片流 HTML,檔名尾為
_mobile.html;可與HTML、EXCEL等並列多選。- 寄信標註:信件內文會把行動版附件標為「(行動版)」並提示用手機瀏覽器開啟。
- 發布到受控網址(選用):排程事件參數新增「發布網址」(預設不啟用);設
Y時
寄信成功後自動把最新行動版推上受 Cloudflare Access 保護的網址,主管手機開網址即看。
需在 worker 環境設定 Cloudflare 憑證與
DASH_ACCESS_CONFIRMED=Y(Access 驗證完成的明示確認)。行為變更
- 排程報表檔名加期間段:
<配置名>_<期間>_<產出日>(期間=目標月 yyyyMM 或「當期」),
例
財務報表_202606_20260714_mobile.html。原因:同配置的日報與週報同日產出時舊檔名會互相覆蓋。保留天數清理同時認得新舊兩種檔名,既有舊檔照常清理。
- 行動版隱藏零值:整列全為 0 的資料列不顯示;數值欄的 0 顯示為空白(代號欄如「0001」不受影響)。
桌機版 HTML/Excel 不變。
- 行動版報表格式
-
07-14 i18n-coverage ▸
2026-07-14 多語言覆蓋補完
改善
- 多語言覆蓋率大幅提升:全系統畫面(XAML)的多語言真實覆蓋率從約 29% 提升到約 74%。
原本大量畫面標籤、表格欄位標題是寫死的中文或英文,切換英/日/越語系時會露出原文;
本次把有多語言基礎的一般程式補齊四語(繁中/英/日/越),切語言時會正確翻譯。
- 英文介面中文化:部分畫面(多為進退貨、統計、報表頁)表格欄位標題原本是英文(如 Line No、SKU、
Unit Price),現已改為中文並補上多語言,中文介面不再露出英文欄名。
修正(順帶清理的既有問題)
- 移除 25 個「永遠空白」的欄位:這些表格欄位綁定到不存在的資料屬性,任何情況下都顯示空白(既有缺陷),
已移除。
- 下架一張空白舊頁:應收對帳的舊列印預覽頁(已被新版取代、開啟即空白)已下架。
已知限制
- 少數畫面(客戶專屬客製版、部分舊式視窗)尚未納入,之後按需補做。
- 自動翻譯的專業術語建議由熟悉業務的人員過目校正。
- 部分表格欄位標題在非中文語系下仍顯示中文(底層命名機制的既有限制,中文顯示不受影響)。
-
07-14 grpm-usage-tab ▸
2026-07-14 群組表維護(GRPM):新增「使用狀況查詢」分頁
變更
- 群組表維護畫面改為兩個分頁:
- 群組資料:原本的群組維護內容(欄位、明細)完全不變。
- 使用狀況:查出目前這個群組代號被哪些主檔資料引用,結果列在表格。
- 使用狀況分頁行為:
- 切到分頁時,依「群組別」自動查對應主檔(品號→品號檔、客戶→客戶檔、廠商→廠商檔、科目→科目群組、總務品號、費用、工作中心、稽核)。
- 上方顯示目前群組代號與群組別;提供「查詢」按鈕可手動重新整理。
- 隨主檔上一筆/下一筆切換自動更新(同一筆重覆切分頁不會重覆查詢)。
- 群組別為「區域」或未設定時,顯示「此群組別尚未支援使用狀況查詢」。
影響範圍
TsERP/B.BasicData/Grpm.xaml(加分頁)、ViewModel/B.BasicData/Grpm/GrpmViewModel.cs
- 新增
LogicBll/B.BasicData/GrpmUsageBll.cs
- 查詢走既有通用查詢 SP(DARB_GETDATA4),不需部署任何資料庫物件。
詳細取捨見 ADR 0099。
-
07-14 customdashcfg-split ▸
2026-07-14 自訂查詢面板瘦身+新程式「自訂面板配置」(A.系統資料)
變更
- 新程式「自訂面板配置」(A.系統資料,標準增刪修程式):自訂查詢面板的配置管理集中到這裡——
- 標準工具列:瀏覽(只列自己的配置)、新增、修改、刪除、存檔。
- 表單:配置名稱、使用部門。
- 「查詢清單」分頁:組裝配置內容(選查詢程式→原生條件畫面設條件→加入/更新條件/移除/清空、每項自訂標題、上移/下移),並可對選中的查詢直接下拉改「彙整列印報表」。
- 「匯出項目」分頁:直接內嵌在畫面上(不再開視窗)——拖曳排序匯出頁順序、新增/編輯/停用報表與圖表顯示項目;「儲存顯示項目」立即生效(全部配置共用),匯出順序則隨「存檔」存進該配置。
- 自訂查詢面板調整:
- 查詢區:既有設置下拉(選了即載入)、查詢清單、目標月份+整批換月;點查詢清單的項目會顯示該查詢的條件畫面,可臨時調整後按「更新條件」(只影響本次,不會改配置)。
- 儲存設置、刪除設置、配置名稱、使用部門、選程式/加入/移除/清空等管理功能移除(改到「自訂面板配置」操作);主工具列移除「匯出設置」鈕,保留 彙整列印、匯出HTML。
- 排程報表(ScheduledDeck)的匯出頁順序改為套用配置存的「匯出項目順序」,與手動匯出一致。
影響範圍
- 新程式需登錄後才可用:
sql/customdashcfg-register-program.sql(選單+瀏覽用_sheetno,待部署;開發環境 dev-programs.json 注入+重登,但瀏覽也需要先跑 SQL 的_sheetno段)。
- 既有配置完全相容;看板選配置、查詢、列印、匯出行為不變。
詳細取捨見 ADR 0096。
-
07-14 accl-tier-cascade ▸
2026-07-14 — 會計科目維護:分類連動與群組代號
會計科目維護(Accl)
- 大分類/中分類/小分類三個下拉連動:
- 選了大分類,中分類與小分類的選項自動縮小到該分類底下。
- 選了中分類,會自動帶入大分類;選了小分類,會自動帶入大分類與中分類(可對應到多個上層時不亂帶,維持原值)。
- 選上層分類不會清掉已填的下層分類,只縮小選項。
- 新增「群組代號」欄位:可搜尋科目群組(群組表中群組別=科目的群組),選了之後自動帶入大/中/小分類,群組代號會隨科目儲存。
- 分類下拉的選項來源(摘要檔)與科目群組表已依現有科目資料重建完成;分類資料有疑義的科目已另列清單待與客戶確認。
注意(IT/部署)
- 本次需搭配資料庫腳本
sql/accl-tier-grpm-seed.sql(新增 accl.群組代號欄+重建摘要檔與科目群組)。先跑腳本再發版,否則開啟會計科目維護會出錯。
-
07-14 acc-selfrpt-percentage-fix ▸
2026-07-14 — 自訂財報百分比欄修復
自訂財報(ACC_SELFRPT)
- 修復:百分比欄位一律顯示 0 的問題。報表定義(acc_rpt)「百分比基準」欄填
Y的那一列,現在會正確作為基準——全表每列的 當期百分比/總計(合計)百分比/當月百分比 = 該列值 ÷ 基準列值 × 100(四捨五入取兩位;基準值為 0 時該欄為 0)。原因:查詢建立輸出列時漏帶「百分比基準」欄位,導致引擎永遠找不到基準列。
- 修復:列印/匯出(N130 報表)「今年當期百分比」誤印成「今年總計百分比」的欄位錯置。
使用方式
在財務報表格式維護(acc_rpt)想當分母的那一列(例如「銷貨收入」或「營業收入合計」)的「百分比基準」欄填
Y即可;一張報表取第一個Y的列為基準。 - 修復:百分比欄位一律顯示 0 的問題。報表定義(acc_rpt)「百分比基準」欄填
-
07-14 acc-scan-formula ▸
2026-07-14 — 自訂財報新增 ACC_SCAN 掃描公式與模擬表預覽
自訂財報公式(ACC_SELFRPT)
- 新增
ACC_SCAN掃描函數:一列公式自動展開成多列(每個符合條件的會計科目一列,抬頭=科目名稱)。
- 寫法:
ACC_SCAN('ISA','L','營業費用',1)- 參數1=目標函數:
ISA、IS、BS、SC、CF(展開成ACC_ISA('科目')等)- 參數2=範圍別:
L大分類、M中分類、S小分類、R科目範圍- 參數3=分類內容,或
R時的起始科目~截止科目- 參數4=抬頭:
1=科目名稱(目前僅此一種,可省略)- 前面加
-(如-ACC_SCAN('ISA','L','營業收入',1))可讓展開的每列公式都帶負號。- 引號寫法兩種都可:每參數各自引號,或一組引號內含逗號(
ACC_SCAN("ISA,L,營業費用,1"))。財務報表格式維護(acc_rpt)
- 新增「模擬表預覽」按鈕:不需執行查詢,直接列出目前公式明細展開後的報表列(列號/序號/抬頭/公式/列印碼),方便確認 ACC_SCAN、ACC_BSCE 會展出哪些科目。
- 注意:
ACC_BSAUTO依實際查詢期間有異動的科目展開,模擬時不會產生列。- 新增「公式檢查」按鈕:一鍵檢查所有明細公式,結果依嚴重度分級列出。
- 錯誤(查詢會當掉或必然算錯):函數名打錯或大小寫錯、括號/引號不配對、
ACC_SCAN/ACC_BSC參數不合法、ACC_ISTB引用的單一序號不存在。- 警告(不會當,但結果必為 0 或空):科目/分類/引用序號範圍查無資料、
ACC_SCAN展開後 0 列、ACC_ISTB引用計算順序排在自己後面的列、展開巨集同一列混寫其他內容。- 檢查不需執行查詢;全部通過時直接提示「未發現公式設定問題」。
- 新增
-
07-13 tscombobox-items-tooltip-fix ▸
下拉選單項目提示(ToolTip)修正:不再顯示程式型別名稱
日期:2026-07-13
使用者可見變動
- 自訂查詢面板 →「彙整列印」選擇報表的下拉選單:滑鼠移上時的提示(ToolTip)原本會顯示
ViewModel.Control.Layout.PrintLayout.ReportPrintSource之類的程式型別名稱,現在正確顯示該下拉內的報表清單(例:1.出貨日報表、2.應收帳款明細逐行列出)。
- 無報表而停用的查詢列,滑鼠移到下拉上現在會顯示「無報表的查詢無法列印」的原因提示(先前停用狀態不會出現任何提示)。
- 本修正在平台層(TsComboBox)生效:所有使用
DisplayMemberPath顯示自訂物件清單的下拉選單,若曾出現同樣的型別名稱提示,一併修復。
備註
- 根因:下拉項目提示在「項目來源已設定、顯示欄位路徑尚未生效」的瞬間產生,取不到顯示文字時退回物件預設字串(即型別全名),且之後不會重算。現改為顯示欄位路徑生效時重新產生提示。
- 純前端控件修正,無資料庫部署需求;runtime 尚未開窗驗收。
- 自訂查詢面板 →「彙整列印」選擇報表的下拉選單:滑鼠移上時的提示(ToolTip)原本會顯示
-
07-13 scheduled-report-deck ▸
排程報表自動寄送:任何自訂查詢面板配置可排程產檔寄信
日期:2026-07-13
使用者可見變動
- 新排程方法「排程報表自動寄送」(自動執行方法
ScheduledDeck):在行事曆排程事件掛上後,系統會定時把指定的自訂查詢面板(CUSTOMDASH)儲存配置整頁跑一遍(含各分頁查詢與圖表),產出 Excel+HTML 檔,作為附件自動寄給指定收件人——財務部月報、業務月報從此無人值守。
- 排程參數:配置 pkid、格式(預設 EXCEL,HTML)、收件人(逗號分隔,必填)、輸出目錄(預設
C:\temps\排程報表\)、月份(支援{-d1}上月自動平移——每月 1 號排程自動產「上個月」的報表)、保留天數(預設 30)。
- 郵件佇列支援附件:排程信可帶多個附件;既有寄信行為不變。
- 產出檔留存:檔案保留在輸出目錄供事後稽核,超過保留天數的舊檔於下次排程自動清理(只清本功能產出的檔案,不動目錄中其他檔案)。
- 排程事件清單上的顯示文字為人話摘要,例:「排程報表:配置#3(當期)→ 收件人 2 人,格式 EXCEL,HTML」。
備註
- 需在排程器(SchedulerWorker)設定檔設定 headless 登入帳號(
ScheduledDeck節);正式環境建議帳密改走 Azure Key Vault。
- PDF 格式本期未支援(匯出引擎無 PDF writer),指定 PDF 會記警告略過。
- 正式環境部署需執行:
sql\mailqueue-attachment-deploy.sql(附件欄+DEQUEUE SP)、sql\mailqueue-enqueue-deploy.sql、sql\alertlog-skd-deploy.sql、sql\autopilotmethod-register-deploy.sql(選用字典)。
- 同步修正:金流跌破警戒警示(ADR 0092)的排程資料存取改走排程派發器,修正排程環境下無法入列的問題。
對應 ADR 0093;沿用 ADR 0018(郵件佇列)、0065(集中自動化庫)、0083(配置持久化)、0088(彙整匯出)。
- 新排程方法「排程報表自動寄送」(自動執行方法
-
07-13 preview-toolbar-and-merged-watermark ▸
2026-07-13 報表預覽:按鈕順序調整+彙整浮水印修正
變更
- 預覽工具列按鈕換位:「列印」與「匯出PDF」對調,順序改為 列印 →(中一刀列印)→ 匯出PDF → 匯出EXCEL → 搜尋 → 浮水印 → 大綱。
- 修正:自訂查詢彙整列印(合併 PDF)預覽套浮水印後,多支報表只剩一支。原因是 FastReport 內建浮水印「套用到全部頁面」會整份重新產生報表,合併自多支範本的頁面因此被洗掉。修正後浮水印直接套用在已備妥的頁面上,各報表內容保持完整;套完即可照常「匯出PDF」。
影響範圍
TsERP/TsFastReportPreview.xaml(按鈕順序、浮水印鈕改自訂處理)
TsERP/TsFastReportPreview.xaml.cs(合併報表浮水印安全路徑)
單一報表預覽的浮水印行為不變。
-
07-13 customdash-month-shift-year-rollover ▸
CUSTOMDASH 整批換月:自訂財報跨年時年度連動
日期:2026-07-13
變更
自訂查詢面板(CUSTOMDASH)的「整批換月」碰到自訂財報(ACC_SELFRPT)時,當期的年度與月份改為一起真實平移:
- 跨年換月時
年度會跟著進位/回溯(例:2026 年 12 月換到下個月 → 2027 年 1 月)。
- 舊行為是年度固定、月份夾在 1–12(12 月 +1 仍停在 12 月),已取消。
- 起訖月份平移後若跨在兩個年度(如 11–12 月換到 12 月與隔年 1 月),年度以截止月份的落點為準,起始月份調整到該年度邊界。
- 截止日期(如 12/31)維持不動。
排程報表自動寄送(ScheduledDeck)的換月走同一套邏輯,行為一併更新。
相關決策:ADR 0089(2026-07-13 修訂段)。
- 跨年換月時
-
07-13 customdash-export-setup ▸
2026-07-13 自訂查詢面板(CUSTOMDASH):新增「匯出設置」畫面(拖曳排序+項目維護)
變更
- 工具列新增「匯出設置」按鈕,開啟匯出內容設置畫面:
- 左側清單列出目前面板各查詢的顯示項目(報表/圖表),可拖曳調整順序(也提供上移/下移按鈕),順序即「匯出HTML」的頁面順序。
- 右側可編輯選中項目的完整定義:名稱、圖型、類別欄/數值欄/顯示欄位(下拉提供查詢結果欄位候選)、排序、TopN、篩選、欄位別名、計算欄、逐欄展開。
- 可新增顯示項目、停用(停用列不再出現在匯出勾選清單,設置畫面標灰可重新啟用)。
- 儲存時逐列驗證;若目前有選定配置會詢問是否同步更新該配置的匯出順序。
- 匯出順序會隨「儲存設置」存進配置,下次套用同配置匯出時自動套用;未調整過順序時行為與先前完全相同。
影響範圍
- 新畫面
TsERP/M.EIS/匯出內容設置.xaml+ViewModel/M.EIS/CustomdashExportSetupViewModel.cs
twork_sys_chartspec改為可由程式寫回(LogicBll/CommonSystem/ChartSpec/ChartSpecBll.cs;表遷移見sql/chartspec-maintain-deploy.sql,需部署)
- CUSTOMDASH 儲存配置 JSON 結構升級為 wrapper(舊配置自動相容)
詳細取捨見 ADR 0095。
-
07-13 customdash-export-hide-zero ▸
2026-07-13 自訂查詢面板(CUSTOMDASH)匯出:新增「隱藏零值」勾選
變更
- 「匯出HTML」的勾選對話框新增「隱藏零值」選項,預設勾選,可取消:
- 資料列中所有數值欄皆為 0 的整列不匯出(純文字列與合計列不受整列過濾影響)。
- 數值為 0 的儲存格顯示空白,不再顯示 0(含合計列)。
- HTML 與 EXCEL 兩種匯出格式皆適用(EXCEL 目前預設未開啟產出,開啟後同樣生效)。
- 取消勾選時輸出與先前完全相同;排程寄送(ScheduledDeck)路徑行為不變。
影響範圍
LogicBll/CommonSystem/Reporting/ReportDeckDtos.cs(DeckExportOptions.HideZeroValues)
LogicBll/CommonSystem/Reporting/HtmlDeckWriter.cs、ExcelDeckWriter.cs(整列過濾+零值留白)
ViewModel/M.EIS/CustomdashExportSelectViewModel.cs、CustomdashViewModel.cs
TsERP/M.EIS/自訂查詢匯出選擇.xaml(新增勾選框)
-
07-13 alert-notifications ▸
主動警示通知:應收逾期/票據到期/金流跌破警戒自動寄信
日期:2026-07-13
使用者可見變動
- 新增三種自動警示信(由排程觸發,經既有郵件佇列寄出):
- 應收逾期帳款通知:逾期超過門檻天數(預設 30 天,可調)的未沖應收清單,含客戶/單號/到期日/逾期天數/金額與合計。
- 票據到期通知:未來 N 天內(預設 7 天,可調)到期的收票/付票清單(收付票可分別開關),含票別/票號/到期日/金額。
- 金流預測跌破警戒通知:金流預測的累計淨額首次跌破警戒線時通知,含首次跌破月/警戒線/最低累計淨額。只通知首次跌破——跌破月與警戒線沒變不會重寄。
- 同一警示不轟炸:警示內容沒變時,抑制視窗(預設 24 小時,可調)內不重寄;內容有變(例如逾期名單多了一張單)會照常通知。
- 警示設定集中維護:門檻、收件人、啟用開關、抑制時數收斂到新的警示規則設定(警示規則維護頁);規則未設收件人時沿用行事曆事件的「通知帳號」,既有安全庫存警示行為不變。
- 金流預測畫面的「資金警戒線」數值現在可持久化到警示規則(原本只在畫面上手填、關窗即失)。
備註
- 通知通道本期為 Email(Mailgun)。LINE Notify 服務已於 2025-03-31 終止,如需 LINE 通知須另行申辦 LINE 官方帳號走 Messaging API,列為後續選項。
- dev 環境已完成三輪功能實測與排程器端到端真寄驗證;正式環境需部署:
sql\alertrule-deploy.sql、sql\alertlog-deploy.sql、sql\ar-overdue-deploy.sql、sql\check-due-deploy.sql(正式機 proc_param 為 IDENTITY,用腳本檔頭註明的不帶 pkid 版)。
- 金流跌破警示的排程實跑(行事曆事件觸發)尚未 runtime 驗收。
對應 ADR 0092(主動警示框架);通道與佇列沿用 ADR 0018、排程沿用 ADR 0065。
-
07-13 ai-nl-query-open-action ▸
AI 查詢:自然語言問句可一鍵開啟查詢程式;資料列不再送雲端模型
日期:2026-07-13
使用者可見變動
- AI 查詢視窗(admin)新增「開啟查詢」動作卡:用自然語言提問(例「上個月哪個客戶毛利最低」)後,AI 會判斷該用哪支查詢程式、幫你填好查詢條件,回覆下方出現卡片與「開啟查詢」按鈕;點擊即關閉 AI 視窗並開啟該程式(例:毛利率分析),條件已預填、不自動查詢——你可以先確認或微調條件再按查詢。
- 首波支援 13 支常用查詢程式(毛利率分析、訂單/出貨/進貨查詢、客戶資料、庫齡呆料、金流預測等);「毛利」類問題固定對應毛利率分析(QRY_PROFIT_NOGI)。
- 資料安全強化(預設生效):AI 對話中的查詢不再把實際資料列傳給雲端模型——模型只知道欄位結構與筆數,明細請透過「開啟查詢」在程式內查看;聊天內圖表改由本地繪製(資料不經模型)。此行為由系統參數
AI_ROWS_TO_MODEL控制(預設關閉)。
- AI 產生的查詢條件經過多重驗證(程式白名單、欄位存在、運算子合法、值型別檢查)才會開窗;個別條件套用失敗會明確提示,不會靜默遺漏。
- 毛利率分析新增預設圖表「客戶毛利額前十五」(需部署 chart-spec)。
備註
- 入口維持 admin 帳號限定;一般使用者開放與逐使用者資料權限過濾為後續議題。
- 測試指令
/testcard(僅開發版)可不接模型驗證動作卡。
- 對應 ADR 0094;沿用 ADR 0007/0027/0030(AI 查詢閘道與稽核)、0091(運算子口徑)。
-
07-13 acc-selfrpt-query-busy ▸
2026-07-13 自訂財報(ACC_SELFRPT):查詢時清空舊結果+執行中指示
變更
- 按下「查詢」後立即清空上一次的查詢結果,避免查詢執行期間舊資料被誤讀成新結果。
- 查詢執行期間,表格區顯示忙碌指示(轉圈),查詢完成自動消失。
影響範圍
ViewModel/N.GeneralLedger/Acc_selfrptViewModel.cs(Query 先清空+IsQuerying 旗標)
TsERP/N.GeneralLedger/Acc_selfrpt.xaml(RadBusyIndicator 包住結果表格)
報表編號未輸入時的行為不變(僅提示訊息)。
-
07-12 browsecondition-type-aware-operators ▸
2026-07-12 — 查詢條件運算子依欄位型別過濾
使用者可見變動
查詢視窗的「條件」面板,運算子下拉選單現在會依欄位型別只顯示合理的運算子,行為對齊表格(RadGridView)內建篩選:
- 文字欄:全部運算子(等於、開始於、包含、被包含…,含大於/小於等區間比較)。
- 數值欄:等於、不等於、大於、小於(及等於)、被包含、介於之間…;不再出現「開始於/包含」等文字專用運算子。
- 日期欄:等於、不等於、大小比較、介於之間…;不再出現文字運算子與「被包含」。
- 是/否(布林)欄:等於、不等於、等於 Null、不等於 Null。
- 切換欄位後,若原本選的運算子在新欄位型別已不適用,會自動改回「不等於」。
「套用此條件/不套用此條件/介於之間」等自家延伸運算子在各型別維持可用。
相容性
- 既有已存的預設查詢條件不受影響(運算子代碼未重編,僅限制「新選」時的可選項)。
- 布林欄位的等於/不等於查詢 SQL 修正為
= 1 / = 0。
詳見 ADR 0091。
-
07-11 flowcast-waterfall ▸
金流預測:下圖改堆疊式瀑布圖、版面調整
日期:2026-07-11(2026-07-12 更新為堆疊式瀑布;2026-07-13 改為月階梯瀑布並移除來源組成瀑布)
使用者可見變動
- 金流預測(FLOWCAST) 畫面的下方圖表由原本的「收付堆疊柱圖」改為 堆疊式瀑布圖:
- 每個月仍依 四來源(票據/帳款/訂單/採購)分色堆疊、收向上/付向下,但整根柱不再從 0 起算,而是錨在「前期累計淨額」基線上浮動——柱的堆疊頂/底恰好接到本期累計,因此下圖的柱與上圖的累計淨額折線相互呼應,一眼看出每個月是哪些來源把現金往上推或往下拉。
- 點柱段過濾:點某來源的收(或付)段,明細分頁會過濾到該月 × 該來源 × 該收付;再點同段取消、點空白清除。
- 上方「來源」勾選(票據/帳款/訂單/採購)照舊即時開關;某來源取消勾選時,該色段會變成 0 高度自動消失。
- 版面比例調整:圖表區放大、數據(明細/彙總)區縮小(由 2:3 改為 3:2)。
- 圖表區加上外框(淺灰圓角邊界)。
- 圖表區改用分頁(2026-07-12):原本累計淨額線圖與瀑布圖上下相擠,改成三個分頁——「累計淨額趨勢」「金流瀑布」「來源組成瀑布」,各佔整個圖表區、各自帶時間軸標籤與圖例。
- 新增「來源組成瀑布」分頁(2026-07-12):把整個查詢區間的淨現金變化,拆成四來源的淨貢獻階梯(票據 → 帳款 → 訂單 → 採購 → 期末淨變化),淨流入藍、淨流出橘、期末總計深藍灰,柱上顯示各步淨變化金額,滑鼠移上顯示名稱/金額/佔比。
- 「金流瀑布」分頁改為逐項順序堆疊(2026-07-12):每月的瀑布柱改依 票據收 + → 票據支出 - → 帳款收 + → 帳款支出 - → 訂單收入 + → 採購支出 - 的順序逐項疊出,末端落在該月累計淨額(原為「所有收往上、所有付往下」的分組堆疊)。
- 條件列改版(2026-07-12):查詢條件(預測顯示區間/帳款立帳起日/資金警戒線)改成左側三排「標籤+輸入框」對齊排列,右側新增「計算方式與口徑」說明框(列出每月現金淨變化公式與各來源可信度)。
- 「金流瀑布」改為月階梯瀑布(2026-07-13):X 軸=月份,每月內六段依 票據收 → 票據付 → 帳款收 → 帳款付 → 訂單收 → 採購付 順序並排階梯(原重疊堆疊在收上付下時會互相遮蓋),深色=收(往上)、淡色=付(往下);每月末段收在該月累計淨額=下月首段起點,另加一條灰色累計淨額階梯線把前後月視覺銜接起來。
- 移除「來源組成瀑布」分頁(2026-07-13):整區間四來源組成的視角改由月階梯瀑布涵蓋(X 軸統一為月份),圖表區回到「累計淨額趨勢」「金流瀑布」兩分頁。
- 條件區說明補詳細口徑(2026-07-13):說明框逐來源列出資料來源與日期依據——票據(票況範圍、預兌日→到期日)、帳款(rp_m 未沖、單據分類 AR+/AP+、到期日→收付條件 PAYMENTTERM 推算→立帳日)、訂單/採購(未交數量×含稅單價、回覆日期→預訂交期+收付條件 PAYMENTTERM 推算)。
備註
- 本版本 Telerik RadChartView 無原生瀑布圖,月階梯瀑布以 6 條
RangeBarSeries(浮動柱、CombineMode=Cluster 同月並排)+各段依前期累計計算的絕對座標+StepLineSeries累計淨額銜接線實作。
- 純前端與 ViewModel 變更,無資料庫部署需求。
- runtime 尚未開窗驗收。
延續 ADR 0084(金流預測圖表拆雙軸)。
-
07-10 bor-cycle-audit ▸
BOR 新增「循環稽核」按鈕
日期:2026-07-10
使用者可見變動
- Bor(上位/下位組織結構維護) 畫面備註欄下方新增一顆 「循環稽核」 按鈕。
- 按下後對全部類別碼(替代/下屬/部門/客戶/廠商/工作中心)的上位/下位關係做循環參照偵測:若存在 A→B→…→A 這種繞回自己的循環鏈,會彈出結果表格視窗列出每一條循環(類別碼/起點編號/循環點編號/循環路徑/層數);沒有循環時提示「循環稽核完成:查無循環參照。」
- 只稽核「當前生效」(依生效起訖日)的關係。
部署需求
- 需在資料庫執行兩支腳本並實查驗證:
-
sql\TWORK_QRY_BOR_CYCLE-deploy-5.sql(建立 SP,csa 五帳套)-
sql\TWORK_QRY_BOR_CYCLE-procparam-log5.sql(proc_param 登錄,log 五庫)- 換別家客戶:照該客戶實際庫名整批取代後再跑。
詳見 ADR 0090。
-
07-09 customdash-batch-month-acc-selfrpt ▸
2026-07-09 自訂查詢面板「整批換月」支援自訂財報
變動
CUSTOMDASH 自訂查詢面板的整批換月現在也會換到 ACC_SELFRPT(自訂財報) 的當期月份:
- 按「整批換月」並選目標月份時,清單中的財報 tile 會把「當期起始月份」與「當期截止月份」兩個月份同步平移到目標月(兩者移動同樣的月數,維持當期區間寬度)。
- 清單即使全部都是財報(沒有一般日期查詢),也能判斷來源月份並換月;先前這種情況會跳出「清單中的條件都沒有日期欄位」而換不了。
注意
- 年度不會被換月改動:只平移兩個當期月份,
年度、截止日期維持不變。因此跨年換月(例如 12 月的報表想換到隔年 1 月)月份會停在 12/1 不外溢——同一年度內逐月推進不受影響。
- 換月改的是設定端查詢清單的條件;換完仍需按「查詢」重新產生面板才會看到更新後的結果(與原本行為一致)。
- 財報的抓數區間(由年度+截止日期決定)不受此次換月影響,換的只是報表中「當期」欄位的計算月份範圍。
對應
- ADR 0089
- runtime 尚未實機驗證(單元測試 35/35 通過)。
-
07-08 accexp-report-print ▸
2026-07-08 費用攤提報表(ACCEXP)列印上線
摘要
費用攤提列印(AccexpPrint)程式原本有查詢參數面板但按不出報表(舊列印邏輯是停用的 Crystal 殘碼)。本次把兩張報表 當月攤提報表 與 年度攤提總表 轉成 FastReport 並接好整條列印管線,使用者現在可從程式實際列印/預覽。
新增
- 當月攤提報表(Accexp1):依「起始/截止費用編號」範圍與「年度/月份」列出當期各費用的本期攤提、累計攤提。
- 年度攤提總表(Accexp2):同範圍條件,橫向列出 01~12 月各月攤提金額的年度總表。
- 兩張報表皆掛在既有的「費用攤提列印」程式,沿用畫面上的年度/月份與費用編號起訖條件。
變更
- 「費用攤提列印」的列印按鈕從無作用改為可正常出報表(預覽/列印)。查詢條件面板與欄位不變。
刪除
- 移除 AccexpPrintViewModel 內已停用的舊 Crystal 列印註解碼(無使用者可見影響)。
Breaking Changes
- 無。
Migration Notes
- 報表檔已佈署:
Accexp1.frx、Accexp2.frx已放入報表目錄C:\dglibrary\REPORTSROOT\Reports\。新機器佈署時,記得將這兩個 .frx 一併同步到該目錄,否則列印會找不到報表。
- 資料來源沿用既有 SP
TWORK_RPT_ACCEXP,無需新增資料庫物件。
已知限制
- 簡體中文版(Accexp1cn/Accexp2cn)暫未接線:舊系統僅「鈞寶電子(蘇州)」使用簡體版報表,本次為本公司(非該客戶)只接繁體版;簡體 .frx 已轉好備存,該客戶需要時再接線。
- runtime 驗收尚未進行(未實開視窗按列印驗證資料回填)。
-
07-06 customdash-export-and-chart-spec ▸
2026-07-06 自訂查詢面板彙整匯出(Excel/PPT/HTML)與宣告式圖表
摘要
自訂查詢面板(CUSTOMDASH)新增
彙整匯出鈕:勾選各查詢要用的報表後,選一個資料夾,一鍵同時輸出 Excel、PowerPoint、HTML 三個檔。同時導入一套「宣告式圖表」機制——圖表定義存在資料庫,前端依定義自動畫圖,加一張圖不用改程式;資產負債表已率先掛上圖表區示範。新增
- 彙整匯出(Excel/PPT/HTML):面板頂端工具列的
彙整列印 (PDF)旁新增彙整匯出鈕。操作與彙整列印一致(逐支查詢勾選、各挑一張報表),確定後選資料夾,系統直接以查詢的原始資料產出三個檔案並自動開啟資料夾。與既有「彙整列印(PDF)」、報表預覽「匯出EXCEL」並存、各自獨立。
- 圖表區:查詢頁面可顯示由「圖表定義」自動產生的圖表(直條/圓餅/折線)。資產負債表第一分頁明細下方已掛上圖表區作為示範;因自訂查詢面板顯示的是各查詢的原生畫面,凡是掛了圖表區的查詢,放進面板後也會一併顯示圖表。
- 匯出檔內含圖表:彙整匯出的 Excel 為 Telerik 原生圖、HTML 為 SVG 圖;PPT 一期先放「圖表位置占位文字框」(原生可編輯圖表為二期)。
變更
- 無既有功能行為變更(純新增按鈕與圖表區;彙整列印、儲存設置、整批換月等既有功能不受影響)。
刪除
- 無使用者可見刪除。
Breaking Changes
- 無。
Migration Notes
- 圖表與匯出圖表需先部署圖表定義:由系統管理者於各客戶資料庫執行
sql/chart-spec-deploy.sql(建表+示範定義;跑含中文腳本須加-f 65001並實查驗證)。
- 未部署時:圖表區不顯示、彙整匯出只輸出表格頁(無圖),功能不會出錯,可照常使用。
- 之後要新增一張圖,只需在資料庫的圖表定義表插入一筆設定,不必改程式、不必重新發版。
已知限制(二期候選)
- PPT 圖表為占位文字框:一期 PowerPoint 檔中,圖表位置以文字框標示;可原生編輯的 PPT 圖表列為二期。Excel 與 HTML 已為真圖。
- 表格頁沿用彙整列印取數,沒有報表的查詢不會有表格頁(圖表頁不受此限)。
- 圖表定義一期支援排序、取前 N 名(TopN)與簡單篩選,不做分組彙總(彙總請由查詢程式本身處理)。
- runtime 驗收進行中。
- 彙整匯出(Excel/PPT/HTML):面板頂端工具列的
-
07-05 excel-export-shrinktofit ▸
匯出EXCEL 重寫:彙整列印一支報表一個工作表、不再出現細碎欄位
- 日期:2026-07-05
- 影響範圍:所有報表預覽視窗(
TsFastReportPreview)的「匯出EXCEL」;彙整列印(CUSTOMDASH)受益最大
變更內容
- 彙整列印匯出 EXCEL:原本所有報表擠在同一張工作表,現在一支報表一個工作表,工作表名稱=報表名稱(超過 31 字自動截斷、重名自動補序號)。一支報表有多頁時仍併在同一張工作表。
- 欄位不再細碎:匯出改用非 Wysiwyg 模式——原本會沿報表物件邊緣切出大量超細欄、跨欄標題被截半;現在改用較粗的欄格,出來的檔案可讀可編輯。
- 縮字貼合:文字塞不下儲存格時自動縮小該格字型完整顯示,不再被隔壁儲存格遮住
(在 OOXML 層整片補上——FastReport 自帶的 ShrinkToFit 量測偏窄會漏,SpreadProcessing 轉存又會把它丟掉)。
- 列高補足:列高低於該列最大字型所需高度時自動拉高(只加高不縮矮)——修「標題整個看不到」
(實例:資產負債表 18.7pt 標題被壓在 8.51pt 的列裡)。
備註
- 版面精度換編輯性:非 Wysiwyg 匯出與預覽畫面不會 100% 相同(要完全一致請用匯出 PDF)。
- 若個別報表匯出後版面不理想,請反映報表名稱。
-
07-05 bomflow-diagram-arrow-keys ▸
BOM流程圖查詢:切到「流程圖圖形」後左側清單上下鍵失效——修正
- 日期:2026-07-05
- 影響範圍:BOM流程圖查詢(
Bom_flow)
變更內容
- 修正:切到「流程圖圖形」分頁後,左側組件清單按上下鍵只動一格(或完全不動)的問題。現在可以用上下鍵連續瀏覽組件、流程圖即時跟著切換。
- 平移改進:按住空白背景拖曳即可平移視角(原本要按住 Ctrl 再拖)。拖曳節點、滾輪縮放不變。
備註
- 原因:流程圖控件(RadDiagram)在圖形重建時會主動搶走鍵盤焦點——左側清單每按一次上下鍵就重建一次流程圖,焦點隨即被搶走,下一鍵就沒反應。
- 修法:擋掉「非滑鼠操作」的焦點進入;滑鼠實際點在流程圖上時照常取得焦點(拖曳、縮放不受影響)。
-
07-05 bom-flow-hier-split ▸
2026-07-05 流程圖製程表與階層式製程表拆回兩支獨立程式
對應 ADR 0087(取代 ADR 0076 併版)。
使用者可見變動
- 流程圖製程表(BOM_FLOW) 回歸單純流程圖用途:
- 查詢條件精簡為 起訖品號 / 去除重複 / 計算流程圖。
- 移除先前併入的階層式專屬條件(查詢類別、生效日期、工時別、數量方式、母件方式),以及 自訂條件、文件說明、製程檢查基準分頁。
- 樹狀展開、流程圖、流程圖圖形、多階材料、含插件等分頁維持不變。
- 階層式製程表(BOM_HIER) 改為獨立程式(原本併在流程圖裡):
- 完整保留 VFP 階層式查詢能力:查詢類別(品號/客戶代號暨品號)、起訖品號、客戶區間、生效日期(本日/指定日期)、工時別(標準/改善前/改善後/備料)、數量方式、母件方式、自訂條件、只顯示工時。
- 自訂條件旁提供 「泛用取品號」按鈕(可由 Excel 品號清單一鍵組成查詢條件)。
- 明細表欄位順序對齊 VFP 原版。
- 選單位置:D.設計 → 階層式製程表。若權限管理中看不到,請開啟該程式的瀏覽權限。
備註
- 兩支現為各自獨立的程式與查詢條件,可分別在「自訂查詢面板(CUSTOMDASH)」加入、各自儲存設定。
- VFP 主檔的「備註」欄本次未帶入(資料源尚未提供);階層式製程表報表(BOM_H1/H2/H4)另案處理。
-
07-04 scx-stk-cy-full-port ▸
2026-07-04 朝陽(CY)庫存模組整支移植(scx_stk_cy)
摘要
VFP 庫存模組
scx_stk_cy(14 class)以三階段流程(兩庫欄位聯集 → VFP 為規格書完整實作 → 報表轉 FastReport)整批移植完成。含 6 支整支新建程式、9 支既有程式補完、5 支轉單子表單、約 50 張報表。全部建置通過;runtime 全未驗,上線前需實機驗收。新增
- 廠商庫存表 INV_SP(CY 專屬):年結計算(沿用 DARB_QRY_INV_SP年結)+ Excel 匯入
- 廠商分攤計算 INV_SP1:三分頁彈窗(調撥廠商/其他單據 FIFO 分攤/稽核上傳),演算法下沉 SQL(ADR 0081)
- 委外申請單 TRINOUT_CY:朝陽委外變體(ADR 0080),含外包查詢、53 委外重算驗證
- 加工單 TRWKMA:主檔維護+外送回收自動產耗料(DB→DARB_LOG_DB_TO_PD)+暫收轉入 Tptodb
- 年度盤點產生 INVREC3Y:勾倉儲批次產生多張盤點單(盤點單其他5鈕)
- 轉單子表單五支:NATRLO 不良轉借、TRLIMA_M 借出查詢、NATRRB 轉不良、TRINOUT1 轉異領、TRLOST_S 調整耗料(負庫存分攤)
- 報表約 50 張:八支單據列印(依前置碼自動選版面)、進貨/出貨分析面板(各 3/4 種×含金額)、INVBK1M/GINVBOOK1 對帳、盤點卡/盤點表/盤點標籤(QR 改 FastReport 原生條碼)、TRLILOBI 未歸還明細表
- invbk1 補:計算廠商、廠商追蹤整頁、日記帳過濾、品號/群組條件別、朝陽預設
- trlost 補:盤點退料鈕+PB→PA 鈕
變更
- trsama「已轉帳款」防呆由警告改為擋下修改(照 VFP,使用者裁定)
- Invrecm 新增查詢改走
DARB_INVREC原版(TWORK_INVREC 從未部署,屬壞引用)
- trsama 訂單轉出貨導航修復(誤用他模組 ViewModel 的 pkid)
- H.Inventory 全部 15 支 Source 補 LocalDbContext 註冊+無參建構子(先前 navigate 開窗即崩)
- IOther7/IOther8 介面簽章 void→Task(框架反射建 Func<Task>,void 實作按下即炸)
- 兩庫欄位聯集同步:trinoutd 委外 9 欄、trsama.隸屬客戶、trrafee.進貨單序號、多個 view 顯示欄
刪除
無(美規 Trinout、DARB 英文版報表 plugin 均保留)
Breaking Changes
無(新程式以 dev-programs.json / ProgramClassRouter 疊加,不影響既有客戶)
Migration Notes
1. 模擬環境已部署/登錄:TWORK_QRY_INV_SP1+proc_param 七筆(INV_SP年結/INV_SP1/TRINOUTE1/TRLOST_S_P2/INVBK1_TRSP/INV_SP2×2/RPT_SPLACE)。正式庫上線時需重跑 sql/ 下對應腳本。
2. CY 切新版時執行
sql/trlost-turn-proc-param-CY.sql註解段(prgsct1 其他鈕重排)——VFP 在線時不可跑。3.
sql/trwkma-add-darb-log-db-to-pd-nogi.sql未執行(鈞寶是否使用加工單 DB 流程待確認)。4. 報表 frx 需同步佈署各機
C:\dglibrary\REPORTSROOT\Reports\;版面為轉檔+手修稿,建議實印後 Designer 微調。5. 刻意延後:WKDAY_TR 耗料產生視窗(另案)、撿料標籤群、trlost2(VFP 無路徑選到)、tr_sp 分攤編輯(invbk1)、SEEKWKQ、樞紐分析。
-
07-03 trrama-trsama-analysis-reports ▸
進貨/出貨分析報表(VFP trrama_bd / trsama_bd 移植)
摘要
scx_stk_cy 報表批次 R5:移植 VFP 瀏覽分析面板掛的 14 張分析報表,並新建兩支承載視窗。
- 進貨分析 6 張:RA_DE1/2/3(廠商別/產品別/日期別)+含金額 RA_DE11/21/31
- 出貨分析 8 張:SAL_YR1/2/3/4(客戶/產品/日期/單號)+含金額 SAL_YR11/21/31/41
新增
- 進貨單(TRRAMA)、出貨單(TRSAMA) 主檔畫面單號旁新增「分析報表」按鈕,開啟分析報表視窗。
- 分析報表視窗(ContentWindow 彈窗):
- 查詢條件:交易日期區間(預設本月 1 日~今天)+廠商/客戶代號區間(空白=全部)
- 報表種類 radio(進貨:廠商別/產品別/進貨日期別;出貨:客戶/產品/日期/單號)
- 「包含金額」勾選 → 改印含 單價/金額 的版本(RA_DE11/21/31、SAL_YR11/21/31/41)
- 預覽 / 列印 按鈕
- 報表頁首顯示查詢條件文字(對應 VFP L_瀏覽查詢條件)。
- 資料源沿用既有 SP
DARB_BD_TRRAMA/DARB_BD_TRSAMA(proc_param 已登錄,無需 DB 佈署)。
變更
- 無既有行為變更。
刪除
- 無。
Breaking Changes
- 無。
Migration Notes
- 報表樣板 14 張
.frx已佈署C:\dglibrary\REPORTSROOT\Reports\(其他機器需同步佈署)。
- VFP 面板上的「遮罩」鈕(grid 數量欄格式化)與樞紐選單為瀏覽 grid 專屬功能,新版由 RadGridView 欄位格式取代,不移植。
-
07-03 salesdash-monthly-report ▸
2026-07-03 業務儀表板 + 業務課報告表自動產生
摘要
新增「業務儀表板」(SALESDASH,E.營業收款)與 AutoPilot 排程任務「產生業務課報告表」,
兩者共用同一產生邏輯:ERP 訂單明細 + TTVMA 汽機車銷售統計自動填入業務課報告表 Excel 範本。
新增
- 業務儀表板:本月訂單金額/出貨數量/LOT 數/交易客戶數 KPI 卡片、
各月訂單金額長條圖、本月客戶 Top15 清單。
- 儀表板內「產生報告表」按鈕:指定年月一鍵產出業務課報告表,可勾選是否含 TTVMA 市場資料,
完成後可直接開啟輸出檔。
- AutoPilot 任務
ORMAST / SalesMonthlyReport:可排程每月自動產生(建議每月 18~20 日產上月,
Month 參數用
{-d1})。- 自動填寫的工作表:原紙(整年訂單明細)、樞紐1~12月、國內/國外向出貨數、國內/國外LOT、
渡邊總工程、銷貨趨勢表(實績)、營業額(實績)、4W/2W銷售(TTVMA 原表)、
汽/機車市場佔有率、4W/2W銷售趨勢圖。
變更
- 無既有功能行為變更。
刪除
- 無。
Breaking Changes
- 無。
Migration Notes
- 範本檔:
C:\dglibrary\REPORTSROOT\Template\業務課報告表範本.xlsx
(SalesReportTemplateBuilder 產生的乾淨空白版;舊人工版備份為同資料夾
-原版備份.xlsx)。- 「5月-市佔率/5月-暢銷車款/電動車市佔」三頁為外部新聞圖片,仍需人工貼圖。
- 銷貨趨勢表未來月份的客戶預示金額、營業額目標列維持人工維護,程式不覆寫。
- 開發環境入口已加入
dev-programs.json;正式環境需登錄 SALESDASH 程式權限。
-
07-03 preview-excel-export ▸
報表預覽工具列:「另存新檔」改為「匯出EXCEL」
- 日期:2026-07-03
- 影響範圍:所有報表預覽視窗(
TsFastReportPreview)
變更內容
- 工具列移除「另存新檔」按鈕(原為 FastReport 原生存檔對話框,可選多種匯出格式)。
- 原位置改為「匯出EXCEL」按鈕:直接匯出
.xlsx(Excel 2007 格式),選好存檔路徑後自動以預設程式開啟。
- 「匯出PDF」按鈕不變。
備註
- 匯出走已備妥的報表頁面,不重新運算(彙整多支合併的報表匯出結果與畫面一致)。
- 原「另存新檔」提供的其他匯出格式(Word、HTML、圖片等)自此版起不再提供入口;如有需要請反映。
-
07-03 manual-site-redesign ▸
2026-07-03 使用手冊網站改版 + 批次補主畫面截圖
摘要
manual.yanyue.io 全站視覺改版:自訂品牌配色(深松石綠 × 工安琥珀)、新首頁「模組索引牆」(20 個模組字母磚依五大業務域上色,與桌面系統選單代號一致)、新 logo/favicon、字體與導覽功能升級。並以新的批次截圖工具補齊 38 張功能頁主畫面截圖。
新增
- 首頁模組索引牆:五大業務域(基礎資料與系統/銷售與供應鏈/製造與品質/財務與帳務/協作與決策)分組的字母磚導航
- 首頁三步驟使用指引與維運連結列
- 38 張功能頁主畫面截圖(
*-step1.png)
- 網站 logo 與 favicon
變更
- 佈景主題配色由預設 indigo 改為自訂色系(亮/暗兩模式皆調整)
- 字體:內文 Noto Sans TC、模組字母與編號 Space Grotesk、程式碼 JetBrains Mono
- 首頁改為隱藏側欄的全寬版面;模組名稱對齊
.nav.yml正式名稱(如「總務管理」「工程資料」「營業收款」)
- 導覽功能追加:instant navigation、navigation.footer、toc.follow、search.share
刪除
- 舊首頁的模組表格(名稱已過時,由索引牆取代)
- 「欄位比對工具」「欄位比對列印」頁面(DB 維運工具,屬開發者工具非終端使用者功能)
Breaking Changes
無。
Migration Notes
無需動作;push 至 master 後由既有 pipeline 自動部署。
-
07-03 flowcast-chart-split-panels ▸
2026-07-03 金流預測圖表拆成上下兩張單軸圖
摘要
「金流預測」的圖表區從單張雙軸圖(6 條收付堆疊柱掛左軸+累計淨額折線與資金警戒線掛右側第二軸),
改成上下兩張共用時間軸的單軸圖:上圖只畫累計淨額,下圖保留收付堆疊柱。
雙軸讓使用者容易把柱頂拿去跟警戒線比較而誤讀(柱頂是單月收付金額,警戒線是累計淨額門檻,兩者量級不同),
拆成兩張單軸圖後每張圖的縱軸只對應一種量級,避免誤讀。
新增
- 上圖新增警戒區塗色:從資金警戒線到(月彙總最低累計淨額/警戒線取小值再留 10% 緩衝)之間塗淡紅色。
- 上圖累計淨額線跌破警戒的區段改標紅色粗線(含跌破區與正常區的銜接邊界)。
- 上圖新增「最低點」標註(僅最低累計吃緊時顯示)與「首次跌破警戒」標註(僅期間內曾跌破時顯示)。
- KPI 摘要列新增「首次跌破警戒」卡片(期末累計淨額卡之後),有跌破顯示月份紅字、無跌破顯示「—」灰字。
變更
- 圖表區由「一張雙軸圖+右側圖例」改成「上圖(累計淨額,45% 高)+下圖(堆疊柱,55% 高)+跨兩列圖例」。
- 下圖(堆疊柱)不再掛累計淨額折線與右側第二軸,只保留 6 條收付堆疊柱;點柱過濾、來源勾選、
X 軸粒度切換(年月/日期)行為不變。
- 圖例文字「累計淨額(右軸)」改為「累計淨額(上圖)」,新增「資金警戒線」「警戒區」兩列圖例。
- 上圖時間軸(X 軸)標籤隱藏,僅下圖顯示時間軸標籤,避免兩張圖重複顯示。
刪除
- 移除右側第二軸(
cumulativeAxis);金流預測不再有雙軸圖表。
Breaking Changes
- 無(純畫面呈現調整,資料來源與明細/月彙總分頁不變)。
Migration Notes
FlowcastMonthPoco新增跌破值(可為 null)、FlowcastSummaryPoco新增首次跌破月/有跌破,
純附加欄位,不影響既有 SP/DB 結構。
FlowcastComposer新增ApplyBaseline(periods, baseline),取代原本內嵌在 ViewModel 的
「跌破警戒」判定迴圈;
Summarize需在ApplyBaseline之後呼叫才能算出正確的「首次跌破月」。- Runtime 未驗(需開啟金流預測畫面實際操作確認圖表呈現、警戒區位置、標註顯示邏輯),已記入 memory。
-
07-03 findash-phase1 ▸
2026-07-03 財務月報一期:自訂查詢面板整批換月+進貨廠商統計
- 自訂查詢面板(CUSTOMDASH)新增「整批換月」:條件區新增「目標月份」與「整批換月」按鈕,一鍵把清單中所有查詢條件的日期平移到目標月份(月底日自動對齊目標月月底,如 5/31→6/30)。載入上個月存的月報配置後不必再逐支手改日期。
- 新增查詢程式「進貨廠商統計」(SPBUYRANK):期間內進貨(含退貨沖減)按廠商彙總金額、降冪排序、附佔比與合計,供財務部月報「進貨/加工廠商金額統計」使用;可加入自訂查詢面板。
- 毛利率分析(QRY_PROFIT_NOGI)新增兩張報表:客戶別(M160-1)與品號別(M160-2)毛利彙總表,毛利率低於 10% 以紅字標示(FastReport 原生 Highlight,非 script);補上後此查詢可加入自訂查詢面板的彙整列印。
- 進貨廠商統計新增報表(M-D5-1):廠商排行列表報表,補齊後可進自訂查詢面板彙整列印。
- 整批換月支援斜線日期格式:條件裡以字串儲存的
yyyy/MM/dd日期(全系統字串日期標準格式)也會被平移,不再只認 DateTime 型日期。
- 終端使用者手冊新增/更新四頁:自訂查詢面板(含整批換月)、進貨廠商統計、毛利率分析(列印一節+移除過期的「尚未移植」標示)、M-EIS 索引。
- 尚未包含:以上各項 runtime 未實機驗證;庫存統計查詢的報表(口徑待確認)後續補。
相關決策:ADR 0085。
-
07-03 customdash-save-config ▸
2026-07-03 自訂查詢面板:儲存設置、報表記憶、點選顯示條件
變更內容
自訂查詢面板(CUSTOMDASH)新增三項功能:
1. 儲存/載入設置(可按組織關係分享):查詢區上方新增配置列——可將目前的查詢清單(選了哪些查詢程式、各自的條件、分頁順序)以名稱儲存,之後從下拉選單載入還原,也可刪除不用的配置。配置存於伺服器資料庫,換電腦也看得到同一份。
- 分享:儲存時會記錄「使用部門」——預設自動帶入自己目前的部門,可手動改成其他部門代號;該部門與其上層部門的人都看得到這份配置。此外,主管看得到下屬(含各層)建立的配置、代理人看得到被代理人的配置。
- 下拉選單中別人分享來的配置會標註擁有者代號;只有自己建立的配置能刪除(別人分享來的不可刪,但可另存成自己的一份)。
2. 彙整列印報表記憶:彙整列印時每支查詢選過的報表會被記住(並隨設置一併儲存),下次開彙整列印視窗自動預選上次的報表;只有勾選列印的列才會更新記憶。
3. 點選查詢清單顯示條件:點擊查詢清單中的項目,左側條件面板會顯示該項目已存的條件內容,可修改後按「更新條件」寫回;原本加入清單後條件只能從 ToolTip 看 JSON。
影響範圍
- 僅自訂查詢面板(M.主管資訊 CUSTOMDASH);其他程式不受影響。
- 需部署資料庫腳本
sql/customdash-config-deploy.sql(五帳套一次跑完:表+讀取權限查詢 SPTWORK_CUSTOMDASH_QRY建至 darbnogicsa1~5、proc_param 登錄至各自配對的 darbnogilog1~5;缺席的帳套庫自動跳過;寫入改走標準上傳引擎,舊的 SAVE/DEL SP 廢除)。未部署時面板照常可用,僅儲存/載入設置會顯示失敗訊息。
- 分享可見範圍依既有的「工作關係設定(BOR)」與人事部門資料判定;未設定組織關係者,配置行為與純個人一致(只有自己看得到)。
-
07-03 check-module-reports-fix ▸
票據管理報表列印修復(Bank / Bankfcst / Spbank / Checkrec1)
摘要
票據管理(O.Check)與帳款管理(I.ARAP)共 76 張報表全面盤點,發現 4 張報表的資料管線斷鏈(皆在票據管理),列印時跳「Not found Assembly」或整張空白,已全部修復。帳款管理 76 張中的其餘報表均健康,無需變動。
變更
- 銀行帳戶表(Bank)、預估資金表(Bankfcst)、廠商帳戶表(Spbank)、應收票據一覽表(Checkrec1):新增對應報表 plugin 與報表 POCO。從主檔畫面列印時由 plugin 以全表資料產出;從瀏覽視窗列印時維持原本的瀏覽結果複製(可先篩選再印)。
- 應收票據一覽表:修正
CheckrecViewModel的 sqlite 資料表名錯位(rpt_o030_checkrec_report1→rpt_o020_checkrec_report1),並將Checkrec1.frx的資料表引用改為瀏覽式_1後綴,與應付票據一覽表(Checkpay)行為一致。
新增檔案
Model/Rpt/Rpt_O010_BankReportPoco.cs、Rpt_O050_BankfcstReportPoco.cs、Rpt_O120_SpbankReportPoco.cs、Rpt_O020_CheckrecReportPoco1.cs
TworkReportPluginOfficial/Bank.cs、Bankfcst.cs、Spbank.cs、Checkrec1.cs
Breaking Changes
無。
Migration Notes
Checkrec1.frx已同步佈署至C:\dglibrary\REPORTSROOT\Reports\;其他機器需隨版更新報表樣板。
- 無 DB 變更(資料取數走既有
DARB_GETDATA4,proc_param 已登錄)。
- Runtime 尚未實機驗證(模擬環境 bankfcst 表無資料屬正常)。
-
07-03 bom-query-condition-parity ▸
2026-07-03 D.Bom 查詢程式條件全面補齊(對齊 VFP scx_eng_cy)
摘要
六支 BOM 查詢程式的條件面板與結果功能依 VFP 對比結果全面補上(ADR 0078)。零 DB 部署。
新增
- 共通
- 「自訂條件」輸入欄(最低階用料/產品用途表/流程圖製程表):自由輸入 SQL 條件,非空白時優先於面板品號條件(取代 VFP _SQLQRY1)。
- 「泛用取品號」Excel 批次品號匯入(最低階用料/產品用途表/成本表):檔案選擇視窗(預設 C:\TEMPS,支援 .xls/.xlsx),格式同 VFP(第 2 列起 B=客戶代號、D=客戶品號、E=品號)。
- 成本表(BOM_COST)
- 代工費率(元/分)+代工費率別(單一費率/代工廠商):P320 委外部門工序成本依此計算;代工廠商模式抓組件主要廠商費率與 B00 報價工時。
- 客戶報價截止日/廠商報價截止日:可回溯歷史報價(空白=最新,維持原行為);廠商報價日同時作為 BOM 展開生效基準日。
- 查詢別「泛用取品號」模式:以 Excel 清單逐列(客戶×品號)計算成本。
- 產品用途表(BOM_PURP):結果篩選別
全部/不含舊品/去除重複星號品。
- 最低階用料(BOM_BOTM):「相同品號彙總」勾選(依品號合併、加總數量/含損耗數量/庫存量/總重)。
- 專用材料表(BOM_EXCL):「品別不含B.客戶機種」勾選(預設勾選,對齊 VFP 預設輸出);查詢前品號必填驗證。
- 流程圖製程表(BOM_FLOW):條件區 ISO 文件說明回顯(品名/文件編號/文件名稱/版次);多階材料用量清單「含插件」整批旗標+欄位;新「製程檢查基準」分頁(工程代號檢查項目/基準)。
變更
- 成本表 比例別預設由「成本」改回 VFP 的「售價」。
- 產品用途表「僅查詢最底階」改傳層數 0 給 SP(VFP 同款),結果等價、查詢資料量大幅下降。
修正
- 🔴 成本表
SetCost_Optimized材料價/委外工序價兩個查價來源交叉錯置:進貨價模式材料誤抓廠商報價、委外工序報價會漏查(人工成本 0)。
- 🔴 專用材料表 用途表
品別欄型別錯誤(SP 回傳「4.成品」字串、Poco 宣告 int):CY 庫開查即炸;連動修正「是否專用」判斷與品別說明。
Breaking Changes
- 無(新條件預設值=原行為;P320 邏輯僅在有該部門代號的庫觸發)。
Migration Notes
- 無 DB 變更。runtime 未驗,重點驗收:自訂條件、Excel 匯入、bom_cost File 模式、代工費率兩模式、報價截止日回溯、bom_excl 品別過濾預設值。
-
07-03 alledi-transfer-completion ▸
2026-07-03 alledi(CY 機車 OEM EDI 轉單)轉單層照 VFP 逐頁補完
摘要
alledi(ProgramClass.ALLEDI)14 個在用分頁的「轉單/上傳」業務邏輯,照 VFP
alledi_utf8.prg各頁轉單 procedure 逐頁補完。先前僅顯示層+讀檔 parser 完成、上傳為通用骨架;本次補齊單價/單位/包裝量反查、預示版次規則、工作日攤分、編輯既有單模式、工具頁產出(EXCEL/DBF),並修正一個必炸接線 bug。新增
- 共用轉單支援
AllediTransferSupport:
- 單價反查
vw_cupdma最新報價(SEEK 品號+客戶品號;舊頁 fallback SEEK 品號、反查不到單價=0)- 單位反查 invent、包裝量/標籤數反查 cuinve(生效/失效區間)
- 預示表版次規則:版次 1→9 找空號、「已有大於本月份之預示訂單」擋下、單號=年月+版次+客戶代號
- 工作日曆
BackWorkDay/WorkDaysBetween(Util_Pdt LCL工作日曆,載不到退日曆日)- 攤分演算法:
SpreadByBase(基數100×工作天倍數攤分)+BuildAllocationOrder(日期分配每 5 工作日跳排)AllediDbfWriter:極簡 dBase III 寫出器(年度銷售「產生DBF」用,Big5 中文欄名)
- SYM預示 工作日攤分:4 個 UI 日期(下一/下二/下三起始日+下三截止日)接進 BLL,
期別末碼≥'A'(CKD/SPD)不拆分、其餘照 VFP edipdsym 攤成逐工作日明細,攤分後逐列重反查品號、備註=期納客供(invent.規格)
- YMTT預示 扣當月訂單量:近一年 vw_ordetlid 對照,交期改最新訂單交期+5工作日、過期標「-過期」、數量=原始數量-當月訂單量
- SY計劃/SYM-2W「編輯既有單」轉單:
UploadSyPlan(依預示單號扣減既有明細'E'+新增'A')、
UploadSym2w(依取代預估單號,起訖區間舊明細標'D'+新增,備註=使用者+日期+EDI);新明細用負數 pkid(同 VFP)- SY_BOM 先刪後建:轉單前刪 bom_m 中品別11(客戶機種)且在本批的既有 BOM(AdeUploadBll.Delete / INPUT-BD),再全新建(途程序號 001…、數量公式=STR(數量))
- SY計劃/SYM-2W BOM 展開接真資料:invent 品號檢核+bom_d(生效/失效過濾)展開,原 TODO stub(展開恆空)移除;需求日提前一工作日(UPDT_BACKWKDAY_LCL -1)
- 工具頁產出:泛用取品號「產生EXCEL」(CopyToExcelBll 匯出開啟)、年度銷售「產生DBF」(C:\TEMPS\訂單及預示.DBF)
- 輔助鈕全數實作:Excel 匯出×5、重新檢查×2(重標無品號)、新YAMAHA 文字檔讀入(notepad 開檔)——原「後續階段實作」占位訊息全移除
變更
- ORMAST 轉單表頭補齊 VFP 共通值:倉儲代號='出貨倉'、訂單別='1'、序號前置碼='CO'、匯率=1、per-vendor 訂單備註(鼎豪=訂單輸入日+採購+今天+EDI轉入、新SUZUKI=展開日期:…);明細補 交貨地點/客戶訂單號/結關日期/單位/包裝量/標籤數/原幣未稅=ROUND(數量×單價,0),序號一律重編 001…
- 轉單前置檢查:訂單類擋「查無品號」列;SY_BOM/SY計劃/SYM-2W/年度銷售 擋「錯誤欄非空」列;SY計劃/SYM-2W 擋「已更新過」重複轉單
- 年度銷售 parser 修正:CSV 第 2 欄是公司品號(含
*,直接查 invent),原誤當客戶品號走 cuinve 反查;補 查無客戶/品號無 */查無品號 檢核與 客戶簡稱/品名/停用說明
- 新YAMAHA/新SUZUKI 雙軌轉單:預示年月基準各自正確(最小預訂交期 / 展開日期);新SUZUKI C檔下示交期接真工作日曆
- SYM-2W parser:.xls 讀檔改走共用 AllediExcel(原 XlsxFormatProvider 讀 .xls 會炸)、客戶品號反查方向修正(品號→客戶品號)
- 慶俊預示/YMTT預示/SY計劃/新SUZUKI 的工作日推算由「日曆日保底」改接真正 LCL 工作日曆(Util_Pdt,載不到才退保底)
修正
- 🔴 慶俊預示轉入必炸:VM 未把 起始日期/客戶代號 設進 BLL,BLL 起始日期必填直接 throw——已接線
- SYM/慶俊/SY計劃/SYM-2W 各頁輸入框(年度/月份/起始日期/預示單號/取代預估單號/轉單起訖日)原是裝飾、未接 BLL/轉單——全部接上
已知限制(待後續)
- 全數 runtime 未驗收:需
C:\轉EDI資料\真實樣本檔逐頁跑(轉入預覽+轉單對帳)
- 選單僅開發期 dev-programs.json 注入;正式 DB 登錄(usp_新增程式+_menum)未做
preord_m.採購員(YMTT預示='貿易商')與ormast.公司代碼合併 Source 無此欄(darbnogicsa1 缺,ADR0050 CY 專屬欄待裁定)→ 未寫入
vw_cupdma最新報價無「已審核」欄(VFP SYM/YMTT 帶此條件;view 本身即最新報價彙總,視為等義)
- SYM預示 VFP 的「重複客戶品號+品號+交貨地點」檢查副表(EDIPDSYMCHK)未呈現(讀檔去重已涵蓋主要情境)
- 年度銷售 grid 以「每月一列」呈現(VFP 為一列 12 月欄+總計列;產生 DBF 的資料等價)
- YMTT訂單 grid「公司報價」欄未回填(轉單時以 vw_cupdma最新報價 反查,資料等價、僅顯示差)
建置
LogicBll(dotnet)/ ViewModel / TsERP.csproj(VS MSBuild)0 error;HarnessSmokeTests 3/3 通過。
TsERP.sln 整包僅 UnitTest1.csproj(net48 參考 net8,既有問題)失敗,與本次無關。
- 共用轉單支援
-
07-02 scx-qry-cy-recompare-fixes ▸
2026-07-02 scx_qry_cy 主管資訊查詢 重新對比修補
摘要
對朝陽 CY 主管資訊 EIS 查詢庫
scx_qry_cy(15 支可執行 class)重新逐支對比 VFP 原碼與新版(程式碼 + 前端 XAML),修掉 4 組會阻斷/算錯的 RED 與數個可直接處理的 YELLOW。whole-tab/子表單/報表列印/DB 客戶專屬公式等 feature port 仍列為延後(見下)。變更(使用者可見)
- 外退不良統計 / 派工排程查詢 / 庫存統計查詢:補回
DIExtension.cs遺漏的 3 支ConditionViewModel註冊。此前這三支開窗即崩(「無法建立 ViewModel」),現在可正常開啟。(Group B 移植當時漏了 DI 那一步,同 Group A 曾犯的病。)
- 達成率統計(pd_qry4):新增「僅查詢訂單」勾選框,預設勾選,勾選時排除 A 開頭預示/估算製通單(
製通單號 NOT LIKE 'A%')。此前無此選項=永遠納入 A% 單,與 VFP 預設相反,會使計畫點數/達成率算錯。動態部門欄改依生產順序排序(原用部門代號字典序)。
- 收料不良統計(pur_qry2):
- 廠商別頁「名次」欄修正 binding(原綁不到屬性永遠空白)。
- 廠商評分公式改對齊 VFP 現行(2019/09/03)算法,並分「採購/外包」兩式(原套用被註解的舊公式且不分類,分數會錯)。
- 明細頁新增「只顯示不良」勾選框,預設勾選(對齊 VFP page4 預設)。
- 期間效率統計(pd_qry2):修「期間工時調整」分頁開啟即崩(重複索引鍵例外);修「組立狀況」起訖品號在派工品號模式下用錯維度(製單品號 vs 派工品號)導致查錯資料。
- 期間效率統計 / 非生產工時統計:查詢前補「請先選擇生產部門」防呆(原全不勾會組出殘缺 SQL 拋例外)。
- 派工排程查詢(pd_qry8):生產部門清單新增「全選/不選」批次鈕。
- 庫存統計查詢(costqry2):Tab A/B 補顯示「期初數量/期前正數量/期前負數量」三欄(資料原已算出只是沒上版面);各補一個 client-side 過濾勾選框(僅顯示單價不完整/銷售價為0;僅顯示材料價為0)。
新增
sql/TWORK_QRY_EXCE_INOUT_darbcycsa1.sql、sql/TWORK_QRY_STOCKLIFE_darbcycsa1.sql:補 CY 庫(darbcycsa1)缺的 SP 本體。原本 SP 只佈署到 darbnogicsa1,但 proc_param 已指向 C → CY 執行會崩「無效物件名稱」。⚠️ body 沿用 nogi 版,執行前須人工複核 CY 是否有客戶專屬差異。
Migration Notes
- 上述兩支 CY SP 部署腳本尚未執行,需在 darbcycsa1 跑過,exce_inout / 庫齡分析 才能在 CY 環境查詢。含中文,用 sqlcmd 要
-f 65001並執行後實查物件存在。
仍延後(本次未做,屬 feature port)
- pur_qry2 Page5「品質管制」整頁(含查詢別2 SP + 品號條件 + grid + Excel)。
- pd_qry2「調整工時」鈕開的子表單 PD_QRY21。
- qc_qry2 Page4「生產日報表含無不良明細」整頁、Page1「個別組立數/個別不良率」兩欄、Page3 權限回寫頁、彙總資料 surface(Bll 已算但未輸出=dead code)。
- 各查詢的 FastReport 列印/Excel/Email(ADR 0034 決策:scx_qry 一律用 RadGridView 內建匯出取代)。
- stocklife:庫齡分桶交易別 DB↔MP 差異(SP 層)、單位成本公式落後版(VFP 2025/07/18 改 BOM材料+製程加工×人工費率)、庫齡明細缺 5 欄、P4 移植的是 VFP 已停用舊演算法。
- pd_qry7:設變建議品號確認窗、外部 DBF 資料別3、Excel 樞紐;OperationForecast 7 支 SP 待部署。
驗證
LogicBll(dotnet)、ViewModel、TsERP(VS MSBuild)三者建置 0 錯誤。runtime 尚未實機驗證。
</content>
</invoke>
- 外退不良統計 / 派工排程查詢 / 庫存統計查詢:補回
-
07-02 scx-ord-cy-xaml-field-completion ▸
2026-07-02 — E.Order(scx_ord_cy+scx_ord)XAML 欄位補齊與綁定修正
摘要
依 VFP 三方對齊檢查(VFP UI 欄 ↔ Source 屬性 ↔ XAML 綁定)結果分兩批補齊:第一批對
scx_ord_cy(CY 版)7 支表單補 UI 缺欄、修正 2 個錯誤綁定、解鎖 5 處唯讀倒退、刪除 2 支不可達 US 變體孤兒 view;第二批對scx_ord(非 CY 版)獨有 12 class 與共用 class 差集再補一輪(ormast 主檔 4+明細 17 欄、cuqt 加工明細 4 欄、cudata 6 欄等)。全部改動 TsERP 整包 build exit 0。新增
表單 新增欄位 訂單(Ormast) 主檔:訂單備註、聯絡單ID;明細:交貨地點、包裝量、標籤數、結關日期、製通單號(唯讀)、合併單號、補貨數量、出通單數量(唯讀) 裝箱單(Pk) 主檔:出船日、到達日;明細:產品別(插在品號附近)、合約號碼、訂單編號、預訂交期 預示訂單(Preord) 明細唯讀欄:停用日期、管制說明、生產線、工時、規格、生產批量;品號/客戶品號改值時即時回填品號附屬欄(查得到才覆蓋) 商業發票(Ci) 主檔:交易條件(可編輯文字,選碼帶入可手改);明細唯讀欄:轉入單號、訂單編號 出貨通知(Salema) 明細:客戶訂單號(可編輯)、訂單編號-序號(唯讀反查) 報價單(Cuqt) 主檔:人工費率、YMT材料費、YMT加工費(費用區,紫標對應 VFP) 客戶資料(Cudata) Tab1:發票地點+發票郵遞號(地址四連段補齊)、英文簡稱、英文名稱、港口代碼(M202 下拉)、助理、助理二、業務主管(SalesRepSearch+姓名反查) 第二批(scx_ord 非 CY 版差集)
表單 新增欄位 訂單(Ormast) 主檔:訂單別、報價單號、業務員編號(SalesRepSearch+姓名)、聯絡人;明細 17 欄:顏色、客訂單序號、廠商代號、建議採購量、建議交期、建議售價(AllowViewPrice 閘)、請購數量、是否採購、是否核發、製程別、採購別、客戶交期、訂單分類、交期變更、營業確認、出貨別、分批交貨 報價單(Cuqt) 加工明細 grid:費率(連動重算)、參考加工費、裸價治具費、治具費(非 CY 欄組原整組漏掉) 客戶資料(Cudata) 對照碼、經銷商(C270 下拉)、科目代號(GLAccountSearch)、倉儲別、公司客號、保養廠代碼 客戶報價(Cupdma) 叫修單號 裝箱單(Pk) 明細:包裝量_箱 送樣(Sample) 聯絡單ID;承認書升級下拉(1.PDF/2.EXCEL/3.書面);完成日期/是否結案唯讀對齊 達成率(Fillrate) 類別欄(C:客戶/S:廠商);備註唯讀對齊 維修(Repair) 5 處唯讀對齊(叫修人/服務人員/品名/機器序號/客戶簡稱)⚠️ 叫修人/服務人員鎖定待裁定(新版原做成可編輯指派欄) 信用額度(Cudatalimit) 上次額度/最新額度欄序修正(原顛倒) typo 修正:Sample1.xaml 兩處
DescriptionBindingPath="SKUDescription"(stale 英文名)→品名。完全對齊零修改:claim、cmplain、culbl、cungma、invent1、orssma、rtaxma、visit、pdtsal、estsal、cuinve、ci、salema(差集部分)。
變更
- Ci 商品名稱碼表修正:
TableAlias C269 → C275。DB 查證:朝陽庫(darbcycsa1)只有vwcmb275_商品名稱(有實際資料),269 不存在;VFP 原始碼c_type=275。原 C269 在 CY 環境下拉會是空/錯表。
- Pk 商品名稱升級下拉:純 TsTextBox →
TsComboBoxBySql TableAlias="C275"(對齊 VFP sqlcombo c_type=275,與 Ci 同款)。
- Cudata 請款郵遞區號錯位修正:請款地點列的郵遞區號原誤綁
發票郵遞號→ 改綁請款郵遞號;地址四連段(公司/發票/請款/送貨)郵遞配對整組核對正確。
- Cudata 唯讀解鎖 5 處:停用(Tab1)、帳號/支存帳號/活存帳號/資本額幣別(Tab2)。VFP 皆可編輯、新版無其他編輯入口、git blame 確認鎖定來自 scaffold 批次非刻意決策。
- Ci_m1(批次選取轉入)接線修復:①視窗標題改綁 VM
Title(出貨通知單轉商業發票/出貨單轉商業發票);②code-behind 補建 VM 與 DataContext(原本被註解掉、整窗 DataContext=null)+ DialogCloser;③轉入時轉入單號依 VFP 規格填「出通單號-序號」(查詢別 21),出貨單路(23)維持只填倉單號。
- Preord 移除無作用的
RowDetailsVisibilityMode殘留屬性;Cuqt 修Orientation=" Horizontal"多餘空格。
刪除
TsERP/E.Order/Ormast_US.xaml(.cs)、TsERP/E.Order/Cudata_US.xaml(.cs):兩支皆為不可達孤兒 view(無任何 DataTemplate/路由引用、TsPage 舊堆疊、綁定大面積 stale——Ormast_US 有 7 個大小寫 dead binding、Cudata_US 有 3 個 typo binding+200+ 英文 stale 綁定)。使用者裁定刪除。tools/release-notes/bootstrap-system-map.ps1跳過清單同步清理。
Breaking Changes
無。所有新增欄位的 Source/Model 屬性原本就存在,DB schema 未動。
Migration Notes
- 本批表單(E.Order 多數)無 per-view 語系 JSON、XAML 全走中文字面值;新增欄位比照既有慣例用中文 Header/Label。日後若做多語系需整模組一起建 JSON,非本次範圍。
- 使用者裁定不補(記憶已載,後續對比勿再報):公司代碼欄(5 支表單,單公司環境維持 hardcode=1)、Cudata 聯絡人 grid skype/msn/facebook/呼叫器 4 欄(已淘汰)。
- 已知另案待辦:ormast 兩庫 twin 欄(訂單號碼/倉庫/ORDERCLOSE/結案 綁美系側,CY 庫需裁定)、preord LTMP 用量 6 欄(需 DB 端彙總設計,grid 已留占位註解)、Ci_m1 挑出通轉入時新欄「訂單編號」為空(TmpSalede POCO 未映射 SP 欄位,需查證 TWORK_QRY_CI)、WindowHelper 對 RadWindow 基底的 TsWindow 會 InvalidCastException(Ci_m1 開窗路徑,建議 window-to-tsview 轉換)、PkViewModel.ItemDescriptionTypeSource 死碼待清。
- 第二批新增另案:cupdma「業務報價查詢」暫存面板(cupdtbizprice grid)、ormast「訂單歷史查詢」彈窗(ltmp訂單歷史 11 欄)、preord「採購需求表」(ltmp 39 欄)三個整組功能未移植(無 Source,屬功能移植非補欄);cudatam「付款條件」反查顯示欄需加 Source 屬性(循 收付條件說明+GetPaymentTermDescription 模式);fillrate「修改模式保留舊資料」邏輯未實作;repair 叫修人/服務人員唯讀鎖定待裁定(VFP 靠派工程式回寫,新系統若無對應則需回退為可編輯)。
- Runtime 未驗:本批為靜態補欄+build 驗證(C#/XAML 編譯通過;完整 build 因執行中 TsERP 鎖 DLL 只到複製步驟),實機開窗驗收待使用者執行。
- Ci 商品名稱碼表修正:
-
07-02 report-preview-custom-toolbar ▸
2026-07-02 報表預覽視窗工具列整併
摘要
報表預覽視窗(TsFastReportPreview)原本上下兩排工具列(自家的「匯出PDF/中一刀列印」+ FastReport 內建英文工具列)整併成單一自家中文工具列。
新增
- 工具列新增:列印、另存新檔(支援 FastReport 全部匯出格式)、搜尋、浮水印編輯、大綱面板開關、第一頁/上一頁/下一頁/最末頁、頁碼輸入框(輸入頁碼按 Enter 跳頁)、目前頁/總頁數顯示、縮小/放大/縮放至頁寬/整頁顯示。
變更
- 「匯出PDF」「中一刀列印」與預覽操作按鈕合併在同一列。
- 工具列文字全面中文化(原內建列為英文圖示列)。
- 工具列改用 Telerik Office2019 主題外觀(RadButton + RadGlyph 圖示),與系統整體風格一致;導覽與縮放為圖示鈕附中文 ToolTip。
刪除
- FastReport 內建工具列隱藏(
ToolbarVisible=False)。其上的 Open/Design/Edit 原本就已停用;Save(匯出)功能由「另存新檔」承接。
Breaking Changes
無。
Migration Notes
無需資料或設定變更。
-
07-02 program-class-router ▸
2026-07-02 程式分流:舊系統共用 DB 的程式鍵導向新版程式
摘要
新增程式分流中央對照表(ADR 0075)。與 VFP 舊系統共用資料庫的客戶(朝陽),選單登錄的
舊程式鍵會在登入後自動導向新版程式;超連結跳轉也會自動解析到該客戶實際使用的客製變體。
新增
- 朝陽:選單「庫存主檔」(
INVENT)現在會開新版INVENT_BS畫面(之前顯示
「無法建立ViewModel」無法進入)。
- 全客戶:程式內品號等超連結寫死
INVENT時,自動跳到該客戶選單實際登錄的變體
(
INVENT_BS/INVENT_PRIME)。變更
- 無既有可運作行為的變更;所有分流都只在原本會失敗(查無程式/無權限)時介入。
刪除
- 無
Breaking Changes
- 無
後續更新(2026-07-03)
- 公版庫存主檔
INVENT完成(ADR 0077)後,移除「朝陽 INVENT→INVENT_BS」的
CompanyOverrides 條目:選單登錄
INVENT的資料庫現在直接開公版畫面。CompanyOverrides 機制本身保留(空表),之後有真實分流需求再登錄。
Migration Notes
- 不需要任何資料庫變更。
- 朝陽如需
INVENT_BS的新版報表,_reportname類 keyed 資料需另行以新鍵登錄
(純新增,不影響 VFP)。
- 朝陽:選單「庫存主檔」(
-
07-02 invent-standard-base ▸
2026-07-02 庫存主檔公版化(INVENT 基底 + 客製衍生)
摘要
新增公版庫存主檔程式
INVENT(ADR 0077)。原禾久版INVENT_BS重構為公版的衍生類,功能與畫面完全不變。搭配程式分流(ADR 0075),超連結寫死
INVENT會自動導航到各客戶實際使用的版本。
新增
- 公版庫存主檔
INVENT(InventViewModel+Invent.xaml+InventSave)。
選單登錄
INVENT的資料庫(且無公司分流對照)現在會開公版畫面。變更
Invent_bsViewModel/Invent_bsSave改為公版的衍生類——對使用者零行為變更。
刪除
- 無
Breaking Changes
- 無
Migration Notes
- 不需要資料庫變更。
- 模擬環境要單獨開公版:dev-programs.json 註冊
INVENT(注意:注入後寫死
INVENT 的超連結會開公版而非客製變體)。
- 公版庫存主檔
-
07-02 flowcast-ux-improvements ▸
2026-07-02 — 金流預測 (flowcast) 畫面與口徑強化
摘要
金流預測第二輪打磨:頂端加 KPI 摘要卡、明細區改「金流明細/月彙總」雙分頁、圖表時間軸空月補零不再跳月、點柱過濾狀態可見可清除。
新增
- KPI 摘要列(畫面頂端五張卡):期間總流入/總流出/淨額/期末累計淨額/最低累計淨額(含發生月)。最低累計跌破資金警戒線(或警戒線 0 時為負)顯示紅字。
- 月彙總分頁:明細區改 TsTab 雙分頁,新增月彙總數字表(年月/應收/應付/當月淨額/累計淨額),累計淨額跌破警戒線的月份整列紅底。
- 點柱過濾狀態列:點圖表柱段後,明細分頁頂端顯示「過濾中:年月 × 來源收付(N 筆)」黃色標籤與 ✕ 清除鈕(原本只能再點同段或點空白取消,狀態不可見)。
- 明細 grid 補 原幣金額 欄(幣別旁,小數位走原幣設定);欄序改「預計現金日」在最前。
- 圖表 tooltip 補來源系列名(原本只有年月+金額,堆疊柱分不出哪層)。
新增(第二批,同日)
- X 軸粒度切換:來源勾選列加「X 軸:年月/日期」radio,日期模式逐日堆疊柱+逐日累計線(點柱過濾與期間彙總表同步以日為鍵)。空日一樣補零,跨度超過 3 年退回稀疏顯示。
- 累計淨額改掛右側副軸:原本與月柱共用左軸,累計量級大把柱壓扁(柱狀體太矮);現在柱用左軸、累計線與資金警戒線用右軸(圖例標示「累計淨額(右軸)」)。
變更
- 空月補零:
GroupByMonth/GroupByMonthStacked產出首月~末月連續月序列,無資料月份補 0 列(累計淨額沿用上月)。原本空月直接消失,柱狀圖時間軸跳月、累計線斜率失真。鍵解析失敗或跨度超過 50 年退回原稀疏序列。
- 摘要 KPI 抽成純函數
FlowcastComposer.Summarize(LogicBll),與月彙總同層可單元測試;FlowcastMonthPoco加跌破警戒旗標(查詢時依當時警戒線計算)。
刪除
- 無。
Breaking Changes
- 無(查詢口徑、SP、參數皆未動;純顯示層與彙總呈現)。
Migration Notes
- 無需 DB 動作。警戒線仍在查詢條件「資金警戒線」設定,查詢後才會反映到月彙總紅底與 KPI 紅字。
-
07-02 bom-purp-process-date-filter ▸
2026-07-02 產品用途表:工程代號查詢補生效區間過濾+成本表預設值修正
摘要
scx_eng_cy 查詢條件全面對比(六支查詢程式)發現的回歸修正。
變更
- 產品用途表(BOM_PURP)以「工程代號」查詢時,補回生效/失效日期過濾:只列「現行有效或未來生效」該工程的組件。VFP 於 2016/11/15 特別修過「工程失效也會出來」的問題,新版移植時用到修正前的舊 SQL,導致已失效工程的品號也被查出。(
Bom_purpBll.cs)
- 成本表(BOM_COST)
起始受訂日預設值補設為空字串:ResetToDefault()原漏設此欄(null),與其他欄位行為不一致。
Breaking Changes
- 無(行為回歸 VFP 正確口徑)。
Migration Notes
- 無 DB 變更。
- 產品用途表(BOM_PURP)以「工程代號」查詢時,補回生效/失效日期過濾:只列「現行有效或未來生效」該工程的組件。VFP 於 2016/11/15 特別修過「工程失效也會出來」的問題,新版移植時用到修正前的舊 SQL,導致已失效工程的品號也被查出。(
-
07-02 bom-hier-parity ▸
2026-07-02 階層式製程表(流程圖製程表)補齊 VFP 缺口
摘要
依 VFP
scx_eng_cy的bom_hier對比結果,把整併在「流程圖製程表」(BOM_FLOW)裡的階層式製程表能力補齊:查詢條件、明細欄位、主檔欄位與「只顯示工時」過濾。(ADR 0076)新增
- 查詢條件
- 查詢類別:
品號/客戶代號暨品號(後者可輸入起訖客戶代號,以客戶產品對照 cuinve 篩品號)- 生效日期:
本日/指定日期(BOM 生效區間以指定日為基準展開)- 工時別:
標準工時/改善前工時/改善後工時/備料工時(改善前/後與備料工時僅朝陽庫有資料,其他庫為 0)-
各層皆自數量1往下查詢:每層母件數量視為 1,明細數量=自身單位用量-
各層須增加原母件資料:每個展開節點前插一列母件自身(顯示序號後綴----)- 製程明細表/製程明細(樹狀) 新欄位:製程別、庫存量、包裝量_包、廠商代號1、廠商簡稱1、治具品號
- 左側查詢組件清單新欄位:品名、客戶品號
- 製程明細表「只顯示工時」勾選:只列製程列(VFP
SET FILTER TO '◇'$顯示品號對應)
變更
- 無既有行為變更:新條件預設值=原行為(本日、標準工時、兩個展開選項不勾)。
刪除
- 無。
Breaking Changes
- 無。
U_Bomflow其他呼叫端(報價單、營運預測、庫齡呆料、生產計劃)不受影響。
Migration Notes
- 無 DB 部署需求(
DARB_QRY_BOM_PROCES/DARB_GETDATA4皆已登錄 proc_param)。
- 尚未移植(後續另案):VFP bom_hier 的「自訂查詢」條件產生器、報表選擇 5 種列印(BOM_H1 產品組件表/BOM_H2 標準工時表×3/BOM_H4 治工具管制表)與治工具管制表 Excel 匯出。
-
07-02 bom-flow-diagram-and-tree-enhancements ▸
2026-07-02 — 流程圖製程表:圖形排版改水平左上、樹狀分頁補按鈕、新增需求數量重算
摘要
D-110 流程圖製程表(Bom_flow)四項強化:流程圖圖形預設改為水平排列(根節點在左上角、先明細後製程、往右下角展開)、製程明細(樹狀)補「展開全部/收攏全部」、新增「需求數量+重新計算」、樹狀根節點補數量/單位並讓製程列顯示名稱。新增
- 需求數量重算:製程明細(樹狀)分頁下方新增
需求數量輸入欄與重新計算按鈕。輸入需求數量後按下,整棵樹的數量(明細 = 父數量 × 單位用量)與標準工時(製程 = 數量 × 單位標工時)即時重算,製程明細表、多階材料用量清單、流程圖、流程圖圖形同步更新;純記憶體計算,不重新查詢資料庫。切換查詢組件時輸入欄會帶回該組件目前的根數量。
- 樹狀分頁按鈕:製程明細(樹狀)分頁下方新增
展開全部/收攏全部按鈕(原本只有製程明細表有)。
變更
- 流程圖圖形預設水平排列:開啟即水平(原預設垂直)。根節點固定在左上角,每條鏈沿明細往右直走、製程與其他分支往下換列,整張圖往右下角延伸——與「流程圖」表格分頁(VFP 原版)的閱讀順序一致。
垂直排列按鈕行為不變。
- 圖形同層順序:展開子節點時先放明細(物料)再放製程;同組內仍照顯示序號。
- 圖形根節點:補顯示數量+單位(第 3 行),品名缺漏時改從查詢結果帶入。
- 樹狀根節點:第一個組件(查詢組件自己)改用查詢結果的層數 0 那筆,因此數量、單位、生效日期等欄位都有值(原本是合成節點,數量/單位空白)。
- 樹狀品號欄:改綁
樹狀顯示品號——去掉縮排與 ▼/▲ 三角形、保留 ◎/◇ 前綴;製程列因此顯示 ◇+工程簡稱(有名稱),不再只有工程代號。
- 製程品名顯示代號+名稱:樹狀分頁品名欄與流程圖圖形的製程節點第 2 行改顯示「工程代號+工程說明」(說明缺漏時退回工程簡稱),代號跟名稱一眼可見。
- 圖形連線改直角折線:連線改 Polyline+自動路由(OrgTreeRouter 依排列方向轉折),不再畫斜線。
- 圖形雙擊不再縮放:拿掉 RadDiagram 內建「雙擊畫布重設 100% 縮放」行為,避免看圖時誤觸突然縮小。
- 隱藏背景格線:畫布背景格子改為不顯示,並在畫板外加一圈框線、自動縮放四周留 30px 邊界。
刪除
- 無。
Breaking Changes
- 無。資料庫、報表、參數皆未變動。
Migration Notes
- 無需任何佈署動作。多語系新增鍵:
展開全部、收攏全部、需求數量、重新計算(Common/Lang/Xaml/Bom_flow.json)。
- 需求數量重算只影響畫面上的顯示值,不寫回任何資料表。
- 需求數量重算:製程明細(樹狀)分頁下方新增
-
07-01 ESTSAL-union-length-fix ▸
2026-07-01 ESTSAL 兩庫欄位聯集同步(長度補齊 + 年預估分類/分類 鏡射)
摘要
依
/dual-db-union-sync ESTSAL比對鈞寶darbnogicsa1與朝陽darbcycsa1兩庫的estsalm(主表,無 view)、estsald/vw_estsald(子表 + view)欄位聯集。結論:Model / Source 的欄位聯集在先前 CY 對比時已補齊(
EstsalmModel、EstsalmSource、Twork_ord_vw_estsaldModel、Twork_ord_vw_estsaldSource皆含兩庫聯集欄)。本次做兩件事:(1) 修正兩個
TsStringLength未取聯集上限、可能截斷 CY 值的問題;(2) 對照 VFP
scx_ord(NOGI)與scx_ord_cy(CY)原始碼確認年預估分類(int) 與分類(char) 是同一「年預估分類」欄的兩庫不同存法(同標籤、同 InputMask 9999),改以「設一欄、鏡射填兩欄」串接共用 UI。
比對結果
物件 NOGI CY 處理 base estsalm10 欄 13 欄 聯集 14 欄,Model/Source 早已齊全 base estsald8 欄 8 欄 相同,Model 無變更 view vw_estsald+品名 +品名/停用/停用說明/停用日期/管制說明 Source 私有欄位早已承接 (主表
estsalm無編輯 view;年預估分類(NOGI int) 與分類(CY char) 名稱不同,聯集各留一欄。)變更
Model/Source/E.Order/EstsalmSource.cs:審核人員TsStringLength(10)→(20)
(NOGI
nvarchar(10)/ CYnvarchar(20),取聯集上限避免截斷 CY 審核人員)。Model/Source/E.Order/Twork_ord_vw_estsaldSource.cs:品名TsStringLength(120)→(200)
(view 顯示欄,NOGI
nvarchar(120)/ CYnvarchar(200),取聯集上限)。Model/Source/E.Order/EstsalmSource.cs:年預估分類(int) 與分類(char(1)) 兩個 setter 互為鏡射
(直接寫對方 Model 欄避免遞迴)。編輯共用 UI 欄或任一庫載入時,兩欄恆同步:
- 設
年預估分類 = N→分類 = N.ToString()(N=0 時清空)。- 設
分類 = s(CY 載入僅回傳此欄)→年預估分類 = int.TryParse(s),讓 UI 顯示與EstsalSave的「年預估分類 != 0」必填檢查對兩庫皆成立。ViewModel/E.Order/EstsalViewModel.cs:AfterAddNew新增預設年預估分類 = 1
(對應 CY VFP
REPLACE 分類 WITH '1'=1.銷售,經鏡射同步填 CY分類)。VFP 對照依據
面向 NOGI scx_ord(int 年預估分類)CY scx_ord_cy(char 分類)綁定欄 年預估分類分類標籤 / InputMask 年預估分類 / 9999年預估分類 / 9999addagain 預設 無 REPLACE 分類 WITH '1'(銷售)allowsave 必填 Empty(年預估分類)EMPTY(分類)參與 單號 組成 註解掉(若啟用取 LEFT(年預估分類,1))年度+分類+版次+客廠部代號(OPMODE 1/8)刪除 / Breaking Changes
無欄位移除。行為變更:NOGI 新增單據時
年預估分類現預設為 1(VFP NOGI 原留空由使用者輸入);因
EstsalSave本就要求非 0,使用者仍會確認/改值,實務影響小。尚未承接(後續另案,非本次範圍)
CY VFP 由
分類等欄自動組單號(年度+分類+版次+客廠部代號)與「上版鈕」載入前版;現行 C#
EstsalSave仍將單號視為使用者輸入(is_noduplicate),CY 的 單號 自動組成尚未移植。Migration Notes
本機 SQLite 由
EnsureCreated/ LocalDbService 補欄安全網自動處理,無需手動 migration。屬 ADR 0050(多客戶差異處理)既有決策的延伸,不新開 ADR。
-
07-01 CI-union-sync ▸
2026-07-01 CI 兩庫欄位聯集同步
摘要
依
/dual-db-union-sync CI比對鈞寶darbnogicsa1與朝陽darbcycsa1兩庫的ci_m/vw_ci_m(主表 + view)、ci_d(子表,無 view)欄位聯集。live 類別為
Twork_ord_vw_ci_mSource/Twork_ord_vw_ci_dSource(CiViewModel+CiSave使用)與其 Model
Twork_ord_vw_ci_mModel/Twork_ord_vw_ci_dModel。本次僅新增兩庫聯集缺漏欄,未動既有欄位。比對結果
物件 NOGI CY 處理 base ci_m27 27 差 1:NOGI 有 稅別(已在 Model)、CY 有是否si→ 補是否siview vw_ci_m31 31 view-only JOIN 欄( 客戶簡稱/出貨港口/目的港口/運送方式)兩庫皆有、Source 已承接base ci_d19 21 NOGI 有 其他金額(已在 Model);CY 多訂單pkid/預訂交期/合約號碼→ 補 3 欄變更(新增欄,皆兩庫聯集)
Common/Model/E.Order/Twork_ord_vw_ci_mModel.cs、Model/Source/E.Order/Twork_ord_vw_ci_mSource.cs:
-
是否si(CYci_mchar(1))— string,[TsStringLength(1)]。Common/Model/E.Order/Twork_ord_vw_ci_dModel.cs、Model/Source/E.Order/Twork_ord_vw_ci_dSource.cs:
-
訂單pkid(CYci_dint)。-
預訂交期(CYci_dchar(10))— string,[TsStringLength(10)]。-
合約號碼(CYci_dnvarchar(20))— string,[TsStringLength(20)]。NOGI 無上述欄,上傳時 OPENXML 依 ADR 0050 取交集自動略過;CY 現可持久化這些欄。
後續清理(同批完成)
- view-only 欄搬入 Source 私有欄位:
客戶簡稱/出貨港口/目的港口/運送方式從Twork_ord_vw_ci_mModel
移除(含 ctor init 與
[XmlAttribute()]屬性),改由Twork_ord_vw_ci_mSource以私有欄位承接,使 Model 純對應 base
ci_m、GetModelBase不再序列化這 4 個 JOIN 唯讀欄。稅別(NOGI base 欄)保留於 Model。- 刪除重複死碼對:
Common/Model/Ci_mModel.cs、Common/Model/Ci_dModel.cs、
Model/Source/E.Order/Ci_mSource.cs、Model/Source/E.Order/Ci_dSource.cs—— 經全 repo(.cs/.xaml)確認無任何 ViewModel/BLL/DataManager 註冊或反射引用,整組移除。
刻意未動(超出本次聯集範圍,另記備查)
- EDI/856-810 欄組:
ci_m的出貨ID/名稱/地址…請款…/trno/blno/scac/carrier/shipdate/estdate/create856/create810/receiveid/TaxCode/出通單PKID、
ci_d的PILinePkid/SalesOrderLinePkid/reqno—— 皆不在 NOGI/CY 兩庫ci_m/ci_d,屬第三變體(EDI)欄,保留。- 型別/精度既有差異:
公司代碼C#shortvs DBint、匯率[TsDecimalLength(19,6)]vs DBnumeric(14,4)、
產品描述別len 10 vs DB 4 —— 皆放大或無害,保留不動。刪除 / Breaking Changes
無欄位移除、無行為變更。純新增聯集欄。
Migration Notes
本機 SQLite 由
EnsureCreated/ LocalDbService 補欄安全網自動處理,無需手動 migration。屬 ADR 0050(多客戶差異處理)既有決策的延伸,不新開 ADR。
📅 2026 年 6 月 (148 篇)
-
06-30 radgridview-header-corner-autofit ▸
2026-06-30 RadGridView 表頭左上角雙擊自動調整欄寬
摘要
TsRadGridView(全 app 共用表格控件)新增一個隱形的快捷操作:在表頭左上角那一格(row indicator 上方的空白角落)點兩下,即把所有欄位寬度設成 Auto、依內容自動調整。等同原本右鍵表頭 →「自動調整欄寬」,但不必開選單。依使用者裁定採「隱形」作法:左上角不放可見按鈕,只在滑鼠移上去時變手型游標並顯示 tooltip「點兩下自動調整欄寬」提示。
新增
TsControl/TsTelerik/TsRadGridView.cs:
- 在
Loaded掛勾表頭列(GridViewHeaderRow)的左上角PART_IndicatorPresenterBorder,加雙擊 → 自動調整欄寬;同時設Cursor=Hand與 tooltip。- 表頭列可能晚於 Loaded 才實體化,找不到角落時延後重試一次。
變更
- 抽出共用方法
AutoFitAllColumns();右鍵選單「自動調整欄寬」與左上角雙擊共用同一實作。
影響範圍
全 app 所有
TsRadGridView。瀏覽/查詢/明細表格皆適用。使用方式
- 表頭左上角空白格 → 點兩下:所有欄寬依內容自動調整。
- 仍保留原入口:表頭右鍵 →「自動調整欄寬」。
Breaking Changes
無。單擊左上角、或雙擊其他表頭格的既有行為(排序)不受影響。
Migration Notes
需重建 TsERP 才會生效(改動在 TsControl 共用控件)。
-
06-30 ORMAST-union-sync ▸
ORMAST 兩庫欄位聯集同步(darbnogicsa1 ∪ darbcycsa1)
摘要
依
_sheetno查得 ORMAST 主表ormast/vw_ormast、子表1ordetl/vw_ordetl,比對鈞寶(
darbnogicsa1)與朝陽(darbcycsa1)兩庫的 base table 與 view 欄位,取聯集後同步回程式:base table 聯集進 Model、view JOIN 唯讀欄進 Source 私有欄位。
屬 ADR 0050(多客戶差異處理)的延伸,未新開 ADR。
比對結果
物件 NOGI CY 差異 處理 base ormast40 36 CY 多 流程樣板號;NOGI 多訂單類別碼/集團代號/聯絡人/報價單號/叫修單號Model 補 流程樣板號(其餘 NOGI 欄早已在 Model)view vw_ormast48 45 CY 多 JOIN 欄 leadtimes/leadtimet(+流程樣板號)Source 補 leadtimes/leadtimet私有欄位base ordetl59 49 CY 多 預示資料/預示比對/比對說明1/比對說明2/回覆Model 補這 5 欄 view vw_ordetl69 57 CY 多 JOIN 欄 停用/停用日期/預訂完工日(+上述 5 base 欄)Source 補 5 base 欄(委派 Model)+ 停用/停用日期/預訂完工日私有欄位(稽核/系統欄
輸入日期/輸入人員/輸入地點/增刪修/選擇/管制碼/srvdbid/pkid/logid/linkid不列入比對。)新增
Common/Model/E.Order/Twork_ord_vw_ormastModel.cs流程樣板號(string,nvarchar(20),CY-only base 欄)
Model/Source/E.Order/Twork_ord_vw_ormastSource.cs流程樣板號(委派 Model,base 欄)
leadtimes、leadtimet(int,view JOIN 唯讀欄 → Source 私有欄位,不上傳)
Common/Model/E.Order/Twork_ord_vw_ordetlModel.cs預示資料(250)、預示比對(150)、比對說明1(150)、比對說明2(150)、回覆(250)(皆 CY-only base 欄)
Model/Source/E.Order/Twork_ord_vw_ordetlSource.cs預示資料、預示比對、比對說明1、比對說明2、回覆(委派 Model,base 欄)
停用(char(1))、停用日期(varchar(10))、預訂完工日(nvarchar(10))(view JOIN 唯讀欄 → Source 私有欄位,不上傳)
變更
無既有欄位行為變更。
vw_ordetl的品名早已由 Source 私有欄位_SKUDescription承接(符合 view-only 規範),不需調整。刪除
無。本次為純加法聯集;舊 Model 既存的 view JOIN 欄(如
客戶簡稱/姓名/中文描述等)未搬離 Model,因使用者本次未要求 Model 嚴格對應 base table。
Breaking Changes
無。
Migration Notes
- 本機 SQLite 由
EnsureCreated重建即帶新欄;缺欄走 LocalDbService 補欄安全網,無需手動 migration。
- 伺服器上傳沿用 ADR 0050 的 OPENXML 自動取交集,目標庫缺的 base 欄(如 NOGI 沒有
流程樣板號、預示資料等)會被自動略過,不影響存檔。
- view JOIN 唯讀欄走 Source 私有欄位、不在
GetModelBase()序列化,本就不會上傳。
-
06-30 customdash-sqlite-temptable-isolation ▸
2026-06-30 自訂查詢面板 SQLite 暫存表真正隔離(TempTableScope)
摘要
補上 CUSTOMDASH(ADR 0068)的 SQLite 盲區:同一支「SQLite 虛擬化型」查詢被寄生多份時,原本共用 per-ProgramClass/固定名的暫存表而互相 DROP/覆蓋。改以
IAppContext.TempTableScope統一隔離,每塊 tile 各自一張表。新增
Common/TempTableNaming.cs:共用後綴 helperApply(scope, table)(scope 空=原樣回傳)。
IAppContext.TempTableScope(+AppContext實作、CreateChildContext沿用)。
SQLiteForBrowse.DropScopedTables():tile 釋放時清掉本後綴的孤兒暫存表。
變更
SQLiteForBrowse:表名T()與清理改讀Context.TempTableScope(取代過渡期的私有 BrowseScope)。
InvpivotBll("invpivot")、Abook1Bll("abook1"):暫存表名帶TempTableScope後綴(寫讀同名)。
ProgramNavigator:寄生查詢時對該 tile 的 scoped context 設唯一TempTableScope。
- 3 個測試
IAppContext實作補TempTableScopestub。
刪除
無。
Breaking Changes
無。
TempTableScope=null(所有正常程式)時表名完全不變、行為零影響——只有 CUSTOMDASH 寄生實例會帶後綴。Migration Notes
- 經全專案掃描確認:
ExportToSqlite(~250 處)皆報表/列印、CreatePivotDateInSqlite皆樞紐 Excel、PurchQuerygrid 為記憶體型——皆非 grid 暫存表,不需隔離。grid 虛擬化只有兩條路(BrowseProvider→SQLiteForBrowse、SQLiteProvider<T>),都已涵蓋。
SQLiteProvider<T>不需改(接收的是已帶後綴的最終表名)。
- 範圍外同型 pattern:
Splace/Gsplace也用SQLiteProvider<T>固定表,但為主檔編輯表單(非查詢程式),CUSTOMDASH 不 host,未處理。
- runtime 僅模擬環境手動驗(INVPIVOT 同支多開)。
-
06-30 customdash-query-all-on-button ▸
2026-06-30 自訂查詢面板改回「按查詢一次全查」
摘要
CUSTOMDASH 原本是「切到分頁才查、每次切到重查」(ADR 0068 option a),用意是避開 SQLite 虛擬化型查詢共用暫存表被覆蓋。
TempTableScope上線讓每塊 tile 暫存表真正隔離後,重查的理由消失——改回使用者偏好的「按查詢按鈕=一次把每塊 tile 都查好」,之後切分頁只顯示既有結果、不重查。變更
CustomdashViewModel:
-
Query()建好 tiles 後呼叫新的全部查詢Async,直接驅動每塊寄生 VM 的Query()(背景緒)+UIUpdate()(UI 緒)一次全查。直呼 VM 而非走QueryButton,因 TabControl 虛擬化、非當前分頁的 View 沒掛ErrorCheckable,走QueryExecute會 NRE。-
SelectedTilesetter 不再觸發查詢(只更新選取)。刪除
切換查詢Async/自動查(lazy 切到就重查)。
CustomdashTileViewModel.查詢中(重入旗標,已不需要)。
Breaking Changes
無。
Migration Notes
- 依賴
TempTableScope暫存表隔離(2026-06-30 temptable changelog)才安全全查;該隔離不可回退。
- runtime 僅模擬環境手動驗。
-
06-30 customdash-parallel-query-per-tile-sqlite ▸
2026-06-30 自訂查詢面板:多支查詢改並行(per-tile 獨立 SQLite 檔)
摘要
CUSTOMDASH 按「查詢」原本一支查完才查下一支(序列)。改成限流並行:每塊 tile 各自一個實體 SQLite 暫存檔,SQL Server 查詢重疊、SQLite 寫入零鎖競爭。清單多支時明顯變快。詳見 ADR 0070。
變更
CustomdashViewModel.全部查詢Async:foreach … await序列 →SemaphoreSlim(4)限流 +Task.WhenAll並行。各塊查完才解除自己的「查詢中…」轉圈。
SQLiteCreatorFactory.GetTempDb:TempTableScope非空時把它接成UserDirectory子資料夾當快取 key/檔案路徑 → 每塊 tile 一個EnvironmentSettingDB.db。正常程式(scope 為空)行為完全不變。
- tile
Dispose:改成刪整個 per-tile 子資料夾 + 淘汰工廠快取項(取代逐表DropScopedTables)。
新增
ISQLiteCreatorFactory.RemoveTempDb(IAppContext):淘汰 per-tile 暫存 DB 快取項,避免 singleton cache 隨每次查詢堆積。
刪除
無。
Breaking Changes
無。
TempTableScope=null(所有正常程式)時暫存 DB 的 key/路徑/表名完全不變——只有 CUSTOMDASH 寄生 tile 會分檔。Migration Notes
- 並行前提:寄生查詢 VM 的
Query()須 scope 自足(無 static/跨 VM 共享可變狀態)。
- runtime 僅模擬環境手動驗(多支同頁並行)。
-
06-30 customdash-merge-print-pdf ▸
2026-06-30 自訂查詢面板:彙整列印(多查詢報表合併成單一 PDF)
摘要
CUSTOMDASH 自訂查詢面板頂端新增「彙整列印 (PDF)」按鈕:把清單裡的多支查詢各挑一張報表,合併成一份 PDF 預覽(預覽視窗內建「匯出PDF」即另存)。詳見 ADR 0071。
新增
- 面板頂端工具列「彙整列印 (PDF)」按鈕。
CustomdashPrintSelectViewModel+自訂查詢彙整列印選擇.xaml(ProgramClass.CUSTOMDASHPRINT):逐查詢勾選+報表下拉的選擇彈窗,無報表的查詢自動 disable。
PrintHelper.PrepareMergedReport(...):多支報表Load+Prepare(append)合併成一份 FastReport Report。
IContentWindowService.ReportPreviewPrepared(report):預覽「已 Prepare」的報表(不 re-Prepare,避免洗掉合併頁)。
CustomdashTileViewModel.ScopeContext:暴露 tile 的 scoped context,供 browse 型報表從 per-tile 暫存檔匯出資料。
變更
TsFastReportPreview建構子加alreadyPrepared旗標(預設 false,既有呼叫零影響)。
- 選擇彈窗改用
TsCheckBox/TsComboBox(原CheckBox/ComboBox);移除說明文字的顏色覆寫。
修正
PrintHelper.ExportDataToSqlitebrowse 路徑:原本用rpt.BrowseTables[i](server 不帶後綴表名)直接讀暫存 DB,但寄生查詢(TempTableScope 非空)的暫存表是帶後綴建的 → 讀到不存在的表 → 合併列印每筆都失敗、跳「沒有可列印的報表資料」。改成讀取/複製來源套TempTableNaming.Apply(TempTableScope, …)(目的表維持乾淨名)。正常程式 scope 為空=原樣,零影響。
- 註記:browse 報表沿用既有慣例,只輸出 grid 中已勾選的列(
CopyBrowseToOtherSqlite以SysIsSelected='Y'過濾)。彙整列印前請先在各查詢結果勾選要印的列。
刪除
無。
Breaking Changes
無。
Migration Notes
- 合併與匯出全走既有 FastReport,無新相依、不動 DB。
- runtime 僅模擬環境手動驗(多查詢挑報表→合併→預覽→匯出PDF)。
- 跨範本
Prepare(append)若 runtime 出現版面/資料問題,備案為改用 Telerik PdfProcessing 合併(見 ADR 0071)。
-
06-30 customdash-hosted-scope-session-inheritance ▸
2026-06-30 自訂查詢面板寄生 scope 繼承登入 session(修查詢 DataSourceRouter NRE)
摘要
CUSTOMDASH 按查詢時
Sql.SetLogSysExecCommand讀_context.DataSourceRouter.DbType拋 NullReferenceException。原因:寄生 tile 用的新 DI scope 取得的是全新未初始化AppContext,DataSourceRouter/User/EnvironmentSetting等登入時手動塞的 session 欄位都是空的。改為新 scope 主動繼承主 context 的 session 狀態。詳見 ADR 0069。新增
AppContext.InheritSessionFrom(IAppContext parent):把 parent 的 session 級服務(DataSourceRouter/User/EnvironmentSetting/LanguageService/MessageService等)灌進本實例;刻意不沿用SQLiteForBrowse/TempTableScope(維持每塊 tile 暫存表隔離)。
ProgramNavigator.CreateHostedScope()(private):統一「建 scope → 繼承 session → 設唯一TempTableScope」。
變更
ProgramNavigator三條寄生路徑改用CreateHostedScope():CreateHostedQueryProgram、CreateHostedContent、GetProgramDefaultParameter。scope 在建 vm 之前先初始化,確保 vm 與其注入的 Sql/BLL 拿到已填好的 context。
刪除
無。
Breaking Changes
無。只有 CUSTOMDASH 寄生路徑會走
CreateHostedScope;正常程式不開新 scope、不受影響。Migration Notes
- 暫存表隔離(ADR 0068 / 2026-06-30 TempTableScope changelog)不受影響:
SQLiteForBrowse與TempTableScope仍 scope-local。
- runtime 僅模擬環境手動驗(CUSTOMDASH 選查詢程式後按查詢)。
-
06-30 customdash-hosted-query-panel ▸
2026-06-30 自訂查詢面板(CUSTOMDASH,spike)
摘要
新增實驗性「自訂查詢面板」(ProgramClass
CUSTOMDASH,放 M.主管資訊):在下方查詢區選多支既有查詢程式、用各程式自己的中文條件畫面設條件、加入清單,按查詢後上方以 TsTab 分頁並列各查詢的原生結果表格。仍為 spike(未做存配置/拖拉版面)。新增
- 自訂查詢面板頁面:
- 查詢區:查詢型程式下拉(只列查詢型)→ 選了直接顯示該程式原生中文條件畫面 → 「加入清單」累積成查詢清單(可移除/清空)。
- 結果區:每支查詢一個 TsTab 分頁(標題=程式名稱),分頁內容=該程式原生 grid。
- 切到分頁就重查:只實體化當前分頁(省記憶體),每次切到用自己的條件重跑。
- 寄生工廠(
ProgramNavigator):CreateHostedQueryProgram/CreateHostedContent/GetHostableQueryPrograms/GetProgramDefaultParameter——以反射建出查詢程式 VM 並包成 layout 寄生,不進導覽快取。
- dev-programs.json 加
CUSTOMDASH(M-D3);App.xaml 2 個 DataTemplate;DI 註冊CustomdashConditionViewModel。
變更
- 條件不再以 JSON 編輯,改用各程式原生條件畫面(全中文)。內部仍以英文屬性名 JSON 儲存(使用者看不到),查詢時
PopulateObject灌回。
- 每塊分頁各自一個 DI scope → 參數隔離(同支多開、與正常開的同支互不干擾)。
刪除
無。
Breaking Changes
無(純新增)。
Migration Notes
- 開發機:
dev-programs.json已含CUSTOMDASH,啟用DevPrograms重新登入即見。正式環境需usp_新增程式登錄(尚未產 SQL,spike 階段)。
- 已知限制:SQLite 虛擬化型查詢的 per-ProgramClass 暫存表為共用資源,DI scope 隔離不到;靠「切到就重查」在循序檢視下顯示正確,快速來回切/與正常程式並跑仍可能撞表。真正隔離需 StagingScope(ADR 0043),未做。
- runtime 僅模擬環境手動驗。
-
06-30 CUQT-union-sync ▸
CUQT 兩庫欄位聯集同步(darbnogicsa1 ∪ darbcycsa1)
摘要
依
_sheetno查得 CUQT(客戶報價單)主表cuqtm/vw_cuqtm、子表1cuqtd1/vw_cuqtd1、子表2cuqtd2(無 view)。比對鈞寶(
darbnogicsa1)與朝陽(darbcycsa1)兩庫 base table 與 view 欄位,取聯集後同步回程式。屬 ADR 0050(多客戶差異處理)的延伸,未新開 ADR。
⚠️ 類別命名對應(TableMap.json)
CUQT 子表類別名稱與實體表有刻意的位移,務必對照
TsERP/Lang/TableMap.json:實體表 中文 對應類別 cuqtm報價主檔 Twork_ord_vw_cuqtmcuqtd1材料明細 Twork_ord_vw_cuqtd(無數字)cuqtd2加工明細 Twork_ord_vw_cuqtd1(帶 1)比對結果
物件 NOGI CY 差異 處理 base cuqtm49 39 CY 多 單品報價別/美元匯率/日圓匯率/模費轉訂單;NOGI 多報價類別/序號前置碼/報價人員/有效期限/最低訂單量/圖檔名稱/模穴數/材質/生產機器/注意事項/模具摘要/聯絡單id/工作流程/已審核Model+Source 補 4 個 CY-only 欄(NOGI 欄早已齊全) view vw_cuqtm52 42 view-only JOIN 客戶簡稱/說明/廠商簡稱(兩庫相同,皆已存在)無新增 base cuqtd1(材料明細,類別cuqtd)20 25 CY 多 原始品號/淨數量/材料費/加工費/殘料量/殘料單價;NOGI 多損耗率Model+Source 補 6 個 CY-only 欄 view vw_cuqtd121 26 view-only JOIN 廠商簡稱(兩庫相同,已存在)無新增 base cuqtd2(加工明細,類別cuqtd1)14 13 CY 多 費率_分/裸價模具費/模具費;NOGI 多費率/裸價治具費/治具費/參考加工費Model+Source 補 3 個 CY-only 欄;無 view (稽核/系統欄
輸入日期/輸入人員/輸入地點/增刪修/選擇/管制碼/srvdbid/pkid/logid/linkid不列入比對。)新增
Twork_ord_vw_cuqtmModel/Twork_ord_vw_cuqtmSource(報價主檔)單品報價別(char(1))、美元匯率(numeric(12,4))、日圓匯率(numeric(12,4))、模費轉訂單(char(1))
Twork_ord_vw_cuqtdModel/Twork_ord_vw_cuqtdSource(材料明細,實體cuqtd1)原始品號(nvarchar(30))、淨數量(numeric(15,4))、材料費(numeric(16,6))、加工費(numeric(16,6))、殘料量(numeric(11,5))、殘料單價(numeric(16,6))
Twork_ord_vw_cuqtd1Model/Twork_ord_vw_cuqtd1Source(加工明細,實體cuqtd2)費率_分(money(19,4))、裸價模具費(int)、模具費(int)
全部為 base table 聯集欄、Source 委派 Model。本次無新增 view-only JOIN 欄(
客戶簡稱/說明/廠商簡稱/廠商簡稱/品名早已存在)。變更
無既有欄位行為變更。
刪除
無。純加法聯集;舊 Model 既存的 view JOIN 欄(
客戶簡稱/說明/廠商簡稱)未搬離 Model,因本次未要求 Model 嚴格對應 base table。已知缺口(非本次處理)
- 實體
cuqtd2(加工明細)在_sheetno列為子表2,無對應 view,且新系統的Twork_ord_vw_cuqtd1類別已承接其欄位(命名位移,見上表)。_sheetno的「子表2cuqtd2」本身沒有獨立的Twork_ord_vw_cuqtd2類別——這是既有架構(cuqtd1↔cuqtd、cuqtd2↔cuqtd1),非缺漏。
Breaking Changes
無。
Migration Notes
- 本機 SQLite 由
EnsureCreated重建即帶新欄;缺欄走 LocalDbService 補欄安全網,無需手動 migration。
- 伺服器上傳沿用 ADR 0050 的 OPENXML 自動取交集,目標庫缺的 base 欄(如 NOGI 沒有
美元匯率、CY 沒有損耗率/參考加工費等)會被自動略過,不影響存檔。
- view JOIN 唯讀欄走 Model 既有欄位承接(本案未新增),不影響上傳。
-
06-30 CUQT-cy-cost-model ▸
CUQT 客戶報價單 — CY(朝陽/鈞寶) 成本模型還原
摘要
繼 CUQT 兩庫欄位聯集同步(commit d96e609c)補齊 DB 欄位後,本次把 CY 版客戶報價單的成本計算與 UI 還原到 VFP
scx_ord_cy/cuqt的口徑。對比報告指出新版整支原本照 NOGI 做,導致 CY 客戶的加工費、模具/治具分攤費會算成 0 或錯值。屬 ADR 0050(多客戶差異處理)的延伸,未新開 ADR。決策:依使用者裁示,本表單顯示直接切成 CY 版(不做 prgsct1 gating),計算邏輯仍以
CompanyShortName(朝陽/鈞寶)分支以保非 CY 路徑安全。新增(UI 欄位)
主檔(
Cuqt.xaml)模具組數、治具組數:CY 模具分攤費的兩個獨立分母(VFP cuqt_cy 行1926-1927)。
材料明細 grid
淨數量、材料費、加工費、殘料量、殘料單價:CY 專屬成本拆解欄(純輸入/顯示,無自動計算)。
加工明細 grid(改為 CY 版)
- 新增
費率(分)(費率_分)、裸價模具費、模具費;移除 NOGI 專屬的費率、裸價治具費、治具費、參考加工費顯示。
變更(計算邏輯)
- 加工金額:CY 改用
次數 × 加工時間 × 費率_分(VFP 行1916/1984);非 CY 維持費率。Twork_ord_vw_cuqtd1Source.Get加工金額()依CompanyShortName分支,新增費率_分Binding觸發重算。
- 主檔治具價格:CY 彙總加工明細的
模具費欄(VFP 行1916),非 NOGI 的治具費。CuqtViewModel.Sum()。
- 族群寫回:VFP 行1929-1941 —
單品報價別='1'(族群) 時不把彙總寫回主檔;其餘才寫回。CuqtViewModel.Sum()以if (單品報價別 != "1")包住主檔寫回。
- 連動重算:master listener 加入
模具組數/治具組數;detail1 listener 加入模具費,使 CY 欄編輯即時觸發Sum()。
- 單價連動(業務新規則,VFP 無此邏輯):材料明細
材料費/加工費異動 →單價 = 材料費 + 加工費,經既有單價Binding連帶重算材料金額(=數量×單價) 與單價百分比,再觸發主檔Sum()。單價仍維持可手動覆寫。Twork_ord_vw_cuqtdSource新增材料費Binding/加工費Binding。
- 百分比顯示(先前 commit c7cdb602):
單價百分比/加工時間百分比補*100。
刪除
加工明細 grid 不再顯示 NOGI 的
費率/裸價治具費/治具費/參考加工費欄(屬性仍保留於 Source/Model,僅移除 UI)。Breaking Changes
本表單顯示改為 CY 版:非 CY(朝陽/鈞寶) 部署的加工明細將看不到
費率/治具費輸入欄。計算分支雖保留非 CY 路徑,但 UI 已不支援非 CY 輸入。實際部署客戶皆為 CY,影響為零。待確認 / 後續
原始品號(材料明細)VFP 無對應 grid 欄,未露出。
Migration Notes
- 純程式變更,無 DB migration(欄位已於 d96e609c 補齊)。
- 本機 SQLite 由
EnsureCreated重建即帶新欄。
驗收條件
1. CY:填 次數/加工時間/費率_分 → 加工金額 = 次數×加工時間×費率_分;加工費彙總正確。
2. CY:加工明細模具費 → 主檔治具價格正確;治具組數>0 → 模具分攤費含治具分攤。
3. CY:模具組數>0 → 模具分攤費含模具分攤。
4. 報價金額 = 材料費+材料利益+加工費+加工利益+包裝費+運費+關稅+模具分攤費。
5. 單品報價別='1'(族群) 時主檔彙總欄不被明細覆蓋。
6. 材料明細輸入材料費/加工費 → 單價自動=材料費+加工費、材料金額=數量×單價隨之更新;單價仍可手動改。
-
06-29 tssearchtextbox-v1-validation-fix ▸
2026-06-29 — 修復 V1 `TsSearchTextBox` 存在性驗證形同虛設
摘要
修正舊版(V1)
TsSearchTextBox搜尋欄輸入不存在的代號卻不會跳錯的問題。根因:
OnApplyTemplate建好了帶TsSearchRule(資料存在性)/PrimaryKeyRule(主鍵)驗證規則的 binding,卻漏呼叫
BindingOperations.SetBinding套回控件,導致規則建好即丟棄、實際 binding 沒有任何驗證。新版
TsSearchTextBoxV2早已修掉此問題(且留有註解),V1 一直沒同步。本次把 V1 對齊 V2。
變更
TsControl/TextBox/TsSearchTextBox.cs:OnApplyTemplate在加完驗證規則後,
以
ruleAdded旗標守護並呼叫BindingOperations.SetBinding(this, TextBox.TextProperty, newBinding)把帶規則的 binding 套回(與
TsSearchTextBoxV2寫法一致)。影響範圍(Breaking-ish 行為變更)
- 所有 使用 V1
TsSearchTextBox且CheckDataExist=true(預設)的欄位,
自即日起會在失焦時驗證代號是否存在於
ExistTable:- 查無 → 嗶聲 + 跳「資料不存在」訊息框 + 紅框,且存檔會被擋。
-
IsPrimaryKey=true的欄位同步啟用主鍵驗證。- 這是還原本來就該有的行為(屬性預設值即
CheckDataExist=true),
但等於讓多支沿用 V1 的表單「突然開始擋」以前默默吃下的亂輸入。
- 觸發本次調查的案例:
Eventproject.xaml的「負責人」(EmployeeSearchstyle,
查
perdata.員工編號)以前亂打不擋,現會擋。注意事項
- 若有欄位本來就允許自由輸入(非主檔代號)卻沒顯式設
CheckDataExist="False",
修正後會被誤擋——請改設
CheckDataExist="False"。建議回歸時重點測 V1 搜尋欄較多的表單。DeepCopyBinding已完整複製Mode/UpdateSourceTrigger/ValidatesOnExceptions/
NotifyOnValidationError等屬性,重新套 binding 不會掉設定。- TsControl 專案已用 VS MSBuild 建置通過(僅既有無關警告)。
-
06-29 safetystock-mailqueue ▸
2026-06-29 安全庫存自動檢查補寄信(TWORK_AUTO_SAFETYSTOCK → mailqueue)
摘要
行事曆「安全庫存檢查」事件自動執行後,原本只把缺料結果寫進
twork_auto_safetystockhistory並回寫 eventitem,從未把信排進
twork_skd_mailqueue,所以 SchedulerWorker 的寄信路徑(Mailgun)永遠撈不到信、收件人收不到通知。
依
darbnogicsa20260513庫內較新版本的TWORK_AUTO_SAFETYSTOCK,把「撈收件人 → 把未達安全庫存清單渲染成 HTML 表格 →
INSERT twork_skd_mailqueue」這段補回 repo 的母本與各客戶部署腳本。變更
SqlBI/TWORK_AUTO_SAFETYSTOCK.sql(csa 母本/對照)— proc 結尾加入寄信段。
sql/deploy-darbnogiauto1.sql(鈞寶集中自動化庫部署版)— 同步加入。
sql/deploy-darbcyauto1.sql(朝陽集中自動化庫部署版,包在EXEC(N'...')內,引號加倍)— 同步加入。
寄信段行為:
1. 從
twork_skd_eventitem.通知帳號(事件設定畫面維護)取收件人;空白則RETURN(不影響本次執行成功狀態)。2. 本次 GUID 批次無缺料品項(
@rowCount = 0)則不寄。3. 主旨:
【安全庫存檢查通知】<日期> 共 N 筆未達安全庫存。4. 內文:HTML 表格(品號/品名/安全庫存/現有數量/滿足安全/M0–M6),現有數量紅字標示。
5.
INSERT dbo.twork_skd_mailqueue(收件人, 主旨, 內文, 是否HTML='Y', 來源預存程序, 執行guid),交由 AP 端
TsERP.SchedulerWorker的DequeueMailAsync經 Mailgun 寄出。Breaking Changes
無。proc 對外回傳的結果集與既有 history 寫入不變,僅在最後多排一封信。
Migration Notes
⚠️ 需在各客戶的集中自動化庫重跑部署腳本才會生效(本機已
SET PARSEONLY驗證文法,未實際部署):sqlcmd -S <server> -E -f 65001 -i sql\deploy-darbnogiauto1.sql # 鈞寶 sqlcmd -S <server> -E -f 65001 -i sql\deploy-darbcyauto1.sql # 朝陽前置:
twork_skd_mailqueue表(部署腳本內已含建表)。
- CY 版另有既有 guard:
darbcycsa1.dbo.twork_skd_eventitem需有執行guid欄,缺欄會跳過建 proc。
- 事件需在行事曆設定「通知帳號」(收件人),否則只寫 history 不寄信。
-
06-29 gldash-general-ledger-dashboard ▸
2026-06-29 總帳儀表板(GLDASH)
摘要
總帳管理(N.總帳管理)新增一支「總帳儀表板」(ProgramClass
GLDASH),比照主管儀表板(EISDASH)的版面,讓主管一頁綜覽財務全貌:損益、資產負債、費用趨勢、傳票與現金。四塊資料全部重用既有作業的 SP / BLL,不需部署任何新 SP,也不需 proc_param 登錄。新增
- 總帳儀表板頁面:工具列(本月/本季/本年/自訂日期快切 + 自動刷新 + 重新整理)+ 8 張 KPI 卡 + 2×2 圖表 + 2 張清單。
- KPI 卡(本期):本期營收、營業毛利(含毛利率)、營業費用、本期淨利(含淨利率,虧損紅字)、總資產、總負債(含負債比)、現金與銀行、本期傳票(含未過帳張數警示)。
- 圖表:損益結構長條(營收→成本→毛利→費用→營業利益→本期損益)、營業費用逐月趨勢、資產=負債+權益環圈、現金/銀行結餘趨勢(含票據預估)。
- 清單:未過帳傳票、本期費用科目 Top 10。
- 點擊卡片/圖表可直達對應總帳作業(損益表/資產負債表/會計日記帳/銀行金流),到頁後自動帶儀表板當前日期區間並自動查詢(不必再手動設條件或按查詢)。銀行金流因日期語意是現金流預估到期日、非查詢區間,故沿用其自身預設。
- 資料來源(皆重用既有):損益與費用走
IncomeBll(DARB_QRY_INCOME)、資產負債走BalanceBll(DARB_QRY_BALANCE)、傳票走SliybrowdBll(DARB_BD_SLIY)、現金走BankflowBll。
- 選單登錄 SQL:
sql/總帳儀表板_register_program_darbnogicsa1.sql(沿用「資產負債表」選單群組、自動取未使用 N-NN 序號)。
- 開發機免動 DB:
dev-programs.json已加GLDASH一筆(啟用DevPrograms後重新登入即見)。
變更
- 金額統一以本位幣顯示。
- 各區塊獨立載入、錯誤隔離:任一塊讀取失敗只該卡片/圖表顯示「讀取失敗」,不影響其他區塊。
刪除
無。
Breaking Changes
無。
Migration Notes
- 正式環境部署:執行
sql/總帳儀表板_register_program_darbnogicsa1.sql一次即可(前置:usp_新增程式已部署於該庫)。
- 無新 SP、無 proc_param、無資料 migration。
- 第一版只呈現當期數字,未做 YoY/MoM 比較基準;runtime 尚未驗收。
-
06-29 eventproject-register-cy ▸
2026-06-29 — EVENTPROJECT(排程事件(專案))補登錄到朝陽 CY
摘要
把 NOGI(
darbnogicsa1)已登錄的 EVENTPROJECT(排程事件(專案))程式,照搬補登錄到朝陽 CY(
darbcycsa1)的四張中繼資料表_menum/_menud/_sheetno/_tableseq,讓「排程事件(專案)」表單在 CY 的 L.聯絡傳訊 模組也能從主選單開啟與建立單號。
新增
sql/eventproject_register_program_darbcycsa1.sql:冪等部署腳本,
以同伺服器跨庫
INSERT...SELECT從darbnogicsa1複製 EVENTPROJECT 四列。四表各以
NOT EXISTS守護,可重複執行。變更(兩處必要偏離,其餘逐欄原樣複製)
- 選單序號:NOGI 用
L-05,但 CY 的L-05已被PROMOT_QRY
(提案資料查詢)占用。腳本於 L.聯絡傳訊 模組自動挑「現有最大序號 +1」的
第一個空號(本次 →
L-07,附加在選單末端)。_tableseq.seqval:NOGI=5,CY 為全新安裝無任何 EVENTPROJECT 單據,
計數器歸 0(與
usp_新增程式慣例一致),單號從頭起算。srvdbid改用 CY 自身值;pkid重算(_sheetno.pkid為 identity)。
Migration Notes
- 執行(中文物件,務必其一,避免 sqlcmd 預設 codepage 靜默漏建):
sqlcmd -S localhost -E -f 65001 -i sql\eventproject_register_program_darbcycsa1.sql或於 SSMS 開檔執行。
- 已在模擬環境(localhost)實跑驗證:四列成功新增、再跑一次全部略過(冪等)。
- 本腳本只動四張選單/單號中繼表;不建
prgsct1權限列、不改 proc。
使用者權限(可否瀏覽/修改)若需要,另循既有
prgsct1流程補。- 相依資料表
twork_skd_eventitemm/twork_skd_eventitem在 CY 已存在;
但排程「自動執行」鏈在 CY csa 仍有落後(見 ADR 0065 備註:CY 缺
twork_skd_eventitem部分欄位、twork_vw_calendareventview 待修),表單本身的登錄/建單不受影響。
-
06-29 efficiency-query-radgrid-tstab-condition ▸
2026-06-29 個人/期間效率統計改用 TsRadGridView + TsTab,條件面板整理
摘要
CY 主管資訊「個人效率統計」(pd_qry1) 與「期間效率統計」(pd_qry2) 內部仍混用舊 WPF 控件,與其餘查詢頁不一致;查詢條件面板排版凌亂、且未標示各條件適用於哪個分頁。本次統一改版並標註。
變更
TsERP/M.EIS/個人效率統計.xaml:左側「生產部門」勾選表DataGrid→TsRadGridView(選擇用TsGridViewCheckBoxColumn,bool 直綁)。結果格本即 TsRadGridView。補ProgramClass="Pd_qry1"啟用欄位版型持久化。此頁無分頁。
TsERP/M.EIS/期間效率統計.xaml:
- 左側「生產部門」
DataGrid→TsRadGridView。- 外層
TabControl(BottomTab 樣式)→TsControl:TsTabControl/TsTabItem(Header 用TsTextBlock)。- 三個結果格補
ProgramClass="Pd_qry2"。TsERP/M.EIS/個人效率統計Condition.xaml:改用 GroupBox(藍色標題「查詢條件(個人效率統計)」),起訖日期一列。
TsERP/M.EIS/期間效率統計Condition.xaml:拆成兩個 GroupBox 並標註適用分頁:
- 「共用條件 · 全部分頁適用」(藍):起訖日期(部門期間效率 / 組立狀況一覽表 / 期間工時調整一覽表 皆適用)。
- 「僅『組立狀況一覽表』分頁適用」(橘):品號類型(4 選 2×2)、起訖品號、查詢效率。
- 分頁對應依
Pd_qry2ViewModel.Query()實際邏輯確認(tab0/tab2 只用起訖日期;tab1 才用品號/效率/品號類型)。影響範圍
- 兩支查詢頁的外觀與其餘查詢頁一致;條件面板可一眼看出哪些條件只對「組立狀況一覽表」生效。
- 純 View 層(XAML)調整,未改 VM/BLL/邏輯與既有資料繫結(
StartDate/EndDate、RadioButtonCheck+RadioConverter、起始品號/截止品號、起始效率/截止效率、選擇、各結果 Source 維持原樣)。
Breaking Changes
無。
Migration Notes
- 改動在
TsERP組件,需重建 TsERP。runtime 行為(查詢結果)不變。
-
06-29 cy-eventitem-param-width-fix ▸
2026-06-29 修復 CY 行事曆事件「執行」按鈕 JSON 截斷錯誤
摘要
在 CY(darbcycsa1)行事曆單獨按某事件的「執行」按鈕,出現:
ExecuteAsync異常: Unterminated string. Expected delimiter: ". Path 'LP_P1', line 1, position 100. at Newtonsoft.Json.Linq.JObject.Parse(...) at AutoPilot.AutoPilotHelper.ExecuteMethod(...)根因:
twork_skd_eventitem.參數欄位在 CY 是nvarchar(100),母本 darbnogicsa1 是nvarchar(4000)(schema 分歧)。AutoPilot 排程事件的 JSON 參數約 113 字,寫入時被 DB 靜默截斷到 100 字,剛好斷在"LP_P1":"之後,尾巴{eventpkid}"}不見 →JObject.Parse在 position 100 失敗。App 端 Source 宣告[TsStringLength(4000)],本就預期 4000。範圍:darbcycsa1 安全庫存排程事件 265 筆參數全部被截斷。
變更
- 新增
sql/fix_eventitem_param_width_darbcycsa1.sql:
1.
ALTER TABLE twork_skd_eventitem ALTER COLUMN 參數 nvarchar(4000)對齊母本。2. 還原被截斷的事件參數為完整模板
{"DataEvent":"AutopilotLogSysExec","Procedure":"TWORK_AUTO_SAFETYSTOCK","Dispatcher":"SKD","LP_P1":"{eventpkid}"}({eventpkid}由SchedulePlaceholders.ReplaceExecutionEventPkidTokens在執行期替換)。影響範圍
- CY 行事曆事件「執行」按鈕:參數可正確解析並派發
TWORK_AUTO_SAFETYSTOCK(@eventitempkid)。
- 僅補欄寬與還原資料,未改 AutoPilot/SP 邏輯。
Breaking Changes
無。
Migration Notes
- 此為 darbcycsa1 的 schema + 資料修正,需在 darbcycsa1 執行
sql/fix_eventitem_param_width_darbcycsa1.sql。
- ⚠️ 本次因安全機制未由工具直接套用到模擬環境,需手動執行該腳本後才生效。
- 其他客戶庫(darbkccsa1 / darbzdcsa1 / darbcmacsa1 等)可能有相同欄寬分歧,尚未逐庫盤點。
- 新增
-
06-29 cy-calendar-system-events-sp-fix ▸
2026-06-29 修復 CY 行事曆看不到系統事件(SP 漏 or 9)
摘要
朝陽 CY(darbcycsa1)以管理員登入後,右側行事曆已能看到「系統」篩選器,但底下沒有任何系統事件。
根因:darbcycsa1 實際部署的
TWORK_SKD_GETEVENT與母本(darbnogicsa1,SqlBI/TWORK_SKD_GETEVENT.sql)分歧——第一段 @list 來源只有擁有者所屬類別=0(公司),漏了or 擁有者所屬類別=9(系統),導致系統事件永遠不進結果集。資料本身存在(darbcycsa1 有 265 筆系統事件,2026-06 就有 5 筆,皆已審核=Y、項目類型=0),純粹是 SP 不撈。(與前一則 admin Trim 修復
2026-06-28-admin-role-trim-fix是接續:先修好 admin 判定讓「系統」篩選器顯示,才發現 SP 這層也漏。)變更
- DB(darbcycsa1):
ALTER PROCEDURE TWORK_SKD_GETEVENT,第一段where 擁有者所屬類別=0→where 擁有者所屬類別=0 or 擁有者所屬類別=9。CY 專屬的部門 JOIN(twork_bas_vw_dept/DepartmentCode/EmployeeCode)原樣保留,未套母本 schema。
- repo:新增
sql/TWORK_SKD_GETEVENT_darbcycsa1.sql,把修正後的 CY 變體納入版控(含與母本差異註記),避免重佈又掉回舊版。
影響範圍
- CY 行事曆:管理員登入即可看到系統事件(驗證:
EXEC TWORK_SKD_GETEVENT '2026/06/29','CMSA'由 0 筆 → 5 筆系統事件)。
- 系統(9) 是否限管理員仍由前端 UI 把關(DB 端不做 admin 過濾,非硬邊界);如需 DB 端硬邊界另議。
Breaking Changes
無。
Migration Notes
- 此為 darbcycsa1 的 SP 變更,已於模擬環境套用;正式佈署各 CY 庫時請跑
sql/TWORK_SKD_GETEVENT_darbcycsa1.sql。
- 其他客戶庫(darbkccsa1 / darbzdcsa1 / darbcmacsa1 等)可能有相同「漏 or 9」分歧,尚未逐庫盤點。
- DB(darbcycsa1):
-
06-29 checkpayprint-blank-fix ▸
2026-06-29 修正支票套印(上海商銀 / Checkpayprint)列印空白
摘要
支票列印彈窗(
CheckPrintViewModel,由應付票據 checkpay 的「支票列印」鈕開啟)中,程式碼註冊的「上海商銀」報表項(
報表名稱 = "Checkpayprint")選取後會套印空白。變更
TworkReportPluginOfficial/Checkpayprint.cs:ExportToSQLite原本是空殼(直接return true、
未把資料寫入 SQLite),補成讀取
parameters["rpt_o030_checkpayreportpoco1"]並ReportSqliteCreator.ExportToSqlite(...),與Checkpayzd1/Checkpayzd2行為一致。原有的
SetParameters(注入公司電話/傳真/地址)保留不動。根因
PluginHelper.GetReportPlugin(插件名稱, 報表名稱)在插件名稱留空時,會以報表名稱找同名plugin class。該報表項未設
插件名稱,於是 fallback 到同名的Checkpayprintplugin——但它的ExportToSQLite沒有把ReportSource資料寫進共用表rpt_o030_checkpay_report1,導致報表讀到空表(或殘留舊資料)。會正確匯出的
Checkpayzd1/zd2(DB 註冊的各銀行版型用)才是正常路徑。影響範圍
- 只影響選取程式碼註冊的「上海商銀 / Checkpayprint」那一筆;DB 註冊的支票套表銀行版型
(走
Checkpayzd1/zd2plugin)不受影響、原本就正常。- 預設選取為清單第一筆(DB 版型),故僅在使用者手動切到該筆時才會踩到。
Breaking Changes / Migration Notes
無。純行為修正,不需資料庫或設定異動。
待驗
- 實機列印確認:套印確實帶出資料(金額、金額大寫、民國年/月/天、支票抬頭)。
-
06-29 admin-role-trim-fix ▸
2026-06-29 修復管理員角色判定未 Trim 空白導致誤判非管理員
摘要
以管理員帳號(
管制系統欄位設為ADMIN)登入,仍被判為非管理員 → 看不到行事曆「系統」事件、以及其他靠IsAdmin()開放的功能。根因:
UserBll.CheckRoleInManagedAccount把管制系統(逗號分隔角色字串)ToLower()後Split(','),但沒有 Trim 各 token。當管制系統是固定寬度 CHAR 欄位(尾端補空白)或手動輸入夾帶空白時,token 會是"admin ",與"admin"不相等 →Contains回 false →IsAdmin()誤判為非管理員。大小寫本來就有處理(兩邊皆ToLower()),不是問題。變更
LogicBll/Login/UserBll.csCheckRoleInManagedAccount:
-
Split(',')後對每個 tokenTrim();比對的role也Trim().ToLower()。- 修正後
"ADMIN"、"ADMIN "、"Manager, Admin"等皆能正確判定為管理員。影響範圍
- 所有透過
IUser.IsAdmin()/CheckRoleInManagedAccount判斷的功能(如右側行事曆「系統」事件可見性CalendarPageViewModel.RefreshUserPermission、其他管理員專屬入口)。
- 只放寬「空白容錯」,不改變角色語意;原本就正確(無空白)的設定行為不變。
Breaking Changes
無。
Migration Notes
- 改動在
LogicBll組件,需重建 TsERP;IsAdmin在登入時依管制系統計算,需重新登入才生效。
- 資料面不需調整;即使
管制系統欄位是 CHAR 補空白或含手動空白,現在都能正確判定。
-
06-28 radgridview-reenable-column-virtualization ▸
2026-06-28 TsRadGridView 重新開啟欄虛擬化(MinColumnWidth 撐住水平捲軸)
摘要
全 app 共用表格
TsRadGridView/TsBrowseRadGridView重新開啟欄虛擬化(取代 ADR 0026 的全域關閉),並用
MinColumnWidth=50把每欄寬度下限拉高,讓欄虛擬化下未實體化的SizeToHeader/Auto欄仍以真實寬度計入水平
ExtentWidth,避免當初「水平捲軸間歇拖不動」重演。變更
TsControl/Themes/TsRadGridViewGeneric.xaml(TsRadGridView、TsBrowseRadGridView兩個 Style):
-
EnableColumnVirtualization由False改為True。- 新增
MinColumnWidth=50。影響範圍
- 全 app 所有
TsRadGridView/TsBrowseRadGridView。
- 寬表(Sliy、總帳類等數十欄)恢復欄虛擬化 → 記憶體/載入/捲動效能回升。
- 各 grid 的窄欄(序號、選擇欄等)寬度下限變為 50px,原本更窄者會略變寬。
- 仍有 local
EnableColumnVirtualization="False"的頁面(ErpPivotQuery2 個 grid、Receivepq1 個 grid)
維持非虛擬化,視為刻意例外,本次未動。
Breaking Changes
無。
Migration Notes
- 需重建 TsERP 才會生效(改動在 TsControl 共用樣式)。
- ⚠️ 需 runtime 驗收:請在 Sliy / SliyTurn / 總帳類寬表實機確認水平捲軸可順拖、欄捲入時寬度正常。
若捲軸仍塌陷,退路為該類寬表欄改固定 px 寬,或回退(兩個 setter 改回 False / 移除 MinColumnWidth)。
- 詳見 ADR 0064。
-
06-28 pivotselector-selection-not-applied ▸
2026-06-28 樞紐選擇器選取項目未生效修復
摘要
查詢/瀏覽類畫面(如 inventquery)底部「樞紐分析表」選擇器(
PivotSelector1)的 combobox 雖可下拉選取,但按下「樞紐分析表」鈕後永遠用清單第一筆的樣板檔開啟,不管使用者實際選了哪一項。原因是控件的選取值沒有回寫到 ViewModel:
1.
PivotSelector1.xaml把 VM 的SelectedItem用預設模式綁到TsComboBoxWithDescription.SelectedItem,但該 DP 未標記BindsTwoWayByDefault,所以是 OneWay(只 VM→控件)。2.
TsComboBoxWithDescription內層 combobox 選取變更時(ComboBox_OnSelectionChanged)只更新Code/Description,從不回寫自己的SelectedItemDP。3. 另一個
Code="{Binding SelectedItem.Code, Mode=OneWay}"綁定是 OneWay 且指向唯讀巢狀路徑,控件裡的UpdateSource()形同空操作。結果:VM 的
SelectedItem始終停在ItemsSourcesetter 初始化的ItemsSource[0],PivotExecute拿它的檔名去組樣板路徑,於是永遠開第一筆。(這是 樞紐選擇器 combobox 在查詢畫面無法下拉修復 的後續:combobox 解鎖能下拉後,選取沒接回 VM 這條暗 bug 才浮現。)
變更
ViewModel/Control/PivotSelector1ViewModel.cs:新增SelectedCode字串屬性,綁到控件的Code(TwoWay-by-default、選取變更時會被推回);setter 依Code從ItemsSource解析出對應的SelectedItem。ItemsSourcesetter 初始化改設SelectedCode = ItemsSource[0].Code(初始仍選第一筆)。
TsControl/Layout/PivotSelector1.xaml:combobox 綁定改為Code="{Binding SelectedCode, Mode=TwoWay}",移除無作用的SelectedItem="{Binding SelectedItem}"與 OneWay 的Code綁定。
影響範圍
- 樞紐選擇器(
PivotSelector1):使用者選哪一項,就用該項對應的樣板檔開啟。
- 未動到共用控件
TsComboBoxWithDescription本身,其餘 64 處用法行為不變。
Breaking Changes
無。
Migration Notes
改動含 TsControl 共用控件所在組件,需重建整個 TsERP 才會完整生效。
-
06-28 pivotselector-combobox-locked ▸
2026-06-28 樞紐選擇器 combobox 在查詢畫面無法下拉修復
摘要
查詢/瀏覽類畫面(如 inventquery)底部「樞紐分析表」選擇器(
PivotSelector1)的 combobox 點不開下拉選單。原因是三件事疊在一起:
1.
TsComboBox(全 app 共用,繼承RadComboBox)2026-04 加入的IsLocked機制,在OnPreviewMouseDown會把滑鼠點擊吃掉並強制關閉下拉。2.
TsComboBox的全域預設樣式(Generic.xaml)把IsLocked綁到所在表單的編輯狀態:FindAncestor(ITsContentControl).DataContext.ViewModelStatus.Status經AdeStatusIsReadOnlyConverter轉換,FallbackValue=true。3.
AdeStatusIsReadOnlyConverter除Empty/Add/Edit/Copy/SpecialEdit外一律回傳true(鎖定)。查詢畫面停在Normal狀態 → 回true→IsLocked=true→ 下拉永遠打不開。樞紐選擇器是「工具型」控件,在瀏覽(Normal)狀態下本就該可操作,卻被全域 combobox「非編輯就鎖」的樣式波及。
變更
TsControl/CombineComboBox/TsComboBoxWithDescription.xaml.cs:新增 opt-in 相依屬性IgnoreEditStatus(預設false)。為true時用區域值把內層TsComboBox.IsLocked覆寫成false(永遠解鎖)、為false時ClearValue還原成預設樣式的狀態綁定;另在Loaded補套用一次以防屬性早於內層控件設定。
TsControl/Layout/PivotSelector1.xaml:combobox 加上IgnoreEditStatus="True"。
影響範圍
- 樞紐選擇器(
PivotSelector1)的 combobox:任何狀態下皆可下拉。
- 其餘 64 處
TsComboBoxWithDescription用途:IgnoreEditStatus預設false,行為完全不變(維持「非編輯狀態鎖定」)。
Breaking Changes
無。
Migration Notes
需重建 TsERP 才會生效(改動在 TsControl 共用控件)。
-
06-28 order-pivot-templates-dbf-to-sqlite ▸
2026-06-28 訂單樞紐樣板資料來源 DBF→SQLite
摘要
把
C:\dglibrary\REPORTSROOT\Template下三支訂單樞紐分析樣板的外部資料來源從 Visual FoxPro DBF 改為 SQLite,並清空殘留的舊快取,比照已轉好的
部門費用統計表.xlsx連線格式。涉及檔案:
客戶訂單品號數量統計.xlsx
訂單生產部門查詢.xlsx
訂單資料樞紐查詢.xlsx
變更
連線字串(`xl/connections.xml`)
項目 變更前 變更後 連線 DSN=Visual FoxPro Tables;SourceDB=c:\TEMPS\PIVOT;SourceType=DBF;…DRIVER={SQLite3 ODBC Driver};Database=C:\Temps\Sqlite\Twork_TW.db;資料表 ` SELECT * FROM訂單明細_d`` SELECT * FROMDARB_BD_ORMAST00`- DBF 的
訂單明細_d(37–39 欄)對應 SQLiteTwork_TW.db的DARB_BD_ORMAST00
(42 欄)。逐欄比對三支樞紐的 cacheField,全部都在該表中;唯一例外是
客戶訂單品號數量統計.xlsx的「年」欄(databaseField="0",是 Excel 對「受訂日期」做的年度分組欄、非來源欄),不影響。
- 用
SQLite3 ODBC Driver以 Excel 實際送出的反引號查詢實測,DARB_BD_ORMAST00
回傳 258 筆正常。
清空舊快取
檔案 原快取筆數 現在 客戶訂單品號數量統計.xlsx0(本來就空) count=0 訂單生產部門查詢.xlsx85 count=0 訂單資料樞紐查詢.xlsx82 count=0 pivotCacheRecords1.xml清成count="0"的空根節點(保留命名空間)。
pivotCacheDefinition1.xml的recordCount設 0。
- 三支全部加上
refreshOnLoad="1",開檔時自動向 SQLite 重抓最新資料。
刪除
移除三支連線中殘留的
odcFile屬性(指向使用者 OneDrive 的(預設) 訂單明細_d.odc,內含舊 DBF 連線)。保留會在重新整理時把來源蓋回 DBF;已轉好的參考檔
部門費用統計表.xlsx亦無此屬性。Breaking Changes
無。樣板沿用既有樞紐版面,僅換來源。
Migration Notes
- 目標機需安裝 SQLite3 ODBC Driver(Excel 樞紐用;開發機已裝 32/64-bit 兩版)。
Twork_TW.db內的DARB_BD_ORMAST00由 ERP 匯出維護,目前已有資料。
- 各檔已備份:
*.xlsx.dbfbak(換來源前)、*.xlsx.cachebak(清快取前)。
- 使用者開檔即自動重新整理;如停用自動重整,手動按「重新整理」即可。
-
06-28 excel-pivot-trusted-location ▸
2026-06-28 Excel 樞紐信任位置自動化(消除「已停用外部資料連線」警告)
摘要
樞紐分析表範本(.xlsx)內嵌一條外部 ODBC 資料連線(
DRIVER={SQLite3 ODBC Driver};Database=C:\Temps\Sqlite\Twork_TW.db),Excel 開檔時預設封鎖外部連線,跳出「安全性警告:已停用外部資料連線 → 啟用內容」橫幅,使用者每次都要手動點「啟用內容」才會刷新資料。由於 app 每次都把範本複製成新檔再開(
PivotBll.CopySqliteAndOpen→C:\Temps\Template\Pivot\),「信任的文件(Trusted Documents)」綁檔案雜湊會每次失效,無法解決;且封鎖是 Excel 用戶端的信任判斷,檔案本身無法宣告連線可信。正解是把固定的開檔夾設為 Excel 信任位置(Trusted Location)——從信任位置開的檔,外部連線自動啟用、也跳過 Protected View。變更
deploy/install-customer.ps1:Install 階段(per-user)新增自動把C:\Temps\Template\Pivot\設為 Excel 信任位置。
- 新函式
Set-ExcelPivotTrustedLocation:涵蓋 Office 2010~365(14/15/16.0),只設已安裝的版本,同路徑已存在就跳過(冪等);寫HKCU\...\Excel\Security\Trusted Locations\LocationN(Path+AllowSubFolders=1)。- 放在「程式是否已安裝」判斷之前,即使程式已裝、每次跑 Install 仍補設一次(新使用者帳號也涵蓋)。
- 新增參數
-SkipExcelPivotTrust(預設關閉=會設)與-PivotTrustPath(預設C:\Temps\Template\Pivot\,對應ERPIO.PivotTemplateDirectory)。影響範圍
- 走
install-customer.ps1 -Stage Install(或 Active Setup / GPO 使用者登入指令碼)的客戶機器:每個使用者首次套用後,開樞紐不再跳「已停用外部資料連線」警告。
- 既有單機可手動跑同等的 HKCU 設定達成相同效果(本次已在開發機 Office 16.0 套用)。
- 不影響 Config(SYSTEM)階段;不影響未走此佈署腳本的環境(行為不變,仍會跳警告直到設定信任位置)。
Breaking Changes
無。
Migration Notes
- 此設定為 per-user(HKCU),須以「該使用者」身分執行 Install 階段才會寫進其設定檔。
- 信任位置只解除「啟用外部連線」警告;連線要真正刷新仍需安裝對應位元數的 SQLite ODBC 驅動(
-InstallOdbc,位元數對應 Excel 而非 OS)。兩者各管一半。
- Excel 在啟動時讀取信任中心設定;若套用當下 Excel 正開著,需完全關閉再開才生效。
-
06-28 eis-efficiency-query-vm-registration ▸
2026-06-28 修復 CY 主管資訊四支效率查詢「無法建立ViewModel」
摘要
朝陽 CY 主管資訊(M.主管資訊)的四支查詢——個人效率統計、期間效率統計、達成率統計、非生產工時統計——按下選單後跳「無法建立ViewModel」錯誤,無法開啟。
根因:這類「條件查詢」程式的主 ViewModel 由 navigator 反射建立,但其依賴的 ConditionViewModel 需透過 DI 取得(
IQueryConditionFactory.Create()→GetService<TCondition>())。這四支的 ConditionViewModel 類別、App.xaml DataTemplate 都齊全,唯獨TsERP/DIExtension.cs漏了 DI 註冊,GetService回 null → 丟未註冊指定查詢條件 ViewModel→ navigator 顯示「無法建立ViewModel」。(真因記錄在
C:\temps\debuglog\<date>.txt,例:[CreateErpProgramBaseViewModel] 未註冊指定查詢條件 ViewModel:Pd_qry1ConditionViewModel。)變更
TsERP/DIExtension.cs:補上四支 ConditionViewModel 的 DI 註冊:
-
Pd_qry1ConditionViewModel(個人效率)-
Pd_qry2ConditionViewModel(期間效率)-
Pd_qry4ConditionViewModel(達成率)-
WknpdtqConditionViewModel(非生產工時)影響範圍
- 上述四支查詢從「打不開」修復為可正常開啟條件查詢畫面。
- 純新增 DI 註冊,不影響其他程式。
Breaking Changes
無。
Migration Notes
- 改動在
TsERP組件,需重建 TsERP 才生效。
- 通則:移植/新增「條件查詢頁」時,除了 VM 改名、ProgramClass、App.xaml DataTemplate,還必須在
DIExtension.cs加services.AddScoped<XxxConditionViewModel>(),否則執行期跳「無法建立ViewModel」。
-
06-28 cuinve-union-cy-nogi-columns ▸
2026-06-28 cuinve NOGI/CY 欄位聯集(view→Source、table→Model)
摘要
依單據別
CUINVE比對darbnogicsa1與darbcycsa1兩庫的_sheetno對應,做欄位聯集後套回程式:- Source 以 VIEW 為準:
vw_cuinvema(主)/vw_cuinve(子)。
- Model 以資料表為準:
cuinvema(主)/cuinve(子)。
主表(
cuinvema/vw_cuinvema)兩庫資料欄完全相同 → Source/Model 皆無變更。差異全在子表
cuinve/vw_cuinve。比對結果
物件 NOGI CY nogi-only cy-only base cuinve35 29 箱長/箱寬/箱高/材積/單重/單價/變動日期/業務員編號 產品別/紙箱尺寸 view vw_cuinve38 63 單重/單價/變動日期/箱長/箱寬/箱高/材積/業務員編號/姓名 (另含 32 個 JOIN 庫存主檔欄) view 比 base 多出的欄是
vw_cuinveJOIN 庫存主檔 invent 得到的唯讀欄。變更
Model(`Twork_ord_vw_cuinveModel`)— 對應 base table `cuinve`
無新增。base
cuinve聯集(含 nogi-only 8 欄與 cy-only產品別/紙箱尺寸)原本即已齊全。Source(`Twork_ord_vw_cuinveSource`)— 對應 view `vw_cuinve`
新增 32 個 CY view 專屬欄(JOIN 庫存主檔),以 Source 自帶私有欄位承接(不寫入 Model):
群組代號, 設變編號, 設變資料, 停用說明, 管制說明, 群組說明, 中文描述, 停用, 停用日期,
品別(byte), 材質, 規格, 型別, 加工, 包裝材料, 包裝量_包, 儲位, 單位, 標準售價,
廠商代號1, leadtime(short), 內箱包裝數, 最小採購量, 英文描述, 最低訂單量, 停用狀態,
庫存管制, abc分類, 生產部門, 採購緊急度, 設變導入日, 生產批量
型別/長度對齊 CY
vw_cuinve。此外,既有 view JOIN 唯讀欄
品名、客戶簡稱、姓名(base tablecuinve沒有、原本誤放在 Model)一併改為 Source 自帶私有欄位,使 Model 純對應 base table。
刪除
Twork_ord_vw_cuinveModel移除品名、客戶簡稱、姓名三個非 base-table 欄(改由 Source 私有欄位承接)。僅 Source 內部委派引用,無其他消費端,移除後 Common/Model/LogicBll/ViewModel 建置均通過。
Breaking Changes
無。Source 新欄為 view JOIN 唯讀欄,
GetModelBase()回傳的 Model 不含這些欄 →存檔不會序列化上傳(本就不屬 base
cuinve實表),與 ADR 0050 union 取交集行為一致。Migration Notes
本機 SQLite 由
EnsureCreated依 Source 模型重建,新欄自動出現;既有本機庫缺欄走補欄安全網。伺服器端 view/table 不變。
- Source 以 VIEW 為準:
-
06-28 central-automation-db ▸
2026-06-28 — 集中自動化庫 darbnogiauto1 + 排程專屬派發器
> 詳見 ADR 0065。
摘要
把排程/自動化預存程序與其產出的資料表,從公司庫
darbnogicsa1集中搬到新的集中自動化庫
darbnogiauto1,並比照 AI 查詢派發器新增**排程專屬派發器DARB_LOG_SYS_SKD_EXEC**(寫獨立稽核表log_sys_skd、目標一律導向新庫)。查詢自動化資料改走與既有 log 派發器相同的機制(新庫內也佈一份
DARB_GETDATA4)。新增
- 資料庫
darbnogiauto1,內含:
- 自動化 proc:
TWORK_SKD_GET_PENDING_NOTIFY、TWORK_SKD_GET_PENDING_AUTOEXEC、TWORK_SKD_MAILQUEUE_DEQUEUE、TWORK_SKD_MAILQUEUE_UPDATE、TWORK_AUTO_SAFETYSTOCK(讀公司資料以三段式
darbnogicsa1.dbo.*)。- 自動化自有表:
twork_skd_mailqueue、twork_auto_safetystockhistory。- 通用查詢 proc
DARB_GETDATA4(供結果檢視走同一派發器讀本庫表)。darbnogilog1:排程專屬派發器DARB_LOG_SYS_SKD_EXEC+ 稽核表log_sys_skd。
- C#:
Procedure.DARB_LOG_SYS_SKD_EXEC、IDatabaseConnection.Log_Sys_Skd_Exec、
AutoPilotTask.Log_Sys_Skd_Exec。- 部署腳本
sql/deploy-darbnogiauto1.sql、sql/deploy-darbcyauto1.sql(冪等)。
- CY 公司庫排程 schema 修補
sql/fix-darbcycsa1-scheduler-schema.sql(補 eventitem 4 欄 + 重建 calendarevent view)。
proc 本體引用本地同名 view、view 抓對應 csa(跨庫集中在 view 層;公司庫缺的
vwseek_*用 csa 基底表組、_date有則 view 抓 csa、無則自建日曆表)。- 版控補回 3 支原本只存在 DB 的 proc DDL:
SqlBI/TWORK_SKD_GETEVENT.sql、
SqlBI/TWORK_SKD_UPDATE_EVENT_STATUS.sql、SqlBI/TWORK_AUTO_SAFETYSTOCK.sql。變更
SchedulerJob:撈待通知/待自動執行、郵件佇列出列/狀態更新 4 處改走Log_Sys_Skd_Exec(→新庫)。
AutopilotMethod_LogSysExec:新增Dispatcher參數;設為SKD時該事件走排程專屬派發器
(→新庫),其餘維持主派發器(→csa)。安全庫存事件請設
Dispatcher=SKD+Procedure=TWORK_AUTO_SAFETYSTOCK。EventResultViewModel:依事件參數的Dispatcher決定讀結果走哪個派發器(SKD→新庫)。
刪除
- 無。
darbnogicsa1原 8 支 proc、原twork_auto_safetystockhistory、proc_param、共用
DARB_LOG_SYS_EXEC/log_sys一律保留(主派發器 fallback)。Breaking Changes
IDatabaseConnection新增Log_Sys_Skd_Exec:若有自訂實作(測試 fake/mock 以外),需補實作。
- 排程作業(
TsERP.SchedulerWorker)升級後,需先部署darbnogiauto1與
DARB_LOG_SYS_SKD_EXEC,否則排程的撈件/寄信/安全庫存會找不到派發器或 proc。Migration Notes
1. 於目標 SQL 執行個體跑
sql/deploy-darbnogiauto1.sql(sqlcmd -S <srv> -E -f 65001 -i ...或 SSMS)。2. 確認派發器
EXECUTE AS身分(loginfoxcsa)在darbnogiauto1有 user(腳本建foxautoexec);若實機 login 名不同,改腳本第 2 節的
FOR LOGIN。3. 安全庫存的行事曆事件:
參數設Dispatcher=SKD、Procedure=TWORK_AUTO_SAFETYSTOCK、結果表填
twork_auto_safetystockhistory。4. 多客戶:其他客戶用對應
sql/deploy-darb<客戶>auto1.sql(view 層改抓該客戶 csa)。CY(朝陽)已完成:公司庫 schema 原本落後,已用
sql/fix-darbcycsa1-scheduler-schema.sql補齊(
twork_skd_eventitem補真正新欄執行開始時間/執行guid;改基底欄名通知→是否通知、停用→是否停用對齊共用 TsERP Source,並連帶更新引用舊名的 CY 物件
twork_skd_vw_eventitem/_v/TWORK_WKFLOW_EVENTITEM/TWORK_MOLD_CHECK/TWORK_SKD_NOTIFYEVENT;twork_vw_calendarevent修IsApproved→已審核、暴露排程欄),重跑
deploy-darbcyauto1.sql後 CY 端對端驗證通過(NOTIFY/AUTOEXEC/安全庫存全 OK、資料保留),與 NOGI 同等。新客戶若 csa schema 落後,先跑對應 csa 修補(參考 CY 那支、注意各庫舊欄名差異與相依物件)再跑 deploy。
5. 未來把信寫進 mailqueue 的入列端 SP,目標表改
darbnogiauto1.dbo.twork_skd_mailqueue。 - 資料庫
-
06-28 browse-grid-sort-filter-and-statistics ▸
2026-06-28 庫存查詢:統計表顯示 + 表頭排序/篩選
摘要
修好 InventQuery(庫存查詢)遷到
TsBrowseRadGridView後遺留的三個缺口,全在共用 browse 控件補回,影響所有用該控件的瀏覽/查詢畫面。詳見 ADR 0066。
變更
最底下統計表恢復顯示資料
- 病根:5 月重構把主表改成自動產生欄位、卻漏改統計表,統計表仍掛
AutoGenerateColumns="False"
→ 欄位只剩沒綁定的表頭、又被
ClearColumn清空 → 整表空白。- 修法:移除統計表的
AutoGenerateColumns="False",與主表一致即顯示資料。
- 順手把統計列高度由
0.3*改0.2*(統計表變矮、主結果區變高)。
表頭排序改伺服器端
- 之前點欄位表頭沒反應(資料虛擬化下內建前端排序只排已載入頁)。
- 改為:點表頭三段切換「遞增 → 遞減 → 取消」,由 provider 在 SQLite 端
ORDER BY後重新分頁抓取,
整體資料重排;表頭排序箭頭正常顯示。
表頭篩選改伺服器端
- 之前欄位漏斗篩選無作用(Telerik 篩選僅支援 IQueryable 來源)。
- 改為:欄位漏斗的「包含/等於/大於/小於/區間…」等 field filter 會轉成 SQL,由 provider 在 SQLite 端
WHERE後重抓;多欄條件以AND疊加;可與排序併用。- 相異值(distinct)勾選清單在虛擬化下不支援,已隱藏,只保留欄位篩選。
已知限制
- 套用排序/篩選後會重建欄位,漏斗的「已篩選」標記不會留著(資料仍是正確篩過的)。
- 清除篩選:按「查詢」重跑(會一併清空排序與篩選),或重開漏斗設新條件。
Breaking Changes
無。
Migration Notes
- 無需資料或設定調整,重建後生效。
- 病根:5 月重構把主表改成自動產生欄位、卻漏改統計表,統計表仍掛
-
06-27 velopack-per-customer-channel ▸
2026-06-27 — Velopack 每客戶獨立發版通道
摘要
更新機制改為支援 Velopack channel:每家客戶可跟自己的通道,發版時指定通道 → 只更新該客戶、不影響其他家。
維持一份程式碼、一個發布包、一個 blob 容器。詳見 ADR 0063。
新增
appsettings.local.json新增Update區段(每客戶部署時設定,不進 repo):
-
Update:Channel— 該客戶的 Velopack 更新通道(建議用客戶代號)。-
Update:FeedUrl— 覆寫更新 feed 網址(預設darb-vpk,保留供日後內網鏡像)。```json
{ "DatabaseListSourcePath": "...", "Update": { "Channel": "cust-b" } }
```
release-velopack.ps1新增-Channel參數(預設dev):
-
.\release-velopack.ps1 -Channel cust-b→ 只發布到cust-b通道,只跟該通道的客戶會更新。- 不帶參數 → 發到
dev(沒有客戶跟,平常開發用)。deploy/deploy-customer.ps1新增-Channel參數:部署客戶時一併把Update:Channel寫進其
appsettings.local.json(設一次即可)。- 新增
deploy/install-customer.ps1— 大量機器(如單一客戶 500 台)一鍵初次佈署:
-
-Stage Config:寫%ProgramData%\TsERP設定(需系管/SYSTEM),適合 GPO 電腦啟動指令碼。-
-Stage Install:per-user 靜默安裝對應通道的 Velopack Setup,已安裝自動跳過,適合 GPO 使用者登入指令碼。- 預設
-Stage Both:手動單機一次跑完。Velopack 靜默安裝用官方--silent旗標(docs.velopack.io 查證)。- 可選
-InstallOdbc [-OdbcBitness x64|x86|both]:一併靜默安裝隨程式打包的 SQLite ODBC 驅動(NSIS
/S),供 Excel 樞紐分析表透過 ODBC 讀 SQLite 資料用。TsERP 本身不需要 ODBC(內建
System.Data.SQLite.Core引擎已打包)。已裝會依 HKLM 註冊偵測自動跳過。⚠ 位元數要對應 Excel 而非 OS(32 位 Office 用
x86)。- 可選
-RegisterActiveSetup [-ActiveSetupVersion N]:在 HKLM 註冊 Active Setup,讓**每個使用者首次登入時自動安裝**(含日後新建帳號),不必逐人手動裝。StubPath 指向
-Source上的本腳本-Stage Install,故-Source須為 UNC 分享;須以 64 位 PowerShell 執行;bump 版本號可強制全體重觸發。(Velopack 為 per-user 安裝,沒有 MSI 式「一份全機共用」;Active Setup 是讓每使用者各自自動裝的標準作法。)
變更
App.xaml.cs的CheckForUpdatesAsync不再寫死 feed 網址,改從appsettings.local.json讀
Update:Channel/Update:FeedUrl,組UpdateManager的ExplicitChannel。讀取失敗回退預設。刪除
無。
Breaking Changes
無。沒設
Update:Channel的既有安裝走 Velopack 預設通道 = 現行行為,不會壞。Migration Notes
- 既有客戶:不需動作即維持現行更新行為。要納入「逐家發版」,重跑
deploy-customer.ps1 -Channel <客戶碼> -Force,或手動在其appsettings.local.json補"Update": { "Channel": "<客戶碼>" }。- 過渡期:尚未設通道的舊機若仍需更新,繼續以預設通道發布一份(
vpk pack不帶 channel 的舊行為);
全數客戶設上通道後即可只發名通道。
- 發版者注意:
-Channel預設dev以防手滑直推客戶;正式更新某家務必明確帶-Channel <該家>。
發版結尾會印出
Channel:供核對。- 某通道首次發布:該通道 blob 尚無 RELEASES,需加
-SkipDownload(與既有首次發布規則一致)。
-
06-27 primarykey-validation-nested-tab-fix ▸
2026-06-27 修正巢狀分頁主檔的「客戶代號/廠商代號」永遠跳「資料重複」
摘要
修正 cudata(客戶資料)、spdata(廠商資料)、invent(料件)等「主鍵欄位放在巢狀分頁裡」的主檔,按下新增後輸入主鍵一律被判定「資料重複」、重新輸入也不會消失、導致無法存檔新增的問題。
根因
主鍵驗證
PrimaryKeyValidateViewModel.CheckPrimaryKey需要取得程式 VM(ERPProgramViewModel)才能查重,否則直接回傳「重複」。它透過控件的
ViewHelper.RootViewModel(Inherits 附加屬性)取 VM。但TsView.DataContextChanged會把每個 TsView 的RootViewModel覆寫成「該 TsView 自己的 DataContext」。當主鍵欄位TsPrimaryKeyTextBox被放進巢狀分頁 TsView(如CudataTab1,DataContext 是CudataTab1ViewModel)時,控件取到的是分頁 VM——它不是ERPProgramViewModel,於是CheckPrimaryKey走進is not ERPProgramViewModel → return true(=重複)的分支,無論輸入什麼值都恆判重複。因為驗證恆失敗、主鍵欄位永遠帶錯誤,連帶無法通過存檔前的錯誤檢查,新增的客戶/廠商存不進去。
變更
- 新增介面
ViewModel.IErpProgramOwner { ERPProgramViewModel ErpProgramViewModel { get; } }。
ERPProgramViewModel實作之,回傳自己。
- 三個巢狀分頁基底 VM 實作之,回傳宿主程式 VM:
-
CudataTabBaseViewModel → CudataViewModel-
SpdataTabBaseViewModel → SpdataViewModel-
InventTabBaseViewModel → InventBsViewModelPrimaryKeyValidateViewModel.CheckPrimaryKey:取不到ERPProgramViewModel時,改用IErpProgramOwner取回真正的程式 VM 再查重。
行為影響
- cudata / spdata / invent 新增主檔時,主鍵查重恢復正常:輸入既有代號才報「資料重複」,輸入新代號即通過、可存檔。
- 一般(非巢狀分頁)主檔的主鍵驗證行為不變。
附帶修正:新增後游標未自動跳到主鍵欄
同源問題。
FocusExtension.IsFocused綁DataContext.IsFocused(分頁 VM),而分頁 VM 的IsFocused只是轉發程式 VM 的同名屬性。程式端ERPProgramViewModel.SetFocus()切的是程式 VM 的IsFocused(false→true),不會觸發分頁 VM 的PropertyChanged,於是FocusExtension收不到 false→true 邊緣、不聚焦——新增後游標不會自動落在客戶代號/廠商代號/料件代號欄。修法:三個分頁 Tab1 VM(
CudataTab1ViewModel/SpdataTab1ViewModel/InventTab1ViewModel)在建構式訂閱程式 VM 的PropertyChanged,把IsFocused變更轉發成自身的PropertyChanged。Breaking Changes
無。
Migration Notes
無;純程式端修正,不需更動資料庫或本機 db。
- 新增介面
-
06-27 eorder-stale-english-cleanup-batch ▸
2026-06-27 訂單管理(E.Order)模組英文殘留中文化(批次)
摘要
延續 CUINVE/CUQT/CUPDMA,將 訂單管理(E.Order / 銷售訂單)整個模組 的 Source/XAML 英文殘留
系統性中文化。流程:先以多代理 inventory workflow 逐表單盤點+對 VFP 驗證每個英文 token 的分類,
再以對抗式驗證代理覆核高風險的「mapped DB 欄」判定,最後分兩波套用、逐波建置+提交。
涵蓋 40 支候選表單:24 支實作(DO)、16 支略過(SKIP)。
分類原則(每個英文 token)
類別 動作 判準 mapped DB 欄 保留英文 Model-backed + [TsColumnName],且 VFP*_v.<col>確認 DB 欄即英文(如 leadtime/email/website/cino/blno/reqno)。只翻欄位標題顯示文字SP/查詢 DTO 欄 保留英文 由 server SP 結果以屬性名對應(如 Cudatalimit 信用額度 grid、Ci_m1/OrderApprove/Odtosl 轉單 grid);改名會靜默清空 grid Excel 依名對應欄 保留英文 PreordPivotInput 的 CustomerCode/UnitPrice 由 Forecast.xlsx 表頭依屬性名匯入 介面成員 保留(已是中文) ISKU/IUnitPrice/ICustomerSKU/IPageHeaderNotes/ISelfDefined 等 NotMapped/TsSkip helper 改中文 UI plumbing;與既有 mapped 同名時加 Display/Binding後綴避免衝突失效英文 helper 砍除 全 repo grep 確認零 consumer 顯示文字 翻中文 XAML Header/Content/DisplayMeta/按鈕字實作清單(24 支)
- wave1(commit c73c6207):Cudata・CudataTab1・CudataTab2・Cudatalimit・Sample・Ormast・Salema・Odtosl・Orssma・Ci・Ci_m1
- wave2(commit 1cd031de):Pk・Preord・PreordPivotInput・Pi・Fillrate・Visit_q・Cmplain・Estsal・Cungma・Odtosladdi・WarrantyCard・OrderDuplicate・OrderApprove
- 先前(commit f7d4b18b):Cuinve・Cuqt・Cupdma(含 CupdmaSpecialQuery 轉 RadGridView)
略過清單(16 支)與原因
- 已是中文(無殘留):CudataAr・CudataStatistics・CudataTab3・Rtaxma・Invent1・Claim・Visit・Pdtsal・Culbl・Alledi
- 英文版本(刻意保留英文 UI):Ormast_s・Ormast_US・Cudata_US・Rma・Shiptoaddress・OrderApprove_Credit・Darbedittool
- 註:這些英文版/工具表單與主表單共用 Source,故主表單 helper 改名時其綁定路徑亦同步更新(顯示文字維持英文)
- 壞掉的空殼:Sample1(ProgramClass 佔位、VM 未實例化、開窗 NRE)
對抗式驗證攔截到的真實風險(已修正)
1. Ormast:原判 5 組 helper(SalesRepName1-3/TaxDescription1-3/Shipping*/Transaction*/ShippingAgentName)為死碼欲砍 → 實際被 Ormast_US/Darbedittool 綁定且 OrmastSave 有引用 → 保留(砍會編譯失敗+斷綁定)
2. Ormast 套用後建置攔截:helper
CustomerName/GroupCompanyName改名撞到既有 mapped客戶簡稱/集團簡稱→ 改為客戶簡稱Display/集團簡稱Display,同步修 Ormast/Ormast_US/Darbedittool 綁定與 C# caller3. Cudatalimit:3 個信用額度欄為 SP 結果依名對應 → 保留英文綁定(只翻標題)
4. PreordPivotInput:CustomerCode/UnitPrice 為 Excel 依名匯入 → 保留
Breaking Changes
- 各表單的英文 NotMapped/TsSkip helper 屬性已改中文名;少數失效 helper 已刪除。外部若以字串/反射引用舊英文名需同步改。
- 保留英文的 mapped DB 欄 / SP-DTO / Excel 欄綁定路徑不變。
Migration / 驗收
- 不需 DB migration(DB 本即中文 schema,本批為 code 端追平)。
- Runtime 未驗:24 支表單建議人工開窗驗收欄位顯示與存取;特別是 Preord 的
停用說明(VFP REPLACE 註解中,view 是否供值待確認)、各轉單/查價 grid 的 SP 欄位填值。
- 建置:Common/Model/LogicBll/ViewModel 全 exit 0、TsERP markup exit 0;per-form 掃描確認各表單自身改名識別字在自身 XAML 0 殘留。
-
06-27 dashboard-deck-redesign ▸
2026-06-27 主管儀表板「匯出簡報」改版(董事會財報風 + 修溢出)
摘要
把主管儀表板(EISDASH)的「匯出簡報」HTML deck 重新設計成專業、給老闆看的董事會財報風,並修正清單筆數多時內容被裁切、超出頁面的問題。功能、操作、輸出路徑與資料來源皆不變。
變更
LogicBll/M.EIS/主管儀表板/儀表板簡報Generator.cs全面改版(公開 API儀表板簡報資料/產生HTML不變,呼叫端EisdashViewModel.匯出簡報無須修改):
- 視覺(乾淨清爽風):冷調淨白底(
#F4F8FA)+ 白卡片 + 墨色字(#17212E)+ 清新藍綠主色 teal(#0E9488,用於眉標細線、KPI 頂條、排名數字、頁碼);封面為淺色薄荷漸層 + 墨字 + teal 邊角,輕盈通透。數字一律以襯線字型(Georgia)tabular 對齊排版,像印製的損益表。警示色用乾淨珊瑚紅(#E0524F)。趨勢圖:受訂深板岩藍、出貨 teal。- 只用系統字型(Georgia / Microsoft JhengHei / Segoe UI),維持離線即開、零外部相依。
- 封面眉標移除「TSERP」前綴(改為「主管儀表板 EISDASH」)。
- 各頁左右邊距加寬至 150px、KPI 頁字級與間距微調,避免 4 卡列右側貼邊。
修正
- 清單溢出:原本呆料 Top、逾期客戶以單欄表格塞進固定 1080px 版面,筆數多時(最多 12 筆)會超出頁面被
overflow:hidden裁掉。改為兩欄 ledger 版式(直排序、依筆數自動算每欄列數),12 筆只佔 6 列,並收緊上方標題/摘要的垂直間距,確保整頁含頁尾都容得下、不裁切。
- 筆數透明化:清單標頭顯示「共 N 筆 · 顯示前 M 筆」,超過 12 筆時明確標示僅顯示前段,不再靜默截斷。
行為
- 仍是當下顯示快照;← → 翻頁、F 全螢幕、視窗等比縮放(1920×1080 舞台)皆維持。
Breaking Changes
無。樣板與樣式更動,無 API / 資料 / 設定變動。
Migration Notes
無需 migration。
相關
- ADR 0048 — 匯出簡報採自包含 HTML deck(架構決策不變)
- 2026-06-21 主管儀表板新增「匯出簡報」
-
06-27 cuqt-stale-english-cleanup ▸
2026-06-27 客戶單品報價單(CUQT)英文殘留中文化
摘要
延續客戶產品表(CUINVE)的清理,將客戶單品報價單(CUQT)的 Source/XAML 英文殘留中文化。
三張 Source(cuqtm 主檔 / cuqtd 材料明細 / cuqtd1 加工明細)的欄位屬性早已中文化,本次處理剩下的
英文 NotMapped/Binding helper、一個失效的英文 mapped 屬性,以及
Cuqt.xaml仍是英文的 Label 與欄位標題。變更
Twork_ord_vw_cuqtm(主檔)
英文(舊) 處置 GroupDescription([TsColumnName(nameof(GroupDescription))]+ 私有 backing)砍除 — DB view 無此欄、永遠空白;群組說明的真實欄是既有 mapped 的 說明,XAML 改綁說明QuotationStaffName(NotMapped,報價人員姓名顯示)改名 報價人員姓名Twork_ord_vw_cuqtd(材料明細)
英文(舊) 中文(新) GroupDescription(NotMapped)群組說明SKUBinding(NotMapped,品號 seek)品號BindingQuotationDateBinding(TsSkip,幣別查匯率用日期)報價日期BindingUnitPriceBinding(TsBinding 單價)單價BindingQuantityBinding(TsBinding 數量)數量BindingTwork_ord_vw_cuqtd1(加工明細)
- Source 早已全中文,僅 XAML 兩個欄位標題中文化(見下)。
Cuqt.xaml
- 主檔 Label 中文化:
Quotation No:→報價單號:、Quotation Staff:→報價人員:、Quotation Date:→報價日期:、
Customer Code:→客戶代號:、Customer SKU:→客戶品號:、Minimum Order Quantity:→最低訂單量:、Vendor Code:→廠商代號:、Group Code:→群組代號:、Material Fee:→材料費:、Processing Fee:→加工費:。- 按鈕文字
Unit Price Adjust→單價調整。
- 群組說明輸入框由
{Binding GroupDescription}改綁{Binding 說明}(顯示真實 DB 欄)。
- 材料明細格標題/綁定中文化:
SKU→品號(綁品號Binding)、SKUDescription→品名、Group Description→群組說明、
Vendor Code→廠商代號、Vendor Name→廠商簡稱、Currency→幣別、Foreign Exchange Rate→匯率、UOM→單位、Quantity→數量(綁數量Binding)、Unit Price(本幣)→單價(本幣)(綁單價Binding)、幣別欄日期改綁報價日期Binding。- 加工明細格標題:
Processing Code→工程代號、Processing Name→工程簡稱。
Caller 連動修正
CuqtBll.AddDetail:SKUBinding/QuantityBinding/GroupDescription/UnitPriceBinding→品號Binding/數量Binding/群組說明/單價Binding。
CuqtViewModel:UnitPriceBinding→單價Binding、QuotationStaffName→報價人員姓名(2 處)、QuotationDateBinding→報價日期Binding。
Breaking Changes
- CUQT 三張 Source 的英文 helper 屬性已改中文名;主檔
GroupDescription已刪除(改用既有說明)。
外部若以字串/反射引用舊英文名需同步改。
Migration Notes
- 不需 DB migration(DB 本來就是中文 schema,本次為 code 端追平)。
- Runtime 未驗:CUQT 開窗、新增、取得資料(匯入 BOM)、單價調整、儲存需人工驗收。
-
06-27 cupdma-stale-english-cleanup ▸
2026-06-27 客戶產品報價(CUPDMA)英文殘留中文化
摘要
延續 CUINVE / CUQT 的清理,將客戶產品報價單(CUPDMA)的 Source/XAML 英文殘留中文化。
主檔(cupdma)與明細(cupdt)的欄位屬性早已中文化,本次處理剩下的英文 NotMapped/TsSkip helper,
並把
Cupdma.xaml仍是英文的 Label 與欄位標題全面中文化。變更
Twork_ord_vw_cupdma(主檔)helper 中文化
英文(舊) 中文(新) CurrencyPlaces(NotMapped,幣別小數位)幣別小數位ProjectName(NotMapped,專案名稱顯示)專案名稱CustomerCodeBinding(NotMapped,客戶代號 seek + 帶客戶資料)客戶代號BindingTwork_ord_vw_cupdt(明細)helper 中文化
英文(舊) 中文(新) Amount(NotMapped,金額)金額QuantityBinding(TsSkip)數量BindingForeignExchangeRate(TsSkip,取主檔匯率)匯率BindingCurrencyPlace(TsSkip,取主檔幣別小數位)幣別小數位BindingSetPrice()內部運算式同步改中文屬性。
Cupdma(指向主檔 Source 的型別參考)保留 — 它是實體參考、非資料欄位/非綁定路徑,命名沿用程式名。
保留的英文 mapped 欄位(DB 欄本身即英文,動了會破壞對應)
Twork_ord_vw_cupdmaSource.ProjectCode(Model-backed mapped 欄)。
Twork_ord_vw_cupdtSource.leadtime(VFP 確認 DB view 欄即客報價明細_v.leadtime)。
- XAML 該欄標題仍中文化為「前置天數」(顯示文字),綁定維持
{Binding leadtime}。Cupdma.xaml
- 主檔 23 個 Label 全面中文化(報價單號/報價別/報價日期/生效日期/客戶代號/客戶名稱/業務員編號/
聯絡人/電話/傳真/幣別/匯率/製表人員/活動起始日/活動截止日/預計結案日/實際結案日/最低毛利率/
有效天數/收付條件/專案代號/頁首備註/報價備註)。
- 主檔綁定:
CustomerCodeBinding→客戶代號Binding、ProjectName→專案名稱(2 處)。
- 明細格 27 個欄位標題中文化;綁定
QuantityBinding→數量Binding、Amount→金額。
Caller 連動修正
CupdmaViewModel.AfterMoverRecord:ProjectName→專案名稱(SetCurrencyPlaces()方法名保留,內部改設幣別小數位)。
- 明細
SetPrice()由e.Item.Cupdma(VM)/幣別匯率 weak event 觸發,運算改中文屬性。
CupdmaSpecialQuery.xaml(查價子面板)
CUPDMA 操作面板的查價子面板,本批一併處理:
TsDataGrid→TsRadGridView(dg-to-radgrid skill):外層容器、DataGrid.Columns、各欄類型轉換,
Binding→DataMemberBinding,v2:TsDateColumnV2→TsGridViewDataDateColumn(MaskInfo→ForceReadOnly),取價按鈕欄改
TsButtonInCell+ButtonCellCellStyle、Command 改RelativeSource AncestorType=TsRadGridView。ItemsSource="{Binding ItemsSource}"為一般集合(非 DataManager pattern),故不加 DataManager;保留外層ProgramClass。- 18 欄表頭全面中文化(取價/報價日期/報價別/客戶代號/客戶名稱/專案代號/專案名稱/地點/單價/品號/
數量/單位/數量2/單位2/備註/幣別/匯率/客戶品號)。
- 綁定維持原查價結果 POCO 的英文屬性(查詢 DTO,不在本次改名範疇)。
Breaking Changes
- CUPDMA 主檔/明細的英文 helper 屬性已改中文名。外部若以字串/反射引用舊英文名需同步改。
Migration Notes
- 不需 DB migration(DB 本來就是中文 schema,本次為 code 端追平)。
- Runtime 未驗:CUPDMA 開窗、新增、查價(FindPrice)、金額試算、儲存需人工驗收。
-
06-27 cuinve-stale-english-cleanup ▸
2026-06-27 客戶產品表(CUINVE)英文殘留中文化
摘要
客戶產品表(CUINVE,E-040)的 DB view(
vw_cuinve/vw_cuinvema)欄位早已中文化,但Source/Model 仍殘留少數英文屬性,且
Cuinve.xaml的欄位標題與 Label 仍是英文。本次以 VFPcuinve原始欄名(
包裝量/包裝量_箱/備註)為準,將殘留英文屬性改名為中文、砍掉重複的死屬性,並把XAML 標題與 Label 全面中文化。
變更
Twork_ord_vw_cuinvema(主檔)
英文(舊) 中文(新) Notes 備註 - Model、Source 同步改名;
[TsColumnName(nameof(Notes))]→[TsColumnName(nameof(備註))](DB 欄本為備註,原英文 mapping 載入永遠空白)。
- 保留 NotMapped helper
CustomerName(UI 查詢用,非 DB 欄)。
Twork_ord_vw_cuinve(明細)
英文(舊) 中文(新) MinimumPackageQuantity 包裝量 - Model 屬性
MinimumPackageQuantity改名包裝量;Source包裝量wrapper 改讀新名([TsColumnName]本就是包裝量,DB 欄不變)。
- 砍除 Model 死屬性
QuantityPerCarton(與既有中文欄包裝量_箱重複、無任何 caller)。
NotMapped UI helper 中文化
英文(舊) 處置 SKUBinding(明細,品號 seek 欄)改名 品號BindingCustomerName(主檔,客戶簡稱查詢顯示)改名 客戶簡稱Display(避開既有 mapped客戶簡稱)SKUDescription(明細)砍除(無任何 caller、未綁定、未賦值的死碼) CustomerName(明細)砍除(死碼) SalesRepName(明細)砍除(死碼) - 連動修正:
Cuinve.xaml(客戶 seekDescription+ 唯讀簡稱框 + 明細品號欄 binding)、CuinveViewModel.GetPrintViewModel(2 處讀取)、Twork_ord_vw_cuinvemaSource.RefreshDescription。
Cuinve.xaml
- 主檔 Label:
Customer Code:→客戶代號:、Notes:→備註:;{Binding Notes}→{Binding 備註}。
- 明細格 26 個欄位標題全面中文化(
LineNo_→序號、SKU→品號、SKU Description→品名、
Customer SKU→客戶品號、Minimum Package Quantity→包裝量、Quantity Per Carton→包裝量(箱)、Notes→備註等),沿用本檔既有 CY 欄位的字面中文 Header 寫法。Breaking Changes
Twork_ord_vw_cuinvemaSource.Notes、Twork_ord_vw_cuinveModel.MinimumPackageQuantity屬性已改中文名;
Twork_ord_vw_cuinveModel.QuantityPerCarton已刪除。外部若以字串/反射引用舊英文名需同步改。- NotMapped helper 改名/刪除:
SKUBinding→品號Binding、主檔CustomerName→客戶簡稱Display;
明細
SKUDescription/CustomerName/SalesRepName已刪除(皆為死碼)。Migration Notes
- 不需 DB migration(DB 本來就是中文 schema,本次為 code 端追平)。
- Runtime 未驗:CUINVE 開窗、新增、儲存需人工驗收欄位顯示與存取正常。
- Model、Source 同步改名;
-
06-27 cudata-cy-account-fields ▸
2026-06-27 — cudata 補 CY 會計欄位、聯絡傳真重排
摘要
客戶資料
cudata(CY 版)補回 VFPscx_ord_cypage2 的三個會計欄位,並整理第二分頁「詳細聯絡資訊」的電話/傳真排列。
新增
- 第二分頁「銀行帳戶與會計科目」群組(原「銀行帳戶」)加入:
- 帳戶代號 — 公司收款帳戶搜尋框,顯示帳戶簡稱。
- 應收科目 — 會計科目搜尋框,顯示科目名稱。
- 銷貨科目 — 會計科目搜尋框,顯示科目名稱。
- 公司傳真 補進第二分頁「詳細聯絡資訊」(原本只有 Tab1 有)。
變更
- 第二分頁「詳細聯絡資訊」電話/傳真改成並排兩列:
- 公司電話 | 公司傳真
- 工廠電話 | 工廠傳真
Migration Notes
這三個欄位是 CY 客戶(darbcycsa 家族)專屬。共用程式會 SELECT 這三欄,因此
每個 cudata 庫都要先於 SSMS 跑
sql/cudata_add_account_fields_CY.sql:- CY 庫:取消腳本 Section 1 註解後執行(建立實體欄位),再執行 Section 2(重建 vw_cudata)。
- 非 CY 庫:只執行 Section 2(vw_cudata 會以空字串常數投影這三欄)。
未跑前該庫開啟客戶資料會載入失敗。腳本可重複執行。詳見 ADR 0062。
-
06-27 bom-botm-include-no-process ▸
2026-06-27 最低階用料查詢還原「含無製程」選項
摘要
還原 VFP
scx_eng_cy中bom_botm(最低階用料 / BOM 底層展開查詢)的「含無製程」勾選框。此選項在 CY 版DARB_QRY_BOM_BOTM預存程序對應第 4 參數@查詢方式,新版 C# 先前固定不帶該參數,導致 CY 永遠走「無製程不展」分支,VFP 時代的展開模式無法觸發。新增
- 「最低階用料」查詢條件頁新增 「含無製程」勾選框(預設不勾)。
- 勾選 → 預存程序走
DARB_BIZ_BOMBOTTOM加含無製程,將無製程組件一併往下展開。- 不勾 → 維持原行為
DARB_BIZ_BOMBOTTOM無製程不展。變更
Bom_botmParameters新增含無製程(bool,預設 false)。
Bom_botmConditionViewModel新增含無製程屬性。
GetSqlData.GetTWORK_QRY_BOM_BOTM新增選用參數queryMode(預設"0"),映射到 dispatcher 的LP_P4(@查詢方式)。
Breaking Changes
無。
queryMode為帶預設值的選用參數,既有呼叫端不受影響。Migration Notes
- 不需資料庫變更。CY 庫
DARB_QRY_BOM_BOTM本就有@查詢方式參數(proc_param.param_qty=4)。
- 多客戶相容:NOGI 等
param_qty=3的庫,dispatcher 不會轉發第 4 參數,故新增的queryMode會被安靜忽略——對非 CY 客戶該勾選框無作用但不報錯,毋需 per-customer 分支。詳見開發者記憶darb-qry-bom-botm-cy-nogi-divergence。
-
06-26 tssearchtextboxv2-seek-validation-fixes ▸
2026-06-26 — 全域 seek 欄位(TsSearchTextBoxV2 / TsSearchRule)存在性驗證修復
摘要
修復共用搜尋輸入控件
TsSearchTextBoxV2與其驗證規則TsSearchRule的一連串問題:存在性驗證從未真正掛載、誤判正確資料為「資料不存在」、錯誤時不跳訊息、跳訊息後焦點被搶回造成洗版、以及清空儲存格後要點兩次按鈕。屬平台層共用控件,影響全 app 使用TsSearchTextBoxV2的 seek 欄位。變更
- 補上漏掉的
SetBinding(TsSearchTextBoxV2.OnApplyTemplate):
- 原本把
TsSearchRule/PrimaryKeyRule加到「深拷貝後的 binding」卻沒套回TextProperty,導致存在性驗證自始未生效。現於加完規則後BindingOperations.SetBinding套回(無規則時不重綁)。- 訊息框改由規則在「發現錯誤的當下」跳出(
TsSearchRule.Validate):
- 查無此代號時,由規則自身即時
TsMsgBox.ShowMessage(資料不存在),不再等失焦後事後檢查Validation.GetHasError(後者因 binding 來源更新晚於 class handler 而讀到舊狀態,永遠不跳)。-
SeekCondition未設定的設定錯誤亦即時跳窗。- 同一個錯誤值只跳一次窗(
TsSearchRule新增lastWarnedValue守門):
- 防止 Telerik 控件一次失焦驗證多次、或焦點抖動造成的訊息洗版;改成有效值或清空後重置守門,輸入新的錯誤值才會再提示。
- 移除錯誤時的焦點搶回(
TsSearchTextBoxV2.OnLostFocus):
- 先前用
Keyboard.Focus(this)把焦點釘回欄位,會與失焦驗證形成死迴圈(點按鈕→失焦→跳窗→焦點被搶回→再點→再跳…按鈕按不到)。改為僅保留紅框(ValidationResult)視覺提示,存檔時仍會被擋。- 清空儲存格即時清除殘留錯誤(
TsSearchTextBoxV2新增OnTextChanged):
- 規則只在失焦時重驗,把錯誤值刪成空白後仍掛著上一個值的錯誤狀態,使儲存格第一次點按鈕被吃掉(要點兩下)。改為文字清空時立即
Validation.ClearInvalid,空白是合法狀態,下次點按鈕一次生效;失焦時規則仍會重新驗證。- 移除驗證結果快取(
TsSearchRule):
- 移除
previousValue/previousResult快取。原快取會把載入當下暫時性的 false(Context/暫存表尚未就緒)寫死,導致之後正確資料也一直回「資料不存在」。改為每次重新判斷。背景
- 2026-06-25 SLIYBROWD 的 changelog 已點出
OnApplyTemplate漏SetBinding的問題,但當時刻意只在該支以 gridCellValidating就地補、未動全域控件。本次改為直接修平台層TsSearchTextBoxV2,全 app 的 seek 欄位一併受惠。
Breaking Changes
- seek 欄位的存在性驗證現在會真正生效(先前形同關閉):輸入主檔不存在的代號會跳「資料不存在」並標紅框。若有畫面原本「靠驗證沒生效」而能存入不存在代號,現在會被擋。
Migration Notes
- 無資料庫異動。存在性查詢沿用既有
TWORK_EXIST(DataValidate 平台),不需新登錄。
- 行為層面:在一般表單欄位,錯誤時不再強制把焦點留在欄位(改靠紅框 + 存檔擋)。
- RadGridView 儲存格情境:「打錯就擋住、強迫修正」是 grid 原生行為(
ActionOnLostFocus預設CommitEdit+ editorValidationRule失敗 → grid 將焦點退回該格),Tab 切格與點 grid 外按鈕都會被擋。經裁定維持此現狀,刻意不在 editor 加PreviewLostKeyboardFocus去區分「Tab 到輸入欄 vs 點動作按鈕」——那會與 grid 自身的焦點管理衝突。若日後想讓「點 grid 外按鈕(取消/關閉)可放行」,正確做法是把該 grid 的ActionOnLostFocus設為None,而非改 editor。
- 補上漏掉的
-
06-26 statistics-definition-chinese ▸
2026-06-26 統計定義中文化(特殊查詢統計面板)
摘要
客戶 / 廠商 / 品號「特殊查詢」統計面板的項目名稱與描述由英文改為繁體中文;
對應的值計算預存程序內的分支字面值同步改為中文(分支鍵維持用 StatisticsName),
並修復廠商採購額三項的計算。
變更
twork_sys_statistics_definition表 27 筆的StatisticsName、Description_
由英文覆寫為繁體中文(例:
Latest Quotation→最新報價單、MTD Sales (Order)→本月銷售額(訂單)、YTD Purchasing→本年採購額)。- 子程序
TWORK_STATISTIC_CUSTOMER/TWORK_STATISTIC_VENDOR/
TWORK_STATISTIC_INVENT的分支判斷字面值由英文改為對應中文(分支鍵仍為StatisticsName)。- 移除
@language參數:父程序與三支子程序簽章去掉@language;日期顯示固定yyyy/mm/dd;
QueryCondition中文化 REPLACE 改無條件套用。C# 端GetSqlDataWrapper.GetStatistic_definition、CudataBll.GetStatisticDataNew及三支 SpecialQuery ViewModel 一併移除語言引數(位置式參數改為 UserID/Classification/PartnerCode)。SQL 與 C# 須一起部署。
修復
- 廠商「本月/本年/去年採購額」(S003/S004/S005)原本因
vwbd_purch欄名不符而留空:
改用該 view 的
本幣未稅金額欄、並把日期條件對應到實體欄採購日期t,計算恢復正常(驗證:本年採購額 328800、去年採購額 995920)。
- 金額一律改用
本幣未稅:三支子程序所有SUM()金額欄由原幣未稅改為本幣未稅
(
vwbd_trsama出貨、vwbd_ormast受訂、vwbd_trrama進貨、vwbd_purch採購)。Dispatcher 登錄(darbnogilog1)
DARB_LOG_SYS_EXEC依proc_param.param_qty決定轉發參數個數。TWORK_STATISTIC_DEFINITION
移除
@language後參數由 4 → 3,故 darbnogilog1 的proc_param.param_qty由 4 改 3。- 部署腳本:
sql/twork_statistic_definition_procparam_darbnogilog1.sql。
Migration Notes
- 部署腳本:
sql/twork_statistics_definition_chinese_darbnogicsa1.sql
(以 Unicode 執行,例如 SSMS 或 SqlClient;勿用預設 codepage 的 sqlcmd,中文會漏寫)。
- 已部署於 darbnogicsa1。其他公司資料庫(darbcycsa1 / darbzdcsa1 等)若也使用此面板,
需另行套用同一腳本(並確認該庫
vwbd_purch欄名)。- 三者須一起部署:darbnogicsa1 程序、darbnogilog1 的
proc_param、C# 端
(移除
@language後參數位置改變;任一未更新都會參數錯位/過多)。- dispatcher
DARB_LOG_SYS_EXEC與proc_param在 log 庫 darbnogilog1,跨庫 EXEC 到 darbnogicsa1。
已走完端到端驗證(dispatcher → 跨庫 → 子程序)result=OK 並回傳中文統計列;C# 編譯通過。
注意
- 子程序分支鍵 = 顯示名稱(
StatisticsName)。日後再調整顯示文字時,務必同步更新三支子程序內
的字面值,否則對應項目的值會靜默變空白。
-
06-26 cuinve-delete-guard ▸
2026-06-26 客戶產品表(CUINVE)刪除防呆還原
摘要
對比 VFP
scx_ord_cycuinve.deleteclick後,補回「本程式不能執行刪除之功能」的整支刪除阻擋。新版原本無
CuinveEdit/CuinveDelete,刪除走 baseDeleteBll無條件允許,使用者可刪掉某客戶的整張客戶產品表(含所有產品列),與舊系統刻意禁刪的行為不符。變更
- 新增
LogicBll/Ade/E.Order/CuinveDelete.cs:覆寫BeforeDelete直接回false並帶出
「本程式不能執行刪除之功能」訊息(工廠以
<Pascal>Delete反射自動接上)。- 僅擋刪除:修改維持 base
EditBll允許(VFP 無allowedit擋修改)。明細列仍可在編輯時以
增刪修=D 標記移除,不受影響——本防呆擋的是主檔(整筆客戶產品表)刪除按鈕。
- 新增訊息鍵
MessageEnum.ThisProgramCannotDelete(Common/Language/MessageService.cs)
與
TsERP/Lang/Message.json對應條目(繁中「本程式不能執行刪除之功能」/ 英文)。修復(順帶)
- CUINVE / CUPDMA 畫面無法顯示:
App.xaml缺這兩支 ViewModel → View 的DataTemplate
(E.Order CY 路線檔案已建但 runtime 未驗的系統性遺漏)。已補上
CuinveViewModel→Cuinve、CupdmaViewModel→Cupdma兩個DataTemplate(含新增xmlns:cupdma命名空間),程式才能正常導覽載入。2026-06-28 追補:不支援刪除的提醒提前
原本「本程式不能執行刪除之功能」走
CuinveDelete.BeforeDelete,而BeforeDelete在DeleteBll.Delete()內才執行——使用者得先按刪除、跳「確定刪除?」確認、按下「是」之後才被告知不支援。- 新增
DeleteBll.IsDeleteNotSupported(out msg)虛擬方法(預設回false=支援刪除)。
CuinveDelete改覆寫IsDeleteNotSupported回true(取代原BeforeDelete覆寫)。
DeleteService.Delete()在最前面、跳確認對話框之前就先呼叫IsDeleteNotSupported,
整支禁刪的程式按下刪除鈕立即提示,不再先問「確定刪除?」。
DeleteBll.BeforeDelete仍呼叫IsDeleteNotSupported作為後端防線。
Breaking Changes / Migration Notes
無資料庫變動。
Message.json需隨版散佈;MessageEnum與 BLL 一起編譯部署即可。 - 新增
-
06-26 cudata-tab-fields-actually-applied ▸
2026-06-26 客戶資料(CUDATA)Tab1/Tab2 欄位實際補回(修正 2026-06-25 文件脫節)
摘要
2026-06-25 的 changelog(
2026-06-25-cudata-vfp-field-restore.md)記載 CudataTab1 與CudataTab2 已補回多個 VFP
scx_ord_cy對比缺漏的欄位,但實際 XAML 從未寫入——當時只加了
Twork_ord_vw_cudataModel的屬性,畫面綁定遺漏(git 亦無對應 commit)。本次將該批欄位實際補進 XAML 並建置通過(VS MSBuild
TsERP.csprojEXIT=0)。新增(Tab1 基本資料)
- 直接出貨、附成績單、轉廠(Y/N 旗標,
YesNoComboBox,置於基本資料群組 Row 2 第 4–9 欄)
新增(Tab2 財務)
- 新群組「詳細聯絡資訊」:負責人、身分證字號、負責人電話/分機、會計、聯絡人職稱、
會計電話/分機、聯絡人2、工廠傳真、聯絡2電話、聯絡2分機、聯絡1分機
- 新群組「公司概況與交易」:國家別、客戶區域、交易方式、成立時間、收款日、營業項目、
稅籍號碼、關係人(關係人為
YesNoComboBox,比照 SpdataTab1/廠商資料慣例)- 新群組「徵信記錄」(多行 memo)
- 財務資訊群組新增:技術報酬金、佣金(
TsNumericTextBox,兩位小數)
變更(版面)
- CudataTab2 主體 Grid 由單列改為兩列:原四個群組(銀行帳戶/財務資訊/帳款與物流設定/
詳細聯絡資訊)維持第 1 列,新增之公司概況與交易、徵信記錄置於第 2 列。
Breaking Changes / Migration Notes
- 技術報酬金 / 佣金為新 DB 欄位:
cudata表與vw_cudataview 原本沒有。
部署前必須先於 SSMS 對每個目標庫(darbnogicsa1 / darbcycsa1 / production)執行
sql/cudata_add_commission_techfee_darbnogicsa1.sql(ALTER TABLE 加兩欄 + 重建 view)。未執行前若儲存客戶資料會因欄位不存在而失敗。
- 其餘欄位皆為既有 DB 欄位,純補 UI,無需 migration。
備註
- 本條目為「文件與實作脫節」之修正紀錄;2026-06-25 changelog 描述之意圖至此才真正落地。
- 後續若再發生「changelog 已記但 XAML 未綁」情形,請以 build + 實查 binding 為準
(參照記憶
vfp-compare-cross-check-xaml-binding)。 - 直接出貨、附成績單、轉廠(Y/N 旗標,
-
06-26 browse-query-sql-injection-hardening ▸
2026-06-26 瀏覽/查詢 SQL Injection 防護
摘要
修補瀏覽/查詢條件產生器的 SQL Injection 風險:字串值跳脫、非 Int32 數值欄補驗證、Between 結束值也驗證,並把「自定義」查詢條件文字框改為唯讀,關閉使用者手打 raw WHERE 的入口。屬安全性修補,純 C# / XAML 變更,不動資料庫。
變更
- 字串值跳脫(
ViewModel/Browse/BrowseConditionHelper.cs):新增Esc()(單引號'→''),套用到所有把字串嵌進N'...'的分支:等於/不等於/大於小於(A~FString)、like(G/H/I/J)、In 清單(K/LString 逐項)、Between(Q起始+結束值)。
- 數值型驗證(
ViewModel/Browse/BrowseConditionChecker.cs):原本只驗Int32/DateTime/Boolean,新增Decimal/Double/Single/Int64/Int16/Byte/SByte,以逗號切分後逐 tokendecimal.TryParse(同時支援單值與 In 清單);非純數字擋下並提示「請輸入數字」。
- Between 結束值驗證 + 無值運算子豁免(
BrowseConditionHelper.GenerateCondition):Between(Q)的結束值一併驗證(原本只驗起始值);IsNull/IsNotNull/IsEmpty/IsNotEmpty/不考慮/R等不吃輸入值的運算子豁免值驗證。
- 自定義條件輸入框唯讀(
TsControl/Themes/TsStyles.xaml,inv:InventQueryControlTemplate):綁SelfDefinedCondition的TsTextBox加IsReadOnly="True",覆蓋共用此控件的 Cudata/Invent/Spdata/Ginvent。
行為變更(使用者可見)
- 數值欄輸入非數字(含 Between 結束值)會被即時擋下並提示,而非送出後由 SQL 報錯。
- 查詢條件區的「自定義」文字框不再可手動輸入;點選預先定義的特殊查詢仍正常產生條件並查詢。
- 修正一個既有副作用:對數值欄做「IS NULL/IS NOT NULL/IS EMPTY」等不需輸入值的查詢,現在不再被誤要求「請輸入數字」。
Breaking Changes
- 無 API/資料庫破壞性變更。唯一行為差異是「自定義」文字框改唯讀,若有流程依賴使用者在該框手打 SQL 條件,將無法再使用(此即本次刻意關閉的注入入口)。
Migration Notes
- 純前端變更,無部署腳本、無 DB/範本檔需求;不影響呼叫
QueryAndStatistics的各表單契約。
- 已用 VS 2022 MSBuild 建置
ViewModel、TsControl通過(exit 0)。
注意(後續待辦,非本次範圍)
- DB 層二階注入未處理:
TWORK_STATISTIC_CUSTOMER等子程序把客戶代號裸拼進QueryCondition(CudataSpecialQuery 來源)、GetSqlData.cs的GetCustomerSKU/GetARAllowan同類;以及 SPTWORK_BD_VIEWLIST的QUOTENAME/連線帳號降權。詳見 ADR 0061。
- 字串值跳脫(
-
06-26 app-datatemplate-restore-h-p ▸
2026-06-26 補回 App.xaml 缺漏的程式 DataTemplate(H.Inventory + P.Invoice 批次)
摘要
延續 E.Order 批次,補上 H.Inventory 與 P.Invoice 缺漏的 VM→View
DataTemplate(缺了會導覽不出畫面)。變更
TsERP/App.xaml:- 新增
xmlns:inventory(ViewModel.H.Inventory)、xmlns:inventory1(TsERP.H.Inventory)命名空間
(此模組原本完全沒有任何 prefix——
invent:是 D.Bom.Invent,不是它)。- P.Invoice 10 支(
invoice:/invoice1:):Tick3、Ticka、Ticka_disc、Ticka_rej、
Ticka_voidrp、Tickmin、Tickr、Ticks、Ticksr、Tother。- H.Inventory 9 支(
inventory:/inventory1:):Bol、Invrec、Jobcode、Splace、
Trinout、Trlima、Trlost、Trrama、Trsama。排除(誤報修正)
- MasterFile(PRIMEEDI810)不補:
MasterFileViewModel雖 overrideProgramClass且繼承
ERPProgramViewModel,但實為Edi_ExportViewModel的內嵌子 VM(Edi_ExportViewModel內new並以property 持有,畫面由
Edi_Export.xaml內聯DataTemplate宿主),且無獨立 View → 非可導覽程式,不需 App.xaml DataTemplate。屬靜態啟發式的預期誤報。
驗證
MSBuild TsERP.csproj /t:MarkupCompilePass1exit 0(19 個 DataType 與 View 型別全解析)。待辦
原 62 支缺漏:已補 E.Order 10 + H.Inventory 9 + P.Invoice 10 = 29,MasterFile 誤報排除 1,剩 32 支
(C.GeneralAffair 8、I.ARAP 5、J.QC 5、F.Production 4、G.Purchasing 4、A.SystemData 2、L.Communication 2、
D.Bom 1、K.Cost 1)分模組逐批補。建議 runtime 逐支導覽確認。
- 新增
-
06-26 app-datatemplate-restore-eorder ▸
2026-06-26 補回 App.xaml 缺漏的程式 DataTemplate(E.Order 批次)
摘要
延續 Cuinve/Cupdma 的修復,系統性盤點
App.xaml:找出所有 overrideProgramClass且繼承導覽型base(
ERPProgramViewModel/ErpProgramWithDetailViewModel)卻沒有 VM→ViewDataTemplate的程式(任何 ResourceDictionary 都查不到 → 導覽時畫面無法顯示)。全專案共 62 支,本批先補 E.Order 10 支。
變更
TsERP/App.xaml新增 10 個DataTemplate(VM 在ViewModel.E.Order=order:,View 在TsERP.E.Order=order1:):Ci、Cuqt、Preord、Salema、Rma、Sample、Visit、Shiptoaddress、Fillrate、WarrantyCard
(其中 Ci/Cuqt/Preord/Salema 即 scx_ord_cy 移植、先前標「檔案已建但 runtime 未驗」的那批。)
驗證
MSBuild TsERP.csproj /t:MarkupCompilePass1exit 0(10 個 DataType 與 View 型別全解析;避開執行中 MCP server 鎖 DLL 的 copy 步驟)。待辦
其餘 52 支(C.GeneralAffair 8、H.Inventory 10、P.Invoice 10、I.ARAP 5、J.QC 5、F.Production 4、G.Purchasing 4、A.SystemData 2、L.Communication 2、D.Bom 1、K.Cost 1)分模組逐批補。
建議 runtime 逐支實際導覽確認能顯示。
-
06-26 alledi-newyamaha-parser-rewrite ▸
2026-06-26 alledi 新YAMAHA parser 重寫(對齊 VFP Page19 / YDS.TXT)
摘要
alledi「新YAMAHA」分頁的解析器原本整支寫成 Page1 舊 YAMAHA 的格式(SDF 固定欄寬、讀
YAMAHA.TXT、單軌 ORMAST),與本頁(VFP Page19 / EDI-P19-YAMAHA)完全不符。本次依 VFPp19yamaha查詢鈕.Click(8089-8353)整支重寫。變更
- 來源檔改為
C:\轉EDI資料\YDS.TXT(逗號分隔 CSV,VFPAPPEND ... DELIMITED),不再是 SDF 固定欄寬的YAMAHA.TXT。VM 預設檔名同步更新。
- 欄位對映改為 YDS.TXT 的逗號欄序(順序/訂單輸入日/追加刪除/客戶品號/交貨地點/客戶訂單號/預訂交期/數量/單位/包裝量…),只取
追加刪除='A'列;略過檔頭列。
- 客戶品號格式重整
xxx-xxxxx-xx-xx-xx(VFP 8192),再以 cuinve 依「該列預訂交期 + 交貨地點」反查品號。
新增
- 5 期工作日攤分演算法(VFP 8264-8333):依 6 個日期輸入(下二~下六起始日 + 下六截止日)切 5 段,落在各段的數量累加進 N2T~N6T 桶(鍵:客戶品號+品號+交貨地點+單位),再以「基數 100 × 工作天數」倍數攤分、逐工作日攤平成多列。
- 日期分配表(VFP 8117-8156):每段把交期每隔 5 個工作天分配一筆、超出再補洞,決定每筆攤分列的交期。
- 特例:品號含
*P(P 件不拆單)或 預訂交期早於下二起始日 → 直接成一列、不攤分。
- 雙軌目標單據(VFP 轉單鈕 8361-8623):列的
客戶訂單號非空 → ORMAST(轉至訂單);空 → PREORD(轉至預示)。攤分(預示)列一律 PREORD。
- 6 個日期輸入框的值由 VM 帶入 BLL;必填 + 嚴格遞增驗證(VFP 8101-8108)。
工作日曆(已接真正的 LCL工作日曆)
UPDT_WKDAYS/UPDT_BACKWKDAY_LCL已接真正的工作日曆(含假日):BLL 預設用Util_Pdt(從本機 SQLite 暫存表LCL工作日曆載入,沿用既有Updt_WkDays/Updt_BackWKDay_Lcl,與 VFP 同義)。
WorkDaysBetween/BackWorkDay仍可覆寫(單元測試用);當工作日曆載不到(如未登入 / 測試環境)時自動退「日曆日」保底。
已知限制(後續階段)
- 需以真實
YDS.TXT樣本檔 + DB(cuinve 反查 + LCL工作日曆 已載入)runtime 驗收欄位座標與攤分交期。
Breaking Changes
無(行為從「錯誤格式」修正為正確格式)。
Migration Notes
無需 migration。
- 來源檔改為
-
06-25 sliybrowd-edit-gate-and-seek-validation ▸
2026-06-25 — 會計日記帳(SLIYBROWD)修改鈕守門 + seek 欄位存在性驗證
摘要
修正會計日記帳查詢頁(SLIYBROWD)修改模式的兩個問題:修改鈕可被任意切換、以及可輸入的代號欄位(項目編號等)不檢查是否存在。對齊 VFP
scx_acc原行為。變更
- 修改鈕守門(
SliybrowdViewModel.Edit()):
- 已在修改模式時再按「修改」不再重新進入 —— 避免重置每列
IsChanged/增刪修把使用者已做的變更追蹤洗掉(按修改→改幾格→又按修改 會靜默清空、儲存等於沒存)。- 需具該程式「可否修改」權限才允許切入修改模式;無權限時跳訊息並維持唯讀。
- 對應 VFP
ledit.Click守門條件「LSAVE.ENABLED=.F. AND IS_可修改」。- seek 欄位存在性驗證(
Sliybrowd.xaml.cs新增CellValidating):
- 修改模式下,項目編號/部門代號/客廠代號/員工編號/專案代號等 seek 欄位提交前會檢查代號是否存在於主檔,查無此代號就擋下提交、焦點留在格內、跳「資料不存在」。
- 空值與
MISC(雜項)不檢查,比照既有TsSearchRule行為。背景
- 既有平台
TsSearchTextBoxV2.OnApplyTemplate把TsSearchRule(存在性檢查)加到「深拷貝後的 binding」卻漏了SetBinding把它套回控件,導致 seek 控件的存在性驗證從未生效(此修正先在 SLIYBROWD 這支以 gridCellValidating就地補上,未動全域TsSearchTextBoxV2,避免影響全 app 其他 seek 欄)。
- VFP 原版實際只開放編輯 摘要/部門代號/專案代號/分類索引1/分類索引2 五欄;新版 grid 另外放開了 項目代號/客廠代號/員工/分類索引3、4。本次先補驗證,是否要把這幾欄改唯讀以完全對齊 VFP 待裁定。
Breaking Changes
- 無「可否修改」權限的使用者,原本能切入修改模式,現在不行(屬權限修正)。
Migration Notes
- 無資料庫異動。存在性查詢走既有
TWORK_EXIST(DataValidate 平台),不需新登錄。
- 修改鈕守門(
-
06-25 scx-ord-cy-feature-completion ▸
scx_ord_cy(CY 朝陽/鈞寶 訂單模組)功能補完
日期:2026-06-25
摘要
依 VFP
scx_ord_cy全模組對比 + 逐欄位(每個 TextBox/Column)稽核結果,補回新版 TsERP 缺漏的欄位驗證/連動/機制。多客戶分歧依 ADR0050 以
Context.Env.CompanyShortName == "朝陽" || "鈞寶"護欄包覆,不污染非 CY(US/NOGIHISA)行為。本批為 ultracode 多代理人協作(對比→稽核→驗證設計→套用)。
新增(universal,全客戶受惠)
- cupdma:選品號帶 leadtime/最低包裝數/最低訂單量/規格/中文描述;master 補綁 最低毛利率/有效天數;最低毛利率≤0 擋存。
- salema:明細品號查無/停用 存檔驗證。
- preord:控制面板補「調整數量」(交期區間×比率)、「交期變更」(工作日曆回推、*P 用 P件天數)。
新增(cy-specific,朝陽/鈞寶 護欄)
- preord:朝陽+客戶 AZY/AZZ 跳過客戶品號反查。
- cuqt:CY 模具/治具各自獨立分母分攤(非 CY 維持新價台數)。
- pk:A07 客戶箱號前置文字='CY'。
- salema:'單價'$IS_備註 權限隱藏 單價/金額 欄。
- estsal:明細帶 SK_INVENT 停用/停用說明/停用日期 唯讀欄;交期排序鈕(品號+預訂交期重編序號)。
- ormast:預訂交期→依客戶 leadtime 工作日曆回推 回覆日期 + 出貨日90日提示;客戶訂單號帶下空白明細。
- pdtsal:grid 客戶簡稱 顯示欄(IsCyCompany 才顯示)。
- ormast(needs-service/reuse):客戶品號→反查 cuinve 帶 品號/包裝量/單價(reuse GetCustomerSKU,無新 SP)。
- 基建:
EnvShortcut.CompanyShortName(供全模組公司分流)。
跳過(使用者裁定)
- 金額幣別小數位(salema GetAmount 維持 round-2,不動金額計算)。
- 所有「列變色 / 動態底色 / 前景色」(cuinve/pdtsal/estsal DynamicBackColor、cuinve 品號變紅)。
- 快速審核(QuickApproval)。
⏳ 待辦(外部相依,本環境無法完成驗證)
1. needs-service(reuse-existing,已設計、同 ormast 客戶品號反查 pattern,待套用):
- estsal 客廠品號↔品號 雙向反查(reuse SetSKUByCustomerSKU/SetCustomerSKUBySKU)+計算單價鈕(DARB_BIZ_CUST_UNITPRICE)
- cupdma 客戶品號→反查品號(reuse GetCustomerSKU)
- preord 客戶品號反查補 預訂交期+交貨地點 第 4 參數 + 查無客戶品號存檔擋
- cuinve 明細唯讀顯示欄(庫存管制/管制說明/停用/群組/設變,reuse Darb_GetData4 'invent')
2. pdtsal「計算資料」鈕(CY 核心,~420 行):跨 preord/ormast/pdtinf/cost/交易單/cupdt 彙總自動產生產銷計畫。
- ⚠️ 依賴 DB view
vw_pdtsal交易單(新庫不存在),須先在 DB 建該 view(資料庫物件,非 SP);之後寫PdtsalCalculateBll+ grid2 成本匯率輸入 + RelayCommand。無此 view 無法取上月庫存/生產實績/銷售實績。3. alledi(CY 機車 OEM EDI 轉訂單,18 個在用分頁):整支未移植。
- 在用分頁:鼎豪/SYM/SYM預示/慶俊訂單/慶俊預示/YMTT/YMTT預示/泛用取品號/年度銷售/SY_BOM/SY計劃/SYM-2W/新YAMAHA/新SUZUKI 等。
- ⚠️ 無法靜態完成:各廠 XLS/XLSX/CSV/PRN(SDF) 解析的欄位起訖/Cell 座標/表頭列數/編碼,須拿
C:\轉EDI資料\下真實樣本檔逐欄校對;cuinve 反查須朝陽/鈞寶實機 DB;上傳須跑 INPUT-BB dispatcher(PREORD/ESTSAL/BOM 上傳路徑各須實測);Telerik SpreadProcessing 解析 API 下筆前須查 telerik-dpl-assistant。建議參考既有LogicBll/E.Order/Darbedittool/(Amazon/EBay/Walmart)架構,逐廠單頁 runtime 驗收。如何檢查
- 建置:VS MSBuild
TsERP\TsERP.csproj(已全程 exit 0)。
- 業務驗收(須在朝陽/鈞寶庫,CompanyShortName=朝陽/鈞寶):
- cupdma:選品號→單位/leadtime/包裝/訂單量自動帶;最低毛利率輸入 0 存檔應擋。
- preord:填交期區間+比率按「調整數量」;按「交期變更」交期回推。
- ormast:輸客戶品號→自動帶品號/單價;改預訂交期→回覆日期回推 + 超90日提示;改主檔客戶訂單號→空白明細帶入。
- salema:權限備註含「單價」者,單價/金額欄應隱藏;明細輸停用品號存檔應擋。
- estsal:明細顯示停用欄;按交期排序序號重編。
- pk:A07 客戶存檔後明細前置文字=CY。
- 非 CY 庫(如禾久)以上 cy 行為應不觸發(護欄)。
-
06-25 operationforecast-fork ▸
2026-06-25 — 新增「營運預測模擬」、原「生產計劃查詢」回歸精簡
摘要
把生產計劃查詢(pd_qry7)拆成兩支:新增獨立的「營運預測模擬」做為前瞻分析/模擬的第二版,
原「生產計劃查詢」回歸只保留 VFP 三頁 + 金流預測。詳見 ADR 0056。
新增
- 營運預測模擬(OperationForecast) 全新程式,為 pd_qry7 的完整 fork(自有 Model/Source/SP/BLL/VM/XAML)。
分頁與目前生產計劃查詢相同:訂單預示預估、生產計畫、使用量、原物料用量(庫存缺口)、金流預測、模擬插單、產能負荷(需求)、樞紐分析。
- 7 支專屬 SP:
TWORK_QRY_OPERATIONFORECAST、TWORK_QRY_OPFCST_{GETORDER,PRODORDER,OTHERDATA,SUPPLY,CASHBASE,WKLOAD}。
- SQL 部署腳本:
sql/TWORK_QRY_OPERATIONFORECAST_darbnogicsa1.sql、sql/TWORK_QRY_OPFCST_EXT_darbnogicsa1.sql、
sql/TWORK_QRY_OPFCST_WKLOAD_darbnogicsa1.sql(+_darbcycsa1.sql)、登錄腳本sql/營運預測模擬_register_program_darbnogicsa1.sql。變更
- 生產計劃查詢 移除四個分頁:原物料用量、模擬插單、產能負荷(需求)、樞紐分析;
保留:訂單、預示及預估/生產計畫/使用量(機種別)/金流預測。
刪除
- 原「生產計劃查詢」清除被移除分頁的 dead code:
- VM 的 模擬/產能/缺口彙總·明細/樞紐 成員、code-behind 樞紐 handler。
- BLL 的
RunSimulation/BuildWorkCenterLoad/WorkCenterLoads與只給模擬用的快取。- 檔案
WorkCenterLoadPoco.cs、SimulationOrderPoco.cs、ProductionplanDrillDownViewModel.cs、生產計劃查詢明細.xaml(.cs);類別ShortageSummaryPoco。- XAML 的
OrderPivotProvider、ShortageRowBackgroundConverter、模擬累計折線與圖例。- 保留:
BuildShortage/ShortageCalculator/ShortageRows與 Supply/CashBase SP — 金流預測的計劃預測層仍需缺口計算。Breaking Changes
- 無(原程式碼識別、ProgramClass、SP 名皆未改;只是分頁變少 + 多一支新程式)。
Migration Notes
- 「營運預測模擬」要能從選單開啟,需在每個目標資料庫部署上述 4 支 SQL(SP+proc_param)並執行登錄腳本。
sqlcmd 跑含中文 UTF-8 無 BOM 腳本要加
-f 65001;朝陽 darbcylog1 的 proc_param.pkid 是 IDENTITY,WKLOAD 用_darbcycsa1.sql版。- 原生產計劃查詢無需任何 DB 變更。
-
06-25 localization-chinese-keys ▸
2026-06-25 — 本地化採「中文當鍵」(additive)
摘要
多語言查表改用中文當鍵:JSON 新增中文鍵別名(保留英文鍵),讓佔 85% 的中文鍵 XAML 綁定能直查到譯文、切換非中文語言正確翻譯。詳見 ADR 0055。
新增
Common/Lang/Xaml/*.json:94 檔新增共 2060 個中文鍵別名(指向同一譯文物件)。
變更
- 還原 Checkpay pilot:
Checkpay.xaml由 PascalCase 鍵改回中文鍵(中文鍵現可直查命中)。
JsonLocalizationStore:移除先前的反查 fallback(中文鍵直查即命中,反查冗餘)。
Breaking Changes
無(英文鍵 JSON 條目保留,77 個英文鍵 XAML 檔零回歸)。
Migration Notes
- runtime 需 Rebuild TsERP 套用 JSON 變更。
- ⚠️ 類別產生器(repo 外)仍輸出 PascalCase 鍵,下次重跑 JSON 會覆寫中文別名(待後續同步生成器)。
- 25 筆撞名(同 class 兩屬性共用同一中文)只保留一個中文別名,待人工檢視。
-
06-25 flowcast ▸
2026-06-25 — 新增「金流預測」(flowcast)
摘要
新增獨立的金流預測程式,用票據/帳款/訂單採購單 三來源推未來現金(月堆疊柱+累計淨額線)。詳見 ADR 0057。
新增
- 金流預測(flowcast) 程式(ProgramClass
FLOWCAST,M.EIS):
- 一支 SP
TWORK_QRY_FLOWCAST回 4 RS(票據/帳款/訂單未交/採購未交)。-
FlowcastComposer(純函數)合成統一現金事件+月彙總/堆疊;到期日接PayTermDate。- UI:來源勾選(票據/帳款/訂單/採購)+月堆疊柱(收上付下)+累計淨額線+資金警戒線+點柱過濾明細。
- 檔:
Model/SQLProcedure/Twork_Qry_Flowcast/*、LogicBll/M.EIS/Flowcast/*、ViewModel/M.EIS/Flowcast{,Condition}ViewModel.cs、TsERP/M.EIS/金流預測{,Condition}.xaml。
- SQL:
sql/TWORK_QRY_FLOWCAST_darbnogicsa1.sql、sql/flowcast_register_program_darbnogicsa1.sql。
口徑重點
- 票據:收 CA/CB/CF、付 CP/CQ(排除 CC/CD 融資);現金日預兌日優先。
- 帳款:rp_m 未沖,方向用 rpdef.單據分類(AR+ 收/AP+ 付);費用申請只算 9B+83 的「6.直接沖帳」;排除預收/預付/暫付/待抵;立帳起日預設近一年。
- 訂單採購:未交=數量−已交數量,非結案;金額本幣含稅按未交比例;現金日回覆日/預訂交期+收付條件。
- 三來源靠票況/單據分類/已交數量分界,零重疊。
Breaking Changes
- 無(全新程式;既有 OperationForecast 的金流分頁不受影響)。
Migration Notes
- 每個資料庫部署
TWORK_QRY_FLOWCASTSP(含 proc_param)+執行登錄 SQL 後,重啟即可從選單開「金流預測」。
- sqlcmd 跑含中文 UTF-8 腳本要
-f 65001(或轉 UTF-16);其他庫 cy/zd/production 各自部署。
- 金流預測(flowcast) 程式(ProgramClass
-
06-25 dev-parameter-registry ▸
2026-06-25 開發用本機臨時參數檔(dev-prgpar.json)
摘要
延續
dev-programs.json(ADR 0054),新增參數版:開發中的新程式需要專屬參數時,可先把臨時參數寫進 repo 內dev-prgpar.json,登入時合併進記憶體參數表,使U_Prgpar(...)不必先寫 DB_prgpar即可讀到。僅開發機啟用,正式環境不受影響。新增
TsERP/dev-prgpar.json:本機臨時參數檔(放 repo、複製到輸出目錄)。欄位對齊_prgpar(programClass/name/value/description/category/categoryDescription),預設parameters: []附範例。
Common/Environment/DevPrgparRegistry.cs:讀 JSON → 合併進ParameterList的載入器(同名鍵覆寫、新鍵新增)。
EnvironmentSetting.DevParametersEnabled靜態旗標;啟動時由App.xaml.cs從設定讀入。
appsettings.example.json新增DevParameters:Enabled說明。
變更
UserBll.GetParameters():建好ParameterList後,旗標開啟時合併dev-prgpar.json的臨時參數。
啟用方式
在
%ProgramData%\TsERP\appsettings.local.json加:{ "DevParameters": { "Enabled": true } }於
dev-prgpar.json的parameters陣列加參數並重新登入;程式內以Context.User.U_Prgpar("名稱")讀取。Breaking Changes
無。Production 不設旗標 → 完全 no-op。
Migration Notes
- 範圍只覆蓋記憶體
U_Prgpar。Util2017.U_PrgparSql(每次查 DB)與「目前表單參數」編輯器(直接讀_prgpar)不受影響。
- 同名鍵:臨時值覆寫已載入的 DB 值(開發時可暫時試不同值)。
- 還原到資料庫:依各筆
programClass開該程式的「目前表單參數」編輯器照值重輸存檔即可(不自動產生 SQL)。
-
06-25 cudata-vfp-field-restore ▸
2026-06-25 客戶資料(CUDATA)補齊 VFP 缺漏欄位與驗證
摘要
以 VFP
scx_ord_cy的cudata逐欄交叉比對現行畫面,補回「資料層有、UI 沒綁」的欄位、新增兩個資料庫欄位,並補回一條輸入驗證。新增(Tab1 基本資料)
- 直接出貨、附成績單、轉廠(Y/N 旗標,置於基本資料群組)
- 英文簡稱、英文名稱
- 工廠電話(聯絡資訊群組;Tab1 電話僅保留公司電話+工廠電話)
- 發票地點、請款郵遞號(地址資訊群組)
新增(Tab2 財務)
- 新群組「詳細聯絡資訊」:負責人、負責人電話/分機、會計、會計電話/分機、聯絡人2、聯絡2電話、聯絡1/2分機、聯絡人職稱、身分證字號、工廠傳真
- 新群組「公司概況與交易」:國家別、客戶區域、交易方式、成立時間、收款日、營業項目、稅籍號碼、關係人
- 新群組「徵信記錄」(多行)
- 財務資訊群組新增:技術報酬金、佣金
變更(行為)
- 帳款起始日:輸入時驗證須為 1~31(對應 VFP
帳款起始日.Valid),於CudataSave.AllowSave。
Breaking Changes / Migration Notes
- 技術報酬金 / 佣金為新欄位:
cudata表與vw_cudataview 原本沒有。
部署前必須先於 SSMS 對每個目標庫執行
sql/cudata_add_commission_techfee_darbnogicsa1.sql(ALTER TABLE 加兩欄 + 重建 view)。未執行前若儲存客戶資料會因欄位不存在而失敗。
- 其餘欄位皆為既有 DB 欄位,純補 UI,無需 migration。
未處理(依需求略過)
- 聯絡人明細 grid 的 skype / msn / facebook / 呼叫器 4 欄(D 類,刻意忽略)。
-
06-25 alledi-tab-display-restore ▸
2026-06-25 alledi 各分頁顯示還原(對齊 VFP)
摘要
alledi(CY 機車 OEM EDI 轉訂單工具)原本 14 個分頁共用同一個簡化版面(固定 11 欄表格、版面全相同)。逐頁對照 VFP 後,把各頁顯示內容還原成與原版一致:各頁專屬表格欄位、客戶選擇器、日期/年月輸入框、小計、Excel/DBF/篩選/重新檢查等按鈕、正確的轉單鈕文字,並修正會讓分頁壞掉的預設檔名。架構改為 per-tab DataTemplate(每頁一個 VM 子類 + 一個對應 DataType 的 DataTemplate,見 ADR 0058)。 顯示與轉入已就緒、轉單上傳走既有
AllediUploadBll;各廠轉單深層規則(報價/單位反查、工作日攤分、版次、.XLS 舊檔、新YAMAHA 重寫)須真實樣本檔 + DB runtime 驗收,屬後續階段。變更
- 預設檔名修正(原本錯誤,部分會導致分頁無法使用):
- SYM:
VMEP.XLS→640C.TXT- SYM預示:
YAMAHA.PRN→640C.TXT- 慶俊訂單/慶俊預示:
640C.TXT→A09.XLS- 新SUZUKI:
SUZUKI.TXT→SUZUKI_A.TXT(B/C 檔由同目錄推導;原檔名會直接 FileNotFound)- 轉單鈕文字依各頁還原(原一律以「是否含預示」推導):SY_BOM=轉至BOM、SY計劃=轉至預示、SYM-2W=轉至年度預估、新YAMAHA/新SUZUKI=轉至訂單及預示、泛用取品號=產生EXCEL、年度銷售=產生DBF,其餘維持轉至訂單/轉至預示。
- 表格欄位改為各頁專屬(對齊 VFP 各頁 cursor 欄位),不再固定 11 欄。
新增
- 各頁還原 VFP 專屬控件:
- 客戶代號選擇器(各頁預設 A01/A02/A04/A07/A09/A33)。
- 日期/年月輸入框:SYM(年度/月份)、SYM預示(下一/下二/下三起始日、下三截止日、年度/月份)、慶俊訂單(年度)、慶俊預示(起始日期/年度/月份)、SY計劃(起始日期/預示單號/轉單起始日)、SYM-2W(起始日期/取代預估單號/轉單起始日/轉單截止日)、新YAMAHA(下二~下六起始日、下六截止日)、年度銷售(年度)。
- 小計:YMTT訂單(數量小計/金額小計)、YMTT預示(原始數量小計/數量小計),轉入後即時重算。
- 額外按鈕:YMTT(Excel)、SY_BOM(EXCEL)、SY計劃/SYM-2W(篩選錯誤、Excel)、新YAMAHA(文字檔讀入、篩選錯誤)、SYM預示/慶俊預示(重新檢查)、年度銷售(篩選錯誤)。
- 篩選錯誤:已實作客端過濾(只顯示「錯誤」欄非空的列)。
- 解析器把原本塞進「備註」的資料改填獨立欄並顯示:鼎豪(客戶訂單號/三陽編號/訂單輸入日)、YMTT訂單(客戶訂單號/結關日期)、新SUZUKI(客戶訂單號/展開日期/類別)。
已知未完成(後續階段)
- 轉單/上傳(ORMAST/PREORD/ESTSAL/BOM 組單、報價反查單價、單位/包裝量帶值、版次遞增、原幣未稅)尚未實作;多數 BLL 目前只做 Parse。
- 預示頁工作日攤分(含第二/三表格明細)未做。
- Excel/DBF/重新檢查/文字檔讀入 按鈕目前點擊顯示「後續階段實作」訊息。
.XLS(舊 BIFF)讀取:SY計劃/SYM-2W 真檔仍會解析失敗(reader 為 XlsxFormatProvider)。
- ~~新YAMAHA:parser 仍為舊 YAMAHA(Page1)格式~~ → 已於 2026-06-26 重寫,見
2026-06-26-alledi-newyamaha-parser-rewrite.md。
Breaking Changes
無(顯示層還原;資料表/上傳格式未變)。
Migration Notes
無需 migration。
AllediImportRow新增多個顯示欄位(聯集),皆為純 POCO 屬性。 -
06-25 alledi-oem-edi-transfer ▸
2026-06-25 alledi(OEM EDI 轉單)移植完成 + scx_ord_cy 收尾
摘要
完成 VFP
scx_ord_cy.prg(CY = 朝陽/鈞寶 客戶專屬版,18 class)對比的最後一塊缺口:alledi(機車 OEM EDI 轉訂單工具)整支移植。同時收尾 scx_ord_cy 的
cy-specific 連動、needs-service(reuse 既有服務)與 pdtsal「計算資料」。
本檔承接
2026-06-25-scx-ord-cy-feature-completion.md,補記 alledi 與建置修正。新增
- alledi 程式(OEM EDI 轉單) —
LogicBll/E.Order/Alledi/、ViewModel/E.Order/Alledi/、TsERP/E.Order/Alledi.xaml
- 統一列模型
AllediImportRow(實作ICustomerSKU)。- 14 支在用廠別 parser(
Alledi*ImportBll.cs):鼎豪/SYM/SYM 預示/慶俊訂單/慶俊預示/YMTT 訂單/YMTT 預示/泛用取品號/年度銷售/SY_BOM/SY 計劃/SYM-2W/新 YAMAHA(P19)/新 SUZUKI(P20)。
cell 座標、SDF 欄寬均抄自 VFP;客戶品號對照走 cuinve 反查。
- 共用讀檔工具
AllediExcel.cs(Telerik Document Processing,.xls+.xlsx皆支援)。- 上傳
AllediUploadBll:依「目標單據」自動分派至 ORMAST/PREORD/ESTSAL/BOM,走 ItemsBindingManager(
Register<Source>().DirectSaveToSqlite → SaveAll → UploadToSql → TruncateAll),主從以
linkid = 主檔 pkid串接。- 程式外殼:
ProgramClass.ALLEDI+AllediViewModel(14 分頁)+AllediVendorTabViewModel(選檔→轉入預覽→上傳)+
Alledi.xaml(RadTabControl+ 預覽RadGridView)+ App.xaml DataTemplate。- dev-programs.json 加入 ALLEDI — 開發期免動 DB,於
appsettings.local.json開
DevPrograms:Enabled後重新登入,即於「E.營業收款」出現「OEM EDI 轉單」。變更
LogicBll/LogicBll.csproj— 新增 4 個 cross-platform Telerik DPL 套件
(
Telerik.Documents.Spreadsheet+.FormatProviders.OpenXml+.FormatProviders.Xls),供 LogicBll 解析 Excel 而不引入 WPF UI 依賴。
Common/ProgramClass.cs— 新增ALLEDI。
TsERP/App.xaml— 新增 alledi namespace 與AllediViewModelDataTemplate。
修正
- 登入崩潰
The given key 'ALLEDI' was not present in the dictionary—GetExtendFunction.SetDescription
(登入時跑)會逐筆走
PermissionTable用dic[類別名稱]取各程式的「其他N說明」(擴充功能鈕標題),字典
dic只由 DBprgsct1建。dev-programs.json 注入的程式(如 ALLEDI)不在 DB →dic["ALLEDI"]丟
KeyNotFoundException擋住整個登入。改為TryGetValue略過缺項(其他N說明留空)——一併修好所有「純注入、未在 DB prgsct1 登錄」的開發程式。(EISDASH/PRODUCTIONPLAN 因已有 DB prgsct1 列才沒踩到。)
- AllediViewModel 點選後空白 — 原繼承
ERPProgramBaseViewModel(非導覽器認得的三種版面型之一,item為 null
→ 不渲染)。改繼承
ERPProgramDefaultViewModel(同 Library/TodoList 自訂頁面型),由ErpProgramDefaultLayout承載 Content;無下方查詢面板故
BottomPanelContent回 null。- 建置「
App未包含InitializeComponent」+ MSB3027/MSB3021 — 並非 App.xaml 錯誤,
而是執行中的
TsErp.Ai.Mcp.Server鎖住輸出 DLL,導致 App.xaml markup 編譯未完成、App.g.cs未重新產生。停掉該程序後重建,TsERP exit 0、0 編譯錯、0 檔案鎖錯。(已記入
[[build-toolchain-vs-msbuild]]:再遇到先關TsErp.Ai.Mcp.Server再 build。)- Telerik DPL Excel API 對版(telerik-dpl-assistant):改用
Import(stream)、
Cells[r,c].GetValue().Value.RawValue、Worksheet,移除不存在的GetValueAsDouble/GetDefaultCellFormat/HasValue/CellValues。- 平行代理產生的 parser bug:SyPlan
客户代號→客戶代號、YmttForecast 重寫補 helper、Sym 客戶代號預設。
跳過(使用者裁定)
- 快速審核、金額幣別小數位、所有列變色/底色/前景色,本次不做。
Migration Notes
- 無新 SP、無 DB schema 變更:pdtsal 計算資料、estsal 客廠品號雙向、ormast/cupdma/preord 客戶品號反查
全 reuse 既有
DescriptionHelper/Darb_GetData4。- alledi 正式上線:開發期走 dev-programs.json;正式須
usp_新增程式+_menum/_menud/prgsct1登錄。
- 待 runtime 驗收:alledi 各廠 parser cell 座標需以
C:\轉EDI資料\真實樣本檔逐欄校對,
主檔表頭預設(受訂日期/序號前置碼/訂單別/幣別/匯率)需依各廠 VFP「轉至訂單」校正。
- cy-specific 連動以
Context.Env.CompanyShortName == "朝陽" || "鈞寶"護欄,非 CY 客戶不受影響。
詳見
LogicBll/E.Order/Alledi/README.md與記憶[[scx-ord-cy-compare-complete]]。 - alledi 程式(OEM EDI 轉單) —
-
06-24 scx-nogi-query-port ▸
2026-06-24 — scx_nogi 鈞寶專屬查詢(6 支)按 VFP 重寫移植
摘要
把 VFP
scx_nogi.vcx(NOGIHISA/鈞寶客戶專屬查詢報表庫)6 支查詢整批按 VFP 行為移植到新版 TsERP,沿用既有 DARB SP,不新建 SP。三專案(LogicBll/ViewModel/TsERP)建置通過,runtime 待驗收。詳見 ADR 0051。新增
- 訂單資料查詢(M-020,
Qry_ord_nogi):起訖訂單/客戶/品號/受訂日期/預訂交期/業務員 + 集團/倉儲/只含未出貨;結果 grid + 訂單/已出/未出三項統計。
- 出貨資料查詢(M-050,
Qry_sal_nogi):8 個彙總頁(出貨明細/產品/客戶/業務/類別/日期/單號/群組);出貨退回(SB)金額取負;合計框。
- 毛利率分析(M-160,
Qry_profit_nogi):8 彙總頁;利潤=本幣未稅−成本、標準利潤對照(coststd);標準單位成本差異%篩選。
- 其他交易單查詢(M-190,
Qry_trli_nogi):12 種倉儲交易單別(EI/EO/LO/LI/BI/BO/AA/SS/IT/NB/GU/IA,第12欄 UI 標 CI 但過濾碼為 IA);LO/LI 自銷售單補抓;EO 交易備註串接。
- 耗料查詢(M-140,
Qry_trwk_nogi):起訖部門/品號/日期/單號 + 交易別/轉入倉儲;衍生欄(未交數量、金額、年月、使用單號依參數 3012)。
變更
- 進貨資料查詢(M-070,
Qry_ra)修正既有 beta bug,對齊 VFPqry_ra_nogi:
- 結果欄位對映修復(原英文屬性無對映 → 整批空白)。
- 4 個單據別 checkbox(進貨RA/退出RB/總務進貨RC/總務退出RD)與付款別(已轉/未轉應付)實際接上查詢條件(原為空,勾選無效)。
- 新增「進貨費用」勾選 → 帶出進貨費用明細列。
刪除 / 不做
- 列印報表(.frx)、樞紐分析表、報表選擇排序鈕:一律不做,改用清單內建排序與匯出。
- 公司專屬除錯碼(特定 usercode 匯出 dbf)不移植。
後續調整(同日)
- 進貨資料查詢(Qry_ra)介面現代化:改為 TsView、查詢條件改成獨立面板、欄位標題與條件 label 全面中文化(對齊其他 5 支 nogi 查詢)。
- 耗料查詢(M-140)新增明細列雙擊 drill-down:雙擊一列依單號開頭開啟對應「加工單」或「損耗單」並定位(還原 VFP 雙擊跳轉)。
Breaking Changes
無。
Migration Notes
- 不需任何 DB migration:沿用現成
DARB_QRY_STD/DARB_GETDATA4,無新 SP、無 proc_param 變更。
- 選單路由:6 支 ProgramClass 命名一致(M-070 進貨已將 VM 改名
Qry_ra_nogiViewModel/ ProgramClassQRY_RA_NOGI),選單碼對應QRY_*_NOGI即可路由。
- 待 runtime 驗收:開啟各查詢確認有資料、條件過濾正確、彙總金額正負號正確。
- 訂單資料查詢(M-020,
-
06-24 localization-single-service-live-switch ▸
2026-06-24 多語言收斂單一服務 + 即時切換語言
摘要
多語言系統改走單一服務(方案 B 第一刀,見 ADR 0052)。切換語言即時生效、不再需要重新登入;
畫面文字、grid 表頭、選單會一起換成新語言。backend 仍是 JSON,之後可無痛換成資料庫。
新增
Common/Lang/ILocalizationStore+JsonLocalizationStore:多語言字串的可抽換來源(之後換 DB 只動這層)。
Common/Lang/ILocalizationService+LocalizationService:單一語言服務(目前語言、即時切換、查表)。
Common/Lang/LocalizationLocator:給元件層取服務的橋接。
TsControl/Localization/HeaderLocalization:TsDataGrid 與 TsRadGridView 共用的表頭翻譯。
- 單元測試
LogicBllTests/Lang/LocalizationServiceTests(8 項,全綠)。
變更
- 設定 → 切換語言:存檔後即時套用,提示改為一般「儲存成功」,不再顯示「請重新登入」。
- ERPSystemContainerView 功能列新增「語言」選單:直接選語言即時切換並持久化(下次登入沿用),
與設定頁共用同一條
ChangePasswordAndMyFavoriteBll.ChangeLanguage;切換時功能列文字本身也即時重翻(
MainWindowMenuViewModel.ChangeText改讀單一服務目前語言 + 訂閱LanguageChanged)。TsRadGridView現在會翻譯欄位表頭(先前完全不翻,dg-to-radgrid 遷移後的迴歸已修)。
- 切換語言後,grid 表頭、選單列、各表單欄位標籤即時更新。
- grid 版型存檔改存「欄位穩定鍵」而非當下譯文 → 版型跨語言通用(英文存、中文開不再被蓋亂)。
缺口補完(同日追加)
- 訊息/對話框文字即時化:
MessageService與ViewModel LanguageService改讀單一服務的目前語言,
切語言後提示訊息、翻譯文字即時跟著變(不重登)。
- 查詢/報表語言對齊:
IUser.Language改為委派單一服務的CurrentLanguage,約 30 個讀User.Language
的呼叫點(查詢/報表撈語系資料)切換後自動使用新語言。
- 報表 locale 即時刷新:新增
FastReportLocalizationService訂閱語言切換 → 重載對應.frl
(繁中/簡中;英日越無檔則退回英文)。新開報表即套新語言。
- grid 右鍵選單翻譯(M2):排序/群組/匯出/匯入/新增/刪除/勾選等 17 條選單字串改走單一服務翻譯,
查無則以現有繁中字面 fallback;選單每次開啟重建,切語言即生效。
- 列舉/下拉即時翻譯:
CobPoco實作 INotifyPropertyChanged +Retranslate,EnumManager訂閱語言切換
反射重翻所有已建立的列舉集 → 列舉下拉顯示文字即時更新。
- 漏譯偵測(L6):DEBUG 下非繁中查無翻譯會去重記到
C:\temps\debuglog\MissingTranslations.txt。
- 壞檔防護(L2):
LanguageMerger.MergeAllper-file try/catch,單一壞 JSON 不再毀整表/擋啟動。
- CJK 標題修正(N2):
AddBlankBeforeCapital含 CJK 直接原樣返回,不再誤刪中日文間空白。
刪除
- 無(
LanguageConverter/TitleConverter兩個空轉換器標[Obsolete],實體刪除留待後續刀次)。
Breaking Changes
- 無對使用者操作的破壞性變更。
Migration Notes
- 既有 grid 版型自動相容:舊版型存的是譯文 header,第一次開啟時當「鍵」查;中文版型會正確翻譯,
非中文/特殊舊版型則原樣顯示,下次存檔自動轉成穩定鍵(自癒),無需手動處理。
- 已知限制:報表(FastReport)文字與系統訊息對話框維持登入當下語言,切換語言後需重新登入才更新;
欄位/表頭/選單則即時生效。
-
06-24 localization-single-json-tree ▸
2026-06-24 — 本地化 JSON 收斂單一樹
摘要
多語言翻譯字典從「分檔樹 + 發行專屬合併樹」兩棵收斂成單一來源樹,並修復約 69 個翻譯分檔未進發行版的漏譯 bug。詳見 ADR 0053。
變更
Common.csproj:Lang\Xaml\*.json、Lang\Model\*.json改用萬用字元一次納入部署(取代 160 筆逐檔登記)。新增 section JSON 免再手動登記。
JsonLocalizationStore.Reload():DEBUG / RELEASE 一致讀Lang/Xaml分檔(移除 release 專屬 Xaml1 分支與 L3 兩樹差異 log),保留 Xaml1 fallback 僅為相容舊輸出。
刪除
TsERP/Lang/Xaml1/(發行專屬合併檔)與TsERP.csproj對應登記。
TsERP/Lang/Model1/Model.json(確認為死檔——全 repo 無.cs讀取)與TsERP.csproj對應登記。
- 舊
ModelMapService機制全清:Common/Lang/Model/(整夾)、Common.csproj的Lang\Model\*.jsonglob、Common/Context/ModelMapAttribute.cs,及Tmp1.cs/Tmp2.cs的[ModelMap]標註。
Breaking Changes
無。執行期行為對使用者相同(翻譯來源不變,僅部署/讀取路徑收斂)。
Migration Notes
- 開發/發行端重建輸出即可;下次 Velopack 發版自動帶齊全部分檔(含先前漏掉的 ~69 個)。
- 舊輸出目錄殘留的
Lang/Xaml1不再被讀取,可忽略或清除。
-
06-24 dev-program-registry ▸
2026-06-24 開發用本機程式註冊檔(dev-programs.json)
摘要
新增開發用機制:免在 DB 權限表(
_menum/_menud/prgsct1)登錄,即可讓新程式出現在左下角程式清單、可點開、權限通過。僅開發機啟用,正式環境不受影響。新增
TsERP/dev-programs.json:本機程式註冊檔(放 repo、跟著 git 走、複製到輸出目錄)。已預載生產計劃查詢(PRODUCTIONPLAN)、主管儀表板(EISDASH)兩支當範例,掛在M.主管資訊模組下。
Common/Environment/DevProgramRegistry.cs:讀 JSON → 建PermissionTable列(權限全開)的載入器。
EnvironmentSetting.DevProgramsEnabled靜態旗標;啟動時由App.xaml.cs從設定讀入。
appsettings.example.json新增DevPrograms:Enabled說明。
變更
UserBll.CreateUserInfo():登入建立權限表後,旗標開啟時注入dev-programs.json的程式列。
啟用方式
在
%ProgramData%\TsERP\appsettings.local.json加:{ "DevPrograms": { "Enabled": true } }重新登入後,
dev-programs.json的程式即出現在左下角清單。新增程式只要在該檔programs陣列加一筆(programClass/programName/subsystem/programNo)並重新登入。Breaking Changes
無。Production 不設旗標 → 完全 no-op。
Migration Notes
- 此機制只負責「程式出現在清單並可導覽 + 權限通過」。資料顯示仍需該程式的 SP / proc_param / view;走 DataManager/Source 的維護畫面仍需
LocalDbContextDbSet 註冊。
- 新電腦 pull 後,
dev-programs.json已隨 repo 帶入;只要各自在本機appsettings.local.json開旗標即可。
-
06-23 trial-advn-page2 ▸
2026-06-23 試算表新增「ADVN 累計試算表」頁,移除「VFP 對照」頁
摘要
試算表(
Trial)頁籤由「目前算法 / VFP 對照」改為「目前算法 / ADVN 累計試算表」。新頁移植自 VFP
scx_acc_advn的trial.pf.page2「舊系統算法」。新增
- 頁籤「ADVN 累計試算表」:以年度結轉檔
sliyyear為期初、依借貸別累計到截止日,
並列功能幣與集團幣兩組「計初借/貸餘、借/貸方金額、累計借/貸餘」,
底部顯示功能幣與集團幣各自的借方/貸方/累計借方/累計貸方合計。
- 後端
TrialAdvnSource(中文屬性)與TrialAdvnBll(沿用DARB_GETDATA3 / DARB_GETDATA4分段查詢,未新增 SP)。
變更
- 試算表第二頁的內容與意義改變(原為開發對拍用的「VFP 對照」鏡像,現為實際的累計試算表)。
- 「目前算法」頁:本幣模式不再顯示「幣別 + 原幣」欄組(原本那組在本幣模式只是功能幣的鏡像、易誤導)。
僅在試算表種類選「原幣」時才顯示原幣欄。以
ShowCurrencyColumns+BindingProxy綁定欄位IsVisible控制。刪除
- 「VFP 對照」頁籤及其後端
TrialBllVfp/TrialTotalsVfp(開發期對拍碼)。
Breaking Changes
無。資料庫、設定、報表皆不變。
Migration Notes
無需 migration,重建後生效。
備註(原幣是否未實作)
DARB_QRY_ABOOK1中「彙總試算表仍然未做」的註解只針對 server 端彙總,不是「原幣未做」。原幣明細試算表(
@查詢別=3)已實作且實測可用,畫面(TrialType.Currency)與報表(
TrialReportType.Currency)皆已接通,本次不更動。 - 頁籤「ADVN 累計試算表」:以年度結轉檔
-
06-23 sliybrowd-edit-accl-validation ▸
2026-06-23 Sliybrowd 修改模式加入科目代號檢查
摘要
總帳明細查詢(Sliybrowd)進入「修改」模式編輯傳票明細時,新增與 Sliy(總帳傳票)一致的會計科目控制檢查:依該科目的控制方式(控制方式1~9、b、6)判斷哪些欄位必須輸入、哪些禁止輸入。
變更
- Sliybrowd 的明細 Grid 掛上與 Sliy 共用的
InjectAcclValidationRuleBehavior,於整列提交(RowValidating)時依科目控制方式檢查:
- 分類索引 1~4、項目編號、部門代號、員工編號、專案代號、產品群組:控制方式為 Y 必填、為 N 禁填。
- 客廠代號:控制方式 6 為 B/C/S 必填、N 禁填。
- 「輸入傳票」非 Y 的統制/標題科目禁止入帳。
- 編輯任一格後(CellEditEnded),該列會標記為「修改(E)」;只有被實際編輯過的列才會觸發科目檢查,未動過的舊列不會被檢查。
- 連帶讓
SliybrowdViewModel.Save的IsChanged篩選能正確抓到被編輯的列(先前列上的編輯不會設旗標,等同沒有可上傳的列)。
Breaking Changes
無。唯讀查詢與報表行為不變;僅影響「修改」模式下的存檔前驗證。
Migration Notes
無需資料庫或設定變更。科目控制方式沿用既有
accl主檔(OpenDbfTable.GetAcclDic())。 - Sliybrowd 的明細 Grid 掛上與 Sliy 共用的
-
06-22 reportsroot-local-override ▸
報表樣板根目錄可由本機設定覆寫
摘要
報表樣板根目錄(
REPORTSROOT,其下放.frx/ Excel 樣板)原本只能從 DBPrgpar表讀取、全 DB 共用。新增可在每台機器的appsettings.local.json覆寫,讓不同機器指向自己的報表樣板資料夾。新增
appsettings.json新增ReportsRootDirectory鍵(預設空字串)。
- 可在
C:\ProgramData\TsERP\appsettings.local.json設定此鍵,做每台機器各自的覆寫。
- 「密碼及我的最愛設定」(
ProgramClass.Setting)新增「本機設定檔」分頁,可直接在程式內編輯%ProgramData%\TsERP\appsettings.local.json:載入/編輯原始 JSON、存檔前驗證格式、自動建立資料夾,存檔後提示需重新啟動。無寫入權限時提示以系統管理員身分執行。
變更
EnvironmentSetting.SetSystemDecimalPlace():ReportsRootDirectory取值改為「appsettings的ReportsRootDirectory有值就用它,否則回退 DBPrgpar的REPORTSROOT」。
- 啟動時於
App.xaml.cs讀取設定並寫入EnvironmentSetting.ReportsRootDirectoryOverride靜態屬性(與既有DatabaseListPath/DatabaseListSourcePath同一處、同一機制)。
Breaking Changes
無。鍵留空時行為與既往完全相同(仍走
Prgpar)。Migration Notes
- 不想改的機器:不必動,保持空值即可。
- 要在本機指向自訂樣板資料夾:在
C:\ProgramData\TsERP\appsettings.local.json加上
```json
{ "ReportsRootDirectory": "D:\\MyReports" }
```
該目錄下需有
Reports\(.frx)與Template\(Excel 樣板)子資料夾,對應ERPIO.ReportDirectory/TemplateDirectory。 -
06-22 adeupload-specialedit-use-xmlsource ▸
2026-06-22 特殊修改(SpecialEdit)改用 xmlSource 上傳,修實際沒上傳的問題
摘要
修正「特殊修改(Special Edit)實際上沒有把資料上傳成功」的問題。
AdeUploadBll.SpecialEdit原本走舊的反射路徑,從_source重新組上傳字串:var stringList = UseRefrectionToCreateUploadData(isModelSource, useMemory); // 讀 _source Upload(..., "Special Edit", stringList, ...);但「特殊修改」狀態實際只會經由新的 ItemsBindingManager 路徑進來:
SaveBll.UpdateData → ItemsBindingManager.UploadToSql(Status) → AdeUploadBll.UpdateToSql(status, xmlSource)這條路徑只會設定預先組好的
xmlSource、不會設定_source。因此SpecialEdit反射到的是null的_source,等於沒有把資料帶上去。(這與 ADR 0010 對 legacyUpdateData(object[], …)路徑的結論相同——該路徑因同樣只讀xmlSource而早已失效。)變更
LogicBll/Ade/AdeUploadBll.cs—SpecialEdit改成與Edit一致,直接上傳xmlSource(移除UseRefrectionToCreateUploadData反射呼叫)。
影響行為
- 使用「特殊修改」的單據(如 paymnt、ftrlima)現在能正確將特殊修改的內容上傳到 SQL;先前實際上傳為空。
Breaking Changes
無。上傳事件(
INPUT-BE/Special Edit)、PassNumber 流程、狀態語意皆未更動。Migration Notes
無需 migration。
影響範圍確認
- 全 repo 舊路徑
UpdateData(object[], …)/UpdateDataWithModel的呼叫者全部只用Add/Edit,沒有任何一處傳SpecialEdit,故移除反射不影響舊路徑。
- 使用特殊修改的表單(paymnt、ftrlima)皆已遷至 ItemsBindingManager,走
UploadToSql新路徑。
相關
- ADR 0010 — BatchEdit 改用 ItemsBindingManager(記載 legacy
UpdateData路徑只讀xmlSource而失效,本次為同類修正)
-
06-21 turn-staging-cleanup-pkid-collision ▸
2026-06-21 轉單上傳後清除 #turn 暫存,修 navigate 撞主鍵
摘要
修正「編輯傳票途中轉傳票後,編輯表單按上/下一筆會崩潰」的問題:
ExecuteAsync異常: constraint failed UNIQUE constraint failed: Sliy.pkid根因是 StagingScope 隔離(ADR 0043)讓「轉單(scope
#turn)」與「編輯表單(scope = ProgramClass.Name)」的列共存於同一張本機 SQLite 實體表,但pkid是該表INTEGER PRIMARY KEY AUTOINCREMENT(全表唯一)。轉單上傳成功後#turn暫存列沒有被清除,殘留在表中;其 pkid 由 AUTOINCREMENT 高水位配出(例 540548,高水位來自先前 navigate 帶入的 server pkid),之後編輯表單 navigate 帶入相同 server pkid 時即撞主鍵。變更
TransferBindingBll.Save():上傳成功後新增Manager.TruncateAll(),立即清除本次轉單的#turn暫存列(scope-aware,只刪#turn,不動編輯表單的列)。
TransferBindingBll.Cancel():取消轉單時亦設定 scope 後TruncateAll(),清除已落地未上傳的#turn列。
DataManager<T>.Truncate():改用 raw SQL(ExecuteSqlRaw DELETE ... WHERE [StagingScope]=...)刪除,刻意繞過 EFChangeTracker/SaveChanges→ApplySyncFields。
- 原本走 EF
RemoveRange + SaveChanges,會對 EF 物化(無參 ctor、Context==null)的列觸發ApplySyncFields→SetUploadValue()而 NullReference;且對「要丟棄的暫存列」蓋上傳稽核欄本就無意義。- 刪除後呼叫
ChangeTracker.Clear()維持追蹤一致性。影響行為
- 轉傳票上傳成功(或取消)後,轉單畫面的暫存清單會清空(
Truncate連帶_observableCollection.Clear())。對批次轉檔屬預期行為。
AddBll.Clear()(新增單據清場)同樣經Truncate(),改 raw SQL 後語意不變(仍是清本機 staging),不再有 EF 蓋章副作用。
Breaking Changes
無。pkid / 主鍵語意、
pkid==0=新列約定、上傳流程皆未更動。Migration Notes
無需 migration。本機 SQLite 由 EnsureCreated 維護;schema 未變。
相關
- ADR 0043 — StagingScope 同表多流程隔離(本次為其後續修正)
- 未採用的替代方案:RowGuid 改當身分鍵(會使新列恆為 pkid=0,衝擊大量
ToDictionary(x=>x.pkid)主從邏輯)、pkid改負號預設(需改全系統pkid<=0=新列約定)。最終取「轉單上傳完即清#turn」這個最小且不動 pkid 語意的解。
-
06-21 sliyturn-asset-accexp-sliy1-detail ▸
2026-06-21 固定資產/費用攤提轉傳票 — sliy1 改放逐筆品號明細
摘要
固定資產折舊(asset)與費用攤提(accexp)轉傳票時,傳票子檔 sliy 維持「彙總分錄」,
sliy1 改為保留「逐筆品號明細」(帶品號/品名),可作品號層級追溯。原本 sliy1 只是
複製彙總後的 sliy(兩張相同、皆無品號)。
變更
- asset/accexp 轉出的 sliy1 現在帶品號(asset=財產編號、accexp=費用編號/費用名稱),
為彙總前的逐筆明細;sliy 不變,仍依科目+部門+輸入地點(accexp 再加客廠)彙總。
- sliy1 明細自動對齊母傳票(linkid)、補功能幣/集團幣金額;空白/借貸皆 0 的列自動略過。
Breaking Changes
無。其餘轉單流程(AP/AR/Payapply/Ftrlima)行為不變,sliy1 仍與 sliy 內容相同。
無資料 migration(staging 每次登入新建;server 端 sliy1 表結構不變)。
Migration Notes
runtime 驗收:轉一筆折舊/攤提,確認 sliy1 帶出品號、sliy 為彙總、傳票可存且借貸平衡、
sliy1 各列總額與 sliy 一致。
已知限制
sliy1 為轉檔當下的原始明細,不反映使用者事後在彙總 grid 的手動改帳;詳見
ADR 0044。
詳見 ADR:
docs/decisions/0044-sliyturn-asset-accexp-sliy1-detail.md -
06-21 recepdt-transfer-parity ▸
2026-06-21 出貨/暫估轉應收帳款 — VFP 對齊修補
摘要
對
recepdt(出貨轉應收)與recepdt_2(暫估轉應收)兩支轉帳表單做 VFP 對比後的行為修補;recepdt_1(應收帳款拆單)確認為未移植缺口、暫不處理。詳見 ADR 0047。新增
- 出貨轉應收:條件面板恢復「帳款別:應收帳款/暫估」選項,可選擇將出貨直接轉為暫估應收(財務類別 17)。
- 出貨轉應收:按「單張轉帳/合併轉帳」前新增前置檢查 — 指定立帳日期模式須先填立帳日期;合併轉帳須至少勾選一種單據別,否則即時提示。
- 暫估轉應收:查詢列新增「全選/不選」兩顆按鈕,可一次勾選/取消所有暫估單。
變更
- 出貨轉應收:合併轉帳時,若某收款客戶該期間只有退貨(SB)而無出貨(SA),整筆改記為銷貨退回(財務類別 21),與舊系統一致(先前固定記為出貨 12/暫估 17)。
- 出貨轉應收:存檔時新增「主檔金額=明細加總」一致性檢查(與付款轉帳一致)。
- 暫估轉應收:發票金額為 0 時,顯示/計算改以暫估本幣金額為基數(先前顯示 0)。
- 暫估轉應收:校正(重算)原幣應收付公式更正為「本幣應收付 ÷ 匯率」(先前誤用稅額);換稅別後的發票金額重算恢復作用。
刪除
- 移除未使用的
Recepdt轉帳.cs(孤兒抽象類別)。
- 出貨轉應收的「無單價/校正」鈕維持不提供(舊系統亦已停用,屬單一客戶專屬)。
Breaking Changes
無。皆為單機程式行為調整,無資料庫結構或預存程序異動。
Migration Notes
recepdt_1(應收帳款拆單視窗)尚未移植:此為把「部分開票仍有餘額」的應收單拆成兩張的獨立工具。若仍有此作業需求,請回報以排程移植(需新增程式代號、DARB_TUR_RECEPDT_1登錄、畫面與拆單邏輯)。
- 本次變更 runtime 尚未實測,建議驗收:合併轉帳純退貨群組的科目別與金額、暫估轉帳校正與換稅別、暫估轉帳全選/不選、出貨轉暫估整條路徑。
-
06-21 po-signing-key-wizard ▸
採購協同 簽章金鑰 備份/還原向導 UI
日期:2026-06-21
模組:PoCollaboration — L.Communication
摘要
把 ADR 0041「未做」清單中的金鑰備份/還原向導接上 UI。後端金鑰服務(
OrgSigningKeyService,規格 §7.2:產生 RSA-3072 → 匯出密碼 .pfx 備份 → 測試還原 → 匯入不可匯出 CNG 容器)先前已實作並有
單元測試,但無任何畫面呼叫它,使用者無法在系統內操作。本次新增 TsView 模態向導把這層串起來。
新增
PoSigningKeyWizardViewModel(ViewModel/L.Communication/PoCollaboration/):
繼承
ERPProgramContentWindowViewModel,三段功能 —- 狀態檢視:是否已設定/已備份/可出單、金鑰指紋、建立與備份時間、備份位置。
- 產生並備份:統編/公司名(預帶
EnvironmentSetting的CompanyTaxID/CompanyName)、備份密碼+確認、備份位置(
SaveFileDialog)。含密碼強度檢核、兩次密碼一致、同碟警告、已設定時重產二次確認;成功後顯示「救援卡」並可另存 .txt。
- 還原:選 .pfx +備份密碼 →
Restore。PoSigningKeyWizard.xaml/.xaml.cs(TsERP/L.Communication/PoCollaboration/):TsView 版面,
PasswordBox 走
PasswordHelper.BindPassword/BoundPassword,文字走 DisplayMeta 多語系。- 多語系:
Common/Lang/Xaml/PoSigningKeyWizard.json(rootPosignkey,含 Common.csproj Content 登錄)
與
TsERP/Lang/Xaml1/Xaml.json同步補Posignkey。- 入口:設定畫面(
SettingView)新增 「採購協同簽章金鑰」分頁,內含開啟向導的按鈕 →
ChangePasswordAndMyFavoriteViewModel.OpenPoSigningKeyWizardCommand以ShowContentWindow開模態。- 權限限定:分頁
Visibility綁IsCmsaAccount(Context.User.UserId == "cmsa",不分大小寫),非 cmsa 帳號看不到分頁;命令本身另有同樣的後端守門(雙重防護)。
變更
- 金鑰持久化改用憑證庫(修 NTE_NOT_SUPPORTED):原以「把 PKCS#8 私鑰 import-create 進具名 CNG
容器」持久化,在 MS Software KSP 實機回 「不支援要求的操作」(按下產生/還原即失敗;單元測試
原本以
Assert.Inconclusive吞掉,等同從未驗證)。改為把含私鑰的 .pfx 以PersistKeySet(不含Exportable)匯入 CurrentUser\My 憑證庫,達成「持久+不可匯出+可簽章」且免提權;金鑰由憑證 SHA-1 指紋索引。
CngSigningKey改為雙後端(Spike 仍走具名容器產生、正式金鑰走憑證庫);
SigningKeyMetadata.CngContainerName→CertStoreThumbprint。單元測試改為實際 round-trip(產生→簽→刪→還原→再簽驗),現 2 綠 0 略過。
Common/ProgramClass.cs:新增POSIGNKEY。
TsERP/App.xaml:加PoSigningKeyWizardViewModel→PoSigningKeyWizard的 DataTemplate 與兩個 xmlns。
TsERP/SettingView.xaml、ViewModel/Setting/ChangePasswordAndMyFavoriteViewModel.cs:新增 cmsa-only 分頁、
IsCmsaAccount旗標、向導命令。追加:公鑰配對(§7.3,見 ADR 0046)
- 發方匯出公鑰:
PublicKeyCard(JSON 公鑰卡,自洽指紋檢核)+OrgSigningKeyService.ExportMyPublicKeyCard();
向導「公鑰交付」區塊 →「匯出我的公鑰」存
*.pokey.json。- 收方信任清單(SQL):
pocollab_counterparty表 +TWORK_POKEY_QRY/SAVE/DEL(走 DARB_LOG_SYS_EXEC
dispatcher,proc_param 登錄);
CounterpartyKeyStore(LogicBll)做匯入/列出/刪除/ResolvePublicKeyDer。向導「往來對象公鑰(信任清單)」區塊:匯入公鑰卡(強制顯示指紋口頭核對)/ 清單 / 移除。
- 驗章接點:
CounterpartyKeyStore.ResolvePublicKeyDer即InboundProcessor的 resolver,已就緒待正式收件流程接。
- 部署腳本(使用者 SSMS 跑):
.claude/tmp/pocollab-counterparties-deploy.sql(建表+3 SP+proc_param,冪等)。
- 單元測試 +1(公鑰卡自洽 + 公鑰可驗證容器私鑰簽章),signing-key 測試現 3 綠 0 略過。
追加:信任清單改為 L.聯絡傳訊 標準維護程式(POKEYCP,見 ADR 0046)
依使用者裁定,「往來對象公鑰信任清單」從 cmsa 設定分頁的自訂 modal,改成 L.聯絡傳訊 正式選單標準維護程式(瀏覽/新增/修改走平台 Ade):
- 新表
twork_com_counterparty(含平台稽核欄、pkid 非 identity);_sheetno登錄POKEYCP(複製 ACCL);TWORK_POKEY_QRY重指向新表;舊pocollab_counterparty+SAVE/DEL+proc_param 移除。腳本.claude/tmp/pocollab-com-counterparty-deploy.sql(模擬環境已執行驗證)。
- 程式碼:
ProgramClass.POKEYCP、ModelTwork_com_counterpartyModel、SourceTwork_com_counterparty、LocalDbContextDbSet、PokeycpViewModel(IAdd/IOther1=匯入公鑰卡/IOther2=開金鑰向導)、PokeycpSave、Pokeycp.xaml、App.xaml DataTemplate。
- 移除 cmsa 設定分頁入口;向導瘦身(移除信任清單區塊);
CounterpartyKeyStore只剩唯讀供驗章。
- 未做:選單/權限需經系統內建【權限設定/選單維護】登錄
POKEYCP到 L.聯絡傳訊;TsERP XAML 未編譯驗證(須關 ERP 重 build);navigate/upload runtime 未驗。
刪除
無
Breaking Changes
無(純新增)。
Migration Notes
- 金鑰私鑰在本機 CNG 不可匯出(憑證庫),metadata 在
%ProgramData%\TsERP\po-collab\signing-keys.json。
- 公鑰配對需先部署 SQL:跑
.claude/tmp/pocollab-counterparties-deploy.sql(建表/SP 在 csa 庫
darbnogicsa1、proc_param 在 log 庫darbnogilog1——已對照連線設定確認為模擬環境;換別家公司部署時改 DB 名,腳本註解附對照表)。未部署前信任清單留空、匯入會提示尚未部署,不影響金鑰產生/備份/匯出公鑰。
- WebView2 已升至 1.0.3650.58;重建需 VS 2022 MSBuild。
- 仍未做:正式收件匣流程接 resolver、公鑰卡離線真實性(目前靠人工口頭核對指紋)、金鑰輪替舊簽章可驗證性。
-
06-21 delete-approved-inreview-guard ▸
2026-06-21 刪除防呆:已審核/審核中/作廢單據不得刪除
摘要
刪除單據時,若主檔的
已審核欄位處於Y(審核完畢)、G(審核中/進行中)或X(已刪除作廢)狀態,會在跳「確定要刪除嗎?」確認對話框之前就提示「資料已審核或審核中,不得修改或刪除」並中止,不讓使用者按完刪除、按下確定後才被擋。已審核欄位代碼(程式既有定義):Y= 審核完畢(已審核)
G= 進行中(審核中)
X= 已刪除作廢
原本
已審核的狀態檢查只在修改 (Edit) 流程(EditBll.CheckIsApproved),刪除 (Delete) 流程未檢查;本次把同樣的保護補進刪除流程,行為與修改一致。變更
LogicBll/Ade/Basic/DeleteBll.cs
- 新增
IsApprovedOrInReview(out msg)(public):透過ItemsBindingManager.GetMasterFirstItem()取主檔,反射讀SysWorkflowFieldEnum.已審核;值為Y/G/X(大小寫不分)時帶出MessageEnum.DataHasBeenApprovedCannotEditOrDelete並回true。-
BeforeDelete()呼叫IsApprovedOrInReview()作為防線(防止其他直接呼叫DeleteBll.Delete()的路徑漏擋)。ViewModel/Ade/DeleteService.cs
- 在
Delete()跳確認對話框之前先呼叫IsApprovedOrInReview(),命中即顯示訊息並return。TsERP/Lang/Message.json
-
DataHasBeenApprovedCannotEditOrDelete文字調整:- 繁中:
資料已審核,無法修改或刪除→資料已審核或審核中,不得修改或刪除- English:同步改為
The data has been approved or is under review, so it cannot be edited or deleted影響行為
- 對
已審核 = Y/G/X的單據按刪除:還沒跳確認對話框就直接提示「資料已審核或審核中,不得修改或刪除」並中止。
- 此訊息為 Edit/Delete 共用 enum,修改 (Edit) 流程顯示的文字也一併更新為新的措辭(更準確、涵蓋審核中),行為不變。
- 其餘狀態(空白)的刪除行為不變。
- 未新增語系 key,僅調整既有
DataHasBeenApprovedCannotEditOrDelete文字。
Breaking Changes
無。
Migration Notes
無需 migration。
-
06-21 dashboard-export-deck ▸
2026-06-21 主管儀表板新增「匯出簡報」
摘要
主管儀表板(EISDASH)右上工具列新增「📊 匯出簡報」鈕,一鍵把目前畫面的 KPI 數據產成一份自包含 HTML 簡報(單檔、瀏覽器開、可全螢幕投影/分享)。
新增
LogicBll/M.EIS/主管儀表板/儀表板簡報Generator.cs:HTML deck 產生器(儀表板簡報資料DTO +產生HTML)。封面 + KPI 8 卡總覽 + 受訂/出貨趨勢面積圖(手繪 SVG)+ 呆料 Top10 + 逾期客戶清單;← → 翻頁、F 全螢幕、視窗等比縮放(1920×1080 舞台)。
EisdashViewModel.匯出簡報Command:組目前顯示資料 → 產 HTML → 寫ERPIO.TempsReportDirectory\經營儀表板簡報_yyyyMMdd_HHmmss.html→Process.Start用預設瀏覽器開。
變更
TsERP/M.EIS/主管儀表板.xaml:工具列「重新整理」旁加「匯出簡報」鈕。
行為
- 匯出的是當下顯示快照(不重查 DB、不即時連動);要最新數字就重按。
- 用瀏覽器開(非 WebView2 內嵌)——簡報用途要全螢幕/分享,理由見 ADR 0048。
Breaking Changes
無。純新增功能。
Migration Notes
無需 migration。輸出目錄
C:\Temps\Reports由程式自動建立。相關
- ADR 0048 — 匯出簡報採自包含 HTML deck(vs open-slide / .pptx;瀏覽器 vs WebView2)
-
06-21 business-registry-autofill ▸
2026-06-21 客戶/廠商輸入統編自動帶入工商登記資料
摘要
客戶主檔(Cudata)與廠商主檔(Spdata)的「統一編號」欄位,輸入 8 碼統編後可自動向
經濟部商工登記公示資料開放平臺查詢,回填名稱、負責人、公司地點、登記資本額。
新增
- 統編欄旁新增「查工商登記」按鈕,可手動查詢回填。
- 統編輸入完離開欄位(LostFocus)時自動查詢回填。
- 查詢來源:經濟部官方開放資料,先查公司登記、查無再查商業登記(涵蓋獨資/合夥商號),免帳號金鑰。
變更
- 回填規則:API 回傳有的欄位才填,沒有的跳過;欄位空白者直接帶入;
已有值且與登記資料不同者,會集中列出並跳確認視窗,按「是」才覆蓋。
- 僅於新增/修改狀態下才會觸發查詢(瀏覽狀態不會打網路)。
- 登記資本額以「萬」為單位帶入(官方 API 回傳為「元」,回填時自動除以 10000)。
刪除
無。
Breaking Changes
無。原有手動輸入行為不受影響。
Migration Notes
- 無資料庫變更。
- 需可連到
https://data.gcis.nat.gov.tw(官方商工登記開放平臺)。內網若有對外白名單需放行此網域。
- 登記資本額以「萬」為單位儲存;廠商主檔為整數欄位,換算後四捨五入。
-
06-17 prodplan-sim-sku-seekcolumn ▸
2026-06-17 生產計劃查詢 — 模擬插單品號改 SeekColumn
摘要
「生產計劃查詢」→「模擬插單」分頁的品號欄,由純文字輸入改為品號 SeekColumn(查 INVENT),選定品號後自動帶出品名;品名欄改為唯讀。
變更
- 品號欄:
TsGridViewDataColumn→TsSkuSeekGridViewColumn,可下拉/輸入查詢 INVENT 品號,DescriptionBindingPath="品名"選定後自動回寫品名。
- 品名欄:加
ForceReadOnly="True",改為唯讀(由品號 seek 自動帶入,不再手動輸入)。
SimulationOrderPoco實作INotifyPropertyChanged,使 seek 回寫品名時唯讀欄即時刷新顯示。
Breaking Changes
無。模擬訂單仍只存記憶體(what-if,不落 DB),套用邏輯不變。
- 品號欄:
-
06-17 memory-leak-and-allocation-fixes ▸
2026-06-17 記憶體洩漏與配置量修補
摘要
接續 2026-06-10 全專案記憶體稽核,本次針對重新掃描找出的新問題做修補:補齊未釋放的 disposable、修兩處事件處理器洩漏,並降低報表寫檔與生產計劃查詢的尖峰配置量。皆為內部修正,無使用者可見行為變動。
變更
洩漏修復(資源未釋放 / 事件未解除)
Common/Environment/Sql.cs— 中央 SQL 執行層 4 個SqlDataAdapter(判斷表名、Log_LogOn、InputCommand、Log_Sys_Input_Multi)改用using。其中判斷表名在每次同步查詢都會跑。
ViewModel/Reports/FastReportExtension.cs—PDFExport/Excel2007Export改用using(ExportBase建構子訂閱AppDomain.UnhandledException,未釋放會被 root)。
ViewModel/L.Communication/PoCollaboration/ReportPdfExporter.cs— 2 個PDFExport改用using。
ViewModel/Other/TodoList/WorkflowPDFHelper.cs—PDFExport改用using。
ViewModel/Control/Layout/PrintLayout/PrintHelper.cs— Print/Excel 路徑的Report改用using(Preview 路徑所有權轉移給預覽視窗,維持不變)。
LogicBll/E.Order/Darbedittool/DarbedittoolBll.cs— EDI 匯入迴圈內StreamReader改用using,避免每個.txt漏一個檔案 handle 並鎖檔。
TsERP/E.Order/Preord.xaml.cs、TsERP/G.Purchasing/Ppur_sug.xaml.cs—Loaded訂閱 VM 的OnColumnHeaderChanged沒有對應-=,導覽快取的長命 VM 會永久 root 住每個 View,且重新載入時處理器累加。改為「先-=再+=」並於Unloaded解除。
尖峰配置量降低
ViewModel/Reports/FastReportExtension.cs— 報表寫檔由File.WriteAllBytes(path, ms.ToArray())改為ms.Position = 0; ms.CopyTo(fs),避免每次列印/匯出在 LOH 另配一份完整 byte[]。
LogicBll/M.EIS/ProductionPlan/ProductionPlanBll.cs— 生產計劃查詢組 CSV 參數字串由迴圈+=(O(N²))改為string.Join。
Breaking Changes
無。
Migration Notes
無需 migration。純內部修正,無 schema、API 簽章或 UI 行為變動。
備註
下列項目經查證後刻意不改:
- 圖片轉換器
DecodePixelWidth:ResourceImageConverter/FileImageConverter綁的是明細頁單張圖/Logo/按鈕圖示,非逐列 grid 縮圖,固定 decode 寬度會讓全尺寸圖變糊;且ResourceImageConverter已有 256 上限+Freeze。
Model/ReportBll.cs雙份物化:DataSet為區域變數,return 後即可回收,「兩份」僅轉換當下短暫並存。
延後(需 runtime 驗證的獨立後續):瀏覽匯出路徑(
SQLiteForBrowse.GetReportSource+ErpBrowseBaseViewModel.MakeReportSource)單次走訪串流化,以消除匯出當下的短暫 2× 峰值。 -
06-16 report-attached-data-signed-pdf ▸
報表用途含「附加資料」→ 匯出/寄送 PDF 嵌入簽章資料附件
日期:2026-06-16
模組:報表列印(PrintLayout)+ PoCollaboration
摘要
延續採購協同簽章 spike,把「資料簽章後嵌入 PDF」接進通用報表列印流程:報表登錄表
報表用途含「附加資料」的報表,在預覽匯出 PDF與Email 寄送時,會把報表資料來源簽章成信封並以 PDF/A-3
AddEmbeddedFile嵌入 PDF;對方系統可讀回驗章後匯入。新增
- 預覽畫面「匯出PDF」按鈕(
TsFastReportPreview):SaveFileDialog 選位置匯出;
報表用途含「附加資料」時自動產生 PDF/A-3 + 嵌入簽章信封,否則一般 PDF。
- 共用層(
ViewModel/L.Communication/PoCollaboration):
-
ReportPdfExporter:把「已 Prepare 的 Report」匯出 PDF;給信封 bytes 則走 PDF/A-3 + 嵌入。-
ReportAttachmentService:報表用途含「附加資料」→ 讀資料來源 → 簽章成信封 bytes。signerId=統一編號、signerName=公司名稱(取自EnvironmentSetting)。LogicBll/PoCollaboration/Core:
-
ReportDataJson:DataTable→ 穩定 JSON bytes(簽章對象)。-
PoSigner.BuildEnvelopeFromBytes(...):泛化簽章(PO 與報表資料共用)。- 單元測試:
ReportDataAttachmentTests(資料序列化穩定、信封 round-trip、竄改驗證)2 支。
變更
SignatureEnvelope新增signerName(公司名稱)與payloadType(PO/REPORT-DATA)欄位。
IContentWindowService.ReportPreview加選用參數byte[] attachmentEnvelopeJson = null;
WindowService同步;PrintHelper預覽分支預先以ReportAttachmentService簽好信封傳入。EmailPrintHelper.ToPdfByGroup:每群組若需附加資料,改用ReportPdfExporter帶簽章附件匯出。
SliyCarrierPdfWriter改用共用ReportPdfExporter(行為不變)。
ReportPrintSource加需附加資料(報表用途含「附加資料」)。
刪除
無
Breaking Changes
無(既有 172 支測試全綠;
報表用途不含「附加資料」者行為完全不變)Migration Notes
- 無資料庫異動;要啟用某報表的附加資料,把該報表登錄列
報表用途設為含「附加資料」。
- 簽章金鑰目前用 interim 固定容器
TsErp.PoCollab.OrgSigning;正式金鑰產生/備份/配對待規格 §7 向導。
- 預覽/Email 只在「會輸出 PDF 檔」的動作嵌附件;直接列印(送印表機)不產生 PDF 故不嵌。
- 預覽畫面「匯出PDF」按鈕(
-
06-16 prodplan-usage-date-and-sim-message ▸
生產計劃查詢:使用量日期格式/模擬插單提示訊息明確化
日期:2026-06-16
模組:M.EIS 生產計劃查詢 (pd_qry7)
摘要
兩處顯示/提示的小修:「使用量(機種別)」頁的日期欄改顯示
yyyy/MM/dd,以及「模擬插單」按「套用模擬」跳出的籠統「沒資料」訊息拆成兩句可診斷的說明。
變更
- 使用量(機種別)頁「日期」欄改顯示
yyyy/MM/dd:該欄綁定
Twork_eis_vw_productiond4Source.日期(System.DateTime),原本漏設IsStringSource="False",走預設ToString()顯示成2026/6/16 上午 12:00:00。補上後套用
yyyy/MM/dd格式,與生產計畫頁一致。- 模擬插單「套用模擬」訊息明確化:原本兩種失敗都跳同一句
MessageEnum.NoData
(「沒資料」),無法判斷原因。現拆為:
- 尚未查詢(
_lastBll == null)→「請先執行查詢,取得基準資料後才能套用模擬。」- 無可套用訂單(
AppliedCount == 0)→「沒有可套用的模擬訂單。每筆需填寫品號、數量(大於 0)與預訂交期;若剛輸入完,請先按 Enter 或點到其他列讓資料落定再套用。」
新增
無
刪除
無
Breaking Changes
無
Migration Notes
- 無資料庫異動。需重建 TsERP(XAML 改動)與 ViewModel(訊息改動)後生效。
- 模擬插單為記憶體 what-if,須先在條件面板執行「查詢」取得基準快照,才能套用模擬。
- 使用量(機種別)頁「日期」欄改顯示
-
06-16 prodplan-sim-reduction-and-ui ▸
生產計劃查詢:模擬減單 + 結果頁與條件面板版型調整
日期:2026-06-16
模組:M.EIS 生產計劃查詢 (pd_qry7)
摘要
模擬功能由「只能插單」擴充為可加單也可減單(數量填負數=抵減既有需求),
並做了一批結果頁與條件面板的版型/可讀性調整。
新增
- 模擬減單:模擬訂單「數量」可填負數,代表減少既有需求(釋放庫存)。
缺口與金流會反映加單/減單的淨效果。詳見 ADR 0040。
- 金流預測圖表 Y 軸縮放:圖表加
ChartPanAndZoomBehavior
(
ZoomMode/PanMode=Vertical),滑鼠滾輪可放大垂直軸、拖曳上下平移;橫軸年月不縮放。變更
- 「樞紐分析」頁移到最後一頁(原在「原物料用量」與「金流預測」之間)。
- 「庫存缺口」頁更名為「原物料用量」(含條件面板步驟③說明文字同步更新);
內部 grid 名稱與 VM 屬性不變。
- 金流明細收/付配色:
dg金流明細依「收付」上色——收(進帳)淡綠、付(出帳)淡紅。
- 模擬「數量」欄標題改為「數量(負=減單)」;「套用模擬」失敗訊息補上
「正數=插單、負數=減單抵減既有需求」說明。
- 條件面板版型:步驟①/成本匯率/步驟② 改為三欄並排(成本匯率獨立中欄);
「金流預測」GroupBox 內「帳款立帳起日」「資金警戒線」改為兩排水平並列。
刪除
無
Breaking Changes
無(既有「只插單」用法完全相容,正數行為不變)
Migration Notes
- 無資料庫異動。需重建 LogicBll / ViewModel / TsERP 後生效。
- 模擬為記憶體 what-if,須先在條件面板執行「查詢」取得基準快照,才能套用模擬。
- 受影響邏輯:
RunSimulation閘門放寬為數量 != 0、CashFlowComposer
計劃預測收移除
Math.Abs保留正負號、ShortageCalculator缺口量僅對正需求計算。 -
06-16 prodplan-query-cashflow-fixes ▸
生產計劃查詢:缺口品號彙總/金流來源過濾/到期日防呆
日期:2026-06-16
模組:M.EIS 生產計劃查詢 (pd_qry7)、共用控件 TsRadGridView、共用 PayTermDate
摘要
延續 2026-06-11 的缺口/金流/模擬功能,補強顯示與健全度:庫存缺口新增品號彙總
master-detail、金流預測新增來源過濾並修正 Y 軸格式,並修掉一個會讓整支查詢崩潰的
到期日計算缺陷與無日期資料污染圖表的問題。
新增
- 庫存缺口-品號彙總表:缺口頁上半新增「品號彙總」(master),依層級+品號彙總
需求數量合計/缺口量合計/缺口筆數/最早短缺日;選一列下方明細只顯示該品號需求列,
上方「顯示全部」按鈕清除選取回顯全部。缺口品號(缺口量>0)優先排序、紅底標示
- 金流預測-來源過濾:頁頂新增「基礎(票據/帳款)」「推估(在途採購/計劃預測)」兩個
勾選(預設全開),即時重算圖表(基準柱/模擬柱/累計淨額折線)與明細
- TsRadGridView.ClearFilterOnItemsSourceChanged(共用控件,opt-in,預設 false):
設 True 時重新查詢(ItemsSource 換新集合)會自動清掉殘留的欄位篩選;排序/群組不受影響。
本頁各查詢結果表已啟用
變更
- 生產計畫頁「日期」欄改顯示
yyyy/MM/dd:該欄為 DateTime 來源,補上
IsStringSource="False"套用格式(原本以預設 ToString 顯示)- 金流預測 Y 軸格式修正:
LabelFormat由{}{0:N0}改為N0
(Telerik 軸吃純 .NET 格式字串,組合格式會失效導致無千分位)
- 金流預測排除無有效日期項目:來源單據缺交期/需求日期造成的
0001/01/01(MinValue)
不再進金流明細與圖表;排除筆數以警告提示(不靜默)
修正
- PayTermDate.DateAdd 年份補零(共用,影響全 ERP 到期日計算):年份未補零,
年份<1000(如 MinValue
0001/01/01)會產出1/02/01,下一輪Left(4)取到1/02→
int.Parse例外。改用ToString("D4"),對正常年份(≥1000)為 no-op。此缺陷會經金流預測 →
CashFlowComposer→ResolveDueDate直接讓整支查詢崩潰- ResolveDueDate 防護網:到期日推算失敗不再中斷查詢,改回空字串讓
CashFlowComposer退回基準日,並以收付條件去重記一次警告供追根- 使用量(d4) 金額 Context NullReference:
Twork_eis_vw_productiond4Source的 ctor
收了
IAppContext卻沒呼叫SetContext,Context恆為 null,金額getter 取Context.Env.LocalDecimal必拋 NullReference。改為:ctor 無參化;金額改成建檔時於GetUsageBom(Context 可用處)算好存入的儲存屬性(本位幣小數位數四捨五入語意不變)刪除
無
Breaking Changes
無
Migration Notes
- 無資料庫異動。
ClearFilterOnItemsSourceChanged為 opt-in,其他查詢畫面如需「重查清篩選」
在 XAML 加
ClearFilterOnItemsSourceChanged="True"即可- 若金流預測出現「已排除 N 筆無有效日期」警告,代表來源單據(多為訂單預訂交期)缺日期,
該補齊來源單據日期後重查
-
06-16 po-collaboration-signature-spike ▸
採購協同 簽章版 MVP:第 0 步 Spike(傳票載體)
日期:2026-06-16
模組:PoCollaboration(新)— L.Communication
摘要
依《採購協同_簽章版MVP_規格書》§10 先做 Spike,驗證「簽章 → 嵌入傳票 PDF/A-3 → 讀回 → 驗章」
端到端可行。因目前無採購單報表,先用既有傳票(Sliy)報表當人看的載體(規格 §8.2:簽的是 payload
bytes 不是 PDF,載體換誰對驗章零影響)。詳見 ADR 0041。
新增
- PoCollaboration 核心(純邏輯,
LogicBll/PoCollaboration/):
-
Core/PoPayload、CanonicalJson(穩定 UTF-8 bytes,規格 §8.3)、SignatureEnvelope(信封 §5.3)、PoSigner(RSA-3072 / SHA-256 / PKCS1 簽驗 §8)、EmbeddedFileReader(PdfPig 讀回嵌入附件)。-
Keys/CngSigningKey(RSA-3072 CNG,不可匯出;MachineKey 優先、無權退回 CurrentUser)。-
Receiving/IInboundProcessor+InboundProcessor(解耦可獨立呼叫的「讀附件→驗章」服務,規格 §4)。- 載體與 Spike(
ViewModel/L.Communication/PoCollaboration/):
-
SliyCarrierPdfWriter:用傳票報表匯出 PDF/A-3 並AddEmbeddedFile嵌入po-data.json。-
IPoSpikeService/PoSpikeService:串接 sign→embed→read→verify,含竄改/錯誤公鑰負向測試。- 暫時開發觸發:MainWindow 熱鍵 Ctrl+Alt+P → 跑 Spike,結果寫桌面
PoCollabSpike\並訊息框顯示。
- 單元測試:
LogicBllTests/PoCollaboration/PoSignerTests(canonical 穩定、簽驗、竄改、錯誤公鑰、
缺簽章、CNG round-trip)共 6 支,全綠。
- 相依:
PdfPig 0.1.9(LogicBll)。
變更
TsERP/DIExtension.cs:註冊IInboundProcessor、IPoSpikeService。
TsERP/MainWindow.xaml、MainWindowViewModel、ErpSystemContainerViewModel:加暫時 Spike 觸發。
刪除
無
Breaking Changes
無(純新增;既有 170 支單元測試全綠)
Migration Notes
- 無資料庫異動(Spike 用記憶體/檔案)。重建需 VS 2022 MSBuild。
- 如何驗收兩大風險(規格 §10):執行 ERP → 登入並開啟任一程式 → 按 Ctrl+Alt+P →
看桌面
PoCollabSpike\的 PDF(用 Acrobat/Edge 確認可開)與spike-result.txt。任一風險不可行 → 依 §10 停下回報,評估 sidecar / PDFsharp / iText。
- 明確未做(下一階段):加密(§2.2 禁止)、金鑰備份/配對向導、IMAP/SMTP、狀態機、正式 UI、正式 SQL 表。
- PoCollaboration 核心(純邏輯,
-
06-16 directsavetosqlite-audit-fields ▸
2026-06-16 修正轉單/批次上傳的稽核欄位(輸入人員等)未寫入
摘要
修正
ItemsBindingManager.DirectSaveToSqlite上傳時漏蓋稽核欄位的問題。最明顯的症狀:進貨轉應付(paypdt)存檔後,資料庫的「輸入人員」欄變成廠商名稱,而非實際登入者。
變更
DirectSaveToSqlite在把資料寫進本機 SQLite 前,補呼叫SourceBase.SetUploadValue(),
與 EF 追蹤路徑(
LocalDbContext.ApplySyncFields在SaveChanges時的行為)對稱。- 受影響的稽核欄位會正確設定為「當下這次上傳」的值:
-
輸入人員= 登入者、輸入日期= 現在、輸入地點= 機器名、logid、選擇清空。-
建檔人員/建檔日期:只有原本為空才補(Edit 不會蓋掉原始建檔資訊)。影響範圍
所有走
DirectSaveToSqlite的功能一併修正:全部轉單(進貨/暫估轉應付、零用金轉入、票據異動、轉傳票家族、付款轉沖帳…)以及附件、結帳、改密碼、使用者設定、表格版型存檔、AutoPilot 匯率等。
這些情境語意都是「當下登入者執行上傳」,蓋成登入者為正確行為,也與舊
AdeUploadBll路徑一致。背景(為什麼 paypdt 會變廠商名)
轉帳查詢刻意借用「輸入人員」欄帶廠商簡稱做預覽顯示(沿襲 VFP
paypdt.prg:c.廠商簡稱 AS 輸入人員;費用路徑輸入人員 = 客廠名稱)。舊上傳路徑會在送出前用SetUploadValue蓋回登入者;遷移到ItemsBindingManager後,DirectSaveToSqlite走UpsertBatch直寫 SQLite、略過 EF 與該蓋值動作,導致廠商名直接存進 DB(並使存檔後以「輸入人員 = 登入者」撈剛存單號的訊息撈不到)。
Migration Notes
無資料庫結構變更。已存在、輸入人員被誤存成廠商名的歷史單據不會自動修正,必要時需另行更新。
待驗證
實機存一張 paypdt 進貨費用單,確認 DB
輸入人員= 登入者、存檔後起訖單號訊息正常。 -
06-15 prodplan-sp-failure-surfaced ▸
2026-06-15 生產計劃查詢:SP 失敗不再靜默回空
摘要
生產計劃查詢(pd_qry7)的「庫存缺口」「金流預測」tab 依賴擴充 SP(
TWORK_QRY_PRODPLAN_SUPPLY/TWORK_QRY_PRODPLAN_CASHBASE)。先前若 SP 未部署或proc_param未登錄,ProductionPlanBll會在BuildShortage()/BuildCashFlow()直接return,結果靜默回空,使用者執行後看到對應 tab 空白卻沒有任何提示,無法判斷是「資料面沒料」還是「SP 沒裝」。變更
ProductionPlanBll新增Warnings清單。三個原本靜默return的點(Handle()基礎資料、BuildShortage()供給、BuildCashFlow()金流)SP 失敗時改寫入帶有 SP 名稱與部署腳本路徑的警告訊息,其餘結果照常顯示。
ProductionplanViewModel.Query()查詢完若有Warnings以提示框一次列出。
- 修正
ProductionplanViewModel.Query()失敗分支的 bug:原本Context.MessageService.GetMessage(MessageEnum.SystemError)只取回字串就丟棄、不跳框,改為TsMsgBox.ShowExclamationMessage(...)。
測試
新增
LogicBllTests/M.EIS/ProductionPlan/ProductionPlanBllTests.cs(9 個測試):BuildDemands:成品/材料合併、層級與欄位對應、數量 0 略過、模擬旗標傳遞。
GetUsageBom:有 BOM 展開用量、品號無 BOM → 使用量為空(記錄此口徑,避免日後誤判為 bug)、多組件各自展開。
ProductionPlan 測試資料夾共 26 個測試全通過。
Breaking Changes
無。
Migration Notes
此變更只負責「把錯誤顯示出來」,不會自動修復空白資料。若「庫存缺口/金流預測」實際為空,仍需在 DB 執行
sql/TWORK_QRY_PRODPLAN_EXT_darbnogicsa1.sql(建立兩支 SP + 登錄proc_param,檔尾含登錄段)。「使用量」為空通常是該計畫品號無 BOM 展開,屬資料面。 -
06-15 prodplan-condition-horizontal-pivot-drilldown ▸
生產計劃查詢:條件面板水平化+樞紐分析雙擊看明細
日期:2026-06-15
模組:M.EIS 生產計劃查詢 (pd_qry7)
摘要
條件面板從縱向堆疊改為水平版面以壓低高度;樞紐分析頁籤新增雙擊彙總格
drill-down 顯示背後訂單明細的功能。
新增
- 樞紐分析 drill-down:在「樞紐分析」頁籤雙擊任一彙總格 → 彈出唯讀明細視窗,
顯示該格(客戶×品號 對 年×月)背後的原始訂單明細(欄位沿用第一頁訂單頁全套)。
雙擊在表頭/空白/無對應彙總格會安全略過。
變更
- 條件面板版面水平化:步驟①(查詢條件+成本匯率)移到左欄、步驟②(客戶設定 grid)
移到右欄並佔滿剩餘寬度與高度、步驟③說明橫跨底部。面板因此變寬變矮、客戶設定 grid
配合可用高度自動拉伸(原為縱向堆疊、整體偏高)。
刪除
無
Breaking Changes
無(第一頁訂單排序維持原本 訂單→預示→預估 分區塊的後端 SQL 順序,未更動)
Migration Notes
- 無資料庫異動;純前端版面與互動調整。
- 修正一處 cross-thread:樞紐
LocalDataSourceProvider餵 ItemsSource 與
GetUnderlyingDataCompleted皆於背景緒觸發,已 marshal 回 UI 緒(DispatcherObject執行緒親和)。
-
06-12 stale-english-cleanup-batch1 ▸
2026-06-12 英文殘留屬性中文化清理(批次 1)
摘要
DB schema 已全面中文化,但 E.Order / J.QC / P.Invoice / H.Inventory 多支 Source/Model 仍殘留英文
[TsColumnName]屬性(DB 已無該欄 → 載入永遠空白、儲存靜默遺失)。本批以 DB view 實際欄名為準,將殘留英文屬性改名為中文、砍掉 DB 已廢除的欄位屬性,並連動修正 C# caller 與 XAML binding。
另對 sample / visit / repair 三支做 VFP 深度對比,缺驗證/預設值直接補修。
F.Production 的 wkpaper 家族不在本批(另案);C.GeneralAffair 由另一 agent 作業。
變更
Twork_ord_vw_samplema(送樣聯絡單 主檔)
英文(舊) 中文(新) DocumentNo 送樣編號 CustomerCode 客戶代號 CustomerName 客戶簡稱 SalesRepCode 業務員編號 Applicant 申請人 DocumentDate 開立日期 NotesID 聯絡單id WorkflowCode 工作流程 Auditor 審核人員 AuditDate 審核日期 IsApproved 已審核 - 砍除:
CreatedDate(DB 無 建檔日期 欄)、SysEntryDate/SysEntryUser/SysEntryMachine/SysRowStatus/SysIsChosen/SysControlCode(改繼承 ModelBase 中文欄)
- 砍除 NotMapped
SalesRepName→ 改用 view JOIN 欄姓名(vwseek_salesmen)
- 補真缺欄:
流程樣板號、姓名(DB 有、原本無任何對應屬性)
- 保留 NotMapped
ApplicantName(view 無對應欄)、CustomerCodeBinding
Twork_ord_vw_samplede(送樣明細)
英文(舊) 中文(新) LineNo_ 序號 Material 材質 Type 型別 Spec 規格 Processing 加工 LocalDescription 中文描述 ImageNo 圖號 ETA 指定納期 CompletionDate 完成日期 Quantity 數量 Acknowledgment 承認書 Portion 份數 IsSample 是否打樣 ShippedQuantity 已交數量 IsClosed 是否結案 Notes 備註 (Model) SKU / SKUDescription / UnitOfMeasurement 品號 / 品名 / 單位 - 砍除 Sys* 6 欄;字串長度/小數位對齊 DB(材質 4、規格 20、數量 16,4 等)
Twork_ord_vw_visit(拜訪單)
- 改名:
CompanyCode→公司代碼、SalesRepCode→業務員編號、SalesRepCodeBinding→業務員編號Binding
- 砍除:
NotesID/WorkflowCode/Auditor/AuditDate/IsApproved/CreatedDate(visit 表與 vw_visit 均無此欄,DB 已廢除)+ Sys* 6 欄
- 砍除 NotMapped
受訪名稱/SalesRepName/業部門名稱→ 改用 view JOIN 欄客戶簡稱/客戶名稱/姓名/部門簡稱(補 4 個 mapped 欄)
RefreshDescription()、GetContent()同步改用中文欄
Twork_jqc_vw_repair(叫修單)
- 改名:
CompanyCode→公司代碼、CustomerCode→客戶代號、SKU→品號
- 砍除:
NotesID/WorkflowCode/Auditor/AuditDate/IsApproved/CreatedDate(DB 已廢除)+ Sys* 6 欄
- 砍除 NotMapped
CustomerName/SKUDescription→ 改用 view JOIN 欄客戶簡稱/品名(補 mapped 欄)
- 保留 NotMapped
服務人員姓名/購買日期(view 無對應欄)
Twork_jqc_vw_purama(暫收單 主檔)
英文(舊) 中文(新) TempReceivingDocumentNo 暫收單號 DocumentPrefix 序號前置碼 PurchasingType 採購別 CompanyCode 公司代碼 WarehouseCode 倉儲代號 TempReceivingDate 暫收日期 ProductionDepartmentCode 生產部門 Currency 幣別 QCOver 檢驗完畢 Remark 暫收備註 MaterialUsageTransactionNo 耗料單號 CreatedDate 建檔日期(型別 string→DateTime,對齊 DB datetime) NotesID 聯絡單id WorkflowCode 工作流程 ProductionDepartmentName 客廠部簡稱(view JOIN cusp) - 砍除(DB 已廢除,22 個):
Auditor/AuditDate/IsApproved、TempReceivingType/VendorCode/VendorName/Trno/InvoiceNo/ShipViaCode/VesselBookingNo/BillOfLadingNo/DeclarationNo/DeclarationDate/CBM/WGT/ETD/ETA/LoadingPort/ETAInWarehouse/PDFFile/TurnInNote/TurnOutNote/ContainerNo+ Sys* 6 欄
- 保留 NotMapped
WarehouseName
Twork_jqc_vw_purade(暫收明細)
⚠️ 此檔同概念新舊兩套英文並存(如 InspectionDate/InspDate),以 DB 中文欄為準收斂成一個中文屬性:
中文(DB 欄) 收斂自(兩套英文) 序號 LineNo_ 庫存管制 InventoryControl 廠商品號 VendorSKU 數量 / 單價 / 幣別 Quantity / UnitPrice / Currency 金額 CurrencyAmountWithoutTax(砍 CurrencyAmount、Amount) 預訂交期 ETA(砍 ETD) 備註 Remark 檢驗日期 InspectionDate(砍 InspDate) 檢驗人員 InspectionStaff(砍 InspStaff) 須否成績表 NeedGrade(砍 IsRpt) 入庫日期 WarehouseInDate(砍 InstkDate) 檢驗別 InspectionType(砍 InspType;DB tinyint 與 byte 型別吻合) 包裝材料 PackagingMaterial(砍 Pkmat) 包裝量_包 / 包裝量_箱 MinimumPackageQuantity / QuantityPerCarton(砍 BagQuantity / CtnQuantity) 儲位 Bin(砍 Site) 成績表扣分 IsGradeMinus(砍 RptMinus;DB char(1) 與 string 吻合) ng數量 / 特採數量 / 入庫數量 NGQuantity / AcceptOnDivisionQuantity / WarehouseInQuantity(砍 SpeadmQuantity / InstkQuantity) 問題點 / 確認 / 抽檢數量 / 檢驗結果 Question / Confirmed / SampleQuantity / InspectionResult(砍 Cinfirmed / SampQuantity / InspResult) 是否結案 / 品質管制日 / 管制批數 / 暫收批數 / 合格 IsClosed / QualityControlDate / ControlLotNum / TempReceivingLotNum / IsAcceptable ng退貨量 / ng退貨日 NGReturnQuantity / NGReturnDate 採購單pkid / 製通單pkid / 派工單pkid / 生產單pkid PurchaseOrderLinePkid / ProductionOrderPkid / WorkOrderPkid / WorkDailyReportPkid 停用說明 / 管制說明(view JOIN) IsDisabled / InventoryControlDescription 派工單號 / 生產單號 / 採購單號 / 合格批數(view JOIN) WorkOrderNo / DailyWorkDocumentNo / PurchaseOrderNo / AcceptableCount - 另砍:
ContNo/ContSize/Instk01~10/InstkQuantity01~10/OtherCost(DB 無)+ Sys* 6 欄
單價精度修正為 DB 實際 (16,6)
Twork_inv_vw_tickadisc_m(折讓單 主檔)
- 砍除英文舊屬性(中文欄屬性先前已補好):
FinancialCategory(→財務類別)、NotesID(→聯絡單id)、WorkflowCode(→工作流程)、Auditor(→審核人員)、AuditDate(→審核日期)、IsApproved(→已審核)、CreatedDate(DB 無)+ Sys* 6 欄
客廠部代號Binding內FinancialCategory == "22"改財務類別 == "22";Model 建構子重複初始化清理
Twork_stk_vw_trrafee(費用明細)
- 砍除:
CustVendDeptName(→客廠部簡稱)、AccountDescription(→科目名稱)(中文 view 欄已存在,無 C# caller,僅 Trrama.xaml 兩欄 binding 改中文)
檔名修正
Model/Source/N.GeneralLedger/Twork_acc_vw_budgetSoruce.cs→Twork_acc_vw_budgetSource.cs(git mv,class 名原本就正確,僅檔名 typo)
Caller 連動修正
C#(23 檔)
- E.Order:SampleViewModel(新增預設 開立日期/申請人)、SampleSave、Sample1Bll、Sample1Source(SP 回傳欄 修改人員/送樣編號/客戶代號/客戶簡稱/開立日期 改中文,修復原本對不上的 mapping)、VisitSave、Visit_weekly/daily/customer/mileage ViewModel(查詢 SQL 原用英文欄名打中文 DB,runtime 必錯,全改 業務員編號/姓名;mileage 加欄位別名對應報表 Poco)
- J.QC:RepairViewModel、RepairSave、Purama/Twrama/Wkrama ViewModel(建檔日期 改 DateTime.Now、列印改用 生產部門)、Purama/Twrama/Wkrama Save、Purama_E/Twrama_E/Wkrama_E Bll(轉單組裝全改中文欄;移除寫入已廢除欄 VendorCode/TurnInNote/ContainerNo/ETA/CurrencyAmount/Amount)
- H.Inventory:TptoraBll(轉單條件改 生產部門/倉儲代號/檢驗完畢/數量/入庫數量;移除 ContainerNo 過濾——DB 已無此欄)、TptowkBll、TptowkViewModel
- P.Invoice:Ticka_discViewModel(FinancialCategory="22" → 財務類別)
XAML(10 檔)
Sample、Sample1、Visit、Visit_q(僅 visitSource 綁定的 tab,週報/里程 Poco 欄不動)、Repair、Purama、Twrama、Wkrama、Ticka_disc、Trrama。
Purama/Twrama/Wkrama 並移除已廢除欄位的整組 label+輸入框(InvoiceNo、TurnInNote、TurnOutNote、ETD、ETA、ETAInWarehouse、DeclarationNo/Date)與明細 ETD 欄。
刪除
- 已廢除 DB 欄對應之輸入欄位:暫收單 master 區的 Invoice No / Turn In Note / Turn Out Note / ETD / ETA / ETA In Warehouse / Declaration No / Declaration Date(DB purama 已無這些欄,原本輸入也存不進去)
- Tptora 轉暫收的「櫃號過濾」條件(DB 無 ContainerNo 欄,原查詢必噴 SQL 錯誤)
VFP 對比結果(sample / visit / repair)
🔴 已修:
1. sample —
客戶代號.Valid一律強制帶出 客戶簡稱(2014/04/03 鈞寶要求):CustomerCodeBinding 補客戶簡稱 = GetCustomerName(...)(原本寫進 stale 英文欄等於沒存)2. sample — 新增預設寫入不存在的 CreatedDate → 改寫
開立日期3. sample — allowsave「客戶代號或客戶簡稱擇一」→ SampleSave 對齊(原本只檢查代號)
4. visit — 新增時未帶
公司代碼、儲存未檢查公司代碼=0→ AfterAddNew 預設 1 + VisitSave 補檢查5. visit — 四支查詢 SQL 英文欄名(SalesRepCode/SalesRepName)打中文 view → 全改中文(原 runtime 必錯)
6. repair — 儲存未檢查
公司代碼=0且表單無輸入欄 → AfterAddNew 預設 1 + RepairSave 補檢查🟡 未修(列出待辦):
1. sample — 明細列
完成日期非空時該列唯讀(VFP grid1.AfterRowColChange)未移植2. sample — SAMPLE1 批次完成後跳轉至該筆(VFP else1click MOVEREC)未移植,現僅 Renew
3. visit — addagain 依公司別(禾久/台賓/可俐明)以登入者姓名反查業務員編號帶入之特例未移植
4. visit — 瀏覽 SEEK 可輸入「客戶簡稱?」模糊查詢(SEEK1.InteractiveChange)未移植
5. repair — VFP 公司代碼可輸入(新版表單無該欄位,固定帶 1);多公司環境需補輸入欄
Breaking Changes
- 本批 Source/Model 屬性名全面改中文:外部若有以反射/字串引用舊英文屬性名(含
.frx以外的自訂報表、AutoPilot 腳本)需同步改名。
Twork_jqc_vw_purama.建檔日期型別由string改為DateTime。
- 已廢除欄屬性(purama 航運欄、purade 重複英文欄、各表 Sys*/CreatedDate)直接刪除,無相容別名。
Migration Notes
- 不需 DB migration(DB 本來就是中文 schema,本批是 code 端追平)。
- 本機 SQLite staging 表為每次查詢重建,無需手動清理。
- Runtime 未驗:sample / visit / repair / purama / twrama / wkrama / ticka_disc / trrama 開窗、新增、儲存、轉單與四支 visit 查詢報表需人工驗收。
- 砍除:
-
06-12 scx_stk-ticka-trxama-fixes ▸
2026-06-12 — scx_stk 對比修補(ticka / trinout / trlima / trrama / trsama)
摘要
VFP
scx_stk五支單據(銷貨發票 H-100、出入庫申請 H-070、出入庫單 H-040、進貨單 H-010、出貨單 H-050)與新版深度對比後的修補。最大宗問題為 2025-12-10 Source 英→中屬性改名(commit e37e2809)後,H.Inventory 四支 XAML 完全沒跟著改,主檔/明細/費用欄位 binding 全數失效(開窗欄位空白、輸入不回寫)。本次以改名 commit 的對應表逐欄修復共 218 處 binding,另補回 4 項 VFP 驗證、1 項編輯防呆、1 個金額公式 bug、1 個代碼表別名錯誤。
變更
XAML stale binding 全面修復(使用者可見:欄位從空白恢復顯示/可輸入)
檔案 修復數 範圍 TsERP/H.Inventory/Trrama.xaml90 行 主檔(倉單號/單號/隸屬倉庫/廠商/幣別/匯率/發票/稅別/報單/提單/分攤費用/應收付…)、明細 grid 全欄、費用 grid 全欄 TsERP/H.Inventory/Trsama.xaml57 行 主檔(倉單號/單號/客戶/集團/業務員/發票/稅別/帳款期別/實際出貨日/應收付…)、明細 grid 主要欄位 TsERP/H.Inventory/Trlima.xaml49 行 主檔(倉單號/單號/交易部門/快遞號碼/程式註記/關聯單號/發票/稅別…)、明細 grid(含例外出入/不良/處理方式代碼欄) TsERP/H.Inventory/Trinout.xaml22 行 主檔(申請單號/申請日期/申請人員/申請部門/廠商/隸屬倉庫/申請原因…)、明細 grid(品號/申請量/單價/核發量/轉入倉儲…) 修法:英文 path → 現行 Source 中文屬性(依 e37e2809 改名對應表+現行 Source 屬性集逐欄核對),
Binding後綴的代理屬性對應到xxxBinding中文版(如SKUBinding→品號Binding、QuantityBinding→數量Binding/申請量Binding、PaymentTerm→收付條件號Binding(trrama))。Ticka.xaml(P.Invoice)逐欄核對結果全數正確,無需修改。驗證 / 防呆補齊(對齊 VFP)
LogicBll/Ade/P.Invoice/TickaSave.cs
- 補:課稅別=
4.作廢時,作廢日期、作廢原因必填(VFP allowsave)。- 補:存檔時幣別空白 → 預設本位幣+匯率 1(VFP changeopmode,與全系統新增預設一致)。
LogicBll/Ade/H.Inventory/TrinoutSave.cs
- 補:申請日期必填、申請部門必填、申請部門不得與隸屬倉庫相同(VFP allowsave 三條漏移植驗證)。
LogicBll/Ade/H.Inventory/TrlimaSave.cs
- 補:EO 單必須輸入維修人員(VFP allowsave)。
- 補:EI 例外出入碼=99(虛擬進貨)單價=0 不得存檔;存檔時自動補
交易別碼='OC'、單位成本=單價、其他資料2='自填成本',並先清除舊「自填成本」註記(VFP 2019/01/16 虛擬進貨邏輯)。LogicBll/Ade/H.Inventory/TrsamaEdit.cs
- 恢復被註解掉的 「已轉發票(發票號碼非空白)不得修改/刪除」 防呆(VFP allowedit;DeleteBll 同走此檢查)。
Bug 修正
LogicBll/H.Inventory/TrramaBll.cs(費用分攤 SetCostAmount)
- 原幣含稅公式錯誤:原寫成
ROUND(單價*(100+稅率)/100)(即含稅單價),漏乘數量、漏加其他金額。改為 VFP 公式ROUND(數量*含稅單價+其他金額, 幣別小數位數)。多數量明細的原幣含稅/本幣含稅原本嚴重失真。TsERP/H.Inventory/Trlima.xaml
- 明細「不良原因碼」下拉代碼表
TableAlias由 C219 改為 C246(VFP 用 cmb_246 報廢不良原因;C218/C220/C221/C245 其餘各欄核對正確)。未修(🟡 列出,含刻意不修)
- trinout:VFP allowsave 的倉儲代號連動驗證/自動補值鏈(依 LCL交易事項表/LCL交易別 的轉入/轉出部門 W/T × 倉同儲 Y/N 決定 轉入倉儲/轉出倉儲 與倉儲代號歸屬檢查)整段未移植——邏輯量大且依賴本地 LCL 表,需 runtime 驗證後另案補。
- trinout XAML Prime 殘留死欄:ApplyType/CUSTCATG/IsFree/Contact/Email/Fax/ShipTo 地址區塊/Attention/Instruction/To Warehouse(
Warehouse)/FreeSample/Pending/Restocked/Billed——Source 無對應屬性(部分疑為 特殊要求/詢比議記錄 的前身,對應不確定,不猜)。
- trsama XAML 死欄:DocumentCategory(進銷分類)/ProjectCode(專案代號)/ShipToAddress/PickDate/PackDate/TrlimaPkid/SKU1/Quantity1·2/UOM1·2/Density/StartPoint/EndPoint/聯單號碼/Remark/DiscountPercentage——屬性已在孤兒清理時刪除或為 trsama_房售 變體殘留。
- trrama XAML:
CompletedAllocation(分攤完成)全 codebase 已無屬性(Gtrrama 同樣殘留),死欄不動。
- VFP 按鈕差異(多為刻意重設計):
- ticka:else3「更新資料」(_CHANGENO 泛用工具) 未移植;批量匯出已對應
ExtendedFunction3→Ticka_export並非缺漏。- trrama/trinout:工作流程/快速審核 → 新版集中式 workflow(已知等價);trrama 特殊修改走框架 SpecialEdit。
- trsama:VFP 批次審核/批次改價/轉訂單/拆單/客戶標籤/借出出貨 vs 新版 訂單轉出貨/Picking/Packshipdate/PickingReport/Ratosa——按鈕集合重新設計,未逐一對應;trinout else3「轉入」(TRINOUT2) 未移植。
- trlima:CMDELSE2~6 在 VFP 即 Visible=.F.,不比;特殊修改走框架。
- ticka:VFP「發票日期必須是今日或本月最後一天」未移植——新版改為允許 發票月份/次月(雙月期別),視為刻意放寬。
- ticka 明細刪除條件:VFP 砍「品號與品名皆空」列,新版只看品號(影響極小)。
- trinout AfterAddNew:隸屬倉庫未帶
U_PRGPAR(7009)預設;公司代碼=1 寫死(與 trlima/trrama/trsama 一致的單公司慣例,不動)。
- trlima:IT 類「調撥金額合計必須=0」檢查為刻意註解(禾久品名調撥可輸單價);新版以分攤群組數量平衡檢查替代。
Breaking Changes
無資料格式變動。出貨單(trsama)已轉發票者將恢復「不得修改/刪除」防呆——此為 VFP 原有行為的回復,需修改時請走特殊修改(不受此限制)。
Migration Notes
無需 migration。XAML/ViewModel 變更需在 Visual Studio 內建置驗證(dotnet CLI 會撞既有 MSB4803,與本次改動無關);runtime 驗收重點:四支 H.Inventory 表單開窗欄位顯示、trrama 多數量明細含稅金額、trsama 已轉發票單據的編輯阻擋。
-
06-12 scx_stk-inv-splace-trlost-fixes ▸
2026-06-12 — scx_stk 對比修補:invbk1 / invrec / invstk / splace / trlost
摘要
VFP 舊版
scx_stk五支表單與新版 TsERP 深度對比(接續 commit9b69004d被中斷的前手批次):- invrec(盤點單 H-080)/splace(倉庫表 H-090):驗證前手修補,確認已完整,本批無新增修改。
- invbk1(交易進出查詢 H-060)/invstk(庫存明細表 H-120)/trlost(耗料單 H-020,含 Trlost_A 發送料):本批新對比並修補。
主要問題型態:2025-10 英→中 schema 改名後殘留的 stale XAML binding(欄位永遠空白)、BLL 查詢 SQL 用到已不存在的英文欄名(runtime 必炸)、查詢條件沒傳給 SP、計算欄串接半成品。
變更
invbk1(交易進出查詢)
Invbk1ViewModel:Bll 改以new Invbk1Bll(context)建構(原無參建構 Context 為 null,查詢必 NRE);移除BeginningBinsetter 內無條件覆寫EndingBin的贅行(清空起始倉儲會把截止倉儲蓋成空字串)。
Invbk1Bll:
- 儲位範圍條件原本拼好但沒傳給 SP(傳的是不含儲位的
skuCondition),且截止儲位誤用BeginningSKUBin(複製貼上 typo)——已改傳完整condition並修正 typo。-
EndingSKUBin預設由zzzzz改回 VFP 哨兵龜鶴遐齡(避免漏排序在 z 之後的中文儲位)。- 交易別碼+交易事項串接:變數算了沒用,三處改用串接後的
transactionCode(明細/日記帳「交易別碼」欄補上中文說明)。- PC 異領單轉入單號補值半成品:原本算出 index 後什麼都沒做,已照 VFP 從
trwkma.轉入備註取「:」後申請單號覆寫PriorTransactionNo。- 品號群組「品號結尾」標記 off-by-one:最後一組末筆補標。
invstk(庫存明細表)
Invstk.xaml:3 處 stale binding 修正(SKU→品號、SKUDescription→品名、ReservedQuantity→ReserveQuantity),主表三欄原本永遠空白。
InvstkBll:
- 品名「包含」查詢 LIKE 補
%(原為完全比對)。- 訂單查詢 SQL 欄名修正:
ETA/ShippedQuantity/結案/訂單號碼→ DB 實欄預訂交期/已交數量/是否結案/訂單編號(原 SQL 必炸)。- 負庫存查詢 SQL 重寫:補
a/b表別名、WHERE 前空白、twork_stk_vw_invstk改回invstk(照 VFP 等價寫法)。- 預訂交期預設改
今天+60 天(VFPDATE()+60的業務意圖:抓 60 天內未交訂單)。trlost(耗料單)+ Trlost_A(發送料轉單)
Trlost.xaml:整頁 stale 英文 binding 全面修正(master 12 處+detail 24 處,修正前所有主檔欄位與大部分明細欄空白);移除 9 個綁定到已刪 DB 欄的孤兒欄/區塊(Quantity1/2、UOM1/2、VehicleNo、EmployeeName、StartPoint、EndPoint、ProjectCode 區塊);補備註1欄(VFP 有)。
Trlost_A.xaml:detail grid 11 處 stale 英文 binding 改中文屬性。
Trlost_APoco/Trlost_APoco1:英文屬性補[TsColumnName]中文欄名映射(對中文 schema SP 回傳欄名原本永遠映射不到,轉單查詢全空)。
TrlostViewModel:listener 的nameof由誤借trlimaSource改正為trwkmaSource(值相同,純正確性)。
前手驗證(invrec / splace,commit 9b69004d)
驗證結論:兩支均已完整,無需再補。
- invrec:欄位/binding 全數 cross-check 通過;
InvrecSave(製單日期/隸屬倉庫必填+倉同儲自動帶倉儲+空列標刪)、InvrecEdit(盤點備註防呆)、IOther1~3(重算帳列/執行確認/轉盤點單)與 VFP else1~3 對齊;快速審核=集中式 workflow(等價);查詢鈕→Invrecm視窗存在且有 VM。
- splace:
SplaceSave涵蓋 VFP allowsave 全部(另多虛擬倉儲自動建立=新版擴充);倉同儲 LostFocus 連動、現有數查詢(DARB_TUR_SPLACE查詢別=2)、批次關帳(else1→Stkbas_1)均對齊。
未修(🟡 已知差異,列入待辦)
- invbk1:
TWORK_INVBK1SP 未部署於 darbnogicsa1 且 proc_param 未登錄(查詢會靜默回空,需部署+登錄);群組代號查詢路徑不可達(UI Collapsed);所有倉庫 chk 與起迄倉庫必填驗證未移植;Journal 頁 p2 查詢鈕、明細 5 個註解欄、單號 drill-down、報表(僅 Excel 匯出)未移植。
- invstk:
TWORK_QRY_INVSTKSP 未部署(本庫只有 DARB 版,且其第 3/5 result set 缺隸屬倉庫欄)+ VM 預設WarehouseOnly="PR"(Prime 專屬倉)三件一體,需部署決策後 runtime 才能跑;今年/去年出貨量、篩選別、品號雙擊連結、交期不同紅底列色、出貨通知單查詢別(刻意隱藏半成品)、起始品號 LostFocus 自動查詢未移植。
- trlost:
TWORK_TUR_TRLOST_ASP 未部署(腳本已備於.claude/tmp/scx_stk/TWORK_TUR_TRLOST_A.sql,請在 SSMS 執行);轉單彈窗家族WindowHelper.OpenWindow+code-behind VM 註解的系統性開窗問題(跨數十支,需 window-to-tsview 專案統一遷移,本批不動);else8 調整耗料(TRLOST_S)未移植;發票四欄被註解;本國幣總額 footer、關聯單號 DblClick 連結、部分 VFP 明細欄(責任單位/退貨日期/轉入單號等)未移植;Model 的材料單價/建檔日期與本機 DB 不一致疑待 migration(需 runtime 驗證)。
- Trlost_A 的 VFP 原始碼缺(獨立 .scx 未匯出),本批僅做新版一致性修補;如需逐欄對比請提供
TRLOST_A.scx匯出檔。
Breaking Changes
無。均為缺陷修補與顯示修正,不改資料格式。
Migration Notes
- runtime 驗收前需在 darbnogicsa1 部署並於 proc_param 登錄:
TWORK_INVBK1(param_qty=6)、TWORK_QRY_INVSTK(需含隸屬倉庫欄)、TWORK_TUR_TRLOST_A(腳本已備)。
- 本批依指示未 build;XAML/ViewModel 改動請於 Visual Studio 建置驗證(dotnet CLI 會撞既有 MSB4803)。
-
06-12 scx_ord-ormast-pk-fixes ▸
2026-06-12 — SCX_ORD ormast (E-060) / pk (E-100) VFP 對比修補
摘要
VFP
scx_ord.prg的ormast(訂單管理)與pk(PACKING LIST)跟新版深度對比後的修補。最大宗問題:2025-10 Source 屬性英→中改名(commit
fd97583d)沒同步改 XAML,Ormast.xaml / Ormast_US.xaml / Pk.xaml 合計 160+ 個 binding 綁到已不存在的英文屬性名,
欄位全部永遠空白、輸入不回寫。
變更
XAML dead binding 全面修正
TsERP/E.Order/Pk.xaml:23 處(主檔 cino/ci日期/製表日期/pino/商品名稱/幣別/頁首備註/頁尾備註/正嘜;明細 序號/客戶品號/單箱數量/毛重/淨重/產品描述/單位/材積/單箱材積/廠商代號/客戶訂單號 等)
TsERP/E.Order/Ormast.xaml:27 處(主檔 訂單號碼/受訂日期/倉庫/幣別/匯率/運送方式碼/付款方式碼/收付條件號/稅別/專案代號/客戶訂單號/ORDERCLOSE/總原幣未稅/總本幣未稅;明細 序號/品名/客戶品號/單位/DISCOUNTPG/原幣未稅/本幣未稅/備註/PICKEDQTY/結案)
TsERP/E.Order/Ormast_US.xaml:121 處(依fd97583d改名對照表機械還原,含註解區一併校正)
VFP 行為補齊
- Ormast.xaml 新增「交易條件 (C202)」下拉(VFP 主檔欄位,新版漏做);
Twork_ord_vw_ormastSource.CustomerCodeBindingsetter 同步補交易條件碼 = item.交易條件碼- OrmastSave:補 VFP allowsave 的
公司代碼、倉儲代號(倉庫)必填檢查(取代原本重複兩次的受訂日期死碼)
- OrmastViewModel:新增單預設補
訂單別 = "1";新增明細列預設出貨別 = "1"(VFP addagain/addsonitem)
- Ormast.xaml / Ormast_US.xaml 匯率改 Buy(買入):原 XAML TsCurrency 用 Sell,與 VFP
U_BLRATE(...,'買')及 Source setter 的 Buy 不一致
- 新增
PkEdit(LogicBll/Ade/E.Order/PkEdit.cs):VFP pk.allowedit 的「轉退稅註記='Y' 不得修改/刪除」防呆,之前完全沒擋
- PkSave:補 VFP allowsave 的「品號空白列標記增刪修='D'」,避免空白明細列入庫
- Pk 明細 起始箱號/截止箱號 自動算箱數:
Twork_ord_vw_pkdeSource新增BeginningBoxNoBinding/EndingBoxNoBinding(VFP LostFocus:箱數=截止-起始+1),Pk.xaml 兩欄改綁新 helper
Breaking Changes
無(全部是修復原本就壞掉/缺漏的行為)。
Migration Notes
- ORMAST / PK 仍未在
TsERP/App.xaml註冊 DataTemplate,程式開啟後無畫面——需另行補
OrmastViewModel→Ormast(或Ormast_US)與PkViewModel→Pk兩條 DataTemplate(共用登錄檔,本次不動)。- ormast Source/Model 仍含大量 US 專屬欄位(SALES1/PICKEDQTY/ORDERCLOSE/訂單號碼/倉庫/付款方式碼…),
本地 darb DB
vw_ormast沒這些欄位(DB 實際是 訂單編號/倉儲代號/結案);schema 對齊需另走
/db-model-compare,本次未動 Model schema。 -
06-12 scx_ord-cuqt-salema-preord-fixes ▸
2026-06-12 scx_ord 對比修補:cuqt / salema / preord
摘要
VFP scx_ord 三支 class(cuqt 客戶單品報價單、salema 出貨通知單、preord 預示表)與新版深度對比後的修補。
最大宗問題:2025-10 Source 屬性英文→中文改名時,三支表單的 XAML binding 沒有同步改名,
造成大量欄位畫面永遠空白/輸入不會存(binding typo 不會編譯錯誤)。
新增
- Cuqt:主檔新增「報價類別」下拉欄位(A.群組 / B.廠商 / C.客戶 / D.特殊,還原 VFP combo;先前完全沒有此欄位)。
- Salema:明細新增「箱數」「包裝量」兩欄(VFP 原有、新版漏建)。
變更
- Cuqt.xaml / Salema.xaml / Preord.xaml:修正共 40+ 處 stale 英文 binding
(如
QuotationNo→報價單號、ShippingNoticeNo→單號、Year→年度…),並修正
模具估價單數→模具價單數、群組代號 seek 欄補 DataMemberBinding(預設產品群組與 Source 不符)。- CuqtSave:AllowSave 改成依報價類別驗證必填(A 驗群組代號、B 驗廠商代號、C/D 驗客戶代號;
原本一律驗客戶代號,群組/廠商報價會被誤擋)。存檔前自動回填「模具組數 = 明細模具編號非空白筆數」(VFP 行為)。
- CuqtBll.Import(取得資料鈕):前置檢查改驗「報價日期」(原誤驗報價單號、訊息卻講報價日期);
匯入前先清空既有明細,避免重複按鈕造成明細重複。
- CuqtViewModel:移除誤接的 IOther1(原本「快速審核」鈕會開「樣品單轉入」視窗,copy-paste 殘留);
快速審核改走集中式工作流程機制。新增時報價類別預設
C.客戶(VFP addagain)。- SalemaViewModel:修正主檔客戶代號連動明細永遠不觸發的 listener case 名稱錯誤
(監聽
客戶代號但 switch 比對CustomerCodeBinding);數量/金額總額改成換筆瀏覽時也會重算(原本只有編輯中才算,瀏覽顯示前一筆的合計)。
- PreordViewModel.ImportExecute:修正
int.TryParse條件相反——使用者輸入的年度/月份會被覆寫成當月(應為解析失敗才補預設)。
- PreordSave:
- 「不得有大於該月份之預示」檢查改成只在新增模式執行(原本修改舊單也會被擋)。
- 新增模式補 VFP 年度(>=2010)/月份(1-12)驗證與月份補零(
3→03,否則單號組錯)。- 明細「原預訂交期必填」檢查改成跳過品號空白列(空白列存檔時本來就會被標記刪除)。
- PreordControlViewModel.SplitExecute(批數拆解):修正拆解列共用同一物件 instance 的 bug
(原本所有拆解列是同一筆、序號尾碼累加成 001A、001AB…);
改為每列獨立 Copy、序號 = 原序號+A/B/C…、交期逐批推算、原始/扣減數量歸零(VFP 行為),並防護空白序號。
刪除
- CuqtViewModel 的
ExtendedFunction1()(開錯視窗的死碼)。
Breaking Changes
無資料格式變更。報價類別新單預設值由存檔時補
C改為新增時帶C.客戶(驗證以開頭字母判斷,兩種舊資料皆相容)。Migration Notes
無需 migration。XAML / ViewModel 變更需在 Visual Studio 內 build 驗證(dotnet CLI 會撞既有 MSB4803 工具鏈問題)。
-
06-12 scx_gen-purch-trxama-fixes ▸
2026-06-12 — scx_gen 五支總務單據 VFP 對比修補(gppurch / gpurch / gtrlima / gtrrama / gtrsama)
摘要
依 VFP 舊版
scx_gen(gppurch G請購單 C-040、gpurch G採購單 C-050、gtrlima G出入庫單 C-080、gtrrama G進貨單 C-070、gtrsama G出貨單 C-090)逐欄/逐驗證對比新版 TsERP。
主要問題為 2025-10 英→中屬性改名後 XAML 留下大量 stale English binding(binding 不報錯但欄位永遠空白、
輸入不會存檔),四支已上線表單全部修正;另補回數個 VFP 驗證/預設值/計算鏈缺漏。
gtrsama(G出貨單)確認為未完工(只有 View 殼,無 ViewModel/Save/接線,docs 狀態 planned),未修。
變更
Gppurch(G請購單)
- XAML stale binding 修正(
TsERP/C.GeneralAffair/Gppurch.xaml):
- 主檔:
備註→請購備註、序號前置碼→倉儲代號(原本倉儲欄綁錯名,畫面顯示/輸入皆無效)。- 明細:
LineNo_→序號、VendorName→廠商簡稱(2 處)、SKUBinding→品號Binding、RequestQuantityBinding→需求數量Binding、UnitPriceBinding→單價Binding、原幣未稅→金額、預定交期→預訂交期(typo)。- 金額計算鏈修正(
Model/Source/C.GeneralAffair/Twork_gen_vw_gppurdeSource.cs):
SetAmount原本金額 = 單價 × 數量,但新版 UI 已將 VFP 的 數量/需求數量 併為單一「需求數量」欄,數量永遠 0 → 金額恆 0。改為金額 = 單價 × 需求數量。- TotalAmount 即時加總修正(
ViewModel/C.GeneralAffair/GppurchViewModel.cs):
WeakEvent listener 清單漏掛
金額,ReceiveWeakEvent的金額 case 從未觸發。已補。- 存檔補值(
LogicBll/Ade/C.GeneralAffair/GppurchSave.cs):
比照 VFP allowsave SCAN,明細
需求部門空白時帶主檔請購部門。- 多語系(
Common/Lang/Xaml/Gppurch.json):序號前置碼條目改正為倉儲代號(原為 WarehouseCode 的誤譯鍵),新增請購備註。
Gpurch(G採購單)
- XAML 全面 stale binding 修正(
TsERP/C.GeneralAffair/Gpurch.xaml,整張表單原本全綁英文舊名):
主檔 採購單號/公司代碼/廠商代號Binding/廠商簡稱/採購日期/倉儲代號/幣別/匯率/收付條件號/說明/採購備註/結案/請購單號;
明細 序號/品號Binding/品名/廠商品號/數量Binding/請購單號/單價Binding/原幣未稅/本幣未稅/預訂交期/回覆日期/暫定週數/備註/是否結案/已交數量/需求部門。
- 死欄位處理:
Purchaser(無對應欄)改為送貨地點(VFP 主檔欄);VesselBookingNo改為傳真日期;TempReceivedQuantity(無對應欄)改為需求部門;ETAInWarehouse改為暫定週數。- 預設值型別錯誤修正(
ViewModel/C.GeneralAffair/GpurchViewModel.cs):
SetNewData誤判Twork_pur_vw_purchSource(PURCH 的型別),預訂交期 +14 天預設從未生效,改為Twork_gen_vw_gpurchSource。- 存檔驗證補齊(
LogicBll/Ade/C.GeneralAffair/GpurchSave.cs):
- 補 VFP
幣別未輸入、匯率<=0驗證。- 補 VFP 明細
需求部門必填驗證、送貨地點空白帶主檔。- 補呼叫
TaxCalculate()(原本方法定義了但沒人呼叫;與 PurchSave/GtrramaSave 平行)→主檔 原幣金額/本幣金額/稅額 存檔時未計算的問題修復(對應 VFP SUM加總 + REPLACE)。
- 預訂交期訊息誤用
ProgramClass.PURCH改為GPURCH。Gtrlima(G出入庫單)
- XAML stale binding 修正(
TsERP/C.GeneralAffair/Gtrlima.xaml):
主檔 倉單號/單號/序號前置碼/交易日期/公司代碼/交易部門/客廠部簡稱/運送方式碼/交易備註/轉入備註/轉出備註;
明細 序號/品號Binding/品名/單位/數量Binding/轉出倉儲/轉入倉儲/途程序號/工程代號/批號別/批號/單價Binding/原幣未稅/本幣未稅/備註。
- 批號別/批號欄改為可輸入:原 IsReadOnly=True,但 GinventorySave 在倉庫批號管制時要求必填,唯讀導致無法存檔。
- 新增欄位/區塊(對應 VFP 既有欄):主檔 幣別(TsCurrency,買入匯率自動帶)+ 匯率;明細 交易別碼、客廠品號、其他金額(其他金額Binding,連動原幣未稅計算)。
Gtrrama(G進貨單)
- XAML 全面 stale binding 修正(
TsERP/C.GeneralAffair/Gtrrama.xaml,主檔+明細+進貨費用三層全英文舊名):
- 主檔:倉單號/單號/隸屬倉庫/序號前置碼/交易日期/廠商代號Binding/廠商簡稱/幣別/匯率/付款方式碼/收付條件號/說明/
發票號碼/發票日期/發票金額/稅別/名稱/稅額/提單號碼/報單號碼/分攤費用/運送方式碼/交易備註/轉入備註/轉出備註/
總費用/總原幣未稅/總本幣未稅/總關稅分攤/總其他分攤。
- 明細:序號/品號Binding/品名/客廠品號/交易別碼/轉出倉儲/轉入倉儲/數量Binding/單位/單價Binding/其他金額Binding/
原幣未稅/關稅稅率/關稅分攤/其他分攤/本幣未稅/單位成本/成本/微調本幣/備註/採購單pkid/採購單號/轉入單pkid/訂單pkid/
其他資料1/其他資料2/途程序號/工程代號/批號別/批號/預訂交期/待轉入倉/待轉出倉/轉帳款數量/分攤品號/分攤群組/庫存管制。
- 進貨費用:序號/費用代碼/費用說明/科目代號/科目名稱/客廠部代號/客廠部簡稱/幣別/匯率/原幣未稅/本幣未稅Binding/是否為成本/費用備註/轉出備註。
- 合計面板死綁定
DueAmountWithCost/ContainerValue改為稅額/本幣應收付(對應 VFP 含稅本幣)。- 刪除無對應欄的死欄位:Transaction Method(C202 交易條件,gtrrama 無此欄)、Declaration Date、Ship Of Origin、
LCNum、Invoice、CompleteAllocation、Notes1、DefectReasonCode、TemporaryDocumentNoA、InventoryControlDescription、
費用表的 InvoiceNo/IsPosted。
Gtrsama(G出貨單 C-090)— 未修(整支未完工)
- 現況:僅有
TsERP/C.GeneralAffair/Gtrsama.xamlView 殼(且 binding 全為英文舊名);
無 GtrsamaViewModel、無 Save/Edit、無任何程式開啟此 View;
docs/C-GeneralAffair/gtrsama.md狀態planned。- Source/Model(
Twork_gen_vw_gtrsamaSource/gtrsadeSource)已存在,後續補 ViewModel + Save(可比照 GtrlimaViewModel + GinventorySave 家族)即可完工。
未修清單(🟡,記錄備查)
- 共通:工作流程/快速審核/流程樣板/審核欄位 → 新版集中式 workflow(等價,不比)。
- Gppurch:採購別 無 UI 且未驗證(預設 1);請購說明/傳真日期/詢比議記錄/聯絡單ID 欄位未做;
需求轉單(GPRTOPP)未移植;廠商代號 LostFocus 自動帶 送貨地點/運送方式碼/幣別 未做;
預訂交期 不得小於今日的驗證未做(新版改為存檔時補今日);送貨地點 prgpar 4003 預設(銓育專屬)未做;
明細多數參考欄(用途/廠牌/分攤*/匯率/預估單價/預估金額/是否結案/採購單號…)UI 簡化未顯示;
VM
DataFromSource屬性為 dead code;savevalid 聯絡單 viewxml 連動(COMMPR)未移植。- Gpptopu(請購轉採購):仍繼承 TransferBll(已知刻意不大改);其
TWORK_TUR_GPPTOPUSP 僅存在 darbzdcsa1(英文欄名版),
中文 schema DB(darbnogicsa1)未部署 → 此轉單在中文庫 runtime 會失敗,需另行部署中文版 SP。
- Gpurch:結案鈕(else5 特殊修改:單價只可調低/備註/是否結案)未移植(含「特殊修改單價不得大於原單價」防呆);
修改交期(PURCH_E 批次改交期)、進貨查詢(GPURCH_S/else6)未移植;
反推稅率/反推未稅價鈕 未移植;交易條件/付款方式/運送方式 主檔欄無 UI;
廠商帶出僅 收付條件/幣別(VFP 另帶 送貨地點/交易條件/付款方式/運送方式);
ExtendedFunction1仍走已廢棄WindowHelper().OpenWindow。- Gtrlima:統計鈕(else4 GSHIPPING)未移植;GMFTOMG 鈕在 VFP 即無 Caption(沒做)不比;
運費轉入鈕(禾久/台賓 Excel)公司專屬不做;品號離焦即時庫存查詢改由 IStockQuery 面板(等價)。
- Gtrrama:送修轉入(else4 GMFTOMG)未移植;明細 請購人員 空白帶 usercode 未做;
費用列 原幣未稅<=0 自動標刪(VFP)新版未做(僅靠分攤平衡驗證擋)。
- 四支表單 XAML Label 仍多為英文字串(未包 DisplayMeta),僅 Gppurch 走 DisplayMeta;後續可跑 xaml-label-to-displaymeta。
Breaking Changes
無資料結構變更。Gpurch/Gtrrama/Gtrlima 删除的皆為綁定失效的死欄位;
Gppurch
金額改按 需求數量 計算屬 bug fix(原值恆 0)。Migration Notes
- 本批未動共用登錄檔、未動 DB schema。
- XAML/ViewModel 變更需在 Visual Studio 內 build 驗證(dotnet CLI 撞 MSB4803 為既有工具鏈問題)。
- runtime 驗收重點:四支表單開窗欄位是否正常顯示/可輸入、Gppurch 金額與 Total 即時計算、
Gpurch 存檔後主檔原幣/本幣金額、Gtrlima 批號輸入、Gtrrama 費用分攤存檔驗證。
- XAML stale binding 修正(
-
06-12 scx_gen-ginvent-gsplace-gsppdt-gtrinout-fixes ▸
2026-06-12 scx_gen 對比修補:ginvent / gsplace / gsppdt / gtrinout
摘要
VFP
scx_gen四支 class(G庫存主檔 ginvent、G倉庫表 gsplace、G廠商報價 gsppdt、G入出庫申請單 gtrinout)與新版 TsERP
C.GeneralAffair模組深度對比後的修補。主軸是 2025-10 英→中改名後殘留的 stale English binding(欄位永遠空白、輸入不會存檔)、
缺驗證、缺預設值與一支呼叫不存在 SP 的查詢。
新增
Ginvent(G庫存主檔)
- 主畫面補上 VFP 有但新版漏掉的欄位:規格、模具型別、模具尺寸、科目代號(AcclSearch)、中文描述、備註。
- 新增「產生品名」按鈕(VFP 產生品名鈕):品名 = 族群名稱(去掉第一段代號)+ 各分類內容串接,截斷 120 字。
Twork_gen_vw_ginventSource.SetDisabledDate():停用='Y' 補停用日期、取消停用清空(對應 VFP else4click 停用鈕,新版改存檔時處理,與 D.Bom Invent 一致)。
- 新增時預設 新增日期=當天(VFP addagain)。
Gsplace(G倉庫表)
- 主畫面補上 送貨地點 欄位(gstkbas 有欄、VFP 有顯示、新版漏掉)。
Gsppdt(G廠商報價)
- 存檔驗證補齊 VFP allowsave:廠商代號 / 報價日期 / 收付條件號 必填。
- 存檔時 幣別空白補本位幣、匯率<=0 補 1、明細「品號+工程代號皆空」列標記刪除。
- 輸入廠商代號自動帶 幣別(VFP sqlnm_sp1.LostFocus;原本只帶收付條件號)。
- 明細表補欄位:內箱包裝數、關稅稅率、特別要求。
- 主畫面補 簽決單號 欄位。
Gtrinout(G入出庫申請單)
- 存檔驗證補:申請日期、申請部門 必填(VFP allowsave)。
- 存檔時:明細 需求部門=申請部門、主檔 幣別=本位幣+匯率=1(VFP「畫面上無幣別」)、
主檔 原幣金額/本幣金額 = 明細原幣未稅合計(VFP sum加總)。
- 主畫面補 廠商代號 欄位(MF 廠商報價查價用)、轉入備註(唯讀)。
- 明細表補欄位:規格、交易別碼、單位(下拉)、其他金額、參考單價、批號別、批號、用途、預訂交期、是否結案。
變更(stale binding / 錯誤修正)
Ginvent.xaml
CreatedDate→新增日期、IsDisabled→停用、英文品名→英文描述、GroupDescription→群組說明
(以上原 binding 在 Source 都不存在,欄位永遠空白且不存檔)。
Gsplace
- Quantity Query(現有數)整段修復:原呼叫不存在的
DARB_QRY_GSPLACE(DB 無此 SP、proc_param 未登錄),
改呼叫 VFP 原本的
DARB_TUR_GSPLACE(查詢別=2,已登錄)。GsplaceQuantityPoco屬性由英文改為中文(倉儲代號/品號/途程序號/工程代號/批號別/批號/現有數量/現有金額/設立說明),
對齊 SP 回傳欄名(DataTable→Poco 按名稱對應,原本全部對不上)。
- 現有數 grid 欄位 binding/標題同步改中文。
Gsppdt.xaml
- 主檔:
VendorCodeBinding→廠商代號Binding、廠商名稱→廠商簡稱、PaymentTermDescription→說明、
ActivityStartDateBinding/ActivityEndDateBinding→活動起始日Binding/活動截止日Binding。- 明細:
LineNo_→序號、SKUBinding→品號Binding、MaterialChargeBinding/ProcessingChargeBinding/UnitPriceBinding
→
材料單價Binding/代工單價Binding/單價Binding、最低採購量→最低採購量Binding。Gtrinout.xaml(全表單 rebind — 原本整張表單 binding 全是英文舊名,欄位全空)
- 主檔:
ApplicationNo→申請單號、ApplyDate→申請日期、DocumentPrefix→序號前置碼、ApplyType→申請原因、
Applicant/ApplicantName→申請人員/姓名、DefaultWarehouse→隸屬倉庫、CustVendCodeBinding/CustVendName→申請部門/部門簡稱(改用 DeptSearch)、TurnOutNote→轉出備註。- 明細:
SKUBinding→品號Binding、SKUDescription→品名、Notes→備註、QuantityBinding→申請量Binding、
UnitPriceBinding→單價Binding、CurrencyAmountWithoutTaxBinding→原幣未稅Binding、DestinationBin→倉儲代號(FilterCondition 改綁MasterItem.隸屬倉庫)、ProcessingCode→工程代號、GivenQuantity→核發量。- 明細 grid 補
DataManager="{Binding DetailData}"。
GtrinoutSave
- 移除「廠商代號必填」(VFP 非必填,僅 MF 查價用;原本畫面又沒有廠商欄位,等於永遠存不了檔)。
刪除
- Ginvent.xaml:
顏色下拉(Source/DB 皆無此欄,從 D.Bom Invent 複製殘留的死 UI)。
- Gsplace.xaml:
管制負數、LotCodeControl兩個下拉(gstkbas 無此欄,binding 永遠落空,僅 stkbas 產銷存版才有 管制負數)。
- Gsppdt.xaml:
生效日期欄(Source 無此屬性)、明細數量欄(=最低採購量 的重複唯讀別名)、代工廠商欄(Source/DB 無此欄)。
- Gtrinout.xaml:
Free Samplecheckbox 與明細FreeSample/Pending/Restocked/Billed欄(Source 皆無對應屬性,死 UI)。
已知未修(🟡,刻意留待後續)
- gsplace 開帳導入(else1):VFP 跑
DARB_LOG_GINVSTK_RECOUNT(含放行碼),新版完全未移植;
現在 IOther1 開的 Gstkbas_1 對應的是 VFP else2 批次關帳。
- gtrinout 轉交易單(else3 → GTRINOUTE):新版 GtrapplyToGtrlima 流程呼叫的
TWORK_TUR_GTRAPPLYTOGTRLIMA/TWORK_QRY_GTRAPPLYPICK在本機 DB 不存在也未登錄 proc_param,且其 Poco 屬性為英文、
DARB_TUR_GTRINOUTE回傳中文欄名——整段轉單流程在本機環境不可用,需另案處理。- gtrinout 轉入倉儲/轉出倉儲 W/T 推導與倉儲代號驗證(VFP allowsave 依 LCL交易別 轉入/轉出部門設定):未移植。
- gtrinout 反推稅率/反推未稅價鈕:未移植。
- ginvent 自動編碼(LCL系統參數表 項目=4 時品號自動編碼、改驗群組代號):未移植。
- ginvent 庫存管制強制 'Y'(VFP「銓育都要管制庫存」存檔時強制):新版改為新增預設 Y + 使用者可改,視為設計決策保留。
- ginvent 分群碼 + 帶分群資料鈕:新版全系統皆無分群碼 UI,未補。
- TsGBinSearchColumn(共用控件) SeekCondition="Bin"/SeekColumn="Description" 疑為英文舊名
(vwseek_gsplace 已是中文欄),屬共用控件不在本次範圍,待確認。
- gstkbas.可用(新版欄位,非 VFP)以 YesNoComboBox(Y/N) 綁 byte 0/1,型別不符恐顯示空白,沿用現狀待確認。
Breaking Changes
無資料結構變動;僅 UI binding、驗證與一支 SP 呼叫名修正。
Migration Notes
- 無需 DB migration。
DARB_TUR_GSPLACE既有且已登錄 proc_param。
- XAML/ViewModel 改動需在 Visual Studio 內建置驗證(dotnet CLI 會撞 MSB4803 ResolveComReference,屬工具鏈問題)。
- 全部修補均未經 runtime 驗證,四支表單建議各做一次 新增→存檔→修改→刪除 煙霧測試。
-
06-12 rtaxma-port ▸
2026-06-12 報關沖退稅/出口報單(RTAXMA,選單 E-120)VFP 移植
摘要
按 VFP 舊版
RTAXMA在 Darbware ERP 新增「報關沖退稅(出口報單)」Master+Detail 單據,走 canonical TsView + ItemsBindingManager 範本(比照 Orssma)。
rtaxma/rtaxde 無 view,Source 直接映射表;子表鍵欄為「項次」。
此單據無審核/工作流程(表無審核三欄與聯絡單id/工作流程欄位)。
新增
TsERP\E.Order\Rtaxma.xaml(.cs):主檔欄位 + 明細 TsRadGridView(欄序依 VFP grid1 ColumnOrder)+ 底部合計列
ViewModel\E.Order\RtaxmaViewModel.cs
LogicBll\Ade\E.Order\RtaxmaSave.cs(刪除無 VFP 客製檢查,走預設 DeleteBll)
Model\Source\E.Order\RtaxmaSource.cs / RtaxdeSource.cs
Common\Model\E.Order\RtaxmaModel.cs / RtaxdeModel.cs
- 多語系
Common\Lang\Xaml\Rtaxma.json(同步併入TsERP\Lang\Xaml1\Xaml.json)
- 登錄:TableMap(rtaxma/rtaxde 直接映射表名)、ClassAliasMap 4 筆、LocalDbContext DbSet、App.xaml DataTemplate
行為(VFP 還原)
- 編號:前置碼 RT + 彙總日期年月 + 5 碼流水(
_sheetno既有設定,server 端產號);新增時彙總日期預設今天
- 箱號計算(txt起始箱號/txt截止箱號.LostFocus):箱數 = 截止箱號 − 起始箱號 + 1
- 計算材積鈕(cmdbtn11.Click,逐列):單箱材積 = ROUND(箱長×箱寬×箱高/1,000,000×35.3147, 2),限編輯模式
- sum加總(排除品號空白與刪除列):總箱數=Σ箱數、總淨重=Σ ROUND(單箱淨重×箱數,2)、
總毛重=Σ ROUND(單箱毛重×箱數,2)、總材積=Σ ROUND(單箱材積×箱數,2)、
總金額=Σ ROUND(單箱數量×單價×IIF(截止箱號=0,1,箱數),2)、總數量=按單位分組 Σ數量 串列
- 存檔驗證(allowsave):彙總日期/客戶代號必填;品號空白明細列視為刪除(CINO 檢查在 VFP 已註解,維持不檢查)
- 列上 數量/淨重/毛重 依 VFP 註解公式自動帶:虛擬箱數=IIF(截止箱號=0,1,箱數)、
數量=ROUND(單箱數量×虛擬箱數,0)、淨重=ROUND(單箱淨重×箱數,2)、毛重=ROUND(單箱毛重×箱數,2)
(VFP 上線版此三欄由轉入帶值後手動維護,新版改為自動計算)
變更(與 VFP 不同處,刻意)
- 明細多一欄唯讀「數量」(VFP grid 未顯示該欄,但合計用得到,可視化計算結果)
- 明細 客戶代號 欄為一般文字欄(VFP sql_cuno 標準驗證,未掛 seek 欄位)
待辦
- 轉入機制未移植:VFP addclick 進新增模式後
DO FORM rtaxma_m,由 modal 挑 PK/CI 出貨單據彙總轉入
明細並回寫主檔「轉入單號」(220 字寬、可多張)。rtaxma_m 原始碼不在抽取檔內,先上手動輸入版;
TODO 註記在
RtaxmaViewModelclass 註解- 報表 RTAXMA_P 未移植(本次刻意不做)
- runtime 未驗收
-
06-12 pi-port ▸
2026-06-12 — PI Proforma Invoice(E-130)按 VFP 還原
摘要
依 VFP 舊版
PI(scx_ord.vcx,1237 行)完美還原 Proforma Invoice 主明細表單到 Darbware ERP,走
ErpProgramWithDetailViewModel+ItemsBindingManager+ TsView/TsRadGridView 最新範本(結構比照 CI 商業發票)。主檔
pi_m、明細pi_d直接綁資料表(無 view)。> ⚠️ pi_m / pi_d 資料表尚未建立(所有本機 DB 皆無),DDL 在
>
.claude/tmp/pi-tables.sql待使用者放行後執行。程式碼(Model/Source/VM/XAML/Save/登錄點)> 已全部照 DDL 完成;_sheetno 的 PI 列既有(pi_m/pino/pi_d),不需 INSERT/UPDATE。
新增
Common/Model/E.Order/Pi_mModel.cs、Pi_dModel.cs
Model/Source/E.Order/Pi_mSource.cs、Pi_dSource.cs
LogicBll/Ade/E.Order/PiSave.cs
ViewModel/E.Order/PiViewModel.cs
TsERP/E.Order/Pi.xaml(.cs)(TsTabControl:明細資料編修 / 頁首資料編修,還原 VFP PF 兩頁)
Common/Lang/Xaml/Pi.json(+ Common.csproj Content)
.claude/tmp/pi-tables.sql(CREATE TABLE pi_m/pi_d + PK/索引,未執行)
PI DDL 摘要
pi_m:pino nvarchar(20)、客戶代號(10)、pi日期(10)、公司代碼 int、幣別(8)、匯率 numeric(14,4)、
報價單號(12)、聯絡人(30)、客戶訂單號(20)、商品名稱(100)、預訂交期(10)、產品描述別(4)、
交易條件碼 int、交易條件(30)、頁首備註/頁尾備註/正麥 nvarchar(max) + 共用欄(照 rtaxma:
pkid 非 IDENTITY、linkid NULL DEFAULT 0);PK=pkid、
IX_pi_mUNIQUE(pino)(比照 ci_m)pi_d:pino(20)、序號(6)、客戶品號(30)、品號(30)、產品描述 nvarchar(max)、數量 numeric(15,4)、
單位(4)、單價 numeric(16,6)、報價單位(4)、備註(30) + 共用欄(照 rtaxde);
PK=pkid、
IX_pi_d(linkid)(比照 ci_d)- 同名欄位型別照 ci_m/ci_d;商品名稱 VFP mask X40 但取 ci_m 的 nvarchar(100)(PI→CI 下游複製不截斷);
欄名「正麥」照 VFP(ci_m 為「正嘜」,是不同欄)
VFP 行為對照
VFP 新版 allowsave: PI日期未輸入/客戶代號未輸入PiSave.AllowSaveGetInputMessageallowsave:明細 數量=0→ 增刪修 'D'Pi_dSource.NeedDeleteFunction(數量==0)+MarkZeroQuantityDetailDeleted雙保險keyfldvalue=PINO(無 is_noduplicate) pino 必填 + IsDocNoDuplicate(DARB_GETDATA4 查 pi_m)— 比照 ESTSAL 範本補上sum加總: SUM 數量, ROUND(數量*單價, TWD/JPY?0:2) FOR 增刪修<>'D' AND NOT EMPTY(品號)PiViewModel.RecalculateTotals:TotalQuantity/TotalAmount,小數位改用幣別小數位設定OpenDbfTable.GetDecimalPlaces(TWD/JPY=0、一般=2,語意等價);ListenerHelper 監聽 數量Binding/單價Binding/幣別 即時重算grid1.Refresh → SUM加總 IMoveRecord.AfterMoverRecord導覽後重算 + 帶客戶簡稱幣別.LostFocus: 匯率 = U_BLRATE(幣別,'1','賣',PI日期)TsCurrency(Currency=幣別、Date=pi日期、FXRate=匯率、SearchType="Sell")changeopmode:報價單號 僅 OPMODE=1(新增)ENABLED XAML AddOnlyTextBoxStyle(DataTrigger on Status=Add/Copy)明細 Replace PINO With PI主檔_V.PINO+ son1fld=序號PiSave.HandleDataBeforeEndEdit回填 pino、空白序號補流水(D3);新增列OnAddListener即時編號grid col品號 sql_mno1dovalid=1品號Binding→SetProduct():驗證(查無→「查無品號 !!!」)+ 依主檔 產品描述別 帶 產品描述/單位(比照 CI 同款邏輯)主檔 產品描述別 sqlcombo(中文,英文) ItemDescriptionTypeSource(EnumManager),切換時重帶全部明細 產品描述(比照 CI)公司代碼 sqlcombotxt c_type=101 / 交易條件 c_type=202 TsComboBoxWithDescriptionBySqlTableAlias C101 / C202數量總額/金額總額 唯讀(txt_color=2) TotalQuantity/TotalAmount 唯讀 TsNumericTextBox (無對應)交易條件 文字欄 比照 CiSave:存檔時 交易條件 空白由 交易條件碼 帶出 變更(既有檔案)
TsERP/Lang/TableMap.json:修正預留映射 —"pi_m"/"pi_d": "twork_ord_vw_pi_*"→"pi_m"/"pi_d"(無 view,照表名)
TsERP/Lang/ClassAliasMap.json:Twork_ord_vw_pi_*預留別名改Pi_m*/Pi_d*
Model/LocalDbContext.cs:DbSet<Pi_mSource> Pi_m、DbSet<Pi_dSource> Pi_d
TsERP/App.xaml:PiViewModel DataTemplate
TsERP/Lang/Xaml1/Xaml.json:Pi區塊
Common/ProgramClass.cs:PI既有,未改
刪除
無。
Breaking Changes
無(新功能;DB 端需另行放行建表)。
Migration Notes / 未還原項目
- DB Migration(待放行):執行
.claude/tmp/pi-tables.sql建pi_m/pi_d後本表單才可運作;
未建表前開窗導覽會因 server 查無資料表而失敗。
- 報表 TODO:VFP 報表程式
PI_P(SCX_ORDP) 尚未移植。
- pi_m 無任何審核欄位 → 不掛集中式審核。
- VFP 已註解(dead code)未還原:報價單號.Valid 複製客報價單、搜尋客號鈕(依客戶歷史訂單帶客戶品號)、
搜尋單價鈕(抓最近訂單單價)、客戶訂單號 重複檢查、sqlnm_cu LostFocus 帶幣別/聯絡人/交易條件/停用檢查、
txtlabel3.Click 頁首備註自動產生。
- VFP page2 公司簡稱 為 attachment_btn(附件鈕):附件行為未還原(公司代碼於頂部以 C101 combo 呈現)。
- VFP changeopmode 新增時自動切到頁首頁籤/焦點控制:未還原(焦點機制不同)。
- runtime 未驗。
-
06-12 pdtsal-port ▸
2026-06-12 — PDTSAL 產銷表(E-940)按 VFP 還原
摘要
依 VFP 舊版
PDTSAL(scx_ord.vcx,773 行)完美還原產銷表 主明細表單到 Darbware ERP,走
ErpProgramWithDetailViewModel+ItemsBindingManager+ TsView/TsRadGridView 最新範本(比照 Estsal/Claim)。主檔
pdtsal_m(DB 無 vw_pdtsal_m,直接綁資料表)、明細走vw_pdtsalview(pdtsal LEFT JOIN vwseek_invent 帶 品名);明細無單號欄位,與主檔以 linkid 關聯(框架標準行為)。
新增
Common/Model/E.Order/Pdtsal_mModel.cs、Vw_pdtsalModel.cs
Model/Source/E.Order/Pdtsal_mSource.cs、Vw_pdtsalSource.cs
LogicBll/Ade/E.Order/PdtsalSave.cs
ViewModel/E.Order/PdtsalViewModel.cs
TsERP/E.Order/Pdtsal.xaml(.cs)
Common/Lang/Xaml/Pdtsal.json(+ Common.csproj Content)
VFP 行為對照
VFP 新版 allowsave:年度/月份/版次 必填( 請輸入年度/月份/版次)PdtsalSave.AllowSave逐項 GetInputMessageallowsave: EMPTY(品號)→ 增刪修 'D'Vw_pdtsalSource.NeedDeleteFunction+MarkEmptyDetailDeleted雙保險keyfldvalue=單號(無 is_noduplicate) 單號必填 + IsDocNoDuplicate(DARB_GETDATA4 查 pdtsal_m)— VFP 由 sqledit 鍵值機制隱含,比照 ESTSAL 範本補上changeopmode:年度/月份/版次 僅 OPMODE=1(新增)ENABLED XAML AddOnlyTextBoxStyle(DataTrigger onAdeViewModel.Status= Add/Copy)grid col品號 sql_mno1dovalid=1品號Binding→SetSkuData(),查無→「查無品號 !!!」grid Column17 U_SEEKNM('SK_INVENT',品號,'品名')+moverec_sk_cursorSK_INVENT 快取明細直接走 vw_pdtsal.品名(navigate 載入即有),編輯時 SetSkuData 重抓grid col客戶代號 sql_cuno1TsCustomerSeekGridViewColumn數量系欄 mask 99,999,999.99(上月庫存~預售計劃4) PlaceEnum TwoPlace(DB money 19,4) 單價 mask 9,999,999,999.999999 PlaceEnum SixPlace(DB numeric 16,6) Init: '單價'$THIS.IS_備註才顯示單價欄(站台設定)新版固定顯示單價欄(無對應站台參數機制,從寬處理) 變更(既有檔案)
TsERP/Lang/TableMap.json:修正預留映射 —
"pdtsal_m": "twork_ord_vw_pdtsal_m"→"pdtsal_m"(DB 無該 view)、"pdtsal": "twork_ord_vw_pdtsal"→"vw_pdtsal"(DB 實際 view 名)TsERP/Lang/ClassAliasMap.json:Twork_ord_vw_pdtsal_m*預留別名改Pdtsal_m*(照表名命名)、
Twork_ord_vw_pdtsal*改Vw_pdtsal*(照 DB view 名,比照 Claim)Model/LocalDbContext.cs:DbSet<Pdtsal_mSource> Pdtsal_m、DbSet<Vw_pdtsalSource> Pdtsal
TsERP/App.xaml:PdtsalViewModel DataTemplate
TsERP/Lang/Xaml1/Xaml.json:Pdtsal區塊
Common/ProgramClass.cs:PDTSAL既有,未改
刪除
無。
Breaking Changes
無。
Migration Notes / 未還原項目
- 報表 TODO:VFP 報表程式
PDTSAL_P(SCX_ORDP) 尚未移植。
- pdtsal_m 無任何審核欄位 → 不掛集中式審核。
- VFP Init 註解掉的 DYNAMICBACKCOLOR(刪除列紅字、單價<=0 綠底)為 dead code,未還原。
- VFP 單價欄「
'單價'$IS_備註才顯示」的站台開關未還原,新版固定顯示。
- runtime 未驗(_sheetno PDTSAL 列既有、pdtsal_m/pdtsal/vw_pdtsal DB 物件既有,無 DB 變更需求)。
-
06-12 orssma-port ▸
2026-06-12 調撥指示單(ORSSMA,選單 E-080)VFP 移植
摘要
按 VFP 舊版
ORSSMA(scx_ord.vcx,調撥通知)在 Darbware ERP 新增「調撥指示單」Master+Detail 單據,走 canonical TsView + ItemsBindingManager 範本(比照 Ormast/Trsama)。
新增
TsERP\E.Order\Orssma.xaml(.cs):主檔欄位 + 明細 TsRadGridView(欄序依 VFP grid1 ColumnOrder)
ViewModel\E.Order\OrssmaViewModel.cs
LogicBll\Ade\E.Order\OrssmaSave.cs / OrssmaDelete.cs
Model\Source\E.Order\Vw_orssmaSource.cs / Vw_orssdeSource.cs
Common\Model\E.Order\Vw_orssmaModel.cs / Vw_orssdeModel.cs
- 多語系
Common\Lang\Xaml\Orssma.json(同步併入TsERP\Lang\Xaml1\Xaml.json)
行為(VFP 還原)
- 編號:前置碼 KU + 受訂日期年月 + 5 碼流水(
_sheetno既有設定,server 端產號)
- 新增預設:訂單別=2、受訂日期=今天、本位幣+匯率1、明細出貨別=1(VFP addagain)
- 客戶代號帶預設:交易方式/業務員/收付條件/幣別/交易條件/運送方式/交易類別/港口/稅別
(沿用 DB 既有
DARB_QRY_ORSSMA查詢別 3);匯率由 TsCurrency 依受訂日期自動帶(買進)- 品號驗證:查無品號/品號停用/匯率未輸入擋下;單價 = ROUND(平均成本/匯率,5)(無平均用標準成本);
客戶品號/單位/製程別抓該客戶最近一張調撥通知(
DARB_QRY_ORSSMA查詢別 4)- 金額:數量×單價=原幣未稅,含稅/本幣按稅別稅率與匯率(TaxCalculator);
orssde 無微調欄位,尾差直接併回明細列金額(對應 VFP 把差額塞最大列)
- 存檔驗證:受訂日期/客戶代號必填;交易類別限 D/I/L;出貨別限 1/2;訂單分類限 A–E;
品號空白或數量 0 的列視為刪除
- 客戶訂單號失焦補空白明細;複製明細鈕還原 VFP 複製鈕
變更(與 VFP 不同處,刻意)
- 工作流程/快速審核:改走集中式(工作流程頁籤 + 審核鈕),不再各表單自寫
- 庫存量/在製品查詢面板(VFP cmdbtn11 + grid2):改用集中式「庫存」查詢頁籤
待辦
- 報表 ORSSMA_P 未移植(本次刻意不做)
_sheetno.流程類別為空 → 工作流程頁籤停用;要啟用需 DB 設定流程類別
- runtime 未驗收
-
06-12 invent1-port ▸
2026-06-12 產品序號表(INVENT1)移植
摘要
依 VFP 舊版
scx_ord.vcx / invent1完整移植「產品序號表」(選單 E-160,保固卡主檔)到 Darbware ERP。單檔主檔(主表
invent1、主表 viewvw_invent1,無明細),編號依_sheetno(單據別 INVENT1、編碼方式 1、srno 長度 3、保固卡號 = 序號前置碼(品號) + 流水號)。
新增
Common\Model\E.Order\Vw_invent1Model.cs
Model\Source\E.Order\Vw_invent1Source.cs— view 顯示欄位 客戶簡稱/客戶簡稱1/品名 僅存 Source 不上傳
ViewModel\E.Order\Invent1ViewModel.cs—ERPProgramViewModel+ IMoveRecord + IOther1
LogicBll\Ade\E.Order\Invent1Save.cs— 反射命名LogicBll.Ade.Invent1Save
TsERP\E.Order\Invent1.xaml(.cs)— TsView 單檔主檔
Common\Lang\Xaml\Invent1.json+TsERP\Lang\Xaml1\Xaml.json併入 Invent1 區段
TsControl\Themes\TsTextBoxGeneric.xaml:新增ProductSerialNoSearch樣式(invent1.保固卡號,供 CLAIM 等表單 F2 查詢)
登錄點
TsERP\Lang\TableMap.json:"invent1": "vw_invent1"
Model\LocalDbContext.cs:DbSet<Vw_invent1Source> Invent1
Common\ProgramClass.cs:INVENT1(之前盤點缺 entry,本次補上)
TsERP\App.xaml:Invent1ViewModel → Invent1DataTemplate
TsERP\Lang\ClassAliasMap.json:Vw_invent1Model/Source → Vw_invent1
Common\Common.csproj:Lang\Xaml\Invent1.jsonContent
VFP 行為對照
VFP 新版 allowsave:客戶代號/品號/購買日期空白擋存Invent1Save.AllowSaveallowsave:REPLACE 序號前置碼 WITH 品號Invent1Save.HandleDataBeforeEndEdit保固期限別.Valid:限 0 或 1Invent1Save.AllowSave(請輸入 0 或 1)銷貨單號.Valid:倉單號=倉庫+銷貨單號 查 trsama 帶公司代碼/客戶代號/集團代號/購買日期(交易日期),保固期限=0→12,倉單號相同不回填銷貨單號Binding → SetShippingData()(DARB_GETDATA4 trsama)倉庫/銷貨單號.Refresh(OPMODE=0):LEFT(倉單號,6) / SUBSTR(倉單號,7)SyncWarehouseDisplay()(VMAfterMoverRecord呼叫)未保養天數.Refresh(U_NOSERVICEDAYS):停用→'停用';否則今天−前次保養日(repair 最大結案日期,無則購買日期);無卡號→'無'SetNoServiceDays()(DARB_GETDATA4 repair,VMAfterMoverRecord呼叫)客戶代號/集團代號(sqlnm_cu)帶簡稱客戶代號Binding/集團代號Binding → DescriptionHelper.GetCustomerName(view 欄 客戶簡稱/客戶簡稱1)品號(sql_mno dovalid=1)帶品名、查無提示品號Binding → SetSkuData()(查無品號 !!!)else1click取得附件:OPMODE=0 → 特殊修改 → GETFILE(附件上限 _prgpar 8 MB)→ U_SAVEFILE2(保固_保固卡號)→ 回填附件 → 立即存檔,失敗取消Invent1ViewModel.ExtendedFunction1(IOther1;ERPIO.SaveToDigitalLibrary,子目錄=年月、檔名前綴=年月保固卡號,與 LEFT(附件,6)=年月 開檔規則一致)顯示附件鈕.Click:U_OpenFile(數位目錄\LEFT(附件,6)\附件)ShowAttachmentCommand(Process.Start UseShellExecute)txtlabel21(保固內容).Click:編輯中_GETMEMO 'M211'帶入保固內容WarrantyMemoCommand(DARB_GETDATA4 smemsd 類別編號='M211' 取敘述,限編輯模式)公司代碼 sqlcombotxt c_type=101 TsComboBoxWithDescriptionBySql TableAlias="C101"機器序號/DATECODE/廠牌/停用 ReadOnly 顯示 唯讀 TsTextBox(資料由出貨/批次程序寫入,本表單不編輯) 無審核三欄 不掛集中式審核 SP 依賴:僅
DARB_GETDATA4(已登錄),無需新 SP。未還原項目
- 報表
INVENT1_P(SCX_ORDP)/printclick(DO FORM INVENT_Q查詢視窗)— TODO(VM 註解)。
注意:
TworkReportPluginOfficial\Invent1.cs現況是 BOR 通用報表來源(ReportBll.GetBorReport),與本維護畫面/invent1 資料表無關,未動。
moverec_sk_cursor(SK_CUDATA/SK_INVENT 快取游標)— 新版 view JOIN 取代,不需要
- else1 鈕的
其他1說明/可否其他1為 DBprgsct1設定(取得附件),需 DB 端設定權限,程式端已實作 IOther1
Runtime 未驗
全部畫面/存檔/附件流程僅 build 驗證,未實機開窗測試。
-
06-12 gtrsama-port ▸
2026-06-12 — GTRSAMA G出貨單(C-090)按 VFP 還原
摘要
依 VFP 舊版
GTRSAMA(scx_gen.vcx,1948 行,sqledittr 子類)還原 G出貨單(主檔 trgama 單據別 '3'、明細 trgade)到 Darbware ERP,走
ErpProgramWithDetailViewModel+ItemsBindingManager+ TsView/TsRadGridView 範本(比照對稱單據 Gtrrama G進貨單)。動庫存單據(_sheetno 查庫存=1)→ 存檔走
GinventorySavebase(倉儲/批號/關帳/權限檢核),修改走
GinventoryEditbase(IA 鎖單/關帳/轉出備註已轉應收)。雙編碼(倉單號+單號,前置碼自 Tritem1、編碼方式 3、srno 5)走 AdeBll.AddBll + _sheetno(GTRSAMA 列既有,pkid 52)。
新增
ViewModel/C.GeneralAffair/GtrsamaViewModel.cs
LogicBll/Ade/C.GeneralAffair/GtrsamaSave.cs、GtrsamaEdit.cs
Common/Lang/Xaml/Gtrsama.json(+ Common.csproj Content + TsERP/Lang/Xaml1/Xaml.json 併入)
VFP 行為對照
VFP 新版 d_單據別 = 3.總務出貨;新增預設 交易日期=今日 GtrsamaViewModel.AfterAddNew(單據別='3'、公司代碼=1、幣別=本位幣+匯率1)allowsave:匯率<=0 → U_BLRATE(幣別,'1','買',交易日期)GtrsamaSave.AllowSave→Util2017.U_Blrate(Accounting/Buy)txt數量/txt單價/txt其他金額.Valid:原幣未稅=ROUND(數量×單價,幣別小數位)+其他金額 即時: Twork_gen_vw_gtrsadeSource.數量Binding/單價Binding/其他金額Binding(既有)→ TaxCalculator.SetDetail;存檔再算一次GtrsamaSave.AllowSavesum加總:金額總額=Σ原幣未稅(品號非空白)、本國幣總額=ROUND(總×匯率,小數位) 主檔 總原幣未稅/總本幣未稅(TaxCalculator.SetDetail 即時維護;本次補 OnPropertyChanged 讓畫面合計即時更新);存檔GtrsamaSave.TaxCalculatesqlnm_cu1.代號.Valid(ControlSource=交易部門):SEEK SK_CUDATA 帶 幣別/稅別/運送方式碼/業務員編號 Twork_gen_vw_gtrsamaSource.客戶代號Binding(DescriptionHelper.GetCustomer,有找到才帶;幣別變更由 TsCurrency 自動帶匯率)幣別.LostFocus:匯率=U_BLRATE('1','買') TsCurrency 控件(SearchType 預設 Buy,Date=交易日期) sql_gmno1.LostFocus:品號≠MISC 帶品名/單位;MISC 僅空白帶入;改品號查庫存(DARB_QUERY_STK1 'trgade',LCL_trga_stk_s) 品號Binding→ SetISKU(既有)+IStockQuery(StockQueryKey=明細選取列,新增時 SwitchToStockTab)空白明細(品號空白)刪除 GinventorySave.HandleDataBeforeEndEdit標增刪修='D'(base 既有)交易別碼空白帶預設交易別、倉同儲帶轉入/轉出倉儲、批號管制檢核、關帳日、倉庫權限 GinventorySavebase(同 Gtrrama/Gtrlima)allowedit(無自訂,sqledittr 基底):IA 不可改/關帳/已轉應收鎖單 GtrsamaEdit : GinventoryEdit(空殼承接 base 規則)changeopmode:單位/交易別碼 欄僅 新增/修改/複製 可改 單位=UOM 下拉、交易別碼=lcl_tritem1 下拉(框架編輯模式統一控管可編輯性) grid1 29 欄(依 ColumnOrder) TsRadGridView 29 欄 + pkid(順序照 VFP ColumnOrder;原幣未稅/本幣未稅/單位成本/成本/待轉出倉/待轉入倉/轉帳款數量 唯讀同 VFP Enabled=.F.) CMDELSE1 工作流程(WKFLOW_ADD G出貨單送審)/ CMDELSE2 快速審核 / 流程樣板號 / 審核人員/審核日期/已審核 新版集中式 workflow(_sheetno 聯絡單view=vwcommpr_gtrsama 既有),不另做;審核欄不上畫面(同 Gtrrama) 變更(既有檔案)
Model/Source/C.GeneralAffair/Twork_gen_vw_gtrsamaSource.cs:
-
客戶代號Binding補客戶連動(幣別/稅別/運送方式碼/業務員編號/客戶簡稱)-
總原幣未稅/總本幣未稅改為 Notify 屬性(畫面合計即時更新)Model/LocalDbContext.cs:#region C.總務追加Trgama/TrgadeDbSet
(DbSet 名刻意取 server 表名 trgama/trgade,navigate 寫入的本機 SQLite 表才會與 EF
Set<T>對上;與 Greqma 等不同是因 GTRSAMA 的 _sheetno 表名 ≠ view 名)
TsERP/App.xaml:C.總務 region 追加 Gtrsama DataTemplate(xmlns 既有)
Common/Common.csproj:Gtrsama.json Content
TsERP/Lang/Xaml1/Xaml.json:併入Gtrsama區塊
TsERP/Lang/ClassAliasMap.json:新增Twork_gen_vw_gtrsama(ma/de) Model/Source4 條別名
TsERP/Lang/TableMap.json:trgama/trgade 條目既有未改(指向twork_gen_vw_gtrgama/gtrgade,
該 view/類別不存在=陳年 stale 條目;ItemsBindingManager 上傳不走 TableMap,不影響本單據,僅記錄)
Common/ProgramClass.cs:GTRSAMA 既有,未改
刪除
無(原 Gtrsama.xaml 為英文 stale binding 空殼,整檔重做為中文 binding)。
Breaking Changes
無。
Migration Notes / 未還原項目
- 報表 TODO:VFP 報表程式
GTRSAMA_P(SCX_GENP)(SPDARB_RPT_GTRSAMADB 既有)尚未移植(VM 留 TODO 註解)。
- 信用額度/已用額度:VFP 畫面兩個 unbound sqltext(prg 內無賦值邏輯,疑由外部 moverec 填)→ 不移植,視同 dead control。
- 聯絡單ID/工作流程/審核人員/審核日期/已審核/PKID 系統欄不上畫面(集中式 workflow / 框架管理,同 Gtrrama)。
- 交易別碼下拉:VFP sqlcombo 的 RowSource 由基底依 browsetype(-GTRS) 篩選;新版列出全部 lcl_tritem1(無可靠對應篩選依據),空白時存檔由 lcl_tritem 預設交易別補。
- 品名/單位帶入:
SetISKU走 invent(生產品號)查找,G 專屬品號由TsGSKUSearchColumn選取時帶 Description(同 Gtrrama 既有折衷)。
- grid 唯讀控制細節:VFP 品名/單位 欄位 MISC 才可改 → 新版品名開放編輯(非 MISC 由品號帶入覆寫),從寬處理(同 GREQMA 決策)。
- runtime 未驗(trgama 本機 DB 目前無 單據別='3' 資料;_sheetno GTRSAMA 列、vw_gtrsama/vwcommpr_gtrsama/DARB_BD_GTRSADE 等 DB 物件皆既有,無 DB 變更需求)。
-
06-12 greqma-port ▸
2026-06-12 — GREQMA G請購需求(C-030)按 VFP 還原
摘要
依 VFP 舊版
GREQMA(scx_gen.vcx,1823 行)還原 G請購需求(主檔 greqma + 明細 greqde)到 Darbware ERP,走
ErpProgramWithDetailViewModel+ItemsBindingManager+ TsView/TsRadGridView 範本(比照同模組 Gppurch/Gpurch)。編號走 _sheetno(前置碼 PR、srno 5 碼、主表 view
vw_greqma)。VFP grid2「廠商比價表」(查價鈕
DARB_BIZ_SPPDTG+ 回傳鈕)以GUnitPriceQueryViewModel+GUnitPriceSpecialQuery(含 Return 鈕寫回 預估單價)還原。新增
ViewModel/C.GeneralAffair/GreqmaViewModel.cs
LogicBll/Ade/C.GeneralAffair/GreqmaSave.cs、GreqmaEdit.cs
TsERP/C.GeneralAffair/Greqma.xaml(.cs)
Common/Lang/Xaml/Greqma.json(+ Common.csproj Content + TsERP/Lang/Xaml1/Xaml.json 併入)
VFP 行為對照
VFP 新版 addagain:需求日期=今日、需求人員=USERCODE、需求部門=USER部門代號、採購別=1、倉儲代號=系統參數4001 GreqmaViewModel.AfterAddNew(倉儲代號Context.User.U_Prgpar("4001"))addagain: REPLACE 品號 WITH 'MISC' FOR EMPTY(品號)移至存檔 GreqmaSave.HandleDataBeforeEndEdit:需求數量>0 且 品號空白 → 'MISC'allowedit:轉出備註 非空 → 已轉請購單不得修改 GreqmaEdit.AllowEditHandle→AlreadyTransferedToOtherCannotEditallowsave:需求日期/需求部門/採購別 必填 GreqmaSave.AllowSave逐項 GetInputMessageallowsave:需求數量>0 且 (預訂交期空 或 用途空) → 擋 GreqmaSave.AllowSave(拆成兩則訊息,附 LineNo)allowsave SCAN:明細需求部門空白帶主檔、需求數量<=0 標 'D' GreqmaSave.HandleDataBeforeEndEditsql_gmno1.LostFocus:品號≠MISC 帶品名/單位;MISC 僅空白帶入 Twork_gen_vw_greqdeSource.品號Binding(MISC 保留使用者輸入)txt需求數量/預估單價.Valid:預估金額=ROUND(需求數量×預估單價, 幣別小數位) 需求數量Binding/預估單價Binding→SetAmount()(LocalDecimal,幣別固定本位幣,比照 Gppurch)col預訂交期 Valid:不得小於今日 預訂交期BindingSetErrors(輸入當下驗證,紅框提示)需求人員.代號.Valid:帶部門(VFP 原碼誤寫 G請購單主檔_v.請購部門) 需求人員Binding:GetPerdata 帶 需求部門/姓名/部門簡稱grid1 17 欄(搜尋/全搜鈕除外 15 資料欄) TsRadGridView 16 欄(含 查價 按鈕欄;全搜未做,見下) 查價鈕(DARB_BIZ_SPPDTG,需求日期查價)+ grid2 廠商比價表 + 回傳鈕 查價按鈕欄 → GUnitPriceQueryViewModel.GetDifferentVendorLatestUnitPrice(採購+報價跨廠商);底部GUnitPriceSpecialQueryReturn 鈕寫回 預估單價並重算 預估金額CMDELSE1 工作流程 / CMDELSE2 快速審核 / 流程樣板號 / 審核三欄 新版集中式 workflow,不另做 changeopmode:單位欄僅編輯模式可改、幣別欄停用 幣別欄 ForceReadOnly;單位欄走框架編輯模式控制 grid1.AfterRowColChange:品名僅 MISC 列可改 品名欄開放編輯(非 MISC 由品號帶入覆寫),從寬處理 變更(既有檔案)
Model/Source/C.GeneralAffair/Twork_gen_vw_greqmaSource.cs:新增需求人員Binding(帶部門/姓名)
Model/Source/C.GeneralAffair/Twork_gen_vw_greqdeSource.cs:實作ISKU/IUnitPrice,新增
品號Binding/需求數量Binding/預估單價Binding/預訂交期Binding/SetAmount/單價Binding/數量Model/LocalDbContext.cs:新增#region C.總務(Greqma/Greqde DbSet,置於 D.BOM 前)
TsERP/App.xaml:新增 xmlnsgeneralaffair/generalaffair1+<!--#region C.總務-->(置於 採購管理 後)+ Greqma DataTemplate
Common/Common.csproj:Greqma.json Content
TsERP/Lang/Xaml1/Xaml.json:Greqma區塊
TsERP/Lang/TableMap.json:greqma/greqde 既有條目核對正確(→ Twork_gen_vw_* Model 類名),未改
TsERP/Lang/ClassAliasMap.json:4 條既有別名核對正確,未改
Common/ProgramClass.cs:GREQMA 既有,未改
刪除
無。
Breaking Changes
無。
Migration Notes / 未還原項目
- 報表 TODO:VFP 報表程式
GREQMA_P(SCX_GENP) 尚未移植(VM 留 TODO 註解)。
- 全搜鈕未做:VFP grid Column17「全搜」走
DARB_BIZ_SPPDTG1(無日期上限版查價);新版僅保留 查價(GppurchBll.GetUnitPrice跨廠商最新報價)。
- 公司專屬未做:
IF PUB_公司名稱='朝陽'(品別=5 → 倉儲代號帶 2.物料倉/1.總務倉)為公司專屬邏輯,不移植。
- VFP 隱藏欄位 需求備註/需求說明(2012/02/02 阿美要求隱藏,Visible=.F.)不在畫面呈現;DB 欄位仍在 Source 可日後啟用。
- VFP 查價鈕「需求日期空白 → 請先輸入需求日期」改為以今日代查(不擋)。
- 回傳鈕僅寫回 預估單價(VFP 另帶 幣別;新版明細幣別固定本位幣概念、欄位唯讀,故不帶)。
- 聯絡單ID/工作流程/pkid/審核人員/審核日期/已審核 等系統欄不在畫面呈現(集中式 workflow / 框架管理)。
- runtime 未驗(_sheetno GREQMA 列既有、greqma/greqde/vw_greqma DB 物件既有,無 DB 變更需求)。
-
06-12 gpurama-port ▸
2026-06-12 — GPURAMA G暫收單(C-060)按 VFP 還原
摘要
依 VFP 舊版
GPURAMA(scx_gen.vcx,1508 行)還原 G暫收單(採購到貨暫收;主檔 gpurama + 明細 gpurade)到 Darbware ERP,走
ErpProgramWithDetailViewModel+ItemsBindingManager+ TsView/TsRadGridView 範本(比照同模組 Greqma/Gpurch/Gtrrama)。編號走 _sheetno(前置碼 TP、srno 5 碼、主表 view
vw_gpurama、查庫存=0 →SaveBll不過庫存)。VFP 標籤「廠商代號」實際存欄位
生產部門(sqlnm_sp),照舊保留欄位名、畫面顯示 廠商代號+廠商簡稱(view JOIN)。新增
ViewModel/C.GeneralAffair/GpuramaViewModel.cs
LogicBll/Ade/C.GeneralAffair/GpuramaSave.cs
TsERP/C.GeneralAffair/Gpurama.xaml(.cs)
Common/Lang/Xaml/Gpurama.json(+ Common.csproj Content + TsERP/Lang/Xaml1/Xaml.json 併入)
VFP 行為對照
VFP 新版 addagain:建檔日期=DATETIME() GpuramaViewModel.AfterAddNew(另比照範本帶 公司代碼=1、暫收日期=今日、幣別=本位幣)allowsave:暫收日期/公司代碼 必填 GpuramaSave.AllowSave逐項 GetInputMessageallowsave SCAN:品號空白 或 數量=0 → 增刪修 'D';否則 幣別 空白帶主檔 幣別 GpuramaSave.HandleDataBeforeEndEdit檢驗完畢.Valid:編輯中勾 'Y' → 明細 檢驗日期 空白者補今日 GpuramaViewModel.ReceiveWeakEvent(ListenerHelper 監聽 檢驗完畢)sql_gmno1.LostFocus:品號≠MISC 一律帶 品名/單位;MISC 僅空白帶入 Twork_gen_vw_gpuradeSource.品號Binding(比照 Greqde MISC 模式改寫)sqlnm_sp1(廠商代號→生產部門)帶 廠商簡稱 Twork_gen_vw_gpuramaSource.生產部門Binding(DescriptionHelper.GetVendor)grid1.AfterRowColChange:入庫數量≠0 → 序號/品號/數量/NG數量/特採數量/檢驗日期/檢驗結果/入庫日期 鎖定 Twork_gen_vw_gpuradeSource.CanEdit(整列鎖,見下)grid1 33 欄(依 ColumnOrder) TsRadGridView 33 欄全數還原(含 採購單/派工單/生產單 PKID 唯讀欄) 須否成績表/是否結案(sqloption1)/檢驗完畢(InputMask Y) TsCheckBox + YesNoConverter moverec_sk_cursor(SK_SPDATA/SK_GINVENT seek 快取) 不需要:廠商簡稱 由 vw_gpurama JOIN、品名 走 DescriptionHelper CMDELSE1 工作流程(WKFLOW_ADD G暫收單送審)/ CMDELSE2 快速審核(已註解) 新版集中式 workflow,不另做 changeopmode:col是否結案 須程式備註(IS_備註)含「結案」才開放 未還原 per-program 備註開關,編輯模式恆開放(見未還原) 變更(既有檔案)
Model/Source/C.GeneralAffair/Twork_gen_vw_gpuramaSource.cs:新增生產部門Binding(帶 廠商簡稱)
Model/Source/C.GeneralAffair/Twork_gen_vw_gpuradeSource.cs:
-
品號Binding改 MISC 模式(非 MISC 強制帶 品名/單位;MISC 僅空白帶入)-
CanEdit由鋪底的採購單pkid <= 0改為入庫數量 == 0(VFP 採轉暫收列仍可登打檢驗結果,已入庫才鎖)Model/LocalDbContext.cs:#region C.總務追加 Gpurama/Gpurade DbSet
TsERP/App.xaml:<!--#region C.總務-->追加 Gpurama DataTemplate
Common/Common.csproj:Gpurama.json Content
TsERP/Lang/Xaml1/Xaml.json:Gpurama區塊
TsERP/Lang/TableMap.json:gpurama/gpurade 既有條目核對正確(→ twork_gen_vw_*),未改
TsERP/Lang/ClassAliasMap.json:4 條既有別名核對正確,未改
Common/ProgramClass.cs:GPURAMA 既有,未改
刪除
無。
Breaking Changes
無。
Migration Notes / 未還原項目
- CMDELSE3 採轉暫收未移植:VFP
DO FORM PUTOTP WITH '4'(採購單轉暫收挑單);新版 Gputora(採購轉進貨)無 '4' 暫收模式,
需另開轉單功能(比照 GputoraViewModel 增加目的單據參數),列為功能缺口。
- 報表 TODO:VFP 報表程式
GPURAMA_P(SCX_GENP) 尚未移植(VM 留 TODO 註解)。
- 是否結案欄開關:VFP 依程式備註(IS_備註 含「結案」)決定該欄可否編輯,屬 per-program 客製設定;新版編輯模式恆開放。
- 列鎖定粒度:VFP 入庫數量≠0 僅鎖 8 個欄位(備註/問題點/確認/儲位等仍可改);新版以
CanEdit整列鎖定,從嚴處理。
- VFP 畫面的 pkid / 輸入日期 唯讀欄位不另呈現(框架/審核軌跡管理)。
- 明細 單價/金額/幣別/最小包裝數/外箱數量 欄位(gpurade 有、VFP grid 未顯示)不上畫面;單價×數量→金額 既有 Binding 保留。
- 主檔 採購別/聯絡單id/工作流程 欄位 VFP 未顯示,不上畫面。
- vw_gpurama 無 審核人員/審核日期/已審核 欄(vw_greqma 有);Source 鋪底的這 3 個屬性保留(載入/上傳皆容錯),
若日後要掛集中式審核需先擴充 view。
- runtime 未驗(_sheetno GPURAMA 列既有、gpurama/gpurade/vw_gpurama DB 物件既有,無 DB 變更需求)。
-
06-12 ginvrec-port ▸
2026-06-12 — GINVREC G盤點單(C-130)按 VFP 還原
摘要
依 VFP 舊版
GINVREC(scx_gen.vcx,1363 行)還原 G盤點單(主檔 ginvrecm + 明細 ginvrecd)到 Darbware ERP,走
ErpProgramWithDetailViewModel+ItemsBindingManager+ TsView/TsRadGridView 範本,行為比照同構的 H.Inventory
INVREC(盤點單 H-110)新版實作。編號走 _sheetno(無前置碼、編碼方式 1、srno 5 碼、無主表 view,以實體表 ginvrecm/ginvrecd 為準)。
三顆其他鈕(重算帳列/執行確認/轉盤點單)走
LOG_SYS_INPUT(DARB_LOG_GINVREC_RECOUNT/CONFIRM/TO_AA);「新增查詢」(VFP
DO FORM GINVREC_M)以GinvrecmViewModel彈窗還原,走DARB_GINVREC(帶入庫存產生盤點資料)。新增
ViewModel/C.GeneralAffair/GinvrecViewModel.cs(IOther1/2/3;報表 TODO 註解)
ViewModel/C.GeneralAffair/GinvrecmViewModel.cs(新增查詢彈窗,ERPProgramContentWindowViewModel + ShowContentWindow)
LogicBll/Ade/C.GeneralAffair/GinvrecSave.cs、GinvrecEdit.cs
LogicBll/C.GeneralAffair/Ginvrec/GinvrecBll.cs(DARB_LOG_GINVREC_* 三支 SP 呼叫)
TsERP/C.GeneralAffair/Ginvrec.xaml(.cs)、Ginvrecm.xaml(.cs)
Common/Lang/Xaml/Ginvrec.json(+ Common.csproj Content + TsERP/Lang/Xaml1/Xaml.json 併入)
VFP 行為對照
VFP 新版 allowsave:製單日期=' ' OR EMPTY(隸屬倉庫) → 請先輸入製單日期及隸屬倉庫 GinvrecSave.AllowSave逐項 GetInputMessageallowsave:REPLACE 增刪修 'D' FOR EMPTY(倉儲代號) AND EMPTY(品號) GinvrecSave.AllowSave/HandleDataBeforeEndEdit(AND 條件照舊版)盤點別.Valid:請輸入 0 或 1 GinvrecSave.AllowSave(存檔把關 + DataIsIncorrect 訊息)allowedit:盤點備註 非空(已轉盤點調整單)→ 不得刪除、修改 GinvrecEdit.AllowEditHandle→AlreadyTransferedToOtherCannotEditelse1click 重算帳列(DARB_LOG_GINVREC_RECOUNT + 放行碼) IOther1.ExtendedFunction1→GinvrecBll.RecalculateQuantityelse2click 執行確認(DARB_LOG_GINVREC_CONFIRM) IOther2.ExtendedFunction2→GinvrecBll.ConfirmQuantityelse3click 轉盤點單(帳列數≠確認盤點數 才可、YesNo 確認、DARB_LOG_GINVREC_TO_AA → trgama 'AA' 單) IOther3.ExtendedFunction3→GinvrecBll.TransferToInventoryAdjustDocument(QuantityAndConfirmedQuantityIsEqual / TransferToInventoryAdjustDocument 訊息)else1/2/3 共同把關:盤點單號未輸入 / 盤點備註非空不得再執行 / ALLOWEDITBASIC 放行碼 GinvrecViewModel.CheckData(IsDataExist + GetPassNumber)else4click 快速審核 / 工作流程 / 審核三欄 新版集中式 workflow,不另做 查詢鈕「新增查詢」:IF OPMODE=1 → DO FORM GINVREC_M AddNewCommand(僅 Add 狀態可執行)→GinvrecmViewModel彈窗GINVREC_M(原始 scx 不可得)→ DARB_GINVREC(篩選別/品號條件/數量別/製單日期/隸屬倉庫/起訖倉儲/異動天數/隨機數) 彈窗 UI 按 SP 參數還原(篩選別 1全部/2品號/3群組/4品別/5儲位/6異動天數/7隨機;數量別 1全部/2≠0/3<0),查詢後回寫主檔 製單日期/隸屬倉庫 並重建明細(盤點卡號 依序編號) sql_gmno1.LostFocus:品號≠MISC 帶品名/單位;MISC 僅空白帶入 Twork_gen_vw_ginvrecdSource.品號Binding(比照 greqde/gcostd)grid 計算欄:初盤差異量=初盤數-帳列數、額=ROUND(量*單位成本,0);複盤/抽盤=IIF(EMPTY(x),0,VAL(x)-帳列數)(Valid 寫回已註解) 初盤數Binding/複盤數Binding/抽盤數Binding輸入當下回寫實體差異欄(比照 H.Inventory Invrec 新版)複盤數/抽盤數 文字欄(InputMask X12,VAL 計算) 維持 string 欄 + TsGridViewDataColumn,差異計算 decimal.TryParse(VAL 語意,非數字=0) changeopmode:單位欄僅編輯可改、品名瀏覽唯讀 框架編輯模式控制(單位 = TsGridViewComboBoxColumn + GetUOM,VFP sqlcombo c_type=104) 盤調單pkid(盤點調整單) 唯讀 + IsHyperLink → GTRLIMA(TO_AA 產生 trgama 單據別 2 'AA') grid1 23 欄(依 ColumnOrder) TsRadGridView 23 欄全還原;帳列數/確認盤點數/差異 6 欄/單位成本 唯讀;差異額 3 欄+單位成本 依檢視單價權限顯示(比照 H Invrec 新版) 變更(既有檔案)
Model/Source/C.GeneralAffair/Twork_gen_vw_ginvrecdSource.cs:實作ISKU,新增
品號Binding/初盤數Binding/複盤數Binding/抽盤數Binding(含 VAL 語意解析);既有屬性未動Model/LocalDbContext.cs:#region C.總務追加 Ginvrecm/Ginvrecd DbSet
Common/DataBaseObjectEnum/Procedure.cs:新增DARB_GINVREC、DARB_LOG_GINVREC_RECOUNT/CONFIRM/TO_AA
TsERP/App.xaml:C.總務 region 追加 Ginvrec + Ginvrecm DataTemplate
Common/Common.csproj:Ginvrec.json Content
TsERP/Lang/Xaml1/Xaml.json:Ginvrec區塊
TsERP/Lang/TableMap.json:ginvrecm/ginvrecd 既有條目核對正確(→ twork_gen_vw_*),未改
TsERP/Lang/ClassAliasMap.json:4 條既有別名核對正確,未改
Common/ProgramClass.cs:GINVREC 既有(line 212),未改
刪除
無。
Breaking Changes
無。
Migration Notes / 未還原項目
- 報表 TODO:VFP 報表程式
GINVREC_P(SCX_GENP)(DB 另有DARB_RPT_GINVREC)尚未移植(VM 留 TODO 註解)。
- 匯出鈕「測試匯出」不移植:VFP
COPY TO C:\TEMPS\G盤點單為測試碼。
- GINVREC_M.scx 原始檔不可得:彈窗 UI 依
DARB_GINVRECSP 參數 + 同構 H.InventoryInvrecm還原;
H 版查詢後另補 100 張空白盤點卡,G 版不補(VFP G allowsave 會把 倉儲代號+品號 全空列標 'D',空白卡存不下來)。
- 品別篩選以文字輸入(H 版用 C204 代碼表 combo;G ginvent 品別 對應代碼表未確認,避免掛錯 alias)。
- 品號帶品名/單位(鍵盤輸入路徑)沿用模組既有
DescriptionHelper.GetInvent/SetISKU,查的是vwseek_invent(B 品號檔)而非vwseek_ginvent(G 品號檔)——greqde/gcostd/gpurch 同此模式(搜尋欄 TsGSKUSearchColumn 本身查 G 表,挑選路徑正確);如 G 品號不在 B 品號檔,鍵入後不自動帶品名,屬模組既有行為。
- txt初盤數/抽盤數/複盤數.Valid 在 VFP 已整段註解(差異欄寫回停用);新版比照 H Invrec 於輸入當下寫回實體差異欄(display 與 stored 一致化)。
- VFP 隱藏系統欄 聯絡單ID/工作流程/pkid/審核人員/審核日期/已審核 不在畫面呈現(集中式 workflow / 框架管理)。
- 公司專屬邏輯:本支 VFP 無
PUB_公司名稱分支。
- dead column:ginvrecd.儲位/品別/群組代號 在 VFP grid 不顯示(由 GINVREC_M 查詢塞值);新版同樣不顯示但查詢時照塞。
- runtime 未驗(DB 物件 ginvrecm/ginvrecd/DARB_GINVREC*/DARB_LOG_GINVREC_* 與 _sheetno GINVREC 列皆既有,無 DB 變更需求)。
-
06-12 ginvbook-port ▸
2026-06-12 — GINVBOOK G庫存帳冊(C-100)按 VFP 還原
摘要
依 VFP 舊版
GINVBOOK(scx_gen.vcx,3582 行,sql_qrya 查詢程式)還原 G庫存帳冊到 Darbware ERP,走
ERPProgramWithQueryViewModel<DefaultParameters, DefaultQueryCondition>+SqlQry查詢程式範本(比照 Invbk1 庫存帳冊)。純查詢程式,不在 _sheetno、無 Source/DataManager(Dapper DataSet → Poco),不動 TableMap/LocalDbContext/ClassAliasMap。
兩支既有 SP(darbnogicsa1,proc_param 已登錄,本次核對簽章與 VFP 呼叫一致,無需修正腳本):
DARB_GINVBOOK(6 參數:隸屬倉庫/品號條件/起迄倉儲/起迄日期;5 個結果集)— 分類進出帳,
每個範圍內 gstkbas 隸屬倉庫呼叫一次,期初(最近 gcostm 成本月份+期前 trgama 異動)/明細拆轉入轉出/結餘 由 client 計算
DARB_GINVBOOK1(7 參數:起迄倉庫/品號條件/起迄倉儲/起迄日期;1 個結果集)— 日記帳,單號 RD 開頭列 數量/其他金額/金額 取負
新增
LogicBll/C.GeneralAffair/Ginvbook/GinvbookBll.cs(含 條件別/單據別/索引別 三個 enum)
LogicBll/C.GeneralAffair/Ginvbook/GinvbookSqlPocos.cs(DARB_GINVBOOK 5 個結果集 Poco)
LogicBll/C.GeneralAffair/Ginvbook/GinvbookMaster.cs、GinvbookDetail.cs(GINVBKM/GINVBKD cursor 對應)
LogicBll/C.GeneralAffair/Ginvbook/GinvbookDetail2Poco.cs(GINVBKD2 日記帳)
ViewModel/C.GeneralAffair/GinvbookViewModel.cs
TsERP/C.GeneralAffair/Ginvbook.xaml(.cs)(TsView + SqlQry 條件區 + 兩個 Tab:分類進出帳 主明細 grid、日記帳 grid)
Common/Lang/Xaml/Ginvbook.json(61 keys;+ Common.csproj Content + TsERP/Lang/Xaml1/Xaml.json 併入)
VFP 行為對照
VFP 新版 Init:起始/截止倉庫=sk_gstkbas 第一筆、倉儲/品號/群組/儲位 ''~'zzzzzz'、日期=今日~今日 GinvbookViewModelctor(GetGstkbas 第一筆)+GinvbookBll屬性預設值起始倉庫.LostFocus → 帶入截止倉庫 起始倉庫setter(非空白即帶)查詢鈕:起迄倉庫皆空 → 擋;查無隸屬倉庫 → 擋 CheckWarehouse()(兩則 VFP 訊息)條件別(品號/群組代號)組 L_品號條件+儲位範圍 GinvbookBll.Query/QueryJournal條件字串(同 VFP 字面)每個隸屬倉庫 LOG_SYS_EXEC('GINVBOOK','DARB_GINVBOOK',6 參數) Log_Sys_Exec(out _, "GINVBOOK", Procedure.DARB_GINVBOOK.Name, ...)TMP品名(RS0∪RS1∪RS2 抓品名/單位) dic品名(首見先贏)不分儲位/不分工程/不分批號 → 鍵值合併(倉儲→隸屬倉庫、途程/工程/批號別→空白、批號→0) ProcessWarehouse對 master/明細/成本表/期前表 一致套用GINVBKD:SQLRESULT2 拆 轉入/轉出 兩列,不在 #depotno 的倉儲不出列 CreateDetail×2(dic倉儲 lookup 失敗即跳過)期初數量=TMP成本表.期初+TMP期前表.(入庫-出庫);期初<>0 或 有明細 → 補「 期 初」明細列 ProcessWarehouse主表迴圈(期初列 交易日期=' 期 初',結餘=期初)3.計算交易進出明細:單號 AA 開頭=盤差,其餘入/出庫;逐列結餘 CalculateRunningBalance(OrderKey:期初列最先→交易日期→入庫先於出庫)期末數量/金額 = 期初+入庫-出庫+盤差 GinvbookMaster.期末數量/期末金額computed property期末不為0 → 刪期末=0;否則刪全零且明細≤1(2016/07/21 一筆期初也過濾) DeleteMaster(multiDetailKeys = 明細筆數>1 的 key)分類1~6(grpm)+尺寸(gitemspec 分類='尺寸') Set分類(資料保留供 Excel 匯出;VFP grid 本來就不顯示,僅模具表報表用)品號結尾:每品號群組最後一筆=.T. Set品號結尾索引別(倉庫排序/品號排序),查詢後重設=倉庫排序 索引別enum 屬性(切換即重排 Master);Query()重設日記帳查詢鈕:DARB_GINVBOOK1(7 參數);單據別=進貨 → + LEFT(a.單號,2) IN ('RC','RD','MG');RD 取負;SET ORDER TO 品號QueryJournal(StartsWith("RD") 取負、OrderBy 品號);單據別預設=進貨(VFP Value=2)GINVBKM↔GINVBKD SET RELATION(鍵=隸屬倉庫+倉儲代號+品號+其他鍵) SelectedMaster→Key→dic(ToDictionaryList)切 DetailEXCEL 匯出(U_ToExcel) IExcel.GenerateExcel(分類進出帳/進出明細/日記帳 三張工作表)變更(既有檔案)
Common/ProgramClass.cs:新增GINVBOOK(GCOST 與 GINVENT 之間,字母序)
Common/DataBaseObjectEnum/Procedure.cs:新增DARB_GINVBOOK、DARB_GINVBOOK1
TsERP/App.xaml:C.總務 region 追加 Ginvbook DataTemplate
Common/Common.csproj:Ginvbook.json Content
TsERP/Lang/Xaml1/Xaml.json:Ginvbook區塊(61 keys)
刪除
無。
Breaking Changes
無(純新增)。
Migration Notes / 未還原項目
- DB 無變更:兩支 SP 既存且 proc_param 已登錄(DARB_GINVBOOK param_qty=6、DARB_GINVBOOK1 param_qty=7,databaseid=C);
本次核對 SP 參數順序/型別與 VFP 呼叫一致、回傳欄位與 Poco 一致,不需 ginvbook-sp.sql。
- 報表 TODO:VFP 報表選擇(明細
GINVBOOK1/ 彙總GINVBK1M/ 模具表GINVBKMD,含 2013/04/22 鈞寶模具
TMPMOLDSTOCK 母模/上模/下模/中棒 統計).frx 未移植(VM 留 TODO 註解)。
- 樞紐分析鈕未移植:VFP 分析鈕走本機
LCL樞紐分析表+ Excel 樞紐檔(GETOBJECT EXCEL.APPLICATION),
屬舊機制;新版 SqlQry 框架內建 PivotSelector 取代。
- 條件區合併:VFP 有兩組獨立條件(PF1.Page1 分類進出帳、PF.Page2 日記帳,後者倉庫預設 ''~'zzzzzz');
新版合併為一組共用條件(預設值取 PF1:倉庫=第一筆 gstkbas)。日記帳要查全部倉庫時請自行放寬起迄倉庫。
- VFP dead column 不移植(VFP 也從未填值,永遠空白):
- 主表:品別/舊品號/群組代號/說明/儲位/現有數量/現有金額/標準成本/新增備註/起始~截止 條件回填欄
- 明細:材料成本/人工成本/加工金額/製造費用/轉入單號/派工單號
- 日記帳:採購單號(SP 只回傳 採購單pkid)
- VFP 起迄倉庫空白訊息原文「請先輸入起迄倉儲代號」為舊版筆誤(檢查的是倉庫欄位),新版訊息改為「起迄倉庫代號」。
- 公司專屬邏輯:模具表(鈞寶)僅在報表層,未涉及;無其他
IF PUB_公司名稱分支。
- runtime 未驗(build 綠燈:Common/LogicBll/ViewModel;TsERP.csproj XAML 編譯由主線統一跑)。
-
06-12 gcost-port ▸
2026-06-12 — GCOST G成本表(C-120)按 VFP 還原
摘要
依 VFP 舊版
GCOST(scx_gen.vcx,2420 行)還原 G成本表(主檔 gcostm + 明細 gcostd)到 Darbware ERP,走
ErpProgramWithDetailViewModel+ItemsBindingManager+ TsView/TsRadGridView 範本(比照同模組 Greqma/Gpurama)。本單據 _sheetno 無前置碼/無編碼方式/srno=0、無主表 view:單號 = 年度月份(使用者輸入鍵值,
InputMask
9999/99、is_noduplicate="gcostm"重複檢查、僅新增模式可輸入)。明細為 76 欄成本彙總 grid(倉儲交易 數/金 對 + 單位成本/計算成本/平均單價 + 期末與完工 材料/人工/製費/加工)。
新增
ViewModel/C.GeneralAffair/GcostViewModel.cs
LogicBll/Ade/C.GeneralAffair/GcostSave.cs
TsERP/C.GeneralAffair/Gcost.xaml(.cs)
Common/Lang/Xaml/Gcost.json(+ Common.csproj Content + TsERP/Lang/Xaml1/Xaml.json 併入)
VFP 行為對照
VFP 新版 年度月份 InputMask="9999/99"、dovalid=1 GcostSave.AllowSave:必填 + 格式 `^\d{4}/(0[1-9]1[0-2])$` 驗證 年度月份 is_noduplicate="gcostm"GcostSave.IsDocNoDuplicate:DARB_GETDATA4查 gcostm年度月份=N'..' AND pkid<>..(比照 EstsalSave)changeopmode:OPMODE=1(新增) 年度月份 ENABLED,其餘停用 GcostViewModel.YearMonthIsEnabled(AdeViewModel.Status 監聽);新版 Copy 也開放(鍵值需重新輸入,否則必撞重複檢查)allowsave: REPLACE 增刪修 WITH 'D' FOR EMPTY(倉儲代號) OR EMPTY(品號) OR EMPTY(隸屬倉庫)GcostSave.MarkEmptyDetailDeleted(AllowSave + HandleDataBeforeEndEdit)+Twork_gen_vw_gcostdSource.NeedDeleteFunctionsql_gmno1.LostFocus:品號≠MISC 一律帶品名(U_SEEKNM SK_GINVENT);MISC 僅品名空白帶入 Twork_gen_vw_gcostdSource.品號Binding(Context.DescriptionHelper.GetInvent,比照 greqde)grid1 76 欄(依 ColumnOrder:隸屬倉庫→倉儲代號→品號→途程序號→工程代號→…→完工加工) TsRadGridView 76 欄同序還原;數量欄 PlaceEnum=PurchaseQuantity、金額欄Local、單位成本/計算成本/平均單價UnitCost倉儲代號 sql_gsplaceno / 品號 sql_gmno / 工程代號 sql_procno 搜尋欄 TsGBinSearchColumn/TsGSKUSearchColumn/TsProcessingSearchColumn隸屬倉庫 sql_gstkbas 搜尋欄 一般 TsGridViewDataColumn(grid 無 G倉庫 搜尋欄型,見未還原)無 addagain(主檔無預設值) 不實作 IAdd(年度月份由使用者輸入) else1click 倉庫表導入(DO FORM gsplace) VFP 原碼已整段註解 = dead code,不移植 變更(既有檔案)
Model/Source/C.GeneralAffair/Twork_gen_vw_gcostdSource.cs:新增品號Binding(MISC 邏輯)+NeedDeleteFunction(三欄任一空白)
Model/LocalDbContext.cs:#region C.總務內新增 Gcostm/Gcostd DbSet
TsERP/App.xaml:C.總務 region 內新增 Gcost DataTemplate
Common/Common.csproj:Gcost.json Content
TsERP/Lang/Xaml1/Xaml.json:Gcost區塊(80 鍵)
TsERP/Lang/TableMap.json:gcostm/gcostd 既有條目核對正確(→ twork_gen_vw_gcostm/gcostd),未改
TsERP/Lang/ClassAliasMap.json:4 條既有別名核對正確,未改
Common/ProgramClass.cs:GCOST 既有,未改
Model/Source/C.GeneralAffair/Twork_gen_vw_gcostmSource.cs:與 DB gcostm 比對,業務欄(年度月份)已齊;既有
建檔日期/已審核/審核日期/審核人員/工作流程/聯絡單id 屬性保留未動(DB 實體表無此 6 欄,見 Migration Notes)
刪除
無。
Breaking Changes
無。
Migration Notes / 未還原項目
- 報表 TODO:VFP 報表程式
GCOST_P(SCX_GENP) 尚未移植(VM 留 TODO 註解)。
- 隸屬倉庫 grid 搜尋欄:VFP 為 sql_gstkbas(G倉庫)搜尋控件;TsControl 無對應的 G倉庫 grid 搜尋欄型
(TsWarehouseSearchColumn 指向 H 模組 stkbas),暫以一般文字欄還原,待補欄型後再換。
- 倉儲代號搜尋未帶隸屬倉庫過濾:VFP sql_gsplaceno 依列上 隸屬倉庫 過濾;
TsGBinSearchColumn.FilterCondition
既有用法只支援 MasterItem 層級(Gtrinout 模式),明細列級過濾暫不掛,搜尋顯示全部 G倉儲位置。
- gcostm 無審核/工作流程欄位:DB 實體表 gcostm 只有 年度月份 + 系統欄;既有 Source 的
建檔日期/已審核/審核日期/審核人員/工作流程/聯絡單id 屬性保留(audit 欄框架慣例,上傳走 XML/SP 映射),
但畫面不呈現、不掛集中式審核(審核三欄在 DB 不存在)。
- changeopmode 差異:VFP 僅 OPMODE=1 開放 年度月份;新版 Copy 模式也開放(複製後鍵值必須改,否則重複檢查擋存檔)。
- 年度月份格式驗證訊息(YYYY/MM)為新版補強(VFP 靠 InputMask 限制輸入,無訊息)。
- runtime 未驗(gcostm/gcostd DB 物件既有、TableMap/_sheetno 列既有,無 DB 變更需求)。
-
06-12 estsal-port ▸
2026-06-12 — ESTSAL 年度預估(E-950)按 VFP 還原
摘要
依 VFP 舊版
ESTSAL(scx_ord.vcx,646 行)完美還原年度預估 主明細表單到 Darbware ERP,走
ErpProgramWithDetailViewModel+ItemsBindingManager+ TsView/TsRadGridView 最新範本(比照 Claim)。主檔
estsalm(DB 無 vw_estsalm,直接綁資料表)、明細走vw_estsaldview(JOIN invent 帶 品名)。新增
Common/Model/E.Order/EstsalmModel.cs、Twork_ord_vw_estsaldModel.cs
Model/Source/E.Order/EstsalmSource.cs、Twork_ord_vw_estsaldSource.cs
LogicBll/Ade/E.Order/EstsalSave.cs
ViewModel/E.Order/EstsalViewModel.cs
TsERP/E.Order/Estsal.xaml(.cs)
Common/Lang/Xaml/Estsal.json(+ Common.csproj Content)
VFP 行為對照
VFP 新版 addagain: REPLACE 幣別 WITH m.指定幣別, 匯率 WITH 1EstsalViewModel.AfterAddNew(IAdd):幣別=Context.Env.LocalCurrency、匯率=1(VFP 指定幣別=本位幣)allowsave:年度/年預估分類/版次/客廠部代號 必填 EstsalSave.AllowSave逐項 GetInputMessage(年預估分類 int → ==0 視為空)單號 is_noduplicate="estsalm"EstsalSave.IsDocNoDuplicate:DARB_GETDATA4 查 estsalm單號=N'x' AND pkid<>current;另補單號必填(_sheetno 無編碼方式,空白單號無法存)allowsave: EMPTY(品號)→ 增刪修 'D'NeedDeleteFunction+MarkEmptyDetailDeleted雙保險grid sql_mno1dovalid=1(品號驗證帶品名)Twork_ord_vw_estsaldSource.品號Binding→SetSkuData(),查無→「查無品號 !!!」grid Column9 U_SEEKNM('SK_INVENT',品號,'品名')+moverec_sk_cursor明細直接走 vw_estsald.品名(navigate 載入即有),編輯時 SetSkuData 重抓grid col單位 sqlcombo c_type=104(changeopmode 控 enable) TsGridViewComboBoxColumn+ComboBoxItemsSource.GetUOM()(Cmb_C104);編輯閘門由 grid 全域 Ade 狀態控制客廠部代號 sqlnm_cuspdp1(代號+簡稱) 客廠部代號Binding+ CuspSearch 樣式,簡稱走DescriptionHelper.GetCustVendDeptName計算屬性幣別 sqlcombo c_type=1 TsCurrency數量 mask .9999 / 單價 mask .999999 / 匯率 mask .9999 PlaceEnum FourPlace / SixPlace / FXRate 輸入日期/審核人員/審核日期 唯讀(txt_color=2) XAML IsReadOnly=True 變更(既有檔案)
TsERP/Lang/TableMap.json:修正預留映射 —
"estsalm": "twork_ord_vw_estsalm"→"estsalm"(DB 無該 view)、"estsald": "twork_ord_vw_estsald"→"vw_estsald"(DB 實際 view 名)TsERP/Lang/ClassAliasMap.json:Twork_ord_vw_estsalm*預留別名改為Estsalm*(照表名命名);
Twork_ord_vw_estsald*預留別名沿用(view 存在)Model/LocalDbContext.cs:DbSet<EstsalmSource> Estsalm、DbSet<Twork_ord_vw_estsaldSource> Estsald
TsERP/App.xaml:EstsalViewModel DataTemplate
TsERP/Lang/Xaml1/Xaml.json:Estsal區塊
Common/ProgramClass.cs:ESTSAL既有,未改
刪除
無。
Breaking Changes
無。
Migration Notes / 未還原項目
- 報表 TODO:VFP 報表程式
ESTSAL_P(SCX_ORDP) 尚未移植。
- 跨單據整合 TODO:preord 預示表的 estsal 補充數量機制(
PreordControlViewModel既有待辦)本次只還原單據本體,整合另案處理(VM 註解已標 TODO)。
- estsalm 僅有 審核人員/審核日期 兩欄、無 已審核 欄 → 依「審核三欄才掛」原則不掛集中式審核,兩欄唯讀顯示。
- VFP 註解掉的單號自動組碼(年度+分類+版次+客廠部代號)為 dead code,未還原。
- runtime 未驗。
-
06-12 darb-sp-repoint ▸
2026-06-12 六支轉單/查詢改接 VFP 原版 DARB SP(TWORK 新版不移植)
摘要
C# 端有 6 個呼叫點指向資料庫不存在的
TWORK_*SP(從未部署,功能開窗即錯)。**使用者裁定:不移植 TWORK 新版 SP,直接改接 darbnogicsa1 既有的 VFP 原版
DARB_*SP。**程式 原呼叫(不存在) 改接(darbnogicsa1 既有) 庫存帳冊 Invbk1 TWORK_INVBK1DARB_INVBK1(6 參數 9 結果集)庫存查詢 Qry_Invstk TWORK_QRY_INVSTKDARB_QRY_INVSTK(2 參數)備料呆滯轉單 Trlost_A TWORK_TUR_TRLOST_ADARB_TUR_TRLOST_A(2 參數)總務請轉採 Gpptopu TWORK_TUR_GPPTOPUDARB_TUR_GPPTOPU(2 參數)總務倉庫關帳 Gstkbas_1 TWORK_TUR_GSTKBASDARB_TUR_GSTKBAS(2 參數)G申請出入轉交易單 GtrapplyToGtrlima TWORK_TUR_GTRAPPLYTOGTRLIMA<br>TWORK_QRY_GTRAPPLYPICKDARB_TUR_GTRINOUTE(2 參數)<br>DARB_TUR_GSPLACE@查詢別=2(挑單庫存)決策依據
- Gpptopu 選
DARB_TUR_GPPTOPU而非已登錄的DARB_TUR_GPPTOPU1:
vfpcode/scx_gen.prggpurchelse3click:IF .T. → DO FORM GPPTOPU(2018/03/12 起設為預設),GPPTOPU1 為備用分支(
gpptopu1.prgdatafunc=DARB_TUR_GPPTOPU1)。照 VFP 實際使用者選 GPPTOPU。- GtrapplyToGtrlima 挑單:VFP GTRINOUTE 表單原始碼不在 repo、DB 也無任何 pick SP;
挑單庫存改用已登錄的
DARB_TUR_GSPLACE查詢別=2(gstkbas/gsplace/ginvstk JOIN,總務庫存),以該申請單品號
IN (...)過濾,與 SplaceBll 既有用法同模式。變更
行為(使用者可見)
- 上述 6 支功能由「開窗查詢即 SP 不存在錯誤」變為可正常查詢/轉單(runtime 未驗收)。
- Gpptopu 篩選:
DARB_TUR_GPPTOPUWHERE 為固定條件(轉出備註空、數量>已訂購、廠商代號非空、未結案),
忽略
@查詢條件;畫面的請購單號/請購日期範圍改在 client 端過濾,結果等價。- Gpptopu 廠商品號:原版 SP 結果無
廠商品號欄,轉出之採購明細該欄為空(VFP 原版同)。
- GtrapplyToGtrlima 挑單:
- 庫存來源為總務
ginvstk(原 TWORK 設計疑似查產銷存 invstk,無從對證——SP 從未存在)。-
ForCustomerCode(工程代號保留客戶)原版查詢無此欄→空字串:帶工程代號的庫存不會自動配置,仍會列在挑單畫面供手動挑。
-
QuantityPerCarton(箱數)gtrinoutd 無此欄→0,轉出 trlist.箱數=0。- 庫存列無交易日期(ginvstk 無此欄),同數量時排序略有差異。
- Qry_Invstk:DARB 版第 3 結果集(採購未入/訂單未交)與第 5 結果集(暫收明細)無
隸屬倉庫欄;
「指定倉庫」(WarehouseOnly)非 all 時這兩類列會被 client filter 全濾掉(原 TWORK 合約無從對證,先按原版)。
程式
Common/DataBaseObjectEnum/Procedure.cs:
- 新增
DARB_INVBK1、DARB_QRY_INVSTK、DARB_TUR_TRLOST_A、DARB_TUR_GPPTOPU、DARB_TUR_GSTKBAS、DARB_TUR_GTRINOUTE、DARB_TUR_GSPLACE。- 移除 7 個無其他引用的死 enum:
TWORK_INVBK1、TWORK_QRY_INVSTK、TWORK_TUR_TRLOST_A、TWORK_TUR_GPPTOPU、TWORK_TUR_GSTKBAS、TWORK_TUR_GTRAPPLYTOGTRLIMA、TWORK_QRY_GTRAPPLYPICK。LogicBll/C.GeneralAffair/Gpptopu/GpptopuBll.cs:主子合併單表 → 依請購單號拆 Master/Detail
(合成 pkid/linkid;子檔 pkid←請購pkid、序號←請購序號)+ client 端範圍過濾。
LogicBll/C.GeneralAffair/Gpptopu/GpptopuLockedSource.cs:補中文TsColumnName映射。
LogicBll/C.GeneralAffair/GtrapplyToGtrlima/GtrapplyToGtrlimaBll.cs:改接 + 依申請單號合成 pkid_m
+挑單改
DARB_TUR_GSPLACE(隸屬倉庫由OpenDbfTable.GetGsplace()對照補上)。LogicBll/C.GeneralAffair/GtrapplyToGtrlima/GtrapplyToGtrlimaPoco.cs:補中文TsColumnName映射。
LogicBll/C.GeneralAffair/GtrapplyToGtrlima/Twork_qry_gtrapplypickPoco.cs:set-only 中文別名屬性
承接 倉儲代號/品號/現有數量(基底為共用 picking poco 不便加屬性標記)。
LogicBll/C.GeneralAffair/Gstkbas_1/Stkbas_1TmpPoco.cs:EditingUser補[TsColumnName("修改人員")]。
LogicBll/H.Inventory/Qry_Invstk/Tmp.cs:品別int→byte、leadtimeint→short
(DB 為 tinyint/smallint,DataTable→Poco 映射不做數值轉型,原型別 runtime 會丟 ArgumentException)。
Invbk1Bll.cs/InvstkBll.cs/Trlost_ABll.cs/Gstkbas_1Bll.cs:SP 名改接(參數/結果集既已對齊 DARB 中文欄名)。
待辦(不要執行 DB 寫入,主線跑)
.claude/tmp/proc-param-register.sql:DARB_TUR_GPPTOPU、DARB_TUR_GSTKBAS兩筆 proc_param 登錄
(其餘 5 支已登錄)。未登錄前這兩支轉單仍會失敗。
- 6 支表單 runtime 驗收(本批次僅靜態對齊+build 綠燈)。
Migration Notes
- 已刪除
.claude/tmp/scx_stk/TWORK_TUR_TRLOST_A.sql(原擬新建 SP 的草稿;原版已存在不需要)。
- 無資料庫 schema 變更;僅 proc_param 兩筆 INSERT(見上)。
- Gpptopu 選
-
06-12 cungma-port ▸
2026-06-12 不良處理單(CUNGMA)移植
摘要
依 VFP 舊版
scx_ord.vcx / cungma完整移植「不良處理單」(選單 H-140)到 Darbware ERP。Master+Detail 單據(主表
cungma、子表cungde,無 view),編號依_sheetno(單據別 CUNGMA、前置碼 N、編碼方式 4、srno 長度 4)。
新增
Common\Model\E.Order\CungmaModel.cs/CungdeModel.cs
Model\Source\E.Order\CungmaSource.cs/CungdeSource.cs
ViewModel\E.Order\CungmaViewModel.cs—ErpProgramWithDetailViewModel+ IAdd
LogicBll\Ade\E.Order\CungmaSave.cs— 反射命名LogicBll.Ade.CungmaSave
TsERP\E.Order\Cungma.xaml(.cs)— TsView + TsRadGridView 明細
Common\Lang\Xaml\Cungma.json+TsERP\Lang\Xaml1\Xaml.json併入 Cungma 區段
登錄點
TsERP\Lang\TableMap.json:"cungma": "cungma"、"cungde": "cungde"
Model\LocalDbContext.cs:DbSet<CungmaSource>、DbSet<CungdeSource>
Common\ProgramClass.cs:CUNGMA
TsERP\App.xaml:CungmaViewModel → CungmaDataTemplate
TsERP\Lang\ClassAliasMap.json:Cungma/Cungde Model+Source
Common\Common.csproj:Lang\Xaml\Cungma.jsonContent
VFP 行為對照
VFP 新版 addagain:公司代碼=1、日期=今天CungmaViewModel.AfterAddNewallowsave:公司代碼/日期空白擋存CungmaSave.AllowSaveallowsave:異常chk1~5,A / 確認chk1~5 組 異常狀況/確認狀況(固定 1~5,A 順序補滿 10 位)CungmaSource的異常Chk*/確認Chk*bool 屬性即時雙向維護字串changeopmode:依 異常狀況/確認狀況 還原勾選同上(屬性 get 從字串解析,移動筆自動刷新) allowsave:SCAN 檢測項目空白 → 增刪修='D'CungmaSave+CungdeSource.NeedDeleteFunction客戶代號.Valid:cudata 帶客戶簡稱/聯絡人1/公司電話/公司傳真客戶代號Binding → SetCustomerData()(DARB_GETDATA4,查無時清空,不另提示=VFP 行為)廠商代號.Valid:spdata 帶廠商簡稱廠商代號Binding → SetVendorData()品號.Valid:invent 帶品名/廠牌品號Binding → SetSkuData()里程數.Refresh:里程數=維修里程-更換里程(不存檔)CungmaSource.里程數NotMapped 計算屬性真因分析選項(sqlcombo c_type=274)TsComboBoxBySql TableAlias="C274"(環境 SQLite CMB_274)綁 VM真因分析選項cmdbtn_yes1(產生鈕):smemsd 摘要=選項 取敘述逐行拆「檢測項目;標準數據」填空白列;未選/已有檢測項目擋下CungmaViewModel.GenerateDetailCommand(限編輯模式)公司代碼 sqlcombotxt c_type=101 TsComboBoxWithDescriptionBySql TableAlias="C101"明細 grid:序號/檢測項目/標準數據/實際數據/OK? TsRadGridView 同欄位 無審核三欄 不掛集中式審核 SP 依賴:僅
DARB_GETDATA4(darbnogilog1.proc_param 已登錄,param_qty=3),無需新 SP。未還原項目
- 報表
CUNGMA_P(SCX_ORDP)— TODO(VM 註解)
- EDI 鈕
else1click(DO FORM EDI_CUNGMA轉入+權限檢查)— 不在本次範圍,TODO(VM 註解)
客戶電話.DblClickSkype 撥號(U_IELINK)— 不移植
- VFP
單號.is_noduplicate(手動輸入單號防重)— 新版單號由_sheetno自動編號(唯讀),不需要
- ⚠️ 真因分析選項清單內容依環境 SQLite
CMB_274;本機smemsd無 C274 類別資料時清單為空(runtime 待驗)
Runtime 未驗
全部畫面/存檔流程僅 build 驗證,未實機開窗測試。
-
06-12 culbl-port ▸
2026-06-12 客戶標籤檔(CULBL)移植
摘要
依 VFP 舊版
scx_ord.vcx / culbl完整移植「客戶標籤檔」(選單 H-130)到 Darbware ERP。單檔主檔(無明細、無 view,直接映射
culbl表),編號依_sheetno(單據別 CULBL、編碼方式 0、srno 長度 3)。新增
Common\Model\E.Order\CulblModel.cs(前手已建,欄位與 DB 核對無誤沿用)
Model\Source\E.Order\CulblSource.cs— 中文屬性對映 DB 欄位
ViewModel\E.Order\CulblViewModel.cs—ERPProgramViewModel單檔主檔
LogicBll\Ade\E.Order\CulblSave.cs— 反射命名LogicBll.Ade.CulblSave
TsERP\E.Order\Culbl.xaml(.cs)— TsView 版面
Common\Lang\Xaml\Culbl.json+TsERP\Lang\Xaml1\Xaml.json併入 Culbl 區段
登錄點
TsERP\Lang\TableMap.json:"culbl": "culbl"
Model\LocalDbContext.cs:DbSet<CulblSource> Culbl
Common\ProgramClass.cs:CULBL
TsERP\App.xaml:CulblViewModel → CulblDataTemplate
TsERP\Lang\ClassAliasMap.json:CulblModel/CulblSource → Culbl
Common\Common.csproj:Lang\Xaml\Culbl.jsonContent
VFP 行為對照
VFP 新版 allowsave:日期空白擋存「請先輸入日期 !!!」CulblSave.AllowSave以 GetInputMessage 提示客戶代號.LostFocus:查 cudata 帶客戶名稱/公司地點/公司電話,查無提示「查無客戶代號 !!!」CulblSource.客戶代號Binding → SetCustomerData()(DARB_GETDATA4)無 addclick/addagain 預設值 不設預設(日期由存檔檢查強制) 無審核三欄 不掛集中式審核 未還原項目
- 報表
CULBL_P(SCX_ORDP)— TODO(VM 註解)
公司地點.DblClick開地圖、公司電話.DblClickSkype 撥號(U_IELINK 桌面整合)— 不移植
-
06-12 cmplain-port ▸
2026-06-12 — CMPLAIN 抱怨單(E-210)按 VFP 還原
摘要
依 VFP 舊版
CMPLAIN(scx_ord.vcx,548 行)完美還原抱怨單 主明細表單到 Darbware ERP,走
ErpProgramWithDetailViewModel+ItemsBindingManager+ TsView/TsRadGridView 最新範本(比照 Claim)。資料表
cmplain_m/cmplain_d(無編輯 view,直接綁資料表)。新增
Common/Model/E.Order/Cmplain_mModel.cs、Cmplain_dModel.cs
Model/Source/E.Order/Cmplain_mSource.cs、Cmplain_dSource.cs
LogicBll/Ade/E.Order/CmplainSave.cs
ViewModel/E.Order/CmplainViewModel.cs
TsERP/E.Order/Cmplain.xaml(.cs)
Common/Lang/Xaml/Cmplain.json(+ Common.csproj Content)
VFP 行為對照
VFP 新版 allowsave:公司代碼=0 擋存 CmplainSave.AllowSaveGetInputMessageallowsave: DTOC(CTOD(年度月份+'/01'))驗證DateTime.TryParseExact(yyyy/MM/dd),訊息「請先輸入正確之年度月份 !!!」allowsave: REPLACE 單號 WITH STR(公司代碼,1)+年度月份HandleDataBeforeEndEdit組前置碼,_sheetno 編碼方式 4 由 server 補 3 碼流水allowsave:明細 日期 非空且 日期<>年度月份(VFP = 比對 LEFT 7 碼)擋存StartsWith(年度月份)檢查,訊息「明細資料日期輸入錯誤 !!!」allowsave:日期空白且抱怨事項空白 → 增刪修 'D' NeedDeleteFunction+MarkEmptyDetailDeleted雙保險sql_cuno1.Valid:DARB_GETDATA4 cudata(客戶代號 OR 對照碼)帶 客戶代號/客戶簡稱/聯絡人1/聯絡1電話;查無→「查無客戶代號 !!!」;含 ?[] 不處理Cmplain_dSource.客戶代號Binding→SetCustomerData(),比照Vw_claim_mSourceBinding 模式主檔 備註 ReadOnly XAML IsReadOnly=True 公司代碼 sqlcombotxt c_type=101 TsComboBoxWithDescriptionBySql TableAlias="C101"完成與否 InputMask "Y" TsGridViewCheckBoxColumn+ YesNoConverter(Y/空白)變更(既有檔案,僅登錄點)
TsERP/Lang/TableMap.json:cmplain_m/cmplain_didentity 登錄(DB 無編輯 view)
Model/LocalDbContext.cs:DbSet<Cmplain_mSource> Cmplain_m、DbSet<Cmplain_dSource> Cmplain_d
Common/ProgramClass.cs:新增CMPLAIN
TsERP/App.xaml:CmplainViewModel DataTemplate
TsERP/Lang/Xaml1/Xaml.json:Cmplain區塊
TsERP/Lang/ClassAliasMap.json:Cmplain_m/dModel/Source 別名
刪除
無。
Breaking Changes
無。
Migration Notes / 未還原項目
- 報表 TODO:VFP 報表程式
CMPLAIN_P(SCX_ORDP) 尚未移植。
- 無審核三欄(cmplain_m 無 已審核/審核人員/審核日期)→ 不掛集中式審核。
- VFP
STR(公司代碼,1)公司代碼 >9 時會變*;新版取字串第 1 碼(公司代碼為 C101 單碼代碼,實務上等價)。
- runtime 未驗(瀏覽 view
vwbd_cmplain/DARB_BD_CMPLAIN為 server 端既有設定,未改動)。
-
06-12 claim-port ▸
2026-06-12 索賠單(CLAIM)移植
摘要
依 VFP 舊版
scx_ord.vcx / claim完整移植「索賠單」(選單 E-180,保固卡索賠)到 Darbware ERP。Master+Detail 單據(主表
claim_m、子表claim_d,viewvw_claim_m/vw_claim_d),編號依
_sheetno(單據別 CLAIM、前置碼 T、編碼方式 4、srno 長度 4)。⚠️ 與既有「應收扣款 ARCLAIM(Arclaim)」是不同功能,勿混。
新增
Common\Model\E.Order\Vw_claim_mModel.cs/Vw_claim_dModel.cs
Model\Source\E.Order\Vw_claim_mSource.cs/Vw_claim_dSource.cs— view 顯示欄位 品名/客戶簡稱/廠商簡稱 僅存 Source 不上傳
ViewModel\E.Order\ClaimViewModel.cs—ErpProgramWithDetailViewModel+ IMoveRecord + IWeakEventListener(sum加總)
LogicBll\Ade\E.Order\ClaimSave.cs— 反射命名LogicBll.Ade.ClaimSave
TsERP\E.Order\Claim.xaml(.cs)— TsView + TsRadGridView 明細
Common\Lang\Xaml\Claim.json+TsERP\Lang\Xaml1\Xaml.json併入 Claim 區段
TsControl\Themes\TsTextBoxGeneric.xaml:新增RepairNoSearch樣式(repair.叫修單號);保固卡號用同批新增的ProductSerialNoSearch
登錄點
TsERP\Lang\TableMap.json:"claim_m": "vw_claim_m"、"claim_d": "vw_claim_d"
Model\LocalDbContext.cs:DbSet<Vw_claim_mSource> Claim_m、DbSet<Vw_claim_dSource> Claim_d
Common\ProgramClass.cs:CLAIM(原本不存在,本次新增)
TsERP\App.xaml:ClaimViewModel → ClaimDataTemplate
TsERP\Lang\ClassAliasMap.json:Vw_claim_m/Vw_claim_dModel+Source
Common\Common.csproj:Lang\Xaml\Claim.jsonContent
VFP 行為對照
VFP 新版 allowsave:客戶代號/公司代碼(=0)/登入日期空白擋存ClaimSave.AllowSaveallowsave:REPLACE 增刪修 WITH 'D' FOR EMPTY(品號)ClaimSave(AllowSave + HandleDataBeforeEndEdit)+Vw_claim_dSource.NeedDeleteFunction保固卡號.LostFocus:查 invent1 帶 客戶代號/品號/機器序號/datecode/購買日期(值不同才回填、查無不提示)保固卡號Binding → SetWarrantyData()(DARB_GETDATA4 invent1)叫修單號.LostFocus:查 repair(客反應主檔) 帶 保固卡號/客戶代號/品號/機器序號/檢修日期/處理情形叫修單號Binding → SetRepairData()(DARB_GETDATA4 repair)sqlnm_sp1.代號.LostFocus:查 spdata 帶幣別廠商代號Binding → SetVendorData()(廠商簡稱 + DARB_GETDATA4 spdata 幣別)客戶代號(sqlnm_cu)帶簡稱客戶代號Binding → DescriptionHelper.GetCustomerName(view 欄 客戶簡稱)品號(sql_mno dovalid=1,主檔與 grid 明細)帶品名、查無提示主檔/明細 品號Binding → SetSku*()(查無品號 !!!)sum加總:總計 = Σ(明細 數量*單價,排除 D 列與空白品號) + 工資;grid1.Refresh 觸發ClaimViewModel.SumTotal():AfterMoverRecord+ 工資/數量/單價/品號 ListenerHelper 即時重算(NotMapped總計)grid col金額:ROUND(數量*單價,2)計算欄Vw_claim_dSource.金額NotMapped 計算屬性(數量/單價 set 連動刷新)保固卡號.is_exist="invent1.保固卡號"/叫修單號.is_exist="repair.叫修單號"ProductSerialNoSearch/RepairNoSearchTsSearchTextBox 樣式(F2 查詢)公司代碼 sqlcombotxt c_type=101 TsComboBoxWithDescriptionBySql TableAlias="C101"幣別 sqlcombo c_type=1 TsCurrency(僅幣別,claim_m 無匯率欄)城市國家/機器序號/DATECODE/品名 ReadOnly 顯示 唯讀 TsTextBox(品名為 view U_SEEKNM 對應欄) 無審核三欄 不掛集中式審核 SP 依賴:僅
DARB_GETDATA4(已登錄),無需新 SP。與 VFP 的刻意差異
- VFP
datecode文字框 ControlSource 誤綁索賠單主檔_V.機器序號(複製貼上 bug,
與
叫修單號.LostFocus寫回DATECODE欄位的程式互相矛盾)。新版 DATE CODE 欄位綁定正確的
datecode欄。未還原項目
- 報表
CLAIM_P(SCX_ORDP)— TODO(VM 註解)
moverec_sk_cursor(SK_CUDATA/SK_SPDATA/SK_INVENT 快取游標)— 新版 view JOIN 取代,不需要
Runtime 未驗
全部畫面/存檔/連動流程僅 build 驗證,未實機開窗測試。
-
06-11 scx-qry-batch-port ▸
2026-06-11 — 主管資訊(EIS)查詢 11 支批次移植完工
摘要
VFP
scx_qry查詢報表庫缺口一次補完:9 支整支新移植 + 2 支半成品完工,主管資訊選單(M 模組)與 H-11/J-05 全部查詢程式自此可在新版開啟。新增
選單 程式 內容 M-03 交期回覆統計(RB_RATIO) 明細 18 欄 + 底部合計(訂單/OK/NG 筆數、回覆即時率%);工時計算 set-based M-04 最近進價與售價(PX_QRY) 售價/進價兩頁,最近+最高+最低三組價格合併一列 M-06 流動狀況表(INV_QRY4) 不分儲位/分儲位兩頁,滯庫天數篩選 M-08 呆料查詢(NOUSE) 期初有庫存且期間交易量低於百分比門檻;查詢後可再按倉庫/說明篩選 M-10 標準成本與進貨比較(CHKRA) 比較單價一頁 M-11 集團資料查詢(CUQRY) 報價/訂單/出貨/待收帳款/授信額度 5 頁(各含子公司+明細) M-15 訂單存貨計劃(ORD_QRY4) 訂單存貨 61 天 + 材料用量 91 天動態日欄、安全庫存連動列 M-17 庫齡呆料分析(STOCKLIFE) 庫齡分析/庫齡明細/呆料分析/交叉分析 4 頁 H-11 例外出入庫查詢(EXCE_INOUT) 例外出入明細 + 組立價/銷售價推估 變更(半成品完工)
- M-18 客戶延納統計(ORD_QRY3)、J-05 廠商延納統計(PUR_QRY3):原中文 ViewModel 是選單反射找不到的孤兒殼,重建為
Ord_qry3ViewModel/Pur_qry3ViewModel並修正對比發現的錯誤(延納率除零、急單參數誤用採購值、延交件數判定不完整、grid binding typo「訂購日期」、月報表捨入位數等共 19 項)。
- 與 VFP 行為的刻意差異(修正 VFP 原生 bug):CUQRY 未轉帳出貨補客戶條件(原版每子公司重複累加全公司出貨)、RB_RATIO 接通「回覆交期」欄(原版欄名錯位永遠空白)、NOUSE 最近購價改取真正最近一筆(原版 per 廠商多列重複)。
刪除
ViewModel/M.EIS/客戶延納統計ViewModel.cs、廠商延納統計ViewModel.cs(孤兒殼)及廠商延納統計三個全註解 Source。
Breaking Changes
無(全部是新增入口;既有程式無行為變更)。
Migration Notes
- 新 SP ×9 需在目標公司資料庫部署:
sql/TWORK_QRY_{INV_QRY4,CHKRA,EXCE_INOUT,RB_RATIO,NOUSE,PX_QRY,CUQRY,ORD_QRY4,STOCKLIFE}_darbnogicsa1.sql,並執行各檔尾darbnogilog1.proc_param登錄(漏登錄會靜默查無資料)。本機 darbnogicsa1 已全數部署+登錄。
- 列印(.frx)鈕未移植(多為 Excel 匯出,grid 內建匯出取代);ORD_QRY3 沿用既有三支 .frx。
- 不在本公司選單的 9 支 scx_qry class 刻意不移植,詳見 ADR-0034。
- M-18 客戶延納統計(ORD_QRY3)、J-05 廠商延納統計(PUR_QRY3):原中文 ViewModel 是選單反射找不到的孤兒殼,重建為
-
06-11 rp-per-form-sqlite-staging ▸
rp 系表單本機 staging 表隔離(修復交錯編輯存檔失敗)
日期:2026-06-11
相關 ADR:0033-rp-per-form-sqlite-staging
摘要
付款單(paymnt)、收款單(receive)、費用申請(payapply_kc)、預付(prepaid)、
其他應收付(otherrp)、零用金(ftrlima)六支表單原本共用同一張本機 SQLite
staging 表。交錯操作(A 表單載單 → B 表單載單 → 回 A 表單編輯存檔)會把 A 的
本機列清掉,造成存檔失敗(DbUpdateConcurrencyException)或改動靜默漏存。
本次讓每支表單使用自己的本機 staging 表,互不干擾。
變更
- 六支表單的本機 SQLite staging 各自獨立(PaymntRp_m/d、ReceiveRp_m/d、
Payapply_kcRp_m/d、PrepaidRp_m、OtherrpRp_m、FtrlimaRp_m/d)。
- navigate 寫入本機的表名改走
ItemsBindingManager.GetLocalTablesName()映射;
server 端上傳表名(rp_m / rp_d)完全不變。
- 舊共用表
Rp_m/Rp_d降級為轉單 BLL(Ftrlima_4/5)scratch 區。
使用者可見影響
- 修復:兩支以上 rp 表單交錯編輯時存檔報「資料庫並行例外」或存檔後改動消失。
- 無 UI / 欄位 / 流程變動;無資料 migration(本機 staging 每次登入重建)。
Breaking Changes
無(server 端資料與 API 不變)。
已知殘餘限制
- 同一支表單在兩個容器同時編輯仍共用同一張 staging 表。
- 若兩個程式代號共用同一 ViewModel 類(疑似 ARALLOWANCE↔RECEIVE、
PAYAPPLY_ZD↔PAYAPPLY_KC),該兩支程式之間仍共表。
-
06-11 prodplan-shortage-cashflow-simulation ▸
生產計劃查詢:庫存缺口/金流預測/模擬插單/樞紐分析
日期:2026-06-11
模組:M.EIS 生產計劃查詢 (pd_qry7)
摘要
生產計劃查詢從三個結果頁籤擴充為七個,新增庫存缺口判斷、金流預測圖表、
what-if 模擬插單與樞紐分析,成為查詢+決策模擬一體的功能。
新增
- 庫存缺口 頁籤:每筆需求(成品=生產計畫、材料=使用量)對「現有庫存+在途採購」
滾動計算可用量、缺口量、最早短缺日;缺口列紅底標示
- 樞紐分析 頁籤:訂單預示預估的 RadPivotGrid 樞紐視角,預設 客戶×品號 對 年度×月份
的 Σ金額/Σ數量,右側欄位清單可拖拉重組
- 金流預測 頁籤:上半月份圖表(應收正向柱/應付負向柱堆疊+累計淨額折線+零軸線
+資金警戒紅線),下半金流明細。四層來源:未兌票據/未沖帳款/在途採購/計劃預測,
各帶可信度(高/中/低)供判讀
- 模擬插單 頁籤:插入假想訂單(品號/數量/交期/客戶,單價空白自動帶客戶報價)→
「套用模擬」自動展 BOM 連動缺口與金流,圖表並排顯示基準/模擬雙組對比,
摘要顯示短缺品號數與累計淨額最低點變化;「清除模擬」即還原。模擬不寫入任何資料庫
- 條件面板新增:帳款立帳起日(金流預測未沖帳款的回溯範圍,預設近一年)、
資金警戒線(金流圖表紅線)
變更
- 條件面板步驟③說明文字更新(列出新頁籤)
刪除
無
Breaking Changes
無(既有三個頁籤行為不變)
Migration Notes
- 需在資料庫執行
sql\TWORK_QRY_PRODPLAN_EXT_darbnogicsa1.sql(兩支新 SP+
darbnogilog1.proc_param 登錄;proc_param 沒登錄查詢會靜默回空)
- 金流「帳款」層的 R/P/A 分類與票貼/質押票據口徑,建議上線後拿票據查詢/帳齡報表對數確認
-
06-11 ftrlima-turn-sliy-date-range ▸
Ftrlima 轉傳票改用立帳日期區間查詢
日期:2026-06-11
模組:總帳 / 財務單轉傳票(SliyTurn — Ftrlima 分頁)
摘要
財務單轉傳票(ftrlima → SLIY 傳票)的查詢條件,從「立帳日期 = 單一日期」改為「立帳日期 起迄區間」,
與既有的應付(Ap)、應收(Ar)轉傳票一致。產生的每張傳票各自採用其來源財務單的立帳日期當傳票日期。
變更
- 查詢條件:
立帳日期 = '{日期}'→立帳日期 BETWEEN '{起}' AND '{迄}'。
- 查詢畫面(SliyTurn 的 Ftrlima 分頁):單一日期欄位 → 起迄兩個日期欄位(
起 ~ 迄),版面對齊 Ap 分頁。
- 傳票日期語意:原本整批傳票都記在使用者輸入的單一日期;現在每張傳票用來源財務單自己的立帳日期
(
Twork_acc_vw_sliymSource.傳票日期 = 來源.立帳日期),與 Ap/Ar 行為一致。零用金(FJ)摘要內的日期也跟著改用來源立帳日期。- 預設區間:起日 = 今天 −7 天、迄日 = 今天(對齊 Ap 分頁預設)。
Breaking Changes
- 轉出的傳票日期不再是「轉檔當下選的那一天」,而是各來源財務單的立帳日期;跨多天的財務單會產生多個不同日期的傳票。
Migration Notes
- 純功能調整,無資料庫 schema 變更。
- 後端 stored proc
DARB_TUR_SLIY_FTRLIMA沿用既有機制(查詢條件以字串注入 WHERE、lp_1傳區間起日),
與
DARB_TUR_SLIY_AP/DARB_TUR_SLIY_AR同款做法(那兩支早已是區間查詢)。上線後仍請實機驗證:起迄區間有正確篩選、各傳票日期 = 來源立帳日期、鎖定清單(LockedSource)與筆數正常。
- 查詢條件:
-
06-11 ftrlima-turn-sliy-account-fixes ▸
ftrlima 轉傳票:票據兌現/電付兌現 科目代號與借貸修正
日期:2026-06-11
範圍:
LogicBll/Other/SliyTurn/Ftrlima/FtrlimaQueryHandle.cs(查詢產生傳票預覽,不影響已存傳票)摘要
runtime 驗收發現付票兌現(BE)/電付兌現(BL)傳票的銀行列科目代號空白。
與 VFP
sliyturn.scx逐段對照後修正四處移植錯誤。根因:FI(付兌提出)的帳戶代號依 LCL交易別設定(轉出部門=B)寫在
轉出倉儲,C# 誤讀轉入倉儲;VFP 的 SEEK 是補空白比對所以舊版容錯,C# 字典是精確比對,key 拿錯直接空值。
修正
- BE 付票兌現:FI 貸方列科目代號改查
轉出倉儲(原誤讀轉入倉儲,永遠空白)。
- BL 電付兌現:
- FI 貸方列分組鍵與科目查找改用
轉出倉儲,且改取銀行科目(原誤取帳戶代號,填進去的不是總帳科目)。
- FI 列金額由借方欄位改放貸方欄位(原本借貸全在借方,傳票不平衡)。
- 序號補遞增(原本全部列都是 000)。
- CU 借方摘要尾端改去除逗號(對齊 VFP,原誤寫成去除句點)。
同日追加:客廠代號補帶入
- B4 收票兌現:CE 貸方(應收票據)列補帶來源明細的
客廠代號。
- BE 付票兌現:CR 借方(應付票據)列補帶來源明細的
客廠代號。
- 依 VFP
SCAT MEMV語意:這兩種列的m.客廠代號=''在 VFP 被註解
(CE 處註記「要客廠代號」),即保留來源值;C# 物件初始化漏設導致空白。
- 其餘列(銀行借方/FI 貸方/匯差)VFP 主動清空,C# 行為一致,不變。
不受影響
- B4 收票兌現與 FJ 零用金撥補路徑與 VFP 對照一致,未改動。
- server 端資料、已轉出的傳票不受影響;此為查詢預覽階段的產生邏輯。
- BE 付票兌現:FI 貸方列科目代號改查
-
06-11 eisdash-dashboard ▸
2026-06-11 主管儀表板(EISDASH)
摘要
新增「主管儀表板」頁面(M.主管資訊選單 M-21):一頁看全公司——8 張 KPI 卡片、4 張互動圖表、2 張警示清單,支援日期快切、自動刷新、點擊直達既有查詢頁。
新增
- KPI 卡片列(8 張,含迷你趨勢線與紅色警示副標):本期受訂、本期出貨、未交訂單(逾期金額)、應收帳款(90天+)、應付帳款(90天+)、庫存金額(呆滯占比)、客戶延納率(當月)、廠商延納率。
- 圖表區(2×2):受訂/出貨趨勢(面積+折線雙序列)、銀行結餘趨勢(含票據預估)、應收帳齡分佈(環圈圖,中央顯示總額)、廠商延納率 Top 10(長條圖)。
- 警示清單:客戶逾期未交 Top 10、呆料金額 Top 10。
- 日期快切:本月 / 本季 / 本年 / 自訂區間 segmented 按鈕,切換即重查。
- 自動刷新:預設每 5 分鐘(可在條件面板調整分鐘數或關閉;切到其他頁面時不會打資料庫)。
- Drill-down:點 KPI 卡片、圖表或「明細 →」直接導航到對應查詢頁(客戶查詢/應收帳齡/應付帳齡/庫齡呆料分析/客戶延納統計/廠商延納統計/銀行流水/呆料查詢)並自動帶入日期條件查詢,上一頁按鈕可回儀表板。
- 單一 KPI 讀取失敗只影響該卡片(顯示「讀取失敗」紅字,滑鼠停留看錯誤訊息),其餘區塊照常顯示。
- 新 SP:
TWORK_QRY_DASH_SALES(受訂/出貨趨勢+合計)、TWORK_QRY_DASH_INVSUM(庫存總額+呆滯+呆料Top)、TWORK_QRY_DASH_BACKLOG(未交/逾期+客戶逾期Top)。
變更
- 無既有功能行為變更(純新增頁面;共用檔僅加註冊行)。
刪除
- 無。
Breaking Changes
- 無。
Migration Notes
部署到其他資料庫環境需三段(漏任何一段該區塊會顯示讀取失敗或選單不出現):
1. darbnogicsa1:執行
sql/TWORK_QRY_DASH_{SALES,INVSUM,BACKLOG}_darbnogicsa1.sql的 CREATE。2. darbnogilog1:執行各檔尾 proc_param 登錄 block。
3. 選單:
EXEC dbo.usp_新增程式 @程式代號=N'EISDASH', @程式名稱=N'主管儀表板', @序號='M-21', @按鈕名稱=N'M.主管資訊', @建立單號=0。本機(localhost)三段已完成。
已知限制(二期候選)
- 品質 KPI(不良率/達成率)未納入第一版(見 ADR-0036)。
- 受訂/出貨/未交的 drill-down 導到客戶查詢頁但不自動查詢(該頁需指定客戶)。
- 客戶延納率取「截止日期當月」單月資料(沿用 ORD_QRY3 SP 的年度月份參數設計)。
-
06-10 scx-pur-pending-fixes ▸
2026-06-10 — 採購模組(scx_pur)對比待修清單收尾
摘要
接續 VFP
scx_pur.vcx對比後留下的待修清單,本次處理三項:1. spdata(廠商資料)存檔驗證補回:VFP
allowsave的「廠商代號必填(且不得為+++)」「幣別必填」兩道驗證在新版被註解掉(且註解內引用已改名的英文屬性VendorCode),本次依 VFP 原邏輯補回;另補「聯絡人空姓名列存檔時自動設刪除」(VFPREPLACE 增刪修 WITH 'D' FOR EMPTY(姓名))。2. purch(採購單)補回「確認」按鈕:VFP
else7click(瀏覽狀態下進編輯 → 主檔「確認」欄蓋目前使用者帳號 → 立即存檔)在新版未接線。PurchViewModel新增IOther4/ExtendedFunction4()實作同流程,存檔失敗自動取消編輯。寫法比照OrmastViewModel.ExtendedFunction3(審核章)。3. Ppurch_c(取消採購/批次結案)上傳表名修正:
UploadTableNames原寫請購表ppurma/ppurde,但實際結案寫回的是採購單purchm(SetUpdateSource建Twork_pur_vw_purchmSource、UploadPrgClass=PURCH),屬 copy-paste 殘留;已改為Purchm/Twork_pur_vw_purch,對齊姊妹類PptopuBll。新增
PurchViewModel:IOther4+ExtendedFunction4()(確認章)。按鈕標題由程式參數/權限(資料端)控制。
變更
SpdataSave.AllowSave:廠商代號(空或+++)、幣別為空時擋存檔,訊息用多語系欄位名(ProgramClass.SPDATA)。
SpdataSave.HandleDataBeforeEndEdit:聯絡人(廠商資料表_1)姓名為空的列設增刪修='D'。
Ppurch_cBll.UploadTableNames:Ppurma/Ppurde→Purchm/Twork_pur_vw_purch。
刪除
- 無。
Breaking Changes
- spdata 原本可存「無廠商代號 / 無幣別」的廠商資料,現在會被擋下(回到 VFP 行為)。既有缺幣別的舊資料下次編輯存檔時需補上幣別。
Migration Notes
- purch「確認」按鈕的顯示/標題由資料端程式權限參數控制,若按鈕未出現請確認 DB 端 PURCH 的其他功能 4 已設定。
備註
- 建置:LogicBll、ViewModel 以 VS MSBuild 建置通過(僅既有警告)。
- scx_pur 殘餘待辦(皆屬功能新建,未動):PPUR_SUG(請購建議→請購單)、purch 修改交期(
_CHANGEDATE)、進貨查詢(PURCH_S);OrmastToPP 轉訂單待 runtime 驗證。
-
06-10 ppur-sug ▸
2026-06-10 — 新增「請購建議表」(PPUR_SUG,VFP 移植)
摘要
移植 VFP
ppur_sug(請購建議表,2149 行)為新版獨立選單程式PPUR_SUG。依需求月份統計 12 期出貨量,套用 VFP 公式推算建議請購量,並把建議量 > 0 的列轉成一張請購單(ppurma/ppurde)。計算公式(忠實 VFP):
- 平均銷貨數 = ROUND(前六月出貨總計 / 6, 0)
- 需求量 = 平均銷貨數 / 30 × Leadtime − 預計可用量(目前可用量+在途量+採購未交量)
- 最低請購量 = MAX(需求量, 最小採購量);建議請購量依內箱包裝數進位
新增
LogicBll/G.Purchasing/Ppur_sug/Ppur_sugBll.cs:查詢(族群/品號/廠商三模式,接TWORK_QRY_PPUR_SUG)、AllowSave 驗證(防重複轉單、預訂交期/倉儲必填、無需求擋存)、SetUpdateSource(單一主檔+建議量>0 明細、報價階梯選價、外幣U_Blrate帶率)、計算金額(2)(含稅 4 欄+尾差調整,純靜態可單測)。
Model/SQLProcedure/Twork_Qry_Ppur_Sug/PpurSugCalculator.cs:相對期別、出貨累加、需求量/建議量演算法、報價階梯選價(靜態純函式)。
ViewModel/G.Purchasing/Ppur_sugViewModel.cs:查詢條件、雙 grid(26 欄主表+C1~C12 月份表)、二次篩選(低於安全庫存/僅需請購)、轉單後鎖查詢。
TsERP/G.Purchasing/Ppur_sug.xaml(.cs):TsView+TsRadGridView;code-behind 依查詢結果把 C1~C12 欄標題換成實際月份(比照Preord.xaml.cs)。
Common/Lang/Xaml/Ppur_sug.json+TsERP/Lang/Xaml1/Xaml.json增Ppur_sug區段(12 個介面文字 key)。
Common/ProgramClass.cs:新增PPUR_SUG;TsERP/App.xaml:新增Ppur_sugViewModel → Ppur_sugDataTemplate。
變更
Twork_Qry_Ppur_SugBll(與 E.Order Preord 共用的查詢引擎):
-
Query()第二參數改傳呼叫端ProgramClass(成本遮罩權限改動態);- 最近進貨/出貨日改
GroupBy().First()取最近一筆(原ToDictionary同品號多列會丟例外);- 演算法搬到
PpurSugCalculator共用。Twork_Qry_Ppur_SugDemandPoco:修正季平均運算優先級 bug(C1+C2+C3/3→(C1+C2+C3)/3)、平均數改MidpointRounding.AwayFromZero、改以相對期別累加。
PreordControlViewModel(E.Order):配合查詢引擎簽名改動;月份欄改新→舊排序、起始月改 -11 月(C1~C12 共 12 期,對齊 VFP)。
刪除
- 無。
Breaking Changes
- 無(Preord 月份欄順序改為新→舊,屬顯示順序對齊 VFP,資料不變)。
Migration Notes
- 新程式為獨立選單程式(VFP 是 ppurch else6 按鈕開啟):DB 選單需新增
PPUR_SUG項目才能進入(同PPURCH_C模式,靠ProgramClass反射啟動)。
- 第一期排除(後續再補):月份欄右鍵出貨明細(VFP
PPUR_SUS)、Excel 匯出/列印。
備註
- 建置:TsERP(含 Common/Model/LogicBll/ViewModel)VS MSBuild 通過,僅既有警告。
- 待 runtime 驗證:查詢三模式、轉請購單上傳、轉單後 Ppurch 開啟確認。
-
06-10 hyperlink-underline-mingliu ▸
2026-06-10 — 超連結欄位底線修復(新細明體 × Display 模式)
摘要
全系統超連結欄位(
TsTextBox設IsHyperLink="True",如傳票號碼、出納/沖帳傳票號、單號連結)長期只有藍字、沒有底線。根因:WPF 的TextOptions.TextFormattingMode="Display"配上系統字型新細明體(MingLiU)時不會渲染TextDecorations底線(TextBlock/TextBox 皆然,指定 Pen 或 PenOffset 都無效)。變更
TsControl/Themes/TsTextBoxGeneric.xaml、TsControl/Themes/V2Generic.xaml(兩處):IsHyperLink=Truetrigger 內加TextOptions.TextFormattingMode="Ideal"——僅超連結欄位切回 Ideal 文字模式,底線恢復顯示;其他欄位維持 Display 模式的點陣銳利渲染。
使用者可見影響
- 超連結欄位現在會顯示藍字+底線(之前只有藍字)。
- 超連結欄位的字體渲染從點陣銳利改為平滑(Ideal 模式),與相鄰欄位略有差異,屬預期取捨。
Migration Notes
- 無需資料或設定變更。若未來全域字型改為微軟正黑體等向量字型,此 workaround 可移除(Display 模式配向量字型可正常畫底線)。
-
06-10 document-json-transfer ▸
2026-06-10 單據匯出/匯入(JSON 交換檔)
摘要
主視窗「目前表單功能」選單新增「匯出單據」與「匯入單據」:可把當前開啟的單據
(主檔+明細)存成
*.tsdoc.json交換檔,拿到另一個資料庫環境的同一支表單匯入成新單據。新增
- 選單「(表單名)功能」→「匯出單據」:非編輯狀態下,把目前單據存成 JSON 交換檔,
預設檔名為
表單類別_單號.tsdoc.json- 選單「(表單名)功能」→「匯入單據」:選擇交換檔後自動進入新增狀態並帶入資料,
使用者檢查內容後按「儲存」完成匯入
- 匯入時自動重新編號(單號不沿用),審核狀態、建檔人員/日期、權限表設定的不複製欄位
一律清空重產,規則與「複製」按鈕一致
變更
- 選單「編輯本表單參數」下方新增分隔線與上述兩個項目
刪除
無
Breaking Changes
無
Migration Notes
- 僅支援走新式資料管理(ItemsBindingManager)的單據表單;舊式表單點選時會提示「此表單不支援」
- 交換檔屬於哪支表單會記錄在檔內,匯入到不同表單會被拒絕
- 目的資料庫若缺少交換檔引用的基本資料(廠商、品號等),儲存時會由既有驗證擋下,
需先補齊基本資料再匯入
-
06-09 progressbar-content-window-sizing-and-flow ▸
2026-06-09 — 進度條彈窗:自動縮放視窗 + 邊顯示邊做事
摘要
修正 ContentWindow 系列彈窗在
IsSizeToContent時仍被撐到主視窗大小、不會縮成內容大小的問題;並把工作流程 PDF 產生的進度條流程,從「開窗 → 等使用者關掉 → 才開始做事」改成正確的「開窗 → 進度條持續轉動、PDF 同時產生 → 做完視窗自動關閉」。對使用者而言,產 PDF 時會看到一個剛好包住進度條、置中在主視窗上的小視窗,期間進度條動畫表示「處理中」,完成即自動消失。新增
IContentWindowLoadedAsync(Common/Context/IContentWindowLoadedAsync.cs):通用 hook 介面。ContentWindow 的內容 VM 實作後,視窗 Loaded 會自動await OnContentWindowLoadedAsync()一次。用於「開窗即做事、做完自動關窗」情境,不綁死 ProgressBar,日後其他彈窗可共用。
ProgressBarViewModel.WorkAsync(ViewModel/ProgressBarViewModel.cs):Func<Task>屬性。指派後,視窗顯示期間執行該工作,finally中設ContentWindowViewModel.DialogResult = true自動關窗(含例外也會關)。未指派時維持原本由呼叫端/使用者關閉的行為。
變更
- ContentWindow / NoBorderContentWindow 尺寸邏輯(
TsERP/Other/ContentWindow.xaml.cs、TsERP/Other/NoBorderContentWindow.xaml.cs):IsSizeToContent為true時只設SizeToContent = true、不再指派顯式Width/Height(保持NaN,讓 RadWindow 量測內容自行縮放);否則才套用原本算好的寬高。非 SizeToContent 的彈窗行為不變。
ContentWindow.Window_Loaded(TsERP/Other/ContentWindow.xaml.cs):改為async,並保存內容 VM 參考;視窗顯示後若該 VM 實作IContentWindowLoadedAsync即 await 其工作。
WorkflowPDFHelper.CreatePdfAndShowProgressBar(ViewModel/Other/TodoList/WorkflowPDFHelper.cs):改用ProgressBarViewModel.WorkAsync = () => CreatePdf(...),工作在視窗顯示期間執行;結果以區域變數outcome帶出,失敗才TsMsgBox.ShowError。簽章由async Task改為Task(方法本體已無await,回傳Task.CompletedTask),呼叫端await不受影響。
Breaking Changes
- 無。對外 API(
CreatePdfAndShowProgressBar回傳Task、ShowContentWindow介面)不變。
Migration Notes
- 無需資料或設定異動。
- 既有以舊流程依賴「先關窗才產 PDF」的隱性行為已不存在——原流程實際上需 DialogResult 為 true 才會產 PDF,而進度視窗並無設 true 再關的路徑,屬於原本就可疑的時序;新流程確保 PDF 一定在顯示期間產生。
備註
- 運作原理:
ShowDialog()是模態阻塞,但跑的是巢狀 Dispatcher 訊息迴圈,await CreatePdf的 continuation 仍會回到 UI 執行緒執行,進度條動畫照常;工作完成才設DialogResult關窗,ShowContentWindow才返回,此時outcome已是最終結果。
- 重點:
Telerik RadWindow.SizeToContent型別是bool(非 WPF 原生SizeToContentenum),原程式賦值本身正確,問題在於先設了顯式Width/Height蓋掉縮放。
- 建置:
TsERP(含Common/ViewModel/TsControl)以 VS MSBuild 建置通過。UnitTest1既有 target framework 不符錯誤與本次變更無關。
-
06-09 perdata-signature-view-col ▸
2026-06-09 — vwseek_perdata 加「簽名圖檔1」欄
摘要
員工資料查詢 view
vwseek_perdata補上簽名圖檔1欄,供簽核 / 報表帶出員工簽名圖檔。DBA 部署時執行下列 SQL。(同批
20260609.sql內另含vwlcl_rptdat加「單據別」欄,該段已記於 2026-06-09-db-sql-scripts-backfill,會自動上頁,故此處不重複收錄。)變更
vwseek_perdataview 欄位清單末端新增簽名圖檔1,並sp_refreshview。
Migration Notes
vwseek_perdata 員工查詢 view 加「簽名圖檔1」欄
> 來源:
20260609.sql。員工資料 viewvwseek_perdata補上簽名圖檔1欄並sp_refreshview,供簽核流程 / 報表取用員工簽名圖檔。ALTER VIEW [dbo].[vwseek_perdata] AS SELECT 員工編號, 姓名, 部門代號, email, 公司代碼, 身份證字號, 性別, 到職日期, 銀行帳號, 本國人, 員工別, 員工類別, 職稱, 職級, 簽名圖檔1 FROM dbo.perdata GO EXEC sp_refreshview 'vwseek_perdata'; GO -
06-09 db-sql-scripts-backfill ▸
2026-06-09 — 資料庫 SQL 腳本彙整(SQL 更新頁補錄)
摘要
將先前散落於
c:\temps\sqlscript但尚未進入「SQL 更新」頁的資料庫部署腳本補錄於此,使對外資訊網的 SQL 更新頁能完整顯示。每段為實際可執行的 SQL,DBA 部署時依序執行。(
更新票據系統.sql、alter.sql(procno/bom_m)已分別記於 2026-05-22-cheque-system-workflow-fields、2026-05-21-procno-bom-m-cols,會自動上頁,故此處不重複。)Migration Notes
vwlcl_rptdat 報表清單 view 加「單據別」欄
> 來源:
改變vwlcl_rptdat.sql。報表清單 viewvwlcl_rptdat補上單據別欄並sp_refreshview,供報表依單據別篩選。/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ ALTER VIEW [dbo].[vwlcl_rptdat] AS SELECT TOP (100) PERCENT 報表編號, 報表分類, 報表用途, 報表名稱, excel檔名, 語言版本, 報表尺寸, 排序, 報表抬頭, 報表位置, 國家區域, sqlite, 可顯示, 插件名稱, 是否為遠端, 註腳, 單據別 FROM dbo._rptdat ORDER BY 報表編號 GO EXEC sp_refreshview 'vwlcl_rptdat';rp_m / rp_d / rpsht 加欄位 + view 重建
> 來源:
更新rp_m.sql。應收/收款相關表rp_m/rp_d/rpsht_m/rpsht_d加建檔日期、原幣稅額、含稅欄位等,並重建對應 view。對應 changelog 2026-05-29-rp-m-schema-extend。ALTER TABLE rp_m add [建檔日期] [char](10) NOT NULL DEFAULT ''; ALTER TABLE rp_m add [原幣稅額] [decimal](19,4) NOT NULL DEFAULT 0; ALTER TABLE rp_m add [總原幣未稅] [decimal](19,4) NOT NULL DEFAULT 0; ALTER TABLE rp_m add [總本幣未稅] [decimal](19,4) NOT NULL DEFAULT 0; ALTER TABLE rp_m add [含稅別] [char](1) NOT NULL DEFAULT ''; ALTER TABLE rp_d add [原幣稅額] [decimal](19,4) NOT NULL DEFAULT 0; ALTER TABLE rp_d add [折扣] [decimal](19,4) NOT NULL DEFAULT 0; ALTER TABLE rp_d add [代工價含稅] [decimal](19,4) NOT NULL DEFAULT 0; ALTER TABLE rp_d add [其他金含稅] [decimal](19,4) NOT NULL DEFAULT 0; ALTER TABLE rp_d add [微調原含稅] [decimal](19,4) NOT NULL DEFAULT 0; ALTER TABLE rp_d add [微調本含稅] [decimal](19,4) NOT NULL DEFAULT 0; ALTER TABLE rp_d add [備註] [nvarchar](120) NOT NULL DEFAULT ''; ALTER TABLE rpsht_m add [建檔日期] [char](10) NOT NULL DEFAULT ''; ALTER TABLE rpsht_d add [分類索引4] [nvarchar](30) NOT NULL DEFAULT ''; ALTER TABLE rpsht_d add [單別3] [char](2) NOT NULL DEFAULT ''; ALTER TABLE rpsht_d add [單號3] [nvarchar](20) NOT NULL DEFAULT ''; go ALTER VIEW [dbo].[vw_rpsht_m] AS SELECT dbo.rpsht_m.收付款單號, dbo.rpsht_m.收付款日期, dbo.rpsht_m.收付款別, dbo.rpsht_m.公司代碼, dbo.rpsht_m.客戶代號, dbo.vwseek_cudata.客戶簡稱, dbo.rpsht_m.廠商代號, dbo.vwseek_spdata.廠商簡稱, dbo.rpsht_m.業務員編號, dbo.vwseek_salesmen.姓名, dbo.rpsht_m.備註, dbo.rpsht_m.沖帳備註, dbo.rpsht_m.出納傳票號, dbo.rpsht_m.沖帳傳票號, dbo.rpsht_m.聯絡單id, dbo.rpsht_m.工作流程, dbo.rpsht_m.審核人員, dbo.rpsht_m.審核日期, dbo.rpsht_m.已審核, dbo.rpsht_m.輸入日期, dbo.rpsht_m.輸入人員, dbo.rpsht_m.輸入地點, dbo.rpsht_m.增刪修, dbo.rpsht_m.選擇, dbo.rpsht_m.管制碼, dbo.rpsht_m.srvdbid, dbo.rpsht_m.pkid, dbo.rpsht_m.logid, dbo.rpsht_m.linkid, dbo.rpsht_m.沖帳方式, dbo.rpsht_m.廠商代號1, dbo.rpsht_m.廠商代號2, dbo.rpsht_m.付款匯率日, ISNULL(dbo.vwseek_cudata.付款方式碼, 0) AS 客付方式碼, ISNULL(dbo.vwseek_cudata.付款方式, N'') AS 客付款方式, ISNULL(dbo.vwseek_cudata.收付條件號, N'') AS 客付條件號, ISNULL(dbo.vwseek_cudata.付款條件, N'') AS 客付款條件, dbo.rpsht_m.建檔日期 FROM dbo.rpsht_m LEFT OUTER JOIN dbo.vwseek_salesmen ON dbo.rpsht_m.業務員編號 = dbo.vwseek_salesmen.業務員編號 LEFT OUTER JOIN dbo.vwseek_spdata ON dbo.rpsht_m.廠商代號 = dbo.vwseek_spdata.廠商代號 LEFT OUTER JOIN dbo.vwseek_cudata ON dbo.rpsht_m.客戶代號 = dbo.vwseek_cudata.客戶代號 GO GO ALTER VIEW [dbo].[vw_rpsht_d] AS SELECT dbo.rpsht_d.序號, dbo.rpsht_d.科目代號, ISNULL(dbo.accl.科目名稱, N'') AS 科目名稱, dbo.rpsht_d.摘要, dbo.rpsht_d.客廠代號, dbo.rpsht_d.幣別, dbo.rpsht_d.匯率, dbo.rpsht_d.原借方金額, dbo.rpsht_d.原貸方金額, dbo.rpsht_d.本借方金額, dbo.rpsht_d.本貸方金額, dbo.rpsht_d.部門代號, dbo.rpsht_d.員工編號, dbo.rpsht_d.項目編號, dbo.rpsht_d.專案代號, dbo.rpsht_d.分類索引1, dbo.rpsht_d.分類索引2, dbo.rpsht_d.分類索引3, dbo.rpsht_d.單別1, dbo.rpsht_d.單號1, dbo.rpsht_d.單別2, dbo.rpsht_d.單號2, dbo.rpsht_d.財務單id, dbo.rpsht_d.財務明細id, dbo.rpsht_d.輸入日期, dbo.rpsht_d.輸入人員, dbo.rpsht_d.輸入地點, dbo.rpsht_d.增刪修, dbo.rpsht_d.選擇, dbo.rpsht_d.管制碼, dbo.rpsht_d.srvdbid, dbo.rpsht_d.pkid, dbo.rpsht_d.logid, dbo.rpsht_d.linkid, dbo.rpsht_d.產品群組, dbo.rpsht_d.品號, dbo.rpsht_d.到期日, dbo.rpsht_d.其他id, dbo.rpsht_d.收付款日, dbo.rpsht_d.帳戶代號, ISNULL(dbo.rp_m.單號, N'') AS 單號, ISNULL(dbo.rp_m.發票號碼, N'') AS 發票號碼, ISNULL(dbo.rp_m.備註, N'') AS 備註, dbo.rpsht_d.分類索引4, dbo.rpsht_d.單別3, dbo.rpsht_d.單號3 FROM dbo.rpsht_d LEFT OUTER JOIN dbo.rp_m ON dbo.rpsht_d.單號2 = dbo.rp_m.財務單號 LEFT OUTER JOIN dbo.accl ON dbo.rpsht_d.科目代號 = dbo.accl.科目代號 GO ALTER VIEW [dbo].[vw_rp_m] AS SELECT dbo.rp_m.公司代碼, dbo.rp_m.財務類別, dbo.rpdef.單據名稱, dbo.rp_m.財務單號, dbo.rp_m.收付款單號, dbo.rp_m.相關單號, dbo.rp_m.客廠部代號, dbo.rp_m.收付客廠號, dbo.rp_m.帳款期別, dbo.rp_m.立帳日期, dbo.rp_m.發票日期, dbo.rp_m.發票號碼, dbo.rp_m.回轉日期, dbo.rp_m.單號, dbo.rp_m.參考單號, dbo.rp_m.獎金日期, dbo.rp_m.業務員編號, dbo.rp_m.消費者, dbo.rp_m.原幣應收付, dbo.rp_m.本幣應收付, dbo.rp_m.稅額, dbo.rp_m.幣別, dbo.rp_m.匯率, dbo.rp_m.沖帳原幣, dbo.rp_m.沖帳本幣, dbo.rp_m.稅別, dbo.rp_m.發票抬頭, dbo.rp_m.統一編號, dbo.rp_m.發票金額, dbo.rp_m.收付條件號, dbo.vwseek_payterm.說明, dbo.rp_m.收付款日, dbo.rp_m.到期日, dbo.rp_m.傳票號碼, dbo.rp_m.進銷分類, dbo.rp_m.備註, dbo.rp_m.申請部門, dbo.rp_m.申請人, dbo.rp_m.使用人, dbo.rp_m.申請日期, dbo.rp_m.事由, dbo.rp_m.受款人, dbo.rp_m.付款方式碼, dbo.rp_m.審核人員, dbo.rp_m.審核日期, dbo.rp_m.其他方式, dbo.rp_m.單據張數, dbo.rp_m.月結廠商, dbo.rp_m.隨貨附發票, dbo.rp_m.轉入備註, dbo.rp_m.訂單編號, dbo.rp_m.訂金比率, dbo.rp_m.輸入日期, dbo.rp_m.輸入人員, dbo.rp_m.輸入地點, dbo.rp_m.增刪修, dbo.rp_m.選擇, dbo.rp_m.管制碼, dbo.rp_m.srvdbid, dbo.rp_m.pkid, dbo.rp_m.logid, dbo.rp_m.linkid, dbo.vwseek_salesmen.姓名, dbo.vwseek_taxtype.名稱, dbo.vwseek_dept.部門簡稱, dbo.vwseek_cusp.客廠部簡稱, vwseek_cusp_1.客廠部簡稱 AS 客廠簡稱1, dbo.rp_m.程式類別, dbo.rp_m.使用日期, dbo.rp_m.使用部門, dbo.rp_m.帳款起始日, dbo.rp_m.聯絡單id, dbo.rp_m.工作流程, dbo.rp_m.已審核, dbo.perdata.姓名 AS 申請人姓名, h.姓名 AS 使用人姓名, dbo.rp_m.數量合併, dbo.rp_m.傳票號碼1, dbo.rp_m.交易日期, dbo.rp_m.專案代號, dbo.rp_m.關係人, dbo.rp_m.群組代號, dbo.aproj.專案簡稱, dbo.rp_m.使用截止日, dbo.rp_m.折讓金額, dbo.rp_m.折讓稅額, dbo.rp_m.暫估原幣, dbo.rp_m.暫估本幣, dbo.rp_m.建檔日期, dbo.rp_m.原幣稅額, dbo.rp_m.總原幣未稅, dbo.rp_m.總本幣未稅, dbo.rp_m.含稅別 FROM dbo.rp_m INNER JOIN dbo.rpdef ON dbo.rp_m.財務類別 = dbo.rpdef.財務類別 LEFT OUTER JOIN dbo.aproj ON dbo.rp_m.專案代號 = dbo.aproj.專案代號 LEFT OUTER JOIN dbo.vwseek_cusp AS vwseek_cusp_1 ON dbo.rp_m.收付客廠號 = vwseek_cusp_1.客廠部代號 LEFT OUTER JOIN dbo.vwseek_cusp ON dbo.rp_m.客廠部代號 = dbo.vwseek_cusp.客廠部代號 LEFT OUTER JOIN dbo.vwseek_payterm ON dbo.rp_m.收付條件號 = dbo.vwseek_payterm.收付條件號 LEFT OUTER JOIN dbo.vwseek_salesmen ON dbo.rp_m.業務員編號 = dbo.vwseek_salesmen.業務員編號 LEFT OUTER JOIN dbo.vwseek_dept ON dbo.rp_m.申請部門 = dbo.vwseek_dept.部門代號 LEFT OUTER JOIN dbo.vwseek_taxtype ON dbo.rp_m.稅別 = dbo.vwseek_taxtype.稅別 LEFT OUTER JOIN dbo.perdata ON dbo.rp_m.申請人 = dbo.perdata.員工編號 LEFT OUTER JOIN dbo.perdata AS h ON dbo.rp_m.使用人 = h.員工編號 GO ALTER VIEW [dbo].[vw_rp_d] AS SELECT dbo.rp_d.序號, dbo.rp_d.期別調整, dbo.rp_d.單號pkid, dbo.rp_d.幣別, dbo.rp_d.匯率, dbo.rp_d.科目代號, dbo.rp_d.轉入倉儲, dbo.rp_d.轉出倉儲, dbo.rp_d.交易別碼, dbo.rp_d.品號, dbo.rp_d.品名, dbo.rp_d.客廠品號, dbo.rp_d.其他鍵, dbo.rp_d.數量, dbo.rp_d.單位, dbo.rp_d.單價, dbo.rp_d.代工單價, dbo.rp_d.其他金額, dbo.rp_d.原幣未稅, dbo.rp_d.原幣含稅, dbo.rp_d.本幣未稅, dbo.rp_d.本幣含稅, dbo.rp_d.沖帳原幣, dbo.rp_d.沖帳本幣, dbo.rp_d.單價別, dbo.rp_d.摘要, dbo.rp_d.客廠代號, dbo.rp_d.客廠名稱, dbo.rp_d.統一編號, dbo.rp_d.發票號碼, dbo.rp_d.發票日期, dbo.rp_d.稅別, dbo.rp_d.其他憑證, dbo.rp_d.稅額, dbo.rp_d.發票pkid, dbo.rp_d.輸入日期, dbo.rp_d.輸入人員, dbo.rp_d.輸入地點, dbo.rp_d.增刪修, dbo.rp_d.選擇, dbo.rp_d.管制碼, dbo.rp_d.srvdbid, dbo.rp_d.pkid, dbo.rp_d.logid, dbo.rp_d.linkid, dbo.accl.科目名稱, dbo.rp_d.單號, dbo.rp_d.交易記錄號, dbo.rp_d.需求部門, dbo.rp_d.收付款pkid, dbo.rp_d.產品群組, dbo.grpm.說明, dbo.grpm.分類1, dbo.grpm.分類2, dbo.grpm.分類3, dbo.rp_d.員工編號, dbo.rp_d.缺件說明, dbo.rp_d.缺件後補日, dbo.rp_d.缺件已補, dbo.rp_d.海關代徵號, dbo.rp_d.單據張數1, ISNULL(dbo.vwseek_dept.部門簡稱, N'') AS 部門簡稱, ISNULL(dbo.cusp.客廠部簡稱, N'') AS 客廠部簡稱, dbo.rp_d.含稅單價, dbo.rp_d.客廠訂單號, dbo.rp_d.日期1, dbo.rp_d.微調原幣, dbo.rp_d.微調本幣, dbo.rp_d.原幣稅額, dbo.rp_d.折扣, dbo.rp_d.代工價含稅, dbo.rp_d.其他金含稅, dbo.rp_d.微調原含稅, dbo.rp_d.微調本含稅, dbo.rp_d.備註 FROM dbo.rp_d LEFT OUTER JOIN dbo.cusp ON dbo.rp_d.客廠代號 = dbo.cusp.客廠部代號 LEFT OUTER JOIN dbo.accl ON dbo.rp_d.科目代號 = dbo.accl.科目代號 LEFT OUTER JOIN dbo.grpm ON dbo.rp_d.產品群組 = dbo.grpm.群組代號 LEFT OUTER JOIN dbo.vwseek_dept ON dbo.rp_d.需求部門 = dbo.vwseek_dept.部門代號 GO EXEC sp_refreshview N'dbo.vw_rp_m'; EXEC sp_refreshview N'dbo.vw_rp_d'; EXEC sp_refreshview N'dbo.vw_rpsht_m'; EXEC sp_refreshview N'dbo.vw_rpsht_d';datatpld 任職經歷範本資料 (CMSA 專屬)
> 來源:
adddatapl.sql。datatpld寫入「任職經歷」P1_4_B 範本欄位定義(客戶 CMSA 專屬資料種子)。INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'1 ', N'原任職公司 ', N'C', 30, 0, N'服務機關名稱', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_4_B_任職經歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 1, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'2 ', N'原部門 ', N'C', 30, 0, N'部門/職稱', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_4_B_任職經歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 2, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'3 ', N'原任職日期 ', N'C', 10, 0, N'到職日', N'9999/99/99', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_4_B_任職經歷', CAST(N'2019-04-18T17:18:41.633' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 3, 215195, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'4 ', N'原離職日期 ', N'C', 10, 0, N'離職日', N'9999/99/99', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_4_B_任職經歷', CAST(N'2019-04-18T17:18:41.633' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 4, 215195, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'5 ', N'原待遇 ', N'N', 18, 6, N'薪資(月)', N'999,999,999', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_4_B_任職經歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 5, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'6 ', N'原工作內容 ', N'C', 80, 0, N'主要工作', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_4_B_任職經歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 6, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'7 ', N'原離職原因 ', N'C', 80, 0, N'離職原因', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_4_B_任職經歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 7, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'8 ', N'學校名稱 ', N'C', 30, 0, N'學校名稱', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_3_B_學歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 8, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'9 ', N'院系科別 ', N'C', 30, 0, N'院系科別', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_3_B_學歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 9, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'10 ', N'修業年月起 ', N'C', 7, 0, N'修業起始年月', N'9999/99', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_3_B_學歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 10, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'11 ', N'修業年月迄 ', N'C', 7, 0, N'修業結束年月', N'9999/99', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_3_B_學歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 11, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'12 ', N'是否畢業 ', N'C', 1, 0, N'畢/肄', N'Y', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_3_B_學歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 12, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'13 ', N'學位 ', N'C', 30, 0, N'學位', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_3_B_學歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 13, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'14 ', N'眷屬稱謂 ', N'C', 10, 0, N'稱謂', N'XXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_2_B_眷屬資料', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 14, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'15 ', N'眷屬姓名 ', N'C', 10, 0, N'姓名', N'XXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_2_B_眷屬資料', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 15, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'16 ', N'眷屬出生 ', N'C', 10, 0, N'出生日期', N'9999/99/99', N'CHKDATE', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_2_B_眷屬資料', CAST(N'2014-06-09T00:04:00.727' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 16, 64740, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'17 ', N'眷屬職業 ', N'C', 20, 0, N'職業', N'XXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_2_B_眷屬資料', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 17, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'18 ', N'緊急聯絡人 ', N'C', 20, 0, N'姓名', N'XXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_1_B_緊急聯絡人', CAST(N'2022-10-13T17:20:14.240' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 18, 526961, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'19 ', N'緊急關係 ', N'C', 10, 0, N'關係', N'XXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_1_B_緊急聯絡人', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 19, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'20 ', N'緊急電話 ', N'C', 20, 0, N'電話', N'XXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_1_B_緊急聯絡人', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 20, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'21 ', N'緊急地址 ', N'C', 80, 0, N'地址', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_1_B_緊急聯絡人', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 21, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'48 ', N'身份證號 ', N'C', 14, 0, N'身份證號', N'XXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_2_B_眷屬資料', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 55, 64734, 3) GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'49 ', N'眷屬關係 ', N'C', 10, 0, N'眷屬關係', N'XXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_2_B_眷屬資料', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 56, 64734, 3) GO INSERT [dbo].[datatplm] ([資料模板號], [說明], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'P1 ', N'人事明細資料', CAST(N'2012-10-04T15:32:02.280' AS DateTime), N'令狐沖', N'WXWG101234 # wg101', N' ', N' ', 0, 1, 3, 2109, 0) GOTWORK_AI_QUERY 預存程序 (AI 查詢)
> 來源:
TWORK_AI_QUERY.sql。AI 智慧查詢預存程序TWORK_AI_QUERY(含白名單檢查)。亦版控於 SqlBI/TWORK_AI_QUERY.sql。對應 changelog 2026-04-22 / 2026-06-02。USE [darbnogicsa1] GO /****** Object: StoredProcedure [dbo].[TWORK_AI_QUERY] Script Date: 2026/6/2 下午 06:40:06 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- 預存程序:TWORK_AI_QUERY -- 參數(配合 Log_Sys_Exec 的 LP 慣例): -- LP_DATAEVENT 事件名稱(Log 用) -- LP_P1 使用者代號 -- LP_P2 AI 生成的 SELECT 語句 -- LP_P3 使用者原始問題描述 -- LP_P4 最大回傳筆數(字串,預設 "200") -- ============================================= ALTER PROCEDURE [dbo].[TWORK_AI_QUERY] @LP_P1 NVARCHAR(50) = '', -- UserId @LP_P2 NVARCHAR(MAX) = '', -- GeneratedSQL @LP_P3 NVARCHAR(500) = '', -- Description @LP_P4 NVARCHAR(10) = '200' -- MaxRows AS BEGIN SET NOCOUNT ON; DECLARE @ErrorMsg NVARCHAR(500); DECLARE @FinalSQL NVARCHAR(MAX); DECLARE @UpperSQL NVARCHAR(MAX); DECLARE @MaxRows INT = TRY_CAST(@LP_P4 AS INT); IF @MaxRows IS NULL OR @MaxRows <= 0 SET @MaxRows = 200; -- ----------------------------------------------- -- 1. 基本驗證 -- ----------------------------------------------- IF @LP_P2 IS NULL OR LTRIM(RTRIM(@LP_P2)) = '' BEGIN SET @ErrorMsg = 'SQL 語句不可為空白'; INSERT INTO _ai_query_log (使用者代號, 查詢描述, 執行SQL, 執行結果) VALUES (@LP_P1, @LP_P3, @LP_P2, @ErrorMsg); RAISERROR(@ErrorMsg, 16, 1); RETURN; END SET @UpperSQL = UPPER(LTRIM(RTRIM(@LP_P2))); -- ----------------------------------------------- -- 2. 只允許 SELECT -- ----------------------------------------------- IF LEFT(@UpperSQL, 6) <> 'SELECT' BEGIN SET @ErrorMsg = '只允許 SELECT 查詢語句'; INSERT INTO _ai_query_log (使用者代號, 查詢描述, 執行SQL, 執行結果) VALUES (@LP_P1, @LP_P3, @LP_P2, @ErrorMsg); RAISERROR(@ErrorMsg, 16, 1); RETURN; END -- ----------------------------------------------- -- 3. 禁止危險關鍵字 -- ----------------------------------------------- IF @UpperSQL LIKE '%INSERT%' OR @UpperSQL LIKE '%UPDATE%' OR @UpperSQL LIKE '%DELETE%' OR @UpperSQL LIKE '%DROP%' OR @UpperSQL LIKE '%CREATE%' OR @UpperSQL LIKE '%ALTER%' OR @UpperSQL LIKE '%TRUNCATE%' OR @UpperSQL LIKE '%MERGE%' OR @UpperSQL LIKE '%EXEC%' OR @UpperSQL LIKE '%EXECUTE%' OR @UpperSQL LIKE '%XP[_]%' OR @UpperSQL LIKE '%SP[_]%' OR @UpperSQL LIKE '%;%' OR @UpperSQL LIKE '%--' OR @UpperSQL LIKE '%OPENROWSET%' OR @UpperSQL LIKE '%OPENDATASOURCE%' BEGIN SET @ErrorMsg = '偵測到不允許的 SQL 語法,查詢已被拒絕'; INSERT INTO _ai_query_log (使用者代號, 查詢描述, 執行SQL, 執行結果) VALUES (@LP_P1, @LP_P3, @LP_P2, @ErrorMsg); RAISERROR(@ErrorMsg, 16, 1); RETURN; END -- ----------------------------------------------- -- 3.5 白名單檢查:FROM/JOIN 後的表名必須登記在 _ai_schema -- (防 AI 幻覺 / prompt injection 超出白名單) -- ----------------------------------------------- DECLARE @scan NVARCHAR(MAX) = ' ' + @UpperSQL + ' '; SET @scan = REPLACE(REPLACE(REPLACE(@scan, CHAR(13), ' '), CHAR(10), ' '), CHAR(9), ' '); DECLARE @tables TABLE (tbl NVARCHAR(200)); DECLARE @searchFrom INT, @pos INT, @tokStart INT, @tokEnd INT, @token NVARCHAR(200); -- 掃 FROM SET @searchFrom = 1; WHILE 1 = 1 BEGIN SET @pos = CHARINDEX(' FROM ', @scan, @searchFrom); IF @pos = 0 BREAK; SET @tokStart = @pos + 6; WHILE SUBSTRING(@scan, @tokStart, 1) = ' ' SET @tokStart += 1; SET @tokEnd = @tokStart; WHILE @tokEnd <= LEN(@scan) AND CHARINDEX(SUBSTRING(@scan, @tokEnd, 1), ' ,;()') = 0 SET @tokEnd += 1; SET @token = SUBSTRING(@scan, @tokStart, @tokEnd - @tokStart); SET @token = REPLACE(REPLACE(@token, '[', ''), ']', ''); IF CHARINDEX('.', @token) > 0 SET @token = SUBSTRING(@token, CHARINDEX('.', @token) + 1, 500); IF LEN(@token) > 0 INSERT INTO @tables (tbl) VALUES (LOWER(@token)); SET @searchFrom = @tokEnd + 1; END -- 掃 JOIN(INNER/LEFT/RIGHT/FULL/CROSS JOIN 都會命中 ' JOIN ') SET @searchFrom = 1; WHILE 1 = 1 BEGIN SET @pos = CHARINDEX(' JOIN ', @scan, @searchFrom); IF @pos = 0 BREAK; SET @tokStart = @pos + 6; WHILE SUBSTRING(@scan, @tokStart, 1) = ' ' SET @tokStart += 1; SET @tokEnd = @tokStart; WHILE @tokEnd <= LEN(@scan) AND CHARINDEX(SUBSTRING(@scan, @tokEnd, 1), ' ,;()') = 0 SET @tokEnd += 1; SET @token = SUBSTRING(@scan, @tokStart, @tokEnd - @tokStart); SET @token = REPLACE(REPLACE(@token, '[', ''), ']', ''); IF CHARINDEX('.', @token) > 0 SET @token = SUBSTRING(@token, CHARINDEX('.', @token) + 1, 500); IF LEN(@token) > 0 INSERT INTO @tables (tbl) VALUES (LOWER(@token)); SET @searchFrom = @tokEnd + 1; END -- 比對 _ai_schema.sql_name(不分大小寫) IF EXISTS ( SELECT 1 FROM @tables t WHERE NOT EXISTS ( SELECT 1 FROM _ai_schema s WHERE LOWER(LTRIM(RTRIM(s.sql_name))) = t.tbl ) ) BEGIN SET @ErrorMsg = '查詢包含不在白名單 (_ai_schema) 的資料表,已被拒絕'; INSERT INTO _ai_query_log (使用者代號, 查詢描述, 執行SQL, 執行結果) VALUES (@LP_P1, @LP_P3, @LP_P2, @ErrorMsg); RAISERROR(@ErrorMsg, 16, 1); RETURN; END -- ----------------------------------------------- -- 4. 加上 TOP 限制 -- ----------------------------------------------- IF PATINDEX('%SELECT TOP %', @UpperSQL) = 0 AND PATINDEX('%SELECT TOP(%', @UpperSQL) = 0 AND PATINDEX('%SELECT DISTINCT TOP %', @UpperSQL) = 0 AND @UpperSQL NOT LIKE '%FETCH NEXT%' BEGIN DECLARE @SelectPos INT = CHARINDEX('SELECT', @UpperSQL); SET @FinalSQL = LEFT(@LP_P2, @SelectPos + 5) + ' TOP (' + CAST(@MaxRows AS NVARCHAR(10)) + ') ' + SUBSTRING(@LP_P2, @SelectPos + 7, LEN(@LP_P2)); END ELSE BEGIN SET @FinalSQL = @LP_P2; END -- ----------------------------------------------- -- 5. 記錄 Log -- ----------------------------------------------- INSERT INTO _ai_query_log (使用者代號, 查詢描述, 執行SQL, 執行結果) VALUES (@LP_P1, @LP_P3, @FinalSQL, 'OK'); -- ----------------------------------------------- -- 6. 執行查詢 -- ----------------------------------------------- BEGIN TRY EXEC sp_executesql @FinalSQL; END TRY BEGIN CATCH DECLARE @CatchMsg NVARCHAR(500) = ERROR_MESSAGE(); UPDATE _ai_query_log SET 執行結果 = 'ERROR: ' + @CatchMsg WHERE pkid = SCOPE_IDENTITY(); RAISERROR(@CatchMsg, 16, 1); END CATCH ENDDARB_LOG_SYS_AI_EXEC 預存程序 (AI log 轉發)
> 來源:
DARB_LOG_SYS_EXEC_AI.sql。log 庫 AI 執行轉發預存程序DARB_LOG_SYS_AI_EXEC(複製 DARB_LOG_SYS_EXEC 改寫 log_sys_ai)。對應 changelog 2026-06-05。USE [darbnogilog1] GO /****** Object: StoredProcedure [dbo].[DARB_LOG_SYS_EXEC] Script Date: 2026/6/5 下午 04:42:41 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO Create PROCEDURE [dbo].[DARB_LOG_SYS_AI_EXEC] (@languagen INT,@eventtype nvarchar(10),@dataevent nvarchar(30),@datafunc nvarchar(30),@param1 nvarchar(500) OUTPUT,@param2 nvarchar(MAX), @param3 nvarchar(1000),@param4 nvarchar(200),@param5 nvarchar(200),@param6 nvarchar(200),@param7 nvarchar(200), @param8 nvarchar(200),@param9 nvarchar(200),@param10 nvarchar(200),@param11 nvarchar(200),@param12 nvarchar(200), @inputstaff nvarchar(20),@localtime datetime,@inputplace nvarchar(18),@srvdbid int,@log_sys_pkid int output,@result nchar(254) output) --2010/12/08 將 @param2 nvarchar(200) 改成 @param2 nvarchar(2000),配合 DARB_BROWSE WITH EXECUTE AS 'foxrunprg' AS BEGIN SET NOCOUNT ON; DECLARE @status1 nchar(6),@errornumber INT,@errormessage NCHAR(238),@sqlstring NVARCHAR(200), @databaseid char(1),@param_qty smallint,@paramoutput CHAR(1),@is_fail char(1), @csadbname nvarchar(20)=SUBSTRING(DB_NAME(),1,CHARINDEX('log',DB_NAME())-1)+'csa'+SUBSTRING(DB_NAME(),CHARINDEX('log',DB_NAME())+3,3) ; SELECT @errornumber='',@errormessage='',@is_fail='N' INSERT INTO dbo.log_sys_ai (languagen,eventtype,dataevent,datafunc, param1,param2,param3,param4,param5,param6,param7,param8,param9,param10,param11,param12, status1,inputstaff,localtime,inputplace,servertime,starttime,srvdbid) VALUES (@languagen,@eventtype,@dataevent,@datafunc, @param1,@param2,@param3,@param4,@param5,@param6,@param7,@param8,@param9,@param10,@param11,@param12, '',@inputstaff,@localtime,@inputplace,GETDATE(),GETDATE(),@srvdbid); SET @log_sys_pkid=scope_identity()--log_sys 的pkid 是 自動加 1 SELECT @databaseid=databaseid,@param_qty=param_qty,@paramoutput=paramoutput FROM proc_param where datafunc=@datafunc IF @@ROWCOUNT=1 BEGIN IF @databaseid='C' -- 代表是darbcsa 1~N SET @sqlstring=@csadbname+'.dbo.'+@datafunc; --N'darbcsa'+SUBSTRING(DB_NAME(),8,6)+'.dbo.'+@datafunc; ELSE -- 代表是darblog 1~N SET @sqlstring='dbo.'+@datafunc; BEGIN TRY IF @paramoutput='Y' --只有第一個參數 OUTPUT BEGIN --IF @param_qty=0 應該要有參數 OUTPUT -- EXEC @sqlstring IF @param_qty=1 EXEC @sqlstring @param1 OUTPUT IF @param_qty=2 EXEC @sqlstring @param1 OUTPUT,@param2 IF @param_qty=3 EXEC @sqlstring @param1 OUTPUT,@param2,@param3 IF @param_qty=4 EXEC @sqlstring @param1 OUTPUT,@param2,@param3,@param4 IF @param_qty=5 EXEC @sqlstring @param1 OUTPUT,@param2,@param3,@param4,@param5 IF @param_qty=6 EXEC @sqlstring @param1 OUTPUT,@param2,@param3,@param4,@param5,@param6 IF @param_qty=7 EXEC @sqlstring @param1 OUTPUT,@param2,@param3,@param4,@param5,@param6,@param7 IF @param_qty=8 EXEC @sqlstring @param1 OUTPUT,@param2,@param3,@param4,@param5,@param6,@param7,@param8 IF @param_qty=9 EXEC @sqlstring @param1 OUTPUT,@param2,@param3,@param4,@param5,@param6,@param7,@param8,@param9 IF @param_qty=10 EXEC @sqlstring @param1 OUTPUT,@param2,@param3,@param4,@param5,@param6,@param7,@param8,@param9,@param10 IF @param_qty=11 EXEC @sqlstring @param1 OUTPUT,@param2,@param3,@param4,@param5,@param6,@param7,@param8,@param9,@param10,@param11 IF @param_qty=12 EXEC @sqlstring @param1 OUTPUT,@param2,@param3,@param4,@param5,@param6,@param7,@param8,@param9,@param10,@param11,@param12 END ELSE BEGIN IF @param_qty=0 EXEC @sqlstring IF @param_qty=1 EXEC @sqlstring @param1 IF @param_qty=2 EXEC @sqlstring @param1,@param2 IF @param_qty=3 EXEC @sqlstring @param1,@param2,@param3 IF @param_qty=4 EXEC @sqlstring @param1,@param2,@param3,@param4 IF @param_qty=5 EXEC @sqlstring @param1,@param2,@param3,@param4,@param5 IF @param_qty=6 EXEC @sqlstring @param1,@param2,@param3,@param4,@param5,@param6 IF @param_qty=7 EXEC @sqlstring @param1,@param2,@param3,@param4,@param5,@param6,@param7 IF @param_qty=8 EXEC @sqlstring @param1,@param2,@param3,@param4,@param5,@param6,@param7,@param8 IF @param_qty=9 EXEC @sqlstring @param1,@param2,@param3,@param4,@param5,@param6,@param7,@param8,@param9 IF @param_qty=10 EXEC @sqlstring @param1,@param2,@param3,@param4,@param5,@param6,@param7,@param8,@param9,@param10 IF @param_qty=11 EXEC @sqlstring @param1,@param2,@param3,@param4,@param5,@param6,@param7,@param8,@param9,@param10,@param11 IF @param_qty=12 EXEC @sqlstring @param1,@param2,@param3,@param4,@param5,@param6,@param7,@param8,@param9,@param10,@param11,@param12 END END TRY BEGIN CATCH set @status1='NG' UPDATE dbo.log_sys_ai SET status1='NG',endtime=GETDATE() WHERE srvdbid=@srvdbid and pkid=@log_sys_pkid insert into log_error(logid,錯誤代碼,錯誤嚴重性,錯誤狀態碼,錯誤程序,錯誤行號,錯誤訊息,srvdbid) select -@log_sys_pkid,error_number() as 錯誤代碼,error_severity() as 錯誤嚴重性, error_state() as 錯誤狀態碼,error_procedure() as 錯誤程序, error_line() as 錯誤行號,error_message() as 錯誤訊息,@srvdbid ; select @errornumber=error_number(),@errormessage=error_message() SET @is_fail='Y' END CATCH IF @is_fail='N' BEGIN UPDATE dbo.log_sys_ai SET status1='OK',endtime=GETDATE() WHERE srvdbid=@srvdbid and pkid=@log_sys_pkid set @status1='OK' END set @result=@status1+N','+convert(nchar(6),@errornumber)+N','+@errormessage END ENDBreaking Changes
- 無(皆為加欄位 / 建立物件 / 資料種子,向後相容)。
-
06-08 supportpanel-attachment-workflow-hint ▸
2026-06-08 — 操作面板:附件 / 工作流程分頁有資料時標題顯示筆數
摘要
在表單操作面板右側的支援分頁(SupportPanel)中,「附件」與「工作流程」分頁的清單若有資料,分頁標題文字旁會以紅字顯示筆數「(N)」(hover 顯示提示「此頁籤資料筆數」),讓使用者不必逐一點開分頁,就能一眼看出目前單據帶有幾筆附件或工作流程。
新增
TabViewModel.HasData/TabViewModel.DataCount(ViewModel/Control/Layout/Tab/TabViewModel.cs):分頁基底新增bool HasData(預設false,控制提示是否顯示)與int DataCount(清單筆數,供標題顯示「(N)」)。其他分頁不設定即維持false/0(不顯示)。
- SupportPanel 分頁標題筆數提示(
TsControl/PageParts/SupportPanel.xaml):TabControl.ItemTemplate由單純文字改為「文字 + 筆數」;筆數為紅字TsTextBlock,Text綁DataCount並以StringFormat=({0})格式化,Visibility綁HasData(透過新增的BooleanToVisibilityConverter資源HasDataToVisibility),並附ToolTip="此頁籤資料筆數"。
變更
AttachmentTabViewModel.Attachmentsetter(ViewModel/Control/Layout/Tab/AttachmentTabViewModel.cs):設定DataCount = value?.Count ?? 0、HasData = DataCount > 0。SetDataGrid()載入實際附件後即反映;Init()/Clear()設空清單時為0/false。
WorkflowTabViewModel.Workflowsetter(ViewModel/Control/Layout/Tab/WorkflowTabViewModel.cs):設定DataCount = value?.Count ?? 0、HasData = DataCount > 0。SetWorkFlowDataGrid()載入後反映;無工作流程時為0/false。
Breaking Changes
- 無。純新增 UI 提示,不影響既有行為與資料。
備註
- 提示來源是分頁實際載入的清單(附件走
LocalDbContext.Attachment、工作流程走LocalDbContext.WorkflowStep),清單一旦重新載入(換單據/查詢)即時更新提示點。
- 建置:
ViewModel與TsControl專案以 VS MSBuild 建置通過(dotnet build因 Office COM 參考的MSB4803 ResolveComReference無法用,需用 VS 版 MSBuild)。
-
06-08 scx-pdt-compare-and-alltrim-binding-fixes ▸
2026-06-08 生產模組(scx_pdt)VFP 對比+ALLTRIM/binding 修正
摘要
對 VFP
scx_pdtlibrary(生產模組,14 個 class)完成 VFP↔新版逐項對比,並修補兩類確認的 bug:1.
ALLTRIM(...)被當字面字串塞進 SQL —PdtinfEdit/WkpaperEdit的「已耗料/已領料/已排程不得修改」防呆全部失效。2. Pdtinf.xaml 中英 binding typo — 品名、單位欄綁到不存在的英文屬性,永遠空白且寫不回。
對比同時發現 F.Production 三支單據(pdtinf/wkpaper/wkday)有更大的「載入層未完成」🔴(Source 未註冊 LocalDbContext),本批未修,列於下方待辦。
變更
修正 1 — ALLTRIM 字面 SQL(LogicBll,已 dotnet build 通過)
VFP 原意
ALLTRIM(派工單_V.派工單號)是將注入值去空白,新版誤將整段ALLTRIM(...)當字串寫進 SQL 條件(如WorkOrderNo LIKE 'ALLTRIM(PD0001)%'),永遠 match 不到 → 防呆形同虛設。改在 C# 端.Trim(),運算子維持原樣:WkpaperEdit.cs:55(CheckMaterialUsage,精確比對=)
WkpaperEdit.cs:75(CheckWorkOrderPicking,前綴LIKE %)
PdtinfEdit.cs:47(CheckMaterialUsage,LIKE %)
PdtinfEdit.cs:67(CheckWorkOrderPicking,LIKE %)
PdtinfEdit.cs:87(CheckWorkOrderScheduling,LIKE %)+ 順手移除假別名A./B.:此方法為單表查詢無 join,欄位都在主表 vw_wkpaper,原本 copy-paste 自有 join 的 picking 方法導致 SQL 必錯(不修則 ALLTRIM 修了也無效)。
加
(x ?? "")防 null,與舊行為一致。修正 2 — Pdtinf.xaml binding typo(TsERP,需 VS build 驗證)
Source 公開屬性是中文
品名(Twork_pdt_vw_pdtinfmaSource.cs:717)、單位(:177),英文名只有 private 欄位:Pdtinf.xaml:96{Binding SKUDescription}→{Binding 品名}(搜尋框描述)
Pdtinf.xaml:115{Binding SKUDescription}→{Binding 品名}(唯讀品名框)
Pdtinf.xaml:154{Binding UnitOfMeasurement}→{Binding 單位}(單位 combo)
已交叉比對 Pdtinf.xaml 全部 binding path,確認無其他漏網 typo。
行為變更提醒
- 修改/刪除防呆恢復:拿一張已耗料/已領料/已排程的製通單(pdtinf)或派工單(wkpaper)去改,會被擋下或跳通知(先前完全不作用)。
- 製通單品名/單位顯示:輸入品號後品名欄、單位欄會正確帶值並可儲存(先前永遠空白)。
- ⚠️ 上述兩項目前 runtime 還測不到 — F.Production 三支單據因 Source 未註冊 LocalDbContext,開窗載入即例外,需先解該載入層問題才能實測。
對比結果:scx_pdt 移植狀態
VFP class 內容 狀態 pdtinf 製造通知單 ⚠️ 有,載入層+按鈕斷線、本批修了 ALLTRIM/binding wkpaper 派工單 ⚠️ 有,載入層斷線、4 功能鈕全缺、本批修了 ALLTRIM wkday 生產實績(含 wkday2 工時) ⚠️ 有,載入層斷線 mrp MRP 計算 🔴 引擎有單元測試但 UI 開不起來/查不出 wkday2 生產工時 🟢 已併入 Wkday perdata1 人事資料(精簡) 🟢 R.HumanResource/Perdata 已涵蓋 wkng 例不良單 🟡 只有 Model/Source,無 UI/VM wknpdt 非生產工時 🟡 只有 Model/Source,無 UI/VM perdmd 要員需求(樞紐) ❌ 未移植 pd_qry5 缺料/進度查詢 ❌ 未移植 pd_qry9 OEE 查詢 ❌ 未移植 wkpaper_brow 樞紐分析 🟢 通用樞紐已覆蓋 wkpaper_bd 委外派工單報表 🟡 含金額兩版報表未實作 尚未處理(已對比出、待後續)
- 🔴 F.Production 載入層未完成:pdtinf/wkpaper/wkday(及 OutSourcingFillRate)的 Source 型別全未註冊進
LocalDbContext的 DbSet,新 DataManager 堆疊Load()走_db.Set<T>()會丟例外 → 開窗載入即崩。wkday 另有英文[TsColumnName]對不上中文 DB view,補註冊後仍需中文化。
- pdtinf:Pdtinf_1/_2(轉單/計畫表)BLL 完整但 DataContext=null、VM 孤兒(疑似十多個轉單視窗系統性未完成);「改數量」(DARB_TUR_PDTINF_QTY SP 已在等)/「特殊修改」未移植;輸入訂單 pkid 不自動帶客戶代號。
- wkpaper:設變/製程表/排程/特殊修改 4 鈕全缺;AllowSave 缺工程代號必填;缺「單價=代工+代料」自動計算;opmode 權限欄管制消失。
- mrp:
MrpViewModel.Query()結果未接回 VM;{StaticResource TwoDecimalPlaces}全 repo 無定義(XamlParseException);SPTWORK_QRY_MRP不存在;替換後品號 stub;轉請購/轉製通(MRP 閉環)整批未移植。
- wkday:刪耗料用
MaterialUsageTransactionPkid但 view 無此欄;工時自動計算(UPDT_WKTIME)、作業者在職驗證未移植。
- 未移植 class:wkng/wknpdt(半成品)、perdmd/pd_qry5/pd_qry9(無對應)待規劃。
- 被開的 .scx 子表單(PDTINF_QTY/DESIGNC/WKPAPER_T_NEW/WKPAPERH/WKDAY_TR 等)原始碼在
C:\DARB_FOX\NOGIHISA\FORMS\未匯出.prg,遞迴對比需另匯出。
Migration Notes
無需資料遷移。
LogicBlldotnet build 通過(0 errors);Pdtinf.xaml屬 TsERP.csproj,dotnet CLI 撞既有 MSB4803,需 VS MSBuild 驗證。 -
06-08 payapply-compare-fixes ▸
2026-06-08 費用申請(payapply_kc)VFP 對比修正
摘要
對 SCX_ARP library 最後一支
payapply_kc(費用申請)完成 VFP↔新版逐項對比(欄位 / allowsave / allowedit / addagain / 事件 / 按鈕 / DB schema),修掉反推未稅金額錯誤、付款條件到期日與匯率查詢日的日期連動、明細欄誤綁、日期連動帶值、以及補上統一編號檢查碼驗證。至此 scx_arp 全 15 class 對比完成。按鈕接線本就完整(轉傳票
IOther1→PayapplyToGl、特殊修改IOther2→SpecialEdit、工作流程/快速審核走集中式 workflow);PayapplySave/PayapplyEdit命名「Payapply」為正確命名(非孤兒,工廠正常載入),本次未動。變更
金額計算(Model)
- 反推未稅除數修正(
Rp_dForPayapplyBindingSource.反推未稅)
- 原
本幣未稅 = 本幣含稅 / (taxRate / 100),稅率 5% 時等於 ÷0.05 = ×20。- 改為
本幣未稅 = 本幣含稅 / (1 + taxRate / 100),對齊 VFP本幣含稅/(100+稅率)*100與正向CalculateTax慣例(GetTaxRate回傳百分比數字,5 代表 5%)。日期連動(Model / ViewModel / XAML)
- 付款條件到期日/付款日、TsCurrency 匯率查詢日改用申請日期
- VFP 付款條件
U_PAYTERMDATE與匯率U_BLRATE使用日期皆以申請日期為基準,但新版SetDueDate()與TsCurrency Date綁的是交易日期,而 payapply 全程從未設過交易日期(恆為空)→ 到期日/付款日算不出、外幣匯率查不到。-
Rp_mForPayapplyBindingSource新增申請日期Binding:設申請日期時同步寫入交易日期,驅動SetDueDate與TsCurrency。-
Payapply.xaml申請日期欄改綁申請日期Binding。-
Payapply_kcViewModel.AfterAddNew補交易日期 = 申請日期,新單即具備匯率日/到期基準。- 申請日期/立帳日期改值連動 帳款期別、使用日期、使用截止日(對應 VFP
申請日期.LostFocus/立帳日期.LostFocus)
- 新增共用
SetUsagePeriod():帳款期別 = 日期前 7 碼;使用日期(月初)、使用截止日(月末)空白才帶(不覆蓋使用者輸入)。-
Rp_mForPayapplyBindingSource新增立帳日期Binding,Payapply.xaml立帳日期欄改綁立帳日期Binding;申請日期亦透過申請日期Binding連動。明細欄位(XAML)
- 「原幣稅額」欄修正綁定:原綁
稅額(本幣稅額),改綁原幣稅額。該欄位於原幣未稅/原幣含稅之間,標題與內容原本不符。
- 發票日期欄改為可輸入:移除
ForceReadOnly="True"(VFPcol發票日期為可輸入,特殊修改模式另開放)。
- 採購單號(缺件說明)欄改為可寫回:
Mode=OneWay→Mode=TwoWay, UpdateSourceTrigger=LostFocus,原本使用者輸入不會存。
新增單據預設值(ViewModel)
- 進銷分類預設改為沿用前一筆,無前一筆則「費用支出」(
Payapply_kcViewModel,對應 VFP addagain:抓當前筆進銷分類,新空白筆若空就帶,前一筆有值用前一筆否則1.費用支出)
- 新增欄位
last進銷分類,於AfterMoverRecord擷取目前顯示這筆的進銷分類(導覽/存檔後皆更新);新增流程Add()不呼叫AfterMoverRecord,故新增當下不會被空白筆覆蓋。-
AfterAddNew移除原本寫死的進銷分類 = "6"(直接沖帳)與重複賦值,改為沿用last進銷分類、空則DocumentCategoryEnum.Expense.Code(="1" 費用支出)。統一編號檢查碼(LogicBll)
- 主檔/明細統一編號補檢查碼驗證(
PayapplySave.AllowSave,對應 VFP 主檔統一編號.Valid與明細text1.Valid),共用Util2017.CheckTaxID(InvoiceArea.T, …):
- 主檔:
00000000豁免 → 8 碼走統編檢查碼 → 10 碼放行 → 其餘長度回「請輸入正確的資料」。- 明細:
'A'開頭豁免(人事資料轉來)→ 同 8/10/其他長度規則。- A 方案:10 碼身分證僅放行、不驗檢查碼(repo 無 ROC 身分證檢查碼工具,且 payapply 多為公司行號)。與 VFP 差異:VFP 明細嚴格只做 8 碼 T1,此處比照主檔放行 10 碼,避免誤擋個人 ID。
Breaking Changes / Migration Notes
無資料結構變更。皆為驗證/連動/綁定行為修正。
- 反推未稅鈕的結果由錯誤(×20)變為正確,舊單若曾用該鈕產生過金額,重存時會被正向
HandleDataBeforeEndEdit重算修正。
- 統編檢查碼上線後,原本存有非法統編(非 00000000、非 8 碼合法、非 10 碼、非 'A' 開頭)的單據在再次存檔時會被擋下,須修正統編後才能存。
驗證
dotnet build Model/Model.csproj、dotnet build LogicBll/LogicBll.csproj皆 0 錯誤。
- XAML/ViewModel 變更需於 Visual Studio build 確認(dotnet CLI 對 TsERP/ViewModel 會撞既有 MSB4803,與本次無關)。
- 業務面驗收:新增→輸入廠商→確認到期日/付款日自動算、外幣依申請日期帶匯率;改申請日期→帳款期別跟著變、使用日期/截止日空白時自動帶月初月末;反推未稅鈕金額正確;輸入非法統編存檔被擋。
- 反推未稅除數修正(
-
06-06 wkflowt-enum-fixes-and-chinese ▸
2026-06-06 工作流程樣板列舉修正 + TodoList 列舉系統值改中文
摘要
修正工作流程樣板(
WKFLOWT)明細的處理事項/狀態/優先順序下拉連動,新增處理事項選擇時的自動帶值規則,並將 TodoList 三組列舉的
SystemDescription(存 DB 的系統值)由英文改為中文。新增
- Wkflowt 處理事項下拉連動(
Twork_sys_vw_wkflowt_dSource.JobCodeEnum):
- 選「發行」→ 自動帶
GetSender預設值(審核順序 0、序號 00、狀態已完成、完成率 100…),處理部門設為登入者佔位符#I#(pkid/linkid 保留由 DataManager 管理)- 選「初審」「複審」→
流程結束 = A(核准)- 選「核定」→
流程結束 = Y(結束)- 選其他(通知/確認/承認)→
流程結束清空Twork_com_vw_commpr_2Source.SetSignInUserWhenPlaceholder()幫助方法:
處理部門為
#I#時清空部門並帶入登入者為處理人(含 email)。變更
TodoListJobCodeEnum/TodoListStatusCodeEnum/TodoListPriorityCodeEnum的
SystemDescription由英文(Notify、NotHappen、Normal…)改為中文(
通知、未開始、中…);兩份語言 JSON(Common/Lang/Xaml/Shared.json、TsERP/Lang/Xaml1/Xaml.json)對應區段同步 re-key,各語言譯文不變(英文介面仍顯示英文)。JobCodeEnum/StatusCodeEnum/PriorityCodeEnumsetter 修正:正確寫回對應的
「碼」欄位與系統值欄位;getter 加依碼回查 fallback,既有資料載入時下拉正確顯示
(原
StatusCodeEnumsetter 誤用_PriorityCodeEnum有 NRE 風險,已修)。RecordWorkflowRegionViewModel的#I#取代改用共用幫助方法後,會跟 Commpr 版一樣
連 email 一起帶入登入者(原本漏帶)。
刪除
- 無。
Breaking Changes
- DB 存值變動:之後新存的
處理事項/狀態/優先順序文字欄位為中文;
既有舊資料仍為英文字串。畫面顯示一律走「碼」欄位回查列舉,不受影響;
已全 repo 檢查無任何程式碼以英文字串比對這三個文字欄位。
Migration Notes
- 若有外部報表/查詢直接依
處理事項等文字欄位過濾英文字串,需改為依「碼」欄位
(
處理事項碼/狀態碼/優先順序碼)或同時相容中英文值。 - Wkflowt 處理事項下拉連動(
-
06-06 receive-compare-fixes ▸
2026-06-06 應收帳款主檔(receive)VFP 對比批次修正
摘要
對 SCX_ARP library 的
receive(應收帳款主檔)完成 VFP↔新版逐項對比。按鈕接線(銷貨轉入 Recepdt、暫估轉AR Recepdt2、轉傳票 ArToGl、修改客戶 TempAllow 流程)與 XAML 欄位本就比 paymnt 完整;問題集中在ReceiveSave的驗證缺漏與「金額回填邏輯整段躺在死方法Old()」。paymnt 批次的共用 Source 修正(廠商帶入、明細重算通知、代工單價Binding)自動惠及 receive。變更
批次 1 — 存檔/編輯驗證與金額回填(LogicBll)
- 稅別必填驗證恢復(
ReceiveSave.AllowSave):新增/複製/修改時必填,財務類別 25暫收/23待抵/26折扣/21退貨 除外;特殊修改可免(對應 VFP 2016/11/07)。
- 匯率必須大於 0 才能存檔。
- 立帳日期必填(原僅驗交易日期)。
- 訊息翻譯 key 由誤植的
PAYMNT改為RECEIVE(交易日期/帳款期別/客廠部代號/幣別/倉庫/原幣未稅 等多處 copy-paste)。
- 財務類別金額回填從死方法
Old()移入正式存檔路徑,並對齊 VFP:
- 15 稅金:應收付(原幣/本幣)= 稅額。
- 19 原幣調整 / 26 折扣:原幣應收付 = 發票金額+稅額;本幣 = ×匯率。
- 22 折讓:應收付 = 發票金額+稅額 改為無條件回填(原版只在無明細時)。
- 死方法
Old()刪除。- 自動算稅範圍收斂回 VFP:僅 11訂金/12出貨/21退貨/31非應收發票/14雜項 且
轉入備註為空 才跑TaxCalculator(對應 VFP 2012/09/12「轉入不得重新計算」)。原版對所有財務類別<>25(含轉入單、15/19/26/23/24)每次存檔都重算,會把轉入單與特殊類別的金額蓋掉。
- 財務類別<>25 時補
程式類別='R'(對應 VFP;原只靠選單帶入,直接開程式新增可能存成空白),並補外幣時本幣應收付=原幣×匯率尾差同步。
- 「舊資料」判斷由完全相等改為包含(
ReceiveEdit),對應 VFP'舊資料'$轉入備註。
批次 2 — 連動與顯示(Model/ViewModel)
- 交易日期輸入後自動帶帳款期別(
Rp_mForARAPBindingSource.交易日期Binding,對應 VFP交易日期.Valid:帳款期別=LEFT(交易日期,7))。共用 Source,paymnt 端交易日期側同步生效(立帳日期側前一批已做)。
- 瀏覽時倉庫欄顯示(
ReceiveViewModel.AfterMoverRecord,對應 VFP倉庫.Refresh:倉庫=LEFT(單號,6))。
行為變更提醒
- 自動算稅收斂後:23待抵/24預收/15/19/26/轉入單存檔不再被 TaxCalculator 重算(與 VFP 一致)。若有流程依賴了原本的「全類別重算」行為需注意。
- 存檔驗證變嚴:稅別空白(指定類別外)、匯率≤0、立帳日期空白 會被擋下。
尚未處理(已對比出、待業務確認)
- 批改客戶(
_CHANGENO_1)、轉入折讓(RECEPDT_DISC)、發票統計(RP_S 'AR')三顆按鈕未接(EF6/EF7 死方法、未宣告 IOther6/7)
- 修改客戶(EF5):用廢棄
WindowHelper.OpenWindow;VFP 改完暫收客戶自動建收款單+沖帳的自動化未移植
- 發票金額輸入不自動算稅額(×稅率);複製限制(VFP 僅 22 折讓可複製)未做
- 傳票號碼未顯示/無連結、相關單號未顯示、查詢收款單頁籤(lcl_rsheet)未移植
- RECEPDT / RECEPDT_2 / RECEPDT_DISC 為獨立 .scx,遞迴對比需另取得 VFP 原始碼
Migration Notes
無需資料遷移。
LogicBlldotnet build 通過、ViewModelVS MSBuild 通過(0 errors)。 - 稅別必填驗證恢復(
-
06-06 paymnt-compare-fixes ▸
2026-06-06 應付帳款主檔(paymnt)VFP 對比批次修正
摘要
對 SCX_ARP library 的
paymnt(應付帳款主檔)完成 VFP↔新版逐項對比(欄位 / allowsave / allowedit / addagain / 事件 / 按鈕),並修掉第一、二批問題。按鈕接線(進貨轉入 Paypdt、暫估轉AP Paypdt2、轉傳票 ApToGl、特殊修改)本就完整,問題集中在存檔驗證缺漏、特定財務類別金額計算、與明細重算連動。變更
批次 1 — 存檔/編輯驗證(LogicBll)
- 匯率必須大於 0 才能存檔(
PaymntSave.AllowSave)
- 對應 VFP「請輸入正確的匯率」。原程式呼叫
U_Blrate但回傳值丟棄(且參數為 Prepaid 殘留),等於沒做;已移除該死碼,改為存檔前驗證並阻擋。- 稅別必填驗證恢復(
PaymntSave.AllowSave)
- 財務類別非 5B(退貨應付)/66(DM折讓)/67(損害賠償)時稅別必填,原驗證整段被註解。
- 立帳日期必填驗證補上(
PaymntSave.AllowSave),原僅驗交易日期。
- 財務類別 55(進貨費用/成本分攤)不得修改或刪除(
PaymntEdit.AllowEditHandle)
- 對應 VFP「進貨費用,不得修改或刪除,請刪除 51進貨單」。原版 55 單可被直接刪除,造成與來源進貨單脫鉤。新增訊息
PurchaseFeeCannotEditOrDeletePleaseDeletePurchaseDocument(Message.json已補中英文)。- 「舊資料」判斷由完全相等改為包含(
PaymntEdit),對應 VFP'舊資料'$轉入備註。
- 財務類別 59:應收付金額 = 發票金額 + 稅額(
PaymntSave.HandleDataBeforeEndEdit)
- 並將 59 排除在自動算稅之外(對應 VFP 2021/11/08 新增段)。
- 財務類別 5B/66/67:應收付金額自動帶出(
PaymntSave.HandleDataBeforeEndEdit)
- 本幣應收付 = 發票金額 + 稅額;原幣應收付 = 本幣 / 匯率(依幣別小數位數四捨五入)。對應 VFP
稅額.Valid;原版這三類單的應收付恆為 0。- 本幣應收付 = 原幣應收付 × 匯率 尾差校正(
SetDueAmount(),對應 VFP allowsave 開頭的 REPLACE)。
批次 2 — 明細重算與預設值(Model/ViewModel/XAML)
- 代工單價參與重算:明細 grid 代工單價欄改綁新的
代工單價Binding,輸入後即重算原幣未稅(公式數量×(單價+代工單價)+其他金額)。原綁定純屬性,改代工單價不會重算。
- 數量 / 其他金額輸入後 grid 即時刷新:
數量Binding/其他金額Bindingsetter 補 raise原幣未稅Binding(原本只有單價Binding有),修正改數量後原幣未稅欄不即時更新。
- 新增單據預設 進銷分類 = 內採(P1)(
PaymntViewModel.AfterAddNew),對應 VFP addagain進銷分類='1.內採'。
- 立帳日期輸入後自動帶帳款期別:主檔立帳日期改綁新的
立帳日期Binding,離焦後帳款期別 = 立帳日期前 7 碼(yyyy/MM),對應 VFP立帳日期.LostFocus。
批次 3 — 輸入廠商帶入廠商資料(業務裁定後實作)
- 新增單據預設維持 本位幣+匯率 1(現行行為,業務確認)。
- 輸入收付客廠號時帶入廠商主檔資料(
Twork_arp_vw_rp_mSource.SetTransactionCustVendDept,對應 VFP收付客廠號.代號.LostFocus):
- 新增帶入:幣別(廠商幣別非空才覆蓋,空則維持本位幣)、帳款起始日、關係人。
- 幣別變更後匯率由
TsCurrency控件自動查匯回填(同手動改幣別的行為)。- 帳款起始日改在 收付條件號 之前設定,到期日/付款日計算(
SetDueDate)使用新起始日。- 此 Source 與應收(receive)共用,應收端同步生效。
- 輸入廠商資料(客廠部代號)時,若付款廠商空白則同步補入(
Rp_mForARAPBindingSource.客廠部代號Binding,對應 VFPsqlnm_sp1.代號.LostFocus):補入後走同一條帶入鏈(幣別/帳款起始日/關係人/收付條件…)。
- 修正既有 binding 通知 bug:
收付客廠號Bindingsetter 原為OnPropertyChanged(客廠部代號Binding)——把屬性「值」當屬性名 raise,導致輸入付款廠商後 廠商資料 欄不會即時刷新;更正為nameof(客廠部代號Binding)。
尚未處理(已對比出、待業務確認)
- 發票統計按鈕(
IOther5宣告但空實作;VFPDO FORM RP_S WITH 'AP',新版無 RP_S 對應)
- else6 更新資料(
_CHANGENO更新進出貨發票)無對應
- 特殊修改稅額尾差攤提整段註解、且金額欄位特殊修改下恐不可編輯
- 「查詢付款單」頁籤(lcl_psheet)未移植;傳票號碼未顯示、無 DblClick 連結
- 主檔 相關單號/訂單編號/回轉日期/暫估/折讓 欄位未顯示;明細 科目代號 等欄在 XAML 註解區
- PAYPDT / PAYPDT_2 子表單內部邏輯待取得 VFP 原始碼後遞迴對比
Breaking Changes
無。皆為回復 VFP 行為的修正;存檔驗證變嚴(匯率≤0、稅別空白、55 刪改會被擋下)。
Migration Notes
無需資料遷移。
LogicBll以dotnet build通過、ViewModel/TsERP以 VS MSBuild 建置通過(0 errors)。 - 匯率必須大於 0 才能存檔(
-
06-06 otherrp-grpmaccl-prepaid-compare-fixes ▸
2026-06-06 代收付/費用科目群組/預付(otherrp・grpmaccl・prepaid)VFP 對比批次修正
摘要
SCX_ARP 三支主檔類對比+第一批修正。最重大發現:預付(PREPAID)的存檔驗證與沖帳防呆整組是孤兒——BLL 類別命名
TemporarySave/TemporaryEdit與工廠反射約定(ProgramClass=PREPAID →PrepaidSave/PrepaidEdit)不符,永遠 fallback 到無驗證的 base,已改名接上。變更
prepaid(預付/暫付申請,View=Temporary.xaml)
TemporarySave→PrepaidSave、TemporaryEdit→PrepaidEdit(改名接線) 🔴
- 接上後生效:財務類別/申請日期/帳款期別/事由/受款人/幣別/原幣金額>0/付款方式/收付款日/到期日 共 10 條存檔驗證 + 已沖帳不得修改防呆 + 備註=事由、收付客廠號、立帳日期=申請日期 等存檔補值。
- 補 客廠部代號(廠商)必填(對應 VFP)。
- 修 匯率≤0 自動補匯率:原
U_Blrate回傳值丟棄(等於沒補),改為填入匯率並重算本幣應收付。
otherrp(代收付)
- 本幣應收付存檔時計算(
SetDueAmount(),對應 VFP 原幣應收付/匯率.LostFocus)——原版完全沒人算,本幣恆 0/stale。
- 修 匯率≤0 自動補匯率(同上
U_Blrate丟棄回傳值病灶)。
- 補 申請日期必填(對應 VFP『申請日期未輸入』)。
OtherrpViewModel實作IAdd:新增預設 申請日期=今天、帳款期別=當月、幣別=本位幣、進銷分類=內銷(DomesticOrder R1,對應 VFP addagain'1.內採')。
grpmaccl(費用科目群組)
- 補 群組科目別(主鍵)必填/
+++檢查(VFP 第一條驗證)。
- 補 借貸別必填(D/C 值域已由 ComboBox 限制)。
- 明細刪列條件補上 群組代號空白→D(對應 VFP
REPLACE ALL 增刪修 WITH 'D' FOR EMPTY(群組代號));保留原有「科目代號空白→D」為新版額外防呆。
已確認非缺漏
- otherrp/prepaid 的「工作流程」「快速審核」按鈕 → 新版集中式 workflow(架構決策)。
- 借貸別 D/C
Valid→ ComboBox 值域取代。
尚未處理(待業務確認)
- otherrp:客廠部代號輸入不帶 幣別/收付條件/帳款起始日/關係人/受款人;收付條件不算付款日/到期日;申請部門→使用部門、申請人→使用人、申請日期→使用日期 空白補值連動(VM 用裸 Source、XAML 綁 plain 屬性,要做需換 BindingSource 衍生類+改 XAML)
- prepaid:匯率手改不重算本幣(匯率 plain 綁定);收付條件 lookup 欄位未移植;使用日期/使用部門/使用人 欄位未移植;
PrepaidEdit用沖帳原幣 vs VFP 沖帳本幣(外幣尾差邊角)
Migration Notes
無需資料遷移。注意:預付單接上驗證後,過去存得進去的不完整單(無廠商、無事由、無受款人…)將開始被擋下,屬預期行為。
LogicBlldotnet build、ViewModelVS MSBuild 皆 0 errors。 -
06-05 ai-log-sys-dispatcher ▸
2026-06-05 AI 查詢與 catalog 全面改走 Log_Sys dispatcher + AI 專用資料庫帳號
摘要
AI 智慧助理的所有 DB 存取(查詢 + catalog 載入)從「直連 proc/資料表」改為比照 ERP 標準
Log_Sys 模式:client 只連 log 資料庫,經
DARB_LOG_SYS_AI_EXECdispatcher(寫
log_sys_ai稽核表、依proc_param以位置參數轉發)執行 csa 庫的目標 proc。同時支援 AI 專用最小權限帳號(
_prgpar的AI_DB_CONN),不再固定使用 ERP 主連線。變更
- 新增共用
LogSysAiDispatcher(TsErp.Ai.Tools/Data):比照SetLogSysExecCommand的參數組法
呼叫
DARB_LOG_SYS_AI_EXEC;@result非 OK 或為空(proc_param未登錄)時丟明確錯誤。AiQueryExecutor:經 dispatcher 轉發TWORK_AI_QUERY(@param1~4=使用者/SQL/描述/筆數上限)。
CatalogSqlReader:catalog 也經 dispatcher——TWORK_AI_GET_USER_SCHEMA(view 清單)與
新 proc
TWORK_AI_GET_VIEW_COLUMNS(view 欄位+型別,describe_view lazy 用),不再直連 csa 庫。TWORK_AI_QUERY(SqlBI 腳本):移除@LP_DATAEVENT參數——dispatcher 是位置參數轉發
(
EXEC target @param1, @param2…),第一個位置就是@param1,保留LP_DATAEVENT會錯位吃到 UserId。另補
@LP_P5~P12預留參數。- 新增
SqlBI/TWORK_AI_GET_VIEW_COLUMNS.sql(csa 庫,查 INFORMATION_SCHEMA 欄位/型別)。
- 新增
SqlBI/TWORK_AI_SYNC_PERMISSION.sql(csa 庫):同步 AI 帳號(預設 foxaiexec)的 view SELECT,
先清空既有再依
_ai_schema重建(idempotent,白名單移除的 view 會被收回)。由
TWORK_AI_GET_SCHEMA末尾自動呼叫,亦可單獨EXEC TWORK_AI_SYNC_PERMISSION '帳號名'。ChatAgentViewModel:AI 連線改讀_prgpar的AI_DB_CONN(AI 專用帳號、指向 log 庫);
未設定時退回 ERP 主連線(舊行為,過渡用)。
Migration Notes(DB 部署清單)
log 庫(darbXXXlogN):
1.
DARB_LOG_SYS_AI_EXECproc(複製DARB_LOG_SYS_EXEC,改寫log_sys_ai)— 已由 DBA 建立2.
log_sys_ai表(複製log_sys結構,pkid需保留 IDENTITY)3.
proc_param登錄三筆轉發規則:```sql
INSERT INTO dbo.proc_param (datafunc, databaseid, param_qty, paramoutput) VALUES
('TWORK_AI_QUERY', 'C', 4, 'N'),
('TWORK_AI_GET_USER_SCHEMA', 'C', 1, 'N'),
('TWORK_AI_GET_VIEW_COLUMNS', 'C', 1, 'N');
```
4. AI 帳號
foxaiexec:同時是連線帳號與 dispatcher 的執行身分。dispatcher 的
WITH EXECUTE AS 'foxrunprg'改成WITH EXECUTE AS 'foxaiexec'(DBA 重部署)。ALTER DATABASE [<log庫>] SET TRUSTWORTHY ON(跨庫 token)。建帳號與授權見
SqlBI/AI_ACCOUNT_SETUP.sql(log 庫:EXECUTE dispatcher + 稽核表權限)。csa 庫(darbXXXcsaN):
1. 部署更新後的
SqlBI/TWORK_AI_QUERY.sql(無LP_DATAEVENT版)、SqlBI/TWORK_AI_GET_SCHEMA.sql、新的
SqlBI/TWORK_AI_GET_VIEW_COLUMNS.sql、SqlBI/TWORK_AI_SYNC_PERMISSION.sql2.
foxaiexecuser +GRANT EXECUTE三支 AI proc(見AI_ACCOUNT_SETUP.sql)3.
EXEC TWORK_AI_GET_SCHEMA(填_ai_schema白名單;末尾自動呼叫TWORK_AI_SYNC_PERMISSION同步 foxaiexec 的 view SELECT)
第二道防線:foxaiexec 在 csa 庫只有白名單 view 的 SELECT(由
TWORK_AI_SYNC_PERMISSION先清空再重建)。
TWORK_AI_QUERY內的動態sp_executesql以 foxaiexec 權限執行——AI 的 SQL即使騙過字串掃描白名單,非白名單 view 仍因無 SELECT 權限被 DB 擋下。
系統參數(
_prgpar):AI_DB_CONN=Data Source=<server>;Initial Catalog=<log庫>;User ID=foxaiexec;Password=<密碼>;TrustServerCertificate=True
Breaking Changes
- 舊版(直呼
TWORK_AI_QUERY/直查_ai_schema)的 client 與新部署不相容,程式與 SqlBI 腳本需一起部署。
proc_param三筆未登錄時,dispatcher 會回空@result,C# 端丟出含修復指引的錯誤。
- 新增共用
-
06-04 sliy-excel-import-bulk-perf ▸
2026-06-04 總帳傳票 Excel 匯入:大批效能、驗證與崩潰修正
摘要
總帳傳票(SLIY)的「Excel 匯入」在匯入大量分錄時又慢又會崩潰、且不合法資料照匯。本次將大批匯入降到秒級、修正崩潰,並在匯入前整批驗證、不合法即中止。
變更
- 匯入大幅加速:6,000+筆從數十秒/分鐘級降到秒級。原本每多 500 列耗時不降反升(O(N²)),現已消除。
- 不合法資料不再被匯入:匯入前先驗證所有列的科目代號(須存在且「可輸入傳票」)。只要有任一列不合法,整批中止,並以單一視窗列出所有問題列(標示 Excel 實際列號與原因),不再逐列跳出大量訊息框。
- 讀檔失敗有明確提示:Excel 檔損毀/被開啟/格式不符時,顯示明確訊息而非讓程式崩潰。
修正
- 修正大批匯入時偶發的程式崩潰(
ExecutionEngineException)。
刪除
- 無(移除的是開發期間的暫時性效能量測碼,對使用者無影響)。
Breaking Changes
- 無。匯入後的金額、匯率、借貸合計與修正前一致。
Migration Notes
- 無需資料或設定遷移,更新版本後即生效。
詳見 ADR 0028。
-
06-04 scx-arp-query-fixes ▸
2026-06-04 應收應付查詢類(SCX_ARP)VFP 對比批次修正
摘要
對 SCX_ARP library 的 5 支查詢/報表類(
pay_qry0/pay_qry1/rec_qry0/rec_qry1/rp_balance)完成 VFP↔新版逐項對比,並修掉第一批「純 bug、不涉業務判斷」的問題。SP 接線與報表頁結構本就移植完整,問題集中在 copy-paste 殘留與日期基準語意。變更
- 應收帳齡 / 應付帳齡:帳齡分界基準日
- 「截止日期」查詢模式下,帳齡桶與會計師帳齡的分界改以使用者輸入的截止日為基準(對應 VFP
L_DATE=CTOD(截止日期)),不再一律用今天。「現有餘額」模式維持以今天為基準。- 影響:
ApAgeHelper/ApAgeBll、ArAgeHelper/ArAgeBll(新增BaseDate,傳入兩個 helper 並用於會計師帳齡)。- 應收帳款查詢(Rec_qry0)年度統計表
- 兩個年度統計 grid 的
ProgramClass由誤植的Pay_qry0改為Rec_qry0(修正欄位設定/權限抓錯模組)。- 欄頭由「廠商代號 / 廠商名稱」改為「客戶代號 / 客戶名稱」。
- Excel 匯出頁籤名由「應付帳款…」改為「應收帳款…」(彙總/明細/年度共 5 個頁籤)。
- 應收 / 應付帳款查詢明細表:統一編號欄
-
Rec_qry0與Pay_qry0明細的taxIDColumn原綁定稅別(與前一欄重複、統一編號永遠看不到),更正為綁定並顯示統一編號。- 應收應付餘額表(Rp_balance)本期沖帳區間
- 本期沖帳日期條件由半開區間
< 截止日改為閉區間<= 截止日(對應 VFP),截止日當天的沖帳不再被漏算。- 查詢條件預設值:截止廠商 / 截止客戶
- 上界預設由
zzzz(4 碼)改回zzzzzz(6 碼),避免代號 >4 碼且以 z 開頭時漏抓尾端資料。涉及ApageParameters/ArageParameters/Pay_qry0Parameters/Rec_qry0Parameters。批次 2(2026-06-04 同日)
- 應付帳齡 / 應收帳齡:結帳年月預設改為上月
-
ApageParameters/ArageParameters的 結帳年度/結帳月份 預設由「當月」改為AddMonths(-1)(上月),對應 VFPDATE()-30並與Pay_qry0/Rec_qry0一致。修正月初查詢時前期/本期分欄歸屬。- 應收帳齡:截止日期模式結帳年月
/0bug
- 移除
ArAgeBll在截止日期模式下用EndingDate.Substring(4,2)覆寫結帳月份的程式碼:截止日格式為yyyy/MM/dd,該寫法取到"/0"而非月份,導致前期/本期分界全錯。改為一律採用使用者輸入的結帳年度/月份(對應 VFP,且與應付帳齡ApAgeBll一致)。- 應收帳齡:移除「報表別」誤解的死碼
-
ArAgeBll內以財務類別 24/29 過濾的註解碼為對 VFP「報表別」的誤解,已移除並加正解說明。VFP「報表別(一般/會計師簡表)」實為 應收明細 頁的 Excel 匯出選項(會計師簡表=精簡欄位、僅未收原幣<>0),非資料過濾。Breaking Changes
無。皆為回復 VFP 行為的修正。
Migration Notes
無需資料遷移。
LogicBll已dotnet build通過(0 errors);XAML / ViewModel 變動(binding/header/匯出標題)需於 Visual Studio 重新建置確認。批次 3 — 逐欄 binding 掃描(2026-06-04 同日)
對 5 支查詢 XAML 做逐欄
DataMemberBinding↔ Poco 屬性 cross-check,又揪出 3 個「binding path 打錯、不會 build error 但欄位永遠空白」的 bug:Pay_qry0.xaml:262出納分錄「收付款日」欄綁收付款日,但Group4Poco屬性是收付款日期→ 改綁收付款日期。
Arage.xaml:546應收明細「公司」欄綁公司名稱,但ArDetailPoco屬性是公司簡稱→ 改綁公司簡稱(Header 一併改為公司簡稱)。
Arage.xaml:602應收明細「收款日期」欄綁收款日期,但ArDetailPoco屬性是收款日→ 改綁收款日。
其餘 4 支(Rec_qry0 / Apage / Rp_balance 全綁定正確;Pay_qry0 僅此一處)。掃描共驗約 500+ 欄。
Rec_qry0另有 2 處 Header 與欄位名語意不同(明細「財務分類」綁單據名稱、產品「財務名稱」綁單據分類)— 資料正常顯示,疑似刻意改標題,未動,待業務確認。批次 4 — 會計師簡表匯出(2026-06-04 同日)
- 應收帳齡 / 應付帳齡:Excel 多加「會計師簡表」頁籤(對應 VFP
rec_qry1/pay_qry1報表別=會計師簡表)。
- 精簡欄位:
立帳日期, 傳票號碼, 帳款單號(=財務單號), 客戶/廠商代號, 客戶/廠商簡稱, 幣別, 原幣餘額(=未收/未付原幣), 本幣餘額(=未收/未付本幣), 到期日。- 過濾與排序比照 VFP:僅
未收/未付原幣<>0,依 客戶/廠商代號 + 立帳日期 排序。- 實作:新增
AccountantArSimplePoco/AccountantApSimplePoco兩個精簡 DTO;Rec_qry1ViewModel.GenerateExcel/Pay_qry1ViewModel.GenerateExcel各加一個會計師簡表頁籤。決策:採「多加一個頁籤」而非新增 UI 切換或取代明細頁籤。- 順手修
Pay_qry1ViewModel.GenerateExcel的複製貼上錯誤(AP 模組沿用了 AR 字樣):頁籤名「未收帳款彙總表/明細表」→「未付帳款彙總表/明細表」;匯出檔名"Arage"→"Apage"。
待確認(仍未實作,需業務拍板)
- 會計師 24 個月帳齡表(表A)、Rp_balance 蘇州
RP_BALANCECN版屬公司特定客製,預設不做。
-
06-04 psheet-closingbook-param ▸
2026-06-04 付款單(Psheet)存檔關帳日參數修正
摘要
VFP→TsERP 對比
psheet(付款單主檔)時發現存檔(allowsave)的關帳日檢查用錯系統參數,已修正。變更
PsheetSave.AllowSave的關帳日期檢查由U_Prgpar("2033")(收款單關帳日期,疑似複製自RsheetSave)改為new Util2017(Context).U_PrgparSql("2001")(會計參數表禁修日期)。
- 對應 VFP
psheetallowsave 的U_PRGPARSQL(2001),並與同模組PsheetEdit.AllowEditHandle(本來就用 2001)一致。- 修正前:付款單存檔與修改/刪除走「不同關帳閘門」(save 用 2033、edit 用 2001),可能在禁修日後仍能存檔、或被收款單關帳日誤擋。
Breaking Changes
無。回復 VFP 行為。
Migration Notes
LogicBll已dotnet build通過(0 errors)。待處理(同次對比發現、未在本次修)
psheet/rsheet 尚有數項偏離 VFP(addagain 未清沖帳備註、rsheet 公司代碼 Save 未補預設、rsheet 沖帳方式無輸入欄、批次電匯仍用舊 WindowHelper、FsheetEdit 缺關帳日檢查)與需業務確認項(rsheet 轉票據 else7 受參數 2035 控制、工作流程 else5、付款匯率日整套)。詳見 memory
scx-arp-query-compare-progress(含主檔段)。 -
06-03 sliy-forbidden-voucher-early-prompt ▸
總帳傳票(sliy)「禁止輸入傳票」改為科目格子當下攔截、焦點留在格內
摘要
總帳傳票(
Sliy,程式代號 SLIY,另含 Budget、Sliyyear)輸入會計科目時,若該科目「輸入傳票」非 Y(統制/標題科目),原本只在整列提交(RowValidating)時才擋;現改為在離開科目代號格子前(CellValidating)就攔截,提示「本科目禁止輸入傳票」並把焦點留在科目格子內,游標不會跳到下一格,逼使用者當下改正。變更
InjectAcclValidationRuleBehavior:除原本的RowValidating外,新增訂閱CellValidating。只針對「科目代號」欄(依DataMemberBinding路徑判斷),輸入禁止入帳的科目時設e.IsValid = false(取消提交、焦點留格內)+e.ErrorMessage,並顯示訊息。
AcclValidation.CanInputVoucher(glAccountCode, out msg):新增的輕量檢查方法,只驗「輸入傳票」必須為 Y;查無科目時不在此擋(交給 RowValidating 完整檢查)。
- 「禁止輸入傳票」的攔截集中在 CellValidating,不放在
OnDetailGLCodeChanged(該處於格子提交後才執行、留不住焦點);常用摘要自動帶入仍維持在OnDetailGLCodeChanged。
新增 / 刪除 / Breaking Changes
無資料欄位異動;無 Breaking Changes。
Migration Notes
- 整列提交時的
RowValidating完整驗證(科目存在性、控制方式 1~9、客廠別等)維持不變,仍為存檔前最後防線。
- 其他需整列欄位齊全才能判斷的控制驗證(索引/部門/客廠等)仍留在 RowValidating 階段,未改於離開單一格子時觸發。
- 程式化批次填入(如 Excel 匯入)不經過 UI 編輯、不觸發 CellValidating,禁止科目仍由 RowValidating/存檔驗證攔下。
-
06-03 accl-default-memo ▸
會計科目(accl)新增「常用摘要」欄位
摘要
會計科目主檔(
Accl,程式代號 ACCL)新增「常用摘要」輸入欄位。資料模型、DB view 與總帳傳票(sliy)帶入邏輯原本就支援此欄位,僅缺主檔的輸入介面,本次補上。新增
Accl.xaml:在「英文名稱」與「大分類」之間(原 Row 3 空列)新增「常用摘要」標籤 + 文字輸入框,綁定常用摘要屬性(Twork_acc_vw_acclSource,長度 80)。
- 多語系字串
常用摘要(DefaultMemo):加入Common/Lang/Xaml/Accl.json與TsERP/Lang/Xaml1/Xaml.json。
變更
無。
刪除
無。
Breaking Changes
無。
Migration Notes
- 無需資料庫異動:
常用摘要欄位於Twork_acc_vw_acclview 既已存在。
- 行為延續:在會計科目設定「常用摘要」後,於總帳傳票(sliy)輸入該科目且該列摘要為空時,會自動帶入此摘要(既有邏輯,見
SliyViewModel.OnDetailGLCodeChanged)。
-
06-02 sliy-save-checks-and-excel-import ▸
2026-06-02 總帳傳票(Sliy):存檔檢查補強 + Excel 匯入分錄
摘要
依 VFP 舊版 sliy 補齊三項:原幣借貸不平衡會跳提示、存檔時擋無效/空白傳票日期、新增「Excel 匯入」分錄按鈕。
新增
- 傳票編輯區新增「Excel 匯入」按鈕:可從 Excel 匯入分錄(第 1 列為標題,第 2 列起 A 欄=科目代號、C 欄=原借方金額、D 欄=原貸方金額),匯入時自動帶本位幣、匯率 1 並換算本幣金額。對應舊版 excel轉入鈕。
變更
- 存檔時若原幣借貸不平衡,會跳提示(僅提示、不阻擋存檔;本幣借貸不平衡仍阻擋)。先前此提示不會出現。
- 存檔時若傳票日期空白或非有效日期,會阻擋並提示(對應舊版檢查)。
- 科目代號驗證新增「本科目禁止輸入傳票」檢查:科目的「輸入傳票」非 Y(統制/標題科目)時,該分錄列驗證不通過、無法存檔(對應舊版 sql_acclno1.Valid,先前漏移植)。新增訊息
ThisGLAccountCannotInputVoucher。
- 科目控制方式驗證(分類索引/部門/客廠/項目/員工/專案/產品群組必填)改為「新增(A)與修改(E)的列」都驗證;先前只驗新增列,編輯既有列不重驗。
- 輸入科目代號時的自動補平金額改為「本幣設精確、原幣=本幣÷匯率」(對應舊版);先前以原幣四捨五入回算本幣,外幣情況可能造成本幣借貸差 1 而擋存。
- 輸入科目代號時,若科目有設「常用摘要」且該列摘要為空,自動帶入常用摘要(對應舊版,先前未做)。
- 明細的「金額」改為隨數量/單價/折扣自動計算:金額 = 四捨五入(數量 × 單價 × 折扣, 幣別小數位);新增明細的折扣預設為 1(對應舊版,先前完全沒做此計算、折扣預設 0 會算出 0)。
Breaking Changes
無。
Migration Notes
無需操作;更新版本後即生效。Excel 匯入的欄位格式:A=科目代號、C=原借方金額、D=原貸方金額,資料自第 2 列開始。
-
06-02 radgridview-horizontal-scroll-fix ▸
2026-06-02 修正 RadGridView 水平捲軸間歇拖不動
摘要
修正資料表(RadGridView)水平捲軸「有時拖得動、有時拖不動」的問題,常見於傳票 Sliy 等欄位很多的明細頁。修正後水平捲軸可穩定拖曳、可捲到最右側欄位。
變更
- 全系統資料表關閉「欄虛擬化」(
EnableColumnVirtualization=False),改在共用樣式統一設定。原因是寬表的 off-screen 欄未被量測會讓水平捲動範圍算錯,導致捲軸拖不動。詳見 ADR 0026。
Breaking Changes
無。
Migration Notes
無需操作;更新版本後即生效。
- 全系統資料表關閉「欄虛擬化」(
-
06-02 ftrlima4-fsheetimport-edge-fixes ▸
2026-06-02 零用金支出/財傳單快速輸入:邊角補齊
摘要
依 VFP 舊版補齊零用金支出(Ftrlima_4)與財傳單快速輸入(FsheetImport)幾項細節。
新增
- 零用金支出:新增「全選 / 全部不選」按鈕,一鍵全勾/全不勾並即時更新金額彙總(對應舊版全選鈕/不選鈕)。
變更
- 財傳單快速輸入:載入既有分錄時,略過沒有科目代號或已標記刪除的列(對應舊版只載入有效分錄)。
- 財傳單快速輸入:新增空白列時,摘要自動帶入上一列摘要,省去重複輸入(對應舊版摘要自動帶值)。
- 財傳單快速輸入:查詢匯率時,外幣有帳戶的列改為「貸方(付款)用銀行日報表帳戶匯率、借方(收款)用掛牌買價」,與舊版一致(先前一律用銀行帳戶匯率)。
已知未調整
- 財傳單快速輸入查詢匯率的「掛牌買價取前一營業日(T-1)」日期慣例尚未調整,待確認新版匯率 SP 與「付款匯率日」是否已內含 T-1,避免重複位移。
Breaking Changes
無。
Migration Notes
無需操作;更新版本後即生效。
-
06-02 ftrlima4-amount-summary ▸
2026-06-02 零用金支出:補本幣/原幣金額彙總顯示
摘要
「零用金支出」(Ftrlima_4) 視窗補上舊版有、新版漏掉的「原幣金額彙總/本幣金額彙總」即時顯示。勾選/取消勾選主檔列時,下方會即時顯示目前已勾選單據其明細的原幣含稅、本幣含稅合計。
新增
- 視窗底部左側顯示「原幣金額彙總」「本幣金額彙總」兩個唯讀金額欄。
- 數值 = 所有已勾選主檔列其明細的
原幣含稅/本幣含稅加總,隨勾選即時更新。
Breaking Changes
無。
Migration Notes
無需操作;更新版本後即生效。
-
06-02 fsheetimport-copy-group-and-currency-balance ▸
2026-06-02 財傳單快速輸入:複製分組修正 + 原幣不平衡提示
摘要
「財傳單快速輸入」(FsheetImport) 的「複製」會把複製出來的分錄列沿用原本的組數,導致之後「查詢匯率」計算各組匯兌損益時把原組與複製組混在一起算錯。已修正為複製時掛新組數。另補上原幣借貸不平衡的提示(對應舊版行為)。
變更
- 複製:複製出來的分錄列改掛新的組數(
Detail.Max(組數)+1),成為獨立分組,匯兌損益依組正確計算。
- 確認/存回時:原幣借貸不平衡會跳提示(僅提示、不阻擋存檔);本幣借貸不平衡維持原本的阻擋。
影響
- 複製分錄後再查詢匯率,匯兌損益分組計算正確。
- 原幣借貸不一致時會多一個提示視窗(不影響可否存檔)。
Breaking Changes
無。
Migration Notes
無需操作;更新版本後即生效。
- 複製:複製出來的分錄列改掛新的組數(
-
06-02 fsheet1-bill-wire-fx-recompute ▸
2026-06-02 批次改財傳單日期:補票據/電匯外幣匯率重算
摘要
「批次改財傳單日期」(fsheet_1) 在變更付款日期時,原本只重算沖帳分錄的匯率,票據與電匯的外幣匯率沒有跟著新日期更新(電匯本幣金額也未重算)。對照 VFP 舊版
修正匯率補齊,使三類資料一致。變更
Fsheet_1Bll.ChangeRate()新增票據(Detail1)、電匯(Detail2) 兩段重算:幣別=本位幣→匯率 1;金額>0 取匯率表(使用匯率),否則取帳戶日報表匯率。電匯另以CalculateAmount()重算本幣金額(=金額×匯率,依幣別小數位)。
影響
- 含外幣票據/電匯的財傳單,批次改日期後其匯率與電匯本幣金額會更新為新付款日期對應的匯率(先前維持查詢當下的舊值)。本位幣資料不受影響。
Breaking Changes
無。
Migration Notes
無需操作;更新版本後即生效。
-
06-02 ai-agent-mcp ▸
2026-06-02 — 全新 MCP-first 內嵌 AI 智慧助理
摘要
主視窗 AI 按鈕改開啟全新的「AI 智慧助理」對話視窗:使用者用自然語言查詢 ERP 唯讀資料、或要求分析出圖(Vega-Lite,WebView2 渲染)。底層採 MCP-first 架構,工具由本機 stdio MCP server 暴露,同一支 server 也能掛進 Claude Desktop / Claude Code。資料存取走 DB 既有的
TWORK_AI_QUERY閘道(LLM 寫 SELECT → proc 驗證/白名單/限筆/稽核後執行)。同時清理數支舊 AI 試作(含一支外洩 OpenAI key 的檔案)。新增
- 新專案:
-
TsErp.Ai.Core:ClaudeClient(串流 + 工具迴圈 + prompt caching)、IAiTool/ErpToolContext、McpClientHost、VegaSpecBuilder、McpServerLocator、JsonDefaults(中文不 escape)。-
TsErp.Ai.Tools:4 支工具list_views/describe_view/run_sql/run_analysis;AiQueryExecutor(呼叫dbo.TWORK_AI_QUERY)、CatalogSqlReader(catalog 直查_ai_schema/INFORMATION_SCHEMA)、ViewCatalogLoader、ErpAiToolRegistry。-
TsErp.Ai.Mcp.Server:MCP-over-stdio(JSON-RPC 2.0)server exe。- WPF:
ViewModel/AIQuery/ChatAgentViewModel.cs+TsERP/AIQuery/ChatAgentView.xaml(.cs)(TelerikRadChat+ WebView2 圖表區);App.xaml加ChatAgentViewModelDataTemplate。
- 可查資料:以 DB 的
_ai_schema為準(執行期載入;實測 darbnogicsa1 有 272 個可查 view),唯讀。加可查表 = 改_ai_schema,不需改程式。
.mcp.json加tserp條目,供 Claude Code / Desktop 掛載同一支 server(Windows 驗證免帳密;env 帶TSERP_AI_RO_CONN/TSERP_AI_DB)。
資料存取(LLM 寫 SQL → TWORK_AI_QUERY)
run_sql/run_analysis接收 LLM 寫的 SELECT,經dbo.TWORK_AI_QUERY執行:該 proc 強制只准 SELECT、擋寫入/危險關鍵字、FROM/JOIN表須在_ai_schema白名單、自動TOP限筆、寫_ai_query_log稽核。
- 初版的「結構化參數 + 程式直查 + 程式白名單」(
QueryDataTool/WhitelistSql/PlanRunner/ReadOnlySqlExecutor) 已移除,改由 DB 閘道把關(見 ADR 0027 演進紀錄)。
變更
- 主視窗 AI 按鈕(
MainWindowBtnAIViewModel.Execute)→ 開啟新ChatAgentViewModel(ShowAiWindow())。
WindowService.ShowAiWindow():由舊AIQueryViewModel改為ChatAgentViewModel。
FoundryPlanService:移除把 AI 輸出寫死到C:\temps\tt.json的 debug 寫檔(此服務仍由Qc_qry3使用,未刪)。
刪除
Common/AI/ChatGptHelper.cs(含明文 OpenAI service-account key,僅一處註解引用,已刪除;該金鑰應於 OpenAI 後台撤銷)。
- 舊 AIQuery 視窗:
ViewModel/AIQuery/AIQueryViewModel.cs、TsERP/AIQuery/AIQueryView.xaml(.cs)、LogicBll/AI/AIQueryBll.cs、App.xaml對應 DataTemplate。
- 語音 AI:
ViewModel/MainWindowPage/AIPageViewModel.cs、TsERP/AIRightSide.xaml(.cs)、Common/TsAzure/SpeechHelper.cs,及其 DI 註冊與 MainWindow VM 注入。
設定需求(系統參數表 `_prgpar`)
CLAUDE_API_KEY(必填):Anthropic Claude API 金鑰。
CLAUDE_MODEL(選填):預設claude-sonnet-4-6。
AI_MCP_SERVER_PATH(選填):MCP server exe 路徑,預設自動尋找。
Breaking Changes
- 舊「AI 資料查詢助理」(AIQuery,自行產 SQL 執行)已移除,由新「AI 智慧助理」取代;查詢改走白名單工具,行為與可查範圍不同。
- 語音 AI 頁面移除。
Migration Notes
- 建置
TsErp.Ai.Mcp.Server(已設為 TsERP 建置相依,會自動先建)。WPF 端由McpServerLocator自動定位 exe;部署時請確保 server 輸出檔與主程式同目錄或以AI_MCP_SERVER_PATH指定。
- 唯讀保證目前以
ApplicationIntent=ReadOnly暫代,建議後續改用專用唯讀 SQL 帳號(DB 層防寫)。
- 安全:請至 OpenAI 後台撤銷舊
ChatGptHelper內的 service-account key。
相關
- [[ADR 0027 — MCP-first 內嵌 AI Agent]](../decisions/0027-mcp-first-ai-agent.md)
-
06-01 usp-新增程式-stored-proc ▸
2026-06-01 新增 `usp_新增程式` 預存程序
摘要
新增一支 SQL Server 預存程序
dbo.usp_新增程式,用來「一次登錄一支新程式」,自動寫入下列 5 張系統表,省去逐表手動 INSERT。已部署於 darbnogicsa1。
程式碼版控於
sql/usp_新增程式.sql。新增
sql/usp_新增程式.sql— 預存程序原始碼。
- 一次寫入:
| 表 | 列數 | pkid |
|----|------|------|
|
_menum(程式主檔)| 1 | 手動 MAX+1 ||
_menud(選單明細/所屬模組)| 1 | 手動 MAX+1 ||
_sheetno(單號設定)| 1 | identity 自動 ||
_tableseq(資料表序號)| 1(該表不存在才補)| 手動 MAX+1 ||
prgsct1(程式權限)| 每使用者 1 列 | 手動 MAX+1 連號 |行為重點
- 跨表關聯鍵:
_menum.類別名稱/_sheetno.單據別/prgsct1.類別名稱= 英文
ProgramClass;
_menum.程式名稱/_menud.程式名稱= 中文顯示名稱。- prgsct1 每使用者一筆:對既有
prgsct1的DISTINCT linkid(= 全部使用者)
逐一產生一列,
linkid即使用者鍵。- 6 個主要權限(瀏覽/明細/修改/新增/刪除/列印)由參數帶入。
- 其餘權限欄位(其他 1–36、看單價、xls、pivot、mail、流程、附件、複製、審核、
自動審核等)一律重設為 0/空白,不繼承任何範本。
- 不讀取
secret1帳密表。- 共通系統欄位:
srvdbid取自現有資料、logid=0、管制碼=0、增刪修/選擇空白、
輸入日期/人員/地點自動帶入。- 防呆:程式代號/選單序號重複、
prgsct1無資料、@建立單號=1卻缺@資料表名稱
皆會
RAISERROR並中止;全程包在BEGIN TRAN+SET XACT_ABORT ON。呼叫範例
EXEC dbo.usp_新增程式 @程式代號 = N'CHKRB', @程式名稱 = N'標準成本與進貨比較B', @序號 = N'M-11', @按鈕名稱 = N'K.成本管理', @說明事項 = N'標準成本與進貨比較B', @資料表名稱 = N'chkrb_m', @前置碼 = N'CB';Migration Notes
- 目前僅部署於 darbnogicsa1(VFP 原始表名
_menum/_menud/_sheetno/_tableseq/prgsct1)。
- 其他客戶庫若採
twork_sys_*前綴 schema(如 darbzdcsa1),欄名與 identity 設定不同,
需另寫版本,不可直接套用本程序。
-
06-01 secretbrowsepage-detail-radgridview ▸
SecretBrowsePage 明細改用 TsBrowseRadGridView
摘要
TsERP/BrowsePage/SecretBrowsePage.xaml(權限瀏覽頁)的明細 grid 從舊的TsControl:TsDataGrid改成tsTelerik:TsBrowseRadGridView,與主檔一致,並對齊通用瀏覽頁TsControl/Layout/ErpBrowse.xaml的 master/detail pattern。變更
- 明細 grid 由
TsControl:TsDataGrid→tsTelerik:TsBrowseRadGridView(x:Name="DgDetail")。
- 改綁
DetailViewModel(TsBrowseDataGridViewModel)的DataView/Schemas,AutoGenerateColumns="True"依 DB schema 動態產生欄位。
- GridSplitter 加上
Visibility="{Binding DetailViewModel.Visibility}",與通用瀏覽頁一致。
- 移除明細寫死的 35+ 個
DataGridTextColumn/DataGridTemplateColumn(Allow* 權限 checkbox)與TsView.Resources內僅供舊欄位用的HeaderCenter、Chkstyle。
修正
- 舊明細 grid 綁
ItemsSource="{Binding DataTableItemsSource}",但其 DataContextDetailViewModel是TsBrowseDataGridViewModel,該型別沒有DataTableItemsSource屬性(只有TsDataGridViewModel才有)。主檔早先已遷移到 browse VM,明細卻未同步,導致明細實際綁不到資料。本次一併修正。
Breaking Changes
無。明細為唯讀瀏覽,欄位改由 schema 動態產生(與其他模組瀏覽頁行為一致);權限旗標以欄位值呈現,不再是唯讀 checkbox。
Migration Notes
無需資料庫或設定變更。
- 明細 grid 由
-
06-01 radgridview-session-sort-persist ▸
TsRadGridView 臨時排序跨畫面切換自動保留
摘要
TsControl/TsTelerik/TsRadGridView.cs新增「執行階段版型暫存」機制:使用者在 grid 上臨時排序(或調欄寬、欄序、群組)後,切到別的畫面再切回來時排序會自動保留,不需要手動點右鍵的「記憶格式」。此機制對全 App 所有TsRadGridView(含繼承的TsBrowseRadGridView)一體生效。背景
本專案切畫面採「換 VM + DataTemplate 重建畫面」模式,切回來時 grid 是全新實例。Telerik
RadGridView的排序狀態(SortDescriptors)只活在該 grid 控件實例上、不在資料來源(DataManager.GridView)上,且原本只有按「記憶格式」(Serialize()寫入 SQL) 才會被保存。因此臨時排序在切畫面後就消失。新增
- 靜態記憶體快取
_sessionFormatCache(Dictionary<string,string>,key =TsDataGridTag=ProgramClass + grid 名稱)。
SaveSessionFormat():Unloaded時用現成的PersistenceManager.Save把目前版型(含排序/欄寬/欄序/群組)序列化存入快取。
變更
TsRadGridView_Unloaded在解除事件掛勾後,多呼叫一次SaveSessionFormat()。
LoadSetting():在讀完 SQL 永久版型後,再套用 session 快取的版型(較新,覆蓋上去),讓切回來的新 grid 還原臨時排序。
行為
- 純記憶體、不寫 SQL:不影響、也不取代「記憶格式」功能(永久保留仍走「記憶格式」→ SQL)。
- App 關閉後快取清空(下次開啟回到 SQL 永久版型或預設)。
- 套用順序:SQL 永久版型 → session 暫存版型(session 較新者勝)。
- 因走整份
PersistenceManager版型,連同欄寬/欄序/群組也會一併在切換間保留,而不只是排序。
Breaking Changes
無。屬於行為增強;既有「記憶格式」(SQL) 流程與資料不受影響。
Migration Notes
無需資料庫或設定變更。
---
修正(2026-06-05):排序/群組改走獨立記憶體快取
問題
上述機制原以為靠
PersistenceManager.Save/Load即可保留排序,實際上排序完全沒被保留。根因:全域註冊的
TsGridViewCustomPropertyProvider只持久化Columns,SortDescriptors/GroupDescriptors的持久化被註解掉,且InitializeObject在還原時主動Clear()排序與群組。因此經 PersistenceManager 的版型一律不含排序。
決策
- 「記憶格式」(SQL 永久版型) 刻意不含排序 —— 維持現狀。
- 排序/群組只在執行階段記憶體快取裡跨畫面保留。
兩個關鍵根因
1. 排序不掛在
this.SortDescriptors。 本專案多數 grid 的ItemsSource綁的是QueryableCollectionView(DataManager.GridView,或直接{Binding Xxx.GridView}而未設DataManagerDP)。Telerik 文件明載:ItemsSource 若已是 QCV,grid 直接使用該實例,排序/群組進的是那個 QCV 的
SortDescriptors/GroupDescriptors,this.SortDescriptors恆為空。所以連
CollectionChanged都不會在this.SortDescriptors上觸發。2. 不能等到
Unloaded才讀。 切畫面Unloaded會 detachItemsSource,太晚。變更(hook 綁定 QCV + eager capture)
_sessionFormatCache值型別由string改為SessionFormat(Xml+Sorts+Groups)。
- 排序/群組改用
Proxies.cs既有的SortDescriptorProxy/GroupDescriptorProxy存進記憶體,
繞過 PersistenceManager,因此不會被「記憶格式」一起寫進 SQL。
- 新增
BoundQcv(ItemsSource as IQueryableCollectionView ?? DataManager?.GridView)與
EffectiveSortDescriptors/EffectiveGroupDescriptors:排序真正掛的集合(綁 QCV 走 QCV,否則退回 grid 自身)。
- 排序/群組改為「變更當下即時寫快取」:
Loaded後HookSortGroupChanged()掛勾
綁定 QCV 的
SortDescriptors.CollectionChanged/GroupDescriptors.CollectionChanged(記住實例
_hookedSorts/_hookedGroups,detach 後仍能正確解掛);任何排序/群組變動立刻由CacheSortGroupNow()從該集合讀取寫入快取。SaveSessionFormat()(Unloaded)只更新欄寬/欄序/隱藏的Xml,不動 Sorts/Groups;
Unloaded一開始就UnhookSortGroupChanged()。- 切畫面回寫防護:切畫面 detach 會把
ItemsSource設 null、連帶清空 QCV 排序並觸發
CollectionChanged。OnSortGroupChanged以!IsLoaded || ItemsSource == null擋掉這種「teardown 清空」——此時
ItemsSourceDP 已是 null(DP 先賦值、再跑變更處理清排序),守門成立,不會用空排序蓋掉快取。正常使用中
IsLoaded=true、ItemsSource有值,照常即時寫。LoadSetting()的ApplySessionSortGroup()還原時套回EffectiveSortDescriptors(即綁定 QCV),
期間以
_suppressSortCache抑制回寫。- 同時支援
ColumnSortDescriptor(UI 排序)與普通SortDescriptor(VM 直接 add,帶Member)兩種型別:
capture 用
SortDescriptorBase/GroupDescriptorBase取鍵(Column.UniqueName或Member),restore 以
ResolveColumnByKey(比UniqueName→SortMemberPath→DataMemberBinding路徑)找回欄位,對得到還原成
ColumnSortDescriptor(含表頭箭頭),對不到則退回普通SortDescriptor(至少資料有排序)。(原本只吃
ColumnSortDescriptor,遇到 VM 預設的普通SortDescriptor(如WkcaldViewModel)會被濾光。)TsGridViewCustomPropertyProvider.cs與Proxies.cs未改。
修正前文校正
本文「新增/變更/行為」段落原稱「
PersistenceManager.Save把目前版型(含排序…)序列化」、「連同…群組也會一併在切換間保留」——就排序/群組而言當時並未成立,以本節為準:
排序/群組走記憶體快取,欄寬/欄序/隱藏才走 PersistenceManager Xml。
- 靜態記憶體快取
-
06-01 operationpanel-ctrl-f12-my-input ▸
2026-06-01 — 操作面板 Ctrl+F12:查詢「我輸入過的資料」
摘要
在表單操作面板新增鍵盤快捷鍵 Ctrl+F12:以「輸入人員 = 目前登入者」為條件,用
DARB_BROWSE的最近輸入筆數模式跑查詢,列出「我最近輸入的 20 筆、依輸入日期由新到舊」,結果直接灌進導覽區的「瀏覽」分頁,停留在目前表單頁面、不切換到瀏覽頁。讓使用者快速看到自己在該表單剛建立過的單據。新增
OperationPanelViewModel.QueryMyInputCommand(ViewModel/Control/PageParts/OperationPanelViewModel.cs)
- 條件:
輸入人員 = N'{Context.User.UserName}'(即「我建的單」)。- 查詢模式:
BrowseQuery(..., lpP3:"1", lpP4:"20"),即DARB_BROWSE @browsecondtype=1(最近輸入筆數)→SELECT TOP 20 ... WHERE 輸入人員=我 ORDER BY 輸入日期 DESC。- 重用既有瀏覽查詢路徑(
BrowseBll.BrowseQuery→DARB_BROWSE→ SQLite 虛擬化IBrowseProvider),主檔表名換成瀏覽用 view(SheetNoMethod.GetBrowseViewName),與ErpBrowseBaseViewModel.GetTablesName一致。- 結果寫進
SupportPanelViewModel.TsBrowseDataGridViewModel,作法比照TsSeekTextBoxViewModel.Seek的 "B"(瀏覽)分支。- 順便把導覽模式切到「瀏覽」:設定
DataNavigatorViewModel.NavigationModeEnum = Browse,等同勾選導覽列的「瀏覽」radio——其 setter 會自動SwitchToBrowseTab(),且讓上一筆/下一筆/第一筆/最後一筆導覽鈕改為操作這份查出來的瀏覽清單(在清單內移動並帶動表單定位)。- 防呆:主檔表為空、或目前在增刪修編輯狀態時不動作(避免覆蓋輸入中的內容);查無資料時於狀態列提示
MessageEnum.NoData。ErpProgramLayout.xaml新增KeyBinding(Key=F12、Modifiers=Control)綁定OperationPanelViewModel.QueryMyInputCommand。放在表單版面層(表單內容與操作面板的共同祖先),焦點在表單任何欄位時都能觸發,作法比照ERPSystemContainerView的全域快捷鍵。
變更
BrowseBll(LogicBll/BrowseAndQuery/BrowseBll.cs)參數化LP_P3/LP_P4:BrowseQuery與GetSqlIntoSqlite原本把DARB_BROWSE的@browsecondtype寫死"2"、@查詢筆數寫死"0",改成可傳參數lpP3="2"、lpP4="0"(預設值不變,現有呼叫端行為不受影響)。讓呼叫端可選lpP3:"1"(最近輸入筆數)並指定lpP4的 TOP N。
- 保底:當
lpP3="1"但lpP4="0"時,自動把lpP4改成"1",避免SELECT TOP 0查不到任何資料。- 方法上方補了完整的 XML 參數說明(
lpP3/lpP4對應的 proc 參數與兩種模式行為)。Breaking Changes
- 無。
備註
- 整合方式為使用者確認後的決策:採「重用既有瀏覽查詢(DARB_BROWSE)」而非直接用
darb_getdata的 DataSet——因為瀏覽格是虛擬化、由 SQLite provider 讀取,無法直接吃darb_getdata的 DataSet;並要求不切換頁面,故灌進導覽區「瀏覽」分頁。
- 建置:
ViewModel與TsControl專案以 VS MSBuild 建置通過(dotnet build因 Office COM 參考的MSB4803 ResolveComReference無法用,需用 VS 版 MSBuild)。TsERPapp 目前另有與本改動無關的 XAML 編譯錯誤(TsERP/Other/Psheet_2.xamldg-to-radgrid 遷移半成品,TsRadGridView.Columns套到TsDataGrid),非本功能造成。
- 前提假設:主檔瀏覽 view 含
輸入人員欄位(標準審核欄位)。若某程式的瀏覽 view 無此欄位,查詢會丟例外並於狀態列顯示錯誤訊息(已 try/catch)。
-
06-01 extension-panel-audit-fields ▸
擴充面板 Popup 新增建檔/輸入/工作流程/聯絡單欄位
摘要
TsControl/PageParts/ExtensionPanel.xaml與TsControl/PageParts/FinancialExtensionPanel.xaml的「加號展開 Popup」中,原本只顯示審核日期 / 審核人員,新增 6 個欄位:建檔日期、輸入日期、輸入人員、輸入地點、工作流程、聯絡單id。新增
兩支面板的 Popup grid 由 2 列擴成 8 列,於審核資訊下方依序新增(皆唯讀):
欄位 控件 備註 建檔日期 TsTextBox 唯讀 string 輸入日期 TsTextBox 唯讀 DateTime→StringFormat=yyyy/MM/dd輸入人員 TsTextBox 唯讀 輸入地點 TsTextBox 唯讀 工作流程 TsTextBox 唯讀 聯絡單id TsTextBox 唯讀 int→StringFormat=N0、靠右- 全部綁
Content.MasterItem.<欄位>,label 用DisplayMeta[<欄位>](FallbackValue 給中文),與既有審核日期/審核人員完全同模式。
- 標籤顏色沿用各面板既有主色:
ExtensionPanel用ImportantColor、FinancialExtensionPanel用SystemGenerateColor。
變更
- 新增欄位皆設
IsReadOnly="True":建檔、輸入、工作流程、聯絡單id 屬系統審核資訊,不開放手動編輯(審核日期/審核人員維持原樣可編輯)。
Breaking Changes
無。屬 UI 顯示增強,不影響資料與既有審核欄位行為。
Migration Notes
- 無需資料庫或設定變更。
輸入日期/輸入人員/輸入地點在SourceBase(每個 master poco 皆有);建檔日期/工作流程/聯絡單id僅存在於部分 Source 類別。
- 面板綁定的
Content.MasterItem為object(任意 master poco),採「字串路徑綁定」:poco 有該屬性即顯示值,沒有則顯示空(FallbackValue)並在 debug 輸出留 binding 訊息,不會 crash。此行為與既有已審核/審核日期/審核人員(同樣非 SourceBase 通用欄位)一致。
- 若要僅在具備這些欄位的特定畫面顯示,可比照
FinancialExtensionPanel對相關單號/傳票號碼的Visibility綁定方式另行控制。
- 全部綁
-
06-01 crash-recovery-no-popup-loop ▸
畫面 render 崩潰不再無限跳窗,改為自動移除壞畫面
摘要
修正當某個程式畫面在 render 途中拋例外(典型如
XamlParseException)時,錯誤視窗會無限重複跳出的問題。改為:同一錯誤只跳一次窗,隨即把壞掉的畫面從導覽移除、清空主內容區,讓 app 繼續可用,而不是反覆洗版或直接關閉整個程式。背景(原因)
「一直跳窗」並非崩潰本身造成,而是復原流程的缺陷:
1. 壞掉的 view 仍是容器(
ErpSystemContainerViewModel)的當前內容,沒有被移除。2. 錯誤用 modal
MessageBox呈現,對話框關閉時觸發主視窗 relayout → 又 render 壞 view → 再拋例外 → 再跳窗,形成迴圈。3.
App_OnDispatcherUnhandledException的迴圈偵測原本用「500ms 內才算重複」的時間窗,但 modal 對話框顯示時間必然 > 500ms,導致重複計數每次被重置、永遠到不了關閉門檻 → 無限跳窗。變更
TsERP/App.xaml.cs—App_OnDispatcherUnhandledException
- 迴圈偵測由「時間差」改為「例外簽章(型別 + 訊息)」比對,不再被 modal 對話框時間打亂。
- 同一錯誤只在第一次跳窗,之後重複只寫 log,不再洗版。
- 每次處理後呼叫復原(見下);同簽章持續重複且復原無效並超過門檻時,才顯示「即將關閉」並
Shutdown。- 新增
TryRecoverFromBrokenView(),從 DI 取IProgramNavigator並呼叫復原(全程 try/catch,復原本身不會再炸)。新增
Common/Interface/IProgramNavigator.cs— 新增bool RecoverFromBrokenCurrentView()。
ViewModel/ProgramNavigator.cs— 實作RecoverFromBrokenCurrentView():把壞掉的當前程式從_programContexts移除、_currentProgramClass設為 null,再SetContainerContext(true)將容器內容清成 null。壞畫面離開視覺樹後 render 迴圈停止;主視窗導覽列保留,使用者可改點其他程式,無需關閉整個 app。下次重新點選該程式會重新建立 context。
Breaking Changes
無 API 破壞性變更(
IProgramNavigator為內部介面,新增方法已在唯一實作ProgramNavigator補齊)。屬全域例外處理策略的行為變更。行為變化與取捨
- 之前:畫面 render 崩潰 → 錯誤視窗無限重複跳出(且因時間窗 bug,原訂的「重複 N 次自動關閉」實際上幾乎不會觸發)。
- 之後:跳一次錯誤訊息 → 自動移除壞畫面、app 續用;真正持續無法復原才關閉。
- 取捨:同一個壞掉的程式若立即再次點選,因例外簽章相同只會靜默復原、不再跳窗(log 仍會記錄)。使用者已看過一次錯誤,可接受。
Migration Notes
無需資料庫或設定變更。
📅 2026 年 5 月 (40 篇)
-
05-29 sppdt-vfp-fixes ▸
2026-05-29 — sppdt(廠商報價)VFP 對比修正
摘要
對比 VFP
scx_pur.vcx的sppdt(廠商報價)後,補回allowsave中三段遺漏的存檔邏輯到SppdtSave。變更
- 無幣別/匯率時預設本幣 + 1:存檔時若
幣別為空且匯率未填(<=0),自動帶入本幣(Context.Env.LocalCurrency)與匯率1(SppdtSave.HandleDataBeforeEndEdit)。未採用 VFP 的U_BLRATE匯率表查詢/無條件覆寫(業務決策)——外幣報價的匯率由使用者自行輸入,已輸入者不覆寫。
- 空明細列自動標記刪除:存檔時,
品號與工程代號皆為空白的明細列自動標增刪修='D',對應 VFPREPLACE 增刪修 WITH 'D' FOR EMPTY(品號) AND EMPTY(工程代號)(SppdtSave.HandleDataBeforeEndEdit)。
新增
- 活動期間驗證:已輸入「活動起始日」但未輸入「活動截止日」時擋存並提示(
SppdtSave.AllowSave),對應 VFP allowsave 同名檢查。
Breaking Changes
- 無。只有在「幣別為空且匯率未填」時才補本幣 + 1;使用者已輸入的幣別/匯率不會被覆寫(業務決策,與 VFP 無條件
U_BLRATE覆寫不同)。
- 備註:新增時
SppdtViewModel.AfterAddNew已預設幣別=本幣、匯率=1,故此存檔保險僅在資料幣別被清空等邊界情況才會觸發。
備註
- VFP 另有事件層邏輯未移植(次要):
幣別.LostFocus即時帶匯率(改由存檔時統一帶)、工程代號對 BOMproces的存在性驗證(VFP 僅提示不擋)。品號歷史單價查詢新版已由 detail listener →QueryCommand涵蓋。
- 建置:
dotnet build LogicBll通過(0 錯誤)。SaveBll 行為面建議由使用者實測:新增→輸外幣→存,確認匯率被帶入;輸活動起始日但留空截止日→存,確認擋下。
- 無幣別/匯率時預設本幣 + 1:存檔時若
-
05-29 rp-m-schema-extend ▸
2026-05-29 — 收付款/財務單(rp_m / rp_d / rpsht)schema 擴充
摘要
替 AR/AP 財務單主子檔(
rp_m/rp_d)與收付款單主子檔(rpsht_m/rpsht_d)新增多個欄位(稅額、含稅金額、備註、建檔日期、第三組單別/單號等),並同步更新對應的 4 個 view 把新欄位帶出來。對應 SQL 腳本:C:\temps\sqlscript\更新rp_m.sql。新增
資料表欄位
rp_m:建檔日期(char 10)、原幣稅額(decimal 19,4)、總原幣未稅(decimal 19,4)、總本幣未稅(decimal 19,4)、含稅別(char 1)
rp_d:原幣稅額、折扣、代工價含稅、其他金含稅、微調原含稅、微調本含稅(皆 decimal 19,4)、備註(nvarchar 120)
rpsht_m:建檔日期(char 10)
rpsht_d:分類索引4(nvarchar 30)、單別3(char 2)、單號3(nvarchar 20)
View 更新(帶出上述新欄位 + sp_refreshview)
vw_rp_m:加建檔日期、原幣稅額、總原幣未稅、總本幣未稅、含稅別
vw_rp_d:加原幣稅額、折扣、代工價含稅、其他金含稅、微調原含稅、微調本含稅、備註
vw_rpsht_m:加建檔日期
vw_rpsht_d:加分類索引4、單別3、單號3(備註改抓rp_m.備註)
變更
- 無(既有欄位/邏輯未改)
刪除
- 無
Breaking Changes
- 無。新欄位皆
NOT NULL DEFAULT,既有資料列以預設值回填,舊程式不受影響。
Migration Notes
- 執行腳本
更新rp_m.sql(依序:ALTER TABLE 加欄位 → ALTER VIEW 4 支 →sp_refreshview)。可整段執行。
- 已修正:原
rpsht_d的單別3/單號3重複 ALTER 已移除;rp_d.備註的 DEFAULT 已由0改為''。
- 對應的 Model/Source(
Twork_arp_*等)若要使用新欄位,需另跑/db-model-compare補上屬性後才會在程式端可用。
-
05-29 remove-rp-m-receipt-xml ▸
2026-05-29 — 移除 RP_M 收據xml 欄位(停用 9B 收據/發票 XML)
摘要
移除 RP_M(rp_m)的
收據xml欄位與其相關的發票 XML 序列化/還原流程。影響財務類別 9B 單據的發票號碼重建。詳見 ADR 0025。變更
- 付款/收款/暫存存檔不再產生
收據xml。
- 9B 單據轉單(RpfZero / Psheet_1)不再從
收據xml還原並覆寫多行「發票號碼」。
- Psheet_1 票據檢核/現金流程的發票號碼累計(
invoiceNO/receiptCount)不再填值(恆為空 / 0)。
新增
無。
刪除
Twork_arp_vw_rp_mModel/Twork_arp_vw_rp_mSource的收據xml屬性。
- 6 處寫入(含
FillXML產生器)、5 處讀取邏輯、語系項ReceiptXML。
- (順帶)Source 端誤掛在
收據xml上的[TsColumnName(使用人)]重複對應。
Breaking Changes
- 9B 單據不再自動把多發票合併顯示在「發票號碼」。
- 依賴 Psheet_1 票據發票號累計的下游(票據分頁/票面發票號)需確認影響。
Migration Notes
- DB 的
收據xml欄位由 DBA 自行處理(移除或保留皆可,程式已不讀寫)。
- DB 內既有的 收據xml 資料不再被使用。
- 付款/收款/暫存存檔不再產生
-
05-29 purch-special-edit ▸
2026-05-29 — purch(採購單)補回「特殊修改」
摘要
對比 VFP
scx_pur.vcx的purch(採購單)發現「特殊修改」按鈕(VFPelse8click,OPMODE=9)在新版未接線——PurchViewModel未宣告IOther3,姊妹類ppurch/fsheet都有。本次補上。變更
- 無
新增
- 特殊修改功能:
PurchViewModel新增IOther3介面與ExtendedFunction3(),呼叫框架AdeViewModel.SpecialEdit(),對應 VFPpurch.else8click(特殊修改 / OPMODE=9)。與姊妹類FsheetViewModel.ExtendedFunction3寫法一致。
Breaking Changes
- 無。新增一顆「其他」功能按鈕(特殊修改);按鈕標題由程式參數/權限設定(資料端)控制。
SpecialEdit刻意比一般編輯寬鬆、不走AllowEditHandle(與 VFP else8 未做 AllowEdit 防呆一致),故未額外加防呆。
備註
- 建置:
dotnet build ViewModel僅剩既有的MSB4803 ResolveComReference工具鏈錯誤(與本改動無關),無 C# 編譯錯誤;最終請在 Visual Studio 內 build 確認。
- purch 仍有未移植項待處理(屬功能新建,本次未動):修改交期(VFP
_CHANGEDATE)、進貨查詢(VFPPURCH_S)、確認(VFP else7,蓋確認章;現有PurchBll.Confirm()為 PO/訂單量差異報告,語意不同且未接線)。見 memoryscx-pur-compare-progress。
-
05-27 sliya5-void-stamp ▸
2026-05-27 傳票 A5 報表補回「本張作廢」章與簽核欄
摘要
比對 VFP 舊報表
sliya5.frx與 FastReport 版Sliy_a5.frx,發現新版漏移植了「本張作廢」作廢章、簽核欄與輸入人員。本次補齊,行為對齊 VFP。新增
- 本張作廢章:傳票
已審核 = 'X'(作廢)時,傳票報表頁首印出紅色作廢章。對齊 VFPsliya5的列印條件已審核='X'。三個版型皆已加入:
-
Sliy_a5.frx(A5)、Sliy.frx(中一刀)→「本張作廢」-
Sliy_e.frx(英文 Letter)→「VOID」- 簽核欄:A5 版(
Sliy_a5.frx)頁尾加「核准/覆核/會計/出納/製單」簽名列。
- 輸入人員:A5 版傳票區塊顯示輸入人員。
- 英文科目名稱:
Sliy_e.frx的科目名稱欄改用英文名稱(英文科目名稱),資料原本已由GetReportSource()由accl.英文名稱帶出。
- 英文公司名稱:
Sliy_e.frx標頭公司名稱由中文[CompanyName]改綁英文[CompanyNameEng](取代,英文報表只顯示英文)。FastReportExtension.SetDefaultReportParameter新增送出CompanyNameEng = EnvironmentSetting.CustomCompanyName(即公司英文名);該參數只有Sliy_e宣告,其他報表不受影響(SetReportParameter只對有宣告的參數設值)。
變更
Model/Rpt/Rpt_N010_SliyReportPoco.cs:新增已審核(C1)屬性。
ViewModel/N.GeneralLedger/GeneralLedger/SliyPrintViewModel.cs:GetReportSource()投影補已審核 = a.已審核,讓匯出到 SQLiterpt_n010_sliy_report1的資料帶上作廢旗標(資料原本已在 masterTworkAccVwSliymRpt.已審核,只是投影時漏掉)。
FastReport/Sliy_a5.frx:資料源加已審核欄;新增TextVoid_BeforePrintscript 依已審核 == "X"控制作廢章顯示;GroupHeader加作廢章與輸入人員;GroupFooter加簽核欄並加高 band。
刪除
無。
Breaking Changes
無。
Migration Notes
- 「作廢」判定沿用 VFP 的
已審核 == "X"。若新系統實際以其他值/欄位標記傳票作廢,需同步調整三張.frx的TextVoid_BeforePrint判斷與後端投影。
Sliy_e.frx的作廢章文字採用英文「VOID」;如需與中文版一致改回「本張作廢」,改該物件Text即可。
- A5 版的簽核欄/輸入人員尚未套用到
Sliy.frx、Sliy_e.frx(本次僅依需求補作廢章);如需一致,比照Sliy_a5.frx加物件。
- 各物件座標為對齊現有版面的擺放,可於 FastReport 設計器微調。
- 本張作廢章:傳票
-
05-27 ppurch-vfp-fixes ▸
2026-05-27 — ppurch(請購單)VFP 對比修正
摘要
對比 VFP
scx_pur.vcx的ppurch(請購單)+ 其開啟的子表單_CSAEDIT(請購單改期別)後,修正一個靜默 binding bug,並補回期別自動分類邏輯。變更
- 請購備註欄位修正:主檔「備註」輸入框原本綁定
{Binding 備註},但 Source 屬性實際是請購備註→ 該欄永遠空白且存不進去;改綁請購備註(Ppurch.xaml)。
- 期別自動分類(補回
_CSAEDIT邏輯):存檔時,若主檔已設「本期」起始日,依各明細的建議行動日落在哪個期間,自動把期別設為 本期 / 下一期 / 下二期 / 其他(PpurchSave.HandleDataBeforeEndEdit)。
- 期別日期遞增驗證:存檔時,若有設期別,檢查 本期A2≥本期A1、下一期A1>本期A2、… 等遞增關係,不符則擋存(
PpurchSave.AllowSave)。
新增
- 無
Breaking Changes
- 無。期別分類與遞增驗證都僅在主檔「本期a1」有值(期別功能使用中)時才生效,未使用期別的請購單存檔行為不變。
備註
- VFP
_CSAEDIT另有「輸入本期A1 自動帶下一/下二期日期(+30/+31/+150/+151/+300 天)」功能,因該天數為特定客戶(凱琦)專屬設定,本次未移植;使用者自行輸入三組期別日期即可,期別分類照樣運作。
- ppurch「轉訂單」(訂單轉請購 / OrmastToPP) 原為半成品,本次重建完成(照 VFP
ODTOPP):OrmastToPPBll.SpecialAdeQuery改接既有 SPDARB_TUR_ODTOPP(手動將中文欄位 map 成英文 Poco),SetUpdateSource補上按「訂單×廠商」分組建立 ppurma/ppurde(金額用既有SetFxRate()/SetAmount());新增Procedure.DARB_TUR_ODTOPP。程式碼編譯乾淨,但尚未 runtime 測試,且外幣匯率取得與分組策略有 caveat(見 memoryscx-pur-compare-progress)。
- 請購備註欄位修正:主檔「備註」輸入框原本綁定
-
05-27 bankfcst-spbank-vfp-fixes ▸
2026-05-27 — bankfcst / spbank / ftrlima / fsheet VFP 對比修正
摘要
對比 VFP
scx_chk.vcx的bankfcst(預估資金表)、spbank(廠商帳戶表)、ftrlima(財務雜項單據)、fsheet(收付款單)後,修正四個與舊系統行為不一致、UI 重複或缺少防呆的問題。另記錄一個待辦(spbank 異動轉檔)。bankacqry(銀行存提表)、bankday(資金日報表)同批對比確認為忠實移植,無需修改。變更
- bankfcst 本幣金額小數位:
存入本幣金額/提出本幣金額原本用外幣(幣別)的小數位數四捨五入,改為用本幣小數位(Context.Env.LocalDecimal),與 VFPROUND(存入金額*匯率,0)及姊妹類 checkrec 的本幣金額算法一致。外幣(例如 USD)預估資金的本幣換算金額顯示位數會因此修正。
- spbank 自訂群組自動帶值:輸入廠商代號時,若「自訂群組」為空白,自動帶入廠商代號本身(還原 VFP
廠商代號.Valid行為)。
- ftrlima 明細移除重複欄:明細 grid 原本有兩個完全相同的「需求部門」欄(複製貼上殘留),移除其中一個。
新增
- fsheet 編輯/刪除防呆(
FsheetEdit):還原 VFPfsheet.allowedit。收付款單若已有「出納傳票號」(已轉票據匯款)、「沖帳備註」(已沖帳)或「沖帳傳票號」(已轉傳票),不得修改或刪除。新版原本缺少FsheetEdit(走 baseEditBll無條件允許),與同表姊妹類PsheetEdit(應付)/RsheetEdit(應收)不一致——本次補齊。保留IsCancelStike例外(取消沖帳流程下允許編輯,對應 VFPIF NOT 取消沖帳)。
Breaking Changes
- 行為變更:先前可以修改/刪除「已轉傳票或已沖帳」的收付款單(F 類),補上防呆後將被擋下並提示。此為還原舊系統與姊妹類既有保護,屬預期行為。
備註
- VFP
fsheet.allowedit僅有上述三條轉檔/沖帳防呆;姊妹類PsheetEdit/RsheetEdit另含「禁修日期(closing book)」檢查。本次FsheetEdit先只還原 VFP 既有的三條,未加禁修日期檢查(若要與 Psheet/Rsheet 完全一致可後續再補)。
新增
- 無
刪除
- 無
Breaking Changes
- 無
Migration Notes
- 無需 DB migration。bankfcst 本幣金額為畫面即時計算(未持久化),僅影響顯示;既有資料不受影響。
待辦(規劃中)
- spbank「異動轉檔」:VFP
spbank.else1click(CMDELSE1,Caption=「異動轉檔」)會匯出台新銀行付款檔(DO FORM SPBANK_E),新版尚未實作對應IOther1.ExtendedFunction1。經確認屬公司專屬需求,暫列待辦、未排程實作。
對使用者的影響
- 「預估資金表」外幣單據的本幣換算金額顯示位數修正為本幣位數。
- 「廠商帳戶表」新增/輸入廠商代號時,自訂群組會自動帶入廠商代號(原本留空)。
- bankfcst 本幣金額小數位:
-
05-27 accself-poco-chinese-columns ▸
2026-05-27 Accself 報表資料源欄位改中文(修好空白問題)
摘要
Accself 系列報表(Accself1~10、Accselfm 等)的 FastReport
.frx都綁中文欄名,但其資料源 POCORpt_N130_AccrptReportPoco1是英文屬性名。ExportToSqlite直接用屬性名當 SQLite 欄名(GetColumnString的translateToLocalColumn實為 no-op),所以匯出的是英文欄 → 與 .frx 的中文綁定對不上 → 報表月份/金額欄空白。本次把該 POCO 屬性名改成中文(對照Model.json既有英中對照、與 .frx 欄名一致),讓資料源欄位與報表綁定吻合。變更
Model/Rpt/Rpt_N130_AccrptReportPoco1.cs:~60 個屬性英文→中文(如ReportTitle→報表抬頭、Year0And01→今年01、Budget01→預算01、DecimalLength→小數位數…)。計算屬性、當期月份setter、NeedShow()內部引用一併中文化,邏輯不變。輔助類Rpt_N130_AccrptReportPoco1Parameter維持英文(不匯出)。
Model/Bll/SelfrptSource.cs:ToRptN130物件初始化左側(POCO 屬性)改中文;右側(SelfrptSource 自身英文屬性 / para)不變。
TworkReportPluginOfficial/N.GeneralLedger/:11 支 plugin 修正對該 POCO 的引用——
- Accself1~6、9、10、Accselfm:
item.ReportTitle/QueryDate→報表抬頭/查詢日期- Accselfm、Accselfm1、Accselfm2:建立 POCO 的物件初始化左側改中文(右側
item.*為 SelfrptSource 英文屬性,不動)Accself7/8/Accselfsimple不受影響(它們的目標是另一支早已中文化的Rpt_N130_AccrptReportPoco,且讀的是 SelfrptSource 英文屬性)。
刪除
無(屬性改名,非刪除)。
Breaking Changes
- 匯出表
rpt_n130_accself_report1的欄名由英文變中文。FastReport.frx已是中文綁定,故報表端不需改;但任何直接以英文欄名讀此表的程式/查詢都需同步改中文(目前未發現此類使用)。
Migration Notes
.frx無需修改、無需重新部署到 Reports 夾。本次純後端改名,需重新編譯部署 app才生效。
- 命名以
TsERP/Lang/Model1/Model.json的Rpt_N130_AccrptReportPoco1英中對照為準,與 .frx 欄名一致。
- 同類別的其他報表 POCO(Sliy、Sliybrowd 等)本來就是中文屬性名,不受影響。
-
05-27 accself-account-name-indent ▸
2026-05-27 Accself 報表科目名稱還原前導縮排空格
摘要
Acc_selfrpt(自訂財報)報表的科目名稱在讀取 SQL 公式表時,前導縮排空格被吃掉,導致報表層級縮排消失(呈現扁平)。本次在讀取後從原始 DataTable 還原前導空格。
變更
LogicBll/N.GeneralLedger/Acc_selfrpt/Acc_selfrptBll.cs:GetTmpmoverecs在dt.ToList<AccselfrptSource>()後,從原始DataTable的「科目名稱」欄還原值(只TrimEnd、保留前導縮排),讓使用者在公式中打的層級縮排空格能呈現於報表。
根因
Common/ListDataTable/DataTableToList.cs對所有字串欄位一律value.ToString().Trim()(全域共用),把使用者在「科目名稱」前面打的縮排空格清掉。自動產生列(ACC_BSAUTO / ACC_BSCE)因為空格是在 ToList 之後用new string(' ', n)補的,所以不受影響——故「自動列有縮排、自訂列沒有」。影響範圍
- 僅 Acc_selfrpt;未改動全域
DataTableToList(避免影響其他報表/查詢)。
- 一般自訂公式列(
FormulaGenerator.GenerateFormula的 else 直通分支)會帶回縮排。
Migration Notes
- 純後端修正,
.frx無需修改、無需重新部署 Reports 夾;需重新編譯部署 app 才生效。
-
05-26 asset-amortization-monthly ▸
2026-05-26 — 財產資料(ASSET) 折舊計算與預留殘值
摘要
財產資料的「計算折舊」改回與舊系統一致的月折舊法;輸入「年限」時自動帶出建議的「預留殘值」。對應 VFP
scx_ast對比結果。變更
- 計算折舊算法:由逐日比例攤提改為月折舊(年折舊額/12、年底補差、最後一期補總差),折舊明細金額分佈與舊系統一致。
- 年限 → 預留殘值自動帶入:在「金額與年限」區改「年限」並離開欄位時,自動填入
預留殘值 = 四捨五入(取得原價(或改良成本) ÷ (年限+1)),可手動覆寫。新增與修改模式皆會觸發。
新增
無新欄位 / 無新畫面。
刪除
無。
Breaking Changes
無。既有已存檔的折舊明細不受影響。
Migration Notes
- 不需 migration。
- 若某筆財產要套用新(月折舊)算法,請重新按「計算折舊」重產折舊明細。
-
05-24 sliy-budget-project-cascade ▸
2026-05-24 — Sliy / Budget 主表專案代號自動帶入明細 + 顯示專案簡稱
摘要
Sliy(總帳傳票)與Budget(預算傳票)兩支畫面:主表「專案代號」變更時,自動把專案代號與專案簡稱覆蓋寫入所有現存明細列;新增明細列時也自動帶入。明細區下方說明區新增「專案簡稱」欄位。Budget 明細表 grid 補上原本沒有的「專案代號 / 專案簡稱」兩欄,跟 Sliy 對齊。新增
ViewModel/N.GeneralLedger/GeneralLedger/SliyVirtual.cs:
-
CascadeProjectToAllDetails()— master 專案代號a 變更時,查Vwseek_aproj取得專案簡稱後,覆蓋所有增刪修 != "D"的明細列-
DetailListenerHelper_OnAddListener()— 新增明細列時依 master 專案代號a 帶入;以AdeViewModel.Status == Normal防呆,避免載入舊資料時誤觸發 DB 查詢Model/Source/N.GeneralLedger/Twork_acc_vw_sliyyearmSource.cs:補專案代號a屬性(純記憶體 stub;該年度匯總類別 DB 端無此欄位,僅為滿足ISliymSource)
TsERP/N.GeneralLedger/Sliy.xaml:下方說明區(DetailSelectedItem)新增 Row 4:專案簡稱 label + read-only textbox
TsERP/N.GeneralLedger/Budget.xaml:
- 明細 grid 新增
TsArpojSeekGridViewColumn(專案代號 seek)+ 專案簡稱顯示欄- 下方說明區新增 Row 4:專案簡稱
變更
Model/Source/N.GeneralLedger/ISliymSource.cs:interface 新增string 專案代號a { get; set; }
Model/Source/N.GeneralLedger/ISliySource.cs:interface 新增string 專案代號 { get; set; }與string 專案簡稱 { get; set; }
SliyVirtual建構子:
- 給
detailListenerHelper掛上OnAddListener事件- 新增
masterListenerHelper(監聽ISliymSource.專案代號a)並呼叫MasterData.AddListener()SliyVirtual.ReceiveWeakEvent():增加sender is T && PropertyName == 專案代號a分支,觸發CascadeProjectToAllDetails()
刪除
無
Breaking Changes
ISliymSource/ISliySource介面擴增屬性:所有實作這兩個介面的類別必須有對應屬性。本次掃過的所有實作(Twork_acc_vw_sliymSource、Twork_acc_vw_budgetmSource、Twork_acc_vw_sliySource、Twork_acc_vw_budgetSource、Twork_acc_vw_sliyyearSource、Twork_acc_vw_sliyyearmSource、Sliy1Source)皆已有或補上對應屬性。外部專案若有自寫實作需自行調整
Migration Notes
無 schema 變更;DB 端的
專案代號欄位本來就存在於 detail 表,本次只是把主表的值同步進去。既有資料不受影響。對使用者的影響
- Sliy:
- 主表輸入或修改「專案代號」後,所有明細列的「專案代號 / 專案簡稱」立即被覆蓋為 master 同值(包含使用者自行調整過的列)。如需明細列各自設定不同專案,請在 master 設好後再個別調整明細
- 下方說明區點選明細列後可看到該列的「專案簡稱」
- Budget:
- 同 Sliy 行為
- 明細表 grid 多出兩欄「專案代號 / 專案簡稱」(先前 Budget grid 沒有露出這兩欄)
- 載入既有傳票時不會觸發 cascade(僅在 Add / Edit 狀態下觸發),不會造成回歸
-
05-24 btn-styles-unify ▸
2026-05-24 — 操作按鈕 Style 統一基準
摘要
TsControl/Themes/Generic.xaml內 6 個TsButtonStyle(BtnSave / BtnReturn / BtnTurn / BtnConfirm / BtnCancel / BtnExit)統一視覺基準與內容寫法,並把唯一漏掉多語系的BtnConfirm文字改成 DisplayMeta 綁定。變更
- 共通基準:6 個按鈕全部對齊
Height="40"+HorizontalContentAlignment="Left"
-
BtnSave補上HorizontalContentAlignment="Left"-
BtnTurn補上Height="40"與HorizontalContentAlignment="Left",移除 Image / TsTextBlock 多餘的HorizontalAlignment="Center"- 內容寫法統一改用
ContentTemplate:BtnConfirm/BtnCancel/BtnExit原本用<Setter Property="Content">直接內嵌StackPanel,已改成ContentTemplate+DataTemplate,避免同一個 UI 元件實例被多顆按鈕共用而觸發 WPF「元件不可有多重父容器」例外
BtnConfirm文字多語系化:Text="Confirm"改為Text="{Binding ElementName=View, Path=DataContext.DisplayMeta[Confirm], FallbackValue=Confirm}"
Migration Notes
- 若有專案資源覆寫
BtnConfirm的 Content Template,請改寫成ContentTemplate
Common/Lang/Xaml/與TsERP/Lang/Xaml1/Xaml.json需確認Confirmkey 已存在(既有其他按鈕已用,理論上已有)
影響檔案
TsControl/Themes/Generic.xaml
未處理(後續)
BtnConfirm圖示目前是返回00.png(與 BtnReturn 同),疑似 copy-paste 錯誤;本次依使用者指示先不動
- 共通基準:6 個按鈕全部對齊
-
05-24 bankflow-chart-fixes ▸
2026-05-24 — Bankflow 全部銀行帳戶折線圖顯示修正
摘要
修正 2026-05-22 加入的「全部銀行帳戶」折線圖三個顯示問題:X 軸日期重複擠在一起、X 軸標籤重疊、Y 軸出現科學記號。
變更
ViewModel/O.Check/BankflowViewModel.cs
-
Bankflow03Chart改為依「日期」分組後取每組Last():Bankflow03是 running balance,同一天多筆交易會在同一個 X category 上重疊;只取每日最後一筆即當日收盤結餘。TsERP/O.CAandCL/Bankflow.xaml
-
CategoricalAxis加LabelInterval="5"+MajorTickInterval="5",搭配既有的LabelFitMode="Rotate",避免標籤密集重疊。-
LinearAxis加LabelFormat="{}{0:N0}",Y 軸金額顯示千分位整數,停用科學記號(如1.23E+6)。Breaking Changes
無。
Bankflow03Chart是純讀取屬性,呼叫端只有 XAML chart binding;分組後資料筆數變少但 schema 不變。Migration Notes
無 DB / 設定遷移。重新 build TsERP 即生效。
相關
- [[Changelog 2026-05-22 — Bankflow Baseline + Chart]](2026-05-22-bankflow-baseline-chart.md)(原始功能)
- [[ADR 0021 — Bankflow chart 採用 Telerik RadCartesianChart]](../decisions/0021-bankflow-chart-telerik.md)
-
05-24 asset-accexp-workflow-fields ▸
2026-05-24 — 固定資產 asset / accexp 加工作流程欄位 + view 同步
摘要
固定資產模組(
Q.FixedAsset)的asset(財產主檔)與accexp(費用主檔)兩張表統一加入工作流程簽核 6 欄(建檔日期/聯絡單id/工作流程/審核人員/審核日期/已審核),讓固定資產主檔也能掛上簽核流程,並同步更新vw_asset/vw_accexpview 加入新欄位。延續 [[2026-05-22-cheque-system-workflow-fields]] 票據系統的相同 pattern。新增
asset/accexp各新增以下 6 欄(搭配 Source/Model 已有對應屬性):
-
[建檔日期] char(10) NOT NULL DEFAULT ''-
[聯絡單id] int NOT NULL DEFAULT 0-
[工作流程] varchar(6) NOT NULL DEFAULT ''-
[審核人員] nvarchar(20) NOT NULL DEFAULT ''-
[審核日期] varchar(10) NOT NULL DEFAULT ''-
[已審核] char(1) NOT NULL DEFAULT ''變更
vw_assetview 重建,SELECT 清單末端加入建檔日期/聯絡單id/工作流程/審核人員/審核日期/已審核
vw_accexpview 重建,SELECT 清單末端加入相同 6 欄
- 兩個 view 重建後執行
sp_refreshview刷新中介資料
刪除
- 無
Breaking Changes
- 無。所有新欄位
NOT NULL DEFAULT,既有 row 直接補預設值
Migration Notes
SQL Server 端必跑 — 升級資料庫到本 commit 前先執行以下 script:
ALTER TABLE accexp add [建檔日期] [char](10) NOT NULL DEFAULT ''; ALTER TABLE accexp add [聯絡單id] [int] NOT NULL DEFAULT 0; ALTER TABLE accexp add [工作流程] [varchar](6) NOT NULL DEFAULT ''; ALTER TABLE accexp add [審核人員] [nvarchar](20) NOT NULL DEFAULT ''; ALTER TABLE accexp add [審核日期] [varchar](10) NOT NULL DEFAULT ''; ALTER TABLE accexp add [已審核] [char](1) NOT NULL DEFAULT ''; ALTER TABLE asset add [建檔日期] [char](10) NOT NULL DEFAULT ''; ALTER TABLE asset add [聯絡單id] [int] NOT NULL DEFAULT 0; ALTER TABLE asset add [工作流程] [varchar](6) NOT NULL DEFAULT ''; ALTER TABLE asset add [審核人員] [nvarchar](20) NOT NULL DEFAULT ''; ALTER TABLE asset add [審核日期] [varchar](10) NOT NULL DEFAULT ''; ALTER TABLE asset add [已審核] [char](1) NOT NULL DEFAULT ''; go ALTER VIEW [dbo].[vw_asset] AS SELECT dbo.asset.財產編號, dbo.asset.資產別, dbo.asset.財產名稱, dbo.asset.財產分類碼, dbo.asset.廠商代號, dbo.spdata.廠商簡稱, dbo.asset.廠牌, dbo.asset.規格, dbo.asset.單位, dbo.asset.部門代號, dbo.asset.數量, dbo.asset.取得日期, dbo.asset.取得原價, dbo.asset.改良成本, dbo.asset.預留殘值, dbo.asset.現有狀況碼, dbo.asset.年限, dbo.asset.備註, dbo.asset.資產減科目, dbo.asset.費用科目, dbo.asset.處分日期, dbo.asset.再提年限, dbo.asset.處分金額, dbo.asset.再提殘值, dbo.asset.輸入日期, dbo.asset.輸入人員, dbo.asset.輸入地點, dbo.asset.增刪修, dbo.asset.選擇, dbo.asset.管制碼, dbo.asset.srvdbid, dbo.asset.pkid, dbo.asset.logid, dbo.asset.linkid, dbo.dept.部門簡稱, dbo.asset.保固年限, dbo.asset.原始金額, dbo.asset.附加費用, dbo.vwcmb223_財產分類.field2 AS 財產分類, dbo.vwcmb224_現有狀況.field2 AS 現有狀況, dbo.asset.傳票號碼, dbo.asset.財務單號, dbo.asset.置放地點, dbo.asset.建檔日期, dbo.asset.聯絡單id, dbo.asset.工作流程, dbo.asset.審核人員, dbo.asset.審核日期, dbo.asset.已審核 FROM dbo.asset LEFT OUTER JOIN dbo.dept ON dbo.asset.部門代號 = dbo.dept.部門代號 LEFT OUTER JOIN dbo.spdata ON dbo.asset.廠商代號 = dbo.spdata.廠商代號 LEFT OUTER JOIN dbo.vwcmb223_財產分類 ON dbo.asset.財產分類碼 = dbo.vwcmb223_財產分類.field1 LEFT OUTER JOIN dbo.vwcmb224_現有狀況 ON dbo.asset.現有狀況碼 = dbo.vwcmb224_現有狀況.field1 GO ALTER VIEW [dbo].[vw_accexp] AS SELECT dbo.accexp.費用編號, dbo.accexp.費用類別碼, dbo.vwcmb226_費用類別.field2 AS 費用類別, dbo.accexp.費用名稱, dbo.accexp.製單日期, dbo.accexp.廠商代號, dbo.accexp.保單號碼, dbo.accexp.費用起始日, dbo.accexp.費用截止日, dbo.accexp.費用金額, dbo.accexp.資產科目, dbo.accexp.費用科目1, dbo.accexp.費用科目2, dbo.accexp.費用科目3, dbo.accexp.費用科目4, dbo.accexp.百分比1, dbo.accexp.百分比2, dbo.accexp.百分比3, dbo.accexp.百分比4, dbo.accexp.備註, dbo.accexp.輸入日期, dbo.accexp.輸入人員, dbo.accexp.輸入地點, dbo.accexp.增刪修, dbo.accexp.選擇, dbo.accexp.管制碼, dbo.accexp.srvdbid, dbo.accexp.pkid, dbo.accexp.logid, dbo.accexp.linkid, dbo.spdata.廠商簡稱, dbo.accexp.財務單pkid, dbo.accexp.傳票號碼, dbo.accexp.財務單號, dbo.accexp.部門代號, dbo.dept.部門簡稱, dbo.accexp.建檔日期, dbo.accexp.聯絡單id, dbo.accexp.工作流程, dbo.accexp.審核人員, dbo.accexp.審核日期, dbo.accexp.已審核 FROM dbo.accexp LEFT OUTER JOIN dbo.dept ON dbo.accexp.部門代號 = dbo.dept.部門代號 LEFT OUTER JOIN dbo.spdata ON dbo.accexp.廠商代號 = dbo.spdata.廠商代號 LEFT OUTER JOIN dbo.vwcmb226_費用類別 ON dbo.accexp.費用類別碼 = dbo.vwcmb226_費用類別.field1 GO EXEC sp_refreshview 'vw_accexp' EXEC sp_refreshview 'vw_asset'對使用者的影響
- 固定資產主檔(
asset)與費用主檔(accexp)開始支援工作流程簽核欄位(DB 端已備齊;UI 是否暴露簽核控制依 XAML / ViewModel 設定,搭配本次TsERP/Q.FixedAsset/Accexp.xaml調整)
vw_asset/vw_accexpview 多了 6 個欄位,下游 browse / 報表若需顯示審核狀態可直接取用
-
05-23 checkpay-checkrec-single-column-layout ▸
2026-05-23 — Bank / Checkpay / Checkrec 改 GroupBox 分區版型
摘要
銀行帳戶(
Bank.xaml)、應付票據(Checkpay.xaml)、應收票據(Checkrec.xaml)三個 Master 編輯區統一改成「外層 2 欄、每欄一個 StackPanel 堆 GroupBox」的版型,把欄位依語意分組(基本資料 / 交易資訊 / 金額匯率 / 票況 / 其他 …)。每個 GroupBox 內部維持 2 欄 Grid(label / 輸入),每組欄位各佔一個Grid.Row。先前版本把多組獨立欄位塞進同一個StackPanel(例如 Bank 的「帳戶代號 + 帳戶簡稱 + 日報表」「支票字軌 + 票號長度 + 票據號碼」、Checkpay 的「票據單號 + 公司代碼」、Checkrec 的「禁止轉讓 + 平行線」「票況 + 異動日期」),造成欄位上下對不齊、巢狀子元素還掛著無效的Grid.Row/Grid.Column屬性,這次一併清掉。變更
TsERP/O.CAandCL/Bank.xaml
- 左欄 GroupBox「基本資料 / 支票設定」、右欄 GroupBox「銀行資訊 / 會計科目 / 其他」
TsERP/O.CAandCL/Checkpay.xaml
- 第一個 tab(應付票據):左欄 GroupBox「基本資料 / 金額匯率」、右欄 GroupBox「交易資訊 / 票況 / 其他」
- 第二個 tab(LC):左欄 GroupBox「基本資料 / 日期」、右欄 GroupBox「金額匯率 / 還款利息 / 其他 / 保險」
- 修正
Orientation=" Horizontal"多空白的小瑕疵TsERP/O.CAandCL/Checkrec.xaml
- 左欄 GroupBox「基本資料 / 金額匯率」、右欄 GroupBox「開票資訊 / 票況 / 其他資訊」
- 統一帳戶代號欄位的 Margin / VerticalAlignment 風格
新增
- 無
刪除
- StackPanel 子元素上殘留的無效
Grid.Row/Grid.Column屬性
Breaking Changes
- 無。純 XAML 排版調整,未動 binding 路徑、未動
x:Name、未動 code-behind
Migration Notes
- 無需 DB / 設定遷移
對使用者的影響
- 應付票據、應收票據新增 / 編輯畫面的欄位排列依語意分區,GroupBox 標題能一眼看出該區欄位的用途(基本資料、金額匯率、票況…)
- 外層左右兩欄擺放 GroupBox,整體高度比單欄全部上下堆疊版本矮,較符合一般螢幕長寬比
DisplayMeta 多語系待補
各 GroupBox 標題以下 key 走 DisplayMeta,目前 fallback 為中文,正式上線前請在
Common/Lang/Xaml/與TsERP/Lang/Xaml1/Xaml.json補對應 JSON:基本資料、交易資訊、金額匯率、票況、其他、日期、還款利息、保險、開票資訊、其他資訊、支票設定、銀行資訊、會計科目
-
05-22 perdata-other-multi-row ▸
2026-05-22 — Perdata「眷屬資料」改為多筆 + perdata_d 序號 schema 兩位前綴
摘要
人事資料(PERDATA)的「眷屬資料」(原 Other)從單組固定欄位 key-value 表單改成多筆同 schema 表格,跟眷屬與聯絡人 / 學歷 / 任職經歷一致。同時把
perdata_d.序號的區塊前綴從一位數統一成兩位數。變更
UI / Storage 行為改變
- 「眷屬資料」grid 從 3 欄寫死(序號 / 標題 / 內容)→ 動態欄位(眷屬稱謂 / 眷屬姓名 / 眷屬出生 / 眷屬職業 / 身份證號 / 眷屬關係),一個員工可以填多筆眷屬
- 右鍵選單支援「新增數筆」(每次補 10 列空白)
- 儲存進
perdata_d的格式從「同 序號='2'、不同 欄位 共 6 筆」→「每一列拆 6 筆,序號 = '02' + 列序號 (如 '0201'/'0202')」
程式碼
ViewModel/R.HumanResource/PerdataViewModel.cs
-
Other屬性型別:List<其他資料Poco>→DataTable- 新增
otherRelatives(List<TsTemplateRelative>) +OtherAdder(IDataGridAdd)-
otherSturcuture建構移除false參數 → 走預設加IsVirtualEmpty/NeedDelete/序號系統欄-
AfterAddNew/EditBll_OnAfterEdit/AfterMoverRecord/SaveBll_OnBeforeAllowSave改成 DataTable 模式(跟其他三個一致)LogicBll/Ade/R.HumanResource/PerdataSave.cs
-
Other屬性型別:List<其他資料Poco>→TemplateDynamicDataGridPoco-
HandleDataBeforeEndEdit改用Action<T>版的Transfer,把detail.AddItem作為 callback 傳入(直接傳detail.ObservableCollection會炸Collection is read-only,因為它是ReadOnlyObservableCollection<T>)- 同步把其他三個 prefix 補 0:
"1"→"01"、"3"→"03"、"4"→"04",跟 [[2026-05-21-perdata-add-multiple-rows]] 內AfterMoverRecord已改成的兩位數StartsWith對齊- 刪除
OtherHandleprivate method 與其他資料PococlassCommon/Model/Vwseek_datatpl.cs
-
TemplateDynamicDataGridPoco.Transfer加Action<T>版 overload;舊IList<T>版改成委派到新版(呼叫detail.Add)。新版讓呼叫端能傳IDataManager.AddItem避開 ReadOnly Collection 問題- 同個 bug 也存在於
SpdataSave(傳ObservableCollection給Transfer),本次未修,視情況另外處理TsERP/R.HumanResource/Perdata.xaml
-
DgOther移除寫死的 3 個 Columns;加DataGridAdd="{Binding OtherAdder}"、ItemsSource="{Binding Other.DefaultView}"TsERP/R.HumanResource/Perdata.xaml.cs
-
Perdata_OnLoaded加new DataGridCreator(Context, "perdata", "P1", "P1_2").SetDataGridColumn(DgOther);Breaking Changes
perdata_d.序號schema 從一位前綴變兩位前綴,沒有遷移會讀不到舊資料:區塊 舊 schema 新 schema 眷屬與聯絡人 1XX01XX眷屬資料 (Other) 2(固定,6 筆同序號)02XX學歷 3XX03XX任職經歷 4XX04XXMigration Notes
對每個目標 DB 執行以下 SQL。先 備份
perdata_d整表再跑。-- 1. Contact / Education / WorkExperience:1XX / 3XX / 4XX → 0XXX (補 0 前綴) UPDATE perdata_d SET 序號 = '0' + RTRIM(序號) WHERE LEFT(RTRIM(序號), 1) IN ('1', '3', '4') AND LEN(RTRIM(序號)) BETWEEN 2 AND 3; -- 2. Other 那組:原本固定 序號='2',每個 perdata master 只有一組 6 筆 → 改成 '0201'(合併成第 1 列) UPDATE perdata_d SET 序號 = '0201' WHERE RTRIM(序號) = '2'; GO注意事項
- 程式讀回時
GetDataTableAndRelatives用序號當 group key,舊 6 筆 ('0201') 會 lookup 成同 1 個 DataRow,UI 自然顯示為「眷屬資料第 1 列已填」。後續使用者新增列從'0202'開始遞增
- 若
perdata_d.序號為char(N)固定長度,RTRIM處理尾端空白後比對應該安全;若為varchar則直接序號 IN ('1', '2', ...)也可
- migration 前先
SELECT 序號, COUNT(*) FROM perdata_d GROUP BY 序號 ORDER BY 序號確認資料現況,再決定 WHERE 條件邊界
相關
- [[2026-05-21-perdata-add-multiple-rows]] — 上一輪先把 Contacts/Education/WorkExperience 接「新增數筆」 + 修 DataTable binding error
-
05-22 inventquery-tab-column-fix ▸
2026-05-22 — InventQuery 切換 tab 後預設 column 殘留修復
摘要
InventQuery系列(客戶報價/訂單/出貨、廠商報價/採購/收貨/工單、Trwkma 等)放在TsTabControl內。原本切走 tab 再切回來時,已經 AutoGenerate 出的真實資料 column 會被「沒 binding 的預設 header column」蓋掉。改完後切回 tab 維持查詢結果的 column。根因
TsTabControl.ContentTemplate每次切換都會重建InventQuery控件樹 → 連帶重建TsBrowseRadGridView。原本「是否已生成預設 column」的旗標isGenerateDefaultColumnHeader是 grid 控件 instance 的 field,跨重建會 reset;但Schemas(在 ViewModel)保留 → 切回時OnSchemasChanged又跑GenerateDefaultColumnHeader,把預設 header-only column 加回來。新增
ViewModel.Control.TsBrowseDataGridViewModel.IsAutoGenerated屬性
- 跨 grid 控件生命週期存活(ViewModel 不會被 tab 切換重建)
-
CreateDataView()結尾設true-
SetNull()重置為false變更
TsControl/TsTelerik/TsBrowseRadGridView.cs
-
OnSchemasChanged開頭加判斷:若DataContext is TsBrowseDataGridViewModel { IsAutoGenerated: true }→ 直接 return,不再呼叫GenerateDefaultColumnHeaderViewModel/Control/TsBrowseDataGridViewModel.cs
-
CreateDataView()末尾追加IsAutoGenerated = true-
SetNull()末尾追加IsAutoGenerated = false刪除
無。
Breaking Changes
無。
IsAutoGenerated是新屬性,預設false→ 第一次查詢前的行為與舊版一致。Migration Notes
無 DB / 設定遷移。重新 build TsERP 即生效。
影響範圍
所有使用
TsBrowseRadGridView+TsBrowseDataGridViewModel+ 動態 Schemas 的查詢頁面。InventQuery系列受惠最大,其他用同一機制的 browse-grid 也順帶修復同類型潛在問題。驗收
1. 進
Invent_bs(或任何掛 InventQuery 的程式)2. 在第一個 tab 按查詢 → 看到真實資料 column
3. 切到第二個 tab → 切回第一個 tab
4. 預期:column 仍是真實資料 column(不是 header-only 預設 column)
-
05-22 cheque-system-workflow-fields ▸
2026-05-22 — 票據系統 7 張表加工作流程欄位 + bank 加票據號碼
摘要
票據系統相關 7 張表(
bank/checkpay/checkrec/bankfcst/bankfxrm/spbank)統一加入工作流程簽核欄位(建檔日期/聯絡單id/工作流程/審核人員/審核日期/已審核),讓票據主檔也能掛上簽核流程。bank表另外補上票據號碼欄位。同時修正_sheetno內BANKFXR單據別的子表 view 名稱為vw_bankfxrd。新增
- 7 張票據相關表新增以下 6 欄(搭配 Source/Model 已有對應屬性):
-
[建檔日期] char(10) NOT NULL DEFAULT ''-
[聯絡單id] int NOT NULL DEFAULT 0-
[工作流程] varchar(6) NOT NULL DEFAULT ''-
[審核人員] nvarchar(20) NOT NULL DEFAULT ''-
[審核日期] varchar(10) NOT NULL DEFAULT ''-
[已審核] char(1) NOT NULL DEFAULT ''bank表額外新增[票據號碼] nvarchar(40) NOT NULL DEFAULT ''
變更
_sheetno內單據別 = 'BANKFXR'的子表1view從原值更新為vw_bankfxrd,配合新版Twork_chk_vw_bankfxrdview 命名
刪除
- 無
Breaking Changes
- 無。所有新欄位
NOT NULL DEFAULT,既有 row 直接補預設值
Migration Notes
SQL Server 端必跑 — 升級資料庫到本 commit 前先執行以下 script:
update _sheetno set 子表1view ='vw_bankfxrd' where 單據別 = 'BANKFXR' ALTER TABLE bank add [票據號碼] [nvarchar](40) NOT NULL DEFAULT ''; ALTER TABLE bank add [建檔日期] [char](10) NOT NULL DEFAULT ''; ALTER TABLE bank add [聯絡單id] [int] NOT NULL DEFAULT 0; ALTER TABLE bank add [工作流程] [varchar](6) NOT NULL DEFAULT ''; ALTER TABLE bank add [審核人員] [nvarchar](20) NOT NULL DEFAULT ''; ALTER TABLE bank add [審核日期] [varchar](10) NOT NULL DEFAULT ''; ALTER TABLE bank add [已審核] [char](1) NOT NULL DEFAULT ''; ALTER TABLE checkpay add [建檔日期] [char](10) NOT NULL DEFAULT ''; ALTER TABLE checkpay add [聯絡單id] [int] NOT NULL DEFAULT 0; ALTER TABLE checkpay add [工作流程] [varchar](6) NOT NULL DEFAULT ''; ALTER TABLE checkpay add [審核人員] [nvarchar](20) NOT NULL DEFAULT ''; ALTER TABLE checkpay add [審核日期] [varchar](10) NOT NULL DEFAULT ''; ALTER TABLE checkpay add [已審核] [char](1) NOT NULL DEFAULT ''; ALTER TABLE checkrec add [建檔日期] [char](10) NOT NULL DEFAULT ''; ALTER TABLE checkrec add [聯絡單id] [int] NOT NULL DEFAULT 0; ALTER TABLE checkrec add [工作流程] [varchar](6) NOT NULL DEFAULT ''; ALTER TABLE checkrec add [審核人員] [nvarchar](20) NOT NULL DEFAULT ''; ALTER TABLE checkrec add [審核日期] [varchar](10) NOT NULL DEFAULT ''; ALTER TABLE checkrec add [已審核] [char](1) NOT NULL DEFAULT ''; ALTER TABLE bankfcst add [建檔日期] [char](10) NOT NULL DEFAULT ''; ALTER TABLE bankfcst add [聯絡單id] [int] NOT NULL DEFAULT 0; ALTER TABLE bankfcst add [工作流程] [varchar](6) NOT NULL DEFAULT ''; ALTER TABLE bankfcst add [審核人員] [nvarchar](20) NOT NULL DEFAULT ''; ALTER TABLE bankfcst add [審核日期] [varchar](10) NOT NULL DEFAULT ''; ALTER TABLE bankfcst add [已審核] [char](1) NOT NULL DEFAULT ''; ALTER TABLE bankfxrm add [建檔日期] [char](10) NOT NULL DEFAULT ''; ALTER TABLE bankfxrm add [聯絡單id] [int] NOT NULL DEFAULT 0; ALTER TABLE bankfxrm add [工作流程] [varchar](6) NOT NULL DEFAULT ''; ALTER TABLE bankfxrm add [審核人員] [nvarchar](20) NOT NULL DEFAULT ''; ALTER TABLE bankfxrm add [審核日期] [varchar](10) NOT NULL DEFAULT ''; ALTER TABLE bankfxrm add [已審核] [char](1) NOT NULL DEFAULT ''; ALTER TABLE spbank add [建檔日期] [char](10) NOT NULL DEFAULT ''; ALTER TABLE spbank add [聯絡單id] [int] NOT NULL DEFAULT 0; ALTER TABLE spbank add [工作流程] [varchar](6) NOT NULL DEFAULT ''; ALTER TABLE spbank add [審核人員] [nvarchar](20) NOT NULL DEFAULT ''; ALTER TABLE spbank add [審核日期] [varchar](10) NOT NULL DEFAULT ''; ALTER TABLE spbank add [已審核] [char](1) NOT NULL DEFAULT '';對使用者的影響
- 票據相關 7 個程式(銀行帳戶、應付/應收票據、預估資金表、銀行日報主檔、廠商帳戶表)開始支援工作流程簽核欄位(DB 端已備齊;UI 是否暴露簽核 UI 依 Source/ViewModel 設定)
bank表(公司銀行帳戶)多了「票據號碼」欄位
- 銀行日報明細的 view 名稱統一為
vw_bankfxrd,相關報表 / browse 設定一致化
-
05-22 bankflow-baseline-chart ▸
2026-05-22 — Bankflow 全部銀行帳戶加結餘趨勢圖 + BaseLine 警示
摘要
Bankflow(資金預估表 O110)的「全部銀行帳戶」分頁加上結餘金額趨勢圖與 BaseLine 警示功能:原本只有純表格,現在右側顯示折線圖、警示線會跟著查詢條件的 BaseLine 即時移動,結餘跌破 BaseLine 的列在 grid 上會自動顯紅底。
新增
- BankflowCondition 的 BaseLine 欄位實際生效:之前只是 UI 上一個 TextBox 沒接後續,現在輸入後會:
1. 第三個 tab 折線圖上畫一條紅色水平警示線
2. 同 tab grid 的列在
結餘金額 < BaseLine時上半透明紅底- 全部銀行帳戶 tab 折線圖:X = 日期、Y = 結餘金額,資料來源
Bankflow03
TsControl/Converter/BankflowBaseLineRowBackgroundConverter.cs:MultiValueConverter,輸入[結餘金額, BaseLine],回 Brush
變更
TsERP/O.CAandCL/Bankflow.xaml
- 加
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"-
TsView.Resources加入 converter 引用- 第三個 tab Grid 加入
RadCartesianChart(Grid.Column=1)-
bankflow03DataGrid加RowStyle(MultiBinding結餘金額+View.DataContext.QueryConditionViewModel.BaseLine)ViewModel/O.Check/BankflowViewModel.cs拿掉舊 LiveCharts 殘留:
- 刪除
UIUpdateoverride、CreateChartmethod- 刪除
Labels、YFormatter屬性、註解掉的SeriesCollection區塊- 對應拿掉
System.Windows.Media、System.Windows.Threading、System.Text、System.Threading.Tasksusing刪除
無外部 API / DB 欄位 / 設定值刪除。
Breaking Changes
無。
BaseLine仍維持在BankflowConditionViewModel的 local field(沒搬進BankflowQueryParameters),未影響任何序列化 / 設定檔。Migration Notes
無 DB / 設定遷移需要。重新 build TsERP 即生效。
相關
- [[ADR 0021 — Bankflow 全部銀行帳戶 tab 折線圖採用 Telerik RadCartesianChart]](../decisions/0021-bankflow-chart-telerik.md)
-
05-21 tserp-info-site ▸
2026-05-21 — 對外資訊網 manual.yanyue.io
摘要
建立對外公開資訊網
manual.yanyue.io(Cloudflare Pages),三頁 + 既有 mkdocs 手冊整合:- 系統地圖:259 個程式扁平單一清單,可搜尋 / 過濾 / 排序
- 修改紀錄:28 篇按月分組
- SQL 更新:4 個 migration(從 changelog
## Migration Notes抽)
- 使用手冊:mkdocs Material build,每頁頂部自動注入「程式資訊」框
詳細決策見 ADR 0020。
新增
docs/
docs/system-map/_subsystems.yml— 18 子系統對照(key + name + 排序 + 短描述 + TsERP / ViewModel / ProgramClass 三端路徑映射)
docs/system-map/README.md— 編輯指南(兩分鐘新增一個程式)
- **
docs/<sub>/*.md× 259** — 系統地圖骨架,bootstrap 自動產出
- 含 YAML frontmatter(id / name / status / features / xaml)
- 含自動產生 body(用途 / 主要欄位 / 操作步驟草稿 / 待確認,全標 ⚠️)
- 14 個 dead-code 候選跳過(見
docs/_scan/follow-ups.md)- 4 個變體標
variant_of:收編tools/release-notes/
工具與腳本:
檔 用途 build.ps1主 build 入口 publish.ps1build + wrangler pages deploybootstrap-system-map.ps1從 snapshot 一次性產 .md 骨架 Fill-Features.ps1從 XAML + VM 抽 features lib/Parse-Frontmatter.ps1YAML + body 解析 lib/Parse-SystemMap.ps1掃 docs/<sub>/*.md lib/Parse-Changelog.ps1掃 changelog lib/Parse-Sql.ps1從 changelog 抽 SQL block lib/Validate-SystemMap.ps1frontmatter 驗證(含 Levenshtein 拼錯建議) lib/Render-Html.ps1markdown → HTML、template token 替換 lib/Preprocess-Docs.ps1注入 metadata admonition 給 mkdocs templates/*.html× 5_layout / index / system-map / changelog / sql public/style.css純 CSS(無 framework) public/search.jsvanilla JS:搜尋 / 排序 / chip filter / URL state / 列展開 變更
docs/_template/feature-template.md— 在最上方補 frontmatter 段(id / name / status / features / xaml 等選填欄位)
.gitignore— 加入docs/_scan/、tools/release-notes/dist/、tools/release-notes/docs-built/、mkdocs-built.yml
刪除
無
Breaking Changes
無 — 純新增,不影響既有 ERP 程式碼、不改 DB、不動 mkdocs nav。
Migration Notes
部署到 manual.yanyue.io(首次)
# 1. 設環境變數 [Environment]::SetEnvironmentVariable('CLOUDFLARE_API_TOKEN', '<token>', 'User') [Environment]::SetEnvironmentVariable('CLOUDFLARE_ACCOUNT_ID', '<account-id>', 'User') # 關 PowerShell 重開 # 2. Build + Deploy cd C:\ERPV2\.claude\worktrees\hungry-brahmagupta-825ce9 pwsh tools\release-notes\publish.ps1publish.ps1 會:
1. 跑 build(驗證 → 解析 → 渲染 → mkdocs build)
2.
wrangler pages project create tserp-info(若不存在)3.
wrangler pages deploy ./dist --project-name=tserp-info首次部署後到 Cloudflare Dashboard → Pages → tserp-info → Custom domains 加
manual.yanyue.io。後續更新
只要編輯
docs/<sub>/*.md、docs/changelog/*.md或docs/system-map/_subsystems.yml,然後重跑publish.ps1即可。環境需求
- PowerShell 7+(pwsh)
- powershell-yaml:
Install-Module powershell-yaml -Scope CurrentUser
- Node.js 20+(wrangler 3 支援)
- mkdocs material:
pip install -r docs/requirements.txt
- Cloudflare API Token(權限 Account → Cloudflare Pages → Edit)
對使用者的影響
- 客戶可在
manual.yanyue.io看到系統有哪些功能、最新變動、要跑哪些 SQL
- 我們維護方式不變(編
docs/<sub>/*.md或docs/changelog/*.md),多了 frontmatter 那段
- depth-C 自動草稿需人工複核(用途 / 操作步驟 / 主要欄位 / 待確認,全部標 ⚠️)
連結
- 掃描原始:
docs/_scan/INDEX.md(gitignored,留本機參考)
- follow-up bug 清單:
docs/_scan/follow-ups.md
- 編輯指南:
docs/system-map/README.md
-
05-21 procno-bom-m-cols ▸
2026-05-21 — procno / bom_m schema 更新 + 人事資料模板種子
摘要
兩組獨立 DB 變動:
1. Schema —
procno(工程代號表)新增 4 個欄位以支援會簽流程與建檔日追蹤;bom_m(BOM 主檔)新增建檔日期欄位。同步更新vw_wkcent、vw_procno、vw_bom_m三個 view 把新欄位納入查詢結果。2. 種子資料 — 新增人事資料模板
P1(人事明細資料),含 23 筆datatpld欄位定義 + 1 筆datatplm主檔,分 4 個子群組(緊急聯絡人 / 眷屬資料 / 學歷 / 任職經歷)。變更
Schema
procno:新增 4 個欄位
-
建檔日期char(10)NOT NULL DEFAULT ''-
聯絡單idintNOT NULL DEFAULT 0-
工作流程varchar(6)NOT NULL DEFAULT ''-
已審核char(1)NOT NULL DEFAULT ''bom_m:新增 1 個欄位
-
建檔日期char(10)NOT NULL DEFAULT ''vw_wkcent:SELECT 補入聯絡單id、工作流程、審核人員、審核日期、已審核、建檔日期
vw_procno:SELECT 補入建檔日期、聯絡單id、工作流程、已審核
vw_bom_m:SELECT 補入建檔日期
種子資料
datatplm/datatpld:新增人事資料模板P1(人事明細資料)
-
P1_1_B_緊急聯絡人:4 欄位(緊急聯絡人 / 緊急關係 / 緊急電話 / 緊急地址)-
P1_2_B_眷屬資料:6 欄位(眷屬稱謂 / 眷屬姓名 / 眷屬出生 / 眷屬職業 / 身份證號 / 眷屬關係)-
P1_3_B_學歷:6 欄位(學校名稱 / 院系科別 / 修業年月起 / 修業年月迄 / 是否畢業 / 學位)-
P1_4_B_任職經歷:7 欄位(原任職公司 / 原部門 / 原任職日期 / 原離職日期 / 原待遇 / 原工作內容 / 原離職原因)Migration Notes
對每個目標 DB 依序執行以下兩段 SQL。
1. 加欄位
ALTER TABLE procno ADD [建檔日期] [char](10) NOT NULL DEFAULT ''; ALTER TABLE procno ADD [聯絡單id] [int] NOT NULL DEFAULT 0; ALTER TABLE procno ADD [工作流程] [varchar](6) NOT NULL DEFAULT ''; ALTER TABLE procno ADD [已審核] [char](1) NOT NULL DEFAULT ''; ALTER TABLE bom_m ADD [建檔日期] [char](10) NOT NULL DEFAULT ''; GO2. 更新 view 定義
ALTER VIEW [dbo].[vw_wkcent] AS SELECT dbo.wkcent.中心群組, dbo.wkcent.中心代號, dbo.wkcent.中心說明, dbo.wkcent.報價費率, dbo.wkcent.產能, dbo.wkcent.人工費率, dbo.wkcent.間接費比例, dbo.wkcent.每週天數, dbo.wkcent.部門代號, dbo.wkcent.輸入日期, dbo.wkcent.輸入人員, dbo.wkcent.輸入地點, dbo.wkcent.增刪修, dbo.wkcent.選擇, dbo.wkcent.管制碼, dbo.wkcent.srvdbid, dbo.wkcent.pkid, dbo.wkcent.logid, dbo.wkcent.linkid, ISNULL(dbo.vwseek_grpm1.說明, N'') AS 說明, ISNULL(dbo.dept.部門簡稱, N'') AS 部門簡稱, dbo.wkcent.聯絡單id, dbo.wkcent.工作流程, dbo.wkcent.審核人員, dbo.wkcent.審核日期, dbo.wkcent.已審核, dbo.wkcent.建檔日期 FROM dbo.wkcent LEFT OUTER JOIN dbo.vwseek_grpm1 ON dbo.wkcent.中心群組 = dbo.vwseek_grpm1.群組代號 LEFT OUTER JOIN dbo.dept ON dbo.wkcent.部門代號 = dbo.dept.部門代號; GOALTER VIEW [dbo].[vw_procno] AS SELECT dbo.procno.工程代號, dbo.procno.工程簡稱, dbo.procno.報價簡稱, dbo.procno.工程說明, dbo.procno.中心群組, dbo.procno.重要度, dbo.procno.重要項目, dbo.procno.圖檔名稱, dbo.procno.製造規格, dbo.procno.檢驗規格, dbo.procno.審核人員, dbo.procno.審核日期, dbo.procno.損耗率, dbo.procno.輸入日期, dbo.procno.輸入人員, dbo.procno.輸入地點, dbo.procno.增刪修, dbo.procno.選擇, dbo.procno.管制碼, dbo.procno.srvdbid, dbo.procno.pkid, dbo.procno.logid, dbo.procno.linkid, dbo.vwseek_grpm1.說明, dbo.procno.建檔日期, dbo.procno.聯絡單id, dbo.procno.工作流程, dbo.procno.已審核 FROM dbo.procno LEFT OUTER JOIN dbo.vwseek_grpm1 ON dbo.procno.中心群組 = dbo.vwseek_grpm1.群組代號; GOALTER VIEW [dbo].[vw_bom_m] AS SELECT dbo.bom_m.組件編號, dbo.vwseek_invent.品名, dbo.vwseek_invent.品別, dbo.vwseek_invent.停用說明, dbo.vwseek_invent.設變編號, dbo.vwseek_invent.設變資料, dbo.bom_m.機種別, dbo.bom_m.銷售地區, dbo.bom_m.客戶, dbo.bom_m.生產轉入倉, dbo.bom_m.流程樣板號, dbo.bom_m.聯絡單id, dbo.bom_m.工作流程, dbo.bom_m.審核人員, dbo.bom_m.審核日期, dbo.bom_m.已審核, dbo.bom_m.輸入日期, dbo.bom_m.輸入人員, dbo.bom_m.輸入地點, dbo.bom_m.增刪修, dbo.bom_m.選擇, dbo.bom_m.管制碼, dbo.bom_m.srvdbid, dbo.bom_m.pkid, dbo.bom_m.logid, dbo.bom_m.linkid, dbo.vwseek_invent.零件編號, dbo.bom_m.建檔日期 FROM dbo.bom_m LEFT OUTER JOIN dbo.vwseek_invent ON dbo.bom_m.組件編號 = dbo.vwseek_invent.品號; GO執行順序:先加欄位再更新 view,避免 view 引用未存在欄位失敗。
3. 人事資料模板種子(datatpld + datatplm)
跑過會在
datatplm留一筆P1主檔、datatpld留 23 筆欄位定義。若目標 DB 已有相同 pkid 會衝突,視情況決定是否先 DELETE。INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'1 ', N'原任職公司 ', N'C', 30, 0, N'服務機關名稱', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_4_B_任職經歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 1, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'2 ', N'原部門 ', N'C', 30, 0, N'部門/職稱', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_4_B_任職經歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 2, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'3 ', N'原任職日期 ', N'C', 10, 0, N'到職日', N'9999/99/99', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_4_B_任職經歷', CAST(N'2019-04-18T17:18:41.633' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 3, 215195, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'4 ', N'原離職日期 ', N'C', 10, 0, N'離職日', N'9999/99/99', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_4_B_任職經歷', CAST(N'2019-04-18T17:18:41.633' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 4, 215195, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'5 ', N'原待遇 ', N'N', 18, 6, N'薪資(月)', N'999,999,999', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_4_B_任職經歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 5, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'6 ', N'原工作內容 ', N'C', 80, 0, N'主要工作', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_4_B_任職經歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 6, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'7 ', N'原離職原因 ', N'C', 80, 0, N'離職原因', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_4_B_任職經歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 7, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'8 ', N'學校名稱 ', N'C', 30, 0, N'學校名稱', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_3_B_學歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 8, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'9 ', N'院系科別 ', N'C', 30, 0, N'院系科別', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_3_B_學歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 9, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'10 ', N'修業年月起 ', N'C', 7, 0, N'修業起始年月', N'9999/99', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_3_B_學歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 10, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'11 ', N'修業年月迄 ', N'C', 7, 0, N'修業結束年月', N'9999/99', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_3_B_學歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 11, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'12 ', N'是否畢業 ', N'C', 1, 0, N'畢/肄', N'Y', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_3_B_學歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 12, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'13 ', N'學位 ', N'C', 30, 0, N'學位', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_3_B_學歷', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 13, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'14 ', N'眷屬稱謂 ', N'C', 10, 0, N'稱謂', N'XXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_2_B_眷屬資料', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 14, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'15 ', N'眷屬姓名 ', N'C', 10, 0, N'姓名', N'XXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_2_B_眷屬資料', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 15, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'16 ', N'眷屬出生 ', N'C', 10, 0, N'出生日期', N'9999/99/99', N'CHKDATE', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_2_B_眷屬資料', CAST(N'2014-06-09T00:04:00.727' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 16, 64740, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'17 ', N'眷屬職業 ', N'C', 20, 0, N'職業', N'XXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_2_B_眷屬資料', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 17, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'18 ', N'緊急聯絡人 ', N'C', 20, 0, N'姓名', N'XXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_1_B_緊急聯絡人', CAST(N'2022-10-13T17:20:14.240' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 18, 526961, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'19 ', N'緊急關係 ', N'C', 10, 0, N'關係', N'XXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_1_B_緊急聯絡人', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 19, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'20 ', N'緊急電話 ', N'C', 20, 0, N'電話', N'XXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_1_B_緊急聯絡人', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 20, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'21 ', N'緊急地址 ', N'C', 80, 0, N'地址', N'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_1_B_緊急聯絡人', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 21, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'48 ', N'身份證號 ', N'C', 14, 0, N'身份證號', N'XXXXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_2_B_眷屬資料', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 55, 64734, 3); GO INSERT [dbo].[datatpld] ([序號], [欄位], [資料型態], [長度], [小數位數], [標題], [輸入遮罩], [valid方法], [公式], [參照資料], [輸入方式], [輸入內容], [允許輸入], [搜尋方式], [權限], [備註], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'49 ', N'眷屬關係 ', N'C', 10, 0, N'眷屬關係', N'XXXXXXXXXX', N'', N'', N'', N'SQLTEXT ', N'', N' ', N'', N'', N'P1_2_B_眷屬資料', CAST(N'2014-06-08T23:59:14.177' AS DateTime), N'Gary', N'CMSA-SERVER # cmsa', N' ', N' ', 0, 1, 56, 64734, 3); GO INSERT [dbo].[datatplm] ([資料模板號], [說明], [輸入日期], [輸入人員], [輸入地點], [增刪修], [選擇], [管制碼], [srvdbid], [pkid], [logid], [linkid]) VALUES (N'P1 ', N'人事明細資料', CAST(N'2012-10-04T15:32:02.280' AS DateTime), N'令狐沖', N'WXWG101234 # wg101', N' ', N' ', 0, 1, 3, 2109, 0); GO執行順序:schema → view → 種子資料皆獨立,可分批執行。種子資料若已存在會 PK 衝突,需先評估是否清除舊資料。
-
05-21 perdata-add-multiple-rows ▸
2026-05-21 — Perdata 右鍵「新增數筆」支援動態 DataTable detail
摘要
人事資料(PERDATA)的三個動態欄位 grid(眷屬與聯絡人 / 學歷 / 任職經歷)現在支援 RadGridView 右鍵選單的「新增數筆」。每按一次補 10 列空白,序號接著當前最大值往下排。
變更
ViewModel/R.HumanResource/PerdataViewModel.cs
- 新增
ContactsAdder/EducationAdder/WorkExperienceAdder三個IDataGridAdd屬性- 新增私有巢狀類別
CallbackGridAdd,把Action包成IDataGridAdd- 三個 adder 在建構子內建立,呼叫既有的
AddLineNo(dt)對Contacts/Education/WorkExperienceDataTable 加列TsERP/R.HumanResource/Perdata.xaml
-
DgContact、DgEducation、DgWorkExperience各加DataGridAdd="{Binding XxxAdder}"背景
TsRadGridView.AddNewRecordsExecute()有兩條路:DataGridAdd != null → DataGridAdd.AddItem() ← 客製化 detail 否則 → AdeViewModel.AddNewRecord(DataManager, ...) ← ObservableCollection-based detailPerdata 的 detail 不是
DataManager<TSource>+ObservableCollection,而是用TsTemplateDataTable從datatpld動態產欄位後綁DataTable,沒有DataManager可用,必須走DataGridAdd路徑。DgOther是固定的List<其他資料Poco>(沒有「新增更多筆」的概念),不接此功能。不影響
- 不影響原本進入新增 / 編輯模式時預先塞 10 列空白的行為(
AfterAddNew/EditBll_OnAfterEdit)
- 不影響
SaveBll_OnBeforeAllowSave把四個 detail 包成TemplateDynamicDataGridPoco的儲存流程
- 不影響其他模組的
TsRadGridView右鍵選單行為
-
05-18 scx_ord-db-model-sync ▸
2026-05-18 — SCX_ORD DB vs Model/Source 同步
摘要
跑
/db-model-compare SCX_ORD比對資料庫 view/table 欄位與Common/Model/E.Order+Model/Source/E.Order內各 Model/Source 類別,做了三層修補:1. 補 92 個 DB 欄位到 Model/Source(之前 Source 沒包到的中文欄位)
2. 補 64 處
[NotMapped]/[Browsable(false)]標記(Source 端的 UI helper props 沒打標記)3. 砍掉英文 stale 屬性 + caller 改名:原本英文 DB 改成中文 DB 後,部分 Source 還留著綁到不存在英文欄位的舊屬性,這次清掉並把 caller(C# + XAML)改用新中文名
變更
1) Model 補欄位(90 個屬性、18 個檔組)
每個檔組(Model + Source pair)都把 DB view/table 內的中文欄位補進
Common/Model/E.Order/<Name>Model.cs與Model/Source/E.Order/<Name>Source.cs:- Twork_ord_vw_ormast(24 model + 26 source)
- Twork_ord_vw_ordetl(31 + 31)
- Twork_ord_vw_cuqtm(3 + 3)
- Twork_ord_vw_cuinve(5 + 5)
- Twork_ord_vw_cupdt(6 + 6)
- Twork_ord_vw_ci_m(5 + 5)
- Twork_ord_vw_preord_d(4 + 4)
- Twork_ord_vw_cupdma(2 + 2)
- Twork_ord_vw_salema(3 + 3)
- Twork_ord_vw_salede(3 + 3)
- 其他 8 個小檔(cuqtd、pkde、cuinvema、pkma、cudata、cudataspec、preord_m、cuqtd1)共 4 + 4
2) Source 補 NotMapped/Browsable(false) 標記(64 處)
凡是 Source 屬性沒對到 DB 欄位、又沒打
[NotMapped]或[Browsable(false)]標記的(多半是 UI binding helper),都補上:- Twork_ord_vw_ormast(18)
- Twork_ord_vw_ordetl(11)
- Twork_ord_vw_cuqtm(8)
- 其他 17 個檔共 27 處
3) 砍英文 stale 屬性 + caller 改名
Source 端砍掉
Source 砍掉 取代為(已存在) Twork_ord_vw_cuinve QuantityPerCarton包裝量_箱Twork_ord_vw_cuqtd VendorName+_VendorNamefield廠商簡稱Twork_ord_vw_cuqtm VendorName+CustomerName+ 2 backing fields廠商簡稱/客戶簡稱Twork_ord_vw_ordetl ETA,ShippedQuantity預訂交期/已交數量Twork_ord_vw_preord_m CustomerName+_CustomerNamefield客戶簡稱RmamModel + RmamSource SysEntryDate / SysEntryUser / SysEntryMachine / SysRowStatus / SysIsChosen / SysControlCode(6 個英文版重複 ModelBase 中文版的審核欄位)ModelBase 內建 輸入日期 / 輸入人員 / 輸入地點 / 增刪修 / 選擇 / 管制碼判斷依據:
vw_cuinve.QuantityPerCarton、vw_ordetl.ETA / ShippedQuantity由 modeljson 確認舊→新(DB 已有對應中文欄)
CustomerName / VendorName同 Source 內已存在我這批新加入的客戶簡稱 / 廠商簡稱,舊版只是 UI helper、DB 沒有對應英文欄位
- Rmam 系列 6 個審核欄位重複 ModelBase 的 Chinese 版本,砍掉後乾淨繼承
C# caller 改名(10 處 LogicBll + 4 處 ViewModel)
LogicBll/E.Order/Cuqt/CuqtBll.cs:VendorName = ...→廠商簡稱 = ...
LogicBll/E.Order/Odtosl/OdtoslBll.cs、OdtosladdiBll.cs:nameof(ETA)/nameof(ShippedQuantity)→ 中文
LogicBll/Ade/E.Order/OrmastSave.cs、OrmastDelete.cs:d.ShippedQuantity/d.ETA→ 中文
LogicBll/E.Order/Darbedittool/DarbedittoolBll.cs:d.ETA = ...→d.預訂交期 = ...
ViewModel/D.Bom/Invent/Condition/SalesOrderConditionViewModel.cs:query condition string 內nameof(ShippedQuantity)→nameof(已交數量)
ViewModel/E.Order/OrmastStockQueryViewModel.cs:同上
ViewModel/E.Order/OrmastViewModel.cs:o.ETA = ...→o.預訂交期 = ...
ViewModel/E.Order/Ormast_sViewModel.cs:LINQ projection 內a.ETA/a.ShippedQuantity→ 中文
XAML caller 改名(5 檔、13 處)
XAML binding 改名 TsERP/E.Order/Cuinve.xaml {Binding QuantityPerCarton}→{Binding 包裝量_箱}TsERP/E.Order/Cuqt.xaml CustomerName× 2 /VendorName× 3 → 中文(master + grid column)TsERP/E.Order/Ormast.xaml ETA/ShippedQuantitygrid column → 中文TsERP/E.Order/Ormast_US.xaml 同 Ormast 3 處 TsERP/E.Order/Preord.xaml CustomerName× 2 →客戶簡稱工具鏈調整
- 4 個檔(vw_ormast、vw_pkde、vw_cupdt)原本 agent 寫
[TsDecimalPrecision(...)],但專案內只有TsDecimalLengthAttribute,統一改[TsDecimalLength(...)]
Breaking Changes
對「外部 caller / plugin」:
Twork_ord_vw_ordetlSource上沒了ETA、ShippedQuantity屬性,要用預訂交期/已交數量
Twork_ord_vw_cuqtmSource/Twork_ord_vw_cuqtdSource上沒了VendorName、CustomerName,要用廠商簡稱/客戶簡稱
Twork_ord_vw_cuinveSource上沒了QuantityPerCarton,要用包裝量_箱
Twork_ord_vw_preord_mSource上沒了CustomerName,要用客戶簡稱
RmamModel/RmamSource上沒了SysEntryDate / SysEntryUser / SysEntryMachine / SysRowStatus / SysIsChosen / SysControlCode,要透過 ModelBase 繼承的輸入日期/輸入人員等中文版
對使用者的影響
- 原本英文屬性綁的畫面:本次同步後改用中文版,runtime 行為應該等價(畢竟英文版本來就沒接到實際 DB 欄位、值是空的)
- vw_ormast 修活:原本 Source 沒包到
訂單編號 / 訂單別 / 客戶簡稱等核心欄位,畫面上對應欄位都是空的(XAML binding 找不到屬性靜默失敗);本次補上後 grid 該顯示正常
待人工複查 / 還沒清的部分
仍有 ~140 個英文 stale 屬性(多半在 ormast,SHEMAIL / CARDTYPE / AUDIT0X 等 EDI / legacy 欄位)沒清,分類如下:
- NoChange (69):modeljson 說欄位沒重命名,但實際 DB 查不到 → modeljson 過時或欄位廢除
- Orphan (73):modeljson 完全沒記載 → 多半是 ormast 內 EDI / legacy 英文欄位
- Renamed but no DB match (1):vw_ordetl 的
ETD(modeljson 說預計出貨日但 DB 沒此欄)
- SemanticGuess (1):vw_cuqtm 的
GroupDescription同檔沒中文版可配對
這些要等下一輪掃過再決定砍 / 補 / 保留為純 UI 屬性。
Build 狀態
Common.csproj/Model.csproj/ViewModel.csproj/LogicBll.csproj/TsERP.csproj全部 0 CS / 0 MC 錯誤、0 BG1002
連結
- 相關 skill:
.claude/skills/db-model-compare
- modeljson 權威來源:
D:\visualstudio\Generator\類別產生器\類別產生器\bin\Debug\net8.0-windows\modeljson\
-
05-17 tspage-to-tsview-batch ▸
2026-05-17 — TsPage → TsView 大批次遷移 + 拆 SqlEdit wrapper + RadGridView header 寫死中文
摘要
接續本日的 obs-to-datamanager(
fccf4d73)與 dg-to-radgrid(b9473cff)兩個批次,把同一批 52 個畫面遷移到TsView:1. 階段 A:42 個 XAML 從
TsPage改成TsView(含x:Name、ElementName、AncestorType、code-behind base class)2. 階段 B:同 42 個 XAML 移除
SqlEdit/SqlEditInventory外層 wrapper3. 階段 C′:C.GeneralAffair 4 個 XAML 把
RadGridView的Header={Binding DataContext.DisplayMeta[X]}寫死成Header="X",共 29 處4. 順手把 Ppurch.xaml(已 TsView)殘留的 2 處
ElementName=Page修掉剩下 10 個檔(C.GeneralAffair 6 + G.Purchasing Ppurch/Purch/Sppdt + R.HumanResource/Persmems)昨天遷移階段已轉好 TsView,今天不動。
變更
階段 A(42 個 XAML + 42 個 .xaml.cs)
XAML 內每檔做:
<TsControl:TsPage>/</TsControl:TsPage>→TsControl:TsView(含.TsPage.Resources→.TsView.Resources)
x:Name="Page"→x:Name="View"
ElementName=Page→ElementName=View
AncestorType=Page→AncestorType=TsControl:TsView
.xaml.cs內:: TsPage→: TsView。階段 B(42 個 XAML)
刪掉外層 wrapper(單行或多行):
<TsControl:SqlEdit ...>↔</TsControl:SqlEdit>
<TsControl:SqlEditInventory ...>↔</TsControl:SqlEditInventory>(H.Inventory 的 Trlima/Trlost/Trrama/Trsama)
內嵌使用的
TsControl:SqlEditTurn不動。階段 C′(4 個 XAML,29 處 header)
Header="{Binding DataContext.DisplayMeta[X], ElementName=View, FallbackValue=X}"→Header="X":- Ginvent (2 處)
- Gppurch (12 處)
- Gsplace (3 處)
- Gsppdt (12 處)
只動
tsTelerik:TsRadGridView內的 columnHeader;TsLabel/TsTextBlock的Content維持走 DisplayMeta 多語系。Breaking Changes
對「外部 caller / plugin」:
- View 類型從
TsPage(System.Windows.Controls.Page)變成TsView(UserControl)。原本靠 WPF Page navigation 開啟畫面的程式碼會壞,要改成 ContentControl swap(這套專案的 navigation 用 VM + DataTemplate 切換,主流程影響很小)
- code-behind 任何
(TsPage)this.xxx強制轉型會壞,要改TsView
- 外層 SqlEdit 沒了,下游的
BindingData推 DataContext 行為消失;如果有 binding 假設BindingData推下來的 DataContext,要手動補DataContext="{Binding ...}"
對使用者的影響:丟失的屬性
11 個檔失去 `HaveWorkflow="True"`
檔 原本行為 Purchasing/G.Purchasing/VendorDefect.xaml workflow 按鈕 / ADE 編輯狀態切換 Purchasing/G.Purchasing/VendorFillRate.xaml 同上 TsERP/E.Order/Ci.xaml 同上 TsERP/E.Order/Cupdma.xaml 同上 TsERP/E.Order/Pk.xaml 同上 TsERP/E.Order/Preord.xaml 同上 TsERP/F.Production/OutSourcingFillRate.xaml 同上 TsERP/G.Purchasing/VendorDefect.xaml 同上 TsERP/G.Purchasing/VendorEvaluation.xaml 同上 TsERP/G.Purchasing/VendorFillRate.xaml 同上 TsERP/H.Inventory/Trinout.xaml 同上 VM 若沒自行處理,這些頁面會失去 workflow 功能。需要後續補回(可考慮在 VM constructor 設旗標,或在 View 內加上其他 workflow 控制元件)。
其他失去的屬性
- TsERP/D.Bom/Invent_prime.xaml:
FirstRowSpace="25"+PkidVisibility="{Binding PkidVisibility}"
- TsERP/E.Order/Ormast_US.xaml:
FirstRowSpace="25"
FirstRowSpace主要影響表頭第一列的間距,視覺差異;PkidVisibility影響 Pkid 欄是否可見,邏輯影響。Column Header 寫死中文(C′)
C.GeneralAffair 4 檔的 grid header 不再走 DisplayMeta 取多語系,目前只顯示中文。
Common/Lang/Xaml/<檔名>.json內的 key 仍保留供TsLabel/TsTextBlock使用。過程中要修的問題
階段 B 的 worker agent 在 14 個檔(G.Purchasing+J.QC+K.Cost+M.EIS+P.Invoice 共 14 個)把
</TsControl:SqlEdit>替換成</Grid>而不是直接刪除,多出 1 個</Grid>close tag。Build 拋 MC3000 抓到,已用 PowerShell regex 統一拔掉檔尾多餘的</Grid>。Build 狀態
TsERP.csproj:連續 2 次 clean build 都是 0 XAML/CS 錯誤、0 BG1002 cascading
- 沒有看到 MC1000 mscorlib 工具鏈 hiccup(前兩個批次的常見 noise)
待人工複查
1. 11 個失去 HaveWorkflow 的檔:如果原本有用 workflow,要決定怎麼補回(VM 內處理 / View 內加控制 / 跳過)
2. Invent_prime 的
PkidVisibility:Pkid 欄顯隱規則重要,建議加回 VM 控制3. Ormast_US.xaml 的 SqlEdit 內直接子元素是
TsControl:TsTabControl不是Grid。TsView 只能一個直接子元素 — 目前編譯過了,runtime 行為要實測4. 縮排:刪 wrapper 後內層內容多了一層縮排,沒整理。要的話另跑 formatter
連結
- 本日批次:
- obs-to-datamanager:
fccf4d73- dg-to-radgrid + 5 個新 SeekGridViewColumn:
b9473cff- tspage-to-tsview(本檔)
- 範本:
TsERP/N.GeneralLedger/Accl.xaml(Master only)、TsERP/N.GeneralLedger/Sliy.xaml(Master + Detail)
- 相關 skill:
.claude/skills/tspage-to-tsview
-
05-17 obs-to-datamanager-batch ▸
2026-05-17 — ObservableCollection → DataManager 大批次轉換
摘要
把剩餘 67 個 ViewModel 的
ObservableCollection<T> Master/Detail/DetailN全面轉成DataManager<T> MasterData/DetailData/DetailNData,並同步更新對應 XAML 與外部 caller。此前已有 ~30 個 VM 在歷次零散轉換中完成,本次把剩下的全部清掉,達到專案內主資料 binding source 一致統一。順帶修活了多支「XAML 已寫成
{Binding MasterItem}但 VM 沒呼叫 Register、實際畫面空白」的程式(典型範例:Jobcode)。執行流程:分 B1(pilot 1 個)→ B2(單 Master 12 個)→ B3(Master+Detail 30 個)→ B4(3-5 sources 14 個)→ B5(部分轉換 cleanup 10 個含 Splace)。每批跑
dotnet build驗證。變更
ViewModel 層(67 檔,按模組分布)
模組 檔數 代表檔 C.GeneralAffair 9 Gtrlima, Gtrinout, Gsppdt, Gppurch, Gsplace, Gpurch, Ginvent, Gtrrama, Persmems(R) E.Order 14 Ci, Cudatam, Cuinve, Cupdma, Fillrate, Pk, Preord, Rma, Salema, Sample, Ormast, Cuqt, WarrantyCard, Shiptoaddress, Visit P.Invoice 10 Tother, Ticks, Ticksr, Tickr, Tickmin, Ticka_voidrp, Ticka_rej, Ticka_disc, Tick3, Ticka H.Inventory 11 Jobcode, Invrec, Bol, Splace, Trlost, Trinout, Trlima, Trrama, Trsama, MasterFile, (含 Splace cleanup) G.Purchasing 7 Purch, Ppurch, TrrafeePrime, Sppdt, VendorDefect, VendorFillRate, VendorEvaluation J.QC 5 Wkrama, Twrama, Repair, Purama, Complain F.Production 4 Wkpaper, Wkday, Pdtinf, OutSourcingFillRate Q.FixedAsset 2 Asset, Accexp D.Bom, K.Cost, M.EIS, Z.System 各 1 Invent_prime, Cost, ProductionPlan, Contract 每個 VM 的處理:
public ObservableCollection<T> XxxName { get/set + _backing }→public DataManager<T> XxxNameData { get; private set; }
- 構造子加
XxxNameData = ItemsBindingManager.Register<T>();(順序對應原本GetBindingSourcesPropertyName的 obj[n] 順序)
- 若 binding sources 全轉了,整段刪除
GetBindingSourcesPropertyName()override
- usages 替換:
.Count > 0→.FirstItem != null、[0]→.FirstItem、[idx]→.ObservableCollection[idx]、foreach→.ObservableCollection、.Add→.AddItem、.Clear→.Clear、= new ObservableCollection<T>(query)視語意改SeedFromRemote或AddRange
masterListenerHelper.SetProperty(ref _Master, value)→ 構造子裡MasterData.AddListener(helper)
XAML 層(~60 檔)
{Binding MasterItem}→{Binding MasterData.GridView.CurrentItem}
{Binding Master[0]}→{Binding MasterData.GridView.CurrentItem}
ItemsSource="{Binding Master}"→ItemsSource="{Binding MasterData.GridView}"
ItemsSource="{Binding Detail}"→ItemsSource="{Binding DetailData.GridView}"
ItemsSource="{Binding DetailN}"→ItemsSource="{Binding DetailNData.GridView}"
{Binding Master.Prop}→{Binding MasterData.GridView.CurrentItem.Prop}
含
Purchasing\G.Purchasing\VendorFillRate.xaml與Purchasing\G.Purchasing\VendorDefect.xaml(重複位置)一併修。外部 caller 與 BLL 簽章(17 處)
修了非主目標但會 reference
viewModel.Master/.Detail的下游:ViewModel/E.Order/WarrantyContentSpecialQueryViewModel.cs
ViewModel/E.Order/Ci_m1ViewModel.cs
ViewModel/E.Order/PreordControlViewModel.cs
ViewModel/E.Order/OrmastStockQueryViewModel.cs
ViewModel/E.Order/Ormast_sViewModel.cs
ViewModel/H.Inventory/InvrecmViewModel.cs
ViewModel/H.Inventory/WhseChangeViewModel.cs
ViewModel/H.Inventory/ItemTransferViewModel.cs
ViewModel/H.Inventory/PickingAdjustViewModel.cs
ViewModel/H.Inventory/StkMoveViewModel.cs
ViewModel/H.Inventory/BOLImportViewModel.cs
ViewModel/H.Inventory/TrramaAllocationViewModel.cs
ViewModel/H.Inventory/TrramaAllocationQueryViewModel.cs
ViewModel/H.Inventory/TrramaAPQueryViewModel.cs
ViewModel/H.Inventory/TrsamaPickingQueryViewModel.cs
ViewModel/C.GeneralAffair/GtrramaAllocationQueryViewModel.cs
LogicBll/E.Order/Cuqt/CuqtBll.cs:Import/AddDetail/AddDetail1參數從ObservableCollection<T>改DataManager<T>、.Add→.AddItem
Breaking Changes
對「外部 caller」(非本批內的 production code,例如 plugin / 自訂 BLL):
- VM 的
Master/Detail/DetailN屬性消失,改用MasterData/DetailData/DetailNData,且改成{ get; private set; }(不能再從外部賦值)
- 若外部要對清單操作:
.Add(item)→.AddItem(item)、.Clear()→.Clear()、.Count→.ObservableCollection.Count、[0]→.FirstItem
- 若外部要替換整批資料:原本
vm.Master = new ObservableCollection<T>(data)不能用,改vm.MasterData.SeedFromRemote(data.ToList())(不標 dirty)或vm.MasterData.AddRange(data)(會標 IsNew/IsDirty)
CuqtBll公開方法簽章變更:呼叫端要傳DataManager<T>而非ObservableCollection<T>
對使用者的影響
- 終端使用者大部分操作無感
- 修活畫面:原本 XAML 寫
{Binding MasterItem}但 VM 沒 Register 的程式(典型如 H.Inventory\Jobcode),本來開啟畫面什麼都沒有,現在正常顯示與編輯
- 可能行為改變:6 處
Detail.Insert(index, item)被改成DetailData.AddItem(item)(append 到尾端),如果原本有業務邏輯依賴「插入到特定位置」,使用者觀察到的順序會不同。詳見「待人工複查」
待人工複查
1. Insert(index) → AddItem 行為改變(6 處,已在原位用 `// NOTE:` 標註)
DataManager<T>目前沒有Insert(int index, T item)API,全改成 append。若這些位置有業務語意,要考慮在DataManager<T>補InsertItem(int index, T item):ViewModel/E.Order/Ci_m1ViewModel.cs:~166
ViewModel/E.Order/PreordControlViewModel.cs:~282
ViewModel/G.Purchasing/PurchViewModel.cs:~219
ViewModel/H.Inventory/TrlimaViewModel.cs:~340(2 處)
ViewModel/H.Inventory/WhseChangeViewModel.cs:~242
ViewModel/H.Inventory/PickingAdjustViewModel.cs:~146
2. 測試檔已壞,未修
下列測試檔用了
viewModel.Master = new ObservableCollection<>()物件初始化器語法,現在 setter 拿掉了會編譯失敗:UnitTest1/UploadTest/PurchasingTests.cs
UnitTest1/UploadTest/InventoryTests.cs:46, 134
Test_SqlModify/UploadTest/PurchasingTests.cs
Test_SqlModify/UploadTest/InventoryTests.cs:46, 134
Migration:物件初始化器中的
Master = new ObservableCollection<T> { ... }改成在arrange後另寫一句viewModel.MasterData.AddRange(new[] { ... })。Detail 同理。3. MasterFileViewModel 無對應獨立 XAML
ViewModel/H.Inventory/Edi_Export/MasterFileViewModel.cs是 nested VM、沒有獨立 .xaml 檔。VM 已轉,但實際上Edi_Export.xaml內並未綁定到它(tab DataContext 是Edi856ViewModel/Edi810ViewModel)。需要再確認這個 VM 是否還有用,若無可考慮整檔刪除。Build 狀態
ViewModel.csproj:exit 0、0 errors
TsERP.csproj:exit 0、0 errors
UnitTest1.csproj/Test_SqlModify.csproj:4 個檔需修才會通過(見「待人工複查 2」)
還剩什麼 ObservableCollection?
完成後仍有
ObservableCollection使用的檔案大多屬於:- ComboBox / dropdown 來源(非 binding source,不需轉)
- 統計查詢、暫存 list、UI 內部 buffer
- Helper / infrastructure(
ObservableCollectionExtensions、HistoryViewModel等)
不在這次轉換目標內。
-
05-17 dg-to-radgrid-batch ▸
2026-05-17 — TsDataGrid → TsRadGridView 大批次轉換 + 補建 SeekGridViewColumn
摘要
接續上午的
ObservableCollection → DataManager遷移(commitfccf4d73),把同一批 52 個 XAML 的TsDataGrid全部換成TsRadGridView,並補上對應DataManager="{Binding XxxData}"、把所有欄位類型/屬性照新版 API 改掉。過程中發現 6 個常用 Seek 欄位(Customer / Vendor / SalesRep / Bin / SKUGroup / Processing)在 Telerik 版下沒有對應類別,補建 5 個新類別(Processing 沿用既有)。變更
新增類別(5 個,`TsControl/TsTelerik/TsRadGridViewColumn/`)
類別 預設 Header / SeekCondition / SeekColumn ExistTable TsCustomerSeekGridViewColumn客戶代號 / 客戶代號 / 客戶簡稱 Cudata TsVendorSeekGridViewColumn廠商代號 / 廠商代號 / 廠商簡稱 Spdata TsSalesRepSeekGridViewColumn業務員編號 / 業務員編號 / 姓名 salesmen TsBinSeekGridViewColumn倉儲代號 / 倉儲代號 / 倉儲說明 Splace TsSKUGroupSeekGridViewColumn群組代號 / 群組代號 / 說明(DataMemberBinding=產品群組) Grpm 全部繼承
TsSeekGridViewColumn,行為與 V2 / DataGridV2 版本對等。預設綁中文欄位;XAML 若有需要可用DataMemberBinding覆寫。XAML(52 + 8 + 6 = 60 處/檔次)
容器與欄位
<TsControl:TsDataGrid>/<local:TsDataGrid>→<tsTelerik:TsRadGridView>
<DataGrid.Columns>/<TsControl:TsDataGrid.Columns>→<tsTelerik:TsRadGridView.Columns>
- 加上
xmlns:tsTelerik、xmlns:tsRadGridViewColumn
- Style key
ERPDataGrid→ErpDataGridView
- 每個
ItemsSource="{Binding XxxData.GridView}"補DataManager="{Binding XxxData}"
欄位類型對照
舊 新 TsDataGridTextColumnTsGridViewDataColumnTsDataGridNumericColumnTsGridViewDataNumericColumnTsDataGridTemplateColumnTsGridViewDataColumn(含 CellTemplate)TsDataGridComboBoxColumnTsGridViewComboBoxColumn(搭 BindingProxy)v2:TsDateColumnV2TsGridViewDataDateColumnTsSKUSearchColumn/TsSkuSeekColumnTsSkuSeekGridViewColumnTsCuspSearchColumnTsCuspSeekGridViewColumnTsBankAccountSeekColumnTsBankaccountSeekGridViewColumnTsDepartmentSearchColumnTsDepartmentSeekGridViewColumnTsGLAccountSearchColumnTsGLAccountSeekGridViewColumnTsGroupSeekColumnTsGroupSeekGridViewColumnTsIndexSearchColumnTsSortSeekGridViewColumnTsSKUFixedAssetSearchColumnTsSkuFixedAssetSeekGridViewColumnv2:TsUomColumnTsUomGridViewColumnTsVendorSearchColumn★TsVendorSeekGridViewColumnTsSalesRepSearchColumn★TsSalesRepSeekGridViewColumnTsBinSearchColumn★TsBinSeekGridViewColumnTsCustomerSeekColumn★TsCustomerSeekGridViewColumnTsSKUGroupSeekColumn★TsSKUGroupSeekGridViewColumnTsProcessingSearchColumn/TsProcessingSeekColumnTsProcessingSeekGridViewColumn★ 標記者本次新建類別。
屬性轉換
Binding="{Binding X}"→DataMemberBinding="{Binding X}"
MaskInfo="ShortDate"(在日期欄位)→ForceReadOnly="True"
BindingName="X"(V2 日期欄位)→DataMemberBinding="{Binding X}"
- Seek 欄位
Description="{Binding X, ...}"→DescriptionBindingPath="X"
- 欄位
Visibility=+VisibilityConverter→IsVisible=(容器 Visibility 維持)
- 移除:
ProgramClass、SelectFirstOnItemsChanged、ClipboardContentBinding="{x:Null}"、NeedTranslate、CheckValidate、CanUserReorder、AvoidEdit、欄位上殘留的DataGridTextColumn.ElementStyle/EditingElementStyle
TsGridViewComboBoxColumn用 BindingProxy 處理ItemsSourceBinding
- ElementStyle/EditingElementStyle 內含的 TextWrapping / AcceptsReturn 改用
CellTemplate/CellEditTemplate重做(Ormast_US、Persmems)
- Button template 改
TsButtonInCell+CellStyle="{StaticResource ButtonCell}"
涵蓋檔案(52 XAML)
C.GeneralAffair (6):Ginvent、Gppurch、Gsplace、Gsppdt、Gtrlima、Gtrrama
E.Order (13):Ci、Cudatalimit、Cuinve、Cupdma、Cuqt、Fillrate、Ormast、Ormast_US、Pk、Preord、Rma、Salema、Sample
F.Production (4):OutSourcingFillRate、Pdtinf、Wkday、Wkpaper
G.Purchasing (6+2):Ppurch、Purch、Sppdt、VendorDefect、VendorEvaluation、VendorFillRate(+ Purchasing 專案 mirror 2 個)
H.Inventory (8):Bol、Invrec、Splace、Trinout、Trlima、Trlost、Trrama、Trsama
J.QC (4):Complain、Purama、Twrama、Wkrama
P.Invoice (5):Ticka、Ticka_disc、Tickr、Ticks、Ticksr
其他:K.Cost/Cost、M.EIS/ProductionPlan、D.Bom/Invent_prime、R.HumanResource/Persmems
Breaking Changes
對「外部 caller / plugin」:
- 上述 52 個 XAML 的 grid x:Name 仍可用,但是元件類型變了。code-behind 若有
(TsDataGrid)detailDataGrid.xxx強制轉型會壞 — 全部要改成TsRadGridView。
- 舊 column 類別屬性差異會影響 templated style:
-
Binding→DataMemberBinding-
Description字串 →DescriptionBindingPath字串(只取 path,不接 Binding 標記)- column 上
Visibility不能用,改IsVisible(bool)TsDataGrid上的下列 API 在新版不存在:NeedTranslate、CheckValidate、CanUserReorder(column)、AvoidEdit、column 上ProgramClass、SelectFirstOnItemsChanged
- 新建 5 個 SeekGridViewColumn 預設 binding 用中文(客戶代號 / 廠商代號 / 業務員編號 / 倉儲代號 / 產品群組);若 row 物件屬性為英文,XAML 必須用
DataMemberBinding覆寫
對使用者的影響
- 一般操作無感
- 修活的畫面:Jobcode 之類「XAML 寫對但 VM 沒 Register」的程式(昨天 obs-to-datamanager 那批同樣狀況)正常顯示
- 行為觀察點:
-
TsProcessingSeekGridViewColumn中文預設(SeekCondition=工程代號)被 Cuqt / Wkpaper / Gsppdt 用英文 DataMemberBinding 覆寫綁;seek popup 查 PROCNOS 表的欄位是中文,要確認該表中英欄位齊全-
TsSalesRepSeekGridViewColumn中文預設被 Cuinve 用英文(SalesRepCode)覆寫,同樣風險-
TsCustomerSeekGridViewColumn在 Cudatalimit 沒 DataMemberBinding 覆寫 → 會用類別預設客戶代號,需要該 row 物件有此屬性才綁得到待人工複查
1. Invent_prime.xaml 內側仍有一個
TsControl:TsVirtualGrid(不是TsRadGridView),inner columns 已還原為TsDataGridTextColumn/TsDataGridTemplateColumn(與容器搭配正確)。但同檔另一個獨立的tsTelerik:TsRadGridView(DetailData)少設DataManager="{Binding DetailData}",仍可用但建議補上以保留 DataManager 行為。2. Pk.xaml 原始 source 有個 typo
BindingName="{Binding 結關日期}"(BindingName 接的是字串 path),E.Order worker 直接轉成DataMemberBinding="{Binding 結關日期}",runtime 行為可能改變,要確認原意。3. 6 處
Detail.Insert(index, item)改成AddItem(append)(屬於昨天 obs-to-datamanager 留下的// NOTE:標註):若DataManager<T>之後補InsertItem(int, T),這些位置可一併還原。4.
TsBinSearchColumn→TsBinSeekGridViewColumn還原時保留了FilterCondition="{Binding WarehouseFilter}"/FilterCondition="{Binding FilterCondition}",行為應等價。Build 狀態
TsERP.csproj:0 XAML 編譯錯誤、0 CS 錯誤
- 多次 build 中偶發
MC1000檔案鎖定 / mscorlib 解析警告,屬於 .NET SDK 10 MSBuild WPF MarkupCompile 工具鏈問題,與本次內容無關
連結
- 相關 skill:
.claude/skills/dg-to-radgrid
-
05-13 per-customer-config ▸
2026-05-13 — 客戶端設定檔同步機制
對應 ADR 0019。
摘要
- 新增
DatabaseListSourcePath設定,TsERP 啟動時依此路徑將客戶專屬DatabaseList.xml同步到本機目的地
- 拿掉「找不到
DatabaseList.xml時自動產生預設清單」的行為
- 新增
deploy/deploy-customer.ps1部署腳本,給 IT 人員在客戶機器一鍵建立設定檔
TsERP.SchedulerWorker同步支援此機制
新增
appsettings.json新欄位DatabaseListSourcePath(TsERP / SchedulerWorker 皆有)
Common\Environment\XmlSqlLocation.EnsureDatabaseList()靜態方法
deploy/deploy-customer.ps1:參數化部署腳本
docs/deployment/per-customer-setup.md:部署 SOP 文件
變更
XmlSqlLocation.GetSqlDataBase()不再呼叫CreateList(),僅讀檔
TsERP/App.xaml.cs:在 DI 註冊前呼叫EnsureDatabaseList(),失敗以MessageBox提示 +Shutdown(1)
TsERP.SchedulerWorker/Program.cs:同樣在 DI 註冊前呼叫EnsureDatabaseList()
刪除
XmlSqlLocation.CreateList()/EditToNewDatabase()/GetData()(含寫死的預設清單)
Breaking Changes
- 開發機若依賴自動產生的預設
DatabaseList.xml會啟動失敗。處理方式:
1. 手動在
c:/TEMPS/SqlLocation/DatabaseList.xml放開發環境清單,或2. 在
%ProgramData%\TsERP\appsettings.local.json設DatabaseListSourcePath指向 dev XML,或3. 跑
deploy/deploy-customer.ps1把開發環境當客戶處理- 新客戶部署流程改變:除了裝 TsERP 本體,需先跑部署腳本(或手動準備
DatabaseList.xml)
Migration Notes
客戶端
- 已部署、且
DatabaseList.xml已存在的客戶:啟動行為無變化
- 新客戶:請參照
docs/deployment/per-customer-setup.md
集中管理客戶設定
DatabaseListSourcePath可指向網路磁碟路徑(例:\\fileserver\TsERPConfig\客戶A\DatabaseList.xml)
- IT 在中央位置更新後,所有客戶下次啟動會依
LastWriteTime自動同步
- 新增
-
05-09 mailqueue-channel ▸
2026-05-09 — 排程信件改走 mailqueue + Mailgun(Database Mail 不再必要)
摘要
SchedulerJob加入 Phase 3DequeueMailAsync:AutoPilot SP 把組好的信件寫進新表twork_skd_mailqueue,由 SchedulerWorker 統一透過既有 Mailgun 通道寄出。客戶端 SQL Server 不再需要設定 Database Mail。新增
- 資料表
twork_skd_mailqueue:排程信件佇列(中文欄位、狀態碼 N/R/Y/F/D 對齊既有已通知/已完成風格)
- SP
TWORK_SKD_MAILQUEUE_DEQUEUE:批次撈待寄信件 + 殭屍回收(>10 分鐘卡 R 自動回 N)
- SP
TWORK_SKD_MAILQUEUE_UPDATE_STATUS:寄送結果回寫,含指數退避(30/60/120/240/480 秒)與死信判定
Procedure.TWORK_SKD_MAILQUEUE_DEQUEUE/TWORK_SKD_MAILQUEUE_UPDATE_STATUSenum
SchedulerJob.DequeueMailAsync:第三 phase,每輪 dequeue 20 筆 → Mailgun → 更新狀態
變更
IMailService.SendAsync新增 optionalisHtml = false參數;MailGunService 在isHtml=true時改用 Mailgun 的html欄位(之前只走text)
SchedulerJob.RunOnceAsync對每個 DB 從 2 phase 變 3 phase(Notify → AutoPilot → DequeueMail)
FakeMailService同步補isHtml參數
刪除
無
Breaking Changes
無:
IMailService.SendAsync是 optional 參數;mailqueue 是新增表。AutoPilot SP 內仍走EXEC msdb.dbo.sp_send_dbmail的客戶不會壞,可漸進改寫。Migration Notes
1. DBA:對每個目標 DB 跑 schema script
SqlBI/twork_skd_mailqueue.sql -- 建表 + index SqlBI/TWORK_SKD_MAILQUEUE_DEQUEUE.sql -- 出列 SP SqlBI/TWORK_SKD_MAILQUEUE_UPDATE_STATUS.sql -- 結果回寫 SP2. AutoPilot SP 改寫範本(漸進式)
把:
EXEC msdb.dbo.sp_send_dbmail @profile_name = N'qq', @recipients = ..., @subject = @subject, @body = @body, @body_format = N'HTML';換成:
INSERT dbo.twork_skd_mailqueue (收件人, 主旨, 內文, 是否HTML, 來源預存程序, 執行guid) VALUES (@recipients, @subject, @body, 'Y', OBJECT_NAME(@@PROCID), @execguid);HTML 組裝(
FOR XML PATH)整段保留,不必重寫。3. 部署順序
1. 先建新 SP / 新表
2. 再升級 SchedulerWorker
3. 一支一支改寫 AutoPilot SP(PoC 推薦從
TWORK_MOLD_SENDMAIL開始)4. 監控查詢
SELECT 狀態, COUNT(*) FROM dbo.twork_skd_mailqueue GROUP BY 狀態; -- 死信檢視 SELECT pkid, 主旨, 重試次數, 最後錯誤, 來源預存程序 FROM dbo.twork_skd_mailqueue WHERE 狀態 = 'D' ORDER BY 建立時間 DESC;相關 ADR
- 資料表
-
05-05 sql-connection-tuning ▸
2026-05-05 — SQL 連線字串補上效能與安全參數
摘要
使用者反映「連 SQL 執行命令有時候比較久」。實測冷啟動 145 ms vs 熱連線 2-3 ms,差距 50 倍。
Microsoft.Data.SqlClient4.0+ 預設Encrypt=True會在內網每次新連線多一段 TLS 交涉。本次在DataBaseParameter.ConnectionString補上Encrypt(依 Azure 旗標切換)、Min Pool Size=1、Connection Timeout=15。詳細決策見 ADR 0016。變更
Common\Environment\DataBaseParameter.cs:ConnectionStringgetter 加入:
-
Encrypt=False(地端)/Encrypt=True(Azure,依Poco.IsAzure)-
Min Pool Size=1— 確保連線池常駐至少一條熱連線-
Connection Timeout=15— 顯式寫出(雖是預設值),方便日後微調對使用者的影響
- 終端使用者:地端連線冷啟動更快;閒置一段時間後第一次操作不會再卡頓
- 管理員 / DBA:無需動 SQL Server 設定
- 開發者:若新增「公網但非 Azure」的連線目標,需要評估
Encrypt=False是否安全;目前判斷依據是DatabaseList.xml的<IsAzure>元素
不在本次範圍
DataBaseDal\PrimeConn.cs與PrimeBll\PrimeConn.cs內各自硬編的ConnectionString未一併修改。Prime 模組相關功能(佣金生成、Prime AR/AP)的連線字串仍是舊格式,若使用者使用該功能且需要相同優化,需後續另開 task
-
05-05 scheduler-log-dedicated-folder ▸
2026-05-05 — SchedulerWorker 改用 SchedulerLog,log 寫到獨立資料夾
摘要
SchedulerWorker 原本透過
Console.WriteLine(正式環境會被丟棄)與DebugLog(只在 catch 區塊呼叫)記錄歷程,導致正式環境完全看不到正常運作訊息。本次新增SchedulerLoghelper,把所有歷程統一寫到C:\temps\scheduler\yyyy-MM-dd.txt,每天一個檔。詳細決策見 ADR 0017。新增
TsERP.SchedulerWorker\SchedulerLog.cs:
- 寫到
C:\temps\scheduler\yyyy-MM-dd.txt- 兩個層級:
Info/Error- 行格式:
yyyy-MM-dd HH:mm:ss [LEVEL] 訊息- 同步輸出到 Console(保留手動執行時可見)
-
lock保護併發;try/catch吃掉 logging 失敗變更
TsERP.SchedulerWorker\SchedulerJob.cs:所有Console.WriteLine/Console.Error.WriteLine/new DebugLog().WriteLog(...)→SchedulerLog.Info(...)/SchedulerLog.Error(...)
TsERP.SchedulerWorker\Program.cs:同上
docs/admin/scheduler.md:更新所有 log 路徑說明,從c:\temps\SCHED\與C:\ERPDeploy\Scheduler\logs\統一改為C:\temps\scheduler\;新增行格式範例
Migration Notes
部署 server 端必做:
# 建立 log 資料夾並設權限 New-Item -Path "C:\temps\scheduler" -ItemType Directory -Force icacls "C:\temps\scheduler" /grant "<服務帳號>:(OI)(CI)M"資料夾不存在時
SchedulerLog會自動建立,但服務帳號必須對C:\temps\有寫入權,否則 logging 會靜默失敗。舊的
C:\temps\debuglog\內 SchedulerWorker 歷史 log 保留,未來不再寫入。對使用者的影響
- 終端使用者:無感
- 管理員:
- 首次能在正式環境看完整歷程(每個 DB 跑了什麼、處理了哪些 pkid、exit code)
- 看 log 的位置從
c:\temps\SCHED\/C:\ERPDeploy\Scheduler\logs\(先前實際也不存在,文件腐爛)改成C:\temps\scheduler\yyyy-MM-dd.txt- DBA / IT:部署需多一步建資料夾與設權限(見 Migration Notes)
- 開發者:未來在 SchedulerWorker 內加新訊息,請使用
SchedulerLog.Info/SchedulerLog.Error,不要回去用Console.WriteLine或DebugLog
-
05-04 skd-sp-split ▸
2026-05-04 — TWORK_SKD_NOTIFYEVENT 拆兩支 + 修積累 bug
摘要
TWORK_SKD_NOTIFYEVENT原本一支 SP 透過@QueryType包了「待 Email 通知」與「待 AutoPilot 自動執行」兩個無關查詢,且@QueryType=2分支累積兩個 bug(停用應是是否停用、殭屍判定還在用退役狀態碼'X')。本次拆成兩支單一職責 SP 並順手修掉。詳細決策見 ADR 0015。新增
- SP
TWORK_SKD_GET_PENDING_NOTIFY(SqlBI/TWORK_SKD_GET_PENDING_NOTIFY.sql):撈待 Email 通知事件,取代原@QueryType=1分支
- SP
TWORK_SKD_GET_PENDING_AUTOEXEC(SqlBI/TWORK_SKD_GET_PENDING_AUTOEXEC.sql):撈待 AutoPilot 自動執行事件,取代原@QueryType=2分支
Procedure.cs加 2 個對應 enum:TWORK_SKD_GET_PENDING_NOTIFY、TWORK_SKD_GET_PENDING_AUTOEXEC
變更
TsERP.SchedulerWorker/SchedulerJob.cs:
-
NotifyAsync:改打TWORK_SKD_GET_PENDING_NOTIFY,移除lp_p1="1"魔術數字-
AutoPilotAsync:改打TWORK_SKD_GET_PENDING_AUTOEXEC,移除lp_p1="2"魔術數字- 兩處
Update已通知/Update已完成(pkid, "X", ...)→"R"(對齊 ADR 0013,先前漏改)Common/DataBaseObjectEnum/Procedure.cs:舊TWORK_SKD_NOTIFYEVENT標[Obsolete],註解指向 ADR 0015
- SP
TWORK_SKD_GET_PENDING_AUTOEXEC內 bug 修復(相對於原@QueryType=2):
-
停用 <> 'Y'→是否停用 <> 'Y'(對齊Twork_skd_vw_eventitemModel.是否停用)-
已完成 <> 'X'→已完成 <> 'R'(殭屍判定恢復作用)-
DATEADD(MINUTE, -10, GETDATE())→DATEADD(MINUTE, -10, @datetime)(基準時間可由 caller 控制)刪除
- 無 — 舊 SP
TWORK_SKD_NOTIFYEVENT留在 DB 與 enum 中,標[Obsolete]漸進淘汰(Migration Notes 第 4 步說明何時可 drop)
Breaking Changes
- DB schema 必動:兩支新 SP 必須先在 DB 建立才能升 SchedulerWorker,否則 worker 跑不起來
- 殭轉判定真的會生效:先前
'X'bug 等於沒判殭屍;現改'R'後,超過 10 分鐘還在執行中的事件會被視為前一輪 crash 而重撈。若 production 真有合法跑超過 10 分鐘的事件,會被重複撈 → 重複跑。建議先觀察一輪執行開始時間分布,視情況調大殭屍 timeout(目前 hardcode 10 分鐘)
- 直呼舊 SP
TWORK_SKD_NOTIFYEVENT的外部腳本 / 排程不受影響(SP 還在),但建議遷移到新 SP
Migration Notes
DBA 端(每個目標 DB 必跑)
-- 1. 建立待通知 SP CREATE PROCEDURE [dbo].[TWORK_SKD_GET_PENDING_NOTIFY] (@datetime datetime) AS BEGIN SET NOCOUNT ON; SELECT * FROM dbo.twork_vw_calendarevent WHERE 已審核 = 'Y' AND 是否停用 <> 'Y' AND 通知 = 'Y' AND 通知帳號 <> '' AND 已通知 <> 'Y' AND @datetime >= 通知時間; END GO -- 2. 建立待自動執行 SP CREATE PROCEDURE [dbo].[TWORK_SKD_GET_PENDING_AUTOEXEC] (@datetime datetime) AS BEGIN SET NOCOUNT ON; SELECT TOP 20 * FROM twork_vw_calendarevent WHERE 已完成 NOT IN ('Y', 'F') AND (已完成 <> 'R' OR 執行開始時間 < DATEADD(MINUTE, -10, @datetime)) AND 已審核 = 'Y' AND 是否停用 <> 'Y' AND 是否自動執行 = 'Y' ORDER BY 預定時間 ASC; END GO完整 script 在
SqlBI/TWORK_SKD_GET_PENDING_NOTIFY.sql與SqlBI/TWORK_SKD_GET_PENDING_AUTOEXEC.sql。部署順序
1. DBA 先建新 SP(上述兩個
CREATE PROCEDURE)2. Build & deploy 新版
TsERP.SchedulerWorker3. 觀察 1-2 輪正常運轉:看
c:\temps\SCHED\內 log 有Notify pkid=.../AutoPilot pkid=...紀錄4. 可選清理:確認穩定後
DROP PROCEDURE TWORK_SKD_NOTIFYEVENT順序顛倒會在升級 gap 期間 SchedulerWorker 找不到 SP 而 crash。
對使用者的影響
- 終端使用者:無感,UI / 行為不變
- 管理員:殭屍事件回收機制現在真的有作用 — 若有事件卡在
R狀態超過 10 分鐘會被視為前一輪 crash 重撈
- DBA:必跑兩個
CREATE PROCEDUREscript
- 開發者:撈待辦事件不再透過
@QueryType魔術數字,新增類似查詢時直接命名新 SP 即可
- SP
-
05-04 rightcalendar-ux-overhaul ▸
2026-05-04 — RightSideCalendar UX 全面改造(圓點著色 / 過期紅色 / 已完成灰階 / 按鈕下排 / async 月快取)
摘要
接續同日
2026-05-04-rightcalendar-event-dot-fix.md的事件圓點修復,本次再做一輪視覺與資料層的改進:日曆圓點按擁有者類別著色、過期未完成事件標紅、已完成事件灰階加刪除線、4 顆操作按鈕從事件右側移到下排,事件清單寬度大幅增加;資料層改 async + 月份快取,切月份不再卡 UI、同月切換不重抓 server;ViewModel 的 4 個Show*屬性整併成OwnerFilterscollection,新增擁有者類別不必再 patch 4 個屬性。詳細決策見 ADR 0014。
新增
ViewModel/MainWindowPage/OwnerFilterItem.cs:擁有者篩選 item POCO(OwnerType/DisplayName/IsVisible/IsChecked)
CalendarPageViewModel.OwnerFilters:ObservableCollection<OwnerFilterItem>,4 顆 toggle 的 binding 來源
CalendarPageViewModel.EventSummaryByDate:Dictionary<DateTime, DayEventSummary>,每日Count+DominantOwnerType,給日曆圓點著色用
CalendarPageViewModel.HasNoEventsToday/HasFilteredOutAll:空狀態分流;前者是「該日完全無事件」,後者是「該日有事件但全被 toggle 篩掉」
CalendarPoco.已過期未完成:衍生屬性(預定時間 < Now && 已完成 != "Y"),給事件 row 標紅用
EventDayTemplateSelector新增 4 個 owner 變體 template:EventTemplatePersonal/Department/Company/System
RightSideCalendar.xamlUserControl.Resources新增 9 個 brush:EventDatePrimaryBrush/EventOwnerSecondaryBrush/EventItemBackgroundBrush/EventEmptyHintBrush/EventOverdueBrush/OwnerColorPersonal/OwnerColorDepartment/OwnerColorCompany/OwnerColorSystem
- 內部欄位
_monthCache: Dictionary<(int Year, int Month), List<CalendarPoco>>:client-side 月份事件快取
- 新增
LoadEventsForMonthAsync(DateTime, bool)private method 取代舊 sync 版
變更
ViewModel/MainWindowPage/CalendarPageViewModel.cs:
- 移除
Show個人 / Show部門 / Show公司 / Show系統屬性與對應欄位- 移除
_show系統UserSet旗標、CanSee系統唯讀屬性、EventDates(HashSet<DateTime>)- 移除 public
GetEvent(string date)(唯一外部呼叫已被註解,改全部走LoadEventsForMonthAsync)- 移除
LoadEventsForMonth同步版,改LoadEventsForMonthAsync-
IsOwnerVisible從 byte switch (0/1/2/9) 改成查OwnerFilters,magic number 消失-
RefreshUserPermission簡化:只看IsAdmin()變化來決定要不要同步系統 toggle 的IsVisible/IsChecked,不再用_show系統UserSet旗標-
DisplayDate.set/Refresh()用_ = LoadEventsForMonthAsync(...)fire-and-forget- 例外處理改為
try/catch + TsMsgBox.ShowError包在LoadEventsForMonthAsync內,避免 fire-and-forget 例外被吞掉-
HasNoEvents拆成HasNoEventsToday+HasFilteredOutAllLogicBll/Calendar/CalendarPoco.cs:
-
已完成Binding.set連帶通知已過期未完成屬性變更(取消勾選後紅色立即恢復)TsControl/Calendar/EventDayTemplateSelector.cs:
- 從原本 1 個
EventTemplate加 fallback 變成 5 個(4 種 owner + fallback gray)-
SelectTemplate改用vm.EventSummaryByDate查DominantOwnerType,再透過vm.Context.EnumManager.EventOwner把 byte 對應到 enumTsControl/Calendar/RightSideCalendar.xaml:
- 4 個獨立
TsToggleButton改成ItemsControl綁OwnerFilters+UniformGrid Columns=4+DataTemplate- 4 顆操作按鈕(導航 / 執行 / 附件 / 報告)從事件 row 右側
Grid.Column=2移到下排Grid.Row=1,用UniformGrid Columns=4等寬排列-
EventControlDataTemplate 內:根 Grid 已完成時Opacity=0.5、EventDate過期未完成 Foreground 變紅、EventTitle已完成加TextDecorations="Strikethrough"- 新增 5 個 EventTemplate XAML block 對應 4 種擁有者類別 + 1 fallback
- 硬編色(
#FF000000/#FF686868/#FFEBEBEB/#FF888888)改用StaticResource引用UserControl.Resources內的 brush- 空狀態 TextBlock 拆兩個:「今日無事件」綁
HasNoEventsToday、「事件已被篩選」綁HasFilteredOutAllViewModel/Common/DataNavigateHelperV2.cs:
- 順手清掉先前診斷 row scroll 問題暫加的
Debug.WriteLine(無功能影響)刪除
CalendarPageViewModel.GetEvent(string date)public method(唯一 caller 已被註解,無實際使用)
CalendarPageViewModel.EventDates(HashSet<DateTime>) 屬性(被EventSummaryByDate取代)
CalendarPageViewModel.Show個人 / Show部門 / Show公司 / Show系統屬性與對應 fields
CalendarPageViewModel.CanSee系統屬性
CalendarPageViewModel._show系統UserSet旗標
CalendarPageViewModel.HasNoEvents屬性(拆成兩個)
Breaking Changes
- 任何外部 XAML / code 若 binding 過
Show個人 / Show部門 / Show公司 / Show系統 / CanSee系統 / EventDates / HasNoEvents,會 binding error。grep 後本 repo 內無此 caller。
CalendarPageViewModel.GetEvent(string)已移除;外部呼叫者請改用Refresh()。本 repo 內無 caller。
Migration Notes
- 無 SQL / 設定變更
- 多語系:新增一條 key
事件已被篩選;未設定時 fallback 到中文字面值,不會 crash
- 顏色與資源:所有 brush 集中在
RightSideCalendar.xaml的UserControl.Resources,未來若要抽到 theme dictionary 一處改即可
對使用者的影響
- 切月份順了:DB 抓資料推到背景 thread,UI thread 不再被卡;同月份切回來不重抓 server
- 過期事件醒目:日期已過但未勾「已完成」的事件,事件 row 上方時間文字會變紅
- 已完成事件視覺淡化:整個 row
Opacity=0.5、標題加刪除線;列表上一眼分辨「已處理」與「待處理」
- 日曆圓點上色:每日事件圓點顏色反映「該日事件最多者」的擁有者類別 — 橘=個人、綠=部門、藍=公司、深灰=系統。掃過月曆能看出主要事件來源
- 事件文字變寬:4 顆操作按鈕從右側移到下排,事件標題與說明的可用寬度從約 60px 增加到約 180px,內容不再被截
- 空狀態分流:當天若資料庫真的無事件,顯示「今日無事件」;若有事件但全被 4 個擁有者 toggle 篩掉,改顯示「事件已被篩選」,避免使用者誤以為資料消失
- 管理員系統 toggle 行為更直觀:admin 第一次開日曆會把「系統」toggle 設成可見且勾選;admin 在 session 內手動取消勾選後,後續
Refresh()不會再被打回去(除非IsAdmin()權限本身變化)
-
05-04 rightcalendar-event-dot-fix ▸
2026-05-04 — RightSideCalendar 事件圓點修復、擁有者篩選與重構
摘要
右側
RightSideCalendar的當日事件圓點之前只有時間正好是 00:00:00 的事件才顯示,其他時間的事件會被當作「無事件」漏掉。同時CalendarPageViewModel的屬性 setter 內含 DB 抓取與 filter 副作用,月切換每格都跑 LINQ。順手把死碼清掉、加上個人 / 部門 / 公司 / 系統四類擁有者的多選 toggle 篩選(系統需 admin 權限),並加上空狀態提示與錯誤處理。新增
- 擁有者類別篩選:右側日曆下方 4 顆 ToggleButton(個人 / 部門 / 公司 / 系統),多選;預設個人+部門+公司開啟、系統依
Context.User.IsAdmin()決定是否顯示
CalendarPageViewModel.Show個人 / Show部門 / Show公司 / Show系統:篩選 toggle binding 屬性
CalendarPageViewModel.CanSee系統:唯讀屬性,控制系統 toggle 的顯示與可勾性,等於IsAdmin()
CalendarPageViewModel.HasEvents / HasNoEvents:給「今日無事件」空狀態提示用的衍生屬性
CalendarPageViewModel.EventDates:HashSet<DateTime>,在Events被指派時一次算好;給EventDayTemplateSelectorO(1) 查詢用
- 內部欄位
_eventsByDate(ILookup<DateTime, CalendarPoco>):以日為鍵預先 group,SelectedDate變更時 O(1) 過濾
- 「今日無事件」空狀態文字:當所選日期 / 篩選條件下無事件時顯示
變更
TsControl/Calendar/EventDayTemplateSelector.cs:
- 從
Events.Select(...).Any(x => x.預定時間 == content.Date)改為vm.EventDates.Contains(content.Date.Date)- 順帶修掉
預定時間(含時分)對content.Date(午夜)的不對等比較 → 以.Date正規化為日比對TsControl/Calendar/RightSideCalendar.xaml:
- ListBoxItem 內 7 處
ElementName=Grid, Path=DataContext.XxxCommand→ 改用RelativeSource AncestorType=UserControl,不再依賴 root grid 命名- 新增 4 顆
TsToggleButton篩選列(UniformGrid 4 欄)- 新增「今日無事件」空狀態 TextBlock,與 ListBox 互斥顯示
- 移除死碼:
StepTemplate、TaskStepListBoxStyle、EventCardTemplateSelector整段ViewModel/MainWindowPage/CalendarPageViewModel.cs:
-
Events.set內預建_eventsByDate與EventDates,並觸發RefreshFiltered()-
SelectedDate.set移除 LINQ filter;改呼叫RefreshFiltered()-
DisplayDate.set移除if (NeedGetEvents) ...內聯邏輯;改呼叫LoadEventsForMonth(value, force:false)- 新增
RefreshFiltered()/LoadEventsForMonth(monthDate, force)/IsOwnerVisible(poco)三個 private method-
Refresh()從 hack 寫法 (DisplayDate = default; DisplayDate = date;) 改為LoadEventsForMonth(date, force:true)-
已完成Execute/NavigateExecute包 try/catch +TsMsgBox.ShowError;已完成Execute失敗時還原 UI 勾選避免 UI/DB 不一致- 兩個 setter 改為只有值變動才觸發(加
if (_xxx == value) return;),減少不必要的 PropertyChanged- 移除未被任何 XAML 使用的
EventText、LayoutText屬性 與QueryCommandLogicBll/Calendar/CalendarPoco.cs:
-
Get擁有者類別描述()從 if/else 寫死 (0/1/2) 改成委派給Context.EnumManager.EventOwner.GetEventOwner(...).Description,正確處理9 = 系統(之前回空字串)刪除
TsControl/Calendar/EventCardTemplateSelector.cs整檔(XAML 已不再 reference,本次連 selector 一起拿掉)
Breaking Changes
- 無;
Events/SelectedDate/DisplayDate/Refresh()公開介面與行為均維持相容
Refresh()仍會把SelectedDate對齊月初(與原版一致),外部呼叫者 (EventSelfViewModel.OnAfterAudit、EventProjectViewModel.AfterMoverRecord) 行為不變
Migration Notes
- 無 SQL / 設定變更,純 .NET 端重構
- 多語系:toggle 文字以
DisplayMeta[個人 / 部門 / 公司 / 系統]取得,未設定時 fallback 到中文字面值
對使用者的影響
- 圓點正確顯示:右側日曆中,只要該日有事件(不論時間是幾點),日期格底下都會出現灰色圓點。原本只有 00:00 事件才顯示
- 月份切換較順:日曆 render 從 O(N×天數) LINQ 降到 O(1) HashSet 查表
- 可依擁有者篩選:4 顆 toggle 自由切換顯示哪幾類事件
- 管理員專屬:「系統」toggle 僅 admin 可見可選;非 admin 即使資料有系統事件也不會顯示在清單
- 空狀態提示:當天無事件(或被篩選掉)時顯示「今日無事件」
- 錯誤可見:勾選「已完成」或點「導航」失敗時顯示錯誤訊息,不再吞掉
- 擁有者類別篩選:右側日曆下方 4 顆 ToggleButton(個人 / 部門 / 公司 / 系統),多選;預設個人+部門+公司開啟、系統依
-
05-03 remove-commpr2-org-titles ▸
2026-05-03 — 移除 commpr_2 的「單位」「職稱」欄位
摘要
從
Twork_com_vw_commpr_2Model移除單位與職稱兩個欄位,並同步清理上下游:兩個 Source、TodoListPoco 衍生屬性、Emailsender 頁面欄位、多語系設定。刪除
Twork_com_vw_commpr_2Model.單位Twork_com_vw_commpr_2Model.職稱兩個 string property
Twork_com_vw_commpr_2Source與WorkflowStepSource對外曝露的單位職稱property wrapper
TodoListPoco.OrganizationTodoListPoco.Titles衍生屬性與其在SetData(Twork_com_vw_commpr_2Source)/SetData(WorkflowStepSource)中的賦值
Emailsender.xaml中 detail grid 的「單位」「職稱」兩欄
- 多語系:
Common/Lang/Xaml/Emailsender.json與Common/Lang/Model/Twork_com_vw_commpr_2.json內對應 key
變更
無(本次純刪除,無功能調整)。
新增
無。
Breaking Changes
- 凡讀取
Twork_com_vw_commpr_2Source.單位/.職稱、WorkflowStepSource.單位/.職稱、或TodoListPoco.Organization/.Titles的外部程式碼會編譯失敗。
- DB view
twork_com_vw_commpr_2端若仍保留這兩個欄位,目前 Dapper 反射映射會忽略它們,不會炸;建議由 DBA 視情況決定是否同步移除。
Migration Notes
若有外掛或自訂程式需要顯示處理人的單位/職稱,請改從
Context.DescriptionHelper.GetPerdata(處理人編號)即時查詢人事檔取得。 -
05-03 eventitem-status-r-completion-time ▸
2026-05-03 — EventItem 狀態:X → R + 完成時間自動寫入
摘要
twork_skd_eventitem的「執行中」狀態碼從'X'(視覺上像失敗)改為'R'(Running)。已完成 = 'Y'時 SP 自動寫完成時間 = GETDATE()。AutoPilotHelper.ExecuteMethod補完整生命週期:執行前標'R'、成功標'Y'、失敗標'F',這樣執行開始時間 / 完成時間才會被填。詳細決策見 ADR 0013。新增
- 無新增類別;只是把既有的
Twork_skd_vw_eventitemModel.完成時間欄位真的開始用
變更
AutoPilot/AutoPilotHelper.cs::ExecuteMethod:
- 執行前
bll.Update已完成(pkid, "R", DateTime.Now)(標執行中 + 寫 執行開始時間)- 成功 +
執行後完成 == "Y":bll.Update已完成(pkid, "Y")—— SP 收到後自動寫完成時間 = GETDATE()- 失敗:
bll.Update已完成(pkid, "F")- 快取
bll變數,避免重複new CalendarBll(Context)- SQL
TWORK_SKD_UPDATE_EVENT_STATUSprocedure:
-
已完成分支多寫[完成時間] = CASE WHEN @LP_P3 = 'Y' THEN GETDATE() ELSE [完成時間] END- 加
[是否停用] = CASE WHEN @LP_P3 = 'Y' THEN 'Y' ELSE '' END同步行為-
LP_P3預期值文件從'X' / 'Y' / 'F' / ''改為'R' / 'Y' / 'F' / ''LogicBllTests/Calendar/CalendarBllTests.cs:
- 所有
"X"字面 →"R"-
LP_P1assertion:已通知系列改"1"、已完成系列改"2",與目前CalendarUpdateTypeenum 值對齊(已通知=1, 已完成=2)- 測試方法名
..._status_X_...→..._status_R_...docs/admin/scheduler.md:狀態碼表格與範例 SQL 同步更新
刪除
- 無
Breaking Changes
- 狀態字面
'X'退役:production 端 grep 過後沒有 active caller 寫'X',所以技術上沒有任何 client 程式會壞。但若有外部系統(手寫 SQL update、其他程式直接寫 DB)使用'X'標執行中,需配合改為'R'。
Migration Notes
1. SQL Server 端必跑:升級
TWORK_SKD_UPDATE_EVENT_STATUSprocedure```sql
ALTER PROCEDURE [dbo].[TWORK_SKD_UPDATE_EVENT_STATUS]
@LP_P1 varchar(1), -- 1 = 已通知, 2 = 已完成
@LP_P2 varchar(50), -- pkid
@LP_P3 varchar(1), -- 'R' / 'Y' / 'F' / ''
@LP_P4 varchar(20) -- yyyy/MM/dd HH:mm:ss 或 ''
AS
BEGIN
SET NOCOUNT ON;
DECLARE @StartTime datetime = NULL;
IF @LP_P4 <> ''
SET @StartTime = CONVERT(datetime, @LP_P4, 111);
IF @LP_P1 = '1'
UPDATE [twork_skd_eventitem]
SET [已通知] = @LP_P3,
[執行開始時間] = CASE WHEN @LP_P4 = '' THEN [執行開始時間] ELSE @StartTime END
WHERE [pkid] = @LP_P2;
ELSE IF @LP_P1 = '2'
UPDATE [twork_skd_eventitem]
SET [已完成] = @LP_P3,
[執行開始時間] = CASE WHEN @LP_P4 = '' THEN [執行開始時間] ELSE @StartTime END,
[完成時間] = CASE WHEN @LP_P3 = 'Y' THEN GETDATE() ELSE [完成時間] END,
[是否停用] = CASE WHEN @LP_P3 = 'Y' THEN 'Y' ELSE '' END
WHERE [pkid] = @LP_P2;
END
```
2. 歷史資料相容(可選):若資料庫殘留
已完成 = 'X'的 row,可一次性轉換:```sql
UPDATE twork_skd_eventitem SET 已完成 = 'R' WHERE 已完成 = 'X';
```
不轉換也不會壞,只是畫面會繼續顯示
X。3. SchedulerWorker / TsERP 升級至此 commit 後,新觸發的 EventItem 才有
執行開始時間 / 完成時間值。歷史資料一律 NULL,無法回填。對使用者的影響
- EventItem 列表新狀態:
R(Running)取代X,視覺上不再像「失敗 / 取消」
- 完整時間軸有資料:
執行開始時間在每次排程觸發時自動填、完成時間在事件成功時自動填
- 失敗事件可分辨:scheduler 跑失敗的事件
已完成 = 'F',可從 EventProject 列表一眼看出
- EventResultView 模態(同日 2026-05-03 changelog)的 header 看到的時間欄位開始有實際值
- 無新增類別;只是把既有的
-
05-03 eventitem-result-viewer ▸
2026-05-03 — EventItem 執行結果檢視畫面 + AutoPilot 執行GUID
摘要
EventItem(行事曆事件項目,由AutoPilotHelper.ExecuteMethod觸發)跑完後,使用者現在可以從Eventproject明細列右鍵「查看執行結果」,開啟一個動態欄位的檢視畫面,看到該次執行寫進結果表的列。為了支援上述查看,
AutoPilotHelper在每次執行 task 前會自動產生「執行GUID」、寫回 EventItem 的執行guid欄位,並把 task JSON 內所有"{guid}"token 替換成實際 guid(opt-in:只有 template 寫了"{guid}"的欄位才會被替換)。新增
Common/AutoPilot/SchedulePlaceholders.cs:
- 新常數
ExecutionGuid = "{guid}",與既有的Today = "{d}"/PreviousMonthEnd = "{-d1}"同一套 token 模式- 新方法
ReplaceExecutionGuidTokens(JObject json, string executionGuid):把 JSON 頂層 string 屬性內的{guid}換成實際 guidLogicBll/Calendar/CalendarBll.cs::UpdateExecutionGuid(int pkid, string executionGuid, out string msg):read-modify-write EventItem.執行guid(沿用同檔Update()的AdeUploadBll模式)
ViewModel/L.Communication/EventResultViewModel.cs:modal VM,繼承ERPProgramContentWindowViewModel,建構式收IAppContext + Twork_skd_vw_eventitemSource。Load 時走Log_Sys_Exec+Procedure.DARB_GETDATA4,condition執行guid = '<guid>',從 EventItem 的結果表撈整列回來,bindable 為DataTable ResultTable
TsERP/L.Communication/EventResultView.xaml+.xaml.cs:<TsControl:TsView>根,上方 5 個 metadata label(執行方法 / 結果表 / 預定時間 / 執行開始時間 / 執行GUID),下方<telerik:RadGridView AutoGenerateColumns="True" IsReadOnly="True" ItemsSource="{Binding ResultTable}" />
Eventproject.xamldetail TsRadGridView 加 row context menu「查看執行結果」
變更
AutoPilot/AutoPilotHelper.cs::ExecuteMethod:執行前Guid.NewGuid()→CalendarBll.UpdateExecutionGuid(item.pkid, guid)→SchedulePlaceholders.ReplaceExecutionGuidTokens(json, guid)。GUID 是框架統一管的,所有 task type 都會生成;JSON 替換只動明確寫"{guid}"的欄位
AutoPilot/AutopilotMethod_LogSysExec.cs:DefaultParameter["LP_P1"]預設值改為SchedulePlaceholders.ExecutionGuid(即"{guid}");doc summary 說明 token 用法
ViewModel/L.Communication/EventProjectViewModel.cs:加ICommand ViewResultCommand+ViewResultExecute(),handler 開EventResultViewModelmodal;空執行guid/結果表/ 沒選 row 時跳訊息
TsERP/App.xaml:加<DataTemplate DataType="{x:Type communication:EventResultViewModel}"><schedule:EventResultView /></DataTemplate>
刪除
- 無
Breaking Changes
- 無(沒有覆蓋使用者既有設定的行為;GUID 替換是 opt-in token)
Migration Notes
1. 既有 EventItem 的
執行guid欄位都是空的:本次升級之前跑過的歷史紀錄,沒有 guid 可查。檢視畫面會顯示「該事件無執行紀錄,請先執行排程」。沒辦法回填。2. 想接 GUID 的使用者建立的 LogSysExec 排程:在想接 guid 的 LP_Px 欄位填字面值
{guid}(或留 default 的 LP_P1)。框架在執行那一刻會替換成實際 guid。沒填{guid}的欄位完全不會被改動。3. 新建/維護中的 SQL Procedure:要走「LogSysExec → 寫結果表 → viewer 撈」流程的 procedure,請確認:
- 對應的
結果表有執行guid欄位(typevarchar(36)或nvarchar(36))- Procedure body INSERT 結果列時把對應
LP_Px(接{guid}那個)寫進執行guid欄位4. EventItem.結果表 由使用者建 EventItem 時填:框架不會自動產生這個值,是 EventItem template 的設定。
對使用者的影響
- 新功能:在「事件項目」頁面(Eventproject)的明細列上右鍵就能看到「查看執行結果」。點下去開模態視窗,顯示該次執行的 metadata(執行方法 / 結果表 / 時間 / GUID)+ 結果表撈出來的對應列
- 欄位是動態自動產生的:依
結果表的 schema 即時組欄位;read-only,不能直接編輯
- 沒跑過的事件:右鍵點下去會跳訊息「該事件無執行紀錄,請先執行排程」
- GUID 對使用者是顯式 opt-in:在 template 參數放
{guid}才會收到;不放就跟之前完全一樣
-
05-03 autopilot-task-unify ▸
2026-05-03 — IAutoPilotTask 收攏參數產生與顯示
摘要
把排程「執行」與「參數產生」兩條原本互相不知道對方存在的程式碼路徑收攏到
IAutoPilotTask一個介面下。AutoPilotGenerator廢除,參數格式統一改 JSON,SelectedMethod改成從 registry 反查、setter 補設執行方法。詳情見
docs/decisions/0012-autopilot-task-unify.md。新增
IAutoPilotTask.BuildScheduledParameter(JObject, DateTime)—— 把 template 的參數骨架(含{d}/{-d1}placeholder)展開成 eventitem 的實際參數。
IAutoPilotTask.FormatDisplay(JObject)—— 給eventitem.參數顯示用的人話字串。
Common/AutoPilot/SchedulePlaceholders.cs—— 集中{d}、{-d1}的解析。
- 三個新 task:
Bcurrenm_FxRate、Pivot_Get、Word_MailMerge。AutoPilotRegistry現在註冊全部 7 個 task(原本只註冊 1 個)。
變更
IAutoPilotTask子類的Name屬性統一改用英文 C# 識別字風格:
-
SliyAutoPilot_CloseBook.Name"關帳"→"CloseBook"-
Balance_Balance.Name"CreateBalanceSheet"→"BalanceReport"-
Paymntpq_Query.Name"CreateEmail"→"PaymntpqQuery"-
SliyAutoPilot_CloseBook.ProgramClass修為Common.ProgramClass.SLIY.Name(原為 null)。- 中文顯示走多語系
DisplayName,key 是ProgramClass.AUTOPILOTMETHOD。Twork_skd_vw_eventtemplatedSource.SelectedMethod:
- getter 從
_registry.GetTask(單據別, 執行方法)反查(原本只回傳快取欄位)。- setter 補設
執行方法 = value.Name,原本只設單據別與參數。- setter 改走
原始Jsonsetter(與TranslateJson()同一條路),不再有兩條互相打架。-
單據別/執行方法setter 加上OnPropertyChanged(nameof(SelectedMethod))。Twork_skd_vw_eventtemplatedSource.CreateEventItem改用task.BuildScheduledParameter+task.FormatDisplay。
刪除
Model/AutoPilotGenerator.cs整支移除。
AutoPilot/AutoPilot.cs整支移除;FxRate/GetPivot/GetWordMailMerge三個 method 的邏輯 inline 進對應 task 的Execute。
AutoPilot/AutoPilotHelper.cs內的AutoPilotResult死碼私有 method 與註解掉的 CSVExecuteMethodoverload 一併清掉。
AutoPilotTask.GetParameterFormula移除(原本宣告JObject卻沒 return 的壞掉 stub)。
Breaking Changes
1. DB 中
執行方法欄位的值需要更新。原本存關帳、CreateEmail、CreateBalanceSheet等舊值的 row,registry lookup 會 miss,排程不會跑。2.
參數欄位 CSV 格式變 JSON。原本"Y,2026/05/03"這種要改成{"CloseType":"Y","CloseDate":"2026/05/03"}。Migration Notes
UPDATE twork_skd_vw_eventtemplated SET 執行方法 = 'CloseBook' WHERE 執行方法 = '關帳'; UPDATE twork_skd_vw_eventitem SET 執行方法 = 'CloseBook' WHERE 執行方法 = '關帳'; UPDATE twork_skd_vw_eventtemplated SET 執行方法 = 'BalanceReport' WHERE 執行方法 = 'CreateBalanceSheet'; UPDATE twork_skd_vw_eventitem SET 執行方法 = 'BalanceReport' WHERE 執行方法 = 'CreateBalanceSheet'; UPDATE twork_skd_vw_eventtemplated SET 執行方法 = 'PaymntpqQuery' WHERE 執行方法 = 'CreateEmail'; UPDATE twork_skd_vw_eventitem SET 執行方法 = 'PaymntpqQuery' WHERE 執行方法 = 'CreateEmail';參數欄位 CSV → JSON 建議讓使用者進排程模板編輯介面重新選一次「執行方法」載入新的預設骨架(DefaultParameter)後再填值。多語系
AUTOPILOTMETHOD多語系檔需要補上新Name對應的中文翻譯(CloseBook→關帳、BalanceReport→資產負債表等),讓 ComboBox 顯示維持中文。 -
05-03 addevent-task-picker ▸
2026-05-03 — 排程模板:合併「單據別 + 執行方法」並加上參數提示
摘要
AddEventContent.xaml的「自動化參數」區塊原本要使用者先選「單據別」再選「執行方法」兩個下拉選單,現整併成一個「執行項目」下拉,顯示文字為「程式名稱 - 方法名稱」。同時在「參數」TextBox 下方加上占位符說明,讓使用者直接看到{d}/{-d1}等可用 token,不必去翻SchedulePlaceholders原始碼。新增
Twork_skd_vw_eventtemplatedSource.AutoPilotTaskOptions— 把 registry 內所有IAutoPilotTask與使用者權限可瀏覽的ProgramClass做交集,包成AutoPilotTaskOption(含Display = "{程式名稱} - {方法 DisplayName}")。
Twork_skd_vw_eventtemplatedSource.SelectedTaskOption— 提供給合併後的 ComboBox 雙向綁定;setter 直接轉發到SelectedMethod,由原有 setter 同步寫入單據別/執行方法/原始Json。
- 「參數」TextBox 下方新增黃底提示框,列出占位符對照表,並動態顯示目前選定方法的
Description(例:「本項目:關帳」)。
- 參數 TextBox 加上
AcceptsReturn=True與FontFamily=Consolas,讓 JSON 多行顯示與閱讀更容易。
變更
- 「單據別 / 執行方法」兩個下拉合併為「執行項目」一個下拉。
- 「執行後完成」「是否自動執行」整理成同一列,標籤改為「執行旗標」並改用 CheckBox 內建 Content 顯示文字。
刪除
無(
AutoPilotProgramClassList/AutoPilotMethodList/SelectedMethod/UpdateMethodListByProgramClass仍保留,內部CreateEventItem流程未變動)。Breaking Changes
無。
單據別與執行方法仍以原本格式寫入 DB;只是 UI 改成由單一下拉一次設定。Migration Notes
無需 DB 或設定檔遷移。
- 既有資料的
單據別/執行方法載入後會自動 round-trip 為對應的SelectedTaskOption。
- 若 registry 內某個 task 的
ProgramClass不在使用者的權限表內,該選項不會出現在下拉中(與舊版「單據別必須先在權限表」一致)。
-
05-02 readme-setup ▸
2026-05-02 — 新增 README 與新機器初始設定指引
摘要
repo 根目錄新增
README.md,集中記錄新機器(含 CI)首次設定 Telerik 私有 NuGet 認證、Telerik 授權檔位置、Telerik MCP tools 安裝步驟。同時把.tools/加入.gitignore。新增
README.md:新機器初次設定流程
- 推薦用
NuGetPackageSourceCredentials_telerik環境變數(Username=...;Password=...)配置 Telerik NuGet 憑證,而非寫進NuGet.Config或dotnet nuget update source --store-password-in-clear-text- Telerik 授權檔位置
%APPDATA%\Telerik\telerik-license.txt-
dotnet tool update --tool-path ./.tools Telerik.WPF.MCP/Telerik.Documents.MCP安裝指令- 常用 build / test / publish / mkdocs 指令彙整
變更
.gitignore:新增.tools/,避免把 dotnet local tool 的二進位與dotnet-tools.json帶進版控
對使用者的影響
- 終端使用者無感
- 開發者 / 新進工程師:新機器只要設一次 user-level 環境變數
NuGetPackageSourceCredentials_telerik,就能 restore Telerik 套件、安裝 MCP tools;不需動NuGet.Config,可避免不小心把帳密 commit 進 repo
- CI/CD:同樣以 secret env var 注入
NuGetPackageSourceCredentials_telerik即可,不需另外建立 credential file
Migration Notes
舊有開發機若先前已透過
dotnet nuget update source telerik --username ... --password ... --store-password-in-clear-text把帳密寫進%AppData%\NuGet\NuGet.Config,建議:1. 設定 user-level 環境變數
NuGetPackageSourceCredentials_telerik2. 從
%AppData%\NuGet\NuGet.Config移除<packageSourceCredentials>區塊內的 telerik 條目3. 重開終端確認
dotnet restore仍能通過無此需求者不必處理。
-
05-02 bom-flow-tree-tab ▸
2026-05-02 — Bom_flow 新增「製程明細(樹狀)」tab + 修 RadDiagram 不顯示
摘要
D.Bom\Bom_flow多一個 tab「製程明細(樹狀)」,原 tab 不動;同時修掉「流程圖圖形」tab 內 RadDiagram 因樣式覆寫導致連線/節點不顯示與一連串 binding error 的問題。新增
- 新 tab「製程明細(樹狀)」(
DisplayMeta[製程明細(樹狀)]),位置:原「製程明細表」之後、「多階材料用量清單」之前
- 用
telerik:RadTreeListView+TreeListViewTableDefinition以組件編號 → 品號自連結建階層- 顯示欄位:品號 / 品名 / 生產部門 / 部門簡稱 / 數量 / 單位 / 損耗率 / 標準工時 / 整備工時 / 移轉天數 / 注意事項 / 生效日期 / 失效日期 / 零件編號 / 顯示序號 / 組件編號
DisplayProcessingPoco.Children屬性(in-memory,給 tree 用,不參與 DB mapping)
Bom_flowViewModel.DisplayProcessingTreeRoots屬性 +BuildTree()私有方法,跟SelectedPartNo連動
變更
RadDiagram.ShapeStyle/ConnectionStyle加BasedOn="{StaticResource {x:Type telerik:RadDiagramShape/Connection}}",保留主題 ControlTemplate
- 修掉 4 條
EndBezierPoint / StartPoint / StartBezierPoint / EndPoint對LineSegment.Point/PathFigure.StartPoint的 binding error- 修掉「流程圖圖形」tab 內 RadDiagram 沒畫出節點/連線的問題
2026-05-03 後續
- 樹狀 tab 把查詢組件本身當成第一層唯一根節點,原本的第一層子項全部掛在它底下,便於整體展開檢視
- 為了能「合成」一個根節點,
DisplayProcessingPoco多一個只吃IAppContext的建構子(原(TMP製程表, IAppContext)不變)-
BuildTree多吃一個IAppContext參數刪除
- 無(原「製程明細表」tab 與其雙擊展開邏輯完全保留)
Breaking Changes
- 無
Migration Notes
- 終端使用者:自動多一個 tab,無操作變更
- 開發者:新 DisplayMeta key
製程明細(樹狀)兩份 JSON 都已更新
-
Common\Lang\Xaml\Bom_flow.json-
TsERP\Lang\Xaml1\Xaml.json- 重 build 前要先關掉執行中的
TsERP.exe,否則bin/Debug/net8.0-windows/*.dll會被鎖住複製失敗(與本次改動無關,是 dev 環境常見現象)
- 新 tab「製程明細(樹狀)」(
📅 2026 年 4 月 (10 篇)
-
04-29 batchedit-itemsbindingmanager ▸
2026-04-29 — BatchEditBll 改用 ItemsBindingManager + EF ChangeTracker
摘要
BatchEditBll(批次編輯 BLL 抽象基底;目前唯一實作為SecretBll,用於權限批次設定)從原本的「adeDataBackup自製 diff +AdeUploadBll.UpdateData」改為「ItemsBindingManager集中管理 + EF ChangeTracker 偵測變動 +UploadToSql」。詳細決策見 ADR 0010。新增
Model/Source/A.SystemData/PrgsctBatch.cs:從LogicBll/Other/Secret/PrgsctBatch.cs搬過來(namespace 改Model),兩個 in-memory only 屬性使用者代號/使用者姓名加[NotMapped]
Model/LocalDbContext.cs新增DbSet<PrgsctBatch> PrgsctBatch:OnModelCreating用HasBaseType((Type)null).ToTable("PrgsctBatch")跟父類別 entity 解綁 + 對到獨立 SQLite 表PrgsctBatch
DataManager<T>.SeedFromRemote(IEnumerable<T> data):取代/重寫先前的DirectSaveToSqliteAndLoad;主動清IsDirty=false/IsNew=false/增刪修=""後 upsert 到 SQLite 並Load()接管 EF tracker
變更
LogicBll/Ade/Transfer/BatchEditBll.cs:
- 抽象屬性
IList[] EditSource→ItemsBindingManager-
Save()流程:UpdateBefore→SetUploadData(保留為 hook,預設無動作)→ItemsBindingManager.SaveAll()→ItemsBindingManager.UploadToSql(Status, out msg)- 移除壞掉的
adeDataBackup.DataBackup/adeDataBackup.GetUpdateData殘留LogicBll/Other/SecretBll.cs:
- 改實作
protected sealed override ItemsBindingManager ItemsBindingManager { get; }- 新增
private readonly DataManager<PrgsctBatch> prgsctData-
PrgsctBatchproperty 從List<PrgsctBatch>(auto-property)改為IList<PrgsctBatch>直接回傳prgsctData.ObservableCollection(live view)-
SqlQuery改用prgsctData.SeedFromRemote(list),不再設EditSource- 移除
using LogicBll.Other.Secret;(不再存在)LogicBll/ItemsBindingManager.cs:
-
DirectSaveToSqliteAndLoad改名SeedFromRemote、加清 dirty/IsNew/增刪修 邏輯、移除冗餘 try/finally-
DataManager.Save()加if (_db == null) return;null guard,避免對未Load/SeedFromRemote的 manager 呼叫SaveAll時 NRELogicBll/LocalDbService.cs+Common/Context/ILocalDbService.cs:UpsertBatchMarkDirty<T>→UpsertBatch<T>(原名誤導;實際上不主動標 dirty,dirty 是由 caller 端先設好)
ViewModel/A.SystemData/PermissionSettingViewModel.cs:
- 移除
using LogicBll.Other.Secret;-
PrgsctBatch型別List<PrgsctBatch>→IEnumerable<PrgsctBatch>(XAMLItemsSourcebinding 不受影響)刪除
LogicBll/Other/Secret/整個資料夾(內只有PrgsctBatch.cs,已搬到 Model)
BatchEditBll.EditSource(抽象屬性)
Breaking Changes
PrgsctBatch型別改隸屬 Model 專案 / namespace 從LogicBll.Other.Secret改為Model:所有 caller 的using需要改。本次掃過的:SecretBll.cs、PermissionSettingViewModel.cs。其他若有依賴需自行調整
BatchEditBll子類別必須提供ItemsBindingManager而非EditSource:目前唯一 subclassSecretBll已調整。任何下游若在自寫 BatchEdit subclass 需重構
DataManager.SeedFromRemote取代DirectSaveToSqliteAndLoad:方法名變更,外部 caller 需更名
UpsertBatchMarkDirty→UpsertBatch:ILocalDbServiceinterface 上的方法名變更
SecretBll.PrgsctBatch不再可寫:原本是{ get; set; }的List<PrgsctBatch>,現在是只讀的IList<PrgsctBatch>(指向DataManager.ObservableCollection)。caller 不能再SecretBll.PrgsctBatch = ...或對它呼叫Add/Remove
Migration Notes
1. 第一次跑這版的 client 端 SQLite:本機資料庫多了一張
PrgsctBatch表- 如果使用
EnsureCreated/ migration:自動處理- 如果手動管理 schema:需建立
PrgsctBatch表,schema 同Prgsct12. caller 的
using升級:所有using LogicBll.Other.Secret;改為using Model;3.
SecretBll.PrgsctBatch用法檢查:以前可能透過此 property 對 listAdd/ 重新賦值,現在這條路被擋掉;若有需求請改透過DataManagerAPI(AddItem/Clear等)4. 若有自寫
BatchEditBllsubclass:- 改實作
ItemsBindingManager抽象屬性(建構子建好後Register<T>())-
SqlQuery把EditSource賦值改為對應DataManager.SeedFromRemote(list)-
WhenSqlQueryTrue等 hook 維持原本 mutation 邏輯即可(mutation 落在dm.ObservableCollection的 instance 上,EF 會自動偵測)對使用者的影響
- 終端使用者無 UI 操作改變
- 權限批次設定(PermissionSetting / SECRET)的「儲存」行為從「diff 我自己算」變「EF 自動判定」;只有真的有變更的 row 才會送上去。對使用者體感應該是一致或更精準
- 第一次跑新版時若 SQLite 沒升級到含
PrgsctBatch表,畫面會在查詢時拋例外;DBA / 升級腳本要先處理本機 schema
-
04-28 scheduler-worker ▸
2026-04-28 — TimerBll 拆出獨立排程 exe(TsERP.SchedulerWorker)
!!! note "後續更新"
本 changelog 描述的 SP
TWORK_SKD_NOTIFYEVENT在 2026-05-04 已被拆成TWORK_SKD_GET_PENDING_NOTIFY與TWORK_SKD_GET_PENDING_AUTOEXEC兩支單一職責 SP,並修正「停用應為是否停用」與「殭屍判定狀態碼還用'X'沒對齊 ADR 0013」兩個積累 bug。詳見 ADR 0015 與 2026-05-04 changelog。摘要
行事曆通知與 AutoPilot 自動化批次的 5 分鐘排程從 WPF App 內的
DispatcherTimer(LogicBll/Timer/TimerBll.cs)拆出來,做成獨立 console exeTsERP.SchedulerWorker,由 Windows 工作排程器每 5 分鐘觸發。從此通知與 AutoPilot 不再依賴「有人開著 ERP」才會跑。詳細決策見 ADR 0009。新增
TsERP.SchedulerWorker/整個專案(net8.0-windows、UseWPF=true、OutputType=Exe)
-
TsERP.SchedulerWorker.csproj-
Program.cs:top-level entry,Global\TsERP_Schedulernamed Mutex 防重疊,exit code0=成功 /1=失敗 /2=被 mutex 擋-
SchedulerJob.cs:取代TimerBll,提供Task<int> RunOnceAsync()-
SchedulerSettings.cs:config POCO-
SchedulerUser.cs:IUserheadless 實作(UserId=SCHED)-
appsettings.json:Scheduler區段(Databases/AlertRecipients/ZombieTimeoutMinutes/BatchSize/DefaultSrvdbid)- 新 SP
TWORK_SKD_UPDATE_EVENT_STATUS:原子化更新事件狀態 + 時間戳
- 行事曆事件「執行中」狀態
'X':已通知/已完成欄位多一個值,配合新執行開始時間欄位做殭屍紀錄回收
變更
LogicBll/Calendar/CalendarBll.cs:新增 3-arg 多載Update已通知(pkid, status, DateTime?)與Update已完成(pkid, status, DateTime?),支援'X'狀態與時間戳。原 2-arg 簽章保留
ViewModel/PageControl/MainWindow/MainWindowBtnTimerViewModel.cs:拿掉TimerBll欄位(VM 殼保留,避免影響 XAML binding)
TsERP.sln:加入TsERP.SchedulerWorker專案
- SP
TWORK_SKD_NOTIFYEVENT行為改變:
- 加
TOP 20、ORDER BY ASC:每次只拿 20 筆- QueryType=2 移除原本 1 小時時間窗
- filter 改為
已完成 NOT IN ('Y','F')+ 殭屍回收('X'超過ZombieTimeoutMinutes視為前一輪 crash 自動拉回)- 失敗事件處理改變:標
'F'後不再自動重跑,需要管理員手動把狀態改回'N'或空
刪除
- 無(
LogicBll/Timer/TimerBll.cs保留為 fallback,未來確認穩定後再評估移除)
Breaking Changes
- DB schema 變更:
twork_skd_eventitem(base table)需新增執行開始時間 datetime NULL欄位
- SP
TWORK_SKD_NOTIFYEVENT行為改變:見上方「變更」段;如有外部程式直接呼叫此 SP 並依賴原 1 小時時間窗或全部撈出的行為,需重新驗證
- 新增 SP
TWORK_SKD_UPDATE_EVENT_STATUS:CalendarBll 新多載呼叫;DB 端必須先建立此 SP 才能升級 ERP / SchedulerWorker
- 失敗事件不再自動重跑:標
'F'後跳過,需要管理員手動處理;先前依賴「自動重試直到成功」的事件流程需要調整 SOP
Migration Notes
1. DBA 端:對每個 darb DB 執行
-
ALTER TABLE twork_skd_eventitem ADD 執行開始時間 datetime NULL-
ALTER PROCEDURE TWORK_SKD_NOTIFYEVENT(加TOP 20、ORDER BY ASC、移除 1 小時時間窗、改 filter 為已完成 NOT IN ('Y','F')+ 殭屍回收)-
CREATE PROCEDURE TWORK_SKD_UPDATE_EVENT_STATUS2. Build & publish
TsERP.SchedulerWorker到 server(建議放D:\TsERP\Scheduler\,self-contained 發布)3. 建專屬服務帳號(例如
TsERP\schedsvc),加入本機 Administrators 群組,密碼設「永不過期」4. 建立 Windows 工作排程:
- 觸發:每 5 分鐘
- 動作:執行
TsERP.SchedulerWorker.exe- 設定:「不要啟動新執行個體」(與 named mutex 雙保險)
- 帳號:上一步建立的服務帳號,勾「不論使用者是否登入皆執行」
5. (可選)監控建議:
- Mailgun dashboard 看寄信統計變化
- SQL Server agent log 看 SP 觸發次數
- 工作排程器歷程記錄看 exit code(
0=成功 /1=失敗 /2=被 mutex 擋)- 定期巡檢
已完成 = 'F'的事件,避免長期堆積對使用者的影響
- 終端使用者無 UI 操作改變
- 行事曆事件通知與 AutoPilot 觸發改由 server 端排程,不再受「有人開著 ERP」影響;下班與週末時段通知也會照常發送
- 若事件第一次失敗(
'F'),不會再自動重試,需聯繫系統管理員處理
-
04-24 mold ▸
2026-04-24 — D.Bom 新增「模具資料表維護」模組
摘要
D.Bom 工程資料模組新增「模具資料表維護」頁面,提供模具主檔(
mold)、品號明細(moldmno)、管制紀錄(moldctrl)三張表的查詢/新增/編輯/刪除,加上「償卻重算」與「Excel 匯出」兩個專屬動作。償卻金額計算統一走 SPDARB_QRY_MOLD,避免畫面、報表、匯出三處邏輯漂移。詳細決策見 ADR 0008。新增
- D.Bom → 模具資料表維護:完整 CRUD + 償卻重算 + Excel 匯出
- 主檔含模具編號、圖號、開模廠商、模具費用、基準/償卻台數、起始分攤日等 67 欄
- 品號明細維護該模具對應的客戶品號與內部品號
- 管制紀錄維護模具維修/送修/報廢等事件時序
-
重算償卻:統一呼叫DARB_QRY_MOLD更新模具分攤費-
Excel 匯出:逐筆呼叫DARB_QRY_MOLD匯出全部模具(非僅當前查詢結果)- 手冊頁:
docs/D-Bom/mold.md
變更
TsERP/Lang/TableMap.json:修正"moldctrl"原本錯誤對應到自己的問題,改為對應"twork_bom_vw_moldctrl";新增"mold"→"twork_bom_vw_mold"、"moldmno"→"twork_bom_vw_moldmno"映射
TsERP/Lang/ClassAliasMap.json:新增Twork_bom_vw_moldctrl{Model,Source}完整別名;移除舊的Moldctrl{Model,Source}短名別名(原短名會跟未來可能加入的moldctrl實體表衝突)
刪除
ClassAliasMap.json中舊的MoldctrlModel/MoldctrlSource短名別名
Breaking Changes
- 外部整合若依賴
moldctrl短名別名:透過ClassAliasMap反射取型別的程式碼(例如自訂報表、整合腳本),若用MoldctrlModel/MoldctrlSource會取不到,需改成完整名Twork_bom_vw_moldctrlModel/Twork_bom_vw_moldctrlSource
Migration Notes
- 升級後如使用外部整合依賴
moldctrl表名別名,請改用完整twork_bom_vw_moldctrl
- DB 端需確認
DARB_QRY_MOLD、DARB_GETDATA4SP 皆存在於目標環境(多數既有環境已部署)
- 首次開啟頁面若顯示權限不足,請檢查使用者是否具備
D-Bom-Mold相關動作權限
- 使用 Excel 匯出前建議先確認模具筆數;超過 5000 筆時匯出時間會隨筆數線性增加
-
04-24 bom-flow-diagram-tab ▸
2026-04-24 — Bom_flow 新增「流程圖(圖形)」tab
摘要
D.Bom\Bom_flow多一個 tab「流程圖圖形」,用 Telerik RadDiagram 把 BOM 樹渲染成節點 + 連線圖,提供放大縮小、垂直/水平切換、自動縮放等互動。新增
- 第 4 個 tab「流程圖圖形」(
DisplayMeta[流程圖圖形]),位於 Bom_flow 右側 TabControl 的最末
- Toolbar 5 顆按鈕:放大、縮小、自動縮放、垂直排列、水平排列、重新排版
- 節點形狀自動切換:
- 根節點(查詢組件):深色圓角矩形
- 物料節點:白底矩形
- 製程節點:淺黃底橢圓
- 每個節點顯示 4 行:品號/部門工程 / 品名 / 數量單位或工時 / 層數+上階+序號
變更
- 無
刪除
- 無(原 90 欄「流程圖」tab 完全保留)
Breaking Changes
- 無
Migration Notes
- 終端使用者無操作改變;開新 tab 自動出現
- 開發者:若要新增 DisplayMeta key,兩份 JSON 都要更新:
-
Common\Lang\Xaml\Bom_flow.json(Debug fallback 來源)-
TsERP\Lang\Xaml1\Xaml.json(Release 來源) - 第 4 個 tab「流程圖圖形」(
-
04-22 velopack-updating-window ▸
2026-04-22 — Velopack 自動更新加上「正在更新」提示視窗
摘要
Velopack 自動更新流程原本完全無聲:啟動後背景檢查、背景下載、下載完直接
ApplyUpdatesAndRestart關閉重開,使用者體感像是登入畫面正在操作時突然被踢掉。現在在發現更新後顯示一個小型 Topmost 視窗,告知使用者「正在下載更新」與進度百分比,下載完成後顯示「即將重新啟動」再執行ApplyUpdatesAndRestart。新增
TsERP/UpdatingWindow.xaml/.xaml.cs:380×130 無邊框置中視窗
-
Topmost="True"、ShowInTaskbar="False"、ResizeMode="NoResize"、無 caption- 一行狀態文字 + 不定/定量進度條
- 公開方法:
SetStatus(string)/SetProgress(int)(呼叫SetProgress時進度條切為定量模式)變更
TsERP/App.xaml.csCheckForUpdatesAsync:偵測到更新時顯示UpdatingWindow
- 發現更新 → 狀態文字:「發現新版本,正在下載更新...」
- 下載進度回呼 → 「正在下載更新(N%)...」+ 進度條填色
- 下載完成 → 「更新下載完成,即將重新啟動...」
-
ApplyUpdatesAndRestart(update)關閉 App,視窗隨程序結束消失- 例外路徑會 Dispatcher 關閉視窗,避免 UI 殘留
- 改用
DownloadUpdatesAsync(update, progress)重載(Velopack 0.0.1298 支援)刪除
- 無
Breaking Changes
- 無(行為變化屬於 UX 提示,不影響更新結果或版本流程)
Migration Notes
- 使用者端無需動作,下次自動更新即生效
- 已知限制:
ApplyUpdatesAndRestart觸發的 VelopackUpdate.exe在切換過程仍可能短暫閃現其自身 UI,本次調整不處理該閃窗。如需完全無縫,需改走WaitExitThenApplyUpdates並搭配外部重啟腳本,成本較高,暫不納入
- 若 debugger 附加中(
Debugger.IsAttached),維持原本略過更新流程的行為,開發環境不會看到此視窗
-
04-22 aiquery-table-whitelist ▸
2026-04-22 — AIQuery 加上表名白名單驗證
摘要
AIQuery 的
TWORK_AI_QUERYSP 在執行前多做一層「FROM/JOIN 後的表名必須登記在_ai_schema」的驗證,同時強化 Claude system prompt,禁止使用sys.*、INFORMATION_SCHEMA.*、以底線開頭的系統表與 CTE。目的在防止 AI 幻覺或 prompt injection 寫出白名單外的查詢。詳細決策見 ADR 0007。新增
SqlBI/TWORK_AI_QUERY.sql:新增步驟 3.5「白名單檢查」
- 掃描 SQL 中
FROM與JOIN後的表名 token- 去掉
[]與schema.前綴後,逐一與_ai_schema.sql_name比對- 任一不符即
RAISERROR並寫入_ai_query_log,錯誤訊息:「查詢包含不在白名單 (_ai_schema) 的資料表,已被拒絕」變更
LogicBll/AI/AIQueryBll.csBuildSystemPrompt:system prompt 新增三條規則
- 嚴禁查詢
sys.*、INFORMATION_SCHEMA.*、任何以底線開頭的系統表- 超出白名單的查詢請求應拒絕並說明,不得自行臆測表名
- 禁止使用 CTE (
WITH ... AS),需用子查詢或 JOIN 改寫刪除
- 無
Breaking Changes
- 使用 CTE 的舊查詢會被擋下:若既有流程或 AI 回答慣例會使用
WITH ... AS,現在會被 SP 回「不在白名單」錯誤。已透過 prompt 指引 Claude 改用子查詢/JOIN
- 字串常數含特定模式可能誤殺:
WHERE 備註 LIKE '%FROM XX%'之類、字串內剛好包含FROM的查詢,token 抽取會誤判。若遇到可調整問法
Migration Notes
- DB 端要執行
SqlBI/TWORK_AI_QUERY.sql(CREATE OR ALTER PROCEDURE)套用新版 SP
_ai_schema表的維運更關鍵:要讓 AI 能查新表,必須先在_ai_schema登記,否則即使有 SELECT 權限也會被 SP 擋下
- 使用者若反映「AI 以前能回答、現在說被拒絕」,先查
_ai_query_log.執行結果:
- 「查詢包含不在白名單」→ 表名未登記 → 補
_ai_schema- 「偵測到不允許的 SQL 語法」→ 關鍵字黑名單擋(維持既有行為)
-
04-20 velopack-upload-incremental ▸
2026-04-20 — Velopack 上傳改為逐檔增量
摘要
release-velopack.ps1的上傳邏輯從az storage blob upload-batch --overwrite(每次全覆蓋)改為先查遠端清單、逐檔決定 NEW / OVER / SKIP。每次發布頻寬從 ~970MB 降至 ~360MB(約 60% 節省)。同時修掉 PS 5.1 +$ErrorActionPreference='Stop'對 az CLI stderr 警告過敏的問題。詳細決策見 ADR 0005。新增
- 無
變更
TsERP/release-velopack.ps1上傳區塊:
- 上傳前先
az storage blob list取得遠端 blob + size map- 逐檔決策:遠端沒有 → upload;遠端有 + 是 nupkg → skip;遠端有 + size 相同 → skip;其他 → overwrite
- az 呼叫包在
$ErrorActionPreference='Continue'的 try/finally,避免 az CLI 寫 stderr 的 info/warning 被 PS 5.1 升級為NativeCommandError終止 script- 個別
az storage blob upload加--only-show-errors抑制雜訊- Console 輸出格式:每檔一行
NEW/OVER/SKIP <name> (<size>),最末印統計NEW x / OVER y / SKIP z刪除
upload-batch --overwrite單次呼叫(被逐檔 upload 取代)
- 中途嘗試過的
az storage blob sync版本(依賴 AzCopy、使用者機器 DNS 被擋 → 失敗退回)
Breaking Changes
- 無(遠端 container 內容與 upload-batch --overwrite 結果等價)
Migration Notes
- 使用者端無需動作
- 發布端改動已在
release-velopack.ps1,下次執行自動生效
- 若未來 Velopack 在
Releases/新增其他「每版都改內容、檔名固定」的檔案類型,現有 size 比對邏輯自動處理;若新增「每版檔名改、內容固定」的類型則視同 new file 上傳、行為正確
- 若未來容器 blob 數量成長到 10000+,
az storage blob list需評估分頁(目前單次呼叫 return 完整清單)
-
04-20 velopack-sign-exe-only ▸
2026-04-20 — Velopack 簽章只簽 EXE
摘要
release-velopack.ps1的vpk pack加上--signExclude '.*\.dll',發布時只簽主程式 EXE,不再簽所有內部 DLL。發布簽章時間從 ~7 分鐘縮短為數秒,USB token PIN 彈窗從 60+ 次降至 2–3 次。詳細決策見 ADR 0004。新增
- 無
變更
TsERP/release-velopack.ps1:vpk pack參數新增--signExclude '.*\.dll'
- 僅在
-SkipSign未指定時生效- 實際被簽的檔案:
TsERP.exe+ Velopack 產出的Setup.exe/Update.exe- 本專案各 DLL(
Common.dll/ViewModel.dll/LogicBll.dll/Model.dll/TsControl.dll/AutoPilot.dll/ 各領域模組)不再簽章刪除
- 無
Breaking Changes
- 無(主 EXE 仍簽章,SmartScreen 發行者顯示不變)
Migration Notes
- 使用者端無需動作,下次 Velopack 自動更新即套用
- 若未來遇到 AppLocker / WDAC 嚴格環境擋未簽 DLL,走 publisher allowlist 或 hash allowlist 處理;尚無此類客訴
- 若未來要改為全面簽章但保留速度,評估遷移至 Azure Trusted Signing(見 ADR 0004 Alternatives Considered)
-
04-20 velopack-release-pipeline ▸
2026-04-20 — Velopack 發布管線
摘要
新增 Velopack 一鍵發布腳本,整合版號遞增、publish、簽章、Azure 上傳、git commit。詳細決策見 ADR 0003。
新增
TsERP/release-velopack.ps1:Velopack 發布主腳本
- 自動把 csproj 的
<VelopackVersion>patch 段 +1-
dotnet publish->vpk download->vpk pack(USB 硬體簽章)->az storage blob upload-batch->git commit- 四個逃生開關:
-SkipDownload(首次發布)、-SkipSign(USB 未插)、-SkipUpload(本地驗證)、-SkipCommitTsERP.csproj新增<VelopackVersion>1.0.1</VelopackVersion>標籤
變更
- 無(既有 ClickOnce 腳本
autodeploy.ps1/darbtestDeploy.ps1完全不動)
刪除
MainWindow.xaml.cs的CheckForUpdate()方法與其在Window_Loaded的呼叫
- 原本會彈「發現新版本 / 是否立即重啟套用」MessageBox
- 與
App.xaml.cs:63Startup 事件裡的靜默自動更新並行執行,兩個UpdateManager同時寫入%LocalAppData%\YanYue.ERP\packages\會產生 file lock 錯誤- 保留
App.xaml.cs的靜默版(啟動時檢查 → 下載 →ApplyUpdatesAndRestart),使用者完全不介入- MainWindow.xaml.cs 不再 using
Velopack/Velopack.Sources,MessageBoxalias 也移除(除了 CheckForUpdate 沒別處用)
Breaking Changes
- 無(Velopack 更新通道
darb-vpk目前僅有App.xaml.cs讀取,使用者端安裝的 ClickOnce 版不受影響)
Migration Notes
首次發布步驟
darb-vpkcontainer 若尚無RELEASES檔,第一次跑要加-SkipDownload:cd C:\ERPV2\TsERP .\release-velopack.ps1 -SkipDownload之後每次發布:
.\release-velopack.ps1前置需求
1. 已安裝
dotnetSDK、vpk全域工具(dotnet tool install -g vpk)、azCLI、git2. USB 硬體簽章 token 已插上(憑證指紋
66AE9BC65D5516A65B8F4860F4F815F56F5CFBFB)3. PowerShell 執行原則若限制未簽章腳本,需用
Set-AuthenticodeSignature幫release-velopack.ps1簽一次(同autodeploy.ps1的做法)手動介入情境
- pack 或 upload 失敗、csproj 版號已寫回但還沒 commit:直接重跑,失敗前的新版號會繼續被用
- git commit 之後才發現 upload 有問題:
git reset --soft HEAD~1退回 commit,處理完再重推
版本號升級
- 預設 patch +1:
1.0.1→1.0.2→1.0.3…
- Major / Minor bump 需要時直接編 csproj 的
<VelopackVersion>(腳本下次執行會從該值繼續 +1)
-
04-17 operator-alignment ▸
2026-04-17 — 查詢條件運算子對齊 Telerik
摘要
全系統查詢畫面的「運算子」下拉重新整理,文字、行為與排序全部對齊 Telerik RadGridView 內建 filter。詳細設計決策見 ADR 0001,使用者操作說明見 查詢條件運算子。
新增
- 真正的「等於」(代碼 A):產生
col = 'x'
- 真正的「不等於」(代碼 B):產生
col <> 'x'
- 結尾為 / EndsWith(代碼 H):產生
col LIKE '%x'
- 被包含 / IsContainedIn(代碼 K):產生
col IN (x,y,z),值用逗號分隔
- 不被包含 / IsNotContainedIn(代碼 L):產生
col NOT IN (...)
- 不等於Null / IsNotNull(代碼 N):產生
col IS NOT NULL
- 不等於空白 / IsNotEmpty(代碼 P)
變更
- 下拉排序:改為 Telerik 自然順序(等於 → 不等於 → 大於 → … → StartsWith → EndsWith → Contains → …)
- 預設運算子:維持重構前的行為,使用 不等於 / IsNotEqualTo(新代碼 B,對應舊 index [2] 的 Not Equal(<>))
- 中文文字修正:
- 舊「等於(=)」實際是 StartsWith → 改稱「開始於」
- 舊「不等於(<>)」實際是 DoesNotStartWith → 整合為「不包含」
- 其他 label 全面對齊 Telerik 繁中 UI 用字
刪除
- 開頭不為 / DoesNotStartWith(舊 C):無 Telerik 對等,遷移到「不包含」
- 多關鍵字包含 / Multi-Keyword Contains(舊 J):無 Telerik 對等,遷移到「包含」。若需多關鍵字查詢,請改用多個「包含」條件以 OR 串接
Breaking Changes
Twork_sys_vw_zcond_define.SymbolNo所有代碼的意義都變了。部署前必須跑 migration SQL(見 ADR 0001 末尾),否則所有客戶既有自訂查詢條件會靜默變意義
- FilterWindow 下拉原本硬限制只顯示代碼
<= "H",現改為白名單顯示 A–Q(排除自家延伸 R/S)
BrowseInitialzation.GetConditionSourceByNoSqlDefaultValue取預設值不再用SymbolNoList[2],改為按代碼"B"(不等於)明確查找
Migration
1. 備份
Twork_sys_vw_zcond_define2. 於測試 DB 執行 ADR 0001 提供的
UPDATE ... CASE WHEN腳本3. 驗證筆數與抽樣結果
4. 正式機執行
5. 若有客戶自訂條件使用到舊 C 或舊 J,執行完 migration 後會被遷移到語意接近但不完全相同的 operator,建議通知使用者重新確認
影響檔案
- 核心 4 個:
LCLZcondOperator.cs、Xaml.json、BrowseConditionHelper.cs、SQLiteConditionHelper.cs
- 連帶 7 個:
BindingListCollectionViewFilterHelper.cs、BrowseInitialzation.cs、FilterWindowViewModel.cs、FilterMethod.cs、BrowseKeyWord.cs、ConditionPoco.cs、加上 9 個業務 ViewModel 的硬編碼遷移
後續修正(同日 hotfix)
- 預設運算子回正:重構初版誤改成
"G"(StartsWith),還原為"B"(不等於)以維持歷史行為
Common/Lang/Xaml/Shared.json補 O–S:DEBUG 模式優先讀Lang/Xaml/分檔,初版漏改此檔導致下拉 O 以後的新運算子顯示不出說明文字。Release 模式讀Lang/Xaml1/Xaml.json不受影響
- 真正的「等於」(代碼 A):產生