jueves, 2 de octubre de 2014

Fusion Charts en Cuadro de Mandos Interactivo de SageCRM (II)



Ya vimos en otro post como crear gráficos más avanzados dentro de nuestro cuadro de mandos mediante desarrollo y la librería de FusionCharts.
En esta ocasión, vamos a ver cómo crear gráficos más complejos (comparativos multibarra, con drill-down)

Se muestra la comparativa de la facturación de X3 entre el año anterior y el año actual de las facturas de las empresas que tenga acceso el usuario. Solamente se tendrán en cuenta las facturas de las empresas que el usuario tenga acceso a visualizar.



Para ello primero hemos tenido que crear una vista que una las tablas de Facturas de Sage X3 contra las tablas de empresa del CRM (relacionado por el campo código de cliente). En nuestro caso la hemos llamado “vZSINVOICED”

En nuestra página asp, que llamaremos desde nuestro cuadro de mandos, hemos añadido la llamada a la librería de FusionCharts.js, y hemos insertado un script que se actualiza en tiempo de ejecución mediante código incrustado asp.



El código que insertamos dentro del script, nos generará el XML que acabaremos insertando dentro del objeto del fusionchart 


var chart_Raul = new FusionCharts("../../FusionCharts/MSColumn3D.swf", "Raul", "100%", 300, "0", "1");
chart_Raul.setDataXML("<%=strXML%>");                     
chart_Raul.render("RaulDiv");   


El XML que se genera acabará teniendo este aspecto:

<chart caption='Comparativa Facturaci&#243;n A&#241;o Anterior-A&#241;o Actual' XAxisName='Meses'   animation='1' subcaption='(Pedidos de X3)' formatNumberScale='0' numberPrefix='€' showValues='0' seriesNameInToolTip='1'>
  <categories>
    <category label='Enero'/>
    <category label='Febrero'/>
    <category label='Marzo'/>
    <category label='Abril'/>
    <category label='Mayo'/>
    <category label='Junio'/>
    <category label='Julio'/>
    <category label='Agosto'/>
    <category label='Setiembre'/>
    <category label='Octubre'/>
    <category label='Noviembre'/>
    <category label='Diciembre'/>
  </categories>
  <dataset seriesname='2012'>
    <set value='864973.35' link='javaScript%3AupdateCharts%281%2C2012%2C107821029734360%29' />
    <set value='489565.13' link='javaScript%3AupdateCharts%282%2C2012%2C107821029734360%29' />
    <set value='617593.84' link='javaScript%3AupdateCharts%283%2C2012%2C107821029734360%29' />
    <set value='528120.42' link='javaScript%3AupdateCharts%284%2C2012%2C107821029734360%29' />
    <set value='939954.34' link='javaScript%3AupdateCharts%285%2C2012%2C107821029734360%29' />
    <set value='550775.8' link='javaScript%3AupdateCharts%286%2C2012%2C107821029734360%29' />
    <set value='455826.34' link='javaScript%3AupdateCharts%287%2C2012%2C107821029734360%29' />
    <set value='606006.47' link='javaScript%3AupdateCharts%288%2C2012%2C107821029734360%29' />
    <set value='737192.67' link='javaScript%3AupdateCharts%289%2C2012%2C107821029734360%29' />
    <set value='1410945.52' link='javaScript%3AupdateCharts%2810%2C2012%2C107821029734360%29' />
    <set value='1157362.2' link='javaScript%3AupdateCharts%2811%2C2012%2C107821029734360%29' />
    <set value='520289.38' link='javaScript%3AupdateCharts%2812%2C2012%2C107821029734360%29' />
  </dataset>
  <dataset seriesname='2013'>
    <set value='875222.79' link='javaScript%3AupdateCharts%281%2C2013%2C107821029734360%29'/>
    <set value='1018402.67' link='javaScript%3AupdateCharts%282%2C2013%2C107821029734360%29'/>
    <set value='557521.97' link='javaScript%3AupdateCharts%283%2C2013%2C107821029734360%29'/>
    <set value='493170.65' link='javaScript%3AupdateCharts%284%2C2013%2C107821029734360%29'/>
    <set value='1470088.01' link='javaScript%3AupdateCharts%285%2C2013%2C107821029734360%29'/>
    <set value='783168.41' link='javaScript%3AupdateCharts%286%2C2013%2C107821029734360%29'/>
    <set value='763674.89' link='javaScript%3AupdateCharts%287%2C2013%2C107821029734360%29'/>
    <set value='710656.08' link='javaScript%3AupdateCharts%288%2C2013%2C107821029734360%29'/>
    <set value='1124640.67' link='javaScript%3AupdateCharts%289%2C2013%2C107821029734360%29'/>
    <set value='944214.25' link='javaScript%3AupdateCharts%2810%2C2013%2C107821029734360%29'/>
    <set value='421320.66' link='javaScript%3AupdateCharts%2811%2C2013%2C107821029734360%29'/>
    <set value='243688.52' link='javaScript%3AupdateCharts%2812%2C2013%2C107821029734360%29'/>
  </dataset>
  <styles>
    <definition>
      <style type='font' name='CaptionFont' size='15' />
      <style type='font' name='SubCaptionFont' bold='0' />
    </definition>
    <application>
      <apply toObject='caption' styles='CaptionFont' />
      <apply toObject='SubCaption' styles='SubCaptionFont' />
    </application>
  </styles>
