This commit is contained in:
Zeeshaun
2026-03-17 09:53:09 -05:00
parent cdcba54aa4
commit 1a0702a79a
590 changed files with 62058 additions and 0 deletions
@@ -0,0 +1,44 @@
using LCU.API.Internal.Operations.IncentiveApiLib.Persistence;
using LCU.API.Internal.Operations.IncentiveApiLib.Services;
using Microsoft.AspNetCore.Authorization;
namespace LCU.API.Internal.Operations.IncentiveApi.Authorization;
public class PermissionAuthorizationHandler : AuthorizationHandler<PermissionRequirement>
{
private readonly ICurrentUserService _currentUserService;
private readonly IUserService _userService;
public PermissionAuthorizationHandler(ICurrentUserService currentUserService, IUserService userService)
{
_currentUserService = currentUserService;
_userService = userService;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context,
PermissionRequirement requirement)
{
try
{
var allowedPermissions = requirement.Permissions.Split(',').ToList();
var appUser = _currentUserService.GetCurrentUser();
if (appUser.Email == null)
{
context.Fail();
return;
}
if (await _userService.UserHasAnyRequiredPermission(appUser.Email, allowedPermissions))
{
context.Succeed(requirement);
return;
}
context.Fail();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
context.Fail();
}
}
}
@@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
namespace LCU.API.Internal.Operations.IncentiveApi.Authorization;
public class PermissionPolicyProvider : IAuthorizationPolicyProvider
{
const string POLICY_PREFIX = "Permission";
public DefaultAuthorizationPolicyProvider FallbackPolicyProvider { get; }
public PermissionPolicyProvider(IOptions<AuthorizationOptions> options)
{
FallbackPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
}
public Task<AuthorizationPolicy> GetDefaultPolicyAsync() => FallbackPolicyProvider.GetDefaultPolicyAsync();
public Task<AuthorizationPolicy> GetFallbackPolicyAsync() => FallbackPolicyProvider.GetFallbackPolicyAsync();
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
if (policyName.StartsWith(POLICY_PREFIX, StringComparison.OrdinalIgnoreCase))
{
var allowedPermissions = policyName.Substring(POLICY_PREFIX.Length);
var policy = new AuthorizationPolicyBuilder();
policy.AddRequirements(new PermissionRequirement(allowedPermissions));
return Task.FromResult(policy.Build());
}
return FallbackPolicyProvider.GetPolicyAsync(policyName);
}
}
@@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Authorization;
namespace LCU.API.Internal.Operations.IncentiveApi.Authorization;
public class PermissionRequirement : IAuthorizationRequirement
{
public string Permissions { get; private set; }
public PermissionRequirement(string permissions)
{
Permissions = permissions;
}
}
@@ -0,0 +1,17 @@
using Microsoft.AspNetCore.Authorization;
namespace LCU.API.Internal.Operations.IncentiveApi.Authorization;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class RequirePermissionAttribute : AuthorizeAttribute
{
const string POLICY_PREFIX = "Permission";
public RequirePermissionAttribute(string permissions) => Permissions = permissions;
public string Permissions
{
get => Policy.Substring(POLICY_PREFIX.Length);
set => Policy = $"{POLICY_PREFIX}{value}";
}
}
@@ -0,0 +1,12 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Configuration;
public class ApiConfiguration
{
public string AppName { get; set; }
public string SeqUrl { get; set; }
public string SeqKey { get; set; }
public string[] CorsAllowedOrigins { get; set; }
public string IncentiveManagerClientUrl { get; set; }
public FeatureFlags FeatureFlags { get; set; }
public string ApplicationDbIntegrityCronSchedule { get; set; }
}
@@ -0,0 +1,41 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace LCU.API.Internal.Operations.IncentiveApi.Configuration;
public class CoreApiWrapperConfiguration
{
public string Url { get; set; }
public string GetNewCheckingAccountActivityEndpoint { get; set; }
public string GetNewDigitalBankingCheckingAccountActivityEndpoint { get; set; }
public string GetNewATMCheckCardActivityEndpoint { get; set; }
public string GetNewActivityManagerReferralsActivityEndpoint { get; set; }
public string GetNewMortgageAccountActivityEndpoint { get; set; }
public string GetNewVehicleSaleActivityEndpoint { get; set; }
public string GetNewDPEligibleAccountsActivityEndpoint { get; set; }
public string QueryActivityManagerActivityEndpoint { get; set; }
public string GetAccountActivityAccountDetailsEndpoint { get; set; }
public string GetTransactionHistoryEndpoint { get; set; }
public string GetEStatementDeliveryMethodsEndpoint { get; set; }
[NotMapped]
public string GetNewCheckingAccountActivityUrl => Url + GetNewCheckingAccountActivityEndpoint;
[NotMapped]
public string GetNewDigitalBankingCheckingAccountActivityUrl => Url + GetNewDigitalBankingCheckingAccountActivityEndpoint;
[NotMapped]
public string GetNewATMCheckCardActivityUrl => Url + GetNewATMCheckCardActivityEndpoint;
[NotMapped]
public string GetNewActivityManagerReferralsActivityUrl => Url + GetNewActivityManagerReferralsActivityEndpoint;
[NotMapped]
public string GetNewMortgageAccountActivityUrl => Url + GetNewMortgageAccountActivityEndpoint;
[NotMapped]
public string GetNewVehicleSaleActivityUrl => Url + GetNewVehicleSaleActivityEndpoint;
[NotMapped]
public string GetNewDPEligibleAccountsActivityUrl => Url + GetNewDPEligibleAccountsActivityEndpoint;
[NotMapped]
public string QueryActivityManagerActivityUrl => Url + QueryActivityManagerActivityEndpoint;
[NotMapped]
public string GetAccountActivityAccountDetailsUrl => Url + GetAccountActivityAccountDetailsEndpoint;
[NotMapped]
public string GetTransactionHistoryUrl => Url + GetTransactionHistoryEndpoint;
[NotMapped]
public string GetEStatementDeliveryMethodsUrl => Url + GetEStatementDeliveryMethodsEndpoint;
}
@@ -0,0 +1,13 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Configuration;
public class DayForceConfiguration
{
public string Url { get; set; }
public string DayForceClientName { get; set; }
public string DayForceApiVersion { get; set; }
public string DayForceUsername { get; set; }
public string DayForcePassword { get; set; }
public string DayForceActiveUserReport { get; set; }
public string DayForceTerminatedUserReport { get; set; }
public List<string> DayForceManualReportRecipients { get; set; }
}
@@ -0,0 +1,7 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Configuration;
public class EmailRecipientsConfiguration
{
public List<string> TransferRequestInitiatedNotification { get; set; }
public bool OverrideRecipients { get; set; }
}
@@ -0,0 +1,18 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Configuration;
public class FeatureFlags
{
public const string EnableControllers = "EnableControllers";
public bool RunImportCreditCardSalesConsumer { get; set; }
public bool RunImportIndirectVehicleSalesConsumer { get; set; }
public bool RunReportingProcessConsumer { get; set; }
public bool RunGoalDispersalProcessConsumer { get; set; }
public bool RunPayoutIncentiveProcessConsumer { get; set; }
public bool RunDayforceSyncProcessConsumer { get; set; }
public bool RunGapMbpProcessConsumer { get; set; }
public bool RunActionCreditCardProcessConsumer { get; set; }
public bool RunActionVehicleProcessConsumer { get; set; }
public bool RunIncentiveProcessesConsumer { get; set; }
public bool RunNightlyIncentiveProcessesConsumer { get; set; }
public bool RunApplicationDbIntegrityHostedService { get; set; }
}
@@ -0,0 +1,20 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace LCU.API.Internal.Operations.IncentiveApi.Configuration;
public class FileOperationsApiConfiguration
{
public string Url { get; set; }
public string GetFileContentEndpoint { get; set; }
public string WriteFileEndpoint { get; set; }
public string BuildDynamicFileListEndpoint { get; set; }
public int RetryCount { get; set; }
[NotMapped]
public Uri GetFileContentUri => new Uri(Url + GetFileContentEndpoint);
[NotMapped]
public Uri BuildDynamicFileListUri => new Uri(Url + BuildDynamicFileListEndpoint);
[NotMapped]
public Uri WriteFileEndpointUri => new Uri(Url + WriteFileEndpoint);
[NotMapped]
public Uri BuildDynamicFileListEndpointUri => new Uri(Url + BuildDynamicFileListEndpoint);
}
@@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace LCU.API.Internal.Operations.IncentiveApi.Configuration;
public class NotificationApiConfiguration
{
public string Url { get; set; }
public string Email { get; set; }
public int RetryCount { get; set; }
[NotMapped]
public string EmailUrl => Url + Email;
}
@@ -0,0 +1,19 @@
using LCU.Library.Internal.LcuMassTransitModels;
namespace LCU.API.Internal.Operations.IncentiveApi.Configuration;
public class ReceiveEndpointConfigurations
{
public ReceiveEndpointConfiguration ImportCreditCardSalesEndpoint { get; set; }
public ReceiveEndpointConfiguration ImportIndirectVehicleSalesEndpoint { get; set; }
public ReceiveEndpointConfiguration ReportingProcessEndpoint { get; set; }
public ReceiveEndpointConfiguration GoalDispersalProcessEndpoint { get; set; }
public ReceiveEndpointConfiguration PayoutIncentiveProcessEndpoint { get; set; }
public ReceiveEndpointConfiguration DayforceSyncProcessEndpoint { get; set; }
public ReceiveEndpointConfiguration GapMbpProcessEndpoint { get; set; }
public ReceiveEndpointConfiguration ActionCreditCardProcessEndpoint { get; set; }
public ReceiveEndpointConfiguration ActionVehicleProcessEndpoint { get; set; }
public ReceiveEndpointConfiguration IncentiveProcessesEndpoint { get; set; }
public ReceiveEndpointConfiguration NightlyIncentiveProcessesEndpoint { get; set; }
}
@@ -0,0 +1,8 @@
using LCU.API.Internal.Operations.IncentiveApi.Models;
namespace LCU.API.Internal.Operations.IncentiveApi.Configuration;
public class ReportConfiguration
{
public List<ReportSettings> ReportConfigs { get; set; }
}
@@ -0,0 +1,8 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Configuration;
public class SqlConnectionConfiguration
{
public string ConnectionString { get; set; }
public int MaxRetryCount { get; set; }
public TimeSpan MaxRetryDelay { get; set; }
}
@@ -0,0 +1,45 @@
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.IncentiveApiModels.Requests;
using LCU.API.Internal.Operations.IncentiveApi.Services.Action;
using Microsoft.Extensions.DependencyInjection;
using MassTransit;
namespace LCU.API.Internal.Operations.IncentiveApi.Consumers;
public class ActionCreditCardConsumer : IConsumer<ActionCreditCardRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public ActionCreditCardConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<ActionCreditCardRequest> context)
{
try
{
Log.Debug("Starting Action Credit Card Process.");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IActionCreditCardImportService>().RunActionCreditCardProcess(context.Message));
Log.Debug("Finished Action Credit Card Process.");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Action Credit Card Failure. " +
$"The Action Credit Card Process Request is placed on LCU.IncentiveApi.ActionCreditCardProcess_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Action Credit Card Failure. " +
"The Action Credit Card Process Request is placed on LCU.IncentiveApi.ActionCreditCardProcess_error.");
throw;
}
}
}
@@ -0,0 +1,45 @@
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.IncentiveApiModels.Requests;
using Microsoft.Extensions.DependencyInjection;
using LCU.API.Internal.Operations.IncentiveApi.Services.Action;
using MassTransit;
namespace LCU.API.Internal.Operations.IncentiveApi.Consumers;
public class ActionVehicleConsumer : IConsumer<ActionVehicleRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public ActionVehicleConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<ActionVehicleRequest> context)
{
try
{
Log.Debug("Starting Action Vehicle Process.");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IActionVehicleImportService>().RunActionVehicleProcess(context.Message));
Log.Debug("Finished Action Vehicle Process.");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Action Vehicle Failure. " +
$"The Action Vehicle Process Request is placed on LCU.IncentiveApi.ActionVehicleProcess_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Action Vehicle Failure. " +
"The Action Vehicle Process Request is placed on LCU.IncentiveApi.ActionVehicleProcess_error.");
throw;
}
}
}
@@ -0,0 +1,45 @@
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.IncentiveApiModels.Requests;
using Microsoft.Extensions.DependencyInjection;
using LCU.API.Internal.Operations.IncentiveApi.Services.Allied;
using MassTransit;
namespace LCU.API.Internal.Operations.IncentiveApi.Consumers;
public class AlliedGapMbpConsumer : IConsumer<AlliedGapMbpRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public AlliedGapMbpConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<AlliedGapMbpRequest> context)
{
try
{
Log.Debug("Starting Allied Gap/Mbp Process.");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IAlliedGapMbpTransactionImportService>().RunAlliedGapMbpProcess(context.Message));
Log.Debug("Finished Allied Gap/Mbp Process.");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Allied Gap/Mbp Failure. " +
$"The Allied Gap/Mbp Process Request is placed on LCU.IncentiveApi.AlliedGapMbpProcess_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Allied Gap/Mbp Failure. " +
"The Allied Gap/Mbp Process Request is placed on LCU.IncentiveApi.AlliedGapMbpProcess_error.");
throw;
}
}
}
@@ -0,0 +1,45 @@
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.IncentiveApiModels.Requests;
using Microsoft.Extensions.DependencyInjection;
using LCU.API.Internal.Operations.IncentiveApi.Services.Dayforce;
using MassTransit;
namespace LCU.API.Internal.Operations.IncentiveApi.Consumers;
public class DayforceSyncProcessConsumer : IConsumer<DayforceProcessRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public DayforceSyncProcessConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<DayforceProcessRequest> context)
{
try
{
Log.Debug("Starting Dayforce Sync Process.");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IDayForceSyncService>().SyncDayForceUsers(context.Message));
Log.Debug("Finished Dayforce Sync Process.");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Dayforce Sync Failure. " +
$"The Dayforce Sync Process Request is placed on LCU.IncentiveApi.DayforceSyncProcess_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Dayforce Sync Failure. " +
$"The Dayforce Sync Failure Process Request is placed on LCU.IncentiveApi.DayforceSyncProcess_error.");
throw;
}
}
}
@@ -0,0 +1,45 @@
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.IncentiveApiModels.Requests;
using Microsoft.Extensions.DependencyInjection;
using LCU.API.Internal.Operations.IncentiveApi.Services;
using MassTransit;
namespace LCU.API.Internal.Operations.IncentiveApi.Consumers;
public class GoalDispersalConsumer : IConsumer<GoalDispersalRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public GoalDispersalConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<GoalDispersalRequest> context)
{
try
{
Log.Debug("Starting Goal Dispersal Process.");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IGoalDispersalService>().ExecuteMonthStartDispersal(context.Message));
Log.Debug("Finished Goal Dispersal Process.");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Goal Dispersal Failure. " +
$"The Goal Dispersal Process Request is placed on LCU.IncentiveApi.GoalDispersalProcess_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Goal Dispersal Failure. " +
$"The Goal Dispersal Process Request is placed on LCU.IncentiveApi.GoalDispersalProcess_error.");
throw;
}
}
}
@@ -0,0 +1,45 @@
using LCU.API.Internal.Operations.IncentiveApi.Services.Temenos;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.IncentiveApiModels.Requests;
using Microsoft.Extensions.DependencyInjection;
using MassTransit;
namespace LCU.API.Internal.Operations.IncentiveApi.Consumers;
public class ImportCreditCardSalesConsumer : IConsumer<ImportCreditCardSalesRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public ImportCreditCardSalesConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<ImportCreditCardSalesRequest> context)
{
try
{
Log.Debug("Starting HandleImportCreditCardSales.");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IImportCreditCardSalesService>().HandleImportCreditCardSales(context.Message));
Log.Debug("Finished HandleImportCreditCardSales.");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Import Credit Card Sales Failure. " +
$"The Import Credit Card Sales Request is placed on LCU.IncentiveApi.ImportCreditCardSales_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Import Credit Card Sales Failure. " +
$"The Import Credit Card Sales Request is placed on LCU.IncentiveApi.ImportCreditCardSales_error.");
throw;
}
}
}
@@ -0,0 +1,45 @@
using LCU.API.Internal.Operations.IncentiveApi.Services.Temenos;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Library.Internal.IncentiveApiModels.Requests;
using Microsoft.Extensions.DependencyInjection;
using LCU.Library.Internal.Exceptions;
using MassTransit;
namespace LCU.API.Internal.Operations.IncentiveApi.Consumers;
public class ImportIndirectVehicleSalesConsumer : IConsumer<ImportIndirectVehicleSalesRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public ImportIndirectVehicleSalesConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<ImportIndirectVehicleSalesRequest> context)
{
try
{
Log.Debug("Starting HandleImportIndirectVehicleSales.");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IImportIndirectVehicleSalesService>().HandleImportIndirectVehicleSales(context.Message));
Log.Debug("Finished HandleImportIndirectVehicleSales.");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Import Indirect Vehicle Sales Failure. " +
$"The Import Indirect Vehicle Sales Request is placed on LCU.IncentiveApi.ImportIndirectVehicleSales_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Import Indirect Vehicle Sales Failure. " +
$"The Import Indirect Vehicle Sales Request is placed on LCU.IncentiveApi.ImportIndirectVehicleSales_error.");
throw;
}
}
}
@@ -0,0 +1,43 @@
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.IncentiveApiModels.Requests;
using LCU.API.Internal.Operations.IncentiveApi.Services;
using Microsoft.Extensions.DependencyInjection;
using MassTransit;
namespace LCU.API.Internal.Operations.IncentiveApi.Consumers;
public class IncentiveProcessesConsumer : IConsumer<IncentiveProcessRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public IncentiveProcessesConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<IncentiveProcessRequest> context)
{
try
{
using var scope = _scopeFactory.CreateScope();
await Task.Run(() => scope.ServiceProvider.GetRequiredService<IDnaActivitySyncService>().HandleProcessRequest(context.Message));
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Incentive Process Failure. " +
$"The Process Request is placed on LCU.IncentiveApi.Process_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Incentive Process Failure. " +
"The Process Request is placed on LCU.IncentiveApi.Process_error.");
throw;
}
}
}
@@ -0,0 +1,43 @@
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.IncentiveApiModels.Requests;
using Microsoft.Extensions.DependencyInjection;
using LCU.API.Internal.Operations.IncentiveApi.Services.NightlyDecisionServices;
using MassTransit;
namespace LCU.API.Internal.Operations.IncentiveApi.Consumers;
public class NightlyIncentiveProcessesConsumer : IConsumer<NightlyIncentiveProcessRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public NightlyIncentiveProcessesConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<NightlyIncentiveProcessRequest> context)
{
try
{
using var scope = _scopeFactory.CreateScope();
await Task.Run(() => scope.ServiceProvider.GetRequiredService<INightlyActivityDecisionService>().HandleProcessRequest(context.Message));
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Nightly Incentive Process Failure. " +
$"The Nightly Incentive Process Request is placed on LCU.IncentiveApi.NightlyIncentiveProcess_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Nightly Incentive Process Failure. " +
"The Nightly Incentive Process Request is placed on LCU.IncentiveApi.NightlyIncentiveProcess_error.");
throw;
}
}
}
@@ -0,0 +1,45 @@
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.IncentiveApiModels.Requests;
using Microsoft.Extensions.DependencyInjection;
using LCU.API.Internal.Operations.IncentiveApi.Services.Payout;
using MassTransit;
namespace LCU.API.Internal.Operations.IncentiveApi.Consumers;
public class PayoutIncentiveConsumer : IConsumer<PayoutIncentiveRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public PayoutIncentiveConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<PayoutIncentiveRequest> context)
{
try
{
Log.Information("Starting Payout Incentive Process.");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IPayoutService>().RunMonthlyIncentivePayouts(context.Message));
Log.Information("Finished Payout Incentive Process.");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Payout Incentive Process Failure. " +
$"The Payout Incentive Process Request is placed on LCU.IncentiveApi.PayoutIncentiveProcess_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Payout Incentive Process Failure. " +
$"The Payout Incentive Process Request is placed on LCU.IncentiveApi.PayoutIncentiveProcess_error.");
throw;
}
}
}
@@ -0,0 +1,45 @@
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.IncentiveApiModels.Requests;
using Microsoft.Extensions.DependencyInjection;
using LCU.API.Internal.Operations.IncentiveApi.Services.Reporting;
using MassTransit;
namespace LCU.API.Internal.Operations.IncentiveApi.Consumers;
public class ReportingConsumer : IConsumer<ReportingRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public ReportingConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<ReportingRequest> context)
{
try
{
Log.Debug("Starting Reporting Process.");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IReportingService>().HandleMonthlyReporting(context.Message));
Log.Debug("Finished Reporting Process.");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Reporting Process Failure. " +
$"The Reporting Process Request is placed on LCU.IncentiveApi.ReportingProcess_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Reporting Process Failure. " +
$"The Reporting Process Request is placed on LCU.IncentiveApi.ReportingProcess_error.");
throw;
}
}
}
@@ -0,0 +1,751 @@
using LCU.API.Internal.Operations.IncentiveApi.Exceptions;
using LCU.API.Internal.Operations.IncentiveApi.Services;
using LCU.API.Internal.Operations.IncentiveApi.Services.AutoDecision;
using LCU.API.Internal.Operations.IncentiveApiLib.Services;
using LCU.API.Internal.Operations.IncentiveApi.Models.DataTransfer;
using LCU.API.Internal.Operations.IncentiveApi.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement.Mvc;
using LCU.API.Internal.Operations.IncentiveApi.Authorization;
using LCU.API.Internal.Operations.IncentiveApi.Configuration;
using LCU.Library.Internal.IncentiveApiModels.Enums;
using LCU.Library.Internal.IncentiveApiModels.Entities;
using LCU.Library.Internal.IncentiveApiModels.Common;
using LCU.API.Internal.Operations.IncentiveApiLib.Persistence;
namespace LCU.API.Internal.Operations.IncentiveApi.Controllers;
[FeatureGate(FeatureFlags.EnableControllers)]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[ApiController]
[Route("api/[controller]")]
public class ActivityController : ControllerBase
{
private readonly IActivityService _activityService;
private readonly IActivityDetailService _activityDetailService;
private readonly IDashboardService _dashboardService;
private readonly IUserService _userService;
private readonly ICurrentUserService _currentUser;
private readonly IActivityDecisionService _activityDecisionService;
private readonly IEStatementService _eStatementService;
public ActivityController(IActivityService activityService, IActivityDetailService activityDetailService, IUserService userService,
ICurrentUserService currentUser, IDashboardService dashboardService, IActivityDecisionService activityDecisionService,
IEStatementService eStatementService)
{
_activityService = activityService;
_activityDetailService = activityDetailService;
_userService = userService;
_currentUser = currentUser;
_dashboardService = dashboardService;
_activityDecisionService = activityDecisionService;
_eStatementService = eStatementService;
}
[HttpGet("paged")]
[ProducesResponseType(typeof(PagedResponse<Activity>), 200)]
public async Task<IActionResult> Get([FromQuery] ActivityFilter filter)
{
try
{
var searchResult = await _activityService.ListByFilterAsync(filter);
foreach (var activity in searchResult.Items)
{
activity?.TransformForView();
}
var result = new PagedResponse<Activity>(searchResult, filter, Url, Request);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("me", Name = "GetCurrentUserProgress")]
[RequirePermission("VIEW_DASHBOARD")]
public async Task<IActionResult> GetCurrentUserProgress([FromQuery] int fromMonth, [FromQuery] int fromYear,
[FromQuery] int toMonth, [FromQuery] int toYear, [FromQuery] string employeeId = "")
{
try
{
var monthRange = new MonthRange(fromYear, fromMonth, toYear, toMonth);
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (!string.IsNullOrWhiteSpace(employeeId))
{
employee = await _userService.GetUserByEmployeeIdAsync(employeeId);
}
if (employee == null)
{
return NoContent();
}
var result = await _dashboardService.GetEmployeeProgressForMonthRangeAsync(employee, monthRange);
result?.TransformForView();
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("me/departments", Name = "GetCurrentUserDepartmentProgress")]
[RequirePermission("VIEW_DASHBOARD,VIEW_PERFORMANCE_FOR_DEPARTMENT")]
public async Task<IActionResult> GetCurrentUserDepartmentProgress([FromQuery] int fromMonth,
[FromQuery] int fromYear,
[FromQuery] int toMonth, [FromQuery] int toYear, [FromQuery] int departmentId = 0)
{
try
{
var monthRange = new MonthRange(fromYear, fromMonth, toYear, toMonth);
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
var result = new List<DepartmentProgress>();
if (departmentId != 0)
{
result.Add(
await _dashboardService.GetDepartmentProgressForMonthRangeAsync(departmentId, monthRange));
}
else
{
result.AddRange(
await _dashboardService.GetDepartmentProgressForMonthRangeAsync(employee.Departments,
monthRange));
}
foreach (var departmentProgress in result)
{
departmentProgress?.TransformForView();
}
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("region", Name = "GetRegionProgress")]
[RequirePermission("VIEW_DASHBOARD,VIEW_PERFORMANCE_FOR_REGION")]
public async Task<IActionResult> GetRegionProgress([FromQuery] int fromMonth,
[FromQuery] int fromYear,
[FromQuery] int toMonth, [FromQuery] int toYear, [FromQuery] string regionCode)
{
try
{
var monthRange = new MonthRange(fromYear, fromMonth, toYear, toMonth);
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
List<Region> regions = new List<Region>();
if (string.IsNullOrEmpty(regionCode))
{
var userDept = employee.Departments.FirstOrDefault(x => x.Role == Role.RegionalManager);
if (userDept == null)
{
return Unauthorized("No User-Dept for region found.");
}
regions.Add(Region.FindByCode(userDept.Department.RegionCode));
}
else if (regionCode == "ALL")
{
regions = Region.Regions;
}
else
{
regions.Add(Region.FindByCode(regionCode));
}
if (!regions.Any())
{
return NoContent();
}
var regionProgress = new List<RegionProgress>();
foreach (var region in regions)
{
var result =
await _dashboardService.GetRegionProgressForMonthRangeAsync(region, monthRange);
regionProgress.Add(result);
}
foreach (var region in regionProgress)
{
region?.TransformForView();
}
return Ok(regionProgress);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("businessLine", Name = "GetBusinessLineProgress")]
[RequirePermission("VIEW_DASHBOARD,VIEW_PERFORMANCE_FOR_BUSINESS_LINE")]
public async Task<IActionResult> GetBusinessLineProgress([FromQuery] int fromMonth,
[FromQuery] int fromYear,
[FromQuery] int toMonth, [FromQuery] int toYear, [FromQuery] string businessLineCode)
{
try
{
var monthRange = new MonthRange(fromYear, fromMonth, toYear, toMonth);
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
List<BusinessLine> bls = new List<BusinessLine>();
if (string.IsNullOrEmpty(businessLineCode))
{
var userDept = employee.FindDepartmentForRole(Role.BusinessLineManager);
if (userDept == null)
{
return Unauthorized("No User-Dept for business line found.");
}
bls.Add(BusinessLine.FindByCode(userDept.Department.BusinessLineCode));
}
else if (businessLineCode == "ALL")
{
bls = BusinessLine.BusinessLines;
}
else
{
bls.Add(BusinessLine.FindByCode(businessLineCode));
}
if (!bls.Any())
{
return NoContent();
}
var blProgress = new List<BusinessLineProgress>();
foreach (var bl in bls)
{
var result =
await _dashboardService.GetBusinessLineProgressForMonthRangeAsync(bl, monthRange);
blProgress.Add(result);
}
foreach (var bl in blProgress)
{
bl?.TransformForView();
}
return Ok(blProgress);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost]
public async Task<IActionResult> CreateActivity([FromBody] Activity activity)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var result = await _activityService.SaveActivityAsync(activity);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("StateChange")]
[HttpPost("ManualStateChange")]
public async Task<IActionResult> ManuallyUpdateActivityState([FromBody] ActivityStateChange activityStateChange)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return Unauthorized("No AD User Found.");
}
await _activityService.ValidateCanApplyActivityStateChange(employee, activityStateChange);
var result = await _activityService.ApplyStateChange(activityStateChange);
result?.TransformForView();
return Ok(result);
}
catch (BadActivityStateChangeException ex)
{
return BadRequest(ex.Message);
}
catch (NotAuthorizedException ex)
{
return StatusCode(403, ex.Message);
}
catch (NotFoundException)
{
return BadRequest("Activity Not Found.");
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("{activityId}/StateChanges")]
public async Task<IActionResult> GetActivityStateChanges([FromRoute] int activityId)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var result = await _activityService.GetActivityStateChanges(activityId);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("{activityId:int}/DetailChanges")]
public async Task<IActionResult> GetActivityDetailChanges([FromRoute] int activityId)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var activity = await _activityService.GetActivity(activityId);
var result = await _activityDetailService.GetAllActivityDetailUpdates(activity.Detail.Id);
if (result == null || !result.Any())
{
NoContent();
}
return Ok(result);
}
catch (NotFoundException)
{
return NotFound($"No activity with Id {activityId} could be found");
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("{activityId}/AvailableCommands")]
public async Task<IActionResult> GetActivityAuthorizedCommands([FromRoute] int activityId, [FromQuery] string employeeId)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (!string.IsNullOrWhiteSpace(employeeId))
{
employee = await _userService.GetUserByEmployeeIdAsync(employeeId);
}
if (employee == null)
{
return Unauthorized("No AD User Found.");
}
var result = await _activityService.GetActivityAuthorizedCommands(employee, activityId);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("{activityId}")]
public async Task<IActionResult> Get([FromRoute] int activityId)
{
try
{
var result = await _activityService.GetActivity(activityId);
result?.TransformForView();
return Ok(result);
}
catch (NotFoundException)
{
return BadRequest("Activity Not Found.");
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("RequestTransfer")]
[RequirePermission("TRANSFER_ACTIVITIES_BETWEEN_DEPARTMENTS, TRANSFER_ACTIVITIES_BETWEEN_ASSOCIATES")]
public async Task<IActionResult> RequestTransfer([FromBody] ActivityTransferRequest transferRequest)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var result = await _activityService.RequestTransfer(transferRequest);
result?.TransformForView();
return Ok(result);
}
catch (NotFoundException)
{
return BadRequest("Activity Not Found.");
}
catch (BadActivityTransferActionException ex)
{
return BadRequest(ex.Message);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("RequestTransferToOwnDepartment")]
public async Task<IActionResult> RequestTransferToOwnDepartment([FromBody] ActivityTransferRequest transferRequest)
{
try
{
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var result = await _activityService.TransferToOwnDepartment(transferRequest, employee);
result?.TransformForView();
return Ok(result);
}
catch (NotFoundException)
{
return BadRequest("Activity Not Found.");
}
catch (BadActivityTransferActionException ex)
{
return BadRequest(ex.Message);
}
catch (NotAuthorizedException ex)
{
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("ApproveTransfer")]
[RequirePermission("TRANSFER_ACTIVITIES_BETWEEN_DEPARTMENTS, TRANSFER_ACTIVITIES_BETWEEN_ASSOCIATES")]
public async Task<IActionResult> ApproveTransfer([FromBody] ActivityTransferApprovalRequest approvalRequest)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return Unauthorized("No AD User Found.");
}
var result = await _activityService.ApproveTransfer(employee, approvalRequest);
result?.TransformForView();
return Ok(result);
}
catch (NotFoundException)
{
return BadRequest("Activity Transfer Not Found.");
}
catch (NotAuthorizedException ex)
{
return StatusCode(403, ex.Message);
}
catch (BadActivityTransferActionException ex)
{
return BadRequest(ex.Message);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("{activityId}/RequestedTransferAction")]
public async Task<IActionResult> GetTransferAction([FromRoute] int activityId)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var result = await _activityService.GetRequestedTransfer(activityId);
result?.TransformForView();
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("")]
[Obsolete("Added here for legacy client support, please use Paginated version")]
public async Task<IActionResult> Get()
{
try
{
var result = await _activityService.GetActivitiesAsync();
foreach (var activity in result)
{
activity?.TransformForView();
}
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("matchActivities")]
[Obsolete("Moved to Processing Controller, please use endpoint QueueNightlyIncentiveProcess/UpdateReferralStatusProcess. Date: 1/1/2025")]
public async Task<IActionResult> GetMatchActivityTemp()
{
try
{
var results = await _activityService.MatchOrExpireReferrals();
return Ok(results);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("updateEStatementReferrals")]
[Obsolete("Moved to Processing Controller, please use endpoint QueueNightlyIncentiveProcess/UpdateEStatementProcess. Date: 1/1/2025")]
public async Task<IActionResult> GetDeliveryMethodsForEStatements()
{
try
{
var results = await _eStatementService.UpdateOrExpireEStatementReferral();
return Ok(results);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("RunDailyManualReviewRequery")]
[Obsolete("Moved to Processing Controller, please use endpoint QueueNightlyIncentiveProcess/UpdateAccountDecisionProcess. Date: 1/1/2025")]
public async Task<IActionResult> RunDailyManualReviewRequery()
{
try
{
var result = await _activityDecisionService.UpdateAndDecideManualReviewActivities();
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("RunDailyLICStationRequery")]
[Obsolete("Moved to Processing Controller, please use endpoint QueueNightlyIncentiveProcess/UpdateLICSalesProcess. Date: 1/1/2025")]
public async Task<IActionResult> RunDailyLICRequery()
{
try
{
var result = await _activityDecisionService.UpdateAndDecideLicReferralActivities();
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("RunDailyDirectDepositRequery")]
[Obsolete("Moved to Processing Controller, please use endpoint QueueNightlyIncentiveProcess/UpdateDirectDepositReferralsProcess. Date: 1/1/2025")]
public async Task<IActionResult> RunDailyDirectDepositRequery()
{
try
{
var result = await _activityDecisionService.UpdateAndDecideDirectDepositPendingReferralActivities();
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("RunDecisionService")]
[Obsolete("Moved to Processing Controller, please use endpoint QueueNightlyIncentiveProcess/UpdateAccountDecisionProcess. Date: 1/1/2025")]
public async Task<IActionResult> RunDecisionService()
{
try
{
Log.Information("RunDecisionService was forced");
var decisioned = await _activityDecisionService.DecisionActivityByState(ActivityState.Created);
Log.Information($"Auto-decisioned {decisioned.Count} activities in Created state");
decisioned = await _activityDecisionService.DecisionActivityByState(ActivityState.ManualReview);
Log.Information($"Auto-decisioned {decisioned.Count} activities in Manual Review state");
decisioned = await _activityDecisionService.UpdateAndDecideManualReviewActivities();
Log.Information($"Updated and Auto-Decisioned {decisioned.Count} Activities");
decisioned = await _activityDecisionService.UpdateAndDecideDpEligibleLoanActivities();
Log.Information($"Updated and Auto-Decisioned {decisioned.Count} Debt Protection Eligible Loan Activities");
return Ok();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,147 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement.Mvc;
using LCU.API.Internal.Operations.IncentiveApi.Services.QueueServices;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.IncentiveApiModels.Requests;
using LCU.API.Internal.Operations.IncentiveApi.Configuration;
namespace LCU.API.Internal.Operations.IncentiveApi.Controllers;
[FeatureGate(FeatureFlags.EnableControllers)]
[ApiController]
[Route("api/[controller]")]
public class ActivityImportController : ControllerBase
{
private readonly IQueueCreditCardImportService _queueCreditCardImportService;
private readonly IQueueIndirectVehicleImportService _queueIndirectVehicleImportService;
private readonly IQueueActionCreditCardService _queueActionCreditCardService;
private readonly IQueueActionVehicleService _queueActionVehicleService;
private readonly IQueueAlliedGapMbpService _queueAlliedGapMbpService;
public ActivityImportController(IQueueCreditCardImportService queueCreditCardImportService,
IQueueIndirectVehicleImportService queueIndirectVehicleImportService, IQueueActionCreditCardService queueActionCreditCardService,
IQueueActionVehicleService queueActionVehicleService, IQueueAlliedGapMbpService queueAlliedGapMbpService)
{
_queueCreditCardImportService = queueCreditCardImportService;
_queueIndirectVehicleImportService = queueIndirectVehicleImportService;
_queueActionCreditCardService = queueActionCreditCardService;
_queueActionVehicleService = queueActionVehicleService;
_queueAlliedGapMbpService = queueAlliedGapMbpService;
}
[HttpPost("QueueCreditCardImportRequest")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueCreditCardImportRequest([FromBody] ImportCreditCardSalesRequest request)
{
try
{
await _queueCreditCardImportService.QueueCreditCardSalesImport(request);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("QueueIndirectVehicleImportRequest")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueIndirectVehicleImportRequest([FromBody] ImportIndirectVehicleSalesRequest request)
{
try
{
await _queueIndirectVehicleImportService.QueueIndirectVehicleSalesImport(request);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("QueueActionCreditCardRequest")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueActionCreditCardRequest([FromBody] ActionCreditCardRequest request)
{
try
{
await _queueActionCreditCardService.QueueActionCreditCardProcess(request);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("QueueActionVehicleRequest")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueActionVehicleRequest([FromBody] ActionVehicleRequest request)
{
try
{
await _queueActionVehicleService.QueueActionVehicleProcess(request);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("QueueAlliedGapMbpRequest")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueAlliedGapMbpRequest([FromBody] AlliedGapMbpRequest request)
{
try
{
await _queueAlliedGapMbpService.QueueGapMbpProcess(request);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,64 @@
using LCU.API.Internal.Operations.IncentiveApi.Exceptions;
using LCU.API.Internal.Operations.IncentiveApi.Services;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement.Mvc;
using LCU.API.Internal.Operations.IncentiveApi.Configuration;
using LCU.Library.Internal.IncentiveApiModels.Entities;
namespace LCU.API.Internal.Operations.IncentiveApi.Controllers;
[FeatureGate(FeatureFlags.EnableControllers)]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Route("api/[controller]")]
[ApiController]
public class CommissionController : ControllerBase
{
private readonly ICommissionService _commissionService;
public CommissionController(ICommissionService commissionService)
{
_commissionService = commissionService;
}
[HttpGet("")]
public async Task<IActionResult> Get()
{
try
{
var results= await _commissionService.GetCommissionsAsync();
return Ok(results);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPut("")]
public async Task<IActionResult> SetCommissions(List<Commission> commissions)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
await _commissionService.SaveCommissionsAsync(commissions);
return NoContent();
}
catch (CommissionExistsException ex)
{
return Conflict(ex.Message);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,88 @@
using LCU.API.Internal.Operations.IncentiveApi.Exceptions;
using LCU.API.Internal.Operations.IncentiveApi.Services;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement.Mvc;
using LCU.API.Internal.Operations.IncentiveApi.Configuration;
using LCU.Library.Internal.IncentiveApiModels.Entities;
using LCU.Library.Internal.IncentiveApiModels.Common;
namespace LCU.API.Internal.Operations.IncentiveApi.Controllers;
[FeatureGate(FeatureFlags.EnableControllers)]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[ApiController]
[Route("api/[controller]")]
public class DeadActivityController: ControllerBase
{
private readonly IDeadActivityService _deadActivityService;
public DeadActivityController(IDeadActivityService deadActivityService)
{
_deadActivityService = deadActivityService;
}
[HttpGet("paged")]
[ProducesResponseType(typeof(PagedResponse<DeadActivity>), 200)]
public async Task<IActionResult> Get([FromQuery] DeadActivityFilter filter)
{
try
{
var searchResult = await _deadActivityService.ListByFilterAsync(filter);
foreach (var activity in searchResult.Items)
{
activity?.TransformForView();
}
var result = new PagedResponse<DeadActivity>(searchResult, filter, Url, Request);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("{activityId}")]
public async Task<IActionResult> Get([FromRoute] int activityId)
{
try
{
var result = await _deadActivityService.GetDeadActivity(activityId);
result?.TransformForView();
return Ok(result);
}
catch (NotFoundException)
{
return BadRequest("DeadActivity Not Found.");
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpDelete("{activityId}")]
public async Task<IActionResult> Delete([FromRoute] int activityId, [FromQuery] int activityRef = -1)
{
try
{
var result = await _deadActivityService.ProcessDeadActivity(activityId, activityRef);
result?.TransformForView();
return Ok(result);
}
catch (NotFoundException)
{
return BadRequest("DeadActivity Not Found.");
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,165 @@
using LCU.API.Internal.Operations.IncentiveApi.Exceptions;
using LCU.API.Internal.Operations.IncentiveApi.Services;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement.Mvc;
using LCU.API.Internal.Operations.IncentiveApi.Configuration;
using LCU.API.Internal.Operations.IncentiveApiLib.Services;
using LCU.Library.Internal.IncentiveApiModels.Entities;
using LCU.API.Internal.Operations.IncentiveApiLib.Persistence;
namespace LCU.API.Internal.Operations.IncentiveApi.Controllers;
[FeatureGate(FeatureFlags.EnableControllers)]
[ApiController]
[Route("api/[controller]")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class DepartmentController : ControllerBase
{
private readonly IDepartmentService _departmentService;
private readonly IUserService _userService;
private readonly ICurrentUserService _currentUser;
public DepartmentController(IDepartmentService departmentService, IUserService userService, ICurrentUserService currentUser)
{
_departmentService = departmentService;
_userService = userService;
_currentUser = currentUser;
}
[HttpGet("", Name = "GetAllDepartments")]
public async Task<IActionResult> GetDepartments([FromQuery] bool? canEditDepartmentGoals, [FromQuery] bool? canEditPersonnelGoals)
{
try
{
if (canEditDepartmentGoals != null || canEditPersonnelGoals != null)
{
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return Unauthorized("No AD User Found.");
}
if (canEditDepartmentGoals.HasValue)
{
return Ok(await _departmentService.GetHierarchicalDepartmentsForEmployeeAsync(employee, false));
}
if (canEditPersonnelGoals.HasValue)
{
return Ok( await _departmentService.GetHierarchicalDepartmentsForEmployeeAsync(employee, true));
}
}
var result = await _departmentService.GetAllDepartmentsAsync();
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("{departmentId:int}", Name = "GetDepartmentById")]
public async Task<IActionResult> GetDepartmentById([FromRoute] int departmentId)
{
try
{
var result = await _departmentService.GetDepartmentByIdAsync(departmentId);
return Ok(result);
}
catch (NotFoundException)
{
return NotFound($"Could not find Department with that Id");
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("", Name = "CreateNewDepartment")]
public async Task<IActionResult> CreateDepartment([FromBody] Department newDepartment)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (newDepartment.Id != null)
{
return BadRequest("Id Field Cannot Be Assigned");
}
var result = await _departmentService.SaveDepartmentAsync(newDepartment);
return (Ok(result));
}
catch (DuplicateDataException)
{
return BadRequest($"Department Name Must Be Unique.");
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPut("{id:int}", Name = "UpdateExistingDepartment")]
public async Task<IActionResult> UpdateDepartment([FromBody] Department newDepartment, [FromRoute] int id)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var result = await _departmentService.UpdateDepartmentAsync(newDepartment, id);
return (Ok(result));
}
catch (DuplicateDataException)
{
return BadRequest($"Department Name Must Be Unique.");
}
catch (NotFoundException)
{
return NotFound($"Could not find Department with that Id");
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("{id:int}/details", Name = "GetDepartmentDetails")]
public async Task<IActionResult> GetDepartmentDetails([FromRoute] int id)
{
try
{
var details = await _departmentService.GetDepartmentDetailsAsync(id);
return Ok(details);
}
catch (NotFoundException ex)
{
return NotFound(ex.Message);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,366 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement.Mvc;
using LCU.API.Internal.Operations.IncentiveApi.Configuration;
using LCU.API.Internal.Operations.IncentiveApi.Extensions;
using LCU.API.Internal.Operations.IncentiveApiLib.Services;
using LCU.API.Internal.Operations.IncentiveApiLib.Persistence;
using LCU.Library.Internal.IncentiveApiModels.Requests;
using LCU.Library.Internal.IncentiveApiModels.Common;
using LCU.API.Internal.Operations.IncentiveApi.Models.DataTransfer;
using LCU.API.Internal.Operations.IncentiveApi.Models.Dayforce;
using LCU.API.Internal.Operations.IncentiveApi.Authorization;
using LCU.API.Internal.Operations.IncentiveApi.Exceptions;
using LCU.API.Internal.Operations.IncentiveApi.Services.Dayforce;
namespace LCU.API.Internal.Operations.IncentiveApi.Controllers;
[FeatureGate(FeatureFlags.EnableControllers)]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[ApiController]
[Route("api/[controller]")]
public class EmployeeController : ControllerBase
{
private readonly ICurrentUserService _currentUserService;
private readonly IDayForceSyncService _dayForceSyncService;
private readonly IUserService _userService;
public EmployeeController(
ICurrentUserService currentUserService,
IDayForceSyncService dayForceSyncService,
IUserService userService
)
{
_currentUserService = currentUserService;
_dayForceSyncService = dayForceSyncService;
_userService = userService;
}
[HttpGet("")]
public async Task<IActionResult> GetAllUsers([FromQuery] string query, [FromQuery] string role)
{
try
{
var searchRequest = new UserSearchRequest
{
Query = query,
Role = role
};
var result = await _userService.GetAllUsersAsync(searchRequest);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("terminated")]
[RequirePermission("GENERATE_PAYOUT_FILES")]
public IActionResult GetTerminatedUsers([FromQuery] int month, [FromQuery] int year)
{
try
{
var monthRange = new MonthRange(year, month);
var result = _userService.GetTerminatedUsersAsync(monthRange);
return Ok(result);
}
catch (ArgumentException ex)
{
Log.Error(ex, $"Bad Request in {GetType().Name}");
return BadRequest(ex.Message);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("resolve")]
public async Task<IActionResult> ResolveUser(
[FromQuery] string employeeId = null,
[FromQuery] string email = null
)
{
try
{
var count = 0;
if (!string.IsNullOrWhiteSpace(employeeId))
{
count++;
}
if (!string.IsNullOrWhiteSpace(email))
{
count++;
}
if (count > 1)
{
return BadRequest("Please provide only one query argument.");
}
var result = await _userService.FindUserAsync(employeeId, email);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("me")]
public async Task<IActionResult> GetCurrentEmployee()
{
try
{
var currentUser = _currentUserService.GetCurrentUser();
if (currentUser?.Email == null)
{
Log.Warning("Failed To Get Current User From Auth Context");
return Unauthorized("No AD User Found.");
}
var result = await _userService.GetUserByAdEmailAsync(currentUser.Email);
if (result == null)
{
Log.Warning($"Failed To Get Current User From Email: {currentUser.Email}");
return NoContent();
}
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("{employeeId}")]
[RequirePermission("ASSIGN_PERMISSIONS_TO_ASSOCIATES,ASSIGN_ASSOCIATES_TO_DEPARTMENT")]
public async Task<IActionResult> GetEmployeeById(string employeeId = null)
{
try
{
if (employeeId == null)
{
return BadRequest("no_employee_id");
}
var result = await _userService.GetUserByEmployeeIdAsync(employeeId);
if (result == null)
{
return NoContent();
}
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[RequirePermission("ASSIGN_ASSOCIATES_TO_DEPARTMENT")]
[HttpPost("{employeeId}/AssignDept", Name = "AssignDept")]
public async Task<IActionResult> AssignDepartment(
string employeeId,
[FromBody] DepartmentAssignmentRequest assignment
)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState.GetErrorMessages());
}
try
{
var currentUser = _currentUserService.GetCurrentUser();
if (currentUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(currentUser.Email);
if (UserService.ValidateChangePermission(employee.EmployeeId, employeeId))
{
return StatusCode(403, "Not allowed to assign yourself to a department.");
}
await _userService.AssignDepartments(employeeId, assignment);
return (Ok());
}
catch (NotFoundException ex)
{
return NotFound(ex.Message);
}
catch (BadDepartmentAssignmentException ex)
{
return BadRequest(ex.Message);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPut("{employeeId}/UpdatePerms", Name = "UpdatePerms")]
public async Task<IActionResult> AssignPermission(
string employeeId,
[FromBody] AdditionalPermissionRequest request
)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState.GetErrorMessages());
}
try
{
var response = await _userService.UpdatePermissions(employeeId, request);
return Ok(response);
}
catch (NotFoundException ex)
{
return NotFound(ex.Message);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[RequirePermission("ASSIGN_ASSOCIATES_TO_DEPARTMENT")]
[HttpPost("{employeeId}/UpdateDept/{assignmentId:int}", Name = "UpdateDept")]
public async Task<IActionResult> UpdateDepartmentAssignment(
string employeeId,
int assignmentId,
[FromBody] DepartmentUpdateRequest request
)
{
try
{
var currentUser = _currentUserService.GetCurrentUser();
if (currentUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(currentUser.Email);
if (UserService.ValidateChangePermission(employee.EmployeeId, employeeId))
{
return StatusCode(403, "Not allowed to terminate yourself from a department.");
}
await _userService.UpdateDepartmentAssignment(request);
return (Ok());
}
catch (NotFoundException ex)
{
return NotFound(ex.Message);
}
catch (BadDepartmentAssignmentException ex)
{
return BadRequest(ex.Message);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("GetHcmSystemUsers")]
[RequirePermission("MANAGE_EMPLOYEE_DETAILS")]
public async Task<IActionResult> GetHcmSystemUsers(string email = "", string employeeId = "", string fullName = "")
{
try
{
var result = await _dayForceSyncService.GetMatchingHcmUsers(email, employeeId, fullName);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("UpdateEmployeeDetails", Name = "UpdateEmployeeDetails")]
[RequirePermission("MANAGE_EMPLOYEE_DETAILS")]
public async Task<IActionResult> UpdateEmployeeDetails([FromBody] EmployeeDetailsUpdate request)
{
try
{
var currentUser = _currentUserService.GetCurrentUser();
if (currentUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var result = await _userService.GetUserByAdEmailAsync(request.OldEmail);
if (result == null)
{
return NoContent();
}
var updatedUserResult = await _dayForceSyncService.UpdateEmployeeDetails(request);
if (updatedUserResult.UpdatedSuccessfully)
{
return Ok(updatedUserResult);
}
return BadRequest(updatedUserResult);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("SyncEmployeeIds")]
[RequirePermission("MANAGE_EMPLOYEE_DETAILS")]
public async Task<IActionResult> SyncEmployeeIds()
{
try
{
var result = await _userService.SyncActiveUserIds();
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("sync", Name = "ForceRefresh")]
public async Task<IActionResult> SyncDayForce()
{
try
{
Log.Information("DayForce Sync was forced");
var request = new DayforceProcessRequest();
await _dayForceSyncService.SyncDayForceUsers(request);
Log.Information("DayForce forced Sync has completed");
return Ok();
}
catch (Exception ex)
{
Log.Information("DayForce forced Sync has failed");
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,268 @@
using LCU.Library.Internal.IncentiveApiModels.Entities;
using LCU.Library.Internal.IncentiveApiModels.Common;
using LCU.Library.Internal.IncentiveApiModels.Requests;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement.Mvc;
using LCU.API.Internal.Operations.IncentiveApi.Services;
using LCU.API.Internal.Operations.IncentiveApi.Models.DataTransfer;
using LCU.API.Internal.Operations.IncentiveApi.Models.GoalDispersal;
using LCU.API.Internal.Operations.IncentiveApi.Authorization;
using LCU.API.Internal.Operations.IncentiveApi.Configuration;
using LCU.API.Internal.Operations.IncentiveApiLib.Services;
using LCU.API.Internal.Operations.IncentiveApiLib.Persistence;
namespace LCU.API.Internal.Operations.IncentiveApi.Controllers;
[FeatureGate(FeatureFlags.EnableControllers)]
[ApiController]
[Route("api/[controller]")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class GoalController : ControllerBase
{
private readonly IGoalService _goalService;
private readonly IGoalDispersalService _goalDispersalService;
private readonly IUserService _userService;
private readonly ICurrentUserService _currentUser;
public GoalController(IGoalService goalService, IGoalDispersalService goalDispersalService, ICurrentUserService currentUser, IUserService userService)
{
_goalService = goalService;
_currentUser = currentUser;
_userService = userService;
_goalDispersalService = goalDispersalService;
}
[HttpGet("", Name = "GetGoals")]
public async Task<IActionResult> GetGoals([FromQuery] int fromMonth, [FromQuery] int fromYear,
[FromQuery] int toMonth, [FromQuery] int toYear, [FromQuery] int departmentId,
[FromQuery] bool includePersonnel = true)
{
try
{
var monthRange = new MonthRange(fromYear, fromMonth, toYear, toMonth);
var query = new GoalSearchRequest()
{
DateRange = monthRange,
departmentId = departmentId,
IncludePersonnel = includePersonnel
};
var result = await _goalService.GetGoalsAsync(query);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("department/", Name = "GetAllDepartmentsGoals")]
public async Task<IActionResult> GetAllDepartmentsGoals([FromQuery] int year)
{
try
{
var searchYear = year > 0 ? year : DateTime.Now.Year;
var result = await _goalService.GetAllAnnualDepartmentGoalsAsync(searchYear);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("department/{departmentId}", Name = "GetDepartmentGoals")]
public async Task<IActionResult> GetDepartmentGoals(int departmentId, [FromQuery] int year)
{
try
{
var searchYear = year > 0 ? year : DateTime.Now.Year;
var result = await _goalService.GetAnnualDepartmentGoalsAsync(departmentId, searchYear);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("personnel/{departmentId}", Name = "GetPersonnelGoals")]
public async Task<IActionResult> GetPersonnelGoals(int departmentId, [FromQuery] int month,
[FromQuery] int year, [FromQuery] bool includeAllPersonnel = false)
{
try
{
var searchYear = year > 0 ? year : DateTime.Now.Year;
var searchMonth = month > 0 ? month : DateTime.Now.Month;
var searchRequest = new DepartmentPersonnelSearchRequest()
{
DepartmentId = departmentId,
Month = searchMonth,
Year = searchYear,
IncludeAllPersonnel = includeAllPersonnel
};
var result = await _goalService.GetMonthlyPersonnelGoalsAsync(searchRequest);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("personnel/{departmentId}/disperse", Name = "DisperseByExtrapolation")]
public async Task<IActionResult> GetPersonnelGoals(int departmentId, [FromBody] ExtrapolateGoalDispersalRequest request)
{
try
{
var result = await _goalDispersalService.DisperseGoalsByExtrapolatingLastMonth(departmentId, request.Month, request.Year);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("me", Name = "GetCurrentUserGoals")]
[RequirePermission("VIEW_DASHBOARD")]
public async Task<IActionResult> GetCurrentUserGoals([FromQuery] int fromMonth, [FromQuery] int fromYear,
[FromQuery] int toMonth, [FromQuery] int toYear)
{
try
{
var monthRange = new MonthRange(fromYear, fromMonth, toYear, toMonth);
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
var result = await _goalService.GetEmployeeGoalsForMonthRangeAsync(employee, monthRange);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("me/departments", Name = "GetCurrentUserDepartmentsGoals")]
[RequirePermission("VIEW_DASHBOARD,VIEW_PERFORMANCE_FOR_DEPARTMENT")]
public async Task<IActionResult> GetCurrentUserDepartmentsGoals([FromQuery] int fromMonth,
[FromQuery] int fromYear,
[FromQuery] int toMonth, [FromQuery] int toYear)
{
try
{
var monthRange = new MonthRange(fromYear, fromMonth, toYear, toMonth);
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
var result = await _goalService.GetEmployeeDepartmentsGoalsForMonthRangeAsync(employee, monthRange);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost]
public async Task<IActionResult> SetGoalForAudienceAndTimePeriod(GoalChange goalChange)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var result = await _goalService.SaveGoalAsync(goalChange);
return Created($"{result.Select(x => x.Id)}", result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("multi")]
public async Task<IActionResult> SetGoalsForAudienceAndTimePeriod(List<GoalChange> goalChanges)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var result = await _goalService.SaveGoalRangeAsync(goalChanges);
return Created($"{result.Count}", result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("DisperseAll")]
public async Task<IActionResult> DisperseAll(GoalDispersalRequest request)
{
try
{
await _goalDispersalService.ExecuteMonthStartDispersal(request);
return Ok();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("personnel/CustomWeightedDispersal")]
public async Task<IActionResult> CustomWeightedDispersal([FromBody] CustomWeightedDispersalRequest request)
{
try
{
var result = await _goalDispersalService.CustomWeightedDispersal(request);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}.");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,59 @@
using LCU.API.Internal.Operations.IncentiveApi.HostedServices;
using LCU.Library.Internal.Exceptions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace LCU.API.Internal.Operations.IncentiveApi.Controllers
{
public class HostedServicesController : ControllerBase
{
private readonly IApplicationDbIntegrityHostedService _applicationDbIntegrityHostedServiceStarter;
public HostedServicesController(IApplicationDbIntegrityHostedService applicationDbIntegrityHostedServiceStarter)
{
_applicationDbIntegrityHostedServiceStarter = applicationDbIntegrityHostedServiceStarter;
}
[HttpPost("StartApplicationDbIntegrity", Name = "StartApplicationDbIntegrity")]
[ProducesResponseType(200)]
[ProducesResponseType(500)]
public async Task<IActionResult> StartApplicationDbIntegrity()
{
try
{
await _applicationDbIntegrityHostedServiceStarter.StartAsync();
return Ok();
}
catch (ServiceException)
{
return StatusCode(StatusCodes.Status500InternalServerError);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("StopApplicationDbIntegrity", Name = "StopApplicationDbIntegrity")]
[ProducesResponseType(200)]
[ProducesResponseType(500)]
public async Task<IActionResult> StopApplicationDbIntegrity()
{
try
{
await _applicationDbIntegrityHostedServiceStarter.StopAsync();
return Ok();
}
catch (ServiceException)
{
return StatusCode(StatusCodes.Status500InternalServerError);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
}
@@ -0,0 +1,261 @@
using LCU.API.Internal.Operations.IncentiveApi.Services;
using LCU.API.Internal.Operations.IncentiveApi.Services.Payout;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement.Mvc;
using LCU.API.Internal.Operations.IncentiveApi.Authorization;
using LCU.API.Internal.Operations.IncentiveApi.Configuration;
using LCU.API.Internal.Operations.IncentiveApiLib.Services;
using LCU.Library.Internal.IncentiveApiModels.Common;
using LCU.API.Internal.Operations.IncentiveApiLib.Persistence;
using LCU.Library.Internal.IncentiveApiModels.Requests;
namespace LCU.API.Internal.Operations.IncentiveApi.Controllers;
[FeatureGate(FeatureFlags.EnableControllers)]
[ApiController]
[Route("api/[controller]")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class PayoutController : ControllerBase
{
private readonly IPayoutService _payoutService;
private readonly IUserService _userService;
private readonly IActivityService _activityService;
private readonly ICurrentUserService _currentUser;
public PayoutController(IPayoutService payoutService, IUserService userService, ICurrentUserService currentUser, IActivityService activityService)
{
_payoutService = payoutService;
_userService = userService;
_currentUser = currentUser;
_activityService = activityService;
}
[HttpGet("{employeeId}", Name = "GetEmployeePayout")]
[RequirePermission("VIEW_DASHBOARD")]
public async Task<IActionResult> GetEmployeePayout(string employeeId, [FromQuery] int year,
[FromQuery] int month)
{
try
{
var searchYear = year > 0 ? year : DateTime.Now.Year;
var searchMonth = month > 0 ? month : DateTime.Now.Month;
var employee = await _userService.GetUserByEmployeeIdAsync(employeeId);
if (employee == null)
{
return NoContent();
}
var result =
await _payoutService.RetrieveCombinedDepartmentPayouts(employee, new MonthRange(searchYear, searchMonth));
return Ok( result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("me", Name = "GetCurrentUserPayout")]
[RequirePermission("VIEW_DASHBOARD")]
public async Task<IActionResult> GetCurrentUserPayout( [FromQuery] int year, [FromQuery] int month)
{
try
{
var searchYear = year > 0 ? year : DateTime.Now.Year;
var searchMonth = month > 0 ? month : DateTime.Now.Month;
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
var result =
await _payoutService.CreateCombinedDepartmentPayouts(employee, new MonthRange(searchYear, searchMonth));
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("export", Name = "ExportMonthlyPayout")]
[RequirePermission("GENERATE_PAYOUT_FILES")]
public async Task<IActionResult> ExportMonthlyPayout([FromQuery] int year,
[FromQuery] int month)
{
try
{
var searchYear = year > 0 ? year : DateTime.Today.Year;
var searchMonth = month > 0 ? month : DateTime.Today.Month;
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
var period = new DateTime(searchYear, searchMonth, 1);
var payouts = await _payoutService.RetrieveMonthlyIncentivePayouts(period);
return Ok(payouts);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("runMonthly", Name = "RunMonthlyPayout")]
[RequirePermission("GENERATE_PAYOUT_FILES")]
public async Task<IActionResult> RunMonthlyPayout([FromQuery] int monthsBack = 0)
{
try
{
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
var request = new PayoutIncentiveRequest()
{
MonthsBack = monthsBack
};
var payouts = await _payoutService.CreateMonthlyIncentivePayouts(request);
return Ok(payouts);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("runAccounting", Name = "RunMonthlyAccounting")]
[RequirePermission("GENERATE_PAYOUT_FILES")]
public async Task<IActionResult> RunMonthlyAccounting([FromQuery] int monthsBack = 0)
{
try
{
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
var period = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
period = period.AddMonths( -1 * monthsBack);
var range = new MonthRange(period);
var payouts = await _payoutService.CreateMonthlyAccountingPayouts(range);
return Ok(payouts);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("getAccounting", Name = "GetMonthlyAccounting")]
[RequirePermission("GENERATE_PAYOUT_FILES")]
public async Task<IActionResult> GetMonthlyAccounting([FromQuery] DateTime period)
{
try
{
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
var range = new MonthRange(period);
var payouts = await _payoutService.RetrieveMonthlyAccountingPayouts(range);
return Ok(payouts);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("runMonthlySingle", Name = "RunMonthlyPayoutSingle")]
[RequirePermission("GENERATE_PAYOUT_FILES")]
public async Task<IActionResult> RunMonthlyPayoutSingle([FromQuery] string employeeId, [FromQuery] int monthsBack = 0)
{
try
{
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var employee = await _userService.GetUserByEmployeeIdAsync(employeeId);
if (employee == null)
{
return NoContent();
}
var period = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
period = period.AddMonths( -1 * monthsBack);
var range = new MonthRange(period);
var payouts = await _payoutService.CreateCombinedDepartmentPayouts(employee, range);
return Ok(payouts);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,393 @@
using LCU.API.Internal.Operations.IncentiveApiLib.Persistence;
using LCU.API.Internal.Operations.IncentiveApi.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement.Mvc;
using LCU.API.Internal.Operations.IncentiveApiLib.Services;
using LCU.API.Internal.Operations.IncentiveApi.Services.Allied;
using LCU.API.Internal.Operations.IncentiveApi.Services.Action;
using LCU.API.Internal.Operations.IncentiveApi.Models.Action;
using LCU.Library.Internal.IncentiveApiModels.Common;
using LCU.Library.Internal.IncentiveApiModels.Requests;
using LCU.API.Internal.Operations.IncentiveApi.Configuration;
using LCU.API.Internal.Operations.IncentiveApi.Models.Allied;
using LCU.API.Internal.Operations.IncentiveApi.Services.QueueServices;
using LCU.Library.Internal.Exceptions;
using System.Threading;
namespace LCU.API.Internal.Operations.IncentiveApi.Controllers;
[FeatureGate(FeatureFlags.EnableControllers)]
[ApiController]
[Route("api/[controller]")]
public class ProcessingController : Controller
{
private readonly IActionCreditCardImportService _actionCreditCardImportService;
private readonly IActionVehicleImportService _actionVehicleImportService;
private readonly IAlliedGapMbpTransactionImportService _alliedTransactionImportService;
private readonly IApplicationDbIntegrityService _applicationDbIntegrityService;
private readonly IDnaActivitySyncService _dnaActivitySyncService;
private readonly IUserService _userService;
private readonly ICurrentUserService _currentUser;
private readonly IGapInsuranceActivityService _gapInsuranceActivityService;
private readonly IQueueIncentiveProcessesService _queueIncentiveProcessService;
private readonly IQueueNightlyIncentiveProcessesService _queueNightlyIncentiveProcessService;
private readonly IQueueReportingService _queueReportingService;
private readonly IQueuePayoutIncentiveService _queuePayoutIncentiveService;
private readonly IQueueGoalDispersalService _queueGoalDispersalService;
private readonly IQueueDayforceSyncService _queueDayforceSyncService;
public ProcessingController(
IActionCreditCardImportService actionCreditCardImportService,
IActionVehicleImportService actionVehicleImportService,
IAlliedGapMbpTransactionImportService alliedTransactionImportService,
IApplicationDbIntegrityService applicationDbIntegrityService,
ICurrentUserService currentUserService,
IDnaActivitySyncService dnaActivitySyncService,
IUserService userService,
IGapInsuranceActivityService gapInsuranceActivityService,
IQueueIncentiveProcessesService queueIncentiveProcessService,
IQueueNightlyIncentiveProcessesService queueNightlyIncentiveProcessService,
IQueueReportingService queueReportingService, IQueuePayoutIncentiveService queuePayoutIncentiveService,
IQueueGoalDispersalService queueGoalDispersalService, IQueueDayforceSyncService queueDayforceSyncService
)
{
_actionCreditCardImportService = actionCreditCardImportService;
_actionVehicleImportService = actionVehicleImportService;
_alliedTransactionImportService = alliedTransactionImportService;
_applicationDbIntegrityService = applicationDbIntegrityService;
_currentUser = currentUserService;
_dnaActivitySyncService = dnaActivitySyncService;
_userService = userService;
_gapInsuranceActivityService = gapInsuranceActivityService;
_queueIncentiveProcessService = queueIncentiveProcessService;
_queueNightlyIncentiveProcessService = queueNightlyIncentiveProcessService;
_queueReportingService = queueReportingService;
_queuePayoutIncentiveService = queuePayoutIncentiveService;
_queueGoalDispersalService = queueGoalDispersalService;
_queueDayforceSyncService = queueDayforceSyncService;
}
[HttpPost("QueueIncentiveProcess")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueIncentiveProcess([FromBody] IncentiveProcessRequest request)
{
try
{
await _queueIncentiveProcessService.QueueIncentiveProcess(request);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Incentive Process Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("QueueNightlyIncentiveProcess")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueNightlyIncentiveProcess([FromBody] NightlyIncentiveProcessRequest request)
{
try
{
await _queueNightlyIncentiveProcessService.QueueNightlyIncentiveProcess(request);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Nightly Incentive Process Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("QueuePayoutProcess")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueuePayoutProcess([FromBody] PayoutIncentiveRequest request)
{
try
{
await _queuePayoutIncentiveService.QueuePayoutIncentiveProcess(request);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("QueueReportingRequest")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueReportingRequest([FromBody] ReportingRequest request)
{
try
{
await _queueReportingService.QueueReportingProcess(request);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("QueueGoalDispersalSyncProcess")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueGoalDispersalSyncProcess([FromBody] GoalDispersalRequest request)
{
try
{
await _queueGoalDispersalService.QueueGoalDispersalProcess(request);
return Accepted();
}
catch (Exception ex)
{
Log.Information("Queue Goal Dispersal Process has failed");
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
}
}
[HttpPost("QueueDayforceSyncProcess")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueDayforceSyncProcess([FromBody] DayforceProcessRequest request)
{
try
{
await _queueDayforceSyncService.QueueDayforceSyncProcess(request);
return Accepted();
}
catch (Exception ex)
{
Log.Information("DayForce forced Sync has failed");
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
}
}
[HttpGet("RunAlliedImport")]
[Obsolete("Replaced with ActivityImport process, please use endpoint ActivityImport/QueueAlliedGapMbpRequest Date: 1/1/2025")]
public async Task<IActionResult> RunAlliedImport([FromBody] AlliedGapMbpRequest request)
{
try
{
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
Log.Information("No AppUser found");
return NoContent();
}
Log.Information($"Importing transactions from Allied, kicked off manually");
var imported = await _alliedTransactionImportService.ImportTransactions<AlliedSaleRow>(request);
Log.Information($"Imported {imported.Count} transactions from Allied");
return Ok();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("RunCreditCardImport")]
[Obsolete("Replaced with ActivityImport process, please use endpoint ActivityImport/QueueActionCreditCardRequest Date: 1/1/2025")]
public async Task<IActionResult> RunCreditCardImport(ActionCreditCardRequest request)
{
try
{
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
Log.Information($"Importing credit cards, kicked off manually");
var imported = await _actionCreditCardImportService.ImportTransactions<ActionCreditCardPersonalRow>("personal", request);
Log.Information($"Imported {imported.Count} credit cards - personal");
imported = await _actionCreditCardImportService.ImportTransactions<ActionCreditCardBusinessRow>("business", request);
Log.Information($"Imported {imported.Count} credit cards - business");
return Ok();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("RunVehicleImport")]
[Obsolete("Replaced with ActivityImport process, please use endpoint ActivityImport/QueueActionVehicleRequest Date: 1/1/2025")]
public async Task<IActionResult> RunVehicleImport([FromBody] ActionVehicleRequest request)
{
try
{
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
Log.Information($"Importing vehicles, kicked off manually");
var imported = await _actionVehicleImportService.ImportTransactions<ActionSaleRow>(request);
Log.Information($"Imported {imported.Count} vehicles");
return Ok();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("RunDnaSyncQuery")]
[Obsolete("Replaced with Incentive Processes, please use QueueIncentiveProcesses. Date: 1/1/2025")]
public async Task<IActionResult> RunDnaSyncQuery()
{
try
{
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
Log.Information("DNA Sync was forced");
await _dnaActivitySyncService.SyncLatestActivitiesFromDna();
return Ok();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("MatchOrRemoveGapAccessories")]
[Obsolete("Moved to Nightly Processes Controller. Please use QueueNightlyIncentiveProcesses. Date: 1/1/2025")]
public async Task<IActionResult> MatchOrRemoveGapAccessories(
[FromQuery] int fromMonth,
[FromQuery] int fromYear,
[FromQuery] int toMonth,
[FromQuery] int toYear
)
{
try
{
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
var monthRange = new MonthRange(fromYear, fromMonth, toYear, toMonth);
Log.Information("MatchOrRemoveGapAccessories was forced");
var updatedCount = await _gapInsuranceActivityService.MatchOrRemoveGapAccessories(monthRange);
Log.Information($"MatchOrRemoveGapAccessories updated {updatedCount} records");
return Ok();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("RunAppUserIdIntegrityMaintenance")]
[Obsolete("Moved to Nightly Processes Controller. Please use QueueNightlyIncentiveProcesses. Date: 1/1/2025")]
public async Task<IActionResult> RunAppUserIdIntegrityMaintenance()
{
try
{
var appUser = _currentUser.GetCurrentUser();
if (appUser?.Email == null)
{
return Unauthorized("No AD User Found");
}
var employee = await _userService.GetUserByAdEmailAsync(appUser.Email);
if (employee == null)
{
return NoContent();
}
Log.Information("AppUserId Integrity Maintenance was forced");
var token = new CancellationToken();
await _applicationDbIntegrityService.AppUserIdIntegrityMaintenanceSucceeded(token);
return Ok();
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,133 @@
using LCU.API.Internal.Operations.IncentiveApi.Services;
using LCU.API.Internal.Operations.IncentiveApi.Models.DataTransfer;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement.Mvc;
using LCU.API.Internal.Operations.IncentiveApi.Configuration;
using LCU.API.Internal.Operations.IncentiveApiLib.Services;
using LCU.API.Internal.Operations.IncentiveApi.Models;
using LCU.Library.Internal.IncentiveApiModels.Enums;
using LCU.API.Internal.Operations.IncentiveApiLib.Persistence;
namespace LCU.API.Internal.Operations.IncentiveApi.Controllers;
[ApiController]
[FeatureGate(FeatureFlags.EnableControllers)]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Route("api/[controller]")]
public class SettingsController : ControllerBase
{
private readonly ICurrentUserService _currentUserService;
private readonly IDateTime _dateTimeService;
private readonly IDepartmentService _departmentService;
private readonly ISettingsService _settingsService;
private readonly IUserService _userService;
public SettingsController(
ICurrentUserService currentUserService,
IDateTime dateTimeService,
IDepartmentService departmentService,
ISettingsService settingsService,
IUserService userService
)
{
_currentUserService = currentUserService;
_dateTimeService = dateTimeService;
_departmentService = departmentService;
_settingsService = settingsService;
_userService = userService;
}
[HttpGet("")]
[ProducesResponseType(200)]
public async Task<IActionResult> Get()
{
try
{
var settings = new Settings();
settings.Departments = await _departmentService.GetAllDepartmentsAsync();
settings.Employees = await _userService.GetAllUserSummariesAsync();
settings.NextBonusPeriod = _dateTimeService.getNextBonusPeriod(DateTime.Today);
var currentUser = _currentUserService.GetCurrentUser();
if (currentUser?.Email != null && currentUser.UserType() != UserType.System)
{
var appUser = await _userService.GetUserByAdEmailAsync(currentUser.Email);
settings.AuthorizedReports = await _settingsService.GetAuthorizedReportSettings(appUser);
Log.Debug($"Returning Settings For AppUser:{appUser.FullName}");
return Ok(settings);
}
Log.Warning("No Authorized AppUser Found, Returning Base Settings");
return Ok(settings);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode((int)System.Net.HttpStatusCode.InternalServerError);
}
}
[HttpGet("GetAllRoleMappings", Name = "GetAllRoleMappings")]
public async Task<IActionResult> GetAllRoleMappings()
{
try
{
var result = await _settingsService.GetRoleMappingsAsync();
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("UpdateRoleMapping", Name = "UpdateRoleMapping")]
public async Task<IActionResult> UpdateRoleMapping([FromBody] RoleMappingUpdateRequest request)
{
try
{
var currentUser = _currentUserService.GetCurrentUser();
if (currentUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
await _settingsService.SaveRoleMappingAsync(request);
return (Ok());
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("GetAuthorizedReportSettings", Name = "GetAuthorizedReportSettings")]
public async Task<IActionResult> GetAuthorizedReports()
{
try
{
var currentUser = _currentUserService.GetCurrentUser();
if (currentUser?.Email == null)
{
return Unauthorized("No AD User Found.");
}
var appUser = await _userService.GetUserByAdEmailAsync(currentUser.Email);
var result = await _settingsService.GetAuthorizedReportSettings(appUser);
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,132 @@
using LCU.API.Internal.Operations.IncentiveApiLib.Persistence;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.Status.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace LCU.API.Internal.Operations.IncentiveApi.Controllers;
[ApiController]
[Route("api/[controller]")]
public class StatusController : ControllerBase
{
private readonly IApiHealthCheckService _apiHealthCheckService;
private readonly IDateTime _dateTime;
public StatusController(IApiHealthCheckService apiHealthCheckService, IDateTime dateTime)
{
_apiHealthCheckService = apiHealthCheckService;
_dateTime = dateTime;
}
[HttpGet]
[ProducesResponseType(200)]
public IActionResult Get()
{
try
{
return Ok(_apiHealthCheckService.CheckApiHealthAndBuildEnvironmentView());
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("LocalTime")]
[ProducesResponseType(200)]
public IActionResult GetLocalTime()
{
try
{
return Ok(_dateTime.Now);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode((int) System.Net.HttpStatusCode.InternalServerError);
}
}
[HttpGet("UtcTime")]
[ProducesResponseType(200)]
public IActionResult GetUTCTime()
{
try
{
return Ok(_dateTime.UTCNow);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode((int) System.Net.HttpStatusCode.InternalServerError);
}
}
[HttpGet("WindowsCstTime")]
[ProducesResponseType(200)]
public IActionResult GetWindowsCSTTime()
{
try
{
return Ok(_dateTime.CSTWindowsNow);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode((int) System.Net.HttpStatusCode.InternalServerError);
}
}
[HttpGet("LinuxCstTime")]
[ProducesResponseType(200)]
public IActionResult GetLinuxCSTTime()
{
try
{
return Ok(_dateTime.CSTLinuxNow);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode((int) System.Net.HttpStatusCode.InternalServerError);
}
}
[HttpGet("ConvertCSTToUTCWindows/{dateTimeString}")]
[ProducesResponseType(200)]
public IActionResult ConvertCSTToUTCWindows(string dateTimeString)
{
try
{
var convertedTime = _dateTime.ConvertDateTimeFromCSTToUTCWindows(dateTimeString);
return Ok(convertedTime);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode((int) System.Net.HttpStatusCode.InternalServerError);
}
}
[HttpGet("ConvertCSTToUTCLinux/{dateTimeString}")]
[ProducesResponseType(200)]
public IActionResult ConvertCSTToUTCLinux(string dateTimeString)
{
try
{
var convertedTime = _dateTime.ConvertDateTimeFromCSTToUTCLinux(dateTimeString);
return Ok(convertedTime);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode((int) System.Net.HttpStatusCode.InternalServerError);
}
}
}
@@ -0,0 +1,63 @@
using LCU.API.Internal.Operations.IncentiveApi.Exceptions;
using LCU.API.Internal.Operations.IncentiveApi.Services;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement.Mvc;
using LCU.API.Internal.Operations.IncentiveApi.Authorization;
using LCU.API.Internal.Operations.IncentiveApi.Configuration;
using LCU.API.Internal.Operations.IncentiveApi.Models.DataTransfer;
using LCU.Library.Internal.IncentiveApiModels.Enums;
namespace LCU.API.Internal.Operations.IncentiveApi.Controllers;
[FeatureGate(FeatureFlags.EnableControllers)]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[ApiController]
[Route("api/[controller]")]
public class UserAssignmentController : ControllerBase
{
private readonly IUserAssignmentService _userAssignmentService;
public UserAssignmentController(IUserAssignmentService userAssignmentService)
{
_userAssignmentService = userAssignmentService;
}
[HttpGet("")]
public async Task<IActionResult> GetAllUserAssignments()
{
try
{
var result = await _userAssignmentService.GetAllUserAssignmentsAsync();
return Ok(result);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[RequirePermission("ASSIGN_REGIONAL_MANAGER")]
[HttpPost("SetRegionalManager", Name = "SetRegionalManager")]
public async Task<IActionResult> SetRegionalManager([FromBody] UserAssignmentRequest assignmentRequest)
{
try
{
assignmentRequest.Type = AssignmentType.RegionalManager;
var result = await _userAssignmentService.SetRegionalManager(assignmentRequest);
return Ok();
}
catch (BadUserAssignmentException ex)
{
return BadRequest(ex.Message);
}
catch (Exception ex)
{
Log.Error(ex, $"Failure in {GetType().Name}");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,222 @@
using System.Globalization;
using System.Web;
using Newtonsoft.Json;
using LCU.API.Internal.Operations.IncentiveApi.Models.Core;
using LCU.API.Internal.Operations.IncentiveApi.Models.ExternalActivities;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Accounts;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Activity;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Transaction;
using LCU.Library.Internal.CoreApiWrapperModel.LcuModels.Account;
using LCU.Library.Internal.IncentiveApiModels.Entities;
using LCU.API.Internal.Operations.IncentiveApi.Configuration;
using LCU.Library.Internal.LcuHttpClient.HttpRequest;
using NewAtmCheckCardActivity = LCU.API.Internal.Operations.IncentiveApi.Models.ExternalActivities.NewAtmCheckCardActivity;
using NewCheckingAccountActivity = LCU.API.Internal.Operations.IncentiveApi.Models.ExternalActivities.NewCheckingAccountActivity;
using NewLoanSaleActivity = LCU.API.Internal.Operations.IncentiveApi.Models.ExternalActivities.NewLoanSaleActivity;
using System.Net;
namespace LCU.API.Internal.Operations.IncentiveApi.DataAccess;
public class CoreApiWrapperDao : ICoreApiWrapperDao
{
private readonly IGetRequest _getRequest;
private readonly IPostRequest _postRequest;
private readonly CoreApiWrapperConfiguration _coreApiWrapperConfiguration;
public CoreApiWrapperDao(CoreApiWrapperConfiguration coreApiWrapperConfiguration, IGetRequest getRequest, IPostRequest postRequest)
{
_getRequest = getRequest;
_postRequest = postRequest;
_coreApiWrapperConfiguration = coreApiWrapperConfiguration;
}
public async Task<IReadOnlyCollection<NewCheckingAccountActivity>> GetNewCheckingAccountSalesActivity(DateTime activityDt)
{
try
{
var url = _coreApiWrapperConfiguration.GetNewCheckingAccountActivityUrl + $"?newerThanDateTime={DateTimeToUrlString(activityDt)}";
var coreResponse = await _getRequest.AsyncWithNewton<CoreResponse<NewCheckingAccountActivity>>(url, null, 0, 300);
return coreResponse.Result;
}
catch (Exception ex)
{
Log.Error(ex, "Error Getting New Checking Account Sales from DNA");
throw;
}
}
public async Task<IReadOnlyCollection<NewCheckingAccountActivity>> GetNewCheckingDigitalBankingAccountSalesActivity(DateTime activityDt)
{
try
{
var url = _coreApiWrapperConfiguration.GetNewDigitalBankingCheckingAccountActivityUrl + $"?newerThanDateTime={DateTimeToUrlString(activityDt)}";
var coreResponse = await _getRequest.AsyncWithNewton<CoreResponse<NewCheckingAccountActivity>>(url,null, 0, 300);
return coreResponse.Result;
}
catch (Exception ex)
{
Log.Error(ex, "Error Getting New Checking Account Sales from DNA for Digital Banking");
throw;
}
}
public async Task<IReadOnlyCollection<NewAtmCheckCardActivity>> GetNewAtmCheckCardSalesActivity(DateTime activityDt)
{
try
{
var url = _coreApiWrapperConfiguration.GetNewATMCheckCardActivityUrl + $"?newerThanDateTime={DateTimeToUrlString(activityDt)}";
var coreResponse = await _getRequest.AsyncWithNewton<CoreResponse<NewAtmCheckCardActivity>>(url, null, 0, 500);
return coreResponse.Result;
}
catch (Exception ex)
{
Log.Error(ex, "Error Getting New ATM and Check Card Sales from DNA");
throw;
}
}
public async Task<IReadOnlyCollection<NewActivityManagerReferral>> GetNewActivityManagerReferralsActivity(DateTime activityDt)
{
try
{
var url = _coreApiWrapperConfiguration.GetNewActivityManagerReferralsActivityUrl + $"?newerThanOriginationDateTime={DateTimeToUrlString(activityDt)}";
var coreResponse = await _getRequest.AsyncWithNewton<CoreResponse<NewActivityManagerReferral>>(url, null, 0, 300);
return coreResponse.Result;
}
catch (Exception ex)
{
Log.Error(ex, "Error Getting New Activity Manager Referrals from DNA");
throw;
}
}
public async Task<IReadOnlyCollection<NewLoanSaleActivity>> GetNewMortgageSaleActivities(DateTime activityDt)
{
try
{
var url = _coreApiWrapperConfiguration.GetNewMortgageAccountActivityUrl + $"?newerThanDateTime={DateTimeToUrlString(activityDt)}";
var coreResponse = await _getRequest.AsyncWithNewton<CoreResponse<NewLoanSaleActivity>>(url, null, 0, 300);
return coreResponse.Result;
}
catch (Exception ex)
{
Log.Error(ex, "Error Getting New Mortgage Sales From DNA");
throw;
}
}
public async Task<IReadOnlyCollection<NewLoanSaleActivity>> GetNewVehicleSaleActivities(DateTime activityDt)
{
try
{
var url = _coreApiWrapperConfiguration.GetNewVehicleSaleActivityUrl + $"?newerThanDateTime={DateTimeToUrlString(activityDt)}";
var coreResponse = await _getRequest.AsyncWithNewton<CoreResponse<NewLoanSaleActivity>>(url, null, 0, 300);
return coreResponse.Result;
}
catch (Exception ex)
{
Log.Error(ex, "Error Getting New Vehicle Sales from DNA");
throw;
}
}
public async Task<IReadOnlyCollection<NewLoanSaleActivity>> GetNewDpEligibleSaleActivities(DateTime activityDt)
{
try
{
var url = _coreApiWrapperConfiguration.GetNewDPEligibleAccountsActivityUrl + $"?newerThanDateTime={DateTimeToUrlString(activityDt)}";
var coreResponse = await _getRequest.AsyncWithNewton<CoreResponse<NewLoanSaleActivity>>(url, null, 0, 300);
return coreResponse.Result;
}
catch (Exception ex)
{
Log.Error(ex, "Error Getting New DP Eligible Sales and Activities");
throw;
}
}
public async Task<IReadOnlyCollection<ActivityAccountDetails>> GetUpdatedAccountInformation(List<long> accountNumbers)
{
try
{
var path = _coreApiWrapperConfiguration.GetAccountActivityAccountDetailsUrl;
var uri = new Uri(path);
var coreResponse = await _postRequest.Async<ActivityAccountDetailsRequest, List<ActivityAccountDetails>>(uri, new ActivityAccountDetailsRequest() { AccountNumbers = accountNumbers }, 0, 300);
return coreResponse;
}
catch (Exception ex)
{
Log.Error(ex, "Error Getting Updated Account Information");
throw;
}
}
public async Task<IReadOnlyCollection<NewActivityManagerReferral>> GetActivityManagerActivities(ActivityQueryRequest request)
{
try
{
var path = _coreApiWrapperConfiguration.QueryActivityManagerActivityUrl;
var uri = new Uri(path);
var coreResponse = await _postRequest.Async<ActivityQueryRequest, CoreResponse<NewActivityManagerReferral>>(uri, new ActivityQueryRequest() { ActivityIds = request.ActivityIds }, 0, 300);
return coreResponse.Result;
}
catch (Exception ex)
{
Log.Error(ex, "Error Getting Updated Account Information");
throw;
}
}
public async Task<IReadOnlyCollection<TransactionHistory>> GetTransactionHistory(string accountNumber, DateTime startDate, DateTime endDate, List<string> transactionCodes)
{
try
{
var transactionCodesString = transactionCodes == null ? "" : string.Join(",", transactionCodes);
var url = _coreApiWrapperConfiguration.GetTransactionHistoryUrl
+ $"?startDateRange={DateTimeToUrlString(startDate)}&endDateRange={DateTimeToUrlString(endDate)}"
+ $"&accountNumber={accountNumber}&transactionTypeCodes={transactionCodesString}";
var httpStatusCodes = new List<HttpStatusCode>() { HttpStatusCode.NoContent, HttpStatusCode.NotFound };
var responseMessage = await _getRequest.Async<IReadOnlyCollection<TransactionHistory>>(url, httpStatusCodes, 0, 300);
var json = JsonConvert.SerializeObject(responseMessage);
var result = JsonConvert.DeserializeObject<IReadOnlyCollection<TransactionHistory>>(json);
return result ?? new List<TransactionHistory>();
}
catch (Exception ex)
{
Log.Error(ex, $"Error Getting Transaction History for AccountNumber: {accountNumber}, TransactionCodes: {transactionCodes}, from {startDate.ToString(CultureInfo.InvariantCulture)} to {endDate.ToString(CultureInfo.InvariantCulture)}");
throw;
}
}
public async Task<IReadOnlyCollection<EStatementDeliveryMethod>> GetEStatmentDeliveryMethods(DateTime activityDt)
{
try
{
var url = _coreApiWrapperConfiguration.GetEStatementDeliveryMethodsUrl + $"?newerThanDateTime={DateTimeToUrlString(activityDt)}";
var coreResponse = await _getRequest.AsyncWithNewton<CoreResponse<EStatementDeliveryMethod>>(url, null, 0, 300);
return coreResponse.Result;
}
catch (Exception ex)
{
Log.Error(ex, "Error Getting EStatement Delivery Methods from DNA");
throw;
}
}
public string DateTimeToUrlString(DateTime dateTime)
{
var dtstring = dateTime.ToString("yyyy-MM-ddTHH:mm:ss");
return HttpUtility.UrlEncode(dtstring);
}
}
@@ -0,0 +1,32 @@
using LCU.API.Internal.Operations.IncentiveApi.Configuration;
using LCU.Library.Internal.FileOperationsModels.Models;
using LCU.Library.Internal.LcuHttpClient.HttpRequest;
namespace LCU.API.Internal.Operations.IncentiveApi.DataAccess;
public class FileOperationsApiDao : IFileOperationsApiDao
{
private readonly FileOperationsApiConfiguration _fileOperationApiConfiguration;
private readonly IGetRequest _getRequest;
private readonly IPostRequest _postRequest;
public FileOperationsApiDao(FileOperationsApiConfiguration fileOperationApiConfiguration, IGetRequest getRequest, IPostRequest postRequest)
{
_fileOperationApiConfiguration = fileOperationApiConfiguration;
_getRequest = getRequest;
_postRequest = postRequest;
}
public async Task<string[]> BuildDynamicFileList(DynamicFileListRequest dynamicFileRequest)
{
var url = _fileOperationApiConfiguration.BuildDynamicFileListUri;
return await _postRequest.AsyncWithNewton<DynamicFileListRequest, string[]>(url, dynamicFileRequest, _fileOperationApiConfiguration.RetryCount);
}
public async Task<string> GetFileContent(string filePath)
{
var finalFilePath = filePath.Replace("\\", "%5C");
var url = new Uri($"{_fileOperationApiConfiguration.GetFileContentUri}/{finalFilePath}");
return await _getRequest.StringResponseAsync(url, _fileOperationApiConfiguration.RetryCount);
}
}
@@ -0,0 +1,25 @@
using LCU.API.Internal.Operations.IncentiveApi.Models.ExternalActivities;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Accounts;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Activity;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Transaction;
using LCU.Library.Internal.IncentiveApiModels.Entities;
using NewAtmCheckCardActivity = LCU.API.Internal.Operations.IncentiveApi.Models.ExternalActivities.NewAtmCheckCardActivity;
using NewCheckingAccountActivity = LCU.API.Internal.Operations.IncentiveApi.Models.ExternalActivities.NewCheckingAccountActivity;
using NewLoanSaleActivity = LCU.API.Internal.Operations.IncentiveApi.Models.ExternalActivities.NewLoanSaleActivity;
namespace LCU.API.Internal.Operations.IncentiveApi.DataAccess;
public interface ICoreApiWrapperDao
{
public Task<IReadOnlyCollection<EStatementDeliveryMethod>> GetEStatmentDeliveryMethods(DateTime activityDt);
public Task<IReadOnlyCollection<NewCheckingAccountActivity>> GetNewCheckingDigitalBankingAccountSalesActivity(DateTime activityDt);
public Task<IReadOnlyCollection<NewCheckingAccountActivity>> GetNewCheckingAccountSalesActivity(DateTime activityDt);
public Task<IReadOnlyCollection<NewAtmCheckCardActivity>> GetNewAtmCheckCardSalesActivity(DateTime activityDt);
public Task<IReadOnlyCollection<NewActivityManagerReferral>> GetNewActivityManagerReferralsActivity(DateTime activityDt);
public Task<IReadOnlyCollection<NewLoanSaleActivity>> GetNewMortgageSaleActivities(DateTime activityDt);
public Task<IReadOnlyCollection<NewLoanSaleActivity>> GetNewVehicleSaleActivities(DateTime activityDt);
Task<IReadOnlyCollection<NewLoanSaleActivity>> GetNewDpEligibleSaleActivities(DateTime activityDt);
Task<IReadOnlyCollection<ActivityAccountDetails>> GetUpdatedAccountInformation(List<long> activityIds);
Task<IReadOnlyCollection<NewActivityManagerReferral>> GetActivityManagerActivities(ActivityQueryRequest request);
Task<IReadOnlyCollection<TransactionHistory>> GetTransactionHistory(string accountNumber, DateTime startDate, DateTime endDate, List<string> transactionCodes);
}
@@ -0,0 +1,9 @@
using LCU.Library.Internal.FileOperationsModels.Models;
namespace LCU.API.Internal.Operations.IncentiveApi.DataAccess;
public interface IFileOperationsApiDao
{
Task<string[]> BuildDynamicFileList(DynamicFileListRequest dynamicFileRequest);
Task<string> GetFileContent(string filePath);
}
@@ -0,0 +1,8 @@
using LCU.API.Internal.NotificationsApiLib.Models;
namespace LCU.API.Internal.Operations.IncentiveApi.DataAccess;
public interface INotificationApiDao
{
public Task SendMessageAsync(EmailRequest request);
}
@@ -0,0 +1,31 @@
using LCU.Library.Internal.LcuHttpClient.HttpRequest;
using LCU.API.Internal.Operations.IncentiveApi.Configuration;
using LCU.API.Internal.NotificationsApiLib.Models;
namespace LCU.API.Internal.Operations.IncentiveApi.DataAccess;
public class NotificationApiDao : INotificationApiDao
{
private readonly NotificationApiConfiguration _notificationApiConfiguration;
private readonly IPostRequest _postRequest;
public NotificationApiDao(NotificationApiConfiguration notificationApiConfiguration, IPostRequest postRequest)
{
_notificationApiConfiguration = notificationApiConfiguration;
_postRequest = postRequest;
}
public async Task SendMessageAsync(EmailRequest request)
{
try
{
await _postRequest.Async(new Uri(_notificationApiConfiguration.EmailUrl), request, _notificationApiConfiguration.RetryCount);
}
catch (Exception ex)
{
Log.Error(ex, "An exception was caught trying to send an email via Notifications API.");
throw;
}
}
}
@@ -0,0 +1,8 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class BadActivityStateChangeException : ApplicationException
{
public BadActivityStateChangeException(string message) : base(message)
{
}
}
@@ -0,0 +1,8 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class BadActivityTransferActionException : ApplicationException
{
public BadActivityTransferActionException(string message) : base(message)
{
}
}
@@ -0,0 +1,8 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class BadDepartmentAssignmentException : ApplicationException
{
public BadDepartmentAssignmentException(string message) : base(message)
{
}
}
@@ -0,0 +1,8 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class BadUserAssignmentException : ApplicationException
{
public BadUserAssignmentException(string message) : base(message)
{
}
}
@@ -0,0 +1,8 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class CommissionExistsException : ApplicationException
{
public CommissionExistsException(string message) : base(message)
{
}
}
@@ -0,0 +1,9 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class DataIntegrityException : ApplicationException
{
public DataIntegrityException(string message) : base(message)
{
}
}
@@ -0,0 +1,8 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class DataIntegrityFailureException : ApplicationException
{
public DataIntegrityFailureException(string message) : base(message)
{
}
}
@@ -0,0 +1,8 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class DeadActivityException: ApplicationException
{
public DeadActivityException(string message) : base(message)
{
}
}
@@ -0,0 +1,9 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class DuplicateDataException : ApplicationException
{
public DuplicateDataException(string message) : base(message)
{
}
}
@@ -0,0 +1,6 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class FailedParsingHeadersException : System.Exception
{
public FailedParsingHeadersException() : base("Missing Required Headers") {}
}
@@ -0,0 +1,13 @@
using LCU.Library.Internal.IncentiveApiModels.Enums;
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class MissingProcessorRunHistoryException : ApplicationException
{
public MissingProcessorRunHistoryException(Process process) : base(
$"{process.ToString()} process does not have a ProcessorHistory entry and needs to be manually seeded.")
{
Log.Fatal(
$"{process.ToString()} does not have a ProcessorHistory entry and needs to be manually seeded. New Activities of this type will not be imported until a record is seeded.");
}
}
@@ -0,0 +1,8 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class NoAvailableDecisionStrategy : ApplicationException
{
public NoAvailableDecisionStrategy(string message) : base(message)
{
}
}
@@ -0,0 +1,8 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class NoAvailableStrategy : ApplicationException
{
public NoAvailableStrategy(string message) : base(message)
{
}
}
@@ -0,0 +1,8 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class NotAuthorizedException : ApplicationException
{
public NotAuthorizedException(string message) : base(message)
{
}
}
@@ -0,0 +1,8 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class NotFoundException : ApplicationException
{
public NotFoundException(string message) : base(message)
{
}
}
@@ -0,0 +1,8 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class PayoutIneligibleException : ApplicationException
{
public PayoutIneligibleException(string message) : base(message)
{
}
}
@@ -0,0 +1,6 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class ServerErrorException : Exception
{
public ServerErrorException(): base("A server error occured. See associated logs.") { }
}
@@ -0,0 +1,9 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Exceptions;
public class UnknownProductException : ApplicationException
{
public UnknownProductException() : base(
"Encountered a product string in an incoming activity Incentive Manager could not pars ")
{
}
}
@@ -0,0 +1,14 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Extensions;
public static class DateTimeExtensions
{
public static DateTime StartOfMonth(this DateTime date)
{
return DateTime.SpecifyKind(new DateTime(date.Year, date.Month, 1), date.Kind);
}
public static DateTime EndOfMonth(this DateTime date)
{
return DateTime.SpecifyKind(date.StartOfMonth().AddMonths(1).AddSeconds(-1), date.Kind);
}
}
@@ -0,0 +1,19 @@
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace LCU.API.Internal.Operations.IncentiveApi.Extensions
{
public static class ModelStateMessages
{
public static List<string> GetErrorMessages(this ModelStateDictionary dictionary)
{
if (dictionary == null)
{
return new List<string>();
}
return dictionary.SelectMany(m => m.Value.Errors)
.Select(m => m.ErrorMessage)
.ToList();
}
}
}
@@ -0,0 +1,63 @@
using Microsoft.Extensions.DependencyInjection;
using System.Threading;
using NCrontab;
using LCU.API.Internal.Operations.IncentiveApiLib.Persistence;
using LCU.Library.Internal.LCUHostedService.LCUBackgroundService;
using LCU.API.Internal.Operations.IncentiveApi.Configuration;
using LCU.API.Internal.Operations.IncentiveApi.Utilities;
namespace LCU.API.Internal.Operations.IncentiveApi.HostedServices;
public class ApplicationDbIntegrityHostedService : LCUBackgroundService, IApplicationDbIntegrityHostedService
{
private readonly ApiConfiguration _apiConfiguration;
private readonly IServiceScopeFactory _scopeFactory;
private readonly CrontabSchedule _applicationDbIntegritySchedule;
private DateTime _nextScheduleRun;
public const string DefaultErrorMonitoringCronPattern = "0 0 * * *";
private CancellationToken _cancellationToken;
public ApplicationDbIntegrityHostedService(IServiceScopeFactory scopeFactory, ApiConfiguration apiConfiguration)
{
_scopeFactory = scopeFactory;
_apiConfiguration = apiConfiguration;
_applicationDbIntegritySchedule = CronHelpers.SetCronSchedule(_apiConfiguration.ApplicationDbIntegrityCronSchedule,
DefaultErrorMonitoringCronPattern);
_nextScheduleRun = _applicationDbIntegritySchedule.GetNextOccurrence(DateTime.Now);
_cancellationToken = new CancellationToken();
}
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
Log.Debug("ApplicationDbIntegrity Hosted Service is starting.");
try
{
while (!cancellationToken.IsCancellationRequested)
{
await Task.Delay(UntilNextExecution(), cancellationToken);
using (var scope = _scopeFactory.CreateScope())
{
Log.Debug("Running ApplicationDbIntegrity Service");
await scope.ServiceProvider.GetRequiredService<IApplicationDbIntegrityService>().AppUserIdIntegrityMaintenanceSucceeded(_cancellationToken);
}
_nextScheduleRun = _applicationDbIntegritySchedule.GetNextOccurrence(DateTime.Now);
}
}
catch (OperationCanceledException taskCanceledEx)
{
Log.Error(taskCanceledEx, $"Manual start/stop of ApplicationDbIntegrity Hosted Service was initiated.");
}
catch (Exception exception)
{
Log.Error(exception,
"Error trying to startup main thread for ApplicationDbIntegrity Hosted Service");
}
Log.Debug("ApplicationDbIntegrity Hosted Service is stopping.");
}
private int UntilNextExecution() => Math.Max(0, (int)_nextScheduleRun.Subtract(DateTime.Now).TotalMilliseconds);
}
@@ -0,0 +1,8 @@
using LCU.Library.Internal.LCUHostedService.LCUBackgroundService;
namespace LCU.API.Internal.Operations.IncentiveApi.HostedServices
{
public interface IApplicationDbIntegrityHostedService : ILCUBackgroundService
{
}
}
@@ -0,0 +1,60 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AssemblyVersion>1.2.3</AssemblyVersion>
<FileVersion>1.2.3</FileVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DocumentationFile>C:\Projects\LCU.API.Operations.IncentiveAPI\LCU.API.Internal.Operations.IncentiveApi\bin\Debug\LCU.API.Internal.Operations.IncentiveApi.xml</DocumentationFile>
<NoWarn>1701;1702;1591</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DocumentationFile>bin\Release\LCU.API.Internal.Operations.IncentiveApi.xml</DocumentationFile>
<NoWarn>1701;1702;1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Startup.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CsvHelper" Version="27.2.1" />
<PackageReference Include="FluentValidation" Version="10.3.6" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="10.3.6" />
<PackageReference Include="itext7" Version="7.2.1" />
<PackageReference Include="LCU.Api.Internal.FTPLib" Version="2.1.0" />
<PackageReference Include="LCU.Api.Internal.MaidBotLib" Version="1.0.2" />
<PackageReference Include="LCU.API.Internal.NotificationsApiLib" Version="2.1.0" />
<PackageReference Include="LCU.Library.Internal.ApiResponse" Version="3.4.1" />
<PackageReference Include="LCU.Library.Internal.Configuration" Version="1.0.0" />
<PackageReference Include="LCU.Library.Internal.Exceptions" Version="1.0.0" />
<PackageReference Include="LCU.Library.Internal.FileOperationsModels" Version="4.1.0" />
<PackageReference Include="LCU.Library.Internal.LCUHostedService" Version="1.0.0" />
<PackageReference Include="LCU.Library.Internal.LcuHttpClient" Version="1.17.0" />
<PackageReference Include="LCU.Library.Internal.LcuMassTransit" Version="1.0.0" />
<PackageReference Include="LCU.Library.Internal.LcuMassTransitModels" Version="1.1.0" />
<PackageReference Include="LCU.Library.Internal.LCUServiceFactory" Version="2.0.0" />
<PackageReference Include="LCU.Library.Internal.Logging" Version="1.1.0" />
<PackageReference Include="LCU.Library.Internal.Security" Version="1.2.3" />
<PackageReference Include="LCU.Library.Internal.Security.Models" Version="1.2.3" />
<PackageReference Include="LCU.Library.Internal.Status" Version="1.2.0" />
<PackageReference Include="LCU.Library.Internal.StatusModels" Version="1.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.2" />
<PackageReference Include="Microsoft.FeatureManagement" Version="2.4.0" />
<PackageReference Include="Microsoft.FeatureManagement.AspNetCore" Version="2.4.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
<PackageReference Include="TimeZoneConverter" Version="6.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LCU.API.Internal.Operations.IncentiveApiLib\LCU.API.Internal.Operations.IncentiveApiLib.csproj" />
<ProjectReference Include="..\LCU.Library.Internal.IncentiveApiModels\LCU.Library.Internal.IncentiveApiModels.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,86 @@
using LCU.Library.Internal.IncentiveApiModels.Entities;
using LCU.Library.Internal.IncentiveApiModels.Enums;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Action;
public class ActionCreditCardBusinessRow : IActionFileObject
{
public string BookedDate { get; set; }
public string BusinessTradeName { get; set; }
public string BusinessLegalName { get; set; }
public string AppID { get; set; }
public string Principal { get; set; }
public string ProdDetailFirstName { get; set; }
public string ProdDetailLastName { get; set; }
public string ProdDetailEmail { get; set; }
public string ProdDetailEmployeeNum { get; set; }
public string IncentiveEarnedEmail { get; set; }
public string ProductShortName { get; set; }
public Activity CreateActivity(AppUser appUser)
{
var homeDept = appUser.FindHomeDepartment();
return new Activity()
{
Product = Product.CreditCard,
Type = ActivityType.Sale,
State = ActivityState.Accepted,
SourceSystem = SystemType.Action,
SourceCreated = DateTime.Parse(BookedDate),
Accepted = DateTime.Parse(BookedDate).Date.AddHours(12),
SourceId = AppID,
Detail = new ActivityDetail()
{
MemberName = BusinessLegalName,
AccountBalance = IActionFileObject.ParseMoneyDouble(Principal),
AccountStatus = ProductShortName
},
AppUserId = appUser.Id,
EmployeeEmail = appUser.AdEmail,
EmployeeId = appUser.EmployeeId,
DepartmentId = homeDept.DepartmentId
};
}
public DeadActivity CreateDeadActivity(DeadActivityReason reasonCode, string note, string employeeEmail = null, string employeeId = null)
{
return new DeadActivity(AppID, SystemType.Action, reasonCode, note)
{
Product = Product.CreditCard,
Type = ActivityType.Sale,
State = ActivityState.Accepted,
SourceSystem = SystemType.Action,
SourceCreated = DateTime.Parse(BookedDate),
Accepted = DateTime.Parse(BookedDate).Date.AddHours(12),
SourceId = AppID,
DeadDetail = new DeadActivityDetail()
{
MemberName = BusinessLegalName,
AccountBalance = IActionFileObject.ParseMoneyDouble(Principal),
AccountStatus = ProductShortName
},
EmployeeEmail = employeeEmail,
EmployeeId = employeeId,
};
}
public string GetEmployeeEmail()
{
return string.IsNullOrWhiteSpace(IncentiveEarnedEmail) ? null : IncentiveEarnedEmail.Trim();
}
public string GetLoanOfficerEmail()
{
return string.IsNullOrWhiteSpace(ProdDetailEmail) ? null : ProdDetailEmail.Trim();
}
public string GetLoanOfficerEmailByName()
{
if (string.IsNullOrWhiteSpace(ProdDetailFirstName) || string.IsNullOrWhiteSpace(ProdDetailLastName))
{
return null;
}
return $"{ProdDetailFirstName.Trim()}{ProdDetailLastName.Trim()}@landmarkcu.com";
}
}
@@ -0,0 +1,86 @@
using LCU.Library.Internal.IncentiveApiModels.Entities;
using LCU.Library.Internal.IncentiveApiModels.Enums;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Action;
public class ActionCreditCardPersonalRow : IActionFileObject
{
public string BookedDate { get; set; }
public string MemberFirstName { get; set; }
public string MemberLastName { get; set; }
public string AppID { get; set; }
public string Principal { get; set; }
public string ProdDetailFirstName { get; set; }
public string ProdDetailLastName { get; set; }
public string ProdDetailEmail { get; set; }
public string ProdDetailEmployeeNum { get; set; }
public string IncentiveEarnedEmail { get; set; }
public string ProductShortName { get; set; }
public Activity CreateActivity(AppUser appUser)
{
var homeDept = appUser.FindHomeDepartment();
return new Activity()
{
Product = Product.CreditCard,
Type = ActivityType.Sale,
State = ActivityState.Accepted,
SourceSystem = SystemType.Action,
SourceCreated = DateTime.Parse(BookedDate),
Accepted = DateTime.Parse(BookedDate).Date.AddHours(12),
SourceId = AppID,
Detail = new ActivityDetail()
{
MemberName = MemberFirstName + " " + MemberLastName,
AccountBalance = IActionFileObject.ParseMoneyDouble(Principal),
AccountStatus = ProductShortName
},
AppUserId = appUser.Id,
EmployeeEmail = appUser.AdEmail,
EmployeeId = appUser.EmployeeId,
DepartmentId = homeDept.DepartmentId
};
}
public DeadActivity CreateDeadActivity(DeadActivityReason reasonCode, string note, string employeeEmail = null, string employeeId = null)
{
return new DeadActivity(AppID, SystemType.Action, reasonCode, note)
{
Product = Product.CreditCard,
Type = ActivityType.Sale,
State = ActivityState.Accepted,
SourceSystem = SystemType.Action,
SourceCreated = DateTime.Parse(BookedDate),
Accepted = DateTime.Parse(BookedDate).Date.AddHours(12),
SourceId = AppID,
DeadDetail = new DeadActivityDetail()
{
MemberName = MemberFirstName + " " + MemberLastName,
AccountBalance = IActionFileObject.ParseMoneyDouble(Principal),
AccountStatus = ProductShortName
},
EmployeeEmail = employeeEmail,
EmployeeId = employeeId,
};
}
public string GetEmployeeEmail()
{
return string.IsNullOrWhiteSpace(IncentiveEarnedEmail) ? null : IncentiveEarnedEmail.Trim();
}
public string GetLoanOfficerEmail()
{
return string.IsNullOrWhiteSpace(ProdDetailEmail) ? null : ProdDetailEmail.Trim();
}
public string GetLoanOfficerEmailByName()
{
if (string.IsNullOrWhiteSpace(ProdDetailFirstName) || string.IsNullOrWhiteSpace(ProdDetailLastName))
{
return null;
}
return $"{ProdDetailFirstName.Trim()}{ProdDetailLastName.Trim()}@landmarkcu.com";
}
}
@@ -0,0 +1,32 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Action;
public class ActionSaleRow
{
public string EmailAddress { get; set; }
public string Member_Number { get; set; }
public string Account_Number { get; set; }
public string Borrower_Name { get; set; }
public string APP_START_DATE { get; set; }
public string OPEN_DATE { get; set; }
public string PBorrowerSSN_Ind { get; set; }
public string CBorrowerName_Ind { get; set; }
public string CBorrowerSSN_Ind { get; set; }
public string SBorrowerName_Ind { get; set; }
public string SBorrowerSSN_Ind { get; set; }
public string IndAppID { get; set; }
public string IndProduct { get; set; }
public string IndAmtFinanced { get; set; }
public string IndCreationDate { get; set; }
public string IndAccountNumber { get; set; }
public string PBorrowerName_Veh { get; set; }
public string PBorrowerSSN_Veh { get; set; }
public string CBorrowerName_Veh { get; set; }
public string CBorrowerSSN_Veh { get; set; }
public string SBorrowerName_Veh { get; set; }
public string SBorrowerSSN_Veh { get; set; }
public string VehAppID { get; set; }
public string VehProduct { get; set; }
public string VehAmtFinanced { get; set; }
public string DistributionChannel { get; set; }
public string DistributionChannelCode { get; set; }
}
@@ -0,0 +1,20 @@
using System.Globalization;
using LCU.Library.Internal.IncentiveApiModels.Entities;
using LCU.Library.Internal.IncentiveApiModels.Enums;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Action;
public interface IActionFileObject
{
static readonly CultureInfo USEnglish = new CultureInfo("en-US");
public Activity CreateActivity(AppUser appUser);
public string GetEmployeeEmail();
public string GetLoanOfficerEmail();
public string GetLoanOfficerEmailByName();
public DeadActivity CreateDeadActivity(DeadActivityReason reasonCode, string note, string employeeEmail = null, string employeeId = null);
public static double? ParseMoneyDouble(string indAmtFinanced)
{
var parsed = decimal.Parse(indAmtFinanced, NumberStyles.Currency, USEnglish);
return (double)parsed;
}
}
@@ -0,0 +1,10 @@
using LCU.Library.Internal.IncentiveApiModels.Entities;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Accounts;
namespace LCU.API.Internal.Operations.IncentiveApi.Models;
public class ActivityDetailUpdateOrder
{
public Activity ExistingActivity { get; set; }
public List<ActivityAccountDetails> DetailUpdates { get; set; }
}
@@ -0,0 +1,11 @@
using LCU.Library.Internal.IncentiveApiModels.Entities;
namespace LCU.API.Internal.Operations.IncentiveApi.Models;
public class ActivityProcessingOrder
{
public Activity ExistingActivity { get; set; }
public List<Activity> ActivityUpdateItems { get; set; }
public bool ProcessingComplete { get; set; }
public int UpdateCount { get; set; }
}
@@ -0,0 +1,81 @@
using CsvHelper.Configuration.Attributes;
using LCU.Library.Internal.IncentiveApiModels.Enums;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Allied;
public class AlliedSaleRow
{
[Name("Quoter")]
public string Quoter { get; set; }
[Name("Issuer")]
public string Issuer { get; set; }
[Name("Origin")]
public string Origin { get; set; }
[Name("Product_Type")]
public string ProductType { get; set; }
[Name("Status")]
public string Status { get; set; }
[Name("Sale_Date")]
public string SaleDate { get; set; }
[Name("Sale_Effective_Date")]
public string SaleEffectiveDate { get; set; }
[Name("Cancellation_Date")]
public string CancellationDate { get; set; }
[Name("Cancellation_Reason")]
public string CancellationReason { get; set; }
[Name("Cancelled_By")]
public string CancelledBy { get; set; }
[Name("Sales_Contract_Number")]
public string SalesContractNumber { get; set; }
[Name("Buyer")]
public string Buyer { get; set; }
[Name("Account_Number")]
public string AccountNumber { get; set; }
[Name("LOS_LOAN_APP_ID_TX")]
public string LosLoanAppIdTx { get; set; }
[Name("Program_Type")]
public string ProgramType { get; set; }
[Name("Buyer_Cost")]
public string BuyerCost { get; set; }
[Name("Flagged_Reasons")]
public string FlaggedReasons { get; set; }
public string DetermineAccountNumber()
{
var accountNumber = "";
if (!string.IsNullOrEmpty(AccountNumber))
{
accountNumber = AccountNumber;
}
else
{
accountNumber = SalesContractNumber ?? "";
}
if (accountNumber.Contains("-"))
{
var transform = accountNumber.Split("-");
if (transform?.Length == 2)
{
return transform[0].Trim();
}
}
return accountNumber;
}
public Product DetermineAlliedProduct()
{
if (string.Equals(ProductType.Trim(), "mbp", StringComparison.CurrentCultureIgnoreCase))
{
return Product.MechanicalBreakdownProtection;
}
if (string.Equals(ProductType.Trim(), "gap", StringComparison.CurrentCultureIgnoreCase))
{
return Product.GAPInsurance;
}
throw new Exception($"Allied should only pass MBP or GAP for product, but received {ProductType}");
}
}
@@ -0,0 +1,17 @@
using LCU.Library.Internal.IncentiveApiModels.Enums;
namespace LCU.API.Internal.Operations.IncentiveApi.Models;
public class AuthorizedActivityCommands
{
public AuthorizedActivityCommands(ActivityState[] allowedChanges,
bool canApproveTransferFrom = false, bool canApproveTransferTo = false)
{
AllowedChanges = allowedChanges;
CanApproveTransferFrom = canApproveTransferFrom;
CanApproveTransferTo = canApproveTransferTo;
}
public ActivityState[] AllowedChanges { get; }
public bool CanApproveTransferFrom { get; }
public bool CanApproveTransferTo { get; }
}
@@ -0,0 +1,27 @@
using LCU.Library.Internal.IncentiveApiModels.Common;
using LCU.Library.Internal.IncentiveApiModels.Entities;
namespace LCU.API.Internal.Operations.IncentiveApi.Models;
public class BusinessLineProgress: IViewTransformable<BusinessLineProgress>
{
public BusinessLineProgress(BusinessLine businessLine, MonthRange monthRange)
{
BusinessLine = businessLine;
MonthRange = monthRange;
Departments = new List<DepartmentProgress>();
}
public BusinessLine BusinessLine { get; }
public MonthRange MonthRange{ get; }
public IList<DepartmentProgress> Departments { get; }
public BusinessLineProgress TransformForView()
{
foreach(var department in Departments)
{
department?.TransformForView();
}
return this;
}
}
@@ -0,0 +1,7 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Constants;
public static class SystemAppUserConstants
{
public const string DigitalBankingEmail = "[email protected]";
public const string FirstMortgageEmail = "[email protected]";
}
@@ -0,0 +1,6 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Constants;
public static class TemenosImportConstants
{
public const string PersonalCardSubProduct = "Credit Card";
}
@@ -0,0 +1,15 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Core;
public class CoreResponse<T>
{
public List<T> Result {get; set;}
public int Id {get; set;}
public string Exception {get; set;}
public string Status {get; set;}
public bool IsCanceled {get; set;}
public bool IsCompleted {get; set;}
public bool IsCompletedSuccessfully {get; set;}
public string CreationOptions {get; set;}
public string AsyncState {get; set;}
public bool IsFaulted {get; set;}
}
@@ -0,0 +1,9 @@
using LCU.Library.Internal.IncentiveApiModels.Enums;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.DataTransfer;
public class ActivityTransferApprovalRequest
{
public int Id { get; set; }
public ActivityTransferState ApprovalState { get; set; }
}
@@ -0,0 +1,12 @@
using LCU.Library.Internal.IncentiveApiModels.Enums;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.DataTransfer;
public class ActivityTransferRequest
{
public int? Id { get; set; }
public ActivityState ActivityStateBeforeTransfer { get; set; }
public int RequestedActivityId { get; set; }
public int NewDepartmentId { get; set; }
public string NewEmployeeId { get; set; }
}
@@ -0,0 +1,7 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Models.DataTransfer;
public class AdditionalPermissionRequest
{
public List<string> AddPermCodes { get; set; }
public List<string> RemovePermCodes { get; set; }
}
@@ -0,0 +1,21 @@
using System.ComponentModel.DataAnnotations;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.DataTransfer;
public class DepartmentAssignmentRequest
{
[Required]
public int[] DepartmentId { get; set; }
[Required]
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
[StringLength(255)]
public string? Note { get; set; }
[Required]
[Range(0,100)]
public decimal SlidingPayout { get; set; }
[Required]
public string Role { get; set; }
}
@@ -0,0 +1,10 @@
using System.ComponentModel.DataAnnotations;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.DataTransfer;
public class ExtrapolateGoalDispersalRequest
{
[Range(1,12)]
public int Month { get; set; }
public int Year { get; set; }
}
@@ -0,0 +1,13 @@
using System.ComponentModel.DataAnnotations;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.DataTransfer;
public class RoleMappingUpdateRequest
{
[Required]
public int Id { get; set; }
[Required]
public string ApplicationRole { get; set; }
[Required]
public string BusinessRole { get; set; }
}
@@ -0,0 +1,18 @@
using LCU.Library.Internal.IncentiveApiModels.Enums;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.ComponentModel.DataAnnotations;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.DataTransfer;
public class UserAssignmentRequest
{
[Required]
public string EmployeeId { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
public AssignmentType? Type { get; set; }
[Required]
public string Key { get; set; }
}
@@ -0,0 +1,9 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Models.DataTransfer;
public class UserNameSearchRequest
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleInit { get; set; }
public string DnaOrgNbr { get; set; }
}
@@ -0,0 +1,18 @@
using LCU.Library.Internal.IncentiveApiModels.Entities;
using LCU.Library.Internal.IncentiveApiModels.Results;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Dayforce;
public class ActiveEmployeeReceipt
{
public ActiveEmployeeReceipt(IDictionary<string,string> reportRow)
{
ReportRow = reportRow;
Status = ActiveEmployeeReceiptStatus.NOT_PROCESSED;
}
public AppUser AppUser { get; set; }
public IDictionary<string,string> ReportRow { get; }
public ActiveEmployeeResult EmployeeRow { get; set; }
public ActiveEmployeeReceiptStatus Status { get; set; }
}
@@ -0,0 +1,10 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Dayforce;
public enum ActiveEmployeeReceiptStatus
{
NOT_PROCESSED,
SUCCESS,
MISSING_ROLE,
MISSING_DATA,
EXCEPTION
}
@@ -0,0 +1,55 @@
using System.ComponentModel.DataAnnotations;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Dayforce;
public class EmployeeDetailsUpdate
{
public string OldEmail { get; set; }
public string OldEmployeeId { get; set; }
public string OldFullName { get; set; }
public string NewEmail { get; set; }
public string NewEmployeeId { get; set; }
public string NewFullName { get; set; }
public bool NewDetailsMatchOld()
{
return OldEmail.Equals(NewEmail, StringComparison.InvariantCultureIgnoreCase)
&& OldEmployeeId.Equals(NewEmployeeId, StringComparison.InvariantCultureIgnoreCase)
&& OldFullName.Equals(NewFullName, StringComparison.InvariantCultureIgnoreCase);
}
public string InvalidUpdateData()
{
if (NewDetailsMatchOld())
{
return $"Invalid Update Data: Old Details Match Updated Details";
}
if (string.IsNullOrWhiteSpace(NewEmail))
{
return $"Invalid Update Data: NewEmail: {NewEmail}";
}
if (!new EmailAddressAttribute().IsValid(NewEmail))
{
return $"Invalid Update Data: NewEmail Is Not A Valid Email: {NewEmail}";
}
if (!NewEmail.Contains("@landmarkcu.com", StringComparison.InvariantCultureIgnoreCase))
{
return $"Invalid Update Data: NewEmail Is Not A Valid Internal Email: {NewEmail}";
}
if (string.IsNullOrWhiteSpace(NewEmployeeId))
{
return $"Invalid Update Data: NewEmployeeId: {NewEmployeeId}";
}
if (string.IsNullOrWhiteSpace(NewFullName))
{
return $"Invalid Update Data: NewFullName: {NewFullName}";
}
return "";
}
}
@@ -0,0 +1,10 @@
using LCU.Library.Internal.IncentiveApiModels.Entities;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Dayforce;
public class EmployeeDetailsUpdateResult
{
public AppUser AppUser { get; set; }
public string UpdateMessage { get; set; }
public bool UpdatedSuccessfully { get; set; }
}
@@ -0,0 +1,25 @@
using System.Runtime.Serialization;
using System.Text;
using Newtonsoft.Json;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Dayforce;
[DataContract]
public class Paging
{
[DataMember(Name = "Next", EmitDefaultValue = false)]
[JsonProperty(PropertyName = "Next")]
public string Next { get; set; }
public override string ToString()
{
var sb = new StringBuilder();
sb.Append("class Paging {\n");
sb.Append(" Next: ").Append(Next).Append("\n");
sb.Append("}\n");
return sb.ToString();
}
public string ToJson()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
}
@@ -0,0 +1,13 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Dayforce;
public class Payload
{
public string RequestId { get; set; }
public List<ProcessResult> ProcessResults { get; set; }
}
public class Payload<T> : Payload
{
public T Data { get; set; }
public Paging Paging { get; set; }
}
@@ -0,0 +1,9 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Dayforce;
public class PayoutEntry
{
public string Code { get; set; }
public string EmployeeName { get; set; }
public string EmployeeId { get; set; }
public decimal PayoutTotal { get; set; }
}
@@ -0,0 +1,42 @@
using System.Runtime.Serialization;
using System.Text;
using Newtonsoft.Json;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Dayforce;
[DataContract]
public class ProcessResult
{
[DataMember(Name = "Code", EmitDefaultValue = false)]
[JsonProperty(PropertyName = "Code")]
public string Code { get; set; }
[DataMember(Name = "Context", EmitDefaultValue = false)]
[JsonProperty(PropertyName = "Context")]
public string Context { get; set; }
[DataMember(Name = "Level", EmitDefaultValue = false)]
[JsonProperty(PropertyName = "Level")]
public string Level { get; set; }
[DataMember(Name = "Message", EmitDefaultValue = false)]
[JsonProperty(PropertyName = "Message")]
public string Message { get; set; }
public override string ToString()
{
var sb = new StringBuilder();
sb.Append("class ProcessResult {\n");
sb.Append(" Code: ").Append(Code).Append("\n");
sb.Append(" Context: ").Append(Context).Append("\n");
sb.Append(" Level: ").Append(Level).Append("\n");
sb.Append(" Message: ").Append(Message).Append("\n");
sb.Append("}\n");
return sb.ToString();
}
public string ToJson()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
}
@@ -0,0 +1,33 @@
using System.Runtime.Serialization;
using System.Text;
using Newtonsoft.Json;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Dayforce;
[DataContract]
public class Report
{
[DataMember(Name = "XRefCode", EmitDefaultValue = false)]
[JsonProperty(PropertyName = "XRefCode")]
public string XRefCode { get; set; }
[DataMember(Name = "Rows", EmitDefaultValue = false)]
[JsonProperty(PropertyName = "Rows")]
public List<Dictionary<String, string>> Rows { get; set; }
public override string ToString()
{
var sb = new StringBuilder();
sb.Append("class Report {\n");
sb.Append(" XRefCode: ").Append(XRefCode).Append("\n");
sb.Append(" Rows: ").Append(Rows).Append("\n");
sb.Append("}\n");
return sb.ToString();
}
public string ToJson()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
}
@@ -0,0 +1,19 @@
using LCU.Library.Internal.IncentiveApiModels.Entities;
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Dayforce;
public class TerminatedEmployeeReceipt
{
public TerminatedEmployeeReceipt(AppUser terminated, PayoutEntry lastMonthPayout, PayoutEntry thisMonthPayout, AppUser manager)
{
Terminated = terminated;
LastMonthPayout = lastMonthPayout;
ThisMonthPayout = thisMonthPayout;
Manager = manager;
}
public AppUser Terminated { get; }
public AppUser Manager { get; }
public PayoutEntry LastMonthPayout { get; }
public PayoutEntry ThisMonthPayout { get; }
}
@@ -0,0 +1,25 @@
namespace LCU.API.Internal.Operations.IncentiveApi.Models.Dayforce;
public class TerminatedEmployeeResult
{
public TerminatedEmployeeResult(IReadOnlyDictionary<string, string> row)
{
DisplayName = row["Employee_DisplayName"];
EmployeeNumber = row["EmployeeEmploymentStatus_EmployeeNumber"];
LoginName = row["IdLibrary_LoginName"];
if (row.ContainsKey("EmployeeManager_ManagerEmployeeNumber"))
{
ManagerKey = row["EmployeeManager_ManagerEmployeeNumber"];
}
var termDate = row["Employee_TerminationDate"];
TerminationDate = string.IsNullOrWhiteSpace(termDate) ? DateTime.Now : DateTime.Parse(termDate);
}
public string DisplayName { get; }
public string EmployeeNumber { get; }
public string LoginName { get; }
public string ManagerKey { get; }
public DateTime TerminationDate { get; }
}
@@ -0,0 +1,10 @@
using LCU.Library.Internal.IncentiveApiModels.Entities;
namespace LCU.API.Internal.Operations.IncentiveApi.Models;
public class DepartmentDetails
{
public Department Department { get; set; }
public IReadOnlyCollection<UserDepartment> Assignments { get; set; }
public AppUser RegionalManager { get; set; }
}
@@ -0,0 +1,30 @@
using LCU.Library.Internal.IncentiveApiModels.Entities;
namespace LCU.API.Internal.Operations.IncentiveApi.Models;
public class DepartmentGoals
{
public DepartmentGoals(int departmentId, int year)
{
DepartmentId = departmentId;
Year = year;
MonthlyGoals = new PerProductGoal[12];
for (var month = 0; month < 12; month++)
{
MonthlyGoals[month] = new PerProductGoal();
}
}
public int DepartmentId { get; }
public int Year { get; }
public PerProductGoal[] MonthlyGoals { get; }
public void ApplyAll(ICollection<Goal> findDepartmentGoals)
{
foreach (var goal in findDepartmentGoals)
{
MonthlyGoals[goal.StartDate.Month-1].ProductGoals[goal.Product] = goal.Value;
}
}
}

Some files were not shown because too many files have changed in this diff Show More