When debugging only app.Services.GetRequiredService<IPCRBService>(); Injected AppSettings instead of using GetEnvironmentVariable at Services level Get ready to use VSCode IDE
320 lines
15 KiB
C#
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;
|
|
}
|
|
}
|
|
} |