Zum Inhalt

Akte

Die Akte ist über Events, Enums und Interfaces erweiterbar. Die gezeigten Beispiele können als AL Projekt heruntergeladen werden.

Link zum Excel Konzept

Erweiterung für eine zusätzliche Entität

Die Aktenfunktionalität soll per Extension auch für Artikel verfügbar sein.

Aufbau von Referenzen für neue Akteneinträge

Als erstes wird das Event OnBeforeNewFileEntryStartWorksheet abonniert, um Referenzen für die neu zu erstellenden Akteneinträge aufzubauen.

codeunit 50104 FileForItem
{
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"BSSSP File Entry Management", 'OnBeforeNewFileEntryStartWorksheet', '', false, false)]
    local procedure OnBeforeNewFileEntryStartWorksheet(var SourceRecRef: RecordRef; var SourceRecordReferences: Record "BSSSP File Entry Reference" temporary; var IsHandled: Boolean)
    var
        RefEntryNo: Integer;
    begin
        case SourceRecRef.Number of
            Database::Item:
                begin
                    // nächste laufende Nummer suchen (PK)
                    SourceRecordReferences.Reset();
                    if SourceRecordReferences.FindLast() then
                        RefEntryNo := SourceRecordReferences."Entry No." + 1
                    else
                        RefEntryNo := 1;

                    // Referenz zu Artikelnummer
                    SourceRecordReferences.Init();
                    SourceRecordReferences."Entry No." := RefEntryNo;
                    SourceRecordReferences."Reference Table No." := SourceRecRef.Number;
                    SourceRecordReferences."Reference Field No." := 1;
                    SourceRecordReferences."Reference Value" := FORMAT(SourceRecRef.Field(1).Value);
                    SourceRecordReferences."Reference System Id" := SourceRecRef.Field(SourceRecRef.SystemIdNo).Value;
                    SourceRecordReferences."System Data" := true;
                    SourceRecordReferences.Insert(true);
                    RefEntryNo := RefEntryNo + 1;

                    //Referenz zu Artikelbeschreibung
                    SourceRecordReferences.Init();
                    SourceRecordReferences."Entry No." := RefEntryNo;
                    SourceRecordReferences."Reference Table No." := SourceRecRef.Number;
                    SourceRecordReferences."Reference Field No." := 3;
                    SourceRecordReferences."Reference Value" := FORMAT(SourceRecRef.Field(3).Value);
                    SourceRecordReferences."Reference System Id" := SourceRecRef.Field(SourceRecRef.SystemIdNo).Value;
                    SourceRecordReferences."System Data" := true;
                    SourceRecordReferences.Insert(true);
                    RefEntryNo := RefEntryNo + 1;
                end;
        end;
    end;
}

Artikelkarte um Aufrufe für die Akte erweitern

Als nächstes wird die Artikelkarte um Aufrufe zum Erstellen eines neuen Aktenvorgangs und zum Anzeigen bestehender Akteneinträge erweitert.

pageextension 50102 FileForItemPagExtension extends "Item Card"
{
    actions
    {
        addlast(navigation)
        {
            action("BSSSP BSSSPShowFileEntries")
            {
                Caption = 'Akteneinträge';
                ApplicationArea = All;
                ToolTip = 'Zeigt die Akteneinträge zum Artikel';
                Image = Documents;

                trigger OnAction()
                var
                    SearchReferences: Record "BSSSP File Entry Reference" temporary;
                    ResultPage: Page "BSSSP File Entry Search Result";
                begin
                    SearchReferences.Init();
                    SearchReferences."Entry No." := 1;
                    SearchReferences."Reference Table No." := 27;
                    SearchReferences."Reference Field No." := 1;
                    SearchReferences."Reference Value" := "No.";
                    SearchReferences.Insert();

                    ResultPage.OpenForSearchTerms(SearchReferences);
                    ResultPage.Run();
                end;
            }
        }
        addlast(processing)
        {
            action("BSSSP BSSSPNewFileEntry")
            {
                Caption = 'Neuer Aktenvorgang';
                ApplicationArea = All;
                ToolTip = 'Anlegen eines neuen Aktenvorgangs';
                Image = Add;

                trigger OnAction()
                var
                    FileEntryMgt: Codeunit "BSSSP File Entry Management";
                    RecRef: RecordRef;
                begin
                    RecRef.Get(RecordId());
                    FileEntryMgt.NewFileEntryStartWorksheet(RecRef);
                end;
            }
        }
    }
}

