Update staffing management to enhance payroll and hiring functionalities
- Increased the `MonthlyPayrollCap` from 10,000 to 40,000, allowing for greater flexibility in hiring and subject assignments. - Revised payroll calculation logic to ensure that staff members are compensated based on their actual weekly hours, with a minimum payment reflecting one full rate. - Updated documentation to clarify the new payroll structure and its implications for hiring and subject assignments. - Enhanced tests to validate the new payroll cap and ensure proper functionality in staffing scenarios, including the handling of uncovered subjects. - Improved localization strings to reflect changes in staffing and payroll terminology.
This commit is contained in:
@@ -211,6 +211,7 @@ internal sealed record StaffMemberResponse(
|
||||
string Position,
|
||||
string PositionLabel,
|
||||
float HourlyWageAsk,
|
||||
float WeeklyHours,
|
||||
float MonthlyPay,
|
||||
IReadOnlyList<DefLabelResponse> Subjects);
|
||||
|
||||
@@ -227,7 +228,7 @@ internal static class StaffingMapper
|
||||
roster ??= new Roster([], [], []);
|
||||
pool ??= ApplicantPool.Empty;
|
||||
var rules = catalog?.StaffingRules;
|
||||
var payroll = rules is null ? 0f : Staffing.Payroll(rules, roster.People);
|
||||
var payroll = rules is null || catalog is null ? 0f : Staffing.Payroll(catalog, rules, roster);
|
||||
var remaining = MathF.Round(MathF.Max(0f, allocated - payroll), 2);
|
||||
|
||||
var uncovered = catalog is null
|
||||
@@ -257,7 +258,7 @@ internal static class StaffingMapper
|
||||
.Where(person => person.IsStaff)
|
||||
.OrderBy(person => person.Name.Surname, StringComparer.Ordinal)
|
||||
.ThenBy(person => person.Id, StringComparer.Ordinal)
|
||||
.Select(person => Member(person, catalog, rules, locale, asOf))
|
||||
.Select(person => Member(person, roster, catalog, rules, locale, asOf))
|
||||
.ToArray();
|
||||
|
||||
var positions = catalog is null
|
||||
@@ -300,13 +301,15 @@ internal static class StaffingMapper
|
||||
|
||||
private static StaffMemberResponse Member(
|
||||
Person person,
|
||||
Roster roster,
|
||||
DefCatalog? catalog,
|
||||
StaffingDef? rules,
|
||||
string locale,
|
||||
DateTime asOf)
|
||||
{
|
||||
var ask = person.HourlyWageAsk ?? 0f;
|
||||
var pay = rules is null ? 0f : Staffing.MonthlyPay(rules, ask, person.Subjects.Count);
|
||||
var hours = catalog is null ? 0f : Staffing.WeeklyHours(catalog, roster, person);
|
||||
var pay = rules is null ? 0f : Staffing.MonthlyPay(rules, ask, hours);
|
||||
var subjects = person.Subjects
|
||||
.Select(name => new DefLabelResponse(
|
||||
name,
|
||||
@@ -324,6 +327,7 @@ internal static class StaffingMapper
|
||||
person.Position ?? string.Empty,
|
||||
PeopleListMapper.PositionLabel(catalog, locale, person.Position) ?? person.Position ?? string.Empty,
|
||||
ask,
|
||||
MathF.Round(hours, 1),
|
||||
pay,
|
||||
subjects);
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"Simulation": {
|
||||
"TickRate": 20,
|
||||
"MaxSchools": 6,
|
||||
"GameMinutesPerRealSecond": 5,
|
||||
"DefaultStartDate": "2012-03-31T06:00:00",
|
||||
"SavesDirectory": "saves",
|
||||
"ModsDirectory": "mods",
|
||||
"SaveIntervalSeconds": 30,
|
||||
"MonthlyPayrollCap": 10000,
|
||||
"SchoolWeekDays": 5
|
||||
}
|
||||
}
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"Simulation": {
|
||||
"TickRate": 20,
|
||||
"MaxSchools": 6,
|
||||
"GameMinutesPerRealSecond": 5,
|
||||
"DefaultStartDate": "2012-03-31T06:00:00",
|
||||
"SavesDirectory": "saves",
|
||||
"ModsDirectory": "mods",
|
||||
"SaveIntervalSeconds": 30,
|
||||
"MonthlyPayrollCap": 40000,
|
||||
"SchoolWeekDays": 5
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
"parentChance": 0.35,
|
||||
"hourlyWageBase": 30,
|
||||
"hourlyWagePerSkill": 0.6,
|
||||
// One ставка. A hired person costs this much even with no subjects, and hours beyond it are
|
||||
// paid on top — that is what makes loading one teacher instead of hiring two cost money.
|
||||
"baseWeeklyHours": 20,
|
||||
// Nobody can carry more than this. Past it the subject needs a second teacher.
|
||||
"maxWeeklyHours": 36,
|
||||
"weeksPerMonth": 4,
|
||||
"extraSubjectSurcharge": 0.25,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user