217 lines
9.9 KiB
C#
217 lines
9.9 KiB
C#
using LCU.API.Internal.Operations.IncentiveApi.Services.DispersalStrategy;
|
|
using LCU.API.Internal.Operations.IncentiveApi.Models.GoalDispersal;
|
|
using LCU.API.Internal.Operations.IncentiveApiLib.Services;
|
|
using LCU.API.Internal.Operations.IncentiveApiLib.Repositories;
|
|
using LCU.Library.Internal.IncentiveApiModels.Requests;
|
|
using LCU.API.Internal.Operations.IncentiveApi.Services.MicroApiServices;
|
|
using LCU.Library.Internal.ApiResponse.Services;
|
|
using LCU.Library.Internal.IncentiveApiModels.Results;
|
|
|
|
namespace LCU.API.Internal.Operations.IncentiveApi.Services;
|
|
|
|
public class GoalDispersalService : IGoalDispersalService
|
|
{
|
|
private readonly IUserService _userService;
|
|
private readonly IGoalService _goalService;
|
|
private readonly IDepartmentRepository _departmentRepository;
|
|
private readonly INotificationApiService _notificationService;
|
|
private readonly IDispersalStrategyService _dispersalStrategyService;
|
|
private readonly ProcessResult _goalDispersalProcessResult;
|
|
|
|
public GoalDispersalService(
|
|
IUserService userService,
|
|
IGoalService goalService,
|
|
IDepartmentRepository departmentRepository,
|
|
INotificationApiService notificationService,
|
|
IDispersalStrategyService dispersalStrategyService
|
|
)
|
|
{
|
|
_userService = userService;
|
|
_goalService = goalService;
|
|
_departmentRepository = departmentRepository;
|
|
_notificationService = notificationService;
|
|
_dispersalStrategyService = dispersalStrategyService;
|
|
_goalDispersalProcessResult = new ProcessResult();
|
|
}
|
|
|
|
public async Task<GoalDispersalReceipt> DisperseGoalsByExtrapolatingLastMonth(int departmentId, int dispersalMonth, int dispersalYear)
|
|
{
|
|
try
|
|
{
|
|
var lastMonth = dispersalMonth == 1 ? 12 : dispersalMonth - 1;
|
|
var lastMonthCorrectedYear = dispersalMonth == 1 ? dispersalYear - 1 : dispersalYear;
|
|
var dispersalMonthStartDateTime = DateTime.Parse($"{dispersalYear}-{dispersalMonth}-01");
|
|
var departmentGoals = await _goalService.GetAnnualDepartmentGoalsAsync(departmentId, dispersalYear);
|
|
var dispersalMonthDepartmentGoals = departmentGoals.MonthlyGoals[dispersalMonth - 1];
|
|
|
|
var dispersalMonthPersonnel = await _userService.FindDepartmentAssignments(
|
|
new DepartmentPersonnelSearchRequest()
|
|
{
|
|
DepartmentId = departmentId,
|
|
Month = dispersalMonth,
|
|
Year = dispersalYear,
|
|
IncludeAllPersonnel = true
|
|
}
|
|
);
|
|
|
|
var dispersalMonthPersonnelGoals = await _goalService.GetMonthlyPersonnelGoalsAsync(
|
|
new DepartmentPersonnelSearchRequest()
|
|
{
|
|
DepartmentId = departmentId,
|
|
Month = dispersalMonth,
|
|
Year = dispersalYear,
|
|
IncludeAllPersonnel = true
|
|
}
|
|
);
|
|
|
|
var modelMonthPersonnelGoals = await _goalService.GetMonthlyPersonnelGoalsAsync(
|
|
new DepartmentPersonnelSearchRequest()
|
|
{
|
|
DepartmentId = departmentId,
|
|
Month = lastMonth,
|
|
Year = lastMonthCorrectedYear,
|
|
IncludeAllPersonnel = true
|
|
}
|
|
);
|
|
|
|
if (modelMonthPersonnelGoals.GoalAudit.All(x => x.Value < 1))
|
|
{
|
|
var weightedDispersalRequest = new DefaultWeightedGoalDispersalData()
|
|
{
|
|
DepartmentId = departmentId,
|
|
DispersalMonthStartDate = dispersalMonthStartDateTime,
|
|
DispersalMonthPersonnel = dispersalMonthPersonnel,
|
|
DispersalMonthDepartmentGoals = dispersalMonthDepartmentGoals
|
|
};
|
|
var weightedReceipt = _dispersalStrategyService.DefaultWeightedDispersal(weightedDispersalRequest);
|
|
await _goalService.SaveGoalRangeAsync(weightedReceipt.GoalChanges);
|
|
return weightedReceipt;
|
|
}
|
|
|
|
departmentGoals = await _goalService.GetAnnualDepartmentGoalsAsync(departmentId, lastMonthCorrectedYear);
|
|
|
|
var lastMonthDepartmentGoals = departmentGoals.MonthlyGoals[lastMonth - 1];
|
|
var extrapolateGoalsDispersalRequest = new ExtrapolationGoalDispersalData()
|
|
{
|
|
DepartmentId = departmentId,
|
|
DispersalMonthStartDate = dispersalMonthStartDateTime,
|
|
DispersalMonthDepartmentGoals = dispersalMonthDepartmentGoals,
|
|
DispersalMonthPersonnelGoals = dispersalMonthPersonnelGoals,
|
|
ModelDepartmentGoals = lastMonthDepartmentGoals,
|
|
ModelPersonnelGoals = modelMonthPersonnelGoals,
|
|
DispersalMonthPersonnel = dispersalMonthPersonnel
|
|
};
|
|
|
|
var receipt = _dispersalStrategyService.ExtrapolateFromExistingGoals(extrapolateGoalsDispersalRequest);
|
|
await _goalService.SaveGoalRangeAsync(receipt.GoalChanges);
|
|
return receipt;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error(ex, $"Failed to DisperseGoalsForNextMonth for dept:{departmentId} month:{dispersalMonth} dispersalYear: {dispersalYear}");
|
|
throw new Exceptions.ServerErrorException();
|
|
}
|
|
}
|
|
|
|
public async Task<Dictionary<string, GoalDispersalReceipt>> DisperseAllDepartmentGoalsForMonth(int month, int year)
|
|
{
|
|
var results = new Dictionary<string, GoalDispersalReceipt>();
|
|
var departments = await _departmentRepository.GetAllDepartmentsAsync();
|
|
foreach (var department in departments)
|
|
{
|
|
try
|
|
{
|
|
if (department.Id == null)
|
|
{
|
|
throw new Exception($"Department Has No Id. Skipping Dispersal: {department.DepartmentName}");
|
|
}
|
|
|
|
var departmentKey = $"{department.Id} - {department.DepartmentName}";
|
|
|
|
Log.Debug($"Dispersing Goals for Department: {departmentKey}");
|
|
var receipt = await DisperseGoalsByExtrapolatingLastMonth((int)department.Id, month, year);
|
|
results.Add(departmentKey, receipt);
|
|
Log.Debug($"Completed Dispersal for: {departmentKey}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var departmentKey = $"{department.Id} - {department.DepartmentName}";
|
|
Log.Error(ex, $"Failed Month Start Auto-Disperse of Personnel Goals for Department: {departmentKey}");
|
|
results.Add(departmentKey, null);
|
|
}
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
public async Task ExecuteMonthStartDispersal(GoalDispersalRequest request)
|
|
{
|
|
try
|
|
{
|
|
Log.Information("Executing Monthly Goal Dispersal");
|
|
var result = await DisperseAllDepartmentGoalsForMonth(request.StartDate.Month, request.StartDate.Year);
|
|
|
|
Log.Information("Finished Monthly Goal Dispersal. Sending Report Email.");
|
|
await _notificationService.SendMonthStartGoalDispersalReceipt(result, request.GoalDispersalNotification);
|
|
|
|
_goalDispersalProcessResult.MessageStack.Add($"Goal Dispersal Service Processed for {request.StartDate.Month}{request.StartDate.Year} records.");
|
|
Log.Information("Successfully Sent Report Email.");
|
|
await QueueReturnResponse.QueueResponse(request, _goalDispersalProcessResult.Success, _goalDispersalProcessResult.MessageStack);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
Log.Fatal(exception, "There was an Unhandled error Executing Month Start Dispersal");
|
|
var processLabel = request == null
|
|
? "unknown"
|
|
: $"{request.StartDate.Month}{request.StartDate.Year}";
|
|
var message = $"There was an issue with handling the Goal Dispersal Service Process {processLabel}. Exception Message: {exception.Message}.";
|
|
_goalDispersalProcessResult.MessageStack.Add(message);
|
|
_goalDispersalProcessResult.Success = false;
|
|
await QueueReturnResponse.QueueResponse(request, _goalDispersalProcessResult.Success, _goalDispersalProcessResult.MessageStack);
|
|
}
|
|
}
|
|
|
|
public async Task<GoalDispersalReceipt> DepartmentGoalChangeReDispersal(DepartmentGoalExtrapolationRequest request)
|
|
{
|
|
var personnelGoals = await _goalService.GetMonthlyPersonnelGoalsAsync(new DepartmentPersonnelSearchRequest()
|
|
{
|
|
DepartmentId = request.DepartmentId,
|
|
IncludeAllPersonnel = true,
|
|
Year = request.DepartmentGoalStartDate.Year,
|
|
Month = request.DepartmentGoalStartDate.Month,
|
|
});
|
|
|
|
var receipt = _dispersalStrategyService.ExtrapolateSingleDepartmentProduct(request, personnelGoals);
|
|
return receipt;
|
|
}
|
|
|
|
public async Task<GoalDispersalReceipt> CustomWeightedDispersal(CustomWeightedDispersalRequest request)
|
|
{
|
|
try
|
|
{
|
|
var departmentGoals = await _goalService.GetAnnualDepartmentGoalsAsync(request.DepartmentId, request.year);
|
|
var productDepartmentGoal = departmentGoals.MonthlyGoals[request.month - 1].ProductGoals[request.DispersalProduct];
|
|
|
|
var departmentPersonnel = await _userService.FindDepartmentAssignments(
|
|
new DepartmentPersonnelSearchRequest()
|
|
{
|
|
DepartmentId = request.DepartmentId,
|
|
Month = request.month,
|
|
Year = request.year,
|
|
IncludeAllPersonnel = true
|
|
}
|
|
);
|
|
|
|
var receipt = _dispersalStrategyService.CustomWeightedDispersal(request, departmentPersonnel, productDepartmentGoal);
|
|
await _goalService.SaveGoalRangeAsync(receipt.GoalChanges);
|
|
|
|
return receipt;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error(ex, "Custom Weighted Dispersal Failed");
|
|
throw new Exceptions.ServerErrorException();
|
|
}
|
|
}
|
|
}
|