CRM 2013 - UR1

by Pedro Azevedo 18. December 2013 23:48

 

Boas pessoal,

Está disponível o primeiro rollup para o CRM 2013. Este pode ser descarregado aqui e podemos ver detalhes sobre o mesmo aqui. De referir que o UR1 já foi aplicado no CRM Online, não sei se em todas as instâncias, para saberem se já foi aplicado podem ver a versão do CRM 2013, o UR1 tem a versão 6.0.1.0061 (a versão sem rollups era 6.0.0.0809).

Tenho a realçar a implementação das alterações realizadas no UR15 para o CRM 2011 no que diz respeito ao cliente para o Outlook. Foram realizadas melhorias ao nível do consumo de memória. Além destas novidades foram também corrigidos diversos erros.

Apenas um parêntesis o esquema de cores também foi modificado desaparecendo o fundo negro da barra de navegação. Pode parecer um detalhe mas faz muita diferença.

 

Até a próxima.

Tags: , , ,

CRM 2011 - XrmServiceToolkit - Exemplo RetrieveAttributeMetadata

by Pedro Azevedo 17. December 2013 15:44

Boas pessoal,

Aproveitando o último post onde utilizei uma chamada SOAP “inteira”, ou seja, tive que colocar todo o request e comparar como poderíamos ter feito a mesma coisa com o uso de a biblioteca XrmServiceToolkit que já apresentei antes aqui no blog.

Para além de menos código, esta biblioteca já resolve um dos problemas que encontraram com o último post, não funciona com o IE10 (nem em browsers como Firefox e Chrome já que não é standard da W3C), isto porque o IE10 já não suporta XPath e por consequência não consegue executar o seguinte código:

selectSingleNode("c:OptionSet//c:Options");

Para resolver este problema usei JQuery para resolver este problema, mas se tivéssemos a usar a biblioteca XrmServiceToolkit este problema já estava resolvido, já que esta biblioteca está sempre a ser atualizada.

Substituindo o código que usava o método anterior por jQuery fica assim:

 

function getOptionSet (entityLogicalName, attributeLogicalName, retrieveAsIfPublished) {				
	var context = GetGlobalContext();
	var serverUrl = context.getServerUrl();
	var SoapPath = serverUrl + "/XRMServices/2011/Organization.svc/web";
	var MetadataId = "00000000-0000-0000-0000-000000000000";
	
	var request = " <soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Body>"
	request += "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
	request += "<request i:type=\"a:RetrieveAttributeRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
	request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
	request += "<a:KeyValuePairOfstringanyType>";
	request += "<b:key>EntityLogicalName</b:key>";
	request += "<b:value i:type=\"c:string\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + entityLogicalName + "</b:value>";
	request += "</a:KeyValuePairOfstringanyType>";
	request += "<a:KeyValuePairOfstringanyType>";
	request += "<b:key>MetadataId</b:key>";
	request += "<b:value i:type=\"ser:guid\"  xmlns:ser=\"http://schemas.microsoft.com/2003/10/Serialization/\">" + MetadataId + "</b:value>";
	request += "</a:KeyValuePairOfstringanyType>";
	request += "<a:KeyValuePairOfstringanyType>";
	request += "<b:key>RetrieveAsIfPublished</b:key>";
	request += "<b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + retrieveAsIfPublished + "</b:value>";
	request += "</a:KeyValuePairOfstringanyType>";
	request += "<a:KeyValuePairOfstringanyType>";
	request += "<b:key>LogicalName</b:key>";
	request += "<b:value i:type=\"c:string\"   xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + attributeLogicalName + "</b:value>";
	request += "</a:KeyValuePairOfstringanyType>";
	request += "</a:Parameters>";
	request += "<a:RequestId i:nil=\"true\" /><a:RequestName>RetrieveAttribute</a:RequestName></request>";
	request += "</Execute>";
	request += "</soapenv:Body></soapenv:Envelope>";
	
	var req = new XMLHttpRequest();
	req.open("POST", SoapPath, false);
	req.setRequestHeader("Accept", "application/xml, text/xml, */*");
	req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
	req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
	req.send(request);

	if (req.responseXML != null) {
		return req.responseXML;
	}
}

 

