概要

項目内容
案件IDMAS-159
カテゴリ自動入力パイプライン(即効)
PhasePhase 1.5
優先度P1 (★★★)
所要時間1-2時間
対象ファイル100_config/101_sys_config.js, 500_import/501_cc_importer.js, 500_import/502_bank_importer.js
前提案件MAS-145, MAS-146

目的

銀行CSV(MAS-145)やクレジットカードCSV(MAS-146)を取り込む際、ユーザーが誤って「同じ期間のCSVを2回アップロード」したり「期間が重複するCSVをアップロード」した場合に、二重取込(B/Sの現預金残高の崩壊)を防ぐ。トランザクションのハッシュ値を用いて冪等性を担保する。

現在のコード

500_import/502_bank_importer.js (L116-120)

      if (importIdx['取込ハッシュ'] !== undefined) {
        importSheet.getRange(row, importIdx['取込ハッシュ'] + 1).setValue(
          computeTxHash_(tx.txDate, tx.memo, tx.deposit, tx.withdrawal)
        );
      }

※ハッシュは計算・出力されているが、重複チェックには使われていない。また、クレカ(501_cc_importer.js)にはハッシュ計算自体が存在しない。

修正方針

Step 1: DDLスキーマ変更

100_config/101_sys_config.js を修正し、33_wrk_bank34_wrk_card に「取込ハッシュ」列を追加する。

  • WRK_BANK: 末尾に 取込ハッシュ を追加。
  • WRK_CARD: 確認FLG の直前に 取込ハッシュ を追加。

Step 2: 銀行CSVの重複チェック実装

500_import/502_bank_importer.js を修正:

  1. importBankStatement 内で、33_wrk_bank の全行から 取込ハッシュ を読み込み、出現回数をカウントするマップ(bankHashMap)を作成。
  2. 36_wrk_bank_import の各行を処理する際、現在のインポート内でのハッシュ出現回数(importHashMap)をカウントアップ。
  3. importHashMap[hash] <= (bankHashMap[hash] || 0) の場合、既に取込済みの重複データと判定し、処理結果重複(取込済)確認FLGTRUE にしてマッチング処理をスキップする。
  4. applyBankSettlement 内で、33_wrk_bank を更新する際、36_wrk_bank_import取込ハッシュ33_wrk_bank に書き込む。

Step 3: クレカCSVの重複チェック実装

500_import/501_cc_importer.js を修正:

  1. computeCcHash_(payDate, merchant, amount) ヘルパー関数を追加。
  2. importCcStatement 内で、Step 2 と同様に 33_wrk_bank のハッシュ出現回数マップを作成。
  3. 34_wrk_card の各行に対してハッシュを計算・出力し、重複判定を行う。重複の場合は 処理結果重複(取込済)確認FLGTRUE にしてスキップ。
  4. applyCcSettlement 内で、33_wrk_bank を更新する際、34_wrk_card取込ハッシュ33_wrk_bank に書き込む。

影響範囲

  • 33_wrk_bank34_wrk_card の列構成が変更される。
  • 銀行・クレカの取込処理において、既に消込済みの明細と同じ内容の明細がインポートされた場合、自動的に「重複」としてスキップされるようになる。

注意事項

  1. 同日・同額・同摘要の複数明細への対応: 単純なハッシュの存在チェック(Set)ではなく、**出現回数のカウント(Map)**を用いること。これにより、本当に1日に2回同じ振込があった場合(例: 10,000円を2回振込)でも、1回目は重複、2回目は新規として正しく処理される。
  2. 101_sys_config.jsautoColssetVali の列インデックス変更を正確に行うこと。

エッジケース

条件表示値理由
過去に1件取込済みのハッシュが、今回のCSVに2件含まれている場合1件目: 重複(取込済)
2件目: 通常処理
出現回数ベースで判定するため、差分の1件のみが新規として扱われる
33_wrk_bank の有効フラグがFALSEの行カウントしない論理削除された明細は「無かったこと」として扱い、再取込を許可するため

