using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading.Tasks; using LCU.API.Internal.Operations.IncentiveApiLib.Repositories; using LCU.Library.Internal.IncentiveApiModels.Entities; using LCU.Library.Internal.IncentiveApiModels.Enums; using Moq; using NUnit.Framework; using LCU.API.Internal.Operations.IncentiveApi.Services.Payout; using LCU.API.Internal.Operations.IncentiveApi.Services.Rules; using LCU.API.Internal.Operations.IncentiveApi.Models; using LCU.Library.Internal.IncentiveApiModels.Common; namespace Application.UnitTests.Services.Payout { public class PayoutCalculateServiceTest { private IPayoutCalculateService _payoutCalculateService; private Mock _mockActivityRepository; private Mock _mockGoalRepository; private Mock _mockCommissionRepository; private Mock _mockBusinessRuleService; private readonly List _departmentRules = new List { new NewCheckingReferralRule(56) // this simulates looking up 200. }; private readonly List _personalRules = new List(); private readonly DateTime _nonOverriddenDateTime = DateTime.ParseExact("2021-12-01", "yyyy-MM-dd", CultureInfo.InvariantCulture); [SetUp] public void Setup() { _mockActivityRepository = new Mock(); _mockGoalRepository = new Mock(); _mockCommissionRepository = new Mock(); _mockBusinessRuleService = new Mock(); IEnumerable payoutStrategies = new List() { new DefaultPayoutStrategy(), new GapPayoutStrategy() }; _mockBusinessRuleService.Setup(x => x.GetRules(PayoutType.Department)).Returns(_departmentRules); _mockBusinessRuleService.Setup(x => x.GetRules(PayoutType.Personal)).Returns(_personalRules); _payoutCalculateService = new PayoutCalculateService(_mockActivityRepository.Object, _mockGoalRepository.Object, _mockCommissionRepository.Object, payoutStrategies, _mockBusinessRuleService.Object); } [Test] public async Task DepartmentPayoutView_Empty() { var theTestDate = DateTime.Today; AppUser employee = GetBasicTestEmployee(Role.BM); var userDepartment = GetBasicDepartmentAssignment(employee, theTestDate); employee.Departments.Add(userDepartment); _mockActivityRepository .Setup(activity => activity.FindEmployeeActivityByMonthRange(employee, It.IsAny())) .ReturnsAsync(new List()); _mockActivityRepository .Setup(activity => activity.FindDepartmentActivityByMonthRange(userDepartment.DepartmentId, It.IsAny())) .ReturnsAsync(new List()); _mockCommissionRepository.Setup(commission => commission.FindProductCommissions(employee.Role)) .ReturnsAsync(new List()); _mockGoalRepository.Setup(goal => goal.FindPersonnelGoalsByMonthRange(userDepartment.DepartmentId, It.IsAny>(), It.IsAny())).ReturnsAsync(new List()); _mockGoalRepository.Setup(goal => goal.FindDepartmentGoalsByMonthRange(userDepartment.DepartmentId, It.IsAny())) .ReturnsAsync(new List()); var deptPayoutView = await _payoutCalculateService.BuildDepartmentPayoutView(employee,userDepartment, new MonthRange(theTestDate.Year, theTestDate.Month)); Assert.NotNull(deptPayoutView); Assert.NotNull(deptPayoutView.CommissionPayouts); Assert.IsEmpty(deptPayoutView.CommissionPayouts); Assert.NotNull(deptPayoutView.GoalPayouts); Assert.IsEmpty(deptPayoutView.GoalPayouts); } /** * Create a user with a department, activity, goals, commissions and a role that * has a matching personal payout plan. * Here we test a BM, as they can earn commission and DEPARTMENT payouts, but not personal * #27202, make sure sales/referrals work correctly. */ [Test] public async Task PayoutPlan_Commission_Payout_Department() { var theTestDate = DateTime.Today; AppUser employee = GetBasicTestEmployee(Role.BM); var userDept = GetBasicDepartmentAssignment(employee, theTestDate); employee.Departments.Add(userDept); userDept.Role = Role.BM; var activity = new List() { new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Type = ActivityType.Sale, Detail = new ActivityDetail() { AccountNumber = "123456789", AgreementNumber = "123456789", SubjectPersonNbr = "IGuess1", SubjectOrgNbr = "IGuess1", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation", AccountBalance = 1000 }, State = ActivityState.ManualReview }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Type = ActivityType.Other, Detail = new ActivityDetail() { AccountNumber = "223456789", AgreementNumber = "223456789", SubjectPersonNbr = "IGuessOther1", SubjectOrgNbr = "IGuessOther1", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "223456789", StationName = "PlayStation", AccountBalance = 1000 }, State = ActivityState.ManualReview }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, Type = ActivityType.Sale, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456788", AgreementNumber = "123456788", SubjectPersonNbr = "IGuess2", SubjectOrgNbr = "IGuess2", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation", AccountBalance = 1000 }, State = ActivityState.ManualReview }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, Type = ActivityType.Sale, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456787", AgreementNumber = "123456787", SubjectPersonNbr = "IGuess3", SubjectOrgNbr = "IGuess3", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation" }, State = ActivityState.ManualReview }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, Type = ActivityType.Sale, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456786", AgreementNumber = "123456786", SubjectPersonNbr = "IGuess4", SubjectOrgNbr = "IGuess4", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation", AccountBalance = 1000 }, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, Type = ActivityType.Other, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "223456786", AgreementNumber = "223456786", SubjectPersonNbr = "IGuessOther4", SubjectOrgNbr = "IGuessOther4", MemberName = "NotNeededOther?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation", AccountBalance = 1000 }, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456785", AgreementNumber = "123456785", SubjectPersonNbr = "IGuess5", SubjectOrgNbr = "IGuess5", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation", AccountBalance = 1000 }, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, Type = ActivityType.Referral, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "1234567850", AgreementNumber = "1234567850", SubjectPersonNbr = "IGuess55", SubjectOrgNbr = "IGuess55", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "1234567890", StationName = "PlayStation", // ,AccountBalance = 5000 TODO #27202, this shouldn't count? Is it all referrals, or mortgage referrals? }, State = ActivityState.Accepted }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, Type = ActivityType.Sale, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456784", AgreementNumber = "123456784", SubjectPersonNbr = "IGuess6", SubjectOrgNbr = "IGuess6", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation" }, State = ActivityState.Accepted } }; var commissions = new List() { new Commission() { Product = Product.Mortgage, RatePerProduct = 5, Role = userDept.Role }, new Commission() { Product = Product.NewChecking, RatePerProduct = 25, Role = userDept.Role }, new Commission() { Product = Product.Vehicle, RatePerProduct = 100, Role = userDept.Role } }; var personalGoals = new List() { new Goal() { Product = Product.Mortgage, Value = 2000, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId } }; var departmentGoals = new List() { new Goal() { Product = Product.Mortgage, Value = 2000, DepartmentId = userDept.DepartmentId } }; _mockActivityRepository .Setup(activity => activity.FindEmployeeActivityByMonthRange(employee, It.IsAny())) .ReturnsAsync(activity); _mockActivityRepository .Setup(activity => activity.FindDepartmentActivityByMonthRange(userDept.DepartmentId, It.IsAny())) .ReturnsAsync(activity); _mockCommissionRepository.Setup(commission => commission.FindProductCommissions(userDept.Role)) .ReturnsAsync(commissions); _mockGoalRepository.Setup(goal => goal.FindPersonnelGoalsByMonthRange(userDept.DepartmentId, It.IsAny>(), It.IsAny())).ReturnsAsync(personalGoals); _mockGoalRepository.Setup(goal => goal.FindDepartmentGoalsByMonthRange(userDept.DepartmentId, It.IsAny())) .ReturnsAsync(departmentGoals); var payout = await _payoutCalculateService.BuildDepartmentPayoutView(employee, userDept, new MonthRange(theTestDate.Year, theTestDate.Month)); Assert.NotNull(payout); Assert.NotNull(payout.CommissionPayouts); Assert.NotNull(payout.CommissionPayouts); Assert.IsNotEmpty(payout.CommissionPayouts); Assert.NotNull(payout.GoalPayouts); Assert.IsNotEmpty(payout.GoalPayouts); var newCheckingComm = payout.CommissionPayouts .FirstOrDefault(x => x.Product == Product.NewChecking); var mortgageComm = payout.CommissionPayouts .FirstOrDefault(x => x.Product == Product.Mortgage); Assert.AreEqual(15, mortgageComm.PayoutTotal); Assert.AreEqual(25, newCheckingComm.PayoutTotal); var payoutRange = PayoutProfile.BMMortgage.Payouts.First().Value; Assert.AreEqual(payoutRange[0].Payout, payout.GoalPayouts.First().PayoutTotal); } /** * Create a user with a department, activity, goals, commissions and a role that * has a matching personal payout plan. * Here we test a BM, as they can earn commission and DEPARTMENT payouts, but not personal * We test this BM in two places - Member Services, and Not. For new checking. #26912 */ [Test] public async Task PayoutPlan_Commission_Goal_Payout_Department_NewChecking_Exception() { var theTestDate = DateTime.Today; AppUser employee = GetBasicTestEmployee(Role.BM); var userDept = GetBasicDepartmentAssignment(employee, theTestDate); employee.Departments.Add(userDept); userDept.Role = Role.BM; var activity = new List() { new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Type = ActivityType.Referral, State = ActivityState.Accepted }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Type = ActivityType.Sale, State = ActivityState.ManualReview }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, Type = ActivityType.Sale, DepartmentId = userDept.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, Type = ActivityType.Referral, DepartmentId = userDept.DepartmentId, State = ActivityState.Rejected } }; var commissions = new List() { new Commission() { Product = Product.NewChecking, RatePerProduct = 25, Role = userDept.Role } }; var personalGoals = new List() { new Goal() { Product = Product.NewChecking, Value = 2, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId } }; var departmentGoals = new List() { new Goal() { Product = Product.NewChecking, Value = 1, DepartmentId = userDept.DepartmentId } }; var departmentRules = new List() { new NewCheckingReferralRule(56) // this simulates looking up 200. }; var personalRules = new List(); _mockActivityRepository .Setup(activity => activity.FindEmployeeActivityByMonthRange(employee, It.IsAny())) .ReturnsAsync(activity); _mockActivityRepository .Setup(activity => activity.FindDepartmentActivityByMonthRange(userDept.DepartmentId, It.IsAny())) .ReturnsAsync(activity); _mockCommissionRepository.Setup(commission => commission.FindProductCommissions(userDept.Role)) .ReturnsAsync(commissions); _mockGoalRepository.Setup(goal => goal.FindPersonnelGoalsByMonthRange(userDept.DepartmentId, It.IsAny>(), It.IsAny())).ReturnsAsync(personalGoals); _mockGoalRepository.Setup(goal => goal.FindDepartmentGoalsByMonthRange(userDept.DepartmentId, It.IsAny())) .ReturnsAsync(departmentGoals); var payout = await _payoutCalculateService.BuildDepartmentPayoutView(employee, userDept, new MonthRange(theTestDate.Year, theTestDate.Month)); Assert.NotNull(payout); Assert.NotNull(payout.CommissionPayouts); Assert.NotNull(payout.CommissionPayouts); Assert.IsNotEmpty(payout.CommissionPayouts); Assert.NotNull(payout.GoalPayouts); Assert.IsNotEmpty(payout.GoalPayouts); var newCheckingComm = payout.CommissionPayouts .FirstOrDefault(x => x.Product == Product.NewChecking); Assert.AreEqual(50, newCheckingComm.PayoutTotal); var payoutRange = PayoutProfile.BMNewChecking.Payouts.First().Value; Assert.AreEqual(payoutRange[0].Payout, payout.GoalPayouts.First().PayoutTotal); } /** * Create a user with a department, activity, goals, and a role that has a GAP payout plan. * Here we test a BM getting GAP payouts. */ [Test] public async Task PayoutPlan_Payout_GAP_Simple() { var theTestDate = DateTime.Today; AppUser employee = GetBasicTestEmployee(Role.BM); var userDept = GetBasicDepartmentAssignment(employee, theTestDate); employee.Departments.Add(userDept); userDept.Role = Role.BM; // We need multiple activity types here.... // Let's lay it out: // 3 GAP, two approved. // 5 that are eligible, 4 are approved. // 3/4 that have debt protection => 3/5 var activity = new List() { new Activity() { Product = Product.GAPInsurance, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456700", AgreementNumber = "123456700", SubjectPersonNbr = "GAP0", SubjectOrgNbr = "DGAP0", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456780", StationName = "PlayStation" }, State = ActivityState.Accepted }, new Activity() { Product = Product.GAPInsurance, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456789", AgreementNumber = "123456789", SubjectPersonNbr = "GAP1", SubjectOrgNbr = "DGAP1", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation" }, State = ActivityState.Accepted }, new Activity() { Product = Product.GAPInsurance, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456789", AgreementNumber = "123456789", SubjectPersonNbr = "GAP2", SubjectOrgNbr = "DGAP2", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation" }, State = ActivityState.Rejected }, new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456788", AgreementNumber = "123456788", SubjectPersonNbr = "DEBTPROTELIG1", SubjectOrgNbr = "DEPTDEBTPROTELIG1", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456788", StationName = "PlayStation", IsDebtProtectionEligible = true, DebtProtectionAddDate = DateTime.UtcNow }, State = ActivityState.Accepted }, new Activity() { Product = Product.Vehicle, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456777", AgreementNumber = "123456777", SubjectPersonNbr = "DEBTPROTELIG2", SubjectOrgNbr = "DEPTDEBTPROTELIG2", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456787", StationName = "PlayStation", IsDebtProtectionEligible = true, DebtProtectionAddDate = DateTime.UtcNow }, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456766", AgreementNumber = "123456766", SubjectPersonNbr = "DEBTPROTELIG3", SubjectOrgNbr = "DEPTDEBTPROTELIG3", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456786", StationName = "PlayStation", IsDebtProtectionEligible = true, DebtProtectionAddDate = DateTime.UtcNow }, State = ActivityState.Accepted }, new Activity() { Product = Product.DebtProtectionEligibleLoan, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456755", AgreementNumber = "123456755", SubjectPersonNbr = "DEBTPROTELIG4", SubjectOrgNbr = "DEPTDEBTPROTELIG4", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456785", StationName = "PlayStation", IsDebtProtectionEligible = true }, State = ActivityState.Rejected }, new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456744", AgreementNumber = "123456744", SubjectPersonNbr = "DEBTPROTELIG5", SubjectOrgNbr = "DEPTDEBTPROTELIG5", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456784", StationName = "PlayStation", IsDebtProtectionEligible = true }, State = ActivityState.Accepted } }; var commissions = new List() { new Commission { Id = 1, Role = userDept.Role, RatePerProduct = 20, Product = Product.GAPInsurance } }; var personalGoals = new List(); var departmentGoals = new List(); _mockActivityRepository .Setup(activity => activity.FindEmployeeActivityByMonthRange(employee, It.IsAny())) .ReturnsAsync(activity); _mockActivityRepository .Setup(activity => activity.FindDepartmentActivityByMonthRange(userDept.DepartmentId, It.IsAny())) .ReturnsAsync(activity); _mockCommissionRepository.Setup(commission => commission.FindProductCommissions(userDept.Role)) .ReturnsAsync(commissions); _mockGoalRepository.Setup(goal => goal.FindPersonnelGoalsByMonthRange(userDept.DepartmentId, It.IsAny>(), It.IsAny())).ReturnsAsync(personalGoals); _mockGoalRepository.Setup(goal => goal.FindDepartmentGoalsByMonthRange(userDept.DepartmentId, It.IsAny())) .ReturnsAsync(departmentGoals); var payout = await _payoutCalculateService.BuildDepartmentPayoutView(employee, userDept, new MonthRange(theTestDate.Year, theTestDate.Month)); Assert.NotNull(payout); Assert.NotNull(payout.CommissionPayouts); Assert.IsNotEmpty(payout.CommissionPayouts); Assert.NotNull(payout.GoalPayouts); Assert.IsEmpty(payout.GoalPayouts); var gapPayout = payout.CommissionPayouts.First(); Assert.NotNull(gapPayout); Assert.AreEqual(2, gapPayout.ActivityTotal); Assert.AreEqual(2 * gapPayout.CommissionValue, gapPayout.PayoutTotal); } /** * Create a user with a department, activity, goals, and a role that has a GAP payout plan. * Here we test a BM getting GAP payouts. */ [Test] public async Task PayoutPlan_Payout_GAP_Complex() { var theTestDate = DateTime.Today; AppUser employee = GetBasicTestEmployee(Role.BM); var userDept = GetBasicDepartmentAssignment(employee, theTestDate); employee.Departments.Add(userDept); userDept.Role = Role.BM; // We need multiple activity types here.... // Let's lay it out: // 4 GAP, three approved. // 1 that is ineligible. // 8 that are eligible: 1 is rejected. 3 have prot. 4 are eligible, no prot. // 7/3 that have debt protection => 3/7 (42%) // 13 total... // Will have -10- associated activities (Eligible + Gap), and pay out 3 x $40.00 ($120), for the 42%. var activity = new List() { // GAP, 3 approved new Activity() { Product = Product.GAPInsurance, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456001", AgreementNumber = "123456001", SubjectPersonNbr = "GAP01", SubjectOrgNbr = "DGAP01", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456700", StationName = "PlayStation" }, State = ActivityState.Accepted }, new Activity() { Product = Product.GAPInsurance, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456700", AgreementNumber = "123456700", SubjectPersonNbr = "GAP0", SubjectOrgNbr = "DGAP0", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456780", StationName = "PlayStation" }, State = ActivityState.Accepted }, new Activity() { Product = Product.GAPInsurance, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456789", AgreementNumber = "123456789", SubjectPersonNbr = "GAP1", SubjectOrgNbr = "DGAP1", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation" }, State = ActivityState.Accepted }, // Gap, 1 Rejected. new Activity() { Product = Product.GAPInsurance, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456789", AgreementNumber = "123456789", SubjectPersonNbr = "GAP2", SubjectOrgNbr = "DGAP2", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation" }, State = ActivityState.Rejected }, // Eligible 3 with prot, accepted new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456788", AgreementNumber = "123456788", SubjectPersonNbr = "DEBTPROTELIG1", SubjectOrgNbr = "DEPTDEBTPROTELIG1", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456788", StationName = "PlayStation", IsDebtProtectionEligible = true, DebtProtectionAddDate = DateTime.UtcNow }, State = ActivityState.Accepted }, new Activity() { Product = Product.Vehicle, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456777", AgreementNumber = "123456777", SubjectPersonNbr = "DEBTPROTELIG2", SubjectOrgNbr = "DEPTDEBTPROTELIG2", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456787", StationName = "PlayStation", IsDebtProtectionEligible = true, DebtProtectionAddDate = DateTime.UtcNow }, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456766", AgreementNumber = "123456766", SubjectPersonNbr = "DEBTPROTELIG3", SubjectOrgNbr = "DEPTDEBTPROTELIG3", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456786", StationName = "PlayStation", IsDebtProtectionEligible = true, DebtProtectionAddDate = DateTime.UtcNow }, State = ActivityState.Accepted }, // 1 Ineligible, accepted, new Activity() { Product = Product.DebtProtectionEligibleLoan, EmployeeId = employee.EmployeeId, Type = ActivityType.Sale, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456755", AgreementNumber = "123456755", SubjectPersonNbr = "DEBTPROTINELIG1", SubjectOrgNbr = "DEPTDEBTPROTINELIG1", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456785", StationName = "PlayStation", IsDebtProtectionEligible = false }, State = ActivityState.Accepted }, // 1 eligible, but rejected, no prot. new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456744", AgreementNumber = "123456744", SubjectPersonNbr = "DEBTPROTELIG5", SubjectOrgNbr = "DEPTDEBTPROTELIG5", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456784", StationName = "PlayStation", IsDebtProtectionEligible = true }, State = ActivityState.Rejected }, // 4 eligible, accepted, no prot. new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456744", AgreementNumber = "123456744", SubjectPersonNbr = "DEBTPROTELIG61", SubjectOrgNbr = "DEPTDEBTPROTELIG61", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456784", StationName = "PlayStation", IsDebtProtectionEligible = true }, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456744", AgreementNumber = "123456744", SubjectPersonNbr = "DEBTPROTELIG62", SubjectOrgNbr = "DEPTDEBTPROTELIG62", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456784", StationName = "PlayStation", IsDebtProtectionEligible = true }, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456744", AgreementNumber = "123456744", SubjectPersonNbr = "DEBTPROTELIG63", SubjectOrgNbr = "DEPTDEBTPROTELIG64", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456784", StationName = "PlayStation", IsDebtProtectionEligible = true }, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456744", AgreementNumber = "123456744", SubjectPersonNbr = "DEBTPROTELIG65", SubjectOrgNbr = "DEPTDEBTPROTELIG65", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456784", StationName = "PlayStation", IsDebtProtectionEligible = true }, State = ActivityState.Accepted } }; var commissions = new List() { new Commission { Id = 1, Role = userDept.Role, RatePerProduct = 20, Product = Product.GAPInsurance } }; var personalGoals = new List(); var departmentGoals = new List(); _mockActivityRepository .Setup(activity => activity.FindEmployeeActivityByMonthRange(employee, It.IsAny())) .ReturnsAsync(activity); _mockActivityRepository .Setup(activity => activity.FindDepartmentActivityByMonthRange(userDept.DepartmentId, It.IsAny())) .ReturnsAsync(activity); _mockCommissionRepository.Setup(commission => commission.FindProductCommissions(userDept.Role)) .ReturnsAsync(commissions); _mockGoalRepository.Setup(goal => goal.FindPersonnelGoalsByMonthRange(userDept.DepartmentId, It.IsAny>(), It.IsAny())).ReturnsAsync(personalGoals); _mockGoalRepository.Setup(goal => goal.FindDepartmentGoalsByMonthRange(userDept.DepartmentId, It.IsAny())) .ReturnsAsync(departmentGoals); var payout = await _payoutCalculateService.BuildDepartmentPayoutView(employee, userDept, new MonthRange(theTestDate.Year, theTestDate.Month)); Assert.NotNull(payout); Assert.NotNull(payout.CommissionPayouts); Assert.IsNotEmpty(payout.CommissionPayouts); Assert.NotNull(payout.GoalPayouts); Assert.IsEmpty(payout.GoalPayouts); var gapPayout = payout.CommissionPayouts.First(); Assert.NotNull(gapPayout); Assert.AreEqual(3, gapPayout.ActivityTotal); Assert.AreEqual(3, gapPayout.ActivityPayouts.Count); var commissionProfile = commissions.First(); Assert.AreEqual(commissionProfile.RatePerProduct * gapPayout.ActivityPayouts.Count, 60); } /** * Create a user with a department, activity, goals, commissions and a role that * has a matching personal payout plan. * Here we test a BM again, but the department is only paying 75%. */ [Test] public async Task PayoutPlan_Commission_Payout_Department_Sliding() { var theTestDate = DateTime.Today; AppUser employee = GetBasicTestEmployee(Role.BM); var userDept = GetBasicDepartmentAssignment(employee, theTestDate); employee.Departments.Add(userDept); userDept.Role = Role.BM; userDept.SlidingPayout = 75; var activity = new List() { new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456789", AgreementNumber = "123456789", SubjectPersonNbr = "IGuess1", SubjectOrgNbr = "IGuess1", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation", AccountBalance = 1000 }, State = ActivityState.ManualReview }, new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456788", AgreementNumber = "123456788", SubjectPersonNbr = "IGuess2", SubjectOrgNbr = "IGuess2", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation", AccountBalance = 1000 }, State = ActivityState.ManualReview }, new Activity() { Product = Product.NewChecking, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456787", AgreementNumber = "123456787", SubjectPersonNbr = "IGuess3", SubjectOrgNbr = "IGuess3", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation" }, State = ActivityState.ManualReview }, new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456786", AgreementNumber = "123456786", SubjectPersonNbr = "IGuess4", SubjectOrgNbr = "IGuess4", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation", AccountBalance = 1000 }, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456785", AgreementNumber = "123456785", SubjectPersonNbr = "IGuess5", SubjectOrgNbr = "IGuess5", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation", AccountBalance = 1000 }, State = ActivityState.Accepted }, new Activity() { Product = Product.NewChecking, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, Detail = new ActivityDetail() { AccountNumber = "123456784", AgreementNumber = "123456784", SubjectPersonNbr = "IGuess6", SubjectOrgNbr = "IGuess6", MemberName = "NotNeeded?", BranchOrgName = "MoreFunFields", BranchOrgNbr = "MoreFunFields", DnaPersonNbr = "123456789", StationName = "PlayStation" }, State = ActivityState.Accepted } }; var commissions = new List() { new Commission() { Product = Product.Mortgage, RatePerProduct = 5, Role = userDept.Role }, new Commission() { Product = Product.NewChecking, RatePerProduct = 25, Role = userDept.Role }, new Commission() { Product = Product.Vehicle, RatePerProduct = 100, Role = userDept.Role } }; var personalGoals = new List() { new Goal() { Product = Product.Mortgage, Value = 2000, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId } }; var departmentGoals = new List() { new Goal() { Product = Product.Mortgage, Value = 2000, DepartmentId = userDept.DepartmentId } }; _mockActivityRepository .Setup(activity => activity.FindEmployeeActivityByMonthRange(employee, It.IsAny())) .ReturnsAsync(activity); _mockActivityRepository .Setup(activity => activity.FindDepartmentActivityByMonthRange(userDept.DepartmentId, It.IsAny())) .ReturnsAsync(activity); _mockCommissionRepository.Setup(commission => commission.FindProductCommissions(userDept.Role)) .ReturnsAsync(commissions); _mockGoalRepository.Setup(goal => goal.FindPersonnelGoalsByMonthRange(userDept.DepartmentId, It.IsAny>(), It.IsAny())).ReturnsAsync(personalGoals); _mockGoalRepository.Setup(goal => goal.FindDepartmentGoalsByMonthRange(userDept.DepartmentId, It.IsAny())) .ReturnsAsync(departmentGoals); var payout = await _payoutCalculateService.BuildDepartmentPayoutView(employee, userDept, new MonthRange(theTestDate.Year, theTestDate.Month)); Assert.NotNull(payout); Assert.NotNull(payout.CommissionPayouts); Assert.NotNull(payout.CommissionPayouts); Assert.IsNotEmpty(payout.CommissionPayouts); Assert.NotNull(payout.GoalPayouts); Assert.IsNotEmpty(payout.GoalPayouts); var newCheckingComm = payout.CommissionPayouts .FirstOrDefault(x => x.Product == Product.NewChecking); var mortgageComm = payout.CommissionPayouts .FirstOrDefault(x => x.Product == Product.Mortgage); Assert.AreEqual(10, mortgageComm.PayoutTotal); Assert.AreEqual(25, newCheckingComm.PayoutTotal); var payoutRange = PayoutProfile.BMMortgage.Payouts.First().Value; Assert.AreEqual( payoutRange[0].Payout * .75, payout.GoalPayouts.First().PayoutTotal); Assert.AreEqual(150, payout.GoalPayouts.First().PayoutTotal); } /** * Create a user with a department, activity, goals, commissions and a role that * has no matching payout plan; should still see commissions. */ [Test] public async Task PayoutPlan_NoPayoutProfile() { var theTestDate = DateTime.Today; AppUser employee = GetBasicTestEmployee(Role.Teller); var userDept = GetBasicDepartmentAssignment(employee, theTestDate); employee.Departments.Add(userDept); userDept.Role = Role.Teller; var activity = new List() { new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.NewChecking, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.Rejected }, new Activity() { Product = Product.Mortgage, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.PendingTransfer }, new Activity() { Product = Product.NewChecking, Type = ActivityType.Sale, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.ManualReview } }; var commissions = new List() { new Commission() { Product = Product.Mortgage, RatePerProduct = 5, Role = userDept.Role } }; var goals = new List() { new Goal() { Product = Product.Mortgage, Value = 2, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId } }; _mockActivityRepository .Setup(activity => activity.FindEmployeeActivityByMonthRange(employee, It.IsAny())) .ReturnsAsync(activity); _mockCommissionRepository.Setup(commission => commission.FindProductCommissions(userDept.Role)) .ReturnsAsync(commissions); _mockGoalRepository.Setup(goal => goal.FindPersonnelGoalsByMonthRange(userDept.DepartmentId, It.IsAny>(), It.IsAny())).ReturnsAsync(goals); var payout = await _payoutCalculateService.BuildDepartmentPayoutView(employee, userDept, new MonthRange(theTestDate)); Assert.NotNull(payout); Assert.NotNull(payout.CommissionPayouts); Assert.NotNull(payout.CommissionPayouts); Assert.IsNotEmpty(payout.CommissionPayouts); Assert.NotNull(payout.GoalPayouts); Assert.IsEmpty(payout.GoalPayouts); var newCheckingComm = payout.CommissionPayouts .FirstOrDefault(x => x.Product == Product.NewChecking); var mortgageComm = payout.CommissionPayouts .FirstOrDefault(x => x.Product == Product.Mortgage); Assert.AreEqual(10, mortgageComm.PayoutTotal); Assert.IsNull(newCheckingComm); } private AppUser GetBasicTestEmployee(Role role) { AppUser employee = new AppUser() { Departments = new List(), AdEmail = "testpayout@test.com", BaseRole = "BM", EmployeeId = "11771", FullName = "Jane Test", HomeDepartment = "Home", PersonId = 11234 }; return employee; } private UserDepartment GetBasicDepartmentAssignment(AppUser employee, DateTime theTestDate) { var department = new Department() { State = DepartmentState.Active, DepartmentName = "Test1", BusinessLineCode = BusinessLine.Operations.Code, Id = 99 }; var assignment1 = new UserDepartment() { DepartmentId = 99, Department = department, Employee = employee, Note = "Default!", IsHome = true, StartDate = new DateTime(theTestDate.Year, theTestDate.Month, 1), SlidingPayout = 100 }; return assignment1; } } }