[IMP] intrastat_product: Add an Intrastat summary in the invoice report.

TT37168
This commit is contained in:
Víctor Martínez
2022-06-08 14:56:26 +02:00
parent 5b43621336
commit e9396ef0eb
12 changed files with 590 additions and 260 deletions

View File

@@ -145,6 +145,7 @@ Contributors
* Tecnativa <www.tecnativa.com>: * Tecnativa <www.tecnativa.com>:
* João Marques * João Marques
* Víctor Martínez
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

View File

@@ -32,9 +32,11 @@
"views/intrastat_transport_mode.xml", "views/intrastat_transport_mode.xml",
"views/intrastat_product_declaration.xml", "views/intrastat_product_declaration.xml",
"views/res_config_settings.xml", "views/res_config_settings.xml",
"views/res_partner_view.xml",
"views/account_move.xml", "views/account_move.xml",
"views/sale_order.xml", "views/sale_order.xml",
"views/stock_warehouse.xml", "views/stock_warehouse.xml",
"views/report_invoice.xml",
"wizards/intrastat_result_view.xml", "wizards/intrastat_result_view.xml",
"data/intrastat_transport_mode.xml", "data/intrastat_transport_mode.xml",
"data/intrastat_unit.xml", "data/intrastat_unit.xml",

File diff suppressed because it is too large Load Diff

View File

