Using the "Codeunit" Output Type
The Codeunit output type can be used to process and send documents via custom business logic.
Instead of using standard output types like E-Mail, FTP, or Download, a codeunit is executed that can transfer or further process the generated documents to any destination.
Info
The Codeunit output type is particularly suitable for integrations where documents are to be transferred to external systems or APIs (e.g., DMS, cloud storage, archive systems).
Typical Use Cases
With this feature, you can, for example:
- Upload documents via external APIs (e.g., Dropbox, Google Drive, or your own repositories)
- Transfer documents to third-party systems (e.g., DMS, archive systems)
- Implement custom processing logic (e.g., encryption, validation, transformation)
- Integrate into company-specific workflows (e.g., automatically starting approval processes)
Setup
To use the Codeunit output type, you need to set up a corresponding Dispatch Profile and specify the desired codeunit.
- Open the Dispatch Profiles page.
- Create a new profile or edit an existing one.
- In the Output Type field, select the Codeunit option.
- Run the Options action in the menu bar.
- In the Codeunit ID field, enter the number of the codeunit to be executed (e.g.,
50000 from the example below).
- Under Dispatch Profile Attachments, configure the documents (reports, files, etc.) to be processed by the codeunit.
When this dispatch profile is now used to send documents, the codeunit you specified will be executed.
How it Works
When a Queue Entry with the Codeunit output type is processed, Document Dispatch performs the following steps:
- All configured attachments (reports, files, XML, etc.) are generated.
- The codeunit stored in the Dispatch Profile is executed via
CODEUNIT.Run().
- The codeunit gains access to the generated documents through the Queue Line entries.
- The codeunit processes and sends the documents according to the implemented logic (e.g., API upload).
Example: Uploading Documents to a Repository via API
The following example shows how documents can be transferred to an external repository via a REST API.
Example Implementation
| AL - Custom Codeunit for API Upload |
|---|
| codeunit 50000 "Doc. Dispatch API Upload"
{
TableNo = "SIM_EDS Record Attachment";
Permissions = tabledata "SIM_EDS Queue Line" = RIM;
trigger OnRun()
begin
UploadDocumentsToAPI();
end;
var
GlobalCodeunitSIMEDSSI: Codeunit "SIM_EDS SI";
/// <summary>
/// Uploads all generated documents to an external repository via an API
/// </summary>
procedure UploadDocumentsToAPI()
var
LocalRecordSIMEDSQueueLine: Record "SIM_EDS Queue Line";
LocalRecordSIMEDSQueueEntry: Record "SIM_EDS Queue Entry";
LocalCodeunitBase64Convert: Codeunit "Base64 Convert";
LocalHttpClient: HttpClient;
LocalHttpContent: HttpContent;
LocalHttpResponse: HttpResponseMessage;
LocalHeaders: HttpHeaders;
LocalInStream: InStream;
LocalFileBase64Text: Text;
LocalApiUrlText: Text;
LocalQueueEntryNo: BigInteger;
LocalSuccessBoolean: Boolean;
begin
// Get Queue Entry No. from Document Dispatch
LocalQueueEntryNo := GlobalCodeunitSIMEDSSI.GetQueueEntryNo();
if LocalQueueEntryNo = 0 then
Error('No Queue Entry found.');
if not LocalRecordSIMEDSQueueEntry.Get(LocalQueueEntryNo) then
Error('Queue Entry %1 not found.', LocalQueueEntryNo);
// Iterate through all generated Queue Lines (= documents) for this Queue Entry
LocalRecordSIMEDSQueueLine.SetRange("Queue Entry No.", LocalQueueEntryNo);
LocalRecordSIMEDSQueueLine.SetRange("Attach Tag", true); // Only tagged attachments
if LocalRecordSIMEDSQueueLine.FindSet() then
repeat
// Get document from Queue Line
LocalRecordSIMEDSQueueLine.CalcFields("Document Blob");
if LocalRecordSIMEDSQueueLine."Document Blob".HasValue then begin
// Convert document to Base64 for API transfer
Clear(LocalInStream);
LocalRecordSIMEDSQueueLine."Document Blob".CreateInStream(LocalInStream);
LocalFileBase64Text := LocalCodeunitBase64Convert.ToBase64(LocalInStream);
// Perform API upload
LocalApiUrlText := GetAPIUploadUrl(); // Your API URL
LocalSuccessBoolean := UploadFileToAPI(
LocalApiUrlText,
LocalRecordSIMEDSQueueLine."Document Name",
LocalFileBase64Text,
LocalRecordSIMEDSQueueEntry
);
if not LocalSuccessBoolean then
Error('Upload failed for document: %1', LocalRecordSIMEDSQueueLine."Document Name");
end;
until LocalRecordSIMEDSQueueLine.Next() = 0;
Message('All documents uploaded successfully.');
end;
local procedure UploadFileToAPI(
ParamApiUrl: Text;
ParamFilename: Text;
ParamFileBase64: Text;
ParamQueueEntry: Record "SIM_EDS Queue Entry"
): Boolean
var
LocalHttpClient: HttpClient;
LocalHttpContent: HttpContent;
LocalHttpResponse: HttpResponseMessage;
LocalHeaders: HttpHeaders;
LocalJsonObject: JsonObject;
LocalJsonText: Text;
LocalRequestBody: Text;
begin
// Create JSON payload for API
LocalJsonObject.Add('filename', ParamFilename);
LocalJsonObject.Add('content', ParamFileBase64);
LocalJsonObject.Add('source_document', Format(ParamQueueEntry."Source ID"));
LocalJsonObject.Add('queue_entry_no', ParamQueueEntry."Entry No.");
LocalJsonObject.WriteTo(LocalJsonText);
// Configure HTTP Request
LocalHttpContent.WriteFrom(LocalJsonText);
LocalHttpContent.GetHeaders(LocalHeaders);
LocalHeaders.Clear();
LocalHeaders.Add('Content-Type', 'application/json');
LocalHeaders.Add('Authorization', GetAPIAuthToken()); // Your auth logic
// Perform API call
if not LocalHttpClient.Post(ParamApiUrl, LocalHttpContent, LocalHttpResponse) then
exit(false);
// Check response
exit(LocalHttpResponse.IsSuccessStatusCode());
end;
local procedure GetAPIUploadUrl(): Text
var
LocalSetup: Record "Your API Setup"; // Your setup table
begin
LocalSetup.Get();
LocalSetup.TestField("API Base URL");
exit(LocalSetup."API Base URL" + '/upload');
end;
local procedure GetAPIAuthToken(): Text
var
LocalSetup: Record "Your API Setup";
begin
LocalSetup.Get();
LocalSetup.TestField("API Token");
exit('Bearer ' + LocalSetup."API Token");
end;
}
|
Advantages
When you use the Codeunit output type, you get the following advantages, among others:
- Full Control: You determine where and how documents are handled.
- Flexibility: Any API, any protocol, any business logic is possible.
- Integration: Seamless integration into the Document Dispatch Queue mechanism.
- Error Handling: Use of the standard error handling mechanisms of Document Dispatch.
- Traceability: Uploads are logged in the Queue History.