Skip to main content

Events beim Validieren eines SQUEEZE-Belegs (Aktion „Validieren")

Zielgruppe

Diese Dokumentation richtet sich an Drittanbieter-Entwickler, die eigene Logik ausführen möchten, wenn ein Anwender auf der Seite DXP SQZ Document v2 (Page 70954659) die Aktion Validieren auslöst – etwa zusätzliche eigene Prüfungen vor der Validierung, das Setzen weiterer Werte auf dem SQUEEZE-Beleg oder Folgeaktionen auf dem erzeugten Zielbeleg.

Die beschriebenen Events stehen ab SQUEEZE für Dynamics 365 BC Version 2.50 zur Verfügung.

Einordnung: Was passiert beim Klick auf „Validieren"?

Die Aktion Validieren ruft nacheinander zwei Routinen der Belegseite auf:

1) CheckPlausibility()

Führt die Plausibilitätsprüfung der jeweiligen Dokumentenklasse aus und aktualisiert die Plausibilitätseinträge im unteren Bereich der Seite. Diese Routine läuft nicht nur beim Klick auf Validieren, sondern nach nahezu jeder Feldänderung. Sie ist deshalb kein geeigneter Aufhängepunkt für „einmalig beim Validieren".

Für Erweiterungen der Prüfung selbst existieren die bereits dokumentierten Events OnBeforeDoPlausibilityChecksOnAfterDoHeaderPlausibilityChecksOnAfterDoLinePlausibilityChecks und OnAfterDoPlausibilityChecks.

2) FinishValidation()

Bricht mit einer Fehlermeldung ab, solange noch Plausibilitätseinträge offen sind, behandelt gegebenenfalls die Dublettenprüfung und ruft anschließend die Methode ValidateSQUEEZEDocument der Codeunit DXP SQZ Document Mgt. (70954632) auf. Dort werden der verarbeitete JSON erzeugt, der Core-Beleg (DXP Document) weiterverarbeitet, der Zielbeleg erstellt und der SQUEEZE-Beleg abgeschlossen.

Beide hier beschriebenen Events werden in DXP SQZ Document Mgt.ValidateSQUEEZEDocument ausgelöst. Damit greifen sie einheitlich für:

  • die Aktion Validieren auf DXP SQZ Document v2 (70954659),
  • die Aktion Validieren auf DXP SQZ Document (Generic) (70954670) und den älteren Belegseiten,
  • die automatische Validierung (z. B. aus der Verarbeitungswarteschlange).

Es gibt bewusst kein Event direkt an der Aktion. Wenn Sie zwischen manuellem Klick und automatischer Validierung unterscheiden möchten, werten Sie den Parameter AutomaticValidation aus.

Event-Matrix (Kurzüberblick)

Bereich Event Zeitpunkt Steuerung Typische Use-Cases
DXP SQZ Document Mgt. OnBeforeValidateSQUEEZEDocument Nach der Plausibilitäts- und Dublettenprüfung, bevor der verarbeitete JSON erzeugt und der Zielbeleg angelegt wird var IsHandled: Boolean bricht die Validierung ab; var DocHeader erlaubt Änderungen am Beleg Eigene Zusatzprüfungen mit Abbruch, Felder nachbefüllen, Freigabeworkflow anstoßen, externe Systeme abfragen
DXP SQZ Document Mgt. OnAfterValidateSQUEEZEDocument Nachdem der Core-Beleg verarbeitet und der Zielbeleg erstellt wurde, vor dem Validierungsdialog Kein Abbruch möglich Zielbeleg nachbearbeiten, eigene Protokolltabellen schreiben, Benachrichtigungen versenden, Drittsysteme informieren

Abgrenzung zu OnAfterWriteProcessedJsonToBlob

Für Logik nach der Validierung existiert bereits ein Core-Event, beschrieben auf der Seite Erstellung benutzerdefinierter Dokumente (Individuelle Verarbeitung):

[IntegrationEvent(false, false)]
local procedure OnAfterWriteProcessedJsonToBlob(var Document: Record "DXP Document"; var ProcessedJSONObj: JsonObject)

Es wird in der Codeunit DXP Document Mgt. (Core) ausgelöst, nachdem der verarbeitete JSON in den Core-Beleg geschrieben wurde – innerhalb des Validierungsvorgangs, also ebenfalls beim Klick auf Validieren.

  OnAfterWriteProcessedJsonToBlob (Core) OnAfterValidateSQUEEZEDocument (SQUEEZE)
