# Copyright © 2018 Garazd Creation () # @author: Yurii Razumovskyi () # @author: Iryna Razumovska () # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0.html). import base64 from typing import List from odoo import api, fields, models, _ from odoo.exceptions import UserError from odoo.addons.base.models.res_partner import _lang_get class PrintProductLabel(models.TransientModel): _name = "print.product.label" _description = 'Wizard to print Product Labels' @api.model def _complete_label_fields(self, label_ids: List[int]) -> List[int]: """Set additional fields for product labels. Method to override.""" # Increase a label sequence labels = self.env['print.product.label.line'].browse(label_ids) for seq, label in enumerate(labels): label.sequence = 1000 + seq return label_ids @api.model def _get_product_label_ids(self): res = [] # flake8: noqa: E501 if self._context.get('active_model') == 'product.template': products = self.env[self._context.get('active_model')].browse( self._context.get('default_product_template_ids') ) for product in products: label = self.env['print.product.label.line'].create({ 'product_id': product.product_variant_id.id, }) res.append(label.id) elif self._context.get('active_model') == 'product.product': products = self.env[self._context.get('active_model')].browse( self._context.get('default_product_product_ids') ) for product in products: label = self.env['print.product.label.line'].create({'product_id': product.id}) res.append(label.id) res = self._complete_label_fields(res) return res @api.model def default_get(self, fields_list): default_vals = super(PrintProductLabel, self).default_get(fields_list) if 'label_type_id' in fields_list and not default_vals.get('label_type_id'): default_vals['label_type_id'] = self.env.ref('garazd_product_label.type_product').id return default_vals name = fields.Char(default='Print Product Labels') message = fields.Char(readonly=True) output = fields.Selection(selection=[('pdf', 'PDF')], string='Print to', default='pdf') mode = fields.Selection( selection=[('product.product', 'Products')], help='Technical field to specify the mode of the label printing wizard.', default='product.product', ) label_type_id = fields.Many2one(comodel_name='print.label.type', string='Label Type') label_ids = fields.One2many( comodel_name='print.product.label.line', inverse_name='wizard_id', string='Labels for Products', default=_get_product_label_ids, ) report_id = fields.Many2one( comodel_name='ir.actions.report', string='Label', domain=[('model', '=', 'print.product.label.line')], ) is_template_report = fields.Boolean(compute='_compute_is_template_report') qty_per_product = fields.Integer( string='Label quantity per product', default=1, ) # Options humanreadable = fields.Boolean( string='Human readable barcode', help='Print digital code of barcode.', default=False, ) border_width = fields.Integer( string='Border', help='Border width for labels (in pixels). Set "0" for no border.' ) lang = fields.Selection( selection=_lang_get, string='Language', help="The language that will be used to translate label names.", ) company_id = fields.Many2one( comodel_name='res.company', help='Specify a company for product labels.' ) @api.depends('report_id') def _compute_is_template_report(self): for wizard in self: # flake8: noqa: E501 wizard.is_template_report = self.report_id == self.env.ref('garazd_product_label.action_report_product_label_from_template') def get_labels_to_print(self): self.ensure_one() labels = self.label_ids.filtered(lambda l: l.selected and l.qty) if not labels: raise UserError(_('Nothing to print, set the quantity of labels in the table.')) return labels def _get_report_action_params(self): """Return two params for a report action: record "ids" and "data".""" self.ensure_one() return self.get_labels_to_print().ids, None def _prepare_report(self): self.ensure_one() output_mode = self._context.get('print_mode', 'pdf') if not self.report_id: raise UserError(_('Please select a label type.')) report = self.report_id.with_context(discard_logo_check=True, lang=self.lang) report.sudo().write({'report_type': f'qweb-{output_mode}'}) return report def action_print(self): """Print labels.""" self.ensure_one() report = self._prepare_report() return report.report_action(*self._get_report_action_params()) def action_set_qty(self): """Set a specific number of labels for all lines.""" self.ensure_one() self.label_ids.write({'qty': self.qty_per_product}) def action_restore_initial_qty(self): """Restore the initial number of labels for all lines.""" self.ensure_one() for label in self.label_ids: if label.qty_initial: label.update({'qty': label.qty_initial}) @api.model def get_quick_report_action( self, model_name: str, ids: List[int], qty: int = None, template=None, force_direct: bool = False, ): """ Allow to get a report action for custom labels. Method to override. """ wizard = self.with_context( **{'active_model': model_name, f'default_{model_name.replace(".", "_")}_ids': ids} ).create({'report_id': self.env.ref('garazd_product_label.action_report_product_label_50x38').id}) return wizard.action_print() @api.model def _set_sequence(self, lbl, seq, processed): if lbl in processed: return seq, processed lbl.sequence = seq seq += 1 processed += lbl return seq, processed def action_sort_by_product(self): self.ensure_one() sequence = 1000 processed_labels = self.env['print.product.label.line'].browse() # flake8: noqa: E501 for label in self.label_ids: sequence, processed_labels = self._set_sequence(label, sequence, processed_labels) tmpl_labels = self.label_ids.filtered(lambda l: l.product_id.product_tmpl_id == label.product_id.product_tmpl_id).sorted(lambda l: l.product_id.id, reverse=True) - label for tmpl_label in tmpl_labels: sequence, processed_labels = self._set_sequence(tmpl_label, sequence, processed_labels) product_labels = tmpl_labels.filtered(lambda l: l.product_id == label.product_id) - tmpl_label for product_label in product_labels: sequence, processed_labels = self._set_sequence(product_label, sequence, processed_labels) def get_pdf(self): self.ensure_one() report = self.with_context(print_mode='pdf')._prepare_report() pdf_data = report._render_qweb_pdf(report, *self._get_report_action_params()) return base64.b64encode(pdf_data[0])