Coding tips (for partners)

Add custom fields to the VPS

In addition to the default fields available in tooltip, label, and table text, it is possible to equip custom fields with data to use them in tooltip, bar label, and table text.

By opening the VPS, the Dynamics 365 BC data tables (containing the necessary data for the visualization) are copied automatically into the extension one to one as so-called SIM (Simulation) data tables and from there are taken to be visualized in the VPS. This means that every scheduling action or modification you carry out in the VPS first impacts the simulation data and only when you press the "Save" button the data will be written back to BC. 

These Dynamics 365 BC data tables copied into SIM data tables are

  • Production Order => "NETVPS SIMPrdOrdr"
  • Prod. Order Line => "NETVPS SIMPrdOrdrLn"
  • Prod. Order Routing Line => "NETVPS SIMPrdOrdrRtngLn"
  • Work Center Group => "NETVPS SIMWrkCntrGrp"
  • Work Center => "NETVPS SIMWrkCntr"
  • Machine Center => "NETVPS SIMMchnCntr"

So if you want to have additional data fields showing in tooltip, label or table text, you have to create 

  1. a table extension for adding the field to the BC table
  2. a table extension for adding the field to the SIM table
  3. if necessary: a page extension for populating the field with data
  • The BC table extension

The extension for the BC table adds the custom data field to the BC table:

tableextension 60001 POBCExt extends "Production Order"

{

    fields

    {

        field(60000; "CustomField"; Code[20])

        {

            DataClassification = CustomerContent;

        }

    }

}
  • The simulation table extension

With this extension, the custom field you have added to the BC table gets added to the SIM table accordingly . 

Please note that the data fields numbers have to be identical.

tableextension 60000 POExt extends "NETVPS SIMPrdOrdr"

{

    fields

    {

        field(60000; "CustomField"; Code[20])

        {

            DataClassification = CustomerContent;

        }

    }

}
  • Population of the BC data field by page extension

Once your field is created it needs to be filled with values. This can be done either by code or by a page extension like shown below:

pageextension 60002 "ProdOrder" extends "Planned Production Order"

{

    layout

    {

        addlast(General)

        {

            field("CustomField"; Rec.CustomField)

            {

                ApplicationArea = All;

            }

        }

    }

}

How to proceed

Step 1

  • Open Visual Studio Code and add a new project with a new al. file. 
  • Create the extension(s) you need like described above.  Please note that the two data fields must have the same id. 

Step 2

The file app.json should contain the dependency for the VPS :

