hrms-api-org/src/controllers/PosMasterActController.ts

881 lines
36 KiB
TypeScript
Raw Normal View History

2024-06-19 23:03:54 +07:00
import {
Controller,
Get,
Post,
Delete,
Route,
Security,
Tags,
Body,
Path,
Request,
Response,
} from "tsoa";
import { AppDataSource } from "../database/data-source";
import HttpSuccess from "../interfaces/http-success";
import HttpStatusCode from "../interfaces/http-status";
import HttpError from "../interfaces/http-error";
import { PosMasterAct } from "../entities/PosMasterAct";
import { PosMaster } from "../entities/PosMaster";
2026-02-13 09:29:31 +07:00
import { Brackets, In, IsNull, LessThan, MoreThan, Not } from "typeorm";
import permission from "../interfaces/permission";
import { OrgRevision } from "../entities/OrgRevision";
import Extension from "../interfaces/extension";
2026-02-02 16:18:32 +07:00
import { ProfileActposition } from "../entities/ProfileActposition";
2026-02-13 09:29:31 +07:00
import { RequestWithUser } from "../middlewares/user";
import { escape } from "querystring";
import { promisify } from "util";
const REDIS_HOST = process.env.REDIS_HOST;
const REDIS_PORT = process.env.REDIS_PORT;
2024-06-19 23:03:54 +07:00
@Route("api/v1/org/pos/act")
@Tags("PosMasterAct")
@Security("bearerAuth")
@Response(
HttpStatusCode.INTERNAL_SERVER_ERROR,
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง",
)
export class PosMasterActController extends Controller {
private orgRevisionRepository = AppDataSource.getRepository(OrgRevision);
2024-06-19 23:03:54 +07:00
private posMasterActRepository = AppDataSource.getRepository(PosMasterAct);
private posMasterRepository = AppDataSource.getRepository(PosMaster);
2026-02-02 16:18:32 +07:00
private actpositionRepository = AppDataSource.getRepository(ProfileActposition);
private redis = require("redis");
2024-06-19 23:03:54 +07:00
/**
* API
*
* @summary (ADMIN)
*
*/
@Post()
async createPosMasterAct(
@Body() requestBody: { posMasterId: string; posMasterChildId: string },
@Request() request: { user: Record<string, any> },
) {
const posMaster = await this.posMasterRepository.findOne({
where: {
id: requestBody.posMasterId,
},
});
if (posMaster == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้");
}
const posMasterChild = await this.posMasterRepository.findOne({
where: {
id: requestBody.posMasterChildId,
},
});
if (posMasterChild == null) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้");
}
const posMasterActOld = await this.posMasterActRepository.findOne({
where: {
posMasterId: requestBody.posMasterId,
},
order: { posMasterOrder: "DESC" },
});
let num = 0;
if (posMasterActOld != null) {
num = posMasterActOld.posMasterOrder;
}
const posMasterAct = new PosMasterAct();
posMasterAct.posMasterOrder = num + 1;
posMasterAct.posMasterId = requestBody.posMasterId;
posMasterAct.posMasterChildId = requestBody.posMasterChildId;
posMasterAct.createdUserId = request.user.sub;
posMasterAct.createdFullName = request.user.name;
posMasterAct.lastUpdateUserId = request.user.sub;
posMasterAct.lastUpdateFullName = request.user.name;
posMasterAct.createdAt = new Date();
posMasterAct.lastUpdatedAt = new Date();
2024-06-19 23:03:54 +07:00
await this.posMasterActRepository.save(posMasterAct);
return new HttpSuccess(posMasterAct);
}
2026-02-13 09:29:31 +07:00
/**
* API .
*
* @summary .
*
*/
@Post("search")
async searchAct(
@Request() request: RequestWithUser,
@Body()
body: {
posmasterId: string;
isAll: boolean;
isAllRoot?: boolean;
page?: number;
pageSize?: number;
2026-02-18 14:53:50 +07:00
keyword?: string;
2026-02-13 09:29:31 +07:00
},
) {
await new permission().PermissionGet(request, "SYS_ACTING");
2026-02-18 14:53:50 +07:00
const { page = 1, pageSize = 100, keyword } = body;
2026-02-13 09:29:31 +07:00
const posMasterMain = await this.posMasterRepository.findOne({
where: { id: body.posmasterId },
relations: ["posMasterActs"],
});
2026-02-18 14:53:50 +07:00
if (!posMasterMain) {
2026-02-13 09:29:31 +07:00
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้");
}
2026-02-18 14:53:50 +07:00
let posId: any[] = posMasterMain.posMasterActs.map((x) => x.posMasterChildId);
2026-02-13 09:29:31 +07:00
posId.push(body.posmasterId);
2026-02-18 14:53:50 +07:00
const query = await AppDataSource.getRepository(PosMaster)
.createQueryBuilder("posMaster")
.leftJoinAndSelect("posMaster.orgRoot", "orgRoot")
.leftJoinAndSelect("posMaster.orgChild1", "orgChild1")
.leftJoinAndSelect("posMaster.orgChild2", "orgChild2")
.leftJoinAndSelect("posMaster.orgChild3", "orgChild3")
.leftJoinAndSelect("posMaster.orgChild4", "orgChild4")
.leftJoinAndSelect("posMaster.current_holder", "current_holder")
.leftJoinAndSelect("current_holder.posLevel", "posLevel")
.leftJoinAndSelect("current_holder.posType", "posType")
.where("posMaster.current_holderId IS NOT NULL")
.andWhere("posMaster.id NOT IN (:...posId)", { posId });
2026-02-13 09:29:31 +07:00
if (!body.isAllRoot) {
2026-02-18 14:53:50 +07:00
if (body.isAll) {
if (posMasterMain.orgChild4Id) {
query.andWhere("posMaster.orgChild4Id = :id", {
id: posMasterMain.orgChild4Id,
});
} else if (posMasterMain.orgChild3Id) {
query.andWhere("posMaster.orgChild3Id = :id", {
id: posMasterMain.orgChild3Id,
});
} else if (posMasterMain.orgChild2Id) {
query.andWhere("posMaster.orgChild2Id = :id", {
id: posMasterMain.orgChild2Id,
});
} else if (posMasterMain.orgChild1Id) {
query.andWhere("posMaster.orgChild1Id = :id", {
id: posMasterMain.orgChild1Id,
});
} else {
query.andWhere("posMaster.orgRootId = :id", {
id: posMasterMain.orgRootId,
});
}
2026-02-13 09:29:31 +07:00
} else {
2026-02-18 14:53:50 +07:00
query
.andWhere(
posMasterMain.orgRootId == null
? "posMaster.orgRootId IS NULL"
: "posMaster.orgRootId = :orgRootId",
{ orgRootId: posMasterMain.orgRootId },
2026-02-18 14:53:50 +07:00
)
.andWhere(
posMasterMain.orgChild1Id == null
? "posMaster.orgChild1Id IS NULL"
: "posMaster.orgChild1Id = :orgChild1Id",
{ orgChild1Id: posMasterMain.orgChild1Id },
2026-02-18 14:53:50 +07:00
)
.andWhere(
posMasterMain.orgChild2Id == null
? "posMaster.orgChild2Id IS NULL"
: "posMaster.orgChild2Id = :orgChild2Id",
{ orgChild2Id: posMasterMain.orgChild2Id },
2026-02-18 14:53:50 +07:00
)
.andWhere(
posMasterMain.orgChild3Id == null
? "posMaster.orgChild3Id IS NULL"
: "posMaster.orgChild3Id = :orgChild3Id",
{ orgChild3Id: posMasterMain.orgChild3Id },
2026-02-18 14:53:50 +07:00
)
.andWhere(
posMasterMain.orgChild4Id == null
? "posMaster.orgChild4Id IS NULL"
: "posMaster.orgChild4Id = :orgChild4Id",
{ orgChild4Id: posMasterMain.orgChild4Id },
2026-02-18 14:53:50 +07:00
);
2026-02-13 09:29:31 +07:00
}
} else {
2026-02-18 14:53:50 +07:00
query.andWhere("posMaster.orgRootId = :orgRootId", {
2026-02-13 09:29:31 +07:00
orgRootId: posMasterMain.orgRootId,
2026-02-18 14:53:50 +07:00
});
2026-02-13 09:29:31 +07:00
}
2026-02-18 14:53:50 +07:00
if (keyword) {
query.andWhere(
new Brackets((qb) => {
qb.where(
`CONCAT(current_holder.prefix, current_holder.firstName, ' ', current_holder.lastName) LIKE :keyword`,
{ keyword: `%${keyword}%` },
2026-02-18 14:53:50 +07:00
)
.orWhere(`current_holder.citizenId LIKE :keyword`, {
keyword: `%${keyword}%`,
})
.orWhere(
`CONCAT(
CASE
WHEN orgChild4.id IS NOT NULL THEN orgChild4.orgChild4ShortName
WHEN orgChild3.id IS NOT NULL THEN orgChild3.orgChild3ShortName
WHEN orgChild2.id IS NOT NULL THEN orgChild2.orgChild2ShortName
WHEN orgChild1.id IS NOT NULL THEN orgChild1.orgChild1ShortName
WHEN orgRoot.id IS NOT NULL THEN orgRoot.orgRootShortName
ELSE ''
END,
' ',
posMaster.posMasterNo
) LIKE :keyword`,
{ keyword: `%${keyword}%` },
2026-02-18 14:53:50 +07:00
)
.orWhere(`posLevel.posLevelName LIKE :keyword`, {
keyword: `%${keyword}%`,
})
.orWhere(`posType.posTypeName LIKE :keyword`, {
keyword: `%${keyword}%`,
})
.orWhere(`current_holder.position LIKE :keyword`, {
keyword: `%${keyword}%`,
});
}),
2026-02-18 14:53:50 +07:00
);
}
query.skip((page - 1) * pageSize).take(pageSize);
const [posMaster, total] = await query.getManyAndCount();
2026-02-13 09:29:31 +07:00
const data = await Promise.all(
posMaster
.sort((a, b) => a.posMasterOrder - b.posMasterOrder)
.map((item) => {
const shortName =
item.orgChild4 != null
? `${item.orgChild4.orgChild4ShortName} ${item.posMasterNo}`
: item?.orgChild3 != null
? `${item.orgChild3.orgChild3ShortName} ${item.posMasterNo}`
: item?.orgChild2 != null
? `${item.orgChild2.orgChild2ShortName} ${item.posMasterNo}`
: item?.orgChild1 != null
? `${item.orgChild1.orgChild1ShortName} ${item.posMasterNo}`
: item?.orgRoot != null
? `${item.orgRoot.orgRootShortName} ${item.posMasterNo}`
: null;
return {
id: item.id,
citizenId: item.current_holder?.citizenId ?? null,
isDirector: item.isDirector ?? null,
prefix: item.current_holder?.prefix ?? null,
firstName: item.current_holder?.firstName ?? null,
lastName: item.current_holder?.lastName ?? null,
posLevel: item.current_holder?.posLevel?.posLevelName ?? null,
posType: item.current_holder?.posType?.posTypeName ?? null,
position: item.current_holder?.position ?? null,
posNo: shortName,
};
}),
);
return new HttpSuccess({ data: data, total });
}
2024-06-19 23:03:54 +07:00
/**
* API
*
* @summary (ADMIN)
*
* @param {string} id Id
*/
@Delete("{id}")
async deletePosMasterAct(@Path() id: string) {
let result: any;
const posMasterAct = await this.posMasterActRepository.findOne({
where: {
id: id,
},
2026-05-12 15:14:21 +07:00
relations: ["posMasterChild", "posMasterChild.current_holder"],
2024-06-19 23:03:54 +07:00
});
try {
result = await this.posMasterActRepository.delete({ id: id });
} catch {
throw new HttpError(
HttpStatusCode.NOT_FOUND,
"ไม่สามารถลบได้เนื่องจากมีการใช้งานระดับตำแหน่งนี้อยู่",
);
}
if (result.affected == undefined || result.affected <= 0) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล");
}
if (posMasterAct != null) {
const posMasterActList = await this.posMasterActRepository.find({
where: {
posMasterId: posMasterAct.posMasterId,
},
});
2024-09-25 16:17:06 +07:00
posMasterActList.forEach(async (p, i) => {
p.posMasterOrder = i + 1;
2024-06-19 23:03:54 +07:00
await this.posMasterActRepository.save(p);
});
}
2026-05-12 15:14:21 +07:00
// ลบ Redis cache ของคนที่เป็น acting
if (posMasterAct != null && posMasterAct.posMasterChild?.current_holderId) {
const profileId = posMasterAct.posMasterChild.current_holderId;
const redisClient = await this.redis.createClient({
host: REDIS_HOST,
port: REDIS_PORT,
});
const delAsync = promisify(redisClient.del).bind(redisClient);
await delAsync("role_" + profileId);
await delAsync("menu_" + profileId);
redisClient.quit();
}
2024-06-19 23:03:54 +07:00
return new HttpSuccess();
}
/**
* API
*
* @summary (ADMIN)
*
*/
@Get("swap/{direction}/{posMasterActId}")
async swapPosMasterAct(
@Path() direction: string,
posMasterActId: string,
@Request() request: { user: Record<string, any> },
) {
const source_item = await this.posMasterActRepository.findOne({
where: {
id: posMasterActId,
},
});
if (source_item == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งนี้");
const sourceOrder = source_item.posMasterOrder;
if (direction.trim().toUpperCase() == "UP") {
const dest_item = await this.posMasterActRepository.findOne({
where: { posMasterId: source_item.posMasterId, posMasterOrder: LessThan(sourceOrder) },
order: { posMasterOrder: "DESC" },
});
if (dest_item == null) return new HttpSuccess();
var destOrder = dest_item.posMasterOrder;
dest_item.posMasterOrder = sourceOrder;
source_item.posMasterOrder = destOrder;
await Promise.all([
this.posMasterActRepository.save(source_item),
this.posMasterActRepository.save(dest_item),
]);
} else {
const dest_item = await this.posMasterActRepository.findOne({
where: { posMasterId: source_item.posMasterId, posMasterOrder: MoreThan(sourceOrder) },
order: { posMasterOrder: "ASC" },
});
if (dest_item == null) return new HttpSuccess();
var destOrder = dest_item.posMasterOrder;
dest_item.posMasterOrder = sourceOrder;
source_item.posMasterOrder = destOrder;
await Promise.all([
this.posMasterActRepository.save(source_item),
this.posMasterActRepository.save(dest_item),
]);
}
return new HttpSuccess();
}
/**
* API
*
* @summary (ADMIN)
*
* @param {string} id Id
*/
@Get("profile")
async GetPosMasterActProfile() {
const orgRevisionActive = await this.orgRevisionRepository.findOne({
where: { orgRevisionIsCurrent: true, orgRevisionIsDraft: false },
});
if (!orgRevisionActive) {
return new HttpSuccess();
}
const posMasterActs = await this.posMasterActRepository.find({
relations: [
"posMaster",
"posMasterChild",
"posMasterChild.orgRoot",
"posMasterChild.orgChild1",
"posMasterChild.orgChild2",
"posMasterChild.orgChild3",
"posMasterChild.orgChild4",
"posMasterChild.current_holder",
"posMasterChild.current_holder.posLevel",
"posMasterChild.current_holder.posType",
],
where: {
posMaster: {
orgRevisionId: orgRevisionActive.id,
},
},
});
if (!posMasterActs) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้");
}
const data = await Promise.all(
posMasterActs
.sort((a, b) => a.posMaster.posMasterOrder - b.posMaster.posMasterOrder)
.map((item) => {
const shortName =
item.posMasterChild != null && item.posMasterChild.orgChild4 != null
2025-04-05 19:21:50 +07:00
? `${item.posMasterChild.orgChild4.orgChild4ShortName} ${item.posMasterChild.posMasterNo}`
: item.posMasterChild != null && item.posMasterChild?.orgChild3 != null
2025-04-05 19:21:50 +07:00
? `${item.posMasterChild.orgChild3.orgChild3ShortName} ${item.posMasterChild.posMasterNo}`
: item.posMasterChild != null && item.posMasterChild?.orgChild2 != null
2025-04-05 19:21:50 +07:00
? `${item.posMasterChild.orgChild2.orgChild2ShortName} ${item.posMasterChild.posMasterNo}`
: item.posMasterChild != null && item.posMasterChild?.orgChild1 != null
2025-04-05 19:21:50 +07:00
? `${item.posMasterChild.orgChild1.orgChild1ShortName} ${item.posMasterChild.posMasterNo}`
: item.posMasterChild != null && item.posMasterChild?.orgRoot != null
2025-04-05 19:21:50 +07:00
? `${item.posMasterChild.orgRoot.orgRootShortName} ${item.posMasterChild.posMasterNo}`
: null;
return {
id: item.id,
posMasterOrder: item.posMasterOrder,
profileId: item.posMasterChild?.current_holder?.id ?? null,
citizenId: item.posMasterChild?.current_holder?.citizenId ?? null,
prefix: item.posMasterChild?.current_holder?.prefix ?? null,
firstName: item.posMasterChild?.current_holder?.firstName ?? null,
lastName: item.posMasterChild?.current_holder?.lastName ?? null,
posLevel: item.posMasterChild?.current_holder?.posLevel?.posLevelName ?? null,
posType: item.posMasterChild?.current_holder?.posType?.posTypeName ?? null,
position: item.posMasterChild?.current_holder?.position ?? null,
posNo: shortName,
};
}),
);
return new HttpSuccess(data);
}
/**
* API
*
* @summary (ADMIN)
*
* @param {string} id Id
*/
@Get("{posMasterActId}/{profileId}")
async GetPosMasterActProfileReport(
@Path() posMasterActId: string,
2024-10-04 22:36:34 +07:00
profileId: string,
@Request() request: { user: Record<string, any> },
) {
const posMasterAct = await this.posMasterActRepository.findOne({
relations: [
"posMaster",
"posMaster",
"posMaster.orgRoot",
"posMaster.orgChild1",
"posMaster.orgChild2",
"posMaster.orgChild3",
"posMaster.orgChild4",
"posMaster.current_holder",
"posMasterChild",
"posMasterChild.orgRoot",
"posMasterChild.orgChild1",
"posMasterChild.orgChild2",
"posMasterChild.orgChild3",
"posMasterChild.orgChild4",
"posMasterChild.current_holder",
"posMasterChild.current_holder.posLevel",
"posMasterChild.current_holder.posType",
],
where: {
id: posMasterActId,
},
});
if (!posMasterAct) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้");
}
const organization = [
posMasterAct.posMasterChild?.current_holder?.position ?? null,
posMasterAct.posMasterChild?.orgChild4?.orgChild4Name ?? null,
posMasterAct.posMasterChild?.orgChild3?.orgChild3Name ?? null,
posMasterAct.posMasterChild?.orgChild2?.orgChild2Name ?? null,
posMasterAct.posMasterChild?.orgChild1?.orgChild1Name ?? null,
posMasterAct.posMasterChild?.orgRoot?.orgRootName ?? null,
];
const _organization = organization
.filter((part) => part !== undefined && part !== null)
2025-01-21 10:45:14 +07:00
.join(" ");
const organizationNew = [
posMasterAct.posMaster?.current_holder?.position ?? null,
posMasterAct.posMaster?.orgChild4?.orgChild4Name ?? null,
posMasterAct.posMaster?.orgChild3?.orgChild3Name ?? null,
posMasterAct.posMaster?.orgChild2?.orgChild2Name ?? null,
posMasterAct.posMaster?.orgChild1?.orgChild1Name ?? null,
posMasterAct.posMaster?.orgRoot?.orgRootName ?? null,
];
const _organizationNew = organizationNew
.filter((part) => part !== undefined && part !== null)
2025-01-21 10:45:14 +07:00
.join(" ");
return new HttpSuccess({
prefix: posMasterAct.posMasterChild?.current_holder?.prefix ?? null,
firstName: posMasterAct.posMasterChild?.current_holder?.firstName ?? null,
lastName: posMasterAct.posMasterChild?.current_holder?.lastName ?? null,
organization: _organization, //
position: posMasterAct.posMasterChild?.current_holder?.position ?? null,
postype: posMasterAct.posMasterChild?.current_holder?.posType?.posTypeName ?? null,
poslevel: posMasterAct.posMasterChild?.current_holder?.posLevel?.posLevelName ?? null,
organizationNew: _organizationNew,
date: Extension.ToThaiShortDate_noPrefix(new Date()),
order:
posMasterAct.posMasterOrder == null
? "-"
: "ลำดับที่ " + Extension.ToThaiNumber(posMasterAct.posMasterOrder.toString()),
});
}
2024-06-19 23:03:54 +07:00
/**
* API
*
* @summary (ADMIN)
*
* @param {string} id Id
*/
@Get("{id}")
async GetPosMasterActDetail(@Path() id: string) {
const posMaster = await this.posMasterRepository.findOne({
relations: [
"posMasterActs",
"posMasterActs.posMasterChild",
"posMasterActs.posMasterChild.orgRoot",
"posMasterActs.posMasterChild.orgChild1",
"posMasterActs.posMasterChild.orgChild2",
"posMasterActs.posMasterChild.orgChild3",
"posMasterActs.posMasterChild.orgChild4",
"posMasterActs.posMasterChild.current_holder",
"posMasterActs.posMasterChild.current_holder.posLevel",
"posMasterActs.posMasterChild.current_holder.posType",
],
where: { id: id },
});
if (!posMaster) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลประเภทตำแหน่งนี้");
}
const data = await Promise.all(
posMaster.posMasterActs
.sort((a, b) => a.posMasterOrder - b.posMasterOrder)
.map((item) => {
const shortName =
item.posMasterChild != null && item.posMasterChild.orgChild4 != null
2025-04-05 19:21:50 +07:00
? `${item.posMasterChild.orgChild4.orgChild4ShortName} ${item.posMasterChild.posMasterNo}`
2024-06-19 23:03:54 +07:00
: item.posMasterChild != null && item.posMasterChild?.orgChild3 != null
2025-04-05 19:21:50 +07:00
? `${item.posMasterChild.orgChild3.orgChild3ShortName} ${item.posMasterChild.posMasterNo}`
2024-06-19 23:03:54 +07:00
: item.posMasterChild != null && item.posMasterChild?.orgChild2 != null
2025-04-05 19:21:50 +07:00
? `${item.posMasterChild.orgChild2.orgChild2ShortName} ${item.posMasterChild.posMasterNo}`
2024-06-19 23:03:54 +07:00
: item.posMasterChild != null && item.posMasterChild?.orgChild1 != null
2025-04-05 19:21:50 +07:00
? `${item.posMasterChild.orgChild1.orgChild1ShortName} ${item.posMasterChild.posMasterNo}`
2024-06-19 23:03:54 +07:00
: item.posMasterChild != null && item.posMasterChild?.orgRoot != null
2025-04-05 19:21:50 +07:00
? `${item.posMasterChild.orgRoot.orgRootShortName} ${item.posMasterChild.posMasterNo}`
2024-06-19 23:03:54 +07:00
: null;
return {
id: item.id,
posMasterOrder: item.posMasterOrder,
citizenId: item.posMasterChild?.current_holder?.citizenId ?? null,
prefix: item.posMasterChild?.current_holder?.prefix ?? null,
firstName: item.posMasterChild?.current_holder?.firstName ?? null,
lastName: item.posMasterChild?.current_holder?.lastName ?? null,
posLevel: item.posMasterChild?.current_holder?.posLevel?.posLevelName ?? null,
posType: item.posMasterChild?.current_holder?.posType?.posTypeName ?? null,
position: item.posMasterChild?.current_holder?.position ?? null,
posNo: shortName,
2026-02-02 16:30:24 +07:00
statusReport: item.statusReport,
2024-06-19 23:03:54 +07:00
};
}),
);
return new HttpSuccess(data);
}
2024-10-23 00:31:00 +07:00
/**
* API
*
* @summary
*
*/
@Post("report/draft")
async reportDraft(
@Body()
body: {
type: string;
rootId: string;
},
) {
let conditionGroup = "";
if (body.type.trim().toUpperCase() == "GROUP1.1") {
conditionGroup =
2025-05-29 17:49:27 +07:00
"(posTypeAct.posTypeName = 'ทั่วไป' AND posLevelAct.posLevelName = 'ชำนาญงาน') OR (posTypeAct.posTypeName = 'ทั่วไป' AND posLevelAct.posLevelName = 'ปฏิบัติงาน') OR (posTypeAct.posTypeName = 'วิชาการ' AND posLevelAct.posLevelName = 'ปฏิบัติการ') OR (posTypeAct.posTypeName = 'วิชาการ' AND posLevelAct.posLevelName = 'ชำนาญการ')";
2024-10-23 00:31:00 +07:00
} else if (body.type.trim().toUpperCase() == "GROUP1.2") {
conditionGroup =
2025-05-29 17:49:27 +07:00
"(posTypeAct.posTypeName = 'ทั่วไป' AND posLevelAct.posLevelName = 'อาวุโส') OR (posTypeAct.posTypeName = 'วิชาการ' AND posLevelAct.posLevelName = 'ชำนาญการพิเศษ') OR (posTypeAct.posTypeName = 'อำนวยการ' AND posLevelAct.posLevelName = 'ต้น')";
2024-10-23 00:31:00 +07:00
} else if (body.type.trim().toUpperCase() == "GROUP2") {
conditionGroup =
2025-05-29 17:49:27 +07:00
"(posTypeAct.posTypeName = 'ทั่วไป' AND posLevelAct.posLevelName = 'ทักษะพิเศษ') OR (posTypeAct.posTypeName = 'วิชาการ' AND posLevelAct.posLevelName = 'เชี่ยวชาญ') OR (posTypeAct.posTypeName = 'วิชาการ' AND posLevelAct.posLevelName = 'ทรงคุณวุฒิ') OR (posTypeAct.posTypeName = 'อำนวยการ' AND posLevelAct.posLevelName = 'สูง') OR (posTypeAct.posTypeName = 'บริหาร' AND posLevelAct.posLevelName = 'ต้น') OR (posTypeAct.posTypeName = 'บริหาร' AND posLevelAct.posLevelName = 'สูง')";
2024-10-23 00:31:00 +07:00
} else {
throw new HttpError(HttpStatusCode.NOT_FOUND, "กลุ่มเป้าหมายไม่ถูกต้อง");
}
let posMaster = await AppDataSource.getRepository(PosMasterAct)
.createQueryBuilder("posMasterAct")
.leftJoinAndSelect("posMasterAct.posMasterChild", "posMasterChild")
.leftJoinAndSelect("posMasterChild.orgRoot", "orgRoot")
.leftJoinAndSelect("posMasterChild.orgChild1", "orgChild1")
.leftJoinAndSelect("posMasterChild.orgChild2", "orgChild2")
.leftJoinAndSelect("posMasterChild.orgChild3", "orgChild3")
.leftJoinAndSelect("posMasterChild.orgChild4", "orgChild4")
.leftJoinAndSelect("posMasterChild.current_holder", "current_holder")
.leftJoinAndSelect("posMasterChild.positions", "positions")
.leftJoinAndSelect("positions.posType", "posType")
.leftJoinAndSelect("positions.posLevel", "posLevel")
2025-05-29 17:49:27 +07:00
.leftJoinAndSelect("posMasterAct.posMaster", "posMaster")
.leftJoinAndSelect("posMaster.positions", "positionActs")
.leftJoinAndSelect("posMaster.orgRoot", "orgRootAct")
.leftJoinAndSelect("posMaster.orgChild1", "orgChild1Act")
.leftJoinAndSelect("posMaster.orgChild2", "orgChild2Act")
.leftJoinAndSelect("posMaster.orgChild3", "orgChild3Act")
.leftJoinAndSelect("posMaster.orgChild4", "orgChild4Act")
2025-05-29 17:49:27 +07:00
.leftJoinAndSelect("positionActs.posType", "posTypeAct")
.leftJoinAndSelect("positionActs.posLevel", "posLevelAct")
2024-10-23 00:31:00 +07:00
.leftJoinAndSelect("posMasterChild.orgRevision", "orgRevision")
.andWhere("posMasterChild.orgRootId LIKE :orgRootId", {
orgRootId: body.type.trim().toUpperCase() == "GROUP1.1" ? body.rootId : `%%`,
})
.andWhere("posMasterAct.statusReport = :statusReport", { statusReport: "PENDING" })
.andWhere("posMasterChild.current_holderId IS NOT NULL")
.andWhere("orgRevision.orgRevisionIsCurrent = :orgRevisionIsCurrent", {
orgRevisionIsCurrent: true,
})
.andWhere("orgRevision.orgRevisionIsDraft = :orgRevisionIsDraft", {
orgRevisionIsDraft: false,
})
.andWhere("positions.positionIsSelected = :isSelected", { isSelected: true })
// .andWhere("positionActs.positionIsSelected = :isSelected", { isSelected: true })
2024-10-23 00:31:00 +07:00
.andWhere(
new Brackets((qb) => {
qb.andWhere(conditionGroup);
}),
)
2025-05-29 17:49:27 +07:00
.orderBy("posMasterAct.posMasterOrder", "ASC")
2024-10-23 00:31:00 +07:00
.select([
"posMasterAct.id",
"posMasterChild.posMasterNo",
"positions.positionName",
"positions.positionIsSelected",
"posType.posTypeName",
"posLevel.posLevelName",
"orgRoot.orgRootShortName",
"orgChild1.orgChild1ShortName",
"orgChild2.orgChild2ShortName",
"orgChild3.orgChild3ShortName",
"orgChild4.orgChild4ShortName",
"posMaster.posMasterNo",
"orgRootAct.orgRootShortName",
"orgChild1Act.orgChild1ShortName",
"orgChild2Act.orgChild2ShortName",
"orgChild3Act.orgChild3ShortName",
"orgChild4Act.orgChild4ShortName",
2024-10-23 00:31:00 +07:00
"current_holder.prefix",
"current_holder.firstName",
"current_holder.lastName",
"current_holder.id",
"current_holder.citizenId",
])
.getMany();
const _posMaster = posMaster.map((x) => {
const posMasterNo =
[
x.posMasterChild?.orgChild4?.orgChild4ShortName,
x.posMasterChild?.orgChild3?.orgChild3ShortName,
x.posMasterChild?.orgChild2?.orgChild2ShortName,
x.posMasterChild?.orgChild1?.orgChild1ShortName,
x.posMasterChild?.orgRoot?.orgRootShortName,
].find((name) => !!name) && x.posMasterChild?.posMasterNo
? `${[
x.posMasterChild?.orgChild4?.orgChild4ShortName,
x.posMasterChild?.orgChild3?.orgChild3ShortName,
x.posMasterChild?.orgChild2?.orgChild2ShortName,
x.posMasterChild?.orgChild1?.orgChild1ShortName,
x.posMasterChild?.orgRoot?.orgRootShortName,
].find((name) => !!name)} ${x.posMasterChild.posMasterNo}`
: x.posMasterChild?.posMasterNo || null;
const orgShortNameAct =
[
x.posMaster?.orgChild4?.orgChild4ShortName,
x.posMaster?.orgChild3?.orgChild3ShortName,
x.posMaster?.orgChild2?.orgChild2ShortName,
x.posMaster?.orgChild1?.orgChild1ShortName,
x.posMaster?.orgRoot?.orgRootShortName,
].find((name) => !!name) || "";
const posMasterNoAct =
orgShortNameAct && x.posMaster?.posMasterNo
? `${orgShortNameAct} ${x.posMaster.posMasterNo}`
: x.posMaster?.posMasterNo || null;
2024-10-23 00:31:00 +07:00
const position =
x.posMasterChild.positions.filter((x) => x.positionIsSelected == true).length > 0
? x.posMasterChild.positions.filter((x) => x.positionIsSelected == true)[0]
: null;
return {
id: x.id,
posMasterNo: posMasterNo,
posMasterNoAct: posMasterNoAct,
2024-10-23 00:31:00 +07:00
positionName: position?.positionName || null,
posType: position?.posType?.posTypeName || null,
posLevel: position?.posLevel?.posLevelName || null,
profileId: x.posMasterChild?.current_holder?.id || null,
prefix: x.posMasterChild?.current_holder?.prefix || null,
firstName: x.posMasterChild?.current_holder?.firstName || null,
lastName: x.posMasterChild?.current_holder?.lastName || null,
citizenId: x.posMasterChild?.current_holder?.citizenId || null,
};
});
return new HttpSuccess(_posMaster);
}
2026-02-02 16:18:32 +07:00
/**
* API active
* @summary active (SUPER ADMIN)
* @param {string} id Id
*/
@Post("{id}")
async activePosMasterAct(@Path() id: string, @Request() req: { user: Record<string, any> }) {
const posMasterActs = await this.posMasterActRepository
.createQueryBuilder("posMasterAct")
.leftJoinAndSelect("posMasterAct.posMaster", "posMaster")
.leftJoinAndSelect("posMaster.orgRoot", "orgRoot")
.leftJoinAndSelect("posMaster.orgChild1", "orgChild1")
.leftJoinAndSelect("posMaster.orgChild2", "orgChild2")
.leftJoinAndSelect("posMaster.orgChild3", "orgChild3")
.leftJoinAndSelect("posMaster.orgChild4", "orgChild4")
.leftJoinAndSelect("posMaster.current_holder", "current_holder")
.leftJoinAndSelect("posMasterAct.posMasterChild", "posMasterChild")
.where("posMaster.orgRootId = :orgRootId", { orgRootId: id })
.andWhere("posMasterAct.statusReport = :statusReport", { statusReport: "PENDING" })
.select([
"posMasterAct.id",
"posMasterAct.statusReport",
"posMaster.posMasterNo",
"orgRoot.orgRootShortName",
"orgChild1.orgChild1ShortName",
"orgChild2.orgChild2ShortName",
"orgChild3.orgChild3ShortName",
"orgChild4.orgChild4ShortName",
"current_holder.position",
"posMasterChild.current_holderId",
])
.getMany();
if (posMasterActs.length === 0) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลรักษาการในตำแหน่งของหน่วยงานนี้");
}
// เก็บรวบรวม profileIds ทั้งหมดเพื่อ clear cache หลังจากบันทึกเสร็จ
const profileIdsToClearCache = new Set<string>();
2026-02-02 16:18:32 +07:00
await Promise.all(
posMasterActs.map(async (posMasterAct) => {
const orgShortName =
[
posMasterAct.posMaster?.orgChild4?.orgChild4ShortName,
posMasterAct.posMaster?.orgChild3?.orgChild3ShortName,
posMasterAct.posMaster?.orgChild2?.orgChild2ShortName,
posMasterAct.posMaster?.orgChild1?.orgChild1ShortName,
posMasterAct.posMaster?.orgRoot?.orgRootShortName,
].find(Boolean) ?? "";
const profileId = posMasterAct.posMasterChild?.current_holderId;
if (profileId) {
profileIdsToClearCache.add(profileId);
2026-02-02 16:18:32 +07:00
const existingActivePositions = await this.actpositionRepository.find({
select: [
"id",
"status",
"lastUpdateUserId",
"lastUpdateFullName",
"lastUpdatedAt",
"dateEnd",
"isDeleted",
2026-02-02 16:18:32 +07:00
],
2026-02-04 16:32:25 +07:00
where: { profileId, status: true, isDeleted: false },
2026-02-02 16:18:32 +07:00
});
if (existingActivePositions.length > 0) {
await Promise.all(
existingActivePositions.map(async (pos) => {
Object.assign(pos, {
status: false,
lastUpdateUserId: req.user?.sub ?? null,
lastUpdateFullName: req.user?.name ?? null,
lastUpdatedAt: new Date(),
dateEnd: new Date(),
});
await this.actpositionRepository.save(pos);
}),
);
}
}
const dataAct = new ProfileActposition();
Object.assign(dataAct, {
profileId: profileId ?? null,
dateStart: new Date(),
posNo:
orgShortName && posMasterAct.posMaster?.posMasterNo
? `${orgShortName} ${posMasterAct.posMaster.posMasterNo}`
: posMasterAct.posMaster?.posMasterNo ?? "-",
position: posMasterAct.posMaster?.current_holder?.position ?? null,
posNoAbb: orgShortName,
status: true,
createdUserId: req.user?.sub ?? null,
createdFullName: req.user?.name ?? null,
lastUpdateUserId: req.user?.sub ?? null,
lastUpdateFullName: req.user?.name ?? null,
});
await this.actpositionRepository.save(dataAct);
posMasterAct.statusReport = "DONE";
await this.posMasterActRepository.save(posMasterAct);
}),
);
// Clear Redis cache หลังจากบันทึกข้อมูลเสร็จแล้ว
// ทำงานนอก loop เพื่อ clear รอบเดียว ไม่ใช่ทุก iteration
if (profileIdsToClearCache.size > 0) {
await Promise.all(
Array.from(profileIdsToClearCache).map(async (profileId) => {
const redisClient = await this.redis.createClient({
host: REDIS_HOST,
port: REDIS_PORT,
});
const delAsync = promisify(redisClient.del).bind(redisClient);
await delAsync("role_" + profileId);
await delAsync("menu_" + profileId);
redisClient.quit();
}),
);
}
2026-02-02 16:18:32 +07:00
return new HttpSuccess();
}
2024-06-19 23:03:54 +07:00
}