Merge pull request 'unit/#102-base-management' (#121) from unit/#102-base-management into milestone/ff-admin-unit

Reviewed-on: #121
This commit is contained in:
Julian Krauser 2025-07-14 13:36:34 +00:00
commit 0f7530ca39
118 changed files with 6733 additions and 21 deletions

View file

@ -0,0 +1,22 @@
export interface CreateDamageReportCommand {
description: string;
reportedBy: string;
imageCount: number;
affectedId: string;
affected: "equipment" | "vehicle" | "wearable";
}
export interface UpdateDamageReportCommand {
id: string;
status: string;
done: boolean;
}
export interface UpdateDamageReportRelatedMaintenanceCommand {
id: string;
maintenanceId: string;
}
export interface DeleteDamageReportCommand {
id: string;
}

View file

@ -0,0 +1,100 @@
import { dataSource } from "../../data-source";
import { damageReport } from "../../entity/unit/damageReport";
import DatabaseActionException from "../../exceptions/databaseActionException";
import {
CreateDamageReportCommand,
UpdateDamageReportCommand,
DeleteDamageReportCommand,
UpdateDamageReportRelatedMaintenanceCommand,
} from "./damageReportCommand";
export default abstract class DamageReportCommandHandler {
/**
* @description create damageReport
* @param {CreateDamageReportCommand} createDamageReport
* @returns {Promise<number>}
*/
static async create(createDamageReport: CreateDamageReportCommand): Promise<number> {
return await dataSource
.createQueryBuilder()
.insert()
.into(damageReport)
.values({
status: "eingereicht",
description: createDamageReport.description,
reportedBy: createDamageReport.reportedBy,
imageCount: createDamageReport.imageCount,
equipmentId: createDamageReport.affected == "equipment" ? createDamageReport.affectedId : null,
vehicleId: createDamageReport.affected == "vehicle" ? createDamageReport.affectedId : null,
wearableId: createDamageReport.affected == "wearable" ? createDamageReport.affectedId : null,
})
.execute()
.then((result) => {
return result.identifiers[0].id;
})
.catch((err) => {
throw new DatabaseActionException("CREATE", "damageReport", err);
});
}
/**
* @description update damageReport
* @param {UpdateDamageReportCommand} updateDamageReport
* @returns {Promise<void>}
*/
static async update(updateDamageReport: UpdateDamageReportCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.update(damageReport)
.set({
status: updateDamageReport.status,
done: updateDamageReport.done,
})
.where("id = :id", { id: updateDamageReport.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("UPDATE", "damageReport", err);
});
}
/**
* @description update damageReport related maintenance
* @param {UpdateDamageReportCommand} updateDamageReport
* @returns {Promise<void>}
*/
static async updateRelatedMaintenance(
updateDamageReport: UpdateDamageReportRelatedMaintenanceCommand
): Promise<void> {
return await dataSource
.createQueryBuilder()
.update(damageReport)
.set({
maintenanceId: updateDamageReport.maintenanceId,
})
.where("id = :id", { id: updateDamageReport.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("UPDATE", "damageReport->maintenance", err);
});
}
/**
* @description delete damageReport
* @param {DeleteDamageReportCommand} deleteDamageReport
* @returns {Promise<void>}
*/
static async delete(deleteDamageReport: DeleteDamageReportCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.delete()
.from(damageReport)
.where("id = :id", { id: deleteDamageReport.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("DELETE", "damageReport", err);
});
}
}

View file

@ -0,0 +1,20 @@
export interface CreateEquipmentCommand {
code?: string;
name: string;
location: string;
commissioned: Date;
equipmentTypeId: string;
}
export interface UpdateEquipmentCommand {
id: string;
code?: string;
name: string;
location: string;
commissioned: Date;
decommissioned?: Date;
}
export interface DeleteEquipmentCommand {
id: string;
}

View file

@ -0,0 +1,74 @@
import { dataSource } from "../../../data-source";
import { equipment } from "../../../entity/unit/equipment/equipment";
import DatabaseActionException from "../../../exceptions/databaseActionException";
import { CreateEquipmentCommand, UpdateEquipmentCommand, DeleteEquipmentCommand } from "./equipmentCommand";
export default abstract class EquipmentCommandHandler {
/**
* @description create equipment
* @param {CreateEquipmentCommand} createEquipment
* @returns {Promise<number>}
*/
static async create(createEquipment: CreateEquipmentCommand): Promise<number> {
return await dataSource
.createQueryBuilder()
.insert()
.into(equipment)
.values({
code: createEquipment.code,
name: createEquipment.name,
location: createEquipment.location,
commissioned: createEquipment.commissioned,
equipmentTypeId: createEquipment.equipmentTypeId,
})
.execute()
.then((result) => {
return result.identifiers[0].id;
})
.catch((err) => {
throw new DatabaseActionException("CREATE", "equipment", err);
});
}
/**
* @description update equipment
* @param {UpdateEquipmentCommand} updateEquipment
* @returns {Promise<void>}
*/
static async update(updateEquipment: UpdateEquipmentCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.update(equipment)
.set({
code: updateEquipment.code,
name: updateEquipment.name,
location: updateEquipment.location,
commissioned: updateEquipment.commissioned,
decommissioned: updateEquipment.decommissioned,
})
.where("id = :id", { id: updateEquipment.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("UPDATE", "equipment", err);
});
}
/**
* @description delete equipment
* @param {DeleteEquipmentCommand} deleteEquipment
* @returns {Promise<void>}
*/
static async delete(deleteEquipment: DeleteEquipmentCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.delete()
.from(equipment)
.where("id = :id", { id: deleteEquipment.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("DELETE", "equipment", err);
});
}
}

View file

@ -0,0 +1,14 @@
export interface CreateEquipmentTypeCommand {
type: string;
description: string;
}
export interface UpdateEquipmentTypeCommand {
id: string;
type: string;
description: string;
}
export interface DeleteEquipmentTypeCommand {
id: string;
}

View file

@ -0,0 +1,72 @@
import { dataSource } from "../../../data-source";
import { equipmentType } from "../../../entity/unit/equipment/equipmentType";
import DatabaseActionException from "../../../exceptions/databaseActionException";
import {
CreateEquipmentTypeCommand,
UpdateEquipmentTypeCommand,
DeleteEquipmentTypeCommand,
} from "./equipmentTypeCommand";
export default abstract class EquipmentTypeCommandHandler {
/**
* @description create equipmentType
* @param {CreateEquipmentTypeCommand} createEquipmentType
* @returns {Promise<number>}
*/
static async create(createEquipmentType: CreateEquipmentTypeCommand): Promise<number> {
return await dataSource
.createQueryBuilder()
.insert()
.into(equipmentType)
.values({
type: createEquipmentType.type,
description: createEquipmentType.description,
})
.execute()
.then((result) => {
return result.identifiers[0].id;
})
.catch((err) => {
throw new DatabaseActionException("CREATE", "equipmentType", err);
});
}
/**
* @description update equipmentType
* @param {UpdateEquipmentTypeCommand} updateEquipmentType
* @returns {Promise<void>}
*/
static async update(updateEquipmentType: UpdateEquipmentTypeCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.update(equipmentType)
.set({
type: updateEquipmentType.type,
description: updateEquipmentType.description,
})
.where("id = :id", { id: updateEquipmentType.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("UPDATE", "equipmentType", err);
});
}
/**
* @description delete equipmentType
* @param {DeleteEquipmentTypeCommand} deleteEquipmentType
* @returns {Promise<void>}
*/
static async delete(deleteEquipmentType: DeleteEquipmentTypeCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.delete()
.from(equipmentType)
.where("id = :id", { id: deleteEquipmentType.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("DELETE", "equipmentType", err);
});
}
}

View file

@ -0,0 +1,21 @@
export interface CreateInspectionCommand {
context: string;
nextInspection?: Date;
inspectionPlanId: string;
relatedId: string;
assigned: "vehicle" | "equipment" | "wearable";
}
export interface UpdateInspectionCommand {
id: string;
context: string;
nextInspection?: Date;
}
export interface FinishInspectionCommand {
id: string;
}
export interface DeleteInspectionCommand {
id: string;
}

View file

@ -0,0 +1,154 @@
import { IsNull, Not } from "typeorm";
import { dataSource } from "../../../data-source";
import { inspection } from "../../../entity/unit/inspection/inspection";
import DatabaseActionException from "../../../exceptions/databaseActionException";
import InspectionService from "../../../service/unit/inspection/inspectionService";
import InspectionVersionedPlanService from "../../../service/unit/inspection/inspectionVersionedPlanService";
import {
CreateInspectionCommand,
UpdateInspectionCommand,
DeleteInspectionCommand,
FinishInspectionCommand,
} from "./inspectionCommand";
export default abstract class InspectionCommandHandler {
/**
* @description create inspection
* @param {CreateInspectionCommand} createInspection
* @returns {Promise<string>}
*/
static async create(createInspection: CreateInspectionCommand): Promise<string> {
let latestVersionedPlan = await InspectionVersionedPlanService.getLatestForInspectionPlan(
createInspection.inspectionPlanId
);
let insertId = "";
return await dataSource
.transaction(async (manager) => {
await manager
.createQueryBuilder()
.update(inspection)
.set({
hasNewer: true,
})
.where({
inspectionPlanId: createInspection.inspectionPlanId,
equipmentId: createInspection.assigned == "equipment" ? createInspection.relatedId : IsNull(),
vehicleId: createInspection.assigned == "vehicle" ? createInspection.relatedId : IsNull(),
wearableId: createInspection.assigned == "wearable" ? createInspection.relatedId : IsNull(),
})
.execute();
await manager
.createQueryBuilder()
.insert()
.into(inspection)
.values({
context: createInspection.context,
nextInspection: createInspection.nextInspection,
inspectionPlanId: createInspection.inspectionPlanId,
inspectionVersionedPlanId: latestVersionedPlan.id,
equipmentId: createInspection.assigned == "equipment" ? createInspection.relatedId : null,
vehicleId: createInspection.assigned == "vehicle" ? createInspection.relatedId : null,
wearableId: createInspection.assigned == "wearable" ? createInspection.relatedId : null,
})
.execute()
.then((result) => {
insertId = result.identifiers[0].id;
});
})
.then(() => {
return insertId;
})
.catch((err) => {
throw new DatabaseActionException("CREATE", "inspection", err);
});
}
/**
* @description update inspection
* @param {UpdateInspectionCommand} updateInspection
* @returns {Promise<void>}
*/
static async update(updateInspection: UpdateInspectionCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.update(inspection)
.set({
context: updateInspection.context,
nextInspection: updateInspection.nextInspection,
})
.where("id = :id", { id: updateInspection.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("UPDATE", "inspection", err);
});
}
/**
* @description finish inspection
* @param {FinishInspectionCommand} finishInspection
* @returns {Promise<void>}
*/
static async finish(finishInspection: FinishInspectionCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.update(inspection)
.set({
finishedAt: new Date(),
})
.where("id = :id", { id: finishInspection.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("FINISH", "inspection", err);
});
}
/**
* @description delete inspection
* @param {DeleteInspectionCommand} deleteInspection
* @returns {Promise<void>}
*/
static async delete(deleteInspection: DeleteInspectionCommand): Promise<void> {
let deleteInspectionData = await InspectionService.getById(deleteInspection.id);
return await dataSource
.transaction(async (manager) => {
let latestInspection = await manager
.createQueryBuilder()
.from(inspection, "sub")
.where({
inspectionPlanId: deleteInspectionData.inspectionPlanId,
inspectionVersionedPlanId: deleteInspectionData.inspectionVersionedPlanId,
equipmentId: deleteInspectionData.equipmentId ?? IsNull(),
vehicleId: deleteInspectionData.vehicleId ?? IsNull(),
wearableId: deleteInspectionData.wearableId ?? IsNull(),
})
.andWhere({ id: Not(deleteInspection.id) })
.orderBy("sub.createdAt", "DESC")
.limit(1)
.getOne();
if (latestInspection)
await manager
.createQueryBuilder()
.update(inspection)
.set({
hasNewer: false,
})
.where({ id: latestInspection.id })
.execute();
await manager
.createQueryBuilder()
.delete()
.from(inspection)
.where("id = :id", { id: deleteInspection.id })
.execute();
})
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("DELETE", "inspection", err);
});
}
}

View file

@ -0,0 +1,20 @@
import { PlanTimeDefinition } from "../../../viewmodel/admin/unit/inspection/inspectionPlan.models";
export interface CreateInspectionPlanCommand {
title: string;
inspectionInterval: PlanTimeDefinition;
remindTime: PlanTimeDefinition;
relatedId: string;
assigned: "vehicle" | "equipment";
}
export interface UpdateInspectionPlanCommand {
id: string;
title: string;
inspectionInterval: PlanTimeDefinition;
remindTime?: PlanTimeDefinition;
}
export interface DeleteInspectionPlanCommand {
id: string;
}

View file

@ -0,0 +1,76 @@
import { dataSource } from "../../../data-source";
import { inspectionPlan } from "../../../entity/unit/inspection/inspectionPlan";
import DatabaseActionException from "../../../exceptions/databaseActionException";
import {
CreateInspectionPlanCommand,
UpdateInspectionPlanCommand,
DeleteInspectionPlanCommand,
} from "./inspectionPlanCommand";
export default abstract class InspectionPlanCommandHandler {
/**
* @description create inspectionPlan
* @param {CreateInspectionPlanCommand} createInspectionPlan
* @returns {Promise<number>}
*/
static async create(createInspectionPlan: CreateInspectionPlanCommand): Promise<number> {
return await dataSource
.createQueryBuilder()
.insert()
.into(inspectionPlan)
.values({
title: createInspectionPlan.title,
inspectionInterval: createInspectionPlan.inspectionInterval,
remindTime: createInspectionPlan.remindTime,
equipmentTypeId: createInspectionPlan.assigned == "equipment" ? createInspectionPlan.relatedId : null,
vehicleTypeId: createInspectionPlan.assigned == "vehicle" ? createInspectionPlan.relatedId : null,
})
.execute()
.then((result) => {
return result.identifiers[0].id;
})
.catch((err) => {
throw new DatabaseActionException("CREATE", "inspectionPlan", err);
});
}
/**
* @description update inspectionPlan
* @param {UpdateInspectionPlanCommand} updateInspectionPlan
* @returns {Promise<void>}
*/
static async update(updateInspectionPlan: UpdateInspectionPlanCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.update(inspectionPlan)
.set({
title: updateInspectionPlan.title,
inspectionInterval: updateInspectionPlan.inspectionInterval,
remindTime: updateInspectionPlan.remindTime,
})
.where("id = :id", { id: updateInspectionPlan.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("UPDATE", "inspectionPlan", err);
});
}
/**
* @description delete inspectionPlan
* @param {DeleteInspectionPlanCommand} deleteInspectionPlan
* @returns {Promise<void>}
*/
static async delete(deleteInspectionPlan: DeleteInspectionPlanCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.delete()
.from(inspectionPlan)
.where("id = :id", { id: deleteInspectionPlan.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("DELETE", "inspectionPlan", err);
});
}
}

View file

@ -0,0 +1,13 @@
import { InspectionPointEnum } from "../../../enums/inspectionEnum";
export interface CreateInspectionPointCommand {
id?: string;
title: string;
description: string;
type: InspectionPointEnum;
min?: number;
max?: number;
others?: string;
sort: number;
versionedPointId?: string;
}

View file

@ -0,0 +1,74 @@
import { dataSource } from "../../../data-source";
import { inspectionPoint } from "../../../entity/unit/inspection/inspectionPoint";
import DatabaseActionException from "../../../exceptions/databaseActionException";
import InspectionPointService from "../../../service/unit/inspection/inspectionPointService";
import { CreateInspectionPointCommand } from "./inspectionPointCommand";
export default abstract class InspectionPointCommandHandler {
/**
* @description create inspectionPoint
* @param {CreateInspectionPointCommand} createInspectionPoint
* @returns {Promise<number>}
*/
static async create(createInspectionPoint: CreateInspectionPointCommand): Promise<number> {
return await dataSource
.createQueryBuilder()
.insert()
.into(inspectionPoint)
.values({
title: createInspectionPoint.title,
description: createInspectionPoint.description,
type: createInspectionPoint.type,
min: createInspectionPoint.min,
max: createInspectionPoint.max,
sort: createInspectionPoint.sort,
versionedPlanId: createInspectionPoint.versionedPointId,
})
.execute()
.then((result) => {
return result.identifiers[0].id;
})
.catch((err) => {
throw new DatabaseActionException("CREATE", "inspectionPoint", err);
});
}
/**
* @description sync points
* @param {string} versionedPlanId
* @param {Array<CreateInspectionPointCommand>} sync
* @returns {Promise<void>}
*/
static async sync(versionedPlanId: string, sync: Array<CreateInspectionPointCommand>): Promise<void> {
let points = await InspectionPointService.getAllForVersionedPlan(versionedPlanId);
await dataSource
.transaction(async (manager) => {
let remove = points.filter((r) => !sync.some((cp) => cp.id == r.id));
await manager
.createQueryBuilder()
.insert()
.into(inspectionPoint)
.values(
sync.map((s) => ({
...s,
id: points.some((p) => p.id == s.id) ? s.id : undefined,
versionedPlanId,
}))
)
.orUpdate(["title", "description", "min", "max", "others", "sort"], ["id"])
.execute();
if (remove.length != 0)
await manager
.createQueryBuilder()
.delete()
.from(inspectionPoint)
.where("id IN (:...ids)", { ids: remove.map((r) => r.id) })
.andWhere({ versionedPlanId })
.execute();
})
.catch((err) => {
throw new DatabaseActionException("SYNC", "inspectionPoint", err);
});
}
}

View file

@ -0,0 +1,5 @@
export interface CreateOrUpdateInspectionPointResultCommand {
inspectionId: string;
inspectionPointId: string;
value: string;
}

View file

@ -0,0 +1,54 @@
import { dataSource } from "../../../data-source";
import { inspectionPointResult } from "../../../entity/unit/inspection/inspectionPointResult";
import DatabaseActionException from "../../../exceptions/databaseActionException";
import { CreateOrUpdateInspectionPointResultCommand } from "./inspectionPointResultCommand";
export default abstract class InspectionPointResultCommandHandler {
/**
* @description create inspectionPointResult
* @param {CreateOrUpdateInspectionPointResultCommand} createInspectionPointResult
* @returns {Promise<number>}
*/
static async createOrUpdate(
createInspectionPointResult: CreateOrUpdateInspectionPointResultCommand
): Promise<number> {
return await dataSource
.createQueryBuilder()
.insert()
.into(inspectionPointResult)
.values({
inspectionId: createInspectionPointResult.inspectionId,
inspectionPointId: createInspectionPointResult.inspectionPointId,
value: createInspectionPointResult.value,
})
.orUpdate(["value"], ["inspectionId", "inspectionPointId"])
.execute()
.then((result) => {
return result.identifiers[0].id;
})
.catch((err) => {
throw new DatabaseActionException("CREATE or UPDATE", "inspectionPointResult", err);
});
}
/**
* @description create inspectionPointResult
* @param {Array<CreateOrUpdateInspectionPointResultCommand>} results
* @returns {Promise<number>}
*/
static async createOrUpdateMultiple(results: Array<CreateOrUpdateInspectionPointResultCommand>): Promise<number> {
return await dataSource
.createQueryBuilder()
.insert()
.into(inspectionPointResult)
.values(results)
.orUpdate(["value"], ["inspectionId", "inspectionPointId"])
.execute()
.then((result) => {
return result.identifiers[0].id;
})
.catch((err) => {
throw new DatabaseActionException("CREATE or UPDATE", "inspectionPointResult", err);
});
}
}

View file

@ -0,0 +1,3 @@
export interface CreateInspectionVersionedPlanCommand {
inspectionPlanId: string;
}

View file

@ -0,0 +1,62 @@
import { dataSource } from "../../../data-source";
import { inspectionPoint } from "../../../entity/unit/inspection/inspectionPoint";
import { inspectionVersionedPlan } from "../../../entity/unit/inspection/inspectionVersionedPlan";
import DatabaseActionException from "../../../exceptions/databaseActionException";
import InspectionVersionedPlanService from "../../../service/unit/inspection/inspectionVersionedPlanService";
import { CreateInspectionPointCommand } from "./inspectionPointCommand";
import { CreateInspectionVersionedPlanCommand } from "./inspectionVersionedPlanCommand";
export default abstract class InspectionVersionedPlanCommandHandler {
/**
* @description create inspectionVersionedPlan
* @param {CreateInspectionVersionedPlanCommand} createInspectionVersionedPlan
* @returns {Promise<string>}
*/
static async create(
createInspectionVersionedPlan: CreateInspectionVersionedPlanCommand,
inspectionPoints: Array<CreateInspectionPointCommand>
): Promise<string> {
let count = await InspectionVersionedPlanService.countForPlanId(createInspectionVersionedPlan.inspectionPlanId);
let returnId = "";
return await dataSource
.transaction(async (manager) => {
await manager
.createQueryBuilder()
.insert()
.into(inspectionVersionedPlan)
.values({
inspectionPlanId: createInspectionVersionedPlan.inspectionPlanId,
version: count,
})
.execute()
.then((result) => {
returnId = result.identifiers[0].id;
});
await manager
.createQueryBuilder()
.insert()
.into(inspectionPoint)
.values(
inspectionPoints.map((ip) => ({
title: ip.title,
description: ip.description,
type: ip.type,
min: ip.min,
max: ip.max,
others: ip.others,
sort: ip.sort,
versionedPlanId: returnId,
}))
)
.execute();
})
.then(() => {
return returnId;
})
.catch((err) => {
throw new DatabaseActionException("CREATE", "inspectionVersionedPlan", err);
});
}
}

