Skip to content

Commit

Permalink
[IMP] account_invoice_overdue_warn: filter by delay lines
Browse files Browse the repository at this point in the history
  • Loading branch information
CristianoMafraJunior committed Mar 27, 2024
1 parent edf1a0c commit 58a3e12
Show file tree
Hide file tree
Showing 3 changed files with 290 additions and 26 deletions.
64 changes: 38 additions & 26 deletions account_invoice_overdue_warn/models/res_partner.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Copyright 2021 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <[email protected]>
# Copyright 2024 Engenere.one
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import fields, models
Expand Down Expand Up @@ -32,43 +33,54 @@ def _compute_overdue_invoice_count_amount(self):
partner.overdue_invoice_count = count
partner.overdue_invoice_amount = amount_company_currency

def _prepare_overdue_invoice_count_amount(self, company_id):
# This method is also called by the module
# account_invoice_overdue_warn_sale where the company_id arg is used
self.ensure_one()
domain = self._prepare_overdue_invoice_domain(company_id)
# amount_residual_signed is in company currency
rg_res = self.env["account.move"].read_group(
domain, ["amount_residual_signed"], []
)
count = 0
overdue_invoice_amount = 0.0
if rg_res:
count = rg_res[0]["__count"]
overdue_invoice_amount = rg_res[0]["amount_residual_signed"]
return (count, overdue_invoice_amount)

