import {
  Controller,
  Post,
  Put,
  Delete,
  Route,
  Security,
  Tags,
  Body,
  Path,
  Request,
  SuccessResponse,
  Response,
  Get,
  Query,
} from "tsoa";
import { AppDataSource } from "../database/data-source";
import HttpSuccess from "../interfaces/http-success";
import HttpStatus from "../interfaces/http-status";
import HttpError from "../interfaces/http-error";
import { Brackets, Double, In, IsNull, Like, Not } from "typeorm";
import { OrgRevision } from "../entities/OrgRevision";
import {
  calculateRetireDate,
  calculateRetireLaw,
  removeProfileInOrganize,
} from "../interfaces/utils";
import { EmployeePosMaster } from "../entities/EmployeePosMaster";
import {
  ProfileEmployee,
  CreateProfileEmployee,
  UpdateProfileEmployee,
  ProfileEmployeeHistory,
  UpdatePositionTempProfileEmployee,
  UpdateInformationProfileEmployee,
} from "../entities/ProfileEmployee";
import { EmployeePosLevel } from "../entities/EmployeePosLevel";
import { EmployeePosType } from "../entities/EmployeePosType";
import { RequestWithUser } from "../middlewares/user";
import { Province } from "../entities/Province";
import { District } from "../entities/District";
import { SubDistrict } from "../entities/SubDistrict";
import { ProfileCertificate } from "../entities/ProfileCertificate";
import { ProfileTraining } from "../entities/ProfileTraining";
import { ProfileDiscipline } from "../entities/ProfileDiscipline";
import { ProfileEducation } from "../entities/ProfileEducation";
import { ProfileSalary } from "../entities/ProfileSalary";
import { ProfileFamilyCouple } from "../entities/ProfileFamilyCouple";
import { ProfileFamilyMother } from "../entities/ProfileFamilyMother";
import { ProfileFamilyFather } from "../entities/ProfileFamilyFather";
import Extension from "../interfaces/extension";
import { OrgRoot } from "../entities/OrgRoot";
import { OrgChild1 } from "../entities/OrgChild1";
import { OrgChild2 } from "../entities/OrgChild2";
import { OrgChild3 } from "../entities/OrgChild3";
import { OrgChild4 } from "../entities/OrgChild4";
import { ProfileEmployeeInformationHistory } from "../entities/ProfileEmployeeInformationHistory";
import {
  ProfileEmployeeEmployment,
  CreateEmploymentProfileEmployee,
  UpdateEmploymentProfileEmployee,
} from "../entities/ProfileEmployeeEmployment";
import { ProfileEmployeeEmploymentHistory } from "../entities/ProfileEmployeeEmploymentHistory";
import CallAPI from "../interfaces/call-api";
import { ProfileInsignia } from "../entities/ProfileInsignia";
import { ProfileLeave } from "../entities/ProfileLeave";
import permission from "../interfaces/permission";
import axios from "axios";
import { Position } from "../entities/Position";
@Route("api/v1/org/profile-employee")
@Tags("ProfileEmployee")
@Security("bearerAuth")
@Response(
  HttpStatus.INTERNAL_SERVER_ERROR,
  "เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง",
)
@SuccessResponse(HttpStatus.OK, "สำเร็จ")
export class ProfileEmployeeController extends Controller {
  private orgRevisionRepo = AppDataSource.getRepository(OrgRevision);
  private posMasterRepo = AppDataSource.getRepository(EmployeePosMaster);
  private profileRepo = AppDataSource.getRepository(ProfileEmployee);
  private profileHistoryRepo = AppDataSource.getRepository(ProfileEmployeeHistory);
  private posLevelRepo = AppDataSource.getRepository(EmployeePosLevel);
  private posTypeRepo = AppDataSource.getRepository(EmployeePosType);
  private provinceRepository = AppDataSource.getRepository(Province);
  private districtRepository = AppDataSource.getRepository(District);
  private subDistrict = AppDataSource.getRepository(SubDistrict);
  private certificateRepository = AppDataSource.getRepository(ProfileCertificate);
  private profileFamilyCoupleRepository = AppDataSource.getRepository(ProfileFamilyCouple);
  private profileFamilyMotherRepository = AppDataSource.getRepository(ProfileFamilyMother);
  private profileFamilyFatherRepository = AppDataSource.getRepository(ProfileFamilyFather);
  private trainingRepository = AppDataSource.getRepository(ProfileTraining);
  private disciplineRepository = AppDataSource.getRepository(ProfileDiscipline);
  private educationRepository = AppDataSource.getRepository(ProfileEducation);
  private salaryRepository = AppDataSource.getRepository(ProfileSalary);
  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 informationHistoryRepository = AppDataSource.getRepository(
    ProfileEmployeeInformationHistory,
  );
  private employmentRepository = AppDataSource.getRepository(ProfileEmployeeEmployment);
  private employmentHistoryRepository = AppDataSource.getRepository(
    ProfileEmployeeEmploymentHistory,
  );
  private profileEducationRepository = AppDataSource.getRepository(ProfileEducation);
  private profileInsigniaRepo = AppDataSource.getRepository(ProfileInsignia);
  private profileLeaveRepository = AppDataSource.getRepository(ProfileLeave);
  private positionRepository = AppDataSource.getRepository(Position);

  /**
   * report ประวัติแบบย่อ ลูกจ้าง
   *
   * @summary report ประวัติแบบย่อ ลูกจ้าง
   *
   * @param {string} id  Id โปรไฟล์
   */
  @Get("kp7-short/{id}")
  async kp7ShortById(@Path() id: string, @Request() req: RequestWithUser) {
    const orgRevision = await this.orgRevisionRepo.findOne({
      where: { orgRevisionIsCurrent: true },
    });

    const profile = await this.profileRepo.findOne({
      relations: [
        "profileSalary",
        "profileEducations",
        "current_holders",
        "current_holders.orgRoot",
        "current_holders.orgChild1",
        "current_holders.orgChild2",
        "current_holders.orgChild3",
        "current_holders.orgChild4",
      ],
      where: { id: id },
      order: {
        profileSalary: {
          date: "DESC",
        },
      },
    });
    if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");
    let _workflow = await new permission().Workflow(req, id, "SYS_REGISTRY_EMP");
    if (_workflow == false && req.user.sub != profile.keycloak)
      await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_EMP", profile.id);
    let ImgUrl: any;
    if (profile?.avatar != null && profile?.avatarName != null) {
      // await new CallAPI()
      //   .GetData(req, `/salary/file/${profile?.avatar}/${profile?.avatarName}`)
      //   .then(async (x) => {
      //     ImgUrl = x.downloadUrl;
      //   })
      //   .catch();
      let req_: any = req;
      const token_ = "Bearer " + req_.headers.authorization.replace("Bearer ", "");
      const url = process.env.API_URL + `/salary/file/${profile?.avatar}/${profile?.avatarName}`;
      try {
        const response_ = await axios.get(url, {
          headers: {
            Authorization: `${token_}`,
            "Content-Type": "application/json",
            api_key: process.env.API_KEY,
          },
        });
        ImgUrl = response_.data.downloadUrl;
      } catch {}
    }
    const province = await this.provinceRepository.findOneBy({
      id: profile.registrationProvinceId,
    });
    const district = await this.districtRepository.findOneBy({
      id: profile.registrationDistrictId,
    });
    const subDistrict = await this.subDistrict.findOneBy({ id: profile.registrationSubDistrictId });

    const root =
      profile.current_holders == null ||
      profile.current_holders.length == 0 ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgRoot;

    const child1 =
      profile.current_holders == null ||
      profile.current_holders.length == 0 ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild1;

    const child2 =
      profile.current_holders == null ||
      profile.current_holders.length == 0 ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild2;

    const child3 =
      profile.current_holders == null ||
      profile.current_holders.length == 0 ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild3;

    const child4 =
      profile.current_holders == null ||
      profile.current_holders.length == 0 ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild4;

    let _regisAddres =
      profile && profile.registrationAddress != null ? profile.registrationAddress : "";
    let _subDistrict =
      subDistrict && subDistrict.name != null ? `\r\nตำบล/แขวง ${province?.name}` : "";
    let _district = district && district.name != null ? `\r\nเขต/อำเภอ ${district?.name}` : "";
    let _province = province && province.name != null ? `\r\nจังหวัด ${province?.name}` : "";
    let registrationZipCode =
      profile && profile.registrationZipCode != null
        ? ` รหัสไปรษณีย์ ${profile.registrationZipCode}`
        : "";
    let _root = root == null || root == undefined ? "" : `${root.orgRootName}`;
    let _child1 = child1 == null || child1 == undefined ? "" : `${child1.orgChild1Name}/`;
    let _child2 = child2 == null || child2 == undefined ? "" : `${child2.orgChild2Name}/`;
    let _child3 = child3 == null || child3 == undefined ? "" : `${child3.orgChild3Name}/`;
    let _child4 = child4 == null || child4 == undefined ? "" : `${child4.orgChild4Name}/`;

    const educations = await this.educationRepository.find({
      select: ["startDate", "endDate", "educationLevel", "degree", "field", "institute"],
      where: { profileEmployeeId: id },
      order: { lastUpdatedAt: "DESC" },
    });
    const Education =
      educations && educations.length > 0
        ? educations.map((item) => ({
            institute: item.institute ? item.institute : "-",
            date:
              item.startDate && item.endDate
                ? `${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.startDate))} - ${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.endDate))}`
                : "-",
            degree: item.degree && item.field ? `${item.degree} ${item.field}` : "-",
          }))
        : [
            {
              institute: "-",
              date: "-",
              degree: "-",
            },
          ];

    const mapData = {
      // Id: profile.id,
      fullName: `${profile?.prefix}${profile?.firstName} ${profile?.lastName}`,
      prefix: profile.prefix != null ? profile.prefix : null,
      firstName: profile.firstName != null ? profile.firstName : null,
      lastName: profile.lastName != null ? profile.lastName : null,
      citizenId: profile.citizenId != null ? Extension.ToThaiNumber(profile.citizenId) : "-",
      dateOfBirth:
        profile.birthDate != null
          ? Extension.ToThaiNumber(Extension.ToThaiShortDate_monthYear(profile.birthDate))
          : "-",
      dateRetire:
        profile.dateRetire != null
          ? Extension.ToThaiNumber(Extension.ToThaiShortDate_monthYear(profile.dateRetire))
          : "-",
      salaryAmount:
        profile.profileSalary.length > 0 && profile.profileSalary[0].amount != null
          ? Extension.ToThaiNumber(profile.profileSalary[0].amount.toLocaleString())
          : "-",
      registrationAddress: Extension.ToThaiNumber(
        `${_regisAddres}${_subDistrict}${_district}${_province}${registrationZipCode}`,
      ),
      salaryDate:
        profile.profileSalary.length > 0 && profile.profileSalary[0].date != null
          ? Extension.ToThaiNumber(
              Extension.ToThaiShortDate_monthYear(profile.profileSalary[0].date),
            )
          : "-",
      positionName: profile.position != null ? profile.position : "-",
      appointText:
        profile.dateAppoint != null
          ? Extension.ToThaiNumber(Extension.ToThaiShortDate_monthYear(profile.dateAppoint))
          : "-",
      ocFullPath: `${_child4}${_child3}${_child2}${_child1}${_root}`,
      educations: Education,
      url: ImgUrl ? ImgUrl : `https://bma-ehr.frappet.synology.me/assets/avatar_user-89f22423.jpg`,
    };

    return new HttpSuccess({
      template: "kp7",
      reportName: "docx-report",
      data: mapData,
    });
  }

  /**
   * รายงาน ก.ก.1 (ลูกจ้างประจำ)
   *
   * @summary รายงาน ก.ก.1 (ลูกจ้างประจำ)
   *
   * @param {string} id  Id โปรไฟล์
   */
  @Get("kk1/{id}")
  public async getKk1Employee(@Path() id: string, @Request() req: RequestWithUser) {
    const profiles = await this.profileRepo.findOne({
      relations: ["currentSubDistrict", "currentDistrict", "currentProvince", "profileAvatars"],
      order: {
        profileAvatars: { createdAt: "ASC" },
      },
      where: { id: id },
    });
    if (!profiles) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");
    let ImgUrl: any = null;
    let _ImgUrl: any = [];
    if (profiles?.avatar != null && profiles?.avatarName != null) {
      // await new CallAPI()
      //   .GetData(req, `/salary/file/${profiles?.avatar}/${profiles?.avatarName}`)
      //   .then(async (x) => {
      //     ImgUrl = x.downloadUrl;
      //   })
      //   .catch();

      let req_: any = req;
      const token_ = "Bearer " + req_.headers.authorization.replace("Bearer ", "");

      await Promise.all(
        await profiles.profileAvatars.slice(-7).map(async (x, i) => {
          if (x == null) {
            _ImgUrl[i] = null;
          } else {
            const url = process.env.API_URL + `/salary/file/${x?.avatar}/${x?.avatarName}`;
            try {
              const response_ = await axios.get(url, {
                headers: {
                  Authorization: `${token_}`,
                  "Content-Type": "application/json",
                  api_key: process.env.API_KEY,
                },
              });
              _ImgUrl[i] = response_.data.downloadUrl;
            } catch {}
          }
        }),
      );
      const url = process.env.API_URL + `/salary/file/${profiles?.avatar}/${profiles?.avatarName}`;
      try {
        const response_ = await axios.get(url, {
          headers: {
            Authorization: `${token_}`,
            "Content-Type": "application/json",
            api_key: process.env.API_KEY,
          },
        });
        ImgUrl = response_.data.downloadUrl;
      } catch {}
    }
    const profileOc = await this.profileRepo.findOne({
      relations: [
        "current_holders",
        "current_holders.orgRoot",
        "current_holders.orgChild1",
        "current_holders.orgChild2",
        "current_holders.orgChild3",
        "current_holders.orgChild4",
      ],
      where: { id: id },
    });
    if (!profileOc) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");

    const orgRevision = await this.orgRevisionRepo.findOne({
      where: { orgRevisionIsCurrent: true },
    });

    const profileFamilyCouple = await this.profileFamilyCoupleRepository.findOne({
      where: { profileEmployeeId: id },
      select: ["couplePrefix", "coupleFirstName", "coupleLastName", "coupleLastNameOld"],
      order: { lastUpdatedAt: "DESC" },
    });

    const profileFamilyMother = await this.profileFamilyMotherRepository.findOne({
      where: { profileEmployeeId: id },
      select: ["motherPrefix", "motherFirstName", "motherLastName"],
      order: { lastUpdatedAt: "DESC" },
    });

    const profileFamilyFather = await this.profileFamilyFatherRepository.findOne({
      where: { profileEmployeeId: id },
      select: ["fatherPrefix", "fatherFirstName", "fatherLastName"],
      order: { lastUpdatedAt: "DESC" },
    });

    const root =
      profileOc.current_holders == null ||
      profileOc.current_holders.length == 0 ||
      profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null
        ? null
        : profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgRoot;

    const child1 =
      profileOc.current_holders == null ||
      profileOc.current_holders.length == 0 ||
      profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null
        ? null
        : profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild1;

    const child2 =
      profileOc.current_holders == null ||
      profileOc.current_holders.length == 0 ||
      profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null
        ? null
        : profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild2;

    const child3 =
      profileOc.current_holders == null ||
      profileOc.current_holders.length == 0 ||
      profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null
        ? null
        : profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild3;

    const child4 =
      profileOc.current_holders == null ||
      profileOc.current_holders.length == 0 ||
      profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id) == null
        ? null
        : profileOc.current_holders.find((x) => x.orgRevisionId == orgRevision?.id)?.orgChild4;

    // Construct org path
    const _root = root ? `${root.orgRootName}` : "";
    const _child1 = child1 ? `${child1.orgChild1Name}/` : "";
    const _child2 = child2 ? `${child2.orgChild2Name}/` : "";
    const _child3 = child3 ? `${child3.orgChild3Name}/` : "";
    const _child4 = child4 ? `${child4.orgChild4Name}/` : "";

