Squeeze for Dynamics 365 BC - en-US

Manual for the administration and use of SQUEEZE for Microsoft Dynamics 365 Business Central. SQUEEZE is a multi-client software solution for document classification and Content extraction. It is a fully web-based system for processing electronic documents, with a significant focus on the recognition and extraction of incoming documents in the B2B sector.

System Requirements

System requirements for using SQUEEZE 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 SQUEEZE versions

The integration of SQUEEZE in Microsoft Dynamics 365 Business Central requires a licensed SQUEEZE system from version 2.0.0 for operation.

Installation

Installation

Licenses

Microsoft

Information about the Microsoft Business Central licenses.

SQUEEZE

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

Installation

Obtaining the DEXPRO modules

Detailed Information 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.

Squeeze_icon_appsource.png

Installation

Setup Wizard

When the SQUEEZE setup is opened for the first time, you will be greeted by the SQUEEZE setup wizard.

This wizard guides the user step by step through the different facilities of the module.

Start

image-1647267970090.png

Selection SQUEEZE system

In this step the URL of the SQUEEZE system is stored.

Example: https://demo.msbc.squeeze.one

image-1647268006811.png

Login to the SQUEEZE system

In this step, you enter the user name and password of a valid SQUEEZE user with the Admin role. This data is only used once for the setup. Subsequently, the login to the SQUEEZE system takes place via API key.

image-1647268051328.png

Number series for the SQUEEZE documents

In this step you select number series for the Core documents and the SQUEEZE documents. If none exists yet, you can also create a new entry via the number series selection.

image-1647268143901.png

Conclusion

By clicking on "Finish" you end the setup wizard. Subsequently, the SQUEEZE setup opened. Further configuration options are described here.

image-1653386053493.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:

image-1647268401269.png

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

SQUEEZE Setup

In the SQUEEZE setup, both the connection to the SQUEEZE system and the processing within the app are set up.

Menu

Process

image-1647268682638.png

Setup Wizard

This is used to start the setup wizard. This guides the user step by step through all menu items.

Get API key

This function is used to set the API key for the configured API name from the connected SQUEEZE system.

Create jobs

The automated retrieval and processing of documents from SQUEEZE requires the setup of a background job. This can be done in via this function.

Copy setup

This copies the setup to other clients.

Master data

image-1647268712087.png

Initially Upload master data

Via the function "Upload master data for the first time" all accounts payable and accounts payable bank accounts are transferred to SQUEEZE for the first time.

Navigation

image-1694605936117.png

Using the SQUEEZE links menu item, you can see which vendor/vendor bank account has which ID on the squeeze page.

image-1647268848380.png

User specific setup

This menu item is used to access the user-specific setup. In this, different rules can be stored for each user.

Import queue entries

This menu displays a list of SQUEEZE vouchers that are ready to be imported into the SQUEEZE for BC app. By changing the system filter it is also possible to view already imported vouchers.

Via this menu item you reach the vendor-related setup. In this, deviating rules can be deposited per creditor.

Document classes setup

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

Fasttabs

General

In this Fasttab you can activate/deactivate the use of this app. Additionally you can see the version of the connected SQUEEZE system.

image-1647268934174.png

API

In this Fasttab the URL of the SQUEEZE system is specified. Furthermore, an API name is set and the corresponding API key is entered via the "Get API key" function.

image-1647268964817.png

Master data

To improve the quality of the readout, SQUEEZE requires the accounts payable information from Microsoft Dynamics 365 Business Central. In this Fasttab you enable/disable the master data Synchronization to SQUEEZE.

image-1647269134128.png

In the field "Client Master Data Tables Id" the ID of the SQUEEZE Company table is specified.

In the field "Creditor Master Data Tables Id" the ID of the SQUEEZE Creditor table is specified.

Number series

The number series for the SQUEEZE covers is indicated here.

image-1647269206724.png

Background jobs

The automated retrieval and processing of documents from SQUEEZE requires the setup of a background job. For this, the code unit 70954640 "DXP SQUEEZE Scheduled Tasks" is entered in the task queue item.

This background job is created automatically after the setup wizard is completed.

image-1647269240118.png

Job queue entries

Codeunit 70954640 "DXP SQUEEZE Scheduled" is entered as an item in the job queue entries.

image-1647269309478.png

Configuration & Administration

Document Classes Setup

In the SQUEEZE 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

You can access the field mapping via this menu item. This defines which fields from the squeeze endpoint are transferred to the defined fields in Microsoft Dynamics 365 Business Central. The standard field mapping cannot be edited. Different mappings can be realized via the custom field mapping.

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.

Squeeze

image-1694690612479.png

Autocomplete:

In the case of documents without a purchase order reference, the system can remember and recall the items read in and the account assignment applied to them for each vendor. There are three options that can be selected for this.

  1. Never: Disables the function and hides the button in the validation page
  2. Manual: Applying the autocomplete data is done manually by clicking the button "Autocomplete". Die Speicherung der Metadaten für die Autovervollständigung wird automatisch beim Abschluss des Validierungsprozesses ausgeführt

    image-1694690158591.png

  3. Automatic: Creating and applying the data for auto-completion is done automatically
    1. When creating the SQUEEZE document, the entries are applied
    2. When the validation is completed, the entries are created/updated
Automatic validation:

Enable this option to have Squeeze for BC automatically validate incoming receipts. Please note that this function works only in case of perfectly plausible data.

Download attachments:

