Business Integration Solutions Documentation

Record Handlers

A record handler enables customizations for a specific table of an internal document through the use of interfaces.

The following Interfaces are exposed that will allow data manipulation when a RECORDGENERATOR activity runs.

Interface Description
BISIOnBeforeProcessRecord This interface can be used to execute functions or to manipulate field values before the record is validated and updated. An example is a General Journal Line which needs to be provided with a special Document No. In the method this interface exposes, the field values are set but not yet validated.
BISIOnInsertRecord This interface can be used to override the Insert trigger of a record. BC will run the OnInsert trigger of a record by default.
Attention: The record will not be inserted if this trigger does not perform an explicit INSERT statement.
BISIOnModifyRecord This interface can be used to override the Modify trigger of a record. BC will run the OnModify trigger of a record by default.
Attention: The record will not be modified if this trigger does not perform an explicit MODIFY statement.
BISIOnDeleteRecord This interface can be used to override the Delete trigger of a record. BC will run the OnDelete trigger of a record by default.
Attention: The record will not be removed when this trigger does not perform an explicit DELETE statement.
BISIOnAfterProcessRecord This interface is executed after validating the record and updating the database. It can be used to update related tables or run additional functions.

Default Record Handlers

Out of the box, 3 record handlers are available;

Handler Remarks
Base Record Handler The default handler
BIS Reopen Document Handler Implements BISIOnBeforeProcessRecord: Reopens a sales or purchase document
BIS Update Released Document Handler Implements BISIOnBeforeProcessRecord and BISIOnAfterProcessRecord: Does the same as before, and also releases the document after the record is processed

How To: Create a custom Record Handler

Usage

Use this task when you want to override one or more triggers that are run during record generation

Prerequisites

The following prerequisites are required

  • Experience in developing in Business Central AL.
  • Basic understanding of Business Integration Solutions.
  • A development license.
  1. Create a new codeunit and implement 1 to 5 interfaces
codeunit 50000 YourCustomHandler implements BISIOnBeforeProcessRecord, BISIOnInsertRecord, BISIOnModifyRecord, BISIOnDeleteRecord, BISIOnAfterProcessRecord
{
    var
        !all the procedures required by the implemented interfaces must be created
        !if in your case you only need to hook into the OnInsert method, put your logic there, and for the rest leave the Base Connector handle those
        BaseConnector: Codeunit "TIC Table Connector Base"

    procedure OnBeforeProcessRecord(var Rec: RecordRef): Boolean
    begin
        exit(BaseConnector.OnBeforeProcessRecord(rec));
    end;

    procedure OnInsertRecord(var Rec: RecordRef): Boolean
    begin
        !Add your logic that needs to be called when inserting a record here
        Rec.Field(YourTable.FieldNo(YourFieldNumber)).Value('New value');
        exit(BaseConnector.OnInsertRecord(rec));
    end;

    procedure OnModifyRecord(var Rec: RecordRef): Boolean
    begin
        exit(BaseConnector.OnModifyRecord(rec));
    end;

    procedure OnDeleteRecord(var Rec: RecordRef): Boolean
    begin
        exit(BaseConnector.OnDeleteRecord(Rec));
    end;
}
  1. Create an enum extension, that extends BISRecordHandler (if you already have one, skip to the next step)
enumextension 50000 YourEnumExtension extends BISRecordHandler
{
    ...
}
  1. Add a new value in this enum extension, that will reference your custom handler from step 1 in one or more ways
enumextension 50000 YourEnumExtension extends BISRecordHandler
{
    value(YourCustomHandlerId; YourCustomHandler)
    {
        Implementation = 
            BISIOnBeforeProcessRecord = YourCustomHandler,
            BISIOnInsertRecord = YourCustomHandler,
            BISIOnModifyRecord = YourCustomHandler,
            BISIOnDeleteRecord = YourCustomHandler,
            BISIOnAfterProcessRecord = YourCustomHandler;
    }
}

You could also have in your enum extension a mix & match scenario where you can use a combination of the custom handler and the base connector. This way you only have to implement the needed interfaces, and the rest is handled by the base connector by default. See the below example.

    !Enum extension example
    value(YourCustomHandlerId; YourCustomHandler)
    {
        Implementation = 
            BISIOnBeforeProcessRecord = YourCustomHandler,
            BISIOnInsertRecord = "BIS RecordHandler",
            BISIOnModifyRecord = "BIS RecordHandler",
            BISIOnDeleteRecord = "BIS RecordHandler",
            BISIOnAfterProcessRecord = YourCustomHandler;
    }

    !Codeunit handler example
    codeunit 50000 YourCustomHandler implements BISIOnBeforeProcessRecord, BISIOnAfterProcessRecord
    {
        procedure OnBeforeProcessRecord(var RecRef: RecordRef): Boolean
        begin
            !Execute your logic here
        end;

        procedure OnAfterProcessRecord(var RecRef: RecordRef): Boolean
        begin
            !Execute your logic here
        end;
    }
  1. Go to your recordgenerator activity setup page, and click on the design action for the linked document
  2. On the document design page, choose the table node that you want to use the new record handler

RecordHandler

Upgrading custom connectors

The following is an example of a legacy custom connector which has the OnInsertRecord hook. This would typically have the following structure.

codeunit 50000 "DemoCustomConnector"
{
    procedure OnInsertRecord(var Rec: Item): Boolean
    begin
        !// Your custom logic
    end
}

To upgrade this connector in the easiest way, carry out the following steps.

  1. Make the custom connector implement BISIOnInsertRecord.
  2. Implement the OnInsertRecord(var RecRef: RecordRef) procedure, by calling the legacy OnInsertRecord(var Rec: Item), or calling the default BISRecordHandler if the table is not supported by your logic.

codeunit 50000 DemoCustomConnector implements BISIOnInsertRecord
{
    procedure OnInsertRecord(var RecRef: RecordRef): Boolean
    var
        Rec: Record Item;
        Result: Boolean;
    begin
        if RecRef.Number() <> Database::Item then
            exit(BISRecordHandler.OnInsertRecord(RecRef));

        RecRef.SetTable(Rec);
        Result := OnInsertRecord(Rec);
        RecRef.GetTable(Rec);
        exit(Result);
    end;

    procedure OnInsertRecord(var Rec: Item): Boolean
    begin
        !// Your custom logic
    end
}

Make sure that RecRef is updated again before exiting using the RecRef.GetTable procedure.

  1. Add the codeunit to an enum extension extending BISRecordHandler.
enumextension 50000 "DemoRecordHandler" extends BISRecordHandler
{
    value(50000; DemoHandler)
    {
        Caption = 'Demo Record Handler';
        Implementation = BISIOnBeforeProcessRecord = "BIS RecordHandler",
                     BISIOnInsertRecord = DemoCustomConnector,
                     BISIOnModifyRecord = "BIS RecordHandler",
                     BISIOnDeleteRecord = "BIS RecordHandler",
                     BISIOnAfterProcessRecord = "BIS RecordHandler";
    }

Remember that one codeunit can implement multiple interfaces.


Also see the Custom Connector approach