mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-15 07:28:39 +00:00
Merge pull request #56144 from nabinhait/refactor-si-status
refactor(sales_invoice): simplify StatusService.set_status, cover set_indicator
This commit is contained in:
@@ -21,45 +21,52 @@ class StatusService:
|
||||
doc.status = "Draft"
|
||||
return
|
||||
|
||||
outstanding_amount = flt(doc.outstanding_amount, doc.precision("outstanding_amount"))
|
||||
total = get_total_in_party_account_currency(doc)
|
||||
|
||||
if not status:
|
||||
if doc.docstatus == 2:
|
||||
status = "Cancelled"
|
||||
elif doc.docstatus == 1:
|
||||
if doc.is_internal_transfer():
|
||||
doc.status = "Internal Transfer"
|
||||
elif is_overdue(doc, total):
|
||||
doc.status = "Overdue"
|
||||
elif 0 < outstanding_amount < total:
|
||||
doc.status = "Partly Paid"
|
||||
elif outstanding_amount > 0 and getdate(doc.due_date) >= getdate():
|
||||
doc.status = "Unpaid"
|
||||
elif doc.is_return == 0 and frappe.db.get_value(
|
||||
"Sales Invoice", {"is_return": 1, "return_against": doc.name, "docstatus": 1}
|
||||
):
|
||||
doc.status = "Credit Note Issued"
|
||||
elif doc.is_return == 1:
|
||||
doc.status = "Return"
|
||||
elif outstanding_amount <= 0:
|
||||
doc.status = "Paid"
|
||||
else:
|
||||
doc.status = "Submitted"
|
||||
|
||||
if (
|
||||
doc.status in ("Unpaid", "Partly Paid", "Overdue")
|
||||
and doc.is_discounted
|
||||
and get_discounting_status(doc.name) == "Disbursed"
|
||||
):
|
||||
doc.status += " and Discounted"
|
||||
|
||||
doc.status = self._get_submitted_status()
|
||||
else:
|
||||
doc.status = "Draft"
|
||||
|
||||
if update:
|
||||
doc.db_set("status", doc.status, update_modified=update_modified)
|
||||
|
||||
def _get_submitted_status(self) -> str:
|
||||
"""Status of a submitted invoice, with the invoice-discounting suffix applied."""
|
||||
doc = self.doc
|
||||
outstanding_amount = flt(doc.outstanding_amount, doc.precision("outstanding_amount"))
|
||||
total = get_total_in_party_account_currency(doc)
|
||||
|
||||
status = self._get_payment_status(outstanding_amount, total)
|
||||
if (
|
||||
status in ("Unpaid", "Partly Paid", "Overdue")
|
||||
and doc.is_discounted
|
||||
and get_discounting_status(doc.name) == "Disbursed"
|
||||
):
|
||||
status += " and Discounted"
|
||||
return status
|
||||
|
||||
def _get_payment_status(self, outstanding_amount: float, total: float) -> str:
|
||||
doc = self.doc
|
||||
if doc.is_internal_transfer():
|
||||
return "Internal Transfer"
|
||||
if is_overdue(doc, total):
|
||||
return "Overdue"
|
||||
if 0 < outstanding_amount < total:
|
||||
return "Partly Paid"
|
||||
if outstanding_amount > 0 and getdate(doc.due_date) >= getdate():
|
||||
return "Unpaid"
|
||||
if doc.is_return == 0 and frappe.db.get_value(
|
||||
"Sales Invoice", {"is_return": 1, "return_against": doc.name, "docstatus": 1}
|
||||
):
|
||||
return "Credit Note Issued"
|
||||
if doc.is_return == 1:
|
||||
return "Return"
|
||||
if outstanding_amount <= 0:
|
||||
return "Paid"
|
||||
return "Submitted"
|
||||
|
||||
def set_indicator(self) -> None:
|
||||
doc = self.doc
|
||||
if doc.outstanding_amount < 0:
|
||||
|
||||
@@ -3880,6 +3880,27 @@ class TestSalesInvoice(ERPNextTestSuite):
|
||||
|
||||
party_link.delete()
|
||||
|
||||
def test_status_indicator(self):
|
||||
from erpnext.accounts.doctype.sales_invoice.services.status import StatusService
|
||||
|
||||
si = create_sales_invoice(do_not_save=True)
|
||||
cases = [
|
||||
# outstanding, due_date, is_return -> indicator color, title
|
||||
(-50, nowdate(), 0, "gray", "Credit Note Issued"),
|
||||
(100, add_days(nowdate(), 5), 0, "orange", "Unpaid"),
|
||||
(100, add_days(nowdate(), -5), 0, "red", "Overdue"),
|
||||
(0, nowdate(), 1, "gray", "Return"),
|
||||
(0, nowdate(), 0, "green", "Paid"),
|
||||
]
|
||||
for outstanding, due_date, is_return, color, title in cases:
|
||||
with self.subTest(title=title):
|
||||
si.outstanding_amount = outstanding
|
||||
si.due_date = due_date
|
||||
si.is_return = is_return
|
||||
StatusService(si).set_indicator()
|
||||
self.assertEqual(si.indicator_color, color)
|
||||
self.assertEqual(si.indicator_title, title)
|
||||
|
||||
def test_payment_statuses(self):
|
||||
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
|
||||
|
||||
|
||||
Reference in New Issue
Block a user