""" Advoware History API Client API client for Advoware History (document timeline) operations. Provides methods to: - Get History entries for Akte - Create new History entry """ from typing import Dict, Any, List, Optional from datetime import datetime from services.advoware import AdvowareAPI from services.logging_utils import get_service_logger from services.exceptions import AdvowareAPIError class AdvowareHistoryService: """ Advoware History API client. Provides methods to: - Get History entries for Akte - Create new History entry """ def __init__(self, ctx): """ Initialize service with context. Args: ctx: Motia context for logging """ self.ctx = ctx self.logger = get_service_logger(__name__, ctx) self.advoware = AdvowareAPI(ctx) # Reuse existing auth self.logger.info("AdvowareHistoryService initialized") def _log(self, message: str, level: str = 'info') -> None: """Helper for consistent logging""" getattr(self.logger, level)(f"[AdvowareHistoryService] {message}") async def get_akte_history(self, akte_nr: str) -> List[Dict[str, Any]]: """ Get all History entries for Akte. Args: akte_nr: Aktennummer (10-digit string, e.g., "2019001145") Returns: List of History entry dicts with fields: - dat: str (timestamp) - art: str (type, e.g., "Schreiben") - text: str (description) - datei: str (file path, e.g., "V:\\12345\\document.pdf") - benutzer: str (user) - versendeart: str - hnr: int (History entry ID) Raises: AdvowareAPIError: If API call fails (non-retryable) Note: Uses correct endpoint: GET /api/v1/advonet/History?nr={aktennummer} """ self._log(f"Fetching History for Akte {akte_nr}") try: endpoint = "api/v1/advonet/History" params = {'nr': akte_nr} result = await self.advoware.api_call(endpoint, method='GET', params=params) if not isinstance(result, list): self._log(f"Unexpected History response format: {type(result)}", level='warning') return [] self._log(f"Successfully fetched {len(result)} History entries for Akte {akte_nr}") return result except Exception as e: error_msg = str(e) # Advoware server bug: "Nullable object must have a value" in ConnectorFunctionsHistory.cs # This is a server-side bug we cannot fix - return empty list and continue if "Nullable object must have a value" in error_msg or "500" in error_msg: self._log( f"⚠️ Advoware server error for Akte {akte_nr} (likely null reference bug): {e}", level='warning' ) self._log(f"Continuing with empty History for Akte {akte_nr}", level='info') return [] # Return empty list instead of failing # For other errors, raise as before self._log(f"Failed to fetch History for Akte {akte_nr}: {e}", level='error') raise AdvowareAPIError(f"History fetch failed: {e}") from e async def create_history_entry( self, akte_id: int, entry_data: Dict[str, Any] ) -> Dict[str, Any]: """ Create new History entry. Args: akte_id: Advoware Akte ID entry_data: History entry data with fields: - dat: str (timestamp, ISO format) - art: str (type, e.g., "Schreiben") - text: str (description) - datei: str (file path, e.g., "V:\\12345\\document.pdf") - benutzer: str (user, default: "AI") - versendeart: str (default: "Y") - visibleOnline: bool (default: True) - posteingang: int (default: 0) Returns: Created History entry Raises: AdvowareAPIError: If creation fails """ self._log(f"Creating History entry for Akte {akte_id}") # Ensure required fields with defaults now = datetime.now().isoformat() payload = { "betNr": entry_data.get('betNr'), # Can be null "dat": entry_data.get('dat', now), "art": entry_data.get('art', 'Schreiben'), "text": entry_data.get('text', 'Document uploaded via Motia'), "datei": entry_data.get('datei', ''), "benutzer": entry_data.get('benutzer', 'AI'), "gelesen": entry_data.get('gelesen'), # Can be null "modified": entry_data.get('modified', now), "vorgelegt": entry_data.get('vorgelegt', ''), "posteingang": entry_data.get('posteingang', 0), "visibleOnline": entry_data.get('visibleOnline', True), "versendeart": entry_data.get('versendeart', 'Y') } try: endpoint = f"api/v1/advonet/Akten/{akte_id}/History" result = await self.advoware.api_call(endpoint, method='POST', json_data=payload) if result: self._log(f"Successfully created History entry for Akte {akte_id}") return result except Exception as e: self._log(f"Failed to create History entry for Akte {akte_id}: {e}", level='error') raise AdvowareAPIError(f"History entry creation failed: {e}") from e