mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-06 11:12:04 +00:00
mapUpliftSummary no longer treats row status as uplift primaryStatus, getUpliftCellLabel hides pills without hasUplift, and vendor submit filters blank new technicians.
158 lines
4.4 KiB
TypeScript
158 lines
4.4 KiB
TypeScript
import type {
|
|
UpliftSummary,
|
|
WorkOrderUplift,
|
|
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<string, unknown> {
|
|
return typeof raw === "object" && raw !== null ? (raw as Record<string, unknown>) : {};
|
|
}
|
|
|
|
function readString(record: Record<string, unknown>, ...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<string, unknown>, ...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<string, unknown>, ...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, unknown>): string | number {
|
|
const value = record.id ?? record.Id;
|
|
if (typeof value === "string" || typeof value === "number") {
|
|
return value;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
function readOptionalId(
|
|
record: Record<string, unknown>,
|
|
...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<string>(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;
|
|
}
|
|
|
|
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"),
|
|
};
|
|
}
|
|
|
|
export function mapWorkOrderUplifts(rawItems: unknown[]): WorkOrderUplift[] {
|
|
return rawItems.map(mapWorkOrderUplift);
|
|
}
|