From 91f58d5632a73ced2bef667265f80b2b06837bb2 Mon Sep 17 00:00:00 2001 From: "david.beal@akretion.com" Date: Fri, 11 Jul 2014 15:08:33 +0200 Subject: [PATCH] [ADD] config helper module --- configuration_helper/__init__.py | 22 ++++++ configuration_helper/__openerp__.py | 82 ++++++++++++++++++++ configuration_helper/config.py | 114 ++++++++++++++++++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 configuration_helper/__init__.py create mode 100644 configuration_helper/__openerp__.py create mode 100644 configuration_helper/config.py diff --git a/configuration_helper/__init__.py b/configuration_helper/__init__.py new file mode 100644 index 000000000..bfca433c9 --- /dev/null +++ b/configuration_helper/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: David BEAL +# Copyright 2014 Akretion +# +# 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 . import config # noqa diff --git a/configuration_helper/__openerp__.py b/configuration_helper/__openerp__.py new file mode 100644 index 000000000..7ca0618fb --- /dev/null +++ b/configuration_helper/__openerp__.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: David BEAL +# Copyright 2014 Akretion +# +# 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 . +# +############################################################################## + +{ + 'name': 'Configuration Helper', + 'version': '0.8', + 'author': 'Akretion', + 'maintainer': 'Akretion', + 'category': 'server', + 'complexity': 'normal', + 'depends': ['base'], + 'description': """ +Configuration Helper +==================== + +*This module is intended for developer only. It does nothing used alone.* + +This module : + + * create automatically related fields in 'whatiwant.config.settings' + using those defined in 'res.company' : it avoid duplicated field definitions. + * company_id field with default value is created + * onchange_company_id is defined to update all related fields + * supported fields: char, text, integer, float, datetime, date, boolean, m2o + + +How to use +---------- + +.. code-block:: python + + from . company import ResCompany + + class WhatiwantClassSettings(orm.TransientModel): + _inherit = ['res.config.settings', 'abstract.config.settings'] + _name = 'whatiwant.config.settings' + # fields must be defined in ResCompany class + # related fields are automatically generated from previous definitions + _companyObject = ResCompany + + +Roadmap +------- + * support (or check support) for these field types : o2m, m2m, reference, property, selection + * automatically generate a default view for 'whatiwant.config.settings' (in --debug ?) + + +Contributors +------------ + +* David BEAL +* Sébastien BEAU +* Yannick Vaucher, Camptocamp, (code refactoring from his module 'delivery_carrier_label_postlogistics') + + """, + 'website': 'http://www.akretion.com/', + 'data': [ + ], + 'tests': [], + 'installable': True, + 'auto_install': False, + 'license': 'AGPL-3', + 'application': True, +} diff --git a/configuration_helper/config.py b/configuration_helper/config.py new file mode 100644 index 000000000..187d683ab --- /dev/null +++ b/configuration_helper/config.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: David BEAL, Copyright 2014 Akretion +# +# 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 . +# +############################################################################## +import re + +from openerp.osv import orm, fields + + +class AbstractConfigSettings(orm.AbstractModel): + _name = 'abstract.config.settings' + _description = 'Abstract configuration settings' + # prefix field name to differentiate fields in company with those in config + _prefix = 'setting_' + # this is the class name to import in your module + # (it should be ResCompany or res_company, depends of your code) + _companyObject = None + + def _filter_field(self, field_key): + """Inherit in your module to define for which company field + you don't want have a matching related field""" + return True + + def __init__(self, pool, cr): + super(AbstractConfigSettings, self).__init__(pool, cr) + if self._companyObject: + for field_key in self._companyObject._columns: + #allows to exclude some field + if self._filter_field(field_key): + args = ('company_id', field_key) + kwargs = { + 'string': self._companyObject._columns[field_key].string, + 'help': self._companyObject._columns[field_key].help, + 'type': self._companyObject._columns[field_key]._type, + } + if '_obj' in self._companyObject._columns[field_key].__dict__.keys(): + kwargs['relation'] = \ + self._companyObject._columns[field_key]._obj + if '_domain' in \ + self._companyObject._columns[field_key].__dict__.keys(): + kwargs['domain'] = \ + self._companyObject._columns[field_key]._domain + field_key = re.sub('^' + self._prefix, '', field_key) + self._columns[field_key] = \ + fields.related(*args, **kwargs) + + _columns = { + 'company_id': fields.many2one( + 'res.company', + 'Company', + required=True), + } + + def _default_company(self, cr, uid, context=None): + user = self.pool['res.users'].browse(cr, uid, uid, context=context) + return user.company_id.id + + _defaults = { + 'company_id': _default_company, + } + + def field_to_populate_as_related(self, cr, uid, field, company_cols, context=None): + """Only fields which comes from company with the right prefix + must be defined as related""" + if self._prefix + field in company_cols: + return True + return False + + def onchange_company_id(self, cr, uid, ids, company_id, context=None): + " update related fields " + values = {} + values['currency_id'] = False + if not company_id: + return {'value': values} + company_m = self.pool['res.company'] + company = company_m.browse( + cr, uid, company_id, context=context) + company_cols = company_m._columns.keys() + for field in self._columns: + if self.field_to_populate_as_related( + cr, uid, field, company_cols, context=context): + cpny_field = self._columns[field].arg[-1] + if self._columns[field]._type == 'many2one': + values[field] = company[cpny_field]['id'] or False + else: + values[field] = company[cpny_field] + return {'value': values} + + def create(self, cr, uid, values, context=None): + id = super(AbstractConfigSettings, self).create( + cr, uid, values, context=context) + # Hack: to avoid some nasty bug, related fields are not written + # upon record creation. Hence we write on those fields here. + vals = {} + for fname, field in self._columns.iteritems(): + if isinstance(field, fields.related) and fname in values: + vals[fname] = values[fname] + self.write(cr, uid, [id], vals, context) + return id