Enable this switch to automatically download SQUEEZE attachments when creating a new document.

Transfer attachments to target document:

Here you can set whether the SQUEEZE attachments are to be transferred to the target document.

Account assignment code:

Specifies the account assignment setup to be used when performing the account assignment in the validation process.

API Settings

At this point, the ID of the connected squeeze client corresponding to the document class is stored, as well as the ID of the pull export interface and the correct line table ID. The default values do not necessarily match the setup in the squeeze client and should be cross-checked.

Order Match

The purchase order reconciliation is used for the automated check of the read out positions with those of the still open purchase orders in Microsoft Dynamics 365 Business Central. In this Fasttab, the permissible amount & quantity tolerances for the matching are set up. Additionally, it can be defined whether the matching should take place on purchase orders or deliveries. If "Replace data" is active, the amounts and descriptions of the items will be replaced with those of the order/delivery after matching.

Configuration & Administration

Vendor Related Setup

In this setup, vendor-specific settings are made per SQUEEZE document class. This is done for vendors that deviate from the set client standard.

In addition to the auto-completion of positions, deviating amount and quantity tolerances can also be set up here.

List

image-1647269412335.png

Card

image-1694689730264.png

Autocomplete:

In the case of documents without a purchase order reference, the system can remember and recall the items read in and the account assignment applied to them for each vendor. There are three options that can be selected for this.

  1. Never: Disables the function and hides the button in the validation page
  2. Manual: Applying the autocomplete data is done manually by clicking the button "Autocomplete". Die Speicherung der Metadaten für die Autovervollständigung wird automatisch beim Abschluss des Validierungsprozesses ausgeführt

    image-1694690158591.png

  3. Automatic: Creating and applying the data for auto-completion is done automatically
    1. When creating the SQUEEZE document, the entries are applied
    2. When the validation is completed, the entries are created/updated
Automatic validation:

Enable this option to have Squeeze for BC automatically validate incoming receipts. Please note that this function works only in case of perfectly plausible data.

Account assignment code:

Specifies the account assignment setup to be used when performing the account assignment in the validation process.

Order Match

The order reconciliation is used for the automated check of the read out positions with those of the still open orders in Microsoft Dynamics 365 Business Central. In this FastTab, the permissible amount & quantity tolerances for the matching are set up. Additionally, it can be defined whether the matching should take place against purchase orders or deliveries. If "Replace data" is active, the amounts and descriptions of the items will be replaced with those of the purchase order/delivery after matching.

 

Configuration & Administration

Account Assignment Setup

Here you will find the account assignment setup. If you have standard account assignments for certain VAT. You can store them here.

image-1729153814670.png

As soon as an account assignment setup with setup lines has been created and stored in a document class or an vendor related setup, it will be used automatically.

When importing a document from Squeeze, the recognized VAT. records are checked against the setup lines of the stored account assignment setup. If matching entries are found, a check is made to determine whether lines with the stored account assignments may be created. In the standard case, this is only done if Squeeze does not supply any items.

In addition, it is possible to set up whether an account assignment setup may be used automatically for validation.

This should not be set as default in the document class setup, as this would then apply to all vendors and documents. This option makes more sense for individual vendors (vendor related setup).

For automatically use, you can additionally activate that all squeeze lines of a document are overwritten with the configured account assignment setup lines. ("Overwrite squeeze lines" checkbox).

Account assignment setup

Setup lines are managed separately for each account assignment code.

image-1729154022362.png

This is where the individual VAT. records for which standard account assignments are to be set.

Account Assignment Type "One Account"

image-1729154104849.png

The selection of the account type corresponds to the BC standard:

image-1694685560820.png

The description can be customized as desired after selecting the number.

Account Assignment Type "Standard Purchase Code"

image-1729154166674.png

Here you can choose the standard purchase code from the recurring purchase lines.

image-1729154341289.png

 

Configuration & Administration

Field Mapping

In Metadata Mapping, the field mapping of each document class is downloaded, creating a set of standard fields and their usage in Microsoft Dynamics 365 Business Central.

image-1647269686928.png

Metadata assignment

Additional SQUEEZE fields which deviate from the standard add.

image-1647269784785.png

After assignment:

image-1647269826827.png

Configuration & Administration

Custom Field Mapping

You may always want to write certain information in certain fields in your process that deviates from the standard field assignment. In the following example, the service date recognized by Squeeze is always written in the “Booking date” field - in addition to the standard behaviour. The service date therefore remains filled.

Open the field assignment in the document class setup:

image-1729154979516.png

Then open the “User-defined field assignment”:

image-1729155003286.png

Then make the desired assignment:

image-1729155021876.png

Configuration & Administration

User specific setup

In this setup, user-specific settings are made. This gives users the option of setting the app individually to their working method and peripheral devices.

image-1694684573345.png

Configuration & Administration

SQUEEZE

The SQUEEZE page must also be prepared for fetching documents from Microsoft Dynamics Business Central.

Each document class that is to be retrieved from Microsoft Dynamics Business Central requires its own export interface of the type "Pull". In addition, the document class ID, the export interface ID and the master data table ID must be stored in Microsoft Dynamics Business Central in the setup for the SQUEEZE document classes.

If the latest SQUEEZE for BC version is not used, the following batch class properties must be set in the SQUEEZE client:


MicrosoftTeams-image.png

Validation

Visual inspection of the read documents

Validation

SQUEEZE Document Overview