Nach diesen zwei Schritten steht die Komplette Aktenfunktionalität für den Artikel zur Verfügung. Zu Steigerung des Komforts sollte noch die Aufzählung BSSSP File Reference Type um einen Eintrag zum Artikel erweitert werden, damit die Entität beim Bearbeiten von Schrittvorlagen und beim Suchen zur Verfügung steht.

Enums

BSSSP File Reference Type

enum 5250419 "BSSSP File Reference Type" implements "BSSSP IReferecenceFields"

Es werden die möglichen Referenzarten aufgezählt. Die Referenzarten werden in der Suche und für die Datenquellen der Vorgangsschritt-Vorlagen verwendet.

Beispiel: Erweiterung der Referenzarten

Die möglichen Referenzarten sollen um Artikel und Ressourcen erweitert werden. Dabei ist darauf zu achten, dass die Werte der neuen Enummember den Tabellennummern in BC entsprechen.

Wichtig: Zur Zeit der Erstellung des Beispiels gab es einen Bug bei der Implementierung von Interfaces in Codeunits, wenn die Funktionsdefinitionen temporäre Recordvariablen enthalten. Mehr dazu bei Github.

Als erstes wird eine Implemtierung für das interface BSSSP IReferecenceFields aus Servicepro 365 erstellt.

codeunit 50103 RefTypeExtensionImpl implements "BSSSP IReferecenceFields"
{
    procedure GetSearchFields(
        ReferenceType: Enum "BSSSP File Reference Type"; 
        var References: Record "BSSSP File Entry Reference")
    var
        EntryNo: Integer;
        NotImplementedErr: Label 'Diese Funktion ist nicht implementiert.';
    begin
        References.Reset();
        if References.FindLast() then
            EntryNo := References."Entry No." + 1
        else
            EntryNo := 1;

        case ReferenceType of
            ReferenceType::Item:
                begin
                    AddItemReferenceFields(References, EntryNo);
                end;
            ReferenceType::Resource:
                begin
                    AddResourceReferenceFields(References, EntryNo);
                end;
        end;
    end;
...

Dann wird die Referenztyp Aufzählung um die gewünschten Einträge erweitert.

enumextension 50102 RefTypeExtension extends "BSSSP File Reference Type"
{
    value(27; Item)
    {
        Caption = 'Artikel';
        Implementation = "BSSSP IReferecenceFields" = RefTypeExtensionImpl;
    }
    value(156; Resource)
    {
        Caption = 'Ressource';
        Implementation = "BSSSP IReferecenceFields" = RefTypeExtensionImpl;
    }
}

Durch diese Anpassung erweitert sich die Anzeige der möglichen Suchbegriffe und die Auswahl der Datenquellen in der Vorgangsschritt-Vorlage um Ressource und Artikel.

Neue Einträge in der Combobox

Events

BSSSP File Entry Management Codeunit

OnBeforeNewFileEntryStartWorksheet

Dieses Event wird ausgelöst, bevor die Seite zum Bearbeiten eines neuen Aktenvorgangs geöffnet wird. Es bietet sich an, wenn zusätzliche Referenzen für einen Akteneintrag hinzugefügt oder neue Entitäten in die Akte eingebunden werden sollen.

[IntegrationEvent(false, false)]
local procedure OnBeforeNewFileEntryStartWorksheet(
    var SourceRecRef: RecordRef; 
    var SourceRecordReferences: Record "BSSSP File Entry Reference" temporary; 
    var IsHandled: Boolean
)

Das Event bietet Zugriff auf den Herkunftsdatensatz SourceRecRef und dessen Referenzen SourceRecordReferences. Über IsHandled kann der Start der Seite unterbunden werden. Die Referenzen in SourceRecordReferences werden beim Erstellen eines neuen Vorgangs mit den Akteneinträgen verknüpft.

Beispiel: hinzufügen von Referenzen

Zusätzlich zu den vom System generierten Referenzen, soll beim Debitor noch ein Verweis zur Debitorenwährung hinzugefügt werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"BSSSP File Entry Management", 'OnBeforeNewFileEntryStartWorksheet', '', false, false)]
local procedure OnBeforeNewFileEntryStartWorksheet(
    var SourceRecRef: RecordRef; 
    var SourceRecordReferences: Record "BSSSP File Entry Reference" temporary; 
    var IsHandled: Boolean)
