Merge branch 'feat-customer-credit-limit' of https://github.com/Mangesh-Khairnar/erpnext into Mangesh-Khairnar-feat-customer-credit-limit
This commit is contained in:
commit
b847731482
@ -304,8 +304,10 @@ class SalesInvoice(SellingController):
|
||||
from erpnext.selling.doctype.customer.customer import check_credit_limit
|
||||
|
||||
validate_against_credit_limit = False
|
||||
bypass_credit_limit_check_at_sales_order = cint(frappe.get_cached_value("Customer", self.customer,
|
||||
"bypass_credit_limit_check_at_sales_order"))
|
||||
bypass_credit_limit_check_at_sales_order = frappe.db.get_value("Customer Credit Limit",
|
||||
filters={'parent': self.customer, 'company': self.company},
|
||||
fieldname=["bypass_credit_limit_check"])
|
||||
|
||||
if bypass_credit_limit_check_at_sales_order:
|
||||
validate_against_credit_limit = True
|
||||
|
||||
|
@ -632,3 +632,4 @@ execute:frappe.reload_doc('desk', 'doctype','dashboard_chart')
|
||||
erpnext.patches.v12_0.add_default_dashboards
|
||||
erpnext.patches.v12_0.remove_bank_remittance_custom_fields
|
||||
erpnext.patches.v12_0.generate_leave_ledger_entries
|
||||
erpnext.patches.v12_0.move_credit_limit_to_customer_credit_limit
|
@ -0,0 +1,39 @@
|
||||
# Copyright (c) 2019, Frappe and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
''' Move credit limit and bypass credit limit to the child table of customer credit limit '''
|
||||
frappe.reload_doc("Selling", "doctype", "Customer Credit Limit")
|
||||
frappe.reload_doc("Selling", "doctype", "Customer")
|
||||
|
||||
if frappe.db.a_row_exists("Customer Credit Limit"):
|
||||
return
|
||||
|
||||
move_credit_limit_to_child_table()
|
||||
|
||||
def move_credit_limit_to_child_table():
|
||||
''' maps data from old field to the new field in the child table '''
|
||||
|
||||
fields=""
|
||||
if frappe.db.has_column('Customer', 'bypass_credit_limit_check_at_sales_order'):
|
||||
fields = ", bypass_credit_limit_check_at_sales_order"
|
||||
|
||||
credit_limit_record = frappe.db.sql(''' SELECT
|
||||
name, credit_limit
|
||||
{0}
|
||||
FROM `tabCustomer`'''.format(fields), as_dict=1) #nosec
|
||||
|
||||
companies = frappe.get_all("Company", 'name')
|
||||
|
||||
for record in credit_limit_record:
|
||||
customer = frappe.get_doc("Customer", record.name)
|
||||
for company in companies:
|
||||
customer.append("credit_limit_reference", {
|
||||
'credit_limit': record.credit_limit,
|
||||
'bypass_credit_limit_check': record.bypass_credit_limit_check_at_sales_order,
|
||||
'company': company.name
|
||||
})
|
||||
customer.db_insert()
|
File diff suppressed because it is too large
Load Diff
@ -167,13 +167,18 @@ class Customer(TransactionBase):
|
||||
frappe.throw(_("A Customer Group exists with same name please change the Customer name or rename the Customer Group"), frappe.NameError)
|
||||
|
||||
def validate_credit_limit_on_change(self):
|
||||
if self.get("__islocal") or not self.credit_limit \
|
||||
or self.credit_limit == frappe.db.get_value("Customer", self.name, "credit_limit"):
|
||||
if self.get("__islocal") or not self.credit_limit_reference:
|
||||
return
|
||||
|
||||
for company in frappe.get_all("Company"):
|
||||
outstanding_amt = get_customer_outstanding(self.name, company.name)
|
||||
if flt(self.credit_limit) < outstanding_amt:
|
||||
company_record = []
|
||||
for limit in self.credit_limit_reference:
|
||||
if limit.company in company_record:
|
||||
frappe.throw(_("Credit limit is already defined for the Company {0}").format(limit.company, self.name))
|
||||
else:
|
||||
company_record.append(limit.company)
|
||||
|
||||
outstanding_amt = get_customer_outstanding(self.name, limit.company)
|
||||
if flt(limit.credit_limit) < outstanding_amt:
|
||||
frappe.throw(_("""New credit limit is less than current outstanding amount for the customer. Credit limit has to be atleast {0}""").format(outstanding_amt))
|
||||
|
||||
def on_trash(self):
|
||||
@ -322,10 +327,10 @@ def get_credit_limit(customer, company):
|
||||
credit_limit = None
|
||||
|
||||
if customer:
|
||||
credit_limit, customer_group = frappe.get_cached_value("Customer",
|
||||
customer, ["credit_limit", "customer_group"])
|
||||
credit_limit = frappe.db.get_value("Customer Credit Limit", {'parent': customer, 'company': company}, 'credit_limit')
|
||||
|
||||
if not credit_limit:
|
||||
customer_group = frappe.get_cached_value("Customer", customer, 'customer_group')
|
||||
credit_limit = frappe.get_cached_value("Customer Group", customer_group, "credit_limit")
|
||||
|
||||
if not credit_limit:
|
||||
|
@ -25,7 +25,7 @@ class TestCustomer(unittest.TestCase):
|
||||
make_test_records('Item')
|
||||
|
||||
def tearDown(self):
|
||||
frappe.db.set_value("Customer", '_Test Customer', 'credit_limit', 0.0)
|
||||
frappe.db.set_value("Customer Credit Limit", {'parent': '_Test Customer', 'company': '_Test Company'}, 'credit_limit', 0.0)
|
||||
|
||||
def test_party_details(self):
|
||||
from erpnext.accounts.party import get_party_details
|
||||
@ -226,7 +226,7 @@ class TestCustomer(unittest.TestCase):
|
||||
make_sales_order(qty=item_qty)
|
||||
|
||||
if credit_limit == 0.0:
|
||||
frappe.db.set_value("Customer", '_Test Customer', 'credit_limit', outstanding_amt - 50.0)
|
||||
frappe.db.set_value("Customer Credit Limit", {'parent': '_Test Customer', 'company': '_Test Company'}, 'credit_limit', outstanding_amt - 50.0)
|
||||
|
||||
# Sales Order
|
||||
so = make_sales_order(do_not_submit=True)
|
||||
@ -241,7 +241,7 @@ class TestCustomer(unittest.TestCase):
|
||||
self.assertRaises(frappe.ValidationError, si.submit)
|
||||
|
||||
if credit_limit > outstanding_amt:
|
||||
frappe.db.set_value("Customer", '_Test Customer', 'credit_limit', credit_limit)
|
||||
frappe.db.set_value("Customer", {'parent': '_Test Customer', 'company': '_Test Company'}, 'credit_limit', credit_limit)
|
||||
|
||||
# Makes Sales invoice from Sales Order
|
||||
so.save(ignore_permissions=True)
|
||||
@ -252,7 +252,10 @@ class TestCustomer(unittest.TestCase):
|
||||
def test_customer_credit_limit_on_change(self):
|
||||
outstanding_amt = self.get_customer_outstanding_amount()
|
||||
customer = frappe.get_doc("Customer", '_Test Customer')
|
||||
customer.credit_limit = flt(outstanding_amt - 100)
|
||||
customer.append('credit_limit_reference', {'credit_limit': flt(outstanding_amt - 100), 'company': '_Test Company'})
|
||||
|
||||
''' define new credit limit for same company '''
|
||||
customer.append('credit_limit_reference', {'credit_limit': flt(outstanding_amt - 100), 'company': '_Test Company'})
|
||||
self.assertRaises(frappe.ValidationError, customer.save)
|
||||
|
||||
def test_customer_payment_terms(self):
|
||||
|
@ -0,0 +1,50 @@
|
||||
{
|
||||
"creation": "2019-08-28 17:29:42.115592",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"company",
|
||||
"column_break_2",
|
||||
"credit_limit",
|
||||
"bypass_credit_limit_check"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"columns": 4,
|
||||
"fieldname": "credit_limit",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Credit Limit"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"columns": 4,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Company",
|
||||
"options": "Company"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "bypass_credit_limit_check",
|
||||
"fieldtype": "Check",
|
||||
"in_list_view": 1,
|
||||
"label": "Bypass credit limit_check"
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"modified": "2019-08-29 20:46:36.073953",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Customer Credit Limit",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class CustomerCreditLimit(Document):
|
||||
pass
|
@ -208,7 +208,7 @@ class SalesOrder(SellingController):
|
||||
def check_credit_limit(self):
|
||||
# if bypass credit limit check is set to true (1) at sales order level,
|
||||
# then we need not to check credit limit and vise versa
|
||||
if not cint(frappe.get_cached_value("Customer", self.customer, "bypass_credit_limit_check_at_sales_order")):
|
||||
if not cint(frappe.db.get_value("Customer Credit Limit", {'parent': self.customer, 'company': self.company}, "bypass_credit_limit_check")):
|
||||
check_credit_limit(self.customer, self.company)
|
||||
|
||||
def check_nextdoc_docstatus(self):
|
||||
|
@ -10,8 +10,9 @@ QUnit.test("test_sales_order_with_bypass_credit_limit_check", function(assert) {
|
||||
() => frappe.quick_entry.dialog.$wrapper.find('.edit-full').click(),
|
||||
() => frappe.timeout(1),
|
||||
() => cur_frm.set_value("customer_name", "Test Customer 10"),
|
||||
() => cur_frm.set_value("credit_limit", 100.00),
|
||||
() => cur_frm.set_value("bypass_credit_limit_check_at_sales_order", 1),
|
||||
() => cur_frm.add_child('credit_limit_reference', {
|
||||
'credit_limit': 1000,
|
||||
'bypass_credit_limit_check': 1}),
|
||||
// save form
|
||||
() => cur_frm.save(),
|
||||
() => frappe.timeout(1),
|
||||
|
@ -10,8 +10,10 @@ QUnit.test("test_sales_order_without_bypass_credit_limit_check", function(assert
|
||||
() => frappe.quick_entry.dialog.$wrapper.find('.edit-full').click(),
|
||||
() => frappe.timeout(1),
|
||||
() => cur_frm.set_value("customer_name", "Test Customer 11"),
|
||||
() => cur_frm.set_value("credit_limit", 100.00),
|
||||
() => cur_frm.set_value("bypass_credit_limit_check_at_sales_order", 0),
|
||||
() => cur_frm.add_child('credit_limit_reference', {
|
||||
'credit_limit': 1000,
|
||||
'company': '_Test Company',
|
||||
'bypass_credit_limit_check': 1}),
|
||||
// save form
|
||||
() => cur_frm.save(),
|
||||
() => frappe.timeout(1),
|
||||
|
@ -29,7 +29,7 @@ def execute(filters=None):
|
||||
|
||||
if customer_naming_type == "Naming Series":
|
||||
row = [d.name, d.customer_name, credit_limit, outstanding_amt, bal,
|
||||
d.bypass_credit_limit_check_at_sales_order, d.is_frozen,
|
||||
d.bypass_credit_limit_check, d.is_frozen,
|
||||
d.disabled]
|
||||
else:
|
||||
row = [d.name, credit_limit, outstanding_amt, bal,
|
||||
@ -60,9 +60,15 @@ def get_details(filters):
|
||||
conditions = ""
|
||||
|
||||
if filters.get("customer"):
|
||||
conditions += " where name = %(customer)s"
|
||||
|
||||
return frappe.db.sql("""select name, customer_name,
|
||||
bypass_credit_limit_check_at_sales_order, is_frozen, disabled from `tabCustomer` %s
|
||||
""" % conditions, filters, as_dict=1)
|
||||
conditions += " AND c.name = " + filters.get("customer")
|
||||
|
||||
return frappe.db.sql("""SELECT
|
||||
c.name, c.customer_name,
|
||||
ccl.bypass_credit_limit_check,
|
||||
c.is_frozen, c.disabled
|
||||
FROM `tabCustomer` c, `tabCustomer Credit Limit` ccl
|
||||
WHERE
|
||||
c.name = ccl.parent
|
||||
AND ccl.company = %s
|
||||
{0}
|
||||
""".format(conditions), (filters.get("company")), as_dict=1) #nosec
|
||||
|
@ -234,8 +234,10 @@ class DeliveryNote(SellingController):
|
||||
|
||||
extra_amount = 0
|
||||
validate_against_credit_limit = False
|
||||
bypass_credit_limit_check_at_sales_order = cint(frappe.db.get_value("Customer", self.customer,
|
||||
"bypass_credit_limit_check_at_sales_order"))
|
||||
bypass_credit_limit_check_at_sales_order = cint(frappe.db.get_value("Customer Credit Limit",
|
||||
filters={'parent': self.customer, 'company': self.company},
|
||||
fieldname="bypass_credit_limit_check"))
|
||||
|
||||
if bypass_credit_limit_check_at_sales_order:
|
||||
validate_against_credit_limit = True
|
||||
extra_amount = self.base_grand_total
|
||||
|
Loading…
Reference in New Issue
Block a user