Add 'apps/mobile/' from commit '5fa30f365f21531094cd4d2045042bb4f1370ac3'
git-subtree-dir: apps/mobile git-subtree-mainline:86f8987dffgit-subtree-split:5fa30f365f
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import type { AppRouter } from "beenvoice/server/api/root";
|
||||
import type { inferRouterInputs, inferRouterOutputs } from "@trpc/server";
|
||||
|
||||
export type InvoicePdfPreviewInput = inferRouterInputs<AppRouter>["invoices"]["previewPdf"];
|
||||
type InvoiceDetail = NonNullable<inferRouterOutputs<AppRouter>["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 ?? invoice.business?.id ?? "",
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user