255 lines
9.7 KiB
C#
255 lines
9.7 KiB
C#
using LCU.API.Internal.Operations.IncentiveApi.Extensions;
|
|
using LCU.API.Internal.Operations.IncentiveApi.Services.DispersalStrategy;
|
|
using LCU.API.Internal.Operations.IncentiveApi.Models;
|
|
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.Entities;
|
|
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.Services;
|
|
|
|
public class GoalService : IGoalService
|
|
{
|
|
private readonly IGoalRepository _goalRepository;
|
|
private readonly IGoalChangeRepository _goalChangeRepository;
|
|
private readonly ICurrentUserService _currentUserService;
|
|
private readonly IDispersalStrategyService _dispersalStrategyService;
|
|
private readonly IDepartmentRepository _departmentRepository;
|
|
private readonly IUserService _userService;
|
|
private readonly IUnitOfWork _unitOfWork;
|
|
|
|
public GoalService(
|
|
IGoalRepository goalRepository,
|
|
IGoalChangeRepository goalChangeRepository,
|
|
ICurrentUserService currentUserService,
|
|
IDispersalStrategyService dispersalStrategyService,
|
|
IUnitOfWork unitOfWork,
|
|
IUserService userService,
|
|
IDepartmentRepository departmentRepository
|
|
)
|
|
{
|
|
_goalRepository = goalRepository;
|
|
_goalChangeRepository = goalChangeRepository;
|
|
_currentUserService = currentUserService;
|
|
_unitOfWork = unitOfWork;
|
|
_userService = userService;
|
|
_departmentRepository = departmentRepository;
|
|
_dispersalStrategyService = dispersalStrategyService;
|
|
}
|
|
|
|
public async Task<List<Goal>> SaveGoalAsync(GoalChange goalChange)
|
|
{
|
|
return await SaveGoalRangeAsync(new List<GoalChange>() { goalChange });
|
|
}
|
|
|
|
private async Task<GoalChange> ConfirmAppUserIdAndSaveGoalChange(GoalChange goalChange)
|
|
{
|
|
if (!goalChange.IsDepartmentGoalChange())
|
|
{
|
|
var appUser = await _userService.GetUserByEmployeeIdAsync(goalChange.PersonId);
|
|
goalChange.AppUserId = appUser.Id;
|
|
}
|
|
|
|
await _goalChangeRepository.SaveGoalChangeAsync(goalChange);
|
|
return goalChange;
|
|
}
|
|
|
|
public async Task<List<Goal>> SaveGoalRangeAsync(List<GoalChange> goalChanges)
|
|
{
|
|
var goalsToSave = new List<Goal>();
|
|
foreach (var goalChange in goalChanges)
|
|
{
|
|
await ConfirmAppUserIdAndSaveGoalChange(goalChange);
|
|
|
|
var goal = await _goalRepository.FindExistingGoal(goalChange);
|
|
if (goal != null)
|
|
{
|
|
var originalGoalValue = goal.Value;
|
|
goal.Value = goalChange.Value;
|
|
|
|
if (goal.IsDepartmentGoal() && originalGoalValue != goal.Value)
|
|
{
|
|
goalsToSave.AddRange(await CreatePersonnelGoalChangesFromDepartmentGoalChange(goalChange, originalGoalValue));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
goal = new Goal()
|
|
{
|
|
AppUserId = goalChange.AppUserId,
|
|
Product = goalChange.Product,
|
|
EmployeeId = goalChange.PersonId,
|
|
DepartmentId = goalChange.DepartmentId,
|
|
StartDate = goalChange.StartDate.StartOfMonth(),
|
|
EndDate = goalChange.EndDate.EndOfMonth(),
|
|
Value = goalChange.Value
|
|
};
|
|
await _goalRepository.SaveGoalAsync(goal);
|
|
}
|
|
|
|
goalsToSave.Add(goal);
|
|
}
|
|
|
|
await _unitOfWork.CompleteAsync();
|
|
return goalsToSave;
|
|
}
|
|
|
|
private async Task<List<Goal>> CreatePersonnelGoalChangesFromDepartmentGoalChange(GoalChange goalChange, int originalGoalValue)
|
|
{
|
|
if (!goalChange.IsDepartmentGoalChange()) return new List<Goal>();
|
|
var personnelGoals = new List<Goal>();
|
|
var departmentPersonnelGoals = await GetMonthlyPersonnelGoalsAsync(
|
|
new DepartmentPersonnelSearchRequest()
|
|
{
|
|
DepartmentId = goalChange.DepartmentId,
|
|
IncludeAllPersonnel = true,
|
|
Year = goalChange.StartDate.Year,
|
|
Month = goalChange.StartDate.Month,
|
|
});
|
|
var receipt = _dispersalStrategyService.ExtrapolateSingleDepartmentProduct(
|
|
new DepartmentGoalExtrapolationRequest()
|
|
{
|
|
DepartmentGoalEndDate = goalChange.EndDate.EndOfMonth(),
|
|
DepartmentGoalStartDate = goalChange.StartDate.StartOfMonth(),
|
|
DepartmentId = goalChange.DepartmentId,
|
|
NewDepartmentGoal = goalChange.Value,
|
|
OriginalDepartmentGoal = originalGoalValue,
|
|
Product = goalChange.Product
|
|
}, departmentPersonnelGoals);
|
|
|
|
foreach (var reDispersedGoalChange in receipt.GoalChanges)
|
|
{
|
|
await ConfirmAppUserIdAndSaveGoalChange(reDispersedGoalChange);
|
|
var reDispersedGoal = await CreateOrUpdateGoalFromGoalChange(reDispersedGoalChange);
|
|
personnelGoals.Add(reDispersedGoal);
|
|
}
|
|
|
|
return personnelGoals;
|
|
}
|
|
|
|
private async Task<Goal> CreateOrUpdateGoalFromGoalChange(GoalChange goalChange)
|
|
{
|
|
var goal = await _goalRepository.FindExistingGoal(goalChange);
|
|
if (goal != null)
|
|
{
|
|
goal.Value = goalChange.Value;
|
|
}
|
|
else
|
|
{
|
|
goal = new Goal()
|
|
{
|
|
Product = goalChange.Product,
|
|
AppUserId = goalChange.AppUserId,
|
|
EmployeeId = goalChange.PersonId,
|
|
DepartmentId = goalChange.DepartmentId,
|
|
StartDate = goalChange.StartDate.StartOfMonth(),
|
|
EndDate = goalChange.EndDate.EndOfMonth(),
|
|
Value = goalChange.Value
|
|
};
|
|
await _goalRepository.SaveGoalAsync(goal);
|
|
}
|
|
|
|
return goal;
|
|
}
|
|
|
|
public async Task<DepartmentGoals> GetAnnualDepartmentGoalsAsync(int departmentId, int year)
|
|
{
|
|
var goals = new DepartmentGoals(departmentId, year);
|
|
|
|
goals.ApplyAll(await _goalRepository.FindAnnualDepartmentGoals(departmentId, year));
|
|
return goals;
|
|
}
|
|
|
|
public async Task<IReadOnlyCollection<DepartmentGoals>> GetAllAnnualDepartmentGoalsAsync(int year)
|
|
{
|
|
var departments = await _departmentRepository.GetAllDepartmentsAsync();
|
|
var departmentGoals = new List<DepartmentGoals>();
|
|
foreach (var department in departments)
|
|
{
|
|
if (department.Id != null)
|
|
{
|
|
departmentGoals.Add(await GetAnnualDepartmentGoalsAsync(department.Id.Value, year));
|
|
}
|
|
}
|
|
|
|
return departmentGoals;
|
|
}
|
|
|
|
public async Task<PersonnelGoals> GetMonthlyPersonnelGoalsAsync(DepartmentPersonnelSearchRequest searchRequest)
|
|
{
|
|
var users = await _userService.FindDepartmentAssignments(searchRequest);
|
|
var goals = new PersonnelGoals(searchRequest.DepartmentId, searchRequest.Year, searchRequest.Month, users);
|
|
|
|
goals.ApplyAll(await _goalRepository.FindMonthlyPersonnelGoals(searchRequest.DepartmentId, users,
|
|
searchRequest.Year, searchRequest.Month));
|
|
return goals;
|
|
}
|
|
|
|
public async Task<IReadOnlyCollection<Goal>> GetGoalsAsync(GoalSearchRequest goalSearchRequest)
|
|
{
|
|
return await _goalRepository.GetGoalsAsync(goalSearchRequest);
|
|
}
|
|
|
|
public async Task<IReadOnlyCollection<GoalChange>> GetGoalChangesAsync()
|
|
{
|
|
return await _goalChangeRepository.GetGoalChangesAsync();
|
|
}
|
|
|
|
public async Task<EmployeeGoals> GetEmployeeGoalsForMonthRangeAsync(AppUser employee, MonthRange monthRange)
|
|
{
|
|
var users = new List<AppUser>()
|
|
{
|
|
employee
|
|
};
|
|
var goals = new EmployeeGoals(employee, monthRange);
|
|
|
|
|
|
foreach (var dept in goals.Departments)
|
|
{
|
|
goals.ApplyAll(
|
|
await _goalRepository.FindPersonnelGoalsByMonthRange(dept.DepartmentId, users, monthRange));
|
|
}
|
|
|
|
return goals;
|
|
}
|
|
|
|
public async Task<IReadOnlyCollection<DepartmentGoalsForRange>> GetEmployeeDepartmentsGoalsForMonthRangeAsync(AppUser employee, MonthRange monthRange)
|
|
{
|
|
var allGoals = new List<DepartmentGoalsForRange>();
|
|
|
|
foreach (var dept in employee.Departments)
|
|
{
|
|
var isAssignedInMonthRange = dept.StartDate.Date < monthRange.EndTime.Date &&
|
|
(dept.EndDate == null ||
|
|
monthRange.StartTime.Date < dept.EndDate.Value.Date);
|
|
if (isAssignedInMonthRange)
|
|
{
|
|
var StartDate = dept.StartDate.Date < monthRange.StartTime.Date
|
|
? monthRange.StartTime.Date
|
|
: dept.StartDate.Date;
|
|
var EndDate = dept.EndDate == null ? monthRange.EndTime.Date
|
|
: dept.EndDate.Value.Date > monthRange.EndTime.Date ? monthRange.EndTime.Date
|
|
: dept.EndDate.Value.Date;
|
|
var monthRangeOfAssignment = new MonthRange
|
|
(
|
|
StartDate.Year,
|
|
StartDate.Month,
|
|
EndDate.Year,
|
|
EndDate.Month
|
|
);
|
|
|
|
var goals = new DepartmentGoalsForRange(dept.DepartmentId, monthRangeOfAssignment);
|
|
var deptGoals =
|
|
await _goalRepository.FindDepartmentGoalsByMonthRange(goals.DepartmentId, goals.MonthRange);
|
|
goals.ApplyAll(deptGoals);
|
|
allGoals.Add(goals);
|
|
}
|
|
}
|
|
|
|
return allGoals;
|
|
}
|
|
}
|