Files
edr-platform/apps/edr-freight-web/portal/src/services/booking-form-data.ts

89 lines
2.4 KiB
TypeScript

import type { CreateBookingPayload } from "./bookings.service";
import { BOOKING_DOCS_SETTING, type BookingDocuments } from "@/pages/bookings/new-booking-form/schema";
function appendValue(formData: FormData, key: string, value: unknown) {
if (value === undefined || value === null) return;
if (typeof value === "boolean") {
formData.append(key, value ? "true" : "false");
return;
}
if (typeof value === "number") {
formData.append(key, String(value));
return;
}
if (typeof value === "string") {
formData.append(key, value);
return;
}
}
function appendContainers(
formData: FormData,
containers: NonNullable<CreateBookingPayload["containers"]>,
) {
containers.forEach((container, index) => {
formData.append(
`containers[${index}][containerTypeId]`,
container.containerTypeId,
);
formData.append(
`containers[${index}][quantity]`,
String(container.quantity),
);
formData.append(
`containers[${index}][vgmPerUnitTons]`,
String(container.vgmPerUnitTons),
);
});
}
function appendDocuments(
formData: FormData,
documents?: Record<string, File | File[] | null>,
) {
if (!documents) return;
for (const [key, fileOrFiles] of Object.entries(documents)) {
if (!fileOrFiles) continue;
if (Array.isArray(fileOrFiles)) {
for (const file of fileOrFiles) {
formData.append(key, file);
}
} else {
formData.append(key, fileOrFiles);
}
}
}
/** Flatten a booking payload (and optional document files) into multipart FormData. */
export function buildBookingFormData(
payload: Partial<CreateBookingPayload>,
documents?: BookingDocuments,
): FormData {
const formData = new FormData();
const skipKeys = new Set(["containers", "freightShapeValidation"]);
for (const [key, value] of Object.entries(payload)) {
if (skipKeys.has(key)) continue;
appendValue(formData, key, value);
}
if (payload.containers?.length) {
appendContainers(formData, payload.containers);
}
appendDocuments(formData, documents);
return formData;
}
/** Returns true when every required booking document field has a file attached. */
export function hasAllRequiredDocuments(
documents: BookingDocuments | undefined | null,
): boolean {
const docs = documents ?? {};
return BOOKING_DOCS_SETTING.fields.every((field) => {
const value = docs[field.fileKey];
if (Array.isArray(value)) return value.length > 0;
return Boolean(value);
});
}