139 lines
5.3 KiB
C#
139 lines
5.3 KiB
C#
using LCU.Library.Internal.IncentiveApiModels.Entities;
|
|
using LCU.Library.Internal.IncentiveApiModels.Enums;
|
|
using LCU.API.Internal.Operations.IncentiveApi.Services.Rules;
|
|
using LCU.API.Internal.Operations.IncentiveApi.Models.Payout;
|
|
using LCU.API.Internal.Operations.IncentiveApiLib.Repositories;
|
|
using LCU.Library.Internal.IncentiveApiModels.Common;
|
|
|
|
namespace LCU.API.Internal.Operations.IncentiveApi.Services.Payout;
|
|
|
|
public class PayoutCalculateService : IPayoutCalculateService
|
|
{
|
|
private readonly IActivityRepository _activityRepository;
|
|
private readonly IGoalRepository _goalRepository;
|
|
private readonly ICommissionRepository _commissionRepository;
|
|
private readonly IEnumerable<IPayoutStrategy> _payoutStrategies;
|
|
private readonly IBusinessRuleService _businessRuleService;
|
|
|
|
public PayoutCalculateService(
|
|
IActivityRepository activityRepository,
|
|
IGoalRepository goalRepository,
|
|
ICommissionRepository commissionRepository,
|
|
IEnumerable<IPayoutStrategy> payoutStrategies,
|
|
IBusinessRuleService businessRuleService
|
|
)
|
|
{
|
|
_activityRepository = activityRepository;
|
|
_goalRepository = goalRepository;
|
|
_commissionRepository = commissionRepository;
|
|
_payoutStrategies = payoutStrategies;
|
|
_businessRuleService = businessRuleService;
|
|
}
|
|
|
|
public async Task<DepartmentPayout> BuildDepartmentPayoutView(
|
|
AppUser employee,
|
|
UserDepartment userDepartment,
|
|
MonthRange monthRange
|
|
)
|
|
{
|
|
var payoutPlan = new DepartmentPayout(employee, userDepartment, monthRange,
|
|
_businessRuleService.GetRules(PayoutType.Department),
|
|
_businessRuleService.GetRules(PayoutType.Personal))
|
|
{
|
|
EligibleCommissions = await _commissionRepository.FindProductCommissions(userDepartment.Role)
|
|
};
|
|
|
|
if (!payoutPlan.HasEligibleIncentives())
|
|
{
|
|
return payoutPlan;
|
|
}
|
|
|
|
payoutPlan.PersonalActivity =
|
|
await _activityRepository.FindEmployeeActivityByMonthRange(payoutPlan.Employee, payoutPlan.MonthRange);
|
|
|
|
payoutPlan.DepartmentActivity =
|
|
await _activityRepository.FindDepartmentActivityByMonthRange(userDepartment.DepartmentId,
|
|
payoutPlan.MonthRange);
|
|
|
|
if (!payoutPlan.HasEligibleActivity())
|
|
{
|
|
return payoutPlan;
|
|
}
|
|
|
|
var users = new List<AppUser>()
|
|
{
|
|
payoutPlan.Employee
|
|
};
|
|
|
|
payoutPlan.PersonalGoals = await _goalRepository.FindPersonnelGoalsByMonthRange(userDepartment.DepartmentId,
|
|
users, payoutPlan.MonthRange);
|
|
|
|
payoutPlan.DepartmentGoals = await _goalRepository.FindDepartmentGoalsByMonthRange(
|
|
userDepartment.DepartmentId,
|
|
payoutPlan.MonthRange);
|
|
|
|
if (payoutPlan.HasEligibleCommissions())
|
|
{
|
|
payoutPlan.CommissionPayouts = CalculateCommissionLineItems(payoutPlan, userDepartment);
|
|
}
|
|
|
|
payoutPlan.GoalPayouts = CalculateGoalLineItems(payoutPlan, userDepartment);
|
|
|
|
return payoutPlan;
|
|
}
|
|
|
|
public List<PayoutLineItem> CalculateCommissionLineItems(DepartmentPayout payoutPlan, UserDepartment userDepartment)
|
|
{
|
|
var lineItems = new List<PayoutLineItem>();
|
|
var departmentCommissions = payoutPlan.EligibleCommissions;
|
|
|
|
if (departmentCommissions == null || !departmentCommissions.Any()) return lineItems;
|
|
|
|
foreach (var product in departmentCommissions.Select(x => x.Product).Distinct().ToList())
|
|
{
|
|
var eligibleCommission = departmentCommissions.FirstOrDefault(c => c.Product == product);
|
|
if (eligibleCommission == null) continue;
|
|
var eligibleActivity = payoutPlan.PersonalActivity
|
|
.Where(a => a.DepartmentId == userDepartment.DepartmentId &&
|
|
a.Product == product &&
|
|
a.Type != ActivityType.Other
|
|
&& a.State == ActivityState.Accepted
|
|
&& !payoutPlan.PersonalRules.Any(x => x.RestrictedByPayoutRule(a, product)))
|
|
.ToList();
|
|
|
|
var lineItem = new PayoutLineItem(product, eligibleCommission, eligibleActivity)
|
|
{
|
|
ActivityPeriod = payoutPlan.MonthRange.StartTime,
|
|
AppUserId = userDepartment.Employee.Id,
|
|
EmployeeId = userDepartment.Employee.EmployeeId,
|
|
DepartmentId = userDepartment.DepartmentId,
|
|
Role = userDepartment.Role
|
|
};
|
|
|
|
if (lineItem.PayoutTotal > 0)
|
|
{
|
|
lineItems.Add(lineItem);
|
|
}
|
|
}
|
|
|
|
return lineItems;
|
|
}
|
|
|
|
public List<PayoutLineItem> CalculateGoalLineItems(DepartmentPayout payoutPlan, UserDepartment userDepartment)
|
|
{
|
|
var lineItems = new List<PayoutLineItem>();
|
|
var departmentPayouts = payoutPlan.EligiblePayouts.ToList();
|
|
if (!departmentPayouts.Any()) return lineItems;
|
|
|
|
foreach (var product in ProductDetail.ProductDetails)
|
|
{
|
|
var strategy = _payoutStrategies.FirstOrDefault(x => x.CanPayoutProduct(product.Product));
|
|
if (strategy == null) continue;
|
|
var items = strategy.CalculateLineItems(payoutPlan, userDepartment, departmentPayouts, product);
|
|
lineItems.AddRange(items);
|
|
}
|
|
|
|
return lineItems;
|
|
}
|
|
}
|