Использование системы печати в Odoo
Оглавление
Подготовка
Для того, чтобы использовать следующий пример, вам необходимо переключить текущий разрабатываемый проект на другую ветку.
Вот ее имя - 16.0-print-form
Затем удалите текущую базу и создайте новую.
Убедитесь, что у вас не осталось вкладок со старыми сессиями
Основные данные
В этой статье я опишу как добавить свою печатную форму для какой либо модели, как на рисунке ниже
В документации, к сожалению не описано подробно как сделать печатную форму.
Общий сценарий работы системы печати:
Report Action(На который ссылается формат бумаги)
|
|
Формируется объект из выбранного рекордсета
|
|
Передача объекта и указанного в экшене шаблона на рендеринг в QWeb
|
|
Финальный объект рендеринга, либо HTML либо PDF
Экшен печати
Пример репорт экшена, в котором мы должны указать модель, к которой он будет прикреплен, тип финального контента после рендеринга, в этом случае я указал qweb-html
, и external_id шаблона на базе которого будет происходить рендеринг.
Детально описание всех параметров вы можете узнать тут. Код ниже взят отсюда
<record id="first_model_print_form_001" model="ir.actions.report">
<field name="name">Print Form Name 001</field>
<field name="model">first.model</field>
<field name="report_type">qweb-html</field>
<field name="report_name">first_module.print_form_001_template</field>
<field name="report_file">first_module.print_form_001_template</field>
<field name="print_report_name">'Document №%s - %s' % (object.id, object.create_date)</field>
<field name="binding_model_id" ref="first_module.model_first_model"></field>
</record>
- Отображаемое имя экшена
- тип генерируемого контента
- Имя документа, в нем может быть использованы значения полей записи, к которой будет формироваться документ записи
- атрибут, который связывает экшен с моделью
Модель расширения объекта печати
Затем на основании вот этой документации мы можем создать модель которая будет создавать объекты для моего шаблона. Это может быть полезно в случаях когда нам нужно, например, добавить дополнительные объекты, или расширить существующие Вот код модели:
class ParticularReport(models.AbstractModel):
_name = "report.first_module.print_form_001_template"
_description = "Extend of print form"
def _get_report_values(self, docids, data=None):
"""
Функция для расширения данных подаваемых на печать в шаблон
param : docids : list : список id записей модели, к которой прикреплен шаблон для печати
param : data : {} : дополнительные которые содержат в себе метаинформацию
return : dict : словарь данными, используемыми в шаблоне
"""
first_model_recordset = self.env["first.model"].browse(docids)
return {
"doc_ids": docids,
"docs": first_model_recordset,
"data": data,
}
Данная модель может быть создана для любого шаблона. Для этого достаточно правильно указать ее имя и определить метод _get_report_values
. Принцип формирования имени следующий: report.полный.xml_d_шаблона
или report.имя_модуля.id_шаблона
. Как вы можете видеть в примере выше имя нашей модели полностью соответствует этому правилу report.first_module.print_form_001_template
. Все параметры и структура объекта, который надо вернуть методом _get_report_values
вы можете увидеть в примере и прочесть в контракте функции.
Использование шаблона
Вот код шаблона, который будет отрендерен. Как создавать шаблоны для QWeb движка и какие директивы вы может использовать можно ознакомиться здесь. Вот код
<template id="print_form_001_template">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="document">
<div class="article" t-att-data-oe-model="document and document._name" t-att-data-oe-id="document and document.id">
<t t-call="first_module.print_form_001_body_template" />
</div>
</t>
</t>
</template>
И вот код основного шаблона, обратите внимание что нам внутри могут быть доступны значения атрибутов и методы набора записей (экземпляра класса модели) по котрой происходит формирование печатной формы
<template id="print_form_001_body_template">
<h1 t-esc="document.name"></h1>
<p>This is example of print form for record <span> </span><span t-esc="document.name"/></p>
<table class="table table-main">
<tr>
<th class="text-center" t-esc="document._fields['field_one'].string"></th>
<th class="text-center" t-esc="document._fields['field_two'].string"></th>
<th class="text-center" t-esc="document._fields['result_field'].string"></th>
</tr>
<tr>
<td class="text-center" t-esc="document.field_one" ></td>
<td class="text-center" t-esc="document.field_two" ></td>
<td class="text-center" t-esc="document.result_field" ></td>
</tr>
</table>
<p t-esc="docs"/>
<p t-esc="data"/>
</template>
Здесь вы можете видеть, как используются дополнительные данные, созданные в служебной промежуточной модели в шаблоне документа:
Формат бумаги
Пример собственного формата бумаги. В данном случае я создал специальный формат, который соответствует накладной Республики Беларусь.
<record id="paperformat_a4_belarus_tn_portrait" model="report.paperformat">
<field name="name">ТН Вертикальная Беларусь</field>
<field name="default" eval="True"/>
<field name="format">custom</field>
<field name="page_height">288</field>
<field name="page_width">204</field>
<field name="orientation">Portrait</field>
<field name="margin_top">4</field>
<field name="margin_bottom">12</field>
<field name="margin_left">11</field>
<field name="margin_right">2</field>
<field name="header_line" eval="False"/>
<field name="header_spacing">0</field>
<field name="dpi">90</field>
<field name="report_ids" eval="[(4, ref('first_module.first_model_print_form_001'))]"/>
</record>
В целом это весьма синтетический пример, но на его основе вы можете полностью понять, как создавать произвольную печатную форму
Задания для самостоятельного повторения:
- Создайте свой шаблон для печати данных из записи
- Создайте альтернативный экшен, который будет запускать созданный вами шаблон.
Обсуждение
Обсудить можно здесь