Executar um FetchXML e exportar para CSV com Javascript

by Pedro Azevedo 19. October 2014 16:12

 

Boas pessoal,

Hoje um post muito rápido de como executar um FetchXML e exportar os resultados para um CSV, tudo isto em Javascript.

Para começar é possível executar um FetchXML através de uma requisição SOAP. Quando tenho este tipo de requisição recorro a biblioteca XrmServiceToolkit, no blog existem vários exemplos.

Para executar um FetchXml usamos a função Fetch:

function ExecuteFetch() {
    var fetchXml =
            "<fetch mapping='logical'>" +
               "<entity name='contact'>" +
                  "<attribute name='contactid' />" +
                  "<attribute name='firstname' />" +
                  "<attribute name='lastname' />" +
                  "<attribute name='middlename' />" +
                  "<filter>" +
                     "<condition attribute='parentcustomerid' operator='eq' value='" + Xrm.Page.data.entity.getId() + "' />" +
                  "</filter>" +
               "</entity>" +
            "</fetch>";

    var retrievedContacts = XrmServiceToolkit.Soap.Fetch(fetchXml);
}

Este código está preparado para correr dentro da entidade cliente, retorna todos os contactos desse cliente. A dificuldade a seguir é colocar os dados num ficheiro CSV e fazer download dele, existem várias estratégias:

var csvString = allValues.join("\n");

    var a  = document.createElement('a');
    a.href = 'data:attachment/csv,' + csvString;
    a.target = '_blank';
    a.download = 'myFile.csv';

    document.body.appendChild(a);
    a.click();

Vamos ver agora o código completo que inclui o tratamento dos dados retornados:

function ExecuteFetch() {
    var fetchXml =
            "<fetch mapping='logical'>" +
               "<entity name='contact'>" +
                  "<attribute name='contactid' />" +
                  "<attribute name='firstname' />" +
                  "<attribute name='lastname' />" +
                  "<attribute name='middlename' />" +
                  "<filter>" +
                     "<condition attribute='parentcustomerid' operator='eq' value='" + Xrm.Page.data.entity.getId() + "' />" +
                  "</filter>" +
               "</entity>" +
            "</fetch>";

    var retrievedContacts = XrmServiceToolkit.Soap.Fetch(fetchXml);

    var allValues = [];
    var strCol = "";
    var strVal = "";

    var cols = true;

     for (var i = 0; i < retrievedContacts.length; i++) {
      var attsValues = retrievedContacts[i].attributes;

      for (var att in attsValues) {
        strVal += attsValues[att].value + ";";

        if(cols){
          strCol += att + ";";
        }
      }

      if(cols){
        allValues.push(strCol);
        cols = false;
      }

      allValues.push(strVal);
      strVal = "";
    }

    var csvString = allValues.join("\n");

    var a  = document.createElement('a');
    a.href = 'data:attachment/csv,' + csvString;
    a.target = '_blank';
    a.download = 'myFile.csv';

    document.body.appendChild(a);
    a.click();
}

 

Até a próxima.

Tags: , , , ,

Como enviar notas criadas por email

by Pedro Azevedo 11. September 2014 07:21

Boas pessoal,

Esta semana decidi colocar um post para resolver uma questão no fórum do Microsoft Dynamics CRM, resumidamente o objetivo é criar um email com as últimas notas criadas.

Na questão é mencionada se é possível criar um modelo de email, mas não conseguimos chegar a entidade Notas. Para este caso penso que o melhor é recorrermos aos Workflows, outra solução era recorrer aos plugins. Então para começar vamos criar o nosso Workflow (na opção Processos):

Como disse vamos recorrer aos Workflow (Fluxo de Trabalho) e vamos querer apanhar eventos na entidade Nota. Continuando a criação vamos querer ser avisados quando uma nota for criada e quero enviar um email (no email é referido a utilização de um modelo de email mas nos modelos não conseguimos chegar a entidade Nota):

Agora vamos definir que valores queremos colocar no email:

E já está, um requisito que parecia a partida que podia levantar alguns problemas foi resolvido facilmente e sem uma única linha de código.

Caso não queiramos receber emails de todas as entidades podemos realizar um filtro antes da criação do email:

Vamos ver a como ficou a condição da cláusula de condição:

Se tiverem alguma dúvida passem no fórum do Microsoft Dynamics CRM e coloquem lá.

 

Até a próxima.

Tags: , , ,

CRM 2013 Javascript Object Model - UI

by Pedro Azevedo 30. August 2014 19:48

Boas pessoal,

 

Mais um post sobre o object model. Desta vez estaremos a ver o “namespace” Xrm.Page.ui.

 

Xrm.Page.ui.close()

Como o próprio nome diz fecha o formulário, infelizmente não conseguir tirar um printscreen Cool mas acreditem que funciona.

function closeTest() {
	Xrm.Page.ui.close();
}

 

formSelector.getCurrentItem

function getCurrentItemTest() {
                var formSelect = Xrm.Page.ui.formSelector.getCurrentItem();
                if (formSelect == null) {
                               Xrm.Utility.alertDialog("é nulo quando existe apenas um form para escolha");
                }
                else {
                               Xrm.Utility.alertDialog("Este é o form escolhido: " + item.getLabel());
                }
}

formSelector.items
function formSelectorItemsTest() {
                Xrm.Page.ui.formSelector.items.forEach(function (item, index) {
                               Xrm.Utility.alertDialog(item.getLabel());
                });
}

Xrm.Page.ui.getViewPortHeight() e Xrm.Page.ui.getViewPortWidth()
function getViewPortHeightWidthTest() {
                Xrm.Utility.alertDialog("Largura: " + Xrm.Page.ui.getViewPortWidth() + ", Altura: " + Xrm.Page.ui.getViewPortHeight());
}

Xrm.Page.ui.getCurrentControl()

function getCurrentControlTest() {
                var currentControl = Xrm.Page.ui.getCurrentControl();
                if (currentControl == null) {
                               alert("Não há controlos com focus");
                }
                else {
                               alert("O controlo com focus é o '" + currentControl.getLabel());
                }
}

Xrm.Page.ui.getFormType()

Valores possíveis de retorno deste método:

Valor

Tipo de formulário

0

Undefined

1

Create (Dá para Quick Create)

2

Update

3

Read Only

4

Disabled

5

Quick Create (Deprecated)

6

Bulk Edit

11

Read Optimized (Deprecated)

function getFormTypeTest() {
                Xrm.Utility.alertDialog(Xrm.Page.ui.getFormType());
}

navigation.items

 

Xrm.Page.ui.setFormNotification(message, level, uniqueId)

Os valores possíveis para definir o nível da mensagem, referir também que o elemento uniqueid deve-se dar uma id único para podermos retirar mais tarde esta notificação.

ERROR

Notification will use the system error icon

WARNING

Notification will use the system warning icon

INFO

Notification will use the system info icon

function setFormNotificationTest() {
                Xrm.Page.ui.setFormNotification("Isto é um teste as notificações", "INFO", "TesteNotificacaoInfo");
}

Xrm.Page.ui.clearFormNotification(uniqueId)
function clearFormNotificationTest() {
                Xrm.Page.ui.clearFormNotification("TesteNotificacaoInfo");
}

 

Mais uma vez não consigo tirar um screenshot que ajude por isso acreditem que funciona.

Xrm.Page.ui.refreshRibbon()

Este método permite refrescar a ribbon, mas o que isto significa? Por exemplo quando temos um botão na ribbon onde o seu estado depende de um valor no formulário, se este for alterado agora podemos dizer que queremos que ele aplique novamente as regras.

function refreshRibbonTest() {
                Xrm.Page.ui.refreshRibbon();
}

 

 

Neste caso coloquei uma condição baseada no campo email, só mostra o botão se o valor for psazevedo@psa.com

 

Até a próxima.

Tags: , , ,

Como obter guids de registos

by Pedro Azevedo 15. August 2014 08:16

