# Events nach der Erstellung eines SQUEEZE-Belegs (CreateSource)

## Zielgruppe

Diese Dokumentation richtet sich an Drittanbieter-Entwickler, die den **Erstellungsprozess eines SQUEEZE-Belegs** (Tabellen `DXP SQZ Document Header`/`DXP SQZ Document Line`) erweitern möchten.

Im Fokus stehen die **Integration Events**, die *nach* bzw. *während* `ISourceDocument.CreateSource(...)` ausgelöst werden.

## Einordnung: Wo wird `CreateSource` aufgerufen?

Der Einstiegspunkt für die SQUEEZE-Integration ist in der Codeunit **`DXP SQZ API Mgt.`**:

- Es wird ein Core-Beleg (`DXP Document`) angelegt (über `DXP Document Mgt.`).
- Anschließend wird über die Dokumentenklasse das Interface **`DXP ISource Document`** aufgelöst und `CreateSource(Document)` ausgeführt.

Vereinfachter Ablauf (aus `CreateCoreAndSQUEEZEDocument`):

1. `DocumentMgt.AddDocument(DocClass, ...)` (Core-Beleg anlegen)
2. `ISourceDocument.CreateSource(Document)` (SQUEEZE-Beleg erzeugen)
3. Import-Queue verarbeiten / SQUEEZE-Dokument „finishen“

## Dokumentenklassen &amp; Default-Verhalten

Welche `CreateSource`-Implementierung ausgeführt wird, ist in der Enum-Erweiterung **`DXP Document Class Ext.`** hinterlegt.

- **`DXP Invoice / Credit Memo`** → Codeunit **`DXP SQZ P. Inv/Crdt Memo Impl.`**
- **`DXP Order Confirmation`** → Codeunit **`DXP SQZ P. Order Conf. Impl.`**

**Default (wenn keine spezifische Implementierung gesetzt ist):** Die Enum `DXP Document Class` definiert eine `DefaultImplementation` auf **`DXP Source Document Def. Impl.`**. Diese Default-Implementierung:

- erzeugt **keinen** SQUEEZE-Beleg,
- `CreateSource(...)` gibt **`false`** zurück.

## Gemeinsame Pipeline innerhalb `CreateSource`

Beide SQUEEZE-Implementierungen folgen (verkürzt) diesem Muster:

1. Guard: Core-Dokument muss `Status = Imported` haben und `JSON Raw` muss existieren.
2. `DXP SQZ Document Mgt.`: 
    - `CreateSQUEEZEDocHeader(Document, DocHeader, RawJson)`
    - `CreateSQUEEZEDocLine(DocHeader, RawJson)`
3. `DXP Document Mgt.`: `UpdateDocumentAfterTransfer(...)` (Core-Dokument auf „Transferred“ setzen und mit SQZ-Header verknüpfen)
4. Ordermatch / Autocomplete / Attachments / Validierung (abhängig von Dokumentenklasse und Setup)

Die wichtigsten Events hängen daher an:

- der Header-/Line-Erzeugung in `DXP SQZ Document Mgt.`
- dem Abschluss der `CreateSource`-Prozedur in den jeweiligen Implementierungen
- optionalen Schritten wie Ordermatch oder Validierung

## Event-Matrix (Kurzüberblick)

