diff --git a/src/controllers/ProfileSalaryEmployeeController.ts b/src/controllers/ProfileSalaryEmployeeController.ts index 8294eb34..07a16050 100644 --- a/src/controllers/ProfileSalaryEmployeeController.ts +++ b/src/controllers/ProfileSalaryEmployeeController.ts @@ -87,6 +87,37 @@ export class ProfileSalaryEmployeeController extends Controller { return new HttpSuccess(record); } + @Get("tenure/{profileId}") + public async getPositionTenure(@Path() profileId: string, @Request() req: RequestWithUser) { + const position = await AppDataSource.query( + "CALL GetProfileEmployeeSalaryPosition(?)", + [profileId] + ); + const _position = position.length > 0 ? position[0] : [] + const mapPosition = _position.length > 1 + ? _position + .slice(1) + .map((curr: any, index: number) => ({ + year: curr.Years ? Math.floor(Number(curr.Years)) : 0, + month: curr.Months ? Math.floor(Number(curr.Months)) : 0, + day: curr.Days ? Math.floor(Number(curr.Days)) : 0, + name: _position[index]?.positionName + })) + : []; + + const posLevel = [{ + year: 3, + month: 0, + day: 0, + name: "ส 1", + }]; + + return new HttpSuccess({ + position: mapPosition, + posLevel: posLevel + }); + } + @Get("admin/{profileId}") public async getSalaryEmployeeAdmin(@Path() profileId: string, @Request() req: RequestWithUser) { let _workflow = await new permission().Workflow(req, profileId, "SYS_WAGE"); diff --git a/src/controllers/ReportController.ts b/src/controllers/ReportController.ts index 644031af..c68e20c6 100644 --- a/src/controllers/ReportController.ts +++ b/src/controllers/ReportController.ts @@ -189,6 +189,9 @@ export class ReportController extends Controller { @Query() isRetire?: boolean, @Query() isRetireLaw?: boolean, @Query() retireType?: string, + @Query() tenureType?: string, + @Query() tenureMin?: number, + @Query() tenureMax?: number, @Query() sortBy: string = "posMasterNo", @Query() sort: "ASC" | "DESC" = "ASC", ) { @@ -211,6 +214,9 @@ export class ReportController extends Controller { ageMin = ageMin ?? 18; ageMax = ageMax ?? 60; + tenureMin = tenureMin ?? 0; + tenureMax = tenureMax ?? 20; + let nodeCondition = "1=1"; if (node === 0 && nodeId) { nodeCondition = "registryOfficer.orgRootId = :nodeId"; @@ -246,11 +252,23 @@ export class ReportController extends Controller { "DATE(registryOfficer.dateRetireLaw) >= :startDateRetireLaw AND DATE(registryOfficer.dateRetireLaw) <= :endDateRetireLaw"; } + let tenureTypeCondition = "1=1"; + if(tenureType != "" && tenureType == "position") { + tenureTypeCondition = "registryOfficer.Years BETWEEN :tenureMin AND :tenureMax"; + } + else if (tenureType != "" && tenureType == "level") { + tenureTypeCondition = "registryOfficer.posxecutiveYears BETWEEN :tenureMin AND :tenureMax"; + } + const [lists, total] = await AppDataSource.getRepository(viewRegistryOfficer) .createQueryBuilder("registryOfficer") .where(nodeCondition, { nodeId: nodeId, }) + .andWhere(tenureTypeCondition, { + tenureMin: tenureMin, + tenureMax: tenureMax, + }) .andWhere("registryOfficer.age BETWEEN :ageMin AND :ageMax", { ageMin, ageMax, @@ -325,6 +343,7 @@ export class ReportController extends Controller { ) .orderBy(`registryOfficer.${sortBy}`, sort) .getManyAndCount(); + const mapData = lists.map((x) => ({ profileId: x.profileId, citizenId: x.citizenId, @@ -362,6 +381,12 @@ export class ReportController extends Controller { age: x.age, currentPosition: null, lengthPosition: null, + Years: x.Years, + Months: x.Months, + Days: x.Days, + // posExecutiveYears: x.posExecutiveYears, + // posExecutiveMonths: x.posExecutiveMonths, + // posExecutiveDays: x.posExecutiveDays })); return new HttpSuccess({ data: mapData, @@ -504,6 +529,9 @@ export class ReportController extends Controller { @Query() retireType?: string, @Query() ageMin?: number, @Query() ageMax?: number, + @Query() tenureType?: string, + @Query() tenureMin?: number, + @Query() tenureMax?: number, @Query() sortBy: string = "posMasterNo", @Query() sort: "ASC" | "DESC" = "ASC", ) { @@ -526,6 +554,9 @@ export class ReportController extends Controller { ageMin = ageMin ?? 18; ageMax = ageMax ?? 60; + tenureMin = tenureMin ?? 0; + tenureMax = tenureMax ?? 20; + let nodeCondition = "1=1"; if (node === 0 && nodeId) { nodeCondition = "registryEmployee.orgRootId = :nodeId"; diff --git a/src/entities/view/viewRegistryOfficer.ts b/src/entities/view/viewRegistryOfficer.ts index b60ed1cb..b96eb063 100644 --- a/src/entities/view/viewRegistryOfficer.ts +++ b/src/entities/view/viewRegistryOfficer.ts @@ -97,12 +97,17 @@ import { ViewColumn, ViewEntity } from "typeorm"; p.dateRetireLaw, p.birthdate, ed.degree, - TIMESTAMPDIFF(YEAR, p.birthdate, CURDATE()) AS age + TIMESTAMPDIFF(YEAR, p.birthdate, CURDATE()) AS age, + vcto.Years, + vcto.Months, + vcto.Days 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 + Inner Join view_current_tenure_officer vcto On p.id = vcto.profileId + Where vcto.orderNumber Is Null `, }) export class viewRegistryOfficer { @@ -207,4 +212,23 @@ export class viewRegistryOfficer { @ViewColumn() age: number; + + @ViewColumn() + Years: number; + + @ViewColumn() + Months: number; + + @ViewColumn() + Days: number; + +// @ViewColumn() +// posExecutiveYears: number; + +// @ViewColumn() +// posExecutiveMonths: number; + +// @ViewColumn() +// posExecutiveDays: number; + } diff --git a/src/migration/1740652136299-updateView.ts b/src/migration/1740652136299-updateView.ts new file mode 100644 index 00000000..61bfcfd7 --- /dev/null +++ b/src/migration/1740652136299-updateView.ts @@ -0,0 +1,227 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdateView1740652136299 implements MigrationInterface { + name = 'UpdateView1740652136299' + + public async up(queryRunner: QueryRunner): Promise { + 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\``); + 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 ASC) AS ed_number + FROM profileEducation ed + WHERE ed.isUse IS TRUE + ORDER BY ed.level ASC + ) + SELECT + p.id as profileId, + p.citizenId, + p.rank, + 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.dateRetire, + p.dateRetireLaw, + p.birthdate, + ed.degree, + TIMESTAMPDIFF(YEAR, p.birthdate, CURDATE()) AS age, + vcto.Years, + vcto.Months, + vcto.Days + 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 + Inner Join view_current_tenure_officer vcto On p.id = vcto.profileId + Where vcto.orderNumber Is Null + `); + 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 ASC) 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.rank,\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.dateRetire,\n p.dateRetireLaw,\n p.birthdate,\n ed.degree,\n TIMESTAMPDIFF(YEAR, p.birthdate, CURDATE()) AS age,\n vcto.Years,\n vcto.Months,\n vcto.Days\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\n Inner Join view_current_tenure_officer vcto On p.id = vcto.profileId\n Where vcto.orderNumber Is Null"]); + } + + 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_officer","bma_ehr_organization_demo"]); + await queryRunner.query(`DROP VIEW \`view_registry_officer\``); + 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 ASC) AS ed_number + FROM profileEducation ed + WHERE ed.isUse IS TRUE + ORDER BY ed.level ASC + ) + SELECT + p.id as profileId, + p.citizenId, + p.rank, + 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.dateRetire, + p.dateRetireLaw, + 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 ASC) 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.rank,\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.dateRetire,\n p.dateRetireLaw,\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"]); + } + +}