From 38b81cfa4c572b604cae9fe5bad0fdffef332d40 Mon Sep 17 00:00:00 2001 From: Antonio Espinosa Date: Mon, 30 Mar 2015 16:06:05 +0200 Subject: [PATCH] [ADD] Partner NACE addon --- partner_nace/README.rst | 34 +++ partner_nace/__init__.py | 26 ++ partner_nace/__openerp__.py | 55 ++++ partner_nace/i18n/es.po | 217 ++++++++++++++ partner_nace/i18n/partner_nace.pot | 211 +++++++++++++ partner_nace/models/__init__.py | 26 ++ partner_nace/models/res_partner.py | 34 +++ partner_nace/models/res_partner_nace.py | 49 +++ partner_nace/security/ir.model.access.csv | 2 + partner_nace/static/description/icon.png | Bin 0 -> 4879 bytes partner_nace/views/res_partner_nace_view.xml | 59 ++++ partner_nace/views/res_partner_view.xml | 38 +++ partner_nace/wizard/__init__.py | 25 ++ partner_nace/wizard/nace_import.py | 297 +++++++++++++++++++ partner_nace/wizard/nace_import_view.xml | 41 +++ 15 files changed, 1114 insertions(+) create mode 100644 partner_nace/README.rst create mode 100644 partner_nace/__init__.py create mode 100644 partner_nace/__openerp__.py create mode 100644 partner_nace/i18n/es.po create mode 100644 partner_nace/i18n/partner_nace.pot create mode 100644 partner_nace/models/__init__.py create mode 100644 partner_nace/models/res_partner.py create mode 100644 partner_nace/models/res_partner_nace.py create mode 100644 partner_nace/security/ir.model.access.csv create mode 100644 partner_nace/static/description/icon.png create mode 100644 partner_nace/views/res_partner_nace_view.xml create mode 100644 partner_nace/views/res_partner_view.xml create mode 100644 partner_nace/wizard/__init__.py create mode 100644 partner_nace/wizard/nace_import.py create mode 100644 partner_nace/wizard/nace_import_view.xml diff --git a/partner_nace/README.rst b/partner_nace/README.rst new file mode 100644 index 000000000..8315a3a31 --- /dev/null +++ b/partner_nace/README.rst @@ -0,0 +1,34 @@ +NACE Activities in Partner +========================== + +This module adds the concept of NACE activity to the partner. Allows you to +select in partner form: + +* Main NACE activity in a dropdown (many2one) +* Secondary NACE activities in a multi label input (many2many) + +This addon is inspired in OCA/community-data-files/l10n_eu_nace, but it does +not use partner categories to assign NACE activities to partner. + +Applies only to partners marked as companies + +After installation, you must click at import wizard to populate NACE items +in Odoo database in: +Sales > Configuration > Address Book > Import NACE Rev.2 from RAMON + +This wizard will download from Europe RAMON service the metadata to +build NACE database in Odoo in all installed languages. + +If you add a new language (or want to re-build NACE database), you should call +import wizard again. + +Only Administrator can manage NACE activity list (it is not neccesary because +it is an European convention) but any registered user can read them, +in order to allow to assign them to partner object. + +Credits +======= + +Contributors +------------ +* Antonio Espinosa diff --git a/partner_nace/__init__.py b/partner_nace/__init__.py new file mode 100644 index 000000000..1f1abdf15 --- /dev/null +++ b/partner_nace/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Python source code encoding : https://www.python.org/dev/peps/pep-0263/ +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright : +# (c) 2015 Antiun Ingenieria, SL (Madrid, Spain, http://www.antiun.com) +# Antonio Espinosa +# +# 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 models +from . import wizard diff --git a/partner_nace/__openerp__.py b/partner_nace/__openerp__.py new file mode 100644 index 000000000..901359fc2 --- /dev/null +++ b/partner_nace/__openerp__.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Python source code encoding : https://www.python.org/dev/peps/pep-0263/ +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright : +# (c) 2015 Antiun Ingenieria, SL (Madrid, Spain, http://www.antiun.com) +# Antonio Espinosa +# +# 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 . +# +############################################################################## + +{ + # Addon information + 'name': 'NACE Activities', + 'category': 'Localisation/Europe', + 'version': '1.0', + 'depends': [ + 'base', + ], + 'external_dependencies': {}, + # Views templates, pages, menus, options and snippets + 'data': [ + 'views/res_partner_nace_view.xml', + 'views/res_partner_view.xml', + 'wizard/nace_import_view.xml', + 'security/ir.model.access.csv', + ], + # Qweb templates + 'qweb': [ + ], + # Your information + 'author': 'Antiun Ingeniería, SL', + 'maintainer': 'Antiun Ingeniería, SL', + 'website': 'http://www.antiun.com', + 'license': 'AGPL-3', + # Technical options + 'demo': [], + 'test': [], + 'installable': True, + # 'auto_install':False, + # 'active':True, +} diff --git a/partner_nace/i18n/es.po b/partner_nace/i18n/es.po new file mode 100644 index 000000000..d41cc901c --- /dev/null +++ b/partner_nace/i18n/es.po @@ -0,0 +1,217 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * partner_nace +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-03-30 13:30+0000\n" +"PO-Revision-Date: 2015-03-30 13:30+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_nace +#: view:res.partner:partner_nace.view_res_partner_filter_nace +msgid "Activity" +msgstr "Actividad" + +#. module: partner_nace +#: field:res.partner.nace,limit_content:0 +msgid "Also contents" +msgstr "También contiene" + +#. module: partner_nace +#: view:nace.import:partner_nace.nace_import_form +msgid "Cancel" +msgstr "Cancelar" + +#. module: partner_nace +#: field:res.partner.nace,children:0 +msgid "Children" +msgstr "Hijos" + +#. module: partner_nace +#: field:res.partner.nace,code:0 +msgid "Code" +msgstr "Código" + +#. module: partner_nace +#: field:res.partner.nace,central_content:0 +msgid "Contents" +msgstr "Contiene" + +#. module: partner_nace +#: field:nace.import,create_uid:0 +#: field:res.partner.nace,create_uid:0 +msgid "Created by" +msgstr "Creado por" + +#. module: partner_nace +#: field:nace.import,create_date:0 +#: field:res.partner.nace,create_date:0 +msgid "Created on" +msgstr "Creado en" + +#. module: partner_nace +#: code:addons/partner_nace/wizard/nace_import.py:204 +#, python-format +msgid "Downloaded file is not a valid XML file" +msgstr "El fichero descargado no es un fichero XML válido" + +#. module: partner_nace +#: field:res.partner.nace,exclusions:0 +msgid "Excludes" +msgstr "Excluye" + +#. module: partner_nace +#: code:addons/partner_nace/wizard/nace_import.py:196 +#, python-format +msgid "Got an error %d when trying to download the file %s." +msgstr "Error %d al intentar descargar el fichero %s." + +#. module: partner_nace +#: code:addons/partner_nace/wizard/nace_import.py:192 +#, python-format +msgid "Got an error when trying to download the file: %s." +msgstr "Error al intentar descargar el fichero: %s." + +#. module: partner_nace +#: field:nace.import,id:0 +#: field:res.partner.nace,id:0 +msgid "ID" +msgstr "ID" + +#. module: partner_nace +#: field:res.partner.nace,generic:0 +msgid "ISIC Rev.4" +msgstr "ISIC Rev.4" + +#. module: partner_nace +#: view:nace.import:partner_nace.nace_import_form +msgid "Import" +msgstr "Importar" + +#. module: partner_nace +#: model:ir.ui.menu,name:partner_nace.nace_import_menu +msgid "Import NACE Rev.2" +msgstr "Importar NACE Rev.2" + +#. module: partner_nace +#: model:ir.actions.act_window,name:partner_nace.nace_import_action +#: view:nace.import:partner_nace.nace_import_form +msgid "Import NACE Rev.2 from RAMON" +msgstr "Importar NACE Rev.2 desde RAMON" + +#. module: partner_nace +#: model:ir.model,name:partner_nace.model_nace_import +msgid "Import NACE activities from European RAMON service" +msgstr "Importar actividades NACE desde el servicio europeo RAMON" + +#. module: partner_nace +#: field:nace.import,write_uid:0 +#: field:res.partner.nace,write_uid:0 +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: partner_nace +#: field:nace.import,write_date:0 +#: field:res.partner.nace,write_date:0 +msgid "Last Updated on" +msgstr "Última actualización en" + +#. module: partner_nace +#: field:res.partner.nace,level:0 +msgid "Level" +msgstr "Nivel" + +#. module: partner_nace +#: field:res.partner,main_nace:0 +msgid "Main activity" +msgstr "Actividad principal" + +#. module: partner_nace +#: model:ir.actions.act_window,name:partner_nace.res_partner_nace_action +#: model:ir.ui.menu,name:partner_nace.res_partner_nace_menu +#: view:res.partner.nace:partner_nace.res_partner_nace_tree +msgid "NACE Activities" +msgstr "Actividades NACE" + +#. module: partner_nace +#: model:ir.model,name:partner_nace.model_res_partner_nace +#: view:res.partner.nace:partner_nace.res_partner_nace_form +msgid "NACE Activity" +msgstr "Actividad NACE" + +#. module: partner_nace +#: field:res.partner.nace,name:0 +msgid "Name" +msgstr "Nombre" + +#. module: partner_nace +#: field:res.partner,secondary_naces:0 +msgid "Other activities" +msgstr "Otras actividades" + +#. module: partner_nace +#: field:res.partner.nace,parent_left:0 +msgid "Parent Left" +msgstr "Padre izquierda" + +#. module: partner_nace +#: field:res.partner.nace,parent_right:0 +msgid "Parent Right" +msgstr "Padre derecha" + +#. module: partner_nace +#: field:res.partner.nace,parent_id:0 +msgid "Parent id" +msgstr "ID del padre" + +#. module: partner_nace +#: model:ir.model,name:partner_nace.model_res_partner +msgid "Partner" +msgstr "Empresa" + +#. module: partner_nace +#: field:res.partner.nace,rules:0 +msgid "Rules" +msgstr "Reglas" + +#. module: partner_nace +#: view:res.partner:partner_nace.view_res_partner_filter_nace +msgid "Salesperson" +msgstr "Comercial" + +#. module: partner_nace +#: view:nace.import:partner_nace.nace_import_form +msgid "This wizard will download the lastest version of\n" +" NACE Rev.2 from Europe RAMON metadata service.\n" +" Updating or creating new NACE code entries if not\n" +" found already in the system, and DELETE MISSING\n" +" ENTRIES from new downloaded file." +msgstr "Este asistente descargará la última version de\n" +" NACE Rev.2 desde el servicio de matadatos europeo RAMON.\n" +" Actualizará o creará nuevas actividades NACE si no\n" +" las encuentra en el sistemma, y BORRARÁ LAS QUE NO ENCUENTRE\n" +" en el nuevo fichero descargado." + +#. module: partner_nace +#: code:addons/partner_nace/wizard/nace_import.py:168 +#, python-format +msgid "Value not found for mandatory field %s" +msgstr "El valor no se ha encontrado para el campo obligatorio %s" + +#. module: partner_nace +#: model:ir.actions.act_window,help:partner_nace.res_partner_nace_action +msgid "You must click at import wizard to populate NACE items\n" +" in Odoo database in:\n" +" Sales > Configuration > Address Book > Import NACE Rev.2" +msgstr "Debes clicar en el asistente de importación para crear las\n" +" las actividades NACE en la base de datos de Odoo, en el menú:\n" +" Ventas > Configuración > Libreta de direcciones > Importar NACE Rev.2" + diff --git a/partner_nace/i18n/partner_nace.pot b/partner_nace/i18n/partner_nace.pot new file mode 100644 index 000000000..2d6439c6e --- /dev/null +++ b/partner_nace/i18n/partner_nace.pot @@ -0,0 +1,211 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * partner_nace +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-03-30 13:30+0000\n" +"PO-Revision-Date: 2015-03-30 13:30+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_nace +#: view:res.partner:partner_nace.view_res_partner_filter_nace +msgid "Activity" +msgstr "" + +#. module: partner_nace +#: field:res.partner.nace,limit_content:0 +msgid "Also contents" +msgstr "" + +#. module: partner_nace +#: view:nace.import:partner_nace.nace_import_form +msgid "Cancel" +msgstr "" + +#. module: partner_nace +#: field:res.partner.nace,children:0 +msgid "Children" +msgstr "" + +#. module: partner_nace +#: field:res.partner.nace,code:0 +msgid "Code" +msgstr "" + +#. module: partner_nace +#: field:res.partner.nace,central_content:0 +msgid "Contents" +msgstr "" + +#. module: partner_nace +#: field:nace.import,create_uid:0 +#: field:res.partner.nace,create_uid:0 +msgid "Created by" +msgstr "" + +#. module: partner_nace +#: field:nace.import,create_date:0 +#: field:res.partner.nace,create_date:0 +msgid "Created on" +msgstr "" + +#. module: partner_nace +#: code:addons/partner_nace/wizard/nace_import.py:204 +#, python-format +msgid "Downloaded file is not a valid XML file" +msgstr "" + +#. module: partner_nace +#: field:res.partner.nace,exclusions:0 +msgid "Excludes" +msgstr "" + +#. module: partner_nace +#: code:addons/partner_nace/wizard/nace_import.py:196 +#, python-format +msgid "Got an error %d when trying to download the file %s." +msgstr "" + +#. module: partner_nace +#: code:addons/partner_nace/wizard/nace_import.py:192 +#, python-format +msgid "Got an error when trying to download the file: %s." +msgstr "" + +#. module: partner_nace +#: field:nace.import,id:0 +#: field:res.partner.nace,id:0 +msgid "ID" +msgstr "" + +#. module: partner_nace +#: field:res.partner.nace,generic:0 +msgid "ISIC Rev.4" +msgstr "" + +#. module: partner_nace +#: view:nace.import:partner_nace.nace_import_form +msgid "Import" +msgstr "" + +#. module: partner_nace +#: model:ir.ui.menu,name:partner_nace.nace_import_menu +msgid "Import NACE Rev.2" +msgstr "" + +#. module: partner_nace +#: model:ir.actions.act_window,name:partner_nace.nace_import_action +#: view:nace.import:partner_nace.nace_import_form +msgid "Import NACE Rev.2 from RAMON" +msgstr "" + +#. module: partner_nace +#: model:ir.model,name:partner_nace.model_nace_import +msgid "Import NACE activities from European RAMON service" +msgstr "" + +#. module: partner_nace +#: field:nace.import,write_uid:0 +#: field:res.partner.nace,write_uid:0 +msgid "Last Updated by" +msgstr "" + +#. module: partner_nace +#: field:nace.import,write_date:0 +#: field:res.partner.nace,write_date:0 +msgid "Last Updated on" +msgstr "" + +#. module: partner_nace +#: field:res.partner.nace,level:0 +msgid "Level" +msgstr "" + +#. module: partner_nace +#: field:res.partner,main_nace:0 +msgid "Main activity" +msgstr "" + +#. module: partner_nace +#: model:ir.actions.act_window,name:partner_nace.res_partner_nace_action +#: model:ir.ui.menu,name:partner_nace.res_partner_nace_menu +#: view:res.partner.nace:partner_nace.res_partner_nace_tree +msgid "NACE Activities" +msgstr "" + +#. module: partner_nace +#: model:ir.model,name:partner_nace.model_res_partner_nace +#: view:res.partner.nace:partner_nace.res_partner_nace_form +msgid "NACE Activity" +msgstr "" + +#. module: partner_nace +#: field:res.partner.nace,name:0 +msgid "Name" +msgstr "" + +#. module: partner_nace +#: field:res.partner,secondary_naces:0 +msgid "Other activities" +msgstr "" + +#. module: partner_nace +#: field:res.partner.nace,parent_left:0 +msgid "Parent Left" +msgstr "" + +#. module: partner_nace +#: field:res.partner.nace,parent_right:0 +msgid "Parent Right" +msgstr "" + +#. module: partner_nace +#: field:res.partner.nace,parent_id:0 +msgid "Parent id" +msgstr "" + +#. module: partner_nace +#: model:ir.model,name:partner_nace.model_res_partner +msgid "Partner" +msgstr "" + +#. module: partner_nace +#: field:res.partner.nace,rules:0 +msgid "Rules" +msgstr "" + +#. module: partner_nace +#: view:res.partner:partner_nace.view_res_partner_filter_nace +msgid "Salesperson" +msgstr "" + +#. module: partner_nace +#: view:nace.import:partner_nace.nace_import_form +msgid "This wizard will download the lastest version of\n" +" NACE Rev.2 from Europe RAMON metadata service.\n" +" Updating or creating new NACE code entries if not\n" +" found already in the system, and DELETE MISSING\n" +" ENTRIES from new downloaded file." +msgstr "" + +#. module: partner_nace +#: code:addons/partner_nace/wizard/nace_import.py:168 +#, python-format +msgid "Value not found for mandatory field %s" +msgstr "" + +#. module: partner_nace +#: model:ir.actions.act_window,help:partner_nace.res_partner_nace_action +msgid "You must click at import wizard to populate NACE items\n" +" in Odoo database in:\n" +" Sales > Configuration > Address Book > Import NACE Rev.2" +msgstr "" + diff --git a/partner_nace/models/__init__.py b/partner_nace/models/__init__.py new file mode 100644 index 000000000..f34f66e64 --- /dev/null +++ b/partner_nace/models/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Python source code encoding : https://www.python.org/dev/peps/pep-0263/ +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright : +# (c) 2015 Antiun Ingenieria, SL (Madrid, Spain, http://www.antiun.com) +# Antonio Espinosa +# +# 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 res_partner_nace +from . import res_partner diff --git a/partner_nace/models/res_partner.py b/partner_nace/models/res_partner.py new file mode 100644 index 000000000..d37cf78da --- /dev/null +++ b/partner_nace/models/res_partner.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Python source code encoding : https://www.python.org/dev/peps/pep-0263/ +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright : +# (c) 2015 Antiun Ingenieria, SL (Madrid, Spain, http://www.antiun.com) +# Antonio Espinosa +# +# 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 openerp import models, fields + + +class ResPartner(models.Model): + _inherit = 'res.partner' + + main_nace = fields.Many2one(comodel_name='res.partner.nace', + string="Main activity") + secondary_naces = fields.Many2many(comodel_name='res.partner.nace', + string="Other activities") diff --git a/partner_nace/models/res_partner_nace.py b/partner_nace/models/res_partner_nace.py new file mode 100644 index 000000000..0230c16d3 --- /dev/null +++ b/partner_nace/models/res_partner_nace.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Python source code encoding : https://www.python.org/dev/peps/pep-0263/ +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright : +# (c) 2015 Antiun Ingenieria, SL (Madrid, Spain, http://www.antiun.com) +# Antonio Espinosa +# +# 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 openerp import models, fields + + +class ResPartnerNace(models.Model): + _name = 'res.partner.nace' + # _order = "parent_left" + # _parent_order = "name" + # _parent_store = True + _description = "NACE Activity" + + # NACE fields + level = fields.Integer(required=True) + code = fields.Char(required=True) + name = fields.Char(required=True, translate=True) + generic = fields.Char(string="ISIC Rev.4") + rules = fields.Text() + central_content = fields.Text(translate=True, string="Contents") + limit_content = fields.Text(translate=True, string="Also contents") + exclusions = fields.Char(string="Excludes") + # Parent hierarchy + parent_id = fields.Many2one(comodel_name='res.partner.nace') + # children = fields.One2many(comodel_name='res.partner.nace', + # inverse_name='parent_id') + # parent_left = fields.Integer('Parent Left', select=True) + # parent_right = fields.Integer('Parent Right', select=True) diff --git a/partner_nace/security/ir.model.access.csv b/partner_nace/security/ir.model.access.csv new file mode 100644 index 000000000..cbf7dd7a9 --- /dev/null +++ b/partner_nace/security/ir.model.access.csv @@ -0,0 +1,2 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +"access_res_partner_nace_user","res_partner_nace group_user","model_res_partner_nace","base.group_user",1,0,0,0 diff --git a/partner_nace/static/description/icon.png b/partner_nace/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cf07216b4137328961802dd200879117514bbd7a GIT binary patch literal 4879 zcma)gWl$Sh&^825p?GmZfl{DQT#5#FDa8vnSaB;(u;3I+Tf9KA5-t!Nij$zlU5f>G zN^$4q{`$W6-#h2ovom{s?3vlw-DjRpy4orvKzbk+78Z$`s-oVbhy7=S_>Xs|jOD>C2q3rKPvQohMCx|YHr@jKUMP7P^Do)C$ykj9^dH#O_*%g0AAjW9;oRBw)}Jn zXGtjPU@UjGfB9vwhijNBK#`wH&Y>!0N<)xVaGPOJ88Veu#pc7>g-fPB>45d3ggdN- zo=@j}JC4KNo0fXst&5zl{KgYHXW`;|(XXMWeY+9^{s$zTS%oIxd8p4xU8in|{Z662&OUqD)NIT!iB9NOSYho*& zbaNNp3=$Vo@$DF#BJ#p1&6tYM^tu1=2V{s|(DVC~yC#@JG^a$6Ivegj6yB*a7!Rig z=}=J402ZKMgV!b`lhJ)}V{G?DV1)dR8UrET(0ZX03M613Tq&XZTSvj+E&0z0#x`6s zAY7Y?xJ1SGH#ZL_xUp09df$oR?&M9hX&7W<`K*VYx^@BYR@E3(hH~ z2ADLud@#Ml@A$}J=`aw$`0%V%^t zY}p>*sauE6B;W8+?8CYBynk<*`C+p1hYYo-@0ut~Wo>z2)BUb;5hJ{lr|<1uK^QU9 z8__IAZhcni@(Zt_mE@%IN#gw6nYp0-J%0A`O4u4Q=)&bY)PuTVD3|CcCm2DMM0!h4 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 hl>bi;`e=Ad + + + + + NACE Activities tree + res.partner.nace + + + + + + + + + + + NACE Activities tree + res.partner.nace + +
+ + + + + + + + + + + + + + + +
+
+
+ + + NACE Activities + ir.actions.act_window + res.partner.nace + form + tree,form + You must click at import wizard to populate NACE items + in Odoo database in: + Sales > Configuration > Address Book > Import NACE Rev.2 + + + + +
+
\ No newline at end of file diff --git a/partner_nace/views/res_partner_view.xml b/partner_nace/views/res_partner_view.xml new file mode 100644 index 000000000..cbe110934 --- /dev/null +++ b/partner_nace/views/res_partner_view.xml @@ -0,0 +1,38 @@ + + + + + + Partner form with NACE activity + res.partner + + +
+ + + + +
+
+
+ + + Partner search with activity + res.partner + + + + + + + + + + + +
+
\ No newline at end of file diff --git a/partner_nace/wizard/__init__.py b/partner_nace/wizard/__init__.py new file mode 100644 index 000000000..2902a27ab --- /dev/null +++ b/partner_nace/wizard/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Python source code encoding : https://www.python.org/dev/peps/pep-0263/ +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright : +# (c) 2015 Antiun Ingenieria, SL (Madrid, Spain, http://www.antiun.com) +# Antonio Espinosa +# +# 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 nace_import diff --git a/partner_nace/wizard/nace_import.py b/partner_nace/wizard/nace_import.py new file mode 100644 index 000000000..937a93b04 --- /dev/null +++ b/partner_nace/wizard/nace_import.py @@ -0,0 +1,297 @@ +# -*- coding: utf-8 -*- +# Python source code encoding : https://www.python.org/dev/peps/pep-0263/ +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright : +# (c) 2015 Antiun Ingenieria, SL (Madrid, Spain, http://www.antiun.com) +# Antonio Espinosa +# +# 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 openerp import models, api, _ +from openerp.exceptions import Warning +import requests +import re +import logging +from lxml import etree +from collections import OrderedDict + +from pprint import pformat + +logger = logging.getLogger(__name__) + + +class NaceImport(models.TransientModel): + _name = 'nace.import' + _description = 'Import NACE activities from European RAMON service' + _parents = [False, False, False, False] + _available_langs = { + 'bg_BG': 'BG', # Bulgarian + 'cs_CZ': 'CZ', # Czech + 'da_DK': 'DA', # Danish + 'de_DE': 'DE', # German + 'et_EE': 'EE', # Estonian + 'el_GR': 'EL', # Greek + 'es_AR': 'ES', # Spanish (AR) + 'es_BO': 'ES', # Spanish (BO) + 'es_CL': 'ES', # Spanish (CL) + 'es_CO': 'ES', # Spanish (CO) + 'es_CR': 'ES', # Spanish (CR) + 'es_DO': 'ES', # Spanish (DO) + 'es_EC': 'ES', # Spanish (EC) + 'es_GT': 'ES', # Spanish (GT) + 'es_HN': 'ES', # Spanish (HN) + 'es_MX': 'ES', # Spanish (MX) + 'es_NI': 'ES', # Spanish (NI) + 'es_PA': 'ES', # Spanish (PA) + 'es_PE': 'ES', # Spanish (PE) + 'es_PR': 'ES', # Spanish (PR) + 'es_PY': 'ES', # Spanish (PY) + 'es_SV': 'ES', # Spanish (SV) + 'es_UY': 'ES', # Spanish (UY) + 'es_VE': 'ES', # Spanish (VE) + 'es_PY': 'ES', # Spanish (PY) + 'es_ES': 'ES', # Spanish + 'fi_FI': 'FI', # Finnish + 'fr_BE': 'FR', # French (FR) + 'fr_CA': 'FR', # French (CA) + 'fr_CH': 'FR', # French (CH) + 'fr_FR': 'FR', # French + 'hr_HR': 'HR', # Croatian + 'hu_HU': 'HU', # Hungarian + 'it_IT': 'IT', # Italian + 'lt_LT': 'LT', # Lithuanian + 'lv_LV': 'LV', # Latvian + # '': 'MT', # Il-Malti, has no language in Odoo + 'nl_BE': 'NL', # Dutch (BE) + 'nl_NL': 'NL', # Dutch + 'nb_NO': 'NO', # Norwegian Bokmål + 'pl_PL': 'PL', # Polish + 'pt_BR': 'PT', # Portuguese (BR) + 'pt_PT': 'PT', # Portuguese + 'ro_RO': 'RO', # Romanian + 'ru_RU': 'RU', # Russian + 'sl_SI': 'SI', # Slovenian + 'sk_SK': 'SK', # Slovak + 'sv_SE': 'SV', # Swedish + 'tr_TR': 'TR', # Turkish + } + _map = OrderedDict([ + ('level', {'xpath': '', 'attrib': 'idLevel', 'type': 'integer', + 'translate': False, 'required': True}), + ('code', {'xpath': '', 'attrib': 'id', 'type': 'string', + 'translate': False, 'required': True}), + ('name', {'xpath': './Label/LabelText', 'type': 'string', + 'translate': True, 'required': True}), + ('generic', { + 'xpath': './Property[@name="Generic"]' + '/PropertyQualifier[@name="Value"]/PropertyText', + 'type': 'string', 'translate': False, 'required': False}), + ('rules', { + 'xpath': './Property[@name="ExplanatoryNote"]' + '/PropertyQualifier[@name="Rules"]/PropertyText', + 'type': 'string', 'translate': False, 'required': False}), + ('central_content', { + 'xpath': './Property[@name="ExplanatoryNote"]' + '/PropertyQualifier[@name="CentralContent"]/PropertyText', + 'type': 'string', 'translate': True, 'required': False}), + ('limit_content', { + 'xpath': './Property[@name="ExplanatoryNote"]' + '/PropertyQualifier[@name="LimitContent"]/PropertyText', + 'type': 'string', 'translate': True, 'required': False}), + ('exclusions', { + 'xpath': './Property[@name="ExplanatoryNote"]' + '/PropertyQualifier[@name="Exclusions"]/PropertyText', + 'type': 'string', 'translate': True, 'required': False}), + ]) + + def _check_node(self, node): + if node.get('id') and node.get('idLevel'): + return True + return False + + def _mapping(self, node, translate): + item = {} + for k, v in self._map.iteritems(): + field_translate = v.get('translate', False) + field_xpath = v.get('xpath', '') + field_attrib = v.get('attrib', False) + field_type = v.get('type', 'string') + field_required = v.get('required', False) + if field_translate == translate: + # logger.info("_mapping = '%s', config = '%s', node = '%s'" % + # (k, pformat(v), pformat(node))) + # logger.info("_mapping:children = '%s'" % + # (pformat(node.getchildren()))) + # for x in node.getchildren(): + # logger.info("_mapping:grandchildren = '%s'" % + # (pformat(x.getchildren()))) + # logger.info("_mapping:LabelText = '%s'" % + # (pformat(node.find('./Label/LabelText')))) + value = '' + if field_xpath: + n = node.find(field_xpath) + # logger.info("_mapping:Finding = '%s', result='%s'" % + # (field_xpath, pformat(n))) + else: + n = node + # logger.info("_mapping:Using same node='%s'" % + # (pformat(n))) + if n is not None: + if field_attrib: + value = n.get(field_attrib, '') + else: + value = n.text + if field_type == 'integer': + try: + value = int(value) + except: + value = 0 + else: + logger.debug("xpath = '%s', not found" % field_xpath) + if field_required and not value: + raise Warning( + _('Value not found for mandatory field %s' % k)) + item[k] = value + return item + + def _download_nace(self, lang_code): + url_base = 'http://ec.europa.eu' + url_path = '/eurostat/ramon/nomenclatures/index.cfm' + url_params = { + 'TargetUrl': 'ACT_OTH_CLS_DLD', + 'StrNom': 'NACE_REV2', + 'StrFormat': 'XML', + 'StrLanguageCode': lang_code, + # 'IntKey': '', + # 'IntLevel': '', + # 'TxtDelimiter': ';', + # 'bExport': '', + } + url = url_base + url_path + '?' + url += '&'.join([k + '=' + v for k, v in url_params.iteritems()]) + logger.info('Starting to download %s' % url) + try: + res_request = requests.get(url) + except Exception, e: + raise Warning( + _('Got an error when trying to download the file: %s.') % + str(e)) + if res_request.status_code != requests.codes.ok: + raise Warning( + _('Got an error %d when trying to download the file %s.') + % (res_request.status_code, url)) + logger.info('Download successfully %d bytes' % + len(res_request.content)) + # Workaround XML: Remove all characters before = 2 and level <= 5: + data['parent_id'] = self._parents[level - 2] + nace = nace_model.search([('level', '=', data['level']), + ('code', '=', data['code'])]) + if nace: + nace.write(data) + else: + nace = nace_model.create(data) + if level >= 1 and level <= 4: + self._parents[level - 1] = nace.id + return nace + + @api.model + def translate_nace(self, node, lang): + translation_model = self.env['ir.translation'] + nace_model = self.env['res.partner.nace'] + index = self._mapping(node, False) + trans = self._mapping(node, True) + nace = nace_model.search([('level', '=', index['level']), + ('code', '=', index['code'])]) + if nace: + for field, value in trans.iteritems(): + name = 'res.partner.nace,' + field + query = [('res_id', '=', nace.id), + ('type', '=', 'model'), + ('name', '=', name), + ('lang', '=', lang.code)] + translation = translation_model.search(query) + data = { + 'value': value, + 'state': 'translated' + } + if translation: + translation_model.write(data) + else: + data['res_id'] = nace.id + data['type'] = 'model' + data['name'] = name + data['lang'] = lang.code + translation_model.create(data) + + @api.one + def run_import(self): + nace_model = self.env['res.partner.nace'] + lang_model = self.env['res.lang'] + # Available lang list + langs = lang_model.search( + [('code', 'in', self._available_langs.keys()), + ('active', '=', True)]) + # All current NACEs, delete if not found above + naces_to_delete = nace_model.search([]) + # Download NACEs in english, create or update + logger.info('Import NACE Rev.2 English') + xmlcontent = self._download_nace('EN') + dom = etree.fromstring(xmlcontent) + for node in dom.iter('Item'): + logger.info('Reading level=%s, code=%s' % + (node.get('idLevel', 'N/A'), + node.get('id', 'N/A'))) + nace = self.create_or_update_nace(node) + if nace and nace in naces_to_delete: + naces_to_delete -= nace + # Download NACEs in other languages, translate them + for lang in langs: + logger.info('Import NACE Rev.2 %s' % lang.code) + nace_lang = self._available_langs[lang.code] + xmlcontent = self._download_nace(nace_lang) + dom = etree.fromstring(xmlcontent) + for node in dom.iter('Item'): + logger.info('Reading lang=%s, level=%s, code=%s' % + (nace_lang, node.get('idLevel', 'N/A'), + node.get('id', 'N/A'))) + self.translate_nace(node, lang) + # Delete obsolete NACEs + if naces_to_delete: + naces_to_delete.unlink() + logger.info('%d NACEs entries deleted' % len(naces_to_delete)) + logger.info( + 'The wizard to create NACEs entries from RAMON ' + 'has been successfully completed.') + + return True diff --git a/partner_nace/wizard/nace_import_view.xml b/partner_nace/wizard/nace_import_view.xml new file mode 100644 index 000000000..c23db3131 --- /dev/null +++ b/partner_nace/wizard/nace_import_view.xml @@ -0,0 +1,41 @@ + + + + + + NACE import + nace.import + +
+
+ This wizard will download the lastest version of + NACE Rev.2 from Europe RAMON metadata service. + Updating or creating new NACE code entries if not + found already in the system, and DELETE MISSING + ENTRIES from new downloaded file. +
+
+
+
+
+
+ + + Import NACE Rev.2 from RAMON + nace.import + form + form + new + + + + +
+