diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index 35e14f97..bc63e568 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -4659,6 +4659,8 @@ export class ProfileController extends Controller { @Query() nodeId?: string, @Query() isAll?: boolean, @Query() retireType?: string, + @Query() sortBy: string = "posMasterNo", + @Query() sort: "ASC"|"DESC" = "ASC", ) { let _data = await new permission().PermissionOrgList(request, "SYS_REGISTRY_OFFICER"); let queryLike = @@ -4814,7 +4816,8 @@ export class ProfileController extends Controller { ); }), ) - .orderBy("current_holders.posMasterNo", "ASC") + // .orderBy("current_holders.posMasterNo", "ASC") + .orderBy(`current_holders.${sortBy}`, sort) .skip((page - 1) * pageSize) .take(pageSize) .getManyAndCount(); @@ -4907,6 +4910,7 @@ export class ProfileController extends Controller { id: _data.id, avatar: _data.avatar, avatarName: _data.avatarName, + dateAppoint: _data.dateAppoint, prefix: _data.prefix, rank: _data.rank, firstName: _data.firstName, diff --git a/src/controllers/ProfileEmployeeController.ts b/src/controllers/ProfileEmployeeController.ts index e02c8584..e12101d0 100644 --- a/src/controllers/ProfileEmployeeController.ts +++ b/src/controllers/ProfileEmployeeController.ts @@ -1704,6 +1704,8 @@ export class ProfileEmployeeController extends Controller { @Query() nodeId?: string, @Query() isAll?: boolean, @Query() retireType?: string, + @Query() sortBy: string = "posMasterNo", + @Query() sort: "ASC"|"DESC" = "ASC", ) { let _data = await new permission().PermissionOrgList(request, "SYS_REGISTRY_EMP"); let queryLike = @@ -1860,7 +1862,8 @@ export class ProfileEmployeeController extends Controller { // .andWhere(`current_holders.orgRevisionId LIKE :orgRevisionId`, { // orgRevisionId: findRevision.id, // }) - .orderBy("current_holders.posMasterNo", "ASC") + // .orderBy("current_holders.posMasterNo", "ASC") + .orderBy(`current_holders.${sortBy}`, sort) .skip((page - 1) * pageSize) .take(pageSize) .getManyAndCount(); diff --git a/src/controllers/ReportController.ts b/src/controllers/ReportController.ts index d06d821c..94422c94 100644 --- a/src/controllers/ReportController.ts +++ b/src/controllers/ReportController.ts @@ -13,7 +13,7 @@ import { AppDataSource } from "../database/data-source"; import HttpSuccess from "../interfaces/http-success"; import HttpStatusCode from "../interfaces/http-status"; import HttpError from "../interfaces/http-error"; -import { In, LessThan } from "typeorm"; +import { In, LessThan, Brackets } from "typeorm"; import { OrgRevision } from "../entities/OrgRevision"; import { OrgRoot } from "../entities/OrgRoot"; import { OrgChild1 } from "../entities/OrgChild1"; @@ -28,6 +28,8 @@ import Extension from "../interfaces/extension"; import { LeaveType } from "../entities/LeaveType"; import HttpStatus from "../interfaces/http-status"; import { Profile } from "../entities/Profile"; +import { viewRegistryOfficer } from "../entities/view/viewRegistryOfficer"; +import { viewRegistryEmployee } from "../entities/view/viewRegistryEmployee"; @Route("api/v1/org/report") @Tags("Report") @Security("bearerAuth") @@ -47,238 +49,514 @@ export class ReportController extends Controller { private posMasterRepository = AppDataSource.getRepository(PosMaster); private profileRepository = AppDataSource.getRepository(Profile); private empPosMasterRepository = AppDataSource.getRepository(EmployeePosMaster); + /** * API รายงานสถิติข้อมูลข้าราชการ กทม. สามัญ * * @summary รายงานสถิติข้อมูลข้าราชการ กทม. สามัญ * */ + // @Get("registry-officer") + // async registryOfficer( + // @Query() rootId?: string, + // @Query() year?: number, + // @Query() ageMin?: number, + // @Query() ageMax?: number, + // ) { + // if (ageMin && (ageMin < 18 || ageMin > 60)) { + // throw new HttpError(HttpStatus.BAD_REQUEST, "ageMin must be between 18 and 60"); + // } + + // if (ageMax && (ageMax < 18 || ageMax > 60)) { + // throw new HttpError(HttpStatus.BAD_REQUEST, "ageMax must be between 18 and 60"); + // } + + // const minAge = ageMin ?? 18; + // const maxAge = ageMax ?? 60; + + // if (minAge > maxAge) { + // throw new HttpError(HttpStatus.NOT_FOUND, "ageMin cannot be greater than ageMax"); + // } + // const yearInAD = year ? year : null; + // const currentRevision = await this.orgRevisionRepository.findOne({ + // where: { + // orgRevisionIsCurrent: true, + // }, + // }); + // const rawdataProfile = await this.posMasterRepository + // .createQueryBuilder('posMaster') + // .leftJoinAndSelect('posMaster.current_holder', 'current_holder') + // .leftJoinAndSelect('posMaster.positions', 'positions') + // .leftJoinAndSelect('posMaster.orgRoot', 'orgRoot') + // .leftJoinAndSelect('positions.posExecutive', 'posExecutive') + // .leftJoinAndSelect('current_holder.posType', 'posType') + // .leftJoinAndSelect('current_holder.posLevel', 'posLevel') + // .leftJoinAndSelect('current_holder.profileEducations', 'profileEducations') + // .where('posMaster.orgRevisionId = :currentRevisionId', { currentRevisionId: currentRevision?.id }) + // .andWhere(rootId?'posMaster.orgRootId = :rootId': "1=1", { rootId: rootId }) + // .andWhere('posMaster.current_holderId Is Not Null') + // .andWhere('positions.positionIsSelected = :positionIsSelected', { positionIsSelected: true }) + // .andWhere( yearInAD && yearInAD != null? 'YEAR(current_holder.dateAppoint) = :year': "1=1", { year: yearInAD }) //ตอนนี้ where ที่วันที่บรรจุ (รอ prove) ว่าจะ where ที่ไหน + // .andWhere(` + // TIMESTAMPDIFF(YEAR, current_holder.birthDate, CURDATE()) >= :minAge + // AND TIMESTAMPDIFF(YEAR, current_holder.birthDate, CURDATE()) <= :maxAge + // `, + // { minAge, maxAge }, + // ) + // .orderBy("posType.posTypeName", "ASC") + // .getMany(); + // if (!rawdataProfile) { + // throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); + // } + // const mapData = rawdataProfile.map((x) => { + // const latestEducation = x.current_holder.profileEducations.sort( + // (a: any, b: any) => b.endDate - a.startDate, + // )[0]; + // return { + // name: x.current_holder.firstName + " " + x.current_holder.lastName, + // affiliation: x.orgRoot.orgRootName ?? "-", + // gender: x.current_holder.gender ?? "-", + // positionName: x.positions[0] ? x.positions[0].positionName : "-", + // status: x.current_holder.relationship ?? "-", + // posType: x.current_holder.posType.posTypeName ?? "-", + // posLevel: x.current_holder.posLevel.posLevelName ?? "-", + // degree: latestEducation ? latestEducation.educationLevel : "-", + // posExecutive: x.positions[0].posExecutive + // ? x.positions[0].posExecutive.posExecutiveName + // : "-", + // currentPreiodPos: "-", + // levelPeriodPos: "-", + // }; + // }); + + // const groupedData = mapData.reduce((acc: any, item) => { + // const key = `${item.posType} - ${item.affiliation} - ${item.gender} - ${item.degree || "ไม่พบข้อมูล"} - ${item.status || "ไม่พบข้อมูล"} - ${item.positionName} - ${item.posLevel} - ${item.posExecutive || "ไม่พบข้อมูล"} `; + // if (!acc[key]) { + // acc[key] = { + // posType: item.posType && item.posType != "" ? item.posType : "-", + // affiliation: item.affiliation && item.affiliation != "" ? item.affiliation : "-", + // gender: item.gender && item.gender != "" ? item.gender : "-", + // degree: item.degree && item.degree != "" ? item.degree : "-", + // status: item.status && item.status != "" ? item.status : "-", + // positionName: item.positionName && item.positionName != "" ? item.positionName : "-", + // posLevel: item.posLevel && item.posLevel != "" ? item.posLevel : "-", + // posExecutive: item.posExecutive && item.posExecutive != "" ? item.posExecutive : "-", + // currentPreiodPos: "-", + // levelPeriodPos: "-", + // count: 0, + // }; + // } + // acc[key].count++; + + // return acc; + // }, {}); + + // const result = Object.values(groupedData).map((item: any) => ({ + // ...item, + // count: Extension.ToThaiNumber(item.count.toString()), + // })); + // return new HttpSuccess({ + // template: "registry-officer", + // reportName: "xlsx-report", + // data: { + // year: year + // ? Extension.ToThaiNumber((year + 543).toString()) + // : Extension.ToThaiNumber((new Date().getFullYear() + 543).toString()), + // date: Extension.ToThaiNumber(Extension.ToThaiShortDate(new Date())), + // list: result, + // }, + // }); + // } + @Get("registry-officer") async registryOfficer( - @Query() rootId?: string, - @Query() year?: number, + @Query() node?: number, + @Query() nodeId?: string, + @Query() posTypeName?: string, + @Query() posLevelName?: string, + @Query() position?: string, + @Query() posExecutiveName?: string, + @Query() gender?: string, + @Query() relationship?: string, + @Query() degree?: string, + @Query() startDateAppoint?: Date, + @Query() endDateAppoint?: Date, @Query() ageMin?: number, @Query() ageMax?: number, + @Query() sortBy: string = "posMasterNo", + @Query() sort: "ASC"|"DESC" = "ASC", ) { if (ageMin && (ageMin < 18 || ageMin > 60)) { - throw new HttpError(HttpStatus.BAD_REQUEST, "ageMin must be between 18 and 60"); + throw new HttpError(HttpStatus.NOT_FOUND, "ageMin must be between 18 and 60"); } - if (ageMax && (ageMax < 18 || ageMax > 60)) { - throw new HttpError(HttpStatus.BAD_REQUEST, "ageMax must be between 18 and 60"); + throw new HttpError(HttpStatus.NOT_FOUND, "ageMax must be between 18 and 60"); } - - const minAge = ageMin ?? 18; - const maxAge = ageMax ?? 60; - - if (minAge > maxAge) { + if (ageMin && ageMax && (ageMin > ageMax)) { throw new HttpError(HttpStatus.NOT_FOUND, "ageMin cannot be greater than ageMax"); } - const yearInAD = year ? year : null; - const currentRevision = await this.orgRevisionRepository.findOne({ - where: { - orgRevisionIsCurrent: true, - }, - }); - const rawdataProfile = await this.posMasterRepository - .createQueryBuilder('posMaster') - .leftJoinAndSelect('posMaster.current_holder', 'current_holder') - .leftJoinAndSelect('posMaster.positions', 'positions') - .leftJoinAndSelect('posMaster.orgRoot', 'orgRoot') - .leftJoinAndSelect('positions.posExecutive', 'posExecutive') - .leftJoinAndSelect('current_holder.posType', 'posType') - .leftJoinAndSelect('current_holder.posLevel', 'posLevel') - .leftJoinAndSelect('current_holder.profileEducations', 'profileEducations') - .where('posMaster.orgRevisionId = :currentRevisionId', { currentRevisionId: currentRevision?.id }) - .andWhere(rootId?'posMaster.orgRootId = :rootId': "1=1", { rootId: rootId }) - .andWhere('posMaster.current_holderId Is Not Null') - .andWhere('positions.positionIsSelected = :positionIsSelected', { positionIsSelected: true }) - .andWhere( yearInAD && yearInAD != null? 'YEAR(current_holder.dateAppoint) = :year': "1=1", { year: yearInAD }) //ตอนนี้ where ที่วันที่บรรจุ (รอ prove) ว่าจะ where ที่ไหน - .andWhere(` - TIMESTAMPDIFF(YEAR, current_holder.birthDate, CURDATE()) >= :minAge - AND TIMESTAMPDIFF(YEAR, current_holder.birthDate, CURDATE()) <= :maxAge - `, - { minAge, maxAge }, - ) - .orderBy("posType.posTypeName", "ASC") - .getMany(); - if (!rawdataProfile) { - throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); + ageMin = ageMin ?? 18; + ageMax = ageMax ?? 60; + + let nodeCondition = "1=1"; + if (node === 0 && nodeId) { + nodeCondition = "registryOfficer.orgRootId = :nodeId"; + } + else if (node === 1 && nodeId) { + nodeCondition = "registryOfficer.orgChild1Id = :nodeId"; + } + else if (node === 2 && nodeId) { + nodeCondition = "registryOfficer.orgChild2Id = :nodeId"; } - const mapData = rawdataProfile.map((x) => { - const latestEducation = x.current_holder.profileEducations.sort( - (a: any, b: any) => b.endDate - a.startDate, - )[0]; - return { - name: x.current_holder.firstName + " " + x.current_holder.lastName, - affiliation: x.orgRoot.orgRootName ?? "-", - gender: x.current_holder.gender ?? "-", - positionName: x.positions[0] ? x.positions[0].positionName : "-", - status: x.current_holder.relationship ?? "-", - posType: x.current_holder.posType.posTypeName ?? "-", - posLevel: x.current_holder.posLevel.posLevelName ?? "-", - degree: latestEducation ? latestEducation.educationLevel : "-", - posExecutive: x.positions[0].posExecutive - ? x.positions[0].posExecutive.posExecutiveName - : "-", - currentPreiodPos: "-", - levelPeriodPos: "-", - }; - }); + else if (node === 3 && nodeId) { + nodeCondition = "registryOfficer.orgChild3Id = :nodeId"; + } + else if (node === 4 && nodeId) { + nodeCondition = "registryOfficer.orgChild4Id = :nodeId"; + } + let dateAppointCondition = "1=1"; + if (startDateAppoint && endDateAppoint) { + dateAppointCondition = "DATE(registryOfficer.dateAppoint) >= :startDateAppoint AND DATE(registryOfficer.dateAppoint) <= :endDateAppoint"; + } else if (startDateAppoint) { + dateAppointCondition = "DATE(registryOfficer.dateAppoint) >= :startDateAppoint"; + } else if (endDateAppoint) { + dateAppointCondition = "DATE(registryOfficer.dateAppoint) <= :endDateAppoint"; + } + const [lists, total] = await AppDataSource.getRepository(viewRegistryOfficer) + .createQueryBuilder("registryOfficer") + .where(nodeCondition, { + nodeId: nodeId + }) + .andWhere("registryOfficer.age BETWEEN :ageMin AND :ageMax", { + ageMin, ageMax + }) + .andWhere(dateAppointCondition, { + startDateAppoint: startDateAppoint?.toISOString().split("T")[0], + endDateAppoint: endDateAppoint?.toISOString().split("T")[0] + }) + .andWhere( + new Brackets((qb) => { + qb.orWhere( + posTypeName != null && posTypeName != "" + ? "registryOfficer.posTypeName LIKE :posTypeName" + : "1=1", + { + posTypeName: `%${posTypeName}%`, + }, + ) + qb.orWhere( + posLevelName != null && posLevelName != "" + ? "registryOfficer.posLevelName LIKE :posLevelName" + : "1=1", + { + posLevelName: `%${posLevelName}%`, + }, + ) + qb.orWhere( + position != null && position != "" + ? "registryOfficer.position LIKE :position" + : "1=1", + { + position: `%${position}%`, + }, + ) + qb.orWhere( + posExecutiveName != null && posExecutiveName != "" + ? "registryOfficer.posExecutiveName LIKE :posExecutiveName" + : "1=1", + { + posExecutiveName: `%${posExecutiveName}%`, + }, + ) + qb.orWhere( + gender != null && gender != "" + ? "registryOfficer.gender LIKE :gender" + : "1=1", + { + gender: `%${gender}%`, + }, + ) + qb.orWhere( + relationship != null && relationship != "" + ? "registryOfficer.relationship LIKE :relationship" + : "1=1", + { + relationship: `%${relationship}%`, + }, + ) + qb.orWhere( + degree != null && degree != "" + ? "registryOfficer.degree LIKE :degree" + : "1=1", + { + degree: `%${degree}%`, + }, + ) + }), + ) + .orderBy(`registryOfficer.${sortBy}`, sort) + .getManyAndCount(); - const groupedData = mapData.reduce((acc: any, item) => { - const key = `${item.posType} - ${item.affiliation} - ${item.gender} - ${item.degree || "ไม่พบข้อมูล"} - ${item.status || "ไม่พบข้อมูล"} - ${item.positionName} - ${item.posLevel} - ${item.posExecutive || "ไม่พบข้อมูล"} `; - if (!acc[key]) { - acc[key] = { - posType: item.posType && item.posType != "" ? item.posType : "-", - affiliation: item.affiliation && item.affiliation != "" ? item.affiliation : "-", - gender: item.gender && item.gender != "" ? item.gender : "-", - degree: item.degree && item.degree != "" ? item.degree : "-", - status: item.status && item.status != "" ? item.status : "-", - positionName: item.positionName && item.positionName != "" ? item.positionName : "-", - posLevel: item.posLevel && item.posLevel != "" ? item.posLevel : "-", - posExecutive: item.posExecutive && item.posExecutive != "" ? item.posExecutive : "-", - currentPreiodPos: "-", - levelPeriodPos: "-", - count: 0, - }; - } - acc[key].count++; - - return acc; - }, {}); - - const result = Object.values(groupedData).map((item: any) => ({ - ...item, - count: Extension.ToThaiNumber(item.count.toString()), - })); return new HttpSuccess({ - template: "registry-officer", - reportName: "xlsx-report", - data: { - year: year - ? Extension.ToThaiNumber((year + 543).toString()) - : Extension.ToThaiNumber((new Date().getFullYear() + 543).toString()), - date: Extension.ToThaiNumber(Extension.ToThaiShortDate(new Date())), - list: result, - }, + // template: "registry-officer", + // reportName: "xlsx-report", + // data: { + // date: Extension.ToThaiNumber(Extension.ToThaiShortDate(new Date())), + // data: lists, + // total: total + // }, + data: lists, + total: total }); } + /** * API รายงานสถิติข้อมูลลูกจ้างประจำ กทม. * * @summary รายงานสถิติข้อมูลลูกจ้างประจำ กทม. * */ + // @Get("registry-emp") + // async registryEmp( + // @Query() rootId?: string, + // @Query() year?: number, + // @Query() ageMin?: number, + // @Query() ageMax?: number, + // ) { + // if (ageMin && (ageMin < 18 || ageMin > 60)) { + // throw new HttpError(HttpStatus.BAD_REQUEST, "ageMin must be between 18 and 60"); + // } + + // if (ageMax && (ageMax < 18 || ageMax > 60)) { + // throw new HttpError(HttpStatus.BAD_REQUEST, "ageMax must be between 18 and 60"); + // } + + // const minAge = ageMin ?? 18; + // const maxAge = ageMax ?? 60; + + // if (minAge > maxAge) { + // throw new HttpError(HttpStatus.NOT_FOUND, "ageMin cannot be greater than ageMax"); + // } + // const yearInAD = year ? year : null; + // const currentRevision = await this.orgRevisionRepository.findOne({ + // where: { + // orgRevisionIsCurrent: true, + // }, + // }); + // const rawdataProfile = await this.empPosMasterRepository + // .createQueryBuilder("posMaster") + // .leftJoinAndSelect("posMaster.current_holder", "current_holder") + // .leftJoinAndSelect("posMaster.positions", "positions") + // .leftJoinAndSelect("posMaster.orgRoot", "orgRoot") + // .leftJoinAndSelect("current_holder.posType", "posType") + // .leftJoinAndSelect("current_holder.posLevel", "posLevel") + // .leftJoinAndSelect("current_holder.profileEducations", "profileEducations") + // .where("posMaster.orgRevisionId = :currentRevisionId", { + // currentRevisionId: currentRevision?.id, + // }) + // .andWhere(rootId ? "posMaster.orgRootId = :rootId" : "1=1", { rootId: rootId }) + // .andWhere("posMaster.current_holderId Is Not Null") + // .andWhere("positions.positionIsSelected = :positionIsSelected", { positionIsSelected: true }) + // .andWhere(yearInAD && yearInAD != null ? "YEAR(current_holder.dateAppoint) = :year" : "1=1", { + // year: yearInAD, + // }) + // .andWhere( + // ` + // TIMESTAMPDIFF(YEAR, current_holder.birthDate, CURDATE()) >= :minAge + // AND TIMESTAMPDIFF(YEAR, current_holder.birthDate, CURDATE()) <= :maxAge + // `, + // { minAge, maxAge }, + // ) + // .orderBy("posType.posTypeName", "ASC") + // .getMany(); + // if (!rawdataProfile) { + // throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); + // } + // const mapData = rawdataProfile.map((x) => { + // const latestEducation = x.current_holder.profileEducations.sort( + // (a: any, b: any) => b.endDate - a.startDate, + // )[0]; + // return { + // name: x.current_holder.firstName + " " + x.current_holder.lastName, + // affiliation: x.orgRoot.orgRootName ?? "-", + // gender: x.current_holder.gender ?? "-", + // positionName: x.positions[0] ? x.positions[0].positionName : "-", + // status: x.current_holder.relationship ?? "-", + // posType: x.current_holder.posType.posTypeName ?? "-", + // posLevel: x.current_holder.posLevel.posLevelName ?? "-", + // degree: latestEducation ? latestEducation.educationLevel : "-", + // period: "-", + // }; + // }); + + // const groupedData = mapData.reduce((acc: any, item) => { + // const key = `${item.affiliation} - ${item.gender} - ${item.degree || "ไม่พบข้อมูล"} - ${item.status || "ไม่พบข้อมูล"} - ${item.posType} - ${item.positionName} - ${item.posLevel} + // `; + // if (!acc[key]) { + // acc[key] = { + // affiliation: item.affiliation && item.affiliation != "" ? item.affiliation : "-", + // gender: item.gender && item.gender != "" ? item.gender : "-", + // degree: item.degree && item.degree != "" ? item.degree : "-", + // status: item.status && item.status != "" ? item.status : "-", + // posType: item.posType && item.posType != "" ? item.posType : "-", + // positionName: item.positionName && item.positionName != "" ? item.positionName : "-", + // posLevel: Extension.ToThaiNumber(item.posLevel.toString()), + // period: "-", + // count: 0, + // }; + // } + // acc[key].count++; + + // return acc; + // }, {}); + + // const result = Object.values(groupedData).map((item: any) => ({ + // ...item, + // count: Extension.ToThaiNumber(item.count.toString()), + // })); + + // return new HttpSuccess({ + // template: "registry-emp", + // reportName: "xlsx-report", + // data: { + // year: year + // ? Extension.ToThaiNumber((year + 543).toString()) + // : Extension.ToThaiNumber((new Date().getFullYear() + 543).toString()), + // date: Extension.ToThaiNumber(Extension.ToThaiShortDate(new Date())), + // list: result, + // }, + // }); + // } @Get("registry-emp") - async registryEmp( - @Query() rootId?: string, - @Query() year?: number, + async registryEmployee( + @Query() node?: number, + @Query() nodeId?: string, + @Query() posTypeName?: string, + @Query() posLevelName?: string, + @Query() position?: string, + @Query() gender?: string, + @Query() relationship?: string, + @Query() degree?: string, + @Query() startDateAppoint?: Date, + @Query() endDateAppoint?: Date, @Query() ageMin?: number, @Query() ageMax?: number, + @Query() sortBy: string = "posMasterNo", + @Query() sort: "ASC"|"DESC" = "ASC", ) { if (ageMin && (ageMin < 18 || ageMin > 60)) { - throw new HttpError(HttpStatus.BAD_REQUEST, "ageMin must be between 18 and 60"); + throw new HttpError(HttpStatus.NOT_FOUND, "ageMin must be between 18 and 60"); } - if (ageMax && (ageMax < 18 || ageMax > 60)) { - throw new HttpError(HttpStatus.BAD_REQUEST, "ageMax must be between 18 and 60"); + throw new HttpError(HttpStatus.NOT_FOUND, "ageMax must be between 18 and 60"); } - - const minAge = ageMin ?? 18; - const maxAge = ageMax ?? 60; - - if (minAge > maxAge) { + if (ageMin && ageMax && (ageMin > ageMax)) { throw new HttpError(HttpStatus.NOT_FOUND, "ageMin cannot be greater than ageMax"); } - const yearInAD = year ? year : null; - const currentRevision = await this.orgRevisionRepository.findOne({ - where: { - orgRevisionIsCurrent: true, - }, - }); - const rawdataProfile = await this.empPosMasterRepository - .createQueryBuilder("posMaster") - .leftJoinAndSelect("posMaster.current_holder", "current_holder") - .leftJoinAndSelect("posMaster.positions", "positions") - .leftJoinAndSelect("posMaster.orgRoot", "orgRoot") - .leftJoinAndSelect("current_holder.posType", "posType") - .leftJoinAndSelect("current_holder.posLevel", "posLevel") - .leftJoinAndSelect("current_holder.profileEducations", "profileEducations") - .where("posMaster.orgRevisionId = :currentRevisionId", { - currentRevisionId: currentRevision?.id, + ageMin = ageMin ?? 18; + ageMax = ageMax ?? 60; + + let nodeCondition = "1=1"; + if (node === 0 && nodeId) { + nodeCondition = "registryOfficer.orgRootId = :nodeId"; + } + else if (node === 1 && nodeId) { + nodeCondition = "registryOfficer.orgChild1Id = :nodeId"; + } + else if (node === 2 && nodeId) { + nodeCondition = "registryOfficer.orgChild2Id = :nodeId"; + } + else if (node === 3 && nodeId) { + nodeCondition = "registryOfficer.orgChild3Id = :nodeId"; + } + else if (node === 4 && nodeId) { + nodeCondition = "registryOfficer.orgChild4Id = :nodeId"; + } + let dateAppointCondition = "1=1"; + if (startDateAppoint && endDateAppoint) { + dateAppointCondition = "DATE(registryOfficer.dateAppoint) >= :startDateAppoint AND DATE(registryOfficer.dateAppoint) <= :endDateAppoint"; + } else if (startDateAppoint) { + dateAppointCondition = "DATE(registryOfficer.dateAppoint) >= :startDateAppoint"; + } else if (endDateAppoint) { + dateAppointCondition = "DATE(registryOfficer.dateAppoint) <= :endDateAppoint"; + } + const [lists, total] = await AppDataSource.getRepository(viewRegistryEmployee) + .createQueryBuilder("registryOfficer") + .where(nodeCondition, { + nodeId: nodeId }) - .andWhere(rootId ? "posMaster.orgRootId = :rootId" : "1=1", { rootId: rootId }) - .andWhere("posMaster.current_holderId Is Not Null") - .andWhere("positions.positionIsSelected = :positionIsSelected", { positionIsSelected: true }) - .andWhere(yearInAD && yearInAD != null ? "YEAR(current_holder.dateAppoint) = :year" : "1=1", { - year: yearInAD, + .andWhere("registryOfficer.age BETWEEN :ageMin AND :ageMax", { + ageMin, ageMax + }) + .andWhere(dateAppointCondition, { + startDateAppoint: startDateAppoint?.toISOString().split("T")[0], + endDateAppoint: endDateAppoint?.toISOString().split("T")[0] }) .andWhere( - ` - TIMESTAMPDIFF(YEAR, current_holder.birthDate, CURDATE()) >= :minAge - AND TIMESTAMPDIFF(YEAR, current_holder.birthDate, CURDATE()) <= :maxAge - `, - { minAge, maxAge }, + new Brackets((qb) => { + qb.orWhere( + posTypeName != null && posTypeName != "" + ? "registryOfficer.posTypeName LIKE :posTypeName" + : "1=1", + { + posTypeName: `%${posTypeName}%`, + }, + ) + qb.orWhere( + posLevelName != null && posLevelName != "" + ? "registryOfficer.posLevelName LIKE :posLevelName" + : "1=1", + { + posLevelName: `%${posLevelName}%`, + }, + ) + qb.orWhere( + position != null && position != "" + ? "registryOfficer.position LIKE :position" + : "1=1", + { + position: `%${position}%`, + }, + ) + qb.orWhere( + gender != null && gender != "" + ? "registryOfficer.gender LIKE :gender" + : "1=1", + { + gender: `%${gender}%`, + }, + ) + qb.orWhere( + relationship != null && relationship != "" + ? "registryOfficer.relationship LIKE :relationship" + : "1=1", + { + relationship: `%${relationship}%`, + }, + ) + qb.orWhere( + degree != null && degree != "" + ? "registryOfficer.degree LIKE :degree" + : "1=1", + { + degree: `%${degree}%`, + }, + ) + }), ) - .orderBy("posType.posTypeName", "ASC") - .getMany(); - if (!rawdataProfile) { - throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); - } - const mapData = rawdataProfile.map((x) => { - const latestEducation = x.current_holder.profileEducations.sort( - (a: any, b: any) => b.endDate - a.startDate, - )[0]; - return { - name: x.current_holder.firstName + " " + x.current_holder.lastName, - affiliation: x.orgRoot.orgRootName ?? "-", - gender: x.current_holder.gender ?? "-", - positionName: x.positions[0] ? x.positions[0].positionName : "-", - status: x.current_holder.relationship ?? "-", - posType: x.current_holder.posType.posTypeName ?? "-", - posLevel: x.current_holder.posLevel.posLevelName ?? "-", - degree: latestEducation ? latestEducation.educationLevel : "-", - period: "-", - }; - }); - - const groupedData = mapData.reduce((acc: any, item) => { - const key = `${item.affiliation} - ${item.gender} - ${item.degree || "ไม่พบข้อมูล"} - ${item.status || "ไม่พบข้อมูล"} - ${item.posType} - ${item.positionName} - ${item.posLevel} - `; - if (!acc[key]) { - acc[key] = { - affiliation: item.affiliation && item.affiliation != "" ? item.affiliation : "-", - gender: item.gender && item.gender != "" ? item.gender : "-", - degree: item.degree && item.degree != "" ? item.degree : "-", - status: item.status && item.status != "" ? item.status : "-", - posType: item.posType && item.posType != "" ? item.posType : "-", - positionName: item.positionName && item.positionName != "" ? item.positionName : "-", - posLevel: Extension.ToThaiNumber(item.posLevel.toString()), - period: "-", - count: 0, - }; - } - acc[key].count++; - - return acc; - }, {}); - - const result = Object.values(groupedData).map((item: any) => ({ - ...item, - count: Extension.ToThaiNumber(item.count.toString()), - })); + .orderBy(`registryOfficer.${sortBy}`, sort) + .getManyAndCount(); return new HttpSuccess({ - template: "registry-emp", - reportName: "xlsx-report", - data: { - year: year - ? Extension.ToThaiNumber((year + 543).toString()) - : Extension.ToThaiNumber((new Date().getFullYear() + 543).toString()), - date: Extension.ToThaiNumber(Extension.ToThaiShortDate(new Date())), - list: result, - }, + // template: "registry-officer", + // reportName: "xlsx-report", + // data: { + // date: Extension.ToThaiNumber(Extension.ToThaiShortDate(new Date())), + // data: lists, + // total: total + // }, + data: lists, + total: total }); } diff --git a/src/entities/view/viewRegistryEmployee.ts b/src/entities/view/viewRegistryEmployee.ts index 2c121956..660c9d12 100644 --- a/src/entities/view/viewRegistryEmployee.ts +++ b/src/entities/view/viewRegistryEmployee.ts @@ -53,6 +53,7 @@ import { ViewColumn, ViewEntity } from "typeorm"; ORDER BY ed.level ASC ) SELECT + p.id as profileEmployeeId, p.citizenId, p.prefix, p.firstName, @@ -97,6 +98,9 @@ import { ViewColumn, ViewEntity } from "typeorm"; `, }) export class viewRegistryEmployee { + @ViewColumn() + profileEmployeeId: string; + @ViewColumn() citizenId: string; diff --git a/src/entities/view/viewRegistryOfficer.ts b/src/entities/view/viewRegistryOfficer.ts index 3c9b84ff..15aa087d 100644 --- a/src/entities/view/viewRegistryOfficer.ts +++ b/src/entities/view/viewRegistryOfficer.ts @@ -57,6 +57,7 @@ import { ViewColumn, ViewEntity } from "typeorm"; ORDER BY ed.level ASC ) SELECT + p.id as profileId, p.citizenId, p.prefix, p.firstName, @@ -103,7 +104,10 @@ import { ViewColumn, ViewEntity } from "typeorm"; }) export class viewRegistryOfficer { @ViewColumn() - id: string; + profileId: string; + + @ViewColumn() + citizenId: string; @ViewColumn() prefix: string; diff --git a/src/migration/1739940470200-updateViewRegistryOfficerAndEmployee.ts b/src/migration/1739940470200-updateViewRegistryOfficerAndEmployee.ts new file mode 100644 index 00000000..3f505112 --- /dev/null +++ b/src/migration/1739940470200-updateViewRegistryOfficerAndEmployee.ts @@ -0,0 +1,213 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdateViewRegistryOfficerAndEmployee1739940470200 implements MigrationInterface { + name = 'UpdateViewRegistryOfficerAndEmployee1739940470200' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE VIEW \`view_registry_officer\` AS + WITH Position AS ( + SELECT + posExecutive.posExecutiveName, + pn.posMasterId, + ROW_NUMBER() OVER (PARTITION BY pn.posMasterId) AS pn_number + FROM position pn + LEFT JOIN posExecutive ON pn.posExecutiveId = posExecutive.id + WHERE pn.positionIsSelected IS TRUE + ), + PosMaster AS ( + SELECT + pm.current_holderId, + pm.posMasterNo, + pm.orgRootId, + pm.orgChild1Id, + pm.orgChild2Id, + pm.orgChild3Id, + pm.orgChild4Id, + orgRoot.orgRootName, + orgChild1.orgChild1Name, + orgChild2.orgChild2Name, + orgChild3.orgChild3Name, + orgChild4.orgChild4Name, + pn.posExecutiveName, + CASE + WHEN pm.orgChild1Id IS NULL THEN CONCAT(orgRoot.orgRootShortName, pm.posMasterNo) + WHEN pm.orgChild2Id IS NULL THEN CONCAT(orgChild1.orgChild1ShortName, pm.posMasterNo) + WHEN pm.orgChild3Id IS NULL THEN CONCAT(orgChild2.orgChild2ShortName, pm.posMasterNo) + WHEN pm.orgChild4Id IS NULL THEN CONCAT(orgChild3.orgChild3ShortName, pm.posMasterNo) + ELSE CONCAT(orgChild4.orgChild4ShortName, pm.posMasterNo) + END AS searchShortName, + ROW_NUMBER() OVER (PARTITION BY pm.current_holderId ORDER BY pm.posMasterNo DESC) AS pm_number + FROM posMaster pm + LEFT JOIN orgRevision ON orgRevision.id = pm.orgRevisionId + LEFT JOIN orgRoot ON orgRoot.id = pm.orgRootId + LEFT JOIN orgChild1 ON orgChild1.id = pm.orgChild1Id + LEFT JOIN orgChild2 ON orgChild2.id = pm.orgChild2Id + LEFT JOIN orgChild3 ON orgChild3.id = pm.orgChild3Id + LEFT JOIN orgChild4 ON orgChild4.id = pm.orgChild4Id + LEFT JOIN Position pn ON pm.id = pn.posMasterId AND pn.pn_number = 1 + WHERE + orgRevision.orgRevisionIsCurrent IS TRUE + AND orgRevision.orgRevisionIsDraft IS FALSE + ), + Education AS ( + SELECT + ed.degree, + ed.profileId, + ed.level, + ROW_NUMBER() OVER (PARTITION BY ed.profileId ORDER BY ed.level DESC) AS ed_number + FROM profileEducation ed + WHERE ed.isUse IS TRUE + ORDER BY ed.level ASC + ) + SELECT + p.id as profileId, + p.citizenId, + p.prefix, + p.firstName, + p.lastName, + p.isProbation, + p.isLeave, + p.isRetirement, + p.leaveType, + pm.posMasterNo, + pm.orgRootId, + pm.orgChild1Id, + pm.orgChild2Id, + pm.orgChild3Id, + pm.orgChild4Id, + pm.orgRootName, + pm.orgChild1Name, + pm.orgChild2Name, + pm.orgChild3Name, + pm.orgChild4Name, + CASE + WHEN pm.orgChild1Id IS NULL THEN pm.orgRootName + WHEN pm.orgChild2Id IS NULL THEN CONCAT(pm.orgChild1Name, " ", pm.orgRootName) + WHEN pm.orgChild3Id IS NULL THEN CONCAT(pm.orgChild2Name, " ", pm.orgChild1Name, " ", pm.orgRootName) + WHEN pm.orgChild4Id IS NULL THEN CONCAT(pm.orgChild3Name, " ", pm.orgChild2Name, " ", pm.orgChild1Name, " ", pm.orgRootName) + ELSE CONCAT(pm.orgChild4Name, " ", pm.orgChild3Name, " ", pm.orgChild2Name, " ", pm.orgChild1Name, " ", pm.orgRootName) + END AS org, + pm.searchShortName, + pm.posExecutiveName, + p.position, + posType.posTypeName, + posLevel.posLevelName, + p.gender, + p.relationship, + p.dateAppoint, + p.birthdate, + ed.degree, + TIMESTAMPDIFF(YEAR, p.birthdate, CURDATE()) AS age + FROM profile p + LEFT JOIN posLevel ON p.posLevelId = posLevel.id + LEFT JOIN posType ON p.posTypeId = posType.id + LEFT JOIN PosMaster pm ON p.id = pm.current_holderId AND pm.pm_number = 1 + LEFT JOIN Education ed ON p.id = ed.profileId AND ed.ed_number = 1 + `); + await queryRunner.query(`INSERT INTO \`bma_ehr_organization_demo\`.\`typeorm_metadata\`(\`database\`, \`schema\`, \`table\`, \`type\`, \`name\`, \`value\`) VALUES (DEFAULT, ?, DEFAULT, ?, ?, ?)`, ["bma_ehr_organization_demo","VIEW","view_registry_officer","WITH Position AS (\n SELECT \n posExecutive.posExecutiveName,\n pn.posMasterId,\n ROW_NUMBER() OVER (PARTITION BY pn.posMasterId) AS pn_number\n FROM position pn\n LEFT JOIN posExecutive ON pn.posExecutiveId = posExecutive.id\n WHERE pn.positionIsSelected IS TRUE\n ),\n PosMaster AS (\n SELECT \n pm.current_holderId,\n pm.posMasterNo,\n pm.orgRootId,\n pm.orgChild1Id,\n pm.orgChild2Id,\n pm.orgChild3Id,\n pm.orgChild4Id,\n orgRoot.orgRootName,\n orgChild1.orgChild1Name,\n orgChild2.orgChild2Name,\n orgChild3.orgChild3Name,\n orgChild4.orgChild4Name,\n pn.posExecutiveName,\n CASE \n WHEN pm.orgChild1Id IS NULL THEN CONCAT(orgRoot.orgRootShortName, pm.posMasterNo)\n WHEN pm.orgChild2Id IS NULL THEN CONCAT(orgChild1.orgChild1ShortName, pm.posMasterNo)\n WHEN pm.orgChild3Id IS NULL THEN CONCAT(orgChild2.orgChild2ShortName, pm.posMasterNo)\n WHEN pm.orgChild4Id IS NULL THEN CONCAT(orgChild3.orgChild3ShortName, pm.posMasterNo)\n ELSE CONCAT(orgChild4.orgChild4ShortName, pm.posMasterNo)\n END AS searchShortName,\n ROW_NUMBER() OVER (PARTITION BY pm.current_holderId ORDER BY pm.posMasterNo DESC) AS pm_number\n FROM posMaster pm\n LEFT JOIN orgRevision ON orgRevision.id = pm.orgRevisionId\n LEFT JOIN orgRoot ON orgRoot.id = pm.orgRootId\n LEFT JOIN orgChild1 ON orgChild1.id = pm.orgChild1Id\n LEFT JOIN orgChild2 ON orgChild2.id = pm.orgChild2Id\n LEFT JOIN orgChild3 ON orgChild3.id = pm.orgChild3Id\n LEFT JOIN orgChild4 ON orgChild4.id = pm.orgChild4Id\n LEFT JOIN Position pn ON pm.id = pn.posMasterId AND pn.pn_number = 1\n WHERE \n orgRevision.orgRevisionIsCurrent IS TRUE \n AND orgRevision.orgRevisionIsDraft IS FALSE\n ),\n Education AS (\n SELECT \n ed.degree,\n ed.profileId,\n ed.level,\n ROW_NUMBER() OVER (PARTITION BY ed.profileId ORDER BY ed.level DESC) AS ed_number\n FROM profileEducation ed\n WHERE ed.isUse IS TRUE\n ORDER BY ed.level ASC\n )\n SELECT \n p.id as profileId,\n p.citizenId,\n p.prefix,\n p.firstName,\n p.lastName,\n p.isProbation,\n p.isLeave,\n p.isRetirement,\n p.leaveType,\n pm.posMasterNo,\n pm.orgRootId,\n pm.orgChild1Id,\n pm.orgChild2Id,\n pm.orgChild3Id,\n pm.orgChild4Id,\n pm.orgRootName,\n pm.orgChild1Name,\n pm.orgChild2Name,\n pm.orgChild3Name,\n pm.orgChild4Name,\n CASE \n WHEN pm.orgChild1Id IS NULL THEN pm.orgRootName\n WHEN pm.orgChild2Id IS NULL THEN CONCAT(pm.orgChild1Name, \" \", pm.orgRootName)\n WHEN pm.orgChild3Id IS NULL THEN CONCAT(pm.orgChild2Name, \" \", pm.orgChild1Name, \" \", pm.orgRootName)\n WHEN pm.orgChild4Id IS NULL THEN CONCAT(pm.orgChild3Name, \" \", pm.orgChild2Name, \" \", pm.orgChild1Name, \" \", pm.orgRootName)\n ELSE CONCAT(pm.orgChild4Name, \" \", pm.orgChild3Name, \" \", pm.orgChild2Name, \" \", pm.orgChild1Name, \" \", pm.orgRootName)\n END AS org,\n pm.searchShortName,\n pm.posExecutiveName,\n p.position,\n posType.posTypeName,\n posLevel.posLevelName,\n p.gender,\n p.relationship,\n p.dateAppoint,\n p.birthdate,\n ed.degree,\n TIMESTAMPDIFF(YEAR, p.birthdate, CURDATE()) AS age\n FROM profile p\n LEFT JOIN posLevel ON p.posLevelId = posLevel.id\n LEFT JOIN posType ON p.posTypeId = posType.id\n LEFT JOIN PosMaster pm ON p.id = pm.current_holderId AND pm.pm_number = 1\n LEFT JOIN Education ed ON p.id = ed.profileId AND ed.ed_number = 1"]); + await queryRunner.query(`CREATE VIEW \`view_registry_employee\` AS + WITH Position AS ( + SELECT + pn.posMasterId, + ROW_NUMBER() OVER (PARTITION BY pn.posMasterId) AS pn_number + FROM employeePosition pn + WHERE pn.positionIsSelected IS TRUE + ), + PosMaster AS ( + SELECT + pm.current_holderId, + pm.posMasterNo, + pm.orgRootId, + pm.orgChild1Id, + pm.orgChild2Id, + pm.orgChild3Id, + pm.orgChild4Id, + orgRoot.orgRootName, + orgChild1.orgChild1Name, + orgChild2.orgChild2Name, + orgChild3.orgChild3Name, + orgChild4.orgChild4Name, + CASE + WHEN pm.orgChild1Id IS NULL THEN CONCAT(orgRoot.orgRootShortName, pm.posMasterNo) + WHEN pm.orgChild2Id IS NULL THEN CONCAT(orgChild1.orgChild1ShortName, pm.posMasterNo) + WHEN pm.orgChild3Id IS NULL THEN CONCAT(orgChild2.orgChild2ShortName, pm.posMasterNo) + WHEN pm.orgChild4Id IS NULL THEN CONCAT(orgChild3.orgChild3ShortName, pm.posMasterNo) + ELSE CONCAT(orgChild4.orgChild4ShortName, pm.posMasterNo) + END AS searchShortName, + ROW_NUMBER() OVER (PARTITION BY pm.current_holderId ORDER BY pm.posMasterNo DESC) AS pm_number + FROM employeePosMaster pm + LEFT JOIN orgRevision ON orgRevision.id = pm.orgRevisionId + LEFT JOIN orgRoot ON orgRoot.id = pm.orgRootId + LEFT JOIN orgChild1 ON orgChild1.id = pm.orgChild1Id + LEFT JOIN orgChild2 ON orgChild2.id = pm.orgChild2Id + LEFT JOIN orgChild3 ON orgChild3.id = pm.orgChild3Id + LEFT JOIN orgChild4 ON orgChild4.id = pm.orgChild4Id + LEFT JOIN Position pn ON pm.id = pn.posMasterId AND pn.pn_number = 1 + WHERE orgRevision.orgRevisionIsCurrent IS TRUE + AND orgRevision.orgRevisionIsDraft IS FALSE + ), + Education AS ( + SELECT + ed.degree, + ed.profileEmployeeId, + ed.level, + ROW_NUMBER() OVER (PARTITION BY ed.profileEmployeeId ORDER BY ed.level DESC) AS ed_number + FROM profileEducation ed + WHERE ed.isUse IS TRUE + ORDER BY ed.level ASC + ) + SELECT + p.id as profileEmployeeId, + p.citizenId, + p.prefix, + p.firstName, + p.lastName, + p.isProbation, + p.isLeave, + p.isRetirement, + p.leaveType, + pm.posMasterNo, + pm.orgRootId, + pm.orgChild1Id, + pm.orgChild2Id, + pm.orgChild3Id, + pm.orgChild4Id, + pm.orgRootName, + pm.orgChild1Name, + pm.orgChild2Name, + pm.orgChild3Name, + pm.orgChild4Name, + CASE + WHEN pm.orgChild1Id IS NULL THEN pm.orgRootName + WHEN pm.orgChild2Id IS NULL THEN CONCAT(pm.orgChild1Name, " ", pm.orgRootName) + WHEN pm.orgChild3Id IS NULL THEN CONCAT(pm.orgChild2Name, " ", pm.orgChild1Name, " ", pm.orgRootName) + WHEN pm.orgChild4Id IS NULL THEN CONCAT(pm.orgChild3Name, " ", pm.orgChild2Name, " ", pm.orgChild1Name, " ", pm.orgRootName) + ELSE CONCAT(pm.orgChild4Name, " ", pm.orgChild3Name, " ", pm.orgChild2Name, " ", pm.orgChild1Name, " ", pm.orgRootName) + END AS org, + pm.searchShortName, + p.position, + posType.posTypeName, + posLevel.posLevelName, + p.gender, + p.relationship, + p.dateAppoint, + p.birthdate, + ed.degree, + TIMESTAMPDIFF(YEAR, p.birthdate, CURDATE()) AS age + FROM profileEmployee p + LEFT JOIN employeePosLevel posLevel ON p.posLevelId = posLevel.id + LEFT JOIN employeePosType posType ON p.posTypeId = posType.id + LEFT JOIN PosMaster pm ON p.id = pm.current_holderId AND pm.pm_number = 1 + LEFT JOIN Education ed ON p.id = ed.profileEmployeeId AND ed.ed_number = 1 + `); + await queryRunner.query(`INSERT INTO \`bma_ehr_organization_demo\`.\`typeorm_metadata\`(\`database\`, \`schema\`, \`table\`, \`type\`, \`name\`, \`value\`) VALUES (DEFAULT, ?, DEFAULT, ?, ?, ?)`, ["bma_ehr_organization_demo","VIEW","view_registry_employee","WITH Position AS (\n SELECT \n pn.posMasterId,\n ROW_NUMBER() OVER (PARTITION BY pn.posMasterId) AS pn_number\n FROM employeePosition pn\n WHERE pn.positionIsSelected IS TRUE\n ),\n PosMaster AS (\n SELECT \n pm.current_holderId,\n pm.posMasterNo,\n pm.orgRootId,\n pm.orgChild1Id,\n pm.orgChild2Id,\n pm.orgChild3Id,\n pm.orgChild4Id,\n orgRoot.orgRootName,\n orgChild1.orgChild1Name,\n orgChild2.orgChild2Name,\n orgChild3.orgChild3Name,\n orgChild4.orgChild4Name,\n CASE \n WHEN pm.orgChild1Id IS NULL THEN CONCAT(orgRoot.orgRootShortName, pm.posMasterNo)\n WHEN pm.orgChild2Id IS NULL THEN CONCAT(orgChild1.orgChild1ShortName, pm.posMasterNo)\n WHEN pm.orgChild3Id IS NULL THEN CONCAT(orgChild2.orgChild2ShortName, pm.posMasterNo)\n WHEN pm.orgChild4Id IS NULL THEN CONCAT(orgChild3.orgChild3ShortName, pm.posMasterNo)\n ELSE CONCAT(orgChild4.orgChild4ShortName, pm.posMasterNo)\n END AS searchShortName,\n ROW_NUMBER() OVER (PARTITION BY pm.current_holderId ORDER BY pm.posMasterNo DESC) AS pm_number\n FROM employeePosMaster pm\n LEFT JOIN orgRevision ON orgRevision.id = pm.orgRevisionId\n LEFT JOIN orgRoot ON orgRoot.id = pm.orgRootId\n LEFT JOIN orgChild1 ON orgChild1.id = pm.orgChild1Id\n LEFT JOIN orgChild2 ON orgChild2.id = pm.orgChild2Id\n LEFT JOIN orgChild3 ON orgChild3.id = pm.orgChild3Id\n LEFT JOIN orgChild4 ON orgChild4.id = pm.orgChild4Id\n LEFT JOIN Position pn ON pm.id = pn.posMasterId AND pn.pn_number = 1\n WHERE orgRevision.orgRevisionIsCurrent IS TRUE \n AND orgRevision.orgRevisionIsDraft IS FALSE\n ),\n Education AS (\n SELECT \n ed.degree,\n ed.profileEmployeeId,\n ed.level,\n ROW_NUMBER() OVER (PARTITION BY ed.profileEmployeeId ORDER BY ed.level DESC) AS ed_number\n FROM profileEducation ed\n WHERE ed.isUse IS TRUE\n ORDER BY ed.level ASC\n )\n SELECT \n p.id as profileEmployeeId,\n p.citizenId,\n p.prefix,\n p.firstName,\n p.lastName,\n p.isProbation,\n p.isLeave,\n p.isRetirement,\n p.leaveType,\n pm.posMasterNo,\n pm.orgRootId,\n pm.orgChild1Id,\n pm.orgChild2Id,\n pm.orgChild3Id,\n pm.orgChild4Id,\n pm.orgRootName,\n pm.orgChild1Name,\n pm.orgChild2Name,\n pm.orgChild3Name,\n pm.orgChild4Name,\n CASE \n WHEN pm.orgChild1Id IS NULL THEN pm.orgRootName\n WHEN pm.orgChild2Id IS NULL THEN CONCAT(pm.orgChild1Name, \" \", pm.orgRootName)\n WHEN pm.orgChild3Id IS NULL THEN CONCAT(pm.orgChild2Name, \" \", pm.orgChild1Name, \" \", pm.orgRootName)\n WHEN pm.orgChild4Id IS NULL THEN CONCAT(pm.orgChild3Name, \" \", pm.orgChild2Name, \" \", pm.orgChild1Name, \" \", pm.orgRootName)\n ELSE CONCAT(pm.orgChild4Name, \" \", pm.orgChild3Name, \" \", pm.orgChild2Name, \" \", pm.orgChild1Name, \" \", pm.orgRootName)\n END AS org,\n pm.searchShortName,\n p.position,\n posType.posTypeName,\n posLevel.posLevelName,\n p.gender,\n p.relationship,\n p.dateAppoint,\n p.birthdate,\n ed.degree,\n TIMESTAMPDIFF(YEAR, p.birthdate, CURDATE()) AS age\n FROM profileEmployee p\n LEFT JOIN employeePosLevel posLevel ON p.posLevelId = posLevel.id\n LEFT JOIN employeePosType posType ON p.posTypeId = posType.id\n LEFT JOIN PosMaster pm ON p.id = pm.current_holderId AND pm.pm_number = 1\n LEFT JOIN Education ed ON p.id = ed.profileEmployeeId AND ed.ed_number = 1"]); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DELETE FROM \`bma_ehr_organization_demo\`.\`typeorm_metadata\` WHERE \`type\` = ? AND \`name\` = ? AND \`schema\` = ?`, ["VIEW","view_registry_employee","bma_ehr_organization_demo"]); + await queryRunner.query(`DROP VIEW \`view_registry_employee\``); + await queryRunner.query(`DELETE FROM \`bma_ehr_organization_demo\`.\`typeorm_metadata\` WHERE \`type\` = ? AND \`name\` = ? AND \`schema\` = ?`, ["VIEW","view_registry_officer","bma_ehr_organization_demo"]); + await queryRunner.query(`DROP VIEW \`view_registry_officer\``); + } + +}