Ficando a chamada e o parsing do resultado assim:

var optionXML = getOptionSet(entityName, fieldName, true);
var a =  $(optionXML.xml).find('OptionMetadata');
a.each(function(){
		  var text = $(this).find('Label').find('UserLocalizedLabel').find('Label').text();
		  $(myList).append('<option>' + text + '</option>');
});

E agora vejam como fica tirando partido da biblioteca XrmServiceToolkit:

var OptionSetControl = XrmServiceToolkit.Soap.RetrieveAttributeMetadata(entityname, fieldname, true);
for(var i = 0; i < OptionSetControl[0].OptionSet.Options.length; ++i)
{
	$(myList).append('<option>' + OptionSetControl[0].OptionSet.Options[i].Label.UserLocalizedLabel.Label + '</option>')
}

Uma diferença ENORME e sim funciona :P.

Mais uma vez fica a solução com os dois Recursos Web, um com a chamada SOAP e outra com o recurso a XrmServiceToolkit. Bem como todas as dependências.

 

Até a próxima.

ListadeEstados_1_0_0_1.zip (66,54 kb)

Tags: ,

CRM 2011 - Listar todas as opções num WebResource (Recurso Web)

by Pedro Azevedo 12. December 2013 01:39

Boas pessoal,

Foi colocada uma questão nos fóruns da Microsoft. Basicamente a questão era como obter todos os estados de uma entidade e listar em um Recurso Web. Como o código e os passos eram bastantes decidi colocar aqui no blog e ajudar futuramente outros programadores.

No final deste desenvolvimento como resultado teremos um Recurso Web a listar num OptionSet todas as opções de um OptionSet criado no CRM. Para isso teremos que aceder aos Metadados do CRM. Neste caso vou usar directamente uma mensagem SOAP para obter estes dados, usando a mensagem RetrieveAttributeRequest. Mas chamando através do Javasript.

O primeiro passo foi criar o Recurso Web no tipo HTML, neste Recurso Web coloquei o seguinte código:

<HTML xmlns:b xmlns:a xmlns:soapenv>
	<HEAD>
         </HEAD>
	<BODY>
		<SELECT id=myList/>
	</BODY>
</HTML>

Até agora nada de especial, vamos colocar algum código Javascript, como vamos estar em um Recurso Web vamos ter que obter informação do contexto para isso teremos que referenciar este aspx ClientGlobalContext.js.aspx (já está no CRM não é necessário referenciar por exemplo noutro Recurso Web).

Com esta referência poderemos então obter o contexto desta maneira:

var context = GetGlobalContext();
var serverUrl = context.getServerUrl();

NOTA: O método getServerUrl encontra-se deprecated com a vinda do UR12, para rollups superiores deve-se usar o método getClientUrl.

Agora "basta" construirmos o pedido SOAP para obter a informação que pretendemos:

var SoapPath = serverUrl + "/XRMServices/2011/Organization.svc/web";
var MetadataId = "00000000-0000-0000-0000-000000000000";
				
var request = " <soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Body>"
request += "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
request += "<request i:type=\"a:RetrieveAttributeRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
request += "<a:KeyValuePairOfstringanyType>";
request += "<b:key>EntityLogicalName</b:key>";
request += "<b:value i:type=\"c:string\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + entityLogicalName + "</b:value>";
request += "</a:KeyValuePairOfstringanyType>";
request += "<a:KeyValuePairOfstringanyType>";
request += "<b:key>MetadataId</b:key>";
request += "<b:value i:type=\"ser:guid\"  xmlns:ser=\"http://schemas.microsoft.com/2003/10/Serialization/\">" + MetadataId + "</b:value>";
request += "</a:KeyValuePairOfstringanyType>";
request += "<a:KeyValuePairOfstringanyType>";
request += "<b:key>RetrieveAsIfPublished</b:key>";
request += "<b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + retrieveAsIfPublished + "</b:value>";
request += "</a:KeyValuePairOfstringanyType>";
request += "<a:KeyValuePairOfstringanyType>";
request += "<b:key>LogicalName</b:key>";
request += "<b:value i:type=\"c:string\"   xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + attributeLogicalName + "</b:value>";
request += "</a:KeyValuePairOfstringanyType>";
request += "</a:Parameters>";
request += "<a:RequestId i:nil=\"true\" /><a:RequestName>RetrieveAttribute</a:RequestName></request>";
request += "</Execute>";
request += "</soapenv:Body></soapenv:Envelope>";
				
