線稿索引所有 spec最後更新 2026-07-03
specs/operating-expenses.md

公司營業費用與月損益表

一句話:每梯次只算到「毛利」(收入 − 直接成本);公司層級的辦公室 / 人事(行政固定薪)/ 實繳稅 / 平台手續費實際月結這些與梯次無關的費用進一本獨立的營業費用分類帳,月損益表 = Σ各區毛利 + 其他收入 − 公司營業費用 = 公司真實淨利。手續費 / 稅只在公司層用實際值扣一次,每梯次不重複估算

畫面(UI = wireframe):損益表 / 財務總覽(獨立 nav,跨梯次)· 費用類別設定見 設定

模組歸屬:屬進階會計模組(受 module_accounting gate);不開模組的租戶用核心掛帳台帳(per-departure 毛利)+ Excel 自行做損益。

1. 目標 / 問題

toko 現有財務只到每梯次層internal-external-ledger 的「真實成本 / 可申報成本 / 預估淨利」、control-financedeparture_costsaccount-settlement 的帳戶補款。缺公司層級:GS「2026荒野旅人五月份總結算」的損益區(B2–B39)有,toko 沒有。

GS 損益結構(2026/05 實證):

一、利潤總計
  國內登山 843,966 + 東南亞 89,775 + 中東非洲 0 + 日本 109,481   = 1,043,222   ← 各區毛利
  − 辦公室支出 643,307 − 稅金 339,480 − 平台手續費 44,959        = −1,027,746  ← 公司營業費用
  = 淨額 15,476 元

明細:辦公室 643,307 = 台新辦公室 88,845 + 永豐辦公室 554,462;稅金 339,480 = 營業稅 204,219(雙月)+ 營所稅 135,261(年,5 月實繳);平台手續費 44,959 = 綠界 43,519 + 豐收款 0 + 寰宇 1,440。

缺的載體:辦公室支出、人事(行政 / 內勤固定薪,非領隊費)、實繳稅、平台手續費實際月結,全無處可記;公司月損益表不存在。

雙重計陷阱(必避):每梯次「預估淨利」已扣預估綠界 / 豐收款手續費 + 預估營所稅(internal-external-ledger §3.1;GS 0501 玉山:淨利未扣稅手續 14,200 → 預估實際淨利 12,487)。若公司層用實際手續費 / 稅扣一次 → 雙重計。本檔把每梯次降為毛利(收入 − 直接成本,不扣手續費 / 稅),手續費 / 稅 / overhead 全移公司層用實際值扣一次。

「人員成本」釐清(GS 0501 玉山鐵證):出團成本計算表的「人員成本」(C40)= 領隊費(領隊 夏鼎 4025/天 × 2 天 = 8,050),是每梯次直接成本,且由領隊經 guide-portal 自填(領隊薪資申請單 Google 表單「本團領隊費總額」= 同數),admin 端鏡像進 departure_costs領隊費屬每梯次毛利、非公司人事;公司人事只裝「行政 / 內勤固定薪 + 勞健保」(領隊薪資申請單底部「行政薪水(直接外加)」,無 per-trip 家)。勿把領隊費重算進公司人事(雙重計)。

範圍:公司營業費用分類帳(類別 per-tenant 可設)+ 月損益表(各區毛利 + 其他收入 − 公司費用)+ 每梯次「淨利 → 毛利」降級。 不做HR 算薪 / payroll(薪資級距、勞健保投保管理、最低薪資自動算、考勤、員工主檔;jurisdiction-specific,由外部記帳 / payroll 提供數字);正式總帳 / 合併財報 / 跨年結轉(未來會計模組);自動串國稅局 / 銀行拉實繳數(人工登錄)。

嚮導 / 領隊費「月結批次匯出」做的是出納面(彙整當月已核准 payable + 通用扣款項 → 一筆匯出 + 批次轉帳清單 + 進對帳),在 control-finance §5.5 出款批次非 HR(不算薪 / 不管投保)。領隊費的成本認列仍是 per-trip departure_costsguide-portal)。

2. 資料模型

2.1 expense_categories(費用類別,per-tenant config,新表)

