import type { DispatchChecklistItem, DispatchComment, DispatchDetail, DispatchSignoff, DispatchToVendorPayload, DispatchWorkOrderRef, EmployeeOption, LocationOption, TaskListTemplate, UpdateDispatchPayload, UpliftRequest, VendorDropdownItem, WorkOrderAuditEntry, WorkOrderComment, WorkOrderDetail, WorkOrderDispatchSummary, WorkOrderFormValues, WorkOrderListItem, } from "@/domain/work-orders/types/work-order"; import { toDateInputValue } from "@/lib/time-utils"; 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 readId(record: Record): string | number { const value = record.id ?? record.Id; if (typeof value === "string" || typeof value === "number") { return 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; } export function mapWorkOrderListItem(raw: unknown): WorkOrderListItem { const item = asRecord(raw); return { id: readId(item), number: readString(item, "internalWONumber", "number", "workOrderNumber"), title: readString(item, "title", "Title"), location: readString(item, "location", "Location", "locationName", "LocationName"), priority: readString(item, "priority", "Priority"), status: readString(item, "status", "Status"), createdDate: readString(item, "createdDate", "CreatedDate"), dueDate: readString(item, "dueDate", "DueDate"), assignedTo: readString(item, "assignedTo", "AssignedTo", "employeeName", "EmployeeName"), lastUpdated: readString(item, "lastUpdated", "LastUpdated"), }; } export function mapWorkOrderListItems(rawItems: unknown[]): WorkOrderListItem[] { return rawItems.map(mapWorkOrderListItem); } export function mapWorkOrderComment(raw: unknown): WorkOrderComment { const item = asRecord(raw); return { id: readId(item), createdDate: readString(item, "createdDate", "CreatedDate"), commenttext: readString(item, "commenttext", "Commenttext", "text", "Text"), commentType: readString(item, "commentType", "CommentType"), userName: readString(item, "userName", "UserName"), commenter: readString(item, "commenter", "Commenter") || null, recordType: readString(item, "recordType", "RecordType") || null, }; } export function mapWorkOrderAuditEntry(raw: unknown): WorkOrderAuditEntry { const item = asRecord(raw); return { id: readId(item), fieldName: readString(item, "fieldName", "FieldName"), oldValue: readString(item, "oldValue", "OldValue"), newValue: readString(item, "newValue", "NewValue"), action: readString(item, "action", "Action"), createdAt: readString(item, "createdAt", "CreatedAt"), userName: readString(item, "userName", "UserName"), }; } export function mapWorkOrderDispatchSummary(raw: unknown): WorkOrderDispatchSummary { const item = asRecord(raw); return { id: readId(item), dispatchNumber: readString(item, "dispatchNumber", "DispatchNumber"), poNumber: readString(item, "poNumber", "PoNumber", "PONumber"), vendorName: readString(item, "vendorName", "VendorName"), nteAmount: readNumber(item, "nteAmount", "NTEAmount"), status: readString(item, "status", "Status"), dispatchedAt: readString(item, "dispatchedAt", "DispatchedAt"), }; } export function mapWorkOrderDetail(raw: unknown): WorkOrderDetail { const wo = asRecord(raw); const locationId = wo.locationId ?? wo.LocationId; return { id: readId(wo), internalWONumber: readString(wo, "internalWONumber", "InternalWONumber"), workOrderNumber: readString(wo, "workerOrderNumber", "workOrderNumber", "WorkerOrderNumber"), title: readString(wo, "title", "workerOrderTitle", "WorkerOrderTitle"), location: readString(wo, "location", "Location"), locationId: locationId != null ? String(locationId) : "", locationZip: readString(wo, "locationZip", "LocationZip"), assignedTo: readString(wo, "assignee", "assignedTo", "Assignee", "AssignedTo"), dueDate: toDateInputValue(readString(wo, "dueDate", "DueDate")), createdDate: toDateInputValue(readString(wo, "createdDate", "CreatedDate")), createdDateFull: readString(wo, "createdDate", "CreatedDate"), description: readString(wo, "description", "Description"), priority: readString(wo, "priority", "Priority"), status: readString(wo, "status", "Status") || "Open", po: readString(wo, "po", "PO"), tt: readString(wo, "tt", "TT"), problem: readString(wo, "problem", "Problem"), trade: readString(wo, "trade", "Trade"), subTrade: readString(wo, "subTrade", "SubTrade"), vendorNTE: wo.vendorNTE != null ? String(wo.vendorNTE) : "", scheduledDate: toDateInputValue(readString(wo, "scheduledDate", "ScheduledDate")), completedDate: toDateInputValue(readString(wo, "completedDate", "CompletedDate")), source: readString(wo, "source", "Source"), comments: Array.isArray(wo.comments) ? wo.comments.map(mapWorkOrderComment) : Array.isArray(wo.Comments) ? wo.Comments.map(mapWorkOrderComment) : [], auditLog: Array.isArray(wo.auditLog) ? wo.auditLog.map(mapWorkOrderAuditEntry) : Array.isArray(wo.AuditLog) ? wo.AuditLog.map(mapWorkOrderAuditEntry) : [], dispatches: Array.isArray(wo.dispatches) ? wo.dispatches.map(mapWorkOrderDispatchSummary) : Array.isArray(wo.Dispatches) ? wo.Dispatches.map(mapWorkOrderDispatchSummary) : [], }; } export function mapWorkOrderDetailToFormValues(detail: WorkOrderDetail): WorkOrderFormValues { return { internalWONumber: detail.internalWONumber, workOrderNumber: detail.workOrderNumber, title: detail.title, locationId: detail.locationId, priority: detail.priority, status: detail.status, createdDate: detail.createdDate, dueDate: detail.dueDate, scheduledDate: detail.scheduledDate, completedDate: detail.completedDate, assignedTo: detail.assignedTo, description: detail.description, po: detail.po, tt: detail.tt, problem: detail.problem, trade: detail.trade, subTrade: detail.subTrade, vendorNTE: detail.vendorNTE, source: detail.source, }; } export function mapWorkOrderFormToCreatePayload( values: WorkOrderFormValues, ): Record { return { WorkerOrderNumber: values.workOrderNumber, WorkerOrderTitle: values.title, LocationId: values.locationId ? parseInt(values.locationId, 10) : null, Priority: values.priority || null, Status: values.status, CreatedDate: values.createdDate || null, DueDate: values.dueDate || null, ScheduledDate: values.scheduledDate || null, CompletedDate: values.completedDate || null, AssignTo: values.assignedTo || null, Description: values.description, PO: values.po || null, TT: values.tt || null, Problem: values.problem || null, Trade: values.trade || null, SubTrade: values.subTrade || null, VendorNTE: values.vendorNTE ? parseFloat(values.vendorNTE) : null, Source: values.source || null, }; } export function mapWorkOrderFormToUpdatePayload( id: string | number, values: WorkOrderFormValues, ): Record { return { Id: id, WorkerOrderNumber: values.workOrderNumber, WorkerOrderTitle: values.title, Description: values.description, PO: values.po || null, TT: values.tt || null, AssignTo: values.assignedTo || null, DueDate: values.dueDate || null, Priority: values.priority || null, Status: values.status, LocationId: values.locationId ? parseInt(values.locationId, 10) : null, Problem: values.problem || null, Trade: values.trade || null, SubTrade: values.subTrade || null, VendorNTE: values.vendorNTE ? parseFloat(values.vendorNTE) : null, ScheduledDate: values.scheduledDate || null, CompletedDate: values.completedDate || null, CreatedDate: values.createdDate || null, Source: values.source || null, }; } export function mapLocationOption(raw: unknown): LocationOption { const item = asRecord(raw); return { id: readId(item), name: readString(item, "name", "Name", "locationName", "LocationName"), }; } export function mapLocationOptions(rawItems: unknown[]): LocationOption[] { return rawItems.map(mapLocationOption); } export function mapEmployeeOption(raw: unknown): EmployeeOption { const item = asRecord(raw); return { id: readId(item), name: readString(item, "name", "Name", "fullName", "FullName", "employeeName", "EmployeeName") || readString(item, "userName", "UserName"), }; } export function mapEmployeeOptions(rawItems: unknown[]): EmployeeOption[] { return rawItems.map(mapEmployeeOption); } export function mapVendorDropdownItem(raw: unknown): VendorDropdownItem { const item = asRecord(raw); return { id: readId(item), companyName: readString(item, "companyName", "CompanyName"), tradeSpecialties: readString(item, "tradeSpecialties", "TradeSpecialties"), address: readString(item, "address", "Address"), distanceMiles: readNumber(item, "distanceMiles", "DistanceMiles"), }; } export function mapVendorDropdownItems(rawItems: unknown[]): VendorDropdownItem[] { return rawItems.map(mapVendorDropdownItem); } export function mapTaskListTemplate(raw: unknown): TaskListTemplate { const item = asRecord(raw); const items = item.items ?? item.Items; return { id: readId(item), name: readString(item, "name", "Name"), items: Array.isArray(items) ? items : [], }; } export function mapTaskListTemplates(rawItems: unknown[]): TaskListTemplate[] { return rawItems.map(mapTaskListTemplate); } export function mapDispatchChecklistItem(raw: unknown): DispatchChecklistItem { const item = asRecord(raw); return { id: readId(item), itemText: readString(item, "itemText", "ItemText"), isCompleted: readBool(item, "isCompleted", "IsCompleted"), completedBy: readString(item, "completedBy", "CompletedBy") || null, completedAt: readString(item, "completedAt", "CompletedAt") || null, }; } export function mapDispatchSignoff(raw: unknown): DispatchSignoff { const item = asRecord(raw); return { id: readId(item), signoffType: readString(item, "signoffType", "SignoffType"), name: readString(item, "name", "Name"), signature: readString(item, "signature", "Signature"), signatureMethod: readString(item, "signatureMethod", "SignatureMethod"), signedAt: readString(item, "signedAt", "SignedAt"), }; } export function mapDispatchComment(raw: unknown): DispatchComment { const item = asRecord(raw); return { id: readId(item), createdDate: readString(item, "createdDate", "CreatedDate"), commenttext: readString(item, "commenttext", "Commenttext", "text", "Text"), userName: readString(item, "userName", "UserName"), commenter: readString(item, "commenter", "Commenter") || null, }; } export function mapDispatchWorkOrderRef(raw: unknown): DispatchWorkOrderRef { const item = asRecord(raw); return { id: readId(item), woNumber: readString(item, "woNumber", "WoNumber", "WONumber", "number", "Number"), }; } export function mapDispatchDetail(raw: unknown): DispatchDetail { const item = asRecord(raw); const checklistItems = item.checklistItems ?? item.ChecklistItems; const signoffs = item.signoffs ?? item.Signoffs; const comments = item.comments ?? item.Comments; const workOrders = item.workOrders ?? item.WorkOrders; return { id: readId(item), dispatchNumber: readString(item, "dispatchNumber", "DispatchNumber"), poNumber: readString(item, "poNumber", "PoNumber", "PONumber"), vendorName: readString(item, "vendorName", "VendorName"), vendorEmail: readString(item, "vendorEmail", "VendorEmail"), woNumber: readString(item, "woNumber", "WoNumber"), status: readString(item, "status", "Status"), nteAmount: readNumber(item, "nteAmount", "NTEAmount"), scheduledDate: readString(item, "scheduledDate", "ScheduledDate"), completedDate: readString(item, "completedDate", "CompletedDate"), description: readString(item, "description", "Description"), dispatchedAt: readString(item, "dispatchedAt", "DispatchedAt"), acknowledgedAt: readString(item, "acknowledgedAt", "AcknowledgedAt"), verifiedAt: readString(item, "verifiedAt", "VerifiedAt"), verifiedBy: readString(item, "verifiedBy", "VerifiedBy"), checklistItems: Array.isArray(checklistItems) ? checklistItems.map(mapDispatchChecklistItem) : [], signoffs: Array.isArray(signoffs) ? signoffs.map(mapDispatchSignoff) : [], comments: Array.isArray(comments) ? comments.map(mapDispatchComment) : [], workOrders: Array.isArray(workOrders) ? workOrders.map(mapDispatchWorkOrderRef) : [], }; } export function mapDispatchToVendorPayload( payload: DispatchToVendorPayload, ): Record { return { WorkOrderIds: payload.workOrderIds, VendorIds: payload.vendorIds, NTEAmount: payload.nteAmount, ScheduledDate: payload.scheduledDate, Description: payload.description, TaskListTemplateId: payload.taskListTemplateId, CustomChecklistItems: payload.customChecklistItems, }; } export function mapUpdateDispatchPayload(payload: UpdateDispatchPayload): Record { return { Id: payload.id, Status: payload.status, NTEAmount: payload.nteAmount, ScheduledDate: payload.scheduledDate, CompletedDate: payload.completedDate, Description: payload.description, }; } export function mapUpliftRequest(raw: unknown): UpliftRequest { const item = asRecord(raw); return { id: readId(item), status: readString(item, "status", "Status"), currentNTE: readNumber(item, "currentNTE", "CurrentNTE"), requestedNTE: readNumber(item, "requestedNTE", "RequestedNTE") ?? 0, delta: readNumber(item, "delta", "Delta") ?? 0, vendorReason: readString(item, "vendorReason", "VendorReason"), requestedAt: readString(item, "requestedAt", "RequestedAt"), requestedByVendorName: readString(item, "requestedByVendorName", "RequestedByVendorName"), decidedAt: readString(item, "decidedAt", "DecidedAt"), decidedByName: readString(item, "decidedByName", "DecidedByName"), decisionNote: readString(item, "decisionNote", "DecisionNote"), requiredTier: readNumber(item, "requiredTier", "RequiredTier") ?? 1, canDecide: readBool(item, "canDecide", "CanDecide"), }; } export function mapUpliftRequests(rawItems: unknown[]): UpliftRequest[] { return rawItems.map(mapUpliftRequest); }