• #連結会計
  • #TypeScript
  • #テスト駆動開発
  • #Codex
  • #シミュレーター
開発eurekapuメモ

連結会計シミュレーター開発 - 10パターン対応とCodexレビュー

2026年2月4日の開発作業のまとめ。連結会計エンジン(consolidation-engine.ts)の大規模改修を実施した。

今日の作業概要

  1. インデックスカードの追加: consolidation-simulatorページへのアクセス導線を追加
  2. UIの改善: プリセットボタン、矢印トラック、ゾーン表示の実装
  3. 持分計算表の評価差額内訳表示の修正
  4. 段階取得に係る差益の仕訳生成
  5. 連結精算表エンジンの修正: 10パターン対応
  6. Codexレビュー対応
  7. 事例データとの整合性テスト

1. インデックスカードの追加

連結会計シミュレーターへのアクセス導線として、トップページにカードコンポーネントを追加した。

<!-- 会計・ファイナンスカテゴリに追加 -->
<IndexCard
  title="連結会計シミュレーター"
  description="持分比率の変動に応じた連結仕訳を自動生成"
  href="/consolidation-simulator"
/>

2. UIの改善

プリセットボタンの視覚的改善

従来のボタン一覧から、3つの領域(その他・持分法・連結)を横に並べた視覚的なUIに変更した。

┌────────┬────────┬────────┐
│ その他 │ 持分法 │  連結  │
│  0-20% │ 20-50% │ 50%+   │
└────────┴────────┴────────┘
     ●─────────→●
   始点        終点

実装のポイント:

  • 各ゾーンを色分け表示
  • 始点(●)と終点(→)を矢印トラック上で表示
  • ヘッダーのX軸を矢印トラックに揃えるため、ボタン分のスペースを追加

外枠とゾーン間の隙間削除

.zone-track {
  border: none;
  gap: 0;
}

.zone {
  border-left: none;
}

3. 持分計算表の評価差額内訳表示

buildEquityTableSimple関数で、S社純資産を1行で表示していたため評価差額の内訳が見えなかった問題を修正。

修正前:

| S社純資産 | 120,000 |

修正後:

| 資本金      |  50,000 |
| 利益剰余金  |  50,000 |
| 評価差額    |  20,000 |
| 資本合計    | 120,000 |

また、S社修正仕訳で計上される評価差額を「期首残高」ではなく「当期変動」として扱うよう修正。

4. 段階取得に係る差益の仕訳生成

「その他→連結」(10%→80%)パターンで、既存投資(10%分)を支配獲得時の時価で評価し「段階取得に係る差益」を認識する機能を追加。

Assumptions型の拡張

interface Assumptions {
  // ... 既存フィールド
  priorAcquisitionCostPerPercent?: number; // 既存投資の1%あたり取得原価
}

差益計算ロジック

// 段階取得に係る差益の計算
const priorInvestmentCost = from * (a.priorAcquisitionCostPerPercent ?? a.acquisitionCostPerPercent);
const priorInvestmentFairValue = from * a.acquisitionCostPerPercent;
const stepAcquisitionGain = priorInvestmentFairValue - priorInvestmentCost;

if (stepAcquisitionGain !== 0) {
  journals.push({
    title: '段階取得に係る差益',
    entries: [
      { account: 'S社株式', debit: stepAcquisitionGain > 0 ? stepAcquisitionGain : 0, credit: stepAcquisitionGain < 0 ? -stepAcquisitionGain : 0 },
      { account: '段階取得に係る差益', debit: stepAcquisitionGain < 0 ? -stepAcquisitionGain : 0, credit: stepAcquisitionGain > 0 ? stepAcquisitionGain : 0 },
    ],
  });
}

5. 連結精算表エンジンの修正

10パターン対応

#パターン遷移タイプ
1その他→持分法10%→30%
2持分法→持分法(追加)30%→40%
3その他→連結10%→80%
4持分法→連結30%→80%
5連結→連結(追加)70%→80%
6連結→連結(一部売却)80%→70%
7連結→持分法80%→20%
8連結→その他80%→0%
9持分法→持分法(一部売却)40%→30%
10持分法→その他30%→10%

評価差額計算の持分比率考慮

修正前: 評価差額を全額計上

