diff --git a/partner_revision/__openerp__.py b/partner_revision/__openerp__.py
index 0494543ce..9588a7081 100644
--- a/partner_revision/__openerp__.py
+++ b/partner_revision/__openerp__.py
@@ -27,7 +27,8 @@
'depends': ['base',
],
'website': 'http://www.camptocamp.com',
- 'data': ['views/res_partner_revision_views.xml',
+ 'data': ['views/menu.xml',
+ 'views/res_partner_revision_views.xml',
'views/revision_behavior_views.xml',
],
'test': [],
diff --git a/partner_revision/models/res_partner_revision.py b/partner_revision/models/res_partner_revision.py
index 62e4a8286..12612284b 100644
--- a/partner_revision/models/res_partner_revision.py
+++ b/partner_revision/models/res_partner_revision.py
@@ -19,7 +19,10 @@
#
#
-from openerp import models, fields, api
+from lxml import etree
+
+from openerp import models, fields, api, exceptions, _
+from openerp.osv.orm import setup_modifiers
class ResPartnerRevision(models.Model):
@@ -35,12 +38,18 @@ class ResPartnerRevision(models.Model):
inverse_name='revision_id',
string='Changes')
date = fields.Datetime(default=fields.Datetime.now)
+ # TODO: add a revision state, done when all lines are done or
+ # canceled
note = fields.Text()
@api.multi
def apply(self):
self.mapped('change_ids').apply()
+ @api.multi
+ def cancel(self):
+ self.mapped('change_ids').cancel()
+
@api.multi
def add_revision(self, record, values):
""" Add a revision on a partner
@@ -103,6 +112,18 @@ class ResPartnerRevisionChange(models.Model):
field_id = fields.Many2one(comodel_name='ir.model.fields',
string='Field',
required=True)
+ field_type = fields.Selection(related='field_id.ttype',
+ string='Field Type',
+ readonly=True)
+
+ current_value_display = fields.Char(
+ string='Current',
+ compute='_compute_value_display',
+ )
+ new_value_display = fields.Char(
+ string='New',
+ compute='_compute_value_display',
+ )
current_value_char = fields.Char(string='Current')
current_value_date = fields.Date(string='Current')
@@ -138,18 +159,36 @@ class ResPartnerRevisionChange(models.Model):
models = self.env['ir.model'].search([])
return [(model.model, model.name) for model in models]
- _type_to_field = {
- 'char': 'char',
- 'date': 'date',
- 'datetime': 'datetime',
- 'float': 'float',
- 'integer': 'integer',
- 'text': 'text',
- 'boolean': 'boolean',
- 'many2one': 'reference',
- 'selection': 'char',
+ _suffix_to_types = {
+ 'char': ('char', 'selection'),
+ 'date': ('date',),
+ 'datetime': ('datetime',),
+ 'float': ('float',),
+ 'integer': ('integer',),
+ 'text': ('text',),
+ 'boolean': ('boolean',),
+ 'reference': ('many2one',),
}
+ _type_to_suffix = {ftype: suffix
+ for suffix, ftypes in _suffix_to_types.iteritems()
+ for ftype in ftypes}
+
+ _current_value_fields = ['current_value_%s' % suffix
+ for suffix in _suffix_to_types]
+ _new_value_fields = ['new_value_%s' % suffix
+ for suffix in _suffix_to_types]
+ _value_fields = _current_value_fields + _new_value_fields
+
+ @api.one
+ @api.depends(lambda self: self._value_fields)
+ def _compute_value_display(self):
+ for prefix in ('current', 'new'):
+ value = getattr(self, 'get_%s_value' % prefix)()
+ if self.field_id.ttype == 'many2one' and value:
+ value = value.display_name
+ setattr(self, '%s_value_display' % prefix, value)
+
@api.model
def create(self, vals):
vals = vals.copy()
@@ -169,9 +208,8 @@ class ResPartnerRevisionChange(models.Model):
@api.model
def get_field_for_type(self, field, current_or_new):
assert current_or_new in ('new', 'current')
- field_type = self._type_to_field.get(field.ttype)
+ field_type = self._type_to_suffix.get(field.ttype)
if not field_type:
- # TODO: prevent to create unsupported types from the views
raise NotImplementedError(
'field type %s is not supported' % field_type
)
@@ -191,6 +229,7 @@ class ResPartnerRevisionChange(models.Model):
@api.multi
def apply(self):
+ # TODO: optimize with 1 write for all fields, group by revision
for change in self:
if change.state in ('cancel', 'done'):
continue
@@ -199,6 +238,15 @@ class ResPartnerRevisionChange(models.Model):
change.get_new_value()
)
partner.write({change.field_id.name: value_for_write})
+ change.write({'state': 'done'})
+
+ @api.multi
+ def cancel(self):
+ if any(change.state == 'done' for change in self):
+ raise exceptions.Warning(
+ _('This change has already be applied.')
+ )
+ self.write({'state': 'cancel'})
@api.model
def _has_field_changed(self, record, field, value):
@@ -261,3 +309,23 @@ class ResPartnerRevisionChange(models.Model):
change['state'] = 'cancel'
pop_value = True # change never applied
return change, pop_value
+
+ def fields_view_get(self, *args, **kwargs):
+ _super = super(ResPartnerRevisionChange, self)
+ result = _super.fields_view_get(*args, **kwargs)
+ if result['type'] != 'form':
+ return
+ doc = etree.XML(result['arch'])
+ for suffix, ftypes in self._suffix_to_types.iteritems():
+ for prefix in ('current', 'new'):
+ field_name = '%s_value_%s' % (prefix, suffix)
+ field_nodes = doc.xpath("//field[@name='%s']" % field_name)
+ for node in field_nodes:
+ node.set(
+ 'attrs',
+ "{'invisible': "
+ "[('field_type', 'not in', %s)]}" % (ftypes,)
+ )
+ setup_modifiers(node)
+ result['arch'] = etree.tostring(doc)
+ return result
diff --git a/partner_revision/tests/test_revision_flow.py b/partner_revision/tests/test_revision_flow.py
index 3fedcc678..b56c370fb 100644
--- a/partner_revision/tests/test_revision_flow.py
+++ b/partner_revision/tests/test_revision_flow.py
@@ -127,6 +127,7 @@ class TestRevisionFlow(RevisionMixin, common.TransactionCase):
revision = self._create_revision(self.partner, changes)
revision.change_ids.apply()
self.assertEqual(self.partner.name, 'Y')
+ self.assertEqual(revision.change_ids.state, 'done')
def test_apply_done_change(self):
""" Done changes do not apply (already applied) """
diff --git a/partner_revision/views/menu.xml b/partner_revision/views/menu.xml
new file mode 100644
index 000000000..a0137e792
--- /dev/null
+++ b/partner_revision/views/menu.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/partner_revision/views/res_partner_revision_views.xml b/partner_revision/views/res_partner_revision_views.xml
index 8dd8c880e..8d44348e0 100644
--- a/partner_revision/views/res_partner_revision_views.xml
+++ b/partner_revision/views/res_partner_revision_views.xml
@@ -22,20 +22,82 @@
-
-
-
-
+
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ res.partner.revision.change.form
+ res.partner.revision.change
+
+
@@ -61,7 +123,7 @@
diff --git a/partner_revision/views/revision_behavior_views.xml b/partner_revision/views/revision_behavior_views.xml
index 78553125d..e9ce1ec76 100644
--- a/partner_revision/views/revision_behavior_views.xml
+++ b/partner_revision/views/revision_behavior_views.xml
@@ -21,7 +21,10 @@
-
+
@@ -51,7 +54,7 @@