Skip to content
This repository has been archived by the owner on Apr 28, 2022. It is now read-only.

Commit

Permalink
[IMP+FIX] 12.0 - Session fixes and attribute invisible on 0 available…
Browse files Browse the repository at this point in the history
… values (#174)

* [FIX]remove first line for the license and add comments

* [FIX]flake8

* [FIX]fix test

* [FIX]fix test case for onchange_attribute

* Make the config_session store json-serializable / string key vs int & search by passed user_id (if any

* Fix missing session update in cfg_session method

* Removing unused variables

* [FIX]hide attribute if no value is available

* [FIX]add field invisible to hide attribute when boolean ticked and no value is available

* [FIX]change attribute name

* [FIX]hide not availble attributes in backend wizard

Co-authored-by: Shruti Singh <[email protected]>
  • Loading branch information
PCatinean and bizzappdev authored Jul 1, 2020
1 parent c244fbb commit 785923c
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 23 deletions.
13 changes: 13 additions & 0 deletions product_configurator/models/product_attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ def onchange_val_custom_field(self):
string='Unit of Measure'
)
image = fields.Binary(string='Image')
hide = fields.Boolean(
string="Invisible",
help="Set in order to make attribute invisible, "
"when there is no available attribute values, in the configuration "
"interface"
)

# TODO prevent the same attribute from being defined twice on the
# attribute lines
Expand Down Expand Up @@ -159,6 +165,7 @@ def onchange_attribute(self):
self.required = self.attribute_id.required
self.multi = self.attribute_id.multi
self.custom = self.attribute_id.val_custom
self.hide = self.attribute_id.hide
# TODO: Remove all dependencies pointed towards the attribute being
# changed

Expand Down Expand Up @@ -189,6 +196,12 @@ def onchange_values(self):
comodel_name='product.template.attribute.value',
search="_search_product_template_value_ids"
)
hide = fields.Boolean(
string="Invisible",
help="Set in order to make attribute invisible, "
"when there is no available attribute values, in the configuration "
"interface"
)
# TODO: Constraint not allowing introducing dependencies that do not exist
# on the product.template

Expand Down
16 changes: 11 additions & 5 deletions product_configurator/models/product_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -911,10 +911,14 @@ def get_variant_vals(self, value_ids=None, custom_vals=None, **kwargs):

@api.multi
def get_session_search_domain(self, product_tmpl_id, state='draft',
parent_id=None):
parent_id=None, user_id=None):

if not user_id:
user_id = self.env.uid

