Files
monorepo/LCU.API.Operations.IncentiveAPI/LCU.API.Internal.Operations.IncentiveApi.UnitTests/Services/Payout/PayoutCalculateServiceTest.cs
T
2026-03-17 09:53:09 -05:00

1441 lines
63 KiB
C#

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<IActivityRepository> _mockActivityRepository;
private Mock<IGoalRepository> _mockGoalRepository;
private Mock<ICommissionRepository> _mockCommissionRepository;
private Mock<IBusinessRuleService> _mockBusinessRuleService;
private readonly List<IPayoutRule> _departmentRules = new List<IPayoutRule>
{
new NewCheckingReferralRule(56) // this simulates looking up 200.
};
private readonly List<IPayoutRule> _personalRules = new List<IPayoutRule>();
private readonly DateTime _nonOverriddenDateTime = DateTime.ParseExact("2021-12-01", "yyyy-MM-dd", CultureInfo.InvariantCulture);
[SetUp]
public void Setup()
{
_mockActivityRepository = new Mock<IActivityRepository>();
_mockGoalRepository = new Mock<IGoalRepository>();
_mockCommissionRepository = new Mock<ICommissionRepository>();
_mockBusinessRuleService = new Mock<IBusinessRuleService>();
IEnumerable<IPayoutStrategy> payoutStrategies = new List<IPayoutStrategy>()
{
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<MonthRange>()))
.ReturnsAsync(new List<Activity>());
_mockActivityRepository
.Setup(activity =>
activity.FindDepartmentActivityByMonthRange(userDepartment.DepartmentId, It.IsAny<MonthRange>()))
.ReturnsAsync(new List<Activity>());
_mockCommissionRepository.Setup(commission => commission.FindProductCommissions(employee.Role))
.ReturnsAsync(new List<Commission>());
_mockGoalRepository.Setup(goal =>
goal.FindPersonnelGoalsByMonthRange(userDepartment.DepartmentId, It.IsAny<List<AppUser>>(),
It.IsAny<MonthRange>())).ReturnsAsync(new List<Goal>());
_mockGoalRepository.Setup(goal =>
goal.FindDepartmentGoalsByMonthRange(userDepartment.DepartmentId, It.IsAny<MonthRange>()))
.ReturnsAsync(new List<Goal>());
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<Activity>()
{
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<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 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(userDept.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 _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<Activity>()
{
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<Commission>()
{
new Commission()
{
Product = Product.NewChecking,
RatePerProduct = 25,
Role = userDept.Role
}
};
var personalGoals = new List<Goal>()
{
new Goal()
{
Product = Product.NewChecking,
Value = 2,
EmployeeId = employee.EmployeeId,
DepartmentId = userDept.DepartmentId
}
};
var departmentGoals = new List<Goal>()
{
new Goal()
{
Product = Product.NewChecking,
Value = 1,
DepartmentId = userDept.DepartmentId
}
};
var departmentRules = new List<IPayoutRule>()
{
new NewCheckingReferralRule(56) // this simulates looking up 200.
};
var personalRules = new List<IPayoutRule>();
_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(personalGoals);
_mockGoalRepository.Setup(goal =>
goal.FindDepartmentGoalsByMonthRange(userDept.DepartmentId, It.IsAny<MonthRange>()))
.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<Activity>()
{
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<Commission>()
{
new Commission
{
Id = 1,
Role = userDept.Role,
RatePerProduct = 20,
Product = Product.GAPInsurance
}
};
var personalGoals = new List<Goal>();
var departmentGoals = 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(personalGoals);
_mockGoalRepository.Setup(goal =>
goal.FindDepartmentGoalsByMonthRange(userDept.DepartmentId, It.IsAny<MonthRange>()))
.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<Activity>()
{
// 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<Commission>()
{
new Commission
{
Id = 1,
Role = userDept.Role,
RatePerProduct = 20,
Product = Product.GAPInsurance
}
};
var personalGoals = new List<Goal>();
var departmentGoals = 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(personalGoals);
_mockGoalRepository.Setup(goal =>
goal.FindDepartmentGoalsByMonthRange(userDept.DepartmentId, It.IsAny<MonthRange>()))
.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<Activity>()
{
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<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 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(userDept.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 _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<Activity>()
{
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<Commission>()
{
new Commission()
{
Product = Product.Mortgage,
RatePerProduct = 5,
Role = userDept.Role
}
};
var goals = new List<Goal>()
{
new Goal()
{
Product = Product.Mortgage,
Value = 2,
EmployeeId = employee.EmployeeId,
DepartmentId = userDept.DepartmentId
}
};
_mockActivityRepository
.Setup(activity => activity.FindEmployeeActivityByMonthRange(employee, 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);
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<UserDepartment>(),
AdEmail = "[email protected]",
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;
}
}
}