major update intrastat V3 modules

This commit is contained in:
luc-demeyer
2015-10-20 20:26:19 +02:00
committed by Alexis de Lattre
parent e0664db3b9
commit f61a01cc7d
51 changed files with 893 additions and 565 deletions

View File

@@ -1,3 +1,9 @@
.. 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
=====================
Intrastat Base Module
=====================
@@ -12,16 +18,39 @@ such as:
- *l10n_be_intrastat_product*:
the module for the Intrastat Declaration for Belgium.
These country-specific modules can be found in the OCA localization for those countries.
Installation
============
WARNING:
This module conflicts with the module *report_intrastat* from the official addons.
If you have already installed the module *report_intrastat*,
you should uninstall it first before installing this module.
Usage
=====
To create H.S. codes, go to the menu *Sales > Configuration > Product Categories and Attributes > H.S. Codes*.
Then you will be able to set the H.S. code on an product (under the *Information* tab) or on a product category. On the product form, you will also be able to set the *Country of Origin* of a product (for example, if the product is *made in China*, select *China* as *Country of Origin*).
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/91/8.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-financial-reporting/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/
account-financial-reporting/issues/new?body=module:%20
intrastat_base%0Aversion:%20
8.0.1.2%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
@@ -29,16 +58,18 @@ Contributors
------------
* Alexis de Lattre, Akretion <alexis.delattre@akretion.com>
* Luc De Meyer, Noviat <info@noviat.com>
Maintainer
----------
.. image:: http://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: http://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.
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 http://odoo-community.org.

View File

@@ -20,8 +20,4 @@
#
##############################################################################
from . import country
from . import product
from . import tax
from . import company
from . import intrastat_common
from . import models

View File

@@ -22,7 +22,7 @@
{
'name': 'Intrastat Reporting Base',
'version': '1.1',
'version': '1.2',
'category': 'Intrastat',
'license': 'AGPL-3',
'summary': 'Base module for Intrastat reporting',
@@ -31,14 +31,16 @@
'depends': ['base_vat'],
'conflicts': ['report_intrastat'],
'data': [
'country_data.xml',
'product_view.xml',
'partner_view.xml',
'country_view.xml',
'tax_view.xml',
'company_view.xml',
'intrastat_view.xml',
'data/country_data.xml',
'views/product_template.xml',
'views/res_partner.xml',
'views/res_country.xml',
'views/account_tax.xml',
'views/res_company.xml',
'views/intrastat.xml',
],
'demo': [
'demo/intrastat_demo.xml',
],
'demo': ['intrastat_demo.xml'],
'installable': True,
}

View File

@@ -0,0 +1,27 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Report intrastat base module for Odoo
# Copyright (C) 2011-2014 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.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_country
from . import product_template
from . import account_tax
from . import res_company
from . import intrastat_common

View File

@@ -27,16 +27,6 @@ from openerp.exceptions import ValidationError
class ResCompany(models.Model):
_inherit = "res.company"
@api.one
@api.depends(
'intrastat_remind_user_ids', 'intrastat_remind_user_ids.email')
def _compute_intrastat_email_list(self):
emails = []
for user in self.intrastat_remind_user_ids:
if user.email:
emails.append(user.email)
self.intrastat_email_list = ','.join(emails)
intrastat_remind_user_ids = fields.Many2many(
'res.users', column1='company_id', column2='user_id',
string="Users Receiving the Intrastat Reminder",
@@ -46,6 +36,16 @@ class ResCompany(models.Model):
compute='_compute_intrastat_email_list',
string='List of emails of Users Receiving the Intrastat Reminder')
@api.one
@api.depends(
'intrastat_remind_user_ids', 'intrastat_remind_user_ids.email')
def _compute_intrastat_email_list(self):
emails = []
for user in self.intrastat_remind_user_ids:
if user.email:
emails.append(user.email)
self.intrastat_email_list = ','.join(emails)
@api.one
@api.constrains('intrastat_remind_user_ids')
def _check_intrastat_remind_users(self):

View File

@@ -17,7 +17,7 @@
parent="account.menu_finance_configuration" sequence="50"/>
<record id="intrastat_result_view" model="ir.ui.view">
<record id="intrastat_result_view_form" model="ir.ui.view">
<field name="name">intrastat.result_view_form</field>
<field name="model">intrastat.result.view</field>
<field name="arch" type="xml">

View File

@@ -32,7 +32,7 @@
</record>
<!-- there is no native search view, so I can't inherit -->
<record id="view_country_search" model="ir.ui.view">
<record id="res_country_view_search" model="ir.ui.view">
<field name="name">intrastat.base.country.search</field>
<field name="model">res.country</field>
<field name="arch" type="xml">

View File

@@ -1,3 +1,8 @@
.. 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
========================
Intrastat Product Module
========================
@@ -17,10 +22,74 @@ Installation
============
WARNING:
This module conflicts with the module *report_intrastat* from the official addons.
If you have already installed the module *report_intrastat*,
you should uninstall it before installing this module.
Usage
=====
This module is used in combination with the country-specific
localization module(s).
Coding guidelines for localization module:
------------------------------------------
We recommend to start by copying an existing module, e.g. l10n_be_intrastat_product
and adapt the code for the specific needs of your country.
* Declaration Object
Create a new class as follows:
.. code-block:: python
class L10nCcIntrastatProductDeclaration(models.Model):
_name = 'l10n.cc.intrastat.product.declaration'
_description = "Intrastat Product Declaration for YourCountry"
_inherit = ['intrastat.product.declaration', 'mail.thread']
whereby cc = your country code
* Computation & Declaration Lines
Create also new objects inheriting from the Computation and Declaration Line Objects
so that you can add methods or customise the methods from the base modules (make a PR when
the customization or new method is required for multiple countries).
Adapt also the parent_id fields of the newly created objects
(cf. l10n_be_intrastat_product as example).
* XML Files: Menu, Action, Views
Cf. l10n_be_istrastat_product as example, replace "be" by your Country Code.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/91/8.0
Known issues / Roadmap
======================
Work is in progress to migrate the existing l10n_fr_intrastat_product module
to this new reporting framework, cf. Alexis de Lattre, Akretion <alexis.delattre@akretion.com>.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-financial-reporting/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/
account-financial-reporting/issues/new?body=module:%20
intrastat_product%0Aversion:%20
8.0.1.4%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
@@ -30,15 +99,18 @@ Contributors
* Alexis de Lattre, Akretion <alexis.delattre@akretion.com>
* Luc De Meyer, Noviat <info@noviat.com>
Maintainer
----------
.. image:: http://odoo-community.org/logo.png
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: http://odoo-community.org
: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.
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 http://odoo-community.org.

View File

@@ -1,7 +1,3 @@
# -*- encoding: utf-8 -*-
from . import res_company
from . import intrastat
from . import intrastat_declaration
from . import stock
from . import account_invoice
from . import models

View File

