Eigene Zielvorlage entwickeln
Diese Seite richtet sich an Entwickler und Partner, die Breeze Interface um eine eigene Zielvorlage (Target Template) erweitern wollen. Sie beschreibt am durchgehenden Beispiel „Rechnung mit Bestellbezug“, wie ein Beleg statt der voreingestellten Zielvorlage eine eigene erhält und welche Verarbeitung beim Setzen des Status Processed ausgeführt wird.
Das Beispiel: Eine Rechnung kommt über Squeeze herein und wird wie gewohnt validiert. Ist im Belegkopf eine Bestellnummer eingetragen, soll nicht wie im Standard eine Einkaufsrechnung erstellt werden. Stattdessen soll die im Kopf hinterlegte Bestellung gebucht werden.
Welcher Weg ist der richtige?
Für eine eigene Belegerstellung gibt es zwei Wege. Sie schließen einander aus – wählen Sie vor Beginn den passenden:
| Eigene Zielvorlage (diese Seite) | Ereignis OnDocumentCreation | |
|---|---|---|
| Einrichtung Zielvorlage | Ihre eigene Zielvorlage | Keine |
| Plausibilitätsprüfung durch Breeze | ja, mit den Schaltern der | nein |
| Mehrere Belegarten parallel | ja, eine Zielvorlage je Fall | nur eine Implementierung für alle Belege |
| Geeignet für | Standard-Einkaufsbelege abweichend behandeln – etwa eine Bestellung buchen statt eine Rechnung anzulegen | Belege in vollständig eigene Tabellen schreiben |
Wollen Sie in eigene Tabellen schreiben und benötigen die Prüfungen von Breeze nicht, folgen Sie stattdessen der Seite Leitfaden zur Implementierung einer individuellen Belegerstellung. Für das hier beschriebene Beispiel ist dieser Weg nicht geeignet: Er setzt die Zielvorlage Keine voraus und umgeht damit die Plausibilitätsprüfung, die eine Rechnung mit Bestellbezug gerade braucht.
Der Standardablauf
Ein Beleg durchläuft von Squeeze bis zum Zielbeleg in Business Central diese Stationen:
- Squeeze übergibt den Beleg an Core. Core legt einen Datensatz in der Tabelle
DXP Documentan. - Core ermittelt über die
BelegklasseDokumentenklasse (DXP Document Class) den nächstenVerarbeitungsschritt.Prozessschritt. Steht dieser auf Breeze Interface, wird ein Breeze-Beleg (DXP BRZ IF Document) erzeugt. - Beim Anlegen erhält der Breeze-Beleg seine Zielvorlage aus der Einrichtung der
BelegklasseDokumentenklasse – Feld Zielvorlage auf der SeiteBelegklassenDokumentenklassen-Einrichtung. - Der Beleg wird im externen Workflow bearbeitet und kommt mit dem Status Processed zurück.
- Breeze Interface löst daraufhin die zur Zielvorlage hinterlegte Implementierung aus. Diese prüft den Beleg auf Plausibilität und übergibt ihn an Core, das den Zielbeleg erzeugt.
Technisch ist die Zielvorlage ein Enum, das ein Interface implementiert:
DXP Breeze IF Target Template– das Enum der Zielvorlagen,Extensible = true.DXP BRZIF IDocument Processing– das Interface, das jede Zielvorlage implementiert. Es besitzt genau eine Methode:procedure ProcessDocument(var BREEZEDoc: Record "DXP BRZ IF Document"; JObject: JsonObject)
Im Auslieferungszustand sind diese Zielvorlagen enthalten:
| Wert | Zielvorlage | Implementierung |
|---|---|---|
| 0 | DXP BRZ Default Processing | |
| 1 | Einkaufsbeleg (Purchase | DXP BRZ IF PInv/Crdt Memo Proc |
| 2 | Einkaufsbestellung (Purchase | DXP BRZ IF Purch. Order Proc. |
| 3 | Auftragsbestätigung (Order | DXP BRZ IF Order Conf. Proc. |
| 4 | Lieferschein (Delivery | DXP BRZ IF Del. Note Proc. |
{add screenshot of Belegklassen Dokumentenklassen-Einrichtung here}
Voraussetzungen
- Eine eigene Extension mit Abhängigkeit auf DEXPRO Breeze Interface (App-Id
7c431886-108e-44c3-9328-30e2b93edfa6) und – überpropagateDependenciesmitgeliefert – auf DEXPRO Core. - Ein eigener Objekt-ID-Bereich. Verwenden Sie nicht den Bereich von Breeze Interface (70954950–70954969) oder Core (70954575–70954624).
- Ein eigener Objektnamen-Affix, den Ihre
AppSourceCop.jsonvorschreibt.
Verwenden Sie für Ihre Objekte niemals das Affix DXP. Es ist für die DEXPRO-Apps reserviert. In den Codebeispielen dieser Seite steht XYZ stellvertretend für Ihr eigenes Affix.
Schritt 1 – Zielvorlage als Enum-Erweiterung anlegen
Das Enum DXP Breeze IF Target Template ist erweiterbar. Legen Sie einen neuen Wert an und verweisen Sie mit Implementation auf Ihre eigene Codeunit:
enumextension 50100 "XYZ Target Template Ext." extends "DXP Breeze IF Target Template"
{
value(50100; "XYZ Post Purchase Order")
{
Caption = 'Bestellung buchen';
Implementation = "DXP BRZIF IDocument Processing" = "XYZ Post Purch. Order Proc.";
}
}
Der Enum-Wert wird auf dem Breeze-Beleg und auf dem Core-Beleg gespeichert. Ändern Sie die Nummer nach dem ersten Produktiveinsatz nicht mehr – bereits gespeicherte Belege würden sonst auf eine andere Zielvorlage zeigen.
Schritt 2 – Die Standardzielvorlage überschreiben
Die Zielvorlage wird beim Anlegen des Breeze-Belegs aus der Belegklassen-Dokumentenklassen-Einrichtung gelesen. Um sie fallabhängig zu übersteuern, abonnieren Sie das Ereignis OnAfterFillDocumentInfo der Codeunit DXP BRZ IF Document Mgt.. Es wird gerufen, während der Breeze-Beleg aus dem JSON gefüllt wird – also bevor er eingefügt ist:
codeunit 50100 "XYZ Breeze Doc. Subscribers"
{
[EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP BRZ IF Document Mgt.", 'OnAfterFillDocumentInfo', '', false, false)]
local procedure SetTargetTemplateOnOrderReference(var BrzIfDoc: Record "DXP BRZ IF Document"; JsonData: JsonObject)
var
CoreTokenMgt: Codeunit "DXP Core Token Mgt.";
JsonHelper: Codeunit "DXP Json Helper";
OrderNo: Code[20];
begin
// Nur Belege umleiten, die im Standard zur Einkaufsrechnung fuehren.
if BrzIfDoc."Target Template" <> BrzIfDoc."Target Template"::"Purchase Document" then
exit;
OrderNo := CopyStr(JsonHelper.ValAsTxt(JsonData, CoreTokenMgt.GetOrderNoTok(), false), 1, MaxStrLen(OrderNo));
if OrderNo = '' then
exit;
BrzIfDoc."Target Template" := BrzIfDoc."Target Template"::"XYZ Post Purchase Order";
end;
}
Die Bestellnummer steht im Belegkopf-JSON unter dem Token orderNo. Lesen Sie sie ausschließlich über DXP Core Token Mgt. aus – die Token-Namen sind dort zentral gepflegt.
Das zweite Argument von ValAsTxt ist EnsureSuccess. Übergeben Sie hier false: Die Bestellnummer ist ein optionales Feld, und bei true würde ein fehlendes Token einen Laufzeitfehler auslösen.
Die Zielvorlage im Core-Beleg nachziehen
Core führt im Feld Breeze Interface Target TemplateZielvorlage der Tabelle DXP Document eine Kopie der Zielvorlage mit. Setzt Ihr Abonnent die Zielvorlage um, aktualisieren Sie dieses Feld mit – sonst zeigt der Core-Beleg weiter die alte Vorlage an. Ihre eigene Verarbeitung aus Schritt 3 erledigt das (siehe CoreDoc.Validate("DXP Breeze IF Target Template", ...) im Beispiel unten).
Schritt 3 – Die Verarbeitung implementieren
Wird der Breeze-Beleg auf Processed gesetzt, ruft Breeze Interface die zur Zielvorlage hinterlegte Implementierung auf:
IDocumentProcessing := Rec."Target Template";
IDocumentProcessing.ProcessDocument(Rec, JsonHelper.JObjectFromBlob(Rec.RecordId, Rec.FieldNo(JSON)));
Ihre Codeunit implementiert dafür DXP BRZIF IDocument Processing. Sie ist verantwortlich für:
- Prüfen des Belegs – im Fehlerfall den Breeze-Beleg auf Status Error setzen und die Meldungen in das JSON schreiben.
- Übergeben an Core über
DXP Document Mgt.UpdateDocument, wenn der Beleg gültig ist. - Löschen des Breeze-Belegs nach erfolgreicher Übergabe. Der Core-Beleg bleibt als Nachweis bestehen.
codeunit 50101 "XYZ Post Purch. Order Proc." implements "DXP BRZIF IDocument Processing"
{
procedure ProcessDocument(var BREEZEDoc: Record "DXP BRZ IF Document"; JObject: JsonObject)
var
CoreDoc: Record "DXP Document";
CoreDocMgt: Codeunit "DXP Document Mgt.";
ValidDoc: Boolean;
begin
ValidDoc := CheckDocument(JObject);
if not ValidDoc then begin
BREEZEDoc.Validate(Status, "DXP Breeze IF Status"::Error);
BREEZEDoc.Modify(false);
exit;
end;
CoreDocMgt.UpdateDocument(
BREEZEDoc."Core Document No.",
"DXP Document Status"::Transferred,
"DXP Target Document Process"::"XYZ Post Purchase Order",
JObject);
CoreDoc.Get(BREEZEDoc."Core Document No.");
CoreDoc.Validate("DXP Breeze IF Target Template", BREEZEDoc."Target Template");
CoreDoc.Modify(true);
BREEZEDoc.Delete(true);
end;
}
Als Vorlage für Plausibilitätsprüfungen dient die ausgelieferte Codeunit DXP BRZ IF PInv/Crdt Memo Proc. Nutzen Sie DXP Plausiblity Check Mgt. für die Prüfungen und DXP BRZ IF Target Templ. Mgt., um die Einrichtung Ihrer Zielvorlage zu lesen – damit greifen die Schalter Betragsprüfung deaktivieren und BuchungsdatumsprüfungBuchungsdatum deaktivierennicht prüfen auch für Ihre Vorlage.
Schritt 4 – Den Zielbeleg in Core erzeugen
Die Zielvorlage in Breeze bestimmt welche Prüfung läuft. Welcher Zielbeleg entsteht, entscheidet ein zweites Enum in Core: DXP Target Document Process, ebenfalls Extensible = true, mit dem Interface DXP IDocument Processing.
Die beiden Enums sind getrennt und müssen beide erweitert werden. Die Breeze-Zielvorlage wählt die Prüfung, der Core-Zielbelegprozess die Belegerstellung. Der Wert wird von Ihrer Verarbeitung aus Schritt 3 an UpdateDocument übergeben.
enumextension 50101 "XYZ Target Doc. Process Ext." extends "DXP Target Document Process"
{
value(50100; "XYZ Post Purchase Order")
{
Caption = 'Bestellung buchen';
Implementation = "DXP IDocument Processing" = "XYZ Post P. Order Creation";
}
}
Das Interface DXP IDocument Processing hat eine Methode, die die RecordId des erzeugten Belegs zurückgibt. Core speichert sie im Feld Linked-toVerknüpfte Record IdDatensatz-ID des Core-Belegs:
procedure ProcessStandardDocument(JObject: JsonObject): RecordId
Ihre Implementierung liest die Bestellnummer aus dem Kopf, holt die Bestellung und bucht sie:
codeunit 50102 "XYZ Post P. Order Creation" implements "DXP IDocument Processing"
{
procedure ProcessStandardDocument(JObject: JsonObject): RecordId
var
PurchaseHeader: Record "Purchase Header";
PurchInvHeader: Record "Purch. Inv. Header";
CoreTokenMgt: Codeunit "DXP Core Token Mgt.";
JsonHelper: Codeunit "DXP Json Helper";
TargetDocumentMgt: Codeunit "DXP Target Document Mgt.";
PurchPost: Codeunit "Purch.-Post";
DocRecRef: RecordRef;
OrderNo: Code[20];
VendorNo: Code[20];
begin
OrderNo := CopyStr(JsonHelper.ValAsTxt(JObject, CoreTokenMgt.GetOrderNoTok(), true), 1, MaxStrLen(OrderNo));
VendorNo := CopyStr(JsonHelper.ValAsTxt(JObject, CoreTokenMgt.GetVendorNoTok(), true), 1, MaxStrLen(VendorNo));
PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Order);
PurchaseHeader.SetRange("No.", OrderNo);
PurchaseHeader.SetRange("Buy-from Vendor No.", VendorNo);
PurchaseHeader.FindFirst();
// Rechnungsdaten aus dem JSON in die Bestellung uebernehmen
// (Belegdatum, Buchungsdatum, Externe Belegnummer, zu berechnende Mengen)
UpdatePurchaseHeaderFromJson(JObject, PurchaseHeader);
PurchPost.SetSuppressCommit(true);
PurchPost.Run(PurchaseHeader);
DocRecRef.Get(PurchaseHeader.RecordId());
TargetDocumentMgt.SetProcessedCompletely(DocRecRef);
PurchInvHeader.SetRange("Order No.", OrderNo);
if PurchInvHeader.FindLast() then
exit(PurchInvHeader.RecordId());
exit(PurchaseHeader.RecordId());
end;
}
Geben Sie niemals eine leere RecordId zurück. Core prüft den Rückgabewert; bleibt er leer, bricht die Verarbeitung mit einer Fehlermeldung ab.
Vollständig verarbeitet kennzeichnen
Core erweitert die Tabelle Einkaufskopf um das Feld CompletelyVollständig Processedverarbeitet. Setzen Sie es über DXP Target Document Mgt.SetProcessedCompletely, sobald der Beleg fertig verarbeitet ist. Die ausgelieferten Implementierungen tun das ebenfalls; das Feld steuert die Anzeige und die nachgelagerte Verarbeitung.
Wenn die Bestellung gebucht wird
Beim Buchen entsteht ein neuer Beleg – die gebuchte Einkaufsrechnung –, während die Bestellung je nach Restmenge gelöscht wird. Verweisen Sie deshalb im Rückgabewert auf den gebuchten Beleg, wie im Beispiel oben. Zeigt Linked-toVerknüpfte Record IdDatensatz-ID auf eine gelöschte Bestellung, läuft der Absprung vom Core-Beleg ins Leere.
Die Einrichtung der Zielvorlage
Zu jeder Zielvorlage gehört ein Datensatz in der Tabelle DXP BRZ IF Target Templ. Setup, sichtbar auf der Seite Zielvorlagen Zielvorlagen-Einrichtung. Er wird beim ersten Zugriff automatisch angelegt. Diese Schalter stehen zur Verfügung:
- Betragsprüfung deaktivieren – unterdrückt den Abgleich von Kopf- und Zeilenbeträgen.
BuchungsdatumsprüfungBuchungsdatumdeaktivierennicht prüfen – unterdrückt die Prüfung des Buchungsdatums.LieferantGesperrtengesperrtKreditoren (Zahlung) ignorieren – lässt Belege gesperrterLieferantenKreditoren zu.- Nicht freigeben – unterdrückt die automatische Freigabe des Zielbelegs.
Sollen für Ihre Zielvorlage andere Vorgabewerte gelten als die leeren Standardwerte, setzen Sie sie beim Anlegen. Die Codeunit DXP BRZ IF Target Templ. Mgt. tut das für die ausgelieferten Vorlagen; für eigene Vorlagen abonnieren Sie den OnInsert-Trigger der Tabelle.
{add screenshot of Zielvorlagen Zielvorlagen-Einrichtung here}
Checkliste
| Schritt | Objekt | Zweck |
|---|---|---|
| 1 | enumextension auf DXP Breeze IF Target Template | Die eigene Zielvorlage bekannt machen |
| 2 | Abonnent auf OnAfterFillDocumentInfo | Die Standardzielvorlage fallabhängig überschreiben |
| 3 | codeunit implements DXP BRZIF IDocument Processing | Prüfen und an Core übergeben |
| 4 | enumextension auf DXP Target Document Process | Den eigenen Zielbelegprozess bekannt machen |
| 5 | codeunit implements DXP IDocument Processing | Den Zielbeleg erzeugen – hier: die Bestellung buchen |
| 6 | Prüfen, dass der nächste |
Fehlersuche
| Beobachtung | Ursache |
|---|---|
| Der Beleg behält die alte Zielvorlage. | Der Abonnent aus Schritt 2 greift nicht. Prüfen Sie, ob die orderNo im Kopf-JSON gefüllt ist. |
| Beim Setzen auf Processed läuft die Standardverarbeitung. | Der Implementation-Verweis im Enum fehlt. Ohne ihn greift die DefaultImplementation des Enums, also DXP BRZ Default Processing. |
| Meldung Document creation failed. RecordId is empty. | Ihre ProcessStandardDocument-Implementierung hat keine RecordId zurückgegeben. |
| Der Absprung vom Core-Beleg öffnet nichts. | |
| Der Beleg steht auf Error, ohne dass eine Meldung erscheint. | Ihre Verarbeitung setzt den Status, schreibt aber keine Prüfmeldungen in das JSON. Nutzen Sie DXP Document Transfer Mgt.AddErrorsToJson. |
Verwandte Themen
ZielvorlagenZielvorlagen-Einrichtung – die Schalter je ZielvorlageBelegklassenDokumentenklassen-Einrichtung – Zuordnung vonBelegklasse,Dokumentenklasse, nächstemVerarbeitungsschrittProzessschritt und Zielvorlage- Breeze
InterfaceBelege – die Belegliste und ihre Status - Leitfaden zur Implementierung einer individuellen Belegerstellung – der alternative Weg über
OnDocumentCreationfür eigene Belegtabellen - Breeze Interface API – Rückmeldung des Belegs aus dem externen Workflow