using AutoMapper; using DigitalData.Core.DTO; using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts; using DigitalData.EmailProfilerDispatcher.Abstraction.DTOs.EmailOut; using DigitalData.EmailProfilerDispatcher.Abstraction.Services; using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiver; using EnvelopeGenerator.Common; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using static EnvelopeGenerator.Common.Constants; using EnvelopeGenerator.Extensions; using EnvelopeGenerator.Application.DTOs.EnvelopeReceiverReadOnly; using EnvelopeGenerator.Application.Configurations; using Newtonsoft.Json.Linq; namespace EnvelopeGenerator.Application.Services { public class EnvelopeMailService : EmailOutService, IEnvelopeMailService { private readonly IEmailTemplateService _tempService; private readonly IEnvelopeReceiverService _envRcvService; private readonly DispatcherConfig _dConfig; private readonly IConfigService _configService; private readonly Dictionary _placeholders; public EnvelopeMailService(IEmailOutRepository repository, IMapper mapper, IEmailTemplateService tempService, IEnvelopeReceiverService envelopeReceiverService, IOptions dispatcherConfigOptions, IConfigService configService, IOptions mailConfig) : base(repository, mapper) { _tempService = tempService; _envRcvService = envelopeReceiverService; _dConfig = dispatcherConfigOptions.Value; _configService = configService; _placeholders = mailConfig.Value.Placeholders; } private async Task> CreatePlaceholders(string? accessCode = null, EnvelopeReceiverDto? envelopeReceiverDto = null) { if (accessCode is not null) _placeholders["[DOCUMENT_ACCESS_CODE]"] = accessCode; if(envelopeReceiverDto?.Envelope is not null && envelopeReceiverDto.Receiver is not null) { var erId = (envelopeReceiverDto.Envelope.Uuid, envelopeReceiverDto.Receiver.Signature).EncodeEnvelopeReceiverId(); var sigHost = await _configService.ReadDefaultSignatureHost(); var linkToDoc = $"{sigHost}/EnvelopeKey/{erId}"; _placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc; _placeholders["[LINK_TO_DOCUMENT_TEXT]"] = linkToDoc[..Math.Min(40, linkToDoc.Length)] + ".."; } return _placeholders; } private async Task> CreatePlaceholders(EnvelopeReceiverReadOnlyDto? readOnlyDto = null) { if (readOnlyDto?.Envelope is not null && readOnlyDto.Receiver is not null) { _placeholders["[NAME_RECEIVER]"] = await _envRcvService.ReadLastUsedReceiverNameByMail(readOnlyDto.AddedWho).ThenAsync(res => res, (msg, ntc) => string.Empty) ?? string.Empty; var erReadOnlyId = (readOnlyDto.Id).EncodeEnvelopeReceiverId(); var sigHost = await _configService.ReadDefaultSignatureHost(); var linkToDoc = $"{sigHost}/EnvelopeKey/{erReadOnlyId}"; _placeholders["[LINK_TO_DOCUMENT]"] = linkToDoc; _placeholders["[LINK_TO_DOCUMENT_TEXT]"] = linkToDoc[..Math.Min(40, linkToDoc.Length)] + ".."; } return _placeholders; } public async Task> SendAccessCodeAsync(EnvelopeReceiverDto dto) => await SendAsync(dto: dto, tempType: EmailTemplateType.DocumentAccessCodeReceived); public async Task> SendAsync(EnvelopeReceiverDto dto, EmailTemplateType tempType, Dictionary? optionalPlaceholders = null) { var tempSerResult = await _tempService.ReadByNameAsync(tempType); if (tempSerResult.IsFailed) return tempSerResult.ToFail().Notice(LogLevel.Error, Flag.DataIntegrityIssue, $"The email cannot send because '{tempType}' template cannot found."); var temp = tempSerResult.Data; var mail = new EmailOutCreateDto() { EmailAddress = dto.Receiver!.EmailAddress, EmailSubj = temp.Subject, EmailBody = temp.Body, //email_type = envelope_status, //message = envelope_message, ReferenceId = dto.EnvelopeId, //REFERENCE_ID = ENVELOPE_ID ReferenceString = dto!.Envelope!.Uuid, //REFERENCE_STRING = ENVELOPE_UUID //receiver_name = receiver.name, //receiver_access_code = receiver.access_code, //sender_adress = envelope.user.email, //sender_name = envelope.user.full_name, //envelope_title = envelope.title, ReminderTypeId = _dConfig.ReminderTypeId, SendingProfile = _dConfig.SendingProfile, EntityId = null, WfId = (int) EnvelopeStatus.MessageAccessCodeSent, WfReference = null, AddedWho = _dConfig.AddedWho, EmailAttmt1 = _dConfig.EmailAttmt1 }; //get acccess code var acResult = await _envRcvService.ReadAccessCodeByIdAsync(envelopeId: dto.EnvelopeId, receiverId: dto.ReceiverId); if (acResult.IsFailed) return acResult.ToFail().Notice(LogLevel.Error, "Therefore, access code cannot be sent"); var accessCode = acResult.Data; var placeholders = await CreatePlaceholders(accessCode: accessCode, envelopeReceiverDto: dto); // Add optional place holders. if (optionalPlaceholders is not null) foreach (var oph in optionalPlaceholders) placeholders[oph.Key] = oph.Value.ToString() ?? "NULL"; //TODO: remove the requirement to add the models using reflections return await CreateWithTemplateAsync(createDto: mail,placeholders: placeholders, dto, dto.Envelope.User!, dto.Envelope); } public async Task> SendAsync(EnvelopeReceiverReadOnlyDto dto, Dictionary? optionalPlaceholders = null) { var tempSerResult = await _tempService.ReadByNameAsync(EmailTemplateType.DocumentShared); if (tempSerResult.IsFailed) return tempSerResult.ToFail().Notice(LogLevel.Error, Flag.DataIntegrityIssue, $"The email cannot send because '{Constants.EmailTemplateType.DocumentShared}' template cannot found."); var temp = tempSerResult.Data; var mail = new EmailOutCreateDto() { EmailAddress = dto.ReceiverMail, EmailSubj = temp.Subject, EmailBody = temp.Body, //TODO: remove int casting when all ReferenceId = (int) dto.EnvelopeId, //REFERENCE_ID = ENVELOPE_ID ReferenceString = dto.Envelope!.Uuid, //REFERENCE_STRING = ENVELOPE_UUID //receiver_name = receiver.name, //receiver_access_code = receiver.access_code, //sender_adress = envelope.user.email, //sender_name = envelope.user.full_name, //envelope_title = envelope.title, ReminderTypeId = _dConfig.ReminderTypeId, SendingProfile = _dConfig.SendingProfile, EntityId = null, WfId = (int)EnvelopeStatus.EnvelopeShared, WfReference = null, AddedWho = _dConfig.AddedWho, EmailAttmt1 = _dConfig.EmailAttmt1 }; var placeholders = await CreatePlaceholders(readOnlyDto: dto); // Add optional place holders. if (optionalPlaceholders is not null) foreach (var oph in optionalPlaceholders) placeholders[oph.Key] = oph.Value.ToString() ?? "NULL"; return await CreateWithTemplateAsync(createDto: mail, placeholders: placeholders, dto.Envelope); } } }