add maintenance model, factory and service

This commit is contained in:
Julian Krauser 2025-05-28 22:51:17 +02:00
parent cb60d61773
commit 0f6401953f
11 changed files with 276 additions and 4 deletions

View file

@ -69,6 +69,7 @@ import { inspectionPoint } from "./entity/unit/inspection/inspectionPoint";
import { inspection } from "./entity/unit/inspection/inspection";
import { inspectionPointResult } from "./entity/unit/inspection/inspectionPointResult";
import { UnitBase1748261477410 } from "./migrations/1748261477410-unitBase";
import { maintenance } from "./entity/unit/maintenance";
configCheck();
@ -131,6 +132,7 @@ const dataSource = new DataSource({
wearableType,
wearable,
damageReport,
maintenance,
inspectionPlan,
inspectionVersionedPlan,
inspectionPoint,

View file

@ -1,7 +1,8 @@
import { Check, Column, CreateDateColumn, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
import { Column, CreateDateColumn, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
import { equipment } from "./equipment/equipment";
import { wearable } from "./wearable/wearable";
import { vehicle } from "./vehicle/vehicle";
import { maintenance } from "./maintenance";
@Entity()
export class damageReport {
@ -29,6 +30,9 @@ export class damageReport {
@Column({ nullable: true, default: null })
equipmentId?: string;
@Column({ nullable: true, default: null })
maintenanceId: string;
@Column({ nullable: true, default: null })
vehicleId?: string;
@ -55,4 +59,11 @@ export class damageReport {
onUpdate: "RESTRICT",
})
wearable?: wearable;
@ManyToOne(() => maintenance, {
nullable: true,
onDelete: "SET NULL",
onUpdate: "RESTRICT",
})
maintenance?: maintenance;
}

View file

@ -0,0 +1,56 @@
import { Column, CreateDateColumn, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { equipment } from "./equipment/equipment";
import { wearable } from "./wearable/wearable";
import { vehicle } from "./vehicle/vehicle";
import { damageReport } from "./damageReport";
@Entity()
export class maintenance {
@PrimaryGeneratedColumn("uuid")
id: string;
@CreateDateColumn()
createdAt: Date;
@Column({ type: "varchar", length: 255 })
status: string;
@Column({ type: "boolean", default: false })
done: boolean;
@Column({ type: "text" })
description: string;
@Column({ nullable: true, default: null })
equipmentId?: string;
@Column({ nullable: true, default: null })
vehicleId?: string;
@Column({ nullable: true, default: null })
wearableId?: string;
@ManyToOne(() => equipment, {
nullable: true,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
equipment?: equipment;
@ManyToOne(() => vehicle, {
nullable: true,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
vehicle?: vehicle;
@ManyToOne(() => wearable, {
nullable: true,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
wearable?: wearable;
@OneToMany(() => damageReport, (dr) => dr.maintenance)
reports: damageReport[];
}

View file

@ -1,6 +1,7 @@
import { damageReport } from "../../../entity/unit/damageReport";
import { DamageReportAssigned, DamageReportViewModel } from "../../../viewmodel/admin/unit/damageReport.models";
import EquipmentFactory from "./equipment/equipment";
import MaintenanceFactory from "./maintenance";
import VehicleFactory from "./vehicle/vehicle";
import WearableFactory from "./wearable/wearable";
@ -34,13 +35,14 @@ export default abstract class DamageReportFactory {
return {
id: record.id,
reported: record.reportedAt,
reportedAt: record.reportedAt,
status: record.status,
done: record.done,
description: record.description,
imageCount: record.imageCount,
reportedBy: record?.reportedBy,
...assigned,
maintenance: record.maintenance ? MaintenanceFactory.mapToSingle(record.maintenance) : null,
};
}

View file

@ -0,0 +1,55 @@
import { maintenance } from "../../../entity/unit/maintenance";
import { MaintenanceAssigned, MaintenanceViewModel } from "../../../viewmodel/admin/unit/maintenance.models";
import DamageReportFactory from "./damageReport";
import EquipmentFactory from "./equipment/equipment";
import VehicleFactory from "./vehicle/vehicle";
import WearableFactory from "./wearable/wearable";
export default abstract class MaintenanceFactory {
/**
* @description map record to maintenance
* @param {maintenance} record
* @returns {MaintenanceViewModel}
*/
public static mapToSingle(record: maintenance): MaintenanceViewModel {
let assigned: MaintenanceAssigned;
if (record?.equipmentId) {
assigned = {
relatedId: record.equipmentId,
assigned: "equipment",
related: EquipmentFactory.mapToSingle(record.equipment),
};
} else if (record?.vehicleId) {
assigned = {
relatedId: record.vehicleId,
assigned: "vehicle",
related: VehicleFactory.mapToSingle(record.vehicle),
};
} else {
assigned = {
relatedId: record.wearableId,
assigned: "wearable",
related: WearableFactory.mapToSingle(record.wearable),
};
}
return {
id: record.id,
createdAt: record.createdAt,
status: record.status,
done: record.done,
description: record.description,
...assigned,
reports: record.reports ? DamageReportFactory.mapToBase(record.reports) : [],
};
}
/**
* @description map records to maintenance
* @param {Array<maintenance>} records
* @returns {Array<MaintenanceViewModel>}
*/
public static mapToBase(records: Array<maintenance>): Array<MaintenanceViewModel> {
return records.map((r) => this.mapToSingle(r));
}
}

View file

@ -7,7 +7,7 @@ import {
wearable_table,
wearable_type_table,
} from "./baseSchemaTables/unit";
import { damage_report_table } from "./baseSchemaTables/unit_extend";
import { damage_report_table, maintenance_table } from "./baseSchemaTables/unit_extend";
import {
inspection_plan_table,
inspection_point_result_table,
@ -27,6 +27,7 @@ export class UnitBase1748261477410 implements MigrationInterface {
await queryRunner.createTable(wearable_type_table, true, true, true);
await queryRunner.createTable(wearable_table, true, true, true);
await queryRunner.createTable(maintenance_table, true, true, true);
await queryRunner.createTable(damage_report_table, true, true, true);
await queryRunner.createTable(inspection_plan_table, true, true, true);
@ -46,6 +47,7 @@ export class UnitBase1748261477410 implements MigrationInterface {
await queryRunner.dropTable(inspection_plan_table, true, true, true);
await queryRunner.dropTable(damage_report_table, true, true, true);
await queryRunner.dropTable(maintenance_table, true, true, true);
await queryRunner.dropTable(wearable_table, true, true, true);
await queryRunner.dropTable(wearable_type_table, true, true, true);

View file

@ -14,6 +14,51 @@ export const damage_report_table = new Table({
{ name: "equipmentId", ...getTypeByORM("uuid", true), default: getDefaultByORM("null") },
{ name: "vehicleId", ...getTypeByORM("uuid", true), default: getDefaultByORM("null") },
{ name: "wearableId", ...getTypeByORM("uuid", true), default: getDefaultByORM("null") },
{ name: "maintenanceId", ...getTypeByORM("uuid", true), default: getDefaultByORM("null") },
],
foreignKeys: [
new TableForeignKey({
columnNames: ["equipmentId"],
referencedColumnNames: ["id"],
referencedTableName: "equipment",
onDelete: "CASCADE",
onUpdate: "RESTRICT",
}),
new TableForeignKey({
columnNames: ["vehicleId"],
referencedColumnNames: ["id"],
referencedTableName: "vehicle",
onDelete: "CASCADE",
onUpdate: "RESTRICT",
}),
new TableForeignKey({
columnNames: ["wearableId"],
referencedColumnNames: ["id"],
referencedTableName: "wearable",
onDelete: "CASCADE",
onUpdate: "RESTRICT",
}),
new TableForeignKey({
columnNames: ["maintenanceId"],
referencedColumnNames: ["id"],
referencedTableName: "maintenance",
onDelete: "SET NULL",
onUpdate: "RESTRICT",
}),
],
});
export const maintenance_table = new Table({
name: "maintenance",
columns: [
{ name: "id", ...getTypeByORM("uuid"), ...isUUIDPrimary },
{ name: "createdAt", ...getTypeByORM("date"), default: getDefaultByORM("currentTimestamp") },
{ name: "status", ...getTypeByORM("varchar") },
{ name: "done", ...getTypeByORM("boolean"), default: getDefaultByORM("boolean", false) },
{ name: "description", ...getTypeByORM("text") },
{ name: "equipmentId", ...getTypeByORM("uuid", true), default: getDefaultByORM("null") },
{ name: "vehicleId", ...getTypeByORM("uuid", true), default: getDefaultByORM("null") },
{ name: "wearableId", ...getTypeByORM("uuid", true), default: getDefaultByORM("null") },
],
foreignKeys: [
new TableForeignKey({

View file

@ -14,6 +14,7 @@ export default abstract class DamageReportService {
.leftJoinAndSelect("damageReport.equipment", "equipment")
.leftJoinAndSelect("damageReport.vehicle", "vehicle")
.leftJoinAndSelect("damageReport.wearable", "wearable")
.leftJoinAndSelect("damageReport.maintenance", "maintenance")
.orderBy("type", "ASC")
.getMany()
.then((res) => {
@ -32,6 +33,10 @@ export default abstract class DamageReportService {
return await dataSource
.getRepository(damageReport)
.createQueryBuilder("damageReport")
.leftJoinAndSelect("damageReport.equipment", "equipment")
.leftJoinAndSelect("damageReport.vehicle", "vehicle")
.leftJoinAndSelect("damageReport.wearable", "wearable")
.leftJoinAndSelect("damageReport.maintenance", "maintenance")
.where({ id })
.getOneOrFail()
.then((res) => {

View file

@ -0,0 +1,49 @@
import { dataSource } from "../../data-source";
import { maintenance } from "../../entity/unit/maintenance";
import DatabaseActionException from "../../exceptions/databaseActionException";
export default abstract class MaintenanceService {
/**
* @description get all maintenances
* @returns {Promise<Array<maintenance>>}
*/
static async getAll(): Promise<Array<maintenance>> {
return await dataSource
.getRepository(maintenance)
.createQueryBuilder("maintenance")
.leftJoinAndSelect("maintenance.equipment", "equipment")
.leftJoinAndSelect("maintenance.vehicle", "vehicle")
.leftJoinAndSelect("maintenance.wearable", "wearable")
.leftJoinAndSelect("maintenance.reports", "reports")
.orderBy("type", "ASC")
.getMany()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "maintenance", err);
});
}
/**
* @description get maintenance by id
* @returns {Promise<maintenance>}
*/
static async getById(id: string): Promise<maintenance> {
return await dataSource
.getRepository(maintenance)
.createQueryBuilder("maintenance")
.leftJoinAndSelect("maintenance.equipment", "equipment")
.leftJoinAndSelect("maintenance.vehicle", "vehicle")
.leftJoinAndSelect("maintenance.wearable", "wearable")
.leftJoinAndSelect("maintenance.reports", "reports")
.where({ id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "maintenance", err);
});
}
}

View file

@ -1,4 +1,5 @@
import { EquipmentViewModel } from "./equipment/equipment.models";
import { MaintenanceViewModel } from "./maintenance.models";
import { VehicleViewModel } from "./vehicle/vehicle.models";
import { WearableViewModel } from "./wearable/wearable.models";
@ -21,12 +22,13 @@ export type DamageReportAssigned = {
export type DamageReportViewModel = {
id: string;
reported: Date;
reportedAt: Date;
status: string;
done: boolean;
description: string;
imageCount: number;
reportedBy: string;
maintenance?: MaintenanceViewModel;
} & DamageReportAssigned;
export interface CreateDamageReportViewModel {

View file

@ -0,0 +1,43 @@
import { DamageReportViewModel } from "./damageReport.models";
import { EquipmentViewModel } from "./equipment/equipment.models";
import { VehicleViewModel } from "./vehicle/vehicle.models";
import { WearableViewModel } from "./wearable/wearable.models";
export type MaintenanceAssigned = {
relatedId: string;
} & (
| {
assigned: "equipment";
related: EquipmentViewModel;
}
| {
assigned: "vehicle";
related: VehicleViewModel;
}
| {
assigned: "wearable";
related: WearableViewModel;
}
);
export type MaintenanceViewModel = {
id: string;
createdAt: Date;
status: string;
done: boolean;
description: string;
reports: DamageReportViewModel[];
} & MaintenanceAssigned;
export interface CreateMaintenanceViewModel {
description: string;
reportedBy: string;
affectedId: string;
affected: "equipment" | "vehicle" | "wearable";
}
export interface UpdateMaintenanceViewModel {
id: string;
status: string;
done: boolean;
}