Skip to content

Ticket Status Event

Business Portals ticketing system can trigger an event when the ticket status is changed on the frontend. This status change is sent to Business Central, where it can be processed by a custom codeunit to perform actions such as logging the interaction or calculating how long the ticket has been sitting in the previous status.

This section provides an example of how to implement a custom codeunit that is triggered when the ticket status is changed by the user.

Code Example

In this example, we will use the Ticket table in a scenario where changing the ticket status triggers an event that can, for instance, log the interaction history and/or calculate how long the ticket has been sitting in the previous status.

The changing of ticket status sends data to Business Central, where it is processed in a Business Central codeunit.

AL
// Log Web Interaction parameter
'LogWebInteraction':
    begin
        EnsureInteractionTemplateExists();
        CreateInteractionLog(Rec, LocalRecordSIMDPSTicketStatus);
    end;

// Log Transition Time parameter
'LogTransitionTime':
    CalculateTransitionTime(Rec);

// Log both Web Interaction and Transition Time parameter
'LogWebAndTransitionTime':
    begin
        EnsureInteractionTemplateExists();
        CreateInteractionLog(Rec, LocalRecordSIMDPSTicketStatus);
        CalculateTransitionTime(Rec);
    end;

// This Procedure is to ensure that interaction group exist in Interaction Log Entries, if it doesn't exist then we will create it
local procedure EnsureInteractionTemplateExists()
    var
        LocalRecordInteractionTemplate: Record "Interaction Template";
        LocalRecordInteractionGroup: Record "Interaction Group";
    begin
        // Safety Check: Ensure the Interaction Group exists to prevent validation errors
        if not LocalRecordInteractionGroup.Get('TICKET') then begin
            LocalRecordInteractionGroup.Init();
            LocalRecordInteractionGroup.Code := 'TICKET';
            LocalRecordInteractionGroup.Description := 'Ticket Operations';
            LocalRecordInteractionGroup.Insert();
        end;

        // Create the Interaction Template if it is missing
        if not LocalRecordInteractionTemplate.Get('TKT_STATUS') then begin
            LocalRecordInteractionTemplate.Init();
            LocalRecordInteractionTemplate.Code := 'TKT_STATUS';
            LocalRecordInteractionTemplate."Interaction Group Code" := 'TICKET';
            LocalRecordInteractionTemplate.Description := 'Ticket Status Change';

            // Set Default Correspondence Type to blank (Space) using the Enum/Option reference
            LocalRecordInteractionTemplate."Correspondence Type (Default)" := LocalRecordInteractionTemplate."Correspondence Type (Default)"::" ";

            LocalRecordInteractionTemplate.Insert();
        end;
    end;

// This Procedure creates the interaction log in Interaction Log Entries
local procedure CreateInteractionLog(var ParamRecordSIMDPSTicket: Record "SIM_DPS Ticket"; ParamRecordSIMDPSTicketStatus: Record "SIM_DPS Ticket Status")
    var
        LocalRecordInteractionLogEntry: Record "Interaction Log Entry";
        LocalRecordSIMDPSWUBusinessMapping: Record "SIM_DPS WU Business Mapping";
        LocalRecordContact: Record Contact;
        LocalContactFoundBoolean: Boolean;
        LocalStatusChangeLabelMsg: Label 'Ticket %1 changed to %2 (%3)', Comment = '%1 = Ticket Number, %2 = Ticket Status, %3 = Ticket Category';
    begin
        // Secure the next Entry No. for the Interaction Log
        LocalRecordInteractionLogEntry.LockTable();
        if LocalRecordInteractionLogEntry.FindLast() then
            LocalRecordInteractionLogEntry."Entry No." += 1
        else
            LocalRecordInteractionLogEntry."Entry No." := 1;

        // Initialize standard auditing fields
        LocalRecordInteractionLogEntry.Init();
        LocalRecordInteractionLogEntry.Date := Today();
        LocalRecordInteractionLogEntry."Time of Interaction" := Time();
        LocalRecordInteractionLogEntry."User ID" := CopyStr(UserId(), 1, MaxStrLen(LocalRecordInteractionLogEntry."User ID"));

        LocalRecordInteractionLogEntry.Description :=
            CopyStr(StrSubstNo(LocalStatusChangeLabelMsg, ParamRecordSIMDPSTicket."No.", ParamRecordSIMDPSTicketStatus.Code, ParamRecordSIMDPSTicketStatus.Category), 1, MaxStrLen(LocalRecordInteractionLogEntry.Description));

        // Assign Template codes
        LocalRecordInteractionLogEntry."Interaction Template Code" := 'TKT_STATUS';
        LocalRecordInteractionLogEntry."Interaction Group Code" := 'TICKET';

        // -------------------------------------------------------------------------
        // CONTACT MAPPING LOGIC
        // -------------------------------------------------------------------------
        LocalContactFoundBoolean := false;

        // Check the Web User Business Mapping
        LocalRecordSIMDPSWUBusinessMapping.Reset();
        LocalRecordSIMDPSWUBusinessMapping.SetRange(Username, ParamRecordSIMDPSTicket.Author);
        LocalRecordSIMDPSWUBusinessMapping.SetRange(Company, CompanyName());
        LocalRecordSIMDPSWUBusinessMapping.SetRange("DPS Business Mapping Code", 'CONTACT');

        if LocalRecordSIMDPSWUBusinessMapping.FindFirst() then begin
            LocalRecordInteractionLogEntry."Contact No." := LocalRecordSIMDPSWUBusinessMapping."No.";
            LocalContactFoundBoolean := true;
        end;

        // Fallback for Internal BC Users
        if not LocalContactFoundBoolean then begin
            LocalRecordContact.Reset();
            LocalRecordContact.SetRange(Type, LocalRecordContact.Type::Company);
            LocalRecordContact.SetRange("Company Name", CompanyName());

            // If a generic company contact exists for the current BC Company, link it
            if LocalRecordContact.FindFirst() then
                LocalRecordInteractionLogEntry."Contact No." := LocalRecordContact."No.";
        end;

        // Commit to the Interaction Log
        LocalRecordInteractionLogEntry.Insert(true);
    end;

// This Procedure calculates the transition time from when the status last changed
local procedure CalculateTransitionTime(var ParamRecordSIMDPSTicket: Record "SIM_DPS Ticket")
    begin
        if ParamRecordSIMDPSTicket."Status Last Changed At" <> 0DT then
            ParamRecordSIMDPSTicket."Transition Duration" := CurrentDateTime() - ParamRecordSIMDPSTicket."Status Last Changed At"

        else
            if ParamRecordSIMDPSTicket.Created <> 0DT then
                ParamRecordSIMDPSTicket."Transition Duration" := CurrentDateTime() - ParamRecordSIMDPSTicket.Created;
    end;