The PO Activity timeline rendered every partial payment as the generic "Partial payment confirmed". markPaid() already persists the instalment amount on the PARTIAL_PAYMENT_CONFIRMED action's metadata (metadata.paymentAmount), so surface it: the row now reads "Partial payment of <amount> confirmed" using the PO's own currency. Falls back to the plain label when paymentAmount is missing or non-numeric (older audit rows) so historical POs never render NaN. Extracted ACTION_LABELS + the new actionLabel() helper into lib/po-activity.ts so the label logic is unit-testable without pulling the server-only PoDetail component (and its storage/auth imports) into jsdom. Fixes #140
40 lines
1.6 KiB
TypeScript
40 lines
1.6 KiB
TypeScript
import type { Prisma } from "@prisma/client";
|
|
import { formatCurrency } from "@/lib/utils";
|
|
|
|
// Human-readable labels for each POAction type, shown in the PO Activity timeline.
|
|
export const ACTION_LABELS: Record<string, string> = {
|
|
CREATED: "Created",
|
|
SUBMITTED: "Submitted for review",
|
|
APPROVED: "Approved",
|
|
APPROVED_WITH_NOTE: "Approved with note",
|
|
REJECTED: "Rejected",
|
|
EDITS_REQUESTED: "Edits requested",
|
|
VENDOR_ID_REQUESTED: "Vendor ID requested",
|
|
VENDOR_ID_PROVIDED: "Vendor ID provided",
|
|
PAYMENT_SENT: "Payment confirmed",
|
|
PARTIAL_PAYMENT_CONFIRMED: "Partial payment confirmed",
|
|
RECEIPT_CONFIRMED: "Receipt confirmed",
|
|
PARTIAL_RECEIPT_CONFIRMED: "Partial receipt confirmed",
|
|
CLOSED: "Closed",
|
|
MANAGER_LINE_EDIT: "Manager amended line items",
|
|
PRODUCT_PRICE_UPDATED: "Product prices updated",
|
|
CANCELLED: "Cancelled",
|
|
SUPERSEDED: "Superseded",
|
|
};
|
|
|
|
// Produce the Activity-timeline label for an action. Most actions use the static
|
|
// ACTION_LABELS map; PARTIAL_PAYMENT_CONFIRMED interpolates the instalment amount
|
|
// from the action's metadata (already persisted by markPaid) — issue #140.
|
|
export function actionLabel(
|
|
action: { actionType: string; metadata: Prisma.JsonValue },
|
|
currency: string,
|
|
): string {
|
|
const fallback = ACTION_LABELS[action.actionType] ?? action.actionType;
|
|
if (action.actionType === "PARTIAL_PAYMENT_CONFIRMED") {
|
|
const amount = (action.metadata as { paymentAmount?: unknown } | null)?.paymentAmount;
|
|
if (typeof amount === "number" && Number.isFinite(amount)) {
|
|
return `Partial payment of ${formatCurrency(amount, currency)} confirmed`;
|
|
}
|
|
}
|
|
return fallback;
|
|
}
|