パイプライン計画データ読込 — dmIngestPipelinePlanData
1. 基本情報
焦点質問: パイプラインの確度別売上見込みをどう計画に反映するか?
| 項目 | 内容 |
|---|---|
| 関数名 | dmIngestPipelinePlanData_ |
| ファイル | 601_datamart_ingest.js |
| 主要関数 | dmIngestPipelinePlanData_ |
| 役割 | 21_bud_pipeline から確度加重した仮想INVイベントを生成し、計画用配列に合流 |
| 呼び出し元 | 602_datamart_main.js の計画パイプライン(dmIngestPlanData_ の後) |
設計方針
インメモリアプローチ(仮想INVの動的生成)を採用。
- 32_wrk_invoice(物理INV台帳)には不確実なヨミのデータを書き込まない
- Datamart構築時に 21_bud_pipeline を読み込み、確度加重した「仮想INVイベント」をメモリ上で生成
- 計画用配列(
planCtx.finalUnionData)に concat して、既存のdmProcessAllEvents_で処理 - 確度の変更は次回マート更新時に即座に反映される
2. インターフェース定義
| 関数 | 引数 | 戻り値 | トリガー |
|---|---|---|---|
dmIngestPipelinePlanData_ | ctx (データマートコンテキスト), sheetPipe (21_bud_pipelineシート) | Array<仮想INVイベント> | 602_datamart_main.js の計画パイプラインから呼び出し |
3. データスキーマ
入力スキーマ (21_bud_pipeline)
| # | 列名 | 型 | 入力/自動 | 説明 |
|---|---|---|---|---|
| 1 | 有効フラグ | BOOLEAN | 入力 | FALSE→処理スキップ |
| 2 | 管理ID | STRING | 自動 | パイプライン行の一意識別子 |
| 3 | PJ・案件名 | STRING | 入力 | 案件名称 |
| 4 | 契約形態 | STRING | 入力 | 「継続」「スポット」等。継続月数のデフォルト判定に使用 |
| 5 | 売上科目 | STRING | 入力 | 空の場合「売上高」をデフォルト適用 |
| 6 | 確度(ヨミ) | STRING | 入力 | Sヨミ/Aヨミ/Bヨミ/Cヨミ/失注/数値% |
| 7 | 計上開始年月 | STRING | 入力 | 空→スキップ |
| 8 | スポット売上・初期費用 | NUMBER | 入力 | 税抜金額 |
| 9 | 継続月額(MRR) | NUMBER | 入力 | 税抜金額 |
| 10 | 継続月数 | NUMBER | 入力 | 空の場合、契約形態から判定 |
| 11 | 入金ラグ(月) | NUMBER | 入力 | 空の場合1ヶ月 |
出力スキーマ (仮想INVイベント)
Array<{
pYm: string, // 発生月(売上計上月)
sYm: string, // 決済月(入金月 = pYm + 入金ラグ)
acc: string, // 売上科目
amt: number, // 確度加重 × 税込金額(Math.round済み)
booked: false, // 計画扱い(期ずれ解消も生成)
isBsForce: null, // P/L扱い(売上)
noCash: false // CF対象
}>
4. 処理ロジック
4.1 確度変換 (STEP 1)
確度文字列 → 加重係数:
"Sヨミ" or 100% → SKIP(受注確定 = 既にINV台帳にある前提)
"Aヨミ" or 80% → 0.8
"Bヨミ" or 50% → 0.5
"Cヨミ" or 30% → 0.3 ※ 20%→30%に変更(402_project_profitability.js と統一)
"失注" or 0% → 0(SKIP)
数値N% → N/100
空 → 1.0(デフォルト)
Sヨミの二重計上防止: Sヨミ(受注確定)の案件はRPA起票で32タブにINV化される前提。
計画Datamartでも dmIngestPlanData_ が32タブの全INVを読むため、Sヨミを仮想INVに含めると二重計上になる。
4.2 パイプライン処理マトリクス (STEP 2-4)
| 項番 | 処理フェーズ | 入力(論理名) | 入力(物理名: タブ.列) | 処理詳細 / 変換ロジック | 出力(論理名) | 出力(物理名: タブ.列) | 例外処理 |
|---|---|---|---|---|---|---|---|
| PP2.1 | スキップ判定 | 有効フラグ, 確度, 計上開始年月 | 21_bud_pipeline.A,F,G列 | FALSE→SKIP。Sヨミ/100%→SKIP(二重計上防止)。失注/0%→SKIP。計上開始年月空→SKIP | — | — | ※1 |
| PP2.2 | 変数算出 | 確度, 売上科目, 入金ラグ | 21_bud_pipeline.F,E,N列 | prob = 確度変換()、acc = 売上科目 || "売上高"、lag = 入金ラグ || 1、taxRate = 0.10 | 各変数 | 変数 | — |
| PP3.1 | スポット売上: 条件 | スポット売上 | 21_bud_pipeline.H列 | > 0 → 仮想イベント生成 | — | — | — |
| PP3.2 | スポット売上: イベント生成 | spot, prob, taxRate | 変数 | weightedAmt = ROUND(spot × prob × (1+taxRate))。pYm=計上開始年月, sYm=pYm+lag | 仮想イベント | 変数: planData[] | — |
| PP4.1 | MRR: 条件 | 継続月額(MRR), 継続月数 | 21_bud_pipeline.I,J列 | MRR > 0 → 月ループ。dur = 継続月数 || (継続系→120, 他→1) | — | — | — |
| PP4.2 | MRR: 月ループ | curYm | 変数 | curYm = addMonths(startYm, m)。curYm > targetMonths[11] → BREAK。weightedMrr = ROUND(MRR × prob × (1+taxRate)) | 仮想イベント | 変数: planData[] | — |
4.3 合流 (STEP 5)
return pipelineEvents[]
→ 呼び出し元で planData = planData.concat(pipelineEvents)
→ planCtx.finalUnionData = planData
→ dmProcessAllEvents_(planCtx) で処理
4.4 呼び出し箇所の変更(602_datamart_main.js)
var planData = dmIngestPlanData_(ctx, sheetInv);
// 計上パイプラインのPHASE 2(STL消込)データも計画に含める
for (var pi = 0; pi < ctx.finalUnionData.length; pi++) {
var row = ctx.finalUnionData[pi];
if (row.fromSTL) planData.push(row);
}
+ // パイプライン(確度加重)を計画に合流
+ var sheetPipe = ss.getSheetByName('21_bud_pipeline');
+ if (sheetPipe) {
+ var pipeEvents = dmIngestPipelinePlanData_(ctx, sheetPipe);
+ planData = planData.concat(pipeEvents);
+ }
planCtx.finalUnionData = planData;
dmProcessAllEvents_(planCtx);
4.5 processEvent での自動処理
仮想INVイベントは booked: false で acc: "売上高" 等の売上科目を持つ。
processEvent は以下を自動処理する:
| pYm vs sYm | B/S形状 | 処理 |
|---|---|---|
| pYm = sYm | なし | P/Lに売上計上のみ |
| pYm < sYm(入金ラグあり) | 売上債権・未収入金 | pYm: +売上債権、sYm: -売上債権(回収) |
CF: booked: false のため計画CFに反映。sYm月に入金として計上。
5. 財務ロジック (FRD)
※ 本セクションは経理担当・CFOが検証可能な表現で記述。技術用語は使用しない。 → 技術詳細: SS4 処理ロジック 参照
5.1 確度加重
パイプライン上の未受注案件は、受注確度(ヨミ)に応じた加重係数を乗じて計画売上に反映する。受注確定(Sヨミ)の案件は既に請求台帳に登録されるため、二重計上を防止するために計画展開の対象外とする。
5.2 入金ラグと期ずれ
売上の計上月と入金月にずれがある場合(入金ラグ)、売上計上月に売上債権(未収入金)が発生し、入金月にその債権が回収される。これにより計画B/Sに売上債権が反映され、計画CFでは入金月に現金入金として計上される。
5.3 消費税の補正
パイプラインの金額は税抜で入力する。計画への反映時には税込金額(税抜 x 確度 x (1 + 消費税率))に変換する。
5.4 業務ルール・注意点
- Sヨミの二重計上防止 -- Sヨミ=受注確定はRPA起票から請求台帳にINV化される。仮想INVに含めると二重になる
- 消費税の補正 -- パイプラインの金額は税抜。仮想INVでは
金額 = 端数処理(税抜 x 確度 x (1 + 税率))で税込に変換 - 継続月数のデフォルト -- 契約形態に「継続」を含む場合は入力値、「スポット」の場合は1、未指定は120(10年上限)
- 対象期外のスキップ -- 対象期最終月を超える月は生成しない
- パイプラインは計画シートのみに反映 -- 計上シート(61/62/71/81/83)には一切影響しない
- 着手金+残金パターン -- 確度や入金時期が異なる場合は21タブで2行に分けて登録する運用ルール
- 確度変換は402_project_profitability.jsと統一 -- 同じ変換ロジックを使用。Cヨミ=30%
6. 冪等性・整合性保証
| 保証項目 | メカニズム | 検証方法 |
|---|---|---|
| 仮想INV非永続化 | 32_wrk_invoice(物理INV台帳)には書き込まない。毎回インメモリで再生成 | マート更新後に32タブの行数が変わらないことを確認 |
| 確度変更の即時反映 | 次回マート更新時に21タブの最新値で仮想INVを再生成 | 確度変更後にマート更新→計画P/Lの金額が変わることを確認 |
| Sヨミ二重計上防止 | Sヨミ/100%の行はSKIP。受注確定案件はRPA起票→32タブINVで処理 | Sヨミ案件を21タブに登録してもイベント生成数が0であることを確認 |
| 対象期外の排除 | targetMonths[11](対象期最終月)を超える月のイベントは生成しない | 対象期外の計上開始月でイベントが0件であることを確認 |
7. テスト仕様
7.1 単体テスト観点
| # | テストケース | 入力 | 期待結果 |
|---|---|---|---|
| T1 | スポット・Aヨミ | スポット100万, MRR=0, 確度=A(80%), 税率10% | amt = round(1,000,000 x 0.8 x 1.1) = 880,000 |
| T2 | 継続MRR・Bヨミ | MRR=50万, 継続12ヶ月, 確度=B(50%), 税率10% | 12件 x round(500,000 x 0.5 x 1.1) = 12 x 275,000 |
| T3 | Sヨミ(除外) | 確度=Sヨミ | 仮想イベント生成されない |
| T4 | 失注(除外) | 確度=失注 | 仮想イベント生成されない |
| T5 | 入金ラグ | ラグ=2, 計上開始=2026-04 | pYm=2026-04, sYm=2026-06 → 売上債権が2ヶ月発生 |
| T6 | スポット+MRR | スポット50万, MRR=10万, 継続6ヶ月, 確度=A | スポット1件(440,000) + MRR 6件(各88,000) = 7件 |
| T7 | 対象期外スキップ | 計上開始=2025-04, 継続120ヶ月 | targetMonths[11]以降は生成しない |
| T8 | 有効フラグOFF | 有効フラグ=FALSE | 生成されない |
| T9 | 数値確度 | 確度="60%" | prob=0.6 |
| T10 | 二重計上防止 | Sヨミ案件が32タブにINVあり | 仮想INV=0件、32タブINVのみ計画に反映 |
7.2 テストデータ・期待結果
テストデータ(21タブ 3行)
| # | PJ・案件名 | 契約形態 | 売上科目 | 確度 | 計上開始 | スポット | MRR | 継続月数 | 入金ラグ |
|---|---|---|---|---|---|---|---|---|---|
| 1 | Webサイト構築A社 | スポット(狩猟) | 売上高 | Aヨミ(80%) | 2026-06 | 1,000,000 | 0 | 1 | 2 |
| 2 | 保守契約B社 | 継続(農耕) | 売上高 | Bヨミ(50%) | 2026-04 | 0 | 100,000 | 12 | 1 |
| 3 | 受注確定C社 | スポット(狩猟) | 売上高 | Sヨミ(受注確定) | 2026-05 | 500,000 | 0 | 1 | 1 |
期待結果(対象期: 2025-04〜2026-03 の場合)
行1 (A社 スポット): 計上開始=2026-06 → 対象期外 → 0件 行2 (B社 継続MRR): 計上開始=2026-04 → 対象期外(2026-03まで)→ 0件 行3 (C社 Sヨミ): Sヨミ → SKIP(二重計上防止)
期待結果(対象期: 2026-04〜2027-03 の場合)
行1 (A社 スポット Aヨミ):
prob = 0.8, taxRate = 0.10
amt = round(1,000,000 × 0.8 × 1.1) = 880,000
pYm = "2026-06", sYm = "2026-08" (ラグ2)
→ 仮想イベント 1件
行2 (B社 継続MRR Bヨミ):
prob = 0.5, taxRate = 0.10
weightedMrr = round(100,000 × 0.5 × 1.1) = 55,000
計上開始=2026-04, 継続12ヶ月 → 2026-04〜2027-03
→ 仮想イベント 12件(各55,000), sYm = pYm + 1ヶ月
行3 (C社 Sヨミ): SKIP
計画P/Lへの反映(売上高):
| 月 | A社スポット | B社MRR | 合計 |
|---|---|---|---|
| 2026-04 | 0 | +55,000 | 55,000 |
| 2026-05 | 0 | +55,000 | 55,000 |
| 2026-06 | +880,000 | +55,000 | 935,000 |
| 2026-07〜2027-03 | 0 | +55,000/月 | 55,000/月 |
| 通期 | 880,000 | 660,000 | 1,540,000 |
計画B/Sへの反映(売上債権・未収入金):
| 月 | A社(ラグ2) | B社(ラグ1) |
|---|---|---|
| 2026-06 | +880,000 | +55,000 → -55,000(前月分回収) |
| 2026-07 | 0 | +55,000 → -55,000 |
| 2026-08 | -880,000(回収) | +55,000 → -55,000 |
付録
付録A: 関連仕様書
| 仕様書 | 関連内容 |
|---|---|
| パイプライン取込 (spec_pipeline_ingest) | 21タブの未受注案件を確度加重でインメモリ展開 |
| データ取込 (spec_datamart_ingest) | PHASE 1/2のINV・STL取込処理 |
| P/L (spec_pl) | 仮想INVイベントのP/L計上 |
| B/S (spec_bs) | 入金ラグによる売上債権の発生・回収 |
| 法人税 (spec_corporate_tax) | 累進ブラケット対応 |