# Advoware Beteiligte API - Field Support

Getestet am: 2026-02-07  
Test betNr: 104860  
API Endpoint: `PUT /api/v1/advonet/Beteiligte/{betNr}`

## Schema vs. Reality

Das Swagger Schema `BeteiligterParameter` definiert viele Felder, aber **nicht alle funktionieren tatsächlich**.

### ✅ FUNKTIONIERENDE Felder (8)

Diese Felder wurden erfolgreich getestet und können via PUT geändert werden:

| Feld | Type | Max Length | Bemerkung |
|------|------|------------|-----------|
| `name` | string | 140 | Nachname / Firmenname |
| `vorname` | string | 30 | Vorname (nur bei natürlichen Personen) |
| `rechtsform` | string | 50 | Muss in GET /Rechtsformen sein |
| `titel` | string | 50 | z.B. "Dr.", "Prof." |
| `anrede` | string | 35 | z.B. "Herr", "Frau", "Mr." |
| `bAnrede` | string | 150 | Briefanrede, z.B. "Sehr geehrter Herr" |
| `zusatz` | string | 100 | Zusatzinformation |
| `geburtsdatum` | datetime | - | Format: "YYYY-MM-DDTHH:MM:SS" |

**Wichtig:** rowId ändert sich bei **jedem** PUT, auch wenn der gleiche Wert gesetzt wird!

### ⚠️ NICHT FUNKTIONIERENDE Felder (6)

Diese Felder sind im Swagger Schema definiert, werden aber im PUT **ignoriert**:

| Feld | Bemerkung |
|------|-----------|
| `art` | Wird ignoriert (evtl. Handelsregisterart?) |
| `kurzname` | Wird ignoriert |
| `geburtsname` | Wird ignoriert |
| `familienstand` | Wird ignoriert |
| `handelsRegisterNummer` | ❌ Wird ignoriert (trotz Swagger!) |
| `registergericht` | ❌ Wird ignoriert (trotz Swagger!) |

### 🚫 DEPRECATED Felder (16)

Diese Felder sind im Schema als `deprecated: true` markiert und sollten **nicht** verwendet werden:

Kontaktdaten (deprecated):
- `anschrift`, `strasse`, `plz`, `ort`
- `email`, `emailGesch`
- `telGesch`, `telPrivat`
- `faxGesch`, `faxPrivat`
- `mobil`, `autotelefon`, `sonstige`
- `internet`, `ePost`, `bea`

**Grund:** Kontaktdaten werden über separate Endpoints verwaltet:
- Adressen: `/api/v1/advonet/BeteiligteAdresse`
- Kommunikation: `/api/v1/advonet/BeteiligteKommunikation`
- Bankverbindungen: `/api/v1/advonet/BeteiligteBankverbindung`

### 📖 READ-ONLY Felder

GET Response enthält zusätzliche Felder die **nicht** im PUT Schema sind:

| Feld | Type | Bemerkung |
|------|------|-----------|
| `betNr` | int | Primary Key (readonly) |
| `id` | int | Alias für betNr |
| `rowId` | string | Binary-ID, ändert sich bei jedem Update |
| `adressen` | array | Nested array, separate Endpoint |
| `kommunikation` | array | Nested array, separate Endpoint |
| `bankkverbindungen` | array | Nested array, separate Endpoint |
| `beteiligungen` | array | Verknüpfungen zu Akten (readonly) |
| `kontaktpersonen` | array | Readonly |
| `geaendertAm` | datetime | System field (readonly) |
| `geaendertVon` | string | System field (readonly) |
| `angelegtAm` | datetime | System field (readonly) |
| `angelegtVon` | string | System field (readonly) |

## Best Practices

### ✅ DO
- Nur die 8 funktionierenden Felder im Mapper verwenden
- Read-Modify-Write Pattern verwenden (ganze Entity laden, dann ändern)
- Nach jedem PUT ein GET machen um neue rowId zu erhalten
- Nested arrays (adressen, kommunikation) aus PUT-Payload **entfernen**

### ❌ DON'T
- Nicht alle GET-Felder zurück im PUT schicken
- Keine deprecated Felder verwenden
- Nicht auf `handelsRegisterNummer` / `registergericht` verlassen (funktioniert nicht!)
- Keine nested arrays im PUT (führt zu Fehlern)

## Mapper Implementation

```python
# EspoCRM → Advoware (nur funktionierende Felder!)
def map_cbeteiligte_to_advoware(espo_entity: Dict) -> Dict:
    # Read-Modify-Write: Lade erst die Entity
    advo_entity = await advo.get_beteiligte(betnr)
    
    # Überschreibe nur die 8 funktionierenden Felder
    advo_entity['name'] = espo_entity.get('firmenname') or espo_entity.get('lastName')
    advo_entity['vorname'] = espo_entity.get('firstName')
    advo_entity['rechtsform'] = espo_entity.get('rechtsform')
    advo_entity['titel'] = espo_entity.get('titel')
    advo_entity['anrede'] = espo_entity.get('salutationName')
    advo_entity['bAnrede'] = espo_entity.get('briefAnrede')
    advo_entity['zusatz'] = espo_entity.get('zusatz')
    advo_entity['geburtsdatum'] = espo_entity.get('dateOfBirth')
    
    # Entferne nested arrays (wichtig!)
    advo_entity.pop('adressen', None)
    advo_entity.pop('kommunikation', None)
    advo_entity.pop('bankkverbindungen', None)
    advo_entity.pop('beteiligungen', None)
    advo_entity.pop('kontaktpersonen', None)
    
    return advo_entity


# Advoware → EspoCRM
def map_advoware_to_cbeteiligte(advo_entity: Dict) -> Dict:
    # Nur die 8 Stammdaten-Felder
    return {
        'lastName': advo_entity.get('name'),  # oder firmenname
        'firstName': advo_entity.get('vorname'),
        'rechtsform': advo_entity.get('rechtsform'),
        'titel': advo_entity.get('titel'),
        'salutationName': advo_entity.get('anrede'),
        'briefAnrede': advo_entity.get('bAnrede'),
        'zusatz': advo_entity.get('zusatz'),
        'dateOfBirth': advo_entity.get('geburtsdatum'),
        'advowareRowId': advo_entity.get('rowId')  # für Change Detection
    }
```

## Siehe auch

- [Advoware API Swagger](advoware/advoware_api_swagger.json)
- [Beteiligte Sync Implementation](../steps/vmh/beteiligte_sync_event_step.py)
- [Beteiligte Mapper](../services/espocrm_mapper.py)
