From 4f415f67e6bc0961464d8da174fd2385d5b23498 Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Tue, 15 Sep 2015 17:13:30 +0200 Subject: [PATCH] Create a partner revision on writes --- partner_revision/__init__.py | 2 + partner_revision/__openerp__.py | 4 +- partner_revision/models/__init__.py | 5 ++ partner_revision/models/res_partner.py | 79 +++++++++++++++++++ .../models/res_partner_revision.py | 63 +++++++++++++++ partner_revision/models/revision_behavior.py | 60 ++++++++++++++ .../views/res_partner_revision_views.xml | 67 ++++++++++++++++ .../views/revision_behavior_views.xml | 58 ++++++++++++++ 8 files changed, 337 insertions(+), 1 deletion(-) create mode 100644 partner_revision/models/__init__.py create mode 100644 partner_revision/models/res_partner.py create mode 100644 partner_revision/models/res_partner_revision.py create mode 100644 partner_revision/models/revision_behavior.py create mode 100644 partner_revision/views/res_partner_revision_views.xml create mode 100644 partner_revision/views/revision_behavior_views.xml diff --git a/partner_revision/__init__.py b/partner_revision/__init__.py index 40a96afc6..cde864bae 100644 --- a/partner_revision/__init__.py +++ b/partner_revision/__init__.py @@ -1 +1,3 @@ # -*- coding: utf-8 -*- + +from . import models diff --git a/partner_revision/__openerp__.py b/partner_revision/__openerp__.py index dab47e0d4..0494543ce 100644 --- a/partner_revision/__openerp__.py +++ b/partner_revision/__openerp__.py @@ -27,7 +27,9 @@ 'depends': ['base', ], 'website': 'http://www.camptocamp.com', - 'data': [], + 'data': ['views/res_partner_revision_views.xml', + 'views/revision_behavior_views.xml', + ], 'test': [], 'installable': True, 'auto_install': False, diff --git a/partner_revision/models/__init__.py b/partner_revision/models/__init__.py new file mode 100644 index 000000000..9a890dbb1 --- /dev/null +++ b/partner_revision/models/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +from . import res_partner +from . import res_partner_revision +from . import revision_behavior diff --git a/partner_revision/models/res_partner.py b/partner_revision/models/res_partner.py new file mode 100644 index 000000000..c3ca31e3d --- /dev/null +++ b/partner_revision/models/res_partner.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +# +# +# Authors: Guewen Baconnier +# Copyright 2015 Camptocamp SA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# + +from openerp import models, fields, api + + +class ResPartner(models.Model): + _inherit = 'res.partner' + + @api.multi + def write(self, values): + for record in self: + values = record._add_revision(values) + return super(ResPartner, self).write(values) + + @api.multi + def _add_revision(self, values): + """ Add a revision on a partner + + :param values: the values being written on the partner + :type values: dict + + :returns: dict of values that should be wrote on the partner + (fields with a 'Validate' or 'Never' rule are excluded) + + """ + self.ensure_one() + write_values = values.copy() + changes = [] + rules = self.env['revision.behavior'].get_rules(self._model._name) + for field in values: + rule = rules.get(field) + if not rule: + continue + if field in values: + # TODO: if a change is done manually, values are always + # written but we create 'done' changes + if self[field] == values[field]: + # TODO handle relations, types + continue + change = { + 'current_value': self[field], + 'new_value': values[field], + 'field_id': rule.field_id.id, + } + if rule.default_behavior == 'auto': + change['state'] = 'done' + elif rule.default_behavior == 'validate': + change['state'] = 'draft' + write_values.pop(field) # change to apply manually + elif rule.default_behavior == 'never': + change['state'] = 'cancel' + write_values.pop(field) # change never applied + changes.append(change) + if changes: + self.env['res.partner.revision'].create({ + 'partner_id': self.id, + 'change_ids': [(0, 0, vals) for vals in changes], + 'date': fields.Datetime.now(), + }) + return write_values diff --git a/partner_revision/models/res_partner_revision.py b/partner_revision/models/res_partner_revision.py new file mode 100644 index 000000000..b8e0ebe15 --- /dev/null +++ b/partner_revision/models/res_partner_revision.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# +# +# Authors: Guewen Baconnier +# Copyright 2015 Camptocamp SA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# + +from openerp import models, fields + + +class ResPartnerRevision(models.Model): + _name = 'res.partner.revision' + _description = 'Partner Revision' + _order = 'date desc' + _rec_name = 'date' + + partner_id = fields.Many2one(comodel_name='res.partner', + string='Partner', + required=True) + change_ids = fields.One2many(comodel_name='res.partner.revision.change', + inverse_name='revision_id', + string='Changes') + date = fields.Datetime() + note = fields.Text() + + +class ResPartnerRevisionChange(models.Model): + _name = 'res.partner.revision.change' + _description = 'Partner Revision Change' + _rec_name = 'new_value' + + revision_id = fields.Many2one(comodel_name='res.partner.revision', + required=True, + string='Revision', + ondelete='cascade') + field_id = fields.Many2one(comodel_name='ir.model.fields', + string='Field', + required=True) + # TODO: different types of fields + current_value = fields.Char('Current') + new_value = fields.Char('New') + state = fields.Selection( + selection=[('draft', 'Waiting'), + ('done', 'Accepted'), + ('cancel', 'Refused'), + ], + required=True, + default='draft', + ) diff --git a/partner_revision/models/revision_behavior.py b/partner_revision/models/revision_behavior.py new file mode 100644 index 000000000..a125e6ed8 --- /dev/null +++ b/partner_revision/models/revision_behavior.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# +# +# Authors: Guewen Baconnier +# Copyright 2015 Camptocamp SA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# + +from openerp import models, fields, api + + +class RevisionBehavior(models.Model): + _name = 'revision.behavior' + _description = 'Revision Behavior' + _rec_name = 'field_id' + + model_id = fields.Many2one(comodel_name='ir.model', + string='Model', + ondelete='cascade', + default=lambda self: self._default_model_id()) + field_id = fields.Many2one(comodel_name='ir.model.fields', + string='Field', + ondelete='cascade') + default_behavior = fields.Selection( + selection='_selection_default_behavior', + string='Default Behavior', + help="Auto: always apply a change.\n" + "Validate: manually applied by an administrator.\n" + "Never: change never applied.", + ) + + @api.model + def _default_model_id(self): + return self.env.ref('base.model_res_partner').id + + @api.model + def _selection_default_behavior(self): + return [('auto', 'Auto'), + ('validate', 'Validate'), + ('never', 'Never'), + ] + + # TODO: cache + @api.model + def get_rules(self, model_name): + rules = self.search([('model_id', '=', model_name)]) + return {rule.field_id.name: rule for rule in rules} diff --git a/partner_revision/views/res_partner_revision_views.xml b/partner_revision/views/res_partner_revision_views.xml new file mode 100644 index 000000000..3b4c233d1 --- /dev/null +++ b/partner_revision/views/res_partner_revision_views.xml @@ -0,0 +1,67 @@ + + + + + res.partner.revision.tree + res.partner.revision + + + + + + + + + + res.partner.revision.form + res.partner.revision + +
+ + + + + + + + + + + + + + + + + + + +
+
+
+ + + res.partner.revision.search + res.partner.revision + + + + + + + + + Partner Revision + ir.actions.act_window + res.partner.revision + form + tree,form + + + + +
+
diff --git a/partner_revision/views/revision_behavior_views.xml b/partner_revision/views/revision_behavior_views.xml new file mode 100644 index 000000000..78553125d --- /dev/null +++ b/partner_revision/views/revision_behavior_views.xml @@ -0,0 +1,58 @@ + + + + + revision.behavior.tree + revision.behavior + + + + + + + + + + + revision.behavior.form + revision.behavior + +
+ + + + + + + +
+
+
+ + + revision.behavior.search + revision.behavior + + + + + + + + + + + Revision Behavior + ir.actions.act_window + revision.behavior + form + tree,form + + + + +
+