WFDASH-WEBAPP/src/lib/order-invoices.test.ts
Dave 7555196166 feat(audit): implement audit trail for delivery notes and orders
- Added an audit trail feature that logs every create, update, and delete action on delivery notes and orders, capturing detailed changes per field.
- Introduced the `AuditTimeline` component to display the history of changes for delivery notes and orders, enhancing traceability.
- Updated the `page.tsx` files for delivery notes and orders to fetch and display audit logs, ensuring users can view the history of modifications.
- Enhanced the `package.json` with a new migration script for setting up the audit log functionality.

This feature improves accountability and transparency in the management of delivery notes and orders.
2026-09-30 01:48:44 +02:00

84 lines
3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { readItemInvoiceNumber, summarizeOrderInvoices } from "./order-invoices";
const qbDetails = (number: string, date = "2026-09-25") => ({
invoice: {
number,
date,
qbInvoiceLink: `https://app.qbo.intuit.com/app/invoice?txnId=${number}`,
billingCompany: "CNL",
setByName: "David Els",
},
});
describe("readItemInvoiceNumber", () => {
it("prefers the Invoicing-page details over customer_invoice_number", () => {
expect(
readItemInvoiceNumber({
customer_invoice_number: "OLD-1",
order_item_details: qbDetails("INV10983"),
}),
).toBe("INV10983");
});
it("falls back to customer_invoice_number", () => {
expect(readItemInvoiceNumber({ customer_invoice_number: "INV1" })).toBe("INV1");
});
it("parses order_item_details stored as a JSON string", () => {
expect(
readItemInvoiceNumber({ order_item_details: JSON.stringify(qbDetails("INV7")) }),
).toBe("INV7");
});
it("ignores the supplier invoice collection-confirm writes before billing", () => {
// Same blob shape collection-confirm writes: no QuickBooks fields.
const supplierInvoice = {
invoice: { number: "IN-5018651", date: "2026-09-25", setBy: "u1", setByName: "Dave", setAt: "x" },
};
expect(readItemInvoiceNumber({ order_item_details: supplierInvoice })).toBeNull();
expect(summarizeOrderInvoices([{ order_item_details: supplierInvoice }])).toEqual([]);
// …but a reconciled customer_invoice_number still counts.
expect(
readItemInvoiceNumber({ order_item_details: supplierInvoice, customer_invoice_number: "INV1" }),
).toBe("INV1");
});
it("returns null for uninvoiced or malformed rows", () => {
expect(readItemInvoiceNumber({})).toBeNull();
expect(readItemInvoiceNumber({ order_item_details: "{not json" })).toBeNull();
expect(readItemInvoiceNumber({ customer_invoice_number: " " })).toBeNull();
});
});
describe("summarizeOrderInvoices", () => {
it("groups lines by invoice number and counts them", () => {
const result = summarizeOrderInvoices([
{ order_item_details: qbDetails("INV2", "2026-09-25") },
{ order_item_details: qbDetails("INV2", "2026-09-25") },
{ order_item_details: qbDetails("INV1", "2026-09-20") },
{ order_item_details: null },
]);
expect(result.map((r) => [r.number, r.lineCount])).toEqual([
["INV1", 1],
["INV2", 2],
]);
expect(result[1]).toMatchObject({
date: "2026-09-25",
billingCompany: "CNL",
setByName: "David Els",
});
});
it("uses invoiced_date when the details carry no date", () => {
const [only] = summarizeOrderInvoices([
{ customer_invoice_number: "INV9", invoiced_date: "2026-09-01" },
]);
expect(only).toMatchObject({ number: "INV9", date: "2026-09-01", qbInvoiceLink: null });
});
it("returns an empty list for an uninvoiced order", () => {
expect(summarizeOrderInvoices([{}, { customer_invoice_number: "" }])).toEqual([]);
});
});