mirror of
https://github.com/OCA/intrastat-extrastat.git
synced 2025-02-16 17:13:41 +02:00
[IMP] intrastat_product: Add an Intrastat summary in the invoice report.
TT37168
This commit is contained in:
@@ -145,6 +145,7 @@ Contributors
|
||||
* Tecnativa <www.tecnativa.com>:
|
||||
|
||||
* João Marques
|
||||
* Víctor Martínez
|
||||
|
||||
Maintainers
|
||||
~~~~~~~~~~~
|
||||
|
||||
@@ -32,9 +32,11 @@
|
||||
"views/intrastat_transport_mode.xml",
|
||||
"views/intrastat_product_declaration.xml",
|
||||
"views/res_config_settings.xml",
|
||||
"views/res_partner_view.xml",
|
||||
"views/account_move.xml",
|
||||
"views/sale_order.xml",
|
||||
"views/stock_warehouse.xml",
|
||||
"views/report_invoice.xml",
|
||||
"wizards/intrastat_result_view.xml",
|
||||
"data/intrastat_transport_mode.xml",
|
||||
"data/intrastat_unit.xml",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 14.0\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"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -302,6 +304,11 @@ msgstr ""
|
||||
msgid "Config Settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: intrastat_product
|
||||
#: model:ir.model,name:intrastat_product.model_res_partner
|
||||
msgid "Contact"
|
||||
msgstr ""
|
||||
|
||||
#. module: intrastat_product
|
||||
#: code:addons/intrastat_product/models/intrastat_product_declaration.py:0
|
||||
#, 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_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_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_stock_location__display_name
|
||||
#: model:ir.model.fields,field_description:intrastat_product.field_stock_warehouse__display_name
|
||||
@@ -639,6 +647,11 @@ msgstr ""
|
||||
msgid "H.S. Codes"
|
||||
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
|
||||
#: 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
|
||||
@@ -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_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_partner__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_warehouse__id
|
||||
@@ -869,6 +883,11 @@ msgstr ""
|
||||
msgid "Intrastat declaration details"
|
||||
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
|
||||
#: 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
|
||||
@@ -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_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_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_stock_location____last_update
|
||||
#: model:ir.model.fields,field_description:intrastat_product.field_stock_warehouse____last_update
|
||||
@@ -1177,6 +1197,11 @@ msgstr ""
|
||||
msgid "Origin Region"
|
||||
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
|
||||
#: 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
|
||||
@@ -1243,6 +1268,7 @@ msgstr ""
|
||||
#: 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_intrastat_product_computation_line__product_id
|
||||
#: model_terms:ir.ui.view,arch_db:intrastat_product.report_invoice_document_intrastat_product
|
||||
#, python-format
|
||||
msgid "Product"
|
||||
msgstr ""
|
||||
@@ -1270,6 +1296,11 @@ msgstr ""
|
||||
msgid "Railway transport (including lorries on railway wagons)"
|
||||
msgstr ""
|
||||
|
||||
#. module: intrastat_product
|
||||
#: model_terms:ir.ui.view,arch_db:intrastat_product.report_invoice_document_intrastat_product
|
||||
msgid "Reference"
|
||||
msgstr ""
|
||||
|
||||
#. module: intrastat_product
|
||||
#: 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
|
||||
@@ -1368,6 +1399,12 @@ msgstr ""
|
||||
msgid "Sequence"
|
||||
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
|
||||
#: code:addons/intrastat_product/models/intrastat_product_declaration.py:0
|
||||
#, python-format
|
||||
@@ -1550,8 +1587,8 @@ msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: intrastat_product
|
||||
#: model:ir.model.fields,help:intrastat_product.field_intrastat_product_declaration__activity_exception_decoration
|
||||
msgid "Type of the exception activity on record."
|
||||
#: model_terms:ir.ui.view,arch_db:intrastat_product.report_invoice_document_intrastat_product
|
||||
msgid "Unit Weight"
|
||||
msgstr ""
|
||||
|
||||
#. module: intrastat_product
|
||||
@@ -1616,6 +1653,7 @@ msgstr ""
|
||||
#: 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_declaration_line__weight
|
||||
#: model_terms:ir.ui.view,arch_db:intrastat_product.report_invoice_document_intrastat_product
|
||||
#, python-format
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from . import res_company
|
||||
from . import res_config_settings
|
||||
from . import res_partner
|
||||
from . import account_move
|
||||
from . import hs_code
|
||||
from . import intrastat_product_declaration
|
||||
|
||||
@@ -105,7 +105,7 @@ class AccountMove(models.Model):
|
||||
{
|
||||
"invoice_line_id": line.id,
|
||||
"hs_code_id": hs_code.id,
|
||||
"transaction_weight": int(weight),
|
||||
"transaction_weight": weight,
|
||||
"transaction_suppl_unit_qty": qty,
|
||||
"product_origin_country_id": line.product_id.origin_country_id.id,
|
||||
"product_origin_country_code": product_origin_country_code,
|
||||
@@ -113,6 +113,45 @@ class AccountMove(models.Model):
|
||||
)
|
||||
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):
|
||||
_inherit = "account.move.line"
|
||||
|
||||
16
intrastat_product/models/res_partner.py
Normal file
16
intrastat_product/models/res_partner.py
Normal 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"]
|
||||
@@ -4,3 +4,4 @@
|
||||
* Tecnativa <www.tecnativa.com>:
|
||||
|
||||
* João Marques
|
||||
* Víctor Martínez
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<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>
|
||||
<style type="text/css">
|
||||
|
||||
@@ -488,6 +488,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
|
||||
<blockquote>
|
||||
<ul class="simple">
|
||||
<li>João Marques</li>
|
||||
<li>Víctor Martínez</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
</li>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Copyright 2021 ACSONE SA/NV
|
||||
# Copyright 2022 Tecnativa - Víctor Martínez
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from psycopg2 import IntegrityError
|
||||
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tests import Form
|
||||
from odoo.tests.common import SavepointCase
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
@@ -12,6 +14,33 @@ from .common import IntrastatProductCommon
|
||||
class TestIntrastatProduct(IntrastatProductCommon):
|
||||
"""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
|
||||
@mute_logger("odoo.sql_db")
|
||||
def test_region(self):
|
||||
@@ -62,6 +91,37 @@ class TestIntrastatProduct(IntrastatProductCommon):
|
||||
with self.assertRaises(UserError):
|
||||
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):
|
||||
"""Test Intrastat Product"""
|
||||
|
||||
54
intrastat_product/views/report_invoice.xml
Normal file
54
intrastat_product/views/report_invoice.xml
Normal 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>
|
||||
13
intrastat_product/views/res_partner_view.xml
Normal file
13
intrastat_product/views/res_partner_view.xml
Normal 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>
|
||||
Reference in New Issue
Block a user