import type { AppRouter } from "beenvoice/server/api/root"; import type { inferRouterInputs, inferRouterOutputs } from "@trpc/server"; export type InvoicePdfPreviewInput = inferRouterInputs["invoices"]["previewPdf"]; type InvoiceDetail = NonNullable["invoices"]["getById"]>; export type InvoicePdfFormFields = { invoiceNumber: string; invoicePrefix?: string | null; businessId?: string | null; clientId: string; issueDate: Date; dueDate: Date; status?: "draft" | "sent" | "paid"; notes?: string | null; emailMessage?: string | null; taxRate: number; currency: string; items: Array<{ date: Date; description: string; hours: number | string; rate: number | string; }>; }; export function buildPreviewPdfInput(fields: InvoicePdfFormFields): InvoicePdfPreviewInput | null { if (!fields.clientId.trim()) return null; const items = fields.items.map((item) => ({ date: item.date, description: item.description.trim() || "Service", hours: Number(item.hours) || 0, rate: Number(item.rate) || 0, })); if (items.length === 0) return null; return { invoiceNumber: fields.invoiceNumber.trim() || "DRAFT", invoicePrefix: fields.invoicePrefix?.trim() || "#", businessId: fields.businessId?.trim() || "", clientId: fields.clientId, issueDate: fields.issueDate, dueDate: fields.dueDate, status: fields.status ?? "draft", notes: fields.notes?.trim() ?? "", emailMessage: fields.emailMessage?.trim() ?? "", taxRate: fields.taxRate, currency: fields.currency, items, }; } export function buildPreviewPdfInputFromInvoice(invoice: InvoiceDetail): InvoicePdfPreviewInput { return { invoiceNumber: invoice.invoiceNumber, invoicePrefix: invoice.invoicePrefix ?? "#", businessId: invoice.businessId ?? "", clientId: invoice.clientId, issueDate: new Date(invoice.issueDate), dueDate: new Date(invoice.dueDate), status: invoice.status as "draft" | "sent" | "paid", notes: invoice.notes ?? "", emailMessage: invoice.emailMessage ?? "", taxRate: invoice.taxRate, currency: invoice.currency ?? "USD", items: invoice.items.map((item) => ({ date: new Date(item.date), description: item.description, hours: item.hours, rate: item.rate, })), }; } export function canPreviewPdfInput(input: InvoicePdfPreviewInput | null): input is InvoicePdfPreviewInput { if (!input?.clientId) return false; return input.items.every((item) => item.description.trim().length > 0); }