Cómo generar un gráfico de pastel de forma dinámica en Odoo
Imprime tu gráfico en un reporte Qweb
20 diciembre, 2020 por
Cómo generar un gráfico de pastel de forma dinámica en Odoo
Yen Martínez
| 3 Comentarios

Si la vista Gráfico de Odoo no es suficiente para cumplir tus requerimientos (tal vez porque necesitas procesar a tu manera los datos antes de dibujar el gráfico, o porque obtienes los datos de una fuente externa), aquí te dejo una forma de generar tu 'Pie Chart' y además imprimirlo luego en un documento PDF.
Te dejo una lista de instrucciones de los principales pasos y también podrás descargar el módulo de ejemplo (Estaremos utilizando la librería matplotlib).

1. Instala la librería matplotlib

            sudo pip install matplotlib

2. Importa image y pyplot. Tu .py lucirá así:

________________________________________________________________________________
my_model.py
________________________________________________________________________________

# -*- coding: utf-8 -*-
from odoo import api, fields, models
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from odoo.exceptions import UserError
from odoo.modules.module import get_module_path

#Crearemos un modelo my.model que contenga una descripción y un monto, que luego utilizaremos como datos de entrada para nuestro gráfico.

class MyModel(models.Model):
   _name = "my.model"
   _description = "My model example"

   name = fields.Char('Name')
   amount = fields.Float('Amount')

   def draw_pie_chart(self, labels, quantity):
       colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral', 'purple']
       plt.pie(quantity, colors=colors, autopct='%1.1f%%',
               shadow=False, startangle=90, labeldistance=1.1)
       plt.axis('equal')
       plt.legend(labels=labels)
       path = get_module_path('pie_chart_print')
       plt.savefig(path + '/static/src/img/pie.png', bbox_inches='tight')
       img = mpimg.imread(path + '/static/src/img/pie.png')
       plt.close() 
       return img

   @api.multi
   def get_chart_print(self):
       for record in self:
           data = {}
           # Build your own data lists
           list_data = self.env['my.model'].search([])
           if list_data:
               pie_chart_labels = list_data.mapped(
                   lambda x: x.name)
               pie_chart_quantities = list_data.mapped(lambda x: x.amount)
               pie = self.draw_pie_chart(pie_chart_labels, pie_chart_quantities)
               # The rest of the data in your report
               # data.update()
               return self.env.ref('pie_chart_print.report_pie_chart_pdf').report_action(self,                                         data=data)
           else:
               raise UserError('Insert a few records')

3. Dibujaremos una vista para registrar nuestros datos, por lo que nuestro .xml será como sigue: 

______________________________________________________________________________
my_model.xml
______________________________________________________________________________

<?xml version="1.0" encoding="utf-8"?>

<odoo>

   <record id="mymodel_report_form_view" model="ir.ui.view">

       <field name="name">My Model view form</field>

       <field name="model">my.model</field>

       <field name="type">form</field>

       <field name="arch" type="xml">

           <form>

               <header>

                   <button name="get_chart_print" type="object" string="Print Pie Chart"

                           class="oe_highlight fa fa-print"/>

               </header>

               <sheet name="My model">

                   <group colspan="4">

                       <group col="2">

                           <field name="name"/>

                       </group>

                       <group col="2">

                           <field name="amount"/>

                       </group>

                   </group>

               </sheet>

           </form>

       </field>

   </record>


   <record id="my_model_view_tree" model="ir.ui.view">

       <field name="name">my_model_view_tree</field>

       <field name="model">my.model</field>

       <field name="arch" type="xml">

           <tree string="My model Tree">

               <field name="name"/>

               <field name="amount"/>

           </tree>

       </field>

   </record>


   <record id="my_model_action" model="ir.actions.act_window">

       <field name="name">My model action</field>

       <field name="type">ir.actions.act_window</field>

       <field name="res_model">my.model</field>

       <field name="view_mode">tree,form</field>

   </record>


   <!-- This Menu Item will appear in the Upper bar, That's why It needs NO parent or action -->

   <menuitem id="mymodel_root" name="My Model Sample" sequence="1"                                                         groups="base.group_user"/>


   <!-- This Menu Item must have a parent and an action -->

   <menuitem id="mymodel_menu" name="My model info" parent="mymodel_root"                         action="my_model_action" sequence="1"/>

</odoo>

4.    A continuación dibujaremos nuestra plantilla de reporte para mostrar nuestro gráfico.

_______________________________________________________________________________

pie_chart_report_template.xml
_______________________________________________________________________________

<?xml version="1.0" encoding="utf-8"?>

<odoo>

  <template id="pie_chart_report_template">

      <t t-call="web.html_container">

          <t t-call="web.external_layout">

              <div class="page" style="font-size: 12px !Important;">

                  <br/>

                  <div class="row">

                      <div class="col-6">

                          <p><span>PIE CHART EXAMPLE</span></p>

                          <img src="/pie_chart_print/static/src/img/pie.png"

                               style="align:left; width:360px;height:260px;"/>

                      </div>

                   </div>

              </div>

          </t>

      </t>

  </template>


   <report

           id="report_pie_chart_pdf"

           string="Pie chart report"

           model="my.model"

           report_type="qweb-pdf"

           file="pie_chart_print.pie_chart_report_template"

           name="pie_chart_print.pie_chart_report_template"

           menu="False"

   />

</odoo>

5. Una vez conformado el módulo según la estructura 'Odoo' (Ver Estructura de un módulo en Odoo), adiciona el módulo a tu addons_path e instálalo en tu bd.

Podrás acceder al módulo de ejemplo en esta dirección: Ejemplo PieChartReport

Luego de ingresar varios registros, en el formulario presionaremos el botón Imprimir Gráfico de pastel y este será nuestro resultado:


Nota
Tendrás que proveer una fuente de colores dinámica para que cada registro tome colores diferentes sin importar la cantidad de registros.
                                                           ***

Como ves la solución acá se ha logrado guardando la imagen en disco duro para luego mostrarla en el pdf generado, lo cual me gustaría poder evitar. Pero no he logrado enviar el archivo imagen generado directamente al reporte pdf (Ese enfoque no me funciona).
Si conoces una forma de hacer esto más ’elegante’, te agradecería la sugerencia.
Chaop ;)

Cómo generar un gráfico de pastel de forma dinámica en Odoo
Yen Martínez
20 diciembre, 2020
Share this post
Archivar
Registrarse to leave a comment