17. Desarrollando con Odoo (12). Separando los modelos en ficheros individuales. Introducció a los Reports
1. Separar los modelos
Dentro de la carpeta models tenemos el fichero __init__.py que ahora hace referencia al megafichero que contiene todos los modulos:
# -*- coding: utf-8 -*- from . import models
Ahora hay que eliminar esta entrada y separarla en cada uno de los modelos que contiene quedando
# -*- coding: utf-8 -*- #from . import models from . import developer from . import project from . import history from . import task from . import bug from . import improvement from . import sprint from . import technology
Ojo: Cada modelo que necesite el logger, hay que añadirles estas 2 líneas antes del class
import logging _logger= logging.getLogger(__name__) class ....
Veamos un ejemplo de model (task.py)
from odoo import models, fields, api import datetime import logging _logger= logging.getLogger(__name__) class task(models.Model): _name = 'ximoapp01.task' _description = 'ximoapp01.task' name = fields.Char(string= "Nombre", readonly=False, required=True, help="Nombre de la Tarea" ) description = fields.Text() start_date = fields.Datetime() duration= fields.Integer() end_date =fields.Datetime(compute="_get_end_date", store=True ) is_paused = fields.Boolean(default=False) code = fields.Char(compute="_get_code") #sprint = fields.Many2one("ximoapp01.sprint", ondelete="set null",help="Macro tarea padre Sprint") sprint = fields.Many2one("ximoapp01.sprint", compute="_get_sprint", ondelete="set null", store= True, help="Macro tarea padre Sprint") history = fields.Many2one("ximoapp01.history", ondelete="set null",help="Historia relacionada") technologies = fields.Many2many(comodel_name="ximoapp01.technology", relation="technology_task", column1="task_id", column2="technology_id", help="Tecnologías empleadas") #def _get_definition_date(self): # return datetime.datetime.now() #definition_date = fields.Datetime(default=_get_definition_date) definition_date = fields.Datetime(default= lambda d: datetime.datetime.now()) def _get_code(self): for record in self: #record.code=record.name + str(record.id) record.code=str(record.id) _logger.debug("Por aquí hemos pasado...") @api.depends('start_date', 'duration') def _get_end_date(self): for record in self: if isinstance(record.start_date, datetime.datetime) and record.duration > 0 : record.end_date = record.start_date + datetime.timedelta(days=record.duration) else: record.end_date=record.start_date @api.depends('history') def _get_sprint(self): for record in self: #sprints = self.env['ximoapp01.sprint'].search([('project.id', '=', record.history.project.id)]) if isinstance(record.history.project.id, models.NewId): id_project= int (record.history.id.origin) else: id_project= record.history.id sprints = self.env['ximoapp01.sprint'].search([('project.id', '=', id_project)]) found = False for sprint in sprints: if not found: if isinstance(sprint.end_date, datetime.datetime): if sprint.end_date > datetime.datetime.now(): record.sprint = sprint.id found = True if not found: record.sprint = False def _get_default_developer(self): developer= self.browse(self._context.get('current_developer')) if developer: return [developer.id] else: return [] #developer = fields.Many2one('res.partner') developers = fields.Many2many(comodel_name="res.partner", relation="partner_task", column1="task_id", column2="partner_id", default=_get_default_developer, help="Desarrolladores")
2. Reports
Para documentarme he utilizado Cybrosys youtube, Cybrosys blog y y Weblearn. Hay que tener en cuenta que ellas aparecen pequeños fallos que hacen que tu aplicación reviente! y hay que ir contrastando lo que dice una y otra.
Veamos los pasos:
1. Si no existe la carpeta report que debe estar al mismo nivel que models o views entonces la creamos.
2. Creamos dentro de la misma un fichero por ejemplo task_report.xml teniendo en cuenta que:
- El model del record es "ir.action.reports" y su id debe ser único (a ser posible debe conservar esta nomeclatura:"action_report_app_modelClass" (donde action_report es fijo y app se refiere al nombre de la aplicación (ximoapp01) y modelClass es el nombre del modelo (task))
- field-name es el nombre del report que aparecerá en la interface de usuario
- field-model es el nombre completo del modelo (app.classModel)
- field-report_type puede ser qweb-pdf, qweb-html y qweb-txt
- field-report_name y field-report_file en principio deben coincidir y la nomenclatura debe ser "app.templateId" (donde app se refiere al nombre de la aplicación (ximoapp01) y templateId es el id que se le assigna al template en el siguiente fichero que adjuntaremos (task_template.xml). En cocreto la línea que tiene el id es : <template id="report_template_task_ximo">
- firld-binding_model_id su nomenclatura es "app.model_app_modelClass" (donde action_report es fijo y app se refiere al nombre de la aplicación (ximoapp01) y modelClass es el nombre del modelo (task))
y le damos este contenido:
<odoo> <record id="action_report_ximoapp01_task" model="ir.actions.report"> <field name="name">A Task Report</field> <field name="model">ximoapp01.task</field> <field name="report_type">qweb-pdf</field> <field name="report_name">ximoapp01.report_template_task_ximo</field> <!-- ximoapp01. + FROM task_template : <template id="my_report_template_task"> --> <field name="report_file">ximoapp01.report_template_task_ximo</field> <field name="binding_model_id" ref="ximoapp01.model_ximoapp01_task"/> <!-- ximoapp01. + 'model_' + ximoapp01 + _ + modelClass --> <field name="binding_type">report</field> </record> </odoo>
3. Creamos el fichero task_template.xml y le damos este contenido:
<odoo> <template id="report_template_task_ximo"> <t t-call="web.html_container"> <t t-foreach="docs" t-as="o"> <t t-call="web.external_layout"> <div class="page"> <div class="oe_structure"/> <h2>Task Report</h2> <p><span t-field="o.name"/></p> </div> </t> </t> </t> </template> </odoo>
4. En el fichero __manifest__.py añadimos dentro de 'data' el acceso a los 2 ficheros anteriores:
# any module necessary for this one to work correctly 'depends': ['base'], # always loaded 'data': [ 'security/ir.model.access.csv', 'views/views.xml', 'views/project.xml', 'views/history.xml', 'views/task.xml', 'views/sprint.xml', 'views/technology.xml', 'views/bug.xml', 'views/improvement.xml', 'views/developer.xml', 'views/templates.xml', 'report/task_report.xml', 'report/task_template.xml' ], # only loaded in demonstration mode 'demo': [ 'demo/demo.xml', ],
Actualizamos la aplicación y suele dar problemas si no definimos bien los parámetros de task_report.xml. Y sale
Y el report
Este es un report introductorio. En principio, más adelatne se intentará explicar como se define un report con datos...
Comentarios
Publicar un comentario