1. 基本情報

焦点質問: SaaSサブスクからどのようなINVを自動生成するか?

23_bud_subscription(SaaS契約マスタ)の各行に対し、契約形態(月額/年額)・決済ラグ・支払基準日を考慮して 対象年月までの未起票分を一括で INV 行に展開 する。1契約1ヶ月あたり1行のINVを生成し、HC RPAのような預り金・仕訳振替・益税の派生Rowは不要。

項目内容
関数名generateSaasInvoices(targetOverride, _silent)
ファイル401_bat_rpa.js
入力23_bud_subscription
出力32_wrk_invoice + 31_wrk_order
メニュー「⚙️ 定期RPA起票 > 📦 SaaS(サブスク)」

2. 前提条件・依存関係

項目内容
SSOT32_wrk_invoice(起票先), 31_wrk_order(発注先)
マスタ依存11_mst_account(writeInvRows_ 内で諸表区分・大分類を科目マスタから自動付与)
前提有効フラグ=TRUEの行のみ処理対象
前提利用ステータスに「解約済」を含む行はスキップ
前提開始・契約年月が空の行はスキップ
ヘルパーINV/ORD ヘルパー 9 関数(一覧は 400_rpa_common.js 参照)
後続処理Action ATRN/STL 自動作成 → Action B消込・決済仕訳)

3. 入力スキーマ

23_bud_subscription カラム定義

#カラム名入力/自動説明制約
1A有効フラグcheckbox入力FALSE→SKIP空セルもFALSE扱い
2B管理IDstring自動(RPA)SAS_NNNN(自動発番)空の場合RPAが自動採番
3Cサービス・ツール名string入力表示名・摘要に使用コード上は 資産・契約名 もフォールバック
4D利用者・部門string入力デフォルト「全社共通」
5E費用科目string入力(pulldown)デフォルト「通信費」11_mst_account に登録済の科目名のみ
6F取引先名string入力(pulldown)「選定中」「未定」含む→空にクレンジング
7G契約形態string入力月額 / 年額月額/年額以外は月額扱い
8H開始・契約年月date入力RPA対象期間の開始空→SKIP。コード上は 開始年月 もフォールバック
9I次回更新・終了年月date入力空=無期限(自動更新)コード上は 終了年月 もフォールバック
10J税抜金額_計画number入力月額/年額の単価必須(空→0扱い)
11K消費税額_計画number入力0の場合もあり(対象外)
12L税区分string入力対象外 / 課税 等
13M決済手段string入力(pulldown)クレカ / 口座振込 / 口座振替 等「未定」含む→空にクレンジング
14N決済ラグ(月)number入力0=当月、1=翌月、-1=前月(前払い)全角数字→半角変換
15O支払基準日number入力日(1-31)。0=月末月末日より大きい場合キャップ
16P休日調整string入力前/後/なし
17QCF計上string入力予算/実績INV起票には影響なし(Datamartで判定)
18R自動更新アラートstring入力参考情報
19S利用ステータスstring入力利用中/解約予定/解約済「解約済」含む→SKIP。コード上は ステータス もフォールバック
20T組織名string入力(pulldown)ORD・INV Rowに転記
21U備考string入力自由記述
22V最終起票年月日date入力(手動)「ここまで起票済」を示す。RPAは書き戻さない
23W最終決済予定日date自動(RPA)列が存在しない場合は自動追加

4. 処理ロジック(マトリクス)

共通INVフィールド(buildInvRow_ が自動設定): 有効フラグ=true, 請求ID=INV_YYYYMMDD_NNNN(自動発番), 起票日時=now, 起票者="RPA自動起票", 請求ステータス="未処理", 収支区分="支出", 通貨="JPY", 未決済残高=税込金額_計画

HCとの違い: SaaS INVは1契約1ヶ月あたり1行のみ。預り金・仕訳振替・益税などの派生Rowは不要。

