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