quinta-feira, 29 de janeiro de 2009

>> CRM 4.0 - Relationship via SDK

Já tiveram a necessidade de relacionar duas entidades, porém o CRM não permite da forma que deseja?

Por exemplo, pode-se relacionar no CRM a entidade [QuoteDetail] a outras entidades, porém somente via [N:1] ou [N:N]...mas não via [1:N].

Porque isto é relevante? Imagine que deseja ter, na tela de [Produtos da Cotação], [Despesas] associadas a cada Item. Via Customização Padrão do CRM não vai conseguir fazer isto! Pois não aparece na tela do [Produto da Cotação] o [Menu Vertical] de links de relacionamentos com outras entidades (comum a maioria das entidades).

O que se aprende neste artigo:

- Funcionamento de [Relationships] do CRM;
- Como reaproveitar chamadas de URL do produto;
- Usar o SDK para, programaticamente, adicionar e remover relacionamento entre entidades (classes AssociateEntitiesRequest e DisassociateEntitiesRequest).

A solução:

1 - Criar o relacionamento [N:N], para gerar o link entre as entidades [QuoteDetail] e [qq outra];

2 - Adicionar um [iFrame] do CRM, e na URL, adicionar o seguinte:



É claro que a URL deverá ser preenchida programaticamente, via [OnLoad] do Form do CRM, pois notamos na URL, parâmetros como [oId] que vai representar o [Guid] da entidade que [contém] o iFrame, o parâmetro [oType], representando o código da entidade, e por fim, [tabSet] que representa o nome do relacionamento entre as entidades.

No meu exemplo acima estou mostrando no iFrame a [Lista de Despesas] associada a um [Produto da Cotação].

Desta forma, consigo mostrar o relacionamento como se fosse [1:N].

Porém, o trabalho não acabou! Se notar, no cabeçalho do Grid que está sendo mostrado no iFrame, possui apenas o botão [Adicionar Existentes]...o que é inviável, pois queremos simular o processo [1:N], na qual apareceria o botão [Novo ].

Para resolver isto, crie um novo botão customizado, alterando o Isv.Config, no meu caso, para a entidade [Despesa], adicionando um JavaScript que:

1 - Captura o Id da entidade principal (no meu exemplo, o Produto da Cotação);
2 - Criar um atributo para guardar o valor do ID do passo 1. No meu exemplo eu guardo o ID do [Produto da Cotação] em um campo criado na Entidade [Despesas];
3 - Prepare a url que simule a criação do registro;
4 - No [OnLoad] do Form (no meu exemplo, de Despesas), recupere o Id capturado no passo 1.

Abaixo segue códigos para os passos citados:

- Adicionando o botão no Isv.Config do CRM4:



- No [OnLoad] do Form do CRM, JavaScript do passo 3:



E finalmente, criar o código SDK (criar uma dll de PLUGIN - PostCreate e PostDelete) para criar o Link entre as entidades (no meu exemplo, entre QuoteDetail e [outra entidade]):

private static void fnEntityRelationShip(Boolean add)
{
// Set up the CRM Service.
CrmAuthenticationToken token = new CrmAuthenticationToken();
token.AuthenticationType = 0;
token.OrganizationName = "OrgName";

CrmService service = new CrmService();
service.Url = "http://localhost:5555/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;

if (add)
{
// Create an AssociateEntities request.
AssociateEntitiesRequest request = new AssociateEntitiesRequest();

request.Moniker1 = new Moniker();
request.Moniker1.Id = new Guid("a1db8742-a3ec-dd11-a193-0015f2044350");
request.Moniker1.Name = EntityName.quotedetail.ToString();

request.Moniker2 = new Moniker();
request.Moniker2.Id = new Guid("21CA2C7C-7989-DD11-B2DA-0015F2044350");
request.Moniker2.Name = EntityName.mit_despesa.ToString();

// Set the relationship name to associate on.
request.RelationshipName = "mit_quotedetail_mit_despesa";

// Execute the request.
service.Execute(request);
}
else
{
// Create a request.
DisassociateEntitiesRequest request = new DisassociateEntitiesRequest();

// Assign the request a moniker for both entities that need to be disassociated.
request.Moniker1 = new Moniker();
request.Moniker1.Id = new Guid("a1db8742-a3ec-dd11-a193-0015f2044350");
request.Moniker1.Name = EntityName.quotedetail.ToString();

request.Moniker2 = new Moniker();
request.Moniker2.Id = new Guid("21CA2C7C-7989-DD11-B2DA-0015F2044350");
request.Moniker2.Name = EntityName.mit_despesa.ToString();

// Set the relationship name that associates the two entities.
request.RelationshipName = "mit_quotedetail_mit_despesa";

// Execute the request.
DisassociateEntitiesResponse response = (DisassociateEntitiesResponse)service.Execute(request);
}
}