專案

一般

配置概況

Bug #1416

是由 陳國瑋 於 約 2 個月 前更新

## 1. 問題摘要 

 A17 的月結算目前以 transaction 開始時間選取整筆交易,且完整交易會優先使用 `meterStart/meterStop` 搭配交易開始時間的單一費率。跨月份、跨尖峰/離峰或在每月 1 日 03:00 尚未完成的交易,可能發生月份歸屬錯誤、費率錯誤及剩餘用電漏帳。 

 本票修正月結算與所有電費預估入口,使其共用同一套以 MeterValue 計費區段為基礎的分月、分時計價規則。 用電區段為基礎的分月、分時計價規則。 

 ## 2. 發生環境與 A17 證據 

 - 系統/模組:`ems_branch` 月結算、帳單與電費預估 
 - 環境:寶台 A17 production 
 - 查核日期:2026-08-07 
 - Transaction:`375` 
 - Connector:`CP003-005` 
 - 開始:2026-05-31 23:58:04 
 - 結束:2026-06-01 04:55:01 
 - 總用電量:16.160 kWh 
 - 5 月結算建立時間:2026-06-01 03:00:00 

 唯讀 DB 核對結果: 

 - 排除 transaction 375 後,該 connector/account 的 5 月交易總量為 498.750 kWh。 
 - 5 月正式帳單為 509.840 kWh、2,044.04 元且狀態為 paid。 
 - 可反推出 transaction 375 在 03:00 結算時只被納入 11.090 kWh、44.13 元。 
 - 交易完成後尚有 5.070 kWh 未結算;依當時離峰費率 3.98 元估算約 20.18 元。 
 - 6 月正式帳單為 513.500 kWh、2,147.27 元,等於所有「6 月開始」交易的總量,未包含上述 5.070 kWh/20.18 元。 

 ## 3. 已確認的帳務期間 

 1. 排程仍於每月 1 日 03:00 執行上月結算。 
 2. 帳務期間固定為上月完整月份。 
 3. 程式內使用半開區間,例如 2026 年 7 月為: 
    - 起點:`2026-07-01 00:00:00`,包含。 
    - 終點:`2026-08-01 00:00:00`,不包含。 
 4. 上述區間等同 7/1 00:00 至 7/31 23:59:59,且可正確處理毫秒/微秒資料。 
 5. 8/1 00:00 至 03:00 的用電不得列入 7 月。 
 6. 時間判斷一律使用案場時區 `Asia/Taipei`。 

 ## 4. 已確認的 MeterValue 計費區段規則 分段規則 

 ### 名詞定義 

 `MeterValue 計費區段` 是由相鄰兩筆累積能源讀數形成的最小計費單位。它不是整筆 Transaction,也不是 Tariff 的尖峰/離峰時段。 

 - 計費區段開始時間:前一筆 MeterValue 的 timestamp。 
 - 計費區段結束時間:後一筆 MeterValue 的 timestamp。 
 - 計費區段用電量:後一筆 MeterValue 減前一筆 MeterValue。 
 - 計費區段的月份與電價:均以前一筆 MeterValue 的 timestamp 判定。 

 例如累積讀值依序為 `7/31 23:59:30 = 10,000 Wh`、`8/1 00:00:00 = 10,050 Wh`、`8/1 00:00:30 = 10,110 Wh`: 

 - 第一個計費區段為 7/31 23:59:30~8/1 00:00:00,用電量 50 Wh;因開始時間在 7 月,整段計入 7 月。 
 - 第二個計費區段為 8/1 00:00:00~8/1 00:00:30,用電量 60 Wh;因開始時間在 8 月,整段計入 8 月。 
 - 若計費區段為 7/31 23:59:50~8/1 00:00:20,整段仍計入 7 月,不依秒數拆分。 

 ### 計算規則 
 1. 交易只要與結算月份有時間重疊就必須納入,不再只依 `Transaction.startTimestamp` 所在月份選取。 
 2. 相鄰兩筆累積能源讀數形成一個用電計費區段: 相鄰兩筆累積能源讀數形成一個用電區段: 
    - 計費區段用電量=後一筆 區段用電量=後一筆 MeterValue-前一筆 MeterValue。 
    - 前一筆 MeterValue 的 timestamp 為計費區段開始時間。 為區段開始時間。 
 3. 以計費區段開始時間決定: 以區段開始時間決定: 
    - 歸屬月份。 
    - 夏月/非夏月。 
    - 平日/週末假日。 
    - 尖峰/半尖峰/離峰。 
    - 當時有效的 Tariff 版本與單價。 
 4. 不做月份或費率邊界內插。 
 5. 若一個採樣計費區段跨過月份或費率邊界,整段歸入計費區段開始時間所屬的月份與費率。 若一個採樣區段跨過月份或費率邊界,整段歸入區段開始時間所屬的月份與費率。 
 6. 允許月份/費率邊界最多有一個 MeterValue 採樣週期的偏差。 
 7. `meterStart` 與 transaction start timestamp 可作為交易起點讀數;`meterStop` 與 transaction stop timestamp 可作為交易終點讀數。 
 8. MeterValue 必須依 timestamp 排序並避免重複計算;負增量、重複/衝突讀數或無法解析的能源讀數視為資料異常,不得靜默計為 0 元。 

 ## 5. 計價與彙總規則 

 1. 各 MeterValue 計費區段使用計費區段開始時間當時有效的歷史 區段使用區段開始時間當時有效的歷史 Tariff 計價。 
 2. 月結算、未結算帳單、交易紀錄及後台預估金額必須共用同一套分段計價引擎,避免不同畫面產生不同結果。 
 3. 各計費區段以完整精度計算,月度金額加總完成後才四捨五入至小數點後 各區段以完整精度計算,月度金額加總完成後才四捨五入至小數點後 2 位。 
 4. 基本費規則維持不變。 
 5. 服務費率維持不變,但服務費須使用分月後的正確用電量計算。 
 6. Tariff 缺少對應日期/時段/費率版本時,不得以 0 元完成結算,必須列為資料異常。 
 7. 後端需保存足以稽核尖峰/半尖峰/離峰度數、單價及金額的計價明細;原始 MeterValue 後續清理後仍須能說明帳單如何計算。 

 ## 6. 進行中交易與延遲資料 

 1. 月初 03:00 若交易仍在進行中,只計算「計費區段開始時間位於上月」的用電計費區段。 若交易仍在進行中,只計算「區段開始時間位於上月」的用電區段。 
 2. 若設備離線、OCPP 訊息尚未補送或 MeterValue 資料不完整: 
    - 只能產生未完成的草稿結算。 
    - 不得進入財務審核。 
    - 不得以 0 度、單一費率或時間比例猜測完成帳單。 
    - MeterValue 補齊後需自動、冪等重算。 
    - 若資料持續異常,維持待處理狀態並留下可查詢的錯誤與稽核紀錄。 
 3. 同一月份重跑結算不得重複計費,也不得遺漏已補齊的用電計費區段。 同一月份重跑結算不得重複計費,也不得遺漏已補齊的用電區段。 

 ## 7. 帳單狀態與歷史資料 

 1. `DRAFT` 可自動重算。 
 2. 待財務審核的資料可由人工觸發重算;重算後必須重新審核。 
 3. `SETTLED`、已付款及已逾期帳單不得自動改寫。 
 4. A17 transaction 375 所屬的 5 月帳單已付款,本票不得直接修改該帳單。 
 5. 漏列的 5.070 kWh/約 20.18 元由財務另行決定是否以後續調整項補收,不納入自動資料修正。 

 ## 8. API、FE 與相容性範圍 

 1. 本票包含後端計算、必要資料結構、稽核明細及既有電費查詢/預估入口的一致性修正。 
 2. 現有 API 的總用電量與總金額欄位必須保持相容。 
 3. 本票不修改住戶端或 Branch Admin FE。 
 4. 客戶帳單目前仍顯示總用電量與總金額。 
 5. 若未來要顯示尖峰/半尖峰/離峰分項,另開 FE 需求。 

 ## 9. 驗收條件 

 - [ ] 8/1 03:00 執行 7 月結算時,只計入計費區段開始時間位於 月結算時,只計入區段開始時間位於 `[7/1 00:00, 8/1 00:00)` 的用電。 
 - [ ] 8/1 00:00 至 03:00 的用電不會進入 7 月帳單。 
 - [ ] 交易開始於上月或更早,只要有用電計費區段開始於本月,就會正確進入本月帳單。 交易開始於上月或更早,只要有用電區段開始於本月,就會正確進入本月帳單。 
 - [ ] 交易結束於次月,只要有用電計費區段開始於本月,就會正確進入本月帳單。 交易結束於次月,只要有用電區段開始於本月,就會正確進入本月帳單。 
 - [ ] 跨月份、夏月/非夏月、平假日、尖峰/半尖峰/離峰及 Tariff 版本邊界時,皆以計費區段開始時間正確歸屬。 版本邊界時,皆以區段開始時間正確歸屬。 
 - [ ] 月結算、未結算帳單、交易紀錄與後台預估金額使用相同分段計價結果。 
 - [ ] 分段用電量合計與可用的 transaction 首尾讀數一致;若不一致則列為異常,不得靜默結算。 
 - [ ] MeterValue 延遲時只產生草稿,資料補齊後可自動且冪等重算。 
 - [ ] Tariff 缺漏、負增量、重複/衝突 MeterValue 等異常不會產生 0 元正式帳單。 
 - [ ] 重跑 DRAFT/待審核結算不會重複計費;已結算、已付款及已逾期帳單不會被自動改寫。 
 - [ ] 現有 API 總額欄位保持相容,現有 FE 不需修改。 
 - [ ] 後端保存可稽核的分時度數、單價與金額明細。 
 - [ ] 新增 production regression E2E case,優先級 P0,trigger:Billing/Tariff/Settlement/Release/Hotfix。 

 ## 10. E2E Impact 

 - Classification:**Add** 
 - Domain:Billing/Tariff/Settlement 
 - Priority:**P0** 
 - Status:實作完成前為 Gap,通過正式回歸後轉 Active 
 - Trigger:Billing、Tariff、Settlement、Release、Hotfix 
 - Release pack:Hotfix 至少執行所有適用 P0;Standard 執行 P0+P1 

 ## 11. 相關程式 

 - `service/SettlementService.java` 
 - `schedule/BillSettlingTask.java` 
 - `repository/TransactionRepository.java` 
 - `repository/MeterValueRepository.java` 
 - `util/TariffCalculationUtil.java` 
 - `service/HistoricalTariffService.java` 
 - `api/bill/BillHqService.java` 
 - `service/TransactionService.java` 

返回