@@ -6,6 +6,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 14.0\n" "Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-08-16 06:43+0000\n"
"PO-Revision-Date: 2022-08-16 06:43+0000\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -302,6 +304,11 @@ msgstr ""
msgid "Config Settings" msgid "Config Settings"
msgstr "" msgstr ""
#. module: intrastat_product
#: model:ir.model,name:intrastat_product.model_res_partner
msgid "Contact"
msgstr ""
#. module: intrastat_product #. module: intrastat_product
#: code:addons/intrastat_product/models/intrastat_product_declaration.py:0 #: code:addons/intrastat_product/models/intrastat_product_declaration.py:0
#, python-format #, python-format
@@ -521,6 +528,7 @@ msgstr ""
#: model:ir.model.fields,field_description:intrastat_product.field_report_intrastat_product_product_declaration_xls__display_name #: model:ir.model.fields,field_description:intrastat_product.field_report_intrastat_product_product_declaration_xls__display_name
#: model:ir.model.fields,field_description:intrastat_product.field_res_company__display_name #: model:ir.model.fields,field_description:intrastat_product.field_res_company__display_name
#: model:ir.model.fields,field_description:intrastat_product.field_res_config_settings__display_name #: model:ir.model.fields,field_description:intrastat_product.field_res_config_settings__display_name
#: model:ir.model.fields,field_description:intrastat_product.field_res_partner__display_name
#: model:ir.model.fields,field_description:intrastat_product.field_sale_order__display_name #: model:ir.model.fields,field_description:intrastat_product.field_sale_order__display_name
#: model:ir.model.fields,field_description:intrastat_product.field_stock_location__display_name #: model:ir.model.fields,field_description:intrastat_product.field_stock_location__display_name
#: model:ir.model.fields,field_description:intrastat_product.field_stock_warehouse__display_name #: model:ir.model.fields,field_description:intrastat_product.field_stock_warehouse__display_name
@@ -639,6 +647,11 @@ msgstr ""
msgid "H.S. Codes" msgid "H.S. Codes"
msgstr "" msgstr ""
#. module: intrastat_product
#: model_terms:ir.ui.view,arch_db:intrastat_product.report_invoice_document_intrastat_product
msgid "HS Code"
msgstr ""
#. module: intrastat_product #. module: intrastat_product
#: model:ir.model.fields,field_description:intrastat_product.field_account_move__id #: model:ir.model.fields,field_description:intrastat_product.field_account_move__id
#: model:ir.model.fields,field_description:intrastat_product.field_account_move_intrastat_line__id #: model:ir.model.fields,field_description:intrastat_product.field_account_move_intrastat_line__id
@@ -655,6 +668,7 @@ msgstr ""
#: model:ir.model.fields,field_description:intrastat_product.field_report_intrastat_product_product_declaration_xls__id #: model:ir.model.fields,field_description:intrastat_product.field_report_intrastat_product_product_declaration_xls__id
#: model:ir.model.fields,field_description:intrastat_product.field_res_company__id #: model:ir.model.fields,field_description:intrastat_product.field_res_company__id
#: model:ir.model.fields,field_description:intrastat_product.field_res_config_settings__id #: model:ir.model.fields,field_description:intrastat_product.field_res_config_settings__id
#: model:ir.model.fields,field_description:intrastat_product.field_res_partner__id
#: model:ir.model.fields,field_description:intrastat_product.field_sale_order__id #: model:ir.model.fields,field_description:intrastat_product.field_sale_order__id
#: model:ir.model.fields,field_description:intrastat_product.field_stock_location__id #: model:ir.model.fields,field_description:intrastat_product.field_stock_location__id
#: model:ir.model.fields,field_description:intrastat_product.field_stock_warehouse__id #: model:ir.model.fields,field_description:intrastat_product.field_stock_warehouse__id
@@ -869,6 +883,11 @@ msgstr ""
msgid "Intrastat declaration details" msgid "Intrastat declaration details"
msgstr "" msgstr ""
#. module: intrastat_product
#: model_terms:ir.ui.view,arch_db:intrastat_product.report_invoice_document_intrastat_product
msgid "Intrastat information"
msgstr ""
#. module: intrastat_product #. module: intrastat_product
#: model:ir.model.fields,help:intrastat_product.field_account_bank_statement_line__intrastat_transaction_id #: model:ir.model.fields,help:intrastat_product.field_account_bank_statement_line__intrastat_transaction_id
#: model:ir.model.fields,help:intrastat_product.field_account_move__intrastat_transaction_id #: model:ir.model.fields,help:intrastat_product.field_account_move__intrastat_transaction_id
@@ -954,6 +973,7 @@ msgstr ""
#: model:ir.model.fields,field_description:intrastat_product.field_report_intrastat_product_product_declaration_xls____last_update #: model:ir.model.fields,field_description:intrastat_product.field_report_intrastat_product_product_declaration_xls____last_update
#: model:ir.model.fields,field_description:intrastat_product.field_res_company____last_update #: model:ir.model.fields,field_description:intrastat_product.field_res_company____last_update
#: model:ir.model.fields,field_description:intrastat_product.field_res_config_settings____last_update #: model:ir.model.fields,field_description:intrastat_product.field_res_config_settings____last_update
#: model:ir.model.fields,field_description:intrastat_product.field_res_partner____last_update
#: model:ir.model.fields,field_description:intrastat_product.field_sale_order____last_update #: model:ir.model.fields,field_description:intrastat_product.field_sale_order____last_update
#: model:ir.model.fields,field_description:intrastat_product.field_stock_location____last_update #: model:ir.model.fields,field_description:intrastat_product.field_stock_location____last_update
#: model:ir.model.fields,field_description:intrastat_product.field_stock_warehouse____last_update #: model:ir.model.fields,field_description:intrastat_product.field_stock_warehouse____last_update
@@ -1177,6 +1197,11 @@ msgstr ""
msgid "Origin Region" msgid "Origin Region"
msgstr "" msgstr ""
#. module: intrastat_product
#: model_terms:ir.ui.view,arch_db:intrastat_product.report_invoice_document_intrastat_product
msgid "Origin country"
msgstr ""
#. module: intrastat_product #. module: intrastat_product
#: model:ir.model.fields,help:intrastat_product.field_account_bank_statement_line__src_dest_region_id #: model:ir.model.fields,help:intrastat_product.field_account_bank_statement_line__src_dest_region_id
#: model:ir.model.fields,help:intrastat_product.field_account_move__src_dest_region_id #: model:ir.model.fields,help:intrastat_product.field_account_move__src_dest_region_id
@@ -1243,6 +1268,7 @@ msgstr ""
#: code:addons/intrastat_product/report/intrastat_product_report_xls.py:0 #: code:addons/intrastat_product/report/intrastat_product_report_xls.py:0
#: model:ir.model.fields,field_description:intrastat_product.field_account_move_intrastat_line__product_id #: model:ir.model.fields,field_description:intrastat_product.field_account_move_intrastat_line__product_id
#: model:ir.model.fields,field_description:intrastat_product.field_intrastat_product_computation_line__product_id #: model:ir.model.fields,field_description:intrastat_product.field_intrastat_product_computation_line__product_id
#: model_terms:ir.ui.view,arch_db:intrastat_product.report_invoice_document_intrastat_product
#, python-format #, python-format
msgid "Product" msgid "Product"
msgstr "" msgstr ""
@@ -1270,6 +1296,11 @@ msgstr ""
msgid "Railway transport (including lorries on railway wagons)" msgid "Railway transport (including lorries on railway wagons)"
msgstr "" msgstr ""
#. module: intrastat_product
#: model_terms:ir.ui.view,arch_db:intrastat_product.report_invoice_document_intrastat_product
msgid "Reference"
msgstr ""
#. module: intrastat_product #. module: intrastat_product
#: model:ir.model.fields,field_description:intrastat_product.field_intrastat_unit__uom_id #: model:ir.model.fields,field_description:intrastat_product.field_intrastat_unit__uom_id
#: model_terms:ir.ui.view,arch_db:intrastat_product.intrastat_unit_search #: model_terms:ir.ui.view,arch_db:intrastat_product.intrastat_unit_search
@@ -1368,6 +1399,12 @@ msgstr ""
msgid "Sequence" msgid "Sequence"
msgstr "" msgstr ""
#. module: intrastat_product
#: model:ir.model.fields,field_description:intrastat_product.field_res_partner__invoice_intrastat_detail
#: model:ir.model.fields,field_description:intrastat_product.field_res_users__invoice_intrastat_detail
msgid "Show intrastat details in invoice report"
msgstr ""
#. module: intrastat_product #. module: intrastat_product
#: code:addons/intrastat_product/models/intrastat_product_declaration.py:0 #: code:addons/intrastat_product/models/intrastat_product_declaration.py:0
#, python-format #, python-format
@@ -1550,8 +1587,8 @@ msgid "Type"
msgstr "" msgstr ""
#. module: intrastat_product #. module: intrastat_product
#: model:ir.model.fields,help:intrastat_product.field_intrastat_product_declaration__activity_exception_decoration #: model_terms:ir.ui.view,arch_db:intrastat_product.report_invoice_document_intrastat_product
msgid "Type of the exception activity on record." msgid "Unit Weight"
msgstr "" msgstr ""
#. module: intrastat_product #. module: intrastat_product
@@ -1616,6 +1653,7 @@ msgstr ""
#: code:addons/intrastat_product/report/intrastat_product_report_xls.py:0 #: code:addons/intrastat_product/report/intrastat_product_report_xls.py:0
#: model:ir.model.fields,field_description:intrastat_product.field_intrastat_product_computation_line__weight #: model:ir.model.fields,field_description:intrastat_product.field_intrastat_product_computation_line__weight
#: model:ir.model.fields,field_description:intrastat_product.field_intrastat_product_declaration_line__weight #: model:ir.model.fields,field_description:intrastat_product.field_intrastat_product_declaration_line__weight
#: model_terms:ir.ui.view,arch_db:intrastat_product.report_invoice_document_intrastat_product
#, python-format #, python-format
msgid "Weight" msgid "Weight"
msgstr "" msgstr ""