項番処理フェーズ入力(論理名)入力(物理名: タブ.列)処理詳細 / 変換ロジック出力(論理名)出力(物理名: タブ.列)例外処理
S1.1初期化: 対象年月算出最終起票年月日(全有効行)23_bud_subscription.V列全有効行の最終起票年月日の最大値を targetYm とする。targetOverride が指定されていればそちらを優先targetYm変数: targetYm (YYYY-MM)⚠️ 全行が空かつtargetOverride未指定 → 当月(YYYY-MM)をtargetYmとする
S1.2初期化: INV重複チェック用データ読込32_wrk_invoice全データ32_wrk_invoice摘要列ベースで重複判定するため全行を読み込むinvData, invHeaders変数
S1.3初期化: ORD準備31_wrk_order全データ31_wrk_orderbuildOrdMap_() で既存ORDマップを構築ordMap変数⚠️ 31タブが存在しない場合はORD作成をスキップ
S2.1ループ開始23_bud_subscription 全行FOR EACH 行 — 以下を各行に対して実行
S2.2スキップ判定①有効フラグ23_bud_subscription.A列= FALSESKIP⚠️ 空セルもFALSE扱い
S2.3スキップ判定②利用ステータス23_bud_subscription.S列"解約済" を含む → SKIP
S2.4スキップ判定③開始・契約年月23_bud_subscription.H列空 → SKIPstartYm変数: startYm
S2.5変数: ラグ算出決済ラグ(月)23_bud_subscription.N列全角→半角変換後パース。空/非数値→0lagForCheck変数
S2.6変数: 有効開始年月startYm, lagForCheck変数lagForCheck < 0(前払い)の場合: effectiveStartYm = startYm + lagForCheck。それ以外: effectiveStartYm = startYmeffectiveStartYm変数
S2.7変数: 行別対象年月最終起票年月日, targetYm, lagForCheck23_bud_subscription.V列rowTargetYmRaw = 行の最終起票年月日 or targetYmrowTargetYm = rowTargetYmRaw - lagForCheck(決済予定日ベース→利用月ベースに変換)rowTargetYm変数⚠️ rowTargetYmRaw < effectiveStartYmSKIP
S2.8管理ID自動発番管理ID23_bud_subscription.B列空の場合 SAS_NNNN(既存最大+1)を発番し23タブに書き戻しsubMgrId23_bud_subscription.B列
S2.9ORD検索/作成subMgrId, startYm31_wrk_orderキー=`subMgrIdstartYmで既存ORDを検索。未存在ならbuildOrdRow_()` でORDを新規作成ordId31_wrk_order(新規行)
S3.1月ループ開始curYm = startYm変数WHILE curYm <= rowTargetYm⚠️ 終了年月あり AND curYm > 終了年月BREAK
S3.2shouldBill判定契約形態23_bud_subscription.G列月額 → 毎月true。年額 → 開始月と同じ月のみtrueshouldBill変数: shouldBill (bool)⚠️ 月額/年額以外 → 毎月true(月額扱い)
S3.3発生日算出curYm変数curYmの月末日 をDate型で取得発生日変数: occurDate (Date)
S3.4決済日_計画算出決済ラグ(月), 支払基準日23_bud_subscription.N列, O列settleDate = curYm + ラグ月 の 支払基準日。支払基準日=0→月末決済日_計画変数: settleDate (Date)⚠️ 支払基準日>月末日→キャップ
S3.5重複チェック摘要32_wrk_invoice.摘要列isDuplicate_()"【RPA:SaaS】{curYm}利用分: {サービス名}" を検索 → 存在すれば SKIP
S3.6申請種別判定決済手段23_bud_subscription.M列振込 含む → 手動振込クレカ or 振替 含む → 自動引落、それ以外 → 請求書受領(AP)appType変数
S3.7INV行生成全変数buildInvRow_() で INV行を構築。親発注ID(ORD)=ordId, 科目名=費用科目, 税抜金額_計画=taxExcl, 消費税額_計画=taxAmt, 税込金額_計画=totalIncTax, 発生日=occurDate, 決済日_計画=settleDate, 決済手段=payMethod(「未定」含む→空), 組織名=orgName, 申請種別=appTypeINV行drafts配列に追加
S3.8ループ進行curYm変数curYm += 1ヶ月 → S3.1に戻る
W1.1一括書き込み: ORDnewOrdRowswriteOrdRows_() で31タブ末尾に追記31_wrk_order⚠️ 31タブ未存在 or ORD 0件 → スキップ
W1.2一括書き込み: INVdraftswriteInvRows_() で32タブ末尾に追記。諸表区分・大分類を科目マスタから自動付与32_wrk_invoice
W1.323タブ更新: 管理IDsubUpdates管理IDが空だった行に自動発番した SAS_NNNN を書き戻し23_bud_subscription.B列