公司營業費用的類別,租戶自定不寫死,且夠細到逐筆明細的科目(GS 辦公室支出 643,307 底下是約 30 筆逐項:薪資 / 廣告 / 勞健保 / 房租 / 水電 / 電信 / 網路 / 保險 / 招募 / 文具 / 法遵 / 交通…):

欄位型別說明
idtext PK(exc_<ulid>主鍵。
codetext NOT NULL科目代碼(租戶內唯一,如 rent / salary_admin / labor_insurance / marketing / utility / telecom / insurance / recruiting / supplies / tax_vat / tax_income / gateway_fee…)。
display_nametext NOT NULL顯示名(房租 / 行政薪資 / 勞健保 / 行銷廣告 / 水電 / 電信 / 保險 / 招募 / 文具 / 營業稅 / 營所稅 / 平台手續費…)。
kindtext NOT NULL default 'opex'opex(一般營業費用)/ tax(稅)/ platform_fee(金流商手續費實際月結)/ special(一次性特殊損益,§3.4)。損益表按 kind roll-upopex 細項彙整成「辦公室支出 / 營業費用」、tax→稅金、platform_fee→平台手續費(= GS 損益區三大格)、special→特殊損益獨立列。
is_activebool default true停用不刪。

兩層:細科目(房租 / 薪資 / 廣告…)是逐筆登錄的維度;損益表上只顯示 kind 三 bucket(辦公室・稅・手續費),點開 drill-down 到細項。tax / platform_fee 是 hint 不是硬枚舉——租戶可只用 opex。「人事(行政固定薪)」是 opex 下的一個科目(GS 就把行政薪資逐筆列在辦公室支出內),不另立頂層;領隊費不在此(per-trip 直接成本)。

2.2 operating_expenses(公司營業費用,新表,無 departure / order

與梯次無關的公司費用,逐筆登錄成明細台帳(對齊 GS 辦公室支出明細 B673–B713:每筆 廠商 / 品名 + 金額 + 代墊者 + 出帳帳戶 + 匯出日):

欄位型別說明
idtext PK(opx_<ulid>主鍵。
category_idtext FK → expense_categories費用科目(細科目,§2.1)。
periodtext NOT NULL歸屬月(YYYY-MM,損益表據此彙整;與支付日可不同,如年營所稅攤)。
incurred_ondate(nullable)發生 / 支付日期;金流商內扣 / 攤提無單一發生日者可留空(UI 標「選填」)。
amount_twdinteger NOT NULL金額(整數 TWD)。
descriptiontext NOT NULL摘要(廠商 / 品名,如 台中房租 / 委外廣告投放 / 林宥潔行政薪 / 履約保證保險…)。
paid_from_account_idtext FK → receiving_accounts nullable出帳帳戶(→ 接 account-settlement / 對帳;金流商內扣者可留空)。
fronted_by_user_idtext FK → user(同庫)nullable代墊者(GS「代墊者」欄:曾帥 / 乃文 / 小御先墊付)。非空 = 此筆由人代墊待回補 → 走請款回補代墊者(payable_id,payee = 代墊者);空 = 公司帳戶直接出帳。
payable_idtext FK → payables nullable若走出款核簽(租金 / 薪資 / 稅 / 代墊回補),連到 payables;金流商自動內扣的手續費不走核簽、留空。
recurringbool default false月固定標記(人工登記時可打勾備註「這是月固定」;真正的自動生成走 §2.2.1 範本表,非此欄)。
statustext default 'confirmed''draft'(月固定範本自動生成、待確認,不入損益)| 'confirmed'(計入損益)。手動登記預設 confirmed(零回歸)。
origintext default 'manual''manual'(手動登記)| 'recurring'(月固定範本自動生成,§2.2.1)。
source_template_idtext FK → recurring_expense_templates nullable生成來源範本(origin=recurring)。partial unique (source_template_id, period):同範本同月至多一列(生成冪等)。
notetext備註。
created_by_user_idtext FK → user(同庫)經手人。
created_at / updated_attimestamptz

約束amount_twd ≥ 0status IN ('draft','confirmed')origin IN ('manual','recurring')。非 append-only(公司費用可更正;更正記 audit_log operating_expense.update,敏感金額留軌跡)。損益只計 status='confirmed'computeCompanyPnLcomputeExpensesByKind / computeSpecial 都帶 AND status='confirmed')—— 這是「避免無人確認的鬼列」的安全前提:自動生成的草稿不確認不入帳。

逐筆明細,不是一坨:辦公室支出在損益表是一格(GS 643,307),但底下是約 30 筆 operating_expenses(薪資逐人 / 廣告 / 勞健保 / 房租 / 水電 / 文具…)。損益表顯示 bucket 合計、點開 drill-down 到逐筆。 四種結付型態:① 公司帳戶直接出帳paid_from_account_idfronted_by 空,如房租自永豐匯出);② 人代墊待回補fronted_by_user_id 非空 → payable_id 走請款回補代墊者,如台北房租曾帥代墊);③ 金流商自動內扣(手續費,paid_from 留空、不走核簽);④ 薪資走月結出款批次(行政 / 內勤固定薪不走逐筆請款——是一條合計,per-person 明細 + 扣勞健保在 出款批次 §5.5「直接外加」;逐筆請款是給供應商 / 代墊回補的)。 行政薪單一真相(避免損益列與出款批次重複出帳):行政薪有兩個面 ——「損益費用列」(本表 operating_expenseskind=opexcode=salary_admin)與「出款執行」(出款批次 §5.5「直接外加」現金)。真相只記一次:出款批次「直接外加」列確認時生成 / 連結對應的 operating_expenses(salary_admin) 列(payout_batch_lineoperating_expense_id,反向 operating_expenses.payable-側不重開),毛額(未扣勞健保自付)= 損益費用、淨額 = 批次匯出金額。不得由會計在損益頁、出納在批次頁各登一次。這對齊領隊費的單鏈(departure_costs → payable → 批次),補上行政薪原本缺的連結。 成本拆分(公司贊助 vs 老闆個人,GS 電子簽 / 機票):一筆支出由公司贊助一部分、老闆 / 員工個人自付一部分時,operating_expenses 只記公司負擔的那筆(kind=opex),個人自付部分不入公司帳;description 註明拆分(如「爪哇電子簽 · 公司贊助 2,078/老闆自付另計」)。不建模個人帳,保持公司損益乾淨。 payables 的分工payables 是「出款核簽 workflow」(誰建單 / 誰核准 / 誰付款);operating_expenses 是「損益表費用列」。需核簽 / 代墊回補的開 payable、付款後填 payable_id 連結(避免重複出款)。兩者一對一可選掛,不是同一張表。多筆 payable 可經 出款批次 §5.5 月結一次匯出。

