Saltar al contenido

Evento de Estado del Ticket

El sistema de tickets de Business Portals puede activar un evento cuando el estado del ticket se cambia en el frontend. Este cambio de estado se envía a Business Central, donde puede ser procesado por un codeunit personalizado para realizar acciones como registrar la interacción o calcular cuánto tiempo ha estado el ticket en el estado anterior.

Esta sección proporciona un ejemplo de cómo implementar un codeunit personalizado que se activa cuando el estado del ticket es cambiado por el usuario.

Ejemplo de Código

En este ejemplo, utilizaremos la tabla Ticket en un escenario donde cambiar el estado del ticket activa un evento que puede, por ejemplo, registrar el historial de interacciones y/o calcular cuánto tiempo ha estado el ticket en el estado anterior.

El cambio de estado del ticket envía datos a Business Central, donde se procesa en un codeunit de Business Central.

AL
// Parámetro de Registro de Interacción Web
'LogWebInteraction':
    begin
        EnsureInteractionTemplateExists();
        CreateInteractionLog(Rec, LocalRecordSIMDPSTicketStatus);
    end;

// Parámetro de Registro de Tiempo de Transición
'LogTransitionTime':
    CalculateTransitionTime(Rec);

// Parámetro de Registro de Interacción Web y Tiempo de Transición
'LogWebAndTransitionTime':
    begin
        EnsureInteractionTemplateExists();
        CreateInteractionLog(Rec, LocalRecordSIMDPSTicketStatus);
        CalculateTransitionTime(Rec);
    end;

// Este Procedimiento asegura que el grupo de interacción exista en las Entradas de Registro de Interacción, si no existe, lo crearemos
local procedure EnsureInteractionTemplateExists()
    var
        LocalRecordInteractionTemplate: Record "Interaction Template";
        LocalRecordInteractionGroup: Record "Interaction Group";
    begin
        // Verificación de Seguridad: Asegurarse de que el Grupo de Interacción exista para prevenir errores de validación
        if not LocalRecordInteractionGroup.Get('TICKET') then begin
            LocalRecordInteractionGroup.Init();
            LocalRecordInteractionGroup.Code := 'TICKET';
            LocalRecordInteractionGroup.Description := 'Operaciones de Ticket';
            LocalRecordInteractionGroup.Insert();
        end;

        // Crear la Plantilla de Interacción si falta
        if not LocalRecordInteractionTemplate.Get('TKT_STATUS') then begin
            LocalRecordInteractionTemplate.Init();
            LocalRecordInteractionTemplate.Code := 'TKT_STATUS';
            LocalRecordInteractionTemplate."Interaction Group Code" := 'TICKET';
            LocalRecordInteractionTemplate.Description := 'Cambio de Estado del Ticket';

            // Establecer el Tipo de Correspondencia Predeterminado en blanco (Espacio) usando la referencia de Enum/Opción
            LocalRecordInteractionTemplate."Correspondence Type (Default)" := LocalRecordInteractionTemplate."Correspondence Type (Default)"::" ";

            LocalRecordInteractionTemplate.Insert();
        end;
    end;

// Este Procedimiento crea el registro de interacción en las Entradas de Registro de Interacción
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 cambiado a %2 (%3)', Comment = '%1 = Número de Ticket, %2 = Estado del Ticket, %3 = Categoría del Ticket';
    begin
        // Asegurar el siguiente Número de Entrada para el Registro de Interacción
        LocalRecordInteractionLogEntry.LockTable();
        if LocalRecordInteractionLogEntry.FindLast() then
            LocalRecordInteractionLogEntry."Entry No." += 1
        else
            LocalRecordInteractionLogEntry."Entry No." := 1;

        // Inicializar campos de auditoría estándar
        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));

        // Asignar códigos de Plantilla
        LocalRecordInteractionLogEntry."Interaction Template Code" := 'TKT_STATUS';
        LocalRecordInteractionLogEntry."Interaction Group Code" := 'TICKET';

        // -------------------------------------------------------------------------
        // LÓGICA DE MAPEADO DE CONTACTO
        // -------------------------------------------------------------------------
        LocalContactFoundBoolean := false;

        // Verificar el Mapeo de Negocios del Usuario Web
        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;

        // Respaldo para Usuarios Internos de BC
        if not LocalContactFoundBoolean then begin
            LocalRecordContact.Reset();
            LocalRecordContact.SetRange(Type, LocalRecordContact.Type::Company);
            LocalRecordContact.SetRange("Company Name", CompanyName());

            // Si existe un contacto de empresa genérico para la empresa BC actual, enlazarlo
            if LocalRecordContact.FindFirst() then
                LocalRecordInteractionLogEntry."Contact No." := LocalRecordContact."No.";
        end;

        // Confirmar en el Registro de Interacción
        LocalRecordInteractionLogEntry.Insert(true);
    end;

// Este Procedimiento calcula el tiempo de transición desde que el estado cambió por última vez
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;