CRM – Events (USD)


Pessoal,

Seguindo a série de posts sobre o USD, irei escrever neste post sobre os Events!

Para ver os posts anteriores, acesse os links (estão por ordem de publicação do mais recente para o mais antigo):

CRM – Action Calls (USD)

CRM – Toolbars e Buttons (USD)

CRM – Agent Scripts (USD)

CRM – Scriptlets (USD)

CRM – Hosted Controls (USD)

CRM – Componentes do USD

CRM Utilidades do USD (Unified Service Desk)

Diferentemente das Action Calls, os Events representam ações (triggers) que são pré determinadas pelos controles, elas irão possuir e executar a partir do momento em que sejam adicionados ou interagidos no USD.

De acordo com o tipo do controle, nativamente, temos alguns Eventos que sempre podem ser adicionados ao controle USD:

events_2Hosted Control do tipo CRM Page

Apesar de termos eventos padrões, podemos criar nossos próprios eventos e decidirmos quando que eles serão adicionados.

Um outro ponto muito bom dos eventos é que conseguimos adicionar quantas Action Calls necessitarmos em um único evento, além disso, é possível determinar a ordem em que as Actions irão ser executadas. Um bom exemplo disso é o hosted control “CRM Global Manager”, ao ser inicializado, ou seja no evento “DesktopReady”, ele executa por padrão as seguintes actions calls:

events_3

Como também já tive que fazer alguns exemplos nos posts anteriores que envolvem o uso de Events, vou inserir neste post, um forma diferente de usarmos…

No post sobre Action Calls, nos dois exemplos estão realizando via C# uma chamada a uma Action Call, podemos fazer da mesma forma, porém usando Events! Assim, conseguimos ter duas coisas a mais:

1 – Ao criar e executar um Event, conseguimos ter um reaproveitamento de código

2 – Podemos acionar mais do que uma Action Call com apenas um acionamento de um único Event

Deste modo, devemos trocar uma chamada a Action:

// Action
var action = new ActionDefinition
{
    Application = "APPLICATION_NAME", // Hosted Control
    Action = "ACTION_NAME", // Action
    ActionData = "DATA_VALUE" // Data
};

