[MIG] report_label

[IMP] allow to create report.paperformat.label without creating each time report.paperformat item
[FIX] Remove useless data that are specific Label: Agipa 114016
[REF] simplify UI, removing custom entry for ir.actions.server
[ADD] migration script to migrate name field
[IMP] Add label_background_color to allow to easily define background-color for label. (That can be usefull to debug label positions)
[DOC] update screenshots to new V16 versions
[IMP] Set body and html margin to 0 to to able to be predictive when designing a label sheet
[IMP] replace style by class in the label template, reducing the size of the html code generated.
[IMP] replace label_template by label_template_view_id on the ir.actions.server model, removing useless xml and python code. (provide migration scripts)
[REF] Split wizard file into wizard and wizard line file, following OCA guidelines
pull/708/head
Sylvain LE GAL 2023-01-03 11:17:16 +01:00
parent fe3537b11b
commit 85bb60b356
25 changed files with 217 additions and 189 deletions

View File

@ -1,7 +1,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Report Labels",
"version": "14.0.1.0.0",
"version": "16.0.1.0.0",
"summary": "Print configurable self-adhesive labels reports",
"author": "Iván Todorovich, Moka Tourisme, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/reporting-engine",
@ -13,7 +13,6 @@
],
"data": [
"security/ir.model.access.csv",
"data/paperformat_label.xml",
"views/ir_actions_server.xml",
"views/report_paperformat_label.xml",
"reports/report_label.xml",

View File

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data noupdate="1">
<record id="agipa_114016" model="report.paperformat.label">
<field name="name">Label: Agipa 114016</field>
<field name="format">A5</field>
<field name="orientation">Portrait</field>
<field name="margin_top" eval="5" />
<field name="margin_right" eval="13" />
<field name="margin_bottom" eval="0" />
<field name="margin_left" eval="13" />
<field name="dpi" eval="82" />
<field name="label_width" eval="38" />
<field name="label_height" eval="19" />
<field name="label_padding_top" eval="1" />
<field name="label_padding_right" eval="1" />
<field name="label_padding_bottom" eval="1" />
<field name="label_padding_left" eval="1" />
<field name="label_margin_top" eval="1" />
<field name="label_margin_right" eval="1" />
<field name="label_margin_bottom" eval="1" />
<field name="label_margin_left" eval="1" />
</record>
</data>
</odoo>

View File

@ -8,18 +8,36 @@
/>
</template>
<record id="report_paperformat_partner_address" model="report.paperformat">
<field name="name">Paperformat for labels (A4: 210mm x 297mm)</field>
<field name="format">A4</field>
<field name="dpi">96</field>
<field name="orientation">Portrait</field>
<field name="margin_top">0</field>
<field name="margin_bottom">0</field>
<field name="margin_right">0</field>
<field name="margin_left">0</field>
<field name="header_spacing">0</field>
<field name="disable_shrinking" eval="True" />
</record>
<record
id="report_paperformat_label_partner_address"
model="report.paperformat.label"
>
<field name="name">Partner Label</field>
<field name="format">A4</field>
<field name="label_height" eval="42.3" />
<field name="label_width" eval="60" />
<field name="name">Partner Labels (3 x 6 = 18 labels per sheet)</field>
<field name="paperformat_id" ref="report_paperformat_partner_address" />
<field name="label_height" eval="49.5" />
<field name="label_width" eval="70" />
<field name="label_padding_top" eval="5" />
<field name="label_padding_right" eval="5" />
<field name="label_padding_bottom" eval="5" />
<field name="label_padding_left" eval="5" />
<field name="label_margin_top" eval="0" />
<field name="label_margin_right" eval="0" />
<field name="label_margin_bottom" eval="0" />
<field name="label_margin_left" eval="0" />
<field name="label_background_color">#729fcf</field>
</record>
<record id="actions_server_label_partner_address" model="ir.actions.server">
@ -30,7 +48,10 @@
name="label_paperformat_id"
ref="report_paperformat_label_partner_address"
/>
<field name="label_template">report_label.label_template_partner_address</field>
<field
name="label_template_view_id"
ref="report_label.label_template_partner_address"
/>
</record>
<!-- Create context action -->

View File

@ -1,6 +1,6 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * report_label
# * report_label
#
msgid ""
msgstr ""

View File

@ -0,0 +1,40 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openupgradelib import openupgrade
from odoo.tools.sql import column_exists
@openupgrade.migrate()
def migrate(env, version):
if not column_exists(env.cr, "base_comment_template", "models"):
openupgrade.logged_query(
env.cr,
"ALTER TABLE report_paperformat_label ADD COLUMN name char",
)
openupgrade.logged_query(
env.cr,
"""
UPDATE report_paperformat_label rpfl
SET name = rpf.name
FROM report_paperformat rpf
WHERE rpfl.name is null
AND rpfl.paperformat_id = rpf.id;
""",
)
if not column_exists(env.cr, "ir_act_server", "label_template_view_id"):
openupgrade.logged_query(
env.cr,
"ALTER TABLE ir_act_server ADD COLUMN label_template_view_id integer;",
)
openupgrade.logged_query(
env.cr,
"""
UPDATE ir_act_server ias
SET label_template_view_id = iuv.id
FROM ir_ui_view iuv
WHERE ias.label_template is not null
AND iuv.key = ias.label_template;
""",
)

View File

@ -9,8 +9,10 @@ class IrActionsServer(models.Model):
selection_add=[("report_label", "Print self-adhesive labels")],
ondelete={"report_label": "cascade"},
)
label_template = fields.Char(
"Label QWeb Template",
label_template_view_id = fields.Many2one(
string="Label QWeb Template",
comodel_name="ir.ui.view",
domain=[("type", "=", "qweb")],
help="The QWeb template key to render the labels",
states={"report_label": [("required", True)]},
)
@ -20,27 +22,12 @@ class IrActionsServer(models.Model):
states={"report_label": [("required", True)]},
)
def report_label_associated_view(self):
"""View the associated qweb templates"""
self.ensure_one()
action = self.env.ref("base.action_ui_view", raise_if_not_found=False)
if not action or len(self.label_template.split(".")) < 2:
return False
res = action.read()[0]
res["domain"] = [
("type", "=", "qweb"),
"|",
("name", "ilike", self.label_template.split(".")[1]),
("key", "=", self.label_template),
]
return res
def _run_action_report_label_multi(self, eval_context=None):
"""Show report label wizard"""
context = dict(self.env.context)
context.update(
{
"label_template": self.label_template,
"label_template_view_id": self.label_template_view_id.id,
"label_paperformat_id": self.label_paperformat_id.id,
"res_model_id": self.model_id.id,
}

View File

@ -3,9 +3,10 @@ from odoo import fields, models
class ReportPaperformatLabel(models.Model):
_name = "report.paperformat.label"
_inherits = {"report.paperformat": "paperformat_id"}
_description = "Label Paper Format"
name = fields.Char(required=True)
paperformat_id = fields.Many2one(
"report.paperformat",
string="Paper Format",
@ -22,6 +23,7 @@ class ReportPaperformatLabel(models.Model):
default=42.3,
required=True,
)
label_background_color = fields.Char(default="#FFFFFF")
label_padding_top = fields.Float("Label Padding Top (mm)", default=2)
label_padding_right = fields.Float("Label Padding Right (mm)", default=2)
label_padding_bottom = fields.Float("Label Padding Bottom (mm)", default=2)
@ -30,9 +32,3 @@ class ReportPaperformatLabel(models.Model):
label_margin_right = fields.Float("Label Margin Right (mm)", default=2)
label_margin_bottom = fields.Float("Label Margin Bottom (mm)", default=2)
label_margin_left = fields.Float("Label Margin Left (mm)", default=2)
# Overload inherits defaults
orientation = fields.Selection(inherited=True, default="Portrait")
header_spacing = fields.Integer(inherited=True, default=0)
margin_top = fields.Float(inherited=True, default=7)
margin_bottom = fields.Float(inherited=True, default=7)

View File

@ -1,10 +1,27 @@
Go to **Settings > Technical > Analysis > Label Paper Format** and create
your self-adhesive label paper formats.
**Configure your Report Label Paperformat**
.. image:: ../static/description/configure_paperformat.png
* Go to "Settings > Technical > Reporting > Label Paper Format"
Go to **Settings > Technical > Analysis > Label Report** and create your label
report, and its context action. You'll also need to create or reuse a
QWeb template for you label.
* Create your self-adhesive label paper formats.
.. image:: ../static/description/configure_report_label.png
You should reuse or create a Paperformat.
.. image:: ../static/description/report_paperformat_label_form.png
**Configure your Server action**
* Go to "Settings > Technical > Actions > Server Actions"
Create your label report :
* In the 'Action to do' field, select 'Print Self-adhesive Labels'
* In the 'Label Paper Format' field, select your label paper format previously created
* In the 'Label Qweb Template' create or reuse a QWeb template for your label.
.. image:: ../static/description/ir_actions_server.png
**Importante Note**
`By design <https://github.com/OCA/reporting-engine/blob/14.0/report_label/reports/report_label.xml#L34>`_, the variable used in this QWeb template must be named `record`.

View File

@ -1,10 +1,12 @@
Known issues:
* `wkhtmltopdf` doesn't always respect dpi, and mm measures don't match. For
this matter, it's recommended to use this module along with
`report_wkhtmltopdf_param` and enable `--disable-smart-shrinking`.
* This module depends on `base_automation` only because this module extends
`ir.actions.server` with a new kind of action, and `base.automation` inherits
from `ir.actions.server` by delegation in such a way that the modules cannot
be loaded in another order.
To do when migrating in version > 16 :
1. remove ``base_automation`` dependency
2. install ``report_label``
3. install then ``base_automation``.
If the installation of ``base_automation`` works, the dependency can be
replaced by ``base``.

View File

@ -1,5 +1,11 @@
1. In the target model's tree view, select the records to print.
2. Click *Action* and your label report action name.
3. Select the number of labels per record to print, and click Print.
* In the target model's tree view, select the records to print.
* Click *Action* and your label report action name.
* Select the number of labels per record to print, and click Print.
.. image:: ../static/description/label_wizard.png
you can optionaly define an offset
.. image:: ../static/description/report_label_wizard_form.png
The items will be printed in a pdf document.
.. image:: ../static/description/report_result.png

View File

@ -2,33 +2,41 @@
<odoo>
<template id="report_label_template">
<t t-call="web.basic_layout">
<t t-set="full_width" t-value="True" />
<t t-set="label_style">
height: <t t-esc="label_format['label_height']" />mm;
width: <t t-esc="label_format['label_width']" />mm;
padding-top: <t t-esc="label_format['label_padding_top']" />mm;
padding-right: <t t-esc="label_format['label_padding_right']" />mm;
padding-bottom: <t t-esc="label_format['label_padding_bottom']" />mm;
padding-left: <t t-esc="label_format['label_padding_left']" />mm;
margin-top: <t t-esc="label_format['label_margin_top']" />mm;
margin-right: <t t-esc="label_format['label_margin_right']" />mm;
margin-bottom: <t t-esc="label_format['label_margin_bottom']" />mm;
margin-left: <t t-esc="label_format['label_margin_left']" />mm;
display: inline-block;
overflow: hidden;
float: left;
position: relative;
page-break-inside: avoid;
box-sizing: border-box;
</t>
<t t-call="web.report_layout">
<style type="text/css">
html, body {
margin: 0px;
padding: 0px;
}
.label_style {
height: <t t-esc="label_format['label_height']" />mm;
width: <t t-esc="label_format['label_width']" />mm;
padding-top: <t t-esc="label_format['label_padding_top']" />mm;
padding-right: <t t-esc="label_format['label_padding_right']" />mm;
padding-bottom: <t t-esc="label_format['label_padding_bottom']" />mm;
padding-left: <t t-esc="label_format['label_padding_left']" />mm;
margin-top: <t t-esc="label_format['label_margin_top']" />mm;
margin-right: <t t-esc="label_format['label_margin_right']" />mm;
margin-bottom: <t t-esc="label_format['label_margin_bottom']" />mm;
margin-left: <t t-esc="label_format['label_margin_left']" />mm;
background-color: <t t-esc="label_format['label_background_color']" />;
display: inline-block;
overflow: hidden;
float: left;
position: relative;
page-break-inside: avoid;
box-sizing: border-box;
}
</style>
<!-- Offset: Skip the first [offset] labels -->
<t t-foreach="range(0, offset)" t-as="i">
<div t-att-style="label_style" />
<div class="label_style" />
</t>
<t t-foreach="lines" t-as="line">
<t t-foreach="range(0, line['quantity'])" t-as="i">
<div t-att-style="label_style">
<div class="label_style">
<t t-call="{{label_template}}">
<t
t-set="record"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -22,6 +22,6 @@ class TestReportLabel(common.TransactionCase):
"discard_logo_check": True,
}
)
wizard = self.env[model].with_context(context).create({})
wizard = self.env[model].with_context(**context).create({})
report_action = wizard.print_report()
self.assertEqual(report_action["type"], "ir.actions.report")