Boas pessoal,

Vou iniciar hoje um conjunto de pelo menos dois artigos onde vou tentar resumir as várias formas que temos para obter os vários tipos de guids e nas duas versões 2011 e 2013. Para começar adicionei uma nova entrada no dicionário de CRM com o que significa GUID.

Hoje vou falar em várias possibilidades de obter os guids de registos, num futuro post irei falar como obter guids de vários objetos. O mais comum é obtermos o guid de um registo, se tivermos dentro desse registo temos várias opções:

CRM 2011

No CRM 2011 podemos obter o guid através do URL, mas quase ele esteja no modo aplicação abre assim:

Não temos URL então podemos fazer F11 ou CTRL+N e conseguimos ver o URL associado:

Seleccionamos o URL e retiramos o que queremos:

http://server/org/main.aspx?etc=3&extraqs=%3f_gridType%3d3%26etc%3d3%26id%3d%257b64E808B4-3A1A-E311-9B18-005056907305%257d%26pagemode%3diframe%26preloadcache%3d1412850657742%26rskey%3d566790654&pagetype=entityrecord

CRM 2013

No CRM 2013 aparentemente deixamos de ter a opção de obtermos através do URL, então uma possibilidade passa por utilizarmos este botão:

Obtemos um email e de onde podemos extrair o guid deste registo:

A. Datum Corporation (sample)
<https://cmfazevedo.crm4.dynamics.com/main.aspx?etc=1&extraqs=formid%3d8448b78f-8f42-454e-8e2a-f8196b0419af&id=%7b0DDD50D8-021E-E411-892E-2C59E541AD08%7d&pagetype=entityrecord>

Bem o que disse anteriormente e como vimos no CRM 2011 deixámos de ver o guid no URL, caso façamos popup desse registo obtemos um URL com o guid:

 

https://cmfazevedo.crm4.dynamics.com/main.aspx?etc=1&extraqs=&histKey=604351270&id={0DDD50D8-021E-E411-892E-2C59E541AD08}&newWindow=true&pagetype=entityrecord#945933055

Outra possibilidade e que funciona para as duas versões é colocar um botão (vou mostrar como fazer mais adiante) para mostrar o guid e para isso basta usar o seguinte código:

function showMeGuid() {
    prompt("Este é o teu GUID",  Xrm.Page.data.entity.getId());
}

 

Este pedaço de código Xrm.Page.data.entity.getId() é o mais importante, é o que permite obter o guid do registo atual.

Agora vamos ver o caso de numa lista de registos querermos saber quais os registos que estão selecionados, para este exemplo vou mostrar como criar o botão com o Ribbon Workbench para refrescar a memória e para mostrar como trabalhar com parâmetros por defeito.

Vamos então acrecentar um botão:

 

Para executar uma ação teremos que adicionar um comando, este comando adicionamos regras para mostrar e tornar disable. Mas onde me quero focar é nas “actions”:

Adiciono uma nova ação de Javascript:

 Dentro da configuração da ação para a chamada de uma função Javascript temos que especificar qual o Recurso Web e qual a função dentro desse recurso que queremos chamar. Para o primeiro caso bastava este passo:

 Mas agora o objetivo é que o CRM nos passe os registos selecionados, conseguimos indicar através dos “parameters”, que neste caso é um parâmetro do CRM:

Como podemos ver podemos passar vários parâmetros, neste caso existe um parâmetro mesmo para aquilo que queremos:

 Terminada a nossa configuração do comando podemos associá-la ao nosso botão:

 E é este o resultado:

Outra maneira que habitualmente queremos saber o guid de um registo é quando temos um lookup no formulário e temos um registo selecionado, aqui recorremos a um post já realizado para ver como podemos aceder a estes dados.

 

Até a próxima

Tags: , , , ,

CRM 2013 Javascript Object Model - Data

by Pedro Azevedo 8. August 2014 02:34

 Boas pessoal,

Continuando a “saga” dos métodos Javascript vamos agora ver os métodos Xrm.Page.data.