domain = [
('product_tmpl_id', '=', product_tmpl_id),
('user_id', '=', self.env.uid),
('user_id', '=', user_id),
('state', '=', state),
]
if parent_id:
Expand Down Expand Up @@ -1422,10 +1426,11 @@ def search_variant(
return products

@api.multi
def search_session(self, product_tmpl_id, parent_id=None):
def search_session(self, product_tmpl_id, parent_id=None, user_id=None):
domain = self.get_session_search_domain(
product_tmpl_id=product_tmpl_id,
parent_id=parent_id
parent_id=parent_id,
user_id=user_id
)
session = self.search(domain, order='create_date desc', limit=1)
return session
Expand All @@ -1436,7 +1441,8 @@ def create_get_session(self, product_tmpl_id, parent_id=None,
if not force_create:
session = self.search_session(
product_tmpl_id=product_tmpl_id,
parent_id=parent_id
parent_id=parent_id,
user_id=user_id,
)
if session:
return session
Expand Down
30 changes: 26 additions & 4 deletions product_configurator/tests/test_product_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,19 +544,41 @@ def test_18_onchange_attribute(self):
})
self.productConfigDomainId.compute_domain()
# create attribute value line 1
config_line = self.env['product.config.line'].create({
self.env['product.config.line'].create({
'product_tmpl_id': self.product_tmpl_id.id,
'attribute_line_id': self.attributeLine1.id,
'value_ids': [(6, 0, [
self.attribute_vals_1.id,
self.attribute_vals_2.id])],
'domain_id': self.productConfigDomainId.id
})
with self.assertRaises(ValidationError):
config_line.onchange_attribute()

line_vals = {
'product_tmpl_id': self.product_tmpl_id.id,
'attribute_line_id': self.attributeLine1.id,
'value_ids': [(6, 0, [
self.attribute_vals_1.id,
self.attribute_vals_2.id])],
'domain_id': self.productConfigDomainId.id
}
order_line_obj = self.env['product.config.line']
specs = order_line_obj._onchange_spec()
updates = order_line_obj.onchange(
line_vals, ['attribute_line_id'], specs
)
values = updates.get('value', {})
for name, val in values.items():
if isinstance(val, tuple):
values[name] = val[0]

self.assertFalse(
config_line.value_ids,
values.get('domain_id'),
'Error: If value_ids True\
Method: onchange_attribute()'
)
self.assertEqual(
values.get('value_ids')[0],
(5,),
'Error: If value_ids True\
Method: onchange_attribute()'
)
Expand Down
1 change: 1 addition & 0 deletions product_configurator/views/product_attribute_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
<group>
<group>
<!--<field name="type"/> -->
<field name="hide"/>
<field name="required"/>
<field name="multi" attrs="{'readonly': [('val_custom','=',True)]}" force_save="1"/>
<field name="val_custom" attrs="{'readonly': [('multi', '=', True)]}" force_save="1"/>
Expand Down
1 change: 1 addition & 0 deletions product_configurator/views/product_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
context="{'show_attribute': False}"
options="{'no_create': True, 'no_create_edit': True}"
invisible="not context.get('default_config_ok', False)"/>
<field name="hide" invisible="not context.get('default_config_ok', False)"/>
<field name="required" invisible="not context.get('default_config_ok', False)"/>
<field name="multi" invisible="not context.get('default_config_ok', False)" attrs="{'readonly': [('custom','=',True)]}" force_save="1"/>
<field name="custom" invisible="not context.get('default_config_ok', False)" attrs="{'readonly': [('multi','=',True)]}" force_save="1"/>
Expand Down
4 changes: 4 additions & 0 deletions product_configurator/wizard/product_configurator.py
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,10 @@ def add_dynamic_fields(self, res, dynamic_fields, wiz):
attrs['readonly'].append(
(dependee_field, 'not in', list(val_ids)))

if not attr_line.custom and attr_line.hide:
attrs['invisible'].append(
(dependee_field, 'not in', list(val_ids)))

if attr_line.required and not attr_line.custom:
attrs['required'].append(
(dependee_field, 'in', list(val_ids)))
Expand Down
14 changes: 7 additions & 7 deletions website_product_configurator/controllers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def get_config_session(self, product_tmpl_id):
{}
)
is_public_user = request.env.user.has_group('base.group_public')
cfg_session_id = product_config_sessions.get(product_tmpl_id.id)
cfg_session_id = product_config_sessions.get(str(product_tmpl_id.id))
if cfg_session_id:
cfg_session = cfg_session_obj.browse(int(cfg_session_id))

Expand All @@ -42,7 +42,7 @@ def get_config_session(self, product_tmpl_id):
user_id=request.env.user.id
)
product_config_sessions.update({
product_tmpl_id.id: cfg_session.id
str(product_tmpl_id.id): cfg_session.id
})
request.session['product_config_session'] = product_config_sessions

Expand Down Expand Up @@ -513,12 +513,12 @@ def cfg_session(self, product_id, **post):
key=lambda obj: obj.attribute_id.sequence
)
pricelist = get_pricelist()
product_config_session = request.session.get('product_config_session')
if (product_config_session and
product_config_session.get(product_tmpl_id.id)):

