feat: Add feature in component and piece for support group
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@ node_modules
|
||||
.env
|
||||
|
||||
/generated/prisma
|
||||
dist
|
||||
@@ -20,7 +20,8 @@ REQUEST_SIZE_LIMIT=10mb
|
||||
SESSION_COOKIE_SECURE=true
|
||||
|
||||
# Configuration de l'API
|
||||
API_PREFIX=api
|
||||
# API_PREFIX est désormais vide car les routes sont exposées à la racine
|
||||
API_PREFIX=
|
||||
API_VERSION=v1
|
||||
|
||||
# Configuration des logs
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- A unique constraint covering the columns `[name]` on the table `constructeurs` will be added. If there are existing duplicate values, this will fail.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "composants" ADD COLUMN "composantModelId" TEXT,
|
||||
ADD COLUMN "typeMachineComponentRequirementId" TEXT;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "constructeurs" ALTER COLUMN "createdAt" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "updatedAt" DROP DEFAULT,
|
||||
ALTER COLUMN "updatedAt" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "pieces" ADD COLUMN "pieceModelId" TEXT,
|
||||
ADD COLUMN "typeMachinePieceRequirementId" TEXT;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "profiles" ALTER COLUMN "updatedAt" DROP DEFAULT;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "composant_models" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"structure" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"typeComposantId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "composant_models_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "piece_models" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"structure" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"typePieceId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "piece_models_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "type_machine_component_requirements" (
|
||||
"id" TEXT NOT NULL,
|
||||
"label" TEXT,
|
||||
"minCount" INTEGER NOT NULL DEFAULT 1,
|
||||
"maxCount" INTEGER,
|
||||
"required" BOOLEAN NOT NULL DEFAULT true,
|
||||
"allowNewModels" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"typeMachineId" TEXT NOT NULL,
|
||||
"typeComposantId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "type_machine_component_requirements_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "type_machine_piece_requirements" (
|
||||
"id" TEXT NOT NULL,
|
||||
"label" TEXT,
|
||||
"minCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"maxCount" INTEGER,
|
||||
"required" BOOLEAN NOT NULL DEFAULT false,
|
||||
"allowNewModels" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"typeMachineId" TEXT NOT NULL,
|
||||
"typePieceId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "type_machine_piece_requirements_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "constructeurs_name_key" ON "constructeurs"("name");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "composants" ADD CONSTRAINT "composants_composantModelId_fkey" FOREIGN KEY ("composantModelId") REFERENCES "composant_models"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "composants" ADD CONSTRAINT "composants_typeMachineComponentRequirementId_fkey" FOREIGN KEY ("typeMachineComponentRequirementId") REFERENCES "type_machine_component_requirements"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "pieces" ADD CONSTRAINT "pieces_pieceModelId_fkey" FOREIGN KEY ("pieceModelId") REFERENCES "piece_models"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "pieces" ADD CONSTRAINT "pieces_typeMachinePieceRequirementId_fkey" FOREIGN KEY ("typeMachinePieceRequirementId") REFERENCES "type_machine_piece_requirements"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "composant_models" ADD CONSTRAINT "composant_models_typeComposantId_fkey" FOREIGN KEY ("typeComposantId") REFERENCES "type_composants"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "piece_models" ADD CONSTRAINT "piece_models_typePieceId_fkey" FOREIGN KEY ("typePieceId") REFERENCES "type_pieces"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "type_machine_component_requirements" ADD CONSTRAINT "type_machine_component_requirements_typeMachineId_fkey" FOREIGN KEY ("typeMachineId") REFERENCES "type_machines"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "type_machine_component_requirements" ADD CONSTRAINT "type_machine_component_requirements_typeComposantId_fkey" FOREIGN KEY ("typeComposantId") REFERENCES "type_composants"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "type_machine_piece_requirements" ADD CONSTRAINT "type_machine_piece_requirements_typeMachineId_fkey" FOREIGN KEY ("typeMachineId") REFERENCES "type_machines"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "type_machine_piece_requirements" ADD CONSTRAINT "type_machine_piece_requirements_typePieceId_fkey" FOREIGN KEY ("typePieceId") REFERENCES "type_pieces"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -12,39 +12,41 @@ datasource db {
|
||||
|
||||
// Entités principales
|
||||
model Site {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
contactName String @default("")
|
||||
contactPhone String @default("")
|
||||
contactAddress String @default("")
|
||||
contactPostalCode String @default("")
|
||||
contactCity String @default("")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations
|
||||
machines Machine[]
|
||||
machines Machine[]
|
||||
documents Document[] @relation("SiteDocuments")
|
||||
|
||||
@@map("sites")
|
||||
}
|
||||
|
||||
model TypeMachine {
|
||||
id String @id @default(cuid())
|
||||
name String @unique
|
||||
description String?
|
||||
category String?
|
||||
id String @id @default(cuid())
|
||||
name String @unique
|
||||
description String?
|
||||
category String?
|
||||
maintenanceFrequency String?
|
||||
components Json? // Stockage de la structure hiérarchique des composants
|
||||
criticalParts Json? // Stockage des pièces critiques
|
||||
machinePieces Json? // Stockage des pièces de machine
|
||||
specifications Json? // Stockage des spécifications techniques
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
components Json? // Stockage de la structure hiérarchique des composants
|
||||
criticalParts Json? // Stockage des pièces critiques
|
||||
machinePieces Json? // Stockage des pièces de machine
|
||||
specifications Json? // Stockage des spécifications techniques
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations
|
||||
machines Machine[]
|
||||
customFields CustomField[] @relation("TypeMachineCustomFields")
|
||||
machines Machine[]
|
||||
customFields CustomField[] @relation("TypeMachineCustomFields")
|
||||
componentRequirements TypeMachineComponentRequirement[]
|
||||
pieceRequirements TypeMachinePieceRequirement[]
|
||||
|
||||
@@map("type_machines")
|
||||
}
|
||||
@@ -57,8 +59,10 @@ model TypeComposant {
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations
|
||||
composants Composant[]
|
||||
customFields CustomField[] @relation("TypeComposantCustomFields")
|
||||
composants Composant[]
|
||||
customFields CustomField[] @relation("TypeComposantCustomFields")
|
||||
models ComposantModel[]
|
||||
componentRequirements TypeMachineComponentRequirement[]
|
||||
|
||||
@@map("type_composants")
|
||||
}
|
||||
@@ -71,8 +75,10 @@ model TypePiece {
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations
|
||||
pieces Piece[]
|
||||
customFields CustomField[] @relation("TypePieceCustomFields")
|
||||
pieces Piece[]
|
||||
customFields CustomField[] @relation("TypePieceCustomFields")
|
||||
models PieceModel[]
|
||||
pieceRequirements TypeMachinePieceRequirement[]
|
||||
|
||||
@@map("type_pieces")
|
||||
}
|
||||
@@ -87,18 +93,18 @@ model Machine {
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations
|
||||
siteId String
|
||||
site Site @relation(fields: [siteId], references: [id], onDelete: Cascade)
|
||||
|
||||
siteId String
|
||||
site Site @relation(fields: [siteId], references: [id], onDelete: Cascade)
|
||||
|
||||
typeMachineId String?
|
||||
typeMachine TypeMachine? @relation(fields: [typeMachineId], references: [id])
|
||||
|
||||
|
||||
constructeurId String?
|
||||
constructeur Constructeur? @relation(fields: [constructeurId], references: [id], onDelete: SetNull)
|
||||
|
||||
composants Composant[]
|
||||
pieces Piece[]
|
||||
documents Document[] @relation("MachineDocuments")
|
||||
|
||||
composants Composant[]
|
||||
pieces Piece[]
|
||||
documents Document[] @relation("MachineDocuments")
|
||||
customFieldValues CustomFieldValue[] @relation("MachineCustomFieldValues")
|
||||
|
||||
@@map("machines")
|
||||
@@ -114,21 +120,27 @@ model Composant {
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations hiérarchiques
|
||||
machineId String?
|
||||
machine Machine? @relation(fields: [machineId], references: [id], onDelete: Cascade)
|
||||
|
||||
machineId String?
|
||||
machine Machine? @relation(fields: [machineId], references: [id], onDelete: Cascade)
|
||||
|
||||
parentComposantId String?
|
||||
parentComposant Composant? @relation("ComposantHierarchy", fields: [parentComposantId], references: [id], onDelete: Cascade)
|
||||
parentComposant Composant? @relation("ComposantHierarchy", fields: [parentComposantId], references: [id], onDelete: Cascade)
|
||||
sousComposants Composant[] @relation("ComposantHierarchy")
|
||||
|
||||
|
||||
typeComposantId String?
|
||||
typeComposant TypeComposant? @relation(fields: [typeComposantId], references: [id])
|
||||
|
||||
|
||||
composantModelId String?
|
||||
composantModel ComposantModel? @relation(fields: [composantModelId], references: [id], onDelete: SetNull)
|
||||
|
||||
typeMachineComponentRequirementId String?
|
||||
typeMachineComponentRequirement TypeMachineComponentRequirement? @relation(fields: [typeMachineComponentRequirementId], references: [id], onDelete: SetNull)
|
||||
|
||||
constructeurId String?
|
||||
constructeur Constructeur? @relation(fields: [constructeurId], references: [id], onDelete: SetNull)
|
||||
|
||||
pieces Piece[]
|
||||
documents Document[] @relation("ComposantDocuments")
|
||||
|
||||
pieces Piece[]
|
||||
documents Document[] @relation("ComposantDocuments")
|
||||
customFieldValues CustomFieldValue[] @relation("ComposantCustomFieldValues")
|
||||
|
||||
@@map("composants")
|
||||
@@ -144,19 +156,25 @@ model Piece {
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations
|
||||
machineId String?
|
||||
machine Machine? @relation(fields: [machineId], references: [id], onDelete: Cascade)
|
||||
|
||||
machineId String?
|
||||
machine Machine? @relation(fields: [machineId], references: [id], onDelete: Cascade)
|
||||
|
||||
composantId String?
|
||||
composant Composant? @relation(fields: [composantId], references: [id], onDelete: Cascade)
|
||||
|
||||
composant Composant? @relation(fields: [composantId], references: [id], onDelete: Cascade)
|
||||
|
||||
typePieceId String?
|
||||
typePiece TypePiece? @relation(fields: [typePieceId], references: [id])
|
||||
|
||||
typePiece TypePiece? @relation(fields: [typePieceId], references: [id])
|
||||
|
||||
pieceModelId String?
|
||||
pieceModel PieceModel? @relation(fields: [pieceModelId], references: [id], onDelete: SetNull)
|
||||
|
||||
typeMachinePieceRequirementId String?
|
||||
typeMachinePieceRequirement TypeMachinePieceRequirement? @relation(fields: [typeMachinePieceRequirementId], references: [id], onDelete: SetNull)
|
||||
|
||||
constructeurId String?
|
||||
constructeur Constructeur? @relation(fields: [constructeurId], references: [id], onDelete: SetNull)
|
||||
|
||||
documents Document[] @relation("PieceDocuments")
|
||||
|
||||
documents Document[] @relation("PieceDocuments")
|
||||
customFieldValues CustomFieldValue[] @relation("PieceCustomFieldValues")
|
||||
|
||||
@@map("pieces")
|
||||
@@ -189,50 +207,50 @@ model Profile {
|
||||
}
|
||||
|
||||
model Document {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
filename String
|
||||
path String
|
||||
mimeType String
|
||||
size Int
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
filename String
|
||||
path String
|
||||
mimeType String
|
||||
size Int
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations polymorphiques
|
||||
machineId String?
|
||||
machine Machine? @relation("MachineDocuments", fields: [machineId], references: [id], onDelete: Cascade)
|
||||
|
||||
composantId String?
|
||||
composant Composant? @relation("ComposantDocuments", fields: [composantId], references: [id], onDelete: Cascade)
|
||||
|
||||
pieceId String?
|
||||
piece Piece? @relation("PieceDocuments", fields: [pieceId], references: [id], onDelete: Cascade)
|
||||
machineId String?
|
||||
machine Machine? @relation("MachineDocuments", fields: [machineId], references: [id], onDelete: Cascade)
|
||||
|
||||
siteId String?
|
||||
site Site? @relation("SiteDocuments", fields: [siteId], references: [id], onDelete: Cascade)
|
||||
composantId String?
|
||||
composant Composant? @relation("ComposantDocuments", fields: [composantId], references: [id], onDelete: Cascade)
|
||||
|
||||
pieceId String?
|
||||
piece Piece? @relation("PieceDocuments", fields: [pieceId], references: [id], onDelete: Cascade)
|
||||
|
||||
siteId String?
|
||||
site Site? @relation("SiteDocuments", fields: [siteId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@map("documents")
|
||||
}
|
||||
|
||||
model CustomField {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
type String // 'string', 'number', 'boolean', 'date'
|
||||
required Boolean @default(false)
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
type String // 'string', 'number', 'boolean', 'date'
|
||||
required Boolean @default(false)
|
||||
defaultValue String?
|
||||
options String[] // Pour les champs de type SELECT
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
options String[] // Pour les champs de type SELECT
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations polymorphiques pour les types
|
||||
typeMachineId String?
|
||||
typeMachine TypeMachine? @relation("TypeMachineCustomFields", fields: [typeMachineId], references: [id], onDelete: Cascade)
|
||||
|
||||
typeMachineId String?
|
||||
typeMachine TypeMachine? @relation("TypeMachineCustomFields", fields: [typeMachineId], references: [id], onDelete: Cascade)
|
||||
|
||||
typeComposantId String?
|
||||
typeComposant TypeComposant? @relation("TypeComposantCustomFields", fields: [typeComposantId], references: [id], onDelete: Cascade)
|
||||
|
||||
typePieceId String?
|
||||
typePiece TypePiece? @relation("TypePieceCustomFields", fields: [typePieceId], references: [id], onDelete: Cascade)
|
||||
|
||||
typePieceId String?
|
||||
typePiece TypePiece? @relation("TypePieceCustomFields", fields: [typePieceId], references: [id], onDelete: Cascade)
|
||||
|
||||
// Relations avec les valeurs
|
||||
customFieldValues CustomFieldValue[]
|
||||
@@ -241,23 +259,97 @@ model CustomField {
|
||||
}
|
||||
|
||||
model CustomFieldValue {
|
||||
id String @id @default(cuid())
|
||||
value String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
id String @id @default(cuid())
|
||||
value String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Relations
|
||||
customFieldId String
|
||||
customField CustomField @relation(fields: [customFieldId], references: [id], onDelete: Cascade)
|
||||
|
||||
machineId String?
|
||||
machine Machine? @relation("MachineCustomFieldValues", fields: [machineId], references: [id], onDelete: Cascade)
|
||||
|
||||
|
||||
machineId String?
|
||||
machine Machine? @relation("MachineCustomFieldValues", fields: [machineId], references: [id], onDelete: Cascade)
|
||||
|
||||
composantId String?
|
||||
composant Composant? @relation("ComposantCustomFieldValues", fields: [composantId], references: [id], onDelete: Cascade)
|
||||
|
||||
pieceId String?
|
||||
piece Piece? @relation("PieceCustomFieldValues", fields: [pieceId], references: [id], onDelete: Cascade)
|
||||
composant Composant? @relation("ComposantCustomFieldValues", fields: [composantId], references: [id], onDelete: Cascade)
|
||||
|
||||
pieceId String?
|
||||
piece Piece? @relation("PieceCustomFieldValues", fields: [pieceId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@map("custom_field_values")
|
||||
}
|
||||
|
||||
model ComposantModel {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
description String?
|
||||
structure Json? // Définition du composant (sous-composants, pièces, champs personnalisés)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
typeComposantId String
|
||||
typeComposant TypeComposant @relation(fields: [typeComposantId], references: [id], onDelete: Cascade)
|
||||
|
||||
composants Composant[]
|
||||
|
||||
@@map("composant_models")
|
||||
}
|
||||
|
||||
model PieceModel {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
description String?
|
||||
structure Json? // Définition de la pièce (champs personnalisés par défaut, etc.)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
typePieceId String
|
||||
typePiece TypePiece @relation(fields: [typePieceId], references: [id], onDelete: Cascade)
|
||||
|
||||
pieces Piece[]
|
||||
|
||||
@@map("piece_models")
|
||||
}
|
||||
|
||||
model TypeMachineComponentRequirement {
|
||||
id String @id @default(cuid())
|
||||
label String?
|
||||
minCount Int @default(1)
|
||||
maxCount Int?
|
||||
required Boolean @default(true)
|
||||
allowNewModels Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
typeMachineId String
|
||||
typeMachine TypeMachine @relation(fields: [typeMachineId], references: [id], onDelete: Cascade)
|
||||
|
||||
typeComposantId String
|
||||
typeComposant TypeComposant @relation(fields: [typeComposantId], references: [id])
|
||||
|
||||
composants Composant[]
|
||||
|
||||
@@map("type_machine_component_requirements")
|
||||
}
|
||||
|
||||
model TypeMachinePieceRequirement {
|
||||
id String @id @default(cuid())
|
||||
label String?
|
||||
minCount Int @default(0)
|
||||
maxCount Int?
|
||||
required Boolean @default(false)
|
||||
allowNewModels Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
typeMachineId String
|
||||
typeMachine TypeMachine @relation(fields: [typeMachineId], references: [id], onDelete: Cascade)
|
||||
|
||||
typePieceId String
|
||||
typePiece TypePiece @relation(fields: [typePieceId], references: [id])
|
||||
|
||||
pieces Piece[]
|
||||
|
||||
@@map("type_machine_piece_requirements")
|
||||
}
|
||||
|
||||
@@ -13,14 +13,44 @@ export class ComposantsService {
|
||||
machine: true,
|
||||
parentComposant: true,
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
sousComposants: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
pieces: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
pieces: {
|
||||
include: {
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
pieces: {
|
||||
include: {
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
pieces: true,
|
||||
documents: true,
|
||||
},
|
||||
});
|
||||
@@ -32,6 +62,12 @@ export class ComposantsService {
|
||||
machine: true,
|
||||
parentComposant: true,
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
customFieldValues: {
|
||||
include: {
|
||||
@@ -41,6 +77,12 @@ export class ComposantsService {
|
||||
sousComposants: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
customFieldValues: {
|
||||
include: {
|
||||
customField: true,
|
||||
@@ -54,6 +96,12 @@ export class ComposantsService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
@@ -67,6 +115,12 @@ export class ComposantsService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
documents: true,
|
||||
@@ -81,6 +135,12 @@ export class ComposantsService {
|
||||
machine: true,
|
||||
parentComposant: true,
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
customFieldValues: {
|
||||
include: {
|
||||
@@ -90,6 +150,12 @@ export class ComposantsService {
|
||||
sousComposants: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
customFieldValues: {
|
||||
include: {
|
||||
customField: true,
|
||||
@@ -103,6 +169,12 @@ export class ComposantsService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
@@ -116,6 +188,12 @@ export class ComposantsService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
documents: true,
|
||||
@@ -130,10 +208,22 @@ export class ComposantsService {
|
||||
machine: true,
|
||||
parentComposant: true,
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
sousComposants: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
pieces: true,
|
||||
constructeur: true,
|
||||
},
|
||||
@@ -146,6 +236,12 @@ export class ComposantsService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
customFieldValues: {
|
||||
@@ -167,6 +263,12 @@ export class ComposantsService {
|
||||
},
|
||||
include: {
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
customFieldValues: {
|
||||
include: {
|
||||
@@ -176,6 +278,12 @@ export class ComposantsService {
|
||||
sousComposants: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
customFieldValues: {
|
||||
include: {
|
||||
@@ -190,11 +298,23 @@ export class ComposantsService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sousComposants: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
customFieldValues: {
|
||||
include: {
|
||||
@@ -209,6 +329,12 @@ export class ComposantsService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -223,6 +349,12 @@ export class ComposantsService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -239,6 +371,12 @@ export class ComposantsService {
|
||||
machine: true,
|
||||
parentComposant: true,
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
customFieldValues: {
|
||||
include: {
|
||||
@@ -248,6 +386,12 @@ export class ComposantsService {
|
||||
sousComposants: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
customFieldValues: {
|
||||
include: {
|
||||
@@ -262,6 +406,12 @@ export class ComposantsService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -274,6 +424,12 @@ export class ComposantsService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
documents: true,
|
||||
|
||||
@@ -1,17 +1,41 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { CreateMachineDto, UpdateMachineDto } from '../shared/dto/machine.dto';
|
||||
import {
|
||||
CreateMachineDto,
|
||||
UpdateMachineDto,
|
||||
MachineComponentSelectionDto,
|
||||
MachinePieceSelectionDto
|
||||
} from '../shared/dto/machine.dto';
|
||||
|
||||
@Injectable()
|
||||
export class MachinesService {
|
||||
constructor(private prisma: PrismaService) {}
|
||||
|
||||
async create(createMachineDto: CreateMachineDto) {
|
||||
// Récupérer le type de machine pour hériter de sa structure
|
||||
const {
|
||||
componentSelections = [],
|
||||
pieceSelections = [],
|
||||
...machineData
|
||||
} = createMachineDto;
|
||||
|
||||
if (!machineData.typeMachineId) {
|
||||
throw new Error('typeMachineId est requis pour créer une machine à partir d\'un squelette.');
|
||||
}
|
||||
|
||||
const typeMachine = await this.prisma.typeMachine.findUnique({
|
||||
where: { id: createMachineDto.typeMachineId },
|
||||
where: { id: machineData.typeMachineId },
|
||||
include: {
|
||||
customFields: true,
|
||||
componentRequirements: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
pieceRequirements: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -19,11 +43,152 @@ export class MachinesService {
|
||||
throw new Error('Type de machine non trouvé');
|
||||
}
|
||||
|
||||
// Créer la machine avec la structure héritée du type
|
||||
const componentRequirementMap = new Map(
|
||||
typeMachine.componentRequirements.map((requirement) => [requirement.id, requirement]),
|
||||
);
|
||||
const pieceRequirementMap = new Map(
|
||||
typeMachine.pieceRequirements.map((requirement) => [requirement.id, requirement]),
|
||||
);
|
||||
|
||||
const componentSelectionMap = new Map<string, MachineComponentSelectionDto[]>();
|
||||
for (const selection of componentSelections) {
|
||||
const requirement = componentRequirementMap.get(selection.requirementId);
|
||||
if (!requirement) {
|
||||
throw new Error(`Sélection de composant invalide: requirementId=${selection.requirementId}`);
|
||||
}
|
||||
if (!componentSelectionMap.has(requirement.id)) {
|
||||
componentSelectionMap.set(requirement.id, []);
|
||||
}
|
||||
componentSelectionMap.get(requirement.id)!.push(selection);
|
||||
}
|
||||
|
||||
const pieceSelectionMap = new Map<string, MachinePieceSelectionDto[]>();
|
||||
for (const selection of pieceSelections) {
|
||||
const requirement = pieceRequirementMap.get(selection.requirementId);
|
||||
if (!requirement) {
|
||||
throw new Error(`Sélection de pièce invalide: requirementId=${selection.requirementId}`);
|
||||
}
|
||||
if (!pieceSelectionMap.has(requirement.id)) {
|
||||
pieceSelectionMap.set(requirement.id, []);
|
||||
}
|
||||
pieceSelectionMap.get(requirement.id)!.push(selection);
|
||||
}
|
||||
|
||||
const componentModelIds = Array.from(
|
||||
new Set(componentSelections.map((selection) => selection.componentModelId).filter(Boolean)),
|
||||
) as string[];
|
||||
const componentModels = componentModelIds.length
|
||||
? await this.prisma.composantModel.findMany({
|
||||
where: { id: { in: componentModelIds } },
|
||||
})
|
||||
: [];
|
||||
const componentModelMap = new Map(componentModels.map((model) => [model.id, model]));
|
||||
|
||||
const pieceModelIds = Array.from(
|
||||
new Set(pieceSelections.map((selection) => selection.pieceModelId).filter(Boolean)),
|
||||
) as string[];
|
||||
const pieceModels = pieceModelIds.length
|
||||
? await this.prisma.pieceModel.findMany({
|
||||
where: { id: { in: pieceModelIds } },
|
||||
})
|
||||
: [];
|
||||
const pieceModelMap = new Map(pieceModels.map((model) => [model.id, model]));
|
||||
|
||||
for (const requirement of typeMachine.componentRequirements) {
|
||||
const selections = componentSelectionMap.get(requirement.id) ?? [];
|
||||
const min = requirement.minCount ?? (requirement.required ? 1 : 0);
|
||||
const max = requirement.maxCount ?? undefined;
|
||||
|
||||
if (selections.length < min) {
|
||||
throw new Error(
|
||||
`Le groupe de composants "${requirement.label || requirement.typeComposant?.name || requirement.id}" requiert au moins ${min} sélection(s).`,
|
||||
);
|
||||
}
|
||||
|
||||
if (max !== undefined && selections.length > max) {
|
||||
throw new Error(
|
||||
`Le groupe de composants "${requirement.label || requirement.typeComposant?.name || requirement.id}" ne peut pas dépasser ${max} sélection(s).`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!requirement.allowNewModels) {
|
||||
const missingModel = selections.find((selection) => !selection.componentModelId);
|
||||
if (missingModel) {
|
||||
throw new Error(
|
||||
`Le groupe de composants "${requirement.label || requirement.typeComposant?.name || requirement.id}" n'autorise que la sélection de modèles existants.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const requirement of typeMachine.pieceRequirements) {
|
||||
const selections = pieceSelectionMap.get(requirement.id) ?? [];
|
||||
const min = requirement.minCount ?? (requirement.required ? 1 : 0);
|
||||
const max = requirement.maxCount ?? undefined;
|
||||
|
||||
if (selections.length < min) {
|
||||
throw new Error(
|
||||
`Le groupe de pièces "${requirement.label || requirement.typePiece?.name || requirement.id}" requiert au moins ${min} sélection(s).`,
|
||||
);
|
||||
}
|
||||
|
||||
if (max !== undefined && selections.length > max) {
|
||||
throw new Error(
|
||||
`Le groupe de pièces "${requirement.label || requirement.typePiece?.name || requirement.id}" ne peut pas dépasser ${max} sélection(s).`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!requirement.allowNewModels) {
|
||||
const missingModel = selections.find((selection) => !selection.pieceModelId);
|
||||
if (missingModel) {
|
||||
throw new Error(
|
||||
`Le groupe de pièces "${requirement.label || requirement.typePiece?.name || requirement.id}" n'autorise que la sélection de modèles existants.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const selection of componentSelections) {
|
||||
if (!selection.componentModelId) {
|
||||
continue;
|
||||
}
|
||||
const model = componentModelMap.get(selection.componentModelId);
|
||||
if (!model) {
|
||||
throw new Error(`Modèle de composant introuvable: ${selection.componentModelId}`);
|
||||
}
|
||||
const requirement = componentRequirementMap.get(selection.requirementId);
|
||||
if (!requirement) {
|
||||
throw new Error(`Requirement de composant introuvable: ${selection.requirementId}`);
|
||||
}
|
||||
if (model.typeComposantId !== requirement.typeComposantId) {
|
||||
throw new Error(
|
||||
`Le modèle de composant "${model.name}" n'appartient pas au type de composant attendu pour ce groupe.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (const selection of pieceSelections) {
|
||||
if (!selection.pieceModelId) {
|
||||
continue;
|
||||
}
|
||||
const model = pieceModelMap.get(selection.pieceModelId);
|
||||
if (!model) {
|
||||
throw new Error(`Modèle de pièce introuvable: ${selection.pieceModelId}`);
|
||||
}
|
||||
const requirement = pieceRequirementMap.get(selection.requirementId);
|
||||
if (!requirement) {
|
||||
throw new Error(`Requirement de pièce introuvable: ${selection.requirementId}`);
|
||||
}
|
||||
if (model.typePieceId !== requirement.typePieceId) {
|
||||
throw new Error(
|
||||
`Le modèle de pièce "${model.name}" n'appartient pas au type de pièce attendu pour ce groupe.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return await this.prisma.$transaction(async (prisma) => {
|
||||
// 1. Créer la machine
|
||||
const machine = await prisma.machine.create({
|
||||
data: createMachineDto,
|
||||
data: machineData,
|
||||
include: {
|
||||
site: true,
|
||||
typeMachine: true,
|
||||
@@ -31,37 +196,71 @@ export class MachinesService {
|
||||
},
|
||||
});
|
||||
|
||||
// 2. Créer les composants basés sur la structure du type
|
||||
const components = (typeMachine as any).components;
|
||||
if (components) {
|
||||
await this.createComponentsFromType(prisma, machine.id, components);
|
||||
if (typeMachine.componentRequirements.length > 0) {
|
||||
for (const requirement of typeMachine.componentRequirements) {
|
||||
const selections = componentSelectionMap.get(requirement.id) ?? [];
|
||||
for (const selection of selections) {
|
||||
const model = selection.componentModelId ? componentModelMap.get(selection.componentModelId) : undefined;
|
||||
const definition = this.normalizeComponentSelection(selection, requirement, model);
|
||||
await this.createComponentsFromType(prisma, machine.id, [definition]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const legacyComponents = (typeMachine as any).components;
|
||||
if (legacyComponents) {
|
||||
await this.createComponentsFromType(prisma, machine.id, legacyComponents);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Créer les pièces de machine basées sur le type
|
||||
const machinePieces = (typeMachine as any).machinePieces;
|
||||
if (machinePieces) {
|
||||
await this.createMachinePiecesFromType(prisma, machine.id, machinePieces);
|
||||
if (typeMachine.pieceRequirements.length > 0) {
|
||||
for (const requirement of typeMachine.pieceRequirements) {
|
||||
const selections = pieceSelectionMap.get(requirement.id) ?? [];
|
||||
for (const selection of selections) {
|
||||
const model = selection.pieceModelId ? pieceModelMap.get(selection.pieceModelId) : undefined;
|
||||
const definition = this.normalizePieceSelection(selection, requirement, model);
|
||||
await this.createMachinePiecesFromType(prisma, machine.id, [definition]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const legacyPieces = (typeMachine as any).machinePieces;
|
||||
if (legacyPieces) {
|
||||
await this.createMachinePiecesFromType(prisma, machine.id, legacyPieces);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Créer les champs personnalisés de la machine basés sur le type
|
||||
if (typeMachine.customFields && typeMachine.customFields.length > 0) {
|
||||
await this.createMachineCustomFieldsFromType(prisma, machine.id, typeMachine.customFields);
|
||||
}
|
||||
|
||||
// 5. Retourner la machine avec sa structure complète
|
||||
return await prisma.machine.findUnique({
|
||||
return prisma.machine.findUnique({
|
||||
where: { id: machine.id },
|
||||
include: {
|
||||
site: true,
|
||||
typeMachine: {
|
||||
include: {
|
||||
customFields: true,
|
||||
componentRequirements: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
pieceRequirements: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
composants: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
sousComposants: true,
|
||||
pieces: {
|
||||
include: {
|
||||
@@ -71,6 +270,12 @@ export class MachinesService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
@@ -84,6 +289,12 @@ export class MachinesService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
customFieldValues: {
|
||||
@@ -97,19 +308,97 @@ export class MachinesService {
|
||||
});
|
||||
}
|
||||
|
||||
private cloneStructure(definition: any): any {
|
||||
if (definition === undefined || definition === null) {
|
||||
return {};
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(JSON.stringify(definition));
|
||||
} catch (error) {
|
||||
if (Array.isArray(definition)) {
|
||||
return definition.map((item) => this.cloneStructure(item));
|
||||
}
|
||||
|
||||
if (typeof definition === 'object') {
|
||||
return { ...definition };
|
||||
}
|
||||
|
||||
return definition;
|
||||
}
|
||||
}
|
||||
|
||||
private normalizeComponentSelection(
|
||||
selection: MachineComponentSelectionDto,
|
||||
requirement: any,
|
||||
model?: any,
|
||||
): any {
|
||||
const baseDefinition = selection.definition ?? (model?.structure ?? {});
|
||||
const definition = this.cloneStructure(baseDefinition);
|
||||
const prepared: any = definition && typeof definition === 'object' && !Array.isArray(definition) ? definition : {};
|
||||
|
||||
prepared.name = prepared.name || model?.name || requirement?.typeComposant?.name || 'Composant';
|
||||
prepared.reference = prepared.reference ?? model?.structure?.reference ?? '';
|
||||
prepared.emplacement = prepared.emplacement ?? model?.structure?.emplacement ?? '';
|
||||
prepared.prix = prepared.prix ?? model?.structure?.prix ?? null;
|
||||
|
||||
prepared.customFields = Array.isArray(prepared.customFields) ? prepared.customFields : [];
|
||||
prepared.pieces = Array.isArray(prepared.pieces)
|
||||
? prepared.pieces
|
||||
: prepared.pieces
|
||||
? [prepared.pieces]
|
||||
: [];
|
||||
prepared.subComponents = Array.isArray(prepared.subComponents)
|
||||
? prepared.subComponents
|
||||
: prepared.subComponents
|
||||
? [prepared.subComponents]
|
||||
: [];
|
||||
|
||||
prepared.typeComposantId = prepared.typeComposantId || requirement?.typeComposantId || model?.typeComposantId || null;
|
||||
prepared.__componentModelId = selection.componentModelId ?? null;
|
||||
prepared.__requirementId = requirement?.id ?? null;
|
||||
|
||||
return prepared;
|
||||
}
|
||||
|
||||
private normalizePieceSelection(
|
||||
selection: MachinePieceSelectionDto,
|
||||
requirement: any,
|
||||
model?: any,
|
||||
): any {
|
||||
const baseDefinition = selection.definition ?? (model?.structure ?? {});
|
||||
const definition = this.cloneStructure(baseDefinition);
|
||||
const prepared: any = definition && typeof definition === 'object' && !Array.isArray(definition) ? definition : {};
|
||||
|
||||
prepared.name = prepared.name || model?.name || requirement?.typePiece?.name || 'Pièce';
|
||||
prepared.customFields = Array.isArray(prepared.customFields) ? prepared.customFields : [];
|
||||
prepared.typePieceId = prepared.typePieceId || requirement?.typePieceId || model?.typePieceId || null;
|
||||
prepared.__pieceModelId = selection.pieceModelId ?? null;
|
||||
prepared.__requirementId = requirement?.id ?? null;
|
||||
|
||||
return prepared;
|
||||
}
|
||||
|
||||
private async createComponentsFromType(prisma: any, machineId: string, components: any[], parentComposantId?: string) {
|
||||
for (const component of components) {
|
||||
if (!component.name) continue;
|
||||
if (!component || !component.name) continue;
|
||||
|
||||
// Créer d'abord le type de composant s'il n'existe pas
|
||||
let typeComposant: any = null;
|
||||
if (component.customFields && component.customFields.length > 0) {
|
||||
// Chercher d'abord si le type de composant existe déjà
|
||||
typeComposant = await prisma.typeComposant.findFirst({
|
||||
where: { name: component.name }
|
||||
const customFields = Array.isArray(component.customFields) ? component.customFields : [];
|
||||
const componentPieces = Array.isArray(component.pieces) ? component.pieces : [];
|
||||
const subComponents = Array.isArray(component.subComponents) ? component.subComponents : [];
|
||||
|
||||
const componentModelId = component.__componentModelId ?? null;
|
||||
const requirementId = component.__requirementId ?? null;
|
||||
const providedTypeComposantId = component.typeComposantId
|
||||
?? (component.typeComposant && component.typeComposant.id ? component.typeComposant.id : null);
|
||||
|
||||
let typeComposantId: string | null = providedTypeComposantId ?? null;
|
||||
|
||||
if (!typeComposantId && customFields.length > 0) {
|
||||
let typeComposant = await prisma.typeComposant.findFirst({
|
||||
where: { name: component.name },
|
||||
});
|
||||
|
||||
// Si le type n'existe pas, le créer
|
||||
if (!typeComposant) {
|
||||
typeComposant = await prisma.typeComposant.create({
|
||||
data: {
|
||||
@@ -118,8 +407,7 @@ export class MachinesService {
|
||||
},
|
||||
});
|
||||
|
||||
// Créer les champs personnalisés pour le type de composant
|
||||
for (const customField of component.customFields) {
|
||||
for (const customField of customFields) {
|
||||
await prisma.customField.create({
|
||||
data: {
|
||||
name: customField.name,
|
||||
@@ -132,6 +420,8 @@ export class MachinesService {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
typeComposantId = typeComposant.id;
|
||||
}
|
||||
|
||||
const createdComposant = await prisma.composant.create({
|
||||
@@ -140,21 +430,22 @@ export class MachinesService {
|
||||
reference: component.reference || '',
|
||||
constructeurId: await this.resolveConstructeurId(prisma, component.constructeur),
|
||||
emplacement: component.emplacement || '',
|
||||
prix: component.prix || null,
|
||||
prix: component.prix ?? null,
|
||||
machineId,
|
||||
parentComposantId,
|
||||
typeComposantId: typeComposant?.id || null,
|
||||
typeComposantId,
|
||||
composantModelId: componentModelId,
|
||||
typeMachineComponentRequirementId: requirementId,
|
||||
},
|
||||
});
|
||||
|
||||
// Créer les valeurs des champs personnalisés pour le composant
|
||||
if (typeComposant && typeComposant.id) {
|
||||
const customFields = await prisma.customField.findMany({
|
||||
where: { typeComposantId: typeComposant.id },
|
||||
if (typeComposantId) {
|
||||
const typeCustomFields = await prisma.customField.findMany({
|
||||
where: { typeComposantId },
|
||||
});
|
||||
|
||||
for (const customField of customFields) {
|
||||
const defaultValue = component.customFields?.find(cf => cf.name === customField.name)?.defaultValue || '';
|
||||
for (const customField of typeCustomFields) {
|
||||
const defaultValue = customFields.find((cf) => cf.name === customField.name)?.defaultValue || '';
|
||||
await prisma.customFieldValue.create({
|
||||
data: {
|
||||
value: defaultValue,
|
||||
@@ -165,79 +456,81 @@ export class MachinesService {
|
||||
}
|
||||
}
|
||||
|
||||
// Créer les pièces du composant avec leurs champs personnalisés
|
||||
if (component.pieces) {
|
||||
for (const piece of component.pieces) {
|
||||
if (!piece || !piece.name) continue;
|
||||
|
||||
// Créer d'abord le type de pièce s'il n'existe pas
|
||||
let typePiece: any = null;
|
||||
if (piece.customFields && piece.customFields.length > 0) {
|
||||
// Chercher d'abord si le type de pièce existe déjà
|
||||
typePiece = await prisma.typePiece.findFirst({
|
||||
where: { name: piece.name }
|
||||
});
|
||||
for (const piece of componentPieces) {
|
||||
if (!piece || !piece.name) continue;
|
||||
|
||||
// Si le type n'existe pas, le créer
|
||||
if (!typePiece) {
|
||||
typePiece = await prisma.typePiece.create({
|
||||
data: {
|
||||
name: piece.name,
|
||||
description: piece.description || '',
|
||||
},
|
||||
});
|
||||
const pieceCustomFields = Array.isArray(piece.customFields) ? piece.customFields : [];
|
||||
const pieceModelId = piece.__pieceModelId ?? null;
|
||||
const pieceRequirementId = piece.__requirementId ?? null;
|
||||
const providedTypePieceId = piece.typePieceId
|
||||
?? (piece.typePiece && piece.typePiece.id ? piece.typePiece.id : null);
|
||||
|
||||
// Créer les champs personnalisés pour le type de pièce
|
||||
for (const customField of piece.customFields) {
|
||||
await prisma.customField.create({
|
||||
data: {
|
||||
name: customField.name,
|
||||
type: customField.type,
|
||||
required: customField.required || false,
|
||||
defaultValue: customField.defaultValue,
|
||||
options: customField.options || [],
|
||||
typePieceId: typePiece.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const createdPiece = await prisma.piece.create({
|
||||
data: {
|
||||
name: piece.name,
|
||||
reference: piece.reference || '',
|
||||
constructeurId: await this.resolveConstructeurId(prisma, piece.constructeur),
|
||||
emplacement: piece.emplacement || '',
|
||||
prix: piece.prix || null,
|
||||
composantId: createdComposant.id,
|
||||
typePieceId: typePiece?.id || null,
|
||||
},
|
||||
let typePieceId: string | null = providedTypePieceId ?? null;
|
||||
|
||||
if (!typePieceId && pieceCustomFields.length > 0) {
|
||||
let typePiece = await prisma.typePiece.findFirst({
|
||||
where: { name: piece.name },
|
||||
});
|
||||
|
||||
// Créer les valeurs des champs personnalisés pour la pièce
|
||||
if (typePiece && typePiece.id) {
|
||||
const customFields = await prisma.customField.findMany({
|
||||
where: { typePieceId: typePiece.id },
|
||||
if (!typePiece) {
|
||||
typePiece = await prisma.typePiece.create({
|
||||
data: {
|
||||
name: piece.name,
|
||||
description: piece.description || '',
|
||||
},
|
||||
});
|
||||
|
||||
for (const customField of customFields) {
|
||||
const defaultValue = piece.customFields?.find(cf => cf.name === customField.name)?.defaultValue || '';
|
||||
await prisma.customFieldValue.create({
|
||||
for (const customField of pieceCustomFields) {
|
||||
await prisma.customField.create({
|
||||
data: {
|
||||
value: defaultValue,
|
||||
customFieldId: customField.id,
|
||||
pieceId: createdPiece.id,
|
||||
name: customField.name,
|
||||
type: customField.type,
|
||||
required: customField.required || false,
|
||||
defaultValue: customField.defaultValue,
|
||||
options: customField.options || [],
|
||||
typePieceId: typePiece.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
typePieceId = typePiece.id;
|
||||
}
|
||||
|
||||
const createdPiece = await prisma.piece.create({
|
||||
data: {
|
||||
name: piece.name,
|
||||
reference: piece.reference || '',
|
||||
constructeurId: await this.resolveConstructeurId(prisma, piece.constructeur),
|
||||
emplacement: piece.emplacement || '',
|
||||
prix: piece.prix ?? null,
|
||||
composantId: createdComposant.id,
|
||||
typePieceId,
|
||||
pieceModelId,
|
||||
typeMachinePieceRequirementId: pieceRequirementId,
|
||||
},
|
||||
});
|
||||
|
||||
if (typePieceId) {
|
||||
const typePieceCustomFields = await prisma.customField.findMany({
|
||||
where: { typePieceId },
|
||||
});
|
||||
|
||||
for (const customField of typePieceCustomFields) {
|
||||
const defaultValue = pieceCustomFields.find((cf) => cf.name === customField.name)?.defaultValue || '';
|
||||
await prisma.customFieldValue.create({
|
||||
data: {
|
||||
value: defaultValue,
|
||||
customFieldId: customField.id,
|
||||
pieceId: createdPiece.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Créer les sous-composants récursivement
|
||||
if (component.subComponents) {
|
||||
await this.createComponentsFromType(prisma, machineId, component.subComponents, createdComposant.id);
|
||||
if (subComponents.length > 0) {
|
||||
await this.createComponentsFromType(prisma, machineId, subComponents, createdComposant.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -245,19 +538,76 @@ export class MachinesService {
|
||||
private async createMachinePiecesFromType(prisma: any, machineId: string, machinePieces: any[]) {
|
||||
for (const piece of machinePieces) {
|
||||
if (!piece || !piece.name) continue;
|
||||
|
||||
|
||||
const customFields = Array.isArray(piece.customFields) ? piece.customFields : [];
|
||||
const pieceModelId = piece.__pieceModelId ?? null;
|
||||
const requirementId = piece.__requirementId ?? null;
|
||||
const providedTypePieceId = piece.typePieceId
|
||||
?? (piece.typePiece && piece.typePiece.id ? piece.typePiece.id : null);
|
||||
|
||||
let typePieceId: string | null = providedTypePieceId ?? null;
|
||||
|
||||
if (!typePieceId && customFields.length > 0) {
|
||||
let typePiece = await prisma.typePiece.findFirst({
|
||||
where: { name: piece.name },
|
||||
});
|
||||
|
||||
if (!typePiece) {
|
||||
typePiece = await prisma.typePiece.create({
|
||||
data: {
|
||||
name: piece.name,
|
||||
description: piece.description || '',
|
||||
},
|
||||
});
|
||||
|
||||
for (const customField of customFields) {
|
||||
await prisma.customField.create({
|
||||
data: {
|
||||
name: customField.name,
|
||||
type: customField.type,
|
||||
required: customField.required || false,
|
||||
defaultValue: customField.defaultValue,
|
||||
options: customField.options || [],
|
||||
typePieceId: typePiece.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
typePieceId = typePiece.id;
|
||||
}
|
||||
|
||||
const createdPiece = await prisma.piece.create({
|
||||
data: {
|
||||
name: piece.name,
|
||||
machineId,
|
||||
reference: piece.reference || '',
|
||||
constructeurId: await this.resolveConstructeurId(prisma, piece.constructeur),
|
||||
emplacement: piece.emplacement || '',
|
||||
prix: piece.prix ?? null,
|
||||
machineId,
|
||||
typePieceId,
|
||||
pieceModelId,
|
||||
typeMachinePieceRequirementId: requirementId,
|
||||
},
|
||||
});
|
||||
|
||||
// Copier les champs personnalisés du type vers la pièce
|
||||
if (piece.customFields && piece.customFields.length > 0) {
|
||||
for (const customField of piece.customFields) {
|
||||
// Créer le champ personnalisé
|
||||
if (typePieceId) {
|
||||
const typePieceCustomFields = await prisma.customField.findMany({
|
||||
where: { typePieceId },
|
||||
});
|
||||
|
||||
for (const customField of typePieceCustomFields) {
|
||||
const defaultValue = customFields.find((cf) => cf.name === customField.name)?.defaultValue || '';
|
||||
await prisma.customFieldValue.create({
|
||||
data: {
|
||||
value: defaultValue,
|
||||
customFieldId: customField.id,
|
||||
pieceId: createdPiece.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
} else if (customFields.length > 0) {
|
||||
for (const customField of customFields) {
|
||||
const createdCustomField = await prisma.customField.create({
|
||||
data: {
|
||||
name: customField.name,
|
||||
@@ -265,11 +615,10 @@ export class MachinesService {
|
||||
required: customField.required || false,
|
||||
defaultValue: customField.defaultValue,
|
||||
options: customField.options || [],
|
||||
typePieceId: null, // Ce champ sera lié à la pièce individuelle
|
||||
typePieceId: null,
|
||||
},
|
||||
});
|
||||
|
||||
// Créer la valeur par défaut
|
||||
await prisma.customFieldValue.create({
|
||||
data: {
|
||||
value: customField.defaultValue || '',
|
||||
@@ -316,12 +665,28 @@ export class MachinesService {
|
||||
typeMachine: {
|
||||
include: {
|
||||
customFields: true,
|
||||
componentRequirements: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
pieceRequirements: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
composants: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
sousComposants: true,
|
||||
customFieldValues: {
|
||||
include: {
|
||||
@@ -337,6 +702,12 @@ export class MachinesService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -349,6 +720,12 @@ export class MachinesService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
customFieldValues: {
|
||||
@@ -369,12 +746,28 @@ export class MachinesService {
|
||||
typeMachine: {
|
||||
include: {
|
||||
customFields: true,
|
||||
componentRequirements: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
pieceRequirements: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
composants: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
sousComposants: true,
|
||||
customFieldValues: {
|
||||
include: {
|
||||
@@ -390,6 +783,12 @@ export class MachinesService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -402,6 +801,12 @@ export class MachinesService {
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
customFieldValues: {
|
||||
@@ -423,17 +828,39 @@ export class MachinesService {
|
||||
typeMachine: {
|
||||
include: {
|
||||
customFields: true,
|
||||
componentRequirements: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
pieceRequirements: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
constructeur: true,
|
||||
composants: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
composantModel: true,
|
||||
typeMachineComponentRequirement: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
sousComposants: true,
|
||||
constructeur: true,
|
||||
pieces: {
|
||||
include: {
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
customFieldValues: {
|
||||
include: {
|
||||
customField: true,
|
||||
@@ -446,6 +873,12 @@ export class MachinesService {
|
||||
pieces: {
|
||||
include: {
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
customFieldValues: {
|
||||
include: {
|
||||
customField: true,
|
||||
|
||||
@@ -15,6 +15,17 @@ export class PiecesService {
|
||||
typePiece: true,
|
||||
documents: true,
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
customFieldValues: {
|
||||
include: {
|
||||
customField: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -27,6 +38,17 @@ export class PiecesService {
|
||||
typePiece: true,
|
||||
documents: true,
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
customFieldValues: {
|
||||
include: {
|
||||
customField: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -40,6 +62,17 @@ export class PiecesService {
|
||||
typePiece: true,
|
||||
documents: true,
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
customFieldValues: {
|
||||
include: {
|
||||
customField: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -53,6 +86,17 @@ export class PiecesService {
|
||||
typePiece: true,
|
||||
documents: true,
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
customFieldValues: {
|
||||
include: {
|
||||
customField: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -66,6 +110,17 @@ export class PiecesService {
|
||||
typePiece: true,
|
||||
documents: true,
|
||||
constructeur: true,
|
||||
pieceModel: true,
|
||||
typeMachinePieceRequirement: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
customFieldValues: {
|
||||
include: {
|
||||
customField: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@ export class CreateComposantDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
typeComposantId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
composantModelId?: string;
|
||||
}
|
||||
|
||||
export class UpdateComposantDto {
|
||||
@@ -60,4 +64,8 @@ export class UpdateComposantDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
typeComposantId?: string;
|
||||
}
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
composantModelId?: string;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,30 @@
|
||||
import { IsString, IsOptional, IsDecimal } from 'class-validator';
|
||||
import { IsString, IsOptional, IsDecimal, IsArray } from 'class-validator';
|
||||
import { Type } from 'class-transformer';
|
||||
import { ValidateNested } from 'class-validator';
|
||||
|
||||
export class MachineComponentSelectionDto {
|
||||
@IsString()
|
||||
requirementId: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
componentModelId?: string;
|
||||
|
||||
@IsOptional()
|
||||
definition?: any;
|
||||
}
|
||||
|
||||
export class MachinePieceSelectionDto {
|
||||
@IsString()
|
||||
requirementId: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
pieceModelId?: string;
|
||||
|
||||
@IsOptional()
|
||||
definition?: any;
|
||||
}
|
||||
|
||||
export class CreateMachineDto {
|
||||
@IsString()
|
||||
@@ -26,6 +52,18 @@ export class CreateMachineDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
typeMachineId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => MachineComponentSelectionDto)
|
||||
componentSelections?: MachineComponentSelectionDto[];
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => MachinePieceSelectionDto)
|
||||
pieceSelections?: MachinePieceSelectionDto[];
|
||||
}
|
||||
|
||||
export class UpdateMachineDto {
|
||||
|
||||
@@ -33,6 +33,10 @@ export class CreatePieceDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
typePieceId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
pieceModelId?: string;
|
||||
}
|
||||
|
||||
export class UpdatePieceDto {
|
||||
@@ -60,4 +64,8 @@ export class UpdatePieceDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
typePieceId?: string;
|
||||
}
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
pieceModelId?: string;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { IsString, IsOptional, IsArray, IsObject, IsBoolean, IsEnum } from 'class-validator';
|
||||
import { IsString, IsOptional, IsArray, IsObject, IsBoolean, IsEnum, IsInt } from 'class-validator';
|
||||
import { Type } from 'class-transformer';
|
||||
import { ValidateNested } from 'class-validator';
|
||||
|
||||
export enum CustomFieldType {
|
||||
TEXT = 'text',
|
||||
@@ -50,6 +52,56 @@ export class UpdateCustomFieldDto {
|
||||
options?: string[];
|
||||
}
|
||||
|
||||
export class TypeMachineComponentRequirementDto {
|
||||
@IsString()
|
||||
typeComposantId: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
label?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
minCount?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
maxCount?: number | null;
|
||||
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
required?: boolean;
|
||||
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
allowNewModels?: boolean;
|
||||
}
|
||||
|
||||
export class TypeMachinePieceRequirementDto {
|
||||
@IsString()
|
||||
typePieceId: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
label?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
minCount?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
maxCount?: number | null;
|
||||
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
required?: boolean;
|
||||
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
allowNewModels?: boolean;
|
||||
}
|
||||
|
||||
export class CreateTypeMachineDto {
|
||||
@IsString()
|
||||
name: string;
|
||||
@@ -77,6 +129,18 @@ export class CreateTypeMachineDto {
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
customFields?: CreateCustomFieldDto[];
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => TypeMachineComponentRequirementDto)
|
||||
componentRequirements?: TypeMachineComponentRequirementDto[];
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => TypeMachinePieceRequirementDto)
|
||||
pieceRequirements?: TypeMachinePieceRequirementDto[];
|
||||
}
|
||||
|
||||
export class UpdateTypeMachineDto {
|
||||
@@ -107,6 +171,18 @@ export class UpdateTypeMachineDto {
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
customFields?: CreateCustomFieldDto[];
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => TypeMachineComponentRequirementDto)
|
||||
componentRequirements?: TypeMachineComponentRequirementDto[];
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => TypeMachinePieceRequirementDto)
|
||||
pieceRequirements?: TypeMachinePieceRequirementDto[];
|
||||
}
|
||||
|
||||
export class CreateTypeComposantDto {
|
||||
@@ -161,4 +237,68 @@ export class UpdateTypePieceDto {
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
customFields?: CreateCustomFieldDto[];
|
||||
}
|
||||
}
|
||||
|
||||
export class CreateComposantModelDto {
|
||||
@IsString()
|
||||
name: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string;
|
||||
|
||||
@IsString()
|
||||
typeComposantId: string;
|
||||
|
||||
@IsOptional()
|
||||
structure?: any;
|
||||
}
|
||||
|
||||
export class UpdateComposantModelDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
name?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
typeComposantId?: string;
|
||||
|
||||
@IsOptional()
|
||||
structure?: any;
|
||||
}
|
||||
|
||||
export class CreatePieceModelDto {
|
||||
@IsString()
|
||||
name: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string;
|
||||
|
||||
@IsString()
|
||||
typePieceId: string;
|
||||
|
||||
@IsOptional()
|
||||
structure?: any;
|
||||
}
|
||||
|
||||
export class UpdatePieceModelDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
name?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
typePieceId?: string;
|
||||
|
||||
@IsOptional()
|
||||
structure?: any;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
|
||||
import { Controller, Get, Post, Body, Patch, Param, Delete, Query } from '@nestjs/common';
|
||||
import { TypesService } from './types.service';
|
||||
import {
|
||||
CreateTypeMachineDto,
|
||||
@@ -6,7 +6,11 @@ import {
|
||||
CreateTypeComposantDto,
|
||||
UpdateTypeComposantDto,
|
||||
CreateTypePieceDto,
|
||||
UpdateTypePieceDto
|
||||
UpdateTypePieceDto,
|
||||
CreateComposantModelDto,
|
||||
UpdateComposantModelDto,
|
||||
CreatePieceModelDto,
|
||||
UpdatePieceModelDto
|
||||
} from '../shared/dto/type.dto';
|
||||
|
||||
@Controller('types')
|
||||
@@ -50,6 +54,32 @@ export class TypesController {
|
||||
return this.typesService.findAllTypeComposants();
|
||||
}
|
||||
|
||||
// ComposantModel routes
|
||||
@Post('composants/models')
|
||||
createComposantModel(@Body() createComposantModelDto: CreateComposantModelDto) {
|
||||
return this.typesService.createComposantModel(createComposantModelDto);
|
||||
}
|
||||
|
||||
@Get('composants/models')
|
||||
findAllComposantModels(@Query('typeComposantId') typeComposantId?: string) {
|
||||
return this.typesService.findAllComposantModels(typeComposantId);
|
||||
}
|
||||
|
||||
@Get('composants/models/:id')
|
||||
findOneComposantModel(@Param('id') id: string) {
|
||||
return this.typesService.findOneComposantModel(id);
|
||||
}
|
||||
|
||||
@Patch('composants/models/:id')
|
||||
updateComposantModel(@Param('id') id: string, @Body() updateComposantModelDto: UpdateComposantModelDto) {
|
||||
return this.typesService.updateComposantModel(id, updateComposantModelDto);
|
||||
}
|
||||
|
||||
@Delete('composants/models/:id')
|
||||
removeComposantModel(@Param('id') id: string) {
|
||||
return this.typesService.removeComposantModel(id);
|
||||
}
|
||||
|
||||
@Get('composants/:id')
|
||||
findOneTypeComposant(@Param('id') id: string) {
|
||||
return this.typesService.findOneTypeComposant(id);
|
||||
@@ -76,6 +106,32 @@ export class TypesController {
|
||||
return this.typesService.findAllTypePieces();
|
||||
}
|
||||
|
||||
// PieceModel routes
|
||||
@Post('pieces/models')
|
||||
createPieceModel(@Body() createPieceModelDto: CreatePieceModelDto) {
|
||||
return this.typesService.createPieceModel(createPieceModelDto);
|
||||
}
|
||||
|
||||
@Get('pieces/models')
|
||||
findAllPieceModels(@Query('typePieceId') typePieceId?: string) {
|
||||
return this.typesService.findAllPieceModels(typePieceId);
|
||||
}
|
||||
|
||||
@Get('pieces/models/:id')
|
||||
findOnePieceModel(@Param('id') id: string) {
|
||||
return this.typesService.findOnePieceModel(id);
|
||||
}
|
||||
|
||||
@Patch('pieces/models/:id')
|
||||
updatePieceModel(@Param('id') id: string, @Body() updatePieceModelDto: UpdatePieceModelDto) {
|
||||
return this.typesService.updatePieceModel(id, updatePieceModelDto);
|
||||
}
|
||||
|
||||
@Delete('pieces/models/:id')
|
||||
removePieceModel(@Param('id') id: string) {
|
||||
return this.typesService.removePieceModel(id);
|
||||
}
|
||||
|
||||
@Get('pieces/:id')
|
||||
findOneTypePiece(@Param('id') id: string) {
|
||||
return this.typesService.findOneTypePiece(id);
|
||||
|
||||
@@ -6,7 +6,11 @@ import {
|
||||
CreateTypeComposantDto,
|
||||
UpdateTypeComposantDto,
|
||||
CreateTypePieceDto,
|
||||
UpdateTypePieceDto
|
||||
UpdateTypePieceDto,
|
||||
CreateComposantModelDto,
|
||||
UpdateComposantModelDto,
|
||||
CreatePieceModelDto,
|
||||
UpdatePieceModelDto
|
||||
} from '../shared/dto/type.dto';
|
||||
|
||||
@Injectable()
|
||||
@@ -15,7 +19,7 @@ export class TypesService {
|
||||
|
||||
// TypeMachine methods
|
||||
async createTypeMachine(createTypeMachineDto: CreateTypeMachineDto) {
|
||||
const { customFields, ...typeData } = createTypeMachineDto;
|
||||
const { customFields, componentRequirements, pieceRequirements, ...typeData } = createTypeMachineDto;
|
||||
|
||||
return this.prisma.typeMachine.create({
|
||||
data: {
|
||||
@@ -28,10 +32,44 @@ export class TypesService {
|
||||
defaultValue: field.defaultValue,
|
||||
options: field.options
|
||||
}))
|
||||
} : undefined
|
||||
} : undefined,
|
||||
componentRequirements: componentRequirements && componentRequirements.length > 0 ? {
|
||||
create: componentRequirements.map(requirement => ({
|
||||
label: requirement.label,
|
||||
minCount: requirement.minCount ?? 1,
|
||||
maxCount: requirement.maxCount ?? null,
|
||||
required: requirement.required ?? true,
|
||||
allowNewModels: requirement.allowNewModels ?? true,
|
||||
typeComposant: {
|
||||
connect: { id: requirement.typeComposantId },
|
||||
},
|
||||
}))
|
||||
} : undefined,
|
||||
pieceRequirements: pieceRequirements && pieceRequirements.length > 0 ? {
|
||||
create: pieceRequirements.map(requirement => ({
|
||||
label: requirement.label,
|
||||
minCount: requirement.minCount ?? 0,
|
||||
maxCount: requirement.maxCount ?? null,
|
||||
required: requirement.required ?? false,
|
||||
allowNewModels: requirement.allowNewModels ?? true,
|
||||
typePiece: {
|
||||
connect: { id: requirement.typePieceId },
|
||||
},
|
||||
}))
|
||||
} : undefined,
|
||||
},
|
||||
include: {
|
||||
customFields: true,
|
||||
componentRequirements: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
pieceRequirements: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -41,6 +79,16 @@ export class TypesService {
|
||||
include: {
|
||||
machines: true,
|
||||
customFields: true,
|
||||
componentRequirements: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
pieceRequirements: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -51,12 +99,22 @@ export class TypesService {
|
||||
include: {
|
||||
machines: true,
|
||||
customFields: true,
|
||||
componentRequirements: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
pieceRequirements: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async updateTypeMachine(id: string, updateTypeMachineDto: UpdateTypeMachineDto) {
|
||||
const { customFields, ...typeData } = updateTypeMachineDto;
|
||||
const { customFields, componentRequirements, pieceRequirements, ...typeData } = updateTypeMachineDto;
|
||||
|
||||
// Si des champs personnalisés sont fournis, on les met à jour
|
||||
if (customFields !== undefined) {
|
||||
@@ -79,12 +137,64 @@ export class TypesService {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (componentRequirements !== undefined) {
|
||||
await this.prisma.typeMachineComponentRequirement.deleteMany({
|
||||
where: { typeMachineId: id },
|
||||
});
|
||||
|
||||
if (componentRequirements.length > 0) {
|
||||
await this.prisma.typeMachineComponentRequirement.createMany({
|
||||
data: componentRequirements.map(requirement => ({
|
||||
label: requirement.label ?? null,
|
||||
minCount: requirement.minCount ?? 1,
|
||||
maxCount: requirement.maxCount ?? null,
|
||||
required: requirement.required ?? true,
|
||||
allowNewModels: requirement.allowNewModels ?? true,
|
||||
typeMachineId: id,
|
||||
typeComposantId: requirement.typeComposantId,
|
||||
})),
|
||||
skipDuplicates: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (pieceRequirements !== undefined) {
|
||||
await this.prisma.typeMachinePieceRequirement.deleteMany({
|
||||
where: { typeMachineId: id },
|
||||
});
|
||||
|
||||
if (pieceRequirements.length > 0) {
|
||||
await this.prisma.typeMachinePieceRequirement.createMany({
|
||||
data: pieceRequirements.map(requirement => ({
|
||||
label: requirement.label ?? null,
|
||||
minCount: requirement.minCount ?? 0,
|
||||
maxCount: requirement.maxCount ?? null,
|
||||
required: requirement.required ?? false,
|
||||
allowNewModels: requirement.allowNewModels ?? true,
|
||||
typeMachineId: id,
|
||||
typePieceId: requirement.typePieceId,
|
||||
})),
|
||||
skipDuplicates: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return this.prisma.typeMachine.update({
|
||||
where: { id },
|
||||
data: typeData,
|
||||
include: {
|
||||
customFields: true,
|
||||
componentRequirements: {
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
},
|
||||
pieceRequirements: {
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -142,6 +252,7 @@ export class TypesService {
|
||||
include: {
|
||||
composants: true,
|
||||
customFields: true,
|
||||
models: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -152,6 +263,7 @@ export class TypesService {
|
||||
include: {
|
||||
composants: true,
|
||||
customFields: true,
|
||||
models: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -224,6 +336,7 @@ export class TypesService {
|
||||
include: {
|
||||
pieces: true,
|
||||
customFields: true,
|
||||
models: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -234,6 +347,7 @@ export class TypesService {
|
||||
include: {
|
||||
pieces: true,
|
||||
customFields: true,
|
||||
models: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -277,4 +391,134 @@ export class TypesService {
|
||||
where: { id },
|
||||
});
|
||||
}
|
||||
|
||||
// ComposantModel methods
|
||||
async createComposantModel(createComposantModelDto: CreateComposantModelDto) {
|
||||
const { typeComposantId, ...data } = createComposantModelDto;
|
||||
|
||||
return this.prisma.composantModel.create({
|
||||
data: {
|
||||
...data,
|
||||
typeComposant: {
|
||||
connect: { id: typeComposantId },
|
||||
},
|
||||
},
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async findAllComposantModels(typeComposantId?: string) {
|
||||
return this.prisma.composantModel.findMany({
|
||||
where: typeComposantId ? { typeComposantId } : undefined,
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
orderBy: {
|
||||
name: 'asc',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async findOneComposantModel(id: string) {
|
||||
return this.prisma.composantModel.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async updateComposantModel(id: string, updateComposantModelDto: UpdateComposantModelDto) {
|
||||
const { typeComposantId, ...data } = updateComposantModelDto;
|
||||
|
||||
return this.prisma.composantModel.update({
|
||||
where: { id },
|
||||
data: {
|
||||
...data,
|
||||
...(typeComposantId
|
||||
? {
|
||||
typeComposant: {
|
||||
connect: { id: typeComposantId },
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
include: {
|
||||
typeComposant: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async removeComposantModel(id: string) {
|
||||
return this.prisma.composantModel.delete({
|
||||
where: { id },
|
||||
});
|
||||
}
|
||||
|
||||
// PieceModel methods
|
||||
async createPieceModel(createPieceModelDto: CreatePieceModelDto) {
|
||||
const { typePieceId, ...data } = createPieceModelDto;
|
||||
|
||||
return this.prisma.pieceModel.create({
|
||||
data: {
|
||||
...data,
|
||||
typePiece: {
|
||||
connect: { id: typePieceId },
|
||||
},
|
||||
},
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async findAllPieceModels(typePieceId?: string) {
|
||||
return this.prisma.pieceModel.findMany({
|
||||
where: typePieceId ? { typePieceId } : undefined,
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
orderBy: {
|
||||
name: 'asc',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async findOnePieceModel(id: string) {
|
||||
return this.prisma.pieceModel.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async updatePieceModel(id: string, updatePieceModelDto: UpdatePieceModelDto) {
|
||||
const { typePieceId, ...data } = updatePieceModelDto;
|
||||
|
||||
return this.prisma.pieceModel.update({
|
||||
where: { id },
|
||||
data: {
|
||||
...data,
|
||||
...(typePieceId
|
||||
? {
|
||||
typePiece: {
|
||||
connect: { id: typePieceId },
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
include: {
|
||||
typePiece: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async removePieceModel(id: string) {
|
||||
return this.prisma.pieceModel.delete({
|
||||
where: { id },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user