View File

@@ -1,5 +1,6 @@
from . import res_company from . import res_company
from . import res_config_settings from . import res_config_settings
from . import res_partner
from . import account_move from . import account_move
from . import hs_code from . import hs_code
from . import intrastat_product_declaration from . import intrastat_product_declaration

View File

@@ -105,7 +105,7 @@ class AccountMove(models.Model):
{ {
"invoice_line_id": line.id, "invoice_line_id": line.id,
"hs_code_id": hs_code.id, "hs_code_id": hs_code.id,
"transaction_weight": int(weight), "transaction_weight": weight,
"transaction_suppl_unit_qty": qty, "transaction_suppl_unit_qty": qty,
"product_origin_country_id": line.product_id.origin_country_id.id, "product_origin_country_id": line.product_id.origin_country_id.id,
"product_origin_country_code": product_origin_country_code, "product_origin_country_code": product_origin_country_code,
@@ -113,6 +113,45 @@ class AccountMove(models.Model):
) )
return vals return vals
def _prepare_intrastat_line_info(self, line):
is_intrastat_line = bool(line._name == "account.move.intrastat.line")
product = line.product_id
return {
"product_id": product,
"hs_code_id": (
line.hs_code_id if is_intrastat_line else product.hs_code_id
),
"weight": (
line.transaction_weight
if is_intrastat_line
else self._get_intrastat_line_vals(line)["transaction_weight"]
),
"origin_country_id": (
line.product_origin_country_id
if is_intrastat_line
else product.origin_country_id
),
}
def _get_intrastat_lines_info(self):
"""We obtain a list of information that we will need to group at the end by
product and sum weight.
"""
res = {}
for line in (
self.invoice_line_ids.filtered(
lambda x: x.product_id.hs_code_id and x.product_id.origin_country_id
)
if not self.intrastat_line_ids
else self.intrastat_line_ids
):
res.setdefault(line.product_id.id, {"weight": 0})
vals = self._prepare_intrastat_line_info(line)
weight = vals.pop("weight")
res[line.product_id.id].update(vals)
res[line.product_id.id]["weight"] += weight
return res.values()
class AccountMoveLine(models.Model): class AccountMoveLine(models.Model):
_inherit = "account.move.line" _inherit = "account.move.line"