2.2.1 recurring_expense_templates(月固定費用範本,新表)+ 自動生成 draft + 確認流

每月會重複的公司費用(台中房租 / 固定薪 / 電信 / 網路…)不必每月手動重登:建一份範本(預設值),排程每月月底(25 號)生成下月草稿(月中即可預先確認下月固定支出),人工確認(可先改金額)後才計入損益。

欄位型別說明
idtext PK(ret_<ulid>主鍵。
category_idtext FK → expense_categories(restrict)費用科目。
amount_twdinteger NOT NULL(≥ 0)預設金額(生成的草稿可逐月修正)。
descriptiontext NOT NULL摘要(帶進草稿的 description)。
paid_from_account_idtext FK → receiving_accounts(restrict)nullable預設出帳帳戶(帶進草稿,可改)。
is_activebool default true停用不刪:停用後不再生成,既有草稿 / 費用列不受影響。
created_by_user_idtext FK → user(同庫)建立者。
created_at / updated_attimestamptz

自動生成(materialize):排程 POST /api/jobs/generate-recurring-expenses(GCP Cloud Scheduler,每月 25 號 06:00 Asia/Taipei,生成下月——sweep 預設 period = 下月,補生成歷史月走 period 參數)逐 active 租戶 fan-out(比照台銀牌告 sync-bot-rates 的四件套:recurring-sweep.ts fan-out + recurring-expenses.tsmaterializeRecurringDrafts + job route + ops script cron:generate-recurring-expenses)。對每個 active 範本 INSERT 一列 operating_expenses 草稿(status='draft'origin='recurring'source_template_id 連回範本、金額 / 摘要 / 帳戶承範本、created_by_user_id 承範本建立者),ON CONFLICT (source_template_id, period) DO NOTHING 保證冪等(同月重跑 / 單一租戶失敗不中斷其餘)。

確認流/admin/pnl 頁列出「待確認月固定費用」草稿卡(status='draft' 該期列),每列一個「確認」鈕 → confirmOperatingExpenseAction(閘 operating_expense.manage + 進階會計模組)→ confirmOperatingExpenseFOR UPDATE 鎖、只確認 draft 列 [NOT_DRAFT 拒重複]、status → confirmed、可同時覆寫金額、寫 audit_log operating_expense.confirm)。確認後即計入損益。範本管理在 設定 · 月固定費用 tab(CRUD,operating_expense.manage)。

