From 6fd10970f12a4e003d7cbe786f9bc468427c9705 Mon Sep 17 00:00:00 2001 From: Holger Brunn Date: Thu, 30 Mar 2017 10:47:26 +0200 Subject: [PATCH] [ADD] allow editing options for rules --- .../__openerp__.py | 1 + ...ment_import_auto_reconcile_exact_amount.py | 1 + ...nk_statement_import_auto_reconcile_rule.py | 104 +++++++++++++++++- ...ent_import_auto_reconcile_exact_amount.xml | 16 +++ ...k_statement_import_auto_reconcile_rule.xml | 1 + 5 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 account_bank_statement_import_auto_reconcile/views/account_bank_statement_import_auto_reconcile_exact_amount.xml diff --git a/account_bank_statement_import_auto_reconcile/__openerp__.py b/account_bank_statement_import_auto_reconcile/__openerp__.py index 5f8f27e..c993fb3 100644 --- a/account_bank_statement_import_auto_reconcile/__openerp__.py +++ b/account_bank_statement_import_auto_reconcile/__openerp__.py @@ -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", diff --git a/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_exact_amount.py b/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_exact_amount.py index 491315a..f514966 100644 --- a/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_exact_amount.py +++ b/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_exact_amount.py @@ -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' diff --git a/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_rule.py b/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_rule.py index b6ba788..790bcbf 100644 --- a/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_rule.py +++ b/account_bank_statement_import_auto_reconcile/models/account_bank_statement_import_auto_reconcile_rule.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- # © 2017 Therp BV # 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 @@ -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') @@ -35,9 +40,100 @@ class AccountBankStatementImportAutoReconcileRule(models.Model): _('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 diff --git a/account_bank_statement_import_auto_reconcile/views/account_bank_statement_import_auto_reconcile_exact_amount.xml b/account_bank_statement_import_auto_reconcile/views/account_bank_statement_import_auto_reconcile_exact_amount.xml new file mode 100644 index 0000000..a5260fe --- /dev/null +++ b/account_bank_statement_import_auto_reconcile/views/account_bank_statement_import_auto_reconcile_exact_amount.xml @@ -0,0 +1,16 @@ + + + + + account.bank.statement.import.auto.reconcile.exact.amount + +
+ + + + +
+
+
+
+
diff --git a/account_bank_statement_import_auto_reconcile/views/account_bank_statement_import_auto_reconcile_rule.xml b/account_bank_statement_import_auto_reconcile/views/account_bank_statement_import_auto_reconcile_rule.xml index 6706c80..d782f48 100644 --- a/account_bank_statement_import_auto_reconcile/views/account_bank_statement_import_auto_reconcile_rule.xml +++ b/account_bank_statement_import_auto_reconcile/views/account_bank_statement_import_auto_reconcile_rule.xml @@ -8,6 +8,7 @@ +