var
    RefEntryNo: Integer;
begin
    case SourceRecRef.Number of
        Database::Customer:
            begin
                // nächste laufende Nummer suchen (PK)
                SourceRecordReferences.Reset();
                if SourceRecordReferences.FindLast() then
                    RefEntryNo := SourceRecordReferences."Entry No." + 1
                else
                    RefEntryNo := 1;

                // weitere Referenz hinzufügen
                SourceRecordReferences.Init();
                SourceRecordReferences."Entry No." := RefEntryNo;
                SourceRecordReferences."Reference Table No." := SourceRecRef.Number;
                SourceRecordReferences."Reference Field No." := 22; // Debitor Währungscode
                SourceRecordReferences."Reference Value" := FORMAT(SourceRecRef.Field(22).Value);
                SourceRecordReferences."Reference System Id" := SourceRecRef.Field(SourceRecRef.SystemIdNo).Value;
                SourceRecordReferences.Insert(true);
            end;
    end;
end;

Es wird eine Referenz mit dem Währungscode des Debitors hinzugefügt, die beim Erstellen eines Vorgangs den Schritten zugeordnet ist.

zusätzliche Refrenz: Währungscode

Hinweis: Fügt man eine Referenz zu einer anderen Entität als der des "SourceRecRef" hinzu, wird diese automatisch beim Office Datenmerge berücksichtigt.

OnBeforeCancelFileEntry

Dieses Event wird ausgelöst bevor ein Akteneintrag storniert wird.

[IntegrationEvent(false, false)]
local procedure OnBeforeCancelFileEntry(
    var FileEntry: Record "BSSSP File Entry"; 
    var Handled: Boolean
)

Das Event bietet Zugriff auf den Akteneintrag. Der Vorgang kann über IsHandled abgebrochen werden.

Beispiel: Confirm bevor storniert wird

Der Benutzer soll vom System gefragt werden, ob er den Eintrag wirklich stornieren möchte.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"BSSSP File Entry Management", 'OnBeforeCancelFileEntry', '', false, false)]
local procedure OnBeforeCancelFileEntry(
    var FileEntry: Record "BSSSP File Entry"; 
    var Handled: Boolean)
var
    DoCancelQst: Label 'Möchten Sie den Akteneintrag wirklich stornieren?';
begin
    if not Confirm(DoCancelQst) then
        Handled := true;
end;

OnAfterCancelFileEntry

Dieses Event wird ausgelöst nachdem ein Akteneintrag storniert wurde. Es bietet sich für Prüfungen oder Aufräumarbeiten an.

[IntegrationEvent(false, false)]
local procedure OnAfterCancelFileEntry(var FileEntry: Record "BSSSP File Entry")

Das Event bietet Zugriff auf den Akteneintrag.

Beispiel: aufräumen nach Storno

Es sollen alle Anhänge eines stornierten Akteneintrages gelöscht werden;

[EventSubscriber(ObjectType::Codeunit, Codeunit::"BSSSP File Entry Management", 'OnAfterCancelFileEntry', '', false, false)]
local procedure OnAfterCancelFileEntry(var FileEntry: Record "BSSSP File Entry")
var
    FileDataset: Record "BSSSP File Dataset";
    FileDatasetEntry: Record "BSSSP File Dataset Entry";