"dependencies": [

        {

      "appId": "5716C909-A743-461e-AC12-D99759152986",

      "name": "Visual Production Scheduler",

      "publisher": "NETRONIC Software GmbH",

      "version": "x.x.x.x"

    }

Step 3

Publish your extensions and the newly added data field will be listed in the configuration for tooltip, label or table text.

 

Result

 

OnBeforeTransfer events

The OnBeforeTransfer events can be used to modify Business Central data before transferring them into our simulation data. This way, the customer can use flow fields, for example. The values of a field class Flowfield of standard BC are dynamically calculated and can be used in fields added by partners, but currently they are not triggered to get calculated during data transmission from Business Central to the SIM tables. By using the new events, these fields can nevertheless be processed in a meaningful way and can be provided for tooltip, bar, and label texts.

The BC enhancements done by the partner:

tableextension 60002 "MCExtension" extends "Machine Center"
{
   fields
   {
//Examples how to calculate BC data
       // Count("Machine Center" WHERE("No." = FIELD("No.")));
       // Count(<DestinationTable> [WHERE (<TableFilters>)]) 
       // Sum(<DestinationTable>.<DestinationFieldName> [WHERE(<TableFilters>)])
       // Average(<DestinationTable>.<DestinationFieldName> [WHERE(<TableFilters>)]) |
       // Min(<DestinationTable>.<DestinationFieldName> [WHERE(<TableFilters>)]) |
       // Max(<DestinationTable>.<DestinationFieldName> [WHERE(<TableFilters>)]) |
       // Lookup(<DestinationTable>.<DestinationFieldName> [WHERE(<TableFilters>)])

      //This field already exists in BC
       field(60000; "Capacity (CustomDefinition)"; Decimal)
       {
           CalcFormula = Sum("Calendar Entry"."Capacity (Effective)" WHERE("Capacity Type"
= CONST("Machine Center"), "No." = FIELD("No."),
"Work Shift Code" = FIELD("Work Shift Filter"),
                            Date = FIELD("Date Filter")));
           Caption = 'Capacity (CustomDefinition)';
           DecimalPlaces = 0 : 5;
           Editable = false;
           FieldClass = FlowField;
       }
   }
}

The SIM tables enhancements done by the partner

tableextension 60003 "MCSIMExtension" extends "NETVPS SIMMchnCntr"
{
   fields
   {
       field(60000; "Capacity (CustomDefinition)"; Decimal)
       {
           Caption = 'Capacity (CustomDefinition)';
           DecimalPlaces = 0 : 5;
           Editable = false;
           FieldClass = Normal;
       }
   }
}

Please note that the data fields numbers have to be identical.

The events occur on loading or reloading and are structured as follows:

OnBeforeTransferBCTableName(pClientGuid: Guid; var pBCTableNameRecord: Record “BCTableName” var pHandled: Boolean)

For more details on the events' structure see here.

The event delivers the BC record to be transferred. Then an own or an already existing FlowFilter can be set and FlowField values be calculated – the new value will be stored in the record. After this, the VPS will process the record and transfer it to the SIM tables. The calculated value is then used as well but it is also possible to describe “nonFlowFields” so that the BC data for the simulation can be modified.

Example 1

    [EventSubscriber(ObjectType::Codeunit, Codeunit::"NETVPS IntegrationMgmt", 
'OnBeforeTransferMachineCenter', '', false, false)]

    local procedure handleOnBeforeTransferMachineCenter(pClientGuid: Guid; var 
pMachineCenter: Record "Machine Center"; var pHandled: Boolean)

   var
       adate: Date;
   begin
       if gEventHandlingActivate then begin
           adate := WorkDate();
           pMachineCenter."Date Filter" := adate;
           pMachineCenter.SetRange("Date Filter", adate);
           pMachineCenter.SetRange("Work Shift Filter", '1');
           if pMachineCenter.CalcFields("Capacity (CustomDefinition)") then;
           pHandled := true;
       end;
    end;

Example 2

//This field is calculated by ourselves

tableextension 60004 "WCExtension" extends "Work Center"
{
   fields
   {
       field(60001; "WCNoOfMCs (CustomDefinition)"; Integer)
       {
           CalcFormula = Count("Machine Center" WHERE("Work Center No." = FIELD("No.")));
           Caption = 'WC Count of MCs per WC';
           Editable = false;
           FieldClass = FlowField;
       }
   }
}

tableextension 60005 "WCSIMExtension" extends "NETVPS SIMWrkCntr"
{
   fields
   {
       field(60001; "WCNoOfMCs (CustomDefinition)"; Integer)
       {
           Caption = 'WC Count of MCs per WC';
           Editable = false;
           FieldClass = Normal;
       }
   }
}

   [EventSubscriber(ObjectType::Codeunit, Codeunit::"NETVPS IntegrationMgmt", 
'OnBeforeTransferWorkCenter', '', false, false)]
    local procedure handleOnBeforeTransferWorkCenter(pClientGuid: Guid; var pWorkCenter: 
Record "Work Center"; var pHandled: Boolean)

   begin

       if gEventHandlingActivate then begin
           pWorkCenter.SetRange("No.", pWorkCenter."No.");
           if pWorkCenter.CalcFields("WCNoOfMCs (CustomDefinition)") then;
           pHandled := true;
       end;
    end;

These data can be displayed in tooltip, bar, or table.