mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-13 11:55:11 +00:00
Co-authored-by: Ravibharathi <131471282+ravibharathi656@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.tests import IntegrationTestCase
|
from frappe.tests import IntegrationTestCase
|
||||||
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.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
||||||
from erpnext.accounts.report.accounts_payable.accounts_payable import execute
|
from erpnext.accounts.report.accounts_payable.accounts_payable import execute
|
||||||
@@ -57,3 +57,66 @@ class TestAccountsPayable(AccountsTestMixin, IntegrationTestCase):
|
|||||||
if not do_not_submit:
|
if not do_not_submit:
|
||||||
pi = pi.submit()
|
pi = pi.submit()
|
||||||
return pi
|
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])
|
||||||
|
|||||||
@@ -1035,9 +1035,8 @@ class ReceivablePayableReport:
|
|||||||
self,
|
self,
|
||||||
):
|
):
|
||||||
self.customer = qb.DocType("Customer")
|
self.customer = qb.DocType("Customer")
|
||||||
|
|
||||||
if self.filters.get("customer_group"):
|
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 = (
|
customers = (
|
||||||
qb.from_(self.customer)
|
qb.from_(self.customer)
|
||||||
.select(self.customer.name)
|
.select(self.customer.name)
|
||||||
@@ -1049,14 +1048,18 @@ class ReceivablePayableReport:
|
|||||||
self.get_hierarchical_filters("Territory", "territory")
|
self.get_hierarchical_filters("Territory", "territory")
|
||||||
|
|
||||||
if self.filters.get("payment_terms_template"):
|
if self.filters.get("payment_terms_template"):
|
||||||
self.qb_selection_filter.append(
|
customer_ptt = self.ple.party.isin(
|
||||||
self.ple.party.isin(
|
qb.from_(self.customer)
|
||||||
qb.from_(self.customer)
|
.select(self.customer.name)
|
||||||
.select(self.customer.name)
|
.where(self.customer.payment_terms == self.filters.get("payment_terms_template"))
|
||||||
.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"):
|
if self.filters.get("sales_partner"):
|
||||||
self.qb_selection_filter.append(
|
self.qb_selection_filter.append(
|
||||||
self.ple.party.isin(
|
self.ple.party.isin(
|
||||||
@@ -1081,14 +1084,53 @@ class ReceivablePayableReport:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if self.filters.get("payment_terms_template"):
|
if self.filters.get("payment_terms_template"):
|
||||||
self.qb_selection_filter.append(
|
supplier_ptt = self.ple.party.isin(
|
||||||
self.ple.party.isin(
|
qb.from_(supplier)
|
||||||
qb.from_(supplier)
|
.select(supplier.name)
|
||||||
.select(supplier.name)
|
.where(supplier.payment_terms == self.filters.get("payment_terms_template"))
|
||||||
.where(supplier.payment_terms == self.filters.get("supplier_group"))
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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):
|
def get_hierarchical_filters(self, doctype, key):
|
||||||
lft, rgt = frappe.db.get_value(doctype, self.filters.get(key), ["lft", "rgt"])
|
lft, rgt = frappe.db.get_value(doctype, self.filters.get(key), ["lft", "rgt"])
|
||||||
|
|
||||||
@@ -1330,20 +1372,26 @@ class ReceivablePayableReport:
|
|||||||
self.err_journals = [x[0] for x in results] if results else []
|
self.err_journals = [x[0] for x in results] if results else []
|
||||||
|
|
||||||
|
|
||||||
def get_customer_group_with_children(customer_groups):
|
def get_party_group_with_children(party, party_groups):
|
||||||
if not isinstance(customer_groups, list):
|
if party not in ("Customer", "Supplier"):
|
||||||
customer_groups = [d.strip() for d in customer_groups.strip().split(",") if d]
|
return []
|
||||||
|
|
||||||
all_customer_groups = []
|
group_dtype = f"{party} Group"
|
||||||
for d in customer_groups:
|
if not isinstance(party_groups, list):
|
||||||
if frappe.db.exists("Customer Group", d):
|
party_groups = [d.strip() for d in party_groups.strip().split(",") if d]
|
||||||
lft, rgt = frappe.db.get_value("Customer Group", d, ["lft", "rgt"])
|
|
||||||
children = frappe.get_all("Customer Group", filters={"lft": [">=", lft], "rgt": ["<=", rgt]})
|
all_party_groups = []
|
||||||
all_customer_groups += [c.name for c in children]
|
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:
|
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:
|
class InitSQLProceduresForAR:
|
||||||
|
|||||||
@@ -1139,3 +1139,66 @@ class TestAccountsReceivable(AccountsTestMixin, IntegrationTestCase):
|
|||||||
self.assertEqual(len(report[1]), 1)
|
self.assertEqual(len(report[1]), 1)
|
||||||
row = report[1][0]
|
row = report[1][0]
|
||||||
self.assertEqual(expected_data_after_payment, [row.voucher_no, row.cost_center, row.outstanding])
|
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