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