# Leitfaden zur Implementierung der benutzerdefinierten Dokumentenerstellung
## Überblick
Diese Dokumentation bietet eine Anleitung zur Implementierung benutzerdefinierter Dokumentenerstellungsprozesse unter Verwendung des Integrationsereignisses `OnDocumentCreation` im DXP-Framework. Während die Standardimplementierung Einkaufsrechnungen erstellt, zeigt dieser Leitfaden, wie Sie Ihre eigene Dokumentenerstellungslogik mithilfe der bereitgestellten JSON-Daten implementieren können.
## Integrationspunkt
Der zentrale Integrationspunkt ist das `OnDocumentCreation`-Ereignis in Codeunit 70954599 "DXP Doc. Creation Def. Impl.". Dieses Ereignis wird während der Dokumentenverarbeitung ausgelöst und ermöglicht die Implementierung einer benutzerdefinierten Dokumentenerstellungslogik.
### Ereignis-Signatur
```al
[IntegrationEvent(false, false)]
local procedure OnDocumentCreation(JObject: JsonObject; var CreatedDocumentRecordId: RecordId)
```
### Parameter
- `JObject`: Enthält die vollständigen JSON-Daten mit den Dokumentinformationen
- `CreatedDocumentRecordId`: Muss mit der RecordId des erstellten Dokuments gesetzt werden
## Implementierungsleitfaden
### Schritt 1: Subscriber-Codeunit erstellen
Zunächst erstellen Sie eine Codeunit, die das OnDocumentCreation-Ereignis abonniert:
```al
codeunit 50100 "Custom Document Creation"
{
[EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP Doc. Creation Def. Impl.", 'OnDocumentCreation', '', false, false)]
local procedure OnDocumentCreation(JObject: JsonObject; var CreatedDocumentRecordId: RecordId)
begin
// Your implementation here
CreateCustomDocument(JObject, CreatedDocumentRecordId);
end;
}
```
### Schritt 2: Dokumentenerstellungslogik implementieren
Hier ein Beispiel für die Implementierung der benutzerdefinierten Dokumentenerstellung:
```al
local procedure CreateCustomDocument(JObject: JsonObject; var CreatedDocumentRecordId: RecordId)
var
CustomHeader: Record "Custom Document Header";
CustomLine: Record "Custom Document Line";
JsonHelper: Codeunit "DXP Json Helper";
HeaderJObject: JsonObject;
LinesJArray: JsonArray;
LineJToken: JsonToken;
LineNo: Integer;
begin
// 1. Create Header
CustomHeader.Init();
CustomHeader."Document Type" := GetDocumentType(JObject);
CustomHeader."Vendor No." := CopyStr(JsonHelper.ValAsTxt(JObject, 'vendorNo', true), 1, MaxStrLen(CustomHeader."Vendor No."));
CustomHeader."Document Date" := JsonHelper.ValAsDate(JObject, 'docDate', true);
CustomHeader."Posting Date" := JsonHelper.ValAsDate(JObject, 'postingDate', true);
CustomHeader."Document Reference" := CopyStr(JsonHelper.ValAsTxt(JObject, 'docReference', true), 1, MaxStrLen(CustomHeader."Document Reference"));
CustomHeader.Insert(true);
// 2. Process Lines
LinesJArray := JsonHelper.ReadJArrayFromObj(JObject, 'lines');
LineNo := 10000;
foreach LineJToken in LinesJArray do begin
CustomLine.Init();
CustomLine."Document No." := CustomHeader."No.";
CustomLine."Line No." := LineNo;
CustomLine."Item No." := CopyStr(JsonHelper.ValAsTxt(LineJToken.AsObject(), 'no', true), 1, MaxStrLen(CustomLine."Item No."));
CustomLine.Quantity := JsonHelper.ValAsDec(LineJToken.AsObject(), 'qty', true);
CustomLine."Unit Price" := JsonHelper.ValAsDec(LineJToken.AsObject(), 'unitPrice', true);
CustomLine.Insert(true);
LineNo += 10000;
end;
CreatedDocumentRecordId := CustomHeader.RecordId;
end;
```
## JSON-Struktur
Die JSON-Eingabe folgt dieser Struktur (wichtige Felder):
```json
{
"type": "Invoice",
"vendorNo": "K00170",
"docDate": "2023-07-13",
"postingDate": "2025-01-23",
"docReference": "R308152",
"lines": [
{
"no": "90011",
"description": "Item Description",
"qty": 12.0,
"unitPrice": 199.95
}
]
}
```
## Beste Praktiken
1. **Fehlerbehandlung**: Implementieren Sie eine ordnungsgemäße Fehlerbehandlung für JSON-Parsing und Datenbankoperationen:
```al
local procedure CreateCustomDocument(JObject: JsonObject; var CreatedDocumentRecordId: RecordId)
var
CustomHeader: Record "Custom Document Header";
begin
if not DoesJsonHaveRequiredFields(JObject) then
Error('Required fields are missing in the JSON payload');
if not TryCreateCustomHeader(JObject, CustomHeader) then
Error('Failed to create document header');
// ... rest of the implementation
end;
```
2. **Transaktionshandling**: Verwenden Sie Transaktionen, um die Datenkonsistenz sicherzustellen:
```al
local procedure CreateCustomDocument(JObject: JsonObject; var CreatedDocumentRecordId: RecordId)
begin
if not GuiAllowed then
Commit();
if not TryProcessDocument(JObject, CreatedDocumentRecordId) then
Error('Document creation failed');
end;
```
3. **Validierung**: Implementieren Sie eine ordnungsgemäße Validierung vor der Dokumenterstellung:
```al
local procedure ValidateDocument(JObject: JsonObject): Boolean
var
Vendor: Record Vendor;
VendorNo: Code[20];
begin
VendorNo := CopyStr(JsonHelper.ValAsTxt(JObject, 'vendorNo', true), 1, MaxStrLen(VendorNo));
if not Vendor.Get(VendorNo) then
Error('Vendor %1 does not exist', VendorNo);
// Add more validation as needed
exit(true);
end;
```
## Häufige Szenarien
### Szenario 1: Verschiedene Dokumenttypen erstellen
```al
local procedure GetDocumentType(JObject: JsonObject): Enum "Custom Document Type"
var
DocType: Text;
begin
DocType := JsonHelper.ValAsTxt(JObject, 'type', true);
case DocType of
'Invoice':
exit("Custom Document Type"::Invoice);
'CreditMemo':
exit("Custom Document Type"::"Credit Memo");
else
Error('Unknown document type: %1', DocType);
end;
end;
```
### Szenario 2: Benutzerdefinierte Felder verarbeiten
```al
local procedure ProcessCustomFields(JObject: JsonObject; var CustomDoc: Record "Custom Document Header")
var
CustomFieldsObj: JsonObject;
CustomFieldsArr: JsonArray;
FieldToken: JsonToken;
begin
if not JsonHelper.TokenExists(JObject, 'customFields') then
exit;
CustomFieldsObj := JsonHelper.ReadJObjectFromObj(JObject, 'customFields');
CustomFieldsArr := JsonHelper.ReadJArrayFromObj(CustomFieldsObj, 'namesAndValues');
foreach FieldToken in CustomFieldsArr do
ProcessCustomField(FieldToken.AsObject(), CustomDoc);
end;
```
## Fehlerbehebung
1. **RecordId ist leer**: Stellen Sie sicher, dass Sie den CreatedDocumentRecordId-Parameter setzen:
```al
CreatedDocumentRecordId := CustomHeader.RecordId;
```
2. **JSON-Parsing-Fehler**: Verwenden Sie die JsonHelper-Funktionen für sicheres Parsing:
```al
if not JsonHelper.TokenExists(JObject, 'vendorNo') then
Error('Vendor number is missing in JSON');
```
3. **Datenvalidierung**: Implementieren Sie eine ordnungsgemäße Datenvalidierung:
```al
if JsonHelper.ValAsDec(LineJToken.AsObject(), 'qty', true) <= 0 then
Error('Quantity must be greater than 0');
```
## Testen
Erstellen Sie eine Test-Codeunit zur Überprüfung Ihrer Implementierung:
```al
codeunit 50101 "Custom Doc. Creation Tests"
{
Subtype = Test;
[Test]
procedure TestCustomDocumentCreation()
var
JObject: JsonObject;
CreatedRecordId: RecordId;
begin
// Arrange
CreateTestJson(JObject);
// Act
OnDocumentCreation(JObject, CreatedRecordId);
// Assert
AssertDocumentCreated(CreatedRecordId);
end;
}
```