diff --git a/.env.example b/.env.example index 5c54552..2c4dd95 100644 --- a/.env.example +++ b/.env.example @@ -8,4 +8,7 @@ SENTRY_DSN=SENTRY_DSN AADIS_URL=AADIS_URL POSTMARK_API_TOKEN=POSTMARK_API_TOKEN POSTMARK_FEEDBACK_TEMPLATE_ID=POSTMARK_FEEDBACK_TEMPLATE_ID +POSTMARK_RECEIVED_REPORT_TEMPLATE_ID=POSTMARK_RECEIVED_REPORT_TEMPLATE_ID +POSTMARK_IN_INVESTIGATION_REPORT_TEMPLATE_ID=POSTMARK_IN_INVESTIGATION_REPORT_TEMPLATE_ID +POSTMARK_INVESTIGATED_REPORT_TEMPLATE_ID=POSTMARK_INVESTIGATED_REPORT_TEMPLATE_ID ADMIN_EMAIL=ADMIN_EMAIL \ No newline at end of file diff --git a/src/admin/admin.module.ts b/src/admin/admin.module.ts index 947d6b5..abe1103 100644 --- a/src/admin/admin.module.ts +++ b/src/admin/admin.module.ts @@ -7,6 +7,7 @@ import { Dump, DumpSchema } from '../repositories/dumps/schemas'; import { ReportRepository } from '../repositories/reports/report.repository'; import { DumpRepository } from '../repositories/dumps/dump.repository'; import { CloudinaryModule } from '../cloudinary/cloudinary.module'; +import { PostmarkService } from 'src/report/postmark.service'; @Module({ imports: [ @@ -15,6 +16,6 @@ import { CloudinaryModule } from '../cloudinary/cloudinary.module'; CloudinaryModule, ], controllers: [AdminController], - providers: [AdminService, ReportRepository, DumpRepository], + providers: [AdminService, ReportRepository, DumpRepository, PostmarkService], }) export class AdminModule {} diff --git a/src/admin/admin.service.ts b/src/admin/admin.service.ts index 5c69c6f..7898789 100644 --- a/src/admin/admin.service.ts +++ b/src/admin/admin.service.ts @@ -136,6 +136,7 @@ export class AdminService { report.imageUrls, report.historyData.map(AdminService.docToHistoryData), report.statusRecords.map(AdminService.docToStatusRecords), + report.emailFeedbackStage, ); } diff --git a/src/admin/dto/full-report.dto.ts b/src/admin/dto/full-report.dto.ts index da5f014..fac970e 100644 --- a/src/admin/dto/full-report.dto.ts +++ b/src/admin/dto/full-report.dto.ts @@ -65,6 +65,9 @@ export class FullReportDto { @ApiProperty({ type: [StatusRecordsDto] }) statusRecords: StatusRecordsDto[]; + @ApiProperty({ format: 'double' }) + emailFeedbackStage: number; + constructor( _id: string, name: string, @@ -85,6 +88,7 @@ export class FullReportDto { imageUrls: string[], historyData: HistoryDataDto[], statusRecords: StatusRecordsDto[], + emailFeedbackStage: number, ) { this._id = _id; this.name = name; @@ -105,5 +109,6 @@ export class FullReportDto { this.imageUrls = imageUrls; this.historyData = historyData; this.statusRecords = statusRecords; + this.emailFeedbackStage = emailFeedbackStage; } } diff --git a/src/report/dto/create-report.dto.ts b/src/report/dto/create-report.dto.ts index cc9249c..cc57bbd 100644 --- a/src/report/dto/create-report.dto.ts +++ b/src/report/dto/create-report.dto.ts @@ -7,6 +7,7 @@ import { IsNotEmpty, } from 'class-validator'; import { ReportCategory } from '../../common/dto/report-category'; +import { ToBoolean } from 'src/common/transform/boolean.transform'; export class CreateReportDto { @IsNotEmpty() @@ -24,6 +25,10 @@ export class CreateReportDto { @IsEmail() email: string; + @ApiProperty() + @ToBoolean() + automaticEmailsEnabled: boolean; + @ApiProperty({ type: 'array', items: { type: 'string', format: 'binary' } }) images: any[]; } diff --git a/src/report/postmark.service.ts b/src/report/postmark.service.ts index cf83887..c2bb206 100644 --- a/src/report/postmark.service.ts +++ b/src/report/postmark.service.ts @@ -16,7 +16,6 @@ export class PostmarkService { email: string, description: string ): Promise { - const templatedMessage: TemplatedMessage = { TemplateId: Number(process.env["POSTMARK_FEEDBACK_TEMPLATE_ID"]), From: process.env["ADMIN_EMAIL"]!, @@ -29,4 +28,67 @@ export class PostmarkService { const message = this.client.sendEmailWithTemplate(templatedMessage); return 'Successfully sent'; } + + async sendReceivedReportEmail( + email: string, + link: string, + ): Promise { + const templatedMessage: TemplatedMessage = { + TemplateId: Number(process.env["POSTMARK_RECEIVED_REPORT_TEMPLATE_ID"]), + From: process.env["ADMIN_EMAIL"]!, + To: email, + TemplateModel: { + link: link, + } + }; + const message = this.client.sendEmailWithTemplate(templatedMessage); + return 'Successfully sent'; + } + + async sendInInvestigationReportEmail( + email: string, + link: string, + ): Promise { + const templatedMessage: TemplatedMessage = { + TemplateId: Number(process.env["POSTMARK_IN_INVESTIGATION_REPORT_TEMPLATE_ID"]), + From: process.env["ADMIN_EMAIL"]!, + To: email, + TemplateModel: { + link: link, + } + }; + const message = this.client.sendEmailWithTemplate(templatedMessage); + return 'Successfully sent'; + } + + async sendInvestigatedReportEmail( + email: string, + link: string, + ): Promise { + const templatedMessage: TemplatedMessage = { + TemplateId: Number(process.env["POSTMARK_INVESTIGATED_REPORT_TEMPLATE_ID"]), + From: process.env["ADMIN_EMAIL"]!, + To: email, + TemplateModel: { + link: link, + } + }; + const message = this.client.sendEmailWithTemplate(templatedMessage); + return 'Successfully sent'; + } + + generateReportUrl(refId: string | number): string { + let id = ''; + if (typeof refId === 'number') { + id = String(refId); + }else{ + id = refId; + } + if (id.length > 8) { + throw new Error('refId cannot be longer than 8 characters.'); + } + const paddedZeros = '0'.repeat(8 - id.length); + const reportName = "TLP-A"+paddedZeros+id.toUpperCase(); + return "https://tvarkaulietuva.lt/pranesimas?id="+reportName; + } } \ No newline at end of file diff --git a/src/report/report.controller.ts b/src/report/report.controller.ts index d3e9efc..40d5661 100644 --- a/src/report/report.controller.ts +++ b/src/report/report.controller.ts @@ -26,7 +26,6 @@ import { FilesInterceptor } from "@nestjs/platform-express"; import { ReportStatisticsDto } from "./dto/report-statistics.dto"; import { ReportCategory } from "../common/dto/report-category"; import { PostmarkService } from "./postmark.service"; -import { MessageSendingResponse } from "postmark/dist/client/models"; import { CreateFeedbackReportDto } from "./dto/create-feedback-report.dto"; @Controller("reports") diff --git a/src/repositories/reports/report.repository.ts b/src/repositories/reports/report.repository.ts index f504dc3..8e49e8f 100644 --- a/src/repositories/reports/report.repository.ts +++ b/src/repositories/reports/report.repository.ts @@ -8,11 +8,13 @@ import { BadRequestException } from '@nestjs/common'; import { HistoryDataDto } from '../../admin/dto/history-data.dto'; import { HistoryEditsDto } from '../../admin/dto/history-edits.dto'; import { ReportCategory } from '../../common/dto/report-category'; +import { PostmarkService } from 'src/report/postmark.service'; export class ReportRepository { constructor( @InjectModel(Report.name) private reportModel: Model, private cloudinary: CloudinaryService, + private readonly postmarkService: PostmarkService, ) {} getVisibleReports(category?: ReportCategory): Promise { @@ -79,6 +81,9 @@ export class ReportRepository { } const reports = await this.reportModel.find().exec(); const reportCount = reports.length; + if(reports != null && createReport.automaticEmailsEnabled != false) { + await this.postmarkService.sendReceivedReportEmail(createReport.email, this.postmarkService.generateReportUrl(reportCount + 1)); + } const newReport = new this.reportModel({ name: createReport.name, type: createReport.category, @@ -93,6 +98,8 @@ export class ReportRepository { isDeleted: false, imageUrls: imageUrls, officerImageUrls: [], + emailFeedbackStage: 1, + automaticEmailsEnabled: createReport.automaticEmailsEnabled, historyData: [ { user: createReport.email, @@ -102,6 +109,10 @@ export class ReportRepository { field: 'status', change: 'gautas', }, + { + field: 'emailFeedbackStage', + change: '1', + }, ], }, ], @@ -112,6 +123,7 @@ export class ReportRepository { }, ], }); + return await newReport.save(); } @@ -185,19 +197,65 @@ export class ReportRepository { ); } } - await this.reportModel.updateOne( - { - refId: updateReport.refId, - }, - { - $push: { - statusRecords: { - status: updateReport.status, - date: new Date(), + + if(updateReport.status == 'tiriamas' && report.emailFeedbackStage < 2 && report.automaticEmailsEnabled){ + await this.postmarkService.sendInInvestigationReportEmail(report.email, this.postmarkService.generateReportUrl(updateReport.refId)); + await this.reportModel.updateOne( + { + refId: updateReport.refId, + }, + { + $push: { + statusRecords: { + status: updateReport.status, + date: new Date(), + }, }, + $set: { + emailFeedbackStage: 2, + } }, - }, - ); + ); + historyEntry.edits.push( + new HistoryEditsDto('emailFeedbackStage', '2'), + ); + }else if((updateReport.status == 'išspręsta' || updateReport.status == 'nepasitvirtino') && report.emailFeedbackStage < 3 && report.automaticEmailsEnabled){ + await this.postmarkService.sendInvestigatedReportEmail(report.email, this.postmarkService.generateReportUrl(updateReport.refId)); + await this.reportModel.updateOne( + { + refId: updateReport.refId, + }, + { + $push: { + statusRecords: { + status: updateReport.status, + date: new Date(), + }, + }, + $set: { + emailFeedbackStage: 3, + } + }, + ); + historyEntry.edits.push( + new HistoryEditsDto('emailFeedbackStage', '3'), + ); + }else { + await this.reportModel.updateOne( + { + refId: updateReport.refId, + }, + { + $push: { + statusRecords: { + status: updateReport.status, + date: new Date(), + }, + }, + }, + ); + } + historyEntry.edits.push( new HistoryEditsDto('status', updateReport.status), ); diff --git a/src/repositories/reports/schemas/report.schema.ts b/src/repositories/reports/schemas/report.schema.ts index 17aad9a..63ae10d 100644 --- a/src/repositories/reports/schemas/report.schema.ts +++ b/src/repositories/reports/schemas/report.schema.ts @@ -56,6 +56,12 @@ export class Report { @Prop({ type: Array, default: [] }) imageUrls: string[]; + @Prop({ type: Number, required: true }) + emailFeedbackStage: number; + + @Prop({ type: Boolean, required: false, default: false }) + automaticEmailsEnabled: boolean; + @Prop({ type: [ {