var req = new XMLHttpRequest();
req.open("POST", SoapPath, false);
req.setRequestHeader("Accept", "application/xml, text/xml, */*");
req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
req.send(request);

Com este pedido podemos aceder a todas as opções do OptionSet escolhido. A seguir vou colocar todo o código, inclusivé o que permite fazer parsing dos resultados e que coloca noutra OptionSet.

<HTML xmlns:b xmlns:a xmlns:soapenv><HEAD>
<SCRIPT src="ClientGlobalContext.js.aspx"></SCRIPT>

<SCRIPT type=text/javascript>
			function getOptionSet (entityLogicalName, attributeLogicalName, retrieveAsIfPublished) {				
				var context = GetGlobalContext();
                var serverUrl = context.getServerUrl();
	            var SoapPath = serverUrl + "/XRMServices/2011/Organization.svc/web";
				var MetadataId = "00000000-0000-0000-0000-000000000000";
				
                var request = " <soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Body>"
				request += "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
				request += "<request i:type=\"a:RetrieveAttributeRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
				request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
				request += "<a:KeyValuePairOfstringanyType>";
				request += "<b:key>EntityLogicalName</b:key>";
				request += "<b:value i:type=\"c:string\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + entityLogicalName + "</b:value>";
				request += "</a:KeyValuePairOfstringanyType>";
				request += "<a:KeyValuePairOfstringanyType>";
				request += "<b:key>MetadataId</b:key>";
				request += "<b:value i:type=\"ser:guid\"  xmlns:ser=\"http://schemas.microsoft.com/2003/10/Serialization/\">" + MetadataId + "</b:value>";
				request += "</a:KeyValuePairOfstringanyType>";
				request += "<a:KeyValuePairOfstringanyType>";
				request += "<b:key>RetrieveAsIfPublished</b:key>";
				request += "<b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + retrieveAsIfPublished + "</b:value>";
				request += "</a:KeyValuePairOfstringanyType>";
				request += "<a:KeyValuePairOfstringanyType>";
				request += "<b:key>LogicalName</b:key>";
				request += "<b:value i:type=\"c:string\"   xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + attributeLogicalName + "</b:value>";
				request += "</a:KeyValuePairOfstringanyType>";
				request += "</a:Parameters>";
				request += "<a:RequestId i:nil=\"true\" /><a:RequestName>RetrieveAttribute</a:RequestName></request>";
				request += "</Execute>";
				request += "</soapenv:Body></soapenv:Envelope>";
				
				var req = new XMLHttpRequest();
				req.open("POST", SoapPath, false);
				req.setRequestHeader("Accept", "application/xml, text/xml, */*");
				req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
				req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
				req.send(request);

				if (req.responseXML != null) {
					var attributeData = req.responseXML.selectSingleNode("//b:value");
					if (attributeData != null) {
						var attributeType = attributeData.selectSingleNode("c:AttributeType").text;
						switch (attributeType) {
							case "Picklist":
								return attributeData;
								break;
							default:
								break;
						}
					}
				}
			}
		</SCRIPT>

<META charset=utf-8></HEAD>
<BODY contentEditable=true><SELECT id=myList></SELECT>
<SCRIPT>
	var optionSet = getOptionSet("ret_accao", "ret_estadocadastro", true);
	var options = optionSet.selectSingleNode("c:OptionSet//c:Options");
    var myPickList = document.getElementById("myList");
	for (var i = 0; i < options.childNodes.length; i++) {
		var textPick = options.childNodes[i].selectSingleNode("c:Label").selectSingleNode("a:UserLocalizedLabel").selectSingleNode("a:Label").text;
        var option = document.createElement("option");
        option.text = textPick;
        myPickList.add(option, myPickList.options[null]);
	}
