import { extname } from "node:path"; import { Controller, Get, Post, Body, Param, UseGuards, UseInterceptors, UploadedFile, Req, Put, UploadedFiles, Patch, Query, } from "@nestjs/common"; import { FileFieldsInterceptor, FileInterceptor, } from "@nestjs/platform-express"; import { ApiBearerAuth, ApiBody, ApiConsumes, ApiParam, ApiQuery, ApiTags, } from "@nestjs/swagger"; import { Request } from "express"; import { diskStorage } from "multer"; import { GlobalGuard } from "src/auth/guards/global.guard"; import { RolesGuard } from "src/auth/guards/role.guard"; import { CurrentUser } from "src/decorators/user.decorator"; import { Roles } from "src/decorators/roles.decorator"; import { AddPlateDto } from "src/profile/dto/user/AddPlateDto"; import { RoleEnum } from "src/Types&Enums/role.enum"; import { BlameDocumentType } from "./entities/schema/blame-document.schema"; import { CarBodyFormDto, CarBodySecondForm, CreateRequestDto, DescriptionDto, InitialFormDto, LocationDto, } from "./dto/create-request-management.dto"; import { RequestManagementService } from "./request-management.service"; import { InPersonVisitDto } from "src/claim-request-management/dto/in-person-visit.dto"; @Controller("blame-request-management") @ApiTags("blame-request-management") @ApiBearerAuth() @UseGuards(GlobalGuard, RolesGuard) @Roles(RoleEnum.USER) export class RequestManagementController { constructor( private readonly requestManagementService: RequestManagementService, ) {} @Post() @UseGuards(GlobalGuard) async createRequest( @CurrentUser() user, @Body() createRequestDto: CreateRequestDto, ) { return await this.requestManagementService.createRequest( user, createRequestDto.type, ); } @Post("/initial-form/:requestId") @ApiParam({ name: "requestId" }) @ApiBody({ type: InitialFormDto }) @UseGuards(GlobalGuard) async initialFrom( @Body() body: InitialFormDto, @CurrentUser() user, @Param("requestId") requestId, ) { return await this.requestManagementService.initialFormStep( body, user, requestId, ); } @ApiBody({ schema: { type: "object", properties: { file: { type: "string", format: "binary", }, }, }, }) @ApiConsumes("multipart/form-data") @UseInterceptors( FileInterceptor("file", { limits: { fileSize: 20 * 1024 * 1024, }, storage: diskStorage({ destination: "./files/video", filename: (req, file, callback) => { const unique = Date.now(); const ex = extname(file.originalname); const filename = `${file.originalname}-${unique}${ex}`; callback(null, filename); }, }), }), ) @UseGuards(GlobalGuard) @ApiParam({ name: "requestId" }) @Post("upload-video/:requestId") @UseGuards(GlobalGuard) async videoUploader( @Param("requestId") requestId, @CurrentUser() user, @UploadedFile() file?: Express.Multer.File, ) { return await this.requestManagementService.videoUploadStep( file, user, requestId, ); } @Post("/add-plate/:requestId") @ApiParam({ name: "requestId" }) @ApiBody({ type: AddPlateDto }) @UseGuards(GlobalGuard) async addPlate( @Body() body: AddPlateDto, @CurrentUser() user, @Param("requestId") requestId, ) { return await this.requestManagementService.addPlateToRequest( user, body, requestId, ); } @Post("/carbody-form/:requestId") @ApiParam({ name: "requestId" }) @ApiBody({ type: CarBodyFormDto }) @UseGuards(GlobalGuard) async carBodyForm( @Body() body: CarBodyFormDto, @CurrentUser() user, @Param("requestId") requestId, ) { return await this.requestManagementService.carBodyFormStep( body, user, requestId, ); } @Post("/carbody-secondform/:requestId") @ApiParam({ name: "requestId" }) @ApiBody({ type: CarBodySecondForm }) @UseGuards(GlobalGuard) async carBodySecondForm( @Body() body: CarBodySecondForm, @CurrentUser() user, @Param("requestId") requestId, ) { return await this.requestManagementService.carBodySecondForm( body, user, requestId, ); } @Post("/add-detail-location/:requestId") @ApiParam({ name: "requestId" }) @ApiBody({ type: LocationDto }) @UseGuards(GlobalGuard) async addLocation( @Body() body: LocationDto, @CurrentUser() user, @Param("requestId") requestId, ) { return await this.requestManagementService.addDetailToRequestLocation( user.sub, body, requestId, user, // Pass user object for expert verification ); } @ApiBody({ schema: { type: "object", properties: { file: { type: "string", format: "binary", }, }, }, }) @ApiConsumes("multipart/form-data") @UseInterceptors( FileInterceptor("file", { limits: { fileSize: 10 * 1024 * 1024, }, storage: diskStorage({ destination: "./files/voice", filename: (req, file, callback) => { const unique = Date.now(); const ex = extname(file.originalname); const flname = file.originalname.split(".")[0]; const filename = `${flname}-${unique}${ex}`; callback(null, filename); }, }), }), ) @ApiParam({ name: "requestId" }) @Post("upload-voice/:requestId") @UseGuards(GlobalGuard) async voiceUploader( @Param("requestId") requestId, @CurrentUser() user, @UploadedFile() voice?: Express.Multer.File, ) { return await this.requestManagementService.voiceUploadStep( user, voice, requestId, ); } @Post("/add-detail-description/:requestId") @ApiParam({ name: "requestId" }) @ApiBody({ type: DescriptionDto }) @UseGuards(GlobalGuard) async addDescription( @Body() body: DescriptionDto, @Param("requestId") requestId, @CurrentUser() user, ) { return await this.requestManagementService.addDescriptionToRequest( user, body, requestId, ); } @Post("add-second-party-details/:phoneNumber/:requestId/:frontendRoutes") @ApiParam({ name: "phoneNumber" }) @ApiParam({ name: "requestId" }) @ApiParam({ name: "frontendRoutes" }) @UseGuards(GlobalGuard) async addSecondPartyDetailsToRequest( @Req() req: Request, @Param("phoneNumber") phoneNumber, @Param("requestId") requestId, @Param("frontendRoutes") frontendRoutes, @CurrentUser() firstPartyUser, ) { return await this.requestManagementService.addSecondPartyDetailsToRequest( phoneNumber, requestId, firstPartyUser, frontendRoutes, req, ); } @Get("requests") async requests(@CurrentUser() user) { return await this.requestManagementService.myRequests(user.username); } @Get("creatable-claims") @UseGuards(GlobalGuard) async getCreatableClaims(@CurrentUser() user) { return await this.requestManagementService.getCreatableClaims(user); } @Get("request/:requestId") @ApiParam({ name: "requestId" }) @Roles(RoleEnum.USER) async checkParties(@CurrentUser() user, @Param("requestId") requestId) { return await this.requestManagementService.requestDetails(user, requestId); } @ApiBody({ schema: { type: "object", properties: { sign: { type: "string", format: "binary", }, isAccept: { type: "Boolean", }, }, }, }) @ApiConsumes("multipart/form-data") @UseInterceptors( FileInterceptor("sign", { limits: { fileSize: 10 * 1024 * 1024, }, storage: diskStorage({ destination: "./files/signs", filename: (req, file, callback) => { const unique = Date.now(); const ex = extname(file.originalname); const filename = `${file.originalname.split(/[.,\s-]/)[0]}-${unique}${ex}`; callback(null, filename); }, }), }), ) @Put("request/reply/:requestId") @ApiParam({ name: "requestId" }) @UseGuards(GlobalGuard) async userReply( @Body("isAccept") isAccept: boolean, @Param("requestId") requestId: string, @CurrentUser() user, @UploadedFile() sign?: Express.Multer.File, ) { const props = { requestId, user }; return await this.requestManagementService.userReply( props, Boolean(isAccept), sign, ); } @ApiBody({ schema: { type: "object", properties: { nationalCertificate: { type: "string", format: "binary" }, carCertificate: { type: "string", format: "binary" }, drivingLicense: { type: "string", format: "binary" }, carGreenCard: { type: "string", format: "binary" }, voice: { type: "string", format: "binary" }, description: { type: "string" }, }, }, }) @ApiConsumes("multipart/form-data") @UseInterceptors( FileFieldsInterceptor( [ { name: "nationalCertificate", maxCount: 1 }, { name: "carCertificate", maxCount: 1 }, { name: "drivingLicense", maxCount: 1 }, { name: "carGreenCard", maxCount: 1 }, { name: "voice", maxCount: 1 }, ], { limits: { fileSize: 10 * 1024 * 1024 }, storage: diskStorage({ destination: "./files/blame-resend-docs", filename: (req, file, callback) => { const unique = Date.now(); const ex = extname(file.originalname); const filename = `${file.fieldname}-${unique}${ex}`; callback(null, filename); }, }), }, ), ) @UseGuards(GlobalGuard) @ApiParam({ name: "requestId" }) @Put("request/resend/:requestId") userResendReply( @Body("description") description: string, @Param("requestId") requestId: string, @CurrentUser() user: any, @UploadedFiles() files: { [key in BlameDocumentType | "voice"]?: Express.Multer.File[] }, ) { return this.requestManagementService.userResend( files, user, requestId, description, ); } }