cairn

成本與範本

每一梯次的成本是一行行登記出來的:你可以逐筆手填,也可以讓行程綁定一份「成本範本」,開梯時自動帶入成本行;其中數量還能依當下人數動態算出來。

理解這點,你才知道一筆梯次成本是怎麼產生的——是手填的 ad-hoc 列,還是範本套出來、會隨人數浮動的動態列。相關 API 是 cost-templatesdepartures 的成本端點。

梯次成本登記

成本掛在**梯次(departure)**上,不在行程、也不在訂單上。你向某梯次登記一筆成本行(品項 × 金額),它就計入該梯的成本:

操作端點
登記一筆成本POST /departures/{depId}/costs
修改 / 刪除一筆.../costs/{costId}(PATCH / DELETE)

每一筆成本行都帶品項category)、供應商vendorName)、金額amountTwd)等欄位。這是「現場作業」:線控、會計在團控頁逐筆登記實際支出,與下面的「範本設定」是兩件事、兩種權限。

說明

成本登記是「成本側」——你付給供應商 / 嚮導的錢。別跟「應收 / 收款」(客人付你的錢)混在一起;那一套是訂單金流,見 付款流程

成本範本(綁行程)

系列團(常態固定會開的團)的成本結構幾乎一樣:車資、餐費、保險、嚮導費、入山證……。與其每開一梯重打一次,你建立一份成本範本,把這些成本行的定義存起來,再綁到行程上:

操作端點
列出範本 / 取綁定清單(?active=1GET /cost-templates
建立範本POST /cost-templates
取範本完整內容(含成本行 lines[]GET /cost-templates/{id}
改範本 headPATCH /cost-templates/{id}
加 / 改 / 刪一條成本行.../{id}/lines.../lines/{lineId}

範本的每一條成本行(lines[])定義 品項 × 單價 × 數量規則categoryvendorNameunitPriceTwd,加上決定「要帶幾份」的 quantityMode。範本只是「設定」——管理範本是後台 setup 層的權限(cost_template.manage),與逐梯成本登記分開。

說明

範本綁定是一對一:一個行程綁至多一份範本。範本停用(statusarchived)後不能再綁新行程,但已套到既有梯次的成本行不受影響。

人頭公式與動態重算

範本成本行的「數量」有兩種:

  • quantityMode: "fixed"——固定份數(quantityFixed),不隨人數變。
  • quantityMode: "headcount"——人頭公式:把選定的人頭相加,再選填組距:
數量 = ceil( Σ(選定人頭) / 組距 )

選定人頭來自 headcountComponents,可多選 passenger(旅客)、leader(領隊)、assistant(協作)、driver(司機);groupDivisor 不填就是直接用人頭總和,填 N 就是「每 N 人一組」(無條件進位,不足一組仍算一組)。

想要的數量headcountComponentsgroupDivisor
旅客數["passenger"]
旅客 + 領隊數["passenger","leader"]
每 8 客配 1 領隊 ceil(旅客/8)["passenger"]8
ceil((旅客+司機)/8) 台車["passenger","driver"]8

套用後,headcount 列的金額會隨人數即時重算:報名成立 / 取消、領隊或協作指派異動、派車異動,平台都會在同一個動作裡重算這些列的 quantityamountTwd。你不需要自己呼叫重算——它跟著人頭變動自動發生。

把範本套到既有梯次(補套新加的成本行、或為尚未套用的梯次套用)用 POST /departures/{depId}/template-costs/apply,回傳 inserted 告訴你補了幾行。套用是冪等的——已存在的範本來源行不會重複插入。

外幣成本範本行

海外團的成本常以外幣發生(地接日幣、印尼盾)。一條範本成本行除了台幣,也可以直接定義成外幣行——不再手動換算,套用到梯次時由平台解析當下匯率、快照台幣金額。

每條範本行用 currency 決定幣別(ISO 4217,預設 "TWD"):

  • 台幣行currency: "TWD"):填 unitPriceTwd,外幣欄位留空。就是前面講的一般成本行。
  • 外幣行currency 非 TWD,如 "JPY"):改填 unitPriceForeign(外幣每單位單價,最小單位整數),並用 internalRateSource 指定內帳匯率怎麼來:
internalRateSource內帳匯率取自額外欄位
"fx_account"指定外幣帳戶的加權平均成本fxAccountId(該外幣帳戶,幣別須與成本幣別相符)
"published"當日台銀牌告
說明

範本層的外幣行只有這兩種內帳匯率來源,沒有「手填成交率」——手填實際成交率本質是逐筆交易當下的事,不適合存進可重用範本。真的要用手填率,套用後在梯次那一列逐筆改即可。外帳(可申報)匯率一律台銀牌告,不用選。

套用時解析、快照雙率

外幣範本行套用到梯次的當下(台北當天)才解析匯率,並把兩個匯率一起快照進該梯成本列:

外帳可申報額 = round( 外幣金額 × 台銀牌告即期賣出率 )
內帳真實額   = round( 外幣金額 × internalRateSource 解出的內帳率 )

快照之後,這一列的匯率就固定了:日後牌告變動、或帳戶加權平均成本浮動,都不回改已套用的成本列。連 headcount 外幣列因人數重算金額時,也是沿用快照匯率重乘新數量,匯率不漂移——只有數量在變。

注意

外幣行套用時 fail-closed:解析不出匯率(牌告當天還沒同步、或指定外幣帳戶還沒有期初餘額)時,平台會跳過那一條外幣行、不會默默用 0 或 1 帶過。套用回傳的 skippedForeign 會告訴你跳過幾行;其餘台幣行照常套用、不受影響。補齊匯率後再套用一次(冪等),被跳過的外幣行會自動補回。

多幣別只在成本側。營收一律台幣——這條界線與 內外帳與損益 講的一致,外幣雙率的完整語意(內外帳兩個匯率、查匯率端點)也在那篇。

逐行 override

自動算出來的金額不一定剛好。你可以手改某一行,覆蓋掉公式結果:

操作端點效果
手改某行金額POST /departures/{depId}/template-costs/{id}/override(帶 amountTwd該行 isManualOverridetrue停止自動重算
恢復動態.../template-costs/{id}/clear-override清除手改,下次人數變動重新依公式算

要看一梯目前所有範本來源的成本行(含是否手改、是否已轉請款),用 GET /departures/{depId}/template-costs。每一行回傳 quantity / unitPriceTwd / amountTwdisManualOverride、以及 payableId

注意

一旦 isManualOverridetrue,這行就凍結——人數再怎麼變都不覆蓋你手改的值,直到你明確 clear-override。另外,已轉請款(payableIdnull)的成本行也會被鎖定、不再重算。

與內外帳 / 損益的銜接

範本套出來的成本行就是一般梯次成本行,沒有特殊金流語意。它一樣帶內外帳維度:isDeclarable(是否可申報)與 invoiceAmountTwd(可申報額)。headcount 列重算金額時,可申報額預設跟著真實金額走;手改或設為不可申報則各自凍結。

也就是說,不論成本是手填還是範本帶出來的,往下游的內外帳、淨利、損益計算看到的都是同一種成本行——範本只負責產生初值,不改變它之後怎麼被認列。

下一步

Command Palette

Search for a command to run...