二次搬出 運搬費 + 収支(P&L)¶
二次搬出 運搬費 + 収支(P&L)¶
二次搬出(1コース=1排出元回収先から各搬出先回収先へ運ぶ/または前日確定の点対点搬出)の「収入」を、重量に依存しない固定運搬費マスタで管理し、費用(車両コスト)と突き合わせて日次 P&L(収入 − 費用 = 粗利)を見る機能。4つの操作面に分かれる:(A) 運搬費マスタ登録、(B) 配車コースへの「排出元 回収先」設定、(C) コスト集計ページの「収入/P&L」タブ閲覧(admin 限定)、(D) 配車ボードでの排出元付き stop 手動追加(アドホック)。
収入の導出は永続化せず、pnl_daily RPC(mig105/mig107/mig110/mig114/mig124/mig132/mig141・SECURITY DEFINER・admin 限定・tenant フィルタ)が実行時に計算する。収入 1 件=完了した二次搬出ストップ(dispatch_stops.status='completed' かつ source_site_id IS NOT NULL)× 引き当てた固定運搬費。引き当てキーは「排出元=各ストップの source_site_id(raw 権威・snapshot。course 由来 stop は生成/編集時に course.source_site_id から補完され、配車ボードで手動追加した stop は指定した排出元を直接保持する。mig110 で pnl の排出元は stop.source_site_id のみを見る=course fallback を撤去)」×「搬出先=ストップの回収先 collection_site」×「実配送日=ドライバーが完了した completed_at の Asia/Tokyo 日付が有効期間内・active」。
運搬費の集計・警告は二次搬出 stop 限定(mig114): 運搬費マスタ(secondary_transport_routes)は二次搬出(排出元→搬出先の点対点)専用のため、収入引き当てと unpriced_count(未登録ペア)警告は source_site_id を持つ二次搬出 stop に限定する。回収(collection)stop は source_site_id IS NULL で運搬費マスタに構造的にマッチせず、運搬費集計の対象外・unpriced 警告の対象外(mig114 以前は回収 stop まで unpriced にカウントされ、運搬費と無関係な回収コースが警告バッジを発火させていた誤りを是正)。二次搬出 stop で運搬費マスタに引き当たらなかったものは従来どおり収入から除外され unpriced_count として警告される。ストップの「完了」操作はドライバーがモバイルで行い、Web 配車ボードは読み取り専用ミラー(事務は Web で完了操作しない)。
A. 固定運搬費マスタの登録(排出元×搬出先×固定運搬費×期間)¶
- 対象ロール: admin / normal(登録・有効/無効切替)。削除は admin のみ。driver は金額秘匿のため画面・データとも一切見えない(RLS で SELECT も除外)。
- 前提: 排出元・搬出先として使う回収先(取引先の回収先)が「取引先」マスタに登録済みであること。運搬費は回収先(collection_site)単位で設定する(取引先 partner 単位ではない・mig107 で re-key 済)。
- 操作手順:
- 左ナビ「マスタ管理」グループ →「二次搬出運搬費」(
/collector/secondary-transport-routes)を開く。ページ見出しは「二次搬出 運搬費」、サブタイトルは「排出元×搬出先の回収先ごとの固定運搬費マスタを管理します(二次搬出 P&L の収入側)」。 - 右上「運搬費を追加」ボタンを押すとフォーム(カード「固定運搬費を登録」)が開く。
- 「排出元(回収先)」セレクトで排出元の回収先を選ぶ(候補は「取引先名 / 回収先名」で表示・同名回収先を取引先で区別)。
- 「搬出先(回収先)」セレクトで搬出先の回収先を選ぶ。
- 「固定運搬費(円・税抜)」に金額を入力(例: 45000。type=number、0 以上)。
- 「開始日」を入力(必須)。「終了日(空欄=無期限)」は任意(空欄なら無期限)。
- 「有効にする」チェックボックス(既定 ON)を確認し、「保存」を押す。成功トースト「固定運搬費を追加しました」。
- 一覧行の「無効化」/「有効化」で active を切替(admin/normal 可)。「削除」は admin のみ表示(確認ダイアログ「この固定運搬費を削除します。よろしいですか?」)。
- 確認/完了条件: 一覧テーブルに「排出元(回収先)/搬出先(回収先)/固定運搬費/有効期間(開始 〜 終了 or 無期限)/状態(有効=緑バッジ / 無効=灰バッジ)」の行が現れる。収入に効くのは状態=有効かつ実配送日(完了時刻の JST 日付)が有効期間内の行のみ。
- つまずき/注意:
- driver では左ナビにこの項目自体が出ず、直接 URL でも RLS でデータが返らない。
- 同一「排出元×搬出先」で有効期間が重複する運搬費は DB の排他制約(btree_gist EXCLUDE)で拒否される(保存エラー・
translateRouteErrorで日本語化)。排出元=搬出先の同一ペアも CHECK で拒否。 - 金額は税抜。マイナス・不正値は保存できない。
- 越境(他テナントの回収先)を指す設定は RLS/トリガで拒否される(通常 UI では発生しない)。
- 関連画面: 取引先(
/collector/partners、回収先マスタ)/コスト集計「収入/P&L」タブ(ここで登録した運搬費が収入として反映)。
B. 配車コースへの「排出元 回収先」設定(収入計上元の指定)¶
- 対象ロール: admin / normal(設定・解除)。driver は現在の排出元をラベル表示のみ(読み取り専用)。
- 前提: 配車コースが作成済み(コースビルダー)。排出元にする回収先が登録済み。
- 操作手順:
- 左ナビ「日次業務」→「配車」(
/collector/dispatch)→ ページ内から「コースビルダー」(/collector/dispatch/courses。パンくず: 概要 › 配車 › コースビルダー)へ。「コース構築」タブを開く。 - 各コース列のヘッダーにある「排出元 回収先(二次搬出の収入計上元)」セレクトで、そのコースの排出元回収先を選ぶ(候補は「取引先名 / 回収先名」昇順)。既定は「未設定」。
- 選ぶと即保存(成功トースト「排出元を設定しました」/解除時「排出元を解除しました」)。
- 確認/完了条件: セレクトに選んだ回収先が表示された状態。以後、そのコースに紐づく完了ストップが「排出元=このコースの回収先」× 各ストップの搬出先で運搬費マスタに引き当たり、収入が導出される。
- つまずき/注意:
- course 由来 stop でコースの排出元が「未設定」のまま完了し、stop 自身の raw
source_site_idもNULLの場合、その stop はsource-lessである。収入には計上されず、unpriced_count(未登録ペア)にも P&L タブの警告にも含まれない(配車ボードで手動追加した排出元付き stop は、course 設定に関係なく指定した排出元を直接持つ・操作面 D)。 - コースの排出元を後から非
NULLに設定すると、同コースに紐づく既存 stop のうち rawsource_site_idがNULLの行だけに排出元が補完される。既に非NULLの raw source は snapshot として保持され、以後のコース排出元変更には追随しない。ただし、排出元回収先そのものを削除した場合の FKon delete set nullは例外で、参照していた raw source はNULLになる。 - 収入は重量に依存しない。1 完了ストップ=固定運搬費 1 件で計上される(計量値は使わない)。
- 排出元回収先が削除されると、コースおよび stop の参照は FK
on delete set nullでNULLになる。rawsource_site_id=NULLの stop は source-less、収入なし、unpriced 警告の対象外である。後からコースに別の非NULL排出元を設定すれば、その時点で rawNULLの course 由来 stop だけが補完対象になる。 - 関連画面: 配車ボード(
/collector/dispatch、完了状況の読み取り専用ミラー)/二次搬出運搬費マスタ。
D. 配車ボードでの二次搬出 stop 追加(日次入力)¶
- 対象ロール: admin / normal(配車ボードの
canManage導線。driver には出ない)。 - 前提: 排出元・搬出先の回収先が「取引先」マスタに登録済み。追加先の当日ボードが開いていること。
- 操作手順:
- 当日配車ボード(
/collector/dispatch)の右上「二次搬出を追加」ボタン → ダイアログ「二次搬出を追加」で「ドライバー」「積方」「入場時間」と排出元→搬出先の順序を入力して「登録」を押す(手順詳細は 04-dispatch.md を参照)。 - 指定ドライバーの当日ルートに、各ペアの排出元(
source_site_id)を持つ stop が追加される(「二次搬出」バッジ+「排出元: …」表示)。 - 確認/完了条件: この stop が完了(ドライバーがモバイルで完了)すると、「排出元=手動指定した source_site_id」×「搬出先=stop の回収先」で運搬費マスタに引き当たり、収入として計上される。
- つまずき/注意:
- B(コースへの排出元設定)を経由しなくても料金計上できる。前日にしか配車が決まらない点対点搬出は曜日テンプレでコース化できないため、「二次搬出を追加」が収入計上の主経路になる。pnl は stop の raw
source_site_id(snapshot)のみで引き当てるため、course 排出元が未設定でも追加した stop は排出元を直接持ち、source-less にはならない。対応する運搬費マスタが無ければ、下記のとおり unpriced として警告される(mig110)。 - 排出元=搬出先は不可。同一ドライバー・同一搬出先・同一排出元の同日二重追加は一意制約で弾かれる(排出元が異なれば同一搬出先でも別ルートとして共存)。
- 引き当てには「その排出元×搬出先の運搬費マスタ(A)」が有効期間内・active で登録済みであることが必要(未登録なら unpriced として警告される)。
- 関連画面: 配車ボード(
/collector/dispatch・04-dispatch.md)/固定運搬費マスタ(A)/収入/P&L タブ(C)。
C. 収入/P&L タブの閲覧(コスト集計・admin 限定)¶
図: 収入/P&Lタブ。①期間・表示範囲 ②完了運搬×固定運搬費 ③日次 P&L 表 ④未登録ペア警告(凡例は図内)。
- 対象ロール: admin のみ。normal/driver にはタブ自体が表示されない(
pnl_dailyは DEFINER で tenant 全体費用を集計=normal の工場スコープを越境しうるため admin 厳密一致・fail-closed で制限)。 - 前提: 完了した二次搬出ストップ(driver がモバイルで完了)+ 車両コスト(コスト入力)+ 運搬費マスタ登録が揃っていること。コース由来の二次搬出 stop はコースへの排出元設定が必要で、配車ボードで手動追加する二次搬出 stop は
source_site_idを直接指定するためコース設定を必要としない。二次搬出表示で費用を出すには、対象車両を「二次搬出専用」に設定する。 - 操作手順:
- 左ナビ「集計・分析」グループ →「コスト集計」(
/collector/fleet/costs)を開く。 - 上部タブ「集計 / 運行ログ明細 / コスト明細 / 収入/P&L」から「収入/P&L」を選ぶ(admin のときのみ出現)。
- 「絞り込み(期間)」の「開始月」「終了月」(type=month)で期間を指定(両空=当月・片側のみは無制限側・逆転は自動で正規化)。期間表示「期間: … 〜 …(未指定のため当月)」で確認。
- 「表示範囲」で「全体」(初期値)または「二次搬出」を選ぶ。全体は二次搬出運搬費の収入と全車両の車両コストを表示する。二次搬出は収入を全体と同じ二次搬出運搬費のままにし、費用だけを「二次搬出専用」車両の車両コストに限定する。「全体」は収入の対象を広げる表示ではない。
- サマリカード「収入(運搬費)(完了運搬 × 固定運搬費)」「費用(燃料・修繕・ETC ほか車両コスト)」「粗利(収入 − 費用)」を確認(粗利マイナスは赤字表示)。
- 「費目別内訳」で費用の費目別合計(金額降順)を確認。
- 「日次 P&L」テーブルで実配送完了日(完了時刻の JST 日付)ごとの「収入 / 費用 / 粗利 / 未登録」を確認(日付降順・末尾に合計行)。
- 確認/完了条件: サマリ 3 カードと日次テーブルに数値が表示される。収入=完了ストップ引き当て額の Σ(全体/二次搬出で同じ)、費用=全体では全
vehicle_cost_entriesの Σ、二次搬出では「二次搬出専用」車両のvehicle_cost_entriesの Σ、粗利=収入 − 費用。データが無い期間は空状態「この期間の収入・費用がありません」。 - 日付基準: 収入の計上日は
dispatch_dateではなく、ドライバーがモバイルで完了した時刻completed_atを Asia/Tokyo で日付化した実配送完了日。前日配車・宵積みでも、実際に完了した日の P&L に入る。 - つまずき/注意:
- unpriced 警告: 完了した二次搬出ストップ(raw
source_site_id有り・mig114)のうち運搬費マスタに引き当たらなかった件数がある期間は、上部に琥珀色アラート「運搬費マスタに未登録の二次搬出があります」(「完了した運搬のうち N 件が…収入から除外されています」)が出る。日次テーブルの「未登録」列にも件数バッジが出る。回収 stop と、排出元未補完または FK nulling 後の source-less stop(rawsource_site_id=NULL)は運搬費集計・警告の対象外なのでこのカウントに含まれない。→ 現在表示中の警告は、その stop の raw snapshot である「排出元×搬出先」に一致する二次搬出運搬費マスタを登録・有効化・修正する。今後作成するコース由来 stopは、作成前にコースの排出元回収先を設定してsource_site_idを補完する。後からコース排出元を非NULLにして補完されるのは rawNULLの既存 stop だけで、既に警告対象になった非NULLraw snapshot は遡及変更されない。 - 二次搬出専用車の設定: 「二次搬出」表示の費用に含める車両は、車両画面(
/collector/fleet/vehicles)で対象行の「編集」を開き、チェックボックス「二次搬出専用」を ON にして保存する。この設定が ON の車両に紐づく車両コストだけが二次搬出表示の費用になる(車両の有効/無効は問わない)。 - 二次搬出専用車に関する空状態は 2 種類: 「二次搬出専用車が未設定です。車両編集で二次搬出専用車を設定してください」は、車両マスタで「二次搬出専用」が ON の車両が 1 台もない(有効/無効を問わず)意味で、表示される「車両を編集」導線は
/collector/fleet/vehiclesへ移動する。 「この期間の二次搬出の車両コストがありません」は、二次搬出専用車は設定済みだが、選択期間にその車両の車両コストがない意味である。 - 費用の集計対象は tenant 全体(工場スコープをバイパス)。このためタブは admin 限定。
- 費用側の燃料費はこのタブではコスト入力(category=fuel)由来で Σ される(集計タブの「燃料費 未確定」の概念とは別集計)。
- 期間フィルタ(開始月/終了月)は集計タブと共有される(タブを行き来しても期間が保たれる)。
- 関連画面: 二次搬出運搬費マスタ(収入側マスタ)/コスト入力・請求書取込(費用側の登録元
/collector/fleet/costs/new・/collector/fleet/costs/import)/配車ボード(完了状況)。
実装状況: 本機能(運搬費マスタ・コース排出元設定・配車ボードでの排出元付き stop 手動追加・収入/P&L タブ)はいずれも実装済み(mig103/mig105/mig107・v1.12.0 以降で prod 反映。アドホック二次搬出=stop への
source_site_id付与と pnl の raw 権威化は mig110・v1.14.0。運搬費の集計・unpriced 警告を二次搬出 stop(source_site_id有り)限定にする scope 修正は mig114。P&L の全体/二次搬出表示切替と車両の「二次搬出専用」設定は mig124。実配送完了日(completed_atの JST 日付)基準は mig141・v1.29.0)。⚠️ 準備中/未実装のサブ機能: 工場別 P&L(normal 向け)は未実装(現状 P&L は tenant 全体・admin 限定のみ)。収入計算の起点となる「ストップ完了」操作は Web には無く、ドライバーのモバイルアプリ側で行う(Web 配車ボードは読み取り専用)。