import { Controller, Get, Post, Patch, Delete, Body, Param, Query, ParseUUIDPipe, UseGuards, } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiQuery } from '@nestjs/swagger'; import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard'; import { CurrentTenant } from '../../tenants/decorators/current-tenant.decorator'; import { CurrentUser } from '../../auth/decorators/current-user.decorator'; import { LeadsService, LeadFilters, PaginationOptions } from '../services/leads.service'; import { CreateLeadDto, UpdateLeadDto, ConvertLeadDto } from '../dto'; import { Lead, LeadStatus, LeadSource } from '../entities/lead.entity'; @ApiTags('Sales - Leads') @ApiBearerAuth() @UseGuards(JwtAuthGuard) @Controller('sales/leads') export class LeadsController { constructor(private readonly leadsService: LeadsService) {} @Get() @ApiOperation({ summary: 'Get all leads' }) @ApiQuery({ name: 'page', required: false, type: Number }) @ApiQuery({ name: 'limit', required: false, type: Number }) @ApiQuery({ name: 'status', required: false, enum: LeadStatus }) @ApiQuery({ name: 'source', required: false, enum: LeadSource }) @ApiQuery({ name: 'assigned_to', required: false, type: String }) @ApiQuery({ name: 'search', required: false, type: String }) @ApiQuery({ name: 'sortBy', required: false, type: String }) @ApiQuery({ name: 'sortOrder', required: false, enum: ['ASC', 'DESC'] }) async findAll( @CurrentTenant() tenantId: string, @Query('page') page?: number, @Query('limit') limit?: number, @Query('status') status?: LeadStatus, @Query('source') source?: LeadSource, @Query('assigned_to') assigned_to?: string, @Query('search') search?: string, @Query('sortBy') sortBy?: string, @Query('sortOrder') sortOrder?: 'ASC' | 'DESC', ) { const filters: LeadFilters = { status, source, assigned_to, search }; const pagination: PaginationOptions = { page, limit, sortBy, sortOrder }; return this.leadsService.findAll(tenantId, filters, pagination); } @Get('stats') @ApiOperation({ summary: 'Get lead statistics' }) async getStats(@CurrentTenant() tenantId: string) { return this.leadsService.getStats(tenantId); } @Get(':id') @ApiOperation({ summary: 'Get a lead by ID' }) @ApiResponse({ status: 200, description: 'Lead found' }) @ApiResponse({ status: 404, description: 'Lead not found' }) async findOne( @CurrentTenant() tenantId: string, @Param('id', ParseUUIDPipe) id: string, ) { return this.leadsService.findOne(tenantId, id); } @Post() @ApiOperation({ summary: 'Create a new lead' }) @ApiResponse({ status: 201, description: 'Lead created' }) async create( @CurrentTenant() tenantId: string, @CurrentUser('id') userId: string, @Body() dto: CreateLeadDto, ) { return this.leadsService.create(tenantId, dto, userId); } @Patch(':id') @ApiOperation({ summary: 'Update a lead' }) @ApiResponse({ status: 200, description: 'Lead updated' }) @ApiResponse({ status: 404, description: 'Lead not found' }) async update( @CurrentTenant() tenantId: string, @Param('id', ParseUUIDPipe) id: string, @Body() dto: UpdateLeadDto, ) { return this.leadsService.update(tenantId, id, dto); } @Delete(':id') @ApiOperation({ summary: 'Delete a lead' }) @ApiResponse({ status: 200, description: 'Lead deleted' }) @ApiResponse({ status: 404, description: 'Lead not found' }) async remove( @CurrentTenant() tenantId: string, @Param('id', ParseUUIDPipe) id: string, ) { await this.leadsService.remove(tenantId, id); return { message: 'Lead deleted successfully' }; } @Post(':id/convert') @ApiOperation({ summary: 'Convert a lead to an opportunity' }) @ApiResponse({ status: 201, description: 'Lead converted to opportunity' }) @ApiResponse({ status: 400, description: 'Lead already converted' }) @ApiResponse({ status: 404, description: 'Lead not found' }) async convertToOpportunity( @CurrentTenant() tenantId: string, @Param('id', ParseUUIDPipe) id: string, @Body() dto: ConvertLeadDto, ) { return this.leadsService.convertToOpportunity(tenantId, id, dto); } @Patch(':id/assign') @ApiOperation({ summary: 'Assign a lead to a user' }) @ApiResponse({ status: 200, description: 'Lead assigned' }) @ApiResponse({ status: 404, description: 'Lead not found' }) async assignTo( @CurrentTenant() tenantId: string, @Param('id', ParseUUIDPipe) id: string, @Body('user_id', ParseUUIDPipe) userId: string, ) { return this.leadsService.assignTo(tenantId, id, userId); } @Patch(':id/score') @ApiOperation({ summary: 'Update lead score' }) @ApiResponse({ status: 200, description: 'Score updated' }) @ApiResponse({ status: 400, description: 'Invalid score' }) @ApiResponse({ status: 404, description: 'Lead not found' }) async updateScore( @CurrentTenant() tenantId: string, @Param('id', ParseUUIDPipe) id: string, @Body('score') score: number, ) { return this.leadsService.updateScore(tenantId, id, score); } }