Initial commit: Odoo 18.0-20251222 extra-addons
This commit is contained in:
1
partner_invoicing_mode/tests/__init__.py
Normal file
1
partner_invoicing_mode/tests/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import test_invoice_mode
|
||||
83
partner_invoicing_mode/tests/common.py
Normal file
83
partner_invoicing_mode/tests/common.py
Normal file
@@ -0,0 +1,83 @@
|
||||
# Copyright 2020 Camptocamp SA
|
||||
# Copyright 2023 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
from odoo import Command
|
||||
|
||||
from odoo.addons.base.tests.common import BaseCommon
|
||||
|
||||
|
||||
class CommonPartnerInvoicingMode(BaseCommon):
|
||||
_invoicing_mode = "standard"
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.SaleOrder = cls.env["sale.order"]
|
||||
cls.partner = cls.env.ref("base.res_partner_1")
|
||||
cls.partner.invoicing_mode = cls._invoicing_mode
|
||||
cls.partner2 = cls.env.ref("base.res_partner_2")
|
||||
cls.partner2.invoicing_mode = cls._invoicing_mode
|
||||
cls.product = cls.env.ref("product.product_delivery_01")
|
||||
cls.pt1 = cls.env["account.payment.term"].create({"name": "Term Two"})
|
||||
cls.pt2 = cls.env["account.payment.term"].create({"name": "Term One"})
|
||||
|
||||
# Create a default pricelist for the test
|
||||
cls.pricelist = cls.env["product.pricelist"].create(
|
||||
{
|
||||
"name": "Test Pricelist",
|
||||
"currency_id": cls.env.ref("base.main_company").currency_id.id,
|
||||
"company_id": cls.env.ref("base.main_company").id,
|
||||
}
|
||||
)
|
||||
|
||||
cls.so1 = cls.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": cls.partner.id,
|
||||
"partner_invoice_id": cls.partner.id,
|
||||
"partner_shipping_id": cls.partner.id,
|
||||
"payment_term_id": cls.pt1.id,
|
||||
"order_line": [
|
||||
Command.create(
|
||||
{
|
||||
"name": "Line one",
|
||||
"product_id": cls.product.id,
|
||||
"product_uom_qty": 4,
|
||||
"product_uom": cls.product.uom_id.id,
|
||||
"price_unit": 123,
|
||||
}
|
||||
)
|
||||
],
|
||||
"pricelist_id": cls.pricelist.id, # Use the newly created pricelist
|
||||
}
|
||||
)
|
||||
# Lets give the saleorder the same partner and payment terms
|
||||
cls.so2 = cls.env["sale.order"].create(
|
||||
{
|
||||
"partner_id": cls.partner.id,
|
||||
"partner_invoice_id": cls.partner.id,
|
||||
"partner_shipping_id": cls.partner.id,
|
||||
"payment_term_id": cls.pt1.id,
|
||||
"order_line": [
|
||||
Command.create(
|
||||
{
|
||||
"name": "Line one",
|
||||
"product_id": cls.product.id,
|
||||
"product_uom_qty": 4,
|
||||
"product_uom": cls.product.uom_id.id,
|
||||
"price_unit": 123,
|
||||
},
|
||||
)
|
||||
],
|
||||
"pricelist_id": cls.pricelist.id, # Use the newly created pricelist
|
||||
}
|
||||
)
|
||||
cls.company = cls.so1.company_id
|
||||
|
||||
@classmethod
|
||||
def _confirm_and_deliver(cls, sale_order):
|
||||
"""
|
||||
Use standard sale flow to confirm delivered products
|
||||
"""
|
||||
sale_order.action_confirm()
|
||||
for line in sale_order.order_line:
|
||||
line.qty_delivered = line.product_uom_qty
|
||||
186
partner_invoicing_mode/tests/test_invoice_mode.py
Normal file
186
partner_invoicing_mode/tests/test_invoice_mode.py
Normal file
@@ -0,0 +1,186 @@
|
||||
# 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)
|
||||
Reference in New Issue
Block a user