import { Body, Controller, Delete, Get, Put, Path, Post, Query, Request, Route, Security, Tags, } from "tsoa"; import { Prisma, Status } from "@prisma/client"; import prisma from "../../db"; import { RequestWithUser } from "../../interfaces/user"; import HttpError from "../../interfaces/http-error"; import HttpStatus from "../../interfaces/http-status"; type ProductGroupCreate = { name: string; detail: string; remark: string; }; type ProductGroupUpdate = { name?: string; detail?: string; remark?: string; }; @Route("api/v1/product-group") @Tags("Product Group") @Security("keycloak") export class ProductGroup extends Controller { @Get("stats") async getProductGroupStats() { return await prisma.productGroup.count(); } @Get() async getProductGroup(@Query() query: string = "") { const where = { OR: [{ name: { contains: query } }, { detail: { contains: query } }], } satisfies Prisma.ProductGroupWhereInput; const result = prisma.productGroup.findMany({ orderBy: { createdAt: "asc" }, where }); return result; } @Get("{groupId}") async getProductGroupById(@Path() groupId: string) { const record = await prisma.productGroup.findFirst({ where: { id: groupId }, }); if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "Product group cannot be found.", "data_not_found"); return record; } @Post() async createProductGroup(@Request() req: RequestWithUser, @Body() body: ProductGroupCreate) { const record = await prisma.$transaction(async (tx) => { const last = await tx.runningNo.upsert({ where: { key: `PRODGRP`, }, create: { key: `PRODGRP`, value: 1, }, update: { value: { increment: 1 } }, }); return await tx.productGroup.create({ data: { ...body, code: `G${last.value.toString().padStart(2, "0")}`, createdBy: req.user.name, updateBy: req.user.name, }, }); }); this.setStatus(HttpStatus.CREATED); return record; } @Put("{groupId}") async editProductGroup( @Request() req: RequestWithUser, @Body() body: ProductGroupUpdate, @Path() groupId: string, ) { if (!(await prisma.work.findUnique({ where: { id: groupId } }))) { throw new HttpError(HttpStatus.NOT_FOUND, "Product group cannot be found.", "data_not_found"); } const record = await prisma.work.update({ data: { ...body, updateBy: req.user.name }, where: { id: groupId }, }); return record; } @Delete("{groupId}") async deleteProductGroup(@Path() groupId: string) { const record = await prisma.productGroup.findFirst({ where: { id: groupId } }); if (!record) { throw new HttpError(HttpStatus.NOT_FOUND, "Product group cannot be found.", "data_not_found"); } if (record.status !== Status.CREATED) { throw new HttpError(HttpStatus.FORBIDDEN, "Product group is in used.", "data_in_used"); } return await prisma.productGroup.delete({ where: { id: groupId } }); } }