View file

@ -0,0 +1,16 @@
export interface CreateMaintenanceCommand {
description: string;
affectedId: string;
affected: "equipment" | "vehicle" | "wearable";
}
export interface UpdateMaintenanceCommand {
id: string;
status: string;
done: boolean;
description: string;
}
export interface DeleteMaintenanceCommand {
id: string;
}

View file

@ -0,0 +1,72 @@
import { dataSource } from "../../data-source";
import { maintenance } from "../../entity/unit/maintenance";
import DatabaseActionException from "../../exceptions/databaseActionException";
import { CreateMaintenanceCommand, UpdateMaintenanceCommand, DeleteMaintenanceCommand } from "./maintenanceCommand";
export default abstract class MaintenanceCommandHandler {
/**
* @description create maintenance
* @param {CreateMaintenanceCommand} createMaintenance
* @returns {Promise<number>}
*/
static async create(createMaintenance: CreateMaintenanceCommand): Promise<number> {
return await dataSource
.createQueryBuilder()
.insert()
.into(maintenance)
.values({
status: "gestartet",
description: createMaintenance.description,
equipmentId: createMaintenance.affected == "equipment" ? createMaintenance.affectedId : null,
vehicleId: createMaintenance.affected == "vehicle" ? createMaintenance.affectedId : null,
wearableId: createMaintenance.affected == "wearable" ? createMaintenance.affectedId : null,
})
.execute()
.then((result) => {
return result.identifiers[0].id;
})
.catch((err) => {
throw new DatabaseActionException("CREATE", "maintenance", err);
});
}
/**
* @description update maintenance
* @param {UpdateMaintenanceCommand} updateMaintenance
* @returns {Promise<void>}
*/
static async update(updateMaintenance: UpdateMaintenanceCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.update(maintenance)
.set({
status: updateMaintenance.status,
done: updateMaintenance.done,
description: updateMaintenance.description,
})
.where("id = :id", { id: updateMaintenance.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("UPDATE", "maintenance", err);
});
}
/**
* @description delete maintenance
* @param {DeleteMaintenanceCommand} deleteMaintenance
* @returns {Promise<void>}
*/
static async delete(deleteMaintenance: DeleteMaintenanceCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.delete()
.from(maintenance)
.where("id = :id", { id: deleteMaintenance.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("DELETE", "maintenance", err);
});
}
}

View file

@ -0,0 +1,20 @@
export interface CreateVehicleCommand {
code?: string;
name: string;
location: string;
commissioned: Date;
vehicleTypeId: string;
}
export interface UpdateVehicleCommand {
id: string;
code?: string;
name: string;
location: string;
commissioned: Date;
decommissioned?: Date;
}
export interface DeleteVehicleCommand {
id: string;
}

View file

@ -0,0 +1,73 @@
import { dataSource } from "../../../data-source";
import { vehicle } from "../../../entity/unit/vehicle/vehicle";
import DatabaseActionException from "../../../exceptions/databaseActionException";
import { CreateVehicleCommand, UpdateVehicleCommand, DeleteVehicleCommand } from "./vehicleCommand";
export default abstract class VehicleCommandHandler {
/**
* @description create vehicle
* @param {CreateVehicleCommand} createVehicle
* @returns {Promise<number>}
*/
static async create(createVehicle: CreateVehicleCommand): Promise<number> {
return await dataSource
.createQueryBuilder()
.insert()
.into(vehicle)
.values({
code: createVehicle.code,
name: createVehicle.name,
location: createVehicle.location,
commissioned: createVehicle.commissioned,
vehicleTypeId: createVehicle.vehicleTypeId,
})
.execute()
.then((result) => {
return result.identifiers[0].id;
})
.catch((err) => {
throw new DatabaseActionException("CREATE", "vehicle", err);
});
}
/**
* @description update vehicle
* @param {UpdateVehicleCommand} updateVehicle
* @returns {Promise<void>}
*/
static async update(updateVehicle: UpdateVehicleCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.update(vehicle)
.set({
code: updateVehicle.code,
name: updateVehicle.name,
location: updateVehicle.location,
commissioned: updateVehicle.commissioned,
})
.where("id = :id", { id: updateVehicle.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("UPDATE", "vehicle", err);
});
}
/**
* @description delete vehicle
* @param {DeleteVehicleCommand} deleteVehicle
* @returns {Promise<void>}
*/
static async delete(deleteVehicle: DeleteVehicleCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.delete()
.from(vehicle)
.where("id = :id", { id: deleteVehicle.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("DELETE", "vehicle", err);
});
}
}

View file

@ -0,0 +1,14 @@
export interface CreateVehicleTypeCommand {
type: string;
description: string;
}
export interface UpdateVehicleTypeCommand {
id: string;
type: string;
description: string;
}
export interface DeleteVehicleTypeCommand {
id: string;
}

View file

@ -0,0 +1,68 @@
import { dataSource } from "../../../data-source";
import { vehicleType } from "../../../entity/unit/vehicle/vehicleType";
import DatabaseActionException from "../../../exceptions/databaseActionException";
import { CreateVehicleTypeCommand, UpdateVehicleTypeCommand, DeleteVehicleTypeCommand } from "./vehicleTypeCommand";
export default abstract class VehicleTypeCommandHandler {
/**
* @description create vehicleType
* @param {CreateVehicleTypeCommand} createVehicleType
* @returns {Promise<number>}
*/
static async create(createVehicleType: CreateVehicleTypeCommand): Promise<number> {
return await dataSource
.createQueryBuilder()
.insert()
.into(vehicleType)
.values({
type: createVehicleType.type,
description: createVehicleType.description,
})
.execute()
.then((result) => {
return result.identifiers[0].id;
})
.catch((err) => {
throw new DatabaseActionException("CREATE", "vehicleType", err);
});
}
/**
* @description update vehicleType
* @param {UpdateVehicleTypeCommand} updateVehicleType
* @returns {Promise<void>}
*/
static async update(updateVehicleType: UpdateVehicleTypeCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.update(vehicleType)
.set({
type: updateVehicleType.type,
description: updateVehicleType.description,
})
.where("id = :id", { id: updateVehicleType.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("UPDATE", "vehicleType", err);
});
}
/**
* @description delete vehicleType
* @param {DeleteVehicleTypeCommand} deleteVehicleType
* @returns {Promise<void>}
*/
static async delete(deleteVehicleType: DeleteVehicleTypeCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.delete()
.from(vehicleType)
.where("id = :id", { id: deleteVehicleType.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("DELETE", "vehicleType", err);
});
}
}

View file

@ -0,0 +1,22 @@
export interface CreateWearableCommand {
code?: string;
name: string;
location: string;
commissioned: Date;
wearableTypeId: string;
wearerId?: string;
}
export interface UpdateWearableCommand {
id: string;
code?: string;
name: string;
location: string;
commissioned: Date;
decommissioned?: Date;
wearerId?: string;
}
export interface DeleteWearableCommand {
id: string;
}

View file

@ -0,0 +1,76 @@
import { dataSource } from "../../../data-source";
import { wearable } from "../../../entity/unit/wearable/wearable";
import DatabaseActionException from "../../../exceptions/databaseActionException";
import { CreateWearableCommand, UpdateWearableCommand, DeleteWearableCommand } from "./wearableCommand";
export default abstract class WearableCommandHandler {
/**
* @description create wearable
* @param {CreateWearableCommand} createWearable
* @returns {Promise<number>}
*/
static async create(createWearable: CreateWearableCommand): Promise<number> {
return await dataSource
.createQueryBuilder()
.insert()
.into(wearable)
.values({
code: createWearable.code,
name: createWearable.name,
location: createWearable.location,
commissioned: createWearable.commissioned,
wearableTypeId: createWearable.wearableTypeId,
wearerId: createWearable.wearerId,
})
.execute()
.then((result) => {
return result.identifiers[0].id;
})
.catch((err) => {
throw new DatabaseActionException("CREATE", "wearable", err);
});
}
/**
* @description update wearable
* @param {UpdateWearableCommand} updateWearable
* @returns {Promise<void>}
*/
static async update(updateWearable: UpdateWearableCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.update(wearable)
.set({
code: updateWearable.code,
name: updateWearable.name,
location: updateWearable.location,
commissioned: updateWearable.commissioned,
decommissioned: updateWearable.decommissioned,
wearerId: updateWearable.wearerId,
})
.where("id = :id", { id: updateWearable.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("UPDATE", "wearable", err);
});
}
/**
* @description delete wearable
* @param {DeleteWearableCommand} deleteWearable
* @returns {Promise<void>}
*/
static async delete(deleteWearable: DeleteWearableCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.delete()
.from(wearable)
.where("id = :id", { id: deleteWearable.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("DELETE", "wearable", err);
});
}
}

View file

@ -0,0 +1,14 @@
export interface CreateWearableTypeCommand {
type: string;
description: string;
}
export interface UpdateWearableTypeCommand {
id: string;
type: string;
description: string;
}
export interface DeleteWearableTypeCommand {
id: string;
}

View file

@ -0,0 +1,68 @@
import { dataSource } from "../../../data-source";
import { wearableType } from "../../../entity/unit/wearable/wearableType";
import DatabaseActionException from "../../../exceptions/databaseActionException";
import { CreateWearableTypeCommand, UpdateWearableTypeCommand, DeleteWearableTypeCommand } from "./wearableTypeCommand";
export default abstract class WearableTypeCommandHandler {
/**
* @description create wearableType
* @param {CreateWearableTypeCommand} createWearableType
* @returns {Promise<number>}
*/
static async create(createWearableType: CreateWearableTypeCommand): Promise<number> {
return await dataSource
.createQueryBuilder()
.insert()
.into(wearableType)
.values({
type: createWearableType.type,
description: createWearableType.description,
})
.execute()
.then((result) => {
return result.identifiers[0].id;
})
.catch((err) => {
throw new DatabaseActionException("CREATE", "wearableType", err);
});
}
/**
* @description update wearableType
* @param {UpdateWearableTypeCommand} updateWearableType
* @returns {Promise<void>}
*/
static async update(updateWearableType: UpdateWearableTypeCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.update(wearableType)
.set({
type: updateWearableType.type,
description: updateWearableType.description,
})
.where("id = :id", { id: updateWearableType.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("UPDATE", "wearableType", err);
});
}
/**
* @description delete wearableType
* @param {DeleteWearableTypeCommand} deleteWearableType
* @returns {Promise<void>}
*/
static async delete(deleteWearableType: DeleteWearableTypeCommand): Promise<void> {
return await dataSource
.createQueryBuilder()
.delete()
.from(wearableType)
.where("id = :id", { id: deleteWearableType.id })
.execute()
.then(() => {})
.catch((err) => {
throw new DatabaseActionException("DELETE", "wearableType", err);
});
}
}

View file

