コンテンツにスキップ

0012. 日次運行ログと燃料の記録 (量と費用の分離)

コンテキストと課題

車両の運行を日次で記録したい (走行距離・給油)。給油は当初「燃料費 (円)」で 1 項目だったが、実務では 燃料の種別 (軽油・アドブルー・ガソリン) ごとの給油量 (L) を運行記録として残したい。一方、燃料費 (円) は 請求書ベースで後から確定するため、運行ログに金額を持たせると 二重計上 や「まだ請求が来ていないのに 0 円表示」といった不整合が起きる。「量」と「費用」を分けて扱う必要がある。

決定

日次運行ログは燃料の「量 (L)」を種別ごとに記録し、燃料の「費用 (円)」はコスト入力から確定する

  • 量 (運行ログ): vehicle_daily_logs (migration 29) に走行 (odometer_out/odometer_indistance_km は生成列) を記録。migration 47 で給油量を 種別ごとの 3 列 (L) に拡張: diesel_liters (軽油) / adblue_liters (アドブルー) / gasoline_liters (ガソリン)、いずれも nullable + 非負制約。燃費 = 走行距離 ÷ (軽油 + ガソリン)。アドブルーは尿素水で燃料ではないため 分母から除外する。
  • 費用 (コスト入力): 燃料費は vehicle_cost_entries (migration 22、category in ('fuel','maintenance','inspection','insurance','tax','tire','other')) の category = 'fuel' 行から 集計する。
  • 未確定表示: ある車両×月に fuel のコスト入力が 1 件も無ければ、コストダッシュボードは燃料費を 「未確定」 と表示する (summarizeFuelCost)。円/km は燃料費に依存するため、燃料費が未確定なら 同じく未確定。総コストは未確定の燃料費を 0 と混ぜず、確定分のみ表示する。
  • 二重計上の防止: 汎用のコスト入力フォームは category = 'fuel'拒否 する (燃料費は専用の 入力経路で扱い、ダッシュボードでの二重計上を防ぐ)。
  • 後方互換: 旧 fuel_cost / fuel_liters 列・制約は DROP せず残し、入力 UI からのみ撤去する。 月次ビュー vehicle_daily_logs_monthly (security_invoker) は種別ごとの合計 L と旧 total_fuel_cost を 併せて持つ。

影響 (Consequences)

良い点

  • 運行 (ドライバーが入力する「量」) と費用 (バックオフィスが請求書から確定する「円」) を 責務分離 でき、入力タイミングのズレを「未確定」として正しく表現できる。
  • 燃料種別を分けたことで、軽油/ガソリンのみを燃費分母に使う等、ドメインに即した集計ができる。
  • 汎用フォームで fuel を拒否することで、燃料費の入力経路を一本化し二重計上を構造的に防ぐ。

トレードオフ / 注意点

  • 燃料費は請求確定まで 「未確定」のままになる。リアルタイムの正確なコストが必要な用途には向かない (運用上の割り切り)。
  • fuel_cost / fuel_liters 列が新しい種別別列と 併存 する (後方互換のため)。マッパーは旧列も 引き続き写すため、どちらを正とするか実装者が意識する必要がある。
  • アドブルーは記録するが燃費分母から外す、という非対称があるため、燃費計算は専用ヘルパー (軽油 + ガソリン) を経由する規律が要る。

根拠 (典拠)

  • supabase/migrations/00000000000029_vehicle_daily_logs.sql:4-29vehicle_daily_logs (odometer / distance_km 生成列 / fuel_cost / fuel_liters / unique(tenant,vehicle,date))。
  • supabase/migrations/00000000000047_daily_log_fuel_types.sql:1-44 — 種別別 L 列 (diesel_liters/adblue_liters/gasoline_liters) + 非負制約、燃費 = 距離 ÷ (軽油+ガソリン)・アドブルー除外、後方互換 (旧列は残す)、月次ビュー更新。
  • supabase/migrations/00000000000022_vehicle_cost_entries.sql:8-26vehicle_cost_entriescategory の check ('fuel' を含む)。
  • apps/web/src/pages/collector/fleet/VehicleCostDashboardPage.tsx:132-149,337,599-647,739-741 — 燃料費の未確定判定と表示 (fuel 入力 0 件なら未確定、円/km も未確定)。
  • apps/web/src/pages/collector/fleet/VehicleCostNewPage.test.tsx:52-56 — 汎用フォームは fuel を拒否 (二重計上防止)。
  • apps/web/src/lib/daily-log.ts:18 / DriverDailyLogPage.tsx:247 / VehicleDailyLogNewPage.tsx:190 — 燃費の分母は軽油+ガソリン (アドブルー除外)。