Отчеты QWeb

Отчеты пишутся в формате HTML/QWeb, как и все обычные представления в Odoo. Вы можете использовать стандартный QWeb. Сам рендеринг PDF выполняется системной утилитой wkhtmltopdf.

Если вы хотите создать отчет для определенной модели, вам нужно будет определить Отчет и Шаблон отчета, которые он будет использовать. Если вы хотите, вы также можете указать конкретный Формат бумаги для этого отчета. Наконец, если вам нужен доступ к чему то большему чем ваша модель, вы можете определить класс Кастомные отчеты, который даст вам доступ к большему количеству моделей и записей в шаблоне.

Отчет

Каждый отчет должен быть объявлен с помощью действия.

Для простоты определения отчета доступен сокращенный элемент <report>, а не настраивать действие и его окружение вручную. Этот <report> может принимать следующие атрибуты:

id
Сгенерированный записью external id
name (обязательный параметр)
полезен только в качестве запоминающегося описания, чтобы можно было найти в списке аналогичных объектов
model (обязательный параметр)
модель к которой относится отчет
report_type (обязательный параметр)
укажите qweb-pdf для создания PDF файлов печатных форм, или qweb-html для HTML
file
Путь к основному файлу отчета (в зависимости от типа отчета) или пусто, если содержимое находится в другом поле
print_report_name
имя отчета (которое будет присвоено выданному PDF файлу)
groups
Many2many поле со ссылкой на группы которым разрешено использовать отчет
attachment_use
Если установлено значение True, отчет будет сохранен как прикрепление к записи с использованием имени, сгенерированного выражением attachment; Вы можете это использовать , если вам нужно, чтобы ваш отчет генерировался только один раз (по юридическим причинам, например)
attachment
Выражение python, которое определяет имя отчета; Запись доступна как переменная object
paperformat
Внешний идентификатор формата бумаги, который вы хотите использовать (по умолчанию используется формат бумаги компании, если он не указан явно)

Пример:

<report
    id="account_invoices"
    model="account.invoice"
    string="Invoices"
    report_type="qweb-pdf"
    name="account.report_invoice"
    file="account.report_invoice"
    attachment_use="True"
    attachment="(object.state in ('open','paid')) and
        ('INV'+(object.number or '').replace('/','')+'.pdf')"
/>

Шаблон отчета

Минимальный жизнеспособный шаблон

Минимальный шаблон будет выглядеть так:

<template id="report_invoice">
    <t t-call="web.html_container">
        <t t-foreach="docs" t-as="o">
            <t t-call="web.external_layout">
                <div class="page">
                    <h2>Report title</h2>
                    <p>This object's name is <span t-field="o.name"/></p>
                </div>
            </t>
        </t>
    </t>
</template>

Вызов external_layout добавит стандартные заголовок и нижний колонтитул в ваш отчет. Тело PDF будет содержимым внутри <div class="page"> . id шаблона должен быть именем, указанным при объявлении отчета; Например account.report_invoice для вышеупомянутого отчета. Поскольку это шаблон QWeb, вы можете получить доступ ко всем полям объекта docs принятого внутри шаблона.

В отчетах доступны переменные, в основном:

docs
записи для текущего отчета
doc_ids
список id для записей docs
doc_model
модель для записей docs
time
ссылка на time из стандартной библиотеки Python
user
запись res.user для пользователя, печатающего отчет
res_company
запись компании текущего user

Если вы хотите получить доступ к другим записям/моделям в шаблоне, вам понадобится кастомный отчет..

Переводимые шаблоны

Если вы хотите перевести отчеты (например, на язык партнера), вам необходимо определить два шаблона:

  • Основной шаблон отчета
  • Переводимый документ

Затем вы можете вызвать переводимый документ из вашего основного шаблона с атрибутом t-lang, для назначено код языка (например, fr или en_US) или назначено поле записи кде этот код содержится. Вам также нужно будет повторно просмотреть связанные записи с надлежащим контекстом, если вы используете поля, которые можно переводить (например, названия стран, состояния продаж и т.д.),

Например, рассмотрим отчет Sale Order из модуля «Продажи»:

<!-- Main template -->
<template id="report_saleorder">
    <t t-call="web.html_container">
        <t t-foreach="docs" t-as="doc">
            <t t-call="sale.report_saleorder_document" t-lang="doc.partner_id.lang"/>
        </t>
    </t>
</template>

<!-- Translatable template -->
<template id="report_saleorder_document">
    <!-- Re-browse of the record with the partner lang -->
    <t t-set="doc" t-value="doc.with_context(lang=doc.partner_id.lang)" />
    <t t-call="web.external_layout">
        <div class="page">
            <div class="oe_structure"/>
            <div class="row">
                <div class="col-6">
                    <strong t-if="doc.partner_shipping_id == doc.partner_invoice_id">Invoice and shipping address:</strong>
                    <strong t-if="doc.partner_shipping_id != doc.partner_invoice_id">Invoice address:</strong>
                    <div t-field="doc.partner_invoice_id" t-options="{&quot;no_marker&quot;: True}"/>
                <...>
            <div class="oe_structure"/>
        </div>
    </t>
</template>