View File

@ -5,42 +5,17 @@
<field name="model">ir.actions.server</field>
<field name="inherit_id" ref="base.view_server_action_form" />
<field name="arch" type="xml">
<header position="inside">
<button
name="report_label_associated_view"
type="object"
string="View QWeb templates"
attrs="{'invisible':['|', ('state', '!=', 'report_label'), ('label_template', '=', False)]}"
help="Display a button in the sidebar of related model to open a wizard"
/>
</header>
<field name="type" position="after">
<field
name="label_paperformat_id"
attrs="{'invisible': [('state', '!=', 'report_label')]}"
/>
<field
name="label_template"
name="label_template_view_id"
attrs="{'invisible': [('state', '!=', 'report_label')]}"
/>
</field>
</field>
</record>
<record id="report_label_action" model="ir.actions.act_window">
<field name="name">Label Reports</field>
<field name="res_model">ir.actions.server</field>
<field name="view_mode">tree,form</field>
<field name="domain">[("state", "=", "report_label")]</field>
<field name="context">{"default_state": "report_label"}</field>
</record>
<menuitem
id="report_label_menu"
name="Label Reports"
action="report_label_action"
parent="base.reporting_menuitem"
sequence="3"
/>
</odoo>

View File

@ -1,50 +1,49 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="paperformat_label_view_form" model="ir.ui.view">
<record id="view_paperformat_label_view_form" model="ir.ui.view">
<field name="model">report.paperformat.label</field>
<field name="inherit_id" ref="base.paperformat_view_form" />
<field name="mode">primary</field>
<field name="arch" type="xml">
<!-- Hide irrelevant fields -->
<field name="header_line" position="attributes">
<attribute name="invisible">1</attribute>
</field>
<field name="header_spacing" position="attributes">
<attribute name="invisible">1</attribute>
</field>
<field name="report_ids" position="attributes">
<attribute name="invisible">1</attribute>
</field>
<!-- Add label paper format fields -->
<sheet position="inside">
<group name="label">
<group name="label_size" string="Label Size" colspan="2">
<field name="label_height" />
<field name="label_width" />
<form string="Paper format configuration">
<sheet>
<group>
<field name="name" />
<field name="paperformat_id" />
</group>
<group name="label_padding" string="Label Padding">
<field string="Top (mm)" name="label_padding_top" />
<field string="Right (mm)" name="label_padding_right" />
<field string="Bottom (mm)" name="label_padding_bottom" />
<field string="Left (mm)" name="label_padding_left" />
<group name="label">
<group
name="label_settings"
string="Label Settings"
colspan="2"
>
<field name="label_height" />
<field name="label_width" />
<field name="label_background_color" widget="color" />
</group>
<group name="label_padding" string="Label Padding">
<field string="Top (mm)" name="label_padding_top" />
<field string="Right (mm)" name="label_padding_right" />
<field string="Bottom (mm)" name="label_padding_bottom" />
<field string="Left (mm)" name="label_padding_left" />
</group>
<group name="label_margin" string="Label Margin">
<field string="Top (mm)" name="label_margin_top" />
<field string="Right (mm)" name="label_margin_right" />
<field string="Bottom (mm)" name="label_margin_bottom" />
<field string="Left (mm)" name="label_margin_left" />
</group>
</group>
<group name="label_margin" string="Label Margin">
<field string="Top (mm)" name="label_margin_top" />
<field string="Right (mm)" name="label_margin_right" />
<field string="Bottom (mm)" name="label_margin_bottom" />
<field string="Left (mm)" name="label_margin_left" />
</group>
</group>
</sheet>
</sheet>
</form>
</field>
</record>
<record id="paperformat_label_view_tree" model="ir.ui.view">
<field name="model">report.paperformat.label</field>
<field name="arch" type="xml">
<tree string="Label paper format configuration">
<tree>
<field name="name" />
<field name="paperformat_id" />
<field name="label_height" />
<field name="label_width" />
</tree>

