fix query registry retire & sort registry of employee

This commit is contained in:
Warunee Tamkoo 2025-10-02 18:42:14 +07:00
parent b5823fdf28
commit 4994c829b5
2 changed files with 498 additions and 462 deletions

View file

@ -13,6 +13,7 @@ import {
Response,
Get,
Query,
Example,
} from "tsoa";
import { AppDataSource } from "../database/data-source";
import HttpSuccess from "../interfaces/http-success";
@ -79,6 +80,7 @@ import { ProfileChangeName } from "../entities/ProfileChangeName";
import { ProfileChildren } from "../entities/ProfileChildren";
import { ProfileDuty } from "../entities/ProfileDuty";
import { getTopDegrees } from "../services/PositionService";
import { ProfileLeaveService } from "../services/ProfileLeaveService";
@Route("api/v1/org/profile-employee")
@Tags("ProfileEmployee")
@Security("bearerAuth")
@ -131,6 +133,9 @@ export class ProfileEmployeeController extends Controller {
private profileAbilityRepo = AppDataSource.getRepository(ProfileAbility);
private profileAssistanceRepository = AppDataSource.getRepository(ProfileAssistance);
// Services
private profileLeaveService = new ProfileLeaveService();
/**
* report
*
@ -2629,6 +2634,29 @@ export class ProfileEmployeeController extends Controller {
*
*/
@Get("profileLeave")
@Example({
status: 200,
message: "สำเร็จ",
result: {
data: [
{
page: 1,
pageSize: 12,
posLevel: "บ 1",
posType: "บริการพื้นฐาน",
isProbation: false,
isRetire: true,
node: 0,
nodeId: "8349b6b6-d005-4eb7-9960-ceb5b96e1962",
isAll: true,
sortBy: "profile.dateAppoint",
sort: "DESC",
retireType: "RETIRE_DECEASED",
},
],
total: 1,
},
})
async listProfileLeave(
@Request() request: RequestWithUser,
@Query("page") page: number = 1,
@ -2638,443 +2666,31 @@ export class ProfileEmployeeController extends Controller {
@Query() searchKeyword: string = "",
@Query() posType?: string,
@Query() posLevel?: string,
@Query() yearLeave?: number,
@Query() isProbation?: boolean,
// @Query() isRetire?: boolean,
@Query() type?: string,
@Query() node?: number,
@Query() nodeId?: string,
@Query() isAll?: boolean,
@Query() retireType?: string,
@Query() sortBy: string = "current_holders.posMasterNo",
@Query() sort: "ASC" | "DESC" = "ASC",
@Query() sortBy: string = "profileEmployee.dateLeave",
@Query() sort: "ASC" | "DESC" = "DESC",
) {
let _data = await new permission().PermissionOrgList(request, "SYS_REGISTRY_EMP");
let queryLike =
"CONCAT(profileEmployee.prefix, profileEmployee.firstName, ' ', profileEmployee.lastName) LIKE :keyword";
if (searchField == "citizenId") {
queryLike = "profileEmployee.citizenId LIKE :keyword";
} else if (searchField == "position") {
queryLike = "profileEmployee.position LIKE :keyword";
}
// else if (searchField == "posNo") {
// queryLike = `
// CASE
// WHEN current_holders.orgChild4Id IS NOT NULL THEN CONCAT(orgChild4.orgChild4ShortName, current_holders.posMasterNo)
// WHEN current_holders.orgChild3Id IS NOT NULL THEN CONCAT(orgChild3.orgChild3ShortName, current_holders.posMasterNo)
// WHEN current_holders.orgChild2Id IS NOT NULL THEN CONCAT(orgChild2.orgChild2ShortName, current_holders.posMasterNo)
// WHEN current_holders.orgChild1Id IS NOT NULL THEN CONCAT(orgChild1.orgChild1ShortName, current_holders.posMasterNo)
// ELSE CONCAT(orgRoot.orgRootShortName, current_holders.posMasterNo)
// END LIKE :keyword
// `;
// }
else if (searchField == "posNo") {
queryLike = `
CONCAT(profileSalary.posNoAbb, profileSalary.posNo) LIKE :keyword
OR CONCAT(profileSalary.posNoAbb, " ", profileSalary.posNo) LIKE :keyword
OR profileSalary.posNo LIKE :keyword
`;
}
let nodeCondition = "1=1";
let nodeAll = "";
let orgRoot = null;
let orgChild1 = null;
let orgChild2 = null;
let orgChild3 = null;
let orgChild4 = null;
const { data, total } = await this.profileLeaveService.getLeaveEmployees(request, {
page,
pageSize,
searchField,
searchKeyword,
posType,
posLevel,
isProbation,
node,
nodeId,
isAll,
retireType,
sortBy,
sort,
});
let pmsCondition = "1=1";
let orgRootPms = null;
let orgChild1Pms = null;
let orgChild2Pms = null;
let orgChild3Pms = null;
let orgChild4Pms = null;
if (node === 0 && nodeId) {
orgRoot = await this.orgRootRepository.findOne({ where: { id: nodeId } });
if (orgRoot) {
nodeCondition = "profileSalary.orgRoot = :orgRoot";
}
if (isAll == false) nodeAll = " AND profileSalary.orgChild1 IS NULL";
} else if (node === 1 && nodeId) {
orgChild1 = await this.child1Repository.findOne({ where: { id: nodeId } });
if (orgChild1) {
nodeCondition = "profileSalary.orgChild1 = :orgChild1";
}
if (isAll == false) nodeAll = " AND profileSalary.orgChild2 IS NULL";
} else if (node === 2 && nodeId) {
orgChild2 = await this.child2Repository.findOne({ where: { id: nodeId } });
if (orgChild2) {
nodeCondition = "profileSalary.orgChild2 = :orgChild2";
}
if (isAll == false) nodeAll = " AND profileSalary.orgChild3 IS NULL";
} else if (node === 3 && nodeId) {
orgChild3 = await this.child3Repository.findOne({ where: { id: nodeId } });
if (orgChild3) {
nodeCondition = "profileSalary.orgChild3 = :orgChild3";
}
if (isAll == false) nodeAll = " AND profileSalary.orgChild4 IS NULL";
} else if (node === 4 && nodeId) {
orgChild4 = await this.child4Repository.findOne({ where: { id: nodeId } });
if (orgChild4) {
nodeCondition = "profileSalary.orgChild4 = :orgChild4";
}
}
nodeCondition = nodeCondition + nodeAll;
if (_data.root) {
orgRootPms = await this.orgRootRepository.findOne({ where: { id: _data.root } });
if (orgRootPms) {
pmsCondition = "profileSalary.orgRoot = :orgRootPms";
}
if (isAll == false) nodeAll = " AND profileSalary.orgChild1 IS NULL";
} else if (_data.child1) {
orgChild1Pms = await this.child1Repository.findOne({ where: { id: _data.child1 } });
if (orgChild1Pms) {
pmsCondition = "profileSalary.orgChild1 = :orgChild1Pms";
}
if (isAll == false) nodeAll = " AND profileSalary.orgChild2 IS NULL";
} else if (_data.child2) {
orgChild2Pms = await this.child2Repository.findOne({ where: { id: _data.child2 } });
if (orgChild2Pms) {
pmsCondition = "profileSalary.orgChild2 = :orgChild2Pms";
}
if (isAll == false) nodeAll = " AND profileSalary.orgChild3 IS NULL";
} else if (_data.child3) {
orgChild3Pms = await this.child3Repository.findOne({ where: { id: _data.child3 } });
if (orgChild3Pms) {
pmsCondition = "profileSalary.orgChild3 = :orgChild3Pms";
}
if (isAll == false) nodeAll = " AND profileSalary.orgChild4 IS NULL";
} else if (_data.child4) {
orgChild4Pms = await this.child4Repository.findOne({ where: { id: _data.child4 } });
if (orgChild4Pms) {
pmsCondition = "profileSalary.orgChild4 = :orgChild4Pms";
}
}
pmsCondition = pmsCondition + nodeAll;
// const findRevision = await this.orgRevisionRepo.findOne({
// where: { orgRevisionIsCurrent: true },
// });
// if (!findRevision) {
// throw new HttpError(HttpStatus.NOT_FOUND, "not found. OrgRevision");
// }
const [record, total] = await this.profileRepo
.createQueryBuilder("profileEmployee")
.leftJoinAndSelect("profileEmployee.posLevel", "posLevel")
.leftJoinAndSelect("profileEmployee.posType", "posType")
// .leftJoinAndSelect("profileEmployee.current_holders", "current_holders")
.leftJoinAndSelect("profileEmployee.profileEmployeeEmployment", "profileEmployeeEmployment")
// .leftJoinAndSelect("current_holders.positions", "positions")
.leftJoinAndSelect("profileEmployee.profileSalary", "profileSalary")
// .leftJoinAndSelect("current_holders.orgRevision", "orgRevision")
// .leftJoinAndSelect("current_holders.orgRoot", "orgRoot")
// .leftJoinAndSelect("current_holders.orgChild1", "orgChild1")
// .leftJoinAndSelect("current_holders.orgChild2", "orgChild2")
// .leftJoinAndSelect("current_holders.orgChild3", "orgChild3")
// .leftJoinAndSelect("current_holders.orgChild4", "orgChild4")
// .where(node && nodeId ? "current_holders.orgRevisionId = :orgRevisionId" : "1=1", {
// orgRevisionId: node && nodeId ? findRevision.id : undefined,
// })
.where(
new Brackets((qb) => {
qb.where("profileEmployee.isLeave = :isLeave", { isLeave: true }).orWhere(
"profileEmployee.isRetirement = :isRetirement",
{ isRetirement: true },
);
}),
)
// .andWhere("profileEmployee.leaveCommandId Is NOT NULL")
.andWhere(
"profileSalary.order = (SELECT MAX(ps.order) FROM profileSalary ps WHERE ps.profileEmployeeId = profileEmployee.id and ps.positionName != 'เกษียณอายุราชการ')",
)
// .andWhere(
// _data.root != undefined && _data.root != null
// ? _data.root[0] != null
// ? `current_holders.orgRootId IN (:...root)`
// : `current_holders.orgRootId is null`
// : "1=1",
// {
// root: _data.root,
// },
// )
// .andWhere(
// _data.child1 != undefined && _data.child1 != null
// ? _data.child1[0] != null
// ? `current_holders.orgChild1Id IN (:...child1)`
// : `current_holders.orgChild1Id is null`
// : "1=1",
// {
// child1: _data.child1,
// },
// )
// .andWhere(
// _data.child2 != undefined && _data.child2 != null
// ? _data.child2[0] != null
// ? `current_holders.orgChild2Id IN (:...child2)`
// : `current_holders.orgChild2Id is null`
// : "1=1",
// {
// child2: _data.child2,
// },
// )
// .andWhere(
// _data.child3 != undefined && _data.child3 != null
// ? _data.child3[0] != null
// ? `current_holders.orgChild3Id IN (:...child3)`
// : `current_holders.orgChild3Id is null`
// : "1=1",
// {
// child3: _data.child3,
// },
// )
// .andWhere(
// _data.child4 != undefined && _data.child4 != null
// ? _data.child4[0] != null
// ? `current_holders.orgChild4Id IN (:...child4)`
// : `current_holders.orgChild4Id is null`
// : "1=1",
// {
// child4: _data.child4,
// },
// )
.andWhere(
posType != undefined && posType != null && posType != ""
? "posType.posTypeName LIKE :keyword1"
: "1=1",
{
keyword1: `${posType}`,
},
)
.andWhere(
posLevel != undefined && posLevel != null && posLevel != ""
? `CONCAT(posType.posTypeShortName,' ',posLevel.posLevelName) LIKE :keyword2`
: "1=1",
{
keyword2: `${posLevel}`,
},
)
.andWhere(
isProbation != undefined && isProbation != null
? `profileEmployee.isProbation = ${isProbation}`
: "1=1",
)
.andWhere(
retireType != undefined && retireType != null
? `profileEmployee.leaveType = :retireType`
: "1=1",
{ retireType: retireType },
)
.andWhere("profileEmployee.employeeClass LIKE :type", {
type: "PERM",
})
.andWhere(
searchKeyword != undefined && searchKeyword != null && searchKeyword != ""
? queryLike
: "1=1",
{
keyword: `%${searchKeyword}%`,
},
)
.andWhere(pmsCondition, {
orgRootPms: orgRootPms ? orgRootPms.orgRootName : "",
orgChild1Pms: orgChild1Pms ? orgChild1Pms.orgChild1Name : "",
orgChild2Pms: orgChild2Pms ? orgChild2Pms.orgChild2Name : "",
orgChild3Pms: orgChild3Pms ? orgChild3Pms.orgChild3Name : "",
orgChild4Pms: orgChild4Pms ? orgChild4Pms.orgChild4Name : "",
})
.andWhere(nodeCondition, {
orgRoot: orgRoot ? orgRoot.orgRootName : "",
orgChild1: orgChild1 ? orgChild1.orgChild1Name : "",
orgChild2: orgChild2 ? orgChild2.orgChild2Name : "",
orgChild3: orgChild3 ? orgChild3.orgChild3Name : "",
orgChild4: orgChild4 ? orgChild4.orgChild4Name : "",
})
// .andWhere(`current_holders.orgRevisionId LIKE :orgRevisionId`, {
// orgRevisionId: findRevision.id,
// })
// .orderBy("current_holders.posMasterNo", "ASC")
// .orderBy(`${sortBy}`, sort)
.skip((page - 1) * pageSize)
.take(pageSize)
.getManyAndCount();
const data = await Promise.all(
record.map((_data) => {
// const shortName =
// _data.current_holders.length == 0
// ? null
// : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
// _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 !=
// null
// ? `${_data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4.orgChild4ShortName}${_data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
// : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
// _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)
// ?.orgChild3 != null
// ? `${_data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3.orgChild3ShortName}${_data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
// : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
// _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)
// ?.orgChild2 != null
// ? `${_data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2.orgChild2ShortName}${_data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
// : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
// _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)
// ?.orgChild1 != null
// ? `${_data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1.orgChild1ShortName}${_data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
// : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) !=
// null &&
// _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)
// ?.orgRoot != null
// ? `${_data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot.orgRootShortName}${_data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
// : null;
const dateEmployment =
_data.profileEmployeeEmployment.length == 0
? null
: _data.profileEmployeeEmployment.reduce((latest, current) => {
return latest.date > current.date ? latest : current;
}).date;
// const root =
// _data.current_holders.length == 0 ||
// (_data.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
// _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null)
// ? null
// : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot;
// const child1 =
// _data.current_holders == null ||
// _data.current_holders.length == 0 ||
// _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null
// ? null
// : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1;
// const child2 =
// _data.current_holders == null ||
// _data.current_holders.length == 0 ||
// _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null
// ? null
// : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2;
// const child3 =
// _data.current_holders == null ||
// _data.current_holders.length == 0 ||
// _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null
// ? null
// : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3;
// const child4 =
// _data.current_holders == null ||
// _data.current_holders.length == 0 ||
// _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null
// ? null
// : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4;
// let _child1 = child1?.orgChild1Name;
// let _child2 = child2?.orgChild2Name;
// let _child3 = child3?.orgChild3Name;
// let _child4 = child4?.orgChild4Name;
return {
id: _data.id,
avatar: _data.avatar,
avatarName: _data.avatarName,
prefix: _data.prefix,
rank: _data.rank,
firstName: _data.firstName,
lastName: _data.lastName,
citizenId: _data.citizenId,
posLevel: _data.posLevel == null ? null : _data.posLevel.posLevelName,
posType: _data.posType == null ? null : _data.posType.posTypeName,
posTypeShortName: _data.posType == null ? null : _data.posType.posTypeShortName,
posLevelId: _data.posLevel == null ? null : _data.posLevel.id,
posTypeId: _data.posType == null ? null : _data.posType.id,
positionId: _data.positionIdTemp,
posmasterId: _data.posmasterIdTemp,
position: _data.position,
posNo:
_data.profileSalary[0].posNoAbb && _data.profileSalary[0].posNo
? `${_data.profileSalary[0].posNoAbb} ${_data.profileSalary[0].posNo}`
: _data.profileSalary[0].posNo || "",
employeeClass: _data.employeeClass == null ? null : _data.employeeClass,
govAge: Extension.CalculateGovAge(_data.dateAppoint, 0, 0),
age: Extension.CalculateAgeStrV2(_data.birthDate, 0, 0, "GET"),
dateEmployment: dateEmployment,
dateAppoint: _data.dateAppoint,
dateStart: _data.dateStart,
createdAt: _data.createdAt,
dateRetireLaw: _data.dateRetireLaw,
draftOrganizationOrganization:
_data.nodeTemp == "0"
? _data.rootTemp
: _data.nodeTemp == "1"
? _data.child1Temp
: _data.nodeTemp == "2"
? _data.child2Temp
: _data.nodeTemp == "3"
? _data.child3Temp
: _data.nodeTemp == "4"
? _data.child4Temp
: null,
draftPositionEmployee: _data.positionTemp,
draftOrgEmployeeStatus: _data.statusTemp,
node: _data.nodeTemp,
nodeId: _data.nodeIdTemp,
nodeName:
_data.nodeTemp == "0"
? _data.rootTemp
: _data.nodeTemp == "1"
? _data.child1Temp
: _data.nodeTemp == "2"
? _data.child2Temp
: _data.nodeTemp == "3"
? _data.child3Temp
: _data.nodeTemp == "4"
? _data.child4Temp
: null,
nodeShortName:
_data.nodeTemp == "0"
? _data.rootShortNameTemp
: _data.nodeTemp == "1"
? _data.child1ShortNameTemp
: _data.nodeTemp == "2"
? _data.child1ShortNameTemp
: _data.nodeTemp == "3"
? _data.child3ShortNameTemp
: _data.nodeTemp == "4"
? _data.child4ShortNameTemp
: null,
root: _data.rootTemp ? _data.rootTemp : null,
rootId: _data.rootIdTemp ? _data.rootIdTemp : null,
rootShortName: _data.rootShortNameTemp ? _data.rootShortNameTemp : null,
child1: _data.child1Temp ? _data.child1Temp : null,
child1Id: _data.child1IdTemp ? _data.child1IdTemp : null,
child1ShortName: _data.child1ShortNameTemp ? _data.child1ShortNameTemp : null,
child2: _data.child2Temp ? _data.child2Temp : null,
child2Id: _data.child2IdTemp ? _data.child2IdTemp : null,
child2ShortName: _data.child2ShortNameTemp ? _data.child2ShortNameTemp : null,
child3: _data.child3Temp ? _data.child3Temp : null,
child3Id: _data.child3IdTemp ? _data.child3IdTemp : null,
child3ShortName: _data.child3ShortNameTemp ? _data.child3ShortNameTemp : null,
child4: _data.child4Temp ? _data.child4Temp : null,
child4Id: _data.child4IdTemp ? _data.child4IdTemp : null,
child4ShortName: _data.child4ShortNameTemp ? _data.child4ShortNameTemp : null,
org:
(_data.profileSalary[0].orgChild4 == null
? ""
: _data.profileSalary[0].orgChild4 + "\n") +
(_data.profileSalary[0].orgChild3 == null
? ""
: _data.profileSalary[0].orgChild3 + "\n") +
(_data.profileSalary[0].orgChild2 == null
? ""
: _data.profileSalary[0].orgChild2 + "\n") +
(_data.profileSalary[0].orgChild1 == null
? ""
: _data.profileSalary[0].orgChild1 + "\n") +
(_data.profileSalary[0].orgRoot == null ? "" : _data.profileSalary[0].orgRoot),
};
}),
);
return new HttpSuccess({ data: data, total });
return new HttpSuccess({ data, total });
}
/**
@ -3137,15 +2753,13 @@ export class ProfileEmployeeController extends Controller {
@Query() searchKeyword: string = "",
@Query() posType?: string,
@Query() posLevel?: string,
@Query() yearLeave?: number,
@Query() isProbation?: boolean,
@Query() isRetire?: boolean,
@Query() type?: string,
@Query() node?: number,
@Query() nodeId?: string,
@Query() isAll?: boolean,
@Query() retireType?: string,
@Query() sortBy: string = "current_holders.posMasterNo",
@Query() sortBy?: string,
@Query() sort: "ASC" | "DESC" = "ASC",
) {
let _data = await new permission().PermissionOrgList(request, "SYS_REGISTRY_EMP");
@ -3300,13 +2914,8 @@ export class ProfileEmployeeController extends Controller {
.andWhere(nodeCondition, {
nodeId: nodeId,
})
// .andWhere(`current_holders.orgRevisionId LIKE :orgRevisionId`, {
// orgRevisionId: findRevision.id,
// })
// .orderBy("current_holders.posMasterNo", "ASC")
// .orderBy(`${sortBy}`, sort)
.addSelect("CASE WHEN current_holders.posMasterNo IS NULL THEN 1 ELSE 0 END", "sort_order")
.orderBy("sort_order", "ASC")
.orderBy(`${sortBy ? sortBy : "sort_order"}`, `${sort}`)
.addOrderBy("orgRoot.orgRootOrder", sort)
.addOrderBy("orgChild1.orgChild1Order", sort)
.addOrderBy("orgChild2.orgChild2Order", sort)
@ -5123,34 +4732,28 @@ export class ProfileEmployeeController extends Controller {
},
);
}),
)
);
if (body.sortBy) {
if(body.sortBy === "posType"){
query = query.orderBy(
`posType.posTypeName`,
body.descending ? "DESC" : "ASC"
);
}else if(body.sortBy === "posLevel"){
if (body.sortBy === "posType") {
query = query.orderBy(`posType.posTypeName`, body.descending ? "DESC" : "ASC");
} else if (body.sortBy === "posLevel") {
query = query
.orderBy(`posType.posTypeShortName`,body.descending ? "DESC" : "ASC")
.addOrderBy(`posLevel.posLevelName`,body.descending ? "DESC" : "ASC");
}else if(body.sortBy === "orgShortName" || body.sortBy === "posMasterNo"){
.orderBy(`posType.posTypeShortName`, body.descending ? "DESC" : "ASC")
.addOrderBy(`posLevel.posLevelName`, body.descending ? "DESC" : "ASC");
} else if (body.sortBy === "orgShortName" || body.sortBy === "posMasterNo") {
query = query
.orderBy(`orgRoot.orgRootShortName`,body.descending ? "DESC" : "ASC")
.addOrderBy(`orgChild1.orgChild1ShortName`,body.descending ? "DESC" : "ASC")
.addOrderBy(`orgChild2.orgChild2ShortName`,body.descending ? "DESC" : "ASC")
.addOrderBy(`orgChild3.orgChild3ShortName`,body.descending ? "DESC" : "ASC")
.addOrderBy(`orgChild4.orgChild4ShortName`,body.descending ? "DESC" : "ASC")
.addOrderBy(`employeePosMaster.posMasterNo`,body.descending ? "DESC" : "ASC")
}else{
query = query.orderBy(
`current_holder.${body.sortBy}`,
body.descending ? "DESC" : "ASC"
);
.orderBy(`orgRoot.orgRootShortName`, body.descending ? "DESC" : "ASC")
.addOrderBy(`orgChild1.orgChild1ShortName`, body.descending ? "DESC" : "ASC")
.addOrderBy(`orgChild2.orgChild2ShortName`, body.descending ? "DESC" : "ASC")
.addOrderBy(`orgChild3.orgChild3ShortName`, body.descending ? "DESC" : "ASC")
.addOrderBy(`orgChild4.orgChild4ShortName`, body.descending ? "DESC" : "ASC")
.addOrderBy(`employeePosMaster.posMasterNo`, body.descending ? "DESC" : "ASC");
} else {
query = query.orderBy(`current_holder.${body.sortBy}`, body.descending ? "DESC" : "ASC");
}
}else{
query = query.orderBy("current_holder.citizenId", "ASC")
} else {
query = query.orderBy("current_holder.citizenId", "ASC");
}
const [findPosMaster, total] = await query

View file

@ -0,0 +1,433 @@
import { AppDataSource } from "../database/data-source";
import { ProfileEmployee } from "../entities/ProfileEmployee";
import { OrgRoot } from "../entities/OrgRoot";
import { OrgChild1 } from "../entities/OrgChild1";
import { OrgChild2 } from "../entities/OrgChild2";
import { OrgChild3 } from "../entities/OrgChild3";
import { OrgChild4 } from "../entities/OrgChild4";
import { Brackets, Repository } from "typeorm";
import Extension from "../interfaces/extension";
import permission from "../interfaces/permission";
import { RequestWithUser } from "../middlewares/user";
export interface LeaveEmployeeFilter {
page: number;
pageSize: number;
searchField?: "firstName" | "lastName" | "fullName" | "citizenId" | "position" | "posNo";
searchKeyword?: string;
posType?: string;
posLevel?: string;
isProbation?: boolean;
node?: number;
nodeId?: string;
isAll?: boolean;
retireType?: string;
sortBy?: string;
sort: "ASC" | "DESC";
}
export interface OrganizationCondition {
condition: string;
params: Record<string, any>;
}
export class ProfileLeaveService {
private profileRepo: Repository<ProfileEmployee>;
private orgRootRepository: Repository<OrgRoot>;
private child1Repository: Repository<OrgChild1>;
private child2Repository: Repository<OrgChild2>;
private child3Repository: Repository<OrgChild3>;
private child4Repository: Repository<OrgChild4>;
constructor() {
this.profileRepo = AppDataSource.getRepository(ProfileEmployee);
this.orgRootRepository = AppDataSource.getRepository(OrgRoot);
this.child1Repository = AppDataSource.getRepository(OrgChild1);
this.child2Repository = AppDataSource.getRepository(OrgChild2);
this.child3Repository = AppDataSource.getRepository(OrgChild3);
this.child4Repository = AppDataSource.getRepository(OrgChild4);
}
/**
* query
*/
buildSearchQuery(searchField?: string): string {
switch (searchField) {
case "citizenId":
return "profileEmployee.citizenId LIKE :keyword";
case "position":
return "profileEmployee.position LIKE :keyword";
case "posNo":
return `
(profileSalary.posNoAbb IS NOT NULL AND CONCAT(profileSalary.posNoAbb, profileSalary.posNo) LIKE :keyword)
OR (profileSalary.posNoAbb IS NOT NULL AND CONCAT(profileSalary.posNoAbb, " ", profileSalary.posNo) LIKE :keyword)
OR (profileSalary.posNo IS NOT NULL AND profileSalary.posNo LIKE :keyword)
`;
default:
return "CONCAT(profileEmployee.prefix, profileEmployee.firstName, ' ', profileEmployee.lastName) LIKE :keyword";
}
}
/**
* node nodeId
*/
async buildNodeCondition(
node?: number,
nodeId?: string,
isAll?: boolean,
): Promise<OrganizationCondition> {
let condition = "1=1";
let nodeAll = "";
const params: Record<string, any> = {};
if (!node || !nodeId) {
return { condition, params };
}
// สร้าง nodeAll condition - เพิ่มการตรวจสอบ IS NULL
if (isAll === false && node < 4) {
const nextLevels = ["orgChild1", "orgChild2", "orgChild3", "orgChild4"];
nodeAll = ` AND (profileSalary.${nextLevels[node]} IS NULL OR profileSalary.id IS NULL)`;
}
try {
switch (node) {
case 0: {
const orgRoot = await this.orgRootRepository.findOne({ where: { id: nodeId } });
if (orgRoot) {
condition = "(profileSalary.orgRoot = :orgRoot OR profileSalary.id IS NULL)";
params.orgRoot = orgRoot.orgRootName;
}
break;
}
case 1: {
const orgChild1 = await this.child1Repository.findOne({ where: { id: nodeId } });
if (orgChild1) {
condition = "(profileSalary.orgChild1 = :orgChild1 OR profileSalary.id IS NULL)";
params.orgChild1 = orgChild1.orgChild1Name;
}
break;
}
case 2: {
const orgChild2 = await this.child2Repository.findOne({ where: { id: nodeId } });
if (orgChild2) {
condition = "(profileSalary.orgChild2 = :orgChild2 OR profileSalary.id IS NULL)";
params.orgChild2 = orgChild2.orgChild2Name;
}
break;
}
case 3: {
const orgChild3 = await this.child3Repository.findOne({ where: { id: nodeId } });
if (orgChild3) {
condition = "(profileSalary.orgChild3 = :orgChild3 OR profileSalary.id IS NULL)";
params.orgChild3 = orgChild3.orgChild3Name;
}
break;
}
case 4: {
const orgChild4 = await this.child4Repository.findOne({ where: { id: nodeId } });
if (orgChild4) {
condition = "(profileSalary.orgChild4 = :orgChild4 OR profileSalary.id IS NULL)";
params.orgChild4 = orgChild4.orgChild4Name;
}
break;
}
}
} catch (error) {
console.error("Error building node condition:", error);
}
return { condition: condition + nodeAll, params };
}
/**
* permission
*/
async buildPermissionCondition(
request: RequestWithUser,
isAll?: boolean,
): Promise<OrganizationCondition> {
const _data = await new permission().PermissionOrgList(request, "SYS_REGISTRY_EMP");
let condition = "1=1";
let nodeAll = "";
const params: Record<string, any> = {};
try {
if (_data.root) {
const orgRootPms = await this.orgRootRepository.findOne({ where: { id: _data.root } });
if (orgRootPms) {
condition = "(profileSalary.orgRoot = :orgRootPms OR profileSalary.id IS NULL)";
params.orgRootPms = orgRootPms.orgRootName;
}
if (isAll === false)
nodeAll = " AND (profileSalary.orgChild1 IS NULL OR profileSalary.id IS NULL)";
} else if (_data.child1) {
const orgChild1Pms = await this.child1Repository.findOne({ where: { id: _data.child1 } });
if (orgChild1Pms) {
condition = "(profileSalary.orgChild1 = :orgChild1Pms OR profileSalary.id IS NULL)";
params.orgChild1Pms = orgChild1Pms.orgChild1Name;
}
if (isAll === false)
nodeAll = " AND (profileSalary.orgChild2 IS NULL OR profileSalary.id IS NULL)";
} else if (_data.child2) {
const orgChild2Pms = await this.child2Repository.findOne({ where: { id: _data.child2 } });
if (orgChild2Pms) {
condition = "(profileSalary.orgChild2 = :orgChild2Pms OR profileSalary.id IS NULL)";
params.orgChild2Pms = orgChild2Pms.orgChild2Name;
}
if (isAll === false)
nodeAll = " AND (profileSalary.orgChild3 IS NULL OR profileSalary.id IS NULL)";
} else if (_data.child3) {
const orgChild3Pms = await this.child3Repository.findOne({ where: { id: _data.child3 } });
if (orgChild3Pms) {
condition = "(profileSalary.orgChild3 = :orgChild3Pms OR profileSalary.id IS NULL)";
params.orgChild3Pms = orgChild3Pms.orgChild3Name;
}
if (isAll === false)
nodeAll = " AND (profileSalary.orgChild4 IS NULL OR profileSalary.id IS NULL)";
} else if (_data.child4) {
const orgChild4Pms = await this.child4Repository.findOne({ where: { id: _data.child4 } });
if (orgChild4Pms) {
condition = "(profileSalary.orgChild4 = :orgChild4Pms OR profileSalary.id IS NULL)";
params.orgChild4Pms = orgChild4Pms.orgChild4Name;
}
}
} catch (error) {
console.error("Error building permission condition:", error);
}
return { condition: condition + nodeAll, params };
}
/**
* format
*/
transformEmployeeData(employee: ProfileEmployee): any {
const dateEmployment =
employee.profileEmployeeEmployment?.length === 0 || !employee.profileEmployeeEmployment
? null
: employee.profileEmployeeEmployment.reduce((latest, current) => {
return latest.date > current.date ? latest : current;
}).date;
// ตรวจสอบว่า profileSalary มีข้อมูลหรือไม่
const salary =
employee.profileSalary && employee.profileSalary.length > 0
? employee.profileSalary[0]
: null;
const posNo =
salary?.posNoAbb && salary?.posNo
? `${salary.posNoAbb} ${salary.posNo}`
: salary?.posNo || "";
// สร้าง organization hierarchy - ใช้ข้อมูลจาก temp fields ถ้า salary ไม่มี
const org = salary
? [salary.orgChild4, salary.orgChild3, salary.orgChild2, salary.orgChild1, salary.orgRoot]
.filter(Boolean)
.join("\n")
: [
employee.child4Temp,
employee.child3Temp,
employee.child2Temp,
employee.child1Temp,
employee.rootTemp,
]
.filter(Boolean)
.join("\n");
// สร้าง node information
const getNodeInfo = (nodeTemp: string) => {
switch (nodeTemp) {
case "0":
return {
name: employee.rootTemp,
shortName: employee.rootShortNameTemp,
};
case "1":
return {
name: employee.child1Temp,
shortName: employee.child1ShortNameTemp,
};
case "2":
return {
name: employee.child2Temp,
shortName: employee.child2ShortNameTemp,
};
case "3":
return {
name: employee.child3Temp,
shortName: employee.child3ShortNameTemp,
};
case "4":
return {
name: employee.child4Temp,
shortName: employee.child4ShortNameTemp,
};
default:
return { name: null, shortName: null };
}
};
const nodeInfo = getNodeInfo(employee.nodeTemp || "0");
return {
id: employee.id,
avatar: employee.avatar,
avatarName: employee.avatarName,
prefix: employee.prefix,
rank: employee.rank,
firstName: employee.firstName,
lastName: employee.lastName,
citizenId: employee.citizenId,
posLevel: employee.posLevel?.posLevelName || null,
posType: employee.posType?.posTypeName || null,
posTypeShortName: employee.posType?.posTypeShortName || null,
posLevelId: employee.posLevel?.id || null,
posTypeId: employee.posType?.id || null,
positionId: employee.positionIdTemp,
posmasterId: employee.posmasterIdTemp,
position: employee.position,
posNo,
employeeClass: employee.employeeClass,
govAge: Extension.CalculateGovAge(employee.dateAppoint, 0, 0),
age: Extension.CalculateAgeStrV2(employee.birthDate, 0, 0, "GET"),
dateEmployment,
dateAppoint: employee.dateAppoint,
dateStart: employee.dateStart,
createdAt: employee.createdAt,
dateRetireLaw: employee.dateRetireLaw,
draftOrganizationOrganization: nodeInfo.name,
draftPositionEmployee: employee.positionTemp,
draftOrgEmployeeStatus: employee.statusTemp,
node: employee.nodeTemp,
nodeId: employee.nodeIdTemp,
nodeName: nodeInfo.name,
nodeShortName: nodeInfo.shortName,
root: employee.rootTemp || null,
rootId: employee.rootIdTemp || null,
rootShortName: employee.rootShortNameTemp || null,
child1: employee.child1Temp || null,
child1Id: employee.child1IdTemp || null,
child1ShortName: employee.child1ShortNameTemp || null,
child2: employee.child2Temp || null,
child2Id: employee.child2IdTemp || null,
child2ShortName: employee.child2ShortNameTemp || null,
child3: employee.child3Temp || null,
child3Id: employee.child3IdTemp || null,
child3ShortName: employee.child3ShortNameTemp || null,
child4: employee.child4Temp || null,
child4Id: employee.child4IdTemp || null,
child4ShortName: employee.child4ShortNameTemp || null,
org,
};
}
/**
*
*/
async getLeaveEmployees(
request: RequestWithUser,
filter: LeaveEmployeeFilter,
): Promise<{ data: any[]; total: number }> {
const {
page,
pageSize,
searchField,
searchKeyword = "",
posType,
posLevel,
isProbation,
node,
nodeId,
isAll,
retireType,
sortBy = "profileEmployee.dateLeave",
sort,
} = filter;
// สร้าง query conditions แบบ parallel
const [nodeCondition, permissionCondition] = await Promise.all([
this.buildNodeCondition(node, nodeId, isAll),
this.buildPermissionCondition(request, isAll),
]);
const searchQuery = this.buildSearchQuery(searchField);
// สร้าง main query - เปลี่ยนจาก leftJoinAndSelect เป็น leftJoin สำหรับ profileSalary
const queryBuilder = this.profileRepo
.createQueryBuilder("profileEmployee")
.leftJoinAndSelect("profileEmployee.posLevel", "posLevel")
.leftJoinAndSelect("profileEmployee.posType", "posType")
.leftJoinAndSelect("profileEmployee.profileEmployeeEmployment", "profileEmployeeEmployment")
.leftJoin(
"profileEmployee.profileSalary",
"profileSalary",
"profileSalary.order = (SELECT MAX(ps.order) FROM profileSalary ps WHERE ps.profileEmployeeId = profileEmployee.id and ps.positionName != 'เกษียณอายุราชการ')",
)
.addSelect([
"profileSalary.id",
"profileSalary.order",
"profileSalary.posNo",
"profileSalary.posNoAbb",
"profileSalary.orgRoot",
"profileSalary.orgChild1",
"profileSalary.orgChild2",
"profileSalary.orgChild3",
"profileSalary.orgChild4",
])
.where(
new Brackets((qb) => {
qb.where("profileEmployee.isLeave = :isLeave", { isLeave: true }).orWhere(
"profileEmployee.isRetirement = :isRetirement",
{ isRetirement: true },
);
}),
)
.andWhere("profileEmployee.employeeClass LIKE :type", { type: "PERM" });
// เพิ่มเงื่อนไขการค้นหา
if (posType) {
queryBuilder.andWhere("posType.posTypeName LIKE :keyword1", { keyword1: `${posType}` });
}
if (posLevel) {
queryBuilder.andWhere(
"CONCAT(posType.posTypeShortName,' ',posLevel.posLevelName) LIKE :keyword2",
{ keyword2: `${posLevel}` },
);
}
if (isProbation !== undefined && isProbation !== null) {
queryBuilder.andWhere(`profileEmployee.isProbation = ${isProbation}`);
}
if (retireType) {
queryBuilder.andWhere("profileEmployee.leaveType = :retireType", { retireType });
}
if (searchKeyword) {
queryBuilder.andWhere(searchQuery, { keyword: `%${searchKeyword}%` });
}
// เพิ่ม permission และ node conditions
queryBuilder
.andWhere(permissionCondition.condition, permissionCondition.params)
.andWhere(nodeCondition.condition, nodeCondition.params);
// เพิ่ม sorting และ pagination
queryBuilder
.orderBy(sortBy, sort)
.skip((page - 1) * pageSize)
.take(pageSize);
const [records, total] = await queryBuilder.getManyAndCount();
// แปลงข้อมูลแบบ parallel
const data = await Promise.all(
records.map((record) => Promise.resolve(this.transformEmployeeData(record))),
);
return { data, total };
}
}