From 62bfe8dcaf77b651103cb71c929684b388cc5563 Mon Sep 17 00:00:00 2001 From: "ksa (Open ERP)" Date: Mon, 31 May 2010 19:21:33 +0530 Subject: [PATCH 1/5] [ADD]: audittrail: product backlog -621 :Apply log detail for action in audittrail bzr revid: ksa@tinyerp.co.in-20100531135133-jhbej4htfiqfj5fe --- addons/audittrail/audittrail.py | 288 +++++++++++++++++++------- addons/audittrail/audittrail_view.xml | 140 +++++++------ addons/audittrail/i18n/it.po | 4 - 3 files changed, 289 insertions(+), 143 deletions(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index 16041889575..d6badfd7c46 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -25,6 +25,7 @@ from tools.translate import _ import ir import pooler import time +import tools class audittrail_rule(osv.osv): """ @@ -33,25 +34,28 @@ class audittrail_rule(osv.osv): _name = 'audittrail.rule' _description = "Audittrail Rule" _columns = { - "name": fields.char("Rule Name", size=32, required=True), - "object_id": fields.many2one('ir.model', 'Object', required=True), - "user_id": fields.many2many('res.users', 'audittail_rules_users', - 'user_id', 'rule_id', 'Users', help="if User is not added then it will applicable for all users"), - "log_read": fields.boolean("Log reads"), - "log_write": fields.boolean("Log writes"), - "log_unlink": fields.boolean("Log deletes"), - "log_create": fields.boolean("Log creates"), - "state": fields.selection((("draft", "Draft"), - ("subscribed", "Subscribed")), - "State", required=True), - "action_id": fields.many2one('ir.actions.act_window', "Action ID"), + "name": fields.char("Rule Name", size=32, required=True), + "object_id": fields.many2one('ir.model', 'Object', required=True), + "user_id": fields.many2many('res.users', 'audittail_rules_users', + 'user_id', 'rule_id', 'Users', help="if User is not added then it will applicable for all users"), + "log_read": fields.boolean("Log Reads"), + "log_write": fields.boolean("Log Writes"), + "log_unlink": fields.boolean("Log Deletes"), + "log_create": fields.boolean("Log Creates"), + "log_action": fields.boolean("Log Action"), + "log_workflow": fields.boolean("Log Workflow"), + "state": fields.selection((("draft", "Draft"), + ("subscribed", "Subscribed")), + "State", required=True), + "action_id": fields.many2one('ir.actions.act_window', "Action ID"), + } _defaults = { - 'state': lambda *a: 'draft', - 'log_create': lambda *a: 1, - 'log_unlink': lambda *a: 1, - 'log_write': lambda *a: 1, + 'state': lambda *a: 'draft', + 'log_create': lambda *a: 1, + 'log_unlink': lambda *a: 1, + 'log_write': lambda *a: 1, } _sql_constraints = [ @@ -65,7 +69,7 @@ class audittrail_rule(osv.osv): @param cr: the current row, from the database cursor, @param uid: the current user’s ID for security checks, @param ids: List of Auddittrail Rule’s IDs. - @return: True + @return: True """ obj_action = self.pool.get('ir.actions.act_window') obj_model = self.pool.get('ir.model.data') @@ -74,13 +78,13 @@ class audittrail_rule(osv.osv): obj = self.pool.get(thisrule.object_id.model) if not obj: raise osv.except_osv( - _('WARNING: audittrail is not part of the pool'), + _('WARNING: audittrail is not part of the pool'), _('Change audittrail depends -- Setting rule as DRAFT')) self.write(cr, uid, [thisrule.id], {"state": "draft"}) val = { - "name": 'View Log', - "res_model": 'audittrail.log', - "src_model": thisrule.object_id.model, + "name": 'View Log', + "res_model": 'audittrail.log', + "src_model": thisrule.object_id.model, "domain": "[('object_id','=', " + str(thisrule.object_id.id) + "), ('res_id', '=', active_id)]" } @@ -98,7 +102,7 @@ class audittrail_rule(osv.osv): @param cr: the current row, from the database cursor, @param uid: the current user’s ID for security checks, @param ids: List of Auddittrail Rule’s IDs. - @return: True + @return: True """ obj_action = self.pool.get('ir.actions.act_window') val_obj = self.pool.get('ir.values') @@ -128,16 +132,19 @@ class audittrail_log(osv.osv): _description = "Audittrail Log" _columns = { - "name": fields.char("Name", size=32), - "object_id": fields.many2one('ir.model', 'Object'), - "user_id": fields.many2one('res.users', 'User'), - "method": fields.selection((('read', 'Read'), - ('write', 'Write'), - ('unlink', 'Delete'), - ('create', 'Create')), "Method"), - "timestamp": fields.datetime("Date"), - "res_id": fields.integer('Resource Id'), - "line_ids": fields.one2many('audittrail.log.line', 'log_id', 'Log lines'), + "name": fields.char("Name", size=32), + "object_id": fields.many2one('ir.model', 'Object'), + "user_id": fields.many2one('res.users', 'User'), + "method": fields.selection((('read', 'Read'), + ('write', 'Write'), + ('unlink', 'Delete'), + ('create', 'Create'), + ('action','Action'), + ('workflow','Workflow')), "Method"), + "timestamp": fields.datetime("Date"), + "res_id": fields.integer('Resource Id'), + "method_name": fields.char("Method Name", size=32), + "line_ids": fields.one2many('audittrail.log.line', 'log_id', 'Log lines'), } _defaults = { @@ -155,14 +162,14 @@ class audittrail_log_line(osv.osv): _name = 'audittrail.log.line' _description = "Log Line" _columns = { - 'field_id': fields.many2one('ir.model.fields', 'Fields', required=True), - 'log_id': fields.many2one('audittrail.log', 'Log'), - 'log': fields.integer("Log ID"), - 'old_value': fields.text("Old Value"), - 'new_value': fields.text("New Value"), - 'old_value_text': fields.text('Old value Text'), - 'new_value_text': fields.text('New value Text'), - 'field_description': fields.char('Field Description', size=64), + 'field_id': fields.many2one('ir.model.fields', 'Fields', required=True), + 'log_id': fields.many2one('audittrail.log', 'Log'), + 'log': fields.integer("Log ID"), + 'old_value': fields.text("Old Value"), + 'new_value': fields.text("New Value"), + 'old_value_text': fields.text('Old value Text'), + 'new_value_text': fields.text('New value Text'), + 'field_description': fields.char('Field Description', size=64), } audittrail_log_line() @@ -170,7 +177,7 @@ audittrail_log_line() class audittrail_objects_proxy(osv_pool): """ Uses Object proxy for auditing changes on object of subscribed Rules""" - + def get_value_text(self, cr, uid, field_name, values, object, context=None): """ Gets textual values for the fields @@ -178,9 +185,9 @@ class audittrail_objects_proxy(osv_pool): @param cr: the current row, from the database cursor, @param uid: the current user’s ID for security checks, - @param field_name: List of fields for text values - @param values: Values for field to be converted into textual values - @return: values: List of textual values for given fields + @param field_name: List of fields for text values + @param values: Values for field to be converted into textual values + @return: values: List of textual values for given fields """ if not context: context = {} @@ -226,7 +233,6 @@ class audittrail_objects_proxy(osv_pool): @param object: Object who's values are being changed @param lines: List of values for line is to be created """ - pool = pooler.get_pool(cr.dbname) obj = pool.get(object.model) #start Loop @@ -242,7 +248,7 @@ class audittrail_objects_proxy(osv_pool): new_value = 'new_value' in line and line['new_value'] or '' old_value_text = 'old_value_text' in line and line['old_value_text'] or '' new_value_text = 'new_value_text' in line and line['new_value_text'] or '' - + if old_value_text == new_value_text: continue if fields[0]['ttype'] == 'many2one': @@ -251,12 +257,12 @@ class audittrail_objects_proxy(osv_pool): if type(new_value) == tuple: new_value = new_value[0] vals = { - "log_id": id, - "field_id": f_id[0], - "old_value": old_value, - "new_value": new_value, - "old_value_text": old_value_text, - "new_value_text": new_value_text, + "log_id": id, + "field_id": f_id[0], + "old_value": old_value, + "new_value": new_value, + "old_value_text": old_value_text, + "new_value_text": new_value_text, "field_description": fields[0]['field_description'] } line_id = pool.get('audittrail.log.line').create(cr, uid, vals) @@ -264,22 +270,25 @@ class audittrail_objects_proxy(osv_pool): #End Loop return True + def log_fct(self, db, uid, object, method, fct_src, *args): """ Logging function: This function is performs logging oprations according to method @param db: the current database @param uid: the current user’s ID for security checks, @param object: Object who's values are being changed - @param method: method to log: create, read, write, unlink + @param method: method to log: create, read, write, unlink @param fct_src: execute method of Object proxy - - @return: Returns result as per method of Object proxy + + @return: Returns result as per method of Object proxy """ logged_uids = [] + res2 = args pool = pooler.get_pool(db) cr = pooler.get_db(db).cursor() obj_ids = pool.get('ir.model').search(cr, uid, [('model', '=', object)]) model_object = pool.get('ir.model').browse(cr, uid, obj_ids)[0] + if method in ('create'): res_id = fct_src(db, uid, object, method, *args) cr.commit() @@ -290,9 +299,9 @@ class audittrail_objects_proxy(osv_pool): resource_name = pool.get(model_object.model).name_get(cr, uid, [res_id]) resource_name = resource_name and resource_name[0][1] or '' vals = { - "method": method, - "object_id": model_object.id, - "user_id": uid, "res_id": res_id, + "method": method, + "object_id": model_object.id, + "user_id": uid, "res_id": res_id, "name": resource_name } id = pool.get('audittrail.log').create(cr, uid, vals) @@ -300,8 +309,8 @@ class audittrail_objects_proxy(osv_pool): for field in new_value: if new_value[field]: line = { - 'name': field, - 'new_value': new_value[field], + 'name': field, + 'new_value': new_value[field], 'new_value_text': self.get_value_text(cr, uid, field, new_value[field], model_object) } lines.append(line) @@ -329,10 +338,10 @@ class audittrail_objects_proxy(osv_pool): for field in args[1].keys(): if args[1].keys(): line = { - 'name': field, - 'new_value': field in new_values and new_values[field] or '', - 'old_value': field in old_values and old_values[field] or '', - 'new_value_text': self.get_value_text(cr, uid, field, new_values[field], model_object), + 'name': field, + 'new_value': field in new_values and new_values[field] or '', + 'old_value': field in old_values and old_values[field] or '', + 'new_value_text': self.get_value_text(cr, uid, field, new_values[field], model_object), 'old_value_text': old_values_text[field] } lines.append(line) @@ -360,8 +369,8 @@ class audittrail_objects_proxy(osv_pool): for field in old_values[res_id]: if old_values[res_id][field]: line = { - 'name': field, - 'old_value': old_values[res_id][field], + 'name': field, + 'old_value': old_values[res_id][field], 'old_value_text': self.get_value_text(cr, uid, field, old_values[res_id][field], model_object) } lines.append(line) @@ -385,8 +394,8 @@ class audittrail_objects_proxy(osv_pool): for field in old_values[res_id]: if old_values[res_id][field]: line = { - 'name': field, - 'old_value': old_values[res_id][field], + 'name': field, + 'old_value': old_values[res_id][field], 'old_value_text': self.get_value_text(cr, uid, field, old_values[res_id][field], model_object) } lines.append(line) @@ -397,16 +406,61 @@ class audittrail_objects_proxy(osv_pool): return res cr.close() + def log_action(self, db, uid, object, method, fct_src, *args): + """ + Logging function: This function is performs logging oprations according to method + @param db: the current database + @param uid: the current user’s ID for security checks, + @param object: Object who's values are being changed + @param method: method to log: create, read, write, unlink + @param fct_src: execute method of Object proxy + + @return: Returns result as per method of Object proxy + """ + + logged_uids = [] + pool = pooler.get_pool(db) + cr = pooler.get_db(db).cursor() + obj_ids = pool.get('ir.model').search(cr, uid, [('model', '=', object)]) + model_object = pool.get('ir.model').browse(cr, uid, obj_ids)[0] + + res_ids = args[0] + old_values = {} + for res_id in res_ids: + old_values[res_id] = pool.get(model_object.model).read(cr, uid, res_id, []) + + for res_id in res_ids: + if not logged_uids or uid in logged_uids: + resource_name = pool.get(model_object.model).name_get(cr, uid, [res_id]) + resource_name = resource_name and resource_name[0][1] or '' + id = pool.get('audittrail.log').create(cr, uid, {"method": 'action', "object_id": model_object.id, "user_id": uid, "res_id": res_id, "name": resource_name, "method_name": method}) + lines = [] + for field in old_values[res_id]: + if old_values[res_id][field]: + line = { + 'name': field, + 'old_value': old_values[res_id][field], + 'old_value_text': self.get_value_text(cr, uid, field, old_values[res_id][field], model_object) + } + lines.append(line) + cr.commit() + self.create_log_line(cr, uid, id, model_object, lines) + res = fct_src(db, uid, object, method, *args) + cr.close() + return res + cr.close() + def execute(self, db, uid, object, method, *args, **kw): """ Overrides Object Proxy execute method @param db: the current database @param uid: the current user’s ID for security checks, @param object: Object who's values are being changed - @param method: method to log: create, read, write, unlink - - @return: Returns result as per method of Object proxy + @param method: method to log: create, read, write, unlink + + @return: Returns result as per method of Object proxy """ + pool = pooler.get_pool(db) cr = pooler.get_db(db).cursor() cr.autocommit(True) @@ -433,13 +487,105 @@ class audittrail_objects_proxy(osv_pool): logged_uids.append(user.id) if not logged_uids or uid in logged_uids: if field in ('read', 'write', 'create', 'unlink'): + if getattr(thisrule, 'log_' + field): return self.log_fct(db, uid, object, method, fct_src, *args) + + elif field not in ('default_get','read','fields_view_get','fields_get','search','search_count','name_search','name_get','get','request_get', 'get_sc', 'unlink') and (field != 'write' and field != 'create'): + if thisrule.log_action: + return self.log_action(db, uid, object, method, fct_src, *args) return fct_src(db, uid, object, method, *args) res = my_fct(db, uid, object, method, *args) cr.close() return res + + def workflow_log(self, db, uid, object, method,*args, **argv): + """ + Logging function: This function is performs logging oprations according to method + @param db: the current database + @param uid: the current user’s ID for security checks, + @param object: Object who's values are being changed + @param method: method to log: create, read, write, unlink + @param fct_src: execute method of Object proxy + + @return: Returns result as per method of Object proxy + """ + + logged_uids = [] + pool = pooler.get_pool(db) + cr = pooler.get_db(db).cursor() + obj_ids = pool.get('ir.model').search(cr, uid, [('model', '=', object)]) + model_object = pool.get('ir.model').browse(cr, uid, obj_ids)[0] + + workflow_obj = pool.get('workflow') + wkf_ids = workflow_obj.search(cr, uid, [('osv', '=', object)]) + wkf_name= workflow_obj.browse(cr, uid, wkf_ids)[0].name + + res_id = args[0] + old_values_text = {} + old_values = pool.get(model_object.model).read(cr, uid, res_id) + for field in old_values.keys(): + old_values_text[field] = self.get_value_text(cr, uid, field, old_values[field], model_object) + + res = super(audittrail_objects_proxy, self).exec_workflow(db, uid, object, method, *args, **argv) + cr.commit() + new_values = pool.get(model_object.model).read(cr, uid, res_id) + + resource_name = pool.get(model_object.model).name_get(cr, uid, [args[0]]) + resource_name = resource_name and resource_name[0][1] or '' + l_id = pool.get('audittrail.log').create(cr, uid, {"method": 'workflow', "object_id": model_object.id, "user_id": uid, "res_id": args[0], "name": resource_name +"/"+ wkf_name }) + lines = [] + diff = {} + log_line_pool = pool.get('audittrail.log.line') + + for field in old_values.keys(): + if old_values[field] == new_values[field]: + continue + else: + diff.update({field: (old_values[field], new_values[field])}) + f_id = pool.get('ir.model.fields').search(cr, uid, [('name', '=', field), ('model_id', '=', model_object.id)]) + log_line_pool.create(cr, uid, {'field_id': f_id[0], 'log_id': l_id, \ + 'old_value': str(old_values[field]),\ + 'new_value': str(new_values[field]),\ + 'old_value_text':str(old_values_text[field]), + 'new_value_text':self.get_value_text(cr, uid, field, new_values[field], model_object), + }) + cr.commit() + cr.close() + return res + + + def exec_workflow(self, db, uid, object, method, *args, **argv): + pool = pooler.get_pool(db) + cr = pooler.get_db(db).cursor() + cr.autocommit(True) + logged_uids = [] + fct_src = super(audittrail_objects_proxy, self).execute + field = method + rule = False + obj_ids = pool.get('ir.model').search(cr, uid, [('model', '=', object)]) + for obj_name in pool.obj_list(): + if obj_name == 'audittrail.rule': + rule = True + if not rule: + return super(audittrail_objects_proxy, self).exec_workflow(db, uid, object, method, *args, **argv) + if not obj_ids: + return super(audittrail_objects_proxy, self).exec_workflow(db, uid, object, method, *args, **argv) + rule_ids = pool.get('audittrail.rule').search(cr, uid, [('object_id', '=', obj_ids[0]), ('state', '=', 'subscribed')]) + if not rule_ids: + res = super(audittrail_objects_proxy, self).exec_workflow(db, uid, object, method, *args, **argv) + + for thisrule in pool.get('audittrail.rule').browse(cr, uid, rule_ids): + for user in thisrule.user_id: + logged_uids.append(user.id) + if not logged_uids or uid in logged_uids: + if thisrule.log_workflow: + return self.workflow_log(db, uid, object, method, *args,**argv) + return super(audittrail_objects_proxy, self).exec_workflow(db, uid, object, method, *args, **argv) + + cr.close() + audittrail_objects_proxy() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/audittrail/audittrail_view.xml b/addons/audittrail/audittrail_view.xml index c8999e78774..d269624f3ca 100644 --- a/addons/audittrail/audittrail_view.xml +++ b/addons/audittrail/audittrail_view.xml @@ -12,10 +12,12 @@
- - - - + + + + + + @@ -38,49 +40,48 @@ - + + + -