Ausgelöst in DXP Document Mgt. DXP SQZ Document Mgt.
Gilt für alle Core-Belege – auch aus anderen DEXPRO-Quell-Apps. Sie müssen selbst auf die Dokumentenklasse filtern. ausschließlich SQUEEZE-Belege
Kontext DXP Document und der verarbeitete JSON zusätzlich der komplette DXP SQZ Document Header mit allen erkannten Werten, Bestellabgleich- und Splitting-Informationen
Manuell vs. automatisch nicht unterscheidbar über AutomaticValidation unterscheidbar
Zeitpunkt direkt nach dem Schreiben des JSON, noch innerhalb der Core-Verarbeitung am Ende der Validierung, nachdem der SQUEEZE-Beleg abgeschlossen wurde
JSON änderbar ja (var ProcessedJSONObj) nein

Empfehlung:

  • Sie möchten den verarbeiteten JSON noch verändern oder einen Beleg in die Individuelle Verarbeitung übernehmen → OnAfterWriteProcessedJsonToBlob.
  • Sie möchten SQUEEZE-spezifische Werte auswerten oder nur bei manueller Validierung reagieren → OnAfterValidateSQUEEZEDocument.
  • Sie möchten vor der Erstellung des Zielbelegs eingreifen oder die Validierung abbrechen → OnBeforeValidateSQUEEZEDocument. Dafür gibt es im Core keine Entsprechung.

OnBeforeValidateSQUEEZEDocument

[IntegrationEvent(false, false)]
local procedure OnBeforeValidateSQUEEZEDocument(var DocHeader: Record "DXP SQZ Document Header"; AutomaticValidation: Boolean; var IsHandled: Boolean)
Parameter Beschreibung
var DocHeader Der zu validierende SQUEEZE-Beleg. Änderungen an Feldern werden anschließend mitgeschrieben und fließen in den Zielbeleg ein.
AutomaticValidation false beim Klick auf Validierentrue bei automatischer Validierung.
var IsHandled Auf true gesetzt bricht die Validierung ab. Der SQUEEZE-Beleg bleibt unverändert offen.

Das Event wird ausgelöst, nachdem:

  • der Beleg neu gelesen wurde und weder den Status Gelöscht noch Abgelehnt hat,
  • bei automatischer Validierung die Plausibilitätsprüfung erfolgreich war,

und bevor der verarbeitete JSON erzeugt wird. Zu diesem Zeitpunkt existiert der Zielbeleg noch nicht.

OnAfterValidateSQUEEZEDocument

[IntegrationEvent(false, false)]
local procedure OnAfterValidateSQUEEZEDocument(DocHeader: Record "DXP SQZ Document Header"; CoreDocument: Record "DXP Document"; AutomaticValidation: Boolean)
Parameter Beschreibung
DocHeader Der validierte SQUEEZE-Beleg. Sein Status ist zu diesem Zeitpunkt bereits Gelöscht – das ist der reguläre Endzustand eines validierten Belegs und kein Fehler.
CoreDocument Der zugehörige Core-Beleg (DXP Document), inklusive Status und Linked-to Record Id des erstellten Zielbelegs.
AutomaticValidation false beim Klick auf Validierentrue bei automatischer Validierung.

Ob der Zielbeleg tatsächlich erstellt wurde, ermitteln Sie über den Core-Beleg:

  • CoreDocument.Status = CoreDocument.Status::Transferred – der Zielbeleg wurde erstellt, CoreDocument."Linked-to Record Id" verweist darauf.
  • CoreDocument.Status = CoreDocument.Status::"Custom Processing" – der Beleg wurde in die Individuelle Verarbeitung übergeben; ein Standard-Zielbeleg existiert nicht.

Wichtig: eigene Prüfungen gehören nicht in dieses Event

Für Prüfungen, die eine Validierung verhindern sollen, ist OnBeforeValidateSQUEEZEDocument der falsche Ort. Ein Error an dieser Stelle erscheint erst nach dem Klick auf Validieren als Dialog – der Anwender sieht das Problem also erst am Ende der Bearbeitung. Nutzen Sie stattdessen einen der beiden folgenden Wege. Beide sorgen dafür, dass das Problem als Plausibilitätseintrag angezeigt und die Aktion Validieren deaktiviert wird.

Weg 1 (ohne Entwicklung): Plausibilitätsregelgruppe

In der Dokumentenklassen-Einrichtung legen Sie unter Plausibilitätsregelgruppe Regeln an. Jede aktive und gültige Regel, deren Bedingungen zutreffen, beschreibt ein Problem und erzeugt automatisch einen Plausibilitätseintrag. Regeln, die sich auf die Belegzeilen beziehen, werden je Zeile ausgewertet, sodass der Eintrag auf die betroffene Zeile verweist.

Für Prüfungen wie „Shortcutdimensionscode 1 darf nicht leer sein" ist das der bevorzugte Weg – kein Code, keine Erweiterung, vom Anwender selbst pflegbar.

