+
diff --git a/addons/stock/wizard/__init__.py b/addons/stock/wizard/__init__.py
index 78817d0422e..65d91a0abe3 100644
--- a/addons/stock/wizard/__init__.py
+++ b/addons/stock/wizard/__init__.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from . import product_label_layout
from . import stock_assign_serial_numbers
from . import stock_picking_return
from . import stock_change_product_qty
diff --git a/addons/stock/wizard/product_label_layout.py b/addons/stock/wizard/product_label_layout.py
new file mode 100644
index 00000000000..26824f54efe
--- /dev/null
+++ b/addons/stock/wizard/product_label_layout.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from collections import defaultdict
+from odoo import fields, models
+
+
+class ProductLabelLayout(models.TransientModel):
+ _inherit = 'product.label.layout'
+
+ move_line_ids = fields.Many2many('stock.move.line')
+ picking_quantity = fields.Selection([
+ ('picking', 'Transfer Quantities'),
+ ('custom', 'Custom')], string="Quantity to print", default='custom')
+ print_format = fields.Selection(selection_add=[
+ ('zpl', 'ZPL Labels'),
+ ('zplxprice', 'ZPL Labels with price')
+ ], ondelete={'zpl': 'set default', 'zplxprice': 'set default'})
+
+ def _prepare_report_data(self):
+ xml_id, data = super()._prepare_report_data()
+
+ if 'zpl' in self.print_format:
+ xml_id = 'stock.label_product_product'
+
+ if self.picking_quantity == 'picking' and self.move_line_ids:
+ qties = defaultdict(int)
+ uom_unit = self.env.ref('uom.product_uom_categ_unit', raise_if_not_found=False)
+ for line in self.move_line_ids:
+ if line.product_uom_id.category_id == uom_unit:
+ qties[line.product_id.id] += line.qty_done
+ # Pass only products with some quantity done to the report
+ data['quantity_by_product'] = {p: int(q) for p, q in qties.items() if q}
+ return xml_id, data
diff --git a/addons/stock/wizard/product_label_layout_views.xml b/addons/stock/wizard/product_label_layout_views.xml
new file mode 100644
index 00000000000..d53e2d3aaef
--- /dev/null
+++ b/addons/stock/wizard/product_label_layout_views.xml
@@ -0,0 +1,20 @@
+
+
+
+ product.label.layout.form
+ product.label.layout
+ primary
+ 25
+
+
+
+
+
+
+
+ {'invisible': [('picking_quantity', '=', 'picking')]}
+
+
+
+
+
diff --git a/addons/stock_picking_batch/models/stock_picking_batch.py b/addons/stock_picking_batch/models/stock_picking_batch.py
index 9aeb4832a47..d7f0047d458 100644
--- a/addons/stock_picking_batch/models/stock_picking_batch.py
+++ b/addons/stock_picking_batch/models/stock_picking_batch.py
@@ -233,6 +233,22 @@ class StockPickingBatch(models.Model):
action['context'] = {'default_picking_ids': self.picking_ids.ids}
return action
+ def action_open_label_layout(self):
+ view = self.env.ref('product.product_label_layout_form')
+ return {
+ 'name': _('Choose Labels Layout'),
+ 'type': 'ir.actions.act_window',
+ 'view_mode': 'form',
+ 'res_model': 'product.label.layout',
+ 'views': [(view.id, 'form')],
+ 'view_id': view.id,
+ 'target': 'new',
+ 'context': {
+ 'default_product_ids': self.move_lines.product_id.ids,
+ 'default_move_line_ids': self.move_line_ids.ids,
+ 'default_picking_quantity': 'picking'},
+ }
+
# -------------------------------------------------------------------------
# Miscellaneous
# -------------------------------------------------------------------------
diff --git a/addons/stock_picking_batch/views/stock_picking_batch_views.xml b/addons/stock_picking_batch/views/stock_picking_batch_views.xml
index d80eeb66cfe..8c056114ca4 100644
--- a/addons/stock_picking_batch/views/stock_picking_batch_views.xml
+++ b/addons/stock_picking_batch/views/stock_picking_batch_views.xml
@@ -102,6 +102,7 @@
('state', '!=', 'draft'),
('show_check_availability', '=', False)]}"/>
+
diff --git a/odoo/addons/base/models/ir_qweb_fields.py b/odoo/addons/base/models/ir_qweb_fields.py
index c0174f6a44d..7d82c53777b 100644
--- a/odoo/addons/base/models/ir_qweb_fields.py
+++ b/odoo/addons/base/models/ir_qweb_fields.py
@@ -451,6 +451,12 @@ class MonetaryConverter(models.AbstractModel):
else:
post = '\N{NO-BREAK SPACE}{symbol}'.format(symbol=display_currency.symbol or '')
+ if options.get('label_price'):
+ sep = lang.decimal_point
+ integer_part, decimal_part = formatted_amount.split(sep)
+ integer_part += sep
+ return M('{pre}
{0}{1}{post}').format(integer_part, decimal_part, pre=pre, post=post)
+
return M('{pre}
{0}{post}').format(formatted_amount, pre=pre, post=post)
@api.model