11# Copyright 2021 Therp B.V.
22# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
33
4- from odoo import models , fields , api , modules , _
4+ from odoo import exceptions , models , fields , api , modules , _
55from odoo .addons .auditlog .models .rule import FIELDS_BLACKLIST
66
77
@@ -10,20 +10,36 @@ class AuditlogRule(models.Model):
1010
1111 field_ids = fields .Many2many (
1212 "ir.model.fields" ,
13- required = True ,
1413 )
1514 group_ids = fields .Many2many (
1615 "res.groups" ,
17- string = "Groups" ,
16+ default = lambda x : x . env . ref ( 'base.group_user' ) ,
1817 help = """Groups that will be allowed to see the logged fields, if left empty
19- all groups will be allowed (global rule creation) """ ,
18+ default will be all users with a login """ ,
2019 )
20+ all_fields = fields .Boolean (
21+ string = "Publicly visible log lines for all fields" ,
22+ readonly = True ,
23+ compute = "compute_all_fields" ,
24+ store = False ,
25+ help = "Check this field if you want this model to be visible by everyone" )
26+
27+ @api .depends ('field_ids' )
28+ def compute_all_fields (self ):
29+ for this in self .sudo ():
30+ this .all_fields = not bool (len (this .field_ids ))
31+
32+ @api .onchange ('model_id' )
33+ def onchange_model_id (self ):
34+ # if model changes we must wipe out all field ids
35+ self .field_ids = False
36+
2137
22- """ note this solution will work only with a hardcoded design of models,
23- because on initialization , self.model_id.id still is not defined.
24- for now, to keep generality we put the filtering in the view."""
2538
2639 def get_field_ids_domain (self ):
40+ """ note this solution will work only with a hardcoded design of models,
41+ because on initialization , self.model_id.id still is not defined.
42+ for now, to keep generality we put the filtering in the view."""
2743 return [
2844 ("model_id" , "=" , self .env .ref ("base.model_res_partner" ).id ),
2945 ("name" , "not in" , FIELDS_BLACKLIST ),
@@ -32,40 +48,63 @@ def get_field_ids_domain(self):
3248 def unlink (self ):
3349 # if we delete auditlog rule, corresponding ir.rules are removed
3450 # TODO PROPOSAL: a warning here with detailed information?
51+ to_delete = self .env ["ir.rule" ].with_context (auditlog_write = True ).search (
52+ [("auditlog_id" , "=" , self .ids )])
3553 res = super (AuditlogRule , self ).unlink ()
36- return (
37- res
38- and self .env ["ir.rule" ]
39- .with_context (auditlog_write = True )
40- .search ([("auditlog_id" , "in" , self .ids )])
41- .unlink ()
42- )
54+ if res :
55+ res = res and to_delete .unlink ()
56+ return res
4357
58+ @api .model
59+ def create (self , vals ):
60+ if 'group_ids' not in vals :
61+ # if group has been removed and no group specified ad base user default
62+ vals ['group_ids' ] = [(6 , 0 , [self .env .ref ('base.group_user' ).id ])]
63+ if 'field_ids' not in vals and not vals .get ('all_fields' ):
64+ # this was done because of a
65+ # bug in attrs={'required': [('all_fields', '!=', True}
66+ raise exceptions .ValidationError (
67+ _ ("please specify fields to log or make all_fields true" ))
68+ res = super (AuditlogRule , self ).create (vals )
69+ res .generate_rules ()
70+ return res
71+
4472 @api .multi
4573 def write (self , vals ):
4674 res = super (AuditlogRule , self ).write (vals )
4775 for this in self :
48- if any ([x in vals for x in ("group_ids" , "field_ids" , "model_id" )]):
76+ if not this .group_ids :
77+ # if no group is specified, we will not create a global, we
78+ # always put at least base.group_user
79+ this .write (
80+ {'group_ids' : [(6 , 0 , [
81+ self .env .ref ('base.group_user' ).id ])]})
82+ if any ([x in vals for x in (
83+ "group_ids" , "field_ids" , "model_id" , "all_fields" )]):
4984 this .generate_rules ()
5085 return res
5186
5287 def generate_rules (self ):
53- old_rule = self .env ["ir.rule" ].search ([("auditlog_id" , "=" , self .id )], limit = 1 )
54- domain_force = (
55- "[ "
56- + " ('log_id.model_id' , '=', %s)," % (self .model_id .id )
57- + "('field_id', 'in', %s)" % (self .field_ids .ids )
58- + "]"
59- )
60- values = {
88+ old_rule = self .env ["ir.rule" ].search (
89+ [("auditlog_id" , "=" , self .id )], limit = 1 )
90+ values = self ._prepare_rule_values ()
91+ if old_rule :
92+ old_rule .with_context (auditlog_write = True ).write (values )
93+ else :
94+ self .with_context (auditlog_write = True ).env ["ir.rule" ].create (
95+ values )
96+
97+ def _prepare_rule_values (self ):
98+ domain_force = "[" + " ('log_id.model_id' , '=', %s)," % (
99+ self .model_id .id )
100+ if self .field_ids :
101+ domain_force += "('field_id', 'in', %s)" % (self .field_ids .ids )
102+ domain_force += "]"
103+ return {
61104 "name" : "auditlog_extended_%s" % self .id ,
62105 "model_id" : self .env .ref ("auditlog.model_auditlog_log_line" ).id ,
63106 "groups" : [(6 , 0 , self .group_ids .ids )],
64107 "perm_read" : True ,
65108 "domain_force" : domain_force ,
66109 "auditlog_id" : self .id ,
67110 }
68- if old_rule :
69- old_rule .with_context (auditlog_write = True ).write (values )
70- else :
71- self .with_context (auditlog_write = True ).env ["ir.rule" ].create (values )
0 commit comments