Skip to content

Commit 4365900

Browse files
tarteoantonioburic
authored andcommitted
[12.0] auditlog: Log exports
1 parent 6f8bb4c commit 4365900

File tree

7 files changed

+110
-17
lines changed

7 files changed

+110
-17
lines changed

auditlog/README.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ Contributors
115115
* Holden Rehg <holdenrehg@gmail.com>
116116
* Bhavesh Odedra <bodedra@opensourceintegrators.com>
117117
* Hardik Suthar <hsuthar@opensourceintegrators.com>
118+
* Dennis Sluijk <d.sluijk@onestein.nl>
118119

119120
Other credits
120121
~~~~~~~~~~~~~

auditlog/models/log.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Copyright 2015 ABF OSIELL <https://osiell.com>
22
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
33
from odoo import models, fields
4+
from odoo.tools.safe_eval import safe_eval
45

56

67
class AuditlogLog(models.Model):
@@ -12,6 +13,7 @@ class AuditlogLog(models.Model):
1213
model_id = fields.Many2one(
1314
'ir.model', string="Model")
1415
res_id = fields.Integer("Resource ID")
16+
res_ids = fields.Char("Resource IDs")
1517
user_id = fields.Many2one(
1618
'res.users', string="User")
1719
method = fields.Char("Method", size=64)
@@ -27,6 +29,15 @@ class AuditlogLog(models.Model):
2729
],
2830
string="Type")
2931

32+
def show_res_ids(self):
33+
self.ensure_one()
34+
return {
35+
"type": "ir.actions.act_window",
36+
"view_mode": "tree,form",
37+
"res_model": self.model_id.model,
38+
"domain": [("id", "in", safe_eval(self.res_ids))],
39+
}
40+
3041

3142
class AuditlogLogLine(models.Model):
3243
_name = 'auditlog.log.line'

auditlog/models/rule.py

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ class AuditlogRule(models.Model):
8282
help=("Select this if you want to keep track of creation on any "
8383
"record of the model of this rule"),
8484
states={'subscribed': [('readonly', True)]})
85+
log_export_data = fields.Boolean(
86+
"Log Exports",
87+
default=True,
88+
help=(
89+
"Select this if you want to keep track of exports "
90+
"of the model of this rule"
91+
),
92+
states={"subscribed": [("readonly", True)]},
93+
)
8594
log_type = fields.Selection(
8695
[('full', "Full log"),
8796
('fast', "Fast log"),
@@ -179,6 +188,12 @@ def _patch_methods(self):
179188
model_model._patch_method('unlink', rule._make_unlink())
180189
setattr(type(model_model), check_attr, True)
181190
updated = True
191+
# -> export_data
192+
check_attr = 'auditlog_ruled_export_data'
193+
if rule.log_export_data and not hasattr(model_model, check_attr):
194+
model_model._patch_method('export_data', rule._make_export_data())
195+
setattr(type(model_model), check_attr, True)
196+
updated = True
182197
return updated
183198

184199
@api.multi
@@ -187,7 +202,7 @@ def _revert_methods(self):
187202
updated = False
188203
for rule in self:
189204
model_model = self.env[rule.model_id.model]
190-
for method in ['create', 'read', 'write', 'unlink']:
205+
for method in ['create', 'read', 'write', 'unlink', 'export_data']:
191206
if getattr(rule, 'log_%s' % method) and hasattr(
192207
getattr(model_model, method), 'origin'):
193208
model_model._revert_method(method)
@@ -231,6 +246,28 @@ def get_auditlog_fields(self, model):
231246
if (not f.compute and not f.related) or f.store
232247
)
233248

249+
def _make_export_data(self):
250+
"""Instanciate a export method that log its calls."""
251+
self.ensure_one()
252+
log_type = self.log_type
253+
254+
def export_data(self, fields_to_export, raw_data=False):
255+
res = export_data.origin(self, fields_to_export, raw_data)
256+
self = self.with_context(auditlog_disabled=True)
257+
rule_model = self.env["auditlog.rule"]
258+
rule_model.sudo().create_logs(
259+
self.env.uid,
260+
self._name,
261+
self.ids,
262+
"export_data",
263+
None,
264+
None,
265+
{"log_type": log_type},
266+
)
267+
return res
268+
269+
return export_data
270+
234271
@api.multi
235272
def _make_create(self):
236273
"""Instanciate a create method that log its calls."""
@@ -393,24 +430,27 @@ def create_logs(self, uid, res_model, res_ids, method,
393430
log_model = self.env['auditlog.log']
394431
http_request_model = self.env['auditlog.http.request']
395432
http_session_model = self.env['auditlog.http.session']
433+
model_model = self.env[res_model]
434+
model_id = self.pool._auditlog_model_cache[res_model]
435+
auditlog_rule = self.env['auditlog.rule'].search([('model_id', '=', model_id)])
436+
vals = {
437+
'model_id': model_id,
438+
'method': method,
439+
'user_id': uid,
440+
'http_request_id': http_request_model.current_http_request(),
441+
'http_session_id': http_session_model.current_http_session(),
442+
}
443+
vals.update(additional_log_values or {})
444+
if method == 'export_data':
445+
vals.update({'name': res_model, 'res_ids': str(res_ids)})
446+
return log_model.create(vals)
447+
448+
log = log_model.create(vals)
396449
for res_id in res_ids:
397-
model_model = self.env[res_model]
398450
name = model_model.browse(res_id).name_get()
399-
model_id = self.pool._auditlog_model_cache[res_model]
400-
auditlog_rule = self.env['auditlog.rule'].search(
401-
[("model_id", "=", model_id)])
402451
res_name = name and name[0] and name[0][1]
403-
vals = {
404-
'name': res_name,
405-
'model_id': self.pool._auditlog_model_cache[res_model],
406-
'res_id': res_id,
407-
'method': method,
408-
'user_id': uid,
409-
'http_request_id': http_request_model.current_http_request(),
410-
'http_session_id': http_session_model.current_http_session(),
411-
}
412-
vals.update(additional_log_values or {})
413-
log = log_model.create(vals)
452+
log_vals = {**vals, 'name': res_name, 'res_id': res_id}
453+
log = log_model.create(log_vals)
414454
diff = DictDiffer(
415455
new_values.get(res_id, EMPTY_DICT),
416456
old_values.get(res_id, EMPTY_DICT))

auditlog/readme/CONTRIBUTORS.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
* Holden Rehg <holdenrehg@gmail.com>
44
* Bhavesh Odedra <bodedra@opensourceintegrators.com>
55
* Hardik Suthar <hsuthar@opensourceintegrators.com>
6+
* Dennis Sluijk <d.sluijk@onestein.nl>

auditlog/static/description/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
12
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
23
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
34
<head>
@@ -460,6 +461,7 @@ <h2><a class="toc-backref" href="#toc-entry-10">Contributors</a></h2>
460461
<li>Holden Rehg &lt;<a class="reference external" href="mailto:holdenrehg&#64;gmail.com">holdenrehg&#64;gmail.com</a>&gt;</li>
461462
<li>Bhavesh Odedra &lt;<a class="reference external" href="mailto:bodedra&#64;opensourceintegrators.com">bodedra&#64;opensourceintegrators.com</a>&gt;</li>
462463
<li>Hardik Suthar &lt;<a class="reference external" href="mailto:hsuthar&#64;opensourceintegrators.com">hsuthar&#64;opensourceintegrators.com</a>&gt;</li>
464+
<li>Dennis Sluijk &lt;<a class="reference external" href="mailto:d.sluijk&#64;onestein.nl">d.sluijk&#64;onestein.nl</a>&gt;</li>
463465
</ul>
464466
</div>
465467
<div class="section" id="other-credits">

auditlog/tests/test_auditlog.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,23 @@ def test_LogDuringUpdate(self):
181181
]))
182182
sql.rename_column(self.env.cr, Rule._table, temp_name, field_name)
183183

