21 febrero 2013

Application Ribbon

- La ribbon de aplicaciones contiene los tabs y grupos de botones comunes a todas las entidades en CRM


- Si tenemos que personalizar el despliegue de alguna de sus secciones o botones debemos tener en cuenta que además de las reglas custom que incluyamos, estos ya tienen además las suyas propias, con lo que debemos añadir en lugar de sobrescribir las propiedades de display, enable y custom actions

- En este ejemplo vamos a incluir una DisplayRule para el botón Búsqueda Avanzada

- El primer paso será crear una solución que incluya la ribbon de aplicaciones y exportarla



- El xml de customizaciones es mostrado a continuación

<ImportExportXml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Entities></Entities>
  <Roles></Roles>
  <Workflows></Workflows>
  <FieldSecurityProfiles></FieldSecurityProfiles>
  <Templates />
  <RibbonDiffXml>
    <CustomActions />
    <Templates>
      <RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>
    </Templates>
    <CommandDefinitions />
    <RuleDefinitions>
      <TabDisplayRules />
      <DisplayRules />
      <EnableRules />
    </RuleDefinitions>
    <LocLabels />
  </RibbonDiffXml>
  <EntityMaps />
  <EntityRelationships />
  <OrganizationSettings />
  <optionsets />
  <Languages>
    <Language>3082</Language>
  </Languages>
</ImportExportXml>


- Para implementar el nuevo despliegue del botón Advanced Find, haremos uso del recurso de SDK applicationribbon.xml, y haremos una búsqueda para encontrar el valor del atributo Command de este botón, en este caso Mscrm.OpenGridAdvancedFind

- Conociendo el Command que localiza en la ribbon nuestro botón, implementaremos la siguiente CommandDefinition en su sección correspondiente CommandDefinitions

    <CommandDefinitions>
      <CommandDefinition Id="Mscrm.OpenGridAdvancedFind">
        <EnableRules/>
        <DisplayRules>
          <DisplayRule Id="Mscrm.OpenGridAdvancedFind.Display" />
        </DisplayRules>
        <Actions>
          <JavaScriptFunction FunctionName="Mscrm.RibbonActions.openAdvancedFind" 
             Library="/_static/_common/scripts/RibbonActions.js">
            <CrmParameter Value="SelectedControl" />
          </JavaScriptFunction>
        </Actions>
      </CommandDefinition>
    </CommandDefinitions>


- Observe que en nuestra customización hemos vuelto a incluir el tag Actions definido en el archivo de SDK applicationribbon.xml

- La implementación de la regla de display Mscrm.OpenGridAdvancedFind.Display es la siguiente

    <DisplayRule Id="Mscrm.OpenGridAdvancedFind.Display">          
      <EntityRule AppliesTo="SelectedEntity" 
           Context="HomePageGrid" EntityName="contact" />
    </DisplayRule>


- Guardaremos los cambios e importaremos la solución customizada, y publicaremos los resultados



- El resultado de este despliegue es que el botón Búsqueda Avanzada se muestra sólo para la entidad seleccionada Contacto
Puede consultar una lista completa de las DisplayRules en el sitio oficial de Microsoft

Desde Innovar Tecnologías esperamos que este documento les sea de ayuda en su desarrollo

08 febrero 2013

Secure Configuration en Plugins

- En CRM es posible enviar información parametrizada a un plugin para ser utilizada durante su ejecución, haciendo uso de los espacios Secure y Unsecure en la configuración durante el registro del plugin

- En este ejemplo vamos a desarrollar un plugin que envíe un email al Contacto principal de una cuenta cuando esta es modificada

- Para ello implementaremos el constructor del plugin que incluye los espaciós de configuración como parámetros

public class Plugin : IPlugin
{
    private IPluginExecutionContext context;
    private IOrganizationServiceFactory factory;
    private IOrganizationService service;
    protected string TextoEmail;

    public Plugin(string unsecureConfig, string secureConfig)
    {
        TextoEmail = secureConfig;
    }

    public void Execute(IServiceProvider serviceProvider)
    {
        context = (IPluginExecutionContext)
           serviceProvider.GetService(typeof(IPluginExecutionContext));
        factory = (IOrganizationServiceFactory)
           serviceProvider.GetService(typeof(IOrganizationServiceFactory));
        service = factory.CreateOrganizationService(context.UserId);

        try
        {
            if (context.PostEntityImages["account"].Contains("primarycontactid"))
            {
                Guid primaryContactId = ((EntityReference)
                   context.PostEntityImages["account"]["primarycontactid"]).Id;

                Email email = new Email();

                ActivityParty fromParty = new ActivityParty();
                fromParty.PartyId = 
                   new EntityReference(SystemUser.EntityLogicalName, context.UserId);
                ActivityParty toParty = new ActivityParty();
                toParty.PartyId = 
                   new EntityReference(Contact.EntityLogicalName, primaryContactId);

                email.From = new ActivityParty[] { fromParty };
                email.To = new ActivityParty[] { toParty };
                email.Description = TextoEmail;
                email.Subject = "Su cuenta " + 
                   context.PostEntityImages["account"]["name"].ToString() + 
                   " ha sido modificada ";

                Guid emailId = service.Create(email);

                SendEmailRequest sendReq = new SendEmailRequest();
                sendReq.IssueSend = true;
                sendReq.TrackingToken = "";
                sendReq.EmailId = emailId;

                service.Execute(sendReq);
            }
        }
        catch (InvalidPluginExecutionException)
        {
            throw;
        }
        catch (Exception ex)
        {
            throw new InvalidPluginExecutionException(ex.Message);
        }
    }
}


- Al realizar el registro del plugin incluiremos datos de Configuración Segura, como se indica a continuación



- Para el desarrollo de este ejemplo registraremos una PostEntityImage con los dos siguientes atributos



- El resultado de una actualización y la ejecución del plugin es el siguiente





- Con el uso de esta configuración en el plugin conseguimos dinamizar los valores de los parámetros durante la ejecución del plugin

Desde Innovar Tecnologías esperamos que este documento les sea de ayuda en su desarrollo


http://www.fotografodebodasbarcelonafg.com