forked from Yara724/api
Delegated the PDF creation task for FE, and BE now only returns the necessary data for it
This commit is contained in:
@@ -1,36 +0,0 @@
|
|||||||
import { Injectable } from "@nestjs/common";
|
|
||||||
import {
|
|
||||||
createPersianPdfDocument,
|
|
||||||
persianPdfToBuffer,
|
|
||||||
} from "src/helpers/persian-pdf-document";
|
|
||||||
import {
|
|
||||||
InsurerFileReportPdfResult,
|
|
||||||
InsurerFileReportViewModel,
|
|
||||||
} from "./case-expert-report.types";
|
|
||||||
import { PR } from "./persian-report-labels";
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class CaseExpertReportPdfService {
|
|
||||||
async render(model: InsurerFileReportViewModel): Promise<InsurerFileReportPdfResult> {
|
|
||||||
const pdf = createPersianPdfDocument();
|
|
||||||
pdf.addTitle(model.title);
|
|
||||||
pdf.addKeyValue(PR.publicId, model.publicId);
|
|
||||||
pdf.addKeyValue(PR.requestNo, model.requestNo);
|
|
||||||
pdf.addBlank();
|
|
||||||
|
|
||||||
for (const section of model.sections) {
|
|
||||||
pdf.addSection(section.title);
|
|
||||||
for (const field of section.fields) {
|
|
||||||
pdf.addKeyValue(field.label, field.value);
|
|
||||||
}
|
|
||||||
pdf.addBlank();
|
|
||||||
}
|
|
||||||
|
|
||||||
const buffer = await persianPdfToBuffer(pdf);
|
|
||||||
const safeId = (model.publicId || "file").replace(/[^\w.-]+/g, "_");
|
|
||||||
return {
|
|
||||||
buffer,
|
|
||||||
filename: `insurer-file-report-${safeId}.pdf`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,14 +4,12 @@ import {
|
|||||||
HttpException,
|
HttpException,
|
||||||
InternalServerErrorException,
|
InternalServerErrorException,
|
||||||
Param,
|
Param,
|
||||||
StreamableFile,
|
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from "@nestjs/common";
|
} from "@nestjs/common";
|
||||||
import {
|
import {
|
||||||
ApiBearerAuth,
|
ApiBearerAuth,
|
||||||
ApiOperation,
|
ApiOperation,
|
||||||
ApiParam,
|
ApiParam,
|
||||||
ApiProduces,
|
|
||||||
ApiResponse,
|
ApiResponse,
|
||||||
ApiTags,
|
ApiTags,
|
||||||
} from "@nestjs/swagger";
|
} from "@nestjs/swagger";
|
||||||
@@ -21,6 +19,7 @@ import { Roles } from "src/decorators/roles.decorator";
|
|||||||
import { CurrentUser } from "src/decorators/user.decorator";
|
import { CurrentUser } from "src/decorators/user.decorator";
|
||||||
import { RoleEnum } from "src/Types&Enums/role.enum";
|
import { RoleEnum } from "src/Types&Enums/role.enum";
|
||||||
import { CaseExpertReportService } from "./case-expert-report.service";
|
import { CaseExpertReportService } from "./case-expert-report.service";
|
||||||
|
import { InsurerFileReportViewModel } from "./case-expert-report.types";
|
||||||
|
|
||||||
@ApiTags("expert-insurer-panel")
|
@ApiTags("expert-insurer-panel")
|
||||||
@Controller("expert-insurer")
|
@Controller("expert-insurer")
|
||||||
@@ -32,36 +31,30 @@ export class CaseExpertReportInsurerController {
|
|||||||
private readonly caseExpertReportService: CaseExpertReportService,
|
private readonly caseExpertReportService: CaseExpertReportService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Get("files/:publicId/report.pdf")
|
@Get("files/:publicId/report")
|
||||||
@ApiOperation({
|
@ApiOperation({
|
||||||
summary: "Download insurer file report PDF",
|
summary: "Get insurer file report data",
|
||||||
description:
|
description:
|
||||||
"Generates a PDF for the shared publicId (blame + claim combined): damaged owner, driver when different, insurance, vehicle, and accident report sections.",
|
"Returns the structured report data for the given publicId (blame + claim combined): damaged owner, driver when different, insurance, vehicle, and accident report sections. The front-end uses this data to render and generate the PDF.",
|
||||||
})
|
})
|
||||||
@ApiParam({ name: "publicId" })
|
@ApiParam({ name: "publicId" })
|
||||||
@ApiProduces("application/pdf")
|
@ApiResponse({ status: 200, description: "Report data" })
|
||||||
@ApiResponse({ status: 200, description: "PDF file" })
|
|
||||||
@ApiResponse({ status: 404, description: "File not found for this publicId" })
|
@ApiResponse({ status: 404, description: "File not found for this publicId" })
|
||||||
async downloadInsurerReport(
|
async getInsurerReport(
|
||||||
@CurrentUser() insurer: { clientKey?: string },
|
@CurrentUser() insurer: { clientKey?: string },
|
||||||
@Param("publicId") publicId: string,
|
@Param("publicId") publicId: string,
|
||||||
): Promise<StreamableFile> {
|
): Promise<InsurerFileReportViewModel> {
|
||||||
try {
|
try {
|
||||||
const { buffer, filename } =
|
return await this.caseExpertReportService.generateForInsurer(
|
||||||
await this.caseExpertReportService.generateForInsurer(
|
publicId,
|
||||||
publicId,
|
insurer,
|
||||||
insurer,
|
);
|
||||||
);
|
|
||||||
return new StreamableFile(buffer, {
|
|
||||||
type: "application/pdf",
|
|
||||||
disposition: `attachment; filename="${filename}"`,
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof HttpException) throw error;
|
if (error instanceof HttpException) throw error;
|
||||||
throw new InternalServerErrorException(
|
throw new InternalServerErrorException(
|
||||||
error instanceof Error
|
error instanceof Error
|
||||||
? error.message
|
? error.message
|
||||||
: "Failed to generate insurer file report PDF",
|
: "Failed to retrieve insurer file report data",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import { Module } from "@nestjs/common";
|
import { Module } from "@nestjs/common";
|
||||||
import { ExpertInsurerModule } from "src/expert-insurer/expert-insurer.module";
|
import { ExpertInsurerModule } from "src/expert-insurer/expert-insurer.module";
|
||||||
import { CaseExpertReportInsurerController } from "./case-expert-report.controller";
|
import { CaseExpertReportInsurerController } from "./case-expert-report.controller";
|
||||||
import { CaseExpertReportPdfService } from "./case-expert-report-pdf.service";
|
|
||||||
import { CaseExpertReportService } from "./case-expert-report.service";
|
import { CaseExpertReportService } from "./case-expert-report.service";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [ExpertInsurerModule],
|
imports: [ExpertInsurerModule],
|
||||||
controllers: [CaseExpertReportInsurerController],
|
controllers: [CaseExpertReportInsurerController],
|
||||||
providers: [CaseExpertReportService, CaseExpertReportPdfService],
|
providers: [CaseExpertReportService],
|
||||||
exports: [CaseExpertReportService],
|
exports: [CaseExpertReportService],
|
||||||
})
|
})
|
||||||
export class CaseExpertReportModule {}
|
export class CaseExpertReportModule {}
|
||||||
|
|||||||
@@ -1,20 +1,18 @@
|
|||||||
import { Injectable, NotFoundException } from "@nestjs/common";
|
import { Injectable, NotFoundException } from "@nestjs/common";
|
||||||
import { ExpertInsurerService } from "src/expert-insurer/expert-insurer.service";
|
import { ExpertInsurerService } from "src/expert-insurer/expert-insurer.service";
|
||||||
import { buildInsurerFileReport } from "./case-expert-report.builder";
|
import { buildInsurerFileReport } from "./case-expert-report.builder";
|
||||||
import { CaseExpertReportPdfService } from "./case-expert-report-pdf.service";
|
import { InsurerFileReportViewModel } from "./case-expert-report.types";
|
||||||
import { InsurerFileReportPdfResult } from "./case-expert-report.types";
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CaseExpertReportService {
|
export class CaseExpertReportService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly expertInsurerService: ExpertInsurerService,
|
private readonly expertInsurerService: ExpertInsurerService,
|
||||||
private readonly pdfService: CaseExpertReportPdfService,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async generateForInsurer(
|
async generateForInsurer(
|
||||||
publicId: string,
|
publicId: string,
|
||||||
actor: { clientKey?: string },
|
actor: { clientKey?: string },
|
||||||
): Promise<InsurerFileReportPdfResult> {
|
): Promise<InsurerFileReportViewModel> {
|
||||||
const clientKey = actor?.clientKey;
|
const clientKey = actor?.clientKey;
|
||||||
if (!clientKey) {
|
if (!clientKey) {
|
||||||
throw new NotFoundException("Insurer context not found");
|
throw new NotFoundException("Insurer context not found");
|
||||||
@@ -24,7 +22,6 @@ export class CaseExpertReportService {
|
|||||||
clientKey,
|
clientKey,
|
||||||
publicId,
|
publicId,
|
||||||
);
|
);
|
||||||
const model = buildInsurerFileReport(file);
|
return buildInsurerFileReport(file);
|
||||||
return this.pdfService.render(model);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,3 @@ export type InsurerFileReportViewModel = {
|
|||||||
requestNo?: string;
|
requestNo?: string;
|
||||||
sections: InsurerFileReportSection[];
|
sections: InsurerFileReportSection[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type InsurerFileReportPdfResult = {
|
|
||||||
buffer: Buffer;
|
|
||||||
filename: string;
|
|
||||||
};
|
|
||||||
|
|||||||
Reference in New Issue
Block a user