@paro.io/expert-shared-components 1.14.75 → 1.14.77
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 +18 -3
- package/lib/tax-axis/components/clientReport/ExecutiveSummary.js +2 -2
- package/lib/tax-axis/components/documents/DocumentReviewModal.d.ts +2 -1
- package/lib/tax-axis/components/documents/DocumentReviewModal.js +4 -3
- package/lib/tax-axis/components/documents/TaxAxisDocuments.js +18 -6
- package/lib/tax-axis/components/intake/RefineAnalysisSection.js +44 -0
- package/lib/tax-axis/components/intake/StrategyRadar.js +1 -1
- package/lib/tax-axis/components/intake/intakeSchema.d.ts +51 -0
- package/lib/tax-axis/components/intake/intakeSchema.js +49 -1
- package/lib/tax-axis/components/preparerWorkpaper/EngagementHeader.js +1 -1
- package/lib/tax-axis/components/prospectReport/TaxAxisProspectReport.js +14 -3
- package/lib/tax-axis/lib/compute/index.js +12 -4
- package/lib/tax-axis/lib/documentFieldCatalog.js +64 -15
- 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);
|
|
@@ -293,7 +306,8 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
293
306
|
updateSessionId(null);
|
|
294
307
|
}, [updateSessionId]);
|
|
295
308
|
const handleProspect = (nextProfile) => __awaiter(void 0, void 0, void 0, function* () {
|
|
296
|
-
|
|
309
|
+
const enriched = enrichWithAllocations(nextProfile);
|
|
310
|
+
setProfile(enriched);
|
|
297
311
|
setIsProspectFlow(true);
|
|
298
312
|
setProspectData(null);
|
|
299
313
|
setProspectLoading(true);
|
|
@@ -301,7 +315,7 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
301
315
|
try {
|
|
302
316
|
if (taxAxisApi.generateProspectReport) {
|
|
303
317
|
const result = yield taxAxisApi.generateProspectReport({
|
|
304
|
-
clientProfile:
|
|
318
|
+
clientProfile: enriched,
|
|
305
319
|
});
|
|
306
320
|
setProspectData({
|
|
307
321
|
computePayload: result.computePayload,
|
|
@@ -317,7 +331,8 @@ const TaxAxisShell = ({ taxAxisApi, userContext = 'expert', initialSessionId, in
|
|
|
317
331
|
}
|
|
318
332
|
});
|
|
319
333
|
const handleFullAnalysis = (0, react_1.useCallback)((nextProfile) => __awaiter(void 0, void 0, void 0, function* () {
|
|
320
|
-
|
|
334
|
+
const enriched = enrichWithAllocations(nextProfile);
|
|
335
|
+
setProfile(enriched);
|
|
321
336
|
setIsProspectFlow(false);
|
|
322
337
|
setError(null);
|
|
323
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)
|
|
@@ -6,8 +6,9 @@ export interface DocumentReviewModalProps {
|
|
|
6
6
|
documentName: string;
|
|
7
7
|
fileName: string;
|
|
8
8
|
jobId: string;
|
|
9
|
+
documentType?: string;
|
|
9
10
|
parsedData?: Record<string, unknown> | null;
|
|
10
11
|
onSaveReviewedData?: (fields: Record<string, string>) => Promise<void>;
|
|
11
12
|
onClose: () => void;
|
|
12
13
|
}
|
|
13
|
-
export declare function DocumentReviewModal({ documentId, documentName, fileName, jobId: _jobId, parsedData, onSaveReviewedData, onClose, }: DocumentReviewModalProps): React.JSX.Element;
|
|
14
|
+
export declare function DocumentReviewModal({ documentId, documentName, fileName, jobId: _jobId, documentType: documentTypeProp, parsedData, onSaveReviewedData, onClose, }: DocumentReviewModalProps): React.JSX.Element;
|
|
@@ -138,7 +138,7 @@ function getTotalFieldCount(sections) {
|
|
|
138
138
|
return sections.reduce((sum, s) => sum + s.fields.length, 0);
|
|
139
139
|
}
|
|
140
140
|
// ── Component ──
|
|
141
|
-
function DocumentReviewModal({ documentId, documentName, fileName, jobId: _jobId, parsedData, onSaveReviewedData, onClose, }) {
|
|
141
|
+
function DocumentReviewModal({ documentId, documentName, fileName, jobId: _jobId, documentType: documentTypeProp, parsedData, onSaveReviewedData, onClose, }) {
|
|
142
142
|
const [loading, setLoading] = (0, react_1.useState)(true);
|
|
143
143
|
const [sections, setSections] = (0, react_1.useState)([]);
|
|
144
144
|
const [saveStatus, setSaveStatus] = (0, react_1.useState)("idle");
|
|
@@ -147,7 +147,8 @@ function DocumentReviewModal({ documentId, documentName, fileName, jobId: _jobId
|
|
|
147
147
|
var _a;
|
|
148
148
|
if (parsedData && typeof parsedData === "object") {
|
|
149
149
|
const fields = ((_a = parsedData.fields) !== null && _a !== void 0 ? _a : parsedData);
|
|
150
|
-
|
|
150
|
+
// Prefer explicit prop, then parsedData.documentType, never fall back to documentId (UUID)
|
|
151
|
+
const documentType = documentTypeProp || parsedData.documentType || "";
|
|
151
152
|
setSections(buildSectionsFromCatalog(documentType, fields));
|
|
152
153
|
setLoading(false);
|
|
153
154
|
return;
|
|
@@ -158,7 +159,7 @@ function DocumentReviewModal({ documentId, documentName, fileName, jobId: _jobId
|
|
|
158
159
|
setLoading(false);
|
|
159
160
|
}, 400);
|
|
160
161
|
return () => clearTimeout(t);
|
|
161
|
-
}, [documentId, parsedData]);
|
|
162
|
+
}, [documentId, documentTypeProp, parsedData]);
|
|
162
163
|
const handleFieldChange = (0, react_1.useCallback)((sectionIdx, fieldIdx, newValue) => {
|
|
163
164
|
setSections((prev) => prev.map((sec, si) => si === sectionIdx
|
|
164
165
|
? Object.assign(Object.assign({}, sec), { fields: sec.fields.map((f, fi) => fi === fieldIdx ? Object.assign(Object.assign({}, f), { value: newValue }) : f) }) : sec));
|
|
@@ -147,6 +147,7 @@ function TaxAxisDocuments({ profile, entityType, onContinue, onBack, onUploadDoc
|
|
|
147
147
|
if (!fetchUploadedDocuments)
|
|
148
148
|
return;
|
|
149
149
|
fetchUploadedDocuments().then((uploaded) => {
|
|
150
|
+
var _a;
|
|
150
151
|
if (!uploaded.length)
|
|
151
152
|
return;
|
|
152
153
|
const parsedByType = {};
|
|
@@ -171,14 +172,25 @@ function TaxAxisDocuments({ profile, entityType, onContinue, onBack, onUploadDoc
|
|
|
171
172
|
}));
|
|
172
173
|
// Populate document ID map in one batch
|
|
173
174
|
setUploadedDocIds((prev) => (Object.assign(Object.assign({}, prev), nextDocIds)));
|
|
174
|
-
// Populate review modal data
|
|
175
|
-
|
|
175
|
+
// Populate review modal data — sort newest-first so the most recent doc wins
|
|
176
|
+
// when multiple docs share the same documentType (e.g. two profit_loss years).
|
|
177
|
+
const uploadedSorted = [...uploaded].sort((a, b) => new Date(String(b.updatedAt || 0)).getTime() - new Date(String(a.updatedAt || 0)).getTime());
|
|
178
|
+
for (const doc of uploadedSorted) {
|
|
176
179
|
if (!doc.documentType)
|
|
177
180
|
continue;
|
|
178
|
-
if
|
|
179
|
-
|
|
181
|
+
// Only store parsedData if it has non-empty fields, and don't overwrite
|
|
182
|
+
// a richer entry already stored for this documentType.
|
|
183
|
+
const pData = doc.parsedData;
|
|
184
|
+
const pFields = pData ? ((_a = pData.fields) !== null && _a !== void 0 ? _a : pData) : null;
|
|
185
|
+
if (pFields && Object.keys(pFields).filter((k) => k !== '_line_items').length > 0) {
|
|
186
|
+
if (!(doc.documentType in parsedByType)) {
|
|
187
|
+
parsedByType[doc.documentType] = pData;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
180
190
|
if (doc.reviewedData && Object.keys(doc.reviewedData).length > 0) {
|
|
181
|
-
|
|
191
|
+
if (!(doc.documentType in reviewedByType)) {
|
|
192
|
+
reviewedByType[doc.documentType] = doc.reviewedData;
|
|
193
|
+
}
|
|
182
194
|
}
|
|
183
195
|
}
|
|
184
196
|
if (Object.keys(parsedByType).length > 0)
|
|
@@ -416,7 +428,7 @@ function TaxAxisDocuments({ profile, entityType, onContinue, onBack, onUploadDoc
|
|
|
416
428
|
: failedCount > 0
|
|
417
429
|
? `Continue (${failedCount} failed)`
|
|
418
430
|
: "Continue")))),
|
|
419
|
-
reviewDoc && (react_1.default.createElement(DocumentReviewModal_1.DocumentReviewModal, { documentId: reviewDoc.id, documentName: reviewDoc.name, fileName: reviewDoc.fileName || "", jobId: jobId, parsedData: reviewParsedData, onSaveReviewedData: onSaveReviewedField
|
|
431
|
+
reviewDoc && (react_1.default.createElement(DocumentReviewModal_1.DocumentReviewModal, { documentId: reviewDoc.id, documentName: reviewDoc.name, fileName: reviewDoc.fileName || "", jobId: jobId, documentType: reviewDoc.documentType || undefined, parsedData: reviewParsedData, onSaveReviewedData: onSaveReviewedField
|
|
420
432
|
? (fields) => __awaiter(this, void 0, void 0, function* () {
|
|
421
433
|
const docId = uploadedDocIds[docs.indexOf(reviewDoc)];
|
|
422
434
|
if (docId)
|
|
@@ -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,
|
|
@@ -111,7 +111,7 @@ function StrategyRadar({ profile }) {
|
|
|
111
111
|
const profileKey = JSON.stringify(profile);
|
|
112
112
|
const computed = (0, react_1.useMemo)(() => (0, compute_1.computeAllStrategies)(safeProfile), [profileKey]);
|
|
113
113
|
const fedRate = parseFloat((profile.federalRate || "24").replace("%", "")) / 100 || 0.24;
|
|
114
|
-
const stateRate = parseFloat(profile.stateRate || "
|
|
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,7 +63,10 @@ exports.intakeSchema = Yup.object().shape({
|
|
|
58
63
|
familyEmployed: Yup.string().ensure(),
|
|
59
64
|
period: Yup.string().ensure(),
|
|
60
65
|
});
|
|
61
|
-
|
|
66
|
+
/* ── Blackridge Construction Partners, LP — Test Fixture ──
|
|
67
|
+
* Swap _BLACKRIDGE_FIXTURE for _EMPTY_DEFAULTS below to revert.
|
|
68
|
+
*/
|
|
69
|
+
const _EMPTY_DEFAULTS = {
|
|
62
70
|
bizName: "",
|
|
63
71
|
cpaName: "",
|
|
64
72
|
entity: "C-Corporation",
|
|
@@ -75,6 +83,7 @@ exports.intakeDefaultValues = {
|
|
|
75
83
|
ownsRealEstate: "No",
|
|
76
84
|
itemizesDeductions: "No",
|
|
77
85
|
singleOwner: "Yes",
|
|
86
|
+
partners: [],
|
|
78
87
|
equipmentPurchased: "0",
|
|
79
88
|
realEstateValue: "0",
|
|
80
89
|
capitalGains: "0",
|
|
@@ -91,3 +100,42 @@ exports.intakeDefaultValues = {
|
|
|
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()],
|
|
@@ -49,17 +49,28 @@ function TaxAxisProspectReport({ profile, backendComputePayload, outputPayload,
|
|
|
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
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 || "
|
|
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
|
+
// 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;
|
|
73
|
+
}
|
|
63
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));
|
|
64
75
|
const optimizedTax = (_e = backendComputePayload === null || backendComputePayload === void 0 ? void 0 : backendComputePayload.gapBlock.optimizedTax) !== null && _e !== void 0 ? _e : (currentTax - realizedSavings);
|
|
65
76
|
const realizedPctOfCurrent = (_f = backendComputePayload === null || backendComputePayload === void 0 ? void 0 : backendComputePayload.gapBlock.realizedPctOfCurrent) !== null && _f !== void 0 ? _f : (currentTax > 0 ? Math.round((realizedSavings / currentTax) * 100) : 0);
|
|
@@ -63,7 +63,7 @@ function computeAllStrategies(profile) {
|
|
|
63
63
|
const hsaExisting = (0, exports.parseNum)(profile.hsaContributions);
|
|
64
64
|
const retirementExisting = (0, exports.parseNum)(profile.retirementContributions);
|
|
65
65
|
const fedRate = parseFloat((profile.federalRate || "24").replace("%", "")) / 100 || 0.24;
|
|
66
|
-
const stateRate = parseFloat(profile.stateRate || "
|
|
66
|
+
const stateRate = parseFloat(profile.stateRate || "0") / 100;
|
|
67
67
|
const combinedRate = fedRate + stateRate;
|
|
68
68
|
const seTaxRate = 0.153;
|
|
69
69
|
const sstb = profile.sstb || "No";
|
|
@@ -139,11 +139,19 @@ function computeAllStrategies(profile) {
|
|
|
139
139
|
}
|
|
140
140
|
/* #15 SALT/PTE Optimization */
|
|
141
141
|
{
|
|
142
|
-
|
|
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);
|
|
143
151
|
const pteSavings = Math.round(statesTaxPaid * 0.70);
|
|
144
152
|
results.set(15, { lo: Math.max(Math.round(pteSavings * 0.80), 0), hi: Math.max(Math.round(pteSavings * 1.10), 0),
|
|
145
|
-
sources: [{ doc: "Intake", line: "Net Income", value: `$${net.toLocaleString()}`, field: "Pass-through Income" }, { doc: "Intake", line: "State Rate", value: `${(
|
|
146
|
-
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" }] });
|
|
147
155
|
}
|
|
148
156
|
/* #22 Overtime Pay Deduction (OBBBA) */
|
|
149
157
|
if (overtime > 0) {
|
|
@@ -39,58 +39,107 @@ exports.DOCUMENT_FIELD_CATALOG = {
|
|
|
39
39
|
sections: [
|
|
40
40
|
{
|
|
41
41
|
head: "Revenue",
|
|
42
|
-
fields: ["total_revenue", "
|
|
42
|
+
fields: ["total_revenue", "cost_of_goods_sold", "gross_profit"],
|
|
43
43
|
},
|
|
44
44
|
{
|
|
45
45
|
head: "Operating Expenses",
|
|
46
|
-
fields: [
|
|
46
|
+
fields: [
|
|
47
|
+
"total_operating_expenses",
|
|
48
|
+
"salaries_wages_staff",
|
|
49
|
+
"rent_expense",
|
|
50
|
+
"depreciation_expense",
|
|
51
|
+
"amortization_expense",
|
|
52
|
+
"advertising_marketing",
|
|
53
|
+
"professional_fees",
|
|
54
|
+
"insurance_nonhealth",
|
|
55
|
+
"business_meals",
|
|
56
|
+
"other_expenses",
|
|
57
|
+
],
|
|
47
58
|
},
|
|
48
59
|
{
|
|
49
60
|
head: "Net Income",
|
|
50
|
-
fields: ["
|
|
61
|
+
fields: ["net_operating_income", "net_income"],
|
|
51
62
|
},
|
|
52
63
|
],
|
|
53
64
|
fields: {
|
|
54
65
|
total_revenue: { label: "Total Revenue" },
|
|
55
|
-
gross_revenue: { label: "Gross Revenue" },
|
|
56
66
|
cost_of_goods_sold: { label: "Cost of Goods Sold (COGS)" },
|
|
57
67
|
gross_profit: { label: "Gross Profit" },
|
|
58
|
-
|
|
59
|
-
|
|
68
|
+
total_operating_expenses: { label: "Total Operating Expenses" },
|
|
69
|
+
salaries_wages_staff: { label: "Salaries & Wages" },
|
|
60
70
|
rent_expense: { label: "Rent / Lease" },
|
|
61
|
-
|
|
71
|
+
depreciation_expense: { label: "Depreciation" },
|
|
72
|
+
amortization_expense: { label: "Amortization" },
|
|
73
|
+
advertising_marketing: { label: "Advertising & Marketing" },
|
|
74
|
+
professional_fees: { label: "Professional Fees" },
|
|
75
|
+
insurance_nonhealth: { label: "Insurance" },
|
|
76
|
+
business_meals: { label: "Meals & Entertainment" },
|
|
62
77
|
other_expenses: { label: "Other Expenses" },
|
|
78
|
+
net_operating_income: { label: "Net Operating Income" },
|
|
63
79
|
net_income: { label: "Net Income" },
|
|
64
|
-
net_margin: { label: "Net Profit Margin" },
|
|
65
80
|
},
|
|
66
81
|
},
|
|
67
82
|
balance_sheet: {
|
|
68
83
|
sections: [
|
|
69
84
|
{
|
|
70
85
|
head: "Assets",
|
|
71
|
-
fields: [
|
|
86
|
+
fields: [
|
|
87
|
+
"total_current_assets",
|
|
88
|
+
"total_assets",
|
|
89
|
+
"cash_and_equivalents",
|
|
90
|
+
"accounts_receivable",
|
|
91
|
+
"inventory",
|
|
92
|
+
"prepaid_expenses",
|
|
93
|
+
"property_equipment_net",
|
|
94
|
+
"accumulated_depreciation",
|
|
95
|
+
],
|
|
72
96
|
},
|
|
73
97
|
{
|
|
74
98
|
head: "Liabilities",
|
|
75
|
-
fields: [
|
|
99
|
+
fields: [
|
|
100
|
+
"total_current_liabilities",
|
|
101
|
+
"total_liabilities",
|
|
102
|
+
"accounts_payable",
|
|
103
|
+
"accrued_liabilities",
|
|
104
|
+
"deferred_revenue",
|
|
105
|
+
"short_term_debt",
|
|
106
|
+
"long_term_debt",
|
|
107
|
+
"total_liabilities_and_equity",
|
|
108
|
+
],
|
|
76
109
|
},
|
|
77
110
|
{
|
|
78
111
|
head: "Equity",
|
|
79
|
-
fields: [
|
|
112
|
+
fields: [
|
|
113
|
+
"total_equity",
|
|
114
|
+
"retained_earnings",
|
|
115
|
+
"owners_equity",
|
|
116
|
+
"common_stock_par_value",
|
|
117
|
+
"additional_paid_in_capital",
|
|
118
|
+
],
|
|
80
119
|
},
|
|
81
120
|
],
|
|
82
121
|
fields: {
|
|
122
|
+
total_current_assets: { label: "Total Current Assets" },
|
|
83
123
|
total_assets: { label: "Total Assets" },
|
|
84
|
-
|
|
85
|
-
cash: { label: "Cash & Equivalents" },
|
|
124
|
+
cash_and_equivalents: { label: "Cash & Equivalents" },
|
|
86
125
|
accounts_receivable: { label: "Accounts Receivable" },
|
|
87
|
-
|
|
126
|
+
inventory: { label: "Inventory" },
|
|
127
|
+
prepaid_expenses: { label: "Prepaid Expenses" },
|
|
128
|
+
property_equipment_net: { label: "Fixed Assets (Net)" },
|
|
129
|
+
accumulated_depreciation: { label: "Accumulated Depreciation" },
|
|
130
|
+
total_current_liabilities: { label: "Total Current Liabilities" },
|
|
88
131
|
total_liabilities: { label: "Total Liabilities" },
|
|
89
|
-
current_liabilities: { label: "Current Liabilities" },
|
|
90
132
|
accounts_payable: { label: "Accounts Payable" },
|
|
133
|
+
accrued_liabilities: { label: "Accrued Liabilities" },
|
|
134
|
+
deferred_revenue: { label: "Deferred Revenue" },
|
|
135
|
+
short_term_debt: { label: "Short-Term Debt" },
|
|
91
136
|
long_term_debt: { label: "Long-Term Debt" },
|
|
137
|
+
total_liabilities_and_equity: { label: "Total Liabilities & Equity" },
|
|
92
138
|
total_equity: { label: "Total Equity" },
|
|
93
139
|
retained_earnings: { label: "Retained Earnings" },
|
|
140
|
+
owners_equity: { label: "Owner's Equity" },
|
|
141
|
+
common_stock_par_value: { label: "Common Stock" },
|
|
142
|
+
additional_paid_in_capital: { label: "Opening Balance Equity" },
|
|
94
143
|
},
|
|
95
144
|
},
|
|
96
145
|
schedule_k1_s_corp: {
|
|
@@ -58,6 +58,11 @@ export interface Strategy {
|
|
|
58
58
|
positionStrength?: string;
|
|
59
59
|
specialistNote?: string;
|
|
60
60
|
}
|
|
61
|
+
export interface PartnerInfo {
|
|
62
|
+
name: string;
|
|
63
|
+
ownershipPct: number;
|
|
64
|
+
partnerType: 'general' | 'limited';
|
|
65
|
+
}
|
|
61
66
|
export interface ClientProfile {
|
|
62
67
|
bizName: string;
|
|
63
68
|
cpaName: string;
|
|
@@ -75,6 +80,13 @@ export interface ClientProfile {
|
|
|
75
80
|
ownsRealEstate: "No" | "Yes — Commercial" | "Yes — Residential" | "Yes — Both";
|
|
76
81
|
itemizesDeductions: "Yes" | "No" | "Unsure";
|
|
77
82
|
singleOwner: "Yes" | "No";
|
|
83
|
+
partners?: PartnerInfo[];
|
|
84
|
+
per_owner_allocations?: Array<{
|
|
85
|
+
owner_name: string;
|
|
86
|
+
ownership_pct: number;
|
|
87
|
+
qbi?: number;
|
|
88
|
+
w2_wages?: number;
|
|
89
|
+
}>;
|
|
78
90
|
equipmentPurchased: string;
|
|
79
91
|
realEstateValue: string;
|
|
80
92
|
capitalGains: string;
|