""" Advoware Service Wrapper Extends AdvowareAPI with higher-level operations for business logic. """ from typing import Dict, Any, Optional from services.advoware import AdvowareAPI from services.logging_utils import get_service_logger class AdvowareService: """ Service layer for Advoware operations. Uses AdvowareAPI for API calls. """ def __init__(self, context=None): self.api = AdvowareAPI(context) self.context = context self.logger = get_service_logger('advoware_service', context) def _log(self, message: str, level: str = 'info') -> None: """Internal logging helper""" log_func = getattr(self.logger, level, self.logger.info) log_func(message) async def api_call(self, *args, **kwargs): """Delegate api_call to underlying AdvowareAPI""" return await self.api.api_call(*args, **kwargs) # ========== BETEILIGTE ========== async def get_beteiligter(self, betnr: int) -> Optional[Dict[str, Any]]: """ Load Beteiligte with all data. Returns: Beteiligte object or None """ try: endpoint = f"api/v1/advonet/Beteiligte/{betnr}" result = await self.api.api_call(endpoint, method='GET') return result except Exception as e: self._log(f"[ADVO] Error loading Beteiligte {betnr}: {e}", level='error') return None # ========== KOMMUNIKATION ========== async def create_kommunikation(self, betnr: int, data: Dict[str, Any]) -> Optional[Dict[str, Any]]: """ Create new Kommunikation. Args: betnr: Beteiligte number data: { 'tlf': str, # Required 'bemerkung': str, # Optional 'kommKz': int, # Required (1-12) 'online': bool # Optional } Returns: New Kommunikation with 'id' or None """ try: endpoint = f"api/v1/advonet/Beteiligte/{betnr}/Kommunikationen" result = await self.api.api_call(endpoint, method='POST', json_data=data) if result: self._log(f"[ADVO] ✅ Created Kommunikation: betnr={betnr}, kommKz={data.get('kommKz')}") return result except Exception as e: self._log(f"[ADVO] Error creating Kommunikation: {e}", level='error') return None async def update_kommunikation(self, betnr: int, komm_id: int, data: Dict[str, Any]) -> bool: """ Update existing Kommunikation. Args: betnr: Beteiligte number komm_id: Kommunikation ID data: { 'tlf': str, # Optional 'bemerkung': str, # Optional 'online': bool # Optional } NOTE: kommKz is READ-ONLY and cannot be changed Returns: True if successful """ try: endpoint = f"api/v1/advonet/Beteiligte/{betnr}/Kommunikationen/{komm_id}" await self.api.api_call(endpoint, method='PUT', json_data=data) self._log(f"[ADVO] ✅ Updated Kommunikation: betnr={betnr}, komm_id={komm_id}") return True except Exception as e: self._log(f"[ADVO] Error updating Kommunikation: {e}", level='error') return False async def delete_kommunikation(self, betnr: int, komm_id: int) -> bool: """ Delete Kommunikation (currently returns 403 Forbidden). NOTE: DELETE is disabled in Advoware API. Use empty slots with empty_slot_marker instead. Returns: True if successful """ try: endpoint = f"api/v1/advonet/Beteiligte/{betnr}/Kommunikationen/{komm_id}" await self.api.api_call(endpoint, method='DELETE') self._log(f"[ADVO] ✅ Deleted Kommunikation: betnr={betnr}, komm_id={komm_id}") return True except Exception as e: # Expected: 403 Forbidden self._log(f"[ADVO] DELETE not allowed (expected): {e}", level='warning') return False