@@ -3,7 +3,7 @@
#
# Intrastat Product module for Odoo
# Copyright (C) 2011-2015 Akretion (http://www.akretion.com)
# Copyright (C) 2015 Noviat (http://www.noviat.com)
# Copyright (C) 2009-2015 Noviat (http://www.noviat.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.com>
#
@@ -24,7 +24,7 @@
{
'name': 'Intrastat Product',
'version': '1.3',
'version': '1.4',
'category': 'Intrastat',
'license': 'AGPL-3',
'summary': 'Base module for Intrastat Product',
@@ -36,16 +36,19 @@
],
'conflicts': ['report_intrastat'],
'data': [
'intrastat_view.xml',
'intrastat_declaration_view.xml',
'res_company_view.xml',
'account_invoice_view.xml',
'stock_view.xml',
'views/hs_code.xml',
'views/intrastat_unit.xml',
'views/intrastat_transaction.xml',
'views/intrastat_transport_mode.xml',
'views/intrastat_product_declaration.xml',
'views/res_company.xml',
'views/account_invoice.xml',
'views/stock_picking.xml',
'security/intrastat_security.xml',
'security/ir.model.access.csv',
'data/intrastat_transport_mode.xml',
'data/intrastat_unit.xml',
],
'demo': ['intrastat_demo.xml'],
'demo': ['demo/intrastat_demo.xml'],
'installable': True,
}

View File

@@ -1,119 +0,0 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Intrastat Product module for Odoo
# Copyright (C) 2011-2015 Akretion (http://www.akretion.com)
# Copyright (C) 2015 Noviat (http://www.noviat.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.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, api, _
from openerp.exceptions import ValidationError
class IntrastatUnit(models.Model):
_name = 'intrastat.unit'
_description = 'Intrastat Supplementary Units'
name = fields.Char(
string='Name', required=True)
description = fields.Char(
string='Description', required=True)
uom_id = fields.Many2one(
'product.uom', string='Regular UoM',
help="Select the regular Unit of Measure of Odoo that corresponds "
"to this Intrastat Supplementary Unit.")
active = fields.Boolean(
string='Active', default=True)
class HSCode(models.Model):
_inherit = "hs.code"
intrastat_unit_id = fields.Many2one(
'intrastat.unit', string='Intrastat Supplementary Unit')
@api.constrains('local_code')
def _hs_code(self):
if self.company_id.country_id.intrastat:
if not self.local_code.isdigit():
raise ValidationError(
_("Intrastat Codes should only contain digits. "
"This is not the case for code '%s'.")
% self.local_code)
if len(self.local_code) != 8:
raise ValidationError(
_("Intrastat Codes should "
"contain 8 digits. This is not the case for "
"Intrastat Code '%s' which has %d digits.")
% (self.local_code, len(self.local_code)))
class IntrastatTransaction(models.Model):
_name = 'intrastat.transaction'
_description = "Intrastat Transaction"
_order = 'code'
_rec_name = 'display_name'
@api.one
@api.depends('code', 'description')
def _compute_display_name(self):
display_name = self.code
if self.description:
display_name += ' ' + self.description
self.display_name = len(display_name) > 55 \
and display_name[:55] + '...' \
or display_name
code = fields.Char(string='Code', required=True)
description = fields.Text(string='Description')
display_name = fields.Char(
compute='_compute_display_name', string="Display Name", readonly=True)
company_id = fields.Many2one(
'res.company', string='Company',
default=lambda self: self.env['res.company']._company_default_get(
'intrastat.transaction'))
_sql_constraints = [(
'intrastat_transaction_code_unique',
'UNIQUE(code, company_id)',
'Code must be unique.')]
class IntrastatTransportMode(models.Model):
_name = 'intrastat.transport_mode'
_description = "Intrastat Transport Mode"
_rec_name = 'display_name'
_order = 'code'
@api.one
@api.depends('name', 'code')
def _display_name(self):
self.display_name = '%s. %s' % (self.code, self.name)
display_name = fields.Char(
string='Display Name', compute='_display_name', store=True,
readonly=True)
code = fields.Char(string='Code', required=True)
name = fields.Char(string='Name', required=True, translate=True)
description = fields.Char(string='Description', translate=True)
_sql_constraints = [(
'intrastat_transport_code_unique',
'UNIQUE(code)',
'Code must be unique.')]

View File

