Tudo sobre WebResources III

by Pedro Azevedo 30. August 2013 16:21

Boas pessoal,

Estou de volta com o último post sobre o assunto dos WebResources agora vendo casos práticos de onde posso usar esta funcionalidade:

Dashboard

Para adicionar é semelhante ao que fizemos quando adicionamos um WebResource ao formulário. Vejam o resultado:

Em relação ao exemplo anterior retirei o acesso ao formulário pois aqui não tínhamos essa situação. Mais de resto o código é igual.

 

Navegação no Formulário

Vamos analisar como podemos adicionar no Sitemap:

 

 Vejam o resultado:

Até aqui nada de especial, conseguimos referenciar os WebResources sem uma única linha de código, vamos ver casos mais complicados.

SiteMap – Sub Area

Para adicionarmos este tipo de link é necessário trabalharmos sobre o sitemap, por isso vamos criar um WebResource com o sitemap e vamos utilizar uma ferramenta SiteMapEditor:

Vejam a forma de referenciar o WebResource através da directiva $webresource. Se não utilizarmos esta ferramenta, teríamos que ter adicionar o SiteMap a uma solução, exportar essa solução e mexer directamente no XML e afectar as propriedades que afectamos em cima e depois importar novamente esta solução.

Vejam o resultado:

 Falta-nos falar de um último sítio onde poderemos usar os WebResources, que é na ribbon. Ora na ribbon o interessante é executarmos código Javascript por exemplo para escondermos ou desabilitarmos um botão ou para abrir um WebResource. Já tenho planeado um post para falar como desabilitar um botão na ribbon, por isso aqui vamos abrir um WebResource.

Apenas como exemplo e sem grande ciência adicionei um botão (utilizei a ferramenta RibbonWorkbench) e adicionei uma acção para abrir um URL, neste caso coloquei como endereço $webresource:ret_testewr como podem verificar na imagem.

E podem ver a sua execução:

Para complementar a situação anterior, existe outra forma de abrirmos um WebResource, utilizando a função openWebResource que apareceu com o UR8. Para a utilizarmos em vez de colocarmos um acção do tipo URL vamos criar uma acção para chamar uma função Javascript:

Antes de mostrar o código da função openwr, reparem como ele referenciou o WebResource onde está a função, através da directiva $webresource. A função openwr é muito simples:

function openwr() {
  Xrm.Utility.openWebResource("ret_testewr");
}

E assim finalizamos esta temática.

 

Até a próxima.

Tags: , , ,

Referência Rápida - StatusCode vs StateCode

by Pedro Azevedo 17. August 2013 00:16

 

 

Boas pessoal,

Segue mais um post que vai servir de referência, ou seja, informação que eu procuro regularmente. Desta vez saber quais as razões de estado possíveis para um determinado estado:

 

Entidade

Estado (statecode)

Razão do Estado (statuscode)

Account

0 Active

1 Active

1 Inactive

2 Inactive

Activity

0 Open

1 Open

1 Completed

2 Completed

2 Canceled

3 Canceled

3 Scheduled

4 Scheduled

Appointment

0 Open

1 Free

2 Tentative

1 Completed

3 Completed

2 Canceled

4 Canceled

3 Scheduled

5 Busy

6 Out of Office

Article

1 Draft

1 Draft

2 Unapproved

2 Unapproved

3 Published

3 Published

Campaign

0 Active

0 Proposed

1 Ready To Launch

2 Launched

3 Completed

4 Canceled

5 Suspended

Campaign Activity

0 Open

0 In Progress

1 Proposed

4 Pending

5 System Aborted

6 Completed

1 Closed

2 Closed

2 Canceled

3 Canceled

Campaign Response

0 Open

1 Open

1 Closed

2 Closed

2 Canceled

3 Canceled

Case

0 Active

1 In Progress

2 On Hold

3 Waiting for Details

4 Researching

1 Resolved

5 Problem Solved

2 Canceled

6 Canceled

Case Resolution

0 Open

1 Open

1 Completed

2 Closed

2 Canceled

3 Canceled

Contact

0 Active

1 Active

1 Inactive

2 Inactive

Contract

0 Draft

1 Draft

1 Invoiced

2 Invoiced

2 Active

3 Active

3 On Hold

4 On Hold

4 Canceled

5 Canceled

5 Expired

6 Expired

Contract Line

0 Existing

1 New

1 Renewed

2 Renewed

2 Canceled

3 Canceled

3 Expired

4 Expired

Currency

0 Active

0 Active

1 Inactive

1 Inactive

Discount

0 Active

100001 Active

1 Inactive

100002 Inactive

E-mail

0 Open

1 Draft

8 Failed

1 Completed

2 Completed

3 Sent

4 Received

6 Pending Send

7 Sending

2 Canceled

5 Canceled

Esta tabela é útil principalmente quando estamos a mudar o estado e temos colocar uma razão de estado válida, senão estamos sujeitos apanhar este erro comum “State code is invalid or state code is valid but status code is invalid for a specified state code.

 

Até a próxima.

 

Tags: , , ,

Obter dados de um SubGrid

by Pedro Azevedo 8. August 2013 01:12

Boas pessoal,

Tinha um requisito que era calcular o valor médio de uma lista. Neste caso vou demonstrar através da lista de oportunidades em que o objectivo é calcular a média do valor dos produtos inseridos.

