4727 lines
129 KiB
TypeScript
4727 lines
129 KiB
TypeScript
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 d’outils',
|
||
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 d’actionnement': '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 d’actionnement': '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 d’outils 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 d’alimentation',
|
||
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 d’outils',
|
||
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 d’alimentation': 'É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 d’outils',
|
||
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();
|