From 585254456e43f8512faa13c852b58ce9ec188eb2 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 30 Jan 2018 12:11:22 +0530 Subject: [PATCH] Check credit limit while making DN, if bypassed on SO (#12702) --- .../doctype/sales_invoice/sales_invoice.py | 7 ++- .../selling/doctype/customer/customer.json | 49 +++++++++++++++---- erpnext/selling/doctype/customer/customer.py | 11 +++-- .../doctype/sales_order/sales_order.py | 9 ---- .../doctype/delivery_note/delivery_note.py | 19 +++++-- 5 files changed, 66 insertions(+), 29 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index df1284cf39..f37fe6114c 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -224,12 +224,17 @@ 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.db.get_value("Customer", self.customer, + "bypass_credit_limit_check_at_sales_order")) + if bypass_credit_limit_check_at_sales_order: + validate_against_credit_limit = True + for d in self.get("items"): if not (d.sales_order or d.delivery_note): validate_against_credit_limit = True break if validate_against_credit_limit: - check_credit_limit(self.customer, self.company) + check_credit_limit(self.customer, self.company, bypass_credit_limit_check_at_sales_order) def set_missing_values(self, for_validate=False): pos = self.set_pos_fields(for_validate) diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json index b618bf3fbc..b2577d5878 100644 --- a/erpnext/selling/doctype/customer/customer.json +++ b/erpnext/selling/doctype/customer/customer.json @@ -1002,9 +1002,9 @@ "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "", - "fieldname": "payment_terms", - "fieldtype": "Link", + "default": "0", + "fieldname": "bypass_credit_limit_check_at_sales_order", + "fieldtype": "Check", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -1012,10 +1012,9 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Default Payment Terms Template", + "label": "Bypass credit limit check at Sales Order", "length": 0, "no_copy": 0, - "options": "Payment Terms Template", "permlevel": 0, "precision": "", "print_hide": 0, @@ -1034,9 +1033,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "default": "0", - "fieldname": "bypass_credit_limit_check_at_sales_order", - "fieldtype": "Check", + "fieldname": "column_break_34", + "fieldtype": "Column Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -1044,7 +1042,6 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Bypass credit limit check at Sales Order", "length": 0, "no_copy": 0, "permlevel": 0, @@ -1059,6 +1056,38 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "", + "fieldname": "payment_terms", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Default Payment Terms Template", + "length": 0, + "no_copy": 0, + "options": "Payment Terms Template", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -1354,7 +1383,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-12-13 18:17:19.894331", + "modified": "2018-01-30 11:52:05.497363", "modified_by": "Administrator", "module": "Selling", "name": "Customer", diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index eaa82b3713..2284f85374 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -185,12 +185,14 @@ def get_customer_list(doctype, txt, searchfield, start, page_len, filters): ("%%%s%%" % txt, "%%%s%%" % txt, "%%%s%%" % txt, "%%%s%%" % txt, start, page_len)) -def check_credit_limit(customer, company): - customer_outstanding = get_customer_outstanding(customer, company) +def check_credit_limit(customer, company, ignore_outstanding_sales_order=False, extra_amount=0): + customer_outstanding = get_customer_outstanding(customer, company, ignore_outstanding_sales_order) + if extra_amount > 0: + customer_outstanding += flt(extra_amount) credit_limit = get_credit_limit(customer, company) if credit_limit > 0 and flt(customer_outstanding) > credit_limit: - msgprint(_("Credit limit has been crossed for customer {0} {1}/{2}") + msgprint(_("Credit limit has been crossed for customer {0} ({1}/{2})") .format(customer, customer_outstanding, credit_limit)) # If not authorized person raise exception @@ -231,7 +233,8 @@ def get_customer_outstanding(customer, company, ignore_outstanding_sales_order=F and dn.customer=%s and dn.company=%s and dn.docstatus = 1 and dn.status not in ('Closed', 'Stopped') and ifnull(dn_item.against_sales_order, '') = '' - and ifnull(dn_item.against_sales_invoice, '') = ''""", (customer, company), as_dict=True) + and ifnull(dn_item.against_sales_invoice, '') = '' + """, (customer, company), as_dict=True) outstanding_based_on_dn = 0.0 diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 1c3354c212..42cde9f2fd 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -484,11 +484,6 @@ def make_delivery_note(source_name, target_doc=None): else: target.po_no = source.po_no - # Since the credit limit check is bypassed at sales order level, - # we need to check it at delivery note - if cint(frappe.db.get_value("Customer", source.customer, "bypass_credit_limit_check_at_sales_order")): - check_credit_limit(source.customer, source.company) - target.ignore_pricing_rule = 1 target.run_method("set_missing_values") target.run_method("calculate_taxes_and_totals") @@ -553,10 +548,6 @@ def make_sales_invoice(source_name, target_doc=None, ignore_permissions=False): target.run_method("set_missing_values") target.run_method("calculate_taxes_and_totals") - # Since the credit limit check is bypassed at sales order level, we need to check it at sales invoice - if cint(frappe.db.get_value("Customer", source.customer, "bypass_credit_limit_check_at_sales_order")): - check_credit_limit(source.customer, source.company) - # set company address target.update(get_company_address(target.company)) if target.company_address: diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index dd00398695..65f384f6d9 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -235,13 +235,22 @@ class DeliveryNote(SellingController): def check_credit_limit(self): from erpnext.selling.doctype.customer.customer import check_credit_limit + extra_amount = 0 validate_against_credit_limit = False - for d in self.get("items"): - if not (d.against_sales_order or d.against_sales_invoice): - validate_against_credit_limit = True - break + bypass_credit_limit_check_at_sales_order = cint(frappe.db.get_value("Customer", self.customer, + "bypass_credit_limit_check_at_sales_order")) + if bypass_credit_limit_check_at_sales_order: + validate_against_credit_limit = True + extra_amount = self.base_grand_total + else: + for d in self.get("items"): + if not (d.against_sales_order or d.against_sales_invoice): + validate_against_credit_limit = True + break + if validate_against_credit_limit: - check_credit_limit(self.customer, self.company) + check_credit_limit(self.customer, self.company, + bypass_credit_limit_check_at_sales_order, extra_amount) def validate_packed_qty(self): """