import { Body, Controller, Delete, Get, Middlewares, Path, Post, Put, Route, Security, Tags, } from "tsoa"; import { RequestWithUser } from "../interfaces/user"; import prisma from "../db"; import HttpStatus from "../interfaces/http-status"; import { permissionCheck } from "../middlewares/employee"; import { notFoundError } from "../utils/error"; import { deleteFile, fileLocation } from "../utils/minio"; const MANAGE_ROLES = [ "system", "head_of_admin", "admin", "head_of_account", "account", "head_of_sale", ]; function globalAllow(user: RequestWithUser["user"]) { const allowList = ["system", "head_of_admin", "head_of_account", "head_of_sale"]; return allowList.some((v) => user.roles?.includes(v)); } type EmployeeVisaPayload = { number: string; type: string; entryCount: number; issueCountry: string; issuePlace: string; issueDate: Date; expireDate: Date; mrz?: string; remark?: string; }; @Route("api/v1/employee/{employeeId}/visa") @Tags("Employee Visa") @Middlewares(permissionCheck(globalAllow)) export class EmployeeVisaController extends Controller { @Get() @Security("keycloak") async list(@Path() employeeId: string) { return prisma.employeeVisa.findMany({ orderBy: { expireDate: "desc" }, where: { employeeId }, }); } @Get("{visaId}") @Security("keycloak") async getById(@Path() employeeId: string, @Path() visaId: string) { const record = await prisma.employeeVisa.findFirst({ where: { id: visaId, employeeId }, }); if (!record) throw notFoundError("Visa"); return record; } @Post() @Security("keycloak", MANAGE_ROLES) async create(@Path() employeeId: string, @Body() body: EmployeeVisaPayload) { const record = await prisma.employeeVisa.create({ data: { ...body, employee: { connect: { id: employeeId } }, }, }); this.setStatus(HttpStatus.CREATED); return record; } @Put("{visaId}") @Security("keycloak", MANAGE_ROLES) async editById( @Path() employeeId: string, @Path() visaId: string, @Body() body: EmployeeVisaPayload, ) { const work = await prisma.employeeVisa.findUnique({ where: { id: visaId, employeeId }, }); if (!work) throw notFoundError("Visa"); const record = await prisma.employeeVisa.update({ where: { id: visaId, employeeId }, data: { ...body }, }); this.setStatus(HttpStatus.CREATED); return record; } @Delete("{visaId}") @Security("keycloak", MANAGE_ROLES) async deleteById(@Path() employeeId: string, @Path() visaId: string) { const record = await prisma.employeeVisa.findFirst({ where: { id: visaId, employeeId }, }); if (!record) throw notFoundError("Visa"); await deleteFile(fileLocation.employee.visa(employeeId, visaId)); return await prisma.employeeVisa.delete({ where: { id: visaId, employeeId } }); } }