Weg 2 (mit Entwicklung): OnAfterDoPlausibilityChecks

Dieses Event wird von allen Dokumentenklassen mit var TempPlausibilityCheckEntry veröffentlicht und ist damit der zuverlässige Weg. Sie fügen Ihren Eintrag direkt in den temporären Datensatz ein:

codeunit 50100 "My SQZ Plausibility Checks"
{
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ P. Inv/Crdt Memo Impl.",
        'OnAfterDoPlausibilityChecks', '', false, false)]
    local procedure OnAfterChecks(DocHeader: Record "DXP SQZ Document Header"; var TempPlausibilityCheckEntry: Record "DXP Plausibility Check Entry" temporary)
    var
        CostCenterMissingLbl: Label 'Please enter a cost center.';
    begin
        if DocHeader."Shortcut Dimension 1 Code" <> '' then
            exit;

        AddEntry(TempPlausibilityCheckEntry, CostCenterMissingLbl, DocHeader.RecordId(), 0);
    end;

    local procedure AddEntry(var TempPlausibilityCheckEntry: Record "DXP Plausibility Check Entry" temporary; MessageText: Text; LinkedToRecId: RecordId; LookupPageId: Integer)
    var
        NewEntryNo: Integer;
    begin
        NewEntryNo := 1;
        TempPlausibilityCheckEntry.Reset();
        TempPlausibilityCheckEntry.SetCurrentKey("Entry No.");
        if TempPlausibilityCheckEntry.FindLast() then
            NewEntryNo := TempPlausibilityCheckEntry."Entry No." + 1;

        TempPlausibilityCheckEntry.Init();
        TempPlausibilityCheckEntry."Entry No." := NewEntryNo;
        TempPlausibilityCheckEntry.Text := CopyStr(MessageText, 1, MaxStrLen(TempPlausibilityCheckEntry.Text));
        TempPlausibilityCheckEntry."Linked to Record Id" := LinkedToRecId;
        TempPlausibilityCheckEntry."Lookup Page Id" := LookupPageId;
        if TempPlausibilityCheckEntry.Insert() then;
    end;
}

Das passende Publisher-Objekt richtet sich nach der Dokumentenklasse:

Dokumentenklasse Codeunit
Einkaufsrechnung / Gutschrift DXP SQZ P. Inv/Crdt Memo Impl.
Auftragsbestätigung DXP SQZ P. Order Conf. Impl.
Generische Dokumentenklassen DXP SQZ Document Mgt.

Setzen Sie Linked to Record Id und Lookup Page Id (für Zeilen: Page::"DXP SQZ Document Subform"), damit der Plausibilitätseintrag anklickbar wird und zum betroffenen Datensatz springt.

Alternative: OnAfterDoHeaderPlausibilityChecks

Mit PlausibilityCheck.AddPlausibilityCheckEntry(...) steht eine bequemere API zur Verfügung, die Ihnen das manuelle Einfügen in den temporären Datensatz erspart:

[EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ P. Inv/Crdt Memo Impl.",
    'OnAfterDoHeaderPlausibilityChecks', '', false, false)]
local procedure OnAfterHeaderChecks(DocHeader: Record "DXP SQZ Document Header"; var PlausibilityCheck: Codeunit "DXP Plausiblity Check Mgt.")
var
    CostCenterMissingLbl: Label 'Please enter a cost center.';
begin
    if DocHeader."Shortcut Dimension 1 Code" = '' then
        PlausibilityCheck.AddPlausibilityCheckEntry(CostCenterMissingLbl, 0);
end;

Für Zeilenprüfungen gilt OnAfterDoLinePlausibilityChecks analog; über die Überladung AddPlausibilityCheckEntry(Text; LinkedToRecId; LookupPageId) wird der Eintrag anklickbar.

Achtung bei der Dokumentenklasse Auftragsbestätigung: In DXP SQZ P. Order Conf. Impl. wurden OnBeforeDoHeaderPlausibilityChecksOnBeforeDoLinePlausibilityChecksOnAfterDoHeaderPlausibilityChecks und OnAfterDoLinePlausibilityChecks ursprünglich ohne var auf dem Parameter PlausibilityCheck veröffentlicht. Ein Subscriber erhält dort eine Kopie, sodass hinzugefügte Einträge verloren gehen. Verwenden Sie in dieser Dokumentenklasse ab Version 2.50 stattdessen die Varianten mit dem Suffix V2 – zum Beispiel OnAfterDoHeaderPlausibilityChecksV2. Sie sind signaturgleich zu den Events der übrigen Dokumentenklassen. Die alten Events bleiben erhalten, sind aber als veraltet markiert.

