diff --git a/src/controllers/CommandController.ts b/src/controllers/CommandController.ts index 19dd6a3f..b401aa31 100644 --- a/src/controllers/CommandController.ts +++ b/src/controllers/CommandController.ts @@ -100,7 +100,7 @@ import { } from "../services/PositionService"; import { LeaveType } from "../entities/LeaveType"; import { KeycloakAttributeService } from "../services/KeycloakAttributeService"; -import { reOrderCommandRecivesAndDelete } from "../services/CommandService"; +import { reOrderCommandRecivesAndDelete, ensureCommandOperator } from "../services/CommandService"; import { RetirementService } from "../services/RetirementService"; import { ExecuteOfficerProfileService } from "../services/ExecuteOfficerProfileService"; import { ExecuteSalaryService } from "../services/ExecuteSalaryService"; @@ -415,6 +415,7 @@ export class CommandController extends Controller { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ"); } const now = new Date(); + let userProfile: any = null; command.detailHeader = commandType.detailHeader; command.detailBody = commandType.detailBody; command.detailFooter = commandType.detailFooter; @@ -428,78 +429,39 @@ export class CommandController extends Controller { command.lastUpdateUserId = request.user.sub; command.lastUpdateFullName = request.user.name; command.lastUpdatedAt = now; - await this.commandRepository.save(command); - // insert commandOperator - if (request.user.sub) { - const profile = await this.profileRepository.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, - }, + // Query profile ครั้งเดียว ใช้ร่วมกันทั้ง shortName และ CommandOperator + userProfile = await this.profileRepository.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) { - 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; + // เช็คถ้าไม่ใช่ กสจ. ดึง root.shortName มาปั๊ม + if (userProfile) { + const currentHolder = userProfile.current_holders?.find( + (x: any) => + x.orgRevision?.orgRevisionIsDraft === false && + x.orgRevision?.orgRevisionIsCurrent === true, + ); - const position = await this.positionRepository.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: command.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - createdAt: now, - lastUpdateUserId: request.user.sub, - lastUpdateFullName: request.user.name, - lastUpdatedAt: now, - }); - await this.commandOperatorRepository.save(operator); + if (currentHolder && !currentHolder.orgChild1?.isOfficer) { + command.shortName = currentHolder.orgRoot?.orgRootShortName ?? null; } } + + await this.commandRepository.save(command); + // insert commandOperator + await ensureCommandOperator(userProfile, command.id, request, now); return new HttpSuccess(command.id); } @@ -2720,80 +2682,7 @@ export class CommandController extends Controller { where: { commandId: command.id, roleName: "เจ้าหน้าที่ดำเนินการ" }, }); if (!checkCommandOperator) { - if (request.user.sub) { - // ใช้ userProfile ที่ query ไปแล้วถ้ามี ถ้าไม่มีค่อย query ใหม่ - let profile = userProfile; - if (!profile) { - profile = await this.profileRepository.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) { - const currentHolder = profile!.current_holders?.find( - (x: any) => - 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 this.positionRepository.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: command.id, - createdUserId: request.user.sub, - createdFullName: request.user.name, - createdAt: now, - lastUpdateUserId: request.user.sub, - lastUpdateFullName: request.user.name, - lastUpdatedAt: now, - }); - await this.commandOperatorRepository.save(operator); - } - } + await ensureCommandOperator(userProfile, command.id, request, now); } const path = commandTypePath(commandCode); diff --git a/src/services/CommandService.ts b/src/services/CommandService.ts index 87334a4b..0c0d7fe9 100644 --- a/src/services/CommandService.ts +++ b/src/services/CommandService.ts @@ -1,8 +1,11 @@ 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 { @@ -144,3 +147,101 @@ export async function getPosNumCodeSit( 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); +}