Implement date range handling for vacation and unavailable events

- Added helper functions to generate ISO 8601 formatted start and end times for calendar days.
- Introduced logic to merge consecutive vacation dates into a single record for improved data representation.
- Updated the duty schedule import process to utilize the new date handling functions for unavailable and vacation events.
- Enhanced integration tests to validate the correct handling of vacation periods and unavailable dates.
- Modified the web application to display formatted date ranges for vacation and unavailable events.
This commit is contained in:
2026-02-17 23:06:23 +03:00
parent 7a963eccd1
commit 3f4c7bf66c
3 changed files with 101 additions and 16 deletions

View File

@@ -140,16 +140,16 @@ def test_import_full_flow_parse_then_import(db_url):
def test_import_event_types_unavailable_vacation(db_url):
"""Import creates records with event_type duty, unavailable, vacation."""
"""Import creates duty, unavailable (full day), vacation (periods). Unavailable: same-day 00:0023:59. Three consecutive vacation days → one record."""
result = DutyScheduleResult(
start_date=date(2026, 2, 16),
end_date=date(2026, 2, 18),
end_date=date(2026, 2, 20),
entries=[
DutyScheduleEntry(
full_name="Mixed User",
duty_dates=[date(2026, 2, 16)],
unavailable_dates=[date(2026, 2, 17)],
vacation_dates=[date(2026, 2, 18)],
vacation_dates=[date(2026, 2, 18), date(2026, 2, 19), date(2026, 2, 20)],
),
],
)
@@ -159,9 +159,48 @@ def test_import_event_types_unavailable_vacation(db_url):
session = get_session(db_url)
try:
duties = get_duties(session, "2026-02-16", "2026-02-19")
duties = get_duties(session, "2026-02-16", "2026-02-21")
finally:
session.close()
assert len(duties) == 3
types = {d[0].event_type for d in duties}
assert types == {"duty", "unavailable", "vacation"}
by_type = {d[0].event_type: d[0] for d in duties}
unav = by_type["unavailable"]
assert unav.start_at == "2026-02-17T00:00:00Z"
assert unav.end_at == "2026-02-17T23:59:59Z"
vac = by_type["vacation"]
assert vac.start_at == "2026-02-18T00:00:00Z"
assert vac.end_at == "2026-02-20T23:59:59Z"
def test_import_vacation_with_gap_two_periods(db_url):
"""Vacation dates with a gap (17, 18, 20 Feb) → two records: 1718 and 20."""
result = DutyScheduleResult(
start_date=date(2026, 2, 16),
end_date=date(2026, 2, 21),
entries=[
DutyScheduleEntry(
full_name="Vacation User",
duty_dates=[],
unavailable_dates=[],
vacation_dates=[date(2026, 2, 17), date(2026, 2, 18), date(2026, 2, 20)],
),
],
)
num_users, num_duty, num_unav, num_vac = _run_import(db_url, result, 6, 0)
assert num_users == 1
assert num_duty == 0 and num_unav == 0 and num_vac == 2
session = get_session(db_url)
try:
duties = get_duties(session, "2026-02-16", "2026-02-21")
finally:
session.close()
vacation_records = [d[0] for d in duties if d[0].event_type == "vacation"]
assert len(vacation_records) == 2
starts = sorted(r.start_at for r in vacation_records)
ends = sorted(r.end_at for r in vacation_records)
assert starts == ["2026-02-17T00:00:00Z", "2026-02-20T00:00:00Z"]
assert ends == ["2026-02-18T23:59:59Z", "2026-02-20T23:59:59Z"]