• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gflohr / e-invoice-eu / 14146692880

29 Mar 2025 02:49PM UTC coverage: 68.541%. First build
14146692880

Pull #110

github

web-flow
Merge d50e1026f into fbaf9faed
Pull Request #110: Move logic into core library

234 of 374 branches covered (62.57%)

Branch coverage included in aggregate %.

432 of 571 new or added lines in 24 files covered. (75.66%)

729 of 1031 relevant lines covered (70.71%)

71.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.63
/apps/server/src/mapping/mapping.controller.ts
1
import { Invoice } from '@e-invoice-eu/core';
2
import {
3✔
3
        BadRequestException,
4
        Controller,
5
        InternalServerErrorException,
6
        Logger,
7
        Param,
8
        Post,
9
        UploadedFiles,
10
        UseInterceptors,
11
} from '@nestjs/common';
12
import { FileFieldsInterceptor } from '@nestjs/platform-express';
3✔
13
import { ApiBody, ApiConsumes, ApiResponse, ApiTags } from '@nestjs/swagger';
3✔
14
import { ValidationError } from 'ajv/dist/2019';
3✔
15

16
import { MappingService } from './mapping.service';
3✔
17

18
@ApiTags('mapping')
19
@Controller('mapping')
20
export class MappingController {
3✔
21
        constructor(
22
                private readonly mappingService: MappingService,
18✔
23
                private readonly logger: Logger,
18✔
24
        ) {}
25

26
        @Post('transform/:format')
27
        @ApiConsumes('multipart/form-data')
28
        @ApiBody({
29
                description: 'The spreadsheet to be transformed.',
30
                required: true,
31
                schema: {
32
                        type: 'object',
33
                        properties: {
34
                                spreadsheet: {
35
                                        type: 'string',
36
                                        format: 'binary',
37
                                        nullable: true,
38
                                        description: 'The spreadsheet to be transformed.'
39
                                },
40
                                data: {
41
                                        type: 'string',
42
                                        format: 'binary',
43
                                        deprecated: true,
44
                                        nullable: true,
45
                                        description:
46
                                                'Will be removed in 2026! An alias for "spreadsheet". Use that instead!',
47
                                },
48
                                mapping: {
49
                                        type: 'string',
50
                                        format: 'binary',
51
                                        description: 'The mapping file in YAML or JSON format.',
52
                                },
53
                        },
54
                },
55
        })
56
        @ApiResponse({
57
                status: 201,
58
                description:
59
                        'Transformation successful. The output is an invoice' +
60
                        ' document that can be used as input for the' +
61
                        ' `/api/invoice/generate` endpoint.',
62
                links: {
63
                        generateInvoice: {
64
                                operationRef: './invoice/generate',
65
                                parameters: {
66
                                        invoice: '$response.body',
67
                                },
68
                        },
69
                },
70
        })
71
        @ApiResponse({
72
                status: 400,
73
                description: 'Bad request with error details',
74
        })
75
        @UseInterceptors(
76
                FileFieldsInterceptor([
77
                        { name: 'spreadsheet', maxCount: 1 },
78
                        { name: 'data', maxCount: 1 },
79
                        { name: 'mapping', maxCount: 1 },
80
                ]),
81
        )
82
        transform(
3✔
83
                @Param('format') format: string,
84
                @UploadedFiles()
85
                files: {
86
                        spreadsheet?: Express.Multer.File[];
87
                        data?: Express.Multer.File[];
88
                        mapping?: Express.Multer.File[];
89
                },
90
        ): Invoice {
91
                if (files.spreadsheet && files.data) {
15!
NEW
92
                        throw new BadRequestException(
×
93
                                'The parameters "spreadsheet" and data" are mutually exclusive.',
94
                        );
95
                }
96

97
                const dataFile = files.spreadsheet ? files.spreadsheet[0] : files.data?.[0];
15✔
98
                if (!dataFile) {
15✔
99
                        throw new BadRequestException('No invoice file uploaded');
3✔
100
                }
101

102
                const mappingFile = files.mapping?.[0];
12✔
103
                if (!mappingFile) {
12✔
104
                        throw new BadRequestException('No mapping file uploaded');
3✔
105
                }
106

107
                try {
9✔
108
                        return this.mappingService.transform(
9✔
109
                                format,
110
                                mappingFile.buffer.toString(),
111
                                dataFile.buffer,
112
                        );
113
                } catch (error) {
114
                        if (error instanceof ValidationError) {
6✔
115
                                throw new BadRequestException({
3✔
116
                                        message: 'Transformation failed.',
117
                                        details: error,
118
                                });
119
                        } else {
120
                                this.logger.error(`unknown error: ${error.message}\n${error.stack}`);
3✔
121
                                throw new InternalServerErrorException();
3✔
122
                        }
123
                }
124
        }
125
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc