FIx: delete champs par default

This commit is contained in:
Matthieu
2025-09-25 11:26:22 +02:00
parent e64fba3ae7
commit 2ce164784f
9 changed files with 226 additions and 200 deletions

View File

@@ -9,8 +9,16 @@ import {
MachinePieceSelectionDto,
} from '../shared/dto/machine.dto';
const CUSTOM_FIELD_SELECT = {
id: true,
name: true,
type: true,
required: true,
options: true,
} as const;
const TYPE_MACHINE_CONFIGURATION_INCLUDE = {
customFields: true,
customFields: { select: CUSTOM_FIELD_SELECT },
componentRequirements: {
include: {
typeComposant: true,
@@ -41,7 +49,7 @@ const MACHINE_DEFAULT_INCLUDE = {
sousComposants: true,
customFieldValues: {
include: {
customField: true,
customField: { select: CUSTOM_FIELD_SELECT },
},
},
constructeur: true,
@@ -49,7 +57,7 @@ const MACHINE_DEFAULT_INCLUDE = {
include: {
customFieldValues: {
include: {
customField: true,
customField: { select: CUSTOM_FIELD_SELECT },
},
},
constructeur: true,
@@ -67,7 +75,7 @@ const MACHINE_DEFAULT_INCLUDE = {
include: {
customFieldValues: {
include: {
customField: true,
customField: { select: CUSTOM_FIELD_SELECT },
},
},
constructeur: true,
@@ -81,7 +89,7 @@ const MACHINE_DEFAULT_INCLUDE = {
},
customFieldValues: {
include: {
customField: true,
customField: { select: CUSTOM_FIELD_SELECT },
},
},
documents: true,
@@ -472,6 +480,19 @@ export class MachinesService {
}
}
private extractCustomFieldValue(field: any): string | undefined {
if (
field &&
Object.prototype.hasOwnProperty.call(field, 'value')
) {
const rawValue = field.value;
return rawValue === undefined || rawValue === null
? ''
: String(rawValue);
}
return undefined;
}
private normalizeComponentSelection(
selection: MachineComponentSelectionDto,
requirement: any,
@@ -491,8 +512,6 @@ export class MachinesService {
'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)
@@ -565,6 +584,14 @@ export class MachinesService {
const customFields = Array.isArray(component.customFields)
? component.customFields
: [];
const componentFieldMap = new Map(
customFields
.filter((field) => field && typeof field.name === 'string')
.map((field) => [field.name, field]),
);
const resolveComponentValue = (fieldName: string) =>
this.extractCustomFieldValue(componentFieldMap.get(fieldName));
const componentPieces = Array.isArray(component.pieces)
? component.pieces
: [];
@@ -582,7 +609,7 @@ export class MachinesService {
let typeComposantId: string | null = providedTypeComposantId ?? null;
if (!typeComposantId && customFields.length > 0) {
if (!typeComposantId && componentFieldMap.size > 0) {
let typeComposant = await prisma.modelType.findFirst({
where: {
name: component.name,
@@ -604,12 +631,12 @@ export class MachinesService {
});
for (const customField of customFields) {
if (!customField?.name) continue;
await prisma.customField.create({
data: {
name: customField.name,
type: customField.type,
required: customField.required || false,
defaultValue: customField.defaultValue,
options: customField.options || [],
typeComposantId: typeComposant.id,
},
@@ -628,7 +655,6 @@ export class MachinesService {
prisma,
component.constructeur,
),
emplacement: component.emplacement || '',
prix: component.prix ?? null,
machineId,
parentComposantId,
@@ -644,16 +670,16 @@ export class MachinesService {
});
for (const customField of typeCustomFields) {
const defaultValue =
customFields.find((cf) => cf.name === customField.name)
?.defaultValue || '';
await prisma.customFieldValue.create({
data: {
value: defaultValue,
customFieldId: customField.id,
composantId: createdComposant.id,
},
});
const providedValue = resolveComponentValue(customField.name);
if (providedValue !== undefined) {
await prisma.customFieldValue.create({
data: {
value: providedValue,
customFieldId: customField.id,
composantId: createdComposant.id,
},
});
}
}
}
@@ -663,6 +689,13 @@ export class MachinesService {
const pieceCustomFields = Array.isArray(piece.customFields)
? piece.customFields
: [];
const pieceFieldMap = new Map(
pieceCustomFields
.filter((field) => field && typeof field.name === 'string')
.map((field) => [field.name, field]),
);
const resolvePieceValue = (fieldName: string) =>
this.extractCustomFieldValue(pieceFieldMap.get(fieldName));
const pieceModelId = piece.__pieceModelId ?? null;
const pieceRequirementId = piece.__requirementId ?? null;
const providedTypePieceId =
@@ -671,7 +704,7 @@ export class MachinesService {
let typePieceId: string | null = providedTypePieceId ?? null;
if (!typePieceId && pieceCustomFields.length > 0) {
if (!typePieceId && pieceFieldMap.size > 0) {
let typePiece = await prisma.typePiece.findFirst({
where: { name: piece.name },
});
@@ -685,12 +718,12 @@ export class MachinesService {
});
for (const customField of pieceCustomFields) {
if (!customField?.name) continue;
await prisma.customField.create({
data: {
name: customField.name,
type: customField.type,
required: customField.required || false,
defaultValue: customField.defaultValue,
options: customField.options || [],
typePieceId: typePiece.id,
},
@@ -709,7 +742,6 @@ export class MachinesService {
prisma,
piece.constructeur,
),
emplacement: piece.emplacement || '',
prix: piece.prix ?? null,
composantId: createdComposant.id,
typePieceId,
@@ -724,16 +756,16 @@ export class MachinesService {
});
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,
},
});
const providedValue = resolvePieceValue(customField.name);
if (providedValue !== undefined) {
await prisma.customFieldValue.create({
data: {
value: providedValue,
customFieldId: customField.id,
pieceId: createdPiece.id,
},
});
}
}
}
}
@@ -760,6 +792,13 @@ export class MachinesService {
const customFields = Array.isArray(piece.customFields)
? piece.customFields
: [];
const fieldMap = new Map(
customFields
.filter((field) => field && typeof field.name === 'string')
.map((field) => [field.name, field]),
);
const resolveProvidedValue = (fieldName: string) =>
this.extractCustomFieldValue(fieldMap.get(fieldName));
const pieceModelId = piece.__pieceModelId ?? null;
const requirementId = piece.__requirementId ?? null;
const providedTypePieceId =
@@ -768,7 +807,7 @@ export class MachinesService {
let typePieceId: string | null = providedTypePieceId ?? null;
if (!typePieceId && customFields.length > 0) {
if (!typePieceId && fieldMap.size > 0) {
let typePiece = await prisma.typePiece.findFirst({
where: { name: piece.name },
});
@@ -782,12 +821,12 @@ export class MachinesService {
});
for (const customField of customFields) {
if (!customField?.name) continue;
await prisma.customField.create({
data: {
name: customField.name,
type: customField.type,
required: customField.required || false,
defaultValue: customField.defaultValue,
options: customField.options || [],
typePieceId: typePiece.id,
},
@@ -806,7 +845,6 @@ export class MachinesService {
prisma,
piece.constructeur,
),
emplacement: piece.emplacement || '',
prix: piece.prix ?? null,
machineId,
typePieceId,
@@ -821,37 +859,40 @@ export class MachinesService {
});
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,
},
});
const providedValue = resolveProvidedValue(customField.name);
if (providedValue !== undefined) {
await prisma.customFieldValue.create({
data: {
value: providedValue,
customFieldId: customField.id,
pieceId: createdPiece.id,
},
});
}
}
} else if (customFields.length > 0) {
} else if (fieldMap.size > 0) {
for (const customField of customFields) {
if (!customField?.name) continue;
const createdCustomField = await prisma.customField.create({
data: {
name: customField.name,
type: customField.type,
required: customField.required || false,
defaultValue: customField.defaultValue,
options: customField.options || [],
typePieceId: null,
},
});
await prisma.customFieldValue.create({
data: {
value: customField.defaultValue || '',
customFieldId: createdCustomField.id,
pieceId: createdPiece.id,
},
});
const providedValue = this.extractCustomFieldValue(customField);
if (providedValue !== undefined) {
await prisma.customFieldValue.create({
data: {
value: providedValue,
customFieldId: createdCustomField.id,
pieceId: createdPiece.id,
},
});
}
}
}
}
@@ -865,26 +906,26 @@ export class MachinesService {
for (const customField of machineCustomFields) {
if (!customField || !customField.name) continue;
// Créer le champ personnalisé pour la machine
const createdCustomField = await prisma.customField.create({
data: {
name: customField.name,
type: customField.type,
required: customField.required || false,
defaultValue: customField.defaultValue,
options: customField.options || [],
typeMachineId: null, // Ce champ sera lié à la machine individuelle
},
});
// Créer la valeur par défaut pour la machine
await prisma.customFieldValue.create({
data: {
value: customField.defaultValue || '',
customFieldId: createdCustomField.id,
machineId: machineId,
},
});
const providedValue = this.extractCustomFieldValue(customField);
if (providedValue !== undefined) {
await prisma.customFieldValue.create({
data: {
value: providedValue,
customFieldId: createdCustomField.id,
machineId,
},
});
}
}
}
@@ -1160,7 +1201,7 @@ export class MachinesService {
},
},
include: {
customField: true,
customField: { select: CUSTOM_FIELD_SELECT },
},
});
@@ -1171,20 +1212,21 @@ export class MachinesService {
name: customField.name,
type: customField.type,
required: customField.required || false,
defaultValue: customField.defaultValue,
options: customField.options || [],
typeMachineId: null, // Ce champ sera lié à la machine individuelle
},
});
// Créer la valeur par défaut pour la machine
await this.prisma.customFieldValue.create({
data: {
value: customField.defaultValue || '',
customFieldId: createdCustomField.id,
machineId: machineId,
},
});
const providedValue = this.extractCustomFieldValue(customField);
if (providedValue !== undefined) {
await this.prisma.customFieldValue.create({
data: {
value: providedValue,
customFieldId: createdCustomField.id,
machineId,
},
});
}
}
}
}
@@ -1199,6 +1241,15 @@ export class MachinesService {
typeComponent.customFields &&
typeComponent.customFields.length > 0
) {
const typeComponentFields = Array.isArray(typeComponent.customFields)
? typeComponent.customFields
: [];
const typeComponentFieldMap = new Map(
typeComponentFields
.filter((field: any) => field && typeof field.name === 'string')
.map((field: any) => [field.name, field]),
);
// Créer le type de composant s'il n'existe pas
let typeComposant = await this.prisma.modelType.findFirst({
where: {
@@ -1222,7 +1273,7 @@ export class MachinesService {
}
// Créer les champs personnalisés pour le type de composant
for (const customField of typeComponent.customFields) {
for (const customField of typeComponentFields) {
const existingField = await this.prisma.customField.findFirst({
where: {
name: customField.name,
@@ -1236,7 +1287,6 @@ export class MachinesService {
name: customField.name,
type: customField.type,
required: customField.required || false,
defaultValue: customField.defaultValue,
options: customField.options || [],
typeComposantId: typeComposant.id,
},
@@ -1264,17 +1314,18 @@ export class MachinesService {
});
if (!existingValue) {
const defaultValue =
typeComponent.customFields.find(
(cf: any) => cf.name === customField.name,
)?.defaultValue || '';
await this.prisma.customFieldValue.create({
data: {
value: defaultValue,
customFieldId: customField.id,
composantId: component.id,
},
});
const providedValue = this.extractCustomFieldValue(
typeComponentFieldMap.get(customField.name),
);
if (providedValue !== undefined) {
await this.prisma.customFieldValue.create({
data: {
value: providedValue,
customFieldId: customField.id,
composantId: component.id,
},
});
}
}
}
@@ -1288,6 +1339,15 @@ export class MachinesService {
typePiece.customFields &&
typePiece.customFields.length > 0
) {
const typePieceFields = Array.isArray(typePiece.customFields)
? typePiece.customFields
: [];
const typePieceFieldMap = new Map(
typePieceFields
.filter((field: any) => field && typeof field.name === 'string')
.map((field: any) => [field.name, field]),
);
// Créer le type de pièce s'il n'existe pas
let typePieceEntity = await this.prisma.modelType.findFirst({
where: {
@@ -1312,7 +1372,7 @@ export class MachinesService {
}
// Créer les champs personnalisés pour le type de pièce
for (const customField of typePiece.customFields) {
for (const customField of typePieceFields) {
const existingField = await this.prisma.customField.findFirst({
where: {
name: customField.name,
@@ -1326,7 +1386,6 @@ export class MachinesService {
name: customField.name,
type: customField.type,
required: customField.required || false,
defaultValue: customField.defaultValue,
options: customField.options || [],
typePieceId: typePieceEntity.id,
},
@@ -1355,17 +1414,18 @@ export class MachinesService {
});
if (!existingValue) {
const defaultValue =
typePiece.customFields.find(
(cf: any) => cf.name === customField.name,
)?.defaultValue || '';
await this.prisma.customFieldValue.create({
data: {
value: defaultValue,
customFieldId: customField.id,
pieceId: piece.id,
},
});
const providedValue = this.extractCustomFieldValue(
typePieceFieldMap.get(customField.name),
);
if (providedValue !== undefined) {
await this.prisma.customFieldValue.create({
data: {
value: providedValue,
customFieldId: customField.id,
pieceId: piece.id,
},
});
}
}
}
}
@@ -1381,6 +1441,15 @@ export class MachinesService {
typePiece.customFields &&
typePiece.customFields.length > 0
) {
const typePieceFields = Array.isArray(typePiece.customFields)
? typePiece.customFields
: [];
const typePieceFieldMap = new Map(
typePieceFields
.filter((field: any) => field && typeof field.name === 'string')
.map((field: any) => [field.name, field]),
);
// Créer le type de pièce s'il n'existe pas
let typePieceEntity = await this.prisma.modelType.findFirst({
where: {
@@ -1405,7 +1474,7 @@ export class MachinesService {
}
// Créer les champs personnalisés pour le type de pièce
for (const customField of typePiece.customFields) {
for (const customField of typePieceFields) {
const existingField = await this.prisma.customField.findFirst({
where: {
name: customField.name,
@@ -1419,7 +1488,6 @@ export class MachinesService {
name: customField.name,
type: customField.type,
required: customField.required || false,
defaultValue: customField.defaultValue,
options: customField.options || [],
typePieceId: typePieceEntity.id,
},
@@ -1447,17 +1515,18 @@ export class MachinesService {
});
if (!existingValue) {
const defaultValue =
typePiece.customFields.find(
(cf: any) => cf.name === customField.name,
)?.defaultValue || '';
await this.prisma.customFieldValue.create({
data: {
value: defaultValue,
customFieldId: customField.id,
pieceId: piece.id,
},
});
const providedValue = this.extractCustomFieldValue(
typePieceFieldMap.get(customField.name),
);
if (providedValue !== undefined) {
await this.prisma.customFieldValue.create({
data: {
value: providedValue,
customFieldId: customField.id,
pieceId: piece.id,
},
});
}
}
}
}

View File

@@ -26,10 +26,6 @@ export class CreateComposantDto {
@IsNumber({}, { message: 'prix must be a valid number' })
prix?: number | null;
@IsOptional()
@IsString()
emplacement?: string;
@IsOptional()
@IsString()
typeComposantId?: string;
@@ -60,10 +56,6 @@ export class UpdateComposantDto {
@IsNumber({}, { message: 'prix must be a valid number' })
prix?: number | null;
@IsOptional()
@IsString()
emplacement?: string;
@IsOptional()
@IsString()
typeComposantId?: string;

View File

@@ -41,10 +41,6 @@ export class CreateMachineDto {
@IsDecimal()
prix?: string;
@IsOptional()
@IsString()
emplacement?: string;
@IsOptional()
@IsString()
typeMachineId?: string;
@@ -79,10 +75,6 @@ export class UpdateMachineDto {
@IsDecimal()
prix?: string;
@IsOptional()
@IsString()
emplacement?: string;
@IsOptional()
@IsString()
typeMachineId?: string;

View File

@@ -26,10 +26,6 @@ export class CreatePieceDto {
@IsNumber({}, { message: 'prix must be a valid number' })
prix?: number | null;
@IsOptional()
@IsString()
emplacement?: string;
@IsOptional()
@IsString()
typePieceId?: string;
@@ -60,10 +56,6 @@ export class UpdatePieceDto {
@IsNumber({}, { message: 'prix must be a valid number' })
prix?: number | null;
@IsOptional()
@IsString()
emplacement?: string;
@IsOptional()
@IsString()
typePieceId?: string;

View File

@@ -29,10 +29,6 @@ export class CreateCustomFieldDto {
@IsBoolean()
required?: boolean;
@IsOptional()
@IsString()
defaultValue?: string;
@IsOptional()
@IsArray()
options?: string[]; // Pour les champs de type SELECT
@@ -51,10 +47,6 @@ export class UpdateCustomFieldDto {
@IsBoolean()
required?: boolean;
@IsOptional()
@IsString()
defaultValue?: string;
@IsOptional()
@IsArray()
options?: string[];

View File

@@ -14,6 +14,14 @@ import {
UpdatePieceModelDto,
} from '../shared/dto/type.dto';
const CUSTOM_FIELD_SELECT = {
id: true,
name: true,
type: true,
required: true,
options: true,
} as const;
@Injectable()
export class TypesService {
constructor(private prisma: PrismaService) {}
@@ -63,7 +71,6 @@ export class TypesService {
name: field.name,
type: field.type,
required: field.required || false,
defaultValue: field.defaultValue,
options: field.options,
})),
}
@@ -100,7 +107,7 @@ export class TypesService {
: undefined,
},
include: {
customFields: true,
customFields: { select: CUSTOM_FIELD_SELECT },
componentRequirements: {
include: {
typeComposant: true,
@@ -119,7 +126,7 @@ export class TypesService {
return this.prisma.typeMachine.findMany({
include: {
machines: true,
customFields: true,
customFields: { select: CUSTOM_FIELD_SELECT },
componentRequirements: {
include: {
typeComposant: true,
@@ -139,7 +146,7 @@ export class TypesService {
where: { id },
include: {
machines: true,
customFields: true,
customFields: { select: CUSTOM_FIELD_SELECT },
componentRequirements: {
include: {
typeComposant: true,
@@ -179,7 +186,6 @@ export class TypesService {
name: field.name,
type: field.type,
required: field.required || false,
defaultValue: field.defaultValue,
options: field.options,
typeMachineId: id,
})),
@@ -233,7 +239,7 @@ export class TypesService {
where: { id },
data: typeData,
include: {
customFields: true,
customFields: { select: CUSTOM_FIELD_SELECT },
componentRequirements: {
include: {
typeComposant: true,
@@ -292,14 +298,13 @@ export class TypesService {
name: field.name,
type: field.type,
required: field.required || false,
defaultValue: field.defaultValue,
options: field.options,
})),
}
: undefined,
},
include: {
customFields: true,
customFields: { select: CUSTOM_FIELD_SELECT },
},
});
}
@@ -309,7 +314,7 @@ export class TypesService {
where: { category: ModelCategory.COMPONENT },
include: {
composants: true,
customFields: true,
customFields: { select: CUSTOM_FIELD_SELECT },
models: true,
},
});
@@ -323,7 +328,7 @@ export class TypesService {
},
include: {
composants: true,
customFields: true,
customFields: { select: CUSTOM_FIELD_SELECT },
models: true,
},
});
@@ -346,7 +351,6 @@ export class TypesService {
name: field.name,
type: field.type,
required: field.required || false,
defaultValue: field.defaultValue,
options: field.options,
typeComposantId: id,
})),
@@ -367,7 +371,7 @@ export class TypesService {
where: { id },
data,
include: {
customFields: true,
customFields: { select: CUSTOM_FIELD_SELECT },
},
});
}
@@ -419,14 +423,13 @@ export class TypesService {
name: field.name,
type: field.type,
required: field.required || false,
defaultValue: field.defaultValue,
options: field.options,
})),
}
: undefined,
},
include: {
pieceCustomFields: true,
pieceCustomFields: { select: CUSTOM_FIELD_SELECT },
pieceModels: true,
pieceRequirements: true,
pieces: true,
@@ -440,7 +443,7 @@ export class TypesService {
const items = await this.prisma.modelType.findMany({
where: { category: ModelCategory.PIECE },
include: {
pieceCustomFields: true,
pieceCustomFields: { select: CUSTOM_FIELD_SELECT },
pieceModels: true,
pieceRequirements: true,
pieces: true,
@@ -455,7 +458,7 @@ export class TypesService {
const item = await this.prisma.modelType.findFirst({
where: { id, category: ModelCategory.PIECE },
include: {
pieceCustomFields: true,
pieceCustomFields: { select: CUSTOM_FIELD_SELECT },
pieceModels: true,
pieceRequirements: true,
pieces: true,
@@ -479,7 +482,6 @@ export class TypesService {
name: field.name,
type: field.type,
required: field.required || false,
defaultValue: field.defaultValue,
options: field.options,
typePieceId: id,
})),
@@ -500,7 +502,7 @@ export class TypesService {
where: { id },
data: updatePayload,
include: {
pieceCustomFields: true,
pieceCustomFields: { select: CUSTOM_FIELD_SELECT },
pieceModels: true,
pieceRequirements: true,
pieces: true,