Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMP] account_invoice_overdue_warn: filtrar parcelas em atraso #1

Open
wants to merge 1 commit into
base: 14.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 35 additions & 17 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,60 @@ def _compute_overdue_invoice_count_amount(self):
partner.overdue_invoice_count = count
partner.overdue_invoice_amount = amount_company_currency

def _get_overdue_move_lines(self, company_id):
domain = self._prepare_overdue_move_lines_domain(company_id)
overdue_move_lines = self.env["account.move.line"].search(domain)
return overdue_move_lines

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"], []
# amount_residual is in company currency
overdue_move_lines = self._get_overdue_move_lines(company_id)
overdue_invoice_amount = self._compute_overdue_move_lines_total(
overdue_move_lines
)
count = 0
overdue_invoice_amount = 0.0
if rg_res:
count = rg_res[0]["__count"]
overdue_invoice_amount = rg_res[0]["amount_residual_signed"]
count = self._count_unique_invoices(overdue_move_lines)
return (count, overdue_invoice_amount)

def _prepare_overdue_invoice_domain(self, company_id):
def _prepare_overdue_move_lines_domain(self, company_id):
# The use of commercial_partner_id is in this method
CristianoMafraJunior marked this conversation as resolved.
Show resolved Hide resolved
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")),
("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"),
("amount_residual", "!=", 0.0),
]
return domain

def _compute_overdue_move_lines_total(self, overdue_move_lines):
return sum(overdue_move_lines.mapped("amount_residual"))

def _get_unique_invoices_id_list(self, overdue_move_lines):
return overdue_move_lines.mapped("move_id").ids

def _count_unique_invoices(self, overdue_move_lines):
unique_invoices = self._get_unique_invoices_id_list(overdue_move_lines)
return len(unique_invoices)

def _prepare_invoice_domain(self, invoice_ids):
return [("id", "in", invoice_ids)]

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_move_lines = self._get_overdue_move_lines(company_id)
unique_invoice_ids = self._get_unique_invoices_id_list(overdue_move_lines)
action["domain"] = self._prepare_invoice_domain(unique_invoice_ids)
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_installment
309 changes: 309 additions & 0 deletions account_invoice_overdue_warn/tests/test_overdue_warn_installment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,309 @@
# 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": "Test 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,
)

self.payment_term = self.env["account.payment.term"].create(
{
"name": "Immediate payment",
"line_ids": [
(
0,
0,
{
"value": "balance",
"days": 0,
},
),
],
}
)

self.payment_term_installments_a = self.env["account.payment.term"].create(
{
"name": "Pay in 3 installments",
"line_ids": [
(
0,
0,
{
"value": "percent",
"value_amount": 33.33,
"days": 0,
},
),
(
0,
0,
{
"value": "percent",
"value_amount": 33.33,
"days": 0,
},
),
(
0,
0,
{
"value": "balance",
"days": 0,
},
),
],
}
)

self.payment_term_installments_b = self.env["account.payment.term"].create(
{
"name": "Pay in 3 installments",
"line_ids": [
(
0,
0,
{
"value": "percent",
"value_amount": 33.33,
"days": 0,
},
),
(
0,
0,
{
"value": "percent",
"value_amount": 33.33,
"days": 0,
},
),
(
0,
0,
{
"value": "balance",
"days": 14,
},
),
],
}
)

def test_out_invoice_draft(self):
out_invoice_draft = 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=9),
"invoice_payment_term_id": self.payment_term.id,
"invoice_line_ids": [
(
0,
0,
{
"name": "Product Test",
"price_unit": 500,
"quantity": 1,
"account_id": self.revenue_acc.id,
},
)
],
}
)
self.assertEqual(
out_invoice_draft.invoice_date_due,
out_invoice_draft.line_ids[1].date_maturity,
)
self.assertEqual(out_invoice_draft.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=9),
"invoice_payment_term_id": self.payment_term.id,
"invoice_line_ids": [
(
0,
0,
{
"name": "Product Test",
"price_unit": 500,
"quantity": 1,
"account_id": self.revenue_acc.id,
},
)
],
}
)
out_invoice_supplier.action_post()
self.assertEqual(
out_invoice_supplier.invoice_date_due,
out_invoice_supplier.line_ids[1].date_maturity,
)
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_payment_term_id": self.payment_term_installments_a.id,
"invoice_line_ids": [
(
0,
0,
{
"name": "Product Test",
"price_unit": 900,
"quantity": 1,
"account_id": self.revenue_acc.id,
},
),
],
}
)
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_payment_term_id": self.payment_term_installments_b.id,
"invoice_line_ids": [
(
0,
0,
{
"name": "Product Test",
"price_unit": 900,
"quantity": 1,
"account_id": self.revenue_acc.id,
},
),
],
}
)
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(
out_invoice_b.invoice_date_due,
out_invoice_b.line_ids[3].date_maturity,
)
self.assertEqual(self.partner.overdue_invoice_count, 2)
CristianoMafraJunior marked this conversation as resolved.
Show resolved Hide resolved
self.assertEqual(self.partner.overdue_invoice_amount, 1049.94)

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_payment_term_id": self.payment_term.id,
"invoice_line_ids": [
(
0,
0,
{
"name": "Product Test",
"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()
CristianoMafraJunior marked this conversation as resolved.
Show resolved Hide resolved
self.assertEqual(
out_invoice_past_paid.invoice_date_due,
out_invoice_past_paid.line_ids[1].date_maturity,
)
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_payment_term_id": self.payment_term.id,
"invoice_line_ids": [
(
0,
0,
{
"name": "Product Test",
"price_unit": 500,
"quantity": 1,
"account_id": self.revenue_acc.id,
},
)
],
}
)
out_invoice_future.action_post()
self.assertEqual(
out_invoice_future.invoice_date_due,
out_invoice_future.line_ids[1].date_maturity,
)
self.assertEqual(self.partner.overdue_invoice_count, 0)
self.assertEqual(self.partner.overdue_invoice_amount, 0)