Skip to content

Commit

Permalink
[ADD] allow editing options for rules
Browse files Browse the repository at this point in the history
  • Loading branch information
hbrunn committed Mar 30, 2017
1 parent 321b239 commit 61dd2f4
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 4 deletions.
Expand Up @@ -18,6 +18,7 @@
"demo/account_bank_statement_import_auto_reconcile_rule.xml",
],
"data": [
"views/account_bank_statement_import_auto_reconcile_exact_amount.xml",
"views/account_bank_statement_import.xml",
"views/account_journal.xml",
"views/account_bank_statement_import_auto_reconcile_rule.xml",
Expand Down
Expand Up @@ -4,6 +4,7 @@
from openerp import api, fields, models


# pylint: disable=R7980
class AccountBankStatementImportAutoReconcileExactAmount(models.AbstractModel):
_inherit = 'account.bank.statement.import.auto.reconcile'
_name = 'account.bank.statement.import.auto.reconcile.exact.amount'
Expand Down
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
# © 2017 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import _, api, exceptions, fields, models
from lxml import etree
from openerp import _, api, exceptions, fields, models, tools
from .account_bank_statement_import_auto_reconcile import\
AccountBankStatementImportAutoReconcile as auto_reconcile_base

Expand All @@ -15,14 +16,18 @@ class AccountBankStatementImportAutoReconcileRule(models.Model):
options = fields.Serialized('Options')

@api.model
def _sel_rule_type(self):
model_names = [
@tools.ormcache()
def _get_model_names(self):
return [
model for model in self.env.registry
if self.env[model]._name != auto_reconcile_base._name and
issubclass(self.env[model].__class__, auto_reconcile_base)
]

@api.model
def _sel_rule_type(self):
return self.env['ir.model'].search([
('model', 'in', model_names),
('model', 'in', self._get_model_names()),
]).mapped(lambda x: (x.model, x.name))

@api.constrains('rule_type')
Expand All @@ -35,9 +40,100 @@ def _check_rule_type(self):
_('Reconciliation rules must be unique per journal')
)

@api.model
def create(self, values):
self._options_from_values(values)
return super(AccountBankStatementImportAutoReconcileRule, self).create(
values
)

@api.multi
def write(self, values):
self._options_from_values(values)
return super(AccountBankStatementImportAutoReconcileRule, self).write(
values
)

@api.multi
def read(self, fields=None, load='_classic_read'):
rule_type_fields = []
self_fields = []
for field in fields or []:
if field in self._fields:
self_fields.append(field)
else:
rule_type_fields.append(field)
if self_fields and rule_type_fields and 'options' not in self_fields:
self_fields.append('options')
result = super(AccountBankStatementImportAutoReconcileRule, self)\
.read(fields=self_fields or None, load=load)
if not rule_type_fields:
return result
defaults = {}
for model_name in self._get_model_names():
defaults.update(self.env[model_name].default_get(rule_type_fields))
for res in result:
for field in rule_type_fields:
res[field] = res['options'].get(field, defaults.get(field))
return result

@api.model
def fields_view_get(self, view_id=None, view_type='form', toolbar=False,
submenu=False):
"""Carve a view such that we can inject every field the view of the
currently selected matching rule into our form"""
# TODO: at a certain point, we'll have to namespace field names in
# order to avoid clashes
result = super(AccountBankStatementImportAutoReconcileRule, self)\
.fields_view_get(view_id=view_id, view_type=view_type,
toolbar=toolbar, submenu=submenu)
standard_fields = set(self.env[auto_reconcile_base._name]._fields)
arch = etree.fromstring(result['arch'])
container = arch.xpath('//div[@name="rule_options"]')[0]

for model_name in self._get_model_names():
fields_view = self.env[model_name].fields_view_get()
if set(fields_view['fields']).issubset(standard_fields):
# this is an autogenerated form
continue
group = etree.SubElement(
container,
'div',
modifiers='{"invisible": [["rule_type", "!=", "%s"]]}' % (
model_name,
)
)
form = etree.fromstring(fields_view['arch'])
for element in form:
group.append(element)
for field in group.xpath('descendant::field[@modifiers]'):
# TODO: merging modifiers would be better
del field.attrib['modifiers']

for key, value in fields_view['fields'].iteritems():
result['fields'][key] = dict(value, readonly=False)

result['arch'] = etree.tostring(arch)
return result

@api.multi
def name_get(self):
return [
(this.id, self.env[this.rule_type]._description)
for this in self
]

@api.multi
def _options_from_values(self, values):
"""Write values we got from the user into options dict"""
if 'options' in values:
return
rule = values.get('rule_type', self and self[:1].rule_type or None)
if not rule or rule not in self.env.registry:
return
rule_model = self.env[rule]
options = self and self[:1].options or {}
for field_name in rule_model._fields:
if field_name in values:
options[field_name] = values.pop(field_name)
values['options'] = options
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="account_bank_statement_import_auto_reconcile_exact_amount_form" model="ir.ui.view">
<field name="model">account.bank.statement.import.auto.reconcile.exact.amount</field>
<field name="arch" type="xml">
<form>
<group>
<field name="substring_match" />
<field name="case_sensitive" />
</group>
</form>
</field>
</record>
</data>
</openerp>
Expand Up @@ -8,6 +8,7 @@
<group>
<field name="rule_type" />
</group>
<div name="rule_options" attrs="{'invisible': [('rule_type', '=', False)]}" />
</form>
</field>
</record>
Expand Down

0 comments on commit 61dd2f4

Please sign in to comment.