概要

項目内容
案件IDMAS-162
カテゴリ外部データ取込
PhaseP1.5
優先度★★
所要時間2時間
対象ファイル500_import/502_bank_importer.js
前提案件MAS-145(銀行CSV取込), MAS-154(名寄せ辞書)

目的

まとめ振込(月額給与3ヶ月分、社保2件分等)で1つの銀行明細に複数STLが対応するケースを自動候補提案する。

実装済みの設計判断(2026-04-16 実装時の知見)

マッチング優先順位

Pass条件結果信頼度
1金額完全一致 + 日付±3日 + 入出金区分一致MATCHED最高
2同一取引先の複数STL合算が金額完全一致 (±1 円厳密)SUGGEST_COMBO
2.5同一取引先の複数STL合算が ±max(1,000 円, 銀行金額×1%) で一致 (ソフト合算)SUGGEST_COMBO_SOFT
3金額±10% + 摘要キーワード一致SUGGEST

重要: Pass 2(合算厳密)→ Pass 2.5(合算ソフト)→ Pass 3(単一候補)の順で実行する。理由: 合算は金額完全一致のため信頼度が高い。Pass 3 を先にすると、合算対象のSTLが個別に消費されてしまう。Pass 2.5 は Pass 2 で不成立だった場合のフォールバックで、口座振替割引等の少額差を救済する (PR #465 で追加)。

Pass 2.5 ソフト合算 (PR #465 追加)

契機

社会保険料 (厚年金 + 健保) の口座振替で、銀行引落額 149,950 円 と STL 合計 150,950 円 (74,575 + 76,375) が ちょうど 1,000 円 ずれて合算候補に提案されない事象を観測。口座振替割引と推測。Pass 2 (±1 円厳密) では救済不可だったため、Pass 2.5 として実装。

実装

findComboGroup_(candidates, txAmt, txType, txYm, tolerance) に許容誤差 tolerance (円) を引数化リファクタ。

Passtolerance 引数用途
Pass 21厳密合算(±1 円・端数対応のみ)
Pass 2.5Math.max(1000, txAmt * 0.01)ソフト合算(±1,000 円 or ±1% の大きい方)

UI 表示

項目Pass 2 (厳密)Pass 2.5 (ソフト)
ラベル合算候補合算候補(差額+1,000円) 等で差額明示
背景色緑 #D5E8D4黄色 #FFF2CC (視覚区別)
確認FLGfalse (人間確認必須)false (人間確認必須・必ず差額の妥当性を判断する)

注意事項

  • 必ず Pass 2 の後に実行する: 厳密一致が優先。±1 円で合致するケースを Pass 2.5 が先取りしてはいけない。
  • 差額の妥当性は人間判断: 1,000 円の差は口座振替割引で説明可能だが、5,000 円の差は調査要 (摘要欄不一致・別案件混入の可能性)。
  • Pass 3 (単一候補) との優先順位: Pass 2.5 が候補を出した場合は Pass 3 をスキップ (combo 変数にヒット結果が残るため)。

取引先別グルーピング

全STLの合計ではなく、同一取引先内でグルーピングしてから合計を照合する。

理由: 異なる取引先のSTLが偶然合計一致する誤マッチを防止。

部分集合の探索方式

同一取引先の全件合計 ≠ 銀行金額のケースが頻出する(例: 4ヶ月分のSTLがあるが振込は3ヶ月分)。以下の3方式で順に探索:

  1. 全件合計一致: 同一取引先の全STL合計が銀行金額と一致
  2. 貪欲法: 日付昇順にSTLを1件ずつ加算し、ちょうど一致したら採用
  3. 同一金額N件: 同一金額のSTLが N件あり、N × 単価 = 銀行金額 で件数マッチ

STLロック

合算マッチ成功時に candidates[ci].matched = true でロックする。これがないと次の銀行明細で同じSTLが再利用される。

処理順序のソート

銀行明細を勘定日の昇順で処理する。行の並び順ではなく内部的にソートし、書き込みは元の行番号に行う。

理由: 古い銀行明細が古いSTLに優先マッチし、日付的な整合性を維持。

Date オブジェクトのソート注意

STLの dueDate が Date オブジェクトの場合、String() でタイムゾーン付き文字列になりソート順が壊れる。Utils.parseDateToYm() で YYYY-MM 形式に統一してからソートすること。

エッジケース

条件動作理由
同一取引先の全件合計 ≠ 銀行金額貪欲法 → 同一金額N件で部分集合を探索4ヶ月分のSTLがあるが3ヶ月分の振込
異なる金額のSTLの合算(社保控除74,575 + 法定福利費76,375 = 150,950)貪欲法で日付昇順に加算して一致同一金額N件では検出できない
同じ金額・同じ取引先の明細が2行ある(2月分と3月分の社保)1行目の処理でSTLがロックされ、2行目は残りのSTLからマッチmatched=true ロックで二重消費防止
36タブの行順序が勘定日と異なる内部ソートにより常に古い明細が先に処理される処理順序のソートで整合性確保
社会保険料の口座振替割引 (銀行引落 149,950 円 vs STL 合計 150,950 円・差 1,000 円)Pass 2 (±1 円) では不成立 → Pass 2.5 (±max(1000, txAmt × 1%) = ±1,500 円) で SUGGEST_COMBO_SOFT 候補化・ラベル 合算候補(差額+1,000円)・黄色背景口座振替割引等の少額差を救済 (PR #465)。差額の妥当性は人間が判断 (確認FLG=false)

関連ドキュメント

仕様書関連箇所
MAS-145 銀行CSV取込基盤の2段階マッチング
MAS-154 取引先略称名寄せ連携(銀行摘要名列)
F.4 失敗パターン一覧合算マッチ関連の失敗 #13-#17 / フィルター silent-fail #35 / 単一マッチ前提ロジック未追従 #36
BUG_tracking.mdMAS-301 (Pass 2.5 追加経緯) / MAS-302 (applyBankSettlement silent-fail) / MAS-303 (合算時差額未記録・MAS-338 で対応)
MAS-338 STL 消込時 差額自動処理機能下流の派生案件。Pass 2.5 ソフト合算ヒット時の差額 (±1,000 円等) を 差額(手数料等) 列に按分記録し、自動推定科目 (雑収入 / 支払手数料 等) を提案する仕組み

変更履歴

日付変更内容
2026-05-01Pass 2.5 ソフト合算追記 (PR #465 反映): findComboGroup_ を tolerance 引数化リファクタし、Pass 2 (±1 円厳密) で不成立時に Pass 2.5 (±max(1000, txAmt × 1%)) で再試行する仕組みを追加。社会保険料の口座振替割引 (1,000 円差) のケースを救済。ラベル 合算候補(差額+1,000円) + 黄色背景 #FFF2CC で人間確認を要求 (Pass 2 厳密合算 = 緑 #D5E8D4 と視覚区別)。エッジケース表に契機を追記。MAS-301 (BUG_tracking) として記録。
2026-04-16初版作成(実装完了後に知見を文書化)