Breeze Interface for Dynamics 365 BC - en-US

Manual for the administration and use of BREEZE for Microsoft Dynamics 365 Business Central.

We deliver our all-in-one BREEZE workflow solutions for document-oriented business processes from a single source, whether as OnPremises or as Solution-as-a-Service.
The BREEZE workflow engine quickly steers documents and data through the entire review process with simple "if-then" rules and conditions, all the way to final approval.

System Requirements

System requirements for using BREEZE for Dynamics 365 BC

System Requirements

Supported Microsoft Dynamics 365 Business Central versions

Microsoft Dynamics 365 Business Central integration is possible from the following version due to minimum technical requirements:

Supportet Microsoft Dynamics 365 Business Central Versions

The prerequisite for operation is that the respective Microsoft Dynamics 365 Business Central version is still in regular support. The extended support is excluded.

 

System Requirements

Supported BREEZE versions

A licensed BREEZE system is required to connect BREEZE to Microsoft Dynamics 365 Business Central and for operation.

Installation

Installation

Licenses

Microsoft

Information about the Microsoft Business Central licenses.

BREEZE

The DEXPRO BREEZE system that should be connected to Business Central requires a valid customer license.

Installation

Obtaining the DEXPRO modules

Detailed informationen are here.

OnPrem

For OnPrem installations, an runtime package with the required apps is provided upon request of a registered reseller / partner. These modules are added to the customer license by the partner and then imported into Microsoft Dynamics Business Central. It should be noted that the DEXPRO Core module forms the basis for all DEXPRO modules and must therefore be imported first.

Cloud

For cloud installations, you only need the Microsoft AppSource. This is where the required DEXPRO modules are downloaded.

BreezeInterface_icon_appsource.png

Configuration & Administration

Configuration & Administration

Permission sets

In order to use the modules, the appropriate authorization set must be assigned to the respective users.

The following are supplied with:

Configuration & Administration

DEXPRO Core

The DEXPRO Core manages the individual DEXPRO apps and their documents per client.

All documents that have been entered and processed via the various DEXPRO modules in Microsoft Dynamics 365 Business Central are displayed. A global number series, which is used across all DEXPRO apps, is used to complete individual documents. This offers the advantage that users only have to work with one number series per document.

Further information can be found here.

Configuration & Administration

Breeze Interface Setup

In the Breeze Interface setup, processing is set up within the app.

Process

Copy Setup

This copies the setup to other clients.

Navigation

Document class setup

Via this menu item you reach the setup for the document classes.

Target Template Setup

This menu item is used to access the target templates setup. Target templates for the Breeze interface are managed here.

General

In this FastTab you can enable/disable the use of this app.

image-1694762018332.png

No. Series

The number series for the Breeze Interface documents is stored here.

image-1694762079375.png

Configuration & Administration

Document Class Setup

In the document class setup, the mapping between the respective document class and your export interface is done. Furthermore, the field mapping of each document class is downloaded here, creating a set of standard fields and their usage in Microsoft Dynamics 365 Business Central.

The document class setup is cross-app and is managed via the DEXPRO Core.

Process

image-1647269521455.png

Download field mapping

This downloads the field structure of the SQUEEZE document class. These are needed for the metadata mapping.

Navigation

image-1647269553966.png

Metadata mapping

Via this menu item you reach the metadata mapping. This defines which fields are to be transferred to Microsoft Dynamics 365 Business Central and how.

List

Document classes

This overview lists all the document classes that have been set up.

image-1647269475167.png

Card

Document class

Here, each document class is set up individually.

General

image-1694690581281.png

In this fastab the name of the document class, the next process step, as well as the automatic enrichment of the positions is set up.

Breeze

image-1694762582536.png

Here you can set the default target template for this document class.

The following are available as standard:

image-1694762618847.png

Configuration & Administration

Target Template Setup

Target templates for the Breeze interface are managed here. These templates are available by default:

image-1694762827872.png

image-1694762866287.png

General

Here you can see which target template is currently being edited.

Plausibility Check

Here, certain plausibility checks per target template can be deactivated.

Configuration & Administration

Generic Custom Fields

Customer-specific fields can be added here that extend or deviate from our standard template. This mapping ensures that this additional content is assigned to the right places.

image-1707821087292.png

The corresponding BC field is assigned to each technical JSON field name.

On the Breeze side, the fields must be added via the additionalFields.

Configuration & Administration

OAuth 2.0 setup (for SaaS only)

Access to web services in Microsoft Dynamics 365 Business Central (BC) in the SaaS version is only possible via OAuth 2.0. The necessary setup of the app in Azure Active Directory and its link to BC is described below.

Azure Portal

Launch Azure Portal and open Microsoft Entra ID

image-1666695107040.png

Create a new app under App registrations

image-1666695222272.png

image-1666695353025.png

Create API permissions

The Application (client) ID can already be copied and stored at this point (will be needed later)

image-1666698096645.png

image-1666696539153.png

image-1666696558451.png

image-1666696591385.png

Create Client secret and store it in a secure location

