first commit

This commit is contained in:
Zeeshaun
2026-03-11 11:18:25 -05:00
commit f3cb730f3b
472 changed files with 53651 additions and 0 deletions
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Landmark.OLA.Application.Controllers;
using Landmark.OLA.Models.Core;
namespace Landmark.OLA.Application.Services
{
public class CoreAccessService
{
public CoreMemberOwner FindMatchingOwner(OnlineIdentityFormData document, List<CoreMemberOwner> owners)
{
if (owners != null && owners.Count != 0 && document != null)
{
foreach (var owner in owners)
{
if (DoesOwnerMatch(owner, document))
{
return owner;
}
}
}
return null;
}
// Expects birthdate in form YYYY-MM-DD and taxid in form ###-##-####
// Expects dob in form MM/DD/YYYY and ssn in form #### (last 4)
// Tries to match this owner and this document.
public bool DoesOwnerMatch(CoreMemberOwner owner, OnlineIdentityFormData document)
{
if (string.IsNullOrEmpty(owner.BirthDate) || owner.TaxId == null || owner.TaxId.Length != 11)
{
return false;
}
if (owner.TaxId.Substring(7) != document.SocialSecurityNumber)
{
return false;
}
string[] formats = { "MM/dd/yyyy", "yyyy-MM-dd" };
var dobEntered = DateTime.ParseExact(document.DateOfBirth, formats, new CultureInfo("en-US"), DateTimeStyles.None);
var dobDesired = DateTime.ParseExact(owner.BirthDate, formats, new CultureInfo("en-US"), DateTimeStyles.None);
return dobEntered == dobDesired;
}
}
}
@@ -0,0 +1,34 @@
using System;
using System.Threading.Tasks;
using Serilog;
using Newtonsoft.Json;
using Landmark.OLA.Models.Core;
using LCU.Library.Internal.LcuHttpClient.HttpRequest;
namespace Landmark.OLA.Application.Services
{
public class CoreService : ICoreService
{
private readonly IGetRequest _getRequest;
public CoreService(IGetRequest getRequest)
{
_getRequest = getRequest;
}
public async Task<CoreIndividual> GetIndividual(string individualId)
{
try
{
var uri = new Uri($"core/individuals?userId={individualId}");
var responseString = await _getRequest.StringResponseAsync(uri);
return JsonConvert.DeserializeObject<CoreIndividual>(responseString);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure to get Individual for IndividualId: {individualId} in {GetType().Name}");
return null;
}
}
}
}
@@ -0,0 +1,9 @@
namespace Landmark.OLA.Application.Services
{
public class CoreSettings
{
public string EndPoint { get; set; }
public int Timeout { get; set; }
}
}
@@ -0,0 +1,113 @@
using System;
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Serilog;
namespace Landmark.OLA.Application.Services.Email
{
public class EmailTemplateService : IEmailTemplateService
{
private readonly string _embeddedLogoBase64;
public EmailTemplateService(IWebHostEnvironment webHostEnvironment)
{
_embeddedLogoBase64 = LoadEmbeddedLogo(webHostEnvironment);
}
private static string LoadEmbeddedLogo(IWebHostEnvironment webHostEnvironment)
{
if (webHostEnvironment == null)
{
return string.Empty;
}
try
{
var logoPath = Path.Combine(webHostEnvironment.ContentRootPath, "Files", "Logo.png");
if (!File.Exists(logoPath))
{
Log.Warning("Logo not found at {LogoPath}. Email will fall back to remote image.", logoPath);
return string.Empty;
}
var bytes = File.ReadAllBytes(logoPath);
return Convert.ToBase64String(bytes);
}
catch (Exception ex)
{
Log.Warning(ex, "Failed to embed logo from file.");
return string.Empty;
}
}
public string BuildBrandedBody(string contentHtml, string redBannerMessage = "")
{
var topLogoTag = $"<img src=\"data:image/png;base64,{_embeddedLogoBase64}\" width=\"225\" height=\"62\" style=\"width: 225px; height: 62px\">";
var bottomLogoTag = $"<img src=\"data:image/png;base64,{_embeddedLogoBase64}\" alt=\"Landmark Credit Union Logo\" height=\"37\" width=\"135\" style=\"width: 180px; max-height: 50px;\">";
redBannerMessage ??= string.Empty;
var bannerHtml = string.IsNullOrWhiteSpace(redBannerMessage)
? string.Empty
:
"<div class=\"red-banner\">" +
"<span style=\"background-color: #FF0000; color: #FFFFFF; font-weight: bold; display: inline-block; padding: 4px 8px;\">" +
redBannerMessage +
"</span><br><br>" +
"</div>";
var requestBody =
"<html>" +
"<body>" +
"<table align=\"center\" width=\"87%\" style=\"margin: auto;\">" +
"<tbody>" +
"<tr height=\"50\"></tr>" +
"<tr>" +
"<td align=\"center\" style=\"margin: auto; width: 250px\">" +
topLogoTag +
"</td>" +
"</tr>" +
"<tr height=\"30\"></tr>" +
"</tbody>" +
"</table>" +
"<table align=\"center\" width=\"87%\" style=\"margin: auto; color: #005674\">" +
"<tbody>" +
"<tr>" +
"<td style=\"font-size: 75%; font-family: Verdana; padding-top: 10px;\">" +
bannerHtml +
contentHtml +
"</td>" +
"</tr>" +
"<tr height=\"50\"></tr>" +
"</tbody>" +
"</table>" +
"<table style=\"text-align: center; color: #888; mso-color-alt: #888; font-size: 70%; background-color: #eee; width: 100%; position: absolute; bottom: 0; margin: auto;\" align=\"center\">" +
"<tbody>" +
"<tr>" +
"<td height=\"15\" colspan=\"4\">&nbsp;</td>" +
"</tr>" +
"<tr>" +
"<td height=\"100\" width=\"6.5%\">&nbsp;</td>" +
"<td height=\"100\" width=\"15%\">" +
"<div style=\"padding-right: 15px;\">" +
"<div style=\"margin: auto; display: flex; justify-content: center; align-items: center;\">" +
bottomLogoTag +
"</div>" +
"</div>" +
"</td>" +
"<td align=\"left\" style=\"padding-left: 25px; font-style: italic;\">" +
"</td>" +
"<td width=\"6.5%\">&nbsp;</td>" +
"</tr>" +
"<tr>" +
"<td height=\"15\" colspan=\"4\">&nbsp;</td>" +
"</tr>" +
"</tbody>" +
"</table>" +
"</body>" +
"</html>";
return requestBody;
}
}
}
@@ -0,0 +1,10 @@
using Microsoft.AspNetCore.Hosting;
namespace Landmark.OLA.Application.Services.Email
{
public interface IEmailTemplateService
{
string BuildBrandedBody(string contentHtml, string redBannerMessage = "");
}
}
@@ -0,0 +1,12 @@
using System;
using System.Net.Http;
namespace Landmark.OLA.Application.Services.Exceptions
{
public class CoreUnavailableException : Exception
{
public CoreUnavailableException(HttpRequestException hre): base(hre.Message, hre)
{
}
}
}
@@ -0,0 +1,10 @@
using System.Threading.Tasks;
using Landmark.OLA.Models.Core;
namespace Landmark.OLA.Application.Services
{
public interface ICoreService
{
Task<CoreIndividual> GetIndividual(string individualId);
}
}
@@ -0,0 +1,8 @@
namespace Landmark.OLA.Application.Services
{
public interface IPdfService
{
byte[] GetFileBytes(string path);
}
}
@@ -0,0 +1,10 @@
using System.Threading.Tasks;
using LCU.Library.Internal.NotificationsModels.Models;
namespace Landmark.OLA.Application.Services.MicroApiServices
{
public interface INotificationsApiService
{
Task SendEmailAsync(EmailRequest request);
}
}
@@ -0,0 +1,32 @@
using Serilog;
using System;
using System.Threading.Tasks;
using Landmark.OLA.Application.DataAccess;
using LCU.Library.Internal.NotificationsModels.Models;
namespace Landmark.OLA.Application.Services.MicroApiServices
{
public class NotificationsApiService : INotificationsApiService
{
private readonly INotificationDao _notificationsApiDao;
public NotificationsApiService(INotificationDao notificationsApiDao)
{
_notificationsApiDao = notificationsApiDao;
}
public async Task SendEmailAsync(EmailRequest request)
{
try
{
await _notificationsApiDao.SendEmailAsync(request);
}
catch (Exception exception)
{
var error = $"Failure during SendEmailAsync. Exception Message: {exception.Message}";
Log.Error(error);
throw new Exception(error);
}
}
}
}
@@ -0,0 +1,18 @@
using System;
using System.IO;
namespace Landmark.OLA.Application.Services
{
public class PdfService : IPdfService
{
public byte[] GetFileBytes(string path)
{
if (!string.IsNullOrWhiteSpace(path) && File.Exists(path))
{
return File.ReadAllBytes(path);
}
throw new ArgumentException($"Path {path} must exist.");
}
}
}