Workflow–condições de espera

by Pedro Azevedo 12. April 2015 23:13

Boas pessoal,

Surgiu uma dúvida no fórum MSDN (para variar aproveitei para fazer um post Sorriso ) que tem a ver quando se quer lançar um Fluxo de Trabalho numa determinada data. Como é uma pergunta recorrente resolvi escrever um post com estas informações, com vários casos de utilização. Para além de podermos esperar até uma determinada data ainda podemos esperar por exemplo até quando um valor mudar. Parecem iguais mas diferem em pequenos pormenores, começando que o “Tempo Limite” como o próprio nome diz vai ser sempre uma condição temporal, enquanto que o tipo “Condição de Espera” vai esperar que um determinado campo chegue a um determinado valor. Mas no fundo o “Tempo Limite” é uma condição de espera.

A primeira ressalva vem logo na criação do Fluxo de Trabalho já que com a nova opção de podermos realizar Fluxo de Trabalho síncronos e caso escolhamos esta opção não vamos ter disponível nenhuma opção de condição de espera, por isso não se esqueçam este fluxo de trabalho terá que ser assíncrono, pois ele vai mesmo ser assíncrono. Mas cometendo esse erro para verificarmos esse comportamento:

image

Como podem verificar na imagem estou a criar um fluxo de processo síncrono, vamos ver qual é o comportamento com estas configurações:

image

Como podem reparar não temos a opção de “Condição de Espera” como referi foi de propósito, para converter num processo assíncrono basta carregarmos neste botão:

image

Ao transformarmos num processo assíncrono passamos a ter as seguintes opções:

image

Agora sim podemos avançar com o nosso tutorial, adicionado um condição de espera:

image

Se selecionarmos par configurarmos a condição vamos ter as várias opções:

image

Aqui podemos escolher a própria entidade, neste caso a Oportunidade ou algumas das entidades relacionadas, para além disso podemos escolher o Processo, este Processo é o que nós vamos utilizar para realizarmos uma condição temporal.

image

Dentro do processo temos a opção “Tempo Limite” e é sobre esta propriedade que podemos colocar uma condição de espera, esta como podemos ver a seguir pode ser uma determinada data, ou passado um determinado tempo, ou podermos referenciar um campo data dentro da entidade sobre a qual estamos a realizar o Fluxo de Trabalho ou sobre uma das relacionadas, vejam a seguir as várias opções:

image

image

image

Como disse aqui entra outra das diferenças entre os dois tipos o “Tempo Limite” não permite duas condições, como vemos ele só mostra a opção Processo mesmo assim não é possível selecionar:image

A diferença entre os dois tipos realmente foram as apresentadas, porque ao nível de criação só muda mesmo a configuração da condição, onde podemos fazer comparações com todos os campos:

image

Neste caso eu quero lançar esta Oportunidade quando a Fase de Venda tenha o valor Propor. Vocês agora podem dizer-me mas esta condição eu posso emular sem um Condição de Espera é verdade se vocês configurarem um Workflow para que seja lançado aquando da mudança de um campo também funciona, mas aqui o objetivo é diferente porque eu posso aplicar estas condições de espera a qualquer momento dentro do meu Workflow, ou seja, posso ter um Workflow com muitos steps e ficar a espera que uma determinada condição de espera seja alcançada.

A seguir temos que colocar o que queremos fazer quando esta condição de espera ocorra:

image

Neste caso envio um email. O exemplo pode ser válido pois é enviado um email ao gestor de cliente quando a Data de Fecho Estimada seja alcançada e assim dizer que tem que fechar hoje a oportunidade.

 

Até a próxima.

Tags: , ,

Enviar email ao antigo owner de um registo

by Administrator 23. January 2015 22:47

Boas pessoal,

Mais um desafio do fórum, desta vez, não fui o primeiro a responder. A pergunta era se era possível enviar um email quando a mudança de owner de um registo, através de Workflow (Fluxo de Trabalho) ou Javascript. Bom a primeira resposta sugere que o melhor é recorrer a plugins e confesso que a primeira vez que li concordei com a afirmação, eu até diria que seria a única hipótese.

Velhos vícios, o mal de ter começado com o CRM 4 e com isso que ainda mantenha algumas soluções dessa altura. Como tenho defendido aqui no blog, deve-se sempre optar por uma solução configurável em vez de uma solução programável, isto porque através de configurações “toda” a gente consegue ler, quer seja uma pessoa técnica ou funcional e na altura de upgrades estes objetos costumam ser mais fáceis de migrar.

Pois bem depois de ter lido esta pergunta uma segunda vez, fez-se um click na minha cabeça e porque não realizar isto com os Fluxos de Trabalho? Pois bem com o CRM 2013 foram introduzidos os Fluxos de Trabalho síncronos, que nos possibilitou por exemplo tratar da numeração automática como podem ver neste post. Com este tipo de Fluxo de Trabalho conseguimos aceder ao valor antigo e ao valor novo e com isso enviar um email ao novo\antigo proprietário.