2.3 每梯次「淨利 → 毛利」(改 internal-external-ledger)

internal-external-ledger §3.1 的「預估淨利」降級:

  • 每梯次權威數=毛利 = 本團收入 − 真實成本(Σ departure_costs.amount_twd + 房費,只計 approved)。不扣手續費 / 稅(那些移公司層)。
  • §2.3 的 ecpay_fee_bps / fongshou_fee_bps / profit_tax_bps 三費率保留但降為「參考預估」:團控 / 線控頁可顯示一個明確標示「預估」的 per-trip 淨利(毛利 − 預估費率),純給現場快速感覺,不是公司財務真相。公司淨利一律以本檔月損益表(實際 overhead)為準。
  • 避免雙重計:手續費 / 稅在公司層用實際值扣一次(§3.1),每梯次毛利不扣。

3. 邏輯 / 存取層

packages/core/src/finance/company-pnl.tsdb: ScopedDb)。純讀派生,沿用 money helper 口徑。

3.1 公司月損益 computeCompanyPnL(db, period)

營收
  團費收入        = Σ tour 訂單該期收入
  住宿 / 裝備收入 = Σ lodging / equipment / 現場代收
  其他收入        = Σ 額外收入(GS「二、額外收入總計」)+ 行政手續費收入(Σ refunds.admin_fee_twd,§3.3)
直接成本(各區毛利)
  逐梯次毛利 = 收入 − 真實成本(§2.3),按【區】分組彙整        ← 國內登山 / 東南亞 / 日本…
公司營業費用
  Σ operating_expenses(kind=opex/tax/platform_fee)            ← 辦公室 / 人事 / 稅 / 平台手續費(實際)
特殊損益(一次性,§3.4)
  Σ operating_expenses(kind=special)                          ← 取消床位沒收 / 一次性外幣損失等
= 公司淨利 = Σ各區毛利 + 其他收入 − Σ公司營業費用 ± 特殊損益

代收代付(pass-through)不入營收:第三方代收(露營區代收款等)是代收代付負債、非旅行社收入,不計入上面任何收入列;其收 / 匯回 / 代退款見 §3.5。

  • 分區(region):損益表上半按「區」分組(對齊 GS 國內登山 / 東南亞 / 中東非洲 / 日本)。區 = per-tenant 維度(不寫死荒野的區)。落地方式:pnl_regions 目錄表pnlr_<ulid>code 租戶內唯一穩定識別、display_namedisplay_orderis_active,停用不刪;CRUD 在 設定 · 損益分區 tab,operating_expense.manage)+ trips.pnl_region_id 指派(set null)。computeRegionMargins 的 region key / label 以 COALESCE(pnl_regions 目錄, 既有派生) 決定:行程有指派分區 → 用目錄('region:'||code key、display_name label、display_order 排序);未指派 → fallback 既有派生is_overseas'overseas:'||destinationis_climbing → 國內登山、其餘 → 國內其他)。向後相容:未建目錄 / 未指派的租戶行為與第一版逐字一致。行程指派欄在行程編輯頁基本 tab(僅進階會計模組授權時顯示;目錄來自 DB 用 Select)。
  • 平台手續費取實際月結(GS 就是 43,519 / 寰宇 1,440 這種對帳單實際數):記為 kind='platform_fee'operating_expenses 列;輔助「依交易量試算」鈕(費率 × 該期金流額)供對照,不取代實際數。
  • :營業稅(雙月)/ 營所稅(年實繳)記 kind='tax'period 歸屬攤提月(GS 5 月實繳 2025 營所稅 135,261)。
  • 取消梯次不入毛利:各區毛利只彙整實際出團的梯次(過濾 departures.status='cancelled');取消梯次的殘餘不可退成本結轉 kind='special'(§3.4),留存行政手續費認列其他收入(§3.3)。
  • 營收認列口徑(與 internal-external-ledger 同一真相):各區毛利的「收入」= 該梯次成交應收gross_receivable),期間歸屬 = 出團月(非收款月 / 付款月),見 internal-external-ledger §3.1。上面 code 的「Σ tour 訂單該期收入」即「Σ 出團月落於 period 的梯次成交應收」。其他收入(額外收入 / 行政手續費)與公司費用則按其 period 歸屬。純讀派生,不寫第二套金額;成本沿用 internal-external-ledger 毛利。