@ -0,0 +1,120 @@
import { Request, Response } from "express";
import DamageReportService from "../../../service/unit/damageReportService";
import DamageReportFactory from "../../../factory/admin/unit/damageReport";
import { CreateDamageReportCommand, UpdateDamageReportCommand } from "../../../command/unit/damageReportCommand";
import DamageReportCommandHandler from "../../../command/unit/damageReportCommandHandler";
import BadRequestException from "../../../exceptions/badRequestException";
/**
* @description get all damageReports by status
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllDamageReportsByStatus(req: Request, res: Response): Promise<any> {
let done = req.query.done === "true";
let offset = parseInt((req.query.offset as string) ?? "0");
let count = parseInt((req.query.count as string) ?? "25");
let noLimit = req.query.noLimit === "true";
let [damageReports, total] = await DamageReportService.getAll(done, { offset, count, noLimit });
res.json({
damageReports: DamageReportFactory.mapToBase(damageReports),
total: total,
offset: offset,
count: count,
});
}
/**
* @description get all damageReports for related id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllDamageReportsForRelated(req: Request, res: Response): Promise<any> {
let relation = req.params.related as "vehicle" | "equipment" | "wearable";
let relationId = req.params.relatedId as string;
let offset = parseInt((req.query.offset as string) ?? "0");
let count = parseInt((req.query.count as string) ?? "25");
let noLimit = req.query.noLimit === "true";
let where;
if (relation == "equipment") {
where = { equipmentId: relationId };
} else if (relation == "vehicle") {
where = { vehicleId: relationId };
} else {
where = { wearableId: relationId };
}
let [damageReports, total] = await DamageReportService.getAllForRelated(where, { offset, count, noLimit });
res.json({
damageReports: DamageReportFactory.mapToBase(damageReports),
total: total,
offset: offset,
count: count,
});
}
/**
* @description get damageReport by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getDamageReportById(req: Request, res: Response): Promise<any> {
const damageReportId = req.params.id;
let damageReport = await DamageReportService.getById(damageReportId);
res.json(DamageReportFactory.mapToSingle(damageReport));
}
/**
* @description create damageReport
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function createDamageReport(req: Request, res: Response): Promise<any> {
const description = req.body.description;
const reportedBy = req.body.reportedBy;
const affectedId = req.body.affectedId;
const affected = req.body.affected;
if (affected != "equipment" && affected != "vehicle" && affected != "wearable")
throw new BadRequestException("set assigned to equipment or vehicle or wearable");
let createDamageReport: CreateDamageReportCommand = {
description,
reportedBy,
imageCount: 0,
affectedId,
affected,
};
let damageReportId = await DamageReportCommandHandler.create(createDamageReport);
res.status(200).send(damageReportId);
}
/**
* @description update damageReport by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function updateDamageReportById(req: Request, res: Response): Promise<any> {
const damageReportId = req.params.id;
const status = req.body.status;
const done = req.body.done;
let updateDamageReport: UpdateDamageReportCommand = {
id: damageReportId,
status,
done,
};
await DamageReportCommandHandler.update(updateDamageReport);
res.sendStatus(204);
}

View file

@ -0,0 +1,133 @@
import { Request, Response } from "express";
import EquipmentService from "../../../service/unit/equipment/equipmentService";
import EquipmentFactory from "../../../factory/admin/unit/equipment/equipment";
import {
CreateEquipmentCommand,
DeleteEquipmentCommand,
UpdateEquipmentCommand,
} from "../../../command/unit/equipment/equipmentCommand";
import EquipmentCommandHandler from "../../../command/unit/equipment/equipmentCommandHandler";
/**
* @description get all equipments
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllEquipments(req: Request, res: Response): Promise<any> {
let offset = parseInt((req.query.offset as string) ?? "0");
let count = parseInt((req.query.count as string) ?? "25");
let search = (req.query.search as string) ?? "";
let noLimit = req.query.noLimit === "true";
let ids = ((req.query.ids ?? "") as string).split(",").filter((i) => i);
let [equipments, total] = await EquipmentService.getAll({ offset, count, search, noLimit, ids });
res.json({
equipments: EquipmentFactory.mapToBase(equipments),
total: total,
offset: offset,
count: count,
});
}
/**
* @description get equipment by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getEquipmentById(req: Request, res: Response): Promise<any> {
const equipmentId = req.params.id;
let equipment = await EquipmentService.getById(equipmentId);
res.json(EquipmentFactory.mapToSingle(equipment));
}
/**
* @description get equipment by Ids
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getEquipmentsByIds(req: Request, res: Response): Promise<any> {
let ids = req.body.ids as Array<string>;
let [equipments, total] = await EquipmentService.getAll({ noLimit: true, ids });
res.json({
equipments: EquipmentFactory.mapToBase(equipments),
total: total,
offset: 0,
count: total,
});
}
/**
* @description create equipment
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function createEquipment(req: Request, res: Response): Promise<any> {
const name = req.body.name;
const code = req.body.code || null;
const location = req.body.location;
const commissioned = req.body.commissioned;
const equipmentTypeId = req.body.equipmentTypeId;
let createEquipment: CreateEquipmentCommand = {
code,
name,
location,
commissioned,
equipmentTypeId,
};
let equipmentId = await EquipmentCommandHandler.create(createEquipment);
res.status(200).send(equipmentId);
}
/**
* @description update equipment by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function updateEquipmentById(req: Request, res: Response): Promise<any> {
const equipmentId = req.params.id;
const name = req.body.name;
const code = req.body.code || null;
const location = req.body.location;
const commissioned = req.body.commissioned;
const decommissioned = req.body.decommissioned || null;
let updateEquipment: UpdateEquipmentCommand = {
id: equipmentId,
name,
code,
location,
commissioned,
decommissioned,
};
await EquipmentCommandHandler.update(updateEquipment);
res.sendStatus(204);
}
/**
* @description delete equipment by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function deleteEquipmentById(req: Request, res: Response): Promise<any> {
const equipmentId = req.params.id;
let deleteEquipment: DeleteEquipmentCommand = {
id: equipmentId,
};
await EquipmentCommandHandler.delete(deleteEquipment);
res.sendStatus(204);
}

View file

@ -0,0 +1,101 @@
import { Request, Response } from "express";
import EquipmentTypeService from "../../../service/unit/equipment/equipmentTypeService";
import EquipmentTypeFactory from "../../../factory/admin/unit/equipment/equipmentType";
import {
CreateEquipmentTypeCommand,
DeleteEquipmentTypeCommand,
UpdateEquipmentTypeCommand,
} from "../../../command/unit/equipment/equipmentTypeCommand";
import EquipmentTypeCommandHandler from "../../../command/unit/equipment/equipmentTypeCommandHandler";
/**
* @description get all equipmentTypes
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllEquipmentTypes(req: Request, res: Response): Promise<any> {
let offset = parseInt((req.query.offset as string) ?? "0");
let count = parseInt((req.query.count as string) ?? "25");
let search = (req.query.search as string) ?? "";
let noLimit = req.query.noLimit === "true";
let [equipmentTypes, total] = await EquipmentTypeService.getAll({ offset, count, search, noLimit });
res.json({
equipmentTypes: EquipmentTypeFactory.mapToBase(equipmentTypes),
total: total,
offset: offset,
count: count,
});
}
/**
* @description get equipmentType by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getEquipmentTypeById(req: Request, res: Response): Promise<any> {
const equipmentTypeId = req.params.id;
let equipmentType = await EquipmentTypeService.getById(equipmentTypeId);
res.json(EquipmentTypeFactory.mapToSingle(equipmentType));
}
/**
* @description create equipmentType
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function createEquipmentType(req: Request, res: Response): Promise<any> {
const type = req.body.type;
const description = req.body.description;
let createEquipmentType: CreateEquipmentTypeCommand = {
type,
description,
};
let equipmentTypeId = await EquipmentTypeCommandHandler.create(createEquipmentType);
res.status(200).send(equipmentTypeId);
}
/**
* @description update equipmentType by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function updateEquipmentTypeById(req: Request, res: Response): Promise<any> {
const equipmentTypeId = req.params.id;
const type = req.body.type;
const description = req.body.description;
let updateEquipmentType: UpdateEquipmentTypeCommand = {
id: equipmentTypeId,
type,
description,
};
await EquipmentTypeCommandHandler.update(updateEquipmentType);
res.sendStatus(204);
}
/**
* @description delete equipmentType by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function deleteEquipmentTypeById(req: Request, res: Response): Promise<any> {
const equipmentTypeId = req.params.id;
let deleteEquipmentType: DeleteEquipmentTypeCommand = {
id: equipmentTypeId,
};
await EquipmentTypeCommandHandler.delete(deleteEquipmentType);
res.sendStatus(204);
}

View file

@ -0,0 +1,392 @@
import { Request, Response } from "express";
import InspectionService from "../../../service/unit/inspection/inspectionService";
import InspectionFactory from "../../../factory/admin/unit/inspection/inspection";
import {
CreateInspectionCommand,
DeleteInspectionCommand,
FinishInspectionCommand,
UpdateInspectionCommand,
} from "../../../command/unit/inspection/inspectionCommand";
import InspectionCommandHandler from "../../../command/unit/inspection/inspectionCommandHandler";
import BadRequestException from "../../../exceptions/badRequestException";
import ForbiddenRequestException from "../../../exceptions/forbiddenRequestException";
import { CreateOrUpdateInspectionPointResultCommand } from "../../../command/unit/inspection/inspectionPointResultCommand";
import InspectionPointResultCommandHandler from "../../../command/unit/inspection/inspectionPointResultCommandHandler";
import { InspectionPointEnum } from "../../../enums/inspectionEnum";
import multer from "multer";
import { FileSystemHelper } from "../../../helpers/fileSystemHelper";
import { PdfExport } from "../../../helpers/pdfExport";
import { PDFDocument } from "pdf-lib";
import sharp from "sharp";
import InspectionPointService from "../../../service/unit/inspection/inspectionPointService";
import InspectionPointResultService from "../../../service/unit/inspection/inspectionPointResultService";
/**
* @description get all inspections sorted by id not having newer inspection
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllInspectionsSortedNotHavingNewer(req: Request, res: Response): Promise<any> {
let offset = parseInt((req.query.offset as string) ?? "0");
let count = parseInt((req.query.count as string) ?? "25");
let noLimit = req.query.noLimit === "true";
let [inspections, total] = await InspectionService.getAllSortedNotHavingNewer({ offset, count, noLimit });
res.json({
inspections: InspectionFactory.mapToBaseNext(inspections),
total: total,
offset: offset,
count: count,
});
}
/**
* @description get all inspections running
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllInspectionsRunning(req: Request, res: Response): Promise<any> {
let offset = parseInt((req.query.offset as string) ?? "0");
let count = parseInt((req.query.count as string) ?? "25");
let noLimit = req.query.noLimit === "true";
let [inspections, total] = await InspectionService.getAllRunning({ offset, count, noLimit });
res.json({
inspections: InspectionFactory.mapToBaseMinified(inspections),
total: total,
offset: offset,
count: count,
});
}
/**
* @description get all inspections for related id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllInspectionsForRelated(req: Request, res: Response): Promise<any> {
let relation = req.params.related as "vehicle" | "equipment" | "wearable";
let relationId = req.params.relatedId as string;
let offset = parseInt((req.query.offset as string) ?? "0");
let count = parseInt((req.query.count as string) ?? "25");
let noLimit = req.query.noLimit === "true";
let where;
if (relation == "equipment") {
where = { equipmentId: relationId };
} else if (relation == "vehicle") {
where = { vehicleId: relationId };
} else {
where = { wearableId: relationId };
}
let [inspections, total] = await InspectionService.getAllForRelated(where, { offset, count, noLimit });
res.json({
inspections: InspectionFactory.mapToBaseMinified(inspections),
total: total,
offset: offset,
count: count,
});
}
/**
* @description get inspection by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getInspectionPrintoutById(req: Request, res: Response): Promise<any> {
const inspectionId = req.params.id;
let inspection = await InspectionService.getById(inspectionId);
if (inspection.finishedAt == null)
throw new ForbiddenRequestException("this inspection has not been finished yet and it so does not have a printout");
let filepath = FileSystemHelper.formatPath("inspection", inspection.id, "printout.pdf");
res.sendFile(filepath, {
headers: {
"Content-Type": "application/pdf",
},
});
}
/**
* @description get inspection by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getInspectionPointUpload(req: Request, res: Response): Promise<any> {
const inspectionId = req.params.id;
const inspectionPointId = req.params.pointId;
let result = await InspectionPointResultService.getForInspectionAndPoint(inspectionId, inspectionPointId);
let filepath = FileSystemHelper.formatPath("inspection", inspectionId, result.value);
if (result.inspectionPoint.others === "pdf") {
res.sendFile(filepath, {
headers: {
"Content-Type": "application/pdf",
},
});
} else {
let image = await sharp(filepath).png().toBuffer();
res.set({
"Content-Type": "image/png",
});
res.send(image);
}
}
/**
* @description get inspection by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getInspectionById(req: Request, res: Response): Promise<any> {
const inspectionId = req.params.id;
let inspection = await InspectionService.getById(inspectionId);
res.json(InspectionFactory.mapToSingle(inspection));
}
/**
* @description create inspection
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function createInspection(req: Request, res: Response): Promise<any> {
const context = req.body.context;
const inspectionPlanId = req.body.inspectionPlanId;
const relatedId = req.body.relatedId;
const assigned = req.body.assigned;
const nextInspection = req.body.nextInspection || null;
if (assigned != "equipment" && assigned != "vehicle" && assigned != "wearable")
throw new BadRequestException("set assigned to equipment or vehicle or wearable");
let existsUnfinished = await InspectionService.existsUnfinishedInspectionToPlan(
inspectionPlanId,
assigned,
relatedId
);
if (existsUnfinished) throw new ForbiddenRequestException("there is already an unfinished inspection existing");
let createInspection: CreateInspectionCommand = {
context,
nextInspection,
inspectionPlanId,
relatedId,
assigned,
};
let inspectionId = await InspectionCommandHandler.create(createInspection);
res.status(200).send(inspectionId);
}
/**
* @description update inspection by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function updateInspectionById(req: Request, res: Response): Promise<any> {
const inspectionId = req.params.id;
const context = req.body.context;
const nextInspection = req.body.nextInspection || null;
let updateInspection: UpdateInspectionCommand = {
id: inspectionId,
context,
nextInspection,
};
await InspectionCommandHandler.update(updateInspection);
res.sendStatus(204);
}
/**
* @description update inspection by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function updateInspectionResults(req: Request, res: Response): Promise<any> {
const inspectionId = req.params.id;
const pointResults = JSON.parse(req.body.results) as Array<{ inspectionPointId: string; value: string }>;
const pointFiles = req.files as Array<Express.Multer.File>;
let inspection = await InspectionService.getById(inspectionId);
let updateResults: Array<CreateOrUpdateInspectionPointResultCommand> = pointResults.map((pr) => ({
inspectionPointId: pr.inspectionPointId,
value:
inspection.inspectionVersionedPlan.inspectionPoints.find((ip) => ip.id == pr.inspectionPointId).type ==
InspectionPointEnum.file && pr.value == "set"
? pointFiles.find((f) => f.filename.startsWith(pr.inspectionPointId))?.filename
: pr.value,
inspectionId,
}));
await InspectionPointResultCommandHandler.createOrUpdateMultiple(updateResults);
res.sendStatus(204);
}
/**
* @description finish inspection by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function finishInspection(req: Request, res: Response): Promise<any> {
const inspectionId = req.params.id;
let inspection = await InspectionService.getById(inspectionId);
function getValueToInspectionPoint(inspectionPointId: string) {
return inspection.pointResults.find((c) => c.inspectionPointId == inspectionPointId)?.value;
}
let everythingFilled = inspection.inspectionVersionedPlan.inspectionPoints.every((p) => {
if (p.type == InspectionPointEnum.file) {
return getValueToInspectionPoint(p.id);
} else if (p.type == InspectionPointEnum.oknok) {
let value = getValueToInspectionPoint(p.id);
return (["true", "false"].includes(value) ? (value as "true" | "false") : "") != "";
} else {
return !!getValueToInspectionPoint(p.id);
}
});
if (!everythingFilled) throw new ForbiddenRequestException("fill out every field before finishing inspection");
let formattedInspection = InspectionFactory.mapToSingle(inspection);
let title = `Prüf-Ausdruck_${[formattedInspection.related.code ?? "", formattedInspection.related.name].join("_")}_${
formattedInspection.inspectionPlan.title
}_${new Date(formattedInspection.finished ?? "").toLocaleDateString("de-de")}`;
let inspectionPoints = [];
for (const ip of formattedInspection.inspectionVersionedPlan.inspectionPoints.sort(
(a, b) => (a.sort ?? 0) - (b.sort ?? 0)
)) {
let value = formattedInspection.checks.find((c) => c.inspectionPointId == ip.id).value;
let image = "";
if (ip.type == InspectionPointEnum.file && ip.others == "img") {
const imagePath = FileSystemHelper.formatPath("inspection", inspection.id, value);
let pngImageBytes = await sharp(imagePath).png().toBuffer();
image = `data:image/png;base64,${pngImageBytes.toString("base64")}`;
} else if (ip.type == InspectionPointEnum.oknok) {
value = value ? "OK" : "Nicht OK";
}
inspectionPoints.push({
title: ip.title,
description: ip.description,
type: ip.type,
min: ip.min,
max: ip.max,
others: ip.others,
value: value,
image: image,
});
}
let pdf = await PdfExport.renderFile({
template: "inspection",
title,
saveToDisk: false,
data: {
inspector: `${req.lastname}, ${req.firstname}`,
context: formattedInspection.context || "---",
createdAt: formattedInspection.created,
finishedAt: formattedInspection.finished ?? new Date(),
nextInspection: formattedInspection.nextInspection,
related: formattedInspection.related,
plan: formattedInspection.inspectionPlan,
planVersion: formattedInspection.inspectionVersionedPlan.version,
planTitle: formattedInspection.inspectionPlan.title,
checks: inspectionPoints,
},
});
const finalDocument = await PDFDocument.create();
const printout = await PDFDocument.load(pdf);
const copiedPages = await finalDocument.copyPages(printout, printout.getPageIndices());
copiedPages.forEach((page) => finalDocument.addPage(page));
let resultsForAppend = inspectionPoints.filter((ip) => ip.type == InspectionPointEnum.file && ip.others == "pdf");
if (resultsForAppend.length !== 0) {
const appendixPage = finalDocument.addPage();
const { width, height } = appendixPage.getSize();
appendixPage.drawText("Anhang:", {
x: 50,
y: height - 50,
size: 24,
});
}
for (const appendix of resultsForAppend) {
const appendixPdfBytes = FileSystemHelper.readFileAsBase64("inspection", inspection.id, appendix.value);
const appendixPdf = await PDFDocument.load(appendixPdfBytes);
const appendixPages = await finalDocument.copyPages(appendixPdf, appendixPdf.getPageIndices());
appendixPages.forEach((page) => finalDocument.addPage(page));
/** print image
const imagePath = FileSystemHelper.formatPath("inspection", inspection.id, checkValue);
let pngImageBytes = await sharp(imagePath).png().toBuffer();
let image = await finalDocument.embedPng(pngImageBytes);
let dims = image.scale(1);
if (image) {
const page = finalDocument.addPage();
const { width, height } = page.getSize();
const x = (width - dims.width) / 2;
const y = (height - dims.height) / 2;
page.drawImage(image, {
x,
y,
width: dims.width,
height: dims.height,
});
}
*/
}
const mergedPdfBytes = await finalDocument.save();
FileSystemHelper.writeFile(`inspection/${inspection.id}`, `printout.pdf`, mergedPdfBytes);
let finish: FinishInspectionCommand = {
id: inspectionId,
};
await InspectionCommandHandler.finish(finish);
res.sendStatus(204);
}
/**
* @description delete inspection by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function deleteInspectionById(req: Request, res: Response): Promise<any> {
const inspectionId = req.params.id;
let deleteInspectionData = await InspectionService.getById(inspectionId);
if (deleteInspectionData.finishedAt != null) {
throw new ForbiddenRequestException("Cannot delete as inspection is already finished");
}
let deleteInspection: DeleteInspectionCommand = {
id: inspectionId,
};
await InspectionCommandHandler.delete(deleteInspection);
res.sendStatus(204);
}

View file

@ -0,0 +1,214 @@
import { Request, Response } from "express";
import InspectionPlanService from "../../../service/unit/inspection/inspectionPlanService";
import InspectionPlanFactory from "../../../factory/admin/unit/inspection/inspectionPlan";
import {
CreateInspectionPlanCommand,
DeleteInspectionPlanCommand,
UpdateInspectionPlanCommand,
} from "../../../command/unit/inspection/inspectionPlanCommand";
import InspectionPlanCommandHandler from "../../../command/unit/inspection/inspectionPlanCommandHandler";
import BadRequestException from "../../../exceptions/badRequestException";
import TypeTester from "../../../helpers/typeTester";
import InspectionPointService from "../../../service/unit/inspection/inspectionPointService";
import InspectionPointFactory from "../../../factory/admin/unit/inspection/inspectionPoint";
import InspectionService from "../../../service/unit/inspection/inspectionService";
import InspectionVersionedPlanCommandHandler from "../../../command/unit/inspection/inspectionVersionedPlanCommandHandler";
import InspectionPointCommandHandler from "../../../command/unit/inspection/inspectionPointCommandHandler";
/**
* @description get all inspectionPlans
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllInspectionPlans(req: Request, res: Response): Promise<any> {
let offset = parseInt((req.query.offset as string) ?? "0");
let count = parseInt((req.query.count as string) ?? "25");
let search = (req.query.search as string) ?? "";
let noLimit = req.query.noLimit === "true";
let ids = ((req.query.ids ?? "") as string).split(",").filter((i) => i);
let [inspectionPlans, total] = await InspectionPlanService.getAll({
offset,
count,
search,
noLimit,
ids,
});
res.json({
inspectionPlans: InspectionPlanFactory.mapToBase(inspectionPlans),
total: total,
offset: offset,
count: count,
});
}
/**
* @description get all inspectionPlans
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllInspectionPlansForRelated(req: Request, res: Response): Promise<any> {
let relation = req.params.related as "vehicleType" | "equipmentType" | "wearableType";
let relationTypeId = req.params.relatedTypeId as string;
let offset = parseInt((req.query.offset as string) ?? "0");
let count = parseInt((req.query.count as string) ?? "25");
let search = (req.query.search as string) ?? "";
let noLimit = req.query.noLimit === "true";
let ids = ((req.query.ids ?? "") as string).split(",").filter((i) => i);
let where;
if (relation == "equipmentType") {
where = { equipmentTypeId: relationTypeId };
} else if (relation == "vehicleType") {
where = { vehicleTypeId: relationTypeId };
} else {
where = { wearableTypeId: relationTypeId };
}
let [inspectionPlans, total] = await InspectionPlanService.getAllForRelated(where, {
offset,
count,
search,
noLimit,
ids,
});
res.json({
inspectionPlans: inspectionPlans,
total: total,
offset: offset,
count: count,
});
}
/**
* @description get inspectionPoints by planid
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getInspectionPointsByPlanId(req: Request, res: Response): Promise<any> {
const inspectionPlanId = req.params.id;
let inspectionPlan = await InspectionPlanService.getById(inspectionPlanId);
if (!inspectionPlan.latestVersionedPlan) {
res.json([]);
} else {
let inspectionPoints = await InspectionPointService.getAllForVersionedPlan(inspectionPlan.latestVersionedPlan.id);
res.json(InspectionPointFactory.mapToBase(inspectionPoints));
}
}
/**
* @description get inspectionPlan by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getInspectionPlanById(req: Request, res: Response): Promise<any> {
const inspectionPlanId = req.params.id;
let inspectionPlan = await InspectionPlanService.getById(inspectionPlanId);
res.json(InspectionPlanFactory.mapToSingle(inspectionPlan));
}
/**
* @description create inspectionPlan
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function createInspectionPlan(req: Request, res: Response): Promise<any> {
const title = req.body.title;
const inspectionInterval = req.body.inspectionInterval;
const remindTime = req.body.remindTime;
const relatedId = req.body.relatedId;
const assigned = req.body.assigned;
TypeTester.testPlanTimeDefinition(inspectionInterval, "inspectionInterval", true);
TypeTester.testPlanTimeDefinition(remindTime, "remindTime", true);
if (assigned != "equipment" && assigned != "vehicle" && assigned != "wearable")
throw new BadRequestException("set assigned to equipment or vehicle or wearable");
let createInspectionPlan: CreateInspectionPlanCommand = {
title,
inspectionInterval,
remindTime,
relatedId,
assigned,
};
let inspectionPlanId = await InspectionPlanCommandHandler.create(createInspectionPlan);
res.status(200).send(inspectionPlanId);
}
/**
* @description update inspectionPlan by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function updateInspectionPlanById(req: Request, res: Response): Promise<any> {
const inspectionPlanId = req.params.id;
const title = req.body.title;
const inspectionInterval = req.body.inspectionInterval;
const remindTime = req.body.remindTime;
TypeTester.testPlanTimeDefinition(inspectionInterval, "inspectionInterval", true);
TypeTester.testPlanTimeDefinition(remindTime, "remindTime", true);
let updateInspectionPlan: UpdateInspectionPlanCommand = {
id: inspectionPlanId,
title,
inspectionInterval,
remindTime,
};
await InspectionPlanCommandHandler.update(updateInspectionPlan);
res.sendStatus(204);
}
/**
* @description get inspectionPoints by planid
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function updateInspectionPointsByPlanId(req: Request, res: Response): Promise<any> {
const inspectionPlanId = req.params.id;
const inspectionPoints = req.body;
let inspectionPlan = await InspectionPlanService.getById(inspectionPlanId);
let usedVersionedPlan = inspectionPlan?.latestVersionedPlan?.id
? await InspectionService.usesVersionedInspectionPlan(inspectionPlan.latestVersionedPlan.id)
: true;
if (usedVersionedPlan) {
await InspectionVersionedPlanCommandHandler.create({ inspectionPlanId }, inspectionPoints);
} else {
await InspectionPointCommandHandler.sync(inspectionPlan.latestVersionedPlan.id, inspectionPoints);
}
res.sendStatus(204);
}
/**
* @description delete inspectionPlan by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function deleteInspectionPlanById(req: Request, res: Response): Promise<any> {
const inspectionPlanId = req.params.id;
let deleteInspectionPlan: DeleteInspectionPlanCommand = {
id: inspectionPlanId,
};
await InspectionPlanCommandHandler.delete(deleteInspectionPlan);
res.sendStatus(204);
}

View file

@ -0,0 +1,119 @@
import { Request, Response } from "express";
import MaintenanceService from "../../../service/unit/maintenanceService";
import MaintenanceFactory from "../../../factory/admin/unit/maintenance";
import { CreateMaintenanceCommand, UpdateMaintenanceCommand } from "../../../command/unit/maintenanceCommand";
import MaintenanceCommandHandler from "../../../command/unit/maintenanceCommandHandler";
import BadRequestException from "../../../exceptions/badRequestException";
/**
* @description get all maintenances by status
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllMaintenancesByStatus(req: Request, res: Response): Promise<any> {
let done = req.query.done === "true";
let offset = parseInt((req.query.offset as string) ?? "0");
let count = parseInt((req.query.count as string) ?? "25");
let noLimit = req.query.noLimit === "true";
let [maintenances, total] = await MaintenanceService.getAll(done, { offset, count, noLimit });
res.json({
maintenances: MaintenanceFactory.mapToBase(maintenances),
total: total,
offset: offset,
count: count,
});
}
/**
* @description get all maintenances for related id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllMaintenancesForRelated(req: Request, res: Response): Promise<any> {
let relation = req.params.related as "vehicle" | "equipment" | "wearable";
let relationId = req.params.relatedId as string;
let offset = parseInt((req.query.offset as string) ?? "0");
let count = parseInt((req.query.count as string) ?? "25");
let noLimit = req.query.noLimit === "true";
let where;
if (relation == "equipment") {
where = { equipmentId: relationId };
} else if (relation == "vehicle") {
where = { vehicleId: relationId };
} else {
where = { wearableId: relationId };
}
let [maintenances, total] = await MaintenanceService.getAllForRelated(where, { offset, count, noLimit });
res.json({
maintenances: MaintenanceFactory.mapToBase(maintenances),
total: total,
offset: offset,
count: count,
});
}
/**
* @description get maintenance by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getMaintenanceById(req: Request, res: Response): Promise<any> {
const maintenanceId = req.params.id;
let maintenance = await MaintenanceService.getById(maintenanceId);
res.json(MaintenanceFactory.mapToSingle(maintenance));
}
/**
* @description create maintenance
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function createMaintenance(req: Request, res: Response): Promise<any> {
const description = req.body.description;
const affectedId = req.body.affectedId;
const affected = req.body.affected;
if (affected != "equipment" && affected != "vehicle" && affected != "wearable")
throw new BadRequestException("set assigned to equipment or vehicle or wearable");
let createMaintenance: CreateMaintenanceCommand = {
description,
affectedId,
affected,
};
let maintenanceId = await MaintenanceCommandHandler.create(createMaintenance);
res.status(200).send(maintenanceId);
}
/**
* @description update maintenance by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function updateMaintenanceById(req: Request, res: Response): Promise<any> {
const maintenanceId = req.params.id;
const description = req.body.description;
const status = req.body.status;
const done = req.body.done;
let updateMaintenance: UpdateMaintenanceCommand = {
id: maintenanceId,
description,
status,
done,
};
await MaintenanceCommandHandler.update(updateMaintenance);
res.sendStatus(204);
}

View file

@ -0,0 +1,133 @@
import { Request, Response } from "express";
import VehicleService from "../../../service/unit/vehicle/vehicleService";
import VehicleFactory from "../../../factory/admin/unit/vehicle/vehicle";
import {
CreateVehicleCommand,
DeleteVehicleCommand,
UpdateVehicleCommand,
} from "../../../command/unit/vehicle/vehicleCommand";
import VehicleCommandHandler from "../../../command/unit/vehicle/vehicleCommandHandler";
/**
* @description get all vehicles
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllVehicles(req: Request, res: Response): Promise<any> {
let offset = parseInt((req.query.offset as string) ?? "0");
let count = parseInt((req.query.count as string) ?? "25");
let search = (req.query.search as string) ?? "";
let noLimit = req.query.noLimit === "true";
let ids = ((req.query.ids ?? "") as string).split(",").filter((i) => i);
let [vehicles, total] = await VehicleService.getAll({ offset, count, search, noLimit, ids });
res.json({
vehicles: VehicleFactory.mapToBase(vehicles),
total: total,
offset: offset,
count: count,
});
}
/**
* @description get vehicle by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getVehicleById(req: Request, res: Response): Promise<any> {
const vehicleId = req.params.id;
let vehicle = await VehicleService.getById(vehicleId);
res.json(VehicleFactory.mapToSingle(vehicle));
}
/**
* @description get vehicle by Ids
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getVehiclesByIds(req: Request, res: Response): Promise<any> {
let ids = req.body.ids as Array<string>;
let [vehicles, total] = await VehicleService.getAll({ noLimit: true, ids });
res.json({
vehicles: VehicleFactory.mapToBase(vehicles),
total: total,
offset: 0,
count: total,
});
}
/**
* @description create vehicle
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function createVehicle(req: Request, res: Response): Promise<any> {
const name = req.body.name;
const code = req.body.code || null;
const location = req.body.location;
const commissioned = req.body.commissioned;
const vehicleTypeId = req.body.vehicleTypeId;
let createVehicle: CreateVehicleCommand = {
code,
name,
location,
commissioned,
vehicleTypeId,
};
let vehicleId = await VehicleCommandHandler.create(createVehicle);
res.status(200).send(vehicleId);
}
/**
* @description update vehicle by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function updateVehicleById(req: Request, res: Response): Promise<any> {
const vehicleId = req.params.id;
const name = req.body.name;
const code = req.body.code || null;
const location = req.body.location;
const commissioned = req.body.commissioned;
const decommissioned = req.body.decommissioned || null;
let updateVehicle: UpdateVehicleCommand = {
id: vehicleId,
code,
name,
location,
commissioned,
decommissioned,
};
await VehicleCommandHandler.update(updateVehicle);
res.sendStatus(204);
}
/**
* @description delete vehicle by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function deleteVehicleById(req: Request, res: Response): Promise<any> {
const vehicleId = req.params.id;
let deleteVehicle: DeleteVehicleCommand = {
id: vehicleId,
};
await VehicleCommandHandler.delete(deleteVehicle);
res.sendStatus(204);
}

View file

@ -0,0 +1,101 @@
import { Request, Response } from "express";
import VehicleTypeService from "../../../service/unit/vehicle/vehicleTypeService";
import VehicleTypeFactory from "../../../factory/admin/unit/vehicle/vehicleType";
import {
CreateVehicleTypeCommand,
DeleteVehicleTypeCommand,
UpdateVehicleTypeCommand,
} from "../../../command/unit/vehicle/vehicleTypeCommand";
import VehicleTypeCommandHandler from "../../../command/unit/vehicle/vehicleTypeCommandHandler";
/**
* @description get all vehicleTypes
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllVehicleTypes(req: Request, res: Response): Promise<any> {
let offset = parseInt((req.query.offset as string) ?? "0");
let count = parseInt((req.query.count as string) ?? "25");
let search = (req.query.search as string) ?? "";
let noLimit = req.query.noLimit === "true";
let [vehicleTypes, total] = await VehicleTypeService.getAll({ offset, count, search, noLimit });
res.json({
vehicleTypes: VehicleTypeFactory.mapToBase(vehicleTypes),
total: total,
offset: offset,
count: count,
});
}
/**
* @description get vehicleType by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getVehicleTypeById(req: Request, res: Response): Promise<any> {
const vehicleTypeId = req.params.id;
let vehicleType = await VehicleTypeService.getById(vehicleTypeId);
res.json(VehicleTypeFactory.mapToSingle(vehicleType));
}
/**
* @description create vehicleType
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function createVehicleType(req: Request, res: Response): Promise<any> {
const type = req.body.type;
const description = req.body.description;
let createVehicleType: CreateVehicleTypeCommand = {
type,
description,
};
let vehicleTypeId = await VehicleTypeCommandHandler.create(createVehicleType);
res.status(200).send(vehicleTypeId);
}
/**
* @description update vehicleType by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function updateVehicleTypeById(req: Request, res: Response): Promise<any> {
const vehicleTypeId = req.params.id;
const type = req.body.type;
const description = req.body.description;
let updateVehicleType: UpdateVehicleTypeCommand = {
id: vehicleTypeId,
type,
description,
};
await VehicleTypeCommandHandler.update(updateVehicleType);
res.sendStatus(204);
}
/**
* @description delete vehicleType by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function deleteVehicleTypeById(req: Request, res: Response): Promise<any> {
const vehicleTypeId = req.params.id;
let deleteVehicleType: DeleteVehicleTypeCommand = {
id: vehicleTypeId,
};
await VehicleTypeCommandHandler.delete(deleteVehicleType);
res.sendStatus(204);
}

View file

@ -0,0 +1,137 @@
import { Request, Response } from "express";
import WearableService from "../../../service/unit/wearable/wearableService";
import WearableFactory from "../../../factory/admin/unit/wearable/wearable";
import {
CreateWearableCommand,
DeleteWearableCommand,
UpdateWearableCommand,
} from "../../../command/unit/wearable/wearableCommand";
import WearableCommandHandler from "../../../command/unit/wearable/wearableCommandHandler";
/**
* @description get all wearables
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllWearables(req: Request, res: Response): Promise<any> {
let offset = parseInt((req.query.offset as string) ?? "0");
let count = parseInt((req.query.count as string) ?? "25");
let search = (req.query.search as string) ?? "";
let noLimit = req.query.noLimit === "true";
let ids = ((req.query.ids ?? "") as string).split(",").filter((i) => i);
let [wearables, total] = await WearableService.getAll({ offset, count, search, noLimit, ids });
res.json({
wearables: WearableFactory.mapToBase(wearables),
total: total,
offset: offset,
count: count,
});
}
/**
* @description get wearable by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getWearableById(req: Request, res: Response): Promise<any> {
const wearableId = req.params.id;
let wearable = await WearableService.getById(wearableId);
res.json(WearableFactory.mapToSingle(wearable));
}
/**
* @description get wearable by Ids
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getWearablesByIds(req: Request, res: Response): Promise<any> {
let ids = req.body.ids as Array<string>;
let [wearables, total] = await WearableService.getAll({ noLimit: true, ids });
res.json({
wearables: WearableFactory.mapToBase(wearables),
total: total,
offset: 0,
count: total,
});
}
/**
* @description create wearable
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function createWearable(req: Request, res: Response): Promise<any> {
const name = req.body.name;
const code = req.body.code || null;
const location = req.body.location;
const commissioned = req.body.commissioned;
const wearableTypeId = req.body.wearableTypeId;
const wearerId = req.body.wearerId || null;
let createWearable: CreateWearableCommand = {
code,
name,
location,
commissioned,
wearableTypeId,
wearerId,
};
let wearableId = await WearableCommandHandler.create(createWearable);
res.status(200).send(wearableId);
}
/**
* @description update wearable by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function updateWearableById(req: Request, res: Response): Promise<any> {
const wearableId = req.params.id;
const name = req.body.name;
const code = req.body.code || null;
const location = req.body.location;
const commissioned = req.body.commissioned;
const decommissioned = req.body.decommissioned || null;
const wearerId = req.body.wearerId || null;
let updateWearable: UpdateWearableCommand = {
id: wearableId,
code,
name,
location,
commissioned,
decommissioned,
wearerId,
};
await WearableCommandHandler.update(updateWearable);
res.sendStatus(204);
}
/**
* @description delete wearable by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function deleteWearableById(req: Request, res: Response): Promise<any> {
const wearableId = req.params.id;
let deleteWearable: DeleteWearableCommand = {
id: wearableId,
};
await WearableCommandHandler.delete(deleteWearable);
res.sendStatus(204);
}

View file

@ -0,0 +1,101 @@
import { Request, Response } from "express";
import WearableTypeService from "../../../service/unit/wearable/wearableTypeService";
import WearableTypeFactory from "../../../factory/admin/unit/wearable/wearableType";
import {
CreateWearableTypeCommand,
DeleteWearableTypeCommand,
UpdateWearableTypeCommand,
} from "../../../command/unit/wearable/wearableTypeCommand";
import WearableTypeCommandHandler from "../../../command/unit/wearable/wearableTypeCommandHandler";
/**
* @description get all wearableTypes
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getAllWearableTypes(req: Request, res: Response): Promise<any> {
let offset = parseInt((req.query.offset as string) ?? "0");
let count = parseInt((req.query.count as string) ?? "25");
let search = (req.query.search as string) ?? "";
let noLimit = req.query.noLimit === "true";
let [wearableTypes, total] = await WearableTypeService.getAll({ offset, count, search, noLimit });
res.json({
wearableTypes: WearableTypeFactory.mapToBase(wearableTypes),
total: total,
offset: offset,
count: count,
});
}
/**
* @description get wearableType by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function getWearableTypeById(req: Request, res: Response): Promise<any> {
const wearableTypeId = req.params.id;
let wearableType = await WearableTypeService.getById(wearableTypeId);
res.json(WearableTypeFactory.mapToSingle(wearableType));
}
/**
* @description create wearableType
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function createWearableType(req: Request, res: Response): Promise<any> {
const type = req.body.type;
const description = req.body.description;
let createWearableType: CreateWearableTypeCommand = {
type,
description,
};
let wearableTypeId = await WearableTypeCommandHandler.create(createWearableType);
res.status(200).send(wearableTypeId);
}
/**
* @description update wearableType by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function updateWearableTypeById(req: Request, res: Response): Promise<any> {
const wearableTypeId = req.params.id;
const type = req.body.type;
const description = req.body.description;
let updateWearableType: UpdateWearableTypeCommand = {
id: wearableTypeId,
type,
description,
};
await WearableTypeCommandHandler.update(updateWearableType);
res.sendStatus(204);
}
/**
* @description delete wearableType by id
* @param req {Request} Express req object
* @param res {Response} Express res object
* @returns {Promise<*>}
*/
export async function deleteWearableTypeById(req: Request, res: Response): Promise<any> {
const wearableTypeId = req.params.id;
let deleteWearableType: DeleteWearableTypeCommand = {
id: wearableTypeId,
};
await WearableTypeCommandHandler.delete(deleteWearableType);
res.sendStatus(204);
}

