From ced183370f50f52f6347628cbe32c0896c1f28b9 Mon Sep 17 00:00:00 2001 From: Stefan Rijnhart Date: Mon, 10 Nov 2014 13:03:50 +0100 Subject: [PATCH] [ADD] Module to split partner street name and street number --- partner_street_number/__init__.py | 1 + partner_street_number/__openerp__.py | 49 +++++++ partner_street_number/i18n/nl.po | 47 +++++++ .../i18n/partner_street_number.pot | 41 ++++++ .../migrations/0.1/post-migrate.py | 46 +++++++ partner_street_number/model/__init__.py | 1 + partner_street_number/model/res_partner.py | 124 ++++++++++++++++++ partner_street_number/view/res_partner.xml | 46 +++++++ 8 files changed, 355 insertions(+) create mode 100644 partner_street_number/__init__.py create mode 100644 partner_street_number/__openerp__.py create mode 100644 partner_street_number/i18n/nl.po create mode 100644 partner_street_number/i18n/partner_street_number.pot create mode 100644 partner_street_number/migrations/0.1/post-migrate.py create mode 100644 partner_street_number/model/__init__.py create mode 100644 partner_street_number/model/res_partner.py create mode 100644 partner_street_number/view/res_partner.xml diff --git a/partner_street_number/__init__.py b/partner_street_number/__init__.py new file mode 100644 index 000000000..9186ee3ad --- /dev/null +++ b/partner_street_number/__init__.py @@ -0,0 +1 @@ +from . import model diff --git a/partner_street_number/__openerp__.py b/partner_street_number/__openerp__.py new file mode 100644 index 000000000..b0ed6112b --- /dev/null +++ b/partner_street_number/__openerp__.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2013-2014 Therp BV (). +# +# 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": "Split street name and number", + "version": "0.1", + "author": "Therp BV", + "category": 'Tools', + "description": """ +This module introduces separate fields for street name and street number. + +Changes to the OpenERP datamodel +================================ + +- Introduce two new fields for street name and number +- Keep 'Street' field as a function field to return street name + number +- Data written to the 'Street' field will be parsed into street name and number + if possible. This will be performed upon installation of the module for + existing partners. + +Compatibility +============= +This module is compatible with OpenERP 7.0. +""", + "depends": [ + 'base' + ], + "data": [ + 'view/res_partner.xml', + ], + 'installable': True, +} diff --git a/partner_street_number/i18n/nl.po b/partner_street_number/i18n/nl.po new file mode 100644 index 000000000..7380bc51f --- /dev/null +++ b/partner_street_number/i18n/nl.po @@ -0,0 +1,47 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * partner_street_number +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-12-07 13:50+0000\n" +"PO-Revision-Date: 2013-12-07 13:50+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: partner_street_number +#: field:res.partner,street_name:0 +msgid "Street name" +msgstr "Straatnaam" + +#. module: partner_street_number +#: field:res.partner,street_number:0 +msgid "Street number" +msgstr "Huisnummer" + +#. module: partner_street_number +#: view:res.partner:0 +msgid "Number..." +msgstr "Nummer..." + +#. module: partner_street_number +#: view:res.partner:0 +msgid "Street..." +msgstr "Straat..." + +#. module: partner_street_number +#: view:res.partner:0 +msgid "{'default_parent_id': active_id, 'default_street_name': street_name, 'default_street_number': street_number, 'default_street2': street2, 'default_city': city, 'default_state_id': state_id, 'default_zip': zip, 'default_country_id': country_id, 'default_supplier': supplier, 'default_customer': customer}" +msgstr "{'default_parent_id': active_id, 'default_street_name': street_name, 'default_street_number': street_number, 'default_street2': street2, 'default_city': city, 'default_state_id': state_id, 'default_zip': zip, 'default_country_id': country_id, 'default_supplier': supplier, 'default_customer': customer}" + +#. module: partner_street_number +#: model:ir.model,name:partner_street_number.model_res_partner +msgid "Partner" +msgstr "Relatie" + diff --git a/partner_street_number/i18n/partner_street_number.pot b/partner_street_number/i18n/partner_street_number.pot new file mode 100644 index 000000000..24dcda0df --- /dev/null +++ b/partner_street_number/i18n/partner_street_number.pot @@ -0,0 +1,41 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * partner_street_number +# +msgid "" +msgstr "" + +#. module: partner_street_number +#: field:res.partner,street_name:0 +msgid "Street name" +msgstr "" + +#. module: partner_street_number +#: field:res.partner,street_number:0 +msgid "Street number" +msgstr "" + +#. module: partner_street_number +#: view:res.partner:0 +msgid "Number..." +msgstr "" + +#. module: partner_street_number +#: view:res.partner:0 +msgid "Street..." +msgstr "" + +#. module: partner_street_number +#: view:res.partner:0 +msgid "" +"{'default_parent_id': active_id, 'default_street_name': street_name, " +"'default_street_number': street_number, 'default_street2': street2, " +"'default_city': city, 'default_state_id': state_id, 'default_zip': zip, " +"'default_country_id': country_id, 'default_supplier': supplier, " +"'default_customer': customer}" +msgstr "" + +#. module: partner_street_number +#: model:ir.model,name:partner_street_number.model_res_partner +msgid "Partner" +msgstr "" diff --git a/partner_street_number/migrations/0.1/post-migrate.py b/partner_street_number/migrations/0.1/post-migrate.py new file mode 100644 index 000000000..5c7cc0de3 --- /dev/null +++ b/partner_street_number/migrations/0.1/post-migrate.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2013-2014 Therp BV (). +# +# @autors: Stefan Rijnhart, Ronald Portier +# +# 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 logging +from openerp import pooler, SUPERUSER_ID + + +def migrate(cr, version): + """ + Post-install script. If version is not set, we are called at installation + time. Because 'street' is now a stored function field, we should be able + to retrieve its values from the cursor. We use those to fill the new + name/number fields using the street field's inverse function, which does + a basic street name/number split. + """ + if version: + return + logging.getLogger('openerp.addons.partner_street_number').info( + 'Migrating existing street names') + cr.execute( + 'SELECT id, street FROM res_partner ' + 'WHERE street IS NOT NULL and street_name IS NULL' + ) + partner_obj = pooler.get_pool(cr.dbname)['res.partner'] + for partner in cr.fetchall(): + partner_obj.write( + cr, SUPERUSER_ID, partner[0], {'street': partner[1]}) diff --git a/partner_street_number/model/__init__.py b/partner_street_number/model/__init__.py new file mode 100644 index 000000000..91fed54d4 --- /dev/null +++ b/partner_street_number/model/__init__.py @@ -0,0 +1 @@ +from . import res_partner diff --git a/partner_street_number/model/res_partner.py b/partner_street_number/model/res_partner.py new file mode 100644 index 000000000..1d50cf682 --- /dev/null +++ b/partner_street_number/model/res_partner.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2013-2014 Therp BV (). +# +# @autors: Stefan Rijnhart, Ronald Portier +# +# 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 ResPartner(orm.Model): + _inherit = 'res.partner' + + def get_street(self, cr, uid, partner, context=None): + """ + Allow to override the field function's value composition + + :param partner: res.partner browse record + :rtype: string + """ + return ' '.join(filter(None, [ + partner.street_name, + partner.street_number, + ])) + + def _get_street(self, cr, uid, select, field_name, args, context=None): + """ Delegates the function field 'street' to an inheritable method""" + res = {} + for partner in self.browse(cr, uid, select, context=context): + res[partner.id] = self.get_street( + cr, uid, partner, context=context) + return res + + def _write_street(self, cr, uid, ids, name, value, arg, context=None): + """ + Simplistically try to parse in case a value should get written + to the 'street' field (for instance at import time, which provides + us with a way of easily restoring the data when this module is + installed on a database that already contains addresses). + """ + street_name = value and value.strip() or False + street_number = False + if value: + match = re.search('(.+)\s+(\d.*)', value.strip()) + if match and len(match.group(2)) < 6: + street_name = match.group(1) + street_number = match.group(2) + return self.write(cr, uid, ids, { + 'street_name': street_name, + 'street_number': street_number, + }, context=context) + + def _display_address( + self, cr, uid, address, without_company=False, context=None): + """ + Inject a context key to prevent the 'street' name to be + deleted from the result of _address_fields when called from + the super. + """ + local_context = dict(context or {}, display_address=True) + return super(ResPartner, self)._display_address( + cr, uid, address, without_company=without_company, + context=local_context) + + def _address_fields(self, cr, uid, context=None): + """ + Pass on the fields for address synchronisation to contacts. + + This method is used on at least two occassions: + + [1] when address fields are synced to contacts, and + [2] when addresses are formatted + + We want to prevent the 'street' field to be passed in the + first case, as it has a fallback write method which should + not be triggered in this case, while leaving the field in + in the second case. Therefore, we remove the field + name from the list of address fields unless we find the context + key that this module injects when formatting an address. + + Could have checked for the occurrence of the synchronisation + method instead, leaving the field in by default but that could + lead to silent data corruption should the synchronisation API + ever change. + """ + res = super(ResPartner, self)._address_fields(cr, uid, context=context) + if 'street' in res and not ( + context and context.get('display_address')): + res.remove('street') + return res + ['street_name', 'street_number'] + + _columns = { + 'street_name': fields.char( + 'Street name', size=118), + 'street_number': fields.char( + 'Street number', size=10), + 'street': fields.function( + _get_street, fnct_inv=_write_street, + type='char', string="Street", + # Must be stored as per https://bugs.launchpad.net/bugs/1253200 + store={ + 'res.partner': ( + lambda self, cr, uid, ids, context=None: ids, + ['street_name', 'street_number'], 10), + }, + ), + } diff --git a/partner_street_number/view/res_partner.xml b/partner_street_number/view/res_partner.xml new file mode 100644 index 000000000..487619b96 --- /dev/null +++ b/partner_street_number/view/res_partner.xml @@ -0,0 +1,46 @@ + + + + + + Add separate fields for street name and number + res.partner + + + + +
+ + +
+
+ + +
+ + +
+
+ + + {'default_parent_id': active_id, 'default_street_name': street_name, 'default_street_number': street_number, 'default_street2': street2, 'default_city': city, 'default_state_id': state_id, 'default_zip': zip, 'default_country_id': country_id, 'default_supplier': supplier, 'default_customer': customer} + + +
+
+
+