View File

@@ -0,0 +1,16 @@
# Copyright 2022 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class ResParter(models.Model):
_inherit = "res.partner"
invoice_intrastat_detail = fields.Boolean(
string="Show intrastat details in invoice report"
)
@api.model
def _commercial_fields(self):
return super()._commercial_fields() + ["invoice_intrastat_detail"]

View File

@@ -4,3 +4,4 @@
* Tecnativa <www.tecnativa.com>: * Tecnativa <www.tecnativa.com>:
* João Marques * João Marques
* Víctor Martínez

View File

@@ -3,7 +3,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.15.1: http://docutils.sourceforge.net/" /> <meta name="generator" content="Docutils: http://docutils.sourceforge.net/" />
<title>Intrastat Product</title> <title>Intrastat Product</title>
<style type="text/css"> <style type="text/css">
@@ -488,6 +488,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<blockquote> <blockquote>
<ul class="simple"> <ul class="simple">
<li>João Marques</li> <li>João Marques</li>
<li>Víctor Martínez</li>
</ul> </ul>
</blockquote> </blockquote>
</li> </li>

View File

@@ -1,8 +1,10 @@
# Copyright 2021 ACSONE SA/NV # Copyright 2021 ACSONE SA/NV
# Copyright 2022 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from psycopg2 import IntegrityError from psycopg2 import IntegrityError
from odoo.exceptions import UserError, ValidationError from odoo.exceptions import UserError, ValidationError
from odoo.tests import Form
from odoo.tests.common import SavepointCase from odoo.tests.common import SavepointCase
from odoo.tools import mute_logger from odoo.tools import mute_logger
@@ -12,6 +14,33 @@ from .common import IntrastatProductCommon
class TestIntrastatProduct(IntrastatProductCommon): class TestIntrastatProduct(IntrastatProductCommon):
"""Tests for this module""" """Tests for this module"""
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.product = cls.env["product.product"].create(
{
"name": "Test product",
"hs_code_id": cls.env.ref("product_harmonized_system.84715000").id,
"origin_country_id": cls.env.ref("base.de").id,
"weight": 1.25,
}
)
cls.partner = cls.partner_obj.create(
{
"name": "Test partner",
"country_id": cls.env.ref("base.fr").id,
"invoice_intrastat_detail": True,
}
)
cls.env["account.journal"].create(
{"name": "Test sale journal", "type": "sale", "code": "TEST-sale"}
)
cls.report_obj = cls.env["ir.actions.report"]
cls.sale_order = cls._create_sale_order(cls)
cls.sale_order.action_confirm()
cls.sale_order.order_line.qty_delivered = 1
cls.invoice = cls.sale_order._create_invoices()
# Test duplicates # Test duplicates
@mute_logger("odoo.sql_db") @mute_logger("odoo.sql_db")
def test_region(self): def test_region(self):
@@ -62,6 +91,37 @@ class TestIntrastatProduct(IntrastatProductCommon):
with self.assertRaises(UserError): with self.assertRaises(UserError):
self.declaration.unlink() self.declaration.unlink()
def _create_sale_order(self):
order_form = Form(self.env["sale.order"])
order_form.partner_id = self.partner
with order_form.order_line.new() as line_form:
line_form.product_id = self.product
with order_form.order_line.new() as line_form:
line_form.product_id = self.product
return order_form.save()
def _test_invoice_report(self, weight):
"""We need to check weight because if intrastat_line_ids already exist
the weight will be different because weight field in model is integer."""
res = self.report_obj._get_report_from_name(
"account.report_invoice_with_payments"
)._render_qweb_text(self.invoice.ids, False)
self.assertRegex(str(res[0]), self.product.hs_code_id.hs_code)
self.assertRegex(str(res[0]), self.product.origin_country_id.name)
res = list(self.invoice._get_intrastat_lines_info())
self.assertEqual(len(res), 1)
self.assertEqual(res[0]["product_id"], self.product)
self.assertEqual(res[0]["hs_code_id"], self.product.hs_code_id)
self.assertEqual(res[0]["origin_country_id"], self.product.origin_country_id)
self.assertEqual(res[0]["weight"], weight)
def test_invoice_report_without_intrastat_lines(self):
self._test_invoice_report(2.5)
def test_invoice_report_with_intrastat_lines(self):
self.invoice.compute_intrastat_lines()
self._test_invoice_report(2)
class TestIntrastatProductCase(TestIntrastatProduct, SavepointCase): class TestIntrastatProductCase(TestIntrastatProduct, SavepointCase):
"""Test Intrastat Product""" """Test Intrastat Product"""

