diff --git a/docs/migrations/fix_GetProfileEmployeeSalaryLevel_calendar_arithmetic.sql b/docs/migrations/fix_GetProfileEmployeeSalaryLevel_calendar_arithmetic.sql deleted file mode 100644 index bca30538..00000000 --- a/docs/migrations/fix_GetProfileEmployeeSalaryLevel_calendar_arithmetic.sql +++ /dev/null @@ -1,140 +0,0 @@ --- ==================================================================== --- Fix GetProfileEmployeeSalaryLevel to use calendar arithmetic --- This changes from fixed formulas to actual calendar arithmetic, --- matching calculateGovAge and GetProfileSalaryLevel behavior --- ==================================================================== - -DELIMITER $$ - -DROP PROCEDURE IF EXISTS `GetProfileEmployeeSalaryLevel`$$ - -CREATE DEFINER=`root`@`%` PROCEDURE `GetProfileEmployeeSalaryLevel`( - IN personId VARCHAR(36), - IN _date DATE -) -BEGIN -WITH ordered AS ( - SELECT * - FROM profileSalary - WHERE profileEmployeeId = personId - AND commandCode IN ('0','1','2','3','4','8','9','10','11','12','13','14','15','16','20') -), -work_session AS ( - SELECT *, - COALESCE( - SUM(CASE WHEN commandCode IN (12,15,16) THEN 1 ELSE 0 END) - OVER (ORDER BY commandDateAffect, commandDateSign - ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING), - 0) AS sessionId - FROM ordered -), -session_end AS ( - SELECT sessionId, MAX(commandDateAffect) AS sessionEndDate - FROM work_session - GROUP BY sessionId -), -level_change AS ( - SELECT *, - CASE - WHEN LAG(positionCee) OVER (ORDER BY commandDateAffect, commandDateSign) <=> positionCee - AND LAG(positionType) OVER (ORDER BY commandDateAffect, commandDateSign) <=> positionType - AND LAG(positionLevel) OVER (ORDER BY commandDateAffect, commandDateSign) <=> positionLevel - AND LAG(sessionId) OVER (ORDER BY commandDateAffect, commandDateSign) = sessionId - THEN 0 - ELSE 1 - END AS isNewLevel - FROM work_session -), -level_group AS ( - SELECT *, - SUM(isNewLevel) OVER (ORDER BY commandDateAffect, commandDateSign) AS levelGroup - FROM level_change -), -first_rows AS ( - SELECT * FROM ( - SELECT *, - ROW_NUMBER() OVER (PARTITION BY levelGroup ORDER BY commandDateAffect, commandDateSign) AS rnLevel - FROM level_group - ) t WHERE rnLevel = 1 -), -rows_with_duration AS ( - SELECT - fr.*, - CASE - WHEN LEAD(fr.commandDateAffect) OVER (ORDER BY fr.commandDateAffect, fr.commandDateSign) IS NULL - THEN NULL - WHEN LEAD(fr.sessionId) OVER (ORDER BY fr.commandDateAffect, fr.commandDateSign) <> fr.sessionId - THEN TIMESTAMPDIFF(DAY, fr.commandDateAffect, se.sessionEndDate) + 1 - ELSE - TIMESTAMPDIFF(DAY, fr.commandDateAffect, - LEAD(fr.commandDateAffect) OVER (ORDER BY fr.commandDateAffect, fr.commandDateSign)) - END AS duration_days - FROM first_rows fr - LEFT JOIN session_end se ON se.sessionId = fr.sessionId -), -resultWithDiff AS ( - SELECT - *, - LAG(duration_days) OVER (ORDER BY commandDateAffect, commandDateSign) AS days_diff - FROM rows_with_duration -) -SELECT - r.commandDateAffect, - r.positionType, - r.positionLevel, - r.positionCee, - r.days_diff, - CASE - WHEN LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign) IS NOT NULL THEN - TIMESTAMPDIFF(YEAR, LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign), r.commandDateAffect) - ELSE 0 - END AS Years, - CASE - WHEN LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign) IS NOT NULL THEN - TIMESTAMPDIFF(MONTH, LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign), r.commandDateAffect) % 12 - ELSE 0 - END AS Months, - CASE - WHEN LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign) IS NOT NULL THEN - DATEDIFF(r.commandDateAffect, - DATE_ADD( - DATE_ADD(LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign), - INTERVAL TIMESTAMPDIFF(YEAR, LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign), r.commandDateAffect) YEAR), - INTERVAL TIMESTAMPDIFF(MONTH, LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign), r.commandDateAffect) % 12 MONTH) - ) - ELSE 0 - END AS Days, - r.posNo, - r.positionExecutive, - r.orgRoot, - r.orgChild1, - r.orgChild2, - r.orgChild3, - r.orgChild4, - r.commandCode, - r.commandName, - r.commandNo, - r.commandYear, - r.remark -FROM resultWithDiff r - -UNION ALL - -SELECT - _date, NULL, NULL, NULL, - TIMESTAMPDIFF(DAY, MAX(commandDateAffect), _date) + 1, - TIMESTAMPDIFF(YEAR, MAX(commandDateAffect), _date), - TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) % 12, - DATEDIFF(_date, - DATE_ADD( - DATE_ADD(MAX(commandDateAffect), - INTERVAL TIMESTAMPDIFF(YEAR, MAX(commandDateAffect), _date) YEAR), - INTERVAL TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) % 12 MONTH) - ), - NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, - NULL,NULL,NULL,NULL -FROM resultWithDiff; - -END$$ - -DELIMITER ; diff --git a/docs/migrations/fix_GetProfileEmployeeSalaryPosition_calendar_arithmetic.sql b/docs/migrations/fix_GetProfileEmployeeSalaryPosition_calendar_arithmetic.sql deleted file mode 100644 index fa53b467..00000000 --- a/docs/migrations/fix_GetProfileEmployeeSalaryPosition_calendar_arithmetic.sql +++ /dev/null @@ -1,137 +0,0 @@ --- ==================================================================== --- Fix GetProfileEmployeeSalaryPosition to use calendar arithmetic --- This changes from fixed formulas to actual calendar arithmetic, --- matching calculateGovAge and GetProfileSalaryPosition behavior --- ==================================================================== - -DELIMITER $$ - -DROP PROCEDURE IF EXISTS `GetProfileEmployeeSalaryPosition`$$ - -CREATE DEFINER=`root`@`%` PROCEDURE `GetProfileEmployeeSalaryPosition`( - IN personId VARCHAR(36), - IN _date DATE -) -BEGIN -WITH ordered AS ( - SELECT * FROM profileSalary WHERE profileEmployeeId = personId AND commandCode IN ('0','1','2','3','4','8','9','10','11','12','13','14','15','16','20') -), -work_session AS ( - SELECT *, - COALESCE( - SUM(CASE WHEN commandCode IN (12,15,16) THEN 1 ELSE 0 END) - OVER (ORDER BY commandDateAffect, commandDateSign - ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING), - 0) AS sessionId - FROM ordered -), -session_end AS ( - SELECT sessionId, MAX(commandDateAffect) AS sessionEndDate - FROM work_session - GROUP BY sessionId -), -position_change AS ( - SELECT *, - CASE - WHEN LAG(positionName) OVER (ORDER BY commandDateAffect, commandDateSign) = positionName - AND LAG(sessionId) OVER (ORDER BY commandDateAffect, commandDateSign) = sessionId - THEN 0 - ELSE 1 - END AS isNewPosition - FROM work_session -), -position_group AS ( - SELECT *, - SUM(isNewPosition) OVER (ORDER BY commandDateAffect, commandDateSign) AS posGroup - FROM position_change -), -first_rows AS ( - SELECT * FROM ( - SELECT *, - ROW_NUMBER() OVER (PARTITION BY posGroup ORDER BY commandDateAffect, commandDateSign) AS rnPos - FROM position_group - ) t WHERE rnPos = 1 -), -rows_with_duration AS ( - SELECT - fr.*, - LEAD(fr.sessionId) OVER (ORDER BY fr.commandDateAffect, fr.commandDateSign) AS nextSessionId, - CASE - WHEN LEAD(fr.commandDateAffect) OVER (ORDER BY fr.commandDateAffect, fr.commandDateSign) IS NULL - THEN NULL - WHEN LEAD(fr.sessionId) OVER (ORDER BY fr.commandDateAffect, fr.commandDateSign) <> fr.sessionId - THEN TIMESTAMPDIFF(DAY, fr.commandDateAffect, se.sessionEndDate) + 1 - ELSE - TIMESTAMPDIFF(DAY, fr.commandDateAffect, - LEAD(fr.commandDateAffect) OVER (ORDER BY fr.commandDateAffect, fr.commandDateSign)) - END AS duration_days - FROM first_rows fr - LEFT JOIN session_end se ON se.sessionId = fr.sessionId -), -resultWithDiff AS ( - SELECT - *, - LAG(duration_days) OVER (ORDER BY commandDateAffect, commandDateSign) AS days_diff - FROM rows_with_duration -) -SELECT - r.commandDateAffect, - r.positionName, - r.positionCee, - r.days_diff, - CASE - WHEN LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign) IS NOT NULL THEN - TIMESTAMPDIFF(YEAR, LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign), r.commandDateAffect) - ELSE 0 - END AS Years, - CASE - WHEN LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign) IS NOT NULL THEN - TIMESTAMPDIFF(MONTH, LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign), r.commandDateAffect) % 12 - ELSE 0 - END AS Months, - CASE - WHEN LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign) IS NOT NULL THEN - TIMESTAMPDIFF(DAY, - DATE_ADD( - DATE_ADD(LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign), - INTERVAL TIMESTAMPDIFF(YEAR, LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign), r.commandDateAffect) YEAR), - INTERVAL TIMESTAMPDIFF(MONTH, LAG(commandDateAffect) OVER (ORDER BY commandDateAffect, commandDateSign), r.commandDateAffect) % 12 MONTH), - r.commandDateAffect) - ELSE 0 - END AS Days, - r.posNo, - r.positionExecutive, - r.positionType, - r.positionLevel, - r.orgRoot, - r.orgChild1, - r.orgChild2, - r.orgChild3, - r.orgChild4, - r.commandCode, - r.commandName, - r.commandNo, - r.commandYear, - r.remark -FROM resultWithDiff r - -UNION ALL - -SELECT - _date, NULL, NULL, - TIMESTAMPDIFF(DAY, MAX(commandDateAffect), _date) + 1, - TIMESTAMPDIFF(YEAR, MAX(commandDateAffect), _date), - TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) % 12, - DATEDIFF(_date, - DATE_ADD( - DATE_ADD(MAX(commandDateAffect), - INTERVAL TIMESTAMPDIFF(YEAR, MAX(commandDateAffect), _date) YEAR), - INTERVAL TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) % 12 MONTH) - ), - NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, - NULL,NULL,NULL,NULL,NULL -FROM resultWithDiff; - -END$$ - -DELIMITER ; diff --git a/docs/migrations/fix_GetProfileSalaryExecutive_calendar_arithmetic.sql b/docs/migrations/fix_GetProfileSalaryExecutive_calendar_arithmetic.sql index 9b1d5d50..e3585c9f 100644 --- a/docs/migrations/fix_GetProfileSalaryExecutive_calendar_arithmetic.sql +++ b/docs/migrations/fix_GetProfileSalaryExecutive_calendar_arithmetic.sql @@ -14,7 +14,7 @@ CREATE DEFINER=`root`@`%` PROCEDURE `GetProfileSalaryExecutive`( ) BEGIN WITH ordered AS ( - SELECT * FROM profileSalary WHERE profileId = personId AND commandCode IN ('0','1','2','3','4','8','9','10','11','12','13','14','15','16','20') AND positionExecutive <> '' + SELECT * FROM profileSalary WHERE profileId = personId AND commandCode IN ('0','1','2','3','4','8','9','10','11','12','13','14','15','16','20') ), work_session AS ( SELECT *, @@ -90,12 +90,12 @@ SELECT END AS Months, CASE WHEN LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign) IS NOT NULL THEN - DATEDIFF(r.commandDateAffect, + TIMESTAMPDIFF(DAY, DATE_ADD( DATE_ADD(LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), INTERVAL TIMESTAMPDIFF(YEAR, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) YEAR), - INTERVAL TIMESTAMPDIFF(MONTH, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) % 12 MONTH) - ) + INTERVAL TIMESTAMPDIFF(MONTH, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) MONTH), + r.commandDateAffect) + 1 ELSE 0 END AS Days, r.posNo, @@ -121,12 +121,12 @@ SELECT TIMESTAMPDIFF(DAY, MAX(commandDateAffect), _date) + 1, TIMESTAMPDIFF(YEAR, MAX(commandDateAffect), _date), TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) % 12, - DATEDIFF(_date, + TIMESTAMPDIFF(DAY, DATE_ADD( DATE_ADD(MAX(commandDateAffect), INTERVAL TIMESTAMPDIFF(YEAR, MAX(commandDateAffect), _date) YEAR), - INTERVAL TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) % 12 MONTH) - ), + INTERVAL TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) MONTH), + _date) + 1, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL FROM resultWithDiff; diff --git a/docs/migrations/fix_GetProfileSalaryLevel_calendar_arithmetic.sql b/docs/migrations/fix_GetProfileSalaryLevel_calendar_arithmetic.sql index 0ce8bbb5..ca811a23 100644 --- a/docs/migrations/fix_GetProfileSalaryLevel_calendar_arithmetic.sql +++ b/docs/migrations/fix_GetProfileSalaryLevel_calendar_arithmetic.sql @@ -94,12 +94,12 @@ SELECT END AS Months, CASE WHEN LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign) IS NOT NULL THEN - DATEDIFF(r.commandDateAffect, + TIMESTAMPDIFF(DAY, DATE_ADD( DATE_ADD(LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), INTERVAL TIMESTAMPDIFF(YEAR, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) YEAR), - INTERVAL TIMESTAMPDIFF(MONTH, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) % 12 MONTH) - ) + INTERVAL TIMESTAMPDIFF(MONTH, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) MONTH), + r.commandDateAffect) + 1 ELSE 0 END AS Days, r.posNo, @@ -123,12 +123,12 @@ SELECT TIMESTAMPDIFF(DAY, MAX(commandDateAffect), _date) + 1, TIMESTAMPDIFF(YEAR, MAX(commandDateAffect), _date), TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) % 12, - DATEDIFF(_date, + TIMESTAMPDIFF(DAY, DATE_ADD( DATE_ADD(MAX(commandDateAffect), INTERVAL TIMESTAMPDIFF(YEAR, MAX(commandDateAffect), _date) YEAR), - INTERVAL TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) % 12 MONTH) - ), + INTERVAL TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) MONTH), + _date) + 1, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL FROM resultWithDiff; diff --git a/docs/migrations/fix_GetProfileSalaryPosition_calendar_arithmetic.sql b/docs/migrations/fix_GetProfileSalaryPosition_calendar_arithmetic.sql index aed2e9e7..a546ad97 100644 --- a/docs/migrations/fix_GetProfileSalaryPosition_calendar_arithmetic.sql +++ b/docs/migrations/fix_GetProfileSalaryPosition_calendar_arithmetic.sql @@ -96,8 +96,8 @@ SELECT DATE_ADD( DATE_ADD(LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), INTERVAL TIMESTAMPDIFF(YEAR, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) YEAR), - INTERVAL TIMESTAMPDIFF(MONTH, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) % 12 MONTH), - r.commandDateAffect) + INTERVAL TIMESTAMPDIFF(MONTH, LAG(r.commandDateAffect) OVER (ORDER BY r.commandDateAffect, r.commandDateSign), r.commandDateAffect) MONTH), + r.commandDateAffect) + 1 ELSE 0 END AS Days, r.posNo, @@ -124,12 +124,12 @@ SELECT TIMESTAMPDIFF(DAY, MAX(commandDateAffect), _date) + 1, TIMESTAMPDIFF(YEAR, MAX(commandDateAffect), _date), TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) % 12, - DATEDIFF(_date, + TIMESTAMPDIFF(DAY, DATE_ADD( DATE_ADD(MAX(commandDateAffect), INTERVAL TIMESTAMPDIFF(YEAR, MAX(commandDateAffect), _date) YEAR), - INTERVAL TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) % 12 MONTH) - ), + INTERVAL TIMESTAMPDIFF(MONTH, MAX(commandDateAffect), _date) MONTH), + _date) + 1, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL FROM resultWithDiff; diff --git a/src/controllers/ApiKeyController.ts b/src/controllers/ApiKeyController.ts index 7de6e415..4c9664d7 100644 --- a/src/controllers/ApiKeyController.ts +++ b/src/controllers/ApiKeyController.ts @@ -20,12 +20,6 @@ import { In } from "typeorm"; import { RequestWithUser } from "../middlewares/user"; import { ApiName } from "../entities/ApiName"; import { ApiHistory } from "../entities/ApiHistory"; -import { OrgRoot } from "../entities/OrgRoot"; -import { OrgChild1 } from "../entities/OrgChild1"; -import { OrgChild2 } from "../entities/OrgChild2"; -import { OrgChild3 } from "../entities/OrgChild3"; -import { OrgChild4 } from "../entities/OrgChild4"; -import { OrgRevision } from "../entities/OrgRevision"; const jwt = require("jsonwebtoken"); @Route("api/v1/org/apiKey") @@ -39,12 +33,6 @@ export class ApiKeyController extends Controller { private apiKeyRepository = AppDataSource.getRepository(ApiKey); private apiNameRepository = AppDataSource.getRepository(ApiName); private apiHistoryRepository = AppDataSource.getRepository(ApiHistory); - private orgRootRepository = AppDataSource.getRepository(OrgRoot); - private orgChild1Repository = AppDataSource.getRepository(OrgChild1); - private orgChild2Repository = AppDataSource.getRepository(OrgChild2); - private orgChild3Repository = AppDataSource.getRepository(OrgChild3); - private orgChild4Repository = AppDataSource.getRepository(OrgChild4); - private orgRevisionRepository = AppDataSource.getRepository(OrgRevision); /** * API ตรวจสอบและถอดรหัส JWT token @@ -163,9 +151,6 @@ export class ApiKeyController extends Controller { relations: ["apiNames", "apiHistorys"], order: { createdAt: "DESC", apiNames: { createdAt: "DESC" } }, }); - - const orgNames = await this.buildOrgNameBatch(apiKey); - const data = apiKey.map((_data) => ({ id: _data.id, createdAt: _data.createdAt, @@ -178,7 +163,6 @@ export class ApiKeyController extends Controller { dnaChild2Id: _data.dnaChild2Id, dnaChild3Id: _data.dnaChild3Id, dnaChild4Id: _data.dnaChild4Id, - orgName: orgNames.get(_data.id), apiNames: _data.apiNames.map((x) => ({ id: x.id, name: x.name, @@ -190,139 +174,10 @@ export class ApiKeyController extends Controller { return new HttpSuccess(data); } - private async buildOrgNameBatch(apiKeys: ApiKey[]): Promise> { - const currentRevision = await this.orgRevisionRepository.findOne({ - where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, - }); - - if (!currentRevision) { - return new Map(apiKeys.map((k) => [k.id, null])); - } - - const currentRevisionId = currentRevision.id; - - const rootIds = [...new Set(apiKeys.map((k) => k.dnaRootId).filter(Boolean))]; - const child1Ids = [...new Set(apiKeys.map((k) => k.dnaChild1Id).filter(Boolean))]; - const child2Ids = [...new Set(apiKeys.map((k) => k.dnaChild2Id).filter(Boolean))]; - const child3Ids = [...new Set(apiKeys.map((k) => k.dnaChild3Id).filter(Boolean))]; - const child4Ids = [...new Set(apiKeys.map((k) => k.dnaChild4Id).filter(Boolean))]; - - const [roots, child1s, child2s, child3s, child4s] = await Promise.all([ - rootIds.length > 0 - ? this.orgRootRepository.find({ - where: [ - { id: In(rootIds), orgRevisionId: currentRevisionId }, - { ancestorDNA: In(rootIds), orgRevisionId: currentRevisionId }, - ], - select: ["id", "ancestorDNA", "orgRootName"], - }) - : [], - child1Ids.length > 0 - ? this.orgChild1Repository.find({ - where: [ - { id: In(child1Ids), orgRevisionId: currentRevisionId }, - { ancestorDNA: In(child1Ids), orgRevisionId: currentRevisionId }, - ], - select: ["id", "ancestorDNA", "orgChild1Name"], - }) - : [], - child2Ids.length > 0 - ? this.orgChild2Repository.find({ - where: [ - { id: In(child2Ids), orgRevisionId: currentRevisionId }, - { ancestorDNA: In(child2Ids), orgRevisionId: currentRevisionId }, - ], - select: ["id", "ancestorDNA", "orgChild2Name"], - }) - : [], - child3Ids.length > 0 - ? this.orgChild3Repository.find({ - where: [ - { id: In(child3Ids), orgRevisionId: currentRevisionId }, - { ancestorDNA: In(child3Ids), orgRevisionId: currentRevisionId }, - ], - select: ["id", "ancestorDNA", "orgChild3Name"], - }) - : [], - child4Ids.length > 0 - ? this.orgChild4Repository.find({ - where: [ - { id: In(child4Ids), orgRevisionId: currentRevisionId }, - { ancestorDNA: In(child4Ids), orgRevisionId: currentRevisionId }, - ], - select: ["id", "ancestorDNA", "orgChild4Name"], - }) - : [], - ]); - - const rootMap = new Map( - roots.map((r) => [r.id, { name: r.orgRootName, ancestorDNA: r.ancestorDNA }]), - ); - const child1Map = new Map( - child1s.map((c) => [c.id, { name: c.orgChild1Name, ancestorDNA: c.ancestorDNA }]), - ); - const child2Map = new Map( - child2s.map((c) => [c.id, { name: c.orgChild2Name, ancestorDNA: c.ancestorDNA }]), - ); - const child3Map = new Map( - child3s.map((c) => [c.id, { name: c.orgChild3Name, ancestorDNA: c.ancestorDNA }]), - ); - const child4Map = new Map( - child4s.map((c) => [c.id, { name: c.orgChild4Name, ancestorDNA: c.ancestorDNA }]), - ); - - const result = new Map(); - for (const apiKey of apiKeys) { - if (apiKey.accessType === "ALL") { - result.set(apiKey.id, null); - continue; - } - - const parts: string[] = []; - - const getOrgName = ( - dnaId: string, - orgMap: Map, - ): string | null => { - const byId = orgMap.get(dnaId); - if (byId) return byId.name; - for (const [, value] of orgMap) { - if (value.ancestorDNA === dnaId) return value.name; - } - return null; - }; - - if (apiKey.dnaChild4Id) { - const name = getOrgName(apiKey.dnaChild4Id, child4Map); - if (name) parts.push(name); - } - if (apiKey.dnaChild3Id) { - const name = getOrgName(apiKey.dnaChild3Id, child3Map); - if (name) parts.push(name); - } - if (apiKey.dnaChild2Id) { - const name = getOrgName(apiKey.dnaChild2Id, child2Map); - if (name) parts.push(name); - } - if (apiKey.dnaChild1Id) { - const name = getOrgName(apiKey.dnaChild1Id, child1Map); - if (name) parts.push(name); - } - if (apiKey.dnaRootId) { - const name = getOrgName(apiKey.dnaRootId, rootMap); - if (name) parts.push(name); - } - - result.set(apiKey.id, parts.length > 0 ? parts.join(" ") : null); - } - - return result; - } - /** - * API รายการ Api Name + * API รายการ Api Key * - * @summary รายการ Api Name (ADMIN) + * @summary รายการ Api Key (ADMIN) * */ @Get("name") diff --git a/src/controllers/ApiManageController.ts b/src/controllers/ApiManageController.ts index 17f14050..01a27eb5 100644 --- a/src/controllers/ApiManageController.ts +++ b/src/controllers/ApiManageController.ts @@ -106,10 +106,10 @@ export class ApiManageController extends Controller { code: "organization", name: "ข้อมูลโครงสร้าง", }, - // { - // code: "position", - // name: "ข้อมูลอัตรากำลัง", - // }, + { + code: "position", + name: "ข้อมูลอัตรากำลัง", + }, ]; // รายการเอนทิตีทั้งหมด @@ -273,240 +273,59 @@ export class ApiManageController extends Controller { description: "ข้อมูลส่วนราชการ ระดับที่ 4", system: ["organization"], }, - // { - // name: "PosMaster", - // repository: this.posMasterRepository, - // description: "ข้อมูลอัตรากำลัง", - // isMain: true, - // system: ["position"], - // }, - // { - // name: "Position", - // repository: this.positionRepository, - // description: "ข้อมูลตำแหน่ง", - // system: ["position"], - // }, - // { - // name: "OrgRoot", - // repository: this.orgRootRepository, - // description: "ข้อมูลหน่วยงาน", - // system: ["position"], - // }, - // { - // name: "OrgChild1", - // repository: this.orgChild1Repository, - // description: "ข้อมูลส่วนราชการ ระดับที่ 1", - // system: ["position"], - // }, - // { - // name: "OrgChild2", - // repository: this.orgChild2Repository, - // description: "ข้อมูลส่วนราชการ ระดับที่ 2", - // system: ["position"], - // }, - // { - // name: "OrgChild3", - // repository: this.orgChild3Repository, - // description: "ข้อมูลส่วนราชการ ระดับที่ 3", - // system: ["position"], - // }, - // { - // name: "OrgChild4", - // repository: this.orgChild4Repository, - // description: "ข้อมูลส่วนราชการ ระดับที่ 4", - // system: ["position"], - // }, - // { - // name: "Profile", - // repository: this.profileRepository, - // description: "ข้อมูลคนครอง", - // system: ["position"], - // }, + { + name: "PosMaster", + repository: this.posMasterRepository, + description: "ข้อมูลอัตรากำลัง", + isMain: true, + system: ["position"], + }, + { + name: "Position", + repository: this.positionRepository, + description: "ข้อมูลตำแหน่ง", + system: ["position"], + }, + { + name: "OrgRoot", + repository: this.orgRootRepository, + description: "ข้อมูลหน่วยงาน", + system: ["position"], + }, + { + name: "OrgChild1", + repository: this.orgChild1Repository, + description: "ข้อมูลส่วนราชการ ระดับที่ 1", + system: ["position"], + }, + { + name: "OrgChild2", + repository: this.orgChild2Repository, + description: "ข้อมูลส่วนราชการ ระดับที่ 2", + system: ["position"], + }, + { + name: "OrgChild3", + repository: this.orgChild3Repository, + description: "ข้อมูลส่วนราชการ ระดับที่ 3", + system: ["position"], + }, + { + name: "OrgChild4", + repository: this.orgChild4Repository, + description: "ข้อมูลส่วนราชการ ระดับที่ 4", + system: ["position"], + }, + { + name: "Profile", + repository: this.profileRepository, + description: "ข้อมูลคนครอง", + system: ["position"], + }, ]; private readonly DEFAULT_PAGE_SIZE = 10; // ขนาดหน้าเริ่มต้น - private readonly EXCLUDED_COLUMNS = [ - "createdUserId", - "lastUpdateUserId", - "createdAt", - "createdFullName", - "lastUpdateFullName", - "avatarName", - "profileId", - "prefixId", - "profileEmployeeId", - "documentId", - "orgRevisionId", - "posMasterId", - "orgRootId", - "orgChild1Id", - "orgChild2Id", - "orgChild3Id", - "orgChild4Id", - "keycloak", - "commandId", - "prefixMain", - "authRoleId", - "next_holderId", - "current_holderId", - "ancestorDNA", - "leaveCommandId", - "posLevelId", - "posTypeId", - "posExecutiveId", - "registrationProvinceId", - "registrationDistrictId", - "registrationSubDistrictId", - "currentProvinceId", - "currentDistrictId", - "currentSubDistrictId", - "isDelete", - "keycloak", - "statusCheckEdit", - "privacyCheckin", - "privacyUser", - "privacyMgt", - "dutyTimeId", - "dutyTimeEffectiveDate", - "profileId", - "profileEmployeeId", - "orgRevisionId", - "rank", - "isUpload", - "isDeleted", - "isEntry", - "prefixId", - "leaveId", - "leaveTypeId", - "isDeputy", - "isCommission", - ]; // ฟิลด์ที่ไม่ต้องการแสดงในผลลัพธ์ - - // การแทนที่ฟิลด์ ID ด้วยฟิลด์ Name สำหรับ Profile entity - private readonly PROFILE_FIELD_REPLACEMENTS: Record< - string, - { propertyName: string; type: string; comment: string; joinTable: string; joinField: string } - > = { - posLevelId: { - propertyName: "posLevelName", - type: "string", - comment: "ระดับตำแหน่ง", - joinTable: "PosLevel", - joinField: "posLevelName", - }, - posTypeId: { - propertyName: "posTypeName", - type: "string", - comment: "ประเภทตำแหน่ง", - joinTable: "PosType", - joinField: "posTypeName", - }, - registrationProvinceId: { - propertyName: "registrationProvinceName", - type: "string", - comment: "จังหวัดตามทะเบียนบ้าน", - joinTable: "Province", - joinField: "name", - }, - registrationDistrictId: { - propertyName: "registrationDistrictName", - type: "string", - comment: "เขตตามทะเบียนบ้าน", - joinTable: "District", - joinField: "name", - }, - registrationSubDistrictId: { - propertyName: "registrationSubDistrictName", - type: "string", - comment: "แขวงตามทะเบียนบ้าน", - joinTable: "SubDistrict", - joinField: "name", - }, - currentProvinceId: { - propertyName: "currentProvinceName", - type: "string", - comment: "จังหวัดตามปัจจุบัน", - joinTable: "Province", - joinField: "name", - }, - currentDistrictId: { - propertyName: "currentDistrictName", - type: "string", - comment: "เขตตามปัจจุบัน", - joinTable: "District", - joinField: "name", - }, - currentSubDistrictId: { - propertyName: "currentSubDistrictName", - type: "string", - comment: "แขวงตามปัจจุบัน", - joinTable: "SubDistrict", - joinField: "name", - }, - }; - - // การแทนที่ฟิลด์ ID ด้วยฟิลด์ Name สำหรับ Position entity - private readonly POSITION_FIELD_REPLACEMENTS: Record< - string, - { propertyName: string; type: string; comment: string; joinTable: string; joinField: string } - > = { - posTypeId: { - propertyName: "posTypeName", - type: "string", - comment: "ประเภทตำแหน่ง", - joinTable: "PosType", - joinField: "posTypeName", - }, - posLevelId: { - propertyName: "posLevelName", - type: "string", - comment: "ระดับตำแหน่ง", - joinTable: "PosLevel", - joinField: "posLevelName", - }, - posExecutiveId: { - propertyName: "posExecutiveName", - type: "string", - comment: "ตำแหน่งทางการบริหาร", - joinTable: "PosExecutive", - joinField: "posExecutiveName", - }, - }; - - // การแทนที่ฟิลด์ ID ด้วยฟิลด์ Name สำหรับ ProfileEmployee entity - private readonly PROFILEEMPLOYEE_FIELD_REPLACEMENTS: Record< - string, - { propertyName: string; type: string; comment: string; joinTable: string; joinField: string } - > = { - posLevelId: { - propertyName: "posLevelName", - type: "string", - comment: "ระดับชั้นงาน", - joinTable: "EmployeePosLevel", - joinField: "posLevelName", - }, - posTypeId: { - propertyName: "posTypeName", - type: "string", - comment: "กลุ่มงาน", - joinTable: "EmployeePosType", - joinField: "posTypeName", - }, - }; - - // การแทนที่ฟิลด์ ID ด้วยฟิลด์ Name สำหรับ ProfileLeave entity - private readonly PROFILELEAVE_FIELD_REPLACEMENTS: Record< - string, - { propertyName: string; type: string; comment: string; joinTable: string; joinField: string } - > = { - leaveTypeId: { - propertyName: "leaveTypeName", - type: "string", - comment: "ประเภทการลา", - joinTable: "LeaveType", - joinField: "name", - }, - }; + private readonly EXCLUDED_COLUMNS = ["createdUserId", "lastUpdateUserId"]; // ฟิลด์ที่ไม่ต้องการแสดงในผลลัพธ์ private validateSuperAdminRole(user: any): void { if (!user.role.includes("SUPER_ADMIN")) { @@ -545,8 +364,11 @@ export class ApiManageController extends Controller { const result = this.entities .filter((entity) => entity.system.includes(system)) - .map(({ name, repository, description, isMain }) => { - let columns = repository.metadata.columns + .map(({ name, repository, description, isMain }) => ({ + tb: name, + description, + isMain: isMain || false, + propertys: repository.metadata.columns .filter( (column: any) => !column.isPrimary && !this.EXCLUDED_COLUMNS.includes(column.propertyName), @@ -556,114 +378,8 @@ export class ApiManageController extends Controller { type: typeof column.type === "string" ? column.type : "string", comment: column.comment, key: column.propertyName, - })); - - // Special handling for Profile entity - replace ID fields with name fields - if (name === "Profile") { - const replacementKeys = Object.keys(this.PROFILE_FIELD_REPLACEMENTS); - - // Remove ID fields that should be replaced - columns = columns.filter( - (col: { propertyName: string }) => !replacementKeys.includes(col.propertyName), - ); - - // Add the corresponding name fields - const nameFields = replacementKeys.map((key) => ({ - propertyName: this.PROFILE_FIELD_REPLACEMENTS[key].propertyName, - type: "string", - comment: this.PROFILE_FIELD_REPLACEMENTS[key].comment, - key: this.PROFILE_FIELD_REPLACEMENTS[key].propertyName, - })); - - columns = [...columns, ...nameFields]; - } - - // Special handling for Position entity - replace ID fields with name fields - if (name === "Position") { - const replacementKeys = Object.keys(this.POSITION_FIELD_REPLACEMENTS); - - // Remove ID fields that should be replaced - columns = columns.filter( - (col: { propertyName: string }) => !replacementKeys.includes(col.propertyName), - ); - - // Add the corresponding name fields - const nameFields = replacementKeys.map((key) => ({ - propertyName: this.POSITION_FIELD_REPLACEMENTS[key].propertyName, - type: "string", - comment: this.POSITION_FIELD_REPLACEMENTS[key].comment, - key: this.POSITION_FIELD_REPLACEMENTS[key].propertyName, - })); - - columns = [...columns, ...nameFields]; - } - - // Special handling for ProfileEmployee entity - replace ID fields with name fields - if (name === "ProfileEmployee") { - const replacementKeys = Object.keys(this.PROFILEEMPLOYEE_FIELD_REPLACEMENTS); - - // Remove ID fields that should be replaced - columns = columns.filter( - (col: { propertyName: string }) => !replacementKeys.includes(col.propertyName), - ); - - // Add the corresponding name fields - const nameFields = replacementKeys.map((key) => ({ - propertyName: this.PROFILEEMPLOYEE_FIELD_REPLACEMENTS[key].propertyName, - type: "string", - comment: this.PROFILEEMPLOYEE_FIELD_REPLACEMENTS[key].comment, - key: this.PROFILEEMPLOYEE_FIELD_REPLACEMENTS[key].propertyName, - })); - - columns = [...columns, ...nameFields]; - } - - // Special handling for ProfileLeave entity - replace ID fields with name fields - if (name === "ProfileLeave") { - const replacementKeys = Object.keys(this.PROFILELEAVE_FIELD_REPLACEMENTS); - - // Remove ID fields that should be replaced - columns = columns.filter( - (col: { propertyName: string }) => !replacementKeys.includes(col.propertyName), - ); - - // Add the corresponding name fields - const nameFields = replacementKeys.map((key) => ({ - propertyName: this.PROFILELEAVE_FIELD_REPLACEMENTS[key].propertyName, - type: "string", - comment: this.PROFILELEAVE_FIELD_REPLACEMENTS[key].comment, - key: this.PROFILELEAVE_FIELD_REPLACEMENTS[key].propertyName, - })); - - columns = [...columns, ...nameFields]; - } - - // Special handling for PosMaster entity - add Profile fields for holder information - if (name === "PosMaster") { - // Add Profile fields that are accessible via current_holder relation - const profileFields = ["prefix", "rank", "firstName", "lastName", "citizenId"]; - const profileRepository = AppDataSource.getRepository(Profile); - const profileColumns = profileRepository.metadata.columns - .filter( - (column: any) => !column.isPrimary && profileFields.includes(column.propertyName), - ) - .map((column: any) => ({ - propertyName: `Profile.${column.propertyName}`, - type: typeof column.type === "string" ? column.type : "string", - comment: column.comment, - key: `Profile.${column.propertyName}`, - })); - - columns = [...columns, ...profileColumns]; - } - - return { - tb: name, - description, - isMain: isMain || false, - propertys: columns, - }; - }); + })), + })); return new HttpSuccess(result); } catch (error) { diff --git a/src/controllers/ApiWebServiceController.ts b/src/controllers/ApiWebServiceController.ts index fbf0ab78..61f3d54a 100644 --- a/src/controllers/ApiWebServiceController.ts +++ b/src/controllers/ApiWebServiceController.ts @@ -8,11 +8,6 @@ import { isPermissionRequest } from "../middlewares/authWebService"; import { RequestWithUserWebService } from "../middlewares/user"; import { OrgRevision } from "../entities/OrgRevision"; import { ApiHistory } from "../entities/ApiHistory"; -import { OrgRoot } from "../entities/OrgRoot"; -import { OrgChild1 } from "../entities/OrgChild1"; -import { OrgChild2 } from "../entities/OrgChild2"; -import { OrgChild3 } from "../entities/OrgChild3"; -import { OrgChild4 } from "../entities/OrgChild4"; import { SystemCode } from "./../interfaces/api-type"; @Route("api/v1/org/api-service") @Tags("ApiKey") @@ -25,198 +20,6 @@ export class ApiWebServiceController extends Controller { private apiNameRepository = AppDataSource.getRepository(ApiName); private orgRevisionRepository = AppDataSource.getRepository(OrgRevision); private apiHistoryRepository = AppDataSource.getRepository(ApiHistory); - private currentRevisionId: string = ""; - - // การแทนที่ฟิลด์ ID ด้วยฟิลด์ Name สำหรับ Profile entity - private readonly PROFILE_FIELD_REPLACEMENTS: Record< - string, - { propertyName: string; joinRelation: string; joinField: string } - > = { - posLevelName: { - propertyName: "posLevelId", - joinRelation: "posLevel", - joinField: "posLevelName", - }, - posTypeName: { - propertyName: "posTypeId", - joinRelation: "posType", - joinField: "posTypeName", - }, - registrationProvinceName: { - propertyName: "registrationProvinceId", - joinRelation: "registrationProvince", - joinField: "name", - }, - registrationDistrictName: { - propertyName: "registrationDistrictId", - joinRelation: "registrationDistrict", - joinField: "name", - }, - registrationSubDistrictName: { - propertyName: "registrationSubDistrictId", - joinRelation: "registrationSubDistrict", - joinField: "name", - }, - currentProvinceName: { - propertyName: "currentProvinceId", - joinRelation: "currentProvince", - joinField: "name", - }, - currentDistrictName: { - propertyName: "currentDistrictId", - joinRelation: "currentDistrict", - joinField: "name", - }, - currentSubDistrictName: { - propertyName: "currentSubDistrictId", - joinRelation: "currentSubDistrict", - joinField: "name", - }, - }; - - // การแทนที่ฟิลด์ ID ด้วยฟิลด์ Name สำหรับ ProfileLeave entity - private readonly PROFILELEAVE_FIELD_REPLACEMENTS: Record< - string, - { propertyName: string; joinRelation: string; joinField: string } - > = { - leaveTypeName: { - propertyName: "leaveTypeId", - joinRelation: "leaveType", - joinField: "name", - }, - }; - - // การแทนที่ฟิลด์ ID ด้วยฟิลด์ Name สำหรับ Position entity - private readonly POSITION_FIELD_REPLACEMENTS: Record< - string, - { propertyName: string; joinRelation: string; joinField: string } - > = { - posTypeName: { - propertyName: "posTypeId", - joinRelation: "posType", - joinField: "posTypeName", - }, - posLevelName: { - propertyName: "posLevelId", - joinRelation: "posLevel", - joinField: "posLevelName", - }, - posExecutiveName: { - propertyName: "posExecutiveId", - joinRelation: "posExecutive", - joinField: "posExecutiveName", - }, - }; - - // การแทนที่ฟิลด์ ID ด้วยฟิลด์ Name สำหรับ ProfileEmployee entity - private readonly PROFILEEMPLOYEE_FIELD_REPLACEMENTS: Record< - string, - { propertyName: string; joinRelation: string; joinField: string } - > = { - posTypeName: { - propertyName: "posTypeId", - joinRelation: "posType", - joinField: "posTypeName", - }, - posLevelName: { - propertyName: "posLevelId", - joinRelation: "posLevel", - joinField: "posLevelName", - }, - }; - - /** - * build posMaster permission condition - * @summary สร้างเงื่อนไขการกรองข้อมูลตามสิทธิ์การเข้าถึง - */ - private buildPosMasterPermissionCondition( - accessType: string | undefined, - dnaIds: { - dnaRootId?: string | null; - dnaChild1Id?: string | null; - dnaChild2Id?: string | null; - dnaChild3Id?: string | null; - dnaChild4Id?: string | null; - }, - tableAlias: string = "posMaster", - ): string { - // ALL - no filtering - if (accessType === "ALL") { - return "1=1"; - } - - // No access type specified but has DNA IDs - default to NORMAL behavior - const conditions: string[] = []; - - if (accessType === "ROOT" && dnaIds.dnaRootId) { - // All organizations under this root - conditions.push( - `${tableAlias}.orgRootId IN (SELECT id FROM orgRoot WHERE orgRevisionId = "${this.currentRevisionId}" AND ancestorDNA LIKE "${dnaIds.dnaRootId}%")`, - ); - } else if (accessType === "CHILD" || accessType === "NORMAL") { - // Build conditions based on which DNA level is specified - if (dnaIds.dnaChild4Id) { - conditions.push( - `${tableAlias}.orgChild4Id IN (SELECT id FROM orgChild4 WHERE orgRevisionId = "${this.currentRevisionId}" AND ancestorDNA = "${dnaIds.dnaChild4Id}")`, - ); - } else if (dnaIds.dnaChild3Id) { - conditions.push( - `${tableAlias}.orgChild3Id IN (SELECT id FROM orgChild3 WHERE orgRevisionId = "${this.currentRevisionId}" AND ancestorDNA = "${dnaIds.dnaChild3Id}")`, - ); - // For CHILD type, include all descendants - if (accessType === "CHILD") { - conditions.push( - `(${tableAlias}.orgChild3Id IN (SELECT id FROM orgChild3 WHERE orgRevisionId = "${this.currentRevisionId}" AND ancestorDNA LIKE "${dnaIds.dnaChild3Id}%") OR ${tableAlias}.orgChild4Id IS NOT NULL)`, - ); - } - } else if (dnaIds.dnaChild2Id) { - conditions.push( - `${tableAlias}.orgChild2Id IN (SELECT id FROM orgChild2 WHERE orgRevisionId = "${this.currentRevisionId}" AND ancestorDNA = "${dnaIds.dnaChild2Id}")`, - ); - if (accessType === "CHILD") { - conditions.push( - `(${tableAlias}.orgChild2Id IN (SELECT id FROM orgChild2 WHERE orgRevisionId = "${this.currentRevisionId}" AND ancestorDNA LIKE "${dnaIds.dnaChild2Id}%") OR ${tableAlias}.orgChild3Id IS NOT NULL)`, - ); - } - } else if (dnaIds.dnaChild1Id) { - conditions.push( - `${tableAlias}.orgChild1Id IN (SELECT id FROM orgChild1 WHERE orgRevisionId = "${this.currentRevisionId}" AND ancestorDNA = "${dnaIds.dnaChild1Id}")`, - ); - if (accessType === "CHILD") { - conditions.push( - `(${tableAlias}.orgChild1Id IN (SELECT id FROM orgChild1 WHERE orgRevisionId = "${this.currentRevisionId}" AND ancestorDNA LIKE "${dnaIds.dnaChild1Id}%") OR ${tableAlias}.orgChild2Id IS NOT NULL)`, - ); - } - } else if (dnaIds.dnaRootId) { - conditions.push( - `${tableAlias}.orgRootId IN (SELECT id FROM orgRoot WHERE orgRevisionId = "${this.currentRevisionId}" AND ancestorDNA = "${dnaIds.dnaRootId}")`, - ); - if (accessType === "CHILD") { - conditions.push( - `(${tableAlias}.orgRootId IN (SELECT id FROM orgRoot WHERE orgRevisionId = "${this.currentRevisionId}" AND ancestorDNA LIKE "${dnaIds.dnaRootId}%") OR ${tableAlias}.orgChild1Id IS NOT NULL)`, - ); - } - } - } - - return conditions.length > 0 ? `(${conditions.join(" OR ")})` : "1=1"; - } - - /** - * rename ancestorDNA to id - * @summary เปลี่ยนชื่อฟิลด์ ancestorDNA เป็น id - */ - private renameAncestorDnaToId(obj: any): any { - if (!obj || typeof obj !== "object") { - return obj; - } - const result = { ...obj }; - if (result.ancestorDNA !== undefined) { - result.id = result.ancestorDNA; - delete result.ancestorDNA; - } - return result; - } /** * list fields by systems @@ -247,42 +50,12 @@ export class ApiWebServiceController extends Controller { } await isPermissionRequest(request, apiName.id); const offset = (page - 1) * pageSize; - let propertyKey = apiName.apiAttributes.map((attr) => `${attr.tbName}.${attr.propertyKey}`); - const selectedFieldsByTable: Record> = {}; - apiName.apiAttributes.forEach((attr) => { - if (!selectedFieldsByTable[attr.tbName]) { - selectedFieldsByTable[attr.tbName] = new Set(); - } - selectedFieldsByTable[attr.tbName].add(attr.propertyKey); - }); - - // สำหรับ Organization: ให้รวม ancestorDNA เสมอ เพื่อแสดงเป็น id - if (system === "organization") { - // สำหรับ OrgRoot - const ancestorDnaField = "OrgRoot.ancestorDNA"; - if (!propertyKey.includes(ancestorDnaField)) { - propertyKey.push(ancestorDnaField); - } - if (!selectedFieldsByTable["OrgRoot"]) { - selectedFieldsByTable["OrgRoot"] = new Set(); - } - selectedFieldsByTable["OrgRoot"].add("ancestorDNA"); - - // สำหรับ OrgChild1, OrgChild2, OrgChild3, OrgChild4 - const childTables = ["OrgChild1", "OrgChild2", "OrgChild3", "OrgChild4"]; - childTables.forEach((table) => { - if (!selectedFieldsByTable[table]) { - selectedFieldsByTable[table] = new Set(); - } - selectedFieldsByTable[table].add("ancestorDNA"); - }); - } + const propertyKey = apiName.apiAttributes.map((attr) => `${attr.tbName}.${attr.propertyKey}`); let tbMain: string = ""; let condition: string = "1=1"; if (system == "registry") { tbMain = "Profile"; - condition = `Profile.isActive = true AND Profile.isDelete = false`; } else if (system == "registry_emp") { tbMain = "ProfileEmployee"; condition = `ProfileEmployee.employeeClass = "PERM"`; @@ -305,152 +78,6 @@ export class ApiWebServiceController extends Controller { condition = `PosMaster.orgRevisionId = "${revision?.id}"`; } - let posMasterCondition: string = "1=1"; - let posMasterAlias: string = ""; - - // Add isDeleted filtering for entities that have this field - // Profile.ts uses isDelete (singular) instead of isDeleted - if (tbMain === "Profile") { - // Already handled above in the registry system condition - } else if ( - [ - "ProfileAbility", - "ProfileAbilityHistory", - "ProfileAbsentLate", - "ProfileActposition", - "ProfileActpositionHistory", - "ProfileAssistance", - "ProfileAssistanceHistory", - "ProfileAssessment", - "ProfileAssessmentHistory", - "ProfileCertificate", - "ProfileCertificateHistory", - "ProfileChangeName", - "ProfileChangeNameHistory", - "ProfileChildren", - "ProfileChildrenHistory", - "ProfileDiscipline", - "ProfileDisciplineHistory", - "ProfileDevelopment", - "ProfileDevelopmentHistory", - "ProfileDuty", - "ProfileDutyHistory", - "ProfileEducation", - "ProfileEducationHistory", - "ProfileHonor", - "ProfileHonorHistory", - "ProfileInsignia", - "ProfileInsigniaHistory", - "ProfileLeave", - "ProfileNopaid", - "ProfileNopaidHistory", - "ProfileOther", - "ProfileOtherHistory", - "ProfileSalary", - "ProfileSalaryHistory", - "ProfileSalaryTemp", - "ProfileTraining", - "ProfileTrainingHistory", - ].includes(tbMain) - ) { - condition = `${tbMain}.isDeleted = false`; - } - - // Special handling for Profile and ProfileEmployee systems with permission filtering - if (system == "registry") { - // Get current revision - const revision = await this.orgRevisionRepository.findOne({ - select: ["id"], - where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, - }); - - // Store for use in permission building - this.currentRevisionId = revision?.id || ""; - posMasterAlias = "posMaster"; - - // Build permission condition - posMasterCondition = this.buildPosMasterPermissionCondition( - request.user.accessType, - { - dnaRootId: request.user.dnaRootId, - dnaChild1Id: request.user.dnaChild1Id, - dnaChild2Id: request.user.dnaChild2Id, - dnaChild3Id: request.user.dnaChild3Id, - dnaChild4Id: request.user.dnaChild4Id, - }, - posMasterAlias, - ); - } else if (system == "registry_emp") { - // Get current revision - const revision = await this.orgRevisionRepository.findOne({ - select: ["id"], - where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, - }); - - // Store for use in permission building - this.currentRevisionId = revision?.id || ""; - posMasterAlias = "employeePosMaster"; - - // Build permission condition - posMasterCondition = this.buildPosMasterPermissionCondition( - request.user.accessType, - { - dnaRootId: request.user.dnaRootId, - dnaChild1Id: request.user.dnaChild1Id, - dnaChild2Id: request.user.dnaChild2Id, - dnaChild3Id: request.user.dnaChild3Id, - dnaChild4Id: request.user.dnaChild4Id, - }, - posMasterAlias, - ); - } else if (system == "registry_temp") { - // Get current revision - const revision = await this.orgRevisionRepository.findOne({ - select: ["id"], - where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, - }); - - // Store for use in permission building - this.currentRevisionId = revision?.id || ""; - posMasterAlias = "employeeTempPosMaster"; - - // Build permission condition - posMasterCondition = this.buildPosMasterPermissionCondition( - request.user.accessType, - { - dnaRootId: request.user.dnaRootId, - dnaChild1Id: request.user.dnaChild1Id, - dnaChild2Id: request.user.dnaChild2Id, - dnaChild3Id: request.user.dnaChild3Id, - dnaChild4Id: request.user.dnaChild4Id, - }, - posMasterAlias, - ); - } else if (system == "position") { - // Get current revision - const revision = await this.orgRevisionRepository.findOne({ - select: ["id"], - where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, - }); - - // Store for use in permission building - this.currentRevisionId = revision?.id || ""; - posMasterAlias = "PosMaster"; // Note: Uses PascalCase to match tbMain alias - - // Build permission condition - posMasterCondition = this.buildPosMasterPermissionCondition( - request.user.accessType, - { - dnaRootId: request.user.dnaRootId, - dnaChild1Id: request.user.dnaChild1Id, - dnaChild2Id: request.user.dnaChild2Id, - dnaChild3Id: request.user.dnaChild3Id, - dnaChild4Id: request.user.dnaChild4Id, - }, - posMasterAlias, - ); - } - const repo = AppDataSource.getRepository(tbMain); const metadata = repo.metadata; @@ -465,271 +92,27 @@ export class ApiWebServiceController extends Controller { ...new Set(propertyKey.map((x) => x.split(".")[0]).filter((tb) => tb !== tbMain)), ]; - // Organization hierarchy is assembled in a separate step; keep main query focused on OrgRoot only. - if (tbMain === "OrgRoot") { - const orgChildTables = new Set(["OrgChild1", "OrgChild2", "OrgChild3", "OrgChild4"]); - propertyKey = propertyKey.filter((key) => !orgChildTables.has(key.split(".")[0])); - propertyOtherKey = propertyOtherKey.filter((tb) => !orgChildTables.has(tb)); - } - - // สำหรับ Profile: ตรวจสอบฟิลด์ที่ต้องการ join และแปลง propertyKey - const profileFieldJoins: Record = {}; // alias -> relationName - if (tbMain === "Profile") { - propertyKey = propertyKey.map((key) => { - const [table, field] = key.split("."); - if (table === "Profile") { - const replacement = this.PROFILE_FIELD_REPLACEMENTS[field]; - if (replacement) { - const alias = `${table}_${replacement.joinRelation}`; - profileFieldJoins[alias] = replacement.joinRelation; - return `${alias}.${replacement.joinField}`; - } - } - return key; - }); - } - - // สำหรับ Position: ตรวจสอบฟิลด์ที่ต้องการ join และแปลง propertyKey - const positionFieldJoins: Record = {}; // alias -> relationName - if (tbMain === "Position" || tbMain === "PosMaster") { - propertyKey = propertyKey.map((key) => { - const [table, field] = key.split("."); - if (table === "Position") { - const replacement = this.POSITION_FIELD_REPLACEMENTS[field]; - if (replacement) { - const alias = `${table}_${replacement.joinRelation}`; - positionFieldJoins[alias] = replacement.joinRelation; - return `${alias}.${replacement.joinField}`; - } - } - return key; - }); - } - - // สำหรับ ProfileEmployee: ตรวจสอบฟิลด์ที่ต้องการ join และแปลง propertyKey - const profileEmployeeFieldJoins: Record = {}; // alias -> relationName - if (tbMain === "ProfileEmployee") { - propertyKey = propertyKey.map((key) => { - const [table, field] = key.split("."); - if (table === "ProfileEmployee") { - const replacement = this.PROFILEEMPLOYEE_FIELD_REPLACEMENTS[field]; - if (replacement) { - const alias = `${table}_${replacement.joinRelation}`; - profileEmployeeFieldJoins[alias] = replacement.joinRelation; - return `${alias}.${replacement.joinField}`; - } - } - return key; - }); - } - - // สำหรับ ProfileLeave: ตรวจสอบฟิลด์ที่ต้องการ join และแปลง propertyKey - const profileLeaveFieldJoins: Record = {}; // alias -> relationName - // Process ProfileLeave fields regardless of main table - propertyKey = propertyKey.map((key) => { - const [table, field] = key.split("."); - if (table === "ProfileLeave") { - const replacement = this.PROFILELEAVE_FIELD_REPLACEMENTS[field]; - if (replacement) { - const alias = `${table}_${replacement.joinRelation}`; - profileLeaveFieldJoins[alias] = replacement.joinRelation; - return `${alias}.${replacement.joinField}`; - } - } - return key; - }); - const queryBuilder = repo.createQueryBuilder(tbMain); // join กับตารารอง if (propertyOtherKey.length > 0) { propertyOtherKey.forEach((tb) => { - // Skip Profile join for PosMaster - it's handled separately below - if (tbMain === "PosMaster" && tb === "Profile") { - return; - } - - // Skip Position join for PosMaster - it's handled separately below - if (tbMain === "PosMaster" && tb === "Position") { - return; - } - const relationName = relationMap[tb]; if (relationName) { - queryBuilder.leftJoin(`${tbMain}.${relationName}`, tb); - } else { - // Remove fields from this table from propertyKey - propertyKey = propertyKey.filter((key) => !key.startsWith(`${tb}.`)); - } - }); - } - - // Check if propertyKey is empty after filtering - if (propertyKey.length === 0) { - throw new HttpError( - HttpStatusCode.BAD_REQUEST, - "ไม่พบฟิลด์ที่ต้องการแสดงผล กรุณาตรวจสอบการตั้งค่า API (ไม่สามารถ join ตารางลูกได้)", - ); - } - - // join สำหรับฟิลด์ Profile ที่ต้องการดึงค่าจากตารางอื่น - if (tbMain === "Profile" && Object.keys(profileFieldJoins).length > 0) { - Object.entries(profileFieldJoins).forEach(([alias, relationName]) => { - queryBuilder.leftJoin(`${tbMain}.${relationName}`, alias); - }); - } - - // join สำหรับฟิลด์ Position ที่ต้องการดึงค่าจากตารางอื่น - if ( - (tbMain === "Position" || tbMain === "PosMaster") && - Object.keys(positionFieldJoins).length > 0 - ) { - if (tbMain === "PosMaster") { - const posMasterPositionRelation = relationMap["Position"]; - if (!posMasterPositionRelation) { - throw new HttpError( - HttpStatusCode.BAD_REQUEST, - "ไม่พบความสัมพันธ์ระหว่าง PosMaster กับ Position กรุณาตรวจสอบการตั้งค่า API", + queryBuilder.leftJoin( + `${tbMain}.${relationName === "next_holder" ? "current_holder" : relationName}`, // เช็คว่าถ้าเป็น next_holder ให้ใช้ current_holder แทน + tb, ); } - - // Join PosMaster -> Position once using actual relation name from metadata - queryBuilder.leftJoin(`PosMaster.${posMasterPositionRelation}`, "Position"); - } - - Object.entries(positionFieldJoins).forEach(([alias, relationName]) => { - if (tbMain === "PosMaster") { - queryBuilder.leftJoin(`Position.${relationName}`, alias); - } else { - queryBuilder.leftJoin(`${tbMain}.${relationName}`, alias); - } }); } - // join สำหรับฟิลด์ ProfileEmployee ที่ต้องการดึงค่าจากตารางอื่น - if (tbMain === "ProfileEmployee" && Object.keys(profileEmployeeFieldJoins).length > 0) { - Object.entries(profileEmployeeFieldJoins).forEach(([alias, relationName]) => { - queryBuilder.leftJoin(`${tbMain}.${relationName}`, alias); - }); - } - - // join สำหรับฟิลด์ ProfileLeave ที่ต้องการดึงค่าจากตารางอื่น - if (Object.keys(profileLeaveFieldJoins).length > 0) { - if (tbMain === "ProfileLeave") { - // ProfileLeave is the main table - direct join - Object.entries(profileLeaveFieldJoins).forEach(([alias, relationName]) => { - queryBuilder.leftJoin(`${tbMain}.${relationName}`, alias); - }); - } else { - // ProfileLeave is a related table - the base join is already created by propertyOtherKey logic - // Join from the ProfileLeave alias (not from nested path) - Object.entries(profileLeaveFieldJoins).forEach(([alias, relationName]) => { - queryBuilder.leftJoin(`ProfileLeave.${relationName}`, alias); - }); - } - } - - // join สำหรับ PosMaster เมื่อต้องการดึงค่าจาก Profile (ข้อมูลคนครอง) - const posMasterProfileFields: string[] = []; - if (tbMain === "PosMaster") { - // Collect Profile fields from both formats: "Profile.xxx" and "PosMaster.Profile.xxx" - const extractedProfileFields = propertyKey - .filter((key) => key.startsWith("Profile.") || key.startsWith("PosMaster.Profile.")) - .map((key) => key.replace(/^PosMaster\.Profile\./, "Profile.")); - - posMasterProfileFields.push(...new Set(extractedProfileFields)); - - // Remove Profile fields then add back normalized "Profile.xxx" form - propertyKey = propertyKey.filter( - (key) => !key.startsWith("Profile.") && !key.startsWith("PosMaster.Profile."), - ); - propertyKey.push(...posMasterProfileFields); - } - - // join PosMaster กับ Profile เมื่อมีการขอ Profile fields - if (tbMain === "PosMaster" && posMasterProfileFields.length > 0) { - // Always join via current_holder (not next_holder) because PosMaster has two relations - // to Profile and relationMap["Profile"] would resolve to next_holder (last defined in entity) - queryBuilder.leftJoin("PosMaster.current_holder", "Profile"); - } - - // สำหรับ registry system: เก็บ posMaster เพื่อดึง org IDs แล้วค่อย query ancestorDNA - let includeOrgAncestorDna = false; - if (system === "registry" || system === "registry_emp" || system === "registry_temp") { - // Always join posMaster for registry systems (inner join to exclude profiles without current posMaster) - // Only include posMaster from current revision - if (tbMain === "Profile") { - queryBuilder.innerJoin("Profile.current_holders", "posMaster", "posMaster.orgRevisionId = :currentRevisionId"); - queryBuilder.setParameter("currentRevisionId", this.currentRevisionId); - - // Add org ID fields from posMaster to propertyKey - propertyKey.push("posMaster.orgRootId"); - propertyKey.push("posMaster.orgChild1Id"); - propertyKey.push("posMaster.orgChild2Id"); - propertyKey.push("posMaster.orgChild3Id"); - propertyKey.push("posMaster.orgChild4Id"); - } else if (tbMain === "ProfileEmployee") { - // For registry_emp and registry_temp, also use inner join with current revision - if (system === "registry_temp") { - queryBuilder.innerJoin("ProfileEmployee.current_holderTemps", "employeeTempPosMaster", "employeeTempPosMaster.orgRevisionId = :currentRevisionId"); - queryBuilder.setParameter("currentRevisionId", this.currentRevisionId); - - // Add org ID fields from employeeTempPosMaster to propertyKey - propertyKey.push("employeeTempPosMaster.orgRootId"); - propertyKey.push("employeeTempPosMaster.orgChild1Id"); - propertyKey.push("employeeTempPosMaster.orgChild2Id"); - propertyKey.push("employeeTempPosMaster.orgChild3Id"); - propertyKey.push("employeeTempPosMaster.orgChild4Id"); - } else { - // registry_emp - queryBuilder.innerJoin("ProfileEmployee.current_holders", "employeePosMaster", "employeePosMaster.orgRevisionId = :currentRevisionId"); - queryBuilder.setParameter("currentRevisionId", this.currentRevisionId); - - // Add org ID fields from employeePosMaster to propertyKey - propertyKey.push("employeePosMaster.orgRootId"); - propertyKey.push("employeePosMaster.orgChild1Id"); - propertyKey.push("employeePosMaster.orgChild2Id"); - propertyKey.push("employeePosMaster.orgChild3Id"); - propertyKey.push("employeePosMaster.orgChild4Id"); - } - } - - // Mark that we need to include ancestorDNA fields - includeOrgAncestorDna = true; - } - - // join กับ posMaster/employeePosMaster/employeeTempPosMaster เพื่อกรองตามสิทธิ์การเข้าถึง - // Skip duplicate join - posMaster already joined for registry systems at lines 569-571 - // Permission condition will use the existing alias - const posMasterAlreadyJoined = (system === "registry" || system === "registry_emp" || system === "registry_temp") && tbMain === "Profile"; - - if ((tbMain === "Profile" || tbMain === "ProfileEmployee") && posMasterCondition !== "1=1") { - if (tbMain === "Profile") { - // Only join if not already joined for registry systems - if (!posMasterAlreadyJoined) { - queryBuilder.innerJoin("Profile.current_holders", "posMaster", "posMaster.orgRevisionId = :currentRevisionIdPerm"); - queryBuilder.setParameter("currentRevisionIdPerm", this.currentRevisionId); - } - } else if (tbMain === "ProfileEmployee") { - // Check if already joined for registry_emp systems - const alreadyJoined = (system === "registry_emp" || system === "registry_temp"); - // Use the correct relation based on posMasterAlias - if (posMasterAlias === "employeeTempPosMaster" && !alreadyJoined) { - queryBuilder.innerJoin("ProfileEmployee.current_holderTemps", "employeeTempPosMaster", "employeeTempPosMaster.orgRevisionId = :currentRevisionIdPerm"); - queryBuilder.setParameter("currentRevisionIdPerm", this.currentRevisionId); - } else if (posMasterAlias === "employeePosMaster" && !alreadyJoined) { - queryBuilder.innerJoin("ProfileEmployee.current_holders", "employeePosMaster", "employeePosMaster.orgRevisionId = :currentRevisionIdPerm"); - queryBuilder.setParameter("currentRevisionIdPerm", this.currentRevisionId); - } - } - } - // // เพิ่ม Main.id เพราะจะใช้ pk ในการแมบและนับจำนวน // if (!propertyKey.includes(`${Main}.id`)) { // propertyKey.push(`${Main}.id`); // } - // add PK - ensure propertyKey is never empty + // add FK let pk: string = ""; const primaryColumns = metadata.primaryColumns; primaryColumns.forEach((col) => { @@ -739,89 +122,13 @@ export class ApiWebServiceController extends Controller { } }); - let items: any[] = []; - let total = 0; - - if (tbMain === "OrgRoot") { - // Organization API should always return full hierarchy regardless of page/pageSize. - [items, total] = await queryBuilder - .select(propertyKey) - .where(condition) - .andWhere(posMasterCondition) - .orderBy(propertyKey[0] || `${tbMain}.${pk}`, "ASC") - .getManyAndCount(); - } else { - [items, total] = await queryBuilder - .select(propertyKey) - .where(condition) - .andWhere(posMasterCondition) - .orderBy(propertyKey[0] || `${tbMain}.${pk}`, "ASC") - .skip(offset) - .take(pageSize) - .getManyAndCount(); - } - - // สำหรับ registry systems: ดึง ancestorDNA จาก org tables - let orgRootAncestorMap: Record = {}; - let orgChild1AncestorMap: Record = {}; - let orgChild2AncestorMap: Record = {}; - let orgChild3AncestorMap: Record = {}; - let orgChild4AncestorMap: Record = {}; - - if (includeOrgAncestorDna && items.length > 0) { - // Collect all unique org IDs - const orgRootIds = new Set(); - const orgChild1Ids = new Set(); - const orgChild2Ids = new Set(); - const orgChild3Ids = new Set(); - const orgChild4Ids = new Set(); - - items.forEach((item) => { - // Handle Profile (registry) - current_holders - if (item["current_holders"] && Array.isArray(item["current_holders"]) && item["current_holders"].length > 0) { - const posMaster = item["current_holders"][0]; - if (posMaster.orgRootId) orgRootIds.add(posMaster.orgRootId); - if (posMaster.orgChild1Id) orgChild1Ids.add(posMaster.orgChild1Id); - if (posMaster.orgChild2Id) orgChild2Ids.add(posMaster.orgChild2Id); - if (posMaster.orgChild3Id) orgChild3Ids.add(posMaster.orgChild3Id); - if (posMaster.orgChild4Id) orgChild4Ids.add(posMaster.orgChild4Id); - } - // Handle ProfileEmployee (registry_emp) - current_holders - if (item["current_holders"] && Array.isArray(item["current_holders"]) && item["current_holders"].length > 0) { - const posMaster = item["current_holders"][0]; - if (posMaster.orgRootId) orgRootIds.add(posMaster.orgRootId); - if (posMaster.orgChild1Id) orgChild1Ids.add(posMaster.orgChild1Id); - if (posMaster.orgChild2Id) orgChild2Ids.add(posMaster.orgChild2Id); - if (posMaster.orgChild3Id) orgChild3Ids.add(posMaster.orgChild3Id); - if (posMaster.orgChild4Id) orgChild4Ids.add(posMaster.orgChild4Id); - } - // Handle ProfileEmployee (registry_temp) - current_holderTemps - if (item["current_holderTemps"] && Array.isArray(item["current_holderTemps"]) && item["current_holderTemps"].length > 0) { - const posMaster = item["current_holderTemps"][0]; - if (posMaster.orgRootId) orgRootIds.add(posMaster.orgRootId); - if (posMaster.orgChild1Id) orgChild1Ids.add(posMaster.orgChild1Id); - if (posMaster.orgChild2Id) orgChild2Ids.add(posMaster.orgChild2Id); - if (posMaster.orgChild3Id) orgChild3Ids.add(posMaster.orgChild3Id); - if (posMaster.orgChild4Id) orgChild4Ids.add(posMaster.orgChild4Id); - } - }); - - // Query org tables to get ancestorDNA - const [orgRoots, orgChild1s, orgChild2s, orgChild3s, orgChild4s] = await Promise.all([ - orgRootIds.size > 0 ? AppDataSource.getRepository(OrgRoot).createQueryBuilder("orgRoot").select(["orgRoot.id", "orgRoot.ancestorDNA"]).where("orgRoot.id IN (:...ids)", { ids: Array.from(orgRootIds) }).getMany() : [], - orgChild1Ids.size > 0 ? AppDataSource.getRepository(OrgChild1).createQueryBuilder("orgChild1").select(["orgChild1.id", "orgChild1.ancestorDNA"]).where("orgChild1.id IN (:...ids)", { ids: Array.from(orgChild1Ids) }).getMany() : [], - orgChild2Ids.size > 0 ? AppDataSource.getRepository(OrgChild2).createQueryBuilder("orgChild2").select(["orgChild2.id", "orgChild2.ancestorDNA"]).where("orgChild2.id IN (:...ids)", { ids: Array.from(orgChild2Ids) }).getMany() : [], - orgChild3Ids.size > 0 ? AppDataSource.getRepository(OrgChild3).createQueryBuilder("orgChild3").select(["orgChild3.id", "orgChild3.ancestorDNA"]).where("orgChild3.id IN (:...ids)", { ids: Array.from(orgChild3Ids) }).getMany() : [], - orgChild4Ids.size > 0 ? AppDataSource.getRepository(OrgChild4).createQueryBuilder("orgChild4").select(["orgChild4.id", "orgChild4.ancestorDNA"]).where("orgChild4.id IN (:...ids)", { ids: Array.from(orgChild4Ids) }).getMany() : [], - ]); - - // Create separate maps for each org level - orgRoots.forEach((org: any) => { orgRootAncestorMap[org.id] = org.ancestorDNA; }); - orgChild1s.forEach((org: any) => { orgChild1AncestorMap[org.id] = org.ancestorDNA; }); - orgChild2s.forEach((org: any) => { orgChild2AncestorMap[org.id] = org.ancestorDNA; }); - orgChild3s.forEach((org: any) => { orgChild3AncestorMap[org.id] = org.ancestorDNA; }); - orgChild4s.forEach((org: any) => { orgChild4AncestorMap[org.id] = org.ancestorDNA; }); - } + const [items, total] = await queryBuilder + .select(propertyKey) + .where(condition) + .orderBy(propertyKey[0], "ASC") + .skip(offset) + .take(pageSize) + .getManyAndCount(); // ลบ Main.id // const results = items.map(({ id, ...x }) => x); @@ -834,330 +141,11 @@ export class ApiWebServiceController extends Controller { // split object id ออกก่อน return const data = items.map((item) => { - const { [pk]: removedPk, ...rest } = item; - - // สำหรับ Profile: แปลงฟิลด์ที่มาจาก join กลับเป็นชื่อเดิม - if (tbMain === "Profile") { - const flattened: any = { ...rest }; - Object.entries(this.PROFILE_FIELD_REPLACEMENTS).forEach(([nameField, config]) => { - const alias = `${tbMain}_${config.joinRelation}`; - if (rest[alias] && rest[alias][config.joinField] !== undefined) { - flattened[nameField] = rest[alias][config.joinField]; - delete flattened[alias]; - } - // Also handle nested relation objects (e.g., "posLevel": { "posLevelName": "..." }) - if ( - rest[config.joinRelation] && - rest[config.joinRelation][config.joinField] !== undefined - ) { - flattened[nameField] = rest[config.joinRelation][config.joinField]; - delete flattened[config.joinRelation]; - } - }); - - // แปลง ancestorDNA เป็น orgRootId, orgChild1Id, etc. - if (includeOrgAncestorDna) { - if (rest["current_holders"] && Array.isArray(rest["current_holders"]) && rest["current_holders"].length > 0) { - const posMaster = rest["current_holders"][0]; - - // Get ancestorDNA from separate maps using org IDs - // Always set the fields, use null if no value - flattened.orgRootId = (posMaster.orgRootId && orgRootAncestorMap[posMaster.orgRootId]) ? orgRootAncestorMap[posMaster.orgRootId] : null; - flattened.orgChild1Id = (posMaster.orgChild1Id && orgChild1AncestorMap[posMaster.orgChild1Id]) ? orgChild1AncestorMap[posMaster.orgChild1Id] : null; - flattened.orgChild2Id = (posMaster.orgChild2Id && orgChild2AncestorMap[posMaster.orgChild2Id]) ? orgChild2AncestorMap[posMaster.orgChild2Id] : null; - flattened.orgChild3Id = (posMaster.orgChild3Id && orgChild3AncestorMap[posMaster.orgChild3Id]) ? orgChild3AncestorMap[posMaster.orgChild3Id] : null; - flattened.orgChild4Id = (posMaster.orgChild4Id && orgChild4AncestorMap[posMaster.orgChild4Id]) ? orgChild4AncestorMap[posMaster.orgChild4Id] : null; - } else { - // No current_holders, set all to null - flattened.orgRootId = null; - flattened.orgChild1Id = null; - flattened.orgChild2Id = null; - flattened.orgChild3Id = null; - flattened.orgChild4Id = null; - } - - // Delete current_holders array - delete flattened["current_holders"]; - } - return flattened; - } - - // สำหรับ Position: แปลงฟิลด์ที่มาจาก join กลับเป็นชื่อเดิม - if (tbMain === "Position" || tbMain === "PosMaster") { - const flattened: any = { ...rest }; - Object.entries(this.POSITION_FIELD_REPLACEMENTS).forEach(([nameField, config]) => { - // Remove the original ID field - delete flattened[config.propertyName]; - // Add the name field from joined table - const alias = `Position_${config.joinRelation}`; - if (rest[alias] && rest[alias][config.joinField] !== undefined) { - flattened[nameField] = rest[alias][config.joinField]; - } - // Remove the joined table object - delete flattened[alias]; - }); - // Remove Position object if exists - if (flattened["Position"]) { - delete flattened["Position"]; - } - return flattened; - } - - // สำหรับ ProfileEmployee: แปลงฟิลด์ที่มาจาก join กลับเป็นชื่อเดิม - if (tbMain === "ProfileEmployee") { - const flattened: any = { ...rest }; - Object.entries(this.PROFILEEMPLOYEE_FIELD_REPLACEMENTS).forEach(([nameField, config]) => { - // Remove the original ID field - delete flattened[config.propertyName]; - // Add the name field from joined table - const alias = `${tbMain}_${config.joinRelation}`; - if (rest[alias] && rest[alias][config.joinField] !== undefined) { - flattened[nameField] = rest[alias][config.joinField]; - } - // Remove the joined table object - delete flattened[alias]; - // Also handle nested relation objects (e.g., "posType": { "posTypeName": "..." }) - if ( - rest[config.joinRelation] && - rest[config.joinRelation][config.joinField] !== undefined - ) { - flattened[nameField] = rest[config.joinRelation][config.joinField]; - delete flattened[config.joinRelation]; - } - }); - - // แปลง ancestorDNA เป็น orgRootId, orgChild1Id, etc. (สำหรับ registry_emp และ registry_temp) - if (includeOrgAncestorDna) { - const posMasterKey = system === "registry_temp" ? "current_holderTemps" : "current_holders"; - if (rest[posMasterKey] && Array.isArray(rest[posMasterKey]) && rest[posMasterKey].length > 0) { - const posMaster = rest[posMasterKey][0]; - - // Always set the fields, use null if no value - flattened.orgRootId = (posMaster.orgRootId && orgRootAncestorMap[posMaster.orgRootId]) ? orgRootAncestorMap[posMaster.orgRootId] : null; - flattened.orgChild1Id = (posMaster.orgChild1Id && orgChild1AncestorMap[posMaster.orgChild1Id]) ? orgChild1AncestorMap[posMaster.orgChild1Id] : null; - flattened.orgChild2Id = (posMaster.orgChild2Id && orgChild2AncestorMap[posMaster.orgChild2Id]) ? orgChild2AncestorMap[posMaster.orgChild2Id] : null; - flattened.orgChild3Id = (posMaster.orgChild3Id && orgChild3AncestorMap[posMaster.orgChild3Id]) ? orgChild3AncestorMap[posMaster.orgChild3Id] : null; - flattened.orgChild4Id = (posMaster.orgChild4Id && orgChild4AncestorMap[posMaster.orgChild4Id]) ? orgChild4AncestorMap[posMaster.orgChild4Id] : null; - } else { - // No posMaster data, set all to null - flattened.orgRootId = null; - flattened.orgChild1Id = null; - flattened.orgChild2Id = null; - flattened.orgChild3Id = null; - flattened.orgChild4Id = null; - } - - // Delete the posMaster array - delete flattened[posMasterKey]; - } - return flattened; - } - - // สำหรับ PosMaster: แปลงฟิลด์ Profile ที่มาจาก join กลับเป็นฟิลด์ระดับบน - if (tbMain === "PosMaster" && posMasterProfileFields.length > 0) { - const flattened: any = { ...rest }; - const profileFieldNames = posMasterProfileFields - .filter((field) => field.startsWith("Profile.")) - .map((field) => field.replace("Profile.", "")); - - // Extract only requested Profile fields and add top-level aliases - if (rest["Profile"]) { - profileFieldNames.forEach((fieldName) => { - if (rest["Profile"][fieldName] !== undefined) { - flattened[`profile_${fieldName}`] = rest["Profile"][fieldName]; - } - }); - // Remove the nested Profile object - delete flattened["Profile"]; - } - return flattened; - } - - // สำหรับ OrgRoot: เก็บ primary key ไว้ใช้ group ข้อมูล แล้วแยก children ภายหลัง - if (tbMain === "OrgRoot") { - return { __rootPk: removedPk, ...rest }; - } - - return rest; + const { [pk]: removedPk, ...x } = item; + return x; }); - let responseData: any[] = data; - let responseTotal = total; - - // สำหรับ Organization: รวมข้อมูลให้เหลือ 1 root ต่อ 1 object และจัด children ตาม hierarchy - if (tbMain === "OrgRoot") { - const rootVisibleFields = Array.from(selectedFieldsByTable["OrgRoot"] || []); - const child1VisibleFields = Array.from(selectedFieldsByTable["OrgChild1"] || []); - const child2VisibleFields = Array.from(selectedFieldsByTable["OrgChild2"] || []); - const child3VisibleFields = Array.from(selectedFieldsByTable["OrgChild3"] || []); - const child4VisibleFields = Array.from(selectedFieldsByTable["OrgChild4"] || []); - - const pickVisibleFields = (obj: any, fields: string[]) => { - const out: any = {}; - fields.forEach((field) => { - if (obj[field] !== undefined) { - // ถ้าเป็น ancestorDNA ให้เปลี่ยนชื่อเป็น id - if (field === "ancestorDNA") { - out.id = obj[field]; - } else { - out[field] = obj[field]; - } - } - }); - return out; - }; - - const rootMap = new Map(); - data.forEach((row: any) => { - if (!row.__rootPk || rootMap.has(row.__rootPk)) { - return; - } - - const rootNode = { - ...pickVisibleFields(row, rootVisibleFields), - children: [], - }; - rootMap.set(row.__rootPk, rootNode); - }); - - const rootIds = Array.from(rootMap.keys()); - - if (rootIds.length > 0) { - const buildSelect = (alias: string, required: string[], visible: string[]) => - Array.from(new Set([...required, ...visible])).map((field) => `${alias}.${field}`); - - const [child1Rows, child2Rows, child3Rows, child4Rows] = await Promise.all([ - AppDataSource.getRepository(OrgChild1) - .createQueryBuilder("OrgChild1") - .select(buildSelect("OrgChild1", ["id", "orgRootId", "ancestorDNA"], child1VisibleFields)) - .where("OrgChild1.orgRootId IN (:...rootIds)", { rootIds }) - .orderBy("OrgChild1.id", "ASC") - .getMany(), - AppDataSource.getRepository(OrgChild2) - .createQueryBuilder("OrgChild2") - .select( - buildSelect("OrgChild2", ["id", "orgRootId", "orgChild1Id", "ancestorDNA"], child2VisibleFields), - ) - .where("OrgChild2.orgRootId IN (:...rootIds)", { rootIds }) - .orderBy("OrgChild2.id", "ASC") - .getMany(), - AppDataSource.getRepository(OrgChild3) - .createQueryBuilder("OrgChild3") - .select( - buildSelect( - "OrgChild3", - ["id", "orgRootId", "orgChild1Id", "orgChild2Id", "ancestorDNA"], - child3VisibleFields, - ), - ) - .where("OrgChild3.orgRootId IN (:...rootIds)", { rootIds }) - .orderBy("OrgChild3.id", "ASC") - .getMany(), - AppDataSource.getRepository(OrgChild4) - .createQueryBuilder("OrgChild4") - .select( - buildSelect( - "OrgChild4", - ["id", "orgRootId", "orgChild1Id", "orgChild2Id", "orgChild3Id", "ancestorDNA"], - child4VisibleFields, - ), - ) - .where("OrgChild4.orgRootId IN (:...rootIds)", { rootIds }) - .orderBy("OrgChild4.id", "ASC") - .getMany(), - ]); - - const child1Map = new Map(); - const child2Map = new Map(); - const child3Map = new Map(); - - child1Rows.forEach((row) => { - const node = { - ...pickVisibleFields(row, child1VisibleFields), - children: [], - }; - child1Map.set(row.id, node); - - const rootNode = rootMap.get(row.orgRootId); - if (rootNode) { - rootNode.children.push(node); - } - }); - - child2Rows.forEach((row) => { - const node = { - ...pickVisibleFields(row, child2VisibleFields), - children: [], - }; - child2Map.set(row.id, node); - - const parent = child1Map.get(row.orgChild1Id); - if (parent) { - parent.children.push(node); - } - }); - - child3Rows.forEach((row) => { - const node = { - ...pickVisibleFields(row, child3VisibleFields), - children: [], - }; - child3Map.set(row.id, node); - - const parent = child2Map.get(row.orgChild2Id); - if (parent) { - parent.children.push(node); - } - }); - - child4Rows.forEach((row) => { - const node = { - ...pickVisibleFields(row, child4VisibleFields), - }; - - const parent = child3Map.get(row.orgChild3Id); - if (parent) { - if (!Array.isArray(parent.children)) { - parent.children = []; - } - parent.children.push(node); - } - }); - } - - responseData = Array.from(rootMap.values()); - - // สำหรับ Organization: เปลี่ยนชื่อ ancestorDNA เป็น id - responseData = responseData.map((root: any) => { - const renamed = this.renameAncestorDnaToId(root); - if (Array.isArray(renamed.children)) { - renamed.children = renamed.children.map((child1: any) => { - const renamedChild1 = this.renameAncestorDnaToId(child1); - if (Array.isArray(renamedChild1.children)) { - renamedChild1.children = renamedChild1.children.map((child2: any) => { - const renamedChild2 = this.renameAncestorDnaToId(child2); - if (Array.isArray(renamedChild2.children)) { - renamedChild2.children = renamedChild2.children.map((child3: any) => { - const renamedChild3 = this.renameAncestorDnaToId(child3); - if (Array.isArray(renamedChild3.children)) { - renamedChild3.children = renamedChild3.children.map((child4: any) => - this.renameAncestorDnaToId(child4), - ); - } - return renamedChild3; - }); - } - return renamedChild2; - }); - } - return renamedChild1; - }); - } - return renamed; - }); - - responseTotal = responseData.length; - } + // console.log("queryBuilder ===> ", queryBuilder.getQuery()); // save api history after query success const history = { @@ -1207,6 +195,6 @@ export class ApiWebServiceController extends Controller { // return flattenedItem; // }); - return new HttpSuccess({ data: responseData, total: responseTotal }); + return new HttpSuccess({ data: data, total }); } } diff --git a/src/controllers/AuthRoleController.ts b/src/controllers/AuthRoleController.ts index 13f5ce04..4159c5ec 100644 --- a/src/controllers/AuthRoleController.ts +++ b/src/controllers/AuthRoleController.ts @@ -123,25 +123,18 @@ export class AuthRoleController extends Controller { // เช็คว่าถ้ามีค่า current_holderId ให้ลบ key สิทธิ์ใน redis if (posMaster.current_holderId) { - let redisClient; - try { - redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); + const redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); - redisClient.del("role_" + posMaster.current_holderId, (err: Error) => { - if (err) console.error("Redis delete role error:", err); - }); + redisClient.del("role_" + posMaster.current_holderId, (err: Error, response: Response) => { + if (err) throw err; + }); - redisClient.del("menu_" + posMaster.current_holderId, (err: Error) => { - if (err) console.error("Redis delete menu error:", err); - }); - } finally { - if (redisClient) { - redisClient.quit(); - } - } + redisClient.del("menu_" + posMaster.current_holderId, (err: Error, response: Response) => { + if (err) throw err; + }); } return new HttpSuccess(); @@ -267,45 +260,20 @@ export class AuthRoleController extends Controller { return newAttr; }); const before = structuredClone(record); + await Promise.all([ + this.authRoleRepo.save(record, { data: req }), + setLogDataDiff(req, { before, after: record }), + ...newAttrs.map((attr) => this.authRoleAttrRepo.save(attr)), + ]); - const queryRunner = AppDataSource.createQueryRunner(); - await queryRunner.connect(); - await queryRunner.startTransaction(); + const redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); - try { - await queryRunner.manager.save(AuthRole, record); - await Promise.all( - newAttrs.map((attr) => queryRunner.manager.save(AuthRoleAttr, attr)) - ); - await queryRunner.commitTransaction(); - - setLogDataDiff(req, { before, after: record }); - } catch (error) { - await queryRunner.rollbackTransaction(); - console.error("Error saving auth role:", error); - throw new HttpError( - HttpStatusCode.INTERNAL_SERVER_ERROR, - "เกิดข้อผิดพลาดในการบันทึกข้อมูลบทบาท กรุณาลองใหม่ในภายหลัง" - ); - } finally { - await queryRunner.release(); - } - - let redisClient; - try { - redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); - - await redisClient.flushdb(function (err: any, succeeded: any) { - console.log(succeeded); // will be true if successfull - }); - } finally { - if (redisClient) { - redisClient.quit(); - } - } + await redisClient.flushdb(function (err: any, succeeded: any) { + console.log(succeeded); // will be true if successfull + }); return new HttpSuccess(); } diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index 828a2fc1..27d2671c 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -41,9 +41,9 @@ import { removeProfileInOrganize, setLogDataDiff, checkReturnCommandType, + checkExceptCommandType, checkCommandType, removePostMasterAct, - logPositionIsSelectedChange, } from "../interfaces/utils"; import { Position } from "../entities/Position"; import { PosMaster } from "../entities/PosMaster"; @@ -205,13 +205,7 @@ export class CommandController extends Controller { child4: null, }; if (request.user.role.includes("STAFF")) { - // #2523 STAFF + isDirector ให้ล้อสิทธิ์เหมือน CHILD - if (!isDirector) { - _data = await new permission().PermissionOrgList(request, "COMMAND"); - - } else { - _data = await new permission().PermissionIsDirectorOrgList(request, "COMMAND", isDirector); - } + _data = await new permission().PermissionOrgList(request, "COMMAND"); } if (isDirector || _data.privilege == "OWNER") { const profiles = await this.profileRepository @@ -342,11 +336,9 @@ export class CommandController extends Controller { .andWhere( new Brackets((qb) => { qb.where( - keyword != null && keyword != "" - ? "TRIM(CONCAT(COALESCE(command.shortName, ''), ' ', command.commandNo, '/', command.commandYear + 543)) LIKE :keyword" - : "1=1", + keyword != null && keyword != "" ? "command.commandNo LIKE :baseKeyword" : "1=1", { - keyword: `%${keyword}%`, + baseKeyword: `%${baseKeyword}%`, }, ) .orWhere(keyword != null && keyword != "" ? "command.issue LIKE :keyword" : "1=1", { @@ -373,7 +365,7 @@ export class CommandController extends Controller { const data = commands.map((_data) => ({ id: _data.id, - commandNo: `${_data.shortName ?? ""} ${_data.commandNo}`.trim(), + commandNo: _data.commandNo, commandYear: _data.commandYear, commandAffectDate: _data.commandAffectDate, commandExcecuteDate: _data.commandExcecuteDate, @@ -523,7 +515,6 @@ export class CommandController extends Controller { const _command = { id: command.id, status: command.status, - shortName: command.shortName ?? "", commandNo: command.commandNo, commandYear: command.commandYear, issue: command.issue, @@ -574,34 +565,6 @@ export class CommandController extends Controller { } const data = new Command(); Object.assign(data, { ...command, ...requestBody }); - - // ถ้าเป็น officer (isOfficer == true) ดึง orgRoot.shortName มาใช้ - const userProfile = await this.profileRepository.findOne({ - where: { keycloak: request.user.sub }, - relations: { - current_holders: { - orgRevision: true, - orgRoot: true, - orgChild1: true, - }, - }, - }); - - if (userProfile) { - const currentHolder = userProfile.current_holders?.find( - (x: any) => - x.orgRevision?.orgRevisionIsDraft === false && - x.orgRevision?.orgRevisionIsCurrent === true, - ); - - if (currentHolder && currentHolder.orgChild1?.isOfficer) { - data.shortName = - requestBody.isBangkok && requestBody.isBangkok === "BANGKOK" - ? "กทม." - : currentHolder.orgRoot?.orgRootShortName ?? "สนป."; - } - } - data.lastUpdateUserId = request.user.sub; data.lastUpdateFullName = request.user.name; data.lastUpdatedAt = new Date(); @@ -2410,9 +2373,9 @@ export class CommandController extends Controller { ? "" : Extension.ToThaiNumber(Extension.ToThaiYear(command.commandYear).toString()), commandExcecuteDate: - command.commandAffectDate == null + command.commandExcecuteDate == null ? "" - : Extension.ToThaiNumber(Extension.ToThaiFullDate2(command.commandAffectDate)), + : Extension.ToThaiNumber(Extension.ToThaiFullDate2(command.commandExcecuteDate)), operators: operators.length > 0 ? operators.map((x) => ({ @@ -2617,9 +2580,7 @@ export class CommandController extends Controller { const now = new Date(); let command = new Command(); let commandCode: string = ""; - let commandSysId: string = ""; let _null: any = null; - let userProfile: any = null; if ( requestBody.commandId != undefined && requestBody.commandId != null && @@ -2637,7 +2598,6 @@ export class CommandController extends Controller { if (!_command) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบคำสั่งนี้ในระบบ"); } - commandSysId = _command.commandType.commandSysId; commandCode = _command.commandType.code; command = _command; } else { @@ -2652,7 +2612,6 @@ export class CommandController extends Controller { if (!commandType) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ"); } - commandSysId = commandType.commandSysId; commandCode = commandType.code; command.detailHeader = commandType.detailHeader; command.detailBody = commandType.detailBody; @@ -2681,37 +2640,6 @@ export class CommandController extends Controller { command.lastUpdateUserId = request.user.sub; command.lastUpdateFullName = request.user.name; command.lastUpdatedAt = now; - - // Query profile ครั้งเดียว ใช้ร่วมกันทั้ง shortName และ CommandOperator - userProfile = await this.profileRepository.findOne({ - where: { keycloak: request.user.sub }, - relations: { - posLevel: true, - posType: true, - current_holders: { - orgRevision: true, - orgRoot: true, - orgChild1: true, - orgChild2: true, - orgChild3: true, - orgChild4: true, - }, - }, - }); - - // เช็คถ้าไม่ใช่ กสจ. ดึง root.shortName มาปั๊ม - if (userProfile) { - const currentHolder = userProfile.current_holders?.find( - (x: any) => - x.orgRevision?.orgRevisionIsDraft === false && - x.orgRevision?.orgRevisionIsCurrent === true, - ); - - if (currentHolder && !currentHolder.orgChild1?.isOfficer) { - command.shortName = currentHolder.orgRoot?.orgRootShortName ?? null; - } - } - await this.commandRepository.save(command); } // insert commandOperator @@ -2720,28 +2648,24 @@ export class CommandController extends Controller { }); if (!checkCommandOperator) { if (request.user.sub) { - // ใช้ userProfile ที่ query ไปแล้วถ้ามี ถ้าไม่มีค่อย query ใหม่ - let profile = userProfile; - if (!profile) { - profile = await this.profileRepository.findOne({ - where: { keycloak: request.user.sub }, - relations: { - posLevel: true, - posType: true, - current_holders: { - orgRevision: true, - orgRoot: true, - orgChild1: true, - orgChild2: true, - orgChild3: true, - orgChild4: true, - }, + const profile = await this.profileRepository.findOne({ + where: { keycloak: request.user.sub }, + relations: { + posLevel: true, + posType: true, + current_holders: { + orgRevision: true, + orgRoot: true, + orgChild1: true, + orgChild2: true, + orgChild3: true, + orgChild4: true, }, - }); - } + }, + }); if (profile) { const currentHolder = profile!.current_holders?.find( - (x: any) => + (x) => x.orgRevision?.orgRevisionIsDraft === false && x.orgRevision?.orgRevisionIsCurrent === true, ); @@ -2797,7 +2721,7 @@ export class CommandController extends Controller { const path = commandTypePath(commandCode); if (path == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ"); - if (commandSysId && commandSysId.toLocaleUpperCase().trim() !== "DISCIPLINE") { + if (!["C-PM-26", "C-PM-25"].includes(commandCode)) { await new CallAPI() .PostData(request, path, { refIds: requestBody.persons.filter((x) => x.refId != null).map((x) => x.refId), @@ -3663,12 +3587,8 @@ export class CommandController extends Controller { positionArea?: string | null; positionType: string | null; positionLevel: string | null; - positionTypeId?: string | null; - positionLevelId?: string | null; posmasterId: string; positionId: string; - posExecutiveId?: string | null; - positionField?: string | null; commandId?: string | null; orgRoot?: string | null; orgChild1?: string | null; @@ -3765,51 +3685,12 @@ export class CommandController extends Controller { history.profileSalaryId = data.id; await this.salaryHistoryRepo.save(history, { data: req }); - // STEP 1: หา posMaster ที่จะใช้งานตาม id ที่ส่งมา - let posMaster = await this.posMasterRepository.findOne({ + const posMaster = await this.posMasterRepository.findOne({ where: { id: item.posmasterId }, - relations: { - orgRevision: true, - orgRoot: true, - orgChild1: true, - orgChild2: true, - orgChild3: true, - orgChild4: true, - }, + relations: ["orgRoot", "orgChild1", "orgChild2", "orgChild3", "orgChild4"], }); - - // เช็คว่า posMaster ที่หามาอยู่ในโครงสร้างปัจจุบันหรือไม่ - const isCurrent = - posMaster?.orgRevision?.orgRevisionIsCurrent === true && - posMaster?.orgRevision?.orgRevisionIsDraft === false; - - // ถ้าไม่อยู่ในโครงสร้างปัจจุบัน ให้หาตัวใหม่จาก ancestorDNA - if (!isCurrent && posMaster?.ancestorDNA) { - posMaster = await this.posMasterRepository.findOne({ - where: { - ancestorDNA: posMaster.ancestorDNA, - orgRevision: { - orgRevisionIsCurrent: true, - orgRevisionIsDraft: false, - }, - }, - relations: { - orgRevision: true, - orgRoot: true, - orgChild1: true, - orgChild2: true, - orgChild3: true, - orgChild4: true, - }, - }); - } - - if (posMaster == null) { - console.error( - `[CommandController] PosMaster not found - posMasterId: ${item.posmasterId}, ` - ); + if (posMaster == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้"); - } const posMasterOld = await this.posMasterRepository.findOne({ where: { @@ -3829,41 +3710,21 @@ export class CommandController extends Controller { }, }); if (positionOld != null) { - logPositionIsSelectedChange(positionOld.id, positionOld.positionIsSelected, false, { - posMasterId: posMasterOld?.id, - userId: req.user.sub, - endpoint: "updateMaster", - action: "command_change_reset_old_position", - }); - positionOld.positionIsSelected = false; await this.positionRepository.save(positionOld); } const checkPosition = await this.positionRepository.find({ where: { - posMasterId: posMaster!.id, // ใช้ posMaster ตัวใหม่ (ที่อาจจะเปลี่ยนจาก ancestorDNA) + posMasterId: item.posmasterId, positionIsSelected: true, }, }); if (checkPosition.length > 0) { - console.log( - `[positionIsSelected-DEBUG] Command change: clearing ${checkPosition.length} positions (posMasterId: ${posMaster!.id}, userId: ${req.user.sub}, endpoint: updateMaster)` - ); - - const clearPosition = checkPosition.map((positions) => { - logPositionIsSelectedChange(positions.id, positions.positionIsSelected, false, { - posMasterId: posMaster!.id, - userId: req.user.sub, - endpoint: "updateMaster", - action: "command_change_clear_positions", - }); - - return { - ...positions, - positionIsSelected: false, - }; - }); + const clearPosition = checkPosition.map((positions) => ({ + ...positions, + positionIsSelected: false, + })); await this.positionRepository.save(clearPosition); } @@ -3877,113 +3738,13 @@ export class CommandController extends Controller { } await this.posMasterRepository.save(posMaster); - // STEP 2: กำหนด position ใหม่ - // Match position ตามลำดับ priority: - // Condition 1: match จาก positionId - // Condition 2: match 7 ฟิลด์ (positionName, posTypeId, posLevelId, positionField, positionArea, positionExecutiveField, posExecutiveId) - // Condition 3: match 3 ฟิลด์ (positionName, posTypeId, posLevelId) - // Fallback: เลือก position แรกใน posMaster - - let positionNew: Position | null = null; - - // Resolve ID: ใช้ positionTypeId/positionLevelId ก่อน ถ้าไม่มี fallback เป็น positionType/positionLevel - const posTypeId = item.positionTypeId || item.positionType; - const posLevelId = item.positionLevelId || item.positionLevel; - - // ═══════════════════════════════════════════════════════════ - // CONDITION 1: เช็คจาก positionId ตรง - // ═══════════════════════════════════════════════════════════ - if (item.positionId) { - const positionById = await this.positionRepository.findOne({ - where: { - id: item.positionId, - posMasterId: posMaster.id, // ต้องอยู่ใน posMaster ที่ถูกต้อง - }, - relations: ["posExecutive"], - }); - - if (positionById) { - positionNew = positionById; - } - } - - // ═══════════════════════════════════════════════════════════ - // CONDITION 2: Match 7 ฟิลด์ (ถ้า Condition 1 ไม่ match) - // ═══════════════════════════════════════════════════════════ - if (!positionNew && item.positionName && posTypeId && posLevelId) { - // สร้าง where clause แบบ dynamic - ใส่เฉพาะฟิลด์ที่มีค่า - const whereCondition: any = { - posMasterId: posMaster.id, - positionName: item.positionName, - posTypeId: posTypeId, - posLevelId: posLevelId, - }; - - // เพิ่มเฉพาะฟิลด์ที่มีค่า (ไม่ใช่ null, undefined, หรือ string ว่าง) - if (item.positionField) { - whereCondition.positionField = item.positionField; - } - if (item.posExecutiveId) { - whereCondition.posExecutiveId = item.posExecutiveId; - } - if (item.positionExecutiveField) { - whereCondition.positionExecutiveField = item.positionExecutiveField; - } - if (item.positionArea) { - whereCondition.positionArea = item.positionArea; - } - - const positionBy7Fields = await this.positionRepository.findOne({ - where: whereCondition, - relations: ["posExecutive"], - order: { orderNo: "ASC" } - }); - - if (positionBy7Fields) { - positionNew = positionBy7Fields; - } - } - - // ═══════════════════════════════════════════════════════════ - // CONDITION 3: Match 3 ฟิลด์ (ถ้า Condition 2 ไม่ match) - // ═══════════════════════════════════════════════════════════ - if (!positionNew && item.positionName && posTypeId && posLevelId) { - const positionBy3Fields = await this.positionRepository.findOne({ - where: { - posMasterId: posMaster.id, - positionName: item.positionName, - posTypeId: posTypeId, - posLevelId: posLevelId, - }, - relations: ["posExecutive"], - order: { orderNo: "ASC" } - }); - - if (positionBy3Fields) { - positionNew = positionBy3Fields; - } - } - - // // ═══════════════════════════════════════════════════════════ - // // FALLBACK: ถ้าทั้ง 3 ไม่ match ให้เลือก position แรกใน posMaster - // // ═══════════════════════════════════════════════════════════ - // if (!positionNew) { - // const fallbackPositions = await this.positionRepository.find({ - // where: { - // posMasterId: posMaster.id, - // }, - // relations: ["posExecutive"], - // order: { - // orderNo: "ASC", - // }, - // take: 1, - // }); - - // if (fallbackPositions.length > 0) { - // positionNew = fallbackPositions[0]; - // } - // } - + const positionNew = await this.positionRepository.findOne({ + where: { + id: item.positionId, + posMasterId: item.posmasterId, + }, + relations: ["posExecutive"], + }); // ถ้าไม่ใช่ตำแหน่งนั่งทับ (isSit = false) ถึงจะอัพเดทตำแหน่งในทะเบียนประวัติ if (positionNew != null) { positionNew.positionIsSelected = true; @@ -4015,7 +3776,7 @@ export class CommandController extends Controller { public async newSalaryEmployeeAndUpdateCurrent( @Request() req: RequestWithUser, @Body() - body: { + body: { data: { profileId: string; amount?: Double | null; @@ -4223,8 +3984,6 @@ export class CommandController extends Controller { isLeave: boolean; leaveReason?: string | null; dateLeave?: Date | null; - posExecutiveId?: string | null; - positionField?: string | null; commandId?: string | null; isGovernment?: boolean | null; orgRoot?: string | null; @@ -4242,7 +4001,6 @@ export class CommandController extends Controller { commandCode?: string | null; commandName?: string | null; remark: string | null; - positionId?: string | null; positionTypeNew?: string | null; positionLevelNew?: string | null; positionNameNew?: string | null; @@ -4312,8 +4070,11 @@ export class CommandController extends Controller { body.data.map(async (item) => { const profile = await this.profileRepository.findOne({ where: { id: item.profileId }, + // relations: ["roleKeycloaks"], relations: { - roleKeycloaks: true + roleKeycloaks: true, + posType: true, + posLevel: true, }, }); if (!profile) { @@ -4446,45 +4207,10 @@ export class CommandController extends Controller { //ปลดตำแหน่งเดิมที่ไม่ถูกปลดออกจากกิ่งครั้งเมื่อออกคำสั่งพักราชการหรือออกราชการไว้ await removeProfileInOrganize(profile.id, "OFFICER"); //ปั๊มตำแหน่งใหม่ - // หา posMaster และเช็ค orgRevisionIsCurrent - let posMaster = await this.posMasterRepository.findOne({ + const posMaster = await this.posMasterRepository.findOne({ where: { id: item.posmasterId?.toString() }, - relations: { - orgRevision: true, - orgRoot: true, - orgChild1: true, - orgChild2: true, - orgChild3: true, - orgChild4: true, - }, }); - // เช็คว่า posMaster ที่หามาอยู่ในโครงสร้างปัจจุบันหรือไม่ - const isCurrent = - posMaster?.orgRevision?.orgRevisionIsCurrent === true && - posMaster?.orgRevision?.orgRevisionIsDraft === false; - - // ถ้าไม่อยู่ในโครงสร้างปัจจุบัน ให้หาตัวใหม่จาก ancestorDNA - if (!isCurrent && posMaster?.ancestorDNA) { - posMaster = await this.posMasterRepository.findOne({ - where: { - ancestorDNA: posMaster.ancestorDNA, - orgRevision: { - orgRevisionIsCurrent: true, - orgRevisionIsDraft: false, - }, - }, - relations: { - orgRevision: true, - orgRoot: true, - orgChild1: true, - orgChild2: true, - orgChild3: true, - orgChild4: true, - }, - }); - } - if (posMaster) { const checkPosition = await this.positionRepository.find({ where: { @@ -4504,113 +4230,16 @@ export class CommandController extends Controller { // posMaster.conditionReason = _null; // posMaster.isCondition = false; await this.posMasterRepository.save(posMaster); - - // Match position ตามลำดับ priority: - // Condition 1: match จาก positionId - // Condition 2: match 7 ฟิลด์ (positionName, posTypeId, posLevelId, positionField, positionArea, positionExecutiveField, posExecutiveId) - // Condition 3: match 3 ฟิลด์ (positionName, posTypeId, posLevelId) - // Fallback: เลือก position แรกใน posMaster - - let positionNew: Position | null = null; - - // ═══════════════════════════════════════════════════════════ - // CONDITION 1: เช็คจาก positionId ตรง - // ═══════════════════════════════════════════════════════════ - if (item.positionId) { - const positionById = await this.positionRepository.findOne({ - where: { - id: item.positionId, - posMasterId: posMaster.id, // ต้องอยู่ใน posMaster ที่ถูกต้อง - }, - relations: ["posExecutive"], - }); - - if (positionById) { - positionNew = positionById; - } - } - - // ═══════════════════════════════════════════════════════════ - // CONDITION 2: Match 7 ฟิลด์ (ถ้า Condition 1 ไม่ match) - // ═══════════════════════════════════════════════════════════ - if (!positionNew && item.positionNameNew && item.positionTypeNew && item.positionLevelNew) { - // สร้าง where clause แบบ dynamic - ใส่เฉพาะฟิลด์ที่มีค่า - const whereCondition: any = { + const positionNew = await this.positionRepository.findOne({ + where: { posMasterId: posMaster.id, - positionName: item.positionNameNew, - posTypeId: item.positionTypeNew, - posLevelId: item.positionLevelNew, - }; - - if (item.positionField) { - whereCondition.positionField = item.positionField; - } - if (item.posExecutiveId) { - whereCondition.posExecutiveId = item.posExecutiveId; - } - if (item.positionExecutiveField) { - whereCondition.positionExecutiveField = item.positionExecutiveField; - } - if (item.positionArea) { - whereCondition.positionArea = item.positionArea; - } - - const positionBy7Fields = await this.positionRepository.findOne({ - where: whereCondition, - relations: ["posExecutive"], - order: { orderNo: "ASC" } - }); - - if (positionBy7Fields) { - positionNew = positionBy7Fields; - } - } - - // ═══════════════════════════════════════════════════════════ - // CONDITION 3: Match 3 ฟิลด์ (ถ้า Condition 2 ไม่ match) - // ═══════════════════════════════════════════════════════════ - if (!positionNew && item.positionNameNew && item.positionTypeNew && item.positionLevelNew) { - const positionBy3Fields = await this.positionRepository.findOne({ - where: { - posMasterId: posMaster.id, - positionName: item.positionNameNew, - posTypeId: item.positionTypeNew, - posLevelId: item.positionLevelNew, - }, - relations: ["posExecutive"], - order: { orderNo: "ASC" } - }); - - if (positionBy3Fields) { - positionNew = positionBy3Fields; - } - } - - // // FALLBACK: เลือก position แรก (ถ้าไม่เจอทั้ง 2 condition) - // if (!positionNew) { - // const fallbackPositions = await this.positionRepository.find({ - // where: { - // posMasterId: posMaster.id, - // }, - // relations: ["posExecutive"], - // order: { - // orderNo: "ASC", - // }, - // take: 1, - // }); - - // if (fallbackPositions.length > 0) { - // positionNew = fallbackPositions[0]; - // } - // } - + }, + }); if (positionNew) { positionNew.positionIsSelected = true; await this.positionRepository.save(positionNew, { data: req }); } await CreatePosMasterHistoryOfficer(posMaster.id, req); - profile.posMasterNo = getPosMasterNo(posMaster); - profile.org = getOrgFullName(posMaster); } const newMapProfileSalary = { profileId: profile.id, @@ -4677,10 +4306,8 @@ export class CommandController extends Controller { const _year = new Date(profile.birthDate.toDateString()).getFullYear() + 543; password = `${_date}${_month}${_year}`; } - // กรอง "." ออกจาก firstName ก่อนส่งไป keycloak - const sanitizedFirstName = profile.firstName?.replace(/\./g, "") ?? ""; userKeycloakId = await createUser(profile.citizenId, password, { - firstName: sanitizedFirstName, + firstName: profile.firstName, lastName: profile.lastName, }); const list = await getRoles(); @@ -5594,7 +5221,6 @@ export class CommandController extends Controller { date: item.commandDateAffect, refCommandDate: item.commandDateSign, refCommandNo: `${item.commandNo}/${item.commandYear}`, - refCommandId: item.commandId, createdUserId: req.user.sub, createdFullName: req.user.name, lastUpdateUserId: req.user.sub, @@ -5628,10 +5254,20 @@ export class CommandController extends Controller { _profile.lastUpdateFullName = req.user.name; _profile.lastUpdatedAt = new Date(); if (item.isLeave == true) { - if (orgRevisionRef) { - await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); + const exceptClear = await checkExceptCommandType(String(item.commandId)); + if (exceptClear.status) { + _profile.leaveReason = item.leaveReason ?? _null; + _profile.leaveCommandId = item.commandId ?? _null; + _profile.leaveCommandNo = `${item.commandNo}/${_commandYear}`; + _profile.leaveRemark = exceptClear.leaveRemark ?? _null; + _profile.leaveDate = item.commandDateAffect ?? _null; + _profile.leaveType = exceptClear.LeaveType ?? _null; + } else { + if (orgRevisionRef) { + await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); + } + await removeProfileInOrganize(_profile.id, "OFFICER"); } - await removeProfileInOrganize(_profile.id, "OFFICER"); } const clearProfile = await checkCommandType(String(item.commandId)); if (clearProfile.status) { @@ -5810,22 +5446,32 @@ export class CommandController extends Controller { _profile.lastUpdateFullName = req.user.name; _profile.lastUpdatedAt = new Date(); if (item.isLeave == true) { - // บันทึกประวัติก่อนลบตำแหน่ง - const curRevision = await this.orgRevisionRepo.findOne({ - where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, - }); - if (curRevision) { - const curPosMaster = await this.employeePosMasterRepository.findOne({ - where: { - current_holderId: _profile.id, - orgRevisionId: curRevision.id, - }, + const exceptClear = await checkExceptCommandType(String(item.commandId)); + if (exceptClear.status) { + _profile.leaveReason = item.leaveReason ?? _null; + _profile.leaveCommandId = item.commandId ?? _null; + _profile.leaveCommandNo = `${item.commandNo}/${_commandYear}`; + _profile.leaveRemark = exceptClear.leaveRemark ?? _null; + _profile.leaveDate = item.commandDateAffect ?? _null; + _profile.leaveType = exceptClear.LeaveType ?? _null; + } else { + // บันทึกประวัติก่อนลบตำแหน่ง + const curRevision = await this.orgRevisionRepo.findOne({ + where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, }); - if (curPosMaster) { - await CreatePosMasterHistoryEmployee(curPosMaster.id, req, "DELETE"); + if (curRevision) { + const curPosMaster = await this.employeePosMasterRepository.findOne({ + where: { + current_holderId: _profile.id, + orgRevisionId: curRevision.id, + }, + }); + if (curPosMaster) { + await CreatePosMasterHistoryEmployee(curPosMaster.id, req, "DELETE"); + } } + await removeProfileInOrganize(_profile.id, "EMPLOYEE"); } - await removeProfileInOrganize(_profile.id, "EMPLOYEE"); } const clearProfile = await checkCommandType(String(item.commandId)); if (clearProfile.status) { @@ -6118,7 +5764,6 @@ export class CommandController extends Controller { date: item.commandDateAffect, refCommandDate: item.commandDateSign, refCommandNo: `${item.commandNo}/${item.commandYear}`, - refCommandId: item.commandId, profileEmployeeId: item.profileId, profileId: undefined, }); @@ -6146,22 +5791,32 @@ export class CommandController extends Controller { _profile.lastUpdateFullName = req.user.name; _profile.lastUpdatedAt = new Date(); if (item.isLeave == true) { - // บันทึกประวัติก่อนลบตำแหน่ง - const curRevision = await this.orgRevisionRepo.findOne({ - where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, - }); - if (curRevision) { - const curPosMaster = await this.employeePosMasterRepository.findOne({ - where: { - current_holderId: _profile.id, - orgRevisionId: curRevision.id, - }, + const exceptClear = await checkExceptCommandType(String(item.commandId)); + if (exceptClear.status) { + _profile.leaveReason = item.leaveReason ?? _null; + _profile.leaveCommandId = item.commandId ?? _null; + _profile.leaveCommandNo = `${item.commandNo}/${_commandYear}`; + _profile.leaveRemark = exceptClear.leaveRemark ?? _null; + _profile.leaveDate = item.commandDateAffect ?? _null; + _profile.leaveType = exceptClear.LeaveType ?? _null; + } else { + // บันทึกประวัติก่อนลบตำแหน่ง + const curRevision = await this.orgRevisionRepo.findOne({ + where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, }); - if (curPosMaster) { - await CreatePosMasterHistoryEmployee(curPosMaster.id, req, "DELETE"); + if (curRevision) { + const curPosMaster = await this.employeePosMasterRepository.findOne({ + where: { + current_holderId: _profile.id, + orgRevisionId: curRevision.id, + }, + }); + if (curPosMaster) { + await CreatePosMasterHistoryEmployee(curPosMaster.id, req, "DELETE"); + } } + await removeProfileInOrganize(_profile.id, "EMPLOYEE"); } - await removeProfileInOrganize(_profile.id, "EMPLOYEE"); } const clearProfile = await checkCommandType(String(item.commandId)); if (clearProfile.status) { @@ -6674,13 +6329,6 @@ export class CommandController extends Controller { bodyPosition?: { posmasterId: string; positionId: string; - positionName: string; - posTypeId: string; - posLevelId: string; - posExecutiveId: string | null; - positionField: string | null; - positionExecutiveField: string | null; - positionArea: string | null; } | null; bodyMarry?: { marry?: boolean | null; @@ -6707,28 +6355,18 @@ export class CommandController extends Controller { }[]; }, ) { - console.log("[Excexute/CreateOfficerProfile] Starting CreateOfficeProfileExcecute"); - console.log("[Excexute/CreateOfficerProfile] Request body count:", body.data?.length); const roleKeycloak = await this.roleKeycloakRepo.findOne({ where: { name: Like("USER") }, }); - console.log("[Excexute/CreateOfficerProfile] roleKeycloak found:", !!roleKeycloak); const list = await getRoles(); - console.log("[Excexute/CreateOfficerProfile] Roles list retrieved, length:", Array.isArray(list) ? list.length : "not array"); - if (!Array.isArray(list)) { - console.error("[Excexute/CreateOfficerProfile] Failed - Cannot get role(s) data from the server"); - throw new Error("Failed. Cannot get role(s) data from the server."); - } + if (!Array.isArray(list)) throw new Error("Failed. Cannot get role(s) data from the server."); let _posNumCodeSit: string = ""; let _posNumCodeSitAbb: string = ""; - console.log("[Excexute/CreateOfficerProfile] Getting command data"); const _command = await this.commandRepository.findOne({ where: { id: body.data.find((x) => x.bodySalarys?.commandId)?.bodySalarys?.commandId ?? "" }, }); - console.log("[Excexute/CreateOfficerProfile] Command found:", !!_command, "isBangkok:", _command?.isBangkok); if (_command) { if (_command?.isBangkok?.toLocaleUpperCase() == "OFFICE") { - console.log("[Excexute/CreateOfficerProfile] Setting position codes for OFFICE"); const orgRootDeputy = await this.orgRootRepository.findOne({ where: { isDeputy: true, @@ -6741,14 +6379,10 @@ export class CommandController extends Controller { }); _posNumCodeSit = orgRootDeputy ? orgRootDeputy?.orgRootName : "สำนักปลัดกรุงเทพมหานคร"; _posNumCodeSitAbb = orgRootDeputy ? orgRootDeputy?.orgRootShortName : "สนป."; - console.log("[Excexute/CreateOfficerProfile] OFFICE position codes set:", _posNumCodeSit, _posNumCodeSitAbb); } else if (_command?.isBangkok?.toLocaleUpperCase() == "BANGKOK") { - console.log("[Excexute/CreateOfficerProfile] Setting position codes for BANGKOK"); _posNumCodeSit = "กรุงเทพมหานคร"; _posNumCodeSitAbb = "กทม."; - console.log("[Excexute/CreateOfficerProfile] BANGKOK position codes set:", _posNumCodeSit, _posNumCodeSitAbb); } else { - console.log("[Excexute/CreateOfficerProfile] Setting position codes from admin profile"); let _profileAdmin = await this.profileRepository.findOne({ where: { keycloak: _command?.createdUserId.toString(), @@ -6767,7 +6401,6 @@ export class CommandController extends Controller { _posNumCodeSitAbb = _profileAdmin?.current_holders.find((x) => x.orgRoot.orgRootShortName)?.orgRoot .orgRootShortName ?? ""; - console.log("[Excexute/CreateOfficerProfile] Admin profile position codes set:", _posNumCodeSit, _posNumCodeSitAbb); } } const before = null; @@ -6779,10 +6412,8 @@ export class CommandController extends Controller { createdAt: new Date(), lastUpdatedAt: new Date(), }; - console.log("[Excexute/CreateOfficerProfile] Starting to process", body.data.length, "profile(s)"); await Promise.all( - body.data.map(async (item, index) => { - console.log("[Excexute/CreateOfficerProfile] Processing item", index + 1, "of", body.data.length); + body.data.map(async (item) => { const _null: any = null; if (item.bodyProfile.posLevelId === "") item.bodyProfile.posLevelId = null; if (item.bodyProfile.posTypeId === "") item.bodyProfile.posTypeId = null; @@ -6790,18 +6421,15 @@ export class CommandController extends Controller { item.bodyProfile.posLevelId && !(await this.posLevelRepo.findOneBy({ id: item.bodyProfile.posLevelId })) ) { - console.error("[Excexute/CreateOfficerProfile] ไม่พบข้อมูลระดับตำแหน่งนี้ posLevelId:", item.bodyProfile.posLevelId); throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้"); } if ( item.bodyProfile.posTypeId && !(await this.posTypeRepo.findOneBy({ id: item.bodyProfile.posTypeId })) ) { - console.error("[Excexute/CreateOfficerProfile] ไม่พบข้อมูลประเภทตำแหน่งนี้ posTypeId:", item.bodyProfile.posTypeId); throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้"); } - console.log("[Excexute/CreateOfficerProfile] Processing citizenId:", item.bodyProfile.citizenId); let registrationProvinceId = await this.provinceRepo.findOneBy({ id: item.bodyProfile.registrationProvinceId ?? "", }); @@ -6820,7 +6448,6 @@ export class CommandController extends Controller { let currentSubDistrictId = await this.subDistrictRepo.findOneBy({ id: item.bodyProfile.currentSubDistrictId ?? "", }); - console.log("[Excexute/CreateOfficerProfile] Address validation completed"); let _dateRetire = item.bodyProfile.birthDate == null @@ -6833,11 +6460,8 @@ export class CommandController extends Controller { let userKeycloakId: any; let result: any; - console.log("[Excexute/CreateOfficerProfile] Checking Keycloak user for citizenId:", item.bodyProfile.citizenId); const checkUser = await getUserByUsername(item.bodyProfile.citizenId); - console.log("[Excexute/CreateOfficerProfile] Keycloak user exists:", checkUser.length > 0); if (checkUser.length == 0) { - console.log("[Excexute/CreateOfficerProfile] Creating new Keycloak user"); let password = item.bodyProfile.citizenId; if (item.bodyProfile.birthDate != null) { const _date = new Date(item.bodyProfile.birthDate.toDateString()) @@ -6850,19 +6474,10 @@ export class CommandController extends Controller { const _year = new Date(item.bodyProfile.birthDate.toDateString()).getFullYear() + 543; password = `${_date}${_month}${_year}`; } - console.log("[Excexute/CreateOfficerProfile] Calling createUser for:", item.bodyProfile.citizenId); - console.log("[Excexute/CreateOfficerProfile] createUser data - firstName:", item.bodyProfile.firstName, "lastName:", item.bodyProfile.lastName); - // กรอง "." ออกจาก firstName ก่อนส่งไป keycloak (ป้องกัน . หรืออักขระอื่นๆ) - const sanitizedFirstName = item.bodyProfile.firstName?.replace(/\./g, "") ?? ""; userKeycloakId = await createUser(item.bodyProfile.citizenId, password, { - firstName: sanitizedFirstName, + firstName: item.bodyProfile.firstName, lastName: item.bodyProfile.lastName, }); - if (userKeycloakId && typeof userKeycloakId === "object" && userKeycloakId.errorMessage) { - console.error("[Excexute/CreateOfficerProfile] createUser FAILED - field:", userKeycloakId.field, "errorMessage:", userKeycloakId.errorMessage, "params:", userKeycloakId.params); - throw new HttpError(HttpStatus.BAD_REQUEST, `Keycloak validation failed: ${userKeycloakId.field} - ${userKeycloakId.errorMessage}`); - } - console.log("[Excexute/CreateOfficerProfile] User created in Keycloak, userKeycloakId:", userKeycloakId); result = await addUserRoles( userKeycloakId, list @@ -6872,18 +6487,14 @@ export class CommandController extends Controller { name: x.name, })), ); - console.log("[Excexute/CreateOfficerProfile] USER role assigned to new user, result:", result); } else { - console.log("[Excexute/CreateOfficerProfile] Updating existing Keycloak user"); userKeycloakId = checkUser[0].id; - console.log("[Excexute/CreateOfficerProfile] Existing userKeycloakId:", userKeycloakId); const rolesData = await getRoleMappings(userKeycloakId); if (rolesData) { const _delRole = rolesData.map((x: any) => ({ id: x.id, name: x.name, })); - console.log("[Excexute/CreateOfficerProfile] Removing old roles:", _delRole.length); await removeUserRoles(userKeycloakId, _delRole); } result = await addUserRoles( @@ -6895,27 +6506,22 @@ export class CommandController extends Controller { name: x.name, })), ); - console.log("[Excexute/CreateOfficerProfile] USER role assigned to existing user"); } let profile: any = await this.profileRepository.findOne({ where: { citizenId: item.bodyProfile.citizenId /*, isActive: true */ }, relations: ["roleKeycloaks", "profileInsignias", "profileAvatars"], }); - console.log("[Excexute/CreateOfficerProfile] Profile found:", !!profile, "for citizenId:", item.bodyProfile.citizenId); let _oldInsigniaIds: string[] = []; let _oldSalaries: any[] = []; //ลูกจ้างประจำ หรือ บุคคลภายนอก if (!profile) { - console.log("[Excexute/CreateOfficerProfile] No existing profile found, creating new profile"); //กรณีลูกจ้างประจำมาสอบเป็นข้าราชการ ต้อง update สถานะโปรไฟล์เดิม let profileEmployee: any = await this.profileEmployeeRepository.findOne({ where: { citizenId: item.bodyProfile.citizenId }, relations: ["profileInsignias", "roleKeycloaks"], }); - console.log("[Excexute/CreateOfficerProfile] Employee profile found:", !!profileEmployee); if (profileEmployee) { - console.log("[Excexute/CreateOfficerProfile] Converting employee profile to officer profile"); const _order = await this.salaryRepo.findOne({ where: { profileEmployeeId: profileEmployee.id }, order: { order: "DESC" }, @@ -6988,9 +6594,8 @@ export class CommandController extends Controller { profile.amountSpecial = item.bodyProfile.amountSpecial ?? null; profile.isProbation = item.bodyProfile.isProbation; //เพิ่มใหม่จากรับโอน - profile.rank = item?.bodyProfile?.rank || null; - profile.prefix = item?.bodyProfile?.rank || item?.bodyProfile?.prefix || null; - profile.prefixMain = item?.bodyProfile?.prefix ?? null; + profile.prefix = item.bodyProfile.prefix ?? null; + profile.prefixMain = item.bodyProfile.prefix ?? null; profile.firstName = item.bodyProfile.firstName ?? null; profile.lastName = item.bodyProfile.lastName ?? null; profile.birthDate = item.bodyProfile.birthDate ?? null; @@ -7002,26 +6607,21 @@ export class CommandController extends Controller { profile.bloodGroup = item.bodyProfile.bloodGroup ?? null; profile.phone = item.bodyProfile.phone ?? null; - console.log("[Excexute/CreateOfficerProfile] Saving new profile"); await this.profileRepository.save(profile); - console.log("[Excexute/CreateOfficerProfile] New profile saved, profileId:", profile.id); // update user attribute in keycloak await updateUserAttributes(profile.keycloak ?? "", { profileId: [profile.id], prefix: [profile.prefix || ""], }); - console.log("[Excexute/CreateOfficerProfile] Keycloak attributes updated"); setLogDataDiff(req, { before, after: profile }); } //ขรก.ในระบบ หรือ ขรก.ในระบบที่สถานะพ้นจากราชการ else { - console.log("[Excexute/CreateOfficerProfile] Existing profile found, isLeave:", profile.isLeave, "leaveType:", profile.leaveType); //สร้างโปรไฟล์ใหม่ ถ้าสถานะพ้นราชการ คำสั่งโอนออกหรือคำสั่งขอลาออก if ( profile.isLeave && ["PLACEMENT_TRANSFER", "RETIRE_RESIGN"].includes(profile.leaveType) ) { - console.log("[Excexute/CreateOfficerProfile] Profile is leaving with eligible leave type, creating new profile record"); //ดึง profileSalary เดิม _oldSalaries = await this.salaryRepo.find({ where: { profileId: profile.id }, @@ -7057,9 +6657,8 @@ export class CommandController extends Controller { profile.amount = item.bodyProfile.amount ?? null; profile.amountSpecial = item.bodyProfile.amountSpecial ?? null; profile.isProbation = item.bodyProfile.isProbation; - profile.rank = item?.bodyProfile?.rank || null; - profile.prefix = item?.bodyProfile?.rank || item?.bodyProfile?.prefix || null; - profile.prefixMain = item?.bodyProfile?.prefix ?? null; + profile.prefix = item.bodyProfile.prefix ?? null; + profile.prefixMain = item.bodyProfile.prefix ?? null; profile.firstName = item.bodyProfile.firstName ?? null; profile.lastName = item.bodyProfile.lastName ?? null; profile.birthDate = item.bodyProfile.birthDate ?? null; @@ -7071,10 +6670,8 @@ export class CommandController extends Controller { profile.bloodGroup = item.bodyProfile.bloodGroup ?? null; profile.phone = item.bodyProfile.phone ?? null; await this.profileRepository.save(profile); - console.log("[Excexute/CreateOfficerProfile] New profile record saved for leaving officer, profileId:", profile.id); setLogDataDiff(req, { before, after: profile }); } else { - console.log("[Excexute/CreateOfficerProfile] Updating existing active profile"); profile.roleKeycloaks = result && roleKeycloak ? [roleKeycloak] : []; profile.keycloak = userKeycloakId && typeof userKeycloakId === "string" ? userKeycloakId : ""; @@ -7118,9 +6715,11 @@ export class CommandController extends Controller { profile.lastUpdateFullName = req.user.name; profile.lastUpdatedAt = new Date(); //เพิ่มใหม่จากรับโอน - profile.rank = item?.bodyProfile?.rank || null; - profile.prefix = item?.bodyProfile?.rank || item?.bodyProfile?.prefix || null; - profile.prefixMain = item?.bodyProfile?.prefix ?? null; + profile.prefix = + item.bodyProfile.prefix && item.bodyProfile.prefix != "" + ? item.bodyProfile.prefix + : profile.prefix; + profile.prefixMain = item.bodyProfile.prefix ?? null; profile.firstName = item.bodyProfile.firstName && item.bodyProfile.firstName != "" ? item.bodyProfile.firstName @@ -7161,16 +6760,13 @@ export class CommandController extends Controller { ? item.bodyProfile.phone : profile.phone; await this.profileRepository.save(profile); - console.log("[Excexute/CreateOfficerProfile] Existing active profile updated, profileId:", profile.id); setLogDataDiff(req, { before, after: profile }); } } if (profile && profile.id) { - console.log("[Excexute/CreateOfficerProfile] Processing additional data for profileId:", profile.id); //Educations if (item.bodyEducations && item.bodyEducations.length > 0) { - console.log("[Excexute/CreateOfficerProfile] Processing educations, count:", item.bodyEducations.length); await Promise.all( item.bodyEducations.map(async (education) => { const profileEdu = new ProfileEducation(); @@ -7193,7 +6789,6 @@ export class CommandController extends Controller { } //Certificates if (item.bodyCertificates && item.bodyCertificates.length > 0) { - console.log("[Excexute/CreateOfficerProfile] Processing certificates, count:", item.bodyCertificates.length); await Promise.all( item.bodyCertificates.map(async (cer) => { const profileCer = new ProfileCertificate(); @@ -7210,7 +6805,6 @@ export class CommandController extends Controller { } //FamilyCouple if (item.bodyMarry != null) { - console.log("[Excexute/CreateOfficerProfile] Processing couple/marry data"); const profileCouple = new ProfileFamilyCouple(); const data = { profileId: profile.id, @@ -7232,7 +6826,6 @@ export class CommandController extends Controller { } //FamilyFather if (item.bodyFather != null) { - console.log("[Excexute/CreateOfficerProfile] Processing father data"); const profileFather = new ProfileFamilyFather(); const data = { profileId: profile.id, @@ -7253,7 +6846,6 @@ export class CommandController extends Controller { } //FamilyMother if (item.bodyMother != null) { - console.log("[Excexute/CreateOfficerProfile] Processing mother data"); const profileMother = new ProfileFamilyMother(); const data = { profileId: profile.id, @@ -7275,7 +6867,6 @@ export class CommandController extends Controller { //Salary //insert profileSalary อันเก่า กรณีพ้นราชการแล้วกลับมาบรรจุ if (_oldSalaries.length > 0) { - console.log("[Excexute/CreateOfficerProfile] Restoring old salaries, count:", _oldSalaries.length); await Promise.all( _oldSalaries.map(async (oldSal) => { const profileSal: any = new ProfileSalary(); @@ -7292,7 +6883,6 @@ export class CommandController extends Controller { } //insert item.bodySalarys ต่อจากที่ insert เดิมไปแล้ว if (item.bodySalarys && item.bodySalarys != null) { - console.log("[Excexute/CreateOfficerProfile] Processing new salary data"); const dest_item = await this.salaryRepo.findOne({ where: { profileId: profile.id }, order: { order: "DESC" }, @@ -7317,9 +6907,7 @@ export class CommandController extends Controller { } //Position if (item.bodyPosition && item.bodyPosition != null) { - console.log("[Excexute/CreateOfficerProfile] Processing position assignment"); // STEP 1: หา posMaster ที่จะใช้งานตาม id ที่ส่งมา (อาจเป็นตำแหน่งเก่าหรือใหม่ก็ได้) - console.log("[Excexute/CreateOfficerProfile] STEP 1: Finding posMaster, posmasterId:", item.bodyPosition.posmasterId); let posMaster = await this.posMasterRepository.findOne({ where: { id: item.bodyPosition.posmasterId, @@ -7333,17 +6921,14 @@ export class CommandController extends Controller { orgChild4: true, }, }); - console.log("[Excexute/CreateOfficerProfile] posMaster found:", !!posMaster); // เช็คว่า posMaster ที่หามาอยู่ในโครงสร้างปัจจุบันหรือไม่ const isCurrent = posMaster?.orgRevision?.orgRevisionIsCurrent === true && posMaster?.orgRevision?.orgRevisionIsDraft === false; - console.log("[Excexute/CreateOfficerProfile] posMaster isCurrent:", isCurrent); // ถ้าไม่อยู่ในโครงสร้างปัจจุบัน ให้หาตัวใหม่จาก ancestorDNA if (!isCurrent && posMaster?.ancestorDNA) { - console.log("[Excexute/CreateOfficerProfile] Finding current posMaster from ancestorDNA"); posMaster = await this.posMasterRepository.findOne({ where: { ancestorDNA: posMaster.ancestorDNA, @@ -7361,18 +6946,12 @@ export class CommandController extends Controller { orgChild4: true, }, }); - console.log("[Excexute/CreateOfficerProfile] Current posMaster from ancestorDNA found:", !!posMaster); } - if (posMaster == null) { - console.error( - `[Excexute/CreateOfficerProfile] not found posMasterId: ${item.bodyPosition.posmasterId}` - ); + if (posMaster == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้"); - } // STEP 2: เคลียร์ข้อมูลตำแหน่งเก่าที่ครองอยู่ ในโครงสร้างปัจจุบัน - console.log("[Excexute/CreateOfficerProfile] STEP 2: Clearing old position data"); const posMasterOld = await this.posMasterRepository.findOne({ where: { current_holderId: profile.id, @@ -7398,7 +6977,6 @@ export class CommandController extends Controller { } // STEP 3: เคลียร์ position ที่เลือกไว้อื่นๆ ใน posMaster ตัวใหม่ - console.log("[Excexute/CreateOfficerProfile] STEP 3: Clearing other selected positions in new posMaster"); const checkPosition = await this.positionRepository.find({ where: { posMasterId: posMaster.id, @@ -7414,7 +6992,6 @@ export class CommandController extends Controller { } // STEP 4: กำหนดคนครองใหม่ให้กับ posMaster - console.log("[Excexute/CreateOfficerProfile] STEP 4: Assigning new holder to posMaster"); posMaster.current_holderId = profile.id; posMaster.lastUpdatedAt = new Date(); // posMaster.conditionReason = _null; @@ -7424,126 +7001,49 @@ export class CommandController extends Controller { await CreatePosMasterHistoryOfficer(posMasterOld.id, req); } await this.posMasterRepository.save(posMaster); - console.log("[Excexute/CreateOfficerProfile] posMaster saved with new holder"); // STEP 5: กำหนด position ใหม่ - console.log("[Excexute/CreateOfficerProfile] STEP 5: Determining position to assign"); - // Match position ตามลำดับ priority: - // Condition 1: match จาก positionId - // Condition 2: match 7 ฟิลด์ (positionName, posTypeId, posLevelId, positionField, positionArea, positionExecutiveField, posExecutiveId) - // Condition 3: match 3 ฟิลด์ (positionName, posTypeId, posLevelId) - // Fallback: เลือก position แรกใน posMaster + // เช็คว่า posMaster เปลี่ยนจากเก่าเป็นใหม่หรือไม่ + const originalPosMasterId = item.bodyPosition.posmasterId; + const isPosMasterChanged = originalPosMasterId !== posMaster.id; - let positionNew: Position | null = null; + let positionNew = null; - // ═══════════════════════════════════════════════════════════ - // CONDITION 1: เช็คจาก positionId ตรง - // ═══════════════════════════════════════════════════════════ - console.log("[Excexute/CreateOfficerProfile] CONDITION 1: Checking by positionId:", item.bodyPosition?.positionId); - if (item.bodyPosition?.positionId) { - const positionById = await this.positionRepository.findOne({ + if (isPosMasterChanged) { + // posMaster เปลี่ยน ต้องหา position ใหม่จากคุณสมบัติของ position เก่า + // 1. หา position เก่าจาก id ที่ส่งมา + const positionOld = await this.positionRepository.findOne({ + where: { id: item.bodyPosition.positionId }, + }); + + if (positionOld) { + // 2. ใช้ posTypeId + posLevelId + positionName หา position ใหม่ใน posMaster ตัวใหม่ + positionNew = await this.positionRepository.findOne({ + where: { + posMasterId: posMaster.id, // ใช้ posMaster ตัวใหม่ + posTypeId: positionOld.posTypeId, + posLevelId: positionOld.posLevelId, + positionName: positionOld.positionName, + }, + }); + } + } else { + // posMaster ไม่เปลี่ยน - ใช้วิธีเดิม + positionNew = await this.positionRepository.findOne({ where: { id: item.bodyPosition.positionId, - posMasterId: posMaster.id, // ต้องอยู่ใน posMaster ที่ถูกต้อง - }, - relations: ["posExecutive"], - }); - - if (positionById) { - positionNew = positionById; - console.log("[Excexute/CreateOfficerProfile] CONDITION 1 matched, positionId:", positionById.id); - } - } - - // ═══════════════════════════════════════════════════════════ - // CONDITION 2: Match 7 ฟิลด์ (ถ้า Condition 1 ไม่ match) - // ═══════════════════════════════════════════════════════════ - if (!positionNew && item.bodyPosition) { - console.log("[Excexute/CreateOfficerProfile] CONDITION 1 not matched, trying CONDITION 2: Match 7 fields"); - // สร้าง where clause แบบ dynamic - ใส่เฉพาะฟิลด์ที่ไม่ใช่ null - const whereCondition: any = { - posMasterId: posMaster.id, - positionName: item.bodyPosition.positionName, - posTypeId: item.bodyPosition.posTypeId, - posLevelId: item.bodyPosition.posLevelId, - }; - - if (item.bodyPosition.positionField) { - whereCondition.positionField = item.bodyPosition.positionField; - } - if (item.bodyPosition.posExecutiveId) { - whereCondition.posExecutiveId = item.bodyPosition.posExecutiveId; - } - if (item.bodyPosition.positionExecutiveField) { - whereCondition.positionExecutiveField = item.bodyPosition.positionExecutiveField; - } - if (item.bodyPosition.positionArea) { - whereCondition.positionArea = item.bodyPosition.positionArea; - } - - const positionBy7Fields = await this.positionRepository.findOne({ - where: whereCondition, - relations: ["posExecutive"], - order: { orderNo: "ASC" } - }); - - if (positionBy7Fields) { - positionNew = positionBy7Fields; - console.log("[Excexute/CreateOfficerProfile] CONDITION 2 matched with 7 fields, positionId:", positionBy7Fields.id); - } - } - - // ═══════════════════════════════════════════════════════════ - // CONDITION 3: Match 3 ฟิลด์ (ถ้า Condition 2 ไม่ match) - // ═══════════════════════════════════════════════════════════ - if (!positionNew && item.bodyPosition) { - console.log("[Excexute/CreateOfficerProfile] CONDITION 2 not matched, trying CONDITION 3: Match 3 fields"); - const positionBy3Fields = await this.positionRepository.findOne({ - where: { posMasterId: posMaster.id, - positionName: item.bodyPosition.positionName, - posTypeId: item.bodyPosition.posTypeId, - posLevelId: item.bodyPosition.posLevelId, }, relations: ["posExecutive"], - order: { orderNo: "ASC" } }); - - if (positionBy3Fields) { - positionNew = positionBy3Fields; - console.log("[Excexute/CreateOfficerProfile] CONDITION 3 matched with 3 fields, positionId:", positionBy3Fields.id); - } else { - console.log("[Excexute/CreateOfficerProfile] No position matched for profileId:", profile.id); - } } - // // ═══════════════════════════════════════════════════════════ - // // FALLBACK: ถ้าทั้ง 3 ไม่ match ให้เลือก position แรกใน posMaster - // // ═══════════════════════════════════════════════════════════ - // if (!positionNew) { - // const fallbackPositions = await this.positionRepository.find({ - // where: { - // posMasterId: posMaster.id, - // }, - // relations: ["posExecutive"], - // order: { - // orderNo: "ASC", - // }, - // take: 1, - // }); - - // if (fallbackPositions.length > 0) { - // positionNew = fallbackPositions[0]; - // } - // } - - // อัพเดท org และ posMasterNo ตลอดไม่ต้องดัก isSit - profile.posMasterNo = getPosMasterNo(posMaster); - profile.org = getOrgFullName(posMaster); // ถ้าไม่ใช่ตำแหน่งนั่งทับ (isSit = false) ถึงจะอัพเดทตำแหน่งในทะเบียนประวัติ if (positionNew != null) { - console.log("[Excexute/CreateOfficerProfile] Final position assignment, isSit:", posMaster.isSit, "positionId:", positionNew.id); positionNew.positionIsSelected = true; + // อัพเดท org และ posMasterNo ตลอดไม่ต้องดัก isSit + profile.posMasterNo = getPosMasterNo(posMaster); + profile.org = getOrgFullName(posMaster); if (!posMaster.isSit) { profile.posLevelId = positionNew.posLevelId; profile.posTypeId = positionNew.posTypeId; @@ -7554,19 +7054,10 @@ export class CommandController extends Controller { profile.positionExecutiveField = positionNew.positionExecutiveField ?? null; // profile.dateStart = new Date(); } + await this.profileRepository.save(profile, { data: req }); + setLogDataDiff(req, { before, after: profile }); await this.positionRepository.save(positionNew, { data: req }); - } else if (!posMaster.isSit) { - // fallback: ตำแหน่งในโครงสร้างถูกแก้ไข ใช้ข้อมูลตำแหน่งที่สมัครสอบมา - console.log("[Excexute/CreateOfficerProfile] positionNew is null, using bodyPosition data as fallback"); - profile.position = item.bodyPosition.positionName ?? null; - profile.posTypeId = item.bodyPosition.posTypeId ?? null; - profile.posLevelId = item.bodyPosition.posLevelId ?? null; - profile.positionField = item.bodyPosition.positionField ?? null; - profile.positionArea = item.bodyPosition.positionArea ?? null; - profile.positionExecutiveField = item.bodyPosition.positionExecutiveField ?? null; } - await this.profileRepository.save(profile, { data: req }); - setLogDataDiff(req, { before, after: profile }); // await CreatePosMasterHistoryOfficer(posMaster.id, req); await CreatePosMasterHistoryOfficer(posMaster.id, req, null, { positionId: positionNew?.id, @@ -7574,7 +7065,6 @@ export class CommandController extends Controller { } // Insignia if (_oldInsigniaIds.length > 0) { - console.log("[Excexute/CreateOfficerProfile] Processing old insignias, count:", _oldInsigniaIds.length); const _insignias = await this.insigniaRepo.find({ where: { id: In(_oldInsigniaIds), isDeleted: false }, order: { createdAt: "ASC" }, @@ -7609,7 +7099,6 @@ export class CommandController extends Controller { } // เพิ่มรูปภาพโปรไฟล์ if (item.bodyProfile.objectRefId) { - console.log("[Excexute/CreateOfficerProfile] Processing profile avatar image, objectRefId:", item.bodyProfile.objectRefId); const _profileAvatar = new ProfileAvatar(); Object.assign(_profileAvatar, { ...meta, @@ -7653,7 +7142,6 @@ export class CommandController extends Controller { } }), ); - console.log("[Excexute/CreateOfficerProfile] CreateOfficeProfileExcecute completed successfully"); return new HttpSuccess(); } @@ -8009,10 +7497,8 @@ export class CommandController extends Controller { const _year = new Date(profile.birthDate.toDateString()).getFullYear() + 543; password = `${_date}${_month}${_year}`; } - // กรอง "." ออกจาก firstName ก่อนส่งไป keycloak - const sanitizedFirstName = profile.firstName?.replace(/\./g, "") ?? ""; const userKeycloakId = await createUser(profile.citizenId, password, { - firstName: sanitizedFirstName, + firstName: profile.firstName, lastName: profile.lastName, // email: profile.email, }); diff --git a/src/controllers/CommandOperatorController.ts b/src/controllers/CommandOperatorController.ts index 18393f53..1a461ab3 100644 --- a/src/controllers/CommandOperatorController.ts +++ b/src/controllers/CommandOperatorController.ts @@ -9,7 +9,7 @@ import { Path, Request, Response, - Get, + Get } from "tsoa"; import { LessThan, MoreThan } from "typeorm"; import { AppDataSource } from "../database/data-source"; @@ -37,7 +37,9 @@ export class CommandOperatorController extends Controller { * @param commandId คีย์คำสั่ง */ @Get("{commandId}") - async getCommandOperatorByCommandId(@Path() commandId: string) { + async getCommandOperatorByCommandId( + @Path() commandId: string + ) { const command = await this.commandRepo.findOne({ where: { id: commandId }, select: { id: true }, @@ -59,7 +61,10 @@ export class CommandOperatorController extends Controller { * @param operatorId คีย์เจ้าหน้าที่ดำเนินการ */ @Get("swap/{direction}/{operatorId}") - async swapCommandOperator(@Path() direction: string, @Path() operatorId: string) { + async swapCommandOperator( + @Path() direction: string, + @Path() operatorId: string, + ) { const source = await this.commandOperatorRepo.findOne({ where: { id: operatorId }, }); @@ -101,7 +106,10 @@ export class CommandOperatorController extends Controller { source.orderNo = dest.orderNo; dest.orderNo = temp; - await Promise.all([this.commandOperatorRepo.save(source), this.commandOperatorRepo.save(dest)]); + await Promise.all([ + this.commandOperatorRepo.save(source), + this.commandOperatorRepo.save(dest), + ]); return new HttpSuccess(); } @@ -133,29 +141,35 @@ export class CommandOperatorController extends Controller { const nextOrderNo = (lastOrderNo?.orderNo ?? 1) + 1; const now = new Date(); - const operator = Object.assign(new CommandOperator(), { - ...body, - commandId: command.id, - orderNo: nextOrderNo, - createdUserId: request.user.sub, - createdFullName: request.user.name, - createdAt: now, - lastUpdateUserId: request.user.sub, - lastUpdateFullName: request.user.name, - lastUpdatedAt: now, - }); + const operator = Object.assign( + new CommandOperator(), + { + ...body, + commandId: command.id, + orderNo: nextOrderNo, + createdUserId: request.user.sub, + createdFullName: request.user.name, + createdAt: now, + lastUpdateUserId: request.user.sub, + lastUpdateFullName: request.user.name, + lastUpdatedAt: now, + } + ); await this.commandOperatorRepo.save(operator); return new HttpSuccess(); } - /** + /** * API ลบเจ้าหน้าที่ดำเนินการที่คำสั่ง * @summary API ลบเจ้าหน้าที่ดำเนินการที่คำสั่ง * @param commandId คีย์คำสั่ง * @param operatorId คีย์เจ้าหน้าที่ดำเนินการ */ @Delete("{commandId}/{operatorId}") - public async deleteCommandOperator(@Path() commandId: string, @Path() operatorId: string) { + public async deleteCommandOperator( + @Path() commandId: string, + @Path() operatorId: string, + ) { const queryRunner = AppDataSource.createQueryRunner(); await queryRunner.connect(); await queryRunner.startTransaction(); @@ -201,9 +215,10 @@ export class CommandOperatorController extends Controller { return new HttpSuccess(true); } catch (error) { await queryRunner.rollbackTransaction(); - console.error("Delete command operator error:", error); + throw error; } finally { await queryRunner.release(); } } + } diff --git a/src/controllers/DevTestController.ts b/src/controllers/DevTestController.ts deleted file mode 100644 index e3edfaa5..00000000 --- a/src/controllers/DevTestController.ts +++ /dev/null @@ -1,576 +0,0 @@ -import { - Controller, - Post, - Put, - Patch, - Delete, - Route, - Security, - Tags, - Body, - Path, - Request, - Response, - Get, - Query, -} from "tsoa"; -import { AppDataSource } from "../database/data-source"; -import HttpStatus from "../interfaces/http-status"; -import HttpSuccess from "../interfaces/http-success"; -import HttpStatusCode from "../interfaces/http-status"; -import HttpError from "../interfaces/http-error"; -import { Command } from "../entities/Command"; -import { Brackets, LessThan, MoreThan, Double, In, Between, IsNull, Not, Any } from "typeorm"; -import { CommandType } from "../entities/CommandType"; -import { Profile, CreateProfileAllFields } from "../entities/Profile"; -import { RequestWithUser, RequestWithUserWebService } from "../middlewares/user"; -import { OrgRevision } from "../entities/OrgRevision"; -import { ProfileEmployee } from "../entities/ProfileEmployee"; -import { PosMaster } from "../entities/PosMaster"; -import permission from "../interfaces/permission"; -import { viewCurrentTenureOfficer } from "../entities/view/viewCurrentTenureOfficer"; -import { CommandController } from "./CommandController"; -import Extension from "../interfaces/extension"; -import { viewRegistryOfficer } from "../entities/view/viewRegistryOfficer"; -import { viewRegistryEmployee } from "../entities/view/viewRegistryEmployee"; -import { Registry } from "../entities/Registry"; -import { RegistryEmployee } from "../entities/RegistryEmployee"; -import { TenurePositionOfficer } from "../entities/TenurePositionOfficer"; -import { PosMasterAssign, PosMasterAssignDTO } from "../entities/PosMasterAssign"; -import { PermissionProfile } from "../entities/PermissionProfile"; -import { OrgRoot } from "../entities/OrgRoot"; -import { MetaWorkflow } from "../entities/MetaWorkflow"; -import { MetaState } from "../entities/MetaState"; -import { MetaStateOperator } from "../entities/MetaStateOperator"; -import { Workflow } from "../entities/Workflow"; -import { State } from "../entities/State"; -import { StateOperator } from "../entities/StateOperator"; -import { StateOperatorUser } from "../entities/StateOperatorUser"; -import { - commandTypePath, - calculateGovAge, - calculateAge, - calculateRetireDate, - calculateRetireLaw, - removeProfileInOrganize, - setLogDataDiff, -} from "../interfaces/utils"; -import CallAPI from "../interfaces/call-api"; -import { PostRetireToExprofile } from "./ExRetirementController" -import { Position } from "../entities/Position"; -import { PosLevel } from "../entities/PosLevel"; -import { TenureLevelOfficer } from "../entities/TenureLevelOfficer"; -import { TenurePositionEmployee } from "../entities/TenurePositionEmployee"; -import { TenureLevelEmployee } from "../entities/TenureLevelEmployee"; -import { TenurePositionExecutiveOfficer } from "../entities/TenurePositionExecutiveOfficer"; - -@Route("api/v1/org/DevTest") -@Tags("DevTest") -@Security("bearerAuth") -@Response( - HttpStatusCode.INTERNAL_SERVER_ERROR, - "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง", -) -export class DevTestController extends Controller { - private commandRepository = AppDataSource.getRepository(Command); - private commandTypeRepository = AppDataSource.getRepository(CommandType); - private orgRevisionRepo = AppDataSource.getRepository(OrgRevision); - private orgRootRepo = AppDataSource.getRepository(OrgRoot); - private posMasterRepo = AppDataSource.getRepository(PosMaster); - private profileRepo = AppDataSource.getRepository(Profile); - private profileEmpRepo = AppDataSource.getRepository(ProfileEmployee); - private registryRepo = AppDataSource.getRepository(Registry); - private registryEmployeeRepo = AppDataSource.getRepository(RegistryEmployee); - private posMasterAssignRepository = AppDataSource.getRepository(PosMasterAssign); - private permissionProfilesRepository = AppDataSource.getRepository(PermissionProfile); - private profileEmployeeRepo = AppDataSource.getRepository(ProfileEmployee); - private metaWorkflowRepo = AppDataSource.getRepository(MetaWorkflow); - private metaStateRepo = AppDataSource.getRepository(MetaState); - private metaStateOperatorRepo = AppDataSource.getRepository(MetaStateOperator); - private workflowRepo = AppDataSource.getRepository(Workflow); - private stateRepo = AppDataSource.getRepository(State); - private stateOperatorRepo = AppDataSource.getRepository(StateOperator); - private stateOperatorUserRepo = AppDataSource.getRepository(StateOperatorUser); - private positionRepository = AppDataSource.getRepository(Position); - private positionOfficerRepo = AppDataSource.getRepository(TenurePositionOfficer); - private positionEmployeeRepo = AppDataSource.getRepository(TenurePositionEmployee); - private levelOfficerRepo = AppDataSource.getRepository(TenureLevelOfficer); - private levelEmployeeRepo = AppDataSource.getRepository(TenureLevelEmployee); - private positionExecutiveOfficerRepo = AppDataSource.getRepository( - TenurePositionExecutiveOfficer, - ); - - @Patch("tick-officer-registry") - public async calculateOfficerPosition( - @Request() req: RequestWithUser, - @Body() - body: { - profileIds: string[]; - }, - ) { - - console.log("1.") - /** - * =============================== - * PREPARE DATA - * =============================== - */ - const profile = await this.profileRepo.find({ - where: { id: In(body.profileIds) }, - relations: { - posLevel: true, - posType: true, - }, - }); - - if (!profile.length) return; - - const [{ today }] = await AppDataSource.query( - "SELECT CURRENT_DATE() as today", - ); - - const orgRevision = await this.orgRevisionRepo.findOne({ - select: ["id"], - where: { - orgRevisionIsDraft: false, - orgRevisionIsCurrent: true, - }, - }); - - /** - * =============================== - * TRANSACTION - * =============================== - */ - const queryRunner = AppDataSource.createQueryRunner(); - await queryRunner.connect(); - await queryRunner.startTransaction(); - console.log("2.") - try { - /** - * =============================== - * RESULT BUFFERS (SAVE ARRAY) - * =============================== - */ - const positionOfficerBulk: any[] = []; - const levelOfficerBulk: any[] = []; - const executiveOfficerBulk: any[] = []; - console.log("3.") - /** - * =============================== - * MAIN LOOP (SINGLE LOOP) - * =============================== - */ - for (const x of profile) { - const currentDate = - x.isLeave && x.leaveDate - ? Extension.toDateOnlyString(x.leaveDate) - : today; - /** - * ==================================== - * PARALLEL STORED PROCEDURES - * ==================================== - */ - const [ - positionResult, - levelResult, - executiveResult, - ] = await Promise.all([ - AppDataSource.query("CALL GetProfileSalaryPosition(?, ?)", [ - x.id, - currentDate, - ]), - AppDataSource.query("CALL GetProfileSalaryLevel(?, ?)", [ - x.id, - currentDate, - ]), - AppDataSource.query("CALL GetProfileSalaryExecutive(?, ?)", [ - x.id, - currentDate, - ]), - ]); - console.log("4.",x.id) - /** - * ==================================== - * POSITION - * ==================================== - */ - const posRows = positionResult?.[0] ?? []; - const posMap = - posRows.length > 1 - ? posRows.slice(1).map((r: any, i: number) => ({ - days_diff: Number(r.days_diff) || 0, - positionName: posRows[i]?.positionName, - })) - : []; - - const posCal = posMap - .filter((p:any) => p.positionName === x.position) - .reduce( - (a:any, c:any) => ({ - days_diff: a.days_diff + c.days_diff, - positionName: c.positionName, - }), - { days_diff: 0, positionName: null }, - ); - - positionOfficerBulk.push({ - profileId: x.id, - positionName: posCal.positionName, - days_diff: posCal.days_diff, - Years: Math.floor(posCal.days_diff / 365.2524), - Months: Math.floor((posCal.days_diff / 30.4375) % 12), - Days: Math.floor(posCal.days_diff % 30.4375), - }); - console.log("5.",x.id) - /** - * ==================================== - * 2️⃣ POSITION LEVEL - * ==================================== - */ - const lvlRows = levelResult?.[0] ?? []; - const lvlMap = - lvlRows.length > 1 - ? lvlRows.slice(1).map((r: any, i: number) => ({ - days_diff: Number(r.days_diff) || 0, - positionType: lvlRows[i]?.positionType, - positionLevel: lvlRows[i]?.positionLevel, - positionCee: lvlRows[i]?.positionCee, - })) - : []; - - const lvlCal = lvlMap - .filter( - (l:any) => - l.positionLevel === x.posLevel?.posLevelName && - l.positionType === x.posType?.posTypeName, - ) - .reduce( - (a:any, c:any) => ({ - days_diff: a.days_diff + c.days_diff, - positionType: c.positionType, - positionLevel: c.positionLevel, - positionCee: c.positionCee, - }), - { - days_diff: 0, - positionType: null, - positionLevel: null, - positionCee: null, - }, - ); - - levelOfficerBulk.push({ - profileId: x.id, - positionType: lvlCal.positionType, - positionLevel: lvlCal.positionLevel, - positionCee: lvlCal.positionCee, - days_diff: lvlCal.days_diff, - Years: x.posLevel ? (lvlCal.days_diff / 365.2524).toFixed(4) : 0, - Months: x.posLevel ? ((lvlCal.days_diff / 30.4375) % 12).toFixed(4) : 0, - Days: x.posLevel ? (lvlCal.days_diff % 30.4375).toFixed(4) : 0, - }); - console.log("6.",x.id) - /** - * ==================================== - * 3️⃣ POSITION EXECUTIVE - * ==================================== - */ - const exeRows = executiveResult?.[0] ?? []; - const exeMap = - exeRows.length > 1 - ? exeRows.slice(1).map((r: any, i: number) => ({ - days_diff: Number(r.days_diff) || 0, - positionExecutive: exeRows[i]?.positionExecutive, - })) - : []; - - const position = await this.positionRepository.findOne({ - where: { - positionIsSelected: true, - posMaster: { - orgRevisionId: orgRevision?.id, - current_holderId: x.id, - }, - }, - order: { createdAt: "DESC" }, - relations: { - posExecutive: true, - }, - }); - - const exeName = position?.posExecutive?.posExecutiveName; - - const exeCal = exeMap - .filter((e:any) => exeName && e.positionExecutive === exeName) - .reduce( - (a:any, c:any) => ({ - days_diff: a.days_diff + c.days_diff, - positionExecutive: c.positionExecutive, - }), - { days_diff: 0, positionExecutive: null }, - ); - - executiveOfficerBulk.push({ - profileId: x.id, - positionExecutiveName: exeCal.positionExecutive, - days_diff: exeCal.days_diff, - Years: (exeCal.days_diff / 365.2524).toFixed(4), - Months: ((exeCal.days_diff / 30.4375) % 12).toFixed(4), - Days: (exeCal.days_diff % 30.4375).toFixed(4), - }); - } - console.log("7.") - /** - * =============================== - * CLEAR ALL DATA AND SAVE ARRAY (BULK) - * =============================== - */ - await queryRunner.manager - .createQueryBuilder() - .delete() - .from(this.positionOfficerRepo.target) - .execute(); - - await queryRunner.manager - .createQueryBuilder() - .delete() - .from(this.levelOfficerRepo.target) - .execute(); - - await queryRunner.manager - .createQueryBuilder() - .delete() - .from(this.positionExecutiveOfficerRepo.target) - .execute(); - console.log("8.") - await queryRunner.manager.save(this.positionOfficerRepo.target, positionOfficerBulk); - await queryRunner.manager.save(this.levelOfficerRepo.target, levelOfficerBulk); - await queryRunner.manager.save(this.positionExecutiveOfficerRepo.target,executiveOfficerBulk); - console.log("9.") - /** - * =============================== - * REGISTRY OFFICER (SYNC VIEW) - * =============================== - */ - const allRegis = await queryRunner.manager - .getRepository(viewRegistryOfficer) - .createQueryBuilder("registryOfficer") - .where("registryOfficer.profileId IN (:...profileIds)", { - profileIds: new Set(profile.map((p) => p.id)) - }) - .getMany(); - - const mapRegistryData = allRegis.map((x) => ({ - ...x, - isProbation: Boolean(x.isProbation), - isLeave: Boolean(x.isLeave), - isRetirement: Boolean(x.isRetirement), - Educations: x.Educations ? JSON.stringify(x.Educations) : "", - })); - console.log("10.") - - await queryRunner.manager - .createQueryBuilder() - .delete() - .from(this.registryRepo.target) - .execute(); - - if (mapRegistryData.length > 0) { - await queryRunner.manager.save(this.registryRepo.target, mapRegistryData); - } - console.log("11.") - /** - * =============================== - * COMMIT - * =============================== - */ - await queryRunner.commitTransaction(); - } catch (error) { - await queryRunner.rollbackTransaction(); - throw error; - } finally { - await queryRunner.release(); - } - } - - @Post("getDNA") - public async GetData( - @Request() req: RequestWithUser - ){ - let _data: any = { - root: null, - child1: null, - child2: null, - child3: null, - child4: null, - }; - - _data = await new permission().PermissionOrgList(req, "COMMAND"); - return new HttpSuccess(_data); - } - - @Post("calculateGovAge") - public async calculateGovAge( - @Request() req: RequestWithUser, - @Body() - body: { - profileId: string; - }, - ){ - return new HttpSuccess(await calculateGovAge(body.profileId, "OFFICER")); - } - - /** - * @summary Test Job กวาดออกคำสั่ง ทำงานทุกๆตี2 - */ - @Post("cronjobCommand") - async CronjobCommand() { - const commandController = new CommandController(); - await commandController.cronjobCommand(); - } - - /** - * @summary payload & Endpoint ออกคำสั่ง - */ - @Put("path-excec/{id}") - async Bright( - @Path() id: string, - @Request() request: RequestWithUser, - ) { - const command = await this.commandRepository.findOne({ - where: { id: id }, - relations: ["commandType", "commandRecives", "commandSends", "commandSends.commandSendCCs"], - }); - if (!command) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลคำสั่งนี้"); - } - const path = commandTypePath(command.commandType.code); - return new HttpSuccess({ - path: path + "/excecute", - refIds: command.commandRecives - .filter((x) => x.refId != null) - .map((x) => ({ - refId: x.refId, - commandNo: command.commandNo, - commandYear: command.commandYear, - commandId: command.id, - remark: command.positionDetail, - amount: x.amount, - amountSpecial: x.amountSpecial, - positionSalaryAmount: x.positionSalaryAmount, - mouthSalaryAmount: x.mouthSalaryAmount, - commandCode: command.commandType.commandCode, - commandName: command.commandType.name, - commandDateAffect: command.commandExcecuteDate, - commandDateSign: command.commandAffectDate, - })), - }); - } - - /** - * API รายละเอียดรายการคำสั่ง tab4 แนบท้าย - * @summary API รายละเอียดรายการคำสั่ง tab4 แนบท้าย - * @param {string} id Id คำสั่ง - * @param {string} profileId profileId - */ - @Get("tab4/attachment/{id}/{profileId}") - async GetByIdTab4Attachment( - @Path() id: string, - @Path() profileId: string, - @Request() request: RequestWithUser - ) { - await new permission().PermissionGet(request, "COMMAND"); - - let profile: Profile | ProfileEmployee | null = null; - profile = await this.profileRepo.findOne({ where: { id: profileId } }); - if (!profile) { - profile = await this.profileEmpRepo.findOne({ where: { id: profileId } }); - if (!profile) - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลบุคคลากรนี้"); - } - - const command = await this.commandRepository.findOne({ - where: { id }, - relations: ["commandType", "commandRecives"], - }); - if (!command) { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลคำสั่งนี้"); - } - - let _command: any = []; - const path = commandTypePath(command.commandType.code); - if (path == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ"); - await new CallAPI() - .PostData(request, path + "/attachment", { - refIds: command.commandRecives - .filter((x) => - x.refId != null && - x.profileId != null && x.profileId == profileId - ) - .map((x) => ({ - refId: x.refId, - Sequence: x.order, - CitizenId: x.citizenId, - Prefix: x.prefix, - FirstName: x.firstName, - LastName: x.lastName, - Amount: x.amount, - PositionSalaryAmount: x.positionSalaryAmount, - MouthSalaryAmount: x.mouthSalaryAmount, - RemarkHorizontal: x.remarkHorizontal, - RemarkVertical: x.remarkVertical, - CommandYear: command.commandYear, - CommandExcecuteDate: command.commandExcecuteDate, - })), - }) - .then(async (res) => { - _command = res; - }) - .catch(() => {}); - - let issue = - command.isBangkok == "OFFICE" - ? "สำนักปลัดกรุงเทพมหานคร" - : command.isBangkok == "BANGKOK" - ? "กรุงเทพมหานคร" - : null; - if (issue == null) { - const orgRevisionActive = await this.orgRevisionRepo.findOne({ - where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false }, - relations: ["posMasters", "posMasters.orgRoot"], - }); - if (orgRevisionActive != null) { - const profile = await this.profileRepo.findOne({ - where: { - keycloak: command.createdUserId.toString(), - }, - }); - if (profile != null) { - issue = - orgRevisionActive?.posMasters?.filter((x) => x.current_holderId == profile.id)[0] - ?.orgRoot?.orgRootName || null; - } - } - } - if (issue == null) issue = "..................................."; - return new HttpSuccess({ - template: command.commandType.fileAttachment, - reportName: "xlsx-report", - data: { - data: _command, - issuerOrganizationName: issue, - commandNo: command.commandNo == null ? "" : Extension.ToThaiNumber(command.commandNo), - commandYear: - command.commandYear == null - ? "" - : Extension.ToThaiNumber(Extension.ToThaiYear(command.commandYear).toString()), - commandExcecuteDate: - command.commandExcecuteDate == null - ? "" - : Extension.ToThaiNumber(Extension.ToThaiFullDate2(command.commandExcecuteDate)), - }, - }); - } - -} diff --git a/src/controllers/EmployeePositionController.ts b/src/controllers/EmployeePositionController.ts index ecf11619..6ead5522 100644 --- a/src/controllers/EmployeePositionController.ts +++ b/src/controllers/EmployeePositionController.ts @@ -1058,11 +1058,11 @@ export class EmployeePositionController extends Controller { let checkChildConditions: any = {}; let keywordAsInt: any; let searchShortName = "1=1"; - let searchShortName0 = `CONCAT_WS(' ',orgRoot.orgRootShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName1 = `CONCAT_WS(' ',orgChild1.orgChild1ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName2 = `CONCAT_WS(' ',orgChild2.orgChild2ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName3 = `CONCAT_WS(' ',orgChild3.orgChild3ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName4 = `CONCAT_WS(' ',orgChild4.orgChild4ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; + let searchShortName0 = `CONCAT(orgRoot.orgRootShortName," ",posMaster.posMasterNo)`; + let searchShortName1 = `CONCAT(orgChild1.orgChild1ShortName," ",posMaster.posMasterNo)`; + let searchShortName2 = `CONCAT(orgChild2.orgChild2ShortName," ",posMaster.posMasterNo)`; + let searchShortName3 = `CONCAT(orgChild3.orgChild3ShortName," ",posMaster.posMasterNo)`; + let searchShortName4 = `CONCAT(orgChild4.orgChild4ShortName," ",posMaster.posMasterNo)`; let _data = await new permission().PermissionOrgList(request, "SYS_ORG_EMP"); if (body.type === 0) { typeCondition = { @@ -1072,7 +1072,7 @@ export class EmployeePositionController extends Controller { checkChildConditions = { orgChild1Id: IsNull(), }; - searchShortName = `CONCAT_WS(' ',orgRoot.orgRootShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgRoot.orgRootShortName," ",posMaster.posMasterNo) like '%${body.keyword}%'`; } else { } } else if (body.type === 1) { @@ -1083,7 +1083,7 @@ export class EmployeePositionController extends Controller { checkChildConditions = { orgChild2Id: IsNull(), }; - searchShortName = `CONCAT_WS(' ',orgChild1.orgChild1ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild1.orgChild1ShortName," ",posMaster.posMasterNo) like '%${body.keyword}%'`; } else { } } else if (body.type === 2) { @@ -1094,7 +1094,7 @@ export class EmployeePositionController extends Controller { checkChildConditions = { orgChild3Id: IsNull(), }; - searchShortName = `CONCAT_WS(' ',orgChild2.orgChild2ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild2.orgChild2ShortName," ",posMaster.posMasterNo) like '%${body.keyword}%'`; } else { } } else if (body.type === 3) { @@ -1105,14 +1105,14 @@ export class EmployeePositionController extends Controller { checkChildConditions = { orgChild4Id: IsNull(), }; - searchShortName = `CONCAT_WS(' ',orgChild3.orgChild3ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild3.orgChild3ShortName," ",posMaster.posMasterNo) like '%${body.keyword}%'`; } else { } } else if (body.type === 4) { typeCondition = { orgChild4Id: body.id, }; - searchShortName = `CONCAT_WS(' ',orgChild4.orgChild4ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild4.orgChild4ShortName," ",posMaster.posMasterNo) like '%${body.keyword}%'`; } let findPosition: any; let masterId = new Array(); @@ -1140,8 +1140,10 @@ export class EmployeePositionController extends Controller { select: ["posMasterId"], }); masterId = masterId.concat(findPosition.map((position: any) => position.posMasterId)); - const numericMatch = body.keyword == null ? null : body.keyword.match(/\d+/); - keywordAsInt = numericMatch ? parseInt(numericMatch[0], 10) : null; + keywordAsInt = body.keyword == null ? null : parseInt(body.keyword, 10); + if (isNaN(keywordAsInt)) { + keywordAsInt = "P@ssw0rd!z"; + } masterId = [...new Set(masterId)]; } @@ -1156,7 +1158,7 @@ export class EmployeePositionController extends Controller { ...(body.keyword && (masterId.length > 0 ? { id: In(masterId) } - : /^\d+$/.test(body.keyword) ? { posMasterNo: keywordAsInt } : { posMasterNo: Like(`%${body.keyword}%`) })), + : { posMasterNo: Like(`%${body.keyword}%`) })), }, ]; diff --git a/src/controllers/EmployeeTempPositionController.ts b/src/controllers/EmployeeTempPositionController.ts index ec17bef5..e5229e67 100644 --- a/src/controllers/EmployeeTempPositionController.ts +++ b/src/controllers/EmployeeTempPositionController.ts @@ -777,11 +777,11 @@ export class EmployeeTempPositionController extends Controller { let checkChildConditions: any = {}; let keywordAsInt: any; let searchShortName = "1=1"; - let searchShortName0 = `CONCAT(orgRoot.orgRootShortName,' ',posMaster.posMasterNo)`; - let searchShortName1 = `CONCAT(orgChild1.orgChild1ShortName,' ',posMaster.posMasterNo)`; - let searchShortName2 = `CONCAT(orgChild2.orgChild2ShortName,' ',posMaster.posMasterNo)`; - let searchShortName3 = `CONCAT(orgChild3.orgChild3ShortName,' ',posMaster.posMasterNo)`; - let searchShortName4 = `CONCAT(orgChild4.orgChild4ShortName,' ',posMaster.posMasterNo)`; + let searchShortName0 = `CONCAT(orgRoot.orgRootShortName," ",posMaster.posMasterNo)`; + let searchShortName1 = `CONCAT(orgChild1.orgChild1ShortName," ",posMaster.posMasterNo)`; + let searchShortName2 = `CONCAT(orgChild2.orgChild2ShortName," ",posMaster.posMasterNo)`; + let searchShortName3 = `CONCAT(orgChild3.orgChild3ShortName," ",posMaster.posMasterNo)`; + let searchShortName4 = `CONCAT(orgChild4.orgChild4ShortName," ",posMaster.posMasterNo)`; let _data = await new permission().PermissionOrgList(request, "SYS_ORG_TEMP"); if (body.type === 0) { typeCondition = { @@ -791,7 +791,7 @@ export class EmployeeTempPositionController extends Controller { checkChildConditions = { orgChild1Id: IsNull(), }; - searchShortName = `CONCAT(orgRoot.orgRootShortName,' ',posMaster.posMasterNo) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgRoot.orgRootShortName," ",posMaster.posMasterNo) like '%${body.keyword}%'`; } else { } } else if (body.type === 1) { @@ -802,7 +802,7 @@ export class EmployeeTempPositionController extends Controller { checkChildConditions = { orgChild2Id: IsNull(), }; - searchShortName = `CONCAT(orgChild1.orgChild1ShortName,' ',posMaster.posMasterNo) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild1.orgChild1ShortName," ",posMaster.posMasterNo) like '%${body.keyword}%'`; } else { } } else if (body.type === 2) { @@ -813,7 +813,7 @@ export class EmployeeTempPositionController extends Controller { checkChildConditions = { orgChild3Id: IsNull(), }; - searchShortName = `CONCAT(orgChild2.orgChild2ShortName,' ',posMaster.posMasterNo) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild2.orgChild2ShortName," ",posMaster.posMasterNo) like '%${body.keyword}%'`; } else { } } else if (body.type === 3) { @@ -824,14 +824,14 @@ export class EmployeeTempPositionController extends Controller { checkChildConditions = { orgChild4Id: IsNull(), }; - searchShortName = `CONCAT(orgChild3.orgChild3ShortName,' ',posMaster.posMasterNo) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild3.orgChild3ShortName," ",posMaster.posMasterNo) like '%${body.keyword}%'`; } else { } } else if (body.type === 4) { typeCondition = { orgChild4Id: body.id, }; - searchShortName = `CONCAT(orgChild4.orgChild4ShortName,' ',posMaster.posMasterNo) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild4.orgChild4ShortName," ",posMaster.posMasterNo) like '%${body.keyword}%'`; } let findPosition: any; let masterId = new Array(); @@ -859,8 +859,10 @@ export class EmployeeTempPositionController extends Controller { select: ["posMasterTempId"], }); masterId = masterId.concat(findPosition.map((position: any) => position.posMasterTempId)); - const numericMatch = body.keyword == null ? null : body.keyword.match(/\d+/); - keywordAsInt = numericMatch ? parseInt(numericMatch[0], 10) : null; + keywordAsInt = body.keyword == null ? null : parseInt(body.keyword, 10); + if (isNaN(keywordAsInt)) { + keywordAsInt = "P@ssw0rd!z"; + } masterId = [...new Set(masterId)]; } @@ -875,7 +877,7 @@ export class EmployeeTempPositionController extends Controller { ...(body.keyword && (masterId.length > 0 ? { id: In(masterId) } - : /^\d+$/.test(body.keyword) ? { posMasterNo: keywordAsInt } : { posMasterNo: Like(`%${body.keyword}%`) })), + : { posMasterNo: Like(`%${body.keyword}%`) })), }, ]; let query = AppDataSource.getRepository(EmployeeTempPosMaster) diff --git a/src/controllers/OrganizationController.ts b/src/controllers/OrganizationController.ts index e107df5c..eb91c408 100644 --- a/src/controllers/OrganizationController.ts +++ b/src/controllers/OrganizationController.ts @@ -214,7 +214,6 @@ export class OrganizationController extends Controller { await sendToQueueOrgDraft(msg); return new HttpSuccess("Draft is being created... Processing in the background."); } catch (error: any) { - console.error("Error creating draft organization:", error); throw error; } } @@ -2530,7 +2529,6 @@ export class OrganizationController extends Controller { await sendToQueueOrg(msg); return new HttpSuccess(); } catch (error: any) { - console.error("Error publishing draft organization:", error); throw error; } } @@ -5809,7 +5807,6 @@ export class OrganizationController extends Controller { .leftJoin("orgRoot.posMasters", "posMasters") .leftJoin("posMasters.current_holder", "current_holder") .orderBy("orgRoot.orgRootOrder", "ASC") - .addOrderBy("posMasters.posMasterOrder", "ASC") .getMany(); const orgRootIds = orgRootData.map((orgRoot) => orgRoot.id) || null; @@ -5850,7 +5847,6 @@ export class OrganizationController extends Controller { .leftJoin("orgChild1.posMasters", "posMasters") .leftJoin("posMasters.current_holder", "current_holder") .orderBy("orgChild1.orgChild1Order", "ASC") - .addOrderBy("posMasters.posMasterOrder", "ASC") .getMany() : []; @@ -5892,7 +5888,6 @@ export class OrganizationController extends Controller { .leftJoin("orgChild2.posMasters", "posMasters") .leftJoin("posMasters.current_holder", "current_holder") .orderBy("orgChild2.orgChild2Order", "ASC") - .addOrderBy("posMasters.posMasterOrder", "ASC") .getMany() : []; @@ -5934,7 +5929,6 @@ export class OrganizationController extends Controller { .leftJoin("orgChild3.posMasters", "posMasters") .leftJoin("posMasters.current_holder", "current_holder") .orderBy("orgChild3.orgChild3Order", "ASC") - .addOrderBy("posMasters.posMasterOrder", "ASC") .getMany() : []; @@ -5971,7 +5965,6 @@ export class OrganizationController extends Controller { .leftJoin("orgChild4.posMasters", "posMasters") .leftJoin("posMasters.current_holder", "current_holder") .orderBy("orgChild4.orgChild4Order", "ASC") - .addOrderBy("posMasters.posMasterOrder", "ASC") .getMany() : []; diff --git a/src/controllers/OrganizationDotnetController.ts b/src/controllers/OrganizationDotnetController.ts index 8e803569..23255fe3 100644 --- a/src/controllers/OrganizationDotnetController.ts +++ b/src/controllers/OrganizationDotnetController.ts @@ -26,7 +26,6 @@ import { OrgRoot } from "../entities/OrgRoot"; import { Position } from "../entities/Position"; import { PosMaster } from "../entities/PosMaster"; import { PosMasterHistory } from "../entities/PosMasterHistory"; -import { PosMasterEmployeeHistory } from "../entities/PosMasterEmployeeHistory"; import { Profile } from "../entities/Profile"; import { ProfileEducation } from "../entities/ProfileEducation"; import { ProfileEmployee } from "../entities/ProfileEmployee"; @@ -40,7 +39,7 @@ import { calculateRetireLaw } from "../interfaces/utils"; import { RequestWithUser } from "../middlewares/user"; @Route("api/v1/org/dotnet") @Tags("Dotnet") -// @Security("bearerAuth") +@Security("bearerAuth") @Response( HttpStatus.INTERNAL_SERVER_ERROR, "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง", @@ -58,7 +57,6 @@ export class OrganizationDotnetController extends Controller { private positionRepository = AppDataSource.getRepository(Position); private posMasterRepository = AppDataSource.getRepository(PosMaster); private posMasterHistoryRepository = AppDataSource.getRepository(PosMasterHistory); - private posMasterEmployeeHistoryRepository = AppDataSource.getRepository(PosMasterEmployeeHistory); private empPosMasterRepository = AppDataSource.getRepository(EmployeePosMaster); private insigniaRepo = AppDataSource.getRepository(ProfileInsignia); private employeePosDictRepository = AppDataSource.getRepository(EmployeePosDict); @@ -73,7 +71,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("check-citizen") - @Security("internalAuth") public async CheckCitizen( @Body() body: { @@ -91,7 +88,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("search") - @Security("internalAuth") public async SearchProfile( @Body() body: { @@ -306,7 +302,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("search-employee") - @Security("internalAuth") public async SearchProfileEmployee( @Body() body: { @@ -491,7 +486,6 @@ export class OrganizationDotnetController extends Controller { * @param {string} id Id หน่วยงาน */ @Get("org/{id}") - @Security("internalAuth") async GetOrganizationById(@Path() id: string) { const orgRoot = await this.orgRootRepo.findOne({ where: { id: id }, @@ -501,7 +495,6 @@ export class OrganizationDotnetController extends Controller { } @Get("agency/{id}") - @Security("internalAuth") async GetOrgAgencyById(@Path() id: string) { const orgRoot = await this.orgRootRepo.findOne({ where: { id: id }, @@ -511,7 +504,6 @@ export class OrganizationDotnetController extends Controller { } @Get("go-agency/{id}") - @Security("internalAuth") async GetOrgGoAgencyById(@Path() id: string) { const orgRoot = await this.orgRootRepo.findOne({ where: { id: id }, @@ -527,7 +519,6 @@ export class OrganizationDotnetController extends Controller { * */ @Get("get-profileId") - @Security("bearerAuth") async getProfileInbox(@Request() request: { user: Record }) { let profile: any; //OFF @@ -563,7 +554,6 @@ export class OrganizationDotnetController extends Controller { * @param {string} keycloakId Id keycloak */ @Get("keycloak-old/{keycloakId}") - @Security("internalAuth") async GetProfileByKeycloakIdAsyncOld(@Path() keycloakId: string) { const profile = await this.profileRepo.findOne({ relations: [ @@ -1363,7 +1353,6 @@ export class OrganizationDotnetController extends Controller { } @Get("keycloak/{keycloakId}") - @Security("internalAuth") async GetProfileByKeycloakIdAsync(@Path() keycloakId: string) { /* ========================= * 1. Load profile @@ -1792,7 +1781,6 @@ export class OrganizationDotnetController extends Controller { } @Get("by-keycloak/{keycloakId}") - @Security("internalAuth") async NewGetProfileByKeycloakIdAsync(@Path() keycloakId: string) { /* ========================= * 1. Load profile @@ -2027,7 +2015,6 @@ export class OrganizationDotnetController extends Controller { // เพิ่มที่อยู่ปัจจุบัน + ตำแหน่งหัวหน้า @Get("by-keycloak2/{keycloakId}") - @Security("internalAuth") async NewGetProfileByKeycloak2IdAsync(@Path() keycloakId: string) { /* ========================= * 1. Load profile @@ -2369,15 +2356,27 @@ export class OrganizationDotnetController extends Controller { * @param {string} keycloakId keycloakId profile */ @Get("check-keycloak/{keycloakId}") - @Security("internalAuth") async GetProfileForProcessCheckInAsync(@Path() keycloakId: string) { - try { - // console.log(`[check-keycloak] START - keycloakId=${keycloakId}`); + /* ========================= + * 1. Load profile (Officer) + * ========================= */ + const profile = await this.profileRepo.findOne({ + where: { keycloak: keycloakId }, + relations: { + current_holders: { + orgRevision: true, + orgRoot: true, + orgChild1: true, + orgChild2: true, + orgChild3: true, + orgChild4: true, + }, + }, + }); - /* ========================= - * 1. Load profile (Officer) - * ========================= */ - const profile = await this.profileRepo.findOne({ + // Employee + if (!profile) { + const profile = await this.profileEmpRepo.findOne({ where: { keycloak: keycloakId }, relations: { current_holders: { @@ -2390,85 +2389,15 @@ export class OrganizationDotnetController extends Controller { }, }, }); - - // Employee - if (!profile) { - console.log(`[check-keycloak] OFFICER_NOT_FOUND - keycloakId=${keycloakId}, checking EMPLOYEE`); - - const empProfile = await this.profileEmpRepo.findOne({ - where: { keycloak: keycloakId }, - relations: { - current_holders: { - orgRevision: true, - orgRoot: true, - orgChild1: true, - orgChild2: true, - orgChild3: true, - orgChild4: true, - }, - }, - }); - - if (!empProfile) { - console.log(`[check-keycloak] EMPLOYEE_NOT_FOUND - keycloakId=${keycloakId}`); - throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); - } - - const currentHolder = empProfile.current_holders?.find( - (x) => - x.orgRevision?.orgRevisionIsDraft === false && - x.orgRevision?.orgRevisionIsCurrent === true, - ); - - const mapProfile = { - profileType: "EMPLOYEE", - id: empProfile.id, - keycloak: empProfile.keycloak, - prefix: empProfile.prefix, - firstName: empProfile.firstName, - lastName: empProfile.lastName, - citizenId: empProfile.citizenId, - gender: empProfile.gender, - - root: currentHolder?.orgRoot?.orgRootName ?? null, - rootId: currentHolder?.orgRootId ?? null, - rootDnaId: currentHolder?.orgRoot?.ancestorDNA ?? null, - child1: currentHolder?.orgChild1?.orgChild1Name ?? null, - child1Id: currentHolder?.orgChild1Id ?? null, - child1DnaId: currentHolder?.orgChild1?.ancestorDNA ?? null, - child2: currentHolder?.orgChild2?.orgChild2Name ?? null, - child2Id: currentHolder?.orgChild2Id ?? null, - child2DnaId: currentHolder?.orgChild2?.ancestorDNA ?? null, - child3: currentHolder?.orgChild3?.orgChild3Name ?? null, - child3Id: currentHolder?.orgChild3Id ?? null, - child3DnaId: currentHolder?.orgChild3?.ancestorDNA ?? null, - child4: currentHolder?.orgChild4?.orgChild4Name ?? null, - child4Id: currentHolder?.orgChild4Id ?? null, - child4DnaId: currentHolder?.orgChild4?.ancestorDNA ?? null, - }; - - // console.log( - // `[check-keycloak] SUCCESS_EMPLOYEE - keycloakId=${keycloakId}, profileType=EMPLOYEE`, - // ); - - return new HttpSuccess(mapProfile); - } - - // console.log(`[check-keycloak] OFFICER_FOUND - keycloakId=${keycloakId}`); - - /* ========================================= - * 2. current holder (Officer) - * ========================================= */ + if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); const currentHolder = profile.current_holders?.find( (x) => - x.orgRevision?.orgRevisionIsDraft === false && x.orgRevision?.orgRevisionIsCurrent === true, + x.orgRevision?.orgRevisionIsDraft === false && + x.orgRevision?.orgRevisionIsCurrent === true, ); - /* ========================================= - * 3. map response - * ========================================= */ const mapProfile = { - profileType: "OFFICER", + profileType: "EMPLOYEE", id: profile.id, keycloak: profile.keycloak, prefix: profile.prefix, @@ -2494,18 +2423,48 @@ export class OrganizationDotnetController extends Controller { child4DnaId: currentHolder?.orgChild4?.ancestorDNA ?? null, }; - // console.log( - // `[check-keycloak] SUCCESS_OFFICER - keycloakId=${keycloakId}, profileType=OFFICER`, - // ); - return new HttpSuccess(mapProfile); - } catch (error: any) { - // Log เฉพาะ unexpected errors (ไม่ใช่ HttpError) - if (!(error instanceof HttpError)) { - console.error(`[check-keycloak] Unexpected error: keycloakId=${keycloakId}`, error); - } - throw error; } + + /* ========================================= + * 2. current holder (Officer) + * ========================================= */ + const currentHolder = profile.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft === false && x.orgRevision?.orgRevisionIsCurrent === true, + ); + + /* ========================================= + * 6. map response + * ========================================= */ + const mapProfile = { + profileType: "OFFICER", + id: profile.id, + keycloak: profile.keycloak, + prefix: profile.prefix, + firstName: profile.firstName, + lastName: profile.lastName, + citizenId: profile.citizenId, + gender: profile.gender, + + root: currentHolder?.orgRoot?.orgRootName ?? null, + rootId: currentHolder?.orgRootId ?? null, + rootDnaId: currentHolder?.orgRoot?.ancestorDNA ?? null, + child1: currentHolder?.orgChild1?.orgChild1Name ?? null, + child1Id: currentHolder?.orgChild1Id ?? null, + child1DnaId: currentHolder?.orgChild1?.ancestorDNA ?? null, + child2: currentHolder?.orgChild2?.orgChild2Name ?? null, + child2Id: currentHolder?.orgChild2Id ?? null, + child2DnaId: currentHolder?.orgChild2?.ancestorDNA ?? null, + child3: currentHolder?.orgChild3?.orgChild3Name ?? null, + child3Id: currentHolder?.orgChild3Id ?? null, + child3DnaId: currentHolder?.orgChild3?.ancestorDNA ?? null, + child4: currentHolder?.orgChild4?.orgChild4Name ?? null, + child4Id: currentHolder?.orgChild4Id ?? null, + child4DnaId: currentHolder?.orgChild4?.ancestorDNA ?? null, + }; + + return new HttpSuccess(mapProfile); } /** @@ -2516,7 +2475,6 @@ export class OrganizationDotnetController extends Controller { * @param {string} keycloakId keycloakId profile */ @Get("user-logs/{keycloakId}") - @Security("internalAuth") async UserLogs(@Path() keycloakId: string) { /* ========================= * 1. Load profile @@ -2596,7 +2554,6 @@ export class OrganizationDotnetController extends Controller { * @param {string} profileId Id profile */ @Get("profile/{profileId}") - @Security("internalAuth") async GetProfileByProfileIdAsync(@Path() profileId: string) { const profile = await this.profileRepo.findOne({ relations: [ @@ -3266,7 +3223,6 @@ export class OrganizationDotnetController extends Controller { * @param {string} citizenId citizen Id */ @Get("citizenId/{citizenId}") - @Security("internalAuth") async GetProfileByCitizenIdAsync(@Path() citizenId: string) { const profile = await this.profileRepo.findOne({ relations: [ @@ -3921,7 +3877,6 @@ export class OrganizationDotnetController extends Controller { * @param {string} keycloakId Id keycloak */ @Get("root/officer/{rootId}") - @Security("internalAuth") async GetProfileByRootIdAsync(@Path() rootId: string) { const profiles = await this.profileRepo.find({ relations: [ @@ -4234,7 +4189,6 @@ export class OrganizationDotnetController extends Controller { * @param {string} keycloakId Id keycloak */ @Get("root/employee/{rootId}") - @Security("internalAuth") async GetProfileByRootIdEmpAsync(@Path() rootId: string) { const profiles = await this.profileEmpRepo.find({ relations: [ @@ -4439,7 +4393,6 @@ export class OrganizationDotnetController extends Controller { * @param {string} keycloakId Id keycloak */ @Post("find/employee/position") - @Security("internalAuth") async GetProfileByPositionEmpAsync( @Body() body: { @@ -4769,7 +4722,6 @@ export class OrganizationDotnetController extends Controller { * @param {string} keycloakId Id keycloak */ @Get("user-fullname/{keycloakId}") - @Security("internalAuth") async GetUserFullName(@Path() keycloakId: string) { const profile = await this.profileRepo.findOne({ where: { keycloak: keycloakId }, @@ -4788,7 +4740,6 @@ export class OrganizationDotnetController extends Controller { * @param {string} keycloakId Id keycloak */ @Get("user-oc/{keycloakId}") - @Security("internalAuth") async getProfileByKeycloak(@Path() keycloakId: string) { const profile = await this.profileRepo.findOne({ where: { keycloak: keycloakId }, @@ -4840,7 +4791,6 @@ export class OrganizationDotnetController extends Controller { * @param {string} keycloakId Id keycloak */ @Get("user-oc-all/{keycloakId}") - @Security("internalAuth") async getAllProfileByKeycloak(@Path() keycloakId: string) { const profile = await this.profileRepo.findOne({ where: { keycloak: keycloakId }, @@ -5008,7 +4958,6 @@ export class OrganizationDotnetController extends Controller { * @param {string} ocId Id หน่วยงาน */ @Get("root-oc/{ocId}") - @Security("internalAuth") async GetRootOcId(@Path() ocId: string) { const orgRoot = await this.orgRootRepo.findOne({ where: { id: ocId }, @@ -5025,7 +4974,6 @@ export class OrganizationDotnetController extends Controller { * */ @Get("keycloak") - @Security("internalAuth") async GetProfileWithKeycloak() { const profile = await this.profileRepo.find({ where: { keycloak: Not(IsNull()) }, @@ -5235,7 +5183,6 @@ export class OrganizationDotnetController extends Controller { * */ @Get("keycloak-employee") - @Security("internalAuth") async GetProfileWithKeycloakEmployee() { const profile = await this.profileEmpRepo.find({ where: { keycloak: Not(IsNull()) || Not("") }, @@ -5364,7 +5311,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("keycloak-all-officer") - @Security("internalAuth") async PostProfileWithKeycloakAllOfficer( @Body() body: { @@ -5535,7 +5481,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("keycloak-all-officer/date") - @Security("internalAuth") async PostProfileWithKeycloakAllOfficerDate( @Body() body: { @@ -5714,7 +5659,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("none-validate-keycloak-all-officer") - @Security("internalAuth") async PostProfileWithNoneValidateKeycloakAllOfficer( @Body() body: { @@ -5884,7 +5828,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("find-node-name") - @Security("internalAuth") async findNodeName( @Body() body: { @@ -5993,7 +5936,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("officer-by-admin-role") - @Security("internalAuth") async GetOfficersByAdminRole( @Body() body: { @@ -6331,7 +6273,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("keycloak-all-employee") - @Security("internalAuth") async PostProfileWithKeycloakAllEmployee( @Body() body: { @@ -6485,7 +6426,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("none-validate-keycloak-all-employee") - @Security("internalAuth") async PostProfileWithNoneValidateKeycloakAllEmployee( @Body() body: { @@ -6639,7 +6579,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("employee-by-admin-role") - @Security("internalAuth") async GetEmployeesByAdminRole( @Body() body: { @@ -6975,274 +6914,229 @@ export class OrganizationDotnetController extends Controller { return new HttpSuccess(profile_); } - /** - * รายชื่อลูกจ้างประจำ ตามสิทธิ์ admin - * @summary รายชื่อลูกจ้างประจำ ตามสิทธิ์ admin - */ - @Post("employee-by-admin-rolev2") - @Security("internalAuth") - async GetEmployeesByAdminRoleV2( - // @Request() req: RequestWithUser, // ไม่ได้ใช้ - @Body() - body: { - node: number; - nodeId: string; - role: string; - isRetirement?: boolean; - reqNode?: number; - reqNodeId?: string; - date: Date; - }, - ) { - let typeCondition: any = {}; - if (body.role === "CHILD" || body.role === "BROTHER") { - if (body.role === "CHILD") { - switch (body.node) { - case 0: - typeCondition = { - rootDnaId: body.nodeId, - }; - break; - case 1: - typeCondition = { - child1DnaId: body.nodeId, - }; - break; - case 2: - typeCondition = { - child2DnaId: body.nodeId, - }; - break; - case 3: - typeCondition = { - child3DnaId: body.nodeId, - }; - break; - case 4: - typeCondition = { - child4DnaId: body.nodeId, - }; - break; - default: - typeCondition = {}; - break; - } - } else if (body.role === "BROTHER") { - switch (body.node) { - case 0: - typeCondition = { - rootDnaId: body.nodeId, - }; - break; - case 1: - typeCondition = { - rootDnaId: body.nodeId, - }; - break; - case 2: - typeCondition = { - child1DnaId: body.nodeId, - }; - break; - case 3: - typeCondition = { - child2DnaId: body.nodeId, - }; - break; - case 4: - typeCondition = { - child3DnaId: body.nodeId, - }; - break; - default: - typeCondition = {}; - break; - } - } - } else if (body.role === "OWNER" || body.role === "ROOT" || body.role === "PARENT") { - switch (body.reqNode) { - case 0: - typeCondition = { - rootDnaId: body.reqNodeId, - }; - break; - case 1: - typeCondition = { - child1DnaId: body.reqNodeId, - }; - break; - case 2: - typeCondition = { - child2DnaId: body.reqNodeId, - }; - break; - case 3: - typeCondition = { - child3DnaId: body.reqNodeId, - }; - break; - case 4: - typeCondition = { - child4DnaId: body.reqNodeId, - }; - break; - default: - typeCondition = {}; - break; - } - } else if (body.role === "NORMAL") { - switch (body.node) { - case 0: - typeCondition = { - rootDnaId: body.nodeId, - child1DnaId: IsNull(), - }; - break; - case 1: - typeCondition = { - child1DnaId: body.nodeId, - child2DnaId: IsNull(), - }; - break; - case 2: - typeCondition = { - child2DnaId: body.nodeId, - child3DnaId: IsNull(), - }; - break; - case 3: - typeCondition = { - child3DnaId: body.nodeId, - child4DnaId: IsNull(), - }; - break; - case 4: - typeCondition = { - child4DnaId: body.nodeId, - }; - break; - default: - typeCondition = {}; - break; - } - } - // set เวลาเป็น 23:59:59 ของวันนั้น - const date = body.date ? new Date(body.date.toISOString().slice(0, 10)) : new Date(); - date.setHours(23, 59, 59, 999); + // /** + // * รายชื่อขรก. ตามสิทธิ์ admin + // * + // * @summary รายชื่อขรก. ตามสิทธิ์ admin + // * + // */ + // @Post("employee-by-admin-rolev2") + // async GetEmployeesByAdminRoleV2( + // @Request() req: RequestWithUser, + // @Body() + // body: { + // node: number; + // nodeId: string; + // role: string; + // isRetirement?: boolean; + // reqNode?: number; + // reqNodeId?: string; + // date?: Date; + // }, + // ) { + // let typeCondition: any = {}; + // if (body.role === "CHILD" || body.role === "PARENT" || body.role === "BROTHER") { + // if (body.role === "CHILD") { + // switch (body.node) { + // case 0: + // typeCondition = { + // rootDnaId: body.nodeId, + // }; + // break; + // case 1: + // typeCondition = { + // child1DnaId: body.nodeId, + // }; + // break; + // case 2: + // typeCondition = { + // child2DnaId: body.nodeId, + // }; + // break; + // case 3: + // typeCondition = { + // child3DnaId: body.nodeId, + // }; + // break; + // case 4: + // typeCondition = { + // child4DnaId: body.nodeId, + // }; + // break; + // default: + // typeCondition = {}; + // break; + // } + // } else if (body.role === "BROTHER") { + // switch (body.node) { + // case 0: + // typeCondition = { + // rootDnaId: body.nodeId, + // }; + // break; + // case 1: + // typeCondition = { + // rootDnaId: body.nodeId, + // }; + // break; + // case 2: + // typeCondition = { + // child1DnaId: body.nodeId, + // }; + // break; + // case 3: + // typeCondition = { + // child2DnaId: body.nodeId, + // }; + // break; + // case 4: + // typeCondition = { + // child3DnaId: body.nodeId, + // }; + // break; + // default: + // typeCondition = {}; + // break; + // } + // } else if (body.role === "PARENT") { + // typeCondition = { + // rootDnaId: body.nodeId, + // child1DnaId: Not(IsNull()), + // }; + // } + // } else if (body.role === "OWNER" || body.role === "ROOT") { + // switch (body.reqNode) { + // case 0: + // typeCondition = { + // rootDnaId: body.reqNodeId, + // }; + // break; + // case 1: + // typeCondition = { + // child1DnaId: body.reqNodeId, + // }; + // break; + // case 2: + // typeCondition = { + // child2DnaId: body.reqNodeId, + // }; + // break; + // case 3: + // typeCondition = { + // child3DnaId: body.reqNodeId, + // }; + // break; + // case 4: + // typeCondition = { + // child4DnaId: body.reqNodeId, + // }; + // break; + // default: + // typeCondition = {}; + // break; + // } + // } else if (body.role === "NORMAL") { + // switch (body.node) { + // case 0: + // typeCondition = { + // rootDnaId: body.nodeId, + // child1DnaId: IsNull(), + // }; + // break; + // case 1: + // typeCondition = { + // child1DnaId: body.nodeId, + // child2DnaId: IsNull(), + // }; + // break; + // case 2: + // typeCondition = { + // child2DnaId: body.nodeId, + // child3DnaId: IsNull(), + // }; + // break; + // case 3: + // typeCondition = { + // child3DnaId: body.nodeId, + // child4DnaId: IsNull(), + // }; + // break; + // case 4: + // typeCondition = { + // child4DnaId: body.nodeId, + // }; + // break; + // default: + // typeCondition = {}; + // break; + // } + // } + // const date = body.date ? new Date(body.date) : new Date(); + // // set เวลาเป็น 23:59:59 ของวันนั้น + // date.setHours(23, 59, 59, 999); - let posEmpHis = await this.posMasterEmployeeHistoryRepository.find({ - where: { - ...typeCondition, - createdAt: LessThanOrEqual(date), - }, - select: [ - "profileEmployeeId", - "prefix", - "firstName", - "lastName", - "shortName", - "posMasterNo", - "position", - "posType", - "posLevel", - "ancestorDNA", - "rootDnaId", - "child1DnaId", - "child2DnaId", - "child3DnaId", - "child4DnaId", - "createdAt", - ], - order: { - firstName: "ASC", - lastName: "ASC", - createdAt: "DESC", - }, - }); + // let profile = await this.posMasterEmployeeHistoryRepository.find({ + // where: { + // ...typeCondition, + // createdAt: LessThanOrEqual(date), + // // firstName: Not("") && Not(IsNull()), + // // lastName: Not("") && Not(IsNull()), + // }, + // order: { + // firstName: "ASC", + // lastName: "ASC", + // createdAt: "DESC", // ให้ createdAt ล่าสุดอยู่ข้างบน + // }, + // }); - // group1: group by ancestorDNA แล้วเลือก create_at ล่าสุด - const grouped1 = new Map(); - for (const item of posEmpHis) { - const key = `${item.ancestorDNA}`; - if (!grouped1.has(key)) { - grouped1.set(key, item); - } else { - // ถ้าเจอซ้ำ ให้เลือก createdAt ล่าสุด - const exist = grouped1.get(key); - if (exist && item.createdAt > exist.createdAt) { - grouped1.set(key, item); - } - } - } - // group2: group by shortName-posMasterNo จากค่าที่ได้จาก group1 - const grouped2 = new Map(); - for (const item of Array.from(grouped1.values())) { - const key = `${item.shortName}-${item.posMasterNo}`; - if (!grouped2.has(key)) { - grouped2.set(key, item); - } else { - // ถ้าเจอซ้ำ ให้เลือก createdAt ล่าสุด - const exist = grouped2.get(key); - if (exist && item.createdAt > exist.createdAt) { - grouped2.set(key, item); - } - } - } - // group3: group by firstName-lastName จากค่าที่ได้จาก group2 - const grouped3 = new Map(); - for (const item of Array.from(grouped2.values())) { - const key = `${item.firstName}-${item.lastName}`; - if (!grouped3.has(key)) { - grouped3.set(key, item); - } else { - // ถ้าเจอซ้ำ ให้เลือก createdAt ล่าสุด - const exist = grouped3.get(key); - if (exist && item.createdAt > exist.createdAt) { - grouped3.set(key, item); - } - } - } + // // group by ancestorDNA แล้วเลือก create_at ล่าสุด + // const grouped = new Map(); + // for (const item of profile) { + // const key = `${item.shortName}-${item.posMasterNo}`; + // if (!grouped.has(key)) { + // grouped.set(key, item); + // } else { + // // ถ้าเจอซ้ำ ให้เลือก createdAt ล่าสุด + // const exist = grouped.get(key); + // if (exist && item.createdAt > exist.createdAt) { + // grouped.set(key, item); + // } + // } + // } - const profileEmployeeIds = Array.from(grouped3.values()) - .filter((x) => x.profileEmployeeId != null) - .map((x) => x.profileEmployeeId); + // const profile_ = await Promise.all( + // Array.from(grouped.values()) + // .filter((x) => x.profileId != null) + // .map(async (item: PosMasterEmployeeHistory) => { + // let profile = await this.profileRepo.findOne({ + // where: { id: item.profileId }, + // }); - const profileEmployees = await this.profileEmpRepo.find({ - where: { id: In(profileEmployeeIds) }, - select: ["id", "citizenId", "dateStart", "dateAppoint", "keycloak"], - }); + // return { + // id: item.profileId, + // prefix: item.prefix, + // firstName: item.firstName, + // lastName: item.lastName, + // citizenId: profile?.citizenId ?? null, + // dateStart: profile?.dateStart ?? null, + // dateAppoint: profile?.dateAppoint ?? null, + // keycloak: profile?.keycloak ?? null, + // posNo: item.shortName, + // position: item.position, + // positionLevel: item.posLevel, + // positionType: item.posType, + // // oc: Oc, + // orgRootId: item.rootDnaId, + // orgChild1Id: item.child1DnaId, + // orgChild2Id: item.child2DnaId, + // orgChild3Id: item.child3DnaId, + // orgChild4Id: item.child4DnaId, + // }; + // }), + // ); - const profileEmployeeMap = new Map(profileEmployees.map((p) => [p.id, p])); - - const profile_ = Array.from(grouped3.values()) - .filter((x) => x.profileEmployeeId != null) - .map((item: PosMasterEmployeeHistory) => { - const profileEmp = profileEmployeeMap.get(item.profileEmployeeId); - return { - id: item.profileEmployeeId, - prefix: item.prefix, - firstName: item.firstName, - lastName: item.lastName, - citizenId: profileEmp?.citizenId ?? null, - dateStart: profileEmp?.dateStart ?? null, - dateAppoint: profileEmp?.dateAppoint ?? null, - keycloak: profileEmp?.keycloak ?? null, - posNo: `${item.shortName} ${item.posMasterNo}`, - position: item.position, - positionLevel: item.posLevel, - positionType: item.posType, - orgRootId: item.rootDnaId, - orgChild1Id: item.child1DnaId, - orgChild2Id: item.child2DnaId, - orgChild3Id: item.child3DnaId, - orgChild4Id: item.child4DnaId, - }; - }); - - return new HttpSuccess( - (profile_ ?? []).sort((a, b) => a.posNo.localeCompare(b.posNo, undefined, { numeric: true })), - ); - } + // return new HttpSuccess(profile_); + // } /** * 4. API Update รอบการลงเวลา ในตาราง profile @@ -7251,7 +7145,6 @@ export class OrganizationDotnetController extends Controller { * */ @Put("update-dutytime") - @Security("bearerAuth") async UpdateDutyTimeAsync( @Request() req: RequestWithUser, @Body() @@ -7294,7 +7187,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("insignia/Dumb") - @Security("bearerAuth") public async newInsignia(@Request() req: RequestWithUser, @Body() body: CreateProfileInsignia) { if (!body.profileId) { throw new HttpError(HttpStatus.BAD_REQUEST, "กรุณากรอก profileId"); @@ -7371,7 +7263,6 @@ export class OrganizationDotnetController extends Controller { * @param {string} keycloakId Id keycloak */ @Get("profile-leave/keycloak/{keycloakId}") - @Security("internalAuth") async GetProfileLeaveByKeycloakIdAsync(@Path() keycloakId: string) { const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today"); let _currentDate = CURRENT_DATE[0].today; @@ -7659,7 +7550,6 @@ export class OrganizationDotnetController extends Controller { } @Post("profile-leave/keycloak") - @Security("internalAuth") async GetProfileLeaveReportByKeycloakIdAsync( @Body() body: { keycloakId: string; report?: string }, ) { @@ -7964,7 +7854,6 @@ export class OrganizationDotnetController extends Controller { * @param {string} type ประเภท (ข้าราชการ หรือ ลูกจ้าง) */ @Post("find/insignia-requests-profile/{type}") - @Security("internalAuth") async GetInsigniaRequestsProfileAsync( @Path() type: string, @Body() @@ -8094,7 +7983,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("officer-by-admin-rolev2") - @Security("internalAuth") async GetOfficersByAdminRoleV2( @Body() body: { @@ -8318,7 +8206,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("officer-by-admin-rolev3") - @Security("internalAuth") async GetOfficersByAdminRoleV3( @Body() body: { @@ -8665,7 +8552,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("officer-by-admin-rolev4") - @Security("internalAuth") async GetOfficersByAdminRoleV4( @Body() body: { @@ -8942,7 +8828,6 @@ export class OrganizationDotnetController extends Controller { * */ @Post("find-staff") - @Security("internalAuth") async findHigher( @Body() requestBody: { @@ -9151,43 +9036,4 @@ export class OrganizationDotnetController extends Controller { }); return new HttpSuccess(filteredPosMasters); } - - /** - * API ตรวจสอบสถานะผู้สมัครสอบ - * @summary API ตรวจสอบสถานะผู้สมัครสอบ - */ - @Post("check-isLeave") - @Security("internalAuth") - async findProfileIsLeave( - @Body() - req: { citizenIds: string[] } - ) { - - const profiles = await this.profileRepo.find({ - select: { - id: true, - citizenId: true, - isLeave: true, - isActive: true - }, - where: { - citizenId: In(req.citizenIds) - } - }); - - if (profiles.length === 0) { - return new HttpSuccess([]); - } - - return new HttpSuccess( - profiles.map(p => ({ - citizenId: p.citizenId, - profileId: p.id, - isLeave: p.isLeave ?? false, - isActive: p.isActive ?? false - })) - ); - - } - } diff --git a/src/controllers/PermissionController.ts b/src/controllers/PermissionController.ts index 44747b09..8c713947 100644 --- a/src/controllers/PermissionController.ts +++ b/src/controllers/PermissionController.ts @@ -37,13 +37,11 @@ export class PermissionController extends Controller { @Get("") public async getPermission(@Request() request: RequestWithUser) { - let redisClient; - try { - redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); - const getAsync = promisify(redisClient.get).bind(redisClient); + const redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); + const getAsync = promisify(redisClient.get).bind(redisClient); let profile: any = await this.profileRepo.findOne({ select: ["id"], @@ -272,11 +270,6 @@ export class PermissionController extends Controller { redisClient.setex("role_" + profile.id, 86400, JSON.stringify(reply)); } return new HttpSuccess(reply); - } finally { - if (redisClient) { - redisClient.quit(); - } - } } @Get("menu") @@ -288,13 +281,11 @@ export class PermissionController extends Controller { orgRevisionIsCurrent: true, }, }); - let redisClient; - try { - redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); - const getAsync = promisify(redisClient.get).bind(redisClient); + const redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); + const getAsync = promisify(redisClient.get).bind(redisClient); let profileType = "OFFICER"; let profile: any = await this.profileRepo.findOne({ @@ -447,11 +438,6 @@ export class PermissionController extends Controller { } return new HttpSuccess(reply); - } finally { - if (redisClient) { - redisClient.quit(); - } - } } /** @@ -686,13 +672,11 @@ export class PermissionController extends Controller { @Path() system: string, @Path() action: string, ) { - let redisClient; - try { - redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); - const getAsync = promisify(redisClient.get).bind(redisClient); + const redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); + const getAsync = promisify(redisClient.get).bind(redisClient); let profileType = "OFFICER"; let profile: any = await this.profileRepo.findOne({ @@ -781,11 +765,6 @@ export class PermissionController extends Controller { } return new HttpSuccess(reply); - } finally { - if (redisClient) { - redisClient.quit(); - } - } } @Get("user/{system}/{action}/{id}") @@ -802,13 +781,11 @@ export class PermissionController extends Controller { orgRevisionIsCurrent: true, }, }); - let redisClient; - try { - redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); - const getAsync = promisify(redisClient.get).bind(redisClient); + const redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); + const getAsync = promisify(redisClient.get).bind(redisClient); let org = this.PermissionOrg(request, system, action); let reply = await getAsync("user_" + id); @@ -889,21 +866,14 @@ export class PermissionController extends Controller { } return new HttpSuccess(reply); - } finally { - if (redisClient) { - redisClient.quit(); - } - } } public async getPermissionFunc(@Request() request: RequestWithUser) { - let redisClient; - try { - redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); - const getAsync = promisify(redisClient.get).bind(redisClient); + const redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); + const getAsync = promisify(redisClient.get).bind(redisClient); let profile: any = await this.profileRepo.findOne({ select: ["id"], @@ -1120,11 +1090,6 @@ export class PermissionController extends Controller { redisClient.setex("role_" + profile.id, 86400, JSON.stringify(reply)); } return reply; - } finally { - if (redisClient) { - redisClient.quit(); - } - } } public async Permission(req: RequestWithUser, system: string, action: string) { @@ -1150,13 +1115,11 @@ export class PermissionController extends Controller { } public async listAuthSysOrgFunc(request: RequestWithUser, system: string, action: string) { - let redisClient; - try { - redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); - const getAsync = promisify(redisClient.get).bind(redisClient); + const redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); + const getAsync = promisify(redisClient.get).bind(redisClient); let profileType = "OFFICER"; let profile: any = await this.profileRepo.findOne({ @@ -1224,11 +1187,6 @@ export class PermissionController extends Controller { redisClient.setex("posMaster_" + profile.id, 86400, JSON.stringify(reply)); } return reply; - } finally { - if (redisClient) { - redisClient.quit(); - } - } } // Helper method: ดึง org scope จากตำแหน่งปกติ @@ -1408,13 +1366,11 @@ export class PermissionController extends Controller { @Get("checkOrg/{keycloakId}") public async checkOrg(@Path() keycloakId: string) { - let redisClient; - try { - redisClient = await this.redis.createClient({ - host: REDIS_HOST, - port: REDIS_PORT, - }); - // const getAsync = promisify(redisClient.get).bind(redisClient); + const redisClient = await this.redis.createClient({ + host: REDIS_HOST, + port: REDIS_PORT, + }); + // const getAsync = promisify(redisClient.get).bind(redisClient); // let profileType = "OFFICER"; let profile: any = await this.profileRepo.findOne({ @@ -1492,10 +1448,5 @@ export class PermissionController extends Controller { // } return new HttpSuccess(reply); - } finally { - if (redisClient) { - redisClient.quit(); - } - } } } diff --git a/src/controllers/PositionController.ts b/src/controllers/PositionController.ts index cd919c19..98120f30 100644 --- a/src/controllers/PositionController.ts +++ b/src/controllers/PositionController.ts @@ -38,7 +38,7 @@ import { EmployeePosLevel } from "../entities/EmployeePosLevel"; import { AuthRole } from "../entities/AuthRole"; import { RequestWithUser } from "../middlewares/user"; import permission from "../interfaces/permission"; -import { resolveNodeLevel, setLogDataDiff, logPositionIsSelectedChange } from "../interfaces/utils"; +import { resolveNodeLevel, setLogDataDiff } from "../interfaces/utils"; import { getPosMasterNo, getOrgFullName } from "../utils/org-formatting"; import { PosMasterAssign } from "../entities/PosMasterAssign"; import { Assign } from "../entities/Assign"; @@ -1427,17 +1427,7 @@ export class PositionController extends Controller { requestBody.positions.map(async (x: any) => { const match = posMaster.positions.find((p: any) => p.id == x.id); if (match) { - const oldValue = match.positionIsSelected; - const newValue = x.positionIsSelected ?? false; - - logPositionIsSelectedChange(match.id, oldValue, newValue, { - posMasterId: posMaster.id, - userId: request.user.sub, - endpoint: "updateMaster", - action: "update_position", - }); - - match.positionIsSelected = newValue; + match.positionIsSelected = x.positionIsSelected ?? false; match.orderNo = x.orderNo ?? null; return match; } else { @@ -1688,11 +1678,11 @@ export class PositionController extends Controller { let checkChildConditions: any = {}; let keywordAsInt: any; let searchShortName = "1=1"; - let searchShortName0 = `CONCAT_WS(' ',orgRoot.orgRootShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName1 = `CONCAT_WS(' ',orgChild1.orgChild1ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName2 = `CONCAT_WS(' ',orgChild2.orgChild2ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName3 = `CONCAT_WS(' ',orgChild3.orgChild3ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName4 = `CONCAT_WS(' ',orgChild4.orgChild4ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; + let searchShortName0 = `CONCAT(orgRoot.orgRootShortName," ",posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix)`; + let searchShortName1 = `CONCAT(orgChild1.orgChild1ShortName," ",posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix)`; + let searchShortName2 = `CONCAT(orgChild2.orgChild2ShortName," ",posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix)`; + let searchShortName3 = `CONCAT(orgChild3.orgChild3ShortName," ",posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix)`; + let searchShortName4 = `CONCAT(orgChild4.orgChild4ShortName," ",posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix)`; if (body.type != null && body.id != null) { if (body.type === 0) { typeCondition = { @@ -1702,7 +1692,7 @@ export class PositionController extends Controller { checkChildConditions = { orgChild1Id: IsNull(), }; - searchShortName = `CONCAT_WS(' ',orgRoot.orgRootShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgRoot.orgRootShortName," ",posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix) like '%${body.keyword}%'`; } else { } } else if (body.type === 1) { @@ -1713,7 +1703,7 @@ export class PositionController extends Controller { checkChildConditions = { orgChild2Id: IsNull(), }; - searchShortName = `CONCAT_WS(' ',orgChild1.orgChild1ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild1.orgChild1ShortName," ",posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix) like '%${body.keyword}%'`; } else { } } else if (body.type === 2) { @@ -1724,7 +1714,7 @@ export class PositionController extends Controller { checkChildConditions = { orgChild3Id: IsNull(), }; - searchShortName = `CONCAT_WS(' ',orgChild2.orgChild2ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild2.orgChild2ShortName," ",posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix) like '%${body.keyword}%'`; } else { } } else if (body.type === 3) { @@ -1735,14 +1725,14 @@ export class PositionController extends Controller { checkChildConditions = { orgChild4Id: IsNull(), }; - searchShortName = `CONCAT_WS(' ',orgChild3.orgChild3ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild3.orgChild3ShortName," ",posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix) like '%${body.keyword}%'`; } else { } } else if (body.type === 4) { typeCondition = { orgChild4Id: body.id, }; - searchShortName = `CONCAT_WS(' ',orgChild4.orgChild4ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild4.orgChild4ShortName," ",posMaster.posMasterNoPrefix,posMaster.posMasterNo,posMaster.posMasterNoSuffix) like '%${body.keyword}%'`; } } else { body.isAll = true; @@ -1787,8 +1777,10 @@ export class PositionController extends Controller { select: ["posMasterId"], }); masterId = masterId.concat(findPosition.map((position: any) => position.posMasterId)); - const numericMatch = body.keyword == null ? null : body.keyword.match(/\d+/); - keywordAsInt = numericMatch ? parseInt(numericMatch[0], 10) : null; + keywordAsInt = body.keyword == null ? null : parseInt(body.keyword, 10); + if (isNaN(keywordAsInt)) { + keywordAsInt = "P@ssw0rd!z"; + } masterId = [...new Set(masterId)]; //serch name สิทธิ์ @@ -1821,7 +1813,7 @@ export class PositionController extends Controller { ...(body.keyword && (masterId.length > 0 ? { id: In(masterId) } - : /^\d+$/.test(body.keyword) ? { posMasterNo: keywordAsInt } : { posMasterNo: Like(`%${body.keyword}%`) })), + : { posMasterNo: Like(`%${body.keyword}%`) })), }, ]; let [posMaster, total] = await AppDataSource.getRepository(PosMaster) @@ -2162,11 +2154,11 @@ export class PositionController extends Controller { let checkChildConditions: any = {}; let keywordAsInt: any; let searchShortName = "1=1"; - let searchShortName0 = `CONCAT_WS(' ',orgRoot.orgRootShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName1 = `CONCAT_WS(' ',orgChild1.orgChild1ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName2 = `CONCAT_WS(' ',orgChild2.orgChild2ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName3 = `CONCAT_WS(' ',orgChild3.orgChild3ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName4 = `CONCAT_WS(' ',orgChild4.orgChild4ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; + let searchShortName0 = `CONCAT(orgRoot.orgRootShortName," ",posMaster.posMasterNo)`; + let searchShortName1 = `CONCAT(orgChild1.orgChild1ShortName," ",posMaster.posMasterNo)`; + let searchShortName2 = `CONCAT(orgChild2.orgChild2ShortName," ",posMaster.posMasterNo)`; + let searchShortName3 = `CONCAT(orgChild3.orgChild3ShortName," ",posMaster.posMasterNo)`; + let searchShortName4 = `CONCAT(orgChild4.orgChild4ShortName," ",posMaster.posMasterNo)`; let _data = await new permission().PermissionOrgList(request, "SYS_ORG"); if (body.type === 0) { typeCondition = { @@ -2176,7 +2168,7 @@ export class PositionController extends Controller { checkChildConditions = { orgChild1Id: IsNull(), }; - searchShortName = `CONCAT_WS(' ',orgRoot.orgRootShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgRoot.orgRootShortName," ",posMaster.posMasterNo) like '%${body.keyword}%'`; } } else if (body.type === 1) { typeCondition = { @@ -2186,7 +2178,7 @@ export class PositionController extends Controller { checkChildConditions = { orgChild2Id: IsNull(), }; - searchShortName = `CONCAT_WS(' ',orgChild1.orgChild1ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild1.orgChild1ShortName," ",posMaster.posMasterNo) like '%${body.keyword}%'`; } } else if (body.type === 2) { typeCondition = { @@ -2196,7 +2188,7 @@ export class PositionController extends Controller { checkChildConditions = { orgChild3Id: IsNull(), }; - searchShortName = `CONCAT_WS(' ',orgChild2.orgChild2ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild2.orgChild2ShortName," ",posMaster.posMasterNo) like '%${body.keyword}%'`; } } else if (body.type === 3) { typeCondition = { @@ -2206,13 +2198,13 @@ export class PositionController extends Controller { checkChildConditions = { orgChild4Id: IsNull(), }; - searchShortName = `CONCAT_WS(' ',orgChild3.orgChild3ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild3.orgChild3ShortName," ",posMaster.posMasterNo) like '%${body.keyword}%'`; } } else if (body.type === 4) { typeCondition = { orgChild4Id: body.id, }; - searchShortName = `CONCAT_WS(' ',orgChild4.orgChild4ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild4.orgChild4ShortName," ",posMaster.posMasterNo) like '%${body.keyword}%'`; } let findPosition: any; let masterId = new Array(); @@ -2249,8 +2241,10 @@ export class PositionController extends Controller { select: ["posMasterId"], }); masterId = masterId.concat(findPosition.map((position: any) => position.posMasterId)); - const numericMatch = body.keyword == null ? null : body.keyword.match(/\d+/); - keywordAsInt = numericMatch ? parseInt(numericMatch[0], 10) : null; + keywordAsInt = body.keyword == null ? null : parseInt(body.keyword, 10); + if (isNaN(keywordAsInt)) { + keywordAsInt = "P@ssw0rd!z"; + } masterId = [...new Set(masterId)]; } @@ -2277,7 +2271,7 @@ export class PositionController extends Controller { ...(body.keyword && (masterId.length > 0 ? { id: In(masterId) } - : /^\d+$/.test(body.keyword) ? { posMasterNo: keywordAsInt } : { posMasterNo: Like(`%${body.keyword}%`) })), + : { posMasterNo: Like(`%${body.keyword}%`) })), }, ]; @@ -2766,19 +2760,7 @@ export class PositionController extends Controller { id: data.id, posMasterOrder: requestBody.sortId.indexOf(data.id) + 1, })); - // Bulk update using CASE WHEN instead of save() per row - const caseClauses_0 = sortData_0 - .map((d) => `WHEN '${d.id}' THEN ${d.posMasterOrder}`) - .join(" "); - const ids_0 = sortData_0.map((d) => `'${d.id}'`).join(","); - await this.posMasterRepository - .createQueryBuilder() - .update(PosMaster) - .set({ - posMasterOrder: () => `CASE id ${caseClauses_0} END`, - }) - .where(`id IN (${ids_0})`) - .execute(); + await this.posMasterRepository.save(sortData_0, { data: request }); setLogDataDiff(request, { before, after: sortData_0 }); break; } @@ -2807,19 +2789,7 @@ export class PositionController extends Controller { id: data.id, posMasterOrder: requestBody.sortId.indexOf(data.id) + 1, })); - // Bulk update using CASE WHEN instead of save() per row - const caseClauses_1 = sortData_1 - .map((d) => `WHEN '${d.id}' THEN ${d.posMasterOrder}`) - .join(" "); - const ids_1 = sortData_1.map((d) => `'${d.id}'`).join(","); - await this.posMasterRepository - .createQueryBuilder() - .update(PosMaster) - .set({ - posMasterOrder: () => `CASE id ${caseClauses_1} END`, - }) - .where(`id IN (${ids_1})`) - .execute(); + await this.posMasterRepository.save(sortData_1, { data: request }); setLogDataDiff(request, { before, after: sortData_1 }); break; } @@ -2848,19 +2818,7 @@ export class PositionController extends Controller { id: data.id, posMasterOrder: requestBody.sortId.indexOf(data.id) + 1, })); - // Bulk update using CASE WHEN instead of save() per row - const caseClauses_2 = sortData_2 - .map((d) => `WHEN '${d.id}' THEN ${d.posMasterOrder}`) - .join(" "); - const ids_2 = sortData_2.map((d) => `'${d.id}'`).join(","); - await this.posMasterRepository - .createQueryBuilder() - .update(PosMaster) - .set({ - posMasterOrder: () => `CASE id ${caseClauses_2} END`, - }) - .where(`id IN (${ids_2})`) - .execute(); + await this.posMasterRepository.save(sortData_2, { data: request }); setLogDataDiff(request, { before, after: sortData_2 }); break; } @@ -2889,19 +2847,7 @@ export class PositionController extends Controller { id: data.id, posMasterOrder: requestBody.sortId.indexOf(data.id) + 1, })); - // Bulk update using CASE WHEN instead of save() per row - const caseClauses_3 = sortData_3 - .map((d) => `WHEN '${d.id}' THEN ${d.posMasterOrder}`) - .join(" "); - const ids_3 = sortData_3.map((d) => `'${d.id}'`).join(","); - await this.posMasterRepository - .createQueryBuilder() - .update(PosMaster) - .set({ - posMasterOrder: () => `CASE id ${caseClauses_3} END`, - }) - .where(`id IN (${ids_3})`) - .execute(); + await this.posMasterRepository.save(sortData_3, { data: request }); setLogDataDiff(request, { before, after: sortData_3 }); break; } @@ -2930,19 +2876,7 @@ export class PositionController extends Controller { id: data.id, posMasterOrder: requestBody.sortId.indexOf(data.id) + 1, })); - // Bulk update using CASE WHEN instead of save() per row - const caseClauses_4 = sortData_4 - .map((d) => `WHEN '${d.id}' THEN ${d.posMasterOrder}`) - .join(" "); - const ids_4 = sortData_4.map((d) => `'${d.id}'`).join(","); - await this.posMasterRepository - .createQueryBuilder() - .update(PosMaster) - .set({ - posMasterOrder: () => `CASE id ${caseClauses_4} END`, - }) - .where(`id IN (${ids_4})`) - .execute(); + await this.posMasterRepository.save(sortData_4, { data: request }); setLogDataDiff(request, { before, after: sortData_4 }); break; } @@ -4040,18 +3974,7 @@ export class PositionController extends Controller { statusReport: "PENDING", }); - console.log( - `[positionIsSelected-DEBUG] Deleting holder, resetting ALL positions to false (posMasterId: ${id}, userId: ${request.user.sub}, endpoint: deleteHolder)` - ); - dataMaster.positions.forEach(async (position) => { - logPositionIsSelectedChange(position.id, position.positionIsSelected, false, { - posMasterId: id, - userId: request.user.sub, - endpoint: "deleteHolder", - action: "delete_holder_reset_positions", - }); - await this.positionRepository.update(position.id, { positionIsSelected: false, }); @@ -4242,7 +4165,6 @@ export class PositionController extends Controller { const [posMaster, total] = await AppDataSource.getRepository(PosMaster) .createQueryBuilder("posMaster") - .leftJoinAndSelect("posMaster.orgRevision", "orgRevision") .leftJoinAndSelect("posMaster.orgRoot", "orgRoot") .leftJoinAndSelect("posMaster.orgChild1", "orgChild1") .leftJoinAndSelect("posMaster.orgChild2", "orgChild2") @@ -4254,8 +4176,6 @@ export class PositionController extends Controller { .leftJoinAndSelect("positions.posType", "posType") .leftJoinAndSelect("positions.posLevel", "posLevel") .leftJoinAndSelect("positions.posExecutive", "posExecutive") - .andWhere("orgRevision.orgRevisionIsCurrent = true") - .andWhere("orgRevision.orgRevisionIsDraft = false") .andWhere( new Brackets((qb) => { qb.andWhere(typeCondition).andWhere(conditionA == null ? "1=1" : conditionA, { @@ -4543,7 +4463,6 @@ export class PositionController extends Controller { const [posMaster, total] = await AppDataSource.getRepository(PosMaster) .createQueryBuilder("posMaster") - .leftJoinAndSelect("posMaster.orgRevision", "orgRevision") .leftJoinAndSelect("posMaster.orgRoot", "orgRoot") .leftJoinAndSelect("posMaster.orgChild1", "orgChild1") .leftJoinAndSelect("posMaster.orgChild2", "orgChild2") @@ -4556,8 +4475,6 @@ export class PositionController extends Controller { .leftJoinAndSelect("positions.posLevel", "posLevel") .leftJoinAndSelect("positions.posExecutive", "posExecutive") .andWhere("posMaster.next_holderId IS NULL") - .andWhere("orgRevision.orgRevisionIsCurrent = true") - .andWhere("orgRevision.orgRevisionIsDraft = false") .andWhere( new Brackets((qb) => { qb.andWhere(typeCondition) @@ -5357,11 +5274,11 @@ export class PositionController extends Controller { let checkChildConditions: any = {}; let keywordAsInt: any; let searchShortName = "1=1"; - let searchShortName0 = `CONCAT_WS(' ',orgRoot.orgRootShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName1 = `CONCAT_WS(' ',orgChild1.orgChild1ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName2 = `CONCAT_WS(' ',orgChild2.orgChild2ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName3 = `CONCAT_WS(' ',orgChild3.orgChild3ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; - let searchShortName4 = `CONCAT_WS(' ',orgChild4.orgChild4ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,''))`; + let searchShortName0 = `CONCAT(orgRoot.orgRootShortName," ",COALESCE(posMaster.posMasterNoPrefix, ""),posMaster.posMasterNo,COALESCE(posMaster.posMasterNoSuffix, ""))`; + let searchShortName1 = `CONCAT(orgChild1.orgChild1ShortName," ",COALESCE(posMaster.posMasterNoPrefix, ""),posMaster.posMasterNo,COALESCE(posMaster.posMasterNoSuffix, ""))`; + let searchShortName2 = `CONCAT(orgChild2.orgChild2ShortName," ",COALESCE(posMaster.posMasterNoPrefix, ""),posMaster.posMasterNo,COALESCE(posMaster.posMasterNoSuffix, ""))`; + let searchShortName3 = `CONCAT(orgChild3.orgChild3ShortName," ",COALESCE(posMaster.posMasterNoPrefix, ""),posMaster.posMasterNo,COALESCE(posMaster.posMasterNoSuffix, ""))`; + let searchShortName4 = `CONCAT(orgChild4.orgChild4ShortName," ",COALESCE(posMaster.posMasterNoPrefix, ""),posMaster.posMasterNo,COALESCE(posMaster.posMasterNoSuffix, ""))`; let _data = await new permission().PermissionOrgList(request, "SYS_POS_CONDITION"); const orgDna = await new permission().checkDna(request, request.user.sub); let level: any = resolveNodeLevel(orgDna); @@ -5403,7 +5320,7 @@ export class PositionController extends Controller { // checkChildConditions = { // orgChild1Id: IsNull(), // }; - // searchShortName = `CONCAT_WS(' ',orgRoot.orgRootShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + // searchShortName = `CONCAT(orgRoot.orgRootShortName," ",COALESCE(posMaster.posMasterNoPrefix, ""),posMaster.posMasterNo,COALESCE(posMaster.posMasterNoSuffix, "")) like '%${body.keyword}%'`; // } else { // } } else if (body.type === 1) { @@ -5414,7 +5331,7 @@ export class PositionController extends Controller { // checkChildConditions = { // orgChild2Id: IsNull(), // }; - // searchShortName = `CONCAT_WS(' ',orgChild1.orgChild1ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + // searchShortName = `CONCAT(orgChild1.orgChild1ShortName," ",COALESCE(posMaster.posMasterNoPrefix, ""),posMaster.posMasterNo,COALESCE(posMaster.posMasterNoSuffix, "")) like '%${body.keyword}%'`; // } else { // } } else if (body.type === 2) { @@ -5425,7 +5342,7 @@ export class PositionController extends Controller { // checkChildConditions = { // orgChild3Id: IsNull(), // }; - // searchShortName = `CONCAT_WS(' ',orgChild2.orgChild2ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + // searchShortName = `CONCAT(orgChild2.orgChild2ShortName," ",COALESCE(posMaster.posMasterNoPrefix, ""),posMaster.posMasterNo,COALESCE(posMaster.posMasterNoSuffix, "")) like '%${body.keyword}%'`; // } else { // } } else if (body.type === 3) { @@ -5436,14 +5353,14 @@ export class PositionController extends Controller { // checkChildConditions = { // orgChild4Id: IsNull(), // }; - // searchShortName = `CONCAT_WS(' ',orgChild3.orgChild3ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + // searchShortName = `CONCAT(orgChild3.orgChild3ShortName," ",COALESCE(posMaster.posMasterNoPrefix, ""),posMaster.posMasterNo,COALESCE(posMaster.posMasterNoSuffix, "")) like '%${body.keyword}%'`; // } else { // } } else if (body.type === 4) { typeCondition = { ...(cannotViewChild4PosMaster ? { orgChild4Id: null } : { orgChild4Id: body.id }), }; - searchShortName = `CONCAT_WS(' ',orgChild4.orgChild4ShortName,NULLIF(posMaster.posMasterNoPrefix,''),posMaster.posMasterNo,NULLIF(posMaster.posMasterNoSuffix,'')) like '%${body.keyword}%'`; + searchShortName = `CONCAT(orgChild4.orgChild4ShortName," ",COALESCE(posMaster.posMasterNoPrefix, ""),posMaster.posMasterNo,COALESCE(posMaster.posMasterNoSuffix, "")) like '%${body.keyword}%'`; } let findPosition: any; let masterId = new Array(); @@ -5480,8 +5397,10 @@ export class PositionController extends Controller { select: ["posMasterId"], }); masterId = masterId.concat(findPosition.map((position: any) => position.posMasterId)); - const numericMatch = body.keyword == null ? null : body.keyword.match(/\d+/); - keywordAsInt = numericMatch ? parseInt(numericMatch[0], 10) : null; + keywordAsInt = body.keyword == null ? null : parseInt(body.keyword, 10); + if (isNaN(keywordAsInt)) { + keywordAsInt = "P@ssw0rd!z"; + } masterId = [...new Set(masterId)]; } @@ -5508,7 +5427,7 @@ export class PositionController extends Controller { ...(body.keyword && (masterId.length > 0 ? { id: In(masterId) } - : /^\d+$/.test(body.keyword) ? { posMasterNo: keywordAsInt } : { posMasterNo: Like(`%${body.keyword}%`) })), + : { posMasterNo: Like(`%${body.keyword}%`) })), ...(!body.isAll && { isCondition: true }), }, ]; diff --git a/src/controllers/ProfileChangeNameController.ts b/src/controllers/ProfileChangeNameController.ts index fa88a252..77cff634 100644 --- a/src/controllers/ProfileChangeNameController.ts +++ b/src/controllers/ProfileChangeNameController.ts @@ -25,7 +25,6 @@ import { } from "../entities/ProfileChangeName"; import { updateName } from "../keycloak"; import permission from "../interfaces/permission"; -import { updateHolderProfileHistory } from "../services/PositionService"; import { setLogDataDiff } from "../interfaces/utils"; @Route("api/v1/org/profile/changeName") @Tags("ProfileChangeName") @@ -128,9 +127,6 @@ export class ProfileChangeNameController extends Controller { } } - // บันทึกประวัติคนครองตำแหน่ง (ถ้า profile นี้ครองตำแหน่งอยู่) - await updateHolderProfileHistory(profile.id, req); - return new HttpSuccess(data.id); } diff --git a/src/controllers/ProfileChangeNameEmployeeController.ts b/src/controllers/ProfileChangeNameEmployeeController.ts index 0a6f2ff0..c2df9c8c 100644 --- a/src/controllers/ProfileChangeNameEmployeeController.ts +++ b/src/controllers/ProfileChangeNameEmployeeController.ts @@ -24,7 +24,6 @@ import { } from "../entities/ProfileChangeName"; import { ProfileEmployee } from "../entities/ProfileEmployee"; import permission from "../interfaces/permission"; -import { updateHolderProfileHistory } from "../services/PositionService"; import { updateName } from "../keycloak"; import { setLogDataDiff } from "../interfaces/utils"; @Route("api/v1/org/profile-employee/changeName") @@ -134,9 +133,6 @@ export class ProfileChangeNameEmployeeController extends Controller { } } - // บันทึกประวัติคนครองตำแหน่ง (ถ้า profile นี้ครองตำแหน่งอยู่) - await updateHolderProfileHistory(profile.id, req, "EMPLOYEE"); - return new HttpSuccess(data.id); } diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index 42b322d3..3c514b6b 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -93,7 +93,6 @@ import { CreatePosMasterHistoryOfficer, getTopDegrees, getPosMasterPositions } f import { ProfileLeaveService } from "../services/ProfileLeaveService"; // import { PostRetireToExprofile } from "./ExRetirementController"; import { getPosNumCodeSit } from "../services/CommandService"; -import { updateHolderProfileHistory } from "../services/PositionService"; @Route("api/v1/org/profile") @Tags("Profile") @Security("bearerAuth") @@ -408,8 +407,8 @@ export class ProfileController extends Controller { ? Extension.ToThaiNumber(Extension.ToThaiNumber(salary_raw[0].positionExecutive)) : "", org: `${salary_raw.length > 0 && salary_raw[0].orgChild4 && salary_raw[0].orgChild4 != "-" - ? Extension.ToThaiNumber(Extension.ToThaiNumber(salary_raw[0].orgChild4)) + " " - : "" + ? Extension.ToThaiNumber(Extension.ToThaiNumber(salary_raw[0].orgChild4)) + " " + : "" }${salary_raw.length > 0 && salary_raw[0].orgChild3 && salary_raw[0].orgChild3 != "-" ? Extension.ToThaiNumber(Extension.ToThaiNumber(salary_raw[0].orgChild3)) + " " : "" @@ -5775,26 +5774,29 @@ export class ProfileController extends Controller { } if (body.citizenId) { - Extension.CheckCitizen(body.citizenId); + const citizenIdDigits = body.citizenId.toString().split("").map(Number); + const cal = + citizenIdDigits[0] * 13 + + citizenIdDigits[1] * 12 + + citizenIdDigits[2] * 11 + + citizenIdDigits[3] * 10 + + citizenIdDigits[4] * 9 + + citizenIdDigits[5] * 8 + + citizenIdDigits[6] * 7 + + citizenIdDigits[7] * 6 + + citizenIdDigits[8] * 5 + + citizenIdDigits[9] * 4 + + citizenIdDigits[10] * 3 + + citizenIdDigits[11] * 2; + const calStp2 = cal % 11; + const chkDigit = (11 - calStp2) % 10; + + if (citizenIdDigits[12] !== chkDigit) { + throw new HttpError(HttpStatus.NOT_FOUND, "ข้อมูลรหัสบัตรประจำตัวประชาชนไม่ถูกต้อง"); + } } const record = await this.profileRepo.findOneBy({ id }); const before = structuredClone(record); - // เช็คว่ามี profileHistory ของ profile นี้หรือไม่ - const historyCount = await this.profileHistoryRepo.count({ - where: { profileId: id }, - }); - - // ถ้าไม่มีเลย ให้บันทึกข้อมูลเริ่มต้น (ก่อน update) ลงไปก่อน - if (historyCount === 0) { - await this.profileHistoryRepo.save( - Object.assign(new ProfileHistory(), { - ...before, - birthDateOld: before?.birthDate, - profileId: id, - id: undefined, - }), - ); - } if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); @@ -5831,9 +5833,6 @@ export class ProfileController extends Controller { } } - // บันทึกประวัติคนครองตำแหน่ง (ถ้า profile นี้ครองตำแหน่งอยู่) - await updateHolderProfileHistory(record.id, request); - return new HttpSuccess(); } @@ -6026,12 +6025,12 @@ export class ProfileController extends Controller { queryLike = "profile.position LIKE :keyword"; } else if (searchField == "posNo") { queryLike = ` - CASE - WHEN current_holders.orgChild4Id IS NOT NULL THEN CONCAT_WS(' ', orgChild4.orgChild4ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - WHEN current_holders.orgChild3Id IS NOT NULL THEN CONCAT_WS(' ', orgChild3.orgChild3ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - WHEN current_holders.orgChild2Id IS NOT NULL THEN CONCAT_WS(' ', orgChild2.orgChild2ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - WHEN current_holders.orgChild1Id IS NOT NULL THEN CONCAT_WS(' ', orgChild1.orgChild1ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - ELSE CONCAT_WS(' ', orgRoot.orgRootShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) + CASE + WHEN current_holders.orgChild4Id IS NOT NULL THEN CONCAT(orgChild4.orgChild4ShortName, " ", current_holders.posMasterNo) + WHEN current_holders.orgChild3Id IS NOT NULL THEN CONCAT(orgChild3.orgChild3ShortName, " ", current_holders.posMasterNo) + WHEN current_holders.orgChild2Id IS NOT NULL THEN CONCAT(orgChild2.orgChild2ShortName, " ", current_holders.posMasterNo) + WHEN current_holders.orgChild1Id IS NOT NULL THEN CONCAT(orgChild1.orgChild1ShortName, " ", current_holders.posMasterNo) + ELSE CONCAT(orgRoot.orgRootShortName, " ", current_holders.posMasterNo) END LIKE :keyword `; } @@ -6301,7 +6300,7 @@ export class ProfileController extends Controller { @Query() sortBy: string = "profile.dateLeave", @Query() sort: "ASC" | "DESC" = "ASC", ) { - let _data = await new permission().PermissionOrgList(request, "SYS_REGISTRY_RETIRE_OFFICER"); + let _data = await new permission().PermissionOrgList(request, "SYS_REGISTRY_OFFICER"); const { data, total } = await this.profileLeaveService.getLeaveOfficer(request, { page, @@ -6616,12 +6615,12 @@ export class ProfileController extends Controller { queryLike = "profile.position LIKE :keyword"; } else if (searchField == "posNo") { queryLike = ` - CASE - WHEN current_holders.orgChild4Id IS NOT NULL THEN CONCAT_WS(' ', orgChild4.orgChild4ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - WHEN current_holders.orgChild3Id IS NOT NULL THEN CONCAT_WS(' ', orgChild3.orgChild3ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - WHEN current_holders.orgChild2Id IS NOT NULL THEN CONCAT_WS(' ', orgChild2.orgChild2ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - WHEN current_holders.orgChild1Id IS NOT NULL THEN CONCAT_WS(' ', orgChild1.orgChild1ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - ELSE CONCAT_WS(' ', orgRoot.orgRootShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) + CASE + WHEN current_holders.orgChild4Id IS NOT NULL THEN CONCAT(orgChild4.orgChild4ShortName, " ", current_holders.posMasterNo) + WHEN current_holders.orgChild3Id IS NOT NULL THEN CONCAT(orgChild3.orgChild3ShortName, " ", current_holders.posMasterNo) + WHEN current_holders.orgChild2Id IS NOT NULL THEN CONCAT(orgChild2.orgChild2ShortName, " ", current_holders.posMasterNo) + WHEN current_holders.orgChild1Id IS NOT NULL THEN CONCAT(orgChild1.orgChild1ShortName, " ", current_holders.posMasterNo) + ELSE CONCAT(orgRoot.orgRootShortName, " ", current_holders.posMasterNo) END LIKE :keyword `; } @@ -6804,19 +6803,18 @@ export class ProfileController extends Controller { .filter(Boolean) .join("\n"); - const numPart = holder ? [holder.posMasterNoPrefix, holder.posMasterNo, holder.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; const shortName = !holder ? null : holder.orgChild4 != null - ? `${holder.orgChild4.orgChild4ShortName} ${numPart}` + ? `${holder.orgChild4.orgChild4ShortName} ${holder.posMasterNo}` : holder.orgChild3 != null - ? `${holder.orgChild3.orgChild3ShortName} ${numPart}` + ? `${holder.orgChild3.orgChild3ShortName} ${holder.posMasterNo}` : holder.orgChild2 != null - ? `${holder.orgChild2.orgChild2ShortName} ${numPart}` + ? `${holder.orgChild2.orgChild2ShortName} ${holder.posMasterNo}` : holder.orgChild1 != null - ? `${holder.orgChild1.orgChild1ShortName} ${numPart}` + ? `${holder.orgChild1.orgChild1ShortName} ${holder.posMasterNo}` : holder.orgRoot != null - ? `${holder.orgRoot.orgRootShortName} ${numPart}` + ? `${holder.orgRoot.orgRootShortName} ${holder.posMasterNo}` : null; return { @@ -7010,12 +7008,12 @@ export class ProfileController extends Controller { queryLike = "profile.position LIKE :keyword"; } else if (searchField == "posNo") { queryLike = ` - CASE - WHEN current_holders.orgChild4Id IS NOT NULL THEN CONCAT_WS(' ', orgChild4.orgChild4ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - WHEN current_holders.orgChild3Id IS NOT NULL THEN CONCAT_WS(' ', orgChild3.orgChild3ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - WHEN current_holders.orgChild2Id IS NOT NULL THEN CONCAT_WS(' ', orgChild2.orgChild2ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - WHEN current_holders.orgChild1Id IS NOT NULL THEN CONCAT_WS(' ', orgChild1.orgChild1ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - ELSE CONCAT_WS(' ', orgRoot.orgRootShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) + CASE + WHEN current_holders.orgChild4Id IS NOT NULL THEN CONCAT(orgChild4.orgChild4ShortName, " ", current_holders.posMasterNo) + WHEN current_holders.orgChild3Id IS NOT NULL THEN CONCAT(orgChild3.orgChild3ShortName, " ", current_holders.posMasterNo) + WHEN current_holders.orgChild2Id IS NOT NULL THEN CONCAT(orgChild2.orgChild2ShortName, " ", current_holders.posMasterNo) + WHEN current_holders.orgChild1Id IS NOT NULL THEN CONCAT(orgChild1.orgChild1ShortName, " ", current_holders.posMasterNo) + ELSE CONCAT(orgRoot.orgRootShortName, " ", current_holders.posMasterNo) END LIKE :keyword `; } @@ -7192,7 +7190,7 @@ export class ProfileController extends Controller { .filter(Boolean) .join("\n"); - const numPart = holder ? [holder.posMasterNoPrefix, holder.posMasterNo, holder.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; + const numPart = holder ? `${holder.posMasterNoPrefix ?? ''}${holder.posMasterNo ?? ''}${holder.posMasterNoSuffix ?? ''}` : ''; const shortName = !holder ? null @@ -7951,38 +7949,40 @@ export class ProfileController extends Controller { privacyUser: profile.privacyUser, privacyMgt: profile.privacyMgt, isDeputy: root?.isDeputy ?? false, + // root?.orgRootShortName && posMaster?.posMasterNo + // ? `${root?.orgRootShortName} ${posMaster?.posMasterNo}` + // : "", }; - const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; if (_profile.child4Id != null) { _profile.node = 4; _profile.nodeId = _profile.child4Id; _profile.nodeDnaId = _profile.child4DnaId; _profile.nodeShortName = _profile.child4ShortName; - _profile.posNo = `${_profile.child4ShortName} ${_numPart}`; + _profile.posNo = `${_profile.child4ShortName} ${_profile.posMasterNo}`; } else if (_profile.child3Id != null) { _profile.node = 3; _profile.nodeId = _profile.child3Id; _profile.nodeDnaId = _profile.child3DnaId; _profile.nodeShortName = _profile.child3ShortName; - _profile.posNo = `${_profile.child3ShortName} ${_numPart}`; + _profile.posNo = `${_profile.child3ShortName} ${_profile.posMasterNo}`; } else if (_profile.child2Id != null) { _profile.node = 2; _profile.nodeId = _profile.child2Id; _profile.nodeDnaId = _profile.child2DnaId; _profile.nodeShortName = _profile.child2ShortName; - _profile.posNo = `${_profile.child2ShortName} ${_numPart}`; + _profile.posNo = `${_profile.child2ShortName} ${_profile.posMasterNo}`; } else if (_profile.child1Id != null) { _profile.node = 1; _profile.nodeId = _profile.child1Id; _profile.nodeDnaId = _profile.child1DnaId; _profile.nodeShortName = _profile.child1ShortName; - _profile.posNo = `${_profile.child1ShortName} ${_numPart}`; + _profile.posNo = `${_profile.child1ShortName} ${_profile.posMasterNo}`; } else if (_profile.rootId != null) { _profile.node = 0; _profile.nodeId = _profile.rootId; _profile.nodeDnaId = _profile.rootDnaId; _profile.nodeShortName = _profile.rootShortName; - _profile.posNo = `${_profile.rootShortName} ${_numPart}`; + _profile.posNo = `${_profile.rootShortName} ${_profile.posMasterNo}`; } return new HttpSuccess(_profile); } @@ -8122,39 +8122,41 @@ export class ProfileController extends Controller { privacyUser: profile.privacyUser, privacyMgt: profile.privacyMgt, isDeputy: root?.isDeputy ?? false, + // root?.orgRootShortName && posMaster?.posMasterNo + // ? `${root?.orgRootShortName} ${posMaster?.posMasterNo}` + // : "", }; - const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; if (_profile.child4Id != null) { _profile.node = 4; _profile.nodeId = _profile.child4Id; _profile.nodeDnaId = _profile.child4DnaId; _profile.nodeShortName = _profile.child4ShortName; - _profile.posNo = `${_profile.child4ShortName} ${_numPart}`; + _profile.posNo = `${_profile.child4ShortName} ${posMaster?.posMasterNo}`; } else if (_profile.child3Id != null) { _profile.node = 3; _profile.nodeId = _profile.child3Id; _profile.nodeDnaId = _profile.child3DnaId; _profile.nodeShortName = _profile.child3ShortName; - _profile.posNo = `${_profile.child3ShortName} ${_numPart}`; + _profile.posNo = `${_profile.child3ShortName} ${posMaster?.posMasterNo}`; } else if (_profile.child2Id != null) { _profile.node = 2; _profile.nodeId = _profile.child2Id; _profile.nodeDnaId = _profile.child2DnaId; _profile.nodeShortName = _profile.child2ShortName; - _profile.posNo = `${_profile.child2ShortName} ${_numPart}`; + _profile.posNo = `${_profile.child2ShortName} ${posMaster?.posMasterNo}`; } else if (_profile.child1Id != null) { _profile.node = 1; _profile.nodeId = _profile.child1Id; _profile.nodeDnaId = _profile.child1DnaId; _profile.nodeShortName = _profile.child1ShortName; - _profile.posNo = `${_profile.child1ShortName} ${_numPart}`; + _profile.posNo = `${_profile.child1ShortName} ${posMaster?.posMasterNo}`; } else if (_profile.rootId != null) { _profile.node = 0; _profile.nodeId = _profile.rootId; _profile.nodeDnaId = _profile.rootDnaId; _profile.nodeShortName = _profile.rootShortName; - _profile.posNo = `${_profile.rootShortName} ${_numPart}`; + _profile.posNo = `${_profile.rootShortName} ${posMaster?.posMasterNo}`; } return new HttpSuccess(_profile); } @@ -8794,21 +8796,32 @@ export class ProfileController extends Controller { posMasterId: posMaster?.id, }, }); - const holder = profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id); - const numPart = holder ? [holder.posMasterNoPrefix, holder.posMasterNo, holder.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; const shortName = - holder == null + profile.current_holders.length == 0 ? null - : holder.orgChild4 != null - ? `${holder.orgChild4.orgChild4ShortName} ${numPart}` - : holder.orgChild3 != null - ? `${holder.orgChild3.orgChild3ShortName} ${numPart}` - : holder.orgChild2 != null - ? `${holder.orgChild2.orgChild2ShortName} ${numPart}` - : holder.orgChild1 != null - ? `${holder.orgChild1.orgChild1ShortName} ${numPart}` - : holder.orgRoot != null - ? `${holder.orgRoot.orgRootShortName} ${numPart}` + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != null && + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) + ?.orgChild4 != null + ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4.orgChild4ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}` + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != null && + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) + ?.orgChild3 != null + ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3.orgChild3ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}` + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != + null && + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) + ?.orgChild2 != null + ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2.orgChild2ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}` + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != + null && + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) + ?.orgChild1 != null + ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1.orgChild1ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}` + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != + null && + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) + ?.orgRoot != null + ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot.orgRootShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}` : null; // const posMasterActs = await this.posMasterActRepository.find({ // relations: [ @@ -9170,32 +9183,26 @@ export class ProfileController extends Controller { profile.avatar && profile.avatarName ? `${profile.avatar}/${profile.avatarName}` : null, }; - const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; if (_profile.child4Id != null) { _profile.node = 4; _profile.nodeId = _profile.child4Id; _profile.nodeShortName = _profile.child4ShortName; - _profile.posNo = `${_profile.child4ShortName} ${_numPart}`; } else if (_profile.child3Id != null) { _profile.node = 3; _profile.nodeId = _profile.child3Id; _profile.nodeShortName = _profile.child3ShortName; - _profile.posNo = `${_profile.child3ShortName} ${_numPart}`; } else if (_profile.child2Id != null) { _profile.node = 2; _profile.nodeId = _profile.child2Id; _profile.nodeShortName = _profile.child2ShortName; - _profile.posNo = `${_profile.child2ShortName} ${_numPart}`; } else if (_profile.child1Id != null) { _profile.node = 1; _profile.nodeId = _profile.child1Id; _profile.nodeShortName = _profile.child1ShortName; - _profile.posNo = `${_profile.child1ShortName} ${_numPart}`; } else if (_profile.rootId != null) { _profile.node = 0; _profile.nodeId = _profile.rootId; _profile.nodeShortName = _profile.rootShortName; - _profile.posNo = `${_profile.rootShortName} ${_numPart}`; } return new HttpSuccess(_profile); } @@ -9325,32 +9332,26 @@ export class ProfileController extends Controller { : "-", }; - const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; if (_profile.child4Id != null) { _profile.node = 4; _profile.nodeId = _profile.child4Id; _profile.nodeShortName = _profile.child4ShortName; - _profile.posNo = `${_profile.child4ShortName} ${_numPart}`; } else if (_profile.child3Id != null) { _profile.node = 3; _profile.nodeId = _profile.child3Id; _profile.nodeShortName = _profile.child3ShortName; - _profile.posNo = `${_profile.child3ShortName} ${_numPart}`; } else if (_profile.child2Id != null) { _profile.node = 2; _profile.nodeId = _profile.child2Id; _profile.nodeShortName = _profile.child2ShortName; - _profile.posNo = `${_profile.child2ShortName} ${_numPart}`; } else if (_profile.child1Id != null) { _profile.node = 1; _profile.nodeId = _profile.child1Id; _profile.nodeShortName = _profile.child1ShortName; - _profile.posNo = `${_profile.child1ShortName} ${_numPart}`; } else if (_profile.rootId != null) { _profile.node = 0; _profile.nodeId = _profile.rootId; _profile.nodeShortName = _profile.rootShortName; - _profile.posNo = `${_profile.rootShortName} ${_numPart}`; } return new HttpSuccess(_profile); } @@ -9531,28 +9532,38 @@ export class ProfileController extends Controller { const mapDataProfile = await Promise.all( findProfile.map(async (item: Profile) => { const fullName = `${item.prefix}${item.firstName} ${item.lastName}`; - const holder = item.current_holders?.find((x) => x.orgRevisionId == findRevision.id); - const _numPart = holder ? [holder.posMasterNoPrefix, holder.posMasterNo, holder.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; - const shortName = !holder - ? null - : holder.orgChild4 != null - ? `${holder.orgChild4.orgChild4ShortName} ${_numPart}` - : holder.orgChild3 != null - ? `${holder.orgChild3.orgChild3ShortName} ${_numPart}` - : holder.orgChild2 != null - ? `${holder.orgChild2.orgChild2ShortName} ${_numPart}` - : holder.orgChild1 != null - ? `${holder.orgChild1.orgChild1ShortName} ${_numPart}` - : holder.orgRoot != null - ? `${holder.orgRoot.orgRootShortName} ${_numPart}` - : null; + const shortName = + item.current_holders.length == 0 + ? null + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 != + null + ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4.orgChild4ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3 != + null + ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3.orgChild3ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgChild2 != null + ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2.orgChild2ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgChild1 != null + ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1.orgChild1ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != + null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgRoot != null + ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot.orgRootShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` + : null; const root = item.current_holders.length == 0 || - (holder != null && - holder?.orgRoot == null) + (item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null) ? null - : holder?.orgRoot; + : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot; const rootHolder = item.current_holders?.find( (x) => x.orgRevisionId == findRevision.id, diff --git a/src/controllers/ProfileEmployeeController.ts b/src/controllers/ProfileEmployeeController.ts index 59f9e91d..c0b36961 100644 --- a/src/controllers/ProfileEmployeeController.ts +++ b/src/controllers/ProfileEmployeeController.ts @@ -84,7 +84,6 @@ import { ProfileDuty } from "../entities/ProfileDuty"; import { CreatePosMasterHistoryEmployee, getTopDegrees } from "../services/PositionService"; import { ProfileLeaveService } from "../services/ProfileLeaveService"; import { CommandCode } from "../entities/CommandCode"; -import { updateHolderProfileHistory } from "../services/PositionService"; @Route("api/v1/org/profile-employee") @Tags("ProfileEmployee") @Security("bearerAuth") @@ -197,7 +196,7 @@ export class ProfileEmployeeController extends Controller { }, }); ImgUrl = response_.data.downloadUrl; - } catch { } + } catch {} } const province = await this.provinceRepository.findOneBy({ id: profile.registrationProvinceId, @@ -209,36 +208,36 @@ export class ProfileEmployeeController extends Controller { const root = profile.current_holders == null || - profile.current_holders.length == 0 || - profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null + profile.current_holders.length == 0 || + profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgRoot; const child1 = profile.current_holders == null || - profile.current_holders.length == 0 || - profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null + profile.current_holders.length == 0 || + profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild1; const child2 = profile.current_holders == null || - profile.current_holders.length == 0 || - profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null + profile.current_holders.length == 0 || + profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild2; const child3 = profile.current_holders == null || - profile.current_holders.length == 0 || - profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null + profile.current_holders.length == 0 || + profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild3; const child4 = profile.current_holders == null || - profile.current_holders.length == 0 || - profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null + profile.current_holders.length == 0 || + profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild4; @@ -287,38 +286,38 @@ export class ProfileEmployeeController extends Controller { const salarys = salary_raw.length > 1 ? salary_raw.slice(1).map((item) => ({ - date: item.commandDateAffect - ? Extension.ToThaiNumber(Extension.ToThaiShortDate(item.commandDateAffect)) - : null, - position: Extension.ToThaiNumber( - Extension.ToThaiNumber( - `${item.positionName != null ? item.positionName : "-"} ${item.positionType == null ? item.positionCee ?? "" : (item.positionType == "อำนวยการ" || item.positionType == "บริหาร" ? item.positionType : "") + item.positionLevel}`, + date: item.commandDateAffect + ? Extension.ToThaiNumber(Extension.ToThaiShortDate(item.commandDateAffect)) + : null, + position: Extension.ToThaiNumber( + Extension.ToThaiNumber( + `${item.positionName != null ? item.positionName : "-"} ${item.positionType == null ? item.positionCee ?? "" : (item.positionType == "อำนวยการ" || item.positionType == "บริหาร" ? item.positionType : "") + item.positionLevel}`, + ), ), - ), - posNo: item.posNo != null ? Extension.ToThaiNumber(item.posNo) : "", - orgRoot: item.orgRoot != null ? Extension.ToThaiNumber(item.orgRoot) : "", - orgChild1: item.orgChild1 != null ? Extension.ToThaiNumber(item.orgChild1) : "", - orgChild2: item.orgChild2 != null ? Extension.ToThaiNumber(item.orgChild2) : "", - orgChild3: item.orgChild3 != null ? Extension.ToThaiNumber(item.orgChild3) : "", - orgChild4: item.orgChild4 != null ? Extension.ToThaiNumber(item.orgChild4) : "", - positionCee: item.positionCee != null ? Extension.ToThaiNumber(item.positionCee) : "", - positionExecutive: - item.positionExecutive != null ? Extension.ToThaiNumber(item.positionExecutive) : "", - })) + posNo: item.posNo != null ? Extension.ToThaiNumber(item.posNo) : "", + orgRoot: item.orgRoot != null ? Extension.ToThaiNumber(item.orgRoot) : "", + orgChild1: item.orgChild1 != null ? Extension.ToThaiNumber(item.orgChild1) : "", + orgChild2: item.orgChild2 != null ? Extension.ToThaiNumber(item.orgChild2) : "", + orgChild3: item.orgChild3 != null ? Extension.ToThaiNumber(item.orgChild3) : "", + orgChild4: item.orgChild4 != null ? Extension.ToThaiNumber(item.orgChild4) : "", + positionCee: item.positionCee != null ? Extension.ToThaiNumber(item.positionCee) : "", + positionExecutive: + item.positionExecutive != null ? Extension.ToThaiNumber(item.positionExecutive) : "", + })) : [ - { - date: "-", - position: "-", - posNo: "-", - orgRoot: null, - orgChild1: null, - orgChild2: null, - orgChild3: null, - orgChild4: null, - positionCee: null, - positionExecutive: null, - }, - ]; + { + date: "-", + position: "-", + posNo: "-", + orgRoot: null, + orgChild1: null, + orgChild2: null, + orgChild3: null, + orgChild4: null, + positionCee: null, + positionExecutive: null, + }, + ]; const educations = await this.profileEducationRepo.find({ select: [ @@ -336,20 +335,20 @@ export class ProfileEmployeeController extends Controller { const Education = educations && educations.length > 0 ? educations.map((item) => ({ - institute: item.institute ? item.institute : "-", - date: - item.startDate && item.endDate - ? `${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.startDate))} - ${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.endDate))}` - : "-", - degree: item.degree && item.field ? `${item.degree} ${item.field}` : "-", - })) + institute: item.institute ? item.institute : "-", + date: + item.startDate && item.endDate + ? `${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.startDate))} - ${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.endDate))}` + : "-", + degree: item.degree && item.field ? `${item.degree} ${item.field}` : "-", + })) : [ - { - institute: "-", - date: "-", - degree: "-", - }, - ]; + { + institute: "-", + date: "-", + degree: "-", + }, + ]; const mapData = { // Id: profile.id, @@ -387,10 +386,10 @@ export class ProfileEmployeeController extends Controller { position: salary_raw.length > 0 && salary_raw[0].positionName != null ? Extension.ToThaiNumber( - Extension.ToThaiNumber( - `${salary_raw[0].positionName != null ? salary_raw[0].positionName : "-"} ${salary_raw[0].positionType == null ? salary_raw[0].positionCee ?? "" : (salary_raw[0].positionType == "อำนวยการ" || salary_raw[0].positionType == "บริหาร" ? salary_raw[0].positionType : "") + salary_raw[0].positionLevel}`, - ), - ) + Extension.ToThaiNumber( + `${salary_raw[0].positionName != null ? salary_raw[0].positionName : "-"} ${salary_raw[0].positionType == null ? salary_raw[0].positionCee ?? "" : (salary_raw[0].positionType == "อำนวยการ" || salary_raw[0].positionType == "บริหาร" ? salary_raw[0].positionType : "") + salary_raw[0].positionLevel}`, + ), + ) : "", positionCee: salary_raw.length > 0 && salary_raw[0].positionCee != null @@ -400,22 +399,27 @@ export class ProfileEmployeeController extends Controller { salary_raw.length > 0 && salary_raw[0].positionExecutive != null ? Extension.ToThaiNumber(Extension.ToThaiNumber(salary_raw[0].positionExecutive)) : "", - org: `${salary_raw.length > 0 && salary_raw[0].orgChild4 && salary_raw[0].orgChild4 != "-" + org: `${ + salary_raw.length > 0 && salary_raw[0].orgChild4 && salary_raw[0].orgChild4 != "-" ? Extension.ToThaiNumber(Extension.ToThaiNumber(salary_raw[0].orgChild4)) + " " : "" - }${salary_raw.length > 0 && salary_raw[0].orgChild3 && salary_raw[0].orgChild3 != "-" + }${ + salary_raw.length > 0 && salary_raw[0].orgChild3 && salary_raw[0].orgChild3 != "-" ? Extension.ToThaiNumber(Extension.ToThaiNumber(salary_raw[0].orgChild3)) + " " : "" - }${salary_raw.length > 0 && salary_raw[0].orgChild2 && salary_raw[0].orgChild2 != "-" + }${ + salary_raw.length > 0 && salary_raw[0].orgChild2 && salary_raw[0].orgChild2 != "-" ? Extension.ToThaiNumber(Extension.ToThaiNumber(salary_raw[0].orgChild2)) + " " : "" - }${salary_raw.length > 0 && salary_raw[0].orgChild1 && salary_raw[0].orgChild1 != "-" + }${ + salary_raw.length > 0 && salary_raw[0].orgChild1 && salary_raw[0].orgChild1 != "-" ? Extension.ToThaiNumber(Extension.ToThaiNumber(salary_raw[0].orgChild1)) + " " : "" - }${salary_raw.length > 0 && salary_raw[0].orgRoot && salary_raw[0].orgRoot != "-" + }${ + salary_raw.length > 0 && salary_raw[0].orgRoot && salary_raw[0].orgRoot != "-" ? Extension.ToThaiNumber(Extension.ToThaiNumber(salary_raw[0].orgRoot)) : "" - }`, + }`, ocFullPath: (_child4 == null ? "" : _child4 + "\n") + (_child3 == null ? "" : _child3 + "\n") + @@ -484,7 +488,7 @@ export class ProfileEmployeeController extends Controller { }, }); _ImgUrl[i] = response_.data.downloadUrl; - } catch { } + } catch {} } }), ); @@ -498,7 +502,7 @@ export class ProfileEmployeeController extends Controller { }, }); ImgUrl = response_.data.downloadUrl; - } catch { } + } catch {} } const profileOc = await this.profileRepo.findOne({ relations: [ @@ -537,36 +541,36 @@ export class ProfileEmployeeController extends Controller { const root = profileOc.current_holders == null || - profileOc.current_holders.length == 0 || - profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null + profileOc.current_holders.length == 0 || + profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null ? null : profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgRoot; const child1 = profileOc.current_holders == null || - profileOc.current_holders.length == 0 || - profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null + profileOc.current_holders.length == 0 || + profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null ? null : profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild1; const child2 = profileOc.current_holders == null || - profileOc.current_holders.length == 0 || - profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null + profileOc.current_holders.length == 0 || + profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null ? null : profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild2; const child3 = profileOc.current_holders == null || - profileOc.current_holders.length == 0 || - profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null + profileOc.current_holders.length == 0 || + profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null ? null : profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild3; const child4 = profileOc.current_holders == null || - profileOc.current_holders.length == 0 || - profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null + profileOc.current_holders.length == 0 || + profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null ? null : profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild4; @@ -585,19 +589,19 @@ export class ProfileEmployeeController extends Controller { const certs = cert_raw.length > 0 ? cert_raw.slice(-2).map((item) => ({ - CertificateType: item.certificateType ?? null, - Issuer: item.issuer ?? null, - CertificateNo: Extension.ToThaiNumber(item.certificateNo) ?? null, - IssueDate: Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.issueDate)) ?? null, - })) + CertificateType: item.certificateType ?? null, + Issuer: item.issuer ?? null, + CertificateNo: Extension.ToThaiNumber(item.certificateNo) ?? null, + IssueDate: Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.issueDate)) ?? null, + })) : [ - { - CertificateType: "-", - Issuer: "-", - CertificateNo: "-", - IssueDate: "-", - }, - ]; + { + CertificateType: "-", + Issuer: "-", + CertificateNo: "-", + IssueDate: "-", + }, + ]; const training_raw = await this.trainingRepository.find({ select: ["startDate", "endDate", "place", "department", "isDeleted"], where: { profileEmployeeId: id, isDeleted: false }, @@ -606,34 +610,34 @@ export class ProfileEmployeeController extends Controller { const trainings = training_raw.length > 0 ? training_raw.slice(-2).map((item) => ({ - Institute: item.department ?? "", - Start: - item.startDate == null - ? "" - : Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.startDate)), - End: - item.endDate == null - ? "" - : Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.endDate)), - Date: - item.startDate && item.endDate - ? `${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.startDate))} - ${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.endDate))}` - : "", - Level: "", - Degree: item.name, - Field: "", - })) + Institute: item.department ?? "", + Start: + item.startDate == null + ? "" + : Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.startDate)), + End: + item.endDate == null + ? "" + : Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.endDate)), + Date: + item.startDate && item.endDate + ? `${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.startDate))} - ${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.endDate))}` + : "", + Level: "", + Degree: item.name, + Field: "", + })) : [ - { - Institute: "-", - Start: "-", - End: "-", - Date: "-", - Level: "-", - Degree: "-", - Field: "-", - }, - ]; + { + Institute: "-", + Start: "-", + End: "-", + Date: "-", + Level: "-", + Degree: "-", + Field: "-", + }, + ]; const discipline_raw = await this.disciplineRepository.find({ select: ["refCommandDate", "refCommandNo", "detail", "isDeleted"], @@ -643,19 +647,19 @@ export class ProfileEmployeeController extends Controller { const disciplines = discipline_raw.length > 0 ? discipline_raw.slice(-2).map((item) => ({ - DisciplineYear: - Extension.ToThaiNumber(new Date(item.refCommandDate).getFullYear().toString()) ?? - null, - DisciplineDetail: item.detail ?? null, - RefNo: item.refCommandNo ? Extension.ToThaiNumber(item.refCommandNo) : null, - })) + DisciplineYear: + Extension.ToThaiNumber(new Date(item.refCommandDate).getFullYear().toString()) ?? + null, + DisciplineDetail: item.detail ?? null, + RefNo: item.refCommandNo ? Extension.ToThaiNumber(item.refCommandNo) : null, + })) : [ - { - DisciplineYear: "-", - DisciplineDetail: "-", - RefNo: "-", - }, - ]; + { + DisciplineYear: "-", + DisciplineDetail: "-", + RefNo: "-", + }, + ]; const education_raw = await this.profileEducationRepo.find({ select: [ @@ -674,34 +678,34 @@ export class ProfileEmployeeController extends Controller { const educations = education_raw.length > 0 ? education_raw.slice(-2).map((item) => ({ - Institute: item.institute, - Start: - item.startDate == null - ? "" - : Extension.ToThaiNumber(new Date(item.startDate).getFullYear().toString()), - End: - item.endDate == null - ? "" - : Extension.ToThaiNumber(new Date(item.endDate).getFullYear().toString()), - Date: - item.startDate && item.endDate - ? `${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.startDate))} - ${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.endDate))}` - : "", - Level: item.educationLevel ?? "", - Degree: item.degree ? `${item.degree} ${item.field ? item.field : ""}` : "", - Field: item.field ?? "-", - })) + Institute: item.institute, + Start: + item.startDate == null + ? "" + : Extension.ToThaiNumber(new Date(item.startDate).getFullYear().toString()), + End: + item.endDate == null + ? "" + : Extension.ToThaiNumber(new Date(item.endDate).getFullYear().toString()), + Date: + item.startDate && item.endDate + ? `${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.startDate))} - ${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.endDate))}` + : "", + Level: item.educationLevel ?? "", + Degree: item.degree ? `${item.degree} ${item.field ? item.field : ""}` : "", + Field: item.field ?? "-", + })) : [ - { - Institute: "-", - Start: "-", - End: "-", - Date: "-", - Level: "-", - Degree: "-", - Field: "-", - }, - ]; + { + Institute: "-", + Start: "-", + End: "-", + Date: "-", + Level: "-", + Degree: "-", + Field: "-", + }, + ]; const salary_raw = await this.salaryRepo.find({ select: [ "commandDateAffect", @@ -721,45 +725,45 @@ export class ProfileEmployeeController extends Controller { const salarys = salary_raw.length > 0 ? salary_raw.map((item) => ({ - SalaryDate: item.commandDateAffect - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateAffect)) - : null, - Position: item.positionName != null ? Extension.ToThaiNumber(item.positionName) : null, - PosNo: item.posNo != null ? Extension.ToThaiNumber(item.posNo) : null, - Salary: - item.amount != null ? Extension.ToThaiNumber(item.amount.toLocaleString()) : null, - Rank: item.positionLevel != null ? Extension.ToThaiNumber(item.positionLevel) : null, - RefAll: item.remark ? Extension.ToThaiNumber(item.remark) : null, - PositionLevel: - item.positionLevel != null ? Extension.ToThaiNumber(item.positionLevel) : null, - PositionType: item.positionType ?? null, - PositionAmount: - item.positionSalaryAmount == null - ? null - : Extension.ToThaiNumber(item.positionSalaryAmount.toLocaleString()), - FullName: `${profiles?.prefix}${profiles?.firstName} ${profiles?.lastName}`, - OcFullPath: - (_child4 == null ? "" : _child4 + "\n") + - (_child3 == null ? "" : _child3 + "\n") + - (_child2 == null ? "" : _child2 + "\n") + - (_child1 == null ? "" : _child1 + "\n") + - (_root == null ? "" : _root), - })) + SalaryDate: item.commandDateAffect + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateAffect)) + : null, + Position: item.positionName != null ? Extension.ToThaiNumber(item.positionName) : null, + PosNo: item.posNo != null ? Extension.ToThaiNumber(item.posNo) : null, + Salary: + item.amount != null ? Extension.ToThaiNumber(item.amount.toLocaleString()) : null, + Rank: item.positionLevel != null ? Extension.ToThaiNumber(item.positionLevel) : null, + RefAll: item.remark ? Extension.ToThaiNumber(item.remark) : null, + PositionLevel: + item.positionLevel != null ? Extension.ToThaiNumber(item.positionLevel) : null, + PositionType: item.positionType ?? null, + PositionAmount: + item.positionSalaryAmount == null + ? null + : Extension.ToThaiNumber(item.positionSalaryAmount.toLocaleString()), + FullName: `${profiles?.prefix}${profiles?.firstName} ${profiles?.lastName}`, + OcFullPath: + (_child4 == null ? "" : _child4 + "\n") + + (_child3 == null ? "" : _child3 + "\n") + + (_child2 == null ? "" : _child2 + "\n") + + (_child1 == null ? "" : _child1 + "\n") + + (_root == null ? "" : _root), + })) : [ - { - SalaryDate: "-", - Position: "-", - PosNo: "-", - Salary: "-", - Rank: "-", - RefAll: "-", - PositionLevel: "-", - PositionType: "-", - PositionAmount: "-", - FullName: "-", - OcFullPath: "-", - }, - ]; + { + SalaryDate: "-", + Position: "-", + PosNo: "-", + Salary: "-", + Rank: "-", + RefAll: "-", + PositionLevel: "-", + PositionType: "-", + PositionAmount: "-", + FullName: "-", + OcFullPath: "-", + }, + ]; const insignia_raw = await this.profileInsigniaRepo.find({ relations: { @@ -773,37 +777,37 @@ export class ProfileEmployeeController extends Controller { const insignias = insignia_raw.length > 0 ? insignia_raw.map((item) => ({ - ReceiveDate: item.receiveDate - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.receiveDate)) - : "", - InsigniaName: item.insignia.name, - InsigniaShortName: item.insignia.shortName, - InsigniaTypeName: item.insignia.insigniaType.name, - No: item.no ? Extension.ToThaiNumber(item.no) : "", - Issue: item.issue ? item.issue : "", - VolumeNo: item.volumeNo ? Extension.ToThaiNumber(item.volumeNo) : "", - Volume: item.volume ? Extension.ToThaiNumber(item.volume) : "", - Section: item.section ? Extension.ToThaiNumber(item.section) : "", - Page: item.page ? Extension.ToThaiNumber(item.page) : "", - RefCommandDate: item.refCommandDate - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.refCommandDate)) - : "", - })) + ReceiveDate: item.receiveDate + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.receiveDate)) + : "", + InsigniaName: item.insignia.name, + InsigniaShortName: item.insignia.shortName, + InsigniaTypeName: item.insignia.insigniaType.name, + No: item.no ? Extension.ToThaiNumber(item.no) : "", + Issue: item.issue ? item.issue : "", + VolumeNo: item.volumeNo ? Extension.ToThaiNumber(item.volumeNo) : "", + Volume: item.volume ? Extension.ToThaiNumber(item.volume) : "", + Section: item.section ? Extension.ToThaiNumber(item.section) : "", + Page: item.page ? Extension.ToThaiNumber(item.page) : "", + RefCommandDate: item.refCommandDate + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.refCommandDate)) + : "", + })) : [ - { - ReceiveDate: "-", - InsigniaName: "-", - InsigniaShortName: "-", - InsigniaTypeName: "-", - No: "-", - Issue: "-", - VolumeNo: "-", - Volume: "-", - Section: "-", - Page: "-", - RefCommandDate: "-", - }, - ]; + { + ReceiveDate: "-", + InsigniaName: "-", + InsigniaShortName: "-", + InsigniaTypeName: "-", + No: "-", + Issue: "-", + VolumeNo: "-", + Volume: "-", + Section: "-", + Page: "-", + RefCommandDate: "-", + }, + ]; const leave_raw = await this.profileLeaveRepository .createQueryBuilder("profileLeave") @@ -893,20 +897,20 @@ export class ProfileEmployeeController extends Controller { profiles.citizenId != null ? Extension.ToThaiNumber(profiles.citizenId.toString()) : "", fatherFullName: profileFamilyFather?.fatherPrefix || - profileFamilyFather?.fatherFirstName || - profileFamilyFather?.fatherLastName + profileFamilyFather?.fatherFirstName || + profileFamilyFather?.fatherLastName ? `${profileFamilyFather?.fatherPrefix ?? ""}${profileFamilyFather?.fatherFirstName ?? ""} ${profileFamilyFather?.fatherLastName ?? ""}`.trim() : null, motherFullName: profileFamilyMother?.motherPrefix || - profileFamilyMother?.motherFirstName || - profileFamilyMother?.motherLastName + profileFamilyMother?.motherFirstName || + profileFamilyMother?.motherLastName ? `${profileFamilyMother?.motherPrefix ?? ""}${profileFamilyMother?.motherFirstName ?? ""} ${profileFamilyMother?.motherLastName ?? ""}`.trim() : null, coupleFullName: profileFamilyCouple?.couplePrefix || - profileFamilyCouple?.coupleFirstName || - profileFamilyCouple?.coupleLastNameOld + profileFamilyCouple?.coupleFirstName || + profileFamilyCouple?.coupleLastNameOld ? `${profileFamilyCouple?.couplePrefix ?? ""}${profileFamilyCouple?.coupleFirstName ?? ""} ${profileFamilyCouple?.coupleLastName ?? ""}`.trim() : null, coupleLastNameOld: profileFamilyCouple?.coupleLastNameOld ?? null, @@ -1024,7 +1028,7 @@ export class ProfileEmployeeController extends Controller { }, }); _ImgUrl[i] = response_.data.downloadUrl; - } catch { } + } catch {} } }), ); @@ -1038,7 +1042,7 @@ export class ProfileEmployeeController extends Controller { }, }); ImgUrl = response_.data.downloadUrl; - } catch { } + } catch {} } const orgRevision = await this.orgRevisionRepo.findOne({ @@ -1072,36 +1076,36 @@ export class ProfileEmployeeController extends Controller { const root = profiles.current_holders == null || - profiles.current_holders.length == 0 || - profiles.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null + profiles.current_holders.length == 0 || + profiles.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null ? null : profiles.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgRoot; const child1 = profiles.current_holders == null || - profiles.current_holders.length == 0 || - profiles.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null + profiles.current_holders.length == 0 || + profiles.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null ? null : profiles.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild1; const child2 = profiles.current_holders == null || - profiles.current_holders.length == 0 || - profiles.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null + profiles.current_holders.length == 0 || + profiles.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null ? null : profiles.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild2; const child3 = profiles.current_holders == null || - profiles.current_holders.length == 0 || - profiles.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null + profiles.current_holders.length == 0 || + profiles.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null ? null : profiles.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild3; const child4 = profiles.current_holders == null || - profiles.current_holders.length == 0 || - profiles.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null + profiles.current_holders.length == 0 || + profiles.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null ? null : profiles.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild4; @@ -1127,31 +1131,31 @@ export class ProfileEmployeeController extends Controller { const certs = cert_raw.length > 0 ? cert_raw.map((item) => ({ - certificateType: item.certificateType ?? null, - issuer: item.issuer ?? null, - certificateNo: item.certificateNo ? Extension.ToThaiNumber(item.certificateNo) : null, - detail: Extension.ToThaiNumber( - `${item.issuer ?? ""} ${item.certificateNo ?? ""}`.trim(), - ), - issueToExpireDate: item.issueDate - ? item.expireDate - ? Extension.ToThaiNumber( - `${Extension.ToThaiFullDate2(item.issueDate)} - ${Extension.ToThaiFullDate2(item.expireDate)}`, - ) - : Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.issueDate)) - : item.expireDate - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.expireDate)) - : "", - })) + certificateType: item.certificateType ?? null, + issuer: item.issuer ?? null, + certificateNo: item.certificateNo ? Extension.ToThaiNumber(item.certificateNo) : null, + detail: Extension.ToThaiNumber( + `${item.issuer ?? ""} ${item.certificateNo ?? ""}`.trim(), + ), + issueToExpireDate: item.issueDate + ? item.expireDate + ? Extension.ToThaiNumber( + `${Extension.ToThaiFullDate2(item.issueDate)} - ${Extension.ToThaiFullDate2(item.expireDate)}`, + ) + : Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.issueDate)) + : item.expireDate + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.expireDate)) + : "", + })) : [ - { - certificateType: "", - issuer: "", - certificateNo: "", - detail: "", - issueToExpireDate: "", - }, - ]; + { + certificateType: "", + issuer: "", + certificateNo: "", + detail: "", + issueToExpireDate: "", + }, + ]; const training_raw = await this.trainingRepository.find({ select: ["place", "department", "name", "duration", "isDeleted", "startDate", "endDate"], where: { profileEmployeeId: id, isDeleted: false }, @@ -1160,23 +1164,23 @@ export class ProfileEmployeeController extends Controller { const trainings = training_raw.length > 0 ? training_raw.map((item) => ({ - institute: item.department ?? "", - degree: item.name ? Extension.ToThaiNumber(item.name) : "", - place: item.place ? Extension.ToThaiNumber(item.place) : "", - duration: item.duration ? Extension.ToThaiNumber(item.duration) : "", - date: Extension.ToThaiNumber( - `${Extension.ToThaiFullDate2(item.startDate)} - ${Extension.ToThaiFullDate2(item.endDate)}`, - ), - })) + institute: item.department ?? "", + degree: item.name ? Extension.ToThaiNumber(item.name) : "", + place: item.place ? Extension.ToThaiNumber(item.place) : "", + duration: item.duration ? Extension.ToThaiNumber(item.duration) : "", + date: Extension.ToThaiNumber( + `${Extension.ToThaiFullDate2(item.startDate)} - ${Extension.ToThaiFullDate2(item.endDate)}`, + ), + })) : [ - { - institute: "", - degree: "", - place: "", - duration: "", - date: "", - }, - ]; + { + institute: "", + degree: "", + place: "", + duration: "", + date: "", + }, + ]; const discipline_raw = await this.disciplineRepository.find({ select: ["refCommandDate", "refCommandNo", "detail", "level", "isDeleted"], @@ -1186,21 +1190,21 @@ export class ProfileEmployeeController extends Controller { const disciplines = discipline_raw.length > 0 ? discipline_raw.map((item) => ({ - disciplineYear: item.refCommandDate - ? Extension.ToThaiNumber(Extension.ToThaiShortYear(new Date(item.refCommandDate))) - : null, - disciplineDetail: item.detail ?? null, - refNo: Extension.ToThaiNumber(item.refCommandNo) ?? null, - level: item.level ?? "", - })) + disciplineYear: item.refCommandDate + ? Extension.ToThaiNumber(Extension.ToThaiShortYear(new Date(item.refCommandDate))) + : null, + disciplineDetail: item.detail ?? null, + refNo: Extension.ToThaiNumber(item.refCommandNo) ?? null, + level: item.level ?? "", + })) : [ - { - disciplineYear: "", - disciplineDetail: "", - refNo: "", - level: "", - }, - ]; + { + disciplineYear: "", + disciplineDetail: "", + refNo: "", + level: "", + }, + ]; const education_raw = await this.profileEducationRepo .createQueryBuilder("education") @@ -1212,21 +1216,21 @@ export class ProfileEmployeeController extends Controller { const educations = education_raw.length > 0 ? education_raw.map((item) => ({ - institute: item.institute, - date: item.isDate - ? `${item.startDate ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.startDate)) : ""} - ${item.endDate ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.endDate)) : ""}` - : `${item.startDate ? Extension.ToThaiNumber(Extension.ToThaiShortYear(new Date(item.startDate))) : ""} - ${item.endDate ? Extension.ToThaiNumber(Extension.ToThaiShortYear(new Date(item.endDate))) : ""}`, - degree: `${item.degree ?? ""} ${item.field ?? ""}`.trim(), - level: item.educationLevel, - })) + institute: item.institute, + date: item.isDate + ? `${item.startDate ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.startDate)) : ""} - ${item.endDate ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.endDate)) : ""}` + : `${item.startDate ? Extension.ToThaiNumber(Extension.ToThaiShortYear(new Date(item.startDate))) : ""} - ${item.endDate ? Extension.ToThaiNumber(Extension.ToThaiShortYear(new Date(item.endDate))) : ""}`, + degree: `${item.degree ?? ""} ${item.field ?? ""}`.trim(), + level: item.educationLevel, + })) : [ - { - institute: "", - date: "", - degree: "", - level: "", - }, - ]; + { + institute: "", + date: "", + degree: "", + level: "", + }, + ]; const salary_raw = await this.salaryRepo.find({ select: [ "commandName", @@ -1254,58 +1258,58 @@ export class ProfileEmployeeController extends Controller { const salarys = salary_raw.length > 0 ? salary_raw.map((item) => ({ - commandName: item.commandName ?? "", - salaryDate: item.commandDateAffect - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateAffect)) - : null, - position: item.positionName != null ? Extension.ToThaiNumber(item.positionName) : null, - posNo: - item.posNoAbb && item.posNo - ? Extension.ToThaiNumber(`${item.posNoAbb}${item.posNo}`) + commandName: item.commandName ?? "", + salaryDate: item.commandDateAffect + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateAffect)) : null, - salary: - item.amount != null ? Extension.ToThaiNumber(item.amount.toLocaleString()) : null, - special: - item.amountSpecial != null - ? Extension.ToThaiNumber(item.amountSpecial.toLocaleString()) - : null, - rank: item.positionLevel != null ? Extension.ToThaiNumber(item.positionLevel) : null, - refAll: item.remark ? Extension.ToThaiNumber(item.remark) : null, - positionLevel: item.positionLevel - ? Extension.ToThaiNumber(item.positionLevel) - : item.positionCee - ? Extension.ToThaiNumber(item.positionCee) - : null, - positionType: item.positionType ?? null, - positionAmount: - item.positionSalaryAmount == null - ? null - : Extension.ToThaiNumber(item.positionSalaryAmount.toLocaleString()), - fullName: `${profiles?.prefix}${profiles?.firstName} ${profiles?.lastName}`, - ocFullPath: - (_child4 == null ? "" : _child4 + "\n") + - (_child3 == null ? "" : _child3 + "\n") + - (_child2 == null ? "" : _child2 + "\n") + - (_child1 == null ? "" : _child1 + "\n") + - (_root == null ? "" : _root), - })) + position: item.positionName != null ? Extension.ToThaiNumber(item.positionName) : null, + posNo: + item.posNoAbb && item.posNo + ? Extension.ToThaiNumber(`${item.posNoAbb}${item.posNo}`) + : null, + salary: + item.amount != null ? Extension.ToThaiNumber(item.amount.toLocaleString()) : null, + special: + item.amountSpecial != null + ? Extension.ToThaiNumber(item.amountSpecial.toLocaleString()) + : null, + rank: item.positionLevel != null ? Extension.ToThaiNumber(item.positionLevel) : null, + refAll: item.remark ? Extension.ToThaiNumber(item.remark) : null, + positionLevel: item.positionLevel + ? Extension.ToThaiNumber(item.positionLevel) + : item.positionCee + ? Extension.ToThaiNumber(item.positionCee) + : null, + positionType: item.positionType ?? null, + positionAmount: + item.positionSalaryAmount == null + ? null + : Extension.ToThaiNumber(item.positionSalaryAmount.toLocaleString()), + fullName: `${profiles?.prefix}${profiles?.firstName} ${profiles?.lastName}`, + ocFullPath: + (_child4 == null ? "" : _child4 + "\n") + + (_child3 == null ? "" : _child3 + "\n") + + (_child2 == null ? "" : _child2 + "\n") + + (_child1 == null ? "" : _child1 + "\n") + + (_root == null ? "" : _root), + })) : [ - { - commandName: "", - salaryDate: "", - position: "", - posNo: "", - salary: "", - special: "", - rank: "", - refAll: "", - positionLevel: "", - positionType: "", - positionAmount: "", - fullName: "", - ocFullPath: "", - }, - ]; + { + commandName: "", + salaryDate: "", + position: "", + posNo: "", + salary: "", + special: "", + rank: "", + refAll: "", + positionLevel: "", + positionType: "", + positionAmount: "", + fullName: "", + ocFullPath: "", + }, + ]; const insignia_raw = await this.profileInsigniaRepo.find({ select: [ @@ -1331,38 +1335,38 @@ export class ProfileEmployeeController extends Controller { const insignias = insignia_raw.length > 0 ? insignia_raw.map((item) => ({ - receiveDate: item.receiveDate - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.receiveDate)) - : "", - insigniaName: item.insignia?.name ?? "", - insigniaShortName: item.insignia?.shortName ?? "", - insigniaTypeName: item.insignia?.insigniaType?.name ?? "", - no: item.no ? Extension.ToThaiNumber(item.no) : "", - issue: item.issue ? Extension.ToThaiNumber(item.issue) : "", - volumeNo: item.volumeNo ? Extension.ToThaiNumber(item.volumeNo) : "", - volume: item.volume ? Extension.ToThaiNumber(item.volume) : "", - section: item.section ? Extension.ToThaiNumber(item.section) : "", - page: item.page ? Extension.ToThaiNumber(item.page) : "", - refCommandDate: item.refCommandDate - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.refCommandDate)) - : "", - note: item.note ? Extension.ToThaiNumber(item.note) : "", - })) + receiveDate: item.receiveDate + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.receiveDate)) + : "", + insigniaName: item.insignia?.name ?? "", + insigniaShortName: item.insignia?.shortName ?? "", + insigniaTypeName: item.insignia?.insigniaType?.name ?? "", + no: item.no ? Extension.ToThaiNumber(item.no) : "", + issue: item.issue ? Extension.ToThaiNumber(item.issue) : "", + volumeNo: item.volumeNo ? Extension.ToThaiNumber(item.volumeNo) : "", + volume: item.volume ? Extension.ToThaiNumber(item.volume) : "", + section: item.section ? Extension.ToThaiNumber(item.section) : "", + page: item.page ? Extension.ToThaiNumber(item.page) : "", + refCommandDate: item.refCommandDate + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.refCommandDate)) + : "", + note: item.note ? Extension.ToThaiNumber(item.note) : "", + })) : [ - { - receiveDate: "", - insigniaName: "", - insigniaShortName: "", - insigniaTypeName: "", - no: "", - issue: "", - volumeNo: "", - volume: "", - section: "", - page: "", - refCommandDate: "", - }, - ]; + { + receiveDate: "", + insigniaName: "", + insigniaShortName: "", + insigniaTypeName: "", + no: "", + issue: "", + volumeNo: "", + volume: "", + section: "", + page: "", + refCommandDate: "", + }, + ]; const leave_raw = await this.profileLeaveRepository .createQueryBuilder("profileLeave") @@ -1500,62 +1504,62 @@ export class ProfileEmployeeController extends Controller { const leaves2 = leave2_raw.length > 0 ? leave2_raw.map((item) => { - const leaveTypeCode = item.code ? item.code.trim().toUpperCase() : ""; + const leaveTypeCode = item.code ? item.code.trim().toUpperCase() : ""; - // ข้อที่ 1: LV-008 ให้ใช้ leaveSubTypeName (ประเภทย่อย) แทน name - const displayType = - leaveTypeCode === "LV-008" && item.leaveSubTypeName - ? item.leaveSubTypeName - : item.name || "-"; + // ข้อที่ 1: LV-008 ให้ใช้ leaveSubTypeName (ประเภทย่อย) แทน name + const displayType = + leaveTypeCode === "LV-008" && item.leaveSubTypeName + ? item.leaveSubTypeName + : item.name || "-"; - // ข้อที่ 2: แสดง reason ก่อนเสมอ ถ้ามี coupleDayLevelCountry ค่อยแสดงประเทศ - const displayReason = item.coupleDayLevelCountry - ? `${item.reason || ""} ลาไปประเทศ ${item.coupleDayLevelCountry}`.trim() - : item.reason || "-"; + // ข้อที่ 2: แสดง reason ก่อนเสมอ ถ้ามี coupleDayLevelCountry ค่อยแสดงประเทศ + const displayReason = item.coupleDayLevelCountry + ? `${item.reason || ""} ลาไปประเทศ ${item.coupleDayLevelCountry}`.trim() + : item.reason || "-"; - return { - date: - item.dateLeaveStart && item.dateLeaveEnd - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.dateLeaveStart)) + - " - " + - Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.dateLeaveEnd)) - : "-", - type: displayType, - leaveDays: item.leaveDays ? Extension.ToThaiNumber(item.leaveDays.toString()) : "-", - reason: displayReason, - }; - }) + return { + date: + item.dateLeaveStart && item.dateLeaveEnd + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.dateLeaveStart)) + + " - " + + Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.dateLeaveEnd)) + : "-", + type: displayType, + leaveDays: item.leaveDays ? Extension.ToThaiNumber(item.leaveDays.toString()) : "-", + reason: displayReason, + }; + }) : [ - { - date: "", - type: "", - leaveDays: "", - reason: "", - }, - ]; + { + date: "", + type: "", + leaveDays: "", + reason: "", + }, + ]; const children_raw = await this.profileChildrenRepository.find({ where: { profileEmployeeId: id, isDeleted: false }, }); const children = children_raw.length > 0 ? children_raw.map((item, index) => ({ - no: Extension.ToThaiNumber((index + 1).toString()), - childrenPrefix: item.childrenPrefix, - childrenFirstName: item.childrenFirstName, - childrenLastName: item.childrenLastName, - childrenFullName: `${item.childrenPrefix}${item.childrenFirstName} ${item.childrenLastName}`, - childrenLive: item.childrenLive == false ? "ถึงแก่กรรม" : "มีชีวิต", - })) + no: Extension.ToThaiNumber((index + 1).toString()), + childrenPrefix: item.childrenPrefix, + childrenFirstName: item.childrenFirstName, + childrenLastName: item.childrenLastName, + childrenFullName: `${item.childrenPrefix}${item.childrenFirstName} ${item.childrenLastName}`, + childrenLive: item.childrenLive == false ? "ถึงแก่กรรม" : "มีชีวิต", + })) : [ - { - no: "", - childrenPrefix: "", - childrenFirstName: "", - childrenLastName: "", - childrenFullName: "", - childrenLive: "", - }, - ]; + { + no: "", + childrenPrefix: "", + childrenFirstName: "", + childrenLastName: "", + childrenFullName: "", + childrenLive: "", + }, + ]; const changeName_raw = await this.changeNameRepository.find({ where: { profileEmployeeId: id, isDeleted: false }, order: { createdAt: "ASC" }, @@ -1563,23 +1567,23 @@ export class ProfileEmployeeController extends Controller { const changeName = changeName_raw.length > 0 ? changeName_raw.map((item) => ({ - createdAt: item.createdAt - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.createdAt)) - : null, - status: item.status, - prefix: item.prefix, - firstName: item.firstName, - lastName: item.lastName, - })) + createdAt: item.createdAt + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.createdAt)) + : null, + status: item.status, + prefix: item.prefix, + firstName: item.firstName, + lastName: item.lastName, + })) : [ - { - createdAt: "", - status: "", - prefix: "", - firstName: "", - lastName: "", - }, - ]; + { + createdAt: "", + status: "", + prefix: "", + firstName: "", + lastName: "", + }, + ]; const profileHistory = await this.profileHistoryRepo.find({ where: { profileEmployeeId: id }, @@ -1588,19 +1592,19 @@ export class ProfileEmployeeController extends Controller { const history = profileHistory.length > 0 ? profileHistory.map((item) => ({ - birthDateOld: item.birthDateOld - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.birthDateOld)) - : "", - birthDate: item.birthDate - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.birthDate)) - : "", - })) + birthDateOld: item.birthDateOld + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.birthDateOld)) + : "", + birthDate: item.birthDate + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.birthDate)) + : "", + })) : [ - { - birthDateOld: "", - birthDate: "", - }, - ]; + { + birthDateOld: "", + birthDate: "", + }, + ]; const position_raw = await this.salaryRepo.find({ where: [ @@ -1634,76 +1638,76 @@ export class ProfileEmployeeController extends Controller { const positionList = position_raw.length > 0 ? await Promise.all( - position_raw.map(async (item, idx, arr) => { - const isLast = idx === arr.length - 1; - if (isLast) { - _commandDateAffect = item.commandDateAffect - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateAffect)) - : ""; - } - const _code = item.commandCode ? Number(item.commandCode) : null; - if (_code != null) { - _commandName = await this.commandCodeRepository.findOne({ - select: { name: true, code: true }, - where: { code: _code }, - }); - } - const codeSitAbb = item.posNumCodeSitAbb ?? "-"; - const commandNo = - item.commandNo && item.commandYear - ? item.commandNo + - "/" + - (item.commandYear > 2500 ? item.commandYear : item.commandYear + 543) + position_raw.map(async (item, idx, arr) => { + const isLast = idx === arr.length - 1; + if (isLast) { + _commandDateAffect = item.commandDateAffect + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateAffect)) + : ""; + } + const _code = item.commandCode ? Number(item.commandCode) : null; + if (_code != null) { + _commandName = await this.commandCodeRepository.findOne({ + select: { name: true, code: true }, + where: { code: _code }, + }); + } + const codeSitAbb = item.posNumCodeSitAbb ?? "-"; + const commandNo = + item.commandNo && item.commandYear + ? item.commandNo + + "/" + + (item.commandYear > 2500 ? item.commandYear : item.commandYear + 543) + : "-"; + const dateAffect = item.commandDateAffect + ? `${Extension.ToThaiFullDate2(item.commandDateAffect)}` : "-"; - const dateAffect = item.commandDateAffect - ? `${Extension.ToThaiFullDate2(item.commandDateAffect)}` - : "-"; - return { - commandName: - _commandName && _commandName.name ? _commandName.name : item.commandName, - commandDateAffect: item.commandDateAffect - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateAffect)) - : "", - commandDateSign: item.commandDateSign - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateSign)) - : "", - posNo: - item.posNoAbb && item.posNo - ? Extension.ToThaiNumber(`${item.posNoAbb} ${item.posNo}`) + return { + commandName: + _commandName && _commandName.name ? _commandName.name : item.commandName, + commandDateAffect: item.commandDateAffect + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateAffect)) : "", - position: item.positionName, - posType: item.positionType, - posLevel: item.positionLevel - ? Extension.ToThaiNumber(item.positionLevel) - : item.positionCee - ? Extension.ToThaiNumber(item.positionCee) - : null, - amount: item.amount - ? Extension.ToThaiNumber(Number(item.amount).toLocaleString()) - : "", - positionSalaryAmount: item.positionSalaryAmount - ? Extension.ToThaiNumber(Number(item.positionSalaryAmount).toLocaleString()) - : "", - refDoc: Extension.ToThaiNumber( - `คำสั่ง ${codeSitAbb} ที่ ${commandNo} ลว. ${dateAffect}`, - ), - }; - }), - ) + commandDateSign: item.commandDateSign + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateSign)) + : "", + posNo: + item.posNoAbb && item.posNo + ? Extension.ToThaiNumber(`${item.posNoAbb} ${item.posNo}`) + : "", + position: item.positionName, + posType: item.positionType, + posLevel: item.positionLevel + ? Extension.ToThaiNumber(item.positionLevel) + : item.positionCee + ? Extension.ToThaiNumber(item.positionCee) + : null, + amount: item.amount + ? Extension.ToThaiNumber(Number(item.amount).toLocaleString()) + : "", + positionSalaryAmount: item.positionSalaryAmount + ? Extension.ToThaiNumber(Number(item.positionSalaryAmount).toLocaleString()) + : "", + refDoc: Extension.ToThaiNumber( + `คำสั่ง ${codeSitAbb} ที่ ${commandNo} ลว. ${dateAffect}`, + ), + }; + }), + ) : [ - { - commandName: "", - commandDateAffect: "", - commandDateSign: "", - posNo: "", - position: "", - posType: "", - posLevel: "", - amount: "", - positionSalaryAmount: "", - refDoc: "", - }, - ]; + { + commandName: "", + commandDateAffect: "", + commandDateSign: "", + posNo: "", + position: "", + posType: "", + posLevel: "", + amount: "", + positionSalaryAmount: "", + refDoc: "", + }, + ]; // ลูกจ้างยังไม่มีรักษาการและช่วยราชการ // const actposition_raw = await this.profileActpositionRepo.find({ @@ -1787,36 +1791,36 @@ export class ProfileEmployeeController extends Controller { const duty = duty_raw.length > 0 ? duty_raw.map((item) => ({ - date: - item.dateStart && item.dateEnd - ? Extension.ToThaiNumber( - `${Extension.ToThaiFullDate2(item.dateStart)} - ${Extension.ToThaiFullDate2(item.dateEnd)}`, - ) - : item.dateStart - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.dateStart)) - : item.dateEnd - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.dateEnd)) - : "", - type: "-", - detail: Extension.ToThaiNumber(item.detail), - agency: "-", - refCommandNo: item.refCommandNo - ? item.refCommandDate - ? Extension.ToThaiNumber( - `${item.refCommandNo} ลว. ${Extension.ToThaiFullDate2(item.refCommandDate)}`, - ) - : Extension.ToThaiNumber(item.refCommandNo) - : "-", - })) + date: + item.dateStart && item.dateEnd + ? Extension.ToThaiNumber( + `${Extension.ToThaiFullDate2(item.dateStart)} - ${Extension.ToThaiFullDate2(item.dateEnd)}`, + ) + : item.dateStart + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.dateStart)) + : item.dateEnd + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.dateEnd)) + : "", + type: "-", + detail: Extension.ToThaiNumber(item.detail), + agency: "-", + refCommandNo: item.refCommandNo + ? item.refCommandDate + ? Extension.ToThaiNumber( + `${item.refCommandNo} ลว. ${Extension.ToThaiFullDate2(item.refCommandDate)}`, + ) + : Extension.ToThaiNumber(item.refCommandNo) + : "-", + })) : [ - { - date: "", - type: "", - detail: "", - agency: "", - refCommandNo: "", - }, - ]; + { + date: "", + type: "", + detail: "", + agency: "", + refCommandNo: "", + }, + ]; const assessments_raw = await this.profileAssessmentsRepository.find({ where: { profileEmployeeId: id, isDeleted: false }, order: { createdAt: "ASC" }, @@ -1824,48 +1828,48 @@ export class ProfileEmployeeController extends Controller { const assessments = assessments_raw.length > 0 ? assessments_raw.map((item) => ({ - year: item.year ? Extension.ToThaiNumber((parseInt(item.year) + 543).toString()) : "", - period: - item.period && item.period == "APR" - ? Extension.ToThaiNumber( - `1 เม.ย. ${(parseInt(item.year) + 543 - 1).toString()} - 31 มี.ค. ${(parseInt(item.year) + 543).toString()}`, - ) - : Extension.ToThaiNumber( - `1 ต.ค. ${(parseInt(item.year) + 543 - 1).toString()} - 30 ก.ย. ${(parseInt(item.year) + 543).toString()}`, - ), - point1: item.point1 ? Extension.ToThaiNumber(item.point1.toString()) : "", - point1Total: item.point1Total - ? Extension.ToThaiNumber(item.point1Total.toString()) - : "", - point2: item.point2 ? Extension.ToThaiNumber(item.point2.toString()) : "", - point2Total: item.point2Total - ? Extension.ToThaiNumber(item.point2Total.toString()) - : "", - pointSum: item.pointSum - ? Extension.ToThaiNumber(`ร้อยละ ${item.pointSum.toString()}`) - : "", - pointSumTh: item.pointSum ? Extension.textPoint(item.pointSum) : "", - level: - item.pointSum < 60.0 - ? "ต้องปรับปรุง" - : item.pointSum <= 69.99 && item.pointSum >= 60.0 - ? "พอใช้" - : item.pointSum <= 79.99 && item.pointSum >= 70.0 - ? "ดี" - : item.pointSum <= 89.99 && item.pointSum >= 80.0 - ? "ดีมาก" - : "ดีเด่น", - })) + year: item.year ? Extension.ToThaiNumber((parseInt(item.year) + 543).toString()) : "", + period: + item.period && item.period == "APR" + ? Extension.ToThaiNumber( + `1 เม.ย. ${(parseInt(item.year) + 543 - 1).toString()} - 31 มี.ค. ${(parseInt(item.year) + 543).toString()}`, + ) + : Extension.ToThaiNumber( + `1 ต.ค. ${(parseInt(item.year) + 543 - 1).toString()} - 30 ก.ย. ${(parseInt(item.year) + 543).toString()}`, + ), + point1: item.point1 ? Extension.ToThaiNumber(item.point1.toString()) : "", + point1Total: item.point1Total + ? Extension.ToThaiNumber(item.point1Total.toString()) + : "", + point2: item.point2 ? Extension.ToThaiNumber(item.point2.toString()) : "", + point2Total: item.point2Total + ? Extension.ToThaiNumber(item.point2Total.toString()) + : "", + pointSum: item.pointSum + ? Extension.ToThaiNumber(`ร้อยละ ${item.pointSum.toString()}`) + : "", + pointSumTh: item.pointSum ? Extension.textPoint(item.pointSum) : "", + level: + item.pointSum < 60.0 + ? "ต้องปรับปรุง" + : item.pointSum <= 69.99 && item.pointSum >= 60.0 + ? "พอใช้" + : item.pointSum <= 79.99 && item.pointSum >= 70.0 + ? "ดี" + : item.pointSum <= 89.99 && item.pointSum >= 80.0 + ? "ดีมาก" + : "ดีเด่น", + })) : [ - { - year: "", - period: "", - point1: "", - point2: "", - pointSum: "", - pointSumTh: "", - }, - ]; + { + year: "", + period: "", + point1: "", + point2: "", + pointSum: "", + pointSumTh: "", + }, + ]; const profileAbility_raw = await this.profileAbilityRepo.find({ where: { profileEmployeeId: id }, order: { createdAt: "ASC" }, @@ -1873,15 +1877,15 @@ export class ProfileEmployeeController extends Controller { const profileAbility = profileAbility_raw.length > 0 ? profileAbility_raw.map((item) => ({ - field: item.field ? item.field : "", - detail: item.detail ? item.detail : "", - })) + field: item.field ? item.field : "", + detail: item.detail ? item.detail : "", + })) : [ - { - field: "", - detail: "", - }, - ]; + { + field: "", + detail: "", + }, + ]; const otherIncome_raw = await this.salaryRepo.find({ where: { @@ -1894,53 +1898,53 @@ export class ProfileEmployeeController extends Controller { const otherIncome = otherIncome_raw.length > 0 ? await Promise.all( - otherIncome_raw.map(async (item) => { - const codeSitAbb = item.posNumCodeSitAbb ?? "-"; - const commandNo = - item.commandNo && item.commandYear - ? item.commandNo + - "/" + - (item.commandYear > 2500 ? item.commandYear : item.commandYear + 543) + otherIncome_raw.map(async (item) => { + const codeSitAbb = item.posNumCodeSitAbb ?? "-"; + const commandNo = + item.commandNo && item.commandYear + ? item.commandNo + + "/" + + (item.commandYear > 2500 ? item.commandYear : item.commandYear + 543) + : "-"; + const dateAffect = item.commandDateAffect + ? `${Extension.ToThaiFullDate2(item.commandDateAffect)}` : "-"; - const dateAffect = item.commandDateAffect - ? `${Extension.ToThaiFullDate2(item.commandDateAffect)}` - : "-"; - return { - commandName: item.commandName ?? "", - commandDateAffect: item.commandDateAffect - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateAffect)) - : "", - commandDateSign: item.commandDateSign - ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateSign)) - : "", - commandNo: item.commandNo ? Extension.ToThaiNumber(item.commandNo) : "", - position: item.positionName, - posLevel: item.positionLevel - ? Extension.ToThaiNumber(item.positionLevel) - : item.positionCee - ? Extension.ToThaiNumber(item.positionCee) - : null, - amount: item.amount - ? Extension.ToThaiNumber(Number(item.amount).toLocaleString()) - : "", - refDoc: Extension.ToThaiNumber( - `คำสั่ง ${codeSitAbb} ที่ ${commandNo} ลว. ${dateAffect}`, - ), - }; - }), - ) + return { + commandName: item.commandName ?? "", + commandDateAffect: item.commandDateAffect + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateAffect)) + : "", + commandDateSign: item.commandDateSign + ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.commandDateSign)) + : "", + commandNo: item.commandNo ? Extension.ToThaiNumber(item.commandNo) : "", + position: item.positionName, + posLevel: item.positionLevel + ? Extension.ToThaiNumber(item.positionLevel) + : item.positionCee + ? Extension.ToThaiNumber(item.positionCee) + : null, + amount: item.amount + ? Extension.ToThaiNumber(Number(item.amount).toLocaleString()) + : "", + refDoc: Extension.ToThaiNumber( + `คำสั่ง ${codeSitAbb} ที่ ${commandNo} ลว. ${dateAffect}`, + ), + }; + }), + ) : [ - { - commandName: "", - commandDateAffect: "", - commandDateSign: "", - commandNo: "", - position: "", - posLevel: "", - amount: "", - refDoc: "", - }, - ]; + { + commandName: "", + commandDateAffect: "", + commandDateSign: "", + commandNo: "", + position: "", + posLevel: "", + amount: "", + refDoc: "", + }, + ]; // ประวัติพ้นจากราชการ let retires = []; @@ -2039,8 +2043,8 @@ export class ProfileEmployeeController extends Controller { profiles?.position != null ? profiles.posType != null && profiles?.posLevel != null ? Extension.ToThaiNumber( - `${profiles.position} ${profiles.posType.posTypeShortName} ${profiles.posLevel.posLevelName}`, - ) + `${profiles.position} ${profiles.posType.posTypeShortName} ${profiles.posLevel.posLevelName}`, + ) : profiles.position : "" ).trim(); @@ -2057,45 +2061,45 @@ export class ProfileEmployeeController extends Controller { const sum = profiles ? Extension.ToThaiNumber( - ( - Number(profiles.amount) + - Number(profiles.positionSalaryAmount) + - Number(profiles.mouthSalaryAmount) + - Number(profiles.amountSpecial) - ).toLocaleString(), - ) + ( + Number(profiles.amount) + + Number(profiles.positionSalaryAmount) + + Number(profiles.mouthSalaryAmount) + + Number(profiles.amountSpecial) + ).toLocaleString(), + ) : ""; const fullCurrentAddress = profiles && profiles.currentAddress ? Extension.ToThaiNumber( - profiles.currentAddress + - (profiles.currentSubDistrict && profiles.currentSubDistrict.name - ? " ตำบล/แขวง " + profiles.currentSubDistrict.name - : "") + - (profiles.currentDistrict && profiles.currentDistrict.name - ? " อำเภอ/เขต " + profiles.currentDistrict.name - : "") + - (profiles.currentProvince && profiles.currentProvince.name - ? " จังหวัด " + profiles.currentProvince.name - : "") + - (profiles.currentZipCode ? " " + profiles.currentZipCode : ""), - ) + profiles.currentAddress + + (profiles.currentSubDistrict && profiles.currentSubDistrict.name + ? " ตำบล/แขวง " + profiles.currentSubDistrict.name + : "") + + (profiles.currentDistrict && profiles.currentDistrict.name + ? " อำเภอ/เขต " + profiles.currentDistrict.name + : "") + + (profiles.currentProvince && profiles.currentProvince.name + ? " จังหวัด " + profiles.currentProvince.name + : "") + + (profiles.currentZipCode ? " " + profiles.currentZipCode : ""), + ) : ""; const fullRegistrationAddress = profiles && profiles.registrationAddress ? Extension.ToThaiNumber( - profiles.registrationAddress + - (profiles.registrationSubDistrict && profiles.registrationSubDistrict.name - ? " ตำบล/แขวง " + profiles.registrationSubDistrict.name - : "") + - (profiles.registrationDistrict && profiles.registrationDistrict.name - ? " อำเภอ/เขต " + profiles.registrationDistrict.name - : "") + - (profiles.registrationProvince && profiles.registrationProvince.name - ? " จังหวัด " + profiles.registrationProvince.name - : "") + - (profiles.currentZipCode ? " " + profiles.currentZipCode : ""), - ) + profiles.registrationAddress + + (profiles.registrationSubDistrict && profiles.registrationSubDistrict.name + ? " ตำบล/แขวง " + profiles.registrationSubDistrict.name + : "") + + (profiles.registrationDistrict && profiles.registrationDistrict.name + ? " อำเภอ/เขต " + profiles.registrationDistrict.name + : "") + + (profiles.registrationProvince && profiles.registrationProvince.name + ? " จังหวัด " + profiles.registrationProvince.name + : "") + + (profiles.currentZipCode ? " " + profiles.currentZipCode : ""), + ) : ""; const data = { currentDate: Extension.ToThaiNumber(Extension.ToThaiFullDate2(currentDate)), @@ -2143,24 +2147,24 @@ export class ProfileEmployeeController extends Controller { profiles.citizenId != null ? Extension.ToThaiNumber(profiles.citizenId.toString()) : "", fatherFullName: profileFamilyFather?.fatherPrefix || - profileFamilyFather?.fatherFirstName || - profileFamilyFather?.fatherLastName + profileFamilyFather?.fatherFirstName || + profileFamilyFather?.fatherLastName ? `${profileFamilyFather?.fatherPrefix ?? ""}${profileFamilyFather?.fatherFirstName ?? ""} ${profileFamilyFather?.fatherLastName ?? ""}`.trim() : null, fatherLive: profileFamilyFather && profileFamilyFather?.fatherLive == true ? "ถึงแก่กรรม" : "มีชีวิต", motherFullName: profileFamilyMother?.motherPrefix || - profileFamilyMother?.motherFirstName || - profileFamilyMother?.motherLastName + profileFamilyMother?.motherFirstName || + profileFamilyMother?.motherLastName ? `${profileFamilyMother?.motherPrefix ?? ""}${profileFamilyMother?.motherFirstName ?? ""} ${profileFamilyMother?.motherLastName ?? ""}`.trim() : null, motherLive: profileFamilyMother && profileFamilyMother?.motherLive == true ? "ถึงแก่กรรม" : "มีชีวิต", coupleFullName: profileFamilyCouple?.couplePrefix || - profileFamilyCouple?.coupleFirstName || - profileFamilyCouple?.coupleLastNameOld + profileFamilyCouple?.coupleFirstName || + profileFamilyCouple?.coupleLastNameOld ? `${profileFamilyCouple?.couplePrefix ?? ""}${profileFamilyCouple?.coupleFirstName ?? ""} ${profileFamilyCouple?.coupleLastName ?? ""}`.trim() : null, coupleLastNameOld: profileFamilyCouple?.coupleLastNameOld ?? null, @@ -2382,27 +2386,28 @@ export class ProfileEmployeeController extends Controller { } if (body.citizenId) { - Extension.CheckCitizen(body.citizenId); + const citizenIdDigits = body.citizenId.toString().split("").map(Number); + const cal = + citizenIdDigits[0] * 13 + + citizenIdDigits[1] * 12 + + citizenIdDigits[2] * 11 + + citizenIdDigits[3] * 10 + + citizenIdDigits[4] * 9 + + citizenIdDigits[5] * 8 + + citizenIdDigits[6] * 7 + + citizenIdDigits[7] * 6 + + citizenIdDigits[8] * 5 + + citizenIdDigits[9] * 4 + + citizenIdDigits[10] * 3 + + citizenIdDigits[11] * 2; + const calStp2 = cal % 11; + const chkDigit = (11 - calStp2) % 10; + + if (citizenIdDigits[12] !== chkDigit) { + throw new HttpError(HttpStatus.NOT_FOUND, "ข้อมูลรหัสบัตรประจำตัวประชาชนไม่ถูกต้อง"); + } } const record = await this.profileRepo.findOneBy({ id }); - const before = structuredClone(record); - // เช็คว่ามี profileHistory ของ profile นี้หรือไม่ - const historyCount = await this.profileHistoryRepo.count({ - where: { profileEmployeeId: id }, - }); - - // ถ้าไม่มีเลย ให้บันทึกข้อมูลเริ่มต้น (ก่อน update) ลงไปก่อน - if (historyCount === 0) { - await this.profileHistoryRepo.save( - Object.assign(new ProfileEmployeeHistory(), { - ...before, - birthDateOld: before?.birthDate, - profileEmployeeId: id, - id: undefined, - }), - ); - } - if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); if (body.employeeClass == null || body.employeeClass == undefined || body.employeeClass == "") { @@ -2434,8 +2439,6 @@ export class ProfileEmployeeController extends Controller { }), ); await this.profileRepo.save(record); - // บันทึกประวัติคนครองตำแหน่ง (ถ้า profile นี้ครองตำแหน่งอยู่) - await updateHolderProfileHistory(record.id, request, "EMPLOYEE"); return new HttpSuccess(); } @@ -2533,8 +2536,8 @@ export class ProfileEmployeeController extends Controller { _data.profileEmployeeEmployment.length == 0 ? null : _data.profileEmployeeEmployment.reduce((latest, current) => { - return latest.date > current.date ? latest : current; - }).date; + return latest.date > current.date ? latest : current; + }).date; return { id: _data.id, prefix: _data.prefix, @@ -2697,32 +2700,32 @@ export class ProfileEmployeeController extends Controller { profile.current_holders.length == 0 ? null : profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 != - null + profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 != + null ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4.orgChild4ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgChild3 != null + profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgChild3 != null ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3.orgChild3ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgChild2 != null + profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgChild2 != null ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2.orgChild2ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgChild1 != null + profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgChild1 != null ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1.orgChild1ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) != - null && - profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgRoot != null + null && + profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgRoot != null ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot.orgRootShortName} ${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : null; const root = profile.current_holders.length == 0 || - (profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null) + (profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null) ? null : profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot; @@ -2849,12 +2852,12 @@ export class ProfileEmployeeController extends Controller { queryLike = "profileEmployee.position LIKE :keyword"; } else if (searchField == "posNo") { queryLike = ` - CASE - WHEN current_holders.orgChild4Id IS NOT NULL THEN CONCAT_WS(' ', orgChild4.orgChild4ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - WHEN current_holders.orgChild3Id IS NOT NULL THEN CONCAT_WS(' ', orgChild3.orgChild3ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - WHEN current_holders.orgChild2Id IS NOT NULL THEN CONCAT_WS(' ', orgChild2.orgChild2ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - WHEN current_holders.orgChild1Id IS NOT NULL THEN CONCAT_WS(' ', orgChild1.orgChild1ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - ELSE CONCAT_WS(' ', orgRoot.orgRootShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) + CASE + WHEN current_holders.orgChild4Id IS NOT NULL THEN CONCAT(orgChild4.orgChild4ShortName, " ", current_holders.posMasterNo) + WHEN current_holders.orgChild3Id IS NOT NULL THEN CONCAT(orgChild3.orgChild3ShortName, " ", current_holders.posMasterNo) + WHEN current_holders.orgChild2Id IS NOT NULL THEN CONCAT(orgChild2.orgChild2ShortName, " ", current_holders.posMasterNo) + WHEN current_holders.orgChild1Id IS NOT NULL THEN CONCAT(orgChild1.orgChild1ShortName, " ", current_holders.posMasterNo) + ELSE CONCAT(orgRoot.orgRootShortName, " ", current_holders.posMasterNo) END LIKE :keyword `; } @@ -2947,57 +2950,57 @@ export class ProfileEmployeeController extends Controller { _data.current_holders.length == 0 ? null : _data.current_holders.find((x) => x.orgRevisionId == revisionId) != null && - _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4 != null + _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4 != null ? `${_data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4.orgChild4ShortName} ${_data.current_holders.find((x) => x.orgRevisionId == revisionId)?.posMasterNo}` : _data.current_holders.find((x) => x.orgRevisionId == revisionId) != null && - _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3 != - null + _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3 != + null ? `${_data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3.orgChild3ShortName} ${_data.current_holders.find((x) => x.orgRevisionId == revisionId)?.posMasterNo}` : _data.current_holders.find((x) => x.orgRevisionId == revisionId) != null && - _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2 != - null + _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2 != + null ? `${_data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2.orgChild2ShortName} ${_data.current_holders.find((x) => x.orgRevisionId == revisionId)?.posMasterNo}` : _data.current_holders.find((x) => x.orgRevisionId == revisionId) != null && - _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1 != - null + _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1 != + null ? `${_data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1.orgChild1ShortName} ${_data.current_holders.find((x) => x.orgRevisionId == revisionId)?.posMasterNo}` : _data.current_holders.find((x) => x.orgRevisionId == revisionId) != null && - _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot != - null + _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot != + null ? `${_data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot.orgRootShortName} ${_data.current_holders.find((x) => x.orgRevisionId == revisionId)?.posMasterNo}` : null; const root = _data.current_holders.length == 0 || - (_data.current_holders.find((x) => x.orgRevisionId == revisionId) != null && - _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot == null) + (_data.current_holders.find((x) => x.orgRevisionId == revisionId) != null && + _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot == null) ? null : _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot; const child1 = _data.current_holders == null || - _data.current_holders.length == 0 || - _data.current_holders.find((x) => x.orgRevisionId == revisionId) == null + _data.current_holders.length == 0 || + _data.current_holders.find((x) => x.orgRevisionId == revisionId) == null ? null : _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1; const child2 = _data.current_holders == null || - _data.current_holders.length == 0 || - _data.current_holders.find((x) => x.orgRevisionId == revisionId) == null + _data.current_holders.length == 0 || + _data.current_holders.find((x) => x.orgRevisionId == revisionId) == null ? null : _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2; const child3 = _data.current_holders == null || - _data.current_holders.length == 0 || - _data.current_holders.find((x) => x.orgRevisionId == revisionId) == null + _data.current_holders.length == 0 || + _data.current_holders.find((x) => x.orgRevisionId == revisionId) == null ? null : _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3; const child4 = _data.current_holders == null || - _data.current_holders.length == 0 || - _data.current_holders.find((x) => x.orgRevisionId == revisionId) == null + _data.current_holders.length == 0 || + _data.current_holders.find((x) => x.orgRevisionId == revisionId) == null ? null : _data.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4; @@ -3108,7 +3111,7 @@ export class ProfileEmployeeController extends Controller { @Query() sortBy: string = "profileEmployee.dateLeave", @Query() sort: "ASC" | "DESC" = "DESC", ) { - let _data = await new permission().PermissionOrgList(request, "SYS_REGISTRY_RETIRE_EMP"); + let _data = await new permission().PermissionOrgList(request, "SYS_REGISTRY_EMP"); const { data, total } = await this.profileLeaveService.getLeaveEmployees(request, { page, @@ -3208,12 +3211,12 @@ export class ProfileEmployeeController extends Controller { queryLike = "profileEmployee.position LIKE :keyword"; } else if (searchField == "posNo") { queryLike = ` - CASE - WHEN current_holders.orgChild4Id IS NOT NULL THEN CONCAT_WS(' ', orgChild4.orgChild4ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - WHEN current_holders.orgChild3Id IS NOT NULL THEN CONCAT_WS(' ', orgChild3.orgChild3ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - WHEN current_holders.orgChild2Id IS NOT NULL THEN CONCAT_WS(' ', orgChild2.orgChild2ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - WHEN current_holders.orgChild1Id IS NOT NULL THEN CONCAT_WS(' ', orgChild1.orgChild1ShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) - ELSE CONCAT_WS(' ', orgRoot.orgRootShortName, NULLIF(current_holders.posMasterNoPrefix,''), current_holders.posMasterNo, NULLIF(current_holders.posMasterNoSuffix,'')) + CASE + WHEN current_holders.orgChild4Id IS NOT NULL THEN CONCAT(orgChild4.orgChild4ShortName, " ", current_holders.posMasterNo) + WHEN current_holders.orgChild3Id IS NOT NULL THEN CONCAT(orgChild3.orgChild3ShortName, " ", current_holders.posMasterNo) + WHEN current_holders.orgChild2Id IS NOT NULL THEN CONCAT(orgChild2.orgChild2ShortName, " ", current_holders.posMasterNo) + WHEN current_holders.orgChild1Id IS NOT NULL THEN CONCAT(orgChild1.orgChild1ShortName, " ", current_holders.posMasterNo) + ELSE CONCAT(orgRoot.orgRootShortName, " ", current_holders.posMasterNo) END LIKE :keyword `; } @@ -3272,7 +3275,7 @@ export class ProfileEmployeeController extends Controller { ? _data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` : // : `current_holders.orgChild1Id is ${_data.privilege == "PARENT" ? "not null" : "null"}` - `current_holders.orgChild1Id is null` + `current_holders.orgChild1Id is null` : "1=1", { child1: _data.child1, @@ -3366,7 +3369,7 @@ export class ProfileEmployeeController extends Controller { const data = await Promise.all( record.map((_data) => { const holder = _data.current_holders.find((x) => x.orgRevisionId == findRevision.id); - const numPart = holder ? [holder.posMasterNoPrefix, holder.posMasterNo, holder.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; + const numPart = holder ? `${holder.posMasterNoPrefix ?? ''}${holder.posMasterNo ?? ''}${holder.posMasterNoSuffix ?? ''}` : ''; const shortName = !holder ? null : holder.orgChild4 != null @@ -3384,40 +3387,40 @@ export class ProfileEmployeeController extends Controller { _data.profileEmployeeEmployment.length == 0 ? null : _data.profileEmployeeEmployment.reduce((latest, current) => { - return latest.date > current.date ? latest : current; - }).date; + return latest.date > current.date ? latest : current; + }).date; const root = _data.current_holders.length == 0 || - (_data.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null) + (_data.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null) ? null : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot; const child1 = _data.current_holders == null || - _data.current_holders.length == 0 || - _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null + _data.current_holders.length == 0 || + _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null ? null : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1; const child2 = _data.current_holders == null || - _data.current_holders.length == 0 || - _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null + _data.current_holders.length == 0 || + _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null ? null : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2; const child3 = _data.current_holders == null || - _data.current_holders.length == 0 || - _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null + _data.current_holders.length == 0 || + _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null ? null : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3; const child4 = _data.current_holders == null || - _data.current_holders.length == 0 || - _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null + _data.current_holders.length == 0 || + _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null ? null : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4; @@ -3685,8 +3688,8 @@ export class ProfileEmployeeController extends Controller { .map((x) => x.current_holderId).length == 0 ? ["zxc"] : orgRevision.employeePosMasters - .filter((x) => x.current_holderId != null) - .map((x) => x.current_holderId), + .filter((x) => x.current_holderId != null) + .map((x) => x.current_holderId), }); }), ) @@ -3843,7 +3846,7 @@ export class ProfileEmployeeController extends Controller { holder.orgChild2?.orgChild2ShortName || holder.orgChild1?.orgChild1ShortName || holder.orgRoot?.orgRootShortName; - return `${shortName || ""} ${[holder.posMasterNoPrefix, holder.posMasterNo, holder.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ')}`; + return `${shortName || ""} ${holder.posMasterNo || ""}`; }); return profile.current_holders.map((holder, index) => { const position = holder.positions.find((position) => position.posMasterId === holder.id); @@ -3924,37 +3927,37 @@ export class ProfileEmployeeController extends Controller { const posMaster = profile.current_holders == null || - profile.current_holders.length == 0 || - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) == null + profile.current_holders.length == 0 || + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id); const root = profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot == null + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot; const child1 = profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1 == + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1; const child2 = profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2 == + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2; const child3 = profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3 == + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3; const child4 = profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4 == + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4; @@ -4021,38 +4024,40 @@ export class ProfileEmployeeController extends Controller { salary: profile ? profile.amount : null, amountSpecial: profile ? profile.amountSpecial : null, posNo: null, + // root?.orgRootShortName && posMaster?.posMasterNo + // ? `${root?.orgRootShortName} ${posMaster?.posMasterNo}` + // : "", }; - const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; if (_profile.child4Id != null) { _profile.node = 4; _profile.nodeId = _profile.child4Id; _profile.nodeDnaId = _profile.child4DnaId; _profile.nodeShortName = _profile.child4ShortName; - _profile.posNo = `${_profile.child4ShortName} ${_numPart}`; + _profile.posNo = `${_profile.child4ShortName} ${_profile.posMasterNo}`; } else if (_profile.child3Id != null) { _profile.node = 3; _profile.nodeId = _profile.child3Id; _profile.nodeDnaId = _profile.child3DnaId; _profile.nodeShortName = _profile.child3ShortName; - _profile.posNo = `${_profile.child3ShortName} ${_numPart}`; + _profile.posNo = `${_profile.child3ShortName} ${_profile.posMasterNo}`; } else if (_profile.child2Id != null) { _profile.node = 2; _profile.nodeId = _profile.child2Id; _profile.nodeDnaId = _profile.child2DnaId; _profile.nodeShortName = _profile.child2ShortName; - _profile.posNo = `${_profile.child2ShortName} ${_numPart}`; + _profile.posNo = `${_profile.child2ShortName} ${_profile.posMasterNo}`; } else if (_profile.child1Id != null) { _profile.node = 1; _profile.nodeId = _profile.child1Id; _profile.nodeDnaId = _profile.child1DnaId; _profile.nodeShortName = _profile.child1ShortName; - _profile.posNo = `${_profile.child1ShortName} ${_numPart}`; + _profile.posNo = `${_profile.child1ShortName} ${_profile.posMasterNo}`; } else if (_profile.rootId != null) { _profile.node = 0; _profile.nodeId = _profile.rootId; _profile.nodeDnaId = _profile.rootDnaId; _profile.nodeShortName = _profile.rootShortName; - _profile.posNo = `${_profile.rootShortName} ${_numPart}`; + _profile.posNo = `${_profile.rootShortName} ${_profile.posMasterNo}`; } return new HttpSuccess(_profile); } @@ -4153,7 +4158,7 @@ export class ProfileEmployeeController extends Controller { ? _data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` : // : `current_holders.orgChild1Id is ${_data.privilege == "PARENT" ? "not null" : "null"}` - `current_holders.orgChild1Id is null` + `current_holders.orgChild1Id is null` : "1=1", { child1: _data.child1 }, ) @@ -4197,32 +4202,32 @@ export class ProfileEmployeeController extends Controller { item.current_holders.length == 0 ? null : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 != - null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 != + null ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4.orgChild4ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3 != - null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3 != + null ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3.orgChild3ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgChild2 != null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgChild2 != null ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2.orgChild2ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgChild1 != null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgChild1 != null ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1.orgChild1ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != - null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgRoot != null + null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgRoot != null ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot.orgRootShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : null; const root = item.current_holders.length == 0 || - (item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null) + (item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null) ? null : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot; @@ -4712,7 +4717,7 @@ export class ProfileEmployeeController extends Controller { ? _data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` : // : `current_holders.orgChild1Id is ${_data.privilege == "PARENT" ? "not null" : "null"}` - `current_holders.orgChild1Id is null` + `current_holders.orgChild1Id is null` : "1=1", { child1: _data.child1, @@ -4783,54 +4788,54 @@ export class ProfileEmployeeController extends Controller { isProbation: item.isProbation, orgRootName: item.current_holders == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot == + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot - ?.orgRootName == null + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot + ?.orgRootName == null ? null : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot - ?.orgRootName, + ?.orgRootName, orgChild1Name: item.current_holders == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild1 == + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild1 == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild1 - ?.orgChild1Name == null + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild1 + ?.orgChild1Name == null ? null : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) - ?.orgChild1?.orgChild1Name, + ?.orgChild1?.orgChild1Name, orgChild2Name: item.current_holders == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild2 == + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild2 == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild2 - ?.orgChild2Name == null + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild2 + ?.orgChild2Name == null ? null : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) - ?.orgChild2?.orgChild2Name, + ?.orgChild2?.orgChild2Name, orgChild3Name: item.current_holders == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild3 == + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild3 == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild3 - ?.orgChild3Name == null + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild3 + ?.orgChild3Name == null ? null : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) - ?.orgChild3?.orgChild3Name, + ?.orgChild3?.orgChild3Name, orgChild4Name: item.current_holders == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild4 == + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild4 == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild4 - ?.orgChild4Name == null + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild4 + ?.orgChild4Name == null ? null : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) - ?.orgChild4?.orgChild4Name, + ?.orgChild4?.orgChild4Name, }; }), ); @@ -4907,49 +4912,49 @@ export class ProfileEmployeeController extends Controller { findProfile.map(async (item: ProfileEmployee) => { const posMaster = item.current_holders == null || - item.current_holders.length == 0 || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) == null + item.current_holders.length == 0 || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) == null ? null : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id); const position = posMaster == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id)?.positions == + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id)?.positions == null || - item.current_holders?.find((x) => x.orgRevisionId == orgRevisionActive.id)?.positions - .length == 0 || - item.current_holders - .find((x) => x.orgRevisionId == orgRevisionActive.id) - ?.positions?.find((position) => position.positionIsSelected == true) == null + item.current_holders?.find((x) => x.orgRevisionId == orgRevisionActive.id)?.positions + .length == 0 || + item.current_holders + .find((x) => x.orgRevisionId == orgRevisionActive.id) + ?.positions?.find((position) => position.positionIsSelected == true) == null ? null : item.current_holders - .find((x) => x.orgRevisionId == orgRevisionActive.id) - ?.positions?.find((position) => position.positionIsSelected == true); + .find((x) => x.orgRevisionId == orgRevisionActive.id) + ?.positions?.find((position) => position.positionIsSelected == true); const shortName = item.current_holders.length == 0 ? null : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) != null && - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) - ?.orgChild4 != null + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) + ?.orgChild4 != null ? `${item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id)?.orgChild4.orgChild4ShortName} ${item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) != null && - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) - ?.orgChild3 != null + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) + ?.orgChild3 != null ? `${item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id)?.orgChild3.orgChild3ShortName} ${item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) != - null && - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) - ?.orgChild2 != null + null && + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) + ?.orgChild2 != null ? `${item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id)?.orgChild2.orgChild2ShortName} ${item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) != - null && - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) - ?.orgChild1 != null + null && + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) + ?.orgChild1 != null ? `${item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id)?.orgChild1.orgChild1ShortName} ${item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) != - null && - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) - ?.orgRoot != null + null && + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id) + ?.orgRoot != null ? `${item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id)?.orgRoot.orgRootShortName} ${item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id)?.posMasterNo}` : null; @@ -4967,54 +4972,54 @@ export class ProfileEmployeeController extends Controller { isProbation: item.isProbation, orgRootName: item.current_holders == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot == + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot - ?.orgRootName == null + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot + ?.orgRootName == null ? null : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot - ?.orgRootName, + ?.orgRootName, orgChild1Name: item.current_holders == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild1 == + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild1 == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild1 - ?.orgChild1Name == null + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild1 + ?.orgChild1Name == null ? null : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) - ?.orgChild1?.orgChild1Name, + ?.orgChild1?.orgChild1Name, orgChild2Name: item.current_holders == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild2 == + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild2 == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild2 - ?.orgChild2Name == null + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild2 + ?.orgChild2Name == null ? null : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) - ?.orgChild2?.orgChild2Name, + ?.orgChild2?.orgChild2Name, orgChild3Name: item.current_holders == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild3 == + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild3 == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild3 - ?.orgChild3Name == null + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild3 + ?.orgChild3Name == null ? null : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) - ?.orgChild3?.orgChild3Name, + ?.orgChild3?.orgChild3Name, orgChild4Name: item.current_holders == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild4 == + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null || + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild4 == null || - item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild4 - ?.orgChild4Name == null + item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild4 + ?.orgChild4Name == null ? null : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) - ?.orgChild4?.orgChild4Name, + ?.orgChild4?.orgChild4Name, }; }), ); @@ -5307,7 +5312,7 @@ export class ProfileEmployeeController extends Controller { isLeave: false, isRetired: item.current_holder.birthDate == null || - calculateRetireDate(item.current_holder.birthDate).getFullYear() != body.year + calculateRetireDate(item.current_holder.birthDate).getFullYear() != body.year ? false : true, isSpecial: false, @@ -5361,98 +5366,98 @@ export class ProfileEmployeeController extends Controller { posTypeId: profile.posType == null ? null : profile.posType.id, rootId: profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot == null + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot == null ? null : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRootId, rootDnaId: profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot == null + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot == null ? null : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.ancestorDNA, root: profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot == null + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot == null ? null : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot.orgRootName, child1Id: profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1 == null + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1Id, child1DnaId: profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1 == null + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.ancestorDNA, child1: profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1 == null + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1 - .orgChild1Name, + .orgChild1Name, child2Id: profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2 == null + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2Id, child2DnaId: profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2 == null + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.ancestorDNA, child2: profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2 == null + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2 - .orgChild2Name, + .orgChild2Name, child3Id: profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3 == null + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3Id, child3DnaId: profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3 == null + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.ancestorDNA, child3: profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3 == null + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3 - .orgChild3Name, + .orgChild3Name, child4Id: profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4 == null + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4Id, child4DnaId: profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4 == null + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.ancestorDNA, child4: profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || - profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4 == null + profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null || + profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4 - .orgChild4Name, + .orgChild4Name, }; return new HttpSuccess(_profile); } @@ -5504,8 +5509,8 @@ export class ProfileEmployeeController extends Controller { const formattedData = profiles.map((item) => { const posMaster = item.current_holders == null || - item.current_holders.length == 0 || - item.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null + item.current_holders.length == 0 || + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null ? null : item.current_holders.find((x) => x.orgRevisionId == findRevision.id); @@ -5513,49 +5518,49 @@ export class ProfileEmployeeController extends Controller { item.current_holders.length == 0 ? null : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 != - null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 != + null ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4.orgChild4ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3 != - null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3 != + null ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3.orgChild3ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2 != - null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2 != + null ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2.orgChild2ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgChild1 != null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgChild1 != null ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1.orgChild1ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgRoot != null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgRoot != null ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot.orgRootShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : null; const root = item.current_holders == null || - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null ? null : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot; const child1 = item.current_holders == null || - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1 == null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1 == null ? null : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1; const child2 = item.current_holders == null || - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2 == null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2 == null ? null : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2; const child3 = item.current_holders == null || - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3 == null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3 == null ? null : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3; const child4 = item.current_holders == null || - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 == null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 == null ? null : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4; @@ -5678,24 +5683,24 @@ export class ProfileEmployeeController extends Controller { !profile.current_holders || profile.current_holders.length == 0 ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) != null && - profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild4 != - null + profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild4 != + null ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild4.orgChild4ShortName}` : profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) != null && - profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild3 != - null + profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild3 != + null ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild3.orgChild3ShortName}` : profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) != null && - profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) - ?.orgChild2 != null + profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) + ?.orgChild2 != null ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild2.orgChild2ShortName}` : profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) != null && - profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) - ?.orgChild1 != null + profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) + ?.orgChild1 != null ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild1.orgChild1ShortName}` : profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) != null && - profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) - ?.orgRoot != null + profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) + ?.orgRoot != null ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgRoot.orgRootShortName}` : null; const dest_item = await this.salaryRepo.findOne({ @@ -6156,7 +6161,7 @@ export class ProfileEmployeeController extends Controller { positionId: profile.positionIdTemp, profileId: profile.id, }) - .then(async () => { }); + .then(async () => {}); } }), ); @@ -6250,33 +6255,33 @@ export class ProfileEmployeeController extends Controller { item.current_holders.length == 0 ? null : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 != - null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 != + null ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4.orgChild4ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgChild3 != null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgChild3 != null ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3.orgChild3ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgChild2 != null + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgChild2 != null ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2.orgChild2ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != - null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgChild1 != null + null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgChild1 != null ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1.orgChild1ShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != - null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id) - ?.orgRoot != null + null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id) + ?.orgRoot != null ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot.orgRootShortName} ${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}` : null; root = item.current_holders.length == 0 || - (item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && - item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null) + (item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null && + item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null) ? null : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot; root = root == null ? null : root.orgRootName; @@ -6427,40 +6432,66 @@ export class ProfileEmployeeController extends Controller { }); const posMaster = profile.current_holders == null || - profile.current_holders.length == 0 || - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) == null + profile.current_holders.length == 0 || + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id); const root = profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot == null + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot; const child1 = profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1 == + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1; const child2 = profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2 == + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2; const child3 = profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3 == + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3; const child4 = profile.current_holders == null || - profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4 == + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4 == null ? null : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4; - const _numPart = posMaster ? [posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ') : ''; + const shortName = + profile.current_holders.length == 0 + ? null + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != null && + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) + ?.orgChild4 != null + ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4.orgChild4ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}` + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != null && + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) + ?.orgChild3 != null + ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3.orgChild3ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}` + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != + null && + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) + ?.orgChild2 != null + ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2.orgChild2ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}` + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != + null && + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) + ?.orgChild1 != null + ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1.orgChild1ShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}` + : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != + null && + profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) + ?.orgRoot != null + ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot.orgRootShortName} ${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}` + : null; const _profile: any = { profileId: profile.id, prefix: profile.prefix, @@ -6502,7 +6533,7 @@ export class ProfileEmployeeController extends Controller { child4ShortName: child4 == null ? null : child4.orgChild4ShortName, node: null, nodeId: null, - posNo: null, + posNo: shortName, salary: profile.amount, education: profile && profile.profileEducations.length > 0 @@ -6517,27 +6548,22 @@ export class ProfileEmployeeController extends Controller { _profile.node = 4; _profile.nodeId = _profile.child4Id; _profile.nodeShortName = _profile.child4ShortName; - _profile.posNo = `${_profile.child4ShortName} ${_numPart}`; } else if (_profile.child3Id != null) { _profile.node = 3; _profile.nodeId = _profile.child3Id; _profile.nodeShortName = _profile.child3ShortName; - _profile.posNo = `${_profile.child3ShortName} ${_numPart}`; } else if (_profile.child2Id != null) { _profile.node = 2; _profile.nodeId = _profile.child2Id; _profile.nodeShortName = _profile.child2ShortName; - _profile.posNo = `${_profile.child2ShortName} ${_numPart}`; } else if (_profile.child1Id != null) { _profile.node = 1; _profile.nodeId = _profile.child1Id; _profile.nodeShortName = _profile.child1ShortName; - _profile.posNo = `${_profile.child1ShortName} ${_numPart}`; } else if (_profile.rootId != null) { _profile.node = 0; _profile.nodeId = _profile.rootId; _profile.nodeShortName = _profile.rootShortName; - _profile.posNo = `${_profile.rootShortName} ${_numPart}`; } return new HttpSuccess(_profile); } diff --git a/src/controllers/ProfileEmployeeTempController.ts b/src/controllers/ProfileEmployeeTempController.ts index 406dce69..a8c017ae 100644 --- a/src/controllers/ProfileEmployeeTempController.ts +++ b/src/controllers/ProfileEmployeeTempController.ts @@ -1001,24 +1001,6 @@ export class ProfileEmployeeTempController extends Controller { } const record = await this.profileRepo.findOneBy({ id }); - const before = structuredClone(record); - // เช็คว่ามี profileHistory ของ profile นี้หรือไม่ - const historyCount = await this.profileHistoryRepo.count({ - where: { profileEmployeeId: id }, - }); - - // ถ้าไม่มีเลย ให้บันทึกข้อมูลเริ่มต้น (ก่อน update) ลงไปก่อน - if (historyCount === 0) { - await this.profileHistoryRepo.save( - Object.assign(new ProfileEmployeeHistory(), { - ...before, - birthDateOld: before?.birthDate, - profileEmployeeId: id, - id: undefined, - }), - ); - } - if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้"); if (body.employeeClass == null || body.employeeClass == undefined || body.employeeClass == "") { diff --git a/src/controllers/ProfileGovernmentEmployeeController.ts b/src/controllers/ProfileGovernmentEmployeeController.ts index 7fdeb9a7..d97a452a 100644 --- a/src/controllers/ProfileGovernmentEmployeeController.ts +++ b/src/controllers/ProfileGovernmentEmployeeController.ts @@ -115,7 +115,7 @@ export class ProfileGovernmentEmployeeController extends Controller { record.posType == null && record.posLevel == null ? null : `${record.posType.posTypeShortName} ${record.posLevel.posLevelName}`, //ระดับ - posMasterNo: posMaster == null ? null : `${orgShortName} ${[posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ')}`, //เลขที่ตำแหน่ง + posMasterNo: posMaster == null ? null : `${orgShortName} ${posMaster.posMasterNoPrefix ?? ''}${posMaster.posMasterNo ?? ''}${posMaster.posMasterNoSuffix ?? ''}`, //เลขที่ตำแหน่ง posType: record.posType == null ? null : record.posType.posTypeName, //ประเภท dateLeave: record.birthDate == null ? null : calculateRetireDate(record.birthDate), dateRetireLaw: record.dateRetireLaw ?? null, @@ -281,7 +281,7 @@ export class ProfileGovernmentEmployeeController extends Controller { record?.isLeave == false ? posMaster == null ? null - : `${orgShortName} ${[posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ')}` + : `${orgShortName} ${posMaster.posMasterNoPrefix ?? ''}${posMaster.posMasterNo ?? ''}${posMaster.posMasterNoSuffix ?? ''}` : posNoLeave /*record && record?.profileSalary.length > 0 ? `${record?.profileSalary[0].posNoAbb} ${record?.profileSalary[0].posNo}` : null*/, //เลขที่ตำแหน่ง @@ -441,7 +441,7 @@ export class ProfileGovernmentEmployeeController extends Controller { record?.isLeave == false ? posMaster == null ? null - : `${orgShortName} ${[posMaster.posMasterNoPrefix, posMaster.posMasterNo, posMaster.posMasterNoSuffix].filter((p) => p !== null && p !== undefined && p !== '').join(' ')}` + : `${orgShortName} ${posMaster.posMasterNoPrefix ?? ''}${posMaster.posMasterNo ?? ''}${posMaster.posMasterNoSuffix ?? ''}` : posNoLeave /*record && record.profileSalary.length > 0 ? `${record?.profileSalary[0].posNoAbb} ${record?.profileSalary[0].posNo}` : null*/, //เลขที่ตำแหน่ง diff --git a/src/controllers/ProfileSalaryController.ts b/src/controllers/ProfileSalaryController.ts index 8abe9aa2..277ac081 100644 --- a/src/controllers/ProfileSalaryController.ts +++ b/src/controllers/ProfileSalaryController.ts @@ -23,21 +23,12 @@ import { ProfileEmployee } from "../entities/ProfileEmployee"; import { In, IsNull, LessThan, MoreThan, Not } from "typeorm"; import permission from "../interfaces/permission"; import { setLogDataDiff } from "../interfaces/utils"; -import { normalizeDurationSumSimple } from "../utils/tenure"; -import { - TenurePositionOfficer, - CreateTenurePositionOfficer, -} from "../entities/TenurePositionOfficer"; -import { TenureLevelOfficer, CreateTenureLevelOfficer } from "../entities/TenureLevelOfficer"; -import { - TenurePositionEmployee, - CreateTenurePositionEmployee, -} from "../entities/TenurePositionEmployee"; -import { TenureLevelEmployee, CreateTenureLevelEmployee } from "../entities/TenureLevelEmployee"; -import { - TenurePositionExecutiveOfficer, - CreateTenurePositionExecutiveOfficer, -} from "../entities/TenurePositionExecutiveOfficer"; +import { calculateTenure } from "../utils/tenure"; +import { TenurePositionOfficer } from "../entities/TenurePositionOfficer"; +import { TenureLevelOfficer } from "../entities/TenureLevelOfficer"; +import { TenurePositionEmployee } from "../entities/TenurePositionEmployee"; +import { TenureLevelEmployee } from "../entities/TenureLevelEmployee"; +import { TenurePositionExecutiveOfficer } from "../entities/TenurePositionExecutiveOfficer"; import { Command } from "../entities/Command"; import { OrgRoot } from "../entities/OrgRoot"; import { OrgRevision } from "../entities/OrgRevision"; @@ -55,303 +46,138 @@ export class ProfileSalaryController extends Controller { private profileEmployeeRepo = AppDataSource.getRepository(ProfileEmployee); private salaryRepo = AppDataSource.getRepository(ProfileSalary); private salaryHistoryRepo = AppDataSource.getRepository(ProfileSalaryHistory); + private positionOfficerRepo = AppDataSource.getRepository(TenurePositionOfficer); + private positionEmployeeRepo = AppDataSource.getRepository(TenurePositionEmployee); + private levelOfficerRepo = AppDataSource.getRepository(TenureLevelOfficer); + private levelEmployeeRepo = AppDataSource.getRepository(TenureLevelEmployee); + private positionExecutiveOfficerRepo = AppDataSource.getRepository( + TenurePositionExecutiveOfficer, + ); private commandRepository = AppDataSource.getRepository(Command); private orgRootRepository = AppDataSource.getRepository(OrgRoot); + private orgRevisionRepository = AppDataSource.getRepository(OrgRevision); + private positionRepo = AppDataSource.getRepository(Position); private registryRepo = AppDataSource.getRepository(Registry); private registryEmployeeRepo = AppDataSource.getRepository(RegistryEmployee); @Get("TenurePositionOfficer") public async cronjobTenurePositionOfficer() { + let data: any = []; + await this.positionOfficerRepo.clear(); + const profile = await this.profileRepo.find(); const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today"); const baseCurrentDate = CURRENT_DATE[0].today; - - const profiles = await this.profileRepo.find({ - select: ["id", "position", "isLeave", "leaveDate"], - where: { position: Not(IsNull()) }, - }); - - const BATCH_SIZE = 50; - let successCount = 0; - let failCount = 0; - const allData: CreateTenurePositionOfficer[] = []; - - for (let i = 0; i < profiles.length; i += BATCH_SIZE) { - const batch = profiles.slice(i, Math.min(i + BATCH_SIZE, profiles.length)); - const results = await Promise.allSettled( - batch.map((profile) => - this.processSingleProfileForTenurePositionOfficer(profile, baseCurrentDate), - ), - ); - - results.forEach((result) => { - if (result.status === "fulfilled" && result.value) { - allData.push(result.value); - successCount++; - } else { - failCount++; - } - }); - } - - await AppDataSource.transaction(async (transactionalEntityManager) => { - await transactionalEntityManager.delete(TenurePositionOfficer, {}); - if (allData.length > 0) { - const entities = allData.map((data) => { - const entity = new TenurePositionOfficer(); - Object.assign(entity, data); - return entity; - }); - await transactionalEntityManager.save(TenurePositionOfficer, entities); - } - }); - - return new HttpSuccess({ - message: `อัปเดต tenure position officer สำเร็จ`, - total: profiles.length, - success: successCount, - failed: failCount, - }); - } - - private async processSingleProfileForTenurePositionOfficer( - profile: Pick, - baseCurrentDate: string, - ): Promise { - try { + for await (const x of profile) { + // Use leave date if available and valid, otherwise use current date let _currentDate = baseCurrentDate; - if (profile.isLeave && profile.leaveDate) { - _currentDate = Extension.toDateOnlyString(profile.leaveDate); + if (x.isLeave && x.leaveDate) { + _currentDate = Extension.toDateOnlyString(x.leaveDate); } - const position = await AppDataSource.query("CALL GetProfileSalaryPosition(?, ?)", [ - profile.id, + x.id, _currentDate, ]); const _position = position.length > 0 ? position[0] : []; - const mapPosition = _position.length > 1 ? _position.slice(1).map((curr: any, index: number) => ({ + days_diff: curr.days_diff, positionName: _position[index]?.positionName, - year: - curr.Years !== null && curr.Years !== undefined - ? Math.floor(Number(curr.Years)) - : 0, - month: - curr.Months !== null && curr.Months !== undefined - ? Math.floor(Number(curr.Months)) - : 0, - day: - curr.Days !== null && curr.Days !== undefined ? Math.floor(Number(curr.Days)) : 0, })) : []; - - const currentTenure = mapPosition.find((curr: any) => curr.positionName === profile.position); - - if (currentTenure) { - const normalized = normalizeDurationSumSimple( - currentTenure.year, - currentTenure.month, - currentTenure.day, + const calDayDiff = mapPosition + .filter((curr: any) => curr.positionName == x.position) + .reduce( + (acc: any, curr: any) => { + acc.days_diff += Number(curr.days_diff) || 0; + acc.positionName = curr.positionName; + return acc; + }, + { days_diff: 0, positionName: null }, ); - return { - profileId: profile.id, - positionName: currentTenure.positionName, - days_diff: null, - Years: normalized.years, - Months: normalized.months, - Days: normalized.days, - }; - } - return null; - } catch (error) { - return null; + const { year, month, day } = calculateTenure(calDayDiff.days_diff); + const mapData: any = { + profileId: x.id, + positionName: calDayDiff.positionName, + days_diff: calDayDiff.days_diff, + Years: year, + Months: month, + Days: day, + }; + data.push(mapData); } + await this.positionOfficerRepo.save(data); + + return new HttpSuccess(); } @Get("TenurePositionEmployee") public async cronjobTenurePositionEmployee() { + let data: any = []; + await this.positionEmployeeRepo.clear(); const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today"); const baseCurrentDate = CURRENT_DATE[0].today; - - const profiles = await this.profileEmployeeRepo.find({ - select: ["id", "position", "isLeave", "leaveDate"], - where: { position: Not(IsNull()) }, - }); - - const BATCH_SIZE = 50; - let successCount = 0; - let failCount = 0; - const allData: CreateTenurePositionEmployee[] = []; - - for (let i = 0; i < profiles.length; i += BATCH_SIZE) { - const batch = profiles.slice(i, Math.min(i + BATCH_SIZE, profiles.length)); - const results = await Promise.allSettled( - batch.map((profile) => - this.processSingleProfileForTenurePositionEmployee(profile, baseCurrentDate), - ), - ); - - results.forEach((result) => { - if (result.status === "fulfilled" && result.value) { - allData.push(result.value); - successCount++; - } else { - failCount++; - } - }); - } - - await AppDataSource.transaction(async (transactionalEntityManager) => { - await transactionalEntityManager.delete(TenurePositionEmployee, {}); - if (allData.length > 0) { - const entities = allData.map((data) => { - const entity = new TenurePositionEmployee(); - Object.assign(entity, data); - return entity; - }); - await transactionalEntityManager.save(TenurePositionEmployee, entities); - } - }); - - return new HttpSuccess({ - message: `อัปเดต tenure position employee สำเร็จ`, - total: profiles.length, - success: successCount, - failed: failCount, - }); - } - - private async processSingleProfileForTenurePositionEmployee( - profile: Pick, - baseCurrentDate: string, - ): Promise { - try { + const profile = await this.profileEmployeeRepo.find(); + for await (const x of profile) { + // Use leave date if available and valid, otherwise use current date let _currentDate = baseCurrentDate; - if (profile.isLeave && profile.leaveDate) { - _currentDate = Extension.toDateOnlyString(profile.leaveDate); + if (x?.isLeave && x.leaveDate) { + _currentDate = Extension.toDateOnlyString(x.leaveDate); } - const position = await AppDataSource.query("CALL GetProfileEmployeeSalaryPosition(?, ?)", [ - profile.id, + x.id, _currentDate, ]); const _position = position.length > 0 ? position[0] : []; - const mapPosition = _position.length > 1 ? _position.slice(1).map((curr: any, index: number) => ({ + days_diff: curr.days_diff, positionName: _position[index]?.positionName, - year: - curr.Years !== null && curr.Years !== undefined - ? Math.floor(Number(curr.Years)) - : 0, - month: - curr.Months !== null && curr.Months !== undefined - ? Math.floor(Number(curr.Months)) - : 0, - day: - curr.Days !== null && curr.Days !== undefined ? Math.floor(Number(curr.Days)) : 0, })) : []; - - const currentTenure = mapPosition.find((curr: any) => curr.positionName === profile.position); - - if (currentTenure) { - const normalized = normalizeDurationSumSimple( - currentTenure.year, - currentTenure.month, - currentTenure.day, + const calDayDiff = mapPosition + .filter((curr: any) => curr.positionName == x.position) + .reduce( + (acc: any, curr: any) => { + acc.days_diff += Number(curr.days_diff) || 0; + acc.positionName = curr.positionName; + return acc; + }, + { days_diff: 0, positionName: null }, ); - return { - profileEmployeeId: profile.id, - positionName: currentTenure.positionName, - days_diff: null, - Years: normalized.years, - Months: normalized.months, - Days: normalized.days, - }; - } - return null; - } catch (error) { - return null; + const { year, month, day } = calculateTenure(calDayDiff.days_diff); + const mapData: any = { + profileEmployeeId: x.id, + positionName: calDayDiff.positionName, + days_diff: calDayDiff.days_diff, + Years: year, + Months: month, + Days: day, + }; + data.push(mapData); } + await this.positionEmployeeRepo.save(data); + + return new HttpSuccess(); } @Get("TenureLevelOfficer") public async cronjobTenureLevelOfficer() { + let data: any = []; + await this.levelOfficerRepo.clear(); + const profile = await this.profileRepo.find({ relations: ["posLevel", "posType"] }); const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today"); const baseCurrentDate = CURRENT_DATE[0].today; - - const profiles = await this.profileRepo.find({ - relations: ["posLevel", "posType"], - select: ["id", "isLeave", "leaveDate", "posLevel", "posType"], - where: { - posLevel: Not(IsNull()), - posType: Not(IsNull()), - }, - }); - - const BATCH_SIZE = 50; - let successCount = 0; - let failCount = 0; - const allData: CreateTenureLevelOfficer[] = []; - - for (let i = 0; i < profiles.length; i += BATCH_SIZE) { - const batch = profiles.slice(i, Math.min(i + BATCH_SIZE, profiles.length)); - const results = await Promise.allSettled( - batch.map((profile) => - this.processSingleProfileForTenureLevelOfficer(profile, baseCurrentDate), - ), - ); - - results.forEach((result) => { - if (result.status === "fulfilled" && result.value) { - allData.push(result.value); - successCount++; - } else { - failCount++; - } - }); - } - - await AppDataSource.transaction(async (transactionalEntityManager) => { - await transactionalEntityManager.delete(TenureLevelOfficer, {}); - if (allData.length > 0) { - const entities = allData.map((data) => { - const entity = new TenureLevelOfficer(); - Object.assign(entity, data); - return entity; - }); - await transactionalEntityManager.save(TenureLevelOfficer, entities); - } - }); - - return new HttpSuccess({ - message: `อัปเดต tenure level officer สำเร็จ`, - total: profiles.length, - success: successCount, - failed: failCount, - }); - } - - private async processSingleProfileForTenureLevelOfficer( - profile: Pick & { - posLevel?: { posLevelName?: string } | null; - posType?: { posTypeName?: string } | null; - }, - baseCurrentDate: string, - ): Promise { - try { + for await (const x of profile) { + // Use leave date if available and valid, otherwise use current date let _currentDate = baseCurrentDate; - if (profile.isLeave && profile.leaveDate) { - _currentDate = Extension.toDateOnlyString(profile.leaveDate); + if (x?.isLeave && x.leaveDate) { + _currentDate = Extension.toDateOnlyString(x.leaveDate); } - const positionLevel = await AppDataSource.query("CALL GetProfileSalaryLevel(?, ?)", [ - profile.id, + x.id, _currentDate, ]); const _positionLevel = positionLevel.length > 0 ? positionLevel[0] : []; - const mapPositionLevel = _positionLevel.length > 1 ? _positionLevel.slice(1).map((curr: any, index: number) => ({ @@ -359,24 +185,13 @@ export class ProfileSalaryController extends Controller { positionType: _positionLevel[index]?.positionType, positionLevel: _positionLevel[index]?.positionLevel, positionCee: _positionLevel[index]?.positionCee, - year: - curr.Years !== null && curr.Years !== undefined - ? Math.floor(Number(curr.Years)) - : 0, - month: - curr.Months !== null && curr.Months !== undefined - ? Math.floor(Number(curr.Months)) - : 0, - day: - curr.Days !== null && curr.Days !== undefined ? Math.floor(Number(curr.Days)) : 0, })) : []; - const calDayDiff = mapPositionLevel .filter( (curr: any) => - curr.positionLevel === (profile.posLevel?.posLevelName ?? null) && - curr.positionType === (profile.posType?.posTypeName ?? null), + curr.positionLevel == (x.posLevel?.posLevelName ?? null) && + curr.positionType == (x.posType?.posTypeName ?? null), ) .reduce( (acc: any, curr: any) => { @@ -384,118 +199,45 @@ export class ProfileSalaryController extends Controller { acc.positionType = curr.positionType; acc.positionLevel = curr.positionLevel; acc.positionCee = curr.positionCee; - acc.year += curr.year; - acc.month += curr.month; - acc.day += curr.day; return acc; }, - { - days_diff: 0, - positionType: null, - positionLevel: null, - positionCee: null, - year: 0, - month: 0, - day: 0, - }, + { days_diff: 0, positionType: null, positionLevel: null, positionCee: null }, ); - - const normalized = normalizeDurationSumSimple( - calDayDiff.year, - calDayDiff.month, - calDayDiff.day, - ); - - return { - profileId: profile.id, + const { year, month, day } = calculateTenure(calDayDiff.days_diff); + const mapData: any = { + profileId: x.id, positionType: calDayDiff.positionType, positionLevel: calDayDiff.positionLevel, positionCee: calDayDiff.positionCee, days_diff: calDayDiff.days_diff, - Years: profile.posLevel == null ? 0 : normalized.years, - Months: profile.posLevel == null ? 0 : normalized.months, - Days: profile.posLevel == null ? 0 : normalized.days, + Years: x.posLevel == null ? 0 : year.toFixed(4), + Months: x.posLevel == null ? 0 : month.toFixed(4), + Days: x.posLevel == null ? 0 : day.toFixed(4), }; - } catch (error) { - return null; + data.push(mapData); } + await this.levelOfficerRepo.save(data); + + return new HttpSuccess(); } @Get("TenureLevelEmployee") public async cronjobTenureLevelEmployee() { + let data: any = []; + await this.levelEmployeeRepo.clear(); + const profile = await this.profileEmployeeRepo.find({ relations: ["posLevel", "posType"] }); const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today"); const baseCurrentDate = CURRENT_DATE[0].today; - - const profiles = await this.profileEmployeeRepo.find({ - relations: ["posLevel", "posType"], - select: ["id", "isLeave", "leaveDate", "posLevel", "posType"], - where: { - posLevel: Not(IsNull()), - posType: Not(IsNull()), - }, - }); - - const BATCH_SIZE = 50; - let successCount = 0; - let failCount = 0; - const allData: CreateTenureLevelEmployee[] = []; - - for (let i = 0; i < profiles.length; i += BATCH_SIZE) { - const batch = profiles.slice(i, Math.min(i + BATCH_SIZE, profiles.length)); - const results = await Promise.allSettled( - batch.map((profile) => - this.processSingleProfileForTenureLevelEmployee(profile, baseCurrentDate), - ), - ); - - results.forEach((result) => { - if (result.status === "fulfilled" && result.value) { - allData.push(result.value); - successCount++; - } else { - failCount++; - } - }); - } - - await AppDataSource.transaction(async (transactionalEntityManager) => { - await transactionalEntityManager.delete(TenureLevelEmployee, {}); - if (allData.length > 0) { - const entities = allData.map((data) => { - const entity = new TenureLevelEmployee(); - Object.assign(entity, data); - return entity; - }); - await transactionalEntityManager.save(TenureLevelEmployee, entities); - } - }); - - return new HttpSuccess({ - message: `อัปเดต tenure level employee สำเร็จ`, - total: profiles.length, - success: successCount, - failed: failCount, - }); - } - - private async processSingleProfileForTenureLevelEmployee( - profile: Pick & { - posLevel?: { posLevelName?: string } | null; - posType?: { posTypeName?: string } | null; - }, - baseCurrentDate: string, - ): Promise { - try { + for await (const x of profile) { + // Use leave date if available and valid, otherwise use current date let _currentDate = baseCurrentDate; - if (profile.isLeave && profile.leaveDate) { - _currentDate = Extension.toDateOnlyString(profile.leaveDate); + if (x?.isLeave && x.leaveDate) { + _currentDate = Extension.toDateOnlyString(x.leaveDate); } - const positionLevel = await AppDataSource.query("CALL GetProfileEmployeeSalaryLevel(?, ?)", [ - profile.id, + x.id, _currentDate, ]); const _positionLevel = positionLevel.length > 0 ? positionLevel[0] : []; - const mapPositionLevel = _positionLevel.length > 1 ? _positionLevel.slice(1).map((curr: any, index: number) => ({ @@ -503,24 +245,13 @@ export class ProfileSalaryController extends Controller { positionType: _positionLevel[index]?.positionType, positionLevel: _positionLevel[index]?.positionLevel, positionCee: _positionLevel[index]?.positionCee, - year: - curr.Years !== null && curr.Years !== undefined - ? Math.floor(Number(curr.Years)) - : 0, - month: - curr.Months !== null && curr.Months !== undefined - ? Math.floor(Number(curr.Months)) - : 0, - day: - curr.Days !== null && curr.Days !== undefined ? Math.floor(Number(curr.Days)) : 0, })) : []; - const calDayDiff = mapPositionLevel .filter( (curr: any) => - curr.positionLevel === (profile.posLevel?.posLevelName ?? null) && - curr.positionType === (profile.posType?.posTypeName ?? null), + curr.positionLevel == (x.posLevel?.posLevelName ?? null) && + curr.positionType == (x.posType?.posTypeName ?? null), ) .reduce( (acc: any, curr: any) => { @@ -528,161 +259,97 @@ export class ProfileSalaryController extends Controller { acc.positionType = curr.positionType; acc.positionLevel = curr.positionLevel; acc.positionCee = curr.positionCee; - acc.year += curr.year; - acc.month += curr.month; - acc.day += curr.day; return acc; }, - { - days_diff: 0, - positionType: null, - positionLevel: null, - positionCee: null, - year: 0, - month: 0, - day: 0, - }, + { days_diff: 0, positionType: null, positionLevel: null, positionCee: null }, ); - - const normalized = normalizeDurationSumSimple( - calDayDiff.year, - calDayDiff.month, - calDayDiff.day, - ); - - return { - profileEmployeeId: profile.id, + const { year, month, day } = calculateTenure(calDayDiff.days_diff); + const mapData: any = { + profileEmployeeId: x.id, positionType: calDayDiff.positionType, positionLevel: calDayDiff.positionLevel, positionCee: calDayDiff.positionCee, days_diff: calDayDiff.days_diff, - Years: profile.posLevel == null ? 0 : normalized.years, - Months: profile.posLevel == null ? 0 : normalized.months, - Days: profile.posLevel == null ? 0 : normalized.days, + Years: x.posLevel == null ? 0 : year.toFixed(4), + Months: x.posLevel == null ? 0 : month.toFixed(4), + Days: x.posLevel == null ? 0 : day.toFixed(4), }; - } catch (error) { - return null; + data.push(mapData); } + await this.levelEmployeeRepo.save(data); + + return new HttpSuccess(); } @Get("TenurePositionExecutiveOfficer") public async cronjobTenureExecutivePositionOfficer() { + let data: any = []; + await this.positionExecutiveOfficerRepo.clear(); + const profile = await this.profileRepo.find(); + const orgRevision = await this.orgRevisionRepository.findOne({ + select: ["id"], + where: { + orgRevisionIsDraft: false, + orgRevisionIsCurrent: true, + }, + }); const CURRENT_DATE = await AppDataSource.query("SELECT CURRENT_DATE() as today"); const baseCurrentDate = CURRENT_DATE[0].today; - - const profiles = await this.profileRepo.find({ - select: ["id", "posExecutive", "isLeave", "leaveDate"], - where: { posExecutive: Not(IsNull()) }, - }); - - const BATCH_SIZE = 50; - let successCount = 0; - let failCount = 0; - const allData: CreateTenurePositionExecutiveOfficer[] = []; - - for (let i = 0; i < profiles.length; i += BATCH_SIZE) { - const batch = profiles.slice(i, Math.min(i + BATCH_SIZE, profiles.length)); - const results = await Promise.allSettled( - batch.map((profile) => - this.processSingleProfileForTenureExecutivePositionOfficer(profile, baseCurrentDate), - ), - ); - - results.forEach((result) => { - if (result.status === "fulfilled" && result.value) { - allData.push(result.value); - successCount++; - } else { - failCount++; - } - }); - } - - await AppDataSource.transaction(async (transactionalEntityManager) => { - await transactionalEntityManager.delete(TenurePositionExecutiveOfficer, {}); - if (allData.length > 0) { - const entities = allData.map((data) => { - const entity = new TenurePositionExecutiveOfficer(); - Object.assign(entity, data); - return entity; - }); - await transactionalEntityManager.save(TenurePositionExecutiveOfficer, entities); - } - }); - - return new HttpSuccess({ - message: `อัปเดต tenure executive position officer สำเร็จ`, - total: profiles.length, - success: successCount, - failed: failCount, - }); - } - - private async processSingleProfileForTenureExecutivePositionOfficer( - profile: Pick, - baseCurrentDate: string, - ): Promise { - try { + for await (const x of profile) { + // Use leave date if available and valid, otherwise use current date let _currentDate = baseCurrentDate; - if (profile.isLeave && profile.leaveDate) { - _currentDate = Extension.toDateOnlyString(profile.leaveDate); + if (x?.isLeave && x.leaveDate) { + _currentDate = Extension.toDateOnlyString(x.leaveDate); } - + const position = await this.positionRepo.findOne({ + where: { + positionIsSelected: true, + posMaster: { + orgRevisionId: orgRevision?.id, + current_holderId: x.id, + }, + }, + order: { createdAt: "DESC" }, + relations: { + posExecutive: true, + }, + }); const positionExecutive = await AppDataSource.query("CALL GetProfileSalaryExecutive(?, ?)", [ - profile.id, + x.id, _currentDate, ]); const _position = positionExecutive.length > 0 ? positionExecutive[0] : []; - const mapPosition = _position.length > 1 ? _position.slice(1).map((curr: any, index: number) => ({ days_diff: curr.days_diff, positionExecutive: _position[index]?.positionExecutive, - year: - curr.Years !== null && curr.Years !== undefined - ? Math.floor(Number(curr.Years)) - : 0, - month: - curr.Months !== null && curr.Months !== undefined - ? Math.floor(Number(curr.Months)) - : 0, - day: - curr.Days !== null && curr.Days !== undefined ? Math.floor(Number(curr.Days)) : 0, })) : []; - + const _posExecutiveName = position?.posExecutive?.posExecutiveName; const calDayDiff = mapPosition - .filter((curr: any) => curr.positionExecutive === profile.posExecutive) + .filter((curr: any) => _posExecutiveName && curr.positionExecutive == _posExecutiveName) .reduce( (acc: any, curr: any) => { acc.days_diff += Number(curr.days_diff) || 0; acc.positionExecutive = curr.positionExecutive; - acc.year += curr.year; - acc.month += curr.month; - acc.day += curr.day; return acc; }, - { days_diff: 0, positionExecutive: null, year: 0, month: 0, day: 0 }, + { days_diff: 0, positionExecutive: null }, ); - - const normalized = normalizeDurationSumSimple( - calDayDiff.year, - calDayDiff.month, - calDayDiff.day, - ); - - return { - profileId: profile.id, + const { year, month, day } = calculateTenure(calDayDiff.days_diff); + const mapData: any = { + profileId: x.id, positionExecutiveName: calDayDiff.positionExecutive, days_diff: calDayDiff.days_diff, - Years: normalized.years, - Months: normalized.months, - Days: normalized.days, + Years: year.toFixed(4), + Months: month.toFixed(4), + Days: day.toFixed(4), }; - } catch (error) { - return null; + data.push(mapData); } + await this.positionExecutiveOfficerRepo.save(data); + return new HttpSuccess(); } @Get("Registry") @@ -929,12 +596,8 @@ export class ProfileSalaryController extends Controller { ? _position.slice(1).map((curr: any, index: number) => ({ days: curr.days_diff ? Number(curr.days_diff) : 0, // Use stored procedure's calculated values (calendar arithmetic) - year: - curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, - month: - curr.Months !== null && curr.Months !== undefined - ? Math.floor(Number(curr.Months)) - : 0, + year: curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, + month: curr.Months !== null && curr.Months !== undefined ? Math.floor(Number(curr.Months)) : 0, day: curr.Days !== null && curr.Days !== undefined ? Math.floor(Number(curr.Days)) : 0, name: _position[index]?.positionName, })) @@ -950,21 +613,19 @@ export class ProfileSalaryController extends Controller { existing.month += curr.month; existing.day += curr.day; } else { - existing = { - name: curr.name, - days: curr.days, - year: curr.year, - month: curr.month, - day: curr.day, - }; + existing = { name: curr.name, days: curr.days, year: curr.year, month: curr.month, day: curr.day }; acc.push(existing); } - // Normalize the summed values using calendar arithmetic - const normalized = normalizeDurationSumSimple(existing.year, existing.month, existing.day); - existing.year = normalized.years; - existing.month = normalized.months; - existing.day = normalized.days; + // Normalize the summed values (convert excess days to months, months to years) + while (existing.day >= 30) { + existing.month += Math.floor(existing.day / 30); + existing.day = existing.day % 30; + } + while (existing.month >= 12) { + existing.year += Math.floor(existing.month / 12); + existing.month = existing.month % 12; + } return acc; }, @@ -980,12 +641,8 @@ export class ProfileSalaryController extends Controller { ? _posLevel.slice(1).map((curr: any, index: number) => ({ days: curr.days_diff ? Number(curr.days_diff) : 0, // Use stored procedure's calculated values (calendar arithmetic) - year: - curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, - month: - curr.Months !== null && curr.Months !== undefined - ? Math.floor(Number(curr.Months)) - : 0, + year: curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, + month: curr.Months !== null && curr.Months !== undefined ? Math.floor(Number(curr.Months)) : 0, day: curr.Days !== null && curr.Days !== undefined ? Math.floor(Number(curr.Days)) : 0, name: !_posLevel[index]?.positionType && _posLevel[index]?.positionCee @@ -1007,21 +664,19 @@ export class ProfileSalaryController extends Controller { existing.month += curr.month; existing.day += curr.day; } else { - existing = { - name: curr.name, - days: curr.days, - year: curr.year, - month: curr.month, - day: curr.day, - }; + existing = { name: curr.name, days: curr.days, year: curr.year, month: curr.month, day: curr.day }; acc.push(existing); } - // Normalize the summed values using calendar arithmetic - const normalized = normalizeDurationSumSimple(existing.year, existing.month, existing.day); - existing.year = normalized.years; - existing.month = normalized.months; - existing.day = normalized.days; + // Normalize the summed values (convert excess days to months, months to years) + while (existing.day >= 30) { + existing.month += Math.floor(existing.day / 30); + existing.day = existing.day % 30; + } + while (existing.month >= 12) { + existing.year += Math.floor(existing.month / 12); + existing.month = existing.month % 12; + } return acc; }, @@ -1038,12 +693,8 @@ export class ProfileSalaryController extends Controller { ? _posExecutive.slice(1).map((curr: any, index: number) => ({ days: curr.days_diff ? Number(curr.days_diff) : 0, // Use stored procedure's calculated values (calendar arithmetic) - year: - curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, - month: - curr.Months !== null && curr.Months !== undefined - ? Math.floor(Number(curr.Months)) - : 0, + year: curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, + month: curr.Months !== null && curr.Months !== undefined ? Math.floor(Number(curr.Months)) : 0, day: curr.Days !== null && curr.Days !== undefined ? Math.floor(Number(curr.Days)) : 0, name: _posExecutive[index]?.positionExecutive, })) @@ -1059,21 +710,19 @@ export class ProfileSalaryController extends Controller { existing.month += curr.month; existing.day += curr.day; } else { - existing = { - name: curr.name, - days: curr.days, - year: curr.year, - month: curr.month, - day: curr.day, - }; + existing = { name: curr.name, days: curr.days, year: curr.year, month: curr.month, day: curr.day }; acc.push(existing); } - // Normalize the summed values using calendar arithmetic - const normalized = normalizeDurationSumSimple(existing.year, existing.month, existing.day); - existing.year = normalized.years; - existing.month = normalized.months; - existing.day = normalized.days; + // Normalize the summed values (convert excess days to months, months to years) + while (existing.day >= 30) { + existing.month += Math.floor(existing.day / 30); + existing.day = existing.day % 30; + } + while (existing.month >= 12) { + existing.year += Math.floor(existing.month / 12); + existing.month = existing.month % 12; + } return acc; }, @@ -1117,12 +766,8 @@ export class ProfileSalaryController extends Controller { ? _position.slice(1).map((curr: any, index: number) => ({ days: curr.days_diff ? Number(curr.days_diff) : 0, // Use stored procedure's calculated values (calendar arithmetic) - year: - curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, - month: - curr.Months !== null && curr.Months !== undefined - ? Math.floor(Number(curr.Months)) - : 0, + year: curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, + month: curr.Months !== null && curr.Months !== undefined ? Math.floor(Number(curr.Months)) : 0, day: curr.Days !== null && curr.Days !== undefined ? Math.floor(Number(curr.Days)) : 0, name: _position[index]?.positionName, })) @@ -1138,21 +783,19 @@ export class ProfileSalaryController extends Controller { existing.month += curr.month; existing.day += curr.day; } else { - existing = { - name: curr.name, - days: curr.days, - year: curr.year, - month: curr.month, - day: curr.day, - }; + existing = { name: curr.name, days: curr.days, year: curr.year, month: curr.month, day: curr.day }; acc.push(existing); } - // Normalize the summed values using calendar arithmetic - const normalized = normalizeDurationSumSimple(existing.year, existing.month, existing.day); - existing.year = normalized.years; - existing.month = normalized.months; - existing.day = normalized.days; + // Normalize the summed values (convert excess days to months, months to years) + while (existing.day >= 30) { + existing.month += Math.floor(existing.day / 30); + existing.day = existing.day % 30; + } + while (existing.month >= 12) { + existing.year += Math.floor(existing.month / 12); + existing.month = existing.month % 12; + } return acc; }, @@ -1169,12 +812,8 @@ export class ProfileSalaryController extends Controller { ? _posLevel.slice(1).map((curr: any, index: number) => ({ days: curr.days_diff ? Number(curr.days_diff) : 0, // Use stored procedure's calculated values (calendar arithmetic) - year: - curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, - month: - curr.Months !== null && curr.Months !== undefined - ? Math.floor(Number(curr.Months)) - : 0, + year: curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, + month: curr.Months !== null && curr.Months !== undefined ? Math.floor(Number(curr.Months)) : 0, day: curr.Days !== null && curr.Days !== undefined ? Math.floor(Number(curr.Days)) : 0, name: !_posLevel[index]?.positionType && _posLevel[index]?.positionCee @@ -1196,21 +835,19 @@ export class ProfileSalaryController extends Controller { existing.month += curr.month; existing.day += curr.day; } else { - existing = { - name: curr.name, - days: curr.days, - year: curr.year, - month: curr.month, - day: curr.day, - }; + existing = { name: curr.name, days: curr.days, year: curr.year, month: curr.month, day: curr.day }; acc.push(existing); } - // Normalize the summed values using calendar arithmetic - const normalized = normalizeDurationSumSimple(existing.year, existing.month, existing.day); - existing.year = normalized.years; - existing.month = normalized.months; - existing.day = normalized.days; + // Normalize the summed values (convert excess days to months, months to years) + while (existing.day >= 30) { + existing.month += Math.floor(existing.day / 30); + existing.day = existing.day % 30; + } + while (existing.month >= 12) { + existing.year += Math.floor(existing.month / 12); + existing.month = existing.month % 12; + } return acc; }, @@ -1227,12 +864,8 @@ export class ProfileSalaryController extends Controller { ? _posExecutive.slice(1).map((curr: any, index: number) => ({ days: curr.days_diff ? Number(curr.days_diff) : 0, // Use stored procedure's calculated values (calendar arithmetic) - year: - curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, - month: - curr.Months !== null && curr.Months !== undefined - ? Math.floor(Number(curr.Months)) - : 0, + year: curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, + month: curr.Months !== null && curr.Months !== undefined ? Math.floor(Number(curr.Months)) : 0, day: curr.Days !== null && curr.Days !== undefined ? Math.floor(Number(curr.Days)) : 0, name: _posExecutive[index]?.positionExecutive, })) @@ -1248,21 +881,19 @@ export class ProfileSalaryController extends Controller { existing.month += curr.month; existing.day += curr.day; } else { - existing = { - name: curr.name, - days: curr.days, - year: curr.year, - month: curr.month, - day: curr.day, - }; + existing = { name: curr.name, days: curr.days, year: curr.year, month: curr.month, day: curr.day }; acc.push(existing); } - // Normalize the summed values using calendar arithmetic - const normalized = normalizeDurationSumSimple(existing.year, existing.month, existing.day); - existing.year = normalized.years; - existing.month = normalized.months; - existing.day = normalized.days; + // Normalize the summed values (convert excess days to months, months to years) + while (existing.day >= 30) { + existing.month += Math.floor(existing.day / 30); + existing.day = existing.day % 30; + } + while (existing.month >= 12) { + existing.year += Math.floor(existing.month / 12); + existing.month = existing.month % 12; + } return acc; }, diff --git a/src/controllers/ProfileSalaryEmployeeController.ts b/src/controllers/ProfileSalaryEmployeeController.ts index 5f2ea997..44b93a5d 100644 --- a/src/controllers/ProfileSalaryEmployeeController.ts +++ b/src/controllers/ProfileSalaryEmployeeController.ts @@ -27,7 +27,7 @@ import { Profile } from "../entities/Profile"; import { In, LessThan, IsNull, MoreThan } from "typeorm"; import permission from "../interfaces/permission"; import { setLogDataDiff } from "../interfaces/utils"; -import { normalizeDurationSumSimple } from "../utils/tenure"; +import { calculateTenure } from "../utils/tenure"; import { Command } from "../entities/Command"; import { OrgRoot } from "../entities/OrgRoot"; import Extension from "../interfaces/extension"; @@ -161,14 +161,6 @@ export class ProfileSalaryEmployeeController extends Controller { _position.length > 1 ? _position.slice(1).map((curr: any, index: number) => ({ days: curr.days_diff ? Number(curr.days_diff) : 0, - // Use stored procedure's calculated values (calendar arithmetic) - year: - curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, - month: - curr.Months !== null && curr.Months !== undefined - ? Math.floor(Number(curr.Months)) - : 0, - day: curr.Days !== null && curr.Days !== undefined ? Math.floor(Number(curr.Days)) : 0, name: _position[index]?.positionName, })) : []; @@ -179,25 +171,15 @@ export class ProfileSalaryEmployeeController extends Controller { if (existing) { existing.days += curr.days; - existing.year += curr.year; - existing.month += curr.month; - existing.day += curr.day; } else { - existing = { - name: curr.name, - days: curr.days, - year: curr.year, - month: curr.month, - day: curr.day, - }; + existing = { name: curr.name, days: curr.days }; acc.push(existing); } - // Normalize the summed values using calendar arithmetic - const normalized = normalizeDurationSumSimple(existing.year, existing.month, existing.day); - existing.year = normalized.years; - existing.month = normalized.months; - existing.day = normalized.days; + const { year, month, day } = calculateTenure(existing.days); + existing.year = year; + existing.month = month; + existing.day = day; return acc; }, @@ -213,14 +195,6 @@ export class ProfileSalaryEmployeeController extends Controller { _posLevel.length > 1 ? _posLevel.slice(1).map((curr: any, index: number) => ({ days: curr.days_diff ? Number(curr.days_diff) : 0, - // Use stored procedure's calculated values (calendar arithmetic) - year: - curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, - month: - curr.Months !== null && curr.Months !== undefined - ? Math.floor(Number(curr.Months)) - : 0, - day: curr.Days !== null && curr.Days !== undefined ? Math.floor(Number(curr.Days)) : 0, name: !_posLevel[index]?.positionType && _posLevel[index]?.positionCee ? `ระดับ ${_posLevel[index]?.positionCee.trim()}` @@ -234,25 +208,15 @@ export class ProfileSalaryEmployeeController extends Controller { if (existing) { existing.days += curr.days; - existing.year += curr.year; - existing.month += curr.month; - existing.day += curr.day; } else { - existing = { - name: curr.name, - days: curr.days, - year: curr.year, - month: curr.month, - day: curr.day, - }; + existing = { name: curr.name, days: curr.days }; acc.push(existing); } - // Normalize the summed values using calendar arithmetic - const normalized = normalizeDurationSumSimple(existing.year, existing.month, existing.day); - existing.year = normalized.years; - existing.month = normalized.months; - existing.day = normalized.days; + const { year, month, day } = calculateTenure(existing.days); + existing.year = year; + existing.month = month; + existing.day = day; return acc; }, @@ -290,14 +254,6 @@ export class ProfileSalaryEmployeeController extends Controller { _position.length > 1 ? _position.slice(1).map((curr: any, index: number) => ({ days: curr.days_diff ? Number(curr.days_diff) : 0, - // Use stored procedure's calculated values (calendar arithmetic) - year: - curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, - month: - curr.Months !== null && curr.Months !== undefined - ? Math.floor(Number(curr.Months)) - : 0, - day: curr.Days !== null && curr.Days !== undefined ? Math.floor(Number(curr.Days)) : 0, name: _position[index]?.positionName, })) : []; @@ -308,25 +264,15 @@ export class ProfileSalaryEmployeeController extends Controller { if (existing) { existing.days += curr.days; - existing.year += curr.year; - existing.month += curr.month; - existing.day += curr.day; } else { - existing = { - name: curr.name, - days: curr.days, - year: curr.year, - month: curr.month, - day: curr.day, - }; + existing = { name: curr.name, days: curr.days }; acc.push(existing); } - // Normalize the summed values using calendar arithmetic - const normalized = normalizeDurationSumSimple(existing.year, existing.month, existing.day); - existing.year = normalized.years; - existing.month = normalized.months; - existing.day = normalized.days; + const { year, month, day } = calculateTenure(existing.days); + existing.year = year; + existing.month = month; + existing.day = day; return acc; }, @@ -342,14 +288,6 @@ export class ProfileSalaryEmployeeController extends Controller { _posLevel.length > 1 ? _posLevel.slice(1).map((curr: any, index: number) => ({ days: curr.days_diff ? Number(curr.days_diff) : 0, - // Use stored procedure's calculated values (calendar arithmetic) - year: - curr.Years !== null && curr.Years !== undefined ? Math.floor(Number(curr.Years)) : 0, - month: - curr.Months !== null && curr.Months !== undefined - ? Math.floor(Number(curr.Months)) - : 0, - day: curr.Days !== null && curr.Days !== undefined ? Math.floor(Number(curr.Days)) : 0, name: !_posLevel[index]?.positionType && _posLevel[index]?.positionCee ? `ระดับ ${_posLevel[index]?.positionCee.trim()}` @@ -363,25 +301,15 @@ export class ProfileSalaryEmployeeController extends Controller { if (existing) { existing.days += curr.days; - existing.year += curr.year; - existing.month += curr.month; - existing.day += curr.day; } else { - existing = { - name: curr.name, - days: curr.days, - year: curr.year, - month: curr.month, - day: curr.day, - }; + existing = { name: curr.name, days: curr.days }; acc.push(existing); } - // Normalize the summed values using calendar arithmetic - const normalized = normalizeDurationSumSimple(existing.year, existing.month, existing.day); - existing.year = normalized.years; - existing.month = normalized.months; - existing.day = normalized.days; + const { year, month, day } = calculateTenure(existing.days); + existing.year = year; + existing.month = month; + existing.day = day; return acc; }, diff --git a/src/controllers/ProfileSalaryTempController.ts b/src/controllers/ProfileSalaryTempController.ts index c166d22d..35279fbc 100644 --- a/src/controllers/ProfileSalaryTempController.ts +++ b/src/controllers/ProfileSalaryTempController.ts @@ -1791,56 +1791,4 @@ export class ProfileSalaryTempController extends Controller { await this.salaryRepo.save(sortLevel); return new HttpSuccess(); } - - /** - * API เรียงลำดับทะเบียนประวัติและเงินเดือนที่กำลังแก้ไขตามวันที่คำสั่งมีผล - * @summary API เรียงลำดับทะเบียนประวัติและเงินเดือนที่กำลังแก้ไขตามวันที่คำสั่งมีผล - */ - @Put("sort-order") - public async reorderSalaryByCommandDate( - @Request() req: RequestWithUser, - @Body() body: { profileId: string; type: "OFFICER" | "EMPLOYEE" }, - ) { - const isOfficer = body.type.toUpperCase() === "OFFICER"; - - // Step 1: SELECT ข้อมูลตาม profileId และ type - const salaryTemps = await this.salaryRepo.find({ - where: isOfficer ? { profileId: body.profileId } : { profileEmployeeId: body.profileId }, - }); - - if (salaryTemps.length === 0) { - throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งเงินเดือน"); - } - - // Step 2: เรียงลำดับตาม commandDateAffect (ASC) - // ถ้า commandDateAffect เท่ากัน ให้ใช้ order เดิมเป็น secondary sort - const sortedSalary = salaryTemps.sort((a, b) => { - // ถ้า commandDateAffect เป็น null ให้ถือว่าเป็นค่าน้อยสุด - const dateA = a.commandDateAffect ? new Date(a.commandDateAffect).getTime() : 0; - const dateB = b.commandDateAffect ? new Date(b.commandDateAffect).getTime() : 0; - - if (dateA !== dateB) { - return dateA - dateB; // เรียงตามวันที่คำสั่งมีผล - } - - // ถ้าวันที่เท่ากัน ให้ใช้ order เดิม - const orderA = a.order ?? 0; - const orderB = b.order ?? 0; - return orderA - orderB; - }); - - // Step 3: UPDATE ฟิลด์ order ตามการเรียงใหม่ - const dateNow = new Date(); - const updatedSalary = sortedSalary.map((item, index) => ({ - ...item, - order: index + 1, - lastUpdateUserId: req.user.sub, - lastUpdateFullName: req.user.name, - lastUpdatedAt: dateNow, - })); - - await this.salaryRepo.save(updatedSalary); - - return new HttpSuccess(); - } } diff --git a/src/controllers/ScriptProfileOrgController.ts b/src/controllers/ScriptProfileOrgController.ts index 0494be98..aa6908e2 100644 --- a/src/controllers/ScriptProfileOrgController.ts +++ b/src/controllers/ScriptProfileOrgController.ts @@ -38,10 +38,6 @@ export class ScriptProfileOrgController extends Controller { process.env.CRONJOB_UPDATE_WINDOW_HOURS || "24", 10, ); - private readonly LEAVE_SERVICE_BATCH_SIZE = parseInt( - process.env.LEAVE_SERVICE_BATCH_SIZE || "50", - 10, - ); /** * Script to update profile's organizational structure in leave service and sync to Keycloak @@ -49,7 +45,7 @@ export class ScriptProfileOrgController extends Controller { * @summary Update org structure for profiles updated within a certain time window and sync to Keycloak */ @Post("update-org") - public async cronjobUpdateOrg(@Request() _request: RequestWithUser) { + public async cronjobUpdateOrg(@Request() request: RequestWithUser) { // Idempotency check - prevent concurrent runs if (this.isRunning) { console.log("cronjobUpdateOrg: Job already running, skipping this execution"); @@ -180,6 +176,21 @@ export class ScriptProfileOrgController extends Controller { }); } + // Update profile's org structure in leave service by calling API + console.log("cronjobUpdateOrg: Calling leave service API", { + payloadCount: payloads.length, + }); + + await axios.put(`${process.env.API_URL}/leave-beginning/schedule/update-dna`, payloads, { + headers: { + "Content-Type": "application/json", + api_key: process.env.API_KEY, + }, + timeout: 30000, // 30 second timeout + }); + + console.log("cronjobUpdateOrg: Leave service API call successful"); + // Group profile IDs by type for proper syncing const profileIdsByType = this.groupProfileIdsByType(payloads); @@ -245,90 +256,16 @@ export class ScriptProfileOrgController extends Controller { syncResults.failed += typeResult.failed; } - // Update profile's org structure in leave service by calling API - console.log("cronjobUpdateOrg: Calling leave service API with chunking", { - payloadCount: payloads.length, - batchSize: this.LEAVE_SERVICE_BATCH_SIZE, - expectedBatches: Math.ceil(payloads.length / this.LEAVE_SERVICE_BATCH_SIZE), - }); - - const chunks = this.chunkArray(payloads, this.LEAVE_SERVICE_BATCH_SIZE); - const leaveServiceResults = { - total: payloads.length, - success: 0, - failed: 0, - batchesCompleted: 0, - batchesFailed: 0, - }; - - for (let i = 0; i < chunks.length; i++) { - const chunk = chunks[i]; - const batchNumber = i + 1; - - console.log( - `cronjobUpdateOrg: Processing leave service batch ${batchNumber}/${chunks.length}`, - { - batchSize: chunk.length, - batchRange: `${i * this.LEAVE_SERVICE_BATCH_SIZE + 1}-${Math.min( - (batchNumber + 1) * this.LEAVE_SERVICE_BATCH_SIZE, - payloads.length, - )}`, - }, - ); - - try { - await axios.put( - `${process.env.API_URL}/leave-beginning/schedule/update-dna`, - chunk, - { - headers: { - "Content-Type": "application/json", - api_key: process.env.API_KEY, - }, - timeout: 120000, // 120 second timeout per chunk - }, - ); - - leaveServiceResults.success += chunk.length; - leaveServiceResults.batchesCompleted++; - - console.log(`cronjobUpdateOrg: Leave service batch ${batchNumber}/${chunks.length} completed`, { - success: chunk.length, - }); - } catch (error: any) { - leaveServiceResults.failed += chunk.length; - leaveServiceResults.batchesFailed++; - - console.error( - `cronjobUpdateOrg: Leave service batch ${batchNumber}/${chunks.length} failed`, - { - error: error.message, - batchSize: chunk.length, - responseStatus: error.response?.status, - responseData: error.response?.data, - }, - ); - - // Continue processing remaining batches - } - } - - console.log("cronjobUpdateOrg: Leave service API call completed", { - ...leaveServiceResults, - }); - const duration = Date.now() - startTime; console.log("cronjobUpdateOrg: Job completed", { duration: `${duration}ms`, processed: payloads.length, - leaveServiceResults, syncResults, }); return new HttpSuccess({ message: "Update org completed", processed: payloads.length, - leaveServiceResults, syncResults, duration: `${duration}ms`, }); diff --git a/src/controllers/UserController.ts b/src/controllers/UserController.ts index 4902ce0f..2120dcff 100644 --- a/src/controllers/UserController.ts +++ b/src/controllers/UserController.ts @@ -580,27 +580,18 @@ export class KeycloakController extends Controller { new Brackets((qb) => { qb.orWhere( body.keyword != null && body.keyword != "" - ? `profile.citizenId LIKE :keyword` + ? `profile.citizenId like '%${body.keyword}%'` : "1=1", - { - keyword: `%${body.keyword}%`, - } ) .orWhere( body.keyword != null && body.keyword != "" - ? `profile.email LIKE :keyword` + ? `profile.email like '%${body.keyword}%'` : "1=1", - { - keyword: `%${body.keyword}%`, - } ) .orWhere( body.keyword != null && body.keyword != "" - ? `CONCAT(profile.prefix, profile.firstName," ",profile.lastName) LIKE :keyword` + ? `CONCAT(profile.prefix, profile.firstName," ",profile.lastName) like '%${body.keyword}%'` : "1=1", - { - keyword: `%${body.keyword}%`, - } ); }), ) @@ -634,27 +625,18 @@ export class KeycloakController extends Controller { new Brackets((qb) => { qb.orWhere( body.keyword != null && body.keyword != "" - ? `profileEmployee.citizenId LIKE :keyword` + ? `profileEmployee.citizenId like '%${body.keyword}%'` : "1=1", - { - keyword: `%${body.keyword}%`, - } ) .orWhere( body.keyword != null && body.keyword != "" - ? `profileEmployee.email LIKE :keyword` + ? `profileEmployee.email like '%${body.keyword}%'` : "1=1", - { - keyword: `%${body.keyword}%`, - } ) .orWhere( body.keyword != null && body.keyword != "" - ? `CONCAT(profileEmployee.prefix, profileEmployee.firstName," ",profileEmployee.lastName) LIKE :keyword` + ? `CONCAT(profileEmployee.prefix, profileEmployee.firstName," ",profileEmployee.lastName) like '%${body.keyword}%'` : "1=1", - { - keyword: `%${body.keyword}%`, - } ); }), ) diff --git a/src/entities/Command.ts b/src/entities/Command.ts index e6af1be8..c6b26626 100644 --- a/src/entities/Command.ts +++ b/src/entities/Command.ts @@ -34,14 +34,6 @@ export class Command extends EntityBase { }) issue: string; - @Column({ - nullable: true, - comment: "ชื่อย่อหน่วยงานที่ออกคำสั่ง", - length: 16, - default: null, - }) - shortName: string; - @Column({ nullable: true, comment: "เลขที่คำสั่ง", diff --git a/src/entities/PosMasterEmployeeHistory.ts b/src/entities/PosMasterEmployeeHistory.ts index e0aa7853..b0418644 100644 --- a/src/entities/PosMasterEmployeeHistory.ts +++ b/src/entities/PosMasterEmployeeHistory.ts @@ -99,51 +99,51 @@ export class PosMasterEmployeeHistory extends EntityBase { }) ancestorDNA: string; - @Column({ - nullable: true, - length: 40, - comment: "คีย์นอก(FK)ของตาราง profileEmployee", - default: null, - }) - profileEmployeeId: string; + // @Column({ + // nullable: true, + // length: 40, + // comment: "คีย์นอก(FK)ของตาราง profile", + // default: null, + // }) + // profileId: string; - @Column({ - nullable: true, - length: 40, - comment: "dna ของตาราง orgRoot", - default: null, - }) - rootDnaId: string; + // @Column({ + // nullable: true, + // length: 40, + // comment: "dna ของตาราง orgRoot", + // default: null, + // }) + // rootDnaId: string; - @Column({ - nullable: true, - length: 40, - comment: "dna ของตาราง orgChild1", - default: null, - }) - child1DnaId: string; + // @Column({ + // nullable: true, + // length: 40, + // comment: "dna ของตาราง orgChild1", + // default: null, + // }) + // child1DnaId: string; - @Column({ - nullable: true, - length: 40, - comment: "dna ของตาราง orgChild2", - default: null, - }) - child2DnaId: string; + // @Column({ + // nullable: true, + // length: 40, + // comment: "dna ของตาราง orgChild2", + // default: null, + // }) + // child2DnaId: string; - @Column({ - nullable: true, - length: 40, - comment: "dna ของตาราง orgChild3", - default: null, - }) - child3DnaId: string; + // @Column({ + // nullable: true, + // length: 40, + // comment: "dna ของตาราง orgChild3", + // default: null, + // }) + // child3DnaId: string; - @Column({ - nullable: true, - length: 40, - comment: "dna ของตาราง orgChild4", - default: null, - }) - child4DnaId: string; + // @Column({ + // nullable: true, + // length: 40, + // comment: "dna ของตาราง orgChild4", + // default: null, + // }) + // child4DnaId: string; } diff --git a/src/entities/ProfileDiscipline.ts b/src/entities/ProfileDiscipline.ts index 7a5f463d..0065528b 100644 --- a/src/entities/ProfileDiscipline.ts +++ b/src/entities/ProfileDiscipline.ts @@ -61,14 +61,6 @@ export class ProfileDiscipline extends EntityBase { default: null, }) refCommandNo: string; - - @Column({ - nullable: true, - length: 40, - comment: "คีย์นอก(FK)ของตาราง command", - default: null, - }) - refCommandId: string; @Column({ nullable: true, diff --git a/src/entities/ProfileDisciplineHistory.ts b/src/entities/ProfileDisciplineHistory.ts index d99a7263..e7dfee58 100644 --- a/src/entities/ProfileDisciplineHistory.ts +++ b/src/entities/ProfileDisciplineHistory.ts @@ -51,14 +51,6 @@ export class ProfileDisciplineHistory extends EntityBase { }) refCommandNo: string; - @Column({ - nullable: true, - length: 40, - comment: "คีย์นอก(FK)ของตาราง command", - default: null, - }) - refCommandId: string; - @Column({ nullable: true, comment: "ล้างมลทิน", diff --git a/src/entities/TenureLevelEmployee.ts b/src/entities/TenureLevelEmployee.ts index 5654e306..36ae0176 100644 --- a/src/entities/TenureLevelEmployee.ts +++ b/src/entities/TenureLevelEmployee.ts @@ -74,7 +74,7 @@ export class TenureLevelEmployee extends EntityBase { positionLevel: string; } -export class CreateTenureLevelEmployee { +export class CreateTenureLevelOfficer { profileEmployeeId: string; positionCee: string | null; days_diff: number | null; diff --git a/src/interfaces/permission.ts b/src/interfaces/permission.ts index 5d22d274..4c3063de 100644 --- a/src/interfaces/permission.ts +++ b/src/interfaces/permission.ts @@ -39,7 +39,7 @@ class CheckAuth { } }); } - public async PermissionOrg(req: RequestWithUser, system: string, action: string, isDirector?: boolean) { + public async PermissionOrg(req: RequestWithUser, system: string, action: string) { if ( req.headers.hasOwnProperty("api_key") && req.headers["api_key"] && @@ -56,7 +56,7 @@ class CheckAuth { return await new CallAPI() .GetData(req, `/org/permission/org/${system}/${action}`) .then(async (x) => { - let privilege = isDirector && isDirector === true ? "CHILD" : x.privilege; + let privilege = x.privilege; let data: any = { root: [null], @@ -288,9 +288,6 @@ class CheckAuth { public async PermissionOrgList(req: RequestWithUser, system: string) { return await this.PermissionOrg(req, system, "LIST"); } - public async PermissionIsDirectorOrgList(req: RequestWithUser, system: string, isDirector: boolean) { - return await this.PermissionOrg(req, system, "LIST", isDirector); - } public async PermissionOrgUpdate(req: RequestWithUser, system: string) { return await this.PermissionOrg(req, system, "UPDATE"); } diff --git a/src/interfaces/utils.ts b/src/interfaces/utils.ts index 3a48ab2b..347f28af 100644 --- a/src/interfaces/utils.ts +++ b/src/interfaces/utils.ts @@ -280,7 +280,7 @@ export async function removeProfileInOrganize(profileId: string, type: string) { await AppDataSource.getRepository(PosMaster) .createQueryBuilder() .update(PosMaster) - .set({ current_holderId: null, isSit: false }) + .set({ current_holderId: null }) .where("id = :id", { id: findProfileInposMaster?.id }) .execute(); @@ -293,7 +293,7 @@ export async function removeProfileInOrganize(profileId: string, type: string) { await AppDataSource.getRepository(PosMaster) .createQueryBuilder() .update(PosMaster) - .set({ next_holderId: null, isSit: false }) + .set({ next_holderId: null }) .where("id = :id", { id: findProfileInposMasterDraft?.id }) .execute(); @@ -326,7 +326,7 @@ export async function removeProfileInOrganize(profileId: string, type: string) { await AppDataSource.getRepository(EmployeePosMaster) .createQueryBuilder() .update(EmployeePosMaster) - .set({ current_holderId: null, isSit: false }) + .set({ current_holderId: null }) .where("id = :id", { id: findProfileInEmpPosMaster?.id }) .execute(); @@ -395,6 +395,43 @@ export async function checkReturnCommandType(commandId: string) { return true; } +export async function checkExceptCommandType(commandId: string) { + const commandRepository = AppDataSource.getRepository(Command); + const commandReciveRepository = AppDataSource.getRepository(CommandRecive); + const _type = await commandRepository.findOne({ + where: { + id: commandId, + }, + relations: ["commandType"], + }); + if (!["C-PM-25", "C-PM-26"].includes(String(_type?.commandType.code))) { + return { status: false, LeaveType: null, leaveRemark: null }; + } + const _commandRecive = await commandReciveRepository.findOne({ + where: { commandId: commandId }, + }); + + let _leaveType: string = ""; + switch (String(_type?.commandType.code)) { + case "C-PM-25": { + _leaveType = "DISCIPLINE_SUSPEND"; //คำสั่งพักจากราชการ + break; + } + case "C-PM-26": { + _leaveType = "DISCIPLINE_TEMP_SUSPEND"; //คำสั่งให้ออกจากราชการไว้ก่อน + break; + } + default: { + _leaveType = ""; + } + } + return { + status: true, + LeaveType: _leaveType, + leaveRemark: _commandRecive ? _commandRecive.remarkVertical : null, + }; +} + export async function checkCommandType(commandId: string) { const commandRepository = AppDataSource.getRepository(Command); const commandReciveRepository = AppDataSource.getRepository(CommandRecive); @@ -414,8 +451,6 @@ export async function checkCommandType(commandId: string) { "C-PM-23", "C-PM-19", "C-PM-20", - "C-PM-25", - "C-PM-26", "C-PM-43", ].includes(String(_type?.commandType.code)) ) { @@ -465,16 +500,6 @@ export async function checkCommandType(commandId: string) { _retireTypeName = "ลาออกจากราชการ"; break; } - case "C-PM-25": { - _leaveType = "DISCIPLINE_SUSPEND"; - _retireTypeName = "พักจากราชการ"; - break; - } - case "C-PM-26": { - _leaveType = "DISCIPLINE_TEMP_SUSPEND"; - _retireTypeName = "ให้ออกจากราชการไว้ก่อน"; - break; - } case "C-PM-43": { _leaveType = "RETIRE_OUT_EMP"; _retireTypeName = "ให้ออกจากราชการ"; @@ -726,23 +751,4 @@ export function resolveNodeId(data: any) { data.rootDnaId ?? null ); -} - -export function logPositionIsSelectedChange( - positionId: string, - oldValue: boolean, - newValue: boolean, - context: { - posMasterId?: string; - userId?: string; - endpoint?: string; - action?: string; - } -) { - if (oldValue !== newValue) { - console.log(`[positionIsSelected-DEBUG] Position ${positionId}: ${oldValue} -> ${newValue}`, { - ...context, - timestamp: new Date().toISOString(), - }); - } } \ No newline at end of file diff --git a/src/keycloak/index.ts b/src/keycloak/index.ts index f359a340..b59d5e81 100644 --- a/src/keycloak/index.ts +++ b/src/keycloak/index.ts @@ -1019,9 +1019,7 @@ export async function resetPassword(username: string) { if (!users.ok) { const errorText = await users.text(); - console.error( - `[resetPassword] Failed to search user. Status: ${users.status}, Error: ${errorText}`, - ); + console.error(`[resetPassword] Failed to search user. Status: ${users.status}, Error: ${errorText}`); return false; } @@ -1049,9 +1047,7 @@ export async function resetPassword(username: string) { if (!resetResponse.ok) { const errorText = await resetResponse.text(); - console.error( - `[resetPassword] Failed to send reset email. Status: ${resetResponse.status}, Error: ${errorText}`, - ); + console.error(`[resetPassword] Failed to send reset email. Status: ${resetResponse.status}, Error: ${errorText}`); return false; } @@ -1121,7 +1117,7 @@ export async function updateUserAttributes( return false; } - // console.log(`[updateUserAttributes] Successfully updated attributes for user ${userId}`); + console.log(`[updateUserAttributes] Successfully updated attributes for user ${userId}`); return true; } catch (error) { console.error(`[updateUserAttributes] Error updating attributes for user ${userId}:`, error); diff --git a/src/middlewares/auth.ts b/src/middlewares/auth.ts index fc006b33..9a571572 100644 --- a/src/middlewares/auth.ts +++ b/src/middlewares/auth.ts @@ -4,7 +4,6 @@ import { createDecoder, createVerifier } from "fast-jwt"; import HttpError from "../interfaces/http-error"; import HttpStatus from "../interfaces/http-status"; import { handleWebServiceAuth } from "./authWebService"; -import { handleInternalAuth } from "./authInternal"; if (!process.env.AUTH_PUBLIC_KEY && !process.env.AUTH_REALM_URL) { throw new Error("Require keycloak AUTH_PUBLIC_KEY or AUTH_REALM_URL."); @@ -40,11 +39,6 @@ export async function expressAuthentication( return { preferred_username: "bypassed" }; } - // เพิ่มการจัดการสำหรับ Internal Authentication (.NET service) - if (securityName === "internalAuth") { - return await handleInternalAuth(request); - } - // เพิ่มการจัดการสำหรับ Web Service Authentication if (securityName === "webServiceAuth") { return await handleWebServiceAuth(request); diff --git a/src/middlewares/authInternal.ts b/src/middlewares/authInternal.ts deleted file mode 100644 index 77da531c..00000000 --- a/src/middlewares/authInternal.ts +++ /dev/null @@ -1,30 +0,0 @@ -import * as express from "express"; -import HttpError from "../interfaces/http-error"; -import HttpStatus from "../interfaces/http-status"; - -// Internal Authentication (สำหรับ Internal Service เช่น .NET) -// ตรวจสอบ API Key จาก Environment Variable (API_KEY) -export async function handleInternalAuth(request: express.Request) { - // รองรับ header หลายรูปแบบ - const apiKey = - request.headers["api-key"] || request.headers["api_key"] || request.headers["apikey"]; - - if (!apiKey || typeof apiKey !== "string") { - throw new HttpError(HttpStatus.UNAUTHORIZED, "API Key is required"); - } - - // ตรวจสอบ API Key จาก Environment Variable (API_KEY) - if (apiKey !== process.env.API_KEY) { - console.log(`[InternalAuth] Invalid API key attempt: ${apiKey.substring(0, 5)}...`); - throw new HttpError(HttpStatus.UNAUTHORIZED, "Invalid API Key"); - } - - // console.log(`[InternalAuth] Authentication successful`); - - return { - sub: "internal_service", - preferred_username: "internal_service", - name: "Internal Service", - internalKey: true, - }; -} diff --git a/src/middlewares/authWebService.ts b/src/middlewares/authWebService.ts index 1f17b9cf..fa50b3fe 100644 --- a/src/middlewares/authWebService.ts +++ b/src/middlewares/authWebService.ts @@ -17,17 +17,7 @@ export async function handleWebServiceAuth(request: express.Request) { // ตรวจสอบ API Key กับฐานข้อมูล const apiKeyData = await AppDataSource.getRepository(ApiKey).findOne({ - select: { - id: true, - name: true, - keyApi: true, - accessType: true, - dnaRootId: true, - dnaChild1Id: true, - dnaChild2Id: true, - dnaChild3Id: true, - dnaChild4Id: true, - }, + select: { id: true, name: true, keyApi: true }, where: { keyApi: apiKey }, relations: ["apiNames"], }); @@ -50,12 +40,6 @@ export async function handleWebServiceAuth(request: express.Request) { name: apiKeyData.name, type: "web-service", accessApi: apiKeyData.apiNames.map((x) => x.id) ?? [], - accessType: apiKeyData.accessType, - dnaRootId: apiKeyData.dnaRootId, - dnaChild1Id: apiKeyData.dnaChild1Id, - dnaChild2Id: apiKeyData.dnaChild2Id, - dnaChild3Id: apiKeyData.dnaChild3Id, - dnaChild4Id: apiKeyData.dnaChild4Id, }; } diff --git a/src/middlewares/user.ts b/src/middlewares/user.ts index 09e32ef9..75c84d01 100644 --- a/src/middlewares/user.ts +++ b/src/middlewares/user.ts @@ -25,11 +25,5 @@ export type RequestWithUserWebService = Request & { id: string; name: string; accessApi: string[]; - accessType?: string; - dnaRootId?: string | null; - dnaChild1Id?: string | null; - dnaChild2Id?: string | null; - dnaChild3Id?: string | null; - dnaChild4Id?: string | null; }; }; diff --git a/src/migration/1779244154610-update_posMasterEmpHis_add_dna.ts b/src/migration/1779244154610-update_posMasterEmpHis_add_dna.ts deleted file mode 100644 index 5b7a4a1d..00000000 --- a/src/migration/1779244154610-update_posMasterEmpHis_add_dna.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; - -export class UpdatePosMasterEmpHisAddDna1779244154610 implements MigrationInterface { - name = 'UpdatePosMasterEmpHisAddDna1779244154610' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`posMasterEmployeeHistory\` ADD \`profileEmployeeId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง profileEmployee'`); - await queryRunner.query(`ALTER TABLE \`posMasterEmployeeHistory\` ADD \`rootDnaId\` varchar(40) NULL COMMENT 'dna ของตาราง orgRoot'`); - await queryRunner.query(`ALTER TABLE \`posMasterEmployeeHistory\` ADD \`child1DnaId\` varchar(40) NULL COMMENT 'dna ของตาราง orgChild1'`); - await queryRunner.query(`ALTER TABLE \`posMasterEmployeeHistory\` ADD \`child2DnaId\` varchar(40) NULL COMMENT 'dna ของตาราง orgChild2'`); - await queryRunner.query(`ALTER TABLE \`posMasterEmployeeHistory\` ADD \`child3DnaId\` varchar(40) NULL COMMENT 'dna ของตาราง orgChild3'`); - await queryRunner.query(`ALTER TABLE \`posMasterEmployeeHistory\` ADD \`child4DnaId\` varchar(40) NULL COMMENT 'dna ของตาราง orgChild4'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`posMasterEmployeeHistory\` DROP COLUMN \`child4DnaId\``); - await queryRunner.query(`ALTER TABLE \`posMasterEmployeeHistory\` DROP COLUMN \`child3DnaId\``); - await queryRunner.query(`ALTER TABLE \`posMasterEmployeeHistory\` DROP COLUMN \`child2DnaId\``); - await queryRunner.query(`ALTER TABLE \`posMasterEmployeeHistory\` DROP COLUMN \`child1DnaId\``); - await queryRunner.query(`ALTER TABLE \`posMasterEmployeeHistory\` DROP COLUMN \`rootDnaId\``); - await queryRunner.query(`ALTER TABLE \`posMasterEmployeeHistory\` DROP COLUMN \`profileEmployeeId\``); - } -} diff --git a/src/migration/1779776860350-update_command_add_shortName.ts b/src/migration/1779776860350-update_command_add_shortName.ts deleted file mode 100644 index 8754d42b..00000000 --- a/src/migration/1779776860350-update_command_add_shortName.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; - -export class UpdateCommandAddShortName1779776860350 implements MigrationInterface { - name = 'UpdateCommandAddShortName1779776860350' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`command\` ADD \`shortName\` varchar(16) NULL COMMENT 'ชื่อย่อหน่วยงานที่ออกคำสั่ง'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`command\` DROP COLUMN \`shortName\``); - } - -} diff --git a/src/migration/1780634210221-update_profileDiscipline_add_refCommandId.ts b/src/migration/1780634210221-update_profileDiscipline_add_refCommandId.ts deleted file mode 100644 index 9e5d1851..00000000 --- a/src/migration/1780634210221-update_profileDiscipline_add_refCommandId.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; - -export class UpdateProfileDisciplineAddRefCommandId1780634210221 implements MigrationInterface { - name = 'UpdateProfileDisciplineAddRefCommandId1780634210221' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`profileDisciplineHistory\` ADD \`refCommandId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง command'`); - await queryRunner.query(`ALTER TABLE \`profileDiscipline\` ADD \`refCommandId\` varchar(40) NULL COMMENT 'คีย์นอก(FK)ของตาราง command'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`profileDiscipline\` DROP COLUMN \`refCommandId\``); - await queryRunner.query(`ALTER TABLE \`profileDisciplineHistory\` DROP COLUMN \`refCommandId\``); - } -} diff --git a/src/scripts/ClearOldOrgRevision.ts b/src/scripts/ClearOldOrgRevision.ts deleted file mode 100644 index 4d2be7a7..00000000 --- a/src/scripts/ClearOldOrgRevision.ts +++ /dev/null @@ -1,27 +0,0 @@ -import "dotenv/config"; -import "reflect-metadata"; -import { AppDataSource } from "../database/data-source"; -import { clearOldOrgRevisionData } from "../services/ClearOldOrgRevisionService"; - -// "clear:old-org-revision": "ts-node src/scripts/ClearOldOrgRevision.ts", - -const defaultOrgRevisionId = "24dacf63-d289-496c-8102-8b25079dbaf2"; - -async function main(): Promise { - const orgRevisionId = process.argv[2] || defaultOrgRevisionId; - - try { - await AppDataSource.initialize(); - const result = await clearOldOrgRevisionData(orgRevisionId); - console.info(JSON.stringify(result, null, 2)); - } catch (error) { - console.error("[ClearOldOrgRevision] Failed:", error); - process.exitCode = 1; - } finally { - if (AppDataSource.isInitialized) { - await AppDataSource.destroy(); - } - } -} - -void main(); diff --git a/src/services/ClearOldOrgRevisionService.ts b/src/services/ClearOldOrgRevisionService.ts deleted file mode 100644 index 056206f3..00000000 --- a/src/services/ClearOldOrgRevisionService.ts +++ /dev/null @@ -1,232 +0,0 @@ -import { EntityManager, EntityTarget, In } from "typeorm"; -import { AppDataSource } from "../database/data-source"; -import { OrgRevision } from "../entities/OrgRevision"; -import { PosMaster } from "../entities/PosMaster"; -import { Position } from "../entities/Position"; -import { OrgRoot } from "../entities/OrgRoot"; -import { OrgChild1 } from "../entities/OrgChild1"; -import { OrgChild2 } from "../entities/OrgChild2"; -import { OrgChild3 } from "../entities/OrgChild3"; -import { OrgChild4 } from "../entities/OrgChild4"; -import { PosMasterAct } from "../entities/PosMasterAct"; -import { PosMasterAssign } from "../entities/PosMasterAssign"; -import { PermissionOrg } from "../entities/PermissionOrg"; -import { PermissionProfile } from "../entities/PermissionProfile"; -import { EmployeePosMaster } from "../entities/EmployeePosMaster"; -import { EmployeeTempPosMaster } from "../entities/EmployeeTempPosMaster"; -import { EmployeePosition } from "../entities/EmployeePosition"; -import { orgStructureCache } from "../utils/OrgStructureCache"; - -export interface ClearOldOrgRevisionSummary { - orgRevisionId: string; - orgRevisionName: string; - deleted: { - positions: number; - employeePositionsByPosMaster: number; - employeePositionsByTempPosMaster: number; - posMasterActsByParent: number; - posMasterActsByChild: number; - posMasterAssigns: number; - posMasters: number; - employeePosMasters: number; - employeeTempPosMasters: number; - permissionOrgs: number; - permissionProfiles: number; - orgChild4s: number; - orgChild3s: number; - orgChild2s: number; - orgChild1s: number; - orgRoots: number; - orgRevisions: number; - }; -} - -interface OrgRevisionSnapshot { - id: string; - orgRevisionName: string; - orgRevisionIsCurrent: boolean; - orgRevisionIsDraft: boolean; -} - -export async function clearOldOrgRevisionData( - orgRevisionId: string, -): Promise { - const result = await AppDataSource.transaction(async (manager) => { - const orgRevision = await manager.findOne(OrgRevision, { - where: { id: orgRevisionId }, - select: ["id", "orgRevisionName", "orgRevisionIsCurrent", "orgRevisionIsDraft"], - }); - - if (!orgRevision) { - throw new Error(`ไม่พบ orgRevision ที่ต้องการล้างข้อมูล: ${orgRevisionId}`); - } - - validateOrgRevisionForDeletion(orgRevision); - - const [posMasters, orgRoots, employeePosMasters, employeeTempPosMasters] = await Promise.all([ - manager.find(PosMaster, { - where: { orgRevisionId }, - select: ["id"], - }), - manager.find(OrgRoot, { - where: { orgRevisionId }, - select: ["id"], - }), - manager.find(EmployeePosMaster, { - where: { orgRevisionId }, - select: ["id"], - }), - manager.find(EmployeeTempPosMaster, { - where: { orgRevisionId }, - select: ["id"], - }), - ]); - - const posMasterIds = posMasters.map((item) => item.id); - const orgRootIds = orgRoots.map((item) => item.id); - const employeePosMasterIds = employeePosMasters.map((item) => item.id); - const employeeTempPosMasterIds = employeeTempPosMasters.map((item) => item.id); - - const [ - positionsCount, - employeePositionsByPosMasterCount, - employeePositionsByTempPosMasterCount, - posMasterActsByParentCount, - posMasterActsByChildCount, - posMasterAssignsCount, - permissionOrgsCount, - permissionProfilesCount, - orgChild4sCount, - orgChild3sCount, - orgChild2sCount, - orgChild1sCount, - ] = await Promise.all([ - countByIds(manager, Position, "posMasterId", posMasterIds), - countByIds(manager, EmployeePosition, "posMasterId", employeePosMasterIds), - countByIds(manager, EmployeePosition, "posMasterTempId", employeeTempPosMasterIds), - countByIds(manager, PosMasterAct, "posMasterId", posMasterIds), - countByIds(manager, PosMasterAct, "posMasterChildId", posMasterIds), - countByIds(manager, PosMasterAssign, "posMasterId", posMasterIds), - countByIds(manager, PermissionOrg, "orgRootId", orgRootIds), - countByIds(manager, PermissionProfile, "orgRootId", orgRootIds), - manager.count(OrgChild4, { where: { orgRevisionId } }), - manager.count(OrgChild3, { where: { orgRevisionId } }), - manager.count(OrgChild2, { where: { orgRevisionId } }), - manager.count(OrgChild1, { where: { orgRevisionId } }), - ]); - - if (positionsCount > 0) { - await manager.delete(Position, { posMasterId: In(posMasterIds) }); - } - if (employeePositionsByPosMasterCount > 0) { - await manager.delete(EmployeePosition, { posMasterId: In(employeePosMasterIds) }); - } - if (employeePositionsByTempPosMasterCount > 0) { - await manager.delete(EmployeePosition, { posMasterTempId: In(employeeTempPosMasterIds) }); - } - if (posMasterActsByParentCount > 0) { - await manager.delete(PosMasterAct, { posMasterId: In(posMasterIds) }); - } - if (posMasterActsByChildCount > 0) { - await manager.delete(PosMasterAct, { posMasterChildId: In(posMasterIds) }); - } - if (posMasterAssignsCount > 0) { - await manager.delete(PosMasterAssign, { posMasterId: In(posMasterIds) }); - } - - const posMastersCount = posMasterIds.length; - const employeePosMastersCount = employeePosMasterIds.length; - const employeeTempPosMastersCount = employeeTempPosMasterIds.length; - - if (posMastersCount > 0) { - await manager.delete(PosMaster, { orgRevisionId }); - } - if (employeePosMastersCount > 0) { - await manager.delete(EmployeePosMaster, { orgRevisionId }); - } - if (employeeTempPosMastersCount > 0) { - await manager.delete(EmployeeTempPosMaster, { orgRevisionId }); - } - - if (permissionOrgsCount > 0) { - await manager.delete(PermissionOrg, { orgRootId: In(orgRootIds) }); - } - if (permissionProfilesCount > 0) { - await manager.delete(PermissionProfile, { orgRootId: In(orgRootIds) }); - } - - if (orgChild4sCount > 0) { - await manager.delete(OrgChild4, { orgRevisionId }); - } - if (orgChild3sCount > 0) { - await manager.delete(OrgChild3, { orgRevisionId }); - } - if (orgChild2sCount > 0) { - await manager.delete(OrgChild2, { orgRevisionId }); - } - if (orgChild1sCount > 0) { - await manager.delete(OrgChild1, { orgRevisionId }); - } - - const orgRootsCount = orgRootIds.length; - if (orgRootsCount > 0) { - await manager.delete(OrgRoot, { orgRevisionId }); - } - - await manager.delete(OrgRevision, { id: orgRevisionId }); - - return { - orgRevisionId: orgRevision.id, - orgRevisionName: orgRevision.orgRevisionName, - deleted: { - positions: positionsCount, - employeePositionsByPosMaster: employeePositionsByPosMasterCount, - employeePositionsByTempPosMaster: employeePositionsByTempPosMasterCount, - posMasterActsByParent: posMasterActsByParentCount, - posMasterActsByChild: posMasterActsByChildCount, - posMasterAssigns: posMasterAssignsCount, - posMasters: posMastersCount, - employeePosMasters: employeePosMastersCount, - employeeTempPosMasters: employeeTempPosMastersCount, - permissionOrgs: permissionOrgsCount, - permissionProfiles: permissionProfilesCount, - orgChild4s: orgChild4sCount, - orgChild3s: orgChild3sCount, - orgChild2s: orgChild2sCount, - orgChild1s: orgChild1sCount, - orgRoots: orgRootsCount, - orgRevisions: 1, - }, - }; - }); - - orgStructureCache.invalidate(orgRevisionId); - return result; -} - -function validateOrgRevisionForDeletion(orgRevision: OrgRevisionSnapshot): void { - if (orgRevision.orgRevisionIsCurrent) { - throw new Error(`ไม่สามารถลบ orgRevision ปัจจุบันได้: ${orgRevision.id}`); - } - - if (orgRevision.orgRevisionIsDraft) { - throw new Error(`ไม่สามารถลบ orgRevision แบบร่างได้ด้วยสคริปต์นี้: ${orgRevision.id}`); - } -} - -async function countByIds( - manager: EntityManager, - entity: EntityTarget, - field: keyof Entity, - ids: string[], -): Promise { - if (ids.length === 0) { - return 0; - } - - const alias = "entity"; - return manager - .createQueryBuilder(entity, alias) - .where(`${alias}.${String(field)} IN (:...ids)`, { ids }) - .getCount(); -} diff --git a/src/services/KeycloakAttributeService.ts b/src/services/KeycloakAttributeService.ts index 7bfe88ed..1e0f3f07 100644 --- a/src/services/KeycloakAttributeService.ts +++ b/src/services/KeycloakAttributeService.ts @@ -530,20 +530,18 @@ export class KeycloakAttributeService { // Initialize rate limiter if rate limiting is enabled if (rateLimit && rateLimit > 0) { rateLimiter = new RateLimiter(rateLimit); - console.log( - `[syncMissingEmpTypeByMonth] Rate limiting enabled: ${rateLimit} requests/second`, - ); + console.log(`[syncMissingEmpTypeByMonth] Rate limiting enabled: ${rateLimit} requests/second`); } // Select repository based on profile type - const repo = profileType === "PROFILE" ? this.profileRepo : this.profileEmployeeRepo; + const repo = + profileType === "PROFILE" ? this.profileRepo : this.profileEmployeeRepo; // Query profiles updated within the month const profiles = await repo .createQueryBuilder("p") .where("p.keycloak IS NOT NULL") .andWhere("p.keycloak != :empty", { empty: "" }) - .andWhere("p.isDelete = :isDelete", { isDelete: false }) .andWhere("p.lastUpdatedAt BETWEEN :start AND :end", { start: startDate, end: endDate, @@ -581,7 +579,8 @@ export class KeycloakAttributeService { try { // Check if empType is empty in Keycloak - const { isEmpty, currentEmpType } = await this.checkEmpTypeEmpty(keycloakUserId); + const { isEmpty, currentEmpType } = + await this.checkEmpTypeEmpty(keycloakUserId); result.profilesChecked++; @@ -608,7 +607,8 @@ export class KeycloakAttributeService { // Sync the profile const success = await withRetry( - async () => this.syncOnOrganizationChange(profile.id, profileType), + async () => + this.syncOnOrganizationChange(profile.id, profileType), 3, // maxRetries 1000, // baseDelay ); @@ -768,13 +768,7 @@ export class KeycloakAttributeService { maxRetries?: number; // Retry attempts for failed operations rateLimit?: number; // Requests per second clearProgress?: boolean; // Start fresh, ignore existing progress - }): Promise<{ - total: number; - success: number; - failed: number; - details: any[]; - resumed?: boolean; - }> { + }): Promise<{ total: number; success: number; failed: number; details: any[]; resumed?: boolean }> { const limit = options?.limit; const concurrency = options?.concurrency ?? 5; const resume = options?.resume ?? false; @@ -928,10 +922,7 @@ export class KeycloakAttributeService { // Save progress after each batch SyncProgressManager.save(updatedState); // Log progress every 50 items - if ( - updatedState.lastSyncedIndex % 50 === 0 || - updatedState.lastSyncedIndex === updatedState.totalProfiles - ) { + if (updatedState.lastSyncedIndex % 50 === 0 || updatedState.lastSyncedIndex === updatedState.totalProfiles) { SyncProgressManager.logProgress(updatedState); } }, diff --git a/src/services/PositionService.ts b/src/services/PositionService.ts index 37c5f083..b1837b99 100644 --- a/src/services/PositionService.ts +++ b/src/services/PositionService.ts @@ -188,7 +188,6 @@ export async function CreatePosMasterHistoryOfficer( return true; } catch (err) { if (manager) { - console.error("CreatePosMasterHistoryOfficer error (external transaction):", err); throw err; } console.error("CreatePosMasterHistoryOfficer transaction error:", err); @@ -231,7 +230,6 @@ export async function CreatePosMasterHistoryEmployee( : null; h.ancestorDNA = pm.ancestorDNA; if (!type || type != "DELETE") { - h.profileEmployeeId = pm.current_holder?.id || _null; h.prefix = pm.current_holder?.prefix || _null; h.firstName = pm.current_holder?.firstName || _null; h.lastName = pm.current_holder?.lastName || _null; @@ -239,11 +237,6 @@ export async function CreatePosMasterHistoryEmployee( h.posType = selectedPosition?.posType?.posTypeName ?? _null; h.posLevel = selectedPosition?.posLevel?.posLevelName ?? _null; } - h.rootDnaId = pm.orgRoot?.ancestorDNA || _null; - h.child1DnaId = pm.orgChild1?.ancestorDNA || _null; - h.child2DnaId = pm.orgChild2?.ancestorDNA || _null; - h.child3DnaId = pm.orgChild3?.ancestorDNA || _null; - h.child4DnaId = pm.orgChild4?.ancestorDNA || _null; h.posMasterNoPrefix = pm.posMasterNoPrefix ?? _null; h.posMasterNo = pm.posMasterNo ?? _null; h.posMasterNoSuffix = pm.posMasterNoSuffix ?? _null; @@ -501,61 +494,3 @@ export async function BatchSavePosMasterHistoryOfficer( return false; } } - -/** - * อัพเดทประวัติคนครองตำแหน่งเมื่อมีการเปลี่ยนแปลงข้อมูล profile - * เช่น เปลี่ยนชื่อ - นามสกุล - * ใช้สำหรับบันทึกประวัติเมื่อ profile ที่ครองตำแหน่งมีการเปลี่ยนแปลง - * - * @param profileId ID ของ profile ที่ต้องการตรวจสอบ - * @param request RequestWithUser สำหรับบันทึกข้อมูลผู้ดำเนินการ - * @param type "OFFICER" สำหรับข้าราชการ | "EMPLOYEE" สำหรับลูกจ้างประจำ (default: "OFFICER") - */ -export async function updateHolderProfileHistory( - profileId: string, - request: RequestWithUser, - type: "OFFICER" | "EMPLOYEE" = "OFFICER", -): Promise { - try { - if (type === "OFFICER") { - const posMasterRepo = AppDataSource.getRepository(PosMaster); - const posMaster = await posMasterRepo.findOne({ - where: { - current_holderId: profileId, - orgRevision: { - orgRevisionIsCurrent: true, - orgRevisionIsDraft: false, - } - }, - relations: { - orgRevision : true - } - }); - - if (posMaster) { - await CreatePosMasterHistoryOfficer(posMaster.id, request); - } - } else if (type === "EMPLOYEE") { - const empPosMasterRepo = AppDataSource.getRepository(EmployeePosMaster); - const employeePosMaster = await empPosMasterRepo.findOne({ - where: { - current_holderId: profileId, - orgRevision: { - orgRevisionIsCurrent: true, - orgRevisionIsDraft: false, - } - }, - relations: { - orgRevision : true - } - }); - - if (employeePosMaster) { - await CreatePosMasterHistoryEmployee(employeePosMaster.id, request); - } - } - } catch (error) { - console.error("updateHolderProfileHistory error:", error); - throw error; - } -} diff --git a/src/services/ProfileLeaveService.ts b/src/services/ProfileLeaveService.ts index 16284bb7..327a1fe2 100644 --- a/src/services/ProfileLeaveService.ts +++ b/src/services/ProfileLeaveService.ts @@ -1,13 +1,12 @@ import { AppDataSource } from "../database/data-source"; import { Profile } from "./../entities/Profile"; import { ProfileEmployee } from "../entities/ProfileEmployee"; -import { ProfileSalary } from "./../entities/ProfileSalary"; import { OrgRoot } from "../entities/OrgRoot"; import { OrgChild1 } from "../entities/OrgChild1"; import { OrgChild2 } from "../entities/OrgChild2"; import { OrgChild3 } from "../entities/OrgChild3"; import { OrgChild4 } from "../entities/OrgChild4"; -import { Brackets, In, Repository } from "typeorm"; +import { Brackets, Repository } from "typeorm"; import Extension from "../interfaces/extension"; import { RequestWithUser } from "../middlewares/user"; @@ -63,7 +62,6 @@ interface OrgParentName { export class ProfileLeaveService { private profileEmployeeRepo: Repository; private profileRepo: Repository; - private profileSalaryRepo: Repository; private orgRootRepository: Repository; private child1Repository: Repository; private child2Repository: Repository; @@ -74,7 +72,6 @@ export class ProfileLeaveService { constructor() { this.profileEmployeeRepo = AppDataSource.getRepository(ProfileEmployee); this.profileRepo = AppDataSource.getRepository(Profile); - this.profileSalaryRepo = AppDataSource.getRepository(ProfileSalary); this.orgRootRepository = AppDataSource.getRepository(OrgRoot); this.child1Repository = AppDataSource.getRepository(OrgChild1); this.child2Repository = AppDataSource.getRepository(OrgChild2); @@ -210,16 +207,19 @@ export class ProfileLeaveService { let params: NodeParams = {}; const orgLists = await this.findOrgNodeParentAll(node, nodeId); - - for (let index = 0; index <= node; index++) { - const config = this.nodeConfigs[index]; - const orgName = orgLists[config.nameField as keyof OrgParentName] || null; - if (orgName) { - nodeCondition += index > 0 ? ` AND ${config.condition}` : config.condition; - nodeCondition += isAll === false && config.isAllTrue ? ` AND ${config.isAllTrue}` : ""; - params[config.paramKey] = orgName; - } - } + console.log("Org Hierarchy for Node Condition:", orgLists); + await Promise.all( + this.nodeConfigs.map(async (config, index) => { + if (index <= node) { + const orgName = orgLists[config.nameField as keyof OrgParentName] || null; + if (orgName) { + nodeCondition += index > 0 ? ` AND ${config.condition}` : config.condition; + nodeCondition += isAll === false && config.isAllTrue ? ` AND ${config.isAllTrue}` : ""; + params[config.paramKey] = orgName; + } + } + }), + ); return { condition: nodeCondition, @@ -234,31 +234,53 @@ export class ProfileLeaveService { child3: string | null; child4: string | null; }): Promise { - const [rootName, child1, child2, child3, child4] = await Promise.all([ - orgIds.root - ? this.orgRootRepository.findOne({ where: { id: orgIds.root }, select: ["orgRootName"] }) - : Promise.resolve(null), - orgIds.child1 - ? this.child1Repository.findOne({ where: { id: orgIds.child1 }, select: ["orgChild1Name"] }) - : Promise.resolve(null), - orgIds.child2 - ? this.child2Repository.findOne({ where: { id: orgIds.child2 }, select: ["orgChild2Name"] }) - : Promise.resolve(null), - orgIds.child3 - ? this.child3Repository.findOne({ where: { id: orgIds.child3 }, select: ["orgChild3Name"] }) - : Promise.resolve(null), - orgIds.child4 - ? this.child4Repository.findOne({ where: { id: orgIds.child4 }, select: ["orgChild4Name"] }) - : Promise.resolve(null), - ]); - - return { - orgRootName: rootName?.orgRootName ?? null, - orgChild1Name: child1?.orgChild1Name ?? null, - orgChild2Name: child2?.orgChild2Name ?? null, - orgChild3Name: child3?.orgChild3Name ?? null, - orgChild4Name: child4?.orgChild4Name ?? null, + const orgNames: OrgParentName = { + orgRootName: null, + orgChild1Name: null, + orgChild2Name: null, + orgChild3Name: null, + orgChild4Name: null, }; + if (orgIds.root) { + const rootName = await this.orgRootRepository.findOne({ + where: { id: orgIds.root }, + select: ["orgRootName"], + }); + orgNames.orgRootName = rootName ? rootName.orgRootName : null; + } + if (orgIds.child1) { + const child1 = await this.child1Repository.findOne({ + where: { id: orgIds.child1 }, + select: ["orgChild1Name"], + }); + orgNames.orgChild1Name = child1 ? child1.orgChild1Name : null; + } + + if (orgIds.child2) { + const child2 = await this.child2Repository.findOne({ + where: { id: orgIds.child2 }, + select: ["orgChild2Name"], + }); + orgNames.orgChild2Name = child2 ? child2.orgChild2Name : null; + } + + if (orgIds.child3) { + const child3 = await this.child3Repository.findOne({ + where: { id: orgIds.child3 }, + select: ["orgChild3Name"], + }); + orgNames.orgChild3Name = child3 ? child3.orgChild3Name : null; + } + + if (orgIds.child4) { + const child4 = await this.child4Repository.findOne({ + where: { id: orgIds.child4 }, + select: ["orgChild4Name"], + }); + orgNames.orgChild4Name = child4 ? child4.orgChild4Name : null; + } + + return orgNames; } /** สร้างเงื่อนไขการค้นหาตาม node และ nodeId และเช็คกับ permission */ @@ -295,15 +317,16 @@ export class ProfileLeaveService { return { condition: "1=0", params: {} }; // no access } - for (let index = 0; index < this.nodeConfigs.length; index++) { - const config = this.nodeConfigs[index]; - const orgName = orgLists[config.nameField as keyof OrgParentName] || null; - if (orgName) { - nodeCondition += index > 0 ? ` AND ${config.condition}` : config.condition; - nodeCondition += isAll === false && config.isAllTrue ? ` AND ${config.isAllTrue}` : ""; - params[config.paramKey] = orgName; - } - } + await Promise.all( + this.nodeConfigs.map(async (config, index) => { + const orgName = orgLists[config.nameField as keyof OrgParentName] || null; + if (orgName) { + nodeCondition += index > 0 ? ` AND ${config.condition}` : config.condition; + nodeCondition += isAll === false && config.isAllTrue ? ` AND ${config.isAllTrue}` : ""; + params[config.paramKey] = orgName; + } + }), + ); return { condition: nodeCondition, @@ -455,146 +478,97 @@ export class ProfileLeaveService { _data, } = filter; - const t0 = Date.now(); const searchQuery = this.buildSearchQuery(searchField, "profileEmployee"); - // สร้าง base WHERE conditions แชร์ระหว่าง count/id/data query - const baseWhere = (qb: any) => { - qb.where( - new Brackets((qb2) => { - qb2.where("profileEmployee.isLeave = :isLeave", { isLeave: true }).orWhere( + // สร้าง main query - เปลี่ยนจาก leftJoinAndSelect เป็น leftJoin สำหรับ profileSalary + const queryBuilder = this.profileEmployeeRepo + .createQueryBuilder("profileEmployee") + .leftJoinAndSelect("profileEmployee.posLevel", "posLevel") + .leftJoinAndSelect("profileEmployee.posType", "posType") + .leftJoinAndSelect("profileEmployee.profileEmployeeEmployment", "profileEmployeeEmployment") + .leftJoin( + "profileEmployee.profileSalary", + "profileSalary", + "profileSalary.order = (SELECT MAX(ps.order) FROM profileSalary ps WHERE ps.profileEmployeeId = profileEmployee.id and ps.positionName != 'เกษียณอายุราชการ')", + ) + .addSelect([ + "profileSalary.id", + "profileSalary.order", + "profileSalary.posNo", + "profileSalary.posNoAbb", + "profileSalary.orgRoot", + "profileSalary.orgChild1", + "profileSalary.orgChild2", + "profileSalary.orgChild3", + "profileSalary.orgChild4", + ]) + .where( + new Brackets((qb) => { + qb.where("profileEmployee.isLeave = :isLeave", { isLeave: true }).orWhere( "profileEmployee.isRetirement = :isRetirement", { isRetirement: true }, ); }), ) - .andWhere("profileEmployee.employeeClass LIKE :type", { type: "PERM" }) - .andWhere( - new Brackets((qb2) => { - qb2.orWhere(searchKeyword && searchKeyword != "" ? searchQuery : "1=1", { - keyword: `%${searchKeyword}%`, - }); - }), - ); + .andWhere("profileEmployee.employeeClass LIKE :type", { type: "PERM" }) + .andWhere( + new Brackets((qb) => { + qb.orWhere(searchKeyword && searchKeyword != "" ? searchQuery : "1=1", { + keyword: `%${searchKeyword}%`, + }); + }), + ); - if (posType) { - qb.andWhere("posType.posTypeName LIKE :keyword1", { keyword1: `${posType}` }); - } - if (posLevel) { - qb.andWhere( - "CONCAT(posType.posTypeShortName, ' ', posLevel.posLevelName) LIKE :keyword2", - { keyword2: `${posLevel}` }, - ); - } - if (isProbation !== undefined && isProbation !== null) { - qb.andWhere("profileEmployee.isProbation = :isProbation", { isProbation }); - } - if (retireType) { - qb.andWhere("profileEmployee.leaveType = :retireType", { retireType }); - } - }; - - // Compute permission/node conditions เพียงครั้งเดียว - const conditions: { condition: string; params: Record }[] = []; - if (_data.privilege !== "OWNER" && _data.privilege !== "PARENT") { - conditions.push(await this.buildPermissionCondition(_data, isAll)); + // เพิ่มเงื่อนไขการค้นหา + if (posType) { + queryBuilder.andWhere("posType.posTypeName LIKE :keyword1", { keyword1: `${posType}` }); } + + if (posLevel) { + queryBuilder.andWhere( + "CONCAT(posType.posTypeShortName, ' ', posLevel.posLevelName) LIKE :keyword2", + { keyword2: `${posLevel}` }, + ); + } + + if (isProbation) { + queryBuilder.andWhere(`profileEmployee.isProbation = ${isProbation}`); + } + + if (retireType) { + queryBuilder.andWhere("profileEmployee.leaveType = :retireType", { retireType }); + } + if (node !== null && node !== undefined && nodeId) { - conditions.push(await this.buildNodeCondition(node, nodeId, isAll)); - } - const applyConditions = (qb: any) => { - for (const cond of conditions) { - qb.andWhere(cond.condition, cond.params); + const [nodeCondition, permissionCondition] = await Promise.all([ + this.buildNodeCondition(node, nodeId, isAll), + this.buildPermissionCondition(_data, isAll), + ]); + // console.log("Permission Condition:", permissionCondition); + // console.log("Node Condition:", nodeCondition); + + queryBuilder.andWhere(nodeCondition.condition, nodeCondition.params); + + if (_data.privilege !== "OWNER" && _data.privilege !== "PARENT") { + queryBuilder.andWhere(permissionCondition.condition, permissionCondition.params); } - }; - - // console.log(`[ProfileLeaveService] getLeaveEmployees conditions took ${Date.now() - t0}ms`); - - // สร้าง salary EXISTS filter (ใช้ซ้ำทั้ง step1, step2) - const applySalaryFilter = (qb: any) => { - if (conditions.length > 0) { - let existsCond = "profileSalary.positionName != :notRetire"; - const existsParams: Record = { notRetire: "เกษียณอายุราชการ" }; - for (const cond of conditions) { - existsCond += ` AND ${cond.condition}`; - Object.assign(existsParams, cond.params); - } - qb.andWhere( - `EXISTS (SELECT 1 FROM profileSalary WHERE profileEmployeeId = profileEmployee.id AND ${existsCond} AND profileSalary.\`order\` = (SELECT MAX(ps.\`order\`) FROM profileSalary ps WHERE ps.profileEmployeeId = profileEmployee.id AND ps.positionName != :notRetire2))`, - { ...existsParams, notRetire2: "เกษียณอายุราชการ" } - ); - } - }; - - // Step 1: Count query - const countQb = this.profileEmployeeRepo - .createQueryBuilder("profileEmployee") - .leftJoinAndSelect("profileEmployee.posLevel", "posLevel") - .leftJoinAndSelect("profileEmployee.posType", "posType"); - baseWhere(countQb); - applySalaryFilter(countQb); - const total = await countQb.getCount(); - - // console.log(`[ProfileLeaveService] getLeaveEmployees count took ${Date.now() - t0}ms, total=${total}`); - - // Step 2: ดึงเฉพาะ profileEmployee IDs ที่ผ่านเงื่อนไข - const idQb = this.profileEmployeeRepo - .createQueryBuilder("profileEmployee") - .select(["profileEmployee.id"]) - .leftJoin("profileEmployee.posLevel", "posLevel") - .leftJoin("profileEmployee.posType", "posType"); - baseWhere(idQb); - applySalaryFilter(idQb); - idQb.orderBy(sortBy, sort).skip((page - 1) * pageSize).take(pageSize); - const rawIds = await idQb.getRawMany(); - const employeeIds = rawIds.map((r) => r.profileEmployee_id); - - // console.log(`[ProfileLeaveService] getLeaveEmployees ids took ${Date.now() - t0}ms, ids=${employeeIds.length}`); - - if (employeeIds.length === 0) { - return { data: [], total }; } - // Step 3: Load full data โดยไม่ JOIN salary - const records = await this.profileEmployeeRepo.find({ - where: { id: In(employeeIds) }, - relations: ["posLevel", "posType", "profileEmployeeEmployment"], - order: { [sortBy.split(".")[1]]: sort } as any, - }); + // เพิ่ม sorting และ pagination + queryBuilder + .orderBy(sortBy, sort) + .skip((page - 1) * pageSize) + .take(pageSize); - // Step 4: Load salary เฉพาะ row ที่มี order สูงสุดต่อ profileEmployeeId (INNER JOIN + GROUP BY) - const salaries = await this.profileSalaryRepo - .createQueryBuilder("ps") - .innerJoin( - (subQuery) => - subQuery - .select("ps2.profileEmployeeId", "pid") - .addSelect("MAX(ps2.order)", "maxOrd") - .from(ProfileSalary, "ps2") - .where("ps2.profileEmployeeId IN (:...employeeIds)", { employeeIds }) - .andWhere("ps2.positionName != :notRetire", { notRetire: "เกษียณอายุราชการ" }) - .groupBy("ps2.profileEmployeeId"), - "latest", - "latest.pid = ps.profileEmployeeId AND ps.order = latest.maxOrd" - ) - .getMany(); + const [records, total] = await queryBuilder.getManyAndCount(); - // สร้าง map: profileEmployeeId → salary ที่มี order สูงสุด - const salaryMap = new Map(); - for (const s of salaries) { - salaryMap.set(s.profileEmployeeId, s); - } + // print query for debug + // console.log("SQL Query:", queryBuilder.getSql()); - // แปลงข้อมูลพร้อม salary - const data = records.map((record) => { - const salary = salaryMap.get(record.id); - if (salary) { - (record as any).profileSalary = [salary]; - } - return this.transformEmployeeData(record); - }); + const data = await Promise.all( + records.map((record) => Promise.resolve(this.transformEmployeeData(record))), + ); - // console.log(`[ProfileLeaveService] getLeaveEmployees total took ${Date.now() - t0}ms, total=${total}`); return { data, total }; } @@ -675,143 +649,94 @@ export class ProfileLeaveService { _data, } = filter; - const t0 = Date.now(); const searchQuery = this.buildSearchQuery(searchField); - // สร้าง base WHERE conditions แชร์ระหว่าง count/id/data query - const baseWhere = (qb: any) => { - qb.where( - new Brackets((qb2) => { - qb2.where("profile.isLeave = :isLeave", { isLeave: true }).orWhere( + // สร้าง main query - เปลี่ยนจาก leftJoinAndSelect เป็น leftJoin สำหรับ profileSalary + const queryBuilder = this.profileRepo + .createQueryBuilder("profile") + .leftJoinAndSelect("profile.posLevel", "posLevel") + .leftJoinAndSelect("profile.posType", "posType") + .leftJoin( + "profile.profileSalary", + "profileSalary", + "profileSalary.order = (SELECT MAX(ps.order) FROM profileSalary ps WHERE ps.profileId = profile.id and ps.positionName != 'เกษียณอายุราชการ')", + ) + .addSelect([ + "profileSalary.id", + "profileSalary.order", + "profileSalary.posNo", + "profileSalary.posNoAbb", + "profileSalary.orgRoot", + "profileSalary.orgChild1", + "profileSalary.orgChild2", + "profileSalary.orgChild3", + "profileSalary.orgChild4", + "profileSalary.positionExecutive", + ]) + .where( + new Brackets((qb) => { + qb.where("profile.isLeave = :isLeave", { isLeave: true }).orWhere( "profile.isRetirement = :isRetirement", { isRetirement: true }, ); }), - ).andWhere( - new Brackets((qb2) => { - qb2.orWhere(searchKeyword && searchKeyword != "" ? searchQuery : "1=1", { + ) + .andWhere( + new Brackets((qb) => { + qb.orWhere(searchKeyword && searchKeyword != "" ? searchQuery : "1=1", { keyword: `%${searchKeyword}%`, }); }), ); - if (posType) { - qb.andWhere("posType.posTypeName LIKE :keyword1", { keyword1: `${posType}` }); - } - if (posLevel) { - qb.andWhere("posLevel.posLevelName LIKE :keyword2", { keyword2: `${posLevel}` }); - } - if (isProbation !== undefined && isProbation !== null) { - qb.andWhere("profile.isProbation = :isProbation", { isProbation }); - } - if (retireType) { - qb.andWhere("profile.leaveType = :retireType", { retireType }); - } - }; - - // Compute permission/node conditions เพียงครั้งเดียว - const conditions: { condition: string; params: Record }[] = []; - if (_data.privilege !== "OWNER" && _data.privilege !== "PARENT") { - conditions.push(await this.buildPermissionCondition(_data, isAll)); + if (posType) { + queryBuilder.andWhere("posType.posTypeName LIKE :keyword1", { keyword1: `${posType}` }); } + + if (posLevel) { + queryBuilder.andWhere("posLevel.posLevelName LIKE :keyword2", { keyword2: `${posLevel}` }); + } + + if (isProbation) { + queryBuilder.andWhere(`profile.isProbation = ${isProbation}`); + } + + if (retireType) { + queryBuilder.andWhere("profile.leaveType = :retireType", { retireType }); + } + + // เพิ่ม permission และ node conditions if (node !== null && node !== undefined && nodeId) { - conditions.push(await this.buildNodeCondition(node, nodeId, isAll)); - } - const applyConditions = (qb: any) => { - for (const cond of conditions) { - qb.andWhere(cond.condition, cond.params); + // สร้าง query conditions แบบ parallel + const [nodeCondition, permissionCondition] = await Promise.all([ + this.buildNodeCondition(node, nodeId, isAll), + this.buildPermissionCondition(_data, isAll), + ]); + console.log("Permission Condition:", permissionCondition); + console.log("Node Condition:", nodeCondition); + + queryBuilder.andWhere(nodeCondition.condition, nodeCondition.params); + + if (_data.privilege !== "OWNER" && _data.privilege !== "PARENT") { + queryBuilder.andWhere(permissionCondition.condition, permissionCondition.params); } - }; - - // console.log(`[ProfileLeaveService] getLeaveOfficer conditions took ${Date.now() - t0}ms`); - - // สร้าง salary EXISTS filter (ใช้ซ้ำทั้ง step1, step2) - const applySalaryFilter = (qb: any) => { - if (conditions.length > 0) { - let existsCond = "profileSalary.positionName != :notRetire"; - const existsParams: Record = { notRetire: "เกษียณอายุราชการ" }; - for (const cond of conditions) { - existsCond += ` AND ${cond.condition}`; - Object.assign(existsParams, cond.params); - } - qb.andWhere( - `EXISTS (SELECT 1 FROM profileSalary WHERE profileId = profile.id AND ${existsCond} AND profileSalary.\`order\` = (SELECT MAX(ps.\`order\`) FROM profileSalary ps WHERE ps.profileId = profile.id AND ps.positionName != :notRetire2))`, - { ...existsParams, notRetire2: "เกษียณอายุราชการ" } - ); - } - }; - - // Step 1: Count query - const countQb = this.profileRepo - .createQueryBuilder("profile") - .leftJoinAndSelect("profile.posLevel", "posLevel") - .leftJoinAndSelect("profile.posType", "posType"); - baseWhere(countQb); - applySalaryFilter(countQb); - const total = await countQb.getCount(); - - // console.log(`[ProfileLeaveService] getLeaveOfficer count took ${Date.now() - t0}ms, total=${total}`); - - // Step 2: ดึงเฉพาะ profile IDs ที่ผ่านเงื่อนไข - const idQb = this.profileRepo - .createQueryBuilder("profile") - .select(["profile.id"]) - .leftJoin("profile.posLevel", "posLevel") - .leftJoin("profile.posType", "posType"); - baseWhere(idQb); - applySalaryFilter(idQb); - idQb.orderBy(sortBy, sort).skip((page - 1) * pageSize).take(pageSize); - const rawIds = await idQb.getRawMany(); - const profileIds = rawIds.map((r) => r.profile_id); - - // console.log(`[ProfileLeaveService] getLeaveOfficer ids took ${Date.now() - t0}ms, ids=${profileIds.length}`); - - if (profileIds.length === 0) { - return { data: [], total }; } - // Step 3: Load full data โดยไม่ JOIN salary - const records = await this.profileRepo.find({ - where: { id: In(profileIds) }, - relations: ["posLevel", "posType"], - order: { [sortBy.split(".")[1]]: sort } as any, - }); - // console.log(`[ProfileLeaveService] getLeaveOfficer step3 (load profiles) took ${Date.now() - t0}ms`); + // เพิ่ม sorting และ pagination + queryBuilder + .orderBy(sortBy, sort) + .skip((page - 1) * pageSize) + .take(pageSize); - // Step 4: Load salary เฉพาะ row ที่มี order สูงสุดต่อ profileId (INNER JOIN + GROUP BY) - const salaries = await this.profileSalaryRepo - .createQueryBuilder("ps") - .innerJoin( - (subQuery) => - subQuery - .select("ps2.profileId", "pid") - .addSelect("MAX(ps2.order)", "maxOrd") - .from(ProfileSalary, "ps2") - .where("ps2.profileId IN (:...profileIds)", { profileIds }) - .andWhere("ps2.positionName != :notRetire", { notRetire: "เกษียณอายุราชการ" }) - .groupBy("ps2.profileId"), - "latest", - "latest.pid = ps.profileId AND ps.order = latest.maxOrd" - ) - .getMany(); - // console.log(`[ProfileLeaveService] getLeaveOfficer step4 (load salaries) took ${Date.now() - t0}ms, salary rows=${salaries.length}`); + const [records, total] = await queryBuilder.getManyAndCount(); - // สร้าง map: profileId → salary ที่มี order สูงสุด - const salaryMap = new Map(); - for (const s of salaries) { - salaryMap.set(s.profileId, s); - } + // print query for debug + // console.log("SQL Query:", queryBuilder.getSql()); - // แปลงข้อมูลพร้อม salary - const data = records.map((record) => { - const salary = salaryMap.get(record.id); - if (salary) { - (record as any).profileSalary = [salary]; - } - return this.transformOfficerData(record); - }); + const data = await Promise.all( + records.map((record) => Promise.resolve(this.transformOfficerData(record))), + ); - // console.log(`[ProfileLeaveService] getLeaveOfficer total took ${Date.now() - t0}ms, total=${total}`); return { data, total }; } } diff --git a/src/services/webSocket.ts b/src/services/webSocket.ts index 7d464655..36359cd8 100644 --- a/src/services/webSocket.ts +++ b/src/services/webSocket.ts @@ -22,7 +22,7 @@ export function initWebSocket() { }); io.on("connection", (ws) => { - // console.log("✅ Client connected to WebSocket"); + console.log("✅ Client connected to WebSocket"); ws.on("close", () => { console.log("❌ Client disconnected"); @@ -46,7 +46,7 @@ export async function sendWebSocket( ) { if (!io) initWebSocket(); // console.log( `🔔 :`,data.message); - + for (let [id, session] of io.of("/").sockets) { const user: { sub: string; diff --git a/src/utils/org-formatting.ts b/src/utils/org-formatting.ts index eb4b7a9d..fd61f33b 100644 --- a/src/utils/org-formatting.ts +++ b/src/utils/org-formatting.ts @@ -101,7 +101,7 @@ export function getOrgFullName(posMaster: PosMaster): string { } /** - * สร้างเลขที่ตำแหน่ง เช่น "กทม. กบ. 1234 ช" + * สร้างเลขที่ตำแหน่ง เช่น "กทม. กบ.1234ช" */ export function getPosMasterNo(posMaster: PosMaster): string { const orgShortName = getOrgShortName(posMaster); @@ -110,5 +110,5 @@ export function getPosMasterNo(posMaster: PosMaster): string { posMaster.posMasterNo, posMaster.posMasterNoSuffix, ].filter((part) => part !== null && part !== undefined); - return `${orgShortName} ${parts.join(' ')}`; + return `${orgShortName} ${parts.join('')}`; } diff --git a/src/utils/tenure.ts b/src/utils/tenure.ts index 1c97dff1..dbdedbb3 100644 --- a/src/utils/tenure.ts +++ b/src/utils/tenure.ts @@ -1,37 +1,18 @@ /** - * Normalize a duration sum using calendar arithmetic - * Converts excess days to months using average month length (30.4375 days) - * and excess months to years. Matches the logic used in stored procedures. - * - * @param years Total years from sum - * @param months Total months from sum - * @param days Total days from sum - * @returns Normalized { years, months, days } + * คำนวณอายุงานจากจำนวนวันรวม + * ใช้สูตรเดียวกับ Stored Procedure GetProfileSalaryPosition + * @param totalDays จำนวนวันรวม + * @returns { year, month, day } ปี เดือน วัน */ -export function normalizeDurationSumSimple( - years: number, - months: number, - days: number, -): { years: number; months: number; days: number } { - const DAYS_PER_MONTH = 30.4375; // Average days per month in Gregorian calendar +export function calculateTenure(totalDays: number) { + // Match stored procedure formula: + // days_diff / 365.2524 AS Years + // (days_diff / 30.4375) % 12 AS Months + // days_diff % 30.4375 AS Days - let totalMonths = months; - let totalDays = days; + const year = Math.floor(totalDays / 365.2524); + const month = Math.floor((totalDays / 30.4375) % 12); + const day = Math.floor(totalDays % 30.4375); - // Convert excess days to months - if (totalDays >= DAYS_PER_MONTH) { - const additionalMonths = Math.floor(totalDays / DAYS_PER_MONTH); - totalMonths += additionalMonths; - totalDays = totalDays - additionalMonths * DAYS_PER_MONTH; - } - - // Convert excess months to years - let totalYears = years; - if (totalMonths >= 12) { - const additionalYears = Math.floor(totalMonths / 12); - totalYears += additionalYears; - totalMonths = totalMonths % 12; - } - - return { years: totalYears, months: Math.floor(totalMonths), days: Math.floor(totalDays) }; + return { year, month, day }; } diff --git a/tsoa.json b/tsoa.json index e346e3b1..492907b8 100644 --- a/tsoa.json +++ b/tsoa.json @@ -29,12 +29,6 @@ "name": "X-API-Key", "description": "API KEY สำหรับ Web Service", "in": "header" - }, - "internalAuth": { - "type": "apiKey", - "name": "api-key", - "description": "API KEY สำหรับ Internal Service (.NET, HRMS)", - "in": "header" } }, "tags": [