def _prepare_overdue_invoice_domain(self, company_id):
# The use of commercial_partner_id is in this method
self.ensure_one()
today = fields.Date.context_today(self)
if company_id is None:
company_id = self.env.company.id
domain = [
("move_type", "=", "out_invoice"),
("company_id", "=", company_id),
("commercial_partner_id", "=", self.commercial_partner_id.id),
("invoice_date_due", "<", today),
("state", "=", "posted"),
("payment_state", "in", ("not_paid", "partial")),
overdue_move_lines_domain = [
("move_id.company_id", "=", company_id),
("move_id.commercial_partner_id", "=", self.commercial_partner_id.id),
("date_maturity", "<", today),
("move_id.state", "=", "posted"),
("reconciled", "=", False),
("account_internal_type", "=", "receivable"),
]
return domain
overdue_move_lines = self.env["account.move.line"].search(
overdue_move_lines_domain
)
overdue_invoice_ids = overdue_move_lines.mapped("move_id").ids
overdue_invoice_domain = [("id", "in", overdue_invoice_ids)]
return overdue_invoice_domain

def _prepare_overdue_invoice_count_amount(self, company_id):
self.ensure_one()
overdue_invoice_domain = self._prepare_overdue_invoice_domain(company_id)
overdue_invoices = self.env["account.move"].search(overdue_invoice_domain)

overdue_invoice_ids = set()
overdue_invoice_amount = 0

for invoice in overdue_invoices:
for line in invoice.line_ids:
if (
line.date_maturity
and line.date_maturity < fields.Date.today()
and not line.reconciled
):
overdue_invoice_ids.add(invoice.id)
overdue_invoice_amount += line.amount_residual

count = len(overdue_invoice_ids)

return count, overdue_invoice_amount

def _prepare_jump_to_overdue_invoices(self, company_id):
action = self.env["ir.actions.actions"]._for_xml_id(
"account.action_move_out_invoice_type"
)
action["domain"] = self._prepare_overdue_invoice_domain(company_id)
overdue_invoice_domain = self._prepare_overdue_invoice_domain(company_id)
action["domain"] = overdue_invoice_domain
action["context"] = {
"journal_type": "sale",
"move_type": "out_invoice",
Expand Down
1 change: 1 addition & 0 deletions account_invoice_overdue_warn/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from . import test_overdue_warn
from . import test_overdue_warn_portion
251 changes: 251 additions & 0 deletions account_invoice_overdue_warn/tests/test_overdue_warn_portion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
# Copyright 2024 Engenere.one
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from datetime import datetime, timedelta

from odoo.tests import Form, tagged
from odoo.tests.common import TransactionCase


@tagged("post_install", "-at_install")
class TestOverdueWarn(TransactionCase):
def setUp(self):
super().setUp()
self.company = self.env.ref("base.main_company")
self.partner = self.env["res.partner"].create(
{
"name": "Teste Partner",
"country_id": self.env.ref("base.br").id,
"company_id": self.company.id,
}
)
self.today = datetime.now().date()
self.revenue_acc = self.env["account.account"].search(
[
("company_id", "=", self.company.id),
(
"user_type_id",
"=",
self.env.ref("account.data_account_type_revenue").id,
),
],
limit=1,
)

def test_late_draft_invoice(self):
out_invoice_sketch = self.env["account.move"].create(
{
"partner_id": self.partner.id,
"move_type": "out_invoice",
"company_id": self.company.id,
"currency_id": self.company.currency_id.id,
"invoice_date": self.today - timedelta(days=5),
"invoice_date_due": self.today - timedelta(days=5),
"invoice_line_ids": [
(
0,
0,
{
"name": "test line",
"price_unit": 500,
"quantity": 1,
"account_id": self.revenue_acc.id,
},
)
],
}
)
self.assertEqual(out_invoice_sketch.state, "draft")
self.assertEqual(self.partner.overdue_invoice_count, 0)
self.assertEqual(self.partner.overdue_invoice_amount, 0.0)

def test_confirmed_supplier_invoice(self):
out_invoice_supplier = self.env["account.move"].create(
{
"partner_id": self.partner.id,
"move_type": "in_invoice",
"company_id": self.company.id,
"currency_id": self.company.currency_id.id,
"invoice_date": self.today - timedelta(days=5),
"invoice_date_due": self.today - timedelta(days=5),
"invoice_line_ids": [
(
0,
0,
{
"name": "test line",
"price_unit": 500,
"quantity": 1,
"account_id": self.revenue_acc.id,
},
)
],
}
)
out_invoice_supplier.action_post()
self.assertEqual(self.partner.overdue_invoice_count, 0)
self.assertEqual(self.partner.overdue_invoice_amount, 0.0)

def test_mixed_case_with_two_invoices(self):

out_invoice_a = self.env["account.move"].create(
{
"partner_id": self.partner.id,
"move_type": "out_invoice",
"company_id": self.company.id,
"currency_id": self.company.currency_id.id,
"invoice_date": self.today - timedelta(days=10),
"invoice_date_due": self.today - timedelta(days=10),
"invoice_line_ids": [
(
0,
0,
{
"name": "Portion 1",
"price_unit": 300,
"quantity": 1,
"account_id": self.revenue_acc.id,
"date_maturity": self.today - timedelta(days=9),
},
),
(
0,
0,
{
"name": "Portion 2",
"price_unit": 300,
"quantity": 1,
"account_id": self.revenue_acc.id,
"date_maturity": self.today - timedelta(days=9),
},
),
(
0,
0,
{
"name": "Portion 3",
"price_unit": 300,
"quantity": 1,
"account_id": self.revenue_acc.id,
"date_maturity": self.today - timedelta(days=9),
},
),
],
}
)
out_invoice_a.action_post()

out_invoice_b = self.env["account.move"].create(
{
"partner_id": self.partner.id,
"move_type": "out_invoice",
"company_id": self.company.id,
"currency_id": self.company.currency_id.id,
"invoice_date": self.today - timedelta(days=10),
"invoice_date_due": self.today - timedelta(days=10),
"invoice_line_ids": [
(
0,
0,
{
"name": "Portion 1",
"price_unit": 300,
"quantity": 1,
"account_id": self.revenue_acc.id,
"date_maturity": self.today - timedelta(days=9),
},
),
(
0,
0,
{
"name": "Portion 2",
"price_unit": 300,
"quantity": 1,
"account_id": self.revenue_acc.id,
"date_maturity": self.today - timedelta(days=9),
},
),
(
0,
0,
{
"name": "Portion 3",
"price_unit": 300,
"quantity": 1,
"account_id": self.revenue_acc.id,
"date_maturity": self.today + timedelta(days=20),
},
),
],
}
)
out_invoice_b.action_post()

action_data_a = out_invoice_a.action_register_payment()
wizard_a = Form(
self.env["account.payment.register"].with_context(action_data_a["context"])
).save()
wizard_a.amount = 450.0
wizard_a.action_create_payments()

self.assertEqual(self.partner.overdue_invoice_count, 2)
self.assertEqual(self.partner.overdue_invoice_amount, 1050.0)

def test_confirmed_invoice_with_past_date(self):
out_invoice_past_paid = self.env["account.move"].create(
{
"partner_id": self.partner.id,
"move_type": "out_invoice",
"company_id": self.company.id,
"currency_id": self.company.currency_id.id,
"invoice_date": self.today - timedelta(days=5),
"invoice_date_due": self.today - timedelta(days=5),
"invoice_line_ids": [
(
0,
0,
{
"name": "test line",
"price_unit": 500.0,
"quantity": 1,
"account_id": self.revenue_acc.id,
},
)
],
}
)
out_invoice_past_paid.action_post()
action_data = out_invoice_past_paid.action_register_payment()
wizard = Form(
self.env["account.payment.register"].with_context(action_data["context"])
).save()
wizard.action_create_payments()
self.assertEqual(self.partner.overdue_invoice_count, 0)
self.assertEqual(self.partner.overdue_invoice_amount, 0)

def test_confirmed_invoice_with_future_date_unpaid(self):
out_invoice_future = self.env["account.move"].create(
{
"partner_id": self.partner.id,
"move_type": "out_invoice",
"company_id": self.company.id,
"currency_id": self.company.currency_id.id,
"invoice_date": self.today + timedelta(days=5),
"invoice_date_due": self.today + timedelta(days=10),
"invoice_line_ids": [
(
0,
0,
{
"name": "test line",
"price_unit": 500,
"quantity": 1,
"account_id": self.revenue_acc.id,
},
)
],
}
)
out_invoice_future.action_post()
self.assertEqual(self.partner.overdue_invoice_count, 0)
self.assertEqual(self.partner.overdue_invoice_amount, 0)

0 comments on commit 58a3e12

Please sign in to comment.