mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-08 15:58:18 +00:00
refactor(reports): export through the shared tabular writer
Completes the writer extraction whose other half landed in fb21ad154.
reports.controller now builds a TabularDoc and calls TabularExportService,
so report-export.service.ts and report-export-request.util.ts are dead and
removed — HEAD was carrying both copies with the controller still on the old
one.
Reports gain CSV for free, and the PDF path now passes buildTabularFallbackPdf
as its fallback: previously it passed none, so a box without Chromium silently
returned PdfRenderService's ~900-character generic text dump instead of a
table. Adds a spec covering the CSV writer's quoting of embedded commas and
double quotes — the reason this uses ExcelJS's csv writer rather than a
hand-rolled join.
This commit is contained in:
@@ -10,8 +10,13 @@ import { BookingStaff } from '../../common/booking-guards';
|
||||
import { assertFreightPermission, hasFreightPermission } from '../../common/freight-permission.util';
|
||||
import { FREIGHT_PERMS, reportPermissionKey } from '../../seed/freight-permissions.registry';
|
||||
import { UserTradeAccessService } from '../user-trade-access/user-trade-access.service';
|
||||
import { ReportExportService } from './report-export.service';
|
||||
import { resolveExportCap, resolveExportColumns, resolveExportFormat } from './report-export-request.util';
|
||||
import {
|
||||
EXPORT_MIME,
|
||||
pickByKey,
|
||||
resolveExportCap,
|
||||
resolveExportFormat,
|
||||
} from '../exports/export-request.util';
|
||||
import { TabularExportService } from '../exports/tabular-export.service';
|
||||
import { RawReportQuery, ReportRunnerService } from './report-runner.service';
|
||||
import { REPORTS, getReport } from './report.registry';
|
||||
import { ReportCatalogEntry, ReportDefinition, ReportFilterOption } from './report.types';
|
||||
@@ -59,7 +64,7 @@ async function resolveFilterOptions(
|
||||
export class ReportsController {
|
||||
constructor(
|
||||
private readonly runner: ReportRunnerService,
|
||||
private readonly exportService: ReportExportService,
|
||||
private readonly exportService: TabularExportService,
|
||||
private readonly userTradeAccessService: UserTradeAccessService,
|
||||
@InjectDataSource() private readonly dataSource: DataSource,
|
||||
) {}
|
||||
@@ -86,7 +91,7 @@ export class ReportsController {
|
||||
}
|
||||
|
||||
@Get(':key/export')
|
||||
@ApiOperation({ summary: 'Export a report to xlsx or pdf' })
|
||||
@ApiOperation({ summary: 'Export a report to xlsx, csv or pdf' })
|
||||
async export(
|
||||
@Param('key') key: string,
|
||||
@Query() query: RawReportQuery & { format?: string; fields?: string; limit?: string },
|
||||
@@ -97,22 +102,27 @@ export class ReportsController {
|
||||
const directions = await this.userTradeAccessService.resolveAllowedDirections(user);
|
||||
const format = resolveExportFormat(query.format);
|
||||
const cap = resolveExportCap(format, query.limit);
|
||||
const exportColumns = resolveExportColumns(def, query.fields);
|
||||
const exportColumns = pickByKey(def.columns, query.fields);
|
||||
|
||||
const { items, kpis } = await this.runner.runAll(def, query, directions, cap);
|
||||
const doc = {
|
||||
title: def.title,
|
||||
description: def.description,
|
||||
label: `report:${def.key}`,
|
||||
columns: exportColumns,
|
||||
rows: items,
|
||||
kpis,
|
||||
};
|
||||
const buffer =
|
||||
format === 'pdf'
|
||||
? await this.exportService.toPdf(def, items, kpis, exportColumns)
|
||||
: await this.exportService.toXlsx(def, items, kpis, exportColumns);
|
||||
? await this.exportService.toPdf(doc)
|
||||
: format === 'csv'
|
||||
? await this.exportService.toCsv(doc)
|
||||
: await this.exportService.toXlsx(doc);
|
||||
|
||||
const filename = `${def.key}.${format === 'pdf' ? 'pdf' : 'xlsx'}`;
|
||||
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
|
||||
res.setHeader(
|
||||
'Content-Type',
|
||||
format === 'pdf'
|
||||
? 'application/pdf'
|
||||
: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
);
|
||||
const mime = EXPORT_MIME[format];
|
||||
res.setHeader('Content-Disposition', `attachment; filename="${def.key}.${mime.ext}"`);
|
||||
res.setHeader('Content-Type', mime.type);
|
||||
res.send(buffer);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user