The document overview lists all documents that have been read by SQUEEZE.

image-1694697704830.png

By double-clicking with the mouse or via Edit/View, a single document is opened in the validation view.

Start

image-1694697848039.png

Download Documents now

This function is used to manually execute the document pickup from SQUEEZE. Optionally, this is controlled and executed via the corresponding background job.

Upload Documents

This function will no longer be available in the future.

Navigation

image-1729155255553.png

Import Queue Entries

This menu displays a list of SQUEEZE vouchers that are ready to be imported into the SQUEEZE for BC app. By changing the system filter it is also possible to view already imported vouchers.

Cross Company Documents

Opens an cross-company document overview.

Queue

Opens an overview that gives you information about the documents in the SQUEEZE queue of the connected client.

 

 

Validation

Cross Company Document Overview

A cross-company view of all Squeeze documents is displayed here. This is updated every few seconds.
The different columns serve as jump points to open the respective client with the desired filter in a new tab.

image-1729155178545.png

Validation

Import Queue Entries

The import queue is a middle layer that imports SQUEEZE vouchers into the appropriate target companies - the target company must match the current BC company (important: the name (primary key) is crucial, not the display name) in which the vouchers are downloaded. If no target company has been detected, the documents for validation will be created in the fallback company that has been set up.

image-1671544207187.png

Navigation

Import Queue Setup

 

image-1694696990877.png

Fallback Company

Specifies the value of the fallback client. This client is used to import documents that have an empty target client in the import queue.

Warning time span (hours)

Specifies the time period after which a warning should be displayed if there are unprocessed entries.

Process

Handle unprocessed entries
Generates SQUEEZE documents from unprocessed entries in the active company. This usually happens when the recognized company does not match any company in the database.

 

Validation

SQUEEZE Document Validation

Voucher validation is the main working area of the application. Here the user checks the read documents, completes and confirms missing information.

Menu

Process

image-1647270266887.png

Open field training

The supplier-specific field training is opened over here.

Open line training

The supplier-specific position training is opened over here.

Recreate result

Here over the document is sent again to SQUEEZE to the extraction. There the Readout result re-evaluated based on current master data and training and then made available for collection again.

Start splitting

This is used to call the document separation. This is used if a supplier has sent several invoices in one PDF.

Autocomplete

The positions are automatically completed with the last validated position data of the vendor. This function is only available for documents without purchase order reference.

Order match

The order comparison is opened here.

Validate

This is used to complete the validation process of the document.

Duplicate check

Over here, the duplicate check is performed manually.

Navigation

image-1647270216798.png

Dimensions

Here you can reach the dimension menu to define dimensions for the document header.

Actions

image-1647270188616.png

Use external viewer

The viewer is undocked over here. This allows you to work on two monitors.

Move document

This is used to move a document to another client.

Download attachments

Over here you download the attachments of the document. Once the download is complete, they will be displayed in the Attachments infobox.

Fasttabs

Document

This area displays the document head information and the SQUEEZE Viewer.

image-1647270362093.png

Header fields

These fields are prefilled with the results from the document reading. The user checks these and corrects or enriches them with further data and thus completes the reading result.

The three dots highlight the location of the respective read result in the viewer.

Viewer

On the right side the SQUEEZE Viewer is displayed. This is not a PDF, but an integrated web component, which is remotely controlled from the validation. It serves for the pictorial representation of the document and for the highlighting of

Findings of read values. Furthermore, the supplier-specific field training is also carried out here.

Lines

In this area the read positions are displayed. The user checks these and corrects or enriches them with further data and thus completes the reading result.

image-1647333812518.png

If the reading result is not sufficient for invoices with purchase order reference, the purchase order/goods receipt lines can be imported directly.

image-1647333602897.png

Dimensions

Here the shortcut dimensions 1 & 2 of the document are displayed.

image-1647331335465.png

SQUEEZE Details

SQUEEZE specific document information is displayed here.

image-1647331213049.png

Infoboxes

The respective info boxes are only displayed depending on the situation.

Plausibility entries

All topics to be clarified for a successful validation are listed here.

image-1647331100105.png

Metadata boxes

The metadata mapping is only displayed if additional fields deviating from the standard have been transferred by SQUEEZE.

Metadata mapping header fields

Here additional fields from SQUEEZE are listed, which do not belong to the standard assignment of header fields.

Metadata mapping position fields

Here additional fields from SQUEEZE are listed, which do not belong to the standard assignment of the positions.

Order matching boxes

The order matching boxes are only displayed if one or more order numbers have been recognized on the document.

Order matching info (prices)

Here the price comparison is displayed for the selected line. The results of SQUEEZE, the delivery, the order and the current line are compared.

image-1647331012395.png

Order matching info (quantities)

Here the quantity comparison is displayed for the selected line. The results of SQUEEZE, the delivery, the order and the current line are compared.

image-1647331038840.png

Attachments

This info box is only displayed if the attachments have been downloaded before. The attachments can be removed again via the three dots.

image-1647331140695.png

Validation

Vendor-specific Training

Training represents an essential optimization component of processing.

If data is not clearly recognized by the system, supplier-specific training can be applied, which increases the degree of automation when entering invoices.

When the training mode is started, all relevant fields for a training can be selected.

Any number of courses can be created per supplier and per invoice field.

External invoice numbers cannot usually be checked for content in the system, as no data exists for verification. This field is ideal for training, for example.

The training window is displayed within the viewer at the bottom of the screen.

 

