lunes, 29 de septiembre de 2014

SageCRM - Desplegables encadenados con SDATA



Con este ejemplo voy a mostrar cómo gracias a la nueva API de Cliente y el método SDATA podemos desarrollar campos desplegable encadenados, es decir, crear un campo desplegable que muestre unos valores dependiendo del valor seleccionado en otro campo.



Esta funcionalidad antiguamente ya la podíamos obtener,  pero en “hard-code” mediante javascript, ya que podíamos escribir directamente los valores del elemento SELECT, dependiendo del valor seleccionado en otro desplegable. Esto tenía el principal problema que era muy poco mantenible, ya que si se añadían nuevos valores al segundo desplegable, se tenía que volver a modificar el script del desarrollo.

Con esta nueva solución no tendremos este problema, ya que mediante SDATA obtenemos los valores que necesitamos mostrar “directamente” de la base de datos, y los escribiremos dentro del objeto SELECT dependiendo del valor que hayamos seleccionado en el primer desplegable.
Para nuestro ejemplo hemos creado dos campos (“tipo de caso” y “subtipo de caso”).


Se ha creado un valor desplegable “Tipo de Caso”, que según el tipo que se seleccione se muestra otro valor dentro del campo “SubTipo de Caso”
Valores de Tipo de Caso:

  •     ADM
  •     SAL
  •     SAT


Los Subtipos de Caso, se han definido con una codificación que siempre empieza con el tipo de caso al que hace referencia. Por ejemplo:
  • ADM-01  (No Conformidad de envío de material a Cliente)
  • ADM-02 (No Conformidad de recepción material de Proveedor)
  • SAL-01 (Proyecto Llave en Mano)
  • SAL-02 (Servicio Analítico Acreditado)
  • SAT-01 (Consultas Técnicas)
  • SAT-02 (Demostraciones de Equipos)

De esta manera conseguimos poder mostrar dinámicamente los valores del campo subtipo, según el valor seleccionado dentro del campo Tipo. (Esto lo haremos mediante la Client Side API de CRM y el método SDATA)
Para ello hemos tenido que habilitar lo siguiente:
1.     Habilitar SData para la tabla CUSTOM_CAPTIONS
UPDATE    Custom_Tables SET Bord_Hidden = NULL, Bord_SDataAccess = 'Y' WHERE (Bord_Caption = 'custom_captions')

2.     También hacemos que la entidad no sea Hidden, para poder acceder a la entidad desde Administración --> Personalización --> Entidades Secundarias (custom_captions)

3.     Desde Administración --> Personalización --> Custom_Captions, lo único que tenemos que hacer es verificar que el acceso externo al SDATA esté en Sí,  y editar la columna capt_captionid (id de la tabla) para que se registre dentro de los metadatos de SageCRM

4.     Reiniciar IIS/Tomcat para que sdata registre esta nueva entidad.
       Verificar que sdata reconoce nuestra nueva entidad, mediante la url:
<xs:element name="custom_captions" sme:label="Custom_Captions" type="tns:custom_captions--type" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false" sme:canPageIndex="true" sme:canPageNext="true" sme:canPagePrevious="true" sme:pluralName="custom_captionscollection" sme:role="resourceKind" sme:canSearch="false"/>
<xs:complexType name="custom_captions--type">
<xs:all>
<xs:element name="capt_order" sme:label="Orden de las etiquetas" type="xs:integer" sme:canFilter="true" sme:isReadOnly="false" nillable="true" sme:canSort="true" sme:isLocalized="true" sme:isCollection="false" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false"/>
<xs:element name="capt_cs" sme:label="Traducción al chino" type="xs:string" sme:canFilter="true" sme:isReadOnly="false" nillable="true" sme:canSort="true" sme:isLocalized="true" sme:isCollection="false" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false"/>
<xs:element name="capt_familytype" sme:label="Tipo de familia de etiquetas" type="xs:string" sme:canFilter="true" sme:isReadOnly="false" nillable="true" sme:canSort="true" sme:isLocalized="true" sme:isCollection="false" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false"/>
<xs:element name="capt_family" sme:label="Familia de etiquetas" type="xs:string" sme:canFilter="true" sme:isReadOnly="false" nillable="true" sme:canSort="true" sme:isLocalized="true" sme:isCollection="false" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false"/>
<xs:element name="capt_context" sme:label="Contexto de la etiqueta" type="xs:string" sme:canFilter="true" sme:isReadOnly="false" nillable="true" sme:canSort="true" sme:isLocalized="true" sme:isCollection="false" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false"/>
<xs:element name="capt_uk" sme:label="Traducción al inglés de R.U." type="xs:string" sme:canFilter="true" sme:isReadOnly="false" nillable="true" sme:canSort="true" sme:isLocalized="true" sme:isCollection="false" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false"/>
<xs:element name="capt_de" sme:label="Traducción al alemán" type="xs:string" sme:canFilter="true" sme:isReadOnly="false" nillable="true" sme:canSort="true" sme:isLocalized="true" sme:isCollection="false" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false"/>
<xs:element name="capt_fr" sme:label="Traducción al francés" type="xs:string" sme:canFilter="true" sme:isReadOnly="false" nillable="true" sme:canSort="true" sme:isLocalized="true" sme:isCollection="false" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false"/>
<xs:element name="capt_es" sme:label="Traducción al español" type="xs:string" sme:canFilter="true" sme:isReadOnly="false" nillable="true" sme:canSort="true" sme:isLocalized="true" sme:isCollection="false" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false"/>
<xs:element name="capt_jp" sme:label="Traducción al Japonés" type="xs:string" sme:canFilter="true" sme:isReadOnly="false" nillable="true" sme:canSort="true" sme:isLocalized="true" sme:isCollection="false" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false"/>
<xs:element name="capt_integrationid" sme:label="Id de integración" type="xs:integer" sme:canFilter="true" sme:isReadOnly="false" nillable="true" sme:canSort="true" sme:isLocalized="true" sme:isCollection="false" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false"/>
<xs:element name="capt_us" sme:label="Traducción al inglés de EE.UU." type="xs:string" sme:canFilter="true" sme:isReadOnly="false" nillable="true" sme:canSort="true" sme:isLocalized="true" sme:isCollection="false" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false"/>
<xs:element name="capt_du" sme:label="Traducción al holandés" type="xs:string" sme:canFilter="true" sme:isReadOnly="false" nillable="true" sme:canSort="true" sme:isLocalized="true" sme:isCollection="false" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false"/>
<xs:element name="capt_captionid" sme:label="Id de Etiqueta" type="xs:integer" sme:canFilter="true" sme:isReadOnly="false" nillable="true" sme:canSort="true" sme:isLocalized="true" sme:isCollection="false" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false"/>
<xs:element name="capt_code" sme:label="Código de etiqueta" type="xs:string" sme:canFilter="true" sme:isReadOnly="false" nillable="true" sme:canSort="true" sme:isLocalized="true" sme:isCollection="false" sme:canGet="true" sme:canPost="false" sme:canPut="false" sme:canDelete="false"/>
</xs:all>
</xs:complexType>



5.     Una vez ya tenemos la entidad Custom_Captions dentro de sdata, ya podemos crear el script mediante la API Cliente de SageCRM, que nos permitirá, en el momento que cambiemos el valor del campo “Tipo de Caso”, obtener mediante la consulta GET de SData contra la tabla custom_captions, los valores que puede mostrar dentro del campo “SubTipo de Caso”

Script de modificación del campo “Tipo de Caso”:
ObtenerSubTipo(this.value)

Script de contenido personalizado
<script>


var successCaption = function (crmRecord) {
        valores="<SELECT class=EDIT size=1 name='case_subtipo'>"
        $.each(crmRecord,function(index){
                 captcode=crmRecord[index].capt_code;
                 captes=crmRecord[index].capt_es;
                 valores=valores + "<OPTION Value='" + captcode + "'>" + captes + "</OPTION>"
        });
        valores=valores + "<OPTION Value='' SELECTED>--Ninguno--</OPTION></SELECT>"
        $("#_Datacase_subtipo").html(valores);
}

function ObtenerSubTipo(tipocaso)
{

        crm.sdata({             
           entity: "custom_captions",
           where: "capt_family = 'case_subtipo' and left(capt_code,3) = '" + tipocaso + "'",
           success: successCaption
        });
                
}

</script>




5 comentarios:

  1. Great article, Thanks for sharing such a useful and informative post.
    IT Support Limerick

    ResponderEliminar
  2. doesnt work with the code in the custom content, have you missed putting the complete code?

    ResponderEliminar
    Respuestas
    1. Hi Kannan

      the code is correct. I have exactly this code in my custom content and it's working correctly.

      As I explain in this post,
      Make sure you have enabled the table "custom_captions" for SDATA and edited the field "capt_captionid"
      And verify in this url "http://[servidor]/sdata/crmj/sagecrm/-/$schema" that capt_captionid exist


      Eliminar
  3. Hello Raul, I have the captionid field in the SDATA output, the issue is i am not sure if this code is exactly in your onchange of case_type field Get Subtype (this value)

    ResponderEliminar
    Respuestas
    1. In my example I have 2 fields (case_type and case_subtipo)
      I need put the script in the "onchange script" of case_type:
      ObtenerSubTipo(this.value)
      So, when I change a value of my case_type, automaticly, the values of case_subtype will be changed.

      The definition of my function (ObtenerSubTipo) are in the custom content script

      Eliminar