驗證對齊 GS 2026/05:各區毛利 1,043,222 − 公司費用(辦公室 643,307 + 稅 339,480 + 平台手續費 44,959 = 1,027,746)= 淨額 15,476。引擎輸出即這張損益總表。

3.3 行政手續費收入認列(GS 行政手續費 11,375)

退款 / 改期收的行政手續費(200 / 100 元/筆)是公司留存的收入(不退給客人那部分)。refunds.admin_fee_twdaccount-settlement §3.5)已逐筆記;損益表把 Σ refunds.admin_fee_twd(該 period)認列進其他收入(§3.1)。純派生、不另存。對齊 GS「登山總收款(含行政手續)」的行政手續費 11,375。

避免與毛利雙計:只認列未出團 / 取消單(未中籤 / 未成團 / 取消,該梯不在各區毛利)的 admin_fee_twd已出團梯次的退款 / 改期(其成交應收已計入該梯毛利收入、且 receivable_reduction 只減退掉的部分、留存的手續費仍在應收內)其 admin_fee 不另認列,否則與毛利收入重複。實作以「退款所屬 departure 是否成行」分流。

3.4 一次性特殊損益事件(GS 五月特殊事件)

非經常性的一次性損益(GS:取消 2026/6/17–21 神山床位虧損 RM$4,000 沒收訂金)——operating_expenseskind='special',損益表獨立列「特殊損益」(在公司營業費用之外、淨利之上)。可為損(沒收 / 賠償)或益(一次性收益)。外幣事件沿用成本側多幣別(currency + foreign_amount + 匯率快照,currency-exchange)—— RM$4,000 × 當日匯率 round 成台幣。與經常性 opex 分開,避免污染營運費用率。

取消梯次殘餘成本結轉(2026-07-03 已定案,選項 C):取消的梯次排除於各區毛利computeRegionMargins / internal-external-ledger 的梯次列表過濾 departures.status='cancelled')——取消梯次沒有「出團月」,其 0 收入 / 正成本混入毛利會讓區間比較失真。已發生、退訂沖銷後殘餘不可退的成本(含分房房費 departure_rooms.base_cost_twd)在梯次取消時結轉一筆 kind='special'operating_expensesperiod = 取消月、摘要含團名 / 梯次連結、寫 audit;GS 神山床位虧損即此型)。與 §3.3「行政手續費只認未出團 / 取消單」對稱:取消梯次的收入面(留存手續費)與成本面(殘餘損失)都在公司層認列,毛利只反映實際出團。結轉是人工確認動作(線控 / 會計在取消流程沖銷可退成本後執行),不自動——自動結轉會把「還在退訂協商中」的成本提早認列為損失。