Head field training

Train a field

After the training function has been started, the field to be trained must be selected.

After selecting the appropriate field, define the anchor.

Anchor in this case means the reference term. In this case, the term for the external document number attached to the respective invoice. The anchor term is to be marked with the right mouse button on the document in the viewer and is then highlighted in yellow.

Then click on the "Value" field in the action area and then on the value to be searched for. This is also to be marked with the right mouse button. If the searched value is not a coherent value, an arbitrarily large area can also be marked with the right mouse button in order to read out all desired information. If the information is specified, the training can be saved via "Train".

The system generates a "regular printout" - this can be optimized by trained specialists or IT staff at any time. E.g. blanks can be ignored, since these are rarely also indicated in the ERP system / in the booking.

 

 

Testing and review of existing training

With "Test" an overview of all previous head field trainings is displayed. The results are output directly as well. Double-clicking on an entry highlights the anchor and the value in the viewer.

Removing a training

To remove a course, open the overview of existing courses and select the entry to be removed. The entry is deleted with the delete key "Del".

Position field Training

Train a column

After the training function has been started, the field to be trained and the corresponding column must be selected.

After this has been selected, the region must be defined.

This should be selected so that it covers the entire column of a field if possible. The region is to be marked with the right mouse button on the document in the viewer and is then highlighted in yellow. It should be noted that no regions should overlap with regions that have already been trained.

If the information is given, the training can be saved via "Train".

Testing and review of existing training

With "Test" an overview of all previous position field trainings is displayed. By double-clicking on an entry, the respective trained area is displayed.

Removing a training

To remove a course, open the overview of existing courses and select the entry to be removed. The entry is deleted with the delete key "Del".

Validation

Document Split

The separator function is mainly intended for email invoices. When suppliers do not adhere to the email invoice delivery default (one invoice per PDF file).

In the new window, a dialog is started to separate the documents from each other and thus turn one document into several.

image-1647335299902.png

On the left side all pages of the original PDF are listed. In the middle is the area for rebuilding and on the right you can see the currently selected page.

To split a document, the pages belonging to an invoice are transferred individually to the center area either by dragging and dropping them with the mouse or by pressing the arrow key on the keyboard.

There you can also correct the order of the pages.

If the invoice document is correctly separated, the creation of a new single document can be started with "Create document". The new document is read out directly by SQUEEZE, processed and, as soon as it is ready, also made available in the overview list. This process is repeated until the original document has been completely separated.

Validation

Order & Goods Receipt Reconciliation

The purchase order & goods receipt comparison checks the read out document items and compares them with all purchase order & goods receipt lines based on the read out purchase order numbers of the document.

The order comparison can only be opened if SQUEEZE has read one or more order numbers from the document or if an order number (stored in the system) has been entered manually in the validation header field.

This comparison is performed automatically after the document has been retrieved from SQUEEZE. The user has the possibility to perform or correct this comparison manually as well.

image-1647334058595.png

Menu

Allocate

image-1647334088082.png

Assigned lines are represented by a green tick image-1646147695338.png.

Allocate

This assigns the selected order/delivery line to the selected SQUEEZE document line.

Allocate automatically

This assigns the appropriate order/delivery line to all SQUEEZE document lines. For this, the order/delivery itself must be selected in the upper area.

Delete allocation

image-1647334163231.png

Unassigned lines are represented by a red exclamation mark image-1646147781116.png.

Delete selected allocation

This removes the assignment of the selected line.

Delete all allocations

This removes all assignments.

Apply

image-1647334307352.png

Apply selected

This applies the assignment of the selected line. Missing information will be added from the order/delivery line. This also immediately transfers this change to the validation line.

Apply all allocated

This applies the assignment of all assigned lines.  Missing information will be added from the assigned order/delivery lines. This will also immediately transfer these changes to the validation lines.

Areas

Order number

image-1647334372419.png

The order number currently to be compared is displayed here. If several order numbers have been read out, the corresponding list can be opened via the three dots.

image-1647334575927.png

Order & Deliveries

in this area the order and all its lines are listed, as well as all related deliveries and their lines.

image-1647334423530.png

SQUEEZE document lines

In this area all read out positions of the SQUEEZE document are listed.

image-1647334455644.png

Validation

Import Order / Goods Receipt Lines

Get items from purchase order / goods receipt

Menu

image-1647334663308.png

Add to import preview

This transfers all selected lines to the import preview. Selected lines are represented by a green check mark image-1646147695338.png.

Delete selected preview line

This removes all selected lines from the import preview.

Apply preview

This transfers all lines from the import preview to the document to be validated. You have the choice whether these lines should replace the SQUEEZE positions or be appended at the end.

Areas

Order number

image-1647334705846.png

The order number read out is displayed here. If several order numbers have been read out, the corresponding list can be opened via the three dots.

image-1647334780477.png

Order & Deliveries

In this area the order and all its lines are listed, as well as all related deliveries and their lines.

image-1647334876921.png

Import preview

All selected items are listed in this area.

image-1647334910671.png

Validation

External Viewer

To simplify working with the Viewer, the embedded Viewer can be undocked and thus used on a second screen.

All viewer functions, such as highlighting of header and position data, as well as the viewer's training functions are still supported.

To ensure that the undocked viewer remains active and updates itself automatically when a document is changed, the "Use external viewer only" field must be set in the user-specific setup.

image-1688735018861.png

Extension Development

