-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: signer AhjoRequest * feat: seed signer org ids setting * feat: improve decisionmaker request error handling * chore: move responseHandler to own file * chore: move requestHandler to own file * feat: signer data from Ahjo
- Loading branch information
Showing
14 changed files
with
538 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
backend/benefit/applications/management/commands/get_signer.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from applications.enums import AhjoRequestType | ||
from applications.management.commands.ahjo_base_command import AhjoRequestBaseClass | ||
|
||
|
||
class Command(AhjoRequestBaseClass): | ||
help = ( | ||
"Get the decision maker from Ahjo and store it in the database in Ahjo settings" | ||
) | ||
request_type = AhjoRequestType.GET_SIGNER |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from enum import Enum, unique | ||
|
||
|
||
@unique | ||
class AhjoSettingName(Enum): | ||
""" | ||
Enum representing different Ahjo setting names. | ||
The @unique decorator ensures that no two enum members have the same value. | ||
""" | ||
|
||
DECISION_MAKER = "ahjo_decision_maker" | ||
DECISION_MAKER_ORG_ID = "ahjo_org_identifier" | ||
SIGNER = "ahjo_signer" | ||
SIGNER_ORG_IDS = "ahjo_signer_org_ids" | ||
|
||
def __str__(self): | ||
""" | ||
Allow the enum to be used directly as a string when converted. | ||
This makes it easy to use in database queries or comparisons. | ||
""" | ||
return self.value | ||
|
||
def __repr__(self): | ||
""" | ||
Provide a clear representation of the enum member. | ||
""" | ||
return f"{self.__class__.__name__}.{self.name}" |
39 changes: 39 additions & 0 deletions
39
backend/benefit/applications/services/ahjo/request_handler.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
from typing import List, Union | ||
|
||
from applications.enums import AhjoRequestType | ||
from applications.services.ahjo.enums import AhjoSettingName | ||
from applications.services.ahjo.setting_response_handler import AhjoResponseHandler | ||
from applications.services.ahjo_authentication import AhjoToken | ||
from applications.services.ahjo_client import ( | ||
AhjoApiClient, | ||
AhjoDecisionMakerRequest, | ||
AhjoRequest, | ||
AhjoSignerRequest, | ||
) | ||
|
||
|
||
class AhjoRequestHandler: | ||
def __init__(self, ahjo_token: AhjoToken, ahjo_request_type: AhjoRequest): | ||
self.ahjo_token = ahjo_token | ||
self.ahjo_request_type = ahjo_request_type | ||
|
||
def handle_request_without_application(self): | ||
if self.ahjo_request_type == AhjoRequestType.GET_DECISION_MAKER: | ||
self.get_setting_from_ahjo( | ||
request_class=AhjoDecisionMakerRequest, | ||
setting_name=AhjoSettingName.DECISION_MAKER, | ||
) | ||
if self.ahjo_request_type == AhjoRequestType.GET_SIGNER: | ||
self.get_setting_from_ahjo( | ||
request_class=AhjoSignerRequest, | ||
setting_name=AhjoSettingName.SIGNER, | ||
) | ||
|
||
def get_setting_from_ahjo( | ||
self, request_class: AhjoRequest, setting_name: AhjoSettingName | ||
) -> Union[List, None]: | ||
ahjo_client = AhjoApiClient(self.ahjo_token, request_class()) | ||
_, result = ahjo_client.send_request_to_ahjo() | ||
AhjoResponseHandler.handle_ahjo_query_response( | ||
setting_name=setting_name, data=result | ||
) |
152 changes: 152 additions & 0 deletions
152
backend/benefit/applications/services/ahjo/setting_response_handler.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
import logging | ||
from typing import Dict, List, Union | ||
|
||
from django.core.exceptions import ValidationError | ||
|
||
from applications.models import AhjoSetting | ||
from applications.services.ahjo.enums import AhjoSettingName | ||
|
||
LOGGER = logging.getLogger(__name__) | ||
|
||
|
||
class AhjoResponseHandler: | ||
@staticmethod | ||
def handle_ahjo_query_response( | ||
setting_name: AhjoSettingName, data: Union[None, dict] | ||
) -> None: | ||
""" | ||
Handle the decision maker response from Ahjo API. | ||
Args: | ||
response: Variable that is either None or the JSON response data | ||
Raises: | ||
ValueError: If response data is invalid | ||
ValidationError: If data validation fails | ||
""" | ||
|
||
if not data: | ||
raise ValueError( | ||
f"Failed to process Ahjo API response for setting {setting_name}, no data received from Ahjo." | ||
) | ||
|
||
try: | ||
# Validate response structure | ||
if not isinstance(data, dict): | ||
raise ValidationError( | ||
f"Invalid response format for setting {setting_name}: expected dictionary" | ||
) | ||
if setting_name == AhjoSettingName.DECISION_MAKER: | ||
filtered_data = AhjoResponseHandler.filter_decision_makers(data) | ||
if setting_name == AhjoSettingName.SIGNER: | ||
filtered_data = AhjoResponseHandler.filter_signers(data) | ||
|
||
if not filtered_data: | ||
LOGGER.warning("No valid decision makers found in response") | ||
return | ||
|
||
# Store the filtered data | ||
AhjoResponseHandler._save_ahjo_setting( | ||
setting_name=setting_name, filtered_data=filtered_data | ||
) | ||
|
||
LOGGER.info(f"Successfully processed {len(filtered_data)} decision makers") | ||
|
||
except Exception as e: | ||
LOGGER.error( | ||
f"Failed to process Ahjo api response for setting {setting_name}: {str(e)}", | ||
exc_info=True, | ||
) | ||
raise | ||
|
||
@staticmethod | ||
def filter_decision_makers(data: Dict) -> List[Dict[str, str]]: | ||
""" | ||
Filter the decision makers Name and ID from the Ahjo response. | ||
Args: | ||
data: Response data dictionary | ||
Returns: | ||
List of filtered decision maker dictionaries | ||
Raises: | ||
ValidationError: If required fields are missing | ||
""" | ||
try: | ||
# Validate required field exists | ||
if "decisionMakers" not in data: | ||
raise ValidationError("Missing decisionMakers field in response") | ||
|
||
result = [] | ||
for item in data["decisionMakers"]: | ||
try: | ||
organization = item.get("Organization", {}) | ||
|
||
# Skip if not a decision maker | ||
if not organization.get("IsDecisionMaker"): | ||
continue | ||
|
||
# Validate required fields | ||
name = organization.get("Name") | ||
org_id = organization.get("ID") | ||
|
||
if not all([name, org_id]): | ||
LOGGER.warning( | ||
f"Missing required fields for organization: {organization}" | ||
) | ||
continue | ||
|
||
result.append({"Name": name, "ID": org_id}) | ||
|
||
except Exception as e: | ||
LOGGER.warning(f"Failed to process decision maker: {str(e)}") | ||
continue | ||
|
||
return result | ||
|
||
except Exception as e: | ||
LOGGER.error(f"Error filtering decision makers: {str(e)}") | ||
raise ValidationError(f"Failed to filter decision makers: {str(e)}") | ||
|
||
@staticmethod | ||
def _save_ahjo_setting( | ||
setting_name: AhjoSettingName, filtered_data: List[Dict[str, str]] | ||
) -> None: | ||
""" | ||
Save an ahjo setting to database. | ||
Args: | ||
filtered_data: List of filtered setting data dictionaries | ||
Raises: | ||
ValidationError: If database operation fails | ||
""" | ||
try: | ||
AhjoSetting.objects.update_or_create( | ||
name=setting_name, defaults={"data": filtered_data} | ||
) | ||
except Exception as e: | ||
LOGGER.error(f"Failed to save setting {setting_name}: {str(e)}") | ||
raise ValidationError( | ||
f"Failed to save setting {setting_name} to database: {str(e)}" | ||
) | ||
|
||
@staticmethod | ||
def filter_signers(data: Dict) -> List[Dict[str, str]]: | ||
""" | ||
Filter the signers Name and ID from the Ahjo response. | ||
Args: | ||
data: Response data dictionary | ||
Returns: | ||
List of filtered signer dictionaries | ||
Raises: | ||
ValidationError: If required fields are missing | ||
""" | ||
result = [] | ||
for item in data["agentList"]: | ||
result.append({"ID": item["ID"], "Name": item["Name"]}) | ||
return result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.