結轉列的生命週期規則(防雙計 / 防漂移):

  • 連結與冪等:結轉列帶 source_departure_id 連回梯次,partial unique 保一梯次至多一筆(併發雙結轉 DB 層擋下);origin='departure_conversion'status='confirmed'(即計入損益)。
  • 撤銷:撤銷結轉=刪除該費用列(寫 audit;已連出款核簽 payable_id 者拒絕)。撤銷後可重新結轉。
  • 反向守衛(所有離開 cancelled 的路徑):已結轉的取消梯次不得直接改回非 cancelled 狀態——否則其成本回到毛利、special 費用仍在=雙計;須先撤銷結轉。守衛釘在每一條狀態轉換路徑:梯次狀態變更(updateDepartureStatus)與結團completeDepartureInTx——取消梯次一律不可結團,不只已結轉者;結團述詞若只擋 completed 會把取消梯次翻成 completed 繞過守衛)。
  • 結轉凍結(成本輸入鎖):已結轉梯次的殘餘成本輸入不得再變動——成本登記 / 編輯 / 刪除 / 嚮導申報覆核、房費(加房 / 刪房 / 改 base_cost_twd)、範本顯式套用與手改——否則 residual 與 special 脫鉤的 delta 在毛利(梯次已排除)與 special(金額不動)兩邊都看不到=靜默漏失。要改一律「撤銷結轉 → 改 → 重新結轉」。自動路徑(建單 / 取消 / 排班 / 派車觸發的範本重算、建梯次 auto-apply)對已結轉梯次靜默跳過(不可炸掉宿主交易;跳過即凍結)——跳過檢查必須先 FOR UPDATE 鎖梯次列(與結轉同鎖序)再讀結轉狀態,純讀檢查會與進行中的結轉競態(重算改了成本、結轉卻用舊殘餘=靜默 delta)。所有守衛與結轉本身都以 departures 列鎖為序列化錨點。DB 層另有 origin='departure_conversion' ⇔ source_departure_id IS NOT NULL 雙向 CHECK 防禦縱深。
  • 編輯鎖:結轉列不可經一般費用編輯改動(改科目會悄悄脫離特殊損益列、改 period 會移動認列月),一律走「撤銷 → 重新結轉」。
  • 結轉金額人工可調(接受的設計)amountTwd 預設殘餘、人工可調(部分殘餘可能事後拿回 / 有帳外損失);audit metadata 同時記 residualCostTwdamountTwd 留差額軌跡。結轉凍結使 residual 不再能事後漂移——差異只剩結轉當下的人為判斷。
  • 掛帳台帳劃界:排除取消梯次只屬毛利側(各區毛利 / 內外帳梯次列表);掛帳台帳是現金 / 應付追蹤視圖,其梯次彙總仍含取消梯次(欠廠商的錢照樣要追,且需與成本掛帳 / 應付清單區塊對得上)。

3.5 第三方代收代付(pass-through,GS 露營區代收款匯回 / 代退款)

替合作方(露營區等)代收款項、再匯回對方、處理代退款 —— 錢是過路、非旅行社收入 / 費用

  • 代收:收到的款掛代收代付負債(pass-through),標記 is_passthrough不入損益營收(§3.1 已排除)。
  • 匯回合作方:開 payables(payee = 合作方)出款,或經 account-settlement account_transfers 帳戶間移轉(GS:永豐 → 台新 186,982)。
  • 代退款:從代收負債退回客人(GS 代退款 28,910),走 refunds 但標 pass-through、不認列收入沖減。
  • 載體沿用 travelinvoice-integration 的代收轉付 pass-through 語意(擴及商業合作方,非僅政府收據);本檔只負責「不入損益」這條界線。

4. UI 與權限

4.1 版面

  • 損益表 / 財務總覽(獨立 nav)/admin/pnl):跨梯次功能 → 獨立 nav(線控 UX 原則:跨梯次才獨立 nav)。選月份 → 上半「各區毛利 + 其他收入」、下半「公司營業費用(按類別)」、底「公司淨利」。對齊 GS 損益總表。
  • 公司費用登記:損益頁內 dialog / 子頁登錄 operating_expenses(類別 / 月 / 金額 / 出帳帳戶 / 是否走核簽 / 摘要);月固定費用(租金 / 固定薪)可從上月帶入 placeholder。
  • 費用類別維護設定 加「費用類別」(expense_categories CRUD),租戶自管。
  • 每梯次:團控 / 內外帳頁的 per-trip「預估淨利」改顯示「毛利(權威)+ 預估淨利(參考)」(§2.3)。

4.2 權限