This chapter lists important integration events and examples that help in developing an extension for SQUEEZE for BC. Important: Customizations may only be performed by appropriately trained consultants/developers. Furthermore, these are always outside of the standard support.

Extension Development

Adding a field in the validation (up to Squeeze Version 1.*)

The following is an example extension that shows how developers can add fields in validation.

Required integration events incl. sample procedures:

codeunit 50100 EventSubs
{
    //
    //Any header field that you want to transfer to the resulting document, has to be added to the source JSON Object
    //
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ Document Mgt.", 'OnBeforeAddLineToDocumentJObj', '', false, false)]
    local procedure SQZDocMgtOnBeforeAddLineToDocumentJObj(var DocumentJObj: JsonObject; DocHeader: Record "DXP SQZ Document Header")
    begin
        AddCustomHeaderFieldsToJson(DocumentJObj, DocHeader);
    end;

    //
    // Any line field that you want to transfer to the resulting document, has to be added to the source JSON Object
    //
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ Document Mgt.", 'OnBeforeAddLineJObjToLineJArray', '', false, false)]
    local procedure SQZDocMgtOnBeforeAddLineJObjToLineJArray(var LineJObj: JsonObject; DocLine: Record "DXP SQZ Document Line")
    begin
        AddCustomLineFieldsToJson(LineJObj, DocLine);
    end;

    //
    // [If you want to perform plausibility checks on the newly added header field, this is the place]
    //
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ Document Mgt.", 'OnAfterDoHeaderPlausibilityChecks', '', false, false)]
    local procedure SQZDocMgtOnBeforeDoHeaderPlausibilityChecks(DocHeader: Record "DXP SQZ Document Header"; var PlausibilityCheck: Codeunit "DXP Plausiblity Check Mgt.")
    begin
        CheckCustomer(PlausibilityCheck, DocHeader."Customer No.");
    end;

    //
    // [If you want to perform plausibility checks on the newly added line field, this is the place]
    //
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ Document Mgt.", 'OnAfterDoLinePlausibilityChecks', '', false, false)]
    local procedure SQZDocMgtOnAfterDoLinePlausibilityChecks(DocHeader: Record "DXP SQZ Document Header"; DocLine: Record "DXP SQZ Document Line"; var PlausibilityCheck: Codeunit "DXP Plausiblity Check Mgt.")
    begin
        CheckCustomer(PlausibilityCheck, DocLine."Customer No.");
    end;

    //
    // The value of the previously extended JSON Object now has to saved to the corresponding field in the SQUEEZE Document Line
    //
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ Document Mgt.", 'OnBeforeModifySQUEEZEDocumentHeader', '', false, false)]
    local procedure SqzDocMgtOnBeforeModifySQUEEZEDocumentHeader(var DocHeader: Record "DXP SQZ Document Header"; RawJson: JsonObject)
    var
        JSONHelper: Codeunit "DXP Json Helper";
        SQZApiTokenMgt: Codeunit "DXP SQZ API Token Mgt.";
        TokenMgt: Codeunit TokenMgt;
    begin
        DocHeader."Customer No." := COPYSTR(JsonHelper.ValAsTxt(RawJson, SQZApiTokenMgt.GetHeaderValueByNameTok(TokenMgt.GetCustomerNoTok()), false), 1, MaxStrLen(DocHeader."Customer No."));
    end;

    //
    // The value of the previously extended JSON Object now has to saved to the corresponding field in the SQUEEZE Document Header
    //
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ Document Mgt.", 'OnBeforeTransferRecognizedValuesOnAfterAssignRecognizedValues', '', false, false)]
    local procedure SQZDocMgtOnBeforeTransferRecognizedValuesOnAfterAssignRecognizedValues(RowJTok: JsonToken; var DocLine: Record "DXP SQZ Document Line")
    var
        JSONHelper: Codeunit "DXP Json Helper";
        SQZApiTokenMgt: Codeunit "DXP SQZ API Token Mgt.";
        TokenMgt: Codeunit TokenMgt;
    begin
        DocLine."Customer No." := CopyStr(JsonHelper.ValAsTxt(RowJTok.AsObject(), SQZApiTokenMgt.GetCellValueTok(TokenMgt.GetCustomerNoTok()), false), 1, MaxStrLen(DocLine."Customer No."));
    end;

    //
    // The newly added fields now have to be added to the field mapping
    // Otherwise the recognized values will be saved as meta data
    // This step is necessary to make sure that the fields can be highlighted in the SQUEEZE Viewer
    //
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ API Mgt.", 'OnAfterInitMapping', '', false, false)]
    local procedure SQZApiMgtOnAfterInitMapping(var HeaderMapping: Dictionary of [Text, Integer]; var LineMapping: Dictionary of [Text, Integer]; DocClass: Enum "DXP Document Class")
    var
        SQZDocHeader: Record "DXP SQZ Document Header";
        SQZDocLine: Record "DXP SQZ Document Line";
        TokenMgt: Codeunit TokenMgt;
    begin
        // The standard (without installed extensions) supports one Document Class
        case DocClass of
            DocClass::"DXP Invoice / Credit Memo":
                begin
                    HeaderMapping.Add(TokenMgt.GetCustomerNoTok(), SQZDocHeader.FieldNo("Customer No."));
                    LineMapping.Add(TokenMgt.GetCustomerNoTok(), SQZDocLine.FieldNo("Customer No."));
                end;
        end;
    end;

    //
    // The value in the JSON Object now has to be transferred to the Purchase Header
    //
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP Document Transfer Mgt.", 'OnAfterCreatePurchaseHeader', '', false, false)]
    local procedure DocTransferMgtOnAfterCreatePurchaseHeader(var JObject: JsonObject; PurchaseHeader: Record "Purchase Header")
    begin
        TransferCustomHeaderFieldFromJsonToPurchaseHeader(JObject, PurchaseHeader);
    end;

    //
    // The value in the JSON Object now has to be transferred to the Purchase Line
    //
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP Document Transfer Mgt.", 'OnBeforeInsertPurchaseLine', '', false, false)]
    local procedure DocTransferMgtOnAfterInsertPurchaseLineOnBeforeAddDimensions(var JObjectLine: JsonObject; var PurchaseLine: Record "Purchase Line")
    begin
        TransferCustomHeaderFieldFromJsonToPurchaseLine(JObjectLine, PurchaseLine);
    end;
    
    local procedure TransferCustomHeaderFieldFromJsonToPurchaseHeader(var JObject: JsonObject; PurchaseHeader: Record "Purchase Header")
    var
        JsonHelper: Codeunit "DXP Json Helper";
        TokenMgt: Codeunit TokenMgt;
    begin
        PurchaseHeader.Validate("DXP Customer No.", JsonHelper.ValAsTxt(JObject, TokenMgt.GetCustomerNoTok(), false));
        PurchaseHeader.Modify();
    end;

    local procedure TransferCustomHeaderFieldFromJsonToPurchaseLine(var JObjectLine: JsonObject; var PurchaseLine: Record "Purchase Line")
    var
        JsonHelper: Codeunit "DXP Json Helper";
        TokenMgt: Codeunit TokenMgt;
    begin
        PurchaseLine.Validate("DXP Customer No.", JsonHelper.ValAsTxt(JObjectLine, TokenMgt.GetCustomerNoTok(), false));
    end;

    local procedure AddCustomHeaderFieldsToJson(var DocumentJObj: JsonObject; SQZDocumentHeader: Record "DXP SQZ Document Header")
    var
        TokenMgt: Codeunit TokenMgt;
    begin
        DocumentJObj.Add(TokenMgt.GetCustomerNoTok(), SQZDocumentHeader."Customer No.");
    end;

    local procedure AddCustomLineFieldsToJson(var LineJObj: JsonObject; SQZDocumentLine: Record "DXP SQZ Document Line")
    var
        TokenMgt: Codeunit TokenMgt;
    begin
        LineJObj.Add(TokenMgt.GetCustomerNoTok(), SQZDocumentLine."Customer No.");
    end;

    [TryFunction]
    local procedure CustomerExists(CustomerNo: Code[20])
    var
        Customer: Record Customer;
    begin
        Customer.Get(CustomerNo);
    end;

    local procedure CheckCustomer(var PlausibilityCheck: Codeunit "DXP Plausiblity Check Mgt."; CustomerNo: Code[20]): Boolean
    begin
        if CustomerNo = '' then
            exit(false);

        if not CustomerExists(CustomerNo) then begin
            PlausibilityCheck.AddPlausibilityCheckEntry(GetLastErrorText(), Page::"Customer List");
            exit(false);
        end;

        exit(true);
    end;
}

