migrate add commandOperator.orderNo & api ส่วนเจ้าหน้าที่ดำเนินการที่คำสั่ง #2220
All checks were successful
Build & Deploy on Dev / build (push) Successful in 49s

This commit is contained in:
harid 2026-02-03 12:22:55 +07:00
parent 4ec334f0d4
commit bb18fed9ae
4 changed files with 363 additions and 28 deletions

View file

@ -27,6 +27,7 @@ import { OrgRevision } from "../entities/OrgRevision";
import { CommandSendCC } from "../entities/CommandSendCC";
import { CommandSalary } from "../entities/CommandSalary";
import { CommandRecive } from "../entities/CommandRecive";
import { CommandOperator } from "../entities/CommandOperator";
import HttpStatus from "../interfaces/http-status";
import Extension from "../interfaces/extension";
import { ProfileEmployee } from "../entities/ProfileEmployee";
@ -112,6 +113,7 @@ export class CommandController extends Controller {
private commandSendCCRepository = AppDataSource.getRepository(CommandSendCC);
private commandSalaryRepository = AppDataSource.getRepository(CommandSalary);
private commandReciveRepository = AppDataSource.getRepository(CommandRecive);
private commandOperatorRepository = AppDataSource.getRepository(CommandOperator);
private profileRepository = AppDataSource.getRepository(Profile);
private profileEmployeeRepository = AppDataSource.getRepository(ProfileEmployee);
private orgRevisionRepo = AppDataSource.getRepository(OrgRevision);
@ -2408,6 +2410,7 @@ export class CommandController extends Controller {
},
@Request() request: RequestWithUser,
) {
const now = new Date();
let command = new Command();
let commandCode: string = "";
let _null: any = null;
@ -2466,12 +2469,86 @@ export class CommandController extends Controller {
: _null),
(command.createdUserId = request.user.sub);
command.createdFullName = request.user.name;
command.createdAt = new Date();
command.createdAt = now;
command.lastUpdateUserId = request.user.sub;
command.lastUpdateFullName = request.user.name;
command.lastUpdatedAt = new Date();
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,
},
},
});
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;
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,
createUserId: request.user.sub,
createdFullName: request.user.name,
createdAt: now,
lastUpdateUserId: request.user.sub,
lastUpdateFullName: request.user.name,
lastUpdatedAt: now,
}
);
await this.commandOperatorRepository.save(operator);
}
}
const path = commandTypePath(commandCode);
if (path == null) throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบประเภทคำสั่งนี้ในระบบ");
@ -2537,10 +2614,10 @@ export class CommandController extends Controller {
commandRecive.commandId = command.id;
commandRecive.createdUserId = request.user.sub;
commandRecive.createdFullName = request.user.name;
commandRecive.createdAt = new Date();
commandRecive.createdAt = now;
commandRecive.lastUpdateUserId = request.user.sub;
commandRecive.lastUpdateFullName = request.user.name;
commandRecive.lastUpdatedAt = new Date();
commandRecive.lastUpdatedAt = now;
if (commandCode == "C-PM-40") {
const posMasterAct = await this.posMasterActRepository.findOne({
@ -2635,10 +2712,10 @@ export class CommandController extends Controller {
commandSend.commandId = command.id;
commandSend.createdUserId = request.user.sub;
commandSend.createdFullName = request.user.name;
commandSend.createdAt = new Date();
commandSend.createdAt = now;
commandSend.lastUpdateUserId = request.user.sub;
commandSend.lastUpdateFullName = request.user.name;
commandSend.lastUpdatedAt = new Date();
commandSend.lastUpdatedAt = now;
await this.commandSendRepository.save(commandSend);
if (commandSend && commandSend.id) {
let _ccName = new Array("EMAIL", "INBOX");
@ -2649,10 +2726,10 @@ export class CommandController extends Controller {
name: _ccName[i],
createdUserId: request.user.sub,
createdFullName: request.user.name,
createdAt: new Date(),
createdAt: now,
lastUpdateUserId: request.user.sub,
lastUpdateFullName: request.user.name,
lastUpdatedAt: new Date(),
lastUpdatedAt: now,
});
}
await this.commandSendCCRepository.save(_dataSendCC);
@ -2692,10 +2769,10 @@ export class CommandController extends Controller {
commandSend.commandId = command.id;
commandSend.createdUserId = request.user.sub;
commandSend.createdFullName = request.user.name;
commandSend.createdAt = new Date();
commandSend.createdAt = now;
commandSend.lastUpdateUserId = request.user.sub;
commandSend.lastUpdateFullName = request.user.name;
commandSend.lastUpdatedAt = new Date();
commandSend.lastUpdatedAt = now;
await this.commandSendRepository.save(commandSend);
if (commandSend && commandSend.id) {
let _ccName = new Array("EMAIL", "INBOX");
@ -2706,10 +2783,10 @@ export class CommandController extends Controller {
name: _ccName[i],
createdUserId: request.user.sub,
createdFullName: request.user.name,
createdAt: new Date(),
createdAt: now,
lastUpdateUserId: request.user.sub,
lastUpdateFullName: request.user.name,
lastUpdatedAt: new Date(),
lastUpdatedAt: now,
});
}
await this.commandSendCCRepository.save(_dataSendCC);
@ -2749,10 +2826,10 @@ export class CommandController extends Controller {
commandSend.commandId = command.id;
commandSend.createdUserId = request.user.sub;
commandSend.createdFullName = request.user.name;
commandSend.createdAt = new Date();
commandSend.createdAt = now;
commandSend.lastUpdateUserId = request.user.sub;
commandSend.lastUpdateFullName = request.user.name;
commandSend.lastUpdatedAt = new Date();
commandSend.lastUpdatedAt = now;
await this.commandSendRepository.save(commandSend);
if (commandSend && commandSend.id) {
let _ccName = new Array("EMAIL", "INBOX");
@ -2763,10 +2840,10 @@ export class CommandController extends Controller {
name: _ccName[i],
createdUserId: request.user.sub,
createdFullName: request.user.name,
createdAt: new Date(),
createdAt: now,
lastUpdateUserId: request.user.sub,
lastUpdateFullName: request.user.name,
lastUpdatedAt: new Date(),
lastUpdatedAt: now,
});
}
await this.commandSendCCRepository.save(_dataSendCC);
@ -2931,10 +3008,10 @@ export class CommandController extends Controller {
commandSend.commandId = command.id;
commandSend.createdUserId = request.user.sub;
commandSend.createdFullName = request.user.name;
commandSend.createdAt = new Date();
commandSend.createdAt = now;
commandSend.lastUpdateUserId = request.user.sub;
commandSend.lastUpdateFullName = request.user.name;
commandSend.lastUpdatedAt = new Date();
commandSend.lastUpdatedAt = now;
await this.commandSendRepository.save(commandSend);
if (commandSend && commandSend.id) {
let _ccName = new Array("EMAIL", "INBOX");
@ -2945,10 +3022,10 @@ export class CommandController extends Controller {
name: _ccName[i],
createdUserId: request.user.sub,
createdFullName: request.user.name,
createdAt: new Date(),
createdAt: now,
lastUpdateUserId: request.user.sub,
lastUpdateFullName: request.user.name,
lastUpdatedAt: new Date(),
lastUpdatedAt: now,
});
}
await this.commandSendCCRepository.save(_dataSendCC);
@ -2992,10 +3069,10 @@ export class CommandController extends Controller {
commandSend.commandId = command.id;
commandSend.createdUserId = request.user.sub;
commandSend.createdFullName = request.user.name;
commandSend.createdAt = new Date();
commandSend.createdAt = now;
commandSend.lastUpdateUserId = request.user.sub;
commandSend.lastUpdateFullName = request.user.name;
commandSend.lastUpdatedAt = new Date();
commandSend.lastUpdatedAt = now;
await this.commandSendRepository.save(commandSend);
if (commandSend && commandSend.id) {
let _ccName = new Array("EMAIL", "INBOX");
@ -3006,10 +3083,10 @@ export class CommandController extends Controller {
name: _ccName[i],
createdUserId: request.user.sub,
createdFullName: request.user.name,
createdAt: new Date(),
createdAt: now,
lastUpdateUserId: request.user.sub,
lastUpdateFullName: request.user.name,
lastUpdatedAt: new Date(),
lastUpdatedAt: now,
});
}
await this.commandSendCCRepository.save(_dataSendCC);
@ -3051,10 +3128,10 @@ export class CommandController extends Controller {
commandSend.commandId = command.id;
commandSend.createdUserId = request.user.sub;
commandSend.createdFullName = request.user.name;
commandSend.createdAt = new Date();
commandSend.createdAt = now;
commandSend.lastUpdateUserId = request.user.sub;
commandSend.lastUpdateFullName = request.user.name;
commandSend.lastUpdatedAt = new Date();
commandSend.lastUpdatedAt = now;
await this.commandSendRepository.save(commandSend);
if (commandSend && commandSend.id) {
let _ccName = new Array("EMAIL", "INBOX");
@ -3065,10 +3142,10 @@ export class CommandController extends Controller {
name: _ccName[i],
createdUserId: request.user.sub,
createdFullName: request.user.name,
createdAt: new Date(),
createdAt: now,
lastUpdateUserId: request.user.sub,
lastUpdateFullName: request.user.name,
lastUpdatedAt: new Date(),
lastUpdatedAt: now,
});
}
await this.commandSendCCRepository.save(_dataSendCC);

View file

@ -0,0 +1,224 @@
import {
Controller,
Post,
Delete,
Route,
Security,
Tags,
Body,
Path,
Request,
Response,
Get
} from "tsoa";
import { LessThan, MoreThan } from "typeorm";
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 { Command } from "../entities/Command";
import { CommandOperator, CreateCommandOperatorDto } from "../entities/CommandOperator";
import { RequestWithUser } from "../middlewares/user";
@Route("api/v1/org/commandOperator")
@Tags("CommandOperator")
@Security("bearerAuth")
@Response(
HttpStatusCode.INTERNAL_SERVER_ERROR,
"เกิดข้อผิดพลาด ไม่สามารถแสดงรายการได้ กรุณาลองใหม่ในภายหลัง",
)
export class CommandOperatorController extends Controller {
private commandRepo = AppDataSource.getRepository(Command);
private commandOperatorRepo = AppDataSource.getRepository(CommandOperator);
/**
* API
* @summary API
* @param commandId
*/
@Get("{commandId}")
async getCommandOperatorByCommandId(
@Path() commandId: string
) {
const command = await this.commandRepo.findOne({
where: { id: commandId },
select: { id: true },
});
if (!command) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลคำสั่งนี้");
}
const commandOperators = await this.commandOperatorRepo.find({
where: { commandId: command.id },
order: { orderNo: "ASC" },
});
return new HttpSuccess(commandOperators);
}
/**
* API (UP / DOWN)
* @summary API (UP / DOWN)
* @param direction (UP / DOWN)
* @param operatorId
*/
@Get("swap/{direction}/{operatorId}")
async swapCommandOperator(
@Path() direction: string,
@Path() operatorId: string,
) {
const source = await this.commandOperatorRepo.findOne({
where: { id: operatorId },
});
if (!source) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลเจ้าหน้าที่");
}
const sourceOrder = source.orderNo;
const isUp = direction.trim().toUpperCase() === "UP";
let dest: CommandOperator | null;
if (isUp) {
dest = await this.commandOperatorRepo.findOne({
where: {
commandId: source.commandId,
orderNo: LessThan(sourceOrder),
},
order: { orderNo: "DESC" },
});
} else {
dest = await this.commandOperatorRepo.findOne({
where: {
commandId: source.commandId,
orderNo: MoreThan(sourceOrder),
},
order: { orderNo: "ASC" },
});
}
// ถ้าไม่มีตัวให้สลับ (บนสุด / ล่างสุด)
if (!dest) {
return new HttpSuccess();
}
// swap
const temp = source.orderNo;
source.orderNo = dest.orderNo;
dest.orderNo = temp;
await Promise.all([
this.commandOperatorRepo.save(source),
this.commandOperatorRepo.save(dest),
]);
return new HttpSuccess();
}
/**
* API
* @summary API
* @param commandId
*/
@Post("{commandId}")
async createCommandOperators(
@Path() commandId: string,
@Request() request: RequestWithUser,
@Body() body: CreateCommandOperatorDto,
) {
const command = await this.commandRepo.findOne({
where: { id: commandId },
select: { id: true },
});
if (!command) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลคำสั่งนี้");
}
const lastOrderNo = await this.commandOperatorRepo.findOne({
where: { commandId: commandId },
order: { orderNo: "DESC" },
select: { orderNo: true },
});
const nextOrderNo = (lastOrderNo?.orderNo ?? 1) + 1;
const now = new Date();
const operator = Object.assign(
new CommandOperator(),
{
...body,
commandId: command.id,
orderNo: nextOrderNo,
createdUserId: request.user.sub,
createdFullName: request.user.name,
createdAt: now,
lastUpdateUserId: request.user.sub,
lastUpdateFullName: request.user.name,
lastUpdatedAt: now,
}
);
await this.commandOperatorRepo.save(operator);
return new HttpSuccess();
}
/**
* API
* @summary API
* @param commandId
* @param operatorId
*/
@Delete("{commandId}/{operatorId}")
public async deleteCommandOperator(
@Path() commandId: string,
@Path() operatorId: string,
) {
const queryRunner = AppDataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
// 1. หา operator
const operator = await queryRunner.manager.findOne(CommandOperator, {
where: {
id: operatorId,
commandId: commandId,
},
});
if (!operator) {
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบเจ้าหน้าที่ดำเนินการ");
}
// 2. ห้ามลบ orderNo = 1
if (operator.orderNo === 1) {
throw new HttpError(
HttpStatusCode.BAD_REQUEST,
"ไม่สามารถลบเจ้าหน้าที่ลำดับที่ 1 ได้"
);
}
const removedOrderNo = operator.orderNo;
// 3. ลบ
await queryRunner.manager.remove(operator);
// 4. re orderNumber ตัวที่เหลือ
await queryRunner.manager
.createQueryBuilder()
.update(CommandOperator)
.set({
orderNo: () => "orderNo - 1",
})
.where("commandId = :commandId", { commandId })
.andWhere("orderNo > :removedOrderNo", { removedOrderNo })
.execute();
await queryRunner.commitTransaction();
return new HttpSuccess(true);
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
await queryRunner.release();
}
}
}

View file

@ -84,6 +84,13 @@ export class CommandOperator extends EntityBase {
})
roleName: string;
@Column({
nullable: true,
comment: "ลำดับบทบาทของเจ้าหน้าที่ดำเนินการ",
default: null,
})
orderNo: number;
@Column({
length: 40,
comment: "คีย์นอก(FK)ของตาราง command",
@ -95,3 +102,16 @@ export class CommandOperator extends EntityBase {
command: Command;
}
export class CreateCommandOperatorDto {
profileId: string;
prefix?: string;
firstName?: string;
lastName?: string;
posNo?: string;
posType?: string;
posLevel?: string;
position?: string;
positionExecutive?: string;
roleName: string;
}

View file

@ -0,0 +1,14 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class UpdateTableCommandOperatorAddColumnOrderNo1770089334925 implements MigrationInterface {
name = 'UpdateTableCommandOperatorAddColumnOrderNo1770089334925'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE \`commandOperator\` ADD \`orderNo\` int NULL COMMENT 'ลำดับบทบาทของเจ้าหน้าที่ดำเนินการ'`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE \`commandOperator\` DROP COLUMN \`orderNo\``);
}
}