Beispiel 1: Werte vor der Übergabe an den Zielbeleg ergänzen

[EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ Document Mgt.",
    'OnBeforeValidateSQUEEZEDocument', '', false, false)]
local procedure OnBeforeValidateSetPostingDescription(var DocHeader: Record "DXP SQZ Document Header"; AutomaticValidation: Boolean; var IsHandled: Boolean)
begin
    if DocHeader."Posting Description" = '' then
        DocHeader."Posting Description" := CopyStr(DocHeader."Document Reference", 1, MaxStrLen(DocHeader."Posting Description"));
    // Kein Modify notwendig – der Beleg wird im Anschluss geschrieben.
end;

Zielbeleg nachbearbeiten: bitte die Core-Events verwenden

Wenn Sie den erzeugten Zielbeleg verändern möchten, ist keines der beiden Events auf dieser Seite der richtige Ort. Der Core stellt dafür Events bereit, die den Zielbeleg direkt übergeben – bei den meisten sogar als typisierten Purchase Header, sodass der Umweg über Linked-to Record Id und einen RecordRef entfällt. Diese Events sind auf der Seite Events nach der Erstellung eines Core-Belegs (DXP Document) beschrieben:

Zielbeleg Codeunit Event
Einkaufsrechnung / Gutschrift DXP P. Inv. CredMemo. Creation OnAfterProcessStandardDocument(JObject; DocRecRef)
Einkaufsbeleg allgemein DXP Document Transfer Mgt. OnAfterCreatePurchaseDoc(var JObject; PurchaseHeader)
Einkaufskopf DXP Document Transfer Mgt. OnAfterCreatePurchaseHeader(var JObject; PurchaseHeader)
Bestellung DXP P. Order Creation OnAfterCreatePurchaseOrder(var JObject; var PurchaseHeader)
Auftragsbestätigung DXP P. Order Confirmation OnAfterProcessStandardDocument(JObject; var PurchaseHeader)

OnAfterValidateSQUEEZEDocument ist erst dann die bessere Wahl, wenn Sie zusätzlich Werte aus dem DXP SQZ Document Header benötigen – etwa erkannte Werte, Bestellabgleich- oder Splitting-Informationen, die im JSON des Core-Belegs nicht enthalten sind.

Beispiel 2: Nur bei manueller Validierung reagieren

[EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ Document Mgt.",
    'OnAfterValidateSQUEEZEDocument', '', false, false)]
local procedure OnAfterValidateNotifyUser(DocHeader: Record "DXP SQZ Document Header"; CoreDocument: Record "DXP Document"; AutomaticValidation: Boolean)
var
    ValidatedMsg: Label 'Document %1 has been forwarded.', Comment = '%1 = SQUEEZE document no.';
begin
    if AutomaticValidation then
        exit;
    if not GuiAllowed() then
        exit;

    Message(ValidatedMsg, DocHeader."No.");
end;

Hinweise und Einschränkungen

  • Kein Dialog in der automatischen Verarbeitung. Prüfen Sie vor MessageConfirm oder Page.RunModal immer AutomaticValidation und GuiAllowed(). Andernfalls läuft die Verarbeitungswarteschlange auf einen Fehler.
  • OnBeforeValidateSQUEEZEDocument läuft nach der Plausibilitätsprüfung. Eigene Prüfungen, die in den Plausibilitätseinträgen der Seite erscheinen und die Aktion Validieren deaktivieren sollen, gehören stattdessen in OnAfterDoHeaderPlausibilityChecks bzw. OnAfterDoLinePlausibilityChecks.
  • IsHandled := true bricht vollständig ab. Es wird kein Zielbeleg erstellt, der Core-Beleg bleibt unverändert und der SQUEEZE-Beleg behält seinen Status. Der Anwender erhält keine Meldung – geben Sie bei Bedarf selbst eine aus.
  • Kein Event bei gelöschten oder abgelehnten Belegen. Hat der Beleg den Status Gelöscht oder Abgelehnt, wird die Validierung vorher beendet und keines der beiden Events ausgelöst.
  • OnAfterValidateSQUEEZEDocument läuft nach einem Commit. Ein Error in einem Subscriber macht die Validierung nicht rückgängig, sondern hinterlässt einen validierten Beleg mit einer Fehlermeldung für den Anwender.

Verwandte Seiten

  • Erstellung benutzerdefinierter Dokumente (Individuelle Verarbeitung)
  • Events nach der Erstellung eines SQUEEZE-Belegs (CreateSource)
  • Events nach der Erstellung eines Core-Belegs (DXP Document)
  • Regelbasierter nächster Prozessschritt (Belege in Individuelle Verarbeitung steuern)