feat: auto populate machine structures and seed sample data
This commit is contained in:
@@ -109,6 +109,32 @@ type PieceRecord = {
|
||||
updatedAt: Date;
|
||||
};
|
||||
|
||||
type MachineComponentLinkRecord = {
|
||||
id: string;
|
||||
machineId: string;
|
||||
composantId: string;
|
||||
parentLinkId: Nullable<string>;
|
||||
typeMachineComponentRequirementId: Nullable<string>;
|
||||
nameOverride: Nullable<string>;
|
||||
referenceOverride: Nullable<string>;
|
||||
prixOverride: Nullable<string>;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
};
|
||||
|
||||
type MachinePieceLinkRecord = {
|
||||
id: string;
|
||||
machineId: string;
|
||||
pieceId: string;
|
||||
parentLinkId: Nullable<string>;
|
||||
typeMachinePieceRequirementId: Nullable<string>;
|
||||
nameOverride: Nullable<string>;
|
||||
referenceOverride: Nullable<string>;
|
||||
prixOverride: Nullable<string>;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
};
|
||||
|
||||
type ModelTypeRecord = {
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -171,6 +197,8 @@ class InMemoryPrismaService {
|
||||
private machines: MachineRecord[] = [];
|
||||
private composants: ComposantRecord[] = [];
|
||||
private pieces: PieceRecord[] = [];
|
||||
private machineComponentLinks: MachineComponentLinkRecord[] = [];
|
||||
private machinePieceLinks: MachinePieceLinkRecord[] = [];
|
||||
private customFields: CustomFieldRecord[] = [];
|
||||
private customFieldValues: CustomFieldValueRecord[] = [];
|
||||
private profiles: ProfileRecord[] = [];
|
||||
@@ -196,6 +224,8 @@ class InMemoryPrismaService {
|
||||
this.machines = [];
|
||||
this.composants = [];
|
||||
this.pieces = [];
|
||||
this.machineComponentLinks = [];
|
||||
this.machinePieceLinks = [];
|
||||
this.customFields = [];
|
||||
this.customFieldValues = [];
|
||||
this.profiles = [];
|
||||
@@ -720,6 +750,108 @@ class InMemoryPrismaService {
|
||||
},
|
||||
};
|
||||
|
||||
machineComponentLink = {
|
||||
create: async ({ data, include }: any) => {
|
||||
const now = new Date();
|
||||
const record: MachineComponentLinkRecord = {
|
||||
id: data.id ?? generateId('mcl'),
|
||||
machineId: data.machineId,
|
||||
composantId: data.composantId,
|
||||
parentLinkId: data.parentLinkId ?? null,
|
||||
typeMachineComponentRequirementId:
|
||||
data.typeMachineComponentRequirementId ?? null,
|
||||
nameOverride:
|
||||
data.nameOverride !== undefined ? data.nameOverride : null,
|
||||
referenceOverride:
|
||||
data.referenceOverride !== undefined ? data.referenceOverride : null,
|
||||
prixOverride:
|
||||
data.prixOverride !== undefined && data.prixOverride !== null
|
||||
? String(data.prixOverride)
|
||||
: data.prixOverride ?? null,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
this.machineComponentLinks.push(record);
|
||||
return this.buildMachineComponentLink(record, include ?? {});
|
||||
},
|
||||
deleteMany: async ({ where }: any) => {
|
||||
const before = this.machineComponentLinks.length;
|
||||
this.machineComponentLinks = this.machineComponentLinks.filter((link) => {
|
||||
if (where?.machineId !== undefined) {
|
||||
return link.machineId !== where.machineId;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return { count: before - this.machineComponentLinks.length };
|
||||
},
|
||||
findMany: async ({ where, include }: any = {}) => {
|
||||
let links = this.machineComponentLinks;
|
||||
if (where?.machineId) {
|
||||
links = links.filter((link) => link.machineId === where.machineId);
|
||||
}
|
||||
if (where?.parentLinkId === null) {
|
||||
links = links.filter((link) => link.parentLinkId === null);
|
||||
} else if (where?.parentLinkId) {
|
||||
links = links.filter(
|
||||
(link) => link.parentLinkId === where.parentLinkId,
|
||||
);
|
||||
}
|
||||
return links.map((link) =>
|
||||
this.buildMachineComponentLink(link, include ?? {}),
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
machinePieceLink = {
|
||||
create: async ({ data, include }: any) => {
|
||||
const now = new Date();
|
||||
const record: MachinePieceLinkRecord = {
|
||||
id: data.id ?? generateId('mpl'),
|
||||
machineId: data.machineId,
|
||||
pieceId: data.pieceId,
|
||||
parentLinkId: data.parentLinkId ?? null,
|
||||
typeMachinePieceRequirementId:
|
||||
data.typeMachinePieceRequirementId ?? null,
|
||||
nameOverride:
|
||||
data.nameOverride !== undefined ? data.nameOverride : null,
|
||||
referenceOverride:
|
||||
data.referenceOverride !== undefined ? data.referenceOverride : null,
|
||||
prixOverride:
|
||||
data.prixOverride !== undefined && data.prixOverride !== null
|
||||
? String(data.prixOverride)
|
||||
: data.prixOverride ?? null,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
this.machinePieceLinks.push(record);
|
||||
return this.buildMachinePieceLink(record, include ?? {});
|
||||
},
|
||||
deleteMany: async ({ where }: any) => {
|
||||
const before = this.machinePieceLinks.length;
|
||||
this.machinePieceLinks = this.machinePieceLinks.filter((link) => {
|
||||
if (where?.machineId !== undefined) {
|
||||
return link.machineId !== where.machineId;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return { count: before - this.machinePieceLinks.length };
|
||||
},
|
||||
findMany: async ({ where, include }: any = {}) => {
|
||||
let links = this.machinePieceLinks;
|
||||
if (where?.machineId) {
|
||||
links = links.filter((link) => link.machineId === where.machineId);
|
||||
}
|
||||
if (where?.parentLinkId === null) {
|
||||
links = links.filter((link) => link.parentLinkId === null);
|
||||
} else if (where?.parentLinkId) {
|
||||
links = links.filter(
|
||||
(link) => link.parentLinkId === where.parentLinkId,
|
||||
);
|
||||
}
|
||||
return links.map((link) => this.buildMachinePieceLink(link, include ?? {}));
|
||||
},
|
||||
};
|
||||
|
||||
customField = {
|
||||
create: async ({ data }: any) => {
|
||||
const now = new Date();
|
||||
@@ -1181,6 +1313,27 @@ class InMemoryPrismaService {
|
||||
base.constructeur = null;
|
||||
}
|
||||
|
||||
if (include?.componentLinks) {
|
||||
const links = this.machineComponentLinks.filter(
|
||||
(link) => link.machineId === machine.id,
|
||||
);
|
||||
base.componentLinks = links.map((link) =>
|
||||
this.buildMachineComponentLink(
|
||||
link,
|
||||
include.componentLinks.include ?? {},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (include?.pieceLinks) {
|
||||
const links = this.machinePieceLinks.filter(
|
||||
(link) => link.machineId === machine.id,
|
||||
);
|
||||
base.pieceLinks = links.map((link) =>
|
||||
this.buildMachinePieceLink(link, include.pieceLinks.include ?? {}),
|
||||
);
|
||||
}
|
||||
|
||||
if (include?.composants) {
|
||||
const composants = this.composants.filter(
|
||||
(component) => component.machineId === machine.id,
|
||||
@@ -1220,6 +1373,87 @@ class InMemoryPrismaService {
|
||||
return base;
|
||||
}
|
||||
|
||||
private buildMachineComponentLink(
|
||||
link: MachineComponentLinkRecord,
|
||||
include: any,
|
||||
) {
|
||||
const base: any = { ...link };
|
||||
|
||||
if (include?.composant) {
|
||||
const composant =
|
||||
this.composants.find((item) => item.id === link.composantId) ?? null;
|
||||
base.composant = composant
|
||||
? this.buildComponent(composant, include.composant.include ?? {})
|
||||
: null;
|
||||
}
|
||||
|
||||
if (include?.typeMachineComponentRequirement) {
|
||||
const requirement = link.typeMachineComponentRequirementId
|
||||
? this.typeMachineComponentRequirements.find(
|
||||
(item) => item.id === link.typeMachineComponentRequirementId,
|
||||
) ?? null
|
||||
: null;
|
||||
base.typeMachineComponentRequirement = requirement
|
||||
? {
|
||||
...requirement,
|
||||
typeComposant:
|
||||
include.typeMachineComponentRequirement.include?.typeComposant
|
||||
? this.typeComposants.find(
|
||||
(item) => item.id === requirement.typeComposantId,
|
||||
) ?? null
|
||||
: undefined,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
if (include?.pieceLinks) {
|
||||
const nestedInclude = include.pieceLinks.include ?? {};
|
||||
const pieces = this.machinePieceLinks.filter(
|
||||
(pieceLink) => pieceLink.parentLinkId === link.id,
|
||||
);
|
||||
base.pieceLinks = pieces.map((pieceLink) =>
|
||||
this.buildMachinePieceLink(pieceLink, nestedInclude),
|
||||
);
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
private buildMachinePieceLink(
|
||||
link: MachinePieceLinkRecord,
|
||||
include: any,
|
||||
) {
|
||||
const base: any = { ...link };
|
||||
|
||||
if (include?.piece) {
|
||||
const piece = this.pieces.find((item) => item.id === link.pieceId) ?? null;
|
||||
base.piece = piece
|
||||
? this.buildPiece(piece, include.piece.include ?? {})
|
||||
: null;
|
||||
}
|
||||
|
||||
if (include?.typeMachinePieceRequirement) {
|
||||
const requirement = link.typeMachinePieceRequirementId
|
||||
? this.typeMachinePieceRequirements.find(
|
||||
(item) => item.id === link.typeMachinePieceRequirementId,
|
||||
) ?? null
|
||||
: null;
|
||||
base.typeMachinePieceRequirement = requirement
|
||||
? {
|
||||
...requirement,
|
||||
typePiece:
|
||||
include.typeMachinePieceRequirement.include?.typePiece
|
||||
? this.typePieces.find(
|
||||
(item) => item.id === requirement.typePieceId,
|
||||
) ?? null
|
||||
: undefined,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
private buildComponent(component: ComposantRecord, include: any) {
|
||||
const base: any = { ...component };
|
||||
|
||||
@@ -1459,42 +1693,46 @@ describe('Inventory flow (e2e)', () => {
|
||||
const componentRequirementId = typeMachine.componentRequirements[0].id;
|
||||
const pieceRequirementId = typeMachine.pieceRequirements[0].id;
|
||||
|
||||
const baseComponent = await prisma.composant.create({
|
||||
data: {
|
||||
name: 'Bloc moteur standard',
|
||||
reference: 'COMP-BASE',
|
||||
typeComposantId,
|
||||
},
|
||||
});
|
||||
|
||||
const basePiece = await prisma.piece.create({
|
||||
data: {
|
||||
name: 'Kit maintenance standard',
|
||||
reference: 'KIT-BASE',
|
||||
typePieceId,
|
||||
},
|
||||
});
|
||||
|
||||
const machineResponse = await request(app.getHttpServer())
|
||||
.post('/machines')
|
||||
.send({
|
||||
name: 'Presse HP-2000',
|
||||
siteId,
|
||||
typeMachineId: typeMachine.id,
|
||||
componentSelections: [
|
||||
componentLinks: [
|
||||
{
|
||||
requirementId: componentRequirementId,
|
||||
definition: {
|
||||
composantId: baseComponent.id,
|
||||
overrides: {
|
||||
name: 'Bloc moteur série X',
|
||||
reference: 'COMP-001',
|
||||
customFields: [
|
||||
{
|
||||
name: 'Puissance nominale',
|
||||
type: 'text',
|
||||
required: true,
|
||||
value: '7 kW',
|
||||
},
|
||||
],
|
||||
prix: '12000.00',
|
||||
},
|
||||
},
|
||||
],
|
||||
pieceSelections: [
|
||||
pieceLinks: [
|
||||
{
|
||||
requirementId: pieceRequirementId,
|
||||
definition: {
|
||||
pieceId: basePiece.id,
|
||||
overrides: {
|
||||
name: 'Kit maintenance niveau 1',
|
||||
reference: 'KIT-001',
|
||||
customFields: [
|
||||
{
|
||||
name: 'Référence fournisseur',
|
||||
type: 'text',
|
||||
value: 'STD-002',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -1509,31 +1747,19 @@ describe('Inventory flow (e2e)', () => {
|
||||
expect(machineDetailsResponse.status).toBe(200);
|
||||
const machine = machineDetailsResponse.body;
|
||||
|
||||
expect(machine.composants).toHaveLength(1);
|
||||
expect(machine.pieces).toHaveLength(1);
|
||||
expect(machine.componentLinks).toHaveLength(1);
|
||||
expect(machine.pieceLinks).toHaveLength(1);
|
||||
|
||||
const component = machine.composants[0];
|
||||
expect(component.name).toBe('Bloc moteur série X');
|
||||
expect(component.customFieldValues[0].value).toBe('7 kW');
|
||||
const componentLink = machine.componentLinks[0];
|
||||
expect(componentLink.composantId).toBe(baseComponent.id);
|
||||
expect(componentLink.overrides.name).toBe('Bloc moteur série X');
|
||||
expect(componentLink.composant.name).toBe('Bloc moteur série X');
|
||||
expect(componentLink.originalComposant.name).toBe('Bloc moteur standard');
|
||||
|
||||
const piece = machine.pieces[0];
|
||||
expect(piece.name).toBe('Kit maintenance niveau 1');
|
||||
expect(piece.customFieldValues[0].value).toBe('STD-002');
|
||||
|
||||
const customFieldValueId = component.customFieldValues[0].id;
|
||||
const updateResponse = await request(app.getHttpServer())
|
||||
.patch(`/custom-fields/values/${customFieldValueId}`)
|
||||
.send({ value: '8 kW' });
|
||||
|
||||
expect(updateResponse.status).toBe(200);
|
||||
expect(updateResponse.body.value).toBe('8 kW');
|
||||
|
||||
const refreshedMachineResponse = await request(app.getHttpServer()).get(
|
||||
`/machines/${machine.id}`,
|
||||
);
|
||||
expect(refreshedMachineResponse.status).toBe(200);
|
||||
const refreshedComponent = refreshedMachineResponse.body.composants[0];
|
||||
expect(refreshedComponent.customFieldValues[0].value).toBe('8 kW');
|
||||
const pieceLink = machine.pieceLinks[0];
|
||||
expect(pieceLink.pieceId).toBe(basePiece.id);
|
||||
expect(pieceLink.overrides.name).toBe('Kit maintenance niveau 1');
|
||||
expect(pieceLink.piece.name).toBe('Kit maintenance niveau 1');
|
||||
});
|
||||
|
||||
describe('POST /composants', () => {
|
||||
|
||||
Reference in New Issue
Block a user