1. 基本情報
焦点質問: 32/33タブのデータをどうマートに取り込むか?
| 項目 | 内容 |
|---|
| ファイル | 601_datamart_ingest.js |
| 主要関数 | dmIngestData_ / dmIngestPlanData_ / dmIngestPipelinePlanData_ / dmSyncInvClassification_ |
| 役割 | 32_wrk_invoice + 33_wrk_bank + 科目マスタを読み込み、統合データ(ctx)を生成 |
| 呼び出し元 | buildBudgetTrendDataMart()(602_datamart_main.js)ステップ1 |
42_trn_journal は監査証跡。集計ソースとしては使用しない。
41_trn_budget は除外。32_wrk_invoice の承認済INVが計画を兼ねる。
アーキテクチャ図(Mermaid)
flowchart TB
subgraph 入力
MST[11_mst_account
科目マスタ]
INV[32_wrk_invoice
承認済INV]
BANK[33_wrk_bank
消込済STL]
end
subgraph dmIngestData_
S1[STEP 1: 科目マスタ読込
→ acctMap]
S2[STEP 2: PHASE 1
P/L計上 + 資産計上B/S]
S3[STEP 3: PHASE 2
期ずれ解消 + B/S消込
+ 仕訳振替INV認識]
S4[STEP 4: 境界月算出]
end
subgraph 出力
CTX[ctx
finalUnionData
acctMap
boundaryMonthStr]
end
MST --> S1
INV --> S2
S1 --> S2
BANK --> S3
INV -.->|INV参照| S3
S2 --> S4
S3 --> S4
S4 --> CTX
2. インターフェース定義
| 関数 | 引数 | 戻り値 | 呼び出し元 |
|---|
dmIngestData_ | ctx, sheetInv (32タブ), sheetBank (33タブ), sheetAcct (11タブ) | void(ctx に直接書き出し) | buildBudgetTrendDataMart() ステップ1 |
dmIngestPlanData_ | ctx (acctMap必須), sheetInv (32タブ) | planUnionData[] | buildBudgetTrendDataMart() 計画ステップ |
dmIngestPipelinePlanData_ | ctx (targetMonths, TAX_RATE必須), sheetPipe (21タブ) | { planData[], viewData[] } | buildBudgetTrendDataMart() パイプライン計画ステップ |
dmSyncInvClassification_ | acctMap, sheetInv (32タブ) | void(シート直接更新) | buildBudgetTrendDataMart() ステップ1b |
3. データスキーマ
3.1 入力: 科目マスタ(11_mst_account)
| # | 列名 | 型 | 用途 |
|---|
| A | 有効フラグ | BOOLEAN | FALSE → スキップ |
| C | 諸表区分 | STRING | P/L or B/S 判定 |
| D | 大分類 | STRING | 資産/負債/資本/収益/費用 |
| E | 表示区分 | STRING | 財務諸表のセクション振り分け |
| J | 科目名 | STRING | acctMap のキー |
3.2 入力: 32_wrk_invoice(PHASE 1 + PHASE 2参照)
| # | 列名 | 型 | 用途 |
|---|
| A | 有効フラグ | BOOLEAN | FALSE → スキップ |
| — | 請求ID(INV) | STRING | invIdxMap のキー(PHASE 2でSTLから逆引き) |
| — | 親発注ID(ORD) | STRING | invOrdMap のキー(仕訳振替INV検索用) |
| — | 発生日(P/L計上日) | DATE | pYm 算出。maxInvYm 更新 |
| — | 決済日_計画 | DATE | sYm 算出。期ずれ判定 |
| — | 請求ステータス | STRING | 承認済/部分決済/決済完了 のみ対象 |
| — | 収支区分 | STRING | 収入/支出。期ずれ解消時のB/S科目判定 |
| — | 科目名 | STRING | acctMap 参照。P/L vs B/S 判定 |
| — | 税込金額_計画 | NUMBER | 計上額 |
| — | 決済手段 | STRING | 仕訳振替/資産計上 の特殊判定 |
3.3 入力: 33_wrk_bank(PHASE 2)
| # | 列名 | 型 | 用途 |
|---|
| A | 有効フラグ | BOOLEAN | FALSE → スキップ |
| — | 消込対象請求ID(INV) | STRING | 対象INV行の逆引き |
| — | 決済日_計画 | DATE | 仕訳振替INV検索の月マッチ |
| — | 決済日_実績 | DATE | sYm 算出。maxInvYm 更新 |
| — | 決済ステータス | STRING | 消込済 のみ対象 |
| — | 税込金額_決済 | NUMBER | STL決済金額(部分決済対応) |
| — | 差額(手数料等) | NUMBER | 手数料等の差額 |
| — | 差額処理科目 | STRING | 差額の計上先科目(空の場合「支払手数料」) |
| — | 自動仕訳JNL_ID | STRING | 空 → スキップ(Action B 未処理) |
3.4 出力: ctx 構造体
| キー | 型 | 内容 |
|---|
acctMap | { [科目名]: { stmt, cat, disp } } | 科目→諸表区分のマッピング |
finalUnionData | Array<UnionEvent> | PHASE 1 + PHASE 2 の統合データ |
boundaryMonthStr | "YYYY-MM" | 実績の最終発生月+1(当月キャップ) |
hasJourData | boolean | 実績データが1件以上あるか |
maxJourYm | "YYYY-MM" | 実績の最終発生月 |
journalSettleMap | {} | 空オブジェクト(互換用) |
3.5 UnionEvent レコード構造
| フィールド | 型 | 説明 |
|---|
pYm | "YYYY-MM" | P/L計上月(発生日ベース) |
sYm | "YYYY-MM" | 決済予定月(決済日_計画ベース) |
acc | string | 科目名 |
amt | number | 金額(税込) |
booked | boolean | true=実績、false=計画 |
isBsForce | boolean | null | true=B/S強制計上 |
fromSTL | boolean | undefined | PHASE 2 で追加されたイベント |
4. 処理ロジックマトリクス
4.1 STEP 1: 科目マスタ読込
| 項番 | 処理フェーズ | 入力(論理名) | 入力(物理名: タブ.列) | 処理詳細 / 変換ロジック | 出力(論理名) | 例外処理 |
|---|
| D1.1 | 科目マスタ読込 | 有効フラグ, 諸表区分, 大分類, 表示区分, 科目名 | 11_mst_account.A,C,D,E,J列 | acctMap[科目名] = { stmt, cat, disp } | acctMap | 有効フラグFALSE→SKIP |
4.2 STEP 2: PHASE 1 — 32_wrk_invoice(承認済INV)
| 項番 | 処理フェーズ | 入力(論理名) | 入力(物理名) | 処理詳細 / 変換ロジック | 出力(論理名) | 例外処理 |
|---|
| D2.1 | スキップ判定 | 有効フラグ, 請求ステータス, 決済手段 | 32.A, I, W列 | FALSE→SKIP。ステータス∉[承認済, 部分決済, 決済完了]→SKIP。仕訳振替→SKIP | — | — |
| D2.2 | 年月算出 | 発生日, 決済日_計画 | 32.G, H列 | pYm = parseDateToYm(発生日), sYm = parseDateToYm(決済日_計画) || pYm | pYm, sYm | pYm=null→SKIP |
| D2.3 | maxInvYm更新 | pYm | 変数 | pYm > maxInvYm なら更新 | maxInvYm | — |
| D2.4 | INV IDマップ構築 | 請求ID, 親発注ID | 32.INV_ID, ORD_ID列 | invIdxMap[invId] = i, invOrdMap[ordId].push(i) | invIdxMap, invOrdMap | — |
| D2.5 | B/S科目除外 | 科目名, 決済手段 | 32.P, W列 | acctMap[科目名].stmt === "B/S" かつ 決済手段≠資産計上 → SKIP | — | 資産計上は即時B/S計上 |
| D2.6 | unionData追加 | 税込金額_計画 | 32.U列 | unionData[] に { pYm, sYm, acc, amt, booked:true } を追加。B/S科目の場合 isBsForce:true | unionData | 科目マスタ未登録→マップなしで続行 |
4.3 STEP 3: PHASE 2 — 33_wrk_bank(消込済STL)
| 項番 | 処理フェーズ | 入力(論理名) | 入力(物理名) | 処理詳細 / 変換ロジック | 出力(論理名) | 例外処理 |
|---|
| D3.1 | スキップ判定 | 有効フラグ, 決済ステータス, JNL_ID | 33.A, G, Q列 | FALSE→SKIP。≠消込済→SKIP。JNL_ID空→SKIP(Action B未処理) | — | — |
| D3.2 | STL基本情報取得 | 決済日_実績, 消込対象INV_ID | 33.決済日_実績, INV_ID列 | sYm = parseDateToYm(決済日_実績)。INV逆引き: invIdxMap[targetInvId] | sYm, targetInvRow | 決済日null / INV不明→SKIP |
| D3.3a | 資産計上INVの消込 | 対象INVの科目, 決済手段 | 32.P, W列 | B/S科目 かつ 資産計上 → STL決済金額分をマイナスでB/S計上(未払金解消) | unionData | — |
| D3.3b | B/S科目INVの消込 | 対象INVの科目, 決済手段 | 32.P, W列 | B/S科目 かつ 仕訳振替以外 → STL決済金額 × INV符号方向でB/S計上(部分決済対応) | unionData | — |
| D3.3c | P/L科目INVの期ずれ解消 | 対象INVの科目, 収支区分, 発生日, 決済日_計画 | 32.P, J, G, H列 | P/L科目 かつ pYm≠sYm(期ずれあり)の場合のみ: 収入→売掛金 -= INV総額、支出→未払金/未払費用 -= INV総額 | unionData | 期ずれなし(pYm=sYm)→何もしない(二重減算防止) |
| D3.4 | 差額(手数料等) | 差額, 差額処理科目 | 33.差額, 差額処理科目列 | 差額≠0 → 差額処理科目(空なら支払手数料)で計上 | unionData | — |
| D3.5 | 仕訳振替INV認識 | 同ORD+同決済日_計画月の仕訳振替INV | 32全体 | 親ORD経由で同月の仕訳振替INVを検索。P/L科目→P/L計上、B/S科目→B/S直接計上。重複防止(recognizedJeSet) | unionData | 同一INV行は1回のみ |
4.4 STEP 4: 境界月
| 項番 | 処理フェーズ | 入力(論理名) | 処理詳細 / 変換ロジック | 出力(論理名) | 例外処理 |
|---|
| D4.1 | 境界月計算 | maxInvYm | boundaryMonthStr = maxInvYm + 1ヶ月。当月超過→当月にキャップ | boundaryMonthStr | データなし→当月 |
5. 財務ロジック (FRD)
※ 本セクションは経理担当・CFOが検証可能な表現で記述。技術用語は使用しない。
→ 技術詳細: §4 処理ロジック 参照
5.1 計上タイミングの振分ルール
| 区分 | 計上タイミング | 根拠 |
|---|
| P/L科目(費用・収益) | 請求書の発生日(発生主義) | 発生日を基準に損益を認識する |
| B/S科目(資産計上以外) | 決済(消込)時点まで計上しない | 決済確定までは残高を動かさない |
| B/S科目(資産計上) | 請求書の承認時点で即時計上 | 設備投資の初回仕訳(取得原価の認識) |
| 仕訳振替 | 決済(消込)時点で認識 | 実際の振替が完了するまで計上しない |
5.2 期ずれ自動生成ルール
発生日の月と決済予定日の月が異なる場合(期ずれ)、以下のB/S科目が自動計上される。
| 取引種別 | 期ずれ時に自動計上されるB/S科目 | 解消タイミング |
|---|
| 支出(費用) | 未払金 or 未払費用 | 銀行消込(Action B)完了時 |
| 収入(売上) | 売掛金 | 銀行消込(Action B)完了時 |
未払金 vs 未払費用の判定基準: 給料・給与・役員報酬・賞与・法定福利・福利厚生・雑給・支払利息・地代家賃・賃借料・支払保険料に該当する科目は「未払費用」、それ以外は「未払金」。
→ 技術詳細: dmIsAccruedExpense_() (602_datamart_main.js)
5.2.1 計画 B/S (PHASE 1) における期ずれ計算 (PR #460・案 A 改 2 で確定)
経緯: 当初実装は 決済日_計画 のみを使う「計画 = 全 INV 即決済前提」だったが、73_bs_plan の現預金が実績 71_bs と乖離 (約 -605K)。未払系負債が計画 B/S に積み上がらず構造的バグ発覚 (詳細: failure_patterns.md #34 + BUG_tracking.md MAS-300)。
dmIngestPlanData_ の期ずれ解消月 sStr 決定ロジック (PR #460 commit 1f04ef5):
| 条件 | sStr (期ずれ解消月) | 意図 |
|---|
決済日_実績 記入済 | settleActStr (実績 PHASE 2 と同月) | 実績 PHASE 2 と整合させる (二重計上防止 + 一貫性) |
決済日_実績 空 + 決済日_計画 ≤ 当月 | '9999-12' (未消込のまま残す) | 未消込 INV を cash plug として B/S に滞留させる (実績の未払金/未収金と同等) |
| それ以外 | 決済日_計画 をそのまま | 通常の計画通り決済予定月で解消 |
設計原則: 計画 B/S 生成時は実績側の決済日 (決済日_実績) を SSoT として優先。実績 PHASE 2 と PHASE 1 (計画) で同じ期ずれ解消月を使うことで実績→計画の連続性を保証。残乖離 ±30K は地代家賃前払 INV の表示差 (cash plug 効果は同値で許容)。
5.3 STL消込時の認識
銀行入出金で消込が完了(消込済 かつ 自動仕訳あり)した際に以下を認識する。
| INV種別 | 消込時の処理 | 金額ベース |
|---|
| P/L科目(期ずれあり) | 未払金/未払費用/売掛金を請求総額で解消 | INV請求総額 |
| P/L科目(期ずれなし) | 追加処理なし | — |
| B/S科目(資産計上) | 既計上分に対してSTL決済額をマイナス計上(未払金解消) | STL決済金額 |
| B/S科目(通常) | STL決済金額でB/S直接計上。符号はINV請求総額の正負を引き継ぐ | STL決済金額 |
| 仕訳振替INV | 同一発注・同月の仕訳振替INVを認識してP/L or B/S計上 | INV税込金額_計画 |
5.4 差額(手数料等)の処理
STLの差額がゼロでない場合、差額処理科目(未指定時は「支払手数料」)で発生月に計上する。
5.5 計画取込(dmIngestPlanData_)の方針
| 項目 | 実績取込との違い |
|---|
| 対象ステータス | ステータス不問(未処理含む全INV) |
| P/L費用 | 発生日ベース(期ずれなし) |
| P/L収入(売上) | 決済日_計画ベース(売掛金を表示) |
| B/S直接計上 | 決済日_計画ベース |
| 仕訳振替 | スキップ(実績PHASE 1と同じ) |
| 資産計上の未収入金 | スキップ(一時科目のため計画では不要) |
| B/S+仕訳振替ペア | 同ORDに同科目の仕訳振替INVがある場合は除外(片方だけだと不整合) |
booked | false(計画扱い) |
6. 冪等性・整合性保証
| 保証項目 | メカニズム | 検証方法 |
|---|
| 仕訳振替INV重複認識防止 | recognizedJeSet[rowIdx + '|' + sYm] で同一INV行×同一決済月を1回のみ認識 | 同一STLで2回実行しても結果が同一 |
| PHASE 1/2の分離 | PHASE 1ではP/L計上のみ(B/S・仕訳振替除外)、PHASE 2でB/S解消・仕訳振替認識 | 二重計上なし |
| P/L期ずれ解消の条件 | pYm ≠ sYm の場合のみ解消レコード生成 | 期ずれなしINVの二重減算を防止 |
| B/S部分決済対応 | STL決済金額ベースで計上(INV請求総額ではなく) | 複数STLで分割決済しても合計が一致 |
| INVマップ構築 | PHASE 1で invIdxMap / invOrdMap を構築し、PHASE 2で参照 | 存在しないINV IDはスキップ |
| 境界月キャップ | boundaryMonthStr > 当月 の場合は当月にキャップ | 未来月が実績扱いにならない |
| 分類同期 | dmSyncInvClassification_ で32タブの諸表区分・大分類・税込金額_決済を科目マスタから一括同期 | マスタ変更が即座に反映 |
7. テスト仕様
| テストID | テスト名 | 前提条件 | 期待結果 |
|---|
| DI-01 | P/L科目INVの取込 | 承認済のP/L科目INV(期ずれなし) | unionDataに booked:true で追加。pYm=sYm |
| DI-02 | P/L科目INVの期ずれ | 発生日と決済日_計画が異なる月のINV | unionDataに追加。sYmが決済日_計画月 |
| DI-03 | B/S科目INVの除外 | B/S科目のINV(資産計上以外) | PHASE 1で除外される |
| DI-04 | 資産計上INVの即時計上 | 決済手段=資産計上のB/S科目INV | PHASE 1で isBsForce:true として追加 |
| DI-05 | 仕訳振替INVの除外 | 決済手段=仕訳振替のINV | PHASE 1で除外される |
| DI-06 | STL消込 — P/L期ずれ解消 | 消込済STL(対象INVがP/L科目、期ずれあり) | 未払金/未払費用/売掛金の解消レコード追加 |
| DI-07 | STL消込 — P/L期ずれなし | 消込済STL(対象INVがP/L科目、pYm=sYm) | 追加レコードなし(二重減算防止) |
| DI-08 | STL消込 — B/S直接計上 | 消込済STL(対象INVがB/S科目) | STL決済金額でB/S計上 |
| DI-09 | STL消込 — 資産計上解消 | 消込済STL(対象INVが資産計上) | マイナス金額でB/S計上(未払金解消) |
| DI-10 | 仕訳振替INV認識 | 同ORD+同月の仕訳振替INV | P/L or B/S計上。重複なし |
| DI-11 | 差額(手数料)計上 | STLに差額あり | 差額処理科目(or 支払手数料)で計上 |
| DI-12 | 境界月キャップ | maxInvYm+1 > 当月 | boundaryMonthStr = 当月 |
| DI-13 | Action B未処理STL除外 | JNL_ID空のSTL | PHASE 2で除外される |
| DI-14 | 部分決済ステータス | 請求ステータス=部分決済のINV | PHASE 1で取込対象 |
テスト手順の詳細: docs/test/02_integration_test.md — マート更新テスト (P/L・B/S・CF)
付録
付録A: ヘルパー関数一覧
| 関数 | ファイル | 役割 |
|---|
dmIsAccruedExpense_ | 06_datamart_main.js | 科目名が未払費用対象かを判定(キーワード一覧は本文参照) |
dmSyncInvClassification_ | 06_datamart_ingest.js | 32 タブの区分・大分類を科目マスタから一括同期 |
Utils.parseDateToYm(date) | Utils | 日付を "YYYY-MM" 文字列に変換 |
Utils.parseAmt(value) | Utils | 金額文字列を数値に変換 |
Utils.addMonths(ymStr, n) | Utils | "YYYY-MM" に n ヶ月加算 |
付録B: 業務ルールサマリ
- 仕訳振替INVは PHASE 1 で除外 — 決済まで発生しないため
- B/S科目INVは PHASE 1 で除外 — STL消込まで計上しない(資産計上は例外)
- PHASE 2 の集計条件 — 消込済 かつ 自動仕訳JNL_ID あり(Action B 処理済)
- P/L INV の消込 → 期ずれあり(pYm≠sYm)の場合のみ: 収支区分='収入'は売掛金解消、'支出'は未払金/未払費用解消(INV請求総額ベース)
- B/S INV の消込 → B/S直接計上(預り金等の増減)。符号はINV請求総額の正負方向を引き継ぐ
- 資産計上INVの消込 → PHASE 1で既にB/S計上済み。STL決済金額分をマイナスでB/S計上(未払金解消)
- 仕訳振替INV認識 — 重複防止(recognizedJeSet)で同一INV×同一決済月を1回のみ
- 差額(手数料等) — STL差額≠0 の場合、差額処理科目(未指定時は支払手数料)で計上
付録C: ADR