<table id="bkmrk-bereich-event-zeitpu"><thead><tr><th>Bereich</th><th>Event</th><th>Zeitpunkt</th><th>Steuerung</th><th>Typische Use-Cases</th></tr></thead><tbody><tr><td>`DXP SQZ API Mgt.`</td><td>[`OnAfterInitMapping(...)`](https://docs.squeeze.one/link/939#bkmrk-onafterinitmapping)</td><td>nach Initialisierung Mapping/Token-Kontext</td><td>–</td><td>Mapping erweitern/prüfen</td></tr><tr><td>`DXP SQZ API Mgt.`</td><td>[`OnAfterSaveAttachment(...)`](https://docs.squeeze.one/link/939#bkmrk-onaftersaveattachmen)</td><td>nach erfolgreichem Speichern eines Attachments</td><td>–</td><td>Nachverarbeitung/Indexierung</td></tr><tr><td>`DXP SQZ API Mgt.`</td><td>[`OnAfterSetOriginFileNameOnBeforeModifyDocumentAttachment(...)`](https://docs.squeeze.one/link/939#bkmrk-onaftersetoriginfile)</td><td>vor dem Modify des Attachment-Datensatzes</td><td>–</td><td>Dateiname/Origin beeinflussen</td></tr><tr><td>`DXP SQZ P. Inv/Crdt Memo Impl.`</td><td>[`OnAfterCreateDocLines`](https://docs.squeeze.one/link/939#bkmrk-onaftercreatedocline)</td><td>direkt nach `CreateSQUEEZEDocLine(...)`</td><td>–</td><td>Lines/RawJson nach Anlage auswerten</td></tr><tr><td>`DXP SQZ P. Inv/Crdt Memo Impl.`</td><td>[`OnAfterCreateSource`](https://docs.squeeze.one/link/939#bkmrk-onaftercreatesource)</td><td>am Ende von `CreateSource(...)`</td><td>–</td><td>Post-Aktionen nach Autocomplete/Ordermatch/Validierung</td></tr><tr><td>`DXP SQZ P. Inv/Crdt Memo Impl.`</td><td>[`OnBeforeDoPlausibilityChecks`](https://docs.squeeze.one/link/939#bkmrk-plausibilit%C3%A4tspr%C3%BCfun)</td><td>vor Plausibilitätschecks</td><td>`IsHandled`</td><td>Checks ersetzen/erweitern</td></tr><tr><td>`DXP SQZ P. Inv/Crdt Memo Impl.`</td><td>[`OnAfterDoPlausibilityChecks`](https://docs.squeeze.one/link/939#bkmrk-plausibilit%C3%A4tspr%C3%BCfun)</td><td>nach Plausibilitätschecks</td><td>–</td><td>Ergebnis weiterverwenden (Entries)</td></tr><tr><td>`DXP SQZ P. Order Conf. Impl.`</td><td>[`OnBeforeDoPlausibilityChecks`](https://docs.squeeze.one/link/939#bkmrk-plausibilit%C3%A4tspr%C3%BCfun-0)</td><td>vor Plausibilitätschecks</td><td>`IsHandled`</td><td>Checks ersetzen/erweitern</td></tr><tr><td>`DXP SQZ Document Mgt.`</td><td>[`OnBeforeModifySQUEEZEDocumentHeader`](https://docs.squeeze.one/link/939#bkmrk-onbeforemodifysqueez)</td><td>in `CreateSQUEEZEDocHeader(...)` vor finalem Modify</td><td>–</td><td>Headerwerte aus `RawJson` ergänzen/normalisieren</td></tr><tr><td>`DXP SQZ Document Mgt.`</td><td>[`OnBeforeTransferRecognizedValuesOnAfterAssignRecognizedValues`](https://docs.squeeze.one/link/939#bkmrk-onbeforetransferreco)</td><td>im Standard-Line-Post-Processing vor `TransferRecognizedValues`</td><td>–</td><td>erkannte Werte pro Line korrigieren</td></tr><tr><td>`DXP SQZ Document Mgt.`</td><td>[`OnAfterTransferRecognizedValuesOnBeforeInsertDocLine`](https://docs.squeeze.one/link/939#bkmrk-onaftertransferrecog)</td><td>im Standard-Line-Post-Processing nach `TransferRecognizedValues`</td><td>–</td><td>line-basierte Ableitungen (Kontierung/Dimensionen)</td></tr><tr><td>`DXP SQZ Document Mgt.`</td><td>[`OnBeforePerformAutomaticOrdermatch`](https://docs.squeeze.one/link/939#bkmrk-onbeforeperformautom)</td><td>vor automatischem Ordermatch</td><td>`IsHandled`</td><td>Ordermatch komplett übernehmen/OrderNoList anpassen</td></tr><tr><td>JSON-Erzeugung</td><td>[`OnBeforeAddLineToDocumentJObj`](https://docs.squeeze.one/link/939#bkmrk-onbeforeaddlinetodoc)</td><td>vor dem Aufbau der Line-Struktur</td><td>–</td><td>Header-JSON erweitern</td></tr><tr><td>JSON-Erzeugung</td><td>[`OnBeforeAddLineJObjToLineJArray`](https://docs.squeeze.one/link/939#bkmrk-onbeforeaddlinejobjt)</td><td>vor `LineJArray.Add(LineJObj)`</td><td>–</td><td>Line-JSON erweitern</td></tr></tbody></table>

---

## Events in `DXP SQZ P. Inv/Crdt Memo Impl.` (Dokumentenklasse: Invoice / Credit Memo)

Diese Codeunit bietet die **stärksten Erweiterungspunkte direkt im `CreateSource`-Ablauf**.

### `OnAfterCreateDocLines`

Wird direkt nach `CreateSQUEEZEDocLine(...)` ausgelöst (also nachdem Header &amp; Lines existieren).

Signatur:

```al
[IntegrationEvent(false, false)]
local procedure OnAfterCreateDocLines(DocHeader: Record "DXP SQZ Document Header"; RawJson: JsonObject)

```

Typische Use-Cases:

- zusätzliche Initialisierung am Header (z. B. eigene Flags/Felder)
- zusätzliche line-basierte Auswertungen direkt nach Anlage
- eigene Metadaten aus `RawJson` extrahieren

### `OnAfterCreateSource`

Wird am Ende von `CreateSource(...)` ausgelöst (nach Autocomplete/Ordermatch/optionalem Attachment-Download/optionalem Auto-Validate).

Signatur:

```al
[IntegrationEvent(false, false)]
local procedure OnAfterCreateSource(DocHeader: Record "DXP SQZ Document Header"; RawJson: JsonObject)

```

Typische Use-Cases:

- nachgelagerte Automatisierungen starten (Workflows, Benachrichtigungen)
- zusätzliche Datenvalidierung oder eigene Statuslogik

### Plausibilitätsprüfung-Events

Diese Events betreffen die Methode `IsSourceDataPlausible(...)` und sind relevant, wenn ihr Plausibilitätschecks erweitert/ersetzt.

Signaturen (Auszug):

```al
[IntegrationEvent(false, false)]
local procedure OnBeforeDoPlausibilityChecks(DocHeader: Record "DXP SQZ Document Header"; var TempPlausibilityCheckEntry: Record "DXP Plausibility Check Entry" temporary; var IsHandled: Boolean)

[IntegrationEvent(false, false)]
local procedure OnBeforeDoHeaderPlausibilityChecks(DocHeader: Record "DXP SQZ Document Header"; var PlausibilityCheck: Codeunit "DXP Plausiblity Check Mgt.")

[IntegrationEvent(false, false)]
local procedure OnBeforeDoLinePlausibilityChecks(DocHeader: Record "DXP SQZ Document Header"; DocLine: Record "DXP SQZ Document Line"; var PlausibilityCheck: Codeunit "DXP Plausiblity Check Mgt.")

[IntegrationEvent(false, false)]
local procedure OnAfterDoPlausibilityChecks(DocHeader: Record "DXP SQZ Document Header"; var TempPlausibilityCheckEntry: Record "DXP Plausibility Check Entry" temporary)

```

### JSON-Erzeugung (Processed JSON aus dem SQZ-Beleg)

Die Implementierung enthält Events, bevor Line-JSON zur Header-Struktur hinzugefügt wird:

#### `OnBeforeAddLineToDocumentJObj`

```al
[IntegrationEvent(false, false)]
local procedure OnBeforeAddLineToDocumentJObj(var DocumentJObj: JsonObject; DocHeader: Record "DXP SQZ Document Header")

```

#### `OnBeforeAddLineJObjToLineJArray`

```al

[IntegrationEvent(false, false)]
local procedure OnBeforeAddLineJObjToLineJArray(var LineJObj: JsonObject; DocLine: Record "DXP SQZ Document Line")

```

Use-Cases:

- zusätzliche Felder ins Header-JSON schreiben
- zusätzliche Felder pro Line ergänzen (Custom Tokens)

---

## Events in `DXP SQZ P. Order Conf. Impl.` (Dokumentenklasse: Order Confirmation)

Diese Codeunit hat **keine** dedizierten `OnAfterCreateSource`-Events in `CreateSource(...)`. Erweiterungen passieren hier typischerweise über:

- `DXP SQZ Document Mgt.` (Header/Line-Erzeugung, Ordermatch)
- die JSON-Erzeugung (`CreateProcessedJsonFromSource`)
- Plausibilitätsprüfung-Events

### JSON-Erzeugung

```al
[IntegrationEvent(false, false)]
local procedure OnBeforeAddLineToDocumentJObj(var DocumentJObj: JsonObject; DocHeader: Record "DXP SQZ Document Header")

[IntegrationEvent(false, false)]
local procedure OnBeforeAddLineJObjToLineJArray(var LineJObj: JsonObject; DocLine: Record "DXP SQZ Document Line")

```

### Plausibilitätsprüfung-Events

Analog zur Invoice/Credit-Memo-Implementierung:

- `OnBeforeDoPlausibilityChecks`
- `OnBeforeDoHeaderPlausibilityChecks`
- `OnBeforeDoLinePlausibilityChecks`
- `OnAfterDoPlausibilityChecks`

---

## Events in `DXP SQZ Document Mgt.` (gemeinsam für alle Dokumentenklassen)

Diese Events sind besonders relevant, weil sie **innerhalb** der Header/Line-Erzeugung und Ordermatch-Pipeline ausgelöst werden.

### `OnBeforeModifySQUEEZEDocumentHeader`

Wird in `CreateSQUEEZEDocHeader(...)` ausgelöst, nachdem Werte über Field Mapping zugewiesen wurden und **bevor** der Header final modifiziert wird.

Signatur:

```al
[IntegrationEvent(false, false)]
local procedure OnBeforeModifySQUEEZEDocumentHeader(var DocHeader: Record "DXP SQZ Document Header"; RawJson: JsonObject)

```

Use-Cases:

- Header-Felder anpassen, bevor Standard-Post-Processing läuft
- zusätzliche Werte aus `RawJson` in den Header übernehmen

### `OnBeforeTransferRecognizedValuesOnAfterAssignRecognizedValues`

### `OnAfterTransferRecognizedValuesOnBeforeInsertDocLine`

Werden im Standard-Line-Post-Processing (für Standard-Dokumentenklassen) um `TransferRecognizedValues(DocLine)` herum ausgelöst.

Signaturen:

```al
[IntegrationEvent(false, false)]
local procedure OnBeforeTransferRecognizedValuesOnAfterAssignRecognizedValues(var DocLine: Record "DXP SQZ Document Line"; RowJTok: JsonToken)

[IntegrationEvent(false, false)]
local procedure OnAfterTransferRecognizedValuesOnBeforeInsertDocLine(var DocLine: Record "DXP SQZ Document Line")

```

Use-Cases:

- erkannte Werte pro Line korrigieren/normalisieren
- zusätzliche Ableitungen (z. B. Kontierung, Dimensionen) vorbereiten

### `OnBeforePerformAutomaticOrdermatch`

Wird in `PerformAutomaticOrdermatch(...)` ausgelöst, nachdem die Order-Nummern-Liste (`OrderNoList`) gefüllt wurde und **bevor** der automatische Ordermatch läuft.

Signatur:

```al
[IntegrationEvent(false, false)]
local procedure OnBeforePerformAutomaticOrdermatch(DocHeader: Record "DXP SQZ Document Header"; var OrderNoList: List of [Code[20]]; var IsHandled: Boolean)

```

Use-Cases:

- automatische Ordermatch-Logik komplett übernehmen (`IsHandled := true`)
- OrderNoList anpassen (z. B. filtern/ergänzen)

---

## Events in `DXP SQZ API Mgt.` (kontextnah zur Anlage/Attachments)

Diese Events liegen „um“ die API-Kommunikation herum (z. B. Attachments).

### `OnAfterInitMapping`

Wird in `DownloadFieldMapping(...)` ausgelöst, **nachdem** die Dokumentenklasse über das Interface `DXP ISource Document` das Default-Mapping initialisiert hat (`ISourceDocument.InitFieldMapping(...)`) und **bevor** die Feldliste aus SQUEEZE in die BC-Field-Mapping-Strukturen synchronisiert wird.

Signatur:

```al
[IntegrationEvent(false, false)]
local procedure OnAfterInitMapping(var HeaderMapping: Dictionary of [Text, Integer]; var LineMapping: Dictionary of [Text, Integer]; DocClass: Enum "DXP Document Class")

```

Parameter:

- `HeaderMapping` / `LineMapping`: Dictionaries mit Default-Zuordnung **SQZ-Feldname → BC-Feldnr.** (über `var` veränderbar)
- `DocClass`: Dokumentenklasse, für die das Mapping geladen wird

Typische Use-Cases:

- zusätzliche (kundenspezifische) Feldnamen als Default-Mapping ergänzen
- Default-Mapping korrigieren (z. B. wenn sich SQZ-Feldnamen geändert haben)
- Mapping-Validierung/Logging je Dokumentenklasse

### `OnAfterSaveAttachment`

Wird in `SaveAttachments(...)` **pro Attachment** ausgelöst, nachdem das Attachment über `DXP Document Attachment Mgt.` angelegt wurde und – falls das Attachment als Origin-Datei markiert ist – nach dem `Modify(true)` des Datensatzes.

Signatur:

```al
[IntegrationEvent(false, false)]
local procedure OnAfterSaveAttachment(DocumentAttachment: Record "DXP Document Attachment")

```

Hinweis:

- `DocumentAttachment` wird **nicht** als `var` übergeben. Wenn ihr Felder am Datensatz persistent ändern möchtet, müsst ihr im Subscriber den Datensatz erneut laden und explizit `Modify(...)` ausführen.

Typische Use-Cases:

- Attachment extern indexieren/archivieren
- Metadaten ableiten (z. B. Klassifizierung nach MIME-Type/Dateiendung)
- Folgeprozesse triggern (z. B. OCR/Preview-Generierung in Drittsystem)

### `OnAfterSetOriginFileNameOnBeforeModifyDocumentAttachment`

Wird in `SaveAttachments(...)` ausgelöst, **wenn** das Attachment laut Payload als Origin-Datei markiert ist und nachdem `Is Source File` sowie `File Name` (Origin-Name) gesetzt wurden – aber **bevor** `DocumentAttachment.Modify(true)` aufgerufen wird.

Signatur:

```al
[IntegrationEvent(false, false)]
local procedure OnAfterSetOriginFileNameOnBeforeModifyDocumentAttachment(var DocumentAttachment: Record "DXP Document Attachment")

```

Typische Use-Cases:

- Origin-Dateinamen normalisieren (z. B. verbotene Zeichen entfernen, Namensschema erzwingen)
- zusätzliche Felder am Attachment setzen, bevor gespeichert wird

## Minimalbeispiele: EventSubscriber für `DXP SQZ API Mgt.`

Die folgenden Beispiele zeigen typische, **kleine** Erweiterungen. Passt Objekt-IDs/Namen an euren Namespace an.

```al
codeunit 50101 "My SQZ API Mgt. Subs"
{
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ API Mgt.", 'OnAfterInitMapping', '', false, false)]
    local procedure OnAfterInitMapping(var HeaderMapping: Dictionary of [Text, Integer]; var LineMapping: Dictionary of [Text, Integer]; DocClass: Enum "DXP Document Class")
    var
        SqzDocHeader: Record "DXP SQZ Document Header";
        SqzDocLine: Record "DXP SQZ Document Line";
    begin
        // Beispiel: neues SQZ-Feld als Default-Mapping ergänzen.
        // Wichtig: Der Integer-Wert ist die BC-Feldnr. des Ziel-Feldes (abhängig von eurem Mapping-Konzept).
        if not HeaderMapping.ContainsKey('my_custom_header_token') then
            HeaderMapping.Add('my_custom_header_token', SqzDocHeader.FieldNo("Vendor No."));

        if not LineMapping.ContainsKey('my_custom_line_token') then
            LineMapping.Add('my_custom_line_token', SqzDocLine.FieldNo(Description));
    end;

    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ API Mgt.", 'OnAfterSetOriginFileNameOnBeforeModifyDocumentAttachment', '', false, false)]
    local procedure OnAfterSetOriginFileNameOnBeforeModifyDocumentAttachment(var DocumentAttachment: Record "DXP Document Attachment")
    begin
        // Beispiel: Origin-Dateiname normalisieren (Whitespace entfernen).
        DocumentAttachment."File Name" := DelChr(DocumentAttachment."File Name", '=', ' ');
    end;

    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ API Mgt.", 'OnAfterSaveAttachment', '', false, false)]
    local procedure OnAfterSaveAttachment(DocumentAttachment: Record "DXP Document Attachment")
    begin
        // Beispiel: Nachverarbeitung anstoßen.
        // Falls ihr persistent am Attachment ändern wollt, könnt ihr den Parameter-Datensatz auch direkt modifizieren.
        // DocumentAttachment.Validate("Your Field", ...);
        // DocumentAttachment.Modify(true);
    end;
}

```