// Execute Actions
CRMWindowRouter.ExecuteActions(localSessionManager.ActiveSession,
    new List<ActionDefinition> { action }, string

Por uma chamada à um Event:

// Event
FireEvent("EVENT_NAME");

No post de Action Calls, fiz um Custom Hosted Control que ao selecionarmos a opção “Ocorrência” do Radio Button e clicar no botão “Ok”, executava uma chamada de uma Action Call.

Agora, fiz um pequeno ajuste, para um nova opção no radio button “Ocorrência e Oportunidade”, que ao selecionarmos e submetermos abrirá duas novas abas (temos que possuir uma sessão com o cliente aberta):

events_4

 

O código, muda muito pouco…

XAML:

<USD:DynamicsBaseHostedControl x:Class="CustomUSDHostedControl.USDControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:USD="clr-namespace:Microsoft.Crm.UnifiedServiceDesk.Dynamics;assembly=Microsoft.Crm.UnifiedServiceDesk.Dynamics" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ToolBarTray Name="ProgrammableToolbarTray" Grid.Row="0" Focusable="false"/>  <!-- this is where any toolbar assigned to this control will go -->

        <Button Name="button" Click="button_Click" HorizontalAlignment="Left" Margin="64,202,0,0" Grid.Row="1" Content="Ok" VerticalAlignment="Top" Width="52" Height="22" />
        <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="78,47,0,0" Grid.Row="1" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
        <RadioButton x:Name="radioButtonInfo" Content="Informação" GroupName="options" HorizontalAlignment="Left" Margin="78,94,0,0" Grid.Row="1" VerticalAlignment="Top"/>
        <RadioButton x:Name="radioButtonOcor" Content="Ocorrência" GroupName="options" HorizontalAlignment="Left" Margin="174,94,0,0" Grid.Row="1" VerticalAlignment="Top" />
        <RadioButton x:Name="radioButtonOcorOp" Content="Ocorrência e Oportunidade" GroupName="options" HorizontalAlignment="Left" Margin="80,133,0,0" Grid.Row="1" VerticalAlignment="Top" />

    </Grid>
</USD:DynamicsBaseHostedControl>

C# (atenção no evento de click do botão “Ok” – button_Click):

// =====================================================================
//  This file is part of the Microsoft Dynamics CRM SDK code samples.
//
//  Copyright (C) Microsoft Corporation.  All rights reserved.
//
//  This source code is intended only as a supplement to Microsoft
//  Development Tools and/or on-line documentation.  See these other
//  materials for detailed information regarding Microsoft code samples.
//
//  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
// =====================================================================

using System;
using System.Globalization;
using System.Windows;
using Microsoft.Crm.UnifiedServiceDesk.CommonUtility;
using Microsoft.Crm.UnifiedServiceDesk.Dynamics;
using System.Collections.Generic;
using Microsoft.Crm.UnifiedServiceDesk.Dynamics.Utilities;

namespace CustomUSDHostedControl
{
    ///

<summary>
    /// Interaction logic for USDControl.xaml
    /// This is a base control for building Unified Service Desk Aware add-ins
    /// See USD API documentation for full API Information available via this control.
    /// </summary>


    public partial class USDControl : DynamicsBaseHostedControl
    {
        #region Vars
        ///

<summary>
        /// Log writer for USD 
        /// </summary>


        private TraceLogger LogWriter = null;

        #endregion

        ///

<summary>
        /// UII Constructor 
        /// </summary>


        /// <param name="appID">ID of the application</param>
        /// <param name="appName">Name of the application</param>
        /// <param name="initString">Initializing XML for the application</param>
        public USDControl(Guid appID, string appName, string initString)
            : base(appID, appName, initString)
        {
            InitializeComponent();

            // This will create a log writer with the default provider for Unified Service desk
            LogWriter = new TraceLogger();

            #region Enhanced LogProvider Info
            // This will create a log writer with the same name as your hosted control. 
            // LogWriter = new TraceLogger(traceSourceName:"MyTraceSource");

            // If you utilize this feature,  you would need to add a section to the system.diagnostics settings area of the UnifiedServiceDesk.exe.config
            //<source name="MyTraceSource" switchName="MyTraceSwitchName" switchType="System.Diagnostics.SourceSwitch">
            //    <listeners>
            //        <add name="console" type="System.Diagnostics.DefaultTraceListener"/>
            //        <add name="fileListener"/>
            //        <add name="USDDebugListener" />
            //        <remove name="Default"/>
            //    </listeners>
            //</source>

            // and then in the switches area : 
            //<add name="MyTraceSwitchName" value="Verbose"/>

            #endregion

        }

        ///

<summary>
        /// Raised when the Desktop Ready event is fired. 
        /// </summary>


        protected override void DesktopReady()
        {
            // this will populate any toolbars assigned to this control in config. 
            PopulateToolbars(ProgrammableToolbarTray);
            base.DesktopReady();
        }

        ///

<summary>
        /// Raised when an action is sent to this control
        /// </summary>


        /// <param name="args">args for the action</param>
        protected override void DoAction(Microsoft.Uii.Csr.RequestActionEventArgs args)
        {
            // Log process.
            LogWriter.Log(string.Format(CultureInfo.CurrentCulture, "{0} -- DoAction called for action: {1}", this.ApplicationName, args.Action), System.Diagnostics.TraceEventType.Information);

            #region Example process action
            //// Process Actions. 
            //if (args.Action.Equals("your action name", StringComparison.OrdinalIgnoreCase))
            //{
            //    // Do some work

            //    // Access CRM and fetch a Record
            //    Microsoft.Xrm.Sdk.Messages.RetrieveRequest req = new Microsoft.Xrm.Sdk.Messages.RetrieveRequest(); 
            //    req.Target = new Microsoft.Xrm.Sdk.EntityReference( "account" , Guid.Parse("0EF05F4F-0D39-4219-A3F5-07A0A5E46FD5")); 
            //    req.ColumnSet = new Microsoft.Xrm.Sdk.Query.ColumnSet("accountid" , "name" );
            //    Microsoft.Xrm.Sdk.Messages.RetrieveResponse response = (Microsoft.Xrm.Sdk.Messages.RetrieveResponse)this._client.CrmInterface.ExecuteCrmOrganizationRequest(req, "Requesting Account"); 


            //    // Example of pulling some data out of the passed in data array
            //    List<KeyValuePair<string, string>> actionDataList = Utility.SplitLines(args.Data, CurrentContext, localSession);
            //    string valueIwant = Utility.GetAndRemoveParameter(actionDataList, "mykey"); // asume there is a myKey=<value> in the data. 



            //    // Example of pushing data to USD
            //    string global = Utility.GetAndRemoveParameter(actionDataList, "global"); // Assume there is a global=true/false in the data
            //    bool saveInGlobalSession = false;
            //    if (!String.IsNullOrEmpty(global))
            //        saveInGlobalSession = bool.Parse(global);

            //    Dictionary<string, CRMApplicationData> myDataToSet = new Dictionary<string, CRMApplicationData>();
            //    // add a string: 
            //    myDataToSet.Add("myNewKey", new CRMApplicationData() { name = "myNewKey", type = "string", value = "TEST" });

            //    // add a entity lookup:
            //    myDataToSet.Add("myNewKey", new CRMApplicationData() { name = "myAccount", type = "lookup", value = "account,0EF05F4F-0D39-4219-A3F5-07A0A5E46FD5,MyAccount" }); 

            //    if (saveInGlobalSession) 
            //    {
            //        // add context item to the global session
            //        ((DynamicsCustomerRecord)((AgentDesktopSession)localSessionManager.GlobalSession).Customer.DesktopCustomer).MergeReplacementParameter(this.ApplicationName, myDataToSet, true);
            //    }
            //    else
            //    {
            //        // Add context item to the current session. 
            //        ((DynamicsCustomerRecord)((AgentDesktopSession)localSessionManager.ActiveSession).Customer.DesktopCustomer).MergeReplacementParameter(this.ApplicationName, myDataToSet, true);
            //    }
            //}
            #endregion

            if (args.Action.Equals("ButtonClick", StringComparison.OrdinalIgnoreCase))
            {
                // Get Data Value
                var dataValue = args.DataObject.ToString();

                // Set Data Value in TextBox
                textBox.Text = dataValue;
            }

            base.DoAction(args);
        }

        ///

<summary>
        /// Raised when a context change occurs in USD
        /// </summary>


        /// <param name="context"></param>
        public override void NotifyContextChange(Microsoft.Uii.Csr.Context context)
        {
            base.NotifyContextChange(context);
        }


        #region User Code Area
        private void button_Click(object sender, RoutedEventArgs e)
        {
            // Verify if radio "Ocorrência e Oportunidade" is Checked
            if (radioButtonOcorOp.IsChecked == true)
            {
                // Event
                FireEvent("Event Open Incident and Opportunity");

                textBox.Text = "Incident and Opportunity Opened!";
            }
            // Verify if radio "Ocorrência" is Checked
            else if (radioButtonOcor.IsChecked == true)
            {
                // Action
                var openIncident = new ActionDefinition
                {
                    Application = "Incident", // Hosted Control
                    Action = "New_CRM_Page", // Action
                    ActionData = "LogicalName=incident" // Data
                };

                // Execute Actions
                CRMWindowRouter.ExecuteActions(localSessionManager.ActiveSession,
                    new List<ActionDefinition> { openIncident }, string.Empty, new Dictionary<string, string>());

                textBox.Text = "Incident Opened!";
            }
            else
            {
                textBox.Text = "Button Fired!";
            }
        }
        #endregion
    }
}

Compile o projeto e adicione a DLL dentro da pasta raiz do USD!

No CRM, temos que criar um Hosted Control Evento, duas Action Calls e uma Windows Navigation Rule.

Caso você não possua um Hosted Control do tipo CRM Page que seja para uma Oportunidade, precisará criar um. Abra seu CRM, navegue me Configurações > Unified Service Desk > Hosted Controls > Novo:

events_9

Precisamos informar:

  • Name – O nome de seu hosted control
  • USD Component Type – CRM Page
  • Display Group – “MainPanel”, não é global é só será aberto quando alguma ação for disparada, quando ocorrer, será apresentado no MainPanel

 

Agora localize o Hosted Control que criamos anteriormente no post de Action Calls “CustomUSDHostedControl” (Configurações > Unified Service Desk > Hosted Controls):

actioncalls_12

Abra o relacionamento do Hosted Control com seus Eventos:

events_5

Depois devemos criar nosso Evento, basta informar um nome. Ao salvar, podemos criar as duas Actions:

events_6

A primeira Action, abrirá uma Ocorrência:

events_7

Devemos informar:

  • Name – O nome de sua action call
  • Hosted Control – “CustomUSDHostedControl”, o nome do nosso Custom Hosted Control
  • Action – “New_CRM_Page”, uma nova página do CRM
  • Data – “LogicalName=incident”, o formulário de Ocorrências do CRM

A segunda Action Call, abrirá o formulário de Oportunidade:

events_8

Devemos informar:

  • Name – O nome de sua action call
  • Hosted Control – “CustomUSDHostedControl”, o nome do nosso Custom Hosted Control
  • Action – “New_CRM_Page”, uma nova página do CRM
  • Data – “LogicalName=incident”, o formulário de Ocorrências do CRM

Por fim, precisamos criar um Window Navigation Rule, para que a aba seja aberta (RouteWindow). A ocorrência abrirá sem problemas, pois já temos uma regra para ela nativamente.

Navegue em Configurações > Unified Service Desk > Windows Navigation Rules > Novo:

events_10

Informe:

Devemos informar:

  • Name – O nome de sua window navigation rule
  • Order – A ordem de execução, insira um número alto, para garantirmos que será uma das últimas ações a serem executadas
  • Entity – “opporunity”, se não tiver cadastrada, crie um novo registro com o nome “opporunity”
  • Action – “Route Windows”, quando um janela da entidade Oportunidade for inserida no USD
  • Target Tab – “Opportunity”, o nome do hosted control que possui o form da Oportunidade
  • Show Tab – “Opportunity”, o nome do hosted control que possui o form da Oportunidade
  • Hide navigation Bar – Marcar a caixa de seleção

Pronto, abra seu USD, inicie um sessão com um cliente e verifique o resultado!

Para maiores informações, consulte os links oficiais:

Events
Create a user-defined event

[]’s,

Tiago Cardoso

2 comentários em “CRM – Events (USD)

  1. Olá, Parabéns pelo Post.
    Você por acaso saberia dizer quais são os Events padrões dos controles hospedados customizados (WPF)?
    Sei que existe o DesktopReady, Close, etc…
    Na verdade, gostaria de saber se é possível disparar uma ação quando a aba de um controle hospedado for clicado.

    Curtir

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.