import { Injectable } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; import { CreateMachineDto, UpdateMachineDto, ReconfigureMachineDto, MachineComponentSelectionDto, MachinePieceSelectionDto, } from '../shared/dto/machine.dto'; const TYPE_MACHINE_CONFIGURATION_INCLUDE = { customFields: true, componentRequirements: { include: { typeComposant: true, }, }, pieceRequirements: { include: { typePiece: true, }, }, }; const MACHINE_DEFAULT_INCLUDE = { site: true, typeMachine: { include: TYPE_MACHINE_CONFIGURATION_INCLUDE, }, constructeur: true, composants: { include: { typeComposant: true, composantModel: true, typeMachineComponentRequirement: { include: { typeComposant: true, }, }, sousComposants: true, customFieldValues: { include: { customField: true, }, }, constructeur: true, pieces: { include: { customFieldValues: { include: { customField: true, }, }, constructeur: true, pieceModel: true, typeMachinePieceRequirement: { include: { typePiece: true, }, }, }, }, }, }, pieces: { include: { customFieldValues: { include: { customField: true, }, }, constructeur: true, pieceModel: true, typeMachinePieceRequirement: { include: { typePiece: true, }, }, }, }, customFieldValues: { include: { customField: true, }, }, documents: true, }; @Injectable() export class MachinesService { constructor(private prisma: PrismaService) {} private async getTypeMachineConfiguration(typeMachineId: string) { const typeMachine = await this.prisma.typeMachine.findUnique({ where: { id: typeMachineId }, include: TYPE_MACHINE_CONFIGURATION_INCLUDE, }); if (!typeMachine) { throw new Error('Type de machine non trouvé'); } return typeMachine; } private async buildConfigurationContext( typeMachine: any, componentSelections: MachineComponentSelectionDto[], pieceSelections: MachinePieceSelectionDto[], ) { const componentRequirements = (Array.isArray(typeMachine.componentRequirements) ? typeMachine.componentRequirements : []) as any[]; const pieceRequirements = (Array.isArray(typeMachine.pieceRequirements) ? typeMachine.pieceRequirements : []) as any[]; const componentRequirementMap = new Map( componentRequirements.map((requirement: any) => [requirement.id, requirement]), ); const pieceRequirementMap = new Map( pieceRequirements.map((requirement: any) => [requirement.id, requirement]), ); const componentSelectionMap = new Map(); for (const selection of componentSelections) { const requirement = componentRequirementMap.get(selection.requirementId); if (!requirement) { throw new Error(`Sélection de composant invalide: requirementId=${selection.requirementId}`); } if (!componentSelectionMap.has(requirement.id)) { componentSelectionMap.set(requirement.id, []); } componentSelectionMap.get(requirement.id)!.push(selection); } const pieceSelectionMap = new Map(); for (const selection of pieceSelections) { const requirement = pieceRequirementMap.get(selection.requirementId); if (!requirement) { throw new Error(`Sélection de pièce invalide: requirementId=${selection.requirementId}`); } if (!pieceSelectionMap.has(requirement.id)) { pieceSelectionMap.set(requirement.id, []); } pieceSelectionMap.get(requirement.id)!.push(selection); } const componentModelIds = Array.from( new Set(componentSelections.map((selection) => selection.componentModelId).filter(Boolean)), ) as string[]; const componentModels = componentModelIds.length ? await this.prisma.composantModel.findMany({ where: { id: { in: componentModelIds } }, }) : []; const componentModelMap = new Map(componentModels.map((model) => [model.id, model])); const pieceModelIds = Array.from( new Set(pieceSelections.map((selection) => selection.pieceModelId).filter(Boolean)), ) as string[]; const pieceModels = pieceModelIds.length ? await this.prisma.pieceModel.findMany({ where: { id: { in: pieceModelIds } }, }) : []; const pieceModelMap = new Map(pieceModels.map((model) => [model.id, model])); for (const requirement of componentRequirements) { const selections = componentSelectionMap.get(requirement.id) ?? []; const min = requirement.minCount ?? (requirement.required ? 1 : 0); const max = requirement.maxCount ?? undefined; if (selections.length < min) { throw new Error( `Le groupe de composants "${requirement.label || requirement.typeComposant?.name || requirement.id}" requiert au moins ${min} sélection(s).`, ); } if (max !== undefined && selections.length > max) { throw new Error( `Le groupe de composants "${requirement.label || requirement.typeComposant?.name || requirement.id}" ne peut pas dépasser ${max} sélection(s).`, ); } if (!requirement.allowNewModels) { const missingModel = selections.find((selection) => !selection.componentModelId); if (missingModel) { throw new Error( `Le groupe de composants "${requirement.label || requirement.typeComposant?.name || requirement.id}" n'autorise que la sélection de modèles existants.`, ); } } } for (const requirement of pieceRequirements) { const selections = pieceSelectionMap.get(requirement.id) ?? []; const min = requirement.minCount ?? (requirement.required ? 1 : 0); const max = requirement.maxCount ?? undefined; if (selections.length < min) { throw new Error( `Le groupe de pièces "${requirement.label || requirement.typePiece?.name || requirement.id}" requiert au moins ${min} sélection(s).`, ); } if (max !== undefined && selections.length > max) { throw new Error( `Le groupe de pièces "${requirement.label || requirement.typePiece?.name || requirement.id}" ne peut pas dépasser ${max} sélection(s).`, ); } if (!requirement.allowNewModels) { const missingModel = selections.find((selection) => !selection.pieceModelId); if (missingModel) { throw new Error( `Le groupe de pièces "${requirement.label || requirement.typePiece?.name || requirement.id}" n'autorise que la sélection de modèles existants.`, ); } } } for (const selection of componentSelections) { if (!selection.componentModelId) { continue; } const model = componentModelMap.get(selection.componentModelId); if (!model) { throw new Error(`Modèle de composant introuvable: ${selection.componentModelId}`); } const requirement = componentRequirementMap.get(selection.requirementId); if (!requirement) { throw new Error(`Requirement de composant introuvable: ${selection.requirementId}`); } if (model.typeComposantId !== requirement.typeComposantId) { throw new Error( `Le modèle de composant "${model.name}" n'appartient pas au type de composant attendu pour ce groupe.`, ); } } for (const selection of pieceSelections) { if (!selection.pieceModelId) { continue; } const model = pieceModelMap.get(selection.pieceModelId); if (!model) { throw new Error(`Modèle de pièce introuvable: ${selection.pieceModelId}`); } const requirement = pieceRequirementMap.get(selection.requirementId); if (!requirement) { throw new Error(`Requirement de pièce introuvable: ${selection.requirementId}`); } if (model.typePieceId !== requirement.typePieceId) { throw new Error( `Le modèle de pièce "${model.name}" n'appartient pas au type de pièce attendu pour ce groupe.`, ); } } return { componentSelectionMap, pieceSelectionMap, componentModelMap, pieceModelMap, }; } async create(createMachineDto: CreateMachineDto) { const { componentSelections = [], pieceSelections = [], ...machineData } = createMachineDto; if (!machineData.typeMachineId) { throw new Error('typeMachineId est requis pour créer une machine à partir d\'un squelette.'); } const typeMachine = await this.getTypeMachineConfiguration(machineData.typeMachineId); const { componentSelectionMap, pieceSelectionMap, componentModelMap, pieceModelMap, } = await this.buildConfigurationContext(typeMachine, componentSelections, pieceSelections); const componentRequirements = (Array.isArray(typeMachine.componentRequirements) ? typeMachine.componentRequirements : []) as any[]; const pieceRequirements = (Array.isArray(typeMachine.pieceRequirements) ? typeMachine.pieceRequirements : []) as any[]; return this.prisma.$transaction(async (prisma) => { const machine = await prisma.machine.create({ data: machineData, include: { site: true, typeMachine: true, constructeur: true, }, }); if (componentRequirements.length > 0) { for (const requirement of componentRequirements) { const selections = componentSelectionMap.get(requirement.id) ?? []; for (const selection of selections) { const model = selection.componentModelId ? componentModelMap.get(selection.componentModelId) : undefined; const definition = this.normalizeComponentSelection(selection, requirement, model); await this.createComponentsFromType(prisma, machine.id, [definition]); } } } else { const legacyComponents = (typeMachine as any).components; if (legacyComponents) { await this.createComponentsFromType(prisma, machine.id, legacyComponents); } } if (pieceRequirements.length > 0) { for (const requirement of pieceRequirements) { const selections = pieceSelectionMap.get(requirement.id) ?? []; for (const selection of selections) { const model = selection.pieceModelId ? pieceModelMap.get(selection.pieceModelId) : undefined; const definition = this.normalizePieceSelection(selection, requirement, model); await this.createMachinePiecesFromType(prisma, machine.id, [definition]); } } } else { const legacyPieces = (typeMachine as any).machinePieces; if (legacyPieces) { await this.createMachinePiecesFromType(prisma, machine.id, legacyPieces); } } if (typeMachine.customFields && typeMachine.customFields.length > 0) { await this.createMachineCustomFieldsFromType(prisma, machine.id, typeMachine.customFields); } return prisma.machine.findUnique({ where: { id: machine.id }, include: MACHINE_DEFAULT_INCLUDE, }); }); } private cloneStructure(definition: any): any { if (definition === undefined || definition === null) { return {}; } try { return JSON.parse(JSON.stringify(definition)); } catch (error) { if (Array.isArray(definition)) { return definition.map((item) => this.cloneStructure(item)); } if (typeof definition === 'object') { return { ...definition }; } return definition; } } private normalizeComponentSelection( selection: MachineComponentSelectionDto, requirement: any, model?: any, ): any { const baseDefinition = selection.definition ?? (model?.structure ?? {}); const definition = this.cloneStructure(baseDefinition); const prepared: any = definition && typeof definition === 'object' && !Array.isArray(definition) ? definition : {}; prepared.name = prepared.name || model?.name || requirement?.typeComposant?.name || 'Composant'; prepared.reference = prepared.reference ?? model?.structure?.reference ?? ''; prepared.emplacement = prepared.emplacement ?? model?.structure?.emplacement ?? ''; prepared.prix = prepared.prix ?? model?.structure?.prix ?? null; prepared.customFields = Array.isArray(prepared.customFields) ? prepared.customFields : []; prepared.pieces = Array.isArray(prepared.pieces) ? prepared.pieces : prepared.pieces ? [prepared.pieces] : []; prepared.subComponents = Array.isArray(prepared.subComponents) ? prepared.subComponents : prepared.subComponents ? [prepared.subComponents] : []; prepared.typeComposantId = prepared.typeComposantId || requirement?.typeComposantId || model?.typeComposantId || null; prepared.__componentModelId = selection.componentModelId ?? null; prepared.__requirementId = requirement?.id ?? null; return prepared; } private normalizePieceSelection( selection: MachinePieceSelectionDto, requirement: any, model?: any, ): any { const baseDefinition = selection.definition ?? (model?.structure ?? {}); const definition = this.cloneStructure(baseDefinition); const prepared: any = definition && typeof definition === 'object' && !Array.isArray(definition) ? definition : {}; prepared.name = prepared.name || model?.name || requirement?.typePiece?.name || 'Pièce'; prepared.customFields = Array.isArray(prepared.customFields) ? prepared.customFields : []; prepared.typePieceId = prepared.typePieceId || requirement?.typePieceId || model?.typePieceId || null; prepared.__pieceModelId = selection.pieceModelId ?? null; prepared.__requirementId = requirement?.id ?? null; return prepared; } private async createComponentsFromType(prisma: any, machineId: string, components: any[], parentComposantId?: string) { for (const component of components) { if (!component || !component.name) continue; const customFields = Array.isArray(component.customFields) ? component.customFields : []; const componentPieces = Array.isArray(component.pieces) ? component.pieces : []; const subComponents = Array.isArray(component.subComponents) ? component.subComponents : []; const componentModelId = component.__componentModelId ?? null; const requirementId = component.__requirementId ?? null; const providedTypeComposantId = component.typeComposantId ?? (component.typeComposant && component.typeComposant.id ? component.typeComposant.id : null); let typeComposantId: string | null = providedTypeComposantId ?? null; if (!typeComposantId && customFields.length > 0) { let typeComposant = await prisma.typeComposant.findFirst({ where: { name: component.name }, }); if (!typeComposant) { typeComposant = await prisma.typeComposant.create({ data: { name: component.name, description: component.description || '', }, }); for (const customField of customFields) { await prisma.customField.create({ data: { name: customField.name, type: customField.type, required: customField.required || false, defaultValue: customField.defaultValue, options: customField.options || [], typeComposantId: typeComposant.id, }, }); } } typeComposantId = typeComposant.id; } const createdComposant = await prisma.composant.create({ data: { name: component.name, reference: component.reference || '', constructeurId: await this.resolveConstructeurId(prisma, component.constructeur), emplacement: component.emplacement || '', prix: component.prix ?? null, machineId, parentComposantId, typeComposantId, composantModelId: componentModelId, typeMachineComponentRequirementId: requirementId, }, }); if (typeComposantId) { const typeCustomFields = await prisma.customField.findMany({ where: { typeComposantId }, }); for (const customField of typeCustomFields) { const defaultValue = customFields.find((cf) => cf.name === customField.name)?.defaultValue || ''; await prisma.customFieldValue.create({ data: { value: defaultValue, customFieldId: customField.id, composantId: createdComposant.id, }, }); } } for (const piece of componentPieces) { if (!piece || !piece.name) continue; const pieceCustomFields = Array.isArray(piece.customFields) ? piece.customFields : []; const pieceModelId = piece.__pieceModelId ?? null; const pieceRequirementId = piece.__requirementId ?? null; const providedTypePieceId = piece.typePieceId ?? (piece.typePiece && piece.typePiece.id ? piece.typePiece.id : null); let typePieceId: string | null = providedTypePieceId ?? null; if (!typePieceId && pieceCustomFields.length > 0) { let typePiece = await prisma.typePiece.findFirst({ where: { name: piece.name }, }); if (!typePiece) { typePiece = await prisma.typePiece.create({ data: { name: piece.name, description: piece.description || '', }, }); for (const customField of pieceCustomFields) { await prisma.customField.create({ data: { name: customField.name, type: customField.type, required: customField.required || false, defaultValue: customField.defaultValue, options: customField.options || [], typePieceId: typePiece.id, }, }); } } typePieceId = typePiece.id; } const createdPiece = await prisma.piece.create({ data: { name: piece.name, reference: piece.reference || '', constructeurId: await this.resolveConstructeurId(prisma, piece.constructeur), emplacement: piece.emplacement || '', prix: piece.prix ?? null, composantId: createdComposant.id, typePieceId, pieceModelId, typeMachinePieceRequirementId: pieceRequirementId, }, }); if (typePieceId) { const typePieceCustomFields = await prisma.customField.findMany({ where: { typePieceId }, }); for (const customField of typePieceCustomFields) { const defaultValue = pieceCustomFields.find((cf) => cf.name === customField.name)?.defaultValue || ''; await prisma.customFieldValue.create({ data: { value: defaultValue, customFieldId: customField.id, pieceId: createdPiece.id, }, }); } } } if (subComponents.length > 0) { await this.createComponentsFromType(prisma, machineId, subComponents, createdComposant.id); } } } private async createMachinePiecesFromType(prisma: any, machineId: string, machinePieces: any[]) { for (const piece of machinePieces) { if (!piece || !piece.name) continue; const customFields = Array.isArray(piece.customFields) ? piece.customFields : []; const pieceModelId = piece.__pieceModelId ?? null; const requirementId = piece.__requirementId ?? null; const providedTypePieceId = piece.typePieceId ?? (piece.typePiece && piece.typePiece.id ? piece.typePiece.id : null); let typePieceId: string | null = providedTypePieceId ?? null; if (!typePieceId && customFields.length > 0) { let typePiece = await prisma.typePiece.findFirst({ where: { name: piece.name }, }); if (!typePiece) { typePiece = await prisma.typePiece.create({ data: { name: piece.name, description: piece.description || '', }, }); for (const customField of customFields) { await prisma.customField.create({ data: { name: customField.name, type: customField.type, required: customField.required || false, defaultValue: customField.defaultValue, options: customField.options || [], typePieceId: typePiece.id, }, }); } } typePieceId = typePiece.id; } const createdPiece = await prisma.piece.create({ data: { name: piece.name, reference: piece.reference || '', constructeurId: await this.resolveConstructeurId(prisma, piece.constructeur), emplacement: piece.emplacement || '', prix: piece.prix ?? null, machineId, typePieceId, pieceModelId, typeMachinePieceRequirementId: requirementId, }, }); if (typePieceId) { const typePieceCustomFields = await prisma.customField.findMany({ where: { typePieceId }, }); for (const customField of typePieceCustomFields) { const defaultValue = customFields.find((cf) => cf.name === customField.name)?.defaultValue || ''; await prisma.customFieldValue.create({ data: { value: defaultValue, customFieldId: customField.id, pieceId: createdPiece.id, }, }); } } else if (customFields.length > 0) { for (const customField of customFields) { const createdCustomField = await prisma.customField.create({ data: { name: customField.name, type: customField.type, required: customField.required || false, defaultValue: customField.defaultValue, options: customField.options || [], typePieceId: null, }, }); await prisma.customFieldValue.create({ data: { value: customField.defaultValue || '', customFieldId: createdCustomField.id, pieceId: createdPiece.id, }, }); } } } } private async createMachineCustomFieldsFromType(prisma: any, machineId: string, machineCustomFields: any[]) { for (const customField of machineCustomFields) { if (!customField || !customField.name) continue; // Créer le champ personnalisé pour la machine const createdCustomField = await prisma.customField.create({ data: { name: customField.name, type: customField.type, required: customField.required || false, defaultValue: customField.defaultValue, options: customField.options || [], typeMachineId: null, // Ce champ sera lié à la machine individuelle }, }); // Créer la valeur par défaut pour la machine await prisma.customFieldValue.create({ data: { value: customField.defaultValue || '', customFieldId: createdCustomField.id, machineId: machineId, }, }); } } async findAll() { return this.prisma.machine.findMany({ include: MACHINE_DEFAULT_INCLUDE, }); } async findOne(id: string) { return this.prisma.machine.findUnique({ where: { id }, include: MACHINE_DEFAULT_INCLUDE, }); } async reconfigure(id: string, reconfigureMachineDto: ReconfigureMachineDto) { const { componentSelections = [], pieceSelections = [], } = reconfigureMachineDto; const machine = await this.prisma.machine.findUnique({ where: { id }, include: { typeMachine: { include: TYPE_MACHINE_CONFIGURATION_INCLUDE, }, }, }); if (!machine) { throw new Error('Machine non trouvée'); } if (!machine.typeMachineId || !machine.typeMachine) { throw new Error('Impossible de reconfigurer une machine sans type de machine associé.'); } const typeMachine = machine.typeMachine; const { componentSelectionMap, pieceSelectionMap, componentModelMap, pieceModelMap, } = await this.buildConfigurationContext(typeMachine, componentSelections, pieceSelections); const componentRequirements = (Array.isArray(typeMachine.componentRequirements) ? typeMachine.componentRequirements : []) as any[]; const pieceRequirements = (Array.isArray(typeMachine.pieceRequirements) ? typeMachine.pieceRequirements : []) as any[]; return this.prisma.$transaction(async (prisma) => { await prisma.customFieldValue.deleteMany({ where: { OR: [ { composant: { machineId: id, typeMachineComponentRequirementId: { not: null }, }, }, { piece: { machineId: id, typeMachinePieceRequirementId: { not: null }, }, }, { piece: { composant: { machineId: id, typeMachineComponentRequirementId: { not: null }, }, }, }, ], }, }); await prisma.piece.deleteMany({ where: { machineId: id, typeMachinePieceRequirementId: { not: null }, }, }); await prisma.composant.deleteMany({ where: { machineId: id, typeMachineComponentRequirementId: { not: null }, }, }); if (componentRequirements.length > 0) { for (const requirement of componentRequirements) { const selections = componentSelectionMap.get(requirement.id) ?? []; for (const selection of selections) { const model = selection.componentModelId ? componentModelMap.get(selection.componentModelId) : undefined; const definition = this.normalizeComponentSelection(selection, requirement, model); await this.createComponentsFromType(prisma, id, [definition]); } } } else { const legacyComponents = (typeMachine as any).components; if (legacyComponents) { await this.createComponentsFromType(prisma, id, legacyComponents); } } if (pieceRequirements.length > 0) { for (const requirement of pieceRequirements) { const selections = pieceSelectionMap.get(requirement.id) ?? []; for (const selection of selections) { const model = selection.pieceModelId ? pieceModelMap.get(selection.pieceModelId) : undefined; const definition = this.normalizePieceSelection(selection, requirement, model); await this.createMachinePiecesFromType(prisma, id, [definition]); } } } else { const legacyPieces = (typeMachine as any).machinePieces; if (legacyPieces) { await this.createMachinePiecesFromType(prisma, id, legacyPieces); } } return prisma.machine.findUnique({ where: { id }, include: MACHINE_DEFAULT_INCLUDE, }); }); } async update(id: string, updateMachineDto: UpdateMachineDto) { return this.prisma.machine.update({ where: { id }, data: updateMachineDto, include: MACHINE_DEFAULT_INCLUDE, }); } private async resolveConstructeurId(prisma: any, rawName?: string) { if (!rawName) return null const name = String(rawName).trim() if (!name) return null const existing = await prisma.constructeur.findFirst({ where: { name: { equals: name, mode: 'insensitive', }, }, }) if (existing) return existing.id const created = await prisma.constructeur.create({ data: { name }, }) return created.id } async remove(id: string) { // Vérifier que la machine existe const machine = await this.prisma.machine.findUnique({ where: { id }, include: { composants: true, pieces: true, documents: true, customFieldValues: true, }, }); if (!machine) { throw new Error('Machine non trouvée'); } // Supprimer la machine et tous ses éléments associés en cascade return await this.prisma.$transaction(async (prisma) => { // Supprimer les valeurs de champs personnalisés if (machine.customFieldValues.length > 0) { await prisma.customFieldValue.deleteMany({ where: { machineId: id }, }); } // Supprimer les documents if (machine.documents.length > 0) { await prisma.document.deleteMany({ where: { machineId: id }, }); } // Supprimer les pièces (sera fait en cascade via la relation) if (machine.pieces.length > 0) { await prisma.piece.deleteMany({ where: { machineId: id }, }); } // Supprimer les composants (sera fait en cascade via la relation) if (machine.composants.length > 0) { await prisma.composant.deleteMany({ where: { machineId: id }, }); } // Supprimer la machine return await prisma.machine.delete({ where: { id }, }); }); } // Méthode pour ajouter les champs personnalisés manquants aux composants et pièces existants async addMissingCustomFields(machineId: string) { const machine = await this.prisma.machine.findUnique({ where: { id: machineId }, include: { typeMachine: true, composants: { include: { pieces: true, }, }, pieces: true, }, }); if (!machine || !machine.typeMachine) { throw new Error('Machine ou type de machine non trouvé'); } const typeMachine = machine.typeMachine as any; const components = typeMachine.components || []; const machinePieces = typeMachine.machinePieces || []; const machineCustomFields = typeMachine.customFields || []; // Traiter les champs personnalisés de la machine if (machineCustomFields && machineCustomFields.length > 0) { for (const customField of machineCustomFields) { const existingValue = await this.prisma.customFieldValue.findFirst({ where: { machineId: machineId, customField: { name: customField.name, }, }, include: { customField: true, }, }); if (!existingValue) { // Créer le champ personnalisé pour la machine const createdCustomField = await this.prisma.customField.create({ data: { name: customField.name, type: customField.type, required: customField.required || false, defaultValue: customField.defaultValue, options: customField.options || [], typeMachineId: null, // Ce champ sera lié à la machine individuelle }, }); // Créer la valeur par défaut pour la machine await this.prisma.customFieldValue.create({ data: { value: customField.defaultValue || '', customFieldId: createdCustomField.id, machineId: machineId, }, }); } } } // Traiter les composants existants for (const component of machine.composants) { const typeComponent = components.find((c: any) => c.name === component.name); if (typeComponent && typeComponent.customFields && typeComponent.customFields.length > 0) { // Créer le type de composant s'il n'existe pas let typeComposant = await this.prisma.typeComposant.findFirst({ where: { name: component.name }, }); if (!typeComposant) { typeComposant = await this.prisma.typeComposant.create({ data: { name: component.name, description: typeComponent.description || '', }, }); } // Créer les champs personnalisés pour le type de composant for (const customField of typeComponent.customFields) { const existingField = await this.prisma.customField.findFirst({ where: { name: customField.name, typeComposantId: typeComposant.id, }, }); if (!existingField) { await this.prisma.customField.create({ data: { name: customField.name, type: customField.type, required: customField.required || false, defaultValue: customField.defaultValue, options: customField.options || [], typeComposantId: typeComposant.id, }, }); } } // Mettre à jour le composant avec le type await this.prisma.composant.update({ where: { id: component.id }, data: { typeComposantId: typeComposant.id }, }); // Créer les valeurs des champs personnalisés pour le composant const customFields = await this.prisma.customField.findMany({ where: { typeComposantId: typeComposant.id }, }); for (const customField of customFields) { const existingValue = await this.prisma.customFieldValue.findFirst({ where: { customFieldId: customField.id, composantId: component.id, }, }); if (!existingValue) { const defaultValue = typeComponent.customFields.find((cf: any) => cf.name === customField.name)?.defaultValue || ''; await this.prisma.customFieldValue.create({ data: { value: defaultValue, customFieldId: customField.id, composantId: component.id, }, }); } } // Traiter les pièces du composant for (const piece of component.pieces) { const typePiece = typeComponent.pieces?.find((p: any) => p.name === piece.name); if (typePiece && typePiece.customFields && typePiece.customFields.length > 0) { // Créer le type de pièce s'il n'existe pas let typePieceEntity = await this.prisma.typePiece.findFirst({ where: { name: piece.name }, }); if (!typePieceEntity) { typePieceEntity = await this.prisma.typePiece.create({ data: { name: piece.name, description: typePiece.description || '', }, }); } // Créer les champs personnalisés pour le type de pièce for (const customField of typePiece.customFields) { const existingField = await this.prisma.customField.findFirst({ where: { name: customField.name, typePieceId: typePieceEntity.id, }, }); if (!existingField) { await this.prisma.customField.create({ data: { name: customField.name, type: customField.type, required: customField.required || false, defaultValue: customField.defaultValue, options: customField.options || [], typePieceId: typePieceEntity.id, }, }); } } // Mettre à jour la pièce avec le type await this.prisma.piece.update({ where: { id: piece.id }, data: { typePieceId: typePieceEntity.id }, }); // Créer les valeurs des champs personnalisés pour la pièce const customFields = await this.prisma.customField.findMany({ where: { typePieceId: typePieceEntity.id }, }); for (const customField of customFields) { const existingValue = await this.prisma.customFieldValue.findFirst({ where: { customFieldId: customField.id, pieceId: piece.id, }, }); if (!existingValue) { const defaultValue = typePiece.customFields.find((cf: any) => cf.name === customField.name)?.defaultValue || ''; await this.prisma.customFieldValue.create({ data: { value: defaultValue, customFieldId: customField.id, pieceId: piece.id, }, }); } } } } } } // Traiter les pièces de machine for (const piece of machine.pieces) { const typePiece = machinePieces.find((p: any) => p.name === piece.name); if (typePiece && typePiece.customFields && typePiece.customFields.length > 0) { // Créer le type de pièce s'il n'existe pas let typePieceEntity = await this.prisma.typePiece.findFirst({ where: { name: piece.name }, }); if (!typePieceEntity) { typePieceEntity = await this.prisma.typePiece.create({ data: { name: piece.name, description: typePiece.description || '', }, }); } // Créer les champs personnalisés pour le type de pièce for (const customField of typePiece.customFields) { const existingField = await this.prisma.customField.findFirst({ where: { name: customField.name, typePieceId: typePieceEntity.id, }, }); if (!existingField) { await this.prisma.customField.create({ data: { name: customField.name, type: customField.type, required: customField.required || false, defaultValue: customField.defaultValue, options: customField.options || [], typePieceId: typePieceEntity.id, }, }); } } // Mettre à jour la pièce avec le type await this.prisma.piece.update({ where: { id: piece.id }, data: { typePieceId: typePieceEntity.id }, }); // Créer les valeurs des champs personnalisés pour la pièce const customFields = await this.prisma.customField.findMany({ where: { typePieceId: typePieceEntity.id }, }); for (const customField of customFields) { const existingValue = await this.prisma.customFieldValue.findFirst({ where: { customFieldId: customField.id, pieceId: piece.id, }, }); if (!existingValue) { const defaultValue = typePiece.customFields.find((cf: any) => cf.name === customField.name)?.defaultValue || ''; await this.prisma.customFieldValue.create({ data: { value: defaultValue, customFieldId: customField.id, pieceId: piece.id, }, }); } } } } return this.findOne(machineId); } }