import type { WorkOrderUplift, UpliftSummary, WorkOrderUpliftStatus, } from "@/domain/work-orders/types/work-order-uplift"; import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row"; export function formatUpliftMoney(value: number | null | undefined): string { if (value == null || Number.isNaN(value)) { return "—"; } return new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", maximumFractionDigits: 0, }).format(value); } const STATUS_LABELS: Record = { pending: "Pending", approved: "Approved", auto_approved: "Auto", rejected: "Rejected", cancelled: "Cancelled", revoked: "Revoked", }; export function formatUpliftStatusLabel(status: WorkOrderUpliftStatus): string { return STATUS_LABELS[status]; } export function getUpliftCellLabel(summary: UpliftSummary): string | null { if (!summary.hasUplift && summary.pendingCount <= 0) { return null; } if (summary.pendingCount > 0) { return summary.pendingCount === 1 ? "1 Pending" : `${summary.pendingCount} Pending`; } if (summary.primaryStatus) { const label = formatUpliftStatusLabel(summary.primaryStatus); if (summary.amount != null) { return `${label} ${formatUpliftMoney(summary.amount)}`; } return label; } if (summary.hasUplift) { return "Uplift"; } return null; } export function getUpliftStatusPillStyle(status: WorkOrderUpliftStatus): { background: string; color: string; } { switch (status) { case "pending": return { background: "var(--status-pending-bg)", color: "var(--status-pending-text)" }; case "approved": return { background: "var(--status-success-bg, #DCFCE7)", color: "var(--color-success)" }; case "auto_approved": return { background: "var(--color-primary-tint)", color: "var(--color-primary)" }; case "rejected": return { background: "#FEE2E2", color: "#B91C1C" }; case "cancelled": case "revoked": return { background: "var(--color-bg-muted)", color: "var(--color-text-muted)" }; default: return { background: "var(--color-bg-muted)", color: "var(--color-text-muted)" }; } } export function isWorkOrderUpliftsReadOnly(status: WorkOrderTableRow["status"]): boolean { return status === "Completed" || status === "Canceled"; } export function canOpenUpliftsDialog( summary: UpliftSummary, status: WorkOrderTableRow["status"], ): boolean { if (summary.hasUplift || summary.pendingCount > 0) { return true; } return !isWorkOrderUpliftsReadOnly(status); } export function canRevokeWorkOrderUplift( uplift: Pick, currentUserId: string | number | null | undefined, ): boolean { if (uplift.status !== "auto_approved") { // SH-214/SH-212: admin-approved revoke lives on Uplift Approvals, not the WO dialog. return false; } return ( currentUserId != null && currentUserId !== "" && uplift.requestedById != null && String(uplift.requestedById) === String(currentUserId) ); } export function upliftRevokeRequiresReason(status: WorkOrderUpliftStatus): boolean { return status === "approved"; } export const UPLIFT_STANDARD_ALLOWANCE_USD = 500; export const UPLIFT_EMERGENCY_ALLOWANCE_USD = 5000; export function getUpliftAllowanceCap(workOrderType: string): number { return workOrderType === "Emergency" ? UPLIFT_EMERGENCY_ALLOWANCE_USD : UPLIFT_STANDARD_ALLOWANCE_USD; } export function hasOpenWorkOrderUplift( uplifts: ReadonlyArray>, ): boolean { return uplifts.some((uplift) => uplift.status === "pending"); } export function getRemainingUpliftAllowance( workOrderType: string, uplifts: ReadonlyArray>, ): number { const consumed = uplifts .filter((uplift) => uplift.status === "auto_approved") .reduce((sum, uplift) => sum + uplift.amount, 0); return Math.max(0, getUpliftAllowanceCap(workOrderType) - consumed); }