Table Extensions:

SQUEEZE 4 BC
tableextension 50100 "SQZ Doc. Header Ext." extends "DXP SQZ Document Header"
{
    fields
    {
        field(50100; "Customer No."; Code[20])
        {
            TableRelation = Customer;
            ValidateTableRelation = false;
            Caption = 'Customer No.';
        }
    }
}
tableextension 50101 "SQZ Doc. Line Ext." extends "DXP SQZ Document Line"
{
    fields
    {
        field(50100; "Customer No."; Code[20])
        {
            TableRelation = Customer;
            ValidateTableRelation = false;
            Caption = 'Customer No.';
        }
    }
}
Target document (here: purchasing document)
tableextension 50102 "Purchase Header Ext." extends "Purchase Header"
{
    fields
    {
        field(50100; "DXP Customer No."; Code[20])
        {
            DataClassification = CustomerContent;
            TableRelation = Customer;
            Caption = 'DEXPRO Customer No.';
        }
    }
}

 

Page Extensions:

SQUEEZE 4 BC
pageextension 50100 "SQZ Document Ext." extends "DXP SQZ Document"
{
    layout
    {
        addafter(BuyFromVendorInternal)
        {
            field("Customer No. Internal"; Rec."Customer No.")
            {
                ApplicationArea = All;
                ToolTip = 'Specifies the value of the Customer No. field.';
                trigger OnAssistEdit()
                begin
                    MarkField(Rec.FieldNo("Customer No."), Rec."Customer No.", Rec);
                end;

                trigger OnValidate()
                begin
                    CheckPlausibility();
                end;
            }
        }
        addafter(BuyFromVendor)
        {
            field("Customer No."; Rec."Customer No.")
            {
                ApplicationArea = All;
                ToolTip = 'Specifies the value of the Customer No. field.';
                trigger OnAssistEdit()
                var
                    ApiMgt: Codeunit "DXP SQZ API Mgt.";
                    ViewerResident: Codeunit "DXP SQUEEZE Viewer Resident";
                begin
                    MarkField(Rec.FieldNo("Customer No."), Rec."Customer No.", Rec);
                end;

                trigger OnValidate()
                begin
                    CheckPlausibility();
                end;
            }
        }
    }

    local procedure MarkField(AppFldNo: Integer; FieldVal: Variant; DocHeader: Record "DXP SQZ Document Header")
    var
        ApiMgt: Codeunit "DXP SQZ API Mgt.";
        ViewerResident: Codeunit "DXP SQUEEZE Viewer Resident";
    begin
        ViewerResident := GetViewerResident();
        ApiMgt.MarkField(AppFldNo, FieldVal, ViewerResident, DocHeader);
    end;
}
pageextension 50101 "SQZ Document Sf. Ext." extends "DXP SQZ Document Subform"
{
    layout
    {
        addafter("No.")
        {
            field("Customer No."; Rec."Customer No.")
            {
                ApplicationArea = All;
                ToolTip = 'Specifies the value of the Customer No. field.';
            }
        }
    }
}
Target document (here: purchasing document)
pageextension 50102 "Purchase Invoice Ext." extends "Purchase Invoice"
{
    layout
    {
        addafter("Buy-from Vendor No.")
        {
            field("DXP Customer No."; Rec."DXP Customer No.")
            {
                ToolTip = 'Specifies the value of the DEXPRO Customer No. field.';
                ApplicationArea = all;
            }
        }
    }
}
pageextension 50103 "Purchase Inv. Sf Ext." extends "Purch. Invoice Subform"
{
    layout
    {
        addafter("No.")
        {
            field("DXP Customer No."; Rec."DXP Customer No.")
            {
                ToolTip = 'Specifies the value of the DEXPRO Customer No. field.';
                ApplicationArea = all;
            }
        }
    }
}
Optional auxiliary objects:
codeunit 50101 TokenMgt
{
    procedure GetCustomerNoTok(): Text
    begin
        exit(CustomerNoTok);
    end;

    var
        CustomerNoTok: Label 'customerNo', Locked = true;
}

 

