會議費用報銷
從同一資料列產生兩份試算表,兩者總計相同,並將它們引用的每張收據儲存到 <conference folder>/החזרים/קבלות/:
- SENT 檔案
<conference folder>/החזרים/<full name> הוצאות.xlsx— 唯一會提交給財務部門的檔案。B 欄סעיף= 預算表類別;包含收據工作表;銀行區塊;匯率。無預算 vs 實際比較。 - INTERNAL 檔案
<conference folder>/החזרים/<full name> הוצאות - פנימי.xlsx— 用戶的本地副本,永不附加或寄出。B 欄השירות= 每個項目的用途(例如 "קפה"、"רכבת שדה–עיר"),在הערות欄之後有一個סעיף類別欄,以及預算比較表。
兩個檔案都是希伯來文且從右到左排列;與用戶交談時使用英文。版面配置來自內建的 assets/claim-template.xlsx(僅標籤);用戶無需提供試算表。
個人資料(全名與銀行帳戶詳細資訊)。 讀取 ~/.config/conference-reimbursement/profile.json({"full_name": "...", "bank": {"בנק": "...", "סניף": "...", "מספר חשבון": "..."}})。如果缺少或不完整,請使用 AskUserQuestion 工具詢問缺少的欄位(用戶自行輸入值作為回答),然後將檔案儲存為權限 600。僅將其保留在此處 — 不在任何儲存庫或專案資料夾內。絕不提交,絕不在聊天或報告中列印銀行詳細資訊(改說「銀行詳細資訊:來自個人資料」),且僅將它們複製到暫存區域規格的 bank 鍵中。
透過 AskUserQuestion 工具向用戶提出每個問題 — 切勿使用散文 — 一次一個決定,建議選項優先。
選擇模式
- 模式 A — 完整報銷。 已核准的預算表 PDF、銀行詳細資訊(個人資料)、收據資料夾和郵件信箱存取權限皆可使用。執行步驟 1–7。
- 模式 B — 部分輸入。 其中一項或多項缺失。執行相同步驟,遺漏的部分則略過,絕不憑空捏造:
- 用戶拒絕提供銀行詳細資訊 → 省略
bank;指令稿會寫入空的標籤儲存格並警告「缺少銀行詳細資訊 — 請手動填寫」;在報告中回報; - 無郵件信箱存取權限 → 僅使用用戶放入
קבלות/的檔案;回報未搜尋電子郵件;在步驟 7 列印郵件內文而非草擬; - 無預算表 → 省略
budget;INTERNAL 檔案將在沒有預算表的情況下建立,且不會與核准金額進行比較。
- 用戶拒絕提供銀行詳細資訊 → 省略
在報告中列出每個模式 B 的缺口,標題為「需要手動完成」。
1. 收集輸入(唯讀)
- 已核准預算。 打開會議資料夾中的差旅預算表 PDF(
*טופס נסיעות*)。自行閱讀;各機構表格不同。以美元記錄每個核准的項目(每日津貼 אש״ל、機票 טיסה、飯店、保險、註冊費、其他)以及旅程日期。 - 個人資料。 按照上述說明載入全名和銀行詳細資訊(僅第一次詢問)。
- 實體收據。 列出
קבלות/並讀取每張圖片(先將 HEIC 轉換,步驟 3)。記錄日期、提供商、金額、幣別、信用卡末四碼及用餐人數。 - 電子郵件收據。 在預訂日期 → 返回日期(再加約兩週)的範圍內,以及用戶的旅行標籤或資料夾中搜尋郵件信箱。一次性一起執行每個類別的查詢 — 首先閱讀
references/email-sources.md。尋找用戶列出項目之外的內容:找出未注意到的費用是此工作的一部分;逐一提出找到的項目。 - 排除其他旅程。 開啟視窗內的所有財務轉帳和所有機票預訂,比對會議、路線和日期。在報告中記錄每個排除項目。
2. 詢問政策決定
僅詢問適用的那些,一次一個決定,建議選項優先。這些預設值來自過往的一次報銷申請;它們是建議,而非機構規定。
- 共享飯店預訂 → 僅自己的房間(建議)/ 整個預訂。
- 共享餐食 → 全額帳單 / 僅自己的份額。標記所選選項以供承辦人員參考。
- 匯率 → 返回日的以色列銀行代表匯率,每種幣別一個匯率(建議)/ 每張收據日期的匯率。
- 共享項目(一張涵蓋兩人的海報發票)→ 報銷用戶的份額,並附上備註。
- 與機票一起購買的附加服務(座位、行李、保險)→ 歸入機票項目內(建議)。
3. 將收據儲存為 PDF
- 電子郵件附件。 如果郵件連接器返回的是郵件文字而非附件,請先重新檢查它現在是否能夠獲取附件;如果不能,請透過瀏覽器自動化下載(開啟郵件,點擊附件的下載圖示,然後將檔案從
~/Downloads移出)。如果沒有瀏覽器自動化,請要求用戶自行下載或將它們放入קבלות/。 - 沒有附件的電子郵件(訂單確認信)→ 列印成 PDF。
- 將每個檔案命名為
<什麼> <提供商> <文件編號>.pdf,使用希伯來文。 - HEIC 照片 → 在原始檔案旁新增一份 PDF 副本,絕不修改原始檔案。macOS:
sips -s format pdf IN.heic --out IN.pdf。其他地方請使用 Pillow 搭配 pillow-heif(如果已安裝),否則請要求用戶將照片匯出為 PDF 或 JPEG。 對於試算表的收據工作表,請將每張照片和螢幕截圖轉換為 JPEG,以其收據基礎名稱命名,放在暫存區域中(絕不能覆蓋原始檔):sips -s format jpeg -s formatOptions 70 -Z 1400 IN --out "<receipt base name>.jpg"。 - 讀取每份已儲存的 PDF。從文件中獲取金額,而非郵件文字。如果兩者不同,以文件為準並標記差異。
4. 建立試算表
-
為所使用的每種外幣,獲取所選日期的以色列銀行代表匯率(boi.org.il)。將日期放入
rates.label:שער יציג בנק ישראל, <dd.mm.yyyy>。絕不重複使用記憶中或先前報銷申請的匯率。 -
在暫存區域中撰寫規格 JSON。結構描述、版面配置和模式 B 行為:
references/spec-format.md;合成的實際範例:references/example-spec.json。從個人資料設定bank。省略template:內建範本是預設值。 -
資料列規則:
- 每張收據一列,按日期排序;
- 金額僅在一個鍵中:其原始幣別(
usd、eur,或也在rates中的其他代碼)或ils; receipt=קבלות/中的檔案基礎名稱,多個以+連接;note解釋任何承辦人員可能質疑的事項(共享帳單、半張發票、從飯店發票中拆分出的項目);line= 與budget中拼寫完全相同的預算項目名稱;SENT 檔案的 B 欄顯示它(僅類別,絕不是 "coffee" 或 "dinner" — 承辦人員看到的是核准類別),INTERNAL 檔案的סעיף欄和預算表也使用它;service= 項目的簡短希伯來文描述("קפה"、"ארוחת ערב"、"רכבת שדה–עיר");僅在 INTERNAL 檔案的 B 欄中顯示(省略則顯示類別);- 餐食,包括會議晚宴 → 歸入每日津貼項目中;
- 飯店發票上的餐廳費用 → 作為自己的餐食列,飯店列的金額相應減少。
receipt_images= 步驟 3 中的 JPEG(僅限本次旅程的照片和螢幕截圖)。它們會放入קבלות工作表,每列 5 張,每張有一個包含其檔案基礎名稱的標題儲存格。電子郵件 PDF 不嵌入;它們會放入步驟 7 的壓縮檔中。
-
執行:
python3 -I "${CLAUDE_PLUGIN_ROOT}/skills/conference-reimbursement/scripts/build_claim.py" spec.json一次執行寫入兩個檔案。它會列印一個 JSON,包含
output(SENT)、output_internal、total_ILS、total_USD和warnings。修正每個關於預算項目的警告;將模式 B 的警告帶入報告。output_internal預設為在 SENT 路徑的.xlsx之前加上- פנימי;僅在需要將本地副本放在其他地方時,才在規格中設定它。 -
除非設定
"overwrite": true,否則此指令稿拒絕覆寫任一輸出。永遠不要對用戶手動編輯過的檔案設定此項;請寫入一個新名稱或提出詢問。
5. 驗證
完成意味著已執行且已檢查。首先閱讀 references/pitfalls.md。
-
執行檢查:
python3 -I "${CLAUDE_PLUGIN_ROOT}/skills/conference-reimbursement/scripts/check_claim.py" spec.jsontotal/total_internal:指令稿的 Python 總計等於每個檔案中סה״כ בש״ח儲存格在 LibreOffice 重新計算後的值(精確到 0.01 謝克爾),因此兩個檔案具有相同總計;sent_no_budget:SENT 檔案不包含預算比較表;receipts:每個引用的檔案都存在於קבלות/;budget:每列的 line 都是一個預算項目,且 INTERNAL 檔案的預算表實際總計等於total_ILS / USD rate。
將
not_run檢查回報為未執行,絕不回報為已通過。 -
獨立稽核:啟動一個子代理,僅給它 SENT 試算表和收據資料夾 — 不給你的結論。要求它檢查每一列的金額、幣別、日期和檔案是否與收據相符,並列出任何財務承辦人員可能質疑的事項。修正真正的錯誤;回報其餘部分。
6. 報告
按此順序:
- 兩個檔案的路徑(SENT,用於附件;INTERNAL,僅限本地)、資料列數、總計謝克爾和約當美元以及與核准總計的比較。
- 新增的收據(以及哪些是在用戶列表之外找到的)。
- 使用的匯率,包含來源和日期。
- 超出預算的項目,以表格呈現:項目、核准金額、實際金額、差異。
- 來源之間的差異(電子郵件 vs 文件)。
- 排除項目(屬於其他旅程的項目)。
- 承辦人員標記(來自
references/pitfalls.md)。 - 需要手動完成的事項(模式 B 缺口、指令稿警告)。
- 未經詢問即做出的決定。
7. 草擬寄送給財務聯絡人的電子郵件
首先閱讀 references/email-draft.md;依序遵循。僅使用並附加 SENT 檔案(output,<full name> הוצאות.xlsx);絕不附加、上傳或引用 INTERNAL - פנימי 檔案 — email_summary.py 會拒絕它。簡而言之:
- 閱讀用戶先前與財務聯絡人的報銷申請郵件串(已寄件備份,大約兩年前,包含回覆),並複製其風格和主旨模式。
- 詢問:銀行詳細資訊是否包含在內;預算或匯率行(預設:都不包含);密件副本給同行旅伴(預設:不;絕不憑空捏造地址)。
scripts/zip_ereceipts.py spec.json→קבלות אלקטרוניות.zip,包含電子收據 PDF(UTF-8 名稱;絕不使用 macOS 的zip指令)。照片和螢幕截圖則放入קבלות工作表。scripts/email_summary.py spec.json …→ RTL HTML 內文("היי ," / "מה שלומך? :)" … "תודה רבה!")、摘要表格,其中包含一個קבלה欄,說明每張收據的位置,以及從試算表讀取的銀行詳細資訊。- 檢查其
total_ILS是否等於建置階段的總計;提及任何rounding_diff。 - Gmail
create_draft,先使用htmlBody。然後透過 Chrome 中的 Claude(在草稿的撰寫檔案輸入上使用file_upload)附加 SENT 試算表和壓縮檔,並確認兩者都已附加 — 連接器僅在接受呼叫時將附件作為 base64 傳入,而update_draft會捨棄它們。絕不寄出。提供用戶草稿連結。
公式
- 資料列:
ILS_i = amount_i × rate[cur_i],或謝克爾金額本身。 - 總計:
T = Σ ILS_i;以美元計:T / rate[USD]。 - 每個預算項目 ℓ(INTERNAL 檔案):
actual_ℓ = Σ_{line_i = ℓ} ILS_i / rate[USD];diff_ℓ = approved_ℓ − actual_ℓ,負數表示超支。當每列的 line 都在預算中時,Σ_ℓ actual_ℓ = T / rate[USD]。
範例:匯率 USD 4.00,EUR 4.50;註冊費 $500,飯店 €600,計程車 ₪200 → 2,000 + 2,700 + 200 = 4,900 謝克爾 = $1,225。
判斷事項
- 飯店自己的發票優先於訂房網站的確認函(它是稅務文件)。
- 銀行詳細資訊來自本地個人資料,放入規格的
bank鍵;指令稿按標籤寫入。僅透過 AskUserQuestion 詢問,絕不透過散文,也絕不回顯。 - 屬於此旅程的先前部分報銷 → 將那些資料列標記為已報銷。
- 用戶所屬機構的規則決定政策問題;應提出詢問,而非斷言規則。
參考資料
references/email-sources.md— 各類別的郵件信箱查詢及應檢查事項(步驟 1.4)。references/spec-format.md— 規格鍵、兩個檔案的版面配置、指令稿輸出、模式 B 行為(步驟 4)。references/example-spec.json— 合成的完整規格(步驟 4)。references/pitfalls.md— 先前見到過的失敗案例及承辦人員標記檢查清單(步驟 5–6)。references/email-draft.md— 電子郵件草稿:先前的郵件串、措辭、附件(步驟 7)。