From d1dda79c2f400c3949a7fc8f387c414b6cda1ca5 Mon Sep 17 00:00:00 2001 From: Victor Feyens Date: Tue, 27 Jul 2021 11:39:20 +0000 Subject: [PATCH] [IMP] product: clean product pricelist report code & logic * Linting, typos & cleanup * Avoid using the context to pass data to the server * JS: let the web client service manage the data transfer instead of "manually" specifying it in the report_name closes odoo/odoo#73198 Signed-off-by: Yannick Tivisse (yti) --- .../report/product_pricelist_report.py | 71 ++++++++----------- .../product_pricelist_report_templates.xml | 2 +- .../static/src/js/product_pricelist_report.js | 43 ++++++----- 3 files changed, 59 insertions(+), 57 deletions(-) diff --git a/addons/product/report/product_pricelist_report.py b/addons/product/report/product_pricelist_report.py index 789fc411626..44463dd5f77 100644 --- a/addons/product/report/product_pricelist_report.py +++ b/addons/product/report/product_pricelist_report.py @@ -4,60 +4,44 @@ from odoo import api, models -class report_product_pricelist(models.AbstractModel): +class ProductPricelistReport(models.AbstractModel): _name = 'report.product.report_pricelist' _description = 'Pricelist Report' def _get_report_values(self, docids, data): - is_visible_title = data['is_visible_title'] and bool(data['is_visible_title']) or False - product_ids = [int(i) for i in data['active_ids'].split(',')] - pricelist_id = data['pricelist_id'] and int(data['pricelist_id']) or None - quantities = [int(i) for i in data['quantities'].split(',')] or [1] - return self._get_report_data(data['active_model'], product_ids, is_visible_title, pricelist_id, quantities, 'pdf') + return self._get_report_data(data, 'pdf') @api.model - def get_html(self): - render_values = self._get_report_data( - self.env.context.get('active_model'), - self.env.context.get('active_ids'), - self.env.context.get('is_visible_title'), - self.env.context.get('pricelist_id'), - self.env.context.get('quantities') or [1] - ) + def get_html(self, data): + render_values = self._get_report_data(data, 'html') return self.env.ref('product.report_pricelist_page')._render(render_values) - def _get_report_data(self, active_model, active_ids, is_visible_title, pricelist_id, quantities, report_type='html'): - products = [] - is_product_tmpl = active_model == 'product.template' + def _get_report_data(self, data, report_type='html'): + quantities = data['quantities'] or [1] - ProductClass = self.env['product.template'] if is_product_tmpl else self.env['product.product'] - ProductPricelist = self.env['product.pricelist'] - pricelist = ProductPricelist.browse(pricelist_id) + pricelist_id = data['pricelist_id'] and int(data['pricelist_id']) or None + pricelist = self.env['product.pricelist'].browse(pricelist_id).exists() if not pricelist: - pricelist = ProductPricelist.search([], limit=1) + pricelist = self.env['product.pricelist'].search([], limit=1) - if is_product_tmpl: - records = ProductClass.browse(active_ids) if active_ids else ProductClass.search([('sale_ok', '=', True)]) - for product in records: - product_data = self._get_product_data(is_product_tmpl, product, pricelist, quantities) - variants = [] - if len(product.product_variant_ids) > 1: - for variant in product.product_variant_ids: - variants.append(self._get_product_data(False, variant, pricelist, quantities)) - product_data['variants'] = variants - products.append(product_data) - else: - records = ProductClass.browse(active_ids) if active_ids else ProductClass.search([('sale_ok', '=', True)]) - for product in records: - products.append(self._get_product_data(is_product_tmpl, product, pricelist, quantities)) + active_model = data['active_model'] + active_ids = data.get('active_ids') or [] + is_product_tmpl = active_model == 'product.template' + ProductClass = self.env[active_model] + + products = ProductClass.browse(active_ids) if active_ids else ProductClass.search([('sale_ok', '=', True)]) + products_data = [ + self._get_product_data(is_product_tmpl, product, pricelist, quantities) + for product in products + ] return { - 'pricelist': pricelist, - 'products': products, - 'quantities': quantities, - 'is_product_tmpl': is_product_tmpl, 'is_html_type': report_type == 'html', - 'is_visible_title': is_visible_title, + 'is_product_tmpl': is_product_tmpl, + 'is_visible_title': bool(data['is_visible_title']) or False, + 'pricelist': pricelist, + 'products': products_data, + 'quantities': quantities, } def _get_product_data(self, is_product_tmpl, product, pricelist, quantities): @@ -69,4 +53,11 @@ class report_product_pricelist(models.AbstractModel): } for qty in quantities: data['price'][qty] = pricelist.get_product_price(product, qty, False) + + if is_product_tmpl and product.product_variant_count > 1: + data['variants'] = [ + self._get_product_data(False, variant, pricelist, quantities) + for variant in product.product_variant_ids + ] + return data diff --git a/addons/product/report/product_pricelist_report_templates.xml b/addons/product/report/product_pricelist_report_templates.xml index 3b13ed591c4..761005fb653 100644 --- a/addons/product/report/product_pricelist_report_templates.xml +++ b/addons/product/report/product_pricelist_report_templates.xml @@ -53,7 +53,7 @@ - + diff --git a/addons/product/static/src/js/product_pricelist_report.js b/addons/product/static/src/js/product_pricelist_report.js index bb4095ccccb..918de273e16 100644 --- a/addons/product/static/src/js/product_pricelist_report.js +++ b/addons/product/static/src/js/product_pricelist_report.js @@ -109,19 +109,19 @@ var GeneratePriceList = AbstractAction.extend(StandaloneFieldManagerMixin, { * @override */ willStart: function () { - let getPricelit; + let getPricelist; // started without a selected pricelist in context? just get the first one if (this.context.default_pricelist) { - getPricelit = Promise.resolve([this.context.default_pricelist]); + getPricelist = Promise.resolve([this.context.default_pricelist]); } else { - getPricelit = this._rpc({ + getPricelist = this._rpc({ model: 'product.pricelist', method: 'search', args: [[]], kwargs: {limit: 1} - }) + }); } - const fieldSetup = getPricelit.then(pricelistIds => { + const fieldSetup = getPricelist.then(pricelistIds => { return this.model.makeRecord('report.product.report_pricelist', [{ name: 'pricelist_id', type: 'many2one', @@ -158,12 +158,12 @@ var GeneratePriceList = AbstractAction.extend(StandaloneFieldManagerMixin, { * the proper context. * @override */ - getState: function() { + getState: function () { return { active_model: this.context.active_model, }; }, - getTitle: function() { + getTitle: function () { return _t('Pricelist Report'); }, @@ -171,6 +171,21 @@ var GeneratePriceList = AbstractAction.extend(StandaloneFieldManagerMixin, { // Private //-------------------------------------------------------------------------- + /** + * Returns the expected data for the report rendering call (html or pdf) + * + * @private + * @returns {Object} + */ + _prepareActionReportParams: function () { + return { + active_model: this.context.active_model, + active_ids: this.context.active_ids, + is_visible_title: this.context.is_visible_title || '', + pricelist_id: this.context.pricelist_id || '', + quantities: this.context.quantities || [1], + }; + }, /** * Get template to display report. * @@ -181,7 +196,9 @@ var GeneratePriceList = AbstractAction.extend(StandaloneFieldManagerMixin, { return this._rpc({ model: 'report.product.report_pricelist', method: 'get_html', - kwargs: {context: this.context}, + kwargs: { + data: this._prepareActionReportParams(), + }, }).then(result => { this.reportHtml = result; }); @@ -253,18 +270,12 @@ var GeneratePriceList = AbstractAction.extend(StandaloneFieldManagerMixin, { * @private */ _onClickPrint: function () { - const reportName = _.str.sprintf('product.report_pricelist?active_model=%s&active_ids=%s&is_visible_title=%s&pricelist_id=%s&quantities=%s', - this.context.active_model, - this.context.active_ids, - this.context.is_visible_title || '', - this.context.pricelist_id || '', - this.context.quantities.toString() || '1', - ); return this.do_action({ type: 'ir.actions.report', report_type: 'qweb-pdf', - report_name: reportName, + report_name: 'product.report_pricelist', report_file: 'product.report_pricelist', + data: this._prepareActionReportParams(), }); }, /**