Coding tips (for partners)

Add custom fields to the VJS

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 VJS, 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 VJS. This means that every scheduling action or modification you carry out in the VJS first impacts the simulation  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

  • Jobs => "NETVJS SIMJob"
  • Job Planning Lines => "NETVJS SIMJobPlanningLine"
  • Job Tasks => "NETVJS SIMJobTask"

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 JobBCExt extends Job

{

    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 JobExt extends "NETVJS SIMJob"

{

    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 "Job" extends "Job Card"

{

    layout

    {

        addlast(General)

        {

            field("CustomField"; "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 VJS : 

"dependencies": [

        {

      "appId": "9a08bc1f-7ac9-4671-b212-9076b2869e80",

      "name": "Visual Jobs 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 these 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 "ResExtension" extends Resource
{
   fields
   {
//Examples how to calculate BC data
       // Count("Resource" 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("Res. Capacity Entry".Capacity WHERE(
                            "Resource No." = FIELD("No."),                            
                            Date = FIELD("Date Filter")));
           Caption = 'Capacity (CustomDefinition)';
           DecimalPlaces = 0 : 5;
           Editable = false;
           FieldClass = FlowField;
       }
   }
}

The SIM tables enhancements done by the partner

tableextension 60003 "ResSIMExtension" extends "NETVJS SIMResource"
{
   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 VJS 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

    [EventSubscriber(ObjectType::Codeunit, Codeunit::"NETVJS IntegrationMgmt", 
  'OnBeforeTransferResource', '', false, false)]

    local procedure handleOnBeforeTransferResource(pClientGuid: Guid; var 
   pResourceRecord: Record Resource; var pHandled: Boolean)

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

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

VSJ-add custom fields