Lebenszyklus¶
Eine DiWaSS-Verbringung durchläuft zwei aufeinander folgende Dokumenten-Lebenszyklen: zuerst die Notifizierung (Anmeldung und Genehmigung), nach erteilter Zustimmung das Movement (operative Durchführung). Beide haben eigene Zustände und eigene Stage-Sequenzen, sind aber kausal verknüpft — ein Movement kann nur zu einer konsentierten Notifizierung existieren.
Dieses Kapitel beschreibt die Zustände, die Choreographie und das Versandverfahren. Den Aufruf-Code findest du in Notification (Company) und Movement (Company).
Rechtsgrundlagen¶
Zwei EU-Rechtsakte sind maßgeblich, und die zweite wird häufig übersehen:
| Rechtsakt | Regelt |
|---|---|
| VO (EU) 2024/1157 (Abfallverbringungsverordnung) | Das Verfahren: wer notifiziert, wer zustimmt, welche Nachweise wann fällig sind |
| DVO (EU) 2025/1290 (Durchführungsverordnung) | Die technische Durchführung: Datenmodell, Vorgangsarten und vor allem die Authentifizierungspflichten in Artikel 14 |
Für eine Integration ist die Durchführungsverordnung die konkretere Quelle. Sie legt fest, welcher Beteiligte welchen Vorgang authentifizieren muss — das ist die Anforderung, die deine Anwendung technisch abbilden muss.
Stage-Vokabular¶
Eine Stage ist ein abgeschlossener Schritt im Dokumenten-Lebenszyklus. Im SDK entspricht ihr je eine Methode auf dem Document-Handler (SetCarrierTransport, SetFacilityReception, …), und jede folgt demselben Zwei-Phasen-Ablauf — siehe Versandverfahren.
Der Status kommt zurück, du schickst ihn nicht
DiWaSS-Dokumente tragen keinen Status im Mutations-Datenmodell. Ein selbst erzeugtes Movement trägt den Request-Typ (MovementTemplateType) — und der hat kein Status-Feld. Dasselbe bei Notifizierung und Annex VII: Mutations-Typen tragen Nutzdaten, den Status trägt nur die Retrieval-Sicht.
Dort ist er aber ein echtes, schema-beschränktes Feld — keine Konvention:
| Feld | Zulässige Werte |
|---|---|
notificationStatus |
DRAFT, SUBMITTED, SATISFIED, CONSENT, INVALID, WITHDRAWN, OBJECTED, CANCELLED |
movementStatus |
DRAFT, ANNOUNCED, SUBMITTED, MOVING, RECEIVED, ACCEPTED, REJECTED, COMPLETED, CANCELLED, TAKE_BACK |
Nutze diese Werte in deinem Code, nicht selbstgewählte Namen. Was in diesem Kapitel als Zwischenlage beschrieben wird — „Nachforderung offen”, „Änderungsantrag läuft” — ist kein eigener Statuswert, sondern wird aus dem Vorhandensein von Blöcken und aus den Followup-Intents abgeleitet. Siehe Zustand bestimmen.
Versandverfahren¶
Der Weg eines Dokuments aus dem SDK ins EU-System verläuft in zwei getrennten Phasen plus einer asynchronen Rückkopplung.
Phase 1 — SaveToZedal()¶
Das Dokument (ZeWaSS-XML) wird in ZEDAL persistiert. In diesem Zustand
- existiert es als adressierbare Version und lässt sich jederzeit zurückladen,
- ist es nicht an das EU-System übermittelt — es findet keine Außenkommunikation statt,
- kann es weiter bearbeitet, validiert oder verworfen werden, ohne dass DiWaSS davon Notiz nimmt.
SaveToZedal() ist der Persistenz-Anker. Erst auf einem persistierten Dokument kann der zweite Schritt erfolgen.
Phase 2 — SendToDiwass()¶
Löst den eigentlichen Versand aus. Der Aufruf kehrt zurück, sobald der Versand serverseitig zur Übermittlung angenommen ist — nicht erst nach Antwort des EU-Systems. Die Transfer-Log-Id steht anschließend in handler.LastTransferLogId.
Es gibt keinen Entwurfsstatus über die API
Was über die GUI ein Entwurf wäre, ist über die API bereits eingereicht: Eine per Schnittstelle erzeugte Notifizierung landet direkt im Status Submitted, ein Movement direkt in Announced. Es gibt keine Vorstufe zum Ausprobieren — jede Validierung greift beim ersten Aufruf, und ein fehlerhaft eingereichtes Dokument ist eingereicht.
Baue deine eigene Vorprüfung deshalb vor SendToDiwass() ein, nicht danach. Die Feldregeln beschreiben, worauf DiWaSS über das Schema hinaus besteht.
Phase 2b — WaitForDiwassTransfer() (optional)¶
Wartet auf die Empfangsbestätigung, indem der Transfer-Log-Status gepollt wird:
- Erfolg (
RECEIVED_RECEIPT_POSITIVEoderDELIVERED_TO_RECIPIENT_INBOX): kehrt regulär zurück. - Ablehnung (
RECEIVED_RECEIPT_NEGATIVEoderCANCELLED): wirftDiwassTransferFailedExceptionmit den Fehlerdetails. - Zeitüberschreitung: wirft
TimeoutException.
Das Warten ist eine lokale Schleife im SDK, kein Wire-Status am Dokument. Es ersetzt nicht die fachliche Antwort aus Phase 3.
Zeitbudget realistisch wählen
Diese Aufrufe dauern deutlich länger, als ein Netzwerk-Timeout vermuten lässt:
| Fall | Typische Dauer | Budget |
|---|---|---|
| Push ohne Anhang | etwa 1 Minute | 90 s reichen |
| Push mit Anhang | über 1,5 Minuten | mindestens 180 s |
| Movement-Kette, pro Stufe | 3 bis 5 Minuten | 180 s reichen nicht |
Der Client-Default des SDK liegt bei 30 Sekunden — für DiWaSS-Pfade zu knapp. Setz die Deadline pro Aufruf über den ZedalCallContext. Ein zu knappes Budget erzeugt Fehler, die wie Serverprobleme aussehen, aber reine Laufzeit sind.
Phase 3 — Asynchrone Antwort¶
Die fachliche Antwort des EU-Systems (Acknowledgement, Validierungsergebnis, Folge-Intents, neuer Status) trifft asynchron ein und wird als neue Version desselben Dokuments in ZEDAL abgelegt. Der DiWaSS-Output ist also kein Rückgabewert von SendToDiwass(), sondern eine spätere Version.
Daraus folgt:
- ein erfolgreiches
SendToDiwass()heißt „zur Übermittlung angenommen”, nicht „von DiWaSS bestätigt”; - ein erfolgreiches
WaitForDiwassTransfer()heißt „von DiWaSS angenommen”, sagt aber nichts über den fachlichen Ausgang; - der fachliche Ausgang erscheint erst in einer späteren Version;
- zu jeder Stage gehört ein eigener Versand- und Antwort-Zyklus.
Fremde Änderungen brauchen Zeit — und den Inbox-Import
Ein Update von außen (Behörden-Nachforderung, Decision, Antwort auf einen Änderungsantrag) erreicht den ZEDAL-Bestand nicht synchron. Rechne mit zwei bis drei Minuten, bis eine Änderung der Behörde in ZEDAL ankommt. Bis dahin liefert ein erneutes Laden das Ausgangsdokument mit leerer Intent-Liste — der Behörden-Block fehlt einfach.
Der Inbox-Import ist dabei der Zustellweg, nicht bloß ein Aufräumschritt: Ohne ihn erscheint die neue Version nicht im Dokumentenbestand. Wie du das sauber aufsetzt, steht unter Aufrufe und Synchronisation.
Zustand bestimmen¶
Weil das Dokument keinen Status mitführt, brauchst du einen anderen Weg. Es gibt genau einen richtigen:
Werte die Followup-Intents aus. Nach jedem Stage-Aufruf listet handler.FollowupIntents die Aktionen, die als Nächstes zulässig sind. Das ist eine Property, keine Methode. Die Liste kommt vom Server und bildet die Regeln ab, die dort gelten — du musst sie nicht nachbauen.
Daraus leitest du Schaltflächen, Sperren und Statusanzeigen ab. Zwei verbreitete Fehler:
Zustand nicht aus Listenlängen ableiten
Das Retrieval-Schema trennt zwei Listen: requestInformation für Nachforderungen der Behörde und replyRequestInformation für die Antworten des Notifizierenden. DiWaSS befüllt nur die erste. Beide Nachrichten — Nachforderung und Antwort — erscheinen als requestInformation-Einträge; die Antwort erkennt man daran, dass sie eine eigene replyRequestInformationId trägt und dieselbe requestInformationId wie die Nachforderung, auf die sie sich bezieht.
Wer „offen gegen beantwortet” über die Listenzugehörigkeit oder einen Längenvergleich der beiden Listen bestimmt, bekommt systematisch falsche Ergebnisse.
RECEIVED heißt nicht „angekommen”
Der Movement-Status ist eine Aggregation über die gesamte Anlagenkette, nicht der Zustand einer einzelnen Anlage. Die Spezifikation stellt die Übergänge ausdrücklich auf ein Ereignis:
ANNOUNCED/MOVING→RECEIVEDbeim ersten EmpfangszertifikatRECEIVED→COMPLETEDbeim Abschlusszertifikat
Da eine Notifizierung mehrere Anlagen führen kann (siehe Anlagenkette), bedeutet RECEIVED also „mindestens eine Anlage hat quittiert” — nicht „die Empfangsanlage hat” und erst recht nicht „alle haben”. Wer den Status als „wo liegt der Abfall gerade” liest, liegt bei Artikel-15-Ketten falsch.
Anlagenkette¶
Eine Notifizierung beschreibt nicht eine einzelne Empfangsanlage, sondern eine Kette. Das ist der Grund, warum es pro Movement mehrere Empfangs- und Abschlusszertifikate geben kann.
Geht eine Verbringung zur vorläufigen Verwertung oder Beseitigung, müssen nach Art. 15 Abs. 1 VO (EU) 2024/1157 alle nachgelagerten Anlagen zusätzlich zur ersten im Notifizierungsformular angegeben werden. Die Notifizierung führt also 1 + n Anlagen.
Welchen Weg eine Anlage nimmt, steht in drei Kennzeichen an der Anlage selbst (FacilityType.OperationalIndicators):
| Kennzeichen | Bedeutung | Folge |
|---|---|---|
InterimFacility |
Diese Anlage führt ein vorläufiges Verfahren durch | Die Kette geht weiter |
NextSubsequent…InSameCountry |
Weitergabe innerhalb des Bestimmungsstaats | Art. 15(5): keine neue Notifizierung, kein neues Movement. Der Nachweis kommt als Artikel-15-Bescheinigung zurück |
NextSubsequent…InAnotherCountry |
Weitergabe ins Ausland | Art. 15(7)/(8): neue Notifizierung mit eigenen Movements erforderlich |
Die letzte Zeile ist für Integratoren die folgenreichste: Im Auslandsfall endet der Vorgang nicht mit einer weiteren Bescheinigung, sondern es beginnt ein komplett neuer Notifizierungsvorgang.
Keine Verkettung im Datenmodell
Für die Neunotifizierung nach Art. 15(7)/(8) gibt es kein Feld, das auf die Vorgängerin verweist. referenceNotificationId ist trotz des Namens keine solche Referenz — es trägt die von der Versandbehörde vergebene Nummer des Dokuments selbst.
Wer die Kette über Landesgrenzen hinweg nachvollziehbar halten will, muss die Verbindung außerhalb von DiWaSS führen.
Aus der Kette folgen die Kardinalitäten im Retrieval: facilityReception und facilityCompletion sind unbegrenzt wiederholbar, consigneeReception steht auf genau einem Eintrag. Jedes Empfangszertifikat trägt selbst, welche Anlage es ausgestellt hat — im Movement-Announcement steht die Anlage noch nicht.
Die Artikel-15-Bescheinigung hängt dabei an der Notifizierung, nicht am Movement, und nennt über movementIdentifier mehrere Verbringungen: Eine Folgeanlage verarbeitet Material aus mehreren Transporten, deshalb ist die Beziehung n:m. Im SDK ist das SetFacilityCompletionUnderArticle15 auf dem NotificationDocumentHandler.
Notifizierung: Zustände¶
stateDiagram-v2
[*] --> SUBMITTED: CreateSubmission
SUBMITTED --> SUBMITTED: Nachforderung, Antwort, Update
SUBMITTED --> CONSENT: alle CAs erteilen Consent
SUBMITTED --> OBJECTED: eine CA widerspricht
CONSENT --> CONSENT: Änderungsantrag und Antworten
SUBMITTED --> CANCELLED: Stornierung
CONSENT --> CANCELLED: Stornierung
CONSENT --> WITHDRAWN: Transit-CA zieht zurück
SUBMITTED --> INVALID: CA erklärt ungültig
CANCELLED --> [*]
OBJECTED --> [*]
WITHDRAWN --> [*]
Vor dem Consent setzt die Versandbehörde das Signal ProperlyCarriedOut und die Bestimmungsbehörde ProperlyCompleted. Diese Signale sind Vorbedingung — sie stellen sicher, dass alle Beteiligten ihre Entscheidung auf demselben Stand bilden.
Notifizierung: Stage-Reihenfolge¶
Die Stage-Namen sind die SDK-Methoden. Company-Seite: NotificationDocumentHandler. Behördenseite: AuthorityNotificationDocumentHandler (siehe Authority). Signale laufen alle über dieselbe Methode SubmitNotificationSignal mit typisiertem Signal-Body.
| # | Stage | Akteur | Art. VO 2024/1157 | Vorbedingung | Wirkung |
|---|---|---|---|---|---|
| 1 | CreateSubmission |
Notifizierender | Art. 4 | — | Submission erstellt, NotificationId vergeben |
| 2 | SetRequestInformation |
eine Behörde | Art. 4(4) | Status SUBMITTED |
Nachforderung offen |
| 3a | SetSubmission |
Notifizierender | Art. 4(4) | offene Nachforderung | Submission aktualisiert |
| 3b | SetReplyToRequestInformation |
Notifizierender | Art. 4(4) | offene Nachforderung | Antwort erfasst |
| 4a | SubmitNotificationSignal (ProperlyCarriedOut) |
Versandbehörde | Art. 10 | alle Nachforderungen geschlossen | Bereitschaft signalisiert |
| 4b | SubmitNotificationSignal (ProperlyCompleted) |
Bestimmungsbehörde | Art. 10 | wie 4a | Bereitschaft signalisiert |
| 5 | SetDecision |
jede beteiligte Behörde einzeln | Art. 5 | 4a und 4b liegen vor | Konsentiert, sobald alle zugestimmt haben |
| 6 | SetRequestForChangeAfterConsent |
Notifizierender | Art. 7 | Status CONSENT |
Änderungsantrag offen |
| 7 | ReplyToRequestForChangeAfterConsent |
jede Behörde einzeln | Art. 7 | offener Änderungsantrag | Zustimmung oder Ablehnung |
| 8 | SubmitNotificationSignal (Stornierung) |
Notifizierender | Art. 6(2) | Status ≠ CANCELLED |
Notifizierung storniert |
| — | SetFacilityCompletionUnderArticle15 |
Anlage der Kette | Art. 15(5) | vorläufiges Verfahren abgeschlossen | Bescheinigung der Folgeanlage, bezieht sich auf mehrere Movements |
Die Entscheidung fällt N-fach, nicht einmal
Eine Verbringung berührt mindestens Versand- und Bestimmungsbehörde, bei Durchfuhr je Transitland eine weitere. Jede gibt ihre Entscheidung separat ab. Erst wenn alle zugestimmt haben, ist die Notifizierung konsentiert — eine fehlende Zustimmung blockiert den Übergang.
Welche Behörde als Durchfuhrbehörde überhaupt zulässig ist, sagt das Verzeichnis nicht. Siehe Feldregeln.
Das Änderungsfenster¶
Eine eingereichte Notifizierung ist nur änderbar, solange mindestens eine Nachforderung offen ist. Ohne offene Nachforderung gibt es im Status SUBMITTED keinen Weg, die Notifizierung noch zu korrigieren.
Drei Konsequenzen, die eine Anwendung tragen muss:
- Das Fenster hängt an „keine mehr offen”, nicht an „eine beantwortet”. Fordern zwei Behörden parallel nach, bleibt die Notifizierung nach der Antwort an die erste weiter änderbar. Es schließt sich mit der letzten Antwort — und öffnet sich wieder, wenn eine neue Nachforderung eingeht.
- Die Reihenfolge ist eine Einbahnstraße. Wer erst quittiert und dann merkt, dass er auch die Notifizierung anpassen muss, hat sich das Fenster selbst zugemacht. Vor dem Absenden der letzten offenen Antwort gehört deshalb eine Rückfrage in die Oberfläche — und solange nichts gesendet ist, muss sich ein Antwort-Entwurf verwerfen lassen.
- „Gesperrt” ist kein gespeicherter Zustand, sondern immer abgeleitet. Leite ihn aus den Followup-Intents ab, nicht aus einem eigenen Flag.
Movement: Zustände¶
stateDiagram-v2
[*] --> ANNOUNCED: CreateMovementTemplate
ANNOUNCED --> MOVING: SetCarrierTransport
MOVING --> RECEIVED: erstes Empfangszertifikat
RECEIVED --> RECEIVED: weitere Anlagen der Kette
RECEIVED --> COMPLETED: Abschlusszertifikat
ANNOUNCED --> TAKE_BACK: Rücknahme angeordnet
MOVING --> TAKE_BACK: Rücknahme angeordnet
RECEIVED --> TAKE_BACK: Rücknahme angeordnet
ANNOUNCED --> CANCELLED: Stornierung durch Notifizierenden
COMPLETED --> [*]
TAKE_BACK --> [*]
CANCELLED --> [*]
Movement: Stage-Reihenfolge¶
| # | Stage | Akteur | Art. VO 2024/1157 | Vorbedingung | Wirkung |
|---|---|---|---|---|---|
| 1 | CreateMovementTemplate |
Notifizierender | Art. 16 | konsentierte Notifizierung | Movement angelegt, MovementId vergeben |
| 2 | SetCarrierTransport |
Beförderer | Art. 16 | Status ANNOUNCED |
Fahrzeug, Abfahrt, Übernahme erfasst |
| 3 | SetConsigneeReception |
Empfänger | Art. 16 | Status MOVING |
Wareneingang bestätigt, Mengenbilanz |
| 4 | SetFacilityReception |
Anlage | Art. 16 | Empfang beim Consignee erfasst | Annahme in der Anlage bestätigt |
| 5 | SetFacilityCompletion |
Anlage | Art. 15 | Status RECEIVED |
Behandlung abgeschlossen, mit R-/D-Code |
| 6 | SetMovementTakeBack |
jede beteiligte Behörde | Art. 22 | Status ANNOUNCED, MOVING oder RECEIVED |
Rücknahme angeordnet; genau eine je Movement, aktualisierbar durch die einreichende Behörde |
| 7 | SubmitMovementSignal (Stornierung) |
Notifizierender | Art. 16 | Status DRAFT oder ANNOUNCED |
Movement storniert |
Der Standardpfad ist sequenziell: Stage n setzt voraus, dass n−1 erfolgreich gepusht wurde. Behördliche Eingriffe können ihn jederzeit beenden.
Stage 3 entfällt, wenn Empfänger und Anlage identisch sind
Sind Consignee und RecoveryDisposalFacility derselbe Betreiber, entfällt die Empfänger-Bestätigung; die Annahme wird in einem einzigen Aufruf in Stage 4 bestätigt. Der Status geht dann von MOVING direkt auf RECEIVED, ohne dass ein Consignee-Zertifikat vorliegt.
Mehrere Anlagen, mehrere Stränge
Weist die Notifizierung mehrere Anlagen aus, führt jede ihre eigenen Reception- und Completion-Stages durch. Abschluss und Annahme gehören dabei zusammen: Die Abschlussmeldung muss von derselben Anlage kommen, die auch die Annahme bestätigt hat.
Fristen¶
Die Verordnung setzt Fristen für die Eingangsbestätigung und für die Abschlussbescheinigung. Sie werden serverseitig geprüft; Verletzungen reicht das SDK als Validierungsfehler nach oben.
Die konkreten Fristenlängen entnimm dem geltenden Verordnungstext — sie unterscheiden sich zwischen dem Notifizierungsverfahren und dem Verfahren nach Anhang VII und hängen am jeweiligen Auslöseereignis.
„Werktag” bedeutet Montag bis Freitag
Der Verordnungsbegriff folgt nicht § 193 BGB, der den Samstag einschließt. Wer Fristen nach deutschem Rechtsverständnis berechnet, rechnet zu kurz. Das ist ein Einzeiler im Code — und eine überschrittene Frist, wenn er fehlt.
Was als Nächstes¶
- Notification (Company) — Stage für Stage mit Code
- Movement (Company) — Stage für Stage mit Code
- Rollen — wer welche Stage auslösen darf
- Aufrufe und Synchronisation — Aufruffrequenz, Fehlerbehandlung, Abgleich
- Fehlercodes — was eine Ablehnung bedeutet