Skip to main content

Leitfaden zur Implementierung der benutzerdefinierten Dokumentenerstellung

# 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;
}
```