Xrm.Page.data.getIsValid()

function getIsValidTest() {
                Xrm.Utility.alertDialog(Xrm.Page.data.getIsValid());
}

Xrm.Page.data.refresh(save).then(successCallback, errorCallback)

Esta função refresh recebe um booleano para dizer se queremos que ele salve depois do formulário ser refrescado. Depois existe a possibilidade de passar funções quando houver sucesso ou insucesso na execução da função.

function refreshTest()
{
                Xrm.Page.data.refresh(false).then(function() {
                                               Xrm.Utility.alertDialog("Sucesso no refrescamento");
                               },
                               function() {
                                               Xrm.Utility.alertDialog("Erro no refrescamento");
                });
}

Esta caixa aparece porque como estou a colocar o evento no onchange de um campo do CRM, ele verifica que estamos a querer refrescar a página sem guardarmos as alterações.

Xrm.Page.data.save().then(successCallback, errorCallback)

function saveTest() {
                Xrm.Page.data.save().then(function() {
                                               Xrm.Utility.alertDialog("Sucesso no save");
                               },
                               function() {
                                               Xrm.Utility.alertDialog("Erro no save");
                });
}

As duas últimas funções são muito rápidas isto porque o refrescamento é só dos dados e não da página inteira.

 

Até a próxima.

Tags: , , , , ,

CRM 2013 Javascript Object Model - Data.Entity

by Pedro Azevedo 9. July 2014 02:24

Boas pessoal,

Mais um capítulo dos métodos de Javascript desta vez sobre o Xrm.Page.data.entity

Xrm.Page.data.entity.addOnSave([function reference])

function showMessage() {
                Xrm.Utility.alertDialog("Função do evento save");
}

 

function addOnSaveTest() {
                Xrm.Page.data.entity.addOnSave(showMessage);
}

Xrm.Page.data.entity.removeOnSave([function reference])

function removeOnSaveTest() {
                Xrm.Page.data.entity.removeOnSave(showMessage);
}

 

Xrm.Page.data.entity.getDataXml()

function getDataXmlTest() {
                Xrm.Page.data.entity.addOnSave(function(){
                               Xrm.Utility.alertDialog(Xrm.Page.data.entity.getDataXml());
                });
}

Neste XML só aparecem os campos que eu alterei e aquelas que serão enviadas para o registo ser guardado.

Xrm.Page.data.entity.getEntityName()

function getEntityNameTest() {
                Xrm.Utility.alertDialog(Xrm.Page.data.entity.getEntityName());
}

Xrm.Page.data.entity.getId()

function getIdTest() {
                Xrm.Utility.alertDialog(Xrm.Page.data.entity.getId())
}

Xrm.Page.data.entity.getIsDirty()

function getIsDirtyTest() {
                Xrm.Utility.alertDialog(Xrm.Page.data.entity.getIsDirty());
}

 

O primeiro teste foi no evento onload do formulário e como se está a espera o formulário não está dirty. O segundo é invocado após alteração do campo como seria de esperar o CRM diz que o formulário está dirty.

Xrm.Page.data.entity.getPrimaryAttributeValue()

function getPrimaryAttributeValueTest() {
                Xrm.Utility.alertDialog(Xrm.Page.data.entity.getPrimaryAttributeValue());
}

Xrm.Page.data.entity.save( null | "saveandclose" |"saveandnew" )

Aqui é definido o comportamento da função save, se passarmos null ele deve simular o gravar normal, o saveandclose e o saveandnew dizem tudo destas duas opções.

function saveTest() {
                Xrm.Page.data.entity.save();

                Xrm.Page.data.entity.save("saveandclose");

                Xrm.Page.data.entity.save("saveandnew");
}

Já tínhamos visto a função Xrm.Page.data.save() a diferença é que esta corre assincronamente enquanto o save dentro da entity é síncrono e com opções diferentes.

 

Até a próxima.

Tags: , , , , , ,

CRM 2013 Javascript Object Model - Coleções

by Pedro Azevedo 30. June 2014 21:47

