hrms-api-org/src/controllers/OrganizationController.ts
Adisak 39a07482cd
All checks were successful
Build & Deploy on Dev / build (push) Successful in 1m0s
add api find dna by keycloak
2026-02-05 11:23:38 +07:00

7708 lines
321 KiB
TypeScript

import { RoleKeycloak } from "./../entities/RoleKeycloak";
import { ProfileEmployee } from "./../entities/ProfileEmployee";
import { EmployeePosition } from "./../entities/EmployeePosition";
import { EmployeePosMaster } from "./../entities/EmployeePosMaster";
import { Position } from "./../entities/Position";
import { ProfileSalaryHistory } from "./../entities/ProfileSalaryHistory";
import { ProfileSalary } from "./../entities/ProfileSalary";
import {
Controller,
Get,
Post,
Put,
Route,
Security,
Tags,
Body,
Path,
Request,
Response,
} from "tsoa";
import { CreateOrgRevision, OrgRevision } from "../entities/OrgRevision";
import { AppDataSource } from "../database/data-source";
import HttpSuccess from "../interfaces/http-success";
import { OrgChild1 } from "../entities/OrgChild1";
import HttpError from "../interfaces/http-error";
import HttpStatusCode from "../interfaces/http-status";
import { In, IsNull, Not } from "typeorm";
import { OrgRoot } from "../entities/OrgRoot";
import { OrgChild2 } from "../entities/OrgChild2";
import { OrgChild3 } from "../entities/OrgChild3";
import { OrgChild4 } from "../entities/OrgChild4";
import { PosMaster } from "../entities/PosMaster";
import { Profile } from "../entities/Profile";
import { RequestWithUser } from "../middlewares/user";
import permission from "../interfaces/permission";
import { checkQueueInProgress, setLogDataDiff } from "../interfaces/utils";
import { sendToQueueOrg, sendToQueueOrgDraft } from "../services/rabbitmq";
import { PosType } from "../entities/PosType";
import { PosLevel } from "../entities/PosLevel";
import { PermissionOrg } from "../entities/PermissionOrg";
import {
deleteUser,
getToken,
createUser,
getUserByUsername,
getRoles,
addUserRoles,
} from "../keycloak";
// import { getPositionCounts, getCounts, getRootCounts } from "../services/OrganizationService";
import {
CreatePosMasterHistoryEmployee,
CreatePosMasterHistoryOfficer,
} from "../services/PositionService";
import { orgStructureCache } from "../utils/OrgStructureCache";
@Route("api/v1/org")
@Tags("Organization")
@Security("bearerAuth")
@Response(
HttpStatusCode.INTERNAL_SERVER_ERROR,
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง",
)
export class OrganizationController extends Controller {
private orgRevisionRepository = AppDataSource.getRepository(OrgRevision);
private orgRootRepository = AppDataSource.getRepository(OrgRoot);
private child1Repository = AppDataSource.getRepository(OrgChild1);
private child2Repository = AppDataSource.getRepository(OrgChild2);
private child3Repository = AppDataSource.getRepository(OrgChild3);
private child4Repository = AppDataSource.getRepository(OrgChild4);
private posMasterRepository = AppDataSource.getRepository(PosMaster);
private profileRepo = AppDataSource.getRepository(Profile);
private posTypeRepository = AppDataSource.getRepository(PosType);
private posLevelRepository = AppDataSource.getRepository(PosLevel);
private permissionOrgRepository = AppDataSource.getRepository(PermissionOrg);
private profileSalaryRepository = AppDataSource.getRepository(ProfileSalary);
private salaryHistoryRepo = AppDataSource.getRepository(ProfileSalaryHistory);
private positionRepository = AppDataSource.getRepository(Position);
private profileEmployeeRepo = AppDataSource.getRepository(ProfileEmployee);
private employeePosMasterRepository = AppDataSource.getRepository(EmployeePosMaster);
private employeePositionRepository = AppDataSource.getRepository(EmployeePosition);
private roleKeycloakRepo = AppDataSource.getRepository(RoleKeycloak);
/**
* API ล้างข้อมูล
*
* @summary ล้างข้อมูล
*
*/
@Get("clear-db")
async ClearDb() {
return new HttpSuccess();
}
/**
* API รายการประวัติโครงสร้าง
*
* @summary ORG_020 - รายการประวัติโครงสร้าง #21
*
*/
@Get("history")
async GetHistory() {
const orgRevision = await this.orgRevisionRepository.find({
select: ["id", "orgRevisionName", "orgRevisionIsCurrent", "createdAt", "orgRevisionIsDraft"],
order: { createdAt: "DESC" },
});
// if (!orgRevision) {
// return new HttpSuccess([]);
// }
const mapOrgRevisions = orgRevision.map((revision) => ({
orgRevisionId: revision.id,
orgRevisionName: revision.orgRevisionName,
orgRevisionIsCurrent: revision.orgRevisionIsCurrent,
orgRevisionCreatedAt: revision.createdAt,
orgRevisionIsDraft: revision.orgRevisionIsDraft,
}));
return new HttpSuccess(mapOrgRevisions);
}
/**
* API โครงสร้างปัจจุบันที่ใช้อยู่
*
* @summary ORG_021 - โครงสร้างปัจจุบันที่ใช้อยู่ #22
*
*/
@Get("active")
async GetActive() {
const orgRevisionActive = await this.orgRevisionRepository.findOne({
where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
});
const orgRevisionDraf = await this.orgRevisionRepository.findOne({
where: { orgRevisionIsCurrent: false, orgRevisionIsDraft: true },
});
const mapData = {
activeId: orgRevisionActive == null ? null : orgRevisionActive.id,
activeName: orgRevisionActive == null ? null : orgRevisionActive.orgRevisionName,
draftId: orgRevisionDraf == null ? null : orgRevisionDraf.id,
draftName: orgRevisionDraf == null ? null : orgRevisionDraf.orgRevisionName,
orgPublishDate: orgRevisionDraf == null ? null : orgRevisionDraf.orgPublishDate,
isPublic: orgRevisionDraf == null || orgRevisionDraf.orgRevisionName == null ? false : true,
};
return new HttpSuccess(mapData);
}
/**
* API สร้างแบบร่างโครงสร้าง
*
* @summary ORG_022 - สร้างโครงสร้างใหม่ #23
*
*/
@Post("draft")
async CreateOrgRevision(
@Body() requestBody: CreateOrgRevision,
@Request() request: RequestWithUser,
) {
try {
// CheckQueueInProgress
const [isBusyDraft, isBusyPublish] = await Promise.all([
checkQueueInProgress(`${process.env.AMQ_QUEUE_ORG_DRAFT}`),
checkQueueInProgress(`${process.env.AMQ_QUEUE_ORG}`),
]);
// console.log("✅ ตรวจสอบแล้ว Draft Busy:", isBusyDraft);
// console.log("✅ ตรวจสอบแล้ว Publish Busy:", isBusyPublish);
if (isBusyDraft || isBusyPublish) {
// console.log("🚫 พบว่ามีงานอยู่ในคิว — error")
throw new HttpError(
HttpStatusCode.CONFLICT,
"ไม่สามารถดำเนินการได้ หากกำลังเผยแพร่หรือสร้างแบบร่างโครงสร้างหน่วยงาน",
);
}
//new main revision
const before = null;
const revision = Object.assign(new OrgRevision(), requestBody) as OrgRevision;
revision.orgRevisionIsDraft = true;
revision.orgRevisionIsCurrent = false;
revision.createdUserId = request.user.sub;
revision.createdFullName = request.user.name;
revision.lastUpdateUserId = request.user.sub;
revision.lastUpdateFullName = request.user.name;
revision.createdAt = new Date();
revision.lastUpdatedAt = new Date();
await this.orgRevisionRepository.save(revision, { data: request });
setLogDataDiff(request, { before, after: revision });
const msg = {
data: {
requestBody: requestBody,
request: request.user,
revision: revision,
},
user: request.user,
};
await sendToQueueOrgDraft(msg);
return new HttpSuccess("Draft is being created... Processing in the background.");
} catch (error: any) {
throw error;
}
}
/**
* API สร้างแบบร่างโครงสร้าง
*
* @summary ORG_022 - สร้างโครงสร้างใหม่ #23
*
*/
@Post("finddna")
async FindDnaOrg(
@Body()
requestBody: {
root: string[] | null;
child1: string[] | null;
child2: string[] | null;
child3: string[] | null;
child4: string[] | null;
privilege: string;
},
@Request() request: RequestWithUser,
) {
const _data = [];
if (requestBody.root != null && requestBody.root.length > 0) {
for (const x of requestBody.root) {
const data = await this.orgRootRepository.findOne({
where: { id: x },
});
if (data) {
_data.push(data.ancestorDNA);
}
}
requestBody.root = _data;
}
const _data1 = [];
if (requestBody.child1 != null && requestBody.child1.length > 0) {
for (const x of requestBody.child1) {
const data = await this.child1Repository.findOne({
where: { id: x },
});
if (data) {
_data1.push(data.ancestorDNA);
}
}
requestBody.child1 = _data1;
}
const _data2 = [];
if (requestBody.child2 != null && requestBody.child2.length > 0) {
for (const x of requestBody.child2) {
const data = await this.child2Repository.findOne({
where: { id: x },
});
if (data) {
_data2.push(data.ancestorDNA);
}
}
requestBody.child2 = _data2;
}
const _data3 = [];
if (requestBody.child3 != null && requestBody.child3.length > 0) {
for (const x of requestBody.child3) {
const data = await this.child3Repository.findOne({
where: { id: x },
});
if (data) {
_data3.push(data.ancestorDNA);
}
}
requestBody.child3 = _data3;
}
const _data4 = [];
if (requestBody.child4 != null && requestBody.child4.length > 0) {
for (const x of requestBody.child4) {
const data = await this.child4Repository.findOne({
where: { id: x },
});
if (data) {
_data4.push(data.ancestorDNA);
}
}
requestBody.child4 = _data4;
}
return new HttpSuccess(requestBody);
}
/**
* API สร้างแบบร่างโครงสร้าง
*
* @summary ORG_022 - สร้างโครงสร้างใหม่ #23
*
*/
@Post("finddna-by-keycloak/{keycloakId}")
async FindDnaOrgByKeycloakId(
@Path() keycloakId: string
) {
let reply: any;
const profileByKeycloak: any = await this.profileRepo.findOne({
where: { keycloak: keycloakId },
select: ["id", "keycloak"]
})
const orgRevision = await this.orgRevisionRepository.findOne({
select: ["id"],
where: {
orgRevisionIsDraft: false,
orgRevisionIsCurrent: true,
},
});
const posMaster = await AppDataSource.getRepository(PosMaster)
.createQueryBuilder("pos")
.leftJoin("pos.orgRoot", "orgRoot")
.leftJoin("pos.orgChild1", "orgChild1")
.leftJoin("pos.orgChild2", "orgChild2")
.leftJoin("pos.orgChild3", "orgChild3")
.leftJoin("pos.orgChild4", "orgChild4")
.where("pos.current_holderId = :holderId", {
holderId: profileByKeycloak.id,
})
.andWhere("pos.orgRevisionId = :revId", {
revId: orgRevision?.id,
})
.select([
"pos.id",
"orgRoot.ancestorDNA as rootDnaId",
"orgChild1.ancestorDNA as child1DnaId",
"orgChild2.ancestorDNA as child2DnaId",
"orgChild3.ancestorDNA as child3DnaId",
"orgChild4.ancestorDNA as child4DnaId",
])
.getRawOne();
if (!posMaster) {
reply = {
rootDnaId: null,
child1DnaId: null,
child2DnaId: null,
child3DnaId: null,
child4DnaId: null,
};
} else {
reply = {
rootDnaId: posMaster.rootDnaId,
child1DnaId: posMaster.child1DnaId,
child2DnaId: posMaster.child2DnaId,
child3DnaId: posMaster.child3DnaId,
child4DnaId: posMaster.child4DnaId,
};
}
return new HttpSuccess(reply);
}
/**
* API เช็คสถานะโครงสร้างว่าส่งคนไปออกคำสั่งหรือไม่
*
* @summary API เช็คสถานะโครงสร้างว่าส่งคนไปออกคำสั่งหรือไม่
*
* @param {string} id Id OrgRevison
*/
@Get("lock/{id}")
async GetById(@Request() request: RequestWithUser, @Path() id: string) {
//add check permission
const orgRevision = await this.orgRevisionRepository.findOne({
where: { id: id },
});
if (!orgRevision) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโครงสร้าง");
}
return new HttpSuccess(orgRevision.isLock);
}
/**
* API รายละเอียดโครงสร้าง
*
* @summary ORG_023 - รายละเอียดโครงสร้าง (ADMIN Menu) #25
*
*/
@Get("admin/{id}")
async detailForAdmin(@Path() id: string, @Request() request: RequestWithUser) {
// let _data: any = {
// root: null,
// child1: null,
// child2: null,
// child3: null,
// child4: null,
// };
const orgRevision = await this.orgRevisionRepository.findOne({ where: { id } });
if (!orgRevision) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
}
// let attrOwnership = null;
if (
orgRevision.orgRevisionIsDraft == true &&
orgRevision.orgRevisionIsCurrent == false &&
request.user.role.includes("SUPER_ADMIN")
// attrOwnership == false
) {
const profile = await this.profileRepo.findOne({
where: { keycloak: request.user.sub },
// relations: ["permissionProfiles"],
});
if (!profile) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผู้ใช้งานในทะเบียนประวัติ");
}
// _data = {
// root: profile.permissionProfiles.map((x) => x.orgRootId),
// child1: null,
// child2: null,
// child3: null,
// child4: null,
// };
}
const orgRootData = await AppDataSource.getRepository(OrgRoot)
.createQueryBuilder("orgRoot")
.where("orgRoot.orgRevisionId = :id", { id })
// .andWhere(
// _data.root != undefined && _data.root != null
// ? _data.root[0] != null
// ? `orgRoot.id IN (:...node)`
// : `orgRoot.id is null`
// : "1=1",
// {
// node: _data.root,
// },
// )
.select([
"orgRoot.id",
"orgRoot.isDeputy",
"orgRoot.isCommission",
"orgRoot.orgRootName",
"orgRoot.orgRootShortName",
"orgRoot.orgRootCode",
"orgRoot.orgRootOrder",
"orgRoot.orgRootPhoneEx",
"orgRoot.orgRootPhoneIn",
"orgRoot.orgRootFax",
"orgRoot.orgRevisionId",
"orgRoot.orgRootRank",
"orgRoot.orgRootRankSub",
"orgRoot.DEPARTMENT_CODE",
"orgRoot.DIVISION_CODE",
"orgRoot.SECTION_CODE",
"orgRoot.JOB_CODE",
"orgRoot.responsibility",
])
.orderBy("orgRoot.orgRootOrder", "ASC")
.getMany();
const orgRootIds = orgRootData.map((orgRoot) => orgRoot.id) || null;
const orgChild1Data =
orgRootIds && orgRootIds.length > 0
? await AppDataSource.getRepository(OrgChild1)
.createQueryBuilder("orgChild1")
.where("orgChild1.orgRootId IN (:...ids)", { ids: orgRootIds })
// .andWhere(
// _data.child1 != undefined && _data.child1 != null
// ? _data.child1[0] != null
// ? `orgChild1.id IN (:...node)`
// : `orgChild1.id is null`
// : "1=1",
// {
// node: _data.child1,
// },
// )
.select([
"orgChild1.id",
"orgChild1.isOfficer",
"orgChild1.isInformation",
"orgChild1.orgChild1Name",
"orgChild1.orgChild1ShortName",
"orgChild1.orgChild1Code",
"orgChild1.orgChild1Order",
"orgChild1.orgChild1PhoneEx",
"orgChild1.orgChild1PhoneIn",
"orgChild1.orgChild1Fax",
"orgChild1.orgRootId",
"orgChild1.orgChild1Rank",
"orgChild1.orgChild1RankSub",
"orgChild1.DEPARTMENT_CODE",
"orgChild1.DIVISION_CODE",
"orgChild1.SECTION_CODE",
"orgChild1.JOB_CODE",
"orgChild1.responsibility",
])
.orderBy("orgChild1.orgChild1Order", "ASC")
.getMany()
: [];
const orgChild1Ids = orgChild1Data.map((orgChild1) => orgChild1.id) || null;
const orgChild2Data =
orgChild1Ids && orgChild1Ids.length > 0
? await AppDataSource.getRepository(OrgChild2)
.createQueryBuilder("orgChild2")
.where("orgChild2.orgChild1Id IN (:...ids)", { ids: orgChild1Ids })
// .andWhere(
// _data.child2 != undefined && _data.child2 != null
// ? _data.child2[0] != null
// ? `orgChild2.id IN (:...node)`
// : `orgChild2.id is null`
// : "1=1",
// {
// node: _data.child2,
// },
// )
.select([
"orgChild2.id",
"orgChild2.orgChild2Name",
"orgChild2.orgChild2ShortName",
"orgChild2.orgChild2Code",
"orgChild2.orgChild2Order",
"orgChild2.orgChild2PhoneEx",
"orgChild2.orgChild2PhoneIn",
"orgChild2.orgChild2Fax",
"orgChild2.orgRootId",
"orgChild2.orgChild2Rank",
"orgChild2.orgChild2RankSub",
"orgChild2.DEPARTMENT_CODE",
"orgChild2.DIVISION_CODE",
"orgChild2.SECTION_CODE",
"orgChild2.JOB_CODE",
"orgChild2.orgChild1Id",
"orgChild2.responsibility",
])
.orderBy("orgChild2.orgChild2Order", "ASC")
.getMany()
: [];
const orgChild2Ids = orgChild2Data.map((orgChild2) => orgChild2.id) || null;
const orgChild3Data =
orgChild2Ids && orgChild2Ids.length > 0
? await AppDataSource.getRepository(OrgChild3)
.createQueryBuilder("orgChild3")
.where("orgChild3.orgChild2Id IN (:...ids)", { ids: orgChild2Ids })
// .andWhere(
// _data.child3 != undefined && _data.child3 != null
// ? _data.child3[0] != null
// ? `orgChild3.id IN (:...node)`
// : `orgChild3.id is null`
// : "1=1",
// {
// node: _data.child3,
// },
// )
.select([
"orgChild3.id",
"orgChild3.orgChild3Name",
"orgChild3.orgChild3ShortName",
"orgChild3.orgChild3Code",
"orgChild3.orgChild3Order",
"orgChild3.orgChild3PhoneEx",
"orgChild3.orgChild3PhoneIn",
"orgChild3.orgChild3Fax",
"orgChild3.orgRootId",
"orgChild3.orgChild3Rank",
"orgChild3.orgChild3RankSub",
"orgChild3.DEPARTMENT_CODE",
"orgChild3.DIVISION_CODE",
"orgChild3.SECTION_CODE",
"orgChild3.JOB_CODE",
"orgChild3.orgChild2Id",
"orgChild3.responsibility",
])
.orderBy("orgChild3.orgChild3Order", "ASC")
.getMany()
: [];
const orgChild3Ids = orgChild3Data.map((orgChild3) => orgChild3.id) || null;
const orgChild4Data =
orgChild3Ids && orgChild3Ids.length > 0
? await AppDataSource.getRepository(OrgChild4)
.createQueryBuilder("orgChild4")
.where("orgChild4.orgChild3Id IN (:...ids)", { ids: orgChild3Ids })
// .andWhere(
// _data.child4 != undefined && _data.child4 != null
// ? _data.child4[0] != null
// ? `orgChild4.id IN (:...node)`
// : `orgChild4.id is null`
// : "1=1",
// {
// node: _data.child4,
// },
// )
.select([
"orgChild4.id",
"orgChild4.orgChild4Name",
"orgChild4.orgChild4ShortName",
"orgChild4.orgChild4Code",
"orgChild4.orgChild4Order",
"orgChild4.orgChild4PhoneEx",
"orgChild4.orgChild4PhoneIn",
"orgChild4.orgChild4Fax",
"orgChild4.orgRootId",
"orgChild4.orgChild4Rank",
"orgChild4.orgChild4RankSub",
"orgChild4.DEPARTMENT_CODE",
"orgChild4.DIVISION_CODE",
"orgChild4.SECTION_CODE",
"orgChild4.JOB_CODE",
"orgChild4.orgChild3Id",
"orgChild4.responsibility",
])
.orderBy("orgChild4.orgChild4Order", "ASC")
.getMany()
: [];
const formattedData = await Promise.all(
orgRootData.map(async (orgRoot) => {
return {
orgTreeId: orgRoot.id,
orgLevel: 0,
orgName: orgRoot.orgRootName,
orgTreeName: orgRoot.orgRootName,
orgTreeShortName: orgRoot.orgRootShortName,
orgTreeCode: orgRoot.orgRootCode,
orgCode: orgRoot.orgRootCode + "00",
orgTreeRank: orgRoot.orgRootRank,
orgTreeRankSub: orgRoot.orgRootRankSub,
DEPARTMENT_CODE: orgRoot.DEPARTMENT_CODE,
DIVISION_CODE: orgRoot.DIVISION_CODE,
SECTION_CODE: orgRoot.SECTION_CODE,
JOB_CODE: orgRoot.JOB_CODE,
orgTreeOrder: orgRoot.orgRootOrder,
orgTreePhoneEx: orgRoot.orgRootPhoneEx,
orgTreePhoneIn: orgRoot.orgRootPhoneIn,
orgTreeFax: orgRoot.orgRootFax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgRoot.responsibility,
isOfficer: false,
isDeputy: orgRoot.isDeputy,
isCommission: orgRoot.isCommission,
labelName:
orgRoot.orgRootName + " " + orgRoot.orgRootCode + "00" + " " + orgRoot.orgRootShortName,
totalPosition: await this.posMasterRepository.count({
where: { orgRevisionId: orgRoot.orgRevisionId, orgRootId: orgRoot.id },
}),
totalPositionCurrentUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
current_holderId: Not(IsNull()) || Not(""),
},
}),
totalPositionCurrentVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
current_holderId: IsNull() || "",
},
}),
totalPositionNextUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
next_holderId: Not(IsNull()) || Not(""),
},
}),
totalPositionNextVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
next_holderId: IsNull() || "",
},
}),
totalRootPosition: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: IsNull() || "",
orgChild2Id: IsNull() || "",
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
},
}),
totalRootPositionCurrentUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: IsNull() || "",
orgChild2Id: IsNull() || "",
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
current_holderId: Not(IsNull()) || Not(""),
},
}),
totalRootPositionCurrentVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: IsNull() || "",
orgChild2Id: IsNull() || "",
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
current_holderId: IsNull() || "",
},
}),
totalRootPositionNextUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: IsNull() || "",
orgChild2Id: IsNull() || "",
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
next_holderId: Not(IsNull()) || Not(""),
},
}),
totalRootPositionNextVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: IsNull() || "",
orgChild2Id: IsNull() || "",
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
next_holderId: IsNull() || "",
},
}),
children: await Promise.all(
orgChild1Data
.filter((orgChild1) => orgChild1.orgRootId === orgRoot.id)
.map(async (orgChild1) => ({
orgTreeId: orgChild1.id,
orgRootId: orgRoot.id,
orgLevel: 1,
orgName: `${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild1.orgChild1Name,
orgTreeShortName: orgChild1.orgChild1ShortName,
orgTreeCode: orgChild1.orgChild1Code,
orgCode: orgRoot.orgRootCode + orgChild1.orgChild1Code,
orgTreeRank: orgChild1.orgChild1Rank,
orgTreeRankSub: orgChild1.orgChild1RankSub,
DEPARTMENT_CODE: orgChild1.DEPARTMENT_CODE,
DIVISION_CODE: orgChild1.DIVISION_CODE,
SECTION_CODE: orgChild1.SECTION_CODE,
JOB_CODE: orgChild1.JOB_CODE,
orgTreeOrder: orgChild1.orgChild1Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild1.orgChild1PhoneEx,
orgTreePhoneIn: orgChild1.orgChild1PhoneIn,
orgTreeFax: orgChild1.orgChild1Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild1.responsibility,
isOfficer: orgChild1.isOfficer,
isInformation: orgChild1.isInformation,
labelName:
orgChild1.orgChild1Name +
" " +
orgRoot.orgRootCode +
orgChild1.orgChild1Code +
" " +
orgChild1.orgChild1ShortName,
totalPosition: await this.posMasterRepository.count({
where: { orgRevisionId: orgRoot.orgRevisionId, orgChild1Id: orgChild1.id },
}),
totalPositionCurrentUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild1Id: orgChild1.id,
current_holderId: Not(IsNull()) || Not(""),
},
}),
totalPositionCurrentVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild1Id: orgChild1.id,
current_holderId: IsNull() || "",
},
}),
totalPositionNextUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild1Id: orgChild1.id,
next_holderId: Not(IsNull()) || Not(""),
},
}),
totalPositionNextVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild1Id: orgChild1.id,
next_holderId: IsNull() || "",
},
}),
totalRootPosition: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: IsNull() || "",
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
},
}),
totalRootPositionCurrentUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: IsNull() || "",
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
current_holderId: Not(IsNull()) || Not(""),
},
}),
totalRootPositionCurrentVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: IsNull() || "",
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
current_holderId: IsNull() || "",
},
}),
totalRootPositionNextUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: IsNull() || "",
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
next_holderId: Not(IsNull()) || Not(""),
},
}),
totalRootPositionNextVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: IsNull() || "",
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
next_holderId: IsNull() || "",
},
}),
children: await Promise.all(
orgChild2Data
.filter((orgChild2) => orgChild2.orgChild1Id === orgChild1.id)
.map(async (orgChild2) => ({
orgTreeId: orgChild2.id,
orgRootId: orgChild1.id,
orgLevel: 2,
orgName: `${orgChild2.orgChild2Name}/${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild2.orgChild2Name,
orgTreeShortName: orgChild2.orgChild2ShortName,
orgTreeCode: orgChild2.orgChild2Code,
orgCode: orgRoot.orgRootCode + orgChild2.orgChild2Code,
orgTreeRank: orgChild2.orgChild2Rank,
orgTreeRankSub: orgChild2.orgChild2RankSub,
DEPARTMENT_CODE: orgChild2.DEPARTMENT_CODE,
DIVISION_CODE: orgChild2.DIVISION_CODE,
SECTION_CODE: orgChild2.SECTION_CODE,
JOB_CODE: orgChild2.JOB_CODE,
orgTreeOrder: orgChild2.orgChild2Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild2.orgChild2PhoneEx,
orgTreePhoneIn: orgChild2.orgChild2PhoneIn,
orgTreeFax: orgChild2.orgChild2Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild2.responsibility,
isOfficer: orgChild1.isOfficer,
labelName:
orgChild2.orgChild2Name +
" " +
orgRoot.orgRootCode +
orgChild2.orgChild2Code +
" " +
orgChild2.orgChild2ShortName,
totalPosition: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild2Id: orgChild2.id,
},
}),
totalPositionCurrentUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild2Id: orgChild2.id,
current_holderId: Not(IsNull()) || Not(""),
},
}),
totalPositionCurrentVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild2Id: orgChild2.id,
current_holderId: IsNull() || "",
},
}),
totalPositionNextUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild2Id: orgChild2.id,
next_holderId: Not(IsNull()) || Not(""),
},
}),
totalPositionNextVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild2Id: orgChild2.id,
next_holderId: IsNull() || "",
},
}),
totalRootPosition: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
},
}),
totalRootPositionCurrentUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
current_holderId: Not(IsNull()) || Not(""),
},
}),
totalRootPositionCurrentVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
current_holderId: IsNull() || "",
},
}),
totalRootPositionNextUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
next_holderId: Not(IsNull()) || Not(""),
},
}),
totalRootPositionNextVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
next_holderId: IsNull() || "",
},
}),
children: await Promise.all(
orgChild3Data
.filter((orgChild3) => orgChild3.orgChild2Id === orgChild2.id)
.map(async (orgChild3) => ({
orgTreeId: orgChild3.id,
orgRootId: orgChild2.id,
orgLevel: 3,
orgName: `${orgChild3.orgChild3Name}/${orgChild2.orgChild2Name}/${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild3.orgChild3Name,
orgTreeShortName: orgChild3.orgChild3ShortName,
orgTreeCode: orgChild3.orgChild3Code,
orgCode: orgRoot.orgRootCode + orgChild3.orgChild3Code,
orgTreeRank: orgChild3.orgChild3Rank,
orgTreeRankSub: orgChild3.orgChild3RankSub,
DEPARTMENT_CODE: orgChild3.DEPARTMENT_CODE,
DIVISION_CODE: orgChild3.DIVISION_CODE,
SECTION_CODE: orgChild3.SECTION_CODE,
JOB_CODE: orgChild3.JOB_CODE,
orgTreeOrder: orgChild3.orgChild3Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild3.orgChild3PhoneEx,
orgTreePhoneIn: orgChild3.orgChild3PhoneIn,
orgTreeFax: orgChild3.orgChild3Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild3.responsibility,
isOfficer: orgChild1.isOfficer,
labelName:
orgChild3.orgChild3Name +
" " +
orgRoot.orgRootCode +
orgChild3.orgChild3Code +
" " +
orgChild3.orgChild3ShortName,
totalPosition: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild3Id: orgChild3.id,
},
}),
totalPositionCurrentUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild3Id: orgChild3.id,
current_holderId: Not(IsNull()) || Not(""),
},
}),
totalPositionCurrentVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild3Id: orgChild3.id,
current_holderId: IsNull() || "",
},
}),
totalPositionNextUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild3Id: orgChild3.id,
next_holderId: Not(IsNull()) || Not(""),
},
}),
totalPositionNextVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild3Id: orgChild3.id,
next_holderId: IsNull() || "",
},
}),
totalRootPosition: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: IsNull() || "",
},
}),
totalRootPositionCurrentUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: IsNull() || "",
current_holderId: Not(IsNull()) || Not(""),
},
}),
totalRootPositionCurrentVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: IsNull() || "",
current_holderId: IsNull() || "",
},
}),
totalRootPositionNextUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: IsNull() || "",
next_holderId: Not(IsNull()) || Not(""),
},
}),
totalRootPositionNextVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: IsNull() || "",
next_holderId: IsNull() || "",
},
}),
children: await Promise.all(
orgChild4Data
.filter((orgChild4) => orgChild4.orgChild3Id === orgChild3.id)
.map(async (orgChild4) => ({
orgTreeId: orgChild4.id,
orgRootId: orgChild3.id,
orgLevel: 4,
orgName: `${orgChild4.orgChild4Name}/${orgChild3.orgChild3Name}/${orgChild2.orgChild2Name}/${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild4.orgChild4Name,
orgTreeShortName: orgChild4.orgChild4ShortName,
orgTreeCode: orgChild4.orgChild4Code,
orgCode: orgRoot.orgRootCode + orgChild4.orgChild4Code,
orgTreeRank: orgChild4.orgChild4Rank,
orgTreeRankSub: orgChild4.orgChild4RankSub,
DEPARTMENT_CODE: orgChild4.DEPARTMENT_CODE,
DIVISION_CODE: orgChild4.DIVISION_CODE,
SECTION_CODE: orgChild4.SECTION_CODE,
JOB_CODE: orgChild4.JOB_CODE,
orgTreeOrder: orgChild4.orgChild4Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild4.orgChild4PhoneEx,
orgTreePhoneIn: orgChild4.orgChild4PhoneIn,
orgTreeFax: orgChild4.orgChild4Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild4.responsibility,
isOfficer: orgChild1.isOfficer,
labelName:
orgChild4.orgChild4Name +
" " +
orgRoot.orgRootCode +
orgChild4.orgChild4Code +
" " +
orgChild4.orgChild4ShortName,
totalPosition: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild4Id: orgChild4.id,
},
}),
totalPositionCurrentUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild4Id: orgChild4.id,
current_holderId: Not(IsNull()) || Not(""),
},
}),
totalPositionCurrentVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild4Id: orgChild4.id,
current_holderId: IsNull() || "",
},
}),
totalPositionNextUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild4Id: orgChild4.id,
next_holderId: Not(IsNull()) || Not(""),
},
}),
totalPositionNextVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgChild4Id: orgChild4.id,
next_holderId: IsNull() || "",
},
}),
totalRootPosition: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
},
}),
totalRootPositionCurrentUse: await this.posMasterRepository.count(
{
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
current_holderId: Not(IsNull()) || Not(""),
},
},
),
totalRootPositionCurrentVacant:
await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
current_holderId: IsNull() || "",
},
}),
totalRootPositionNextUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
next_holderId: Not(IsNull()) || Not(""),
},
}),
totalRootPositionNextVacant: await this.posMasterRepository.count(
{
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
next_holderId: IsNull() || "",
},
},
),
})),
),
})),
),
})),
),
})),
),
};
}),
);
return new HttpSuccess(formattedData);
}
/**
* API รายละเอียดโครงสร้าง
*
* @summary ORG_023 - รายละเอียดโครงสร้าง (ADMIN) #25
*
*/
@Get("super-admin/{id}")
async detailSuperAdmin(@Path() id: string, @Request() request: RequestWithUser) {
const orgRevision = await this.orgRevisionRepository.findOne({
where: { id: id },
});
if (!orgRevision) return new HttpSuccess([]);
let rootId: any = null;
if (!request.user.role.includes("SUPER_ADMIN")) {
const profile = await this.profileRepo.findOne({
where: {
keycloak: request.user.sub,
},
select: ["id"],
});
if (profile == null) return new HttpSuccess([]);
const posMaster = await this.posMasterRepository.findOne({
where:
orgRevision.orgRevisionIsCurrent && !orgRevision.orgRevisionIsDraft
? {
orgRevisionId: id,
current_holderId: profile.id,
}
: {
orgRevisionId: id,
next_holderId: profile.id,
},
});
if (!posMaster) return new HttpSuccess([]);
rootId = posMaster.orgRootId;
}
// OPTIMIZED: Check cache first
const cachedResponse = await orgStructureCache.get(id, rootId);
if (cachedResponse) {
return new HttpSuccess(cachedResponse);
}
// OPTIMIZED: Get all position counts in ONE query (closed)
// const { orgRootMap, orgChild1Map, orgChild2Map, orgChild3Map, orgChild4Map, rootPosMap } =
// await getPositionCounts(id);
// OPTIMIZED: Fetch orgRoot first, then fetch all child levels in parallel
const orgRootData = await AppDataSource.getRepository(OrgRoot)
.createQueryBuilder("orgRoot")
.where("orgRoot.orgRevisionId = :id", { id })
.andWhere(rootId != null ? `orgRoot.id = :rootId` : "1=1", {
rootId: rootId,
})
.orderBy("orgRoot.orgRootOrder", "ASC")
.getMany();
const orgRootIds = orgRootData.map((orgRoot) => orgRoot.id);
// OPTIMIZED: Fetch all child levels in parallel using orgRevisionId
// This is faster than sequential queries that depend on parent IDs
const [orgChild1AllData, orgChild2AllData, orgChild3AllData, orgChild4AllData] =
await Promise.all([
AppDataSource.getRepository(OrgChild1)
.createQueryBuilder("orgChild1")
.where("orgChild1.orgRevisionId = :id", { id })
.orderBy("orgChild1.orgChild1Order", "ASC")
.getMany(),
AppDataSource.getRepository(OrgChild2)
.createQueryBuilder("orgChild2")
.where("orgChild2.orgRevisionId = :id", { id })
.orderBy("orgChild2.orgChild2Order", "ASC")
.getMany(),
AppDataSource.getRepository(OrgChild3)
.createQueryBuilder("orgChild3")
.where("orgChild3.orgRevisionId = :id", { id })
.orderBy("orgChild3.orgChild3Order", "ASC")
.getMany(),
AppDataSource.getRepository(OrgChild4)
.createQueryBuilder("orgChild4")
.where("orgChild4.orgRevisionId = :id", { id })
.orderBy("orgChild4.orgChild4Order", "ASC")
.getMany(),
]);
// Filter child1 data by orgRootIds (maintains backward compatibility)
const orgChild1Data =
orgRootIds && orgRootIds.length > 0
? orgChild1AllData.filter((orgChild1) => orgRootIds.includes(orgChild1.orgRootId))
: [];
// Build maps for efficient filtering of deeper levels
const orgChild1Ids = orgChild1Data.map((orgChild1) => orgChild1.id);
const orgChild2Data =
orgChild1Ids && orgChild1Ids.length > 0
? orgChild2AllData.filter((orgChild2) => orgChild1Ids.includes(orgChild2.orgChild1Id))
: [];
const orgChild2Ids = orgChild2Data.map((orgChild2) => orgChild2.id);
const orgChild3Data =
orgChild2Ids && orgChild2Ids.length > 0
? orgChild3AllData.filter((orgChild3) => orgChild2Ids.includes(orgChild3.orgChild2Id))
: [];
const orgChild3Ids = orgChild3Data.map((orgChild3) => orgChild3.id);
const orgChild4Data =
orgChild3Ids && orgChild3Ids.length > 0
? orgChild4AllData.filter((orgChild4) => orgChild3Ids.includes(orgChild4.orgChild3Id))
: [];
// OPTIMIZED: Build formatted data using pre-calculated counts (no nested queries!)
const formattedData = orgRootData.map((orgRoot) => {
// const rootCounts = getCounts(orgRootMap, orgRoot.id);
// const rootPosCounts = getRootCounts(rootPosMap, orgRoot.id);
return {
orgTreeId: orgRoot.id,
orgLevel: 0,
orgName: orgRoot.orgRootName,
orgTreeName: orgRoot.orgRootName,
orgTreeShortName: orgRoot.orgRootShortName,
orgTreeCode: orgRoot.orgRootCode,
orgCode: orgRoot.orgRootCode + "00",
orgTreeRank: orgRoot.orgRootRank,
orgTreeRankSub: orgRoot.orgRootRankSub,
orgRootDnaId: orgRoot.ancestorDNA,
DEPARTMENT_CODE: orgRoot.DEPARTMENT_CODE,
DIVISION_CODE: orgRoot.DIVISION_CODE,
SECTION_CODE: orgRoot.SECTION_CODE,
JOB_CODE: orgRoot.JOB_CODE,
orgTreeOrder: orgRoot.orgRootOrder,
orgTreePhoneEx: orgRoot.orgRootPhoneEx,
orgTreePhoneIn: orgRoot.orgRootPhoneIn,
orgTreeFax: orgRoot.orgRootFax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
isDeputy: orgRoot.isDeputy,
isCommission: orgRoot.isCommission,
responsibility: orgRoot.responsibility,
labelName:
orgRoot.orgRootName + " " + orgRoot.orgRootCode + "00" + " " + orgRoot.orgRootShortName,
// totalPosition: rootCounts.totalPosition,
// totalPositionCurrentUse: rootCounts.totalPositionCurrentUse,
// totalPositionCurrentVacant: rootCounts.totalPositionCurrentVacant,
// totalPositionNextUse: rootCounts.totalPositionNextUse,
// totalPositionNextVacant: rootCounts.totalPositionNextVacant,
// totalRootPosition: rootPosCounts.totalRootPosition,
// totalRootPositionCurrentUse: rootPosCounts.totalRootPositionCurrentUse,
// totalRootPositionCurrentVacant: rootPosCounts.totalRootPositionCurrentVacant,
// totalRootPositionNextUse: rootPosCounts.totalRootPositionNextUse,
// totalRootPositionNextVacant: rootPosCounts.totalRootPositionNextVacant,
children: orgChild1Data
.filter((orgChild1) => orgChild1.orgRootId === orgRoot.id)
.map((orgChild1) => {
// const child1Counts = getCounts(orgChild1Map, orgChild1.id);
// const child1PosKey = `${orgRoot.id}-${orgChild1.id}`;
// const child1PosCounts = getRootCounts(rootPosMap, child1PosKey);
return {
orgTreeId: orgChild1.id,
orgRootId: orgRoot.id,
orgLevel: 1,
orgName: `${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild1.orgChild1Name,
orgTreeShortName: orgChild1.orgChild1ShortName,
orgTreeCode: orgChild1.orgChild1Code,
orgCode: orgRoot.orgRootCode + orgChild1.orgChild1Code,
orgTreeRank: orgChild1.orgChild1Rank,
orgTreeRankSub: orgChild1.orgChild1RankSub,
orgRootDnaId: orgRoot.ancestorDNA,
orgChild1DnaId: orgChild1.ancestorDNA,
DEPARTMENT_CODE: orgChild1.DEPARTMENT_CODE,
DIVISION_CODE: orgChild1.DIVISION_CODE,
SECTION_CODE: orgChild1.SECTION_CODE,
JOB_CODE: orgChild1.JOB_CODE,
orgTreeOrder: orgChild1.orgChild1Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild1.orgChild1PhoneEx,
orgTreePhoneIn: orgChild1.orgChild1PhoneIn,
orgTreeFax: orgChild1.orgChild1Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild1.responsibility,
isOfficer: orgChild1.isOfficer,
isInformation: orgChild1.isInformation,
labelName:
orgChild1.orgChild1Name +
" " +
orgRoot.orgRootCode +
orgChild1.orgChild1Code +
" " +
orgChild1.orgChild1ShortName,
// totalPosition: child1Counts.totalPosition,
// totalPositionCurrentUse: child1Counts.totalPositionCurrentUse,
// totalPositionCurrentVacant: child1Counts.totalPositionCurrentVacant,
// totalPositionNextUse: child1Counts.totalPositionNextUse,
// totalPositionNextVacant: child1Counts.totalPositionNextVacant,
// totalRootPosition: child1PosCounts.totalRootPosition,
// totalRootPositionCurrentUse: child1PosCounts.totalRootPositionCurrentUse,
// totalRootPositionCurrentVacant: child1PosCounts.totalRootPositionCurrentVacant,
// totalRootPositionNextUse: child1PosCounts.totalRootPositionNextUse,
// totalRootPositionNextVacant: child1PosCounts.totalRootPositionNextVacant,
children: orgChild2Data
.filter((orgChild2) => orgChild2.orgChild1Id === orgChild1.id)
.map((orgChild2) => {
// const child2Counts = getCounts(orgChild2Map, orgChild2.id);
// const child2PosKey = `${orgRoot.id}-${orgChild1.id}-${orgChild2.id}`;
// const child2PosCounts = getRootCounts(rootPosMap, child2PosKey);
return {
orgTreeId: orgChild2.id,
orgRootId: orgChild1.id,
orgLevel: 2,
orgName: `${orgChild2.orgChild2Name}/${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild2.orgChild2Name,
orgTreeShortName: orgChild2.orgChild2ShortName,
orgTreeCode: orgChild2.orgChild2Code,
orgCode: orgRoot.orgRootCode + orgChild2.orgChild2Code,
orgTreeRank: orgChild2.orgChild2Rank,
orgTreeRankSub: orgChild2.orgChild2RankSub,
orgRootDnaId: orgRoot.ancestorDNA,
orgChild1DnaId: orgChild1.ancestorDNA,
orgChild2DnaId: orgChild2.ancestorDNA,
DEPARTMENT_CODE: orgChild2.DEPARTMENT_CODE,
DIVISION_CODE: orgChild2.DIVISION_CODE,
SECTION_CODE: orgChild2.SECTION_CODE,
JOB_CODE: orgChild2.JOB_CODE,
orgTreeOrder: orgChild2.orgChild2Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild2.orgChild2PhoneEx,
orgTreePhoneIn: orgChild2.orgChild2PhoneIn,
orgTreeFax: orgChild2.orgChild2Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild2.responsibility,
labelName:
orgChild2.orgChild2Name +
" " +
orgRoot.orgRootCode +
orgChild2.orgChild2Code +
" " +
orgChild2.orgChild2ShortName,
// totalPosition: child2Counts.totalPosition,
// totalPositionCurrentUse: child2Counts.totalPositionCurrentUse,
// totalPositionCurrentVacant: child2Counts.totalPositionCurrentVacant,
// totalPositionNextUse: child2Counts.totalPositionNextUse,
// totalPositionNextVacant: child2Counts.totalPositionNextVacant,
// totalRootPosition: child2PosCounts.totalRootPosition,
// totalRootPositionCurrentUse: child2PosCounts.totalRootPositionCurrentUse,
// totalRootPositionCurrentVacant: child2PosCounts.totalRootPositionCurrentVacant,
// totalRootPositionNextUse: child2PosCounts.totalRootPositionNextUse,
// totalRootPositionNextVacant: child2PosCounts.totalRootPositionNextVacant,
children: orgChild3Data
.filter((orgChild3) => orgChild3.orgChild2Id === orgChild2.id)
.map((orgChild3) => {
// const child3Counts = getCounts(orgChild3Map, orgChild3.id);
// const child3PosKey = `${orgRoot.id}-${orgChild1.id}-${orgChild2.id}-${orgChild3.id}`;
// const child3PosCounts = getRootCounts(rootPosMap, child3PosKey);
return {
orgTreeId: orgChild3.id,
orgRootId: orgChild2.id,
orgLevel: 3,
orgName: `${orgChild3.orgChild3Name}/${orgChild2.orgChild2Name}/${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild3.orgChild3Name,
orgTreeShortName: orgChild3.orgChild3ShortName,
orgTreeCode: orgChild3.orgChild3Code,
orgCode: orgRoot.orgRootCode + orgChild3.orgChild3Code,
orgTreeRank: orgChild3.orgChild3Rank,
orgTreeRankSub: orgChild3.orgChild3RankSub,
orgRootDnaId: orgRoot.ancestorDNA,
orgChild1DnaId: orgChild1.ancestorDNA,
orgChild2DnaId: orgChild2.ancestorDNA,
orgChild3DnaId: orgChild3.ancestorDNA,
DEPARTMENT_CODE: orgChild3.DEPARTMENT_CODE,
DIVISION_CODE: orgChild3.DIVISION_CODE,
SECTION_CODE: orgChild3.SECTION_CODE,
JOB_CODE: orgChild3.JOB_CODE,
orgTreeOrder: orgChild3.orgChild3Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild3.orgChild3PhoneEx,
orgTreePhoneIn: orgChild3.orgChild3PhoneIn,
orgTreeFax: orgChild3.orgChild3Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild3.responsibility,
labelName:
orgChild3.orgChild3Name +
" " +
orgRoot.orgRootCode +
orgChild3.orgChild3Code +
" " +
orgChild3.orgChild3ShortName,
// totalPosition: child3Counts.totalPosition,
// totalPositionCurrentUse: child3Counts.totalPositionCurrentUse,
// totalPositionCurrentVacant: child3Counts.totalPositionCurrentVacant,
// totalPositionNextUse: child3Counts.totalPositionNextUse,
// totalPositionNextVacant: child3Counts.totalPositionNextVacant,
// totalRootPosition: child3PosCounts.totalRootPosition,
// totalRootPositionCurrentUse: child3PosCounts.totalRootPositionCurrentUse,
// totalRootPositionCurrentVacant:
// child3PosCounts.totalRootPositionCurrentVacant,
// totalRootPositionNextUse: child3PosCounts.totalRootPositionNextUse,
// totalRootPositionNextVacant: child3PosCounts.totalRootPositionNextVacant,
children: orgChild4Data
.filter((orgChild4) => orgChild4.orgChild3Id === orgChild3.id)
.map((orgChild4) => {
// const child4Counts = getCounts(orgChild4Map, orgChild4.id);
// const child4PosKey = `${orgRoot.id}-${orgChild1.id}-${orgChild2.id}-${orgChild3.id}-${orgChild4.id}`;
// const child4PosCounts = getRootCounts(rootPosMap, child4PosKey);
return {
orgTreeId: orgChild4.id,
orgRootId: orgChild3.id,
orgLevel: 4,
orgName: `${orgChild4.orgChild4Name}/${orgChild3.orgChild3Name}/${orgChild2.orgChild2Name}/${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild4.orgChild4Name,
orgTreeShortName: orgChild4.orgChild4ShortName,
orgTreeCode: orgChild4.orgChild4Code,
orgCode: orgRoot.orgRootCode + orgChild4.orgChild4Code,
orgTreeRank: orgChild4.orgChild4Rank,
orgTreeRankSub: orgChild4.orgChild4RankSub,
orgRootDnaId: orgRoot.ancestorDNA,
orgChild1DnaId: orgChild1.ancestorDNA,
orgChild2DnaId: orgChild2.ancestorDNA,
orgChild3DnaId: orgChild3.ancestorDNA,
orgChild4DnaId: orgChild4.ancestorDNA,
DEPARTMENT_CODE: orgChild4.DEPARTMENT_CODE,
DIVISION_CODE: orgChild4.DIVISION_CODE,
SECTION_CODE: orgChild4.SECTION_CODE,
JOB_CODE: orgChild4.JOB_CODE,
orgTreeOrder: orgChild4.orgChild4Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild4.orgChild4PhoneEx,
orgTreePhoneIn: orgChild4.orgChild4PhoneIn,
orgTreeFax: orgChild4.orgChild4Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild4.responsibility,
labelName:
orgChild4.orgChild4Name +
" " +
orgRoot.orgRootCode +
orgChild4.orgChild4Code +
" " +
orgChild4.orgChild4ShortName,
// totalPosition: child4Counts.totalPosition,
// totalPositionCurrentUse: child4Counts.totalPositionCurrentUse,
// totalPositionCurrentVacant: child4Counts.totalPositionCurrentVacant,
// totalPositionNextUse: child4Counts.totalPositionNextUse,
// totalPositionNextVacant: child4Counts.totalPositionNextVacant,
// totalRootPosition: child4PosCounts.totalRootPosition,
// totalRootPositionCurrentUse:
// child4PosCounts.totalRootPositionCurrentUse,
// totalRootPositionCurrentVacant:
// child4PosCounts.totalRootPositionCurrentVacant,
// totalRootPositionNextUse: child4PosCounts.totalRootPositionNextUse,
// totalRootPositionNextVacant:
// child4PosCounts.totalRootPositionNextVacant,
children: [],
};
}),
};
}),
};
}),
};
}),
};
});
// OPTIMIZED: Cache the result
await orgStructureCache.set(id, rootId, formattedData);
return new HttpSuccess(formattedData);
}
/**
* API รายละเอียดโครงสร้าง
*
* @summary ORG_023 - รายละเอียดโครงสร้าง (ADMIN) #25
*
*/
@Get("{id}")
async detail(@Path() id: string, @Request() request: RequestWithUser) {
let _data: any = {
root: null,
child1: null,
child2: null,
child3: null,
child4: null,
};
let _data1: any = {
root: null,
};
const orgRevision = await this.orgRevisionRepository.findOne({ where: { id } });
if (!orgRevision) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
}
let _privilege = await new permission().PermissionOrgList(request, "SYS_ORG");
const attrOwnership = _privilege.root === null ? true : false;
const profile = await this.profileRepo.findOne({
where: { keycloak: request.user.sub },
relations: ["permissionProfiles", "current_holders", "current_holders.posMasterAssigns"],
});
if (!profile) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผู้ใช้งานในทะเบียนประวัติ");
}
let profileAssign = profile.current_holders
?.find((x) => x.orgRevisionId === id)
?.posMasterAssigns.find((x) => x.assignId === "SYS_ORG");
if (orgRevision.orgRevisionIsDraft && !orgRevision.orgRevisionIsCurrent && !attrOwnership) {
if (Array.isArray(profile.permissionProfiles) && profile.permissionProfiles.length > 0) {
_data.root = profile.permissionProfiles.map((x) => x.orgRootId);
} else {
return new HttpSuccess({ remark: "", data: [] });
}
}
// กำหนดการเข้าถึงข้อมูลตามสถานะและสิทธิ์
const isCurrentActive = !orgRevision.orgRevisionIsDraft && orgRevision.orgRevisionIsCurrent;
if (isCurrentActive) {
if (profileAssign && _privilege.privilege !== "OWNER") {
if (_privilege.privilege == "NORMAL") {
const holder = profile.current_holders.find((x) => x.orgRevisionId === id);
if (!holder) return;
_data.root = [holder.orgRootId];
_data.child1 = [holder.orgChild1Id];
_data.child2 = [holder.orgChild2Id];
_data.child3 = [holder.orgChild3Id];
_data.child4 = [holder.orgChild4Id];
} else if (_privilege.privilege == "CHILD" || _privilege.privilege == "BROTHER") {
const holder = profile.current_holders.find((x) => x.orgRevisionId === id);
if (!holder) return;
_data.root = [holder.orgRootId];
if (_privilege.root && _privilege.child1 === null) {
} else if (_privilege.child1 && _privilege.child2 === null) {
_data.child1 = [holder.orgChild1Id];
} else if (_privilege.child2 && _privilege.child3 === null) {
_data.child1 = [holder.orgChild1Id];
_data.child2 = [holder.orgChild2Id];
} else if (_privilege.child3 && _privilege.child4 === null) {
_data.child1 = [holder.orgChild1Id];
_data.child2 = [holder.orgChild2Id];
_data.child3 = [holder.orgChild3Id];
_data.child4 = [holder.orgChild4Id];
}
} else {
_data.root = [profile.current_holders.find((x) => x.orgRevisionId === id)?.orgRootId];
}
} else {
if (!attrOwnership) _data = _privilege;
}
}
const _revision = await this.orgRevisionRepository.findOne({
where: { id: id },
});
if (!_revision) throw new HttpError(HttpStatusCode.NOT_FOUND, "not found.");
const orgRootData = await AppDataSource.getRepository(OrgRoot)
.createQueryBuilder("orgRoot")
.where("orgRoot.orgRevisionId = :id", { id })
.andWhere(
_data.root !== undefined && _data.root !== null
? _data.root[0] !== null
? `orgRoot.id IN (:...node)`
: `orgRoot.id is null`
: "1=1",
{
node: _data.root,
},
)
.select([
"orgRoot.id",
"orgRoot.misId",
"orgRoot.isDeputy",
"orgRoot.isCommission",
"orgRoot.orgRootName",
"orgRoot.orgRootShortName",
"orgRoot.orgRootCode",
"orgRoot.orgRootOrder",
"orgRoot.orgRootPhoneEx",
"orgRoot.orgRootPhoneIn",
"orgRoot.orgRootFax",
"orgRoot.orgRevisionId",
"orgRoot.orgRootRank",
"orgRoot.orgRootRankSub",
"orgRoot.DEPARTMENT_CODE",
"orgRoot.DIVISION_CODE",
"orgRoot.SECTION_CODE",
"orgRoot.JOB_CODE",
"orgRoot.responsibility",
])
.orderBy("orgRoot.orgRootOrder", "ASC")
.getMany();
const orgRootIds = orgRootData.map((orgRoot) => orgRoot.id) || null;
const orgChild1Data =
orgRootIds && orgRootIds.length > 0
? await AppDataSource.getRepository(OrgChild1)
.createQueryBuilder("orgChild1")
.where("orgChild1.orgRootId IN (:...ids)", { ids: orgRootIds })
.andWhere(
_data.child1 !== undefined && _data.child1 !== null
? _data.child1[0] !== null
? `orgChild1.id IN (:...node)`
: `orgChild1.id is null`
: "1=1",
{
node: _data.child1,
},
)
.select([
"orgChild1.id",
"orgChild1.misId",
"orgChild1.isOfficer",
"orgChild1.isInformation",
"orgChild1.orgChild1Name",
"orgChild1.orgChild1ShortName",
"orgChild1.orgChild1Code",
"orgChild1.orgChild1Order",
"orgChild1.orgChild1PhoneEx",
"orgChild1.orgChild1PhoneIn",
"orgChild1.orgChild1Fax",
"orgChild1.orgRootId",
"orgChild1.orgChild1Rank",
"orgChild1.orgChild1RankSub",
"orgChild1.DEPARTMENT_CODE",
"orgChild1.DIVISION_CODE",
"orgChild1.SECTION_CODE",
"orgChild1.JOB_CODE",
"orgChild1.responsibility",
])
.orderBy("orgChild1.orgChild1Order", "ASC")
.getMany()
: [];
const orgChild1Ids = orgChild1Data.map((orgChild1) => orgChild1.id) || null;
const orgChild2Data =
orgChild1Ids && orgChild1Ids.length > 0
? await AppDataSource.getRepository(OrgChild2)
.createQueryBuilder("orgChild2")
.where("orgChild2.orgChild1Id IN (:...ids)", { ids: orgChild1Ids })
.andWhere(
_data.child2 !== undefined && _data.child2 !== null
? _data.child2[0] !== null
? `orgChild2.id IN (:...node)`
: `orgChild2.id is null`
: "1=1",
{
node: _data.child2,
},
)
.select([
"orgChild2.id",
"orgChild2.misId",
"orgChild2.orgChild2Name",
"orgChild2.orgChild2ShortName",
"orgChild2.orgChild2Code",
"orgChild2.orgChild2Order",
"orgChild2.orgChild2PhoneEx",
"orgChild2.orgChild2PhoneIn",
"orgChild2.orgChild2Fax",
"orgChild2.orgRootId",
"orgChild2.orgChild2Rank",
"orgChild2.orgChild2RankSub",
"orgChild2.DEPARTMENT_CODE",
"orgChild2.DIVISION_CODE",
"orgChild2.SECTION_CODE",
"orgChild2.JOB_CODE",
"orgChild2.orgChild1Id",
"orgChild2.responsibility",
])
.orderBy("orgChild2.orgChild2Order", "ASC")
.getMany()
: [];
const orgChild2Ids = orgChild2Data.map((orgChild2) => orgChild2.id) || null;
const orgChild3Data =
orgChild2Ids && orgChild2Ids.length > 0
? await AppDataSource.getRepository(OrgChild3)
.createQueryBuilder("orgChild3")
.where("orgChild3.orgChild2Id IN (:...ids)", { ids: orgChild2Ids })
.andWhere(
_data.child3 !== undefined && _data.child3 !== null
? _data.child3[0] !== null
? `orgChild3.id IN (:...node)`
: `orgChild3.id is null`
: "1=1",
{
node: _data.child3,
},
)
.select([
"orgChild3.id",
"orgChild3.misId",
"orgChild3.orgChild3Name",
"orgChild3.orgChild3ShortName",
"orgChild3.orgChild3Code",
"orgChild3.orgChild3Order",
"orgChild3.orgChild3PhoneEx",
"orgChild3.orgChild3PhoneIn",
"orgChild3.orgChild3Fax",
"orgChild3.orgRootId",
"orgChild3.orgChild3Rank",
"orgChild3.orgChild3RankSub",
"orgChild3.DEPARTMENT_CODE",
"orgChild3.DIVISION_CODE",
"orgChild3.SECTION_CODE",
"orgChild3.JOB_CODE",
"orgChild3.orgChild2Id",
"orgChild3.responsibility",
])
.orderBy("orgChild3.orgChild3Order", "ASC")
.getMany()
: [];
const orgChild3Ids = orgChild3Data.map((orgChild3) => orgChild3.id) || null;
const orgChild4Data =
orgChild3Ids && orgChild3Ids.length > 0
? await AppDataSource.getRepository(OrgChild4)
.createQueryBuilder("orgChild4")
.where("orgChild4.orgChild3Id IN (:...ids)", { ids: orgChild3Ids })
.andWhere(
_data.child4 !== undefined && _data.child4 !== null
? _data.child4[0] !== null
? `orgChild4.id IN (:...node)`
: `orgChild4.id is null`
: "1=1",
{
node: _data.child4,
},
)
.select([
"orgChild4.id",
"orgChild4.misId",
"orgChild4.orgChild4Name",
"orgChild4.orgChild4ShortName",
"orgChild4.orgChild4Code",
"orgChild4.orgChild4Order",
"orgChild4.orgChild4PhoneEx",
"orgChild4.orgChild4PhoneIn",
"orgChild4.orgChild4Fax",
"orgChild4.orgRootId",
"orgChild4.orgChild4Rank",
"orgChild4.orgChild4RankSub",
"orgChild4.DEPARTMENT_CODE",
"orgChild4.DIVISION_CODE",
"orgChild4.SECTION_CODE",
"orgChild4.JOB_CODE",
"orgChild4.orgChild3Id",
"orgChild4.responsibility",
])
.orderBy("orgChild4.orgChild4Order", "ASC")
.getMany()
: [];
const formattedData = await Promise.all(
orgRootData.map(async (orgRoot) => {
return {
orgTreeId: orgRoot.id,
orgLevel: 0,
misId: orgRoot.misId,
orgName: orgRoot.orgRootName,
orgTreeName: orgRoot.orgRootName,
orgTreeShortName: orgRoot.orgRootShortName,
orgTreeCode: orgRoot.orgRootCode,
orgCode: orgRoot.orgRootCode + "00",
orgTreeRank: orgRoot.orgRootRank,
orgTreeRankSub: orgRoot.orgRootRankSub,
DEPARTMENT_CODE: orgRoot.DEPARTMENT_CODE,
DIVISION_CODE: orgRoot.DIVISION_CODE,
SECTION_CODE: orgRoot.SECTION_CODE,
JOB_CODE: orgRoot.JOB_CODE,
orgTreeOrder: orgRoot.orgRootOrder,
orgTreePhoneEx: orgRoot.orgRootPhoneEx,
orgTreePhoneIn: orgRoot.orgRootPhoneIn,
orgTreeFax: orgRoot.orgRootFax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
isDeputy: orgRoot.isDeputy,
isCommission: orgRoot.isCommission,
responsibility: orgRoot.responsibility,
labelName:
orgRoot.orgRootName + " " + orgRoot.orgRootCode + "00" + " " + orgRoot.orgRootShortName,
children: await Promise.all(
orgChild1Data
.filter((orgChild1) => orgChild1.orgRootId === orgRoot.id)
.map(async (orgChild1) => ({
orgTreeId: orgChild1.id,
orgRootId: orgRoot.id,
orgLevel: 1,
misId: orgChild1.misId,
orgName: `${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild1.orgChild1Name,
orgTreeShortName: orgChild1.orgChild1ShortName,
orgTreeCode: orgChild1.orgChild1Code,
orgCode: orgRoot.orgRootCode + orgChild1.orgChild1Code,
orgTreeRank: orgChild1.orgChild1Rank,
orgTreeRankSub: orgChild1.orgChild1RankSub,
DEPARTMENT_CODE: orgChild1.DEPARTMENT_CODE,
DIVISION_CODE: orgChild1.DIVISION_CODE,
SECTION_CODE: orgChild1.SECTION_CODE,
JOB_CODE: orgChild1.JOB_CODE,
orgTreeOrder: orgChild1.orgChild1Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild1.orgChild1PhoneEx,
orgTreePhoneIn: orgChild1.orgChild1PhoneIn,
orgTreeFax: orgChild1.orgChild1Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild1.responsibility,
isOfficer: orgChild1.isOfficer,
isInformation: orgChild1.isInformation,
labelName:
orgChild1.orgChild1Name +
" " +
orgRoot.orgRootCode +
orgChild1.orgChild1Code +
" " +
orgChild1.orgChild1ShortName +
"/" +
orgRoot.orgRootName +
" " +
orgRoot.orgRootCode +
"00" +
" " +
orgRoot.orgRootShortName,
children: await Promise.all(
orgChild2Data
.filter((orgChild2) => orgChild2.orgChild1Id === orgChild1.id)
.map(async (orgChild2) => ({
orgTreeId: orgChild2.id,
orgRootId: orgChild1.id,
orgLevel: 2,
misId: orgChild2.misId,
orgName: `${orgChild2.orgChild2Name}/${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild2.orgChild2Name,
orgTreeShortName: orgChild2.orgChild2ShortName,
orgTreeCode: orgChild2.orgChild2Code,
orgCode: orgRoot.orgRootCode + orgChild2.orgChild2Code,
orgTreeRank: orgChild2.orgChild2Rank,
orgTreeRankSub: orgChild2.orgChild2RankSub,
DEPARTMENT_CODE: orgChild2.DEPARTMENT_CODE,
DIVISION_CODE: orgChild2.DIVISION_CODE,
SECTION_CODE: orgChild2.SECTION_CODE,
JOB_CODE: orgChild2.JOB_CODE,
orgTreeOrder: orgChild2.orgChild2Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild2.orgChild2PhoneEx,
orgTreePhoneIn: orgChild2.orgChild2PhoneIn,
orgTreeFax: orgChild2.orgChild2Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild2.responsibility,
labelName:
orgChild2.orgChild2Name +
" " +
orgRoot.orgRootCode +
orgChild2.orgChild2Code +
" " +
orgChild2.orgChild2ShortName +
"/" +
orgChild1.orgChild1Name +
" " +
orgRoot.orgRootCode +
orgChild1.orgChild1Code +
" " +
orgChild1.orgChild1ShortName +
"/" +
orgRoot.orgRootName +
" " +
orgRoot.orgRootCode +
"00" +
" " +
orgRoot.orgRootShortName,
children: await Promise.all(
orgChild3Data
.filter((orgChild3) => orgChild3.orgChild2Id === orgChild2.id)
.map(async (orgChild3) => ({
orgTreeId: orgChild3.id,
orgRootId: orgChild2.id,
orgLevel: 3,
misId: orgChild3.misId,
orgName: `${orgChild3.orgChild3Name}/${orgChild2.orgChild2Name}/${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild3.orgChild3Name,
orgTreeShortName: orgChild3.orgChild3ShortName,
orgTreeCode: orgChild3.orgChild3Code,
orgCode: orgRoot.orgRootCode + orgChild3.orgChild3Code,
orgTreeRank: orgChild3.orgChild3Rank,
orgTreeRankSub: orgChild3.orgChild3RankSub,
DEPARTMENT_CODE: orgChild3.DEPARTMENT_CODE,
DIVISION_CODE: orgChild3.DIVISION_CODE,
SECTION_CODE: orgChild3.SECTION_CODE,
JOB_CODE: orgChild3.JOB_CODE,
orgTreeOrder: orgChild3.orgChild3Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild3.orgChild3PhoneEx,
orgTreePhoneIn: orgChild3.orgChild3PhoneIn,
orgTreeFax: orgChild3.orgChild3Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild3.responsibility,
labelName:
orgChild3.orgChild3Name +
" " +
orgRoot.orgRootCode +
orgChild3.orgChild3Code +
" " +
orgChild3.orgChild3ShortName +
"/" +
orgChild2.orgChild2Name +
" " +
orgRoot.orgRootCode +
orgChild2.orgChild2Code +
" " +
orgChild2.orgChild2ShortName +
"/" +
orgChild1.orgChild1Name +
" " +
orgRoot.orgRootCode +
orgChild1.orgChild1Code +
" " +
orgChild1.orgChild1ShortName +
"/" +
orgRoot.orgRootName +
" " +
orgRoot.orgRootCode +
"00" +
" " +
orgRoot.orgRootShortName,
children: await Promise.all(
orgChild4Data
.filter((orgChild4) => orgChild4.orgChild3Id === orgChild3.id)
.map(async (orgChild4) => ({
orgTreeId: orgChild4.id,
orgRootId: orgChild3.id,
orgLevel: 4,
misId: orgChild4.misId,
orgName: `${orgChild4.orgChild4Name}/${orgChild3.orgChild3Name}/${orgChild2.orgChild2Name}/${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild4.orgChild4Name,
orgTreeShortName: orgChild4.orgChild4ShortName,
orgTreeCode: orgChild4.orgChild4Code,
orgCode: orgRoot.orgRootCode + orgChild4.orgChild4Code,
orgTreeRank: orgChild4.orgChild4Rank,
orgTreeRankSub: orgChild4.orgChild4RankSub,
DEPARTMENT_CODE: orgChild4.DEPARTMENT_CODE,
DIVISION_CODE: orgChild4.DIVISION_CODE,
SECTION_CODE: orgChild4.SECTION_CODE,
JOB_CODE: orgChild4.JOB_CODE,
orgTreeOrder: orgChild4.orgChild4Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild4.orgChild4PhoneEx,
orgTreePhoneIn: orgChild4.orgChild4PhoneIn,
orgTreeFax: orgChild4.orgChild4Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild4.responsibility,
labelName:
orgChild4.orgChild4Name +
" " +
orgRoot.orgRootCode +
orgChild4.orgChild4Code +
" " +
orgChild4.orgChild4ShortName +
"/" +
orgChild3.orgChild3Name +
" " +
orgRoot.orgRootCode +
orgChild3.orgChild3Code +
" " +
orgChild3.orgChild3ShortName +
"/" +
orgChild2.orgChild2Name +
" " +
orgRoot.orgRootCode +
orgChild2.orgChild2Code +
" " +
orgChild2.orgChild2ShortName +
"/" +
orgChild1.orgChild1Name +
" " +
orgRoot.orgRootCode +
orgChild1.orgChild1Code +
" " +
orgChild1.orgChild1ShortName +
"/" +
orgRoot.orgRootName +
" " +
orgRoot.orgRootCode +
"00" +
" " +
orgRoot.orgRootShortName,
})),
),
})),
),
})),
),
})),
),
};
}),
);
// return new HttpSuccess({ remark: _revision.remark, data: formattedData });
return new HttpSuccess({ remark: _revision.remark, data: formattedData });
}
/**
* API ตั้งเวลาเผยแพร่
*
* @summary ORG_025 - ตั้งเวลาเผยแพร่ (ADMIN) #27
*
* @param {string} id Id revison
*/
@Put("/set/publish/{id}")
async Edit(
@Path() id: string,
@Body() requestBody: { orgPublishDate: Date },
@Request() request: RequestWithUser,
) {
// await new permission().PermissionUpdate(request, "SYS_ORG");//ไม่แน่ใจOFFปิดไว้ก่อน
const orgRevision = await this.orgRevisionRepository.findOne({
where: {
id: id,
orgRevisionIsDraft: true,
orgRevisionIsCurrent: false,
},
});
if (!orgRevision) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found. RevisionId");
}
const before = structuredClone(orgRevision);
orgRevision.lastUpdateUserId = request.user.sub;
orgRevision.lastUpdateFullName = request.user.name;
orgRevision.lastUpdatedAt = new Date();
orgRevision.orgPublishDate = requestBody.orgPublishDate;
this.orgRevisionRepository.merge(orgRevision, requestBody);
await this.orgRevisionRepository.save(orgRevision, { data: request });
setLogDataDiff(request, { before, after: orgRevision });
return new HttpSuccess();
}
/**
* API ประวัติหน่วยงาน
*
* @summary ORG_039 - ประวัติหน่วยงาน (ADMIN) #42
*
*/
@Post("/history/publish")
async GetHistoryPublish(
@Body()
requestBody: {
id: string;
type: number;
},
@Request() request: RequestWithUser,
) {
if (requestBody.type == 1) {
const orgChild1 = await this.child1Repository.findOne({
where: { id: requestBody.id },
});
if (!orgChild1) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found. Child1");
}
const datas = await this.child1Repository
.createQueryBuilder("child1")
.where("child1.ancestorDNA = :ancestorDNA", { ancestorDNA: orgChild1.ancestorDNA })
.andWhere("child1.ancestorDNA <> :nullUUID", {
nullUUID: "00000000-0000-0000-0000-000000000000",
})
.andWhere("child1.ancestorDNA IS NOT NULL")
.leftJoinAndSelect("child1.orgRevision", "orgRevision")
.orderBy("child1.lastUpdatedAt", "DESC")
.getMany();
const _data = datas.map((item) => ({
id: item.id,
orgRevisionName: item.orgRevision == null ? null : item.orgRevision.orgRevisionName,
name: item.orgChild1Name,
lastUpdatedAt: item.lastUpdatedAt,
}));
return new HttpSuccess(_data);
} else if (requestBody.type == 2) {
const orgChild2 = await this.child2Repository.findOne({
where: { id: requestBody.id },
});
if (!orgChild2) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found. Child2");
}
const datas = await this.child2Repository
.createQueryBuilder("child2")
.where("child2.ancestorDNA = :ancestorDNA", { ancestorDNA: orgChild2.ancestorDNA })
.andWhere("child2.ancestorDNA <> :nullUUID", {
nullUUID: "00000000-0000-0000-0000-000000000000",
})
.andWhere("child2.ancestorDNA IS NOT NULL")
.leftJoinAndSelect("child2.orgRevision", "orgRevision")
.orderBy("child2.lastUpdatedAt", "DESC")
.getMany();
const _data = datas.map((item) => ({
id: item.id,
orgRevisionName: item.orgRevision == null ? null : item.orgRevision.orgRevisionName,
name: item.orgChild2Name,
lastUpdatedAt: item.lastUpdatedAt,
}));
return new HttpSuccess(_data);
} else if (requestBody.type == 3) {
const orgChild3 = await this.child3Repository.findOne({
where: { id: requestBody.id },
});
if (!orgChild3) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found. Child3");
}
const datas = await this.child3Repository
.createQueryBuilder("child3")
.where("child3.ancestorDNA = :ancestorDNA", { ancestorDNA: orgChild3.ancestorDNA })
.andWhere("child3.ancestorDNA <> :nullUUID", {
nullUUID: "00000000-0000-0000-0000-000000000000",
})
.andWhere("child3.ancestorDNA IS NOT NULL")
.leftJoinAndSelect("child3.orgRevision", "orgRevision")
.orderBy("child3.lastUpdatedAt", "DESC")
.getMany();
const _data = datas.map((item) => ({
id: item.id,
orgRevisionName: item.orgRevision == null ? null : item.orgRevision.orgRevisionName,
name: item.orgChild3Name,
lastUpdatedAt: item.lastUpdatedAt,
}));
return new HttpSuccess(_data);
} else if (requestBody.type == 4) {
const orgChild4 = await this.child4Repository.findOne({
where: { id: requestBody.id },
});
if (!orgChild4) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found. Child4");
}
const datas = await this.child4Repository
.createQueryBuilder("child4")
.where("child4.ancestorDNA = :ancestorDNA", { ancestorDNA: orgChild4.ancestorDNA })
.andWhere("child4.ancestorDNA <> :nullUUID", {
nullUUID: "00000000-0000-0000-0000-000000000000",
})
.andWhere("child4.ancestorDNA IS NOT NULL")
.leftJoinAndSelect("child4.orgRevision", "orgRevision")
.orderBy("child4.lastUpdatedAt", "DESC")
.getMany();
const _data = datas.map((item) => ({
id: item.id,
orgRevisionName: item.orgRevision == null ? null : item.orgRevision.orgRevisionName,
name: item.orgChild4Name,
lastUpdatedAt: item.lastUpdatedAt,
}));
return new HttpSuccess(_data);
} else {
const orgRoot = await this.orgRootRepository.findOne({
where: { id: requestBody.id },
});
if (!orgRoot) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found. Root");
}
const datas = await this.orgRootRepository
.createQueryBuilder("root")
.where("root.ancestorDNA = :ancestorDNA", { ancestorDNA: orgRoot.ancestorDNA })
.andWhere("root.ancestorDNA <> :nullUUID", {
nullUUID: "00000000-0000-0000-0000-000000000000",
})
.andWhere("root.ancestorDNA IS NOT NULL")
.leftJoinAndSelect("root.orgRevision", "orgRevision")
.orderBy("root.lastUpdatedAt", "DESC")
.getMany();
const _data = datas.map((item) => ({
id: item.id,
orgRevisionName: item.orgRevision == null ? null : item.orgRevision.orgRevisionName,
name: item.orgRootName,
lastUpdatedAt: item.lastUpdatedAt,
}));
return new HttpSuccess(_data);
}
}
/**
* API จัดลำดับโครงสร้าง
*
* @summary ORG_038 - จัดลำดับโครงสร้าง (ADMIN) #41
*
*/
@Post("sort")
async Sort(
@Body() requestBody: { id: string; type: number; sortId: string[] },
@Request() request: RequestWithUser,
) {
await new permission().PermissionUpdate(request, "SYS_ORG");
const before = null;
switch (requestBody.type) {
case 0: {
const revisionId = await this.orgRevisionRepository.findOne({
where: { id: requestBody.id },
});
if (!revisionId?.id) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found revisionId: " + requestBody.id);
}
const listRootId = await this.orgRootRepository.find({
where: { orgRevisionId: requestBody.id },
select: ["id", "orgRootOrder"],
});
if (!listRootId) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found rootId.");
}
const sortData = listRootId.map((data) => ({
id: data.id,
orgRootOrder: requestBody.sortId.indexOf(data.id) + 1,
}));
await this.orgRootRepository.save(sortData, { data: request });
setLogDataDiff(request, { before, after: sortData });
break;
}
case 1: {
const rootId = await this.orgRootRepository.findOne({ where: { id: requestBody.id } });
if (!rootId?.id) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found rootId: " + requestBody.id);
}
const listChild1Id = await this.child1Repository.find({
where: { orgRootId: requestBody.id },
select: ["id", "orgChild1Order"],
});
if (!listChild1Id) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child1Id.");
}
const sortData = listChild1Id.map((data) => ({
id: data.id,
orgChild1Order: requestBody.sortId.indexOf(data.id) + 1,
}));
await this.child1Repository.save(sortData, { data: request });
setLogDataDiff(request, { before, after: sortData });
break;
}
case 2: {
const child1Id = await this.child1Repository.findOne({ where: { id: requestBody.id } });
if (!child1Id?.id) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child1Id: " + requestBody.id);
}
const listChild2Id = await this.child2Repository.find({
where: { orgChild1Id: requestBody.id },
select: ["id", "orgChild2Order"],
});
if (!listChild2Id) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child2Id.");
}
const sortData = listChild2Id.map((data) => ({
id: data.id,
orgChild2Order: requestBody.sortId.indexOf(data.id) + 1,
}));
await this.child2Repository.save(sortData, { data: request });
setLogDataDiff(request, { before, after: sortData });
break;
}
case 3: {
const child2Id = await this.child2Repository.findOne({ where: { id: requestBody.id } });
if (!child2Id?.id) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child2Id: " + requestBody.id);
}
const listChild3Id = await this.child3Repository.find({
where: { orgChild2Id: requestBody.id },
select: ["id", "orgChild3Order"],
});
if (!listChild3Id) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child3Id.");
}
const sortData = listChild3Id.map((data) => ({
id: data.id,
orgChild3Order: requestBody.sortId.indexOf(data.id) + 1,
}));
await this.child3Repository.save(sortData, { data: request });
setLogDataDiff(request, { before, after: sortData });
break;
}
case 4: {
const child3Id = await this.child3Repository.findOne({ where: { id: requestBody.id } });
if (!child3Id?.id) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child3Id: " + requestBody.id);
}
const listChild4Id = await this.child4Repository.find({
where: { orgChild3Id: requestBody.id },
select: ["id", "orgChild4Order"],
});
if (!listChild4Id) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child4Id.");
}
const sortData = listChild4Id.map((data) => ({
id: data.id,
orgChild4Order: requestBody.sortId.indexOf(data.id) + 1,
}));
await this.child4Repository.save(sortData, { data: request });
setLogDataDiff(request, { before, after: sortData });
break;
}
default:
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found type: " + requestBody.type);
}
return new HttpSuccess();
}
/**
* API เผยแพร่ข้อมูล
*
* @summary ORG_071 - เผยแพร่ข้อมูล (ADMIN) #57
*
* @param {string} id Id revison
*/
@Get("get/publish")
async runPublish(@Request() request: RequestWithUser) {
try {
// CheckQueueInProgress
// console.log("🚀 ตรวจสอบว่ามีงานอยู่ในคิว");
const [isBusyDraft, isBusyPublish] = await Promise.all([
checkQueueInProgress(`${process.env.AMQ_QUEUE_ORG_DRAFT}`),
checkQueueInProgress(`${process.env.AMQ_QUEUE_ORG}`),
]);
// console.log("✅ ตรวจสอบแล้ว Draft Busy:", isBusyDraft);
// console.log("✅ ตรวจสอบแล้ว Publish Busy:", isBusyPublish);
if (isBusyDraft || isBusyPublish) {
// console.log("🚫 พบว่ามีงานอยู่ในคิว — error")
throw new HttpError(
HttpStatusCode.CONFLICT,
"ไม่สามารถดำเนินการได้ หากกำลังเผยแพร่หรือสร้างแบบร่างโครงสร้างหน่วยงาน",
);
}
const today = new Date();
today.setHours(0, 0, 0, 0); // Set time to the beginning of the day
const orgRevisionDraft = await this.orgRevisionRepository
.createQueryBuilder("orgRevision")
.where("orgRevision.orgRevisionIsDraft = true")
.andWhere("orgRevision.orgRevisionIsCurrent = false")
// .andWhere("DATE(orgRevision.orgPublishDate) = :today", { today })
.getOne();
if (!orgRevisionDraft) {
return new HttpSuccess();
// throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่มีข้อมูลเผยแพร่");
}
// if (orgRevisionPublish) {
// orgRevisionPublish.orgRevisionIsDraft = false;
// orgRevisionPublish.orgRevisionIsCurrent = false;
// await this.orgRevisionRepository.save(orgRevisionPublish);
// }
// orgRevisionDraft.orgRevisionIsCurrent = true;
// orgRevisionDraft.orgRevisionIsDraft = false;
// await this.orgRevisionRepository.save(orgRevisionDraft);
const msg = {
data: {
id: orgRevisionDraft.id,
status: "NOW",
lastUpdateUserId: request.user.sub,
lastUpdateFullName: request.user.name,
lastUpdatedAt: new Date(),
},
user: request.user,
token: request.headers["authorization"],
};
await sendToQueueOrg(msg);
return new HttpSuccess();
} catch (error: any) {
throw error;
}
}
/**
* Cronjob
*/
async cronjobRevision() {
const today = new Date();
today.setUTCHours(0, 0, 0, 0); // Set time to the beginning of the day
const tomorrow = new Date(today);
tomorrow.setDate(tomorrow.getDate() + 1);
const orgRevisionDraft = await this.orgRevisionRepository
.createQueryBuilder("orgRevision")
.where("orgRevision.orgRevisionIsDraft = true")
.andWhere("orgRevision.orgRevisionIsCurrent = false")
.andWhere("orgRevision.orgPublishDate BETWEEN :today AND :tomorrow", { today, tomorrow })
.getOne();
if (!orgRevisionDraft) {
return new HttpSuccess();
}
// if (orgRevisionPublish) {
// orgRevisionPublish.orgRevisionIsDraft = false;
// orgRevisionPublish.orgRevisionIsCurrent = false;
// await this.orgRevisionRepository.save(orgRevisionPublish);
// }
// orgRevisionDraft.orgRevisionIsCurrent = true;
// orgRevisionDraft.orgRevisionIsDraft = false;
// await this.orgRevisionRepository.save(orgRevisionDraft);
// const posMaster = await this.posMasterRepository.find({
// where: { orgRevisionId: orgRevisionDraft.id },
// });
// posMaster.forEach(async (item) => {
// // if(item.next_holderId != null){
// item.current_holderId = item.next_holderId;
// item.next_holderId = null;
// await this.posMasterRepository.save(item);
// // }
// });
const msg = {
data: {
id: orgRevisionDraft.id,
status: "ON_SCHEDULE",
lastUpdateUserId: "system",
lastUpdateFullName: "system",
lastUpdatedAt: new Date(),
},
};
sendToQueueOrg(msg);
return new HttpSuccess();
}
/**
* API Organizational Chart
*
* @summary Organizational Chart
*
* @param {string} revisionId Id revison
*/
@Get("org-chart/{revisionId}")
async orgchart(@Path() revisionId: string) {
const data = await this.orgRevisionRepository.findOne({
where: { id: revisionId },
});
if (!data) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโครงสร้าง");
}
let posMasterRoot: any;
let posMasterChild1: any;
let posMasterChild2: any;
let posMasterChild3: any;
let posMasterChild4: any;
if (data.orgRevisionIsCurrent == true && data.orgRevisionIsDraft == false) {
// ใช้ query เดียวแทน 5 queries แยก เพื่อความเร็วในการทำงาน
const allPosMasters = await this.posMasterRepository.find({
where: {
orgRevisionId: data.id,
},
relations: [
"current_holder",
"orgRoot",
"orgChild1",
"orgChild2",
"orgChild3",
"orgChild4",
],
order: {
orgRoot: {
orgRootOrder: "ASC",
},
posMasterOrder: "ASC",
posMasterNo: "ASC",
},
});
// แยกข้อมูลด้วย JavaScript แทนการใช้ database queries หลาย ๆ ครั้ง
posMasterRoot = allPosMasters.filter((item) => item.orgChild1Id === null);
posMasterChild1 = allPosMasters.filter(
(item) => item.orgChild2Id === null && item.orgChild1Id !== null,
);
posMasterChild2 = allPosMasters.filter(
(item) => item.orgChild3Id === null && item.orgChild2Id !== null,
);
posMasterChild3 = allPosMasters.filter(
(item) => item.orgChild4Id === null && item.orgChild3Id !== null,
);
posMasterChild4 = allPosMasters.filter((item) => item.orgChild4Id !== null);
// สร้าง Maps เพื่อ lookup ที่เร็วขึ้น แทนการใช้ filter หลายรอบ
const rootByOrgRootId = new Map<string, PosMaster[]>();
const child1ByOrgRootId = new Map<string, PosMaster[]>();
const child1ByOrgChild1Id = new Map<string, PosMaster[]>();
const child2ByOrgChild1Id = new Map<string, PosMaster[]>();
const child2ByOrgChild2Id = new Map<string, PosMaster[]>();
const child3ByOrgChild2Id = new Map<string, PosMaster[]>();
const child3ByOrgChild3Id = new Map<string, PosMaster[]>();
const child4ByOrgChild3Id = new Map<string, PosMaster[]>();
// Pre-compute all lookups เพื่อหลีกเลี่ยงการ filter ซ้ำๆ
posMasterRoot.forEach((item: PosMaster) => {
if (item.current_holderId) {
if (item.isDirector) {
// Root directors will be processed in main loop
} else {
// Group root non-directors by orgRootId
const key = item.orgRootId || "";
if (!rootByOrgRootId.has(key)) rootByOrgRootId.set(key, []);
rootByOrgRootId.get(key)!.push(item);
}
}
});
posMasterChild1.forEach((item: PosMaster) => {
if (item.isDirector) {
// Group child1 directors by orgRootId
const key = item.orgRootId || "";
if (!child1ByOrgRootId.has(key)) child1ByOrgRootId.set(key, []);
child1ByOrgRootId.get(key)!.push(item);
} else if (item.current_holderId) {
// Group child1 non-directors by orgChild1Id
const key = item.orgChild1Id || "";
if (!child1ByOrgChild1Id.has(key)) child1ByOrgChild1Id.set(key, []);
child1ByOrgChild1Id.get(key)!.push(item);
}
});
posMasterChild2.forEach((item: PosMaster) => {
if (item.isDirector) {
// Group child2 directors by orgChild1Id
const key = item.orgChild1Id || "";
if (!child2ByOrgChild1Id.has(key)) child2ByOrgChild1Id.set(key, []);
child2ByOrgChild1Id.get(key)!.push(item);
} else if (item.current_holderId) {
// Group child2 non-directors by orgChild2Id
const key = item.orgChild2Id || "";
if (!child2ByOrgChild2Id.has(key)) child2ByOrgChild2Id.set(key, []);
child2ByOrgChild2Id.get(key)!.push(item);
}
});
posMasterChild3.forEach((item: PosMaster) => {
if (item.isDirector) {
// Group child3 directors by orgChild2Id
const key = item.orgChild2Id || "";
if (!child3ByOrgChild2Id.has(key)) child3ByOrgChild2Id.set(key, []);
child3ByOrgChild2Id.get(key)!.push(item);
} else if (item.current_holderId) {
// Group child3 non-directors by orgChild3Id
const key = item.orgChild3Id || "";
if (!child3ByOrgChild3Id.has(key)) child3ByOrgChild3Id.set(key, []);
child3ByOrgChild3Id.get(key)!.push(item);
}
});
posMasterChild4.forEach((item: PosMaster) => {
if (item.isDirector) {
// Group child4 directors by orgChild3Id
const key = item.orgChild3Id || "";
if (!child4ByOrgChild3Id.has(key)) child4ByOrgChild3Id.set(key, []);
child4ByOrgChild3Id.get(key)!.push(item);
}
});
// Helper function เพื่อสร้าง node object
const createNode = (item: PosMaster, level: number, holder: any, orgInfo: any) => ({
level,
personID: holder?.id ?? "",
name: holder ? `${holder.firstName} ${holder.lastName}` : "ว่าง",
avatar:
holder?.avatar && holder?.avatarName ? `${holder.avatar}/${holder.avatarName}` : null,
positionName: holder?.position ?? "",
positionNum: `${orgInfo.shortName} ${item.posMasterNo}`,
positionNumInt: item.posMasterNo,
departmentName: orgInfo.name,
organizationId: orgInfo.id,
children: [] as any[],
});
let formattedData = posMasterRoot
.filter((x: any) => x.current_holderId != null && x.isDirector)
.map((x0: PosMaster) => {
const childLevel1: any[] = [];
// Add root non-directors (Level 2)
const rootNonDirectors = rootByOrgRootId.get(x0.orgRootId || "") || [];
rootNonDirectors.forEach((x00: PosMaster) => {
childLevel1.push(
createNode(x00, 2, x00.current_holder, {
shortName: x00.orgRoot.orgRootShortName,
name: x00.orgRoot.orgRootName,
id: x00.orgRoot.id,
}),
);
});
// Add child1 directors (Level 2)
const child1Directors = child1ByOrgRootId.get(x0.orgRootId || "") || [];
child1Directors.forEach((x1: PosMaster) => {
const childLevel2: any[] = [];
// Add child1 non-directors (Level 3)
const child1NonDirectors = child1ByOrgChild1Id.get(x1.orgChild1Id || "") || [];
child1NonDirectors.forEach((x11: PosMaster) => {
childLevel2.push(
createNode(x11, 3, x11.current_holder, {
shortName: x11.orgChild1.orgChild1ShortName,
name: x11.orgChild1.orgChild1Name,
id: x11.orgChild1.id,
}),
);
});
// Add child2 directors (Level 3)
const child2Directors = child2ByOrgChild1Id.get(x1.orgChild1Id || "") || [];
child2Directors.forEach((x2: PosMaster) => {
const childLevel3: any[] = [];
// Add child2 non-directors (Level 4)
const child2NonDirectors = child2ByOrgChild2Id.get(x2.orgChild2Id || "") || [];
child2NonDirectors.forEach((x22: PosMaster) => {
childLevel3.push(
createNode(x22, 4, x22.current_holder, {
shortName: x22.orgChild2.orgChild2ShortName,
name: x22.orgChild2.orgChild2Name,
id: x22.orgChild2.id,
}),
);
});
// Add child3 directors (Level 4)
const child3Directors = child3ByOrgChild2Id.get(x2.orgChild2Id || "") || [];
child3Directors.forEach((x3: PosMaster) => {
const childLevel4: any[] = [];
// Add child3 non-directors (Level 5)
const child3NonDirectors = child3ByOrgChild3Id.get(x3.orgChild3Id || "") || [];
child3NonDirectors.forEach((x33: PosMaster) => {
childLevel4.push(
createNode(x33, 5, x33.current_holder, {
shortName: x33.orgChild3.orgChild3ShortName,
name: x33.orgChild3.orgChild3Name,
id: x33.orgChild3.id,
}),
);
});
// Add child4 directors (Level 5)
const child4Directors = child4ByOrgChild3Id.get(x3.orgChild3Id || "") || [];
child4Directors.forEach((x4: PosMaster) => {
const childLevel5: any[] = [];
// Add child4 non-directors (Level 5)
posMasterChild4
.filter(
(x: PosMaster) =>
!x.isDirector && x.current_holderId && x.orgChild3Id === x4.orgChild3Id,
)
.forEach((x44: PosMaster) => {
childLevel5.push(
createNode(x44, 5, x44.current_holder, {
shortName: x44.orgChild4.orgChild4ShortName,
name: x44.orgChild4.orgChild4Name,
id: x44.orgChild4.id,
}),
);
});
const child4Node = createNode(x4, 4, x4.current_holder, {
shortName: x4.orgChild4.orgChild4ShortName,
name: x4.orgChild4.orgChild4Name,
id: x4.orgChild4.id,
});
child4Node.children = childLevel5;
childLevel4.push(child4Node);
});
const child3Node = createNode(x3, 4, x3.current_holder, {
shortName: x3.orgChild3.orgChild3ShortName,
name: x3.orgChild3.orgChild3Name,
id: x3.orgChild3.id,
});
child3Node.children = childLevel4;
childLevel3.push(child3Node);
});
const child2Node = createNode(x2, 3, x2.current_holder, {
shortName: x2.orgChild2.orgChild2ShortName,
name: x2.orgChild2.orgChild2Name,
id: x2.orgChild2.id,
});
child2Node.children = childLevel3;
childLevel2.push(child2Node);
});
const child1Node = createNode(x1, 2, x1.current_holder, {
shortName: x1.orgChild1.orgChild1ShortName,
name: x1.orgChild1.orgChild1Name,
id: x1.orgChild1.id,
});
child1Node.children = childLevel2;
childLevel1.push(child1Node);
});
// Root Level 1
const rootNode = createNode(x0, 1, x0.current_holder, {
shortName: x0.orgRoot.orgRootShortName,
name: x0.orgRoot.orgRootName,
id: x0.orgRoot.id,
});
rootNode.children = childLevel1;
return rootNode;
});
const formattedData_ = {
personID: "",
name: "",
avatar: "",
positionName: "",
positionNum: "",
positionNumInt: null,
departmentName: data.orgRevisionName,
organizationId: data.id,
children: formattedData,
};
return new HttpSuccess([formattedData_]);
} else if (data.orgRevisionIsCurrent == false && data.orgRevisionIsDraft == true) {
// ใช้ query เดียวแทน 5 queries แยก เพื่อความเร็วในการทำงาน
const allPosMasters = await this.posMasterRepository.find({
where: {
orgRevisionId: data.id,
// next_holderId: Not(IsNull()),
},
relations: ["next_holder", "orgRoot", "orgChild1", "orgChild2", "orgChild3", "orgChild4"],
});
// แยกข้อมูลด้วย JavaScript แทนการใช้ database queries หลาย ๆ ครั้ง
posMasterRoot = allPosMasters.filter((item) => item.orgChild1Id === null);
posMasterChild1 = allPosMasters.filter(
(item) => item.orgChild2Id === null && item.orgChild1Id !== null,
);
posMasterChild2 = allPosMasters.filter(
(item) => item.orgChild3Id === null && item.orgChild2Id !== null,
);
posMasterChild3 = allPosMasters.filter(
(item) => item.orgChild4Id === null && item.orgChild3Id !== null,
);
posMasterChild4 = allPosMasters.filter((item) => item.orgChild4Id !== null);
// สร้าง Maps เพื่อ lookup ที่เร็วขึ้น แทนการใช้ filter หลายรอบ สำหรับ draft version
const rootByOrgRootIdDraft = new Map<string, PosMaster[]>();
const child1ByOrgRootIdDraft = new Map<string, PosMaster[]>();
const child1ByOrgChild1IdDraft = new Map<string, PosMaster[]>();
const child2ByOrgChild1IdDraft = new Map<string, PosMaster[]>();
const child2ByOrgChild2IdDraft = new Map<string, PosMaster[]>();
const child3ByOrgChild2IdDraft = new Map<string, PosMaster[]>();
const child3ByOrgChild3IdDraft = new Map<string, PosMaster[]>();
const child4ByOrgChild3IdDraft = new Map<string, PosMaster[]>();
// Pre-compute all lookups เพื่อหลีกเลี่ยงการ filter ซ้ำๆ สำหรับ draft version
posMasterRoot.forEach((item: PosMaster) => {
if (item.next_holderId) {
if (item.isDirector) {
// Root directors will be processed in main loop
} else {
// Group root non-directors by orgRootId
const key = item.orgRootId || "";
if (!rootByOrgRootIdDraft.has(key)) rootByOrgRootIdDraft.set(key, []);
rootByOrgRootIdDraft.get(key)!.push(item);
}
}
});
posMasterChild1.forEach((item: PosMaster) => {
if (item.isDirector) {
// Group child1 directors by orgRootId
const key = item.orgRootId || "";
if (!child1ByOrgRootIdDraft.has(key)) child1ByOrgRootIdDraft.set(key, []);
child1ByOrgRootIdDraft.get(key)!.push(item);
} else if (item.next_holderId) {
// Group child1 non-directors by orgChild1Id
const key = item.orgChild1Id || "";
if (!child1ByOrgChild1IdDraft.has(key)) child1ByOrgChild1IdDraft.set(key, []);
child1ByOrgChild1IdDraft.get(key)!.push(item);
}
});
posMasterChild2.forEach((item: PosMaster) => {
if (item.isDirector) {
// Group child2 directors by orgChild1Id
const key = item.orgChild1Id || "";
if (!child2ByOrgChild1IdDraft.has(key)) child2ByOrgChild1IdDraft.set(key, []);
child2ByOrgChild1IdDraft.get(key)!.push(item);
} else if (item.next_holderId) {
// Group child2 non-directors by orgChild2Id
const key = item.orgChild2Id || "";
if (!child2ByOrgChild2IdDraft.has(key)) child2ByOrgChild2IdDraft.set(key, []);
child2ByOrgChild2IdDraft.get(key)!.push(item);
}
});
posMasterChild3.forEach((item: PosMaster) => {
if (item.isDirector) {
// Group child3 directors by orgChild2Id
const key = item.orgChild2Id || "";
if (!child3ByOrgChild2IdDraft.has(key)) child3ByOrgChild2IdDraft.set(key, []);
child3ByOrgChild2IdDraft.get(key)!.push(item);
} else if (item.next_holderId) {
// Group child3 non-directors by orgChild3Id
const key = item.orgChild3Id || "";
if (!child3ByOrgChild3IdDraft.has(key)) child3ByOrgChild3IdDraft.set(key, []);
child3ByOrgChild3IdDraft.get(key)!.push(item);
}
});
posMasterChild4.forEach((item: PosMaster) => {
if (item.isDirector) {
// Group child4 directors by orgChild3Id
const key = item.orgChild3Id || "";
if (!child4ByOrgChild3IdDraft.has(key)) child4ByOrgChild3IdDraft.set(key, []);
child4ByOrgChild3IdDraft.get(key)!.push(item);
}
});
// Helper function เพื่อสร้าง node object สำหรับ draft version
const createNodeDraft = (item: PosMaster, level: number, holder: any, orgInfo: any) => ({
level,
personID: holder?.id ?? "",
name: holder ? `${holder.firstName} ${holder.lastName}` : "ว่าง",
avatar:
holder?.avatar && holder?.avatarName ? `${holder.avatar}/${holder.avatarName}` : null,
positionName: holder?.position ?? "",
positionNum: `${orgInfo.shortName} ${item.posMasterNo}`,
positionNumInt: item.posMasterNo,
departmentName: orgInfo.name,
organizationId: orgInfo.id,
children: [] as any[],
});
let formattedData = posMasterRoot
.filter((x: any) => x.next_holderId != null && x.isDirector)
.map((x0: PosMaster) => {
const childLevel1: any[] = [];
// Add root non-directors (Level 2)
const rootNonDirectors = rootByOrgRootIdDraft.get(x0.orgRootId || "") || [];
rootNonDirectors.forEach((x00: PosMaster) => {
childLevel1.push(
createNodeDraft(x00, 2, x00.next_holder, {
shortName: x00.orgRoot.orgRootShortName,
name: x00.orgRoot.orgRootName,
id: x00.orgRoot.id,
}),
);
});
// Add child1 directors (Level 2)
const child1Directors = child1ByOrgRootIdDraft.get(x0.orgRootId || "") || [];
child1Directors.forEach((x1: PosMaster) => {
const childLevel2: any[] = [];
// Add child1 non-directors (Level 3)
const child1NonDirectors = child1ByOrgChild1IdDraft.get(x1.orgChild1Id || "") || [];
child1NonDirectors.forEach((x11: PosMaster) => {
childLevel2.push(
createNodeDraft(x11, 3, x11.next_holder, {
shortName: x11.orgChild1.orgChild1ShortName,
name: x11.orgChild1.orgChild1Name,
id: x11.orgChild1.id,
}),
);
});
// Add child2 directors (Level 3)
const child2Directors = child2ByOrgChild1IdDraft.get(x1.orgChild1Id || "") || [];
child2Directors.forEach((x2: PosMaster) => {
const childLevel3: any[] = [];
// Add child2 non-directors (Level 4)
const child2NonDirectors = child2ByOrgChild2IdDraft.get(x2.orgChild2Id || "") || [];
child2NonDirectors.forEach((x22: PosMaster) => {
childLevel3.push(
createNodeDraft(x22, 4, x22.next_holder, {
shortName: x22.orgChild2.orgChild2ShortName,
name: x22.orgChild2.orgChild2Name,
id: x22.orgChild2.id,
}),
);
});
// Add child3 directors (Level 4)
const child3Directors = child3ByOrgChild2IdDraft.get(x2.orgChild2Id || "") || [];
child3Directors.forEach((x3: PosMaster) => {
const childLevel4: any[] = [];
// Add child3 non-directors (Level 5)
const child3NonDirectors = child3ByOrgChild3IdDraft.get(x3.orgChild3Id || "") || [];
child3NonDirectors.forEach((x33: PosMaster) => {
childLevel4.push(
createNodeDraft(x33, 5, x33.next_holder, {
shortName: x33.orgChild3.orgChild3ShortName,
name: x33.orgChild3.orgChild3Name,
id: x33.orgChild3.id,
}),
);
});
// Add child4 directors (Level 5)
const child4Directors = child4ByOrgChild3IdDraft.get(x3.orgChild3Id || "") || [];
child4Directors.forEach((x4: PosMaster) => {
const childLevel5: any[] = [];
// Add child4 non-directors (Level 5)
posMasterChild4
.filter(
(x: PosMaster) =>
!x.isDirector && x.next_holderId && x.orgChild3Id === x4.orgChild3Id,
)
.forEach((x44: PosMaster) => {
childLevel5.push(
createNodeDraft(x44, 5, x44.next_holder, {
shortName: x44.orgChild4.orgChild4ShortName,
name: x44.orgChild4.orgChild4Name,
id: x44.orgChild4.id,
}),
);
});
const child4Node = createNodeDraft(x4, 4, x4.next_holder, {
shortName: x4.orgChild4.orgChild4ShortName,
name: x4.orgChild4.orgChild4Name,
id: x4.orgChild4.id,
});
child4Node.children = childLevel5;
childLevel4.push(child4Node);
});
const child3Node = createNodeDraft(x3, 4, x3.next_holder, {
shortName: x3.orgChild3.orgChild3ShortName,
name: x3.orgChild3.orgChild3Name,
id: x3.orgChild3.id,
});
child3Node.children = childLevel4;
childLevel3.push(child3Node);
});
const child2Node = createNodeDraft(x2, 3, x2.next_holder, {
shortName: x2.orgChild2.orgChild2ShortName,
name: x2.orgChild2.orgChild2Name,
id: x2.orgChild2.id,
});
child2Node.children = childLevel3;
childLevel2.push(child2Node);
});
const child1Node = createNodeDraft(x1, 2, x1.next_holder, {
shortName: x1.orgChild1.orgChild1ShortName,
name: x1.orgChild1.orgChild1Name,
id: x1.orgChild1.id,
});
child1Node.children = childLevel2;
childLevel1.push(child1Node);
});
// Root Level 1
const rootNode = createNodeDraft(x0, 1, x0.next_holder, {
shortName: x0.orgRoot.orgRootShortName,
name: x0.orgRoot.orgRootName,
id: x0.orgRoot.id,
});
rootNode.children = childLevel1;
return rootNode;
});
const formattedData_ = {
personID: "",
name: "",
avatar: "",
positionName: "",
positionNum: "",
positionNumInt: null,
departmentName: data.orgRevisionName,
organizationId: data.id,
children: formattedData,
};
return new HttpSuccess([formattedData_]);
} else {
return new HttpSuccess([
{
personID: "",
name: "",
avatar: "",
positionName: "",
positionNum: "",
positionNumInt: null,
departmentName: data.orgRevisionName,
organizationId: data.id,
children: [],
},
]);
}
}
/**
* API Organizational Chart
*
* @summary Organizational Chart
*
* @param {string} revisionId Id revison
*/
@Get("org-chart/{revisionId}/{rootId}")
async orgChartByRoot(@Path() revisionId: string, @Path() rootId: string) {
// get revision data
const data = await this.orgRevisionRepository.findOne({ where: { id: revisionId } });
if (!data) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลโครงสร้าง");
}
type OrgInfo = { shortName: string; name: string; id: string };
let fieldId: "current_holderId" | "next_holderId" = "current_holderId";
let relations: string[] =
rootId === "root"
? ["current_holder", "orgRoot"]
: ["current_holder", "orgRoot", "orgChild1", "orgChild2", "orgChild3", "orgChild4"];
if (data.orgRevisionIsCurrent === false && data.orgRevisionIsDraft === true) {
fieldId = "next_holderId";
relations =
rootId === "root"
? ["next_holder", "orgRoot"]
: ["next_holder", "orgRoot", "orgChild1", "orgChild2", "orgChild3", "orgChild4"];
}
const where =
rootId === "root"
? { orgRevisionId: data.id, posMasterNo: 1 }
: { orgRevisionId: data.id, orgRootId: rootId };
const allPosMasters = await this.posMasterRepository.find({
where,
relations,
order: {
orgRoot: { orgRootOrder: "ASC" },
posMasterOrder: "ASC",
posMasterNo: "ASC",
},
});
// Split positions by level
const posMasterRoot = allPosMasters.filter((item) => item.orgChild1Id === null);
const posMasterChild1 =
rootId !== "root"
? allPosMasters.filter((item) => item.orgChild2Id === null && item.orgChild1Id !== null)
: [];
const posMasterChild2 =
rootId !== "root"
? allPosMasters.filter((item) => item.orgChild3Id === null && item.orgChild2Id !== null)
: [];
const posMasterChild3 =
rootId !== "root"
? allPosMasters.filter((item) => item.orgChild4Id === null && item.orgChild3Id !== null)
: [];
const posMasterChild4 =
rootId !== "root" ? allPosMasters.filter((item) => item.orgChild4Id !== null) : [];
// Find the minimum posMasterNo for each orgRootId
const minPosMasterNoByOrgRootId = new Map<string, number>();
posMasterRoot.forEach((x) => {
const orgRootId = x.orgRootId ?? "";
const currentMin = minPosMasterNoByOrgRootId.get(orgRootId);
if (
(currentMin === undefined || x.posMasterNo < currentMin) &&
(x as any)[fieldId] != null &&
x.isDirector
) {
minPosMasterNoByOrgRootId.set(orgRootId, x.posMasterNo);
}
});
// Utility to group by key
function groupBy<T>(
arr: T[],
keyFn: (item: T) => string | number | undefined | null,
): Map<string, T[]> {
const map = new Map<string, T[]>();
for (const item of arr) {
let key = keyFn(item);
if (key === undefined || key === null) key = "";
key = String(key);
if (!map.has(key)) map.set(key, []);
map.get(key)!.push(item);
}
return map;
}
// Build lookup maps
const rootByOrgRootId = groupBy(
posMasterRoot.filter(
(item) =>
((item as any)[fieldId] && !item.isDirector) ||
(item.isDirector &&
minPosMasterNoByOrgRootId.get(item.orgRootId ?? "") !== item.posMasterNo),
),
(item) => item.orgRootId ?? "",
);
const child1ByOrgRootId = groupBy(
posMasterChild1.filter((item) => item.isDirector),
(item) => item.orgRootId ?? "",
);
const child1ByOrgChild1Id = groupBy(
posMasterChild1.filter((item) => (item as any)[fieldId] && !item.isDirector),
(item) => item.orgChild1Id ?? "",
);
const child2ByOrgChild1Id = groupBy(
posMasterChild2.filter((item) => item.isDirector),
(item) => item.orgChild1Id ?? "",
);
const child2ByOrgChild2Id = groupBy(
posMasterChild2.filter((item) => (item as any)[fieldId] && !item.isDirector),
(item) => item.orgChild2Id ?? "",
);
const child3ByOrgChild2Id = groupBy(
posMasterChild3.filter((item) => item.isDirector),
(item) => item.orgChild2Id ?? "",
);
const child3ByOrgChild3Id = groupBy(
posMasterChild3.filter((item) => (item as any)[fieldId] && !item.isDirector),
(item) => item.orgChild3Id ?? "",
);
const child4ByOrgChild3Id = groupBy(
posMasterChild4.filter((item) => item.isDirector),
(item) => item.orgChild3Id ?? "",
);
// Helper to create node
function createNode(item: any, level: number, orgInfo: OrgInfo): any {
const holder = fieldId === "current_holderId" ? item.current_holder : item.next_holder;
return {
level,
personID: holder?.id ?? "",
name: holder ? `${holder.firstName} ${holder.lastName}` : "ว่าง",
avatar:
holder?.avatar && holder?.avatarName ? `${holder.avatar}/${holder.avatarName}` : null,
positionName: holder?.position ?? "",
positionNum: `${orgInfo.shortName} ${item.posMasterNo}`,
positionNumInt: item.posMasterNo,
departmentName: orgInfo.name,
organizationId: orgInfo.id,
children: [],
};
}
// Recursive builder for children
function buildChildren(level: number, parent: any, orgInfo: OrgInfo): any[] {
if (level === 2) {
// Level 2: child1 non-directors and child2 directors
const children: any[] = [];
// Root non-directors
(
rootByOrgRootId
.get(parent.orgRootId)
?.filter(
(x00) =>
!x00.isDirector ||
(x00.isDirector &&
minPosMasterNoByOrgRootId.get(x00.orgRootId ?? "") !== x00.posMasterNo),
) || []
).forEach((x00) => {
children.push(
createNode(x00, 2, {
shortName: x00.orgRoot.orgRootShortName,
name: x00.orgRoot.orgRootName,
id: x00.orgRoot.id,
}),
);
});
if (rootId !== "root") {
// Child1 directors
(child1ByOrgRootId.get(parent.orgRootId) || []).forEach((x1) => {
const childLevel2 = buildChildren(3, x1, {
shortName: x1.orgChild1.orgChild1ShortName,
name: x1.orgChild1.orgChild1Name,
id: x1.orgChild1.id,
});
const node = createNode(x1, 2, {
shortName: x1.orgChild1.orgChild1ShortName,
name: x1.orgChild1.orgChild1Name,
id: x1.orgChild1.id,
});
node.children = childLevel2;
children.push(node);
});
}
return children;
} else if (level === 3) {
// Level 3: child1 non-directors and child2 directors
const children: any[] = [];
(child1ByOrgChild1Id.get(parent.orgChild1Id) || []).forEach((x11) => {
children.push(
createNode(x11, 3, {
shortName: x11.orgChild1.orgChild1ShortName,
name: x11.orgChild1.orgChild1Name,
id: x11.orgChild1.id,
}),
);
});
(child2ByOrgChild1Id.get(parent.orgChild1Id) || []).forEach((x2) => {
const childLevel3 = buildChildren(4, x2, {
shortName: x2.orgChild2.orgChild2ShortName,
name: x2.orgChild2.orgChild2Name,
id: x2.orgChild2.id,
});
const node = createNode(x2, 3, {
shortName: x2.orgChild2.orgChild2ShortName,
name: x2.orgChild2.orgChild2Name,
id: x2.orgChild2.id,
});
node.children = childLevel3;
children.push(node);
});
return children;
} else if (level === 4) {
// Level 4: child2 non-directors and child3 directors
const children: any[] = [];
(child2ByOrgChild2Id.get(parent.orgChild2Id) || []).forEach((x22) => {
children.push(
createNode(x22, 4, {
shortName: x22.orgChild2.orgChild2ShortName,
name: x22.orgChild2.orgChild2Name,
id: x22.orgChild2.id,
}),
);
});
(child3ByOrgChild2Id.get(parent.orgChild2Id) || []).forEach((x3) => {
const childLevel4 = buildChildren(5, x3, {
shortName: x3.orgChild3.orgChild3ShortName,
name: x3.orgChild3.orgChild3Name,
id: x3.orgChild3.id,
});
const node = createNode(x3, 4, {
shortName: x3.orgChild3.orgChild3ShortName,
name: x3.orgChild3.orgChild3Name,
id: x3.orgChild3.id,
});
node.children = childLevel4;
children.push(node);
});
return children;
} else if (level === 5) {
// Level 5: child3 non-directors and child4 directors
const children: any[] = [];
(child3ByOrgChild3Id.get(parent.orgChild3Id) || []).forEach((x33) => {
children.push(
createNode(x33, 5, {
shortName: x33.orgChild3.orgChild3ShortName,
name: x33.orgChild3.orgChild3Name,
id: x33.orgChild3.id,
}),
);
});
(child4ByOrgChild3Id.get(parent.orgChild3Id) || []).forEach((x4) => {
// Level 5: child4 directors and their non-directors
const childLevel5: any[] = [];
posMasterChild4
.filter((x) => !x.isDirector && (x as any)[fieldId] && x.orgChild3Id === x4.orgChild3Id)
.forEach((x44) => {
childLevel5.push(
createNode(x44, 5, {
shortName: x44.orgChild4.orgChild4ShortName,
name: x44.orgChild4.orgChild4Name,
id: x44.orgChild4.id,
}),
);
});
const node = createNode(x4, 4, {
shortName: x4.orgChild4.orgChild4ShortName,
name: x4.orgChild4.orgChild4Name,
id: x4.orgChild4.id,
});
node.children = childLevel5;
children.push(node);
});
return children;
}
return [];
}
// Build root nodes
const formattedData = posMasterRoot
.filter(
(x: any) =>
x.isDirector && minPosMasterNoByOrgRootId.get(x.orgRootId ?? "") === x.posMasterNo,
)
.map((x0) => {
const rootNode = createNode(x0, 1, {
shortName: x0.orgRoot.orgRootShortName,
name: x0.orgRoot.orgRootName,
id: x0.orgRoot.id,
});
rootNode.children = buildChildren(2, x0, {
shortName: x0.orgRoot.orgRootShortName,
name: x0.orgRoot.orgRootName,
id: x0.orgRoot.id,
});
return rootNode;
});
const formattedData_ =
rootId === "root"
? [
{
personID: "",
name: "",
avatar: "",
positionName: "",
positionNum: "",
positionNumInt: null,
departmentName: data.orgRevisionName,
organizationId: data.id,
children: formattedData,
},
]
: formattedData;
return new HttpSuccess(formattedData_);
}
/**
* API Organizational StructChart
*
* @summary Organizational StructChart
*
*/
@Get("struct-chart/{idNode}/{type}")
async structchart(@Path() idNode: string, type: number) {
switch (type) {
case 0: {
const data = await this.orgRevisionRepository.findOne({
where: { id: idNode },
relations: [
"orgRoots",
"orgRoots.orgChild1s",
"orgRoots.orgChild1s.orgChild2s",
"orgRoots.orgChild1s.orgChild2s.orgChild3s",
"orgRoots.orgChild1s.orgChild2s.orgChild3s.orgChild4s",
],
});
if (!data) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found revision");
}
const formattedData = {
departmentName: data.orgRevisionName,
deptID: data.id,
type: 0,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: { orgRevisionId: data.id },
}),
totalPositionVacant:
data.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgRevisionId: data.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgRevisionId: data.id,
// next_holderId: IsNull() || "",
// },
// }),
children: await Promise.all(
data.orgRoots
.sort((a, b) => a.orgRootOrder - b.orgRootOrder)
.map(async (orgRoot: OrgRoot) => {
return {
departmentName: orgRoot.orgRootName,
deptID: orgRoot.id,
type: 1,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: { orgRevisionId: data.id, orgRootId: orgRoot.id },
}),
totalPositionVacant:
data.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgRootId: orgRoot.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgRootId: orgRoot.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgRevisionId: data.id,
// orgRootId: orgRoot.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgRevisionId: data.id,
// orgRootId: orgRoot.id,
// next_holderId: IsNull() || "",
// },
// }),
children: await Promise.all(
orgRoot.orgChild1s
.sort((a, b) => a.orgChild1Order - b.orgChild1Order)
.map(async (orgChild1) => ({
departmentName: orgChild1.orgChild1Name,
deptID: orgChild1.id,
type: 2,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
},
}),
totalPositionVacant:
data.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgRevisionId: data.id,
// orgRootId: orgRoot.id,
// orgChild1Id: orgChild1.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgRevisionId: data.id,
// orgRootId: orgRoot.id,
// orgChild1Id: orgChild1.id,
// next_holderId: IsNull() || "",
// },
// }),
children: await Promise.all(
orgChild1.orgChild2s
.sort((a, b) => a.orgChild2Order - b.orgChild2Order)
.map(async (orgChild2) => ({
departmentName: orgChild2.orgChild2Name,
deptID: orgChild2.id,
type: 3,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
},
}),
totalPositionVacant:
data.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgRevisionId: data.id,
// orgRootId: orgRoot.id,
// orgChild1Id: orgChild1.id,
// orgChild2Id: orgChild2.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgRevisionId: data.id,
// orgRootId: orgRoot.id,
// orgChild1Id: orgChild1.id,
// orgChild2Id: orgChild2.id,
// next_holderId: IsNull() || "",
// },
// }),
children: await Promise.all(
orgChild2.orgChild3s
.sort((a, b) => a.orgChild3Order - b.orgChild3Order)
.map(async (orgChild3) => ({
departmentName: orgChild3.orgChild3Name,
deptID: orgChild3.id,
type: 4,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
},
}),
totalPositionVacant:
data.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant:
// await this.posMasterRepository.count({
// where: {
// orgRevisionId: data.id,
// orgRootId: orgRoot.id,
// orgChild1Id: orgChild1.id,
// orgChild2Id: orgChild2.id,
// orgChild3Id: orgChild3.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count(
// {
// where: {
// orgRevisionId: data.id,
// orgRootId: orgRoot.id,
// orgChild1Id: orgChild1.id,
// orgChild2Id: orgChild2.id,
// orgChild3Id: orgChild3.id,
// next_holderId: IsNull() || "",
// },
// },
// ),
children: await Promise.all(
orgChild3.orgChild4s
.sort((a, b) => a.orgChild4Order - b.orgChild4Order)
.map(async (orgChild4) => ({
departmentName: orgChild4.orgChild4Name,
deptID: orgChild4.id,
type: 5,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
},
}),
totalPositionVacant:
data.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgRootId: orgRoot.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant:
// await this.posMasterRepository.count({
// where: {
// orgRevisionId: data.id,
// orgRootId: orgRoot.id,
// orgChild1Id: orgChild1.id,
// orgChild2Id: orgChild2.id,
// orgChild3Id: orgChild3.id,
// orgChild4Id: orgChild4.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant:
// await this.posMasterRepository.count({
// where: {
// orgRevisionId: data.id,
// orgRootId: orgRoot.id,
// orgChild1Id: orgChild1.id,
// orgChild2Id: orgChild2.id,
// orgChild3Id: orgChild3.id,
// orgChild4Id: orgChild4.id,
// next_holderId: IsNull() || "",
// },
// }),
})),
),
})),
),
})),
),
})),
),
};
}),
),
};
return new HttpSuccess([formattedData]);
}
case 1: {
const data = await this.orgRootRepository.findOne({
where: { id: idNode },
relations: [
"orgRevision",
"orgChild1s",
"orgChild1s.orgChild2s",
"orgChild1s.orgChild2s.orgChild3s",
"orgChild1s.orgChild2s.orgChild3s.orgChild4s",
],
});
if (!data) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found rootId");
}
const formattedData = {
departmentName: data.orgRootName,
deptID: data.id,
type: 1,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: { orgRootId: data.id },
}),
totalPositionVacant:
data.orgRevision.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgRootId: data.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgRootId: data.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgRootId: data.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgRootId: data.id,
// next_holderId: IsNull() || "",
// },
// }),
children: await Promise.all(
data.orgChild1s
.sort((a, b) => a.orgChild1Order - b.orgChild1Order)
.map(async (orgChild1) => ({
departmentName: orgChild1.orgChild1Name,
deptID: orgChild1.id,
type: 2,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: { orgRootId: data.id, orgChild1Id: orgChild1.id },
}),
totalPositionVacant:
data.orgRevision.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgRootId: data.id,
orgChild1Id: orgChild1.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgRootId: data.id,
orgChild1Id: orgChild1.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgRootId: data.id,
// orgChild1Id: orgChild1.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgRootId: data.id,
// orgChild1Id: orgChild1.id,
// next_holderId: IsNull() || "",
// },
// }),
children: await Promise.all(
orgChild1.orgChild2s
.sort((a, b) => a.orgChild2Order - b.orgChild2Order)
.map(async (orgChild2) => ({
departmentName: orgChild2.orgChild2Name,
deptID: orgChild2.id,
type: 3,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: {
orgRootId: data.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
},
}),
totalPositionCurrentVacant:
data.orgRevision.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgRootId: data.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgRootId: data.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgRootId: data.id,
// orgChild1Id: orgChild1.id,
// orgChild2Id: orgChild2.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgRootId: data.id,
// orgChild1Id: orgChild1.id,
// orgChild2Id: orgChild2.id,
// next_holderId: IsNull() || "",
// },
// }),
children: await Promise.all(
orgChild2.orgChild3s
.sort((a, b) => a.orgChild3Order - b.orgChild3Order)
.map(async (orgChild3) => ({
departmentName: orgChild3.orgChild3Name,
deptID: orgChild3.id,
type: 4,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: {
orgRootId: data.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
},
}),
totalPositionVacant:
data.orgRevision.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgRootId: data.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgRootId: data.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgRootId: data.id,
// orgChild1Id: orgChild1.id,
// orgChild2Id: orgChild2.id,
// orgChild3Id: orgChild3.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgRootId: data.id,
// orgChild1Id: orgChild1.id,
// orgChild2Id: orgChild2.id,
// orgChild3Id: orgChild3.id,
// next_holderId: IsNull() || "",
// },
// }),
children: await Promise.all(
orgChild3.orgChild4s
.sort((a, b) => a.orgChild4Order - b.orgChild4Order)
.map(async (orgChild4) => ({
departmentName: orgChild4.orgChild4Name,
deptID: orgChild4.id,
type: 5,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: {
orgRootId: data.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
},
}),
totalPositionVacant:
data.orgRevision.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgRootId: data.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgRootId: data.id,
orgChild1Id: orgChild1.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant:
// await this.posMasterRepository.count({
// where: {
// orgRootId: data.id,
// orgChild1Id: orgChild1.id,
// orgChild2Id: orgChild2.id,
// orgChild3Id: orgChild3.id,
// orgChild4Id: orgChild4.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgRootId: data.id,
// orgChild1Id: orgChild1.id,
// orgChild2Id: orgChild2.id,
// orgChild3Id: orgChild3.id,
// orgChild4Id: orgChild4.id,
// next_holderId: IsNull() || "",
// },
// }),
})),
),
})),
),
})),
),
})),
),
};
return new HttpSuccess([formattedData]);
}
case 2: {
const data = await this.child1Repository.findOne({
where: { id: idNode },
relations: [
"orgRevision",
"orgChild2s",
"orgChild2s.orgChild3s",
"orgChild2s.orgChild3s.orgChild4s",
],
});
if (!data) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child1Id");
}
const formattedData = {
departmentName: data.orgChild1Name,
deptID: data.id,
type: 2,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: { orgChild1Id: data.id },
}),
totalPositionVacant:
data.orgRevision.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgChild1Id: data.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgChild1Id: data.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgChild1Id: data.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgChild1Id: data.id,
// next_holderId: IsNull() || "",
// },
// }),
children: await Promise.all(
data.orgChild2s
.sort((a, b) => a.orgChild2Order - b.orgChild2Order)
.map(async (orgChild2) => ({
departmentName: orgChild2.orgChild2Name,
deptID: orgChild2.id,
type: 3,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: { orgChild1Id: data.id, orgChild2Id: orgChild2.id },
}),
totalPositionVacant:
data.orgRevision.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgChild1Id: data.id,
orgChild2Id: orgChild2.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgChild1Id: data.id,
orgChild2Id: orgChild2.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgChild1Id: data.id,
// orgChild2Id: orgChild2.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgChild1Id: data.id,
// orgChild2Id: orgChild2.id,
// next_holderId: IsNull() || "",
// },
// }),
children: await Promise.all(
orgChild2.orgChild3s
.sort((a, b) => a.orgChild3Order - b.orgChild3Order)
.map(async (orgChild3) => ({
departmentName: orgChild3.orgChild3Name,
deptID: orgChild3.id,
type: 4,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
},
}),
totalPositionVacant:
data.orgRevision.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgRevisionId: data.id,
// orgChild2Id: orgChild2.id,
// orgChild3Id: orgChild3.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgRevisionId: data.id,
// orgChild2Id: orgChild2.id,
// orgChild3Id: orgChild3.id,
// next_holderId: IsNull() || "",
// },
// }),
children: await Promise.all(
orgChild3.orgChild4s
.sort((a, b) => a.orgChild4Order - b.orgChild4Order)
.map(async (orgChild4) => ({
departmentName: orgChild4.orgChild4Name,
deptID: orgChild4.id,
type: 5,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
},
}),
totalPositionVacant:
data.orgRevision.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgRevisionId: data.id,
orgChild2Id: orgChild2.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgRevisionId: data.id,
// orgChild2Id: orgChild2.id,
// orgChild3Id: orgChild3.id,
// orgChild4Id: orgChild4.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgRevisionId: data.id,
// orgChild2Id: orgChild2.id,
// orgChild3Id: orgChild3.id,
// orgChild4Id: orgChild4.id,
// next_holderId: IsNull() || "",
// },
// }),
})),
),
})),
),
})),
),
};
return new HttpSuccess([formattedData]);
}
case 3: {
const data = await this.child2Repository.findOne({
where: { id: idNode },
relations: ["orgRevision", "orgChild3s", "orgChild3s.orgChild4s"],
});
if (!data) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child2Id");
}
const formattedData = {
departmentName: data.orgChild2Name,
deptID: data.id,
type: 3,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: { orgChild2Id: data.id },
}),
totalPositionVacant:
data.orgRevision.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgChild2Id: data.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgChild2Id: data.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgChild2Id: data.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgChild2Id: data.id,
// next_holderId: IsNull() || "",
// },
// }),
children: await Promise.all(
data.orgChild3s
.sort((a, b) => a.orgChild3Order - b.orgChild3Order)
.map(async (orgChild3) => ({
departmentName: orgChild3.orgChild3Name,
deptID: orgChild3.id,
type: 4,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: { orgChild2Id: data.id, orgChild3Id: orgChild3.id },
}),
totalPositionVacant:
data.orgRevision.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgChild2Id: data.id,
orgChild3Id: orgChild3.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgChild2Id: data.id,
orgChild3Id: orgChild3.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgChild2Id: data.id,
// orgChild3Id: orgChild3.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgChild2Id: data.id,
// orgChild3Id: orgChild3.id,
// next_holderId: IsNull() || "",
// },
// }),
children: await Promise.all(
orgChild3.orgChild4s
.sort((a, b) => a.orgChild4Order - b.orgChild4Order)
.map(async (orgChild4) => ({
departmentName: orgChild4.orgChild4Name,
deptID: orgChild4.id,
type: 5,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: {
orgChild2Id: data.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
},
}),
totalPositionVacant:
data.orgRevision.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgChild2Id: data.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgChild2Id: data.id,
orgChild3Id: orgChild3.id,
orgChild4Id: orgChild4.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgChild2Id: data.id,
// orgChild3Id: orgChild3.id,
// orgChild4Id: orgChild4.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgChild2Id: data.id,
// orgChild3Id: orgChild3.id,
// orgChild4Id: orgChild4.id,
// next_holderId: IsNull() || "",
// },
// }),
})),
),
})),
),
};
return new HttpSuccess([formattedData]);
}
case 4: {
const data = await this.child3Repository.findOne({
where: { id: idNode },
relations: ["orgRevision", "orgChild4s"],
});
if (!data) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child3Id");
}
const formattedData = {
departmentName: data.orgChild3Name,
deptID: data.id,
type: 4,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: { orgChild3Id: data.id },
}),
totalPositionVacant:
data.orgRevision.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgChild3Id: data.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgChild3Id: data.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgChild3Id: data.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgChild3Id: data.id,
// next_holderId: IsNull() || "",
// },
// }),
children: await Promise.all(
data.orgChild4s
.sort((a, b) => a.orgChild4Order - b.orgChild4Order)
.map(async (orgChild4) => ({
departmentName: orgChild4.orgChild4Name,
deptID: orgChild4.id,
type: 5,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: { orgChild3Id: data.id, orgChild4Id: orgChild4.id },
}),
totalPositionVacant:
data.orgRevision.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgChild3Id: data.id,
orgChild4Id: orgChild4.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgChild3Id: data.id,
orgChild4Id: orgChild4.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgChild3Id: data.id,
// orgChild4Id: orgChild4.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgChild3Id: data.id,
// orgChild4Id: orgChild4.id,
// next_holderId: IsNull() || "",
// },
// }),
})),
),
};
return new HttpSuccess([formattedData]);
}
case 5: {
const data = await this.child4Repository.findOne({
where: { id: idNode },
relations: ["orgRevision"],
});
if (!data) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child4Id");
}
const formattedData = {
departmentName: data.orgChild4Name,
deptID: data.id,
type: 5,
// heads:
totalPositionCount: await this.posMasterRepository.count({
where: { orgChild4Id: data.id },
}),
totalPositionVacant:
data.orgRevision.orgRevisionIsDraft == true
? await this.posMasterRepository.count({
where: {
orgChild4Id: data.id,
next_holderId: IsNull() || "",
},
})
: await this.posMasterRepository.count({
where: {
orgChild4Id: data.id,
current_holderId: IsNull() || "",
},
}),
// totalPositionCurrentVacant: await this.posMasterRepository.count({
// where: {
// orgChild4Id: data.id,
// current_holderId: IsNull() || "",
// },
// }),
// totalPositionNextVacant: await this.posMasterRepository.count({
// where: {
// orgChild4Id: data.id,
// next_holderId: IsNull() || "",
// },
// }),
};
return new HttpSuccess([formattedData]);
}
default:
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found type: ");
}
}
/**
* API เช็ค node
*
* @summary เช็ค node (ADMIN)
*
*/
@Post("find/node")
async findNodeAll(@Body() requestBody: { node: number; nodeId: string }) {
switch (requestBody.node) {
case 0: {
const data = await this.orgRootRepository.findOne({
where: { id: requestBody.nodeId },
});
if (data == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found rootId.");
}
return new HttpSuccess([data.id]);
}
case 1: {
const data = await this.child1Repository.findOne({
where: { id: requestBody.nodeId },
});
if (data == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child1.");
}
return new HttpSuccess([data.orgRootId, data.id]);
}
case 2: {
const data = await this.child2Repository.findOne({
where: { id: requestBody.nodeId },
});
if (data == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child2.");
}
return new HttpSuccess([data.orgRootId, data.orgChild1Id, data.id]);
}
case 3: {
const data = await this.child3Repository.findOne({
where: { id: requestBody.nodeId },
});
if (data == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child3.");
}
return new HttpSuccess([data.orgRootId, data.orgChild1Id, data.orgChild2Id, data.id]);
}
case 4: {
const data = await this.child4Repository.findOne({
where: { id: requestBody.nodeId },
});
if (data == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child4.");
}
return new HttpSuccess([
data.orgRootId,
data.orgChild1Id,
data.orgChild2Id,
data.orgChild3Id,
data.id,
]);
}
default:
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found type: " + requestBody.node);
}
}
/**
* API เช็ค node
*
* @summary เช็ค node (ADMIN)
*
*/
@Post("find/node-all")
async findNodeAllOrg(@Body() requestBody: { node: number | null; nodeId: string | null }) {
let orgRootRankSub1 = ["BUREAU", "OFFICE"];
let orgRootRankSub2 = ["DISTRICT"];
let data1: any;
let data2: any;
switch (requestBody.node) {
case 0: {
const _data1 = await this.orgRootRepository.find({
where: {
id: requestBody.nodeId ?? "",
orgRootRankSub: In(orgRootRankSub1),
},
order: { orgRootOrder: "ASC" },
});
const _data2 = await this.orgRootRepository.find({
where: [
{
id: requestBody.nodeId ?? "",
orgRootRankSub: In(orgRootRankSub2),
},
{
id: requestBody.nodeId ?? "",
orgRootRankSub: IsNull(),
},
],
order: { orgRootOrder: "ASC" },
});
data1 = _data1.map((y) => ({
name: y.orgRootName,
rootId: y.id,
rootDnaId: y.ancestorDNA,
child1Id: null,
child1DnaId: null,
child2Id: null,
child2DnaId: null,
child3Id: null,
child3DnaId: null,
child4Id: null,
child4DnaId: null,
}));
data2 = _data2.map((y) => ({
name: y.orgRootName,
rootId: y.id,
rootDnaId: y.ancestorDNA,
child1Id: null,
child1DnaId: null,
child2Id: null,
child2DnaId: null,
child3Id: null,
child3DnaId: null,
child4Id: null,
child4DnaId: null,
}));
break;
}
case 1: {
const _data1 = await this.child1Repository.find({
where: {
id: requestBody.nodeId ?? "",
orgRoot: {
orgRootRankSub: In(orgRootRankSub1),
},
},
order: {
orgRoot: { orgRootOrder: "ASC" },
},
relations: ["orgRoot"],
});
const _data2 = await this.child1Repository.find({
where: [
{
id: requestBody.nodeId ?? "",
orgRoot: {
orgRootRankSub: In(orgRootRankSub2),
},
},
{
id: requestBody.nodeId ?? "",
orgRoot: {
orgRootRankSub: IsNull(),
},
},
],
order: {
orgRoot: { orgRootOrder: "ASC" },
},
relations: ["orgRoot"],
});
data1 = _data1.map((y) => ({
name: y.orgRoot.orgRootName,
rootId: y.orgRoot.id,
rootDnaId: y.orgRoot.ancestorDNA,
child1Id: y.id,
child1DnaId: y.ancestorDNA,
child2Id: null,
child2DnaId: null,
child3Id: null,
child3DnaId: null,
child4Id: null,
child4DnaId: null,
}));
data2 = _data2.map((y) => ({
name: y.orgRoot.orgRootName,
rootId: y.orgRoot.id,
rootDnaId: y.orgRoot.ancestorDNA,
child1Id: y.id,
child1DnaId: y.ancestorDNA,
child2Id: null,
child2DnaId: null,
child3Id: null,
child3DnaId: null,
child4Id: null,
child4DnaId: null,
}));
break;
}
case 2: {
const _data1 = await this.child2Repository.find({
where: {
id: requestBody.nodeId ?? "",
orgRoot: {
orgRootRankSub: In(orgRootRankSub1),
},
},
order: {
orgRoot: { orgRootOrder: "ASC" },
},
relations: ["orgRoot", "orgChild1"],
});
const _data2 = await this.child2Repository.find({
where: [
{
id: requestBody.nodeId ?? "",
orgRoot: {
orgRootRankSub: In(orgRootRankSub2),
},
},
{
id: requestBody.nodeId ?? "",
orgRoot: {
orgRootRankSub: IsNull(),
},
},
],
order: {
orgRoot: { orgRootOrder: "ASC" },
},
relations: ["orgRoot", "orgChild1"],
});
data1 = _data1.map((y) => ({
name: y.orgRoot.orgRootName,
rootId: y.orgRoot.id,
rootDnaId: y.orgRoot.ancestorDNA,
child1Id: y.orgChild1.id,
child1DnaId: y.orgChild1.ancestorDNA,
child2Id: y.id,
child2DnaId: y.ancestorDNA,
child3Id: null,
child3DnaId: null,
child4Id: null,
child4DnaId: null,
}));
data2 = _data2.map((y) => ({
name: y.orgRoot.orgRootName,
rootId: y.orgRoot.id,
rootDnaId: y.orgRoot.ancestorDNA,
child1Id: y.orgChild1.id,
child1DnaId: y.orgChild1.ancestorDNA,
child2Id: y.id,
child2DnaId: y.ancestorDNA,
child3Id: null,
child3DnaId: null,
child4Id: null,
child4DnaId: null,
}));
break;
}
case 3: {
const _data1 = await this.child3Repository.find({
where: {
id: requestBody.nodeId ?? "",
orgRoot: {
orgRootRankSub: In(orgRootRankSub1),
},
},
order: {
orgRoot: { orgRootOrder: "ASC" },
},
relations: ["orgRoot", "orgChild1", "orgChild2"],
});
const _data2 = await this.child3Repository.find({
where: [
{
id: requestBody.nodeId ?? "",
orgRoot: {
orgRootRankSub: In(orgRootRankSub2),
},
},
{
id: requestBody.nodeId ?? "",
orgRoot: {
orgRootRankSub: IsNull(),
},
},
],
order: {
orgRoot: { orgRootOrder: "ASC" },
},
relations: ["orgRoot", "orgChild1", "orgChild2"],
});
data1 = _data1.map((y) => ({
name: y.orgRoot.orgRootName,
rootId: y.orgRoot.id,
rootDnaId: y.orgRoot.ancestorDNA,
child1Id: y.orgChild1.id,
child1DnaId: y.orgChild1.ancestorDNA,
child2Id: y.orgChild2.id,
child2DnaId: y.orgChild2.ancestorDNA,
child3Id: y.id,
child3DnaId: y.ancestorDNA,
child4Id: null,
child4DnaId: null,
}));
data2 = _data2.map((y) => ({
name: y.orgRoot.orgRootName,
rootId: y.orgRoot.id,
rootDnaId: y.orgRoot.ancestorDNA,
child1Id: y.orgChild1.id,
child1DnaId: y.orgChild1.ancestorDNA,
child2Id: y.orgChild2.id,
child2DnaId: y.orgChild2.ancestorDNA,
child3Id: y.id,
child3DnaId: y.ancestorDNA,
child4Id: null,
child4DnaId: null,
}));
break;
}
case 4: {
const _data1 = await this.child4Repository.find({
where: {
id: requestBody.nodeId ?? "",
orgRoot: {
orgRootRankSub: In(orgRootRankSub1),
},
},
order: {
orgRoot: { orgRootOrder: "ASC" },
},
relations: ["orgRoot", "orgChild1", "orgChild2", "orgChild3"],
});
const _data2 = await this.child4Repository.find({
where: [
{
id: requestBody.nodeId ?? "",
orgRoot: {
orgRootRankSub: In(orgRootRankSub2),
},
},
{
id: requestBody.nodeId ?? "",
orgRoot: {
orgRootRankSub: IsNull(),
},
},
],
order: {
orgRoot: { orgRootOrder: "ASC" },
},
relations: ["orgRoot", "orgChild1", "orgChild2", "orgChild3"],
});
data1 = _data1.map((y) => ({
name: y.orgRoot.orgRootName,
rootId: y.orgRoot.id,
rootDnaId: y.orgRoot.ancestorDNA,
child1Id: y.orgChild1.id,
child1DnaId: y.orgChild1.ancestorDNA,
child2Id: y.orgChild2.id,
child2DnaId: y.orgChild2.ancestorDNA,
child3Id: y.orgChild3.id,
child3DnaId: y.orgChild3.ancestorDNA,
child4Id: y.id,
child4DnaId: y.ancestorDNA,
}));
data2 = _data2.map((y) => ({
name: y.orgRoot.orgRootName,
rootId: y.orgRoot.id,
rootDnaId: y.orgRoot.ancestorDNA,
child1Id: y.orgChild1.id,
child1DnaId: y.orgChild1.ancestorDNA,
child2Id: y.orgChild2.id,
child2DnaId: y.orgChild2.ancestorDNA,
child3Id: y.orgChild3.id,
child3DnaId: y.orgChild3.ancestorDNA,
child4Id: y.id,
child4DnaId: y.ancestorDNA,
}));
break;
}
default: {
const orgRevision = await this.orgRevisionRepository.findOne({
where: {
orgRevisionIsCurrent: true,
orgRevisionIsDraft: false,
},
});
const _data1 = await this.orgRootRepository.find({
where: {
orgRevisionId: orgRevision?.id,
orgRootRankSub: In(orgRootRankSub1),
},
order: { orgRootOrder: "ASC" },
});
const _data2 = await this.orgRootRepository.find({
where: [
{
orgRevisionId: orgRevision?.id,
orgRootRankSub: In(orgRootRankSub2),
},
{
orgRevisionId: orgRevision?.id,
orgRootRankSub: IsNull(),
},
],
order: { orgRootOrder: "ASC" },
});
data1 = _data1.map((y) => ({
name: y.orgRootName,
rootId: y.id,
rootDnaId: y.ancestorDNA,
child1Id: null,
child2Id: null,
child3Id: null,
child4Id: null,
}));
data2 = _data2.map((y) => ({
name: y.orgRootName,
rootId: y.id,
rootDnaId: y.ancestorDNA,
child1Id: null,
child2Id: null,
child3Id: null,
child4Id: null,
}));
}
}
return new HttpSuccess({ isRootTrue: data1, isRootFalse: data2 });
}
/**
* API เช็ค node detail
*
* @summary เช็ค node detail (ADMIN)
*
*/
@Post("find/all")
async findNodeAllDetail(@Body() requestBody: { node: number; nodeId: string }) {
switch (requestBody.node) {
case 0: {
const data = await this.orgRootRepository.findOne({
where: { id: requestBody.nodeId },
});
if (data == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found rootId.");
}
return new HttpSuccess({
rootId: data.id,
rootDnaId: data.ancestorDNA,
root: data.orgRootName,
rootShortName: data.orgRootShortName,
});
}
case 1: {
const data = await this.child1Repository.findOne({
where: { id: requestBody.nodeId },
relations: {
orgRoot: true,
},
});
if (data == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child1.");
}
return new HttpSuccess({
rootId: data.orgRootId,
rootDnaId: data.orgRoot == null ? null : data.orgRoot.ancestorDNA,
root: data.orgRoot == null ? null : data.orgRoot.orgRootName,
rootShortName: data.orgRoot == null ? null : data.orgRoot.orgRootShortName,
child1Id: data.id,
child1DnaId: data.ancestorDNA,
child1: data.orgChild1Name,
child1ShortName: data.orgChild1ShortName,
});
}
case 2: {
const data = await this.child2Repository.findOne({
where: { id: requestBody.nodeId },
relations: {
orgRoot: true,
orgChild1: true,
},
});
if (data == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child2.");
}
return new HttpSuccess({
rootId: data.orgRootId,
rootDnaId: data.orgRoot == null ? null : data.orgRoot.ancestorDNA,
root: data.orgRoot == null ? null : data.orgRoot.orgRootName,
rootShortName: data.orgRoot == null ? null : data.orgRoot.orgRootShortName,
child1Id: data.orgChild1Id,
child1DnaId: data.orgChild1 == null ? null : data.orgChild1.ancestorDNA,
child1: data.orgChild1 == null ? null : data.orgChild1.orgChild1Name,
child1ShortName: data.orgChild1 == null ? null : data.orgChild1.orgChild1ShortName,
child2Id: data.id,
child2DnaId: data.ancestorDNA,
child2: data.orgChild2Name,
child2ShortName: data.orgChild2ShortName,
});
}
case 3: {
const data = await this.child3Repository.findOne({
where: { id: requestBody.nodeId },
relations: {
orgRoot: true,
orgChild1: true,
orgChild2: true,
},
});
if (data == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child3.");
}
return new HttpSuccess({
rootId: data.orgRootId,
rootDnaId: data.orgRoot == null ? null : data.orgRoot.ancestorDNA,
root: data.orgRoot == null ? null : data.orgRoot.orgRootName,
rootShortName: data.orgRoot == null ? null : data.orgRoot.orgRootShortName,
child1Id: data.orgChild1Id,
child1DnaId: data.orgChild1 == null ? null : data.orgChild1.ancestorDNA,
child1: data.orgChild1 == null ? null : data.orgChild1.orgChild1Name,
child1ShortName: data.orgChild1 == null ? null : data.orgChild1.orgChild1ShortName,
child2Id: data.orgChild2Id,
child2DnaId: data.orgChild2 == null ? null : data.orgChild2.ancestorDNA,
child2: data.orgChild2 == null ? null : data.orgChild2.orgChild2Name,
child2ShortName: data.orgChild2 == null ? null : data.orgChild2.orgChild2ShortName,
child3Id: data.id,
child3DnaId: data.ancestorDNA,
child3: data.orgChild3Name,
child3ShortName: data.orgChild3ShortName,
});
}
case 4: {
const data = await this.child4Repository.findOne({
where: { id: requestBody.nodeId },
relations: {
orgRoot: true,
orgChild1: true,
orgChild2: true,
orgChild3: true,
},
});
if (data == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child4.");
}
return new HttpSuccess({
rootId: data.orgRootId,
rootDnaId: data.orgRoot == null ? null : data.orgRoot.ancestorDNA,
root: data.orgRoot == null ? null : data.orgRoot.orgRootName,
rootShortName: data.orgRoot == null ? null : data.orgRoot.orgRootShortName,
child1Id: data.orgChild1Id,
child1DnaId: data.orgChild1 == null ? null : data.orgChild1.ancestorDNA,
child1: data.orgChild1 == null ? null : data.orgChild1.orgChild1Name,
child1ShortName: data.orgChild1 == null ? null : data.orgChild1.orgChild1ShortName,
child2Id: data.orgChild2Id,
child2DnaId: data.orgChild2 == null ? null : data.orgChild2.ancestorDNA,
child2: data.orgChild2 == null ? null : data.orgChild2.orgChild2Name,
child2ShortName: data.orgChild2 == null ? null : data.orgChild2.orgChild2ShortName,
child3Id: data.orgChild3Id,
child3DnaId: data.orgChild3 == null ? null : data.orgChild3.ancestorDNA,
child3: data.orgChild3 == null ? null : data.orgChild3.orgChild3Name,
child3ShortName: data.orgChild3 == null ? null : data.orgChild3.orgChild3ShortName,
child4Id: data.id,
child4DnaId: data.ancestorDNA,
child4: data.orgChild4Name,
child4ShortName: data.orgChild4ShortName,
});
}
default:
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found type: " + requestBody.node);
}
}
/**
* API เช็ค node detail
*
* @summary เช็ค node detail (ADMIN)
*
*/
@Post("find/allv2")
async findNodeAllDetailV2(@Body() requestBody: { node: number; nodeId: string }) {
switch (requestBody.node) {
case 0: {
const data = await this.orgRootRepository.findOne({
where: { ancestorDNA: requestBody.nodeId },
order: { createdAt: "DESC" },
});
if (data == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found rootId.");
}
return new HttpSuccess({
rootId: data.id,
rootDnaId: data.ancestorDNA,
root: data.orgRootName,
rootShortName: data.orgRootShortName,
});
}
case 1: {
const data = await this.child1Repository.findOne({
where: { ancestorDNA: requestBody.nodeId },
relations: {
orgRoot: true,
},
order: { createdAt: "DESC" },
});
if (data == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child1.");
}
return new HttpSuccess({
rootId: data.orgRootId,
rootDnaId: data.orgRoot == null ? null : data.orgRoot.ancestorDNA,
root: data.orgRoot == null ? null : data.orgRoot.orgRootName,
rootShortName: data.orgRoot == null ? null : data.orgRoot.orgRootShortName,
child1Id: data.id,
child1DnaId: data.ancestorDNA,
child1: data.orgChild1Name,
child1ShortName: data.orgChild1ShortName,
});
}
case 2: {
const data = await this.child2Repository.findOne({
where: { ancestorDNA: requestBody.nodeId },
relations: {
orgRoot: true,
orgChild1: true,
},
order: { createdAt: "DESC" },
});
if (data == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child2.");
}
return new HttpSuccess({
rootId: data.orgRootId,
rootDnaId: data.orgRoot == null ? null : data.orgRoot.ancestorDNA,
root: data.orgRoot == null ? null : data.orgRoot.orgRootName,
rootShortName: data.orgRoot == null ? null : data.orgRoot.orgRootShortName,
child1Id: data.orgChild1Id,
child1DnaId: data.orgChild1 == null ? null : data.orgChild1.ancestorDNA,
child1: data.orgChild1 == null ? null : data.orgChild1.orgChild1Name,
child1ShortName: data.orgChild1 == null ? null : data.orgChild1.orgChild1ShortName,
child2Id: data.id,
child2DnaId: data.ancestorDNA,
child2: data.orgChild2Name,
child2ShortName: data.orgChild2ShortName,
});
}
case 3: {
const data = await this.child3Repository.findOne({
where: { ancestorDNA: requestBody.nodeId },
relations: {
orgRoot: true,
orgChild1: true,
orgChild2: true,
},
order: { createdAt: "DESC" },
});
if (data == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child3.");
}
return new HttpSuccess({
rootId: data.orgRootId,
rootDnaId: data.orgRoot == null ? null : data.orgRoot.ancestorDNA,
root: data.orgRoot == null ? null : data.orgRoot.orgRootName,
rootShortName: data.orgRoot == null ? null : data.orgRoot.orgRootShortName,
child1Id: data.orgChild1Id,
child1DnaId: data.orgChild1 == null ? null : data.orgChild1.ancestorDNA,
child1: data.orgChild1 == null ? null : data.orgChild1.orgChild1Name,
child1ShortName: data.orgChild1 == null ? null : data.orgChild1.orgChild1ShortName,
child2Id: data.orgChild2Id,
child2DnaId: data.orgChild2 == null ? null : data.orgChild2.ancestorDNA,
child2: data.orgChild2 == null ? null : data.orgChild2.orgChild2Name,
child2ShortName: data.orgChild2 == null ? null : data.orgChild2.orgChild2ShortName,
child3Id: data.id,
child3DnaId: data.ancestorDNA,
child3: data.orgChild3Name,
child3ShortName: data.orgChild3ShortName,
});
}
case 4: {
const data = await this.child4Repository.findOne({
where: { ancestorDNA: requestBody.nodeId },
relations: {
orgRoot: true,
orgChild1: true,
orgChild2: true,
orgChild3: true,
},
order: { createdAt: "DESC" },
});
if (data == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found child4.");
}
return new HttpSuccess({
rootId: data.orgRootId,
rootDnaId: data.orgRoot == null ? null : data.orgRoot.ancestorDNA,
root: data.orgRoot == null ? null : data.orgRoot.orgRootName,
rootShortName: data.orgRoot == null ? null : data.orgRoot.orgRootShortName,
child1Id: data.orgChild1Id,
child1DnaId: data.orgChild1 == null ? null : data.orgChild1.ancestorDNA,
child1: data.orgChild1 == null ? null : data.orgChild1.orgChild1Name,
child1ShortName: data.orgChild1 == null ? null : data.orgChild1.orgChild1ShortName,
child2Id: data.orgChild2Id,
child2DnaId: data.orgChild2 == null ? null : data.orgChild2.ancestorDNA,
child2: data.orgChild2 == null ? null : data.orgChild2.orgChild2Name,
child2ShortName: data.orgChild2 == null ? null : data.orgChild2.orgChild2ShortName,
child3Id: data.orgChild3Id,
child3DnaId: data.orgChild3 == null ? null : data.orgChild3.ancestorDNA,
child3: data.orgChild3 == null ? null : data.orgChild3.orgChild3Name,
child3ShortName: data.orgChild3 == null ? null : data.orgChild3.orgChild3ShortName,
child4Id: data.id,
child4DnaId: data.ancestorDNA,
child4: data.orgChild4Name,
child4ShortName: data.orgChild4ShortName,
});
}
default:
throw new HttpError(HttpStatusCode.NOT_FOUND, "not found type: " + requestBody.node);
}
}
/**
* API หาสำนักทั้งหมด
*
* @summary หาสำนักทั้งหมด
*
*/
@Get("active/root")
async GetActiveRoot() {
const orgRevisionActive = await this.orgRevisionRepository.findOne({
where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
});
if (!orgRevisionActive) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบโครงสร้างที่เผยแพร่อยู่ตอนนี้");
}
const data = await this.orgRootRepository.find({
where: { orgRevisionId: orgRevisionActive.id },
relations: [
"orgRevision",
"orgChild1s",
"orgChild1s.orgChild2s",
"orgChild1s.orgChild2s.orgChild3s",
"orgChild1s.orgChild2s.orgChild3s.orgChild4s",
],
order: {
orgChild1s: {
orgChild1Order: "ASC",
orgChild2s: {
orgChild2Order: "ASC",
orgChild3s: {
orgChild3Order: "ASC",
orgChild4s: {
orgChild4Order: "ASC",
},
},
},
},
},
});
return new HttpSuccess(data);
}
/**
* API หาสำนักทั้งหมด
*
* @summary หาสำนักทั้งหมด
*
*/
@Get("active/root/id")
async GetActiveRootId() {
const orgRevisionActive = await this.orgRevisionRepository.findOne({
where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
});
if (!orgRevisionActive) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบโครงสร้างที่เผยแพร่อยู่ตอนนี้");
}
const data = await this.orgRootRepository.find({
where: { orgRevisionId: orgRevisionActive.id },
order: {
orgRootOrder: "ASC",
},
});
return new HttpSuccess(data.map((x) => x.id));
}
/**
* API หาสำนักทั้งหมด
*
* @summary หาสำนักทั้งหมด
*
*/
@Get("active/root/all")
async GetActiveRootAll() {
const orgRevisionActive = await this.orgRevisionRepository.findOne({
where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
});
if (!orgRevisionActive) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบโครงสร้างที่เผยแพร่อยู่ตอนนี้");
}
const data = await this.orgRootRepository.find({
where: {
orgRevisionId: orgRevisionActive.id,
id: In([
"d7e98989-b5ce-47d6-93c3-ab63ed486348",
"6f9b30e1-757a-40d5-b053-61eb1b91c0f0",
"eaf65f33-25e9-4956-9dba-5d909f5eb595",
"87c5bc89-300c-4b6a-99e4-26371436caa2",
"982d33af-4eb5-4cc8-9c9f-b3ccadbb66d7",
"e0545eca-5d0a-4a1c-8bbd-e3e25c2521db",
]),
},
order: {
orgRootOrder: "ASC",
},
});
return new HttpSuccess(data);
}
/**
* API
*
* @summary
*
*/
@Get("active/root/latest")
async GetActiveRootIdLatest() {
const orgRevisionActive = await this.orgRevisionRepository.findOne({
where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
});
if (!orgRevisionActive) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบโครงสร้างที่เผยแพร่อยู่ตอนนี้");
}
return new HttpSuccess(orgRevisionActive.id);
}
/**
* API หาสำนักทั้งหมด by revision
*
* @summary หาสำนักทั้งหมด by revision
*
*/
@Get("active/root/{revisionId}")
async GetActiveRootByRevision(@Path() revisionId: string) {
const rawData = await this.orgRootRepository.find({
where: { orgRevisionId: revisionId },
relations: [
"orgRevision",
"orgChild1s",
"orgChild1s.orgChild2s",
"orgChild1s.orgChild2s.orgChild3s",
"orgChild1s.orgChild2s.orgChild3s.orgChild4s",
],
order: {
orgRootOrder: "ASC",
orgChild1s: {
orgChild1Order: "ASC",
orgChild2s: {
orgChild2Order: "ASC",
orgChild3s: {
orgChild3Order: "ASC",
orgChild4s: {
orgChild4Order: "ASC",
},
},
},
},
},
});
const data = rawData.map((item) => ({
...item,
orgRootCode: item.orgRootCode + "00",
}));
return new HttpSuccess(data);
}
/**
* API หา revision ล่าสุด
*
* @summary หา revision ล่าสุด
*
*/
@Get("revision/latest")
async salaryGen() {
const findRevision = await this.orgRevisionRepository.findOne({
where: { orgRevisionIsCurrent: true },
});
if (!findRevision) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบโครงสร้างล่าสุด");
}
return new HttpSuccess(findRevision.id);
}
/**
* API รายละเอียดโครงสร้าง
*
* @summary รายละเอียดโครงสร้าง (ADMIN)
*
*/
@Get("act/{id}")
async detailAct(@Path() id: string, @Request() request: RequestWithUser) {
// let _data = {
// root: null,
// child1: null,
// child2: null,
// child3: null,
// child4: null,
// };
// if (!request.user.role.includes("SUPER_ADMIN")) {
// _data = await new permission().PermissionOrgList(request, "SYS_ACTING");
// }
await new permission().PermissionOrgList(request, "SYS_ACTING");
const orgRevision = await this.orgRevisionRepository.findOne({ where: { id } });
if (!orgRevision) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
}
const orgRootData = await AppDataSource.getRepository(OrgRoot)
.createQueryBuilder("orgRoot")
.where("orgRoot.orgRevisionId = :id", { id })
// .andWhere(
// _data.root != undefined && _data.root != null
// ? _data.root[0] != null
// ? `orgRoot.id IN (:...node)`
// : `orgRoot.id is null`
// : "1=1",
// {
// node: _data.root,
// },
// )
.leftJoinAndSelect("orgRoot.posMasters", "posMasters")
.leftJoinAndSelect("posMasters.current_holder", "current_holder")
.orderBy("orgRoot.orgRootOrder", "ASC")
.getMany();
const orgRootIds = orgRootData.map((orgRoot) => orgRoot.id) || null;
const orgChild1Data =
orgRootIds && orgRootIds.length > 0
? await AppDataSource.getRepository(OrgChild1)
.createQueryBuilder("orgChild1")
.where("orgChild1.orgRootId IN (:...ids)", { ids: orgRootIds })
// .andWhere(
// _data.child1 != undefined && _data.child1 != null
// ? _data.child1[0] != null
// ? `orgChild1.id IN (:...node)`
// : `orgChild1.id is null`
// : "1=1",
// {
// node: _data.child1,
// },
// )
.leftJoinAndSelect("orgChild1.posMasters", "posMasters")
.leftJoinAndSelect("posMasters.current_holder", "current_holder")
.orderBy("orgChild1.orgChild1Order", "ASC")
.getMany()
: [];
const orgChild1Ids = orgChild1Data.map((orgChild1) => orgChild1.id) || null;
const orgChild2Data =
orgChild1Ids && orgChild1Ids.length > 0
? await AppDataSource.getRepository(OrgChild2)
.createQueryBuilder("orgChild2")
.where("orgChild2.orgChild1Id IN (:...ids)", { ids: orgChild1Ids })
// .andWhere(
// _data.child2 != undefined && _data.child2 != null
// ? _data.child2[0] != null
// ? `orgChild2.id IN (:...node)`
// : `orgChild2.id is null`
// : "1=1",
// {
// node: _data.child2,
// },
// )
.leftJoinAndSelect("orgChild2.posMasters", "posMasters")
.leftJoinAndSelect("posMasters.current_holder", "current_holder")
.orderBy("orgChild2.orgChild2Order", "ASC")
.getMany()
: [];
const orgChild2Ids = orgChild2Data.map((orgChild2) => orgChild2.id) || null;
const orgChild3Data =
orgChild2Ids && orgChild2Ids.length > 0
? await AppDataSource.getRepository(OrgChild3)
.createQueryBuilder("orgChild3")
.where("orgChild3.orgChild2Id IN (:...ids)", { ids: orgChild2Ids })
// .andWhere(
// _data.child3 != undefined && _data.child3 != null
// ? _data.child3[0] != null
// ? `orgChild3.id IN (:...node)`
// : `orgChild3.id is null`
// : "1=1",
// {
// node: _data.child3,
// },
// )
.leftJoinAndSelect("orgChild3.posMasters", "posMasters")
.leftJoinAndSelect("posMasters.current_holder", "current_holder")
.orderBy("orgChild3.orgChild3Order", "ASC")
.getMany()
: [];
const orgChild3Ids = orgChild3Data.map((orgChild3) => orgChild3.id) || null;
const orgChild4Data =
orgChild3Ids && orgChild3Ids.length > 0
? await AppDataSource.getRepository(OrgChild4)
.createQueryBuilder("orgChild4")
.where("orgChild4.orgChild3Id IN (:...ids)", { ids: orgChild3Ids })
// .andWhere(
// _data.child4 != undefined && _data.child4 != null
// ? _data.child4[0] != null
// ? `orgChild4.id IN (:...node)`
// : `orgChild4.id is null`
// : "1=1",
// {
// node: _data.child4,
// },
// )
.leftJoinAndSelect("orgChild4.posMasters", "posMasters")
.leftJoinAndSelect("posMasters.current_holder", "current_holder")
.orderBy("orgChild4.orgChild4Order", "ASC")
.getMany()
: [];
// const formattedData = orgRootData.map((orgRoot) => {
const formattedData = await Promise.all(
orgRootData.map(async (orgRoot) => {
return {
orgTreeId: orgRoot.id,
orgLevel: 0,
orgName: orgRoot.orgRootName,
orgTreeName: orgRoot.orgRootName,
orgTreeShortName: orgRoot.orgRootShortName,
orgTreeCode: orgRoot.orgRootCode,
orgCode: orgRoot.orgRootCode + "00",
orgRootName: orgRoot.orgRootName,
labelName:
orgRoot.orgRootName + " " + orgRoot.orgRootCode + "00" + " " + orgRoot.orgRootShortName,
posMaster: await Promise.all(
orgRoot.posMasters
.filter(
(x) =>
x.orgChild1Id == null &&
// x.current_holderId != null &&
x.isDirector === true,
)
// .sort((a, b) => a.posMasterOrder - b.posMasterOrder) // Sort by posMasterOrder ASC
// .slice(0, 3) // Select the first 3 rows
.map(async (x) => ({
posmasterId: x.id,
posNo: `${orgRoot.orgRootShortName} ${x.posMasterNo}`,
orgTreeId: orgRoot.id,
orgLevel: 0,
fullNameCurrentHolder:
x.current_holder == null
? null
: `${x.current_holder.prefix}${x.current_holder.firstName} ${x.current_holder.lastName}`,
})),
),
children: await Promise.all(
orgChild1Data
.filter((orgChild1) => orgChild1.orgRootId === orgRoot.id)
.map(async (orgChild1) => ({
orgTreeId: orgChild1.id,
orgRootId: orgRoot.id,
orgLevel: 1,
orgName: `${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild1.orgChild1Name,
orgTreeShortName: orgChild1.orgChild1ShortName,
orgTreeCode: orgChild1.orgChild1Code,
orgCode: orgRoot.orgRootCode + orgChild1.orgChild1Code,
orgRootName: orgRoot.orgRootName,
labelName:
orgChild1.orgChild1Name +
" " +
orgRoot.orgRootCode +
orgChild1.orgChild1Code +
" " +
orgChild1.orgChild1ShortName +
"/" +
orgRoot.orgRootName +
" " +
orgRoot.orgRootCode +
"00" +
" " +
orgRoot.orgRootShortName,
posMaster: await Promise.all(
orgChild1.posMasters
.filter(
(x) =>
x.orgChild2Id == null &&
// x.current_holderId != null &&
x.isDirector === true,
)
// .sort((a, b) => a.posMasterOrder - b.posMasterOrder) // Sort by posMasterOrder ASC
// .slice(0, 3) // Select the first 3 rows
.map(async (x) => ({
posmasterId: x.id,
posNo: `${orgChild1.orgChild1ShortName} ${x.posMasterNo}`,
orgTreeId: orgChild1.id,
orgLevel: 1,
fullNameCurrentHolder:
x.current_holder == null
? null
: `${x.current_holder.prefix}${x.current_holder.firstName} ${x.current_holder.lastName}`,
})),
),
children: await Promise.all(
orgChild2Data
.filter((orgChild2) => orgChild2.orgChild1Id === orgChild1.id)
.map(async (orgChild2) => ({
orgTreeId: orgChild2.id,
orgRootId: orgChild1.id,
orgLevel: 2,
orgName: `${orgChild2.orgChild2Name}/${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild2.orgChild2Name,
orgTreeShortName: orgChild2.orgChild2ShortName,
orgTreeCode: orgChild2.orgChild2Code,
orgCode: orgRoot.orgRootCode + orgChild2.orgChild2Code,
orgRootName: orgRoot.orgRootName,
labelName:
orgChild2.orgChild2Name +
" " +
orgRoot.orgRootCode +
orgChild2.orgChild2Code +
" " +
orgChild2.orgChild2ShortName +
"/" +
orgChild1.orgChild1Name +
" " +
orgRoot.orgRootCode +
orgChild1.orgChild1Code +
" " +
orgChild1.orgChild1ShortName +
"/" +
orgRoot.orgRootName +
" " +
orgRoot.orgRootCode +
"00" +
" " +
orgRoot.orgRootShortName,
posMaster: await Promise.all(
orgChild2.posMasters
.filter(
(x) =>
x.orgChild3Id == null &&
// x.current_holderId != null &&
x.isDirector === true,
)
// .sort((a, b) => a.posMasterOrder - b.posMasterOrder) // Sort by posMasterOrder ASC
// .slice(0, 3) // Select the first 3 rows
.map(async (x) => ({
posmasterId: x.id,
posNo: `${orgChild2.orgChild2ShortName} ${x.posMasterNo}`,
orgTreeId: orgChild2.id,
orgLevel: 2,
fullNameCurrentHolder:
x.current_holder == null
? null
: `${x.current_holder.prefix}${x.current_holder.firstName} ${x.current_holder.lastName}`,
})),
),
children: await Promise.all(
orgChild3Data
.filter((orgChild3) => orgChild3.orgChild2Id === orgChild2.id)
.map(async (orgChild3) => ({
orgTreeId: orgChild3.id,
orgRootId: orgChild2.id,
orgLevel: 3,
orgName: `${orgChild3.orgChild3Name}/${orgChild2.orgChild2Name}/${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild3.orgChild3Name,
orgTreeShortName: orgChild3.orgChild3ShortName,
orgTreeCode: orgChild3.orgChild3Code,
orgCode: orgRoot.orgRootCode + orgChild3.orgChild3Code,
orgRootName: orgRoot.orgRootName,
labelName:
orgChild3.orgChild3Name +
" " +
orgRoot.orgRootCode +
orgChild3.orgChild3Code +
" " +
orgChild3.orgChild3ShortName +
"/" +
orgChild2.orgChild2Name +
" " +
orgRoot.orgRootCode +
orgChild2.orgChild2Code +
" " +
orgChild2.orgChild2ShortName +
"/" +
orgChild1.orgChild1Name +
" " +
orgRoot.orgRootCode +
orgChild1.orgChild1Code +
" " +
orgChild1.orgChild1ShortName +
"/" +
orgRoot.orgRootName +
" " +
orgRoot.orgRootCode +
"00" +
" " +
orgRoot.orgRootShortName,
posMaster: await Promise.all(
orgChild3.posMasters
.filter(
(x) =>
x.orgChild4Id == null &&
// x.current_holderId != null &&
x.isDirector === true,
)
// .sort((a, b) => a.posMasterOrder - b.posMasterOrder) // Sort by posMasterOrder ASC
// .slice(0, 3) // Select the first 3 rows
.map(async (x) => ({
posmasterId: x.id,
posNo: `${orgChild3.orgChild3ShortName} ${x.posMasterNo}`,
orgTreeId: orgChild3.id,
orgLevel: 3,
fullNameCurrentHolder:
x.current_holder == null
? null
: `${x.current_holder.prefix}${x.current_holder.firstName} ${x.current_holder.lastName}`,
})),
),
children: await Promise.all(
orgChild4Data
.filter((orgChild4) => orgChild4.orgChild3Id === orgChild3.id)
.map(async (orgChild4) => ({
orgTreeId: orgChild4.id,
orgRootId: orgChild3.id,
orgLevel: 4,
orgName: `${orgChild4.orgChild4Name}/${orgChild3.orgChild3Name}/${orgChild2.orgChild2Name}/${orgChild1.orgChild1Name}/${orgRoot.orgRootName}`,
orgTreeName: orgChild4.orgChild4Name,
orgTreeShortName: orgChild4.orgChild4ShortName,
orgTreeCode: orgChild4.orgChild4Code,
orgCode: orgRoot.orgRootCode + orgChild4.orgChild4Code,
orgRootName: orgRoot.orgRootName,
labelName:
orgChild4.orgChild4Name +
" " +
orgRoot.orgRootCode +
orgChild4.orgChild4Code +
" " +
orgChild4.orgChild4ShortName +
"/" +
orgChild3.orgChild3Name +
" " +
orgRoot.orgRootCode +
orgChild3.orgChild3Code +
" " +
orgChild3.orgChild3ShortName +
"/" +
orgChild2.orgChild2Name +
" " +
orgRoot.orgRootCode +
orgChild2.orgChild2Code +
" " +
orgChild2.orgChild2ShortName +
"/" +
orgChild1.orgChild1Name +
" " +
orgRoot.orgRootCode +
orgChild1.orgChild1Code +
" " +
orgChild1.orgChild1ShortName +
"/" +
orgRoot.orgRootName +
" " +
orgRoot.orgRootCode +
"00" +
" " +
orgRoot.orgRootShortName,
posMaster: await Promise.all(
orgChild4.posMasters
.filter(
(x) =>
// x.current_holderId != null &&
x.isDirector === true,
)
// .sort((a, b) => a.posMasterOrder - b.posMasterOrder) // Sort by posMasterOrder ASC
// .slice(0, 3) // Select the first 3 rows
.map(async (x) => ({
posmasterId: x.id,
posNo: `${orgChild4.orgChild4ShortName} ${x.posMasterNo}`,
orgTreeId: orgChild4.id,
orgLevel: 4,
fullNameCurrentHolder:
x.current_holder == null
? null
: `${x.current_holder.prefix}${x.current_holder.firstName} ${x.current_holder.lastName}`,
})),
),
})),
),
})),
),
})),
),
})),
),
};
}),
);
return new HttpSuccess(formattedData);
}
/**
* API
*
* @summary (ADMIN)
*
* @param {string} id
*/
@Get("approver/{id}")
async getUserRootOrg(@Path() id: string, @Request() request: RequestWithUser) {
if (id == "00000000-0000-0000-0000-000000000000") {
const maps = {
id: "00000000-0000-0000-0000-000000000000",
name: "",
positionName: "ปลัดกรุงเทพมหานคร",
};
return new HttpSuccess(maps);
}
const root = await this.orgRootRepository.findOne({
where: { id: id },
});
if (!root) throw new HttpError(HttpStatusCode.NOT_FOUND, "not found. Root");
const posMaster = await this.posMasterRepository.find({
where: { orgRootId: root.id, orgChild1Id: IsNull(), current_holder: Not(IsNull()) },
relations: ["current_holder"],
});
if (!posMaster) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่ง");
const maps = posMaster.map((posMaster) => ({
id: posMaster?.current_holder?.id,
name: `${posMaster?.current_holder?.prefix}${posMaster?.current_holder?.firstName} ${posMaster?.current_holder?.lastName}`,
positionName: posMaster?.current_holder?.position,
}));
return new HttpSuccess(maps);
}
/**
* API รายละเอียดโครงสร้าง
*
* @summary ORG_023 - รายละเอียดโครงสร้าง (ADMIN) #25
*
*/
@Get("system/{id}/{system}")
async detailBySystem(
@Path() id: string,
@Path() system: string,
@Request() request: RequestWithUser,
) {
const orgRevision = await this.orgRevisionRepository.findOne({ where: { id } });
if (!orgRevision) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
}
let _data: any = {
root: null,
child1: null,
child2: null,
child3: null,
child4: null,
};
if (
(orgRevision.orgRevisionIsDraft == true && orgRevision.orgRevisionIsCurrent == false) ||
system != "SYS_ORG"
) {
_data = await new permission().PermissionOrgList(request, system.trim().toUpperCase());
}
const profile = await this.profileRepo.findOne({
where: { keycloak: request.user.sub },
relations: ["permissionProfiles", "current_holders"],
});
if (!profile) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผู้ใช้งานในทะเบียนประวัติ");
}
let _privilege = await new permission().PermissionOrgList(request, system);
const attrOwnership = _privilege.root === null ? true : false;
if (orgRevision.orgRevisionIsDraft && !orgRevision.orgRevisionIsCurrent && !attrOwnership) {
if (Array.isArray(profile.permissionProfiles) && profile.permissionProfiles.length > 0) {
_data.root = profile.permissionProfiles.map((x) => x.orgRootId);
} else {
return new HttpSuccess({ remark: "", data: [] });
}
}
// กำหนดการเข้าถึงข้อมูลตามสถานะและสิทธิ์
const isCurrentActive = !orgRevision.orgRevisionIsDraft && orgRevision.orgRevisionIsCurrent;
if (isCurrentActive) {
if (_privilege.privilege !== "OWNER") {
if (_privilege.privilege == "NORMAL") {
const holder = profile.current_holders.find((x) => x.orgRevisionId === id);
if (!holder) return;
_data.root = [holder.orgRootId];
_data.child1 = [holder.orgChild1Id];
_data.child2 = [holder.orgChild2Id];
_data.child3 = [holder.orgChild3Id];
_data.child4 = [holder.orgChild4Id];
} else if (_privilege.privilege == "CHILD" || _privilege.privilege == "BROTHER") {
const holder = profile.current_holders.find((x) => x.orgRevisionId === id);
if (!holder) return;
_data.root = [holder.orgRootId];
if (_privilege.root && _privilege.child1 === null) {
} else if (_privilege.child1 && _privilege.child2 === null) {
_data.child1 = [holder.orgChild1Id];
} else if (_privilege.child2 && _privilege.child3 === null) {
_data.child1 = [holder.orgChild1Id];
_data.child2 = [holder.orgChild2Id];
} else if (_privilege.child3 && _privilege.child4 === null) {
_data.child1 = [holder.orgChild1Id];
_data.child2 = [holder.orgChild2Id];
_data.child3 = [holder.orgChild3Id];
_data.child4 = [holder.orgChild4Id];
}
} else {
_data.root = [profile.current_holders.find((x) => x.orgRevisionId === id)?.orgRootId];
}
} else {
if (!attrOwnership) _data = _privilege;
}
}
const orgRootData = await AppDataSource.getRepository(OrgRoot)
.createQueryBuilder("orgRoot")
.where("orgRoot.orgRevisionId = :id", { id })
.andWhere(
_data.root != undefined && _data.root != null
? _data.root[0] != null
? `orgRoot.id IN (:...node)`
: `orgRoot.id is null`
: "1=1",
{
node: _data.root,
},
)
.select([
"orgRoot.id",
"orgRoot.ancestorDNA",
"orgRoot.orgRootName",
"orgRoot.orgRootShortName",
"orgRoot.orgRootCode",
"orgRoot.orgRootOrder",
"orgRoot.orgRootPhoneEx",
"orgRoot.orgRootPhoneIn",
"orgRoot.orgRootFax",
"orgRoot.orgRevisionId",
"orgRoot.orgRootRank",
"orgRoot.orgRootRankSub",
"orgRoot.DEPARTMENT_CODE",
"orgRoot.DIVISION_CODE",
"orgRoot.SECTION_CODE",
"orgRoot.JOB_CODE",
"orgRoot.responsibility",
])
.orderBy("orgRoot.orgRootOrder", "ASC")
.getMany();
const orgRootIds = orgRootData.map((orgRoot) => orgRoot.id) || null;
const orgChild1Data =
orgRootIds && orgRootIds.length > 0
? await AppDataSource.getRepository(OrgChild1)
.createQueryBuilder("orgChild1")
.where("orgChild1.orgRootId IN (:...ids)", { ids: orgRootIds })
.andWhere(
_data.child1 != undefined && _data.child1 != null
? _data.child1[0] != null
? `orgChild1.id IN (:...node)`
: `orgChild1.id is ${_data.privilege == "PARENT" ? "not null" : "null"}`
: "1=1",
{
node: _data.child1,
},
)
.select([
"orgChild1.id",
"orgChild1.ancestorDNA",
"orgChild1.orgChild1Name",
"orgChild1.orgChild1ShortName",
"orgChild1.orgChild1Code",
"orgChild1.orgChild1Order",
"orgChild1.orgChild1PhoneEx",
"orgChild1.orgChild1PhoneIn",
"orgChild1.orgChild1Fax",
"orgChild1.orgRootId",
"orgChild1.orgChild1Rank",
"orgChild1.orgChild1RankSub",
"orgChild1.DEPARTMENT_CODE",
"orgChild1.DIVISION_CODE",
"orgChild1.SECTION_CODE",
"orgChild1.JOB_CODE",
"orgChild1.responsibility",
])
.orderBy("orgChild1.orgChild1Order", "ASC")
.getMany()
: [];
const orgChild1Ids = orgChild1Data.map((orgChild1) => orgChild1.id) || null;
const orgChild2Data =
orgChild1Ids && orgChild1Ids.length > 0
? await AppDataSource.getRepository(OrgChild2)
.createQueryBuilder("orgChild2")
.where("orgChild2.orgChild1Id IN (:...ids)", { ids: orgChild1Ids })
.andWhere(
_data.child2 != undefined && _data.child2 != null
? _data.child2[0] != null
? `orgChild2.id IN (:...node)`
: `orgChild2.id is null`
: "1=1",
{
node: _data.child2,
},
)
.select([
"orgChild2.id",
"orgChild2.ancestorDNA",
"orgChild2.orgChild2Name",
"orgChild2.orgChild2ShortName",
"orgChild2.orgChild2Code",
"orgChild2.orgChild2Order",
"orgChild2.orgChild2PhoneEx",
"orgChild2.orgChild2PhoneIn",
"orgChild2.orgChild2Fax",
"orgChild2.orgRootId",
"orgChild2.orgChild2Rank",
"orgChild2.orgChild2RankSub",
"orgChild2.DEPARTMENT_CODE",
"orgChild2.DIVISION_CODE",
"orgChild2.SECTION_CODE",
"orgChild2.JOB_CODE",
"orgChild2.orgChild1Id",
"orgChild2.responsibility",
])
.orderBy("orgChild2.orgChild2Order", "ASC")
.getMany()
: [];
const orgChild2Ids = orgChild2Data.map((orgChild2) => orgChild2.id) || null;
const orgChild3Data =
orgChild2Ids && orgChild2Ids.length > 0
? await AppDataSource.getRepository(OrgChild3)
.createQueryBuilder("orgChild3")
.where("orgChild3.orgChild2Id IN (:...ids)", { ids: orgChild2Ids })
.andWhere(
_data.child3 != undefined && _data.child3 != null
? _data.child3[0] != null
? `orgChild3.id IN (:...node)`
: `orgChild3.id is null`
: "1=1",
{
node: _data.child3,
},
)
.select([
"orgChild3.id",
"orgChild3.ancestorDNA",
"orgChild3.orgChild3Name",
"orgChild3.orgChild3ShortName",
"orgChild3.orgChild3Code",
"orgChild3.orgChild3Order",
"orgChild3.orgChild3PhoneEx",
"orgChild3.orgChild3PhoneIn",
"orgChild3.orgChild3Fax",
"orgChild3.orgRootId",
"orgChild3.orgChild3Rank",
"orgChild3.orgChild3RankSub",
"orgChild3.DEPARTMENT_CODE",
"orgChild3.DIVISION_CODE",
"orgChild3.SECTION_CODE",
"orgChild3.JOB_CODE",
"orgChild3.orgChild2Id",
"orgChild3.responsibility",
])
.orderBy("orgChild3.orgChild3Order", "ASC")
.getMany()
: [];
const orgChild3Ids = orgChild3Data.map((orgChild3) => orgChild3.id) || null;
const orgChild4Data =
orgChild3Ids && orgChild3Ids.length > 0
? await AppDataSource.getRepository(OrgChild4)
.createQueryBuilder("orgChild4")
.where("orgChild4.orgChild3Id IN (:...ids)", { ids: orgChild3Ids })
.andWhere(
_data.child4 != undefined && _data.child4 != null
? _data.child4[0] != null
? `orgChild4.id IN (:...node)`
: `orgChild4.id is null`
: "1=1",
{
node: _data.child4,
},
)
.select([
"orgChild4.id",
"orgChild4.ancestorDNA",
"orgChild4.orgChild4Name",
"orgChild4.orgChild4ShortName",
"orgChild4.orgChild4Code",
"orgChild4.orgChild4Order",
"orgChild4.orgChild4PhoneEx",
"orgChild4.orgChild4PhoneIn",
"orgChild4.orgChild4Fax",
"orgChild4.orgRootId",
"orgChild4.orgChild4Rank",
"orgChild4.orgChild4RankSub",
"orgChild4.DEPARTMENT_CODE",
"orgChild4.DIVISION_CODE",
"orgChild4.SECTION_CODE",
"orgChild4.JOB_CODE",
"orgChild4.orgChild3Id",
"orgChild4.responsibility",
])
.orderBy("orgChild4.orgChild4Order", "ASC")
.getMany()
: [];
// const formattedData = orgRootData.map((orgRoot) => {
const formattedData = await Promise.all(
orgRootData.map(async (orgRoot) => {
// const sum0 = await this.posMasterRepository.find({
// where: { orgRevisionId: orgRoot.orgRevisionId, orgRootId: orgRoot.id },
// select: [
// "current_holderId",
// "next_holderId",
// "orgRootId",
// "orgChild1Id",
// "orgChild2Id",
// "orgChild3Id",
// "orgChild4Id",
// ],
// });
return {
orgTreeId: orgRoot.id,
orgTreeDnaId: orgRoot.ancestorDNA,
orgLevel: 0,
orgName: orgRoot.orgRootName,
orgTreeName: orgRoot.orgRootName,
orgTreeShortName: orgRoot.orgRootShortName,
orgTreeCode: orgRoot.orgRootCode,
orgCode: orgRoot.orgRootCode + "00",
orgTreeRank: orgRoot.orgRootRank,
orgTreeRankSub: orgRoot.orgRootRankSub,
DEPARTMENT_CODE: orgRoot.DEPARTMENT_CODE,
DIVISION_CODE: orgRoot.DIVISION_CODE,
SECTION_CODE: orgRoot.SECTION_CODE,
JOB_CODE: orgRoot.JOB_CODE,
orgTreeOrder: orgRoot.orgRootOrder,
orgTreePhoneEx: orgRoot.orgRootPhoneEx,
orgTreePhoneIn: orgRoot.orgRootPhoneIn,
orgTreeFax: orgRoot.orgRootFax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgRoot.responsibility,
labelName:
orgRoot.orgRootName + " " + orgRoot.orgRootCode + "00" + " " + orgRoot.orgRootShortName,
// totalPosition: sum0.length + 1,
// totalPositionCurrentUse:
// sum0.filter((x) => x.current_holderId != null && x.current_holderId != "").length + 1,
// totalPositionCurrentVacant:
// sum0.filter((x) => x.current_holderId == null || x.current_holderId == "").length + 1,
// totalPositionNextUse:
// sum0.filter((x) => x.next_holderId != null && x.next_holderId != "").length + 1,
// totalPositionNextVacant:
// sum0.filter((x) => x.next_holderId == null || x.next_holderId == "").length + 1,
// totalRootPosition:
// sum0.filter(
// (x) =>
// (x.orgChild1Id == null || x.orgChild1Id == "") &&
// (x.orgChild2Id == null || x.orgChild2Id == "") &&
// (x.orgChild3Id == null || x.orgChild3Id == "") &&
// (x.orgChild4Id == null || x.orgChild4Id == ""),
// ).length + 1,
// totalRootPositionCurrentUse:
// sum0.filter(
// (x) =>
// (x.orgChild1Id == null || x.orgChild1Id == "") &&
// (x.orgChild2Id == null || x.orgChild2Id == "") &&
// (x.orgChild3Id == null || x.orgChild3Id == "") &&
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// x.current_holderId != null &&
// x.current_holderId != "",
// ).length + 1,
// totalRootPositionCurrentVacant:
// sum0.filter(
// (x) =>
// (x.orgChild1Id == null || x.orgChild1Id == "") &&
// (x.orgChild2Id == null || x.orgChild2Id == "") &&
// (x.orgChild3Id == null || x.orgChild3Id == "") &&
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// (x.current_holderId == null || x.current_holderId == ""),
// ).length + 1,
// totalRootPositionNextUse:
// sum0.filter(
// (x) =>
// (x.orgChild1Id == null || x.orgChild1Id == "") &&
// (x.orgChild2Id == null || x.orgChild2Id == "") &&
// (x.orgChild3Id == null || x.orgChild3Id == "") &&
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// x.next_holderId != null &&
// x.next_holderId != "",
// ).length + 1,
// totalRootPositionNextVacant:
// sum0.filter(
// (x) =>
// (x.orgChild1Id == null || x.orgChild1Id == "") &&
// (x.orgChild2Id == null || x.orgChild2Id == "") &&
// (x.orgChild3Id == null || x.orgChild3Id == "") &&
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// (x.next_holderId == null || x.next_holderId == ""),
// ).length + 1,
children: await Promise.all(
orgChild1Data
.filter((orgChild1) => orgChild1.orgRootId === orgRoot.id)
.map(async (orgChild1) => {
// const sum1 = await this.posMasterRepository.find({
// where: {
// orgRevisionId: orgRoot.orgRevisionId,
// orgRootId: orgRoot.id,
// orgChild1Id: orgChild1.id,
// },
// select: [
// "current_holderId",
// "next_holderId",
// "orgRootId",
// "orgChild1Id",
// "orgChild2Id",
// "orgChild3Id",
// "orgChild4Id",
// ],
// });
return {
orgTreeId: orgChild1.id,
orgTreeDnaId: orgChild1.ancestorDNA,
orgRootId: orgRoot.id,
orgRootDnaId: orgRoot.ancestorDNA,
orgLevel: 1,
orgName: `${orgChild1.orgChild1Name} ${orgRoot.orgRootName}`,
orgTreeName: orgChild1.orgChild1Name,
orgTreeShortName: orgChild1.orgChild1ShortName,
orgTreeCode: orgChild1.orgChild1Code,
orgCode: orgRoot.orgRootCode + orgChild1.orgChild1Code,
orgTreeRank: orgChild1.orgChild1Rank,
orgTreeRankSub: orgChild1.orgChild1RankSub,
DEPARTMENT_CODE: orgChild1.DEPARTMENT_CODE,
DIVISION_CODE: orgChild1.DIVISION_CODE,
SECTION_CODE: orgChild1.SECTION_CODE,
JOB_CODE: orgChild1.JOB_CODE,
orgTreeOrder: orgChild1.orgChild1Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild1.orgChild1PhoneEx,
orgTreePhoneIn: orgChild1.orgChild1PhoneIn,
orgTreeFax: orgChild1.orgChild1Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild1.responsibility,
labelName:
orgChild1.orgChild1Name +
" " +
orgRoot.orgRootCode +
orgChild1.orgChild1Code +
" " +
orgChild1.orgChild1ShortName +
"/" +
orgRoot.orgRootName +
" " +
orgRoot.orgRootCode +
"00" +
" " +
orgRoot.orgRootShortName,
// totalPosition: sum1.length + 1,
// totalPositionCurrentUse:
// sum1.filter((x) => x.current_holderId != null && x.current_holderId != "")
// .length + 1,
// totalPositionCurrentVacant:
// sum1.filter((x) => x.current_holderId == null || x.current_holderId == "")
// .length + 1,
// totalPositionNextUse:
// sum1.filter((x) => x.next_holderId != null && x.next_holderId != "").length + 1,
// totalPositionNextVacant:
// sum1.filter((x) => x.next_holderId == null || x.next_holderId == "").length + 1,
// totalRootPosition:
// sum1.filter(
// (x) =>
// (x.orgChild2Id == null || x.orgChild2Id == "") &&
// (x.orgChild3Id == null || x.orgChild3Id == "") &&
// (x.orgChild4Id == null || x.orgChild4Id == ""),
// ).length + 1,
// totalRootPositionCurrentUse:
// sum1.filter(
// (x) =>
// (x.orgChild2Id == null || x.orgChild2Id == "") &&
// (x.orgChild3Id == null || x.orgChild3Id == "") &&
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// x.current_holderId != null &&
// x.current_holderId != "",
// ).length + 1,
// totalRootPositionCurrentVacant:
// sum1.filter(
// (x) =>
// (x.orgChild2Id == null || x.orgChild2Id == "") &&
// (x.orgChild3Id == null || x.orgChild3Id == "") &&
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// (x.current_holderId == null || x.current_holderId == ""),
// ).length + 1,
// totalRootPositionNextUse:
// sum1.filter(
// (x) =>
// (x.orgChild2Id == null || x.orgChild2Id == "") &&
// (x.orgChild3Id == null || x.orgChild3Id == "") &&
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// x.next_holderId != null &&
// x.next_holderId != "",
// ).length + 1,
// totalRootPositionNextVacant:
// sum1.filter(
// (x) =>
// (x.orgChild2Id == null || x.orgChild2Id == "") &&
// (x.orgChild3Id == null || x.orgChild3Id == "") &&
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// (x.next_holderId == null || x.next_holderId == ""),
// ).length + 1,
children: await Promise.all(
orgChild2Data
.filter((orgChild2) => orgChild2.orgChild1Id === orgChild1.id)
.map(async (orgChild2) => {
// const sum2 = await this.posMasterRepository.find({
// where: {
// orgRevisionId: orgRoot.orgRevisionId,
// orgRootId: orgRoot.id,
// orgChild1Id: orgChild1.id,
// orgChild2Id: orgChild2.id,
// },
// select: [
// "current_holderId",
// "next_holderId",
// "orgRootId",
// "orgChild1Id",
// "orgChild2Id",
// "orgChild3Id",
// "orgChild4Id",
// ],
// });
return {
orgTreeId: orgChild2.id,
orgTreeDnaId: orgChild2.ancestorDNA,
orgRootId: orgChild1.id,
orgRootDnaId: orgChild1.ancestorDNA,
orgLevel: 2,
orgName: `${orgChild2.orgChild2Name} ${orgChild1.orgChild1Name} ${orgRoot.orgRootName}`,
orgTreeName: orgChild2.orgChild2Name,
orgTreeShortName: orgChild2.orgChild2ShortName,
orgTreeCode: orgChild2.orgChild2Code,
orgCode: orgRoot.orgRootCode + orgChild2.orgChild2Code,
orgTreeRank: orgChild2.orgChild2Rank,
orgTreeRankSub: orgChild2.orgChild2RankSub,
DEPARTMENT_CODE: orgChild2.DEPARTMENT_CODE,
DIVISION_CODE: orgChild2.DIVISION_CODE,
SECTION_CODE: orgChild2.SECTION_CODE,
JOB_CODE: orgChild2.JOB_CODE,
orgTreeOrder: orgChild2.orgChild2Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild2.orgChild2PhoneEx,
orgTreePhoneIn: orgChild2.orgChild2PhoneIn,
orgTreeFax: orgChild2.orgChild2Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild2.responsibility,
labelName:
orgChild2.orgChild2Name +
" " +
orgRoot.orgRootCode +
orgChild2.orgChild2Code +
" " +
orgChild2.orgChild2ShortName +
"/" +
orgChild1.orgChild1Name +
" " +
orgRoot.orgRootCode +
orgChild1.orgChild1Code +
" " +
orgChild1.orgChild1ShortName +
"/" +
orgRoot.orgRootName +
" " +
orgRoot.orgRootCode +
"00" +
" " +
orgRoot.orgRootShortName,
// totalPosition: sum2.length + 1,
// totalPositionCurrentUse:
// sum2.filter(
// (x) => x.current_holderId != null && x.current_holderId != "",
// ).length + 1,
// totalPositionCurrentVacant:
// sum2.filter(
// (x) => x.current_holderId == null || x.current_holderId == "",
// ).length + 1,
// totalPositionNextUse:
// sum2.filter((x) => x.next_holderId != null && x.next_holderId != "")
// .length + 1,
// totalPositionNextVacant:
// sum2.filter((x) => x.next_holderId == null || x.next_holderId == "")
// .length + 1,
// totalRootPosition:
// sum2.filter(
// (x) =>
// (x.orgChild3Id == null || x.orgChild3Id == "") &&
// (x.orgChild4Id == null || x.orgChild4Id == ""),
// ).length + 1,
// totalRootPositionCurrentUse:
// sum2.filter(
// (x) =>
// (x.orgChild3Id == null || x.orgChild3Id == "") &&
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// x.current_holderId != null &&
// x.current_holderId != "",
// ).length + 1,
// totalRootPositionCurrentVacant:
// sum2.filter(
// (x) =>
// (x.orgChild3Id == null || x.orgChild3Id == "") &&
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// (x.current_holderId == null || x.current_holderId == ""),
// ).length + 1,
// totalRootPositionNextUse:
// sum2.filter(
// (x) =>
// (x.orgChild3Id == null || x.orgChild3Id == "") &&
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// x.next_holderId != null &&
// x.next_holderId != "",
// ).length + 1,
// totalRootPositionNextVacant:
// sum2.filter(
// (x) =>
// (x.orgChild3Id == null || x.orgChild3Id == "") &&
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// (x.next_holderId == null || x.next_holderId == ""),
// ).length + 1,
children: await Promise.all(
orgChild3Data
.filter((orgChild3) => orgChild3.orgChild2Id === orgChild2.id)
.map(async (orgChild3) => {
// const sum3 = await this.posMasterRepository.find({
// where: {
// orgRevisionId: orgRoot.orgRevisionId,
// orgRootId: orgRoot.id,
// orgChild1Id: orgChild1.id,
// orgChild2Id: orgChild2.id,
// orgChild3Id: orgChild3.id,
// },
// select: [
// "current_holderId",
// "next_holderId",
// "orgRootId",
// "orgChild1Id",
// "orgChild2Id",
// "orgChild3Id",
// "orgChild4Id",
// ],
// });
return {
orgTreeId: orgChild3.id,
orgTreeDnaId: orgChild3.ancestorDNA,
orgRootId: orgChild2.id,
orgRootDnaId: orgChild2.ancestorDNA,
orgLevel: 3,
orgName: `${orgChild3.orgChild3Name} ${orgChild2.orgChild2Name} ${orgChild1.orgChild1Name} ${orgRoot.orgRootName}`,
orgTreeName: orgChild3.orgChild3Name,
orgTreeShortName: orgChild3.orgChild3ShortName,
orgTreeCode: orgChild3.orgChild3Code,
orgCode: orgRoot.orgRootCode + orgChild3.orgChild3Code,
orgTreeRank: orgChild3.orgChild3Rank,
orgTreeRankSub: orgChild3.orgChild3RankSub,
DEPARTMENT_CODE: orgChild3.DEPARTMENT_CODE,
DIVISION_CODE: orgChild3.DIVISION_CODE,
SECTION_CODE: orgChild3.SECTION_CODE,
JOB_CODE: orgChild3.JOB_CODE,
orgTreeOrder: orgChild3.orgChild3Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild3.orgChild3PhoneEx,
orgTreePhoneIn: orgChild3.orgChild3PhoneIn,
orgTreeFax: orgChild3.orgChild3Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild3.responsibility,
labelName:
orgChild3.orgChild3Name +
" " +
orgRoot.orgRootCode +
orgChild3.orgChild3Code +
" " +
orgChild3.orgChild3ShortName +
"/" +
orgChild2.orgChild2Name +
" " +
orgRoot.orgRootCode +
orgChild2.orgChild2Code +
" " +
orgChild2.orgChild2ShortName +
"/" +
orgChild1.orgChild1Name +
" " +
orgRoot.orgRootCode +
orgChild1.orgChild1Code +
" " +
orgChild1.orgChild1ShortName +
"/" +
orgRoot.orgRootName +
" " +
orgRoot.orgRootCode +
"00" +
" " +
orgRoot.orgRootShortName,
// totalPosition: sum3.length + 1,
// totalPositionCurrentUse:
// sum3.filter(
// (x) => x.current_holderId != null && x.current_holderId != "",
// ).length + 1,
// totalPositionCurrentVacant:
// sum3.filter(
// (x) => x.current_holderId == null || x.current_holderId == "",
// ).length + 1,
// totalPositionNextUse:
// sum3.filter(
// (x) => x.next_holderId != null && x.next_holderId != "",
// ).length + 1,
// totalPositionNextVacant:
// sum3.filter(
// (x) => x.next_holderId == null || x.next_holderId == "",
// ).length + 1,
// totalRootPosition:
// sum3.filter((x) => x.orgChild4Id == null || x.orgChild4Id == "")
// .length + 1,
// totalRootPositionCurrentUse:
// sum3.filter(
// (x) =>
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// x.current_holderId != null &&
// x.current_holderId != "",
// ).length + 1,
// totalRootPositionCurrentVacant:
// sum3.filter(
// (x) =>
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// (x.current_holderId == null || x.current_holderId == ""),
// ).length + 1,
// totalRootPositionNextUse:
// sum3.filter(
// (x) =>
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// x.next_holderId != null &&
// x.next_holderId != "",
// ).length + 1,
// totalRootPositionNextVacant:
// sum3.filter(
// (x) =>
// (x.orgChild4Id == null || x.orgChild4Id == "") &&
// (x.next_holderId == null || x.next_holderId == ""),
// ).length + 1,
children: await Promise.all(
orgChild4Data
.filter((orgChild4) => orgChild4.orgChild3Id === orgChild3.id)
.map(async (orgChild4) => {
// const sum4 = await this.posMasterRepository.find({
// where: {
// orgRevisionId: orgRoot.orgRevisionId,
// orgRootId: orgRoot.id,
// orgChild1Id: orgChild1.id,
// orgChild2Id: orgChild2.id,
// orgChild3Id: orgChild3.id,
// orgChild4Id: orgChild4.id,
// },
// select: [
// "current_holderId",
// "next_holderId",
// "orgRootId",
// "orgChild1Id",
// "orgChild2Id",
// "orgChild3Id",
// "orgChild4Id",
// ],
// });
return {
orgTreeId: orgChild4.id,
orgTreeDnaId: orgChild4.ancestorDNA,
orgRootId: orgChild3.id,
orgRootDnaId: orgChild3.ancestorDNA,
orgLevel: 4,
orgName: `${orgChild4.orgChild4Name} ${orgChild3.orgChild3Name} ${orgChild2.orgChild2Name} ${orgChild1.orgChild1Name} ${orgRoot.orgRootName}`,
orgTreeName: orgChild4.orgChild4Name,
orgTreeShortName: orgChild4.orgChild4ShortName,
orgTreeCode: orgChild4.orgChild4Code,
orgCode: orgRoot.orgRootCode + orgChild4.orgChild4Code,
orgTreeRank: orgChild4.orgChild4Rank,
orgTreeRankSub: orgChild4.orgChild4RankSub,
DEPARTMENT_CODE: orgChild4.DEPARTMENT_CODE,
DIVISION_CODE: orgChild4.DIVISION_CODE,
SECTION_CODE: orgChild4.SECTION_CODE,
JOB_CODE: orgChild4.JOB_CODE,
orgTreeOrder: orgChild4.orgChild4Order,
orgRootCode: orgRoot.orgRootCode,
orgTreePhoneEx: orgChild4.orgChild4PhoneEx,
orgTreePhoneIn: orgChild4.orgChild4PhoneIn,
orgTreeFax: orgChild4.orgChild4Fax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgChild4.responsibility,
labelName:
orgChild4.orgChild4Name +
" " +
orgRoot.orgRootCode +
orgChild4.orgChild4Code +
" " +
orgChild4.orgChild4ShortName +
"/" +
orgChild3.orgChild3Name +
" " +
orgRoot.orgRootCode +
orgChild3.orgChild3Code +
" " +
orgChild3.orgChild3ShortName +
"/" +
orgChild2.orgChild2Name +
" " +
orgRoot.orgRootCode +
orgChild2.orgChild2Code +
" " +
orgChild2.orgChild2ShortName +
"/" +
orgChild1.orgChild1Name +
" " +
orgRoot.orgRootCode +
orgChild1.orgChild1Code +
" " +
orgChild1.orgChild1ShortName +
"/" +
orgRoot.orgRootName +
" " +
orgRoot.orgRootCode +
"00" +
" " +
orgRoot.orgRootShortName,
// totalPosition: sum4.length + 1,
// totalPositionCurrentUse:
// sum4.filter(
// (x) =>
// x.current_holderId != null &&
// x.current_holderId != "",
// ).length + 1,
// totalPositionCurrentVacant:
// sum4.filter(
// (x) =>
// x.current_holderId == null ||
// x.current_holderId == "",
// ).length + 1,
// totalPositionNextUse:
// sum4.filter(
// (x) =>
// x.next_holderId != null && x.next_holderId != "",
// ).length + 1,
// totalPositionNextVacant:
// sum4.filter(
// (x) =>
// x.next_holderId == null || x.next_holderId == "",
// ).length + 1,
// totalRootPosition: sum4.length + 1,
// totalRootPositionCurrentUse:
// sum4.filter(
// (x) =>
// x.current_holderId != null &&
// x.current_holderId != "",
// ).length + 1,
// totalRootPositionCurrentVacant:
// sum4.filter(
// (x) =>
// x.current_holderId == null ||
// x.current_holderId == "",
// ).length + 1,
// totalRootPositionNextUse:
// sum4.filter(
// (x) =>
// x.next_holderId != null && x.next_holderId != "",
// ).length + 1,
// totalRootPositionNextVacant:
// sum4.filter(
// (x) =>
// x.next_holderId == null || x.next_holderId == "",
// ).length + 1,
};
}),
),
};
}),
),
};
}),
),
};
}),
),
};
}),
);
return new HttpSuccess(formattedData);
}
/**
* API รายละเอียดโครงสร้าง
*
* @summary ORG_023 - รายละเอียดโครงสร้าง (ADMIN) #25
*
*/
@Get("system-root/{id}/{system}")
async detailBySystemRoot(
@Path() id: string,
@Path() system: string,
@Request() request: RequestWithUser,
) {
const orgRevision = await this.orgRevisionRepository.findOne({ where: { id } });
if (!orgRevision) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
}
let _data = {
root: null,
child1: null,
child2: null,
child3: null,
child4: null,
};
if (orgRevision.orgRevisionIsDraft == true && orgRevision.orgRevisionIsCurrent == false) {
_data = await new permission().PermissionOrgList(request, system.trim().toUpperCase());
}
const orgRootData = await AppDataSource.getRepository(OrgRoot)
.createQueryBuilder("orgRoot")
.where("orgRoot.orgRevisionId = :id", { id })
.andWhere(
_data.root != undefined && _data.root != null
? _data.root[0] != null
? `orgRoot.id IN (:...node)`
: `orgRoot.id is null`
: "1=1",
{
node: _data.root,
},
)
.select([
"orgRoot.id",
"orgRoot.orgRootName",
"orgRoot.orgRootShortName",
"orgRoot.orgRootCode",
"orgRoot.orgRootOrder",
"orgRoot.orgRootPhoneEx",
"orgRoot.orgRootPhoneIn",
"orgRoot.orgRootFax",
"orgRoot.orgRevisionId",
"orgRoot.orgRootRank",
"orgRoot.orgRootRankSub",
"orgRoot.responsibility",
"orgRoot.isDeputy",
])
.orderBy("orgRoot.orgRootOrder", "ASC")
.getMany();
const formattedData = await Promise.all(
orgRootData.map(async (orgRoot) => {
return {
orgTreeId: orgRoot.id,
orgLevel: 0,
isDeputy: orgRoot.isDeputy,
orgName: orgRoot.orgRootName,
orgTreeName: orgRoot.orgRootName,
orgTreeShortName: orgRoot.orgRootShortName,
orgTreeCode: orgRoot.orgRootCode,
orgCode: orgRoot.orgRootCode + "00",
orgTreeRank: orgRoot.orgRootRank,
orgTreeRankSub: orgRoot.orgRootRankSub,
orgTreeOrder: orgRoot.orgRootOrder,
orgTreePhoneEx: orgRoot.orgRootPhoneEx,
orgTreePhoneIn: orgRoot.orgRootPhoneIn,
orgTreeFax: orgRoot.orgRootFax,
orgRevisionId: orgRoot.orgRevisionId,
orgRootName: orgRoot.orgRootName,
responsibility: orgRoot.responsibility,
labelName:
orgRoot.orgRootName + " " + orgRoot.orgRootCode + "00" + " " + orgRoot.orgRootShortName,
totalPosition: await this.posMasterRepository.count({
where: { orgRevisionId: orgRoot.orgRevisionId, orgRootId: orgRoot.id },
}),
totalPositionCurrentUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
current_holderId: Not(IsNull()) || Not(""),
},
}),
totalPositionCurrentVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
current_holderId: IsNull() || "",
},
}),
totalPositionNextUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
next_holderId: Not(IsNull()) || Not(""),
},
}),
totalPositionNextVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
next_holderId: IsNull() || "",
},
}),
totalRootPosition: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: IsNull() || "",
orgChild2Id: IsNull() || "",
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
},
}),
totalRootPositionCurrentUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: IsNull() || "",
orgChild2Id: IsNull() || "",
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
current_holderId: Not(IsNull()) || Not(""),
},
}),
totalRootPositionCurrentVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: IsNull() || "",
orgChild2Id: IsNull() || "",
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
current_holderId: IsNull() || "",
},
}),
totalRootPositionNextUse: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: IsNull() || "",
orgChild2Id: IsNull() || "",
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
next_holderId: Not(IsNull()) || Not(""),
},
}),
totalRootPositionNextVacant: await this.posMasterRepository.count({
where: {
orgRevisionId: orgRoot.orgRevisionId,
orgRootId: orgRoot.id,
orgChild1Id: IsNull() || "",
orgChild2Id: IsNull() || "",
orgChild3Id: IsNull() || "",
orgChild4Id: IsNull() || "",
next_holderId: IsNull() || "",
},
}),
};
}),
);
return new HttpSuccess(formattedData);
}
/**
* API เช็ค org ในระบบ
*
* @summary - เช็ค org ในระบบ (ADMIN)
*
*/
@Get("check/child1/{id}")
async findIsOfficerChild1(@Path() id: string, @Request() request: RequestWithUser) {
const orgRevision = await this.orgRevisionRepository.findOne({
where: { id },
relations: ["orgChild1s"],
});
if (!orgRevision) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
}
const check = orgRevision.orgChild1s.find((x) => x.isOfficer == true);
return new HttpSuccess(check != null);
}
/**
* API เช็ค org ในระบบ
*
* @summary - เช็ค org ในระบบ (ADMIN)
*
*/
@Get("check/root/{id}")
async findIsDeputyRoot(@Path() id: string, @Request() request: RequestWithUser) {
const orgRevision = await this.orgRevisionRepository.findOne({
where: { id },
relations: ["orgRoots"],
});
if (!orgRevision) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
}
const check = orgRevision.orgRoots.find((x) => x.isDeputy == true);
return new HttpSuccess(check != null);
}
/**
* API หา สกก1
*
* @summary - หา สกก1 (ADMIN)
*
*/
@Get("find/head/officer")
async findIsHeadOfficer(@Request() request: RequestWithUser) {
const posMaster = await this.posMasterRepository.find({
where: {
orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
orgRoot: { isCommission: true },
orgChild1Id: IsNull(),
isDirector: true,
current_holderId: Not(IsNull()),
// posMasterActs: { statusReport: "DONE" },
// posMasterActChilds: { statusReport: "DONE" },
},
order: { posMasterOrder: "ASC", posMasterActChilds: { posMasterOrder: "ASC" } },
relations: [
"current_holder",
// "posMasterActChilds",
// "posMasterActChilds.posMasterChild",
// "posMasterActChilds.posMasterChild.current_holder",
],
});
if (posMaster.length <= 0) {
return new HttpSuccess({
name: "......................................................",
position: "......................................................",
});
}
if (posMaster[0].current_holder == null) {
const posMaster = await this.posMasterRepository.find({
where: {
orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
orgRoot: { isCommission: true },
orgChild1Id: IsNull(),
isDirector: true,
posMasterActs: { statusReport: "DONE" },
posMasterActChilds: { statusReport: "DONE" },
},
order: { posMasterOrder: "ASC", posMasterActChilds: { posMasterOrder: "ASC" } },
relations: [
"current_holder",
"posMasterActChilds",
"posMasterActChilds.posMasterChild",
"posMasterActChilds.posMasterChild.current_holder",
],
});
if (
posMaster[0].posMasterActChilds.length <= 0 ||
posMaster[0].posMasterActChilds[0].posMasterChild == null ||
posMaster[0].posMasterActChilds[0].posMasterChild.current_holder == null
) {
return new HttpSuccess({
name: "......................................................",
position: "......................................................",
});
}
return new HttpSuccess({
name: `${posMaster[0].posMasterActChilds[0].posMasterChild.current_holder.prefix}${posMaster[0].posMasterActChilds[0].posMasterChild.current_holder.firstName} ${posMaster[0].posMasterActChilds[0].posMasterChild.current_holder.lastName}`,
position: posMaster[0].posMasterActChilds[0].posMasterChild.current_holder.position,
});
} else {
return new HttpSuccess({
name: `${posMaster[0].current_holder.prefix}${posMaster[0].current_holder.firstName} ${posMaster[0].current_holder.lastName}`,
position: posMaster[0].current_holder.position,
});
}
}
/**
* API ลำดับโครงสร้าง
*
* @summary - ลำดับโครงสร้าง (ADMIN)
*
*/
@Get("root/search/sort")
async searchSortRootLevelType(@Request() request: RequestWithUser) {
const root1 = await this.orgRootRepository.find({
where: {
orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
DEPARTMENT_CODE: Not("50"),
},
order: { isDeputy: "DESC", orgRootOrder: "ASC" },
select: ["orgRootName"],
});
const root2 = await this.orgRootRepository.find({
where: {
orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
DEPARTMENT_CODE: "50",
},
order: { orgRootName: "ASC" },
select: ["orgRootName"],
});
const root = [...root1, ...root2];
const child1 = await this.child1Repository.find({
where: {
orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
},
order: { orgChild1Order: "ASC" },
select: ["orgChild1Name"],
});
const child2 = await this.child2Repository.find({
where: {
orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
},
order: { orgChild2Order: "ASC" },
select: ["orgChild2Name"],
});
const child3 = await this.child3Repository.find({
where: {
orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
},
order: { orgChild3Order: "ASC" },
select: ["orgChild3Name"],
});
const child4 = await this.child4Repository.find({
where: {
orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
},
order: { orgChild4Order: "ASC" },
select: ["orgChild4Name"],
});
const hospital = await this.child1Repository.find({
where: [
{
orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
orgRoot: { isDeputy: true },
},
{
orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true },
orgChild1RankSub: "HOSPITAL",
},
],
select: ["orgChild1Name"],
});
const posType = await this.posTypeRepository.find({
order: { posTypeRank: "DESC" },
select: ["posTypeName"],
});
const posLevel = await this.posLevelRepository.find({
order: { posLevelRank: "DESC" },
select: ["posLevelName"],
});
return new HttpSuccess({
root: root.map((x) => x.orgRootName),
child1: child1.map((x) => x.orgChild1Name),
child2: child2.map((x) => x.orgChild2Name),
child3: child3.map((x) => x.orgChild3Name),
child4: child4.map((x) => x.orgChild4Name),
hospital: hospital.map((x) => x.orgChild1Name),
posTypeNameOrder: posType.map((x) => x.posTypeName),
posLevelNameOrder: posLevel.map((x) => x.posLevelName),
});
}
/**
* API เพิ่มสิทธิ์โครงสร้าง
*
* @summary - เพิ่มสิทธิ์โครงสร้าง (ADMIN)
*
*/
@Get("root/add/permission/{child1Id}")
async addRootPermission(@Path() child1Id: string, @Request() request: RequestWithUser) {
const profiles = await this.profileRepo.find({
where: {
keycloak: Not(IsNull()),
current_holders: {
orgChild1Id: child1Id,
},
},
});
const orgRoots = await this.orgRootRepository.find({
where: {
orgRevision: {
orgRevisionIsDraft: true,
orgRevisionIsCurrent: false,
},
},
});
for await (const root of orgRoots) {
const _permissionOrg = profiles.map((profile) => {
const permission = new PermissionOrg();
permission.orgRootId = root.id;
permission.profileId = profile.id;
permission.createdUserId = request.user.sub;
permission.createdFullName = request.user.name;
permission.lastUpdateUserId = request.user.sub;
permission.lastUpdateFullName = request.user.name;
permission.createdAt = new Date();
permission.lastUpdatedAt = new Date();
return permission;
});
await this.permissionOrgRepository.save(_permissionOrg);
}
return new HttpSuccess();
}
/**
* API ลบข้าราชการในโครงสร้าง
*
* @summary - ลบข้าราชการในโครงสร้าง (ADMIN)
*
*/
@Get("delete/profile-officer/org/{orgRevisionId}")
async deleteOfficerRetireInOrg(
@Path() orgRevisionId: string,
@Request() request: RequestWithUser,
) {
const posMasters = await this.posMasterRepository.find({
where: {
orgRevisionId,
current_holderId: Not(IsNull()),
current_holder: {
isLeave: true,
isRetirement: true,
},
// positions: { positionIsSelected: true },
},
relations: ["positions"],
});
let checkOfficer = 0;
await Promise.all([
posMasters.map(async (posMaster) => {
posMaster.current_holderId = null;
posMaster.isSit = false;
if (posMaster.positions) {
for (const position of posMaster.positions) {
position.positionIsSelected = false;
await this.positionRepository.save(position);
checkOfficer += 1;
}
}
await this.posMasterRepository.save(posMaster);
await CreatePosMasterHistoryOfficer(posMaster.id, null);
}),
]);
return new HttpSuccess({
totalOfficer: posMasters.length,
officerSuccessAmount: checkOfficer,
});
}
/**
* API ลบลูกจ้างในโครงสร้าง
*
* @summary - ลบลูกจ้างในโครงสร้าง (ADMIN)
*
*/
@Get("delete/profile-emp/org/{orgRevisionId}")
async deleteRetireEmpInOrg(@Path() orgRevisionId: string, @Request() request: RequestWithUser) {
const posMastersEmployee = await this.employeePosMasterRepository.find({
where: {
orgRevisionId,
current_holderId: Not(IsNull()),
current_holder: {
isLeave: true,
isRetirement: true,
},
// positions: { positionIsSelected: true },
},
relations: ["positions"],
});
let checkEmployee = 0;
await Promise.all(
posMastersEmployee.map(async (posMaster) => {
posMaster.current_holderId = null;
posMaster.isSit = false;
if (posMaster.positions) {
for (const position of posMaster.positions) {
position.positionIsSelected = false;
await this.employeePositionRepository.save(position);
checkEmployee += 1;
}
}
await this.employeePosMasterRepository.save(posMaster);
await CreatePosMasterHistoryEmployee(posMaster.id, null);
}),
);
return new HttpSuccess({
totalEmployee: posMastersEmployee.length,
employeeSuccessAmount: checkEmployee,
});
}
/**
* API บันทึกลงประวัติตำแหน่ง
*
* @summary - บันทึกลงประวัติตำแหน่ง (ADMIN)
*
*/
@Get("save/profile/position-history")
async saveRetireToPositionHistory(@Request() request: RequestWithUser) {
const [profileLeave, profileEmployeeLeave] = await Promise.all([
this.profileRepo.find({
where: {
isLeave: true,
isRetirement: true,
leaveType: IsNull(),
},
}),
this.profileEmployeeRepo.find({
where: {
isLeave: true,
isRetirement: true,
leaveType: IsNull(),
},
}),
]);
let checkOfficer: number = 0;
await Promise.all(
profileLeave.map(async (profile: any) => {
const dest_item = await this.profileSalaryRepository.findOne({
where: { profileId: profile.id },
order: { order: "DESC" },
});
const data: any = {
order: dest_item == null ? 1 : dest_item.order + 1,
amount: null,
positionSalaryAmount: null,
mouthSalaryAmount: null,
profileId: profile.id,
posNo: null,
positionExecutive: null,
positionType: null,
positionLevel: null,
amountSpecial: null,
orgRoot: null,
orgChild1: null,
orgChild2: null,
orgChild3: null,
orgChild4: null,
commandYear: new Date().getFullYear() + 543,
commandDateAffect: profile.dateLeave,
commandCode: "16",
commandName: "พ้นจากราชการ",
posNoAbb: null,
isEntry: false,
positionName: "เกษียณอายุราชการ",
createdUserId: request.user.sub,
createdFullName: request.user.name,
lastUpdateUserId: request.user.sub,
lastUpdateFullName: request.user.name,
createdAt: new Date(),
lastUpdatedAt: new Date(),
remark: "ประกาศคณะอนุกรรมการสามัญข้าราชการกรุงเทพมหานครสามัญ ลว. 31 มี.ค. 68", // script เกษียณจริง ๆ ให้เอา “วันที่ประกาศเกษียณฉบับแรก” มาลงในเอกสารอ้างอิง
isGovernment: false,
};
const history = new ProfileSalaryHistory();
Object.assign(history, { ...data, id: undefined });
data.dateGovernment = profile.dateLeave;
const savedData = await this.profileSalaryRepository.save(data);
history.profileSalaryId = savedData.id;
await this.salaryHistoryRepo.save(history);
checkOfficer += 1;
}),
);
let checkEmployee: number = 0;
await Promise.all(
profileEmployeeLeave.map(async (profile: any) => {
const dest_item = await this.profileSalaryRepository.findOne({
where: { profileEmployeeId: profile.id },
order: { order: "DESC" },
});
const data: any = {
order: dest_item == null ? 1 : dest_item.order + 1,
amount: null,
positionSalaryAmount: null,
mouthSalaryAmount: null,
profileEmployeeId: profile.id,
posNo: null,
positionExecutive: null,
positionType: null,
positionLevel: null,
amountSpecial: null,
orgRoot: null,
orgChild1: null,
orgChild2: null,
orgChild3: null,
orgChild4: null,
commandYear: new Date().getFullYear() + 543,
commandDateAffect: profile.dateLeave,
commandCode: "16",
commandName: "พ้นจากราชการ",
posNoAbb: null,
isEntry: false,
positionName: "เกษียณอายุราชการ",
createdUserId: request.user.sub,
createdFullName: request.user.name,
lastUpdateUserId: request.user.sub,
lastUpdateFullName: request.user.name,
createdAt: new Date(),
lastUpdatedAt: new Date(),
remark: "ประกาศคณะอนุกรรมการสามัญข้าราชการกรุงเทพมหานครสามัญ ลว. 31 มี.ค. 68", // script เกษียณจริง ๆ ให้เอา “วันที่ประกาศเกษียณฉบับแรก” มาลงในเอกสารอ้างอิง
isGovernment: false,
};
const history = new ProfileSalaryHistory();
Object.assign(history, { ...data, id: undefined });
data.dateGovernment = profile.dateLeave;
const savedData = await this.profileSalaryRepository.save(data);
history.profileSalaryId = savedData.id;
await this.salaryHistoryRepo.save(history);
checkEmployee += 1;
}),
);
// จำนวนคนที่บันทึกลงประวัติตำแหน่ง
const totalOfficer = profileLeave.length;
const totalEmployee = profileEmployeeLeave.length;
// จำนวนคนที่ถูกบันทึกลงประวัติตำแหน่งสำเร็จ
return new HttpSuccess({
totalOfficer,
totalEmployee,
officerSuccessAmount: checkOfficer,
successEmployeeAmount: checkEmployee,
});
}
/**
* API แก้ไขเหตุผลการลาออก และปลดจาก keycloak
*
* @summary - แก้ไขเหตุผลการลาออก และปลดจาก keycloak (ADMIN)
*
*/
@Get("update/profile/leave-reason")
async updateRetireReason() {
const [profileLeave, profileEmployeeLeave, token] = await Promise.all([
this.profileRepo.find({
where: {
isLeave: true,
isRetirement: true,
leaveType: IsNull(),
},
}),
this.profileEmployeeRepo.find({
where: {
isLeave: true,
isRetirement: true,
leaveType: IsNull(),
},
}),
getToken(),
]);
if (!token)
throw new HttpError(HttpStatusCode.INTERNAL_SERVER_ERROR, "ไม่สามารถเชื่อมต่อ Keycloak");
let checkOfficer: number = 0;
let notDeleteOfficer: string[] = [];
await Promise.all(
profileLeave.map(async (profile) => {
profile.leaveReason = "เกษียณอายุราชการ";
profile.leaveType = "RETIRE";
profile.isActive = false;
if (profile.keycloak != null && profile.keycloak != "") {
const delUserKeycloak = await deleteUser(profile.keycloak, token);
if (delUserKeycloak) {
profile.keycloak = "";
profile.roleKeycloaks = [];
checkOfficer += 1;
} else {
// push array not delete
notDeleteOfficer.push(profile.keycloak);
}
}
await this.profileRepo.save(profile);
}),
);
let checkEmployee: number = 0;
let notDeleteEmployee: string[] = [];
await Promise.all(
profileEmployeeLeave.map(async (profileEmp) => {
profileEmp.leaveReason = "เกษียณอายุราชการ";
profileEmp.leaveType = "RETIRE";
profileEmp.leaveDate = new Date("2025-09-30");
profileEmp.dateLeave = new Date("2025-09-30");
profileEmp.lastUpdatedAt = new Date();
profileEmp.isActive = false;
if (profileEmp.keycloak != null && profileEmp.keycloak != "") {
const delUserKeycloak = await deleteUser(profileEmp.keycloak, token);
if (delUserKeycloak) {
profileEmp.keycloak = "";
profileEmp.roleKeycloaks = [];
checkEmployee += 1;
} else {
// push array not delete
notDeleteEmployee.push(profileEmp.keycloak);
}
}
await this.profileEmployeeRepo.save(profileEmp);
}),
);
// loop batch at 50 profiles
// const chunkSize = 50;
// for (let i = 0; i < profileLeave.length; i += chunkSize) {
// const chunk = profileLeave.slice(i, i + chunkSize);
// await Promise.all(
// chunk.map(async (profile) => {
// profile.leaveReason = "เกษียณอายุราชการ";
// profile.isActive = false;
// if (profile.keycloak != null && profile.keycloak != "") {
// const delUserKeycloak = await deleteUser(profile.keycloak, token);
// if (delUserKeycloak) {
// profile.keycloak = "";
// profile.roleKeycloaks = [];
// check += 1;
// } else {
// // push array not delete
// notDelete.push(profile.keycloak);
// }
// }
// await this.profileEmployeeRepo.save(profile);
// }),
// );
// }
// จำนวนคนที่ถูกแก้ไขเหตุผลการลาออก
const total = profileLeave.length;
return new HttpSuccess({
total,
successOfficerAmount: checkOfficer,
notDeleteOfficer,
successEmployeeAmount: checkEmployee,
notDeleteEmployee,
});
}
/**
* API สร้าง keycloak ใหม่สำหรับข้าราชการที่รันเกษียณผิด
*
* @summary - สร้าง keycloak ใหม่สำหรับข้าราชการที่รันเกษียณผิด (ADMIN)
*
*/
@Get("update/org/profile-officer/create-keycloak")
async createKeycloakForOfficer(@Request() request: RequestWithUser) {
const [profiles, token] = await Promise.all([
this.profileRepo.find({
where: {
keycloak: IsNull(),
isActive: true,
},
relations: ["roleKeycloaks"],
}),
getToken(),
]);
if (!token)
throw new HttpError(HttpStatusCode.INTERNAL_SERVER_ERROR, "ไม่สามารถเชื่อมต่อ Keycloak");
let check: number = 0;
for await (const _item of profiles) {
let password = _item.citizenId;
if (_item.birthDate != null) {
const _date = new Date(_item.birthDate.toDateString())
.getDate()
.toString()
.padStart(2, "0");
const _month = (new Date(_item.birthDate.toDateString()).getMonth() + 1)
.toString()
.padStart(2, "0");
const _year = new Date(_item.birthDate.toDateString()).getFullYear() + 543;
password = `${_date}${_month}${_year}`;
}
const checkUser = await getUserByUsername(_item.citizenId, token);
let userId: any = "";
if (checkUser.length == 0) {
userId = await createUser(
_item.citizenId,
password,
{
firstName: _item.firstName,
lastName: _item.lastName,
// email: _item.email,
},
token,
);
if (typeof userId !== "string") {
throw new Error(userId.errorMessage);
}
} else {
userId = checkUser[0].id;
}
const list = await getRoles("", token);
if (!Array.isArray(list)) throw new Error("Failed. Cannot get role(s) data from the server.");
const result = await addUserRoles(
userId,
list.filter((v) => v.id == "8a1a0dc9-304c-4e5b-a90a-65f841048212"),
token,
);
if (!result) {
throw new Error("Failed. Cannot set user's role.");
}
if (typeof userId === "string") {
_item.keycloak = userId;
}
const roleKeycloak = await this.roleKeycloakRepo.find({
where: { id: "8a1a0dc9-304c-4e5b-a90a-65f841048212" },
});
if (_item) {
_item.roleKeycloaks = Array.from(new Set([..._item.roleKeycloaks, ...roleKeycloak]));
this.profileRepo.save(_item);
check += 1;
}
}
const total = profiles.length;
return new HttpSuccess({ total, successAmount: check });
}
/**
* API สร้าง keycloak ใหม่สำหรับลูกจ้างที่รันเกษียณผิด
*
* @summary - สร้าง keycloak ใหม่สำหรับลูกจ้างที่รันเกษียณผิด (ADMIN)
*
*/
@Get("update/org/profile-employee/create-keycloak")
async createKeycloakForEmployee(@Request() request: RequestWithUser) {
let check: number = 0;
const profiles = await this.profileEmployeeRepo.find({
where: {
keycloak: IsNull(),
isLeave: false,
isRetirement: false,
},
order: { citizenId: "ASC" },
relations: ["roleKeycloaks"],
});
// ดึงข้อมูลที่ใช้บ่อยก่อน (cache)
const rolesList = await getRoles();
if (!Array.isArray(rolesList))
throw new Error("Failed. Cannot get role(s) data from the server.");
const roleKeycloak = await this.roleKeycloakRepo.find({
where: { id: "8a1a0dc9-304c-4e5b-a90a-65f841048212" },
});
// Process แบบ batch เพื่อลดการเรียก API ทีละตัว
const batchSize = 100;
const batches = [];
for (let i = 0; i < profiles.length; i += batchSize) {
batches.push(profiles.slice(i, i + batchSize));
}
for (const batch of batches) {
await Promise.all(
batch.map(async (_item) => {
let password = _item.citizenId;
if (_item.birthDate != null) {
const _date = new Date(_item.birthDate.toDateString())
.getDate()
.toString()
.padStart(2, "0");
const _month = (new Date(_item.birthDate.toDateString()).getMonth() + 1)
.toString()
.padStart(2, "0");
const _year = new Date(_item.birthDate.toDateString()).getFullYear() + 543;
password = `${_date}${_month}${_year}`;
}
try {
const checkUser = await getUserByUsername(_item.citizenId);
let userId: any = "";
if (checkUser.length == 0) {
userId = await createUser(_item.citizenId, password, {
firstName: _item.firstName,
lastName: _item.lastName,
});
if (typeof userId !== "string") {
console.error(`Failed to create user for ${_item.citizenId}:`, userId.errorMessage);
return;
}
} else {
userId = checkUser[0].id;
}
const result = await addUserRoles(
userId,
rolesList.filter((v) => v.id == "8a1a0dc9-304c-4e5b-a90a-65f841048212"),
);
if (!result) {
console.error(`Failed to set role for user ${_item.citizenId}`);
return;
}
if (typeof userId === "string") {
_item.keycloak = userId;
}
if (_item) {
_item.roleKeycloaks = Array.from(new Set([..._item.roleKeycloaks, ...roleKeycloak]));
check += 1;
await this.profileEmployeeRepo.save(_item);
}
} catch (error) {
console.error(`Error processing ${_item.citizenId}:`, error);
}
}),
);
}
const total = profiles.length;
return new HttpSuccess({ total, successAmount: check });
}
}