Skip to content

Commit

Permalink
🚑 web_website fixes after odoo update odoo/odoo@b6d32de
Browse files Browse the repository at this point in the history
  • Loading branch information
KolushovAlexandr committed Dec 7, 2018
1 parent 0bf2e41 commit ba68534
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 5 deletions.
114 changes: 110 additions & 4 deletions web_website/models/ir_property.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
# Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr>
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
import logging
from odoo import models, fields, api
from odoo.addons.base.models.ir_property import TYPE2FIELD


_logger = logging.getLogger(__name__)

GET_CONTEXT = dict(
_get_domain_website_dependent=True,
_search_order_website_dependent=True,
Expand Down Expand Up @@ -98,10 +103,111 @@ def get(self, name, model, res_id=False):

@api.model
def get_multi(self, name, model, ids):
return super(IrProperty, self._check_website_dependent(
name, model,
**GET_CONTEXT
)).get_multi(name, model, ids)
# Due to https://github.com/odoo/odoo/commit/b6d32de31e0e18a506ae06dc27561d1d078f3ab1 commit
# We override the super method to make it website dependent
# It has the same idea and structure, but sql request and set record value method are changed
if not ids:
return {}
website_id = self._context.get('website_id', None)
field = self.env[model]._fields[name]
field_id = self.env['ir.model.fields']._get(model, name).id
company_id = (self._context.get('force_company')
or self.env['res.company']._company_default_get(model, field_id).id)

if field.type == 'many2one':
comodel = self.env[field.comodel_name]
model_pos = len(model) + 2
value_pos = len(comodel._name) + 2
# retrieve values: both p.res_id and p.value_reference are formatted
# as "<rec._name>,<rec.id>"; the purpose of the LEFT JOIN is to
# return the value id if it exists, NULL otherwise
query = """
SELECT substr(p.res_id, %s)::integer, r.id, p.company_id, p.website_id
FROM ir_property p
LEFT JOIN {} r ON substr(p.value_reference, %s)::integer=r.id
WHERE p.fields_id=%s
AND (p.company_id=%s OR p.company_id IS NULL)
AND (p.website_id=%s OR p.website_id IS NULL)
AND (p.res_id IN %s OR p.res_id IS NULL)
ORDER BY p.website_id NULLS FIRST, p.company_id NULLS FIRST
""".format(comodel._table)
params = [model_pos, value_pos, field_id, company_id, website_id]
elif field.type in TYPE2FIELD:
model_pos = len(model) + 2
# retrieve values: p.res_id is formatted as "<rec._name>,<rec.id>"
query = """
SELECT substr(p.res_id, %s)::integer, p.{0}, p.company_id, p.website_id
FROM ir_property p
WHERE p.fields_id=%s
AND (p.company_id=%s OR p.company_id IS NULL)
AND (p.website_id=%s OR p.website_id IS NULL)
AND (p.res_id IN %s OR p.res_id IS NULL)
ORDER BY p.website_id NULLS FIRST, p.company_id NULLS FIRST
""".format(TYPE2FIELD[field.type])
params = [model_pos, field_id, company_id, website_id]
else:
return dict.fromkeys(ids, (False, False, False, False))

# retrieve values
cr = self.env.cr
result = {}
refs = {"%s,%s" % (model, id) for id in ids}
for sub_refs in cr.split_for_in_conditions(refs):
cr.execute(query, params + [sub_refs])
fetched_result = cr.fetchall()
_logger.debug('Properties for website=%s, company=%s, resource=%s:\n%s', website_id, company_id, sub_refs, fetched_result)
# fetched_result format: [(res_id, val, company_id, website_id), ...]
# fetched_result sorting:

# [(RES_ID, 'only_res', None, None),
# (None, 'only_field', None, None),

# (RES_ID, 'company_and_resource', COMPANY, None),
# (None, 'only_company', COMPANY, None),

# (RES_ID, 'website_and_resource', None, WEBSITE),
# (None, 'only_website', None, WEBSITE),

# (RES_ID, 'company_website', COMPANY, WEBSITE)]

res = {
i[0]: i for i in fetched_result
}
result.update(res)

# result format: {res_id: (res_id, val, company_id, website_id), ...}
# from fetched result was taken only the last row for each res_id

default_value = result.pop(None, None)
default_company_id = default_value and default_value[2]
default_website_id = default_value and default_value[3]
for id in ids:
if id not in result:
# 5 Company, Resource and Website are empty (i.e. only Field is matched)
result[id] = default_value
else:
result_website_id = result[id][3]
if result_website_id:
# 1 Website and Resource are matched
continue
if default_website_id:
# 2 Website is matched, Resource is empty
result[id] = default_value
# No properties with website
result_company_id = result[id][2]
if result_company_id:
# 3 Company and Resource are matched, Website is empty
continue
# no property for res and company
if default_company_id:
# 4 Company is matched, Resource and Website are empty
result[id] = default_value

for key, value in result.items():
# set data to appropriate form
result[key] = value[1]
# result format: {id: val, ...}
return result

@api.model
def search_multi(self, name, model, operator, value):
Expand Down
5 changes: 4 additions & 1 deletion web_website/models/website_dependent_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ def _force_default(self, field_name, prop_value):
value = value.id
except AttributeError:
pass

try:
prop_value = prop_value.id
except AttributeError:
pass
if value != prop_value:
vals['value'] = prop_value

Expand Down

0 comments on commit ba68534

Please sign in to comment.