begin
    FileDatasetEntry.SetRange("Dataset Id", FileEntry."Dataset Id");
    FileDatasetEntry.DeleteAll(true);

    FileDataset.SetRange(Id, FileEntry."Dataset Id");
    FileDataset.DeleteAll(true);
end;

OnBeforeHandleUploadedFile

Dieses Event wird ausgelöst nachdem ein Anhang hochgeladen aber bevor die Datei in die Datenbank geschrieben wird. Es bietet sich dazu an, die Dateien vor dem Speichern zu bearbeiten und eigene Aktionen mit den Dateien auszuführen.

[IntegrationEvent(false, false)]
local procedure OnBeforeHandleUploadedFile(
    DatasetId: Guid; 
    var UploadedFile: Record "BSSSP File Dataset Entry" temporary; 
    var Handled: Boolean
)

Das Event bietet Zugriff auf die DatasetId für die die Datei Hochgeladen wird und den Anhang UploadedFile der Hochgeladen wurde. Die Verarbeitung kann über Handled abgebrochen werden.

Beipiel: mit Fehlermeldung abbrechen, wenn falscher Dateityp

Das Programm soll mit einer Fehlermeldung abbrechen, wenn ein Benutzer eine *.al Datei hochlädt.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"BSSSP File Entry Management", 'OnBeforeHandleUploadedFile', '', false, false)]
local procedure OnBeforeHandleUploadedFile(
    DatasetId: Guid; 
    var UploadedFile: Record "BSSSP File Dataset Entry" temporary; 
    var Handled: Boolean)
var
    FileMgt: Codeunit "File Management";
    AlFileNotAllowedErr: Label 'AL Dateien sind nicht erlaubt.';
begin
    if FileMgt.GetExtension(UploadedFile.Filename) = 'al' then
        Error(AlFileNotAllowedErr);
end;

OnBeforeMergeDataToDocx

Dieses Event wird ausgelöst bevor ein Word-Dokument mit XML Daten befüllt wird. Es eignet sich dazu Datensätze zum Merge hinzuzufügen, oder den Merge komplett abzubrechen.

[IntegrationEvent(false, false)]
local procedure OnBeforeMergeDataToDocx(
    DatasetEntryId: Guid; 
    var MergeData: Record "BSSSP File Entry Reference" temporary; 
    var Handled: Boolean
)

Das Event bietet Zugriff auf die Anhang-Id DatasetEntryId und die zu mergenden Datensätze MergeData. Der Merge kann über Handled abgebrochen werden.

Beispiel: einen Datensatz dem Merge hinzufügen

Es soll ein Artikel zu den XML Datenquellen des Docx Dokuments hinzugefügt werden.

[EventSubscriber(ObjectType::Codeunit, Codeunit::"BSSSP File Entry Management", 'OnBeforeMergeDataToDocx', '', false, false)]
local procedure OnBeforeMergeDataToDocx(
    DatasetEntryId: Guid; 
    var MergeData: Record "BSSSP File Entry Reference" temporary; 
    var Handled: Boolean)
var
    Item: Record Item;
    NewEntryNo: Integer;
begin
    // Ersten Artikel auswählen
    Item.FindFirst();

    // neue Laufende Nummer ermitteln (PK)
    MergeData.Reset();
    if MergeData.FindLast() then
        NewEntryNo := MergeData."Entry No." + 1
    else
        NewEntryNo := 1;

    //Artikel hinzufügen
    MergeData.Init();
    MergeData."Entry No." := NewEntryNo;
    MergeData."Reference Table No." := 27; // Artikel
    MergeData."Reference System Id" := Item.SystemId;
    MergeData.Insert();
end;

Durch diesen Subscriber, wird jedem Worddokument beim Office-Datenmerge der erste im Mandanten gefundene Artikel hinzugefügt.

OnBeforeSendJsonToDocxService