action用途opadminaccountant
operating_expense.read看公司費用 / 損益表
operating_expense.manage登錄 / 更正公司費用、維護費用類別
  • 公司損益 / 費用是敏感全局財務 → 鎖 admin / accountantop / sales / guide 無(連每梯次淨利都不對線控顯示,見 internal-external-ledger §4)。
  • 走核簽的費用沿用 payable 既有權限;本 resource 只管費用列與損益。

5. 開放議題

  • 月固定費用自動帶入(已定案落地,§2.2.1):範本表 recurring_expense_templates + 每月月底排程生成下月 status='draft' 草稿(origin='recurring'source_template_id 冪等鍵)+ 人工確認流(confirmOperatingExpense,可先改金額)。損益只計 confirmed 保住「避免無人確認的鬼列」。fan-out 比照台銀牌告 sync(單一租戶失敗不中斷、同月重跑冪等)。
  • 區(region)維度落點(已定案落地,§3.1):新增 pnl_regions per-tenant 目錄 + trips.pnl_region_id 指派;computeRegionMarginsCOALESCE(目錄, 既有派生) 分組,未指派向後相容 fallback。
  • 平台手續費實際 vs 試算:已定取實際月結(§3.1),試算僅輔助;未來串金流商對帳檔自動帶入。
  • 月結薪資 workflow:領隊月結薪資(Σ per-trip 領隊費 + 行政薪 + 勞健保 → 批次轉帳)是獨立 payroll 系統,本檔只收「行政固定薪」一筆 opex;payroll 另案。
  • 跨期 / 年度:營所稅是年度數攤到月,跨年結轉與年度損益留未來會計模組。

Changelog