</chart>


Para generarlo hacemos lo siguiente:

<%
                        
SID=Request.QueryString("SID")                                    
                
strXML="<chart caption='Comparativa Facturaci&#243;n A&#241;o Anterior-A&#241;o Actual' XAxisName='Meses'   animation='1' subcaption='(Facturas de X3)'  numberPrefix='€' showValues='0' seriesNameInToolTip='1'>"
                        
//Obtener Categorias (Meses)
Hoy=new Date()
MesActual=Hoy.getMonth()+1
                        
strXML= strXML + "<categories>"
for (var i=1;i<=12;i++)
{
        idmes=i+MesActual
        strXML= strXML + "<category label='" + GetMes(idmes) + "'/>"
}
strXML= strXML + "</categories>"
                                         
                        
                        
idEmpresas=ObtenerIdEmpresasAcceso(PerfilUsuario)
                        
                        
                                                  
//DATOS AÑO ANTERIOR
AnyoAnterior=Hoy.getYear()-1
AnyoAnteriorAnterior=Hoy.getYear()-2
strXML= strXML + "<dataset seriesname='Año Anterior'>"
                                                                                            
Query = eWare.CreateQueryObj("SELECT ANYO_0 AS anyo, MES_0 as mes, SUM(AMTNOTLIN_0) as total FROM vZSINVOICED WHERE ((ANYO_0=" + AnyoAnteriorAnterior + "  AND MES_0>" + MesActual + ") or (ANYO_0=" + AnyoAnterior + "  AND MES_0<=" + MesActual + "))  AND Comp_Companyid IN (" + idEmpresas + ")  GROUP BY ANYO_0,MES_0 ORDER BY ANYO_0 , MES_0", "VISTASX3");
                        
Query.SelectSql();
contadormes=MesActual                    
while (!Query.eof)
{
        if (contadormes==13)
                 contadormes=1
                                         
        mes=Query.FieldValue("mes")
        anyo=Query.FieldValue("anyo")
        total=Query.FieldValue("total")
        total=total.replace(",",".")
                                 
        //PARA ASEGURARNOS QUE SE MUESTRAN TODOS LOS MESES
        for (var cont=contadormes;cont<mes-1;cont++)
        {
                 strXML= strXML + "<set value='0' />"
                 contadormes+=1
        }
        contadormes+=1          
        strXML= strXML + "<set value='" + total + "' />"                           
        Query.NextRecord();
}
strXML= strXML + "</dataset>"
                        
//DATOS AÑO ACTUAL
AnyoActual=Hoy.getYear()
strXML= strXML + "<dataset seriesname='Año Actual'>"
                                                                                                    
Query = eWare.CreateQueryObj("SELECT ANYO_0 AS anyo, MES_0 as mes, SUM(AMTNOTLIN_0) as total FROM vZSINVOICED WHERE ((ANYO_0=" + AnyoAnterior + "  AND MES_0>" + MesActual + ") or (ANYO_0=" + AnyoActual + "  AND MES_0<=" + MesActual + "))  AND Comp_Companyid IN (" + idEmpresas + ") GROUP BY ANYO_0,MES_0 ORDER BY ANYO_0 , MES_0", "VISTASX3");
                        
Query.SelectSql();      
contadormes=MesActual            
while (!Query.eof)
{
        if (contadormes==13)
                 contadormes=1
                                         
        mes=Query.FieldValue("mes")
        anyo=Query.FieldValue("anyo")
        total=Query.FieldValue("total")
        total=total.replace(",",".")
                                 
        //PARA ASEGURARNOS QUE SE MUESTRAN TODOS LOS MESES
        for (var cont=contadormes;cont<mes-1;cont++)
        {
                 strXML= strXML + "<set value='0' />"
                 contadormes+=1
        }
        contadormes+=1                                                                             
        strXML= strXML + "<set value='" + total + "' link='" + strLink + "'/>"
        Query.NextRecord();
}
strXML= strXML + "</dataset>"
                                                  
