mirror of
https://github.com/OCA/contract.git
synced 2025-02-13 17:57:24 +02:00
ADJ: When generating invoices from the Wizard to create invoices manually, reraise any UserError with information about which contract triggered the exception to facilitate the investigation by accountants in case invoices are not generated automatically.
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
from . import test_contract
|
from . import test_contract
|
||||||
|
from . import test_contract_manually_create_invoice
|
||||||
from . import test_portal
|
from . import test_portal
|
||||||
from . import test_multicompany
|
from . import test_multicompany
|
||||||
|
|||||||
@@ -1754,37 +1754,6 @@ class TestContract(TestContractBase):
|
|||||||
len(invoice_lines),
|
len(invoice_lines),
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_contract_manually_create_invoice(self):
|
|
||||||
self.acct_line.date_start = "2018-01-01"
|
|
||||||
self.acct_line.recurring_invoicing_type = "post-paid"
|
|
||||||
self.acct_line.date_end = "2018-03-15"
|
|
||||||
self.contract2.unlink()
|
|
||||||
contracts = self.contract
|
|
||||||
for _i in range(10):
|
|
||||||
contracts |= self.contract.copy()
|
|
||||||
wizard = self.env["contract.manually.create.invoice"].create(
|
|
||||||
{"invoice_date": self.today}
|
|
||||||
)
|
|
||||||
wizard.action_show_contract_to_invoice()
|
|
||||||
contract_to_invoice_count = wizard.contract_to_invoice_count
|
|
||||||
self.assertFalse(
|
|
||||||
contracts
|
|
||||||
- self.env["contract.contract"].search(
|
|
||||||
wizard.action_show_contract_to_invoice()["domain"]
|
|
||||||
),
|
|
||||||
)
|
|
||||||
action = wizard.create_invoice()
|
|
||||||
invoice_lines = self.env["account.move.line"].search(
|
|
||||||
[("contract_line_id", "in", contracts.mapped("contract_line_ids").ids)]
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
len(contracts.mapped("contract_line_ids")),
|
|
||||||
len(invoice_lines),
|
|
||||||
)
|
|
||||||
invoices = self.env["account.move"].search(action["domain"])
|
|
||||||
self.assertFalse(invoice_lines.mapped("move_id") - invoices)
|
|
||||||
self.assertEqual(len(invoices), contract_to_invoice_count)
|
|
||||||
|
|
||||||
def test_get_period_to_invoice_monthlylastday_postpaid(self):
|
def test_get_period_to_invoice_monthlylastday_postpaid(self):
|
||||||
self.acct_line.date_start = "2018-01-05"
|
self.acct_line.date_start = "2018-01-05"
|
||||||
self.acct_line.recurring_invoicing_type = "post-paid"
|
self.acct_line.recurring_invoicing_type = "post-paid"
|
||||||
|
|||||||
70
contract/tests/test_contract_manually_create_invoice.py
Normal file
70
contract/tests/test_contract_manually_create_invoice.py
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# Copyright 2018 Tecnativa - Carlos Dauden
|
||||||
|
# Copyright 2018-2020 Tecnativa - Pedro M. Baeza
|
||||||
|
# Copyright 2021 Tecnativa - Víctor Martínez
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
|
from .test_contract import TestContractBase
|
||||||
|
|
||||||
|
|
||||||
|
class TestContractManuallyCreateInvoice(TestContractBase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super().setUpClass()
|
||||||
|
cls.acct_line.date_start = "2018-01-01"
|
||||||
|
cls.acct_line.recurring_invoicing_type = "post-paid"
|
||||||
|
cls.acct_line.date_end = "2018-03-15"
|
||||||
|
cls.contract2.unlink()
|
||||||
|
|
||||||
|
def test_contract_manually_create_invoice(self):
|
||||||
|
|
||||||
|
contracts = self.contract
|
||||||
|
for _i in range(10):
|
||||||
|
contracts |= self.contract.copy()
|
||||||
|
wizard = self.env["contract.manually.create.invoice"].create(
|
||||||
|
{"invoice_date": self.today}
|
||||||
|
)
|
||||||
|
wizard.action_show_contract_to_invoice()
|
||||||
|
contract_to_invoice_count = wizard.contract_to_invoice_count
|
||||||
|
self.assertFalse(
|
||||||
|
contracts
|
||||||
|
- self.env["contract.contract"].search(
|
||||||
|
wizard.action_show_contract_to_invoice()["domain"]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
action = wizard.create_invoice()
|
||||||
|
invoice_lines = self.env["account.move.line"].search(
|
||||||
|
[("contract_line_id", "in", contracts.mapped("contract_line_ids").ids)]
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
len(contracts.mapped("contract_line_ids")),
|
||||||
|
len(invoice_lines),
|
||||||
|
)
|
||||||
|
invoices = self.env["account.move"].search(action["domain"])
|
||||||
|
self.assertFalse(invoice_lines.mapped("move_id") - invoices)
|
||||||
|
self.assertEqual(len(invoices), contract_to_invoice_count)
|
||||||
|
|
||||||
|
def test_contract_manually_create_invoice_with_usererror(self):
|
||||||
|
|
||||||
|
contracts = self.contract
|
||||||
|
|
||||||
|
accounts = self.product_1.product_tmpl_id.get_product_accounts()
|
||||||
|
accounts["income"].deprecated = True # To trigger a UserError
|
||||||
|
|
||||||
|
for _i in range(3):
|
||||||
|
contracts |= self.contract.copy()
|
||||||
|
wizard = self.env["contract.manually.create.invoice"].create(
|
||||||
|
{"invoice_date": self.acct_line.date_end}
|
||||||
|
)
|
||||||
|
|
||||||
|
with self.assertRaises(UserError):
|
||||||
|
# The UserError re-raise a UserError
|
||||||
|
wizard.create_invoice()
|
||||||
|
|
||||||
|
try:
|
||||||
|
wizard.create_invoice()
|
||||||
|
except Exception as e:
|
||||||
|
# The re-raised UserError message is the modified one.
|
||||||
|
self.assertTrue(str(e).startswith("Failed to process the contract"))
|
||||||
@@ -2,6 +2,13 @@
|
|||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo import _, api, fields, models
|
from odoo import _, api, fields, models
|
||||||
|
from odoo.exceptions import (
|
||||||
|
AccessDenied,
|
||||||
|
AccessError,
|
||||||
|
MissingError,
|
||||||
|
UserError,
|
||||||
|
ValidationError,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ContractManuallyCreateInvoice(models.TransientModel):
|
class ContractManuallyCreateInvoice(models.TransientModel):
|
||||||
@@ -52,7 +59,24 @@ class ContractManuallyCreateInvoice(models.TransientModel):
|
|||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
invoices = self.env["account.move"]
|
invoices = self.env["account.move"]
|
||||||
for contract in self.contract_to_invoice_ids:
|
for contract in self.contract_to_invoice_ids:
|
||||||
invoices |= contract.recurring_create_invoice()
|
try:
|
||||||
|
invoices |= contract.recurring_create_invoice()
|
||||||
|
except (
|
||||||
|
AccessDenied,
|
||||||
|
AccessError,
|
||||||
|
MissingError,
|
||||||
|
UserError,
|
||||||
|
ValidationError,
|
||||||
|
) as oe:
|
||||||
|
raise UserError(
|
||||||
|
_(
|
||||||
|
"Failed to process the contract %(name)s [id: %(id)s]:\n%(ue)s",
|
||||||
|
name=contract.name,
|
||||||
|
id=contract.id,
|
||||||
|
ue=repr(oe),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"type": "ir.actions.act_window",
|
"type": "ir.actions.act_window",
|
||||||
"name": _("Invoices"),
|
"name": _("Invoices"),
|
||||||
|
|||||||
Reference in New Issue
Block a user