@e-invoice-eu/server
Version:
REST API for generating EN16931 conforming electronic invoices
227 lines • 10.4 kB
JavaScript
;
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