Boas pessoal,

Neste post mais uma vez sobre o object model do Javascript para o Dynamics CRM 2013, iremos debruçar sobre collections. Antes virmos os métodos que nos permitem aceder as várias colecções vamos ver três métodos que nos vão ajudar a trabalhar sobre as colecções:

Xrm.Page.ui.controls.forEach(delegate function(control, index))

Aplica uma acção numa função delegate a cada objecto numa colecção

Xrm.Page.ui.controls.get([String][Number][delegate function(attribute, index)])

Extrair um ou mais objectos da colecção

Xrm.Page.ui.controls.getLength()

Retorna o número de itens de uma colecção

Fica aqui uma pequena referência mas eu vou aplicar várias vezes estes métodos com as várias assinaturas. Principalmente no primeiro exemplo que vou percorrer todos este métodos.

Xrm.Page.data.entity.attributes

function attributesAllTest() {

                    Xrm.Utility.alertDialog("Esta entidade tem " + Xrm.Page.data.entity.attributes.getLength() + " entidades no formulário");

                   

                    var firstControlById = Xrm.Page.data.entity.attributes.get(0);

                    var firstControlByName = Xrm.Page.data.entity.attributes.get(firstControlById.getName());

                   

                    var booleanAtts = Xrm.Page.data.entity.attributes.get(isBoolean);

                    var message = "";

                    for (var i in booleanAtts) {

                                         message += "- " + booleanAtts[i].getName() + "\n";

                    }

                    Xrm.Utility.alertDialog(message);

                   

                    message = "";

                    Xrm.Page.data.entity.attributes.forEach(function (attribute, index) {

                                         message += attribute.getName() + "(" + attribute.getAttributeType() + ") \n";

                    });

                    Xrm.Utility.alertDialog(message);

}

 

function isBoolean(att, index) {

                    return att.getAttributeType() == "boolean";

}

 

 

 

Xrm.Page.ui.controls

function controlsTest() {

                    var message = "";

                    Xrm.Page.ui.controls.forEach(function (control, index) {

                                         message += control.getName() + "(" + control.getControlType() + ") \n";

                    });

                   

                    Xrm.Utility.alertDialog(message);

}

Xrm.Page.ui.formSelector.items

Vou abordar esta colecção aquando Xrm.Page.ui.

Xrm.Page.ui.navigation.items

Vou abordar esta colecção aquando Xrm.Page.ui.

Xrm.Page.ui.tabs

function tabsTest() {

                    var message = "";

                    Xrm.Page.ui.tabs.forEach(function (tab, index) {

                                         message += "A tab " + tab.getName() + " está " + tab.getDisplayState() + "\n";

                    });

                   

                    Xrm.Utility.alertDialog(message);

}

 

 

Xrm.Page.getAttribute("…").controls

function attControlsTest() {

                    var message = "";

                    Xrm.Page.getAttribute("subject").controls.forEach(function (control, index) {

                                         message += control.getName() + "(" + control.getControlType() + ") \n";

                    });

                   

                    Xrm.Utility.alertDialog(message);

}

 

Xrm.Page.ui.tabs.get("…").sections

function sectionsTest() {

                    var message = "";

                    Xrm.Page.ui.tabs.get("Summary").sections.forEach(function (section, index) {

                                         message += "A secção " + section.getName() + "tem a seguinte label " + section.getLabel() + " \n";

                    });

                   

                    Xrm.Utility.alertDialog(message);

}

 Xrm.Page.ui.tabs.get("…").sections.get("…").controls

function sectionControlsTest() {

                    var message = "";

                    Xrm.Page.ui.tabs.get("Summary").sections.get("Contact").controls.forEach(function (control, index) {

                                         message += control.getName() + "(" + control.getControlType() + ") \n";

                    });

                   

                    Xrm.Utility.alertDialog(message);

}

 

Até a próxima.

Tags: , , ,

CRM 2013 Javascript Object Model - Contexto

by Pedro Azevedo 28. May 2014 20:04

Boas pessoal,