</SCRIPT>
</BODY></HTML>

Se não quiserem andarem a fazer copy paste do código tenho aqui a solution que contém este código. É fazer download e importá-lo na vossa organização e lançar num botão por exemplo.

NOTA: Atenção ao cache dos web resources, façam iisreset e caso não resulte forcem o reload (CTRL+F5) na própria páguina que contiver este web resource

ListadeEstados_1_0_0_0.zip (3,29 kb)

Tags: , , , ,

Ferramenta - Ribbon Workbench

by Pedro Azevedo 6. December 2013 08:05

 Boas pessoal,

Inicio agora formalmente uma nova série de posts, que tem como objetivo mostrar as várias ferramentas\utilitários\bibliotecas disponíveis para o CRM e que tem como objetivo auxiliar-nos no dia-a-dia. A primeira “vítima” foi a biblioteca XrmServiceToolkit.

Hoje vou apresentar uma ferramenta muito útil e que não se pode viver sem ela. Estou a falar da ferramenta Ribbon Workbench. Como o próprio nome denúncia serve para customizar a Ribbon. Existem outras alternativas, tais como, Ribbon Editor, Pragma Toolkit e Visual Ribbon Editor mas a que mais utilizo é realmente a Ribbon Workbench. Esta já suporta CRM 2013 as outras ferramentas não tenho a certeza.

Para instalar basta ir a página http://www.develop1.net/public/page/Ribbon-Workbench-for-Dynamics-CRM-2011.aspx aqui temos várias informações e podemos escolher sobre qual versão do CRM queremos trabalhar.

Em ambos os casos vai fazer download da solução que devemos instalar na nossa organização. Depois de instalarmos a solução devemos ter a seguinte visualização:

Para aceder é selecionar o botão “Personalizado” no CRM 2011 tem o seguinte aspecto:

Depois de entrarmos no Ribbon Workbench temos que escolher a solução quer queremos customizar, por isso, já temos que ter criado uma solução e que esta inclua a entidade sobre a qual queremos customizar a ribbon, neste caso concreto adicionei a entidade Proposta (quote).

 

Depois de carregar a solução temos o seguinte aspecto:

Vamos então analisar cada uma destas secções individualmente:

 

Aqui vemos quais os botões que são possíveis de ver nas várias visualizações:

·         Home – é o menu que é mostrado nos ecrãs principais.

·         Sub-Grid – menu que é mostrado quando selecionamos uma subgrid, ou seja, no CRM 2011 sempre que selecionavamos uma subgrid a ribbon mudava para o contexto da entidade da subgird. No CRM 2013 não existe esta funcionalidade. Quer dizer existir existe por exemplo quando estamos num cliente e se virmos a lista de contactos:

 

Quando carregamos na lista aparece a lista em baixo:

 

Onde aqui aparece este menu.

·         Form – menu que aparece quando abrimos um registo de uma entidade.

De referir que temos a opção de ver a ribbon que aparece no cliente para o Outlook e que por ter a mesma estrutura que a barra de comandos e como vamos ver em futuros posts nós conseguimos recorrendo a ribbon acrescentar botões que não existem na barra de comandos.

Na próxima secção mostra os vários controlos que poderemos inserir na barra de comandos:

 

O tab permite agrupar botões, a tab scale define como os botões mudam quando existem retrições de tamanho. O grupo permite dar contexto a um conjunto de botões dentro de um determinado tab. E depois os vários tipos de botões, ou seja, Button, Split Button e Flyout. O Menu Section é o chamado Jewel Menu, que basicamente é o menu File que aparece no CRM 2011.

