Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions client/src/hooks/use-reports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,120 @@ export function useRunTaxAutomation() {
apiRequest('POST', '/api/workflows/close-tax-automation', params).then(r => r.json()),
});
}

// ── Tax Report Types ──

export interface TaxReportParams {
taxYear: number;
includeDescendants?: boolean;
}

export interface ScheduleELineItem {
lineNumber: string;
lineLabel: string;
amount: number;
transactionCount: number;
}

export interface ScheduleEPropertyColumn {
propertyId: string;
propertyName: string;
address: string;
state: string;
filingType: 'schedule-e-personal' | 'schedule-e-partnership';
tenantId: string;
tenantName: string;
lines: ScheduleELineItem[];
totalIncome: number;
totalExpenses: number;
netIncome: number;
}

export interface ScheduleEReport {
taxYear: number;
properties: ScheduleEPropertyColumn[];
entityLevelItems: ScheduleELineItem[];
entityLevelTotal: number;
uncategorizedAmount: number;
uncategorizedCount: number;
unmappedCategories: string[];
}

export interface K1MemberAllocation {
memberName: string;
pct: number;
ordinaryIncome: number;
rentalIncome: number;
guaranteedPayments: number;
otherDeductions: number;
totalAllocated: number;
periods: Array<{
startDate: string;
endDate: string;
pct: number;
dayCount: number;
allocatedIncome: number;
}>;
}

export interface Form1065Report {
taxYear: number;
entityId: string;
entityName: string;
entityType: string;
ordinaryIncome: number;
totalDeductions: number;
netIncome: number;
incomeByCategory: Array<{ category: string; coaCode: string; amount: number }>;
deductionsByCategory: Array<{ category: string; coaCode: string; amount: number; scheduleELine?: string }>;
memberAllocations: K1MemberAllocation[];
warnings: string[];
}

function buildTaxQueryString(params: TaxReportParams): string {
const qs = new URLSearchParams();
qs.set('taxYear', String(params.taxYear));
if (params.includeDescendants !== undefined) qs.set('includeDescendants', String(params.includeDescendants));
return qs.toString();
}

export function useScheduleEReport(params: TaxReportParams | null) {
const tenantId = useTenantId();
const qs = params ? buildTaxQueryString(params) : '';
return useQuery<ScheduleEReport>({
queryKey: [`/api/reports/tax/schedule-e?${qs}`, tenantId],
enabled: !!tenantId && !!params,
staleTime: 2 * 60 * 1000,
});
}

export function useForm1065Report(params: TaxReportParams | null) {
const tenantId = useTenantId();
const qs = params ? buildTaxQueryString(params) : '';
return useQuery<Form1065Report[]>({
queryKey: [`/api/reports/tax/form-1065?${qs}`, tenantId],
enabled: !!tenantId && !!params,
staleTime: 2 * 60 * 1000,
});
}

export function useExportTaxPackage() {
return useMutation<void, Error, TaxReportParams & { format?: 'csv' | 'json' }>({
mutationFn: async (params) => {
const qs = new URLSearchParams();
qs.set('taxYear', String(params.taxYear));
qs.set('format', params.format || 'csv');
if (params.includeDescendants !== undefined) qs.set('includeDescendants', String(params.includeDescendants));
const res = await fetch(`/api/reports/tax/export?${qs}`, { credentials: 'include' });
if (!res.ok) throw new Error('Export failed');
const blob = await res.blob();
const ext = params.format === 'json' ? 'json' : 'csv';
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `tax-package-${params.taxYear}.${ext}`;
a.click();
URL.revokeObjectURL(url);
},
});
}
Loading
Loading