product_config_session = request.session.get(
'product_config_session', {}
)
if product_config_session.get(str(product_tmpl_id.id)):
# Bizzappdev end code
del product_config_session[product_tmpl_id.id]
del product_config_session[str(product_tmpl_id.id)]
request.session['product_config_session'] = product_config_session
values = {
'product_id': product_id,
Expand Down
14 changes: 8 additions & 6 deletions website_product_configurator/data/config_form_templates.xml
Original file line number Diff line number Diff line change
Expand Up @@ -277,16 +277,17 @@
<t t-set="custom_field_prefix" t-value="prefixes.get('custom_field_prefix')"/>
<t t-foreach="cfg_step_attribute_line_ids" t-as="line">
<t t-set="custom_value" t-value="custom_value_ids.filtered(lambda x, line=line: x.attribute_id == line.attribute_id)"/>
<t t-set="available_val" t-value="any(val.id in available_value_ids for val in line.value_ids)"/>
<div t-att-class="'attribute_container'">
<t t-set="available_val" t-value="any(val in available_value_ids for val in (line.value_ids.ids + (line.custom and [custom_val_id.id] or [])))"/>
<div t-att-class="'attribute_container' + ((not available_val and line.hide) and ' d-none' or '')">
<label class="control-label" t-esc="line.attribute_id.name" t-att-data-oe-id="line.attribute_id.id"></label>
<select t-att-id="'%s%s' % (field_prefix, line.attribute_id.id)"
t-att-data-oe-id="line.attribute_id.id"
t-att-data-attr-required="line.required"
t-att-multiple="'multiple' if line.multi else None"
t-att-name="'%s%s' % (field_prefix, line.attribute_id.id)"
t-att-class="'form-control config_attribute' + (' required_config_attrib' if (not available_val and line.required and line.custom) or (available_val and line.required) else '') + (' d-none' if not line.value_ids else '')"
t-att-data-old-val-id="(value_ids &amp; line.value_ids) and (value_ids &amp; line.value_ids).ids[0] or ''">
t-att-data-old-val-id="(value_ids &amp; line.value_ids) and (value_ids &amp; line.value_ids).ids[0] or ''"
t-att-data-attr-hide="line.hide">

<!-- t-att-disabled="'disabled' if not available_val_ids and not line.custom else None" -->
<option name=""/>
Expand Down Expand Up @@ -337,16 +338,17 @@
<t t-set="custom_field_prefix" t-value="prefixes.get('custom_field_prefix')"/>
<t t-foreach="cfg_step_attribute_line_ids" t-as="line">
<t t-set="custom_value" t-value="custom_value_ids.filtered(lambda x, line=line: x.attribute_id == line.attribute_id)"/>
<t t-set="available_val" t-value="any(val.id in available_value_ids for val in line.value_ids)"/>
<div t-att-class="'attribute_container'">
<t t-set="available_val" t-value="any(val in available_value_ids for val in (line.value_ids.ids + (line.custom and [custom_val_id.id] or [])))"/>
<div t-att-class="'attribute_container' + ((not available_val and line.hide) and ' d-none' or '')">
<label class="control-label" t-esc="line.attribute_id.name" t-att-data-oe-id="line.attribute_id.id"></label>
<fieldset t-att-id="'%s%s' % (field_prefix, line.attribute_id.id)"
t-att-data-oe-id="line.attribute_id.id"
t-att-data-attr-required="line.required"
t-att-name="'%s%s' % (field_prefix, line.attribute_id.id)"
t-att-class="'form-control config_attribute' + (' required_config_attrib' if (not available_val and line.required and line.custom) or (available_val and line.required) else '') + (' d-none' if not line.value_ids else '')"
style="height: unset;"
t-att-data-old-val-id="(value_ids &amp; line.value_ids) and (value_ids &amp; line.value_ids).ids[0] or ''">
t-att-data-old-val-id="(value_ids &amp; line.value_ids) and (value_ids &amp; line.value_ids).ids[0] or ''"
t-att-data-attr-hide="line.hide">
<t t-foreach="line.value_ids" t-as="value">
<div class="radio-card-container">
<div class="info_config_attr_value_radio">
Expand Down
6 changes: 5 additions & 1 deletion website_product_configurator/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
from odoo import api, models, _
from odoo.http import request
Expand All @@ -17,6 +16,7 @@ def _cart_update(self, product_id=None, line_id=None,
self.ensure_one()
product_context = dict(self.env.context)
product_context.setdefault('lang', self.sudo().partner_id.lang)
# BizzAppDev Customization
cfg_product = self.env['product.product'].with_context(
product_context
).browse(int(product_id))
Expand All @@ -28,6 +28,7 @@ def _cart_update(self, product_id=None, line_id=None,
set_qty=set_qty,
kwargs=kwargs
)
# BizzAppDev Customization End

SaleOrderLineSudo = self.env['sale.order.line'].sudo().\
with_context(product_context)
Expand Down Expand Up @@ -85,9 +86,11 @@ def _cart_update(self, product_id=None, line_id=None,
combination = product_template._get_closest_possible_combination(
received_combination)

# BizzAppDev Customization
# prevent to change variant in cart
# get or create (if dynamic) the correct variant
# product = product_template._create_product_variant(combination)
# BizzAppDev Customization End

if not product:
raise UserError(_(
Expand Down Expand Up @@ -204,6 +207,7 @@ def _cart_update(self, product_id=None, line_id=None,
'quantity': quantity,
'date': order.date_order,
'pricelist': order.pricelist_id.id,
'force_company': order.company_id.id,
})
product = self.env['product.product'].with_context(
product_context).browse(product_id)
Expand Down
8 changes: 8 additions & 0 deletions website_product_configurator/static/src/js/config_form.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@ odoo.define('website_product_configurator.config_form', function (require) {
) {
$selection.addClass('required_config_attrib');
}

var attr_box = $selection.closest('.attribute_container');
if (!domain[0][2].length && $selection.attr('data-attr-hide') && !attr_box.hasClass('d-none')) {
attr_box.addClass('d-none');
$selection.removeClass('textbox-border-color');
} else if (domain[0][2].length && attr_box.hasClass('d-none')) {
attr_box.removeClass('d-none');
}
});
},

Expand Down

0 comments on commit 785923c

Please sign in to comment.