Skip to content

Commit 543d416

Browse files
ivantodorovichlegalsylvain
authored andcommitted
[ADD] report_label
1 parent 79d2153 commit 543d416

25 files changed

+549
-0
lines changed

report_label/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from . import models
2+
from . import wizards

report_label/__manifest__.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
'name': 'Report Labels',
3+
'version': '12.0.1.0.0',
4+
'summary': 'Print configurable self-adhesive labels reports',
5+
'author': 'Iván Todorovich, Moka Tourisme, Odoo Community Association (OCA)',
6+
'website': 'https://github.com/OCA/reporting-engine',
7+
'license': 'AGPL-3',
8+
'category': 'Reporting',
9+
'maintainers': [
10+
'ivantodorovich'
11+
],
12+
'depends': [
13+
'base',
14+
],
15+
'data': [
16+
'security/ir.model.access.csv',
17+
'data/paperformat_label.xml',
18+
'views/ir_actions_server.xml',
19+
'views/report_paperformat_label.xml',
20+
'reports/report_label.xml',
21+
'wizards/report_label_wizard.xml',
22+
],
23+
'demo': [
24+
'demo/demo.xml',
25+
]
26+
}
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<odoo>
3+
<data noupdate="1">
4+
5+
<record id="agipa_114016" model="report.paperformat.label">
6+
<field name="name">Label: Agipa 114016</field>
7+
<field name="format">A5</field>
8+
<field name="orientation">Portrait</field>
9+
<field name="margin_top" eval="5"/>
10+
<field name="margin_right" eval="13"/>
11+
<field name="margin_bottom" eval="0"/>
12+
<field name="margin_left" eval="13"/>
13+
<field name="dpi" eval="82"/>
14+
<field name="label_width" eval="38"/>
15+
<field name="label_height" eval="19"/>
16+
<field name="label_padding_top" eval="1"/>
17+
<field name="label_padding_right" eval="1"/>
18+
<field name="label_padding_bottom" eval="1"/>
19+
<field name="label_padding_left" eval="1"/>
20+
<field name="label_margin_top" eval="1"/>
21+
<field name="label_margin_right" eval="1"/>
22+
<field name="label_margin_bottom" eval="1"/>
23+
<field name="label_margin_left" eval="1"/>
24+
</record>
25+
26+
</data>
27+
</odoo>

report_label/demo/demo.xml

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<odoo>
3+
4+
<template id="label_template_partner_address" name="Partner Label: Address">
5+
<address
6+
t-field="record.self"
7+
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}'
8+
/>
9+
</template>
10+
11+
<record id="report_paperformat_label_partner_address" model="report.paperformat.label">
12+
<field name="name">Partner Label</field>
13+
<field name="format">A4</field>
14+
<field name="label_height" eval="42.3"/>
15+
<field name="label_width" eval="60"/>
16+
<field name="label_padding_top" eval="5"/>
17+
<field name="label_padding_right" eval="5"/>
18+
<field name="label_padding_bottom" eval="5"/>
19+
<field name="label_padding_left" eval="5"/>
20+
</record>
21+
22+
<record id="actions_server_label_partner_address" model="ir.actions.server">
23+
<field name="name">Print Address Labels</field>
24+
<field name="state">report_label</field>
25+
<field name="model_id" ref="base.model_res_partner"/>
26+
<field name="label_paperformat_id" ref="report_paperformat_label_partner_address"/>
27+
<field name="label_template">report_label.label_template_partner_address</field>
28+
</record>
29+
30+
<!-- Create context action -->
31+
<function model="ir.actions.server" eval="[ref('actions_server_label_partner_address')]" name="create_action"/>
32+
33+
</odoo>

