/
website_dependent_mixin.py
129 lines (105 loc) · 4.62 KB
/
website_dependent_mixin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo import models, api
import logging
_logger = logging.getLogger(__name__)
class WebsiteDependentMixin(models.AbstractModel):
"""Mixin Class with helpers to convert previously normal fields to website-depedent"""
_name = 'website_dependent.mixin'
def _prop_label(self, field_name, company=None, website=None):
self.ensure_one()
label = self.display_name
label = "%s's %s: " % (label, field_name)
if not company and not website:
label += 'default'
elif website:
label += 'company + website'
else:
label += 'company'
return label
def _update_properties_label(self, field_name):
for r in self:
domain = self.env['ir.property']._get_domain(field_name, self._name)
domain += [('res_id', '=', '%s,%s' % (self._name, self.id))]
for prop in self.env['ir.property'].search(domain):
prop.name = self._prop_label(field_name, prop.company_id, prop.website_id)
def _force_default(self, field_name, prop_value):
"""Remove company-dependent values and keeps only default one"""
self.ensure_one()
Prop = self.env['ir.property']
domain = Prop._get_domain(field_name, self._name)
# find all props
props = Prop.search(domain + [
('res_id', '=', '%s,%s' % (self._name, self.id)),
])
default_prop = None
if len(props) == 0:
field = self._get_field_object(field_name)
default_prop = self._create_default_value(field, prop_value)
elif len(props) == 1:
default_prop = props
else:
default_prop = props.filtered(lambda r: not r.company_id)[:1]
if not default_prop:
default_prop = props[0]
# remove rest properties
(props - default_prop).unlink()
vals = {
'name': self._prop_label(field_name),
}
if default_prop.company_id:
vals['company_id'] = None
if default_prop.get_by_record() != prop_value:
vals[field_name] = prop_value
default_prop.write(vals)
self._update_db_value(field_name, prop_value)
return self
def _update_db_value(self, field_name, value):
"""Store value in db column. We can use it only directly,
because ORM treat value as computed multi-company field"""
self.ensure_one()
self.env.cr.execute("UPDATE %s SET %s=%%s WHERE id = %s" % (self._table, field_name, self.id), (value,))
@api.multi
def _create_default_value(self, field, prop_value):
"""Set company-independent default value"""
self.ensure_one()
domain = [
('company_id', '=', False),
('res_id', '=', '%s,%s' % (self._name, self.id))
]
existing = self.env['ir.property'].search(domain)
if existing:
# already exists
return existing
label = self._prop_label(field.name)
return self.env['ir.property'].create({
'fields_id': field.id,
'res_id': '%s,%s' % (self._name, self.id),
'name': label,
'value': prop_value,
'type': 'text',
})
def _get_field_object(self, field_name):
return self.env['ir.model.fields'].search([
('name', '=', field_name),
('model_id.model', '=', self._name)
])
def _auto_init_website_dependent(self, field_name):
cr = self.env.cr
# rename FIELD to "FIELD_tmp"
# to don't lose values, because during installation the column "value" is deleted
cr.execute("ALTER TABLE %s RENAME COLUMN %s TO %s_tmp" % (self._table, field_name, field_name))
self.pool.post_init(self._post_init_website_dependent, field_name)
def _post_init_website_dependent(self, field_name):
cr = self.env.cr
# rename "FIELD_tmp" back to "FIELD"
cr.execute("ALTER TABLE %s RENAME COLUMN %s_tmp TO %s" % (self._table, field_name, field_name))
field = self._get_field_object(field_name)
for r in self.sudo().search([]):
cr.execute("SELECT %s FROM %s WHERE id = %s" % (field_name, self._table, r.id))
res = cr.dictfetchone()
value = res.get(field_name)
# value may be empty after migration from previous module version
if value:
# create default value if it doesn't exist
r._create_default_value(field, value)