View file

@ -20,6 +20,7 @@ import { member } from "./entity/club/member/member";
import { memberAwards } from "./entity/club/member/memberAwards";
import { memberExecutivePositions } from "./entity/club/member/memberExecutivePositions";
import { memberQualifications } from "./entity/club/member/memberQualifications";
import { memberEducations } from "./entity/club/member/memberEducations";
import { membership } from "./entity/club/member/membership";
import { protocol } from "./entity/club/protocol/protocol";
import { protocolAgenda } from "./entity/club/protocol/protocolAgenda";
@ -46,10 +47,24 @@ import { webapiPermission } from "./entity/management/webapi_permission";
import { salutation } from "./entity/configuration/salutation";
import { setting } from "./entity/management/setting";
import { education } from "./entity/configuration/education";
import { memberEducations } from "./entity/club/member/memberEducations";
import { equipmentType } from "./entity/unit/equipment/equipmentType";
import { equipment } from "./entity/unit/equipment/equipment";
import { vehicleType } from "./entity/unit/vehicle/vehicleType";
import { vehicle } from "./entity/unit/vehicle/vehicle";
import { wearableType } from "./entity/unit/wearable/wearableType";
import { wearable } from "./entity/unit/wearable/wearable";
import { damageReport } from "./entity/unit/damageReport";
import { inspectionPlan } from "./entity/unit/inspection/inspectionPlan";
import { inspectionVersionedPlan } from "./entity/unit/inspection/inspectionVersionedPlan";
import { inspectionPoint } from "./entity/unit/inspection/inspectionPoint";
import { inspection } from "./entity/unit/inspection/inspection";
import { inspectionPointResult } from "./entity/unit/inspection/inspectionPointResult";
import { maintenance } from "./entity/unit/maintenance";
import { BackupAndResetDatabase1749296262915 } from "./migrations/1749296262915-BackupAndResetDatabase";
import { CreateSchema1749296280721 } from "./migrations/1749296280721-CreateSchema";
import { UnitBase1749361405703 } from "./migrations/1749361405703-UnitBase";
configCheck();
@ -107,8 +122,21 @@ const dataSource = new DataSource({
webapi,
webapiPermission,
setting,
equipmentType,
equipment,
vehicleType,
vehicle,
wearableType,
wearable,
damageReport,
maintenance,
inspectionPlan,
inspectionVersionedPlan,
inspectionPoint,
inspection,
inspectionPointResult,
],
migrations: [BackupAndResetDatabase1749296262915, CreateSchema1749296280721],
migrations: [BackupAndResetDatabase1749296262915, CreateSchema1749296280721, UnitBase1749361405703],
migrationsRun: true,
migrationsTransactionMode: "each",
subscribers: [],

View file

@ -0,0 +1,69 @@
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 {
@PrimaryGeneratedColumn("uuid")
id: string;
@CreateDateColumn()
reportedAt: Date;
@Column({ type: "varchar", length: 255 })
status: string;
@Column({ type: "boolean", default: false })
done: boolean;
@Column({ type: "text" })
description: string;
@Column({ type: "varchar", length: 255 })
reportedBy: string;
@Column({ type: "int", default: 0 })
imageCount: number;
@Column({ nullable: true, default: null })
equipmentId?: string;
@Column({ nullable: true, default: null })
vehicleId?: string;
@Column({ nullable: true, default: null })
wearableId?: string;
@Column({ nullable: true, default: null })
maintenanceId?: string;
@ManyToOne(() => equipment, (e) => e.reports, {
nullable: true,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
equipment?: equipment;
@ManyToOne(() => vehicle, (v) => v.reports, {
nullable: true,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
vehicle?: vehicle;
@ManyToOne(() => wearable, (w) => w.reports, {
nullable: true,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
wearable?: wearable;
@ManyToOne(() => maintenance, (m) => m.reports, {
nullable: true,
onDelete: "SET NULL",
onUpdate: "RESTRICT",
})
maintenance?: maintenance;
}

View file

@ -0,0 +1,46 @@
import { Column, ColumnType, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { getTypeByORM } from "../../../migrations/ormHelper";
import { equipmentType } from "./equipmentType";
import { damageReport } from "../damageReport";
import { inspection } from "../inspection/inspection";
import { maintenance } from "../maintenance";
@Entity()
export class equipment {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ type: "varchar", length: 255, nullable: true, default: null, unique: true })
code?: string;
@Column({ type: "varchar", length: 255 })
name: string;
@Column({ type: "varchar", length: 255 })
location: string;
@Column({ type: getTypeByORM("date").type as ColumnType })
commissioned: Date;
@Column({ type: getTypeByORM("date").type as ColumnType, nullable: true, default: null })
decommissioned?: Date;
@Column()
equipmentTypeId: string;
@ManyToOne(() => equipmentType, {
nullable: false,
onDelete: "RESTRICT",
onUpdate: "RESTRICT",
})
equipmentType: equipmentType;
@OneToMany(() => damageReport, (d) => d.equipment, { cascade: ["insert"] })
reports: damageReport[];
@OneToMany(() => maintenance, (m) => m.equipment, { cascade: ["insert"] })
maintenances: maintenance[];
@OneToMany(() => inspection, (i) => i.equipment, { cascade: ["insert"] })
inspections: inspection[];
}

View file

@ -0,0 +1,23 @@
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { equipment } from "./equipment";
import { inspectionPlan } from "../inspection/inspectionPlan";
@Entity()
export class equipmentType {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ type: "varchar", length: 255, unique: true })
type: string;
@Column({ type: "text", nullable: true })
description: string;
@OneToMany(() => equipment, (e) => e.equipmentType, { cascade: ["insert"] })
equipment: equipment[];
@OneToMany(() => inspectionPlan, (ip) => ip.equipmentType, { cascade: ["insert"] })
inspectionPlans: inspectionPlan[];
equipmentCount: number;
}

View file

@ -0,0 +1,82 @@
import { Column, ColumnType, CreateDateColumn, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { inspectionPlan } from "./inspectionPlan";
import { inspectionVersionedPlan } from "./inspectionVersionedPlan";
import { getTypeByORM } from "../../../migrations/ormHelper";
import { vehicle } from "../vehicle/vehicle";
import { equipment } from "../equipment/equipment";
import { inspectionPointResult } from "./inspectionPointResult";
import { wearable } from "../wearable/wearable";
@Entity()
export class inspection {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ type: "text" })
context: string;
@CreateDateColumn()
createdAt: Date;
@Column({ type: getTypeByORM("date").type as ColumnType, nullable: true, default: null })
finishedAt?: Date;
@Column({ type: getTypeByORM("date").type as ColumnType, nullable: true, default: null })
nextInspection?: Date;
@Column({ type: "boolean", default: false })
hasNewer: boolean;
@Column()
inspectionPlanId: string;
@Column()
inspectionVersionedPlanId: string;
@Column({ nullable: true, default: null })
equipmentId?: string;
@Column({ nullable: true, default: null })
vehicleId?: string;
@Column({ nullable: true, default: null })
wearableId?: string;
@ManyToOne(() => inspectionPlan, {
nullable: false,
onDelete: "RESTRICT",
onUpdate: "RESTRICT",
})
inspectionPlan: inspectionPlan;
@ManyToOne(() => inspectionVersionedPlan, {
nullable: false,
onDelete: "RESTRICT",
onUpdate: "RESTRICT",
})
inspectionVersionedPlan: inspectionVersionedPlan;
@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(() => inspectionPointResult, (ipr) => ipr.inspection, { cascade: ["insert"] })
pointResults: inspectionPointResult[];
}

View file

@ -0,0 +1,61 @@
import { Column, CreateDateColumn, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { PlanTimeDefinition } from "../../../viewmodel/admin/unit/inspection/inspectionPlan.models";
import { inspectionVersionedPlan } from "./inspectionVersionedPlan";
import { equipmentType } from "../equipment/equipmentType";
import { vehicleType } from "../vehicle/vehicleType";
import { wearableType } from "../wearable/wearableType";
@Entity()
export class inspectionPlan {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ type: "varchar", length: 255 })
title: string;
@Column({ type: "varchar", length: 255 })
inspectionInterval: PlanTimeDefinition;
@Column({ type: "varchar", length: 255 })
remindTime: PlanTimeDefinition;
@CreateDateColumn()
createdAt: Date;
@Column({ nullable: true, default: null })
equipmentTypeId?: string;
@Column({ nullable: true, default: null })
vehicleTypeId?: string;
@Column({ nullable: true, default: null })
wearableTypeId?: string;
@ManyToOne(() => equipmentType, {
nullable: true,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
equipmentType?: equipmentType;
@ManyToOne(() => vehicleType, {
nullable: true,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
vehicleType?: vehicleType;
@ManyToOne(() => wearableType, {
nullable: true,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
wearableType?: wearableType;
@OneToMany(() => inspectionVersionedPlan, (ivp) => ivp.inspectionPlan, {
cascade: ["insert"],
})
versionedPlans: inspectionVersionedPlan[];
latestVersionedPlan?: inspectionVersionedPlan;
}

View file

@ -0,0 +1,51 @@
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn, Unique } from "typeorm";
import { InspectionPointEnum } from "../../../enums/inspectionEnum";
import { inspectionVersionedPlan } from "./inspectionVersionedPlan";
@Entity()
export class inspectionPoint {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ type: "varchar", length: 255 })
title: string;
@Column({ type: "text" })
description: string;
@Column({
type: "varchar",
length: 255,
transformer: {
to(value: InspectionPointEnum) {
return value.toString();
},
from(value: string) {
return InspectionPointEnum[value as keyof typeof InspectionPointEnum];
},
},
})
type: InspectionPointEnum;
@Column({ type: "int", nullable: true, default: null })
min?: number;
@Column({ type: "int", nullable: true, default: null })
max?: number;
@Column({ type: "varchar", length: 255, default: null })
others?: string;
@Column({ type: "int", default: 0 })
sort: number;
@Column()
versionedPlanId: string;
@ManyToOne(() => inspectionVersionedPlan, {
nullable: false,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
versionedPlan: inspectionVersionedPlan;
}

View file

@ -0,0 +1,29 @@
import { Column, Entity, ManyToOne, PrimaryColumn } from "typeorm";
import { inspection } from "./inspection";
import { inspectionPoint } from "./inspectionPoint";
@Entity()
export class inspectionPointResult {
@PrimaryColumn()
inspectionId: string;
@PrimaryColumn()
inspectionPointId: string;
@Column({ type: "text" })
value: string;
@ManyToOne(() => inspection, {
nullable: false,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
inspection: inspection;
@ManyToOne(() => inspectionPoint, {
nullable: false,
onDelete: "RESTRICT",
onUpdate: "RESTRICT",
})
inspectionPoint: inspectionPoint;
}

View file

@ -0,0 +1,31 @@
import { Column, CreateDateColumn, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn, Unique } from "typeorm";
import { inspectionPlan } from "./inspectionPlan";
import { inspectionPoint } from "./inspectionPoint";
@Entity()
@Unique("unique_version", ["version", "inspectionPlanId"])
export class inspectionVersionedPlan {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ type: "int", default: 0 })
version: number;
@CreateDateColumn()
createdAt: Date;
@Column()
inspectionPlanId: string;
@ManyToOne(() => inspectionPlan, {
nullable: false,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
inspectionPlan: inspectionPlan;
@OneToMany(() => inspectionPoint, (ip) => ip.versionedPlan, {
cascade: ["insert"],
})
inspectionPoints: inspectionPoint[];
}

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, (e) => e.maintenances, {
nullable: true,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
equipment?: equipment;
@ManyToOne(() => vehicle, (v) => v.maintenances, {
nullable: true,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
vehicle?: vehicle;
@ManyToOne(() => wearable, (w) => w.maintenances, {
nullable: true,
onDelete: "CASCADE",
onUpdate: "RESTRICT",
})
wearable?: wearable;
@OneToMany(() => damageReport, (dr) => dr.maintenance)
reports: damageReport[];
}

View file

@ -0,0 +1,46 @@
import { Column, ColumnType, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { getTypeByORM } from "../../../migrations/ormHelper";
import { vehicleType } from "./vehicleType";
import { damageReport } from "../damageReport";
import { inspection } from "../inspection/inspection";
import { maintenance } from "../maintenance";
@Entity()
export class vehicle {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ type: "varchar", length: 255, nullable: true, default: null, unique: true })
code?: string;
@Column({ type: "varchar", length: 255 })
name: string;
@Column({ type: "varchar", length: 255 })
location: string;
@Column({ type: getTypeByORM("date").type as ColumnType })
commissioned: Date;
@Column({ type: getTypeByORM("date").type as ColumnType, nullable: true, default: null })
decommissioned?: Date;
@Column()
vehicleTypeId: string;
@ManyToOne(() => vehicleType, {
nullable: false,
onDelete: "RESTRICT",
onUpdate: "RESTRICT",
})
vehicleType: vehicleType;
@OneToMany(() => damageReport, (d) => d.vehicle, { cascade: ["insert"] })
reports: damageReport[];
@OneToMany(() => maintenance, (m) => m.vehicle, { cascade: ["insert"] })
maintenances: maintenance[];
@OneToMany(() => inspection, (i) => i.vehicle, { cascade: ["insert"] })
inspections: inspection[];
}

View file

@ -0,0 +1,23 @@
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { vehicle } from "./vehicle";
import { inspectionPlan } from "../inspection/inspectionPlan";
@Entity()
export class vehicleType {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ type: "varchar", length: 255, unique: true })
type: string;
@Column({ type: "text", nullable: true })
description: string;
@OneToMany(() => vehicle, (e) => e.vehicleType, { cascade: ["insert"] })
vehicle: vehicle[];
@OneToMany(() => inspectionPlan, (ip) => ip.vehicleType, { cascade: ["insert"] })
inspectionPlans: inspectionPlan[];
vehicleCount: number;
}

View file

@ -0,0 +1,57 @@
import { Column, ColumnType, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { getTypeByORM } from "../../../migrations/ormHelper";
import { wearableType } from "./wearableType";
import { damageReport } from "../damageReport";
import { member } from "../../club/member/member";
import { inspection } from "../inspection/inspection";
import { maintenance } from "../maintenance";
@Entity()
export class wearable {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ type: "varchar", length: 255, nullable: true, default: null, unique: true })
code?: string;
@Column({ type: "varchar", length: 255 })
name: string;
@Column({ type: "varchar", length: 255 })
location: string;
@Column({ type: getTypeByORM("date").type as ColumnType })
commissioned: Date;
@Column({ type: getTypeByORM("date").type as ColumnType, nullable: true, default: null })
decommissioned?: Date;
@Column()
wearableTypeId: string;
@Column({ nullable: true, default: null })
wearerId?: string;
@ManyToOne(() => wearableType, {
nullable: false,
onDelete: "RESTRICT",
onUpdate: "RESTRICT",
})
wearableType: wearableType;
@ManyToOne(() => member, {
nullable: true,
onDelete: "SET NULL",
onUpdate: "RESTRICT",
})
wearer?: member;
@OneToMany(() => damageReport, (d) => d.wearable, { cascade: ["insert"] })
reports: damageReport[];
@OneToMany(() => maintenance, (m) => m.wearable, { cascade: ["insert"] })
maintenances: maintenance[];
@OneToMany(() => inspection, (i) => i.wearable, { cascade: ["insert"] })
inspections: inspection[];
}

View file

@ -0,0 +1,23 @@
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { wearable as wearable } from "./wearable";
import { inspectionPlan } from "../inspection/inspectionPlan";
@Entity()
export class wearableType {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ type: "varchar", length: 255, unique: true })
type: string;
@Column({ type: "text", nullable: true })
description: string;
@OneToMany(() => wearable, (e) => e.wearableType, { cascade: ["insert"] })
wearable: wearable[];
@OneToMany(() => inspectionPlan, (ip) => ip.wearableType, { cascade: ["insert"] })
inspectionPlans: inspectionPlan[];
wearableCount: number;
}

View file

@ -0,0 +1,6 @@
export enum InspectionPointEnum {
oknok = "oknok",
text = "text",
number = "number",
file = "file",
}

View file

@ -15,7 +15,7 @@ export default abstract class MemberFactory {
public static mapToSingle(record: member): MemberViewModel {
return {
id: record?.id,
salutation: SalutationFactory.mapToSingle(record?.salutation),
salutation: record?.salutation ? SalutationFactory.mapToSingle(record?.salutation) : null,
firstname: record?.firstname,
lastname: record?.lastname,
nameaffix: record?.nameaffix,

View file

@ -0,0 +1,57 @@
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";
export default abstract class DamageReportFactory {
/**
* @description map record to damageReport
* @param {damageReport} record
* @returns {DamageReportViewModel}
*/
public static mapToSingle(record: damageReport): DamageReportViewModel {
let assigned: DamageReportAssigned;
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,
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,
};
}
/**
* @description map records to damageReport
* @param {Array<damageReport>} records
* @returns {Array<DamageReportViewModel>}
*/
public static mapToBase(records: Array<damageReport>): Array<DamageReportViewModel> {
return records.map((r) => this.mapToSingle(r));
}
}

View file

@ -0,0 +1,32 @@
import { equipment } from "../../../../entity/unit/equipment/equipment";
import { EquipmentViewModel } from "../../../../viewmodel/admin/unit/equipment/equipment.models";
import EquipmentTypeFactory from "./equipmentType";
export default abstract class EquipmentFactory {
/**
* @description map record to equipment
* @param {equipment} record
* @returns {EquipmentViewModel}
*/
public static mapToSingle(record: equipment): EquipmentViewModel {
return {
id: record.id,
code: record?.code,
name: record.name,
location: record.location,
commissioned: record.commissioned,
decommissioned: record?.decommissioned,
equipmentTypeId: record?.equipmentTypeId,
equipmentType: record?.equipmentType ? EquipmentTypeFactory.mapToSingle(record.equipmentType) : null,
};
}
/**
* @description map records to equipment
* @param {Array<equipment>} records
* @returns {Array<EquipmentViewModel>}
*/
public static mapToBase(records: Array<equipment>): Array<EquipmentViewModel> {
return records.map((r) => this.mapToSingle(r));
}
}

View file

@ -0,0 +1,27 @@
import { equipmentType } from "../../../../entity/unit/equipment/equipmentType";
import { EquipmentTypeViewModel } from "../../../../viewmodel/admin/unit/equipment/equipmentType.models";
export default abstract class EquipmentTypeFactory {
/**
* @description map record to equipmentType
* @param {equipmentType} record
* @returns {EquipmentTypeViewModel}
*/
public static mapToSingle(record: equipmentType): EquipmentTypeViewModel {
return {
id: record.id,
type: record.type,
description: record.description,
equipmentCount: record.equipmentCount,
};
}
/**
* @description map records to equipmentType
* @param {Array<equipmentType>} records
* @returns {Array<EquipmentTypeViewModel>}
*/
public static mapToBase(records: Array<equipmentType>): Array<EquipmentTypeViewModel> {
return records.map((r) => this.mapToSingle(r));
}
}

View file

@ -0,0 +1,133 @@
import { inspection } from "../../../../entity/unit/inspection/inspection";
import {
InspectionNextViewModel,
InspectionRelated,
InspectionViewModel,
MinifiedInspectionViewModel,
} from "../../../../viewmodel/admin/unit/inspection/inspection.models";
import EquipmentFactory from "../equipment/equipment";
import VehicleFactory from "../vehicle/vehicle";
import WearableFactory from "../wearable/wearable";
import InspectionPlanFactory from "./inspectionPlan";
import InspectionPointResultFactory from "./inspectionPointResult";
import InspectionVersionedPlanFactory from "./inspectionVersionedPlan";
export default abstract class InspectionFactory {
/**
* @description map record to inspection
* @param {inspection} record
* @returns {InspectionViewModel}
*/
public static mapRelated(record: inspection): InspectionRelated {
let related: InspectionRelated;
if (record?.equipmentId) {
related = {
relatedId: record.equipmentId,
assigned: "equipment",
related: EquipmentFactory.mapToSingle(record.equipment),
};
} else if (record?.vehicleId) {
related = {
relatedId: record.vehicleId,
assigned: "vehicle",
related: VehicleFactory.mapToSingle(record.vehicle),
};
} else {
related = {
relatedId: record.wearableId,
assigned: "wearable",
related: WearableFactory.mapToSingle(record.wearable),
};
}
return related;
}
/**
* @description map record to inspection
* @param {inspection} record
* @returns {InspectionViewModel}
*/
public static mapToSingle(record: inspection): InspectionViewModel {
let related = this.mapRelated(record);
return {
id: record.id,
inspectionPlanId: record.inspectionPlanId,
inspectionPlan: InspectionPlanFactory.mapToSingle(record.inspectionPlan),
inspectionVersionedPlanId: record.inspectionVersionedPlanId,
inspectionVersionedPlan: InspectionVersionedPlanFactory.mapToSingle(record.inspectionVersionedPlan),
context: record.context,
created: record.createdAt,
finished: record?.finishedAt,
isOpen: record?.finishedAt == undefined,
nextInspection: record?.nextInspection,
checks: InspectionPointResultFactory.mapToBase(record.pointResults),
...related,
};
}
/**
* @description map records to inspection
* @param {Array<inspection>} records
* @returns {Array<InspectionViewModel>}
*/
public static mapToBase(records: Array<inspection>): Array<InspectionViewModel> {
return records.map((r) => this.mapToSingle(r));
}
/**
* @description map record to minified inspection
* @param {inspection} record
* @returns {MinifiedInspectionViewModel}
*/
public static mapToSingleMinified(record: inspection): MinifiedInspectionViewModel {
let related = this.mapRelated(record);
return {
id: record.id,
inspectionPlanId: record.inspectionPlanId,
inspectionPlan: InspectionPlanFactory.mapToSingle(record.inspectionPlan),
context: record.context,
created: record.createdAt,
finished: record?.finishedAt,
isOpen: record?.finishedAt == undefined,
nextInspection: record?.nextInspection,
...related,
};
}
/**
* @description map records to minified inspection
* @param {Array<inspection>} records
* @returns {Array<MinifiedInspectionViewModel>}
*/
public static mapToBaseMinified(records: Array<inspection>): Array<MinifiedInspectionViewModel> {
return records.map((r) => this.mapToSingleMinified(r));
}
/**
* @description map record to next inspection
* @param {inspection} record
* @returns {InspectionNextViewModel}
*/
public static mapToSingleNext(record: inspection): InspectionNextViewModel {
let related = this.mapRelated(record);
return {
id: record.id,
inspectionPlanId: record.inspectionPlanId,
inspectionPlan: InspectionPlanFactory.mapToSingle(record.inspectionPlan),
dueDate: record?.nextInspection,
...related,
};
}
/**
* @description map records to next inspection
* @param {Array<inspection>} records
* @returns {Array<InspectionNextViewModel>}
*/
public static mapToBaseNext(records: Array<inspection>): Array<InspectionNextViewModel> {
return records.map((r) => this.mapToSingleNext(r));
}
}

View file

@ -0,0 +1,63 @@
import { inspectionPlan } from "../../../../entity/unit/inspection/inspectionPlan";
import {
InspectionPlanRelated,
InspectionPlanViewModel,
} from "../../../../viewmodel/admin/unit/inspection/inspectionPlan.models";
import EquipmentFactory from "../equipment/equipment";
import EquipmentTypeFactory from "../equipment/equipmentType";
import VehicleFactory from "../vehicle/vehicle";
import VehicleTypeFactory from "../vehicle/vehicleType";
import WearableTypeFactory from "../wearable/wearableType";
import InspectionPointFactory from "./inspectionPoint";
export default abstract class InspectionPlanFactory {
/**
* @description map record to inspectionPlan
* @param {inspectionPlan} record
* @returns {InspectionPlanViewModel}
*/
public static mapToSingle(record: inspectionPlan): InspectionPlanViewModel {
let related: InspectionPlanRelated;
if (record?.equipmentTypeId) {
related = {
relatedId: record.equipmentTypeId,
assigned: "equipment",
related: EquipmentTypeFactory.mapToSingle(record.equipmentType),
};
} else if (record?.vehicleTypeId) {
related = {
relatedId: record.vehicleTypeId,
assigned: "vehicle",
related: VehicleTypeFactory.mapToSingle(record.vehicleType),
};
} else {
related = {
relatedId: record.wearableTypeId,
assigned: "wearable",
related: WearableTypeFactory.mapToSingle(record.wearableType),
};
}
return {
id: record.id,
title: record.title,
inspectionInterval: record.inspectionInterval,
remindTime: record.remindTime,
version: record?.latestVersionedPlan?.version ?? 0,
created: record.createdAt,
inspectionPoints: record.latestVersionedPlan
? InspectionPointFactory.mapToBase(record.latestVersionedPlan.inspectionPoints)
: [],
...related,
};
}
/**
* @description map records to inspectionPlan
* @param {Array<inspectionPlan>} records
* @returns {Array<InspectionPlanViewModel>}
*/
public static mapToBase(records: Array<inspectionPlan>): Array<InspectionPlanViewModel> {
return records.map((r) => this.mapToSingle(r));
}
}

View file

@ -0,0 +1,31 @@
import { inspectionPoint } from "../../../../entity/unit/inspection/inspectionPoint";
import { InspectionPointViewModel } from "../../../../viewmodel/admin/unit/inspection/inspectionPlan.models";
export default abstract class InspectionPointFactory {
/**
* @description map record to inspectionPoint
* @param {inspectionPoint} record
* @returns {InspectionPointViewModel}
*/
public static mapToSingle(record: inspectionPoint): InspectionPointViewModel {
return {
id: record.id,
title: record.title,
description: record.description,
type: record.type,
sort: record.sort,
min: record?.min,
max: record?.max,
others: record?.others,
};
}
/**
* @description map records to inspectionPoint
* @param {Array<inspectionPoint>} records
* @returns {Array<InspectionPointViewModel>}
*/
public static mapToBase(records: Array<inspectionPoint>): Array<InspectionPointViewModel> {
return records.map((r) => this.mapToSingle(r));
}
}

View file

@ -0,0 +1,28 @@
import { inspectionPointResult } from "../../../../entity/unit/inspection/inspectionPointResult";
import { InspectionPointResultViewModel } from "../../../../viewmodel/admin/unit/inspection/inspection.models";
import InspectionPointFactory from "./inspectionPoint";
export default abstract class InspectionPointResultFactory {
/**
* @description map record to inspectionPointResult
* @param {inspectionPointResult} record
* @returns {InspectionPointResultViewModel}
*/
public static mapToSingle(record: inspectionPointResult): InspectionPointResultViewModel {
return {
inspectionId: record.inspectionId,
inspectionPointId: record.inspectionPointId,
inspectionPoint: InspectionPointFactory.mapToSingle(record.inspectionPoint),
value: record.value,
};
}
/**
* @description map records to inspectionPointResult
* @param {Array<inspectionPointResult>} records
* @returns {Array<InspectionPointResultViewModel>}
*/
public static mapToBase(records: Array<inspectionPointResult>): Array<InspectionPointResultViewModel> {
return records.map((r) => this.mapToSingle(r));
}
}

View file

@ -0,0 +1,28 @@
import { inspectionVersionedPlan } from "../../../../entity/unit/inspection/inspectionVersionedPlan";
import { InspectionVersionedPlanViewModel } from "../../../../viewmodel/admin/unit/inspection/inspectionPlan.models";
import InspectionPointFactory from "./inspectionPoint";
export default abstract class InspectionVersionedPlanFactory {
/**
* @description map record to inspectionVersionedPlan
* @param {inspectionVersionedPlan} record
* @returns {InspectionVersionedPlanViewModel}
*/
public static mapToSingle(record: inspectionVersionedPlan): InspectionVersionedPlanViewModel {
return {
id: record.id,
version: record.version,
created: record.createdAt,
inspectionPoints: InspectionPointFactory.mapToBase(record.inspectionPoints),
};
}
/**
* @description map records to inspectionVersionedPlan
* @param {Array<inspectionVersionedPlan>} records
* @returns {Array<InspectionVersionedPlanViewModel>}
*/
public static mapToBase(records: Array<inspectionVersionedPlan>): Array<InspectionVersionedPlanViewModel> {
return records.map((r) => this.mapToSingle(r));
}
}

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

@ -0,0 +1,32 @@
import { vehicle } from "../../../../entity/unit/vehicle/vehicle";
import { VehicleViewModel } from "../../../../viewmodel/admin/unit/vehicle/vehicle.models";
import VehicleTypeFactory from "./vehicleType";
export default abstract class VehicleFactory {
/**
* @description map record to vehicle
* @param {vehicle} record
* @returns {VehicleViewModel}
*/
public static mapToSingle(record: vehicle): VehicleViewModel {
return {
id: record.id,
code: record?.code,
name: record.name,
location: record.location,
commissioned: record.commissioned,
decommissioned: record?.decommissioned,
vehicleTypeId: record?.vehicleTypeId,
vehicleType: record?.vehicleType ? VehicleTypeFactory.mapToSingle(record.vehicleType) : null,
};
}
/**
* @description map records to vehicle
* @param {Array<vehicle>} records
* @returns {Array<VehicleViewModel>}
*/
public static mapToBase(records: Array<vehicle>): Array<VehicleViewModel> {
return records.map((r) => this.mapToSingle(r));
}
}

View file

@ -0,0 +1,27 @@
import { vehicleType } from "../../../../entity/unit/vehicle/vehicleType";
import { VehicleTypeViewModel } from "../../../../viewmodel/admin/unit/vehicle/vehicleType.models";
export default abstract class VehicleTypeFactory {
/**
* @description map record to vehicleType
* @param {vehicleType} record
* @returns {VehicleTypeViewModel}
*/
public static mapToSingle(record: vehicleType): VehicleTypeViewModel {
return {
id: record.id,
type: record.type,
description: record.description,
vehicleCount: record.vehicleCount,
};
}
/**
* @description map records to vehicleType
* @param {Array<vehicleType>} records
* @returns {Array<VehicleTypeViewModel>}
*/
public static mapToBase(records: Array<vehicleType>): Array<VehicleTypeViewModel> {
return records.map((r) => this.mapToSingle(r));
}
}

View file

@ -0,0 +1,35 @@
import { wearable } from "../../../../entity/unit/wearable/wearable";
import { WearableViewModel } from "../../../../viewmodel/admin/unit/wearable/wearable.models";
import MemberFactory from "../../club/member/member";
import WearableTypeFactory from "./wearableType";
export default abstract class WearableFactory {
/**
* @description map record to wearable
* @param {wearable} record
* @returns {WearableViewModel}
*/
public static mapToSingle(record: wearable): WearableViewModel {
return {
id: record.id,
code: record?.code,
name: record.name,
location: record.location,
commissioned: record.commissioned,
decommissioned: record?.decommissioned,
wearableTypeId: record?.wearableTypeId,
wearableType: record?.wearableType ? WearableTypeFactory.mapToSingle(record.wearableType) : null,
wearerId: record?.wearerId,
wearer: record?.wearer ? MemberFactory.mapToSingle(record.wearer) : null,
};
}
/**
* @description map records to wearable
* @param {Array<wearable>} records
* @returns {Array<WearableViewModel>}
*/
public static mapToBase(records: Array<wearable>): Array<WearableViewModel> {
return records.map((r) => this.mapToSingle(r));
}
}

View file

@ -0,0 +1,27 @@
import { wearableType } from "../../../../entity/unit/wearable/wearableType";
import { WearableTypeViewModel } from "../../../../viewmodel/admin/unit/wearable/wearableType.models";
export default abstract class WearableTypeFactory {
/**
* @description map record to wearableType
* @param {wearableType} record
* @returns {WearableTypeViewModel}
*/
public static mapToSingle(record: wearableType): WearableTypeViewModel {
return {
id: record.id,
type: record.type,
description: record.description,
wearableCount: record.wearableCount,
};
}
/**
* @description map records to wearableType
* @param {Array<wearableType>} records
* @returns {Array<WearableTypeViewModel>}
*/
public static mapToBase(records: Array<wearableType>): Array<WearableTypeViewModel> {
return records.map((r) => this.mapToSingle(r));
}
}

View file

@ -59,3 +59,7 @@ Handlebars.registerHelper("longdatetimeWithWeekday", function (aString) {
Handlebars.registerHelper("json", function (context) {
return JSON.stringify(context);
});
Handlebars.registerHelper("eq", function (p, q, options) {
return p == q ? options.fn(this) : options.inverse(this);
});

View file

@ -8,7 +8,6 @@ import DatabaseActionException from "../exceptions/databaseActionException";
import { availableTemplates } from "../type/templateTypes";
import SettingHelper from "./settingsHelper";
import { LoginRoutineEnum } from "../enums/loginRoutineEnum";
import { education } from "../entity/configuration/education";
export type BackupSection =
| "member"
@ -21,7 +20,9 @@ export type BackupSection =
| "template"
| "user"
| "webapi"
| "settings";
| "settings"
| "unitBase"
| "unitInstances";
export type BackupSectionRefered = {
[key in BackupSection]?: Array<string>;
@ -35,7 +36,7 @@ export type BackupFileContentSection = Array<any> | { [key: string]: Array<any>
export default abstract class BackupHelper {
// ! Order matters because of foreign keys
private static readonly backupSection: Array<{ type: BackupSection; orderOnInsert: number; orderOnClear: number }> = [
{ type: "member", orderOnInsert: 2, orderOnClear: 2 }, // CLEAR depends on protcol INSERT depends on Base
{ type: "member", orderOnInsert: 2, orderOnClear: 2 }, // CLEAR depends on protcol and wearables INSERT depends on Base
{ type: "memberBase", orderOnInsert: 1, orderOnClear: 3 }, // CLEAR depends on member
{ type: "protocol", orderOnInsert: 3, orderOnClear: 1 }, // INSERT depends on member
{ type: "newsletter", orderOnInsert: 3, orderOnClear: 1 }, // INSERT depends on member & query & calendar
@ -46,6 +47,8 @@ export default abstract class BackupHelper {
{ type: "user", orderOnInsert: 1, orderOnClear: 1 },
{ type: "webapi", orderOnInsert: 1, orderOnClear: 1 },
{ type: "settings", orderOnInsert: 1, orderOnClear: 1 },
{ type: "unitBase", orderOnInsert: 1, orderOnClear: 2 },
{ type: "unitInstances", orderOnInsert: 3, orderOnClear: 1 }, // INSERT depends on member in wearable
];
private static readonly backupSectionRefered: BackupSectionRefered = {
@ -83,6 +86,8 @@ export default abstract class BackupHelper {
user: ["user", "user_permission", "role", "role_permission", "invite"],
webapi: ["webapi", "webapi_permission"],
settings: ["setting"],
unitBase: ["equipment_type", "vehicle_type", "wearable_type"],
unitInstances: ["equipment", "vehicle", "wearable"],
};
private static transactionManager: EntityManager;
@ -162,7 +167,7 @@ export default abstract class BackupHelper {
for (const section of sections.filter((s) => Object.keys(backup).includes(s.type))) {
let refered = this.backupSectionRefered[section.type];
for (const ref of refered) {
await this.transactionManager.getRepository(ref).delete({});
await this.transactionManager.getRepository(ref).deleteAll();
}
}
}
@ -229,6 +234,10 @@ export default abstract class BackupHelper {
return await this.getWebapi();
case "settings":
return await this.getSettings();
case "unitBase":
return await this.getUnitBase();
case "unitInstances":
return await this.getUnitInstances();
default:
return [];
}
@ -490,6 +499,27 @@ export default abstract class BackupHelper {
.select(["setting.topic", "setting.key", "setting.value"])
.getMany();
}
private static async getUnitBase(): Promise<{ [key: string]: Array<any> }> {
return {
equipment_type: await dataSource.getRepository("equipment_type").find(),
vehicle_type: await dataSource.getRepository("vehicle_type").find(),
wearable_type: await dataSource.getRepository("wearable_type").find(),
inspection_plan: await dataSource.getRepository("inspection_plan").find(),
inspection_versioned_plan: await dataSource.getRepository("inspection_versioned_plan").find(),
inspection_point: await dataSource.getRepository("inspection_point").find(),
};
}
private static async getUnitInstances(): Promise<{ [key: string]: Array<any> }> {
return {
equipment: await dataSource.getRepository("equipment").find(),
vehicle: await dataSource.getRepository("vehicle").find(),
wearable: await dataSource.getRepository("wearable").find(),
maintenance: await dataSource.getRepository("maintenance").find(),
damage_report: await dataSource.getRepository("damage_report").find(),
inspection: await dataSource.getRepository("inspection").find(),
inspection_point_result: await dataSource.getRepository("inspection_point_result").find(),
};
}
private static async setSectionData(
section: BackupSection,
@ -507,6 +537,8 @@ export default abstract class BackupHelper {
if (section == "user" && !Array.isArray(data)) await this.setUser(data);
if (section == "webapi" && Array.isArray(data)) await this.setWebapi(data);
if (section == "settings" && Array.isArray(data)) await this.setSettings(data);
if (section == "unitBase" && !Array.isArray(data)) await this.setUnitBase(data);
if (section == "unitInstances" && !Array.isArray(data)) await this.setUnitInstances(data);
}
private static async setMemberData(data: Array<any>): Promise<void> {
@ -870,4 +902,24 @@ export default abstract class BackupHelper {
private static async setSettings(data: Array<any>): Promise<void> {
await this.transactionManager.getRepository("setting").save(data);
}
private static async setUnitBase(data: { [key: string]: Array<any> }): Promise<void> {
await this.transactionManager.getRepository("equipment_type").save(data["equipment_type"]);
await this.transactionManager.getRepository("vehicle_type").save(data["vehicle_type"]);
await this.transactionManager.getRepository("wearable_type").save(data["wearable_type"]);
await this.transactionManager.getRepository("inspection_plan").save(data["inspection_plan"]);
await this.transactionManager.getRepository("inspection_versioned_plan").save(data["inspection_versioned_plan"]);
await this.transactionManager.getRepository("inspection_point").save(data["inspection_point"]);
}
private static async setUnitInstances(data: { [key: string]: Array<any> }): Promise<void> {
await this.transactionManager.getRepository("equipment").save(data["equipment"]);
await this.transactionManager.getRepository("vehicle").save(data["vehicle"]);
await this.transactionManager.getRepository("wearable").save(data["wearable"]);
await this.transactionManager.getRepository("damage_report").save(data["damage_report"]);
await this.transactionManager.getRepository("maintenance").save(data["maintenance"]);
await this.transactionManager.getRepository("inspection").save(data["inspection"]);
await this.transactionManager.getRepository("inspection_point_result").save(data["inspection_point_result"]);
}
}

View file

@ -15,7 +15,7 @@ export abstract class FileSystemHelper {
return readFileSync(this.formatPath(...filePath), "utf8");
}
static readFileasBase64(...filePath: string[]) {
static readFileAsBase64(...filePath: string[]) {
this.createFolder(...filePath);
return readFileSync(this.formatPath(...filePath), "base64");
}

View file

@ -127,7 +127,7 @@ export abstract class PdfExport {
const mergedPdf = await PDFDocument.create();
for (const pdfPath of pdfFilePaths) {
const pdfBytes = FileSystemHelper.readFileasBase64(inputFolder, pdfPath);
const pdfBytes = FileSystemHelper.readFileAsBase64(inputFolder, pdfPath);
const pdf = await PDFDocument.load(pdfBytes);
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
copiedPages.forEach((page) => mergedPdf.addPage(page));

18
src/helpers/typeTester.ts Normal file
View file

@ -0,0 +1,18 @@
import { PlanTimeDefinition } from "../viewmodel/admin/unit/inspection/inspectionPlan.models";
export default abstract class TypeTester {
static testPlanTimeDefinition(val: string, key: string = "", throwErr: boolean = false): PlanTimeDefinition | null {
if (/^(\d+-(d|m|y)|\d+\/(\d+|\*))$/.test(val)) {
return val as PlanTimeDefinition;
} else if (throwErr) {
throw Error(
[
key,
"provided String does not match PlanTimeDefinition Format: ${number}-${'d'|'m'|'y'} or ${number}/${number|'*'}",
].join(": ")
);
} else {
return null;
}
}
}

View file

@ -11,6 +11,8 @@ declare global {
export interface Request {
userId: string;
username: string;
firstname: string;
lastname: string;
isOwner: boolean;
permissions: PermissionObject;
isPWA: boolean;

View file

@ -35,6 +35,8 @@ export default async function authenticate(req: Request, res: Response, next: Ne
req.userId = decoded.userId;
req.username = decoded.username;
req.firstname = decoded.firstname;
req.lastname = decoded.lastname;
req.isOwner = decoded.isOwner;
req.permissions = decoded.permissions;
req.isWebApiRequest = decoded?.sub == "webapi_access_token";

View file

@ -3,6 +3,7 @@ import { FileSystemHelper } from "../helpers/fileSystemHelper";
import path from "path";
import BadRequestException from "../exceptions/badRequestException";
/**Settings image upload */
export const clubImageStorage = multer.diskStorage({
destination: FileSystemHelper.formatPath("/app"),
filename: function (req, file, cb) {
@ -33,3 +34,27 @@ export const clubImageUpload = clubImageMulter.fields([
{ name: "icon", maxCount: 1 },
{ name: "logo", maxCount: 1 },
]);
/**Inspection file upload */
export const inspectionFileStorage = multer.diskStorage({
destination: function (req, file, cb) {
FileSystemHelper.createFolder("inspection", req.params.id);
cb(null, FileSystemHelper.formatPath("inspection", req.params.id));
},
filename: function (req, file, cb) {
cb(null, file.originalname);
},
});
export const inspectionFileMulter = multer({
storage: inspectionFileStorage,
fileFilter(req, file, cb) {
if (file.mimetype.startsWith("image/") || file.mimetype === "application/pdf") {
cb(null, true);
} else {
cb(new BadRequestException("Wrong file format"));
}
},
});
export const inspectionFileUpload = inspectionFileMulter.array("files");

View file

@ -0,0 +1,80 @@
import { MigrationInterface, QueryRunner } from "typeorm";
import {
inspection_plan_table,
inspection_versioned_plan_table,
inspection_point_table,
inspection_table,
inspection_point_result_table,
} from "./baseSchemaTables/inspection";
import {
equipment_type_table,
equipment_table,
vehicle_type_table,
vehicle_table,
wearable_type_table,
wearable_table,
} from "./baseSchemaTables/unit";
import { maintenance_table, damage_report_table } from "./baseSchemaTables/unit_extend";
import { availableTemplates } from "../type/templateTypes";
import { template_usage_table } from "./baseSchemaTables/query_template";
export class UnitBase1749361405703 implements MigrationInterface {
name = "UnitBase1749361405703";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.createTable(equipment_type_table, true, true, true);
await queryRunner.createTable(equipment_table, true, true, true);
await queryRunner.createTable(vehicle_type_table, true, true, true);
await queryRunner.createTable(vehicle_table, true, true, true);
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);
await queryRunner.createTable(inspection_versioned_plan_table, true, true, true);
await queryRunner.createTable(inspection_point_table, true, true, true);
await queryRunner.createTable(inspection_table, true, true, true);
await queryRunner.createTable(inspection_point_result_table, true, true, true);
await queryRunner.manager
.createQueryBuilder()
.insert()
.into(template_usage_table.name)
.values(
availableTemplates.map((at) => ({
scope: at,
}))
)
.orIgnore()
.execute();
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.dropTable(inspection_point_result_table, true, true, true);
await queryRunner.dropTable(inspection_table, true, true, true);
await queryRunner.dropTable(inspection_point_table, true, true, true);
await queryRunner.dropTable(inspection_versioned_plan_table, true, true, true);
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);
await queryRunner.dropTable(vehicle_table, true, true, true);
await queryRunner.dropTable(vehicle_type_table, true, true, true);
await queryRunner.dropTable(equipment_table, true, true, true);
await queryRunner.dropTable(equipment_type_table, true, true, true);
await queryRunner.manager
.createQueryBuilder()
.delete()
.from(template_usage_table.name)
.where({ scope: "inspection" })
.execute();
}
}

View file

@ -0,0 +1,167 @@
import { Table, TableForeignKey, TableUnique } from "typeorm";
import { getTypeByORM, isUUIDPrimary, getDefaultByORM } from "../ormHelper";
export const inspection_plan_table = new Table({
name: "inspection_plan",
columns: [
{ name: "id", ...getTypeByORM("uuid"), ...isUUIDPrimary },
{ name: "title", ...getTypeByORM("varchar") },
{ name: "inspectionInterval", ...getTypeByORM("varchar") },
{ name: "remindTime", ...getTypeByORM("varchar") },
{ name: "createdAt", ...getTypeByORM("datetime"), default: getDefaultByORM("currentTimestamp") },
{ name: "equipmentTypeId", ...getTypeByORM("uuid", true) },
{ name: "vehicleTypeId", ...getTypeByORM("uuid", true) },
{ name: "wearableTypeId", ...getTypeByORM("uuid", true) },
],
foreignKeys: [
new TableForeignKey({
columnNames: ["equipmentTypeId"],
referencedColumnNames: ["id"],
referencedTableName: "equipment_type",
onDelete: "CASCADE",
onUpdate: "RESTRICT",
}),
new TableForeignKey({
columnNames: ["vehicleTypeId"],
referencedColumnNames: ["id"],
referencedTableName: "vehicle_type",
onDelete: "CASCADE",
onUpdate: "RESTRICT",
}),
new TableForeignKey({
columnNames: ["wearableTypeId"],
referencedColumnNames: ["id"],
referencedTableName: "wearable_type",
onDelete: "CASCADE",
onUpdate: "RESTRICT",
}),
],
});
export const inspection_versioned_plan_table = new Table({
name: "inspection_versioned_plan",
columns: [
{ name: "id", ...getTypeByORM("uuid"), ...isUUIDPrimary },
{ name: "version", ...getTypeByORM("int"), default: getDefaultByORM("number", 0) },
{ name: "createdAt", ...getTypeByORM("datetime"), default: getDefaultByORM("currentTimestamp") },
{ name: "inspectionPlanId", ...getTypeByORM("uuid") },
],
foreignKeys: [
new TableForeignKey({
columnNames: ["inspectionPlanId"],
referencedColumnNames: ["id"],
referencedTableName: "inspection_plan",
onDelete: "CASCADE",
onUpdate: "RESTRICT",
}),
],
uniques: [
new TableUnique({
name: "unique_version",
columnNames: ["version", "inspectionPlanId"],
}),
],
});
export const inspection_point_table = new Table({
name: "inspection_point",
columns: [
{ name: "id", ...getTypeByORM("uuid"), ...isUUIDPrimary },
{ name: "title", ...getTypeByORM("varchar") },
{ name: "description", ...getTypeByORM("text") },
{ name: "type", ...getTypeByORM("varchar") },
{ name: "min", ...getTypeByORM("int", true) },
{ name: "max", ...getTypeByORM("int", true) },
{ name: "others", ...getTypeByORM("varchar", true) },
{ name: "sort", ...getTypeByORM("int"), default: getDefaultByORM("number", 0) },
{ name: "versionedPlanId", ...getTypeByORM("uuid") },
],
foreignKeys: [
new TableForeignKey({
columnNames: ["versionedPlanId"],
referencedColumnNames: ["id"],
referencedTableName: "inspection_versioned_plan",
onDelete: "CASCADE",
onUpdate: "RESTRICT",
}),
],
});
export const inspection_table = new Table({
name: "inspection",
columns: [
{ name: "id", ...getTypeByORM("uuid"), ...isUUIDPrimary },
{ name: "context", ...getTypeByORM("text") },
{ name: "createdAt", ...getTypeByORM("datetime"), default: getDefaultByORM("currentTimestamp") },
{ name: "finishedAt", ...getTypeByORM("date", true) },
{ name: "nextInspection", ...getTypeByORM("date", true) },
{ name: "hasNewer", ...getTypeByORM("boolean"), default: getDefaultByORM("boolean", false) },
{ name: "inspectionPlanId", ...getTypeByORM("uuid") },
{ name: "inspectionVersionedPlanId", ...getTypeByORM("uuid") },
{ name: "equipmentId", ...getTypeByORM("uuid", true) },
{ name: "vehicleId", ...getTypeByORM("uuid", true) },
{ name: "wearableId", ...getTypeByORM("uuid", true) },
],
foreignKeys: [
new TableForeignKey({
columnNames: ["inspectionPlanId"],
referencedColumnNames: ["id"],
referencedTableName: "inspection_plan",
onDelete: "RESTRICT",
onUpdate: "RESTRICT",
}),
new TableForeignKey({
columnNames: ["inspectionVersionedPlanId"],
referencedColumnNames: ["id"],
referencedTableName: "inspection_versioned_plan",
onDelete: "RESTRICT",
onUpdate: "RESTRICT",
}),
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",
}),
],
});
export const inspection_point_result_table = new Table({
name: "inspection_point_result",
columns: [
{ name: "inspectionId", ...getTypeByORM("uuid"), isPrimary: true },
{ name: "inspectionPointId", ...getTypeByORM("uuid"), isPrimary: true },
{ name: "value", ...getTypeByORM("text") },
],
foreignKeys: [
new TableForeignKey({
columnNames: ["inspectionId"],
referencedColumnNames: ["id"],
referencedTableName: "inspection",
onDelete: "CASCADE",
onUpdate: "RESTRICT",
}),
new TableForeignKey({
columnNames: ["inspectionPointId"],
referencedColumnNames: ["id"],
referencedTableName: "inspection_point",
onDelete: "RESTRICT",
onUpdate: "RESTRICT",
}),
],
});

View file

@ -0,0 +1,103 @@
import { Table, TableForeignKey } from "typeorm";
import { getTypeByORM, isUUIDPrimary, getDefaultByORM } from "../ormHelper";
export const equipment_table = new Table({
name: "equipment",
columns: [
{ name: "id", ...getTypeByORM("uuid"), ...isUUIDPrimary },
{ name: "code", ...getTypeByORM("varchar", true), isUnique: true },
{ name: "name", ...getTypeByORM("varchar") },
{ name: "location", ...getTypeByORM("varchar") },
{ name: "commissioned", ...getTypeByORM("date") },
{ name: "decommissioned", ...getTypeByORM("date", true) },
{ name: "equipmentTypeId", ...getTypeByORM("uuid") },
],
foreignKeys: [
new TableForeignKey({
columnNames: ["equipmentTypeId"],
referencedColumnNames: ["id"],
referencedTableName: "equipment_type",
onDelete: "RESTRICT",
onUpdate: "RESTRICT",
}),
],
});
export const equipment_type_table = new Table({
name: "equipment_type",
columns: [
{ name: "id", ...getTypeByORM("uuid"), ...isUUIDPrimary },
{ name: "type", ...getTypeByORM("varchar"), isUnique: true },
{ name: "description", ...getTypeByORM("text", true) },
],
});
export const vehicle_table = new Table({
name: "vehicle",
columns: [
{ name: "id", ...getTypeByORM("uuid"), ...isUUIDPrimary },
{ name: "code", ...getTypeByORM("varchar", true), isUnique: true },
{ name: "name", ...getTypeByORM("varchar") },
{ name: "location", ...getTypeByORM("varchar") },
{ name: "commissioned", ...getTypeByORM("date") },
{ name: "decommissioned", ...getTypeByORM("date", true) },
{ name: "vehicleTypeId", ...getTypeByORM("uuid") },
],
foreignKeys: [
new TableForeignKey({
columnNames: ["vehicleTypeId"],
referencedColumnNames: ["id"],
referencedTableName: "vehicle_type",
onDelete: "RESTRICT",
onUpdate: "RESTRICT",
}),
],
});
export const vehicle_type_table = new Table({
name: "vehicle_type",
columns: [
{ name: "id", ...getTypeByORM("uuid"), ...isUUIDPrimary },
{ name: "type", ...getTypeByORM("varchar"), isUnique: true },
{ name: "description", ...getTypeByORM("text", true) },
],
});
export const wearable_table = new Table({
name: "wearable",
columns: [
{ name: "id", ...getTypeByORM("uuid"), ...isUUIDPrimary },
{ name: "code", ...getTypeByORM("varchar", true), isUnique: true },
{ name: "name", ...getTypeByORM("varchar") },
{ name: "location", ...getTypeByORM("varchar") },
{ name: "commissioned", ...getTypeByORM("date") },
{ name: "decommissioned", ...getTypeByORM("date", true) },
{ name: "wearableTypeId", ...getTypeByORM("uuid") },
{ name: "wearerId", ...getTypeByORM("uuid", true) },
],
foreignKeys: [
new TableForeignKey({
columnNames: ["wearableTypeId"],
referencedColumnNames: ["id"],
referencedTableName: "wearable_type",
onDelete: "RESTRICT",
onUpdate: "RESTRICT",
}),
new TableForeignKey({
columnNames: ["wearerId"],
referencedColumnNames: ["id"],
referencedTableName: "member",
onDelete: "SET NULL",
onUpdate: "RESTRICT",
}),
],
});
export const wearable_type_table = new Table({
name: "wearable_type",
columns: [
{ name: "id", ...getTypeByORM("uuid"), ...isUUIDPrimary },
{ name: "type", ...getTypeByORM("varchar"), isUnique: true },
{ name: "description", ...getTypeByORM("text", true) },
],
});

View file

@ -0,0 +1,86 @@
import { Table, TableForeignKey } from "typeorm";
import { getTypeByORM, isUUIDPrimary, getDefaultByORM } from "../ormHelper";
export const damage_report_table = new Table({
name: "damage_report",
columns: [
{ name: "id", ...getTypeByORM("uuid"), ...isUUIDPrimary },
{ name: "reportedAt", ...getTypeByORM("datetime"), default: getDefaultByORM("currentTimestamp") },
{ name: "status", ...getTypeByORM("varchar") },
{ name: "done", ...getTypeByORM("boolean"), default: getDefaultByORM("boolean", false) },
{ name: "description", ...getTypeByORM("text") },
{ name: "reportedBy", ...getTypeByORM("varchar") },
{ name: "imageCount", ...getTypeByORM("int"), default: getDefaultByORM("number", 0) },
{ name: "equipmentId", ...getTypeByORM("uuid", true) },
{ name: "vehicleId", ...getTypeByORM("uuid", true) },
{ name: "wearableId", ...getTypeByORM("uuid", true) },
{ name: "maintenanceId", ...getTypeByORM("uuid", true) },
],
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("datetime"), default: getDefaultByORM("currentTimestamp") },
{ name: "status", ...getTypeByORM("varchar") },
{ name: "done", ...getTypeByORM("boolean"), default: getDefaultByORM("boolean", false) },
{ name: "description", ...getTypeByORM("text") },
{ name: "equipmentId", ...getTypeByORM("uuid", true) },
{ name: "vehicleId", ...getTypeByORM("uuid", true) },
{ name: "wearableId", ...getTypeByORM("uuid", true) },
],
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",
}),
],
});

View file

@ -2,6 +2,7 @@ import express from "express";
import PermissionHelper from "../../helpers/permissionHelper";
import preventWebapiAccess from "../../middleware/preventWebApiAccess";
/** configuration */
import award from "./configuration/award";
import communicationType from "./configuration/communicationType";
import executivePosition from "./configuration/executivePosition";
@ -15,6 +16,7 @@ import template from "./configuration/template";
import templateUsage from "./configuration/templateUsage";
import newsletterConfig from "./configuration/newsletterConfig";
/** club */
import member from "./club/member";
import protocol from "./club/protocol";
import calendar from "./club/calendar";
@ -22,6 +24,7 @@ import queryBuilder from "./club/queryBuilder";
import newsletter from "./club/newsletter";
import listprint from "./club/listprint";
/** management */
import role from "./management/role";
import user from "./management/user";
import invite from "./management/invite";
@ -29,8 +32,21 @@ import api from "./management/webapi";
import backup from "./management/backup";
import setting from "./management/setting";
/** unit */
import equipment from "./unit/equipment";
import equipmentType from "./unit/equipmentType";
import vehicle from "./unit/vehicle";
import vehicleType from "./unit/vehicleType";
import wearable from "./unit/wearable";
import wearableType from "./unit/wearableType";
import inspection from "./unit/inspection";
import inspectionPlan from "./unit/inspectionPlan";
import damageReport from "./unit/damageReport";
import maintenance from "./unit/maintenance";
var router = express.Router({ mergeParams: true });
/** configuration */
router.use(
"/award",
PermissionHelper.passCheckSomeMiddleware([
@ -121,6 +137,7 @@ router.use(
newsletterConfig
);
/** club */
router.use("/member", PermissionHelper.passCheckMiddleware("read", "club", "member"), member);
router.use(
"/protocol",
@ -152,6 +169,7 @@ router.use(
);
router.use("/listprint", PermissionHelper.passCheckMiddleware("read", "club", "listprint"), listprint);
/** management */
router.use("/role", PermissionHelper.passCheckMiddleware("read", "management", "role"), role);
router.use(
"/user",
@ -171,4 +189,99 @@ router.use(
);
router.use("/setting", PermissionHelper.passCheckMiddleware("read", "management", "setting"), setting);
/** unit */
router.use(
"/equipment",
PermissionHelper.passCheckSomeMiddleware([
{ requiredPermission: "read", section: "unit", module: "equipment" },
{ requiredPermission: "read", section: "unit", module: "inspection_plan" },
]),
equipment
);
router.use(
"/equipmenttype",
PermissionHelper.passCheckSomeMiddleware([
{ requiredPermission: "read", section: "unit", module: "equipment_type" },
{ requiredPermission: "read", section: "unit", module: "equipment" },
{ requiredPermission: "read", section: "unit", module: "inspection_plan" },
]),
equipmentType
);
router.use(
"/vehicle",
PermissionHelper.passCheckSomeMiddleware([
{ requiredPermission: "read", section: "unit", module: "vehicle" },
{ requiredPermission: "read", section: "unit", module: "inspection_plan" },
]),
vehicle
);
router.use(
"/vehicletype",
PermissionHelper.passCheckSomeMiddleware([
{ requiredPermission: "read", section: "unit", module: "vehicle_type" },
{ requiredPermission: "read", section: "unit", module: "vehicle" },
{ requiredPermission: "read", section: "unit", module: "inspection_plan" },
]),
vehicleType
);
router.use(
"/wearable",
PermissionHelper.passCheckSomeMiddleware([
{ requiredPermission: "read", section: "unit", module: "wearable" },
{ requiredPermission: "read", section: "unit", module: "inspection_plan" },
]),
wearable
);
router.use(
"/wearabletype",
PermissionHelper.passCheckSomeMiddleware([
{ requiredPermission: "read", section: "unit", module: "wearable_type" },
{ requiredPermission: "read", section: "unit", module: "wearable" },
{ requiredPermission: "read", section: "unit", module: "inspection_plan" },
]),
wearableType
);
router.use(
"/inspection",
PermissionHelper.passCheckSomeMiddleware([
{ requiredPermission: "read", section: "unit", module: "inspection" },
{ requiredPermission: "read", section: "unit", module: "equipment" },
{ requiredPermission: "read", section: "unit", module: "vehicle" },
{ requiredPermission: "read", section: "unit", module: "wearable" },
]),
inspection
);
router.use(
"/inspectionplan",
PermissionHelper.passCheckSomeMiddleware([
{ requiredPermission: "read", section: "unit", module: "inspection_plan" },
{ requiredPermission: "read", section: "unit", module: "inspection" },
{ requiredPermission: "read", section: "unit", module: "equipment_type" },
{ requiredPermission: "read", section: "unit", module: "vehicle_type" },
{ requiredPermission: "read", section: "unit", module: "wearable_type" },
]),
inspectionPlan
);
router.use(
"/damagereport",
PermissionHelper.passCheckSomeMiddleware([
{ requiredPermission: "read", section: "unit", module: "damage_report" },
{ requiredPermission: "read", section: "unit", module: "maintenance" },
{ requiredPermission: "read", section: "unit", module: "equipment" },
{ requiredPermission: "read", section: "unit", module: "vehicle" },
{ requiredPermission: "read", section: "unit", module: "wearable" },
]),
damageReport
);
router.use(
"/maintenance",
PermissionHelper.passCheckSomeMiddleware([
{ requiredPermission: "read", section: "unit", module: "maintenance" },
{ requiredPermission: "read", section: "unit", module: "equipment" },
{ requiredPermission: "read", section: "unit", module: "vehicle" },
{ requiredPermission: "read", section: "unit", module: "wearable" },
]),
maintenance
);
export default router;

View file

@ -0,0 +1,50 @@
import express, { Request, Response } from "express";
import PermissionHelper from "../../../helpers/permissionHelper";
import {
createInspection,
deleteInspectionById,
getAllInspectionsForRelated,
getInspectionById,
updateInspectionById,
} from "../../../controller/admin/unit/inspectionController";
import {
getAllDamageReportsByStatus,
getAllDamageReportsForRelated,
getDamageReportById,
updateDamageReportById,
} from "../../../controller/admin/unit/damageReportController";
var router = express.Router({ mergeParams: true });
router.get("/", async (req: Request, res: Response) => {
await getAllDamageReportsByStatus(req, res);
});
router.get(
["/vehicle/:relatedId", "/equipment/:relatedId", "/wearable/:relatedId"],
async (req: Request, res: Response) => {
if (req.path.startsWith("/vehicle")) {
req.params.related = "vehicle";
} else if (req.path.startsWith("/equipment")) {
req.params.related = "equipment";
} else {
req.params.related = "wearable";
}
await getAllDamageReportsForRelated(req, res);
}
);
router.get("/:id", async (req: Request, res: Response) => {
await getDamageReportById(req, res);
});
router.patch(
"/:id",
PermissionHelper.passCheckMiddleware("update", "unit", "inspection"),
async (req: Request, res: Response) => {
await updateDamageReportById(req, res);
}
);
export default router;

View file

@ -0,0 +1,50 @@
import express, { Request, Response } from "express";
import PermissionHelper from "../../../helpers/permissionHelper";
import {
createEquipment,
deleteEquipmentById,
getAllEquipments,
getEquipmentById,
getEquipmentsByIds,
updateEquipmentById,
} from "../../../controller/admin/unit/equipmentController";
var router = express.Router({ mergeParams: true });
router.get("/", async (req: Request, res: Response) => {
await getAllEquipments(req, res);
});
router.get("/:id", async (req: Request, res: Response) => {
await getEquipmentById(req, res);
});
router.post("/ids", async (req: Request, res: Response) => {
await getEquipmentsByIds(req, res);
});
router.post(
"/",
PermissionHelper.passCheckMiddleware("create", "unit", "equipment"),
async (req: Request, res: Response) => {
await createEquipment(req, res);
}
);
router.patch(
"/:id",
PermissionHelper.passCheckMiddleware("update", "unit", "equipment"),
async (req: Request, res: Response) => {
await updateEquipmentById(req, res);
}
);
router.delete(
"/:id",
PermissionHelper.passCheckMiddleware("delete", "unit", "equipment"),
async (req: Request, res: Response) => {
await deleteEquipmentById(req, res);
}
);
export default router;

View file

@ -0,0 +1,45 @@
import express, { Request, Response } from "express";
import PermissionHelper from "../../../helpers/permissionHelper";
import {
createEquipmentType,
deleteEquipmentTypeById,
getAllEquipmentTypes,
getEquipmentTypeById,
updateEquipmentTypeById,
} from "../../../controller/admin/unit/equipmentTypeController";
var router = express.Router({ mergeParams: true });
router.get("/", async (req: Request, res: Response) => {
await getAllEquipmentTypes(req, res);
});
router.get("/:id", async (req: Request, res: Response) => {
await getEquipmentTypeById(req, res);
});
router.post(
"/",
PermissionHelper.passCheckMiddleware("create", "unit", "equipment_type"),
async (req: Request, res: Response) => {
await createEquipmentType(req, res);
}
);
router.patch(
"/:id",
PermissionHelper.passCheckMiddleware("update", "unit", "equipment_type"),
async (req: Request, res: Response) => {
await updateEquipmentTypeById(req, res);
}
);
router.delete(
"/:id",
PermissionHelper.passCheckMiddleware("delete", "unit", "equipment_type"),
async (req: Request, res: Response) => {
await deleteEquipmentTypeById(req, res);
}
);
export default router;

View file

@ -0,0 +1,96 @@
import express, { Request, Response } from "express";
import PermissionHelper from "../../../helpers/permissionHelper";
import {
createInspection,
deleteInspectionById,
getAllInspectionsSortedNotHavingNewer,
getAllInspectionsForRelated,
getInspectionById,
updateInspectionById,
getAllInspectionsRunning,
updateInspectionResults,
getInspectionPrintoutById,
finishInspection,
getInspectionPointUpload,
} from "../../../controller/admin/unit/inspectionController";
import { inspectionFileUpload } from "../../../middleware/multer";
var router = express.Router({ mergeParams: true });
router.get("/next", async (req: Request, res: Response) => {
await getAllInspectionsSortedNotHavingNewer(req, res);
});
router.get("/running", async (req: Request, res: Response) => {
await getAllInspectionsRunning(req, res);
});
router.get(
["/vehicle/:relatedId", "/equipment/:relatedId", "/wearable/:relatedId"],
async (req: Request, res: Response) => {
if (req.path.startsWith("/vehicle")) {
req.params.related = "vehicle";
} else if (req.path.startsWith("/equipment")) {
req.params.related = "equipment";
} else {
req.params.related = "wearable";
}
await getAllInspectionsForRelated(req, res);
}
);
router.get("/:id", async (req: Request, res: Response) => {
await getInspectionById(req, res);
});
router.get("/:id/printout", async (req: Request, res: Response) => {
await getInspectionPrintoutById(req, res);
});
router.get("/:id/:pointId/upload", async (req: Request, res: Response) => {
await getInspectionPointUpload(req, res);
});
router.post(
"/",
PermissionHelper.passCheckMiddleware("create", "unit", "inspection"),
async (req: Request, res: Response) => {
await createInspection(req, res);
}
);
router.patch(
"/:id",
PermissionHelper.passCheckMiddleware("update", "unit", "inspection"),
async (req: Request, res: Response) => {
await updateInspectionById(req, res);
}
);
router.patch(
"/:id/results",
PermissionHelper.passCheckMiddleware("update", "unit", "inspection"),
inspectionFileUpload,
async (req: Request, res: Response) => {
await updateInspectionResults(req, res);
}
);
router.patch(
"/:id/finish",
PermissionHelper.passCheckMiddleware("update", "unit", "inspection"),
async (req: Request, res: Response) => {
await finishInspection(req, res);
}
);
router.delete(
"/:id",
PermissionHelper.passCheckMiddleware("delete", "unit", "inspection"),
async (req: Request, res: Response) => {
await deleteInspectionById(req, res);
}
);
export default router;

View file

@ -0,0 +1,75 @@
import express, { Request, Response } from "express";
import PermissionHelper from "../../../helpers/permissionHelper";
import {
createInspectionPlan,
deleteInspectionPlanById,
getAllInspectionPlans,
getAllInspectionPlansForRelated,
getInspectionPlanById,
getInspectionPointsByPlanId,
updateInspectionPlanById,
updateInspectionPointsByPlanId,
} from "../../../controller/admin/unit/inspectionPlanController";
var router = express.Router({ mergeParams: true });
router.get("/", async (req: Request, res: Response) => {
await getAllInspectionPlans(req, res);
});
router.get("/:id/points", async (req: Request, res: Response) => {
await getInspectionPointsByPlanId(req, res);
});
router.get(
["/vehicleType/:relatedTypeId", "/equipmentType/:relatedTypeId", "/wearableType/:relatedTypeId"],
async (req: Request, res: Response) => {
if (req.path.startsWith("/vehicleType")) {
req.params.related = "vehicleType";
} else if (req.path.startsWith("/equipmentType")) {
req.params.related = "equipmentType";
} else {
req.params.related = "wearableType";
}
await getAllInspectionPlansForRelated(req, res);
}
);
router.get("/:id", async (req: Request, res: Response) => {
await getInspectionPlanById(req, res);
});
router.post(
"/",
PermissionHelper.passCheckMiddleware("create", "unit", "inspection_plan"),
async (req: Request, res: Response) => {
await createInspectionPlan(req, res);
}
);
router.patch(
"/:id",
PermissionHelper.passCheckMiddleware("update", "unit", "inspection_plan"),
async (req: Request, res: Response) => {
await updateInspectionPlanById(req, res);
}
);
router.patch(
"/:id/points",
PermissionHelper.passCheckMiddleware("update", "unit", "inspection_plan"),
async (req: Request, res: Response) => {
await updateInspectionPointsByPlanId(req, res);
}
);
router.delete(
"/:id",
PermissionHelper.passCheckMiddleware("delete", "unit", "inspection_plan"),
async (req: Request, res: Response) => {
await deleteInspectionPlanById(req, res);
}
);
export default router;

View file

@ -0,0 +1,43 @@
import express, { Request, Response } from "express";
import PermissionHelper from "../../../helpers/permissionHelper";
import {
getAllMaintenancesByStatus,
getAllMaintenancesForRelated,
getMaintenanceById,
updateMaintenanceById,
} from "../../../controller/admin/unit/maintenanceController";
var router = express.Router({ mergeParams: true });
router.get("/", async (req: Request, res: Response) => {
await getAllMaintenancesByStatus(req, res);
});
router.get(
["/vehicle/:relatedId", "/equipment/:relatedId", "/wearable/:relatedId"],
async (req: Request, res: Response) => {
if (req.path.startsWith("/vehicle")) {
req.params.related = "vehicle";
} else if (req.path.startsWith("/equipment")) {
req.params.related = "equipment";
} else {
req.params.related = "wearable";
}
await getAllMaintenancesForRelated(req, res);
}
);
router.get("/:id", async (req: Request, res: Response) => {
await getMaintenanceById(req, res);
});
router.patch(
"/:id",
PermissionHelper.passCheckMiddleware("update", "unit", "inspection"),
async (req: Request, res: Response) => {
await updateMaintenanceById(req, res);
}
);
export default router;

View file

@ -0,0 +1,50 @@
import express, { Request, Response } from "express";
import PermissionHelper from "../../../helpers/permissionHelper";
import {
createVehicle,
deleteVehicleById,
getAllVehicles,
getVehicleById,
getVehiclesByIds,
updateVehicleById,
} from "../../../controller/admin/unit/vehicleController";
var router = express.Router({ mergeParams: true });
router.get("/", async (req: Request, res: Response) => {
await getAllVehicles(req, res);
});
router.get("/:id", async (req: Request, res: Response) => {
await getVehicleById(req, res);
});
router.post("/ids", async (req: Request, res: Response) => {
await getVehiclesByIds(req, res);
});
router.post(
"/",
PermissionHelper.passCheckMiddleware("create", "unit", "vehicle"),
async (req: Request, res: Response) => {
await createVehicle(req, res);
}
);
router.patch(
"/:id",
PermissionHelper.passCheckMiddleware("update", "unit", "vehicle"),
async (req: Request, res: Response) => {
await updateVehicleById(req, res);
}
);
router.delete(
"/:id",
PermissionHelper.passCheckMiddleware("delete", "unit", "vehicle"),
async (req: Request, res: Response) => {
await deleteVehicleById(req, res);
}
);
export default router;

View file

@ -0,0 +1,45 @@
import express, { Request, Response } from "express";
import PermissionHelper from "../../../helpers/permissionHelper";
import {
createVehicleType,
deleteVehicleTypeById,
getAllVehicleTypes,
getVehicleTypeById,
updateVehicleTypeById,
} from "../../../controller/admin/unit/vehicleTypeController";
var router = express.Router({ mergeParams: true });
router.get("/", async (req: Request, res: Response) => {
await getAllVehicleTypes(req, res);
});
router.get("/:id", async (req: Request, res: Response) => {
await getVehicleTypeById(req, res);
});
router.post(
"/",
PermissionHelper.passCheckMiddleware("create", "unit", "vehicle_type"),
async (req: Request, res: Response) => {
await createVehicleType(req, res);
}
);
router.patch(
"/:id",
PermissionHelper.passCheckMiddleware("update", "unit", "vehicle_type"),
async (req: Request, res: Response) => {
await updateVehicleTypeById(req, res);
}
);
router.delete(
"/:id",
PermissionHelper.passCheckMiddleware("delete", "unit", "vehicle_type"),
async (req: Request, res: Response) => {
await deleteVehicleTypeById(req, res);
}
);
export default router;

View file

@ -0,0 +1,50 @@
import express, { Request, Response } from "express";
import PermissionHelper from "../../../helpers/permissionHelper";
import {
createWearable,
deleteWearableById,
getAllWearables,
getWearableById,
getWearablesByIds,
updateWearableById,
} from "../../../controller/admin/unit/wearableController";
var router = express.Router({ mergeParams: true });
router.get("/", async (req: Request, res: Response) => {
await getAllWearables(req, res);
});
router.get("/:id", async (req: Request, res: Response) => {
await getWearableById(req, res);
});
router.post("/ids", async (req: Request, res: Response) => {
await getWearablesByIds(req, res);
});
router.post(
"/",
PermissionHelper.passCheckMiddleware("create", "unit", "wearable"),
async (req: Request, res: Response) => {
await createWearable(req, res);
}
);
router.patch(
"/:id",
PermissionHelper.passCheckMiddleware("update", "unit", "wearable"),
async (req: Request, res: Response) => {
await updateWearableById(req, res);
}
);
router.delete(
"/:id",
PermissionHelper.passCheckMiddleware("delete", "unit", "wearable"),
async (req: Request, res: Response) => {
await deleteWearableById(req, res);
}
);
export default router;

View file

@ -0,0 +1,45 @@
import express, { Request, Response } from "express";
import PermissionHelper from "../../../helpers/permissionHelper";
import {
createWearableType,
deleteWearableTypeById,
getAllWearableTypes,
getWearableTypeById,
updateWearableTypeById,
} from "../../../controller/admin/unit/wearableTypeController";
var router = express.Router({ mergeParams: true });
router.get("/", async (req: Request, res: Response) => {
await getAllWearableTypes(req, res);
});
router.get("/:id", async (req: Request, res: Response) => {
await getWearableTypeById(req, res);
});
router.post(
"/",
PermissionHelper.passCheckMiddleware("create", "unit", "wearable_type"),
async (req: Request, res: Response) => {
await createWearableType(req, res);
}
);
router.patch(
"/:id",
PermissionHelper.passCheckMiddleware("update", "unit", "wearable_type"),
async (req: Request, res: Response) => {
await updateWearableTypeById(req, res);
}
);
router.delete(
"/:id",
PermissionHelper.passCheckMiddleware("delete", "unit", "wearable_type"),
async (req: Request, res: Response) => {
await deleteWearableTypeById(req, res);
}
);
export default router;

View file

@ -14,6 +14,10 @@ router.get("/calendar", async (req, res) => {
await getCalendarItemsByTypes(req, res);
});
router.post("/reportdamage", async (req, res) => {
res.send("TODO");
});
router.get("/configuration", async (req, res) => {
await getApplicationConfig(req, res);
});

View file

@ -0,0 +1,96 @@
import { dataSource } from "../../data-source";
import { damageReport } from "../../entity/unit/damageReport";
import DatabaseActionException from "../../exceptions/databaseActionException";
export default abstract class DamageReportService {
private static query = () =>
dataSource
.getRepository(damageReport)
.createQueryBuilder("damageReport")
.leftJoinAndSelect("damageReport.equipment", "equipment")
.leftJoinAndSelect("damageReport.vehicle", "vehicle")
.leftJoinAndSelect("damageReport.wearable", "wearable")
.leftJoinAndSelect("damageReport.maintenance", "maintenance");
/**
* @description get all damageReports By done
* @returns {Promise<[Array<damageReport>, number]>}
*/
static async getAll(
done = false,
{
offset = 0,
count = 25,
noLimit = false,
}: {
offset?: number;
count?: number;
noLimit?: boolean;
}
): Promise<[Array<damageReport>, number]> {
let query = this.query().where({ done });
if (!noLimit) {
query = query.offset(offset).limit(count);
}
return await query
.orderBy("damageReport.reportedAt", "ASC")
.getManyAndCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "damageReport", err);
});
}
/**
* @description get all damageReports By related
* @returns {Promise<[Array<damageReport>, number]>}
*/
static async getAllForRelated(
where: { equipmentId: string } | { vehicleId: string } | { wearableId: string },
{
offset = 0,
count = 25,
noLimit = false,
}: {
offset?: number;
count?: number;
noLimit?: boolean;
}
): Promise<[Array<damageReport>, number]> {
let query = this.query().where(where);
if (!noLimit) {
query = query.offset(offset).limit(count);
}
return await query
.orderBy("damageReport.reportedAt", "ASC")
.getManyAndCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "damageReport", err);
});
}
/**
* @description get damageReport by id
* @returns {Promise<damageReport>}
*/
static async getById(id: string): Promise<damageReport> {
return await this.query()
.where({ id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "damageReport", err);
});
}
}

View file

@ -0,0 +1,79 @@
import { In, Like } from "typeorm";
import { dataSource } from "../../../data-source";
import { equipment } from "../../../entity/unit/equipment/equipment";
import DatabaseActionException from "../../../exceptions/databaseActionException";
export default abstract class EquipmentService {
/**
* @description get all equipment
* @returns {Promise<[Array<equipment>, number]>}
*/
static async getAll({
offset = 0,
count = 25,
search = "",
noLimit = false,
ids = [],
}: {
offset?: number;
count?: number;
search?: string;
noLimit?: boolean;
ids?: Array<string>;
}): Promise<[Array<equipment>, number]> {
let query = dataSource
.getRepository(equipment)
.createQueryBuilder("equipment")
.leftJoinAndSelect("equipment.equipmentType", "equipmenttype");
if (search != "") {
query = query
.where({
code: Like(`%${search}%`),
})
.orWhere({
name: Like(`%${search}%`),
})
.orWhere({
location: Like(`%${search}%`),
});
}
if (ids.length != 0) {
query = query.where({ id: In(ids) });
}
if (!noLimit) {
query = query.offset(offset).limit(count);
}
return await query
.orderBy("name", "ASC")
.getManyAndCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "equipment", err);
});
}
/**
* @description get equipment by id
* @returns {Promise<equipment>}
*/
static async getById(id: string): Promise<equipment> {
return await dataSource
.getRepository(equipment)
.createQueryBuilder("equipment")
.leftJoinAndSelect("equipment.equipmentType", "equipmenttype")
.where({ id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "equipment", err);
});
}
}

View file

@ -0,0 +1,65 @@
import { Like, In } from "typeorm";
import { dataSource } from "../../../data-source";
import { equipmentType } from "../../../entity/unit/equipment/equipmentType";
import DatabaseActionException from "../../../exceptions/databaseActionException";
export default abstract class EquipmentTypeService {
/**
* @description get all equipmentTypes
* @returns {Promise<[Array<equipmentType>, number]>}
*/
static async getAll({
offset = 0,
count = 25,
search = "",
noLimit = false,
}: {
offset?: number;
count?: number;
search?: string;
noLimit?: boolean;
}): Promise<[Array<equipmentType>, number]> {
let query = dataSource
.getRepository(equipmentType)
.createQueryBuilder("equipmentType")
.loadRelationCountAndMap("equipmentType.equipmentCount", "equipmentType.equipment");
if (search != "") {
query = query.where({
type: Like(`%${search}%`),
});
}
if (!noLimit) {
query = query.offset(offset).limit(count);
}
return await query
.orderBy("type", "ASC")
.getManyAndCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "equipmentType", err);
});
}
/**
* @description get equipmentType by id
* @returns {Promise<equipmentType>}
*/
static async getById(id: string): Promise<equipmentType> {
return await dataSource
.getRepository(equipmentType)
.createQueryBuilder("equipmentType")
.where({ id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "equipmentType", err);
});
}
}

View file

@ -0,0 +1,128 @@
import { Like, In } from "typeorm";
import { dataSource } from "../../../data-source";
import { inspectionPlan } from "../../../entity/unit/inspection/inspectionPlan";
import DatabaseActionException from "../../../exceptions/databaseActionException";
export default abstract class InspectionPlanService {
private static query = () =>
dataSource
.getRepository(inspectionPlan)
.createQueryBuilder("inspectionPlan")
.leftJoinAndMapOne(
"inspectionPlan.latestVersionedPlan",
"inspectionPlan.versionedPlans",
"latestVersionedPlan",
'latestVersionedPlan.inspectionPlanId = inspectionPlan.id AND latestVersionedPlan.version = (SELECT MAX("ivp"."version") FROM "inspection_versioned_plan" "ivp" WHERE "ivp"."inspectionPlanId" = "inspectionPlan"."id")'
)
.leftJoinAndSelect("latestVersionedPlan.inspectionPoints", "inspectionPoints")
.leftJoinAndSelect("inspectionPlan.equipmentType", "equipmentType")
.leftJoinAndSelect("inspectionPlan.vehicleType", "vehicleType")
.leftJoinAndSelect("inspectionPlan.wearableType", "wearableType");
/**
* @description get all inspectionPlans for related
* @returns {Promise<[Array<inspectionPlan>, number]>}
*/
static async getAll({
offset = 0,
count = 25,
search = "",
noLimit = false,
ids = [],
}: {
offset?: number;
count?: number;
search?: string;
noLimit?: boolean;
ids?: Array<string>;
}): Promise<[Array<inspectionPlan>, number]> {
let query = this.query();
if (search != "") {
query = query.where({
title: Like(`%${search}%`),
});
}
if (ids.length != 0) {
query = query.where({ id: In(ids) });
}
if (!noLimit) {
query = query.offset(offset).limit(count);
}
return await query
.orderBy("inspectionPlan.title", "ASC")
.getManyAndCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "inspectionPlan", err);
});
}
/**
* @description get all inspectionPlans for related
* @returns {Promise<[Array<inspectionPlan>, number]>}
*/
static async getAllForRelated(
where: { equipmentTypeId: string } | { vehicleTypeId: string } | { wearableTypeId: string },
{
offset = 0,
count = 25,
search = "",
noLimit = false,
ids = [],
}: {
offset?: number;
count?: number;
search?: string;
noLimit?: boolean;
ids?: Array<string>;
}
): Promise<[Array<inspectionPlan>, number]> {
let query = this.query().where(where);
if (search != "") {
query = query.andWhere({
title: Like(`%${search}%`),
});
}
if (ids.length != 0) {
query = query.andWhere({ id: In(ids) });
}
if (!noLimit) {
query = query.offset(offset).limit(count);
}
return await query
.orderBy("inspectionPlan.title", "ASC")
.getManyAndCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "inspectionPlan", err);
});
}
/**
* @description get inspectionPlan by id
* @returns {Promise<inspectionPlan>}
*/
static async getById(id: string): Promise<inspectionPlan> {
return await this.query()
.where({ id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "inspectionPlan", err);
});
}
}