旧仕様との差異(コード検証結果):

  • 旧S4.5「起票時期チェック(settleDate > targetDate → SKIP)」は現在のコードには存在しない。代わりに行別の rowTargetYm で利用月ベースのループ上限を制御している(S2.7)
  • 旧W1.2「最終起票年月日・最終決済予定日の書き戻し」は現在のコードでは行われない(コメント「手入力のため書き戻しなし」)
  • ORD(31_wrk_order)の自動作成が追加されている(S2.9, W1.1)
  • 申請種別が決済手段に応じて自動判定される(S3.6)。旧仕様では固定値「請求書受領(AP)」

5. 出力サマリー

32_wrk_invoice(INV行)

フィールド備考
有効フラグTRUE
親発注ID(ORD)ORD_YYYYMMDD_NNNN31タブのORDに紐づく
請求ID(INV)INV_YYYYMMDD_NNNN自動発番
起票日時実行時刻
起票者RPA自動起票
申請種別手動振込 / 自動引落 / 請求書受領(AP)決済手段から自動判定
発生日(P/L計上日)対象年月の末日
決済日_計画対象年月 + ラグ月 の 支払基準日
請求ステータス未処理
収支区分支出
取引先名23タブの値「選定中」「未定」→空
科目名23タブの費用科目
税区分23タブの値
通貨JPY
税抜金額_計画23タブの値
消費税額_計画23タブの値
税込金額_計画税抜 + 消費税
未決済残高税込金額_計画初期値=税込金額
決済手段23タブの値「未定」→空
組織名23タブの値
摘要【RPA:SaaS】YYYY-MM利用分: サービス名重複チェックのキー

31_wrk_order(ORD行)

フィールド備考
発注ID(ORD)ORD_YYYYMMDD_NNNN自動発番
契約・件名サービス名 + 契約形態
摘要【RPA:SaaS】サービス名
税抜/消費税/税込金額_発注月額単価 × 契約月数終了年月なし→12ヶ月
参照元区分SaaS
参照元IDSAS_NNNN23タブの管理ID

6. 業務ルール

  1. 行別の最終起票年月日で起票範囲を制御 — 各行の最終起票年月日(手入力)を「ここまで起票済」の上限として扱う。最終起票年月日は決済予定日ベースの値なので、利用月ベースに変換(ラグ分を差し引く)してループ上限とする
  2. 取引先名が「選定中」「未定」なら空に — INVに不確定な名前を入れない
  3. 年額の課金月 — 開始月と同じ月にだけ起票(コード上は月の一致で判定)
  4. 決済ラグの全角対応 — 全角数字を半角に変換してパース
  5. 解約済は除外 — 利用ステータスに「解約済」を含むSaaSは起票しない
  6. 1契約1INV/月 — HCと異なり、預り金・益税等の派生Rowは生成しない
  7. ORD自動作成 — 管理ID+開始年月をキーにORDを検索し、未存在なら自動作成する。契約金額は月額単価×契約月数(終了年月未設定なら12ヶ月)
  8. 管理ID自動発番 — 管理IDが空の行には SAS_NNNN を自動採番し23タブに書き戻す
  9. 申請種別の自動判定 — 決済手段に「振込」を含む→手動振込、「クレカ」「振替」を含む→自動引落、その他→請求書受領(AP)
  10. 決済手段「未定」の除外 — 決済手段に「未定」を含む場合はINVの決済手段を空にする
  11. 前払い(ラグ<0)の有効開始年月 — ラグが負の場合、開始年月にラグ月を加算した月を有効開始年月とする(支払月が開始月より前になるため)

7. 冪等性(二重起票防止)