184+
def test_LogExport(self):
185+
self.groups_rule.subscribe()
186+
187+
auditlog_log = self.env["auditlog.log"]
188+
self.env["res.groups"].search([]).export_data(["name"])
189+
created_log = auditlog_log.search(
190+
[
191+
("model_id", "=", self.groups_model_id),
192+
("method", "=", "export_data"),
193+
]
194+
).ensure_one()
195+
self.assertTrue(created_log)
196+
action = created_log.show_res_ids()
197+
domain = action["domain"] # [('id', 'in', [1, 2, ...])]
198+
self.assertIsInstance(domain, list)
199+
self.assertIsInstance(domain[0][2], list)
200+
184201

185202
class TestAuditlogFull(TransactionCase, AuditlogCommon):
186203

auditlog/views/auditlog_view.xml

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<field name="log_write"/>
3434
<field name="log_unlink"/>
3535
<field name="log_create"/>
36+
<field name="log_export_data"/>
3637
</group>
3738
</group>
3839
</sheet>
@@ -52,6 +53,7 @@
5253
<field name="log_write"/>
5354
<field name="log_unlink"/>
5455
<field name="log_create"/>
56+
<field name="log_export_data"/>
5557
<field name="state"/>
5658
</tree>
5759
</field>
@@ -97,6 +99,16 @@
9799
<field name="arch" type="xml">
98100
<form string="Log">
99101
<sheet>
102+
<div class="oe_button_box" name="button_box">
103+
<button
104+
name="show_res_ids"
105+
type="object"
106+
class="oe_stat_button"
107+
attrs="{'invisible': [('res_ids', '=', False)]}"
108+
icon="fa-external-link"
109+
string="Exported Records"
110+
/>
111+
</div>
100112
<group string="Log">
101113
<group colspan="1">
102114
<field name="create_date" readonly="1"/>
@@ -106,7 +118,16 @@
106118
</group>
107119
<group colspan="1">
108120
<field name="model_id" readonly="1"/>
109-
<field name="res_id" readonly="1"/>
121+
<field
122+
name="res_id"
123+
readonly="1"
124+
attrs="{'invisible': [('res_id', '=', 0)]}"
125+
/>
126+
<field
127+
name="res_ids"
128+
readonly="1"
129+
attrs="{'invisible': [('res_ids', '=', False)]}"
130+
/>
110131
<field name="name" readonly="1"/>
111132
</group>
112133
</group>

0 commit comments

Comments
 (0)