実データ検証

  • 33_wrk_bank の既存データに 取込ハッシュ 列が追加された後、過去のデータにはハッシュが空欄となるが、空欄のハッシュは重複チェックから除外(無視)されるロジックになっているか確認。

関連ドキュメント

仕様書リンク関連箇所
dev_mas-145_bank_csv_import.md銀行CSV取込ロジック
dev_mas-146_cc_auto_settlement.mdクレカ自動消込ロジック

人間が検討すべき事項

なし(即実装可)


実装プロンプト(Claude Code 用)

あなたはGAS会計システム(bizlp-gas-accounting)のシニア開発者です。
案件 MAS-159「銀行・クレカCSV取込の重複防止(冪等性)ガード」を実装してください。

## 実行前タスク
以下のファイルを読み込んでください:
1. `100_config/101_sys_config.js` — `WRK_BANK` と `WRK_CARD` のヘッダー定義、`autoCols`、`setVali` の位置
2. `500_import/502_bank_importer.js` — `importBankStatement` と `applyBankSettlement` の既存ロジック
3. `500_import/501_cc_importer.js` — `importCcStatement` と `applyCcSettlement` の既存ロジック

## 修正対象ファイル
- `100_config/101_sys_config.js` (変更)
- `500_import/502_bank_importer.js` (変更)
- `500_import/501_cc_importer.js` (変更)

## 実装内容

### Step 1: DDLスキーマ変更
`100_config/101_sys_config.js` を修正:
- `WRK_BANK` のヘッダー: 末尾に `取込ハッシュ` を追加。
  - 変更前: `["有効フラグ","決済ID(STL)","消込対象請求ID(INV)","決済日_計画","立替日","決済日_実績","決済ステータス","入出金区分","決済口座","取引先名","税込金額_決済","差額(手数料等)","差額処理科目","組織名","摘要","消込手段","自動仕訳JNL_ID"]`
  - 変更後: `["有効フラグ","決済ID(STL)","消込対象請求ID(INV)","決済日_計画","立替日","決済日_実績","決済ステータス","入出金区分","決済口座","取引先名","税込金額_決済","差額(手数料等)","差額処理科目","組織名","摘要","消込手段","自動仕訳JNL_ID","取込ハッシュ"]`
- `WRK_CARD` のヘッダー: `確認FLG` の直前に `取込ハッシュ` を追加。
  - 変更前: `["決済日_実績","ご利用者","カテゴリ","発生日(P/L計上日)","ご利用先など","税込金額_決済","決済区分","今回回数","訂正サイン","税抜金額_決済","国内/海外","摘要","備考","確認FLG","処理結果","マッチ決済ID(STL)","STL決済日_計画","STL税込金額_決済","STL取引先名","STL摘要"]`
  - 変更後: `["決済日_実績","ご利用者","カテゴリ","発生日(P/L計上日)","ご利用先など","税込金額_決済","決済区分","今回回数","訂正サイン","税抜金額_決済","国内/海外","摘要","備考","取込ハッシュ","確認FLG","処理結果","マッチ決済ID(STL)","STL決済日_計画","STL税込金額_決済","STL取引先名","STL摘要"]`
- `autoCols` の修正: `WRK_BANK` に `18` を追加。
- `setVali` の修正: `WRK_BANK` の列番号変更はなし(末尾追加のため)。

### Step 2: 銀行CSVの重複チェック実装
`500_import/502_bank_importer.js` を修正:
- `importBankStatement` 内で、`33_wrk_bank` のデータを読み込み、有効フラグがTRUEの行の `取込ハッシュ` の出現回数をカウントする `bankHashMap` を作成(空欄は無視)。
- `36_wrk_bank_import` のループ内で、`importHashMap` を用いて現在のハッシュ出現回数をカウント。
- `importHashMap[hash] <= (bankHashMap[hash] || 0)` の場合、`処理結果` に `重複(取込済)`、`確認FLG` に `true` をセットし、マッチング処理(`extractBankCandidateStls_` 等の呼び出しや `isMemoFuzzyMatch_`)をスキップする。
- `applyBankSettlement` 内で、`33_wrk_bank` を更新する際、`36_wrk_bank_import` の `取込ハッシュ` を `33_wrk_bank` の `取込ハッシュ` 列に書き込む。

