From 2a13974125aec5363dde1004c1bbb85a55d1e5ff Mon Sep 17 00:00:00 2001 From: MatthieuTD <39524319+MatthieuTD@users.noreply.github.com> Date: Wed, 1 Oct 2025 16:44:20 +0200 Subject: [PATCH] Revamp demo seed dataset with detailed machines --- scripts/seed-industrial-data.ts | 3425 +++++++++++++++++++++---------- 1 file changed, 2376 insertions(+), 1049 deletions(-) diff --git a/scripts/seed-industrial-data.ts b/scripts/seed-industrial-data.ts index e979a1b..4999677 100644 --- a/scripts/seed-industrial-data.ts +++ b/scripts/seed-industrial-data.ts @@ -4,7 +4,7 @@ const prisma = new PrismaClient(); type CustomFieldSpec = { name: string; - type: 'string' | 'number' | 'boolean' | 'date'; + type: 'string' | 'number' | 'boolean' | 'date' | 'select'; required?: boolean; defaultValue?: string; options?: string[]; @@ -70,6 +70,50 @@ type ComponentInstance = { children?: ComponentInstance[]; }; +type TypeMachineDefinition = { + code: string; + name: string; + description: string; + category: string; + maintenanceFrequency: string; + specifications: Prisma.InputJsonValue; + customFields: CustomFieldSpec[]; + componentRequirements: { + label: string; + typeCode: string; + minCount: number; + maxCount?: number; + required: boolean; + }[]; + pieceRequirements?: { + label: string; + typeCode: string; + minCount: number; + maxCount?: number; + required: boolean; + }[]; +}; + +type MachineBuildSpec = { + code: string; + typeMachineCode: string; + name: string; + reference: string; + prix: string; + constructeurKey: string; + customFieldValues: Record; + components: ComponentInstance[]; + sparePieces?: (ComponentPieceInstance & { requirementLabel?: string })[]; +}; + +type TypeMachineRecord = Prisma.TypeMachineGetPayload<{ + include: { + customFields: true; + componentRequirements: true; + pieceRequirements: true; + }; +}>; + const componentTypeDefinitions: ComponentTypeDefinition[] = [ { code: 'bucket-elevator', @@ -79,7 +123,12 @@ const componentTypeDefinitions: ComponentTypeDefinition[] = [ customFields: [ { name: 'Débit nominal (t/h)', type: 'number', required: true }, { name: 'Hauteur de levage (m)', type: 'number' }, - { name: 'Matériau des godets', type: 'string', defaultValue: 'Acier galvanisé' }, + { + name: 'Matériau des godets', + type: 'select', + defaultValue: 'Acier galvanisé', + options: ['Acier galvanisé', 'Acier inoxydable', 'Polypropylène renforcé'], + }, ], }, { @@ -90,7 +139,12 @@ const componentTypeDefinitions: ComponentTypeDefinition[] = [ customFields: [ { name: 'Largeur de bande (mm)', type: 'number', required: true }, { name: 'Longueur (m)', type: 'number' }, - { name: 'Type de bande', type: 'string', defaultValue: 'Caoutchouc anti-statique' }, + { + name: 'Type de bande', + type: 'select', + defaultValue: 'Caoutchouc anti-statique', + options: ['Caoutchouc anti-statique', 'PVC alimentaire', 'Polyuréthane grain'], + }, ], }, { @@ -101,18 +155,28 @@ const componentTypeDefinitions: ComponentTypeDefinition[] = [ customFields: [ { name: 'Capacité de tri (t/h)', type: 'number', required: true }, { name: 'Fréquence de vibration (Hz)', type: 'number' }, - { name: 'Type de plateau', type: 'string', defaultValue: 'Acier perforé' }, + { + name: 'Type de plateau', + type: 'select', + defaultValue: 'Acier perforé', + options: ['Acier perforé', 'Inox poli', 'Tôle aluminium'], + }, ], }, { code: 'grain-dryer', name: 'Séchoir à grains', description: - 'Séchoir continu assurant la réduction du taux d\'humidité des céréales.', + "Séchoir continu assurant la réduction du taux d'humidité des céréales.", customFields: [ { name: 'Capacité sèche (t/h)', type: 'number', required: true }, { name: "Nombre d'étages", type: 'number' }, - { name: "Type d'énergie", type: 'string', defaultValue: 'Gaz naturel' }, + { + name: "Type d'énergie", + type: 'select', + defaultValue: 'Gaz naturel', + options: ['Gaz naturel', 'Biomasse', 'Fioul léger'], + }, ], }, { @@ -132,17 +196,33 @@ const componentTypeDefinitions: ComponentTypeDefinition[] = [ customFields: [ { name: 'Capacité de pesée (kg)', type: 'number', required: true }, { name: 'Précision (%)', type: 'number' }, - { name: 'Nombre de capteurs', type: 'number', defaultValue: '4' }, + { + name: 'Mode de vidange', + type: 'select', + defaultValue: 'Trappe motorisée', + options: ['Trappe motorisée', 'Vis doseuse', 'Vanne guillotine'], + }, ], }, { code: 'control-panel', name: 'Armoire de contrôle', - description: 'Armoire électrique pilotant l\'ensemble de la ligne de triage.', + description: "Armoire électrique pilotant l'ensemble de la ligne de triage.", customFields: [ - { name: 'Automate principal', type: 'string', required: true }, + { + name: 'Automate principal', + type: 'select', + required: true, + defaultValue: 'Schneider Modicon M340', + options: ['Schneider Modicon M340', 'Siemens S7-1500', 'Schneider Modicon M221'], + }, { name: 'Année de mise à jour', type: 'number' }, - { name: "Indice de protection", type: 'string', defaultValue: 'IP55' }, + { + name: "Indice de protection", + type: 'select', + defaultValue: 'IP55', + options: ['IP55', 'IP65', 'IP54'], + }, ], }, { @@ -153,7 +233,12 @@ const componentTypeDefinitions: ComponentTypeDefinition[] = [ customFields: [ { name: 'Capacité de levage (t)', type: 'number', required: true }, { name: 'Hauteur de levage (m)', type: 'number' }, - { name: "Type d'attache", type: 'string', defaultValue: 'Fourches FEM' }, + { + name: "Type d'attache", + type: 'select', + defaultValue: 'Fourches FEM', + options: ['Fourches FEM', 'Godet céréales', 'Pince big-bag'], + }, ], }, { @@ -162,8 +247,18 @@ const componentTypeDefinitions: ComponentTypeDefinition[] = [ description: 'Module de combustion alimentant le séchoir en air chaud.', customFields: [ { name: 'Puissance thermique (kW)', type: 'number', required: true }, - { name: 'Type de carburant', type: 'string', defaultValue: 'Gaz naturel' }, - { name: "Système d'allumage", type: 'string', defaultValue: 'Double électrode' }, + { + name: 'Type de carburant', + type: 'select', + defaultValue: 'Gaz naturel', + options: ['Gaz naturel', 'Biométhane', 'Fioul léger'], + }, + { + name: "Système d'allumage", + type: 'select', + defaultValue: 'Double électrode', + options: ['Double électrode', 'Brûleur pilote', 'Allumeur électronique'], + }, ], }, { @@ -172,21 +267,176 @@ const componentTypeDefinitions: ComponentTypeDefinition[] = [ description: 'Filtre à cyclone captant les poussières en sortie de séchoir.', customFields: [ { name: 'Efficacité de filtration (%)', type: 'number', required: true }, - { name: 'Type de média filtrant', type: 'string' }, + { + name: 'Type de média filtrant', + type: 'select', + options: ['Polyester', 'Fibre de verre', 'Polypropylène'], + defaultValue: 'Polyester', + }, { name: 'Nombre de cartouches', type: 'number' }, ], }, + { + code: 'motor-drive', + name: 'Groupe moteur', + description: 'Motorisation asynchrone montée sur bride pour entraînements industriels.', + customFields: [ + { name: 'Puissance nominale (kW)', type: 'number', required: true }, + { + name: 'Classe énergétique', + type: 'select', + defaultValue: 'IE3', + options: ['IE2', 'IE3', 'IE4'], + }, + { + name: "Indice de protection", + type: 'select', + defaultValue: 'IP55', + options: ['IP55', 'IP65', 'IP23'], + }, + ], + }, + { + code: 'gearbox-assembly', + name: 'Train réducteur', + description: 'Réducteur de vitesse pour entraînement lourd.', + customFields: [ + { + name: 'Rapport de réduction', + type: 'select', + defaultValue: '1:28', + options: ['1:28', '1:24', '1:18'], + }, + { name: 'Couple nominal (Nm)', type: 'number' }, + { + name: 'Type de montage', + type: 'select', + options: ['À pattes', 'À bride', 'Sur arbre'], + defaultValue: 'À bride', + }, + ], + }, + { + code: 'hydraulic-power-pack', + name: 'Groupe hydraulique', + description: "Groupe hydraulique alimentant les vérins d'un chariot télescopique.", + customFields: [ + { name: 'Débit nominal (l/min)', type: 'number', required: true }, + { name: 'Pression max (bar)', type: 'number' }, + { + name: 'Type de pompe', + type: 'select', + options: ['Piston axial', 'Palette', 'Engrenages'], + defaultValue: 'Piston axial', + }, + ], + }, + { + code: 'ventilation-fan', + name: 'Ventilateur process', + description: "Ventilateur d'extraction pour séchage et dépoussiérage.", + customFields: [ + { name: 'Débit (m³/h)', type: 'number', required: true }, + { + name: 'Type de roue', + type: 'select', + options: ['Axiale', 'Centrifuge', 'Mixte'], + defaultValue: 'Centrifuge', + }, + { name: 'Vitesse nominale (rpm)', type: 'number' }, + ], + }, ]; const pieceTypeDefinitions: PieceTypeDefinition[] = [ { - code: 'electric-motor', - name: 'Moteur électrique', - description: 'Motorisation asynchrone IE3 pour entraînements industriels.', + code: 'hex-screw', + name: 'Vis hexagonale', + description: 'Visserie pour assemblages mécaniques.', customFields: [ - { name: 'Puissance nominale (kW)', type: 'number', required: true }, - { name: 'Tension (V)', type: 'number' }, - { name: "Indice de protection", type: 'string', defaultValue: 'IP55' }, + { name: 'Diamètre (mm)', type: 'number', required: true }, + { name: 'Longueur (mm)', type: 'number', required: true }, + { + name: 'Classe acier', + type: 'select', + options: ['8.8', '10.9', '12.9'], + defaultValue: '8.8', + }, + ], + }, + { + code: 'lock-washer', + name: 'Rondelle Grower', + description: 'Rondelle anti-desserrage.', + customFields: [ + { name: 'Diamètre (mm)', type: 'number', required: true }, + { + name: 'Finition', + type: 'select', + options: ['Zinguée', 'Inox', 'Noire'], + defaultValue: 'Zinguée', + }, + ], + }, + { + code: 'flat-gasket', + name: 'Joint plat', + description: 'Joint pour brides et trappes de maintenance.', + customFields: [ + { + name: 'Matière', + type: 'select', + options: ['NBR', 'PTFE', 'Fibre compressée'], + defaultValue: 'NBR', + }, + { name: 'Épaisseur (mm)', type: 'number', required: true }, + ], + }, + { + code: 'drive-belt', + name: 'Courroie', + description: 'Courroie transporteuse ou de transmission.', + customFields: [ + { name: 'Largeur (mm)', type: 'number', required: true }, + { + name: 'Matériau', + type: 'select', + options: ['Caoutchouc nitrile', 'Polyuréthane', 'PVC'], + defaultValue: 'Caoutchouc nitrile', + }, + ], + }, + { + code: 'roller-bearing', + name: 'Roulement', + description: 'Roulement à semelle ou palier.', + customFields: [ + { + name: 'Série', + type: 'select', + options: ['UCP', 'UCFL', 'UCT'], + defaultValue: 'UCP', + }, + { + name: "Type d'étanchéité", + type: 'select', + options: ['2RS', 'ZZ', 'Ouvert'], + defaultValue: '2RS', + }, + ], + }, + { + code: 'filter-cartridge', + name: 'Cartouche filtrante', + description: 'Cartouche filtrante pour dépoussiérage.', + customFields: [ + { + name: 'Classe de filtration', + type: 'select', + options: ['G4', 'F7', 'M5'], + defaultValue: 'G4', + }, + { name: 'Dimensions (mm)', type: 'string', required: true }, ], }, { @@ -194,7 +444,12 @@ const pieceTypeDefinitions: PieceTypeDefinition[] = [ name: 'Capteur de vitesse', description: 'Capteur inductif contrôlant la vitesse des organes rotatifs.', customFields: [ - { name: 'Type de sortie', type: 'string', required: true }, + { + name: 'Type de sortie', + type: 'select', + options: ['PNP 4-20 mA', 'PNP tout ou rien', 'NPN'], + defaultValue: 'PNP 4-20 mA', + }, { name: 'Plage de mesure (rpm)', type: 'number' }, ], }, @@ -203,62 +458,27 @@ const pieceTypeDefinitions: PieceTypeDefinition[] = [ name: 'Sonde de température', description: 'Sonde PT100 pour la surveillance thermique du séchoir.', customFields: [ + { + name: 'Type de sonde', + type: 'select', + options: ['PT100 classe A', 'PT100 classe B', 'Thermocouple K'], + defaultValue: 'PT100 classe A', + }, { name: 'Plage de mesure (°C)', type: 'string', required: true }, - { name: 'Type de sonde', type: 'string', defaultValue: 'PT100' }, ], }, { - code: 'belt', - name: 'Bande transporteuse', - description: 'Bande caoutchouc renforcée pour convoyeurs et élévateurs.', - customFields: [ - { name: 'Largeur (mm)', type: 'number', required: true }, - { name: 'Matériau', type: 'string' }, - ], - }, - { - code: 'bearing', - name: 'Roulement', - description: 'Roulement à semelle pour transmissions tournantes.', - customFields: [ - { name: 'Référence fournisseur', type: 'string', required: true }, - { name: "Type d'étanchéité", type: 'string' }, - ], - }, - { - code: 'gearbox', - name: 'Réducteur', - description: 'Réducteur de vitesse pour entraînement lourd.', - customFields: [ - { name: 'Rapport de réduction', type: 'string', required: true }, - { name: 'Couple nominal (Nm)', type: 'number' }, - ], - }, - { - code: 'air-filter', - name: 'Filtre à air', - description: 'Cartouche filtrante pour dépoussiérage.', - customFields: [ - { name: 'Classe de filtration', type: 'string', required: true }, - { name: 'Dimensions (mm)', type: 'string' }, - ], - }, - { - code: 'hydraulic-pump', - name: 'Pompe hydraulique', - description: 'Pompe hydraulique pour chariot télescopique.', - customFields: [ - { name: 'Débit nominal (l/min)', type: 'number', required: true }, - { name: 'Pression max (bar)', type: 'number' }, - ], - }, - { - code: 'control-module', + code: 'plc-module', name: 'Module automate', - description: 'Module PLC assurant le contrôle de ligne.', + description: 'Module PLC assurant des entrées/sorties pour la ligne.', customFields: [ { name: "Nombre d'E/S", type: 'number', required: true }, - { name: 'Version firmware', type: 'string' }, + { + name: 'Version firmware', + type: 'select', + options: ['V2.8', 'V2.9', 'V3.0'], + defaultValue: 'V2.9', + }, ], }, { @@ -267,48 +487,187 @@ const pieceTypeDefinitions: PieceTypeDefinition[] = [ description: 'Capteur de pesage pour benne peseuse.', customFields: [ { name: 'Capacité (kg)', type: 'number', required: true }, - { name: 'Sensibilité (mV/V)', type: 'string' }, + { + name: 'Type de connexion', + type: 'select', + options: ['Câble 4 fils', 'Câble 6 fils', 'Connecteur M12'], + defaultValue: 'Câble 6 fils', + }, + ], + }, + { + code: 'fuse-cartridge', + name: 'Fusible industriel', + description: 'Fusible de protection pour armoire électrique.', + customFields: [ + { name: 'Calibre (A)', type: 'number', required: true }, + { + name: 'Type de fusible', + type: 'select', + options: ['gG', 'aM', 'gR'], + defaultValue: 'gG', + }, ], }, ]; const pieceModelDefinitions: PieceModelDefinition[] = [ { - code: 'motor-75kw', - name: 'Moteur IE3 75 kW', - description: 'Moteur principal pour élévateur haute capacité.', - typeCode: 'electric-motor', + code: 'screw-m10x60', + name: 'Vis M10x60 10.9', + description: 'Vis hexagonale classe 10.9 longueur 60 mm.', + typeCode: 'hex-screw', structure: { defaultCustomFieldValues: { - 'Puissance nominale (kW)': '75', - 'Tension (V)': '400', - "Indice de protection": 'IP55', + 'Diamètre (mm)': '10', + 'Longueur (mm)': '60', + 'Classe acier': '10.9', }, }, }, { - code: 'motor-45kw', - name: 'Moteur IE3 45 kW', - description: 'Motorisation pour convoyeur ou ventilateur.', - typeCode: 'electric-motor', + code: 'screw-m12x80', + name: 'Vis M12x80 8.8', + description: 'Vis hexagonale galvanisée 80 mm.', + typeCode: 'hex-screw', structure: { defaultCustomFieldValues: { - 'Puissance nominale (kW)': '45', - 'Tension (V)': '400', - "Indice de protection": 'IP55', + 'Diamètre (mm)': '12', + 'Longueur (mm)': '80', + 'Classe acier': '8.8', }, }, }, { - code: 'motor-18kw', - name: 'Moteur IE3 18,5 kW', - description: 'Motorisation pour vis sans fin ou table densimétrique.', - typeCode: 'electric-motor', + code: 'screw-m8x30', + name: 'Vis M8x30 inox', + description: 'Visserie inox pour équipements alimentaires.', + typeCode: 'hex-screw', structure: { defaultCustomFieldValues: { - 'Puissance nominale (kW)': '18.5', - 'Tension (V)': '400', - "Indice de protection": 'IP55', + 'Diamètre (mm)': '8', + 'Longueur (mm)': '30', + 'Classe acier': '8.8', + }, + }, + }, + { + code: 'washer-grower-10', + name: 'Rondelle Grower Ø10', + description: 'Rondelle Grower zinguée diamètre 10 mm.', + typeCode: 'lock-washer', + structure: { + defaultCustomFieldValues: { + 'Diamètre (mm)': '10', + 'Finition': 'Zinguée', + }, + }, + }, + { + code: 'washer-grower-12', + name: 'Rondelle Grower Ø12 inox', + description: 'Rondelle Grower inox diamètre 12 mm.', + typeCode: 'lock-washer', + structure: { + defaultCustomFieldValues: { + 'Diamètre (mm)': '12', + 'Finition': 'Inox', + }, + }, + }, + { + code: 'gasket-nbr-5', + name: 'Joint NBR 5 mm', + description: 'Joint plat NBR épaisseur 5 mm.', + typeCode: 'flat-gasket', + structure: { + defaultCustomFieldValues: { + Matière: 'NBR', + 'Épaisseur (mm)': '5', + }, + }, + }, + { + code: 'gasket-ptfe-3', + name: 'Joint PTFE 3 mm', + description: 'Joint plat PTFE pour brides haute température.', + typeCode: 'flat-gasket', + structure: { + defaultCustomFieldValues: { + Matière: 'PTFE', + 'Épaisseur (mm)': '3', + }, + }, + }, + { + code: 'belt-hd-800', + name: 'Courroie renforcée 800 mm', + description: 'Bande transporteuse HD 800 mm.', + typeCode: 'drive-belt', + structure: { + defaultCustomFieldValues: { + 'Largeur (mm)': '800', + Matériau: 'Caoutchouc nitrile', + }, + }, + }, + { + code: 'belt-hd-650', + name: 'Courroie renforcée 650 mm', + description: 'Bande transporteuse 650 mm.', + typeCode: 'drive-belt', + structure: { + defaultCustomFieldValues: { + 'Largeur (mm)': '650', + Matériau: 'Polyuréthane', + }, + }, + }, + { + code: 'bearing-ucp210', + name: 'Palier UCP210', + description: 'Palier fonte UCP210 graissable.', + typeCode: 'roller-bearing', + structure: { + defaultCustomFieldValues: { + Série: 'UCP', + "Type d'étanchéité": '2RS', + }, + }, + }, + { + code: 'bearing-ucfl207', + name: 'Palier UCFL207', + description: 'Palier à semelle UCFL207.', + typeCode: 'roller-bearing', + structure: { + defaultCustomFieldValues: { + Série: 'UCFL', + "Type d'étanchéité": 'ZZ', + }, + }, + }, + { + code: 'filter-g4-500', + name: 'Cartouche G4 500x500', + description: 'Cartouche filtrante G4.', + typeCode: 'filter-cartridge', + structure: { + defaultCustomFieldValues: { + 'Classe de filtration': 'G4', + 'Dimensions (mm)': '500x500x50', + }, + }, + }, + { + code: 'filter-f7-610', + name: 'Cartouche F7 610x610', + description: 'Cartouche haute efficacité F7.', + typeCode: 'filter-cartridge', + structure: { + defaultCustomFieldValues: { + 'Classe de filtration': 'F7', + 'Dimensions (mm)': '610x610x75', }, }, }, @@ -320,99 +679,63 @@ const pieceModelDefinitions: PieceModelDefinition[] = [ structure: { defaultCustomFieldValues: { 'Type de sortie': 'PNP 4-20 mA', - 'Plage de mesure (rpm)': '0-1200', + 'Plage de mesure (rpm)': '1200', + }, + }, + }, + { + code: 'sensor-speed-m18', + name: 'Capteur inductif M18', + description: 'Capteur de vitesse M18 robuste.', + typeCode: 'speed-sensor', + structure: { + defaultCustomFieldValues: { + 'Type de sortie': 'PNP tout ou rien', + 'Plage de mesure (rpm)': '900', }, }, }, { code: 'temp-probe-pt100', - name: 'Sonde PT100 classe A', - description: 'Sonde PT100 pour mesure d\'air chaud.', + name: 'Sonde PT100 250 mm', + description: 'Sonde PT100 pour mesure d’air chaud.', typeCode: 'temperature-probe', structure: { defaultCustomFieldValues: { - 'Plage de mesure (°C)': '0-250', 'Type de sonde': 'PT100 classe A', + 'Plage de mesure (°C)': '0-250', }, }, }, { - code: 'belt-hd-800', - name: 'Bande renforcée 800 mm', - description: 'Bande HD 800 mm anti-statique.', - typeCode: 'belt', + code: 'temp-probe-pt100-short', + name: 'Sonde PT100 150 mm', + description: 'Sonde PT100 courte pour supervision.', + typeCode: 'temperature-probe', structure: { defaultCustomFieldValues: { - 'Largeur (mm)': '800', - 'Matériau': 'Caoutchouc nitrile', + 'Type de sonde': 'PT100 classe B', + 'Plage de mesure (°C)': '0-200', }, }, }, { - code: 'belt-hd-650', - name: 'Bande renforcée 650 mm', - description: 'Bande HD 650 mm résistante à l\'abrasion.', - typeCode: 'belt', + code: 'plc-module-s71200', + name: 'Module PLC S7-1200', + description: 'Module d’entrées/sorties Siemens S7-1200.', + typeCode: 'plc-module', structure: { defaultCustomFieldValues: { - 'Largeur (mm)': '650', - 'Matériau': 'Caoutchouc anti-abrasion', + "Nombre d'E/S": '24', + 'Version firmware': 'V2.8', }, }, }, { - code: 'bearing-ucp210', - name: 'Roulement UCP210', - description: 'Roulement à semelle graissable.', - typeCode: 'bearing', - structure: { - defaultCustomFieldValues: { - 'Référence fournisseur': 'SKF UCP210', - "Type d'étanchéité": '2RS', - }, - }, - }, - { - code: 'gearbox-flender', - name: 'Réducteur Flender FZ', - description: 'Réducteur coaxial pour charge lourde.', - typeCode: 'gearbox', - structure: { - defaultCustomFieldValues: { - 'Rapport de réduction': '1:28', - 'Couple nominal (Nm)': '3200', - }, - }, - }, - { - code: 'filter-g4-500', - name: 'Filtre G4 500x500', - description: 'Cartouche filtrante G4 pour dépoussiérage.', - typeCode: 'air-filter', - structure: { - defaultCustomFieldValues: { - 'Classe de filtration': 'G4', - 'Dimensions (mm)': '500x500x50', - }, - }, - }, - { - code: 'hydraulic-pump-pvh98', - name: 'Pompe hydraulique PVH98', - description: 'Pompe haute pression pour Manitou.', - typeCode: 'hydraulic-pump', - structure: { - defaultCustomFieldValues: { - 'Débit nominal (l/min)': '160', - 'Pression max (bar)': '320', - }, - }, - }, - { - code: 'plc-module-siemens-1512', - name: 'Module PLC Siemens 1512', - description: 'Automate Siemens S7-1500 1512SP.', - typeCode: 'control-module', + code: 'plc-module-m340', + name: 'Module PLC Modicon M340', + description: 'Module entrée/sortie Modicon M340.', + typeCode: 'plc-module', structure: { defaultCustomFieldValues: { "Nombre d'E/S": '32', @@ -428,7 +751,43 @@ const pieceModelDefinitions: PieceModelDefinition[] = [ structure: { defaultCustomFieldValues: { 'Capacité (kg)': '5000', - 'Sensibilité (mV/V)': '2.0', + 'Type de connexion': 'Câble 6 fils', + }, + }, + }, + { + code: 'load-cell-10t', + name: 'Capteur de pesage 10 t', + description: 'Capteur de pesage haute capacité.', + typeCode: 'load-cell', + structure: { + defaultCustomFieldValues: { + 'Capacité (kg)': '10000', + 'Type de connexion': 'Connecteur M12', + }, + }, + }, + { + code: 'fuse-gg-25a', + name: 'Fusible gG 25A', + description: 'Fusible gG calibre 25A.', + typeCode: 'fuse-cartridge', + structure: { + defaultCustomFieldValues: { + 'Calibre (A)': '25', + 'Type de fusible': 'gG', + }, + }, + }, + { + code: 'fuse-gg-40a', + name: 'Fusible gG 40A', + description: 'Fusible gG calibre 40A.', + typeCode: 'fuse-cartridge', + structure: { + defaultCustomFieldValues: { + 'Calibre (A)': '40', + 'Type de fusible': 'gG', }, }, }, @@ -441,18 +800,42 @@ const componentModelDefinitions: ComponentModelDefinition[] = [ description: 'Élévateur à godets 120 t/h, 38 m.', typeCode: 'bucket-elevator', structure: { - defaultPieces: [ - { modelCode: 'motor-75kw', role: 'Motorisation principale' }, - { modelCode: 'gearbox-flender', role: 'Réducteur' }, - { modelCode: 'belt-hd-800', role: 'Courroie élévateur' }, - { modelCode: 'sensor-speed-m12', role: 'Capteur vitesse tête' }, - { modelCode: 'bearing-ucp210', role: 'Paliers de tête' }, - ], recommendedCustomFields: { 'Débit nominal (t/h)': '120', 'Hauteur de levage (m)': '38', 'Matériau des godets': 'Acier galvanisé', }, + defaultPieces: [ + { modelCode: 'belt-hd-800', role: 'Courroie élévatrice' }, + { modelCode: 'screw-m12x80', role: 'Fixations tête' }, + { modelCode: 'washer-grower-12', role: 'Sécurité visserie' }, + ], + subComponents: [ + { modelCode: 'motor-drive-75', role: 'Groupe moteur' }, + { modelCode: 'gearbox-flender', role: 'Train réducteur' }, + ], + }, + }, + { + code: 'elevator-z320', + name: 'Élévateur Z320', + description: 'Élévateur à godets 95 t/h, 32 m.', + typeCode: 'bucket-elevator', + structure: { + recommendedCustomFields: { + 'Débit nominal (t/h)': '95', + 'Hauteur de levage (m)': '32', + 'Matériau des godets': 'Polypropylène renforcé', + }, + defaultPieces: [ + { modelCode: 'belt-hd-650', role: 'Courroie élévatrice' }, + { modelCode: 'screw-m10x60', role: 'Fixations pied' }, + { modelCode: 'washer-grower-10', role: 'Sécurité pied' }, + ], + subComponents: [ + { modelCode: 'motor-drive-55', role: 'Groupe moteur' }, + { modelCode: 'gearbox-bonfiglioli', role: 'Réducteur' }, + ], }, }, { @@ -461,16 +844,40 @@ const componentModelDefinitions: ComponentModelDefinition[] = [ description: 'Convoyeur à bande 800 mm, 18 mètres.', typeCode: 'belt-conveyor', structure: { - defaultPieces: [ - { modelCode: 'motor-45kw', role: 'Motorisation' }, - { modelCode: 'belt-hd-800', role: 'Bande transporteuse' }, - { modelCode: 'sensor-speed-m12', role: 'Capteur rotation' }, - ], recommendedCustomFields: { 'Largeur de bande (mm)': '800', 'Longueur (m)': '18', 'Type de bande': 'Caoutchouc anti-statique', }, + defaultPieces: [ + { modelCode: 'belt-hd-800', role: 'Bande transporteuse' }, + { modelCode: 'screw-m10x60', role: 'Kit boulonnerie' }, + ], + subComponents: [ + { modelCode: 'motor-drive-45', role: 'Motorisation' }, + { modelCode: 'gearbox-bonfiglioli', role: 'Réducteur' }, + ], + }, + }, + { + code: 'conveyor-25m', + name: 'Convoyeur bande 25 m', + description: 'Convoyeur à bande 650 mm, 25 mètres.', + typeCode: 'belt-conveyor', + structure: { + recommendedCustomFields: { + 'Largeur de bande (mm)': '650', + 'Longueur (m)': '25', + 'Type de bande': 'PVC alimentaire', + }, + defaultPieces: [ + { modelCode: 'belt-hd-650', role: 'Bande transporteuse' }, + { modelCode: 'screw-m8x30', role: 'Kit tendeur' }, + ], + subComponents: [ + { modelCode: 'motor-drive-37', role: 'Motorisation' }, + { modelCode: 'gearbox-bonfiglioli', role: 'Réducteur' }, + ], }, }, { @@ -479,15 +886,34 @@ const componentModelDefinitions: ComponentModelDefinition[] = [ description: 'Table densimétrique haute précision 120 t/h.', typeCode: 'gravity-separator', structure: { - defaultPieces: [ - { modelCode: 'motor-18kw', role: 'Motorisation vibration' }, - { modelCode: 'sensor-speed-m12', role: 'Capteur vibration' }, - ], recommendedCustomFields: { 'Capacité de tri (t/h)': '120', 'Fréquence de vibration (Hz)': '45', 'Type de plateau': 'Acier perforé', }, + defaultPieces: [ + { modelCode: 'sensor-speed-m12', role: 'Capteur vibration' }, + { modelCode: 'screw-m8x30', role: 'Fixation plateau' }, + ], + subComponents: [{ modelCode: 'motor-drive-18', role: 'Moteur vibration' }], + }, + }, + { + code: 'gravity-table-compact', + name: 'Table densimétrique Compact 80', + description: 'Table densimétrique compacte 80 t/h.', + typeCode: 'gravity-separator', + structure: { + recommendedCustomFields: { + 'Capacité de tri (t/h)': '80', + 'Fréquence de vibration (Hz)': '40', + 'Type de plateau': 'Inox poli', + }, + defaultPieces: [ + { modelCode: 'sensor-speed-m18', role: 'Capteur vibration' }, + { modelCode: 'screw-m8x30', role: 'Fixation plateau' }, + ], + subComponents: [{ modelCode: 'motor-drive-15', role: 'Moteur vibration' }], }, }, { @@ -496,19 +922,36 @@ const componentModelDefinitions: ComponentModelDefinition[] = [ description: 'Séchoir continu 6 étages avec récupération de chaleur.', typeCode: 'grain-dryer', structure: { - defaultPieces: [ - { modelCode: 'motor-45kw', role: 'Ventilateur principal' }, - { modelCode: 'temp-probe-pt100', role: 'Sonde air chaud' }, - ], - subComponents: [ - { modelCode: 'burner-module-3mw', role: 'Brûleur gaz principal' }, - { modelCode: 'dust-filter-fc12', role: 'Filtre cyclone' }, - ], recommendedCustomFields: { 'Capacité sèche (t/h)': '60', "Nombre d'étages": '6', "Type d'énergie": 'Gaz naturel', }, + defaultPieces: [{ modelCode: 'gasket-nbr-5', role: 'Joint trappe inspection' }], + subComponents: [ + { modelCode: 'burner-module-3mw', role: 'Brûleur principal' }, + { modelCode: 'dust-filter-fc12', role: 'Filtre cyclone' }, + { modelCode: 'ventilation-fan-axial90', role: 'Ventilateur extraction' }, + ], + }, + }, + { + code: 'grain-dryer-cd4', + name: 'Séchoir continu CD-4', + description: 'Séchoir continu 4 étages compact.', + typeCode: 'grain-dryer', + structure: { + recommendedCustomFields: { + 'Capacité sèche (t/h)': '40', + "Nombre d'étages": '4', + "Type d'énergie": 'Biomasse', + }, + defaultPieces: [{ modelCode: 'gasket-ptfe-3', role: 'Joint trappe inspection' }], + subComponents: [ + { modelCode: 'burner-module-2mw', role: 'Brûleur biomasse' }, + { modelCode: 'dust-filter-fc8', role: 'Filtre cyclone' }, + { modelCode: 'ventilation-fan-axial60', role: 'Ventilateur extraction' }, + ], }, }, { @@ -517,15 +960,34 @@ const componentModelDefinitions: ComponentModelDefinition[] = [ description: 'Vis de reprise diamètre 200 mm.', typeCode: 'screw-conveyor', structure: { - defaultPieces: [ - { modelCode: 'motor-18kw', role: 'Motorisation vis' }, - { modelCode: 'bearing-ucp210', role: 'Paliers supports' }, - ], recommendedCustomFields: { 'Diamètre vis (mm)': '200', 'Inclinaison (°)': '12', 'Vitesse (rpm)': '140', }, + defaultPieces: [ + { modelCode: 'screw-m12x80', role: 'Fixations palier' }, + { modelCode: 'bearing-ucp210', role: 'Paliers supports' }, + ], + subComponents: [{ modelCode: 'motor-drive-18', role: 'Motorisation vis' }], + }, + }, + { + code: 'screw-conveyor-v160', + name: 'Vis sans fin V160', + description: 'Vis de transfert diamètre 160 mm.', + typeCode: 'screw-conveyor', + structure: { + recommendedCustomFields: { + 'Diamètre vis (mm)': '160', + 'Inclinaison (°)': '8', + 'Vitesse (rpm)': '110', + }, + defaultPieces: [ + { modelCode: 'screw-m10x60', role: 'Fixations palier' }, + { modelCode: 'bearing-ucfl207', role: 'Paliers supports' }, + ], + subComponents: [{ modelCode: 'motor-drive-15', role: 'Motorisation vis' }], }, }, { @@ -534,15 +996,32 @@ const componentModelDefinitions: ComponentModelDefinition[] = [ description: 'Benna peseuse 5 tonnes pour chargement camion.', typeCode: 'weigh-hopper', structure: { - defaultPieces: [ - { modelCode: 'load-cell-5t', role: 'Capteurs de pesage' }, - { modelCode: 'sensor-speed-m12', role: 'Capteur rotation trappe' }, - ], recommendedCustomFields: { 'Capacité de pesée (kg)': '5000', 'Précision (%)': '0.5', - 'Nombre de capteurs': '4', + 'Mode de vidange': 'Trappe motorisée', }, + defaultPieces: [ + { modelCode: 'load-cell-5t', role: 'Capteurs de pesage' }, + { modelCode: 'screw-m10x60', role: 'Kit fixation capteur' }, + ], + }, + }, + { + code: 'weigh-hopper-bp3', + name: 'Benna peseuse BP-3', + description: 'Benna peseuse 3 tonnes pour chargement big-bags.', + typeCode: 'weigh-hopper', + structure: { + recommendedCustomFields: { + 'Capacité de pesée (kg)': '3000', + 'Précision (%)': '0.3', + 'Mode de vidange': 'Vis doseuse', + }, + defaultPieces: [ + { modelCode: 'load-cell-5t', role: 'Capteurs de pesage' }, + { modelCode: 'screw-m8x30', role: 'Kit fixation capteur' }, + ], }, }, { @@ -551,15 +1030,33 @@ const componentModelDefinitions: ComponentModelDefinition[] = [ description: 'Armoire Schneider Electric avec automate M340.', typeCode: 'control-panel', structure: { - defaultPieces: [ - { modelCode: 'plc-module-siemens-1512', role: 'Automate principal' }, - { modelCode: 'sensor-speed-m12', role: 'Entrée vitesse générale' }, - ], recommendedCustomFields: { 'Automate principal': 'Schneider Modicon M340', 'Année de mise à jour': '2023', "Indice de protection": 'IP55', }, + defaultPieces: [ + { modelCode: 'plc-module-m340', role: 'Automate principal' }, + { modelCode: 'fuse-gg-25a', role: 'Protection alimentation' }, + { modelCode: 'sensor-speed-m12', role: 'Entrée vitesse ligne' }, + ], + }, + }, + { + code: 'control-panel-s7', + name: 'Armoire Siemens S7-1500', + description: 'Armoire Siemens S7-1500 pour ligne secondaire.', + typeCode: 'control-panel', + structure: { + recommendedCustomFields: { + 'Automate principal': 'Siemens S7-1500', + 'Année de mise à jour': '2022', + "Indice de protection": 'IP65', + }, + defaultPieces: [ + { modelCode: 'plc-module-s71200', role: 'Module E/S' }, + { modelCode: 'fuse-gg-40a', role: 'Protection puissance' }, + ], }, }, { @@ -568,14 +1065,26 @@ const componentModelDefinitions: ComponentModelDefinition[] = [ description: 'Brûleur gaz modulant 3 MW pour séchoir.', typeCode: 'burner-module', structure: { - defaultPieces: [ - { modelCode: 'temp-probe-pt100', role: 'Sonde sécurité flamme' }, - ], recommendedCustomFields: { 'Puissance thermique (kW)': '3000', 'Type de carburant': 'Gaz naturel', "Système d'allumage": 'Double électrode', }, + defaultPieces: [{ modelCode: 'temp-probe-pt100', role: 'Sonde sécurité flamme' }], + }, + }, + { + code: 'burner-module-2mw', + name: 'Brûleur biomasse 2 MW', + description: 'Brûleur biomasse 2 MW pour séchoir compact.', + typeCode: 'burner-module', + structure: { + recommendedCustomFields: { + 'Puissance thermique (kW)': '2000', + 'Type de carburant': 'Biomasse', + "Système d'allumage": 'Brûleur pilote', + }, + defaultPieces: [{ modelCode: 'temp-probe-pt100-short', role: 'Sonde sécurité flamme' }], }, }, { @@ -584,14 +1093,26 @@ const componentModelDefinitions: ComponentModelDefinition[] = [ description: 'Filtre cyclone avec cartouches G4.', typeCode: 'dust-filter', structure: { - defaultPieces: [ - { modelCode: 'filter-g4-500', role: 'Cartouche filtrante' }, - ], recommendedCustomFields: { 'Efficacité de filtration (%)': '95', 'Type de média filtrant': 'Polyester', 'Nombre de cartouches': '6', }, + defaultPieces: [{ modelCode: 'filter-g4-500', role: 'Cartouche filtrante' }], + }, + }, + { + code: 'dust-filter-fc8', + name: 'Filtre cyclone FC-8', + description: 'Filtre cyclone compact avec cartouches F7.', + typeCode: 'dust-filter', + structure: { + recommendedCustomFields: { + 'Efficacité de filtration (%)': '90', + 'Type de média filtrant': 'Fibre de verre', + 'Nombre de cartouches': '4', + }, + defaultPieces: [{ modelCode: 'filter-f7-610', role: 'Cartouche filtrante' }], }, }, { @@ -600,15 +1121,223 @@ const componentModelDefinitions: ComponentModelDefinition[] = [ description: 'Chariot télescopique Manitou 4 t.', typeCode: 'telehandler', structure: { - defaultPieces: [ - { modelCode: 'hydraulic-pump-pvh98', role: 'Pompe hydraulique principale' }, - { modelCode: 'bearing-ucp210', role: 'Articulation de flèche' }, - ], recommendedCustomFields: { 'Capacité de levage (t)': '4', 'Hauteur de levage (m)': '9.6', "Type d'attache": 'Fourches FEM', }, + subComponents: [ + { modelCode: 'motor-drive-75', role: 'Moteur principal' }, + { modelCode: 'hydraulic-pack-pvh98', role: 'Groupe hydraulique' }, + ], + defaultPieces: [ + { modelCode: 'gasket-nbr-5', role: 'Joint clapet' }, + { modelCode: 'fuse-gg-40a', role: 'Protection cabine' }, + ], + }, + }, + { + code: 'telehandler-mlt840', + name: 'Manitou MLT 840', + description: 'Chariot télescopique Manitou 3,5 t.', + typeCode: 'telehandler', + structure: { + recommendedCustomFields: { + 'Capacité de levage (t)': '3.5', + 'Hauteur de levage (m)': '7.5', + "Type d'attache": 'Godet céréales', + }, + subComponents: [ + { modelCode: 'motor-drive-55', role: 'Moteur principal' }, + { modelCode: 'hydraulic-pack-vg80', role: 'Groupe hydraulique' }, + ], + defaultPieces: [{ modelCode: 'fuse-gg-25a', role: 'Protection cabine' }], + }, + }, + { + code: 'motor-drive-75', + name: 'Groupe moteur IE3 75 kW', + description: 'Moteur IE3 75 kW montage à bride.', + typeCode: 'motor-drive', + structure: { + recommendedCustomFields: { + 'Puissance nominale (kW)': '75', + 'Classe énergétique': 'IE3', + "Indice de protection": 'IP55', + }, + defaultPieces: [ + { modelCode: 'screw-m12x80', role: 'Fixations bride' }, + { modelCode: 'washer-grower-12', role: 'Sécurité bride' }, + ], + }, + }, + { + code: 'motor-drive-55', + name: 'Groupe moteur IE3 55 kW', + description: 'Moteur IE3 55 kW.', + typeCode: 'motor-drive', + structure: { + recommendedCustomFields: { + 'Puissance nominale (kW)': '55', + 'Classe énergétique': 'IE3', + "Indice de protection": 'IP55', + }, + defaultPieces: [ + { modelCode: 'screw-m12x80', role: 'Fixations bride' }, + { modelCode: 'washer-grower-12', role: 'Sécurité bride' }, + ], + }, + }, + { + code: 'motor-drive-45', + name: 'Groupe moteur IE3 45 kW', + description: 'Moteur IE3 45 kW pour convoyeurs.', + typeCode: 'motor-drive', + structure: { + recommendedCustomFields: { + 'Puissance nominale (kW)': '45', + 'Classe énergétique': 'IE3', + "Indice de protection": 'IP55', + }, + defaultPieces: [ + { modelCode: 'screw-m10x60', role: 'Fixations bride' }, + { modelCode: 'washer-grower-10', role: 'Sécurité bride' }, + ], + }, + }, + { + code: 'motor-drive-37', + name: 'Groupe moteur IE3 37 kW', + description: 'Moteur IE3 37 kW pour convoyeur long.', + typeCode: 'motor-drive', + structure: { + recommendedCustomFields: { + 'Puissance nominale (kW)': '37', + 'Classe énergétique': 'IE3', + "Indice de protection": 'IP55', + }, + defaultPieces: [ + { modelCode: 'screw-m10x60', role: 'Fixations bride' }, + { modelCode: 'washer-grower-10', role: 'Sécurité bride' }, + ], + }, + }, + { + code: 'motor-drive-18', + name: 'Groupe moteur IE3 18,5 kW', + description: 'Moteur IE3 pour vis sans fin.', + typeCode: 'motor-drive', + structure: { + recommendedCustomFields: { + 'Puissance nominale (kW)': '18.5', + 'Classe énergétique': 'IE3', + "Indice de protection": 'IP55', + }, + defaultPieces: [ + { modelCode: 'screw-m10x60', role: 'Fixations bride' }, + { modelCode: 'washer-grower-10', role: 'Sécurité bride' }, + ], + }, + }, + { + code: 'motor-drive-15', + name: 'Groupe moteur IE3 15 kW', + description: 'Moteur IE3 pour équipements auxiliaires.', + typeCode: 'motor-drive', + structure: { + recommendedCustomFields: { + 'Puissance nominale (kW)': '15', + 'Classe énergétique': 'IE3', + "Indice de protection": 'IP55', + }, + defaultPieces: [ + { modelCode: 'screw-m8x30', role: 'Fixations bride' }, + { modelCode: 'washer-grower-10', role: 'Sécurité bride' }, + ], + }, + }, + { + code: 'gearbox-flender', + name: 'Réducteur Flender FZ', + description: 'Réducteur coaxial pour charge lourde.', + typeCode: 'gearbox-assembly', + structure: { + recommendedCustomFields: { + 'Rapport de réduction': '1:28', + 'Couple nominal (Nm)': '3200', + 'Type de montage': 'À bride', + }, + defaultPieces: [{ modelCode: 'gasket-nbr-5', role: 'Joint de bride' }], + }, + }, + { + code: 'gearbox-bonfiglioli', + name: 'Réducteur Bonfiglioli TA', + description: 'Réducteur orthogonal Bonfiglioli.', + typeCode: 'gearbox-assembly', + structure: { + recommendedCustomFields: { + 'Rapport de réduction': '1:24', + 'Couple nominal (Nm)': '2100', + 'Type de montage': 'Sur arbre', + }, + defaultPieces: [{ modelCode: 'gasket-ptfe-3', role: 'Joint de bride' }], + }, + }, + { + code: 'hydraulic-pack-pvh98', + name: 'Groupe hydraulique PVH98', + description: 'Groupe hydraulique 160 l/min.', + typeCode: 'hydraulic-power-pack', + structure: { + recommendedCustomFields: { + 'Débit nominal (l/min)': '160', + 'Pression max (bar)': '320', + 'Type de pompe': 'Piston axial', + }, + defaultPieces: [{ modelCode: 'gasket-nbr-5', role: 'Joint collecteur' }], + }, + }, + { + code: 'hydraulic-pack-vg80', + name: 'Groupe hydraulique VG80', + description: 'Groupe hydraulique 110 l/min.', + typeCode: 'hydraulic-power-pack', + structure: { + recommendedCustomFields: { + 'Débit nominal (l/min)': '110', + 'Pression max (bar)': '260', + 'Type de pompe': 'Engrenages', + }, + defaultPieces: [{ modelCode: 'gasket-ptfe-3', role: 'Joint collecteur' }], + }, + }, + { + code: 'ventilation-fan-axial90', + name: 'Ventilateur axial 90 kW', + description: 'Ventilateur axial 90 kW.', + typeCode: 'ventilation-fan', + structure: { + recommendedCustomFields: { + 'Débit (m³/h)': '48000', + 'Type de roue': 'Axiale', + 'Vitesse nominale (rpm)': '980', + }, + defaultPieces: [{ modelCode: 'screw-m12x80', role: 'Fixations châssis' }], + }, + }, + { + code: 'ventilation-fan-axial60', + name: 'Ventilateur axial 60 kW', + description: 'Ventilateur axial 60 kW compact.', + typeCode: 'ventilation-fan', + structure: { + recommendedCustomFields: { + 'Débit (m³/h)': '32000', + 'Type de roue': 'Axiale', + 'Vitesse nominale (rpm)': '1450', + }, + defaultPieces: [{ modelCode: 'screw-m10x60', role: 'Fixations châssis' }], }, }, ]; @@ -680,6 +1409,24 @@ const constructeurDefinitions: ConstructeurDefinition[] = [ email: 'industry.fr@siemens.com', phone: '+33 1 85 57 00 00', }, + { + key: 'bonfiglioli', + name: 'Bonfiglioli Riduttori', + email: 'sales@bonfiglioli.com', + phone: '+39 051 647 3111', + }, + { + key: 'agrifan', + name: 'AgriFan Ventilation', + email: 'contact@agrifan.fr', + phone: '+33 2 44 55 12 32', + }, + { + key: 'poclain', + name: 'Poclain Hydraulics', + email: 'support@poclain-hydraulics.com', + phone: '+33 3 44 31 74 00', + }, ]; async function clearDatabaseExceptSitesAndProfiles() { @@ -746,9 +1493,7 @@ async function createConstructeurs() { return Object.fromEntries(entries) as Record; } -function mapCustomFields( - fields: { id: string; name: string }[], -): Record { +function mapCustomFields(fields: { id: string; name: string }[]) { return fields.reduce>((acc, field) => { acc[field.name] = field.id; return acc; @@ -760,10 +1505,7 @@ async function createModelTypes() { const componentTypeEntries: [ string, - { - id: string; - customFields: Record; - }, + { id: string; customFields: Record }, ][] = []; for (const definition of componentTypeDefinitions) { @@ -783,26 +1525,18 @@ async function createModelTypes() { })), }, }, - include: { - customFields: true, - }, + include: { customFields: true }, }); componentTypeEntries.push([ definition.code, - { - id: record.id, - customFields: mapCustomFields(record.customFields), - }, + { id: record.id, customFields: mapCustomFields(record.customFields) }, ]); } const pieceTypeEntries: [ string, - { - id: string; - customFields: Record; - }, + { id: string; customFields: Record }, ][] = []; for (const definition of pieceTypeDefinitions) { @@ -822,17 +1556,12 @@ async function createModelTypes() { })), }, }, - include: { - pieceCustomFields: true, - }, + include: { pieceCustomFields: true }, }); pieceTypeEntries.push([ definition.code, - { - id: record.id, - customFields: mapCustomFields(record.pieceCustomFields), - }, + { id: record.id, customFields: mapCustomFields(record.pieceCustomFields) }, ]); } @@ -886,159 +1615,327 @@ async function createComponentModels( return Object.fromEntries(entries) as Record; } -async function createTypeMachine( +const typeMachineDefinitions: TypeMachineDefinition[] = [ + { + code: 'triage-line', + name: 'Ligne de triage céréales 120 t/h', + description: + 'Chaîne automatisée de réception, triage, ventilation et expédition des céréales.', + category: 'Triage et stockage', + maintenanceFrequency: + 'Inspection quotidienne, graissage hebdomadaire, révision trimestrielle.', + specifications: { + nominalThroughput: 120, + shiftsPerDay: 2, + building: 'Hall principal', + }, + customFields: [ + { name: 'Capacité nominale (t/h)', type: 'number', required: true }, + { + name: 'Produit traité', + type: 'select', + required: true, + defaultValue: 'Blé tendre', + options: ['Blé tendre', 'Orge brassicole', 'Maïs grain', 'Pois protéagineux'], + }, + { name: 'Date de mise en service', type: 'date', required: true }, + { + name: 'Responsable de ligne', + type: 'select', + defaultValue: 'Lucie Bernard', + options: ['Lucie Bernard', 'Karim Dubois', 'Anaëlle Petit'], + }, + ], + componentRequirements: [ + { + label: 'Élévateurs principaux', + typeCode: 'bucket-elevator', + minCount: 2, + maxCount: 2, + required: true, + }, + { + label: "Convoyeurs d'alimentation", + typeCode: 'belt-conveyor', + minCount: 2, + required: true, + }, + { + label: 'Table densimétrique', + typeCode: 'gravity-separator', + minCount: 1, + maxCount: 1, + required: true, + }, + { + label: 'Vis de reprise', + typeCode: 'screw-conveyor', + minCount: 2, + required: true, + }, + { + label: 'Poste de pesage', + typeCode: 'weigh-hopper', + minCount: 1, + maxCount: 1, + required: true, + }, + { + label: 'Armoire de contrôle', + typeCode: 'control-panel', + minCount: 1, + maxCount: 1, + required: true, + }, + { + label: 'Ventilation', + typeCode: 'ventilation-fan', + minCount: 1, + required: true, + }, + ], + pieceRequirements: [ + { + label: 'Kit visserie critique', + typeCode: 'hex-screw', + minCount: 1, + required: false, + }, + { + label: 'Capteurs de vitesse de secours', + typeCode: 'speed-sensor', + minCount: 2, + required: false, + }, + { + label: 'Cartouches de filtration', + typeCode: 'filter-cartridge', + minCount: 2, + required: false, + }, + ], + }, + { + code: 'grain-dryer-station', + name: 'Station de séchage et dépoussiérage', + description: 'Poste de séchage haute capacité avec filtration et reprise.', + category: 'Séchage', + maintenanceFrequency: 'Contrôle brûleur hebdomadaire, nettoyage cyclone mensuel.', + specifications: { + nominalThroughput: 60, + building: 'Tour de séchage', + nightOperation: true, + }, + customFields: [ + { + name: 'Produit séché', + type: 'select', + defaultValue: 'Maïs grain', + options: ['Maïs grain', 'Blé dur', 'Tournesol'], + required: true, + }, + { + name: 'Mode d’alimentation', + type: 'select', + options: ['Élévateur principal', 'Vis de reprise', 'Chargement manuel'], + defaultValue: 'Élévateur principal', + }, + { name: 'Date de mise en service', type: 'date', required: true }, + ], + componentRequirements: [ + { + label: 'Séchoir continu', + typeCode: 'grain-dryer', + minCount: 1, + maxCount: 1, + required: true, + }, + { + label: 'Module brûleur', + typeCode: 'burner-module', + minCount: 1, + required: true, + }, + { + label: 'Filtration poussières', + typeCode: 'dust-filter', + minCount: 1, + required: true, + }, + { + label: 'Ventilation process', + typeCode: 'ventilation-fan', + minCount: 1, + required: true, + }, + { + label: 'Vis de reprise', + typeCode: 'screw-conveyor', + minCount: 1, + required: true, + }, + { + label: 'Armoire de supervision', + typeCode: 'control-panel', + minCount: 1, + required: true, + }, + ], + pieceRequirements: [ + { + label: 'Joints haute température', + typeCode: 'flat-gasket', + minCount: 2, + required: false, + }, + { + label: 'Sondes de température de secours', + typeCode: 'temperature-probe', + minCount: 2, + required: false, + }, + ], + }, + { + code: 'telehandler-support', + name: 'Chariot télescopique logistique', + description: 'Chariot télescopique dédié aux manutentions céréalières.', + category: 'Logistique', + maintenanceFrequency: 'Graissage hebdomadaire, contrôle hydraulique mensuel.', + specifications: { + yardArea: 'Cour logistique', + rotation: '3 équipes', + }, + customFields: [ + { + name: 'Usage principal', + type: 'select', + options: ['Chargement camions', 'Gestion big-bags', 'Maintenance silo'], + defaultValue: 'Chargement camions', + }, + { + name: 'Lieu de stationnement', + type: 'select', + options: ['Hangar nord', 'Cour extérieure', 'Atelier maintenance'], + defaultValue: 'Hangar nord', + }, + { name: "Année d'achat", type: 'number', required: true }, + ], + componentRequirements: [ + { + label: 'Châssis télescopique', + typeCode: 'telehandler', + minCount: 1, + maxCount: 1, + required: true, + }, + { + label: 'Groupe moteur', + typeCode: 'motor-drive', + minCount: 1, + required: true, + }, + { + label: 'Groupe hydraulique', + typeCode: 'hydraulic-power-pack', + minCount: 1, + required: true, + }, + { + label: 'Armoire de contrôle cabine', + typeCode: 'control-panel', + minCount: 1, + required: false, + }, + ], + pieceRequirements: [ + { + label: 'Fusibles cabine', + typeCode: 'fuse-cartridge', + minCount: 1, + required: false, + }, + { + label: 'Joints hydrauliques de secours', + typeCode: 'flat-gasket', + minCount: 1, + required: false, + }, + ], + }, +]; + +async function createTypeMachines( componentTypes: Record, pieceTypes: Record, ) { - console.log('🧬 Création du squelette de machine...'); + console.log('🧬 Création des squelettes de machines...'); - const typeMachine = await prisma.typeMachine.create({ - data: { - name: 'Ligne de triage et séchage céréales 120 t/h', - description: - 'Chaîne automatisée de réception, triage, séchage et expédition des céréales.', - category: 'Triage et stockage', - maintenanceFrequency: - 'Inspection quotidienne, graissage hebdomadaire, révision trimestrielle.', - specifications: { - nominalThroughput: 120, - moistureTarget: 14.5, - building: 'Hall principal', - shiftsPerDay: 2, - }, - components: { - layout: [ - { order: 1, zone: 'Réception', type: 'bucket-elevator', model: 'elevator-z400' }, - { order: 2, zone: 'Pré-nettoyage', type: 'belt-conveyor', model: 'conveyor-18m' }, - { order: 3, zone: 'Séparation', type: 'gravity-separator', model: 'gravity-table-tqx' }, - { order: 4, zone: 'Séchage', type: 'grain-dryer', model: 'grain-dryer-cd6' }, - { order: 5, zone: 'Reprise', type: 'screw-conveyor', model: 'screw-conveyor-v200' }, - { order: 6, zone: 'Expédition', type: 'weigh-hopper', model: 'weigh-hopper-bp5' }, - ], - }, - criticalParts: { - motors: ['motor-75kw', 'motor-45kw'], - sensors: ['sensor-speed-m12', 'temp-probe-pt100'], - wearItems: ['belt-hd-800', 'filter-g4-500'], - }, - machinePieces: { - recommendedStock: [ - { model: 'motor-75kw', quantity: 1 }, - { model: 'sensor-speed-m12', quantity: 3 }, - { model: 'belt-hd-800', quantity: 1 }, - ], - }, - customFields: { - create: [ - { - name: 'Capacité nominale (t/h)', - type: 'number', - required: true, - options: [], + const entries = await Promise.all( + typeMachineDefinitions.map(async (definition) => { + const record = await prisma.typeMachine.create({ + data: { + name: definition.name, + description: definition.description, + category: definition.category, + maintenanceFrequency: definition.maintenanceFrequency, + specifications: definition.specifications, + components: { + layout: definition.componentRequirements.map((requirement, index) => ({ + order: index + 1, + zone: requirement.label, + type: requirement.typeCode, + })), }, - { - name: 'Produit traité', - type: 'string', - required: true, - defaultValue: 'Blé tendre', - options: [], + machinePieces: { + recommendedStock: [], }, - { - name: 'Date de mise en service', - type: 'date', - required: true, - options: [], + customFields: { + create: definition.customFields.map((field) => ({ + name: field.name, + type: field.type, + required: field.required ?? false, + defaultValue: field.defaultValue, + options: field.options ?? [], + })), }, - { - name: 'Responsable de ligne', - type: 'string', - required: false, - defaultValue: 'Lucie Bernard', - options: [], + componentRequirements: { + create: definition.componentRequirements.map((requirement) => ({ + label: requirement.label, + minCount: requirement.minCount, + maxCount: requirement.maxCount, + required: requirement.required, + typeComposant: { + connect: { id: componentTypes[requirement.typeCode].id }, + }, + })), }, - ], - }, - componentRequirements: { - create: [ - { - label: 'Élévateurs principaux', - minCount: 2, - maxCount: 2, - required: true, - typeComposant: { connect: { id: componentTypes['bucket-elevator'].id } }, - }, - { - label: "Convoyeurs d'alimentation", - minCount: 2, - required: true, - typeComposant: { connect: { id: componentTypes['belt-conveyor'].id } }, - }, - { - label: 'Table densimétrique', - minCount: 1, - maxCount: 1, - required: true, - typeComposant: { connect: { id: componentTypes['gravity-separator'].id } }, - }, - { - label: 'Séchoir continu', - minCount: 1, - maxCount: 1, - required: true, - typeComposant: { connect: { id: componentTypes['grain-dryer'].id } }, - }, - { - label: 'Vis de reprise', - minCount: 2, - required: true, - typeComposant: { connect: { id: componentTypes['screw-conveyor'].id } }, - }, - { - label: 'Benna peseuse', - minCount: 1, - required: true, - typeComposant: { connect: { id: componentTypes['weigh-hopper'].id } }, - }, - { - label: 'Armoire de contrôle', - minCount: 1, - maxCount: 1, - required: true, - typeComposant: { connect: { id: componentTypes['control-panel'].id } }, - }, - { - label: 'Chariot télescopique', - minCount: 1, - required: false, - typeComposant: { connect: { id: componentTypes['telehandler'].id } }, - }, - ], - }, - pieceRequirements: { - create: [ - { - label: 'Moteurs de rechange', - minCount: 1, - required: false, - typePiece: { connect: { id: pieceTypes['electric-motor'].id } }, - }, - { - label: 'Capteurs de vitesse de secours', - minCount: 2, - required: false, - typePiece: { connect: { id: pieceTypes['speed-sensor'].id } }, - }, - ], - }, - }, - include: { - customFields: true, - componentRequirements: true, - pieceRequirements: true, - }, - }); + pieceRequirements: definition.pieceRequirements + ? { + create: definition.pieceRequirements.map((requirement) => ({ + label: requirement.label, + minCount: requirement.minCount, + maxCount: requirement.maxCount, + required: requirement.required, + typePiece: { + connect: { id: pieceTypes[requirement.typeCode].id }, + }, + })), + } + : undefined, + }, + include: { + customFields: true, + componentRequirements: true, + pieceRequirements: true, + }, + }); - return typeMachine; + return [definition.code, record] as const; + }), + ); + + return Object.fromEntries(entries) as Record; } function buildCustomFieldValues( @@ -1143,9 +2040,1031 @@ async function createComponentHierarchy( return record; } -async function createMachineWithComponents( +const machineBuilds: MachineBuildSpec[] = [ + { + code: 'triage-line-main', + typeMachineCode: 'triage-line', + name: 'Ligne de triage Valgrain 2024', + reference: 'VT-TRI-2024', + prix: '725000', + constructeurKey: 'buhler', + customFieldValues: { + 'Capacité nominale (t/h)': 120, + 'Produit traité': 'Blé tendre', + 'Date de mise en service': new Date('2024-02-01'), + 'Responsable de ligne': 'Lucie Bernard', + }, + components: [ + { + name: 'Élévateur amont Z400', + reference: 'BE-Z400-01', + prix: '58000', + typeCode: 'bucket-elevator', + requirementLabel: 'Élévateurs principaux', + modelCode: 'elevator-z400', + constructeur: 'agritech', + customValues: { + 'Débit nominal (t/h)': 120, + 'Hauteur de levage (m)': 38, + 'Matériau des godets': 'Acier galvanisé', + }, + pieces: [ + { + name: 'Courroie élévateur 800 mm', + reference: 'BLT-800-01', + prix: '2300', + typeCode: 'drive-belt', + modelCode: 'belt-hd-800', + constructeur: 'agritech', + customValues: { + 'Largeur (mm)': 800, + Matériau: 'Caoutchouc nitrile', + }, + }, + { + name: 'Kit visserie tête élévateur', + reference: 'KIT-VIS-EL-01', + typeCode: 'hex-screw', + modelCode: 'screw-m12x80', + customValues: { + 'Diamètre (mm)': 12, + 'Longueur (mm)': 80, + 'Classe acier': '8.8', + }, + }, + { + name: 'Rondelles Grower Ø12', + reference: 'RW-12-EL-01', + typeCode: 'lock-washer', + modelCode: 'washer-grower-12', + customValues: { + 'Diamètre (mm)': 12, + Finition: 'Inox', + }, + }, + ], + children: [ + { + name: 'Moteur élévateur 75 kW', + reference: 'MTR-75-01', + typeCode: 'motor-drive', + modelCode: 'motor-drive-75', + constructeur: 'sew', + customValues: { + 'Puissance nominale (kW)': 75, + 'Classe énergétique': 'IE3', + "Indice de protection": 'IP55', + }, + }, + { + name: 'Réducteur tête Flender', + reference: 'GBX-FZ-01', + typeCode: 'gearbox-assembly', + modelCode: 'gearbox-flender', + constructeur: 'flender', + customValues: { + 'Rapport de réduction': '1:28', + 'Couple nominal (Nm)': 3200, + 'Type de montage': 'À bride', + }, + }, + ], + }, + { + name: 'Élévateur aval Z320', + reference: 'BE-Z320-02', + prix: '49700', + typeCode: 'bucket-elevator', + requirementLabel: 'Élévateurs principaux', + modelCode: 'elevator-z320', + constructeur: 'agritech', + customValues: { + 'Débit nominal (t/h)': 95, + 'Hauteur de levage (m)': 32, + 'Matériau des godets': 'Polypropylène renforcé', + }, + pieces: [ + { + name: 'Courroie élévateur 650 mm', + reference: 'BLT-650-02', + typeCode: 'drive-belt', + modelCode: 'belt-hd-650', + customValues: { + 'Largeur (mm)': 650, + Matériau: 'Polyuréthane', + }, + }, + { + name: 'Kit visserie pied élévateur', + reference: 'KIT-VIS-EL-02', + typeCode: 'hex-screw', + modelCode: 'screw-m10x60', + customValues: { + 'Diamètre (mm)': 10, + 'Longueur (mm)': 60, + 'Classe acier': '10.9', + }, + }, + { + name: 'Rondelles Grower Ø10', + reference: 'RW-10-EL-02', + typeCode: 'lock-washer', + modelCode: 'washer-grower-10', + customValues: { + 'Diamètre (mm)': 10, + Finition: 'Zinguée', + }, + }, + ], + children: [ + { + name: 'Moteur élévateur 55 kW', + reference: 'MTR-55-02', + typeCode: 'motor-drive', + modelCode: 'motor-drive-55', + constructeur: 'sew', + customValues: { + 'Puissance nominale (kW)': 55, + 'Classe énergétique': 'IE3', + "Indice de protection": 'IP55', + }, + }, + { + name: 'Réducteur Bonfiglioli TA', + reference: 'GBX-TA-02', + typeCode: 'gearbox-assembly', + modelCode: 'gearbox-bonfiglioli', + constructeur: 'bonfiglioli', + customValues: { + 'Rapport de réduction': '1:24', + 'Couple nominal (Nm)': 2100, + 'Type de montage': 'Sur arbre', + }, + }, + ], + }, + { + name: "Convoyeur d'alimentation A", + reference: 'CV-18-01', + prix: '36200', + typeCode: 'belt-conveyor', + requirementLabel: "Convoyeurs d'alimentation", + modelCode: 'conveyor-18m', + constructeur: 'valmont', + customValues: { + 'Largeur de bande (mm)': 800, + 'Longueur (m)': 18, + 'Type de bande': 'Caoutchouc anti-statique', + }, + pieces: [ + { + name: 'Bande transporteuse 800 mm', + reference: 'BAND-800-A', + typeCode: 'drive-belt', + modelCode: 'belt-hd-800', + customValues: { + 'Largeur (mm)': 800, + Matériau: 'Caoutchouc nitrile', + }, + }, + { + name: 'Kit tendeur M10', + reference: 'KIT-TEN-01', + typeCode: 'hex-screw', + modelCode: 'screw-m10x60', + customValues: { + 'Diamètre (mm)': 10, + 'Longueur (mm)': 60, + 'Classe acier': '10.9', + }, + }, + ], + children: [ + { + name: 'Motorisation convoyeur A', + reference: 'MTR-45-01', + typeCode: 'motor-drive', + modelCode: 'motor-drive-45', + constructeur: 'sew', + customValues: { + 'Puissance nominale (kW)': 45, + 'Classe énergétique': 'IE3', + "Indice de protection": 'IP55', + }, + }, + { + name: 'Réducteur convoyeur A', + reference: 'GBX-TA-03', + typeCode: 'gearbox-assembly', + modelCode: 'gearbox-bonfiglioli', + constructeur: 'bonfiglioli', + customValues: { + 'Rapport de réduction': '1:24', + 'Couple nominal (Nm)': 2100, + 'Type de montage': 'Sur arbre', + }, + }, + ], + }, + { + name: "Convoyeur d'expédition B", + reference: 'CV-25-02', + prix: '41800', + typeCode: 'belt-conveyor', + requirementLabel: "Convoyeurs d'alimentation", + modelCode: 'conveyor-25m', + constructeur: 'valmont', + customValues: { + 'Largeur de bande (mm)': 650, + 'Longueur (m)': 25, + 'Type de bande': 'PVC alimentaire', + }, + pieces: [ + { + name: 'Bande transporteuse 650 mm', + reference: 'BAND-650-B', + typeCode: 'drive-belt', + modelCode: 'belt-hd-650', + customValues: { + 'Largeur (mm)': 650, + Matériau: 'Polyuréthane', + }, + }, + { + name: 'Kit visserie tendeur inox', + reference: 'KIT-TEN-02', + typeCode: 'hex-screw', + modelCode: 'screw-m8x30', + customValues: { + 'Diamètre (mm)': 8, + 'Longueur (mm)': 30, + 'Classe acier': '8.8', + }, + }, + ], + children: [ + { + name: 'Motorisation convoyeur B', + reference: 'MTR-37-02', + typeCode: 'motor-drive', + modelCode: 'motor-drive-37', + constructeur: 'sew', + customValues: { + 'Puissance nominale (kW)': 37, + 'Classe énergétique': 'IE3', + "Indice de protection": 'IP55', + }, + }, + { + name: 'Réducteur convoyeur B', + reference: 'GBX-TA-04', + typeCode: 'gearbox-assembly', + modelCode: 'gearbox-bonfiglioli', + constructeur: 'bonfiglioli', + customValues: { + 'Rapport de réduction': '1:24', + 'Couple nominal (Nm)': 2100, + 'Type de montage': 'Sur arbre', + }, + }, + ], + }, + { + name: 'Table densimétrique TQX', + reference: 'TBL-TQX-01', + prix: '68500', + typeCode: 'gravity-separator', + requirementLabel: 'Table densimétrique', + modelCode: 'gravity-table-tqx', + constructeur: 'buhler', + customValues: { + 'Capacité de tri (t/h)': 120, + 'Fréquence de vibration (Hz)': 45, + 'Type de plateau': 'Acier perforé', + }, + pieces: [ + { + name: 'Capteur vibration table', + reference: 'SNS-VIB-01', + typeCode: 'speed-sensor', + modelCode: 'sensor-speed-m12', + constructeur: 'ifm', + customValues: { + 'Type de sortie': 'PNP 4-20 mA', + 'Plage de mesure (rpm)': 1200, + }, + }, + { + name: 'Kit visserie plateau', + reference: 'KIT-VIS-PL-01', + typeCode: 'hex-screw', + modelCode: 'screw-m8x30', + customValues: { + 'Diamètre (mm)': 8, + 'Longueur (mm)': 30, + 'Classe acier': '8.8', + }, + }, + ], + children: [ + { + name: 'Moteur vibration 18,5 kW', + reference: 'MTR-18-01', + typeCode: 'motor-drive', + modelCode: 'motor-drive-18', + constructeur: 'sew', + customValues: { + 'Puissance nominale (kW)': 18.5, + 'Classe énergétique': 'IE3', + "Indice de protection": 'IP55', + }, + }, + ], + }, + { + name: 'Vis de reprise nord', + reference: 'SC-V200-N', + prix: '27400', + typeCode: 'screw-conveyor', + requirementLabel: 'Vis de reprise', + modelCode: 'screw-conveyor-v200', + constructeur: 'valmont', + customValues: { + 'Diamètre vis (mm)': 200, + 'Inclinaison (°)': 12, + 'Vitesse (rpm)': 140, + }, + pieces: [ + { + name: 'Palier UCP 210', + reference: 'BRG-UCP210-01', + typeCode: 'roller-bearing', + modelCode: 'bearing-ucp210', + constructeur: 'skf', + customValues: { + Série: 'UCP', + "Type d'étanchéité": '2RS', + }, + }, + { + name: 'Kit visserie palier', + reference: 'KIT-VIS-PA-01', + typeCode: 'hex-screw', + modelCode: 'screw-m12x80', + customValues: { + 'Diamètre (mm)': 12, + 'Longueur (mm)': 80, + 'Classe acier': '8.8', + }, + }, + ], + children: [ + { + name: 'Motorisation vis nord', + reference: 'MTR-18-02', + typeCode: 'motor-drive', + modelCode: 'motor-drive-18', + constructeur: 'sew', + customValues: { + 'Puissance nominale (kW)': 18.5, + 'Classe énergétique': 'IE3', + "Indice de protection": 'IP55', + }, + }, + ], + }, + { + name: 'Vis de reprise sud', + reference: 'SC-V160-S', + prix: '23600', + typeCode: 'screw-conveyor', + requirementLabel: 'Vis de reprise', + modelCode: 'screw-conveyor-v160', + constructeur: 'valmont', + customValues: { + 'Diamètre vis (mm)': 160, + 'Inclinaison (°)': 8, + 'Vitesse (rpm)': 110, + }, + pieces: [ + { + name: 'Palier UCFL207', + reference: 'BRG-UCFL207-01', + typeCode: 'roller-bearing', + modelCode: 'bearing-ucfl207', + constructeur: 'skf', + customValues: { + Série: 'UCFL', + "Type d'étanchéité": 'ZZ', + }, + }, + { + name: 'Kit visserie palier UCFL', + reference: 'KIT-VIS-PA-02', + typeCode: 'hex-screw', + modelCode: 'screw-m10x60', + customValues: { + 'Diamètre (mm)': 10, + 'Longueur (mm)': 60, + 'Classe acier': '10.9', + }, + }, + ], + children: [ + { + name: 'Motorisation vis sud', + reference: 'MTR-15-01', + typeCode: 'motor-drive', + modelCode: 'motor-drive-15', + constructeur: 'sew', + customValues: { + 'Puissance nominale (kW)': 15, + 'Classe énergétique': 'IE3', + "Indice de protection": 'IP55', + }, + }, + ], + }, + { + name: 'Poste de pesage BP-5', + reference: 'BP-5000-01', + prix: '39200', + typeCode: 'weigh-hopper', + requirementLabel: 'Poste de pesage', + modelCode: 'weigh-hopper-bp5', + constructeur: 'buhler', + customValues: { + 'Capacité de pesée (kg)': 5000, + 'Précision (%)': 0.5, + 'Mode de vidange': 'Trappe motorisée', + }, + pieces: [ + { + name: 'Capteur pesage 1', + reference: 'LC-5000-01', + typeCode: 'load-cell', + modelCode: 'load-cell-5t', + constructeur: 'ifm', + customValues: { + 'Capacité (kg)': 5000, + 'Type de connexion': 'Câble 6 fils', + }, + }, + { + name: 'Capteur pesage 2', + reference: 'LC-5000-02', + typeCode: 'load-cell', + modelCode: 'load-cell-5t', + constructeur: 'ifm', + customValues: { + 'Capacité (kg)': 5000, + 'Type de connexion': 'Câble 6 fils', + }, + }, + { + name: 'Capteur pesage 3', + reference: 'LC-5000-03', + typeCode: 'load-cell', + modelCode: 'load-cell-5t', + constructeur: 'ifm', + customValues: { + 'Capacité (kg)': 5000, + 'Type de connexion': 'Câble 6 fils', + }, + }, + { + name: 'Capteur pesage 4', + reference: 'LC-5000-04', + typeCode: 'load-cell', + modelCode: 'load-cell-5t', + constructeur: 'ifm', + customValues: { + 'Capacité (kg)': 5000, + 'Type de connexion': 'Câble 6 fils', + }, + }, + ], + }, + { + name: 'Armoire Schneider M340', + reference: 'CTRL-M340-01', + prix: '46500', + typeCode: 'control-panel', + requirementLabel: 'Armoire de contrôle', + modelCode: 'control-panel-m340', + constructeur: 'schneider', + customValues: { + 'Automate principal': 'Schneider Modicon M340', + 'Année de mise à jour': 2023, + "Indice de protection": 'IP55', + }, + pieces: [ + { + name: 'Module PLC M340', + reference: 'PLC-M340-01', + typeCode: 'plc-module', + modelCode: 'plc-module-m340', + constructeur: 'schneider', + customValues: { + "Nombre d'E/S": 32, + 'Version firmware': 'V2.9', + }, + }, + { + name: 'Fusible alimentation 25A', + reference: 'FUS-25A-01', + typeCode: 'fuse-cartridge', + modelCode: 'fuse-gg-25a', + constructeur: 'schneider', + customValues: { + 'Calibre (A)': 25, + 'Type de fusible': 'gG', + }, + }, + { + name: 'Entrée vitesse ligne', + reference: 'SNS-VIT-CTRL-01', + typeCode: 'speed-sensor', + modelCode: 'sensor-speed-m12', + constructeur: 'ifm', + customValues: { + 'Type de sortie': 'PNP 4-20 mA', + 'Plage de mesure (rpm)': 1000, + }, + }, + ], + }, + { + name: "Ventilateur d'extraction principal", + reference: 'FAN-AX-90', + prix: '32500', + typeCode: 'ventilation-fan', + requirementLabel: 'Ventilation', + modelCode: 'ventilation-fan-axial90', + constructeur: 'agrifan', + customValues: { + 'Débit (m³/h)': 48000, + 'Type de roue': 'Axiale', + 'Vitesse nominale (rpm)': 980, + }, + pieces: [ + { + name: 'Kit fixation ventilateur', + reference: 'KIT-FAN-01', + typeCode: 'hex-screw', + modelCode: 'screw-m12x80', + customValues: { + 'Diamètre (mm)': 12, + 'Longueur (mm)': 80, + 'Classe acier': '8.8', + }, + }, + ], + }, + ], + sparePieces: [ + { + requirementLabel: 'Kit visserie critique', + name: 'Kit visserie M12 galvanisé', + reference: 'KIT-VIS-M12', + prix: '180', + typeCode: 'hex-screw', + modelCode: 'screw-m12x80', + constructeur: 'agritech', + customValues: { + 'Diamètre (mm)': 12, + 'Longueur (mm)': 80, + 'Classe acier': '8.8', + }, + }, + { + requirementLabel: 'Capteurs de vitesse de secours', + name: 'Capteur vitesse M12 de secours', + reference: 'SNS-VIT-SPARE-01', + prix: '190', + typeCode: 'speed-sensor', + modelCode: 'sensor-speed-m12', + constructeur: 'ifm', + customValues: { + 'Type de sortie': 'PNP 4-20 mA', + 'Plage de mesure (rpm)': 1200, + }, + }, + { + requirementLabel: 'Cartouches de filtration', + name: 'Cartouche G4 de rechange', + reference: 'FLT-G4-SPARE', + prix: '140', + typeCode: 'filter-cartridge', + modelCode: 'filter-g4-500', + constructeur: 'agrifan', + customValues: { + 'Classe de filtration': 'G4', + 'Dimensions (mm)': '500x500x50', + }, + }, + ], + }, + { + code: 'dryer-station', + typeMachineCode: 'grain-dryer-station', + name: 'Poste de séchage CD-6', + reference: 'VT-DRY-01', + prix: '512000', + constructeurKey: 'agridry', + customFieldValues: { + 'Produit séché': 'Maïs grain', + 'Mode d’alimentation': 'Élévateur principal', + 'Date de mise en service': new Date('2023-09-15'), + }, + components: [ + { + name: 'Séchoir continu CD-6', + reference: 'DRY-CD6-01', + prix: '265000', + typeCode: 'grain-dryer', + requirementLabel: 'Séchoir continu', + modelCode: 'grain-dryer-cd6', + constructeur: 'agridry', + customValues: { + 'Capacité sèche (t/h)': 60, + "Nombre d'étages": 6, + "Type d'énergie": 'Gaz naturel', + }, + pieces: [ + { + name: 'Joint trappe inspection', + reference: 'JNT-DRY-01', + typeCode: 'flat-gasket', + modelCode: 'gasket-nbr-5', + customValues: { + Matière: 'NBR', + 'Épaisseur (mm)': 5, + }, + }, + ], + children: [ + { + name: 'Brûleur gaz principal', + reference: 'BRN-3MW-01', + typeCode: 'burner-module', + requirementLabel: 'Module brûleur', + modelCode: 'burner-module-3mw', + constructeur: 'agridry', + customValues: { + 'Puissance thermique (kW)': 3000, + 'Type de carburant': 'Gaz naturel', + "Système d'allumage": 'Double électrode', + }, + pieces: [ + { + name: 'Sonde flamme PT100', + reference: 'TMP-SEC-01', + typeCode: 'temperature-probe', + modelCode: 'temp-probe-pt100', + constructeur: 'ifm', + customValues: { + 'Type de sonde': 'PT100 classe A', + 'Plage de mesure (°C)': '0-250', + }, + }, + ], + }, + { + name: 'Filtre cyclone FC-12', + reference: 'FIL-FC12-01', + typeCode: 'dust-filter', + requirementLabel: 'Filtration poussières', + modelCode: 'dust-filter-fc12', + constructeur: 'agrifan', + customValues: { + 'Efficacité de filtration (%)': 95, + 'Type de média filtrant': 'Polyester', + 'Nombre de cartouches': 6, + }, + pieces: [ + { + name: 'Cartouche filtrante G4', + reference: 'FLT-G4-01', + typeCode: 'filter-cartridge', + modelCode: 'filter-g4-500', + constructeur: 'agrifan', + customValues: { + 'Classe de filtration': 'G4', + 'Dimensions (mm)': '500x500x50', + }, + }, + ], + }, + ], + }, + { + name: 'Ventilateur extraction séchoir', + reference: 'FAN-DRY-01', + prix: '43500', + typeCode: 'ventilation-fan', + requirementLabel: 'Ventilation process', + modelCode: 'ventilation-fan-axial90', + constructeur: 'agrifan', + customValues: { + 'Débit (m³/h)': 48000, + 'Type de roue': 'Axiale', + 'Vitesse nominale (rpm)': 980, + }, + pieces: [ + { + name: 'Kit fixation ventilateur séchoir', + reference: 'KIT-FAN-DRY', + typeCode: 'hex-screw', + modelCode: 'screw-m12x80', + customValues: { + 'Diamètre (mm)': 12, + 'Longueur (mm)': 80, + 'Classe acier': '8.8', + }, + }, + ], + }, + { + name: 'Vis de reprise séchoir', + reference: 'SC-DRY-01', + prix: '24800', + typeCode: 'screw-conveyor', + requirementLabel: 'Vis de reprise', + modelCode: 'screw-conveyor-v200', + constructeur: 'valmont', + customValues: { + 'Diamètre vis (mm)': 200, + 'Inclinaison (°)': 10, + 'Vitesse (rpm)': 130, + }, + pieces: [ + { + name: 'Palier UCP 210', + reference: 'BRG-UCP210-05', + typeCode: 'roller-bearing', + modelCode: 'bearing-ucp210', + constructeur: 'skf', + customValues: { + Série: 'UCP', + "Type d'étanchéité": '2RS', + }, + }, + ], + children: [ + { + name: 'Motorisation vis séchoir', + reference: 'MTR-18-05', + typeCode: 'motor-drive', + modelCode: 'motor-drive-18', + constructeur: 'sew', + customValues: { + 'Puissance nominale (kW)': 18.5, + 'Classe énergétique': 'IE3', + "Indice de protection": 'IP55', + }, + }, + ], + }, + { + name: 'Armoire supervision séchage', + reference: 'CTRL-S7-DRY', + prix: '38900', + typeCode: 'control-panel', + requirementLabel: 'Armoire de supervision', + modelCode: 'control-panel-s7', + constructeur: 'siemens', + customValues: { + 'Automate principal': 'Siemens S7-1500', + 'Année de mise à jour': 2022, + "Indice de protection": 'IP65', + }, + pieces: [ + { + name: 'Module S7-1200', + reference: 'PLC-S7-01', + typeCode: 'plc-module', + modelCode: 'plc-module-s71200', + constructeur: 'siemens', + customValues: { + "Nombre d'E/S": 24, + 'Version firmware': 'V2.8', + }, + }, + { + name: 'Fusible puissance 40A', + reference: 'FUS-40A-DRY', + typeCode: 'fuse-cartridge', + modelCode: 'fuse-gg-40a', + constructeur: 'schneider', + customValues: { + 'Calibre (A)': 40, + 'Type de fusible': 'gG', + }, + }, + ], + }, + ], + sparePieces: [ + { + requirementLabel: 'Joints haute température', + name: 'Joint PTFE 3 mm de rechange', + reference: 'JNT-PTFE-SPARE', + typeCode: 'flat-gasket', + modelCode: 'gasket-ptfe-3', + constructeur: 'agridry', + customValues: { + Matière: 'PTFE', + 'Épaisseur (mm)': 3, + }, + }, + { + requirementLabel: 'Sondes de température de secours', + name: 'Sonde PT100 courte', + reference: 'TMP-SPARE-02', + typeCode: 'temperature-probe', + modelCode: 'temp-probe-pt100-short', + constructeur: 'ifm', + customValues: { + 'Type de sonde': 'PT100 classe B', + 'Plage de mesure (°C)': '0-200', + }, + }, + ], + }, + { + code: 'telehandler-logistics', + typeMachineCode: 'telehandler-support', + name: 'Manitou MLT 1040 logistique', + reference: 'VT-MAN-01', + prix: '73500', + constructeurKey: 'manitou', + customFieldValues: { + 'Usage principal': 'Gestion big-bags', + 'Lieu de stationnement': 'Hangar nord', + "Année d'achat": 2021, + }, + components: [ + { + name: 'Chariot télescopique MLT 1040', + reference: 'MLT-1040-01', + prix: '73500', + typeCode: 'telehandler', + requirementLabel: 'Châssis télescopique', + modelCode: 'telehandler-mlt1040', + constructeur: 'manitou', + customValues: { + 'Capacité de levage (t)': 4, + 'Hauteur de levage (m)': 9.6, + "Type d'attache": 'Fourches FEM', + }, + pieces: [ + { + name: 'Cartouche cabine 40A', + reference: 'FUS-CAB-40A', + typeCode: 'fuse-cartridge', + modelCode: 'fuse-gg-40a', + constructeur: 'schneider', + customValues: { + 'Calibre (A)': 40, + 'Type de fusible': 'gG', + }, + }, + { + name: 'Joint clapet direction', + reference: 'JNT-DIR-01', + typeCode: 'flat-gasket', + modelCode: 'gasket-nbr-5', + constructeur: 'manitou', + customValues: { + Matière: 'NBR', + 'Épaisseur (mm)': 5, + }, + }, + ], + children: [ + { + name: 'Moteur principal 75 kW', + reference: 'MTR-MAN-01', + typeCode: 'motor-drive', + requirementLabel: 'Groupe moteur', + modelCode: 'motor-drive-75', + constructeur: 'sew', + customValues: { + 'Puissance nominale (kW)': 75, + 'Classe énergétique': 'IE3', + "Indice de protection": 'IP55', + }, + pieces: [ + { + name: 'Kit fixation moteur Manitou', + reference: 'KIT-MTR-MAN', + typeCode: 'hex-screw', + modelCode: 'screw-m12x80', + customValues: { + 'Diamètre (mm)': 12, + 'Longueur (mm)': 80, + 'Classe acier': '8.8', + }, + }, + ], + }, + { + name: 'Groupe hydraulique PVH98', + reference: 'HYD-PVH98-01', + typeCode: 'hydraulic-power-pack', + requirementLabel: 'Groupe hydraulique', + modelCode: 'hydraulic-pack-pvh98', + constructeur: 'poclain', + customValues: { + 'Débit nominal (l/min)': 160, + 'Pression max (bar)': 320, + 'Type de pompe': 'Piston axial', + }, + pieces: [ + { + name: 'Joint collecteur hydraulique', + reference: 'JNT-HYD-01', + typeCode: 'flat-gasket', + modelCode: 'gasket-nbr-5', + customValues: { + Matière: 'NBR', + 'Épaisseur (mm)': 5, + }, + }, + ], + }, + { + name: 'Tableau cabine M340', + reference: 'CTRL-CAB-01', + typeCode: 'control-panel', + requirementLabel: 'Armoire de contrôle cabine', + modelCode: 'control-panel-m340', + constructeur: 'schneider', + customValues: { + 'Automate principal': 'Schneider Modicon M340', + 'Année de mise à jour': 2023, + "Indice de protection": 'IP55', + }, + pieces: [ + { + name: 'Module PLC cabine', + reference: 'PLC-CAB-01', + typeCode: 'plc-module', + modelCode: 'plc-module-m340', + constructeur: 'schneider', + customValues: { + "Nombre d'E/S": 32, + 'Version firmware': 'V2.9', + }, + }, + { + name: 'Fusible cabine 25A', + reference: 'FUS-CAB-25A', + typeCode: 'fuse-cartridge', + modelCode: 'fuse-gg-25a', + constructeur: 'schneider', + customValues: { + 'Calibre (A)': 25, + 'Type de fusible': 'gG', + }, + }, + ], + }, + ], + }, + ], + sparePieces: [ + { + requirementLabel: 'Fusibles cabine', + name: 'Fusible cabine gG 25A', + reference: 'FUS-SPARE-25A', + typeCode: 'fuse-cartridge', + modelCode: 'fuse-gg-25a', + constructeur: 'schneider', + customValues: { + 'Calibre (A)': 25, + 'Type de fusible': 'gG', + }, + }, + { + requirementLabel: 'Joints hydrauliques de secours', + name: 'Kit joints NBR Manitou', + reference: 'KIT-JNT-MAN', + typeCode: 'flat-gasket', + modelCode: 'gasket-nbr-5', + constructeur: 'manitou', + customValues: { + Matière: 'NBR', + 'Épaisseur (mm)': 5, + }, + }, + ], + }, +]; +async function createMachines( siteId: string, - typeMachine: Awaited>, + typeMachines: Record, context: { componentTypes: Record }>; componentModels: Record; @@ -1154,681 +3073,89 @@ async function createMachineWithComponents( constructeurs: Record; }, ) { - console.log('🏗️ Création de la machine de démonstration...'); + console.log('🏗️ Création des machines de démonstration...'); - const requirementMap = new Map(); - typeMachine.componentRequirements.forEach((requirement) => { - if (requirement.label) { - requirementMap.set(requirement.label, requirement.id); + for (const build of machineBuilds) { + const typeMachine = typeMachines[build.typeMachineCode]; + if (!typeMachine) { + throw new Error(`Type de machine introuvable pour ${build.typeMachineCode}`); } - }); - const pieceRequirementMap = new Map(); - typeMachine.pieceRequirements.forEach((requirement) => { - if (requirement.label) { - pieceRequirementMap.set(requirement.label, requirement.id); + const requirementMap = new Map(); + typeMachine.componentRequirements.forEach((requirement) => { + if (requirement.label) { + requirementMap.set(requirement.label, requirement.id); + } + }); + + const pieceRequirementMap = new Map(); + typeMachine.pieceRequirements.forEach((requirement) => { + if (requirement.label) { + pieceRequirementMap.set(requirement.label, requirement.id); + } + }); + + const machineCustomFieldMap = mapCustomFields(typeMachine.customFields); + + const machine = await prisma.machine.create({ + data: { + name: build.name, + reference: build.reference, + prix: new Prisma.Decimal(build.prix), + site: { connect: { id: siteId } }, + typeMachine: { connect: { id: typeMachine.id } }, + constructeur: { + connect: { id: context.constructeurs[build.constructeurKey].id }, + }, + customFieldValues: buildCustomFieldValues( + machineCustomFieldMap, + build.customFieldValues, + ), + }, + }); + + console.log(`⚙️ ${build.name} - ajout des composants...`); + + const componentContext = { + ...context, + requirementMap, + }; + + for (const component of build.components) { + await createComponentHierarchy(machine.id, component, componentContext); } - }); - const machineCustomFieldMap = mapCustomFields(typeMachine.customFields); + if (build.sparePieces && build.sparePieces.length > 0) { + console.log(`📦 ${build.name} - enregistrement des pièces de réserve...`); + for (const spare of build.sparePieces) { + const pieceType = context.pieceTypes[spare.typeCode]; + const requirementId = spare.requirementLabel + ? pieceRequirementMap.get(spare.requirementLabel) + : undefined; - const machine = await prisma.machine.create({ - data: { - name: 'Ligne de triage Valgrain 2024', - reference: 'VT-TRI-2024', - prix: new Prisma.Decimal('725000'), - site: { connect: { id: siteId } }, - typeMachine: { connect: { id: typeMachine.id } }, - constructeur: { connect: { id: context.constructeurs['buhler'].id } }, - customFieldValues: buildCustomFieldValues(machineCustomFieldMap, { - 'Capacité nominale (t/h)': 120, - 'Produit traité': 'Blé tendre, orge brassicole', - 'Date de mise en service': new Date('2024-02-01'), - 'Responsable de ligne': 'Lucie Bernard', - }), - }, - }); - - console.log('⚙️ Ajout des composants et sous-ensembles...'); - - const componentContext = { - ...context, - requirementMap, - }; - - const components: ComponentInstance[] = [ - { - name: 'Élévateur amont Z400', - reference: 'BE-Z400-01', - prix: '58000', - typeCode: 'bucket-elevator', - requirementLabel: 'Élévateurs principaux', - modelCode: 'elevator-z400', - constructeur: 'agritech', - customValues: { - 'Débit nominal (t/h)': 120, - 'Hauteur de levage (m)': 38, - 'Matériau des godets': 'Acier galvanisé', - }, - pieces: [ - { - name: 'Moteur principal 75 kW', - reference: 'MTR-75-01', - prix: '8200', - typeCode: 'electric-motor', - modelCode: 'motor-75kw', - constructeur: 'sew', - customValues: { - 'Puissance nominale (kW)': 75, - 'Tension (V)': 400, - "Indice de protection": 'IP55', + await prisma.piece.create({ + data: { + name: spare.name, + reference: spare.reference, + prix: spare.prix ? new Prisma.Decimal(spare.prix) : undefined, + machine: { connect: { id: machine.id } }, + typePiece: { connect: { id: pieceType.id } }, + pieceModel: { connect: { id: context.pieceModels[spare.modelCode].id } }, + constructeur: spare.constructeur + ? { connect: { id: context.constructeurs[spare.constructeur].id } } + : undefined, + typeMachinePieceRequirement: requirementId + ? { connect: { id: requirementId } } + : undefined, + customFieldValues: buildCustomFieldValues( + pieceType.customFields, + spare.customValues, + ), }, - }, - { - name: 'Réducteur Flender FZ', - reference: 'GBX-FZ-01', - prix: '5100', - typeCode: 'gearbox', - modelCode: 'gearbox-flender', - constructeur: 'flender', - customValues: { - 'Rapport de réduction': '1:28', - 'Couple nominal (Nm)': 3200, - }, - }, - { - name: 'Courroie élévateur 800 mm', - reference: 'BLT-800-01', - prix: '2300', - typeCode: 'belt', - modelCode: 'belt-hd-800', - constructeur: 'agritech', - customValues: { - 'Largeur (mm)': 800, - 'Matériau': 'Caoutchouc nitrile', - }, - }, - { - name: 'Capteur vitesse tête', - reference: 'SNS-VIT-01', - typeCode: 'speed-sensor', - modelCode: 'sensor-speed-m12', - constructeur: 'ifm', - customValues: { - 'Type de sortie': 'PNP 4-20 mA', - 'Plage de mesure (rpm)': 1200, - }, - }, - { - name: 'Roulement tête élévateur', - reference: 'BRG-UCP210-01', - typeCode: 'bearing', - modelCode: 'bearing-ucp210', - constructeur: 'skf', - customValues: { - 'Référence fournisseur': 'SKF UCP210', - "Type d'étanchéité": '2RS', - }, - }, - ], - }, - { - name: 'Élévateur aval Z400', - reference: 'BE-Z400-02', - prix: '56800', - typeCode: 'bucket-elevator', - requirementLabel: 'Élévateurs principaux', - modelCode: 'elevator-z400', - constructeur: 'agritech', - customValues: { - 'Débit nominal (t/h)': 115, - 'Hauteur de levage (m)': 36, - 'Matériau des godets': 'Acier galvanisé', - }, - pieces: [ - { - name: 'Moteur principal 75 kW (aval)', - reference: 'MTR-75-02', - prix: '8150', - typeCode: 'electric-motor', - modelCode: 'motor-75kw', - constructeur: 'sew', - customValues: { - 'Puissance nominale (kW)': 75, - 'Tension (V)': 400, - "Indice de protection": 'IP55', - }, - }, - { - name: 'Courroie élévateur 800 mm (aval)', - reference: 'BLT-800-02', - typeCode: 'belt', - modelCode: 'belt-hd-800', - constructeur: 'agritech', - customValues: { - 'Largeur (mm)': 800, - 'Matériau': 'Caoutchouc nitrile', - }, - }, - { - name: 'Capteur vitesse aval', - reference: 'SNS-VIT-02', - typeCode: 'speed-sensor', - modelCode: 'sensor-speed-m12', - constructeur: 'ifm', - customValues: { - 'Type de sortie': 'PNP 4-20 mA', - 'Plage de mesure (rpm)': 1100, - }, - }, - ], - }, - { - name: "Convoyeur alimentation réception", - reference: 'CV-ALIM-01', - prix: '24500', - typeCode: 'belt-conveyor', - requirementLabel: "Convoyeurs d'alimentation", - modelCode: 'conveyor-18m', - constructeur: 'valmont', - customValues: { - 'Largeur de bande (mm)': 800, - 'Longueur (m)': 18, - 'Type de bande': 'Caoutchouc anti-statique', - }, - pieces: [ - { - name: 'Moteur convoyeur 45 kW', - reference: 'MTR-45-01', - prix: '6100', - typeCode: 'electric-motor', - modelCode: 'motor-45kw', - constructeur: 'sew', - customValues: { - 'Puissance nominale (kW)': 45, - 'Tension (V)': 400, - "Indice de protection": 'IP55', - }, - }, - { - name: 'Bande transporteuse 800 mm', - reference: 'BLT-800-03', - typeCode: 'belt', - modelCode: 'belt-hd-800', - constructeur: 'valmont', - customValues: { - 'Largeur (mm)': 800, - 'Matériau': 'Caoutchouc anti-abrasion', - }, - }, - { - name: 'Capteur vitesse convoyeur', - reference: 'SNS-VIT-03', - typeCode: 'speed-sensor', - modelCode: 'sensor-speed-m12', - constructeur: 'ifm', - customValues: { - 'Type de sortie': 'PNP 4-20 mA', - 'Plage de mesure (rpm)': 900, - }, - }, - ], - }, - { - name: "Convoyeur alimentation séparateur", - reference: 'CV-ALIM-02', - prix: '23200', - typeCode: 'belt-conveyor', - requirementLabel: "Convoyeurs d'alimentation", - modelCode: 'conveyor-18m', - constructeur: 'valmont', - customValues: { - 'Largeur de bande (mm)': 650, - 'Longueur (m)': 15, - 'Type de bande': 'Caoutchouc anti-statique', - }, - pieces: [ - { - name: 'Moteur convoyeur 45 kW (séparateur)', - reference: 'MTR-45-02', - typeCode: 'electric-motor', - modelCode: 'motor-45kw', - constructeur: 'sew', - customValues: { - 'Puissance nominale (kW)': 45, - 'Tension (V)': 400, - "Indice de protection": 'IP55', - }, - }, - { - name: 'Bande transporteuse 650 mm', - reference: 'BLT-650-01', - typeCode: 'belt', - modelCode: 'belt-hd-650', - constructeur: 'valmont', - customValues: { - 'Largeur (mm)': 650, - 'Matériau': 'Caoutchouc anti-abrasion', - }, - }, - { - name: 'Capteur vitesse convoyeur 2', - reference: 'SNS-VIT-04', - typeCode: 'speed-sensor', - modelCode: 'sensor-speed-m12', - constructeur: 'ifm', - customValues: { - 'Type de sortie': 'PNP 4-20 mA', - 'Plage de mesure (rpm)': 850, - }, - }, - ], - }, - { - name: 'Table densimétrique TQX-120', - reference: 'TBL-TQX-01', - prix: '68500', - typeCode: 'gravity-separator', - requirementLabel: 'Table densimétrique', - modelCode: 'gravity-table-tqx', - constructeur: 'buhler', - customValues: { - 'Capacité de tri (t/h)': 120, - 'Fréquence de vibration (Hz)': 45, - 'Type de plateau': 'Acier perforé', - }, - pieces: [ - { - name: 'Moteur vibration 18,5 kW', - reference: 'MTR-18-01', - typeCode: 'electric-motor', - modelCode: 'motor-18kw', - constructeur: 'sew', - customValues: { - 'Puissance nominale (kW)': 18.5, - 'Tension (V)': 400, - "Indice de protection": 'IP55', - }, - }, - { - name: 'Capteur vibration table', - reference: 'SNS-VIB-01', - typeCode: 'speed-sensor', - modelCode: 'sensor-speed-m12', - constructeur: 'ifm', - customValues: { - 'Type de sortie': 'PNP 4-20 mA', - 'Plage de mesure (rpm)': 600, - }, - }, - ], - }, - { - name: 'Séchoir continu CD-6', - reference: 'DRY-CD6-01', - prix: '148000', - typeCode: 'grain-dryer', - requirementLabel: 'Séchoir continu', - modelCode: 'grain-dryer-cd6', - constructeur: 'agridry', - customValues: { - 'Capacité sèche (t/h)': 60, - "Nombre d'étages": 6, - "Type d'énergie": 'Gaz naturel', - }, - pieces: [ - { - name: 'Ventilateur principal 45 kW', - reference: 'MTR-45-03', - typeCode: 'electric-motor', - modelCode: 'motor-45kw', - constructeur: 'sew', - customValues: { - 'Puissance nominale (kW)': 45, - 'Tension (V)': 400, - "Indice de protection": 'IP55', - }, - }, - { - name: "Sonde air chaud PT100", - reference: 'TMP-PT100-01', - typeCode: 'temperature-probe', - modelCode: 'temp-probe-pt100', - constructeur: 'ifm', - customValues: { - 'Plage de mesure (°C)': '0-250', - 'Type de sonde': 'PT100 classe A', - }, - }, - ], - children: [ - { - name: 'Brûleur gaz modulant', - reference: 'BRN-3MW-01', - typeCode: 'burner-module', - modelCode: 'burner-module-3mw', - constructeur: 'agridry', - customValues: { - 'Puissance thermique (kW)': 2950, - 'Type de carburant': 'Gaz naturel', - "Système d'allumage": 'Double électrode', - }, - pieces: [ - { - name: 'Sonde sécurité flamme', - reference: 'TMP-PT100-02', - typeCode: 'temperature-probe', - modelCode: 'temp-probe-pt100', - constructeur: 'ifm', - customValues: { - 'Plage de mesure (°C)': '0-250', - 'Type de sonde': 'PT100 classe A', - }, - }, - ], - }, - { - name: 'Filtre cyclone FC-12', - reference: 'FLT-FC12-01', - typeCode: 'dust-filter', - modelCode: 'dust-filter-fc12', - constructeur: 'agridry', - customValues: { - 'Efficacité de filtration (%)': 95, - 'Type de média filtrant': 'Polyester', - 'Nombre de cartouches': 6, - }, - pieces: [ - { - name: 'Cartouche filtrante G4', - reference: 'FLT-G4-01', - typeCode: 'air-filter', - modelCode: 'filter-g4-500', - constructeur: 'agridry', - customValues: { - 'Classe de filtration': 'G4', - 'Dimensions (mm)': '500x500x50', - }, - }, - ], - }, - ], - }, - { - name: 'Vis de reprise nord', - reference: 'SC-V200-01', - prix: '18400', - typeCode: 'screw-conveyor', - requirementLabel: 'Vis de reprise', - modelCode: 'screw-conveyor-v200', - constructeur: 'valmont', - customValues: { - 'Diamètre vis (mm)': 200, - 'Inclinaison (°)': 10, - 'Vitesse (rpm)': 140, - }, - pieces: [ - { - name: 'Moteur vis 18,5 kW', - reference: 'MTR-18-02', - typeCode: 'electric-motor', - modelCode: 'motor-18kw', - constructeur: 'sew', - customValues: { - 'Puissance nominale (kW)': 18.5, - 'Tension (V)': 400, - "Indice de protection": 'IP55', - }, - }, - { - name: 'Palier vis nord', - reference: 'BRG-UCP210-02', - typeCode: 'bearing', - modelCode: 'bearing-ucp210', - constructeur: 'skf', - customValues: { - 'Référence fournisseur': 'SKF UCP210', - "Type d'étanchéité": '2RS', - }, - }, - ], - }, - { - name: 'Vis de reprise sud', - reference: 'SC-V200-02', - prix: '18100', - typeCode: 'screw-conveyor', - requirementLabel: 'Vis de reprise', - modelCode: 'screw-conveyor-v200', - constructeur: 'valmont', - customValues: { - 'Diamètre vis (mm)': 200, - 'Inclinaison (°)': 12, - 'Vitesse (rpm)': 145, - }, - pieces: [ - { - name: 'Moteur vis 18,5 kW (sud)', - reference: 'MTR-18-03', - typeCode: 'electric-motor', - modelCode: 'motor-18kw', - constructeur: 'sew', - customValues: { - 'Puissance nominale (kW)': 18.5, - 'Tension (V)': 400, - "Indice de protection": 'IP55', - }, - }, - { - name: 'Palier vis sud', - reference: 'BRG-UCP210-03', - typeCode: 'bearing', - modelCode: 'bearing-ucp210', - constructeur: 'skf', - customValues: { - 'Référence fournisseur': 'SKF UCP210', - "Type d'étanchéité": '2RS', - }, - }, - ], - }, - { - name: 'Benna peseuse BP-5', - reference: 'BP-5000-01', - prix: '39200', - typeCode: 'weigh-hopper', - requirementLabel: 'Benna peseuse', - modelCode: 'weigh-hopper-bp5', - constructeur: 'buhler', - customValues: { - 'Capacité de pesée (kg)': 5000, - 'Précision (%)': 0.5, - 'Nombre de capteurs': 4, - }, - pieces: [ - { - name: 'Capteur pesage 1', - reference: 'LC-5000-01', - typeCode: 'load-cell', - modelCode: 'load-cell-5t', - constructeur: 'ifm', - customValues: { - 'Capacité (kg)': 5000, - 'Sensibilité (mV/V)': '2.0', - }, - }, - { - name: 'Capteur pesage 2', - reference: 'LC-5000-02', - typeCode: 'load-cell', - modelCode: 'load-cell-5t', - constructeur: 'ifm', - customValues: { - 'Capacité (kg)': 5000, - 'Sensibilité (mV/V)': '2.0', - }, - }, - { - name: 'Capteur pesage 3', - reference: 'LC-5000-03', - typeCode: 'load-cell', - modelCode: 'load-cell-5t', - constructeur: 'ifm', - customValues: { - 'Capacité (kg)': 5000, - 'Sensibilité (mV/V)': '2.0', - }, - }, - { - name: 'Capteur pesage 4', - reference: 'LC-5000-04', - typeCode: 'load-cell', - modelCode: 'load-cell-5t', - constructeur: 'ifm', - customValues: { - 'Capacité (kg)': 5000, - 'Sensibilité (mV/V)': '2.0', - }, - }, - ], - }, - { - name: 'Armoire Schneider M340', - reference: 'CTRL-M340-01', - prix: '46500', - typeCode: 'control-panel', - requirementLabel: 'Armoire de contrôle', - modelCode: 'control-panel-m340', - constructeur: 'schneider', - customValues: { - 'Automate principal': 'Schneider Modicon M340', - 'Année de mise à jour': 2023, - "Indice de protection": 'IP55', - }, - pieces: [ - { - name: 'Module PLC Siemens 1512', - reference: 'PLC-1512-01', - typeCode: 'control-module', - modelCode: 'plc-module-siemens-1512', - constructeur: 'siemens', - customValues: { - "Nombre d'E/S": 32, - 'Version firmware': 'V2.9', - }, - }, - { - name: 'Entrée vitesse ligne', - reference: 'SNS-VIT-CTRL-01', - typeCode: 'speed-sensor', - modelCode: 'sensor-speed-m12', - constructeur: 'ifm', - customValues: { - 'Type de sortie': 'PNP 4-20 mA', - 'Plage de mesure (rpm)': 1000, - }, - }, - ], - }, - { - name: 'Chariot télescopique Manitou', - reference: 'MLT-1040-01', - prix: '73500', - typeCode: 'telehandler', - requirementLabel: 'Chariot télescopique', - modelCode: 'telehandler-mlt1040', - constructeur: 'manitou', - customValues: { - 'Capacité de levage (t)': 4, - 'Hauteur de levage (m)': 9.6, - "Type d'attache": 'Fourches FEM', - }, - pieces: [ - { - name: 'Pompe hydraulique principale', - reference: 'HDP-PVH98-01', - typeCode: 'hydraulic-pump', - modelCode: 'hydraulic-pump-pvh98', - constructeur: 'manitou', - customValues: { - 'Débit nominal (l/min)': 160, - 'Pression max (bar)': 320, - }, - }, - { - name: 'Palier articulation flèche', - reference: 'BRG-UCP210-04', - typeCode: 'bearing', - modelCode: 'bearing-ucp210', - constructeur: 'skf', - customValues: { - 'Référence fournisseur': 'SKF UCP210', - "Type d'étanchéité": '2RS', - }, - }, - ], - }, - ]; - - for (const component of components) { - await createComponentHierarchy(machine.id, component, componentContext); + }); + } + } } - - console.log('📦 Ajout des pièces de réserve machine...'); - - const spareMotor = await prisma.piece.create({ - data: { - name: 'Moteur IE3 75 kW de secours', - reference: 'MTR-75-SPARE', - prix: new Prisma.Decimal('7900'), - machine: { connect: { id: machine.id } }, - typePiece: { connect: { id: context.pieceTypes['electric-motor'].id } }, - pieceModel: { connect: { id: context.pieceModels['motor-75kw'].id } }, - constructeur: { connect: { id: context.constructeurs['sew'].id } }, - typeMachinePieceRequirement: { - connect: { id: pieceRequirementMap.get('Moteurs de rechange')! }, - }, - customFieldValues: buildCustomFieldValues( - context.pieceTypes['electric-motor'].customFields, - { - 'Puissance nominale (kW)': 75, - 'Tension (V)': 400, - "Indice de protection": 'IP55', - }, - ), - }, - }); - - await prisma.piece.create({ - data: { - name: 'Capteur vitesse M12 de secours', - reference: 'SNS-VIT-SPARE-01', - prix: new Prisma.Decimal('190'), - machine: { connect: { id: machine.id } }, - typePiece: { connect: { id: context.pieceTypes['speed-sensor'].id } }, - pieceModel: { connect: { id: context.pieceModels['sensor-speed-m12'].id } }, - constructeur: { connect: { id: context.constructeurs['ifm'].id } }, - typeMachinePieceRequirement: { - connect: { id: pieceRequirementMap.get('Capteurs de vitesse de secours')! }, - }, - customFieldValues: buildCustomFieldValues( - context.pieceTypes['speed-sensor'].customFields, - { - 'Type de sortie': 'PNP 4-20 mA', - 'Plage de mesure (rpm)': 1200, - }, - ), - }, - }); - - console.log( - `✅ Machine créée avec ${components.length} composants et pièces critiques enregistrées.`, - ); - - return { - machine, - spareMotor, - }; } async function main() { @@ -1841,13 +3168,13 @@ async function main() { ]); const { componentTypes, pieceTypes } = await createModelTypes(); - const [pieceModels, componentModels, typeMachine] = await Promise.all([ + const [pieceModels, componentModels, typeMachines] = await Promise.all([ createPieceModels(pieceTypes), createComponentModels(componentTypes), - createTypeMachine(componentTypes, pieceTypes), + createTypeMachines(componentTypes, pieceTypes), ]); - await createMachineWithComponents(site.id, typeMachine, { + await createMachines(site.id, typeMachines, { componentTypes, componentModels, pieceTypes,