View file

@ -0,0 +1,45 @@
import { dataSource } from "../../../data-source";
import { inspectionPointResult } from "../../../entity/unit/inspection/inspectionPointResult";
import DatabaseActionException from "../../../exceptions/databaseActionException";
export default abstract class InspectionPointResultService {
/**
* @description get all inspectionPointResults
* @returns {Promise<Array<inspectionPointResult>>}
*/
static async getAllForInspection(inspectionId: string): Promise<Array<inspectionPointResult>> {
return await dataSource
.getRepository(inspectionPointResult)
.createQueryBuilder("inspectionPointResult")
.leftJoinAndSelect("inspectionPointResult.inspectionPoint", "inspectionPoint")
.where({ inspectionId })
.getMany()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "inspectionPointResult", err);
});
}
/**
* @description get inspectionPointResults by inspection and point
* @returns {Promise<Array<inspectionPointResult>>}
*/
static async getForInspectionAndPoint(
inspectionId: string,
inspectionPointId: string
): Promise<inspectionPointResult> {
return await dataSource
.getRepository(inspectionPointResult)
.createQueryBuilder("inspectionPointResult")
.leftJoinAndSelect("inspectionPointResult.inspectionPoint", "inspectionPoint")
.where({ inspectionId, inspectionPointId })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "inspectionPointResult", err);
});
}
}