No CRM 2013 temos mais algumas definições. Na imagem estamos a ver a barra de comandos que pode mostrar até 5 comandos, os três pontos permite expandir as opções e é designado por overflow. Dentro da barra de comandos podemos ver os botões “normais”, os botões flyout podem estar dentro da barra de comandos e dentro do overflow:

 

Na secção final que vamos analisar temos as acções que poderemos realizar sobre os botões:

 

Na lista de entidades vemos as entidades que estavam na solução que escolhemos quando lançamos a ferramenta. Na lista ao lado temos os elementos da solução, incluindo os comandos que são executados, bem como as regras de mostrar ou não os botões. Este assunto dava para um livro por isso eu demonstrando nos vários posts que pretendo criar.

A última lista estão as propriedades dos elementos gráficos ou dos comandos ou regras.

A última acção e a mais importante é publicarmos as mudanças que realizamos, para isso basta carregar no botão "Publish".

Espero que tenham ficado com uma ideia desta magnifica ferramenta, um bem haja ao Scott Durow. Em futuros posts eu vou demonstrar como podemos acrescentar, esconder botões.

Até a próxima.

Tags: , , ,

CRM 2013 - Obter tipo de formulário

by Pedro Azevedo 17. November 2013 11:28

 

Boas Pessoal,

Hoje deixo aqui um post rápido, apenas porque precisei desta informação. E decidi criar uma categoria de posts sobre funções javascript da API Javascript do CRM 2013. Por isso já falei com getSaveMode. Desta vez vou citar outro método o getFormType que nos dá qual o tipo de formulário que estamos a trabalhar.

Por exemplo se estamos num form de criação, actualização ou se estamos em readonly. Isto é útil.

Aqui ficam os vários valores possíveis:

Form Type

Value

Undefined

0

Create

1

Update

2

Read Only

3

Disabled

4

Quick Create

5

Bulk Edit

6

Read Optimized

11

 

Vejam aqui um pequeno troço que como utilizar esta função:

function alertFormType()

{

    var formType = Xrm.Page.ui.getFormType();

    alert(formType);

}

 

Fonte: http://msdn.microsoft.com/en-us/library/gg327828.aspx#BKMK_getFormType~

Até a próxima.

Tags: , ,

CRM 2013 - Obter o modo ou razão de um registo gravado

by Pedro Azevedo 17. November 2013 09:27

 

Boas pessoal,

Na sequência dos posts de manusear o AutoSave achei pertinente mostrar que como é que no CRM 2013 se obtêm o modo ou a razão que um registo é gravado, através da função getSaveMode, eis os valores que a função retorna:

 

Entity

Event Mode

Value

All

Guardar

1

All

Guardar e Fechar

2

All

Guardar e Novo

59

All

AutoSave

70

Activities

Guardar como Concluída

58

All

Ativar

5

All

Reativar

6

User or Team owned entities

Atribuir

47

Email (E-mail)

Enviar

7

Lead

Qualificar

16

Lead

Desqualificar

15

 

O problema é que esta lista é muito diminuta comparada com a que existia no CRM 2011, podemos comparar no seguinte artigo. Apanhar quando por exemplo uma Proposta era ganha ou perdida era muito usado, pois permitia agirmos mediante um destes eventos. No CRM 2013 não é lançado nenhum evento de guardar.

Para experimentarem coloquem o seguinte código no onsave do formulário:

function onclosequote(context)
{
   var saveMode = context.getEventArgs().getSaveMode();
   alert(saveMode);
}

E não se esqueçam de dizer para passar no primeiro parâmetro o contexto para que o método consiga executar.

Neste momento e dependendo do que queremos fazer podemos contornar, tenho contornado este problema utilizando plugins. Ou no onload do evento por exemplo da encomenda, onde verifico qual o tipo de formulário e se tem alguma proposta associada.

Até a próxima.

Tags: , ,

CRM 2013 - Gerir funcionalidade AutoSave

by Pedro Azevedo 13. November 2013 07:32

Boas Pessoal,

Como prometido aqui estou eu a falar sobre como podemos gerir o Autosave, como é que o podemos ativar ou desativar e como vamos lidar com ele via código.

