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 */ export async function reOrderCommandRecivesAndDelete( reciveId: string, manager?: EntityManager, ): Promise { 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 ข้อมูลชื่อหน่วยงานและชื่อย่อ */ export async function getPosNumCodeSit( commandId: string, status?: string ): Promise { 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 */ export async function ensureCommandOperator( userProfile: Profile | null, commandId: string, request: RequestWithUser, now: Date, manager?: EntityManager, ): Promise { 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); }