Skip to content

Commit e2493b7

Browse files
fix - ELI-674 - 'current_iteration' uses data and time to get the latest active iteration(#602)
1 parent d538a2c commit e2493b7

2 files changed

Lines changed: 40 additions & 8 deletions

File tree

src/eligibility_signposting_api/model/campaign_config.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -415,11 +415,22 @@ def check_start_and_end_dates_sensible(self) -> typing.Self:
415415

416416
@model_validator(mode="after")
417417
def check_no_overlapping_iterations(self) -> typing.Self:
418-
iterations_by_date = Counter([i.iteration_date for i in self.iterations])
419-
if multiple_found := next(((d, c) for d, c in iterations_by_date.most_common() if c > 1), None):
420-
iteration_date, count = multiple_found
421-
message = f"{count} iterations with iteration date {iteration_date} in campaign {self.id}"
418+
date_time_pairs = []
419+
for i in self.iterations:
420+
effective_time = i.iteration_time or self.iteration_time
421+
date_time_pairs.append((i.iteration_date, effective_time))
422+
423+
counts = Counter(date_time_pairs)
424+
425+
duplicate = next(((dt, c) for dt, c in counts.items() if c > 1), None)
426+
427+
if duplicate:
428+
(iteration_date, iteration_time), count = duplicate
429+
message = (
430+
f"{count} iterations with iteration date/time {iteration_date} {iteration_time} in campaign {self.id}"
431+
)
422432
raise ValueError(message)
433+
423434
return self
424435

425436
@cached_property
@@ -429,9 +440,9 @@ def campaign_live(self) -> bool:
429440

430441
@cached_property
431442
def current_iteration(self) -> Iteration:
432-
today = datetime.now(tz=UTC).date()
433-
iterations_by_date_descending = sorted(self.iterations, key=attrgetter("iteration_date"), reverse=True)
434-
return next(i for i in iterations_by_date_descending if i.iteration_date <= today)
443+
now = datetime.now(tz=UTC)
444+
iterations_by_date_descending = sorted(self.iterations, key=attrgetter("iteration_datetime"), reverse=True)
445+
return next(i for i in iterations_by_date_descending if i.iteration_datetime <= now)
435446

436447
def __str__(self) -> str:
437448
return json.dumps(self.model_dump(by_alias=True), indent=2)

tests/unit/validation/test_campaign_config_validator.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
from datetime import datetime
1+
from datetime import UTC, datetime
22

33
import pytest
4+
from freezegun import freeze_time
45
from pydantic import ValidationError
56

67
from rules_validation_api.validators.campaign_config_validator import CampaignConfigValidation
@@ -320,3 +321,23 @@ def test_approval_minimum_greater_than_approval_maximum_is_invalid(
320321
data["ApprovalMinimum"] = approval_min
321322
data["ApprovalMaximum"] = approval_max
322323
CampaignConfigValidation(**data)
324+
325+
@freeze_time("2026-03-30 01:00:00")
326+
def test_get_current_iteration_by_iteration_date_time(self, valid_campaign_config_with_only_mandatory_fields):
327+
data = valid_campaign_config_with_only_mandatory_fields.copy()
328+
data["StartDate"] = "20260301"
329+
data["EndDate"] = "20260630"
330+
iteration_1 = data["Iterations"][0]
331+
iteration_1["IterationDate"] = "20260329"
332+
iteration_1["IterationTime"] = "01:00:00"
333+
iteration_2 = data["Iterations"][1]
334+
iteration_2["IterationDate"] = "20260329"
335+
iteration_2["IterationTime"] = "01:00:02"
336+
337+
model = CampaignConfigValidation(**data)
338+
339+
expected = datetime.strptime(
340+
iteration_2["IterationDate"] + iteration_2["IterationTime"], "%Y%m%d%H:%M:%S"
341+
).replace(tzinfo=UTC)
342+
343+
assert model.current_iteration.iteration_datetime == expected

0 commit comments

Comments
 (0)