Merge lp:~fabien-morin/unifield-server/fm-us-2160 into lp:unifield-server
- fm-us-2160
- Merge into trunk
Status: | Rejected |
---|---|
Rejected by: | jftempo |
Proposed branch: | lp:~fabien-morin/unifield-server/fm-us-2160 |
Merge into: | lp:unifield-server |
Diff against target: |
412 lines (+164/-96) 7 files modified
bin/addons/base/base_update.xml (+0/-47) bin/addons/base/res/res_user.py (+78/-36) bin/addons/msf_audittrail/__openerp__.py (+1/-0) bin/addons/msf_audittrail/audittrail.py (+6/-6) bin/addons/msf_audittrail/data/audittrail_res_users.yml (+69/-0) bin/addons/unifield_setup/unifield_setup_data.xml (+0/-6) bin/service/web_services.py (+10/-1) |
To merge this branch: | bzr merge lp:~fabien-morin/unifield-server/fm-us-2160 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+315653@code.launchpad.net |
Commit message
Description of the change
- 4166. By Fabien MORIN
-
US-2160 [FIX] remove password from the list of tracked changes fields.
- 4167. By Fabien MORIN
-
US-2160 [FIX] add audittrail line on related user when a group is created with
users.
[FIX] m2m syntax on res.groups. i.e write
{'users': [(3, 73)]} - 4168. By Fabien MORIN
-
US-2160 [IMP] do not use view=extended/
simple anymore. Add the extended group
to admin at database creation to make possible for him to install other
modules. - 4169. By Fabien MORIN
-
US-2160 [FIX] check user_obj have a check_audit method (only if sync_client
installed) before to continue. - 4170. By Fabien MORIN
-
US-2160 [FIX] user_id was missing in the call of _track_
change_ of_users( )
[IMP] make the code a bit more crash proof after reading the complet diff of
the ticket. - 4171. By Fabien MORIN
-
US-2160 [FIX] typo
- 4172. By Fabien MORIN
-
US-2160 [MERGE] with latest trunk
- 4173. By Fabien MORIN
-
US-2160 [FIX] tuple comprenhension return a generator while we need a list or a
tuple.
[FIX] give the list of ids to name_get to have a list of result (instead of
only one).
[IMP] user translation_obj instead of calling self.pool.get all the time
jftempo (jfb-tempo-consulting) : | # |
Fabien MORIN (fabien-morin) wrote : | # |
- 4174. By Fabien MORIN
-
US-2160 [FIX] the current class is groups2, not groups
Unmerged revisions
- 4174. By Fabien MORIN
-
US-2160 [FIX] the current class is groups2, not groups
Preview Diff
1 | === modified file 'bin/addons/base/base_update.xml' |
2 | --- bin/addons/base/base_update.xml 2016-11-16 07:57:07 +0000 |
3 | +++ bin/addons/base/base_update.xml 2017-02-20 13:31:41 +0000 |
4 | @@ -139,7 +139,6 @@ |
5 | <field name="context_lang"/> |
6 | <field name="context_tz"/> |
7 | <group colspan="2" col="4"> |
8 | - <field name="view" readonly="0"/> |
9 | <field name="menu_tips" colspan="2"/> |
10 | </group> |
11 | </group> |
12 | @@ -314,57 +313,11 @@ |
13 | <field name="target">new</field> |
14 | </record> |
15 | |
16 | - <record id="view_confirm_simple_view_form" model="ir.ui.view"> |
17 | - <field name="name">Configure Your Interface</field> |
18 | - <field name="model">res.config.view</field> |
19 | - <field name="type">form</field> |
20 | - <field name="inherit_id" ref="res_config_view_base"/> |
21 | - <field name="arch" type="xml"> |
22 | - <data> |
23 | - <form position="attributes"> |
24 | - <attribute name="string">Configure Your Interface</attribute> |
25 | - </form> |
26 | - <xpath expr="//label[@string='description']" |
27 | - position="attributes"> |
28 | - <attribute name="string">If you use OpenERP for the first time we strongly advise you to select the simplified interface, which has less features but is easier. You can always switch later from the user preferences.</attribute> |
29 | - </xpath> |
30 | - <xpath expr='//separator[@string="title"]' position='attributes'> |
31 | - <attribute name='string'>Configure Your Interface</attribute> |
32 | - </xpath> |
33 | - <xpath expr='//separator[@string="vsep"]' position='attributes'> |
34 | - <attribute name='string'></attribute> |
35 | - <attribute name='rowspan'>12</attribute> |
36 | - </xpath> |
37 | - <group string="res_config_contents" position="replace"> |
38 | - <group colspan="4"> |
39 | - <field colspan="4" name="view" nolabel="1"/> |
40 | - </group> |
41 | - </group> |
42 | - <xpath expr='//button[@name="action_skip"]' position='replace'/> |
43 | - </data> |
44 | - </field> |
45 | - </record> |
46 | - |
47 | - <record id="action_config_simple_view_form" model="ir.actions.act_window"> |
48 | - <field name="name">Configure Your Interface</field> |
49 | - <field name="type">ir.actions.act_window</field> |
50 | - <field name="res_model">res.config.view</field> |
51 | - <field name="view_type">form</field> |
52 | - <field name="view_id" ref="view_confirm_simple_view_form"/> |
53 | - <field name="view_mode">form</field> |
54 | - <field name="target">new</field> |
55 | - </record> |
56 | - |
57 | <record id="config_wizard_step_user" model="ir.actions.todo"> |
58 | <field name="action_id" ref="action_config_user_form"/> |
59 | <field name="sequence">10</field> |
60 | <field name="restart">never</field> |
61 | <field name="state">done</field> |
62 | </record> |
63 | - <record id="config_wizard_simple_view" model="ir.actions.todo"> |
64 | - <field name="action_id" ref="action_config_simple_view_form"/> |
65 | - <field name="restart">always</field> |
66 | - <field name="sequence">1</field> |
67 | - </record> |
68 | </data> |
69 | </openerp> |
70 | |
71 | === modified file 'bin/addons/base/res/res_user.py' |
72 | --- bin/addons/base/res/res_user.py 2017-01-03 16:05:44 +0000 |
73 | +++ bin/addons/base/res/res_user.py 2017-02-20 13:31:41 +0000 |
74 | @@ -114,6 +114,7 @@ |
75 | _uid_cache = {} |
76 | _name = "res.users" |
77 | _order = 'name' |
78 | + _trace = True |
79 | |
80 | WELCOME_MAIL_SUBJECT = u"Welcome to OpenERP" |
81 | WELCOME_MAIL_BODY = u"An OpenERP account has been created for you, "\ |
82 | @@ -178,36 +179,6 @@ |
83 | body=self.get_welcome_mail_body( |
84 | cr, uid, context=context) % user) |
85 | |
86 | - def _set_interface_type(self, cr, uid, ids, name, value, arg, context=None): |
87 | - """Implementation of 'view' function field setter, sets the type of interface of the users. |
88 | - @param name: Name of the field |
89 | - @param arg: User defined argument |
90 | - @param value: new value returned |
91 | - @return: True/False |
92 | - """ |
93 | - if not value or value not in ['simple','extended']: |
94 | - return False |
95 | - group_obj = self.pool.get('res.groups') |
96 | - extended_group_id = group_obj.get_extended_interface_group(cr, uid, context=context) |
97 | - # First always remove the users from the group (avoids duplication if called twice) |
98 | - self.write(cr, uid, ids, {'groups_id': [(3, extended_group_id)]}, context=context) |
99 | - # Then add them back if requested |
100 | - if value == 'extended': |
101 | - self.write(cr, uid, ids, {'groups_id': [(4, extended_group_id)]}, context=context) |
102 | - return True |
103 | - |
104 | - |
105 | - def _get_interface_type(self, cr, uid, ids, name, args, context=None): |
106 | - """Implementation of 'view' function field getter, returns the type of interface of the users. |
107 | - @param field_name: Name of the field |
108 | - @param arg: User defined argument |
109 | - @return: Dictionary of values |
110 | - """ |
111 | - group_obj = self.pool.get('res.groups') |
112 | - extended_group_id = group_obj.get_extended_interface_group(cr, uid, context=context) |
113 | - extended_users = group_obj.read(cr, uid, extended_group_id, ['users'], context=context)['users'] |
114 | - return dict(zip(ids, ['extended' if user in extended_users else 'simple' for user in ids])) |
115 | - |
116 | def _email_get(self, cr, uid, ids, name, arg, context=None): |
117 | # perform this as superuser because the current user is allowed to read users, and that includes |
118 | # the email, even without any direct read access on the res_partner_address object. |
119 | @@ -294,8 +265,9 @@ |
120 | for user_id in ids: |
121 | level = False |
122 | company_id = self._get_company(cr, user_id, context=context) |
123 | - instance_id = self.pool.get('res.company').read(cr, uid, company_id, |
124 | - ['instance_id'], context=context)['instance_id'] |
125 | + company_obj = self.pool.get('res.company') |
126 | + instance_id = company_obj.read(cr, uid, company_id, |
127 | + ['instance_id'], context=context).get('instance_id', False) |
128 | instance_id = instance_id and instance_id[0] or False |
129 | if instance_id: |
130 | level = self.pool.get('msf.instance').read(cr, uid, instance_id, ['level'], context=context)['level'] |
131 | @@ -341,8 +313,7 @@ |
132 | 'context_tz': fields.selection(_tz_get, 'Timezone', size=64, |
133 | help="The user's timezone, used to perform timezone conversions " |
134 | "between the server and the client."), |
135 | - 'view': fields.function(_get_interface_type, method=True, type='selection', fnct_inv=_set_interface_type, |
136 | - selection=[('simple','Simplified'),('extended','Extended')], |
137 | + 'view': fields.selection([('simple','Simplified'),('extended','Extended')], |
138 | string='Interface', help="Choose between the simplified interface and the extended one"), |
139 | 'user_email': fields.function(_email_get, method=True, fnct_inv=_email_set, string='Email', type="char", size=240), |
140 | 'menu_tips': fields.boolean('Menu Tips', help="Check out this box if you want to always display tips on each menu action"), |
141 | @@ -452,6 +423,7 @@ |
142 | 'address_id': False, |
143 | 'menu_tips':True, |
144 | 'force_password_change': False, |
145 | + 'view': 'simple', |
146 | } |
147 | |
148 | @tools.cache() |
149 | @@ -789,6 +761,76 @@ |
150 | 'users': fields.many2many('res.users', 'res_groups_users_rel', 'gid', 'uid', 'Users'), |
151 | } |
152 | |
153 | + def _track_change_of_users(self, cr, uid, previous_values, user_ids, |
154 | + vals, context=None): |
155 | + '''add audittrail entry to the related users if their groups were changed |
156 | + @param previous_values: list of dict containing groups_ids of the users |
157 | + @param user_ids: related user ids |
158 | + @param vals: vals parameter from the write/create |
159 | + ''' |
160 | + current_values = {} |
161 | + audit_obj = self.pool.get('audittrail.rule') |
162 | + if isinstance(user_ids, (int, long)): |
163 | + user_ids = [user_ids] |
164 | + if 'users' in vals and user_ids: |
165 | + if vals['users'] and len(vals['users'][0]) > 2: |
166 | + users_deleted = list(set(user_ids).difference(vals['users'][0][2])) |
167 | + users_added = list(set(vals['users'][0][2]).difference(user_ids)) |
168 | + user_obj = self.pool.get('res.users') |
169 | + if not hasattr(user_obj, 'check_audit'): |
170 | + return |
171 | + audit_rule_ids = user_obj.check_audit(cr, uid, 'write') |
172 | + if users_deleted: |
173 | + previous_values = [x for x in previous_values if x['id'] in users_deleted] |
174 | + current_values = dict((x['id'], x) for x in user_obj.read(cr, uid, users_deleted, ['groups_id'], context=context)) |
175 | + audit_obj.audit_log(cr, uid, audit_rule_ids, user_obj, users_deleted, 'write', previous_values, current_values, context=context) |
176 | + if users_added: |
177 | + previous_values = [x for x in previous_values if x['id'] in users_added] |
178 | + current_values = dict((x['id'], x) for x in user_obj.read(cr, uid, users_added, ['groups_id'], context=context)) |
179 | + audit_obj.audit_log(cr, uid, audit_rule_ids, user_obj, users_added, 'write', previous_values, current_values, context=context) |
180 | + |
181 | + def create(self, cr, uid, vals, context=None): |
182 | + ''' |
183 | + In case user have been added, a new audit line should be created on the related users |
184 | + ''' |
185 | + change_user_group = False |
186 | + previous_values = [] |
187 | + if 'users' in vals and vals['users'] and len(vals['users'][0]) > 2: |
188 | + user_obj = self.pool.get('res.users') |
189 | + previous_values = user_obj.read(cr, uid, vals['users'][0][2], ['groups_id'], context=context) |
190 | + change_user_group = True |
191 | + user_id = super(groups2, self).create(cr, uid, vals, context=context) |
192 | + if change_user_group: |
193 | + self._track_change_of_users(cr, uid, previous_values, [user_id], |
194 | + vals, context=context) |
195 | + return user_id |
196 | + |
197 | + def write(self, cr, uid, ids, vals, context=None): |
198 | + ''' |
199 | + In case user have been added or deleted, a new audit line should be created on the related users |
200 | + ''' |
201 | + all_user_ids = [] # previous user ids + current |
202 | + previous_values = [] |
203 | + user_ids = [] |
204 | + if isinstance(ids, (int, long)): |
205 | + ids = [ids] |
206 | + if 'users' in vals: |
207 | + new_user_ids = [] |
208 | + if vals['users'] and len(vals['users'][0]) > 2: |
209 | + new_user_ids = vals['users'][0][2] |
210 | + for record in self.read(cr, uid, ids, ['users'], context=context): |
211 | + if record['users']: |
212 | + user_ids.extend(record['users']) |
213 | + all_user_ids = set(new_user_ids).union(user_ids) |
214 | + user_obj = self.pool.get('res.users') |
215 | + previous_values = user_obj.read(cr, uid, all_user_ids, ['groups_id'], context=context) |
216 | + |
217 | + res = super(groups2, self).write(cr, uid, ids, vals, context=context) |
218 | + if 'users' in vals: |
219 | + self._track_change_of_users(cr, uid, previous_values, user_ids, |
220 | + vals, context=context) |
221 | + return res |
222 | + |
223 | def unlink(self, cr, uid, ids, context=None): |
224 | group_users = [] |
225 | for record in self.read(cr, uid, ids, ['users'], context=context): |
226 | @@ -814,10 +856,10 @@ |
227 | 'name':fields.char('Name', size=64), |
228 | 'view': fields.selection([('simple','Simplified'), |
229 | ('extended','Extended')], |
230 | - 'Interface', required=True ), |
231 | + 'Interface', required=False ), |
232 | } |
233 | _defaults={ |
234 | - 'view':lambda self,cr,uid,*args: self.pool.get('res.users').browse(cr, uid, uid).view or 'simple', |
235 | + 'view': 'simple', |
236 | } |
237 | |
238 | def execute(self, cr, uid, ids, context=None): |
239 | |
240 | === modified file 'bin/addons/msf_audittrail/__openerp__.py' |
241 | --- bin/addons/msf_audittrail/__openerp__.py 2016-06-07 15:10:42 +0000 |
242 | +++ bin/addons/msf_audittrail/__openerp__.py 2017-02-20 13:31:41 +0000 |
243 | @@ -46,6 +46,7 @@ |
244 | 'data/audittrail_data_purchase.yml', |
245 | 'data/audittrail_data_products.yml', |
246 | 'data/audittrail_data_JI.yml', |
247 | + 'data/audittrail_res_users.yml', |
248 | 'audittrail_report.xml', |
249 | 'audittrail_invoice_data.yml', |
250 | ], |
251 | |
252 | === modified file 'bin/addons/msf_audittrail/audittrail.py' |
253 | --- bin/addons/msf_audittrail/audittrail.py 2017-02-06 11:14:07 +0000 |
254 | +++ bin/addons/msf_audittrail/audittrail.py 2017-02-20 13:31:41 +0000 |
255 | @@ -795,7 +795,7 @@ |
256 | """ |
257 | _name = 'audittrail.log.line' |
258 | _description = "Log Line" |
259 | - _order = 'timestamp desc, id desc' |
260 | + _order = 'timestamp desc, log desc' |
261 | |
262 | def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): |
263 | """ |
264 | @@ -1050,9 +1050,8 @@ |
265 | res = [] |
266 | if values and values != '[]': |
267 | values = values[1:-1].split(',') |
268 | - values = (int(v) for v in values) |
269 | - res = [x[1] for x in relation_model_pool.name_get(cr, uid, |
270 | - [long(values[0])])] |
271 | + values = [int(v) for v in values] |
272 | + res = [x[1] for x in relation_model_pool.name_get(cr, uid, values)] |
273 | return res |
274 | elif field['ttype'] == 'date': |
275 | res = False |
276 | @@ -1076,15 +1075,16 @@ |
277 | elif field['ttype'] == 'selection': |
278 | res = False |
279 | if values: |
280 | + translation_obj = self.pool.get('ir.translation') |
281 | fct_object = model_pool.browse(cr, uid, model.id, context=context).model |
282 | sel = self.pool.get(fct_object).fields_get(cr, uid, [field['name']]) |
283 | if field['name'] in sel: |
284 | res = dict(sel[field['name']]['selection']).get(values) |
285 | name = '%s,%s' % (fct_object, field['name']) |
286 | # Search translation |
287 | - res_tr_ids = self.pool.get('ir.translation').search(cr, uid, [('type', '=', 'selection'), ('name', '=', name), ('src', 'in', [values])]) |
288 | + res_tr_ids = translation_obj.search(cr, uid, [('type', '=', 'selection'), ('name', '=', name), ('src', 'in', [values])]) |
289 | if res_tr_ids: |
290 | - res = self.pool.get('ir.translation').read(cr, uid, res_tr_ids, ['value'])[0]['value'] |
291 | + res = translation_obj.read(cr, uid, res_tr_ids, ['value'])[0]['value'] |
292 | else: |
293 | res = values |
294 | return res |
295 | |
296 | === added file 'bin/addons/msf_audittrail/data/audittrail_res_users.yml' |
297 | --- bin/addons/msf_audittrail/data/audittrail_res_users.yml 1970-01-01 00:00:00 +0000 |
298 | +++ bin/addons/msf_audittrail/data/audittrail_res_users.yml 2017-02-20 13:31:41 +0000 |
299 | @@ -0,0 +1,69 @@ |
300 | +- |
301 | + For Users, rule for the CREATE of objects with the list of fields to track |
302 | +- |
303 | + !python {model: audittrail.rule}: | |
304 | + name = 'USER CREATE' |
305 | + object_ids = self.pool.get('ir.model').search(cr, uid, [('model', '=', 'res.users')], context=context) |
306 | + rule_id = self.search(cr, uid, [('name', '=', name)], context=context) |
307 | + if object_ids: |
308 | + fields = ['action_id', 'active', 'address_id', 'email', 'force_password_change', 'groups_id', 'login', 'menu_id', 'menu_tips', 'name', 'signature', 'user_email'] |
309 | + fields_ids = self.pool.get('ir.model.fields').search(cr, uid, [('model', '=' ,'res.users'), ('name', 'in', fields)], context=context) |
310 | + vals = {'name': name, |
311 | + 'object_id': object_ids[0], |
312 | + 'log_create': True, |
313 | + 'log_write': False, |
314 | + 'log_unlink': False, |
315 | + 'field_ids': [(6, 0, fields_ids)], |
316 | + } |
317 | + if not rule_id: |
318 | + rule_id = self.create(cr, uid, vals, context=context) |
319 | + elif rule_id: |
320 | + self.write(cr, uid, rule_id, vals, context=context) |
321 | + # Subscribe to the rule |
322 | + self.subscribe(cr, uid, rule_id) |
323 | +- |
324 | + For Users, rule for the WRITE of objects with the list of fields to track |
325 | +- |
326 | + !python {model: audittrail.rule}: | |
327 | + name = 'USER WRITE' |
328 | + object_ids = self.pool.get('ir.model').search(cr, uid, [('model', '=', 'res.users')], context=context) |
329 | + rule_id = self.search(cr, uid, [('name', '=', name)], context=context) |
330 | + if object_ids: |
331 | + fields = ['action_id', 'active', 'address_id', 'email', 'force_password_change', 'groups_id', 'login', 'menu_id', 'menu_tips', 'name', 'signature', 'user_email'] |
332 | + fields_ids = self.pool.get('ir.model.fields').search(cr, uid, [('model', '=' ,'res.users'), ('name', 'in', fields)], context=context) |
333 | + vals = {'name': name, |
334 | + 'object_id': object_ids[0], |
335 | + 'log_create': False, |
336 | + 'log_write': True, |
337 | + 'log_unlink': False, |
338 | + 'field_ids': [(6, 0, fields_ids)], |
339 | + } |
340 | + if not rule_id: |
341 | + rule_id = self.create(cr, uid, vals, context=context) |
342 | + elif rule_id: |
343 | + self.write(cr, uid, rule_id, vals, context=context) |
344 | + # Subscribe to the rule |
345 | + self.subscribe(cr, uid, rule_id) |
346 | +- |
347 | + For USERS, rule for the DELETE of objects with the list of fields to track |
348 | +- |
349 | + !python {model: audittrail.rule}: | |
350 | + name = 'USER DELETE' |
351 | + object_ids = self.pool.get('ir.model').search(cr, uid, [('model', '=', 'res.users')], context=context) |
352 | + rule_id = self.search(cr, uid, [('name', '=', name)], context=context) |
353 | + if object_ids: |
354 | + fields = ['name'] |
355 | + fields_ids = self.pool.get('ir.model.fields').search(cr, uid, [('model', '=' ,'res.users'), ('name', 'in', fields)], context=context) |
356 | + vals = {'name': name, |
357 | + 'object_id': object_ids[0], |
358 | + 'log_create': False, |
359 | + 'log_write': False, |
360 | + 'log_unlink': True, |
361 | + 'field_ids': [(6, 0, fields_ids)], |
362 | + } |
363 | + if not rule_id: |
364 | + rule_id = self.create(cr, uid, vals, context=context) |
365 | + elif rule_id: |
366 | + self.write(cr, uid, rule_id, vals, context=context) |
367 | + # Subscribe to the rule |
368 | + self.subscribe(cr, uid, rule_id) |
369 | |
370 | === modified file 'bin/addons/unifield_setup/unifield_setup_data.xml' |
371 | --- bin/addons/unifield_setup/unifield_setup_data.xml 2012-11-19 17:26:48 +0000 |
372 | +++ bin/addons/unifield_setup/unifield_setup_data.xml 2017-02-20 13:31:41 +0000 |
373 | @@ -3,12 +3,6 @@ |
374 | <data noupdate="0"> |
375 | |
376 | <!-- Re-order the configuration wizards sequences --> |
377 | - <record id="base.config_wizard_simple_view" model="ir.actions.todo"> |
378 | - <field name="sequence" eval="1" /> |
379 | - <field name="restart">never</field> |
380 | - <field name="state">done</field> |
381 | - </record> |
382 | - |
383 | <record id="base_setup.base_setup_company_todo" model="ir.actions.todo"> |
384 | <field name="sequence" eval="17" /> |
385 | <field name="restart">always</field> |
386 | |
387 | === modified file 'bin/service/web_services.py' |
388 | --- bin/service/web_services.py 2017-01-31 11:13:35 +0000 |
389 | +++ bin/service/web_services.py 2017-02-20 13:31:41 +0000 |
390 | @@ -167,12 +167,21 @@ |
391 | mids = modobj.search(cr, 1, [('state', '=', 'installed')]) |
392 | modobj.update_translations(cr, 1, mids, lang) |
393 | |
394 | - cr.execute('UPDATE res_users SET password=%s, context_lang=%s, active=True WHERE login=%s', ( |
395 | + cr.execute('UPDATE res_users SET password=%s, context_lang=%s, active=True WHERE login=%s RETURNING id', ( |
396 | user_password, lang, 'admin')) |
397 | + uid = cr.fetchone()[0] |
398 | cr.execute('SELECT login, password, name ' \ |
399 | ' FROM res_users ' \ |
400 | ' ORDER BY login') |
401 | serv.actions[id]['users'] = cr.dictfetchall() |
402 | + |
403 | + # add the extended interface group to the admin user |
404 | + # this is needed to be able to install other modules |
405 | + res_group_obj = pool.get('res.groups') |
406 | + group_extended_id = res_group_obj.get_extended_interface_group(cr, 1) |
407 | + if group_extended_id: |
408 | + res_users_obj = pool.get('res.users') |
409 | + res_users_obj.write(cr, uid, uid, {'groups_id': [(4, group_extended_id)]}) |
410 | serv.actions[id]['clean'] = True |
411 | cr.commit() |
412 | except Exception, e: |
Fixed
On Monday 20 February 2017 13:06:51 you wrote: base/res/ res_user. py' base/res/ res_user. py 2017-01-03 16:05:44 +0000 base/res/ res_user. py 2017-02-16 09:43:29 +0000 many2many( 'res.users' , 'res_groups_ users_rel' , change_ of_users( self, cr, uid, previous_values, user_ids, get('audittrail .rule') user_ids, (int, long)): 'users' ][0]) > 2: user_ids) .difference( vals['users' ][0][2] )) + vals['users' ][0][2] ).difference( user_ids) ) + get('res. users') check_audit( cr, uid, 'write') audit_log( cr, uid, audit_rule_ids, user_obj, users_deleted, audit_log( cr, uid, audit_rule_ids, user_obj, users_added, 'users' ][0]) > get('res. users') ][0][2] ,
> Diff comments:
> > === modified file 'bin/addons/
> > --- bin/addons/
> > +++ bin/addons/
> > @@ -789,6 +761,76 @@
> >
> > 'users': fields.
> > 'gid', 'uid', 'Users'),>
> > }
> >
> > + def _track_
> > + vals, context=None):
> > + '''add audittrail entry to the related users if their groups were
> > changed + @param previous_values: list of dict containing
> > groups_ids of the users + @param user_ids: related user ids
> > + @param vals: vals parameter from the write/create
> > + '''
> > + current_values = {}
> > + audit_obj = self.pool.
> > + if isinstance(
> > + user_ids = [user_ids]
> > + if 'users' in vals and user_ids:
> > + if vals['users'] and len(vals[
> > + users_deleted =
> > list(set(
> > users_added = list(set(
> > user_obj = self.pool.
> > + if not hasattr(user_obj, 'check_audit'):
> > + return
> > + audit_rule_ids = user_obj.
> > + if users_deleted:
> > + previous_values = [x for x in previous_values if
> > x['id'] in users_deleted] + current_values =
> > dict((x['id'], x) for x in user_obj.read(cr, uid, users_deleted,
> > ['groups_id'], context=context)) +
> > audit_obj.
> > 'write', previous_values, current_values, context=context) +
> > if users_added:
> > + previous_values = [x for x in previous_values if
> > x['id'] in users_added] + current_values =
> > dict((x['id'], x) for x in user_obj.read(cr, uid, users_added,
> > ['groups_id'], context=context)) +
> > audit_obj.
> > 'write', previous_values, current_values, context=context) +
> > + def create(self, cr, uid, vals, context=None):
> > + '''
> > + In case user have been added, a new audit line should be created
> > on the related users + '''
> > + change_user_group = False
> > + previous_values = []
> > + if 'users' in vals and vals['users'] and len(vals[
> > 2: + user_obj = self.pool.
> > + previous_values = user_obj.read(cr, uid, vals['users'
> > ['groups_id'], context=context) + change_user_group = True
> > + user_id = super(groups, self).create(cr, uid, vals,
> > context=context)
> > + if change_user_group:
> "Funny" bug here: you a not in groups() class but in groups2, so it should
> be user_id = super(grou...