report_label/models/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from . import report_paperformat_label
2+
from . import ir_actions_server
3+
from . import ir_actions_report
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from odoo import api, models
2+
3+
4+
class IrActionsReport(models.Model):
5+
_inherit = "ir.actions.report"
6+
7+
@api.model
8+
def get_paperformat(self):
9+
# Allow to define paperformat via context
10+
res = super().get_paperformat()
11+
if self.env.context.get("paperformat_id"):
12+
res = self.env["report.paperformat"].browse(
13+
self.env.context.get("paperformat_id"))
14+
return res
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from odoo import api, models, fields
2+
3+
4+
class IrActionsServer(models.Model):
5+
_inherit = "ir.actions.server"
6+
7+
state = fields.Selection(
8+
selection_add=[("report_label", "Print self-adhesive labels")]
9+
)
10+
label_template = fields.Char(
11+
"Label QWeb Template",
12+
help="The QWeb template key to render the labels",
13+
states={
14+
"report_label": [("required", True)]
15+
}
16+
)
17+
label_paperformat_id = fields.Many2one(
18+
"report.paperformat.label",
19+
"Label Paper Format",
20+
states={
21+
"report_label": [("required", True)]
22+
}
23+
)
24+
25+
@api.multi
26+
def report_label_associated_view(self):
27+
""" View the associated qweb templates """
28+
self.ensure_one()
29+
action = self.env.ref('base.action_ui_view', raise_if_not_found=False)
30+
if not action or len(self.label_template.split('.')) < 2:
31+
return False
32+
res = action.read()[0]
33+
res['domain'] = [
34+
('type', '=', 'qweb'),
35+
'|',
36+
('name', 'ilike', self.label_template.split('.')[1]),
37+
('key', '=', self.label_template),
38+
]
39+
return res
40+
41+
@api.model
42+
def run_action_report_label_multi(self, action, eval_context=None):
43+
""" Show report label wizard """
44+
context = dict(self.env.context)
45+
context.update({
46+
"label_template": action.label_template,
47+
"label_paperformat_id": action.label_paperformat_id.id,
48+
"res_model_id": action.model_id.id,
49+
})
50+
return {
51+
"name": action.name,
52+
"type": "ir.actions.act_window",
53+
"res_model": "report.label.wizard",
54+
"context": str(context),
55+
"view_mode": "form",
56+
"target": "new",
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from odoo import models, fields
2+
3+
4+
class ReportPaperformatLabel(models.Model):
5+
_name = "report.paperformat.label"
6+
_inherits = {"report.paperformat": "paperformat_id"}
7+
_description = "Label Paper Format"
8+
9+
paperformat_id = fields.Many2one(
10+
"report.paperformat",
11+
string="Paper Format",
12+
required=True,
13+
ondelete="cascade",
14+
)
15+
label_width = fields.Float(
16+
"Label Width (mm)",
17+
default=60,
18+
required=True,
19+
)
20+
label_height = fields.Float(
21+
"Label Height (mm)",
22+
default=42.3,
23+
required=True,
24+
)
25+
label_padding_top = fields.Float("Label Padding Top (mm)", default=2)
26+
label_padding_right = fields.Float("Label Padding Right (mm)", default=2)
27+
label_padding_bottom = fields.Float("Label Padding Bottom (mm)", default=2)
28+
label_padding_left = fields.Float("Label Padding Left (mm)", default=2)
29+
label_margin_top = fields.Float("Label Margin Top (mm)", default=2)
30+
label_margin_right = fields.Float("Label Margin Right (mm)", default=2)
31+
label_margin_bottom = fields.Float("Label Margin Bottom (mm)", default=2)
32+
label_margin_left = fields.Float("Label Margin Left (mm)", default=2)
33+
34+
# Overload inherits defaults
35+
orientation = fields.Selection(inherited=True, default="Portrait")
36+
header_spacing = fields.Integer(inherited=True, default=0)
37+
margin_top = fields.Float(inherited=True, default=7)
38+
margin_bottom = fields.Float(inherited=True, default=7)

report_label/readme/CONFIGURE.rst

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Go to **Settings > Technical > Analysis > Label Paper Format** and create
2+
your self-adhesive label paper formats.
3+
4+
.. image:: ../static/description/configure_paperformat.png
5+
6+
Go to **Settings > Technical > Analysis > Label Report** and create your label
7+
report, and its context action. You'll also need to create or reuse a
8+
QWeb template for you label.
9+
10+
.. image:: ../static/description/configure_report_label.png

report_label/readme/CONTRIBUTORS.rst

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
* Iván Todorovich <ivan.todorovich@gmail.com>
2+
3+
* `Moka Tourisme <https://www.mokatourisme.fr>`_:
4+
* Grégory Schreiner
5+
6+
* Sylvain LE GAL <https://twitter.com/legalsylvain>

report_label/readme/DESCRIPTION.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This module allows you to create self-adhesive label printing actions on any model.

report_label/readme/ROADMAP.rst

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
* `wkhtmltopdf` doesn't always respect dpi, and mm measures don't match. For
2+
this matter, it's recommended to use this module along with
3+
`report_wkhtmltopdf_param` and enable `--disable-smart-shrinking`.

report_label/readme/USAGE.rst

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
1. In the target model's tree view, select the records to print.
2+
2. Click *Action* and your label report action name.
3+
3. Select the number of labels per record to print, and click Print.
4+
5+
.. image:: ../static/description/label_wizard.png

report_label/reports/report_label.xml

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<odoo>
3+
4+
<template id="report_label_template">
5+
<t t-call="web.basic_layout">
6+
<t t-set="full_width" t-value="True"/>
7+
<t t-set="label_style">
8+
height: <t t-esc="label_format['label_height']"/>mm;
9+
width: <t t-esc="label_format['label_width']"/>mm;
10+
padding-top: <t t-esc="label_format['label_padding_top']"/>mm;
11+
padding-right: <t t-esc="label_format['label_padding_right']"/>mm;
12+
padding-bottom: <t t-esc="label_format['label_padding_bottom']"/>mm;
13+
padding-left: <t t-esc="label_format['label_padding_left']"/>mm;
14+
margin-top: <t t-esc="label_format['label_margin_top']"/>mm;
15+
margin-right: <t t-esc="label_format['label_margin_right']"/>mm;
16+
margin-bottom: <t t-esc="label_format['label_margin_bottom']"/>mm;
17+
margin-left: <t t-esc="label_format['label_margin_left']"/>mm;
18+
display: inline-block;
19+
overflow: hidden;
20+
float: left;
21+
position: relative;
22+
page-break-inside: avoid;
23+
box-sizing: border-box;
24+
</t>
25+
<!-- Offset: Skip the first [offset] labels -->
26+
<t t-foreach="range(0, offset)" t-as="i">
27+
<div t-att-style="label_style"></div>
28+
</t>
29+
<t t-foreach="lines" t-as="line">
30+
<t t-foreach="range(0, line['quantity'])" t-as="i">
31+
<div t-att-style="label_style">
32+
<t t-call="{{label_template}}">
33+
<t t-set="record" t-value="docs.env[res_model].browse(line['res_id'])"/>
34+
</t>
35+
</div>
36+
</t>
37+
</t>
38+
</t>
39+
</template>
40+
41+
<record id="report_label" model="ir.actions.report">
42+
<field name="name">Label Report</field>
43+
<field name="model">report.label.wizard</field>
44+
<field name="report_type">qweb-pdf</field>
45+
<field name="report_name">report_label.report_label_template</field>
46+
<field name="report_file">report_label.report_label_template</field>
47+
</record>
48+
49+
</odoo>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2+
access_report_paperformat_label_all,report.paperformat.label all,model_report_paperformat_label,,1,,,
3+
access_report_label_layout_admin,report.paperformat.label admin,model_report_paperformat_label,base.group_system,1,1,1,1
Loading
Loading
21.9 KB
Loading

report_label/tests/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import test_report_label
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from odoo.tests import common
2+
from ast import literal_eval
3+
4+
5+
class TestReportLabel(common.TransactionCase):
6+
7+
def setUp(self):
8+
super().setUp()
9+
self.partner_label = self.env.ref(
10+
"report_label.actions_server_label_partner_address")
11+
12+
def test_01_print_partner_label(self):
13+
self.partner_label.create_action()
14+
action = self.partner_label.run()
15+
model = action["res_model"]
16+
context = literal_eval(action["context"])
17+
context["active_model"] = "res.partner"
18+
context["active_ids"] = self.env["res.partner"].search([]).ids
19+
wizard = self.env[model].with_context(context).create({})
20+
report_action = wizard.print_report()
21+
self.assertEquals(report_action["type"], "ir.actions.report")
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<odoo>
3+
4+
<record id="view_server_action_form" model="ir.ui.view">
5+
<field name="model">ir.actions.server</field>
6+
<field name="inherit_id" ref="base.view_server_action_form"/>
7+
<field name="arch" type="xml">
8+
<header position="inside">
9+
<button
10+
name="report_label_associated_view"
11+
type="object"
12+
string="View QWeb templates"
13+
attrs="{'invisible':['|', ('state', '!=', 'report_label'), ('label_template', '=', False)]}"
14+
help="Display a button in the sidebar of related model to open a wizard"
15+
/>
16+
</header>
17+
<field name="type" position="after">
18+
<field name="label_paperformat_id" attrs="{'invisible': [('state', '!=', 'report_label')]}"/>
19+
<field name="label_template" attrs="{'invisible': [('state', '!=', 'report_label')]}"/>
20+
</field>
21+
</field>
22+
</record>
23+
24+
<record id="report_label_action" model="ir.actions.act_window">
25+
<field name="name">Label Reports</field>
26+
<field name="res_model">ir.actions.server</field>
27+
<field name="view_type">form</field>
28+
<field name="view_mode">tree,form</field>
29+
<field name="domain">[("state", "=", "report_label")]</field>
30+
<field name="context">{"default_state": "report_label"}</field>
31+
</record>
32+
33+
<menuitem
34+
id="report_label_menu"
35+
name="Label Reports"
36+
action="report_label_action"
37+
parent="base.reporting_menuitem"
38+
sequence="3"/>
39+
40+
</odoo>

0 commit comments

Comments
 (0)