Saltar al contenido
Volver al blog
DesarrolloQWebInformes

Informes PDF con QWeb en Odoo: del formulario al documento que cierra ventas

QWeb es HTML que se convierte en PDF. Te enseñamos a montar un informe, recorrer registros con t-foreach y por qué t-field te ahorra mil dolores de cabeza.

COConsultor Odoo31 de mayo de 20264 min de lectura

Forma parte de nuestra guía completa: Desarrollo de módulos en Odoo.

Hay una parte de Odoo que el cliente final ve más que ninguna otra y que, paradójicamente, suele ser la peor cuidada: los informes en PDF. La factura, el presupuesto, la ficha de producto, la orden de trabajo. Son el documento que sale de tu empresa con tu logo y llega al cliente. Y, sin embargo, demasiadas veces es un PDF descuadrado, con la fecha en formato americano y un total que no cuadra con la pantalla.

La buena noticia: en Odoo los informes son QWeb, que en el fondo es HTML con superpoderes. Si sabes maquetar una tabla, sabes hacer un informe. Vamos a verlo.

Dos piezas: la acción y la plantilla

Un informe son siempre dos cosas. Primero, una acción de informe (ir.actions.report) que le dice a Odoo "sobre este modelo, ofrece este PDF y añádelo al menú Imprimir":

<record id="action_report_property" model="ir.actions.report">
    <field name="name">Ficha de propiedad</field>
    <field name="model">estate.property</field>
    <field name="report_type">qweb-pdf</field>
    <field name="report_name">estate.report_property</field>
    <field name="binding_model_id" ref="model_estate_property"/>
    <field name="binding_type">report</field>
</record>

Ese binding_model_id es el detalle que mucha gente olvida: es lo que hace que el botón "Imprimir" aparezca en el formulario. Sin él, el informe existe pero no hay forma de lanzarlo desde la interfaz, y empiezan los "no me sale por ningún lado".

La plantilla: HTML que recorre tus datos

La segunda pieza es la plantilla QWeb. Aquí es donde se ve que QWeb es HTML con directivas t-. Te apoyas en los layouts estándar de Odoo (web.html_container, web.external_layout) para heredar la cabecera con el logo y el pie de página de la empresa gratis:

<template id="report_property">
    <t t-call="web.html_container">
        <t t-foreach="docs" t-as="doc">
            <t t-call="web.external_layout">
                <div class="page">
                    <h2 t-field="doc.name"/>
                    <p>Precio esperado: <span t-field="doc.expected_price"/></p>
                    <table class="table table-sm">
                        <thead>
                            <tr><th>Cliente</th><th>Oferta</th></tr>
                        </thead>
                        <tbody>
                            <tr t-foreach="doc.offer_ids" t-as="offer">
                                <td t-field="offer.partner_id"/>
                                <td t-field="offer.price"/>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </t>
        </t>
    </t>
</template>

Ese docs es la colección de registros que mandaste a imprimir; el t-foreach los recorre uno a uno (y aquí también funciona con el One2many de las ofertas, justo como vimos en relaciones entre modelos). Como ves, las clases table table-sm son Bootstrap: Odoo lo trae de serie, así que no maquetas desde cero.

t-field vs t-esc: el detalle que separa un PDF profesional de uno cutre

Aquí está el matiz que más impacto tiene en la calidad del documento, y casi nadie lo explica bien. Tienes dos formas de pintar un valor:

  • t-esc (o t-out) imprime el dato en crudo. Un float sale como 250000.0. Una fecha, en formato técnico.
  • t-field imprime el dato formateado según su tipo y la configuración de la empresa: el precio sale como 250.000,00 €, la fecha en el formato del idioma, el Many2one como el nombre del registro.

Regla simple: para mostrar campos de un registro, usa siempre t-field. Reserva t-esc/t-out para valores calculados al vuelo que no son un campo. El día que entiendes esto, tus PDF dejan de parecer un volcado de base de datos y empiezan a parecer documentos de empresa.

Hereda los informes estándar, no los copies

¿Necesitas añadir tu campo a la factura estándar de Odoo? La tentación es duplicar la plantilla de factura entera y editarla. Mal. Igual que con las vistas, se hereda con xpath —el mismo principio que explicamos en herencia en Odoo—:

<template id="report_invoice_zone" inherit_id="account.report_invoice_document">
    <xpath expr="//div[@id='informations']" position="inside">
        <p>Zona de reparto: <span t-field="o.delivery_zone"/></p>
    </xpath>
</template>

Así tu añadido sobrevive a las actualizaciones, en lugar de quedarte con una factura congelada que pierde cada mejora que Odoo publique.

El gotcha del motor de renderizado

Un aviso que ahorra horas: el PDF lo genera wkhtmltopdf, que no es un navegador moderno. Hay CSS que en pantalla se ve perfecto y en el PDF se rompe (flexbox caprichoso, márgenes que se ignoran, saltos de página inesperados). La cura es maquetar sobre las clases de Bootstrap que Odoo ya usa y probar siempre el PDF real, no solo la previsualización HTML. Lo que ves en el navegador no es lo que imprime el motor.

Por qué esto no es un detalle menor

Un presupuesto bien maquetado transmite seriedad antes de que el cliente lea una sola cifra; uno descuadrado siembra dudas. El informe es marketing silencioso. Por eso, cuando montamos un Odoo, los documentos que salen al exterior reciben el mismo cuidado que la lógica de negocio.

¿Tus PDF de Odoo dan una imagen que no te representa, o necesitas un informe a medida que hoy no existe? En una sesión de diagnóstico los revisamos, o míralo dentro de nuestro desarrollo a medida. Para el resto del recorrido, tienes la anatomía de un módulo y las acciones automatizadas.

#Desarrollo#QWeb#Informes
Compartir artículo

Comentarios (0)

Sé el primero en comentar.

Inicia sesión para dejar un comentario.

Acceder

Los comentarios se revisan antes de publicarse.

¿Listo para sacarle el máximo partido a Odoo?

Cuéntanos tu reto. En una primera llamada de 30 minutos te diremos cómo Odoo puede ayudarte, sin compromiso.