When printing labels in a `ready` picking, if no quantities are set it will only print the reserved quantities as labels. Then, if a product has no reserved quantity, it will not have any move_lines. Which means its initial demand won't be able to be fetched, and the default behavior will be used, which is to print a single label. By giving the moves instead of the move_lines to the wizard, we allow to fetch for moves that have no reservation and print labels correctly using their initial demand if no reservation is found. The standard behavior once quantities are set remains untouched. closes odoo/odoo#106414 Related: odoo/upgrade#4091 Signed-off-by: William Henrotin (whe) <whe@odoo.com>
48 lines
2.5 KiB
Python
48 lines
2.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from collections import defaultdict
|
|
from odoo import fields, models
|
|
from odoo.tools import float_compare, float_is_zero
|
|
|
|
class ProductLabelLayout(models.TransientModel):
|
|
_inherit = 'product.label.layout'
|
|
|
|
move_ids = fields.Many2many('stock.move')
|
|
picking_quantity = fields.Selection([
|
|
('picking', 'Transfer Quantities'),
|
|
('custom', 'Custom')], string="Quantity to print", required=True, 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'
|
|
|
|
quantities = defaultdict(int)
|
|
uom_unit = self.env.ref('uom.product_uom_categ_unit', raise_if_not_found=False)
|
|
if self.picking_quantity == 'picking' and self.move_ids and all(float_is_zero(ml.qty_done, precision_rounding=ml.product_uom_id.rounding) for ml in self.move_ids.move_line_ids):
|
|
for move in self.move_ids:
|
|
if move.product_uom.category_id == uom_unit:
|
|
use_reserved = float_compare(move.reserved_availability, 0, precision_rounding=move.product_uom.rounding) > 0
|
|
useable_qty = move.reserved_availability if use_reserved else move.product_uom_qty
|
|
if not float_is_zero(useable_qty, precision_rounding=move.product_uom.rounding):
|
|
quantities[move.product_id.id] += useable_qty
|
|
data['quantity_by_product'] = {p: int(q) for p, q in quantities.items()}
|
|
elif self.picking_quantity == 'picking' and self.move_ids.move_line_ids:
|
|
custom_barcodes = defaultdict(list)
|
|
for line in self.move_ids.move_line_ids:
|
|
if line.product_uom_id.category_id == uom_unit:
|
|
if (line.lot_id or line.lot_name) and int(line.qty_done):
|
|
custom_barcodes[line.product_id.id].append((line.lot_id.name or line.lot_name, int(line.qty_done)))
|
|
continue
|
|
quantities[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 quantities.items() if q}
|
|
data['custom_barcodes'] = custom_barcodes
|
|
return xml_id, data
|