メカニズム詳細
摘要ベース重複チェックisDuplicate_()"【RPA:SaaS】{curYm}利用分: {サービス名}" を32_wrk_invoiceの摘要列から検索。完全一致する行が存在すればその月の起票をスキップ
ORD重複チェックbuildOrdMap_() で `管理ID

再実行安全性: 同一条件で再実行しても、重複チェックにより既起票分はスキップされるため、二重起票は発生しない。


8. エラーハンドリング

エラー条件処理ユーザー通知
23_bud_subscription タブが存在しない即座にreturn🚨 23_bud_subscription が見つかりません。
SaaSデータが0行(ヘッダのみ)即座にreturn✅ SaaSデータがありません。
必須ヘッダー列が見つからない(サービス名/費用科目/開始年月/税抜金額)即座にreturn⚠️ サブスク台帳の必須項目が見つかりません。
起票対象0件正常終了✅ 起票対象なし: {targetYm} の期間で新たに起票すべきSaaSはありませんでした。
起票成功正常終了🎉 SaaS起票完了: {count}件 のINV行を生成しました。
予期しないエラー(try-catch)Utils.logError でログ出力後return 0🚨 generateSaasInvoices でエラーが発生しました: {e.message}
_silent=true の場合ダイアログを表示しない

9. テスト仕様

単体テスト観点

テストIDテストケース入力期待結果
T1月額・基本M365 Premium: 月額4,354, ラグ1, 支払基準日10, target=2026-02INV1行: 通信費4,354, 発生日=2026-02-28, 決済日_計画=2026-03-10
T2前払い(ラグ-1)オフィス家賃: 月額30,000, ラグ-1, 支払基準日25, target=2026-05INV: 発生日=2026-06-30, 決済日_計画=2026-05-25
T3年額・基本Adobe CC: 年額60,000, 開始2025-04, target=2026-042026-04のみ起票
T4解約済SKIP利用ステータス="解約済"起票されない
T5重複チェック同月を2回実行2回目は0件起票
T6キャッチアップ最終起票=2026-01, target=2026-0302月分・03月分をまとめて起票
T7CF計上=実績オフィス家賃: CF計上="実績"INV起票は通常通り(CF計上はDatamartで判定)
T8消費税あり税抜5,000, 消費税500税込=5,500
T9STL税込金額_決済親ORDあり, 税込4,354Action A後STL税込金額_決済=4,354(jeFxAmt差引きなし)
T10管理ID自動発番管理IDが空の行SAS_NNNN が自動採番され23タブに書き戻し
T11ORD自動作成31タブにORD未存在ORD行が31タブに追加される
T12申請種別: 振込決済手段="口座振込_福井銀行"申請種別="手動振込"
T13申請種別: クレカ決済手段="クレカ_福井銀行"申請種別="自動引落"
T14申請種別: その他決済手段="現金"申請種別="請求書受領(AP)"

テストデータ(23タブ 3行)

#サービス名費用科目取引先サイクル税抜消費税税区分決済手段ラグ支払基準日休日調整CF計上ステータス
1Microsoft 365 Business Premium通信費日本マイクロソフト月額4,3540対象外クレカ_福井銀行110予算利用中
2Microsoft 365 Business Standard通信費日本マイクロソフト月額1,8370対象外クレカ_福井銀行110予算利用中
3オフィス家賃地代家賃高野組月額30,0000対象外口座振込_福井銀行-125実績利用中

ケース A: M365 Premium(月額・後払い・ラグ+1)target=2026-02

算出変数

startYm       = "2026-01"
curYm         = "2026-01"(最終起票=2026-02-10 → lastBilledYm="2026-02" → curYm="2026-03"の場合あり)
cycle         = "月額" → shouldBill = true
lag           = 1
payDay        = 10(後)

32タブ期待結果(INV 2行: 1月分・2月分)

前提: 最終起票年月日をクリアしてtarget=2026-02で実行

#摘要科目名税抜消費税税込発生日決済日_計画決済手段取引先
1【RPA:SaaS】2026-01利用分: M365 Premium通信費4,35404,3542026-01-312026-02-10クレカ_福井銀行日本マイクロソフト
2【RPA:SaaS】2026-02利用分: M365 Premium通信費4,35404,3542026-02-282026-03-10クレカ_福井銀行日本マイクロソフト

: 2月分の決済日_計画=2026-03-10 > targetDate=2026-02-28 のため、2月分はスキップされる。実際にはINV 1行(1月分のみ)。

33タブ期待結果(STL 1行 — Action A後)

STL消込対象INV入出金決済口座取引先税込金額_決済
STL 1INV (1月分)出金クレカ_福井銀行日本マイクロソフト4,354

期待値サマリー

財務諸表科目金額タイミング
P/L通信費-4,3542026-01(発生月)
B/S未払金+4,354 → 01月に計上 → 2月STL消込で解消
B/S現預金-4,354STL消込後
CF出金4,354STL消込時(2026-02)

ケース B: オフィス家賃(月額・前払い・ラグ-1)target=2026-05

算出変数

startYm       = "2026-02"
cycle         = "月額" → shouldBill = true
lag           = -1     ← 前払い(翌月分を前月に支払い)
payDay        = 25(前)

32タブ期待結果

前提: 最終起票=2026-05-25 → lastBilledYm="2026-05" → curYm="2026-06"

#摘要科目名税抜消費税税込発生日決済日_計画決済手段
1【RPA:SaaS】2026-06利用分: オフィス家賃地代家賃30,000030,0002026-06-302026-05-25口座振込_福井銀行

: 6月利用分を5月に前払い。発生日(6月末) > 決済日_計画(5月25日) → 期ズレパターン: 前払費用。

33タブ期待結果(STL 1行 — Action A後)

STL消込対象INV入出金決済口座取引先税込金額_決済
STL 1INV (6月分)出金口座振込_福井銀行高野組30,000

期待値サマリー

財務諸表科目金額タイミング
P/L地代家賃-30,0002026-06(発生月)
B/S前払費用+30,000 → 05月に前払計上 → 6月に解消
B/S現預金-30,000STL消込後(2026-05)
CF出金30,000STL消込時(2026-05)

ケース C: 3行同時テスト(target=2026-02)

前提: 全行の最終起票年月日をクリア

期待される32タブ INV行数

#サービス名摘要の利用月発生日決済日_計画target内?INV行
1M365 Premium2026-012026-01-312026-02-10o1行
2M365 Standard2026-012026-01-312026-02-10o1行
3オフィス家賃2026-022026-02-282026-01-25o1行
4オフィス家賃2026-032026-03-312026-02-25o1行

合計: INV 4行

: オフィス家賃はラグ=-1(前払い)のため、3月利用分の決済日_計画(02-25)もtarget(02-28)内に入り、2行起票される。

33タブ期待結果(STL 4行 — Action A後)

STLINV摘要科目税込金額_決済決済口座
STL 1【RPA:SaaS】2026-01利用分: M365 Premium通信費4,354クレカ_福井銀行
STL 2【RPA:SaaS】2026-01利用分: M365 Standard通信費1,837クレカ_福井銀行
STL 3【RPA:SaaS】2026-02利用分: オフィス家賃地代家賃30,000口座振込_福井銀行
STL 4【RPA:SaaS】2026-03利用分: オフィス家賃地代家賃30,000口座振込_福井銀行

全消込後の期待値サマリー

財務諸表科目金額
P/L通信費-6,1912026-01(M365 Premium 4,354 + Standard 1,837)
P/L地代家賃-30,0002026-02(オフィス家賃 2月利用分)
P/L地代家賃-30,0002026-03(オフィス家賃 3月利用分)
B/S未払金(通信費)+6,191 → 01月計上 → 2月消込
B/S前払費用(家賃2月分)0発生日=02-28, 決済日_計画=01-25 → 前払だがtarget内で即解消
B/S前払費用(家賃3月分)+30,000 → 02月前払 → 3月解消
B/S現預金-66,191全STL消込後
CF出金(通信費)6,1912026-02
CF出金(家賃2月分)30,0002026-01(決済日_計画)
CF出金(家賃3月分)30,0002026-02(決済日_計画)

付録

付録A: Action A → Action B の流れ

SaaS INVはHCと同じ汎用エンジン(403_subledger_engine.js)で処理される。

Action A(INV承認 → TRN + STL自動作成)

1. 32タブで請求ステータスを "承認済" に変更
2. Action A を実行
3. 結果:
   - 42_trn_journal: TRN 1行追加(費用計上仕訳)
     発生日 = INVの発生日
     決済日_計画 = INVの決済日_計画
     科目名 = INVの科目名
     金額 = INVの税込金額_計画
   - 32タブ: 自動仕訳JNL_ID ← TRN_ID
   - 33タブ: STL 1行自動作成(仕訳振替以外のINVのみ)
     税込金額_決済 = 税込金額_計画 ← 仕訳振替Rowなし → そのまま

ORDありの場合のSTL金額: SaaS INVはORDに紐づくが、jeFxAmtMapによる仕訳振替分の差引きは発生しない(SaaS INVに仕訳振替Rowがないため)。STL税込金額_決済 = INV税込金額_計画となる。

Action B(STL消込 → 決済仕訳)

1. 33タブでSTLに決済日・決済ステータス="消込済" を入力
2. Action B を実行
3. 結果:
   - 42_trn_journal: TRN追加(決済仕訳)
     決済日_実績 = STLの決済日
   - 33タブ: 自動仕訳JNL_ID ← TRN_ID
   - 32タブ: INVの未決済残高=0、請求ステータス=決済完了

付録B: 決済ラグによる期ズレパターン

ラグパターンB/S影響
0当月決済pYm=sYm → 期ズレなしなし
+1翌月後払い3月利用→4月決済 → 3月に未払金+、4月に未払金-未払金
-1前月前払い3月利用→2月決済 → 2月に前払費用+、3月に前払費用-前払費用

期ズレは 602_datamart_main.jsprocessEvent() が自動処理する(B/S形状ロジック)。