# Copyright 2022 Opener B.V. # Copyright 2023 ACSONE SA/NV # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) from unittest import mock from freezegun import freeze_time from odoo import fields from odoo.tests import Form from odoo.addons.queue_job.tests.common import trap_jobs from ..models.res_partner import ResPartner from .common import CommonPartnerInvoicingMode class TestInvoiceMode(CommonPartnerInvoicingMode): @classmethod def setUpClass(cls): super().setUpClass() cls.cron = cls.env.ref( "partner_invoicing_mode.ir_cron_generate_standard_invoice" ) def test_invoice_job_related_action(self): """Dedicated invoice view is present in queue job's multi invoice action""" invoice1 = self.env.ref("account.1_demo_invoice_1").copy() invoice2 = self.env.ref("account.1_demo_invoice_1").copy() job_single = self.env["queue.job"].search( [("uuid", "=", invoice1.with_delay()._validate_invoice().uuid)] ) action_single = job_single.open_related_action() self.assertFalse(action_single.get("view_id")) job_multi = self.env["queue.job"].search( [("uuid", "=", (invoice1 + invoice2).with_delay()._validate_invoice().uuid)] ) action_multi = job_multi.open_related_action() self.assertEqual( action_multi["view_id"], self.env.ref("account.view_out_invoice_tree").id ) def test_invoicing_standard(self): self.so1.payment_term_id = self.pt1.id self._confirm_and_deliver(self.so1) self.assertFalse(self.so1.invoice_ids) with trap_jobs() as trap: self.SaleOrder.generate_invoices() for job in trap.enqueued_jobs: job.perform() self.assertTrue(self.so1.invoice_ids) # No errors are raised when called without anything to invoice with trap_jobs() as trap: self.SaleOrder.generate_invoices() trap.assert_jobs_count(0) def test_invoicing_standard_cron(self): self.so1.payment_term_id = self.pt1.id self._confirm_and_deliver(self.so1) self.assertFalse(self.so1.invoice_ids) with trap_jobs() as trap: self.cron.method_direct_trigger() for job in trap.enqueued_jobs: job.perform() self.assertTrue(self.so1.invoice_ids) def test_invoicing_standard_grouping(self): # Confirm and deliver both sale orders self._confirm_and_deliver(self.so1) self._confirm_and_deliver(self.so2) with trap_jobs() as trap: self.SaleOrder.generate_invoices() for job in trap.enqueued_jobs: job.perform() # Check one invoice is generated self.assertEqual(1, len(self.so2.invoice_ids)) self.assertEqual(1, len(self.so1.invoice_ids)) # Check the invoice is the same self.assertEqual(self.so2.invoice_ids, self.so1.invoice_ids) def test_invoicing_standard_no_grouping(self): # Confirm and deliver both sale orders self.so1.one_invoice_per_order = True self.so2.one_invoice_per_order = True self._confirm_and_deliver(self.so1) self._confirm_and_deliver(self.so2) with trap_jobs() as trap: self.SaleOrder.generate_invoices() for job in trap.enqueued_jobs: job.perform() # Check one invoice is generated self.assertEqual(1, len(self.so2.invoice_ids)) self.assertEqual(1, len(self.so1.invoice_ids)) # Check the invoice is the same self.assertNotEqual(self.so2.invoice_ids, self.so1.invoice_ids) def test_grouping_change(self): # Create a sale order with a partner that have one invoice per order enabled # Check if the sale order created has that option enabled # Change the partner, then check if the option is disabled # Then, set it manually and check if value remains. self.partner2.one_invoice_per_order = True so3 = self.so1.copy() so3.partner_id = self.partner2 self.assertTrue(so3.one_invoice_per_order) so3.partner_id = self.partner self.assertFalse(so3.one_invoice_per_order) so3.one_invoice_per_order = True self.assertTrue(so3.one_invoice_per_order) def test_update_date(self): # Check the update next invoice date function has been called with mock.patch.object(ResPartner, "_update_next_invoice_date") as mock_update: self._confirm_and_deliver(self.so1) with trap_jobs() as trap: self.SaleOrder.generate_invoices() for job in trap.enqueued_jobs: job.perform() mock_update.assert_called() @freeze_time("2024-03-10") def test_invoicing_standard_cron_invoice_date(self): """ - Generate the invoice at day one - Execute the validation job at day two - Check the invoice date is day one """ self.so1.payment_term_id = self.pt1.id self._confirm_and_deliver(self.so1) self.assertFalse(self.so1.invoice_ids) with trap_jobs() as trap: self.cron.method_direct_trigger() for job in trap.enqueued_jobs: with trap_jobs() as trap_validate: job.perform() self.assertEqual(1, len(trap_validate.enqueued_jobs)) for validate_job in trap_validate.enqueued_jobs: with freeze_time("2024-03-11"): validate_job.perform() self.assertTrue(self.so1.invoice_ids) self.assertEqual( fields.Date.from_string("2024-03-10"), self.so1.invoice_ids.date ) def test_invoicing_standard_grouping_partner_invoicing(self): # Activate the ability to define a different invoice address # Create a new partner for invoicing self.env.user.groups_id |= self.env.ref( "account.group_delivery_invoice_address" ) self.partner_invoice = self.env["res.partner"].create( {"name": "Partner Invoicing"} ) self._confirm_and_deliver(self.so1) with Form(self.so2) as so2_form: so2_form.partner_invoice_id = self.partner_invoice self._confirm_and_deliver(self.so2) with trap_jobs() as trap: self.SaleOrder.generate_invoices() for job in trap.enqueued_jobs: job.perform() # Check one invoice is generated self.assertEqual(1, len(self.so2.invoice_ids)) self.assertEqual(1, len(self.so1.invoice_ids)) # Check the invoice is the same self.assertNotEqual(self.so2.invoice_ids, self.so1.invoice_ids) def test_invoicing_standard_grouping_payment_term_invoicing(self): # Activate the ability to define a different payment term self.env.user.groups_id |= self.env.ref( "account.group_delivery_invoice_address" ) self._confirm_and_deliver(self.so1) with Form(self.so2) as so2_form: so2_form.payment_term_id = self.env.ref( "account.account_payment_term_21days" ) self._confirm_and_deliver(self.so2) with trap_jobs() as trap: self.SaleOrder.generate_invoices() for job in trap.enqueued_jobs: job.perform() # Check one invoice is generated self.assertEqual(1, len(self.so2.invoice_ids)) self.assertEqual(1, len(self.so1.invoice_ids)) # Check the invoice is the same self.assertNotEqual(self.so2.invoice_ids, self.so1.invoice_ids)