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 { Position } from "../entities/Position";
import { Profile } from "../entities/Profile";
import { RequestWithUser } from "../middlewares/user";
import permission from "../interfaces/permission";
import { PermissionOrg } from "../entities/PermissionOrg";
import { setLogDataDiff } from "../interfaces/utils";
import { sendToQueueOrg } from "../services/rabbitmq";

@Route("api/v1/org")
@Tags("Organization")
@Security("bearerAuth")
@Response(
  HttpStatusCode.INTERNAL_SERVER_ERROR,
  "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง",
)
export class OrganizationController extends Controller {
  private orgRevisionRepository = AppDataSource.getRepository(OrgRevision);
  private permissionOrgRepository = AppDataSource.getRepository(PermissionOrg);
  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 positionRepository = AppDataSource.getRepository(Position);
  private profileRepo = AppDataSource.getRepository(Profile);

  /**
   * 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,
  ) {
    //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 });
    //cone tree
    if (
      requestBody.typeDraft.toUpperCase() == "ORG" ||
      requestBody.typeDraft.toUpperCase() == "ORG_POSITION" ||
      requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON" ||
      requestBody.typeDraft.toUpperCase() == "ORG_POSITION_ROLE" ||
      requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON_ROLE"
    ) {
      //cone by revisionId
      if (requestBody.orgRevisionId == null)
        throw new HttpError(HttpStatusCode.NOT_FOUND, "not found.");
      const _revision = await this.orgRevisionRepository.findOne({
        where: { id: requestBody.orgRevisionId },
      });
      if (!_revision) throw new HttpError(HttpStatusCode.NOT_FOUND, "not found.");

      //หา dna tree ถ้าไม่มีให้เอาตัวเองเป็น dna
      const orgRoot = await this.orgRootRepository.find({
        where: { orgRevisionId: requestBody.orgRevisionId },
      });
      let _orgRoot: any = orgRoot.map((x) => ({
        ...x,
        ancestorDNA:
          x.ancestorDNA == null || x.ancestorDNA == "00000000-0000-0000-0000-000000000000"
            ? x.id
            : x.ancestorDNA,
      }));
      await this.orgRootRepository.save(_orgRoot);

      const orgChild1 = await this.child1Repository.find({
        where: { orgRevisionId: requestBody.orgRevisionId },
      });
      let _orgChild1: any = orgChild1.map((x) => ({
        ...x,
        ancestorDNA:
          x.ancestorDNA == null || x.ancestorDNA == "00000000-0000-0000-0000-000000000000"
            ? x.id
            : x.ancestorDNA,
      }));
      await this.child1Repository.save(_orgChild1);

      const orgChild2 = await this.child2Repository.find({
        where: { orgRevisionId: requestBody.orgRevisionId },
      });
      let _orgChild2: any = orgChild2.map((x) => ({
        ...x,
        ancestorDNA:
          x.ancestorDNA == null || x.ancestorDNA == "00000000-0000-0000-0000-000000000000"
            ? x.id
            : x.ancestorDNA,
      }));
      await this.child2Repository.save(_orgChild2);

      const orgChild3 = await this.child3Repository.find({
        where: { orgRevisionId: requestBody.orgRevisionId },
      });
      let _orgChild3: any = orgChild3.map((x) => ({
        ...x,
        ancestorDNA:
          x.ancestorDNA == null || x.ancestorDNA == "00000000-0000-0000-0000-000000000000"
            ? x.id
            : x.ancestorDNA,
      }));
      await this.child3Repository.save(_orgChild3);

      const orgChild4 = await this.child4Repository.find({
        where: { orgRevisionId: requestBody.orgRevisionId },
      });
      let _orgChild4: any = orgChild4.map((x) => ({
        ...x,
        ancestorDNA:
          x.ancestorDNA == null || x.ancestorDNA == "00000000-0000-0000-0000-000000000000"
            ? x.id
            : x.ancestorDNA,
      }));
      await this.child4Repository.save(_orgChild4);

      //หา dna posmaster ถ้าไม่มีให้เอาตัวเองเป็น dna
      const orgPosMaster = await this.posMasterRepository.find({
        where: { orgRevisionId: requestBody.orgRevisionId },
        relations: ["positions"],
      });

      let _orgPosMaster: PosMaster[];
      if (
        requestBody.typeDraft.toUpperCase() == "ORG_POSITION" ||
        requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON" ||
        requestBody.typeDraft.toUpperCase() == "ORG_POSITION_ROLE" ||
        requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON_ROLE"
      ) {
        _orgPosMaster = orgPosMaster.map((x) => ({
          ...x,
          ancestorDNA:
            x.ancestorDNA == null || x.ancestorDNA == "00000000-0000-0000-0000-000000000000"
              ? x.id
              : x.ancestorDNA,
        }));
        await this.posMasterRepository.save(_orgPosMaster);
      }
      //create org
      _orgRoot.forEach(async (x: any) => {
        var dataId = x.id;
        delete x.id;
        const data = Object.assign(new OrgRoot(), x);
        data.orgRevisionId = revision.id;
        data.createdUserId = request.user.sub;
        data.createdFullName = request.user.name;
        data.createdAt = new Date();
        data.lastUpdateUserId = request.user.sub;
        data.lastUpdateFullName = request.user.name;
        data.lastUpdatedAt = new Date();
        await this.orgRootRepository.save(data);
        if (
          requestBody.typeDraft.toUpperCase() == "ORG_POSITION" ||
          requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON" ||
          requestBody.typeDraft.toUpperCase() == "ORG_POSITION_ROLE" ||
          requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON_ROLE"
        ) {
          //create posmaster
          await Promise.all(
            _orgPosMaster
              .filter((x: PosMaster) => x.orgRootId == dataId && x.orgChild1Id == null)
              .map(async (item: any) => {
                delete item.id;
                const posMaster = Object.assign(new PosMaster(), item);
                posMaster.positions = [];
                if (
                  requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON" ||
                  requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON_ROLE"
                ) {
                  posMaster.next_holderId = item.current_holderId;
                } else {
                  posMaster.next_holderId = null;
                  posMaster.isSit = false;
                }
                if (
                  requestBody.typeDraft.toUpperCase() == "ORG_POSITION_ROLE" ||
                  requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON_ROLE"
                ) {
                  posMaster.authRoleId = item.authRoleId;
                } else {
                  posMaster.authRoleId = null;
                }
                posMaster.current_holderId = null;
                posMaster.orgRevisionId = revision.id;
                posMaster.orgRootId = data.id;
                posMaster.createdUserId = request.user.sub;
                posMaster.createdFullName = request.user.name;
                posMaster.createdAt = new Date();
                posMaster.lastUpdateUserId = request.user.sub;
                posMaster.lastUpdateFullName = request.user.name;
                posMaster.lastUpdatedAt = new Date();
                await this.posMasterRepository.save(posMaster);

                //create position
                item.positions.map(async (pos: any) => {
                  delete pos.id;
                  const position = Object.assign(new Position(), pos);
                  position.posMasterId = posMaster.id;
                  if (
                    requestBody.typeDraft.toUpperCase() == "ORG_POSITION" ||
                    requestBody.typeDraft.toUpperCase() == "ORG_POSITION_ROLE"
                  ) {
                    position.positionIsSelected = false;
                  }
                  position.createdUserId = request.user.sub;
                  position.createdFullName = request.user.name;
                  position.createdAt = new Date();
                  position.lastUpdateUserId = request.user.sub;
                  position.lastUpdateFullName = request.user.name;
                  position.lastUpdatedAt = new Date();
                  await this.positionRepository.save(position);
                });
              }),
          );
        }

        //create org
        _orgChild1
          .filter((x: OrgChild1) => x.orgRootId == dataId)
          .forEach(async (x: any) => {
            var data1Id = x.id;
            delete x.id;
            const data1 = Object.assign(new OrgChild1(), x);
            data1.orgRootId = data.id;
            data1.orgRevisionId = revision.id;
            data1.createdUserId = request.user.sub;
            data1.createdFullName = request.user.name;
            data1.createdAt = new Date();
            data1.lastUpdateUserId = request.user.sub;
            data1.lastUpdateFullName = request.user.name;
            data1.lastUpdatedAt = new Date();
            await this.child1Repository.save(data1);
            if (
              requestBody.typeDraft.toUpperCase() == "ORG_POSITION" ||
              requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON"
            ) {
              //create posmaster
              await Promise.all(
                _orgPosMaster
                  .filter((x: PosMaster) => x.orgChild1Id == data1Id && x.orgChild2Id == null)
                  .map(async (item: any) => {
                    delete item.id;
                    const posMaster = Object.assign(new PosMaster(), item);
                    posMaster.positions = [];
                    if (
                      requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON" ||
                      requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON_ROLE"
                    ) {
                      posMaster.next_holderId = item.current_holderId;
                    } else {
                      posMaster.next_holderId = null;
                      posMaster.isSit = false;
                    }
                    if (
                      requestBody.typeDraft.toUpperCase() == "ORG_POSITION_ROLE" ||
                      requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON_ROLE"
                    ) {
                      posMaster.authRoleId = item.authRoleId;
                    } else {
                      posMaster.authRoleId = null;
                    }
                    posMaster.current_holderId = null;
                    posMaster.orgRevisionId = revision.id;
                    posMaster.orgRootId = data.id;
                    posMaster.orgChild1Id = data1.id;
                    posMaster.createdUserId = request.user.sub;
                    posMaster.createdFullName = request.user.name;
                    posMaster.createdAt = new Date();
                    posMaster.lastUpdateUserId = request.user.sub;
                    posMaster.lastUpdateFullName = request.user.name;
                    posMaster.lastUpdatedAt = new Date();
                    await this.posMasterRepository.save(posMaster);

                    //create position
                    item.positions.map(async (pos: any) => {
                      delete pos.id;
                      const position = Object.assign(new Position(), pos);
                      position.posMasterId = posMaster.id;
                      if (
                        requestBody.typeDraft.toUpperCase() == "ORG_POSITION" ||
                        requestBody.typeDraft.toUpperCase() == "ORG_POSITION_ROLE"
                      ) {
                        position.positionIsSelected = false;
                      }
                      position.createdUserId = request.user.sub;
                      position.createdFullName = request.user.name;
                      position.createdAt = new Date();
                      position.lastUpdateUserId = request.user.sub;
                      position.lastUpdateFullName = request.user.name;
                      position.lastUpdatedAt = new Date();
                      await this.positionRepository.save(position);
                    });
                  }),
              );
            }

            //create org
            _orgChild2
              .filter((x: OrgChild2) => x.orgChild1Id == data1Id)
              .forEach(async (x: any) => {
                var data2Id = x.id;
                delete x.id;
                const data2 = Object.assign(new OrgChild2(), x);
                data2.orgChild1Id = data1.id;
                data2.orgRootId = data.id;
                data2.orgRevisionId = revision.id;
                data2.createdUserId = request.user.sub;
                data2.createdFullName = request.user.name;
                data2.createdAt = new Date();
                data2.lastUpdateUserId = request.user.sub;
                data2.lastUpdateFullName = request.user.name;
                data2.lastUpdatedAt = new Date();
                await this.child2Repository.save(data2);
                if (
                  requestBody.typeDraft.toUpperCase() == "ORG_POSITION" ||
                  requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON"
                ) {
                  //create posmaster
                  await Promise.all(
                    _orgPosMaster
                      .filter((x: PosMaster) => x.orgChild2Id == data2Id && x.orgChild3Id == null)
                      .map(async (item: any) => {
                        delete item.id;
                        const posMaster = Object.assign(new PosMaster(), item);
                        posMaster.positions = [];
                        if (
                          requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON" ||
                          requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON_ROLE"
                        ) {
                          posMaster.next_holderId = item.current_holderId;
                        } else {
                          posMaster.next_holderId = null;
                          posMaster.isSit = false;
                        }
                        if (
                          requestBody.typeDraft.toUpperCase() == "ORG_POSITION_ROLE" ||
                          requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON_ROLE"
                        ) {
                          posMaster.authRoleId = item.authRoleId;
                        } else {
                          posMaster.authRoleId = null;
                        }
                        posMaster.current_holderId = null;
                        posMaster.orgRevisionId = revision.id;
                        posMaster.orgRootId = data.id;
                        posMaster.orgChild1Id = data1.id;
                        posMaster.orgChild2Id = data2.id;
                        posMaster.createdUserId = request.user.sub;
                        posMaster.createdFullName = request.user.name;
                        posMaster.createdAt = new Date();
                        posMaster.lastUpdateUserId = request.user.sub;
                        posMaster.lastUpdateFullName = request.user.name;
                        posMaster.lastUpdatedAt = new Date();
                        await this.posMasterRepository.save(posMaster);

                        //create position
                        item.positions.map(async (pos: any) => {
                          delete pos.id;
                          const position = Object.assign(new Position(), pos);
                          position.posMasterId = posMaster.id;
                          if (
                            requestBody.typeDraft.toUpperCase() == "ORG_POSITION" ||
                            requestBody.typeDraft.toUpperCase() == "ORG_POSITION_ROLE"
                          ) {
                            position.positionIsSelected = false;
                          }
                          position.createdUserId = request.user.sub;
                          position.createdFullName = request.user.name;
                          position.createdAt = new Date();
                          position.lastUpdateUserId = request.user.sub;
                          position.lastUpdateFullName = request.user.name;
                          position.lastUpdatedAt = new Date();
                          await this.positionRepository.save(position);
                        });
                      }),
                  );
                }

                //create org
                _orgChild3
                  .filter((x: OrgChild3) => x.orgChild2Id == data2Id)
                  .forEach(async (x: any) => {
                    var data3Id = x.id;
                    delete x.id;
                    const data3 = Object.assign(new OrgChild3(), x);
                    data3.orgChild2Id = data2.id;
                    data3.orgChild1Id = data1.id;
                    data3.orgRootId = data.id;
                    data3.orgRevisionId = revision.id;
                    data3.createdUserId = request.user.sub;
                    data3.createdFullName = request.user.name;
                    data3.createdAt = new Date();
                    data3.lastUpdateUserId = request.user.sub;
                    data3.lastUpdateFullName = request.user.name;
                    data3.lastUpdatedAt = new Date();
                    await this.child3Repository.save(data3);
                    if (
                      requestBody.typeDraft.toUpperCase() == "ORG_POSITION" ||
                      requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON"
                    ) {
                      //create posmaster
                      await Promise.all(
                        _orgPosMaster
                          .filter(
                            (x: PosMaster) => x.orgChild3Id == data3Id && x.orgChild4Id == null,
                          )
                          .map(async (item: any) => {
                            delete item.id;
                            const posMaster = Object.assign(new PosMaster(), item);
                            posMaster.positions = [];
                            if (
                              requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON" ||
                              requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON_ROLE"
                            ) {
                              posMaster.next_holderId = item.current_holderId;
                            } else {
                              posMaster.next_holderId = null;
                              posMaster.isSit = false;
                            }
                            if (
                              requestBody.typeDraft.toUpperCase() == "ORG_POSITION_ROLE" ||
                              requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON_ROLE"
                            ) {
                              posMaster.authRoleId = item.authRoleId;
                            } else {
                              posMaster.authRoleId = null;
                            }
                            posMaster.current_holderId = null;
                            posMaster.orgRevisionId = revision.id;
                            posMaster.orgRootId = data.id;
                            posMaster.orgChild1Id = data1.id;
                            posMaster.orgChild2Id = data2.id;
                            posMaster.orgChild3Id = data3.id;
                            posMaster.createdUserId = request.user.sub;
                            posMaster.createdFullName = request.user.name;
                            posMaster.createdAt = new Date();
                            posMaster.lastUpdateUserId = request.user.sub;
                            posMaster.lastUpdateFullName = request.user.name;
                            posMaster.lastUpdatedAt = new Date();
                            await this.posMasterRepository.save(posMaster);

                            //create position
                            item.positions.map(async (pos: any) => {
                              delete pos.id;
                              const position = Object.assign(new Position(), pos);
                              position.posMasterId = posMaster.id;
                              if (
                                requestBody.typeDraft.toUpperCase() == "ORG_POSITION" ||
                                requestBody.typeDraft.toUpperCase() == "ORG_POSITION_ROLE"
                              ) {
                                position.positionIsSelected = false;
                              }
                              position.createdUserId = request.user.sub;
                              position.createdFullName = request.user.name;
                              position.createdAt = new Date();
                              position.lastUpdateUserId = request.user.sub;
                              position.lastUpdateFullName = request.user.name;
                              position.lastUpdatedAt = new Date();
                              await this.positionRepository.save(position);
                            });
                          }),
                      );
                    }

                    //create org
                    _orgChild4
                      .filter((x: OrgChild4) => x.orgChild3Id == data3Id)
                      .forEach(async (x: any) => {
                        var data4Id = x.id;
                        delete x.id;
                        const data4 = Object.assign(new OrgChild4(), x);
                        data4.orgChild3Id = data3.id;
                        data4.orgChild2Id = data2.id;
                        data4.orgChild1Id = data1.id;
                        data4.orgRootId = data.id;
                        data4.orgRevisionId = revision.id;
                        data4.createdUserId = request.user.sub;
                        data4.createdFullName = request.user.name;
                        data4.createdAt = new Date();
                        data4.lastUpdateUserId = request.user.sub;
                        data4.lastUpdateFullName = request.user.name;
                        data4.lastUpdatedAt = new Date();
                        await this.child4Repository.save(data4);
                        if (
                          requestBody.typeDraft.toUpperCase() == "ORG_POSITION" ||
                          requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON"
                        ) {
                          await Promise.all(
                            _orgPosMaster
                              .filter((x: PosMaster) => x.orgChild4Id == data4Id)
                              .map(async (item: any) => {
                                delete item.id;
                                const posMaster = Object.assign(new PosMaster(), item);
                                posMaster.positions = [];
                                if (
                                  requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON" ||
                                  requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON_ROLE"
                                ) {
                                  posMaster.next_holderId = item.current_holderId;
                                } else {
                                  posMaster.next_holderId = null;
                                  posMaster.isSit = false;
                                }
                                if (
                                  requestBody.typeDraft.toUpperCase() == "ORG_POSITION_ROLE" ||
                                  requestBody.typeDraft.toUpperCase() == "ORG_POSITION_PERSON_ROLE"
                                ) {
                                  posMaster.authRoleId = item.authRoleId;
                                } else {
                                  posMaster.authRoleId = null;
                                }
                                posMaster.current_holderId = null;
                                posMaster.orgRevisionId = revision.id;
                                posMaster.orgRootId = data.id;
                                posMaster.orgChild1Id = data1.id;
                                posMaster.orgChild2Id = data2.id;
                                posMaster.orgChild3Id = data3.id;
                                posMaster.orgChild4Id = data4.id;
                                posMaster.createdUserId = request.user.sub;
                                posMaster.createdFullName = request.user.name;
                                posMaster.createdAt = new Date();
                                posMaster.lastUpdateUserId = request.user.sub;
                                posMaster.lastUpdateFullName = request.user.name;
                                posMaster.lastUpdatedAt = new Date();
                                await this.posMasterRepository.save(posMaster);

                                //create position
                                item.positions.map(async (pos: any) => {
                                  delete pos.id;
                                  const position = Object.assign(new Position(), pos);
                                  position.posMasterId = posMaster.id;
                                  if (
                                    requestBody.typeDraft.toUpperCase() == "ORG_POSITION" ||
                                    requestBody.typeDraft.toUpperCase() == "ORG_POSITION_ROLE"
                                  ) {
                                    position.positionIsSelected = false;
                                  }
                                  position.createdUserId = request.user.sub;
                                  position.createdFullName = request.user.name;
                                  position.createdAt = new Date();
                                  position.lastUpdateUserId = request.user.sub;
                                  position.lastUpdateFullName = request.user.name;
                                  position.lastUpdatedAt = new Date();
                                  await this.positionRepository.save(position);
                                });
                              }),
                          );
                        }
                      });
                  });
              });
          });
      });
    }

    const _orgRevisions = await this.orgRevisionRepository.find({
      where: [{ orgRevisionIsDraft: true, id: Not(revision.id) }],
    });
    const _posMasters = await this.posMasterRepository.find({
      where: [{ orgRevisionId: In(_orgRevisions.map((x) => x.id)) }],
    });
    const _positions = await this.positionRepository.find({
      where: [{ posMasterId: In(_posMasters.map((x) => x.id)) }],
    });
    await this.positionRepository.remove(_positions);
    await this.posMasterRepository.remove(_posMasters);
    await this.child4Repository.delete({ orgRevisionId: In(_orgRevisions.map((x) => x.id)) });
    await this.child3Repository.delete({ orgRevisionId: In(_orgRevisions.map((x) => x.id)) });
    await this.child2Repository.delete({ orgRevisionId: In(_orgRevisions.map((x) => x.id)) });
    await this.child1Repository.delete({ orgRevisionId: In(_orgRevisions.map((x) => x.id)) });
    await this.permissionOrgRepository.delete({
      orgRootId: In(_posMasters.map((x) => x.orgRootId)),
    });
    await this.orgRootRepository.delete({ orgRevisionId: In(_orgRevisions.map((x) => x.id)) });
    await this.orgRevisionRepository.remove(_orgRevisions);

    return new HttpSuccess(revision);
  }

  /**
   * 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.orgRootName",
        "orgRoot.orgRootShortName",
        "orgRoot.orgRootCode",
        "orgRoot.orgRootOrder",
        "orgRoot.orgRootPhoneEx",
        "orgRoot.orgRootPhoneIn",
        "orgRoot.orgRootFax",
        "orgRoot.orgRevisionId",
        "orgRoot.orgRootRank",
        "orgRoot.orgRootRankSub",
        "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.orgChild1Name",
              "orgChild1.orgChild1ShortName",
              "orgChild1.orgChild1Code",
              "orgChild1.orgChild1Order",
              "orgChild1.orgChild1PhoneEx",
              "orgChild1.orgChild1PhoneIn",
              "orgChild1.orgChild1Fax",
              "orgChild1.orgRootId",
              "orgChild1.orgChild1Rank",
              "orgChild1.orgChild1RankSub",
              "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.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.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.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,
          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,
          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,
                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,
                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,
                      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,
                            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,
                                  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) {
    // 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, "ไม่พบข้อมูล");
    // }
    // if (!request.user.role.includes("SUPER_ADMIN")) {
    //   if (orgRevision.orgRevisionIsDraft == true && orgRevision.orgRevisionIsCurrent == false) {
    //     _data = await this.listAuthSysOrgFuncByRevisionIdN(request, "SYS_ORG", orgRevision.id);
    //   } else {
    //     _data = await this.listAuthSysOrgFuncByRevisionIdC(request, "SYS_ORG", orgRevision.id);
    //   }
    // }

    const orgRevision = await this.orgRevisionRepository.findOne({
      where: { id: id },
      relations: ["posMasters"],
    });
    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,
        },
      });
      if (profile == null) return new HttpSuccess([]);

      if (!request.user.role.includes("SUPER_ADMIN")) {
        if (orgRevision.orgRevisionIsDraft == true && orgRevision.orgRevisionIsCurrent == false) {
          rootId =
            orgRevision?.posMasters?.filter((x) => x.next_holderId == profile.id)[0]?.orgRootId ||
            null;
          if (!rootId) return new HttpSuccess([]);
        } else {
          rootId =
            orgRevision?.posMasters?.filter((x) => x.current_holderId == profile.id)[0]
              ?.orgRootId || null;
          if (!rootId) return new HttpSuccess([]);
        }
      }
    }

    const orgRootData = await AppDataSource.getRepository(OrgRoot)
      .createQueryBuilder("orgRoot")
      .where("orgRoot.orgRevisionId = :id", { id })
      .andWhere(rootId != null ? `orgRoot.id = :rootId` : "1=1", {
        rootId: rootId,
      })
      .select([
        "orgRoot.id",
        "orgRoot.isDeputy",
        "orgRoot.orgRootName",
        "orgRoot.orgRootShortName",
        "orgRoot.orgRootCode",
        "orgRoot.orgRootOrder",
        "orgRoot.orgRootPhoneEx",
        "orgRoot.orgRootPhoneIn",
        "orgRoot.orgRootFax",
        "orgRoot.orgRevisionId",
        "orgRoot.orgRootRank",
        "orgRoot.orgRootRankSub",
        "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 })
            .select([
              "orgChild1.id",
              "orgChild1.isOfficer",
              "orgChild1.orgChild1Name",
              "orgChild1.orgChild1ShortName",
              "orgChild1.orgChild1Code",
              "orgChild1.orgChild1Order",
              "orgChild1.orgChild1PhoneEx",
              "orgChild1.orgChild1PhoneIn",
              "orgChild1.orgChild1Fax",
              "orgChild1.orgRootId",
              "orgChild1.orgChild1Rank",
              "orgChild1.orgChild1RankSub",
              "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 })
            .select([
              "orgChild2.id",
              "orgChild2.orgChild2Name",
              "orgChild2.orgChild2ShortName",
              "orgChild2.orgChild2Code",
              "orgChild2.orgChild2Order",
              "orgChild2.orgChild2PhoneEx",
              "orgChild2.orgChild2PhoneIn",
              "orgChild2.orgChild2Fax",
              "orgChild2.orgRootId",
              "orgChild2.orgChild2Rank",
              "orgChild2.orgChild2RankSub",
              "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 })
            .select([
              "orgChild3.id",
              "orgChild3.orgChild3Name",
              "orgChild3.orgChild3ShortName",
              "orgChild3.orgChild3Code",
              "orgChild3.orgChild3Order",
              "orgChild3.orgChild3PhoneEx",
              "orgChild3.orgChild3PhoneIn",
              "orgChild3.orgChild3Fax",
              "orgChild3.orgRootId",
              "orgChild3.orgChild3Rank",
              "orgChild3.orgChild3RankSub",
              "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 })
            .select([
              "orgChild4.id",
              "orgChild4.orgChild4Name",
              "orgChild4.orgChild4ShortName",
              "orgChild4.orgChild4Code",
              "orgChild4.orgChild4Order",
              "orgChild4.orgChild4PhoneEx",
              "orgChild4.orgChild4PhoneIn",
              "orgChild4.orgChild4Fax",
              "orgChild4.orgRootId",
              "orgChild4.orgChild4Rank",
              "orgChild4.orgChild4RankSub",
              "orgChild4.orgChild3Id",
              "orgChild4.responsibility",
            ])
            .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",
          orgTreeRank: orgRoot.orgRootRank,
          orgTreeRankSub: orgRoot.orgRootRankSub,
          orgTreeOrder: orgRoot.orgRootOrder,
          orgTreePhoneEx: orgRoot.orgRootPhoneEx,
          orgTreePhoneIn: orgRoot.orgRootPhoneIn,
          orgTreeFax: orgRoot.orgRootFax,
          orgRevisionId: orgRoot.orgRevisionId,
          orgRootName: orgRoot.orgRootName,
          isDeputy: orgRoot.isDeputy,
          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() || "",
            },
          }),

          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,
                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,
                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,
                      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: 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,
                            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: 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,
                                  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: 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("{id}")
  async detail(@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;
    let _privilege = await new permission().PermissionOrgList(request, "SYS_ORG");
    attrOwnership = _privilege.root == null ? true : false;
    if (
      orgRevision.orgRevisionIsDraft == true &&
      orgRevision.orgRevisionIsCurrent == false &&
      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.orgRootName",
        "orgRoot.orgRootShortName",
        "orgRoot.orgRootCode",
        "orgRoot.orgRootOrder",
        "orgRoot.orgRootPhoneEx",
        "orgRoot.orgRootPhoneIn",
        "orgRoot.orgRootFax",
        "orgRoot.orgRevisionId",
        "orgRoot.orgRootRank",
        "orgRoot.orgRootRankSub",
        "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.orgChild1Name",
              "orgChild1.orgChild1ShortName",
              "orgChild1.orgChild1Code",
              "orgChild1.orgChild1Order",
              "orgChild1.orgChild1PhoneEx",
              "orgChild1.orgChild1PhoneIn",
              "orgChild1.orgChild1Fax",
              "orgChild1.orgRootId",
              "orgChild1.orgChild1Rank",
              "orgChild1.orgChild1RankSub",
              "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.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.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.orgChild3Id",
              "orgChild4.responsibility",
            ])
            .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",
          orgTreeRank: orgRoot.orgRootRank,
          orgTreeRankSub: orgRoot.orgRootRankSub,
          orgTreeOrder: orgRoot.orgRootOrder,
          orgTreePhoneEx: orgRoot.orgRootPhoneEx,
          orgTreePhoneIn: orgRoot.orgRootPhoneIn,
          orgTreeFax: orgRoot.orgRootFax,
          orgRevisionId: orgRoot.orgRevisionId,
          orgRootName: orgRoot.orgRootName,
          isDeputy: orgRoot.isDeputy,
          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() || "",
            },
          }),

          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,
                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,
                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,
                      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: 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,
                            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: 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,
                                  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: 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_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) {
    const today = new Date();
    today.setHours(0, 0, 0, 0); // Set time to the beginning of the day
    const orgRevisionPublish = await this.orgRevisionRepository
      .createQueryBuilder("orgRevision")
      .where("orgRevision.orgRevisionIsDraft = false")
      .andWhere("orgRevision.orgRevisionIsCurrent = true")
      .getOne();

    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"],
    };
    sendToQueueOrg(msg);
    return new HttpSuccess();
  }

  /**
   * 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 orgRevisionPublish = await this.orgRevisionRepository
      .createQueryBuilder("orgRevision")
      .where("orgRevision.orgRevisionIsDraft = false")
      .andWhere("orgRevision.orgRevisionIsCurrent = true")
      .getOne();

    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) {
      posMasterRoot = await this.posMasterRepository.find({
        where: {
          orgRevisionId: data.id,
          orgChild1Id: IsNull(),
          // current_holderId: Not(IsNull()),
        },
        relations: ["current_holder", "orgRoot"],
        order: { posMasterOrder: "ASC" },
      });
      posMasterChild1 = await this.posMasterRepository.find({
        where: {
          orgRevisionId: data.id,
          orgChild2Id: IsNull(),
          orgChild1Id: Not(IsNull()),
          // current_holderId: Not(IsNull()),
        },
        relations: ["current_holder", "orgChild1"],
        order: { posMasterOrder: "ASC" },
      });
      posMasterChild2 = await this.posMasterRepository.find({
        where: {
          orgRevisionId: data.id,
          orgChild3Id: IsNull(),
          orgChild2Id: Not(IsNull()),
          // current_holderId: Not(IsNull()),
        },
        relations: ["current_holder", "orgChild2"],
        order: { posMasterOrder: "ASC" },
      });
      posMasterChild3 = await this.posMasterRepository.find({
        where: {
          orgRevisionId: data.id,
          orgChild4Id: IsNull(),
          orgChild3Id: Not(IsNull()),
          // current_holderId: Not(IsNull()),
        },
        relations: ["current_holder", "orgChild3"],
        order: { posMasterOrder: "ASC" },
      });
      posMasterChild4 = await this.posMasterRepository.find({
        where: {
          orgRevisionId: data.id,
          orgChild4Id: Not(IsNull()),
          // current_holderId: Not(IsNull()),
        },
        relations: ["current_holder", "orgChild4"],
        order: { posMasterOrder: "ASC" },
      });

      let formattedData = posMasterRoot
        .filter((x: any) => x.current_holderId != null && x.isDirector)
        .map((x0: PosMaster) => {
          // Level 2
          const childLevel1 = [
            // Level 2: Root not director
            ...posMasterRoot
              .filter(
                (x: any) =>
                  x.orgRootId == x0.orgRootId && x.current_holderId != null && !x.isDirector,
              )
              .map((x00: PosMaster) => ({
                level: 2,
                personID: x00.current_holder ? x00.current_holder.id : "",
                name: x00.current_holder
                  ? `${x00.current_holder.firstName} ${x00.current_holder.lastName}`
                  : "ว่าง",
                avatar:
                  x00.current_holder &&
                  x00.current_holder.avatar != null &&
                  x00.current_holder.avatarName != null
                    ? `${x00.current_holder.avatar}/${x00.current_holder.avatarName}`
                    : null,
                positionName: x00.current_holder ? x00.current_holder.position : "",
                positionNum: x00.orgRoot.orgRootShortName + x00.posMasterNo,
                positionNumInt: x00.posMasterNo,
                departmentName: x00.orgRoot.orgRootName,
                organizationId: x00.orgRoot.id,
                children: [],
              })),
            // Level 2: Child 1 director
            ...posMasterChild1
              .filter((x: any) => x.isDirector && x.orgRootId == x0.orgRootId)
              .map((x1: PosMaster) => {
                // Level 3
                const childLevel2 = [
                  // Level 3: Child 1 not director
                  ...posMasterChild1
                    .filter(
                      (x: any) =>
                        x.orgChild1Id == x1.orgChild1Id &&
                        !x.isDirector &&
                        x.current_holderId != null,
                    )
                    .map((x11: PosMaster) => {
                      return {
                        level: 3,
                        personID: x11.current_holder ? x11.current_holder.id : "",
                        name: x11.current_holder
                          ? `${x11.current_holder.firstName} ${x11.current_holder.lastName}`
                          : "ว่าง",
                        avatar:
                          x11.current_holder &&
                          x11.current_holder.avatar != null &&
                          x11.current_holder.avatarName != null
                            ? `${x11.current_holder.avatar}/${x11.current_holder.avatarName}`
                            : null,
                        positionName: x11.current_holder ? x11.current_holder.position : "",
                        positionNum: x11.orgChild1.orgChild1ShortName + x11.posMasterNo,
                        positionNumInt: x11.posMasterNo,
                        departmentName: x11.orgChild1.orgChild1Name,
                        organizationId: x11.orgChild1.id,
                        children: [],
                      };
                    }),
                  // Level 3: Child 2 director
                  ...posMasterChild2
                    .filter((x: any) => x.isDirector && x.orgChild1Id == x1.orgChild1Id)
                    .map((x2: PosMaster) => {
                      const childLevel3 = [
                        // Level 4: Child 2 not director
                        ...posMasterChild2
                          .filter(
                            (x: any) =>
                              !x.isDirector &&
                              x.current_holderId != null &&
                              x.orgChild1Id == x2.orgChild1Id,
                          )
                          .map((x22: PosMaster) => ({
                            level: 4,
                            personID: x22.current_holder ? x22.current_holder.id : "",
                            name: x22.current_holder
                              ? `${x22.current_holder.firstName} ${x22.current_holder.lastName}`
                              : "ว่าง",
                            avatar:
                              x22.current_holder &&
                              x22.current_holder.avatar != null &&
                              x22.current_holder.avatarName != null
                                ? `${x22.current_holder.avatar}/${x22.current_holder.avatarName}`
                                : null,
                            positionName: x22.current_holder ? x22.current_holder.position : "",
                            positionNum: `${x22.orgChild2.orgChild2ShortName} ${x22.posMasterNo}`,
                            positionNumInt: x22.posMasterNo,
                            departmentName: x22.orgChild2.orgChild2Name,
                            organizationId: x22.orgChild2.id,
                            children: [],
                          })),
                        // Level 4: Child 3 director
                        ...posMasterChild3
                          .filter((x: any) => x.isDirector && x.orgChild2Id == x2.orgChild2Id)
                          .map((x3: PosMaster) => {
                            const childLevel4 = [
                              ...posMasterChild3
                                .filter(
                                  (x: any) =>
                                    !x.isDirector &&
                                    x.current_holderId != null &&
                                    x.orgChild2Id == x3.orgChild2Id,
                                )
                                .map((x33: PosMaster) => ({
                                  level: 5,
                                  personID: x33.current_holder ? x33.current_holder.id : "",
                                  name: x33.current_holder
                                    ? `${x33.current_holder.firstName} ${x33.current_holder.lastName}`
                                    : "ว่าง",
                                  avatar:
                                    x33.current_holder &&
                                    x33.current_holder.avatar != null &&
                                    x33.current_holder.avatarName != null
                                      ? `${x33.current_holder.avatar}/${x33.current_holder.avatarName}`
                                      : null,
                                  positionName: x33.current_holder
                                    ? x33.current_holder.position
                                    : "",
                                  positionNum: x33.orgChild3.orgChild3ShortName + x33.posMasterNo,
                                  positionNumInt: x33.posMasterNo,
                                  departmentName: x33.orgChild3.orgChild3Name,
                                  organizationId: x33.orgChild3.id,
                                  children: [],
                                })),
                              ...posMasterChild4
                                .filter((x: any) => x.isDirector && x.orgChild3Id == x3.orgChild3Id)
                                .map((x4: PosMaster) => {
                                  const childLevel5 = posMasterChild4
                                    .filter(
                                      (x: any) =>
                                        !x.isDirector &&
                                        x.current_holderId != null &&
                                        x.orgChild3Id == x4.orgChild3Id,
                                    )
                                    .map((x44: PosMaster) => ({
                                      level: 5,
                                      personID: x44.current_holder ? x44.current_holder.id : "",
                                      name: x44.current_holder
                                        ? `${x44.current_holder.firstName} ${x44.current_holder.lastName}`
                                        : "ว่าง",
                                      avatar:
                                        x44.current_holder &&
                                        x44.current_holder.avatar != null &&
                                        x44.current_holder.avatarName != null
                                          ? `${x44.current_holder.avatar}/${x44.current_holder.avatarName}`
                                          : null,
                                      positionName: x44.current_holder
                                        ? x44.current_holder.position
                                        : "",
                                      positionNum:
                                        x44.orgChild4.orgChild4ShortName + x44.posMasterNo,
                                      positionNumInt: x44.posMasterNo,
                                      departmentName: x44.orgChild4.orgChild4Name,
                                      organizationId: x44.orgChild4.id,
                                      children: [],
                                    }));

                                  return {
                                    level: 4,
                                    personID: x4.current_holder ? x4.current_holder.id : "",
                                    name: x4.current_holder
                                      ? `${x4.current_holder.firstName} ${x4.current_holder.lastName}`
                                      : "ว่าง",
                                    avatar:
                                      x4.current_holder &&
                                      x4.current_holder.avatar != null &&
                                      x4.current_holder.avatarName != null
                                        ? `${x4.current_holder.avatar}/${x4.current_holder.avatarName}`
                                        : null,
                                    positionName: x4.current_holder
                                      ? x4.current_holder.position
                                      : "",
                                    positionNum: x4.orgChild4.orgChild4ShortName + x4.posMasterNo,
                                    positionNumInt: x4.posMasterNo,
                                    departmentName: x4.orgChild4.orgChild4Name,
                                    organizationId: x4.orgChild4.id,
                                    children: childLevel5,
                                  };
                                }),
                            ];

                            return {
                              level: 4,
                              personID: x3.current_holder ? x3.current_holder.id : "",
                              name: x3.current_holder
                                ? `${x3.current_holder.firstName} ${x3.current_holder.lastName}`
                                : "ว่าง",
                              avatar:
                                x3.current_holder &&
                                x3.current_holder.avatar != null &&
                                x3.current_holder.avatarName != null
                                  ? `${x3.current_holder.avatar}/${x3.current_holder.avatarName}`
                                  : null,
                              positionName: x3.current_holder ? x3.current_holder.position : "",
                              positionNum: `${x3.orgChild3.orgChild3ShortName} ${x3.posMasterNo}`,
                              positionNumInt: x3.posMasterNo,
                              departmentName: x3.orgChild3.orgChild3Name,
                              organizationId: x3.orgChild3.id,
                              children: childLevel4,
                            };
                          }),
                      ];

                      return {
                        level: 3,
                        personID: x2.current_holder ? x2.current_holder.id : "",
                        name: x2.current_holder
                          ? `${x2.current_holder.firstName} ${x2.current_holder.lastName}`
                          : "ว่าง",
                        avatar:
                          x2.current_holder &&
                          x2.current_holder.avatar != null &&
                          x2.current_holder.avatarName != null
                            ? `${x2.current_holder.avatar}/${x2.current_holder.avatarName}`
                            : null,
                        positionName: x2.current_holder ? x2.current_holder.position : "",
                        positionNum: x2.orgChild2.orgChild2ShortName + x2.posMasterNo,
                        positionNumInt: x2.posMasterNo,
                        departmentName: x2.orgChild2.orgChild2Name,
                        organizationId: x2.orgChild2.id,
                        children: childLevel3,
                      };
                    }),
                ];

                return {
                  level: 2,
                  personID: x1.current_holder ? x1.current_holder.id : "",
                  name: x1.current_holder
                    ? `${x1.current_holder.firstName} ${x1.current_holder.lastName}`
                    : "ว่าง",
                  avatar:
                    x1.current_holder &&
                    x1.current_holder.avatar != null &&
                    x1.current_holder.avatarName != null
                      ? `${x1.current_holder.avatar}/${x1.current_holder.avatarName}`
                      : null,
                  positionName: x1.current_holder ? x1.current_holder.position : "",
                  positionNum: x1.orgChild1.orgChild1ShortName + x1.posMasterNo,
                  positionNumInt: x1.posMasterNo,
                  departmentName: x1.orgChild1.orgChild1Name,
                  organizationId: x1.orgChild1.id,
                  children: childLevel2,
                };
              }),
          ];

          // Root Level 1
          return {
            level: 1,
            personID: x0.current_holder.id,
            name: `${x0.current_holder.firstName} ${x0.current_holder.lastName}`,
            avatar:
              x0.current_holder &&
              x0.current_holder.avatar != null &&
              x0.current_holder.avatarName != null
                ? `${x0.current_holder.avatar}/${x0.current_holder.avatarName}`
                : null,
            positionName: x0.current_holder.position,
            positionNum: x0.orgRoot.orgRootShortName + x0.posMasterNo,
            positionNumInt: x0.posMasterNo,
            departmentName: x0.orgRoot.orgRootName,
            organizationId: x0.orgRoot.id,
            children: childLevel1,
          };
        });

      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) {
      posMasterRoot = await this.posMasterRepository.find({
        where: {
          orgRevisionId: data.id,
          orgChild1Id: IsNull(),
          // next_holderId: Not(IsNull()),
        },
        relations: ["next_holder", "orgRoot"],
      });
      posMasterChild1 = await this.posMasterRepository.find({
        where: {
          orgRevisionId: data.id,
          orgChild2Id: IsNull(),
          orgChild1Id: Not(IsNull()),
          // next_holderId: Not(IsNull()),
        },
        relations: ["next_holder", "orgChild1"],
      });
      posMasterChild2 = await this.posMasterRepository.find({
        where: {
          orgRevisionId: data.id,
          orgChild3Id: IsNull(),
          orgChild2Id: Not(IsNull()),
          // next_holderId: Not(IsNull()),
        },
        relations: ["next_holder", "orgChild2"],
      });
      posMasterChild3 = await this.posMasterRepository.find({
        where: {
          orgRevisionId: data.id,
          orgChild4Id: IsNull(),
          orgChild3Id: Not(IsNull()),
          // next_holderId: Not(IsNull()),
        },
        relations: ["next_holder", "orgChild3"],
      });
      posMasterChild4 = await this.posMasterRepository.find({
        where: {
          orgRevisionId: data.id,
          orgChild4Id: Not(IsNull()),
          // next_holderId: Not(IsNull()),
        },
        relations: ["next_holder", "orgChild4"],
      });

      let formattedData = posMasterRoot
        .filter((x: any) => x.next_holderId != null && x.isDirector)
        .map((x0: PosMaster) => {
          // Level 2
          const childLevel1 = [
            // Level 2: Root not director
            ...posMasterRoot
              .filter(
                (x: any) => x.orgRootId == x0.orgRootId && x.next_holderId != null && !x.isDirector,
              )
              .map((x00: PosMaster) => ({
                level: 2,
                personID: x00.next_holder ? x00.next_holder.id : "",
                name: x00.next_holder
                  ? `${x00.next_holder.firstName} ${x00.next_holder.lastName}`
                  : "ว่าง",
                avatar:
                  x00.next_holder &&
                  x00.next_holder.avatar != null &&
                  x00.next_holder.avatarName != null
                    ? `${x00.next_holder.avatar}/${x00.next_holder.avatarName}`
                    : null,
                positionName: x00.next_holder ? x00.next_holder.position : "",
                positionNum: x00.orgRoot.orgRootShortName + x00.posMasterNo,
                positionNumInt: x00.posMasterNo,
                departmentName: x00.orgRoot.orgRootName,
                organizationId: x00.orgRoot.id,
                children: [],
              })),
            // Level 2: Child 1 director
            ...posMasterChild1
              .filter((x: any) => x.isDirector && x.orgRootId == x0.orgRootId)
              .map((x1: PosMaster) => {
                // Level 3
                const childLevel2 = [
                  // Level 3: Child 1 not director
                  ...posMasterChild1
                    .filter(
                      (x: any) =>
                        x.orgChild1Id == x1.orgChild1Id && !x.isDirector && x.next_holderId != null,
                    )
                    .map((x11: PosMaster) => {
                      return {
                        level: 3,
                        personID: x11.next_holder ? x11.next_holder.id : "",
                        name: x11.next_holder
                          ? `${x11.next_holder.firstName} ${x11.next_holder.lastName}`
                          : "ว่าง",
                        avatar:
                          x11.next_holder &&
                          x11.next_holder.avatar != null &&
                          x11.next_holder.avatarName != null
                            ? `${x11.next_holder.avatar}/${x11.next_holder.avatarName}`
                            : null,
                        positionName: x11.next_holder ? x11.next_holder.position : "",
                        positionNum: x11.orgChild1.orgChild1ShortName + x11.posMasterNo,
                        positionNumInt: x11.posMasterNo,
                        departmentName: x11.orgChild1.orgChild1Name,
                        organizationId: x11.orgChild1.id,
                        children: [],
                      };
                    }),
                  // Level 3: Child 2 director
                  ...posMasterChild2
                    .filter((x: any) => x.isDirector && x.orgChild1Id == x1.orgChild1Id)
                    .map((x2: PosMaster) => {
                      const childLevel3 = [
                        // Level 4: Child 2 not director
                        ...posMasterChild2
                          .filter(
                            (x: any) =>
                              !x.isDirector &&
                              x.next_holderId != null &&
                              x.orgChild1Id == x2.orgChild1Id,
                          )
                          .map((x22: PosMaster) => ({
                            level: 4,
                            personID: x22.next_holder ? x22.next_holder.id : "",
                            name: x22.next_holder
                              ? `${x22.next_holder.firstName} ${x22.next_holder.lastName}`
                              : "ว่าง",
                            avatar:
                              x22.next_holder &&
                              x22.next_holder.avatar != null &&
                              x22.next_holder.avatarName != null
                                ? `${x22.next_holder.avatar}/${x22.next_holder.avatarName}`
                                : null,
                            positionName: x22.next_holder ? x22.next_holder.position : "",
                            positionNum: `${x22.orgChild2.orgChild2ShortName} ${x22.posMasterNo}`,
                            positionNumInt: x22.posMasterNo,
                            departmentName: x22.orgChild2.orgChild2Name,
                            organizationId: x22.orgChild2.id,
                            children: [],
                          })),
                        // Level 4: Child 3 director
                        ...posMasterChild3
                          .filter((x: any) => x.isDirector && x.orgChild2Id == x2.orgChild2Id)
                          .map((x3: PosMaster) => {
                            const childLevel4 = [
                              ...posMasterChild3
                                .filter(
                                  (x: any) =>
                                    !x.isDirector &&
                                    x.next_holderId != null &&
                                    x.orgChild2Id == x3.orgChild2Id,
                                )
                                .map((x33: PosMaster) => ({
                                  level: 5,
                                  personID: x33.next_holder ? x33.next_holder.id : "",
                                  name: x33.next_holder
                                    ? `${x33.next_holder.firstName} ${x33.next_holder.lastName}`
                                    : "ว่าง",
                                  avatar:
                                    x33.next_holder &&
                                    x33.next_holder.avatar != null &&
                                    x33.next_holder.avatarName != null
                                      ? `${x33.next_holder.avatar}/${x33.next_holder.avatarName}`
                                      : null,
                                  positionName: x33.next_holder ? x33.next_holder.position : "",
                                  positionNum: x33.orgChild3.orgChild3ShortName + x33.posMasterNo,
                                  positionNumInt: x33.posMasterNo,
                                  departmentName: x33.orgChild3.orgChild3Name,
                                  organizationId: x33.orgChild3.id,
                                  children: [],
                                })),
                              ...posMasterChild4
                                .filter((x: any) => x.isDirector && x.orgChild3Id == x3.orgChild3Id)
                                .map((x4: PosMaster) => {
                                  const childLevel5 = posMasterChild4
                                    .filter(
                                      (x: any) =>
                                        !x.isDirector &&
                                        x.next_holderId != null &&
                                        x.orgChild3Id == x4.orgChild3Id,
                                    )
                                    .map((x44: PosMaster) => ({
                                      level: 5,
                                      personID: x44.next_holder ? x44.next_holder.id : "",
                                      name: x44.next_holder
                                        ? `${x44.next_holder.firstName} ${x44.next_holder.lastName}`
                                        : "ว่าง",
                                      avatar:
                                        x44.next_holder &&
                                        x44.next_holder.avatar != null &&
                                        x44.next_holder.avatarName != null
                                          ? `${x44.next_holder.avatar}/${x44.next_holder.avatarName}`
                                          : null,
                                      positionName: x44.next_holder ? x44.next_holder.position : "",
                                      positionNum:
                                        x44.orgChild4.orgChild4ShortName + x44.posMasterNo,
                                      positionNumInt: x44.posMasterNo,
                                      departmentName: x44.orgChild4.orgChild4Name,
                                      organizationId: x44.orgChild4.id,
                                      children: [],
                                    }));

                                  return {
                                    level: 4,
                                    personID: x4.next_holder ? x4.next_holder.id : "",
                                    name: x4.next_holder
                                      ? `${x4.next_holder.firstName} ${x4.next_holder.lastName}`
                                      : "ว่าง",
                                    avatar:
                                      x4.next_holder &&
                                      x4.next_holder.avatar != null &&
                                      x4.next_holder.avatarName != null
                                        ? `${x4.next_holder.avatar}/${x4.next_holder.avatarName}`
                                        : null,
                                    positionName: x4.next_holder ? x4.next_holder.position : "",
                                    positionNum: x4.orgChild4.orgChild4ShortName + x4.posMasterNo,
                                    positionNumInt: x4.posMasterNo,
                                    departmentName: x4.orgChild4.orgChild4Name,
                                    organizationId: x4.orgChild4.id,
                                    children: childLevel5,
                                  };
                                }),
                            ];

                            return {
                              level: 4,
                              personID: x3.next_holder ? x3.next_holder.id : "",
                              name: x3.next_holder
                                ? `${x3.next_holder.firstName} ${x3.next_holder.lastName}`
                                : "ว่าง",
                              avatar:
                                x3.next_holder &&
                                x3.next_holder.avatar != null &&
                                x3.next_holder.avatarName != null
                                  ? `${x3.next_holder.avatar}/${x3.next_holder.avatarName}`
                                  : null,
                              positionName: x3.next_holder ? x3.next_holder.position : "",
                              positionNum: `${x3.orgChild3.orgChild3ShortName} ${x3.posMasterNo}`,
                              positionNumInt: x3.posMasterNo,
                              departmentName: x3.orgChild3.orgChild3Name,
                              organizationId: x3.orgChild3.id,
                              children: childLevel4,
                            };
                          }),
                      ];

                      return {
                        level: 3,
                        personID: x2.next_holder ? x2.next_holder.id : "",
                        name: x2.next_holder
                          ? `${x2.next_holder.firstName} ${x2.next_holder.lastName}`
                          : "ว่าง",
                        avatar:
                          x2.next_holder &&
                          x2.next_holder.avatar != null &&
                          x2.next_holder.avatarName != null
                            ? `${x2.next_holder.avatar}/${x2.next_holder.avatarName}`
                            : null,
                        positionName: x2.next_holder ? x2.next_holder.position : "",
                        positionNum: x2.orgChild2.orgChild2ShortName + x2.posMasterNo,
                        positionNumInt: x2.posMasterNo,
                        departmentName: x2.orgChild2.orgChild2Name,
                        organizationId: x2.orgChild2.id,
                        children: childLevel3,
                      };
                    }),
                ];

                return {
                  level: 2,
                  personID: x1.next_holder ? x1.next_holder.id : "",
                  name: x1.next_holder
                    ? `${x1.next_holder.firstName} ${x1.next_holder.lastName}`
                    : "ว่าง",
                  avatar:
                    x1.next_holder &&
                    x1.next_holder.avatar != null &&
                    x1.next_holder.avatarName != null
                      ? `${x1.next_holder.avatar}/${x1.next_holder.avatarName}`
                      : null,
                  positionName: x1.next_holder ? x1.next_holder.position : "",
                  positionNum: x1.orgChild1.orgChild1ShortName + x1.posMasterNo,
                  positionNumInt: x1.posMasterNo,
                  departmentName: x1.orgChild1.orgChild1Name,
                  organizationId: x1.orgChild1.id,
                  children: childLevel2,
                };
              }),
          ];

          // Root Level 1
          return {
            level: 1,
            personID: x0.next_holder.id,
            name: `${x0.next_holder.firstName} ${x0.next_holder.lastName}`,
            avatar:
              x0.next_holder && x0.next_holder.avatar != null && x0.next_holder.avatarName != null
                ? `${x0.next_holder.avatar}/${x0.next_holder.avatarName}`
                : null,
            positionName: x0.next_holder.position,
            positionNum: x0.orgRoot.orgRootShortName + x0.posMasterNo,
            positionNumInt: x0.posMasterNo,
            departmentName: x0.orgRoot.orgRootName,
            organizationId: x0.orgRoot.id,
            children: childLevel1,
          };
        });

      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 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: { orgRevisionId: 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 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,
          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,
          root: data.orgRoot == null ? null : data.orgRoot.orgRootName,
          rootShortName: data.orgRoot == null ? null : data.orgRoot.orgRootShortName,
          child1Id: data.id,
          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,
          root: data.orgRoot == null ? null : data.orgRoot.orgRootName,
          rootShortName: data.orgRoot == null ? null : data.orgRoot.orgRootShortName,
          child1Id: data.orgChild1Id,
          child1: data.orgChild1 == null ? null : data.orgChild1.orgChild1Name,
          child1ShortName: data.orgChild1 == null ? null : data.orgChild1.orgChild1ShortName,
          child2Id: data.id,
          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,
          root: data.orgRoot == null ? null : data.orgRoot.orgRootName,
          rootShortName: data.orgRoot == null ? null : data.orgRoot.orgRootShortName,
          child1Id: data.orgChild1Id,
          child1: data.orgChild1 == null ? null : data.orgChild1.orgChild1Name,
          child1ShortName: data.orgChild1 == null ? null : data.orgChild1.orgChild1ShortName,
          child2Id: data.orgChild2Id,
          child2: data.orgChild2 == null ? null : data.orgChild2.orgChild2Name,
          child2ShortName: data.orgChild2 == null ? null : data.orgChild2.orgChild2ShortName,
          child3Id: data.id,
          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,
          root: data.orgRoot == null ? null : data.orgRoot.orgRootName,
          rootShortName: data.orgRoot == null ? null : data.orgRoot.orgRootShortName,
          child1Id: data.orgChild1Id,
          child1: data.orgChild1 == null ? null : data.orgChild1.orgChild1Name,
          child1ShortName: data.orgChild1 == null ? null : data.orgChild1.orgChild1ShortName,
          child2Id: data.orgChild2Id,
          child2: data.orgChild2 == null ? null : data.orgChild2.orgChild2Name,
          child2ShortName: data.orgChild2 == null ? null : data.orgChild2.orgChild2ShortName,
          child3Id: data.orgChild3Id,
          child3: data.orgChild3 == null ? null : data.orgChild3.orgChild3Name,
          child3ShortName: data.orgChild3 == null ? null : data.orgChild3.orgChild3ShortName,
          child4Id: data.id,
          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 },
    });
    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 },
    });
    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 data = await this.orgRootRepository.find({
      where: { orgRevisionId: revisionId },
      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 หา 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.posMasterOrder <= 3 &&
                  x.isDirector === true,
              )
              .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,
                posMaster: await Promise.all(
                  orgChild1.posMasters
                    .filter(
                      (x) =>
                        x.orgChild2Id == null &&
                        x.current_holderId != null &&
                        x.posMasterOrder <= 3 &&
                        x.isDirector === true,
                    )
                    .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,
                      posMaster: await Promise.all(
                        orgChild2.posMasters
                          .filter(
                            (x) =>
                              x.orgChild3Id == null &&
                              x.current_holderId != null &&
                              x.posMasterOrder <= 3 &&
                              x.isDirector === true,
                          )
                          .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,
                            posMaster: await Promise.all(
                              orgChild3.posMasters
                                .filter(
                                  (x) =>
                                    x.orgChild4Id == null &&
                                    x.current_holderId != null &&
                                    x.posMasterOrder <= 3 &&
                                    x.isDirector === true,
                                )
                                .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,
                                  posMaster: await Promise.all(
                                    orgChild4.posMasters
                                      .filter(
                                        (x) =>
                                          x.current_holderId != null &&
                                          x.posMasterOrder <= 3 &&
                                          x.isDirector === true,
                                      )
                                      .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 = {
      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 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",
      ])
      .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.orgChild1Name",
              "orgChild1.orgChild1ShortName",
              "orgChild1.orgChild1Code",
              "orgChild1.orgChild1Order",
              "orgChild1.orgChild1PhoneEx",
              "orgChild1.orgChild1PhoneIn",
              "orgChild1.orgChild1Fax",
              "orgChild1.orgRootId",
              "orgChild1.orgChild1Rank",
              "orgChild1.orgChild1RankSub",
              "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.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.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.orgChild3Id",
              "orgChild4.responsibility",
            ])
            .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",
          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() || "",
            },
          }),

          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,
                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,
                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,
                      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: 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,
                            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: 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,
                                  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: 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("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",
      ])
      .orderBy("orgRoot.orgRootOrder", "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,
          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);
  }
  public async listAuthSysOrgFuncByRevisionIdN(
    request: RequestWithUser,
    system: string,
    revisionId: string,
  ) {
    let profile = await this.profileRepo.findOne({
      where: {
        keycloak: request.user.sub,
      },
      relations: ["next_holders", "next_holders.authRole", "next_holders.authRole.authRoles"],
    });
    let data: any = {
      root: [null],
      child1: [null],
      child2: [null],
      child3: [null],
      child4: [null],
    };
    if (!profile) {
      return {
        root: null,
        child1: null,
        child2: null,
        child3: null,
        child4: null,
      };
    }

    let attrOwnership =
      profile?.next_holders
        .filter((x) => x.orgRevisionId == revisionId)[0]
        ?.authRole?.authRoles?.filter((x) => x.authSysId == system)[0]?.attrOwnership || null;

    let attrPrivilege =
      profile?.next_holders
        .filter((x) => x.orgRevisionId == revisionId)[0]
        ?.authRole?.authRoles?.filter((x) => x.authSysId == system)[0]?.attrPrivilege || null;

    const posMaster = await this.posMasterRepository.findOne({
      where: {
        next_holderId: profile.id,
        orgRevisionId: revisionId,
      },
    });
    if (!posMaster) {
      data = {
        root: [null],
        child1: [null],
        child2: [null],
        child3: [null],
        child4: [null],
      };
    } else if (attrOwnership == "OWNER") {
      data = {
        root: null,
        child1: null,
        child2: null,
        child3: null,
        child4: null,
      };
    } else if (attrPrivilege == "ROOT") {
      data = {
        root: [posMaster.orgRootId],
        child1: null,
        child2: null,
        child3: null,
        child4: null,
        privilege: "ROOT",
      };
    } else if (attrPrivilege == "CHILD") {
      let node = 4;
      if (posMaster.orgChild1Id == null) {
        node = 0;
      } else if (posMaster.orgChild2Id == null) {
        node = 1;
      } else if (posMaster.orgChild3Id == null) {
        node = 2;
      } else if (posMaster.orgChild4Id == null) {
        node = 3;
      }
      data = {
        root: node >= 0 ? [posMaster.orgRootId] : null,
        child1: node >= 1 ? [posMaster.orgChild1Id] : null,
        child2: node >= 2 ? [posMaster.orgChild2Id] : null,
        child3: node >= 3 ? [posMaster.orgChild3Id] : null,
        child4: node >= 4 ? [posMaster.orgChild4Id] : null,
      };
    } else if (attrPrivilege == "NORMAL") {
      data = {
        root: [posMaster.orgRootId],
        child1: [posMaster.orgChild1Id],
        child2: [posMaster.orgChild2Id],
        child3: [posMaster.orgChild3Id],
        child4: [posMaster.orgChild4Id],
      };
    } else if (attrPrivilege == "SPECIFIC") {
    }
    return data;
  }
  public async listAuthSysOrgFuncByRevisionIdC(
    request: RequestWithUser,
    system: string,
    revisionId: string,
  ) {
    let profile = await this.profileRepo.findOne({
      where: {
        keycloak: request.user.sub,
      },
      relations: [
        "current_holders",
        "current_holders.authRole",
        "current_holders.authRole.authRoles",
      ],
    });
    let data: any = {
      root: [null],
      child1: [null],
      child2: [null],
      child3: [null],
      child4: [null],
    };
    if (!profile) {
      return {
        root: null,
        child1: null,
        child2: null,
        child3: null,
        child4: null,
      };
    }

    let attrOwnership =
      profile?.current_holders
        .filter((x) => x.orgRevisionId == revisionId)[0]
        ?.authRole?.authRoles?.filter((x) => x.authSysId == system)[0]?.attrOwnership || null;

    let attrPrivilege =
      profile?.current_holders
        .filter((x) => x.orgRevisionId == revisionId)[0]
        ?.authRole?.authRoles?.filter((x) => x.authSysId == system)[0]?.attrPrivilege || null;

    const posMaster = await this.posMasterRepository.findOne({
      where: {
        next_holderId: profile.id,
        orgRevisionId: revisionId,
      },
    });
    if (!posMaster) {
      data = {
        root: [null],
        child1: [null],
        child2: [null],
        child3: [null],
        child4: [null],
      };
    } else if (attrOwnership == "OWNER") {
      data = {
        root: null,
        child1: null,
        child2: null,
        child3: null,
        child4: null,
      };
    } else if (attrPrivilege == "ROOT") {
      data = {
        root: [posMaster.orgRootId],
        child1: null,
        child2: null,
        child3: null,
        child4: null,
        privilege: "ROOT",
      };
    } else if (attrPrivilege == "CHILD") {
      let node = 4;
      if (posMaster.orgChild1Id == null) {
        node = 0;
      } else if (posMaster.orgChild2Id == null) {
        node = 1;
      } else if (posMaster.orgChild3Id == null) {
        node = 2;
      } else if (posMaster.orgChild4Id == null) {
        node = 3;
      }
      data = {
        root: node >= 0 ? [posMaster.orgRootId] : null,
        child1: node >= 1 ? [posMaster.orgChild1Id] : null,
        child2: node >= 2 ? [posMaster.orgChild2Id] : null,
        child3: node >= 3 ? [posMaster.orgChild3Id] : null,
        child4: node >= 4 ? [posMaster.orgChild4Id] : null,
      };
    } else if (attrPrivilege == "NORMAL") {
      data = {
        root: [posMaster.orgRootId],
        child1: [posMaster.orgChild1Id],
        child2: [posMaster.orgChild2Id],
        child3: [posMaster.orgChild3Id],
        child4: [posMaster.orgChild4Id],
      };
    } else if (attrPrivilege == "SPECIFIC") {
    }
    return data;
  }
}
