diff --git a/l10n_it_vat_settlement_date/models/account_move.py b/l10n_it_vat_settlement_date/models/account_move.py index e4bbcfb01b0d..c1f067c8fc05 100644 --- a/l10n_it_vat_settlement_date/models/account_move.py +++ b/l10n_it_vat_settlement_date/models/account_move.py @@ -2,7 +2,8 @@ # Copyright 2024 Simone Rubino - Aion Tech # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import api, fields, models +from odoo import _, api, fields, models +from odoo.tools import format_date class AccountMove(models.Model): @@ -25,3 +26,49 @@ def _compute_l10n_it_vat_settlement_date(self): move.date or move.invoice_date or fields.Date.context_today(move) ) move.l10n_it_vat_settlement_date = settlement_date + + def _get_violated_lock_dates(self, invoice_date, has_tax): + settlement_date = self.l10n_it_vat_settlement_date + if has_tax and settlement_date and invoice_date == self.date: + # When tax is involved, + # VAT Settlement Date is the date that has to be after the lock. + invoice_date = settlement_date + return super()._get_violated_lock_dates(invoice_date, has_tax) + + def _get_lock_date_message(self, invoice_date, has_tax): + message = super()._get_lock_date_message(invoice_date, has_tax) + if message: + lock_dates = self._get_violated_lock_dates(invoice_date, has_tax) + settlement_date = self.l10n_it_vat_settlement_date + if lock_dates and has_tax and settlement_date and invoice_date == self.date: + # The super's message talks about a generic date. + # When tax is involved, + # VAT Settlement Date is the date that has to be after the lock, + # and it will be moved too. + lock_date, lock_type = lock_dates[-1] + unlocked_invoice_date = self._get_accounting_date(invoice_date, has_tax) + message = _( + "The VAT Settlement Date is being set " + "prior to the %(lock_type)s lock date %(lock_date)s.\n" + "The Journal Entry will be accounted " + "on %(unlocked_invoice_date)s upon posting.", + lock_type=lock_type, + lock_date=format_date(self.env, lock_date), + unlocked_invoice_date=format_date(self.env, unlocked_invoice_date), + ) + message = "\n".join( + [ + message, + _( + "Both VAT Settlement Date and accounting date " + "will be changed upon posting.", + ), + ] + ) + return message + + @api.depends( + "l10n_it_vat_settlement_date", + ) + def _compute_tax_lock_date_message(self): + return super()._compute_tax_lock_date_message() diff --git a/l10n_it_vat_settlement_date/tests/__init__.py b/l10n_it_vat_settlement_date/tests/__init__.py index 2d4ef90063e5..84b8d6d340bb 100644 --- a/l10n_it_vat_settlement_date/tests/__init__.py +++ b/l10n_it_vat_settlement_date/tests/__init__.py @@ -1,4 +1,5 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import test_lock_dates from . import test_vat_period_end_statement from . import test_vat_registry diff --git a/l10n_it_vat_settlement_date/tests/test_lock_dates.py b/l10n_it_vat_settlement_date/tests/test_lock_dates.py new file mode 100644 index 000000000000..548e50f8a493 --- /dev/null +++ b/l10n_it_vat_settlement_date/tests/test_lock_dates.py @@ -0,0 +1,64 @@ +# Copyright 2024 Simone Rubino - Aion Tech +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import datetime + +from odoo.tests import tagged + +from odoo.addons.account.tests.common import AccountTestInvoicingCommon + + +@tagged("post_install", "-at_install") +class TestLockDates(AccountTestInvoicingCommon): + @classmethod + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) + cls.company = cls.env.company + + def test_bill_tax_lock(self): + """The tax lock date is checked against + the settlement date of a supplier bill.""" + settlement_date = datetime.date(2020, month=1, day=1) + tax_lock_date = datetime.date(2020, month=1, day=2) + accounting_date = datetime.date(2020, month=1, day=3) + self.company.tax_lock_date = tax_lock_date + bill = self.init_invoice( + "in_invoice", + invoice_date=accounting_date, + amounts=[100], + ) + # pre-condition + self.assertEqual(bill.date, accounting_date) + self.assertEqual(bill.invoice_date, accounting_date) + self.assertTrue(settlement_date < tax_lock_date < accounting_date) + self.assertFalse(bill.tax_lock_date_message) + + # Act + bill.l10n_it_vat_settlement_date = settlement_date + + # Assert + self.assertIn("VAT Settlement Date", bill.tax_lock_date_message) + + def test_invoice_tax_lock(self): + """The tax lock date is checked against + the settlement date of a customer invoice.""" + settlement_date = datetime.date(2020, month=1, day=1) + tax_lock_date = datetime.date(2020, month=1, day=2) + accounting_date = datetime.date(2020, month=1, day=3) + self.company.tax_lock_date = tax_lock_date + invoice = self.init_invoice( + "out_invoice", + invoice_date=accounting_date, + amounts=[100], + ) + # pre-condition + self.assertEqual(invoice.date, accounting_date) + self.assertEqual(invoice.invoice_date, accounting_date) + self.assertTrue(settlement_date < tax_lock_date < accounting_date) + self.assertFalse(invoice.tax_lock_date_message) + + # Act + invoice.l10n_it_vat_settlement_date = settlement_date + + # Assert + self.assertIn("VAT Settlement Date", invoice.tax_lock_date_message)