Files
2026-03-17 09:53:09 -05:00

1106 lines
48 KiB
C#

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<IActivityRepository> _mockActivityRepository;
private Mock<IGoalRepository> _mockGoalRepository;
private Mock<ICommissionRepository> _mockCommissionRepository;
private Mock<IUserRepository> _mockUserRepository;
private Mock<IPayoutRepository> _mockPayoutRepository;
private Mock<IUnitOfWork> _mockUnitOfWork;
private IPayoutCalculateService _payoutCalculateService;
private Mock<IPayoutCalculateService> _mockPayoutCalculateService;
private Mock<IBusinessRuleService> _mockBusinessRuleService;
private Mock<IAccountingRepository> _mockAccountingRepository;
private Mock<IActivityService> _mockActivityService;
private readonly List<IPayoutRule> departmentRules = new List<IPayoutRule>
{
new NewCheckingReferralRule(56)
};
private readonly List<IPayoutRule> personalRules = new List<IPayoutRule>()
{
};
[SetUp]
public void Setup()
{
_mockActivityRepository = new Mock<IActivityRepository>();
_mockGoalRepository = new Mock<IGoalRepository>();
_mockCommissionRepository = new Mock<ICommissionRepository>();
_mockUserRepository = new Mock<IUserRepository>();
_mockPayoutRepository = new Mock<IPayoutRepository>();
_mockUnitOfWork = new Mock<IUnitOfWork>();
_mockPayoutCalculateService = new Mock<IPayoutCalculateService>();
_mockActivityService = new Mock<IActivityService>();
_mockBusinessRuleService = new Mock<IBusinessRuleService>();
_mockAccountingRepository = new Mock<IAccountingRepository>();
_mockBusinessRuleService.Setup(x => x.GetRules(PayoutType.Department)).Returns(departmentRules);
_mockBusinessRuleService.Setup(x => x.GetRules(PayoutType.Personal)).Returns(personalRules);
IEnumerable<IPayoutStrategy> payoutStrategies = new List<IPayoutStrategy>()
{
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<AppUser>(),
It.IsAny<UserDepartment>(),
It.IsAny<MonthRange>())).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<AppUser>(),
It.IsAny<UserDepartment>(),
It.IsAny<MonthRange>()), 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<IPayoutRule>(), new List<IPayoutRule>());
_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<AppUser>(),
It.IsAny<UserDepartment>(),
It.IsAny<MonthRange>()), 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<Activity>()
{
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<Commission>();
var personalGoals = new List<Goal>()
{
new Goal()
{
Product = Product.Mortgage,
Value = 2000,
EmployeeId = employee.EmployeeId,
DepartmentId = userDept.DepartmentId
}
};
var departmentGoals = new List<Goal>()
{
new Goal()
{
Product = Product.Mortgage,
Value = 2000,
DepartmentId = userDept.DepartmentId
}
};
_mockActivityRepository
.Setup(activity => activity.FindEmployeeActivityByMonthRange(employee, It.IsAny<MonthRange>()))
.ReturnsAsync(activity);
_mockActivityRepository
.Setup(activity =>
activity.FindDepartmentActivityByMonthRange(userDept.DepartmentId, It.IsAny<MonthRange>()))
.ReturnsAsync(activity);
_mockCommissionRepository.Setup(commission => commission.FindProductCommissions(employee.Role))
.ReturnsAsync(commissions);
_mockGoalRepository.Setup(goal =>
goal.FindPersonnelGoalsByMonthRange(userDept.DepartmentId, It.IsAny<List<AppUser>>(),
It.IsAny<MonthRange>())).ReturnsAsync(personalGoals);
_mockGoalRepository.Setup(goal =>
goal.FindDepartmentGoalsByMonthRange(userDept.DepartmentId, It.IsAny<MonthRange>()))
.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<Activity>()
{
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<Commission>()
{
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<Goal>();
_mockActivityRepository
.Setup(activity => activity.FindEmployeeActivityByMonthRange(employee, It.IsAny<MonthRange>()))
.ReturnsAsync(activity);
_mockActivityRepository
.Setup(activity =>
activity.FindDepartmentActivityByMonthRange(userDept.DepartmentId, It.IsAny<MonthRange>()))
.ReturnsAsync(activity);
_mockCommissionRepository.Setup(commission => commission.FindProductCommissions(userDept.Role))
.ReturnsAsync(commissions);
_mockGoalRepository.Setup(goal =>
goal.FindPersonnelGoalsByMonthRange(userDept.DepartmentId, It.IsAny<List<AppUser>>(),
It.IsAny<MonthRange>())).ReturnsAsync(goals);
_mockGoalRepository.Setup(goal =>
goal.FindDepartmentGoalsByMonthRange(userDept.DepartmentId, It.IsAny<MonthRange>()))
.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<Activity>()
{
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<Commission>()
{
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<Goal>();
_mockActivityRepository
.Setup(activity => activity.FindEmployeeActivityByMonthRange(employee, It.IsAny<MonthRange>()))
.ReturnsAsync(activity);
_mockActivityRepository
.Setup(activity =>
activity.FindDepartmentActivityByMonthRange(userDept1.DepartmentId, It.IsAny<MonthRange>()))
.ReturnsAsync(activity.Where(x => x.DepartmentId == userDept1.DepartmentId).ToList());
_mockActivityRepository
.Setup(activity =>
activity.FindDepartmentActivityByMonthRange(userDept2.DepartmentId, It.IsAny<MonthRange>()))
.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<int>(), It.IsAny<List<AppUser>>(),
It.IsAny<MonthRange>())).ReturnsAsync(goals);
_mockGoalRepository.Setup(goal =>
goal.FindDepartmentGoalsByMonthRange(It.IsAny<int>(), It.IsAny<MonthRange>()))
.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<Activity>()
{
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<Commission>()
{
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<Goal>();
_mockActivityRepository
.Setup(activity => activity.FindEmployeeActivityByMonthRange(employee, It.IsAny<MonthRange>()))
.ReturnsAsync(activity);
_mockActivityRepository
.Setup(activity =>
activity.FindDepartmentActivityByMonthRange(userDept1.DepartmentId, It.IsAny<MonthRange>()))
.ReturnsAsync(activity.Where(x => x.DepartmentId == userDept1.DepartmentId).ToList());
_mockActivityRepository
.Setup(activity =>
activity.FindDepartmentActivityByMonthRange(userDept2.DepartmentId, It.IsAny<MonthRange>()))
.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<int>(), It.IsAny<List<AppUser>>(),
It.IsAny<MonthRange>())).ReturnsAsync(goals);
_mockGoalRepository.Setup(goal =>
goal.FindDepartmentGoalsByMonthRange(It.IsAny<int>(), It.IsAny<MonthRange>()))
.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<Activity>()
{
// 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<Commission>();
var personalGoals = new List<Goal>()
{
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<Goal>()
{
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<MonthRange>()))
.ReturnsAsync(activity.Where(x => x.EmployeeId == employee.EmployeeId).ToList());
_mockActivityRepository
.Setup(activity =>
activity.FindDepartmentActivityByMonthRange(userDept1.DepartmentId, It.IsAny<MonthRange>()))
.ReturnsAsync(activity);
_mockCommissionRepository.Setup(commission => commission.FindProductCommissions(userDept1.Role))
.ReturnsAsync(commissions);
_mockGoalRepository.Setup(goal =>
goal.FindPersonnelGoalsByMonthRange(userDept1.DepartmentId, It.IsAny<List<AppUser>>(),
It.IsAny<MonthRange>())).ReturnsAsync(personalGoals);
_mockGoalRepository.Setup(goal =>
goal.FindDepartmentGoalsByMonthRange(userDept1.DepartmentId, It.IsAny<MonthRange>()))
.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<DateTime>()))
.ReturnsAsync(new List<PayoutLineItem>());
var deptPayout = new DepartmentPayout(employee, userDept1, range, new List<IPayoutRule>(), new List<IPayoutRule>())
{
CommissionPayouts = new List<PayoutLineItem>()
{
new PayoutLineItem()
{
Product = Product.Mortgage,
ActivityTotal = 500,
CommissionId = 19,
CommissionValue = 10,
PayoutTotal = 5000
}
}
};
_mockPayoutCalculateService
.Setup(x => x.BuildDepartmentPayoutView(employee, userDept1, It.IsAny<MonthRange>()))
.ReturnsAsync(deptPayout);
_mockPayoutRepository
.Setup(activity => activity.SavePayoutLineItemRangeAsync(It.IsAny<List<PayoutLineItem>>()))
.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<DateTime>()),
Times.Exactly(4));
_mockPayoutCalculateService
.Verify(x => x.BuildDepartmentPayoutView(employee, userDept1, It.IsAny<MonthRange>()),
Times.Exactly(2));
_mockPayoutRepository
.Verify(activity => activity.SavePayoutLineItemRangeAsync(It.IsAny<List<PayoutLineItem>>()),
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<DateTime>()))
.ReturnsAsync(new List<PayoutLineItem>()
{
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<string>())).ReturnsAsync(employee);
var results = await _payoutService.RetrieveMonthlyIncentivePayouts(theTestDate);
Assert.NotNull(results);
Assert.IsNotEmpty(results);
_mockPayoutRepository
.Verify(activity => activity.GetPayoutLineItemsForPeriodAsync(It.IsAny<DateTime>()), Times.Once);
_mockUserRepository.Verify(x => x.FindUserByEmployeeIdAsync(It.IsAny<string>()), 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<AppUser>()
{
employee
};
_mockPayoutRepository
.Setup(activity => activity.GetPayoutLineItemsForPeriodAsync(It.IsAny<DateTime>()))
.ReturnsAsync(new List<PayoutLineItem>()
{
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<string>())).ReturnsAsync(employee);
_mockUnitOfWork.Setup(x => x.CompleteAsync()).Verifiable();
_mockUserRepository.Setup(x => x.GetAllUsersToPayoutAsync(It.IsAny<MonthRange>())).ReturnsAsync(employees);
_mockUnitOfWork.Setup(x => x.CompleteAsync()).Verifiable();
_mockPayoutRepository
.Setup(activity => activity.GetEmployeePayoutsForPeriod(employee, It.IsAny<DateTime>()))
.ReturnsAsync(new List<PayoutLineItem>());
var deptPayout = new DepartmentPayout(employee, userDept1, range, new List<IPayoutRule>(), new List<IPayoutRule>())
{
CommissionPayouts = new List<PayoutLineItem>()
{
new PayoutLineItem()
{
Product = Product.Mortgage,
ActivityTotal = 500,
CommissionId = 19,
CommissionValue = 10,
PayoutTotal = 5000
}
}
};
_mockPayoutCalculateService
.Setup(x => x.BuildDepartmentPayoutView(employee, userDept1, It.IsAny<MonthRange>()))
.ReturnsAsync(deptPayout);
_mockPayoutRepository
.Setup(activity => activity.SavePayoutLineItemRangeAsync(It.IsAny<List<PayoutLineItem>>()))
.Verifiable();
var request = new PayoutIncentiveRequest()
{
MonthsBack = -2,
};
var results = await _payoutService.CreateMonthlyIncentivePayouts(request);
Assert.NotNull(results);
_mockUserRepository.Verify(x => x.GetAllUsersToPayoutAsync(It.IsAny<MonthRange>()), Times.Once);
_mockUnitOfWork.Verify(x => x.CompleteAsync(), Times.Once);
}
private AppUser GetBasicTestEmployee(Role role)
{
AppUser employee = new AppUser()
{
Departments = new List<UserDepartment>(),
AdEmail = "[email protected]",
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;
}
}
}