Como eu apresentei esta nova funcionalidade parece que parecia que era inevitável utilizar, mas esta decisão terá que ser realizada com muita ponderação. Já que como referi no último post vai passar pelos eventos (OnSave, Plugins e Workflows) de um guardar “normal”, ou seja, de 30 em 30 segundos poderá executar estes eventos. Por essa razão deveremos ponderar quando utilizar e sensibilizar todos os utilizadores desta nova funcionalidade.

Vamos então ver onde podemos ativar ou desativar esta funcionalidade. Se formos a barra de navegação e escolhermos Definições -> Administração. Temos a opção Definições de Sistema e aqui podemos ver esta opção:

De realçar que este parâmetro apenas vai fazer efeito sobre os 30 segundos, ou seja, o formulário vai deixar de gravar de 30 em 30 segundos. Mas ele vai gravar sempre automaticamente quando fecharmos uma tab, se utilizarmos a barra navegação ou utilizarmos os botões de back e foward do browser.

Infelizmente esta funcionalidade só pode ser configurada ao nível da organização e não a cada entidade. O que podia fazer sentido, porque mediante a entidade e a complexidade dos eventos que ocorrem esta funcionalidade poderia ser útil.

Uma maneira de lidarmos com o problema anterior é deixarmos este setting ativo e controlarmos o autosave através de código em cada entidade.

A maneira de controlarmos através de código é no evento onsave colocarmos o seguinte código:

function stopAutoSave(contexto) {

    var eArgs = contexto.getEventArgs();

    if (eArgs.getSaveMode() == 70) { //AutoSave

        eArgs.preventDefault();

    }

    else if (eArgs.getSaveMode() == 1) { //Guardar

        alert(‘Guardar e Fechar’);

    }

    else if (eArgs.getSaveMode() == 2) { //Guardar e Fechar

        alert(‘Guardar e Fechar’);

    }

    else if (eArgs.getSaveMode() == 59) { //Guardar e Novo

        alert(‘Guardar e Fechar’);

    }

}

Para mais informação sobre os valores do método getSaveMode estará neste post.

O código que referi é genérico para qualquer entidade, por isso basta fazermos upload como Recurso Web:

 

Depois em qualquer entidade poderemos adicionar este Recurso Web e depois é chamar o método stopAutoSave no OnSave do formulário:

 

Quando se adiciona o método não esquecer de marcar a opção para passar o conecto no primeiro parâmetro, e que se vocês repararem já estamos a espera de o receber. Finalmente não esquecer de publicar estas alterações.

 

 

Até a próxima

Tags: , , ,

CRM 2011 - UR15

by Pedro Azevedo 10. November 2013 02:41

 

Boas pessoal,

Está disponível o Update Rollup 15, podem descarregar aqui. Todas as informações estão disponíveis aqui com todos os dados e novidades.

De realçar temos uma grande melhoria no cliente do Outlook, algumas das novidades:

·         Isolamento do processo do cliente para o Outlook do processo do próprio Outlook, com esta nova funcionalidade deixa de haver partilha de memória entre as duas aplicações. Esta nova funcionalidade também está escalonada para o CRM 2013.

·         Melhoria da gestão de memória para o SQL Server CE 4.0

·         Entre outras funcionalidades que aconselho a lerem no link acima.

 

Até a próxima.

Tags: , ,

CRM 2013 - Autosave

by Pedro Azevedo 31. October 2013 07:10

Boas pessoal,

O AutoSave passou a ser uma feature por defeito no CRM 2013 (a sua primeira aparição foi no Polaris em algumas entidades), ou seja, não existe mais o botão de guardar, mentira como vamos ver mais a frente o botão continua a existir. Mas atenção que esta feature pode ser desactivada quando quisermos. O funcionamento é muito simples, o formulário é gravado automaticamente de 30 em 30 segundos ou quando saímos do formulário, quer estejamos a editar ou criar um registo. Evita termos que “clickar” no save e evitar os popup’s quando saímos de um formulário sem guardar.

