MAS-166: 立替精算STLの振込先名データ改善
概要
| 項目 | 内容 |
|---|---|
| 案件ID | MAS-166 |
| カテゴリ | 外部データ取込 |
| Phase | P1.5 |
| 優先度 | ★★ |
| 所要時間 | 2-3時間 |
| 対象ファイル | 400_domain/410_subledger_engine.js, 500_import/502_bank_importer.js, 800_ops/808_migration_i24.js(新規), 100_config/101_sys_config.js |
| 前提案件 | MAS-145(銀行CSV取込), MAS-162(合算マッチング) |
| 実装日 | 2026-04-17 |
目的
立替精算STLの決済口座名に「振込先名(個人名)」を付加することで、銀行CSVの実振込データと突合可能にする。これにより給与振込+立替精算をまとめた振込(1明細に複数STL対応)の自動合算マッチを実現する。
背景: なぜこの変更が必要だったか
MAS-162 で合算マッチを実装したが、給与STL + 立替精算STL のパターンが成立しなかった。原因は合算マッチの「同一取引先グルーピング」ロジック:
- 給与STL:
取引先名=代表取締役,決済口座=口座振込_福井銀行 - 立替精算STL:
取引先名=立替先(例: Amazon等),決済口座=立替精算 - 実際の銀行振込: 代表取締役宛に給与+立替精算をまとめて振込
取引先名でグルーピングすると両者が別グループになり合算できない。決済口座に振込先名を付加することで「受取人」という第二のグルーピング軸を導入し、横断合算を可能にした。
実装済みの設計判断
1. 振込先名のシステムパラメータ化
03_sys_params に CFG_REIMBURSEMENT_PAYEE を追加(例: 代表取締役)。
- Action A(自動仕訳エンジン)が立替精算STLを生成する際、決済口座を
立替精算_{CFG_REIMBURSEMENT_PAYEE}とする - 立替者が変わった場合はこのパラメータだけ更新すれば追随
- 未設定時はフォールバックせず立替精算のまま(後方互換)
2. 決済口座のフォーマット: 立替精算_{個人名}
プレフィックス 立替精算_ + 個人名とする。理由:
- 銀行CSVアダプターの
accountKeysは完全一致ベース → プレフィックス一致を追加実装 substring(5)で個人名を取り出して合算グルーピングに使用(立替精算_は5文字)
3. 銀行CSVアダプターに accountPrefixes を追加
BANK_ADAPTERS の各アダプターに accountPrefixes: ['立替精算_'] を追加。extractBankCandidateStls_ を拡張し、完全一致(accountKeys)orプレフィックス一致(accountPrefixes)のどちらかで候補に含める。
4. 合算マッチの2段階グルーピング
502_bank_importer.js:198-215 の Pass 2 に payeeグループ を追加:
| 段階 | グルーピングキー | 用途 |
|---|---|---|
| 1 | vendor(取引先名) | 同一取引先の複数STL合算(MAS-162既存) |
| 2 | payee(受取人) | 給与 + 立替精算の横断合算(MAS-166新規) |
payeeKey は次のように算出:
- 決済口座が
立替精算_XXX→payeeKey = XXX - それ以外 →
payeeKey = vendor
vendorグループで先にマッチしなかった場合のみ payeeグループを試行。順序が逆だと、同一取引先内の合算が先取りされる可能性があるため。
5. candidate に account フィールド追加
extractBankCandidateStls_ の戻り値に account を追加(L480)。Pass 2 の payeeKey 算出で決済口座を参照するため。
6. マイグレーション: 既存STL更新 (808_migration_i24.js)
実装前に生成された 33_wrk_bank のSTL(決済口座=立替精算)を一括更新する冪等スクリプト。
CFG_REIMBURSEMENT_PAYEE未設定時はエラーダイアログで停止決済口座 === '立替精算'の行のみ更新(既に立替精算_で始まる行はスキップ)- 有効フラグ=FALSE はスキップ
- 手順: dev で実行・検証 →
npm run push:prod→ prod で実行
変更ファイルサマリー
| ファイル | 変更量 | 内容 |
|---|---|---|
400_domain/410_subledger_engine.js | +6行 | Action A の STL 生成時に payMethod を書き換え |
500_import/502_bank_importer.js | +15行 | accountPrefixes 対応、account フィールド追加、payeeグループ追加 |
800_ops/808_migration_i24.js | 新規59行 | 既存STLの決済口座一括更新スクリプト |
100_config/101_sys_config.js | +1行 | マイグレーションメニュー登録 |
エッジケース
| 条件 | 動作 | 理由 |
|---|---|---|
CFG_REIMBURSEMENT_PAYEE 未設定 | Action A は 立替精算 のまま(付加しない)、マイグレーションはエラー停止 | 後方互換。立替者が未確定の環境で誤データを生成しない |
| 立替者が複数(将来) | 現行は未対応。MAS-168 で対応予定 | MAS-168: 立替精算INVに「立替者」列を追加、INV 毎に解決 |
既存STLの決済口座が既に 立替精算_ で始まる | マイグレーションでスキップ | 冪等性確保(再実行しても重複更新しない) |
| 銀行明細の受取人がパラメータと不一致 | 通常の合算グループに流れる(payeeグループで一致せず、vendorグループで試行) | 2段階グルーピングのフォールバック |
| 同じpayeeに複数の給与STL(例: 月額給与+賞与) | matched=true ロックで二重消費防止(MAS-162と同じ) | MAS-162実装の合算ロック機構を継承 |
注意事項
- プレフィックスの文字数ハードコード:
substring(5)は立替精算_(5文字)の長さ前提。プレフィックスを変更する際は要更新。 - vendorグループ優先の順序:
comboMaps = [comboByVendor, comboByPayee]の順序を逆転させると MAS-162 の既存マッチに影響する。変更禁止。 - 33タブのSTL重複に注意: 実装デバッグ中に「同一INVに複数STL」という重複データが発見され、合算合計が合わないバグを起こした。根本対策は MAS-167(STL重複検出ツール)で別案件化済み。
- Action A の
payMethod書き換えは L247 の STL 生成ブロック内のみ。他の判定(needsStlOverride等)は元のpayMethod='立替精算'前提のため影響なし(立替精算は仕訳振替/資産計上でない任意文字列なのでSTL生成対象に入る)。
実データ検証
本番投入前に以下を確認:
03_sys_paramsにCFG_REIMBURSEMENT_PAYEEが設定されているか(未設定ならマイグレーションが停止)- 33_wrk_bank の既存STLで
決済口座=立替精算の件数(マイグレーション対象件数) - 銀行振込明細の受取人名と
CFG_REIMBURSEMENT_PAYEEの表記が完全一致するか(半角/全角、スペースの有無)
関連ドキュメント
| 仕様書 | 関連箇所 |
|---|---|
| MAS-145 銀行CSV取込 | 銀行CSVアダプター・2段階マッチングの基盤 |
| MAS-162 合算マッチング | vendorグループ合算の既存実装 |
| MAS-116 マイグレーション基盤 | 808_migration_i24.js のパターン準拠元 |
人間が検討すべき事項
| 検討項目 | ステータス |
|---|---|
CFG_REIMBURSEMENT_PAYEE のprod環境への設定 | 未実施(2026-04-17時点) |
prod環境での migrationI24 実行 | 未実施 |
| 将来の複数立替者対応 | MAS-168 として別案件化 |
| 33タブのSTL重複検出ツール | MAS-167 として別案件化 |
実装プロンプト(Claude Code 用)
※ 本案件は実装完了済み。以下のプロンプトは「同じ仕様で再実装する場合」「類似案件(例: 別の決済口座名バリエーション対応)の参考」として記録。
あなたはGAS会計システム(bizlp-gas-accounting)のシニア開発者です。
案件 MAS-166「立替精算STLの振込先名データ改善」を実装してください。
## 実行前タスク
以下のファイルを読み込み、既存実装を把握してください:
- `CLAUDE.md` — コーディング規約・ファイル番号体系・マイグレーション運用ルール
- `400_domain/410_subledger_engine.js` — Action A のSTL生成ロジック(L242 付近)
- `500_import/502_bank_importer.js` — 銀行CSVアダプター、合算マッチ Pass 2(L190 付近)、`extractBankCandidateStls_`(L455 付近)
- `docs/dev/dev_mas-162_bank_combo_match.md` — 合算マッチの既存設計(vendorグループ、matched ロック、日付昇順ソート)
- `docs/dev/dev_mas-116_migration_framework.md` — マイグレーションスクリプトの命名・冪等性ルール
- `800_ops/805_migration_d04_d06.js` もしくは `807_migration_i10.js` — マイグレーションの実装パターン
## 修正対象ファイル
- `400_domain/410_subledger_engine.js` — Action A の STL 生成ブロックへの6行追記
- `500_import/502_bank_importer.js` — `BANK_ADAPTERS` に `accountPrefixes` 追加、`extractBankCandidateStls_` のプレフィックス一致対応、Pass 2 の payeeグループ追加
- `800_ops/808_migration_i24.js` — 新規作成(既存STL一括更新スクリプト)
- `100_config/101_sys_config.js` — 「🔧 マイグレーション」メニューに `migrationI24` を追加
## 実装内容
### Step 1: Action A の STL 生成時に決済口座を書き換え
`410_subledger_engine.js` の STL 生成ブロック(`payMethod` を確定する直前、L244 付近)に以下を追加:
var payMethod = String(row[invIdx['決済手段']] || '').trim();
const memo = String(row[invIdx['摘要']] || '').trim();
// MAS-166: 立替精算の場合、決済口座に振込先名を付加(銀行CSVマッチング用)
if (payMethod === '立替精算') {
var reimbPayee = Constants.getParam('CFG_REIMBURSEMENT_PAYEE', '');
if (reimbPayee) {
payMethod = '立替精算_' + reimbPayee;
}
}
### Step 2: 銀行CSVアダプターに accountPrefixes を追加
`BANK_ADAPTERS` の福井銀行アダプター(および他行があれば全て)に `accountPrefixes: ['立替精算_']` を追加。
`extractBankCandidateStls_` のシグネチャを `(bankData, bankIdx, accountKeys, accountPrefixes)` に拡張し、決済口座の判定を:
- `accountKeys.indexOf(acct) !== -1`(完全一致)
- または `prefixes` のいずれかで `acct.indexOf(prefix) === 0`(プレフィックス一致)
さらに candidate の戻り値オブジェクトに `account: acct` を追加。
### Step 3: 合算マッチに payeeグループを追加
`502_bank_importer.js` の Pass 2(L195 付近、vendor グルーピングの直後)に payee グルーピングを追加:
var comboByVendor = {};
var comboByPayee = {}; // MAS-166: 給与+立替精算の合算用
for (...) {
var vKey = candidates[s3].vendor || '_unknown';
if (!comboByVendor[vKey]) comboByVendor[vKey] = [];
comboByVendor[vKey].push(s3);
var cAcct = candidates[s3].account || '';
var payeeKey = (cAcct.indexOf('立替精算_') === 0) ? cAcct.substring(5) : vKey;
if (!comboByPayee[payeeKey]) comboByPayee[payeeKey] = [];
comboByPayee[payeeKey].push(s3);
}
探索ループは vendor→payee の順(`comboMaps = [comboByVendor, comboByPayee]`)。vendorで見つかったら payee は試行しない。
### Step 4: マイグレーションスクリプト
`800_ops/808_migration_i24.js` を新規作成。仕様:
- 関数名 `migrationI24`
- `CFG_REIMBURSEMENT_PAYEE` を取得、未設定なら UI アラートで停止
- 33_wrk_bank を全走査し、`決済口座 === '立替精算'` の行のみ `立替精算_{payee}` に更新
- 有効フラグ=FALSE はスキップ、既に `立替精算_` で始まる行はスキップ(冪等性)
- 完了時に `Utils.logInfo` と `SpreadsheetApp.getUi().alert` で更新件数を通知
### Step 5: メニュー登録
`101_sys_config.js` の「🔧 マイグレーション」メニューに追加:
.addItem('MAS-166: 立替精算STLに起票者名付加', 'migrationI24')
## 制約
- `立替精算` 単独は後方互換のため残す。`CFG_REIMBURSEMENT_PAYEE` 未設定時は書き換えない
- vendor→payee の探索順は固定。逆にすると MAS-162 の既存マッチに影響
- `accountPrefixes` を未指定のアダプター(将来追加分)も壊れないよう `prefixes = accountPrefixes || []` で防御
- 33_wrk_bank への書き込みは列B(決済ID(STL))ではなく `決済口座` 列のみ。他の列は触らない
- MAS-162 の `matched=true` ロック機構は継承(二重消費防止)
## エッジケース
| 条件 | 期待動作 |
|------|---------|
| `CFG_REIMBURSEMENT_PAYEE` 未設定 | Action A は元の `立替精算` のまま、マイグレーションはエラー停止 |
| 既存STLが既に `立替精算_XXX` | マイグレーションでスキップ(冪等) |
| 銀行明細受取人とパラメータが不一致 | payeeグループで一致せず、vendorグループにフォールバック |
| payee内に複数STL(給与+賞与+立替精算) | 全件合計一致 or 貪欲法 or 同一金額N件 で合算判定(MAS-162既存ロジック) |
| 決済口座の立替精算_プレフィックス文字数変更 | `substring(5)` がハードコードなので要同時更新 |
## 実データ検証
実装前に MCP で以下を確認:
- `03_sys_params` に `CFG_REIMBURSEMENT_PAYEE` の行が既存するか(なければ追加)
- 33_wrk_bank の `決済口座` 列で「立替精算」完全一致の件数(マイグレーション対象件数)
- 実際の銀行CSVで立替振込の「受取人名義」表記が `CFG_REIMBURSEMENT_PAYEE` と完全一致するか
## 動作確認
1. `npm run push:dev` で dev GAS にデプロイ
2. dev の `03_sys_params` に `CFG_REIMBURSEMENT_PAYEE` を設定
3. メニュー「🔧 マイグレーション → MAS-166: 立替精算STLに起票者名付加」を実行。更新件数が期待通りか確認
4. 新規に立替精算INVを起票 → Action A 実行 → 33_wrk_bank の新STLの決済口座が `立替精算_{payee}` になっているか確認
5. 36_wrk_bank_import に給与+立替精算をまとめた振込明細を投入 → 銀行マッチ実行 → `SUGGEST_COMBO` + 「合算候補」になるか確認
6. `matched=true` ロックで同じSTLが他の銀行明細で再利用されないことを確認
7. 既存のマッチ(MAS-162 vendorグループ単独)がリグレッションしていないことを別明細で確認
8. 問題なければ `npm run push:prod` で本番デプロイ、prod の `03_sys_params` 設定とマイグレーション実行
### 拡張思考の使用状況
| フェーズ | 拡張思考 | 備考 |
|---------|:---:|------|
| 既存コード把握(Step 0) | あり | MAS-162 の合算ロジックとの整合を理解する必要 |
| Step 1-2 実装 | なし | 挿入位置が明確 |
| Step 3 実装(payeeグループ) | あり | vendorグループとの探索順・グルーピングキー設計の判断 |
| Step 4-5(マイグレーション・メニュー) | なし | 807_migration_i10.js のパターン踏襲 |
推奨実行モデル
| 工程 | 推奨モデル | 理由 |
|---|---|---|
| Step 0(既存コード把握) | Sonnet | MAS-145/MAS-162 の既存実装と新規設計の接続を理解 |
| Step 1-2(Action A・アダプター拡張) | Sonnet | 挿入位置の特定と既存パターンの踏襲 |
| Step 3(payeeグループ追加) | Opus | vendor→payee 2段階の順序・グルーピングキー設計判断 |
| Step 4-5(マイグレーション・メニュー) | Haiku | 既存パターンのコピー+置換で済む |
変更履歴
| 日付 | 変更内容 |
|---|---|
| 2026-04-17 | 初版作成(実装完了後に知見を文書化) |
| 2026-04-17 | 実装プロンプト(Claude Code 用)と推奨実行モデルを追記 |