1. 概要・目的
法人クレジットカードの CSV 明細を 証憑管理簿(14列スプレッドシート)に 自動登録し、既存の受領証憑(レシート・領収書)と突合できる状態を作る機能。
前提:証憑管理簿の位置づけ
- スプシ ID:
1F6PTXD3ckob3EeglnS7gyjSG6RM0CS-PKRaoBwzXK-Eタブ名:証憑管理簿 - 14列(A〜N)構造、sheet_writer_v4.py で書き込む(connect8_ai 認証)
- Freee への書き込みは今回スコープ外。スプシが叩き台、確定は人間が Freee UI で実施
2. スコープ
| 項目 | 今回(v1.0) | 次フェーズ以降 |
|---|---|---|
| 対象カード | AMEX のみ(プロトタイプ) | 三井住友 / JCB / 楽天 等(アダプタ追加) |
| CSV 取込 → スプシ登録 | 設計確定・プロトタイプ実装 | LaunchAgent 常駐化 |
| PDF リネーム → Drive 保管 | 設計のみ(Drive 実書込なし) | CEO 承認後に実装 |
| INBOX フォルダ作成 | 提案のみ(作成は CEO 承認後) | 承認次第即時作成可能 |
| 突合エンジン(I列埋め) | 設計のみ | 次フェーズで実装 |
| Freee 連携 | スコープ外 | Phase C で対応 |
_proto_creditcard / dry-run のみ。
3. 全体フロー
3-1. CSV 取込フロー
INBOX_creditcard/ 投入(Drive)INBOX_creditcard/ を検知証憑管理簿 タブに append(G列=クレカ明細、E列=会社支払 固定)_processed/<YYYY-MM>/ へ移動・ログ記録3-2. PDF 明細保管フロー(設計のみ・実装は承認後)
INBOX_creditcard/ に投入YYYYMMDD_AMEX_明細_会社支払_クレカ明細.pdf 形式1qmG4ACZ-5H9Qh3R0hzIMkmBNJjZzIDAI(法人クレカ明細(随時保管))へ保管3-3. システム全体図
【投入】
CEO → INBOX_creditcard/ (Drive)
├─ CSV ファイル → うーぱん CSV パイプライン
└─ PDF 明細 → Codex リネーム → Drive 保管フォルダ
【CSV パイプライン】
INBOX_creditcard/
↓ カード判定
カード別アダプタ(amex_adapter.py / smbc_adapter.py[stub] / ...)
↓ 共通内部スキーマ
dedup チェック(日付+金額+外貨 vs 既存クレカ明細行)
↓
sheet_writer_v4.append_row() → 証憑管理簿タブ
↓ G列=クレカ明細
[次フェーズ] reconciler → I列(突合記号)埋め
【証憑管理簿(最終状態のイメージ)】
row 100: 2026-05-01 | 474 | 76,960 VND | GRAB | 会社支払 | 電子証憑 | 電子その他 | [レシートURL] | ◯ | ...
row 200: 2026-05-01 | 474 | 76,960 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | [明細URL] | ◯ | ...
↑ I列で突合
4. マッピング表(確定版)
4-1. AMEX CSV 列定義
| 列名(CSV) | 内容 | 備考 |
|---|---|---|
| ご利用日 | 利用日(例: 04/30) | MM/DD 形式、年度は会計年度から補完 |
| データ処理日 | AMEX が処理した日 | 取込には使わない(発生日は「ご利用日」) |
| ご利用内容 | 店舗名・サービス名 | 例: GRAB, AMAZON.CO.JP |
| カード会員様名 | 氏名 | マスク必須(スプシには書かない) |
| 会員番号# | カード番号 | マスク必須(下4桁のみ備考に記録) |
| 金額 | 日本円請求額(整数) | クレカ明細の正式請求額 |
| 海外通貨利用金額 | 現地通貨額(例: "9,360 VND") | 空の場合あり(国内利用) |
| 換算レート | 為替レート | 参考値(スプシ N列備考に記録) |
4-2. 証憑管理簿 14列へのマッピング
| 列 | 列名 | マッピング元(AMEX CSV) | 値の規則 |
|---|---|---|---|
| A | 発生日 | ご利用日 | YYYY-MM-DD 形式に変換(年度補完) |
| B | 金額(税込) | 金額 | JPY 整数・1円単位・丸め禁止 |
| C | 外貨 | 海外通貨利用金額 | 例: "76,960 VND"。国内は空欄 |
| D | 店舗・発行者名 | ご利用内容 | 原文ママ(正規化はしない) |
| E | 支払区分 | 固定値 | 会社支払(法人カード固定) |
| F | 証憑種別 | 固定値 | 電子証憑(CSV = 電子データ固定) |
| G | 証憑形式 | 固定値 | クレカ明細(CEO確定・VALID_VOUCHER_FORMS 登録済) |
| H | Drive URL | PDF 保管後の Drive URL | PDF 未保管時は空欄。=HYPERLINK(...) 形式 |
| I | 突合記号 | 空欄 | reconciler が後で埋める(次フェーズ) |
| J | Freee deal_id | 空欄 | Freee 連携フェーズで埋める |
| K | 信頼スコア | 0.95(固定) | CSV パースは高信頼。OCR 誤認なし |
| L | 要確認 | 基本空欄 | dedup 疑いの場合のみフラグ立て |
| M | 処理日時 | 実行時刻 | YYYY-MM-DD HH:MM JST |
| N | 備考 | カード名・元CSV・換算レート | 例: "AMEX / 20260510_amex.csv / rate:0.006 / card:****1234" |
card:****1234)。
氏名(カード会員様名)はスプシに一切書かない。
5. dedup(重複カット)仕様
5-1. 照合キー
証憑管理簿の既存行のうち G列 = "クレカ明細" の行に対して以下の3軸で照合する。
| 軸 | 照合方法 | 備考 |
|---|---|---|
| 発生日(A列) | 完全一致 | YYYY-MM-DD 正規化後 |
| 金額(B列) | 完全一致 | JPY 整数 |
| 外貨(C列) | 数値部分一致(通貨も一致) | 空欄同士は「一致」扱い |
5-2. 判定結果
| 判定 | 条件 | 処理 |
|---|---|---|
| 重複確定スキップ | 3軸すべて一致 | スプシへの書き込みをスキップ。ログに「dedup skip row=X」を記録 |
| 要確認 | 日付+金額一致・外貨不一致(例: 同日同額で通貨違い) | L列「日付・金額が row X と一致・外貨要確認」を記入。書き込みは実行 |
| 通常登録 | 一致なし | 通常 append |
6. 照合(reconciliation)方針
Phase 1(今回): 明細 side 登録
- クレカ CSV の各行を G列=「クレカ明細」として証憑管理簿に追加
- I列(突合記号)は空欄のまま
- 既存レシート行(G=電子その他 等)とは独立して共存
Phase 2(次フェーズ): 突合エンジン
以下のキーで「クレカ明細行」と「レシート行」を照合し、I列に突合記号を書き込む。
| 照合優先度 | キー | 条件 | 信頼度 |
|---|---|---|---|
| 高 | 金額(JPY)+ 日付(±3日) | JPY 完全一致 + 発生日が3日以内 | 0.9 |
| 高(海外) | 外貨金額 + 通貨 + 日付(±3日) | 外貨数値・通貨一致 + 発生日3日以内 | 0.95 |
| 中 | 店舗名(正規化後)+ 日付(±3日) | GRAB = grab 等の正規化後一致 | 0.7 |
| 低 | 日付(±1日)+ 金額(±5%) | ファジー一致。手動確認推奨 | 0.5 |
GRAB 分割計上の特殊ルール
問題: AMEX 明細が「1乗車 = 複数行」に分割計上されるケースあり
例: GRAB 57円(9,360 VND)+ 294円(47,840 VND)= 合計 351円(57,200 VND)
対応(Phase 2):
- 同日・同店舗の明細行を外貨合計で集計(合計照合モード)
- 合計が既存レシート行の外貨と一致 → 複数行まとめて同一突合記号を付与
- 合計照合は単一照合の次に試行(単一マッチが優先)
7. カード別 CSV アダプタ設計
7-1. 共通内部スキーマ(CardTransaction)
@dataclass
class CardTransaction:
use_date: date # 発生日(ご利用日)
amount_jpy: int # 日本円請求額(1円単位)
store_name: str # 店舗名(原文)
foreign_str: str | None # 外貨表示文字列 例: "76,960 VND"
card_label: str # カード識別名 例: "AMEX"
source_file: str # 元CSVファイル名
card_last4: str | None # カード下4桁(マスク済)
fx_rate: float | None # 換算レート(参考値)
7-2. アダプタ一覧
| カード | アダプタ | 状態 | 備考 |
|---|---|---|---|
| AMEX | amex_adapter.py |
実装済 | ヘッダ判定: "ご利用日" + "海外通貨利用金額" |
| 三井住友 | smbc_adapter.py |
スタブのみ | CSV サンプル待ち。ヘッダ: "利用日" + "利用金額(円)" 想定 |
| JCB | jcb_adapter.py |
スタブのみ | CSV サンプル待ち |
| 楽天 | rakuten_adapter.py |
スタブのみ | CSV サンプル待ち |
7-3. カード自動判定ロジック
- ファイル名に "amex" / "american" が含まれる → AMEX アダプタ
- ファイル名での判定不可 → CSV 先頭行のヘッダ列名を照合
- AMEX:
["ご利用日", "ご利用内容", "海外通貨利用金額"]が含まれる - 判定できない場合 →
_要確認/に退避・通知
7-4. アダプタ共通インターフェース
class BaseCardAdapter(ABC):
CARD_LABEL: str # "AMEX" / "SMBC" / etc.
@classmethod
def can_handle(cls, headers: list[str]) -> bool:
"""CSVヘッダ行から対応可否を返す"""
...
def parse(
self,
filepath: str,
fiscal_year: int = 2026, # 年度(MM/DD → YYYY-MM-DD 変換用)
) -> list[CardTransaction]:
"""CSV をパースして CardTransaction リストを返す"""
...
8. INBOX 提案(CEO 承認待ち)
CEO 判断ポイント:INBOX フォルダ作成の可否
現在の A10 Drive には法人クレカ CSV / PDF 専用の投入フォルダが存在しない。 以下の新規フォルダ作成を提案する。作成は CEO 承認後に実施。
8-1. 提案フォルダ
| フォルダ名(案) | 用途 | 親フォルダ |
|---|---|---|
INBOX_creditcard |
CSV / PDF の投入口(すべてのカード共通) | 経理 Drive ルート 1RbqJDW00aQGi9eqhaTdG_K0girAVHdkl |
8-2. フォルダ内の流れ(承認後)
INBOX_creditcard/ にドロップ(Drive/Telegram/Discord 共通)_processed/<YYYY-MM>/ へ移動1qmG4ACZ-5H9Qh3R0hzIMkmBNJjZzIDAI(法人クレカ明細(随時保管)フォルダ)へ移動8-3. SUICA ポーラーとの比較
| 項目 | SUICA ポーラー | クレカ CSV(今回) |
|---|---|---|
| 投入フォルダ | INBOX_suica | INBOX_creditcard(提案) |
| 処理スケジュール | 1時間毎 LaunchAgent | 日曜 23:30 or 手動(頻度低) |
| 対象ファイル | CSV のみ | CSV + PDF |
| 書込先 | SUICA 明細管理簿スプシ | 証憑管理簿スプシ |
9. AMEX プロトタイプ
9-1. テストタブ
プロトタイプの書き込み先:証憑管理簿スプシ内に一時タブ _proto_creditcard を作成。
主シート「証憑管理簿」本体には書かない。
9-2. フィクスチャデータ(AMEX GRAB 18件)
今会話で確認した実データ(2026年5月 ベトナム GRAB 利用)を fixture として使用。
9-3. 整形後の出力(dry-run)
以下が証憑管理簿 14列フォーマットに変換した結果。
| A 発生日 | B 金額(JPY) | C 外貨 | D 店舗 | E 支払区分 | F 証憑種別 | G 証憑形式 | H Drive URL | K 信頼 | N 備考(抜粋) |
|---|---|---|---|---|---|---|---|---|---|
| 2026-05-01 | 474 | 76,960 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | (PDF保管後) | 0.95 | AMEX / rate:0.006 |
| 2026-05-01 | 736 | 119,600 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-01 | 769 | 124,800 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-03 | 250 | 40,560 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-03 | 333 | 54,080 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-03 | 386 | 62,400 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-03 | 475 | 76,960 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-04 | 65 | 10,400 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-04 | 109 | 17,680 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-04 | 290 | 46,800 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-04 | 400 | 64,480 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-04 | 478 | 76,960 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-04 | 562 | 90,480 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-06 | 211 | 34,320 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-06 | 229 | 37,440 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-07 | 57 | 9,360 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-07 | 294 | 47,840 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 | |
| 2026-05-07 | 430 | 69,680 VND | GRAB | 会社支払 | 電子証憑 | クレカ明細 | 0.95 | AMEX / rate:0.006 |
合計 18 件。JPY 合計: 6,348 円。VND 合計: 1,030,720 VND
9-4. プロトタイプスクリプト
実装ファイル:2_Areas/A10_corporate_finance/phase_b_reimbursement/creditcard/amex_adapter.py
実行方法(CEO 承認後、テストタブへの書き込み時):
# dry-run モード(スプシへの書き込みなし・整形結果のみ出力) python amex_adapter.py --csv 20260609_amex_grab_charges.csv --dry-run # テストタブ書き込みモード(_proto_creditcard タブに書く・主タブは触らない) python amex_adapter.py --csv 20260609_amex_grab_charges.csv --test-tab
_proto_creditcard タブへの書き込み / dry-run 出力に限定。
10. CEO 判断ポイント
判断 1:INBOX_creditcard フォルダ作成の可否
Drive 経理ルート直下に INBOX_creditcard/ を新設する。
CSV・PDF 両対応の投入口として使う。
YES の場合:即時作成し drive_folder_ids.json を更新する。
NO の場合:手動パス指定でスクリプトを動かす運用も可能。
判断 2:テストタブへの書き込み実行の可否
証憑管理簿スプシに一時タブ _proto_creditcard を作成し、
AMEX fixture データ 18件を書き込んでよいか。
YES の場合:プロトタイプスクリプトを実行して実物を確認できる。
NO の場合:dry-run 出力(このHTML)で設計確認のみ。
判断 3:他カード(三井住友/JCB/楽天)の CSV サンプル提供
各カードのアダプタを実装するには CSV ヘッダ・サンプルデータが必要。
各カードの明細 CSV(個人情報マスク済みで可)を提供いただけるか。
提供可能なカードから順次アダプタを実装する。
判断 4:代表個人カード(将来)の支払区分ルール
現在は「法人カード = 会社支払」固定。
将来、代表個人カードの明細も同じパイプラインで扱う場合:
カードごとに支払区分を設定ファイルで切り替える設計を用意する(例: card_config.json)。
確認:代表個人カード(立替扱い)の CSV 取込を今後のスコープに含めるか。
判断 5:実突合エンジン(Phase 2)の Go / No-Go
明細 side 登録が安定稼働してから突合エンジン実装に進む。
Phase 1 完了後に Go / No-Go を判断いただきたい。
突合エンジンの前提:GRAB レシート行(既存証憑)が証憑管理簿に正しく登録されていること。
11. 変更履歴
| 日付 | バージョン | 変更内容 |
|---|---|---|
| 2026-06-10 | v1.0 | 初版作成(CEO 指示 2026-06-10 に基づく設計) |