カテゴリ判定関数(カリー化パターン)
税法上の各控除は、配偶者の所得や扶養親族の年齢といった「生の事実」から直接判定するのではなく、税法カテゴリ(同一生計配偶者、控除対象扶養親族等)の該当有無 を中間判定として経由する。これにより、所得閾値 T(R7: 58万円)のような年度依存パラメータの定義箇所を一元化し、法改正時の修正箇所を最小化する。
→ 設計思想の詳細: 税法カテゴリ判定の一元化 → データモデル: DM-409 CategoryJudgmentResult
3段階カリー化
カテゴリ判定に必要な情報は同時に確定するわけではない。先に確定する情報を部分適用し、残りの情報が確定した時点で判定を完了する カリー化パターンを採用する。
| 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: [...] -- 判定理由
// }なぜカリー化が有効か
- Draft 時のリアルタイムプレビュー最適化: 所得見積額が変わるたびに Stage 1・Stage 2 をやり直す必要がない。Stage 3 のみを再実行 すれば全カテゴリが再判定される
- 年度パラメータの一括切替:
CategoryJudgmentFactory.Create(r7Params)とCreate(r8Params)を差し替えるだけで年度切替可能。テスト時に任意の年度パラメータを注入できる - 純粋関数の保証: 各段階の関数は副作用を持たず、同一入力→同一出力(参照透過性)。Property tests で検証可能
- 合成可能性: カテゴリ判定結果をイミュータブルなレコードとして複数の控除計算関数に共有できる
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 | 同居老親等 | 老人扶養親族 + 直系尊属 + 所得者又は配偶者と同居 |
IsUnder16FuyoShinzoku | 16歳未満扶養親族 | 扶養親族 + 16歳未満(所得税の控除なし、住民税用に保持) |
IsTokuteiShinzoku | 特定親族 | 19歳以上23歳未満 + 所得 T超〜123万円 + 生計一 |
障害者に関するカテゴリ:
| フラグ | 日本語名 | 判定条件(概要) |
|---|---|---|
DisabilityGrade | 障害者区分 | なし / 一般の障害者 / 特別障害者 / 同居特別障害者 |
注意: 年齢は生年月日から12月31日現況で自動計算する。前日満了ルール(誕生日の前日に年齢加算)を適用するため、1月1日生まれと1月2日生まれで結果が異なる。