Browse Source

[ADD] partner_nace

pull/220/head
Javier Iniesta 9 years ago
parent
commit
1a74f256a2
  1. 100
      partner_nace/README.rst
  2. 6
      partner_nace/__init__.py
  3. 29
      partner_nace/__openerp__.py
  4. 0
      partner_nace/i18n/.gitkeep
  5. 217
      partner_nace/i18n/es.po
  6. 211
      partner_nace/i18n/partner_nace.pot
  7. 6
      partner_nace/models/__init__.py
  8. 15
      partner_nace/models/res_partner.py
  9. 28
      partner_nace/models/res_partner_nace.py
  10. 2
      partner_nace/security/ir.model.access.csv
  11. BIN
      partner_nace/static/description/icon.png
  12. 61
      partner_nace/views/res_partner_nace_view.xml
  13. 40
      partner_nace/views/res_partner_view.xml
  14. 5
      partner_nace/wizard/__init__.py
  15. 265
      partner_nace/wizard/nace_import.py
  16. 43
      partner_nace/wizard/nace_import_view.xml

100
partner_nace/README.rst

@ -0,0 +1,100 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
==========================
NACE Activities in Partner
==========================
This module adds the concept of NACE activity to the partner.
NACE is the Statistical Classification of Economic Activities in the European
Community. More info at http://ec.europa.eu/eurostat/en/web/products-manuals-and-guidelines/-/KS-RA-07-015
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.
Installation
============
To install this module, you need request python module:
* pip intall requests
Configuration
=============
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.
Usage
=====
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.
After configuration, all NACE activities are available to be selected in
partner form as main and secondary activities.
Applies only to partners marked as companies
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/134/8.0
For further information, please visit:
* https://www.odoo.com/forum/help-1
Known issues / Roadmap
======================
* Improve import algorithm: Use context lang key to translate NACE items
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/partner-contact/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback
`here <https://github.com/OCA/partner-contact/issues/new?body=module:%20partner_nace%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
Contributors
------------
* Rafael Blasco <rafabn@antiun.com>
* Antonio Espinosa <antonioea@antiun.com>
* Javier Iniesta <javieria@antiun.com>
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
To contribute to this module, please visit https://odoo-community.org.

6
partner_nace/__init__.py

@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import models
from . import wizard

29
partner_nace/__openerp__.py

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "NACE Activities",
"version": "8.0.1.0.0",
"category": "Localisation/Europe",
"website": "http://www.antiun.com",
"author": "Antiun Ingeniería S.L., "
"Odoo Community Association (OCA)",
"license": "AGPL-3",
"application": False,
"installable": True,
"external_dependencies": {
"python": [
"requests",
],
},
"depends": [
"base",
],
"data": [
'views/res_partner_nace_view.xml',
'views/res_partner_view.xml',
'wizard/nace_import_view.xml',
'security/ir.model.access.csv',
]
}

0
partner_nace/i18n/.gitkeep

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,child_ids: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_id: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_nace_ids: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,child_ids: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_id: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_nace_ids: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 ""

6
partner_nace/models/__init__.py

@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import res_partner
from . import res_partner_nace

15
partner_nace/models/res_partner.py

@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, fields
class ResPartner(models.Model):
_inherit = 'res.partner'
main_nace_id = fields.Many2one(comodel_name='res.partner.nace',
string="Main activity", ondelete='set null')
secondary_nace_ids = fields.Many2many(comodel_name='res.partner.nace',
string="Other activities",
ondelete='set null')

28
partner_nace/models/res_partner_nace.py

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
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"
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_id = fields.Many2one(comodel_name='res.partner.nace',
ondelete='restrict')
child_ids = fields.One2many(comodel_name='res.partner.nace',
inverse_name='parent_id', string="Children")
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

61
partner_nace/views/res_partner_nace_view.xml

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<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>

40
partner_nace/views/res_partner_view.xml

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<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_id"
attrs="{'invisible': [('is_company', '=', False)]}"/>
<field name="secondary_nace_ids" 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_id"/>
</field>
<filter string="Salesperson" position="after">
<filter string="Activity"
domain="[('is_company', '=', True)]"
context="{'group_by': 'main_nace_id'}"/>
</filter>
</field>
</record>
</data>
</openerp>

5
partner_nace/wizard/__init__.py

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import nace_import

265
partner_nace/wizard/nace_import.py

@ -0,0 +1,265 @@
# -*- coding: utf-8 -*-
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, api, _
from openerp.exceptions import Warning
import requests
import re
import logging
from lxml import etree
from collections import OrderedDict
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_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}),
])
_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': 'EN',
# 'IntKey': '',
# 'IntLevel': '',
# 'TxtDelimiter': ';',
# 'bExport': '',
}
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:
value = ''
if field_xpath:
n = node.find(field_xpath)
else:
n = node
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):
params = self._url_params.copy()
params['StrLanguageCode'] = lang_code
url = self._url_base + self._url_path + '?'
url += '&'.join([k + '=' + v for k, v in 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'].\
with_context(defer_parent_store_computation=True)
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.debug('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.debug('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

43
partner_nace/wizard/nace_import_view.xml

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<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