Microsoft Dynamics CRM 2015 – download the preview guide

Download your free release preview guide for Microsoft Dynamics CRM 2015 here for on-line and premise users;

The preview looks at the capabilities available for

  • Microsoft Dynamics CRM 2015
  • Microsoft Dynamics CRM Online (2015 Update)
  • Microsoft Dynamics Marketing (2015 Update)
  • Microsoft Social Listening

 

CRM2011 – Retrieve Plugin

2007_microsoft_dynamics_crmToday I need to execute a method every time open a Contact record.

Usually this would be frowned upon because this code could easily present a performance issues, especially if the data you’re gathering is hosted on an external resource.

In the off-change you do need to do this, here is the solution:

First, create a new Plugin and sign the assembly with a key:

public void Execute(IServiceProvider serviceProvider)
{
    // Obtain the execution context from the service provider.
    Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
        serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));

    if (context.Depth == 1)
    {
        IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
        IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

        // Obtain the target entity from the input parmameters.
        EntityReference entity = (EntityReference)context.InputParameters["Target"];

        ColumnSet cols = new ColumnSet(
                             new String[] { "lastname", "firstname", "address1_name" });

        var contact = service.Retrieve("contact", entity.Id, cols);

        if (contact != null)
        {
            if (contact.Attributes.Contains("address1_name") == false)
            {
                Random rndgen = new Random();
                contact.Attributes.Add("address1_name", "first time value: " + rndgen.Next().ToString());
            }
            else
            {
                contact["address1_name"] = "i already exist";
            }
            service.Update(contact);
        }
    }
}

Next, hop over to the Plugin Registration Tool (included with the CRM SDK) and register the plugin:
Unbenannt

What you’ll end up with in this example is:

On first open of the record:

clip_image002_thumb

 

 

 

On all future opens of the record:

clip_image0025_thumb

CRM 2011 – Pass Data Between Plugins using SharedVariables

2007_microsoft_dynamics_crmEvery day I have new things to learn … and yesterday I had a problem about tho share variables between plugins in my CRM2011 project. MSCRM2011 and the execution pipeline provides the ability to pass data from one plug-in to another through an IPluginExecutionContext property called SharedVariables. This property is a collection of key/value pairs which developers can use to share data between plug-ins which are registered on both the pre and post events.

Here is the way to pass some paramters and get in between the steps in MS CRM 2011, while writing plugin.

Pre-Create Account Plug-in

if (context.InputParameters.ContainsKey("Target") && context.InputParameters["Target"] is Entity)
{
Entity target = context.InputParameters["Target"] as Entity;
if (target != null)
{
// some wacky data validation
string city = target.GetAttributeValue<string>("address1_city") ?? string.Empty;
int numEmployees = target.GetAttributeValue<int>("numberofemployees");
int accountCategory = target.GetAttributeValue<int>("accountcategorycode");

// city is auckland, numEmployees > 100, account category is preferred customer
bool updateRelated = city.Equals("Auckland", StringComparison.InvariantCultureIgnoreCase) && numEmployees > 100 && accountCategory == 1;
context.SharedVariables.Add("updatedRelated", updateRelated);
}
}

Post-Create Account Plug-in

if (context.InputParameters.ContainsKey("Target") && context.InputParameters["Target"] is Entity)
{
Entity target = context.InputParameters["Target"] as Entity;
if (target != null)
{
if (context.SharedVariables.ContainsKey("updatedRelated"))
{
bool updateRelated = (bool)context.SharedVariables["updatedRelated"];
if (updateRelated)
{
// additional logic to update related records of the Account
}
}
}
}

Agile Methodologies: Quando, Dove e Perche’ utilizzarle.

Quando e’ meglio utilizzarle e quando no. Le mie considerazioni.

Introduzione