View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template
id="report_invoice_document_intrastat_product"
inherit_id="account.report_invoice_document"
>
<xpath expr="//div[hasclass('page')]" position="inside">
<t t-if="o.partner_id.invoice_intrastat_detail">
<t
t-set="intrastat_lines_info"
t-value="o._get_intrastat_lines_info()"
/>
<t t-if="intrastat_lines_info">
<p style="page-break-before: always;" />
<h5>Intrastat information</h5>
<table name="intrastat_transaction_detail" class="table">
<thead>
<tr>
<th>Reference</th>
<th>Product</th>
<th>HS Code</th>
<th>Unit Weight</th>
<th>Weight</th>
<th>Origin country</th>
</tr>
</thead>
<tbody>
<tr t-foreach="intrastat_lines_info" t-as="line">
<td>
<span t-esc="line['product_id'].default_code" />
</td>
<td>
<span t-esc="line['product_id'].display_name" />
</td>
<td>
<span t-esc="line['hs_code_id'].local_code" />
</td>
<td>
<span t-esc="line['product_id'].weight" />
</td>
<td>
<span t-esc="round(line['weight'], 2)" />
</td>
<td>
<span t-esc="line['origin_country_id'].name" />
</td>
</tr>
</tbody>
</table>
</t>
</t>
</xpath>
</template>
</odoo>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" ?>
<odoo>
<record id="view_partner_property_form" model="ir.ui.view">
<field name="name">res.partner.form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="account.view_partner_property_form" />
<field name="arch" type="xml">
<field name="property_account_position_id" position="after">
<field name="invoice_intrastat_detail" />
</field>
</field>
</record>
</odoo>