Dieses Event wird ausgelöst bevor das Worddokument mit den zu mergenden Daten an den Webservice geschickt wird. Es eignet sich dazu die Daten des Webrequest vor dem Versand zu manipulieren. Es können Daten hinzugefügt, entfernt oder verändert werden.

[IntegrationEvent(false, false)]
local procedure OnBeforeSendJsonToDocxService(
    DatasetEntryId: Guid;
    ReferenceId: Guid; 
    var RequestObject: JsonObject; 
    var Handled: Boolean
)

Das Event bietet Zugriff auf die Anhangs Id DatasetEntryId, die Referenzsatz Id ReferenceId und das RequestObject. Der Vorgang kann über Handled abgebrochen werden.

Bei Verwendung dieses Events muss der Abonnent selbst dafür Sorge tragen, dass das RequestObject folgende Struktur aufweist. Sonst ist nicht sicher gestellt, dass der Webservice die Daten korrekt verarbeiten kann.

{
    "ExportData": [
        {
            "Name": "Customer",
            "FieldNamesValues": [
                {
                    "Key": "Name",
                    "Value": "Max Mustermann"
                },
                {
                    "Key": "Address",
                    "Value": "Musterstr. 8"
                },
                {
                    "Key": "PostCode",
                    "Value": "11122"
                },
                {
                    "Key": "City",
                    "Value": "Musterstadt"
                }
            ]
        },
        {
            "Name": "Item",
            "FieldNamesValues": [
                {
                    "Key": "No",
                    "Value": "1000"
                },
                {
                    "Key": "Description",
                    "Value": "Rennrad"
                },
                {
                    "Key": "Price",
                    "Value": "3500\u20AC"
                }
            ]
        }
    ],
    "ExportLines": [
        {
            "TableName": "Items",
            "TableRows": [
                {
                    "Name": "Item",
                    "FieldNamesValues": [
                        {
                            "Key": "No",
                            "Value": "1000"
                        },
                        {
                            "Key": "Description",
                            "Value": "Rennrad"
                        },
                        {
                            "Key": "Price",
                            "Value": "3500\u20AC"
                        }
                    ]
                },
                {
                    "Name": "Item",
                    "FieldNamesValues": [
                        {
                            "Key": "No",
                            "Value": "2000"
                        },
                        {
                            "Key": "Description",
                            "Value": "City Bike"
                        },
                        {
                            "Key": "Price",
                            "Value": "1200\u20AC"
                        }
                    ]
                }
            ]
        },
        {
            "TableName": "Resources",
            "TableRows": [
                {
                    "Name": "Resource",
                    "FieldNamesValues": [
                        {
                            "Key": "No",
                            "Value": "AH"
                        },
                        {
                            "Key": "Description",
                            "Value": "Armin Hellmann"
                        },
                        {
                            "Key": "Price",
                            "Value": "55\u20AC"
                        }
                    ]
                },
                {
                    "Name": "Resource",
                    "FieldNamesValues": [
                        {
                            "Key": "No",
                            "Value": "PK"
                        },
                        {
                            "Key": "Description",
                            "Value": "Peter King"
                        },
                        {
                            "Key": "Price",
                            "Value": "75\u20AC"
                        }
                    ]
                }
            ]
        }
    ],
    "DocxData": "Base64 encoded Document"
}

ExportData: dieses Array eignet sich für einzelne Datensätze. Ein Array Mitglied hat die Name Eigenschaft für den Tabellennamen. Unter diesem Namen sind die Daten später im Dokument unter XML Datenquellen zu finden. FieldNamesValues ist eine Array aus Key-Value Objekten für Spaltenname und Spaltenwert.

ExportLines: ist ein Array für die Ablage von Zeilendaten. Ein Array Mitglied hat die Eigenschaften TableName für den Tabellennanem und TableRows als Array von FieldNamesValues. FieldNamesValues ist eine Array aus Key-Value Objekten für Spaltenname und Spaltenwert.

DocxData: ist die base64 codeierte Darstellung des Word Dokumentes.