Browse Source

[ADD] Partner NACE addon

pull/106/head
Antonio Espinosa 10 years ago
parent
commit
38b81cfa4c
  1. 34
      partner_nace/README.rst
  2. 26
      partner_nace/__init__.py
  3. 55
      partner_nace/__openerp__.py
  4. 217
      partner_nace/i18n/es.po
  5. 211
      partner_nace/i18n/partner_nace.pot
  6. 26
      partner_nace/models/__init__.py
  7. 34
      partner_nace/models/res_partner.py
  8. 49
      partner_nace/models/res_partner_nace.py
  9. 2
      partner_nace/security/ir.model.access.csv
  10. BIN
      partner_nace/static/description/icon.png
  11. 59
      partner_nace/views/res_partner_nace_view.xml
  12. 38
      partner_nace/views/res_partner_view.xml
  13. 25
      partner_nace/wizard/__init__.py
  14. 297
      partner_nace/wizard/nace_import.py
  15. 41
      partner_nace/wizard/nace_import_view.xml

34
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 <antonioea@antiun.com>

26
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 <antonioea@antiun.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import models
from . import wizard

55
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 <antonioea@antiun.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
{
# 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,
}

217
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"

211
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 ""

26
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 <antonioea@antiun.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import res_partner_nace
from . import res_partner

34
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 <antonioea@antiun.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
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")

49
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 <antonioea@antiun.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
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)

2
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

BIN
partner_nace/static/description/icon.png

After

Width: 128  |  Height: 128  |  Size: 4.8 KiB

59
partner_nace/views/res_partner_nace_view.xml

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="res_partner_nace_tree" model="ir.ui.view">
<field name="name">NACE Activities tree</field>
<field name="model">res.partner.nace</field>
<field name="arch" type="xml">
<tree string="NACE Activities">
<field name="level"/>
<field name="code"/>
<field name="name"/>
</tree>
</field>
</record>
<record id="res_partner_nace_form" model="ir.ui.view">
<field name="name">NACE Activities tree</field>
<field name="model">res.partner.nace</field>
<field name="arch" type="xml">
<form string="NACE Activity">
<group>
<group>
<field name="level"/>
<field name="code"/>
</group>
</group>
<group>
<field name="parent_id"/>
<field name="name"/>
<field name="rules"/>
<field name="generic"/>
<field name="central_content"/>
<field name="limit_content"/>
<field name="exclusions"/>
</group>
</form>
</field>
</record>
<record id="res_partner_nace_action" model="ir.actions.act_window">
<field name="name">NACE Activities</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.partner.nace</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help">You must click at import wizard to populate NACE items
in Odoo database in:
Sales > Configuration > Address Book > Import NACE Rev.2</field>
</record>
<menuitem action="res_partner_nace_action"
id="res_partner_nace_menu"
name="NACE Activities"
parent="base.menu_config_address_book"
sequence="40"/>
</data>
</openerp>

38
partner_nace/views/res_partner_view.xml

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record model="ir.ui.view" id="view_partner_form_nace">
<field name="name">Partner form with NACE activity</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<div name="buttons" position="after">
<group>
<field name="main_nace"
attrs="{'invisible': [('is_company', '=', False)]}"/>
<field name="secondary_naces" widget="many2many_tags"
attrs="{'invisible': [('is_company', '=', False)]}"/>
</group>
</div>
</field>
</record>
<record model="ir.ui.view" id="view_res_partner_filter_nace">
<field name="name">Partner search with activity</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_res_partner_filter"/>
<field name="arch" type="xml">
<field name="category_id" position="after">
<field name="main_nace"/>
</field>
<filter string="Salesperson" position="after">
<filter string="Activity"
domain="[]"
context="{'group_by': 'main_nace'}"/>
</filter>
</field>
</record>
</data>
</openerp>

25
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 <antonioea@antiun.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import nace_import

297
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 <antonioea@antiun.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
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 <?xml
pattern = re.compile(r'^.*<\?xml', re.DOTALL)
content_fixed = re.sub(pattern, '<?xml', res_request.content)
if not re.match(r'<\?xml', content_fixed):
raise Warning(_('Downloaded file is not a valid XML file'))
return content_fixed
@api.model
def create_or_update_nace(self, node):
if not self._check_node(node):
return False
nace_model = self.env['res.partner.nace']
data = self._mapping(node, False)
data.update(self._mapping(node, True))
level = data.get('level', 0)
if level >= 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

41
partner_nace/wizard/nace_import_view.xml

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="nace_import_form" model="ir.ui.view">
<field name="name">NACE import</field>
<field name="model">nace.import</field>
<field name="arch" type="xml">
<form string="Import NACE Rev.2 from RAMON">
<div>
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.
</div>
<footer>
<button name="run_import" type="object"
class="oe_highlight" string="Import"/>
<button special="cancel" string="Cancel" class="oe_link"/>
</footer>
</form>
</field>
</record>
<record id="nace_import_action" model="ir.actions.act_window">
<field name="name">Import NACE Rev.2 from RAMON</field>
<field name="res_model">nace.import</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<menuitem action="nace_import_action"
id="nace_import_menu"
name="Import NACE Rev.2"
parent="base.menu_config_address_book"
sequence="45"/>
</data>
</openerp>
Loading…
Cancel
Save