Ho appena finito di leggere questo articolo (Inutilità del Diagramma di Gantt – http://blogs.ugidotnet.org/manuel0081/archive/2013/03/09/inutilita-del-diagramma-di-gantt.aspx) che ho trovato molto utile e molto interessante e che mi trova pienamente d’accordo. L’articolo descrive come i diagrammi di Gantt in alcune situazioni aziendali possono essere spesso sopravvalutati. Ho pensato quindi di scrivere un articolo simile orientato metodologie agili, descrivendo il mio punto di vista e le mie considerazioni, il mio pensiero e soprattutto i casi in cui preferisco utilizzarle e quando no.
Spesso accade di sentire parole chiave come SCRUM, AGILE, SPRINT, LAVAGNA “alla macchinetta del caffè”. Senza approfondire questi importanti argomenti e sottovalutandone i contenuti, si rischia di arrivare a parlare di nulla e di trasformare ogni parola in qualcosa di inapplicabile e addirittura, a volte, deleterio. Non deve essere un argomento che va di moda, ma dovrebbe al contrario essere sviscerato, analizzato e compreso, per fare in modo che la sua applicazione possa essere utile e, soprattutto, vincente. Perchè stiamo parlando di team e situazioni reali, quindi applicare le regole, significa avere anche una profonda conoscenza del mezzo.
Prima di iniziare a scrivere le mie considerazioni vorrei fare un’importante considerazione: questi sono appunto miei pensieri e, vanno valutati come tali. È una parte della mia esperienza avuta sul campo.L’articolo non vuole essere una critica a nessuno ma un punto di raccolta da condividere per capire se le mie osservazioni sulla loro scelta sono corrette oppure no.
Scrivo da fan e da utilizzatore accanito di queste metodologie: le utilizzo da anni e non potrei farne a meno.
Cerchiamo di capire quanto voglio dire analizzando, passatemi il termine, i momenti:

Prima di scegliere

Quando mi trovo di fronte ad una scelta di uno strumento o, come in questo caso, la metodologia corretta da utilizzare nella fase di sviluppo, cerco sempre di capire se tale scelta mi porterà benefici oppure no. Sembra banale la scelta ma molte volte è quella più difficile, e molto spesso è sottovalutata tanto da arrivare a non rendersi nemmeno conto di non essersi nemmeno soffermati un minuto. Uno strumento o una metodologia scelta in maniera errata potrebbe causare non solo rallentamenti e sviluppi erronei, ma, nei casi peggiori, anche il fallimento.
A mio modesto parere si dovrebbe tenere conto di alcuni punti fondamentali che in futuro ci aiuteranno a prendere la giusta decisione. Alcuni troveranno i punti seguenti in contrasto tra loro e contro qualsiasi metodolgia di lavoro; purtroppo la realtà aziendale è sempre molto diversa dall’idea teorica (e ogni business ha il suo set di regole ben diverse) e tutti i buoni propositi vanno a farsi benedire.
Ecco cosa mi fa scegliere se utilizzare o no una metodologia durante lo sviluppo del progetto, perchè è di questo che si sta parlando:

  • Durata del progetto: In un progetto dove il ciclo di sviluppo ha una durata inferiore al mese, l’utilizzo di metodologie agili, secondo me, è controproducente: I processi da adottare in metodologie come scrum, posso portare ad un prolungamento del processo di sviluppo e possono portare ad uno stress.
  • Team a disposizione: Il team è molto importante perchè è l’apparato operativo del progetto stesso. Un team rodato e che lavora insieme da anni è un ottimo punto a favore della scelta, ma se si disponesse di un team nuovo, nel quale le persone non hanno mai lavoraro tra loro, sarebbe meglio trovare un compromesso. Il mio consiglio è di utilizzare sempre team misti: dove ci sono membri esperti e membri non esperti: in questo modo si ha la possibilità di far crescere il team. Non userei queste metodologie in un team nuovo: specialmente in un team formato da soli consulenti: ho notato che è molto difficile far lavorare un gruppo di consulenti con queste metodologie (per esempio ho notato che molte volte tra consulenti si fa fatica a chiedere un aiuto: si ha paura molte volte che la richiesta di aiuto venga vista come fattore negativo). Altre volte la condivisione di conoscenza è molto difficoltosa: alcune persone hanno paura di condividere tecniche o conoscenza per continuare ad essere indispensabile ai fini del progetto. Quest’ultime affermazioni sono molto significative per soddisfare a pieno un requisito nell’utilizzo di queste metodologie: IL CORAGGIO.
  • Livello del team: Anche il livello del team ha una rilevanza non meno importante sulla scelta. Il livelo di competenza e conoscenza deve essere per il 70% del team comunque. Non possiamo avere due marce differenti per lavorare. Anche se è vero che se il team ha una disposizione propositiva esso può avere anche due ritmi diversi e chi ha un livello maggiore aiuterà (anche implicitamente) gli altri a crescere.
  • Conoscenze della metodologia: è importante che almeno la maggior parte del team sia consapevole su cosa vuol dire agile e su come si lavora. E che abbia avuto almeno una minima esperienza di lavorazione su questo. Partire senza queste basi è molto difficile portare al completamento un progetto.
  • Formazione: In un team nuovo ho tempo di effetturare della formazione sulle metodologie prima di iniziare? Se la risposta è negativa allora la scelta è da analizzare meglio: Come detto, devo avere almeno una parte del team che abbia avuto esperienza o almeno conosca queste metodologie. Utilizzare senza una base è pericoloso per la riuscita del progetto: Possono essere utilizzate in maniera non corretta e possono fare perdere tempo. Inoltre devo mettere in conto che durante il progetto ci sara’ anche sessioni di apprendimento. Se posso fare questo allora posso iniziare a lavorare in agile.
  • Budget: Un budget limitato (sia di tempo che di denaro) implica un’analisi delicata per la scelta di queste metodologie. Il loro utilizzo, la maggior parte delle volte, porta ad aumenti di tempo e di costi.
  • Cliente: Il cliente, essendo il destinatario dello sviluppo, ha necessità di entrare nel progetto in termini di comprensione dello stesso. Prima di tutto bisogna far capire al cliente quali sono i benefici della scelta. Questo è molto complesso in contesti dove il risparmio è condizione imprenscindibile. Una durata maggiore e costi diversi non sempre vengono apprezzati, anche se in cambio si ha un progetto robusto, un progetto testato. Se il cliente vuole tutto e subito allora non è possibile nemmeno prendere in cosiderazione la metodologia.
  • Struttura aziendale: Anche la struttura aziendale può essere influente. Siamo sicuri che i nostri manager, i nostri pm e addirittura l’organizzanzione anziendale siano in grado di poterci garantire serenità nel lavoro in agile. Le frasi “deve essere pronto per ieri” o “il più presto possibile” non esistono con queste metodologie (anche se secondo me non devono mai esistere). Una metedologia di questo tipo può solo danneggiare la serenità degli sviluppatori in queste situazioni.

Perchè le scelgo e perchè non le scelgo… che dilemma!

Il paragrafo precedente dovrebbe rispondere a queste due domande ma molte volte, anche se si hanno a disposizione tutti i pezzi del puzzle per prendere una decisione, rispondere può apparire ancora difficile.
Quando sono io a decidere, cerco prima di tutto di capire quale team ho a disposizione. Può succedere che per un progetto viene chiesto di usare Agile, con carta bianca, ma la risposta è negativa e quindi, si sceglie di non usarle. Perchè? Perchè il progetto ed il team non sempre sono adatti. E questo capita quando gli sviluppatori si preoccupano più della lavagna e dei post-it (o dello strumento software) che del progetto stesso. Ma non solo, anche quando il team non ha una cultura tale da poter seguire le metodologie; nessuno le conosce profondamente o nessuno le ha mai utilizzate prima. Formare i PM, il team e cercare un PO adatto risulterebbe, di conseguenza, troppo dispendioso e dispersivo per il progetto. Risultato, non c’è il tempo. Se poi aggiungiamo che in molti casi il meeting giornaliero è utilizzato come momento di ritrovo e non come sincronizzazione, il progetto ne risentirà senz’altro.

Troviamo un compromesso

Anche se succedono cose come quelle appena descritte, quello che cerco di fare sempre è trovare un compromesso. Le agile methodologies sono formate da un’insieme di leggi e di processi. Anzi alcune volte utilizzo queste due parole durante la formazione per non spaventare le persone con paroloni che vogliono dire tutto e niente.
Utilizzare processi e leggi è forse la cosa più complessa e molte volte invece di portare benefici determinano effetti negativi sul progetto. In contesti disorganizzati inserire un nuovo piccolo processo, o una nuova piccola legge può portare effetti positivi oltre che a formare le persone. E quindi a volte è meglio affrontare un cambiamento strutturale del processo di sviluppo step by step, per fare in modo di non spaventare l’organizzazione in essere.
Quello che faccio è cercare di utilizzare sempre il meglio di ogni metodologia:
Facciamo un altro esempio: parliamo di un cliente il cui problema principale è la comunicazione. L’obbiettivo è applicare una metodologia in un team in cui appunto, la comunicazione è un po’ trascurata. A causa della mancanza di conoscenza da parte del team delle metodologie agili, si può cercare di introdurle poco alla volta evitando di entrare a “gamba tesa”. Quello che potremmo fare è provare a creare la comunicazione prima di tutto, con il team, introducendo i morning meeting; Questo molto spesso ha risposta positiva, e quindi apre lo spiraglio per l’introduzione di una nuova figura: il product owner (P.O.) che cerca di intermediare il business con lo sviluppo. Con questi primi passi si riesce a far comunicare gli elementi del team tra di loro (Adesso almeno sannno cosa stanno facendo) e si crea un muro di protezione tra le richieste del businness e quelle del team. In questo modo si evita che chiunque entri in ufficio chieda modifiche fuori controllo, nuove implementazioni agli sviluppatori. Tuttavia, chiunque avesse qualcosa da dire deve passare sempre dal P.O.
Finalmente il team inizia a comunicare. Il passo successivo può essere fatto sulla parte organizzativa. Immaginiamo ora che il team approcci alla gestione dei task nei modi seguenti:
• tramite unico file di testo contentnete una lista infinita di requisiti (molti anche vecchi di anni)
• a voce (richiesta ad una risorsa casuale on demand)
Queste tipologie di lavoro creano due problemi molto importanti:

  • Il progetto non ha nè inizio nè fine: mancano deploy programmati. Il deploy è on demand, a seconda del bug e/o della nuova implementazione; lo sviluppatore non vede mai una luce in fondo al tunnel e il progetto è sempre un code and fix. Il businees deve anche aspettare mesi per avere un deploy verificabile o che sia degno del nome oppure richiede un deploy senza testare per implementazioni che non sempre sono così utili.
  • Manca anche uno storico delle richieste: come succede sempre quando ci sono problemi tutti negano il fatto ed inoltre queste richieste non vengono mai testate per farne subito deploy. Non rimane traccia ordinata di quello che è successo e reperire la pipeline degli eventi è veramente dura.

Per iniziare a risolvere questi problemi, con l’aiuto del P.O. prima di tutto vi è da scremare tutti i requisiti meno utili e quelli non più validi, poi con il business si decide di tagliare i contatti diretti con il team (tra business e team). Ogni comunicazione di richiesta o bug deve essere fatta al P.O.
Infine si inizia a dividere i task in “sprint” e, a seconda della priorità, se ne sceglie un gruppo e si programma un deploy ogni fine sprint. Ogni task , in questo modo, viene analizzato al fine di ridurre al massimo regressioni e bug. In questo modo lo sviluppatore non viene inoltre mai appesantito, e sa cosa fare lavorando sereno.
Durante queste fasi il team continuerà a sviluppare tranquillamente seguendo quello che ha sempre fatto. In questo periodo il team si forma, inizia a lavorare insieme, e si organizza.
In una delle mie esperienze personali però, procedendo secondo quanto ho descritto nell’esempio, mi è capitato qualcosa che non mi sarei aspettato. Mi è successo infatti che gli sviluppatori si sono aiutati per portare a compimento lo sprint. A questo punto erano pronti per un’ulteriore passo: TDD e pair programming. Con non pochi scogli, il team ha iniziato a pensare ai test e alla interazione. Ancora non lavorano in agile perchè mancano delle figure importanti, ma almeno hanno scelto di utilizzare il buon senso e di fare piccoli passi per poi arrivare un giorno ad avere una serie di automatismi ed una consapevolezza sul concetto di “lavoro organizzato”.

Conclusioni

Ho cercato di scrivere cosa penso delle agile methodologies visto che sono ormai passati sei anni dalla prima volta che le ho incontrate ed utilizzate.
Molte volte occorre utilizzare il buon senso e capire se è meglio utilizzare una certa metodologia o un certo strumento oppure continuare a lavorare come si è sempre fatto.
L’introduzione di un diverso modus operandi può portare effetti collaterali negativi piuttosto che benefici. Occorre quindi pensare bene se azienda, team e cliente sono pronti a lavorare a determinate condizioni al fine di portare benefici nel medio/lungo periodo.
La scelta all’inizio del progetto deve essere presa usando il buon senso prendendo in considerazione ogni contesto. Non basta studiare un testo o leggere libri. L’azienda stessa potrebbe aver bisogno di utilizzare Agile per organizzare prima tutti i processi e pensare di partire da un progetto per farlo non è a mio avviso il miglior modo possibile.

Infine le agile methodologies vengono considerate come condizione necessaria e sufficiente per portare a termine e con SUCCESSO un progetto. Purtroppo questo non è corretto. Si possono seguire tutte le pratiche agili (essere il “guru” delle metodologie) e FALLIRE. Il fallimento può essere dovuto alle condizioni ereditate del team e dall’azienda. Affinchè un progetto abbia successo, è necessario che tutti remino nella stessa direzione e che in aggiunta ogni team abbia attributi fondamentali, come ad esempio le competenze degli sviluppatori, la conoscenza del business da parte del P.O., ecc.
Analogamente un progetto software può avere successo anche senza usare nessuna pratica agile. Se tutto va bene in questo modo, sono il primo a dire “continuate in questa direzione, magari aggiungendo qualche processo che possa giovare e non distruggere il progetto”. Non scegliete di cambiare il proprio modus operandi per un capriccio o per una moda, si rischierà di portare solo problemi.

CRM 2011 – How to get the current user from within a dialog

2007_microsoft_dynamics_crmI needed to get the current user in a dialog but CRM 2011 Dialogs do not provide any easy way to access the currently logged in user’s information. To get this information I found two ways (I don’t know if they are the unique ways.. but run!!):

1. USE ENTITY

The first way was to create a new instance if an entity: I created a new entity, the owner field will contain the currently logged in user.
The steps I followed:

  • Log into CRM and create a new entity, call it new_CurrentDialogUser. You do not have to add any new fields.
  • Open your existing dialog for editing.
  • From the Dialog editor, the first thing to do is create an instance of new_CurrentDialogUser.
    • Create a new stage, positioned at the very beginning of the dialog.
    • Click ‘Add Step’ and select ‘Create Record’.
    • Choose the type to be new_CurrentDialogUser.
    • Click on properties. Notice the owner field is presented. Do not populate this field. Instead, when the ‘Create Record’ step executes, it will default the owner to the currently logged in user.
  • Once the ‘Create Record’ steps executes in your dialog, you have the ability to reference this step from throughout the rest of your dialog, just as if you were referencing the current record that is related to your dialog.
  • In my case, I use an ‘Assign Value’ step to store the owner of the newly created new_ CurrentDialogUser to a local variable, called CurrentUser.
    • Click ‘Add Step’ and choose ‘assign value details.’
    • In the ‘Look For’, select from the local values, the choice ‘Create (Current Dialog User)’.
  • Finally, once my am done using the current user, I perform an ‘UpdateStatus’ step, as a means to
    deactivate the dynamically created new_CurrentDialogUser instance.
    • Add step, select ‘Change Status’
    • Select the ‘Create (Current Dialog user)’.
    • Change the status to ‘Inactive’.

2. USE ACTIVITY WORKFLOW

I created a new workflow activity with Output parameters. This output parameters are all parameters that I needed in my dialog. For example I have the Current User, etc. In following the piece of code:

// <copyright file="ParametersActivity.cs" company="">
// Copyright (c) 2014 All Rights Reserved
// </copyright>
// <author>Alessandro Graps</author>
// <date>6/25/2014 8:34:52 AM</date>
// <summary>Implements the ParametersActivity Workflow Activity.</summary>

using ActivityRecording.Entities;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;

namespace Winvs.Next.ActivityRecording.Workflow
{
    using System;
    using System.Activities;
    using System.ServiceModel;
    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Sdk.Workflow;

    public sealed class ParametersActivity : CodeActivity
    {
        [Output("Current User")]
        [ReferenceTarget("systemuser")]
        public OutArgument<EntityReference> CurrentUser { get; set; }

        [Output("Current Time Mapping")]
        [ReferenceTarget(winvs_unitconfiguration.EntityLogicalName)]
        public OutArgument<EntityReference> CurrentTimeMapping { get; set; }

        protected override void Execute(CodeActivityContext context)
        {
            IWorkflowContext workflowContext = context.GetExtension<IWorkflowContext>();

            if (workflowContext == null)
            {
                throw new InvalidPluginExecutionException("Failed to retrieve workflow context.");
            }

            if (workflowContext.Depth > 1)
                return;
            
            CurrentUser.Set(context, new EntityReference("systemuser", workflowContext.InitiatingUserId));


            IOrganizationServiceFactory serviceFactory = context.GetExtension<IOrganizationServiceFactory>();
            IOrganizationService service = serviceFactory.CreateOrganizationService(workflowContext.UserId);

            winvs_unitconfiguration winvsUnitconfiguration = GetConfigurationEntityUnitGroup(service);

            CurrentTimeMapping.Set(context, new EntityReference("winvs_unitconfiguration", winvsUnitconfiguration.Id));

        }

        public winvs_unitconfiguration GetConfigurationEntityUnitGroup(IOrganizationService service)
        {
            string entityName = "winvs_unitconfiguration";

            // Get the metadata for the currently list's entity
            // This metadata is used to create a "Property Descriptor Collection"

            QueryExpression qe = new QueryExpression();
            qe.ColumnSet = new ColumnSet(true);
            qe.EntityName = entityName;

            RetrieveMultipleRequest request = new RetrieveMultipleRequest();
            request.Query = qe;
            RetrieveMultipleResponse response = (RetrieveMultipleResponse)service.Execute(request);


            if (response.EntityCollection.Entities.Count == 0)
                throw new Exception(string.Format("The configuration entity is empty."));

            foreach (Entity unitConfigurationEntity in response.EntityCollection.Entities)
            {
                winvs_unitconfiguration winvsUnitconfiguration = unitConfigurationEntity.ToEntity<winvs_unitconfiguration>();
                return winvsUnitconfiguration;
                break;
            }

            throw new Exception(string.Format("The configuration entity is empty."));
        }

    }
}

This is a fast way to get all information that I don’t have in dialogs.