Skip to content

Commit 4e1ead4

Browse files
committed
eli-579 adding a base class for derived field calculations, with aim of making it compatible with the token parsing logic
1 parent 44fed02 commit 4e1ead4

1 file changed

Lines changed: 66 additions & 0 deletions

File tree

  • src/eligibility_signposting_api/services/processors/derived_values
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
from abc import ABC, abstractmethod
2+
from dataclasses import dataclass
3+
from typing import Any
4+
5+
6+
@dataclass
7+
class DerivedValueContext:
8+
"""Context object containing all data needed for derived value calculation.
9+
10+
Attributes:
11+
person_data: List of person attribute dictionaries
12+
attribute_name: The condition/vaccine type (e.g., 'COVID', 'RSV')
13+
source_attribute: The source attribute to derive from (e.g., 'LAST_SUCCESSFUL_DATE')
14+
function_args: Arguments passed to the function (e.g., number of days)
15+
date_format: Optional date format string for output formatting
16+
"""
17+
18+
person_data: list[dict[str, Any]]
19+
attribute_name: str
20+
source_attribute: str | None
21+
function_args: str | None
22+
date_format: str | None
23+
24+
25+
class DerivedValueHandler(ABC):
26+
"""Abstract base class for derived value handlers.
27+
28+
Derived value handlers compute values that don't exist directly in the data
29+
but are calculated from existing attributes. Each handler is responsible for
30+
a specific type of calculation (e.g., adding days to a date).
31+
32+
To create a new derived value handler:
33+
1. Subclass DerivedValueHandler
34+
2. Set the `function_name` class attribute to the token function name (e.g., 'ADD_DAYS')
35+
3. Implement the `calculate` method
36+
4. Register the handler with the DerivedValueRegistry
37+
"""
38+
39+
function_name: str = ""
40+
41+
@abstractmethod
42+
def calculate(self, context: DerivedValueContext) -> str:
43+
"""Calculate the derived value.
44+
45+
Args:
46+
context: DerivedValueContext containing all necessary data
47+
48+
Returns:
49+
The calculated value as a string
50+
51+
Raises:
52+
ValueError: If the calculation cannot be performed
53+
"""
54+
55+
@abstractmethod
56+
def get_source_attribute(self, target_attribute: str) -> str:
57+
"""Get the source attribute name needed for this derived value.
58+
59+
For example, NEXT_DOSE_DUE derives from LAST_SUCCESSFUL_DATE.
60+
61+
Args:
62+
target_attribute: The target derived attribute name (e.g., 'NEXT_DOSE_DUE')
63+
64+
Returns:
65+
The source attribute name to use for calculation
66+
"""

0 commit comments

Comments
 (0)