Browse Source

Improve the revision user interface

pull/208/head
Guewen Baconnier 9 years ago
parent
commit
e6b4296a1e
  1. 3
      partner_revision/__openerp__.py
  2. 94
      partner_revision/models/res_partner_revision.py
  3. 1
      partner_revision/tests/test_revision_flow.py
  4. 9
      partner_revision/views/menu.xml
  5. 76
      partner_revision/views/res_partner_revision_views.xml
  6. 7
      partner_revision/views/revision_behavior_views.xml

3
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': [],

94
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

1
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) """

9
partner_revision/views/menu.xml

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="0">
<menuitem id="menu_revision"
name="Partner Revisions"
parent="base.menu_base_config"
sequence="20"/>
</data>
</openerp>

76
partner_revision/views/res_partner_revision_views.xml

@ -22,19 +22,81 @@
<field name="partner_id"/>
<field name="date"/>
</group>
<group string="Changes">
<field name="change_ids" nolabel="1">
<tree string="Partner Revision Change">
<field name="field_id" context="{'no_open': true}"/>
<field name="field_type" invisible="1"/>
<field name="current_value_display"/>
<field name="new_value_display"/>
<field name="state"/>
<button name="apply"
string="Apply" type="object"
icon="gtk-apply"
states="draft"/>
<button name="cancel"
string="Reject" type="object"
icon="gtk-close"
states="draft"/>
</tree>
</field>
</group>
<group>
<field name="note"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_res_partner_revision_change_form" model="ir.ui.view">
<field name="name">res.partner.revision.change.form</field>
<field name="model">res.partner.revision.change</field>
<field name="arch" type="xml">
<form string="Partner Revision Change">
<header>
<button name="apply"
string="Apply" type="object"
class="oe_highlight"
states="draft"/>
<button name="cancel"
string="Reject" type="object"
class="oe_highlight"
states="draft"/>
</header>
<sheet>
<group>
<field name="change_ids" nolabel="1">
<tree>
<field name="field_id" context="{'no_open': true}"/>
<!-- TODO show according to field ttype -->
<field name="field_id" options="{'no_open': true}"/>
<field name="field_type" invisible="1"/>
<!-- attrs are added in fields_view_get -->
<field name="current_value_char"/>
<field name="new_value_char"/>
<field name="current_value_date"/>
<field name="new_value_date"/>
<field name="current_value_datetime"/>
<field name="new_value_datetime"/>
<field name="current_value_float"/>
<field name="new_value_float"/>
<field name="current_value_integer"/>
<field name="new_value_integer"/>
<field name="current_value_text"/>
<field name="new_value_text"/>
<field name="current_value_boolean"/>
<field name="new_value_boolean"/>
<field name="current_value_reference"/>
<field name="new_value_reference"/>
<field name="state"/>
</tree>
</field>
</group>
</sheet>
</form>
@ -61,7 +123,7 @@
</record>
<menuitem id="menu_res_partner_revision"
parent="base.menu_base_config"
parent="menu_revision"
sequence="20"
action="action_res_partner_revision_view"/>
</data>

7
partner_revision/views/revision_behavior_views.xml

@ -21,7 +21,10 @@
<sheet string="Revision Behavior">
<group>
<field name="model_id" invisible="1"/>
<field name="field_id" domain="[('model_id', '=', model_id)]"/>
<field name="field_id"
domain="[('model_id', '=', model_id),
('ttype', 'in', ('char', 'selection', 'date', 'datetime', 'float', 'integer', 'text', 'boolean', 'many2one')),
('readonly', '=', False)]"/>
<field name="default_behavior"/>
</group>
</sheet>
@ -51,7 +54,7 @@
</record>
<menuitem id="menu_revision_behavior"
parent="base.menu_base_config"
parent="menu_revision"
sequence="20"
action="action_revision_behavior_view"/>
</data>

Loading…
Cancel
Save