diff --git a/src/controllers/inpatient_room.ts b/src/controllers/inpatient_room.ts index 8234e6c..e0fc36b 100644 --- a/src/controllers/inpatient_room.ts +++ b/src/controllers/inpatient_room.ts @@ -1,4 +1,4 @@ -import { Paging, InpatientRoom, Room } from "entity"; +import { Paging, InpatientRoom, Room, InpatientRoomBed, InpatientRoomBedStatus } from "entity"; import { NextFunction, Response } from "express"; import { Request } from "express-jwt"; import Joi from "joi"; @@ -117,6 +117,9 @@ export class InpatientRoomController { } */ + const queryRunner = OrmHelper.DB.createQueryRunner(); + await queryRunner.startTransaction(); + try { const schema = Joi.object().keys({ room_id: Joi.string().uuid().required().label("Room ID"), @@ -135,14 +138,27 @@ export class InpatientRoomController { data.number_of_bed = param.number_of_bed; data.created_by = req.auth?.data.name; - await OrmHelper.DB.manager.save(data); + await queryRunner.manager.save(data); + + for (let i = 1; i <= param.number_of_bed; i++) { + const bed = new InpatientRoomBed(); + bed.inpatient_room = data; + bed.number = i; + bed.status = InpatientRoomBedStatus.Empty; + bed.created_by = req.auth?.data.name; + await queryRunner.manager.save(bed); + } + + await queryRunner.commitTransaction(); return ReturnHelper.successResponseAny(res, 200, Language.lang.success_insert, data); } catch (e: unknown) { + await queryRunner.rollbackTransaction(); log.error(e); const err = e as Error; - return ReturnHelper.errorResponse(res, 400, 401, Language.lang.failed_insert, err.message); + } finally { + await queryRunner.release(); } } @@ -186,26 +202,26 @@ export class InpatientRoomController { static async update(req: Request, res: Response, next: NextFunction): Promise { /* - #swagger.tags = ['Inpatient Room'] - #swagger.security = [{ - "bearerAuth": [] - }] - #swagger.parameters['id'] = { - description:'', - in: 'path', - type: 'string' - } - #swagger.requestBody = { - required: true, - content: { - "application/json": { - schema: { - $ref: "#/components/schemas/inpatient_room" - } - } - } - } - */ + #swagger.tags = ['Inpatient Room'] + #swagger.security = [{ + "bearerAuth": [] + }] + #swagger.parameters['id'] = { + description:'', + in: 'path', + type: 'string' + } + #swagger.requestBody = { + required: true, + content: { + "application/json": { + schema: { + $ref: "#/components/schemas/inpatient_room" + } + } + } + } + */ const queryRunner = OrmHelper.DB.createQueryRunner(); await queryRunner.startTransaction(); @@ -228,10 +244,71 @@ export class InpatientRoomController { let room: Room = await RoomModel.list({ id: param.room_id }).then((q) => q.getOne()); if (!room) throw { message: "Room " + Language.lang.failed_not_found }; + const newNumberOfBed: number = param.number_of_bed; + const authName = req.auth?.data?.name; + + const existingBeds = await queryRunner.manager + .getRepository(InpatientRoomBed) + .createQueryBuilder("bed") + .leftJoinAndSelect("bed.boarding_room", "boarding_room") + .leftJoin("bed.inpatient_room", "inpatient_room") + .where("inpatient_room.id = :roomId", { roomId: param.id }) + .andWhere("bed.deleted_at IS NULL") + .orderBy("bed.number", "DESC") + .getMany(); + + const occupiedCount = existingBeds.filter((bed) => bed.boarding_room != null).length; + if (occupiedCount > newNumberOfBed) { + throw { message: "Update gagal, masih ada bed yang sedang digunakan" }; + } + + if (existingBeds.length > newNumberOfBed) { + let remainingToDelete = existingBeds.length - newNumberOfBed; + + for (const bed of existingBeds) { + if (remainingToDelete <= 0) break; + if (bed.boarding_room != null) continue; + + await queryRunner.manager.update(InpatientRoomBed, { id: bed.id }, { deleted_by: authName }); + await queryRunner.manager.softDelete(InpatientRoomBed, { id: bed.id }); + remainingToDelete--; + } + + if (remainingToDelete > 0) { + throw { message: "Update gagal, masih ada bed yang sedang digunakan" }; + } + } + + const activeBeds = await queryRunner.manager + .getRepository(InpatientRoomBed) + .createQueryBuilder("bed") + .leftJoin("bed.inpatient_room", "inpatient_room") + .where("inpatient_room.id = :roomId", { roomId: param.id }) + .andWhere("bed.deleted_at IS NULL") + .getMany(); + + if (activeBeds.length < newNumberOfBed) { + const usedNumbers = activeBeds.map((bed) => bed.number); + let added = 0; + const toAdd = newNumberOfBed - activeBeds.length; + + for (let i = 1; i <= newNumberOfBed && added < toAdd; i++) { + if (usedNumbers.includes(i)) continue; + + const bed = new InpatientRoomBed(); + bed.inpatient_room = inpatientRoom; + bed.number = i; + bed.status = InpatientRoomBedStatus.Empty; + bed.created_by = authName; + await queryRunner.manager.save(bed); + added++; + } + } + inpatientRoom.room = room; inpatientRoom.name = param.name; - inpatientRoom.number_of_bed = param.number_of_bed; - inpatientRoom.updated_by = req.auth?.data.name; + inpatientRoom.number_of_bed = newNumberOfBed; + inpatientRoom.updated_by = authName; await queryRunner.manager.save(inpatientRoom);