    const cert_raw = await this.certificateRepository.find({
      where: { profileEmployeeId: id },
      select: ["certificateType", "issuer", "certificateNo", "issueDate"],
      order: { createdAt: "ASC" },
    });
    const certs =
      cert_raw.length > 0
        ? cert_raw.slice(-2).map((item) => ({
            CertificateType: item.certificateType ?? null,
            Issuer: item.issuer ?? null,
            CertificateNo: Extension.ToThaiNumber(item.certificateNo) ?? null,
            IssueDate: Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.issueDate)) ?? null,
          }))
        : [
            {
              CertificateType: "-",
              Issuer: "-",
              CertificateNo: "-",
              IssueDate: "-",
            },
          ];
    const training_raw = await this.trainingRepository.find({
      select: ["startDate", "endDate", "place", "department"],
      where: { profileEmployeeId: id },
      order: { createdAt: "ASC" },
    });
    const trainings =
      training_raw.length > 0
        ? training_raw.slice(-2).map((item) => ({
            Institute: item.department ?? "",
            Start:
              item.startDate == null
                ? ""
                : Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.startDate)),
            End:
              item.endDate == null
                ? ""
                : Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.endDate)),
            Date:
              item.startDate && item.endDate
                ? `${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.startDate))} - ${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.endDate))}`
                : "",
            Level: "",
            Degree: item.name,
            Field: "",
          }))
        : [
            {
              Institute: "-",
              Start: "-",
              End: "-",
              Date: "-",
              Level: "-",
              Degree: "-",
              Field: "-",
            },
          ];

    const discipline_raw = await this.disciplineRepository.find({
      select: ["refCommandDate", "refCommandNo", "detail"],
      where: { profileEmployeeId: id },
      order: { createdAt: "ASC" },
    });
    const disciplines =
      discipline_raw.length > 0
        ? discipline_raw.slice(-2).map((item) => ({
            DisciplineYear:
              Extension.ToThaiNumber(new Date(item.refCommandDate).getFullYear().toString()) ??
              null,
            DisciplineDetail: item.detail ?? null,
            RefNo: Extension.ToThaiNumber(item.refCommandNo) ?? null,
          }))
        : [
            {
              DisciplineYear: "-",
              DisciplineDetail: "-",
              RefNo: "-",
            },
          ];

    const education_raw = await this.educationRepository.find({
      select: ["startDate", "endDate", "educationLevel", "degree", "field", "institute"],
      where: { profileEmployeeId: id },
      // order: { lastUpdatedAt: "DESC" },
      order: { createdAt: "ASC" },
    });
    const educations =
      education_raw.length > 0
        ? education_raw.slice(-2).map((item) => ({
            Institute: item.institute,
            Start:
              item.startDate == null
                ? ""
                : Extension.ToThaiNumber(new Date(item.startDate).getFullYear().toString()),
            End:
              item.endDate == null
                ? ""
                : Extension.ToThaiNumber(new Date(item.endDate).getFullYear().toString()),
            Date:
              item.startDate && item.endDate
                ? `${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.startDate))} - ${Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.endDate))}`
                : "",
            Level: item.educationLevel ?? "",
            Degree: item.degree ? `${item.degree} ${item.field ? item.field : ""}` : "",
            Field: item.field ?? "-",
          }))
        : [
            {
              Institute: "-",
              Start: "-",
              End: "-",
              Date: "-",
              Level: "-",
              Degree: "-",
              Field: "-",
            },
          ];
    const salary_raw = await this.salaryRepository.find({
      select: [
        "date",
        "position",
        "posNo",
        "positionType",
        "positionLevel",
        "positionSalaryAmount",
        "refCommandNo",
        "amount",
        "templateDoc",
      ],
      where: { profileEmployeeId: id },
      order: { order: "ASC" },
    });

    const salarys =
      salary_raw.length > 0
        ? salary_raw.map((item) => ({
            SalaryDate: item.date
              ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.date))
              : null,
            Position: item.position != null ? Extension.ToThaiNumber(item.position) : null,
            PosNo: item.posNo != null ? Extension.ToThaiNumber(item.posNo) : null,
            Salary:
              item.amount != null ? Extension.ToThaiNumber(item.amount.toLocaleString()) : null,
            Rank: item.positionLevel != null ? Extension.ToThaiNumber(item.positionLevel) : null,
            RefAll: item.templateDoc ? Extension.ToThaiNumber(item.templateDoc) : null,
            PositionLevel:
              item.positionLevel != null ? Extension.ToThaiNumber(item.positionLevel) : null,
            PositionType: item.positionType ?? null,
            PositionAmount:
              item.positionSalaryAmount == null
                ? null
                : Extension.ToThaiNumber(item.positionSalaryAmount.toLocaleString()),
            FullName: `${profiles?.prefix}${profiles?.firstName} ${profiles?.lastName}`,
            OcFullPath: `${_child4}${_child3}${_child2}${_child1}${_root}`,
          }))
        : [
            {
              SalaryDate: "-",
              Position: "-",
              PosNo: "-",
              Salary: "-",
              Rank: "-",
              RefAll: "-",
              PositionLevel: "-",
              PositionType: "-",
              PositionAmount: "-",
              FullName: "-",
              OcFullPath: "-",
            },
          ];

    const insignia_raw = await this.profileInsigniaRepo.find({
      relations: {
        insignia: {
          insigniaType: true,
        },
      },
      where: { profileEmployeeId: id },
      order: { receiveDate: "ASC" },
    });
    const insignias =
      insignia_raw.length > 0
        ? insignia_raw.map((item) => ({
            ReceiveDate: item.receiveDate
              ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.receiveDate))
              : "",
            InsigniaName: item.insignia.name,
            InsigniaShortName: item.insignia.shortName,
            InsigniaTypeName: item.insignia.insigniaType.name,
            No: item.no ? Extension.ToThaiNumber(item.no) : "",
            Issue: item.issue ? item.issue : "",
            VolumeNo: item.volumeNo ? Extension.ToThaiNumber(item.volumeNo) : "",
            Volume: item.volume ? Extension.ToThaiNumber(item.volume) : "",
            Section: item.section ? Extension.ToThaiNumber(item.section) : "",
            Page: item.page ? Extension.ToThaiNumber(item.page) : "",
            RefCommandDate: item.refCommandDate
              ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.refCommandDate))
              : "",
          }))
        : [
            {
              ReceiveDate: "-",
              InsigniaName: "-",
              InsigniaShortName: "-",
              InsigniaTypeName: "-",
              No: "-",
              Issue: "-",
              VolumeNo: "-",
              Volume: "-",
              Section: "-",
              Page: "-",
              RefCommandDate: "-",
            },
          ];

    const leave_raw = await this.profileLeaveRepository.find({
      relations: { leaveType: true },
      where: { profileEmployeeId: id },
      order: { dateLeaveStart: "ASC" },
    });
    const leaves =
      leave_raw.length > 0
        ? leave_raw.map((item) => ({
            LeaveTypeName: item.leaveType.name,
            DateLeaveStart: item.dateLeaveStart
              ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(item.dateLeaveStart))
              : "",
            LeaveDays: item.leaveDays ? Extension.ToThaiNumber(item.leaveDays.toString()) : "",
          }))
        : [
            {
              LeaveTypeName: "-",
              DateLeaveStart: "-",
              LeaveDays: "-",
            },
          ];

    const data = {
      fullName: `${profiles?.prefix}${profiles?.firstName} ${profiles?.lastName}`,
      prefix: profiles?.prefix != null ? profiles.prefix : "",
      firstName: profiles?.firstName != null ? profiles.firstName : "",
      lastName: profiles?.lastName != null ? profiles.lastName : "",
      ocFullPath: `${_child4}${_child3}${_child2}${_child1}${_root}`,
      birthDate: profiles?.birthDate
        ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(profiles.birthDate))
        : "",
      retireDate:
        profiles.dateRetireLaw != null
          ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(profiles.dateRetireLaw))
          : "",
      appointDate: profiles?.dateAppoint
        ? Extension.ToThaiNumber(Extension.ToThaiFullDate2(profiles.dateAppoint))
        : "",
      citizenId:
        profiles.citizenId != null ? Extension.ToThaiNumber(profiles.citizenId.toString()) : "",
      fatherFullName:
        profileFamilyFather?.fatherPrefix ||
        profileFamilyFather?.fatherFirstName ||
        profileFamilyFather?.fatherLastName
          ? `${profileFamilyFather?.fatherPrefix ?? ""}${profileFamilyFather?.fatherFirstName ?? ""} ${profileFamilyFather?.fatherLastName ?? ""}`.trim()
          : null,
      motherFullName:
        profileFamilyMother?.motherPrefix ||
        profileFamilyMother?.motherFirstName ||
        profileFamilyMother?.motherLastName
          ? `${profileFamilyMother?.motherPrefix ?? ""}${profileFamilyMother?.motherFirstName ?? ""} ${profileFamilyMother?.motherLastName ?? ""}`.trim()
          : null,
      coupleFullName:
        profileFamilyCouple?.couplePrefix ||
        profileFamilyCouple?.coupleFirstName ||
        profileFamilyCouple?.coupleLastNameOld
          ? `${profileFamilyCouple?.couplePrefix ?? ""}${profileFamilyCouple?.coupleFirstName ?? ""} ${profileFamilyCouple?.coupleLastName ?? ""}`.trim()
          : null,
      coupleLastNameOld: profileFamilyCouple?.coupleLastNameOld ?? null,
      currentAddress:
        profiles.currentAddress != null ? Extension.ToThaiNumber(profiles.currentAddress) : "",
      currentSubDistrict:
        profiles.currentSubDistrict != null
          ? Extension.ToThaiNumber(profiles.currentSubDistrict.name)
          : "",
      currentDistrict:
        profiles.currentDistrict != null
          ? Extension.ToThaiNumber(profiles.currentDistrict.name)
          : "",
      currentProvince:
        profiles.currentProvince != null
          ? Extension.ToThaiNumber(profiles.currentProvince.name)
          : "",
      telephone:
        profiles.telephoneNumber != null ? Extension.ToThaiNumber(profiles.telephoneNumber) : "",
      url: ImgUrl ? ImgUrl : `https://bma-ehr.frappet.synology.me/assets/avatar_user-89f22423.jpg`,
      url1: _ImgUrl[0] ? _ImgUrl[0] : null,
      yearUpload1: profiles.profileAvatars[0]
        ? Extension.ToThaiNumber(Extension.ToThaiShortYear(profiles.profileAvatars[0].createdAt))
        : null,
      url2: _ImgUrl[1] ? _ImgUrl[1] : null,
      yearUpload2: profiles.profileAvatars[1]
        ? Extension.ToThaiNumber(Extension.ToThaiShortYear(profiles.profileAvatars[1].createdAt))
        : null,
      url3: _ImgUrl[2] ? _ImgUrl[2] : null,
      yearUpload3: profiles.profileAvatars[2]
        ? Extension.ToThaiNumber(Extension.ToThaiShortYear(profiles.profileAvatars[2].createdAt))
        : null,
      url4: _ImgUrl[3] ? _ImgUrl[3] : null,
      yearUpload4: profiles.profileAvatars[3]
        ? Extension.ToThaiNumber(Extension.ToThaiShortYear(profiles.profileAvatars[3].createdAt))
        : null,
      url5: _ImgUrl[4] ? _ImgUrl[4] : null,
      yearUpload5: profiles.profileAvatars[4]
        ? Extension.ToThaiNumber(Extension.ToThaiShortYear(profiles.profileAvatars[4].createdAt))
        : null,
      url6: _ImgUrl[5] ? _ImgUrl[5] : null,
      yearUpload6: profiles.profileAvatars[5]
        ? Extension.ToThaiNumber(Extension.ToThaiShortYear(profiles.profileAvatars[5].createdAt))
        : null,
      url7: _ImgUrl[6] ? _ImgUrl[6] : null,
      yearUpload7: profiles.profileAvatars[6]
        ? Extension.ToThaiNumber(Extension.ToThaiShortYear(profiles.profileAvatars[6].createdAt))
        : null,
      insignias,
      leaves,
      certs,
      trainings,
      disciplines,
      educations,
      salarys,
    };

    return new HttpSuccess({
      template: "kk1-emp",
      reportName: "docx-report",
      data: data,
    });
  }

  /**
   * API สร้างทะเบียนประวัติ
   *
   * @summary ORG_065 - สร้างทะเบียนประวัติ (ADMIN) #70
   *
   */
  @Post()
  async createProfile(@Body() body: CreateProfileEmployee, @Request() request: RequestWithUser) {
    //ไม่แน่ใจEMPปิดไว้ก่อน
    if (await this.profileRepo.findOneBy({ citizenId: body.citizenId })) {
      throw new HttpError(
        HttpStatus.INTERNAL_SERVER_ERROR,
        "รหัสบัตรประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว",
      );
    }

    if (body.posLevelId === "") body.posLevelId = null;
    if (body.posTypeId === "") body.posTypeId = null;

    if (body.posLevelId && !(await this.posLevelRepo.findOneBy({ id: body.posLevelId }))) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้");
    }

    if (body.posTypeId && !(await this.posTypeRepo.findOneBy({ id: body.posTypeId }))) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้");
    }

    if (body.employeeClass == null || body.employeeClass == undefined || body.employeeClass == "") {
      body.employeeClass = "PERM";
    }
    if (!["PERM", "TEMP"].includes(body.employeeClass.toLocaleUpperCase())) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ประเภทลูกจ้างไม่ถูกต้อง");
    }

    const profile = Object.assign(new ProfileEmployee(), body);
    profile.createdUserId = request.user.sub;
    profile.createdFullName = request.user.name;
    profile.lastUpdateUserId = request.user.sub;
    profile.lastUpdateFullName = request.user.name;
    profile.createdAt = new Date();
    profile.lastUpdatedAt = new Date();
    profile.dateRetire = calculateRetireDate(profile.birthDate);
    profile.dateRetireLaw = calculateRetireLaw(profile.birthDate);
    profile.citizenId = Extension.CheckCitizen(profile.citizenId);
    profile.statusTemp = profile.employeeClass.toLocaleUpperCase() == "TEMP" ? "WAITTING" : "";
    profile.employeeClass = profile.employeeClass.toLocaleUpperCase();
    await this.profileRepo.save(profile);
    return new HttpSuccess();
  }

  /**
   * API แก้ไขทะเบียนประวัติ
   *
   * @summary ORG_065 - แก้ไขทะเบียนประวัติ (ADMIN) #70
   *
   * @param {string} id  Id ทะเบียนประวัติ
   */
  @Put("{id}")
  async updateProfileEmployee(
    @Request() request: RequestWithUser,
    @Path() id: string,
    @Body() body: UpdateProfileEmployee,
  ) {
    await new permission().PermissionOrgUserUpdate(request, "SYS_REGISTRY_EMP", id);
    const exists =
      !!body.citizenId &&
      (await this.profileRepo.findOne({
        where: {
          id: Not(id),
          citizenId: body.citizenId,
          employeeClass: String(body.employeeClass),
        },
      }));

    if (exists) {
      throw new HttpError(HttpStatus.CONFLICT, "รหัสบัตรประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว");
    }

    if (body.posLevelId === "") body.posLevelId = null;
    if (body.posTypeId === "") body.posTypeId = null;

    if (body.posLevelId && !(await this.posLevelRepo.findOneBy({ id: body.posLevelId }))) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้");
    }

    if (body.posTypeId && !(await this.posTypeRepo.findOneBy({ id: body.posTypeId }))) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้");
    }

    const record = await this.profileRepo.findOneBy({ id });
    if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้");

    if (body.employeeClass == null || body.employeeClass == undefined || body.employeeClass == "") {
      body.employeeClass = "PERM";
    }
    if (!["PERM", "TEMP"].includes(body.employeeClass.toLocaleUpperCase())) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ประเภทลูกจ้างไม่ถูกต้อง");
    }

    Object.assign(record, body);
    record.createdUserId = request.user.sub;
    record.createdFullName = request.user.name;
    record.createdAt = new Date();
    record.lastUpdateUserId = request.user.sub;
    record.lastUpdateFullName = request.user.name;
    record.lastUpdatedAt = new Date();
    await this.profileHistoryRepo.save(
      Object.assign(new ProfileEmployeeHistory(), {
        ...record,
        lastUpdateUserId: request.user.sub,
        lastUpdateFullName: request.user.name,
        lastUpdatedAt: new Date(),
        profileEmployeeId: id,
        id: undefined,
      }),
    );
    await this.profileRepo.save(record);
    return new HttpSuccess();
  }

  /**
   * API ลบทะเบียนประวัติ
   *
   * @summary ORG_065 - ลบทะเบียนประวัติ (ADMIN) #70
   *
   * @param {string} id  Id ทะเบียนประวัติ
   */
  @Delete("{id}")
  async deleteProfile(@Path() id: string, @Request() request: RequestWithUser) {
    const result = await this.profileRepo.findOne({ where: { id: id } });
    if (!result) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");
    }
    await new permission().PermissionOrgUserDelete(request, "SYS_REGISTRY_EMP", result.id);
    await this.informationHistoryRepository.delete({ profileEmployeeId: id });
    await this.profileRepo.remove(result);
    return new HttpSuccess();
  }

  /**
   * API รายละเอียดรายการทะเบียนประวัติ
   *
   * @summary ORG_065 - รายละเอียดรายการทะเบียนประวัติ  (ADMIN) #70
   *
   * @param {string} id  Id ทะเบียนประวัติ
   */
  @Get("user")
  async detailProfileUser(@Request() request: RequestWithUser) {
    const profile = await this.profileRepo.findOne({
      relations: {
        posLevel: true,
        posType: true,
        // gender: true,
        // relationship: true,
        // bloodGroup: true,
      },
      where: { keycloak: request.user.sub },
    });

    if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");

    return new HttpSuccess(profile);
  }

  /**
   * API รายการทะเบียนประวัติลูกจ้างชั่วคราว
   *
   * @summary รายการทะเบียนประวัติลูกจ้างชั่วคราว (ADMIN)
   *
   */
  @Get("temp")
  async listProfileEmp() {
    const [record, total] = await this.profileRepo
      .createQueryBuilder("profileEmployee")
      .leftJoinAndSelect("profileEmployee.posLevel", "posLevel")
      .leftJoinAndSelect("profileEmployee.posType", "posType")
      .leftJoinAndSelect("profileEmployee.current_holders", "current_holders")
      .leftJoinAndSelect("profileEmployee.profileEmployeeEmployment", "profileEmployeeEmployment")
      .leftJoinAndSelect("current_holders.positions", "positions")
      .leftJoinAndSelect("current_holders.orgRoot", "orgRoot")
      .leftJoinAndSelect("current_holders.orgChild1", "orgChild1")
      .leftJoinAndSelect("current_holders.orgChild2", "orgChild2")
      .leftJoinAndSelect("current_holders.orgChild3", "orgChild3")
      .leftJoinAndSelect("current_holders.orgChild4", "orgChild4")
      .andWhere("profileEmployee.employeeClass = :employeeClass", { employeeClass: "TEMP" })
      .andWhere("profileEmployee.statusTemp = :statusTemp", { statusTemp: "PENDING" })
      .getManyAndCount();
    const data = await Promise.all(
      record.map((_data) => {
        const shortName =
          _data.current_holders.length == 0
            ? null
            : _data.current_holders[0].orgChild4 != null
              ? `${_data.current_holders[0].orgChild4.orgChild4ShortName}${_data.current_holders[0].posMasterNo}`
              : _data.current_holders[0].orgChild3 != null
                ? `${_data.current_holders[0].orgChild3.orgChild3ShortName}${_data.current_holders[0].posMasterNo}`
                : _data.current_holders[0].orgChild2 != null
                  ? `${_data.current_holders[0].orgChild2.orgChild2ShortName}${_data.current_holders[0].posMasterNo}`
                  : _data.current_holders[0].orgChild1 != null
                    ? `${_data.current_holders[0].orgChild1.orgChild1ShortName}${_data.current_holders[0].posMasterNo}`
                    : _data.current_holders[0].orgRoot != null
                      ? `${_data.current_holders[0].orgRoot.orgRootShortName}${_data.current_holders[0].posMasterNo}`
                      : null;
        const dateEmployment =
          _data.profileEmployeeEmployment.length == 0
            ? null
            : _data.profileEmployeeEmployment.reduce((latest, current) => {
                return latest.date > current.date ? latest : current;
              }).date;
        return {
          id: _data.id,
          prefix: _data.prefix,
          rank: _data.rank,
          firstName: _data.firstName,
          lastName: _data.lastName,
          citizenId: _data.citizenId,
          posLevel: _data.posLevel == null ? null : _data.posLevel.posLevelName,
          posType: _data.posType == null ? null : _data.posType.posTypeName,
          posTypeShortName: _data.posType == null ? null : _data.posType.posTypeShortName,
          posLevelId: _data.posLevel == null ? null : _data.posLevel.id,
          posTypeId: _data.posType == null ? null : _data.posType.id,
          positionId: _data.positionIdTemp,
          posmasterId: _data.posmasterIdTemp,
          position: _data.position,
          posNo: _data.employeeClass == "TEMP" ? _data.posMasterNoTemp : shortName,
          employeeClass: _data.employeeClass == null ? null : _data.employeeClass,
          govAge: Extension.CalculateGovAge(_data.dateAppoint, 0, 0),
          age: Extension.CalculateAgeStrV2(_data.birthDate, 0, 0),
          dateEmployment: dateEmployment,
          dateAppoint: _data.dateAppoint,
          dateStart: _data.dateStart,
          createdAt: _data.createdAt,
          dateRetireLaw: _data.dateRetireLaw,
          draftOrganizationOrganization:
            _data.nodeTemp == "0"
              ? _data.rootTemp
              : _data.nodeTemp == "1"
                ? _data.child1Temp
                : _data.nodeTemp == "2"
                  ? _data.child2Temp
                  : _data.nodeTemp == "3"
                    ? _data.child3Temp
                    : _data.nodeTemp == "4"
                      ? _data.child4Temp
                      : null,
          draftPositionEmployee: _data.positionTemp,
          draftOrgEmployeeStatus: _data.statusTemp,
          node: _data.nodeTemp,
          nodeId: _data.nodeIdTemp,
          nodeName:
            _data.nodeTemp == "0"
              ? _data.rootTemp
              : _data.nodeTemp == "1"
                ? _data.child1Temp
                : _data.nodeTemp == "2"
                  ? _data.child2Temp
                  : _data.nodeTemp == "3"
                    ? _data.child3Temp
                    : _data.nodeTemp == "4"
                      ? _data.child4Temp
                      : null,
          nodeShortName:
            _data.nodeTemp == "0"
              ? _data.rootShortNameTemp
              : _data.nodeTemp == "1"
                ? _data.child1ShortNameTemp
                : _data.nodeTemp == "2"
                  ? _data.child1ShortNameTemp
                  : _data.nodeTemp == "3"
                    ? _data.child3ShortNameTemp
                    : _data.nodeTemp == "4"
                      ? _data.child4ShortNameTemp
                      : null,
          root: _data.rootTemp ? _data.rootTemp : null,
          rootId: _data.rootIdTemp ? _data.rootIdTemp : null,
          rootShortName: _data.rootShortNameTemp ? _data.rootShortNameTemp : null,
          child1: _data.child1Temp ? _data.child1Temp : null,
          child1Id: _data.child1IdTemp ? _data.child1IdTemp : null,
          child1ShortName: _data.child1ShortNameTemp ? _data.child1ShortNameTemp : null,
          child2: _data.child2Temp ? _data.child2Temp : null,
          child2Id: _data.child2IdTemp ? _data.child2IdTemp : null,
          child2ShortName: _data.child2ShortNameTemp ? _data.child2ShortNameTemp : null,
          child3: _data.child3Temp ? _data.child3Temp : null,
          child3Id: _data.child3IdTemp ? _data.child3IdTemp : null,
          child3ShortName: _data.child3ShortNameTemp ? _data.child3ShortNameTemp : null,
          child4: _data.child4Temp ? _data.child4Temp : null,
          child4Id: _data.child4IdTemp ? _data.child4IdTemp : null,
          child4ShortName: _data.child4ShortNameTemp ? _data.child4ShortNameTemp : null,
        };
      }),
    );

    return new HttpSuccess({ data: data, total });
  }

  /**
   * API ประวัติการแก้ไขรายการทะเบียนประวัติ
   *
   * @summary ประวัติการแก้ไขรายการทะเบียนประวัติ
   *
   * @param {string} id  Id โปรไฟล์
   */
  @Get("history/user")
  async getHistoryProfileByUser(@Request() request: RequestWithUser) {
    const historyProfile = await this.profileHistoryRepo.find({
      relations: {
        posLevel: true,
        posType: true,
      },
      where: { keycloak: request.user.sub },
      order: {
        createdAt: "ASC",
      },
    });

    if (!historyProfile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");

    return new HttpSuccess(historyProfile);
  }

  /**
   * API ออกคำสั่งลูกจ้าง
   *
   * @summary ORG_038 - ออกคำสั่งลูกจ้าง (ADMIN) #
   *
   */
  @Get("report")
  async getReport(@Request() request: RequestWithUser) {
    const profiles = await this.profileRepo.find({
      where: { statusTemp: "REPORT", employeeClass: "TEMP" },
      relations: [
        "posLevel",
        "posType",
        "current_holders",
        "current_holders.orgChild1",
        "current_holders.orgChild2",
        "current_holders.orgChild3",
        "current_holders.orgChild4",
      ],
    });

    if (!profiles) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");
    }

    const findRevision = await this.orgRevisionRepo.findOne({
      where: { orgRevisionIsCurrent: true },
    });
    if (!findRevision) {
      throw new HttpError(HttpStatus.NOT_FOUND, "not found. OrgRevision");
    }

    const formattedData = profiles.map((profile) => {
      const fullName = `${profile.prefix} ${profile.firstName} ${profile.lastName}`;
      const shortName =
        profile.current_holders.length == 0
          ? null
          : profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
              profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 !=
                null
            ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4.orgChild4ShortName}${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
            : profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
                profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)
                  ?.orgChild3 != null
              ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3.orgChild3ShortName}${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
              : profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
                  profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)
                    ?.orgChild2 != null
                ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2.orgChild2ShortName}${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
                : profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
                    profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)
                      ?.orgChild1 != null
                  ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1.orgChild1ShortName}${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
                  : profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) !=
                        null &&
                      profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)
                        ?.orgRoot != null
                    ? `${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot.orgRootShortName}${profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
                    : null;

      const root =
        profile.current_holders.length == 0 ||
        (profile.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
          profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null)
          ? null
          : profile.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot;

      return {
        id: profile.id,
        prefix: profile.prefix,
        firstName: profile.firstName,
        lastName: profile.lastName,
        fullName: fullName,
        birthDate: profile.birthDate,
        rank: profile.rank,
        citizenId: profile.citizenId,
        email: profile.email,
        phone: profile.phone,
        isProbation: profile.isProbation,
        isLeave: profile.isLeave,
        leaveReason: profile.leaveReason,
        dateLeave: profile.dateLeave,
        dateRetire: profile.dateRetire,
        dateRetireLaw: profile.dateRetireLaw,
        salaryLevel: profile.salaryLevel,
        group: profile.group,
        ethnicity: profile.ethnicity,
        telephoneNumber: profile.telephoneNumber,
        nationality: profile.nationality,
        gender: profile.gender,
        relationship: profile.relationship,
        religion: profile.religion,
        bloodGroup: profile.bloodGroup,
        positionNumber: shortName,
        organization: root == null ? null : root.orgRootShortName,
        positionName: profile.position,
        possitionTypeId: profile.posTypeId,
        positionType: profile.posType?.posTypeName,
        positionLevelId: profile.posLevelId,
        positionLevel: profile.posLevel?.posLevelName,
      };
    });

    return new HttpSuccess(formattedData);
  }

  /**
   * API ออกคำสั่งลูกจ้าง
   *
   * @summary ORG_038 - ออกคำสั่งลูกจ้าง (ADMIN) #
   *
   */
  @Get("report-temp")
  async getReportTemp(@Request() request: RequestWithUser) {
    const profiles = await this.profileRepo.find({
      where: { statusTemp: "REPORT", employeeClass: "TEMP" },
    });

    if (!profiles) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");
    }

    const findRevision = await this.orgRevisionRepo.findOne({
      where: { orgRevisionIsCurrent: true },
    });
    if (!findRevision) {
      throw new HttpError(HttpStatus.NOT_FOUND, "not found. OrgRevision");
    }

    const formattedData = profiles.map((profile) => {
      const shortName =
        profile.child4Temp != null
          ? `${profile.child4ShortNameTemp}${profile.posMasterNoTemp}`
          : profile.child3Temp != null
            ? `${profile.child3ShortNameTemp}${profile.posMasterNoTemp}`
            : profile.child2Temp != null
              ? `${profile.child2ShortNameTemp}${profile.posMasterNoTemp}`
              : profile.child1Temp != null
                ? `${profile.child1ShortNameTemp}${profile.posMasterNoTemp}`
                : profile.rootIdTemp != null
                  ? `${profile.rootShortNameTemp}${profile.posMasterNoTemp}`
                  : null;

      return {
        id: profile.id,
        citizenId: profile.citizenId,
        prefix: profile.prefix,
        firstName: profile.firstName,
        lastName: profile.lastName,
        organization: profile.rootTemp,
        positionName: profile.positionTemp,
        positionType: profile.posTypeNameTemp,
        positionLevel: profile.posLevelNameTemp,
        positionNumber: shortName,
        birthDate: profile.birthDate,
      };
    });

    return new HttpSuccess(formattedData);
  }

  /**
   * API รายละเอียดรายการทะเบียนประวัติ
   *
   * @summary ORG_065 - รายละเอียดรายการทะเบียนประวัติ  (ADMIN) #70
   *
   * @param {string} id  Id ทะเบียนประวัติ
   */
  @Get("{id}")
  async detailProfile(@Path() id: string, @Request() req: RequestWithUser) {
    let _workflow = await new permission().Workflow(req, id, "SYS_REGISTRY_EMP");
    if (_workflow == false)
      await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_EMP", id);
    const profile: any = await this.profileRepo.findOne({
      relations: {
        posLevel: true,
        posType: true,
        // gender: true,
        // relationship: true,
        // bloodGroup: true,
      },
      where: { id },
    });

    if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");
    profile.profileType = "EMPLOYEE";

    return new HttpSuccess(profile);
  }

  @Get("admin/{id}")
  async detailProfileAdmin(@Path() id: string) {
    const profile = await this.profileRepo.findOne({
      relations: {
        posLevel: true,
        posType: true,
      },
      where: { id },
    });

    if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");

    return new HttpSuccess(profile);
  }

  /**
   * API รายการทะเบียนประวัติ
   *
   * @summary ORG_065 - รายการทะเบียนประวัติ (ADMIN) #70
   *
   */
  @Get()
  async listProfile(
    @Request() request: RequestWithUser,
    @Query("page") page: number = 1,
    @Query("pageSize") pageSize: number = 10,
    @Query()
    searchField?: "firstName" | "lastName" | "fullName" | "citizenId" | "position" | "posNo",
    @Query() searchKeyword: string = "",
    @Query() posType?: string,
    @Query() posLevel?: string,
    @Query() yearLeave?: number,
    @Query() isProbation?: boolean,
    @Query() isRetire?: boolean,
    @Query() type?: string,
    @Query() node?: number,
    @Query() nodeId?: string,
    @Query() isAll?: boolean,
  ) {
    let _data = await new permission().PermissionOrgList(request, "SYS_REGISTRY_EMP");
    let queryLike =
      "CONCAT(profileEmployee.prefix, profileEmployee.firstName, ' ', profileEmployee.lastName) LIKE :keyword";
    if (searchField == "citizenId") {
      queryLike = "profileEmployee.citizenId LIKE :keyword";
    } else if (searchField == "position") {
      queryLike = "profileEmployee.position LIKE :keyword";
    } else if (searchField == "posNo") {
      queryLike = `CONCAT(
          IFNULL(orgChild4.orgChild4ShortName, ''),
          IFNULL(orgChild3.orgChild3ShortName, ''),
          IFNULL(orgChild2.orgChild2ShortName, ''),
          IFNULL(orgChild1.orgChild1ShortName, ''),
          IFNULL(orgRoot.orgRootShortName, ''),
          IFNULL(current_holders.posMasterNo , '')
        ) LIKE :keyword`;
    }
    let nodeCondition = "1=1";
    let nodeAll = "";
    if (node === 0 && nodeId) {
      nodeCondition = "current_holders.orgRootId = :nodeId";
      if (isAll == false) nodeAll = " AND current_holders.orgChild1Id IS NULL";
    } else if (node === 1 && nodeId) {
      nodeCondition = "current_holders.orgChild1Id = :nodeId";
      if (isAll == false) nodeAll = " AND current_holders.orgChild2Id IS NULL";
    } else if (node === 2 && nodeId) {
      nodeCondition = "current_holders.orgChild2Id = :nodeId";
      if (isAll == false) nodeAll = " AND current_holders.orgChild3Id IS NULL";
    } else if (node === 3 && nodeId) {
      nodeCondition = "current_holders.orgChild3Id = :nodeId";
      if (isAll == false) nodeAll = " AND current_holders.orgChild4Id IS NULL";
    } else if (node === 4 && nodeId) {
      nodeCondition = "current_holders.orgChild4Id = :nodeId";
    }
    nodeCondition = nodeCondition + nodeAll;
    const [record, total] = await this.profileRepo
      .createQueryBuilder("profileEmployee")
      .leftJoinAndSelect("profileEmployee.posLevel", "posLevel")
      .leftJoinAndSelect("profileEmployee.posType", "posType")
      .leftJoinAndSelect("profileEmployee.current_holders", "current_holders")
      .leftJoinAndSelect("profileEmployee.profileEmployeeEmployment", "profileEmployeeEmployment")
      .leftJoinAndSelect("current_holders.positions", "positions")
      .leftJoinAndSelect("current_holders.orgRoot", "orgRoot")
      .leftJoinAndSelect("current_holders.orgChild1", "orgChild1")
      .leftJoinAndSelect("current_holders.orgChild2", "orgChild2")
      .leftJoinAndSelect("current_holders.orgChild3", "orgChild3")
      .leftJoinAndSelect("current_holders.orgChild4", "orgChild4")
      .andWhere(
        _data.root != undefined && _data.root != null
          ? _data.root[0] != null
            ? `current_holders.orgRootId IN (:...root)`
            : `current_holders.orgRootId is null`
          : "1=1",
        {
          root: _data.root,
        },
      )
      .andWhere(
        _data.child1 != undefined && _data.child1 != null
          ? _data.child1[0] != null
            ? `current_holders.orgChild1Id IN (:...child1)`
            : `current_holders.orgChild1Id is null`
          : "1=1",
        {
          child1: _data.child1,
        },
      )
      .andWhere(
        _data.child2 != undefined && _data.child2 != null
          ? _data.child2[0] != null
            ? `current_holders.orgChild2Id IN (:...child2)`
            : `current_holders.orgChild2Id is null`
          : "1=1",
        {
          child2: _data.child2,
        },
      )
      .andWhere(
        _data.child3 != undefined && _data.child3 != null
          ? _data.child3[0] != null
            ? `current_holders.orgChild3Id IN (:...child3)`
            : `current_holders.orgChild3Id is null`
          : "1=1",
        {
          child3: _data.child3,
        },
      )
      .andWhere(
        _data.child4 != undefined && _data.child4 != null
          ? _data.child4[0] != null
            ? `current_holders.orgChild4Id IN (:...child4)`
            : `current_holders.orgChild4Id is null`
          : "1=1",
        {
          child4: _data.child4,
        },
      )
      .andWhere(
        posType != undefined && posType != null && posType != ""
          ? "posType.posTypeName LIKE :keyword1"
          : "1=1",
        {
          keyword1: `${posType}`,
        },
      )
      .andWhere(
        posLevel != undefined && posLevel != null && posLevel != ""
          ? "posLevel.posLevelName LIKE :keyword2"
          : "1=1",
        {
          keyword2: `${posLevel}`,
        },
      )
      .andWhere(
        isProbation != undefined && isProbation != null
          ? `profile.isProbation = ${isProbation}`
          : "1=1",
      )
      .andWhere(
        isRetire != undefined && isRetire != null
          ? isRetire == true
            ? `profile.dateRetire IS null`
            : `profile.dateRetire IS NOT NULL`
          : "1=1",
      )
      .andWhere("profileEmployee.employeeClass LIKE :type", {
        type: "PERM",
      })
      .andWhere(
        searchKeyword != undefined && searchKeyword != null && searchKeyword != ""
          ? queryLike
          : "1=1",
        {
          keyword: `%${searchKeyword}%`,
        },
      )
      .andWhere(nodeCondition, {
        nodeId: nodeId,
      })
      .skip((page - 1) * pageSize)
      .take(pageSize)
      .getManyAndCount();
    const findRevision = await this.orgRevisionRepo.findOne({
      where: { orgRevisionIsCurrent: true },
    });
    if (!findRevision) {
      throw new HttpError(HttpStatus.NOT_FOUND, "not found. OrgRevision");
    }
    const data = await Promise.all(
      record.map((_data) => {
        const shortName =
          _data.current_holders.length == 0
            ? null
            : _data.current_holders[0].orgChild4 != null
              ? `${_data.current_holders[0].orgChild4.orgChild4ShortName}${_data.current_holders[0].posMasterNo}`
              : _data.current_holders[0].orgChild3 != null
                ? `${_data.current_holders[0].orgChild3.orgChild3ShortName}${_data.current_holders[0].posMasterNo}`
                : _data.current_holders[0].orgChild2 != null
                  ? `${_data.current_holders[0].orgChild2.orgChild2ShortName}${_data.current_holders[0].posMasterNo}`
                  : _data.current_holders[0].orgChild1 != null
                    ? `${_data.current_holders[0].orgChild1.orgChild1ShortName}${_data.current_holders[0].posMasterNo}`
                    : _data.current_holders[0].orgRoot != null
                      ? `${_data.current_holders[0].orgRoot.orgRootShortName}${_data.current_holders[0].posMasterNo}`
                      : null;
        const dateEmployment =
          _data.profileEmployeeEmployment.length == 0
            ? null
            : _data.profileEmployeeEmployment.reduce((latest, current) => {
                return latest.date > current.date ? latest : current;
              }).date;
        const root =
          _data.current_holders.length == 0 ||
          (_data.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
            _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null)
            ? null
            : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot;

        const child1 =
          _data.current_holders == null ||
          _data.current_holders.length == 0 ||
          _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null
            ? null
            : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1;

        const child2 =
          _data.current_holders == null ||
          _data.current_holders.length == 0 ||
          _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null
            ? null
            : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2;

        const child3 =
          _data.current_holders == null ||
          _data.current_holders.length == 0 ||
          _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null
            ? null
            : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3;

        const child4 =
          _data.current_holders == null ||
          _data.current_holders.length == 0 ||
          _data.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null
            ? null
            : _data.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4;

        let _child1 = child1 == null ? "" : `${child1.orgChild1Name}/`;
        let _child2 = child2 == null ? "" : `${child2.orgChild2Name}/`;
        let _child3 = child3 == null ? "" : `${child3.orgChild3Name}/`;
        let _child4 = child4 == null ? "" : `${child4.orgChild4Name}/`;
        return {
          id: _data.id,
          prefix: _data.prefix,
          rank: _data.rank,
          firstName: _data.firstName,
          lastName: _data.lastName,
          citizenId: _data.citizenId,
          posLevel: _data.posLevel == null ? null : _data.posLevel.posLevelName,
          posType: _data.posType == null ? null : _data.posType.posTypeName,
          posTypeShortName: _data.posType == null ? null : _data.posType.posTypeShortName,
          posLevelId: _data.posLevel == null ? null : _data.posLevel.id,
          posTypeId: _data.posType == null ? null : _data.posType.id,
          positionId: _data.positionIdTemp,
          posmasterId: _data.posmasterIdTemp,
          position: _data.position,
          posNo: _data.employeeClass == "TEMP" ? _data.posMasterNoTemp : shortName,
          employeeClass: _data.employeeClass == null ? null : _data.employeeClass,
          govAge: Extension.CalculateGovAge(_data.dateAppoint, 0, 0),
          age: Extension.CalculateAgeStrV2(_data.birthDate, 0, 0),
          dateEmployment: dateEmployment,
          dateAppoint: _data.dateAppoint,
          dateStart: _data.dateStart,
          createdAt: _data.createdAt,
          dateRetireLaw: _data.dateRetireLaw,
          draftOrganizationOrganization:
            _data.nodeTemp == "0"
              ? _data.rootTemp
              : _data.nodeTemp == "1"
                ? _data.child1Temp
                : _data.nodeTemp == "2"
                  ? _data.child2Temp
                  : _data.nodeTemp == "3"
                    ? _data.child3Temp
                    : _data.nodeTemp == "4"
                      ? _data.child4Temp
                      : null,
          draftPositionEmployee: _data.positionTemp,
          draftOrgEmployeeStatus: _data.statusTemp,
          node: _data.nodeTemp,
          nodeId: _data.nodeIdTemp,
          nodeName:
            _data.nodeTemp == "0"
              ? _data.rootTemp
              : _data.nodeTemp == "1"
                ? _data.child1Temp
                : _data.nodeTemp == "2"
                  ? _data.child2Temp
                  : _data.nodeTemp == "3"
                    ? _data.child3Temp
                    : _data.nodeTemp == "4"
                      ? _data.child4Temp
                      : null,
          nodeShortName:
            _data.nodeTemp == "0"
              ? _data.rootShortNameTemp
              : _data.nodeTemp == "1"
                ? _data.child1ShortNameTemp
                : _data.nodeTemp == "2"
                  ? _data.child1ShortNameTemp
                  : _data.nodeTemp == "3"
                    ? _data.child3ShortNameTemp
                    : _data.nodeTemp == "4"
                      ? _data.child4ShortNameTemp
                      : null,
          root: _data.rootTemp ? _data.rootTemp : null,
          rootId: _data.rootIdTemp ? _data.rootIdTemp : null,
          rootShortName: _data.rootShortNameTemp ? _data.rootShortNameTemp : null,
          child1: _data.child1Temp ? _data.child1Temp : null,
          child1Id: _data.child1IdTemp ? _data.child1IdTemp : null,
          child1ShortName: _data.child1ShortNameTemp ? _data.child1ShortNameTemp : null,
          child2: _data.child2Temp ? _data.child2Temp : null,
          child2Id: _data.child2IdTemp ? _data.child2IdTemp : null,
          child2ShortName: _data.child2ShortNameTemp ? _data.child2ShortNameTemp : null,
          child3: _data.child3Temp ? _data.child3Temp : null,
          child3Id: _data.child3IdTemp ? _data.child3IdTemp : null,
          child3ShortName: _data.child3ShortNameTemp ? _data.child3ShortNameTemp : null,
          child4: _data.child4Temp ? _data.child4Temp : null,
          child4Id: _data.child4IdTemp ? _data.child4IdTemp : null,
          child4ShortName: _data.child4ShortNameTemp ? _data.child4ShortNameTemp : null,
          org: `${_child4}${_child3}${_child2}${_child1}${root?.orgRootName ?? ""}`,
        };
      }),
    );

    return new HttpSuccess({ data: data, total });
  }

  @Get("history/{id}")
  async getProfileHistory(@Path() id: string, @Request() req: RequestWithUser) {
    //await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_EMP", id); ไม่แน่ใจEMPปิดไว้ก่อน;
    const profile = await this.profileHistoryRepo.find({
      relations: {
        posLevel: true,
        posType: true,
      },
      where: { profileEmployeeId: id },
      order: {
        createdAt: "ASC",
      },
    });

    if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");

    return new HttpSuccess(profile);
  }

  /**
   * API ค้นหารายชื่อไปครองตำแหน่ง
   *
   * @summary ORG_063 - ค้นหารายชื่อไปครองตำแหน่ง (ADMIN) #68
   *
   */
  @Post("search")
  async searchProfileOrg(
    @Body()
    requestBody: {
      position?: string;
      posLevelId?: string;
      posTypeId?: string;
      page: number;
      pageSize: number;
      keyword?: string;
    },
  ) {
    const orgRevision = await this.orgRevisionRepo.findOne({
      where: {
        orgRevisionIsDraft: false,
        orgRevisionIsCurrent: true,
      },
      relations: ["employeePosMasters"],
    });
    if (!orgRevision) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง");
    }
    const [profiles, total] = await this.profileRepo
      .createQueryBuilder("profileEmployee")
      .leftJoinAndSelect("profileEmployee.next_holders", "next_holders")
      .leftJoinAndSelect("profileEmployee.posLevel", "posLevel")
      .leftJoinAndSelect("profileEmployee.posType", "posType")
      .where(
        requestBody.position != null && requestBody.position != ""
          ? "profileEmployee.position LIKE :position"
          : "1=1",
        {
          position: `%${requestBody.position}%`,
        },
      )
      .andWhere("profileEmployee.isLeave IS FALSE")
      .andWhere(
        new Brackets((qb) => {
          qb.where(
            requestBody.keyword != null && requestBody.keyword != ""
              ? "profileEmployee.prefix LIKE :keyword"
              : "1=1",
            {
              keyword: `%${requestBody.keyword}%`,
            },
          )
            .orWhere(
              requestBody.keyword != null && requestBody.keyword != ""
                ? "profileEmployee.firstName LIKE :keyword"
                : "1=1",
              {
                keyword: `%${requestBody.keyword}%`,
              },
            )
            .orWhere(
              requestBody.keyword != null && requestBody.keyword != ""
                ? "profileEmployee.lastName LIKE :keyword"
                : "1=1",
              {
                keyword: `%${requestBody.keyword}%`,
              },
            )
            .orWhere(
              requestBody.keyword != null && requestBody.keyword != ""
                ? "profileEmployee.citizenId LIKE :keyword"
                : "1=1",
              {
                keyword: `%${requestBody.keyword}%`,
              },
            );
        }),
      )
      .andWhere(
        requestBody.posTypeId != null && requestBody.posTypeId != ""
          ? "profileEmployee.posTypeId LIKE :posTypeId"
          : "1=1",
        {
          posTypeId: `%${requestBody.posTypeId}%`,
        },
      )
      .andWhere(
        requestBody.posLevelId != null && requestBody.posLevelId != ""
          ? "profileEmployee.posLevelId LIKE :posLevelId"
          : "1=1",
        {
          posLevelId: `%${requestBody.posLevelId}%`,
        },
      )
      .andWhere(
        new Brackets((qb) => {
          qb.where("profileEmployee.id NOT IN (:...ids)", {
            ids:
              orgRevision.employeePosMasters
                .filter((x) => x.next_holderId != null)
                .map((x) => x.next_holderId).length == 0
                ? ["zxc"]
                : orgRevision.employeePosMasters
                    .filter((x) => x.next_holderId != null)
                    .map((x) => x.next_holderId),
          });
        }),
      )
      .andWhere("profileEmployee.employeeClass = :employeeClass", { employeeClass: "PERM" })
      .skip((requestBody.page - 1) * requestBody.pageSize)
      .take(requestBody.pageSize)
      .getManyAndCount();
    const data = profiles.map((_data) => ({
      id: _data.id,
      prefix: _data.prefix,
      rank: _data.rank,
      firstName: _data.firstName,
      lastName: _data.lastName,
      citizenId: _data.citizenId,
      posLevel: _data.posLevel == null ? null : _data.posLevel.posLevelName,
      posType: _data.posType == null ? null : _data.posType.posTypeName,
      position: _data.position,
    }));

    return new HttpSuccess({ data: data, total });
  }

  /**
   * API ค้นหาประวัติการครองตำแหน่ง ลูกจ้าง
   *
   * @summary ค้นหาประวัติการครองตำแหน่ง ลูกจ้าง
   *
   */
  @Post("search/history/oc")
  async searchHistoryOC(
    @Body()
    requestBody: {
      posNo?: string;
      position?: string;
    },
  ) {
    const profiles = await this.profileRepo
      .createQueryBuilder("profileEmployee")
      .leftJoinAndSelect("profileEmployee.profileSalary", "profileSalary")
      .select([
        "profileEmployee.id",
        "profileEmployee.prefix",
        "profileEmployee.firstName",
        "profileEmployee.lastName",
        "profileEmployee.citizenId",
        "profileSalary.position",
        "profileSalary.posNo",
        "profileSalary.date",
      ])
      .andWhere(
        requestBody.position != null && requestBody.position != "" && requestBody.posNo == undefined
          ? "profileSalary.position LIKE :position"
          : "1=2",
        {
          position: `%${requestBody.position}%`,
        },
      )
      .orWhere(
        requestBody.posNo != null && requestBody.posNo != "" && requestBody.position == undefined
          ? "profileSalars.posNo LIKE :posNo"
          : "1=2",
        {
          posNo: `%${requestBody.posNo}%`,
        },
      )
      .getMany();

    const mapData = profiles.map((profile) => {
      let profileSalary;
      if (profile.profileSalary && profile.profileSalary.length > 0) {
        profileSalary = profile.profileSalary.reduce((latest, current) => {
          return new Date(current.date) > new Date(latest.date) ? current : latest;
        });
      }
      return {
        id: profile.id,
        fullName: `${profile.prefix}${profile.firstName} ${profile.lastName}`,
        citizenId: profile.citizenId,
        position: profileSalary ? profileSalary.position : null,
        posNo: profileSalary ? profileSalary.posNo : null,
        date: profileSalary ? profileSalary.date : null,
      };
    });

    return new HttpSuccess(mapData);
  }

  /**
   * API ข้อมูลทะเบียนประวัติตาม keycloak
   *
   * @summary ORG_065 - ข้อมูลทะเบียนประวัติตาม keycloak (ADMIN) #70
   *
   */
  @Get("keycloak/position")
  async getProfileByKeycloak(
    @Request() request: { user: Record<string, any> },
    @Query("revisionId") revisionId?: string,
  ) {
    const profile = await this.profileRepo.findOne({
      where: { keycloak: request.user.sub },
      relations: [
        "posLevel",
        "posType",
        "current_holders",
        "current_holders.orgRoot",
        "current_holders.orgChild1",
        "current_holders.orgChild2",
        "current_holders.orgChild3",
        "current_holders.orgChild4",
        "profileSalary",
      ],
      order: {
        profileSalary: {
          order: "DESC",
        },
      },
    });
    if (!profile) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ");
    }

    let orgRevisionPublish: any = await this.orgRevisionRepo
      .createQueryBuilder("orgRevision")
      .where("orgRevision.orgRevisionIsDraft = false")
      .andWhere("orgRevision.orgRevisionIsCurrent = true")
      .getOne();
    if (!orgRevisionPublish) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง");
    }

    if (revisionId) {
      orgRevisionPublish = await this.orgRevisionRepo
        .createQueryBuilder("orgRevision")
        .where("orgRevision.id = :revisionId", { revisionId })
        .getOne();
      if (!orgRevisionPublish) {
        throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง");
      }
    }

    const posMaster =
      profile.current_holders == null ||
      profile.current_holders.length == 0 ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) == null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id);

    const root =
      profile.current_holders == null ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot == null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot;
    const child1 =
      profile.current_holders == null ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1 ==
        null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1;
    const child2 =
      profile.current_holders == null ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2 ==
        null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2;
    const child3 =
      profile.current_holders == null ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3 ==
        null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3;
    const child4 =
      profile.current_holders == null ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4 ==
        null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4;

    const position = await this.positionRepository.findOne({
      relations: ["posExecutive"],
      where: {
        posMasterId: posMaster?.id,
      },
    });

    const _profile = {
      profileId: profile.id,
      prefix: profile.prefix,
      rank: profile.rank,
      avatar: profile.avatar,
      isProbation: profile.isProbation,
      avatarName: profile.avatarName,
      firstName: profile.firstName,
      lastName: profile.lastName,
      citizenId: profile.citizenId,
      birthDate: profile.birthDate,
      position: profile.position,
      leaveDate: profile.dateLeave,
      dateStart: profile.dateStart,
      dateRetireLaw: profile.dateRetireLaw,
      posMaster: posMaster == null ? null : posMaster.posMasterNo,
      posMasterNo: posMaster == null ? null : posMaster.posMasterNo,
      posLevelName: profile.posLevel == null ? null : profile.posLevel.posLevelName,
      posLevelRank: profile.posLevel == null ? null : profile.posLevel.posLevelRank,
      posLevelId: profile.posLevel == null ? null : profile.posLevel.id,
      posTypeName: profile.posType == null ? null : profile.posType.posTypeName,
      posTypeRank: profile.posType == null ? null : profile.posType.posTypeRank,
      posTypeId: profile.posType == null ? null : profile.posType.id,
      posExecutiveName:
        position == null || position.posExecutive == null
          ? null
          : position.posExecutive.posExecutiveName,
      posExecutivePriority:
        position == null || position.posExecutive == null
          ? null
          : position.posExecutive.posExecutivePriority,
      posExecutiveId:
        position == null || position.posExecutive == null ? null : position.posExecutive.id,
      rootId: root == null ? null : root.id,
      root: root == null ? null : root.orgRootName,
      rootShortName: root == null ? null : root.orgRootShortName,
      child1Id: child1 == null ? null : child1.id,
      child1: child1 == null ? null : child1.orgChild1Name,
      child1ShortName: child1 == null ? null : child1.orgChild1ShortName,
      child2Id: child2 == null ? null : child2.id,
      child2: child2 == null ? null : child2.orgChild2Name,
      child2ShortName: child2 == null ? null : child2.orgChild2ShortName,
      child3Id: child3 == null ? null : child3.id,
      child3: child3 == null ? null : child3.orgChild3Name,
      child3ShortName: child3 == null ? null : child3.orgChild3ShortName,
      child4Id: child4 == null ? null : child4.id,
      child4: child4 == null ? null : child4.orgChild4Name,
      child4ShortName: child4 == null ? null : child4.orgChild4ShortName,
      node: null,
      nodeId: null,
      salary: profile && profile.profileSalary.length > 0 ? profile.profileSalary[0].amount : null,
    };
    return new HttpSuccess(_profile);
  }

  /**
   * API ค้นหาข้อมูลทะเบียนประวัติ
   *
   * @summary ORG_065 - ค้นหาข้อมูลทะเบียนประวัติ (ADMIN) #70
   *
   */
  @Post("search-personal")
  async getProfileBySearchKeyword(
    @Query("page") page: number = 1,
    @Query("pageSize") pageSize: number = 10,
    @Body()
    body: {
      fieldName: string;
      keyword?: string;
    },
  ) {
    let findProfile: any;
    let total: any;
    const skip = (page - 1) * pageSize;
    const take = pageSize;
    switch (body.fieldName) {
      case "citizenId":
        [findProfile, total] = await this.profileRepo.findAndCount({
          where: { citizenId: Like(`%${body.keyword}%`) },
          relations: [
            "posType",
            "posLevel",
            "current_holders",
            "profileSalary",
            "current_holders.orgRoot",
            "current_holders.orgChild1",
            "current_holders.orgChild2",
            "current_holders.orgChild3",
            "current_holders.orgChild4",
          ],
          skip,
          take,
        });
        break;

      case "firstname":
        [findProfile, total] = await this.profileRepo.findAndCount({
          where: { firstName: Like(`%${body.keyword}%`) },
          relations: [
            "posType",
            "posLevel",
            "current_holders",
            "profileSalary",
            "current_holders.orgRoot",
            "current_holders.orgChild1",
            "current_holders.orgChild2",
            "current_holders.orgChild3",
            "current_holders.orgChild4",
          ],
          skip,
          take,
        });
        break;

      case "lastname":
        [findProfile, total] = await this.profileRepo.findAndCount({
          where: { lastName: Like(`%${body.keyword}%`) },
          relations: [
            "posType",
            "posLevel",
            "current_holders",
            "profileSalary",
            "current_holders.orgRoot",
            "current_holders.orgChild1",
            "current_holders.orgChild2",
            "current_holders.orgChild3",
            "current_holders.orgChild4",
          ],
          skip,
          take,
        });
        break;

      default:
        [findProfile, total] = await this.profileRepo.findAndCount({
          relations: [
            "posType",
            "posLevel",
            "current_holders",
            "profileSalary",
            "current_holders.orgRoot",
            "current_holders.orgChild1",
            "current_holders.orgChild2",
            "current_holders.orgChild3",
            "current_holders.orgChild4",
          ],
          skip,
          take,
        });
        break;
    }

    const findRevision = await this.orgRevisionRepo.findOne({
      where: { orgRevisionIsCurrent: true },
    });
    if (!findRevision) {
      throw new HttpError(HttpStatus.NOT_FOUND, "not found. OrgRevision");
    }

    const mapDataProfile = await Promise.all(
      findProfile.map(async (item: ProfileEmployee) => {
        const fullName = `${item.prefix} ${item.firstName} ${item.lastName}`;
        const shortName =
          item.current_holders.length == 0
            ? null
            : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
                item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 !=
                  null
              ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4.orgChild4ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
              : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
                  item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3 !=
                    null
                ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3.orgChild3ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
                : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
                    item.current_holders.find((x) => x.orgRevisionId == findRevision.id)
                      ?.orgChild2 != null
                  ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2.orgChild2ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
                  : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
                      item.current_holders.find((x) => x.orgRevisionId == findRevision.id)
                        ?.orgChild1 != null
                    ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1.orgChild1ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
                    : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) !=
                          null &&
                        item.current_holders.find((x) => x.orgRevisionId == findRevision.id)
                          ?.orgRoot != null
                      ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot.orgRootShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
                      : null;

        const root =
          item.current_holders.length == 0 ||
          (item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
            item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null)
            ? null
            : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot;

        let salary: any = "";
        if (item != null && item.profileSalary != null && item.profileSalary.length > 0) {
          let _salary: any = item.profileSalary.sort(
            (a, b) =>
              (b.date == null ? 0 : b.date.getTime()) - (a.date == null ? 0 : a.date.getTime()),
          );
          if (_salary.length > 0) {
            salary = _salary[0];
          }
        }

        const rootHolder = item.current_holders?.find(
          (x) => x.orgRevisionId == findRevision.id,
        )?.orgRoot;
        const child1Holder = item.current_holders?.find(
          (x) => x.orgRevisionId == findRevision.id,
        )?.orgChild1;
        const child2Holder = item.current_holders?.find(
          (x) => x.orgRevisionId == findRevision.id,
        )?.orgChild2;
        const child3Holder = item.current_holders?.find(
          (x) => x.orgRevisionId == findRevision.id,
        )?.orgChild3;
        const child4Holder = item.current_holders?.find(
          (x) => x.orgRevisionId == findRevision.id,
        )?.orgChild4;
        const posMasterNo = item.current_holders?.find(
          (x) => x.orgRevisionId == findRevision.id,
        )?.posMasterNo;

        const latestProfileEducation = await this.profileEducationRepository.findOne({
          where: { profileEmployeeId: item.id },
          order: { endDate: "DESC" },
        });

        return {
          id: item.id,
          prefix: item.prefix,
          rank: item.rank,
          firstName: item.firstName,
          lastName: item.lastName,
          position: item.position,
          citizenId: item.citizenId,
          email: item.email,
          phone: item.phone,
          name: fullName,
          birthDate: item.birthDate,
          positionLevel: item.posLevelId,
          positionLevelName: item.posLevel?.posLevelName,
          positionType: item.posTypeId,
          positionTypeName: item.posType?.posTypeName,
          posNo: shortName,
          organization: root == null ? null : root.orgRootShortName,
          salary: salary == "" ? "" : salary.amount,
          root: rootHolder?.orgRootName ?? null,
          rootId: rootHolder?.id ?? null,
          rootShortName: rootHolder?.orgRootShortName ?? null,
          child1: child1Holder?.orgChild1Name ?? null,
          child1Id: child1Holder?.id ?? null,
          child1ShortName: child1Holder?.orgChild1ShortName ?? null,
          child2: child2Holder?.orgChild2Name ?? null,
          child2Id: child2Holder?.id ?? null,
          child2ShortName: child2Holder?.orgChild2ShortName ?? null,
          child3: child3Holder?.orgChild3Name ?? null,
          child3Id: child3Holder?.id ?? null,
          child3ShortName: child3Holder?.orgChild3ShortName ?? null,
          child4: child4Holder?.orgChild4Name ?? null,
          child4Id: child4Holder?.id ?? null,
          child4ShortName: child4Holder?.orgChild4ShortName ?? null,
          posMasterNo: posMasterNo ?? null,
          posTypeId: item.posTypeId,
          posTypeName: item.posType?.posTypeName,
          posLevelId: item.posLevelId,
          posLevelName: item.posLevel?.posLevelName,
          educationDegree:
            latestProfileEducation != null && latestProfileEducation.educationLevel != null
              ? latestProfileEducation.educationLevel
              : null,
          // ? {
          //     id: latestProfileEducation.id,
          //     degree: latestProfileEducation.degree,
          //     country: latestProfileEducation.country,
          //     duration: latestProfileEducation.duration,
          //     durationYear: latestProfileEducation.durationYear,
          //     field: latestProfileEducation.field,
          //     finishDate: latestProfileEducation.finishDate,
          //     fundName: latestProfileEducation.fundName,
          //     gpa: latestProfileEducation.gpa,
          //     institute: latestProfileEducation.institute,
          //     other: latestProfileEducation.other,
          //     startDate: latestProfileEducation.startDate,
          //     endDate: latestProfileEducation.endDate,
          //     educationLevel: latestProfileEducation.educationLevel,
          //     positionPath: latestProfileEducation.positionPath,
          //     positionPathId: latestProfileEducation.positionPathId,
          //     isDate: latestProfileEducation.isDate,
          //     isEducation: latestProfileEducation.isEducation,
          //     note: latestProfileEducation.note,
          //   }
          // : null,
        };
      }),
    );

    return new HttpSuccess({ data: mapDataProfile, total });
  }

  /**
   * API ค้นหาผู้บังคับบัญชา
   *
   * @summary ORG_069 - ค้นหาผู้บังคับบัญชา (ADMIN) #75
   *
   */
  @Get("search/commander")
  async searchCommander(@Request() request: { user: Record<string, any> }) {
    let fullName_: any = {};
    let position_: any = {};
    let commanderAboveFullname_: any = {};
    let commanderAbovePosition_: any = {};
    let commanderFullname_: any = {};
    let commanderPosition_: any = {};

    const findProfile = await this.profileRepo.findOne({
      where: { keycloak: request.user.sub },
    });

    const findRevision = await this.orgRevisionRepo.findOne({
      where: {
        orgRevisionIsCurrent: true,
      },
    });

    const findPosMaster = await this.posMasterRepo.findOne({
      where: {
        current_holderId: findProfile?.id,
        orgRevisionId: findRevision?.id,
      },
    });

    let node = 4;
    let childId = findPosMaster?.orgChild4Id;
    let condition: any = { orgChild4Id: childId };

    if (findPosMaster?.orgChild4Id == null && findPosMaster?.orgChild3Id != null) {
      node = 3;
      childId = findPosMaster?.orgChild3Id;
      condition = { orgChild3Id: childId, orgChild4Id: IsNull() };
    } else if (findPosMaster?.orgChild3Id == null && findPosMaster?.orgChild2Id != null) {
      node = 2;
      childId = findPosMaster?.orgChild2Id;
      condition = { orgChild2Id: childId, orgChild3Id: IsNull() };
    } else if (findPosMaster?.orgChild2Id == null && findPosMaster?.orgChild1Id != null) {
      node = 1;
      childId = findPosMaster?.orgChild1Id;
      condition = { orgChild1Id: childId, orgChild2Id: IsNull() };
    } else if (findPosMaster?.orgChild1Id == null) {
      node = 0;
      childId = findPosMaster?.orgRootId;
      condition = { orgRootId: childId, orgChild1Id: IsNull() };
    }

    const findCmd = await this.posMasterRepo.findOne({
      where: {
        current_holderId: Not(IsNull()) || Not(""),
        orgRevisionId: findRevision?.id,
        ...condition,
      },
      relations: ["current_holder"],
      order: { posMasterOrder: "ASC" },
    });
    let findOSAB: EmployeePosMaster | null = null;
    let findTSAB: EmployeePosMaster | null = null;
    //หาผู้บังคับบัญชาที่เหนือขึ้นไปอีก 1 ขั้น
    if (node !== 0) {
      findOSAB = await AppDataSource.getRepository(EmployeePosMaster)
        .createQueryBuilder("posMaster")
        .leftJoinAndSelect("posMaster.current_holder", "current_holder")
        .where("posMaster.current_holderId IS NOT NULL")
        .andWhere("posMaster.orgRevisionId = :revisionId", { revisionId: findRevision?.id })
        .andWhere(
          new Brackets((qb) => {
            if (node === 4) {
              qb.andWhere("posMaster.orgChild4Id IS NULL");
              qb.andWhere("posMaster.orgChild3Id = :childId", {
                childId: findPosMaster?.orgChild3Id,
              });
            } else if (node === 3) {
              qb.andWhere("posMaster.orgChild3Id IS NULL");
              qb.andWhere("posMaster.orgChild2Id = :childId", {
                childId: findPosMaster?.orgChild2Id,
              });
            } else if (node === 2) {
              qb.andWhere("posMaster.orgChild2Id IS NULL");
              qb.andWhere("posMaster.orgChild1Id = :childId", {
                childId: findPosMaster?.orgChild1Id,
              });
            } else if (node === 1) {
              qb.andWhere("posMaster.orgChild1Id IS NULL");
              qb.andWhere("posMaster.orgRootId = :childId", { childId: findPosMaster?.orgRootId });
            }
          }),
        )
        .orderBy("posMaster.posMasterOrder", "ASC")
        .getOne();
    }

    //หาผู้บังคับบัญชาที่เหนือขึ้นไปอีก 2 ขั้น
    if (node !== 0 && node !== 1) {
      findTSAB = await AppDataSource.getRepository(EmployeePosMaster)
        .createQueryBuilder("posMaster")
        .leftJoinAndSelect("posMaster.current_holder", "current_holder")
        .where("posMaster.current_holderId IS NOT NULL")
        .andWhere("posMaster.orgRevisionId = :revisionId", { revisionId: findRevision?.id })
        .andWhere(
          new Brackets((qb) => {
            if (node === 4) {
              qb.andWhere("posMaster.orgChild3Id IS NULL");
              qb.andWhere("posMaster.orgChild2Id = :childId", {
                childId: findPosMaster?.orgChild2Id,
              });
            } else if (node === 3) {
              qb.andWhere("posMaster.orgChild2Id IS NULL");
              qb.andWhere("posMaster.orgChild1Id = :childId", {
                childId: findPosMaster?.orgChild1Id,
              });
            } else if (node === 2) {
              qb.andWhere("posMaster.orgChild1Id IS NULL");
              qb.andWhere("posMaster.orgRootId = :childId", {
                childId: findPosMaster?.orgRootId,
              });
            }
          }),
        )
        .orderBy("posMaster.posMasterOrder", "ASC")
        .getOne();
    }
    fullName_ =
      (findProfile?.prefix ?? "") +
      (findProfile?.firstName ?? "") +
      (findProfile?.firstName ? " " : "") +
      (findProfile?.lastName ?? "");
    position_ = findProfile?.position ?? "";
    commanderFullname_ =
      (findCmd?.current_holder?.prefix ?? "") +
      (findCmd?.current_holder?.firstName ?? "") +
      (findCmd?.current_holder?.firstName ? " " : "") +
      (findCmd?.current_holder?.lastName ?? "");
    commanderPosition_ = findCmd?.current_holder?.position ?? "";
    commanderAboveFullname_ =
      (findOSAB?.current_holder?.prefix ?? "") +
      (findOSAB?.current_holder?.firstName ?? "") +
      (findOSAB?.current_holder?.firstName ? " " : "") +
      (findOSAB?.current_holder?.lastName ?? "");
    commanderAbovePosition_ = findOSAB?.current_holder?.position ?? "";

    if (findCmd?.current_holderId == findProfile?.id) {
      commanderFullname_ =
        (findOSAB?.current_holder?.prefix ?? "") +
        (findOSAB?.current_holder?.firstName ?? "") +
        (findOSAB?.current_holder?.firstName ? " " : "") +
        (findOSAB?.current_holder?.lastName ?? "");
      commanderPosition_ = findOSAB?.current_holder?.position ?? "";
      commanderAboveFullname_ =
        (findTSAB?.current_holder?.prefix ?? "") +
        (findTSAB?.current_holder?.firstName ?? "") +
        (findTSAB?.current_holder?.firstName ? " " : "") +
        (findTSAB?.current_holder?.lastName ?? "");
      commanderAbovePosition_ = findTSAB?.current_holder?.position ?? "";

      const formattedDataTSAB = {
        fullname: fullName_,
        position: position_,
        commanderAboveFullname: commanderAboveFullname_,
        commanderAbovePosition: commanderAbovePosition_,
        commanderFullname: commanderFullname_,
        commanderPosition: commanderPosition_,
      };
      return new HttpSuccess(formattedDataTSAB);
    }

    const formattedData = {
      fullname: fullName_,
      position: position_,
      commanderAboveFullname: commanderAboveFullname_,
      commanderAbovePosition: commanderAbovePosition_,
      commanderFullname: commanderFullname_,
      commanderPosition: commanderPosition_,
    };
    return new HttpSuccess(formattedData);
  }

  /**
   * API บันทึกตำแหน่งลูกจ้างชั่วคราว
   *
   * @summary บันทึกตำแหน่งลูกจ้างชั่วคราว (ADMIN)
   *
   * @param {string} id  Id ทะเบียนประวัติลูกจ้างชั่วคราว
   */
  @Put("position/{id}")
  async positionProfileEmployee(
    @Request() request: RequestWithUser,
    @Path() id: string,
    @Body() body: UpdatePositionTempProfileEmployee,
  ) {
    // await new permission().PermissionOrgUserUpdate(request, "SYS_REGISTRY_EMP", id);//ไม่แน่ใจEMPปิดไว้ก่อน
    if (body.posLevelId === "") body.posLevelId = null;
    if (body.posTypeId === "") body.posTypeId = null;

    if (body.posLevelId && !(await this.posLevelRepo.findOneBy({ id: body.posLevelId }))) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลระดับตำแหน่งนี้");
    }
    if (body.posTypeId && !(await this.posTypeRepo.findOneBy({ id: body.posTypeId }))) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้");
    }
    const profileEmp = await this.profileRepo.findOneBy({ id });
    if (!profileEmp) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้");

    switch (body.node) {
      case 0: {
        const data = await this.orgRootRepository.findOne({
          where: { id: body.nodeId },
        });
        if (data != null) {
          profileEmp.rootIdTemp = data.id;
          profileEmp.rootTemp = data.orgRootName;
          profileEmp.rootShortNameTemp = data.orgRootShortName;
        }
      }
      case 1: {
        const data = await this.child1Repository.findOne({
          where: { id: body.nodeId },
          relations: ["orgRoot"],
        });
        if (data != null) {
          profileEmp.rootIdTemp = data.orgRoot.id;
          profileEmp.rootTemp = data.orgRoot.orgRootName;
          profileEmp.rootShortNameTemp = data.orgRoot.orgRootShortName;
          profileEmp.child1IdTemp = data.id;
          profileEmp.child1Temp = data.orgChild1Name;
          profileEmp.child1ShortNameTemp = data.orgChild1ShortName;
        }
      }
      case 2: {
        const data = await this.child2Repository.findOne({
          where: { id: body.nodeId },
          relations: ["orgRoot", "orgChild1"],
        });
        if (data != null) {
          profileEmp.rootIdTemp = data.orgRoot.id;
          profileEmp.rootTemp = data.orgRoot.orgRootName;
          profileEmp.rootShortNameTemp = data.orgRoot.orgRootShortName;
          profileEmp.child1IdTemp = data.orgChild1.id;
          profileEmp.child1Temp = data.orgChild1.orgChild1Name;
          profileEmp.child1ShortNameTemp = data.orgChild1.orgChild1ShortName;
          profileEmp.child2IdTemp = data.id;
          profileEmp.child2Temp = data.orgChild2Name;
          profileEmp.child2ShortNameTemp = data.orgChild2ShortName;
        }
      }
      case 3: {
        const data = await this.child3Repository.findOne({
          where: { id: body.nodeId },
          relations: ["orgRoot", "orgChild1", "orgChild2"],
        });
        if (data != null) {
          profileEmp.rootIdTemp = data.orgRoot.id;
          profileEmp.rootTemp = data.orgRoot.orgRootName;
          profileEmp.rootShortNameTemp = data.orgRoot.orgRootShortName;
          profileEmp.child1IdTemp = data.orgChild1.id;
          profileEmp.child1Temp = data.orgChild1.orgChild1Name;
          profileEmp.child1ShortNameTemp = data.orgChild1.orgChild1ShortName;
          profileEmp.child2IdTemp = data.orgChild2.id;
          profileEmp.child2Temp = data.orgChild2.orgChild2Name;
          profileEmp.child2ShortNameTemp = data.orgChild2.orgChild2ShortName;
          profileEmp.child3IdTemp = data.id;
          profileEmp.child3Temp = data.orgChild3Name;
          profileEmp.child3ShortNameTemp = data.orgChild3ShortName;
        }
      }
      case 4: {
        const data = await this.child4Repository.findOne({
          where: { id: body.nodeId },
          relations: ["orgRoot", "orgChild1", "orgChild2", "orgChild3"],
        });
        if (data != null) {
          profileEmp.rootIdTemp = data.orgRoot.id;
          profileEmp.rootTemp = data.orgRoot.orgRootName;
          profileEmp.rootShortNameTemp = data.orgRoot.orgRootShortName;
          profileEmp.child1IdTemp = data.orgChild1.id;
          profileEmp.child1Temp = data.orgChild1.orgChild1Name;
          profileEmp.child1ShortNameTemp = data.orgChild1.orgChild1ShortName;
          profileEmp.child2IdTemp = data.orgChild2.id;
          profileEmp.child2Temp = data.orgChild2.orgChild2Name;
          profileEmp.child2ShortNameTemp = data.orgChild2.orgChild2ShortName;
          profileEmp.child3IdTemp = data.orgChild3.id;
          profileEmp.child3Temp = data.orgChild3.orgChild3Name;
          profileEmp.child3ShortNameTemp = data.orgChild3.orgChild3ShortName;
          profileEmp.child4IdTemp = data.id;
          profileEmp.child4Temp = data.orgChild4Name;
          profileEmp.child4ShortNameTemp = data.orgChild4ShortName;
        }
      }
    }

    profileEmp.lastUpdateUserId = request.user.sub;
    profileEmp.lastUpdateFullName = request.user.name;
    profileEmp.lastUpdatedAt = new Date();
    profileEmp.nodeTemp = String(body.node);
    profileEmp.nodeIdTemp = body.nodeId;
    profileEmp.orgRevisionIdTemp = body.orgRevisionId;
    profileEmp.posmasterIdTemp = body.posmasterId;
    profileEmp.posMasterNoTemp = body.posMasterNo;
    profileEmp.positionIdTemp = body.positionId;
    profileEmp.positionTemp = body.position;
    profileEmp.positionFieldTemp = body.positionField;
    profileEmp.posTypeIdTemp = String(body.posTypeId);
    profileEmp.posTypeNameTemp = body.posTypeName;
    profileEmp.posLevelIdTemp = String(body.posLevelId);
    profileEmp.posLevelNameTemp = body.posLevelName;
    profileEmp.statusTemp = "PENDING";
    this.profileRepo.merge(profileEmp, body);
    await this.profileRepo.save(profileEmp);
    return new HttpSuccess();
  }

  /**
   * API เช็คเลขบัตร
   *
   * @summary เช็คเลขบัตร  (ADMIN)
   *
   * @param {string} id  Id ทะเบียนประวัติ
   */
  @Put("citizenId/{id}")
  async checkCitizenIdProfile(
    @Path() id: string,
    @Request() req: RequestWithUser,
    @Body()
    requestBody: { citizenId: string },
  ) {
    const profile = await this.profileRepo.findOne({
      where: { id: Not(id), citizenId: requestBody.citizenId },
    });
    if (profile) {
      throw new HttpError(
        HttpStatus.INTERNAL_SERVER_ERROR,
        "เลขประจำตัวประชาชนนี้มีอยู่ในระบบแล้ว",
      );
    }
    return new HttpSuccess();
  }

  /**
   * API ค้นหาข้อมูลทะเบียนประวัติ ทดลองปฏิบัติหน้าที่ราชการ
   *
   * @summary ค้นหาข้อมูลทะเบียนประวัติ ทดลองปฏิบัติหน้าที่ราชการ (ADMIN)
   *
   */
  @Post("probation")
  async getProfileBySearchKeywordProbation(
    @Request() request: RequestWithUser,
    @Body()
    body: {
      page: number;
      pageSize: number;
      keyword?: string;
    },
  ) {
    let _data: any = {
      root: null,
      child1: null,
      child2: null,
      child3: null,
      child4: null,
    };
    if (!request.user.role.includes("SUPER_ADMIN")) {
      _data = await new permission().PermissionOrgCreate(request, "SYS_PROBATION");
    }
    const [findProfile, total] = await AppDataSource.getRepository(ProfileEmployee)
      .createQueryBuilder("profile")
      .leftJoinAndSelect("profile.posLevel", "posLevel")
      .leftJoinAndSelect("profile.current_holders", "current_holders")
      .leftJoinAndSelect("current_holders.orgRevision", "orgRevision")
      .leftJoinAndSelect("current_holders.orgRoot", "orgRoot")
      .leftJoinAndSelect("current_holders.orgChild1", "orgChild1")
      .leftJoinAndSelect("current_holders.orgChild2", "orgChild2")
      .leftJoinAndSelect("current_holders.orgChild3", "orgChild3")
      .leftJoinAndSelect("current_holders.orgChild4", "orgChild4")
      .andWhere(
        _data.root != undefined && _data.root != null
          ? _data.root[0] != null
            ? `current_holders.orgRootId IN (:...root)`
            : `current_holders.orgRootId is null`
          : "1=1",
        {
          root: _data.root,
        },
      )
      .andWhere(
        _data.child1 != undefined && _data.child1 != null
          ? _data.child1[0] != null
            ? `current_holders.orgChild1Id IN (:...child1)`
            : `current_holders.orgChild1Id is null`
          : "1=1",
        {
          child1: _data.child1,
        },
      )
      .andWhere(
        _data.child2 != undefined && _data.child2 != null
          ? _data.child2[0] != null
            ? `current_holders.orgChild2Id IN (:...child2)`
            : `current_holders.orgChild2Id is null`
          : "1=1",
        {
          child2: _data.child2,
        },
      )
      .andWhere(
        _data.child3 != undefined && _data.child3 != null
          ? _data.child3[0] != null
            ? `current_holders.orgChild3Id IN (:...child3)`
            : `current_holders.orgChild3Id is null`
          : "1=1",
        {
          child3: _data.child3,
        },
      )
      .andWhere(
        _data.child4 != undefined && _data.child4 != null
          ? _data.child4[0] != null
            ? `current_holders.orgChild4Id IN (:...child4)`
            : `current_holders.orgChild4Id is null`
          : "1=1",
        {
          child4: _data.child4,
        },
      )
      .andWhere(
        new Brackets((qb) => {
          qb.orWhere("profile.prefix LIKE :keyword", { keyword: `%${body.keyword}%` })
            .orWhere("profile.firstName LIKE :keyword", { keyword: `%${body.keyword}%` })
            .orWhere("profile.lastName LIKE :keyword", { keyword: `%${body.keyword}%` })
            .orWhere("profile.position LIKE :keyword", { keyword: `%${body.keyword}%` })
            .orWhere("posLevel.posLevelName LIKE :keyword", { keyword: `%${body.keyword}%` });
        }),
      )
      .orderBy("profile.citizenId", "ASC")
      .skip((body.page - 1) * body.pageSize)
      .take(body.pageSize)
      .getManyAndCount();

    const orgRevisionActive = await this.orgRevisionRepo.findOne({
      where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
    });

    const mapDataProfile = await Promise.all(
      findProfile.map(async (item: ProfileEmployee) => {
        return {
          id: item.id,
          rank: item.rank,
          prefix: item.prefix,
          firstName: item.firstName,
          lastName: item.lastName,
          position: item.position,
          idcard: item.citizenId,
          posLevelName: item.posLevel == null ? null : item.posLevel.posLevelName,
          isProbation: item.isProbation,
          orgRootName:
            item.current_holders == null ||
            item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null ||
            item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot ==
              null ||
            item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot
              ?.orgRootName == null
              ? null
              : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgRoot
                  ?.orgRootName,
          orgChild1Name:
            item.current_holders == null ||
            item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null ||
            item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild1 ==
              null ||
            item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild1
              ?.orgChild1Name == null
              ? null
              : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)
                  ?.orgChild1?.orgChild1Name,
          orgChild2Name:
            item.current_holders == null ||
            item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null ||
            item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild2 ==
              null ||
            item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild2
              ?.orgChild2Name == null
              ? null
              : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)
                  ?.orgChild2?.orgChild2Name,
          orgChild3Name:
            item.current_holders == null ||
            item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null ||
            item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild3 ==
              null ||
            item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild3
              ?.orgChild3Name == null
              ? null
              : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)
                  ?.orgChild3?.orgChild3Name,
          orgChild4Name:
            item.current_holders == null ||
            item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id) == null ||
            item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild4 ==
              null ||
            item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)?.orgChild4
              ?.orgChild4Name == null
              ? null
              : item.current_holders.find((x) => x.orgRevisionId == orgRevisionActive?.id)
                  ?.orgChild4?.orgChild4Name,
        };
      }),
    );

    return new HttpSuccess({ data: mapDataProfile, total });
  }

  /**
   * API รายชื่อราชการที่เลื่อนเงินเดือน
   *
   * @summary ORG_072 - รายชื่อราชการที่เลื่อนเงินเดือน #76
   *
   */
  @Post("salary/gen")
  async salaryGen(
    @Body()
    body: {
      page: number;
      pageSize: number;
      keyword?: string;
      rootId?: string;
      year: number;
      period: string;
    },
  ) {
    const findRevision = await this.orgRevisionRepo.findOne({
      where: { orgRevisionIsCurrent: true },
    });
    if (!findRevision) {
      throw new HttpError(HttpStatus.NOT_FOUND, "not found. OrgRevision");
    }

    const [findPosMaster, total] = await AppDataSource.getRepository(EmployeePosMaster)
      .createQueryBuilder("employeePosMaster")
      .leftJoinAndSelect("employeePosMaster.current_holder", "current_holder")
      .leftJoinAndSelect("employeePosMaster.orgRoot", "orgRoot")
      .leftJoinAndSelect("employeePosMaster.orgChild1", "orgChild1")
      .leftJoinAndSelect("employeePosMaster.orgChild2", "orgChild2")
      .leftJoinAndSelect("employeePosMaster.orgChild3", "orgChild3")
      .leftJoinAndSelect("employeePosMaster.orgChild4", "orgChild4")
      .leftJoinAndSelect("employeePosMaster.positions", "positions")
      .leftJoinAndSelect("current_holder.profileSalary", "profileSalary")
      .leftJoinAndSelect("current_holder.profileDisciplines", "profileDisciplines")
      .leftJoinAndSelect("current_holder.posLevel", "posLevel")
      .leftJoinAndSelect("current_holder.posType", "posType")
      .where((qb) => {
        if (body.rootId) {
          qb.andWhere("employeePosMaster.orgRootId = :rootId", { rootId: body.rootId });
        }
        qb.andWhere("employeePosMaster.current_holderId IS NOT NULL");
        qb.andWhere("employeePosMaster.orgRevisionId = :orgRevisionId", {
          orgRevisionId: findRevision?.id,
        });
      })
      .andWhere(
        new Brackets((qb) => {
          qb.where(
            body.keyword != null && body.keyword != ""
              ? "current_holder.prefix LIKE :keyword"
              : "1=1",
            {
              keyword: `%${body.keyword}%`,
            },
          )
            .orWhere(
              body.keyword != null && body.keyword != ""
                ? "current_holder.firstName LIKE :keyword"
                : "1=1",
              {
                keyword: `%${body.keyword}%`,
              },
            )
            .orWhere(
              body.keyword != null && body.keyword != ""
                ? "current_holder.lastName LIKE :keyword"
                : "1=1",
              {
                keyword: `%${body.keyword}%`,
              },
            )
            .orWhere(
              body.keyword != null && body.keyword != ""
                ? "current_holder.position LIKE :keyword"
                : "1=1",
              {
                keyword: `%${body.keyword}%`,
              },
            )

            .orWhere(
              body.keyword != null && body.keyword != ""
                ? "current_holder.citizenId LIKE :keyword"
                : "1=1",
              {
                keyword: `%${body.keyword}%`,
              },
            )
            .orWhere(
              body.keyword != null && body.keyword != ""
                ? "posType.posTypeName LIKE :keyword"
                : "1=1",
              {
                keyword: `%${body.keyword}%`,
              },
            )
            .orWhere(
              body.keyword != null && body.keyword != ""
                ? "posLevel.posLevelName LIKE :keyword"
                : "1=1",
              {
                keyword: `%${body.keyword}%`,
              },
            );
        }),
      )
      .orderBy("current_holder.citizenId", "ASC")
      .skip((body.page - 1) * body.pageSize)
      .take(body.pageSize)
      .getManyAndCount();
    if (!findPosMaster) {
      throw new HttpError(HttpStatus.NOT_FOUND, "not found. PosMaster");
    }

    const formattedData = findPosMaster.map((item) => {
      let orgShortName = "";

      if (item.orgChild1Id === null) {
        orgShortName = item.orgRoot?.orgRootShortName;
      } else if (item.orgChild2Id === null) {
        orgShortName = item.orgChild1?.orgChild1ShortName;
      } else if (item.orgChild3Id === null) {
        orgShortName = item.orgChild2?.orgChild2ShortName;
      } else if (item.orgChild4Id === null) {
        orgShortName = item.orgChild3?.orgChild3ShortName;
      } else {
        orgShortName = item.orgChild4?.orgChild4ShortName;
      }

      const amount =
        item.current_holder == null || item.current_holder.profileSalary.length == 0
          ? null
          : item.current_holder.profileSalary.sort((a: any, b: any) => b.date - a.date)[0].amount;
      let datePeriodStart = new Date(
        `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, "0")}-${String(new Date().getDate() + 1).padStart(2, "0")}T00:00:00.000Z`,
      );
      let datePeriodEnd = new Date(
        `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, "0")}-${String(new Date().getDate() + 1).padStart(2, "0")}T00:00:00.000Z`,
      );
      if (body.period.toLocaleUpperCase() == "APR") {
        datePeriodStart = new Date(`${body.year}-03-31T00:00:00.000Z`);
        datePeriodEnd = new Date(`${body.year}-03-31T00:00:00.000Z`);
      }
      if (body.period.toLocaleUpperCase() == "OCT") {
        datePeriodStart = new Date(`${body.year}-09-30T00:00:00.000Z`);
        datePeriodEnd = new Date(`${body.year}-09-30T00:00:00.000Z`);
      }
      datePeriodStart = new Date(
        new Date(datePeriodStart.setDate(datePeriodStart.getDate() + 1)).setMonth(
          datePeriodStart.getMonth() - 6,
        ),
      );
      //   const specialPosition = item.positions.find(
      //     (position) => position.positionIsSelected === true,
      //   );
      //   const isSpecial = specialPosition ? specialPosition.isSpecial : null;

      return {
        profileId: item.current_holder.id,
        salaryLevel: item.current_holder.salaryLevel,
        group: item.current_holder.group,
        rank: item.current_holder.rank,
        prefix: item.current_holder.prefix,
        firstName: item.current_holder.firstName,
        lastName: item.current_holder.lastName,
        citizenId: item.current_holder.citizenId,
        posMasterNoPrefix: item.posMasterNoPrefix,
        posMasterNo: item.posMasterNo,
        posMasterNoSuffix: item.posMasterNoSuffix,
        orgShortName: orgShortName,
        position: item.current_holder.position,
        posType:
          item.current_holder.posType == null ? null : item.current_holder.posType.posTypeName,
        posTypeShort:
          item.current_holder.posType == null ? null : item.current_holder.posType.posTypeShortName,
        posLevel:
          item.current_holder.posLevel == null ? null : item.current_holder.posLevel.posLevelName,
        amount: amount ? amount : null,
        rootId: item.orgRootId,
        root: item.orgRoot?.orgRootName ? item.orgRoot.orgRootName : null,
        child1Id: item.orgChild1Id,
        child1: item.orgChild1?.orgChild1Name ? item.orgChild1.orgChild1Name : null,
        child2Id: item.orgChild2Id,
        child2: item.orgChild2?.orgChild2Name ? item.orgChild2.orgChild2Name : null,
        child3Id: item.orgChild3Id,
        child3: item.orgChild3?.orgChild3Name ? item.orgChild3.orgChild3Name : null,
        child4Id: item.orgChild4Id,
        child4: item.orgChild4?.orgChild4Name ? item.orgChild4.orgChild4Name : null,
        result: null,
        duration: null,
        isPunish:
          item.current_holder.profileDisciplines.filter(
            (x: any) =>
              new Date(
                `${new Date(x.date).getFullYear()}-${String(new Date(x.date).getMonth() + 1).padStart(2, "0")}-${String(new Date(x.date).getDate() + 1).padStart(2, "0")}T00:00:00.000Z`,
              ) >= datePeriodStart &&
              new Date(
                `${new Date(x.date).getFullYear()}-${String(new Date(x.date).getMonth() + 1).padStart(2, "0")}-${String(new Date(x.date).getDate() + 1).padStart(2, "0")}T00:00:00.000Z`,
              ) <= datePeriodEnd,
          ).length > 0
            ? true
            : false,
        isSuspension: item.current_holder.dateRetire == null ? false : true,
        isAbsent: false,
        isLeave: false,
        isRetired:
          item.current_holder.birthDate == null ||
          calculateRetireDate(item.current_holder.birthDate).getFullYear() != body.year
            ? false
            : true,
        isSpecial: false,
      };
    });

    return new HttpSuccess({ data: formattedData, total: total });
  }

  /**
   * API ข้อมูลทะเบียนประวัติตาม keycloak by revisionId
   *
   * @summary ข้อมูลทะเบียนประวัติตาม keycloak by revisionId (ADMIN)
   *
   */
  @Get("keycloak/position/{revisionId}")
  async getProfileByKeycloakByRevision(
    @Path() revisionId: string,
    @Request() request: { user: Record<string, any> },
  ) {
    const profile = await this.profileRepo.findOne({
      where: { keycloak: request.user.sub },
      relations: [
        "posLevel",
        "posType",
        "current_holders",
        "current_holders.orgRoot",
        "current_holders.orgChild1",
        "current_holders.orgChild2",
        "current_holders.orgChild3",
        "current_holders.orgChild4",
      ],
    });
    if (!profile) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ");
    }
    const _profile = {
      profileId: profile.id,
      rank: profile.rank,
      prefix: profile.prefix,
      firstName: profile.firstName,
      lastName: profile.lastName,
      citizenId: profile.citizenId,
      position: profile.position,
      posLevelName: profile.posLevel == null ? null : profile.posLevel.posLevelName,
      posLevelRank: profile.posLevel == null ? null : profile.posLevel.posLevelRank,
      posLevelId: profile.posLevel == null ? null : profile.posLevel.id,
      posTypeName: profile.posType == null ? null : profile.posType.posTypeName,
      posTypeRank: profile.posType == null ? null : profile.posType.posTypeRank,
      posTypeId: profile.posType == null ? null : profile.posType.id,
      rootId:
        profile.current_holders == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot == null
          ? null
          : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRootId,
      root:
        profile.current_holders == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot == null
          ? null
          : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgRoot.orgRootName,
      child1Id:
        profile.current_holders == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1 == null
          ? null
          : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1Id,
      child1:
        profile.current_holders == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1 == null
          ? null
          : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild1
              .orgChild1Name,
      child2Id:
        profile.current_holders == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2 == null
          ? null
          : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2Id,
      child2:
        profile.current_holders == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2 == null
          ? null
          : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild2
              .orgChild2Name,
      child3Id:
        profile.current_holders == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3 == null
          ? null
          : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3Id,
      child3:
        profile.current_holders == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3 == null
          ? null
          : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild3
              .orgChild3Name,
      child4Id:
        profile.current_holders == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4 == null
          ? null
          : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4Id,
      child4:
        profile.current_holders == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId) == null ||
        profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4 == null
          ? null
          : profile.current_holders.find((x) => x.orgRevisionId == revisionId)?.orgChild4
              .orgChild4Name,
    };
    return new HttpSuccess(_profile);
  }

  /**
   * API ข้อมูลบุลคลที่มีอายุเกษียณราชการตามปี
   *
   * @summary ข้อมูลบุลคลที่มีอายุเกษียณราชการตามปี
   *
   */
  @Get("profileid/retire/{year}")
  async getProfileByRetireYear(@Path() year: number, @Request() req: RequestWithUser) {
    // await new permission().PermissionOrgUserList(req, "SYS_REGISTRY_EMP", id);//ไม่แน่ใจEMPปิดไว้ก่อน
    const profiles = await this.profileRepo
      .createQueryBuilder("profileEmployee")
      .leftJoinAndSelect("profileEmployee.posLevel", "posLevel")
      .leftJoinAndSelect("profileEmployee.posType", "posType")
      .leftJoinAndSelect("profileEmployee.current_holders", "current_holders")
      .leftJoinAndSelect("current_holders.orgRoot", "orgRoot")
      .leftJoinAndSelect("current_holders.orgChild1", "orgChild1")
      .leftJoinAndSelect("current_holders.orgChild2", "orgChild2")
      .leftJoinAndSelect("current_holders.orgChild3", "orgChild3")
      .leftJoinAndSelect("current_holders.orgChild4", "orgChild4")
      .leftJoinAndSelect("current_holders.positions", "positions")
      // .leftJoinAndSelect("positions.posExecutive", "posExecutive")
      .where("YEAR(profileEmployee.dateRetire) = :year", { year })
      .getMany();

    if (!profiles || profiles.length === 0) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลที่มีอายุเกษียณราชการในปีนี้");
    }

    const findRevision = await this.orgRevisionRepo.findOne({
      where: { orgRevisionIsCurrent: true },
    });
    if (!findRevision) {
      throw new HttpError(HttpStatus.NOT_FOUND, "not found. OrgRevision");
    }
    const formattedData = profiles.map((item) => {
      const posMaster =
        item.current_holders == null ||
        item.current_holders.length == 0 ||
        item.current_holders.find((x) => x.orgRevisionId == findRevision.id) == null
          ? null
          : item.current_holders.find((x) => x.orgRevisionId == findRevision.id);
      // const posExecutive =
      //   position == null ||
      //   item.current_holders
      //     .find((x) => x.orgRevisionId == findRevision.id)
      //     ?.positions?.find((position) => position.positionIsSelected == true)?.posExecutive ==
      //     null ||
      //   item.current_holders
      //     .find((x) => x.orgRevisionId == findRevision.id)
      //     ?.positions?.find((position) => position.positionIsSelected == true)?.posExecutive
      //     ?.posExecutiveName == null
      //     ? null
      //     : item.current_holders
      //         .find((x) => x.orgRevisionId == findRevision.id)
      //         ?.positions?.find((position) => position.positionIsSelected == true)?.posExecutive
      //         .posExecutiveName;
      // const posExecutiveId =
      //   position == null || position.posExecutive == null ? null : position.posExecutive.id;

      const shortName =
        item.current_holders.length == 0
          ? null
          : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
              item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 !=
                null
            ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4.orgChild4ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
            : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
                item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3 !=
                  null
              ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3.orgChild3ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
              : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
                  item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2 !=
                    null
                ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2.orgChild2ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
                : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
                    item.current_holders.find((x) => x.orgRevisionId == findRevision.id)
                      ?.orgChild1 != null
                  ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1.orgChild1ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
                  : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
                      item.current_holders.find((x) => x.orgRevisionId == findRevision.id)
                        ?.orgRoot != null
                    ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot.orgRootShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
                    : null;
      const root =
        item.current_holders == null ||
        item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null
          ? null
          : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot;
      const child1 =
        item.current_holders == null ||
        item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1 == null
          ? null
          : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1;
      const child2 =
        item.current_holders == null ||
        item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2 == null
          ? null
          : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2;
      const child3 =
        item.current_holders == null ||
        item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3 == null
          ? null
          : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3;
      const child4 =
        item.current_holders == null ||
        item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 == null
          ? null
          : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4;

      let node = null;
      let nodeId = null;
      let nodeShortName = null;

      if (root) {
        node = 0;
        nodeId = root.id;
        nodeShortName = root.orgRootShortName;
      }
      if (child1) {
        node = 1;
        nodeId = child1.id;
        nodeShortName = child1.orgChild1ShortName;
      }
      if (child2) {
        node = 2;
        nodeId = child2.id;
        nodeShortName = child2.orgChild2ShortName;
      }
      if (child3) {
        node = 3;
        nodeId = child3.id;
        nodeShortName = child3.orgChild3ShortName;
      }
      if (child4) {
        node = 4;
        nodeId = child4.id;
        nodeShortName = child4.orgChild4ShortName;
      }

      return {
        profileId: item.id,
        prefix: item.prefix,
        rank: item.rank,
        firstName: item.firstName,
        lastName: item.lastName,
        citizenId: item.citizenId,
        root: root == null ? null : root.orgRootName,
        rootId: root == null ? null : root.id,
        rootShortName: root == null ? null : root.orgRootShortName,
        child1: child1 == null ? null : child1.orgChild1Name,
        child1Id: child1 == null ? null : child1.id,
        child1ShortName: child1 == null ? null : child1.orgChild1ShortName,
        child2: child2 == null ? null : child2.orgChild2Name,
        child2Id: child2 == null ? null : child2.id,
        child2ShortName: child2 == null ? null : child2.orgChild2ShortName,
        child3: child3 == null ? null : child3.orgChild3Name,
        child3Id: child3 == null ? null : child3.id,
        child3ShortName: child3 == null ? null : child3.orgChild3ShortName,
        child4: child4 == null ? null : child4.orgChild4Name,
        child4Id: child4 == null ? null : child4.id,
        child4ShortName: child4 == null ? null : child4.orgChild4ShortName,
        dateRetire: item.dateRetire,
        posLevelId: item.posLevel == null ? null : item.posLevel.id,
        posLevelName: item.posLevel == null ? null : item.posLevel.posLevelName,
        posLevelRank: item.posLevel == null ? null : item.posLevel.posLevelRank,
        posTypeId: item.posType == null ? null : item.posType.id,
        posTypeName: item.posType == null ? null : item.posType.posTypeName,
        posTypeRank: item.posType == null ? null : item.posType.posTypeRank,
        posNo: shortName,
        posMasterNo: posMaster == null ? null : posMaster.posMasterNo,
        position: item.position,
        // posExecutiveId: posExecutiveId,
        // posExecutiveName: posExecutive,
        node: node,
        nodeId: nodeId,
        nodeShortName: nodeShortName,
      };
    });
    return new HttpSuccess(formattedData);
  }

  /**
   * API อัพเดทเกษียณ
   *
   * @summary อัพเดทเกษียณ  (ADMIN)
   *
   * @param {string} id  Id ทะเบียนประวัติ
   */
  @Post("leave/{id}")
  async updateLeaveUser(
    @Path() id: string,
    @Body()
    requestBody: { isLeave: boolean; leaveReason: string; dateLeave: Date },
    @Request() request: RequestWithUser,
  ) {
    const profile = await this.profileRepo.findOne({
      where: { id: id },
    });
    if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");

    profile.isLeave = requestBody.isLeave;
    profile.leaveReason = requestBody.leaveReason;
    profile.dateLeave = requestBody.dateLeave;
    if (requestBody.isLeave == true) {
      await removeProfileInOrganize(profile.id, "EMPLOYEE");
    }
    await this.profileRepo.save(profile);

    return new HttpSuccess();
  }

  /**
   * API แก้ไขข้อมูลลูกจ้างชั่วคราว
   *
   * @summary แก้ไขข้อมูลลูกจ้างชั่วคราว (ADMIN)
   *
   * @param {string} profileEmployeeId  profileEmployeeId ทะเบียนประวัติลูกจ้างชั่วคราว
   */
  @Put("information/{profileEmployeeId}")
  async ProfileEmployeeInformation(
    @Request() request: RequestWithUser,
    @Path() profileEmployeeId: string,
    @Body() body: UpdateInformationProfileEmployee,
  ) {
    await new permission().PermissionOrgUserUpdate(request, "SYS_REGISTRY_EMP", profileEmployeeId);
    const profileEmp = await this.profileRepo.findOneBy({ id: profileEmployeeId });
    if (!profileEmp) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลโปรไฟล์นี้");

    const history = new ProfileEmployeeInformationHistory();
    Object.assign(profileEmp, body);
    Object.assign(history, { ...profileEmp, id: undefined });
    history.profileEmployeeId = profileEmployeeId;
    history.lastUpdateFullName = request.user.name;
    history.lastUpdateUserId = request.user.sub;
    history.lastUpdatedAt = new Date();
    history.createdUserId = request.user.sub;
    history.createdFullName = request.user.name;
    history.createdAt = new Date();
    profileEmp.lastUpdateUserId = request.user.sub;
    profileEmp.lastUpdateFullName = request.user.name;
    profileEmp.lastUpdatedAt = new Date();

    await Promise.all([
      this.profileRepo.save(profileEmp),
      this.informationHistoryRepository.save(history),
    ]);
    return new HttpSuccess();
  }

  /**
   * API ข้อมูลลูกจ้างชั่วคราว
   *
   * @summary ข้อมูลลูกจ้างชั่วคราว (ADMIN)
   *
   * @param {string} profileEmployeeId profileEmployeeId ทะเบียนประวัติลูกจ้างชั่วคราว
   */
  @Get("information/{profileEmployeeId}")
  async getInformationById(@Path() profileEmployeeId: string, @Request() req: RequestWithUser) {
    let _workflow = await new permission().Workflow(req, profileEmployeeId, "SYS_REGISTRY_EMP");
    if (_workflow == false)
      await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_EMP", profileEmployeeId);
    const profileInformation = await this.profileRepo.findOne({
      where: { id: profileEmployeeId },
    });
    if (!profileInformation) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");

    const mapData = {
      id: profileInformation.id,
      positionEmployeeGroupId: profileInformation.positionEmployeeGroupId,
      positionEmployeeLineId: profileInformation.positionEmployeeLineId,
      positionEmployeePositionId: profileInformation.positionEmployeePositionId,
      employeeOc: profileInformation.employeeOc,
      employeeTypeIndividual: profileInformation.employeeTypeIndividual,
      employeeWage: profileInformation.employeeWage,
      employeeMoneyIncrease: profileInformation.employeeMoneyIncrease,
      employeeMoneyAllowance: profileInformation.employeeMoneyAllowance,
      employeeMoneyEmployee: profileInformation.employeeMoneyEmployee,
      employeeMoneyEmployer: profileInformation.employeeMoneyEmployer,
    };
    return new HttpSuccess(mapData);
  }

  /**
   * API ประวัติการแก้ไขข้อมูลลูกจ้างชั่วคราว
   *
   * @summary ประวัติการแก้ไขข้อมูลลูกจ้างชั่วคราว (ADMIN)
   *
   * @param {string} profileEmployeeId profileEmployeeId ทะเบียนประวัติลูกจ้างชั่วคราว
   */
  @Get("information/history/{profileEmployeeId}")
  async getInformationHistory(@Path() profileEmployeeId: string, @Request() req: RequestWithUser) {
    let _workflow = await new permission().Workflow(req, profileEmployeeId, "SYS_REGISTRY_EMP");
    if (_workflow == false)
      await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_EMP", profileEmployeeId);
    const profileInformation = await this.informationHistoryRepository.find({
      where: { profileEmployeeId: profileEmployeeId },
      order: {
        createdAt: "DESC",
      },
    });
    return new HttpSuccess(profileInformation);
  }

  /**
   * API รายการข้อมูลการจ้าง
   *
   * @summary รายการข้อมูลการจ้าง
   *
   * @param {string} profileEmployeeId profileEmployeeId ทะเบียนประวัติลูกจ้างชั่วคราว
   */
  @Get("employment/{profileEmployeeId}")
  async ProfileEmployeeEmployment(
    @Path() profileEmployeeId: string,
    @Request() req: RequestWithUser,
  ) {
    let _workflow = await new permission().Workflow(req, profileEmployeeId, "SYS_REGISTRY_EMP");
    if (_workflow == false)
      await new permission().PermissionOrgUserGet(req, "SYS_REGISTRY_EMP", profileEmployeeId);
    const employment = await this.employmentRepository.find({
      where: { profileEmployeeId: profileEmployeeId },
      order: { createdAt: "ASC" },
    });
    const mapData = employment.map((employment) => ({
      id: employment.id,
      date: employment.date,
      command: employment.command,
    }));
    return new HttpSuccess(mapData);
  }

  /**
   * API รายละเอียดข้อมูลการจ้าง
   *
   * @summary รายละเอียดข้อมูลการจ้าง
   *
   * @param {string} id Id ข้อมูลการจ้าง
   */
  @Get("employment/id/{id}")
  async GetEmploymentById(@Path() id: string, @Request() req: RequestWithUser) {
    const employment = await this.employmentRepository.findOne({
      where: { id: id },
    });
    if (employment) {
      let _workflow = await new permission().Workflow(req, id, "SYS_REGISTRY_EMP");
      if (_workflow == false)
        await new permission().PermissionOrgUserGet(
          req,
          "SYS_REGISTRY_EMP",
          employment.profileEmployeeId,
        );
    }
    return new HttpSuccess(employment);
  }

  /**
   * API ประวัติของข้อมูลการจ้าง
   *
   * @summary ประวัติของข้อมูลการจ้าง
   *
   * @param {string} id Id ข้อมูลการจ้าง
   */
  @Get("employment/history/{id}")
  async GetHistoryEmploymentById(@Path() id: string, @Request() req: RequestWithUser) {
    const employment = await this.employmentRepository.findOne({
      where: { id: id },
    });
    if (employment) {
      let _workflow = await new permission().Workflow(req, id, "SYS_REGISTRY_EMP");
      if (_workflow == false)
        await new permission().PermissionOrgUserGet(
          req,
          "SYS_REGISTRY_EMP",
          employment.profileEmployeeId,
        );
    }
    const employmentHistory = await this.employmentHistoryRepository.find({
      where: { profileEmployeeEmploymentId: id },
      order: { lastUpdatedAt: "ASC" },
    });
    return new HttpSuccess(employmentHistory);
  }

  /**
   * API เพิ่มข้อมูลการจ้าง
   *
   * @summary เพิ่มข้อมูลการจ้าง
   *
   * @param {string} profileEmployeeId  profileEmployeeId ทะเบียนประวัติลูกจ้างชั่วคราว
   */
  @Post("employment/{profileEmployeeId}")
  async CreateEmployment(
    @Path() profileEmployeeId: string,
    @Body() body: CreateEmploymentProfileEmployee,
    @Request() request: RequestWithUser,
  ) {
    const profile = await this.profileRepo.findOne({
      where: { id: profileEmployeeId },
    });
    if (!profile) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");
    await new permission().PermissionOrgUserUpdate(request, "SYS_REGISTRY_EMP", profile.id);

    const data = new ProfileEmployeeEmployment();

    const meta = {
      createdUserId: request.user.sub,
      createdFullName: request.user.name,
      lastUpdateUserId: request.user.sub,
      lastUpdateFullName: request.user.name,
      createdAt: new Date(),
      lastUpdatedAt: new Date(),
      profileEmployeeId: profileEmployeeId,
    };

    Object.assign(data, { ...body, ...meta });
    const history = new ProfileEmployeeEmploymentHistory();
    Object.assign(history, { ...data, id: undefined });

    await this.employmentRepository.save(data);
    history.profileEmployeeEmploymentId = data.id;
    await this.employmentHistoryRepository.save(history);

    return new HttpSuccess();
  }

  /**
   * API ลบข้อมูลการจ้าง
   *
   * @summary ลบข้อมูลการจ้าง  (ADMIN)
   *
   * @param {string} id  Id ข้อมูลการจ้าง
   */
  @Delete("employment/{id}")
  async DeleteEmployment(@Path() id: string, @Request() request: RequestWithUser) {
    const employment = await this.employmentRepository.findOne({
      where: { id: id },
    });
    if (employment) {
      await new permission().PermissionOrgUserDelete(
        request,
        "SYS_REGISTRY_EMP",
        employment.profileEmployeeId,
      );
    }
    await this.employmentHistoryRepository.delete({
      profileEmployeeEmploymentId: id,
    });

    const result = await this.employmentRepository.delete({ id });
    if (result.affected == undefined || result.affected <= 0) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");
    }
    return new HttpSuccess();
  }

  /**
   * API แก้ไขข้อมูลการจ้าง
   *
   * @summary แก้ไขข้อมูลการจ้าง (ADMIN)
   *
   * @param {string} id  Id ข้อมูลการจ้าง
   */
  @Put("employment/{id}")
  async UpdateEmployment(
    @Request() request: RequestWithUser,
    @Path() id: string,
    @Body() body: UpdateEmploymentProfileEmployee,
  ) {
    const employment = await this.employmentRepository.findOneBy({ id });
    if (!employment) throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล");
    await new permission().PermissionOrgUserUpdate(
      request,
      "SYS_REGISTRY_EMP",
      employment.profileEmployeeId,
    );

    const history = new ProfileEmployeeEmploymentHistory();
    Object.assign(employment, body);
    Object.assign(history, { ...employment, id: undefined });

    employment.lastUpdateUserId = request.user.sub;
    employment.lastUpdateFullName = request.user.name;
    employment.lastUpdatedAt = new Date();
    history.profileEmployeeEmploymentId = id;
    history.lastUpdateUserId = request.user.sub;
    history.lastUpdateFullName = request.user.name;
    history.createdUserId = request.user.sub;
    history.createdFullName = request.user.name;
    history.createdAt = new Date();
    history.lastUpdatedAt = new Date();

    await Promise.all([
      this.employmentRepository.save(employment),
      this.employmentHistoryRepository.save(history),
    ]);

    return new HttpSuccess();
  }

  /**
   * API ออกคำสั่งลูกจ้าง
   *
   * @summary ORG_038 - ออกคำสั่งลูกจ้าง (ADMIN) #
   *
   */
  @Post("report")
  async sendReport(@Request() request: RequestWithUser, @Body() requestBody: { id: string[] }) {
    const profiles = await this.profileRepo.find({ where: { id: In(requestBody.id) } });

    const _profiles = await Promise.all(
      profiles.map(async (item: any) => {
        return {
          ...item,
          statusTemp: "REPORT",
          lastUpdateUserId: request.user.sub,
          lastUpdateFullName: request.user.name,
          lastUpdatedAt: new Date(),
        };
      }),
    );
    await this.profileRepo.save(_profiles);
    return new HttpSuccess();
  }

  /**
   * API ออกคำสั่งลูกจ้าง
   *
   * @summary ORG_038 - ออกคำสั่งลูกจ้าง (ADMIN) #
   *
   */
  @Post("report/resume")
  async doneReport(
    @Body()
    body: {
      result: {
        id: string;
        templateDoc: string;
        amount: Double | null;
        positionSalaryAmount: Double | null;
        mouthSalaryAmount: Double | null;
        refCommandNo: string;
      }[];
    },
    @Request() request: { user: Record<string, any> },
  ) {
    await Promise.all(
      body.result.map(async (v) => {
        const profile = await this.profileRepo.findOne({
          where: {
            id: v.id,
          },
          relations: ["posType", "posLevel"],
        });
        if (profile != null) {
          await new CallAPI()
            .PostData(request, "/org/profile-employee/salary", {
              profileEmployeeId: profile.id,
              date: new Date(),
              amount: v.amount,
              positionSalaryAmount: v.positionSalaryAmount,
              mouthSalaryAmount: v.mouthSalaryAmount,
              posNo: profile.posMasterNoTemp,
              position: profile.positionTemp,
              positionType: profile.posTypeNameTemp,
              positionLevel: profile.posLevelNameTemp,
              refCommandNo: v.refCommandNo,
              templateDoc: v.templateDoc,
            })
            .then(async () => {
              profile.statusTemp = "DONE";
              profile.employeeClass = "PERM";
              const _null: any = null;
              profile.employeeWage = v.amount == null ? _null : v.amount.toString();
              await this.profileRepo.save(profile);
            });
          await new CallAPI()
            .PostData(request, "/org/employee/pos/report/current", {
              posmasterId: profile.posmasterIdTemp,
              positionId: profile.positionIdTemp,
              profileId: profile.id,
            })
            .then(async () => {});
        }
      }),
    );
    return new HttpSuccess();
  }

  /**
   * API ค้นหาข้อมูลทะเบียนประวัติที่ยังไม่เชื่อม keycloak
   *
   * @summary ค้นหาข้อมูลทะเบียนประวัติที่ยังไม่เชื่อม keycloak
   *
   */
  @Post("search-personal-no-keycloak")
  async getProfileBySearchKeywordNoKeyCloak(
    @Query("page") page: number = 1,
    @Query("pageSize") pageSize: number = 10,
    @Body()
    body: {
      fieldName: string;
      keyword?: string;
    },
  ) {
    let findProfile: any;
    let total: any;
    const skip = (page - 1) * pageSize;
    const take = pageSize;
    switch (body.fieldName) {
      case "citizenId":
        [findProfile, total] = await this.profileRepo.findAndCount({
          where: {
            keycloak: IsNull(),
            citizenId: Like(`%${body.keyword}%`),
          },
          relations: ["posType", "posLevel", "current_holders", "profileSalary"],
          skip,
          take,
        });
        break;

      case "firstname":
        [findProfile, total] = await this.profileRepo.findAndCount({
          where: {
            keycloak: IsNull(),
            firstName: Like(`%${body.keyword}%`),
          },
          relations: ["posType", "posLevel", "current_holders", "profileSalary"],
          skip,
          take,
        });
        break;

      case "lastname":
        [findProfile, total] = await this.profileRepo.findAndCount({
          where: {
            keycloak: IsNull(),
            lastName: Like(`%${body.keyword}%`),
          },
          relations: ["posType", "posLevel", "current_holders", "profileSalary"],
          skip,
          take,
        });
        break;

      default:
        [findProfile, total] = await this.profileRepo.findAndCount({
          where: {
            keycloak: IsNull(),
          },
          relations: ["posType", "posLevel", "current_holders", "profileSalary"],
          skip,
          take,
        });
        break;
    }

    const findRevision = await this.orgRevisionRepo.findOne({
      where: { orgRevisionIsCurrent: true },
    });
    if (!findRevision) {
      throw new HttpError(HttpStatus.NOT_FOUND, "not found. OrgRevision");
    }

    const mapDataProfile = await Promise.all(
      findProfile.map(async (item: ProfileEmployee) => {
        const fullName = `${item.prefix} ${item.firstName} ${item.lastName}`;
        const shortName =
          item.current_holders.length == 0
            ? null
            : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
                item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4 !=
                  null
              ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild4.orgChild4ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
              : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
                  item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3 !=
                    null
                ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild3.orgChild3ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
                : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
                    item.current_holders.find((x) => x.orgRevisionId == findRevision.id)
                      ?.orgChild2 != null
                  ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild2.orgChild2ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
                  : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
                      item.current_holders.find((x) => x.orgRevisionId == findRevision.id)
                        ?.orgChild1 != null
                    ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgChild1.orgChild1ShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
                    : item.current_holders.find((x) => x.orgRevisionId == findRevision.id) !=
                          null &&
                        item.current_holders.find((x) => x.orgRevisionId == findRevision.id)
                          ?.orgRoot != null
                      ? `${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot.orgRootShortName}${item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.posMasterNo}`
                      : null;

        const root =
          item.current_holders.length == 0 ||
          (item.current_holders.find((x) => x.orgRevisionId == findRevision.id) != null &&
            item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot == null)
            ? null
            : item.current_holders.find((x) => x.orgRevisionId == findRevision.id)?.orgRoot;

        let salary: any = "";
        if (item != null && item.profileSalary != null && item.profileSalary.length > 0) {
          let _salary: any = item.profileSalary.sort(
            (a, b) =>
              (b.date == null ? 0 : b.date.getTime()) - (a.date == null ? 0 : a.date.getTime()),
          );
          if (_salary.length > 0) {
            salary = _salary[0];
          }
        }

        const posMasterNo = item.current_holders?.find(
          (x) => x.orgRevisionId == findRevision.id,
        )?.posMasterNo;

        const latestProfileEducation = await this.profileEducationRepository.findOne({
          where: { profileEmployeeId: item.id },
          order: { endDate: "DESC" },
        });

        return {
          id: item.id,
          prefix: item.prefix,
          rank: item.rank,
          firstName: item.firstName,
          lastName: item.lastName,
          position: item.position,
          citizenId: item.citizenId,
          email: item.email,
          phone: item.phone,
          name: fullName,
          birthDate: item.birthDate,
          positionLevel: item.posLevelId,
          positionLevelName: item.posLevel?.posLevelName,
          positionType: item.posTypeId,
          positionTypeName: item.posType?.posTypeName,
          posNo: shortName,
          organization: root == null ? null : root.orgRootShortName,
          salary: salary == "" ? "" : salary.amount,
          posMasterNo: posMasterNo ?? null,
          posTypeId: item.posTypeId,
          posTypeName: item.posType?.posTypeName,
          posLevelId: item.posLevelId,
          posLevelName: item.posLevel?.posLevelName,
          educationDegree:
            latestProfileEducation != null && latestProfileEducation.educationLevel != null
              ? latestProfileEducation.educationLevel
              : null,
        };
      }),
    );

    return new HttpSuccess({ data: mapDataProfile, total });
  }
  /**
   * API ข้อมูลทะเบียนประวัติตาม profileid
   *
   * @summary ORG_065 - ข้อมูลทะเบียนประวัติตาม profileid (ADMIN) #70
   *
   */
  @Get("profileid/position/{id}")
  async getProfileByProfileid(@Request() request: RequestWithUser, @Path() id: string) {
    const profile = await this.profileRepo.findOne({
      where: { id: id },
      relations: [
        "posLevel",
        "posType",
        "current_holders",
        "current_holders.orgRoot",
        "current_holders.orgChild1",
        "current_holders.orgChild2",
        "current_holders.orgChild3",
        "current_holders.orgChild4",
        "profileSalary",
        "profileEducations",
      ],
      order: {
        // profileSalary: {
        //   order: "DESC",
        // },
        profileEducations: {
          createdAt: "DESC",
        },
      },
    });
    if (!profile) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ");
    }
    //await new permission().PermissionOrgUserGet(request, "SYS_REGISTRY_EMP", profile.id); //ไม่แน่ใจEMPปิดไว้ก่อน

    const orgRevisionPublish = await this.orgRevisionRepo
      .createQueryBuilder("orgRevision")
      .where("orgRevision.orgRevisionIsDraft = false")
      .andWhere("orgRevision.orgRevisionIsCurrent = true")
      .getOne();
    if (!orgRevisionPublish) {
      throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบแบบร่างโครงสร้าง");
    }

    const posMaster =
      profile.current_holders == null ||
      profile.current_holders.length == 0 ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) == null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id);
    const root =
      profile.current_holders == null ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot == null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot;
    const child1 =
      profile.current_holders == null ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1 ==
        null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1;
    const child2 =
      profile.current_holders == null ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2 ==
        null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2;
    const child3 =
      profile.current_holders == null ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3 ==
        null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3;
    const child4 =
      profile.current_holders == null ||
      profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4 ==
        null
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4;
    // const position = await this.positionRepository.findOne({
    //   relations: ["posExecutive"],
    //   where: {
    //     posMasterId: posMaster?.id,
    //   },
    // });
    const shortName =
      profile.current_holders.length == 0
        ? null
        : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != null &&
            profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)
              ?.orgChild4 != null
          ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild4.orgChild4ShortName}${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}`
          : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) != null &&
              profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)
                ?.orgChild3 != null
            ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild3.orgChild3ShortName}${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}`
            : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) !=
                  null &&
                profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)
                  ?.orgChild2 != null
              ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild2.orgChild2ShortName}${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}`
              : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) !=
                    null &&
                  profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)
                    ?.orgChild1 != null
                ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgChild1.orgChild1ShortName}${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}`
                : profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id) !=
                      null &&
                    profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)
                      ?.orgRoot != null
                  ? `${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.orgRoot.orgRootShortName}${profile.current_holders.find((x) => x.orgRevisionId == orgRevisionPublish.id)?.posMasterNo}`
                  : null;
    const _profile: any = {
      profileId: profile.id,
      prefix: profile.prefix,
      rank: profile.rank,
      isProbation: profile.isProbation,
      firstName: profile.firstName,
      lastName: profile.lastName,
      citizenId: profile.citizenId,
      birthDate: profile.birthDate,
      position: profile.position,
      leaveDate: profile.dateLeave,
      posMasterNo: posMaster == null ? null : posMaster.posMasterNo,
      posLevelName: profile.posLevel == null ? null : profile.posLevel.posLevelName,
      posLevelRank: profile.posLevel == null ? null : profile.posLevel.posLevelRank,
      posLevelId: profile.posLevel == null ? null : profile.posLevel.id,
      posTypeName: profile.posType == null ? null : profile.posType.posTypeName,
      posTypeRank: profile.posType == null ? null : profile.posType.posTypeRank,
      posTypeId: profile.posType == null ? null : profile.posType.id,
      // posExecutiveName: "",
      rootId: root == null ? null : root.id,
      root: root == null ? null : root.orgRootName,
      rootShortName: root == null ? null : root.orgRootShortName,
      child1Id: child1 == null ? null : child1.id,
      child1: child1 == null ? null : child1.orgChild1Name,
      child1ShortName: child1 == null ? null : child1.orgChild1ShortName,
      child2Id: child2 == null ? null : child2.id,
      child2: child2 == null ? null : child2.orgChild2Name,
      child2ShortName: child2 == null ? null : child2.orgChild2ShortName,
      child3Id: child3 == null ? null : child3.id,
      child3: child3 == null ? null : child3.orgChild3Name,
      child3ShortName: child3 == null ? null : child3.orgChild3ShortName,
      child4Id: child4 == null ? null : child4.id,
      child4: child4 == null ? null : child4.orgChild4Name,
      child4ShortName: child4 == null ? null : child4.orgChild4ShortName,
      node: null,
      nodeId: null,
      posNo: shortName,
      salary: profile && profile.profileSalary.length > 0 ? profile.profileSalary[0].amount : null,
      education:
        profile && profile.profileEducations.length > 0
          ? `${profile.profileEducations[0].degree ?? ""}/${profile.profileEducations[0].field ?? ""}`
          : "-",
    };

    if (_profile.child4Id != null) {
      _profile.node = 4;
      _profile.nodeId = _profile.child4Id;
      _profile.nodeShortName = _profile.child4ShortName;
    } else if (_profile.child3Id != null) {
      _profile.node = 3;
      _profile.nodeId = _profile.child3Id;
      _profile.nodeShortName = _profile.child3ShortName;
    } else if (_profile.child2Id != null) {
      _profile.node = 2;
      _profile.nodeId = _profile.child2Id;
      _profile.nodeShortName = _profile.child2ShortName;
    } else if (_profile.child1Id != null) {
      _profile.node = 1;
      _profile.nodeId = _profile.child1Id;
      _profile.nodeShortName = _profile.child1ShortName;
    } else if (_profile.rootId != null) {
      _profile.node = 0;
      _profile.nodeId = _profile.rootId;
      _profile.nodeShortName = _profile.rootShortName;
    }
    return new HttpSuccess(_profile);
  }
}