Основной шаблон вызывает переводимый шаблон с doc.partner_id.lang в качестве параметра t-lang, поэтому он будет отображаться на языке партнера. Таким образом, каждый Sale Order будет напечатан на языке соответствующего покупателя. Если вы хотите перевести только тело документа, но сохранить верхний и нижний колонтитулы на языке по умолчанию, вы можете вызвать внешний макет отчета следующим образом:

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

Штрих-коды

Штрих-коды - это изображения, возвращаемые контроллером и легко встраиваемые в отчеты благодаря синтаксису QWeb (см Атрибуты:

<img t-att-src="'/report/barcode/QR/%s' % 'My text in qr code'"/>

Дополнительные параметры могут быть переданы как строка запроса

<img t-att-src="'/report/barcode/?
    type=%s&amp;value=%s&amp;width=%s&amp;height=%s'%('QR', 'text', 200, 200)"/>

Полезные заметки

  • Классы Bootstrap и FontAwesome можно использовать в шаблоне отчета.
  • Локальный CSS можно поместить непосредственно в шаблон
  • Глобальный CSS можно вставить в основной макет отчета, унаследовав его шаблон и вставить свой CSS

    <template id="report_saleorder_style" inherit_id="report.style">
      <xpath expr=".">
        <t>
          .example-css-class {
            background-color: red;
          }
        </t>
      </xpath>
    </template>
    
  • Если кажется, что в вашем отчете PDF отсутствуют стили, проверьте эти инструкции.

Формат бумаги

Форматы бумаги - это записи модели report.paperformat и могут содержать следующие атрибуты:

name (обязательный параметр)
полезен только в качестве запоминающегося описания, чтобы можно было найти в списке аналогичных объектов
description
небольшое описание вашего формата
format
либо предопределенный формат (от A0 до A9, от B0 до B10, Legal, Letter, Tabloid, …) или custom; A4 по умолчанию. Вы не можете использовать нестандартный формат, если вы определяете размеры страницы.
dpi
значение DPI на выходе; 90 по умолчанию
margin_top, margin_bottom, margin_left, margin_right
размеры полей в мм
page_height, page_width
размер страницы в мм
orientation
Landscape или Portrait
header_line
булево значение для отображения строки заголовка
header_spacing
Отступ от заголовка в мм

Пример:

<record id="paperformat_frenchcheck" model="report.paperformat">
    <field name="name">French Bank Check</field>
    <field name="default" eval="True"/>
    <field name="format">custom</field>
    <field name="page_height">80</field>
    <field name="page_width">175</field>
    <field name="orientation">Portrait</field>
    <field name="margin_top">3</field>
    <field name="margin_bottom">3</field>
    <field name="margin_left">3</field>
    <field name="margin_right">3</field>
    <field name="header_line" eval="False"/>
    <field name="header_spacing">3</field>
    <field name="dpi">80</field>
</record>

Кастомные отчеты

Модель отчета имеет стандартную функцию get_html, которая ищет модель с именем report.Module.report_name. Если он существует, он будет использовать его для вызова генератора шаблонов QWeb; В противном случае будет использоваться общая функция. Если вы хотите настроить свои отчеты путем включения большего количества вещей в шаблон (например, записи других моделей), вы можете определить эту модель, перезаписать функцию render_html и передать объекты в словаре docargs:

from odoo import api, models

class ParticularReport(models.AbstractModel):
    _name = 'report.module.report_name'

    @api.model
    def _get_report_values(self, docids, data=None):
        report_obj = self.env['ir.actions.report']
        report = report_obj._get_report_from_name('module.report_name')
        docargs = {
            'doc_ids': docids,
            'doc_model': report.model,
            'docs': self,
        }
        return docargs

Кастомные шрифты

Если вы хотите задейтсвовать кастомные шрифты, вам нужно добавить свой собственный шрифт и связанный с ним less/CSS в бандле ассетов web.reports_assets_common. Добавление кастомных шрифтов в бандл web.assets_common или web.assets_backend не сделает ваш шрифт доступным в отчетах QWeb.

Пример:

<template id="report_assets_common_custom_fonts" name="Custom QWeb fonts" inherit_id="web.report_assets_common">
    <xpath expr="." position="inside">
        <link href="/your_module/static/src/less/fonts.less" rel="stylesheet" type="text/less"/>
    </xpath>
</template>

Вам нужно будет определить ваш @font-face в этом less файле, даже если вы использовали его в другом бандле ассетов (кроме web.reports_assets_common).

Пример:

@font-face {
    font-family: 'MonixBold';
    src: local('MonixBold'), local('MonixBold'), url(/your_module/static/src/fonts/MonixBold-Regular.otf) format('opentype');
}

.h1-title-big {
    font-family: MonixBold;
    font-size: 60px;
    color: #3399cc;
}

После того, как вы добавили less в свой бандл ассетов, вы можете использовать классы - в этом примере h1-title-big - в своем кастомном отчете QWeb.

Отчеты - это веб-страницы

Отчеты динамически генерируются модулем отчета и могут быть доступны напрямую через URL:

Например, вы можете получить доступ к отчету Sale Order в режиме html, перейдя в http://<server-address>/report/html/sale.report_saleorder/38

Или вы можете получить доступ к PDF-версии по адресу http://<server-address>/report/pdf/sale.report_saleorder/38