Merge lp:~fabien-morin/unifield-server/fm-us-1719 into lp:unifield-server
- fm-us-1719
- Merge into trunk
Proposed by
jftempo
Status: | Merged |
---|---|
Merged at revision: | 4220 |
Proposed branch: | lp:~fabien-morin/unifield-server/fm-us-1719 |
Merge into: | lp:unifield-server |
Diff against target: |
610 lines (+308/-129) 7 files modified
bin/addons/msf_profile/data/patches.xml (+4/-0) bin/addons/msf_profile/msf_profile.py (+78/-18) bin/addons/sync_client/ir_model_data.py (+5/-11) bin/addons/sync_client/orm.py (+4/-4) bin/addons/sync_client/sync_client.py (+77/-0) bin/addons/sync_common/common.py (+138/-94) bin/addons/sync_server/rules.py (+2/-2) |
To merge this branch: | bzr merge lp:~fabien-morin/unifield-server/fm-us-1719 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email:
|
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/addons/msf_profile/data/patches.xml' | |||
2 | --- bin/addons/msf_profile/data/patches.xml 2017-02-09 17:18:36 +0000 | |||
3 | +++ bin/addons/msf_profile/data/patches.xml 2017-02-16 09:58:42 +0000 | |||
4 | @@ -1,6 +1,10 @@ | |||
5 | 1 | <?xml version="1.0" encoding="utf-8" ?> | 1 | <?xml version="1.0" encoding="utf-8" ?> |
6 | 2 | <openerp> | 2 | <openerp> |
7 | 3 | <data> | 3 | <data> |
8 | 4 | <record id="remove_not_synchronized_data" model="patch.scripts"> | ||
9 | 5 | <field name="method">remove_not_synchronized_data</field> | ||
10 | 6 | </record> | ||
11 | 7 | |||
12 | 4 | <record id="us_2110_patch" model="patch.scripts"> | 8 | <record id="us_2110_patch" model="patch.scripts"> |
13 | 5 | <field name="method">us_2110_patch</field> | 9 | <field name="method">us_2110_patch</field> |
14 | 6 | </record> | 10 | </record> |
15 | 7 | 11 | ||
16 | === modified file 'bin/addons/msf_profile/msf_profile.py' | |||
17 | --- bin/addons/msf_profile/msf_profile.py 2017-02-13 11:31:10 +0000 | |||
18 | +++ bin/addons/msf_profile/msf_profile.py 2017-02-16 09:58:42 +0000 | |||
19 | @@ -46,6 +46,50 @@ | |||
20 | 46 | 'model': lambda *a: 'patch.scripts', | 46 | 'model': lambda *a: 'patch.scripts', |
21 | 47 | } | 47 | } |
22 | 48 | 48 | ||
23 | 49 | def remove_not_synchronized_data(self, cr, uid, *a, **b): | ||
24 | 50 | ''' | ||
25 | 51 | The list of models to synchronize was wrong. It is now build | ||
26 | 52 | automatically and is then more exact. | ||
27 | 53 | This patch will remove all the data from ir_model_data that are not | ||
28 | 54 | synchronized models. | ||
29 | 55 | ''' | ||
30 | 56 | from sync_common import WHITE_LIST_MODEL | ||
31 | 57 | removed_obj = 0 | ||
32 | 58 | |||
33 | 59 | # if sync_client module is installed, get the list of synchronized models | ||
34 | 60 | if self.pool.get('sync.client.rule') and\ | ||
35 | 61 | self.pool.get('sync.client.message_rule'): | ||
36 | 62 | entity_obj = self.pool.get('sync.client.entity') | ||
37 | 63 | server_model_white_set = entity_obj.get_model_white_list(cr, uid) | ||
38 | 64 | |||
39 | 65 | # check that all models from the newly generated list are in the hardcoded white list | ||
40 | 66 | difference = server_model_white_set.difference(WHITE_LIST_MODEL) | ||
41 | 67 | if difference: | ||
42 | 68 | err_msg = 'Warning: Some models used in the synchronization '\ | ||
43 | 69 | 'rule are not present in the WHITE_LIST_MODEL: %s' | ||
44 | 70 | self._logger.error(err_msg) | ||
45 | 71 | raise osv.except_osv( | ||
46 | 72 | 'Error', | ||
47 | 73 | err_msg, | ||
48 | 74 | ) | ||
49 | 75 | elif server_model_white_set: | ||
50 | 76 | # get list of all existing models used in ir_model_data | ||
51 | 77 | cr.execute('SELECT DISTINCT(model) FROM ir_model_data') | ||
52 | 78 | model_list = [x and x[0] for x in cr.fetchall()] | ||
53 | 79 | model_to_remove = (set(model_list).difference(server_model_white_set)) | ||
54 | 80 | import pprint | ||
55 | 81 | pp = pprint.PrettyPrinter(indent=2) | ||
56 | 82 | model_to_remove_pp = pp.pformat(model_to_remove) | ||
57 | 83 | self._logger.warn('%s models should not be part of ir_model_data.' % len(model_to_remove)) | ||
58 | 84 | self._logger.warn('The objects linked to the model(s) %s will be removed from ir_model_data.' % model_to_remove_pp) | ||
59 | 85 | |||
60 | 86 | for model in model_to_remove: | ||
61 | 87 | cr.execute("DELETE FROM ir_model_data WHERE model='%s' AND module='sd'" % model) | ||
62 | 88 | current_count = cr.rowcount | ||
63 | 89 | removed_obj += current_count | ||
64 | 90 | self._logger.warn('ir.model.data, model=%s, %s objects deleted.' % (model, current_count)) | ||
65 | 91 | self._logger.warn('ir.model.data, total of %s objects deleted.' % removed_obj) | ||
66 | 92 | |||
67 | 49 | def us_1613_remove_all_track_changes_action(self, cr, uid, *a, **b): | 93 | def us_1613_remove_all_track_changes_action(self, cr, uid, *a, **b): |
68 | 50 | ''' | 94 | ''' |
69 | 51 | each time the msf_audittrail is updated, the subscribe() method is | 95 | each time the msf_audittrail is updated, the subscribe() method is |
70 | @@ -126,25 +170,31 @@ | |||
71 | 126 | def setup_security_on_sync_server(self, cr, uid, *a, **b): | 170 | def setup_security_on_sync_server(self, cr, uid, *a, **b): |
72 | 127 | update_module = self.pool.get('sync.server.update') | 171 | update_module = self.pool.get('sync.server.update') |
73 | 128 | if not update_module: | 172 | if not update_module: |
75 | 129 | # this script is exucuted on server side, update the first delete | 173 | # this script is exucuted on server side only |
76 | 130 | return | 174 | return |
77 | 131 | 175 | ||
78 | 132 | data_obj = self.pool.get('ir.model.data') | 176 | data_obj = self.pool.get('ir.model.data') |
94 | 133 | group_id = data_obj.get_object_reference(cr, uid, 'base', | 177 | group_id = None |
95 | 134 | 'group_erp_manager')[1] | 178 | try: |
96 | 135 | 179 | group_id = data_obj.get_object_reference(cr, 1, 'base', | |
97 | 136 | model_obj = self.pool.get('ir.model') | 180 | 'group_erp_manager')[1] |
98 | 137 | model_list_not_to_change = ['res.users', 'res.lang', 'res.widget', | 181 | except ValueError: |
99 | 138 | 'res.widget.user', 'res.log', 'publisher_warranty.contract', | 182 | # If these groups does not exists anymore |
100 | 139 | 'module.module'] | 183 | pass |
101 | 140 | model_ids = model_obj.search(cr, uid, | 184 | |
102 | 141 | [('model', 'not like', "ir%"), | 185 | if group_id: |
103 | 142 | ('model', 'not in', model_list_not_to_change)]) | 186 | model_obj = self.pool.get('ir.model') |
104 | 143 | 187 | model_list_not_to_change = ['res.users', 'res.lang', 'res.widget', | |
105 | 144 | access_obj = self.pool.get('ir.model.access') | 188 | 'res.widget.user', 'res.log', 'publisher_warranty.contract', |
106 | 145 | no_group_access = access_obj.search(cr, uid, [('group_id', '=', False), | 189 | 'module.module'] |
107 | 146 | ('model_id', 'in', model_ids)]) | 190 | model_ids = model_obj.search(cr, uid, |
108 | 147 | access_obj.write(cr, uid, no_group_access, {'group_id': group_id}) | 191 | [('model', 'not like', "ir%"), |
109 | 192 | ('model', 'not in', model_list_not_to_change)]) | ||
110 | 193 | |||
111 | 194 | access_obj = self.pool.get('ir.model.access') | ||
112 | 195 | no_group_access = access_obj.search(cr, uid, [('group_id', '=', False), | ||
113 | 196 | ('model_id', 'in', model_ids)]) | ||
114 | 197 | access_obj.write(cr, uid, no_group_access, {'group_id': group_id}) | ||
115 | 148 | 198 | ||
116 | 149 | def us_1482_fix_default_code_on_msf_lines(self, cr, uid, *a, **b): | 199 | def us_1482_fix_default_code_on_msf_lines(self, cr, uid, *a, **b): |
117 | 150 | """ | 200 | """ |
118 | @@ -185,6 +235,8 @@ | |||
119 | 185 | {'password': encrypted_password}) | 235 | {'password': encrypted_password}) |
120 | 186 | 236 | ||
121 | 187 | def us_1610_set_oc_on_all_groups(self, cr, uid, *a, **b): | 237 | def us_1610_set_oc_on_all_groups(self, cr, uid, *a, **b): |
122 | 238 | from sync_common import OC_LIST | ||
123 | 239 | lower_oc_list = [x.lower() for x in OC_LIST] | ||
124 | 188 | logger = logging.getLogger('update') | 240 | logger = logging.getLogger('update') |
125 | 189 | update_module = self.pool.get('sync.server.entity_group') | 241 | update_module = self.pool.get('sync.server.entity_group') |
126 | 190 | if update_module: | 242 | if update_module: |
127 | @@ -196,7 +248,11 @@ | |||
128 | 196 | if 'oc' in group_name: | 248 | if 'oc' in group_name: |
129 | 197 | index = group_name.index('oc') | 249 | index = group_name.index('oc') |
130 | 198 | oc = group_name[index:index+3] | 250 | oc = group_name[index:index+3] |
132 | 199 | update_module.write(cr, uid, group['id'], {'oc': oc}) | 251 | if oc in lower_oc_list: |
133 | 252 | update_module.write(cr, uid, group['id'], {'oc': oc}) | ||
134 | 253 | else: | ||
135 | 254 | logger.warn("""OC = %s from group '%s' is not in the OC_LIST, please fix | ||
136 | 255 | mannualy""" % (oc, group['name'])) | ||
137 | 200 | else: | 256 | else: |
138 | 201 | logger.warn('sync.server.entity_group "%s" does not contain '\ | 257 | logger.warn('sync.server.entity_group "%s" does not contain '\ |
139 | 202 | '"oc" or "OC" in its name. Please set up the '\ | 258 | '"oc" or "OC" in its name. Please set up the '\ |
140 | @@ -213,7 +269,11 @@ | |||
141 | 213 | if 'oc' in entity_name: | 269 | if 'oc' in entity_name: |
142 | 214 | index = entity_name.index('oc') | 270 | index = entity_name.index('oc') |
143 | 215 | oc = entity_name[index:index+3] | 271 | oc = entity_name[index:index+3] |
145 | 216 | sync_client_module.write(cr, uid, entity['id'], {'oc': oc}) | 272 | if oc in lower_oc_list: |
146 | 273 | sync_client_module.write(cr, uid, entity['id'], {'oc': oc}) | ||
147 | 274 | else: | ||
148 | 275 | logger.warn("""OC = %s from group '%s' is not in the OC_LIST, please fix | ||
149 | 276 | mannualy""" % (oc, group['name'])) | ||
150 | 217 | else: | 277 | else: |
151 | 218 | logger.warn('sync.client.entity "%s" does not contain '\ | 278 | logger.warn('sync.client.entity "%s" does not contain '\ |
152 | 219 | '"oc" or "OC" in its name. Please set up the '\ | 279 | '"oc" or "OC" in its name. Please set up the '\ |
153 | 220 | 280 | ||
154 | === modified file 'bin/addons/sync_client/ir_model_data.py' | |||
155 | --- bin/addons/sync_client/ir_model_data.py 2016-11-09 09:40:24 +0000 | |||
156 | +++ bin/addons/sync_client/ir_model_data.py 2017-02-16 09:58:42 +0000 | |||
157 | @@ -24,7 +24,7 @@ | |||
158 | 24 | from osv import osv, fields | 24 | from osv import osv, fields |
159 | 25 | import tools | 25 | import tools |
160 | 26 | 26 | ||
162 | 27 | from sync_common import MODELS_TO_IGNORE, MODELS_TO_IGNORE_DOMAIN, normalize_sdref | 27 | from sync_common import WHITE_LIST_MODEL, normalize_sdref |
163 | 28 | 28 | ||
164 | 29 | 29 | ||
165 | 30 | class ir_module_module(osv.osv): | 30 | class ir_module_module(osv.osv): |
166 | @@ -98,16 +98,10 @@ | |||
167 | 98 | """ | 98 | """ |
168 | 99 | # loop on objects that don't match the models to ignore domain in sync common | 99 | # loop on objects that don't match the models to ignore domain in sync common |
169 | 100 | result = set() | 100 | result = set() |
178 | 101 | ir_model = self.pool.get('ir.model') | 101 | for model in WHITE_LIST_MODEL: |
179 | 102 | model_ids = ir_model.search(cr, 1, MODELS_TO_IGNORE_DOMAIN) | 102 | obj = self.pool.get(model) |
172 | 103 | |||
173 | 104 | for model in filter(lambda m:m.model not in MODELS_TO_IGNORE, | ||
174 | 105 | ir_model.browse(cr, 1, model_ids)): | ||
175 | 106 | |||
176 | 107 | obj = self.pool.get(model.model) | ||
177 | 108 | |||
180 | 109 | if obj is None: | 103 | if obj is None: |
182 | 110 | self._logger.warn('Could not get object %s while creating all missing sdrefs' % model.model) | 104 | self._logger.warn('Could not get object %s while creating all missing sdrefs' % model) |
183 | 111 | continue | 105 | continue |
184 | 112 | 106 | ||
185 | 113 | # ignore wizard objects | 107 | # ignore wizard objects |
186 | @@ -251,7 +245,7 @@ | |||
187 | 251 | 245 | ||
188 | 252 | # when a module load a specific xmlid, the sdref is updated according | 246 | # when a module load a specific xmlid, the sdref is updated according |
189 | 253 | # that xmlid | 247 | # that xmlid |
191 | 254 | if values['model'] not in MODELS_TO_IGNORE and \ | 248 | if values['model'] in WHITE_LIST_MODEL and \ |
192 | 255 | values['module'] not in ('sd', '__export__') and \ | 249 | values['module'] not in ('sd', '__export__') and \ |
193 | 256 | not (values['module'] == 'base' and values['name'].startswith('main_')): | 250 | not (values['module'] == 'base' and values['name'].startswith('main_')): |
194 | 257 | sdref_name = "%(module)s_%(name)s" % values | 251 | sdref_name = "%(module)s_%(name)s" % values |
195 | 258 | 252 | ||
196 | === modified file 'bin/addons/sync_client/orm.py' | |||
197 | --- bin/addons/sync_client/orm.py 2016-08-23 12:54:03 +0000 | |||
198 | +++ bin/addons/sync_client/orm.py 2017-02-16 09:58:42 +0000 | |||
199 | @@ -8,7 +8,7 @@ | |||
200 | 8 | import types | 8 | import types |
201 | 9 | from datetime import date, datetime | 9 | from datetime import date, datetime |
202 | 10 | 10 | ||
204 | 11 | from sync_common import MODELS_TO_IGNORE, xmlid_to_sdref | 11 | from sync_common import WHITE_LIST_MODEL, xmlid_to_sdref |
205 | 12 | 12 | ||
206 | 13 | #import cProfile | 13 | #import cProfile |
207 | 14 | ## Helpers ################################################################### | 14 | ## Helpers ################################################################### |
208 | @@ -489,7 +489,7 @@ | |||
209 | 489 | funct_field = audit_obj.get_functionnal_fields(cr, 1, self._name, audit_rule_ids) | 489 | funct_field = audit_obj.get_functionnal_fields(cr, 1, self._name, audit_rule_ids) |
210 | 490 | 490 | ||
211 | 491 | to_be_synchronized = ( | 491 | to_be_synchronized = ( |
213 | 492 | self._name not in MODELS_TO_IGNORE and | 492 | self._name in WHITE_LIST_MODEL and |
214 | 493 | (not context.get('sync_update_execution') and | 493 | (not context.get('sync_update_execution') and |
215 | 494 | not context.get('sync_update_creation'))) | 494 | not context.get('sync_update_creation'))) |
216 | 495 | 495 | ||
217 | @@ -528,7 +528,7 @@ | |||
218 | 528 | funct_field = audit_obj.get_functionnal_fields(cr, 1, self._name, audit_rule_ids) | 528 | funct_field = audit_obj.get_functionnal_fields(cr, 1, self._name, audit_rule_ids) |
219 | 529 | 529 | ||
220 | 530 | to_be_synchronized = ( | 530 | to_be_synchronized = ( |
222 | 531 | self._name not in MODELS_TO_IGNORE and | 531 | self._name in WHITE_LIST_MODEL and |
223 | 532 | (not context.get('sync_update_execution') and | 532 | (not context.get('sync_update_execution') and |
224 | 533 | not context.get('sync_update_creation'))) | 533 | not context.get('sync_update_creation'))) |
225 | 534 | 534 | ||
226 | @@ -617,7 +617,7 @@ | |||
227 | 617 | # synchronization is made. | 617 | # synchronization is made. |
228 | 618 | # Otherwise, references are kept and synchronization is triggered | 618 | # Otherwise, references are kept and synchronization is triggered |
229 | 619 | # ...see? | 619 | # ...see? |
231 | 620 | if self._name not in MODELS_TO_IGNORE \ | 620 | if self._name in WHITE_LIST_MODEL \ |
232 | 621 | and not context.get('sync_update_creation'): | 621 | and not context.get('sync_update_creation'): |
233 | 622 | context = dict(context, avoid_sdref_deletion=True) | 622 | context = dict(context, avoid_sdref_deletion=True) |
234 | 623 | if not context.get('sync_update_execution'): | 623 | if not context.get('sync_update_execution'): |
235 | 624 | 624 | ||
236 | === modified file 'bin/addons/sync_client/sync_client.py' | |||
237 | --- bin/addons/sync_client/sync_client.py 2016-11-18 13:31:06 +0000 | |||
238 | +++ bin/addons/sync_client/sync_client.py 2017-02-16 09:58:42 +0000 | |||
239 | @@ -42,6 +42,7 @@ | |||
240 | 42 | 42 | ||
241 | 43 | import functools | 43 | import functools |
242 | 44 | 44 | ||
243 | 45 | from sync_common import WHITE_LIST_MODEL | ||
244 | 45 | from datetime import datetime, timedelta | 46 | from datetime import datetime, timedelta |
245 | 46 | 47 | ||
246 | 47 | from sync_common import OC_LIST_TUPLE | 48 | from sync_common import OC_LIST_TUPLE |
247 | @@ -205,6 +206,17 @@ | |||
248 | 205 | self.pool.get('sync.monitor').get_logger(cr, uid, defaults_logger, context=context) | 206 | self.pool.get('sync.monitor').get_logger(cr, uid, defaults_logger, context=context) |
249 | 206 | context['log_sale_purchase'] = True | 207 | context['log_sale_purchase'] = True |
250 | 207 | 208 | ||
251 | 209 | # generate a white list of models | ||
252 | 210 | if self.pool.get('sync.client.rule') and\ | ||
253 | 211 | self.pool.get('sync.client.message_rule'): | ||
254 | 212 | server_model_white_set = self.get_model_white_list(cr, uid) | ||
255 | 213 | # check all models are in the hardcoded white list | ||
256 | 214 | difference = server_model_white_set.difference(WHITE_LIST_MODEL) | ||
257 | 215 | if difference: | ||
258 | 216 | msg = 'Warning: Some models used in the synchronization '\ | ||
259 | 217 | 'rule are not present in the WHITE_LIST_MODEL: %s' | ||
260 | 218 | logger.append(_(msg) % ' ,'.join(list(difference))) | ||
261 | 219 | |||
262 | 208 | # create a specific cursor for the call | 220 | # create a specific cursor for the call |
263 | 209 | self.sync_cursor = pooler.get_db(cr.dbname).cursor() | 221 | self.sync_cursor = pooler.get_db(cr.dbname).cursor() |
264 | 210 | 222 | ||
265 | @@ -497,6 +509,71 @@ | |||
266 | 497 | finally: | 509 | finally: |
267 | 498 | self.renew_lock.release() | 510 | self.renew_lock.release() |
268 | 499 | 511 | ||
269 | 512 | def get_model_white_list(self, cr, uid): | ||
270 | 513 | ''' | ||
271 | 514 | return a set of all models involved in the synchronization process | ||
272 | 515 | ''' | ||
273 | 516 | model_field_dict = {} | ||
274 | 517 | |||
275 | 518 | # search for model of sync_server.sync_rule | ||
276 | 519 | if self.pool.get('sync_server.sync_rule'): | ||
277 | 520 | rule_module = self.pool.get('sync_server.sync_rule') | ||
278 | 521 | model_field_name = 'model_id' | ||
279 | 522 | else: | ||
280 | 523 | rule_module = self.pool.get('sync.client.rule') | ||
281 | 524 | model_field_name = 'model' | ||
282 | 525 | obj_ids = rule_module.search(cr, uid, [('active', '=', True)]) | ||
283 | 526 | for obj in rule_module.read(cr, uid, obj_ids, [model_field_name, 'included_fields']): | ||
284 | 527 | if obj[model_field_name] not in model_field_dict: | ||
285 | 528 | model_field_dict[obj[model_field_name]] = set() | ||
286 | 529 | model_field_dict[obj[model_field_name]].update(eval(obj['included_fields'])) | ||
287 | 530 | |||
288 | 531 | # search for model of sync_server.message_rule | ||
289 | 532 | if self.pool.get('sync_server.message_rule'): | ||
290 | 533 | rule_module = self.pool.get('sync_server.message_rule') | ||
291 | 534 | model_field_name = 'model_id' | ||
292 | 535 | else: | ||
293 | 536 | rule_module = self.pool.get('sync.client.message_rule') | ||
294 | 537 | model_field_name = 'model' | ||
295 | 538 | obj_ids = rule_module.search(cr, uid, [('active', '=', True)]) | ||
296 | 539 | for obj in rule_module.read(cr, uid, obj_ids, [model_field_name, 'arguments']): | ||
297 | 540 | if obj[model_field_name] not in model_field_dict: | ||
298 | 541 | model_field_dict[obj[model_field_name]] = set() | ||
299 | 542 | model_field_dict[obj[model_field_name]].update(eval(obj['arguments'])) | ||
300 | 543 | |||
301 | 544 | model_set = set(model_field_dict.keys()) | ||
302 | 545 | |||
303 | 546 | def get_field_obj(model, field_name): | ||
304 | 547 | model_obj = self.pool.get(model) | ||
305 | 548 | field_obj = None | ||
306 | 549 | if field_name in model_obj._columns: | ||
307 | 550 | field_obj = model_obj._columns[field_name] | ||
308 | 551 | elif field_name in model_obj._inherit_fields: | ||
309 | 552 | field_obj = model_obj._inherit_fields[field_name][2] | ||
310 | 553 | return field_obj | ||
311 | 554 | |||
312 | 555 | |||
313 | 556 | # for each field corresponding to each model, check if it is a m2m m2o or o2m | ||
314 | 557 | # if yes, add the model of the relation to the model set | ||
315 | 558 | |||
316 | 559 | for model, field_list in model_field_dict.items(): | ||
317 | 560 | field_list_to_parse = [x for x in field_list if '/id' in x] | ||
318 | 561 | if not field_list_to_parse: | ||
319 | 562 | continue | ||
320 | 563 | |||
321 | 564 | for field in field_list_to_parse: | ||
322 | 565 | field = field.replace('/id', '') | ||
323 | 566 | if len(field.split('/')) == 2: | ||
324 | 567 | related_field, field = field.split('/') | ||
325 | 568 | field_obj = get_field_obj(model, related_field) | ||
326 | 569 | related_model = field_obj._obj | ||
327 | 570 | field_obj = get_field_obj(related_model, field) | ||
328 | 571 | else: | ||
329 | 572 | field_obj = get_field_obj(model, field) | ||
330 | 573 | if field_obj._type in ('many2one', 'many2many', 'one2many'): | ||
331 | 574 | model_set.add(field_obj._obj) | ||
332 | 575 | return model_set | ||
333 | 576 | |||
334 | 500 | @sync_process('data_push') | 577 | @sync_process('data_push') |
335 | 501 | def push_update(self, cr, uid, context=None): | 578 | def push_update(self, cr, uid, context=None): |
336 | 502 | """ | 579 | """ |
337 | 503 | 580 | ||
338 | === modified file 'bin/addons/sync_common/common.py' | |||
339 | --- bin/addons/sync_common/common.py 2016-11-18 13:31:06 +0000 | |||
340 | +++ bin/addons/sync_common/common.py 2017-02-16 09:58:42 +0000 | |||
341 | @@ -8,101 +8,147 @@ | |||
342 | 8 | import tools | 8 | import tools |
343 | 9 | from tools.translate import _ | 9 | from tools.translate import _ |
344 | 10 | 10 | ||
345 | 11 | # model related to synchronization, this model don't have to be ignored. | ||
346 | 12 | # list build by getting models of update rules and message rules | ||
347 | 13 | WHITE_LIST_MODEL = [ | ||
348 | 14 | 'account.account', | ||
349 | 15 | 'account.account.type', | ||
350 | 16 | 'account.analytic.account', | ||
351 | 17 | 'account.analytic.journal', | ||
352 | 18 | 'account.analytic.line', | ||
353 | 19 | 'account.bank.statement', | ||
354 | 20 | 'account.bank.statement.line', | ||
355 | 21 | 'account.bank.statement.line.deleted', | ||
356 | 22 | 'account.cashbox.line', | ||
357 | 23 | 'account.destination.link', | ||
358 | 24 | 'account.fiscal.position', | ||
359 | 25 | 'account.fiscalyear', | ||
360 | 26 | 'account.fiscalyear.state', | ||
361 | 27 | 'account.invoice', | ||
362 | 28 | 'account.journal', | ||
363 | 29 | 'account.move', | ||
364 | 30 | 'account.move.line', | ||
365 | 31 | 'account.move.reconcile', | ||
366 | 32 | 'account.payment.term', | ||
367 | 33 | 'account.period', | ||
368 | 34 | 'account.period.state', | ||
369 | 35 | 'account.target.costcenter', | ||
370 | 36 | 'account.tax', | ||
371 | 37 | 'account.tax.code', | ||
372 | 38 | 'analytic.distribution', | ||
373 | 39 | 'claim.event', | ||
374 | 40 | 'claim.product.line', | ||
375 | 41 | 'composition.item', | ||
376 | 42 | 'composition.kit', | ||
377 | 43 | 'cost.center.distribution.line', | ||
378 | 44 | 'country.export.mapping', | ||
379 | 45 | 'distribution.line', | ||
380 | 46 | 'financing.contract.contract', | ||
381 | 47 | 'financing.contract.donor', | ||
382 | 48 | 'financing.contract.format', | ||
383 | 49 | 'financing.contract.format.line', | ||
384 | 50 | 'financing.contract.funding.pool.line', | ||
385 | 51 | 'free.1.distribution.line', | ||
386 | 52 | 'free.2.distribution.line', | ||
387 | 53 | 'funding.pool.distribution.line', | ||
388 | 54 | 'hq.entries', | ||
389 | 55 | 'hr.employee', | ||
390 | 56 | 'hr.employee.marital.status', | ||
391 | 57 | 'hr.job', | ||
392 | 58 | 'initial.stock.inventory', | ||
393 | 59 | 'initial.stock.inventory.line', | ||
394 | 60 | 'ir.actions.act_window', | ||
395 | 61 | 'ir.filters', | ||
396 | 62 | 'ir.model', | ||
397 | 63 | 'ir.model.access', | ||
398 | 64 | 'ir.model.fields', | ||
399 | 65 | 'ir.rule', | ||
400 | 66 | 'ir.sequence', | ||
401 | 67 | 'ir.translation', | ||
402 | 68 | 'ir.ui.menu', | ||
403 | 69 | 'ir.ui.view', | ||
404 | 70 | 'kit.creation', | ||
405 | 71 | 'kit.creation.to.consume', | ||
406 | 72 | 'monthly.review.consumption', | ||
407 | 73 | 'monthly.review.consumption.line', | ||
408 | 74 | 'msf.budget', | ||
409 | 75 | 'msf.budget.decision.moment', | ||
410 | 76 | 'msf.budget.line', | ||
411 | 77 | 'msf.instance', | ||
412 | 78 | 'msf_button_access_rights.button_access_rule', | ||
413 | 79 | 'msf_field_access_rights.field_access_rule', | ||
414 | 80 | 'msf_field_access_rights.field_access_rule_line', | ||
415 | 81 | 'pack.type', | ||
416 | 82 | 'procurement.order', | ||
417 | 83 | 'product.asset', | ||
418 | 84 | 'product.asset.type', | ||
419 | 85 | 'product.category', | ||
420 | 86 | 'product.cold_chain', | ||
421 | 87 | 'product.heat_sensitive', | ||
422 | 88 | 'product.international.status', | ||
423 | 89 | 'product.justification.code', | ||
424 | 90 | 'product.list', | ||
425 | 91 | 'product.list.line', | ||
426 | 92 | 'product.nomenclature', | ||
427 | 93 | 'product.pricelist', | ||
428 | 94 | 'product.pricelist.type', | ||
429 | 95 | 'product.pricelist.version', | ||
430 | 96 | 'product.product', | ||
431 | 97 | 'product.uom', | ||
432 | 98 | 'product.uom.categ', | ||
433 | 99 | 'purchase.order', | ||
434 | 100 | 'purchase.order.line', | ||
435 | 101 | 'real.average.consumption', | ||
436 | 102 | 'real.average.consumption.line', | ||
437 | 103 | 'res.company', | ||
438 | 104 | 'res.country', | ||
439 | 105 | 'res.country.restriction', | ||
440 | 106 | 'res.country.state', | ||
441 | 107 | 'res.currency', | ||
442 | 108 | 'res.currency.rate', | ||
443 | 109 | 'res.currency.table', | ||
444 | 110 | 'res.groups', | ||
445 | 111 | 'res.partner', | ||
446 | 112 | 'res.partner.address', | ||
447 | 113 | 'res.partner.title', | ||
448 | 114 | 'res.users', | ||
449 | 115 | 'return.claim', | ||
450 | 116 | 'sale.order', | ||
451 | 117 | 'sale.order.line', | ||
452 | 118 | 'sale.order.line.cancel', | ||
453 | 119 | 'shipment', | ||
454 | 120 | 'stock.frequence', | ||
455 | 121 | 'stock.inventory', | ||
456 | 122 | 'stock.inventory.line', | ||
457 | 123 | 'stock.journal', | ||
458 | 124 | 'stock.location', | ||
459 | 125 | 'stock.location.chained.options', | ||
460 | 126 | 'stock.mission.report', | ||
461 | 127 | 'stock.mission.report.line', | ||
462 | 128 | 'stock.move', | ||
463 | 129 | 'stock.picking', | ||
464 | 130 | 'stock.production.lot', | ||
465 | 131 | 'stock.reason.type', | ||
466 | 132 | 'stock.warehouse', | ||
467 | 133 | 'stock.warehouse.automatic.supply', | ||
468 | 134 | 'stock.warehouse.automatic.supply.line', | ||
469 | 135 | 'stock.warehouse.order.cycle', | ||
470 | 136 | 'stock.warehouse.order.cycle.line', | ||
471 | 137 | 'stock.warehouse.orderpoint', | ||
472 | 138 | 'supplier.catalogue', | ||
473 | 139 | 'supplier.catalogue.line', | ||
474 | 140 | 'sync.monitor', | ||
475 | 141 | 'sync.sale.order.line.split', | ||
476 | 142 | 'sync.version.instance.monitor', | ||
477 | 143 | 'tender', | ||
478 | 144 | 'tender.line', | ||
479 | 145 | 'threshold.value', | ||
480 | 146 | 'threshold.value.line', | ||
481 | 147 | ] | ||
482 | 148 | |||
483 | 11 | OC_LIST = ['OCA', 'OCB', 'OCBA', 'OCG', 'OCP'] | 149 | OC_LIST = ['OCA', 'OCB', 'OCBA', 'OCG', 'OCP'] |
484 | 12 | OC_LIST_TUPLE = zip([x.lower() for x in OC_LIST], OC_LIST) | 150 | OC_LIST_TUPLE = zip([x.lower() for x in OC_LIST], OC_LIST) |
485 | 13 | 151 | ||
486 | 14 | MODELS_TO_IGNORE = [ | ||
487 | 15 | 'ir.actions.wizard', | ||
488 | 16 | 'ir.actions.act_window.view', | ||
489 | 17 | 'ir.report.custom', | ||
490 | 18 | 'ir.actions.act_window.view', | ||
491 | 19 | 'ir.actions.wizard', | ||
492 | 20 | 'ir.report.custom', | ||
493 | 21 | 'ir.ui.view', | ||
494 | 22 | 'ir.sequence', | ||
495 | 23 | 'ir.actions.url', | ||
496 | 24 | 'ir.values', | ||
497 | 25 | 'ir.report.custom.fields', | ||
498 | 26 | 'ir.cron', | ||
499 | 27 | 'ir.actions.report.xml', | ||
500 | 28 | 'ir.property', | ||
501 | 29 | 'ir.actions.todo', | ||
502 | 30 | 'ir.sequence.type', | ||
503 | 31 | #'ir.actions.act_window', | ||
504 | 32 | 'ir.module.module', | ||
505 | 33 | 'ir.ui.view', | ||
506 | 34 | 'ir.module.repository', | ||
507 | 35 | 'ir.model.data', | ||
508 | 36 | 'ir.model.fields', | ||
509 | 37 | 'ir.ui.view_sc', | ||
510 | 38 | 'ir.config_parameter', | ||
511 | 39 | |||
512 | 40 | #'sync.monitor', | ||
513 | 41 | 'sync.client.rule', | ||
514 | 42 | 'sync.client.push.data.information', | ||
515 | 43 | 'sync.client.update_to_send', | ||
516 | 44 | 'sync.client.update_received', | ||
517 | 45 | 'sync.client.entity', | ||
518 | 46 | 'sync.client.sync_server_connection', | ||
519 | 47 | 'sync.client.message_rule', | ||
520 | 48 | 'sync.client.message_to_send', | ||
521 | 49 | 'sync.client.message_received', | ||
522 | 50 | 'sync.client.message_sync', | ||
523 | 51 | 'sync.client.orm_extended', | ||
524 | 52 | |||
525 | 53 | 'sync.server.test', | ||
526 | 54 | 'sync_server.version.manager', | ||
527 | 55 | 'sync.server.entity_group', | ||
528 | 56 | 'sync.server.entity', | ||
529 | 57 | 'sync.server.group_type', | ||
530 | 58 | 'sync.server.entity_group', | ||
531 | 59 | 'sync.server.entity', | ||
532 | 60 | 'sync.server.sync_manager', | ||
533 | 61 | 'sync_server.sync_rule', | ||
534 | 62 | 'sync_server.message_rule', | ||
535 | 63 | 'sync_server.sync_rule.forced_values', | ||
536 | 64 | 'sync_server.sync_rule.fallback_values', | ||
537 | 65 | 'sync_server.rule.validation.message', | ||
538 | 66 | 'sync.server.update', | ||
539 | 67 | 'sync.server.message', | ||
540 | 68 | 'sync_server.version', | ||
541 | 69 | 'sync.server.puller_logs', | ||
542 | 70 | 'audittrail.log.sequence', | ||
543 | 71 | 'audittrail.log.line', | ||
544 | 72 | |||
545 | 73 | 'res.widget', | ||
546 | 74 | 'product.likely.expire.report', | ||
547 | 75 | 'product.likely.expire.report.line', | ||
548 | 76 | 'operations.event', | ||
549 | 77 | ] | ||
550 | 78 | |||
551 | 79 | MODELS_TO_IGNORE_DOMAIN = [ | ||
552 | 80 | 'sync_client.%', | ||
553 | 81 | 'sync_server.%', | ||
554 | 82 | 'res.widget%', | ||
555 | 83 | 'base%', | ||
556 | 84 | 'board%', | ||
557 | 85 | 'audittrail%', | ||
558 | 86 | 'workflow%', | ||
559 | 87 | ] | ||
560 | 88 | |||
561 | 89 | def __compile_models_to_ignore(): | ||
562 | 90 | global MODELS_TO_IGNORE_DOMAIN | ||
563 | 91 | simple_patterns = [] | ||
564 | 92 | exact_models = [] | ||
565 | 93 | for model in MODELS_TO_IGNORE_DOMAIN: | ||
566 | 94 | if model.find('%') >= 0: | ||
567 | 95 | simple_patterns.append(model) | ||
568 | 96 | else: | ||
569 | 97 | exact_models.append(model) | ||
570 | 98 | MODELS_TO_IGNORE_DOMAIN[:] = [('model','not in',exact_models)] | ||
571 | 99 | for pattern in simple_patterns: | ||
572 | 100 | MODELS_TO_IGNORE_DOMAIN.extend(['!',('model','=like',pattern)]) | ||
573 | 101 | |||
574 | 102 | __compile_models_to_ignore() | ||
575 | 103 | |||
576 | 104 | |||
577 | 105 | |||
578 | 106 | def xmlid_to_sdref(xmlid): | 152 | def xmlid_to_sdref(xmlid): |
579 | 107 | if not xmlid: return None | 153 | if not xmlid: return None |
580 | 108 | head, sep, tail = xmlid.partition('.') | 154 | head, sep, tail = xmlid.partition('.') |
581 | @@ -112,8 +158,6 @@ | |||
582 | 112 | else: | 158 | else: |
583 | 113 | return head | 159 | return head |
584 | 114 | 160 | ||
585 | 115 | |||
586 | 116 | |||
587 | 117 | # TODO deprecated, should disappear | 161 | # TODO deprecated, should disappear |
588 | 118 | def sync_log(obj, message=None, level='debug', ids=None, data=None, tb=False): | 162 | def sync_log(obj, message=None, level='debug', ids=None, data=None, tb=False): |
589 | 119 | if not hasattr(obj, '_logger'): | 163 | if not hasattr(obj, '_logger'): |
590 | 120 | 164 | ||
591 | === modified file 'bin/addons/sync_server/rules.py' | |||
592 | --- bin/addons/sync_server/rules.py 2016-11-18 11:26:45 +0000 | |||
593 | +++ bin/addons/sync_server/rules.py 2017-02-16 09:58:42 +0000 | |||
594 | @@ -27,7 +27,7 @@ | |||
595 | 27 | from datetime import datetime | 27 | from datetime import datetime |
596 | 28 | 28 | ||
597 | 29 | import logging | 29 | import logging |
599 | 30 | from sync_common import MODELS_TO_IGNORE_DOMAIN, sync_log | 30 | from sync_common import sync_log |
600 | 31 | 31 | ||
601 | 32 | _field2type = { | 32 | _field2type = { |
602 | 33 | 'text' : 'str', | 33 | 'text' : 'str', |
603 | @@ -829,7 +829,7 @@ | |||
604 | 829 | 829 | ||
605 | 830 | def _get_fallback_value(self, cr, uid, context=None): | 830 | def _get_fallback_value(self, cr, uid, context=None): |
606 | 831 | model = self.pool.get('ir.model') | 831 | model = self.pool.get('ir.model') |
608 | 832 | ids = model.search(cr, uid, MODELS_TO_IGNORE_DOMAIN) | 832 | ids = model.search(cr, uid, ('model', 'not in', WHITE_LIST_MODEL)) |
609 | 833 | res = model.read(cr, uid, ids, ['model'], context) | 833 | res = model.read(cr, uid, ids, ['model'], context) |
610 | 834 | return [(r['model'], r['model']) for r in res] | 834 | return [(r['model'], r['model']) for r in res] |
611 | 835 | 835 |