專案

一般

配置概況

Bug #1521

是由 陳國瑋 於 2 天 前更新

## 背景與目的 

 本票是 #1518 的 R3 子票。修正兩個相連的問題:補送舊 ENERGY 讀值後,即時預估費用可能停在舊值;停充後若完整計價尚無法成立,充電紀錄不應把部分金額或 0 元顯示成已確認的費用。 

 工作位置:主 workspace `/Users/ken/Documents/workspace/workspace_cloudlink/ems`、現有 branch `feature/redmine-1517-ocpp-liveness`。不建立 worktree;未經 Ken 指示不部署或重啟案場服務。#1518 的程式尚未部署 A17;已套用的第一階段索引不受本票影響。 

 ## 問題一:補送舊讀值未更新即時預估 

 `LiveTransactionCostService` 目前記住最新 ENERGY 讀值與累計費用。若 CP 補送較早 timestamp 的資料,而最新讀值本身未變,下一次 estimate 會沿用舊結果,也不會重新檢查游標以前的資料。 

 例:原本只有 07:59:30 10000 Wh、08:01:00 10090 Wh,跨越 08:00 費率邊界;之後補送 08:00:00 10030 Wh、08:00:30 10060 Wh。補送前資料不足,補送後依完整歷史可算 0.45 元,但舊 cache 仍回傳 0.00 元。 

 ## 問題二:停充紀錄可能把未完成的計算當作確定金額 

 Branch 管理端與車主端的充電紀錄都讀取完整歷史計價結果,但現行程式未在展示前確認 `calculation.status`。引擎在資料不足或錯誤時仍可能帶有可計價區段的部分合計;管理端甚至在例外時填 0 元。因此「停充後的金額」可能被誤讀為已確認。即時費用本來就是預估;車主充電中畫面已改標示「目前預估費用」。 

 ## 修正方式 

 1. 保留現有 process-local cache,不增加資料表、Redis 或另一份需維護的持久快取。每個 PDU 保存時,只記錄成功保存的 ENERGY 中最早 timestamp;非 ENERGY 不觸發費用失效。 
 2. 交易成功 commit 後,若該 timestamp 早於或等於 cache 目前最新 ENERGY,就把該交易摘要標記 dirty;下一次 estimate 從資料庫完整歷史重建一次。正常較新讀值仍走既有尾端增量路徑。Rollback 不得失效;同 timestamp 新讀值與舊新混合 PDU 都要涵蓋。已有其他人工補正入口時,亦應共用同一失效方法。 
 3. 充電紀錄沿用共用 `MeterValueTariffCalculationService` 的 `COMPLETE / PENDING_DATA / ERROR` 判定,不以「中途漏一筆」直接視為資料不足。只有整段計價需要的起訖讀值、費率及跨邊界資料足以讓引擎回傳 `COMPLETE`,才顯示費用。短暫漏點但可完整、安全計價仍是 `COMPLETE`。 
 4. 停充後結果為 `PENDING_DATA`(例如缺起訖錨點或跨費率邊界的長缺口)時,API 金額為 null,畫面顯示「計費待確認」;`ERROR`(例如衝突讀值、無法處理的負增量、缺費率或計算例外)時,API 金額為 null,畫面顯示「計費異常」。不得將部分金額或 0 元當成確定金額。真正完整計算出 0 元時仍可顯示 0.00 元。 
 5. 管理端的總額與平均費用若包含未能完整計價的紀錄,也不得以已算出的部分合計冒充完整總額;API 要提供可區分狀態,畫面要對應呈現。車主端透過 HQ 轉送的紀錄也要帶出同樣狀態。進行中的交易仍為預估,不宣稱已結算。 
 6. 本票不改月結/請款規則,不新增 schema,不在案場有車充電時重啟服務。 

 ## 驗收條件 

 - 補送上述兩筆 ENERGY 並成功 commit 後,即使最新讀值不變,下一次即時估算得到 0.45 元;正常遞增仍走增量路徑。 
 - 較早 timestamp、同 timestamp、新舊混合 PDU 都正確失效;非 ENERGY 與 rollback 不誤觸發。失效與 estimate 並發時不丟失 dirty 訊號。 
 - 缺中間少量讀值但完整計價狀態為 COMPLETE 時,停充紀錄仍顯示正確金額;PENDING_DATA/ERROR 或計算例外時顯示對應文字且不顯示部分費用。 
 - Branch 管理端單筆、彙總與車主充電紀錄的金額語意一致;API 可區分完整、待確認、異常。跨月查詢維持既有區段歸屬規則。 
 - 不新增持久快取或資料庫 migration。補送及停充狀態案例加入 E2E catalog,後續於 ken environment 驗證;部署、E2E 另由 Ken 指示。 

 ## 重現與驗證 

 現有單案例重現:`python3 test_report/evidence/1518-review/run_one.py late-reading`(修正前預期 0.45、實際 0.00)。本地可執行隔離單一 Unit Test 與跳過測試的編譯;跨服務/E2E 測試需依 SOP 另列計畫,由 Ken 啟動。 

 ## 帳單詳情相容性 

 `BillService` 的帳單詳情會重用 `computeConnectorBillDetail` 並累加各 Connector 的統計值。因未完整計價的明細現在回傳 null,呼叫端須避免加總 null 而拋錯。已有持久化月結金額時仍以該金額為權威值;尚無完整金額時,不以已算出的部分金額或基本費拼出確定總額。未完整計價的度數也不顯示部分值,但原始 `meterStart/meterStop` 仍保留供核對。

返回