版本日期變更Commit
82026-07-03§3.4 取消梯次結轉全鏈實作落地(選項 C 工程半場):引擎過濾(computeRegionMargins + 內外帳梯次列表排除 status='cancelled'includeCancelled opt-in)+ 結轉流程(內外帳頁「取消梯次待結轉」卡 + 結轉 / 撤銷 dialog、operating_expenses.source_departure_id partial unique 一梯一筆、origin='departure_conversion')+ 生命週期規則入文(撤銷刪列、反向守衛、結轉列一般編輯鎖 CONVERSION_LOCKED、掛帳台帳彙總仍含取消梯次的劃界)。Codex 對抗覆核第二輪追加兩個防雙計 / 防漏失守衛:①結團路徑補洞(completeDepartureInTx 一律拒絕取消梯次——原 status <> 'completed' 述詞會把已結轉取消梯次翻成 completed=殘餘雙計)②結轉凍結(已結轉梯次的成本 / 房費 / 範本輸入一律擋 DEPARTURE_CONVERTED,自動重算路徑靜默跳過)。API /internal-external-ledger/cancelled-departures{,/convert,/revert} + CLI 鏡像,皆閘進階會計模組。
72026-07-03取消梯次殘餘成本結轉(已定案,選項 C)(§3.1 / §3.4):取消梯次排除於各區毛利(過濾 departures.status='cancelled');已發生、退訂沖銷後殘餘不可退的成本(含房費)於梯次取消時人工確認結轉一筆 kind='special'operating_expenses(period=取消月、連結梯次、audit)。與 §3.3 admin_fee 口徑對稱:取消梯次的收支都在公司層認列,毛利只反映實際出團。GS 先例=神山床位虧損。引擎過濾與結轉流程待實作(狀態見 roadmap)。
62026-07-03T2 月固定費用自動帶入 + 損益分區目錄(§5 兩條 follow-up 落地):(§2.2.1) 新表 recurring_expense_templates(範本 CRUD)+ operating_expensesstatus(draft/confirmed,default confirmed 零回歸)/ origin(manual/recurring)/ source_template_id(partial unique (source_template_id, period) 冪等);每月排程 generate-recurring-expenses 逐 active 租戶 fan-out 生成下月 draft(比照 sync-bot-rates 四件套 + scheduler.tf「0 6 25 * *」月底生下月,2026-07-03 拍板);/admin/pnl 待確認草稿卡 + confirmOperatingExpense(FOR UPDATE、只確認 draft、可改金額、audit operating_expense.confirm);設定新增「月固定費用」tab。(§2.2 / §3.1 最關鍵) computeCompanyPnL 只計 status='confirmed'(草稿不入損益)。(§3.1) 新表 pnl_regions(per-tenant 分區目錄)+ trips.pnl_region_id 指派;computeRegionMarginsCOALESCE(目錄, 既有派生) 分組、未指派向後相容 fallback;設定新增「損益分區」tab + 行程編輯頁指派欄。權限沿用 operating_expense.read/manage,cron 走 x-job-token。e2e 48-recurring-expenses-pnl-regions
52026-06-28F5 實作落地 + 雙審修正computeCompanyPnL / operating_expenses / expense_categories / /admin/pnl / 設定費用類別 tab 全數實作(e2e 38-pnl-expense-categories)。審查修正:(資料表) incurred_onnullable(對齊 schema / UI「選填」,code is truth);(§2.2) 公司費用更正 UI 落地updateOperatingExpenseAction + 明細列鉛筆編輯,整列覆寫 + audit,payable_id 以 hidden 欄原樣帶回不清空);(§3.3) computeAdminFeeIncome 認列述詞註解修正為實作語意(NOT EXISTS completed = 訂單無已成行梯次才認列;現行一單一梯次故等價,跨梯次精確歸屬需 refund.departure_id,列 follow-up)。
42026-06-28金流→會計流程一致性修正 #2/#3/#4:(§3.1) 收入口徑釘死「出團月 × 成交應收」(對齊 internal-external-ledger §3.1);(§2.2 型態④) 行政薪單一真相——出款批次「直接外加」確認時生成 / 連結 operating_expenses(salary_admin)payout_batch_line.operating_expense_id),毛額=損益、淨額=匯出,不得損益頁 / 批次頁各登一次;(§3.3) admin_fee 只認列未出團 / 取消單,已出團梯次其手續費已含毛利收入、不重複認列。
32026-06-25GS 202605記事整頁稽核補缺口(淘汰 GS 不可缺漏):§3.3 行政手續費收入認列(Σ refunds.admin_fee_twd → 其他收入,GS 11,375);§3.4 一次性特殊損益kind='special',損益表獨立列,含外幣事件如神山床位虧損 RM$4,000);§3.5 第三方代收代付(露營區代收 / 匯回 / 代退款=pass-through 不入損益,載體沿用 travelinvoice + account-settlement);§2.2 成本拆分(公司贊助 vs 老闆個人,只記公司負擔)。§2.1 kind 加 special。考勤(HR)維持外部、供應商預付確認 payables 夠用(不補)。未實作。
22026-06-25逐筆明細 + 代墊者(§2.1 / §2.2,回應 GS 辦公室支出明細 B673–B713 約 30 筆):費用類別放寬到細科目(房租 / 行政薪資 / 勞健保 / 行銷廣告 / 水電 / 電信 / 保險 / 招募 / 文具…),損益表按 kind roll-up 成 辦公室 / 稅 / 手續費 三 bucket、點開 drill-down 到逐筆;operating_expensesfronted_by_user_id代墊者,非空 → 走請款回補代墊者)。三種出款型態(公司帳戶直接 / 人代墊待回補 / 金流商內扣)。「不做」改為不做 HR 算薪 / payroll;嚮導月結批次匯出(出納面)移 control-finance §5.5未實作。
12026-06-25初版(會計系統最後一塊:公司層級,spec / wireframe 先行):expense_categories(per-tenant 費用類別,kind=opex/tax/platform_fee)+ operating_expenses(公司營業費用,無 departure/order,period 歸屬、可選掛 payable 核簽、paid_from_account 接對帳)+ computeCompanyPnL(各區毛利 + 其他收入 − 公司費用 = 公司淨利,對齊 GS 2026/05 淨額 15,476)。每梯次「預估淨利 → 毛利」降級(手續費 / 稅移公司層用實際值扣一次,避免雙重計;三費率保留為 per-trip 參考預估)。GS 0501 玉山鐵證:「人員成本」= 領隊費 = 每梯次直接成本(領隊經 guide-portal 自填),非公司人事;公司人事只收「行政固定薪 + 勞健保」。月結薪資 workflow 另案。新 resource operating_expense。獨立 nav 損益表 + 設定費用類別。連改 internal-external-ledger(淨利→毛利)。未實作。