shoc-frontend-new/src/domain/work-orders/utils/uplift-display-utils.ts

107 lines
3.2 KiB
TypeScript
Raw Normal View History

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<WorkOrderUpliftStatus, string> = {
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<WorkOrderUplift, "status" | "requestedById">,
currentUserId: string | number | null | undefined,
isAdmin: boolean,
): boolean {
if (uplift.status === "auto_approved") {
// SH-196: auto-approved revoke is dispatcher-own only (no admin bypass).
return (
currentUserId != null &&
currentUserId !== "" &&
uplift.requestedById != null &&
String(uplift.requestedById) === String(currentUserId)
);
}
return isAdmin && uplift.status === "approved";
}
export function upliftRevokeRequiresReason(status: WorkOrderUpliftStatus): boolean {
return status === "approved";
}