import { Controller, Get, Post, Put, Delete, Route, Security, Tags, Body, Path, Request, Example, Query, } from "tsoa"; import { SalaryEmployees, CreateSalaryEmployee, UpdateSalaryEmployee, } from "../entities/SalaryEmployees"; import { AppDataSource } from "../database/data-source"; import { Not } from "typeorm"; import HttpSuccess from "../interfaces/http-success"; import HttpError from "../interfaces/http-error"; import HttpStatusCode from "../interfaces/http-status"; import { SalaryRankEmployees } from "../entities/SalaryRankEmployees"; import { randomUUID } from "crypto"; @Route("api/v1/salary") @Tags("Salary") @Security("bearerAuth") export class Salary extends Controller { private salaryEmployeeRepository = AppDataSource.getRepository(SalaryEmployees); private salaryRankEmployeeRepository = AppDataSource.getRepository(SalaryRankEmployees); /** * API สร้างผังเงินเดือนลูกจ้าง * * */ @Post() @Example({ name: "string", //*ชื่อผัง group: "string", //*กลุ่มผัง isActive: "boolean", //*สถานะการใช้งาน date: "datetime", //ให้ไว้ ณ วันที่ startDate: "datetime", //วันที่มีผลบังคับใช้ endDate: "datetime", //วันที่สิ้นสุดบังคับใช้ detail: "string", //คำอธิบาย }) async create_salary( @Body() requestBody: CreateSalaryEmployee, @Request() request: { user: Record }, ) { const salarys = Object.assign(new SalaryEmployees(), requestBody); if (!salarys) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); } const chk_3fields = await this.salaryEmployeeRepository.findOne({ where: { group: salarys.group, }, }); if (chk_3fields && salarys.isActive) { salarys.isActive = false; } salarys.createdUserId = request.user.sub; salarys.createdFullName = request.user.name; salarys.lastUpdateUserId = request.user.sub; salarys.lastUpdateFullName = request.user.name; await this.salaryEmployeeRepository.save(salarys); return new HttpSuccess(salarys.id); } /** * API แก้ไขผังเงินเดือนลูกจ้าง * * * @param {string} id Guid, *Id ผังเงินเดือน */ @Put("{id}") @Example({ name: "string", //*ชื่อผัง group: "string", //*กลุ่มผัง isActive: "boolean", //*สถานะการใช้งาน date: "datetime", //ให้ไว้ ณ วันที่ startDate: "datetime", //วันที่มีผลบังคับใช้ endDate: "datetime", //วันที่สิ้นสุดบังคับใช้ detail: "string", //คำอธิบาย }) async update_salary( @Path() id: string, @Body() requestBody: UpdateSalaryEmployee, @Request() request: { user: Record }, ) { const chk_Salary = await this.salaryEmployeeRepository.findOne({ where: { id: id }, }); if (!chk_Salary) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผังเงินเดือนนี้"); } if (chk_Salary.isActive && !requestBody.isActive) { throw new HttpError( HttpStatusCode.NOT_FOUND, "ไม่สามารถแก้ไขสถานะการใช้งานที่เป็น Default ได้", ); } const chk_3fields = await this.salaryEmployeeRepository.find({ where: { group: requestBody.group, isActive: true, id: Not(id), }, }); if (chk_3fields.length > 0 && requestBody.isActive) { chk_3fields.forEach(async (item) => { item.isActive = false; item.lastUpdateUserId = request.user.sub; item.lastUpdateFullName = request.user.name; item.lastUpdatedAt = new Date(); await this.salaryEmployeeRepository.save(chk_3fields); }); } const mergeData = Object.assign(new SalaryEmployees(), requestBody); chk_Salary.lastUpdateUserId = request.user.sub; chk_Salary.lastUpdateFullName = request.user.name; chk_Salary.lastUpdatedAt = new Date(); this.salaryEmployeeRepository.merge(chk_Salary, mergeData); await this.salaryEmployeeRepository.save(chk_Salary); return new HttpSuccess(id); } /** * API ลบผังเงินเดือนลูกจ้าง * * * @param {string} id Guid, *Id ผังเงินเดือน */ @Delete("{id}") async delete_salary(@Path() id: string) { const chk_Salary = await this.salaryEmployeeRepository.findOne({ where: { id: id }, }); if (!chk_Salary) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผังเงินเดือนนี้"); } if (chk_Salary.isActive) { throw new HttpError( HttpStatusCode.NOT_FOUND, "ไม่สามารถลบข้อมูลนี้ได้ เนื่องจากเปิดใช้งานอยู่", ); } const del_SalaryRank = await this.salaryRankEmployeeRepository.find({ where: { salaryEmployeeId: chk_Salary.id }, }); await this.salaryRankEmployeeRepository.remove(del_SalaryRank); await this.salaryEmployeeRepository.remove(chk_Salary); return new HttpSuccess(); } /** * API รายละเอียดผังเงินเดือนลูกจ้าง * * * @param {string} id Guid, *Id ผังเงินเดือน */ @Get("{id}") @Example({ name: "string", //*ชื่อผัง group: "string", //*กลุ่มผัง isActive: "boolean", //*สถานะการใช้งาน date: "datetime", //ให้ไว้ ณ วันที่ startDate: "datetime", //วันที่มีผลบังคับใช้ endDate: "datetime", //วันที่สิ้นสุดบังคับใช้ detail: "string", //คำอธิบาย }) async GetSalaryById(@Path() id: string) { const salary = await this.salaryEmployeeRepository.findOne({ where: { id: id }, select: ["name", "group", "isActive", "date", "startDate", "endDate", "details"], }); if (!salary) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผังเงินเดือนนี้"); } return new HttpSuccess(salary); } /** * API รายการผังเงินเดือนลูกจ้าง * * */ @Get() async listSalary( @Query("page") page: number = 1, @Query("pageSize") pageSize: number = 10, @Query("keyword") keyword?: string, ) { const [salary, total] = await this.salaryEmployeeRepository.findAndCount({ order: { isActive: "DESC", group: "ASC", }, ...(keyword ? {} : { skip: (page - 1) * pageSize, take: pageSize }), }); if (keyword != undefined && keyword !== "") { const filteredSalary = salary.filter( (x) => x.name?.toString().includes(keyword) || x.group?.toString().includes(keyword) || x.isActive?.toString().includes(keyword) || x.date?.toString().includes(keyword) || x.startDate?.toString().includes(keyword) || x.endDate?.toString().includes(keyword) || x.details?.toString().includes(keyword), ); const formattedData = filteredSalary.map((item) => ({ id: item.id, name: item.name, group: item.group, isActive: item.isActive, date: item.date, startDate: item.startDate, endDate: item.endDate, details: item.details, })); const slicedData = formattedData.slice((page - 1) * pageSize, page * pageSize); return new HttpSuccess({ data: slicedData, total: formattedData.length }); } const formattedData = salary.map((item) => ({ id: item.id, name: item.name, group: item.group, isActive: item.isActive, date: item.date, startDate: item.startDate, endDate: item.endDate, details: item.details, })); return new HttpSuccess({ data: formattedData, total }); } /** * API copy ผังเงินเดือนลูกจ้าง * * */ @Post("copy") async copySalary( @Body() body: { id: string }, @Request() request: { user: Record }, ) { const salary = await this.salaryEmployeeRepository.findOne({ relations: ["salaryRankEmployees_"], where: { id: body.id }, }); if (!salary) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลผังเงินเดือนนี้"); } const salaryRank = await this.salaryRankEmployeeRepository.find({ where: { salaryEmployeeId: salary?.id }, }); const newSalary = { ...salary, id: randomUUID(), isActive: false }; await this.salaryEmployeeRepository.save(newSalary); await Promise.all( salaryRank.map(async (v) => { const newSalaryRank = { ...v, id: randomUUID() }; await this.salaryRankEmployeeRepository.save(newSalaryRank); }), ); return new HttpSuccess({ id: newSalary.id }); } }