@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
|
@@ -128,6 +128,19 @@ function buildSessionInput(profile) {
|
|
|
128
128
|
states: profile.states || [],
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
|
+
function enrichWithAllocations(p) {
|
|
132
|
+
var _a;
|
|
133
|
+
if (!((_a = p.partners) === null || _a === void 0 ? void 0 : _a.length))
|
|
134
|
+
return p;
|
|
135
|
+
const netIncome = toInt(p.netIncome);
|
|
136
|
+
const ownerComp = toInt(p.ownerComp);
|
|
137
|
+
return Object.assign(Object.assign({}, p), { per_owner_allocations: p.partners.map(partner => ({
|
|
138
|
+
owner_name: partner.name,
|
|
139
|
+
ownership_pct: partner.ownershipPct / 100,
|
|
140
|
+
qbi: Math.round(netIncome * (partner.ownershipPct / 100)),
|
|
141
|
+
w2_wages: Math.round(ownerComp * (partner.ownershipPct / 100)),
|
|
142
|
+
})) });
|
|
143
|
+
}
|
|
131
144
|
function ShellContainer({ children, fullWidth = false, }) {
|
|
132
145
|
if (fullWidth) {
|
|
133
146
|
return react_1.default.createElement(react_1.default.Fragment, null, children);
|
|
@@ -195,20 +208,68 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
195
208
|
}
|
|
196
209
|
}), [taxAxisApi]);
|
|
197
210
|
// On mount: if a sessionId was injected (e.g. returning to an existing session),
|
|
198
|
-
//
|
|
211
|
+
// fetch the session stage and resume at the correct step.
|
|
199
212
|
(0, react_1.useEffect)(() => {
|
|
200
|
-
if (!initialSessionId
|
|
213
|
+
if (!initialSessionId)
|
|
201
214
|
return;
|
|
202
|
-
taxAxisApi.
|
|
203
|
-
.then((
|
|
204
|
-
|
|
205
|
-
|
|
215
|
+
taxAxisApi.getSession(initialSessionId)
|
|
216
|
+
.then((session) => __awaiter(void 0, void 0, void 0, function* () {
|
|
217
|
+
var _a;
|
|
218
|
+
if (!session)
|
|
219
|
+
return;
|
|
220
|
+
// Restore profile from session fields so DOCUMENT_UPLOAD header renders correctly
|
|
221
|
+
setSessionId(initialSessionId);
|
|
222
|
+
setProfile((prev) => {
|
|
223
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
224
|
+
return prev !== null && prev !== void 0 ? prev : {
|
|
225
|
+
bizName: (_a = session.businessName) !== null && _a !== void 0 ? _a : '',
|
|
226
|
+
entity: (_b = session.entityType) !== null && _b !== void 0 ? _b : '',
|
|
227
|
+
industry: (_c = session.industry) !== null && _c !== void 0 ? _c : '',
|
|
228
|
+
year: String((_d = session.taxYear) !== null && _d !== void 0 ? _d : new Date().getFullYear()),
|
|
229
|
+
revenue: String((_e = session.annualRevenue) !== null && _e !== void 0 ? _e : ''),
|
|
230
|
+
ownerComp: String((_f = session.w2Compensation) !== null && _f !== void 0 ? _f : ''),
|
|
231
|
+
employees: String((_g = session.employeeCount) !== null && _g !== void 0 ? _g : ''),
|
|
232
|
+
states: (_h = session.states) !== null && _h !== void 0 ? _h : [],
|
|
233
|
+
};
|
|
234
|
+
});
|
|
235
|
+
const stage = (_a = session.stage) !== null && _a !== void 0 ? _a : '';
|
|
236
|
+
if (stage === 'REPORT_READY' || stage === 'COMPLETED') {
|
|
237
|
+
// Load LLM run data and jump to dashboard
|
|
238
|
+
if (taxAxisApi.getLlmRun) {
|
|
239
|
+
try {
|
|
240
|
+
const run = yield taxAxisApi.getLlmRun(initialSessionId, 'GENERATION');
|
|
241
|
+
if (run === null || run === void 0 ? void 0 : run.outputPayload) {
|
|
242
|
+
setLlmResult(run.outputPayload);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch ( /* non-blocking */_b) { /* non-blocking */ }
|
|
246
|
+
}
|
|
247
|
+
yield fetchAndSetParsedDocuments(initialSessionId);
|
|
206
248
|
setStep('DASHBOARD');
|
|
207
|
-
|
|
249
|
+
if (onSessionChange)
|
|
250
|
+
onSessionChange(initialSessionId);
|
|
251
|
+
return;
|
|
208
252
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
253
|
+
if (stage === 'LLM_RUNNING' || stage === 'EVAL_RUNNING') {
|
|
254
|
+
// Jump straight to processing screen and start polling
|
|
255
|
+
setStep('PROCESSING');
|
|
256
|
+
pollForResult(initialSessionId);
|
|
257
|
+
if (onSessionChange)
|
|
258
|
+
onSessionChange(initialSessionId);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
// INITIALIZED, DOCUMENTS_UPLOADED, PARSING, PARSED, EXTRACTION_REVIEW, FAILED, EVAL_FAILED
|
|
262
|
+
// Resume at document upload so the user can review/add documents or retry
|
|
263
|
+
setStep('DOCUMENT_UPLOAD');
|
|
264
|
+
if (onSessionChange)
|
|
265
|
+
onSessionChange(initialSessionId);
|
|
266
|
+
}))
|
|
267
|
+
.catch(() => {
|
|
268
|
+
// On error fall back to SESSION_SETUP — clear skeleton so page isn't stuck
|
|
269
|
+
if (onSessionChange)
|
|
270
|
+
onSessionChange(null);
|
|
271
|
+
});
|
|
272
|
+
// fetchAndSetParsedDocuments and pollForResult intentionally excluded: only runs on mount
|
|
212
273
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
213
274
|
}, [initialSessionId]);
|
|
214
275
|
const updateSessionId = (0, react_1.useCallback)((nextSessionId) => {
|
|
@@ -245,7 +306,8 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
245
306
|
updateSessionId(null);
|
|
246
307
|
}, [updateSessionId]);
|
|
247
308
|
const handleProspect = (nextProfile) => __awaiter(void 0, void 0, void 0, function* () {
|
|
248
|
-
|
|
309
|
+
const enriched = enrichWithAllocations(nextProfile);
|
|
310
|
+
setProfile(enriched);
|
|
249
311
|
setIsProspectFlow(true);
|
|
250
312
|
setProspectData(null);
|
|
251
313
|
setProspectLoading(true);
|
|
@@ -253,7 +315,7 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
253
315
|
try {
|
|
254
316
|
if (taxAxisApi.generateProspectReport) {
|
|
255
317
|
const result = yield taxAxisApi.generateProspectReport({
|
|
256
|
-
clientProfile:
|
|
318
|
+
clientProfile: enriched,
|
|
257
319
|
});
|
|
258
320
|
setProspectData({
|
|
259
321
|
computePayload: result.computePayload,
|
|
@@ -269,7 +331,8 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
269
331
|
}
|
|
270
332
|
});
|
|
271
333
|
const handleFullAnalysis = (0, react_1.useCallback)((nextProfile) => __awaiter(void 0, void 0, void 0, function* () {
|
|
272
|
-
|
|
334
|
+
const enriched = enrichWithAllocations(nextProfile);
|
|
335
|
+
setProfile(enriched);
|
|
273
336
|
setIsProspectFlow(false);
|
|
274
337
|
setError(null);
|
|
275
338
|
setBusyMessage('Creating Tax Axis session...');
|
|
@@ -52,7 +52,7 @@ function ExecutiveSummary({ profile, eligible, computed, totalLo, totalHi, leadC
|
|
|
52
52
|
" Savings estimates reflect your current revenue of ",
|
|
53
53
|
rev >= 1000000 ? "$" + (rev / 1000000).toFixed(1) + "M" : "$" + Math.round(rev / 1000) + "K",
|
|
54
54
|
", an effective tax rate of ",
|
|
55
|
-
effectiveTaxRate != null ? Math.round((effectiveTaxRate <= 1 ? effectiveTaxRate * 100 : effectiveTaxRate) * 10) / 10 : ((profile.entity === "C-Corporation" ? 21 : parseFloat(profile.federalRate || "24")) + parseFloat(profile.stateRate || "
|
|
55
|
+
effectiveTaxRate != null ? Math.round((effectiveTaxRate <= 1 ? effectiveTaxRate * 100 : effectiveTaxRate) * 10) / 10 : ((profile.entity === "C-Corporation" ? 21 : parseFloat(profile.federalRate || "24")) + parseFloat(profile.stateRate || "0")),
|
|
56
56
|
"%, and ",
|
|
57
57
|
dataYearsLabel,
|
|
58
58
|
" of financial data."),
|
|
@@ -60,7 +60,7 @@ function ExecutiveSummary({ profile, eligible, computed, totalLo, totalHi, leadC
|
|
|
60
60
|
// C-Corps have a flat 21% federal rate
|
|
61
61
|
const isCCorp = profile.entity === "C-Corporation";
|
|
62
62
|
const fedRate = isCCorp ? 21 : parseFloat(profile.federalRate || "24");
|
|
63
|
-
const stateRate = parseFloat(profile.stateRate || "
|
|
63
|
+
const stateRate = parseFloat(profile.stateRate || "0");
|
|
64
64
|
// If engine provided effective_tax_rate (as a decimal 0-1), convert to percentage
|
|
65
65
|
const currentRate = effectiveTaxRate != null
|
|
66
66
|
? (effectiveTaxRate <= 1 ? effectiveTaxRate * 100 : effectiveTaxRate)
|
|
@@ -80,13 +80,6 @@ function ClientParametersSection({ userContext = "expert", }) {
|
|
|
80
80
|
setValue("period", "YTD");
|
|
81
81
|
}
|
|
82
82
|
}, [isCurrentOrFuture, setValue]);
|
|
83
|
-
// Auto-select 21% federal rate for C-Corporations (flat TCJA rate)
|
|
84
|
-
const selectedEntity = watch("entity");
|
|
85
|
-
react_1.default.useEffect(() => {
|
|
86
|
-
if (selectedEntity === "C-Corporation") {
|
|
87
|
-
setValue("federalRate", "21%");
|
|
88
|
-
}
|
|
89
|
-
}, [selectedEntity, setValue]);
|
|
90
83
|
const [expanded, setExpanded] = (0, react_1.useState)(true);
|
|
91
84
|
return (react_1.default.createElement(TaxAxisCard_1.TaxAxisCard, null,
|
|
92
85
|
react_1.default.createElement("div", { onClick: () => setExpanded((prev) => !prev), className: "flex items-center justify-between cursor-pointer", style: { marginBottom: expanded ? 14 : 0 } },
|
|
@@ -42,7 +42,7 @@ const SSTB_OPTIONS = ["Yes", "No", "Unsure"];
|
|
|
42
42
|
const REAL_ESTATE_OPTIONS = ["No", "Yes — Commercial", "Yes — Residential", "Yes — Both"];
|
|
43
43
|
const ITEMIZES_OPTIONS = ["Yes", "No", "Unsure"];
|
|
44
44
|
const SINGLE_OWNER_OPTIONS = ["Yes", "No"];
|
|
45
|
-
const FEDERAL_RATE_OPTIONS = ["10%", "12%", "
|
|
45
|
+
const FEDERAL_RATE_OPTIONS = ["10%", "12%", "22%", "24%", "32%", "35%", "37%"];
|
|
46
46
|
const TAX_DATA_YEARS_OPTIONS = ["1 year", "2 years", "3 years", "4 years", "5 years"];
|
|
47
47
|
// Risk Tolerance: mock stores first char ("1"-"5") as value.
|
|
48
48
|
// NOTE: intakeDefaultValues sets riskTolerance to "M" (spec) but the mock
|
|
@@ -60,6 +60,22 @@ function RefineAnalysisSection({ userContext: _userContext, }) {
|
|
|
60
60
|
const [expanded, setExpanded] = (0, react_1.useState)(false);
|
|
61
61
|
const { control, watch, formState: { errors }, } = (0, react_hook_form_1.useFormContext)();
|
|
62
62
|
const ownsRealEstate = watch("ownsRealEstate");
|
|
63
|
+
const entity = watch("entity");
|
|
64
|
+
const singleOwner = watch("singleOwner");
|
|
65
|
+
const showRoster = (entity === "Partnership" || entity === "LLC") && singleOwner === "No";
|
|
66
|
+
const { fields, append, remove } = (0, react_hook_form_1.useFieldArray)({ control, name: "partners" });
|
|
67
|
+
const watchedPartners = watch("partners") || [];
|
|
68
|
+
const totalPct = watchedPartners.reduce((sum, p) => sum + (Number(p === null || p === void 0 ? void 0 : p.ownershipPct) || 0), 0);
|
|
69
|
+
const pctValid = Math.abs(totalPct - 100) < 0.01;
|
|
70
|
+
(0, react_1.useEffect)(() => {
|
|
71
|
+
if (showRoster && fields.length === 0) {
|
|
72
|
+
append([
|
|
73
|
+
{ name: "", ownershipPct: 0, partnerType: "general" },
|
|
74
|
+
{ name: "", ownershipPct: 0, partnerType: "general" },
|
|
75
|
+
]);
|
|
76
|
+
}
|
|
77
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
78
|
+
}, [showRoster]);
|
|
63
79
|
return (react_1.default.createElement(TaxAxisCard_1.TaxAxisCard, null,
|
|
64
80
|
react_1.default.createElement("div", { onClick: () => setExpanded(prev => !prev), className: "flex items-center justify-between cursor-pointer", style: { marginBottom: expanded ? 10 : 0 } },
|
|
65
81
|
react_1.default.createElement("span", { className: "text-[11px] font-semibold uppercase tracking-wider text-tax-axis-text-3" }, "Refine Analysis"),
|
|
@@ -102,6 +118,34 @@ function RefineAnalysisSection({ userContext: _userContext, }) {
|
|
|
102
118
|
react_1.default.createElement(react_hook_form_1.Controller, { name: "singleOwner", control: control, render: ({ field }) => (react_1.default.createElement("div", { className: "relative" },
|
|
103
119
|
react_1.default.createElement("select", Object.assign({}, field, { className: selectCls }), SINGLE_OWNER_OPTIONS.map(o => (react_1.default.createElement("option", { key: o, value: o, className: "bg-tax-axis-surface-2" }, o)))),
|
|
104
120
|
react_1.default.createElement(Chevron, null))) }))),
|
|
121
|
+
showRoster && (react_1.default.createElement("div", { className: "mt-3 mb-2.5" },
|
|
122
|
+
react_1.default.createElement("div", { className: subHeaderCls, style: { marginTop: 0 } }, "Partner / Member Roster"),
|
|
123
|
+
react_1.default.createElement("div", { className: "space-y-2" }, fields.map((field, idx) => (react_1.default.createElement("div", { key: field.id, className: "flex items-end gap-2" },
|
|
124
|
+
react_1.default.createElement("div", { className: "flex-1 min-w-0" },
|
|
125
|
+
idx === 0 && react_1.default.createElement("label", { className: labelCls }, "Name"),
|
|
126
|
+
react_1.default.createElement(react_hook_form_1.Controller, { name: `partners.${idx}.name`, control: control, render: ({ field: f }) => (react_1.default.createElement("input", Object.assign({}, f, { placeholder: "Partner name", className: inputCls }))) })),
|
|
127
|
+
react_1.default.createElement("div", { className: "w-[90px] shrink-0" },
|
|
128
|
+
idx === 0 && react_1.default.createElement("label", { className: labelCls }, "Ownership %"),
|
|
129
|
+
react_1.default.createElement(react_hook_form_1.Controller, { name: `partners.${idx}.ownershipPct`, control: control, render: ({ field: f }) => (react_1.default.createElement("div", { className: "relative" },
|
|
130
|
+
react_1.default.createElement("input", Object.assign({}, f, { type: "number", min: 0, max: 100, placeholder: "0", className: `${inputCls} pr-6`, onChange: (e) => f.onChange(Number(e.target.value) || 0) })),
|
|
131
|
+
react_1.default.createElement("span", { className: "absolute right-2.5 top-1/2 -translate-y-1/2 text-tax-axis-text-3 text-[13px]" }, "%"))) })),
|
|
132
|
+
react_1.default.createElement("div", { className: "w-[130px] shrink-0" },
|
|
133
|
+
idx === 0 && react_1.default.createElement("label", { className: labelCls }, "Type"),
|
|
134
|
+
react_1.default.createElement(react_hook_form_1.Controller, { name: `partners.${idx}.partnerType`, control: control, render: ({ field: f }) => (react_1.default.createElement("div", { className: "relative" },
|
|
135
|
+
react_1.default.createElement("select", Object.assign({}, f, { className: selectCls }),
|
|
136
|
+
react_1.default.createElement("option", { value: "general", className: "bg-tax-axis-surface-2" }, "General"),
|
|
137
|
+
react_1.default.createElement("option", { value: "limited", className: "bg-tax-axis-surface-2" }, "Limited")),
|
|
138
|
+
react_1.default.createElement(Chevron, null))) })),
|
|
139
|
+
fields.length > 1 && (react_1.default.createElement("button", { type: "button", onClick: () => remove(idx), className: "w-7 h-[38px] shrink-0 flex items-center justify-center text-tax-axis-text-4 hover:text-tax-axis-red transition-colors", title: "Remove partner" },
|
|
140
|
+
react_1.default.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none" },
|
|
141
|
+
react_1.default.createElement("path", { d: "M2 2l8 8M10 2l-8 8", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })))))))),
|
|
142
|
+
react_1.default.createElement("div", { className: "flex items-center justify-between mt-2 px-1" },
|
|
143
|
+
react_1.default.createElement("button", { type: "button", onClick: () => append({ name: "", ownershipPct: 0, partnerType: "general" }), className: "text-[11px] text-tax-axis-teal-light hover:text-white transition-colors font-tax-axis-body" }, "+ Add Partner"),
|
|
144
|
+
react_1.default.createElement("div", { className: `text-[11px] font-tax-axis-body ${pctValid ? "text-green-400" : "text-tax-axis-red"}` },
|
|
145
|
+
"Total: ",
|
|
146
|
+
totalPct,
|
|
147
|
+
"%",
|
|
148
|
+
!pctValid && " — must equal 100%")))),
|
|
105
149
|
react_1.default.createElement("div", { className: subHeaderCls }, "Financial Data"),
|
|
106
150
|
react_1.default.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 mb-2.5" },
|
|
107
151
|
react_1.default.createElement("div", null,
|
|
@@ -110,8 +110,8 @@ function StrategyRadar({ profile }) {
|
|
|
110
110
|
// so [profile] as a dep would never re-fire the memo on field changes
|
|
111
111
|
const profileKey = JSON.stringify(profile);
|
|
112
112
|
const computed = (0, react_1.useMemo)(() => (0, compute_1.computeAllStrategies)(safeProfile), [profileKey]);
|
|
113
|
-
const fedRate =
|
|
114
|
-
const stateRate = parseFloat(profile.stateRate || "
|
|
113
|
+
const fedRate = parseFloat((profile.federalRate || "24").replace("%", "")) / 100 || 0.24;
|
|
114
|
+
const stateRate = parseFloat(profile.stateRate || "0") / 100;
|
|
115
115
|
const netIncome = parseInt((profile.netIncome || "0").replace(/,/g, "")) || Math.round(rev * 0.3);
|
|
116
116
|
let loSum = eligibleStrategies.reduce((a, s) => { var _a, _b; return a + ((_b = (_a = computed.get(s.rank)) === null || _a === void 0 ? void 0 : _a.lo) !== null && _b !== void 0 ? _b : s.lo); }, 0);
|
|
117
117
|
let hiSum = eligibleStrategies.reduce((a, s) => { var _a, _b; return a + ((_b = (_a = computed.get(s.rank)) === null || _a === void 0 ? void 0 : _a.hi) !== null && _b !== void 0 ? _b : s.hi); }, 0);
|
|
@@ -17,6 +17,23 @@ export declare const intakeSchema: Yup.ObjectSchema<import("yup/lib/object").Ass
|
|
|
17
17
|
ownsRealEstate: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
18
18
|
itemizesDeductions: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
19
19
|
singleOwner: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
20
|
+
partners: import("yup/lib/array").RequiredArraySchema<Yup.ObjectSchema<import("yup/lib/object").Assign<import("yup/lib/object").ObjectShape, {
|
|
21
|
+
name: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
22
|
+
ownershipPct: Yup.NumberSchema<number, import("yup/lib/types").AnyObject, number>;
|
|
23
|
+
partnerType: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
24
|
+
}>, import("yup/lib/object").AnyObject, import("yup/lib/object").TypeOfShape<import("yup/lib/object").Assign<import("yup/lib/object").ObjectShape, {
|
|
25
|
+
name: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
26
|
+
ownershipPct: Yup.NumberSchema<number, import("yup/lib/types").AnyObject, number>;
|
|
27
|
+
partnerType: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
28
|
+
}>>, import("yup/lib/object").AssertsShape<import("yup/lib/object").Assign<import("yup/lib/object").ObjectShape, {
|
|
29
|
+
name: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
30
|
+
ownershipPct: Yup.NumberSchema<number, import("yup/lib/types").AnyObject, number>;
|
|
31
|
+
partnerType: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
32
|
+
}>>>, import("yup/lib/types").AnyObject, import("yup/lib/object").TypeOfShape<import("yup/lib/object").Assign<import("yup/lib/object").ObjectShape, {
|
|
33
|
+
name: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
34
|
+
ownershipPct: Yup.NumberSchema<number, import("yup/lib/types").AnyObject, number>;
|
|
35
|
+
partnerType: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
36
|
+
}>>[] | undefined>;
|
|
20
37
|
equipmentPurchased: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
21
38
|
realEstateValue: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
22
39
|
capitalGains: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
@@ -49,6 +66,23 @@ export declare const intakeSchema: Yup.ObjectSchema<import("yup/lib/object").Ass
|
|
|
49
66
|
ownsRealEstate: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
50
67
|
itemizesDeductions: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
51
68
|
singleOwner: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
69
|
+
partners: import("yup/lib/array").RequiredArraySchema<Yup.ObjectSchema<import("yup/lib/object").Assign<import("yup/lib/object").ObjectShape, {
|
|
70
|
+
name: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
71
|
+
ownershipPct: Yup.NumberSchema<number, import("yup/lib/types").AnyObject, number>;
|
|
72
|
+
partnerType: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
73
|
+
}>, import("yup/lib/object").AnyObject, import("yup/lib/object").TypeOfShape<import("yup/lib/object").Assign<import("yup/lib/object").ObjectShape, {
|
|
74
|
+
name: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
75
|
+
ownershipPct: Yup.NumberSchema<number, import("yup/lib/types").AnyObject, number>;
|
|
76
|
+
partnerType: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
77
|
+
}>>, import("yup/lib/object").AssertsShape<import("yup/lib/object").Assign<import("yup/lib/object").ObjectShape, {
|
|
78
|
+
name: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
79
|
+
ownershipPct: Yup.NumberSchema<number, import("yup/lib/types").AnyObject, number>;
|
|
80
|
+
partnerType: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
81
|
+
}>>>, import("yup/lib/types").AnyObject, import("yup/lib/object").TypeOfShape<import("yup/lib/object").Assign<import("yup/lib/object").ObjectShape, {
|
|
82
|
+
name: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
83
|
+
ownershipPct: Yup.NumberSchema<number, import("yup/lib/types").AnyObject, number>;
|
|
84
|
+
partnerType: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
85
|
+
}>>[] | undefined>;
|
|
52
86
|
equipmentPurchased: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
53
87
|
realEstateValue: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
54
88
|
capitalGains: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
@@ -81,6 +115,23 @@ export declare const intakeSchema: Yup.ObjectSchema<import("yup/lib/object").Ass
|
|
|
81
115
|
ownsRealEstate: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
82
116
|
itemizesDeductions: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
83
117
|
singleOwner: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
118
|
+
partners: import("yup/lib/array").RequiredArraySchema<Yup.ObjectSchema<import("yup/lib/object").Assign<import("yup/lib/object").ObjectShape, {
|
|
119
|
+
name: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
120
|
+
ownershipPct: Yup.NumberSchema<number, import("yup/lib/types").AnyObject, number>;
|
|
121
|
+
partnerType: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
122
|
+
}>, import("yup/lib/object").AnyObject, import("yup/lib/object").TypeOfShape<import("yup/lib/object").Assign<import("yup/lib/object").ObjectShape, {
|
|
123
|
+
name: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
124
|
+
ownershipPct: Yup.NumberSchema<number, import("yup/lib/types").AnyObject, number>;
|
|
125
|
+
partnerType: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
126
|
+
}>>, import("yup/lib/object").AssertsShape<import("yup/lib/object").Assign<import("yup/lib/object").ObjectShape, {
|
|
127
|
+
name: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
128
|
+
ownershipPct: Yup.NumberSchema<number, import("yup/lib/types").AnyObject, number>;
|
|
129
|
+
partnerType: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
130
|
+
}>>>, import("yup/lib/types").AnyObject, import("yup/lib/object").TypeOfShape<import("yup/lib/object").Assign<import("yup/lib/object").ObjectShape, {
|
|
131
|
+
name: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
132
|
+
ownershipPct: Yup.NumberSchema<number, import("yup/lib/types").AnyObject, number>;
|
|
133
|
+
partnerType: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
134
|
+
}>>[] | undefined>;
|
|
84
135
|
equipmentPurchased: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
85
136
|
realEstateValue: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
86
137
|
capitalGains: Yup.StringSchema<string, import("yup/lib/types").AnyObject, string>;
|
|
@@ -42,6 +42,11 @@ exports.intakeSchema = Yup.object().shape({
|
|
|
42
42
|
ownsRealEstate: Yup.string().ensure(),
|
|
43
43
|
itemizesDeductions: Yup.string().ensure(),
|
|
44
44
|
singleOwner: Yup.string().ensure(),
|
|
45
|
+
partners: Yup.array().of(Yup.object().shape({
|
|
46
|
+
name: Yup.string().ensure(),
|
|
47
|
+
ownershipPct: Yup.number().min(0).max(100).default(0),
|
|
48
|
+
partnerType: Yup.string().oneOf(["general", "limited"]).default("general"),
|
|
49
|
+
})).ensure(),
|
|
45
50
|
equipmentPurchased: Yup.string().ensure(),
|
|
46
51
|
realEstateValue: Yup.string().ensure(),
|
|
47
52
|
capitalGains: Yup.string().ensure(),
|
|
@@ -58,36 +63,79 @@ exports.intakeSchema = Yup.object().shape({
|
|
|
58
63
|
familyEmployed: Yup.string().ensure(),
|
|
59
64
|
period: Yup.string().ensure(),
|
|
60
65
|
});
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
66
|
+
/* ── Blackridge Construction Partners, LP — Test Fixture ──
|
|
67
|
+
* Swap _BLACKRIDGE_FIXTURE for _EMPTY_DEFAULTS below to revert.
|
|
68
|
+
*/
|
|
69
|
+
const _EMPTY_DEFAULTS = {
|
|
70
|
+
bizName: "",
|
|
71
|
+
cpaName: "",
|
|
64
72
|
entity: "C-Corporation",
|
|
65
|
-
industry: "
|
|
66
|
-
revenue: "
|
|
67
|
-
netIncome: "
|
|
68
|
-
ownerComp: "
|
|
69
|
-
employees: "
|
|
70
|
-
year: "
|
|
71
|
-
states: [
|
|
73
|
+
industry: "Professional Services",
|
|
74
|
+
revenue: "",
|
|
75
|
+
netIncome: "",
|
|
76
|
+
ownerComp: "",
|
|
77
|
+
employees: "",
|
|
78
|
+
year: "2026",
|
|
79
|
+
states: [],
|
|
72
80
|
filingStatus: "MFJ",
|
|
73
|
-
age: "
|
|
81
|
+
age: "",
|
|
74
82
|
sstb: "No",
|
|
75
83
|
ownsRealEstate: "No",
|
|
76
84
|
itemizesDeductions: "No",
|
|
77
|
-
singleOwner: "
|
|
78
|
-
|
|
85
|
+
singleOwner: "Yes",
|
|
86
|
+
partners: [],
|
|
87
|
+
equipmentPurchased: "0",
|
|
79
88
|
realEstateValue: "0",
|
|
80
89
|
capitalGains: "0",
|
|
81
|
-
federalRate: "
|
|
82
|
-
stateRate: "
|
|
90
|
+
federalRate: "24%",
|
|
91
|
+
stateRate: "",
|
|
83
92
|
taxDataYears: "1 year",
|
|
84
93
|
riskTolerance: "3",
|
|
85
94
|
overtimePremium: "0",
|
|
86
95
|
tipIncomePct: "0",
|
|
87
96
|
retirementContributions: "0",
|
|
88
|
-
hdhpEnrolled: "
|
|
97
|
+
hdhpEnrolled: "No",
|
|
89
98
|
hsaContributions: "0",
|
|
90
99
|
wotcHires: "No",
|
|
91
100
|
familyEmployed: "No",
|
|
92
101
|
period: "YTD",
|
|
93
102
|
};
|
|
103
|
+
const _BLACKRIDGE_FIXTURE = {
|
|
104
|
+
bizName: "Blackridge Construction Partners, LP",
|
|
105
|
+
cpaName: "Amar",
|
|
106
|
+
entity: "Partnership",
|
|
107
|
+
industry: "Construction",
|
|
108
|
+
revenue: "4800000",
|
|
109
|
+
netIncome: "720000",
|
|
110
|
+
ownerComp: "412000",
|
|
111
|
+
employees: "28",
|
|
112
|
+
year: "2023",
|
|
113
|
+
states: ["TX", "CA"],
|
|
114
|
+
filingStatus: "MFJ",
|
|
115
|
+
age: "52",
|
|
116
|
+
sstb: "No",
|
|
117
|
+
ownsRealEstate: "Yes — Commercial",
|
|
118
|
+
itemizesDeductions: "No",
|
|
119
|
+
singleOwner: "No",
|
|
120
|
+
partners: [
|
|
121
|
+
{ name: "Marcus D. Blackridge", ownershipPct: 50, partnerType: "general" },
|
|
122
|
+
{ name: "David L. Chen", ownershipPct: 30, partnerType: "general" },
|
|
123
|
+
{ name: "Sarah A. Okonkwo", ownershipPct: 20, partnerType: "general" },
|
|
124
|
+
],
|
|
125
|
+
equipmentPurchased: "193000",
|
|
126
|
+
realEstateValue: "560000",
|
|
127
|
+
capitalGains: "0",
|
|
128
|
+
federalRate: "32%",
|
|
129
|
+
stateRate: "0",
|
|
130
|
+
taxDataYears: "3 years",
|
|
131
|
+
riskTolerance: "3",
|
|
132
|
+
overtimePremium: "34000",
|
|
133
|
+
tipIncomePct: "0",
|
|
134
|
+
retirementContributions: "42000",
|
|
135
|
+
hdhpEnrolled: "Yes",
|
|
136
|
+
hsaContributions: "0",
|
|
137
|
+
wotcHires: "Yes",
|
|
138
|
+
familyEmployed: "No",
|
|
139
|
+
period: "Full Year",
|
|
140
|
+
};
|
|
141
|
+
exports.intakeDefaultValues = _BLACKRIDGE_FIXTURE;
|
|
@@ -30,7 +30,7 @@ function EngagementHeader({ profile, palette }) {
|
|
|
30
30
|
["Filing", filingDisplay],
|
|
31
31
|
["SSTB", profile.sstb || "No"],
|
|
32
32
|
["Fed Rate", fedRateDisplay],
|
|
33
|
-
["State Rate", (profile.stateRate || "
|
|
33
|
+
["State Rate", (profile.stateRate || "0") + "%"],
|
|
34
34
|
["Revenue", "$" + (rev || 0).toLocaleString()],
|
|
35
35
|
["Net Income", "$" + (0, compute_1.parseNum)(profile.netIncome).toLocaleString()],
|
|
36
36
|
["Owner Comp", "$" + (0, compute_1.parseNum)(profile.ownerComp).toLocaleString()],
|
|
@@ -2,9 +2,6 @@ import React from "react";
|
|
|
2
2
|
interface SampleAnalysisPreviewProps {
|
|
3
3
|
sectionNum: string;
|
|
4
4
|
eligibleCount: number;
|
|
5
|
-
fedRatePct?: number;
|
|
6
|
-
stateRatePct?: number;
|
|
7
|
-
stateCode?: string;
|
|
8
5
|
}
|
|
9
|
-
export declare function SampleAnalysisPreview({ sectionNum, eligibleCount
|
|
6
|
+
export declare function SampleAnalysisPreview({ sectionNum, eligibleCount }: SampleAnalysisPreviewProps): React.JSX.Element;
|
|
10
7
|
export {};
|
|
@@ -26,9 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.SampleAnalysisPreview = SampleAnalysisPreview;
|
|
27
27
|
const react_1 = __importStar(require("react"));
|
|
28
28
|
const theme_1 = require("./theme");
|
|
29
|
-
function SampleAnalysisPreview({ sectionNum, eligibleCount
|
|
30
|
-
const fedRateDecimal = (fedRatePct / 100).toFixed(2);
|
|
31
|
-
const stateRateDecimal = (stateRatePct / 100).toFixed(4);
|
|
29
|
+
function SampleAnalysisPreview({ sectionNum, eligibleCount }) {
|
|
32
30
|
return (react_1.default.createElement("div", { style: { marginBottom: 24 } },
|
|
33
31
|
react_1.default.createElement("div", { style: { display: "flex", alignItems: "baseline", gap: 10, marginBottom: 6 } },
|
|
34
32
|
react_1.default.createElement("span", { style: { fontSize: 11, fontWeight: 700, color: theme_1.T.accent, fontFamily: theme_1.T.body } }, sectionNum),
|
|
@@ -64,12 +62,12 @@ function SampleAnalysisPreview({ sectionNum, eligibleCount, fedRatePct = 24, sta
|
|
|
64
62
|
react_1.default.createElement("span", { style: { color: theme_1.T.orange, fontWeight: 700 } }, "\u00B7 illustrative")),
|
|
65
63
|
react_1.default.createElement("div", { style: { display: "grid", gridTemplateColumns: "1fr auto", gap: "6px 16px", fontSize: 11, fontFamily: theme_1.T.mono, marginBottom: 6 } }, [
|
|
66
64
|
["state_income_attributable_to_owner", "$1,750,000"],
|
|
67
|
-
["state_rate",
|
|
65
|
+
["state_rate", "0.0495 (IL)"],
|
|
68
66
|
["filing_status", "mfj"],
|
|
69
67
|
["MAGI_PROXY: net_income", "$1,750,000"],
|
|
70
68
|
["EFFECTIVE_SALT_CAP", "$0 (fully phased out by MFJ income)"],
|
|
71
|
-
["federal_marginal_rate",
|
|
72
|
-
["state_credit_rate",
|
|
69
|
+
["federal_marginal_rate", "0.24"],
|
|
70
|
+
["state_credit_rate", "1.00 (IL full credit)"],
|
|
73
71
|
["pte_tax_paid", "$86,625"],
|
|
74
72
|
].map(([k, v]) => (react_1.default.createElement(react_1.Fragment, { key: k },
|
|
75
73
|
react_1.default.createElement("span", { style: { color: theme_1.T.text3 } }, k),
|
|
@@ -81,8 +79,8 @@ function SampleAnalysisPreview({ sectionNum, eligibleCount, fedRatePct = 24, sta
|
|
|
81
79
|
{ doc: "Form 1120-S", line: "Line 12 \u00B7 Taxes and licenses", field: "pte_tax_paid" },
|
|
82
80
|
{ doc: "Schedule K-1", line: "Box 16, Code A \u00B7 State tax credit info", field: "state_credit_pass_through" },
|
|
83
81
|
{ doc: "Form 1040 Sch A", line: "Line 5a \u00B7 State and local income tax", field: "salt_paid" },
|
|
84
|
-
{ doc:
|
|
85
|
-
{ doc: "Parser-injected", line:
|
|
82
|
+
{ doc: "State Return (IL-1120-ST)", line: "PTE election line items", field: "pte_election_status" },
|
|
83
|
+
{ doc: "Parser-injected", line: "state_pte_lookup[IL]", field: "state_credit_rate, pte_deadline" },
|
|
86
84
|
].map((s, idx) => (react_1.default.createElement("div", { key: idx, style: { display: "grid", gridTemplateColumns: "1.1fr 1.4fr 1fr", gap: 12, fontSize: 11, fontFamily: theme_1.T.body, padding: "7px 12px", background: theme_1.T.surface2, border: `1px solid ${theme_1.T.border}`, borderRadius: 6 } },
|
|
87
85
|
react_1.default.createElement("span", { style: { color: theme_1.T.text, fontWeight: 600 } }, s.doc),
|
|
88
86
|
react_1.default.createElement("span", { style: { color: theme_1.T.text2, fontFamily: theme_1.T.mono, fontSize: 10 } }, s.line),
|
|
@@ -104,20 +102,13 @@ function SampleAnalysisPreview({ sectionNum, eligibleCount, fedRatePct = 24, sta
|
|
|
104
102
|
react_1.default.createElement("div", { style: { fontSize: 11, color: theme_1.T.text2, fontFamily: theme_1.T.mono, lineHeight: 1.6 } },
|
|
105
103
|
"State PTE election form",
|
|
106
104
|
react_1.default.createElement("br", null),
|
|
107
|
-
"(",
|
|
108
|
-
stateCode,
|
|
109
|
-
": Schedule B, Form ",
|
|
110
|
-
stateCode,
|
|
111
|
-
"-1120-ST)",
|
|
105
|
+
"(IL: Schedule B, Form IL-1120-ST)",
|
|
112
106
|
react_1.default.createElement("br", null),
|
|
113
107
|
"Updated Schedule K-1 (Box 13)"))),
|
|
114
108
|
react_1.default.createElement("div", { style: { marginTop: 14, paddingTop: 14, borderTop: `1px solid ${theme_1.T.border}`, display: "flex", justifyContent: "space-between", alignItems: "center", gap: 14 } },
|
|
115
109
|
react_1.default.createElement("div", null,
|
|
116
110
|
react_1.default.createElement("div", { style: { fontSize: 9, fontWeight: 700, color: theme_1.T.orange, textTransform: "uppercase", letterSpacing: "0.12em", fontFamily: theme_1.T.body, marginBottom: 3 } }, "deadline_flag"),
|
|
117
|
-
react_1.default.createElement("div", { style: { fontSize: 11, color: theme_1.T.text2, fontFamily: theme_1.T.body } },
|
|
118
|
-
"Per state_pte_lookup \u2014 ",
|
|
119
|
-
stateCode,
|
|
120
|
-
": file with original return")),
|
|
111
|
+
react_1.default.createElement("div", { style: { fontSize: 11, color: theme_1.T.text2, fontFamily: theme_1.T.body } }, "Per state_pte_lookup \u2014 IL: file with original return")),
|
|
121
112
|
react_1.default.createElement("span", { style: { fontSize: 9, fontWeight: 700, padding: "4px 9px", background: theme_1.T.surface2, border: `1px solid ${theme_1.T.border}`, borderRadius: 4, color: theme_1.T.text3, fontFamily: theme_1.T.mono, letterSpacing: 0.6, textTransform: "uppercase" } }, "algorithm_version V9.0")))),
|
|
122
113
|
react_1.default.createElement("div", { style: { marginTop: 14, padding: "14px 18px", background: `linear-gradient(135deg,${theme_1.T.accentBg} 0%,rgba(36,131,132,0.04) 100%)`, border: `1px solid ${theme_1.T.accent}`, borderRadius: 10, display: "flex", alignItems: "center", gap: 14 } },
|
|
123
114
|
react_1.default.createElement("div", { style: { flex: 1, fontSize: 13, color: theme_1.T.text, fontFamily: theme_1.T.body, lineHeight: 1.55 } },
|
|
@@ -36,7 +36,7 @@ const ProspectDocuments_1 = require("./ProspectDocuments");
|
|
|
36
36
|
const ProspectNextSteps_1 = require("./ProspectNextSteps");
|
|
37
37
|
const ProspectPrintView_1 = require("./ProspectPrintView");
|
|
38
38
|
function TaxAxisProspectReport({ profile, backendComputePayload, outputPayload, onUpgrade, onPresent, onReset, }) {
|
|
39
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
39
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
40
40
|
const bizName = profile.bizName || "Client";
|
|
41
41
|
const [confirmReset, setConfirmReset] = (0, react_1.useState)(false);
|
|
42
42
|
const [printMode, setPrintMode] = (0, react_1.useState)(false);
|
|
@@ -47,26 +47,29 @@ function TaxAxisProspectReport({ profile, backendComputePayload, outputPayload,
|
|
|
47
47
|
const top3 = (0, react_1.useMemo)(() => [...eligible].sort((a, b) => b.score - a.score).slice(0, 3), [eligible]);
|
|
48
48
|
const remaining = eligible.length - top3.length;
|
|
49
49
|
const remainingNames = eligible.filter(s => !top3.includes(s)).slice(0, 4).map(s => s.name);
|
|
50
|
-
// ═══
|
|
50
|
+
// ═══ SAVINGS RANGE — backend-authoritative when available ═══
|
|
51
51
|
const computed = (0, react_1.useMemo)(() => (0, compute_1.computeAllStrategies)(profile), [profile]);
|
|
52
|
-
|
|
52
|
+
let displayLo = backendComputePayload
|
|
53
53
|
? Math.round(backendComputePayload.savingsLo / 1000)
|
|
54
54
|
: Math.round(eligible.reduce((a, s) => { var _a, _b; return a + ((_b = (_a = computed.get(s.rank)) === null || _a === void 0 ? void 0 : _a.lo) !== null && _b !== void 0 ? _b : s.lo); }, 0) / 1000);
|
|
55
|
-
|
|
55
|
+
let displayHi = backendComputePayload
|
|
56
56
|
? Math.round(backendComputePayload.savingsHi / 1000)
|
|
57
57
|
: Math.round(eligible.reduce((a, s) => { var _a, _b; return a + ((_b = (_a = computed.get(s.rank)) === null || _a === void 0 ? void 0 : _a.hi) !== null && _b !== void 0 ? _b : s.hi); }, 0) / 1000);
|
|
58
58
|
// ═══ GAP BLOCK — backend-authoritative when available ═══
|
|
59
|
-
const fedRatePct = (_a = backendComputePayload === null || backendComputePayload === void 0 ? void 0 : backendComputePayload.gapBlock.fedRatePct) !== null && _a !== void 0 ? _a : (
|
|
60
|
-
const stateRatePct = (_b = backendComputePayload === null || backendComputePayload === void 0 ? void 0 : backendComputePayload.gapBlock.stateRatePct) !== null && _b !== void 0 ? _b : (parseFloat(profile.stateRate || "
|
|
59
|
+
const fedRatePct = (_a = backendComputePayload === null || backendComputePayload === void 0 ? void 0 : backendComputePayload.gapBlock.fedRatePct) !== null && _a !== void 0 ? _a : (parseFloat((profile.federalRate || "24").replace("%", "")) || 24);
|
|
60
|
+
const stateRatePct = (_b = backendComputePayload === null || backendComputePayload === void 0 ? void 0 : backendComputePayload.gapBlock.stateRatePct) !== null && _b !== void 0 ? _b : (parseFloat(profile.stateRate || "0"));
|
|
61
61
|
const currentTax = (_c = backendComputePayload === null || backendComputePayload === void 0 ? void 0 : backendComputePayload.gapBlock.currentTax) !== null && _c !== void 0 ? _c : Math.round(((0, compute_1.parseNum)(profile.netIncome) || Math.round((0, compute_1.parseNum)(profile.revenue) * 0.20))
|
|
62
62
|
* (fedRatePct + stateRatePct) / 100);
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
63
|
+
// Cap savings range: hi ≤ currentTax, lo ≤ 60% of hi, K-rounding safety
|
|
64
|
+
if (!backendComputePayload) {
|
|
65
|
+
const currentTaxK = Math.round(currentTax / 1000);
|
|
66
|
+
if (displayHi > currentTaxK)
|
|
67
|
+
displayHi = currentTaxK;
|
|
68
|
+
const loFloor = Math.round(displayHi * 0.60);
|
|
69
|
+
if (displayLo > loFloor)
|
|
70
|
+
displayLo = loFloor;
|
|
71
|
+
if (displayLo >= displayHi && displayHi > 1)
|
|
72
|
+
displayLo = displayHi - 1;
|
|
70
73
|
}
|
|
71
74
|
const realizedSavings = (_d = backendComputePayload === null || backendComputePayload === void 0 ? void 0 : backendComputePayload.gapBlock.realizedSavings) !== null && _d !== void 0 ? _d : Math.min(Math.round((displayLo + displayHi) / 2 * 1000 * 0.325), Math.round(currentTax * 0.6));
|
|
72
75
|
const optimizedTax = (_e = backendComputePayload === null || backendComputePayload === void 0 ? void 0 : backendComputePayload.gapBlock.optimizedTax) !== null && _e !== void 0 ? _e : (currentTax - realizedSavings);
|
|
@@ -176,7 +179,7 @@ function TaxAxisProspectReport({ profile, backendComputePayload, outputPayload,
|
|
|
176
179
|
react_1.default.createElement("div", { style: { fontSize: 13, color: theme_1.T.text2, fontFamily: theme_1.T.body, lineHeight: 1.7, marginBottom: 10 } }, (outputPayload === null || outputPayload === void 0 ? void 0 : outputPayload.additionalStrategiesBlurb)
|
|
177
180
|
|| `Including: ${remainingNames.join(", ")}${remaining > 4 ? " and more" : ""}`),
|
|
178
181
|
react_1.default.createElement("div", { style: { fontSize: 12, color: theme_1.T.text3, fontFamily: theme_1.T.body, lineHeight: 1.6, borderLeft: `3px solid ${theme_1.T.accent}`, paddingLeft: 12 } }, "Full analysis with documents unlocks specific savings estimates for every eligible strategy.")))),
|
|
179
|
-
react_1.default.createElement(SampleAnalysisPreview_1.SampleAnalysisPreview, { sectionNum: sectionNums.sample, eligibleCount: eligible.length
|
|
182
|
+
react_1.default.createElement(SampleAnalysisPreview_1.SampleAnalysisPreview, { sectionNum: sectionNums.sample, eligibleCount: eligible.length }),
|
|
180
183
|
react_1.default.createElement(ProspectDocuments_1.ProspectDocuments, { sectionNum: sectionNums.documents, requiredDocs: requiredDocs, recommendedDocs: recommendedDocs, conditionalDocs: conditionalDocs }),
|
|
181
184
|
react_1.default.createElement(ProspectNextSteps_1.ProspectNextSteps, { sectionNum: sectionNums.nextSteps, bizName: bizName, onUpgrade: onUpgrade, onPresent: onPresent, onPrint: handlePrint, onReset: onReset, confirmReset: confirmReset, onConfirmResetChange: setConfirmReset })));
|
|
182
185
|
}
|