View File

@ -1 +1,2 @@
from . import report_label_wizard
from . import report_label_wizard_line

View File

@ -38,11 +38,13 @@ class ReportLabelWizard(models.TransientModel):
required=True,
default=lambda self: self.env.context.get("label_paperformat_id"),
)
label_template = fields.Char(
"Label QWeb Template",
label_template_view_id = fields.Many2one(
string="Label QWeb Template",
comodel_name="ir.ui.view",
readonly=True,
required=True,
default=lambda self: self.env.context.get("label_template"),
default=lambda self: self.env.context.get("label_template_view_id"),
)
offset = fields.Integer(
help="Number of labels to skip when printing",
@ -59,7 +61,7 @@ class ReportLabelWizard(models.TransientModel):
self.ensure_one()
return {
"label_format": self.label_paperformat_id.read()[0],
"label_template": self.label_template,
"label_template": self.label_template_view_id.key,
"offset": self.offset,
"res_model": self.model_id.model,
"lines": [
@ -79,30 +81,3 @@ class ReportLabelWizard(models.TransientModel):
"paperformat_id": self.label_paperformat_id.paperformat_id.id,
}
return action
class ReportLabelWizardLine(models.TransientModel):
_name = "report.label.wizard.line"
_description = "Report Label Wizard Line"
_order = "sequence"
wizard_id = fields.Many2one(
"report.label.wizard",
"Wizard",
required=True,
ondelete="cascade",
)
sequence = fields.Integer(default=10)
res_id = fields.Integer("Resource ID", required=True)
res_name = fields.Char(compute="_compute_res_name")
quantity = fields.Integer(default=1, required=True)
@api.depends("wizard_id.model_id", "res_id")
def _compute_res_name(self):
wizard = self.mapped("wizard_id")
wizard.ensure_one()
res_model = wizard.model_id.model
res_ids = self.mapped("res_id")
names_map = dict(self.env[res_model].browse(res_ids).name_get())
for rec in self:
rec.res_name = names_map.get(rec.res_id)

View File

@ -21,7 +21,7 @@
<field name="offset" />
<field name="model_id" invisible="1" />
<field name="label_paperformat_id" />
<field name="label_template" invisible="1" />
<field name="label_template_view_id" invisible="1" />
</group>
</group>
</sheet>

View File

@ -0,0 +1,29 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class ReportLabelWizardLine(models.TransientModel):
_name = "report.label.wizard.line"
_description = "Report Label Wizard Line"
_order = "sequence"
wizard_id = fields.Many2one(
"report.label.wizard",
"Wizard",
required=True,
ondelete="cascade",
)
sequence = fields.Integer(default=10)
res_id = fields.Integer("Resource ID", required=True)
res_name = fields.Char(compute="_compute_res_name")
quantity = fields.Integer(default=1, required=True)
@api.depends("wizard_id.model_id", "res_id")
def _compute_res_name(self):
wizard = self.mapped("wizard_id")
wizard.ensure_one()
res_model = wizard.model_id.model
res_ids = self.mapped("res_id")
names_map = dict(self.env[res_model].browse(res_ids).name_get())
for rec in self:
rec.res_name = names_map.get(rec.res_id)