template-saas-backend-v2/src/modules/commissions/controllers/periods.controller.ts
Adrian Flores Cortes eb6a83daba feat(sales,commissions): Add Sales and Commissions backend modules
Sales Module (SAAS-018):
- Entities: PipelineStage, Lead, Opportunity, Activity
- Services: LeadsService, OpportunitiesService, ActivitiesService, PipelineService, SalesDashboardService
- Controllers: 25 endpoints for leads, opportunities, activities, pipeline, dashboard
- DTOs: Complete CRUD and query DTOs
- Integration with DDL functions: convert_lead_to_opportunity, update_opportunity_stage, calculate_lead_score

Commissions Module (SAAS-020):
- Entities: CommissionScheme, CommissionAssignment, CommissionPeriod, CommissionEntry
- Services: SchemesService, AssignmentsService, EntriesService, PeriodsService, CommissionsDashboardService
- Controllers: 25 endpoints for schemes, assignments, entries, periods, dashboard
- DTOs: Complete CRUD and query DTOs
- Integration with DDL functions: calculate_commission, close_period, get_user_earnings

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 22:23:02 -06:00

117 lines
2.9 KiB
TypeScript

import {
Controller,
Get,
Post,
Put,
Delete,
Body,
Param,
Query,
UseGuards,
ParseUUIDPipe,
} from '@nestjs/common';
import { JwtAuthGuard } from '@modules/auth/guards/jwt-auth.guard';
import { CurrentUser } from '@modules/auth/decorators/current-user.decorator';
import { PeriodsService } from '../services';
import {
CreatePeriodDto,
UpdatePeriodDto,
ClosePeriodDto,
MarkPaidDto,
PeriodListQueryDto,
PeriodResponseDto,
PaginatedPeriodsDto,
} from '../dto';
interface RequestUser {
id: string;
tenant_id: string;
email: string;
role: string;
}
@Controller('commissions/periods')
@UseGuards(JwtAuthGuard)
export class PeriodsController {
constructor(private readonly periodsService: PeriodsService) {}
@Get()
async findAll(
@CurrentUser() user: RequestUser,
@Query() query: PeriodListQueryDto,
): Promise<PaginatedPeriodsDto> {
return this.periodsService.findAll(user.tenant_id, query);
}
@Get('current')
async getCurrentPeriod(@CurrentUser() user: RequestUser): Promise<PeriodResponseDto | null> {
return this.periodsService.getCurrentPeriod(user.tenant_id);
}
@Get(':id')
async findOne(
@CurrentUser() user: RequestUser,
@Param('id', ParseUUIDPipe) id: string,
): Promise<PeriodResponseDto> {
return this.periodsService.findOne(user.tenant_id, id);
}
@Post()
async create(
@CurrentUser() user: RequestUser,
@Body() dto: CreatePeriodDto,
): Promise<PeriodResponseDto> {
return this.periodsService.create(user.tenant_id, user.id, dto);
}
@Put(':id')
async update(
@CurrentUser() user: RequestUser,
@Param('id', ParseUUIDPipe) id: string,
@Body() dto: UpdatePeriodDto,
): Promise<PeriodResponseDto> {
return this.periodsService.update(user.tenant_id, id, dto);
}
@Post(':id/close')
async close(
@CurrentUser() user: RequestUser,
@Param('id', ParseUUIDPipe) id: string,
@Body() dto: ClosePeriodDto,
): Promise<PeriodResponseDto> {
return this.periodsService.close(user.tenant_id, id, user.id, dto);
}
@Post(':id/mark-paid')
async markPaid(
@CurrentUser() user: RequestUser,
@Param('id', ParseUUIDPipe) id: string,
@Body() dto: MarkPaidDto,
): Promise<PeriodResponseDto> {
return this.periodsService.markAsPaid(user.tenant_id, id, user.id, dto);
}
@Delete(':id')
async remove(
@CurrentUser() user: RequestUser,
@Param('id', ParseUUIDPipe) id: string,
): Promise<{ message: string }> {
await this.periodsService.remove(user.tenant_id, id);
return { message: 'Commission period deleted successfully' };
}
@Post(':id/assign-entries')
async assignEntries(
@CurrentUser() user: RequestUser,
@Param('id', ParseUUIDPipe) id: string,
@Body() body: { entryIds: string[] },
): Promise<{ assigned: number }> {
const assigned = await this.periodsService.assignEntriesToPeriod(
user.tenant_id,
id,
body.entryIds,
);
return { assigned };
}
}