Merge branch 'develop'
This commit is contained in:
commit
f53d843e0d
@ -562,6 +562,23 @@ def _action_period(
|
||||
return period_start, period_end
|
||||
|
||||
|
||||
def _empty_personnel_metrics(skill_states) -> dict[str, object]:
|
||||
for state in skill_states.values():
|
||||
state.pop("_rolling_dates", None)
|
||||
state["recent_violation_dates"] = []
|
||||
return {
|
||||
"worked_days": 0,
|
||||
"current_reliability_streak": 0,
|
||||
"best_reliability_streak": 0,
|
||||
"current_resilience_streak": 0,
|
||||
"best_resilience_streak": 0,
|
||||
"leave_or_day_off_episodes": 0,
|
||||
"sick_leave_episodes": 0,
|
||||
"personnel_last_evaluated_date": "",
|
||||
"skill_states": skill_states,
|
||||
}
|
||||
|
||||
|
||||
def calculate_personnel_secret_metrics( # noqa: C901
|
||||
employee: Employee,
|
||||
actions: Iterable[EmployeeAction],
|
||||
@ -592,33 +609,13 @@ def calculate_personnel_secret_metrics( # noqa: C901
|
||||
}
|
||||
employment_period = _employment_period(employee, sorted_actions, reference_date)
|
||||
if employment_period is None:
|
||||
return {
|
||||
"worked_days": 0,
|
||||
"current_reliability_streak": 0,
|
||||
"best_reliability_streak": 0,
|
||||
"current_resilience_streak": 0,
|
||||
"best_resilience_streak": 0,
|
||||
"leave_or_day_off_episodes": 0,
|
||||
"sick_leave_episodes": 0,
|
||||
"personnel_last_evaluated_date": "",
|
||||
"skill_states": skill_states,
|
||||
}
|
||||
return _empty_personnel_metrics(skill_states)
|
||||
|
||||
start_date, end_date = employment_period
|
||||
if since is not None:
|
||||
start_date = max(start_date, since)
|
||||
if start_date > end_date:
|
||||
return {
|
||||
"worked_days": 0,
|
||||
"current_reliability_streak": 0,
|
||||
"best_reliability_streak": 0,
|
||||
"current_resilience_streak": 0,
|
||||
"best_resilience_streak": 0,
|
||||
"leave_or_day_off_episodes": 0,
|
||||
"sick_leave_episodes": 0,
|
||||
"personnel_last_evaluated_date": "",
|
||||
"skill_states": skill_states,
|
||||
}
|
||||
return _empty_personnel_metrics(skill_states)
|
||||
reliability_blocked_dates: set[date] = set()
|
||||
reliability_paused_dates: set[date] = set()
|
||||
resilience_blocked_dates: set[date] = set()
|
||||
|
||||
@ -376,6 +376,36 @@ def test_personnel_recalculation_counts_days_only_since_boundary(user_factory):
|
||||
assert progress.is_active is False
|
||||
|
||||
|
||||
def test_personnel_cutoff_after_dismissal_saves_json_state(user_factory):
|
||||
employee = user_factory()
|
||||
start = date(2025, 1, 1)
|
||||
_action(employee, ACTION_HIRED, start)
|
||||
_action(employee, ACTION_DISMISSED, start + timedelta(days=10))
|
||||
skill = Skill.objects.get(system_code="attendance_reliability")
|
||||
progress = EmployeeSkillProgress.objects.create(
|
||||
employee=employee,
|
||||
skill=skill,
|
||||
special_rank="bronze",
|
||||
is_active=True,
|
||||
)
|
||||
employee.skills.add(skill)
|
||||
|
||||
with patch(
|
||||
"employees.services.secret_skills.timezone.localdate",
|
||||
return_value=start + timedelta(days=100),
|
||||
):
|
||||
recalculate_attendance_secret_skills(
|
||||
employee.id,
|
||||
since=start + timedelta(days=50),
|
||||
)
|
||||
|
||||
progress.refresh_from_db()
|
||||
assert progress.special_rank == "none"
|
||||
assert progress.is_active is False
|
||||
assert progress.progress_data["recent_violation_dates"] == []
|
||||
assert "_rolling_dates" not in progress.progress_data
|
||||
|
||||
|
||||
def test_remote_reactivates_employment_without_resetting_active_period(user_factory):
|
||||
employee = user_factory()
|
||||
start = date(2025, 1, 1)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user