UNPKG

@e-invoice-eu/server

Version:

REST API for generating EN16931 conforming electronic invoices

227 lines 10.4 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.InvoiceController = void 0; const openapi = require("@nestjs/swagger"); const common_1 = require("@nestjs/common"); const platform_express_1 = require("@nestjs/platform-express"); const swagger_1 = require("@nestjs/swagger"); const _2019_1 = require("ajv/dist/2019"); const invoice_service_1 = require("./invoice.service"); const mapping_service_1 = require("../mapping/mapping.service"); let InvoiceController = class InvoiceController { constructor(invoiceService, mappingService, logger) { this.invoiceService = invoiceService; this.mappingService = mappingService; this.logger = logger; } async create(response, format, files, body) { const { mapping, invoice, pdf, attachment } = files; const spreadsheet = files.spreadsheet; let attachmentIDs = body.attachmentID || []; if (typeof attachmentIDs !== 'object') attachmentIDs = [attachmentIDs]; let attachmentDescriptions = body.attachmentDescription || []; if (typeof attachmentDescriptions !== 'object') attachmentDescriptions = [attachmentDescriptions]; if (!invoice && !mapping) { throw new common_1.BadRequestException('Either an invoice or mapping file must be provided'); } else if (invoice && mapping) { throw new common_1.BadRequestException('Both an invoice and mapping file cannot be provided'); } else if (mapping && !spreadsheet) { throw new common_1.BadRequestException('No invoice file uploaded'); } const attachments = []; if (attachment) { for (let i = 0; i < attachment.length; ++i) { attachments[i] = { file: attachment[i], id: attachmentIDs[i], description: attachmentDescriptions[i], }; } } try { let invoiceData; if (invoice) { invoiceData = JSON.parse(invoice[0].buffer.toString()); } else { invoiceData = this.mappingService.transform(format.toLowerCase(), mapping[0].buffer.toString(), spreadsheet[0].buffer); } const document = await this.invoiceService.generate(invoiceData, { format: format.toLowerCase(), spreadsheet: spreadsheet ? spreadsheet[0] : undefined, pdf: pdf ? pdf[0] : undefined, lang: body.lang ?? 'en', attachments: attachments, embedPDF: body.embedPDF, pdfID: body.pdfID, pdfDescription: body.pdfDescription, }); if (typeof document === 'string') { response.set('Content-Type', 'application/xml'); } else { response.set('Content-Type', 'application/pdf'); } response.status(common_1.HttpStatus.CREATED).send(document); } catch (error) { if (error instanceof _2019_1.ValidationError) { throw new common_1.BadRequestException({ message: 'Transformation failed.', details: error, }); } else { this.logger.error(`unknown error: ${error.message}\n${error.stack}`); throw new common_1.InternalServerErrorException(); } } } }; exports.InvoiceController = InvoiceController; __decorate([ (0, common_1.Post)('create/:format'), (0, swagger_1.ApiParam)({ name: 'format', type: String, description: 'The format of the invoice to create, for' + ' example "UBL" or "CII". Case does not matter.', example: 'UBL', }), (0, swagger_1.ApiConsumes)('multipart/form-data'), (0, swagger_1.ApiBody)({ required: true, schema: { type: 'object', properties: { invoice: { type: 'object', nullable: true, description: 'The invoice data in the internal format as JSON. See the [JSON schema for the internal format](#/schema/SchemaController_invoice)! Mandatory, if the invoice should be generated from JSON data.', }, mapping: { type: 'string', nullable: true, format: 'binary', description: 'The mapping from spreadsheet data to the internal format as YAML or JSON. See the [JSON schema for mappings](#/schema/SchemaController_mapping). Mandatory, if the invoice should be generated from spreadsheet data.', }, lang: { type: 'string', nullable: true, description: 'Primary language of your document as a locale identifier like fr-ca, defaults to en', }, spreadsheet: { type: 'string', nullable: true, format: 'binary', description: 'The spreadsheet to be transformed.', }, pdf: { type: 'string', format: 'binary', nullable: true, description: 'Optional PDF version of the invoice. For Factur-X/ZUGFeRD, if no PDF is uploaded, one is generated from the Spreadsheet with the help of LibreOffice.', }, attachment: { type: 'array', nullable: true, description: 'An arbitrary number of supplementary attachments.', items: { type: 'string', format: 'binary', description: 'The individual attachment. Note that only' + ' the MIME types "text/csv", "application/pdf"' + ' "image/png", "image/jpeg"' + ' "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",' + ' and "application/vnd.oasis.opendocument.spreadsheet"' + ' are allowed as MIME types to XML invoices.', }, }, attachmentID: { type: 'array', nullable: true, description: 'Optional ids for each supplementary attachment', items: { type: 'string', description: 'Description for the corresponding attachment.', }, }, attachmentDescription: { type: 'array', nullable: true, description: 'Optional descriptions for each supplementary attachment.', items: { type: 'string', description: 'Description for the corresponding attachment.', }, }, embedPDF: { type: 'boolean', nullable: true, description: 'Pass if a PDF version of the invoice should be' + ' embedded into the XML; ignored for Factur-X.' + ' If no PDF is uploaded, one is generated from the' + ' Spreadsheet with the help of LibreOffice.', }, pdfID: { type: 'string', nullable: true, description: 'ID of the embedded PDF, defaults to the document' + ' number.', }, pdfDescription: { type: 'string', nullable: true, description: 'Optional description for the embedded PDF.', }, }, }, }), (0, swagger_1.ApiResponse)({ status: 201, description: 'Creation successful. The output is an invoice' + ' document as either XML or PDF.', }), (0, swagger_1.ApiResponse)({ status: 400, description: 'Bad request with error details', }), (0, common_1.UseInterceptors)((0, platform_express_1.FileFieldsInterceptor)([ { name: 'invoice', maxCount: 1 }, { name: 'mapping', maxCount: 1 }, { name: 'spreadsheet', maxCount: 1 }, { name: 'pdf', maxCount: 1 }, { name: 'attachment' }, ])), openapi.ApiResponse({ status: 201 }), __param(0, (0, common_1.Res)()), __param(1, (0, common_1.Param)('format')), __param(2, (0, common_1.UploadedFiles)()), __param(3, (0, common_1.Body)()), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, String, Object, Object]), __metadata("design:returntype", Promise) ], InvoiceController.prototype, "create", null); exports.InvoiceController = InvoiceController = __decorate([ (0, swagger_1.ApiTags)('invoice'), (0, common_1.Controller)('invoice'), __metadata("design:paramtypes", [invoice_service_1.InvoiceService, mapping_service_1.MappingService, common_1.Logger]) ], InvoiceController); //# sourceMappingURL=invoice.controller.js.map