import { CONSEGNA_CONSTRAINTS } from "./constraints"; import { buildResult, normalizePositiveInt, normalizeString, validateDate, validateEnum, validateMaxLength, validatePositiveInt, validateRequired, type FieldErrors, type ValidationResult, } from "./primitives"; export type StatoConsegna = (typeof CONSEGNA_CONSTRAINTS.stato.allowedValues)[number]; export interface ConsegnaInput { dataRitiro: string; dataConsegna: string; stato: StatoConsegna; chiaveConsegna: string; clienteId: number; } function todayAtMidnight(): Date { const today = new Date(); today.setHours(0, 0, 0, 0); return today; } function validateDateNotRetroactive( errors: FieldErrors, field: string, value: string, label: string ): void { if (!value || errors[field]) return; const parsed = new Date(`${value}T00:00:00`); if (parsed < todayAtMidnight()) { errors[field] = `${label} non può essere anteriore alla data odierna`; } } export function normalizeConsegnaInput(raw: Record): ConsegnaInput { return { dataRitiro: normalizeString(raw.dataRitiro), dataConsegna: normalizeString(raw.dataConsegna), stato: normalizeString(raw.stato || "in deposito") as StatoConsegna, chiaveConsegna: normalizeString(raw.chiaveConsegna).toUpperCase(), clienteId: normalizePositiveInt(raw.clienteId), }; } function validateConsegnaFields( raw: Record, data: ConsegnaInput, errors: FieldErrors, options: { requireAll: boolean } ): void { if (options.requireAll || "dataRitiro" in raw) { validateRequired(errors, "dataRitiro", data.dataRitiro, "Data ritiro obbligatoria"); validateDate(errors, "dataRitiro", data.dataRitiro, "Data ritiro"); validateDateNotRetroactive(errors, "dataRitiro", data.dataRitiro, "Data ritiro"); } if (options.requireAll || "dataConsegna" in raw) { validateRequired( errors, "dataConsegna", data.dataConsegna, "Data consegna obbligatoria" ); validateDate(errors, "dataConsegna", data.dataConsegna, "Data consegna"); validateDateNotRetroactive(errors, "dataConsegna", data.dataConsegna, "Data consegna"); } if (options.requireAll || "stato" in raw) { validateRequired(errors, "stato", data.stato, "Stato obbligatorio"); validateEnum( errors, "stato", data.stato, CONSEGNA_CONSTRAINTS.stato.allowedValues, "Stato" ); } if (options.requireAll || "chiaveConsegna" in raw) { validateRequired( errors, "chiaveConsegna", data.chiaveConsegna, "Chiave consegna obbligatoria" ); validateMaxLength( errors, "chiaveConsegna", data.chiaveConsegna, CONSEGNA_CONSTRAINTS.chiaveConsegna.maxLength, "Chiave consegna" ); } if (options.requireAll || "clienteId" in raw) { validatePositiveInt(errors, "clienteId", data.clienteId, "Cliente", options.requireAll); } } export function validateConsegnaCreate( raw: Record ): ValidationResult { const data = normalizeConsegnaInput(raw); const errors: FieldErrors = {}; validateConsegnaFields(raw, data, errors, { requireAll: true }); return buildResult(data, errors); } export function validateConsegnaUpdate( raw: Record ): ValidationResult> { const errors: FieldErrors = {}; const data: Partial = {}; if ("dataRitiro" in raw) { data.dataRitiro = normalizeString(raw.dataRitiro); validateRequired(errors, "dataRitiro", data.dataRitiro, "Data ritiro obbligatoria"); validateDate(errors, "dataRitiro", data.dataRitiro, "Data ritiro"); validateDateNotRetroactive(errors, "dataRitiro", data.dataRitiro, "Data ritiro"); } if ("dataConsegna" in raw) { data.dataConsegna = normalizeString(raw.dataConsegna); validateRequired( errors, "dataConsegna", data.dataConsegna, "Data consegna obbligatoria" ); validateDate(errors, "dataConsegna", data.dataConsegna, "Data consegna"); validateDateNotRetroactive(errors, "dataConsegna", data.dataConsegna, "Data consegna"); } if ("stato" in raw) { data.stato = normalizeString(raw.stato) as StatoConsegna; validateRequired(errors, "stato", data.stato, "Stato obbligatorio"); validateEnum( errors, "stato", data.stato, CONSEGNA_CONSTRAINTS.stato.allowedValues, "Stato" ); } if ("chiaveConsegna" in raw) { data.chiaveConsegna = normalizeString(raw.chiaveConsegna).toUpperCase(); validateRequired( errors, "chiaveConsegna", data.chiaveConsegna, "Chiave consegna obbligatoria" ); validateMaxLength( errors, "chiaveConsegna", data.chiaveConsegna, CONSEGNA_CONSTRAINTS.chiaveConsegna.maxLength, "Chiave consegna" ); } if ("clienteId" in raw) { data.clienteId = normalizePositiveInt(raw.clienteId); validatePositiveInt(errors, "clienteId", data.clienteId, "Cliente"); } if (Object.keys(data).length === 0) { errors._form = "Nessun campo da aggiornare"; } return buildResult(data, errors); }