import { Injectable } from '@nestjs/common' import { plainToClass } from 'class-transformer' import { chunk, compact, isEmpty, isNil, omitBy } from 'lodash' import { RequiredArgumentError } from '../../../errors' import { BioimpedanceImportation, Patient } from '../../../models' import { CampaignMessageRepository } from '../../../repositories/campaign_message.repository' import { PatientRepository } from '../../../repositories/patient.repository' import { LanguageCountryCode } from '../../../utils/countries' import { AwsService } from '../../aws/aws.service' import { TranslateNotificationServiceHelper } from '../i18n' import { NotificationService } from '../notification.service' import { Notification, NotificationType } from '../types' export type GetMessageArgs = { patient_id: string device_id: string document_number: string country_code: LanguageCountryCode cell_phone: string email: string type: NotificationType bioimpedance_importation_id?: string } @Injectable() export class BioimpedanceNotificationService { constructor( private readonly notificationService: NotificationService, private readonly awsService: AwsService, private readonly campaignMessageRepository: CampaignMessageRepository, private readonly patientRepository: PatientRepository, private readonly translator: TranslateNotificationServiceHelper, ) {} async sendNotificatonForBioImports( bioimpedanceImportations: Array, countryCode: LanguageCountryCode, ): Promise { const chunked = chunk(bioimpedanceImportations, 5) for (const bioimpedances of chunked) { const patients = await Promise.all( bioimpedances.map(async (bioimpedanceImportation: BioimpedanceImportation) => this.sendNotification(bioimpedanceImportation, countryCode), ), ) const patientsWithDevice = compact( patients.map((patient: Partial) => !isNil(patient?.device_id) && !isEmpty(patient?.device_id) ? patient.id : null, ), ) if (patientsWithDevice.length > 0) await this.campaignMessageRepository.scheduleCheckPushConversion(patientsWithDevice) } } async send(patient: Patient, bioimpedanceImportationId?: string, type?: NotificationType): Promise { this.validatePatient(patient) if (!type) type = patient.device_id ? 'bio_importation_push' : 'bio_importation_sms' const message = this.getMessageToPrepare({ patient_id: patient.id, device_id: patient.device_id, document_number: patient.document_number, country_code: patient.country_code as LanguageCountryCode, cell_phone: patient.cell_phone, email: patient.email, bioimpedance_importation_id: bioimpedanceImportationId, type, }) await this.awsService.sendSQS(this.notificationService.prepareMessage(message)) } private async sendNotification( bioimpedanceImportation: BioimpedanceImportation, countryCode: LanguageCountryCode, ): Promise<{ id: string; device_id: string }> { const login = bioimpedanceImportation[Patient.loginField(countryCode)] let patient = await this.patientRepository.findByLogin(login, countryCode) if (!patient) patient = plainToClass(Patient, { ...bioimpedanceImportation, country_code: countryCode, id: null }) if (patient.country_code === LanguageCountryCode.ES_DO) await this.send(patient, bioimpedanceImportation.id, 'bio_importation_email') else await this.send(patient) return { id: patient?.id, device_id: patient?.device_id } } private validatePatient(patient: Patient): void { if (!patient.country_code) throw new RequiredArgumentError('country_code') if (!patient.document_number && !patient.email) throw new RequiredArgumentError(Patient.loginField(patient.country_code)) } private getMessageToPrepare({ patient_id, device_id, document_number, country_code, cell_phone, email, bioimpedance_importation_id, type, }: GetMessageArgs): Notification { const additional_data = omitBy( { document_number, email, patient_id, device_id, country_code, cell_phone, bioimpedance_importation_id, }, isNil, ) const messageType = type === 'bio_importation_push' ? 'pushes' : 'sms' const msg = this.translator.get(country_code, `${messageType}.bio_import.message` as any) return { DelaySeconds: 0, title: '', type, msg, additional_data, } as Notification } }