@classytic/ca-tax 0.0.22 → 0.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.23] - 2026-09-17
4
+
5
+ ### Fixed — two mandatory AT1 gate lines went to TRA unfiled
6
+
7
+ Both are "N" (yes/no) fields marked `M` in AT1-Chapter3-2026.4, described by
8
+ the transcribed form model while no builder emitted them — every Schedule 2
9
+ and every Schedule 12 filed missing a mandatory line. Neither needed to be
10
+ asked; the specification derives each default:
11
+
12
+ - **Schedule 2, line `001`** — is the corporation in a special allocation
13
+ category (airline, railway, bank, insurer, grain elevator, …)? "If special
14
+ allocation rules apply (fed `005100` value is other than 402), value = 1.
15
+ Otherwise, if general allocation (fed `005100` = 402), default value = 2."
16
+ This engine computes only the general Regulation 402 formula (½ revenue + ½
17
+ salaries), so it files the honest default — a true statement, not a guess
18
+ at an unasked question. `specialAllocationCategory?: boolean` lets a host
19
+ that knows otherwise override it.
20
+ - **Schedule 12, lines `100`/`102`/`104`/`106`** — the active business income
21
+ reconciliation. `100` is mandatory on every Schedule 12; the spec defaults
22
+ it to "No" (2) unless a divergence between Alberta and federal ABI is
23
+ stated. On "Yes", `102`/`104` "must exist" and `106` (their sum) is what
24
+ AT1 Schedule 1 line `003` reads in place of the federal figure — which is
25
+ why the Alberta small-business deduction ends up computed on the wrong
26
+ amount if this block is silently absent on a divergent return.
27
+ `albertaActiveBusinessIncome?: { differsFromFederal, federalAmount?,
28
+ discretionaryAdjustment? }`.
29
+
30
+ `tests/at1-mandatory-gates.test.ts`.
31
+
3
32
  ## [0.0.22] - 2026-09-16
4
33
 
5
34
  ### Added — AT1 Schedule 15 transcribed in full: 5 lines to 127 boxes across six pages
package/dist/index3.d.mts CHANGED
@@ -2901,6 +2901,28 @@ interface Schedule12FilingInput {
2901
2901
  alberta: number;
2902
2902
  federal: number;
2903
2903
  };
2904
+ /**
2905
+ * 012100-012106 — the active business income reconciliation.
2906
+ *
2907
+ * 100 is MANDATORY on every Schedule 12 and §3.2.3.13 supplies its default:
2908
+ * "If the corp is calculating Alberta ABI different from federal ABI, set
2909
+ * value = 1 (Yes). Otherwise, default to 2 (No)." So the block is filed as a
2910
+ * plain "No" unless a divergence is stated — omitting the line entirely, as
2911
+ * this builder did, is the one thing the rule does not allow.
2912
+ *
2913
+ * When it IS "Yes", three more lines follow and the spec is strict about
2914
+ * both directions: 102 and 104 "must exist" on a Yes and "must not exist" on
2915
+ * a No. 106 is their sum, and AT1 Schedule 1 line 003 then takes it instead
2916
+ * of the federal figure — "if 012100 = 1, then value = 012102 + 012104 …
2917
+ * otherwise, if form 012 does not exist, default to fed 200400" — which is
2918
+ * why the Alberta small-business deduction has to be computed on this
2919
+ * amount, not on the federal one.
2920
+ */
2921
+ albertaActiveBusinessIncome?: {
2922
+ /** 012100 — Yes (1) when Alberta's ABI differs from federal's. */differsFromFederal: boolean; /** 012102 — the federal figure being reconciled (T2 line 400, or S7 amount Q / S16 line 124). Signed. */
2923
+ federalAmount?: number; /** 012104 — the adjustment for discretionary items. Signed: the form prints "Show negative amount in brackets ()." */
2924
+ discretionaryAdjustment?: number;
2925
+ };
2904
2926
  /**
2905
2927
  * Area B — losses of preceding taxation years, deducted in arriving at Alberta
2906
2928
  * taxable income. Same federal/Alberta pairing as Area A, but NOT the same
@@ -3140,6 +3162,21 @@ interface Schedule2FilingInput {
3140
3162
  totalSalaries?: number;
3141
3163
  albertaRevenue?: number;
3142
3164
  totalRevenue?: number;
3165
+ /**
3166
+ * 002001 — is the corporation in one of the SPECIAL allocation categories
3167
+ * (airline, railway, bank, insurer, grain elevator, …)?
3168
+ *
3169
+ * §3.2.3.3 derives this rather than asking: "If special allocation rules
3170
+ * apply (fed 005100 value is other than 402), value = 1. Otherwise, if
3171
+ * general allocation (fed 005100 = 402), default value = 2."
3172
+ *
3173
+ * This engine computes only the GENERAL Regulation 402 formula (½ revenue +
3174
+ * ½ salaries — see `computeAllocationFactor`), so the default is 2 and that
3175
+ * is the honest answer for every return it can calculate. A host that knows
3176
+ * otherwise sets this; the factor filed beside it would then have to come
3177
+ * from the special formula, which this engine does not implement.
3178
+ */
3179
+ specialAllocationCategory?: boolean;
3143
3180
  }
3144
3181
  declare function schedule2Values$1(input: Schedule2FilingInput): At1ScheduleData;
3145
3182
  /**
package/dist/t2.mjs CHANGED
@@ -908,6 +908,15 @@ function schedule12Values(input) {
908
908
  const derive = (income, deductions, additions) => income - deductions < 0 && additions > 0 ? additions : income - deductions + additions;
909
909
  put("090", input.taxableIncome?.alberta ?? derive(n("054"), sum(AREA_B_ALBERTA), n("082")));
910
910
  put("091", input.taxableIncome?.federal ?? derive(n("002"), sum(AREA_B_FEDERAL), n("083")));
911
+ const abi = input.albertaActiveBusinessIncome;
912
+ put("100", abi?.differsFromFederal ? 1 : 2);
913
+ if (abi?.differsFromFederal) {
914
+ const federalAmount = Math.round(abi.federalAmount ?? 0);
915
+ const adjustment = Math.round(abi.discretionaryAdjustment ?? 0);
916
+ put("102", federalAmount);
917
+ put("104", adjustment);
918
+ put("106", federalAmount + adjustment);
919
+ }
911
920
  return {
912
921
  scheduleId: "012",
913
922
  values
@@ -1079,6 +1088,7 @@ function schedule2Values$1(input) {
1079
1088
  value: Math.max(0, value)
1080
1089
  });
1081
1090
  };
1091
+ put("001", input.specialAllocationCategory ? 1 : 2);
1082
1092
  put("002", input.albertaSalaries);
1083
1093
  put("004", input.totalSalaries);
1084
1094
  put("006", input.albertaRevenue);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/ca-tax",
3
- "version": "0.0.22",
3
+ "version": "0.0.23",
4
4
  "description": "Canadian corporate tax engine for @classytic/tax-core — federal T2, Alberta AT1 and Québec CO-17 with form definitions traced to the published forms, plus GST/HST/PST/QST with dated provincial regimes.",
5
5
  "type": "module",
6
6
  "license": "MIT",