View file

@ -0,0 +1,42 @@
import { dataSource } from "../../../data-source";
import { inspectionPoint } from "../../../entity/unit/inspection/inspectionPoint";
import DatabaseActionException from "../../../exceptions/databaseActionException";
export default abstract class InspectionPointService {
/**
* @description get all inspectionPoints
* @returns {Promise<Array<inspectionPoint>>}
*/
static async getAllForVersionedPlan(versionedPlanId: string): Promise<Array<inspectionPoint>> {
return await dataSource
.getRepository(inspectionPoint)
.createQueryBuilder("inspectionPoint")
.where({ versionedPlanId })
.orderBy("sort", "ASC")
.getMany()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "inspectionPoint", err);
});
}
/**
* @description get inspectionPoint by id
* @returns {Promise<inspectionPoint>}
*/
static async getById(id: string): Promise<inspectionPoint> {
return await dataSource
.getRepository(inspectionPoint)
.createQueryBuilder("inspectionPoint")
.where({ id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "inspectionPoint", err);
});
}
}

View file

@ -0,0 +1,191 @@
import { IsNull, Not } from "typeorm";
import { dataSource } from "../../../data-source";
import { inspection } from "../../../entity/unit/inspection/inspection";
import DatabaseActionException from "../../../exceptions/databaseActionException";
export default abstract class InspectionService {
private static query = () =>
dataSource
.getRepository(inspection)
.createQueryBuilder("inspection")
.leftJoinAndSelect("inspection.inspectionPlan", "inspectionPlan")
.leftJoinAndSelect("inspectionPlan.equipmentType", "equipmentType")
.leftJoinAndSelect("inspectionPlan.vehicleType", "vehicleType")
.leftJoinAndSelect("inspectionPlan.wearableType", "wearableType")
.leftJoinAndSelect("inspection.inspectionVersionedPlan", "inspectionVersionedPlan")
.leftJoinAndSelect("inspectionVersionedPlan.inspectionPoints", "inspectionPoints")
.leftJoinAndSelect("inspection.pointResults", "pointResults")
.leftJoinAndSelect("pointResults.inspectionPoint", "inspectionPoint")
.leftJoinAndSelect("inspection.equipment", "equipment")
.leftJoinAndSelect("inspection.vehicle", "vehicle")
.leftJoinAndSelect("inspection.wearable", "wearable");
private static minifiedQuery = () =>
dataSource
.getRepository(inspection)
.createQueryBuilder("inspection")
.leftJoinAndSelect("inspection.inspectionPlan", "inspectionPlan")
.leftJoinAndSelect("inspectionPlan.equipmentType", "equipmentType")
.leftJoinAndSelect("inspectionPlan.vehicleType", "vehicleType")
.leftJoinAndSelect("inspectionPlan.wearableType", "wearableType")
.leftJoinAndSelect("inspection.equipment", "equipment")
.leftJoinAndSelect("inspection.vehicle", "vehicle")
.leftJoinAndSelect("inspection.wearable", "wearable");
/**
* @description get all inspections sorted by next inspection not having newer
* @returns {Promise<Array<inspection>>}
*/
static async getAllSortedNotHavingNewer({
offset = 0,
count = 25,
noLimit = false,
}: {
offset?: number;
count?: number;
noLimit?: boolean;
}): Promise<[Array<inspection>, number]> {
let query = this.query().where({ hasNewer: false });
if (!noLimit) {
query = query.offset(offset).limit(count);
}
return await query
.orderBy("inspection.nextInspection", "ASC", "NULLS LAST")
.getManyAndCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "inspection", err);
});
}
/**
* @description get all inspections running
* @returns {Promise<Array<inspection>>}
*/
static async getAllRunning({
offset = 0,
count = 25,
noLimit = false,
}: {
offset?: number;
count?: number;
noLimit?: boolean;
}): Promise<[Array<inspection>, number]> {
let query = this.minifiedQuery().where({ finishedAt: IsNull() });
if (!noLimit) {
query = query.offset(offset).limit(count);
}
return await query
.orderBy("inspection.createdAt", "ASC")
.getManyAndCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "inspection", err);
});
}
/**
* @description get all inspections for related
* @returns {Promise<Array<inspection>>}
*/
static async getAllForRelated(
where: { equipmentId: string } | { vehicleId: string } | { wearableId: string },
{
offset = 0,
count = 25,
noLimit = false,
}: {
offset?: number;
count?: number;
noLimit?: boolean;
}
): Promise<[Array<inspection>, number]> {
let query = this.minifiedQuery().where(where);
if (!noLimit) {
query = query.offset(offset).limit(count);
}
return await query
.orderBy("inspection.createdAt", "DESC")
.getManyAndCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "inspection", err);
});
}
/**
* @description get inspection by id
* @returns {Promise<inspection>}
*/
static async getById(id: string): Promise<inspection> {
return await this.query()
.where({ id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "inspection", err);
});
}
/**
* @description uses versionedPlan
* @returns {Promise<boolean>}
*/
static async existsUnfinishedInspectionToPlan(
inspectionPlanId: string,
relation: "vehicle" | "equipment" | "wearable",
relationId: string
): Promise<boolean> {
let where: { equipmentId: string } | { vehicleId: string } | { wearableId: string };
if (relation == "equipment") {
where = { equipmentId: relationId };
} else if (relation == "vehicle") {
where = { vehicleId: relationId };
} else {
where = { wearableId: relationId };
}
return await dataSource
.getRepository(inspection)
.createQueryBuilder("inspection")
.where({ inspectionPlanId, finishedAt: IsNull(), ...where })
.getExists()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "used inspection", err);
});
}
/**
* @description uses versionedPlan
* @returns {Promise<boolean>}
*/
static async usesVersionedInspectionPlan(inspectionVersionedPlanId: string): Promise<boolean> {
return await dataSource
.getRepository(inspection)
.createQueryBuilder("inspection")
.where({ inspectionVersionedPlanId })
.getExists()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "used inspection", err);
});
}
}

