using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using LCU.API.Internal.Operations.IncentiveApiLib.Repositories; using LCU.API.Internal.Operations.IncentiveApi.Services.Payout; using LCU.Library.Internal.IncentiveApiModels.Entities; using LCU.Library.Internal.IncentiveApiModels.Enums; using Moq; using NUnit.Framework; using LCU.Library.Internal.IncentiveApiModels.Common; using LCU.API.Internal.Operations.IncentiveApi.Models.Payout; using LCU.API.Internal.Operations.IncentiveApi.Models; using LCU.API.Internal.Operations.IncentiveApi.Services.Rules; using LCU.API.Internal.Operations.IncentiveApi.Services; using LCU.Library.Internal.IncentiveApiModels.Requests; namespace Application.UnitTests.Services.Payout { public class PayoutServiceTest { private IPayoutService _payoutService; private Mock _mockActivityRepository; private Mock _mockGoalRepository; private Mock _mockCommissionRepository; private Mock _mockUserRepository; private Mock _mockPayoutRepository; private Mock _mockUnitOfWork; private IPayoutCalculateService _payoutCalculateService; private Mock _mockPayoutCalculateService; private Mock _mockBusinessRuleService; private Mock _mockAccountingRepository; private Mock _mockActivityService; private readonly List departmentRules = new List { new NewCheckingReferralRule(56) }; private readonly List personalRules = new List() { }; [SetUp] public void Setup() { _mockActivityRepository = new Mock(); _mockGoalRepository = new Mock(); _mockCommissionRepository = new Mock(); _mockUserRepository = new Mock(); _mockPayoutRepository = new Mock(); _mockUnitOfWork = new Mock(); _mockPayoutCalculateService = new Mock(); _mockActivityService = new Mock(); _mockBusinessRuleService = new Mock(); _mockAccountingRepository = new Mock(); _mockBusinessRuleService.Setup(x => x.GetRules(PayoutType.Department)).Returns(departmentRules); _mockBusinessRuleService.Setup(x => x.GetRules(PayoutType.Personal)).Returns(personalRules); IEnumerable payoutStrategies = new List() { new DefaultPayoutStrategy(), new GapPayoutStrategy() }; _payoutCalculateService = new PayoutCalculateService(_mockActivityRepository.Object, _mockGoalRepository.Object, _mockCommissionRepository.Object, payoutStrategies, _mockBusinessRuleService.Object); } /** * If a user has no departments, then they should get no payouts. */ [Test] public async Task PayoutPlans_No_Departments() { _payoutService = new PayoutService(_mockUserRepository.Object, _mockPayoutRepository.Object, _mockUnitOfWork.Object, _mockPayoutCalculateService.Object, _mockAccountingRepository.Object, _mockActivityService.Object); _mockPayoutCalculateService.Setup(x => x.BuildDepartmentPayoutView(It.IsAny(), It.IsAny(), It.IsAny())).Verifiable(); AppUser employee = GetBasicTestEmployee(Role.BM); var payout = await _payoutService.BuildUserDepartmentsPayoutView(employee, new MonthRange(DateTime.Today.Year, DateTime.Today.Month)); Assert.NotNull(payout); Assert.IsFalse(payout.Any()); _mockPayoutCalculateService.Verify(x => x.BuildDepartmentPayoutView(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); } [Test] public async Task PayoutPlans_NonEmpty() { _payoutService = new PayoutService(_mockUserRepository.Object, _mockPayoutRepository.Object, _mockUnitOfWork.Object, _mockPayoutCalculateService.Object, _mockAccountingRepository.Object, _mockActivityService.Object); var theTestDate = DateTime.Today; var range = new MonthRange(theTestDate); AppUser employee = GetBasicTestEmployee(Role.BM); var userDepartment = GetBasicDepartmentAssignment(employee, theTestDate,Role.BM); employee.Departments.Add(userDepartment); var deptPayoutView = new DepartmentPayout(employee, userDepartment, range, new List(), new List()); _mockPayoutCalculateService.Setup(x => x.BuildDepartmentPayoutView(employee, userDepartment, range)).ReturnsAsync(deptPayoutView); var payout = await _payoutService.BuildUserDepartmentsPayoutView(employee, range); Assert.NotNull(payout); Assert.IsNotEmpty(payout); Assert.AreEqual(1, payout.Count()); Assert.NotNull(payout.First().CommissionPayouts); Assert.IsEmpty(payout.First().CommissionPayouts); Assert.NotNull(payout.First().GoalPayouts); Assert.IsEmpty(payout.First().GoalPayouts); _mockPayoutCalculateService.Verify(x => x.BuildDepartmentPayoutView(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); } /** * Create a user with a department, activity, goals, no commissions and a role that * has a matching payout plan; should still see goal payout. */ [Test] public async Task PayoutPlan_No_Commissions() { _payoutService = new PayoutService(_mockUserRepository.Object, _mockPayoutRepository.Object, _mockUnitOfWork.Object, _payoutCalculateService, _mockAccountingRepository.Object, _mockActivityService.Object); var theTestDate = DateTime.Today; AppUser employee = GetBasicTestEmployee(Role.BM); var userDept = GetBasicDepartmentAssignment(employee, theTestDate, Role.BM); employee.Departments.Add(userDept); var activity = new List() { new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.Accepted, Detail = new ActivityDetail() { AccountBalance = 1000 } }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.Accepted, Detail = new ActivityDetail() { AccountBalance = 1000 } }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.Rejected, Detail = new ActivityDetail() { AccountBalance = 1000 } }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.Rejected, Detail = new ActivityDetail() { AccountBalance = 1000 } }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.ManualReview } }; var commissions = new List(); 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(employee.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 _payoutService.BuildUserDepartmentsPayoutView(employee, new MonthRange(theTestDate)); Assert.NotNull(payout); Assert.NotNull(payout.First().CommissionPayouts); Assert.NotNull(payout.First().CommissionPayouts); Assert.IsEmpty(payout.First().CommissionPayouts); Assert.NotNull(payout.First().GoalPayouts); Assert.IsNotEmpty(payout.First().GoalPayouts); var payoutRange = PayoutProfile.BMMortgage.Payouts.First().Value; Assert.AreEqual(payoutRange[0].Payout, payout.First().GoalPayouts.First().PayoutTotal); } /** * Create a user with a department, activity, no goals, commissions and a role that * has a matching payout plan; should still see commissions, but no goal payouts since there are no goals. */ [Test] public async Task PayoutPlan_No_Goals() { _payoutService = new PayoutService(_mockUserRepository.Object, _mockPayoutRepository.Object, _mockUnitOfWork.Object, _payoutCalculateService, _mockAccountingRepository.Object, _mockActivityService.Object); var theTestDate = DateTime.Today; AppUser employee = GetBasicTestEmployee(Role.BM); var userDept = GetBasicDepartmentAssignment(employee, theTestDate, Role.BM); employee.Departments.Add(userDept); var activity = new List() { new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.Rejected }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.PendingTransfer }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, DepartmentId = userDept.DepartmentId, State = ActivityState.ManualReview } }; 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 goals = 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(goals); _mockGoalRepository.Setup(goal => goal.FindDepartmentGoalsByMonthRange(userDept.DepartmentId, It.IsAny())) .ReturnsAsync(goals); var payout = await _payoutService.BuildUserDepartmentsPayoutView(employee, new MonthRange(theTestDate.Year, theTestDate.Month)); Assert.NotNull(payout); Assert.NotNull(payout.First().CommissionPayouts); Assert.NotNull(payout.First().CommissionPayouts); Assert.IsNotEmpty(payout.First().CommissionPayouts); Assert.NotNull(payout.First().GoalPayouts); Assert.IsEmpty(payout.First().GoalPayouts); var newCheckingComm = payout.First().CommissionPayouts .FirstOrDefault(x => x.Product == Product.NewChecking); var mortgageComm = payout.First().CommissionPayouts .FirstOrDefault(x => x.Product == Product.Mortgage); Assert.AreEqual(10, mortgageComm.PayoutTotal); Assert.AreEqual(25, newCheckingComm.PayoutTotal); } /** * Create a user with two departments, activity, no goals, commissions and a role that * has a matching payout plan; should see commissions for both departments. */ [Test] public async Task Commission_Only_User_Multi_Dept() { _payoutService = new PayoutService(_mockUserRepository.Object, _mockPayoutRepository.Object, _mockUnitOfWork.Object, _payoutCalculateService, _mockAccountingRepository.Object, _mockActivityService.Object); var theTestDate = DateTime.Today; AppUser employee = GetBasicTestEmployee(Role.Teller); var userDept1 = GetBasicDepartmentAssignment(employee, theTestDate, Role.Teller); var userDept2 = GetOtherDepartmentAssignment(651, employee, theTestDate); userDept2.Role = Role.Teller; employee.Departments.Add(userDept1); employee.Departments.Add(userDept2); var activity = new List() { new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.Vehicle, EmployeeId = employee.EmployeeId, DepartmentId = userDept2.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept2.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, DepartmentId = userDept2.DepartmentId, State = ActivityState.Accepted }, // Won't count. new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept2.DepartmentId, State = ActivityState.Rejected }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, DepartmentId = userDept2.DepartmentId, State = ActivityState.ManualReview } }; var commissions = new List() { new Commission() { Product = Product.Mortgage, RatePerProduct = 5, Role = userDept1.Role }, new Commission() { Product = Product.NewChecking, RatePerProduct = 25, Role = userDept1.Role }, new Commission() { Product = Product.Vehicle, RatePerProduct = 100, Role = userDept1.Role } }; var goals = new List(); _mockActivityRepository .Setup(activity => activity.FindEmployeeActivityByMonthRange(employee, It.IsAny())) .ReturnsAsync(activity); _mockActivityRepository .Setup(activity => activity.FindDepartmentActivityByMonthRange(userDept1.DepartmentId, It.IsAny())) .ReturnsAsync(activity.Where(x => x.DepartmentId == userDept1.DepartmentId).ToList()); _mockActivityRepository .Setup(activity => activity.FindDepartmentActivityByMonthRange(userDept2.DepartmentId, It.IsAny())) .ReturnsAsync(activity.Where(x => x.DepartmentId == userDept2.DepartmentId).ToList()); _mockCommissionRepository.Setup(commission => commission.FindProductCommissions(userDept1.Role)) .ReturnsAsync(commissions); _mockGoalRepository.Setup(goal => goal.FindPersonnelGoalsByMonthRange(It.IsAny(), It.IsAny>(), It.IsAny())).ReturnsAsync(goals); _mockGoalRepository.Setup(goal => goal.FindDepartmentGoalsByMonthRange(It.IsAny(), It.IsAny())) .ReturnsAsync(goals); var payout = await _payoutService.BuildUserDepartmentsPayoutView(employee, new MonthRange(theTestDate.Year, theTestDate.Month)); Assert.NotNull(payout); Assert.NotNull(payout.ElementAt(0).CommissionPayouts); Assert.NotNull(payout.ElementAt(0).CommissionPayouts); Assert.IsNotEmpty(payout.ElementAt(0).CommissionPayouts); Assert.NotNull(payout.ElementAt(1).CommissionPayouts); Assert.NotNull(payout.ElementAt(1).CommissionPayouts); Assert.IsNotEmpty(payout.ElementAt(1).CommissionPayouts); Assert.NotNull(payout.First().GoalPayouts); Assert.IsEmpty(payout.First().GoalPayouts); var userDept1Payouts = payout.FirstOrDefault(x => x.Department == userDept1); var userDept2Payouts = payout.FirstOrDefault(x => x.Department == userDept2); var dept1Mortgage = userDept1Payouts.CommissionPayouts.FirstOrDefault(x => x.Product == Product.Mortgage); Assert.AreEqual(10, dept1Mortgage.PayoutTotal); var dept1Checking = userDept1Payouts.CommissionPayouts.FirstOrDefault(x => x.Product == Product.NewChecking); Assert.AreEqual(25, dept1Checking.PayoutTotal); var dept2Mortgage = userDept2Payouts.CommissionPayouts.FirstOrDefault(x => x.Product == Product.Mortgage); Assert.AreEqual(5, dept2Mortgage.PayoutTotal); var dept2Checking = userDept2Payouts.CommissionPayouts.FirstOrDefault(x => x.Product == Product.NewChecking); Assert.AreEqual(25, dept2Checking.PayoutTotal); var dept2Vehicle = userDept2Payouts.CommissionPayouts.FirstOrDefault(x => x.Product == Product.Vehicle); Assert.AreEqual(100, dept2Vehicle.PayoutTotal); } /** * Create a user with two departments, activity, no goals, commissions and a role that * has a matching payout plan; should see commissions for both departments. * Have them be different roles! */ [Test] public async Task Commission_Only_User_Multi_Dept_MultiRole() { _payoutService = new PayoutService(_mockUserRepository.Object, _mockPayoutRepository.Object, _mockUnitOfWork.Object, _payoutCalculateService, _mockAccountingRepository.Object, _mockActivityService.Object); var theTestDate = DateTime.Today; AppUser employee = GetBasicTestEmployee(Role.Teller); var userDept1 = GetBasicDepartmentAssignment(employee, theTestDate, Role.Teller); var userDept2 = GetOtherDepartmentAssignment(651, employee, theTestDate); userDept2.Role = Role.ABM; employee.Departments.Add(userDept1); employee.Departments.Add(userDept2); var activity = new List() { new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.Vehicle, EmployeeId = employee.EmployeeId, DepartmentId = userDept2.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept2.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, DepartmentId = userDept2.DepartmentId, State = ActivityState.Accepted } }; var commissions = new List() { new Commission() { Product = Product.Mortgage, RatePerProduct = 5, Role = userDept1.Role }, new Commission() { Product = Product.Mortgage, RatePerProduct = 5, Role = userDept2.Role }, new Commission() { Product = Product.NewChecking, RatePerProduct = 25, Role = userDept1.Role }, new Commission() { Product = Product.NewChecking, RatePerProduct = 25, Role = userDept2.Role }, new Commission() { Product = Product.Vehicle, RatePerProduct = 100, Role = userDept2.Role } }; var goals = new List(); _mockActivityRepository .Setup(activity => activity.FindEmployeeActivityByMonthRange(employee, It.IsAny())) .ReturnsAsync(activity); _mockActivityRepository .Setup(activity => activity.FindDepartmentActivityByMonthRange(userDept1.DepartmentId, It.IsAny())) .ReturnsAsync(activity.Where(x => x.DepartmentId == userDept1.DepartmentId).ToList()); _mockActivityRepository .Setup(activity => activity.FindDepartmentActivityByMonthRange(userDept2.DepartmentId, It.IsAny())) .ReturnsAsync(activity.Where(x => x.DepartmentId == userDept2.DepartmentId).ToList()); _mockCommissionRepository.Setup(commission => commission.FindProductCommissions(userDept1.Role)) .ReturnsAsync(commissions.Where(x => x.Role == userDept1.Role).ToList()); _mockCommissionRepository.Setup(commission => commission.FindProductCommissions(userDept2.Role)) .ReturnsAsync(commissions.Where(x => x.Role == userDept2.Role).ToList()); _mockGoalRepository.Setup(goal => goal.FindPersonnelGoalsByMonthRange(It.IsAny(), It.IsAny>(), It.IsAny())).ReturnsAsync(goals); _mockGoalRepository.Setup(goal => goal.FindDepartmentGoalsByMonthRange(It.IsAny(), It.IsAny())) .ReturnsAsync(goals); var payout = await _payoutService.BuildUserDepartmentsPayoutView(employee, new MonthRange(theTestDate.Year, theTestDate.Month)); Assert.NotNull(payout); Assert.NotNull(payout.ElementAt(0).CommissionPayouts); Assert.NotNull(payout.ElementAt(0).CommissionPayouts); Assert.IsNotEmpty(payout.ElementAt(0).CommissionPayouts); Assert.NotNull(payout.ElementAt(1).CommissionPayouts); Assert.NotNull(payout.ElementAt(1).CommissionPayouts); Assert.IsNotEmpty(payout.ElementAt(1).CommissionPayouts); Assert.NotNull(payout.First().GoalPayouts); Assert.IsEmpty(payout.First().GoalPayouts); var userDept1Payouts = payout.FirstOrDefault(x => x.Department == userDept1); var userDept2Payouts = payout.FirstOrDefault(x => x.Department == userDept2); var dept1Mortgage = userDept1Payouts.CommissionPayouts.FirstOrDefault(x => x.Product == Product.Mortgage); Assert.AreEqual(10, dept1Mortgage.PayoutTotal); var dept1Checking = userDept1Payouts.CommissionPayouts.FirstOrDefault(x => x.Product == Product.NewChecking); Assert.AreEqual(25, dept1Checking.PayoutTotal); var dept2Mortgage = userDept2Payouts.CommissionPayouts.FirstOrDefault(x => x.Product == Product.Mortgage); Assert.AreEqual(5, dept2Mortgage.PayoutTotal); var dept2Checking = userDept2Payouts.CommissionPayouts.FirstOrDefault(x => x.Product == Product.NewChecking); Assert.AreEqual(25, dept2Checking.PayoutTotal); var dept2Vehicle = userDept2Payouts.CommissionPayouts.FirstOrDefault(x => x.Product == Product.Vehicle); Assert.AreEqual(100, dept2Vehicle.PayoutTotal); } /** * MSC Team lead is a great test scenario. They get paid for both personal and department goals, which this * test demonstrates. */ [Test] public async Task Only_PayoutPlan_Personal_And_Department() { _payoutService = new PayoutService(_mockUserRepository.Object, _mockPayoutRepository.Object, _mockUnitOfWork.Object, _payoutCalculateService, _mockAccountingRepository.Object, _mockActivityService.Object); var theTestDate = DateTime.Today; AppUser employee = GetBasicTestEmployee(Role.MSCTeamLead); var userDept1 = GetBasicDepartmentAssignment(employee, theTestDate, Role.MSCTeamLead); employee.Departments.Add(userDept1); var activity = new List() { // Not this person, but dept 1 mortgage new Activity() { Product = Product.Mortgage, EmployeeId = "9898", DepartmentId = userDept1.DepartmentId, State = ActivityState.Accepted, Detail = new ActivityDetail() { AccountBalance = 1000 } }, new Activity() { Product = Product.Mortgage, EmployeeId = "9898", DepartmentId = userDept1.DepartmentId, State = ActivityState.Rejected, Detail = new ActivityDetail() { AccountBalance = 1000 } }, new Activity() { // Not this person, but dept 1 mortgage Product = Product.Mortgage, EmployeeId = "9897", DepartmentId = userDept1.DepartmentId, State = ActivityState.Accepted, Detail = new ActivityDetail() { AccountBalance = 1000 } }, new Activity() { // Not this person, but dept 1 checking Product = Product.NewChecking, EmployeeId = "9896", DepartmentId = userDept1.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId, State = ActivityState.Accepted, Detail = new ActivityDetail() { AccountBalance = 1000 } }, new Activity() { Product = Product.Mortgage, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId, State = ActivityState.Accepted, Detail = new ActivityDetail() { AccountBalance = 1000 } }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId, State = ActivityState.Accepted }, new Activity() { Product = Product.NewChecking, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId, State = ActivityState.ManualReview } }; var commissions = new List(); var personalGoals = new List() { new Goal() { Product = Product.Mortgage, Value = 2000, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId }, // Employee will miss this goal new Goal() { Product = Product.NewChecking, Value = 2, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId } }; var departmentGoals = new List() { new Goal() { Product = Product.Mortgage, Value = 4000, DepartmentId = userDept1.DepartmentId }, new Goal() { Product = Product.NewChecking, Value = 2, DepartmentId = userDept1.DepartmentId } }; _mockActivityRepository .Setup(activity => activity.FindEmployeeActivityByMonthRange(employee, It.IsAny())) .ReturnsAsync(activity.Where(x => x.EmployeeId == employee.EmployeeId).ToList()); _mockActivityRepository .Setup(activity => activity.FindDepartmentActivityByMonthRange(userDept1.DepartmentId, It.IsAny())) .ReturnsAsync(activity); _mockCommissionRepository.Setup(commission => commission.FindProductCommissions(userDept1.Role)) .ReturnsAsync(commissions); _mockGoalRepository.Setup(goal => goal.FindPersonnelGoalsByMonthRange(userDept1.DepartmentId, It.IsAny>(), It.IsAny())).ReturnsAsync(personalGoals); _mockGoalRepository.Setup(goal => goal.FindDepartmentGoalsByMonthRange(userDept1.DepartmentId, It.IsAny())) .ReturnsAsync(departmentGoals); var payouts = await _payoutService.BuildUserDepartmentsPayoutView(employee, new MonthRange(theTestDate.Year, theTestDate.Month)); Assert.NotNull(payouts); Assert.IsNotEmpty(payouts); var payout1 = payouts.First(); Assert.NotNull(payout1.CommissionPayouts); Assert.IsEmpty(payout1.CommissionPayouts); Assert.NotNull(payout1.GoalPayouts); Assert.IsNotEmpty(payout1.GoalPayouts); Assert.AreEqual(3, payout1.GoalPayouts.Count()); // employee should have 2 department level, and a personal level payout. var dept1Mortgage = payout1.GoalPayouts.FirstOrDefault(x => x.Product == Product.Mortgage && PayoutProfile.FindById(x.PayoutProfileId).Type == PayoutType.Department); Assert.AreEqual(50, dept1Mortgage.PayoutTotal); var dept1Checking = payout1.GoalPayouts.FirstOrDefault(x => x.Product == Product.NewChecking && PayoutProfile.FindById(x.PayoutProfileId).Type == PayoutType.Department); Assert.AreEqual(50, dept1Checking.PayoutTotal); var persMortgage = payout1.GoalPayouts.FirstOrDefault(x => x.Product == Product.Mortgage && PayoutProfile.FindById(x.PayoutProfileId).Type == PayoutType.Personal); Assert.AreEqual(100, persMortgage.PayoutTotal); } [Test] public async Task Payout_Terminated_Basic() { _payoutService = new PayoutService(_mockUserRepository.Object, _mockPayoutRepository.Object, _mockUnitOfWork.Object, _mockPayoutCalculateService.Object, _mockAccountingRepository.Object, _mockActivityService.Object); var theTestDate = DateTime.Today; var range = new MonthRange(theTestDate); var manager = GetBasicTestEmployee(Role.Manager); var employee = GetBasicTestEmployee(Role.Teller); var userDept1 = GetBasicDepartmentAssignment(employee, theTestDate, Role.Teller); employee.Departments.Add(userDept1); // We need the user to have been in the department last month.... userDept1.StartDate= userDept1.StartDate.AddMonths(-1); _mockPayoutRepository .Setup(activity => activity.GetEmployeePayoutsForPeriod(employee, It.IsAny())) .ReturnsAsync(new List()); var deptPayout = new DepartmentPayout(employee, userDept1, range, new List(), new List()) { CommissionPayouts = new List() { new PayoutLineItem() { Product = Product.Mortgage, ActivityTotal = 500, CommissionId = 19, CommissionValue = 10, PayoutTotal = 5000 } } }; _mockPayoutCalculateService .Setup(x => x.BuildDepartmentPayoutView(employee, userDept1, It.IsAny())) .ReturnsAsync(deptPayout); _mockPayoutRepository .Setup(activity => activity.SavePayoutLineItemRangeAsync(It.IsAny>())) .Verifiable(); _mockUnitOfWork.Setup(x => x.CompleteAsync()).Verifiable(); var receipt = await _payoutService.CreateTerminatedEmployeePayouts(employee, manager); Assert.NotNull(receipt); Assert.NotNull(receipt.LastMonthPayout); Assert.NotNull(receipt.ThisMonthPayout); _mockPayoutRepository .Verify(activity => activity.GetEmployeePayoutsForPeriod(employee, It.IsAny()), Times.Exactly(4)); _mockPayoutCalculateService .Verify(x => x.BuildDepartmentPayoutView(employee, userDept1, It.IsAny()), Times.Exactly(2)); _mockPayoutRepository .Verify(activity => activity.SavePayoutLineItemRangeAsync(It.IsAny>()), Times.Exactly(2)); _mockUnitOfWork.Verify(x => x.CompleteAsync(), Times.Exactly(1)); } [Test] public async Task RetrieveMonthlyIncentivePayouts_Basic() { _payoutService = new PayoutService(_mockUserRepository.Object, _mockPayoutRepository.Object, _mockUnitOfWork.Object, _mockPayoutCalculateService.Object, _mockAccountingRepository.Object, _mockActivityService.Object); var theTestDate = DateTime.Today; var employee = GetBasicTestEmployee(Role.Teller); var userDept1 = GetBasicDepartmentAssignment(employee, theTestDate, Role.Teller); employee.Departments.Add(userDept1); _mockPayoutRepository .Setup(activity => activity.GetPayoutLineItemsForPeriodAsync( It.IsAny())) .ReturnsAsync(new List() { new PayoutLineItem() { Product = Product.Mortgage, Role = Role.Teller, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId, PayoutTotal = 50 }, new PayoutLineItem() { Product = Product.Vehicle, Role = Role.Teller, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId, PayoutTotal = 60 } }); _mockUserRepository.Setup(x => x.FindUserByEmployeeIdAsync(It.IsAny())).ReturnsAsync(employee); var results = await _payoutService.RetrieveMonthlyIncentivePayouts(theTestDate); Assert.NotNull(results); Assert.IsNotEmpty(results); _mockPayoutRepository .Verify(activity => activity.GetPayoutLineItemsForPeriodAsync(It.IsAny()), Times.Once); _mockUserRepository.Verify(x => x.FindUserByEmployeeIdAsync(It.IsAny()), Times.Once); } [Test] public async Task CreateMonthlyIncentivePayouts_Basic() { _payoutService = new PayoutService(_mockUserRepository.Object, _mockPayoutRepository.Object, _mockUnitOfWork.Object, _mockPayoutCalculateService.Object, _mockAccountingRepository.Object, _mockActivityService.Object); var theTestDate = DateTime.Today; var range = new MonthRange(theTestDate); var employee = GetBasicTestEmployee(Role.Teller); var userDept1 = GetBasicDepartmentAssignment(employee, theTestDate, Role.Teller); employee.Departments.Add(userDept1); var employees = new List() { employee }; _mockPayoutRepository .Setup(activity => activity.GetPayoutLineItemsForPeriodAsync(It.IsAny())) .ReturnsAsync(new List() { new PayoutLineItem() { Product = Product.Mortgage, Role = Role.Teller, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId, PayoutTotal = 50 }, new PayoutLineItem() { Product = Product.Vehicle, Role = Role.Teller, EmployeeId = employee.EmployeeId, DepartmentId = userDept1.DepartmentId, PayoutTotal = 60 } }); _mockUserRepository.Setup(x => x.FindUserByEmployeeIdAsync(It.IsAny())).ReturnsAsync(employee); _mockUnitOfWork.Setup(x => x.CompleteAsync()).Verifiable(); _mockUserRepository.Setup(x => x.GetAllUsersToPayoutAsync(It.IsAny())).ReturnsAsync(employees); _mockUnitOfWork.Setup(x => x.CompleteAsync()).Verifiable(); _mockPayoutRepository .Setup(activity => activity.GetEmployeePayoutsForPeriod(employee, It.IsAny())) .ReturnsAsync(new List()); var deptPayout = new DepartmentPayout(employee, userDept1, range, new List(), new List()) { CommissionPayouts = new List() { new PayoutLineItem() { Product = Product.Mortgage, ActivityTotal = 500, CommissionId = 19, CommissionValue = 10, PayoutTotal = 5000 } } }; _mockPayoutCalculateService .Setup(x => x.BuildDepartmentPayoutView(employee, userDept1, It.IsAny())) .ReturnsAsync(deptPayout); _mockPayoutRepository .Setup(activity => activity.SavePayoutLineItemRangeAsync(It.IsAny>())) .Verifiable(); var request = new PayoutIncentiveRequest() { MonthsBack = -2, }; var results = await _payoutService.CreateMonthlyIncentivePayouts(request); Assert.NotNull(results); _mockUserRepository.Verify(x => x.GetAllUsersToPayoutAsync(It.IsAny()), Times.Once); _mockUnitOfWork.Verify(x => x.CompleteAsync(), Times.Once); } 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, Role role) { 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), Role = role, SlidingPayout = 100 }; return assignment1; } private UserDepartment GetOtherDepartmentAssignment(int DepartmentId, AppUser employee, DateTime theTestDate) { var department = new Department() { State = DepartmentState.Active, DepartmentName = "Test1", BusinessLineCode = BusinessLine.Operations.Code, Id = DepartmentId }; var assignment1 = new UserDepartment() { DepartmentId = DepartmentId, Department = department, Employee = employee, Note = "Custom", IsHome = false, StartDate = new DateTime(theTestDate.Year, theTestDate.Month, 1), SlidingPayout = 100 }; return assignment1; } } }