[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) <yti@odoo.com>
This commit is contained in:
Victor Feyens
2021-08-23 09:33:19 +00:00
committed by Yannick Tivisse
parent 1ad72def2a
commit d1dda79c2f
3 changed files with 59 additions and 57 deletions
@@ -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
@@ -53,7 +53,7 @@
</td>
</t>
</tr>
<t t-if="is_product_tmpl">
<t t-if="is_product_tmpl and 'variants' in product">
<tr t-foreach="product['variants']" t-as="variant">
<td>
<a t-if="is_html_type" href="#" class="o_action ml-4" data-model="product.product" t-att-data-res-id="variant['id']">
@@ -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(),
});
},
/**