### Step 3: クレカCSVの重複チェック実装
`500_import/501_cc_importer.js` を修正:
- ファイル末尾に `computeCcHash_(payDate, merchant, amount)` を追加(`yyyyMMdd|merchant|amount` の形式)。
- `importCcStatement` 内で、Step 2 と同様に `bankHashMap` を作成。
- `34_wrk_card` のループ内でハッシュを計算し、`取込ハッシュ` 列に出力。
- `importHashMap` を用いて重複判定を行い、重複の場合は `処理結果` に `重複(取込済)`、`確認FLG` に `true` をセットしてスキップ。
- `applyCcSettlement` 内で、`33_wrk_bank` を更新する際、`34_wrk_card` の `取込ハッシュ` を `33_wrk_bank` の `取込ハッシュ` 列に書き込む。

## 制約
- 重複判定は必ず「出現回数(カウント)」ベースで行うこと。単純な `Set` による存在チェックは不可(同日同額同摘要の複数明細が処理できなくなるため)。

## エッジケース
- データなし: `33_wrk_bank` の `取込ハッシュ` が空欄の過去データは、`bankHashMap` に含めない(無視する)。

## 実データ検証
- `101_sys_config.js` の `WRK_CARD` のヘッダー追加により、既存の `確認FLG` 以降の列インデックスが1つずれるため、`501_cc_importer.js` 内の列インデックス参照(`findCardCol_` 等)が正しく追従するか確認。

## 動作確認
1. `npm run push:dev` を実行。
2. GASエディタで `setupAllSchemas` を実行し、`33_wrk_bank` と `34_wrk_card` に `取込ハッシュ` 列が追加されることを確認。
3. `36_wrk_bank_import` にテストデータを入力し、「🏦 銀行CSV 取込・マッチング」を実行。
4. マッチした明細を「🏦 銀行CSV 消込実行」で `33_wrk_bank` に反映(`取込ハッシュ` が書き込まれることを確認)。
5. 再度「🏦 銀行CSV 取込・マッチング」を実行し、先ほど消込した明細が `重複(取込済)` と判定されることを確認。

### 拡張思考の使用状況
| フェーズ | 拡張思考 | 備考 |
|---------|:--------:|------|
| Step 2-3 | あり | 同日同額同摘要の複数明細を正しく処理するための、出現回数ベースの重複判定ロジックの構築 |

推奨実行モデル

工程推奨モデル理由
仕様書作成(本ドキュメント)Claude Opus 4.6複数ファイルにまたがるデータフローと、出現回数ベースの高度な冪等性ロジックの設計が必要なため
実装Claude Sonnet 4.6DDL変更と、既存のインポート処理への重複判定ロジックの組み込みが必要

変更履歴

日付変更内容
2026-04-16初版作成
2026-04-20実装完了 (PR #221)。WRK_BANK / WRK_CARD に「取込ハッシュ」列追加。出現回数カウントベースで同日同額同摘要の複数明細に対応(単純ハッシュでは衝突する正当なケースを救う設計)。銀行: 金額完全一致 + 日付±3日 でマッチ、クレカ: computeCcHash_(yyyyMMdd|merchant|amount) でハッシュ化。UX 改善として集計ダイアログに重複検知件数を表示。drive-by fix: CC UNMATCHED 時の 確認FLG=FALSE セット漏れを同時修正。後続: MAS-171 クレカ N:1 消込合算マッチ / MAS-172 CC MATCHED 自動承認化検討 を新規起票