diff --git a/intrastat_product/report/intrastat_product_report_xls.py b/intrastat_product/report/intrastat_product_report_xls.py index 48ccb26..daa63b1 100644 --- a/intrastat_product/report/intrastat_product_report_xls.py +++ b/intrastat_product/report/intrastat_product_report_xls.py @@ -28,6 +28,10 @@ class IntrastatProductDeclarationXlsx(models.AbstractModel): return val def _get_template(self, declaration): + """ + Return a dictionary that contains columns specifications + see: report_xlsx_helper / _write_line() method + """ template = { "product": { diff --git a/intrastat_product/tests/common.py b/intrastat_product/tests/common.py index 6efb68b..4047ba6 100644 --- a/intrastat_product/tests/common.py +++ b/intrastat_product/tests/common.py @@ -1,5 +1,7 @@ # Copyright 2021 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +import xlrd +from werkzeug.urls import url_encode from odoo.addons.intrastat_base.tests.common import IntrastatCommon @@ -63,6 +65,10 @@ class IntrastatProductCommon(IntrastatCommon): cls.declaration_obj = cls.env["intrastat.product.declaration"] cls.position_obj = cls.env["account.fiscal.position"] cls.hs_code_computer = cls.env.ref("product_harmonized_system.84715000") + cls.report_obj = cls.env["ir.actions.report"] + cls.xls_declaration = cls.env[ + "report.intrastat_product.product_declaration_xls" + ] cls.transport_rail = cls.env.ref("intrastat_product.intrastat_transport_2") cls.transport_road = cls.env.ref("intrastat_product.intrastat_transport_3") @@ -72,6 +78,78 @@ class IntrastatProductCommon(IntrastatCommon): cls._init_fiscal_position() cls._init_products() + @classmethod + def _create_xls(cls, declaration=False): + """ + Prepare the Excel report to be tested + + :return: The Excel file + :rtype: bytes + """ + report = cls.declaration.with_context( + active_ids=cls.declaration.ids + ).create_xls() + report_name = report.get("report_name") + cls.report = cls.report_obj._get_report_from_name(report_name) + datas = { + "context": { + "active_ids": [cls.declaration.id], + } + } + data = {} + encoded_data = "report/report_xlsx/" + report_name + "?" + url_encode(data) + datas["data"] = encoded_data + context = { + "active_model": cls.declaration._name, + } + if not declaration: + context.update({"computation_lines": True}) + else: + context.update({"declaration_lines": True}) + file_data = cls.xls_declaration.with_context(context).create_xlsx_report( + None, datas + ) + return file_data + + def check_xls(self, xls, declaration=False): + """ + Check that the xls content correspond to computation/declaration + lines values + + :param xls: the Excel file content + :type xls: bytes + :param declaration: By default, check computation lines, either declaration ones + :type declaration: bool, optional + """ + book = xlrd.open_workbook(file_contents=xls) + sheet = book.sheet_by_index(0) + # Get the template used to build the Excel file lines + template = self.xls_declaration._get_template(self.declaration) + # Get the declaration lines or the computation ones + if not declaration: + declaration_lines = self.declaration.computation_line_ids + line_fields = self.declaration._xls_computation_line_fields() + else: + declaration_lines = self.declaration.declaration_line_ids + line_fields = self.declaration._xls_declaration_line_fields() + i = 0 + # Iterate on each row beginning on third one (two headers) + for rx in range(3, sheet.nrows): + line = declaration_lines[i] + row = sheet.row(rx) + j = 0 + dict_compare = dict() + for line_field in line_fields: + column_spec = template.get(line_field) + dict_compare.update( + {row[j].value: column_spec.get("line").get("value")} + ) + j += 1 + for key, value in dict_compare.items(): + value_eval = self.xls_declaration._eval(value, {"line": line}) + self.assertEqual(key, value_eval) + i += 1 + @classmethod def _create_region(cls, vals=None): values = { diff --git a/intrastat_product/tests/test_purchase_order.py b/intrastat_product/tests/test_purchase_order.py index 236ffe7..88528e2 100644 --- a/intrastat_product/tests/test_purchase_order.py +++ b/intrastat_product/tests/test_purchase_order.py @@ -48,6 +48,14 @@ class TestIntrastatProductPurchase(IntrastatPurchaseCommon): self.declaration.generate_declaration() self._check_line_values(final=True) + # Check the Excel computation file + file_data = self._create_xls() + self.check_xls(file_data[0]) + + # Check the Excel declaration file + file_data = self._create_xls(True) + self.check_xls(file_data[0], True) + class TestIntrastatProductPurchaseCase(TestIntrastatProductPurchase, SavepointCase): """Test Intrastat Purchase""" diff --git a/intrastat_product/tests/test_sale_order.py b/intrastat_product/tests/test_sale_order.py index 7c01f1b..aedfe7f 100644 --- a/intrastat_product/tests/test_sale_order.py +++ b/intrastat_product/tests/test_sale_order.py @@ -83,6 +83,14 @@ class TestIntrastatProductSale(IntrastatSaleCommon): self.declaration.generate_declaration() self._check_line_values(final=True) + # Check the Excel computation file + file_data = self._create_xls() + self.check_xls(file_data[0]) + + # Check the Excel declaration file + file_data = self._create_xls(True) + self.check_xls(file_data[0], True) + class TestIntrastatProductSaleCase(TestIntrastatProductSale, SavepointCase): """Test Intrastat Sale"""