import { Injectable } from '@nestjs/common' import { first } from 'lodash' import { LanguageCountryCode } from '../../utils' import { MailService } from '../mail' import { StorageService } from '../storage' import { PDFService } from '../pdf' import { UnprocessableEntityError } from '../../errors' import { HTML_SUBSCRIPTION_CONTRACT_PT_BR } from './static' import { TranslateContractHelper } from './i18n' export type ContractData = { person: { name: string birthday: string document_cpf: string email: string } wallet: { masked_card_number: string responsible_name: string responsible_cpf: string } subscription: { id: string date: string plan_name: string price: string | number installments: number teleconsultations_value: number origin_humanize: string } } export type ContractEmailDynamicData = { first_name: string installments: number plan: { name: string price: string teleconsultations_value: number type: { [key: string]: boolean } } } const DEFAULT_HTML_TEMPLATE_BY_LANGUAGE = { pt_BR: HTML_SUBSCRIPTION_CONTRACT_PT_BR, } @Injectable() export class ContractService { constructor( private readonly mailService: MailService, private readonly storageService: StorageService, private readonly pdfService: PDFService, private readonly translator: TranslateContractHelper, ) {} async generateSubscriptionContract( data: ContractData, patientId: string, subscriptionId: string, language: LanguageCountryCode, ): Promise { const html = DEFAULT_HTML_TEMPLATE_BY_LANGUAGE[language] if (!html) throw new UnprocessableEntityError('Contract not available in that language') const pdfBuffer = await this.pdfService.generatePDF({ html, dynamicData: data, }) const dynamicTemplateData: ContractEmailDynamicData = { first_name: first(data.person.name.split(' ')), installments: data.subscription.installments, plan: { name: data.subscription.plan_name, price: `${data.subscription.price}`, teleconsultations_value: data.subscription.teleconsultations_value, type: { teleconsultation: data.subscription.plan_name.indexOf('Teleconsulta') >= 0, bio: data.subscription.plan_name.indexOf('Bio') >= 0, complete: data.subscription.plan_name.indexOf('Completo') >= 0, }, }, } await Promise.allSettled([ this.upload(patientId, subscriptionId, pdfBuffer), this.attachAndSendEmail({ email: data.person.email, pdf: pdfBuffer, dynamicTemplateData, language, }), ]) } private attachAndSendEmail({ email, pdf, language, dynamicTemplateData, }: { email: string pdf: Buffer language: LanguageCountryCode dynamicTemplateData: ContractEmailDynamicData }): Promise { const templateId = this.translator.get(language, 'email_templates.subscription_contract') return this.mailService.send({ to: email, templateId, dynamicTemplateData, attachments: [ { content: pdf, filename: 'contrato_smart_fit_nutri.pdf', type: 'application/pdf', }, ], }) } private upload(patientId: string, subscriptionId: string, pdf: Buffer): Promise { return this.storageService.upload(this.makeStorageFilePath(patientId, subscriptionId), pdf, 'application/pdf') } private makeStorageFilePath(patientId: string, subscriptionId: string): string { return `users/${patientId}/contracts/contract_${subscriptionId}.pdf` } }