Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions product_label_image/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
===================
Product Label Image
===================

Product barcode print with product image
1 change: 1 addition & 0 deletions product_label_image/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import reports, wizard
18 changes: 18 additions & 0 deletions product_label_image/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "Product Label Image",
"category": "other",
"version": "18.0.1.0.1",
"summary": """Prints product barcode along with product image""",
"author": "Nitrokey GmbH",
"website": "https://github.com/Nitrokey/odoo-modules",
"license": "AGPL-3",
"depends": ["product"],
"data": [
"reports/product_template_report.xml",
],
"assets": {
"web.report_assets_common": [
"product_label_image/static/src/scss/product_label_image.scss"
],
},
}
1 change: 1 addition & 0 deletions product_label_image/reports/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import product_label_report
50 changes: 50 additions & 0 deletions product_label_image/reports/product_label_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from collections import defaultdict

from odoo import _, models
from odoo.exceptions import UserError


def _prepare_data(env, data):
# change product ids by actual product object to get access to fields in xml
# template we needed to pass ids because reports only accepts native python
# types (int, float, strings, ...)
if data.get("active_model") == "product.template":
Product = env["product.template"].with_context(display_default_code=False)
elif data.get("active_model") == "product.product":
Product = env["product.product"].with_context(display_default_code=False)
else:
raise UserError(
_("Product model not defined, Please contact your administrator.")
)

total, quantity_by_product = 0, defaultdict(list)
for p, q in data.get("quantity_by_product", {}).items():
product = Product.browse(int(p))
quantity_by_product[product].append((product.barcode, q))
total += q
if data.get("custom_barcodes"):
# we expect custom barcodes format as: {product: [(barcode, qty_of_barcode)]}
for product, barcodes_qtys in data.get("custom_barcodes").items():
quantity_by_product[Product.browse(int(product))] += barcodes_qtys
total += sum(qty for _, qty in barcodes_qtys)

layout_wizard = env["product.label.layout"].browse(data.get("layout_wizard"))
if not layout_wizard:
return {}

return {
"quantity": quantity_by_product,
"rows": layout_wizard.rows,
"columns": layout_wizard.columns,
"page_numbers": (total - 1) // (layout_wizard.rows * layout_wizard.columns) + 1,
"price_included": data.get("price_included"),
"extra_html": layout_wizard.extra_html,
}


class ReportProductTemplateLabelImage4x6(models.AbstractModel):
_name = "report.product_label_image.producttemplatelabel_image_4x6"
_description = "Product Label Report"

def _get_report_values(self, docids, data):
return _prepare_data(self.env, data)
76 changes: 76 additions & 0 deletions product_label_image/reports/product_template_report.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<template id="report_simple_label_image_4x6">
<tr>
<td t-att-style="make_invisible and 'visibility:hidden;'">
<div class="row o_firstdiv">
<div class="o_seconddiv">
<div class="o_thirddiv">
<strong t-field="product.display_name" />
</div>
<div class="text-center">
<t t-if="barcode">
<div
class="o_barcode"
t-out="barcode"
t-options="{'widget': 'barcode', 'symbology': 'auto', 'img_style': 'width:71mm; height:15mm;'}"
/>
<span class="text-center" t-out="barcode" />
</t>
</div>
</div>
<t t-if="product and product.image_512">
<div class="o_product_img_div1">
<div class="text-center align-middle img_div2">
<img
class="o_product_picture"
t-att-src="image_data_uri(product.image_512)"
t-attf-style="max-width: 100%; max-height: 100%; object-fit: contain;"
/>
</div>
</div>
</t>
</div>
</td>
</tr>
</template>

<template id="report_productlabel_image_4x6">
<t t-call="web.html_container">
<t t-foreach="quantity.items()" t-as="barcode_and_qty_by_product">
<t t-set="product" t-value="barcode_and_qty_by_product[0]" />
<t t-foreach="barcode_and_qty_by_product[1]" t-as="barcode_and_qty">
<t t-set="barcode" t-value="barcode_and_qty[0]" />
<t t-foreach="range(barcode_and_qty[1])" t-as="qty">
<t t-call="product_label_image.report_simple_label_image_4x6" />
</t>
</t>
</t>
</t>
</template>

<template id="producttemplatelabel_image_4x6">
<t t-call="web.basic_layout">
<div class="page">
<t t-call="product_label_image.report_productlabel_image_4x6">
<t t-set="products" t-value="products" />
</t>
</div>
</t>
</template>

<record id="report_product_label_image_4x6" model="ir.actions.report">
<field name="name">Product Label (PDF)</field>
<field name="model">product.template</field>
<field name="report_type">qweb-pdf</field>
<field
name="report_name"
>product_label_image.producttemplatelabel_image_4x6</field>
<field
name="report_file"
>product_label_image.producttemplatelabel_image_4x6</field>
<field name="paperformat_id" ref="product.paperformat_label_sheet" />
<field name="print_report_name">'Products Labels - %s' % (object.name)</field>
<field name="binding_type">report</field>
</record>
</odoo>
37 changes: 37 additions & 0 deletions product_label_image/static/src/scss/product_label_image.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
div {
&.o_firstdiv {
width: 100%;
margin-bottom: 200px;
}
&.o_seconddiv {
width: 310px;
height: 210px;
border: 2px solid #555555 !important;
padding: 2px 4px;
}
&.o_thirddiv {
height: 86px;
margin-bottom: 18px;
overflow: hidden;
& > strong {
font-size: 16px;
}
}
&.o_barcode {
padding: 5px;
}
&.o_product_img_div1 {
width: 310px;
height: 210px;
border: 2px solid #555555;
border-left: 1px;
}
&.img_div2 {
height: 10rem;
}
& > img.o_product_picture {
height: 190px;
width: auto;
margin-top: 8%;
}
}
1 change: 1 addition & 0 deletions product_label_image/wizard/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import product_label_layout
39 changes: 39 additions & 0 deletions product_label_image/wizard/product_label_layout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from odoo import _, fields, models
from odoo.exceptions import UserError


class ProductLabelLayout(models.TransientModel):
_inherit = "product.label.layout"

print_format = fields.Selection(
selection_add=[("4x6", "4x6")],
default="4x6",
ondelete={"4x6": "set default"},
)

def _prepare_report_data(self):
if self.custom_quantity <= 0:
raise UserError(_("You need to set a positive quantity."))

# Get layout grid
if self.print_format != "4x6":
return super()._prepare_report_data()

xml_id = "product_label_image.report_product_label_image_4x6"

active_model = ""
if self.product_tmpl_ids:
products = self.product_tmpl_ids.ids
active_model = "product.template"
elif self.product_ids:
products = self.product_ids.ids
active_model = "product.product"

# Build data to pass to the report
data = {
"active_model": active_model,
"quantity_by_product": {p: self.custom_quantity for p in products},
"layout_wizard": self.id,
"price_included": "xprice" in self.print_format,
}
return xml_id, data