Skip to content

Commit 10c66a4

Browse files
ELI-615 | campaign having recent - active start_date supersedes the others sharing same best-status
1 parent 84d4b6b commit 10c66a4

2 files changed

Lines changed: 194 additions & 198 deletions

File tree

src/eligibility_signposting_api/services/calculators/eligibility_calculator.py

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
from eligibility_signposting_api.audit.audit_context import AuditContext
1212
from eligibility_signposting_api.model import campaign_config, eligibility_status
1313
from eligibility_signposting_api.model.eligibility_status import (
14+
BestIterationResult,
1415
CohortGroupResult,
1516
Condition,
1617
ConditionName,
1718
EligibilityStatus,
1819
IterationResult,
19-
IterationResultSummary,
2020
Reason,
2121
Status,
2222
StatusText,
@@ -32,6 +32,7 @@
3232
from eligibility_signposting_api.model.campaign_config import (
3333
CampaignConfig,
3434
CohortLabel,
35+
IterationName,
3536
)
3637
from eligibility_signposting_api.model.person import Person
3738

@@ -80,32 +81,31 @@ def get_the_best_cohort_memberships(
8081

8182
return best_status, best_cohorts
8283

83-
def get_eligibility_status(
84-
self, include_actions: str, conditions: list[str], requested_category: str
85-
) -> EligibilityStatus:
84+
def get_eligibility_status(self, include_actions: str, conditions: list[str], category: str) -> EligibilityStatus:
8685
include_actions_flag = include_actions.upper() == "Y"
8786
condition_results: dict[ConditionName, IterationResult] = {}
8887
final_result = []
8988

90-
requested_cc_with_active_iteration = (
91-
self.campaign_evaluator.get_campaign_with_latest_active_iteration_per_target(
92-
self.campaign_configs, conditions, requested_category
93-
)
89+
requested_grouped_campaigns = self.campaign_evaluator.get_requested_grouped_campaigns(
90+
self.campaign_configs, conditions, category
9491
)
95-
for condition_name, campaign in requested_cc_with_active_iteration:
96-
iteration_result_summary = self.evaluate_iteration_result_summary(campaign)
92+
for condition_name, campaign_group in requested_grouped_campaigns:
93+
best_iteration_result = self.get_best_iteration_result(campaign_group)
94+
95+
if best_iteration_result is None:
96+
continue
9797

9898
matched_action_detail = self.action_rule_handler.get_actions(
9999
self.person,
100-
iteration_result_summary.active_iteration,
101-
iteration_result_summary.iteration_result,
100+
best_iteration_result.active_iteration,
101+
best_iteration_result.iteration_result,
102102
include_actions_flag=include_actions_flag,
103103
)
104104

105-
iteration_result_summary = TokenProcessor.find_and_replace_tokens(self.person, iteration_result_summary)
105+
best_iteration_result = TokenProcessor.find_and_replace_tokens(self.person, best_iteration_result)
106106
matched_action_detail = TokenProcessor.find_and_replace_tokens(self.person, matched_action_detail)
107107

108-
condition_results[condition_name] = iteration_result_summary.iteration_result
108+
condition_results[condition_name] = best_iteration_result.iteration_result
109109
condition_results[condition_name].actions = matched_action_detail.actions
110110

111111
condition: Condition = self.build_condition(
@@ -116,35 +116,57 @@ def get_eligibility_status(
116116

117117
AuditContext.append_audit_condition(
118118
condition_name,
119-
iteration_result_summary,
119+
best_iteration_result,
120120
matched_action_detail,
121121
)
122122

123123
# Consolidate all the results and return
124124
return eligibility_status.EligibilityStatus(conditions=final_result)
125125

126-
def evaluate_iteration_result_summary(
127-
self, campaign_with_active_iteration: CampaignConfig
128-
) -> IterationResultSummary:
129-
active_iteration = campaign_with_active_iteration.current_iteration
130-
cohort_results: dict[CohortLabel, CohortGroupResult] = self.rule_processor.get_cohort_group_results(
131-
self.person, active_iteration
132-
)
126+
def get_best_iteration_result(self, campaign_group: list[CampaignConfig]) -> BestIterationResult | None:
127+
sorted_campaigns = sorted(campaign_group, key=lambda c: c.start_date, reverse=True)
133128

134-
# Determine Result between cohorts - get the best
135-
status, best_cohorts = self.get_the_best_cohort_memberships(cohort_results)
136-
status_text = self.get_status_text(
137-
active_iteration.status_text, ConditionName(campaign_with_active_iteration.target), status
138-
)
129+
iteration_results = self.get_iteration_results(sorted_campaigns)
130+
131+
if not iteration_results:
132+
return None
139133

140-
return IterationResultSummary(
141-
IterationResult(status, status_text, best_cohorts, []),
142-
active_iteration,
143-
campaign_with_active_iteration.id,
144-
campaign_with_active_iteration.version,
145-
cohort_results,
134+
(_best_iteration_name, best_iteration_result) = max(
135+
iteration_results.items(),
136+
key=lambda item: next(iter(item[1].cohort_results.values())).status.value
137+
# Below handles the case where there are no cohort results
138+
if item[1].cohort_results
139+
else -1,
146140
)
147141

142+
return best_iteration_result
143+
144+
def get_iteration_results(self, campaign_group: list[CampaignConfig]) -> dict[IterationName, BestIterationResult]:
145+
iteration_results: dict[IterationName, BestIterationResult] = {}
146+
147+
for cc in campaign_group:
148+
try:
149+
active_iteration = cc.current_iteration
150+
except StopIteration:
151+
logger.info("Skipping campaign ID %s as no active iteration was found.", cc.id)
152+
continue
153+
cohort_results: dict[CohortLabel, CohortGroupResult] = self.rule_processor.get_cohort_group_results(
154+
self.person, active_iteration
155+
)
156+
157+
# Determine Result between cohorts - get the best
158+
status, best_cohorts = self.get_the_best_cohort_memberships(cohort_results)
159+
status_text = self.get_status_text(active_iteration.status_text, ConditionName(cc.target), status)
160+
161+
iteration_results[active_iteration.name] = BestIterationResult(
162+
IterationResult(status, status_text, best_cohorts, []),
163+
active_iteration,
164+
cc.id,
165+
cc.version,
166+
cohort_results,
167+
)
168+
return iteration_results
169+
148170
@staticmethod
149171
def get_status_text(
150172
status_text: campaign_config.StatusText | None, condition_name: ConditionName, status: Status

0 commit comments

Comments
 (0)