refactor: prepare multi-machine inventory associations

This commit is contained in:
Matthieu
2025-10-08 16:23:49 +02:00
parent c23ba3a587
commit 48a74b74d7
19 changed files with 1166 additions and 297 deletions

View File

@@ -36,9 +36,15 @@ export class PiecesService {
constructor(private prisma: PrismaService) {}
async create(createPieceDto: CreatePieceDto) {
const requirementId = createPieceDto.typeMachinePieceRequirementId;
const requirementId = createPieceDto.typeMachinePieceRequirementId ?? null;
let machineId = createPieceDto.machineId;
if (requirementId && !createPieceDto.machineId) {
throw new BadRequestException(
'Un requirement ne peut pas être utilisé sans machine ciblée.',
);
}
let machineId = createPieceDto.machineId ?? null;
if (createPieceDto.composantId) {
const composantMachineId = await this.resolveMachineIdFromComposant(
@@ -51,59 +57,69 @@ export class PiecesService {
);
}
machineId = composantMachineId;
machineId = composantMachineId ?? machineId;
}
if (!machineId) {
throw new BadRequestException(
'Un machineId ou un composantId valide est requis pour créer une pièce.',
);
}
let requirement: PieceRequirementWithType | null = null;
const machine = await this.prisma.machine.findUnique({
where: { id: machineId },
include: {
typeMachine: {
include: {
pieceRequirements: {
include: {
typePiece: true,
if (machineId) {
const machine = await this.prisma.machine.findUnique({
where: { id: machineId },
include: {
typeMachine: {
include: {
pieceRequirements: {
include: {
typePiece: true,
},
},
},
},
},
},
});
});
if (!machine || !machine.typeMachine) {
throw new BadRequestException(
'La machine ciblée doit être associée à un type de machine pour valider les requirements.',
);
if (!machine || !machine.typeMachine) {
throw new BadRequestException(
'La machine ciblée doit être associée à un type de machine pour valider les requirements.',
);
}
if (requirementId) {
requirement =
(
machine.typeMachine.pieceRequirements as PieceRequirementWithType[]
).find((pieceRequirement) => pieceRequirement.id === requirementId) ??
null;
if (!requirement) {
throw new BadRequestException(
'Le requirement de pièce fourni ne correspond pas au squelette de la machine.',
);
}
if (
createPieceDto.typePieceId &&
createPieceDto.typePieceId !== requirement.typePieceId
) {
throw new BadRequestException(
'Le type de pièce fourni ne correspond pas au requirement pour cette machine.',
);
}
}
}
const requirement = machine.typeMachine.pieceRequirements.find(
(pieceRequirement) => pieceRequirement.id === requirementId,
);
const typePieceId =
createPieceDto.typePieceId ?? requirement?.typePieceId ?? null;
if (!requirement) {
throw new BadRequestException(
'Le requirement de pièce fourni ne correspond pas au squelette de la machine.',
);
}
if (
createPieceDto.typePieceId &&
createPieceDto.typePieceId !== requirement.typePieceId
) {
throw new BadRequestException(
'Le type de pièce fourni ne correspond pas au requirement pour cette machine.',
);
}
const data = {
...createPieceDto,
const data: Prisma.PieceUncheckedCreateInput = {
name: createPieceDto.name,
reference: createPieceDto.reference ?? null,
constructeurId: createPieceDto.constructeurId ?? null,
prix: createPieceDto.prix !== undefined ? createPieceDto.prix : null,
machineId,
typePieceId: createPieceDto.typePieceId ?? requirement.typePieceId,
composantId: createPieceDto.composantId ?? null,
typePieceId,
typeMachinePieceRequirementId: requirement?.id ?? requirementId ?? null,
};
const created = await this.prisma.piece.create({
@@ -113,10 +129,7 @@ export class PiecesService {
await this.applyPieceSkeleton({
pieceId: created.id,
typePiece:
(requirement.typePiece as PieceTypeWithSkeleton | null) ??
(created.typePiece as PieceTypeWithSkeleton | null) ??
null,
typePiece: created.typePiece as PieceTypeWithSkeleton | null,
});
return this.prisma.piece.findUnique({
@@ -217,8 +230,8 @@ export class PiecesService {
}
const skeleton = this.parsePieceSkeleton(
(typePiece as { pieceSkeleton?: Prisma.JsonValue | null } | null)?.
pieceSkeleton,
(typePiece as { pieceSkeleton?: Prisma.JsonValue | null } | null)
?.pieceSkeleton,
);
if (!skeleton) {
@@ -227,10 +240,7 @@ export class PiecesService {
const customFields = skeleton.customFields ?? [];
await this.ensurePieceCustomFieldDefinitions(
typePiece.id,
customFields,
);
await this.ensurePieceCustomFieldDefinitions(typePiece.id, customFields);
await this.createPieceCustomFieldValues(
pieceId,
@@ -255,7 +265,11 @@ export class PiecesService {
typePieceId: string,
customFields: PieceModelStructure['customFields'],
) {
if (!typePieceId || !Array.isArray(customFields) || customFields.length === 0) {
if (
!typePieceId ||
!Array.isArray(customFields) ||
customFields.length === 0
) {
return;
}
@@ -265,7 +279,10 @@ export class PiecesService {
});
const existingByName = new Map(
existing.map((field) => [this.normalizeIdentifier(field.name) ?? field.name, field.id]),
existing.map((field) => [
this.normalizeIdentifier(field.name) ?? field.name,
field.id,
]),
);
for (const field of customFields) {
@@ -306,7 +323,11 @@ export class PiecesService {
typePieceId: string,
customFields: PieceModelStructure['customFields'],
) {
if (!typePieceId || !Array.isArray(customFields) || customFields.length === 0) {
if (
!typePieceId ||
!Array.isArray(customFields) ||
customFields.length === 0
) {
return;
}
@@ -320,7 +341,10 @@ export class PiecesService {
}
const definitionMap = new Map(
definitions.map((field) => [this.normalizeIdentifier(field.name) ?? field.name, field.id]),
definitions.map((field) => [
this.normalizeIdentifier(field.name) ?? field.name,
field.id,
]),
);
const existingValues = await this.prisma.customFieldValue.findMany({
@@ -328,7 +352,9 @@ export class PiecesService {
select: { customFieldId: true },
});
const existingIds = new Set(existingValues.map((value) => value.customFieldId));
const existingIds = new Set(
existingValues.map((value) => value.customFieldId),
);
for (const field of customFields) {
if (!field) {
@@ -363,9 +389,7 @@ export class PiecesService {
const rawOptions = field?.options;
if (Array.isArray(rawOptions)) {
const normalized = rawOptions
.map((option) =>
typeof option === 'string' ? option.trim() : '',
)
.map((option) => (typeof option === 'string' ? option.trim() : ''))
.filter((option) => option.length > 0);
return normalized.length > 0 ? normalized : undefined;