View file

@ -0,0 +1,83 @@
import { dataSource } from "../../../data-source";
import { inspectionVersionedPlan } from "../../../entity/unit/inspection/inspectionVersionedPlan";
import DatabaseActionException from "../../../exceptions/databaseActionException";
export default abstract class InspectionVersionedPlanService {
/**
* @description get all inspectionVersionedPlans
* @returns {Promise<Array<inspectionVersionedPlan>>}
*/
static async getAllForInspectionPlan(inspectionPlanId: string): Promise<Array<inspectionVersionedPlan>> {
return await dataSource
.getRepository(inspectionVersionedPlan)
.createQueryBuilder("inspectionVersionedPlan")
.leftJoinAndSelect("inspectionVersionedPlan.inspectionPoints", "inspectionPoints")
.where({ inspectionPlanId })
.orderBy("version", "ASC")
.getMany()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "inspectionVersionedPlan", err);
});
}
/**
* @description get latest inspectionVersionedPlan for plan
* @returns {Promise<Array<inspectionVersionedPlan>>}
*/
static async getLatestForInspectionPlan(inspectionPlanId: string): Promise<inspectionVersionedPlan> {
return await dataSource
.getRepository(inspectionVersionedPlan)
.createQueryBuilder("inspectionVersionedPlan")
.leftJoinAndSelect("inspectionVersionedPlan.inspectionPoints", "inspectionPoints")
.where({ inspectionPlanId })
.orderBy("inspectionVersionedPlan.version", "DESC")
.limit(1)
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "inspectionVersionedPlan", err);
});
}
/**
* @description get inspectionVersionedPlan by id
* @returns {Promise<inspectionVersionedPlan>}
*/
static async getById(id: string): Promise<inspectionVersionedPlan> {
return await dataSource
.getRepository(inspectionVersionedPlan)
.createQueryBuilder("inspectionVersionedPlan")
.leftJoinAndSelect("inspectionVersionedPlan.inspectionPoints", "inspectionPoints")
.where({ id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "inspectionVersionedPlan", err);
});
}
/**
* @description count for plan id
* @returns {Promise<number>}
*/
static async countForPlanId(planId: string): Promise<number> {
return await dataSource
.getRepository(inspectionVersionedPlan)
.createQueryBuilder("inspectionVersionedPlan")
.where({ inspectionPlanId: planId })
.getCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "inspectionVersionedPlan", err);
});
}
}

