diff --git a/src/controllers/service_fare.ts b/src/controllers/service_fare.ts index e6dc424..d6b8aa2 100644 --- a/src/controllers/service_fare.ts +++ b/src/controllers/service_fare.ts @@ -1,4 +1,4 @@ -import { ServiceFare, Paging } from "entity"; +import { ServiceFare, ServiceClass, Service, FareType, Paging } from "entity"; import { NextFunction, Response } from "express"; import { Request } from "express-jwt"; import Joi from "joi"; @@ -75,6 +75,67 @@ export class ServiceFareController { } } + static async option(req: Request, res: Response, next: NextFunction): Promise { + /* + #swagger.tags = ['Service Fare'] + #swagger.security = [{ "bearerAuth": [] }] + */ + try { + const [services, fareTypes, serviceClasses] = await Promise.all([ + OrmHelper.DB.getRepository(Service) + .createQueryBuilder("Service") + .select(["Service.id", "Service.name"]) + .getMany(), + + OrmHelper.DB.getRepository(FareType) + .createQueryBuilder("FareType") + .select(["FareType.id", "FareType.name"]) + .getMany(), + + OrmHelper.DB.getRepository(ServiceClass) + .createQueryBuilder("ServiceClass") + .select(["ServiceClass.id", "ServiceClass.name"]) + .getMany(), + ]); + + // Semua FareType dapat semua ServiceClass + const fareTypesWithClass = fareTypes.map((ft) => ({ + id: ft.id, + name: ft.name, + service_class: serviceClasses.map((sc) => ({ + id: sc.id, + name: sc.name, + })), + })); + + // Semua Service dapat semua FareType (yang sudah berisi ServiceClass) + const list_data = services.map((svc) => ({ + service: { + id: svc.id, + name: svc.name, + faretype: fareTypesWithClass, + }, + })); + + const total_count_data = list_data.length; + const count_data = CommonHelper.countObject(list_data); + + return ReturnHelper.successResponselist( + res, 200, + Language.lang.success_view, + count_data, + 1, + total_count_data, + list_data + ); + + } catch (e: unknown) { + log.error(e); + const err = e as Error; + return ReturnHelper.errorResponse(res, 400, 401, Language.lang.failed_view, err.message); + } + } + static async create(req: Request, res: Response, next: NextFunction): Promise { /* #swagger.tags = ['Service Fare'] @@ -85,42 +146,62 @@ export class ServiceFareController { await queryRunner.startTransaction(); try { const schema = Joi.object().keys({ - service_class_id: Joi.string().uuid().required().label("Service Class ID"), service_id: Joi.string().uuid().required().label("Service ID"), - fare: Joi.number().min(0).required().label("Fare"), - faretype: Joi.string().uuid().required().label("Fare Type ID"), + faretype: Joi.array().items( + Joi.object().keys({ + faretype_id: Joi.string().uuid().required().label("Fare Type ID"), + service_class: Joi.array().items( + Joi.object().keys({ + service_class_id: Joi.string().uuid().required().label("Service Class ID"), + fare: Joi.number().min(0).allow(null).label("Fare"), + }) + ).min(1).required().label("Service Class"), + }) + ).min(1).required().label("Fare Type"), }); let param: any = await schema.validateAsync(req.body); - let serviceClass = await ServiceClassModel.list({ "ServiceClass.id": param.service_class_id }).then((q) => q.getOne()); - if (!serviceClass) throw { message: "Service Class not found" }; - + // Validasi Service let service = await ServiceModel.list({ "Service.id": param.service_id }).then((q) => q.getOne()); if (!service) throw { message: "Service not found" }; - let fareType = await OrmHelper.DB.getRepository("FareType").createQueryBuilder("FareType").where("FareType.id = :id", { id: param.faretype }).getOne(); - if (!fareType) throw { message: "Fare Type not found" }; + const savedServiceFares: ServiceFare[] = []; - // let filter = { - // serviceClassId: param.service_class_id, - // serviceId: param.service_id, - // }; - // let exist = await ServiceFareModel.list(filter).then((q) => q.getOne()); - // if (exist) throw { message: "Service Fare " + Language.lang.failed_duplicate }; + // Loop tiap faretype + for (const ft of param.faretype) { - let serviceFare = new ServiceFare(); - serviceFare.serviceClass = serviceClass; - serviceFare.service = service; - serviceFare.fare = String(param.fare); - serviceFare.faretype = param.faretype; - serviceFare.created_by = req.auth.data.name; - serviceFare.updated_by = req.auth.data.name; - await queryRunner.manager.save(serviceFare); + // Validasi FareType + let fareType = await OrmHelper.DB.getRepository("FareType") + .createQueryBuilder("FareType") + .where("FareType.id = :id", { id: ft.faretype_id }) + .getOne(); + if (!fareType) throw { message: `Fare Type ID ${ft.faretype_id} not found` }; + + // Loop tiap service_class dalam faretype ini + for (const sc of ft.service_class) { + + // Validasi ServiceClass + let serviceClass = await ServiceClassModel.list({ "ServiceClass.id": sc.service_class_id }).then((q) => q.getOne()); + if (!serviceClass) throw { message: `Service Class ID ${sc.service_class_id} not found` }; + + let serviceFare = new ServiceFare(); + serviceFare.service = service; + serviceFare.faretype = ft.faretype_id; + serviceFare.serviceClass = serviceClass; + serviceFare.fare = String(sc.fare ?? 0); + serviceFare.created_by = req.auth.data.name; + serviceFare.updated_by = req.auth.data.name; + + const saved = await queryRunner.manager.save(serviceFare); + savedServiceFares.push(saved); + } + } await queryRunner.commitTransaction(); - return ReturnHelper.successResponseAny(res, 200, Language.lang.success_insert, serviceFare); + return ReturnHelper.successResponseAny(res, 200, Language.lang.success_insert, savedServiceFares); + } catch (e: unknown) { await queryRunner.rollbackTransaction(); log.error(e); @@ -170,47 +251,69 @@ export class ServiceFareController { await queryRunner.startTransaction(); try { - req.body.id = req.params["id"]; - const schema = Joi.object().keys({ - id: Joi.string().uuid().required().label("Service Fare ID"), - service_class_id: Joi.string().uuid().required().label("Service Class ID"), service_id: Joi.string().uuid().required().label("Service ID"), - fare: Joi.number().min(0).required().label("Fare"), - faretype: Joi.string().uuid().required().label("Fare Type ID"), + faretype: Joi.array().items( + Joi.object().keys({ + faretype_id: Joi.string().uuid().required().label("Fare Type ID"), + service_class: Joi.array().items( + Joi.object().keys({ + service_class_id: Joi.string().uuid().required().label("Service Class ID"), + fare: Joi.number().min(0).allow(null).label("Fare"), + }) + ).min(1).required().label("Service Class"), + }) + ).min(1).required().label("Fare Type"), }); let param: any = await schema.validateAsync(req.body); - let serviceClass = await ServiceClassModel.list({ "ServiceClass.id": param.service_class_id }).then((q) => q.getOne()); - if (!serviceClass) throw { message: "Service Class not found" }; - + // Validasi Service let service = await ServiceModel.list({ "Service.id": param.service_id }).then((q) => q.getOne()); if (!service) throw { message: "Service not found" }; - let serviceFare = await ServiceFareModel.list({ "ServiceFare.id": param.id }).then((q) => q.getOne()); - if (!serviceFare) throw { message: "Service Fare " + Language.lang.failed_not_found }; + // Hapus semua row lama berdasarkan service_id + const existingFares = await ServiceFareModel.list({ "ServiceFare.serviceId": param.service_id }).then((q) => q.getMany()); + if (existingFares.length > 0) { + await queryRunner.manager.remove(existingFares); + } - let fareType = await OrmHelper.DB.getRepository("FareType").createQueryBuilder("FareType").where("FareType.id = :id", { id: param.faretype }).getOne(); - if (!fareType) throw { message: "Fare Type not found" }; + const savedServiceFares: ServiceFare[] = []; - // let filter = { - // serviceClassId: param.service_class_id, - // serviceId: param.service_id, - // }; - // let exist = await ServiceFareModel.list(filter).then((q) => q.getOne()); - // if (exist && exist.id != param.id) throw { message: "Service Fare " + Language.lang.failed_duplicate }; + // Loop tiap faretype + for (const ft of param.faretype) { - serviceFare.serviceClass = serviceClass; - serviceFare.service = service; - serviceFare.fare = String(param.fare); - serviceFare.faretype = param.faretype; - serviceFare.updated_by = req.auth.data.name; - await queryRunner.manager.save(serviceFare); + // Validasi FareType + let fareType = await OrmHelper.DB.getRepository("FareType") + .createQueryBuilder("FareType") + .where("FareType.id = :id", { id: ft.faretype_id }) + .getOne(); + if (!fareType) throw { message: `Fare Type ID ${ft.faretype_id} not found` }; + + // Loop tiap service_class dalam faretype ini + for (const sc of ft.service_class) { + + // Validasi ServiceClass + let serviceClass = await ServiceClassModel.list({ "ServiceClass.id": sc.service_class_id }).then((q) => q.getOne()); + if (!serviceClass) throw { message: `Service Class ID ${sc.service_class_id} not found` }; + + let serviceFare = new ServiceFare(); + serviceFare.service = service; + serviceFare.faretype = ft.faretype_id; + serviceFare.serviceClass = serviceClass; + serviceFare.fare = String(sc.fare ?? 0); + serviceFare.created_by = req.auth.data.name; + serviceFare.updated_by = req.auth.data.name; + + const saved = await queryRunner.manager.save(serviceFare); + savedServiceFares.push(saved); + } + } await queryRunner.commitTransaction(); - return ReturnHelper.successResponseAny(res, 200, Language.lang.success_update, serviceFare); + return ReturnHelper.successResponseAny(res, 200, Language.lang.success_update, savedServiceFares); + } catch (e: unknown) { await queryRunner.rollbackTransaction(); log.error(e); diff --git a/src/routes/private.ts b/src/routes/private.ts index 4d7918c..20dd6dc 100644 --- a/src/routes/private.ts +++ b/src/routes/private.ts @@ -182,6 +182,7 @@ export class RoutePrivate { app.put('/api/service/restore/:id', ServiceController.restore) app.get('/api/service-fare/list', ServiceFareController.list) + app.get('/api/service-fare/option', ServiceFareController.option) app.post('/api/service-fare/create', ServiceFareController.create) app.get('/api/service-fare/detail/:id', ServiceFareController.detail) app.put('/api/service-fare/update/:id', ServiceFareController.update) diff --git a/src/swagger/builder.js b/src/swagger/builder.js index 83d1ade..526ed7d 100644 --- a/src/swagger/builder.js +++ b/src/swagger/builder.js @@ -146,10 +146,18 @@ const doc = { $service_ids: ["uuid-string"], }, serviceFare: { - $service_class_id: "uuid-string", $service_id: "uuid-string", - $faretype: "uuid-string", - $fare: 100000, + $faretype: [ + { + $faretype_id: "uuid-string", + $service_class: [ + { + $service_class_id: "uuid-string", + $fare: 100000, + } + ] + } + ] }, servicePackage: { $name: "Package name",