Отчеты пишутся в формате HTML/QWeb, как и все обычные представления в Odoo. Вы можете использовать стандартный QWeb. Сам рендеринг PDF выполняется системной утилитой wkhtmltopdf.
Если вы хотите создать отчет для определенной модели, вам нужно будет определить Отчет и Шаблон отчета, которые он будет использовать. Если вы хотите, вы также можете указать конкретный Формат бумаги для этого отчета. Наконец, если вам нужен доступ к чему то большему чем ваша модель, вы можете определить класс Кастомные отчеты, который даст вам доступ к большему количеству моделей и записей в шаблоне.
Отчет
Каждый отчет должен быть объявлен с помощью действия.
Для простоты определения отчета доступен сокращенный элемент <report>
, а не настраивать действие и его окружение вручную. Этот <report>
может принимать следующие атрибуты:
id
- Сгенерированный записью external id
name
(обязательный параметр)- полезен только в качестве запоминающегося описания, чтобы можно было найти в списке аналогичных объектов
model
(обязательный параметр)- модель к которой относится отчет
report_type
(обязательный параметр)- укажите
qweb-pdf
для создания PDF файлов печатных форм, илиqweb-html
для HTML 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="{"no_marker": 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">
Совет
Обратите внимание, что это работает только при вызове внешних шаблонов, вы не сможете перевести часть документа, установив атрибут t-lang
на узле xml отличный от t-call
. Если вы хотите перевести часть шаблона, вы можете создать внешний шаблон с этим неполным шаблоном и вызвать его из основного с атрибутом t-lang
.
Штрих-коды
Штрих-коды - это изображения, возвращаемые контроллером и легко встраиваемые в отчеты благодаря синтаксису QWeb (см Атрибуты:
<img t-att-src="'/report/barcode/QR/%s' % 'My text in qr code'"/>
Дополнительные параметры могут быть переданы как строка запроса
<img t-att-src="'/report/barcode/?
type=%s&value=%s&width=%s&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