# Befund: Teuerungszuschlag fehlt auf der AB (ORDRSP)

Stand: 2026-07-03 · Beispiele: **AWDESO000399-1**, **AWDESO000401-1** · Status: Befund bestätigt.

> **⚠️ UPDATE 2026-07-03 (iwofurn-Feedback):** Die ursprünglich geplante Sofort-Lösung ist
> teilweise verworfen — siehe Abschnitt 2b. **CNDL via Lobster ist der Hauptweg** (Abschnitt 3),
> `AdditionalLineAmount` ist laut iwofurn "nicht hinreichend", der FOOT-Ausweis von
> Positions-Zuschlägen ist unzulässig.

## 1. Befund (DB-verifiziert)

- **D365 hat den Zuschlag korrekt:** Beide Aufträge tragen 3% "Teuerungszuschlag"
  (`SalesOrderLineChargeV2Staging`, `SALESCHARGECODE = Aufpreis`) auf jeder Position
  (Set-Kopf + Komponenten).
- **Unser AB-JSON sendet den Zuschlag** als `LineCharge` am Set-Kopf
  (`OrderResponse.php:801` — Set-Unterpositionen bewusst ohne, die dürfen keine Preise tragen).
  Rechnerisch steckt er auch in `LineVAT.VatBase` und den FOOT-Summen.
- **Lobster verwirft ihn:** Der ORDRSP-Input-Baum (ExportTree vom 2026-07-02) hat KEINEN
  `LineCharge`-Knoten — der Invoice-Baum hat ihn. Nicht im Baum definierte JSON-Felder werden
  kommentarlos gedroppt → im iwofurn-XML fehlt die CNDL-Kondition.
- **Folge beim Kunden:** Die Summen der AB sind um den Zuschlag höher als die ausgewiesenen
  Positionswerte, ohne erklärende Konditionszeile — "nicht ausgewiesen, nicht herleitbar".
  Betrifft JEDE AB mit Zuschlag, nicht nur Sets. (Auf der Rechnung funktioniert es, weil der
  Invoice-Baum `LineCharge` kennt.)

## 1b. Zusatzbefund: Auch der BETRAG wird nirgends ausgewiesen

Selbst in unserem JSON steht der berechnete Zuschlagsbetrag nicht drin
(`OrderResponse.php:829-837`):
- `LineCharge.Percent` = 3 ✓, aber `LineCharge.Amount` = `FIXEDCHARGEAMOUNT` = **0** bei
  Prozent-Zuschlägen. Der Euro-Betrag (`LINEAMOUNT × 3%`) wird nur intern in die Steuerbasis
  gerechnet, nie ausgegeben.
- FOOT-Summe (`AdditionalAmounts`) summiert `UNITCHARGEAMOUNT` = ebenfalls 0 bei
  Prozent-Zuschlägen → fehlt komplett.
- Die **Rechnung** macht es richtig: `TotalLineCharge.TotalAmount` = echter Betrag aus D365
  (`LINETOTALCHARGEAMOUNT`). Die AB hat kein Pendant.

→ Selbst nach einer Lobster-CNDL-Erweiterung sähe der Kunde nur "3%" ohne Betrag.
Die Sofort-Lösung (Abschnitt 2) behebt genau das: berechneter Betrag je Position + Belegsumme.

## 2. Sofort-Lösung: Ausweis über Felder, die der Lobster-Baum SCHON KANN

Der ORDRSP-Baum enthält zwei bislang von uns leer gelassene Strukturen, die genau für diesen
Zweck definiert sind (iwofurn-/EDIFACT-Semantik):

### 2.1 Positionsebene: `AdditionalLineAmount` (im Baum: `ITEMS;AdditionalLineAmount;0..9999`)

Qualifier `"Summe"` (`LINEAMOUNTQUALIFIER_SUM`, EDIFACT 131) = **"Summe aller Zu-/Abschläge
auf Positionsebene (CNDL)"** — exakt das Feld, aus dem der Kunde den Zuschlag herleiten kann:

```json
"AdditionalLineAmount": [
  { "Qualifier": "Summe", "Currency": "EUR", "Value": 18.26 }
]
```

Damit geht die Rechnung für den Kunden auf: `NetLineAmount + AdditionalLineAmount(Summe) = LineVAT.VatBase`.

Befüllung in `OrderResponse::generateJSON()` (Items-Schleife, wo heute schon `$totalNetto`
den Zuschlag einrechnet, Z. 693-699): denselben Betrag zusätzlich als
`AdditionalLineAmount`-Eintrag ausgeben (nur `!$isSetSub`, analog `LineCharge`).

### 2.2 Belegebene: FOOT `AdditionalAmounts` (im Baum vorhanden, wird von uns schon genutzt)

