diff --git a/apps/edr-freight-api/src/modules/rule-engine/repositories/cargo-types.repository.ts b/apps/edr-freight-api/src/modules/rule-engine/repositories/cargo-types.repository.ts index 4df961aaa..07993c267 100644 --- a/apps/edr-freight-api/src/modules/rule-engine/repositories/cargo-types.repository.ts +++ b/apps/edr-freight-api/src/modules/rule-engine/repositories/cargo-types.repository.ts @@ -59,26 +59,57 @@ export class CargoTypesRepository implements ICargoTypesRepository { } async create(data: Partial): Promise { - const entity = this.repo.create(data); - return this.repo.save(entity); + const { wagonTypes, ...columns } = data; + const entity = this.repo.create(columns); + const saved = await this.repo.save(entity); + if (wagonTypes?.length) { + await this.syncWagonTypes(saved.id, wagonTypes.map((wt) => wt.id), []); + } + return (await this.findById(saved.id)) ?? saved; } async update(id: string, data: Partial): Promise { - // Relation lists can't ride a column UPDATE — sync them via entity save. const { wagonTypes, ...columns } = data; if (Object.keys(columns).length) { await this.repo.update(id, columns as never); } if (wagonTypes) { - const entity = await this.repo.findOne({ where: { id } }); - if (entity) { - entity.wagonTypes = wagonTypes; - await this.repo.save(entity); + const current = await this.repo.findOne({ + where: { id }, + relations: { wagonTypes: true }, + }); + if (current) { + await this.syncWagonTypes( + id, + wagonTypes.map((wt) => wt.id), + (current.wagonTypes ?? []).map((wt) => wt.id), + ); } } return this.findById(id); } + /** + * Diffs the wagon-type links through the relation query builder rather than + * an entity save: junction-row inserts from save() broadcast afterInsert with + * no entity attached, which the @tria-plc/auditlog subscriber (deployed + * builds) dereferences and crashes the request on. + */ + private async syncWagonTypes( + id: string, + nextIds: string[], + currentIds: string[], + ): Promise { + const toAdd = nextIds.filter((x) => !currentIds.includes(x)); + const toRemove = currentIds.filter((x) => !nextIds.includes(x)); + if (!toAdd.length && !toRemove.length) return; + await this.repo + .createQueryBuilder() + .relation(CargoType, 'wagonTypes') + .of(id) + .addAndRemove(toAdd, toRemove); + } + async softDelete(id: string): Promise { await this.repo.softDelete(id); } diff --git a/apps/edr-freight-web/backoffice/src/components/fleet/FleetRecordActions.tsx b/apps/edr-freight-web/backoffice/src/components/fleet/FleetRecordActions.tsx index 4ab2c42f9..898982f34 100644 --- a/apps/edr-freight-web/backoffice/src/components/fleet/FleetRecordActions.tsx +++ b/apps/edr-freight-web/backoffice/src/components/fleet/FleetRecordActions.tsx @@ -126,6 +126,15 @@ const FleetRecordActions = ({ {removeLabel} ) : null} + {onPurge ? ( + onPurge(record)} + leftSection={} + > + Delete permanently + + ) : null} );