from odoo import models, fields, _ from odoo.exceptions import UserError class StockPicking(models.Model): _inherit = 'stock.picking' def _compute_has_printable_lots(self): for picking in self: picking.has_printable_lots = any(picking.move_line_ids.mapped('lot_id')) has_printable_lots = fields.Boolean(compute='_compute_has_printable_lots') def action_print_citizen_label(self): self.ensure_one() if self.state != 'done': raise UserError(_("You can only print labels for done pickings.")) # Filter lines with lots move_lines_with_lots = self.move_line_ids.filtered(lambda ml: ml.lot_id) if not move_lines_with_lots: raise UserError(_("No lots found in this picking to print.")) # Group by lots to avoid duplicates if needed, or just print all lines? # Usually one label per lot. lot_ids = move_lines_with_lots.mapped('lot_id') if not lot_ids: raise UserError(_("No lots found.")) # Create Wizard wizard_vals = { 'picking_id': self.id, 'line_ids': [], } # Use set to avoid duplicates if move_lines map to same lot multiple times # But we want to preserve order if possible or just use unique lots unique_lots = list(set(lot_ids)) for lot in unique_lots: wizard_vals['line_ids'].append((0, 0, { 'lot_id': lot.id, 'quantity': 1, })) wizard = self.env['citizen.printer.wizard'].create(wizard_vals) return { 'name': _('Print ZPL Labels'), 'type': 'ir.actions.act_window', 'view_mode': 'form', 'res_model': 'citizen.printer.wizard', 'res_id': wizard.id, 'target': 'new', }