mirror of
https://github.com/frappe/erpnext.git
synced 2026-03-23 05:04:52 +01:00
Co-authored-by: Ravibharathi <131471282+ravibharathi656@users.noreply.github.com> Co-authored-by: diptanilsaha <diptanil@frappe.io>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import today
|
||||
from frappe.utils import add_days, today
|
||||
|
||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
||||
from erpnext.accounts.report.accounts_payable.accounts_payable import execute
|
||||
@@ -57,3 +57,66 @@ class TestAccountsPayable(AccountsTestMixin, FrappeTestCase):
|
||||
if not do_not_submit:
|
||||
pi = pi.submit()
|
||||
return pi
|
||||
|
||||
def test_payment_terms_template_filters(self):
|
||||
from erpnext.controllers.accounts_controller import get_payment_terms
|
||||
|
||||
payment_term1 = frappe.get_doc(
|
||||
{"doctype": "Payment Term", "payment_term_name": "_Test 50% on 15 Days"}
|
||||
).insert()
|
||||
payment_term2 = frappe.get_doc(
|
||||
{"doctype": "Payment Term", "payment_term_name": "_Test 50% on 30 Days"}
|
||||
).insert()
|
||||
|
||||
template = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Payment Terms Template",
|
||||
"template_name": "_Test 50-50",
|
||||
"terms": [
|
||||
{
|
||||
"doctype": "Payment Terms Template Detail",
|
||||
"due_date_based_on": "Day(s) after invoice date",
|
||||
"payment_term": payment_term1.name,
|
||||
"description": "_Test 50-50",
|
||||
"invoice_portion": 50,
|
||||
"credit_days": 15,
|
||||
},
|
||||
{
|
||||
"doctype": "Payment Terms Template Detail",
|
||||
"due_date_based_on": "Day(s) after invoice date",
|
||||
"payment_term": payment_term2.name,
|
||||
"description": "_Test 50-50",
|
||||
"invoice_portion": 50,
|
||||
"credit_days": 30,
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
template.insert()
|
||||
|
||||
filters = {
|
||||
"company": self.company,
|
||||
"report_date": today(),
|
||||
"range": "30, 60, 90, 120",
|
||||
"based_on_payment_terms": 1,
|
||||
"payment_terms_template": template.name,
|
||||
"ageing_based_on": "Posting Date",
|
||||
}
|
||||
|
||||
pi = self.create_purchase_invoice(do_not_submit=True)
|
||||
pi.payment_terms_template = template.name
|
||||
schedule = get_payment_terms(template.name)
|
||||
pi.set("payment_schedule", [])
|
||||
|
||||
for row in schedule:
|
||||
row["due_date"] = add_days(pi.posting_date, row.get("credit_days", 0))
|
||||
pi.append("payment_schedule", row)
|
||||
|
||||
pi.save()
|
||||
pi.submit()
|
||||
|
||||
report = execute(filters)
|
||||
row = report[1][0]
|
||||
|
||||
self.assertEqual(len(report[1]), 2)
|
||||
self.assertEqual([pi.name, payment_term1.payment_term_name], [row.voucher_no, row.payment_term])
|
||||
|
||||
@@ -1029,9 +1029,8 @@ class ReceivablePayableReport:
|
||||
self,
|
||||
):
|
||||
self.customer = qb.DocType("Customer")
|
||||
|
||||
if self.filters.get("customer_group"):
|
||||
groups = get_customer_group_with_children(self.filters.customer_group)
|
||||
groups = get_party_group_with_children("Customer", self.filters.customer_group)
|
||||
customers = (
|
||||
qb.from_(self.customer)
|
||||
.select(self.customer.name)
|
||||
@@ -1043,14 +1042,18 @@ class ReceivablePayableReport:
|
||||
self.get_hierarchical_filters("Territory", "territory")
|
||||
|
||||
if self.filters.get("payment_terms_template"):
|
||||
self.qb_selection_filter.append(
|
||||
self.ple.party.isin(
|
||||
qb.from_(self.customer)
|
||||
.select(self.customer.name)
|
||||
.where(self.customer.payment_terms == self.filters.get("payment_terms_template"))
|
||||
)
|
||||
customer_ptt = self.ple.party.isin(
|
||||
qb.from_(self.customer)
|
||||
.select(self.customer.name)
|
||||
.where(self.customer.payment_terms == self.filters.get("payment_terms_template"))
|
||||
)
|
||||
|
||||
si_ptt = self.add_payment_term_template_filters("Sales Invoice")
|
||||
|
||||
sales_ptt = self.ple.against_voucher_no.isin(si_ptt)
|
||||
|
||||
self.qb_selection_filter.append(Criterion.any([customer_ptt, sales_ptt]))
|
||||
|
||||
if self.filters.get("sales_partner"):
|
||||
self.qb_selection_filter.append(
|
||||
self.ple.party.isin(
|
||||
@@ -1075,14 +1078,53 @@ class ReceivablePayableReport:
|
||||
)
|
||||
|
||||
if self.filters.get("payment_terms_template"):
|
||||
self.qb_selection_filter.append(
|
||||
self.ple.party.isin(
|
||||
qb.from_(supplier)
|
||||
.select(supplier.name)
|
||||
.where(supplier.payment_terms == self.filters.get("supplier_group"))
|
||||
)
|
||||
supplier_ptt = self.ple.party.isin(
|
||||
qb.from_(supplier)
|
||||
.select(supplier.name)
|
||||
.where(supplier.payment_terms == self.filters.get("payment_terms_template"))
|
||||
)
|
||||
|
||||
pi_ptt = self.add_payment_term_template_filters("Purchase Invoice")
|
||||
|
||||
purchase_ptt = self.ple.against_voucher_no.isin(pi_ptt)
|
||||
|
||||
self.qb_selection_filter.append(Criterion.any([supplier_ptt, purchase_ptt]))
|
||||
|
||||
def add_payment_term_template_filters(self, dtype):
|
||||
voucher_type = qb.DocType(dtype)
|
||||
|
||||
ptt = (
|
||||
qb.from_(voucher_type)
|
||||
.select(voucher_type.name)
|
||||
.where(voucher_type.payment_terms_template == self.filters.get("payment_terms_template"))
|
||||
.where(voucher_type.company == self.filters.company)
|
||||
)
|
||||
|
||||
if dtype == "Purchase Invoice":
|
||||
party = "Supplier"
|
||||
party_group_type = "supplier_group"
|
||||
acc_type = "credit_to"
|
||||
else:
|
||||
party = "Customer"
|
||||
party_group_type = "customer_group"
|
||||
acc_type = "debit_to"
|
||||
|
||||
if self.filters.get(party_group_type):
|
||||
party_groups = get_party_group_with_children(party, self.filters.get(party_group_type))
|
||||
ptt = ptt.where((voucher_type[party_group_type]).isin(party_groups))
|
||||
|
||||
if self.filters.party:
|
||||
ptt = ptt.where((voucher_type[party.lower()]).isin(self.filters.party))
|
||||
|
||||
if self.filters.cost_center:
|
||||
cost_centers = get_cost_centers_with_children(self.filters.cost_center)
|
||||
ptt = ptt.where(voucher_type.cost_center.isin(cost_centers))
|
||||
|
||||
if self.filters.party_account:
|
||||
ptt = ptt.where(voucher_type[acc_type] == self.filters.party_account)
|
||||
|
||||
return ptt
|
||||
|
||||
def get_hierarchical_filters(self, doctype, key):
|
||||
lft, rgt = frappe.db.get_value(doctype, self.filters.get(key), ["lft", "rgt"])
|
||||
|
||||
@@ -1320,20 +1362,26 @@ class ReceivablePayableReport:
|
||||
self.err_journals = [x[0] for x in results] if results else []
|
||||
|
||||
|
||||
def get_customer_group_with_children(customer_groups):
|
||||
if not isinstance(customer_groups, list):
|
||||
customer_groups = [d.strip() for d in customer_groups.strip().split(",") if d]
|
||||
def get_party_group_with_children(party, party_groups):
|
||||
if party not in ("Customer", "Supplier"):
|
||||
return []
|
||||
|
||||
all_customer_groups = []
|
||||
for d in customer_groups:
|
||||
if frappe.db.exists("Customer Group", d):
|
||||
lft, rgt = frappe.db.get_value("Customer Group", d, ["lft", "rgt"])
|
||||
children = frappe.get_all("Customer Group", filters={"lft": [">=", lft], "rgt": ["<=", rgt]})
|
||||
all_customer_groups += [c.name for c in children]
|
||||
group_dtype = f"{party} Group"
|
||||
if not isinstance(party_groups, list):
|
||||
party_groups = [d.strip() for d in party_groups.strip().split(",") if d]
|
||||
|
||||
all_party_groups = []
|
||||
for d in party_groups:
|
||||
if frappe.db.exists(group_dtype, d):
|
||||
lft, rgt = frappe.db.get_value(group_dtype, d, ["lft", "rgt"])
|
||||
children = frappe.get_all(
|
||||
group_dtype, filters={"lft": [">=", lft], "rgt": ["<=", rgt]}, pluck="name"
|
||||
)
|
||||
all_party_groups += children
|
||||
else:
|
||||
frappe.throw(_("Customer Group: {0} does not exist").format(d))
|
||||
frappe.throw(_("{0}: {1} does not exist").format(group_dtype, d))
|
||||
|
||||
return list(set(all_customer_groups))
|
||||
return list(set(all_party_groups))
|
||||
|
||||
|
||||
class InitSQLProceduresForAR:
|
||||
|
||||
@@ -1139,3 +1139,66 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase):
|
||||
self.assertEqual(len(report[1]), 1)
|
||||
row = report[1][0]
|
||||
self.assertEqual(expected_data_after_payment, [row.voucher_no, row.cost_center, row.outstanding])
|
||||
|
||||
def test_payment_terms_template_filters(self):
|
||||
from erpnext.controllers.accounts_controller import get_payment_terms
|
||||
|
||||
payment_term1 = frappe.get_doc(
|
||||
{"doctype": "Payment Term", "payment_term_name": "_Test 50% on 15 Days"}
|
||||
).insert()
|
||||
payment_term2 = frappe.get_doc(
|
||||
{"doctype": "Payment Term", "payment_term_name": "_Test 50% on 30 Days"}
|
||||
).insert()
|
||||
|
||||
template = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Payment Terms Template",
|
||||
"template_name": "_Test 50-50",
|
||||
"terms": [
|
||||
{
|
||||
"doctype": "Payment Terms Template Detail",
|
||||
"due_date_based_on": "Day(s) after invoice date",
|
||||
"payment_term": payment_term1.name,
|
||||
"description": "_Test 50-50",
|
||||
"invoice_portion": 50,
|
||||
"credit_days": 15,
|
||||
},
|
||||
{
|
||||
"doctype": "Payment Terms Template Detail",
|
||||
"due_date_based_on": "Day(s) after invoice date",
|
||||
"payment_term": payment_term2.name,
|
||||
"description": "_Test 50-50",
|
||||
"invoice_portion": 50,
|
||||
"credit_days": 30,
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
template.insert()
|
||||
|
||||
filters = {
|
||||
"company": self.company,
|
||||
"report_date": today(),
|
||||
"range": "30, 60, 90, 120",
|
||||
"based_on_payment_terms": 1,
|
||||
"payment_terms_template": template.name,
|
||||
"ageing_based_on": "Posting Date",
|
||||
}
|
||||
|
||||
si = self.create_sales_invoice(no_payment_schedule=True, do_not_submit=True)
|
||||
si.payment_terms_template = template.name
|
||||
schedule = get_payment_terms(template.name)
|
||||
si.set("payment_schedule", [])
|
||||
|
||||
for row in schedule:
|
||||
row["due_date"] = add_days(si.posting_date, row.get("credit_days", 0))
|
||||
si.append("payment_schedule", row)
|
||||
|
||||
si.save()
|
||||
si.submit()
|
||||
|
||||
report = execute(filters)
|
||||
row = report[1][0]
|
||||
|
||||
self.assertEqual(len(report[1]), 2)
|
||||
self.assertEqual([si.name, payment_term1.payment_term_name], [row.voucher_no, row.payment_term])
|
||||
|
||||
Reference in New Issue
Block a user