Vamos então observar como esta feature se comporta. O botão de guardar aparentemente desapareceu, menos quando estamos a criar a entidade como podem ver na próxima imagem:

Mas quando gravamos este comando desaparece. Como podemos mais uma vez comprovar:

 

Então como podemos ver se o nosso registo está gravado ou não? Bom na verdade não temos que nos preocupar com isso, já que ele grava automaticamente de 30 em 30 segundos ou quando saímos desse registo. Mesmo assim é possível ver qual o estado actual deste registo. Como se vê na próxima imagem no canto inferior direito temos a indicação desse estado.

A disquete significa que o registo está guardado, quando alteramos algo no nosso formulário ele comuta automaticamente para o estado da imagem seguinte:

Como sabemos existem campos obrigatórios, como lida o CRM com esta questão? Se houver campos obrigatórios e caso eles não estejam preenchidos o CRM não pode gravar automaticamente. Como podemos ver nas duas imagens a seguir, primeiro aparece o texto da primeira imagem, carregando na disquete ele dá informação da razão de não ter gravado automaticamente. Para além dos registos obrigatórios ele valida o tipo de dados que estamos a introduzir.

Neste estado se tentarmos deixar esta página ele vai avisar-nos com um popup semelhante ao que acontece com o CRM 2011, ou seja, pergunta se queremos mesmo sair do registo.

Para o utilizador mais curioso posso confirmar que o botão da disquete funciona, ou seja, se carregarmos na disquete ele força a gravação:

Para além desta feature nos poupar o número de clicks também previne ou diminui as possibilidades de perca de informação, por falha de rede e outros problemas.

Quando temos um formulário só de leitura o save não está disponível e consequentemente o autosave não está disponível.

Problemas?

O fato de o formulário gravar sem a intervenção do utilizador pode gerar problemas e temos que gerir e sensibilizar os utilizadores muito bem. Quantas vezes vamos a um formulário e brincamos mexendo nos vários campos, para testar uma determinada funcionalidade? E podemos fazer isso diretamente em produção porque só gravava quando carregávamos no gravar. Este é um problema pois como grava automaticamente se calhar só queríamos testar valores.

Mas existe outro mais preocupante, deixo a deixa e no artigo que vamos falar mais tecnicamente desta feature vou mostrar como evitarmos, e a pergunta é:

Como se comportam os plugins e os workflows? Bem como seria de esperar estes são corridos a mesma, ora de 30 em 30 segundos estes estão a correr, vamos depois ver como podemos controlar este problema.

 

Até a próxima.

Tags: , ,

Estamos preparados para migrar para o CRM 2013 (Orion)?

by Pedro Azevedo 23. October 2013 05:49

Boas Pessoal,

O CRM 2011 permitiu que continuássemos a usar o código CRM 4.0 pelo menos até ao UR12. Com a vinda do CRM 2013 esta compatibilidade foi completamente quebrada e para fazer upgrade para o CRM 2013 primeiro teremos que migrar para o CRM 2011 e depois para o CRM 2013 pelo menos é o aconselhável.

Para quem tem o código todo 100% compatível com o CRM 2011 incluindo os seus endpoints pouco ou nada terá que fazer. Mas para não garantir realize estes passos:

1 - A primeira coisa que deve fazer é se modo HTC está aplicado, se tiver desligue e teste novamente, caso corra tudo bem então o seu código tem boas probabilidades de funcionar no CRM 2013.

2 - Correr a ferramenta Custom Code Validation Tool for Microsoft Dynamics CRM 2013 que valida os web resources que fundamentalmente vai verificar se ainda estamos a usar a API do CRM 4.0 ou algum endpoint dessa versão.

3 - Para o código server-side (.Net) e se mais uma vez estamos a usar os WebServices do CRM 2011 também podemos estar descansados, já que não será necessário fazer mais nada. Mesmo assim existe uma ferramenta chamada Legacy Feature Check Tool que permite validar este mesmo código, vejam o readme que explica como executar.

Em futuros posts vou falar melhor sobre o CRM 2013 e todas as suas funcionalidades.

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