Vamos ver na prática como o fazemos. Primeiro passo é criar um Fluxo de Trabalho síncrono:

image

Reparem que tiramos o pisco (que por defeito está selecionado) que fazia com que o Fluxo de Trabalho corresse assincronamente. Assim o Fluxo de trabalho torna-se síncrono. Avançando com o processo podemos então criar a notificação ao novo e antigo owner. Caso esqueçamos de retirar o pisco não faz mal porque dentro do Fluxo de Trabalho temos a hipótese de transformar o Fluxo de Trabalho em síncrono e vice-versa.

Mas primeiro temos que dizer ao Fluxo de Trabalho que ele pode correr quando houver alteração de um campo, neste caso como se trata do proprietário, podemos escolher quando o registo é atribuído e informamos que ele deve correr antes de guardar o registo e assim apanhar o valor antigo:

image
Pode parecer estranho mas o nosso Fluxo de Trabalho já está configurado, agora basta criar o email e no campo para enviar vamos colocar o proprietário pois configuramos o Fluxo de Trabalho para correr antes de ser assignado outro proprietário:

image

Uma solução que prometia mais trabalho que se tornou simples por utilizarmos a última novidades da plataforma.

Até a próxima

Tags: , ,

Como fazer debug de um plugin e atividade customizada no CRM On-Premise

by Pedro Azevedo 4. December 2014 02:23

Boas pessoal,

Vou continuar a série de fazer debug. Até agora abordamos como realizar debug sobre plugins online e em Web Resources. De referir que a prática que usamos no CRM Online pode-se usar no on-premise também.

Hoje quero falar sobre fazer debug em plugins num ambiente on-premise, que vai permitir realizar um debug em real-time. Para ser mais exato este procedimento é para código servidor, ou seja, tanto dá para plugins como para atividades workflow.

A primeira premissa é termos a nossa DLL do plugin ou da atividade de workflow e o ficheiro PDB (contém informações para realizar debug). Temos que colocar estes dois ficheiros na pasta: “<pasta de instalação>\Microsoft CRM\server\bin\assembly” (C:\Program Files\Microsoft CRM\server\bin\assembly), nesta pasta também devem ser todas as DLLs que se dependa a não ser que estas estejam registadas no GAC.

Uma vez que temos estes ficheiros podemos chegar ao nosso servidor de desenvolvimento e com o projeto do plugin aberto anexarmos um destes processos:

  • w3wp.exe para os plugins síncronos;
  • Microsoft.Crm.Application.Hoster.exe para quando temos uma ligação offline através do Outlook.
  • CrmAsyncService.exe quando se trata de um plugin assíncrono ou uma atividade workflow
  • Microsoft.Crm.Sandbox.WorkerProcess.exe quando temos o plugin registado no modo sandbox.

Vejam a seguir alguns screenshots de como fazer attach a alguns dos processos acima:

Com esta configuração o próximo plugin ou atividade de workflow irá parar no breakpoint definido.

As vezes pode ser frustrante porque o breakpoint não é ativado. Quando isto acontece podemos seguir uma espécie de checklist:

  1. Reset ao IIS (diretamente no IIS ou na linha de comandos escrever iisreset)
  2. Se for uma atividade de workflow ou plugin assíncrono, restaurar o serviço Assync do CRM
  3. Recompilar (em vez de Rebuild, podemos efetuar também o clean) o projeto do plugin ou atividade workflow
  4. Colocar a DLL e o PDB na pasta referida
  5. Registar o assembly pelo Registration Tool
  6. No Visual Studio colocar o breakpoint e anexar os processos referidos.

 

Se no Visual Studio se houver a seguinte mensagem sobre o breakpoint, quer dizer que temos que efetuar a lista acima:

Se o breakpoint apresentar a mensagem a seguir não se preocupem que em principio ele para no breakpoint:

E aqui está um exemplo, neste caso este plugin é lançado aquando da criação de um cliente:

Esta estratégia funciona bem nos ambientes de desenvolvimento, onde temos o visual studio instalado na mesma máquina onde está o servidor de CRM. Caso não tenhamos este cenário necessitamos de um auxiliar que é o Remote Debugger instalado. Podem ver aqui um bom artigo para auxiliar a sua instalação. Depois de estar instalado o Remote Debugger é colocarmos no campo Qualifier o nome do servidor.

 

PS: A versão do CRM usado neste post foi o CRM 2011 com o VS 2010, mas em outros ambientes é praticamente igual.

 

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: , , ,

Custom Workflow Activities - Resolução de incidentes

by Pedro Azevedo 9. September 2013 06:06

Boas pessoal,

