Files
monorepo/LCU.API.Collections.RepoApi-old/LCU.API.Collections.RepoApi/Services/Emailer.cs
T
2026-04-20 14:47:24 -05:00

204 lines
8.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using LCU.API.Collections.RepoApi.Configuration;
using LCU.Shared.Collections.RepoApiLib.Models;
using LCU.Shared.Collections.RepoApiLib.Models.AutoIms;
using LCU.Shared.Collections.RepoApiLib.Models.Consumer;
using LCU.Shared.Common.NotificationApiLib.Models;
using Microsoft.EntityFrameworkCore.Internal;
using Newtonsoft.Json;
using Serilog;
namespace LCU.API.Collections.RepoApi.Services
{
public class Emailer : IEmailer
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly RepoApiConfiguration _configuration;
private readonly IEventAlertService _eventAlertService;
private const string O4RStatus = "O4R";
public Emailer(IHttpClientFactory httpClientFactory, RepoApiConfiguration configuration, IEventAlertService eventAlertService)
{
_httpClientFactory = httpClientFactory;
_configuration = configuration;
_eventAlertService = eventAlertService;
}
public async Task<HttpResponseMessage> SendMessageAsync(List<string> recipient, string subject, string body)
{
var emailRequest = new EmailRequest
{
Recipient = recipient,
Subject = subject,
Body = body
};
var encoded = JsonConvert.SerializeObject(emailRequest);
try
{
var client = _httpClientFactory.CreateClient();
var c = new StringContent(encoded, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(_configuration.NotificationsEmailUrl, c);
response.EnsureSuccessStatusCode();
return response;
}
catch (Exception ex)
{
Log.Error(ex, "An exception was caught trying to send an email via Notifications API.");
return null;
}
}
public async Task<HttpResponseMessage> SendFloorPriceAcceptedEmail(bool isManual, string accountNo, decimal? oldFloorPrice, decimal? newFloorPrice)
{
var subject = isManual ? "Manual Floor Price Set" : "Automated Floor Price Set";
var body = string.Format(subject + " for account {0} from {1} to {2}.", accountNo, oldFloorPrice?.ToString("C2", CultureInfo.CurrentCulture), newFloorPrice?.ToString("C2", CultureInfo.CurrentCulture));
return await SendMessageAsync(_configuration.FloorPriceAcceptedRecipients, subject, body);
}
public async Task<HttpResponseMessage> SendSurplusDeficiencyLetterEmailAsync(RepoAccount repoAccount)
{
var message = "Please Send the Surplus Deficiency letter. Please notify the Repo Specialists when the letter has been sent, so that this account can be closed in Repo Manager.<br/><br/>";
var member = repoAccount.Borrowers?.First(b => b.OwnershipType == 6);
var memberName = "Member Name: " + member?.IndividualName + "<br/>";
var accountNo = "Account No: " + repoAccount.AccountNo + "<br/>";
return await SendMessageAsync(_configuration.CollectionsClerkRecipients, "Refunds Recieved", string.Concat(message, memberName, accountNo));
}
public async Task<HttpResponseMessage> MaybeSendO4rNoCollateralEmail(RepoAccount repoAccount)
{
if (repoAccount != null && repoAccount.DateClosed == null && repoAccount.Status == O4RStatus)
{
var subject = "O4R No Collateral";
var body = string.Format("Account {0} set to O4R with no collateral.", repoAccount.AccountNo);
return await SendMessageAsync(_configuration.RepoManagerAdminRecipients, subject, body);
}
return new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
}
public async Task<HttpResponseMessage> SendAlertSummaryEmailWithEndTime(DateTime endTime)
{
var startTime = endTime.AddHours(-1);
var eventAlerts = _eventAlertService.ListWithinDateRange(startTime, endTime).GetAwaiter().GetResult();
var subject = "Repo Manager Alerts " + endTime.ToString("MM-dd-yyyy HH:mm:ss");
var body = "<h2>" + subject + "</h2><br/>";
foreach (var eventAlert in eventAlerts)
{
var entry = CreateAlertEmailEntry(eventAlert);
if (!string.IsNullOrEmpty(entry))
{
body += CreateAlertEmailEntry(eventAlert) + "<br/><br/>";
}
}
if (!eventAlerts.Any())
{
body += "No new alerts.";
}
return await SendMessageAsync(_configuration.CollectionsRecipients, subject, body);
}
private string CreateAlertEmailEntry(EventAlert eventAlert)
{
var accountNo = "Account No: " + eventAlert.AccountNo + "<br/>";
var alert = "Alert: " + eventAlert.Message + "<br/>";
var url = eventAlert.RepoId != null
? _configuration.RepoManagerAccountUrl + eventAlert.RepoId
: "";
var link = eventAlert.RepoId != null
? string.Format("<a href={0}>{0}</a>", url) + "<br/>"
: "";
return string.Concat(accountNo, alert, link);
}
public void SendSummaryEmail(IReadOnlyCollection<ImportResultRow> imported, IReadOnlyCollection<ImportResultRow> floors)
{
Log.Debug("Sending AutoIMS Import Email");
var subject = "Landmark Auto IMS Import " + DateTime.Now;
var reports = new List<string>();
if (imported == null || floors == null)
{
Log.Error("Null result sets passed to SendSummaryEmail");
return;
}
foreach (var importResultRow in imported)
{
reports.Add(importResultRow.BuildStatusReport(_configuration.RepoManagerAccountUrl));
reports.Add("=====================================================================================================<br/>");
}
foreach (var importResultRow in floors)
{
reports.Add(importResultRow.BuildStatusReport(_configuration.RepoManagerAccountUrl));
}
var result = reports.Join("<br/>");
SendMessageAsync(_configuration.CreditDebitsRecipients, subject, result).GetAwaiter().GetResult();
Log.Debug("AutoIMS Import Email Sent");
}
public void SendRefundProcessStartEmails(IReadOnlyCollection<ImportResultRow> models)
{
if (models == null || !models.Any())
{
Log.Warning("No models to process sold emails for.");
return;
}
var soldResults = models.Where(x => x.Data?.SoldDate?.Date == DateTime.Now.Date).ToList();
foreach (var sale in soldResults)
{
SendMessageAsync(_configuration.CollectionsClerkRecipients, "Auction sold, please start the refund process", CreateRefundProcessEmailBody(sale)).GetAwaiter().GetResult();
}
}
public string CreateRefundProcessEmailBody(ImportResultRow sale)
{
if (sale?.RepoAccount == null || sale.Data == null || sale.RepoAccount.Borrowers == null)
{
Log.Error("Invalid data, can't create email body for account.");
return "";
}
var member = sale.RepoAccount.Borrowers?.First(b => b.OwnershipType == 6);
var individualName = member != null ? member.IndividualName : "No Primary Owner!";
var memberName = "Member Name: " + individualName + "<br/>";
var accountNo = "Account No: " + sale.RepoAccount.AccountNo + "<br/>";
var collateralVin = "VIN: " + sale.Data.VIN + "<br/>";
return string.Concat(memberName, accountNo, collateralVin);
}
public async Task<HttpResponseMessage> SendProccessSummary(RepoRunInfo runInfo)
{
string subject = $"Repo Processor Run Receipt [{runInfo.Receipts.Count}]";
var receiptList = runInfo.Receipts.Select(receipt => receipt.Pretty());
string bodyData = string.Join("<br/>", receiptList);
string body = $"Process Started: {runInfo.StartDateTime} and completed at {runInfo.CompleteDateTime}<br/><br/>";
return await SendMessageAsync(_configuration.RepoManagerAdminRecipients, subject, body + bodyData);
}
}
}