""" EspoCRM ↔ Advoware Entity Mapper Transformiert Beteiligte zwischen den beiden Systemen basierend auf ENTITY_MAPPING_CBeteiligte_Advoware.md """ from typing import Dict, Any, Optional, List from datetime import datetime import logging logger = logging.getLogger(__name__) class BeteiligteMapper: """Mapper für CBeteiligte (EspoCRM) ↔ Beteiligte (Advoware)""" @staticmethod def map_cbeteiligte_to_advoware(espo_entity: Dict[str, Any]) -> Dict[str, Any]: """ Transformiert EspoCRM CBeteiligte → Advoware Beteiligte Format Args: espo_entity: CBeteiligte Entity von EspoCRM Returns: Dict für Advoware API (POST/PUT /api/v1/advonet/Beteiligte) """ logger.debug(f"Mapping EspoCRM → Advoware: {espo_entity.get('id')}") # Bestimme ob Person oder Firma is_firma = bool(espo_entity.get('firmenname')) rechtsform = espo_entity.get('rechtsform', '') # Basis-Struktur advo_data = { 'rechtsform': rechtsform, } # NAME: Person vs. Firma if is_firma: # Firma: name = firmenname advo_data['name'] = espo_entity.get('firmenname', '') advo_data['vorname'] = None else: # Person: name = lastName, vorname = firstName advo_data['name'] = espo_entity.get('lastName', '') advo_data['vorname'] = espo_entity.get('firstName', '') # ANREDE salutation = espo_entity.get('salutationName', '') if salutation: advo_data['anrede'] = salutation # GEBURTSDATUM date_of_birth = espo_entity.get('dateOfBirth') if date_of_birth: advo_data['geburtsdatum'] = date_of_birth # KONTAKTDATEN # E-Mail (emailAddressData ist Array, wir nehmen Primary) email_data = espo_entity.get('emailAddressData') if email_data and isinstance(email_data, list): primary_email = next((e for e in email_data if e.get('primary')), None) if primary_email: advo_data['emailGesch'] = primary_email.get('emailAddress') elif espo_entity.get('emailAddress'): advo_data['emailGesch'] = espo_entity.get('emailAddress') # Telefon (phoneNumberData ist Array, wir nehmen Primary) phone_data = espo_entity.get('phoneNumberData') if phone_data and isinstance(phone_data, list): primary_phone = next((p for p in phone_data if p.get('primary')), None) if primary_phone: phone_num = primary_phone.get('phoneNumber') phone_type = primary_phone.get('type', '').lower() if 'mobile' in phone_type or 'mobil' in phone_type: advo_data['mobil'] = phone_num else: advo_data['telGesch'] = phone_num elif espo_entity.get('phoneNumber'): advo_data['telGesch'] = espo_entity.get('phoneNumber') # HANDELSREGISTER (nur für Firmen) if is_firma: hr_nummer = espo_entity.get('handelsregisterNummer') if hr_nummer: advo_data['handelsRegisterNummer'] = hr_nummer # DISGTYP (EspoCRM spezifisch - falls vorhanden) disgtyp = espo_entity.get('disgTyp') if disgtyp: advo_data['disgTyp'] = disgtyp logger.debug(f"Mapped to Advoware: name={advo_data.get('name')}, vorname={advo_data.get('vorname')}") return advo_data @staticmethod def map_advoware_to_cbeteiligte(advo_entity: Dict[str, Any]) -> Dict[str, Any]: """ Transformiert Advoware Beteiligte → EspoCRM CBeteiligte Format Args: advo_entity: Beteiligter von Advoware API Returns: Dict für EspoCRM API (POST/PUT /api/v1/CBeteiligte) """ logger.debug(f"Mapping Advoware → EspoCRM: betNr={advo_entity.get('betNr')}") # Bestimme ob Person oder Firma vorname = advo_entity.get('vorname') is_person = bool(vorname) # Basis-Struktur espo_data = { 'rechtsform': advo_entity.get('rechtsform', ''), 'betnr': advo_entity.get('betNr'), # Link zu Advoware } # NAME: Person vs. Firma if is_person: # Person espo_data['firstName'] = vorname espo_data['lastName'] = advo_entity.get('name', '') espo_data['name'] = f"{vorname} {advo_entity.get('name', '')}".strip() espo_data['firmenname'] = None else: # Firma espo_data['firmenname'] = advo_entity.get('name', '') espo_data['name'] = advo_entity.get('name', '') espo_data['firstName'] = None espo_data['lastName'] = None # ANREDE anrede = advo_entity.get('anrede') if anrede: espo_data['salutationName'] = anrede # GEBURTSDATUM geburtsdatum = advo_entity.get('geburtsdatum') if geburtsdatum: espo_data['dateOfBirth'] = geburtsdatum # KONTAKTDATEN # E-Mail (emailGesch ist primary) email_gesch = advo_entity.get('emailGesch') email = advo_entity.get('email') primary_email = email_gesch or email if primary_email: espo_data['emailAddress'] = primary_email espo_data['emailAddressData'] = [ { 'emailAddress': primary_email, 'primary': True, 'optOut': False, 'invalid': False } ] # Telefon (telGesch ist primary, mobil als secondary) tel_gesch = advo_entity.get('telGesch') tel_privat = advo_entity.get('telPrivat') mobil = advo_entity.get('mobil') phone_data = [] # Primary: telGesch oder telPrivat primary_tel = tel_gesch or tel_privat if primary_tel: espo_data['phoneNumber'] = primary_tel phone_data.append({ 'phoneNumber': primary_tel, 'primary': True, 'type': 'Office' if tel_gesch else 'Home' }) # Secondary: mobil if mobil and mobil != primary_tel: phone_data.append({ 'phoneNumber': mobil, 'primary': False, 'type': 'Mobile' }) if phone_data: espo_data['phoneNumberData'] = phone_data # HANDELSREGISTER (nur für Firmen) if not is_person: hr_nummer = advo_entity.get('handelsRegisterNummer') if hr_nummer: espo_data['handelsregisterNummer'] = hr_nummer # DISGTYP disgtyp = advo_entity.get('disgTyp') if disgtyp: espo_data['disgTyp'] = disgtyp logger.debug(f"Mapped to EspoCRM: name={espo_data.get('name')}") return espo_data @staticmethod def get_changed_fields(espo_entity: Dict[str, Any], advo_entity: Dict[str, Any]) -> List[str]: """ Vergleicht zwei Entities und gibt Liste der geänderten Felder zurück Args: espo_entity: EspoCRM CBeteiligte advo_entity: Advoware Beteiligte Returns: Liste von Feldnamen die unterschiedlich sind """ # Mappe Advoware zu EspoCRM Format für Vergleich mapped_advo = BeteiligteMapper.map_advoware_to_cbeteiligte(advo_entity) changed = [] # Vergleiche wichtige Felder compare_fields = [ 'name', 'firstName', 'lastName', 'firmenname', 'emailAddress', 'phoneNumber', 'dateOfBirth', 'rechtsform', 'handelsregisterNummer' ] for field in compare_fields: espo_val = espo_entity.get(field) advo_val = mapped_advo.get(field) # Normalisiere None und leere Strings espo_val = espo_val if espo_val else None advo_val = advo_val if advo_val else None if espo_val != advo_val: changed.append(field) logger.debug(f"Field '{field}' changed: EspoCRM='{espo_val}' vs Advoware='{advo_val}'") return changed