diff --git a/src/controllers/branch/contact-controller.ts b/src/controllers/branch/contact-controller.ts new file mode 100644 index 0000000..a673f2d --- /dev/null +++ b/src/controllers/branch/contact-controller.ts @@ -0,0 +1,136 @@ +import { + Body, + Controller, + Delete, + Get, + Patch, + Path, + Post, + Query, + Request, + Route, + Security, + Tags, +} from "tsoa"; + +import prisma from "../../db"; +import minio from "../../services/minio"; +import HttpError from "../../interfaces/http-error"; +import HttpStatus from "../../interfaces/http-status"; +import { RequestWithUser } from "../../interfaces/user"; + +if (!process.env.MINIO_BUCKET) { + throw Error("Require MinIO bucket."); +} + +const MINIO_BUCKET = process.env.MINIO_BUCKET; + +type BranchContactCreate = { + lineId: string; + telephoneNo: string; +}; + +type BranchContactUpdate = { + lineId?: string; + telephoneNo?: string; +}; + +function imageLocation(id: string) { + return `branch/contact-${id}`; +} + +@Route("api/branch/{branchId}/contact") +@Tags("Branch Contact") +@Security("keycloak") +export class BranchContactController extends Controller { + @Get() + async getBranchContact( + @Path() branchId: string, + @Query() page: number = 1, + @Query() pageSize: number = 30, + ) { + const [result, total] = await prisma.$transaction([ + prisma.branchContact.findMany({ + where: { branchId }, + take: pageSize, + skip: (page - 1) * pageSize, + }), + prisma.branchContact.count({ where: { branchId } }), + ]); + + return { result, page, pageSize, total }; + } + + @Get("{contactId}") + async getBranchContactById(@Path() branchId: string, @Path() contactId: string) { + const record = await prisma.branchContact.findFirst({ where: { id: contactId, branchId } }); + + if (!record) throw new HttpError(HttpStatus.NOT_FOUND, "User cannot be found."); + + return Object.assign(record, { + qrCodeImageUrl: await minio.presignedGetObject(MINIO_BUCKET, imageLocation(record.id)), + }); + } + + @Post() + async createBranchContact( + @Request() req: RequestWithUser, + @Path() branchId: string, + @Body() body: BranchContactCreate, + ) { + if (!(await prisma.branch.findFirst({ where: { id: branchId } }))) { + throw new HttpError(HttpStatus.BAD_REQUEST, "Branch not found."); + } + const record = await prisma.branchContact.create({ + include: { branch: true }, + data: { ...body, branchId, createdBy: req.user.name, updateBy: req.user.name }, + }); + return Object.assign(record, { + qrCodeImageUrl: await minio.presignedGetObject( + MINIO_BUCKET, + imageLocation(record.id), + 12 * 60 * 60, + ), + qrCodeImageUploadUrl: await minio.presignedPutObject( + MINIO_BUCKET, + imageLocation(record.id), + 12 * 60 * 60, + ), + }); + } + + @Patch("{contactId}") + async editBranchContact( + @Request() req: RequestWithUser, + @Body() body: BranchContactUpdate, + @Path() branchId: string, + @Path() contactId: string, + ) { + const record = await prisma.branchContact.update({ + include: { branch: true }, + data: { ...body, updateBy: req.user.name }, + where: { id: contactId, branchId }, + }); + if (!record) { + throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found."); + } + return Object.assign(record, { + qrCodeImageUrl: await minio.presignedGetObject( + MINIO_BUCKET, + imageLocation(record.id), + 12 * 60 * 60, + ), + qrCodeImageUploadUrl: await minio.presignedPutObject( + MINIO_BUCKET, + imageLocation(record.id), + 12 * 60 * 60, + ), + }); + } + + @Delete("{contactId}") + async deleteBranchContact(@Path() branchId: string, @Path() contactId: string) { + const result = await prisma.branchContact.deleteMany({ where: { id: contactId, branchId } }); + if (result.count <= 0) throw new HttpError(HttpStatus.NOT_FOUND, "Branch cannot be found."); + } +}