using LCU.Library.Internal.IncentiveApiModels.Entities; using LCU.Library.Internal.IncentiveApiModels.Enums; using LCU.API.Internal.Operations.IncentiveApi.Models.Payout; namespace LCU.API.Internal.Operations.IncentiveApi.Services.Payout; public class GapPayoutStrategy : IPayoutStrategy { private const bool IsEnabled = false; public bool CanPayoutProduct(Product product) { return product == Product.GAPInsurance && IsEnabled; } public IReadOnlyCollection CalculateLineItems( DepartmentPayout payoutPlan, UserDepartment userDepartment, List departmentPayouts, ProductDetail product ) { var lineItems = new List(); if (!payoutPlan.Department.IsHome) return lineItems; var eligiblePayouts = departmentPayouts.Where(p => p.Product == product.Product); if (eligiblePayouts.Any(x => x.Type == PayoutType.Department)) { throw new Exception("GAP Payouts configured for personal goals only, if you have enable department payouts you must add payout logic."); } foreach (var eligiblePayoutProfile in eligiblePayouts.Where(x => x.Type == PayoutType.Personal)) { var eligibleGoal = payoutPlan.PersonalActivity .Where(a => a.Detail is { IsDebtProtectionEligible: true } && a.State == ActivityState.Accepted) .ToList(); if (!eligibleGoal.Any()) continue; var gapActivity = payoutPlan.PersonalActivity .Where(a => a.Product == product.Product && a.State == ActivityState.Accepted && !payoutPlan.PersonalRules.Any(x => x.RestrictedByPayoutRule(a, product.Product)) ) .ToList(); var goalCount = eligibleGoal.Count; var actualCount = eligibleGoal.Count(a => a.Detail.DebtProtectionAddDate != null && a.Detail.DebtProtectionRemoveDate == null); gapActivity.AddRange(eligibleGoal); var lineItem = new PayoutLineItem(product.Product, eligiblePayoutProfile, eligibleGoal.Count, userDepartment.SlidingPayout, gapActivity) { ActivityPeriod = payoutPlan.MonthRange.StartTime, AppUserId = userDepartment.Employee.Id, EmployeeId = userDepartment.Employee.EmployeeId, DepartmentId = userDepartment.DepartmentId, Role = userDepartment.Role }; lineItem.PayoutTotal = CalculateLineItemPayout(eligiblePayoutProfile, goalCount, actualCount, lineItem.ActivityTotal, payoutPlan.MonthRange.StartTime, lineItem.SlidingPayout); if (lineItem.PayoutTotal > 0) { lineItems.Add(lineItem); } } return lineItems; } private decimal CalculateLineItemPayout(PayoutProfile profile, int goal, decimal actual, decimal each, DateTime runDate, decimal payoutPercent = 100) { if (profile == null) { throw new Exception("Attempt to calculate payout with null profile"); } if (goal == 0) return 0; var goalPercentage = (double)actual / goal; var payoutRange = profile.FindPayoutRange(goalPercentage, runDate); if (payoutRange == null) { return 0; } decimal payoutAmt = payoutRange.Payout; if (profile.PayEach) { payoutAmt *= each; } var payoutPercentage = (double)payoutPercent / 100; var finalPayout = (double)payoutAmt * payoutPercentage; payoutAmt = (decimal)Math.Round(finalPayout, 2); return payoutAmt; } }