diff --git a/l10n_it_intrastat_statement/models/intrastat_statement.py b/l10n_it_intrastat_statement/models/intrastat_statement.py index 4e6cb7e39a9d..0b895423c724 100644 --- a/l10n_it_intrastat_statement/models/intrastat_statement.py +++ b/l10n_it_intrastat_statement/models/intrastat_statement.py @@ -1,7 +1,7 @@ # Copyright 2019 Simone Rubino - Agile Business Group # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from datetime import date, datetime, timedelta +from datetime import date, timedelta from dateutil.relativedelta import relativedelta @@ -449,7 +449,7 @@ def get_dates_start_stop(self): month = self.period_number period_date_start = date(year, month, 1) period_date_stop = ( - datetime(year, month, 1) + relativedelta(months=1) - timedelta(days=1) + period_date_start + relativedelta(months=1) - timedelta(days=1) ) elif self.period_type == "T": quarter = self.period_number @@ -819,11 +819,21 @@ def compute_statement(self): refund_section_details = (section_type, refund_section_number) section_field = self.get_section_field_name(*section_details) for line in self[section_field]: - refund_section_model = self.get_section_model( - *refund_section_details - ) - to_refund_model = self.env[refund_section_model] - self.refund_line(line, to_refund_model) + # Compensation can happen only if the credit note has been issued + # for invoices belonging the considered period. Here we check + # if the reversed entry of the Sale/Purchase section 2 line + # respect this constraint otherwise no compensation should + # happen + refund_date = line.invoice_id.reversed_entry_id.invoice_date + if ( + refund_date + and period_date_start <= refund_date <= period_date_stop + ): + refund_section_model = self.get_section_model( + *refund_section_details + ) + to_refund_model = self.env[refund_section_model] + self.refund_line(line, to_refund_model) return True @staticmethod diff --git a/l10n_it_intrastat_statement/tests/test_intrastat_statement.py b/l10n_it_intrastat_statement/tests/test_intrastat_statement.py index f4e391535f65..eef35e5464bc 100644 --- a/l10n_it_intrastat_statement/tests/test_intrastat_statement.py +++ b/l10n_it_intrastat_statement/tests/test_intrastat_statement.py @@ -88,7 +88,11 @@ def setUp(self): ) def _get_intrastat_computed_bill( - self, product=None, currency=None, price_unit=100.0 + self, + product=None, + currency=None, + price_unit=100.0, + date=None, ): if product is None: product = self.product01 @@ -98,13 +102,14 @@ def _get_intrastat_computed_bill( product=product, taxes=self.tax22_purchase, amount=price_unit, + date=date, ) if currency: invoice.currency_id = currency invoice.action_post() return invoice - def _get_intrastat_computed_invoice(self, price_unit=100.0): + def _get_intrastat_computed_invoice(self, price_unit=100.0, date=None): invoice = self._create_move( "out_invoice", partner=self.partner01, @@ -112,6 +117,7 @@ def _get_intrastat_computed_invoice(self, price_unit=100.0): taxes=self.tax22_sale, amount=price_unit, post=True, + date=date, ) return invoice @@ -218,6 +224,11 @@ def test_statement_purchase_refund(self): statement.generate_file_export() statement.compute_statement() + + # Check compensation, we expect only purchase section 1 having one line + self.assertEqual(len(statement.purchase_section1_ids), 1) + self.assertEqual(len(statement.purchase_section2_ids), 0) + file_content = statement.with_context(purchase=True).generate_file_export() self.assertIn(bill_refund.partner_id.vat[2:], file_content) @@ -229,6 +240,34 @@ def test_statement_purchase_refund(self): self.assertEqual(len(file_lines), 3) self.assertSetEqual({len(line) for line in file_lines}, {75, 130, 119}) + def test_statement_purchase_refund_no_compensation(self): + bill = self._get_intrastat_computed_bill(date="2018-12-15") + self._get_intrastat_computed_bill(date="2019-01-05") + + bill_refund = self._create_move_refund(bill, date="2019-01-10") + # This refund will be subtracted from bill + bill_refund.update( + { + "intrastat": True, + } + ) + bill_refund.action_post() + bill_refund.compute_intrastat_lines() + + statement = self.statement_model.create( + { + "period_number": bill_refund.invoice_date.month, + "fiscalyear": bill_refund.invoice_date.year, + } + ) + + statement.compute_statement() + + # No compensation should happen, we expect both purchase section 1 and 2 + # to have 1 entry + self.assertEqual(len(statement.purchase_section1_ids), 1) + self.assertEqual(len(statement.purchase_section2_ids), 1) + def test_statement_purchase_refund_no_subtract(self): bill = self._get_intrastat_computed_bill() @@ -504,11 +543,14 @@ def _create_move( product=None, amount=None, taxes=None, + date=None, ): move_form = Form( self.env["account.move"].with_context(default_move_type=move_type) ) - move_form.invoice_date = invoice_date or fields.Date.from_string("2019-01-01") + move_form.invoice_date = invoice_date or fields.Date.from_string( + date or "2019-01-01" + ) move_form.partner_id = partner or self.partner_a move_form.intrastat = True @@ -526,13 +568,13 @@ def _create_move( return rslt - def _create_move_refund(self, move): + def _create_move_refund(self, move, date=None): move_reversal = ( self.env["account.move.reversal"] .with_context(active_model="account.move", active_ids=move.ids) .create( { - "date": fields.Date.from_string("2019-01-01"), + "date": fields.Date.from_string(date or "2019-01-01"), "reason": "no reason", "refund_method": "refund", } diff --git a/l10n_it_intrastat_statement/views/intrastat.xml b/l10n_it_intrastat_statement/views/intrastat.xml index 5c1a9a57801e..f2d6ef7e7044 100644 --- a/l10n_it_intrastat_statement/views/intrastat.xml +++ b/l10n_it_intrastat_statement/views/intrastat.xml @@ -282,15 +282,15 @@ account.intrastat.statement.sale.section1 - - - - - - - - - + + + + + + + + + @@ -356,16 +356,17 @@ account.intrastat.statement.sale.section2 - - - - - - - - - - + + + + + + + + + + +