Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-19 22:02:49 +00:00
co-authored by renee-png
parent 4bda7b9765
commit 3d92e220e0
+65
View File
@@ -1374,6 +1374,71 @@ function ImportPage() {
if (cfg.postInsert) cfg.postInsert(inserted_rows, ctx);
// For time/expense imports: create invoice_line_items for any inserted
// row that was attached to an invoice (billed=true), then recompute the
// affected invoices' subtotal/total = sum of all their lines.
if ((cfg.table === "time_entries" || cfg.table === "expenses") && inserted_rows.length > 0) {
type LinkedRow = Row & { id: string; invoice_id: string; case_id: string };
const linked = inserted_rows.filter(
(r) => r.invoice_id && r.id && r.case_id,
) as LinkedRow[];
if (linked.length > 0) {
const lineItems = linked.map((r) => {
if (cfg.table === "time_entries") {
const qty = Number(r.hours ?? 0);
const rate = Number(r.hourly_rate ?? 0);
return {
invoice_id: r.invoice_id,
case_id: r.case_id,
kind: "time",
description: String(r.description ?? "Time entry"),
work_date: r.work_date ?? null,
quantity: qty,
rate,
amount: +(qty * rate).toFixed(2),
time_entry_id: r.id,
user_id: r.user_id ?? null,
};
}
const amt = Number(r.amount ?? 0);
return {
invoice_id: r.invoice_id,
case_id: r.case_id,
kind: "expense",
description: String(r.description ?? "Expense"),
work_date: r.expense_date ?? null,
quantity: 1,
rate: amt,
amount: amt,
expense_id: r.id,
user_id: r.user_id ?? null,
};
});
for (let i = 0; i < lineItems.length; i += 500) {
const slice = lineItems.slice(i, i + 500);
const { error: liErr } = await supabase
.from("invoice_line_items")
.insert(slice as any);
if (liErr) errors.push(`Line items (batch ${i / 500 + 1}): ${liErr.message}`);
}
const invoiceIds = Array.from(new Set(linked.map((r) => r.invoice_id)));
for (const invId of invoiceIds) {
const { data: lines } = await supabase
.from("invoice_line_items")
.select("amount")
.eq("invoice_id", invId);
const subtotal = (lines ?? []).reduce(
(s, l) => s + Number((l as { amount: number }).amount ?? 0),
0,
);
await supabase
.from("invoices")
.update({ subtotal, total: subtotal } as any)
.eq("id", invId);
}
}
}
// Mirror imported "client" contacts into the clients table so they appear on the Clients page.
let mirrored = 0;
if (cfg.key === "contacts" && contactGroup === "client" && inserted_rows.length > 0) {