Skip to content

Commit 887ccdf

Browse files
feat: Implement Send Invoice Email to Recipient (#1006)
* Implement Invoice CRUD opteration of FE and BE * fix backend api issues * delete not required files and folder from FE and BE * implement update, create and delete invoice * Implement Invoice CRUD opteration of FE and BE * fix backend api issues * delete not required files and folder from FE and BE * implement update, create and delete invoice * formatting * fix merge conflict errors * feat: SRS-1002 Implement the file upload feature and integrate it with coms (#1000) * complete implementation of upload invoice attachment * formatting * fix merfe issue and minor css * key required in openshift * formatting * implement api to send invoice email with attachment * implement send invoice email on frontend * fix dropdown css issues * graphql * auto generated graphql * fix minor issues and merge conflict * formatting
1 parent b537c18 commit 887ccdf

File tree

23 files changed

+1577
-723
lines changed

23 files changed

+1577
-723
lines changed

backend/cats/package-lock.json

Lines changed: 978 additions & 267 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/cats/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"@nestjs/common": "^9.0.0",
3939
"@nestjs/core": "^9.0.0",
4040
"@nestjs/graphql": "^10.1.3",
41-
"@nestjs/platform-express": "^9.0.0",
41+
"@nestjs/platform-express": "^9.4.3",
4242
"@nestjs/typeorm": "^10.0.2",
4343
"apollo-server-express": "^3.10.2",
4444
"axios": "^1.7.9",
@@ -47,6 +47,7 @@
4747
"date-fns": "^4.1.0",
4848
"graphql": "^16.6.0",
4949
"keycloak-connect": "^18.0.2",
50+
"multer": "^2.0.2",
5051
"nest-keycloak-connect": "^1.9.0",
5152
"pg": "^8.8.0",
5253
"reflect-metadata": "^0.1.13",
@@ -70,6 +71,7 @@
7071
"@nestjs/testing": "^9.0.0",
7172
"@types/express": "^4.17.13",
7273
"@types/jest": "28.1.8",
74+
"@types/multer": "^2.0.0",
7375
"@types/node": "^16.0.0",
7476
"@types/supertest": "^2.0.11",
7577
"@typescript-eslint/eslint-plugin": "^5.0.0",

backend/cats/src/app/cats.module.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ import { ServiceAssignmentFactor } from './entities/serviceAssignmentFactor';
9595
import { PermissionServiceType } from './entities/permissionServiceType';
9696
import { ApplicationSite } from './entities/applicationSite.entity';
9797
import { InvoiceItem } from './entities/invoiceItem.entity';
98+
import { EmailController } from './controllers/email.controller';
9899

99100
/**
100101
* Module for wrapping all functionalities in user microserivce
@@ -200,6 +201,6 @@ import { InvoiceItem } from './entities/invoiceItem.entity';
200201
DashboardService,
201202
DashboardResolver,
202203
],
203-
controllers: [UserController],
204+
controllers: [UserController, EmailController],
204205
})
205206
export class CatsModule { }
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { Body, Controller, Post, UploadedFile, UseInterceptors, UsePipes, ValidationPipe } from '@nestjs/common';
2+
import { Resource} from 'nest-keycloak-connect';
3+
import { LoggerService } from '../logger/logger.service';
4+
import { FileInterceptor } from '@nestjs/platform-express/multer/interceptors/file.interceptor';
5+
import { InvoiceEmail } from '../dto/invoice/invoiceEmail/invoiceEmail.dto';
6+
import { InvoiceService } from '../services/invoice/invoice.service';
7+
import { HttpStatusCode } from 'axios';
8+
9+
@Controller('email')
10+
@Resource('cats-service')
11+
export class EmailController {
12+
constructor(
13+
private readonly invoiceService: InvoiceService,
14+
private readonly loggerService: LoggerService,
15+
) {}
16+
17+
@Post('/sendEmail')
18+
@UseInterceptors(FileInterceptor('file'))
19+
@UsePipes(new ValidationPipe({
20+
transform: true,
21+
transformOptions: { enableImplicitConversion: true },
22+
whitelist: true,
23+
}))
24+
async sendEmail( @UploadedFile() file: Express.Multer.File, @Body() invoiceEmail: InvoiceEmail) {
25+
try {
26+
let attachments = null;
27+
this.loggerService.log('Email controller: sendEmail() start');
28+
this.loggerService.log('Email controller: sendEmail() generateInvoicePdf start');
29+
if (file) {
30+
// Handle the uploaded file directly
31+
this.loggerService.log('Email controller: using uploaded file as attachment');
32+
attachments =[
33+
{
34+
filename: `Invoice-${invoiceEmail.invoiceId}.pdf`,
35+
content: file.buffer.toString('base64'),
36+
encoding: 'base64',
37+
}
38+
];
39+
}
40+
this.loggerService.log('Email controller: sendEmail() generateInvoicePdf end');
41+
42+
if(!attachments) {
43+
this.loggerService.log('Email controller: sendEmail() chesEmailService.sendEmail() no attachments start');
44+
await this.invoiceService.sendInvoice(invoiceEmail);
45+
this.loggerService.log('Email controller: sendEmail() chesEmailService.sendEmail() no attachments end');
46+
this.loggerService.log('Email controller: sendEmail() end');
47+
return {
48+
message: 'Email sent successfully without attachments',
49+
statusCode: HttpStatusCode.Ok,
50+
success: true
51+
};
52+
}
53+
else {
54+
this.loggerService.log('Email controller: sendEmail() chesEmailService.sendEmail() with attachments start');
55+
await this.invoiceService.sendInvoice(invoiceEmail, attachments);
56+
this.loggerService.log('Email controller: sendEmail() chesEmailService.sendEmail() with attachments end');
57+
this.loggerService.log('Email controller: sendEmail() end');
58+
return {
59+
message: 'Email sent successfully with attachments',
60+
statusCode: HttpStatusCode.Ok,
61+
success: true
62+
};
63+
}
64+
}
65+
catch (error) {
66+
this.loggerService.error('Email controller: sendEmail() error', error);
67+
}
68+
}
69+
}

backend/cats/src/app/dto/dropdown.dto.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ export class DropdownDto {
1515
@Field()
1616
value: string;
1717

18-
@Field()
19-
metaData?: string;
18+
@Field({ nullable: true })
19+
metaData?: string | null;
2020
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsString } from "class-validator";
2+
3+
export class InvoiceEmail {
4+
@IsNotEmpty()
5+
@IsInt()
6+
invoiceId: number;
7+
8+
@IsEmail()
9+
@IsNotEmpty()
10+
to: string;
11+
12+
@IsString()
13+
@IsOptional()
14+
subject?: string | null;
15+
16+
@IsString()
17+
@IsOptional()
18+
body?: string | null;
19+
}

0 commit comments

Comments
 (0)