import { Controller, Get, Put, Post, Body, Param, Query, Res, UseGuards, ParseIntPipe } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger'; import { Response } from 'express'; import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard'; import { RequireCapability } from '../../common/decorators/capability.decorator'; import { BudgetsService } from './budgets.service'; import { UpsertBudgetDto } from './dto/upsert-budget.dto'; @ApiTags('budgets') @Controller('budgets') @ApiBearerAuth() @UseGuards(JwtAuthGuard) export class BudgetsController { constructor(private budgetsService: BudgetsService) {} @Post(':year/import') @ApiOperation({ summary: 'Import budget data from parsed CSV/XLSX lines' }) @RequireCapability('financials.budgets.edit') importBudget( @Param('year', ParseIntPipe) year: number, @Body() lines: any[], ) { return this.budgetsService.importBudget(year, lines); } @Get(':year/template') @ApiOperation({ summary: 'Download budget CSV template for a fiscal year' }) @RequireCapability('financials.budgets.view') async getTemplate( @Param('year', ParseIntPipe) year: number, @Res() res: Response, ) { const csv = await this.budgetsService.getTemplate(year); res.set({ 'Content-Type': 'text/csv', 'Content-Disposition': `attachment; filename="budget_template_${year}.csv"`, }); res.send(csv); } @Get(':year/vs-actual') @ApiOperation({ summary: 'Budget vs actual comparison' }) @RequireCapability('financials.budgets.view') budgetVsActual( @Param('year', ParseIntPipe) year: number, @Query('month') month?: string, ) { return this.budgetsService.getBudgetVsActual(year, month ? parseInt(month) : undefined); } @Get(':year') @ApiOperation({ summary: 'Get budgets for a fiscal year' }) @RequireCapability('financials.budgets.view') findByYear(@Param('year', ParseIntPipe) year: number) { return this.budgetsService.findByYear(year); } @Put(':year') @ApiOperation({ summary: 'Upsert budgets for a fiscal year' }) @RequireCapability('financials.budgets.edit') upsert( @Param('year', ParseIntPipe) year: number, @Body() budgets: UpsertBudgetDto[], ) { return this.budgetsService.upsert(year, budgets); } }