hrms-api-org/src/controllers/CommandOperatorController.ts
harid d6bb9be93d
All checks were successful
Build & Deploy on Dev / build (push) Successful in 3m3s
comment ห้ามลบเจ้าหน้าที่ลำดับที่ 1 #2220
2026-02-10 10:44:58 +07:00

224 lines
7.2 KiB
TypeScript

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();
}
}
}