Extension Development

Deviating use of the SQUEEZE attachments

The following is a brief explanation of how the attachments downloaded through SQUEEZE for BC can be used for a scenario that differs from the intended use.

After creating the purchasing document from the validated SQUEEZE document, you have the option to retrieve the attachments (if they have been downloaded in advance).

    // Set IsHandled to true and implement your code
    // Do not forget to deactivate "Transfer attachments to target document" in the Document Class Setup
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP Document Mgt.", 'OnBeforeTransferCoreAttachmentsToStandardDocument', '', false, false)]
    local procedure DXPDocMgtOnBeforeTransferCoreAttachmentsToStandardDocument(Document: Record "DXP Document"; var IsHandled: Boolean)
    begin
    	IsHandled := true;
        HandleCoreAttachmentsAccordingToYourNeeds(Document, IsHandled);
    end;

    procedure HandleCoreAttachmentsAccordingToYourNeeds(Document: Record "DXP Document"; var IsHandled: Boolean)
    var
        CoreAttachments: Record "DXP Document Attachment";
        InStr: InStream;
    begin
        CoreAttachments.SetRange("Document No.", Document."No.");
        CoreAttachments.IsEmpty() then
       		exit;
        CoreAttachments.FindSet();
        repeat
            CoreAttachments.Calcfields(Attachment);
            CoreAttachments.Attachment.CreateInStream(InStr);
            // Here you can handle the file stream according to your needs
         	[...]
        until CoreAttachments.Next() = 0;
    end;
Extension Development

Adding a field in the validation (from version 2.10)

The following example extension shows how developers can add fields in the validation (here: document class invoice/credit note).

Optional integration events incl. sample procedures:

codeunit 50100 EventSubs
{
    //
    // [If you want to perform plausibility checks on the newly added header field, this is the place]
    //
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ P. Inv/Crdt Memo Impl.", 'OnAfterDoHeaderPlausibilityChecks', '', false, false)]
    local procedure SQZPInvCrdtMemoImplOnBeforeDoHeaderPlausibilityChecks(DocHeader: Record "DXP SQZ Document Header"; var PlausibilityCheck: Codeunit "DXP Plausiblity Check Mgt.")
    begin
        CheckCustomer(PlausibilityCheck, DocHeader."Customer No.");
    end;

    // 
    // [If you want to perform plausibility checks on the newly added line field, this is the place]
    //
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP SQZ P. Inv/Crdt Memo Impl.", 'OnAfterDoLinePlausibilityChecks', '', false, false)]
    local procedure SQZPInvCrdtMemoImplOnAfterDoLinePlausibilityChecks(DocHeader: Record "DXP SQZ Document Header"; DocLine: Record "DXP SQZ Document Line"; var PlausibilityCheck: Codeunit "DXP Plausiblity Check Mgt.")
    begin
        CheckCustomer(PlausibilityCheck, DocLine."Customer No.");
    end;

    [TryFunction]
    local procedure CustomerExists(CustomerNo: Code[20])
    var
        Customer: Record Customer;
    begin
        Customer.Get(CustomerNo);
    end;

    local procedure CheckCustomer(var PlausibilityCheck: Codeunit "DXP Plausiblity Check Mgt."; CustomerNo: Code[20]): Boolean
    begin
        if CustomerNo = '' then
            exit(false);

        if not CustomerExists(CustomerNo) then begin
            PlausibilityCheck.AddPlausibilityCheckEntry(GetLastErrorText(), Page::"Customer List");
            exit(false);
        end;

        exit(true);
    end;
}

Table Extensions:

SQUEEZE 4 BC
tableextension 50100 "SQZ Doc. Header Ext." extends "DXP SQZ Document Header"
{
    fields
    {
        field(50100; "Customer No."; Code[20])
        {
            TableRelation = Customer;
            ValidateTableRelation = false;
            Caption = 'Customer No.';
        }
    }
}
tableextension 50101 "SQZ Doc. Line Ext." extends "DXP SQZ Document Line"
{
    fields
    {
        field(50100; "Customer No."; Code[20])
        {
            TableRelation = Customer;
            ValidateTableRelation = false;
            Caption = 'Customer No.';
        }
    }
}
Target document (here: Purchase Document)
tableextension 50102 "Purchase Header Ext." extends "Purchase Header"
{
    fields
    {
        field(50100; "DXP Customer No."; Code[20])
        {
            DataClassification = CustomerContent;
            TableRelation = Customer;
            Caption = 'DEXPRO Customer No.';
        }
    }
}

 

Page Extensions:

SQUEEZE 4 BC
pageextension 50100 "SQZ Document Ext." extends "DXP SQZ Document v2"
{
    layout
    {
        addafter(BuyFromVendorInternal)
        {
            field("Customer No. Internal"; Rec."Customer No.")
            {
                ApplicationArea = All;
                ToolTip = 'Specifies the value of the Customer No. field.';
              	//The following code is optional. It is used to highlight a recognized value in the Squeeze Viewer
                trigger OnAssistEdit()
                begin
                    MarkField(Rec.FieldNo("Customer No."), Rec."Customer No.", Rec);
                end;

                trigger OnValidate()
                begin
                    CheckPlausibility();
                end;
            }
        }
        addafter(BuyFromVendorExternal)
        {
            field("Customer No."; Rec."Customer No.")
            {
                ApplicationArea = All;
                ToolTip = 'Specifies the value of the Customer No. field.';
                //The following code is optional. It is used to highlight a recognized value in the Squeeze Viewer
                trigger OnAssistEdit()
                var
                    ApiMgt: Codeunit "DXP SQZ API Mgt.";
                    ViewerResident: Codeunit "DXP SQUEEZE Viewer Resident";
                begin
                    MarkField(Rec.FieldNo("Customer No."), Rec."Customer No.", Rec);
                end;

                trigger OnValidate()
                begin
                    CheckPlausibility();
                end;
            }
        }
    }

    local procedure MarkField(AppFldNo: Integer; FieldVal: Variant; DocHeader: Record "DXP SQZ Document Header")
    var
        ApiMgt: Codeunit "DXP SQZ API Mgt.";
        ViewerResident: Codeunit "DXP SQUEEZE Viewer Resident";
    begin
        ViewerResident := GetViewerResident();
        ApiMgt.MarkField(AppFldNo, FieldVal, ViewerResident, DocHeader);
    end;
}
pageextension 50101 "SQZ Document Sf. Ext." extends "DXP SQZ Document Subform"
{
    layout
    {
        addafter("No.")
        {
            field("Customer No."; Rec."Customer No.")
            {
                ApplicationArea = All;
                ToolTip = 'Specifies the value of the Customer No. field.';
            }
        }
    }
}
Target document (here: Purchase document)
pageextension 50102 "Purchase Invoice Ext." extends "Purchase Invoice"
{
    layout
    {
        addafter("Buy-from Vendor No.")
        {
            field("DXP Customer No."; Rec."DXP Customer No.")
            {
                ToolTip = 'Specifies the value of the DEXPRO Customer No. field.';
                ApplicationArea = all;
            }
        }
    }
}
pageextension 50103 "Purchase Inv. Sf Ext." extends "Purch. Invoice Subform"
{
    layout
    {
        addafter("No.")
        {
            field("DXP Customer No."; Rec."DXP Customer No.")
            {
                ToolTip = 'Specifies the value of the DEXPRO Customer No. field.';
                ApplicationArea = all;
            }
        }
    }
}

 

Extension Development

Alternative use of the SQUEEZE attachments

The following briefly explains how the attachments downloaded by SQUEEZE for BC can be used for a scenario that differs from the intended use.

After creating the purchase document from the validated SQUEEZE document, you have the option of accessing the attachments ( assuming they have been downloaded in advance).

    // Set IsHandled to true and implement your code
    // Do not forget to deactivate "Transfer attachments to target document" in the Document Class Setup
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"DXP Document Mgt.", 'OnBeforeTransferCoreAttachmentsToStandardDocument', '', false, false)]
    local procedure DXPDocMgtOnBeforeTransferCoreAttachmentsToStandardDocument(Document: Record "DXP Document"; var IsHandled: Boolean)
    begin
    	IsHandled := true;
        HandleCoreAttachmentsAccordingToYourNeeds(Document, IsHandled);
    end;

    procedure HandleCoreAttachmentsAccordingToYourNeeds(Document: Record "DXP Document"; var IsHandled: Boolean)
    var
        CoreAttachments: Record "DXP Document Attachment";
        InStr: InStream;
    begin
        CoreAttachments.SetRange("Document No.", Document."No.");
        CoreAttachments.IsEmpty() then
       		exit;
        CoreAttachments.FindSet();
        repeat
            CoreAttachments.Calcfields(Attachment);
            CoreAttachments.Attachment.CreateInStream(InStr);
            // Here you can handle the file stream according to your needs
         	[...]
        until CoreAttachments.Next() = 0;
    end;