Cleanup and fixes of payment terms feature
This commit is contained in:
parent
7fa111de45
commit
0551f7bb00
@ -505,12 +505,10 @@ def get_outstanding_reference_documents(args):
|
|||||||
company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency")
|
company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency")
|
||||||
|
|
||||||
# Get negative outstanding sales /purchase invoices
|
# Get negative outstanding sales /purchase invoices
|
||||||
total_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
|
|
||||||
|
|
||||||
negative_outstanding_invoices = []
|
negative_outstanding_invoices = []
|
||||||
if (args.get("party_type") != "Student"):
|
if args.get("party_type") not in ["Student", "Employee"]:
|
||||||
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"),
|
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"),
|
||||||
args.get("party"), args.get("party_account"), total_field)
|
args.get("party"), args.get("party_account"), party_account_currency, company_currency)
|
||||||
|
|
||||||
# Get positive outstanding sales /purchase invoices/ Fees
|
# Get positive outstanding sales /purchase invoices/ Fees
|
||||||
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
|
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
|
||||||
@ -580,28 +578,34 @@ def get_orders_to_be_billed(posting_date, party_type, party, party_account_curre
|
|||||||
|
|
||||||
return order_list
|
return order_list
|
||||||
|
|
||||||
def get_negative_outstanding_invoices(party_type, party, party_account, total_field):
|
def get_negative_outstanding_invoices(party_type, party, party_account, party_account_currency, company_currency):
|
||||||
if party_type != "Employee":
|
voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice"
|
||||||
voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice"
|
if party_account_currency == company_currency:
|
||||||
return frappe.db.sql("""
|
grand_total_field = "base_grand_total"
|
||||||
select
|
rounded_total_field = "base_rounded_total"
|
||||||
"{voucher_type}" as voucher_type, name as voucher_no,
|
|
||||||
{total_field} as invoice_amount, outstanding_amount, posting_date,
|
|
||||||
due_date, conversion_rate as exchange_rate
|
|
||||||
from
|
|
||||||
`tab{voucher_type}`
|
|
||||||
where
|
|
||||||
{party_type} = %s and {party_account} = %s and docstatus = 1 and outstanding_amount < 0
|
|
||||||
order by
|
|
||||||
posting_date, name
|
|
||||||
""".format(**{
|
|
||||||
"total_field": total_field,
|
|
||||||
"voucher_type": voucher_type,
|
|
||||||
"party_type": scrub(party_type),
|
|
||||||
"party_account": "debit_to" if party_type == "Customer" else "credit_to"
|
|
||||||
}), (party, party_account), as_dict=True)
|
|
||||||
else:
|
else:
|
||||||
return []
|
grand_total_field = "grand_total"
|
||||||
|
rounded_total_field = "rounded_total"
|
||||||
|
|
||||||
|
return frappe.db.sql("""
|
||||||
|
select
|
||||||
|
"{voucher_type}" as voucher_type, name as voucher_no,
|
||||||
|
if({rounded_total_field}, {rounded_total_field}, {grand_total_field}) as invoice_amount,
|
||||||
|
outstanding_amount, posting_date,
|
||||||
|
due_date, conversion_rate as exchange_rate
|
||||||
|
from
|
||||||
|
`tab{voucher_type}`
|
||||||
|
where
|
||||||
|
{party_type} = %s and {party_account} = %s and docstatus = 1 and outstanding_amount < 0
|
||||||
|
order by
|
||||||
|
posting_date, name
|
||||||
|
""".format(**{
|
||||||
|
"rounded_total_field": rounded_total_field,
|
||||||
|
"grand_total_field": grand_total_field,
|
||||||
|
"voucher_type": voucher_type,
|
||||||
|
"party_type": scrub(party_type),
|
||||||
|
"party_account": "debit_to" if party_type == "Customer" else "credit_to"
|
||||||
|
}), (party, party_account), as_dict=True)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_party_details(company, party_type, party, date):
|
def get_party_details(company, party_type, party, date):
|
||||||
@ -721,7 +725,10 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
|||||||
if party_amount:
|
if party_amount:
|
||||||
grand_total = outstanding_amount = party_amount
|
grand_total = outstanding_amount = party_amount
|
||||||
elif dt in ("Sales Invoice", "Purchase Invoice"):
|
elif dt in ("Sales Invoice", "Purchase Invoice"):
|
||||||
grand_total = doc.base_grand_total if party_account_currency == doc.company_currency else doc.grand_total
|
if party_account_currency == doc.company_currency:
|
||||||
|
grand_total = doc.base_rounded_total or doc.base_grand_total
|
||||||
|
else:
|
||||||
|
grand_total = doc.rounded_total or doc.grand_total
|
||||||
outstanding_amount = doc.outstanding_amount
|
outstanding_amount = doc.outstanding_amount
|
||||||
elif dt in ("Expense Claim"):
|
elif dt in ("Expense Claim"):
|
||||||
grand_total = doc.total_sanctioned_amount
|
grand_total = doc.total_sanctioned_amount
|
||||||
@ -730,8 +737,10 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
|||||||
grand_total = doc.grand_total
|
grand_total = doc.grand_total
|
||||||
outstanding_amount = doc.outstanding_amount
|
outstanding_amount = doc.outstanding_amount
|
||||||
else:
|
else:
|
||||||
total_field = "base_grand_total" if party_account_currency == doc.company_currency else "grand_total"
|
if party_account_currency == doc.company_currency:
|
||||||
grand_total = flt(doc.get(total_field))
|
grand_total = flt(doc.get("base_rounded_total") or doc.base_grand_total)
|
||||||
|
else:
|
||||||
|
grand_total = flt(doc.get("rounded_total") or doc.grand_total)
|
||||||
outstanding_amount = grand_total - flt(doc.advance_paid)
|
outstanding_amount = grand_total - flt(doc.advance_paid)
|
||||||
|
|
||||||
# bank or cash
|
# bank or cash
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
"label": "Due Date",
|
"label": "Due Date",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "payment_term.due_date",
|
"options": "",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
@ -129,7 +129,7 @@
|
|||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 1,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
@ -179,7 +179,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-09-26 05:13:54.187475",
|
"modified": "2017-11-21 19:23:08.490659",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Schedule",
|
"name": "Payment Schedule",
|
||||||
|
@ -255,6 +255,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
self.assertEqual(pi.outstanding_amount, 1212.30)
|
self.assertEqual(pi.outstanding_amount, 1212.30)
|
||||||
|
|
||||||
pi.disable_rounded_total = 0
|
pi.disable_rounded_total = 0
|
||||||
|
pi.get("payment_schedule")[0].payment_amount = 1512.0
|
||||||
pi.save()
|
pi.save()
|
||||||
self.assertEqual(pi.outstanding_amount, 1212.0)
|
self.assertEqual(pi.outstanding_amount, 1212.0)
|
||||||
|
|
||||||
@ -279,7 +280,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
jv.submit()
|
jv.submit()
|
||||||
|
|
||||||
pi = frappe.copy_doc(test_records[0])
|
pi = frappe.copy_doc(test_records[0])
|
||||||
|
pi.disable_rounded_total = 1
|
||||||
pi.append("advances", {
|
pi.append("advances", {
|
||||||
"reference_type": "Journal Entry",
|
"reference_type": "Journal Entry",
|
||||||
"reference_name": jv.name,
|
"reference_name": jv.name,
|
||||||
@ -290,9 +291,10 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
})
|
})
|
||||||
pi.insert()
|
pi.insert()
|
||||||
|
|
||||||
pi.update(
|
pi.update({
|
||||||
{"payment_schedule": get_payment_terms("_Test Payment Term Template", pi.posting_date, pi.grand_total)}
|
"payment_schedule": get_payment_terms("_Test Payment Term Template",
|
||||||
)
|
pi.posting_date, pi.grand_total)
|
||||||
|
})
|
||||||
|
|
||||||
pi.save()
|
pi.save()
|
||||||
pi.submit()
|
pi.submit()
|
||||||
@ -619,7 +621,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
"invoice_portion": 40.00
|
"invoice_portion": 40.00
|
||||||
})
|
})
|
||||||
pi.append("payment_schedule", {
|
pi.append("payment_schedule", {
|
||||||
"due_date": add_days(nowdate(), 45),
|
"due_date": add_days(nowdate(), 25),
|
||||||
"payment_amount": 150,
|
"payment_amount": 150,
|
||||||
"invoice_portion": 60.00
|
"invoice_portion": 60.00
|
||||||
})
|
})
|
||||||
@ -634,7 +636,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
expected_gl_entries = sorted([
|
expected_gl_entries = sorted([
|
||||||
[pi.credit_to, 0.0, 100.0, add_days(nowdate(), 15)],
|
[pi.credit_to, 0.0, 100.0, add_days(nowdate(), 15)],
|
||||||
[pi.credit_to, 0.0, 150.0, add_days(nowdate(), 45)],
|
[pi.credit_to, 0.0, 150.0, add_days(nowdate(), 25)],
|
||||||
["_Test Account Cost for Goods Sold - _TC", 250.0, 0.0, None]
|
["_Test Account Cost for Goods Sold - _TC", 250.0, 0.0, None]
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
si.insert()
|
si.insert()
|
||||||
|
|
||||||
self.assertTrue(si.payment_schedule)
|
self.assertTrue(si.payment_schedule)
|
||||||
self.assertEqual(si.payment_schedule[0].due_date, si.due_date)
|
self.assertEqual(getdate(si.payment_schedule[0].due_date), getdate(si.due_date))
|
||||||
|
|
||||||
def test_sales_invoice_calculation_base_currency(self):
|
def test_sales_invoice_calculation_base_currency(self):
|
||||||
si = frappe.copy_doc(test_records[2])
|
si = frappe.copy_doc(test_records[2])
|
||||||
|
@ -320,7 +320,8 @@ def validate_due_date(posting_date, due_date, party_type, party):
|
|||||||
msgprint(_("Note: Due / Reference Date exceeds allowed customer credit days by {0} day(s)")
|
msgprint(_("Note: Due / Reference Date exceeds allowed customer credit days by {0} day(s)")
|
||||||
.format(date_diff(due_date, default_due_date)))
|
.format(date_diff(due_date, default_due_date)))
|
||||||
else:
|
else:
|
||||||
frappe.throw(_("Due / Reference Date cannot be after {0}").format(formatdate(default_due_date)))
|
frappe.throw(_("Due / Reference Date cannot be after {0}")
|
||||||
|
.format(formatdate(default_due_date)))
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def set_taxes(party, party_type, posting_date, company, customer_group=None, supplier_type=None,
|
def set_taxes(party, party_type, posting_date, company, customer_group=None, supplier_type=None,
|
||||||
|
@ -26,9 +26,12 @@ class AccountsController(TransactionBase):
|
|||||||
return self.__company_currency
|
return self.__company_currency
|
||||||
|
|
||||||
def onload(self):
|
def onload(self):
|
||||||
self.get("__onload").make_payment_via_journal_entry = frappe.db.get_single_value('Accounts Settings', 'make_payment_via_journal_entry')
|
self.get("__onload").make_payment_via_journal_entry \
|
||||||
|
= frappe.db.get_single_value('Accounts Settings', 'make_payment_via_journal_entry')
|
||||||
|
|
||||||
if self.is_new():
|
if self.is_new():
|
||||||
relevant_docs = ("Quotation", "Purchase Order", "Sales Order", "Purchase Invoice", "Purchase Order")
|
relevant_docs = ("Quotation", "Purchase Order", "Sales Order",
|
||||||
|
"Purchase Invoice", "Sales Invoice")
|
||||||
if self.doctype in relevant_docs:
|
if self.doctype in relevant_docs:
|
||||||
self.set_payment_schedule()
|
self.set_payment_schedule()
|
||||||
|
|
||||||
@ -59,21 +62,18 @@ class AccountsController(TransactionBase):
|
|||||||
self.validate_paid_amount()
|
self.validate_paid_amount()
|
||||||
|
|
||||||
def validate_invoice_documents_schedule(self):
|
def validate_invoice_documents_schedule(self):
|
||||||
if self.get("payment_schedule"):
|
self.validate_payment_schedule_dates()
|
||||||
self.set_due_date()
|
self.set_due_date()
|
||||||
self.validate_payment_schedule()
|
self.validate_invoice_portion()
|
||||||
else:
|
self.set_payment_schedule()
|
||||||
self.set_payment_schedule()
|
self.validate_payment_schedule_amount()
|
||||||
self.set_due_date()
|
|
||||||
self.validate_due_date()
|
self.validate_due_date()
|
||||||
self.validate_advance_entries()
|
self.validate_advance_entries()
|
||||||
|
|
||||||
def validate_non_invoice_documents_schedule(self):
|
def validate_non_invoice_documents_schedule(self):
|
||||||
if self.get("payment_schedule"):
|
self.validate_invoice_portion()
|
||||||
self.validate_invoice_portion()
|
self.set_payment_schedule()
|
||||||
self.validate_payment_schedule_amount()
|
self.validate_payment_schedule_amount()
|
||||||
else:
|
|
||||||
self.set_payment_schedule()
|
|
||||||
|
|
||||||
def validate_all_documents_schedule(self):
|
def validate_all_documents_schedule(self):
|
||||||
if self.doctype in ("Sales Invoice", "Purchase Invoice") and not self.is_return:
|
if self.doctype in ("Sales Invoice", "Purchase Invoice") and not self.is_return:
|
||||||
@ -628,22 +628,24 @@ class AccountsController(TransactionBase):
|
|||||||
posting_date = self.get("posting_date") or self.get("transaction_date")
|
posting_date = self.get("posting_date") or self.get("transaction_date")
|
||||||
date = self.get("due_date")
|
date = self.get("due_date")
|
||||||
due_date = date or posting_date
|
due_date = date or posting_date
|
||||||
|
grand_total = self.get("rounded_total") or self.grand_total
|
||||||
|
|
||||||
if self.get("payment_terms_template") and not self.get("payment_schedule"):
|
if not self.get("payment_schedule"):
|
||||||
data = get_payment_terms(self.payment_terms_template, posting_date, self.grand_total)
|
if self.get("payment_terms_template"):
|
||||||
for item in data:
|
data = get_payment_terms(self.payment_terms_template, posting_date, grand_total)
|
||||||
self.append("payment_schedule", item)
|
for item in data:
|
||||||
elif not self.get("payment_schedule"):
|
self.append("payment_schedule", item)
|
||||||
data = dict(due_date=due_date, invoice_portion=100, payment_amount=self.grand_total)
|
else:
|
||||||
self.append("payment_schedule", data)
|
data = dict(due_date=due_date, invoice_portion=100, payment_amount=grand_total)
|
||||||
|
self.append("payment_schedule", data)
|
||||||
|
else:
|
||||||
|
for d in self.get("payment_schedule"):
|
||||||
|
d.payment_amount = grand_total * flt(d.invoice_portion) / 100
|
||||||
|
|
||||||
def set_due_date(self):
|
def set_due_date(self):
|
||||||
self.due_date = max([d.due_date for d in self.get("payment_schedule")])
|
due_dates = [d.due_date for d in self.get("payment_schedule") if d.due_date]
|
||||||
|
if due_dates:
|
||||||
def validate_payment_schedule(self):
|
self.due_date = max(due_dates)
|
||||||
self.validate_payment_schedule_dates()
|
|
||||||
self.validate_invoice_portion()
|
|
||||||
self.validate_payment_schedule_amount()
|
|
||||||
|
|
||||||
def validate_payment_schedule_dates(self):
|
def validate_payment_schedule_dates(self):
|
||||||
dates = []
|
dates = []
|
||||||
@ -661,24 +663,27 @@ class AccountsController(TransactionBase):
|
|||||||
|
|
||||||
if li:
|
if li:
|
||||||
duplicates = '<br>' + '<br>'.join(li)
|
duplicates = '<br>' + '<br>'.join(li)
|
||||||
frappe.throw(_("Rows with duplicate due dates in other rows were found: {list}").format(list=duplicates))
|
frappe.throw(_("Rows with duplicate due dates in other rows were found: {list}")
|
||||||
|
.format(list=duplicates))
|
||||||
|
|
||||||
def validate_payment_schedule_amount(self):
|
def validate_payment_schedule_amount(self):
|
||||||
total = 0
|
if self.get("payment_schedule"):
|
||||||
for d in self.get("payment_schedule"):
|
total = 0
|
||||||
total += flt(d.payment_amount)
|
for d in self.get("payment_schedule"):
|
||||||
|
total += flt(d.payment_amount)
|
||||||
|
|
||||||
if total != self.grand_total:
|
grand_total = self.get("rounded_total") or self.grand_total
|
||||||
frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand Total"))
|
if total != grand_total:
|
||||||
|
frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand / Rounded Total"))
|
||||||
|
|
||||||
def validate_invoice_portion(self):
|
def validate_invoice_portion(self):
|
||||||
total_portion = 0
|
if self.get("payment_schedule"):
|
||||||
for term in self.payment_schedule:
|
total_portion = 0
|
||||||
total_portion += flt(term.get('invoice_portion', 0))
|
for term in self.payment_schedule:
|
||||||
|
total_portion += flt(term.get('invoice_portion', 0))
|
||||||
|
|
||||||
if flt(total_portion, 2) != 100.00:
|
if flt(total_portion, 2) != 100.00:
|
||||||
frappe.msgprint(_('Combined invoice portion must equal 100%'), raise_exception=1, indicator='red')
|
frappe.throw(_('Combined invoice portion must equal 100%'), indicator='red')
|
||||||
|
|
||||||
def is_rounded_total_disabled(self):
|
def is_rounded_total_disabled(self):
|
||||||
if self.meta.get_field("disable_rounded_total"):
|
if self.meta.get_field("disable_rounded_total"):
|
||||||
|
@ -460,12 +460,8 @@ execute:frappe.delete_doc_if_exists("DocType", "Program Fee")
|
|||||||
erpnext.patches.v9_0.set_pos_profile_name
|
erpnext.patches.v9_0.set_pos_profile_name
|
||||||
erpnext.patches.v9_0.remove_non_existing_warehouse_from_stock_settings
|
erpnext.patches.v9_0.remove_non_existing_warehouse_from_stock_settings
|
||||||
execute:frappe.delete_doc_if_exists("DocType", "Program Fee")
|
execute:frappe.delete_doc_if_exists("DocType", "Program Fee")
|
||||||
erpnext.patches.v8_10.add_due_date_to_gle
|
|
||||||
erpnext.patches.v8_10.update_gl_due_date_for_pi_and_si
|
erpnext.patches.v8_10.update_gl_due_date_for_pi_and_si
|
||||||
erpnext.patches.v8_10.add_payment_terms_field_to_supplier
|
|
||||||
erpnext.patches.v8_10.change_default_customer_credit_days
|
erpnext.patches.v8_10.change_default_customer_credit_days
|
||||||
erpnext.patches.v8_10.add_payment_terms_field_to_supplier_type
|
|
||||||
erpnext.patches.v8_10.change_default_supplier_type_credit_days
|
|
||||||
erpnext.patches.v9_0.update_employee_loan_details
|
erpnext.patches.v9_0.update_employee_loan_details
|
||||||
erpnext.patches.v9_2.delete_healthcare_domain_default_items
|
erpnext.patches.v9_2.delete_healthcare_domain_default_items
|
||||||
erpnext.patches.v9_1.create_issue_opportunity_type
|
erpnext.patches.v9_1.create_issue_opportunity_type
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
|
|
||||||
|
|
||||||
def execute():
|
|
||||||
if not frappe.db.has_column("GL Entry", "due_date"):
|
|
||||||
frappe.db.sql("ALTER TABLE `tabGL Entry` ADD COLUMN `due_date` DATE NULL")
|
|
@ -1,9 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
|
|
||||||
|
|
||||||
def execute():
|
|
||||||
if not frappe.db.has_column("Customer", "payment_terms"):
|
|
||||||
frappe.db.sql("ALTER TABLE `tabCustomer` ADD COLUMN `payment_terms` VARCHAR(140) NULL")
|
|
||||||
if not frappe.db.has_column("Supplier", "payment_terms"):
|
|
||||||
frappe.db.sql("ALTER TABLE `tabSupplier` ADD COLUMN `payment_terms` VARCHAR(140) NULL")
|
|
@ -1,7 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
|
|
||||||
|
|
||||||
def execute():
|
|
||||||
if not frappe.db.has_column("Supplier Type", "payment_terms"):
|
|
||||||
frappe.db.sql("ALTER TABLE `tabSupplier Type` ADD COLUMN `payment_terms` VARCHAR(140) NULL")
|
|
@ -3,67 +3,49 @@ import frappe
|
|||||||
|
|
||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
|
frappe.reload_doc("selling", "doctype", "customer")
|
||||||
|
frappe.reload_doc("buying", "doctype", "supplier")
|
||||||
|
frappe.reload_doc("setup", "doctype", "supplier_type")
|
||||||
frappe.reload_doc("accounts", "doctype", "payment_term")
|
frappe.reload_doc("accounts", "doctype", "payment_term")
|
||||||
frappe.reload_doc("accounts", "doctype", "payment_terms_template_detail")
|
frappe.reload_doc("accounts", "doctype", "payment_terms_template_detail")
|
||||||
frappe.reload_doc("accounts", "doctype", "payment_terms_template")
|
frappe.reload_doc("accounts", "doctype", "payment_terms_template")
|
||||||
|
|
||||||
payment_terms = []
|
payment_terms = []
|
||||||
customers = []
|
records = []
|
||||||
suppliers = []
|
for doctype in ("Customer", "Supplier", "Supplier Type"):
|
||||||
credit_days = frappe.db.sql(
|
credit_days = frappe.db.sql("""
|
||||||
"SELECT DISTINCT `credit_days`, `credit_days_based_on`, `customer_name` from "
|
SELECT DISTINCT `credit_days`, `credit_days_based_on`, `name`
|
||||||
"`tabCustomer` where credit_days_based_on='Fixed Days' or "
|
from `tab{0}`
|
||||||
"credit_days_based_on='Last Day of the Next Month'")
|
where
|
||||||
|
(credit_days_based_on='Fixed Days' and credit_days is not null)
|
||||||
|
or credit_days_based_on='Last Day of the Next Month'
|
||||||
|
""".format(doctype))
|
||||||
|
|
||||||
credit_records = ((record[0], record[1], record[2]) for record in credit_days)
|
credit_records = ((record[0], record[1], record[2]) for record in credit_days)
|
||||||
for days, based_on, customer_name in credit_records:
|
for days, based_on, party_name in credit_records:
|
||||||
payment_term = make_payment_term(days, based_on)
|
if based_on == "Fixed Days":
|
||||||
template = make_template(payment_term)
|
pyt_template_name = 'Default Payment Term - N{0}'.format(days)
|
||||||
payment_terms.append('WHEN `customer_name`="%s" THEN "%s"' % (customer_name, template.template_name))
|
else:
|
||||||
customers.append(customer_name)
|
pyt_template_name = 'Default Payment Term - EO2M'
|
||||||
|
|
||||||
begin_query_str = "UPDATE `tabCustomer` SET `payment_terms` = CASE "
|
if not frappe.db.exists("Payment Terms Template", pyt_template_name):
|
||||||
value_query_str = " ".join(payment_terms)
|
payment_term = make_payment_term(days, based_on)
|
||||||
cond_query_str = " ELSE `payment_terms` END WHERE "
|
template = make_template(payment_term)
|
||||||
|
else:
|
||||||
|
template = frappe.get_doc("Payment Terms Template", pyt_template_name)
|
||||||
|
|
||||||
if customers:
|
payment_terms.append('WHEN `name`="%s" THEN "%s"' % (party_name, template.template_name))
|
||||||
frappe.db.sql(
|
records.append(party_name)
|
||||||
begin_query_str + value_query_str + cond_query_str + '`customer_name` IN %s',
|
|
||||||
(customers,)
|
|
||||||
)
|
|
||||||
|
|
||||||
# reset
|
begin_query_str = "UPDATE `tab{0}` SET `payment_terms` = CASE ".format(doctype)
|
||||||
payment_terms = []
|
value_query_str = " ".join(payment_terms)
|
||||||
credit_days = frappe.db.sql(
|
cond_query_str = " ELSE `payment_terms` END WHERE "
|
||||||
"SELECT DISTINCT `credit_days`, `credit_days_based_on`, `supplier_name` from "
|
|
||||||
"`tabSupplier` where credit_days_based_on='Fixed Days' or "
|
|
||||||
"credit_days_based_on='Last Day of the Next Month'")
|
|
||||||
|
|
||||||
credit_records = ((record[0], record[1], record[2]) for record in credit_days)
|
if records:
|
||||||
for days, based_on, supplier_name in credit_records:
|
frappe.db.sql(
|
||||||
if based_on == "Fixed Days":
|
begin_query_str + value_query_str + cond_query_str + '`name` IN %s',
|
||||||
pyt_template_name = 'Default Payment Term - N{0}'.format(days)
|
(records,)
|
||||||
else:
|
)
|
||||||
pyt_template_name = 'Default Payment Term - EO2M'
|
|
||||||
|
|
||||||
if not frappe.db.exists("Payment Term Template", pyt_template_name):
|
|
||||||
payment_term = make_payment_term(days, based_on)
|
|
||||||
template = make_template(payment_term)
|
|
||||||
else:
|
|
||||||
template = frappe.get_doc("Payment Term Template", pyt_template_name)
|
|
||||||
|
|
||||||
payment_terms.append('WHEN `supplier_name`="%s" THEN "%s"' % (supplier_name, template.template_name))
|
|
||||||
suppliers.append(supplier_name)
|
|
||||||
|
|
||||||
begin_query_str = "UPDATE `tabSupplier` SET `payment_terms` = CASE "
|
|
||||||
value_query_str = " ".join(payment_terms)
|
|
||||||
cond_query_str = " ELSE `payment_terms` END WHERE "
|
|
||||||
|
|
||||||
if suppliers:
|
|
||||||
frappe.db.sql(
|
|
||||||
begin_query_str + value_query_str + cond_query_str + '`supplier_name` IN %s',
|
|
||||||
(suppliers,)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def make_template(payment_term):
|
def make_template(payment_term):
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
import frappe
|
|
||||||
from erpnext.patches.v8_10.change_default_customer_credit_days import make_payment_term, make_template
|
|
||||||
|
|
||||||
|
|
||||||
def execute():
|
|
||||||
payment_terms = []
|
|
||||||
supplier_types = []
|
|
||||||
|
|
||||||
credit_days = frappe.db.sql(
|
|
||||||
"SELECT DISTINCT `credit_days`, `credit_days_based_on`, `supplier_type` from "
|
|
||||||
"`tabSupplier Type` where credit_days_based_on='Fixed Days' or "
|
|
||||||
"credit_days_based_on='Last Day of the Next Month'")
|
|
||||||
|
|
||||||
records = ((record[0], record[1], record[2]) for record in credit_days)
|
|
||||||
|
|
||||||
for days, based_on, supplier_type in records:
|
|
||||||
if based_on == "Fixed Days":
|
|
||||||
pyt_term_name = 'N{0}'.format(days)
|
|
||||||
else:
|
|
||||||
pyt_term_name = 'EO2M'
|
|
||||||
|
|
||||||
if not frappe.db.exists("Payment Term", pyt_term_name):
|
|
||||||
payment_term = make_payment_term(days, based_on)
|
|
||||||
make_template(payment_term)
|
|
||||||
else:
|
|
||||||
payment_term = frappe.get_doc("Payment Term", pyt_term_name)
|
|
||||||
|
|
||||||
payment_terms.append('WHEN `supplier_type`="%s" THEN "%s"' % (supplier_type, payment_term.payment_term_name))
|
|
||||||
supplier_types.append(supplier_type)
|
|
||||||
|
|
||||||
begin_query_str = "UPDATE `tabSupplier Type` SET `payment_terms` = CASE "
|
|
||||||
value_query_str = " ".join(payment_terms)
|
|
||||||
cond_query_str = " ELSE `payment_terms` END WHERE "
|
|
||||||
|
|
||||||
if supplier_types:
|
|
||||||
frappe.db.sql(
|
|
||||||
begin_query_str + value_query_str + cond_query_str + '`supplier_type` IN %s',
|
|
||||||
(supplier_types,)
|
|
||||||
)
|
|
@ -6,6 +6,8 @@ import frappe
|
|||||||
|
|
||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
|
frappe.reload_doc("accounts", "doctype", "gl_entry")
|
||||||
|
|
||||||
kwargs = get_query_kwargs()
|
kwargs = get_query_kwargs()
|
||||||
|
|
||||||
for kwarg in kwargs:
|
for kwarg in kwargs:
|
||||||
|
@ -1153,7 +1153,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
args: {
|
args: {
|
||||||
terms_template: this.frm.doc.payment_terms_template,
|
terms_template: this.frm.doc.payment_terms_template,
|
||||||
posting_date: this.frm.doc.posting_date || this.frm.doc.transaction_date,
|
posting_date: this.frm.doc.posting_date || this.frm.doc.transaction_date,
|
||||||
grand_total: this.frm.doc.grand_total
|
grand_total: this.frm.doc.rounded_total || this.frm.doc.grand_total
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if(r.message && !r.exc) {
|
if(r.message && !r.exc) {
|
||||||
@ -1172,7 +1172,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
args: {
|
args: {
|
||||||
term: row.payment_term,
|
term: row.payment_term,
|
||||||
posting_date: this.frm.doc.posting_date || this.frm.doc.transaction_date,
|
posting_date: this.frm.doc.posting_date || this.frm.doc.transaction_date,
|
||||||
grand_total: this.frm.doc.grand_total
|
grand_total: this.frm.doc.rounded_total || this.frm.doc.grand_total
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if(r.message && !r.exc) {
|
if(r.message && !r.exc) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user