import { Controller, Get, Post, Put, Delete, Patch, Route, Security, Tags, Body, Path, Request, Example, Query, } from "tsoa"; import { AppDataSource } from "../database/data-source"; import { DeepPartial, In, IsNull, Not, Between } from "typeorm"; import HttpSuccess from "../interfaces/http-success"; import HttpError from "../interfaces/http-error"; import HttpStatusCode from "../interfaces/http-status"; import { CreateSalaryPeriod, SalaryPeriod, UpdateSalaryPeriod } from "../entities/SalaryPeriod"; import Extension from "../interfaces/extension"; @Route("api/v1/salary") @Tags("Salary") @Security("bearerAuth") export class SalaryPeriodController extends Controller { private salaryPeriodRepository = AppDataSource.getRepository(SalaryPeriod); /** * API สร้างรอบเงินเดือน * * @summary SLR_016 - สร้างรอบเงินเดือน #16 * */ @Post("period") async create_salary_period( @Body() requestBody: CreateSalaryPeriod, @Request() request: { user: Record }, ) { const salaryPeriod = Object.assign(new SalaryPeriod(), requestBody); if (!salaryPeriod) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูล"); } const chk_toUpper = ["SPECIAL", "APR", "OCT"]; if (!chk_toUpper.includes(salaryPeriod.period.toUpperCase())) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทผัง ไม่ถูกต้อง"); } const startOfYear = new Date(salaryPeriod.effectiveDate.getFullYear(), 0, 1); const endOfYear = new Date(salaryPeriod.effectiveDate.getFullYear(), 11, 31); const chk_period = await this.salaryPeriodRepository.findOne({ where: { period: salaryPeriod.period, effectiveDate: Between(startOfYear, endOfYear) }, }); if (chk_period) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทผังปี "+ salaryPeriod.effectiveDate.getFullYear() +" ซ้ำ"); } salaryPeriod.period = salaryPeriod.period.toUpperCase(); salaryPeriod.createdUserId = request.user.sub; salaryPeriod.createdFullName = request.user.name; salaryPeriod.lastUpdateUserId = request.user.sub; salaryPeriod.lastUpdateFullName = request.user.name; await this.salaryPeriodRepository.save(salaryPeriod); return new HttpSuccess(salaryPeriod.id); } /** * API แก้ไขรอบเงินเดือน * * @summary SLR_017 - แก้ไขรอบเงินเดือน #17 * * @param {string} id Guid, *Id รอบเงินเดือน */ @Put("period/{id}") async update_salary_period( @Path() id: string, @Body() requestBody: UpdateSalaryPeriod, @Request() request: { user: Record }, ) { const chk_SalaryPeriod = await this.salaryPeriodRepository.findOne({ where: { id: id }, }); if (!chk_SalaryPeriod) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลไอดี: " + id); } const chk_toUpper = ["SPECIAL", "APR", "OCT"]; if (!chk_toUpper.includes(requestBody.period.toUpperCase())) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทผัง ไม่ถูกต้อง"); } const startOfYear = new Date(requestBody.effectiveDate.getFullYear(), 0, 1); const endOfYear = new Date(requestBody.effectiveDate.getFullYear(), 11, 31); const chk_period = await this.salaryPeriodRepository.findOne({ where: { period: requestBody.period, id: Not(id), effectiveDate: Between(startOfYear, endOfYear) }, }); if (chk_period) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ประเภทผังปี "+ (requestBody.effectiveDate.getFullYear()+543) +" ซ้ำ"); } chk_SalaryPeriod.period = requestBody.period.toUpperCase(); chk_SalaryPeriod.lastUpdateUserId = request.user.sub; chk_SalaryPeriod.lastUpdateFullName = request.user.name; chk_SalaryPeriod.lastUpdatedAt = new Date(); this.salaryPeriodRepository.merge(chk_SalaryPeriod, requestBody); await this.salaryPeriodRepository.save(chk_SalaryPeriod); return new HttpSuccess(id); } /** * API ลบรอบเงินเดือน * * @summary SLR_018 - ลบรอบเงินเดือน #18 * * @param {string} id Guid, *Id รอบเงินเดือน */ @Delete("period/{id}") async delete_salary_period(@Path() id: string) { const SalaryPeriod = await this.salaryPeriodRepository.findOne({ where: { id: id }, }); if (!SalaryPeriod) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลไอดี: " + id); } await this.salaryPeriodRepository.remove(SalaryPeriod); return new HttpSuccess(); } /** * API รายละเอียดรอบเงินเดือน * * @summary SLR_019 - รายละเอียดรอบเงินเดือน #19 * * @param {string} id Guid, *Id รอบเงินเดือน */ @Get("period/{id}") async GetSalaryPeriod_ById(@Path() id: string) { const salaryPeriod = await this.salaryPeriodRepository.findOne({ where: { id: id }, select: [ "id", "period", "isActive", "effectiveDate", "isActive", "status", ], }); if (!salaryPeriod) { throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบข้อมูลไอดี: " + id); } return new HttpSuccess(salaryPeriod); } /** * API รายการรอบเงินเดือน * * @summary SLR_020 - รายการรอบเงินเดือน #20 * */ @Get("period") async GetListsSalaryPeriod( @Query("page") page: number = 1, @Query("pageSize") pageSize: number = 10, @Query("keyword") keyword?: string, @Query("year") year: number = 2024, ) { let salaryPeriod: any let total: any if(year != 0){ const startOfYear = new Date(year, 0, 1); const endOfYear = new Date(year, 11, 31); [salaryPeriod, total] = await this.salaryPeriodRepository.findAndCount({ skip: (page - 1) * pageSize, take: pageSize, where: { effectiveDate: Between(startOfYear, endOfYear) } }); }else{ [salaryPeriod, total] = await this.salaryPeriodRepository.findAndCount({ skip: (page - 1) * pageSize, take: pageSize, }); } if (keyword != undefined && keyword !== "") { const filteredSalaryPeriod = salaryPeriod.filter( (x:any) => x.period.toString().includes(keyword) || x.isActive.toString().includes(keyword) || x.effectiveDate.getFullYear().toString().includes(keyword) ); const formattedData = filteredSalaryPeriod.map((item:any) => ({ id: item.id, period: item.period, isActive: item.isActive, effectiveDate: item.effectiveDate, status: item.status, })); return new HttpSuccess({ data: formattedData, total: formattedData.length }); } if (!salaryPeriod) { return new HttpSuccess([]); } const formattedData = salaryPeriod.map((item:any) => ({ id: item.id, period: item.period, isActive: item.isActive, effectiveDate: item.effectiveDate, status: item.status, })); return new HttpSuccess({ data: formattedData, total }); } }