mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-01 14:23:11 +00:00
100 lines
3.1 KiB
TypeScript
100 lines
3.1 KiB
TypeScript
import {
|
|
DOC_STATUS_API,
|
|
WORK_ORDER_TYPE_API_TO_FE,
|
|
} from "@/domain/work-orders/types/work-order-board";
|
|
import type { CompletionDocStatus } from "@/domain/work-orders/types/work-order-table-row";
|
|
import type { WOType } from "@/domain/work-orders/types/work-order-wizard";
|
|
|
|
// SH-126/SH-184: Add-On is a backend-authoritative indicator (`isAddOn`), not a
|
|
// selectable business type, so it is no longer part of the WOType union.
|
|
const DETAIL_WO_TYPES = new Set(["PM", "Reactive", "Emergency", "Overdue"]);
|
|
|
|
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;
|
|
}
|
|
|
|
/** Authoritative WO type only — never falls back to integration `source`. */
|
|
export function readDetailWoType(record: Record<string, unknown>): WOType | "" {
|
|
const numeric =
|
|
readNumber(record, "workOrderType", "WorkOrderType") ?? readNumber(record, "type", "Type");
|
|
if (numeric != null && WORK_ORDER_TYPE_API_TO_FE[numeric]) {
|
|
return WORK_ORDER_TYPE_API_TO_FE[numeric] as WOType;
|
|
}
|
|
|
|
const raw = readString(
|
|
record,
|
|
"workOrderType",
|
|
"WorkOrderType",
|
|
"type",
|
|
"Type",
|
|
"woType",
|
|
"WoType",
|
|
);
|
|
if (DETAIL_WO_TYPES.has(raw)) {
|
|
return raw as WOType;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
export function readDetailDocStatus(record: Record<string, unknown>): CompletionDocStatus {
|
|
const numeric = readNumber(record, "docStatus", "DocStatus");
|
|
if (numeric === DOC_STATUS_API.Yes) return "Yes";
|
|
if (numeric === DOC_STATUS_API.No) return "No";
|
|
if (numeric === DOC_STATUS_API.NotNeeded) return "NN";
|
|
|
|
const nestedCompletion = asRecord(record.completion ?? record.Completion);
|
|
const nestedNumeric = readNumber(nestedCompletion, "docStatus", "DocStatus");
|
|
if (nestedNumeric === DOC_STATUS_API.Yes) return "Yes";
|
|
if (nestedNumeric === DOC_STATUS_API.No) return "No";
|
|
if (nestedNumeric === DOC_STATUS_API.NotNeeded) return "NN";
|
|
|
|
const raw = readString(record, "docStatus", "DocStatus", "completionDoc", "CompletionDoc");
|
|
if (raw === "Yes" || raw === "No" || raw === "NN") {
|
|
return raw;
|
|
}
|
|
if (raw === "NotNeeded") {
|
|
return "NN";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
export function readDetailMediaCount(record: Record<string, unknown>): number {
|
|
const explicit = readNumber(record, "mediaCount", "MediaCount");
|
|
if (explicit != null) {
|
|
return explicit;
|
|
}
|
|
const media = record.media ?? record.Media;
|
|
if (Array.isArray(media)) {
|
|
return media.length;
|
|
}
|
|
return 0;
|
|
}
|