import type { UpliftSummary, WorkOrderUplift, WorkOrderUpliftAttachment, WorkOrderUpliftStatus, } from "@/domain/work-orders/types/work-order-uplift"; import { WORK_ORDER_UPLIFT_STATUSES } from "@/domain/work-orders/types/work-order-uplift"; function asRecord(raw: unknown): Record { return typeof raw === "object" && raw !== null ? (raw as Record) : {}; } function readString(record: Record, ...keys: string[]): string { for (const key of keys) { const value = record[key]; if (typeof value === "string") { return value; } if (typeof value === "number") { return String(value); } } return ""; } function readNumber(record: Record, ...keys: string[]): number | null { for (const key of keys) { const value = record[key]; if (typeof value === "number") { return value; } if (typeof value === "string" && value !== "") { const parsed = Number(value); if (!Number.isNaN(parsed)) { return parsed; } } } return null; } function readBool(record: Record, ...keys: string[]): boolean { for (const key of keys) { const value = record[key]; if (typeof value === "boolean") { return value; } } return false; } function readId(record: Record): string | number { const value = record.id ?? record.Id; if (typeof value === "string" || typeof value === "number") { return value; } return ""; } function readOptionalId( record: Record, ...keys: string[] ): string | number | null { for (const key of keys) { const value = record[key]; if (typeof value === "string" || typeof value === "number") { return value; } } return null; } const STATUS_SET = new Set(WORK_ORDER_UPLIFT_STATUSES); function normalizeUpliftStatus(raw: string): WorkOrderUpliftStatus { const normalized = raw.trim().toLowerCase().replace(/\s+/g, "_"); if (STATUS_SET.has(normalized)) { return normalized as WorkOrderUpliftStatus; } if (normalized === "canceled") { return "cancelled"; } if (normalized === "autoapproved") { return "auto_approved"; } return "pending"; } export function mapUpliftSummary(raw: unknown): UpliftSummary { const item = asRecord(raw); const nested = asRecord(item.upliftSummary ?? item.UpliftSummary); const hasNested = Object.keys(nested).length > 0; const source = hasNested ? nested : item; const pendingCount = readNumber(source, "pendingCount", "PendingCount") ?? readNumber(item, "pendingUpliftCount", "PendingUpliftCount") ?? 0; const hasUplift = readBool(source, "hasUplift", "HasUplift") || readBool(item, "hasUplift", "HasUplift") || pendingCount > 0; // Never treat the work-order lifecycle status/Status as uplift primaryStatus. const primaryStatusRaw = hasNested ? readString(source, "primaryStatus", "PrimaryStatus", "status", "Status") : readString(item, "primaryStatus", "PrimaryStatus"); const amount = hasNested ? readNumber(source, "amount", "Amount") : readNumber(item, "amount", "Amount"); const summary: UpliftSummary = { hasUplift, pendingCount, }; if (primaryStatusRaw) { summary.primaryStatus = normalizeUpliftStatus(primaryStatusRaw); } if (amount != null) { summary.amount = amount; } return summary; } function mapUpliftAttachment(raw: unknown, index: number): WorkOrderUpliftAttachment | null { const record = asRecord(raw); const name = readString(record, "name", "Name", "fileName", "FileName"); if (name === "") return null; const idValue = record.id ?? record.Id; const id = typeof idValue === "string" || typeof idValue === "number" ? String(idValue) : `${name}-${index}`; return { id, name, url: readString(record, "url", "Url", "fileUrl", "FileUrl"), }; } function mapUpliftAttachments(raw: unknown): WorkOrderUpliftAttachment[] { if (!Array.isArray(raw)) return []; return raw.flatMap((item, index) => { const attachment = mapUpliftAttachment(item, index); return attachment == null ? [] : [attachment]; }); } function mapEvidenceAttachment(item: Record): WorkOrderUpliftAttachment[] { const listed = mapUpliftAttachments( item.attachments ?? item.Attachments ?? item.documents ?? item.Documents, ); if (listed.length > 0) return listed; const evidenceId = readOptionalId(item, "evidenceDocumentId", "EvidenceDocumentId"); const name = readString( item, "evidenceFileName", "EvidenceFileName", "originalFileName", "OriginalFileName", ); if (evidenceId == null && name === "") return []; return [ { id: evidenceId == null ? "evidence" : String(evidenceId), name: name === "" ? `Document #${evidenceId}` : name, url: "", }, ]; } export function mapWorkOrderUplift(raw: unknown): WorkOrderUplift { const item = asRecord(raw); const statusRaw = readString(item, "status", "Status"); return { id: readId(item), status: statusRaw ? normalizeUpliftStatus(statusRaw) : "pending", amount: readNumber(item, "amount", "Amount", "requestedNTE", "RequestedNTE") ?? 0, notes: readString(item, "notes", "Notes", "vendorReason", "VendorReason"), requestedAt: readString(item, "requestedAt", "RequestedAt"), requestedById: readOptionalId( item, "requestedById", "RequestedById", "requesterId", "RequesterId", ), requestedByName: readString( item, "requestedByName", "RequestedByName", "requestedByVendorName", "RequestedByVendorName", ), decidedAt: readString(item, "decidedAt", "DecidedAt"), decidedByName: readString(item, "decidedByName", "DecidedByName"), decisionNote: readString(item, "decisionNote", "DecisionNote", "revokeReason", "RevokeReason"), attachments: mapEvidenceAttachment(item), }; } export function mapWorkOrderUplifts(rawItems: unknown[]): WorkOrderUplift[] { return rawItems.map(mapWorkOrderUplift); }