product_matrix/models/product_template.py

86 lines
3.4 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import itertools
from odoo import models, fields
class ProductTemplate(models.Model):
_inherit = 'product.template'
def _get_template_matrix(self, **kwargs):
self.ensure_one()
company_id = kwargs.get('company_id', None) or self.company_id or self.env.company
currency_id = kwargs.get('currency_id', None) or self.currency_id
display_extra = kwargs.get('display_extra_price', False)
attribute_lines = self.valid_product_template_attribute_line_ids
Attrib = self.env['product.template.attribute.value']
first_line_attributes = attribute_lines[0].product_template_value_ids._only_active()
attribute_ids_by_line = [line.product_template_value_ids._only_active().ids for line in attribute_lines]
header = [{"name": self.display_name}] + [
attr._grid_header_cell(
fro_currency=self.currency_id,
to_currency=currency_id,
company=company_id,
display_extra=display_extra
) for attr in first_line_attributes]
result = [[]]
for pool in attribute_ids_by_line:
result = [x + [y] for y in pool for x in result]
args = [iter(result)] * len(first_line_attributes)
rows = itertools.zip_longest(*args)
matrix = []
for row in rows:
row_attributes = Attrib.browse(row[0][1:])
row_header_cell = row_attributes._grid_header_cell(
fro_currency=self.currency_id,
to_currency=currency_id,
company=company_id,
display_extra=display_extra)
result = [row_header_cell]
for cell in row:
combination = Attrib.browse(cell)
is_possible_combination = self._is_combination_possible(combination)
cell.sort()
result.append({
"ptav_ids": cell,
"qty": 0,
"is_possible_combination": is_possible_combination
})
matrix.append(result)
return {
"header": header,
"matrix": matrix,
}
class ProductTemplateAttributeValue(models.Model):
_inherit = "product.template.attribute.value"
def _grid_header_cell(self, fro_currency, to_currency, company, display_extra=True):
"""Generate a header matrix cell for 1 or multiple attributes.
:param res.currency fro_currency:
:param res.currency to_currency:
:param res.company company:
:param bool display_extra: whether extra prices should be displayed in the cell
True by default, used to avoid showing extra prices on purchases.
:returns: cell with name (and price if any price_extra is defined on self)
:rtype: dict
"""
header_cell = {
'name': ''.join([attr.name for attr in self]) if self else " "
} # The " " is to avoid having 'Not available' if the template has only one attribute line.
extra_price = sum(self.mapped('price_extra')) if display_extra else 0
if extra_price:
header_cell['currency_id'] = to_currency.id
header_cell['price'] = fro_currency._convert(
extra_price, to_currency, company, fields.Date.today())
return header_cell