hrms-api-org/src/services/CommandService.ts
2026-07-02 14:46:57 +07:00

247 lines
9.2 KiB
TypeScript

import { AppDataSource } from "../database/data-source";
import { CommandRecive } from "../entities/CommandRecive";
import { Command } from "../entities/Command";
import { CommandOperator } from "../entities/CommandOperator";
import { OrgRoot } from "../entities/OrgRoot";
import { Position } from "../entities/Position";
import { Profile } from "../entities/Profile";
import { RequestWithUser } from "../middlewares/user";
import { EntityManager } from "typeorm";
export interface PosNumCodeSitResult {
posNumCodeSit: string;
posNumCodeSitAbb: string;
commandTypeName: string;
commandNo: string;
commandYear: number;
commandExcecuteDate: Date;
}
/**
* เรียงลำดับผู้ได้รับคำสั่งใหม่หลังจากลบรายการ และอัพเดทสถานะคำสั่งถ้าไม่มีผู้ได้รับคำสั่งเหลือ
* @param reciveId commandRecive.Id ของผู้ได้รับคำสั่ง
* @param code ประเภทคำสั่ง
* @param manager ถ้าส่งเข้ามา → ทุก operation อยู่ใน transaction ของ caller (all-or-nothing)
* @returns Promise<void>
*/
export async function reOrderCommandRecivesAndDelete(
reciveId: string,
manager?: EntityManager,
): Promise<void> {
const ds = manager ?? AppDataSource;
const commandReciveRepo = ds.getRepository(CommandRecive);
const commandRepo = ds.getRepository(Command);
// ค้นหาข้อมูลผู้ได้รับคำสั่งตาม reciveId
const commandRecive = await commandReciveRepo.findOne({
where: { id: reciveId },
});
if (commandRecive == null) return;
const commandId = commandRecive.commandId;
// ลบตาม refId
await commandReciveRepo.delete(commandRecive.id);
const commandReciveList = await commandReciveRepo.find({
where: { commandId: commandId },
order: { order: "ASC" },
});
// ลำดับผู้ได้รับคำสั่งใหม่
if (commandReciveList.length > 0) {
for (let i = 0; i < commandReciveList.length; i++) {
commandReciveList[i].order = i + 1;
await commandReciveRepo.save(commandReciveList[i]);
}
} else {
// ถ้าไม่มีผู้ได้รับคำสั่งเหลือเลย ให้ยกเลิกคำสั่ง
await commandRepo.update({ id: commandId }, { status: "CANCEL" });
}
}
/**
* ดึงข้อมูล posNumCodeSit และ posNumCodeSitAbb จาก commandId
* @param commandId ID ของคำสั่ง
* @param status สถานะของคำสั่ง (ไม่บังคับส่ง)
* @returns Promise<PosNumCodeSitResult> ข้อมูลชื่อหน่วยงานและชื่อย่อ
*/
export async function getPosNumCodeSit(
commandId: string,
status?: string
): Promise<PosNumCodeSitResult> {
const commandRepo = AppDataSource.getRepository(Command);
const orgRootRepo = AppDataSource.getRepository(OrgRoot);
const profileRepo = AppDataSource.getRepository(Profile);
let posNumCodeSit:string = "";
let posNumCodeSitAbb:string = "";
let commandTypeName:string = "";
let commandNo:string = "";
let commandYear:number = 0;
let commandExcecuteDate:Date = new Date;
let _command: Command | null;
if (!status) {
_command = await commandRepo.findOne({
where: { id: commandId },
relations: { commandType: true }
});
}
else {
_command = await commandRepo.findOne({
where: { id: commandId, status: status },
relations: { commandType: true }
});
}
if (_command) {
if (_command?.isBangkok?.toLocaleUpperCase() == "OFFICE") {
const orgRootDeputy = await orgRootRepo.findOne({
where: {
isDeputy: true,
orgRevision: {
orgRevisionIsCurrent: true,
orgRevisionIsDraft: false,
},
},
relations: ["orgRevision"],
});
posNumCodeSit = orgRootDeputy ? orgRootDeputy?.orgRootName : "สำนักปลัดกรุงเทพมหานคร";
posNumCodeSitAbb = orgRootDeputy ? orgRootDeputy?.orgRootShortName : "สนป.";
} else if (_command?.isBangkok?.toLocaleUpperCase() == "BANGKOK") {
posNumCodeSit = "กรุงเทพมหานคร";
posNumCodeSitAbb = "กทม.";
} else {
let _profileAdmin = await profileRepo.findOne({
where: {
keycloak: _command?.createdUserId.toString(),
current_holders: {
orgRevision: {
orgRevisionIsCurrent: true,
orgRevisionIsDraft: false,
},
},
},
relations: ["current_holders", "current_holders.orgRevision", "current_holders.orgRoot"],
});
posNumCodeSit =
_profileAdmin?.current_holders.find((x) => x.orgRoot.orgRootName)?.orgRoot.orgRootName ??
"";
posNumCodeSitAbb =
_profileAdmin?.current_holders.find((x) => x.orgRoot.orgRootShortName)?.orgRoot
.orgRootShortName ?? "";
}
commandTypeName = _command?.commandType?.name ?? "";
commandNo = _command?.commandNo ?? "";
commandYear = _command?.commandYear;
commandExcecuteDate = _command?.commandExcecuteDate;
}
return {
posNumCodeSit,
posNumCodeSitAbb,
commandTypeName,
commandNo,
commandYear,
commandExcecuteDate,
};
}
/**
* สร้าง/insert CommandOperator "เจ้าหน้าที่ดำเนินการ" สำหรับ command
* ใช้ userProfile ที่ query ไปแล้วถ้ามี ถ้าไม่มีค่อย query ใหม่
* @param userProfile profile ที่ query ไปแล้ว (หรือ null ถ้ายังไม่ได้ query)
* @param commandId command id ที่จะผูกกับ operator
* @param request request context (สำหรับ user.sub / user.name)
* @param now timestamp สำหรับ audit fields
* @param manager ถ้าส่งเข้ามา → ทุก operation อยู่ใน transaction ของ caller (all-or-nothing)
* @returns Promise<void>
*/
export async function ensureCommandOperator(
userProfile: Profile | null,
commandId: string,
request: RequestWithUser,
now: Date,
manager?: EntityManager,
): Promise<void> {
const ds = manager ?? AppDataSource;
const profileRepo = ds.getRepository(Profile);
const positionRepo = ds.getRepository(Position);
const commandOperatorRepo = ds.getRepository(CommandOperator);
if (!request.user.sub) return;
// ใช้ userProfile ที่ query ไปแล้วถ้ามี ถ้าไม่มีค่อย query ใหม่
let profile = userProfile;
if (!profile) {
profile = await profileRepo.findOne({
where: { keycloak: request.user.sub },
relations: {
posLevel: true,
posType: true,
current_holders: {
orgRevision: true,
orgRoot: true,
orgChild1: true,
orgChild2: true,
orgChild3: true,
orgChild4: true,
},
},
});
}
if (!profile) return;
const currentHolder = profile.current_holders?.find(
(x) =>
x.orgRevision?.orgRevisionIsDraft === false &&
x.orgRevision?.orgRevisionIsCurrent === true,
);
const posNo =
currentHolder != null && currentHolder.orgChild4 != null
? `${currentHolder.orgChild4.orgChild4ShortName} ${currentHolder.posMasterNo}`
: currentHolder != null && currentHolder.orgChild3 != null
? `${currentHolder.orgChild3.orgChild3ShortName} ${currentHolder.posMasterNo}`
: currentHolder != null && currentHolder.orgChild2 != null
? `${currentHolder.orgChild2.orgChild2ShortName} ${currentHolder.posMasterNo}`
: currentHolder != null && currentHolder.orgChild1 != null
? `${currentHolder.orgChild1.orgChild1ShortName} ${currentHolder.posMasterNo}`
: currentHolder != null && currentHolder?.orgRoot != null
? `${currentHolder.orgRoot.orgRootShortName} ${currentHolder.posMasterNo}`
: null;
const position = await positionRepo.findOne({
where: {
positionIsSelected: true,
posMaster: {
orgRevisionId: currentHolder?.orgRevisionId,
current_holderId: profile.id,
},
},
order: { createdAt: "DESC" },
relations: { posExecutive: true },
});
const operator = Object.assign(new CommandOperator(), {
profileId: profile?.id,
prefix: profile?.prefix,
firstName: profile?.firstName,
lastName: profile?.lastName,
posNo: posNo,
posType: profile?.posType?.posTypeName ?? null,
posLevel: profile?.posLevel?.posLevelName ?? null,
position: position?.positionName ?? null,
positionExecutive: position?.posExecutive?.posExecutiveName ?? null,
roleName: "เจ้าหน้าที่ดำเนินการ",
orderNo: 1,
commandId: commandId,
createdUserId: request.user.sub,
createdFullName: request.user.name,
createdAt: now,
lastUpdateUserId: request.user.sub,
lastUpdateFullName: request.user.name,
lastUpdatedAt: now,
});
await commandOperatorRepo.save(operator);
}