# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. from collections import defaultdict from odoo import _, models from odoo.exceptions import UserError def _prepare_data(env, docids, 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, ...) layout_wizard = env['product.label.layout'].browse(data.get('layout_wizard')) 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) elif data.get("studio") and docids: # special case: users trying to customize labels products = env['product.template'].with_context(display_default_code=False).browse(docids) quantity_by_product = defaultdict(list) for product in products: quantity_by_product[product].append((product.barcode, 1)) return { 'quantity': quantity_by_product, 'page_numbers': 1, 'pricelist': layout_wizard.pricelist_id, } else: raise UserError(_('Product model not defined, Please contact your administrator.')) if not layout_wizard: return {} total = 0 qty_by_product_in = data.get('quantity_by_product') # search for products all at once, ordered by name desc since popitem() used in xml to print the labels # is LIFO, which results in ordering by product name in the report products = Product.search([('id', 'in', [int(p) for p in qty_by_product_in.keys()])], order='name desc') quantity_by_product = defaultdict(list) for product in products: q = qty_by_product_in[str(product.id)] 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) return { 'quantity': quantity_by_product, 'page_numbers': (total - 1) // (layout_wizard.rows * layout_wizard.columns) + 1, 'price_included': data.get('price_included'), 'extra_html': layout_wizard.extra_html, 'pricelist': layout_wizard.pricelist_id, } class ReportProductTemplateLabel2x7(models.AbstractModel): _name = 'report.product.report_producttemplatelabel2x7' _description = 'Product Label Report 2x7' def _get_report_values(self, docids, data): return _prepare_data(self.env, docids, data) class ReportProductTemplateLabel4x7(models.AbstractModel): _name = 'report.product.report_producttemplatelabel4x7' _description = 'Product Label Report 4x7' def _get_report_values(self, docids, data): return _prepare_data(self.env, docids, data) class ReportProductTemplateLabel4x12(models.AbstractModel): _name = 'report.product.report_producttemplatelabel4x12' _description = 'Product Label Report 4x12' def _get_report_values(self, docids, data): return _prepare_data(self.env, docids, data) class ReportProductTemplateLabel4x12NoPrice(models.AbstractModel): _name = 'report.product.report_producttemplatelabel4x12noprice' _description = 'Product Label Report 4x12 No Price' def _get_report_values(self, docids, data): return _prepare_data(self.env, docids, data) class ReportProductTemplateLabelDymo(models.AbstractModel): _name = 'report.product.report_producttemplatelabel_dymo' _description = 'Product Label Report' def _get_report_values(self, docids, data): return _prepare_data(self.env, docids, data)