const evalDiff = calcEvaluationDiff(a); // 全額

修正後: 持分比率に応じた計上

function calcEvaluationDiffWithRatio(a: Assumptions, ratio: number): number {
  const fullEvalDiff = (a.landFairValue ?? a.landBookValue) - a.landBookValue;
  return fullEvalDiff * (ratio / 100);
}

2期目以降の開始仕訳対応

1期目と2期目以降で仕訳タイトルと計算ロジックを分ける。

interface Assumptions {
  // ... 既存フィールド
  priorPeriodCount?: number; // 前期までの連結決算回数(0=1期目)
  priorGoodwillAmortization?: number; // 前期までののれん償却累計額
}

function buildOpeningEntry(a: Assumptions): Journal {
  const isPeriod1 = (a.priorPeriodCount ?? 0) === 0;

  return {
    title: isPeriod1 ? '投資と資本の相殺消去' : '開始仕訳',
    entries: [
      // 2期目以降は「利益剰余金(期首)」を使用
      {
        account: isPeriod1 ? '利益剰余金' : '利益剰余金(期首)',
        // ...
      },
    ],
  };
}

勘定科目名の統一

事例データとの一致を図るため、勘定科目名を統一。

修正前修正後
非支配株主に帰属する当期純損益非支配株主に帰属する当期純利益
売却損益S社株式売却益

6. Codexレビュー対応

レビュー依頼

Codexにレビューを依頼します。

Codexの指摘事項

  1. 取得時純資産の評価差額: 取得時の純資産計算に評価差額を含めるべき
  2. のれん計算のタイミング: 10%取得時(その他有価証券)ではのれんを計上しない
  3. 持分法期間の投資利益: 段階取得時に持分法期間の投資利益を考慮

対応内容

「その他→持分法」パターン用の新しい持分計算表関数を追加:

function buildEquityTableOtherToEquity(a: Assumptions): EquityTable {
  // 10%取得時はのれんなし
  // 30%になって初めてのれんを計算
  const goodwill = calcGoodwillAtEquityMethodStart(a);
  // ...
}

今後の改善点として記録

Codexレビューの指摘事項は .claude/codex-review/2026-02-04_093853.md に保存。

7. 事例データとの整合性テスト

computeTransitionJournals関数のテスト

事例データ(Truth)とエンジン出力を比較するテストを作成。

describe('事例データとの整合性テスト', () => {
  const testCases = [
    { name: '追加取得70→80', assumptions: additionalAcquisition7080Assumptions, expected: additionalAcquisition7080Data },
    { name: '段階取得10→80', assumptions: stepAcquisition1080Assumptions, expected: stepAcquisition1080Data },
    // ... 全10パターン
  ];

  testCases.forEach(({ name, assumptions, expected }) => {
    it(`${name}: 仕訳が一致する`, () => {
      const result = computeTransitionJournals(assumptions);
      compareJournals(result.journals, expected.journalEntries);
    });
  });
});

テスト結果

✅ 追加取得70→80: 一致
✅ 段階取得10→80: 一致
✅ 段階取得30→80: 一致
✅ 一部売却80→70: 一致
✅ 連結除外80→20: 一致
✅ 全部売却80→0: 一致

最終結果: 仕訳比較テストは全パターンで一致を確認。


技術的なポイント

純粋関数による計算ロジック

// 評価差額計算(持分比率考慮)
const calcEvaluationDiffWithRatio = (a: Assumptions, ratio: number): number =>
  ((a.landFairValue ?? a.landBookValue) - a.landBookValue) * (ratio / 100);

// のれん計算
const calcGoodwill = (a: Assumptions): number =>
  a.pSInvestment - calcSNetAssets(a) * (a.to / 100);

テスト駆動開発

事例データを「正」として、エンジンをそれに合わせて修正する方針を採用。

事例データ(Truth) ← エンジン出力を合わせる

Codexとの協調

複雑なビジネスロジックのレビューにCodexを活用。人間の確認が難しい計算ロジックの妥当性検証に有効。


次のステップ

  1. 連結精算表テストの完全実装(P社個別財務諸表の値をパラメータ化)
  2. 持分法会計の詳細テスト追加
  3. UIでの10パターン切り替え機能の検証