Skip to content

カテゴリ判定関数(カリー化パターン)

税法上の各控除は、配偶者の所得や扶養親族の年齢といった「生の事実」から直接判定するのではなく、税法カテゴリ(同一生計配偶者、控除対象扶養親族等)の該当有無 を中間判定として経由する。これにより、所得閾値 T(R7: 58万円)のような年度依存パラメータの定義箇所を一元化し、法改正時の修正箇所を最小化する。

→ 設計思想の詳細: 税法カテゴリ判定の一元化 → データモデル: DM-409 CategoryJudgmentResult

3段階カリー化

カテゴリ判定に必要な情報は同時に確定するわけではない。先に確定する情報を部分適用し、残りの情報が確定した時点で判定を完了する カリー化パターンを採用する。

Stage 1: 年度開始時Stage 2: 家族登録時Stage 3: 申告時CategoryJudgmentインスタンスMemberJudgment(人物固有の判定関数)CategoryJudgmentResult(12個の boolean フラグ)TaxYearParameters所得閾値 T年齢境界控除額テーブルCategoryJudgmentFactory.Create()生年月日続柄障害者区分居住区分.ForMember()合計所得金額の見積額.Evaluate()
Stage 1: 年度開始時Stage 2: 家族登録時Stage 3: 申告時CategoryJudgmentインスタンスMemberJudgment(人物固有の判定関数)CategoryJudgmentResult(12個の boolean フラグ)TaxYearParameters所得閾値 T年齢境界控除額テーブルCategoryJudgmentFactory.Create()生年月日続柄障害者区分居住区分.ForMember()合計所得金額の見積額.Evaluate()
Stage確定タイミング適用する情報生成物
Stage 1年度開始時(年度中は不変)所得閾値 T、年齢境界(16歳/19歳/23歳/70歳)、控除額テーブル等CategoryJudgment インスタンス
Stage 2家族登録時(年度中ほぼ不変)生年月日、続柄(FamilyRelationship)、障害者区分、居住/非居住区分MemberJudgment(人物固有の判定関数)
Stage 3申告時(見積りが変わりうる)合計所得金額の見積額CategoryJudgmentResult(→ DM-409

C# での実装イメージ

csharp
// Stage 1: 年度パラメータを適用 → 当年度用の判定関数群を生成
var judge = CategoryJudgmentFactory.Create(taxYearParameters);

// Stage 2: 安定した事実を適用 → 人物固有の判定関数を生成
//   生年月日から年齢を内部で計算(前日満了ルール適用)
//   続柄から親族区分を内部で判定
var memberJudge = judge.ForMember(
    member.BirthDate,
    member.Relationship,
    member.DisabilityCategory,
    member.ResidencyStatus);

// Stage 3: 変動する事実を適用 → 最終判定
var result = memberJudge.Evaluate(member.EstimatedIncome);
// result: CategoryJudgmentResult {
//   IsDouitsuSeikeihaitgusha: true,     -- 同一生計配偶者
//   IsKoujoTaishoHaigusha: true,        -- 控除対象配偶者
//   IsGensenKoujoTaishoHaigusha: false, -- 源泉控除対象配偶者
//   IsFuyoShinzoku: false,              -- 扶養親族
//   IsKoujoTaishoFuyoShinzoku: false,   -- 控除対象扶養親族
//   IsTokuteiYuyoShinzoku: false,       -- 特定扶養親族
//   IsRoujinFuyoShinzoku: false,        -- 老人扶養親族
//   IsDoukyoRoujin: false,              -- 同居老親等
//   IsUnder16FuyoShinzoku: false,       -- 16歳未満扶養親族
//   IsTokuteiShinzoku: false,           -- 特定親族
//   DisabilityGrade: None,              -- 障害者/特別障害者/同居特別障害者
//   JudgmentReasons: [...]              -- 判定理由
// }

なぜカリー化が有効か

  1. Draft 時のリアルタイムプレビュー最適化: 所得見積額が変わるたびに Stage 1・Stage 2 をやり直す必要がない。Stage 3 のみを再実行 すれば全カテゴリが再判定される
  2. 年度パラメータの一括切替: CategoryJudgmentFactory.Create(r7Params)Create(r8Params) を差し替えるだけで年度切替可能。テスト時に任意の年度パラメータを注入できる
  3. 純粋関数の保証: 各段階の関数は副作用を持たず、同一入力→同一出力(参照透過性)。Property tests で検証可能
  4. 合成可能性: カテゴリ判定結果をイミュータブルなレコードとして複数の控除計算関数に共有できる

CategoryJudgmentResult の出力フラグ一覧

CategoryJudgmentResult(→ DM-409)は、各家族構成員に対する税法上のカテゴリ該当有無を boolean フラグ群で保持する。

配偶者に関するカテゴリ:

フラグ日本語名判定条件(概要)
IsDouitsuSeikeihaitgusha同一生計配偶者配偶者の合計所得金額 ≤ T + 生計一 + 専従者除外
IsKoujoTaishoHaigusha控除対象配偶者同一生計配偶者 + 本人の合計所得金額 ≤ 1,000万円
IsGensenKoujoTaishoHaigusha源泉控除対象配偶者配偶者の合計所得金額 ≤ 95万円 + 本人の合計所得金額 ≤ 900万円
IsHaigushaTokubetsuKoujoTaisho配偶者特別控除対象配偶者の合計所得金額 T超〜133万円 + 本人の合計所得金額 ≤ 1,000万円

扶養親族に関するカテゴリ:

フラグ日本語名判定条件(概要)
IsFuyoShinzoku扶養親族親族範囲内 + 親族の合計所得金額 ≤ T + 生計一 + 専従者除外 + 配偶者でない
IsKoujoTaishoFuyoShinzoku控除対象扶養親族扶養親族 + 16歳以上
IsTokuteiFuyoShinzoku特定扶養親族控除対象扶養親族 + 19歳以上23歳未満
IsRoujinFuyoShinzoku老人扶養親族控除対象扶養親族 + 70歳以上
IsDoukyoRoujin同居老親等老人扶養親族 + 直系尊属 + 所得者又は配偶者と同居
IsUnder16FuyoShinzoku16歳未満扶養親族扶養親族 + 16歳未満(所得税の控除なし、住民税用に保持)
IsTokuteiShinzoku特定親族19歳以上23歳未満 + 所得 T超〜123万円 + 生計一

障害者に関するカテゴリ:

フラグ日本語名判定条件(概要)
DisabilityGrade障害者区分なし / 一般の障害者 / 特別障害者 / 同居特別障害者

注意: 年齢は生年月日から12月31日現況で自動計算する。前日満了ルール(誕生日の前日に年齢加算)を適用するため、1月1日生まれと1月2日生まれで結果が異なる。