Zusätzlicher Eintrag mit Qualifier `TotalOfDocumentAdditionsAndDeductions`
(`TOTALAMOUNTQUALIFIER_TOTALOFDOCUMENTADDITIONSANDDEDUCTIONS`, EDIFACT 131 = "Summe aller
Beleg-Zu-/Abschläge") = Summe aller Positions-Zuschläge des Belegs.

**Bugfix nötig:** Die heutige FOOT-Berechnung (`OrderResponse.php:893-901`) summiert nur
`UNITCHARGEAMOUNT` — der ist bei **Prozent-Zuschlägen 0** (verifiziert an AWDESO000399:
`CHARGEPERCENTAGE=3, UNITCHARGEAMOUNT=0`). Korrekt: `LINEAMOUNT * CHARGEPERCENTAGE/100
+ FIXEDCHARGEAMOUNT` je Zeile (wie in der Positions-Berechnung Z. 697).

### 2.3 Grenze der Sofort-Lösung

`AdditionalLineAmount` transportiert nur den BETRAG. Beschreibung ("Teuerungszuschlag"),
Prozentsatz und Konditionstyp gehen erst mit der echten CNDL-Kondition (Abschnitt 3) durch.
Der Kunde kann den Zuschlag damit HERLEITEN (Betrag je Position + Belegsumme), aber nicht
den Grund lesen. (`LineTexts` als Text-Alternative fehlt im ORDRSP-Baum ebenfalls.)

## 2b. iwofurn-Feedback (2026-07-03) — Sofort-Lösung teilweise VERWORFEN

Antwort von iwofurn auf unsere Anfrage:
1. **FOOT-Ausweis gestrichen (2.2 entfällt in Teilen):** "Die Summe der Positions-Zuschläge
   oder generell positionale Konditionen gehören NUR in die Positionen und dürfen nicht im
   FOOT eingerechnet werden. Genauso Beleg-Konditionen — die werden nicht in den Positionen
   eingerechnet." → Der geplante FOOT-Eintrag (Qualifier 131 = Beleg-Zu-/Abschläge CNDF) ist
   für POSITIONS-Zuschläge semantisch falsch. Der FOOT-Berechnungs-Bugfix
   (`UNITCHARGEAMOUNT`-Problem) bleibt sinnvoll, aber nur für echte Beleg-Konditionen.
2. **`AdditionalLineAmount` 131 ist "meistens nicht Pflicht und auch nicht hinreichend":**
   Wenn Brutto- und Nettoeinzelpreis differieren, erwarten die Empfänger **mindestens ein
   CNDL** auf der Position. → Die Positions-Zuschläge MÜSSEN als CNDL-Kondition raus;
   `AdditionalLineAmount` allein genügt nicht (kann ergänzend bleiben).
3. **Alternative für Empfänger ohne Konditions-Verarbeitung:** Nettoeinzelpreis mit
   EINGERECHNETER Kondition senden — muss aber je Händler abgestimmt werden (Preis-Semantik!).
   Nur als Option je Empfänger, keine globale Lösung.

**Konsequenz:** Die Lobster-Baum-Erweiterung (CNDL, Abschnitt 3) ist nicht "sauberer
zweiter Schritt", sondern der EINZIGE tragfähige Weg → priorisieren. Unser Code sendet die
CNDL-Daten bereits; zusätzlich sollten wir den berechneten Betrag in die Kondition legen
(heute `Amount` = nur Fix-Anteil = 0 bei %-Zuschlägen, siehe 1b) — mit Lobster klären,
welches Feld im CNDL den Betrag trägt (`AmountOfCondition`).

## 3. Saubere Lösung: Lobster-Baum erweitern (Beauftragung)

An Lobster zu geben:
1. ORDRSP-Baum um `ITEMS/LineCharge` erweitern — Struktur identisch zum Invoice-Baum
   (`ConditionIndicator, ConditionLevel, Percent, Amount, VatPercentage, Description,
   TypeOfCondition`), Mapping auf das XML-`CNDL`-Segment. **Unser JSON sendet die Daten
   bereits heute** — es ist reine Baum+Mapping-Arbeit bei Lobster.
2. Im selben Zug: `ITEMS/LineTexts` und `HEAD/HeadTexts` ergänzen (senden wir ebenfalls,
   werden ebenso gedroppt).
3. Prüfen lassen, ob `AdditionalLineAmount` im Mapping wirklich auf `LINE/AdditionalLineAmount`
   durchgereicht wird (Baum kann es; Mapping-Ziel bestätigen — Voraussetzung für Abschnitt 2).

## 4. Empfehlung (AKTUALISIERT nach iwofurn-Feedback 2026-07-03)

1. **Lobster JETZT mit der CNDL-Erweiterung beauftragen** (Abschnitt 3) — laut iwofurn der
   einzige hinreichende Weg. Dabei klären, wie der berechnete Zuschlagsbetrag in die
   Kondition kommt (`AmountOfCondition`), damit nicht nur "3%" ankommt.
2. Optional ergänzend (nach Lobster-Freigabe): `AdditionalLineAmount` 131 je Position als
   Kontrollsumme — NICHT als Ersatz.
3. **Gestrichen & umgesetzt (Branch `edi-iwofurn-fixes`):** FOOT-Ausweis der Positions-Zuschläge entfernt (unzulässig laut iwofurn; alter Block nutzte zudem Qualifier 79 statt 131 und feuerte bei %-Zuschlägen nie).
4. Fallweise mit Händlern, die keine Konditionen verarbeiten: Einrechnung in den
   Nettoeinzelpreis abstimmen (Fachbereich-Entscheidung je Empfänger).

## 5. Set-Sonderfall (zur Einordnung für den Fachbereich)

Bei Set-Aufträgen (wie den beiden Beispielen) trägt nur der **Set-Kopf** den Zuschlag
(aggregiert); die Komponenten sind bewusst preislos (Einzelpreise geheim). Das bleibt auch
mit beiden Lösungen so — der Kunde sieht den Zuschlag auf der Set-Position, nicht auf den Teilen.

## 6. Offene Punkte

- [ ] GO für Sofort-Lösung (2.1 + 2.2 inkl. FOOT-Bugfix).
- [ ] Lobster: CNDL/LineTexts/HeadTexts-Erweiterung beauftragen; Mapping von
      `AdditionalLineAmount` bestätigen.
- [ ] Nach Lobster-Umstellung: prüfen ob `AdditionalLineAmount` zusätzlich zu `LineCharge`
      bleiben soll (redundant, aber EDIFACT-konform als Kontrollsumme 131).
