From 7b84f8af7bafafaf421c2cbe2c6378af65ce1173 Mon Sep 17 00:00:00 2001 From: harid Date: Mon, 10 Nov 2025 13:48:34 +0700 Subject: [PATCH 01/38] #1831 --- .../OrganizationUnauthorizeController.ts | 648 ++++++++++++++++-- 1 file changed, 587 insertions(+), 61 deletions(-) diff --git a/src/controllers/OrganizationUnauthorizeController.ts b/src/controllers/OrganizationUnauthorizeController.ts index 64d52b4c..28c88db6 100644 --- a/src/controllers/OrganizationUnauthorizeController.ts +++ b/src/controllers/OrganizationUnauthorizeController.ts @@ -21,6 +21,7 @@ import { viewProfileEmployeeEvaluation } from "../entities/view/viewProfileEmplo import Extension from "../interfaces/extension"; import { resetPassword } from "../keycloak"; import { viewEmployeePosMaster } from "../entities/view/viewEmployeePosMaster"; +import { EmployeePosDict } from "../entities/EmployeePosDict"; @Route("api/v1/org/unauthorize") @Tags("OrganizationUnauthorize") @Response( @@ -37,6 +38,7 @@ export class OrganizationUnauthorizeController extends Controller { private viewProfileEmployeeEvaluationRepo = AppDataSource.getRepository( viewProfileEmployeeEvaluation, ); + private employeePosDictRepository = AppDataSource.getRepository(EmployeePosDict); @Post("user/reset-password") async forgetPassword( @@ -1505,22 +1507,25 @@ export class OrganizationUnauthorizeController extends Controller { return new HttpSuccess(data); } - /** - * 3. API Get Profile จาก keycloak id - * - * @summary 3. API Get Profile จาก keycloak id - * - * @param {string} keycloakId Id keycloak - */ @Get("root/officer/{rootId}") async GetProfileByRootIdAsync(@Path() rootId: string) { const profiles = await this.profileRepo.find({ - relations: { - posLevel: true, - posType: true, - profileSalary: true, - profileInsignias: true, - }, + relations: [ + "posLevel", + "posType", + "profileSalary", + "profileInsignias", + "profileInsignias.insignia", + "profileDisciplines", + "profileAssessments", + "current_holders", + "current_holders.orgRevision", + "current_holders.orgRoot", + "current_holders.orgChild1", + "current_holders.orgChild2", + "current_holders.orgChild3", + "current_holders.orgChild4", + ], where: { current_holders: { orgRootId: rootId } }, order: { profileSalary: { @@ -1531,55 +1536,267 @@ export class OrganizationUnauthorizeController extends Controller { }, }, }); - // if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); - const mapProfile = profiles.map((profile) => ({ - id: profile.id, - avatar: profile.avatar, - avatarName: profile.avatarName, - rank: profile.rank, - prefix: profile.prefix, - firstName: profile.firstName, - lastName: profile.lastName, - citizenId: profile.citizenId, - position: profile.position, - posLevelId: profile.posLevelId, - email: profile.email, - phone: profile.phone, - keycloak: profile.keycloak, - isProbation: profile.isProbation, - isLeave: profile.isLeave, - leaveReason: profile.leaveReason, - dateRetire: profile.dateRetire, - dateAppoint: profile.dateAppoint, - dateRetireLaw: profile.dateRetireLaw, - dateStart: profile.dateStart, - govAgeAbsent: profile.govAgeAbsent, - govAgePlus: profile.govAgePlus, - birthDate: profile.birthDate, - reasonSameDate: profile.reasonSameDate, - telephoneNumber: profile.phone, - nationality: profile.nationality, - gender: profile.gender, - relationship: profile.relationship, - religion: profile.religion, - bloodGroup: profile.bloodGroup, - registrationAddress: profile.registrationAddress, - registrationProvinceId: profile.registrationProvinceId, - registrationDistrictId: profile.registrationDistrictId, - registrationSubDistrictId: profile.registrationSubDistrictId, - registrationZipCode: profile.registrationZipCode, - currentAddress: profile.currentAddress, - currentProvinceId: profile.currentProvinceId, - currentSubDistrictId: profile.currentSubDistrictId, - currentZipCode: profile.currentZipCode, - dutyTimeId: profile.dutyTimeId, - dutyTimeEffectiveDate: profile.dutyTimeEffectiveDate, - posLevel: profile.posLevel ? profile.posLevel : null, - posType: profile.posType ? profile.posType : null, - profileSalary: profile.profileSalary, - profileInsignia: profile.profileInsignias, - })); + const currentYear = new Date().getFullYear(); + const years = [currentYear, currentYear - 1, currentYear - 2, currentYear - 3, currentYear - 4]; + + // APR Averages + const aprAverages: { [year: number]: number | null } = {}; + const aprSums: { [year: number]: number } = {}; + const aprCounts: { [year: number]: number } = {}; + + // OCT Averages + const octAverages: { [year: number]: number | null } = {}; + const octSums: { [year: number]: number } = {}; + const octCounts: { [year: number]: number } = {}; + + years.forEach((year) => { + aprAverages[year] = null; + aprSums[year] = 0; + aprCounts[year] = 0; + + octAverages[year] = null; + octSums[year] = 0; + octCounts[year] = 0; + }); + + profiles.forEach((profile) => { + const assessments = profile.profileAssessments || []; + + assessments.forEach((assessment) => { + const year = Number(assessment.year); + + if (years.includes(year)) { + if (assessment.period === "APR") { + aprSums[year] += assessment.pointSum; + aprCounts[year] += 1; + } + + if (assessment.period === "OCT") { + octSums[year] += assessment.pointSum; + octCounts[year] += 1; + } + } + }); + }); + + years.forEach((year) => { + aprAverages[year] = aprCounts[year] > 0 ? aprSums[year] / aprCounts[year] : null; + octAverages[year] = octCounts[year] > 0 ? octSums[year] / octCounts[year] : null; + }); + + const findRevision = await this.orgRevisionRepository.findOne({ + where: { orgRevisionIsCurrent: true }, + }); + + const mapProfile = profiles.map((profile) => { + const shortName = + 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.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.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.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.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 + ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id)?.orgRoot.orgRootShortName} ${profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id)?.posMasterNo}` + : null; + + return { + id: profile.id, + avatar: profile.avatar, + avatarName: profile.avatarName, + rank: profile.rank ?? "", + prefix: profile.prefix ?? "", + firstName: profile.firstName ?? "", + lastName: profile.lastName ?? "", + citizenId: profile.citizenId ?? "", + position: profile.position ?? "", + posLevelId: profile.posLevelId, + posTypeId: profile.posTypeId, + email: profile.email, + phone: profile.phone, + keycloak: profile.keycloak, + isProbation: profile.isProbation, + isLeave: profile.isLeave, + leaveReason: profile.leaveReason, + dateRetire: profile.dateRetire, + dateAppoint: profile.dateAppoint, + dateRetireLaw: profile.dateRetireLaw, + dateStart: profile.dateStart, + govAgeAbsent: profile.govAgeAbsent, + govAgePlus: profile.govAgePlus, + birthDate: profile.birthDate ?? new Date(), + reasonSameDate: profile.reasonSameDate, + telephoneNumber: profile.phone, + nationality: profile.nationality, + gender: profile.gender ?? "", + relationship: profile.relationship ?? "", + religion: profile.religion ?? "", + bloodGroup: profile.bloodGroup ?? "", + registrationAddress: profile.registrationAddress, + registrationProvinceId: profile.registrationProvinceId, + registrationDistrictId: profile.registrationDistrictId, + registrationSubDistrictId: profile.registrationSubDistrictId, + registrationZipCode: profile.registrationZipCode, + currentAddress: profile.currentAddress, + currentProvinceId: profile.currentProvinceId, + currentSubDistrictId: profile.currentSubDistrictId, + currentZipCode: profile.currentZipCode, + dutyTimeId: profile.dutyTimeId, + dutyTimeEffectiveDate: profile.dutyTimeEffectiveDate, + posLevel: profile.posLevel?.posLevelName ?? "", + posType: profile.posType?.posTypeName ?? "", + profileSalary: profile.profileSalary, + profileInsignia: profile.profileInsignias.map((x) => { + return { ...x, insignia: x.insignia.name }; + }), + amount: profile.amount, + positionSalaryAmount: profile.positionSalaryAmount, + mouthSalaryAmount: profile.mouthSalaryAmount, + profileType: "OFFICER", + root: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgRoot?.orgRootName ?? null, + rootId: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgRootId ?? null, + rootDnaId: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgRoot?.ancestorDNA ?? null, + child1: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild1?.orgChild1Name ?? null, + child1Id: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild1Id ?? null, + child1DnaId: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild1?.ancestorDNA ?? null, + child2: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild2?.orgChild2Name ?? null, + child2Id: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild2Id ?? null, + child2DnaId: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild2?.ancestorDNA ?? null, + child3: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild3?.orgChild3Name ?? null, + child3Id: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild3Id ?? null, + child3DnaId: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild3?.ancestorDNA ?? null, + child4: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild4?.orgChild4Name ?? null, + child4Id: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild4Id ?? null, + child4DnaId: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild4?.ancestorDNA ?? null, + posNo: shortName ?? "", + markDiscipline: profile.profileDisciplines.length > 0 ? true : false, + markLeave: false, + markRate: profile.profileAssessments.length > 0 ? true : false, + markInsignia: profile.profileInsignias.length > 0 ? true : false, + apr1: aprAverages[currentYear] + ? Extension.textPoint(aprAverages[currentYear] as number) + : null, + apr2: aprAverages[currentYear - 1] + ? Extension.textPoint(aprAverages[currentYear - 1] as number) + : null, + apr3: aprAverages[currentYear - 2] + ? Extension.textPoint(aprAverages[currentYear - 2] as number) + : null, + apr4: aprAverages[currentYear - 3] + ? Extension.textPoint(aprAverages[currentYear - 3] as number) + : null, + apr5: aprAverages[currentYear - 4] + ? Extension.textPoint(aprAverages[currentYear - 4] as number) + : null, + oct1: octAverages[currentYear] + ? Extension.textPoint(octAverages[currentYear] as number) + : null, + oct2: octAverages[currentYear - 1] + ? Extension.textPoint(octAverages[currentYear - 1] as number) + : null, + oct3: octAverages[currentYear - 2] + ? Extension.textPoint(octAverages[currentYear - 2] as number) + : null, + oct4: octAverages[currentYear - 3] + ? Extension.textPoint(octAverages[currentYear - 3] as number) + : null, + oct5: octAverages[currentYear - 4] + ? Extension.textPoint(octAverages[currentYear - 4] as number) + : null, + }; + }); return new HttpSuccess(mapProfile); } @@ -1663,6 +1880,315 @@ export class OrganizationUnauthorizeController extends Controller { return new HttpSuccess(mapProfile); } + @Post("find/employee/position") + async GetProfileByPositionEmpAsync( + @Body() + body: { + empPosId: string[]; + rootId: string; + }, + ) { + const findRevision = await this.orgRevisionRepository.findOne({ + where: { orgRevisionIsCurrent: true }, + }); + const employeePosDict = await this.employeePosDictRepository.find({ + where: { id: In(body.empPosId) }, + }); + + const profiles = await this.profileEmpRepo.find({ + relations: [ + "posLevel", + "posType", + "profileSalary", + "profileInsignias", + "profileInsignias.insignia", + "profileDisciplines", + "profileAssessments", + "current_holders", + "current_holders.orgRevision", + "current_holders.orgRoot", + "current_holders.orgChild1", + "current_holders.orgChild2", + "current_holders.orgChild3", + "current_holders.orgChild4", + ], + where: employeePosDict.map((entry) => ({ + posLevelId: entry.posLevelId, + posTypeId: entry.posTypeId, + position: entry.posDictName, + current_holders: { orgRootId: body.rootId }, + })), + order: { + profileSalary: { + commandDateAffect: "DESC", + }, + profileInsignias: { + receiveDate: "DESC", + }, + }, + }); + + const currentYear = new Date().getFullYear(); + const years = [currentYear, currentYear - 1, currentYear - 2, currentYear - 3, currentYear - 4]; + + // APR Averages + const aprAverages: { [year: number]: number | null } = {}; + const aprSums: { [year: number]: number } = {}; + const aprCounts: { [year: number]: number } = {}; + + // OCT Averages + const octAverages: { [year: number]: number | null } = {}; + const octSums: { [year: number]: number } = {}; + const octCounts: { [year: number]: number } = {}; + + years.forEach((year) => { + aprAverages[year] = null; + aprSums[year] = 0; + aprCounts[year] = 0; + + octAverages[year] = null; + octSums[year] = 0; + octCounts[year] = 0; + }); + + profiles.forEach((profile) => { + const assessments = profile.profileAssessments || []; + + assessments.forEach((assessment) => { + const year = Number(assessment.year); + + if (years.includes(year)) { + if (assessment.period === "APR") { + aprSums[year] += assessment.pointSum; + aprCounts[year] += 1; + } + + if (assessment.period === "OCT") { + octSums[year] += assessment.pointSum; + octCounts[year] += 1; + } + } + }); + }); + + years.forEach((year) => { + aprAverages[year] = aprCounts[year] > 0 ? aprSums[year] / aprCounts[year] : null; + octAverages[year] = octCounts[year] > 0 ? octSums[year] / octCounts[year] : null; + }); + + const mapProfile = profiles.map((profile) => { + const shortName = + 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.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.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.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.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 + ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id)?.orgRoot.orgRootShortName} ${profile.current_holders.find((x) => x.orgRevisionId == findRevision?.id)?.posMasterNo}` + : null; + return { + id: profile.id, + avatar: profile.avatar, + avatarName: profile.avatarName, + rank: profile.rank ?? "", + prefix: profile.prefix ?? "", + firstName: profile.firstName ?? "", + lastName: profile.lastName ?? "", + citizenId: profile.citizenId ?? "", + position: profile.position ?? "", + posLevelId: profile.posLevelId, + email: profile.email, + phone: profile.phone, + keycloak: profile.keycloak, + isProbation: profile.isProbation, + isLeave: profile.isLeave, + leaveReason: profile.leaveReason, + dateRetire: profile.dateRetire, + dateAppoint: profile.dateAppoint, + dateRetireLaw: profile.dateRetireLaw, + dateStart: profile.dateStart, + govAgeAbsent: profile.govAgeAbsent, + govAgePlus: profile.govAgePlus, + birthDate: profile.birthDate ?? new Date(), + reasonSameDate: profile.reasonSameDate, + telephoneNumber: profile.phone, + nationality: profile.nationality, + gender: profile.gender ?? "", + relationship: profile.relationship ?? "", + religion: profile.religion ?? "", + bloodGroup: profile.bloodGroup ?? "", + registrationAddress: profile.registrationAddress, + registrationProvinceId: profile.registrationProvinceId, + registrationDistrictId: profile.registrationDistrictId, + registrationSubDistrictId: profile.registrationSubDistrictId, + registrationZipCode: profile.registrationZipCode, + currentAddress: profile.currentAddress, + currentProvinceId: profile.currentProvinceId, + currentSubDistrictId: profile.currentSubDistrictId, + currentZipCode: profile.currentZipCode, + posLevel: + (profile.posType == null || profile.posType?.posTypeShortName == null + ? "" + : profile.posType?.posTypeShortName + " ") + (profile.posLevel?.posLevelName ?? ""), + posType: profile.posType?.posTypeName ?? "", + profileSalary: profile.profileSalary.map((x) => { + return { ...x, date: x.commandDateAffect ?? new Date() }; + }), + profileInsignia: profile.profileInsignias.map((x) => { + return { ...x, insignia: x.insignia.name }; + }), + amount: profile.amount, + positionSalaryAmount: profile.positionSalaryAmount, + mouthSalaryAmount: profile.mouthSalaryAmount, + profileType: "EMPLOYEE", + root: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgRoot?.orgRootName ?? null, + rootId: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgRootId ?? null, + rootDnaId: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgRoot?.ancestorDNA ?? null, + child1: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild1?.orgChild1Name ?? null, + child1Id: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild1Id ?? null, + child1DnaId: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild1?.ancestorDNA ?? null, + child2: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild2?.orgChild2Name ?? null, + child2Id: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild2Id ?? null, + child2DnaId: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild2?.ancestorDNA ?? null, + child3: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild3?.orgChild3Name ?? null, + child3Id: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild3Id ?? null, + child3DnaId: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild3?.ancestorDNA ?? null, + child4: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild4?.orgChild4Name ?? null, + child4Id: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild4Id ?? null, + child4DnaId: + profile?.current_holders?.find( + (x) => + x.orgRevision?.orgRevisionIsDraft == false && + x.orgRevision?.orgRevisionIsCurrent == true, + )?.orgChild4?.ancestorDNA ?? null, + posNo: shortName ?? "", + markDiscipline: profile.profileDisciplines.length > 0 ? true : false, + markLeave: false, + markRate: profile.profileAssessments.length > 0 ? true : false, + markInsignia: profile.profileInsignias.length > 0 ? true : false, + apr1: aprAverages[currentYear] + ? Extension.textPoint(aprAverages[currentYear] as number) + : null, + apr2: aprAverages[currentYear - 1] + ? Extension.textPoint(aprAverages[currentYear - 1] as number) + : null, + apr3: aprAverages[currentYear - 2] + ? Extension.textPoint(aprAverages[currentYear - 2] as number) + : null, + apr4: aprAverages[currentYear - 3] + ? Extension.textPoint(aprAverages[currentYear - 3] as number) + : null, + apr5: aprAverages[currentYear - 4] + ? Extension.textPoint(aprAverages[currentYear - 4] as number) + : null, + oct1: octAverages[currentYear] + ? Extension.textPoint(octAverages[currentYear] as number) + : null, + oct2: octAverages[currentYear - 1] + ? Extension.textPoint(octAverages[currentYear - 1] as number) + : null, + oct3: octAverages[currentYear - 2] + ? Extension.textPoint(octAverages[currentYear - 2] as number) + : null, + oct4: octAverages[currentYear - 3] + ? Extension.textPoint(octAverages[currentYear - 3] as number) + : null, + oct5: octAverages[currentYear - 4] + ? Extension.textPoint(octAverages[currentYear - 4] as number) + : null, + }; + }); + + return new HttpSuccess(mapProfile); + } + /** * API ยืนยัน Email * From b329dcaa0e04e7863a1a9f68836946816eb37888 Mon Sep 17 00:00:00 2001 From: Adisak Date: Mon, 10 Nov 2025 15:35:30 +0700 Subject: [PATCH 02/38] update clear user in org draft --- src/interfaces/utils.ts | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/interfaces/utils.ts b/src/interfaces/utils.ts index cf86f369..78c01910 100644 --- a/src/interfaces/utils.ts +++ b/src/interfaces/utils.ts @@ -259,7 +259,13 @@ export async function removeProfileInOrganize(profileId: string, type: string) { .andWhere("orgRevision.orgRevisionIsCurrent = true") .getOne(); - if (!currentRevision) { + const draftRevision = await AppDataSource.getRepository(OrgRevision) + .createQueryBuilder("orgRevision") + .where("orgRevision.orgRevisionIsDraft = true") + .andWhere("orgRevision.orgRevisionIsCurrent = false") + .getOne(); + + if (!currentRevision && !draftRevision) { return; } if (type === "OFFICER") { @@ -276,7 +282,20 @@ export async function removeProfileInOrganize(profileId: string, type: string) { .where("id = :id", { id: findProfileInposMaster?.id }) .execute(); - if (!findProfileInposMaster) { + const findProfileInposMasterDraft = await AppDataSource.getRepository(PosMaster) + .createQueryBuilder("posMaster") + .where("posMaster.orgRevisionId = :orgRevisionId", { orgRevisionId: draftRevision?.id }) + .andWhere("posMaster.current_holderId = :profileId", { profileId }) + .getOne(); + + await AppDataSource.getRepository(PosMaster) + .createQueryBuilder() + .update(PosMaster) + .set({ next_holderId: null }) + .where("id = :id", { id: findProfileInposMasterDraft?.id }) + .execute(); + + if (!findProfileInposMaster && !findProfileInposMasterDraft) { return; } const findPosition = await AppDataSource.getRepository(Position) From 7737f09493809a595a2c0d8a69563648daf66c3e Mon Sep 17 00:00:00 2001 From: Adisak Date: Mon, 10 Nov 2025 15:54:49 +0700 Subject: [PATCH 03/38] update --- src/interfaces/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/utils.ts b/src/interfaces/utils.ts index 78c01910..12636a36 100644 --- a/src/interfaces/utils.ts +++ b/src/interfaces/utils.ts @@ -285,7 +285,7 @@ export async function removeProfileInOrganize(profileId: string, type: string) { const findProfileInposMasterDraft = await AppDataSource.getRepository(PosMaster) .createQueryBuilder("posMaster") .where("posMaster.orgRevisionId = :orgRevisionId", { orgRevisionId: draftRevision?.id }) - .andWhere("posMaster.current_holderId = :profileId", { profileId }) + .andWhere("posMaster.next_holderId = :profileId", { profileId }) .getOne(); await AppDataSource.getRepository(PosMaster) From 5029890831c15c21ee2ee846861655d74073eb73 Mon Sep 17 00:00:00 2001 From: mamoss <> Date: Wed, 12 Nov 2025 01:55:06 +0700 Subject: [PATCH 04/38] check api-key --- src/middlewares/auth.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/middlewares/auth.ts b/src/middlewares/auth.ts index 396ada4d..1f636080 100644 --- a/src/middlewares/auth.ts +++ b/src/middlewares/auth.ts @@ -27,6 +27,14 @@ export async function expressAuthentication( securityName: string, _scopes?: string[], ) { + // API_KEY bypass logic (support api_key, x-api-key, apikey) + const apiKeyHeader = + request.headers["api-key"] || request.headers["x-api-key"] || request.headers["apikey"]; + if (apiKeyHeader !== undefined) { + if (apiKeyHeader === process.env.API_KEY) { + return { preferred_username: "api_key_bypass", apiKeyBypass: true }; + } + } if (process.env.NODE_ENV !== "production" && process.env.AUTH_BYPASS) { return { preferred_username: "bypassed" }; } From 83de71c40cd7e553ad913beef54616f8534cb745 Mon Sep 17 00:00:00 2001 From: Adisak Date: Wed, 12 Nov 2025 14:39:44 +0700 Subject: [PATCH 05/38] #1945 fix --- src/controllers/ProfileController.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index 57d618c6..f4769367 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -86,7 +86,7 @@ import { ProfileSalaryHistory } from "../entities/ProfileSalaryHistory"; import { ProfileAssistance } from "../entities/ProfileAssistance"; import { CommandRecive } from "../entities/CommandRecive"; import { EmployeePosMaster } from "../entities/EmployeePosMaster"; -import { getTopDegrees } from "../services/PositionService"; +import { CreatePosMasterHistoryOfficer, getTopDegrees } from "../services/PositionService"; import { ProfileLeaveService } from "../services/ProfileLeaveService"; @Route("api/v1/org/profile") @@ -10789,6 +10789,9 @@ export class ProfileController extends Controller { await this.profileRepo.save(profile, { data: request }); setLogDataDiff(request, { before, after: profile }); if (requestBody.isLeave == true) { + if(orgRevisionRef){ + await CreatePosMasterHistoryOfficer(orgRevisionRef.id, request); + } await removeProfileInOrganize(profile.id, "OFFICER"); } return new HttpSuccess(); From 841d4d271f119a255d29bc38e26e30e0037f1759 Mon Sep 17 00:00:00 2001 From: Adisak Date: Wed, 12 Nov 2025 15:02:17 +0700 Subject: [PATCH 06/38] test --- src/middlewares/auth.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/middlewares/auth.ts b/src/middlewares/auth.ts index 1f636080..c27e6188 100644 --- a/src/middlewares/auth.ts +++ b/src/middlewares/auth.ts @@ -27,14 +27,14 @@ export async function expressAuthentication( securityName: string, _scopes?: string[], ) { - // API_KEY bypass logic (support api_key, x-api-key, apikey) - const apiKeyHeader = - request.headers["api-key"] || request.headers["x-api-key"] || request.headers["apikey"]; - if (apiKeyHeader !== undefined) { - if (apiKeyHeader === process.env.API_KEY) { - return { preferred_username: "api_key_bypass", apiKeyBypass: true }; - } - } + // // API_KEY bypass logic (support api_key, x-api-key, apikey) + // const apiKeyHeader = + // request.headers["api-key"] || request.headers["x-api-key"] || request.headers["apikey"]; + // if (apiKeyHeader !== undefined) { + // if (apiKeyHeader === process.env.API_KEY) { + // return { preferred_username: "api_key_bypass", apiKeyBypass: true }; + // } + // } if (process.env.NODE_ENV !== "production" && process.env.AUTH_BYPASS) { return { preferred_username: "bypassed" }; } From b468d7bfe9c5103da1c8e2ac890a3135ebf76d8e Mon Sep 17 00:00:00 2001 From: Adisak Date: Wed, 12 Nov 2025 15:18:07 +0700 Subject: [PATCH 07/38] test fix --- src/middlewares/auth.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/middlewares/auth.ts b/src/middlewares/auth.ts index c27e6188..d18c2578 100644 --- a/src/middlewares/auth.ts +++ b/src/middlewares/auth.ts @@ -27,14 +27,16 @@ export async function expressAuthentication( securityName: string, _scopes?: string[], ) { - // // API_KEY bypass logic (support api_key, x-api-key, apikey) - // const apiKeyHeader = - // request.headers["api-key"] || request.headers["x-api-key"] || request.headers["apikey"]; - // if (apiKeyHeader !== undefined) { - // if (apiKeyHeader === process.env.API_KEY) { - // return { preferred_username: "api_key_bypass", apiKeyBypass: true }; - // } - // } + // API_KEY bypass logic (support api_key, x-api-key, apikey) + const apiKeyHeader = + request.headers["api-key"] || request.headers["x-api-key"] || request.headers["apikey"]; + if (apiKeyHeader !== undefined) { + if (apiKeyHeader === process.env.API_KEY) { + return { preferred_username: "api_key_bypass", apiKeyBypass: true }; + } else { + return undefined; + } + } if (process.env.NODE_ENV !== "production" && process.env.AUTH_BYPASS) { return { preferred_username: "bypassed" }; } From f035713e34054c7395d98265b38b57cb22b8c8c9 Mon Sep 17 00:00:00 2001 From: Adisak Date: Wed, 12 Nov 2025 15:21:59 +0700 Subject: [PATCH 08/38] fix and test --- src/controllers/ProfileController.ts | 2 +- src/middlewares/auth.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index f4769367..e1573661 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -10790,7 +10790,7 @@ export class ProfileController extends Controller { setLogDataDiff(request, { before, after: profile }); if (requestBody.isLeave == true) { if(orgRevisionRef){ - await CreatePosMasterHistoryOfficer(orgRevisionRef.id, request); + await CreatePosMasterHistoryOfficer(orgRevisionRef.id, request, "DELETE"); } await removeProfileInOrganize(profile.id, "OFFICER"); } diff --git a/src/middlewares/auth.ts b/src/middlewares/auth.ts index d18c2578..4f2d5438 100644 --- a/src/middlewares/auth.ts +++ b/src/middlewares/auth.ts @@ -34,7 +34,7 @@ export async function expressAuthentication( if (apiKeyHeader === process.env.API_KEY) { return { preferred_username: "api_key_bypass", apiKeyBypass: true }; } else { - return undefined; + throw new HttpError(HttpStatus.FORBIDDEN, "API key ไม่ถูกต้อง"); } } if (process.env.NODE_ENV !== "production" && process.env.AUTH_BYPASS) { From 129ea8c102d99eb09055de96d5ac1e469cc63900 Mon Sep 17 00:00:00 2001 From: Adisak Date: Wed, 12 Nov 2025 15:24:38 +0700 Subject: [PATCH 09/38] revert --- src/middlewares/auth.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/middlewares/auth.ts b/src/middlewares/auth.ts index 4f2d5438..c27e6188 100644 --- a/src/middlewares/auth.ts +++ b/src/middlewares/auth.ts @@ -27,16 +27,14 @@ export async function expressAuthentication( securityName: string, _scopes?: string[], ) { - // API_KEY bypass logic (support api_key, x-api-key, apikey) - const apiKeyHeader = - request.headers["api-key"] || request.headers["x-api-key"] || request.headers["apikey"]; - if (apiKeyHeader !== undefined) { - if (apiKeyHeader === process.env.API_KEY) { - return { preferred_username: "api_key_bypass", apiKeyBypass: true }; - } else { - throw new HttpError(HttpStatus.FORBIDDEN, "API key ไม่ถูกต้อง"); - } - } + // // API_KEY bypass logic (support api_key, x-api-key, apikey) + // const apiKeyHeader = + // request.headers["api-key"] || request.headers["x-api-key"] || request.headers["apikey"]; + // if (apiKeyHeader !== undefined) { + // if (apiKeyHeader === process.env.API_KEY) { + // return { preferred_username: "api_key_bypass", apiKeyBypass: true }; + // } + // } if (process.env.NODE_ENV !== "production" && process.env.AUTH_BYPASS) { return { preferred_username: "bypassed" }; } From 85121ffae8101bc585c491270912d82444da9ab4 Mon Sep 17 00:00:00 2001 From: Adisak Date: Wed, 12 Nov 2025 16:35:18 +0700 Subject: [PATCH 10/38] #1948 , #1950 , #1951 --- src/controllers/CommandController.ts | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index e4538538..29b9533c 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -4266,12 +4266,22 @@ export class CommandController extends Controller { body.data.map(async (item) => { const profile: any = await this.profileRepository.findOne({ where: { id: item.profileId }, - relations: ["roleKeycloaks"], + relations: ["roleKeycloaks","current_holders"], }); if (!profile) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทะเบียนประวัตินี้"); } + const orgRevision = await this.orgRevisionRepo.findOne({ + where: { + orgRevisionIsCurrent: true, + orgRevisionIsDraft: false, + }, + }); + + const orgRevisionRef = + profile?.current_holders?.find((x:any) => x.orgRevisionId == orgRevision?.id) ?? null; + //ลบตำแหน่งที่รักษาการแทน const code = _command?.commandType?.code; if (code && ["C-PM-13"].includes(code)) { @@ -4300,6 +4310,9 @@ export class CommandController extends Controller { lastUpdatedAt: new Date(), }; if (item.isLeave != undefined && item.isLeave == true) { + if(orgRevisionRef){ + await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); + } await removeProfileInOrganize(profile.id, "OFFICER"); } const clearProfile = await checkCommandType(String(item.commandId)); @@ -4628,8 +4641,8 @@ export class CommandController extends Controller { orgRevisionIsDraft: false, }, }); - // const orgRevisionRef = - // profile?.current_holders?.find((x) => x.orgRevisionId == orgRevision?.id) ?? null; + const orgRevisionRef = + profile?.current_holders?.find((x) => x.orgRevisionId == orgRevision?.id) ?? null; // const orgRootRef = orgRevisionRef?.orgRoot ?? null; // const orgChild1Ref = orgRevisionRef?.orgChild1 ?? null; // const orgChild2Ref = orgRevisionRef?.orgChild2 ?? null; @@ -4770,6 +4783,9 @@ export class CommandController extends Controller { _profile.leaveDate = item.commandDateAffect ?? _null; _profile.leaveType = exceptClear.LeaveType ?? _null; } else { + if(orgRevisionRef){ + await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); + } await removeProfileInOrganize(_profile.id, "OFFICER"); } } From 043a2d344efdb6a2132439150ddc83bce9dc16e0 Mon Sep 17 00:00:00 2001 From: Adisak Date: Wed, 12 Nov 2025 17:28:32 +0700 Subject: [PATCH 11/38] fix --- src/controllers/CommandController.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index 29b9533c..42aab934 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -4310,9 +4310,9 @@ export class CommandController extends Controller { lastUpdatedAt: new Date(), }; if (item.isLeave != undefined && item.isLeave == true) { - if(orgRevisionRef){ - await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); - } + // if(orgRevisionRef){ + // await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); + // } await removeProfileInOrganize(profile.id, "OFFICER"); } const clearProfile = await checkCommandType(String(item.commandId)); From 3d689ff19c01ff511f67e7a0d7bb9852d61ed752 Mon Sep 17 00:00:00 2001 From: Adisak Date: Wed, 12 Nov 2025 17:50:42 +0700 Subject: [PATCH 12/38] log --- src/controllers/CommandController.ts | 8 +++++--- src/interfaces/utils.ts | 22 +++++++++++++++------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index 42aab934..e7f883d0 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -4310,10 +4310,12 @@ export class CommandController extends Controller { lastUpdatedAt: new Date(), }; if (item.isLeave != undefined && item.isLeave == true) { - // if(orgRevisionRef){ - // await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); - // } + if(orgRevisionRef){ + await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); + } + console.log("A"); await removeProfileInOrganize(profile.id, "OFFICER"); + console.log("Z"); } const clearProfile = await checkCommandType(String(item.commandId)); const _null: any = null; diff --git a/src/interfaces/utils.ts b/src/interfaces/utils.ts index 12636a36..f5c9e608 100644 --- a/src/interfaces/utils.ts +++ b/src/interfaces/utils.ts @@ -253,65 +253,73 @@ export function calculateRetireYear(birthDate: Date) { return yy + 61; } export async function removeProfileInOrganize(profileId: string, type: string) { + console.log(1); const currentRevision = await AppDataSource.getRepository(OrgRevision) .createQueryBuilder("orgRevision") .where("orgRevision.orgRevisionIsDraft = false") .andWhere("orgRevision.orgRevisionIsCurrent = true") .getOne(); - + console.log(2); const draftRevision = await AppDataSource.getRepository(OrgRevision) .createQueryBuilder("orgRevision") .where("orgRevision.orgRevisionIsDraft = true") .andWhere("orgRevision.orgRevisionIsCurrent = false") .getOne(); - + console.log(3); if (!currentRevision && !draftRevision) { + console.log(4); return; } if (type === "OFFICER") { + console.log(5); const findProfileInposMaster = await AppDataSource.getRepository(PosMaster) .createQueryBuilder("posMaster") .where("posMaster.orgRevisionId = :orgRevisionId", { orgRevisionId: currentRevision?.id }) .andWhere("posMaster.current_holderId = :profileId", { profileId }) .getOne(); - + console.log(6); await AppDataSource.getRepository(PosMaster) .createQueryBuilder() .update(PosMaster) .set({ current_holderId: null }) .where("id = :id", { id: findProfileInposMaster?.id }) .execute(); - + console.log(7); const findProfileInposMasterDraft = await AppDataSource.getRepository(PosMaster) .createQueryBuilder("posMaster") .where("posMaster.orgRevisionId = :orgRevisionId", { orgRevisionId: draftRevision?.id }) .andWhere("posMaster.next_holderId = :profileId", { profileId }) .getOne(); - + console.log(8); await AppDataSource.getRepository(PosMaster) .createQueryBuilder() .update(PosMaster) .set({ next_holderId: null }) .where("id = :id", { id: findProfileInposMasterDraft?.id }) .execute(); - + console.log(9); if (!findProfileInposMaster && !findProfileInposMasterDraft) { + console.log(10); return; } + console.log(11); const findPosition = await AppDataSource.getRepository(Position) .createQueryBuilder("position") .where("position.posMasterId = :posMasterId", { posMasterId: findProfileInposMaster?.id }) .getMany(); - + console.log(12); if (!findPosition) { + console.log(13); return; } + console.log(13); await AppDataSource.getRepository(Position) .createQueryBuilder() .update(Position) .set({ positionIsSelected: false }) .where("id IN (:...ids)", { ids: findPosition.map((item) => item.id) }) .execute(); + console.log(14); } if (type === "EMPLOYEE") { const findProfileInEmpPosMaster = await AppDataSource.getRepository(EmployeePosMaster) From 62750576d385ceb7c08523da1f378ae3c9801fcc Mon Sep 17 00:00:00 2001 From: Adisak Date: Wed, 12 Nov 2025 18:02:28 +0700 Subject: [PATCH 13/38] update --- src/controllers/CommandController.ts | 2 -- src/interfaces/utils.ts | 22 +++++++--------------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index e7f883d0..29b9533c 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -4313,9 +4313,7 @@ export class CommandController extends Controller { if(orgRevisionRef){ await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); } - console.log("A"); await removeProfileInOrganize(profile.id, "OFFICER"); - console.log("Z"); } const clearProfile = await checkCommandType(String(item.commandId)); const _null: any = null; diff --git a/src/interfaces/utils.ts b/src/interfaces/utils.ts index f5c9e608..12636a36 100644 --- a/src/interfaces/utils.ts +++ b/src/interfaces/utils.ts @@ -253,73 +253,65 @@ export function calculateRetireYear(birthDate: Date) { return yy + 61; } export async function removeProfileInOrganize(profileId: string, type: string) { - console.log(1); const currentRevision = await AppDataSource.getRepository(OrgRevision) .createQueryBuilder("orgRevision") .where("orgRevision.orgRevisionIsDraft = false") .andWhere("orgRevision.orgRevisionIsCurrent = true") .getOne(); - console.log(2); + const draftRevision = await AppDataSource.getRepository(OrgRevision) .createQueryBuilder("orgRevision") .where("orgRevision.orgRevisionIsDraft = true") .andWhere("orgRevision.orgRevisionIsCurrent = false") .getOne(); - console.log(3); + if (!currentRevision && !draftRevision) { - console.log(4); return; } if (type === "OFFICER") { - console.log(5); const findProfileInposMaster = await AppDataSource.getRepository(PosMaster) .createQueryBuilder("posMaster") .where("posMaster.orgRevisionId = :orgRevisionId", { orgRevisionId: currentRevision?.id }) .andWhere("posMaster.current_holderId = :profileId", { profileId }) .getOne(); - console.log(6); + await AppDataSource.getRepository(PosMaster) .createQueryBuilder() .update(PosMaster) .set({ current_holderId: null }) .where("id = :id", { id: findProfileInposMaster?.id }) .execute(); - console.log(7); + const findProfileInposMasterDraft = await AppDataSource.getRepository(PosMaster) .createQueryBuilder("posMaster") .where("posMaster.orgRevisionId = :orgRevisionId", { orgRevisionId: draftRevision?.id }) .andWhere("posMaster.next_holderId = :profileId", { profileId }) .getOne(); - console.log(8); + await AppDataSource.getRepository(PosMaster) .createQueryBuilder() .update(PosMaster) .set({ next_holderId: null }) .where("id = :id", { id: findProfileInposMasterDraft?.id }) .execute(); - console.log(9); + if (!findProfileInposMaster && !findProfileInposMasterDraft) { - console.log(10); return; } - console.log(11); const findPosition = await AppDataSource.getRepository(Position) .createQueryBuilder("position") .where("position.posMasterId = :posMasterId", { posMasterId: findProfileInposMaster?.id }) .getMany(); - console.log(12); + if (!findPosition) { - console.log(13); return; } - console.log(13); await AppDataSource.getRepository(Position) .createQueryBuilder() .update(Position) .set({ positionIsSelected: false }) .where("id IN (:...ids)", { ids: findPosition.map((item) => item.id) }) .execute(); - console.log(14); } if (type === "EMPLOYEE") { const findProfileInEmpPosMaster = await AppDataSource.getRepository(EmployeePosMaster) From 92f4ccb30a69d941e51195a4ffedfb467996351f Mon Sep 17 00:00:00 2001 From: Adisak Date: Wed, 12 Nov 2025 18:20:02 +0700 Subject: [PATCH 14/38] test --- src/controllers/CommandController.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index 29b9533c..32a2c1c2 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -4266,21 +4266,21 @@ export class CommandController extends Controller { body.data.map(async (item) => { const profile: any = await this.profileRepository.findOne({ where: { id: item.profileId }, - relations: ["roleKeycloaks","current_holders"], + relations: ["roleKeycloaks"], }); if (!profile) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทะเบียนประวัตินี้"); } - const orgRevision = await this.orgRevisionRepo.findOne({ - where: { - orgRevisionIsCurrent: true, - orgRevisionIsDraft: false, - }, - }); + // const orgRevision = await this.orgRevisionRepo.findOne({ + // where: { + // orgRevisionIsCurrent: true, + // orgRevisionIsDraft: false, + // }, + // }); - const orgRevisionRef = - profile?.current_holders?.find((x:any) => x.orgRevisionId == orgRevision?.id) ?? null; + // const orgRevisionRef = + // profile?.current_holders?.find((x:any) => x.orgRevisionId == orgRevision?.id) ?? null; //ลบตำแหน่งที่รักษาการแทน const code = _command?.commandType?.code; @@ -4310,9 +4310,9 @@ export class CommandController extends Controller { lastUpdatedAt: new Date(), }; if (item.isLeave != undefined && item.isLeave == true) { - if(orgRevisionRef){ - await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); - } + // if(orgRevisionRef){ + // await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); + // } await removeProfileInOrganize(profile.id, "OFFICER"); } const clearProfile = await checkCommandType(String(item.commandId)); From 37790d56f44a7d2fbe90a7de3a9bac4d5fce8393 Mon Sep 17 00:00:00 2001 From: mamoss <> Date: Wed, 12 Nov 2025 23:28:16 +0700 Subject: [PATCH 15/38] add read me --- README.md | 109 +++++++++++++++++++++++++++++- scripts/clean-migration-fk-idx.js | 37 ++++++++++ src/database/data-source.ts | 4 +- 3 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 scripts/clean-migration-fk-idx.js diff --git a/README.md b/README.md index 7f9bda54..63577b2f 100644 --- a/README.md +++ b/README.md @@ -1 +1,108 @@ -# bma-ehr-organization +# hrms-api-org + +ระบบ API สำหรับจัดการข้อมูลบุคลากรและโครงสร้างองค์กร (HRMS) + +--- + +## ✨ Features + +- **RESTful API** (Express) +- **ฐานข้อมูล MySQL** (TypeORM) +- **Cronjob อัตโนมัติ** (node-cron) +- **WebSocket** สำหรับ real-time +- **RabbitMQ integration** +- **Swagger UI** สำหรับ API docs +- รองรับการ **import/export ข้อมูล** + +--- + +## 🗂️ โครงสร้างโปรเจกต์หลัก + +| Path | รายละเอียด | +| ----------------------------------- | ------------------------------------- | +| `src/controllers/` | API Controllers | +| `src/entities/` | Entity สำหรับ TypeORM | +| `src/services/` | Service logic (RabbitMQ, WebSocket) | +| `src/database/data-source.ts` | ตั้งค่าเชื่อมต่อฐานข้อมูล | +| `src/migration/` | ไฟล์ migration ของฐานข้อมูล | +| `static/` | ไฟล์ static และ config | +| `scripts/clean-migration-fk-idx.js` | สคริปต์ลบบรรทัด FK*/idx* ใน migration | + +--- + +## 🚀 การใช้งานเบื้องต้น + +1. **ติดตั้ง dependencies** + + ```sh + npm install + ``` + +2. **สร้างไฟล์ `.env`** + + - กำหนดค่าฐานข้อมูลและ API_KEY ตามต้องการ + +3. **Build และ Start** + + ```sh + npm run build + npm start + ``` + +4. **ดู API docs** + - เปิดที่ `http://localhost:3000/api-docs` + +--- + +## 🛠️ คำสั่งที่สำคัญ (npm scripts) + +- `npm run dev` : รันแบบ development (hot reload) +- `npm run build` : สร้างไฟล์สำหรับ production +- `npm run migration:generate` : สร้าง migration ใหม่ เช่น + + ```sh + npm run migration:generate src/migration/update_table_0811202s + ``` + +- `npm run migration:run` : รัน migration +- `node scripts/clean-migration-fk-idx.js` : ลบบรรทัดที่มี `FK_` หรือ `idx_` ใน migration อัตโนมัติ (ควรรันหลัง gen migration ทุกครั้ง) + +--- + +## 🐳 การ Build/Deploy ด้วย act (local GitHub Actions) + +หากต้องการ build และ deploy ด้วย workflow release (เช่น ทดสอบ pipeline บนเครื่อง) +ให้ใช้คำสั่งนี้: + +```sh +act workflow_dispatch -W .github/workflows/release.yaml --input IMAGE_VER=latest -s DOCKER_USER=admin -s DOCKER_PASS=FPTadmin2357 -s SSH_PASSWORD=FPTadmin2357 +``` + +**อธิบาย option ที่ใช้:** + +- `-W .github/workflows/release.yaml` : ระบุ workflow ที่จะรัน +- `--input IMAGE_VER=latest` : กำหนด tag ของ docker image (เช่น latest) +- `-s DOCKER_USER=...` : กำหนด secret สำหรับ docker registry +- `-s DOCKER_PASS=...` : กำหนด secret สำหรับ docker registry +- `-s SSH_PASSWORD=...` : กำหนด secret สำหรับ ssh deploy + +> ⚠️ **หมายเหตุ:** สำหรับ production ห้ามใช้รหัสผ่านจริงใน public repo หรือแชร์ credentials + +--- + +## ⚠️ หมายเหตุเกี่ยวกับ Migration + +- หลังจากใช้ `npm run migration:generate` แล้ว **ต้องลบบรรทัดที่มี `FK_` หรือ `idx_` ออกจากไฟล์ migration ทุกครั้ง** (ทั้งในฟังก์ชัน up/down) +- สามารถใช้สคริปต์นี้ช่วยลบอัตโนมัติ: + + ```sh + node scripts/clean-migration-fk-idx.js + ``` + +- สคริปต์นี้จะค้นหาและแทนที่บรรทัดที่มี `FK_` หรือ `idx_` ด้วย comment `// removed FK_/idx_ auto-cleanup` ในทุกไฟล์ migration + +--- + +## 📄 License + +Distributed under the ISC License. diff --git a/scripts/clean-migration-fk-idx.js b/scripts/clean-migration-fk-idx.js new file mode 100644 index 00000000..6743a7e6 --- /dev/null +++ b/scripts/clean-migration-fk-idx.js @@ -0,0 +1,37 @@ +// Script: scripts/clean-migration-fk-idx.js +// ลบบรรทัดที่มี FK_ หรือ idx_ ในไฟล์ migration ทั้งหมด และแทนที่ด้วย comment + +const fs = require("fs"); +const path = require("path"); + +const MIGRATION_DIR = path.join(__dirname, "../src/migration"); + +function processFile(filePath) { + const lines = fs.readFileSync(filePath, "utf8").split("\n"); + let changed = false; + const newLines = lines.map((line) => { + if (/FK_|idx_/.test(line)) { + changed = true; + return " // removed FK_/idx_ auto-cleanup"; + } + return line; + }); + if (changed) { + fs.writeFileSync(filePath, newLines.join("\n"), "utf8"); + console.log("Cleaned:", filePath); + } +} + +function walk(dir) { + fs.readdirSync(dir).forEach((f) => { + const fullPath = path.join(dir, f); + if (fs.statSync(fullPath).isDirectory()) { + walk(fullPath); + } else if (f.endsWith(".ts")) { + processFile(fullPath); + } + }); +} + +walk(MIGRATION_DIR); +console.log("Migration FK_/idx_ cleanup complete."); diff --git a/src/database/data-source.ts b/src/database/data-source.ts index 655d6386..9de306d7 100644 --- a/src/database/data-source.ts +++ b/src/database/data-source.ts @@ -47,9 +47,7 @@ export const AppDataSource = new DataSource({ logging: true, // timezone: "Z", entities: - process.env.NODE_ENV !== "production" - ? ["src/entities/**/*.ts"] - : ["dist/entities/**/*{.ts,.js}"], + process.env.NODE_ENV !== "production" ? ["src/entities/*.ts"] : ["dist/entities/*{.ts,.js}"], migrations: process.env.NODE_ENV !== "production" ? ["src/migration/**/*.ts"] From fab6b31d46da3c5a488102226df2f26613331553 Mon Sep 17 00:00:00 2001 From: mamoss <> Date: Wed, 12 Nov 2025 23:30:50 +0700 Subject: [PATCH 16/38] delete comment --- ...4755-update_table_apiKey_add_accessType.ts | 24 -- .../1762159481993-update_size_keyapi_field.ts | 17 - .../1762159824907-update_size_place_field.ts | 16 - ...dd_field_isAdminVisibled_table_AuthRole.ts | 14 - ...rApi_and_tokenApi_field_ApiHistoryTable.ts | 20 -- ...e_viewDirectior_and_viewDirectiorActing.ts | 292 ------------------ 6 files changed, 383 deletions(-) delete mode 100644 src/migration/1761330464755-update_table_apiKey_add_accessType.ts delete mode 100644 src/migration/1762159481993-update_size_keyapi_field.ts delete mode 100644 src/migration/1762159824907-update_size_place_field.ts delete mode 100644 src/migration/1762165716863-add_field_isAdminVisibled_table_AuthRole.ts delete mode 100644 src/migration/1762243747843-update_size_headerApi_and_tokenApi_field_ApiHistoryTable.ts delete mode 100644 src/migration/1762489522691-update_viewDirectior_and_viewDirectiorActing.ts diff --git a/src/migration/1761330464755-update_table_apiKey_add_accessType.ts b/src/migration/1761330464755-update_table_apiKey_add_accessType.ts deleted file mode 100644 index cfe72a82..00000000 --- a/src/migration/1761330464755-update_table_apiKey_add_accessType.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; - -export class UpdateTableApiKeyAddAccessType1761330464755 implements MigrationInterface { - name = 'UpdateTableApiKeyAddAccessType1761330464755' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`apiKey\` ADD \`accessType\` varchar(40) NULL COMMENT 'accessType'`); - await queryRunner.query(`ALTER TABLE \`apiKey\` ADD \`dnaRootId\` varchar(40) NULL COMMENT 'dnaRootId'`); - await queryRunner.query(`ALTER TABLE \`apiKey\` ADD \`dnaChild1Id\` varchar(40) NULL COMMENT 'dnaChild1Id'`); - await queryRunner.query(`ALTER TABLE \`apiKey\` ADD \`dnaChild2Id\` varchar(40) NULL COMMENT 'dnaChild2Id'`); - await queryRunner.query(`ALTER TABLE \`apiKey\` ADD \`dnaChild3Id\` varchar(40) NULL COMMENT 'dnaChild3Id'`); - await queryRunner.query(`ALTER TABLE \`apiKey\` ADD \`dnaChild4Id\` varchar(40) NULL COMMENT 'dnaChild4Id'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`apiKey\` DROP COLUMN \`dnaChild4Id\``); - await queryRunner.query(`ALTER TABLE \`apiKey\` DROP COLUMN \`dnaChild3Id\``); - await queryRunner.query(`ALTER TABLE \`apiKey\` DROP COLUMN \`dnaChild2Id\``); - await queryRunner.query(`ALTER TABLE \`apiKey\` DROP COLUMN \`dnaChild1Id\``); - await queryRunner.query(`ALTER TABLE \`apiKey\` DROP COLUMN \`dnaRootId\``); - await queryRunner.query(`ALTER TABLE \`apiKey\` DROP COLUMN \`accessType\``); - } - -} diff --git a/src/migration/1762159481993-update_size_keyapi_field.ts b/src/migration/1762159481993-update_size_keyapi_field.ts deleted file mode 100644 index 17b1b0d2..00000000 --- a/src/migration/1762159481993-update_size_keyapi_field.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; - -export class UpdateSizeKeyapiField1762159481993 implements MigrationInterface { - name = 'UpdateSizeKeyapiField1762159481993' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`apiKey\` DROP COLUMN \`keyApi\``); - await queryRunner.query(`ALTER TABLE \`apiKey\` ADD \`keyApi\` longtext NULL COMMENT 'keyApi'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`apiKey\` DROP COLUMN \`keyApi\``); - await queryRunner.query(`ALTER TABLE \`apiKey\` ADD \`keyApi\` varchar(255) NULL COMMENT 'keyApi'`); - - } - -} diff --git a/src/migration/1762159824907-update_size_place_field.ts b/src/migration/1762159824907-update_size_place_field.ts deleted file mode 100644 index 56976d9f..00000000 --- a/src/migration/1762159824907-update_size_place_field.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; - -export class UpdateSizePlaceField1762159824907 implements MigrationInterface { - name = 'UpdateSizePlaceField1762159824907' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`profileTraining\` DROP COLUMN \`place\``); - await queryRunner.query(`ALTER TABLE \`profileTraining\` ADD \`place\` longtext NULL COMMENT 'สถานที่ฝึกอบรม/ดูงาน'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`profileTraining\` DROP COLUMN \`place\``); - await queryRunner.query(`ALTER TABLE \`profileTraining\` ADD \`place\` varchar(200) NULL COMMENT 'สถานที่ฝึกอบรม/ดูงาน '`); - } - -} diff --git a/src/migration/1762165716863-add_field_isAdminVisibled_table_AuthRole.ts b/src/migration/1762165716863-add_field_isAdminVisibled_table_AuthRole.ts deleted file mode 100644 index 42348da7..00000000 --- a/src/migration/1762165716863-add_field_isAdminVisibled_table_AuthRole.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; - -export class AddFieldIsAdminVisibledTableAuthRole1762165716863 implements MigrationInterface { - name = 'AddFieldIsAdminVisibledTableAuthRole1762165716863' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`authRole\` ADD \`isAdminVisibled\` tinyint NULL COMMENT 'ข้อมูลที่ role admin สามารถเห็นได้'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`authRole\` DROP COLUMN \`isAdminVisibled\``); - } - -} diff --git a/src/migration/1762243747843-update_size_headerApi_and_tokenApi_field_ApiHistoryTable.ts b/src/migration/1762243747843-update_size_headerApi_and_tokenApi_field_ApiHistoryTable.ts deleted file mode 100644 index bed2927e..00000000 --- a/src/migration/1762243747843-update_size_headerApi_and_tokenApi_field_ApiHistoryTable.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; - -export class UpdateSizeHeaderApiAndTokenApiFieldApiHistoryTable1762243747843 implements MigrationInterface { - name = 'UpdateSizeHeaderApiAndTokenApiFieldApiHistoryTable1762243747843' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`apiHistory\` DROP COLUMN \`headerApi\``); - await queryRunner.query(`ALTER TABLE \`apiHistory\` ADD \`headerApi\` longtext NULL COMMENT 'header'`); - await queryRunner.query(`ALTER TABLE \`apiHistory\` DROP COLUMN \`tokenApi\``); - await queryRunner.query(`ALTER TABLE \`apiHistory\` ADD \`tokenApi\` longtext NULL COMMENT 'token'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE \`apiHistory\` DROP COLUMN \`tokenApi\``); - await queryRunner.query(`ALTER TABLE \`apiHistory\` ADD \`tokenApi\` varchar(255) NULL COMMENT 'token'`); - await queryRunner.query(`ALTER TABLE \`apiHistory\` DROP COLUMN \`headerApi\``); - await queryRunner.query(`ALTER TABLE \`apiHistory\` ADD \`headerApi\` varchar(255) NULL COMMENT 'header'`); - } - -} diff --git a/src/migration/1762489522691-update_viewDirectior_and_viewDirectiorActing.ts b/src/migration/1762489522691-update_viewDirectior_and_viewDirectiorActing.ts deleted file mode 100644 index f3db9b44..00000000 --- a/src/migration/1762489522691-update_viewDirectior_and_viewDirectiorActing.ts +++ /dev/null @@ -1,292 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; - -export class UpdateViewDirectiorAndViewDirectiorActing1762489522691 implements MigrationInterface { - name = 'UpdateViewDirectiorAndViewDirectiorActing1762489522691' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DELETE FROM \`hrms_organization\`.\`typeorm_metadata\` WHERE \`type\` = ? AND \`name\` = ? AND \`schema\` = ?`, ["VIEW", "view_director_acting", "hrms_organization"]); - await queryRunner.query(`DROP VIEW IF EXISTS \`view_director_acting\``); - // await queryRunner.query(`INSERT INTO \`hrms_organization\`.\`typeorm_metadata\`(\`database\`, \`schema\`, \`table\`, \`type\`, \`name\`, \`value\`) VALUES (DEFAULT, ?, DEFAULT, ?, ?, ?)`, ["hrms_organization", "VIEW", "view_director", "SELECT \n profile.id AS Id,\n profile.prefix AS prefix,\n profile.firstName AS firstName,\n profile.lastName AS lastName,\n profile.citizenId AS citizenId,\n profile.position AS position,\n CONCAT(\n CASE \n WHEN posMaster.orgChild1Id IS NULL THEN orgRoot.orgRootShortName\n WHEN posMaster.orgChild2Id IS NULL THEN orgChild1.orgChild1ShortName\n WHEN posMaster.orgChild3Id IS NULL THEN orgChild2.orgChild2ShortName\n WHEN posMaster.orgChild4Id IS NULL THEN orgChild3.orgChild3ShortName\n ELSE orgChild4.orgChild4ShortName\n END,\n posMaster.posMasterNo\n ) AS posNo,\n posMaster.isDirector AS isDirector,\n posLevel.posLevelName AS posLevel,\n posType.posTypeName AS posType,\n posExecutive.posExecutiveName AS posExecutiveName,\n orgRoot.isDeputy AS isDeputy,\n orgChild1.isOfficer AS isOfficer,\n posMaster.orgRevisionId AS orgRevisionId,\n posMaster.orgRootId AS orgRootId,\n posMaster.orgChild1Id AS orgChild1Id,\n posMaster.orgChild2Id AS orgChild2Id,\n posMaster.orgChild3Id AS orgChild3Id,\n posMaster.orgChild4Id AS orgChild4Id,\n CONCAT(posMaster.id, profile.id) AS `key`,\n (\n SELECT hrms_organization.acting.actFullNameKeycloakId\n FROM hrms_organization.view_director_acting acting\n WHERE ((hrms_organization.acting.Id = hrms_organization.posMaster.current_holderId)\n AND (hrms_organization.acting.orgRootId = hrms_organization.posMaster.orgRootId)\n AND ((hrms_organization.acting.orgChild1Id = hrms_organization.posMaster.orgChild1Id)\n OR (hrms_organization.acting.orgChild1Id IS NULL))\n AND ((hrms_organization.acting.orgChild2Id = hrms_organization.posMaster.orgChild2Id)\n OR (hrms_organization.acting.orgChild2Id IS NULL))\n AND ((hrms_organization.acting.orgChild3Id = hrms_organization.posMaster.orgChild3Id)\n OR (hrms_organization.acting.orgChild3Id IS NULL))\n AND ((hrms_organization.acting.orgChild4Id = hrms_organization.posMaster.orgChild4Id)\n OR (hrms_organization.acting.orgChild4Id IS NULL)))\n LIMIT 1\n ) AS actFullNameKeycloakId,\n (\n SELECT actFullNameId \n FROM view_director_acting AS acting\n WHERE acting.Id = posMaster.current_holderId \n AND acting.orgRootId = posMaster.orgRootId \n AND (acting.orgChild1Id = posMaster.orgChild1Id OR acting.orgChild1Id IS NULL)\n AND (acting.orgChild2Id = posMaster.orgChild2Id OR acting.orgChild2Id IS NULL)\n AND (acting.orgChild3Id = posMaster.orgChild3Id OR acting.orgChild3Id IS NULL)\n AND (acting.orgChild4Id = posMaster.orgChild4Id OR acting.orgChild4Id IS NULL)\n LIMIT 1\n ) AS actFullNameId,\n (\n SELECT actFullName \n FROM view_director_acting AS acting\n WHERE acting.Id = posMaster.current_holderId \n AND acting.orgRootId = posMaster.orgRootId \n AND (acting.orgChild1Id = posMaster.orgChild1Id OR acting.orgChild1Id IS NULL)\n AND (acting.orgChild2Id = posMaster.orgChild2Id OR acting.orgChild2Id IS NULL)\n AND (acting.orgChild3Id = posMaster.orgChild3Id OR acting.orgChild3Id IS NULL)\n AND (acting.orgChild4Id = posMaster.orgChild4Id OR acting.orgChild4Id IS NULL)\n LIMIT 1\n ) AS actFullName\n FROM\n posMaster\n JOIN profile ON posMaster.current_holderId = profile.id\n LEFT JOIN orgRoot ON posMaster.orgRootId = orgRoot.id\n LEFT JOIN orgChild1 ON posMaster.orgChild1Id = orgChild1.id\n LEFT JOIN orgChild2 ON posMaster.orgChild2Id = orgChild2.id\n LEFT JOIN orgChild3 ON posMaster.orgChild3Id = orgChild3.id\n LEFT JOIN orgChild4 ON posMaster.orgChild4Id = orgChild4.id\n JOIN posLevel ON profile.posLevelId = posLevel.id\n JOIN posType ON profile.posTypeId = posType.id\n LEFT JOIN position ON posMaster.id = position.posMasterId\n LEFT JOIN posExecutive ON position.posExecutiveId = posExecutive.id\n INNER JOIN orgRevision ON posMaster.orgRevisionId = orgRevision.id\n WHERE\n (position.positionIsSelected = TRUE)\n AND (orgRevision.orgRevisionIsCurrent = TRUE\n AND orgRevision.orgRevisionIsDraft = FALSE)"]); - await queryRunner.query(`CREATE VIEW \`view_director_acting\` AS SELECT - \`profileChild\`.\`id\` AS \`Id\`, - \`profileChild\`.\`prefix\` AS \`prefix\`, - \`profileChild\`.\`firstName\` AS \`firstName\`, - \`profileChild\`.\`lastName\` AS \`lastName\`, - \`profileChild\`.\`citizenId\` AS \`citizenId\`, - \`profileChild\`.\`position\` AS \`position\`, - \`profile\`.\`isProbation\` AS \`isProbation\`, - CONCAT((CASE - WHEN (\`posMaster\`.\`orgChild1Id\` IS NULL) THEN \`orgRootChild\`.\`orgRootShortName\` - WHEN (\`posMaster\`.\`orgChild2Id\` IS NULL) THEN \`orgChild1Child\`.\`orgChild1ShortName\` - WHEN (\`posMaster\`.\`orgChild3Id\` IS NULL) THEN \`orgChild2Child\`.\`orgChild2ShortName\` - WHEN (\`posMaster\`.\`orgChild4Id\` IS NULL) THEN \`orgChild3Child\`.\`orgChild3ShortName\` - ELSE \`orgChild4Child\`.\`orgChild4ShortName\` - END), - \`posMaster\`.\`posMasterNo\`) AS \`posNo\`, - \`posMasterChild\`.\`isDirector\` AS \`isDirectorChild\`, - \`posMaster\`.\`isDirector\` AS \`isDirector\`, - \`posLevel\`.\`posLevelName\` AS \`posLevel\`, - \`posType\`.\`posTypeName\` AS \`posType\`, - \`posExecutive\`.\`posExecutiveName\` AS \`posExecutiveName\`, - \`orgRoot\`.\`isDeputy\` AS \`isDeputy\`, - \`orgChild1\`.\`isOfficer\` AS \`isOfficer\`, - \`posMaster\`.\`orgRevisionId\` AS \`orgRevisionId\`, - \`posMaster\`.\`orgRootId\` AS \`orgRootId\`, - \`posMaster\`.\`orgChild1Id\` AS \`orgChild1Id\`, - \`posMaster\`.\`orgChild2Id\` AS \`orgChild2Id\`, - \`posMaster\`.\`orgChild3Id\` AS \`orgChild3Id\`, - \`posMaster\`.\`orgChild4Id\` AS \`orgChild4Id\`, - CONCAT(\`hrms_organization\`.\`profile\`.\`keycloak\`) AS \`actFullNameKeycloakId\`, - CONCAT(\`posMaster\`.\`id\`, \`profileChild\`.\`id\`) AS \`key\`, - \`profile\`.\`id\` AS \`actFullNameId\`, - CONCAT(\`profile\`.\`prefix\`, - \`profile\`.\`firstName\`, - ' ', - \`profile\`.\`lastName\`) AS \`actFullName\` - FROM - (((((((((((((((\`posMasterAct\` - JOIN \`posMaster\` \`posMasterChild\` ON ((\`posMasterAct\`.\`posMasterChildId\` = \`posMasterChild\`.\`id\`))) - JOIN \`profile\` \`profileChild\` ON ((\`posMasterChild\`.\`current_holderId\` = \`profileChild\`.\`id\`))) - LEFT JOIN \`orgRoot\` \`orgRootChild\` ON ((\`posMasterChild\`.\`orgRootId\` = \`orgRootChild\`.\`id\`))) - LEFT JOIN \`orgChild1\` \`orgChild1Child\` ON ((\`posMasterChild\`.\`orgChild1Id\` = \`orgChild1Child\`.\`id\`))) - LEFT JOIN \`orgChild2\` \`orgChild2Child\` ON ((\`posMasterChild\`.\`orgChild2Id\` = \`orgChild2Child\`.\`id\`))) - LEFT JOIN \`orgChild3\` \`orgChild3Child\` ON ((\`posMasterChild\`.\`orgChild3Id\` = \`orgChild3Child\`.\`id\`))) - LEFT JOIN \`orgChild4\` \`orgChild4Child\` ON ((\`posMasterChild\`.\`orgChild4Id\` = \`orgChild4Child\`.\`id\`))) - JOIN \`posLevel\` ON ((\`profileChild\`.\`posLevelId\` = \`posLevel\`.\`id\`))) - JOIN \`posType\` ON ((\`profileChild\`.\`posTypeId\` = \`posType\`.\`id\`))) - JOIN \`posMaster\` ON ((\`posMasterAct\`.\`posMasterId\` = \`posMaster\`.\`id\`))) - LEFT JOIN \`orgRoot\` ON ((\`posMaster\`.\`orgRootId\` = \`orgRoot\`.\`id\`))) - LEFT JOIN \`orgChild1\` ON ((\`posMaster\`.\`orgChild1Id\` = \`orgChild1\`.\`id\`))) - JOIN \`profile\` ON ((\`posMaster\`.\`current_holderId\` = \`profile\`.\`id\`))) - LEFT JOIN \`position\` ON ((\`posMasterChild\`.\`id\` = \`position\`.\`posMasterId\`))) - LEFT JOIN \`posExecutive\` ON ((\`position\`.\`posExecutiveId\` = \`posExecutive\`.\`id\`))) - WHERE - (\`position\`.\`positionIsSelected\` = TRUE)`); - - await queryRunner.query(`DELETE FROM \`hrms_organization\`.\`typeorm_metadata\` WHERE \`type\` = ? AND \`name\` = ? AND \`schema\` = ?`, ["VIEW", "view_director", "hrms_organization"]); - await queryRunner.query(`DROP VIEW IF EXISTS \`view_director\``); - // await queryRunner.query(`INSERT INTO \`hrms_organization\`.\`typeorm_metadata\`(\`database\`, \`schema\`, \`table\`, \`type\`, \`name\`, \`value\`) VALUES (DEFAULT, ?, DEFAULT, ?, ?, ?)`, ["hrms_organization", "VIEW", "view_employee_pos_master", "SELECT \n employeePosMaster.id,\n employeePosMaster.posMasterNoPrefix,\n employeePosMaster.posMasterNo,\n employeePosMaster.posMasterNoSuffix,\n employeePosMaster.orgRevisionId,\n employeePosMaster.orgRootId,\n employeePosMaster.orgChild1Id,\n employeePosMaster.orgChild2Id,\n employeePosMaster.orgChild3Id,\n employeePosMaster.orgChild4Id,\n employeePosMaster.current_holderId,\n profileEmployee.id as profileId,\n profileEmployee.prefix,\n profileEmployee.firstName,\n profileEmployee.lastName,\n profileEmployee.citizenId,\n profileEmployee.position,\n profileEmployee.amount,\n profileEmployee.dateRetire,\n profileEmployee.birthDate,\n profileEmployee.salaryLevel,\n profileEmployee.group,\n orgRoot.id as rootId,\n orgRoot.orgRootShortName,\n orgRoot.orgRootOrder,\n orgRoot.orgRootName,\n orgChild1.id as child1Id,\n orgChild1.orgChild1ShortName,\n orgChild1.orgChild1Order,\n orgChild1.orgChild1Name,\n orgChild2.id as child2Id,\n orgChild2.orgChild2ShortName,\n orgChild2.orgChild2Order,\n orgChild2.orgChild2Name,\n orgChild3.id as child3Id,\n orgChild3.orgChild3ShortName,\n orgChild3.orgChild3Order,\n orgChild3.orgChild3Name,\n orgChild4.id as child4Id,\n orgChild4.orgChild4ShortName,\n orgChild4.orgChild4Order,\n orgChild4.orgChild4Name,\n position.id as positionId,\n position.positionIsSelected,\n position.posExecutiveId as positionPosExecutiveId,\n position.isSpecial,\n posExecutive.id as posExecutiveId,\n posExecutive.posExecutiveName,\n profileDiscipline.id as profileDisciplineId,\n profileDiscipline.date as disCriplineDate,\n profileLeave.id as profileLeaveId,\n profileAssessment.id as profileAssessmentId,\n profileAssessment.pointSum,\n employeePosLevel.id as posLevelId,\n employeePosLevel.posLevelName,\n\temployeePosType.id as posTypeId,\n employeePosType.posTypeName,\n employeePosType.posTypeShortName\n FROM \n employeePosMaster\n LEFT JOIN \n profileEmployee ON employeePosMaster.current_holderId = profileEmployee.id \n LEFT JOIN \n orgRoot ON employeePosMaster.orgRootId = orgRoot.id\n LEFT JOIN \n orgChild1 ON employeePosMaster.orgChild1Id = orgChild1.id\n LEFT JOIN \n orgChild2 ON employeePosMaster.orgChild2Id = orgChild2.id\n LEFT JOIN \n orgChild3 ON employeePosMaster.orgChild3Id = orgChild3.id\n LEFT JOIN \n orgChild4 ON employeePosMaster.orgChild4Id = orgChild4.id\n LEFT JOIN \n position ON employeePosMaster.id = position.posMasterId\n LEFT JOIN \n posExecutive ON position.posExecutiveId = posExecutive.id\n LEFT JOIN (\n SELECT *\n FROM profileDisciplineEmployee pd1\n WHERE pd1.date = (\n SELECT MAX(pd2.date)\n FROM profileDisciplineEmployee pd2\n WHERE pd2.profileId = pd1.profileId\n )\n ) AS profileDiscipline ON profileDiscipline.profileId = profileEmployee.id\n LEFT JOIN (\n SELECT pl1.*\n FROM profileLeave pl1\n INNER JOIN (\n SELECT profileId, MAX(createdAt) AS maxDate\n FROM profileLeave\n GROUP BY profileId\n ) pl2 ON pl1.profileId = pl2.profileId\n AND pl1.createdAt = pl2.maxDate\n ) AS profileLeave ON profileLeave.profileId = employeePosMaster.current_holderId\n LEFT JOIN (\n SELECT pa1.*\n FROM profileAssessment pa1\n INNER JOIN (\n SELECT profileId, MAX(createdAt) AS maxDate\n FROM profileAssessment\n GROUP BY profileId\n ) pa2 ON pa1.profileId = pa2.profileId\n AND pa1.createdAt = pa2.maxDate\n ) AS profileAssessment \n ON profileAssessment.profileId = profileEmployee.id\n LEFT JOIN \n employeePosLevel ON profileEmployee.posLevelId = employeePosLevel.id\n LEFT JOIN \n employeePosType ON profileEmployee.posTypeId = employeePosType.id\n WHERE \t\n employeePosMaster.current_holderId IS NOT NULL\n ORDER BY \n profileEmployee.citizenId ASC"]); - await queryRunner.query(`CREATE VIEW \`view_director\` AS SELECT - profile.id AS Id, - profile.prefix AS prefix, - profile.firstName AS firstName, - profile.lastName AS lastName, - profile.citizenId AS citizenId, - profile.position AS position, - profile.keycloak AS keycloakId, - profile.isProbation AS isProbation, - CONCAT( - CASE - WHEN posMaster.orgChild1Id IS NULL THEN orgRoot.orgRootShortName - WHEN posMaster.orgChild2Id IS NULL THEN orgChild1.orgChild1ShortName - WHEN posMaster.orgChild3Id IS NULL THEN orgChild2.orgChild2ShortName - WHEN posMaster.orgChild4Id IS NULL THEN orgChild3.orgChild3ShortName - ELSE orgChild4.orgChild4ShortName - END, - posMaster.posMasterNo - ) AS posNo, - posMaster.isDirector AS isDirector, - posLevel.posLevelName AS posLevel, - posType.posTypeName AS posType, - posExecutive.posExecutiveName AS posExecutiveName, - orgRoot.isDeputy AS isDeputy, - orgChild1.isOfficer AS isOfficer, - posMaster.orgRevisionId AS orgRevisionId, - posMaster.orgRootId AS orgRootId, - posMaster.orgChild1Id AS orgChild1Id, - posMaster.orgChild2Id AS orgChild2Id, - posMaster.orgChild3Id AS orgChild3Id, - posMaster.orgChild4Id AS orgChild4Id, - CONCAT(posMaster.id, profile.id) AS \`key\`, - ( - SELECT hrms_organization.acting.actFullNameKeycloakId - FROM hrms_organization.view_director_acting acting - WHERE ((hrms_organization.acting.Id = hrms_organization.posMaster.current_holderId) - AND (hrms_organization.acting.orgRootId = hrms_organization.posMaster.orgRootId) - AND ((hrms_organization.acting.orgChild1Id = hrms_organization.posMaster.orgChild1Id) - OR (hrms_organization.acting.orgChild1Id IS NULL)) - AND ((hrms_organization.acting.orgChild2Id = hrms_organization.posMaster.orgChild2Id) - OR (hrms_organization.acting.orgChild2Id IS NULL)) - AND ((hrms_organization.acting.orgChild3Id = hrms_organization.posMaster.orgChild3Id) - OR (hrms_organization.acting.orgChild3Id IS NULL)) - AND ((hrms_organization.acting.orgChild4Id = hrms_organization.posMaster.orgChild4Id) - OR (hrms_organization.acting.orgChild4Id IS NULL))) - LIMIT 1 - ) AS actFullNameKeycloakId, - ( - SELECT actFullNameId - FROM view_director_acting AS acting - WHERE acting.Id = posMaster.current_holderId - AND acting.orgRootId = posMaster.orgRootId - AND (acting.orgChild1Id = posMaster.orgChild1Id OR acting.orgChild1Id IS NULL) - AND (acting.orgChild2Id = posMaster.orgChild2Id OR acting.orgChild2Id IS NULL) - AND (acting.orgChild3Id = posMaster.orgChild3Id OR acting.orgChild3Id IS NULL) - AND (acting.orgChild4Id = posMaster.orgChild4Id OR acting.orgChild4Id IS NULL) - LIMIT 1 - ) AS actFullNameId, - ( - SELECT actFullName - FROM view_director_acting AS acting - WHERE acting.Id = posMaster.current_holderId - AND acting.orgRootId = posMaster.orgRootId - AND (acting.orgChild1Id = posMaster.orgChild1Id OR acting.orgChild1Id IS NULL) - AND (acting.orgChild2Id = posMaster.orgChild2Id OR acting.orgChild2Id IS NULL) - AND (acting.orgChild3Id = posMaster.orgChild3Id OR acting.orgChild3Id IS NULL) - AND (acting.orgChild4Id = posMaster.orgChild4Id OR acting.orgChild4Id IS NULL) - LIMIT 1 - ) AS actFullName - FROM - posMaster - JOIN profile ON posMaster.current_holderId = profile.id - LEFT JOIN orgRoot ON posMaster.orgRootId = orgRoot.id - LEFT JOIN orgChild1 ON posMaster.orgChild1Id = orgChild1.id - LEFT JOIN orgChild2 ON posMaster.orgChild2Id = orgChild2.id - LEFT JOIN orgChild3 ON posMaster.orgChild3Id = orgChild3.id - LEFT JOIN orgChild4 ON posMaster.orgChild4Id = orgChild4.id - JOIN posLevel ON profile.posLevelId = posLevel.id - JOIN posType ON profile.posTypeId = posType.id - LEFT JOIN position ON posMaster.id = position.posMasterId - LEFT JOIN posExecutive ON position.posExecutiveId = posExecutive.id - INNER JOIN orgRevision ON posMaster.orgRevisionId = orgRevision.id - WHERE - (position.positionIsSelected = TRUE) - AND (orgRevision.orgRevisionIsCurrent = TRUE - AND orgRevision.orgRevisionIsDraft = FALSE)`); - - await queryRunner.query(`INSERT INTO \`hrms_organization\`.\`typeorm_metadata\`(\`database\`, \`schema\`, \`table\`, \`type\`, \`name\`, \`value\`) VALUES (DEFAULT, ?, DEFAULT, ?, ?, ?)`, ["hrms_organization", "VIEW", "view_current_tenure_employee", "WITH resultData AS (\n SELECT\n commandDateAffect,\n positionName,\n positionCee,\n TIMESTAMPDIFF(\n DAY,\n LAG(MIN(commandDateAffect)) OVER (ORDER BY commandDateAffect), MIN(commandDateAffect)) AS days_diff,\n TIMESTAMPDIFF(\n DAY,\n LAG(MIN(commandDateAffect)) OVER (ORDER BY commandDateAffect), MIN(commandDateAffect)) / 365.2524 AS 'Years',\n TIMESTAMPDIFF(\n DAY,\n LAG(MIN(commandDateAffect)) OVER (ORDER BY commandDateAffect), MIN(commandDateAffect)) / 30.4375 % 12 AS 'Months',\n TIMESTAMPDIFF(\n DAY,\n LAG(MIN(commandDateAffect)) OVER (ORDER BY commandDateAffect), MIN(commandDateAffect)) % 30.4375 AS 'Days',\n posNo,\n positionExecutive,\n positionType,\n positionLevel,\n OrgRoot,\n orgChild1,\n orgChild2,\n orgChild3,\n orgChild4,\n commandCode,\n commandName,\n commandNo,\n commandYear,\n remark,\n profileEmployeeId,\n ROW_NUMBER() OVER (PARTITION BY profileEmployeeId ORDER BY commandDateAffect ASC) AS orderNumber\n FROM (\n SELECT\n commandDateAffect,\n commandDateSign,\n positionName,\n positionCee,\n posNo,\n positionExecutive,\n positionType,\n positionLevel,\n OrgRoot,\n orgChild1,\n orgChild2,\n orgChild3,\n orgChild4,\n commandCode,\n commandName,\n commandNo,\n commandYear,\n remark,\n profileEmployeeId,\n LAG(commandDateSign) OVER (ORDER BY commandDateAffect ASC, commandDateSign ASC) AS prevCommandDateSign,\n ROW_NUMBER() OVER (ORDER BY commandDateAffect ASC, commandDateSign ASC) -\n ROW_NUMBER() OVER (PARTITION BY positionName ORDER BY commandDateAffect ASC, commandDateSign ASC) as groupedId\n FROM\n profileSalary\n WHERE\n commandCode IN (1, 2, 3, 4, 8, 10, 11, 12, 15, 16)\n ORDER BY\n commandDateAffect ASC, commandDateSign ASC\n ) AS groupedPosition\n WHERE\n prevCommandDateSign IS NULL OR commandDateSign >= prevCommandDateSign\n GROUP BY\n profileEmployeeId, groupedId, positionName\n )\n SELECT\n commandDateAffect,\n positionName,\n positionCee,\n days_diff,\n Years,\n Months,\n Days,\n posNo,\n positionExecutive,\n positionType,\n positionLevel,\n OrgRoot,\n orgChild1,\n orgChild2,\n orgChild3,\n orgChild4,\n commandCode,\n commandName,\n commandNo,\n commandYear,\n remark,\n profileEmployeeId,\n orderNumber\n FROM resultData\n\n UNION ALL\n\n SELECT\n CURDATE() AS commandDateAffect,\n NULL AS positionName,\n NULL AS positionCee,\n TIMESTAMPDIFF(DAY, MAX(commandDateAffect), CURDATE()) AS days_diff,\n TIMESTAMPDIFF(DAY, MAX(commandDateAffect), CURDATE()) / 365.2524 AS 'Years',\n TIMESTAMPDIFF(DAY, MAX(commandDateAffect), CURDATE()) / 30.4375 % 12 AS 'Months',\n TIMESTAMPDIFF(DAY, MAX(commandDateAffect), CURDATE()) % 30.4375 AS 'Days',\n NULL AS posNo,\n NULL AS positionExecutive,\n NULL AS positionType,\n NULL AS positionLevel,\n NULL AS OrgRoot,\n NULL AS orgChild1,\n NULL AS orgChild2,\n NULL AS orgChild3,\n NULL AS orgChild4,\n NULL AS commandCode,\n NULL AS commandName,\n NULL AS commandNo,\n NULL AS commandYear,\n NULL AS remark,\n profileEmployeeId,\n NULL AS orderNumber\n FROM resultData"]); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DELETE FROM \`hrms_organization\`.\`typeorm_metadata\` WHERE \`type\` = ? AND \`name\` = ? AND \`schema\` = ?`, ["VIEW", "view_director_acting", "hrms_organization"]); - await queryRunner.query(`DROP VIEW IF EXISTS \`view_director_acting\``); - await queryRunner.query(`CREATE VIEW \`view_director_acting\` AS SELECT - \`profileChild\`.\`id\` AS \`Id\`, - \`profileChild\`.\`prefix\` AS \`prefix\`, - \`profileChild\`.\`firstName\` AS \`firstName\`, - \`profileChild\`.\`lastName\` AS \`lastName\`, - \`profileChild\`.\`citizenId\` AS \`citizenId\`, - \`profileChild\`.\`position\` AS \`position\`, - CONCAT((CASE - WHEN (\`posMaster\`.\`orgChild1Id\` IS NULL) THEN \`orgRootChild\`.\`orgRootShortName\` - WHEN (\`posMaster\`.\`orgChild2Id\` IS NULL) THEN \`orgChild1Child\`.\`orgChild1ShortName\` - WHEN (\`posMaster\`.\`orgChild3Id\` IS NULL) THEN \`orgChild2Child\`.\`orgChild2ShortName\` - WHEN (\`posMaster\`.\`orgChild4Id\` IS NULL) THEN \`orgChild3Child\`.\`orgChild3ShortName\` - ELSE \`orgChild4Child\`.\`orgChild4ShortName\` - END), - \`posMaster\`.\`posMasterNo\`) AS \`posNo\`, - \`posMasterChild\`.\`isDirector\` AS \`isDirectorChild\`, - \`posMaster\`.\`isDirector\` AS \`isDirector\`, - \`posLevel\`.\`posLevelName\` AS \`posLevel\`, - \`posType\`.\`posTypeName\` AS \`posType\`, - \`posExecutive\`.\`posExecutiveName\` AS \`posExecutiveName\`, - \`orgRoot\`.\`isDeputy\` AS \`isDeputy\`, - \`orgChild1\`.\`isOfficer\` AS \`isOfficer\`, - \`posMaster\`.\`orgRevisionId\` AS \`orgRevisionId\`, - \`posMaster\`.\`orgRootId\` AS \`orgRootId\`, - \`posMaster\`.\`orgChild1Id\` AS \`orgChild1Id\`, - \`posMaster\`.\`orgChild2Id\` AS \`orgChild2Id\`, - \`posMaster\`.\`orgChild3Id\` AS \`orgChild3Id\`, - \`posMaster\`.\`orgChild4Id\` AS \`orgChild4Id\`, - CONCAT(\`posMaster\`.\`id\`, \`profileChild\`.\`id\`) AS \`key\`, - \`profile\`.\`id\` AS \`actFullNameId\`, - CONCAT(\`profile\`.\`prefix\`, - \`profile\`.\`firstName\`, - ' ', - \`profile\`.\`lastName\`) AS \`actFullName\` - FROM - (((((((((((((((\`posMasterAct\` - JOIN \`posMaster\` \`posMasterChild\` ON ((\`posMasterAct\`.\`posMasterChildId\` = \`posMasterChild\`.\`id\`))) - JOIN \`profile\` \`profileChild\` ON ((\`posMasterChild\`.\`current_holderId\` = \`profileChild\`.\`id\`))) - LEFT JOIN \`orgRoot\` \`orgRootChild\` ON ((\`posMasterChild\`.\`orgRootId\` = \`orgRootChild\`.\`id\`))) - LEFT JOIN \`orgChild1\` \`orgChild1Child\` ON ((\`posMasterChild\`.\`orgChild1Id\` = \`orgChild1Child\`.\`id\`))) - LEFT JOIN \`orgChild2\` \`orgChild2Child\` ON ((\`posMasterChild\`.\`orgChild2Id\` = \`orgChild2Child\`.\`id\`))) - LEFT JOIN \`orgChild3\` \`orgChild3Child\` ON ((\`posMasterChild\`.\`orgChild3Id\` = \`orgChild3Child\`.\`id\`))) - LEFT JOIN \`orgChild4\` \`orgChild4Child\` ON ((\`posMasterChild\`.\`orgChild4Id\` = \`orgChild4Child\`.\`id\`))) - JOIN \`posLevel\` ON ((\`profileChild\`.\`posLevelId\` = \`posLevel\`.\`id\`))) - JOIN \`posType\` ON ((\`profileChild\`.\`posTypeId\` = \`posType\`.\`id\`))) - JOIN \`posMaster\` ON ((\`posMasterAct\`.\`posMasterId\` = \`posMaster\`.\`id\`))) - LEFT JOIN \`orgRoot\` ON ((\`posMaster\`.\`orgRootId\` = \`orgRoot\`.\`id\`))) - LEFT JOIN \`orgChild1\` ON ((\`posMaster\`.\`orgChild1Id\` = \`orgChild1\`.\`id\`))) - JOIN \`profile\` ON ((\`posMaster\`.\`current_holderId\` = \`profile\`.\`id\`))) - LEFT JOIN \`position\` ON ((\`posMasterChild\`.\`id\` = \`position\`.\`posMasterId\`))) - LEFT JOIN \`posExecutive\` ON ((\`position\`.\`posExecutiveId\` = \`posExecutive\`.\`id\`))) - WHERE - (\`position\`.\`positionIsSelected\` = TRUE)`); - - // await queryRunner.query(`INSERT INTO \`hrms_organization\`.\`typeorm_metadata\`(\`database\`, \`schema\`, \`table\`, \`type\`, \`name\`, \`value\`) VALUES (DEFAULT, ?, DEFAULT, ?, ?, ?)`, ["hrms_organization", "VIEW", "view_director_acting", "SELECT \n `profileChild`.`id` AS `Id`,\n `profileChild`.`prefix` AS `prefix`,\n `profileChild`.`firstName` AS `firstName`,\n `profileChild`.`lastName` AS `lastName`,\n `profileChild`.`citizenId` AS `citizenId`,\n `profileChild`.`position` AS `position`,\n CONCAT((CASE\n WHEN (`posMaster`.`orgChild1Id` IS NULL) THEN `orgRootChild`.`orgRootShortName`\n WHEN (`posMaster`.`orgChild2Id` IS NULL) THEN `orgChild1Child`.`orgChild1ShortName`\n WHEN (`posMaster`.`orgChild3Id` IS NULL) THEN `orgChild2Child`.`orgChild2ShortName`\n WHEN (`posMaster`.`orgChild4Id` IS NULL) THEN `orgChild3Child`.`orgChild3ShortName`\n ELSE `orgChild4Child`.`orgChild4ShortName`\n END),\n `posMaster`.`posMasterNo`) AS `posNo`,\n `posMasterChild`.`isDirector` AS `isDirectorChild`,\n `posMaster`.`isDirector` AS `isDirector`,\n `posLevel`.`posLevelName` AS `posLevel`,\n `posType`.`posTypeName` AS `posType`,\n `posExecutive`.`posExecutiveName` AS `posExecutiveName`,\n `orgRoot`.`isDeputy` AS `isDeputy`,\n `orgChild1`.`isOfficer` AS `isOfficer`,\n `posMaster`.`orgRevisionId` AS `orgRevisionId`,\n `posMaster`.`orgRootId` AS `orgRootId`,\n `posMaster`.`orgChild1Id` AS `orgChild1Id`,\n `posMaster`.`orgChild2Id` AS `orgChild2Id`,\n `posMaster`.`orgChild3Id` AS `orgChild3Id`,\n `posMaster`.`orgChild4Id` AS `orgChild4Id`,\n CONCAT(`posMaster`.`id`, `profileChild`.`id`) AS `key`,\n `profile`.`id` AS `actFullNameId`,\n CONCAT(`profile`.`prefix`,\n `profile`.`firstName`,\n ' ',\n `profile`.`lastName`) AS `actFullName`\n FROM\n (((((((((((((((`posMasterAct`\n JOIN `posMaster` `posMasterChild` ON ((`posMasterAct`.`posMasterChildId` = `posMasterChild`.`id`)))\n JOIN `profile` `profileChild` ON ((`posMasterChild`.`current_holderId` = `profileChild`.`id`)))\n LEFT JOIN `orgRoot` `orgRootChild` ON ((`posMasterChild`.`orgRootId` = `orgRootChild`.`id`)))\n LEFT JOIN `orgChild1` `orgChild1Child` ON ((`posMasterChild`.`orgChild1Id` = `orgChild1Child`.`id`)))\n LEFT JOIN `orgChild2` `orgChild2Child` ON ((`posMasterChild`.`orgChild2Id` = `orgChild2Child`.`id`)))\n LEFT JOIN `orgChild3` `orgChild3Child` ON ((`posMasterChild`.`orgChild3Id` = `orgChild3Child`.`id`)))\n LEFT JOIN `orgChild4` `orgChild4Child` ON ((`posMasterChild`.`orgChild4Id` = `orgChild4Child`.`id`)))\n JOIN `posLevel` ON ((`profileChild`.`posLevelId` = `posLevel`.`id`)))\n JOIN `posType` ON ((`profileChild`.`posTypeId` = `posType`.`id`)))\n JOIN `posMaster` ON ((`posMasterAct`.`posMasterId` = `posMaster`.`id`)))\n LEFT JOIN `orgRoot` ON ((`posMaster`.`orgRootId` = `orgRoot`.`id`)))\n LEFT JOIN `orgChild1` ON ((`posMaster`.`orgChild1Id` = `orgChild1`.`id`)))\n JOIN `profile` ON ((`posMaster`.`current_holderId` = `profile`.`id`)))\n LEFT JOIN `position` ON ((`posMasterChild`.`id` = `position`.`posMasterId`)))\n LEFT JOIN `posExecutive` ON ((`position`.`posExecutiveId` = `posExecutive`.`id`)))\n WHERE\n (`position`.`positionIsSelected` = TRUE)"]); - await queryRunner.query(`DELETE FROM \`hrms_organization\`.\`typeorm_metadata\` WHERE \`type\` = ? AND \`name\` = ? AND \`schema\` = ?`, ["VIEW", "view_director", "hrms_organization"]); - await queryRunner.query(`DROP VIEW IF EXISTS \`view_director\``); - await queryRunner.query(`CREATE VIEW \`view_director\` AS SELECT - profile.id AS Id, - profile.prefix AS prefix, - profile.firstName AS firstName, - profile.lastName AS lastName, - profile.citizenId AS citizenId, - profile.position AS position, - CONCAT( - CASE - WHEN posMaster.orgChild1Id IS NULL THEN orgRoot.orgRootShortName - WHEN posMaster.orgChild2Id IS NULL THEN orgChild1.orgChild1ShortName - WHEN posMaster.orgChild3Id IS NULL THEN orgChild2.orgChild2ShortName - WHEN posMaster.orgChild4Id IS NULL THEN orgChild3.orgChild3ShortName - ELSE orgChild4.orgChild4ShortName - END, - posMaster.posMasterNo - ) AS posNo, - posMaster.isDirector AS isDirector, - posLevel.posLevelName AS posLevel, - posType.posTypeName AS posType, - posExecutive.posExecutiveName AS posExecutiveName, - orgRoot.isDeputy AS isDeputy, - orgChild1.isOfficer AS isOfficer, - posMaster.orgRevisionId AS orgRevisionId, - posMaster.orgRootId AS orgRootId, - posMaster.orgChild1Id AS orgChild1Id, - posMaster.orgChild2Id AS orgChild2Id, - posMaster.orgChild3Id AS orgChild3Id, - posMaster.orgChild4Id AS orgChild4Id, - CONCAT(posMaster.id, profile.id) AS \`key\`, - ( - SELECT actFullNameId - FROM view_director_acting AS acting - WHERE acting.Id = posMaster.current_holderId - AND acting.orgRootId = posMaster.orgRootId - AND (acting.orgChild1Id = posMaster.orgChild1Id OR acting.orgChild1Id IS NULL) - AND (acting.orgChild2Id = posMaster.orgChild2Id OR acting.orgChild2Id IS NULL) - AND (acting.orgChild3Id = posMaster.orgChild3Id OR acting.orgChild3Id IS NULL) - AND (acting.orgChild4Id = posMaster.orgChild4Id OR acting.orgChild4Id IS NULL) - LIMIT 1 - ) AS actFullNameId, - ( - SELECT actFullName - FROM view_director_acting AS acting - WHERE acting.Id = posMaster.current_holderId - AND acting.orgRootId = posMaster.orgRootId - AND (acting.orgChild1Id = posMaster.orgChild1Id OR acting.orgChild1Id IS NULL) - AND (acting.orgChild2Id = posMaster.orgChild2Id OR acting.orgChild2Id IS NULL) - AND (acting.orgChild3Id = posMaster.orgChild3Id OR acting.orgChild3Id IS NULL) - AND (acting.orgChild4Id = posMaster.orgChild4Id OR acting.orgChild4Id IS NULL) - LIMIT 1 - ) AS actFullName - FROM - posMaster - JOIN profile ON posMaster.current_holderId = profile.id - LEFT JOIN orgRoot ON posMaster.orgRootId = orgRoot.id - LEFT JOIN orgChild1 ON posMaster.orgChild1Id = orgChild1.id - LEFT JOIN orgChild2 ON posMaster.orgChild2Id = orgChild2.id - LEFT JOIN orgChild3 ON posMaster.orgChild3Id = orgChild3.id - LEFT JOIN orgChild4 ON posMaster.orgChild4Id = orgChild4.id - JOIN posLevel ON profile.posLevelId = posLevel.id - JOIN posType ON profile.posTypeId = posType.id - LEFT JOIN position ON posMaster.id = position.posMasterId - LEFT JOIN posExecutive ON position.posExecutiveId = posExecutive.id - INNER JOIN orgRevision ON posMaster.orgRevisionId = orgRevision.id - WHERE - (position.positionIsSelected = TRUE) - AND (orgRevision.orgRevisionIsCurrent = TRUE - AND orgRevision.orgRevisionIsDraft = FALSE)`); - - // await queryRunner.query(`INSERT INTO \`hrms_organization\`.\`typeorm_metadata\`(\`database\`, \`schema\`, \`table\`, \`type\`, \`name\`, \`value\`) VALUES (DEFAULT, ?, DEFAULT, ?, ?, ?)`, ["hrms_organization", "VIEW", "view_director", "SELECT \n profile.id AS Id,\n profile.prefix AS prefix,\n profile.firstName AS firstName,\n profile.lastName AS lastName,\n profile.citizenId AS citizenId,\n profile.position AS position,\n CONCAT(\n CASE \n WHEN posMaster.orgChild1Id IS NULL THEN orgRoot.orgRootShortName\n WHEN posMaster.orgChild2Id IS NULL THEN orgChild1.orgChild1ShortName\n WHEN posMaster.orgChild3Id IS NULL THEN orgChild2.orgChild2ShortName\n WHEN posMaster.orgChild4Id IS NULL THEN orgChild3.orgChild3ShortName\n ELSE orgChild4.orgChild4ShortName\n END,\n posMaster.posMasterNo\n ) AS posNo,\n posMaster.isDirector AS isDirector,\n posLevel.posLevelName AS posLevel,\n posType.posTypeName AS posType,\n posExecutive.posExecutiveName AS posExecutiveName,\n orgRoot.isDeputy AS isDeputy,\n orgChild1.isOfficer AS isOfficer,\n posMaster.orgRevisionId AS orgRevisionId,\n posMaster.orgRootId AS orgRootId,\n posMaster.orgChild1Id AS orgChild1Id,\n posMaster.orgChild2Id AS orgChild2Id,\n posMaster.orgChild3Id AS orgChild3Id,\n posMaster.orgChild4Id AS orgChild4Id,\n CONCAT(posMaster.id, profile.id) AS `key`,\n (\n SELECT actFullNameId \n FROM view_director_acting AS acting\n WHERE acting.Id = posMaster.current_holderId \n AND acting.orgRootId = posMaster.orgRootId \n AND (acting.orgChild1Id = posMaster.orgChild1Id OR acting.orgChild1Id IS NULL)\n AND (acting.orgChild2Id = posMaster.orgChild2Id OR acting.orgChild2Id IS NULL)\n AND (acting.orgChild3Id = posMaster.orgChild3Id OR acting.orgChild3Id IS NULL)\n AND (acting.orgChild4Id = posMaster.orgChild4Id OR acting.orgChild4Id IS NULL)\n LIMIT 1\n ) AS actFullNameId,\n (\n SELECT actFullName \n FROM view_director_acting AS acting\n WHERE acting.Id = posMaster.current_holderId \n AND acting.orgRootId = posMaster.orgRootId \n AND (acting.orgChild1Id = posMaster.orgChild1Id OR acting.orgChild1Id IS NULL)\n AND (acting.orgChild2Id = posMaster.orgChild2Id OR acting.orgChild2Id IS NULL)\n AND (acting.orgChild3Id = posMaster.orgChild3Id OR acting.orgChild3Id IS NULL)\n AND (acting.orgChild4Id = posMaster.orgChild4Id OR acting.orgChild4Id IS NULL)\n LIMIT 1\n ) AS actFullName\n FROM\n posMaster\n JOIN profile ON posMaster.current_holderId = profile.id\n LEFT JOIN orgRoot ON posMaster.orgRootId = orgRoot.id\n LEFT JOIN orgChild1 ON posMaster.orgChild1Id = orgChild1.id\n LEFT JOIN orgChild2 ON posMaster.orgChild2Id = orgChild2.id\n LEFT JOIN orgChild3 ON posMaster.orgChild3Id = orgChild3.id\n LEFT JOIN orgChild4 ON posMaster.orgChild4Id = orgChild4.id\n JOIN posLevel ON profile.posLevelId = posLevel.id\n JOIN posType ON profile.posTypeId = posType.id\n LEFT JOIN position ON posMaster.id = position.posMasterId\n LEFT JOIN posExecutive ON position.posExecutiveId = posExecutive.id\n INNER JOIN orgRevision ON posMaster.orgRevisionId = orgRevision.id\n WHERE\n (position.positionIsSelected = TRUE)\n AND (orgRevision.orgRevisionIsCurrent = TRUE\n AND orgRevision.orgRevisionIsDraft = FALSE)"]); - } - -} From 263f9ea2c9acac6caa74090f21cd8ca21098e1f4 Mon Sep 17 00:00:00 2001 From: mamoss <> Date: Wed, 12 Nov 2025 23:47:34 +0700 Subject: [PATCH 17/38] test api-key --- src/middlewares/auth.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/middlewares/auth.ts b/src/middlewares/auth.ts index c27e6188..1f636080 100644 --- a/src/middlewares/auth.ts +++ b/src/middlewares/auth.ts @@ -27,14 +27,14 @@ export async function expressAuthentication( securityName: string, _scopes?: string[], ) { - // // API_KEY bypass logic (support api_key, x-api-key, apikey) - // const apiKeyHeader = - // request.headers["api-key"] || request.headers["x-api-key"] || request.headers["apikey"]; - // if (apiKeyHeader !== undefined) { - // if (apiKeyHeader === process.env.API_KEY) { - // return { preferred_username: "api_key_bypass", apiKeyBypass: true }; - // } - // } + // API_KEY bypass logic (support api_key, x-api-key, apikey) + const apiKeyHeader = + request.headers["api-key"] || request.headers["x-api-key"] || request.headers["apikey"]; + if (apiKeyHeader !== undefined) { + if (apiKeyHeader === process.env.API_KEY) { + return { preferred_username: "api_key_bypass", apiKeyBypass: true }; + } + } if (process.env.NODE_ENV !== "production" && process.env.AUTH_BYPASS) { return { preferred_username: "bypassed" }; } From 1680c7eba197543d10965df3dc4506326363ee42 Mon Sep 17 00:00:00 2001 From: mamoss <> Date: Thu, 13 Nov 2025 01:12:03 +0700 Subject: [PATCH 18/38] comment api-key --- src/middlewares/auth.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/middlewares/auth.ts b/src/middlewares/auth.ts index 1f636080..c27e6188 100644 --- a/src/middlewares/auth.ts +++ b/src/middlewares/auth.ts @@ -27,14 +27,14 @@ export async function expressAuthentication( securityName: string, _scopes?: string[], ) { - // API_KEY bypass logic (support api_key, x-api-key, apikey) - const apiKeyHeader = - request.headers["api-key"] || request.headers["x-api-key"] || request.headers["apikey"]; - if (apiKeyHeader !== undefined) { - if (apiKeyHeader === process.env.API_KEY) { - return { preferred_username: "api_key_bypass", apiKeyBypass: true }; - } - } + // // API_KEY bypass logic (support api_key, x-api-key, apikey) + // const apiKeyHeader = + // request.headers["api-key"] || request.headers["x-api-key"] || request.headers["apikey"]; + // if (apiKeyHeader !== undefined) { + // if (apiKeyHeader === process.env.API_KEY) { + // return { preferred_username: "api_key_bypass", apiKeyBypass: true }; + // } + // } if (process.env.NODE_ENV !== "production" && process.env.AUTH_BYPASS) { return { preferred_username: "bypassed" }; } From c4e1ee55463de7ada93424507d492aff79acd4e4 Mon Sep 17 00:00:00 2001 From: Adisak Date: Thu, 13 Nov 2025 09:56:24 +0700 Subject: [PATCH 19/38] update --- src/controllers/CommandController.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index 32a2c1c2..2bf311ac 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -4265,8 +4265,16 @@ export class CommandController extends Controller { await Promise.all( body.data.map(async (item) => { const profile: any = await this.profileRepository.findOne({ - where: { id: item.profileId }, - relations: ["roleKeycloaks"], + where: { + id: item.profileId , + current_holders: { + orgRevision: { + orgRevisionIsCurrent: true, + orgRevisionIsDraft: false, + }, + } + }, + relations: ["current_holders","roleKeycloaks"], }); if (!profile) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทะเบียนประวัตินี้"); @@ -4310,9 +4318,7 @@ export class CommandController extends Controller { lastUpdatedAt: new Date(), }; if (item.isLeave != undefined && item.isLeave == true) { - // if(orgRevisionRef){ - // await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); - // } + await CreatePosMasterHistoryOfficer(profile.current_holders.id, req, "DELETE"); await removeProfileInOrganize(profile.id, "OFFICER"); } const clearProfile = await checkCommandType(String(item.commandId)); From cf00a32549a58c5555d54977bf0d7ffcbb699a50 Mon Sep 17 00:00:00 2001 From: Adisak Date: Thu, 13 Nov 2025 10:19:34 +0700 Subject: [PATCH 20/38] fix --- src/controllers/CommandController.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index 2bf311ac..1212d497 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -4274,7 +4274,7 @@ export class CommandController extends Controller { }, } }, - relations: ["current_holders","roleKeycloaks"], + relations: ["current_holders","current_holders.orgRevision","roleKeycloaks"], }); if (!profile) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทะเบียนประวัตินี้"); @@ -4318,7 +4318,9 @@ export class CommandController extends Controller { lastUpdatedAt: new Date(), }; if (item.isLeave != undefined && item.isLeave == true) { + console.log("profile.current_holders.id>>>",profile.current_holders.id); await CreatePosMasterHistoryOfficer(profile.current_holders.id, req, "DELETE"); + console.log("profile.id>>>",profile.id); await removeProfileInOrganize(profile.id, "OFFICER"); } const clearProfile = await checkCommandType(String(item.commandId)); From badecd1a3d17d19697affe3baaed143704080c75 Mon Sep 17 00:00:00 2001 From: Adisak Date: Thu, 13 Nov 2025 11:13:02 +0700 Subject: [PATCH 21/38] test --- src/controllers/CommandController.ts | 64 +++++++++++++++++++--------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index 1212d497..e5b9b553 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -4175,7 +4175,39 @@ export class CommandController extends Controller { return new HttpSuccess(); } + @Get("testPosMaster/{profileId}") + public async newnwenew( + @Request() req:RequestWithUser, + @Path() profileId:string + ){ + const profile: any = await this.profileRepository.findOne({ + where: { + id: profileId , + // current_holders: { + // orgRevision: { + // orgRevisionIsCurrent: true, + // orgRevisionIsDraft: false, + // }, + // } + }, + relations: ["current_holders","roleKeycloaks"], + }); + const orgRevision = await this.orgRevisionRepo.findOne({ + where: { + orgRevisionIsCurrent: true, + orgRevisionIsDraft: false, + }, + }); + + const orgRevisionRef = + profile?.current_holders?.find((x:any) => x.orgRevisionId == orgRevision?.id) ?? null; + console.log("profile.current_holders.id>>>",orgRevisionRef.id); + await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); + console.log("profile.id>>>",profile.id); + await removeProfileInOrganize(profile.id, "OFFICER"); + return new HttpSuccess(profile) + } @Post("excexute/salary") public async newSalaryAndUpdate( @Request() req: RequestWithUser, @@ -4265,30 +4297,22 @@ export class CommandController extends Controller { await Promise.all( body.data.map(async (item) => { const profile: any = await this.profileRepository.findOne({ - where: { - id: item.profileId , - current_holders: { - orgRevision: { - orgRevisionIsCurrent: true, - orgRevisionIsDraft: false, - }, - } - }, - relations: ["current_holders","current_holders.orgRevision","roleKeycloaks"], + where: { id: item.profileId }, + relations: ["current_holders","roleKeycloaks"], }); if (!profile) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทะเบียนประวัตินี้"); } - // const orgRevision = await this.orgRevisionRepo.findOne({ - // where: { - // orgRevisionIsCurrent: true, - // orgRevisionIsDraft: false, - // }, - // }); + const orgRevision = await this.orgRevisionRepo.findOne({ + where: { + orgRevisionIsCurrent: true, + orgRevisionIsDraft: false, + }, + }); - // const orgRevisionRef = - // profile?.current_holders?.find((x:any) => x.orgRevisionId == orgRevision?.id) ?? null; + const orgRevisionRef = + profile?.current_holders?.find((x:any) => x.orgRevisionId == orgRevision?.id) ?? null; //ลบตำแหน่งที่รักษาการแทน const code = _command?.commandType?.code; @@ -4318,8 +4342,8 @@ export class CommandController extends Controller { lastUpdatedAt: new Date(), }; if (item.isLeave != undefined && item.isLeave == true) { - console.log("profile.current_holders.id>>>",profile.current_holders.id); - await CreatePosMasterHistoryOfficer(profile.current_holders.id, req, "DELETE"); + console.log("profile.current_holders.id>>>",orgRevisionRef.id); + await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); console.log("profile.id>>>",profile.id); await removeProfileInOrganize(profile.id, "OFFICER"); } From 484d2994cee46d54cabc603cb673654b99a914df Mon Sep 17 00:00:00 2001 From: Adisak Date: Thu, 13 Nov 2025 11:49:38 +0700 Subject: [PATCH 22/38] fix --- src/controllers/CommandController.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index e5b9b553..aa4f6678 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -4341,9 +4341,11 @@ export class CommandController extends Controller { createdAt: new Date(), lastUpdatedAt: new Date(), }; - if (item.isLeave != undefined && item.isLeave == true) { + if (orgRevisionRef && item.isLeave == true){ console.log("profile.current_holders.id>>>",orgRevisionRef.id); await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); + } + if (item.isLeave != undefined && item.isLeave == true) { console.log("profile.id>>>",profile.id); await removeProfileInOrganize(profile.id, "OFFICER"); } From e1b4f9f9294576d55e7345d3fc86e45f0ee0a138 Mon Sep 17 00:00:00 2001 From: Adisak Date: Thu, 13 Nov 2025 13:13:03 +0700 Subject: [PATCH 23/38] =?UTF-8?q?=E0=B8=82=E0=B8=AD=E0=B9=82=E0=B8=AD?= =?UTF-8?q?=E0=B8=99=E0=B8=A5=E0=B8=9A=E0=B8=84=E0=B8=99=20+=20=E0=B9=80?= =?UTF-8?q?=E0=B8=9E=E0=B8=B4=E0=B9=88=E0=B8=A1=E0=B8=9B=E0=B8=A3=E0=B8=B0?= =?UTF-8?q?=E0=B8=A7=E0=B8=B1=E0=B8=95=E0=B8=B4=E0=B8=95=E0=B8=B3=E0=B9=81?= =?UTF-8?q?=E0=B8=AB=E0=B8=99=E0=B9=88=E0=B8=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/CommandController.ts | 57 ++++++---------------------- 1 file changed, 12 insertions(+), 45 deletions(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index aa4f6678..77e87ede 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -4175,39 +4175,7 @@ export class CommandController extends Controller { return new HttpSuccess(); } - @Get("testPosMaster/{profileId}") - public async newnwenew( - @Request() req:RequestWithUser, - @Path() profileId:string - ){ - const profile: any = await this.profileRepository.findOne({ - where: { - id: profileId , - // current_holders: { - // orgRevision: { - // orgRevisionIsCurrent: true, - // orgRevisionIsDraft: false, - // }, - // } - }, - relations: ["current_holders","roleKeycloaks"], - }); - const orgRevision = await this.orgRevisionRepo.findOne({ - where: { - orgRevisionIsCurrent: true, - orgRevisionIsDraft: false, - }, - }); - - const orgRevisionRef = - profile?.current_holders?.find((x:any) => x.orgRevisionId == orgRevision?.id) ?? null; - console.log("profile.current_holders.id>>>",orgRevisionRef.id); - await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); - console.log("profile.id>>>",profile.id); - await removeProfileInOrganize(profile.id, "OFFICER"); - return new HttpSuccess(profile) - } @Post("excexute/salary") public async newSalaryAndUpdate( @Request() req: RequestWithUser, @@ -4298,21 +4266,24 @@ export class CommandController extends Controller { body.data.map(async (item) => { const profile: any = await this.profileRepository.findOne({ where: { id: item.profileId }, - relations: ["current_holders","roleKeycloaks"], + relations: ["roleKeycloaks"], }); if (!profile) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทะเบียนประวัตินี้"); } - - const orgRevision = await this.orgRevisionRepo.findOne({ - where: { - orgRevisionIsCurrent: true, - orgRevisionIsDraft: false, + const posMaster: any = await this.posMasterRepository.findOne({ + where: { + current_holderId: item.profileId, + orgRevision:{ + orgRevisionIsCurrent: true, + orgRevisionIsDraft: false, + } }, + relations:['orgRevision'] }); - const orgRevisionRef = - profile?.current_holders?.find((x:any) => x.orgRevisionId == orgRevision?.id) ?? null; + + const orgRevisionRef = posMaster?posMaster.id: null; //ลบตำแหน่งที่รักษาการแทน const code = _command?.commandType?.code; @@ -4341,12 +4312,8 @@ export class CommandController extends Controller { createdAt: new Date(), lastUpdatedAt: new Date(), }; - if (orgRevisionRef && item.isLeave == true){ - console.log("profile.current_holders.id>>>",orgRevisionRef.id); - await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); - } if (item.isLeave != undefined && item.isLeave == true) { - console.log("profile.id>>>",profile.id); + await CreatePosMasterHistoryOfficer(orgRevisionRef, req, "DELETE"); await removeProfileInOrganize(profile.id, "OFFICER"); } const clearProfile = await checkCommandType(String(item.commandId)); From 6376a6ecfdc6eaf5362a4002b07920dcf9cb8fe4 Mon Sep 17 00:00:00 2001 From: harid Date: Thu, 13 Nov 2025 15:14:10 +0700 Subject: [PATCH 24/38] fix #1981, #1982 --- src/controllers/ProfileController.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index e1573661..120a7fa5 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -8584,6 +8584,7 @@ export class ProfileController extends Controller { node: null, nodeId: null, amount: profile ? profile.amount : null, + AmountOld: profile ? profile.amount : null, positionSalaryAmount: profile ? profile.positionSalaryAmount : null, mouthSalaryAmount: profile ? profile.mouthSalaryAmount : null, education: From f4f775b5ea001c87ead7f5b3261d87c0091de7f3 Mon Sep 17 00:00:00 2001 From: harid Date: Fri, 14 Nov 2025 17:33:37 +0700 Subject: [PATCH 25/38] =?UTF-8?q?=E0=B9=80=E0=B8=A3=E0=B8=B5=E0=B8=A2?= =?UTF-8?q?=E0=B8=87=E0=B8=A5=E0=B8=B3=E0=B8=94=E0=B8=B1=E0=B8=9A=E0=B8=82?= =?UTF-8?q?=E0=B9=89=E0=B8=AD=E0=B8=A1=E0=B8=B9=E0=B8=A5=E0=B8=AB=E0=B8=A5?= =?UTF-8?q?=E0=B8=B1=E0=B8=81=20#1991?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/MainController.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/controllers/MainController.ts b/src/controllers/MainController.ts index 0556570b..744c2c8f 100644 --- a/src/controllers/MainController.ts +++ b/src/controllers/MainController.ts @@ -36,14 +36,14 @@ export class MainController extends Controller { */ @Get("main/person") async getMainPerson() { - const bloodGroups = await this.bloodGroupRepo.find(); - const genders = await this.genderRepo.find(); - const prefixs = await this.prefixeRepo.find(); - const relationships = await this.relationshipRepo.find(); - const religions = await this.religionRepo.find(); - const rank = await this.rankRepo.find(); - const educationLevels = await this.educationLevelRepo.find(); - const provinces = await this.provinceRepo.find(); + const bloodGroups = await this.bloodGroupRepo.find({order: { name: "ASC" }}); + const genders = await this.genderRepo.find({order: { name: "ASC" }}); + const prefixs = await this.prefixeRepo.find({order: { name: "ASC" }}); + const relationships = await this.relationshipRepo.find({order: { name: "ASC" }}); + const religions = await this.religionRepo.find({order: { name: "ASC" }}); + const rank = await this.rankRepo.find({order: { name: "ASC" }}); + const educationLevels = await this.educationLevelRepo.find({order: { rank: "ASC" }}); + const provinces = await this.provinceRepo.find({order: { name: "ASC" }}); return new HttpSuccess({ bloodGroups, From 12f05e5ec3b99deb04de419b30c184bf7b14d3f0 Mon Sep 17 00:00:00 2001 From: harid Date: Mon, 17 Nov 2025 11:13:49 +0700 Subject: [PATCH 26/38] revert (fix view error) --- src/database/data-source.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/database/data-source.ts b/src/database/data-source.ts index 9de306d7..db5afc0d 100644 --- a/src/database/data-source.ts +++ b/src/database/data-source.ts @@ -47,7 +47,9 @@ export const AppDataSource = new DataSource({ logging: true, // timezone: "Z", entities: - process.env.NODE_ENV !== "production" ? ["src/entities/*.ts"] : ["dist/entities/*{.ts,.js}"], + process.env.NODE_ENV !== "production" + ? ["src/entities/**/*.ts"] + : ["dist/entities/**/*{.ts,.js}"], migrations: process.env.NODE_ENV !== "production" ? ["src/migration/**/*.ts"] From 925994dec6eb30bff32dfebc20b10442468379e5 Mon Sep 17 00:00:00 2001 From: harid Date: Wed, 19 Nov 2025 14:19:08 +0700 Subject: [PATCH 27/38] add districts & subDistricts --- src/controllers/MainController.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/controllers/MainController.ts b/src/controllers/MainController.ts index 744c2c8f..8429d1d1 100644 --- a/src/controllers/MainController.ts +++ b/src/controllers/MainController.ts @@ -10,6 +10,8 @@ import { Religion } from "../entities/Religion"; import { Rank } from "../entities/Rank"; import { EducationLevel } from "../entities/EducationLevel"; import { Province } from "../entities/Province"; +import { District } from "../entities/District"; +import { SubDistrict } from "../entities/SubDistrict"; @Route("api/v1/org/metadata") @Tags("Profile") @@ -28,6 +30,8 @@ export class MainController extends Controller { private rankRepo = AppDataSource.getRepository(Rank); private educationLevelRepo = AppDataSource.getRepository(EducationLevel); private provinceRepo = AppDataSource.getRepository(Province); + private districtRepo = AppDataSource.getRepository(District); + private subDistrictRepo = AppDataSource.getRepository(SubDistrict); /** * API ข้อมูลหลัก * @@ -44,6 +48,8 @@ export class MainController extends Controller { const rank = await this.rankRepo.find({order: { name: "ASC" }}); const educationLevels = await this.educationLevelRepo.find({order: { rank: "ASC" }}); const provinces = await this.provinceRepo.find({order: { name: "ASC" }}); + const districts = await this.districtRepo.find({order: { name: "ASC" }}); + const subDistricts = await this.subDistrictRepo.find({order: { name: "ASC" }}); return new HttpSuccess({ bloodGroups, @@ -54,6 +60,8 @@ export class MainController extends Controller { rank, educationLevels, provinces, + districts, + subDistricts, }); } } From 7c345a61f3e558867f41028251b9eadf58e7964e Mon Sep 17 00:00:00 2001 From: Adisak Date: Mon, 24 Nov 2025 10:38:58 +0700 Subject: [PATCH 28/38] #2004 --- src/controllers/CommandController.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index 77e87ede..3435a0c7 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -5718,6 +5718,9 @@ export class CommandController extends Controller { posNumCodeSit: _posNumCodeSit, posNumCodeSitAbb: _posNumCodeSitAbb, }); + if(orgRevisionRef){ + await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); + } await removeProfileInOrganize(profile.id, "OFFICER"); const clearProfile = await checkCommandType(String(item.commandId)); const _null: any = null; From d2426ca6e4a902738384ffe69935cf400842a67f Mon Sep 17 00:00:00 2001 From: Adisak Date: Tue, 25 Nov 2025 10:54:16 +0700 Subject: [PATCH 29/38] fix --- src/controllers/OrganizationUnauthorizeController.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/controllers/OrganizationUnauthorizeController.ts b/src/controllers/OrganizationUnauthorizeController.ts index 28c88db6..c5f67dee 100644 --- a/src/controllers/OrganizationUnauthorizeController.ts +++ b/src/controllers/OrganizationUnauthorizeController.ts @@ -517,8 +517,8 @@ export class OrganizationUnauthorizeController extends Controller { new Date( `${new Date(item.disCriplineDate).getFullYear()}-${String(new Date(item.disCriplineDate).getMonth() + 1).padStart(2, "0")}-${String(new Date(item.disCriplineDate).getDate() + 1).padStart(2, "0")}T00:00:00.000Z`, ) <= datePeriodEnd - ? true - : false, + ? false + : true, isSuspension: item.dateRetire == null ? false : true, isAbsent: item.profileDisciplineId ? true : false, isLeave: item.profileLeaveId ? true : false, @@ -971,8 +971,8 @@ export class OrganizationUnauthorizeController extends Controller { new Date( `${new Date(item.disCriplineDate).getFullYear()}-${String(new Date(item.disCriplineDate).getMonth() + 1).padStart(2, "0")}-${String(new Date(item.disCriplineDate).getDate() + 1).padStart(2, "0")}T00:00:00.000Z`, ) <= datePeriodEnd - ? true - : false, + ? false + : true, isSuspension: item.dateRetire == null ? false : true, isAbsent: item.profileDisciplineId ? true : false, isLeave: item.profileLeaveId ? true : false, From b26cbad5ee3d568ed1f4157205bff57bc41990b3 Mon Sep 17 00:00:00 2001 From: Adisak Date: Tue, 25 Nov 2025 12:01:06 +0700 Subject: [PATCH 30/38] fix duplicate salary list --- src/controllers/OrganizationUnauthorizeController.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/controllers/OrganizationUnauthorizeController.ts b/src/controllers/OrganizationUnauthorizeController.ts index c5f67dee..4510351c 100644 --- a/src/controllers/OrganizationUnauthorizeController.ts +++ b/src/controllers/OrganizationUnauthorizeController.ts @@ -340,6 +340,7 @@ export class OrganizationUnauthorizeController extends Controller { const [findPosMaster, total] = await AppDataSource.getRepository(viewPosMaster) .createQueryBuilder("viewPosMaster") .where({orgRevisionId: findRevision?.id}) + .andWhere({positionIsSelected: true}) // .andWhere("viewPosMaster.rootId IN (:...rootIds)", { rootIds }) .andWhere( new Brackets((qb) => { From 8f6637a6565698766dad92ce351a48d7bfc097fb Mon Sep 17 00:00:00 2001 From: Adisak Date: Tue, 25 Nov 2025 13:36:17 +0700 Subject: [PATCH 31/38] =?UTF-8?q?=E0=B8=AD=E0=B8=B1=E0=B8=9E=E0=B9=80?= =?UTF-8?q?=E0=B8=94=E0=B8=97=20view=5Fpos=5Fmaster?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/entities/view/viewPosMaster.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/entities/view/viewPosMaster.ts b/src/entities/view/viewPosMaster.ts index 58d341d3..c44aa2d6 100644 --- a/src/entities/view/viewPosMaster.ts +++ b/src/entities/view/viewPosMaster.ts @@ -78,14 +78,18 @@ import { ViewColumn, ViewEntity } from "typeorm"; LEFT JOIN posExecutive ON position.posExecutiveId = posExecutive.id LEFT JOIN ( - SELECT * - FROM profileDiscipline pd1 - WHERE pd1.date = ( - SELECT MAX(pd2.date) - FROM profileDiscipline pd2 - WHERE pd2.profileId = pd1.profileId - ) - ) AS profileDiscipline ON profileDiscipline.profileId = profile.id + SELECT * + FROM ( + SELECT + pd.*, + ROW_NUMBER() OVER ( + PARTITION BY profileId + ORDER BY date DESC, id DESC + ) AS rn + FROM profileDiscipline pd + ) t + WHERE rn = 1 + ) AS profileDiscipline ON profileDiscipline.profileId = profile.id LEFT JOIN ( SELECT pl1.* FROM profileLeave pl1 From 4c3d3dceffadb8e21e9d970e7b11c25db0d4907a Mon Sep 17 00:00:00 2001 From: harid Date: Tue, 25 Nov 2025 17:11:51 +0700 Subject: [PATCH 32/38] =?UTF-8?q?=E0=B8=AD=E0=B8=B1=E0=B8=9E=E0=B9=80?= =?UTF-8?q?=E0=B8=94=E0=B8=95=E0=B8=9F=E0=B8=B4=E0=B8=A5=E0=B8=94=E0=B9=8C?= =?UTF-8?q?=20prefixMain=20#2033?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/CommandController.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index 3435a0c7..b6b5fc7d 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -6041,6 +6041,7 @@ export class CommandController extends Controller { profile.isProbation = item.bodyProfile.isProbation; //เพิ่มใหม่จากรับโอน 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; @@ -6093,6 +6094,7 @@ export class CommandController extends Controller { profile.amountSpecial = item.bodyProfile.amountSpecial ?? null; profile.isProbation = item.bodyProfile.isProbation; 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; @@ -6152,6 +6154,7 @@ export class CommandController extends Controller { 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 From 4f30ea9c6ba6a8195342e82ee24535ca2d64bbe8 Mon Sep 17 00:00:00 2001 From: Adisak Date: Wed, 26 Nov 2025 09:42:43 +0700 Subject: [PATCH 33/38] #2036 --- src/controllers/ProfileController.ts | 25 ++++---------------- src/controllers/ProfileEmployeeController.ts | 10 ++------ src/interfaces/extension.ts | 5 +--- 3 files changed, 8 insertions(+), 32 deletions(-) diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index 120a7fa5..6558f0ee 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -3302,10 +3302,7 @@ export class ProfileController extends Controller { citizenIdDigits[10] * 3 + citizenIdDigits[11] * 2; const calStp2 = cal % 11; - let chkDigit = 11 - calStp2; - if (chkDigit >= 10) { - chkDigit = 0; - } + const chkDigit = (11 - calStp2) % 10; if (citizenIdDigits[12] !== chkDigit) { throw new HttpError(HttpStatus.NOT_FOUND, "ข้อมูลรหัสบัตรประจำตัวประชาชนไม่ถูกต้อง"); @@ -3338,10 +3335,7 @@ export class ProfileController extends Controller { citizenIdDigits[10] * 3 + citizenIdDigits[11] * 2; const calStp2 = cal % 11; - let chkDigit = 11 - calStp2; - if (chkDigit >= 10) { - chkDigit = 0; - } + const chkDigit = (11 - calStp2) % 10; // else if(chkDigit === 11){ // chkDigit = cal % 10; // } @@ -3416,10 +3410,7 @@ export class ProfileController extends Controller { citizenIdDigits[10] * 3 + citizenIdDigits[11] * 2; const calStp2 = cal % 11; - let chkDigit = 11 - calStp2; - if (chkDigit >= 10) { - chkDigit = 0; - } + const chkDigit = (11 - calStp2) % 10; if (citizenIdDigits[12] !== chkDigit) { throw new HttpError(HttpStatus.NOT_FOUND, "ข้อมูลรหัสบัตรประจำตัวประชาชนไม่ถูกต้อง"); @@ -3484,10 +3475,7 @@ export class ProfileController extends Controller { citizenIdDigits[10] * 3 + citizenIdDigits[11] * 2; const calStp2 = cal % 11; - let chkDigit = 11 - calStp2; - if (chkDigit >= 10) { - chkDigit = 0; - } + const chkDigit = (11 - calStp2) % 10; if (citizenIdDigits[12] !== chkDigit) { throw new HttpError(HttpStatus.NOT_FOUND, "ข้อมูลรหัสบัตรประจำตัวประชาชนไม่ถูกต้อง"); @@ -5249,10 +5237,7 @@ export class ProfileController extends Controller { citizenIdDigits[10] * 3 + citizenIdDigits[11] * 2; const calStp2 = cal % 11; - let chkDigit = 11 - calStp2; - if (chkDigit >= 10) { - chkDigit = 0; - } + const chkDigit = (11 - calStp2) % 10; if (citizenIdDigits[12] !== chkDigit) { throw new HttpError(HttpStatus.NOT_FOUND, "ข้อมูลรหัสบัตรประจำตัวประชาชนไม่ถูกต้อง"); diff --git a/src/controllers/ProfileEmployeeController.ts b/src/controllers/ProfileEmployeeController.ts index cdbac600..ac5523bb 100644 --- a/src/controllers/ProfileEmployeeController.ts +++ b/src/controllers/ProfileEmployeeController.ts @@ -1891,10 +1891,7 @@ export class ProfileEmployeeController extends Controller { citizenIdDigits[10] * 3 + citizenIdDigits[11] * 2; const calStp2 = cal % 11; - let chkDigit = 11 - calStp2; - if (chkDigit >= 10) { - chkDigit = 0; - } + const chkDigit = (11 - calStp2) % 10; if (citizenIdDigits[12] !== chkDigit) { throw new HttpError(HttpStatus.NOT_FOUND, "ข้อมูลรหัสบัตรประจำตัวประชาชนไม่ถูกต้อง"); @@ -1983,10 +1980,7 @@ export class ProfileEmployeeController extends Controller { citizenIdDigits[10] * 3 + citizenIdDigits[11] * 2; const calStp2 = cal % 11; - let chkDigit = 11 - calStp2; - if (chkDigit >= 10) { - chkDigit = 0; - } + const chkDigit = (11 - calStp2) % 10; if (citizenIdDigits[12] !== chkDigit) { throw new HttpError(HttpStatus.NOT_FOUND, "ข้อมูลรหัสบัตรประจำตัวประชาชนไม่ถูกต้อง"); diff --git a/src/interfaces/extension.ts b/src/interfaces/extension.ts index c81e66c0..4a5dc5a3 100644 --- a/src/interfaces/extension.ts +++ b/src/interfaces/extension.ts @@ -275,10 +275,7 @@ class Extension { citizenIdDigits[10] * 3 + citizenIdDigits[11] * 2; const calStp2 = cal % 11; - let chkDigit = 11 - calStp2; - if (chkDigit >= 10) { - chkDigit = 0; - } + const chkDigit = (11 - calStp2) % 10; // if (citizenIdDigits[12] !== chkDigit) { // throw new HttpError(HttpStatus.NOT_FOUND, "ข้อมูลรหัสบัตรประจำตัวประชาชนไม่ถูกต้อง"); From a0f18b858feb22f6c6dd0d5ded3a03bfd99b9e2c Mon Sep 17 00:00:00 2001 From: Adisak Date: Wed, 26 Nov 2025 09:47:12 +0700 Subject: [PATCH 34/38] =?UTF-8?q?fix=20=E0=B8=A3=E0=B8=B2=E0=B8=A2?= =?UTF-8?q?=E0=B8=8A=E0=B8=B7=E0=B9=88=E0=B8=AD=E0=B8=A3=E0=B8=B2=E0=B8=8A?= =?UTF-8?q?=E0=B8=81=E0=B8=B2=E0=B8=A3=E0=B8=97=E0=B8=B5=E0=B9=88=E0=B9=80?= =?UTF-8?q?=E0=B8=A5=E0=B8=B7=E0=B9=88=E0=B8=AD=E0=B8=99=E0=B9=80=E0=B8=87?= =?UTF-8?q?=E0=B8=B4=E0=B8=99=E0=B9=80=E0=B8=94=E0=B8=B7=E0=B8=AD=E0=B8=99?= =?UTF-8?q?=20(isPunish)=20salary/gen=20=E0=B9=80=E0=B8=AA=E0=B9=89?= =?UTF-8?q?=E0=B8=99=E0=B9=80=E0=B8=81=E0=B9=88=E0=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/OrganizationUnauthorizeController.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/controllers/OrganizationUnauthorizeController.ts b/src/controllers/OrganizationUnauthorizeController.ts index 4510351c..c72b600f 100644 --- a/src/controllers/OrganizationUnauthorizeController.ts +++ b/src/controllers/OrganizationUnauthorizeController.ts @@ -280,8 +280,8 @@ export class OrganizationUnauthorizeController extends Controller { `${new Date(x.date).getFullYear()}-${String(new Date(x.date).getMonth() + 1).padStart(2, "0")}-${String(new Date(x.date).getDate() + 1).padStart(2, "0")}T00:00:00.000Z`, ) <= datePeriodEnd, ).length > 0 - ? true - : false, + ? false + : true, isSuspension: item.current_holder.dateRetire == null ? false : true, isAbsent: item.current_holder.profileDisciplines.length > 0 ? true : false, isLeave: item.current_holder.profileLeaves.length > 0 ? true : false, @@ -740,8 +740,8 @@ export class OrganizationUnauthorizeController extends Controller { `${new Date(x.date).getFullYear()}-${String(new Date(x.date).getMonth() + 1).padStart(2, "0")}-${String(new Date(x.date).getDate() + 1).padStart(2, "0")}T00:00:00.000Z`, ) <= datePeriodEnd, ).length > 0 - ? true - : false, + ? false + : true, isSuspension: item.current_holder.dateRetire == null ? false : true, isAbsent: item.current_holder.profileDisciplines.length > 0 ? true : false, isLeave: item.current_holder.profileLeaves.length > 0 ? true : false, From 4ba71ff83036bb03264a6abb6edc5c8f3e730e03 Mon Sep 17 00:00:00 2001 From: harid Date: Wed, 26 Nov 2025 16:20:11 +0700 Subject: [PATCH 35/38] =?UTF-8?q?=E0=B9=80=E0=B8=89=E0=B8=9E=E0=B8=B2?= =?UTF-8?q?=E0=B8=B0=E0=B8=84=E0=B8=B3=E0=B8=AA=E0=B8=B1=E0=B9=88=E0=B8=87?= =?UTF-8?q?=20C-PM-10=20=E0=B9=83=E0=B8=AB=E0=B9=89=E0=B8=95=E0=B8=B1?= =?UTF-8?q?=E0=B8=94=20receiverUserId=20=E0=B8=97=E0=B8=B5=E0=B9=88?= =?UTF-8?q?=E0=B8=AA=E0=B9=88=E0=B8=87=20noti=20=E0=B8=84=E0=B8=A3?= =?UTF-8?q?=E0=B8=B1=E0=B9=89=E0=B8=87=E0=B9=81=E0=B8=A3=E0=B8=81=E0=B8=AD?= =?UTF-8?q?=E0=B8=AD=E0=B8=81=20#1995?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/rabbitmq.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/services/rabbitmq.ts b/src/services/rabbitmq.ts index dd57d886..74df4dc0 100644 --- a/src/services/rabbitmq.ts +++ b/src/services/rabbitmq.ts @@ -445,7 +445,11 @@ async function handler_command_noti(msg: amqp.ConsumeMessage): Promise isSendNotification: true, })) : []; - + /*เฉพาะคำสั่ง C-PM-10 ให้ตัด receiverUserId ที่ส่ง noti ครั้งแรกออก*/ + if (command && command.commandType && ["C-PM-10"].includes(command.commandType.code)) { + const firstNotiIds = profiles.map((p:any) => p.receiverUserId); + profilesSend = profilesSend.filter((x:any) => !firstNotiIds.includes(x.receiverUserId)); + } const payloadStr = await PayloadSendNoti(command.id); const profilesSendRequest = new CallAPI() .PostData( From 4bdf1ad7b49f3fa10469e789f323049ecc0212fc Mon Sep 17 00:00:00 2001 From: harid Date: Wed, 26 Nov 2025 16:48:35 +0700 Subject: [PATCH 36/38] =?UTF-8?q?=E0=B9=80=E0=B8=89=E0=B8=9E=E0=B8=B2?= =?UTF-8?q?=E0=B8=B0=E0=B8=84=E0=B8=B3=E0=B8=AA=E0=B8=B1=E0=B9=88=E0=B8=87?= =?UTF-8?q?=20C-PM-10=20=E0=B9=83=E0=B8=AB=E0=B9=89=E0=B8=95=E0=B8=B1?= =?UTF-8?q?=E0=B8=94=20profilesNotiRequest=20=E0=B8=97=E0=B8=B5=E0=B9=88?= =?UTF-8?q?=E0=B8=AA=E0=B9=88=E0=B8=87=20noti=20=E0=B8=84=E0=B8=A3?= =?UTF-8?q?=E0=B8=B1=E0=B9=89=E0=B8=87=E0=B9=81=E0=B8=A3=E0=B8=81=E0=B8=AD?= =?UTF-8?q?=E0=B8=AD=E0=B8=81=20=E0=B9=80=E0=B8=9E=E0=B8=A3=E0=B8=B2?= =?UTF-8?q?=E0=B8=B0=20UI=20=E0=B8=9B=E0=B8=B4=E0=B8=94=20Tab=20=E0=B8=99?= =?UTF-8?q?=E0=B8=B5=E0=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/rabbitmq.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/services/rabbitmq.ts b/src/services/rabbitmq.ts index 74df4dc0..0c18117c 100644 --- a/src/services/rabbitmq.ts +++ b/src/services/rabbitmq.ts @@ -445,11 +445,6 @@ async function handler_command_noti(msg: amqp.ConsumeMessage): Promise isSendNotification: true, })) : []; - /*เฉพาะคำสั่ง C-PM-10 ให้ตัด receiverUserId ที่ส่ง noti ครั้งแรกออก*/ - if (command && command.commandType && ["C-PM-10"].includes(command.commandType.code)) { - const firstNotiIds = profiles.map((p:any) => p.receiverUserId); - profilesSend = profilesSend.filter((x:any) => !firstNotiIds.includes(x.receiverUserId)); - } const payloadStr = await PayloadSendNoti(command.id); const profilesSendRequest = new CallAPI() .PostData( @@ -479,7 +474,14 @@ async function handler_command_noti(msg: amqp.ConsumeMessage): Promise console.error("Full error object:", error); }); - await Promise.all([profilesNotiRequest, profilesSendRequest]); + /*เฉพาะคำสั่ง C-PM-10 ให้ตัด profilesNotiRequest ที่ส่ง noti ครั้งแรกออก*/ + if (command && command.commandType && ["C-PM-10"].includes(command.commandType.code)) { + await Promise.all([profilesSendRequest]); + } + else { + await Promise.all([profilesNotiRequest, profilesSendRequest]); + } + console.log("[AMQ] Send Notification Success"); return true; From 072d9a6880d2b49f746412e7a347b48449ba7187 Mon Sep 17 00:00:00 2001 From: harid Date: Thu, 27 Nov 2025 19:28:38 +0700 Subject: [PATCH 37/38] migrate #2043 --- src/controllers/EducationLevelController.ts | 4 ++++ src/entities/EducationLevel.ts | 21 +++++++++++++++++++ ...-update_table_educationLeave_add_fields.ts | 16 ++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 src/migration/1764244579743-update_table_educationLeave_add_fields.ts diff --git a/src/controllers/EducationLevelController.ts b/src/controllers/EducationLevelController.ts index eecdbda0..f99214a9 100644 --- a/src/controllers/EducationLevelController.ts +++ b/src/controllers/EducationLevelController.ts @@ -132,6 +132,8 @@ export class EducationLevelController extends Controller { "id", "name", "rank", + "educationLevel", + "isHigh", "createdAt", "lastUpdatedAt", "createdFullName", @@ -157,6 +159,8 @@ export class EducationLevelController extends Controller { "id", "name", "rank", + "educationLevel", + "isHigh", "createdAt", "lastUpdatedAt", "createdFullName", diff --git a/src/entities/EducationLevel.ts b/src/entities/EducationLevel.ts index 631c5a9d..cc291e90 100644 --- a/src/entities/EducationLevel.ts +++ b/src/entities/EducationLevel.ts @@ -17,6 +17,21 @@ export class EducationLevel extends EntityBase { default: null, }) rank: number; + + @Column({ + nullable: true, + comment: "ขีดจำกัดวุฒิการศึกษา", + length: 50, + default: null, + }) + educationLevel?: string; + + @Column({ + nullable: true, + comment: "วุฒิการศึกษาสูงสุด", + default: null, + }) + isHigh?: boolean; } export class CreateEducationLevel { @@ -25,6 +40,12 @@ export class CreateEducationLevel { @Column() rank: number; + + @Column() + educationLevel?: string; + + @Column() + isHigh?: boolean; } export type UpdateEducationLevel = Partial; diff --git a/src/migration/1764244579743-update_table_educationLeave_add_fields.ts b/src/migration/1764244579743-update_table_educationLeave_add_fields.ts new file mode 100644 index 00000000..0453ff63 --- /dev/null +++ b/src/migration/1764244579743-update_table_educationLeave_add_fields.ts @@ -0,0 +1,16 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class UpdateTableEducationLeaveAddFields1764244579743 implements MigrationInterface { + name = 'UpdateTableEducationLeaveAddFields1764244579743' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`educationLevel\` ADD \`educationLevel\` varchar(50) NULL COMMENT 'ขีดจำกัดวุฒิการศึกษา'`); + await queryRunner.query(`ALTER TABLE \`educationLevel\` ADD \`isHigh\` tinyint NULL COMMENT 'วุฒิการศึกษาสูงสุด'`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`educationLevel\` DROP COLUMN \`isHigh\``); + await queryRunner.query(`ALTER TABLE \`educationLevel\` DROP COLUMN \`educationLevel\``); + } + +} From bd9c270cd7de29fad9f41fe0a104d4303eac83a3 Mon Sep 17 00:00:00 2001 From: mamoss <> Date: Sat, 29 Nov 2025 14:56:58 +0700 Subject: [PATCH 38/38] add role parent --- src/controllers/CommandController.ts | 107 ++++++++-------- .../DevelopmentRequestController.ts | 35 +++--- .../OrganizationDotnetController.ts | 10 ++ src/controllers/ProfileController.ts | 73 ++++++----- src/controllers/ProfileEditController.ts | 39 +++--- .../ProfileEditEmployeeController.ts | 30 ++--- src/controllers/ProfileEmployeeController.ts | 58 +++++---- .../ProfileSalaryTempController.ts | 118 +++++++----------- src/interfaces/permission.ts | 2 +- 9 files changed, 231 insertions(+), 241 deletions(-) diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index b6b5fc7d..cad8dc18 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -215,7 +215,7 @@ export class CommandController extends Controller { _data.child1 != undefined && _data.child1 != null ? _data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` + : `current_holders.orgChild1Id is ${_data.privilege == "PARENT" ? "not null" : "null"}` : "1=1", { child1: _data.child1, @@ -1477,7 +1477,7 @@ export class CommandController extends Controller { } // @Get("XXX") async cronjobUpdateRetirementStatus(/*@Request() request: RequestWithUser*/) { - const adminToken = await getToken() ?? ""; + const adminToken = (await getToken()) ?? ""; const today = new Date(); today.setUTCHours(0, 0, 0, 0); let type: string = "OFFICER"; @@ -1672,7 +1672,7 @@ export class CommandController extends Controller { positionIsSelected: false, lastUpdateFullName: "System Administrator", lastUpdatedAt: _Date, - } + }, ); _posMaster.isSit = false; _posMaster.current_holderId = null; @@ -1702,7 +1702,7 @@ export class CommandController extends Controller { positionIsSelected: false, lastUpdateFullName: "System Administrator", lastUpdatedAt: _Date, - } + }, ); _posMaster.isSit = false; _posMaster.next_holderId = null; @@ -1730,7 +1730,7 @@ export class CommandController extends Controller { positionIsSelected: false, lastUpdateFullName: "System Administrator", lastUpdatedAt: _Date, - } + }, ); _posMaster.isSit = false; _posMaster.current_holderId = null; @@ -1977,62 +1977,68 @@ export class CommandController extends Controller { if (commandCode == "C-PM-21") { profileTemp.position = profile?.positionTemp ?? "-"; profileTemp.posLevel = profile?.posLevelNameTemp ?? "-"; - profileTemp.org = (profile?.child4Temp == null ? "" : profile?.child4Temp + "\n") + + profileTemp.org = + (profile?.child4Temp == null ? "" : profile?.child4Temp + "\n") + (profile?.child3Temp == null ? "" : profile?.child3Temp + "\n") + (profile?.child2Temp == null ? "" : profile?.child2Temp + "\n") + (profile?.child1Temp == null ? "" : profile?.child1Temp + "\n") + - (profile?.rootTemp == null ? "" : profile?.rootTemp) + (profile?.rootTemp == null ? "" : profile?.rootTemp); if (profile?.nodeTemp) { switch (profile?.nodeTemp) { case "4": profileTemp.posNo = `${profile.child4ShortNameTemp} ${profile?.posMasterNoTemp}`; - break + break; case "3": - profileTemp.posNo = `${profile.child3ShortNameTemp} ${profile?.posMasterNoTemp}`; - break + profileTemp.posNo = `${profile.child3ShortNameTemp} ${profile?.posMasterNoTemp}`; + break; case "2": profileTemp.posNo = `${profile.child2ShortNameTemp} ${profile?.posMasterNoTemp}`; - break + break; case "1": - profileTemp.posNo = `${profile.child1ShortNameTemp} ${profile?.posMasterNoTemp}`; - break + profileTemp.posNo = `${profile.child1ShortNameTemp} ${profile?.posMasterNoTemp}`; + break; case "0": - profileTemp.posNo = `${profile.rootShortNameTemp} ${profile?.posMasterNoTemp}`; - break - default: break; + profileTemp.posNo = `${profile.rootShortNameTemp} ${profile?.posMasterNoTemp}`; + break; + default: + break; } } } return { no: Extension.ToThaiNumber((idx + 1).toString()), - org: commandCode != "C-PM-21" - ? profile?.isLeave == false - ? (_child4 == null ? "" : _child4 + "\n") + - (_child3 == null ? "" : _child3 + "\n") + - (_child2 == null ? "" : _child2 + "\n") + - (_child1 == null ? "" : _child1 + "\n") + - (_root == null ? "" : _root) - : orgLeave - : profileTemp.org, + org: + commandCode != "C-PM-21" + ? profile?.isLeave == false + ? (_child4 == null ? "" : _child4 + "\n") + + (_child3 == null ? "" : _child3 + "\n") + + (_child2 == null ? "" : _child2 + "\n") + + (_child1 == null ? "" : _child1 + "\n") + + (_root == null ? "" : _root) + : orgLeave + : profileTemp.org, fullName: `${x.prefix}${x.firstName} ${x.lastName}`, citizenId: Extension.ToThaiNumber(x.citizenId), - position: commandCode != "C-PM-21" - ? profile?.position - ? profile?.position - : "-" - : profileTemp.position, - posLevel: commandCode != "C-PM-21" - ? profile?.posType && profile?.posLevel - ? Extension.ToThaiNumber( - `${profile?.posType.posTypeShortName} ${profile?.posLevel.posLevelName}`, - ) - : "-" - : Extension.ToThaiNumber(profileTemp.posLevel), - posNo: commandCode != "C-PM-21" - ? shortName - ? Extension.ToThaiNumber(shortName) - : "-" - : Extension.ToThaiNumber(profileTemp.posNo), + position: + commandCode != "C-PM-21" + ? profile?.position + ? profile?.position + : "-" + : profileTemp.position, + posLevel: + commandCode != "C-PM-21" + ? profile?.posType && profile?.posLevel + ? Extension.ToThaiNumber( + `${profile?.posType.posTypeShortName} ${profile?.posLevel.posLevelName}`, + ) + : "-" + : Extension.ToThaiNumber(profileTemp.posLevel), + posNo: + commandCode != "C-PM-21" + ? shortName + ? Extension.ToThaiNumber(shortName) + : "-" + : Extension.ToThaiNumber(profileTemp.posNo), amount: x.amount ? Extension.ToThaiNumber(x.amount.toLocaleString()) : "-", dateRetire: profile?.dateRetire ? Extension.ToThaiNumber(Extension.ToThaiShortDate_monthYear(profile?.dateRetire)) @@ -4272,18 +4278,17 @@ export class CommandController extends Controller { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลทะเบียนประวัตินี้"); } const posMaster: any = await this.posMasterRepository.findOne({ - where: { + where: { current_holderId: item.profileId, - orgRevision:{ + orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false, - } + }, }, - relations:['orgRevision'] + relations: ["orgRevision"], }); - - - const orgRevisionRef = posMaster?posMaster.id: null; + + const orgRevisionRef = posMaster ? posMaster.id : null; //ลบตำแหน่งที่รักษาการแทน const code = _command?.commandType?.code; @@ -4784,7 +4789,7 @@ export class CommandController extends Controller { _profile.leaveDate = item.commandDateAffect ?? _null; _profile.leaveType = exceptClear.LeaveType ?? _null; } else { - if(orgRevisionRef){ + if (orgRevisionRef) { await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); } await removeProfileInOrganize(_profile.id, "OFFICER"); @@ -5718,7 +5723,7 @@ export class CommandController extends Controller { posNumCodeSit: _posNumCodeSit, posNumCodeSitAbb: _posNumCodeSitAbb, }); - if(orgRevisionRef){ + if (orgRevisionRef) { await CreatePosMasterHistoryOfficer(orgRevisionRef.id, req, "DELETE"); } await removeProfileInOrganize(profile.id, "OFFICER"); diff --git a/src/controllers/DevelopmentRequestController.ts b/src/controllers/DevelopmentRequestController.ts index 7c646230..16288640 100644 --- a/src/controllers/DevelopmentRequestController.ts +++ b/src/controllers/DevelopmentRequestController.ts @@ -52,7 +52,7 @@ export class DevelopmentRequestController extends Controller { if (!profile) { throw new HttpError(HttpStatus.BAD_REQUEST, "ไม่พบ profile ดังกล่าว"); } - + let query = await AppDataSource.getRepository(DevelopmentRequest) .createQueryBuilder("developmentRequest") .andWhere( @@ -104,16 +104,13 @@ export class DevelopmentRequestController extends Controller { ); }), ) - .orderBy("developmentRequest.createdAt", "DESC") + .orderBy("developmentRequest.createdAt", "DESC"); - if (sortBy) { - query = query.orderBy( - `developmentRequest.${sortBy}`, - descending ? "DESC" : "ASC" - ); - } + if (sortBy) { + query = query.orderBy(`developmentRequest.${sortBy}`, descending ? "DESC" : "ASC"); + } - const [lists, total] = await query + const [lists, total] = await query .skip((page - 1) * pageSize) .take(pageSize) .getManyAndCount(); @@ -166,7 +163,7 @@ export class DevelopmentRequestController extends Controller { data.child1 != undefined && data.child1 != null ? data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` + : `current_holders.orgChild1Id is ${data.privilege == "PARENT" ? "not null" : "null"}` : "1=1", { child1: data.child1, @@ -250,21 +247,17 @@ export class DevelopmentRequestController extends Controller { ); }), ) - .orderBy("developmentRequest.createdAt", "DESC") - + .orderBy("developmentRequest.createdAt", "DESC"); if (sortBy) { - query = query.orderBy( - `developmentRequest.${sortBy}`, - descending ? "DESC" : "ASC" - ); + query = query.orderBy(`developmentRequest.${sortBy}`, descending ? "DESC" : "ASC"); } - const [lists, total] = await query - .skip((page - 1) * pageSize) - .take(pageSize) - .getManyAndCount(); - + const [lists, total] = await query + .skip((page - 1) * pageSize) + .take(pageSize) + .getManyAndCount(); + const _data = lists.map((item) => ({ ...item, profile: null })); return new HttpSuccess({ data: _data, total }); } diff --git a/src/controllers/OrganizationDotnetController.ts b/src/controllers/OrganizationDotnetController.ts index 52acf7f0..52fbd5cd 100644 --- a/src/controllers/OrganizationDotnetController.ts +++ b/src/controllers/OrganizationDotnetController.ts @@ -1211,6 +1211,7 @@ export class OrganizationDotnetController extends Controller { let pos = await this.posMasterRepository.findOne({ relations: ["current_holder"], where: { + current_holder: Not(IsNull()), orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false, @@ -1234,6 +1235,7 @@ export class OrganizationDotnetController extends Controller { let pos = await this.posMasterRepository.findOne({ relations: ["current_holder"], where: { + current_holder: Not(IsNull()), orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false, @@ -1256,6 +1258,7 @@ export class OrganizationDotnetController extends Controller { let pos = await this.posMasterRepository.findOne({ relations: ["current_holder"], where: { + current_holder: Not(IsNull()), orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false, @@ -1278,6 +1281,7 @@ export class OrganizationDotnetController extends Controller { let pos = await this.posMasterRepository.findOne({ relations: ["current_holder"], where: { + current_holder: Not(IsNull()), orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false, @@ -1300,6 +1304,7 @@ export class OrganizationDotnetController extends Controller { let pos = await this.posMasterRepository.findOne({ relations: ["current_holder"], where: { + current_holder: Not(IsNull()), orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false, @@ -1511,6 +1516,7 @@ export class OrganizationDotnetController extends Controller { let pos = await this.posMasterRepository.findOne({ relations: ["current_holder"], where: { + current_holder: Not(IsNull()), orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false, @@ -1534,6 +1540,7 @@ export class OrganizationDotnetController extends Controller { let pos = await this.posMasterRepository.findOne({ relations: ["current_holder"], where: { + current_holder: Not(IsNull()), orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false, @@ -1556,6 +1563,7 @@ export class OrganizationDotnetController extends Controller { let pos = await this.posMasterRepository.findOne({ relations: ["current_holder"], where: { + current_holder: Not(IsNull()), orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false, @@ -1578,6 +1586,7 @@ export class OrganizationDotnetController extends Controller { let pos = await this.posMasterRepository.findOne({ relations: ["current_holder"], where: { + current_holder: Not(IsNull()), orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false, @@ -1600,6 +1609,7 @@ export class OrganizationDotnetController extends Controller { let pos = await this.posMasterRepository.findOne({ relations: ["current_holder"], where: { + current_holder: Not(IsNull()), orgRevision: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false, diff --git a/src/controllers/ProfileController.ts b/src/controllers/ProfileController.ts index 6558f0ee..ac19ffdf 100644 --- a/src/controllers/ProfileController.ts +++ b/src/controllers/ProfileController.ts @@ -2219,7 +2219,7 @@ export class ProfileController extends Controller { _data.child1 != undefined && _data.child1 != null ? _data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` + : `current_holders.orgChild1Id is ${_data.privilege == "PARENT" ? "not null" : "null"}` : "1=1", { child1: _data.child1, @@ -6137,7 +6137,7 @@ export class ProfileController extends Controller { _data.child1 != undefined && _data.child1 != null ? _data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` + : `current_holders.orgChild1Id is ${_data.privilege == "PARENT" ? "not null" : "null"}` : "1=1", { child1: _data.child1 }, ) @@ -6524,7 +6524,7 @@ export class ProfileController extends Controller { _data.child1 != undefined && _data.child1 != null ? _data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` + : `current_holders.orgChild1Id is ${_data.privilege == "PARENT" ? "not null" : "null"}` : "1=1", { child1: _data.child1 }, ) @@ -6632,6 +6632,7 @@ export class ProfileController extends Controller { position: _data.position, posNo: shortName ?? null, rootId: holder?.orgRoot?.id ?? null, + child1Id: holder?.orgChild1Id ?? null, root: holder?.orgRoot?.orgRootName ?? null, rootDnaId: holder?.orgRoot == null ? null : holder?.orgRoot?.ancestorDNA, orgRootShortName: holder?.orgRoot?.orgRootShortName ?? null, @@ -7352,10 +7353,10 @@ export class ProfileController extends Controller { nodeDnaId: null, type: profile.employeeClass, salary: profile.amount, - posNo: null - // root?.orgRootShortName && posMaster?.posMasterNo - // ? `${root?.orgRootShortName} ${posMaster?.posMasterNo}` - // : "", + posNo: null, + // root?.orgRootShortName && posMaster?.posMasterNo + // ? `${root?.orgRootShortName} ${posMaster?.posMasterNo}` + // : "", }; if (_profile.child4Id != null) { _profile.node = 4; @@ -7521,10 +7522,10 @@ export class ProfileController extends Controller { nodeDnaId: null, salary: profile ? profile.amount : null, amountSpecial: profile ? profile.amountSpecial : null, - posNo: null - // root?.orgRootShortName && posMaster?.posMasterNo - // ? `${root?.orgRootShortName} ${posMaster?.posMasterNo}` - // : "", + posNo: null, + // root?.orgRootShortName && posMaster?.posMasterNo + // ? `${root?.orgRootShortName} ${posMaster?.posMasterNo}` + // : "", }; if (_profile.child4Id != null) { @@ -8867,7 +8868,7 @@ export class ProfileController extends Controller { _data.child1 != undefined && _data.child1 != null ? _data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` + : `current_holders.orgChild1Id is ${_data.privilege == "PARENT" ? "not null" : "null"}` : "1=1", { child1: _data.child1 }, ) @@ -9390,7 +9391,7 @@ export class ProfileController extends Controller { _data.child1 != undefined && _data.child1 != null ? _data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` + : `current_holders.orgChild1Id is ${_data.privilege == "PARENT" ? "not null" : "null"}` : "1=1", { child1: _data.child1, @@ -9781,21 +9782,26 @@ export class ProfileController extends Controller { .leftJoinAndSelect("current_holders.positions", "positions") .leftJoinAndSelect("positions.posExecutive", "posExecutive") .andWhere( - new Brackets(qb => { + new Brackets((qb) => { qb.where("profile.position LIKE :keyword", { keyword: `%${body.keyword}%` }) .orWhere("posLevel.posLevelName LIKE :keyword", { keyword: `%${body.keyword}%` }) .orWhere("posType.posTypeName LIKE :keyword", { keyword: `%${body.keyword}%` }) - .orWhere("CONCAT(profile.prefix, profile.firstName, ' ', profile.lastName) LIKE :keyword", { keyword: `%${body.keyword}%` }); - }) + .orWhere( + "CONCAT(profile.prefix, profile.firstName, ' ', profile.lastName) LIKE :keyword", + { keyword: `%${body.keyword}%` }, + ); + }), ) .andWhere("profile.isLeave = false") - .andWhere("current_holders.orgRevisionId = :orgRevisionId", { orgRevisionId: orgRevisionActive.id }); + .andWhere("current_holders.orgRevisionId = :orgRevisionId", { + orgRevisionId: orgRevisionActive.id, + }); - const [findProfile, total] = await query - .orderBy("profile.citizenId", "ASC") - .skip((body.page - 1) * body.pageSize) - .take(body.pageSize) - .getManyAndCount(); + const [findProfile, total] = await query + .orderBy("profile.citizenId", "ASC") + .skip((body.page - 1) * body.pageSize) + .take(body.pageSize) + .getManyAndCount(); const mapDataProfile = await Promise.all( findProfile.map(async (item: Profile) => { @@ -9807,9 +9813,10 @@ export class ProfileController extends Controller { : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id); const position = posMaster == null || - 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 == + 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 @@ -9837,18 +9844,20 @@ export class ProfileController extends Controller { 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) != + 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) != + 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}` @@ -10775,7 +10784,7 @@ export class ProfileController extends Controller { await this.profileRepo.save(profile, { data: request }); setLogDataDiff(request, { before, after: profile }); if (requestBody.isLeave == true) { - if(orgRevisionRef){ + if (orgRevisionRef) { await CreatePosMasterHistoryOfficer(orgRevisionRef.id, request, "DELETE"); } await removeProfileInOrganize(profile.id, "OFFICER"); diff --git a/src/controllers/ProfileEditController.ts b/src/controllers/ProfileEditController.ts index c7d66ee0..4c4fc6b8 100644 --- a/src/controllers/ProfileEditController.ts +++ b/src/controllers/ProfileEditController.ts @@ -75,19 +75,16 @@ export class ProfileEditController extends Controller { ); }), ) - .orderBy("ProfileEdit.createdAt", "DESC") + .orderBy("ProfileEdit.createdAt", "DESC"); if (sortBy) { - query = query.orderBy( - `ProfileEdit.${sortBy}`, - descending ? "DESC" : "ASC" - ); + query = query.orderBy(`ProfileEdit.${sortBy}`, descending ? "DESC" : "ASC"); } const [getProfileEdit, total] = await query - .skip((page - 1) * pageSize) - .take(pageSize) - .getManyAndCount(); + .skip((page - 1) * pageSize) + .take(pageSize) + .getManyAndCount(); const _data = getProfileEdit.map((item) => ({ id: item.id, @@ -153,7 +150,7 @@ export class ProfileEditController extends Controller { data.child1 != undefined && data.child1 != null ? data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` + : `current_holders.orgChild1Id is ${data.privilege == "PARENT" ? "not null" : "null"}` : "1=1", { child1: data.child1, @@ -216,26 +213,20 @@ export class ProfileEditController extends Controller { ); }), ) - .orderBy("ProfileEdit.createdAt", "DESC") - + .orderBy("ProfileEdit.createdAt", "DESC"); + if (sortBy) { - if(sortBy == "fullname"){ - query = query.orderBy( - `profile.firstName`, - descending ? "DESC" : "ASC" - ); - }else{ - query = query.orderBy( - `ProfileEdit.${sortBy}`, - descending ? "DESC" : "ASC" - ); + if (sortBy == "fullname") { + query = query.orderBy(`profile.firstName`, descending ? "DESC" : "ASC"); + } else { + query = query.orderBy(`ProfileEdit.${sortBy}`, descending ? "DESC" : "ASC"); } } const [getProfileEdit, total] = await query - .skip((page - 1) * pageSize) - .take(pageSize) - .getManyAndCount(); + .skip((page - 1) * pageSize) + .take(pageSize) + .getManyAndCount(); const _data = getProfileEdit.map((item) => ({ id: item.id, diff --git a/src/controllers/ProfileEditEmployeeController.ts b/src/controllers/ProfileEditEmployeeController.ts index 75fa1672..8abc6d8b 100644 --- a/src/controllers/ProfileEditEmployeeController.ts +++ b/src/controllers/ProfileEditEmployeeController.ts @@ -119,7 +119,7 @@ export class ProfileEditEmployeeController extends Controller { .where("orgRevision.orgRevisionIsDraft = false") .andWhere("orgRevision.orgRevisionIsCurrent = true") .getOne(); - + let query = await AppDataSource.getRepository(ProfileEdit) .createQueryBuilder("ProfileEdit") .leftJoinAndSelect("ProfileEdit.profileEmployee", "profileEmployee") @@ -148,7 +148,7 @@ export class ProfileEditEmployeeController extends Controller { data.child1 != undefined && data.child1 != null ? data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` + : `current_holders.orgChild1Id is ${data.privilege == "PARENT" ? "not null" : "null"}` : "1=1", { child1: data.child1, @@ -211,26 +211,20 @@ export class ProfileEditEmployeeController extends Controller { ); }), ) - .orderBy("ProfileEdit.createdAt", "DESC") - + .orderBy("ProfileEdit.createdAt", "DESC"); + if (sortBy) { - if(sortBy == "fullname"){ - query = query.orderBy( - `profileEmployee.firstName`, - descending ? "DESC" : "ASC" - ); - }else{ - query = query.orderBy( - `ProfileEdit.${sortBy}`, - descending ? "DESC" : "ASC" - ); + if (sortBy == "fullname") { + query = query.orderBy(`profileEmployee.firstName`, descending ? "DESC" : "ASC"); + } else { + query = query.orderBy(`ProfileEdit.${sortBy}`, descending ? "DESC" : "ASC"); } } - + let [getProfileEdit, total] = await query - .skip((page - 1) * pageSize) - .take(pageSize) - .getManyAndCount(); + .skip((page - 1) * pageSize) + .take(pageSize) + .getManyAndCount(); const _data = getProfileEdit.map((item) => ({ id: item.id, diff --git a/src/controllers/ProfileEmployeeController.ts b/src/controllers/ProfileEmployeeController.ts index ac5523bb..f72df407 100644 --- a/src/controllers/ProfileEmployeeController.ts +++ b/src/controllers/ProfileEmployeeController.ts @@ -2034,12 +2034,15 @@ export class ProfileEmployeeController extends Controller { if (!result) { throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); } - try{ + try { await new permission().PermissionOrgUserDelete(request, "SYS_REGISTRY_EMP", result.id); await this.informationHistoryRepository.delete({ profileEmployeeId: id }); await this.profileRepo.remove(result); } catch { - throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่สามารถลบข้อมูลได้ เนื่องจากข้อมูลนี้ถูกใช้งานในระบบอื่น"); + throw new HttpError( + HttpStatusCode.NOT_FOUND, + "ไม่สามารถลบข้อมูลได้ เนื่องจากข้อมูลนี้ถูกใช้งานในระบบอื่น", + ); } return new HttpSuccess(); } @@ -2837,7 +2840,7 @@ export class ProfileEmployeeController extends Controller { _data.child1 != undefined && _data.child1 != null ? _data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` + : `current_holders.orgChild1Id is ${_data.privilege == "PARENT" ? "not null" : "null"}` : "1=1", { child1: _data.child1, @@ -3582,10 +3585,10 @@ export class ProfileEmployeeController extends Controller { nodeDnaId: null, salary: profile ? profile.amount : null, amountSpecial: profile ? profile.amountSpecial : null, - posNo: null - // root?.orgRootShortName && posMaster?.posMasterNo - // ? `${root?.orgRootShortName} ${posMaster?.posMasterNo}` - // : "", + posNo: null, + // root?.orgRootShortName && posMaster?.posMasterNo + // ? `${root?.orgRootShortName} ${posMaster?.posMasterNo}` + // : "", }; if (_profile.child4Id != null) { _profile.node = 4; @@ -3716,7 +3719,7 @@ export class ProfileEmployeeController extends Controller { _data.child1 != undefined && _data.child1 != null ? _data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` + : `current_holders.orgChild1Id is ${_data.privilege == "PARENT" ? "not null" : "null"}` : "1=1", { child1: _data.child1 }, ) @@ -4274,7 +4277,7 @@ export class ProfileEmployeeController extends Controller { _data.child1 != undefined && _data.child1 != null ? _data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` + : `current_holders.orgChild1Id is ${_data.privilege == "PARENT" ? "not null" : "null"}` : "1=1", { child1: _data.child1, @@ -4435,22 +4438,26 @@ export class ProfileEmployeeController extends Controller { .leftJoinAndSelect("current_holders.orgChild4", "orgChild4") .leftJoinAndSelect("current_holders.positions", "positions") .andWhere( - new Brackets(qb => { + new Brackets((qb) => { qb.where("profileEmployee.position LIKE :keyword", { keyword: `%${body.keyword}%` }) .orWhere("posLevel.posLevelName LIKE :keyword", { keyword: `%${body.keyword}%` }) .orWhere("posType.posTypeName LIKE :keyword", { keyword: `%${body.keyword}%` }) - .orWhere("CONCAT(profileEmployee.prefix, profileEmployee.firstName, ' ', profileEmployee.lastName) LIKE :keyword", { keyword: `%${body.keyword}%` }); - }) + .orWhere( + "CONCAT(profileEmployee.prefix, profileEmployee.firstName, ' ', profileEmployee.lastName) LIKE :keyword", + { keyword: `%${body.keyword}%` }, + ); + }), ) .andWhere("profileEmployee.isLeave = false") - .andWhere("current_holders.orgRevisionId = :orgRevisionId", { orgRevisionId: orgRevisionActive.id }); + .andWhere("current_holders.orgRevisionId = :orgRevisionId", { + orgRevisionId: orgRevisionActive.id, + }); if (body.type) { const typeUpper = body.type.trim().toUpperCase(); if (typeUpper === "EMPLOYEE") { query = query.andWhere("profileEmployee.employeeClass = 'PERM'"); - } - else if (typeUpper === "TEMP"){ + } else if (typeUpper === "TEMP") { query = query.andWhere("profileEmployee.employeeClass = 'TEMP'"); } } @@ -4471,9 +4478,10 @@ export class ProfileEmployeeController extends Controller { : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive.id); const position = posMaster == null || - 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 == + 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 @@ -4486,18 +4494,20 @@ export class ProfileEmployeeController extends Controller { 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) != + 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) != + 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}` diff --git a/src/controllers/ProfileSalaryTempController.ts b/src/controllers/ProfileSalaryTempController.ts index 5da8860e..8b49622a 100644 --- a/src/controllers/ProfileSalaryTempController.ts +++ b/src/controllers/ProfileSalaryTempController.ts @@ -120,7 +120,7 @@ export class ProfileSalaryTempController extends Controller { _data.child1 != undefined && _data.child1 != null ? _data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` + : `current_holders.orgChild1Id is ${_data.privilege == "PARENT" ? "not null" : "null"}` : "1=1", { child1: _data.child1, @@ -322,52 +322,42 @@ export class ProfileSalaryTempController extends Controller { .andWhere("current_holders.orgRootId = :rootId", { rootId: rootId, }) - .addSelect("CASE WHEN current_holders.posMasterNo IS NULL THEN 1 ELSE 0 END", "sort_order") - // .orderBy(`${sortBy}`, sort) + .addSelect("CASE WHEN current_holders.posMasterNo IS NULL THEN 1 ELSE 0 END", "sort_order"); + // .orderBy(`${sortBy}`, sort) if (sortBy) { - if(sortBy == "posLevel"){ - query = query.orderBy( - `posLevel.posLevelName`, - descending ? "DESC" : "ASC" - ); - }else if(sortBy == "posType"){ - query = query.orderBy( - `posType.posTypeName`, - descending ? "DESC" : "ASC" - ); - }else if(sortBy == "posExecutive"){ - query = query.orderBy( - `posExecutive.posExecutiveName`, - descending ? "DESC" : "ASC" - ); - }else if(sortBy == "posNo"){ - query = query.orderBy("orgChild4.orgChild4ShortName",descending ? "DESC" : "ASC") - .addOrderBy("orgChild3.orgChild3ShortName",descending ? "DESC" : "ASC") - .addOrderBy("orgChild2.orgChild2ShortName",descending ? "DESC" : "ASC") - .addOrderBy("orgChild1.orgChild1ShortName",descending ? "DESC" : "ASC") - .addOrderBy("orgRoot.orgRootShortName",descending ? "DESC" : "ASC") - .addOrderBy("current_holders.posMasterNo",descending ? "DESC" : "ASC") - }else{ - query = query.orderBy( - `profile.${sortBy}`, - descending ? "DESC" : "ASC" - ); + if (sortBy == "posLevel") { + query = query.orderBy(`posLevel.posLevelName`, descending ? "DESC" : "ASC"); + } else if (sortBy == "posType") { + query = query.orderBy(`posType.posTypeName`, descending ? "DESC" : "ASC"); + } else if (sortBy == "posExecutive") { + query = query.orderBy(`posExecutive.posExecutiveName`, descending ? "DESC" : "ASC"); + } else if (sortBy == "posNo") { + query = query + .orderBy("orgChild4.orgChild4ShortName", descending ? "DESC" : "ASC") + .addOrderBy("orgChild3.orgChild3ShortName", descending ? "DESC" : "ASC") + .addOrderBy("orgChild2.orgChild2ShortName", descending ? "DESC" : "ASC") + .addOrderBy("orgChild1.orgChild1ShortName", descending ? "DESC" : "ASC") + .addOrderBy("orgRoot.orgRootShortName", descending ? "DESC" : "ASC") + .addOrderBy("current_holders.posMasterNo", descending ? "DESC" : "ASC"); + } else { + query = query.orderBy(`profile.${sortBy}`, descending ? "DESC" : "ASC"); } - }else{ - query = query.orderBy("sort_order", "ASC") - .addOrderBy("orgRoot.orgRootOrder", "ASC") - .addOrderBy("orgChild1.orgChild1Order", "ASC") - .addOrderBy("orgChild2.orgChild2Order", "ASC") - .addOrderBy("orgChild3.orgChild3Order", "ASC") - .addOrderBy("orgChild4.orgChild4Order", "ASC") - .addOrderBy("current_holders.posMasterNo", "ASC") + } else { + query = query + .orderBy("sort_order", "ASC") + .addOrderBy("orgRoot.orgRootOrder", "ASC") + .addOrderBy("orgChild1.orgChild1Order", "ASC") + .addOrderBy("orgChild2.orgChild2Order", "ASC") + .addOrderBy("orgChild3.orgChild3Order", "ASC") + .addOrderBy("orgChild4.orgChild4Order", "ASC") + .addOrderBy("current_holders.posMasterNo", "ASC"); } const [record, total] = await query - .skip((page - 1) * pageSize) - .take(pageSize) - .getManyAndCount(); + .skip((page - 1) * pageSize) + .take(pageSize) + .getManyAndCount(); const data = await Promise.all( record.map((_data) => { @@ -541,7 +531,7 @@ export class ProfileSalaryTempController extends Controller { _data.child1 != undefined && _data.child1 != null ? _data.child1[0] != null ? `current_holders.orgChild1Id IN (:...child1)` - : `current_holders.orgChild1Id is null` + : `current_holders.orgChild1Id is ${_data.privilege == "PARENT" ? "not null" : "null"}` : "1=1", { child1: _data.child1, @@ -755,36 +745,24 @@ export class ProfileSalaryTempController extends Controller { .andWhere("current_holders.orgRootId = :rootId", { rootId: rootId, }) - .orderBy("current_holders.posMasterNo", "ASC") - // .orderBy(`${sortBy}`, sort) + .orderBy("current_holders.posMasterNo", "ASC"); + // .orderBy(`${sortBy}`, sort) - if (sortBy) { - if(sortBy == "posLevel"){ - query = query.orderBy( - `posLevel.posLevelName`, - descending ? "DESC" : "ASC" - ); - }else if(sortBy == "posType"){ - query = query.orderBy( - `posType.posTypeName`, - descending ? "DESC" : "ASC" - ); - }else if(sortBy == "posNo"){ - query = query.orderBy( - `orgRoot.orgRootShortName`, - descending ? "DESC" : "ASC" - ); - }else{ - query = query.orderBy( - `profileEmployee.${sortBy}`, - descending ? "DESC" : "ASC" - ); + if (sortBy) { + if (sortBy == "posLevel") { + query = query.orderBy(`posLevel.posLevelName`, descending ? "DESC" : "ASC"); + } else if (sortBy == "posType") { + query = query.orderBy(`posType.posTypeName`, descending ? "DESC" : "ASC"); + } else if (sortBy == "posNo") { + query = query.orderBy(`orgRoot.orgRootShortName`, descending ? "DESC" : "ASC"); + } else { + query = query.orderBy(`profileEmployee.${sortBy}`, descending ? "DESC" : "ASC"); } } const [record, total] = await query - .skip((page - 1) * pageSize) - .take(pageSize) - .getManyAndCount(); + .skip((page - 1) * pageSize) + .take(pageSize) + .getManyAndCount(); const data = await Promise.all( record.map((_data) => { @@ -1192,7 +1170,7 @@ export class ProfileSalaryTempController extends Controller { order: { order: "DESC" }, }); if (salary) { - dest_item = salary.order+1; + dest_item = salary.order + 1; } // const profile = await this.profileRepo.findOneBy({ id: body.profileId }); // if (!profile) { @@ -1210,7 +1188,7 @@ export class ProfileSalaryTempController extends Controller { order: { order: "DESC" }, }); if (salary) { - dest_item = salary.order+1; + dest_item = salary.order + 1; } // const profile = await this.profileEmployeeRepo.findOneBy({ id: body.profileId }); // if (!profile) { diff --git a/src/interfaces/permission.ts b/src/interfaces/permission.ts index 1819b647..b48478dc 100644 --- a/src/interfaces/permission.ts +++ b/src/interfaces/permission.ts @@ -97,7 +97,7 @@ class CheckAuth { } else if (privilege == "PARENT") { data = { root: [x.orgRootId], - child1: null, + child1: [null], child2: null, child3: null, child4: null,