Merge lp:~openerp-dev/openobject-addons/7.0-opw-589931-rgo into lp:openobject-addons
- 7.0-opw-589931-rgo
- Merge into trunk
Proposed by
Lithin T
Status: | Rejected | ||||
---|---|---|---|---|---|
Rejected by: | Naresh(OpenERP) | ||||
Proposed branch: | lp:~openerp-dev/openobject-addons/7.0-opw-589931-rgo | ||||
Merge into: | lp:openobject-addons | ||||
Diff against target: |
208 lines (+177/-0) (has conflicts) 1 file modified
audittrail/audittrail.py (+177/-0) Text conflict in audittrail/audittrail.py |
||||
To merge this branch: | bzr merge lp:~openerp-dev/openobject-addons/7.0-opw-589931-rgo | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Lithin T (community) | Disapprove | ||
Review via email: mp+191347@code.launchpad.net |
Commit message
This fix is not traking when we deleting the records. So it should not be merged to the branch
Description of the change
To post a comment you must log in.
Revision history for this message
Lithin T (lithint-mail) : | # |
review:
Disapprove
Revision history for this message
Naresh(OpenERP) (nch-openerp) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'audittrail/audittrail.py' | |||
2 | --- audittrail/audittrail.py 2013-03-29 14:37:20 +0000 | |||
3 | +++ audittrail/audittrail.py 2013-10-16 08:27:50 +0000 | |||
4 | @@ -284,6 +284,7 @@ | |||
5 | 284 | res_ids = [] | 284 | res_ids = [] |
6 | 285 | if args: | 285 | if args: |
7 | 286 | res_ids = args[0] | 286 | res_ids = args[0] |
8 | 287 | <<<<<<< TREE | ||
9 | 287 | if isinstance(res_ids, (long, int)): | 288 | if isinstance(res_ids, (long, int)): |
10 | 288 | res_ids = [res_ids] | 289 | res_ids = [res_ids] |
11 | 289 | if res_ids: | 290 | if res_ids: |
12 | @@ -305,6 +306,88 @@ | |||
13 | 305 | This function simply read all the fields of the given res_ids, and also recurisvely on | 306 | This function simply read all the fields of the given res_ids, and also recurisvely on |
14 | 306 | all records of a x2m fields read that need to be logged. Then it returns the result in | 307 | all records of a x2m fields read that need to be logged. Then it returns the result in |
15 | 307 | convenient structure that will be used as comparison basis. | 308 | convenient structure that will be used as comparison basis. |
16 | 309 | ======= | ||
17 | 310 | old_values = self.get_data(cr, uid_orig, pool, res_ids, model, method) | ||
18 | 311 | res = fct_src(cr, uid_orig, model.model, method, *args, **kw) | ||
19 | 312 | else: # method is write, action or workflow action | ||
20 | 313 | res_ids = [] | ||
21 | 314 | if args: | ||
22 | 315 | res_ids = args[0] | ||
23 | 316 | if isinstance(res_ids, (long, int)): | ||
24 | 317 | res_ids = [res_ids] | ||
25 | 318 | if res_ids: | ||
26 | 319 | # store the old values into a dictionary | ||
27 | 320 | old_values = self.get_data(cr, uid_orig, pool, res_ids, model, method) | ||
28 | 321 | # process the original function, workflow trigger... | ||
29 | 322 | res = fct_src(cr, uid_orig, model.model, method, *args, **kw) | ||
30 | 323 | if method == 'copy': | ||
31 | 324 | res_ids = [res] | ||
32 | 325 | if res_ids: | ||
33 | 326 | # check the new values and store them into a dictionary | ||
34 | 327 | new_values = self.get_data(cr, uid_orig, pool, res_ids, model, method) | ||
35 | 328 | # compare the old and new values and create audittrail log if needed | ||
36 | 329 | self.process_data(cr, uid_orig, pool, res_ids, model, method, old_values, new_values, field_list) | ||
37 | 330 | return res | ||
38 | 331 | |||
39 | 332 | def get_data(self, cr, uid, pool, res_ids, model, method): | ||
40 | 333 | """ | ||
41 | 334 | This function simply read all the fields of the given res_ids, and also recurisvely on | ||
42 | 335 | all records of a x2m fields read that need to be logged. Then it returns the result in | ||
43 | 336 | convenient structure that will be used as comparison basis. | ||
44 | 337 | |||
45 | 338 | :param cr: the current row, from the database cursor, | ||
46 | 339 | :param uid: the current user’s ID. This parameter is currently not used as every | ||
47 | 340 | operation to get data is made as super admin. Though, it could be usefull later. | ||
48 | 341 | :param pool: current db's pooler object. | ||
49 | 342 | :param res_ids: Id's of resource to be logged/compared. | ||
50 | 343 | :param model: Object whose values are being changed | ||
51 | 344 | :param method: method to log: create, read, unlink, write, actions, workflow actions | ||
52 | 345 | :return: dict mapping a tuple (model_id, resource_id) with its value and textual value | ||
53 | 346 | { (model_id, resource_id): { 'value': ... | ||
54 | 347 | 'textual_value': ... | ||
55 | 348 | }, | ||
56 | 349 | } | ||
57 | 350 | """ | ||
58 | 351 | data = {} | ||
59 | 352 | resource_pool = pool.get(model.model) | ||
60 | 353 | # read all the fields of the given resources in super admin mode | ||
61 | 354 | for resource in resource_pool.read(cr, SUPERUSER_ID, res_ids): | ||
62 | 355 | values = {} | ||
63 | 356 | values_text = {} | ||
64 | 357 | resource_id = resource['id'] | ||
65 | 358 | # loop on each field on the res_ids we just have read | ||
66 | 359 | for field in resource: | ||
67 | 360 | if field in ('__last_update', 'id') or not resource_pool._all_columns.get(field): | ||
68 | 361 | continue | ||
69 | 362 | values[field] = resource[field] | ||
70 | 363 | # get the textual value of that field for this record | ||
71 | 364 | values_text[field] = self.get_value_text(cr, SUPERUSER_ID, pool, resource_pool, method, field, resource[field]) | ||
72 | 365 | |||
73 | 366 | field_obj = resource_pool._all_columns.get(field).column | ||
74 | 367 | if field_obj._type in ('one2many','many2many'): | ||
75 | 368 | # check if an audittrail rule apply in super admin mode | ||
76 | 369 | if self.check_rules(cr, SUPERUSER_ID, field_obj._obj, method): | ||
77 | 370 | # check if the model associated to a *2m field exists, in super admin mode | ||
78 | 371 | x2m_model_ids = pool.get('ir.model').search(cr, SUPERUSER_ID, [('model', '=', field_obj._obj)]) | ||
79 | 372 | x2m_model_id = x2m_model_ids and x2m_model_ids[0] or False | ||
80 | 373 | assert x2m_model_id, _("'%s' Model does not exist..." %(field_obj._obj)) | ||
81 | 374 | x2m_model = pool.get('ir.model').browse(cr, SUPERUSER_ID, x2m_model_id) | ||
82 | 375 | field_resource_ids = list(set(resource[field])) | ||
83 | 376 | if model.model == x2m_model.model: | ||
84 | 377 | # we need to remove current resource_id from the many2many to prevent an infinit loop | ||
85 | 378 | if resource_id in field_resource_ids: | ||
86 | 379 | field_resource_ids.remove(resource_id) | ||
87 | 380 | data.update(self.get_data(cr, SUPERUSER_ID, pool, field_resource_ids, x2m_model, method)) | ||
88 | 381 | |||
89 | 382 | data[(model.id, resource_id)] = {'text':values_text, 'value': values} | ||
90 | 383 | return data | ||
91 | 384 | |||
92 | 385 | def prepare_audittrail_log_line(self, cr, uid, pool, model, resource_id, method, old_values, new_values, field_list=None): | ||
93 | 386 | """ | ||
94 | 387 | This function compares the old data (i.e before the method was executed) and the new data | ||
95 | 388 | (after the method was executed) and returns a structure with all the needed information to | ||
96 | 389 | log those differences. | ||
97 | 390 | >>>>>>> MERGE-SOURCE | ||
98 | 308 | 391 | ||
99 | 309 | :param cr: the current row, from the database cursor, | 392 | :param cr: the current row, from the database cursor, |
100 | 310 | :param uid: the current user’s ID. This parameter is currently not used as every | 393 | :param uid: the current user’s ID. This parameter is currently not used as every |
101 | @@ -346,6 +429,7 @@ | |||
102 | 346 | field_resource_ids = list(set(resource[field])) | 429 | field_resource_ids = list(set(resource[field])) |
103 | 347 | if model.model == x2m_model.model: | 430 | if model.model == x2m_model.model: |
104 | 348 | # we need to remove current resource_id from the many2many to prevent an infinit loop | 431 | # we need to remove current resource_id from the many2many to prevent an infinit loop |
105 | 432 | <<<<<<< TREE | ||
106 | 349 | if resource_id in field_resource_ids: | 433 | if resource_id in field_resource_ids: |
107 | 350 | field_resource_ids.remove(resource_id) | 434 | field_resource_ids.remove(resource_id) |
108 | 351 | data.update(get_data(cr, SUPERUSER_ID, pool, field_resource_ids, x2m_model, method)) | 435 | data.update(get_data(cr, SUPERUSER_ID, pool, field_resource_ids, x2m_model, method)) |
109 | @@ -502,6 +586,99 @@ | |||
110 | 502 | return True | 586 | return True |
111 | 503 | elif method not in ('default_get','read','fields_view_get','fields_get','search','search_count','name_search','name_get','get','request_get', 'get_sc', 'unlink', 'write', 'create', 'read_group', 'import_data'): | 587 | elif method not in ('default_get','read','fields_view_get','fields_get','search','search_count','name_search','name_get','get','request_get', 'get_sc', 'unlink', 'write', 'create', 'read_group', 'import_data'): |
112 | 504 | if rule['log_action']: | 588 | if rule['log_action']: |
113 | 589 | ======= | ||
114 | 590 | if resource_id in res_ids: | ||
115 | 591 | res_ids.remove(resource_id) | ||
116 | 592 | for res_id in res_ids: | ||
117 | 593 | lines.update(self.prepare_audittrail_log_line(cr, SUPERUSER_ID, pool, x2m_model, res_id, method, old_values, new_values, field_list)) | ||
118 | 594 | # if the value value is different than the old value: record the change | ||
119 | 595 | if key not in old_values or key not in new_values or old_values[key]['value'][field_name] != new_values[key]['value'][field_name]: | ||
120 | 596 | data = { | ||
121 | 597 | 'name': field_name, | ||
122 | 598 | 'new_value': key in new_values and new_values[key]['value'].get(field_name), | ||
123 | 599 | 'old_value': key in old_values and old_values[key]['value'].get(field_name), | ||
124 | 600 | 'new_value_text': key in new_values and new_values[key]['text'].get(field_name), | ||
125 | 601 | 'old_value_text': key in old_values and old_values[key]['text'].get(field_name) | ||
126 | 602 | } | ||
127 | 603 | lines[key].append(data) | ||
128 | 604 | return lines | ||
129 | 605 | |||
130 | 606 | def process_data(self, cr, uid, pool, res_ids, model, method, old_values=None, new_values=None, field_list=None): | ||
131 | 607 | """ | ||
132 | 608 | This function processes and iterates recursively to log the difference between the old | ||
133 | 609 | data (i.e before the method was executed) and the new data and creates audittrail log | ||
134 | 610 | accordingly. | ||
135 | 611 | |||
136 | 612 | :param cr: the current row, from the database cursor, | ||
137 | 613 | :param uid: the current user’s ID, | ||
138 | 614 | :param pool: current db's pooler object. | ||
139 | 615 | :param res_ids: Id's of resource to be logged/compared. | ||
140 | 616 | :param model: model object which values are being changed | ||
141 | 617 | :param method: method to log: create, read, unlink, write, actions, workflow actions | ||
142 | 618 | :param old_values: dict of values read before execution of the method | ||
143 | 619 | :param new_values: dict of values read after execution of the method | ||
144 | 620 | :param field_list: optional argument containing the list of fields to log. Currently only | ||
145 | 621 | used when performing a read, it could be usefull later on if we want to log the write | ||
146 | 622 | on specific fields only. | ||
147 | 623 | :return: True | ||
148 | 624 | """ | ||
149 | 625 | if field_list is None: | ||
150 | 626 | field_list = [] | ||
151 | 627 | # loop on all the given ids | ||
152 | 628 | for res_id in res_ids: | ||
153 | 629 | # compare old and new values and get audittrail log lines accordingly | ||
154 | 630 | lines = self.prepare_audittrail_log_line(cr, uid, pool, model, res_id, method, old_values, new_values, field_list) | ||
155 | 631 | |||
156 | 632 | # if at least one modification has been found | ||
157 | 633 | for model_id, resource_id in lines: | ||
158 | 634 | current_model = pool.get('ir.model').browse(cr, uid, model_id).model | ||
159 | 635 | if method == 'unlink': | ||
160 | 636 | name = old_values[(model_id, resource_id)]['text'].get(pool.get(current_model)._rec_name) | ||
161 | 637 | else: | ||
162 | 638 | name = pool.get(current_model).name_get(cr, uid, [resource_id])[0][1] | ||
163 | 639 | vals = { | ||
164 | 640 | 'method': method, | ||
165 | 641 | 'object_id': model_id, | ||
166 | 642 | 'user_id': uid, | ||
167 | 643 | 'res_id': resource_id, | ||
168 | 644 | 'name': name, | ||
169 | 645 | } | ||
170 | 646 | if (model_id, resource_id) not in old_values and method not in ('copy', 'read'): | ||
171 | 647 | # the resource was not existing so we are forcing the method to 'create' | ||
172 | 648 | # (because it could also come with the value 'write' if we are creating | ||
173 | 649 | # new record through a one2many field) | ||
174 | 650 | vals.update({'method': 'create'}) | ||
175 | 651 | if (model_id, resource_id) not in new_values and method not in ('copy', 'read'): | ||
176 | 652 | # the resource is not existing anymore so we are forcing the method to 'unlink' | ||
177 | 653 | # (because it could also come with the value 'write' if we are deleting the | ||
178 | 654 | # record through a one2many field) | ||
179 | 655 | vals.update({'method': 'unlink'}) | ||
180 | 656 | # create the audittrail log in super admin mode, only if a change has been detected | ||
181 | 657 | if lines[(model_id, resource_id)]: | ||
182 | 658 | log_id = pool.get('audittrail.log').create(cr, SUPERUSER_ID, vals) | ||
183 | 659 | model = pool.get('ir.model').browse(cr, uid, model_id) | ||
184 | 660 | self.create_log_line(cr, SUPERUSER_ID, log_id, model, lines[(model_id, resource_id)]) | ||
185 | 661 | return True | ||
186 | 662 | |||
187 | 663 | def check_rules(self, cr, uid, model, method): | ||
188 | 664 | """ | ||
189 | 665 | Checks if auditrails is installed for that db and then if one rule match | ||
190 | 666 | @param cr: the current row, from the database cursor, | ||
191 | 667 | @param uid: the current user’s ID, | ||
192 | 668 | @param model: value of _name of the object which values are being changed | ||
193 | 669 | @param method: method to log: create, read, unlink,write,actions,workflow actions | ||
194 | 670 | @return: True or False | ||
195 | 671 | """ | ||
196 | 672 | pool = pooler.get_pool(cr.dbname) | ||
197 | 673 | if 'audittrail.rule' in pool.models: | ||
198 | 674 | model_ids = pool.get('ir.model').search(cr, SUPERUSER_ID, [('model', '=', model)]) | ||
199 | 675 | model_id = model_ids and model_ids[0] or False | ||
200 | 676 | if model_id: | ||
201 | 677 | rule_ids = pool.get('audittrail.rule').search(cr, SUPERUSER_ID, [('object_id', '=', model_id), ('state', '=', 'subscribed')]) | ||
202 | 678 | for rule in pool.get('audittrail.rule').read(cr, SUPERUSER_ID, rule_ids, ['user_id','log_read','log_write','log_create','log_unlink','log_action','log_workflow']): | ||
203 | 679 | if len(rule['user_id']) == 0 or uid in rule['user_id']: | ||
204 | 680 | if rule.get('log_'+method,0): | ||
205 | 681 | >>>>>>> MERGE-SOURCE | ||
206 | 505 | return True | 682 | return True |
207 | 506 | 683 | ||
208 | 507 | # Replace the openerp.service.model functions. | 684 | # Replace the openerp.service.model functions. |
Hello Lithin,
Please don't propose a merge proposal to its opposite source version. Here you proposed this to trunk source while it was intended for stable 7.0. Infact already a merge proposal was available for stable 7.0 https:/ /code.launchpad .net/~openerp- dev/openobject- addons/ 7.0-opw- 589931- rgo/+merge/ 156130 so there was no need to do this extra work.
Please keep this note for future reference. It will save time for all of us.
Thanks,