mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
IMP sale_line_reconfigure Get _get_first_possible_combination faster by ordering by 'is_default'
This improves the performance greatly in ecommerce if you have MANY combinations and an exclusion on a high up attribute (as it will 'fail' potentially millions of combinations before coming to something that 'is_default' would have given you already).
This commit is contained in:
@@ -27,6 +27,7 @@ class ProductConfiguratorController(product_configurator.ProductConfiguratorCont
|
||||
'sale_line': sale_line,
|
||||
# get_attribute_exclusions deprecated, use product method
|
||||
'get_attribute_exclusions': self._get_attribute_exclusions,
|
||||
# get_attribute_value_defaults deprecated due to ecommerce templates
|
||||
'get_attribute_value_defaults': self._get_attribute_value_defaults,
|
||||
})
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from odoo import fields, models
|
||||
from odoo import api, fields, models, _
|
||||
|
||||
|
||||
class ProductTemplate(models.Model):
|
||||
@@ -40,6 +40,58 @@ class ProductTemplate(models.Model):
|
||||
|
||||
return attribute_values
|
||||
|
||||
"""
|
||||
This override will move 'default' attribute values to the top of the possible combinations to allow
|
||||
reasonable amount of time to get '_get_first_possible_combination' on a VERY large product configuration.
|
||||
"""
|
||||
@api.multi
|
||||
def _get_possible_combinations(self, parent_combination=None, necessary_values=None):
|
||||
"""Generator returning combinations that are possible, following the
|
||||
sequence of attributes and values.
|
||||
|
||||
See `_is_combination_possible` for what is a possible combination.
|
||||
|
||||
When encountering an impossible combination, try to change the value
|
||||
of attributes by starting with the further regarding their sequences.
|
||||
|
||||
Ignore attributes that have no values.
|
||||
|
||||
:param parent_combination: combination from which `self` is an
|
||||
optional or accessory product.
|
||||
:type parent_combination: recordset `product.template.attribute.value`
|
||||
|
||||
:param necessary_values: values that must be in the returned combination
|
||||
:type necessary_values: recordset of `product.template.attribute.value`
|
||||
|
||||
:return: the possible combinations
|
||||
:rtype: generator of recordset of `product.template.attribute.value`
|
||||
"""
|
||||
self.ensure_one()
|
||||
|
||||
if not self.active:
|
||||
return _("The product template is archived so no combination is possible.")
|
||||
|
||||
necessary_values = necessary_values or self.env['product.template.attribute.value']
|
||||
necessary_attributes = necessary_values.mapped('attribute_id')
|
||||
ptal_stack = [self.valid_product_template_attribute_line_ids.filtered(lambda ptal: ptal.attribute_id not in necessary_attributes)]
|
||||
combination_stack = [necessary_values]
|
||||
|
||||
# keep going while we have attribute lines to test
|
||||
while len(ptal_stack):
|
||||
attribute_lines = ptal_stack.pop()
|
||||
combination = combination_stack.pop()
|
||||
|
||||
if not attribute_lines:
|
||||
# full combination, if it's possible return it, otherwise skip it
|
||||
if self._is_combination_possible(combination, parent_combination):
|
||||
yield(combination)
|
||||
else:
|
||||
# we have remaining attribute lines to consider
|
||||
for ptav in reversed(attribute_lines[0].product_template_value_ids.sorted(lambda l: not l.is_default)):
|
||||
ptal_stack.append(attribute_lines[1:])
|
||||
combination_stack.append(combination + ptav)
|
||||
|
||||
return _("There are no remaining possible combination.")
|
||||
|
||||
class ProductTemplateAttributeValue(models.Model):
|
||||
_inherit = 'product.template.attribute.value'
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<template id="variants_inherit" inherit_id="sale.variants">
|
||||
<xpath expr="//t[@t-set='attribute_exclusions']" position="after">
|
||||
<t t-set="attribute_value_defaults" t-value="get_attribute_value_defaults(product, sale_line)"/>
|
||||
<t t-set="attribute_value_defaults" t-value="product.get_default_attribute_values(sale_line)"/>
|
||||
</xpath>
|
||||
<xpath expr="//t[@t-foreach='variant_id.product_template_value_ids']/option" position="attributes">
|
||||
<attribute name="t-att-data-is_custom">value_id.is_custom</attribute>
|
||||
|
||||
Reference in New Issue
Block a user