@paro.io/expert-shared-components 1.14.74 → 1.14.76
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/lib/components/TaxAxis/TaxAxisShell.js +76 -13
- package/lib/tax-axis/components/clientReport/ExecutiveSummary.js +2 -2
- package/lib/tax-axis/components/intake/ClientParametersSection.js +0 -7
- package/lib/tax-axis/components/intake/RefineAnalysisSection.js +45 -1
- package/lib/tax-axis/components/intake/StrategyRadar.js +2 -2
- package/lib/tax-axis/components/intake/intakeSchema.d.ts +51 -0
- package/lib/tax-axis/components/intake/intakeSchema.js +64 -16
- package/lib/tax-axis/components/preparerWorkpaper/EngagementHeader.js +1 -1
- package/lib/tax-axis/components/prospectReport/SampleAnalysisPreview.d.ts +1 -4
- package/lib/tax-axis/components/prospectReport/SampleAnalysisPreview.js +8 -17
- package/lib/tax-axis/components/prospectReport/TaxAxisProspectReport.js +17 -14
- package/lib/tax-axis/lib/compute/index.js +14 -14
- package/lib/tax-axis/lib/documentFieldCatalog.d.ts +5 -10
- package/lib/tax-axis/lib/documentFieldCatalog.js +115 -329
- package/lib/tax-axis/lib/types/index.d.ts +12 -0
- package/package.json +1 -1
|
@@ -48,8 +48,6 @@ function filterEligibleStrategies(profile) {
|
|
|
48
48
|
return false;
|
|
49
49
|
if (s.needsOwnerComp && ownerComp <= 0)
|
|
50
50
|
return false;
|
|
51
|
-
if (s.rank === 8 && (profile.ownsRealEstate || "No") === "No")
|
|
52
|
-
return false;
|
|
53
51
|
return true;
|
|
54
52
|
});
|
|
55
53
|
}
|
|
@@ -64,8 +62,8 @@ function computeAllStrategies(profile) {
|
|
|
64
62
|
const age = parseInt(profile.age || "45") || 45;
|
|
65
63
|
const hsaExisting = (0, exports.parseNum)(profile.hsaContributions);
|
|
66
64
|
const retirementExisting = (0, exports.parseNum)(profile.retirementContributions);
|
|
67
|
-
const fedRate =
|
|
68
|
-
const stateRate = parseFloat(profile.stateRate || "
|
|
65
|
+
const fedRate = parseFloat((profile.federalRate || "24").replace("%", "")) / 100 || 0.24;
|
|
66
|
+
const stateRate = parseFloat(profile.stateRate || "0") / 100;
|
|
69
67
|
const combinedRate = fedRate + stateRate;
|
|
70
68
|
const seTaxRate = 0.153;
|
|
71
69
|
const sstb = profile.sstb || "No";
|
|
@@ -135,17 +133,25 @@ function computeAllStrategies(profile) {
|
|
|
135
133
|
const hsaLimit = 8550;
|
|
136
134
|
const hsaAdditional = Math.max(hsaLimit - hsaExisting, 0);
|
|
137
135
|
const hsaSavings = Math.round(hsaAdditional * (combinedRate + 0.0765));
|
|
138
|
-
results.set(9, { lo: Math.max(Math.round(hsaSavings * 0.
|
|
136
|
+
results.set(9, { lo: Math.max(Math.round(hsaSavings * 0.90), 0), hi: Math.max(Math.round(hsaSavings * 1.05), 0),
|
|
139
137
|
sources: [{ doc: "Intake", line: "HSA", value: `$${hsaExisting.toLocaleString()}`, field: "YTD Contributions" }, { doc: "IRS 2026", line: "Rev. Proc.", value: "$8,550", field: "Family Limit" }],
|
|
140
138
|
trace: [{ n: 1, step: "2026 family limit", formula: "Rev. Proc. 2025-32", result: "$8,550", src: "IRS" }, { n: 2, step: "Already contributed", formula: "W-2 Box 12 Code W", result: `$${hsaExisting.toLocaleString()}`, src: "Intake" }, { n: 3, step: "Remaining room", formula: `8,550 \u2212 ${hsaExisting.toLocaleString()}`, result: `$${hsaAdditional.toLocaleString()}`, src: "Computed" }, { n: 4, step: "Tax savings", formula: `${hsaAdditional.toLocaleString()} \u00D7 ${((combinedRate + 0.0765) * 100).toFixed(1)}%`, result: `$${hsaSavings.toLocaleString()}`, src: "Triple tax" }] });
|
|
141
139
|
}
|
|
142
140
|
/* #15 SALT/PTE Optimization */
|
|
143
141
|
{
|
|
144
|
-
|
|
142
|
+
// When primary state rate is 0 (e.g. TX), use highest nexus state rate
|
|
143
|
+
let pteStateRate = stateRate;
|
|
144
|
+
if (pteStateRate === 0 && (profile.states || []).length > 1) {
|
|
145
|
+
const STATE_TOP_RATES = { CA: 13.30, NY: 10.90, NJ: 10.75, HI: 11.00, OR: 9.90, MN: 9.85, DC: 10.75, VT: 8.75, WI: 7.65, ME: 7.15, CT: 6.99, NE: 6.64, DE: 6.60, MT: 6.75, SC: 6.50, RI: 5.99, ID: 5.80, NM: 5.90, VA: 5.75, MD: 5.75, KS: 5.70, GA: 5.39, WV: 5.12, MA: 5.00, MS: 5.00, AL: 5.00, MO: 4.95, IL: 4.95, UT: 4.65, OK: 4.75, NC: 4.50, CO: 4.40, AR: 4.40, MI: 4.25, LA: 4.25, KY: 4.00, OH: 3.75, IN: 3.05, PA: 3.07, AZ: 2.50, ND: 1.95 };
|
|
146
|
+
const nexusRates = (profile.states || []).map(s => { var _a; return ((_a = STATE_TOP_RATES[s]) !== null && _a !== void 0 ? _a : 0) / 100; }).filter(r => r > 0);
|
|
147
|
+
if (nexusRates.length > 0)
|
|
148
|
+
pteStateRate = Math.max(...nexusRates);
|
|
149
|
+
}
|
|
150
|
+
const statesTaxPaid = Math.round(net * pteStateRate);
|
|
145
151
|
const pteSavings = Math.round(statesTaxPaid * 0.70);
|
|
146
152
|
results.set(15, { lo: Math.max(Math.round(pteSavings * 0.80), 0), hi: Math.max(Math.round(pteSavings * 1.10), 0),
|
|
147
|
-
sources: [{ doc: "Intake", line: "Net Income", value: `$${net.toLocaleString()}`, field: "Pass-through Income" }, { doc: "Intake", line: "State Rate", value: `${(
|
|
148
|
-
trace: [{ n: 1, step: "Entity-level state tax", formula: `${net.toLocaleString()} \u00D7 ${(
|
|
153
|
+
sources: [{ doc: "Intake", line: "Net Income", value: `$${net.toLocaleString()}`, field: "Pass-through Income" }, { doc: "Intake", line: "State Rate", value: `${(pteStateRate * 100).toFixed(2)}%`, field: "Marginal State Rate" }, { doc: "OBBBA \u00A770109", line: "SALT Cap", value: "$40,400", field: "2026 Cap" }],
|
|
154
|
+
trace: [{ n: 1, step: "Entity-level state tax", formula: `${net.toLocaleString()} \u00D7 ${(pteStateRate * 100).toFixed(2)}%`, result: `$${statesTaxPaid.toLocaleString()}`, src: "Intake" }, { n: 2, step: "PTE deduction value", formula: "Entity-level deduction bypasses SALT cap", result: `$${statesTaxPaid.toLocaleString()}`, src: "Notice 2020-75" }, { n: 3, step: "Net savings (credit offset)", formula: `${statesTaxPaid.toLocaleString()} \u00D7 70% recovery`, result: `$${pteSavings.toLocaleString()}`, src: "State credit" }] });
|
|
149
155
|
}
|
|
150
156
|
/* #22 Overtime Pay Deduction (OBBBA) */
|
|
151
157
|
if (overtime > 0) {
|
|
@@ -167,11 +173,5 @@ function computeAllStrategies(profile) {
|
|
|
167
173
|
results.set(rank, Object.assign(Object.assign({}, v), { lo: Math.round(v.hi / 3.0) }));
|
|
168
174
|
}
|
|
169
175
|
}
|
|
170
|
-
// Safety net: ensure lo and hi don't round to same K (prevents "$XK–$XK" display)
|
|
171
|
-
for (const [rank, v] of results) {
|
|
172
|
-
if (v.hi > 0 && v.lo > 0 && Math.round(v.lo / 1000) >= Math.round(v.hi / 1000)) {
|
|
173
|
-
results.set(rank, Object.assign(Object.assign({}, v), { lo: Math.round(v.hi * 0.85) }));
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
176
|
return results;
|
|
177
177
|
}
|
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
export interface
|
|
2
|
-
label
|
|
1
|
+
export interface FieldDef {
|
|
2
|
+
label: string;
|
|
3
3
|
sourceRef?: string;
|
|
4
4
|
}
|
|
5
5
|
export interface CatalogSection {
|
|
6
6
|
head: string;
|
|
7
7
|
fields: string[];
|
|
8
8
|
}
|
|
9
|
-
export interface
|
|
9
|
+
export interface DocumentCatalogEntry {
|
|
10
10
|
sections: CatalogSection[];
|
|
11
|
-
fields: Record<string,
|
|
11
|
+
fields: Record<string, FieldDef>;
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
* Keyed by documentType string returned by the backend in parsedData.documentType.
|
|
15
|
-
* When DocumentReviewModal receives parsedData, it looks up the documentType here
|
|
16
|
-
* to get section groupings and field labels. Falls back to flat rendering if no entry.
|
|
17
|
-
*/
|
|
18
|
-
export declare const DOCUMENT_FIELD_CATALOG: Record<string, CatalogEntry>;
|
|
13
|
+
export declare const DOCUMENT_FIELD_CATALOG: Record<string, DocumentCatalogEntry>;
|