using System.Net; using System.Net.Mail; using System.Text; using MesaFabApproval.Shared.Models; using Microsoft.Extensions.Caching.Memory; namespace MesaFabApproval.API.Services; public interface IMRBService { Task> GetAllMRBs(); Task GetMRBById(int id); Task GetMRBByTitle(string title, bool bypassCache); Task CreateNewMRB(MRB mrb); Task UpdateMRB(MRB mrb); Task CreateMRBAction(MRBAction mrbAction); Task> GetMRBActionsForMRB(int mrbNumber, bool bypassCache); Task UpdateMRBAction(MRBAction mrbAction); Task DeleteMRBAction(int mrbActionID, int mrbNumber); Task> UploadAttachments(IEnumerable files, int mrbNumber); Task> GetAllAttachmentsForMRB(int mrbNumber, bool bypassCache); Task DeleteAttachment(MRBAttachment attachment); Task NotifyNewApprovals(MRB mrb); Task NotifyApprovers(MRBNotification notification); Task NotifyOriginator(MRBNotification notification); } public class MRBService : IMRBService { private readonly ILogger _logger; private readonly IDalService _dalService; private readonly IMemoryCache _cache; private readonly IUserService _userService; private readonly IApprovalService _approvalService; private readonly ISmtpService _smtpService; private readonly string _siteBaseUrl; private readonly string _mrbAttachmentPath; public MRBService(ILogger logger, IDalService dalService, IMemoryCache cache, IUserService userService, IApprovalService approvalService, ISmtpService smtpService) { _logger = logger ?? throw new ArgumentNullException("ILogger not injected"); _dalService = dalService ?? throw new ArgumentNullException("IDalService not injected"); _cache = cache ?? throw new ArgumentNullException("IMemoryCache not injected"); _userService = userService ?? throw new ArgumentNullException("IUserService not injected"); _approvalService = approvalService ?? throw new ArgumentNullException("IApprovalService not injected"); _smtpService = smtpService ?? throw new ArgumentNullException("ISmtpService not injected"); _siteBaseUrl = Environment.GetEnvironmentVariable("NewFabApprovalBaseUrl") ?? throw new ArgumentNullException("FabApprovalBaseUrl environment variable not found"); _mrbAttachmentPath = Environment.GetEnvironmentVariable("FabApprovalMrbAttachmentPath") ?? throw new ArgumentNullException("FabApprovalMrbAttachmentPath environment variable not found"); } public async Task CreateNewMRB(MRB mrb) { try { _logger.LogInformation("Attempting to generate new MRB"); if (mrb is null) throw new ArgumentNullException("MRB cannot be null"); StringBuilder queryBuilder = new(); queryBuilder.Append("insert into MRB (OriginatorID, Title, "); if (mrb.SubmittedDate > DateTime.MinValue) queryBuilder.Append("SubmittedDate, "); if (mrb.CloseDate < DateTime.MaxValue) queryBuilder.Append("CloseDate, "); if (mrb.CancelDate < DateTime.MaxValue) queryBuilder.Append("CancelDate, "); queryBuilder.Append("NumberOfLotsAffected, "); if (mrb.ApprovalDate < DateTime.MaxValue) queryBuilder.Append("ApprovalDate, "); queryBuilder.Append("IssueDescription, CustomerImpacted, Department, Process, Val, RMANo, "); queryBuilder.Append("PCRBNo, SpecsImpacted, TrainingRequired, Status, StageNo) values ("); queryBuilder.Append($"{mrb.OriginatorID}, '{mrb.Title}', "); if (mrb.SubmittedDate > DateTime.MinValue) queryBuilder.Append($"'{mrb.SubmittedDate.ToString("yyyy-MM-dd HH:mm:ss")}', "); if (mrb.CloseDate < DateTime.MaxValue) queryBuilder.Append($"'{mrb.CloseDate.ToString("yyyy-MM-dd HH:mm:ss")}', "); if (mrb.CancelDate < DateTime.MaxValue) queryBuilder.Append($"'{mrb.CancelDate.ToString("yyyy-MM-dd HH:mm:ss")}', "); queryBuilder.Append($"{mrb.NumberOfLotsAffected}, "); if (mrb.ApprovalDate < DateTime.MaxValue) queryBuilder.Append($"'{mrb.ApprovalDate.ToString("yyyy-MM-dd HH:mm:ss")}', "); queryBuilder.Append($"'{mrb.IssueDescription}', {Convert.ToUInt32(mrb.CustomerImpacted)}, "); queryBuilder.Append($"'{mrb.Department}', '{mrb.Process}', '{mrb.Val}', {mrb.RMANo}, {mrb.PCRBNo}, "); queryBuilder.Append($"{Convert.ToInt32(mrb.SpecsImpacted)}, {Convert.ToInt32(mrb.TrainingRequired)}, "); queryBuilder.Append($"'{mrb.Status}', {mrb.StageNo});"); int rowsCreated = await _dalService.ExecuteAsync(queryBuilder.ToString()); if (rowsCreated <= 0) throw new Exception("Unable to create new MRB"); mrb = await GetMRBByTitle(mrb.Title, true); _cache.Set($"mrb{mrb.MRBNumber}", mrb, DateTimeOffset.Now.AddHours(1)); _cache.Set($"mrb{mrb.Title}", mrb, DateTimeOffset.Now.AddHours(1)); IEnumerable? allMrbs = _cache.Get>("allMrbs"); if (allMrbs is not null) { List mrbList = allMrbs.ToList(); mrbList.Add(mrb); _cache.Set("allMrbs", mrbList, DateTimeOffset.Now.AddHours(1)); } } catch (Exception ex) { _logger.LogError($"An exception occurred when attempting to create new MRB. Exception: {ex.Message}"); throw; } } public async Task> GetAllMRBs() { try { _logger.LogInformation("Attempting to get all MRBs"); IEnumerable? allMrbs = _cache.Get>("allMrbs"); if (allMrbs is null) { StringBuilder queryBuilder = new(); queryBuilder.Append("select (u.FirstName + ' ' + u.LastName) as OriginatorName, m.* "); queryBuilder.Append("from MRB m join Users u on m.OriginatorID = u.UserID;"); allMrbs = (await _dalService.QueryAsync(queryBuilder.ToString())).ToList(); _cache.Set("allMrbs", allMrbs, DateTimeOffset.Now.AddHours(1)); } if (allMrbs is null || allMrbs.Count() == 0) throw new Exception("No MRBs found"); return allMrbs; } catch (Exception ex) { _logger.LogError($"An exception occurred when attempting to get all MRBs. Exception: {ex.Message}"); throw; } } public async Task GetMRBById(int id) { try { _logger.LogInformation("Attempting to get an MRB by ID"); if (id < 0) throw new ArgumentException("Invalid MRB number"); MRB? mrb = _cache.Get($"mrb{id}"); if (mrb is null) { StringBuilder queryBuilder = new(); queryBuilder.Append("select (u.FirstName + ' ' + u.LastName) as OriginatorName, m.* "); queryBuilder.Append("from MRB m join Users u on m.OriginatorID = u.UserID "); queryBuilder.Append($"where m.MRBNumber = {id}"); mrb = (await _dalService.QueryAsync(queryBuilder.ToString())).FirstOrDefault(); _cache.Set($"mrb{id}", mrb, DateTimeOffset.Now.AddHours(1)); } if (mrb is null) throw new Exception($"Unable to get MRB {id}"); return mrb; } catch (Exception ex) { _logger.LogError($"An exception occurred when attempting to get an MRB. Exception: {ex.Message}"); throw; } } public async Task GetMRBByTitle(string title, bool bypassCache) { try { _logger.LogInformation("Attempting to get an MRB by title"); if (string.IsNullOrWhiteSpace(title)) throw new ArgumentException("Title cannot be null or emtpy"); MRB? mrb = null; if (!bypassCache) mrb = _cache.Get($"mrb{title}"); if (mrb is null) { StringBuilder queryBuilder = new(); queryBuilder.Append("select (u.FirstName + ' ' + u.LastName) as OriginatorName, m.* "); queryBuilder.Append("from MRB m join Users u on m.OriginatorID = u.UserID "); queryBuilder.Append($"where m.Title = '{title}'"); mrb = (await _dalService.QueryAsync(queryBuilder.ToString())).FirstOrDefault(); _cache.Set($"mrb{title}", mrb, DateTimeOffset.Now.AddHours(1)); } if (mrb is null) throw new Exception($"Unable to get MRB {title}"); return mrb; } catch (Exception ex) { _logger.LogError($"An exception occurred when attempting to get an MRB. Exception: {ex.Message}"); throw; } } public async Task UpdateMRB(MRB mrb) { try { _logger.LogInformation("Attempting to update an MRB"); if (mrb is null) throw new ArgumentNullException("MRB cannot be null"); StringBuilder queryBuilder = new(); queryBuilder.Append($"update MRB set OriginatorID = {mrb.OriginatorID}, "); queryBuilder.Append($"Title = '{mrb.Title}', "); if (mrb.SubmittedDate > DateTime.MinValue) queryBuilder.Append($"SubmittedDate = '{mrb.SubmittedDate.ToString("yyyy-MM-dd HH:mm:ss")}', "); if (mrb.CloseDate < DateTime.MaxValue) queryBuilder.Append($"CloseDate = '{mrb.CloseDate.ToString("yyyy-MM-dd HH:mm:ss")}', "); if (mrb.CancelDate < DateTime.MaxValue) queryBuilder.Append($"CancelDate = '{mrb.CancelDate.ToString("yyyy-MM-dd HH:mm:ss")}', "); queryBuilder.Append($"NumberOfLotsAffected = {mrb.NumberOfLotsAffected}, "); if (mrb.ApprovalDate < DateTime.MaxValue) queryBuilder.Append($"ApprovalDate = '{mrb.ApprovalDate.ToString("yyyy-MM-dd HH:mm:ss")}', "); queryBuilder.Append($"IssueDescription = '{mrb.IssueDescription}', "); queryBuilder.Append($"CustomerImpacted = {Convert.ToInt32(mrb.CustomerImpacted)}, "); queryBuilder.Append($"Department = '{mrb.Department}', "); queryBuilder.Append($"Process = '{mrb.Process}', "); queryBuilder.Append($"Val = '{mrb.Val}', "); queryBuilder.Append($"RMANo = {mrb.RMANo}, "); queryBuilder.Append($"PCRBNo = {mrb.PCRBNo}, "); queryBuilder.Append($"SpecsImpacted = {Convert.ToInt32(mrb.SpecsImpacted)}, "); queryBuilder.Append($"TrainingRequired = {Convert.ToInt32(mrb.TrainingRequired)}, "); queryBuilder.Append($"Status = '{mrb.Status}', StageNo = {mrb.StageNo} "); queryBuilder.Append($"where MRBNumber = {mrb.MRBNumber};"); int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString()); if (rowsAffected <= 0) throw new Exception($"Unable to update MRB {mrb.MRBNumber}"); _cache.Set($"mrb{mrb.MRBNumber}", mrb, DateTimeOffset.Now.AddHours(1)); _cache.Set($"mrb{mrb.Title}", mrb, DateTimeOffset.Now.AddHours(1)); IEnumerable? allMrbs = _cache.Get>("allMrbs"); if (allMrbs is not null) { List mrbList = allMrbs.ToList(); mrbList.RemoveAll(m => m.MRBNumber ==mrb.MRBNumber); mrbList.Add(mrb); _cache.Set("allMrbs", mrbList, DateTimeOffset.Now.AddHours(1)); } } catch (Exception ex) { _logger.LogError($"An exception occurred when attempting to update an MRB. Exception: {ex.Message}"); throw; } } public async Task CreateMRBAction(MRBAction mrbAction) { try { _logger.LogInformation("Attempting to generate new MRB action"); if (mrbAction is null) throw new ArgumentNullException("MRB action cannot be null"); StringBuilder queryBuilder = new(); queryBuilder.Append("insert into MRBAction (Action, Customer, Quantity, PartNumber, LotNumber, MRBNumber) "); queryBuilder.Append($"values ('{mrbAction.Action}', '{mrbAction.Customer}', {mrbAction.Quantity}, "); queryBuilder.Append($"'{mrbAction.PartNumber}', '{mrbAction.LotNumber}', {mrbAction.MRBNumber});"); int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString()); if (rowsAffected <= 0) throw new Exception("Unable to create MRB action in database"); } catch (Exception ex) { _logger.LogError($"An exception occurred when attempting to create new MRB action. Exception: {ex.Message}"); throw; } } public async Task> GetMRBActionsForMRB(int mrbNumber, bool bypassCache) { try { _logger.LogInformation($"Attempting to get MRB actions for MRB {mrbNumber}"); if (mrbNumber <= 0) throw new ArgumentException($"{mrbNumber} is not a valid MRB number"); IEnumerable? mrbActions = null; if (!bypassCache) _cache.Get>($"mrbActions{mrbNumber}"); if (mrbActions is null) { string sql = $"select * from MRBAction where MRBNumber = {mrbNumber}"; mrbActions = (await _dalService.QueryAsync(sql)).ToList(); if (mrbActions is not null) { foreach (MRBAction action in mrbActions) { if (action.CompletedDate < DateTime.MaxValue && action.CompletedByUserID > 0) { action.CompletedByUser = await _userService.GetUserByUserId(action.CompletedByUserID); } } _cache.Set($"mrbActions{mrbNumber}", mrbActions, DateTimeOffset.Now.AddMinutes(30)); } } if (mrbActions is null) throw new Exception($"Unable to find MRB actions for MRB {mrbNumber}"); return mrbActions; } catch (Exception ex) { _logger.LogError($"Unable to get MRB actions for MRB {mrbNumber}, because {ex.Message}"); throw; } } public async Task UpdateMRBAction(MRBAction mrbAction) { try { _logger.LogInformation("Attempting to update MRB action"); if (mrbAction is null) throw new ArgumentNullException("MRB action cannot be null"); StringBuilder queryBuilder = new(); queryBuilder.Append($"update MRBAction set Action = '{mrbAction.Action}', "); queryBuilder.Append($"Customer = '{mrbAction.Customer}', "); queryBuilder.Append($"Quantity = {mrbAction.Quantity}, "); queryBuilder.Append($"PartNumber = '{mrbAction.PartNumber}', "); queryBuilder.Append($"LotNumber = '{mrbAction.LotNumber}', "); if (mrbAction.AssignedDate > DateTime.MinValue) queryBuilder.Append($"AssignedDate= '{mrbAction.AssignedDate.ToString("yyyy-MM-dd HH:mm:ss")}', "); if (mrbAction.CompletedDate < DateTime.MaxValue) queryBuilder.Append($"CompletedDate= '{mrbAction.CompletedDate.ToString("yyyy-MM-dd HH:mm:ss")}', "); queryBuilder.Append($"CompletedByUserID={mrbAction.CompletedByUserID} "); queryBuilder.Append($"where ActionID={mrbAction.ActionID};"); int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString()); if (rowsAffected <= 0) throw new Exception($"There were no MRB actions found with MRB# {mrbAction.MRBNumber}"); List? mrbActions = _cache.Get>($"mrbActions{mrbAction.MRBNumber}")?.ToList(); if (mrbActions is not null) { mrbActions.RemoveAll(m => m.ActionID == mrbAction.ActionID); mrbActions.Add(mrbAction); _cache.Set($"mrbActions{mrbAction.MRBNumber}", mrbActions, DateTimeOffset.Now.AddMinutes(30)); } } catch (Exception ex) { _logger.LogError($"Unable to update MRB action, because {ex.Message}"); throw; } } public async Task DeleteMRBAction(int mrbActionID, int mrbNumber) { try { _logger.LogInformation($"Attempting to delete MRB action {mrbActionID}"); if (mrbActionID <= 0) throw new ArgumentException($"{mrbActionID} is not a valid MRBActionID"); if (mrbNumber <= 0) throw new ArgumentException($"{mrbNumber} is not a valid MRBNumber"); string sql = $"delete from MRBAction where ActionID = {mrbActionID};"; int rowsAffected = await _dalService.ExecuteAsync(sql); if (rowsAffected <= 0) throw new Exception($"No MRB action was found to delete for ActionID {mrbActionID}"); List? mrbActions = _cache.Get>($"mrbActions{mrbNumber}")?.ToList(); if (mrbActions is not null) { mrbActions.RemoveAll(m => m.ActionID == mrbActionID); _cache.Set($"mrbActions{mrbNumber}", mrbActions, DateTimeOffset.Now.AddMinutes(30)); } } catch (Exception ex) { _logger.LogError($"An exception occurred when attempting to delete MRB action {mrbActionID}. Exception: {ex.Message}"); throw; } } public async Task> UploadAttachments(IEnumerable files, int mrbNumber) { try { _logger.LogInformation("Attempting to upload attachments"); List uploadResults = new(); if (files is null) throw new ArgumentNullException("Files cannot be null"); if (files.Count() <= 0) throw new ArgumentException("Files cannot be empty"); if (mrbNumber <= 0) throw new ArgumentException($"{mrbNumber} is not a valid MRB number"); List taskList = new (); foreach (IFormFile file in files) { try { if (file is null) throw new ArgumentException("File cannot be null"); if (file.Length <= 0) throw new ArgumentException("File size cannot be zero"); string encodedName = WebUtility.HtmlEncode(file.FileName); string path = $"{_mrbAttachmentPath}\\{mrbNumber}\\{encodedName}"; taskList.Add(SaveFileToFileSystem(file, path)); taskList.Add(SaveAttachmentInDb(file, path, mrbNumber)); UploadResult uploadResult = new() { UploadSuccessful = true, FileName = file.FileName }; uploadResults.Add(uploadResult); } catch (Exception ex) { UploadResult uploadResult = new() { UploadSuccessful = false, FileName = file.FileName, Error = ex.Message }; uploadResults.Add(uploadResult); } } Task.WaitAll(taskList.ToArray()); return uploadResults; } catch (Exception ex) { _logger.LogError($"An exception occurred when attempting to upload attachment. Exception: {ex.Message}"); throw; } } public async Task> GetAllAttachmentsForMRB(int mrbNumber, bool bypassCache) { try { _logger.LogInformation($"Attempting to get all attachments for MRB {mrbNumber}"); if (mrbNumber <= 0) throw new ArgumentException($"{mrbNumber} is not a valid MRB number"); IEnumerable? attachments = null; if (!bypassCache) _cache.Get>($"mrbAttachments{mrbNumber}"); if (attachments is null) { string sql = $"select * from MRBAttachment where MRBNumber = {mrbNumber};"; attachments = (await _dalService.QueryAsync(sql)).ToList(); _cache.Set($"mrbAttachments{mrbNumber}", attachments, DateTimeOffset.Now.AddMinutes(15)); } return attachments; } catch (Exception ex) { StringBuilder errMsgBuilder = new(); errMsgBuilder.Append($"An error occurred when attempting to get all attachments for MRB {mrbNumber}. "); errMsgBuilder.Append($"Exception: {ex.Message}"); _logger.LogError(errMsgBuilder.ToString()); throw; } } public async Task DeleteAttachment(MRBAttachment attachment) { try { _logger.LogInformation("Attempting to delete an attachment"); if (attachment is null) throw new ArgumentNullException("Attachment cannot be null"); if (!File.Exists(attachment.Path)) throw new FileNotFoundException("No file found at provided path"); File.Delete(attachment.Path); string sql = $"delete from MRBAttachment where AttachmentID = {attachment.AttachmentID};"; int rowsDeleted = await _dalService.ExecuteAsync(sql); if (rowsDeleted <= 0) throw new Exception($"No attachments found in the database with attachment ID {attachment.AttachmentID}"); } catch (Exception ex) { _logger.LogError($"An exception occurred when attempting to delete an attachment. Exception: {ex.Message}"); throw; } } public async Task NotifyNewApprovals(MRB mrb) { try { _logger.LogInformation("Attempting to notify approvers"); if (mrb is null) throw new ArgumentNullException("MRB cannot be null"); IEnumerable approvals = await _approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); List approvalsNeedingNotification = approvals.Where(a => a.NotifyDate <= DateTime.MinValue).ToList(); HashSet emailsAlreadySent = new(); foreach (Approval approval in approvalsNeedingNotification) { User user = await _userService.GetUserByUserId(approval.UserID); if (!emailsAlreadySent.Contains(user.Email)) { emailsAlreadySent.Add(user.Email); List toAddresses = new(); toAddresses.Add(new MailAddress(user.Email)); List ccAddresses = new(); string subject = $"[New Task] Mesa Fab Approval - MRB# {mrb.MRBNumber}"; StringBuilder bodyBuilder = new(); bodyBuilder.Append($"You have been assigned a new task in Mesa Fab Approval for issue {approval.IssueID}. The assigned role is {approval.SubRoleCategoryItem}.

"); bodyBuilder.Append($"Click {_siteBaseUrl}/redirect?jwt=jwt&refreshToken=refreshToken&redirectPath=/mrb/{approval.IssueID} to view the task."); await _smtpService.SendEmail(toAddresses, ccAddresses, subject, bodyBuilder.ToString()); approval.NotifyDate = DateTime.Now; await _approvalService.UpdateApproval(approval); } } } catch (Exception ex) { _logger.LogError($"Unable to notify approvers, because {ex.Message}"); throw; } } public async Task NotifyApprovers(MRBNotification notification) { try { _logger.LogInformation("Attempting to send notification to approvers"); if (notification is null) throw new ArgumentNullException("notification cannot be null"); if (notification.MRB is null) throw new ArgumentNullException("MRB cannot be null"); if (string.IsNullOrWhiteSpace(notification.Message)) throw new ArgumentException("message cannot be null or empty"); IEnumerable approvals = await _approvalService.GetApprovalsForIssueId(notification.MRB.MRBNumber, true); List approvalsNeedingNotification = approvals.Where(a => a.NotifyDate <= DateTime.MinValue).ToList(); HashSet emailsAlreadySent = new(); foreach (Approval approval in approvalsNeedingNotification) { User user = await _userService.GetUserByUserId(approval.UserID); if (!emailsAlreadySent.Contains(user.Email)) { emailsAlreadySent.Add(user.Email); List toAddresses = new(); toAddresses.Add(new MailAddress(user.Email)); List ccAddresses = new(); string subject = $"[Update] Mesa Fab Approval - MRB# {notification.MRB.MRBNumber}"; StringBuilder bodyBuilder = new(); bodyBuilder.Append($"{notification.Message}

"); bodyBuilder.Append($"Click {_siteBaseUrl}/redirect?jwt=jwt&refreshToken=refreshToken&redirectPath=/mrb/{approval.IssueID} to view the MRB."); await _smtpService.SendEmail(toAddresses, ccAddresses, subject, bodyBuilder.ToString()); approval.NotifyDate = DateTime.Now; await _approvalService.UpdateApproval(approval); } } } catch (Exception ex) { _logger.LogError($"Unable to send notification to originator, because {ex.Message}"); throw; } } public async Task NotifyOriginator(MRBNotification notification) { try { _logger.LogInformation("Attempting to send notification to originator"); if (notification is null) throw new ArgumentNullException("notification cannot be null"); if (notification.MRB is null) throw new ArgumentNullException("MRB cannot be null"); if (string.IsNullOrWhiteSpace(notification.Message)) throw new ArgumentException("message cannot be null or empty"); User user = await _userService.GetUserByUserId(notification.MRB.OriginatorID); List toAddresses = new(); toAddresses.Add(new MailAddress(user.Email)); List ccAddresses = new(); string subject = $"[Update] Mesa Fab Approval - MRB# {notification.MRB.MRBNumber}"; StringBuilder bodyBuilder = new(); bodyBuilder.Append($"{notification.Message}

"); bodyBuilder.Append($"Click {_siteBaseUrl}/redirect?jwt=jwt&refreshToken=refreshToken&redirectPath=/mrb/{notification.MRB.MRBNumber} to view the MRB."); await _smtpService.SendEmail(toAddresses, ccAddresses, subject, bodyBuilder.ToString()); } catch (Exception ex) { _logger.LogError($"Unable to send notification to originator, because {ex.Message}"); throw; } } private async Task SaveFileToFileSystem(IFormFile file, string path) { try { _logger.LogInformation($"Attempting to save file to file system"); if (file is null) throw new ArgumentNullException("File cannot be null"); if (string.IsNullOrWhiteSpace(path)) throw new ArgumentException("Path cannot be null or empty"); if (File.Exists(path)) throw new Exception($"A file already exists with name {file.FileName}"); string? directoryPath = Path.GetDirectoryName(path); if (!string.IsNullOrWhiteSpace(directoryPath)) Directory.CreateDirectory(directoryPath); using (FileStream stream = File.Create(path)) { await file.OpenReadStream().CopyToAsync(stream); } } catch (Exception ex) { _logger.LogError($"An exception occurred when attempting to save file to file system. Exception: {ex.Message}"); throw; } } private async Task SaveAttachmentInDb(IFormFile file, string path, int mrbNumber) { try { _logger.LogInformation($"Attempting to save attachment to database"); if (file is null) throw new ArgumentNullException("File cannot be null"); if (string.IsNullOrWhiteSpace(path)) throw new ArgumentException("Path cannot be null or empty"); if (mrbNumber <= 0) throw new ArgumentException($"{mrbNumber} is not a valid MRB number"); StringBuilder queryBuilder = new(); queryBuilder.Append("insert into MRBAttachment (MRBNumber, FileName, UploadDate, Path) "); queryBuilder.Append($"values ({mrbNumber}, '{file.FileName}', "); queryBuilder.Append($"'{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}', '{path}');"); int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString()); if (rowsAffected <= 0) throw new Exception("Unable to insert attachment in database"); } catch (Exception ex) { _logger.LogError($"An exception occurred when attempting to save file to file system. Exception: {ex.Message}"); throw; } } }