@@ -1,203 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2010-2015 Akretion (http://www.akretion.com/)
Copyright (C) 2015 Noviat (http://www.noviat.com/)
@author Alexis de Lattre <alexis.delattre@akretion.com>
@author Luc De Meyer <luc.demeyer@noviat.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<!-- Add the H.S. code menu under the Intrastat Config menu -->
<menuitem id="intrastat_code_menu"
action="product_harmonized_system.hs_code_action"
parent="intrastat_base.menu_intrastat_config_root"
sequence="10"/>
<!-- Inherit tree view of H.S. code -->
<record id="hs_code_tree" model="ir.ui.view">
<field name="name">intrastat.hs.code.tree</field>
<field name="model">hs.code</field>
<field name="inherit_id" ref="product_harmonized_system.hs_code_tree"/>
<field name="arch" type="xml">
<field name="local_code" position="after">
<field name="intrastat_unit_id"/>
</field>
</field>
</record>
<!-- Inherit form view for H.S. code -->
<record id="hs_code_form" model="ir.ui.view">
<field name="name">intrastat.hs.code.form</field>
<field name="model">hs.code</field>
<field name="inherit_id" ref="product_harmonized_system.hs_code_form"/>
<field name="arch" type="xml">
<field name="local_code" position="after">
<field name="intrastat_unit_id"/>
</field>
</field>
</record>
<!-- Intrastat Supplementary Unit -->
<record id="intrastat_unit_form" model="ir.ui.view">
<field name="name">intrastat.unit.form</field>
<field name="model">intrastat.unit</field>
<field name="arch" type="xml">
<form string="Intrastat Supplementary Unit">
<group>
<field name="name"/>
<field name="uom_id" required="1"/>
<field name="description"/>
<field name="active"/>
</group>
</form>
</field>
</record>
<record id="intrastat_unit_tree" model="ir.ui.view">
<field name="name">intrastat.unit.tree</field>
<field name="model">intrastat.unit</field>
<field name="arch" type="xml">
<tree string="Intrastat Supplementary Units">
<field name="name"/>
<field name="uom_id"/>
<field name="description"/>
</tree>
</field>
</record>
<record id="intrastat_unit_search" model="ir.ui.view">
<field name="name">intrastat.unit.search</field>
<field name="model">intrastat.unit</field>
<field name="arch" type="xml">
<search string="Search Intrastat Supplementary Units">
<field name="name"
filter_domain="['|', ('name', 'ilike', self), ('description', 'ilike', self)]"/>
<group string="Group By" name="groupby">
<filter name="uom_groupby" string="Regular UoM"
context="{'group_by': 'uom_id'}"/>
</group>
</search>
</field>
</record>
<record id="intrastat_unit_action" model="ir.actions.act_window">
<field name="name">Supplementary Units</field>
<field name="res_model">intrastat.unit</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="intrastat_unit_menu"
action="intrastat_unit_action"
parent="intrastat_base.menu_intrastat_config_root"
sequence="40"/>
<!-- Intrastat Transaction Type -->
<record id="intrastat_transaction_form" model="ir.ui.view">
<field name="name">intrastat.transaction_form</field>
<field name="model">intrastat.transaction</field>
<field name="arch" type="xml">
<form string="Intrastat Transaction Type">
<group>
<field name="code"/>
<field name="description"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
</form>
</field>
</record>
<record id="intrastat_transaction_tree" model="ir.ui.view">
<field name="name">intrastat.transaction_tree</field>
<field name="model">intrastat.transaction</field>
<field name="arch" type="xml">
<tree string="Intrastat Transaction Types">
<field name="code"/>
<field name="description"/>
<field name="company_id" groups="base.group_multi_company"/>
</tree>
</field>
</record>
<record id="intrastat_transaction_mode_search" model="ir.ui.view">
<field name="name">intrastat.transaction.mode.search</field>
<field name="model">intrastat.transaction</field>
<field name="arch" type="xml">
<search string="Search Intrastat Transaction Types">
<field name="description" string="Code or Description"
filter_domain="['|', ('code', 'ilike', self), ('description', 'ilike', self)]"/>
<group string="Group By" name="groupby">
<filter name="company_groupby" string="Company"
context="{'group_by': 'company_id'}"/>
</group>
</search>
</field>
</record>
<record id="intrastat_transaction_action" model="ir.actions.act_window">
<field name="name">Transaction Types</field>
<field name="res_model">intrastat.transaction</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="intrastat_transaction_menu"
action="intrastat_transaction_action"
parent="intrastat_base.menu_intrastat_config_root"
sequence="20"/>
<!-- Intrastat Transport Mode -->
<record id="intrastat_transport_mode_form" model="ir.ui.view">
<field name="name">intrastat.transport.mode.form</field>
<field name="model">intrastat.transport_mode</field>
<field name="arch" type="xml">
<form string="Intrastat Transport Mode">
<group>
<field name="name"/>
<field name="code"/>
<field name="description"/>
</group>
</form>
</field>
</record>
<record id="intrastat_transport_mode_tree" model="ir.ui.view">
<field name="name">intrastat.transport.mode.tree</field>
<field name="model">intrastat.transport_mode</field>
<field name="arch" type="xml">
<tree string="Intrastat Transportat Modes">
<field name="code"/>
<field name="name"/>
<field name="description"/>
</tree>
</field>
</record>
<record id="intrastat_transport_mode_search" model="ir.ui.view">
<field name="name">intrastat.transport.mode.search</field>
<field name="model">intrastat.transport_mode</field>
<field name="arch" type="xml">
<search string="Search Intrastat Transport Modes">
<field name="name" string="Name, Code or Description"
filter_domain="['|', '|', ('name', 'ilike', self), ('description', 'ilike', self), ('code', 'ilike', self)]"/>
</search>
</field>
</record>
<record id="intrastat_transport_action" model="ir.actions.act_window">
<field name="name">Transport Modes</field>
<field name="res_model">intrastat.transport_mode</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="intrastat_transport_menu"
action="intrastat_transport_action"
parent="intrastat_base.menu_intrastat_config_root"
sequence="30"/>
</data>
</openerp>

View File

@@ -0,0 +1,10 @@
# -*- encoding: utf-8 -*-
from . import res_company
from . import hs_code
from . import intrastat_transaction
from . import intrastat_unit
from . import intrastat_transport_mode
from . import intrastat_product_declaration
from . import stock_picking
from . import account_invoice

View File

@@ -1,10 +1,11 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012-2015 Noviat nv/sa (www.noviat.com)
# Copyright (C) 2015 Akretion (http://www.akretion.com)
# @author Luc de Meyer <info@noviat.com>
# Intrastat Product module for Odoo
# Copyright (C) 2011-2015 Akretion (http://www.akretion.com)
# Copyright (C) 2009-2015 Noviat (http://www.noviat.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.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
@@ -13,11 +14,11 @@
#
# 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
# 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/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@@ -27,14 +28,14 @@ from openerp import models, fields, api
class AccountInvoice(models.Model):
_inherit = 'account.invoice'
@api.model
def _default_intrastat_transaction(self):
""" placeholder for localisation modules """
return self.env['intrastat.transaction'].browse([])
incoterm_id = fields.Many2one(
'stock.incoterms', string='Incoterm',
help="International Commercial Terms are a series of predefined "
"commercial terms used in international transactions.")
intrastat_transaction_id = fields.Many2one(
'intrastat.transaction', string='Intrastat Transaction Type',
default=_default_intrastat_transaction, ondelete='restrict',
default=lambda self: self._default_intrastat_transaction(),
ondelete='restrict',
help="Intrastat nature of transaction")
intrastat_transport_id = fields.Many2one(
'intrastat.transport_mode', string='Intrastat Transport Mode',
@@ -49,6 +50,11 @@ class AccountInvoice(models.Model):
string='Intrastat Declaration',
related='company_id.intrastat', store=True, readonly=True)
@api.model
def _default_intrastat_transaction(self):
""" placeholder for localisation modules """
return self.env['intrastat.transaction'].browse([])
@api.multi
def onchange_partner_id(
self, type, partner_id, date_invoice=False,
@@ -82,7 +88,9 @@ class AccountInvoiceLine(models.Model):
if product:
product = self.env['product.product'].browse(product)
hs_code = product.get_hs_code_recursively()
hs_code = product.product_tmpl_id.get_hs_code_recursively()
if hs_code:
res['value']['hs_code_id'] = hs_code.id
else:
res['value']['hs_code_id'] = False
return res

View File

@@ -0,0 +1,48 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Intrastat Product module for Odoo
# Copyright (C) 2011-2015 Akretion (http://www.akretion.com)
# Copyright (C) 2009-2015 Noviat (http://www.noviat.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.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, api, _
from openerp.exceptions import ValidationError
class HSCode(models.Model):
_inherit = "hs.code"
intrastat_unit_id = fields.Many2one(
'intrastat.unit', string='Intrastat Supplementary Unit')
@api.constrains('local_code')
def _hs_code(self):
if self.company_id.country_id.intrastat:
if not self.local_code.isdigit():
raise ValidationError(
_("Intrastat Codes should only contain digits. "
"This is not the case for code '%s'.")
% self.local_code)
if len(self.local_code) != 8:
raise ValidationError(
_("Intrastat Codes should "
"contain 8 digits. This is not the case for "
"Intrastat Code '%s' which has %d digits.")
% (self.local_code, len(self.local_code)))

View File

@@ -3,7 +3,9 @@
#
# Intrastat Product module for Odoo
# Copyright (C) 2011-2015 Akretion (http://www.akretion.com)
# Copyright (C) 2011-2015 Noviat (http://www.noviat.com)
# Copyright (C) 2009-2015 Noviat (http://www.noviat.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.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
@@ -21,12 +23,11 @@
##############################################################################
from openerp import models, fields, api, _
from openerp.exceptions import Warning, RedirectWarning, ValidationError
from openerp.exceptions import RedirectWarning, ValidationError
import openerp.addons.decimal_precision as dp
from datetime import datetime, date
from dateutil.relativedelta import relativedelta
import logging
_logger = logging.getLogger(__name__)
@@ -105,6 +106,10 @@ class IntrastatProductDeclaration(models.Model):
'res.company', string='Company', readonly=True,
default=lambda self: self.env['res.company']._company_default_get(
'intrastat.product.declaration'))
company_country_code = fields.Char(
compute='_compute_company_country_code',
string='Company Country Code', readonly=True, store=True,
help="Used in views and methods of localization modules.")
year = fields.Integer(
string='Year', required=True,
default=_get_year)
@@ -186,12 +191,19 @@ class IntrastatProductDeclaration(models.Model):
_sql_constraints = [
('date_uniq',
'unique(year_month, company_id, type)',
'unique(year_month, company_id, type, revision)',
"A declaration of the same type already exists for this month !"
"\nYou should update the existing declaration "
"or change the revision number of this one."),
]
@api.one
@api.depends('company_id')
def _compute_company_country_code(self):
if self.company_id:
self.company_country_code = \
self.company_id.country_id.code.lower()
@api.one
@api.depends('year', 'month')
def _compute_year_month(self):
@@ -219,7 +231,7 @@ class IntrastatProductDeclaration(models.Model):
_('Go to company configuration screen'))
def _get_partner_country(self, inv_line):
country = inv_line.invoice_id.intrastat_country_id \
country = inv_line.invoice_id.src_dest_country_id \
or inv_line.invoice_id.partner_id.country_id
if not country.intrastat:
country = False
@@ -228,53 +240,13 @@ class IntrastatProductDeclaration(models.Model):
return country
def _get_intrastat_transaction(self, inv_line):
if inv_line.invoice_id.intrastat_transaction_id:
tr = inv_line.invoice_id.intrastat_transaction_id.code
else:
tr = self.env.ref(
'l10n_be_intrastat_advanced.intrastat_transaction_1')
return tr
def _get_region(self, inv_line):
"""
Logic copied from standard addons, l10n_be_intrastat module:
If purchase, comes from purchase order, linked to a location,
which is linked to the warehouse.
If sales, the sale order is linked to the warehouse.
If sales, from a delivery order, linked to a location,
which is linked to the warehouse.
If none found, get the company one.
"""
region = False
if inv_line.invoice_id.type in ('in_invoice', 'in_refund'):
po_lines = self.env['purchase.order.line'].search(
[('invoice_lines', 'in', inv_line.id)])
if po_lines:
po = po_lines.order_id
region = self.env['stock.warehouse'].get_region_from_location(
po.location_id)
elif inv_line.invoice_id.type in ('out_invoice', 'out_refund'):
so_lines = self.env['sale.order.line'].search(
[('invoice_lines', 'in', inv_line.id)])
if so_lines:
so = so_lines.order_id
region = so.warehouse_id.region_id
if not region:
if self.company_id.intrastat_region_id:
region = self.company_id.intrastat_region_id
else:
msg = _(
"The Intrastat Region of the Company is not set, "
"please configure it first.")
self._company_warning(msg)
return region
return inv_line.invoice_id.intrastat_transaction_id
def _get_weight_and_supplunits(self, inv_line):
line_qty = inv_line.quantity
product = inv_line.product_id
invoice = inv_line.invoice_id
intrastat_unit_id = inv_line.intrastat_id.intrastat_unit_id
intrastat_unit_id = inv_line.hs_code_id.intrastat_unit_id
source_uom = inv_line.uos_id
weight_uom_categ = self._uom_refs['weight_uom_categ']
kg_uom = self._uom_refs['kg_uom']
@@ -303,10 +275,10 @@ class IntrastatProductDeclaration(models.Model):
"Please correct the Intrastat Supplementary Unit "
"settingsand regenerate the lines or adjust the lines "
"with Intrastat Code '%s' manually"
) % intrastat_code
) % inv_line.hs_code_id.local_code
self._note += note
return weight, suppl_unit_qty
if target_uom.categ_id == source_uom.category_id:
if target_uom.category_id == source_uom.category_id:
suppl_unit_qty = self.env['product.uom']._compute_qty_obj(
source_uom, line_qty, target_uom)
else:
@@ -371,7 +343,7 @@ class IntrastatProductDeclaration(models.Model):
return amount
def _get_transport(self, inv_line):
transport = inv_line.invoice.transport_mode_id \
transport = inv_line.invoice_id.intrastat_transport_id \
or self.company_id.intrastat_transport_id
if not transport:
msg = _(
@@ -382,8 +354,8 @@ class IntrastatProductDeclaration(models.Model):
return transport
def _get_incoterm(self, inv_line):
incoterm = inv_line.invoice.incoterm_id \
or self.company_id.incoterm_id
incoterm = inv_line.invoice_id.incoterm_id \
or self.company_id.intrastat_incoterm_id
if not incoterm:
msg = _(
"The default Incoterm "
@@ -392,9 +364,13 @@ class IntrastatProductDeclaration(models.Model):
self._company_warning(msg)
return incoterm
def _update_computation_line_vals(self, inv_line, line_vals):
""" placeholder for localization modules """
pass
def _gather_invoices(self):
decl_lines = []
lines = []
start_date = date(self.year, self.month, 1)
end_date = start_date + relativedelta(day=1, months=+1, days=-1)
@@ -416,7 +392,7 @@ class IntrastatProductDeclaration(models.Model):
for inv_line in invoice.invoice_line:
intrastat = inv_line.intrastat_id
intrastat = inv_line.hs_code_id
if not intrastat:
continue
if not inv_line.quantity:
@@ -429,8 +405,6 @@ class IntrastatProductDeclaration(models.Model):
intrastat_transaction = \
self._get_intrastat_transaction(inv_line)
region = self._get_region(inv_line)
weight, suppl_unit_qty = self._get_weight_and_supplunits(
inv_line)
@@ -439,29 +413,27 @@ class IntrastatProductDeclaration(models.Model):
line_vals = {
'parent_id': self.id,
'invoice_line_id': inv_line.id,
'partner_country_id': partner_country.id,
'src_dest_country_id': partner_country.id,
'product_id': inv_line.product_id.id,
'intrastat_code_id': intrastat.id,
'hs_code_id': intrastat.id,
'weight': weight,
'suppl_unit_qty': suppl_unit_qty,
'amount_company_currency': amount_company_currency,
'transaction_id': intrastat_transaction.id,
'region_id': region.id,
'extended': self._extended,
}
# extended declaration
if self._extended:
transport = self._get_transport(inv_line)
incoterm = self._get_incoterm(inv_line)
line_vals.update({
'transport_id': transport.id,
'incoterm_id': incoterm.id,
})
decl_lines.append((0, 0, line_vals))
self._update_computation_line_vals(inv_line, line_vals)
return decl_lines
lines.append((line_vals))
return lines
@api.multi
def action_gather(self):
@@ -482,27 +454,23 @@ class IntrastatProductDeclaration(models.Model):
else:
self._extended = False
decl_lines_init = [(6, 0, [])]
decl_lines = decl_lines_init[:]
self.computation_line_ids.unlink()
lines = self._gather_invoices()
decl_lines += self._gather_invoices()
if decl_lines == decl_lines_init:
if not lines:
self.action = 'nihil'
note = "\n" + \
_("No records found for the selected period !") + '\n' + \
_("The Declaration Action has been set to 'nihil'.")
self._note += note
# To DO: add check on tax cases 46, 48, 84, 86
self.write({'intrastat_line_ids': decl_lines})
else:
self.write({'computation_line_ids': [(0, 0, x) for x in lines]})
if self._note:
note_header = '\n\n>>> ' + str(date.today()) + '\n'
self.note = (self.note or '') + note_header + self._note
self.note = note_header + self._note + (self.note or '')
result_view = self.env.ref(
'l10n_be_intrastat_advanced.intrastat_result_view')
'intrastat_base.intrastat_result_view_form')
return {
'name': _("Generate lines from invoices: results"),
'view_type': 'form',
@@ -520,7 +488,7 @@ class IntrastatProductDeclaration(models.Model):
def group_line_hashcode(self, computation_line):
hashcode = "%s-%s-%s-%s-%s" % (
computation_line.src_dest_country_id.id or False,
computation_line.hs_code or False,
computation_line.hs_code_id.id or False,
computation_line.intrastat_unit_id.id or False,
computation_line.transaction_id.id or False,
computation_line.transport_id.id or False
@@ -542,13 +510,22 @@ class IntrastatProductDeclaration(models.Model):
dl_group[hashcode].append(cl)
else:
dl_group[hashcode] = [cl]
ipdlo = self.pool['intrastat.product.declaration.line']
ipdl = self.declaration_line_ids
for cl_lines in dl_group.values():
vals = ipdlo._prepare_declaration_line(cl_lines)
declaration_line = ipdlo.create(vals)
cl_lines.write({'declaration_line_id': declaration_line.id})
vals = ipdl._prepare_declaration_line(cl_lines)
declaration_line = ipdl.create(vals)
for cl in cl_lines:
cl.write({'declaration_line_id': declaration_line.id})
return True
@api.multi
def done(self):
self.write({'state': 'done'})
@api.multi
def back2draft(self):
self.write({'state': 'draft'})
class IntrastatProductComputationLine(models.Model):
_name = 'intrastat.product.computation.line'
@@ -613,6 +590,8 @@ class IntrastatProductComputationLine(models.Model):
'intrastat.transaction',
string='Intrastat Transaction')
# extended declaration
incoterm_id = fields.Many2one(
'stock.incoterms', string='Incoterm')
transport_id = fields.Many2one(
'intrastat.transport_mode',
string='Transport Mode')
@@ -687,16 +666,19 @@ class IntrastatProductDeclarationLine(models.Model):
'intrastat.transaction',
string='Intrastat Transaction')
# extended declaration
# extended declaration
incoterm_id = fields.Many2one(
'stock.incoterms', string='Incoterm')
transport_id = fields.Many2one(
'intrastat.transport_mode',
string='Transport Mode')
@api.model
def _prepare_grouped_fields(computation_line, fields_to_sum):
def _prepare_grouped_fields(self, computation_line, fields_to_sum):
vals = {
'src_dest_country_id': computation_line.src_dest_country_id.id,
'intrastat_unit_id': computation_line.intrastat_unit_id.id,
'hs_code': computation_line.hs_code_id.local_code,
'hs_code_id': computation_line.hs_code_id.id,
'transaction_id': computation_line.transaction_id.id,
'transport_id': computation_line.transport_id.id,
'parent_id': computation_line.parent_id.id,
@@ -705,7 +687,7 @@ class IntrastatProductDeclarationLine(models.Model):
vals[field] = 0.0
return vals
def _fields_to_sum():
def _fields_to_sum(self):
fields_to_sum = [
'weight',
'suppl_unit_qty',

View File

@@ -0,0 +1,56 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Intrastat Product module for Odoo
# Copyright (C) 2011-2015 Akretion (http://www.akretion.com)
# Copyright (C) 2009-2015 Noviat (http://www.noviat.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.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, api
class IntrastatTransaction(models.Model):
_name = 'intrastat.transaction'
_description = "Intrastat Transaction"
_order = 'code'
_rec_name = 'display_name'
code = fields.Char(string='Code', required=True)
description = fields.Text(string='Description')
display_name = fields.Char(
compute='_compute_display_name', string="Display Name", readonly=True)
company_id = fields.Many2one(
'res.company', string='Company',
default=lambda self: self.env['res.company']._company_default_get(
'intrastat.transaction'))
@api.one
@api.depends('code', 'description')
def _compute_display_name(self):
display_name = self.code
if self.description:
display_name += ' ' + self.description
self.display_name = len(display_name) > 55 \
and display_name[:55] + '...' \
or display_name
_sql_constraints = [(
'intrastat_transaction_code_unique',
'UNIQUE(code, company_id)',
'Code must be unique.')]

View File

@@ -0,0 +1,49 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Intrastat Product module for Odoo
# Copyright (C) 2011-2015 Akretion (http://www.akretion.com)
# Copyright (C) 2009-2015 Noviat (http://www.noviat.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.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, api
class IntrastatTransportMode(models.Model):
_name = 'intrastat.transport_mode'
_description = "Intrastat Transport Mode"
_rec_name = 'display_name'
_order = 'code'
display_name = fields.Char(
string='Display Name', compute='_display_name', store=True,
readonly=True)
code = fields.Char(string='Code', required=True)
name = fields.Char(string='Name', required=True, translate=True)
description = fields.Char(string='Description', translate=True)
@api.one
@api.depends('name', 'code')
def _display_name(self):
self.display_name = '%s. %s' % (self.code, self.name)
_sql_constraints = [(
'intrastat_transport_code_unique',
'UNIQUE(code)',
'Code must be unique.')]

View File

@@ -0,0 +1,41 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Intrastat Product module for Odoo
# Copyright (C) 2011-2015 Akretion (http://www.akretion.com)
# Copyright (C) 2009-2015 Noviat (http://www.noviat.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.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 IntrastatUnit(models.Model):
_name = 'intrastat.unit'
_description = 'Intrastat Supplementary Units'
name = fields.Char(
string='Name', required=True)
description = fields.Char(
string='Description', required=True)
uom_id = fields.Many2one(
'product.uom', string='Regular UoM',
help="Select the regular Unit of Measure of Odoo that corresponds "
"to this Intrastat Supplementary Unit.")
active = fields.Boolean(
string='Active', default=True)

View File

@@ -1,10 +1,11 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012-2015 Noviat nv/sa (www.noviat.com)
# Copyright (C) 2015 Akretion (http://www.akretion.com)
# @author Luc de Meyer <info@noviat.com>
# Intrastat Product module for Odoo
# Copyright (C) 2011-2015 Akretion (http://www.akretion.com)
# Copyright (C) 2009-2015 Noviat (http://www.noviat.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.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
@@ -13,11 +14,11 @@
#
# 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
# 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/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@@ -27,6 +28,25 @@ from openerp import models, fields, api
class ResCompany(models.Model):
_inherit = 'res.company'
intrastat_incoterm_id = fields.Many2one(
'stock.incoterms',
string='Default incoterm for Intrastat',
help="International Commercial Terms are a series of "
"predefined commercial terms used in international "
"transactions.")
intrastat_arrivals = fields.Selection(
'_intrastat_arrivals', string='Arrivals',
default='extended', required=True)
intrastat_dispatches = fields.Selection(
'_intrastat_arrivals', string='Dispatches',
default='extended', required=True)
intrastat_transport_id = fields.Many2one(
'intrastat.transport_mode',
string='Default Transport Mode', ondelete='restrict')
intrastat = fields.Char(
string='Intrastat Declaration', store=True, readonly=True,
compute='_compute_intrastat')
@api.model
def _intrastat_arrivals(self):
return [
@@ -52,16 +72,3 @@ class ResCompany(models.Model):
self.intrastat = 'extended'
else:
self.intrastat = 'standard'
intrastat_arrivals = fields.Selection(
'_intrastat_arrivals', string='Arrivals',
default='extended', required=True)
intrastat_dispatches = fields.Selection(
'_intrastat_arrivals', string='Dispatches',
default='extended', required=True)
intrastat_transport_id = fields.Many2one(
'intrastat.transport_mode',
string='Default Transport Mode', ondelete='restrict')
intrastat = fields.Char(
string='Intrastat Declaration', store=True, readonly=True,
compute='_compute_intrastat')

View File

@@ -1,8 +1,11 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2010-2015 Akretion (http://www.akretion.com)
# Intrastat Product module for Odoo
# Copyright (C) 2011-2015 Akretion (http://www.akretion.com)
# Copyright (C) 2009-2015 Noviat (http://www.noviat.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.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

View File

@@ -7,6 +7,10 @@
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='date_due']" position="after">
<field name="incoterm_id"
attrs="{'invisible': [('intrastat', '!=', 'extended')]}"/>
</xpath>
<xpath expr="//field[@name='move_id']" position="after">
<field name="intrastat_transaction_id"/>
<field name="intrastat" invisible="1"/>
@@ -26,6 +30,10 @@
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.invoice_supplier_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='payment_term']" position="after">
<field name="incoterm_id"
attrs="{'invisible': [('intrastat', '!=', 'extended')]}"/>
</xpath>
<xpath expr="//field[@name='period_id']" position="after">
<field name="intrastat_transaction_id"/>
<field name="intrastat" invisible="1"/>

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2010-2015 Akretion (http://www.akretion.com/)
Copyright (C) 2015 Noviat (http://www.noviat.com/)
@author Alexis de Lattre <alexis.delattre@akretion.com>
@author Luc De Meyer <luc.demeyer@noviat.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<!-- Add the H.S. code menu under the Intrastat Config menu -->
<menuitem id="intrastat_code_menu"
action="product_harmonized_system.hs_code_action"
parent="intrastat_base.menu_intrastat_config_root"
sequence="10"/>
<!-- Inherit tree view of H.S. code -->
<record id="hs_code_tree" model="ir.ui.view">
<field name="name">intrastat.hs.code.tree</field>
<field name="model">hs.code</field>
<field name="inherit_id" ref="product_harmonized_system.hs_code_view_tree"/>
<field name="arch" type="xml">
<field name="local_code" position="after">
<field name="intrastat_unit_id"/>
</field>
</field>
</record>
<!-- Inherit form view for H.S. code -->
<record id="hs_code_form" model="ir.ui.view">
<field name="name">intrastat.hs.code.form</field>
<field name="model">hs.code</field>
<field name="inherit_id" ref="product_harmonized_system.hs_code_view_form"/>
<field name="arch" type="xml">
<field name="local_code" position="after">
<field name="intrastat_unit_id"/>
</field>
</field>
</record>
</data>
</openerp>

View File

@@ -2,7 +2,7 @@
<openerp>
<data>
<record id="intrastat_product_declaration_form" model="ir.ui.view">
<record id="intrastat_product_declaration_view_form" model="ir.ui.view">
<field name="name">intrastat.product.declaration.form</field>
<field name="model">intrastat.product.declaration</field>
<field name="arch" type="xml">
@@ -40,6 +40,7 @@
<field name="num_decl_lines"/>
<field name="total_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
<field name="company_country_code" invisible="1"/>
<field name="currency_id" invisible="1"/>
</group>
</group>
@@ -74,6 +75,7 @@
<field name="reporting_level" invisible="1"/>
<field name="transport_id"
attrs="{'required': [('reporting_level', '=', 'extended')], 'invisible': [('reporting_level', '!=', 'extended')]}"/>
<field name="incoterm_id" invisible="1"/>
</group>
</form>
</field>
@@ -91,6 +93,9 @@
<field name="suppl_unit_qty"/>
<field name="transaction_id"/>
<field name="reporting_level" invisible="1"/>
<field name="transport_id"
attrs="{'required': [('reporting_level', '=', 'extended')], 'invisible': [('reporting_level', '!=', 'extended')]}"/>
<field name="incoterm_id" invisible="1"/>
</tree>
</field>
</group>
@@ -117,8 +122,8 @@
<field name="description">Intrastat Product Declaration Validated</field>
</record>
<record id="intrastat_product_tree" model="ir.ui.view">
<field name="name">intrastat.product.tree</field>
<record id="intrastat_product_declaration_view_tree" model="ir.ui.view">
<field name="name">intrastat.product.declaration.tree</field>
<field name="model">intrastat.product.declaration</field>
<field name="arch" type="xml">
<tree string="Intrastat Product Declarations" colors="blue:state=='draft'">
@@ -133,8 +138,8 @@
</field>
</record>
<record id="intrastat_product_search" model="ir.ui.view">
<field name="name">intrastat.product.search</field>
<record id="intrastat_product_declaration_view_search" model="ir.ui.view">
<field name="name">intrastat.product.declaration.search</field>
<field name="model">intrastat.product.declaration</field>
<field name="arch" type="xml">
<search string="Search Intrastat Product Declarations">
@@ -150,8 +155,8 @@
</field>
</record>
<record id="intrastat_product_graph" model="ir.ui.view">
<field name="name">intrastat.product.graph</field>
<record id="intrastat_product_declaration_view_graph" model="ir.ui.view">
<field name="name">intrastat.product.declaration.graph</field>
<field name="model">intrastat.product.declaration</field>
<field name="arch" type="xml">
<graph string="Intrastat Product" type="bar">
@@ -162,16 +167,7 @@
</field>
</record>
<record id="intrastat_product_tree_action" model="ir.actions.act_window">
<field name="name">Intrastat Product Declaration</field>
<field name="res_model">intrastat.product.declaration</field>
<field name="view_mode">tree,form,graph</field>
</record>
<!-- TO BE REMOVED -->
<menuitem id="intrastat_product_menu"
parent="intrastat_base.menu_intrastat_base_root"
action="intrastat_product_tree_action"/>
<!-- No menuitem nor action since these are provided by the localization modules -->
</data>
</openerp>

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2010-2015 Akretion (http://www.akretion.com/)
Copyright (C) 2015 Noviat (http://www.noviat.com/)
@author Alexis de Lattre <alexis.delattre@akretion.com>
@author Luc De Meyer <luc.demeyer@noviat.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<!-- Intrastat Transaction Type -->
<record id="intrastat_transaction_form" model="ir.ui.view">
<field name="name">intrastat.transaction_form</field>
<field name="model">intrastat.transaction</field>
<field name="arch" type="xml">
<form string="Intrastat Transaction Type">
<group>
<field name="code"/>
<field name="description"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
</form>
</field>
</record>
<record id="intrastat_transaction_tree" model="ir.ui.view">
<field name="name">intrastat.transaction_tree</field>
<field name="model">intrastat.transaction</field>
<field name="arch" type="xml">
<tree string="Intrastat Transaction Types">
<field name="code"/>
<field name="description"/>
<field name="company_id" groups="base.group_multi_company"/>
</tree>
</field>
</record>
<record id="intrastat_transaction_mode_search" model="ir.ui.view">
<field name="name">intrastat.transaction.mode.search</field>
<field name="model">intrastat.transaction</field>
<field name="arch" type="xml">
<search string="Search Intrastat Transaction Types">
<field name="description" string="Code or Description"
filter_domain="['|', ('code', 'ilike', self), ('description', 'ilike', self)]"/>
<group string="Group By" name="groupby">
<filter name="company_groupby" string="Company"
context="{'group_by': 'company_id'}"/>
</group>
</search>
</field>
</record>
<record id="intrastat_transaction_action" model="ir.actions.act_window">
<field name="name">Transaction Types</field>
<field name="res_model">intrastat.transaction</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="intrastat_transaction_menu"
action="intrastat_transaction_action"
parent="intrastat_base.menu_intrastat_config_root"
sequence="20"/>
</data>
</openerp>

View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2010-2015 Akretion (http://www.akretion.com/)
Copyright (C) 2015 Noviat (http://www.noviat.com/)
@author Alexis de Lattre <alexis.delattre@akretion.com>
@author Luc De Meyer <luc.demeyer@noviat.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<!-- Intrastat Transport Mode -->
<record id="intrastat_transport_mode_form" model="ir.ui.view">
<field name="name">intrastat.transport.mode.form</field>
<field name="model">intrastat.transport_mode</field>
<field name="arch" type="xml">
<form string="Intrastat Transport Mode">
<group>
<field name="name"/>
<field name="code"/>
<field name="description"/>
</group>
</form>
</field>
</record>
<record id="intrastat_transport_mode_tree" model="ir.ui.view">
<field name="name">intrastat.transport.mode.tree</field>
<field name="model">intrastat.transport_mode</field>
<field name="arch" type="xml">
<tree string="Intrastat Transportat Modes">
<field name="code"/>
<field name="name"/>
<field name="description"/>
</tree>
</field>
</record>
<record id="intrastat_transport_mode_search" model="ir.ui.view">
<field name="name">intrastat.transport.mode.search</field>
<field name="model">intrastat.transport_mode</field>
<field name="arch" type="xml">
<search string="Search Intrastat Transport Modes">
<field name="name" string="Name, Code or Description"
filter_domain="['|', '|', ('name', 'ilike', self), ('description', 'ilike', self), ('code', 'ilike', self)]"/>
</search>
</field>
</record>
<record id="intrastat_transport_action" model="ir.actions.act_window">
<field name="name">Transport Modes</field>
<field name="res_model">intrastat.transport_mode</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="intrastat_transport_menu"
action="intrastat_transport_action"
parent="intrastat_base.menu_intrastat_config_root"
sequence="30"/>
</data>
</openerp>

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2010-2015 Akretion (http://www.akretion.com/)
Copyright (C) 2015 Noviat (http://www.noviat.com/)
@author Alexis de Lattre <alexis.delattre@akretion.com>
@author Luc De Meyer <luc.demeyer@noviat.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<!-- Intrastat Supplementary Unit -->
<record id="intrastat_unit_form" model="ir.ui.view">
<field name="name">intrastat.unit.form</field>
<field name="model">intrastat.unit</field>
<field name="arch" type="xml">
<form string="Intrastat Supplementary Unit">
<group>
<field name="name"/>
<field name="uom_id" required="1"/>
<field name="description"/>
<field name="active"/>
</group>
</form>
</field>
</record>
<record id="intrastat_unit_tree" model="ir.ui.view">
<field name="name">intrastat.unit.tree</field>
<field name="model">intrastat.unit</field>
<field name="arch" type="xml">
<tree string="Intrastat Supplementary Units">
<field name="name"/>
<field name="uom_id"/>
<field name="description"/>
</tree>
</field>
</record>
<record id="intrastat_unit_search" model="ir.ui.view">
<field name="name">intrastat.unit.search</field>
<field name="model">intrastat.unit</field>
<field name="arch" type="xml">
<search string="Search Intrastat Supplementary Units">
<field name="name"
filter_domain="['|', ('name', 'ilike', self), ('description', 'ilike', self)]"/>
<group string="Group By" name="groupby">
<filter name="uom_groupby" string="Regular UoM"
context="{'group_by': 'uom_id'}"/>
</group>
</search>
</field>
</record>
<record id="intrastat_unit_action" model="ir.actions.act_window">
<field name="name">Supplementary Units</field>
<field name="res_model">intrastat.unit</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="intrastat_unit_menu"
action="intrastat_unit_action"
parent="intrastat_base.menu_intrastat_config_root"
sequence="40"/>
</data>
</openerp>

View File

@@ -13,6 +13,8 @@
<field name="intrastat_dispatches"/>
<field name="intrastat_transport_id"
attrs="{'required': [('intrastat', '=', 'extended')], 'invisible': [('intrastat', '!=', 'extended')]}"/>
<field name="intrastat_incoterm_id"
attrs="{'required': [('intrastat', '=', 'extended')], 'invisible': [('intrastat', '!=', 'extended')]}"/>
</group>
</field>
</record>

View File

@@ -1,6 +1,9 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
============================================
Harmonized System Codes (and National Codes)
============================================
@@ -12,11 +15,13 @@ You will also be able to configure the country of origin of a product, which is
This module should be usefull for all companies that export physical goods abroad. This module is also used by the Intrastat modules for the European Union, cf the *intrastat_product* module.
Installation
============
This module is NOT compatible with the *report_intrastat* module from the official addons.
Usage
=====
@@ -24,15 +29,32 @@ To create H.S. codes, go to the menu *Sales > Configuration > Product Categories
Then you will be able to set the H.S. code on an product (under the *Information* tab) or on a product category. On the product form, you will also be able to set the *Country of Origin* of a product (for example, if the product is *made in China*, select *China* as *Country of Origin*).
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/91/8.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-financial-reporting/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/
account-financial-reporting/issues/new?body=module:%20
product_harmonized_system%0Aversion:%20
8.0.0.2%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
Author
-------
Contributors
------------
* Alexis de Lattre, Akretion <alexis.delattre@akretion.com>
* Luc De Meyer, Noviat <info@noviat.com>
Maintainer
----------
.. image:: http://odoo-community.org/logo.png

View File

@@ -1,4 +1,3 @@
# -*- encoding: utf-8 -*-
from . import hs
from . import product
from . import models

View File

@@ -2,7 +2,7 @@
##############################################################################
#
# Copyright (C) 2011-2015 Akretion (http://www.akretion.com)
# Copyright (C) 2015 Noviat (http://www.noviat.com)
# Copyright (C) 2009-2015 Noviat (http://www.noviat.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.com>
#
@@ -23,7 +23,7 @@
{
'name': 'Product Harmonized System Codes',
'version': '0.1',
'version': '0.2',
'category': 'Reporting',
'license': 'AGPL-3',
'summary': 'Base module for Product Import/Export reports',
@@ -31,11 +31,14 @@
'depends': ['product'],
'conflicts': ['report_intrastat'],
'data': [
'product_view.xml',
'hs_view.xml',
'security/product_hs_security.xml',
'security/ir.model.access.csv',
'views/hs_code.xml',
'views/product_category.xml',
'views/product_template.xml',
],
'demo': [
'demo/product_demo.xml',
],
'demo': ['product_demo.xml'],
'installable': True,
}

View File

@@ -0,0 +1,5 @@
# -*- encoding: utf-8 -*-
from . import hs_code
from . import product_category
from . import product_template

View File

@@ -2,7 +2,7 @@
##############################################################################
#
# Copyright (C) 2011-2015 Akretion (http://www.akretion.com)
# Copyright (C) 2015 Noviat (http://www.noviat.com)
# Copyright (C) 2009-2015 Noviat (http://www.noviat.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.com>
#
@@ -30,23 +30,8 @@ class HSCode(models.Model):
_order = "local_code"
_rec_name = "display_name"
@api.one
@api.depends('local_code')
def _get_hs_code(self):
self.hs_code = self.local_code and self.local_code[:6]
@api.one
@api.depends('local_code', 'description')
def _compute_display_name(self):
display_name = self.local_code
if self.description:
display_name += ' ' + self.description
self.display_name = len(display_name) > 55 \
and display_name[:55] + '...' \
or display_name
hs_code = fields.Char(
string='H.S. Code', compute='_get_hs_code', readonly=True,
string='H.S. Code', compute='_compute_hs_code', readonly=True,
help="Harmonized System code (6 digits). Full list is "
"available from the World Customs Organisation, see "
"http://www.wcoomd.org")
@@ -67,6 +52,21 @@ class HSCode(models.Model):
default=lambda self: self.env['res.company']._company_default_get(
'hs.code'))
@api.one
@api.depends('local_code')
def _compute_hs_code(self):
self.hs_code = self.local_code and self.local_code[:6]
@api.one
@api.depends('local_code', 'description')
def _compute_display_name(self):
display_name = self.local_code
if self.description:
display_name += ' ' + self.description
self.display_name = len(display_name) > 55 \
and display_name[:55] + '...' \
or display_name
_sql_constraints = [
('local_code_company_uniq', 'unique(local_code, company_id)',
'This code already exists for this company !'),

View File

@@ -0,0 +1,46 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2011-2015 Akretion (http://www.akretion.com)
# Copyright (C) 2009-2015 Noviat (http://www.noviat.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.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, api
class ProductCategory(models.Model):
_inherit = "product.category"
hs_code_id = fields.Many2one(
'hs.code', string='H.S. Code',
company_dependent=True, ondelete='restrict',
help="Harmonised System Code. If this code is not "
"set on the product itself, it will be read here, on the "
"related product category.")
@api.multi
def get_hs_code_recursively(self):
self.ensure_one()
if self.hs_code_id:
res = self.hs_code_id
elif self.parent_id:
res = self.parent_id.get_hs_code_recursively()
else:
res = None
return res

View File

@@ -2,7 +2,7 @@
##############################################################################
#
# Copyright (C) 2011-2015 Akretion (http://www.akretion.com)
# Copyright (C) 2015 Noviat (http://www.noviat.com)
# Copyright (C) 2009-2015 Noviat (http://www.noviat.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.com>
#
@@ -49,25 +49,3 @@ class ProductTemplate(models.Model):
else:
res = None
return res
class ProductCategory(models.Model):
_inherit = "product.category"
hs_code_id = fields.Many2one(
'hs.code', string='H.S. Code',
company_dependent=True, ondelete='restrict',
help="Harmonised System Code. If this code is not "
"set on the product itself, it will be read here, on the "
"related product category.")
@api.multi
def get_hs_code_recursively(self):
self.ensure_one()
if self.hs_code_id:
res = self.hs_code_id
elif self.parent_id:
res = self.parent_id.get_hs_code_recursively()
else:
res = None
return res

View File

@@ -10,7 +10,7 @@
<data>
<!-- Search view for H.S. code -->
<record id="hs_code_search" model="ir.ui.view">
<record id="hs_code_view_search" model="ir.ui.view">
<field name="name">hs.code.search</field>
<field name="model">hs.code</field>
<field name="arch" type="xml">
@@ -22,7 +22,7 @@
</record>
<!-- Tree view for H.S. code -->
<record id="hs_code_tree" model="ir.ui.view">
<record id="hs_code_view_tree" model="ir.ui.view">
<field name="name">hs.code.tree</field>
<field name="model">hs.code</field>
<field name="arch" type="xml">
@@ -36,7 +36,7 @@
</record>
<!-- Form view for H.S. code -->
<record id="hs_code_form" model="ir.ui.view">
<record id="hs_code_view_form" model="ir.ui.view">
<field name="name">hs.code.form</field>
<field name="model">hs.code</field>
<field name="arch" type="xml">

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2010-2014 Akretion (http://www.akretion.com/)
@author Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<!-- Product category form view -->
<record id="product_category_form_view" model="ir.ui.view">
<field name="name">hs_code.product.category.form</field>
<field name="model">product.category</field>
<field name="inherit_id" ref="product.product_category_form_view"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='parent']" position="inside">
<group name="hs_code" string="Import/Export Properties" colspan="2">
<field name="hs_code_id"/>
</group>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@@ -22,19 +22,5 @@
</field>
</record>
<!-- Product category form view -->
<record id="product_category_form_view" model="ir.ui.view">
<field name="name">hs_code.product.category.form</field>
<field name="model">product.category</field>
<field name="inherit_id" ref="product.product_category_form_view"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='parent']" position="inside">
<group name="hs_code" string="Import/Export Properties" colspan="2">
<field name="hs_code_id"/>
</group>
</xpath>
</field>
</record>
</data>
</openerp>