EDIT: Eu já cá tinha um exemplo de uma criação de um Custom WorkFlow Activity, o post continua igual (alterei apenas o objectivo) mas mudei o exemplo, o exemplo que tinha era muito simples e estou a trocar por um exemplo que acontece-nos penso que a todos. O objectivo é extrair propriedades da Resolução de Incidente.

Hoje vou fazer um pouco de código C# Smile estava a ver que não… vamos falar em concreto sobre Custom Workflow Activities que permitem estender o comportamento por defeito dos Workflows.

O objectivo será que quando um incidente seja encerrado enviar em email com a descrição de resolução. A primeira opção que ocorria era criar um workflow, o problema é que dentro de um Workflow não conseguimos aceder a entidade Resolução de Incidente.

Uma solução seria criar um campo no incidente com esta informação. Mas existe uma solução mais eficaz que é recorrer a actividades customizadas de Workflow. Dentro desta actividade vamos pesquisar por esta entidade e retornar a descrição.

A primeira coisa a fazer é criar um projecto do template Workflow, do tipo Activity Designer Library:

 

Depois do projecto criado podem apagar o ficheiro que é criado por defeito:

 

E adicionem uma classe normal:

 

Antes de começarmos a colocar código vamos referenciar três DLLs fundamentais para programarmos para o CRM:

 

Estas DLLs estão na pasta onde vocês instalaram o SDK (se não tiverem podem sacar aqui). A seguir podemos colocar o seguinte código:

public class GetIncidentRes : CodeActivity
{
    protected override void Execute(CodeActivityContext activityContext)
    {
        IWorkflowContext contexto = activityContext.GetExtension<IWorkflowContext>();
        IOrganizationServiceFactory serviceFact = activityContext.GetExtension<IOrganizationServiceFactory>();
        IOrganizationService service = serviceFact.CreateOrganizationService(contexto.UserId);

        QueryByAttribute queryIncRes = new QueryByAttribute();
        queryIncRes.Attributes.AddRange(new string[] { "incidentid" });
        queryIncRes.ColumnSet = new ColumnSet(new string[] { "description" });
        queryIncRes.EntityName = IncidentResolution.EntityLogicalName;
        queryIncRes.Values.AddRange(new object[] { contexto.PrimaryEntityId });

        EntityCollection incidentResEntity = service.RetrieveMultiple(queryIncRes);
        IncidentResolution incidentResolution = (IncidentResolution)incidentResEntity.Entities.FirstOrDefault();
        DescrResol.Set(activityContext, incidentResolution.Description);
    }


    [OutputAttribute("DescrResol")]
    public OutArgument<string> DescrResol { get; set; }
}

Temos que referenciar três namespaces:

using System.Activities;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Workflow;

Em relação ao código é bastante simples, temos que derivar de CodeActivity, declarar o nosso output através do atributo OutputAttribute o texto que colocamos é o nome que vai aparecer depois no editor do Workflow. Mais de resto é o que fazemos habitualmente no CRM.

O Visual Studio vai-se queixar que não conhece a class IncidentResolution, isto porque ele não conhece as entidades que temos no CRM. Como estamos a trabalhar apenas com as entidades standard temos um ficheiro com todas as entidades standard na pasta do SDK (\samplecode\cs\helpercode). Poderíamos ter optado por usar o método late bound, mas neste caso quero trabalhar com early bound para isso teremos que gerar as classes das entidades e assim receber as entidades customizadas. Teremos que utilizar a ferramenta crmsvcutil.exe (\bin), a sua definição é a seguinte:

CrmSvcUtil.exe /url:http://<serverName>/<organizationName>/XRMServices/2011/Organization.svc /out:<outputFilename>.cs 
/username:<username> /password:<password> /domain:<domainName>

Podemos adicionar o ficheiro resultante ao nosso projecto:

 

Ao tentarmos compilar vai aparecer mais alguns erros um deles relacionado com a versão do .Net que ele coloca por defeito “.NET Framework 4 Client Profile”, mudamos para a “normal”:

Adicionamos ainda outra referência – System.Runtime.Serialization. Uma última coisa que é adicionar um strong name a nossa DLL:

Depois disto tudo vamos registar a nossa DLL, através da ferramenta: Plugin Registration Tool:

 

 

Depois de escolhermos a nossa DLL, basta dizer qual o workflow que queremos registar e temos o nosso workflow registrado.

Agora já podemos ir ao CRM e fazer o nosso Workflow que quando um incidente for finalizado envie um email com os detalhes da resolução, portanto criamos um novo processo do tipo Fluxo de Trabalho:

Depois de dizermos que o workflow só vai correr aquando da mudança de estado e depois de adicionarmos a condição que é apenas no estado Resolvido, podemos executar a nossa actividade customizada:

Depois deste passo podemos criar o email com base na informação retornada do nossa actividade customizada:

 

E temos a nossa actividade customizada, podem ver a sua funcionalidade e utilidade deste mecanismo.

 

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