strXML= strXML + "<styles><definition><style type='font' name='CaptionFont' size='15' /><style type='font' name='SubCaptionFont' bold='0' /></definition><application><apply toObject='caption' styles='CaptionFont' /><apply toObject='SubCaption' styles='SubCaptionFont' /></application></styles></chart>"
%>


Para hacer drill-down lo único que tenemos que hacer añadir dentro del elemento set del XML de salida, la etiqueta link , con una llamada a una función javascript pasándole por parámetro el mes y el año, que lo que hará es generar otro XML con los datos de facturación de ese mes/año. Y mostrándolos en otro chart situado en la pantalla principal.

<script type="text/javascript"> 
      
       function updateCharts(mes, anyo, SID)
       {                  
             //Get reference to chart object using Dom ID "SalesByCat"
             var chartObj = getChartFromId("chart2");           
             //Send request for XML
             chartObj.setXMLUrl("ComparativaRepMesXML.asp?SID=" + SID + "&mes=" + mes + "&anyo=" + anyo);     
             chartObj.render("Chart2Div");                
       }


       ...

       <%
       ...

       strLink = Server.URLEncode("javaScript:updateCharts(" + mes + "," + anyo + "," + SID + ")")
       strXML= strXML + "<set value='" + total + "' link='" + strLink + "'/>"

       ...

       %>
       var chart2 = new FusionCharts("../../FusionCharts/MSColumn3D.swf?ChartNoDataText=Selecciona un Mes del grafico superior", "chart2", "100%", 300, "0", "1");
       chart2.setDataXML("");                
       //Finally, render the chart.          
       chart2.render("Chart2Div");
</script>   

4 comentarios:

  1. This is in fact a wonderful post, the piece of writing has really allured me, and you have given a definite idea of this issue. Nice!!
    IT Support Limerick
    Sage Manufacturing

    ResponderEliminar
    Respuestas
    1. Thanks.
      I hope to make new posts about SageCRM in the future that also you like

      Eliminar
  2. hello Raul , can you provide the view you created in CRM for the X3 Invoice Table and the Companry Table

    ResponderEliminar
    Respuestas
    1. HiKannan

      I have a synchronization between SageX3 and SageCRM, and I have a field in SageCRM that contain the customer code (comp_codexterno)

      I have the X3 database and the CRM database in different SQL Server, but I have configured a linked server.

      I have created this view in my CRM database:
      vZSINVOICED

      SELECT ZSINVOICED.SOHNUM_0, ZSINVOICED.BPCNUM_0, ZSINVOICED.BPRNAM_0, ZSINVOICED.AMTNOTLIN_0, ZSINVOICED.REP1_0, ZSINVOICED.REP2_0, ZSINVOICED.ANYO_0, ZSINVOICED.MES_0, dbo.vCompany.Comp_Name, dbo.vCompany.Comp_CompanyId, dbo.vCompany.Comp_SecTerr, dbo.vCompany.Comp_PrimaryUserId, dbo.vCompany.Comp_CreatedBy, dbo.vCompany.Comp_ChannelID
      FROM [SAGEERP\SAGEV6].sage.X3.ZSINVOICED AS ZSINVOICED
      INNER JOIN dbo.vCompany ON ZSINVOICED.BPCNUM_0 = dbo.vCompany.comp_codexterno COLLATE Latin1_General_CI_AS


      AND it is my vZINVOICED in X3 database:
      SELECT BPC.BPCNUM_0, BP.BPRNAM_0 + ' ' + BP.BPRNAM_1 AS BPRNAM_0, SUM(SD.AMTNOTLIN_0 * S.SNS_0) AS AMTNOTLIN_0, SD.REP1_0, SD.REP2_0, YEAR(SD.INVDAT_0) AS ANYO_0, MONTH(SD.INVDAT_0) AS MES_0, SD.SOHNUM_0
      FROM IPE.BPARTNER AS BP
      LEFT OUTER JOIN IPE.BPCUSTOMER AS BPC ON BPC.BPCNUM_0 = BP.BPRNUM_0
      LEFT OUTER JOIN IPE.SINVOICE AS S ON S.BPR_0 = BPC.BPCNUM_0
      LEFT OUTER JOIN IPE.SINVOICED AS SD ON SD.NUM_0 = S.NUM_0
      WHERE (BPC.BPCNUM_0 <> 'INN') AND (S.SIVTYP_0 <> 'PRF')
      GROUP BY BPC.BPCNUM_0, BP.BPRNAM_0 + ' ' + BP.BPRNAM_1, SD.REP1_0, SD.REP2_0, YEAR(SD.INVDAT_0), MONTH(SD.INVDAT_0), SD.SOHNUM_0


      Eliminar