|
| 1 | +import { Controller, Get, Query, Res, UsePipes, ValidationPipe, BadRequestException } from '@nestjs/common'; |
| 2 | +import { Response } from 'express'; |
| 3 | +import { ReportsService } from './reports.service'; |
| 4 | +import { ReportQueryDto } from './dto/report-query.dto'; |
| 5 | +import { jsonToCsvStream } from './utils/csv.helper'; |
| 6 | +import { recordsToPdfStream } from './utils/pdf.helper'; |
| 7 | + |
| 8 | +@Controller('reports') |
| 9 | +export class ReportsController { |
| 10 | + constructor(private readonly reportsService: ReportsService) {} |
| 11 | + |
| 12 | + // GET /reports/assets?startDate=...&endDate=...&categoryId=...&departmentId=...&format=csv|pdf |
| 13 | + @Get('assets') |
| 14 | + @UsePipes(new ValidationPipe({ transform: true, whitelist: true })) |
| 15 | + async assets(@Query() q: ReportQueryDto, @Res() res: Response) { |
| 16 | + const { format = 'csv', startDate, endDate, categoryId, departmentId } = q; |
| 17 | + const data = await this.reportsService.getAssetsReport({ startDate, endDate, categoryId, departmentId }); |
| 18 | + const filename = `assets-report-${Date.now()}.${format}`; |
| 19 | + |
| 20 | + if (format === 'csv') { |
| 21 | + const fields = ['id','name','serialNumber','model','category','department','createdAt','metadata']; |
| 22 | + const stream = jsonToCsvStream(data, fields); |
| 23 | + res.setHeader('Content-Type', 'text/csv'); |
| 24 | + res.setHeader('Content-Disposition', `attachment; filename="${filename}"`); |
| 25 | + stream.pipe(res); |
| 26 | + } else if (format === 'pdf') { |
| 27 | + const columns = ['id','name','serialNumber','model','category','department','createdAt']; |
| 28 | + const stream = recordsToPdfStream('Assets Report', columns, data); |
| 29 | + res.setHeader('Content-Type', 'application/pdf'); |
| 30 | + res.setHeader('Content-Disposition', `attachment; filename="${filename}"`); |
| 31 | + stream.pipe(res); |
| 32 | + } else { |
| 33 | + throw new BadRequestException('Unsupported format'); |
| 34 | + } |
| 35 | + } |
| 36 | + |
| 37 | + // GET /reports/inventory |
| 38 | + @Get('inventory') |
| 39 | + @UsePipes(new ValidationPipe({ transform: true, whitelist: true })) |
| 40 | + async inventory(@Query() q: ReportQueryDto, @Res() res: Response) { |
| 41 | + const { format = 'csv', startDate, endDate, categoryId, departmentId } = q; |
| 42 | + const data = await this.reportsService.getInventoryReport({ startDate, endDate, categoryId, departmentId }); |
| 43 | + const filename = `inventory-report-${Date.now()}.${format}`; |
| 44 | + |
| 45 | + if (format === 'csv') { |
| 46 | + const fields = ['id','name','quantity','category','department','createdAt','metadata']; |
| 47 | + const stream = jsonToCsvStream(data, fields); |
| 48 | + res.setHeader('Content-Type', 'text/csv'); |
| 49 | + res.setHeader('Content-Disposition', `attachment; filename="${filename}"`); |
| 50 | + stream.pipe(res); |
| 51 | + } else if (format === 'pdf') { |
| 52 | + const columns = ['id','name','quantity','category','department','createdAt']; |
| 53 | + const stream = recordsToPdfStream('Inventory Report', columns, data); |
| 54 | + res.setHeader('Content-Type', 'application/pdf'); |
| 55 | + res.setHeader('Content-Disposition', `attachment; filename="${filename}"`); |
| 56 | + stream.pipe(res); |
| 57 | + } else { |
| 58 | + throw new BadRequestException('Unsupported format'); |
| 59 | + } |
| 60 | + } |
| 61 | + |
| 62 | + // GET /reports/usage |
| 63 | + @Get('usage') |
| 64 | + @UsePipes(new ValidationPipe({ transform: true, whitelist: true })) |
| 65 | + async usage(@Query() q: ReportQueryDto, @Res() res: Response) { |
| 66 | + const { format = 'csv', startDate, endDate, categoryId, departmentId } = q; |
| 67 | + const data = await this.reportsService.getUsageReport({ startDate, endDate, categoryId, departmentId }); |
| 68 | + const filename = `usage-report-${Date.now()}.${format}`; |
| 69 | + |
| 70 | + if (format === 'csv') { |
| 71 | + const fields = ['id','action','assetId','assetName','inventoryItemId','inventoryItemName','department','performedBy','performedAt','meta']; |
| 72 | + const stream = jsonToCsvStream(data, fields); |
| 73 | + res.setHeader('Content-Type', 'text/csv'); |
| 74 | + res.setHeader('Content-Disposition', `attachment; filename="${filename}"`); |
| 75 | + stream.pipe(res); |
| 76 | + } else if (format === 'pdf') { |
| 77 | + const columns = ['performedAt','action','assetName','inventoryItemName','department','performedBy']; |
| 78 | + const stream = recordsToPdfStream('Usage History Report', columns, data); |
| 79 | + res.setHeader('Content-Type', 'application/pdf'); |
| 80 | + res.setHeader('Content-Disposition', `attachment; filename="${filename}"`); |
| 81 | + stream.pipe(res); |
| 82 | + } else { |
| 83 | + throw new BadRequestException('Unsupported format'); |
| 84 | + } |
| 85 | + } |
| 86 | +} |
0 commit comments