183 lines
5.9 KiB
TypeScript
183 lines
5.9 KiB
TypeScript
import { EmpruntAvecMateriel } from '../repositories/emprunt.repository';
|
|
import { MaterielResponse, toMaterielResponse } from './materiel.dto';
|
|
import { AppError } from '../errors/app-error';
|
|
import { ETAT_CHECKLIST_ELEMENT, MODE_IDENTIFICATION } from '../models/enums';
|
|
|
|
export interface EmpruntResponse {
|
|
id: number;
|
|
dateEmprunt: Date;
|
|
dateRetourPrevue: Date;
|
|
dateRetourReelle: Date | null;
|
|
statut: string;
|
|
materiel: MaterielResponse;
|
|
checklistDepart: ChecklistElementResponse[];
|
|
}
|
|
|
|
export interface ChecklistElementResponse {
|
|
accessoireId: number | null;
|
|
nomElement: string;
|
|
etat: string;
|
|
quantiteConstatee: number;
|
|
}
|
|
|
|
export function toEmpruntResponse(emprunt: EmpruntAvecMateriel): EmpruntResponse {
|
|
const checklistDepart = emprunt.checklists.find((checklist) => checklist.type === 'DEPART');
|
|
|
|
return {
|
|
id: emprunt.id,
|
|
dateEmprunt: emprunt.dateEmprunt,
|
|
dateRetourPrevue: emprunt.dateRetourPrevue,
|
|
dateRetourReelle: emprunt.dateRetourReelle,
|
|
statut: emprunt.statut,
|
|
materiel: toMaterielResponse(emprunt.materiel),
|
|
checklistDepart:
|
|
checklistDepart?.elements.map((element) => ({
|
|
accessoireId: element.accessoireId,
|
|
nomElement: element.nomElement,
|
|
etat: element.etat,
|
|
quantiteConstatee: element.quantiteConstatee,
|
|
})) ?? [],
|
|
};
|
|
}
|
|
|
|
export interface ChecklistElementRequest {
|
|
accessoireId?: number;
|
|
nomElement: string;
|
|
etat: string;
|
|
quantiteConstatee: number;
|
|
commentaire?: string;
|
|
}
|
|
|
|
export interface CreerEmpruntRequest {
|
|
materielId: number;
|
|
posteEmpruntId: number;
|
|
modeIdentification: string;
|
|
commentaireDepart?: string;
|
|
elements: ChecklistElementRequest[];
|
|
}
|
|
|
|
function asObject(value: unknown, message: string): Record<string, unknown> {
|
|
if (typeof value !== 'object' || value === null) {
|
|
throw new AppError(400, message);
|
|
}
|
|
return value as Record<string, unknown>;
|
|
}
|
|
|
|
function asPositiveInt(value: unknown, champ: string): number {
|
|
if (typeof value !== 'number' || !Number.isInteger(value) || value <= 0) {
|
|
throw new AppError(400, `${champ} doit etre un entier positif`);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
function asIntOrZero(value: unknown, champ: string): number {
|
|
if (typeof value !== 'number' || !Number.isInteger(value) || value < 0) {
|
|
throw new AppError(400, `${champ} doit etre un entier positif ou nul`);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
function asEnum<T extends string>(value: unknown, autorisees: readonly T[], champ: string): T {
|
|
if (typeof value !== 'string' || !(autorisees as readonly string[]).includes(value)) {
|
|
throw new AppError(400, `${champ} invalide`);
|
|
}
|
|
return value as T;
|
|
}
|
|
|
|
function parseElement(value: unknown, index: number): ChecklistElementRequest {
|
|
const obj = asObject(value, `elements[${index}] invalide`);
|
|
|
|
if (typeof obj.nomElement !== 'string' || obj.nomElement.trim() === '') {
|
|
throw new AppError(400, `elements[${index}].nomElement requis`);
|
|
}
|
|
|
|
const element: ChecklistElementRequest = {
|
|
nomElement: obj.nomElement,
|
|
etat: asEnum(obj.etat, ETAT_CHECKLIST_ELEMENT, `elements[${index}].etat`),
|
|
quantiteConstatee: asIntOrZero(obj.quantiteConstatee, `elements[${index}].quantiteConstatee`),
|
|
};
|
|
|
|
if (obj.accessoireId !== undefined) {
|
|
element.accessoireId = asPositiveInt(obj.accessoireId, `elements[${index}].accessoireId`);
|
|
}
|
|
if (obj.commentaire !== undefined) {
|
|
if (typeof obj.commentaire !== 'string') {
|
|
throw new AppError(400, `elements[${index}].commentaire invalide`);
|
|
}
|
|
element.commentaire = obj.commentaire;
|
|
}
|
|
|
|
return element;
|
|
}
|
|
|
|
export function parseCreerEmpruntRequest(body: unknown): CreerEmpruntRequest {
|
|
const obj = asObject(body, 'Corps de requete invalide');
|
|
|
|
if (!Array.isArray(obj.elements) || obj.elements.length === 0) {
|
|
throw new AppError(400, 'La checklist de depart est obligatoire (RG11)');
|
|
}
|
|
|
|
const request: CreerEmpruntRequest = {
|
|
materielId: asPositiveInt(obj.materielId, 'materielId'),
|
|
posteEmpruntId: asPositiveInt(obj.posteEmpruntId, 'posteEmpruntId'),
|
|
modeIdentification: asEnum(obj.modeIdentification, MODE_IDENTIFICATION, 'modeIdentification'),
|
|
elements: obj.elements.map((element, index) => parseElement(element, index)),
|
|
};
|
|
|
|
if (obj.commentaireDepart !== undefined) {
|
|
if (typeof obj.commentaireDepart !== 'string') {
|
|
throw new AppError(400, 'commentaireDepart invalide');
|
|
}
|
|
request.commentaireDepart = obj.commentaireDepart;
|
|
}
|
|
|
|
return request;
|
|
}
|
|
|
|
export interface RestituerEmpruntRequest {
|
|
modeIdentification: string;
|
|
commentaireRetour?: string;
|
|
elements: ChecklistElementRequest[];
|
|
}
|
|
|
|
export interface SignalerTentativeRetourRequest {
|
|
nomElement: string;
|
|
etatInitial: string;
|
|
etatDemande: string;
|
|
}
|
|
|
|
export function parseSignalerTentativeRetourRequest(body: unknown): SignalerTentativeRetourRequest {
|
|
const obj = asObject(body, 'Corps de requete invalide');
|
|
if (typeof obj.nomElement !== 'string' || obj.nomElement.trim() === '') {
|
|
throw new AppError(400, 'nomElement requis');
|
|
}
|
|
|
|
return {
|
|
nomElement: obj.nomElement.trim(),
|
|
etatInitial: asEnum(obj.etatInitial, ETAT_CHECKLIST_ELEMENT, 'etatInitial'),
|
|
etatDemande: asEnum(obj.etatDemande, ETAT_CHECKLIST_ELEMENT, 'etatDemande'),
|
|
};
|
|
}
|
|
|
|
export function parseRestituerEmpruntRequest(body: unknown): RestituerEmpruntRequest {
|
|
const obj = asObject(body, 'Corps de requete invalide');
|
|
|
|
if (!Array.isArray(obj.elements) || obj.elements.length === 0) {
|
|
throw new AppError(400, 'La checklist de retour est obligatoire (RG16)');
|
|
}
|
|
|
|
const request: RestituerEmpruntRequest = {
|
|
modeIdentification: asEnum(obj.modeIdentification, MODE_IDENTIFICATION, 'modeIdentification'),
|
|
elements: obj.elements.map((element, index) => parseElement(element, index)),
|
|
};
|
|
|
|
if (obj.commentaireRetour !== undefined) {
|
|
if (typeof obj.commentaireRetour !== 'string') {
|
|
throw new AppError(400, 'commentaireRetour invalide');
|
|
}
|
|
request.commentaireRetour = obj.commentaireRetour;
|
|
}
|
|
|
|
return request;
|
|
}
|