View file

@ -0,0 +1,95 @@
import { dataSource } from "../../data-source";
import { maintenance } from "../../entity/unit/maintenance";
import DatabaseActionException from "../../exceptions/databaseActionException";
export default abstract class MaintenanceService {
private static query = () =>
dataSource
.getRepository(maintenance)
.createQueryBuilder("maintenance")
.leftJoinAndSelect("maintenance.equipment", "equipment")
.leftJoinAndSelect("maintenance.vehicle", "vehicle")
.leftJoinAndSelect("maintenance.wearable", "wearable")
.leftJoinAndSelect("maintenance.reports", "reports");
/**
* @description get all maintenances
* @returns {Promise<[Array<maintenance>, number]>}
*/
static async getAll(
done = false,
{
offset = 0,
count = 25,
noLimit = false,
}: {
offset?: number;
count?: number;
noLimit?: boolean;
}
): Promise<[Array<maintenance>, number]> {
let query = this.query().where({ done });
if (!noLimit) {
query = query.offset(offset).limit(count);
}
return await query
.orderBy("maintenance.createdAt", "ASC")
.getManyAndCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "maintenance", err);
});
}
/**
* @description get all maintenances By related
* @returns {Promise<[Array<maintenance>, number]>}
*/
static async getAllForRelated(
where: { equipmentId: string } | { vehicleId: string } | { wearableId: string },
{
offset = 0,
count = 25,
noLimit = false,
}: {
offset?: number;
count?: number;
noLimit?: boolean;
}
): Promise<[Array<maintenance>, number]> {
let query = this.query().where(where);
if (!noLimit) {
query = query.offset(offset).limit(count);
}
return await query
.orderBy("maintenance.createdAt", "ASC")
.getManyAndCount()
.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 this.query()
.where({ id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "maintenance", err);
});
}
}

View file

@ -0,0 +1,79 @@
import { Like, In } from "typeorm";
import { dataSource } from "../../../data-source";
import { vehicle } from "../../../entity/unit/vehicle/vehicle";
import DatabaseActionException from "../../../exceptions/databaseActionException";
export default abstract class VehicleService {
/**
* @description get all vehicles
* @returns {Promise<[Array<vehicle>, number]>}
*/
static async getAll({
offset = 0,
count = 25,
search = "",
noLimit = false,
ids = [],
}: {
offset?: number;
count?: number;
search?: string;
noLimit?: boolean;
ids?: Array<string>;
}): Promise<[Array<vehicle>, number]> {
let query = dataSource
.getRepository(vehicle)
.createQueryBuilder("vehicle")
.leftJoinAndSelect("vehicle.vehicleType", "vehicletype");
if (search != "") {
query = query
.where({
code: Like(`%${search}%`),
})
.orWhere({
name: Like(`%${search}%`),
})
.orWhere({
location: Like(`%${search}%`),
});
}
if (ids.length != 0) {
query = query.where({ id: In(ids) });
}
if (!noLimit) {
query = query.offset(offset).limit(count);
}
return await query
.orderBy("name", "ASC")
.getManyAndCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "vehicle", err);
});
}
/**
* @description get vehicle by id
* @returns {Promise<vehicle>}
*/
static async getById(id: string): Promise<vehicle> {
return await dataSource
.getRepository(vehicle)
.createQueryBuilder("vehicle")
.leftJoinAndSelect("vehicle.vehicleType", "vehicletype")
.where({ id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "vehicle", err);
});
}
}

View file

@ -0,0 +1,65 @@
import { Like, In } from "typeorm";
import { dataSource } from "../../../data-source";
import { vehicleType } from "../../../entity/unit/vehicle/vehicleType";
import DatabaseActionException from "../../../exceptions/databaseActionException";
export default abstract class VehicleTypeService {
/**
* @description get all vehicleTypes
* @returns {Promise<[Array<vehicleType>, number]>}
*/
static async getAll({
offset = 0,
count = 25,
search = "",
noLimit = false,
}: {
offset?: number;
count?: number;
search?: string;
noLimit?: boolean;
}): Promise<[Array<vehicleType>, number]> {
let query = dataSource
.getRepository(vehicleType)
.createQueryBuilder("vehicleType")
.loadRelationCountAndMap("vehicleType.vehicleCount", "vehicleType.vehicle");
if (search != "") {
query = query.where({
type: Like(`%${search}%`),
});
}
if (!noLimit) {
query = query.offset(offset).limit(count);
}
return await query
.orderBy("type", "ASC")
.getManyAndCount()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "vehicleType", err);
});
}
/**
* @description get vehicleType by id
* @returns {Promise<vehicleType>}
*/
static async getById(id: string): Promise<vehicleType> {
return await dataSource
.getRepository(vehicleType)
.createQueryBuilder("vehicleType")
.where({ id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new DatabaseActionException("SELECT", "vehicleType", err);
});
}
}

Some files were not shown because too many files have changed in this diff Show more