Chegou a vez de falarmos sobre o Xrm.Page.context. Aqui temos que obter primeiro o objecto de contexto.

context.client.getClient()

Valores de retorno possíveis deste método:

Cliente

Valor

Browser

Web

Outlook

Outlook

Mobile

Mobile

function getClientTest() {

                Xrm.Utility.alertDialog(Xrm.Page.context.client.getClient());

}

De referir que este método veio tornar o método isOutlookClient obsoleto.

 

context.client.getClientState()

Valores de retorno possíveis deste método:

Cliente

Valor

Web, Outlook, Mobile

Online

Outlook, Mobile

Offline

function getClientStateTest() {

                Xrm.Utility.alertDialog(Xrm.Page.context.client.getClientState());

}

Tal como o método anterior este método veio tornar obsoleto o método isOutlookOnline.

 

context.getClientUrl()

Valores possíveis no retorno:

Cliente

Valor

Microsoft Dynamics CRM (on-premises)

http(s)://server/org

Microsoft Dynamics CRM Online

https://org.crm.dynamics.com

Microsoft Dynamics CRM for Outlook with Offline Access when offline

http://localhost:2525

Na documentação o método getServerURL não vem documentado mas ainda funciona apesar de estar obsoleto deve-se usar sempre o getClientUrl.

 

context.getCurrentTheme()

Este método serve essencialmente para podermos customizar os nossos Recursos Web mediante o theme do Outlook. Valores possíveis de retorno para este método:

Valor

Theme

default

Microsoft Dynamics CRM web application

Office12Blue

Microsoft Dynamics CRM for Outlook 2007 or 2010 Blue Theme

Office14Silver

Microsoft Dynamics CRM for Outlook 2007 or 2010 Silver or Black Theme

function getCurrentThemeTest() {

                Xrm.Utility.alertDialog(Xrm.Page.context.getCurrentTheme());

}

Devem ter atenção que alguns destes métodos não funcionam por exemplo nos tablets por isso os métodos acima passam a ser essenciais. Por exemplo este método em específico não funciona nos tablets.

 

context.getOrgLcid()

Esta função permite devolver a linguagem base da organização.

 

function getOrgLcidTest() {

                Xrm.Utility.alertDialog(Xrm.Page.context.getOrgLcid());

}

Este valor representa o Português de Portugal. Já agora o Português do Brazil é o 1046.

 

context.getOrgUniqueName()

function getOrgUniqueNameTest() {

                Xrm.Utility.alertDialog(Xrm.Page.context.getOrgUniqueName());

}

context.getQueryStringParameters()

Este método serve para ler os query strings passados ao formulário para além dos parâmetros que o CRM envia pode-se passar parâmetros customizados, por exemplo usando a função que já testamos a openEntityForm.

 

function getQueryStringParametersTest() {

                var params = Xrm.Page.context.getQueryStringParameters();

                for(var par in params) {

                               Xrm.Utility.alertDialog("QueryString:" + par + " com o valor " + params[par]);

                }

}

 

 

context.getUserId()
function getUserIdTest() {

                Xrm.Utility.alertDialog(Xrm.Page.context.getUserId());

}

 

context.getUserId() 
function getUserLcidTest() {

                Xrm.Utility.alertDialog(Xrm.Page.context.getUserLcid());

}

 

context.getUserName()
Esta função retorna o nome do utilizador.
function getUserNameTest() {

                    Xrm.Utility.alertDialog(Xrm.Page.context.getUserName());

}

 

context.getUserRoles()

function getUserRolesTest() {

                var roles = Xrm.Page.context.getUserRoles();

                for(var role in roles) {

                               Xrm.Utility.alertDialog("Role ID:" + role);

                }

}

context.prependOrgName(sPath)

 

function prependOrgNameTest() {

Xrm.Utility.alertDialog(getClientUrlTest() + Xrm.Page.context.prependOrgName("/XRMServices/2011/OrganizationData.svc/"));

}

 

