mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-01 15:47:06 +00:00
Merge pull request #57983 from Jatin3128/fix/disabled-party-validation-opportunity-rfq
fix: block disabled/frozen party on Opportunity and Request for Quotation
This commit is contained in:
@@ -13,6 +13,7 @@ from frappe.utils import get_url
|
|||||||
from frappe.utils.print_format import download_pdf
|
from frappe.utils.print_format import download_pdf
|
||||||
from frappe.utils.user import get_user_fullname
|
from frappe.utils.user import get_user_fullname
|
||||||
|
|
||||||
|
from erpnext.accounts.party import validate_party_frozen_disabled
|
||||||
from erpnext.buying.utils import validate_for_items
|
from erpnext.buying.utils import validate_for_items
|
||||||
from erpnext.controllers.buying_controller import BuyingController
|
from erpnext.controllers.buying_controller import BuyingController
|
||||||
|
|
||||||
@@ -122,6 +123,8 @@ class RequestforQuotation(BuyingController):
|
|||||||
|
|
||||||
def validate_supplier_list(self):
|
def validate_supplier_list(self):
|
||||||
for d in self.suppliers:
|
for d in self.suppliers:
|
||||||
|
validate_party_frozen_disabled(self.company, "Supplier", d.supplier)
|
||||||
|
|
||||||
prevent_rfqs = frappe.db.get_value("Supplier", d.supplier, "prevent_rfqs")
|
prevent_rfqs = frappe.db.get_value("Supplier", d.supplier, "prevent_rfqs")
|
||||||
if prevent_rfqs:
|
if prevent_rfqs:
|
||||||
standing = frappe.db.get_value("Supplier Scorecard", d.supplier, "status")
|
standing = frappe.db.get_value("Supplier Scorecard", d.supplier, "status")
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ from erpnext.buying.doctype.request_for_quotation.request_for_quotation import (
|
|||||||
from erpnext.controllers.accounts_controller import InvalidQtyError
|
from erpnext.controllers.accounts_controller import InvalidQtyError
|
||||||
from erpnext.crm.doctype.opportunity.mapper import make_request_for_quotation as make_rfq
|
from erpnext.crm.doctype.opportunity.mapper import make_request_for_quotation as make_rfq
|
||||||
from erpnext.crm.doctype.opportunity.test_opportunity import make_opportunity
|
from erpnext.crm.doctype.opportunity.test_opportunity import make_opportunity
|
||||||
|
from erpnext.exceptions import PartyDisabled
|
||||||
from erpnext.stock.doctype.item.test_item import make_item
|
from erpnext.stock.doctype.item.test_item import make_item
|
||||||
from erpnext.stock.doctype.material_request.test_material_request import make_material_request
|
from erpnext.stock.doctype.material_request.test_material_request import make_material_request
|
||||||
from erpnext.templates.pages.rfq import check_supplier_has_docname_access
|
from erpnext.templates.pages.rfq import check_supplier_has_docname_access
|
||||||
@@ -89,6 +90,17 @@ class TestRequestforQuotation(ERPNextTestSuite):
|
|||||||
)
|
)
|
||||||
self.assertRaises(frappe.ValidationError, rfq.save)
|
self.assertRaises(frappe.ValidationError, rfq.save)
|
||||||
|
|
||||||
|
def test_rfq_blocked_for_disabled_supplier(self):
|
||||||
|
frappe.db.set_value("Supplier", "_Test Supplier", "disabled", 1)
|
||||||
|
rfq = make_request_for_quotation(
|
||||||
|
supplier_data=[{"supplier": "_Test Supplier", "supplier_name": "_Test Supplier"}],
|
||||||
|
do_not_save=True,
|
||||||
|
)
|
||||||
|
self.assertRaises(PartyDisabled, rfq.save)
|
||||||
|
|
||||||
|
frappe.db.set_value("Supplier", "_Test Supplier", "disabled", 0)
|
||||||
|
rfq.save()
|
||||||
|
|
||||||
def test_rfq_status_lifecycle(self):
|
def test_rfq_status_lifecycle(self):
|
||||||
rfq = make_request_for_quotation()
|
rfq = make_request_for_quotation()
|
||||||
self.assertEqual(rfq.status, "Submitted")
|
self.assertEqual(rfq.status, "Submitted")
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Supplier",
|
"label": "Supplier",
|
||||||
|
"link_filters": "[[\"Supplier\",\"disabled\",\"=\",0]]",
|
||||||
"options": "Supplier",
|
"options": "Supplier",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ from frappe.query_builder import DocType, Interval
|
|||||||
from frappe.query_builder.functions import Now
|
from frappe.query_builder.functions import Now
|
||||||
from frappe.utils import flt, get_fullname
|
from frappe.utils import flt, get_fullname
|
||||||
|
|
||||||
|
from erpnext.accounts.party import validate_party_frozen_disabled
|
||||||
from erpnext.crm.utils import (
|
from erpnext.crm.utils import (
|
||||||
CRMNote,
|
CRMNote,
|
||||||
copy_comments,
|
copy_comments,
|
||||||
@@ -132,6 +133,7 @@ class Opportunity(TransactionBase, CRMNote):
|
|||||||
self.validate_item_details()
|
self.validate_item_details()
|
||||||
self.validate_uom_is_integer("uom", "qty")
|
self.validate_uom_is_integer("uom", "qty")
|
||||||
self.validate_cust_name()
|
self.validate_cust_name()
|
||||||
|
self.validate_party()
|
||||||
self.map_fields()
|
self.map_fields()
|
||||||
self.validate_qty()
|
self.validate_qty()
|
||||||
self.set_exchange_rate()
|
self.set_exchange_rate()
|
||||||
@@ -355,6 +357,10 @@ class Opportunity(TransactionBase, CRMNote):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def validate_party(self) -> None:
|
||||||
|
if self.opportunity_from == "Customer":
|
||||||
|
validate_party_frozen_disabled(self.company, "Customer", self.party_name)
|
||||||
|
|
||||||
def validate_cust_name(self):
|
def validate_cust_name(self):
|
||||||
if self.party_name:
|
if self.party_name:
|
||||||
if self.opportunity_from == "Customer":
|
if self.opportunity_from == "Customer":
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from erpnext.crm.doctype.lead.test_lead import make_lead
|
|||||||
from erpnext.crm.doctype.opportunity.mapper import make_quotation
|
from erpnext.crm.doctype.opportunity.mapper import make_quotation
|
||||||
from erpnext.crm.doctype.opportunity.opportunity import auto_close_opportunity, get_item_details
|
from erpnext.crm.doctype.opportunity.opportunity import auto_close_opportunity, get_item_details
|
||||||
from erpnext.crm.utils import get_linked_communication_list
|
from erpnext.crm.utils import get_linked_communication_list
|
||||||
|
from erpnext.exceptions import PartyDisabled
|
||||||
from erpnext.tests.utils import ERPNextTestSuite
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
|
|
||||||
@@ -71,6 +72,23 @@ class TestOpportunity(ERPNextTestSuite):
|
|||||||
opportunity_doc = make_opportunity(with_items=1, rate=1100, qty=2)
|
opportunity_doc = make_opportunity(with_items=1, rate=1100, qty=2)
|
||||||
self.assertEqual(opportunity_doc.total, 2200)
|
self.assertEqual(opportunity_doc.total, 2200)
|
||||||
|
|
||||||
|
def test_disabled_customer_not_allowed(self):
|
||||||
|
frappe.db.set_value("Customer", "_Test Customer", "disabled", 1)
|
||||||
|
|
||||||
|
self.assertRaises(PartyDisabled, make_opportunity, with_items=0)
|
||||||
|
|
||||||
|
frappe.db.set_value("Customer", "_Test Customer", "disabled", 0)
|
||||||
|
make_opportunity(with_items=0)
|
||||||
|
|
||||||
|
def test_disabled_lead_not_blocked(self):
|
||||||
|
# Lead.disabled isn't enforced anywhere else (e.g. the Lead picker query only
|
||||||
|
# excludes Converted leads), so it shouldn't block Opportunity creation either.
|
||||||
|
lead_doc = make_lead()
|
||||||
|
frappe.db.set_value("Lead", lead_doc.name, "disabled", 1)
|
||||||
|
|
||||||
|
opp_doc = make_opportunity(opportunity_from="Lead", lead=lead_doc.name)
|
||||||
|
self.assertEqual(opp_doc.party_name, lead_doc.name)
|
||||||
|
|
||||||
def test_carry_forward_of_email_and_comments(self):
|
def test_carry_forward_of_email_and_comments(self):
|
||||||
frappe.db.set_single_value("CRM Settings", "carry_forward_communication_and_comments", 1)
|
frappe.db.set_single_value("CRM Settings", "carry_forward_communication_and_comments", 1)
|
||||||
lead_doc = make_lead()
|
lead_doc = make_lead()
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ $.extend(erpnext.queries, {
|
|||||||
return { query: "erpnext.controllers.queries.lead_query" };
|
return { query: "erpnext.controllers.queries.lead_query" };
|
||||||
},
|
},
|
||||||
|
|
||||||
|
customer: function () {
|
||||||
|
return { filters: { disabled: 0 } };
|
||||||
|
},
|
||||||
|
|
||||||
item: function (filters) {
|
item: function (filters) {
|
||||||
var args = { query: "erpnext.controllers.queries.item_query" };
|
var args = { query: "erpnext.controllers.queries.item_query" };
|
||||||
if (filters) args["filters"] = filters;
|
if (filters) args["filters"] = filters;
|
||||||
|
|||||||
Reference in New Issue
Block a user