Mike Phares 538b1f817e Align .editorconfig files
When debugging only
app.Services.GetRequiredService<IPCRBService>();

Injected AppSettings instead of using GetEnvironmentVariable at Services level

Get ready to use VSCode IDE
2024-12-03 12:23:56 -07:00

320 lines
15 KiB
C#

using System.Text;
using MesaFabApproval.Shared.Models;
using MesaFabApproval.Shared.Utilities;
using Microsoft.Extensions.Caching.Memory;
namespace MesaFabApproval.API.Services;
public interface IApprovalService {
Task<int> GetRoleIdForRoleName(string roleName);
Task<IEnumerable<SubRole>> GetSubRolesForSubRoleName(string subRoleName, int roleId);
Task<IEnumerable<User>> GetApprovalGroupMembers(int subRoleId);
Task CreateApproval(Approval approval);
Task UpdateApproval(Approval approval);
Task Approve(Approval approval);
Task Deny(Approval approval);
Task<IEnumerable<Approval>> GetApprovalsForIssueId(int issueId, bool bypassCache);
Task<IEnumerable<Approval>> GetApprovalsForUserId(int userId, bool bypassCache);
}
public class ApprovalService : IApprovalService {
private readonly ILogger<ApprovalService> _logger;
private readonly IMemoryCache _cache;
private readonly IDalService _dalService;
private readonly IUserService _userService;
public ApprovalService(ILogger<ApprovalService> logger, IMemoryCache cache, IDalService dalService, IUserService userService) {
_logger = logger ?? throw new ArgumentNullException("ILogger not injected");
_cache = cache ?? throw new ArgumentNullException("IMemoryCache not injected");
_dalService = dalService ?? throw new ArgumentNullException("IDalService not injected");
_userService = userService ?? throw new ArgumentNullException("IUserService not injected");
}
public async Task CreateApproval(Approval approval) {
try {
_logger.LogInformation("Attempting to generate new Approval");
if (approval is null) throw new ArgumentNullException("Approval cannot be null");
StringBuilder queryBuilder = new();
queryBuilder.Append("insert into Approval (IssueID, RoleName, SubRole, UserID, SubRoleID, ItemStatus, ");
queryBuilder.Append("AssignedDate, DocumentTypeID, DisplayDeniedDocument, Step, TaskID) ");
queryBuilder.Append($"values ({approval.IssueID}, '{approval.RoleName}', '{approval.SubRole}', {approval.UserID}, ");
queryBuilder.Append($"{approval.SubRoleID}, 0, '{approval.AssignedDate.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"3, 0, {approval.Step}, {approval.TaskID});");
int rowsCreated = await _dalService.ExecuteAsync(queryBuilder.ToString());
if (rowsCreated <= 0) throw new Exception("Unable to insert approval in database");
await GetApprovalsForIssueId(approval.IssueID, true);
} catch (Exception ex) {
_logger.LogError($"An exception occurred when attempting to create new Approval. Exception: {ex.Message}");
throw;
}
}
public async Task<IEnumerable<Approval>> GetApprovalsForIssueId(int issueId, bool bypassCache) {
try {
_logger.LogInformation($"Attempting to get all approvals for issue {issueId}");
if (issueId <= 0) throw new ArgumentException($"{issueId} is not a valid issue ID");
IEnumerable<Approval>? approvals = new List<Approval>();
if (!bypassCache)
approvals = _cache.Get<IEnumerable<Approval>>($"approvals{issueId}");
if (approvals is null || approvals.Count() == 0) {
StringBuilder queryBuilder = new();
queryBuilder.Append("select a.*, src.SubRoleCategoryItem from Approval a ");
queryBuilder.Append("join SubRole sr on a.SubRoleID=sr.SubRoleID ");
queryBuilder.Append("join SubRoleCategory src on sr.SubRoleCategoryID=src.SubRoleCategoryID ");
queryBuilder.Append($"where a.IssueID={issueId}");
approvals = (await _dalService.QueryAsync<Approval>(queryBuilder.ToString())).ToList();
foreach (Approval approval in approvals) {
int successfulUpdates = 0;
User? user = await _userService.GetUserByUserId(approval.UserID);
if (user is not null) {
approval.User = user;
successfulUpdates++;
}
if (approval.ItemStatus < 0)
approval.StatusMessage = "Denied";
if (approval.ItemStatus == 0)
approval.StatusMessage = "Assigned";
if (approval.ItemStatus > 0)
approval.StatusMessage = "Approved";
}
_cache.Set($"approvals{issueId}", approvals, DateTimeOffset.Now.AddMinutes(5));
}
return approvals;
} catch (Exception ex) {
_logger.LogError($"Unable to fetch approvals for issue {issueId}, because {ex.Message}");
throw;
}
}
public async Task<int> GetRoleIdForRoleName(string roleName) {
try {
_logger.LogInformation($"Attempting to get role ID by name");
if (string.IsNullOrWhiteSpace(roleName))
throw new ArgumentException("Role name cannot be null or empty");
int roleId = _cache.Get<int>($"role{roleName}");
if (roleId <= 0) {
string sql = $"select RoleID from Role where RoleName = '{roleName}'";
roleId = (await _dalService.QueryAsync<int>(sql)).ToList().FirstOrDefault();
if (roleId > 0)
_cache.Set($"role{roleName}", roleId, DateTimeOffset.Now.AddDays(1));
}
if (roleId <= 0)
throw new Exception($"Unable to find role with name {roleName}");
return roleId;
} catch (Exception ex) {
_logger.LogError($"Unable to find role ID, because {ex.Message}");
throw;
}
}
public async Task<IEnumerable<SubRole>> GetSubRolesForSubRoleName(string subRoleName, int roleId) {
try {
_logger.LogInformation($"Attempting to get sub role ID by name for role ID {roleId}");
if (string.IsNullOrWhiteSpace(subRoleName))
throw new ArgumentException("sub role name cannot be null or empty");
if (roleId <= 0) throw new ArgumentException($"{roleId} is not a valid role ID");
IEnumerable<SubRole>? subRoles = _cache.Get<IEnumerable<SubRole>>($"subRoles{subRoleName}");
if (subRoles is null || subRoles.Count() <= 0) {
StringBuilder queryBuilder = new();
queryBuilder.Append("select src.SubRoleCategoryID, sr.SubRole as SubRoleName, src.SubRoleCategoryItem, sr.SubRoleID ");
queryBuilder.Append("from SubRole sr join SubRoleCategory src on sr.SubRoleCategoryID=src.SubRoleCategoryID ");
queryBuilder.Append($"where sr.RoleID={roleId} and sr.SubRole='{subRoleName}' and sr.Inactive=0");
subRoles = (await _dalService.QueryAsync<SubRole>(queryBuilder.ToString())).ToList();
if (subRoles is not null && subRoles.Count() > 0)
_cache.Set($"subRole{subRoleName}", subRoles, DateTimeOffset.Now.AddDays(1));
}
if (subRoles is null || subRoles.Count() <= 0)
throw new Exception($"Unable to find sub role with name {subRoleName} for role {roleId}");
return subRoles;
} catch (Exception ex) {
_logger.LogError($"Unable to find sub roles, because {ex.Message}");
throw;
}
}
public async Task<IEnumerable<User>> GetApprovalGroupMembers(int subRoleId) {
try {
_logger.LogInformation($"Attempting to get members of sub role {subRoleId}");
if (subRoleId <= 0) throw new ArgumentException($"{subRoleId} is not a valid sub role ID");
List<User>? members = _cache.Get<List<User>>($"approvalMembers{subRoleId}");
if (members is null || members.Count() <= 0) {
IEnumerable<int>? memberIds = _cache.Get<IEnumerable<int>>($"approvalMemberIds{subRoleId}");
if (memberIds is null) {
string sql = $"select UserID from UserSubRole where SubRoleID = {subRoleId};";
memberIds = await _dalService.QueryAsync<int>(sql);
if (memberIds is null || memberIds.Count() <= 0)
throw new Exception($"No members found in sub role {subRoleId}");
_cache.Set($"approvalMemberIds{subRoleId}", memberIds, DateTimeOffset.Now.AddMinutes(5));
}
members = new();
foreach (int id in memberIds) {
User member = await _userService.GetUserByUserId(id);
members.Add(member);
}
if (members.Count() <= 0) throw new Exception("No users found with IDs matching those found in SubRole");
_cache.Set($"approvalMembers{subRoleId}", members, DateTimeOffset.Now.AddMinutes(5));
}
return members;
} catch (Exception ex) {
_logger.LogError($"Unable to get sub role {subRoleId} members, because {ex.Message}");
throw;
}
}
public async Task<IEnumerable<Approval>> GetApprovalsForUserId(int userId, bool bypassCache) {
try {
_logger.LogInformation($"Attempting to get approvals for user ID {userId}");
if (userId <= 0) throw new ArgumentException($"{userId} is not a valid user ID");
IEnumerable<Approval>? approvals = null;
if (!bypassCache) approvals = _cache.Get<IEnumerable<Approval>>($"approvalMembers{userId}");
if (approvals is null) {
StringBuilder queryBuilder = new();
queryBuilder.Append($"select a.*, src.SubRoleCategoryItem from Approval a ");
queryBuilder.Append("join SubRole sr on a.SubRoleID=sr.SubRoleID ");
queryBuilder.Append("join SubRoleCategory src on sr.SubRoleCategoryID=src.SubRoleCategoryID ");
queryBuilder.Append($"where UserID={userId} and ");
queryBuilder.Append($"((CompletedDate >= '{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}') or ");
queryBuilder.Append($"(CompletedDate is null));");
string sql = queryBuilder.ToString();
approvals = (await _dalService.QueryAsync<Approval>(sql)).ToList();
_cache.Set($"approvalMembers{userId}", approvals, DateTimeOffset.Now.AddHours(1));
}
return approvals;
} catch (Exception ex) {
_logger.LogError($"Unable to get approvals for user ID {userId}, because {ex.Message}");
throw;
}
}
public async Task UpdateApproval(Approval approval) {
try {
_logger.LogInformation("Attempting to update an approval");
if (approval is null) throw new ArgumentNullException("Approval cannot be null");
StringBuilder queryBuilder = new();
queryBuilder.Append($"update Approval set IssueID={approval.IssueID}, RoleName='{approval.RoleName}', ");
queryBuilder.Append($"SubRole='{approval.SubRole}', UserID={approval.UserID}, SubRoleID={approval.SubRoleID}, ");
queryBuilder.Append($"ItemStatus={Convert.ToInt32(approval.ItemStatus)}, Step={approval.Step}, ");
queryBuilder.Append($"NotifyDate='{approval.NotifyDate.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"AssignedDate='{approval.AssignedDate.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"CompletedDate='{approval.CompletedDate.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"Comments='{approval.Comments.Replace("'", "''")}', ");
queryBuilder.Append($"TaskID={approval.TaskID} ");
queryBuilder.Append($"where ApprovalID={approval.ApprovalID};");
int rowsUpdated = await _dalService.ExecuteAsync(queryBuilder.ToString());
if (rowsUpdated <= 0) throw new Exception("Unable to update approval in database");
} catch (Exception ex) {
_logger.LogError($"Approval update failed, because {ex.Message}");
throw;
}
}
public async Task Approve(Approval approval) {
try {
_logger.LogInformation("Attempting to submit approval");
if (approval is null) throw new ArgumentNullException("Approval cannot be null");
StringBuilder queryBuilder = new();
queryBuilder.Append($"update Approval set IssueID={approval.IssueID}, RoleName='{approval.RoleName}', ");
queryBuilder.Append($"SubRole='{approval.SubRole}', UserID={approval.UserID}, SubRoleID={approval.SubRoleID}, ");
queryBuilder.Append($"ItemStatus=1, Step={approval.Step}, ");
if (approval.NotifyDate < DateTimeUtilities.MIN_DT)
approval.NotifyDate = DateTimeUtilities.MIN_DT;
queryBuilder.Append($"NotifyDate='{approval.NotifyDate.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"AssignedDate='{approval.AssignedDate.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"CompletedDate='{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"Comments='{approval.Comments}', ");
queryBuilder.Append($"TaskID={approval.TaskID} ");
queryBuilder.Append($"where ApprovalID={approval.ApprovalID};");
int rowsUpdated = await _dalService.ExecuteAsync(queryBuilder.ToString());
if (rowsUpdated <= 0) throw new Exception("Unable to submit approval in database");
} catch (Exception ex) {
_logger.LogError($"Approval failed, because {ex.Message}");
throw;
}
}
public async Task Deny(Approval approval) {
try {
_logger.LogInformation("Attempting to deny approval");
if (approval is null) throw new ArgumentNullException("Approval cannot be null");
StringBuilder queryBuilder = new();
queryBuilder.Append($"update Approval set IssueID={approval.IssueID}, RoleName='{approval.RoleName}', ");
queryBuilder.Append($"SubRole='{approval.SubRole}', UserID={approval.UserID}, SubRoleID={approval.SubRoleID}, ");
queryBuilder.Append($"ItemStatus=-1, Step={approval.Step}, ");
if (approval.NotifyDate < DateTimeUtilities.MIN_DT)
approval.NotifyDate = DateTimeUtilities.MIN_DT;
queryBuilder.Append($"NotifyDate='{approval.NotifyDate.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"AssignedDate='{approval.AssignedDate.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"CompletedDate='{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"Comments='{approval.Comments}', ");
queryBuilder.Append($"TaskID={approval.TaskID} ");
queryBuilder.Append($"where ApprovalID={approval.ApprovalID};");
int rowsUpdated = await _dalService.ExecuteAsync(queryBuilder.ToString());
if (rowsUpdated <= 0) throw new Exception("Unable to deny approval in database");
} catch (Exception ex) {
_logger.LogError($"Approval denial failed, because {ex.Message}");
throw;
}
}
}