Bom a minha primeira solução foi obter os registos directamente a grid, já que lá estavam os dados, assim fiz então baseei-me em alguns blogs ora vejam:

http://lakshmanindian.wordpress.com/2012/05/25/retrieve-subgrid-rows-in-crm-2011-using-jscript/

http://stackoverflow.com/questions/17651752/how-to-retrieve-all-record-ids-of-a-sub-grid-in-crm-2011-using-javascript

http://crmbusiness.wordpress.com/2011/05/19/crm-2011-javascript-and-subgrids-code-example/

Mas sempre tive problemas:

  • ·         Com o ir buscar a grid, com o código pré e após UR12
  • ·         Como ir buscar todos os elementos da grid, pois alguns dos métodos só vão buscar os registos que estão visíveis.
  • ·         Ter os campos necessários na lista

Então passei a enveredar por outra solução que é realizar uma query odata para obter todos os registos e apenas os campos que necessito. Tenho um overhead de obter todos os dados novamente, mas tenho uma solução que sei que vai perdurar no tempo pois qualquer mudança na forma de obter os registos de uma subgrid vou ficar imune.

Independentemente da forma como vou buscar os produtos da oportunidade terei que adicionar um Recurso Web em que neste caso terá apenas uma caixa de texto. Aqui podia não ter optado por um Recurso Web e ter colocado num campo que criasse como atributo da oportunidade. O Recurso Web permite ter campos dinâmicos, no requisito que referi tinha que realizar várias análises de qual o produto com maior valor, qual o produto com mais unidades, qual o produto que demorava mais a instalar. Por essa razão e porque o vosso caso pode ser semelhante vou manter a solução de um Recurso Web. Podem ver neste artigo um pouco mais sobre Recurso Web.

Vamos então adicionar um Recurso Web a nossa solução:

E colocar o seguinte código:

<HTML><HEAD><BASE>
<META charset=utf-8></HEAD>
<BODY contentEditable=true><INPUT id=quantity name=quantity>

<SCRIPT type=text/javascript src="ret_jquery"></SCRIPT>
<SCRIPT src="ClientGlobalContext.js.aspx"></SCRIPT>
<SCRIPT type=text/javascript>
  $(document).ready(function(){
    var entityId = window.parent.Xrm.Page.data.entity.getId();
    var serverUrl = window.location.protocol + "//" + window.location.host + "/" + Xrm.Page.context.getOrgUniqueName();
    var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";

    var odataSetName = "OpportunitySet";
    var relName = "/product_opportunities";

    var odataSelect = serverUrl + ODATA_ENDPOINT + "/" + odataSetName + "(guid'" + entityId.substr(1,36) + "')" + relName;

    return $.ajax({
       type: "GET",
       contentType: "application/json; charset=utf-8",
       datatype: "json",
       url: odataSelect,
       beforeSend: function (XMLHttpRequest) { XMLHttpRequest.setRequestHeader("Accept", "application/json"); },
       success: function (data, textStatus, XmlHttpRequest){
              RetrieveMultipleEntities(data.d.results);
       },
       error: function (XmlHttpRequest, textStatus, errorThrown) { alert('TextStatus:' + textStatus + "\nerror:" + errorThrown); }
    });
  });

  function RetrieveMultipleEntities(ManyEntities)
  {
    var total = 0;
    for( i=0; i< ManyEntities.length; i++){
      var Entity = ManyEntities[i];
      total = total + parseFloat(Entity.BaseAmount.Value)
    }
    $('#quantity').val(total/ManyEntities.length);
  }
</SCRIPT>

<P><FONT size=2 face=Tahoma></FONT> </P></BODY></HTML>

E o nosso desenvolvimento acabou, basta adicionarmos este Recurso Web dentro do formulário (que vamos fazer mais tarde) e este código funciona as mil maravilhas. Vamos explorar alguns pormenores que apesar de já estar explicado em outros artigos que escrevi, nunca é demais referir:

·         Este código pressupõe termos adicionado um Recurso Web com a biblioteca jQuery, vejam aqui como referencio:

<SCRIPT type=text/javascript src="ret_jquery"></SCRIPT>

·         A referência a biblioteca para podermos aceder ao contexto da entidade:

<SCRIPT src="ClientGlobalContext.js.aspx"></SCRIPT>

·         A construção do URL para obter o endpoint OData:

var serverUrl = window.location.protocol + "//" + window.location.host + "/" + Xrm.Page.context.getOrgUniqueName();
var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";

Vejam a utilização do Xrm.Page.context para obter o contexto, que sem a referenciação a biblioteca anterior não funcionava. O resultado da variável deve ficar algo do género:

http://<server>/<organization>/XRMServices/2011/OrganizationData.svc

·         Por último a obtenção do GUID do registo onde estamos:

var entityId = window.parent.Xrm.Page.data.entity.getId();

Vejam como eu referencio o Xrm.Page para poder aceder por exemplo aos campos do formulário.

Se tivéssemos optado por não utilizar um Recurso Web o código era semelhante, não teríamos que referenciar as duas bibliotecas Javascript (apesar de termos que incluir a biblioteca jQuery na solução) e na obtenção do id do registo podemos retirar a parte do window.parent.

Como tinha referenciado agora basta adicionarmos o Recurso Web ao formulário: 

 

Vejam o resultado final:

 

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