image-1666697533453.png

image-1666697558892.png

Business Central

Open Microsoft Entra Applications and create a new entry

image-1747214121234.png

image-1747214145583.png

Set up Microsoft Entra Application

  1. Enter the Client ID
  2. Enter description (description is a bit misleading. This is rather a user name).
  3. Assign user permission set(s) individually.
  4. (Optional)
  5. Activate application

image-1747214264623.png

 

 

 

 

 

 

 

 

 

 

 

 

 

Configuration & Administration

Breeze Workflow

To connect our Breeze Invoice Workflow to Dynamics 365 BC please read this manual.

 

Application / Usage

This describes the process from the provision of validated squeeze purchasing documents to external workflows to the posting transfer of released documents.

Application / Usage

Breeze Interface Documents

All documents that are in the Breeze process are listed here.

image-1694763197320.png

Statuswerte
Application / Usage

Transfer to the unposted purchasing documents

After the workflow system has released the purchasing document, it is transferred to the Breeze interface. A plausibility check is then performed in the interface. If the check is successful, an unposted purchasing document is created.

If the plausibility check failed, the document is set to the status "error" and the error message is appended to the respective position in the Json structure of the document. Now the document is again waiting to be picked up and corrected by the workflow.

image-1694763696103.png

The unposted purchase document is created with all data from the Json structure. If attachments from the process have been attached, these will also be transferred to the unposted document.

image-1694763737921.png

Application / Usage

Breeze Interface API

Here you will find the documentation for the following products:

Extension Development

This chapter lists important integration events and examples that help in developing an extension for BREEZE Interface for BC.

Important:
Customizations may only be performed by appropriately trained consultants/developers. Furthermore, these are always outside of the standard support.

Extension Development

Guide to implementing customized document creation

Overview

This documentation provides guidance on implementing custom document creation processes using the Integration Event OnDocumentCreation in the DEXPRO Core Framework. While the default implementation creates purchase documents (Tables 38, 39), this guide shows you how to implement your own document creation logic using the provided JSON data.

Requirements

The following setting must be made in the document class setup before validating a document:

image-1769677432619.png

image-1769677479900.png

Have you validated a document with the DEXPRO Squeeze app and transferred it to the next process step, Breeze Interface? If so, you will now see it in Breeze Interface in a waiting status (WaitingForRetrieval). At this point, you have the option of transferring the validated document to an approval workflow so that it can be reported back after approval and transferred to the target document creation process. Further information on the Breeze Interface API can be found here.

image-1737637141572.png

Once you have changed the status of the Breeze receipt to "Processed", it will be reported to the DEXPRO Core for further processing—this is the integration point where you need to start.

Integration point

The central integration point is the OnDocumentCreation event in Codeunit 70954599 “DXP Doc. Creation Def. Impl.” in the DEXPRO Core app. This event is triggered during document processing and enables the implementation of custom document creation logic.

Event Signature

[IntegrationEvent(false, false)]
local procedure OnDocumentCreation(JObject: JsonObject; var CreatedDocumentRecordId: RecordId)

Parameter

Implementation Guide

Step 1: Create Subscriber-Codeunit

First, create a codeunit that subscribes to the OnDocumentCreation event:

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

Step 2: Implement document creation logic

Here is an example of how to implement custom document creation:

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-Structure

The JSON input follows this structure:

{
   "type":"Invoice",
   "vendorNo":"K00170",
   "iban":"DE58520503530052599766",
   "vatRegNo":"DE540026784",
   "barcode":"123456789",
   "docDate":"2023-07-13",
   "serviceDate":"2023-07-13",
   "postingDate":"2025-01-23",
   "postingDesc":"Die ist eine Buchungsbeschreibung.",
   "docReference":"R308154",
   "orderNo":"B23106029",
   "netAmount":7894.71,
   "netAmount2":0.0,
   "netAmount3":0.0,
   "taxRate":19.0,
   "taxRate2":0.0,
   "taxRate3":0.0,
   "taxAmount":1499.99,
   "taxAmount2":0.0,
   "taxAmount3":0.0,
   "totalAmount":9394.7,
   "currency":"EUR",
   "assignedTo":"BERND.FEDDERSEN",
   "note":"Die ist eine Bemerkung!",
   "dimensions":{
      "ABTEILUNG":"PROD",
      "EINKÄUFER":"BF",
      "KOSTENTRÄGER":"IT"
   },
   "dimensionSetID":27,
   "customFields":{
      "docClass":"DXP Invoice / Credit Memo",
      "namesAndValues":[
         {
            "name":"Customer_No",
            "value":"01121212"
         },
         {
            "name":"Custom_Date",
            "value":"2025-01-26"
         }
      ]
   },
   "orderMatchDifference":"false",
   "lines":[
      {
         "orderNo":"B23106029",
         "orderLineNo":10000,
         "receiptNo":"ELIEF107004",
         "receiptLineNo":10000,
         "vendorItemNo":"",
         "type":"Item",
         "no":"90002",
         "description":"JogiTek G 1337 Gaming-Headset",
         "qty":17.0,
         "uom":"STÜCK",
         "unitPrice":99.99,
         "lineDisc":0.0,
         "netAmount":1699.83,
         "totalAmount":2022.8,
         "taxRate":19.0,
         "vatBusPostingGroup":"INLAND",
         "vatProdPostingGroup":"MWST.19",
         "dimensions":{
            "ABTEILUNG":"PROD",
            "BEREICH":"30",
            "EINKÄUFER":"BF",
            "KOSTENTRÄGER":"IT",
            "VERKAUFSKAMPAGNE":"WINTER"
         },
         "dimensionSetID":53,
         "genProdPostingGroup":"HANDEL",
         "genBusPostingGroup":"INLAND",
         "deferralCode":"",
         "quantityDifference":"false",
         "unitPriceDifference":"false",
         "discountDifference":"false",
         "receiptDateDifference":"false",
         "customFields":{
            "docClass":"DXP Invoice / Credit Memo",
            "namesAndValues":[
               {
                  "name":"Custom_Field_1",
                  "value":"Text in Zeile 10000"
               },
               {
                  "name":"Custom_Field_2",
                  "value":"2025-01-31"
               }
            ]
         }
      },
      {
         "orderNo":"B23106029",
         "orderLineNo":30000,
         "receiptNo":"ELIEF107004",
         "receiptLineNo":30000,
         "vendorItemNo":"",
         "type":"Item",
         "no":"90005",
         "description":"Sumsing Galaxy 23",
         "qty":12.0,
         "uom":"STÜCK",
         "unitPrice":349.99,
         "lineDisc":0.0,
         "netAmount":4199.88,
         "totalAmount":4997.86,
         "taxRate":19.0,
         "vatBusPostingGroup":"INLAND",
         "vatProdPostingGroup":"MWST.19",
         "dimensions":{
            "ABTEILUNG":"PROD",
            "BEREICH":"50",
            "EINKÄUFER":"BF",
            "KOSTENTRÄGER":"IT",
            "VERKAUFSKAMPAGNE":"WINTER"
         },
         "dimensionSetID":55,
         "genProdPostingGroup":"HANDEL",
         "genBusPostingGroup":"INLAND",
         "deferralCode":"",
         "quantityDifference":"false",
         "unitPriceDifference":"false",
         "discountDifference":"false",
         "receiptDateDifference":"false",
         "customFields":{
            "docClass":"DXP Invoice / Credit Memo",
            "namesAndValues":[
               {
                  "name":"Custom_Field_1",
                  "value":"Text in Zeile 20000"
               },
               {
                  "name":"Custom_Field_2",
                  "value":"2025-01-30"
               }
            ]
         }
      },
      {
         "orderNo":"B23106029",
         "orderLineNo":20000,
         "receiptNo":"ELIEF107004",
         "receiptLineNo":20000,
         "vendorItemNo":"",
         "type":"Item",
         "no":"90000",
         "description":"Y-Phone Ultra Pro 23",
         "qty":5.0,
         "uom":"STÜCK",
         "unitPrice":399.0,
         "lineDisc":0.0,
         "netAmount":1995.0,
         "totalAmount":2374.05,
         "taxRate":19.0,
         "vatBusPostingGroup":"INLAND",
         "vatProdPostingGroup":"MWST.19",
         "dimensions":{
            "ABTEILUNG":"PROD",
            "BEREICH":"70",
            "EINKÄUFER":"BF",
            "KOSTENTRÄGER":"IT",
            "VERKÄUFER":"JH",
            "VERKAUFSKAMPAGNE":"WINTER"
         },
         "dimensionSetID":58,
         "genProdPostingGroup":"HANDEL",
         "genBusPostingGroup":"INLAND",
         "deferralCode":"",
         "quantityDifference":"false",
         "unitPriceDifference":"false",
         "discountDifference":"false",
         "receiptDateDifference":"false",
         "customFields":{
            "docClass":"DXP Invoice / Credit Memo",
            "namesAndValues":[
               {
                  "name":"Custom_Field_1",
                  "value":"Text in Zeile 30000"
               },
               {
                  "name":"Custom_Field_2",
                  "value":"2025-01-29"
               }
            ]
         }
      }
   ]
}

Best practice

  1. Error handling: Implement proper error handling for JSON parsing and database operations:
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;
  1. Validation: Implement proper validation before document creation:
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;

Common scenarios

Scenario 1: Create different document types

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;

Scenario 2: Processing custom fields

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;

Troubleshooting

  1. RecordId is empty: Ensure that you set the CreatedDocumentRecordId parameter:
CreatedDocumentRecordId := CustomHeader.RecordId;
  1. JSON-Parsing-Error: Use the JsonHelper functions for secure parsing:
if not JsonHelper.TokenExists(JObject, 'vendorNo') then
    Error('Vendor number is missing in JSON');
  1. Data validation: Implement proper data validation:
if JsonHelper.ValAsDec(LineJToken.AsObject(), 'qty', true) <= 0 then
    Error('Quantity must be greater than 0');