import { Injectable } from '@angular/core'; import { TimeZoneService } from '@core/services/time-zone.service'; import { environment } from '@environment'; import { EmailResources } from '@features/system-emails/email.resources'; import { EmailService } from '@features/system-emails/email.service'; import { EmailNotificationType, EmailStatus } from '@features/system-emails/email.typing'; import { ExportEmailService } from '@features/system-emails/export-emails/export-emails.service'; import { FileService, YcFile } from '@yourcause/common'; import { I18nService } from '@yourcause/common/i18n'; import { LogService } from '@yourcause/common/logging'; import { NotifierService } from '@yourcause/common/notifier'; import { AttachYCState, BaseYCService } from '@yourcause/common/state'; import moment from 'moment'; import { CommunicationsResources } from './communications.resources'; import { CommunicationsState } from './communications.state'; import { ApplicationAPICommunication, Communication, CommunicationsByDate, CommunicationTypes, OrganizationAPICommunication, SimpleCommunication, SimpleEmail } from './communications.typing'; @AttachYCState(CommunicationsState) @Injectable({ providedIn: 'root' }) export class CommunicationsService extends BaseYCService { constructor ( private logger: LogService, private i18n: I18nService, private communicationResources: CommunicationsResources, private emailResources: EmailResources, private notifier: NotifierService, private fileService: FileService, private timezoneService: TimeZoneService, private emailService: EmailService, private exportEmailService: ExportEmailService ) { super(); } get applicationCommunicationsMap () { return this.get('applicationCommunicationsMap'); } get nonprofitCommunicationsMap () { return this.get('nonprofitCommunicationsMap'); } async adaptCommunicationToApplicantCommunication ( comm: Communication, applicationId: number ): Promise { return { [ comm.joinCommunicationId ? 'applicationCommunicationsId' : 'applicationCommunicationId' ]: comm.joinCommunicationId, applicationId, type: comm.type, content: comm.content, visibility: comm.visibility, subject: comm.subject, date: comm.date, publishToNonprofit: comm.publishToNonprofit, fileUploadIds: comm.files.map((file) => file.fileUploadId) }; } async adaptCommunicationToNonprofitCommunication ( comm: Communication, organizationId: number ): Promise { return { organizationCommunicationsId: comm.joinCommunicationId, organizationId, type: comm.type, content: comm.content, visibility: comm.visibility, subject: comm.subject, date: comm.date, fileUploadIds: comm.files.map((file) => file.fileUploadId) }; } getFileUploadIdForSaveCommunication (request: YcFile) { return this.communicationResources.uploadCommunicationFile( request ); } async handleMultipleCommFileUploads (fileRequests: YcFile[]) { try { const requests = fileRequests.filter(request => { return !request?.canceled; }); const filesResponse = await Promise.all(requests.map(async (fileRequest: YcFile) => { const fileUploadId = await this.getFileUploadIdForSaveCommunication( fileRequest ); return { fileUploadId, fileName: fileRequest.fileName }; })); return filesResponse; } catch (e) { this.logger.error(e); this.notifier.error(this.i18n.translate( 'common:textErrorUploadingFileds', {}, 'There was an error uploading the file(s)' )); return null; } } adaptSimpleCommunication ( communication: SimpleCommunication, isManual = false ): Communication { return { communicationId: communication.communicationId, joinCommunicationId: 'applicationCommunicationId' in communication ? communication.applicationCommunicationId : communication.organizationCommunicationId, type: communication.type, subject: communication.subject, date: communication.date, updatedDate: communication.updatedDate, fileName: communication.fileName, content: '', createdBy: communication.createdBy, updatedBy: communication.updatedBy, isManual, visibility: communication.visibility, emailNotificationType: communication.emailNotificationType, files: communication.files }; } sortCommunications ( communicationsByDate: CommunicationsByDate[] ): Communication[][] { return communicationsByDate.sort((comm1, comm2) => { if (moment(comm1.date).isAfter(comm2.date)) { return -1; } else if (comm1.date === comm2.date) { return 0; } else { return 1; } }).map((comm) => { return comm.communications; }); } stripExtraText (text: string) { const commentReplacement = /\/\*.*\*\//gm; const styleReplacement = /