Neste contexto ainda tenho a referir que o método getAuthenticationHeader foi retirado definitivamente, este tinha permanecido por causa de compatibilidades com o CRM 4.0.

 

Até a próxima

 

Tags: , , , , , , ,

Plugin para intervir na operações especiais - Ganho e Perda da Oportunidade

by Pedro Azevedo 18. May 2014 19:21

Boas pessoal,

Na continuação deste post vou aqui relatar como realizar o dito plugin, um plugin que interfere em operações especiais. Neste caso vai-se referenciar as operações na entidade Oportunidade que permite marcar um registo como Ganho ou Perdido. Imaginamos que se quer verificar se um determinado campo está preenchido, neste caso quero obrigar que o utilizador preencha a descrição antes de fechar a oportunidade.

O código é o seguinte:

public class CloseOpportunity : IPlugin {
	public void Execute(IServiceProvider serviceProvider) {
		ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
		IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

		if (context.InputParameters.Contains("OpportunityClose") && context.InputParameters["OpportunityClose"] is Entity) {
			Guid oppId = ((EntityReference)((Entity)context.InputParameters["OpportunityClose"]).Attributes["opportunityid"]).Id;

			IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
			IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

			Entity opportunity = service.Retrieve("opportunity", oppId, new Xrm.Sdk.Query.ColumnSet(true));
			if (!opportunity.Contains("description") || string.IsNullOrEmpty(opportunity["description"].ToString()))
				throw new InvalidPluginExecutionException("Para fechar a Oportunidade terá que preencher a descrição");
		}
	}
}

O normal em plugins é esperarmos a entidade no parâmetro “Target” neste caso, esta informação está no parâmetro “OpportunityClose”, ou seja, vem na forma do objecto final, pois quando fechamos uma Oportunidade temos que preencher informações, do estado, receita real, data de fecho e caso seja perdida qual o concorrente que ganhou.

Para verificarmos as propriedades da Oportunidade teremos que obter e no objecto “OpportunityClose” tem o ID da Oportunidade e é com esse ID que vamos obter a Oportunidade relacionada.

No código ainda se pode ressalvar como cancelamos a operação, com recurso a excepção “InvalidPluginExecutionException”, a mensagem que colocamos na excepção é a mensagem que vai aparecer ao utilizador.

Depois do código completo temos que registar o plugin com as seguintes configurações:

  •         Mensagem: Win ou Lose
  •         Entidade Primária: Opportunity
  •         Entidade Secundária: Nenhuma

E registamos no event Pre-Operation para que não seja gravado na BD.

Vamos ver diretamente no Plugin Registration como fica, depois de realizarmos uma ligação, podemos registar o nosso assembly:

 Após selecionarmos a opção "Register New Assembly" aparecerá um formulário para colocarmos o caminho do assembly que contém o nosso plugin e escolhemos qual o Plugin que queremos registar, neste caso estou a selecionar o Plugin acima:

 Se tudo correr bem obtém-se a seguinte mensagem:

Irá aparecer um novo nó com o assembly que se acabou de criar e sobre este vamos adicionar um "passo" (Register New Step):

No formulário a seguir configuramos em que mensagem queremos nos registar, qual a entidade primária, em que fase do pipeline e o modo de execução:

Com isto temos o nosso Plugin registado e pronto a funcionar.

Até a próxima.

Tags: , , , ,

CRM 2011 - UR17

by Pedro Azevedo 9. May 2014 01:21

 Boas pessoal,

Quando os olhos estão virados para a saída do SP1 do Dynamics CRM 2013, saiu mais um rollup para o Dynamics CRM 2011, UR17.

O grande destaque vai para os utilizadores do Internet Explorer 11 tanto para o Windows 8.1 e Windows 7, pois passam a ter suporte. O KB com mais de 60 issues resolvidos podem ser vistos aqui. Para fazer download pode ser aqui.

 

Até a próxima.

Tags: ,

About

Muito bem casado, Pai babado e um gosto muito grande pela tecnologia.

Tenho um lema "Sharing is Learning"

Mais aqui -> http://www.psazevedo.com

Month List