This repository has been archived on 2026-04-01. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Inventory_backend/scripts/seed-industrial-data.ts

4727 lines
129 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { PrismaClient, Prisma, ModelCategory } from '@prisma/client';
import { normalizeComponentModelStructure } from '../src/component-models/structure.normalizer';
import type { ComponentModelStructure } from '../src/shared/types/inventory';
const prisma = new PrismaClient();
type CustomFieldSpec = {
name: string;
type: 'string' | 'number' | 'boolean' | 'date' | 'select';
required?: boolean;
defaultValue?: string;
options?: string[];
};
type ComponentTypeDefinition = {
code: string;
name: string;
description: string;
customFields: CustomFieldSpec[];
};
type PieceTypeDefinition = {
code: string;
name: string;
description: string;
customFields: CustomFieldSpec[];
};
type PieceModelDefinition = {
code: string;
name: string;
description: string;
typeCode: string;
structure?: Prisma.InputJsonValue;
};
type ComponentModelStructureDraft =
| ComponentModelStructure
| ({
recommendedCustomFields?: Record<string, unknown>;
customFields?: Array<{ key?: string; name?: string; value?: unknown }>;
pieceTemplates?: Array<{
typeCode?: string;
modelCode?: string;
quantity?: number;
usage?: string;
notes?: string;
role?: string;
}>;
subComponentTemplates?: Array<{
typeCode?: string;
suggestedModelCodes?: string[];
alias?: string;
notes?: string;
}>;
} & Record<string, unknown>);
type ComponentModelDefinition = {
code: string;
name: string;
description: string;
typeCode: string;
structure?: ComponentModelStructureDraft | Prisma.InputJsonValue;
};
type ConstructeurDefinition = {
key: string;
name: string;
email?: string;
phone?: string;
};
type ComponentPieceInstance = {
name: string;
reference?: string;
prix?: string;
typeCode: string;
modelCode: string;
constructeur?: string;
customValues?: Record<string, string | number | boolean | Date>;
};
type ComponentInstance = {
name: string;
reference?: string;
prix?: string;
typeCode: string;
requirementLabel?: string;
modelCode: string;
constructeur?: string;
customValues?: Record<string, string | number | boolean | Date>;
pieces?: ComponentPieceInstance[];
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<string, string | number | boolean | Date>;
components: ComponentInstance[];
sparePieces?: (ComponentPieceInstance & { requirementLabel?: string })[];
};
type TypeMachineRecord = Prisma.TypeMachineGetPayload<{
include: {
customFields: true;
componentRequirements: true;
pieceRequirements: true;
};
}>;
const componentTypeDefinitions: ComponentTypeDefinition[] = [
{
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 industriel pour adaptation de vitesse.',
customFields: [
{
name: 'Rapport de réduction',
type: 'select',
defaultValue: '1:25',
options: ['1:18', '1:24', '1:28', '1:32'],
},
{ name: 'Couple nominal (Nm)', type: 'number', required: true },
{
name: 'Type de montage',
type: 'select',
options: ['À bride', 'À pattes', 'Sur arbre'],
defaultValue: 'À bride',
},
],
},
{
code: 'bucket-head-section',
name: "Tête d'élévateur",
description: 'Module supérieur avec tambour moteur et trappes de visite.',
customFields: [
{ name: 'Largeur tambour (mm)', type: 'number', required: true },
{
name: 'Type de revêtement',
type: 'select',
options: ['Caoutchouc rainuré', 'Céramique', 'Acier lisse'],
defaultValue: 'Caoutchouc rainuré',
},
{ name: 'Nombre de trappes', type: 'number' },
],
},
{
code: 'bucket-boot-section',
name: "Pied d'élévateur",
description: 'Module inférieur avec trémie et organes de tension.',
customFields: [
{ name: 'Capacité trémie (L)', type: 'number', required: true },
{
name: 'Mode de tension',
type: 'select',
options: ['Vis manuelle', 'Contrepoids', 'Hydraulique'],
defaultValue: 'Vis manuelle',
},
{
name: 'Système de nettoyage',
type: 'select',
options: ['Grattoirs', 'Balais', 'Vide-pied'],
defaultValue: 'Grattoirs',
},
],
},
{
code: 'bucket-leg-section',
name: 'Tronçon de gaine',
description: 'Section intermédiaire de gaine pour élévateur.',
customFields: [
{ name: 'Hauteur section (m)', type: 'number', required: true },
{
name: 'Type de gaine',
type: 'select',
options: ['Boulonnée', 'Soudée', 'Renforcée'],
defaultValue: 'Boulonnée',
},
],
},
{
code: 'belt-drive-station',
name: "Station d'entraînement",
description: 'Station de tête pour convoyeur à bande.',
customFields: [
{
name: 'Type de tambour',
type: 'select',
options: ['Caoutchouc rainuré', 'Métallique', 'Céramique'],
defaultValue: 'Caoutchouc rainuré',
},
{
name: 'Système de tension',
type: 'select',
options: ['Vis manuelle', 'Hydraulique', 'Pneumatique'],
defaultValue: 'Vis manuelle',
},
],
},
{
code: 'belt-tail-station',
name: 'Station de retour',
description: 'Tambour de retour et système de nettoyage de bande.',
customFields: [
{
name: 'Nettoyeur principal',
type: 'select',
options: ['Racleur PU', 'Brosse acier', 'Racleur secondaire'],
defaultValue: 'Racleur PU',
},
{ name: 'Diamètre tambour (mm)', type: 'number', required: true },
],
},
{
code: 'belt-support-frame',
name: 'Ossature convoyeur',
description: 'Structure intermédiaire et rouleaux porteurs.',
customFields: [
{ name: 'Longueur (m)', type: 'number', required: true },
{ name: 'Nombre de rouleaux', type: 'number', required: true },
{
name: 'Type de châssis',
type: 'select',
options: ['Treillis', 'Caisson', 'Portique'],
defaultValue: 'Treillis',
},
],
},
{
code: 'gravity-vibration-deck',
name: 'Plateau vibrant',
description: 'Plateau densimétrique pour séparation des grains.',
customFields: [
{
name: 'Type de plateau',
type: 'select',
options: ['Acier perforé', 'Inox poli', 'Composite'],
defaultValue: 'Acier perforé',
},
{ name: 'Fréquence de vibration (Hz)', type: 'number', required: true },
{ name: 'Inclinaison plateau (°)', type: 'number' },
],
},
{
code: 'ventilation-fan',
name: 'Ventilateur process',
description: "Ventilateur d'aspiration ou d'extraction pour ligne céréalière.",
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' },
],
},
{
code: 'control-panel',
name: 'Armoire de contrôle',
description: 'Armoire électrique pilotant un équipement ou une machine.',
customFields: [
{
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: 'select',
defaultValue: 'IP55',
options: ['IP55', 'IP65', 'IP54'],
},
],
},
{
code: 'burner-module',
name: 'Module brûleur',
description: 'Module de combustion alimentant un séchoir en air chaud.',
customFields: [
{ name: 'Puissance thermique (kW)', type: 'number', required: true },
{
name: 'Type de carburant',
type: 'select',
defaultValue: 'Gaz naturel',
options: ['Gaz naturel', 'Biomasse', 'Fioul léger'],
},
{
name: "Système d'allumage",
type: 'select',
defaultValue: 'Double électrode',
options: ['Double électrode', 'Brûleur pilote', 'Allumeur électronique'],
},
],
},
{
code: 'dryer-column-segment',
name: 'Segment de colonne',
description: 'Module de colonne de séchage empilable.',
customFields: [
{ name: 'Hauteur segment (m)', type: 'number', required: true },
{
name: 'Zone de séchage',
type: 'select',
options: ['Échauffage', 'Tempe', 'Refroidissement'],
defaultValue: 'Échauffage',
},
{ name: 'Capteurs intégrés', type: 'boolean', defaultValue: 'true' },
],
},
{
code: 'dust-filter',
name: 'Filtre à poussière',
description: 'Filtre à manches ou cyclone pour dépoussiérage.',
customFields: [
{ name: 'Efficacité de filtration (%)', type: 'number', required: true },
{
name: 'Type de média filtrant',
type: 'select',
options: ['Polyester', 'Fibre de verre', 'Polypropylène'],
defaultValue: 'Polyester',
},
{ name: 'Nombre de cartouches', type: 'number' },
],
},
{
code: 'screw-trough-section',
name: 'Caisson de vis',
description: 'Tronçon de vis sans fin avec palier intermédiaire.',
customFields: [
{ name: 'Longueur (m)', type: 'number', required: true },
{ name: 'Diamètre vis (mm)', type: 'number', required: true },
{
name: 'Matériau',
type: 'select',
options: ['Acier peint', 'Acier inoxydable', 'Galvanisé'],
defaultValue: 'Acier peint',
},
],
},
{
code: 'screw-inlet-hopper',
name: "Trémie d'alimentation",
description: 'Trémie de reprise amont pour vis sans fin.',
customFields: [
{ name: 'Capacité (L)', type: 'number', required: true },
{
name: 'Type de grille',
type: 'select',
options: ['Grille lisse', 'Grille anti-gravats', 'Grille magnétique'],
defaultValue: 'Grille anti-gravats',
},
],
},
{
code: 'screw-outlet-chute',
name: 'Goulotte de sortie',
description: 'Sortie aval avec vanne de réglage.',
customFields: [
{
name: 'Type de vanne',
type: 'select',
options: ['Guillotine', 'Papillon', 'By-pass'],
defaultValue: 'Guillotine',
},
{ name: "Orientation (°)", type: 'number' },
],
},
{
code: 'weigh-load-frame',
name: 'Cadre peseur',
description: 'Structure équipée de capteurs de pesage.',
customFields: [
{ name: 'Capacité nominale (kg)', type: 'number', required: true },
{ name: 'Nombre de capteurs', type: 'number', required: true },
{
name: 'Protection IP',
type: 'select',
options: ['IP54', 'IP65', 'IP67'],
defaultValue: 'IP65',
},
],
},
{
code: 'weigh-discharge-gate',
name: 'Vanne de vidange',
description: 'Organe de vidange motorisé pour benne peseuse.',
customFields: [
{
name: "Type d'actionneur",
type: 'select',
options: ['Hydraulique', 'Motoréducteur', 'Pneumatique'],
defaultValue: 'Hydraulique',
},
{ name: "Temps d'ouverture (s)", type: 'number' },
],
},
{
code: 'hydraulic-power-pack',
name: 'Groupe hydraulique',
description: 'Groupe hydraulique alimentant vérins et accessoires.',
customFields: [
{ name: 'Débit nominal (l/min)', type: 'number', required: true },
{ name: 'Pression max (bar)', type: 'number', required: true },
{
name: 'Type de pompe',
type: 'select',
options: ['Piston axial', 'Palette', 'Engrenages'],
defaultValue: 'Piston axial',
},
],
},
{
code: 'telehandler-boom',
name: 'Flèche télescopique',
description: 'Flèche et berceau de levage pour chariot télescopique.',
customFields: [
{ name: 'Hauteur max (m)', type: 'number', required: true },
{ name: 'Sections télescopiques', type: 'number', required: true },
{
name: 'Type de guidage',
type: 'select',
options: ['Galets', 'Patins composites'],
defaultValue: 'Galets',
},
],
},
{
code: 'telehandler-cab-module',
name: 'Cabine opérateur',
description: 'Cabine pressurisée avec commandes.',
customFields: [
{
name: 'Type de cabine',
type: 'select',
options: ['Standard', 'Premium climatisée', 'Haute visibilité'],
defaultValue: 'Premium climatisée',
},
{ name: 'Climatisation', type: 'boolean', defaultValue: 'true' },
{ name: 'Nombre de caméras', type: 'number' },
],
},
{
code: 'telehandler-attachment-carrier',
name: 'Support doutils',
description: 'Plaque porte-outils et attelage rapide.',
customFields: [
{
name: "Type d'attache",
type: 'select',
options: ['Fourches FEM', 'Attache Euro', 'Attache Manitou'],
defaultValue: 'Attache Manitou',
},
{ name: 'Capacité nominale (t)', type: 'number', required: true },
],
},
];
const pieceTypeDefinitions: PieceTypeDefinition[] = [
{
code: 'hex-screw',
name: 'Vis hexagonale',
description: 'Visserie pour assemblages mécaniques.',
customFields: [
{ 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: 'Inox',
},
],
},
{
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 élévatrice.',
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: ['ZZ', '2RS'],
defaultValue: '2RS',
},
],
},
{
code: 'filter-cartridge',
name: 'Cartouche filtrante',
description: 'Cartouche de dépoussiérage.',
customFields: [
{ name: 'Longueur (mm)', type: 'number', required: true },
{
name: 'Média filtrant',
type: 'select',
options: ['Polyester', 'Fibre de verre', 'Nomex'],
defaultValue: 'Polyester',
},
],
},
{
code: 'speed-sensor',
name: 'Capteur de vitesse',
description: 'Capteur inductif pour surveillance de rotation.',
customFields: [
{
name: 'Type de sortie',
type: 'select',
options: ['PNP 4-20 mA', 'PNP Tout ou rien'],
defaultValue: 'PNP 4-20 mA',
},
{ name: 'Plage de mesure (rpm)', type: 'number', required: true },
],
},
{
code: 'temperature-probe',
name: 'Sonde de température',
description: 'Sonde PT100 pour surveillance du séchage.',
customFields: [
{
name: 'Type',
type: 'select',
options: ['PT100 classe A', 'PT100 classe B'],
defaultValue: 'PT100 classe A',
},
{ name: 'Longueur tige (mm)', type: 'number', required: true },
],
},
{
code: 'fuse-cartridge',
name: 'Fusible',
description: 'Fusible cylindrique pour protection électrique.',
customFields: [
{ name: 'Calibre (A)', type: 'number', required: true },
{
name: 'Type',
type: 'select',
options: ['gG', 'aM'],
defaultValue: 'gG',
},
],
},
{
code: 'load-cell',
name: 'Capteur de pesage',
description: 'Capteur de pesage pour benne peseuse.',
customFields: [
{ name: 'Capacité (kg)', type: 'number', required: true },
{
name: 'Type de connexion',
type: 'select',
options: ['Câble 4 fils', 'Câble 6 fils'],
defaultValue: 'Câble 6 fils',
},
],
},
{
code: 'lubrication-cartridge',
name: 'Cartouche de graisse',
description: 'Cartouche pour point de graissage automatique.',
customFields: [
{ name: 'Volume (cm³)', type: 'number', required: true },
{
name: 'Grade de graisse',
type: 'select',
options: ['NLGI 1', 'NLGI 2'],
defaultValue: 'NLGI 2',
},
],
},
{
code: 'hydraulic-hose',
name: 'Flexible hydraulique',
description: 'Flexible haute pression pour circuit hydraulique.',
customFields: [
{ name: 'Pression max (bar)', type: 'number', required: true },
{
name: 'Type de renfort',
type: 'select',
options: ['2 tresses acier', '4 nappes acier'],
defaultValue: '2 tresses acier',
},
{ name: 'Longueur (mm)', type: 'number', required: true },
],
},
];
const pieceModelDefinitions: PieceModelDefinition[] = [
{
code: 'screw-m12x80',
name: 'Vis M12x80 8.8',
description: 'Vis tête hexagonale pour charpente.',
typeCode: 'hex-screw',
structure: { standard: 'ISO 4014' },
},
{
code: 'screw-m10x60',
name: 'Vis M10x60 10.9',
description: 'Vis haute résistance pour convoyeur.',
typeCode: 'hex-screw',
},
{
code: 'screw-m8x30',
name: 'Vis M8x30 inox',
description: 'Visserie inox pour accessoires.',
typeCode: 'hex-screw',
},
{
code: 'washer-grower-12',
name: 'Rondelle Grower Ø12',
description: 'Rondelle de sécurité inox.',
typeCode: 'lock-washer',
},
{
code: 'washer-grower-10',
name: 'Rondelle Grower Ø10',
description: 'Rondelle pour visserie M10.',
typeCode: 'lock-washer',
},
{
code: 'gasket-ht-200',
name: 'Joint haute température 200°C',
description: 'Joint fibre compressée pour trappe.',
typeCode: 'flat-gasket',
},
{
code: 'belt-hd-800',
name: 'Courroie 800 mm Heavy Duty',
description: 'Courroie caoutchouc nitrile 800 mm.',
typeCode: 'drive-belt',
},
{
code: 'belt-hd-650',
name: 'Courroie 650 mm Agro',
description: 'Courroie polyuréthane 650 mm.',
typeCode: 'drive-belt',
},
{
code: 'bearing-ucp210',
name: 'Palier UCP210',
description: 'Roulement semelle fonte.',
typeCode: 'roller-bearing',
},
{
code: 'bearing-ucfl207',
name: 'Palier UCFL207',
description: 'Roulement bride deux trous.',
typeCode: 'roller-bearing',
},
{
code: 'filter-dust-610',
name: 'Cartouche filtre 610 mm',
description: 'Cartouche polyester 610 mm.',
typeCode: 'filter-cartridge',
},
{
code: 'filter-dust-480',
name: 'Cartouche filtre 480 mm',
description: 'Cartouche polyester 480 mm.',
typeCode: 'filter-cartridge',
},
{
code: 'sensor-speed-m12',
name: 'Capteur vitesse M12',
description: 'Capteur inductif M12 PNP 4-20 mA.',
typeCode: 'speed-sensor',
},
{
code: 'sensor-speed-m18',
name: 'Capteur vitesse M18',
description: 'Capteur inductif M18 PNP.',
typeCode: 'speed-sensor',
},
{
code: 'temp-probe-pt100',
name: 'Sonde PT100 300 mm',
description: 'Sonde PT100 classe A tige 300 mm.',
typeCode: 'temperature-probe',
},
{
code: 'temp-probe-pt100-short',
name: 'Sonde PT100 200 mm',
description: 'Sonde PT100 compacte.',
typeCode: 'temperature-probe',
},
{
code: 'fuse-gg-25a',
name: 'Fusible gG 25A',
description: 'Fusible protection puissance 25A.',
typeCode: 'fuse-cartridge',
},
{
code: 'fuse-gg-40a',
name: 'Fusible gG 40A',
description: 'Fusible protection 40A.',
typeCode: 'fuse-cartridge',
},
{
code: 'load-cell-5t',
name: 'Capteur pesage 5T',
description: 'Capteur compression 5 tonnes.',
typeCode: 'load-cell',
},
{
code: 'grease-cartridge-400',
name: 'Cartouche graisse 400g',
description: 'Cartouche graisse NLGI2 400g.',
typeCode: 'lubrication-cartridge',
},
{
code: 'hydraulic-hose-2w',
name: 'Flexible 2 tresses 420 bar',
description: 'Flexible 2 tresses acier 420 bar.',
typeCode: 'hydraulic-hose',
},
];
const componentModelDefinitions: ComponentModelDefinition[] = [
{
code: 'motor-drive-75',
name: 'Moteur 75 kW IE3',
description: 'Moteur IE3 75 kW IP55.',
typeCode: 'motor-drive',
structure: {
recommendedCustomFields: {
'Puissance nominale (kW)': '75',
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
},
},
{
code: 'motor-drive-55',
name: 'Moteur 55 kW IE3',
description: 'Motorisation ligne aval.',
typeCode: 'motor-drive',
structure: {
recommendedCustomFields: {
'Puissance nominale (kW)': '55',
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
pieceTemplates: [
{
typeCode: 'roller-bearing',
modelCode: 'bearing-ucfl207',
quantity: 2,
usage: 'Support pattes moteur',
},
{
typeCode: 'hex-screw',
modelCode: 'screw-m10x60',
quantity: 6,
usage: 'Fixations supérieures',
},
],
maintenanceNotes: 'Contrôle vibrations mensuel, resserrage annuel.',
},
},
{
code: 'motor-drive-45',
name: 'Moteur 45 kW IE3',
description: 'Motorisation convoyeur principal.',
typeCode: 'motor-drive',
structure: {
recommendedCustomFields: {
'Puissance nominale (kW)': '45',
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
pieceTemplates: [
{
typeCode: 'roller-bearing',
modelCode: 'bearing-ucfl207',
quantity: 2,
usage: 'Palier de sortie',
},
],
subComponentTemplates: [
{
typeCode: 'gearbox-assembly',
suggestedModelCodes: ['gearbox-sew'],
notes: 'Prévoir accouplement conique.',
},
],
},
},
{
code: 'motor-drive-37',
name: 'Moteur 37 kW IE3',
description: 'Motorisation convoyeur secondaire.',
typeCode: 'motor-drive',
structure: {
recommendedCustomFields: {
'Puissance nominale (kW)': '37',
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
pieceTemplates: [
{
typeCode: 'roller-bearing',
modelCode: 'bearing-ucp210',
quantity: 2,
usage: 'Roulements moteur',
},
],
},
},
{
code: 'motor-drive-18',
name: 'Moteur 18.5 kW IE3',
description: 'Motorisation vis sans fin.',
typeCode: 'motor-drive',
structure: {
recommendedCustomFields: {
'Puissance nominale (kW)': '18.5',
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m10x60',
quantity: 4,
usage: 'Fixation semelle',
},
],
subComponentTemplates: [
{
typeCode: 'gearbox-assembly',
suggestedModelCodes: ['gearbox-sew'],
notes: 'Couple conique pour vis sans fin.',
},
],
},
},
{
code: 'motor-drive-15',
name: 'Moteur 15 kW IE3',
description: 'Motorisation vis compact.',
typeCode: 'motor-drive',
structure: {
recommendedCustomFields: {
'Puissance nominale (kW)': '15',
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m8x30',
quantity: 6,
usage: 'Fixation petits supports',
},
],
},
},
{
code: 'motor-drive-110',
name: 'Moteur 110 kW IE3',
description: 'Motorisation séchoir.',
typeCode: 'motor-drive',
structure: {
recommendedCustomFields: {
'Puissance nominale (kW)': '110',
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
pieceTemplates: [
{
typeCode: 'roller-bearing',
modelCode: 'bearing-ucp210',
quantity: 2,
usage: 'Roulements renforts',
},
{
typeCode: 'hex-screw',
modelCode: 'screw-m12x80',
quantity: 12,
usage: 'Ancrage châssis',
},
],
maintenanceNotes: 'Contrôle isolation bobinage semestriel.',
},
},
{
code: 'gearbox-flender',
name: 'Réducteur Flender 3200 Nm',
description: 'Réducteur à couple élevé.',
typeCode: 'gearbox-assembly',
structure: {
recommendedCustomFields: {
'Rapport de réduction': '1:28',
'Couple nominal (Nm)': '3200',
'Type de montage': 'À bride',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m12x80',
quantity: 12,
usage: 'Fixation bride réducteur',
},
{
typeCode: 'lock-washer',
modelCode: 'washer-grower-12',
quantity: 12,
usage: 'Sécurisation boulonnerie',
},
],
subComponentTemplates: [
{
typeCode: 'motor-drive',
suggestedModelCodes: ['motor-drive-75', 'motor-drive-55'],
notes: 'Association moteur IE3 selon besoin.',
},
],
},
},
{
code: 'gearbox-bonfiglioli',
name: 'Réducteur Bonfiglioli TA',
description: 'Réducteur montage sur arbre.',
typeCode: 'gearbox-assembly',
structure: {
recommendedCustomFields: {
'Rapport de réduction': '1:24',
'Couple nominal (Nm)': '2100',
'Type de montage': 'Sur arbre',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m10x60',
quantity: 8,
usage: 'Fixations bras couple',
},
{
typeCode: 'lock-washer',
modelCode: 'washer-grower-10',
quantity: 8,
usage: 'Sécurisation fixations',
},
],
},
},
{
code: 'gearbox-sew',
name: 'Réducteur SEW K',
description: 'Réducteur coaxial pour vis.',
typeCode: 'gearbox-assembly',
structure: {
recommendedCustomFields: {
'Rapport de réduction': '1:18',
'Couple nominal (Nm)': '1800',
'Type de montage': 'À bride',
},
pieceTemplates: [
{
typeCode: 'lock-washer',
modelCode: 'washer-grower-12',
quantity: 10,
usage: 'Contre-écrous',
},
],
subComponentTemplates: [
{
typeCode: 'motor-drive',
suggestedModelCodes: ['motor-drive-18', 'motor-drive-15'],
notes: 'Motorisation vis standard.',
},
],
},
},
{
code: 'bucket-head-120',
name: 'Tête élévateur 800 mm',
description: 'Tête renforcée 800 mm.',
typeCode: 'bucket-head-section',
structure: {
recommendedCustomFields: {
'Largeur tambour (mm)': '820',
'Type de revêtement': 'Caoutchouc rainuré',
'Nombre de trappes': '3',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m12x80',
quantity: 24,
usage: 'Assemblage flasques',
},
{
typeCode: 'lock-washer',
modelCode: 'washer-grower-12',
quantity: 24,
usage: 'Sécurisation visserie',
},
{
typeCode: 'speed-sensor',
modelCode: 'sensor-speed-m12',
quantity: 1,
usage: 'Contrôle vitesse tambour',
},
],
subComponentTemplates: [
{
typeCode: 'motor-drive',
suggestedModelCodes: ['motor-drive-75'],
notes: 'Motorisation tête élévateur',
},
{
typeCode: 'gearbox-assembly',
suggestedModelCodes: ['gearbox-flender'],
notes: 'Réducteur couple élevé',
},
],
},
},
{
code: 'bucket-head-95',
name: 'Tête élévateur 650 mm',
description: 'Tête compacte 650 mm.',
typeCode: 'bucket-head-section',
structure: {
recommendedCustomFields: {
'Largeur tambour (mm)': '660',
'Type de revêtement': 'Polyuréthane',
'Nombre de trappes': '2',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m10x60',
quantity: 18,
usage: 'Assemblage coiffe',
},
{
typeCode: 'lock-washer',
modelCode: 'washer-grower-10',
quantity: 18,
usage: 'Sécurité assemblage',
},
],
subComponentTemplates: [
{
typeCode: 'motor-drive',
suggestedModelCodes: ['motor-drive-55'],
notes: 'Motorisation compacte',
},
{
typeCode: 'gearbox-assembly',
suggestedModelCodes: ['gearbox-bonfiglioli'],
notes: 'Montage sur arbre',
},
],
},
},
{
code: 'bucket-boot-heavy',
name: 'Pied élévateur renforcé',
description: 'Pied avec tension à vis.',
typeCode: 'bucket-boot-section',
structure: {
recommendedCustomFields: {
'Capacité trémie (L)': '480',
'Mode de tension': 'Vis manuelle',
'Système de nettoyage': 'Grattoirs',
},
pieceTemplates: [
{
typeCode: 'flat-gasket',
modelCode: 'gasket-ht-200',
quantity: 2,
usage: 'Etanchéité trappes',
},
{
typeCode: 'hex-screw',
modelCode: 'screw-m12x80',
quantity: 16,
usage: 'Assemblage flasques',
},
],
subComponentTemplates: [
{
typeCode: 'motor-drive',
suggestedModelCodes: ['motor-drive-18'],
notes: 'Motorisation vis de nettoyage',
},
],
},
},
{
code: 'bucket-boot-compact',
name: 'Pied élévateur compact',
description: 'Pied compact avec tension hydraulique.',
typeCode: 'bucket-boot-section',
structure: {
recommendedCustomFields: {
'Capacité trémie (L)': '320',
'Mode de tension': 'Vérin hydraulique',
'Système de nettoyage': 'Trappe déportée',
},
pieceTemplates: [
{
typeCode: 'flat-gasket',
modelCode: 'gasket-ht-200',
quantity: 1,
usage: 'Joint inspection',
},
],
},
},
{
code: 'bucket-leg-3m',
name: 'Tronçon 3 m',
description: 'Gaine 3 mètres renforcée.',
typeCode: 'bucket-leg-section',
structure: {
recommendedCustomFields: {
'Hauteur section (m)': '3',
'Type de gaine': 'Boulonnée',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m12x80',
quantity: 32,
usage: 'Assemblage brides',
},
],
},
},
{
code: 'bucket-leg-2-5m',
name: 'Tronçon 2,5 m',
description: 'Gaine 2,5 mètres compacte.',
typeCode: 'bucket-leg-section',
structure: {
recommendedCustomFields: {
'Hauteur section (m)': '2.5',
'Type de gaine': 'Soudée',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m10x60',
quantity: 24,
usage: 'Assemblage brides',
},
],
},
},
{
code: 'belt-drive-800',
name: "Station entraînement 800",
description: 'Station tête 800 mm.',
typeCode: 'belt-drive-station',
structure: {
recommendedCustomFields: {
'Diamètre tambour (mm)': '630',
'Type de racleur': 'Polyuréthane',
},
pieceTemplates: [
{
typeCode: 'roller-bearing',
modelCode: 'bearing-ucp210',
quantity: 2,
usage: 'Paliers tambour',
},
{
typeCode: 'drive-belt',
modelCode: 'belt-hd-800',
quantity: 1,
usage: 'Bande principale',
},
],
subComponentTemplates: [
{
typeCode: 'motor-drive',
suggestedModelCodes: ['motor-drive-45'],
notes: 'Motorisation convoyeur',
},
{
typeCode: 'gearbox-assembly',
suggestedModelCodes: ['gearbox-bonfiglioli'],
notes: 'Réducteur montage sur arbre',
},
],
},
},
{
code: 'belt-drive-650',
name: "Station entraînement 650",
description: 'Station tête 650 mm.',
typeCode: 'belt-drive-station',
structure: {
recommendedCustomFields: {
'Diamètre tambour (mm)': '520',
'Type de racleur': 'Caoutchouc',
},
pieceTemplates: [
{
typeCode: 'roller-bearing',
modelCode: 'bearing-ucfl207',
quantity: 2,
usage: 'Paliers excentriques',
},
],
subComponentTemplates: [
{
typeCode: 'motor-drive',
suggestedModelCodes: ['motor-drive-37'],
notes: 'Motorisation secondaire',
},
],
},
},
{
code: 'belt-tail-800',
name: 'Station retour 800',
description: 'Retour 800 mm avec racleur.',
typeCode: 'belt-tail-station',
structure: {
recommendedCustomFields: {
'Type de racleur retour': 'Racleur bande mousse',
'Système tension': 'Vis double',
},
pieceTemplates: [
{
typeCode: 'roller-bearing',
modelCode: 'bearing-ucp210',
quantity: 2,
usage: 'Paliers tambour retour',
},
{
typeCode: 'hex-screw',
modelCode: 'screw-m12x80',
quantity: 12,
usage: 'Fixation réglages',
},
],
},
},
{
code: 'belt-tail-650',
name: 'Station retour 650',
description: 'Retour 650 mm compact.',
typeCode: 'belt-tail-station',
structure: {
recommendedCustomFields: {
'Type de racleur retour': 'Racleur brosse',
'Système tension': 'Poids',
},
pieceTemplates: [
{
typeCode: 'roller-bearing',
modelCode: 'bearing-ucfl207',
quantity: 2,
usage: 'Paliers retour',
},
],
},
},
{
code: 'belt-frame-18m',
name: 'Ossature 18 m',
description: 'Châssis convoyeur 18 m.',
typeCode: 'belt-support-frame',
structure: {
recommendedCustomFields: {
'Longueur module (m)': '6',
'Nombre de rouleaux': '45',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m12x80',
quantity: 60,
usage: 'Assemblage modules',
},
],
},
},
{
code: 'belt-frame-25m',
name: 'Ossature 25 m',
description: 'Châssis convoyeur 25 m.',
typeCode: 'belt-support-frame',
structure: {
recommendedCustomFields: {
'Longueur module (m)': '8.3',
'Nombre de rouleaux': '68',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m12x80',
quantity: 84,
usage: 'Assemblage modules',
},
],
},
},
{
code: 'gravity-deck-120',
name: 'Plateau densimétrique 120',
description: 'Plateau haute capacité.',
typeCode: 'gravity-vibration-deck',
structure: {
recommendedCustomFields: {
'Inclinaison plateau (°)': '6',
'Tamis maille (µm)': '650',
'Amplitude vibration (mm)': '4.5',
},
pieceTemplates: [
{
typeCode: 'speed-sensor',
modelCode: 'sensor-speed-m18',
quantity: 2,
usage: 'Suivi vibrations',
},
{
typeCode: 'filter-cartridge',
modelCode: 'filter-dust-610',
quantity: 1,
usage: 'Aspiration plateau',
},
],
subComponentTemplates: [
{
typeCode: 'ventilation-fan',
suggestedModelCodes: ['fan-process-45'],
notes: 'Aspiration principale',
},
],
},
},
{
code: 'gravity-deck-80',
name: 'Plateau densimétrique 80',
description: 'Plateau compact.',
typeCode: 'gravity-vibration-deck',
structure: {
recommendedCustomFields: {
'Inclinaison plateau (°)': '5',
'Tamis maille (µm)': '450',
'Amplitude vibration (mm)': '3.2',
},
pieceTemplates: [
{
typeCode: 'speed-sensor',
modelCode: 'sensor-speed-m12',
quantity: 1,
usage: 'Capteur de vibration',
},
],
},
},
{
code: 'fan-process-45',
name: 'Ventilateur 45 kW',
description: 'Ventilateur centrifuge 45 kW.',
typeCode: 'ventilation-fan',
structure: {
recommendedCustomFields: {
'Débit (m³/h)': '48000',
'Pression disponible (Pa)': '3200',
'Sens de rotation': 'Horaire',
},
pieceTemplates: [
{
typeCode: 'roller-bearing',
modelCode: 'bearing-ucp210',
quantity: 2,
usage: 'Roulements arbre ventilateur',
},
{
typeCode: 'temperature-probe',
modelCode: 'temp-probe-pt100',
quantity: 1,
usage: 'Surveillance chauffe palier',
},
],
subComponentTemplates: [
{
typeCode: 'motor-drive',
suggestedModelCodes: ['motor-drive-110'],
notes: 'Entraînement direct haute puissance',
},
],
},
},
{
code: 'fan-process-30',
name: 'Ventilateur 30 kW',
description: 'Ventilateur centrifuge 30 kW.',
typeCode: 'ventilation-fan',
structure: {
recommendedCustomFields: {
'Débit (m³/h)': '28000',
'Pression disponible (Pa)': '2200',
'Sens de rotation': 'Antihoraire',
},
pieceTemplates: [
{
typeCode: 'roller-bearing',
modelCode: 'bearing-ucfl207',
quantity: 2,
usage: 'Roulements',
},
{
typeCode: 'temperature-probe',
modelCode: 'temp-probe-pt100-short',
quantity: 1,
usage: 'Sonde palier',
},
],
},
},
{
code: 'control-panel-m340',
name: 'Armoire Schneider M340',
description: 'Armoire Schneider Electric.',
typeCode: 'control-panel',
structure: {
recommendedCustomFields: {
'Automate principal': 'Schneider Modicon M340',
'Indice de protection': 'IP55',
'Capacité IO': '48',
},
pieceTemplates: [
{
typeCode: 'fuse-cartridge',
modelCode: 'fuse-gg-25a',
quantity: 3,
usage: 'Protection générale',
},
{
typeCode: 'temperature-probe',
modelCode: 'temp-probe-pt100-short',
quantity: 1,
usage: 'Sonde ambiance armoire',
},
],
subComponentTemplates: [
{
typeCode: 'control-panel',
suggestedModelCodes: ['control-panel-s7'],
notes: 'Extension communication',
},
],
},
},
{
code: 'control-panel-s7',
name: 'Armoire Siemens S7',
description: 'Armoire Siemens S7-1500.',
typeCode: 'control-panel',
structure: {
recommendedCustomFields: {
'Automate principal': 'Siemens S7-1500',
'Indice de protection': 'IP54',
'Capacité IO': '64',
},
pieceTemplates: [
{
typeCode: 'fuse-cartridge',
modelCode: 'fuse-gg-40a',
quantity: 3,
usage: 'Protection circuits puissance',
},
{
typeCode: 'temperature-probe',
modelCode: 'temp-probe-pt100',
quantity: 1,
usage: 'Sonde coffret',
},
],
},
},
{
code: 'burner-module-3mw',
name: 'Brûleur gaz 3 MW',
description: 'Brûleur gaz modulant.',
typeCode: 'burner-module',
structure: {
recommendedCustomFields: {
'Puissance thermique (MW)': '3',
'Type de combustible': 'Gaz naturel',
'Taux O2 résiduel (%)': '4',
},
pieceTemplates: [
{
typeCode: 'temperature-probe',
modelCode: 'temp-probe-pt100',
quantity: 2,
usage: 'Surveillance foyer',
},
{
typeCode: 'hydraulic-hose',
modelCode: 'hydraulic-hose-2w',
quantity: 1,
usage: 'Alimentation vérin clapet',
},
],
subComponentTemplates: [
{
typeCode: 'dust-filter',
suggestedModelCodes: ['dust-filter-cyclone'],
notes: 'Aspiration fumées',
},
],
},
},
{
code: 'burner-module-2mw',
name: 'Brûleur biomasse 2 MW',
description: 'Brûleur biomasse compact.',
typeCode: 'burner-module',
structure: {
recommendedCustomFields: {
'Puissance thermique (MW)': '2',
'Type de combustible': 'Biomasse',
'Taux O2 résiduel (%)': '5',
},
pieceTemplates: [
{
typeCode: 'temperature-probe',
modelCode: 'temp-probe-pt100-short',
quantity: 2,
usage: 'Surveillance foyer',
},
{
typeCode: 'flat-gasket',
modelCode: 'gasket-ht-200',
quantity: 4,
usage: 'Trappes de visite',
},
],
},
},
{
code: 'dryer-column-2m',
name: 'Segment colonne 2 m',
description: 'Segment de colonne zone chaude.',
typeCode: 'dryer-column-segment',
structure: {
recommendedCustomFields: {
'Hauteur segment (m)': '2',
'Zone procédé': 'Chauffage',
'Isolation (mm)': '80',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m12x80',
quantity: 40,
usage: 'Assemblage panneaux',
},
{
typeCode: 'flat-gasket',
modelCode: 'gasket-ht-200',
quantity: 6,
usage: 'Joints inspections',
},
],
subComponentTemplates: [
{
typeCode: 'burner-module',
suggestedModelCodes: ['burner-module-3mw'],
notes: 'Brûleur associé zone chaude',
},
],
},
},
{
code: 'dryer-column-1-5m',
name: 'Segment colonne 1,5 m',
description: 'Segment zone refroidissement.',
typeCode: 'dryer-column-segment',
structure: {
recommendedCustomFields: {
'Hauteur segment (m)': '1.5',
'Zone procédé': 'Refroidissement',
'Isolation (mm)': '60',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m10x60',
quantity: 32,
usage: 'Assemblage panneaux',
},
{
typeCode: 'filter-cartridge',
modelCode: 'filter-dust-480',
quantity: 1,
usage: 'Filtration air',
},
],
},
},
{
code: 'dust-filter-cyclone',
name: 'Filtre cyclone 610',
description: 'Filtre cyclone 6 cartouches.',
typeCode: 'dust-filter',
structure: {
recommendedCustomFields: {
'Nombre de cartouches': '6',
'Surface filtration (m²)': '48',
'Mode nettoyage': 'Pulse jet',
},
pieceTemplates: [
{
typeCode: 'filter-cartridge',
modelCode: 'filter-dust-610',
quantity: 6,
usage: 'Cartouches filtrantes',
},
{
typeCode: 'temperature-probe',
modelCode: 'temp-probe-pt100',
quantity: 1,
usage: 'Sonde température air',
},
],
subComponentTemplates: [
{
typeCode: 'ventilation-fan',
suggestedModelCodes: ['fan-process-45'],
notes: 'Ventilateur extraction',
},
],
},
},
{
code: 'dust-filter-compact',
name: 'Filtre compact 480',
description: 'Filtre compact 4 cartouches.',
typeCode: 'dust-filter',
structure: {
recommendedCustomFields: {
'Nombre de cartouches': '4',
'Surface filtration (m²)': '28',
'Mode nettoyage': 'Vibration',
},
pieceTemplates: [
{
typeCode: 'filter-cartridge',
modelCode: 'filter-dust-480',
quantity: 4,
usage: 'Cartouches filtrantes',
},
],
},
},
{
code: 'screw-trough-200',
name: 'Caisson vis 200',
description: 'Caisson pour vis 200 mm.',
typeCode: 'screw-trough-section',
structure: {
recommendedCustomFields: {
'Diamètre vis (mm)': '200',
'Longueur module (m)': '2',
'Finition intérieure': 'Galvanisée',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m10x60',
quantity: 28,
usage: 'Assemblage couvercles',
},
{
typeCode: 'lock-washer',
modelCode: 'washer-grower-10',
quantity: 28,
usage: 'Maintien visserie',
},
],
subComponentTemplates: [
{
typeCode: 'motor-drive',
suggestedModelCodes: ['motor-drive-18'],
notes: 'Motorisation vis 200',
},
{
typeCode: 'gearbox-assembly',
suggestedModelCodes: ['gearbox-sew'],
notes: 'Réducteur vis 200',
},
],
},
},
{
code: 'screw-trough-160',
name: 'Caisson vis 160',
description: 'Caisson pour vis 160 mm.',
typeCode: 'screw-trough-section',
structure: {
recommendedCustomFields: {
'Diamètre vis (mm)': '160',
'Longueur module (m)': '1.6',
'Finition intérieure': 'Peinte',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m8x30',
quantity: 24,
usage: 'Assemblage couvercles',
},
],
subComponentTemplates: [
{
typeCode: 'motor-drive',
suggestedModelCodes: ['motor-drive-15'],
notes: 'Motorisation vis 160',
},
],
},
},
{
code: 'screw-inlet-200',
name: 'Trémie alimentation 200',
description: 'Trémie 200 l anti-gravats.',
typeCode: 'screw-inlet-hopper',
structure: {
recommendedCustomFields: {
'Capacité (L)': '200',
'Type grille': 'Anti-gravats',
'Présence capteur niveau': 'Oui',
},
pieceTemplates: [
{
typeCode: 'speed-sensor',
modelCode: 'sensor-speed-m12',
quantity: 1,
usage: 'Capteur niveau vibrant',
},
{
typeCode: 'hex-screw',
modelCode: 'screw-m8x30',
quantity: 12,
usage: 'Fixation grille',
},
],
},
},
{
code: 'screw-inlet-160',
name: 'Trémie alimentation 160',
description: 'Trémie 160 l compacte.',
typeCode: 'screw-inlet-hopper',
structure: {
recommendedCustomFields: {
'Capacité (L)': '160',
'Type grille': 'Maille fine',
'Présence capteur niveau': 'Non',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m8x30',
quantity: 8,
usage: 'Fixation couvercle',
},
],
},
},
{
code: 'screw-outlet-vanne',
name: 'Goulotte vanne guillotine',
description: 'Goulotte sortie vanne guillotine.',
typeCode: 'screw-outlet-chute',
structure: {
recommendedCustomFields: {
'Type de vanne': 'Guillotine',
'Commande': 'Manuelle',
'Largeur (mm)': '220',
},
pieceTemplates: [
{
typeCode: 'flat-gasket',
modelCode: 'gasket-ht-200',
quantity: 2,
usage: "Joint d'accouplement",
},
{
typeCode: 'hex-screw',
modelCode: 'screw-m10x60',
quantity: 10,
usage: 'Fixation bride',
},
],
},
},
{
code: 'screw-outlet-flap',
name: 'Goulotte vanne clapet',
description: 'Goulotte sortie vanne clapet.',
typeCode: 'screw-outlet-chute',
structure: {
recommendedCustomFields: {
'Type de vanne': 'Clapet',
'Commande': 'Pneumatique',
'Largeur (mm)': '180',
},
pieceTemplates: [
{
typeCode: 'hydraulic-hose',
modelCode: 'hydraulic-hose-2w',
quantity: 1,
usage: 'Raccordement vérin',
},
],
},
},
{
code: 'weigh-frame-5t',
name: 'Cadre peseur 5T',
description: 'Cadre peseur 5 tonnes.',
typeCode: 'weigh-load-frame',
structure: {
recommendedCustomFields: {
'Capacité pesée (kg)': '5000',
'Matière': 'Acier galvanisé',
'Nombre de cellules': '4',
},
pieceTemplates: [
{
typeCode: 'load-cell',
modelCode: 'load-cell-5t',
quantity: 4,
usage: 'Cellules de pesée',
},
{
typeCode: 'hex-screw',
modelCode: 'screw-m12x80',
quantity: 16,
usage: 'Fixation platines',
},
],
},
},
{
code: 'weigh-frame-3t',
name: 'Cadre peseur 3T',
description: 'Cadre peseur 3 tonnes.',
typeCode: 'weigh-load-frame',
structure: {
recommendedCustomFields: {
'Capacité pesée (kg)': '3000',
'Matière': 'Acier peint',
'Nombre de cellules': '4',
},
pieceTemplates: [
{
typeCode: 'load-cell',
modelCode: 'load-cell-5t',
quantity: 4,
usage: 'Cellules de pesée',
},
],
},
},
{
code: 'weigh-gate-hydraulic',
name: 'Vanne hydraulique',
description: 'Vanne hydraulique ouverture rapide.',
typeCode: 'weigh-discharge-gate',
structure: {
recommendedCustomFields: {
'Type dactionnement': 'Hydraulique',
'Temps ouverture (s)': '2.5',
'Pression service (bar)': '180',
},
pieceTemplates: [
{
typeCode: 'hydraulic-hose',
modelCode: 'hydraulic-hose-2w',
quantity: 2,
usage: 'Lignes de puissance',
},
],
},
},
{
code: 'weigh-gate-screw',
name: 'Vanne vis motorisée',
description: 'Vanne motoréducteur vis.',
typeCode: 'weigh-discharge-gate',
structure: {
recommendedCustomFields: {
'Type dactionnement': 'Motoréducteur vis',
'Temps ouverture (s)': '6',
'Couple (Nm)': '450',
},
pieceTemplates: [
{
typeCode: 'motor-drive',
modelCode: 'motor-drive-15',
quantity: 1,
usage: 'Motorisation vanne',
},
],
subComponentTemplates: [
{
typeCode: 'gearbox-assembly',
suggestedModelCodes: ['gearbox-sew'],
notes: 'Réducteur vanne',
},
],
},
},
{
code: 'hydraulic-pack-tele',
name: 'Groupe hydraulique 140 l/min',
description: 'Groupe hydraulique Manitou.',
typeCode: 'hydraulic-power-pack',
structure: {
recommendedCustomFields: {
'Débit nominal (l/min)': '140',
'Pression nominale (bar)': '250',
'Nombre de distributeurs': '3',
},
pieceTemplates: [
{
typeCode: 'hydraulic-hose',
modelCode: 'hydraulic-hose-2w',
quantity: 4,
usage: 'Lignes auxiliaires',
},
{
typeCode: 'lubrication-cartridge',
modelCode: 'grease-cartridge-400',
quantity: 2,
usage: 'Graissage articulations',
},
],
},
},
{
code: 'tele-boom-8m',
name: 'Flèche télescopique 8 m',
description: 'Flèche 4 sections 8 m.',
typeCode: 'telehandler-boom',
structure: {
recommendedCustomFields: {
'Hauteur max (m)': '8',
'Nombre de sections': '4',
'Traitement anticorrosion': 'Peinture époxy',
},
pieceTemplates: [
{
typeCode: 'hydraulic-hose',
modelCode: 'hydraulic-hose-2w',
quantity: 3,
usage: 'Vérins télescopiques',
},
],
subComponentTemplates: [
{
typeCode: 'hydraulic-power-pack',
suggestedModelCodes: ['hydraulic-pack-tele'],
notes: 'Alimentation vérins',
},
],
},
},
{
code: 'tele-cab-premium',
name: 'Cabine premium climatisée',
description: 'Cabine Manitou climatisée.',
typeCode: 'telehandler-cab-module',
structure: {
recommendedCustomFields: {
'Climatisation': 'Oui',
'Suspension cabine': 'Hydraulique',
'Siège chauffant': 'Oui',
},
pieceTemplates: [
{
typeCode: 'temperature-probe',
modelCode: 'temp-probe-pt100-short',
quantity: 1,
usage: 'Sonde confort cabine',
},
],
},
},
{
code: 'tele-carrier-quick',
name: 'Attache rapide universelle',
description: 'Support doutils Manitou.',
typeCode: 'telehandler-attachment-carrier',
structure: {
recommendedCustomFields: {
'Type attache': 'Euro',
'Capacité (kg)': '3500',
'Verrouillage hydraulique': 'Oui',
},
pieceTemplates: [
{
typeCode: 'hex-screw',
modelCode: 'screw-m12x80',
quantity: 10,
usage: 'Fixation crochets',
},
{
typeCode: 'hydraulic-hose',
modelCode: 'hydraulic-hose-2w',
quantity: 1,
usage: 'Commande verrouillage',
},
],
},
},
];
const constructeurDefinitions: ConstructeurDefinition[] = [
{
key: 'buhler',
name: 'Bühler Grain Systems',
email: 'contact@buhlergroup.com',
phone: '+41 71 955 11 11',
},
{
key: 'agritech',
name: 'Agritech Elevators',
email: 'info@agritech.fr',
phone: '+33 4 78 12 34 56',
},
{
key: 'valmont',
name: 'Valmont Handling',
email: 'sales@valmont.fr',
phone: '+33 3 88 77 41 20',
},
{
key: 'agridry',
name: 'Agridry Systems',
email: 'support@agridry.eu',
phone: '+33 2 41 52 78 00',
},
{
key: 'agrifan',
name: 'AgriFan Ventilation',
email: 'contact@agrifan.fr',
phone: '+33 2 44 55 12 32',
},
{
key: 'manitou',
name: 'Manitou Group',
email: 'support@manitou-group.com',
phone: '+33 2 40 09 10 11',
},
{
key: 'sew',
name: 'SEW-Eurodrive',
email: 'info@sew-eurodrive.fr',
phone: '+33 4 72 24 60 00',
},
{
key: 'flender',
name: 'Flender GmbH',
email: 'contact@flender.com',
phone: '+49 203 998 0',
},
{
key: 'bonfiglioli',
name: 'Bonfiglioli Riduttori',
email: 'sales@bonfiglioli.com',
phone: '+39 051 647 3111',
},
{
key: 'poclain',
name: 'Poclain Hydraulics',
email: 'support@poclain-hydraulics.com',
phone: '+33 3 44 31 74 00',
},
{
key: 'ifm',
name: 'IFM Electronic',
email: 'contact@ifm.com',
phone: '+33 1 69 11 37 00',
},
{
key: 'skf',
name: 'SKF France',
email: 'support@skf.com',
phone: '+33 4 37 24 64 00',
},
];
const typeMachineDefinitions: TypeMachineDefinition[] = [
{
code: 'bucket-elevator',
name: 'Élévateur à godets industriel',
description: 'Machine de manutention verticale pour élévation de céréales.',
category: 'Triage & convoyage',
maintenanceFrequency:
"Inspection journalière des trappes, graissage hebdomadaire des paliers, contrôle courroie mensuel.",
specifications: {
zone: 'Réception',
instrumentation: ['Capteur vitesse', 'Capteur niveau'],
},
customFields: [
{ name: 'Capacité nominale (t/h)', type: 'number', required: true },
{ name: 'Hauteur de levage (m)', type: 'number', required: true },
{
name: 'Produit traité',
type: 'select',
options: ['Blé tendre', 'Orge brassicole', 'Maïs grain'],
defaultValue: 'Blé tendre',
required: true,
},
{ name: 'Date de mise en service', type: 'date', required: true },
],
componentRequirements: [
{
label: "Tête d'élévateur",
typeCode: 'bucket-head-section',
minCount: 1,
maxCount: 1,
required: true,
},
{
label: "Pied d'élévateur",
typeCode: 'bucket-boot-section',
minCount: 1,
maxCount: 1,
required: true,
},
{
label: 'Tronçons de gaine',
typeCode: 'bucket-leg-section',
minCount: 2,
required: true,
},
{
label: 'Motorisation principale',
typeCode: 'motor-drive',
minCount: 1,
required: true,
},
{
label: 'Réducteur principal',
typeCode: 'gearbox-assembly',
minCount: 1,
required: true,
},
{
label: 'Armoire locale',
typeCode: 'control-panel',
minCount: 1,
maxCount: 1,
required: false,
},
],
pieceRequirements: [
{
label: 'Courroie élévatrice',
typeCode: 'drive-belt',
minCount: 1,
required: true,
},
{
label: 'Capteur de vitesse',
typeCode: 'speed-sensor',
minCount: 1,
required: false,
},
{
label: 'Kit visserie structure',
typeCode: 'hex-screw',
minCount: 1,
required: false,
},
],
},
{
code: 'belt-conveyor',
name: 'Convoyeur à bande industriel',
description: 'Convoyeur horizontal ou incliné pour transfert de grains.',
category: 'Triage & convoyage',
maintenanceFrequency: 'Contrôle visuel quotidien, réglage de bande hebdomadaire, révision annuelle.',
specifications: {
zone: 'Transfert',
supports: ['Passerelle', 'Structure acier'],
},
customFields: [
{ name: 'Débit (t/h)', type: 'number', required: true },
{ name: 'Longueur (m)', type: 'number', required: true },
{
name: 'Localisation',
type: 'select',
options: ['Réception', 'Nettoyage', 'Expédition'],
defaultValue: 'Réception',
},
],
componentRequirements: [
{
label: "Station d'entraînement",
typeCode: 'belt-drive-station',
minCount: 1,
maxCount: 1,
required: true,
},
{
label: 'Station de retour',
typeCode: 'belt-tail-station',
minCount: 1,
maxCount: 1,
required: true,
},
{
label: 'Ossature intermédiaire',
typeCode: 'belt-support-frame',
minCount: 1,
required: true,
},
{
label: 'Motorisation convoyeur',
typeCode: 'motor-drive',
minCount: 1,
required: true,
},
{
label: 'Réducteur convoyeur',
typeCode: 'gearbox-assembly',
minCount: 1,
required: true,
},
{
label: 'Coffret de commande',
typeCode: 'control-panel',
minCount: 1,
required: false,
},
],
pieceRequirements: [
{
label: 'Bande transporteuse',
typeCode: 'drive-belt',
minCount: 1,
required: true,
},
{
label: 'Paliers supports',
typeCode: 'roller-bearing',
minCount: 2,
required: false,
},
{
label: 'Visserie ossature',
typeCode: 'hex-screw',
minCount: 1,
required: false,
},
],
},
{
code: 'gravity-separator',
name: 'Table densimétrique',
description: 'Table vibrante pour séparation par densité.',
category: 'Nettoyage',
maintenanceFrequency: 'Nettoyage tamis quotidien, contrôle vibrateurs hebdomadaire.',
specifications: {
zone: 'Nettoyage fin',
aspiration: true,
},
customFields: [
{ name: 'Capacité de tri (t/h)', type: 'number', required: true },
{
name: 'Produit traité',
type: 'select',
options: ['Blé', 'Orge', 'Tournesol'],
defaultValue: 'Blé',
},
{ name: 'Date de mise en service', type: 'date', required: true },
],
componentRequirements: [
{
label: 'Plateau vibrant',
typeCode: 'gravity-vibration-deck',
minCount: 1,
required: true,
},
{
label: 'Ventilateur aspiration',
typeCode: 'ventilation-fan',
minCount: 1,
required: true,
},
{
label: 'Armoire de réglage',
typeCode: 'control-panel',
minCount: 1,
required: true,
},
],
pieceRequirements: [
{
label: 'Capteur vibration',
typeCode: 'speed-sensor',
minCount: 1,
required: false,
},
{
label: 'Kit visserie plateau',
typeCode: 'hex-screw',
minCount: 1,
required: false,
},
{
label: 'Cartouche aspiration',
typeCode: 'filter-cartridge',
minCount: 1,
required: false,
},
],
},
{
code: 'grain-dryer',
name: 'Séchoir à grains continu',
description: 'Système de séchage continu haute capacité.',
category: 'Séchage',
maintenanceFrequency:
'Contrôle brûleur hebdomadaire, nettoyage filtre et vérification ventilateurs mensuels.',
specifications: {
bâtiment: 'Tour de séchage',
energie: ['Gaz naturel', 'Électricité'],
},
customFields: [
{ name: 'Capacité sèche (t/h)', type: 'number', required: true },
{
name: 'Mode dalimentation',
type: 'select',
options: ['Élévateur principal', 'Vis de reprise'],
defaultValue: 'Élévateur principal',
},
{ name: 'Date de mise en service', type: 'date', required: true },
],
componentRequirements: [
{
label: 'Module brûleur',
typeCode: 'burner-module',
minCount: 1,
required: true,
},
{
label: 'Colonnes de séchage',
typeCode: 'dryer-column-segment',
minCount: 2,
required: true,
},
{
label: 'Ventilation process',
typeCode: 'ventilation-fan',
minCount: 1,
required: true,
},
{
label: 'Filtre poussières',
typeCode: 'dust-filter',
minCount: 1,
required: true,
},
{
label: 'Armoire de pilotage',
typeCode: 'control-panel',
minCount: 1,
required: true,
},
],
pieceRequirements: [
{
label: 'Sondes température',
typeCode: 'temperature-probe',
minCount: 2,
required: false,
},
{
label: 'Joints haute température',
typeCode: 'flat-gasket',
minCount: 1,
required: false,
},
{
label: 'Cartouches dépoussiéreur',
typeCode: 'filter-cartridge',
minCount: 2,
required: false,
},
],
},
{
code: 'screw-conveyor',
name: 'Vis de reprise céréales',
description: 'Vis sans fin pour reprise et rechargement des silos.',
category: 'Convoyage',
maintenanceFrequency: 'Graissage paliers hebdomadaire, inspection trémie mensuelle.',
specifications: {
position: ['Sous cellules', 'Sortie séchoir'],
},
customFields: [
{ name: 'Diamètre vis (mm)', type: 'number', required: true },
{ name: 'Inclinaison (°)', type: 'number' },
{ name: 'Vitesse (rpm)', type: 'number' },
],
componentRequirements: [
{
label: 'Caisson principal',
typeCode: 'screw-trough-section',
minCount: 1,
required: true,
},
{
label: "Trémie d'alimentation",
typeCode: 'screw-inlet-hopper',
minCount: 1,
required: true,
},
{
label: 'Goulotte de sortie',
typeCode: 'screw-outlet-chute',
minCount: 1,
required: true,
},
{
label: 'Motorisation vis',
typeCode: 'motor-drive',
minCount: 1,
required: true,
},
{
label: 'Réducteur vis',
typeCode: 'gearbox-assembly',
minCount: 1,
required: true,
},
],
pieceRequirements: [
{
label: 'Paliers de ligne',
typeCode: 'roller-bearing',
minCount: 2,
required: false,
},
{
label: 'Kit visserie caisson',
typeCode: 'hex-screw',
minCount: 1,
required: false,
},
{
label: 'Cartouches de graisse',
typeCode: 'lubrication-cartridge',
minCount: 1,
required: false,
},
],
},
{
code: 'weigh-hopper',
name: 'Benne peseuse',
description: 'Benne peseuse pour chargement camions ou big-bags.',
category: 'Expédition',
maintenanceFrequency: 'Vérification capteurs hebdomadaire, recalibrage trimestriel.',
specifications: {
utilisation: ['Chargement camion', 'Conditionnement big-bag'],
},
customFields: [
{ name: 'Capacité de pesée (kg)', type: 'number', required: true },
{
name: 'Précision (%)',
type: 'number',
required: true,
},
{
name: 'Mode de vidange',
type: 'select',
options: ['Trappe motorisée', 'Vis doseuse', 'Vanne guillotine'],
defaultValue: 'Trappe motorisée',
},
],
componentRequirements: [
{
label: 'Cadre peseur',
typeCode: 'weigh-load-frame',
minCount: 1,
required: true,
},
{
label: 'Vanne de vidange',
typeCode: 'weigh-discharge-gate',
minCount: 1,
required: true,
},
{
label: 'Coffret de pesage',
typeCode: 'control-panel',
minCount: 1,
required: true,
},
],
pieceRequirements: [
{
label: 'Capteurs de pesage',
typeCode: 'load-cell',
minCount: 2,
required: true,
},
{
label: 'Fusibles de protection',
typeCode: 'fuse-cartridge',
minCount: 1,
required: false,
},
{
label: 'Joint trappe',
typeCode: 'flat-gasket',
minCount: 1,
required: false,
},
],
},
{
code: 'telehandler',
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: 'Flèche télescopique',
typeCode: 'telehandler-boom',
minCount: 1,
required: true,
},
{
label: 'Groupe hydraulique',
typeCode: 'hydraulic-power-pack',
minCount: 1,
required: true,
},
{
label: 'Groupe moteur',
typeCode: 'motor-drive',
minCount: 1,
required: true,
},
{
label: 'Cabine opérateur',
typeCode: 'telehandler-cab-module',
minCount: 1,
required: true,
},
{
label: 'Support doutils',
typeCode: 'telehandler-attachment-carrier',
minCount: 1,
required: true,
},
],
pieceRequirements: [
{
label: 'Flexibles hydrauliques',
typeCode: 'hydraulic-hose',
minCount: 2,
required: false,
},
{
label: 'Fusibles cabine',
typeCode: 'fuse-cartridge',
minCount: 1,
required: false,
},
{
label: 'Cartouches graissage',
typeCode: 'lubrication-cartridge',
minCount: 1,
required: false,
},
],
},
];
const machineBuilds: MachineBuildSpec[] = [
{
code: 'bucket-elevator-upstream',
typeMachineCode: 'bucket-elevator',
name: 'Élévateur amont Z400',
reference: 'BE-Z400-01',
prix: '58000',
constructeurKey: 'agritech',
customFieldValues: {
'Capacité nominale (t/h)': 120,
'Hauteur de levage (m)': 38,
'Produit traité': 'Blé tendre',
'Date de mise en service': new Date('2023-10-12'),
},
components: [
{
name: 'Tête haute Z400',
reference: 'BE-TETE-400',
prix: '18500',
typeCode: 'bucket-head-section',
requirementLabel: "Tête d'élévateur",
modelCode: 'bucket-head-120',
constructeur: 'agritech',
customValues: {
'Largeur tambour (mm)': 820,
'Type de revêtement': 'Caoutchouc rainuré',
'Nombre de trappes': 3,
},
pieces: [
{
name: 'Kit visserie tête',
reference: 'KIT-TETE-01',
typeCode: 'hex-screw',
modelCode: 'screw-m12x80',
customValues: {
'Diamètre (mm)': 12,
'Longueur (mm)': 80,
'Classe acier': '8.8',
},
},
{
name: 'Rondelles de sécurité Ø12',
reference: 'RDL-TETE-01',
typeCode: 'lock-washer',
modelCode: 'washer-grower-12',
customValues: {
'Diamètre (mm)': 12,
Finition: 'Inox',
},
},
],
children: [
{
name: 'Motorisation 75 kW',
reference: 'MTR-75-EL1',
typeCode: 'motor-drive',
requirementLabel: 'Motorisation principale',
modelCode: 'motor-drive-75',
constructeur: 'sew',
customValues: {
'Puissance nominale (kW)': 75,
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
},
{
name: 'Réducteur Flender 3200',
reference: 'GBX-FL-01',
typeCode: 'gearbox-assembly',
requirementLabel: 'Réducteur principal',
modelCode: 'gearbox-flender',
constructeur: 'flender',
customValues: {
'Rapport de réduction': '1:28',
'Couple nominal (Nm)': 3200,
'Type de montage': 'À bride',
},
},
],
},
{
name: 'Pied élévateur renforcé',
reference: 'BE-PIED-400',
prix: '14600',
typeCode: 'bucket-boot-section',
requirementLabel: "Pied d'élévateur",
modelCode: 'bucket-boot-heavy',
constructeur: 'agritech',
customValues: {
'Capacité trémie (L)': 480,
'Mode de tension': 'Vis manuelle',
'Système de nettoyage': 'Grattoirs',
},
pieces: [
{
name: 'Joint trappe inspection',
reference: 'JNT-PIED-01',
typeCode: 'flat-gasket',
modelCode: 'gasket-ht-200',
customValues: {
Matière: 'Fibre compressée',
'Épaisseur (mm)': 3,
},
},
],
},
{
name: 'Gaine intermédiaire 3 m - A',
reference: 'BE-GAINE-1',
typeCode: 'bucket-leg-section',
requirementLabel: 'Tronçons de gaine',
modelCode: 'bucket-leg-3m',
constructeur: 'agritech',
customValues: {
'Hauteur section (m)': 3,
'Type de gaine': 'Boulonnée',
},
},
{
name: 'Gaine intermédiaire 3 m - B',
reference: 'BE-GAINE-2',
typeCode: 'bucket-leg-section',
requirementLabel: 'Tronçons de gaine',
modelCode: 'bucket-leg-3m',
constructeur: 'agritech',
customValues: {
'Hauteur section (m)': 3,
'Type de gaine': 'Renforcée',
},
},
{
name: 'Armoire locale tête élévateur',
reference: 'ARM-EL-01',
prix: '7800',
typeCode: 'control-panel',
requirementLabel: 'Armoire locale',
modelCode: 'control-panel-m340',
constructeur: 'buhler',
customValues: {
'Automate principal': 'Schneider Modicon M340',
'Année de mise à jour': 2023,
"Indice de protection": 'IP55',
},
pieces: [
{
name: 'Fusible alimentation 25A',
reference: 'FS-25A-EL',
typeCode: 'fuse-cartridge',
modelCode: 'fuse-gg-25a',
customValues: {
'Calibre (A)': 25,
Type: 'gG',
},
},
],
},
],
sparePieces: [
{
name: 'Courroie de rechange 800 mm',
reference: 'SP-BELT-800',
prix: '2200',
typeCode: 'drive-belt',
modelCode: 'belt-hd-800',
constructeur: 'agritech',
requirementLabel: 'Courroie élévatrice',
customValues: {
'Largeur (mm)': 800,
Matériau: 'Caoutchouc nitrile',
},
},
{
name: 'Capteur vitesse secours',
reference: 'SP-SPEED-01',
typeCode: 'speed-sensor',
modelCode: 'sensor-speed-m12',
constructeur: 'ifm',
requirementLabel: 'Capteur de vitesse',
customValues: {
'Type de sortie': 'PNP 4-20 mA',
'Plage de mesure (rpm)': 1200,
},
},
{
name: 'Jeu visserie structure',
reference: 'SP-VISS-EL',
typeCode: 'hex-screw',
modelCode: 'screw-m12x80',
requirementLabel: 'Kit visserie structure',
customValues: {
'Diamètre (mm)': 12,
'Longueur (mm)': 80,
'Classe acier': '8.8',
},
},
],
},
{
code: 'bucket-elevator-downstream',
typeMachineCode: 'bucket-elevator',
name: 'Élévateur aval Z320',
reference: 'BE-Z320-02',
prix: '49700',
constructeurKey: 'agritech',
customFieldValues: {
'Capacité nominale (t/h)': 95,
'Hauteur de levage (m)': 32,
'Produit traité': 'Orge brassicole',
'Date de mise en service': new Date('2022-09-05'),
},
components: [
{
name: 'Tête compact Z320',
reference: 'BE-TETE-320',
typeCode: 'bucket-head-section',
requirementLabel: "Tête d'élévateur",
modelCode: 'bucket-head-95',
constructeur: 'agritech',
customValues: {
'Largeur tambour (mm)': 680,
'Type de revêtement': 'Céramique',
'Nombre de trappes': 2,
},
children: [
{
name: 'Motorisation 55 kW',
reference: 'MTR-55-EL2',
typeCode: 'motor-drive',
requirementLabel: 'Motorisation principale',
modelCode: 'motor-drive-55',
constructeur: 'sew',
customValues: {
'Puissance nominale (kW)': 55,
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
},
{
name: 'Réducteur Bonfiglioli',
reference: 'GBX-BF-02',
typeCode: 'gearbox-assembly',
requirementLabel: 'Réducteur principal',
modelCode: 'gearbox-bonfiglioli',
constructeur: 'bonfiglioli',
customValues: {
'Rapport de réduction': '1:24',
'Couple nominal (Nm)': 2100,
'Type de montage': 'Sur arbre',
},
},
],
},
{
name: 'Pied élévateur compact',
reference: 'BE-PIED-320',
typeCode: 'bucket-boot-section',
requirementLabel: "Pied d'élévateur",
modelCode: 'bucket-boot-compact',
constructeur: 'agritech',
customValues: {
'Capacité trémie (L)': 360,
'Mode de tension': 'Hydraulique',
'Système de nettoyage': 'Vide-pied',
},
},
{
name: 'Gaine intermédiaire 2,5 m',
reference: 'BE-GAINE-3',
typeCode: 'bucket-leg-section',
requirementLabel: 'Tronçons de gaine',
modelCode: 'bucket-leg-2-5m',
constructeur: 'agritech',
customValues: {
'Hauteur section (m)': 2.5,
'Type de gaine': 'Boulonnée',
},
},
{
name: 'Gaine renfort 3 m',
reference: 'BE-GAINE-4',
typeCode: 'bucket-leg-section',
requirementLabel: 'Tronçons de gaine',
modelCode: 'bucket-leg-3m',
constructeur: 'agritech',
customValues: {
'Hauteur section (m)': 3,
'Type de gaine': 'Renforcée',
},
},
{
name: 'Coffret local aval',
reference: 'ARM-EL-02',
typeCode: 'control-panel',
requirementLabel: 'Armoire locale',
modelCode: 'control-panel-s7',
constructeur: 'buhler',
customValues: {
'Automate principal': 'Siemens S7-1500',
'Année de mise à jour': 2022,
"Indice de protection": 'IP65',
},
},
],
sparePieces: [
{
name: 'Courroie de secours 650 mm',
reference: 'SP-BELT-650',
typeCode: 'drive-belt',
modelCode: 'belt-hd-650',
requirementLabel: 'Courroie élévatrice',
customValues: {
'Largeur (mm)': 650,
Matériau: 'Polyuréthane',
},
},
{
name: 'Capteur vitesse compact',
reference: 'SP-SPEED-02',
typeCode: 'speed-sensor',
modelCode: 'sensor-speed-m18',
constructeur: 'ifm',
requirementLabel: 'Capteur de vitesse',
customValues: {
'Type de sortie': 'PNP Tout ou rien',
'Plage de mesure (rpm)': 900,
},
},
{
name: 'Kit visserie élévateur aval',
reference: 'SP-VISS-EL2',
typeCode: 'hex-screw',
modelCode: 'screw-m10x60',
requirementLabel: 'Kit visserie structure',
customValues: {
'Diamètre (mm)': 10,
'Longueur (mm)': 60,
'Classe acier': '10.9',
},
},
],
},
{
code: 'belt-conveyor-feed',
typeMachineCode: 'belt-conveyor',
name: "Convoyeur alimentation 18 m",
reference: 'CV-ALIM-18',
prix: '32600',
constructeurKey: 'valmont',
customFieldValues: {
'Débit (t/h)': 110,
'Longueur (m)': 18,
Localisation: 'Réception',
},
components: [
{
name: "Station d'entraînement 800",
reference: 'CV-DRIVE-18',
typeCode: 'belt-drive-station',
requirementLabel: "Station d'entraînement",
modelCode: 'belt-drive-800',
constructeur: 'valmont',
customValues: {
'Type de tambour': 'Caoutchouc rainuré',
'Système de tension': 'Hydraulique',
},
children: [
{
name: 'Moteur 45 kW',
reference: 'MTR-45-CV1',
typeCode: 'motor-drive',
requirementLabel: 'Motorisation convoyeur',
modelCode: 'motor-drive-45',
constructeur: 'sew',
customValues: {
'Puissance nominale (kW)': 45,
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
},
{
name: 'Réducteur Bonfiglioli TA',
reference: 'GBX-TA-CV1',
typeCode: 'gearbox-assembly',
requirementLabel: 'Réducteur convoyeur',
modelCode: 'gearbox-bonfiglioli',
constructeur: 'bonfiglioli',
customValues: {
'Rapport de réduction': '1:24',
'Couple nominal (Nm)': 2100,
'Type de montage': 'Sur arbre',
},
},
],
},
{
name: 'Station de retour 800',
reference: 'CV-TAIL-18',
typeCode: 'belt-tail-station',
requirementLabel: 'Station de retour',
modelCode: 'belt-tail-800',
constructeur: 'valmont',
customValues: {
'Nettoyeur principal': 'Racleur PU',
'Diamètre tambour (mm)': 420,
},
pieces: [
{
name: 'Grattoir principal PU',
reference: 'GRAT-800-01',
typeCode: 'flat-gasket',
modelCode: 'gasket-ht-200',
customValues: {
Matière: 'NBR',
'Épaisseur (mm)': 5,
},
},
],
},
{
name: 'Ossature 18 m',
reference: 'CV-FRAME-18',
typeCode: 'belt-support-frame',
requirementLabel: 'Ossature intermédiaire',
modelCode: 'belt-frame-18m',
constructeur: 'valmont',
customValues: {
'Longueur (m)': 18,
'Nombre de rouleaux': 36,
'Type de châssis': 'Treillis',
},
pieces: [
{
name: 'Roulement UCP210',
reference: 'BRG-UCP210-02',
typeCode: 'roller-bearing',
modelCode: 'bearing-ucp210',
constructeur: 'skf',
customValues: {
Série: 'UCP',
"Type d'étanchéité": '2RS',
},
},
],
},
{
name: 'Coffret convoyeur réception',
reference: 'ARM-CV-01',
typeCode: 'control-panel',
requirementLabel: 'Coffret de commande',
modelCode: 'control-panel-m340',
constructeur: 'buhler',
customValues: {
'Automate principal': 'Schneider Modicon M340',
"Indice de protection": 'IP55',
},
},
],
sparePieces: [
{
name: 'Bande transporteuse 800 mm',
reference: 'SP-BAND-800',
typeCode: 'drive-belt',
modelCode: 'belt-hd-800',
requirementLabel: 'Bande transporteuse',
customValues: {
'Largeur (mm)': 800,
Matériau: 'Caoutchouc nitrile',
},
},
{
name: 'Kit palier de rechange',
reference: 'SP-BRG-800',
typeCode: 'roller-bearing',
modelCode: 'bearing-ucp210',
requirementLabel: 'Paliers supports',
constructeur: 'skf',
customValues: {
Série: 'UCP',
"Type d'étanchéité": '2RS',
},
},
{
name: 'Visserie ossature',
reference: 'SP-VISS-CV1',
typeCode: 'hex-screw',
modelCode: 'screw-m10x60',
requirementLabel: 'Visserie ossature',
customValues: {
'Diamètre (mm)': 10,
'Longueur (mm)': 60,
'Classe acier': '10.9',
},
},
],
},
{
code: 'belt-conveyor-expedition',
typeMachineCode: 'belt-conveyor',
name: 'Convoyeur expédition 25 m',
reference: 'CV-EXP-25',
prix: '35400',
constructeurKey: 'valmont',
customFieldValues: {
'Débit (t/h)': 90,
'Longueur (m)': 25,
Localisation: 'Expédition',
},
components: [
{
name: 'Station tête 650',
reference: 'CV-DRIVE-25',
typeCode: 'belt-drive-station',
requirementLabel: "Station d'entraînement",
modelCode: 'belt-drive-650',
constructeur: 'valmont',
customValues: {
'Type de tambour': 'Céramique',
'Système de tension': 'Vis manuelle',
},
children: [
{
name: 'Moteur 37 kW',
reference: 'MTR-37-CV2',
typeCode: 'motor-drive',
requirementLabel: 'Motorisation convoyeur',
modelCode: 'motor-drive-37',
constructeur: 'sew',
customValues: {
'Puissance nominale (kW)': 37,
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
},
{
name: 'Réducteur SEW K',
reference: 'GBX-SEW-CV2',
typeCode: 'gearbox-assembly',
requirementLabel: 'Réducteur convoyeur',
modelCode: 'gearbox-sew',
constructeur: 'sew',
customValues: {
'Rapport de réduction': '1:18',
'Couple nominal (Nm)': 1800,
'Type de montage': 'À pattes',
},
},
],
},
{
name: 'Station retour 650',
reference: 'CV-TAIL-25',
typeCode: 'belt-tail-station',
requirementLabel: 'Station de retour',
modelCode: 'belt-tail-650',
constructeur: 'valmont',
customValues: {
'Nettoyeur principal': 'Brosse acier',
'Diamètre tambour (mm)': 360,
},
},
{
name: 'Ossature 25 m',
reference: 'CV-FRAME-25',
typeCode: 'belt-support-frame',
requirementLabel: 'Ossature intermédiaire',
modelCode: 'belt-frame-25m',
constructeur: 'valmont',
customValues: {
'Longueur (m)': 25,
'Nombre de rouleaux': 48,
'Type de châssis': 'Portique',
},
},
{
name: 'Coffret expédition',
reference: 'ARM-CV-02',
typeCode: 'control-panel',
requirementLabel: 'Coffret de commande',
modelCode: 'control-panel-s7',
constructeur: 'buhler',
customValues: {
'Automate principal': 'Siemens S7-1500',
'Année de mise à jour': 2021,
"Indice de protection": 'IP65',
},
},
],
sparePieces: [
{
name: 'Bande transporteuse 650 mm',
reference: 'SP-BAND-650',
typeCode: 'drive-belt',
modelCode: 'belt-hd-650',
requirementLabel: 'Bande transporteuse',
customValues: {
'Largeur (mm)': 650,
Matériau: 'Polyuréthane',
},
},
{
name: 'Palier UCFL207',
reference: 'SP-BRG-UCFL',
typeCode: 'roller-bearing',
modelCode: 'bearing-ucfl207',
requirementLabel: 'Paliers supports',
constructeur: 'skf',
customValues: {
Série: 'UCFL',
"Type d'étanchéité": 'ZZ',
},
},
{
name: 'Visserie tendeurs',
reference: 'SP-VISS-CV2',
typeCode: 'hex-screw',
modelCode: 'screw-m8x30',
requirementLabel: 'Visserie ossature',
customValues: {
'Diamètre (mm)': 8,
'Longueur (mm)': 30,
'Classe acier': '8.8',
},
},
],
},
{
code: 'gravity-table-main',
typeMachineCode: 'gravity-separator',
name: 'Table densimétrique TQX',
reference: 'TBL-TQX-01',
prix: '68500',
constructeurKey: 'buhler',
customFieldValues: {
'Capacité de tri (t/h)': 120,
'Produit traité': 'Blé',
'Date de mise en service': new Date('2021-03-22'),
},
components: [
{
name: 'Plateau TQX-120',
reference: 'TBL-PLT-01',
typeCode: 'gravity-vibration-deck',
requirementLabel: 'Plateau vibrant',
modelCode: 'gravity-deck-120',
constructeur: 'buhler',
customValues: {
'Type de plateau': 'Acier perforé',
'Fréquence de vibration (Hz)': 45,
'Inclinaison plateau (°)': 5,
},
children: [
{
name: 'Moteur vibrateur 18,5 kW',
reference: 'MTR-18-VIB',
typeCode: 'motor-drive',
modelCode: 'motor-drive-18',
constructeur: 'sew',
customValues: {
'Puissance nominale (kW)': 18.5,
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
},
],
},
{
name: 'Ventilateur aspiration 45 kW',
reference: 'VENT-45-01',
typeCode: 'ventilation-fan',
requirementLabel: 'Ventilateur aspiration',
modelCode: 'fan-process-45',
constructeur: 'agrifan',
customValues: {
'Débit (m³/h)': 45000,
'Type de roue': 'Centrifuge',
'Vitesse nominale (rpm)': 1450,
},
},
{
name: 'Armoire réglage table',
reference: 'ARM-TBL-01',
typeCode: 'control-panel',
requirementLabel: 'Armoire de réglage',
modelCode: 'control-panel-m340',
constructeur: 'buhler',
customValues: {
'Automate principal': 'Schneider Modicon M340',
'Année de mise à jour': 2023,
"Indice de protection": 'IP55',
},
},
],
sparePieces: [
{
name: 'Capteur vibration M12',
reference: 'SP-SNS-VIB',
typeCode: 'speed-sensor',
modelCode: 'sensor-speed-m12',
requirementLabel: 'Capteur vibration',
customValues: {
'Type de sortie': 'PNP 4-20 mA',
'Plage de mesure (rpm)': 1500,
},
},
{
name: 'Kit visserie plateau',
reference: 'SP-VISS-TBL',
typeCode: 'hex-screw',
modelCode: 'screw-m8x30',
requirementLabel: 'Kit visserie plateau',
customValues: {
'Diamètre (mm)': 8,
'Longueur (mm)': 30,
'Classe acier': '8.8',
},
},
{
name: 'Cartouche aspiration 610',
reference: 'SP-FILT-610',
typeCode: 'filter-cartridge',
modelCode: 'filter-dust-610',
requirementLabel: 'Cartouche aspiration',
customValues: {
'Longueur (mm)': 610,
'Média filtrant': 'Polyester',
},
},
],
},
{
code: 'grain-dryer-main',
typeMachineCode: 'grain-dryer',
name: 'Séchoir continu SC-60',
reference: 'DRY-SC60',
prix: '212000',
constructeurKey: 'agridry',
customFieldValues: {
'Capacité sèche (t/h)': 60,
'Mode dalimentation': 'Élévateur principal',
'Date de mise en service': new Date('2020-07-15'),
},
components: [
{
name: 'Brûleur gaz 3 MW',
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',
},
},
{
name: 'Colonne zone chaude',
reference: 'COL-CHAUD-01',
typeCode: 'dryer-column-segment',
requirementLabel: 'Colonnes de séchage',
modelCode: 'dryer-column-2m',
constructeur: 'agridry',
customValues: {
'Hauteur segment (m)': 2,
'Zone de séchage': 'Échauffage',
'Capteurs intégrés': true,
},
},
{
name: 'Colonne zone tempérée',
reference: 'COL-TEMP-01',
typeCode: 'dryer-column-segment',
requirementLabel: 'Colonnes de séchage',
modelCode: 'dryer-column-1-5m',
constructeur: 'agridry',
customValues: {
'Hauteur segment (m)': 1.5,
'Zone de séchage': 'Tempe',
'Capteurs intégrés': true,
},
},
{
name: 'Ventilateur process principal',
reference: 'VENT-45-DRY',
typeCode: 'ventilation-fan',
requirementLabel: 'Ventilation process',
modelCode: 'fan-process-45',
constructeur: 'agrifan',
customValues: {
'Débit (m³/h)': 52000,
'Type de roue': 'Centrifuge',
'Vitesse nominale (rpm)': 1480,
},
children: [
{
name: 'Motorisation ventilateur 110 kW',
reference: 'MTR-110-VENT',
typeCode: 'motor-drive',
modelCode: 'motor-drive-110',
constructeur: 'sew',
customValues: {
'Puissance nominale (kW)': 110,
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
},
],
},
{
name: 'Filtre cyclone 610',
reference: 'FIL-CYCL-01',
typeCode: 'dust-filter',
requirementLabel: 'Filtre poussières',
modelCode: 'dust-filter-cyclone',
constructeur: 'agrifan',
customValues: {
'Efficacité de filtration (%)': 98,
'Type de média filtrant': 'Polyester',
'Nombre de cartouches': 6,
},
pieces: [
{
name: 'Cartouche polyester 610',
reference: 'FILT-610-01',
typeCode: 'filter-cartridge',
modelCode: 'filter-dust-610',
customValues: {
'Longueur (mm)': 610,
'Média filtrant': 'Polyester',
},
},
],
},
{
name: 'Armoire pilotage séchoir',
reference: 'ARM-DRY-01',
typeCode: 'control-panel',
requirementLabel: 'Armoire de pilotage',
modelCode: 'control-panel-m340',
constructeur: 'buhler',
customValues: {
'Automate principal': 'Schneider Modicon M340',
'Année de mise à jour': 2024,
"Indice de protection": 'IP55',
},
},
],
sparePieces: [
{
name: 'Sonde PT100 longue',
reference: 'SP-PT100-01',
typeCode: 'temperature-probe',
modelCode: 'temp-probe-pt100',
requirementLabel: 'Sondes température',
customValues: {
Type: 'PT100 classe A',
'Longueur tige (mm)': 300,
},
},
{
name: 'Sonde PT100 courte',
reference: 'SP-PT100-02',
typeCode: 'temperature-probe',
modelCode: 'temp-probe-pt100-short',
requirementLabel: 'Sondes température',
customValues: {
Type: 'PT100 classe B',
'Longueur tige (mm)': 200,
},
},
{
name: 'Joint trappe brûleur',
reference: 'SP-JOINT-DRY',
typeCode: 'flat-gasket',
modelCode: 'gasket-ht-200',
requirementLabel: 'Joints haute température',
customValues: {
Matière: 'Fibre compressée',
'Épaisseur (mm)': 4,
},
},
{
name: 'Cartouche rechange 480',
reference: 'SP-FILT-480',
typeCode: 'filter-cartridge',
modelCode: 'filter-dust-480',
requirementLabel: 'Cartouches dépoussiéreur',
customValues: {
'Longueur (mm)': 480,
'Média filtrant': 'Polyester',
},
},
],
},
{
code: 'screw-conveyor-north',
typeMachineCode: 'screw-conveyor',
name: 'Vis de reprise nord V200',
reference: 'SC-V200-N',
prix: '27400',
constructeurKey: 'valmont',
customFieldValues: {
'Diamètre vis (mm)': 200,
'Inclinaison (°)': 12,
'Vitesse (rpm)': 140,
},
components: [
{
name: 'Caisson principal 200',
reference: 'SC-CAISSON-200',
typeCode: 'screw-trough-section',
requirementLabel: 'Caisson principal',
modelCode: 'screw-trough-200',
constructeur: 'valmont',
customValues: {
'Longueur (m)': 9,
'Diamètre vis (mm)': 200,
Matériau: 'Acier peint',
},
},
{
name: "Trémie d'alimentation 200",
reference: 'SC-TREMIE-200',
typeCode: 'screw-inlet-hopper',
requirementLabel: "Trémie d'alimentation",
modelCode: 'screw-inlet-200',
constructeur: 'valmont',
customValues: {
'Capacité (L)': 220,
'Type de grille': 'Grille anti-gravats',
},
},
{
name: 'Goulotte sortie vanne',
reference: 'SC-GOUL-200',
typeCode: 'screw-outlet-chute',
requirementLabel: 'Goulotte de sortie',
modelCode: 'screw-outlet-vanne',
constructeur: 'valmont',
customValues: {
'Type de vanne': 'Guillotine',
"Orientation (°)": 45,
},
},
{
name: 'Moteur vis 18.5 kW',
reference: 'MTR-18-SC1',
typeCode: 'motor-drive',
requirementLabel: 'Motorisation vis',
modelCode: 'motor-drive-18',
constructeur: 'sew',
customValues: {
'Puissance nominale (kW)': 18.5,
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
},
{
name: 'Réducteur SEW K',
reference: 'GBX-SEW-SC1',
typeCode: 'gearbox-assembly',
requirementLabel: 'Réducteur vis',
modelCode: 'gearbox-sew',
constructeur: 'sew',
customValues: {
'Rapport de réduction': '1:32',
'Couple nominal (Nm)': 1800,
'Type de montage': 'À pattes',
},
},
],
sparePieces: [
{
name: 'Palier UCP210',
reference: 'SP-PALIER-200',
typeCode: 'roller-bearing',
modelCode: 'bearing-ucp210',
requirementLabel: 'Paliers de ligne',
constructeur: 'skf',
customValues: {
Série: 'UCP',
"Type d'étanchéité": '2RS',
},
},
{
name: 'Kit visserie caisson',
reference: 'SP-VISS-SC1',
typeCode: 'hex-screw',
modelCode: 'screw-m12x80',
requirementLabel: 'Kit visserie caisson',
customValues: {
'Diamètre (mm)': 12,
'Longueur (mm)': 80,
'Classe acier': '8.8',
},
},
{
name: 'Cartouche graisse 400g',
reference: 'SP-GRAISSE-01',
typeCode: 'lubrication-cartridge',
modelCode: 'grease-cartridge-400',
requirementLabel: 'Cartouches de graisse',
customValues: {
'Volume (cm³)': 400,
'Grade de graisse': 'NLGI 2',
},
},
],
},
{
code: 'screw-conveyor-south',
typeMachineCode: 'screw-conveyor',
name: 'Vis de reprise sud V160',
reference: 'SC-V160-S',
prix: '23600',
constructeurKey: 'valmont',
customFieldValues: {
'Diamètre vis (mm)': 160,
'Inclinaison (°)': 8,
'Vitesse (rpm)': 110,
},
components: [
{
name: 'Caisson principal 160',
reference: 'SC-CAISSON-160',
typeCode: 'screw-trough-section',
requirementLabel: 'Caisson principal',
modelCode: 'screw-trough-160',
constructeur: 'valmont',
customValues: {
'Longueur (m)': 7,
'Diamètre vis (mm)': 160,
Matériau: 'Galvanisé',
},
},
{
name: "Trémie d'alimentation 160",
reference: 'SC-TREMIE-160',
typeCode: 'screw-inlet-hopper',
requirementLabel: "Trémie d'alimentation",
modelCode: 'screw-inlet-160',
constructeur: 'valmont',
customValues: {
'Capacité (L)': 160,
'Type de grille': 'Grille magnétique',
},
},
{
name: 'Goulotte clapet',
reference: 'SC-GOUL-160',
typeCode: 'screw-outlet-chute',
requirementLabel: 'Goulotte de sortie',
modelCode: 'screw-outlet-flap',
constructeur: 'valmont',
customValues: {
'Type de vanne': 'By-pass',
"Orientation (°)": 60,
},
},
{
name: 'Moteur vis 15 kW',
reference: 'MTR-15-SC2',
typeCode: 'motor-drive',
requirementLabel: 'Motorisation vis',
modelCode: 'motor-drive-15',
constructeur: 'sew',
customValues: {
'Puissance nominale (kW)': 15,
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
},
{
name: 'Réducteur Bonfiglioli',
reference: 'GBX-BF-SC2',
typeCode: 'gearbox-assembly',
requirementLabel: 'Réducteur vis',
modelCode: 'gearbox-bonfiglioli',
constructeur: 'bonfiglioli',
customValues: {
'Rapport de réduction': '1:28',
'Couple nominal (Nm)': 1600,
'Type de montage': 'Sur arbre',
},
},
],
sparePieces: [
{
name: 'Palier UCFL207',
reference: 'SP-PALIER-160',
typeCode: 'roller-bearing',
modelCode: 'bearing-ucfl207',
requirementLabel: 'Paliers de ligne',
constructeur: 'skf',
customValues: {
Série: 'UCFL',
"Type d'étanchéité": 'ZZ',
},
},
{
name: 'Kit visserie vis 160',
reference: 'SP-VISS-SC2',
typeCode: 'hex-screw',
modelCode: 'screw-m10x60',
requirementLabel: 'Kit visserie caisson',
customValues: {
'Diamètre (mm)': 10,
'Longueur (mm)': 60,
'Classe acier': '10.9',
},
},
{
name: 'Cartouche graisse 400g',
reference: 'SP-GRAISSE-02',
typeCode: 'lubrication-cartridge',
modelCode: 'grease-cartridge-400',
requirementLabel: 'Cartouches de graisse',
customValues: {
'Volume (cm³)': 400,
'Grade de graisse': 'NLGI 2',
},
},
],
},
{
code: 'weigh-hopper-truck',
typeMachineCode: 'weigh-hopper',
name: 'Benne peseuse camion 5T',
reference: 'BP-5000-01',
prix: '39200',
constructeurKey: 'buhler',
customFieldValues: {
'Capacité de pesée (kg)': 5000,
'Précision (%)': 0.5,
'Mode de vidange': 'Trappe motorisée',
},
components: [
{
name: 'Cadre peseur 5T',
reference: 'BP-CADRE-01',
typeCode: 'weigh-load-frame',
requirementLabel: 'Cadre peseur',
modelCode: 'weigh-frame-5t',
constructeur: 'buhler',
customValues: {
'Capacité nominale (kg)': 5000,
'Nombre de capteurs': 4,
'Protection IP': 'IP65',
},
},
{
name: 'Vanne hydraulique rapide',
reference: 'BP-VANNE-01',
typeCode: 'weigh-discharge-gate',
requirementLabel: 'Vanne de vidange',
modelCode: 'weigh-gate-hydraulic',
constructeur: 'poclain',
customValues: {
"Type d'actionneur": 'Hydraulique',
"Temps d'ouverture (s)": 4,
},
},
{
name: 'Coffret pesage camion',
reference: 'ARM-BP-01',
typeCode: 'control-panel',
requirementLabel: 'Coffret de pesage',
modelCode: 'control-panel-m340',
constructeur: 'buhler',
customValues: {
'Automate principal': 'Schneider Modicon M340',
'Année de mise à jour': 2023,
"Indice de protection": 'IP55',
},
},
],
sparePieces: [
{
name: 'Capteur pesage 5T',
reference: 'SP-LC-5T-01',
typeCode: 'load-cell',
modelCode: 'load-cell-5t',
requirementLabel: 'Capteurs de pesage',
constructeur: 'ifm',
customValues: {
'Capacité (kg)': 5000,
'Type de connexion': 'Câble 6 fils',
},
},
{
name: 'Capteur pesage secours',
reference: 'SP-LC-5T-02',
typeCode: 'load-cell',
modelCode: 'load-cell-5t',
requirementLabel: 'Capteurs de pesage',
constructeur: 'ifm',
customValues: {
'Capacité (kg)': 5000,
'Type de connexion': 'Câble 6 fils',
},
},
{
name: 'Fusibles 40A coffret',
reference: 'SP-FS-40A-01',
typeCode: 'fuse-cartridge',
modelCode: 'fuse-gg-40a',
requirementLabel: 'Fusibles de protection',
customValues: {
'Calibre (A)': 40,
Type: 'gG',
},
},
{
name: 'Joint trappe benne',
reference: 'SP-JNT-BP',
typeCode: 'flat-gasket',
modelCode: 'gasket-ht-200',
requirementLabel: 'Joint trappe',
customValues: {
Matière: 'NBR',
'Épaisseur (mm)': 5,
},
},
],
},
{
code: 'telehandler-mlt841',
typeMachineCode: 'telehandler',
name: 'Manitou MLT 841 Logistique',
reference: 'MLT-841-01',
prix: '87500',
constructeurKey: 'manitou',
customFieldValues: {
'Usage principal': 'Chargement camions',
'Lieu de stationnement': 'Hangar nord',
"Année d'achat": 2021,
},
components: [
{
name: 'Flèche télescopique 8 m',
reference: 'MLT-BOOM-01',
typeCode: 'telehandler-boom',
requirementLabel: 'Flèche télescopique',
modelCode: 'tele-boom-8m',
constructeur: 'manitou',
customValues: {
'Hauteur max (m)': 8,
'Sections télescopiques': 4,
'Type de guidage': 'Galets',
},
},
{
name: 'Groupe hydraulique 140 l/min',
reference: 'MLT-HYDRO-01',
typeCode: 'hydraulic-power-pack',
requirementLabel: 'Groupe hydraulique',
modelCode: 'hydraulic-pack-tele',
constructeur: 'poclain',
customValues: {
'Débit nominal (l/min)': 140,
'Pression max (bar)': 280,
'Type de pompe': 'Piston axial',
},
},
{
name: 'Groupe moteur 110 kW',
reference: 'MLT-MOTEUR-01',
typeCode: 'motor-drive',
requirementLabel: 'Groupe moteur',
modelCode: 'motor-drive-110',
constructeur: 'sew',
customValues: {
'Puissance nominale (kW)': 110,
'Classe énergétique': 'IE3',
"Indice de protection": 'IP55',
},
},
{
name: 'Cabine premium climatisée',
reference: 'MLT-CAB-01',
typeCode: 'telehandler-cab-module',
requirementLabel: 'Cabine opérateur',
modelCode: 'tele-cab-premium',
constructeur: 'manitou',
customValues: {
'Type de cabine': 'Premium climatisée',
Climatisation: true,
'Nombre de caméras': 2,
},
},
{
name: 'Support attache rapide',
reference: 'MLT-ATTACHE-01',
typeCode: 'telehandler-attachment-carrier',
requirementLabel: 'Support doutils',
modelCode: 'tele-carrier-quick',
constructeur: 'manitou',
customValues: {
"Type d'attache": 'Attache Manitou',
'Capacité nominale (t)': 4.1,
},
},
],
sparePieces: [
{
name: 'Flexible hydraulique 2 tresses',
reference: 'SP-HOSE-01',
typeCode: 'hydraulic-hose',
modelCode: 'hydraulic-hose-2w',
requirementLabel: 'Flexibles hydrauliques',
constructeur: 'poclain',
customValues: {
'Pression max (bar)': 420,
'Type de renfort': '2 tresses acier',
'Longueur (mm)': 1800,
},
},
{
name: 'Fusibles cabine 40A',
reference: 'SP-FS-CAB',
typeCode: 'fuse-cartridge',
modelCode: 'fuse-gg-40a',
requirementLabel: 'Fusibles cabine',
customValues: {
'Calibre (A)': 40,
Type: 'gG',
},
},
{
name: 'Cartouche graisse MLT',
reference: 'SP-GRAISSE-MLT',
typeCode: 'lubrication-cartridge',
modelCode: 'grease-cartridge-400',
requirementLabel: 'Cartouches graissage',
customValues: {
'Volume (cm³)': 400,
'Grade de graisse': 'NLGI 2',
},
},
],
},
];
async function clearDatabaseExceptSitesAndProfiles() {
console.log('🧹 Nettoyage des tables (hors sites et profils)...');
const deleteOrder = [
prisma.customFieldValue.deleteMany(),
prisma.document.deleteMany(),
prisma.piece.deleteMany(),
prisma.composant.deleteMany(),
prisma.machine.deleteMany(),
prisma.typeMachineComponentRequirement.deleteMany(),
prisma.typeMachinePieceRequirement.deleteMany(),
prisma.customField.deleteMany(),
prisma.pieceModel.deleteMany(),
prisma.composantModel.deleteMany(),
prisma.typeMachine.deleteMany(),
prisma.modelType.deleteMany(),
prisma.constructeur.deleteMany(),
];
for (const promise of deleteOrder) {
await promise;
}
console.log('✅ Tables nettoyées.');
}
async function ensureDemoSite() {
const existingSite = await prisma.site.findFirst();
if (existingSite) {
return existingSite;
}
console.log('🏗️ Création du site de démonstration...');
return prisma.site.create({
data: {
name: 'Usine de triage Valgrain',
contactName: 'Lucie Bernard',
contactPhone: '+33 3 80 12 45 78',
contactAddress: 'Zone industrielle des Platanes',
contactPostalCode: '21000',
contactCity: 'Dijon',
},
});
}
async function createConstructeurs() {
console.log('🏭 Création des constructeurs...');
const entries = await Promise.all(
constructeurDefinitions.map((definition) =>
prisma.constructeur
.create({
data: {
name: definition.name,
email: definition.email,
phone: definition.phone,
},
})
.then((constructeur) => [definition.key, constructeur] as const),
),
);
return Object.fromEntries(entries) as Record<string, { id: string }>;
}
function mapCustomFields(fields: { id: string; name: string }[]) {
return fields.reduce<Record<string, string>>((acc, field) => {
acc[field.name] = field.id;
return acc;
}, {});
}
async function createModelTypes() {
console.log('🗂️ Création des catégories de composants et pièces...');
const componentTypeEntries: [
string,
{ id: string; customFields: Record<string, string> },
][] = [];
for (const definition of componentTypeDefinitions) {
const record = await prisma.modelType.create({
data: {
name: definition.name,
code: definition.code,
category: ModelCategory.COMPONENT,
description: definition.description,
customFields: {
create: definition.customFields.map((field) => ({
name: field.name,
type: field.type,
required: field.required ?? false,
defaultValue: field.defaultValue,
options: field.options ?? [],
})),
},
},
include: { customFields: true },
});
componentTypeEntries.push([
definition.code,
{ id: record.id, customFields: mapCustomFields(record.customFields) },
]);
}
const pieceTypeEntries: [
string,
{ id: string; customFields: Record<string, string> },
][] = [];
for (const definition of pieceTypeDefinitions) {
const record = await prisma.modelType.create({
data: {
name: definition.name,
code: definition.code,
category: ModelCategory.PIECE,
description: definition.description,
customFields: {
create: definition.customFields.map((field) => ({
name: field.name,
type: field.type,
required: field.required ?? false,
defaultValue: field.defaultValue,
options: field.options ?? [],
})),
},
},
include: { customFields: true },
});
pieceTypeEntries.push([
definition.code,
{ id: record.id, customFields: mapCustomFields(record.customFields) },
]);
}
return {
componentTypes: Object.fromEntries(componentTypeEntries) as Record<
string,
{ id: string; customFields: Record<string, string> }
>,
pieceTypes: Object.fromEntries(pieceTypeEntries) as Record<
string,
{ id: string; customFields: Record<string, string> }
>,
};
}
async function createPieceModels(
pieceTypes: Record<string, { id: string }>,
) {
console.log('🧩 Création des modèles de pièces...');
const entries = await Promise.all(
pieceModelDefinitions.map(async (definition) => {
const type = pieceTypes[definition.typeCode];
if (!type) {
throw new Error(`Type de pièce introuvable: ${definition.typeCode}`);
}
const record = await prisma.pieceModel.create({
data: {
name: definition.name,
description: definition.description,
typePiece: { connect: { id: type.id } },
structure: definition.structure,
},
});
return [definition.code, record] as const;
}),
);
return Object.fromEntries(entries) as Record<string, { id: string }>;
}
function buildComponentModelStructure(
structure: ComponentModelStructureDraft | Prisma.InputJsonValue | undefined,
componentTypes: Record<string, { id: string }>,
pieceTypes: Record<string, { id: string }>,
): Prisma.InputJsonValue | undefined {
if (!structure) {
return undefined;
}
if (typeof structure !== 'object' || structure === null) {
return structure as Prisma.InputJsonValue;
}
const candidate = structure as Record<string, unknown>;
const asCleanString = (value: unknown): string | undefined => {
if (value === undefined || value === null) {
return undefined;
}
const text = String(value).trim().replace(/\s+/g, ' ');
return text ? text : undefined;
};
if (
Array.isArray((candidate as any).pieces) ||
Array.isArray((candidate as any).customFields) ||
Array.isArray((candidate as any).subcomponents) ||
Array.isArray((candidate as any).subComponents)
) {
return normalizeComponentModelStructure(candidate) as Prisma.InputJsonValue;
}
const customFieldEntries = new Map<string, unknown>();
const presetCustomFields = Array.isArray((candidate as any).customFields)
? ((candidate as any).customFields as Array<Record<string, unknown>>)
: [];
for (const entry of presetCustomFields) {
const key = String(entry?.key ?? entry?.name ?? '').trim();
if (!key) {
continue;
}
if (!customFieldEntries.has(key)) {
customFieldEntries.set(key, entry?.value ?? null);
}
}
const recommended = (candidate as any).recommendedCustomFields as
| Record<string, unknown>
| undefined;
if (recommended) {
for (const [key, value] of Object.entries(recommended)) {
const trimmedKey = String(key).trim();
if (!trimmedKey) {
continue;
}
if (!customFieldEntries.has(trimmedKey)) {
customFieldEntries.set(trimmedKey, value ?? null);
}
}
}
const pieces: ComponentModelStructure['pieces'] = [];
const subcomponents: ComponentModelStructure['subcomponents'] = [];
const pieceTemplates = Array.isArray((candidate as any).pieceTemplates)
? ((candidate as any).pieceTemplates as Array<Record<string, unknown>>)
: [];
for (const template of pieceTemplates) {
const typeCode = String(template?.typeCode ?? '').trim();
if (!typeCode) {
continue;
}
const normalizedRole = asCleanString(
template?.usage ?? template?.role ?? template?.notes ?? null,
);
if (pieceTypes[typeCode]) {
pieces.push(
normalizedRole
? { familyCode: typeCode, role: normalizedRole }
: { familyCode: typeCode },
);
continue;
}
if (componentTypes[typeCode]) {
subcomponents.push(
normalizedRole
? { familyCode: typeCode, alias: normalizedRole }
: { familyCode: typeCode },
);
continue;
}
pieces.push(
normalizedRole
? { familyCode: typeCode, role: normalizedRole }
: { familyCode: typeCode },
);
}
const subComponentTemplates = Array.isArray((candidate as any).subComponentTemplates)
? ((candidate as any).subComponentTemplates as Array<Record<string, unknown>>)
: [];
for (const template of subComponentTemplates) {
const typeCode = String(template?.typeCode ?? '').trim();
const normalizedAlias = asCleanString(template?.alias ?? template?.notes ?? null);
const suggestedModels = Array.isArray(template?.suggestedModelCodes)
? (template?.suggestedModelCodes as string[])
: [];
if (suggestedModels.length > 0) {
suggestedModels.forEach((modelCode, index) => {
const hint =
normalizedAlias && suggestedModels.length > 1
? `${normalizedAlias} #${index + 1}`
: normalizedAlias;
const fallbackFamily = typeCode || String(modelCode ?? '').trim() || 'UNKNOWN';
subcomponents.push(
hint
? { familyCode: fallbackFamily, alias: hint }
: { familyCode: fallbackFamily },
);
});
continue;
}
if (typeCode) {
subcomponents.push(
normalizedAlias
? { familyCode: typeCode, alias: normalizedAlias }
: { familyCode: typeCode },
);
continue;
}
}
const canonical: ComponentModelStructure = {
pieces,
subcomponents,
customFields: Array.from(customFieldEntries.entries()).map(([key, value]) => ({
key,
value: value ?? null,
})),
};
return normalizeComponentModelStructure(canonical) as Prisma.InputJsonValue;
}
async function createComponentModels(
componentTypes: Record<string, { id: string }>,
pieceTypes: Record<string, { id: string }>,
) {
console.log('🛠️ Création des modèles de composants...');
const entries = await Promise.all(
componentModelDefinitions.map(async (definition) => {
const type = componentTypes[definition.typeCode];
if (!type) {
throw new Error(`Type de composant introuvable: ${definition.typeCode}`);
}
const record = await prisma.composantModel.create({
data: {
name: definition.name,
description: definition.description,
typeComposant: { connect: { id: type.id } },
structure: buildComponentModelStructure(
definition.structure,
componentTypes,
pieceTypes,
),
},
});
return [definition.code, record] as const;
}),
);
return Object.fromEntries(entries) as Record<string, { id: string }>;
}
async function createTypeMachines(
componentTypes: Record<string, { id: string }>,
pieceTypes: Record<string, { id: string }>,
) {
console.log('🧬 Création des squelettes de machines...');
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,
})),
},
machinePieces: {
recommendedStock: [],
},
customFields: {
create: definition.customFields.map((field) => ({
name: field.name,
type: field.type,
required: field.required ?? false,
defaultValue: field.defaultValue,
options: field.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 },
},
})),
},
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 [definition.code, record] as const;
}),
);
return Object.fromEntries(entries) as Record<string, TypeMachineRecord>;
}
function buildCustomFieldValues(
fieldMap: Record<string, string>,
values?: Record<string, string | number | boolean | Date>,
) {
if (!values) {
return undefined;
}
return {
create: Object.entries(values).map(([name, value]) => {
const fieldId = fieldMap[name];
if (!fieldId) {
throw new Error(`Champ personnalisé inconnu: ${name}`);
}
return {
value: value instanceof Date ? value.toISOString() : String(value),
customField: {
connect: { id: fieldId },
},
};
}),
};
}
async function createComponentHierarchy(
machineId: string,
component: ComponentInstance,
context: {
componentTypes: Record<string, { id: string; customFields: Record<string, string> }>;
componentModels: Record<string, { id: string }>;
pieceTypes: Record<string, { id: string; customFields: Record<string, string> }>;
pieceModels: Record<string, { id: string }>;
constructeurs: Record<string, { id: string }>;
requirementMap: Map<string, string>;
},
parentId?: string,
) {
const requirementId = component.requirementLabel
? context.requirementMap.get(component.requirementLabel)
: undefined;
const record = await prisma.composant.create({
data: {
name: component.name,
reference: component.reference,
prix: component.prix ? new Prisma.Decimal(component.prix) : undefined,
machine: { connect: { id: machineId } },
parentComposant: parentId ? { connect: { id: parentId } } : undefined,
typeComposant: { connect: { id: context.componentTypes[component.typeCode].id } },
composantModel: {
connect: { id: context.componentModels[component.modelCode].id },
},
constructeur: component.constructeur
? { connect: { id: context.constructeurs[component.constructeur].id } }
: undefined,
typeMachineComponentRequirement: requirementId
? { connect: { id: requirementId } }
: undefined,
customFieldValues: buildCustomFieldValues(
context.componentTypes[component.typeCode].customFields,
component.customValues,
),
pieces: component.pieces
? {
create: component.pieces.map((piece) => {
const type = context.pieceTypes[piece.typeCode];
if (!type) {
throw new Error(`Type de pièce introuvable: ${piece.typeCode}`);
}
return {
name: piece.name,
reference: piece.reference,
prix: piece.prix ? new Prisma.Decimal(piece.prix) : undefined,
typePiece: { connect: { id: type.id } },
pieceModel: {
connect: { id: context.pieceModels[piece.modelCode].id },
},
constructeur: piece.constructeur
? { connect: { id: context.constructeurs[piece.constructeur].id } }
: undefined,
customFieldValues: buildCustomFieldValues(
type.customFields,
piece.customValues,
),
};
}),
}
: undefined,
},
});
if (component.children && component.children.length > 0) {
for (const child of component.children) {
await createComponentHierarchy(machineId, child, context, record.id);
}
}
return record;
}
async function createMachines(
siteId: string,
typeMachines: Record<string, TypeMachineRecord>,
context: {
componentTypes: Record<string, { id: string; customFields: Record<string, string> }>;
componentModels: Record<string, { id: string }>;
pieceTypes: Record<string, { id: string; customFields: Record<string, string> }>;
pieceModels: Record<string, { id: string }>;
constructeurs: Record<string, { id: string }>;
},
) {
console.log('🏗️ Création des machines de démonstration...');
for (const build of machineBuilds) {
const typeMachine = typeMachines[build.typeMachineCode];
if (!typeMachine) {
throw new Error(`Type de machine introuvable pour ${build.typeMachineCode}`);
}
const requirementMap = new Map<string, string>();
typeMachine.componentRequirements.forEach((requirement) => {
if (requirement.label) {
requirementMap.set(requirement.label, requirement.id);
}
});
const pieceRequirementMap = new Map<string, string>();
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);
}
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];
if (!pieceType) {
throw new Error(`Type de pièce inconnu pour pièce de secours: ${spare.typeCode}`);
}
const requirementId = spare.requirementLabel
? pieceRequirementMap.get(spare.requirementLabel)
: undefined;
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,
),
},
});
}
}
}
}
async function main() {
try {
await clearDatabaseExceptSitesAndProfiles();
const [site, constructeurs] = await Promise.all([
ensureDemoSite(),
createConstructeurs(),
]);
const { componentTypes, pieceTypes } = await createModelTypes();
const [pieceModels, componentModels, typeMachines] = await Promise.all([
createPieceModels(pieceTypes),
createComponentModels(componentTypes, pieceTypes),
createTypeMachines(componentTypes, pieceTypes),
]);
await createMachines(site.id, typeMachines, {
componentTypes,
componentModels,
pieceTypes,
pieceModels,
constructeurs,
});
console.log('🎉 Données de démonstration générées avec succès.');
} catch (error) {
console.error('❌ Erreur pendant la génération des données :', error);
process.exitCode = 1;
} finally {
await prisma.$disconnect();
}
}
main();