CRM 4 – Plugin Pre-Event


Já havia comentado sobre as diferenças quando registramos um plugin no Pre-Event ou Post-Event. Neste post irei descrever sobre as diferenças na codificação de um plugin registrado no Pre-Event.

Ao contrário de plugins registrados no Post-Event, onde, na maiorias das vezes, necessitamos realizamos um Update no registro atual para as alterações do plugin terem efeito sob o registro. Em um Pre-Event, apenas mudamos ou incluímos os atributos do registro alvo, pois ele ainda não foi adicionado na base de dados e estamos interceptando em um momento antes da interação com o SQL. Vamos ao código…

Primeiramente, o padrão de um plugin, implementar a interface IPlugin:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Sdk.Query;
using System.Data.SqlClient;
using System.Data;
using System.IO;
using System.Web.Services.Protocols; // Para usar o SOAP Exception

public class SUACLASSE : IPlugin
{
    // Cria objeto para a comunicação com o Web Service CRM
    private ICrmService crmService = null;

    ///<summary> 
    /// Método que a interface IPlugin nos "obriga" a implementar
    ///</summary>
    /// <param name="context">Contexto</param>
    public void Execute(IPluginExecutionContext context)
    {

    }
}

Neste exemplo, estou simulando uma importação de contatos relacionados à uma conta, o plugin foi necessário devido as informações do arquivo .csv serem apenas:

  • Nome;
  • Código do Cliente – Este código foi criado como uma chave exclusiva, numérica e sequencial na entidade account;

Deste modo, para realizar o relacionamento entre conta e contato (parentcustomerid), teremos que efetuar uma busca pelo código na entidade account em um plugin registrado no pre-event, com isso, obtemos o id da conta e relacionamos com o contato. Veja o padrão para o arquivo .csv:

Nome;CodigoConta

João;1000

José;1000

Maria;1000

Com isso precisamos recuperar o código da conta do arquivo e buscar no Web Service do CRM pela conta:

///<summary> 
/// Método que a interface IPlugin nos "obriga" a implementar
///</summary>
///<param name="context">Contexto</param>
public void Execute(IPluginExecutionContext context)
{
    // Declara objetos
    DynamicEntity entity;
    decimal codigo;

    try
    {
        // Recupera a Entidade que acionou o plugin
        entity = (DynamicEntity)context.InputParameters["Target"];

        // Verifica se a Entidade foi localizada
        if (entity != null)
        {
            // Verifica se o Código do Account existe
            if (entity.Properties.Contains("xxx_codigoaccount"))
            {
                // Cria a comunicação com o Web Service do CRM
                crmService = context.CreateCrmService(false);

                // Recupera o Código
                codigo = Convert.ToInt32(entity.Properties["xxx_codigoaccount"]);

                // Atualiza informações que não foram enviadas na importação,
                // de acordo com a entidade solicitada
                this.AlterarContato(codigo, entity);
            }
            else
                throw new InvalidPluginExecutionException("O Contato não possui Código da Conta");
        }
    }
    catch (SoapException ex)
    {
        throw new InvalidPluginExecutionException(ex.Detail.SelectSingleNode("//description").InnerText);
    }
}

Notem que existe uma chamada ao método AlterarContato, a função dele é recuperar o id da conta e adicionar a propriedade parentcustomerid no contato, vejam:

///<summary> 
/// Atualiza informações que não foram enviadas na importação,
/// de acordo com a entidade solicitada
///</summary>
///<param name="codigo">Código da Conta</param>
///<param name="entidade">Entidade alvo, que chamou o plugin</param>
public void AlterarContato(int codigo, DynamicEntity entity)
{
    // Declara objetos
    DynamicEntity entityConta;
    LookupProperty lookupProperty;

    // Cria objetos
    lookupProperty = new LookupProperty();

    // Consultar Produto pelo Código da Conta
    entityConta = this.ConsultarConta(codigo);

    // Verifica se localizou a Conta
    if (entityConta != null)
    {
        // AccountId
        if (entityConta.Properties.Contains("accountid"))
        {
            // Aqui é feita a "mágica", uma propriedade é criada e associada
            // a entidade Target do contexto atual
            lookupProperty.Name = "accountid";
            lookupProperty.Value = new Lookup();
            lookupProperty.Value.type = EntityName.account.ToString();
            lookupProperty.Value.Value = ((Key)entityConta.Properties["accountid"]).Value;

            entity.Properties.Add(lookupProperty);
        }
    }
    else
        throw new InvalidPluginExecutionException("A Conta " + codigo + " não foi localizada");
}

///<summary> 
/// Consultar Conta pelo Código da Conta
///</summary>
///<param name="codigo">Código da Conta</param>
///<returns>Dynamic Entity com a Conta</returns>
private DynamicEntity ConsultarConta(int codigo)
{
    // Declara objetos
    DynamicEntity entity = null;
    QueryExpression query;
    ColumnSet columns;
    ConditionExpression condition1;
    FilterExpression filter;
    RetrieveMultipleRequest request;
    RetrieveMultipleResponse response;

    // Cria objetos
    query = new QueryExpression();
    columns = new ColumnSet();
    condition1 = new ConditionExpression();
    request = new RetrieveMultipleRequest();
    filter = new FilterExpression();

    // Colunas que serão retornadas
    columns.AddColumn("accountid");

    // Setup the query for the account entity
    query.EntityName = "account";
    query.ColumnSet = columns;

    // Create the xxx_codigoconta condition
    condition1.AttributeName = "xxx_codigoconta";
    condition1.Operator = ConditionOperator.Equal;
    condition1.Values = new Object[] { codigo.ToString() };

    // Create filter
    filter.FilterOperator = LogicalOperator.And;
    filter.AddCondition(condition1);

    query.Criteria = filter;

    // Cria o Request
    request.ReturnDynamicEntities = true;
    request.Query = query;

    // Recupera informações
    response = (RetrieveMultipleResponse)crmService.Execute(request);

    // Verifica se localizou resultados
    if (response.BusinessEntityCollection != null && response.BusinessEntityCollection.BusinessEntities.Count > 0)
    {
        // Recupera a Conta
        entity = (DynamicEntity)response.BusinessEntityCollection.BusinessEntities[0];
    }

    return entity;
}

Com a codificação concluída, esta na hora de compilar e registrar a .dll, cheguei a fazer um exemplo, não esqueçam de registrar no Pre-Event.

Por fim, importe o arquivo .csv e veja os resultados.

Espero que seja útil, o mais importante é o conceito e o que podemos fazer!

[]’s

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.