mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-09 15:29:30 +00:00
Co-authored-by: Mihir Kandoi <kandoimihir@gmail.com>
This commit is contained in:
@@ -25,6 +25,7 @@ import erpnext
|
||||
from erpnext import get_company_currency
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
from erpnext.exceptions import InvalidAccountCurrency, PartyDisabled, PartyFrozen
|
||||
from erpnext.stock.doctype.price_list.price_list import is_price_list_enabled
|
||||
from erpnext.utilities.regional import temporary_flag
|
||||
|
||||
try:
|
||||
@@ -370,12 +371,17 @@ def set_other_values(party_details, party, party_type):
|
||||
|
||||
|
||||
def get_default_price_list(party):
|
||||
"""Return default price list for party (Document object)"""
|
||||
if party.get("default_price_list"):
|
||||
return party.default_price_list
|
||||
"""Return the first enabled default price list for party (Document object)"""
|
||||
price_list = party.get("default_price_list")
|
||||
if is_price_list_enabled(price_list):
|
||||
return price_list
|
||||
|
||||
if party.doctype == "Customer":
|
||||
return frappe.get_cached_value("Customer Group", party.customer_group, "default_price_list")
|
||||
if party.doctype != "Customer":
|
||||
return
|
||||
|
||||
price_list = frappe.get_cached_value("Customer Group", party.customer_group, "default_price_list")
|
||||
if is_price_list_enabled(price_list):
|
||||
return price_list
|
||||
|
||||
|
||||
def set_price_list(party_details, party, party_type, given_price_list, pos=None):
|
||||
@@ -388,7 +394,7 @@ def set_price_list(party_details, party, party_type, given_price_list, pos=None)
|
||||
elif pos and party_type == "Customer":
|
||||
customer_price_list = frappe.get_value("Customer", party.name, "default_price_list")
|
||||
|
||||
if customer_price_list:
|
||||
if is_price_list_enabled(customer_price_list):
|
||||
price_list = customer_price_list
|
||||
else:
|
||||
pos_price_list = frappe.get_value("POS Profile", pos, "selling_price_list")
|
||||
@@ -396,6 +402,9 @@ def set_price_list(party_details, party, party_type, given_price_list, pos=None)
|
||||
else:
|
||||
price_list = get_default_price_list(party) or given_price_list
|
||||
|
||||
if price_list and not is_price_list_enabled(price_list):
|
||||
price_list = None
|
||||
|
||||
if price_list:
|
||||
party_details.price_list_currency = frappe.db.get_value(
|
||||
"Price List", price_list, "currency", cache=True
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import frappe
|
||||
|
||||
from erpnext.accounts.party import get_default_price_list
|
||||
from erpnext.accounts.party import get_default_price_list, set_price_list
|
||||
from erpnext.tests.utils import ERPNextTestSuite
|
||||
|
||||
|
||||
@@ -16,3 +16,46 @@ class PartyTestCase(ERPNextTestSuite):
|
||||
customer.save()
|
||||
price_list = get_default_price_list(customer)
|
||||
assert price_list is None
|
||||
|
||||
def test_disabled_party_default_should_fall_back_to_given_price_list(self):
|
||||
customer = self.create_customer(default_price_list=self.create_price_list(enabled=0))
|
||||
given_price_list = self.create_price_list(enabled=1)
|
||||
|
||||
party_details = frappe._dict()
|
||||
set_price_list(party_details, customer, "Customer", given_price_list)
|
||||
|
||||
self.assertEqual(party_details.selling_price_list, given_price_list)
|
||||
|
||||
def test_disabled_given_price_list_should_not_be_set(self):
|
||||
customer = self.create_customer()
|
||||
|
||||
party_details = frappe._dict()
|
||||
set_price_list(party_details, customer, "Customer", self.create_price_list(enabled=0))
|
||||
|
||||
self.assertIsNone(party_details.selling_price_list)
|
||||
|
||||
def create_price_list(self, enabled):
|
||||
price_list = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Price List",
|
||||
"price_list_name": frappe.generate_hash(length=10),
|
||||
"currency": "INR",
|
||||
"selling": 1,
|
||||
"enabled": enabled,
|
||||
}
|
||||
).insert(ignore_permissions=True)
|
||||
|
||||
return price_list.name
|
||||
|
||||
def create_customer(self, **values):
|
||||
customer = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Customer",
|
||||
"customer_name": frappe.generate_hash(length=10),
|
||||
**values,
|
||||
}
|
||||
).insert(ignore_permissions=True, ignore_mandatory=True)
|
||||
customer.customer_group = None
|
||||
customer.save()
|
||||
|
||||
return customer
|
||||
|
||||
@@ -69,7 +69,7 @@ erpnext.buying = {
|
||||
if (this.frm.fields_dict.buying_price_list) {
|
||||
this.frm.set_query("buying_price_list", function () {
|
||||
return {
|
||||
filters: { buying: 1 },
|
||||
filters: { buying: 1, enabled: 1 },
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ erpnext.sales_common = {
|
||||
|
||||
if (this.frm.fields_dict.selling_price_list) {
|
||||
this.frm.set_query("selling_price_list", function () {
|
||||
return { filters: { selling: 1 } };
|
||||
return { filters: { selling: 1, enabled: 1 } };
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ from frappe.defaults import get_user_default
|
||||
from frappe.utils import cint
|
||||
|
||||
import erpnext.accounts.utils
|
||||
from erpnext.stock.doctype.price_list.price_list import is_price_list_enabled
|
||||
|
||||
|
||||
def boot_session(bootinfo):
|
||||
@@ -28,6 +29,8 @@ def boot_session(bootinfo):
|
||||
frappe.get_single_value("Accounts Settings", "disable_include_dimensions")
|
||||
)
|
||||
|
||||
remove_disabled_price_list_defaults(bootinfo)
|
||||
|
||||
bootinfo.sysdefaults.quotation_valid_till = cint(
|
||||
frappe.db.get_single_value("CRM Settings", "default_valid_till")
|
||||
)
|
||||
@@ -72,6 +75,18 @@ def boot_session(bootinfo):
|
||||
bootinfo.sysdefaults.repost_allowed_doctypes = frappe.get_hooks("repost_allowed_doctypes")
|
||||
|
||||
|
||||
def remove_disabled_price_list_defaults(bootinfo):
|
||||
user_defaults = (bootinfo.user or {}).get("defaults") or {}
|
||||
|
||||
for key in ("selling_price_list", "buying_price_list"):
|
||||
price_list = bootinfo.sysdefaults.get(key) or user_defaults.get(key)
|
||||
if not isinstance(price_list, str) or is_price_list_enabled(price_list):
|
||||
continue
|
||||
|
||||
bootinfo.sysdefaults.pop(key, None)
|
||||
user_defaults.pop(key, None)
|
||||
|
||||
|
||||
def update_page_info(bootinfo):
|
||||
bootinfo.page_info.update(
|
||||
{
|
||||
|
||||
30
erpnext/startup/test_boot.py
Normal file
30
erpnext/startup/test_boot.py
Normal file
@@ -0,0 +1,30 @@
|
||||
# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
import frappe
|
||||
|
||||
from erpnext.tests.utils import ERPNextTestSuite
|
||||
|
||||
|
||||
class TestBoot(ERPNextTestSuite):
|
||||
def test_boot_session_drops_disabled_price_list_default(self):
|
||||
from erpnext.startup.boot import boot_session
|
||||
|
||||
price_list = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Price List",
|
||||
"price_list_name": frappe.generate_hash(length=10),
|
||||
"currency": "INR",
|
||||
"selling": 1,
|
||||
"enabled": 0,
|
||||
}
|
||||
).insert(ignore_permissions=True)
|
||||
|
||||
bootinfo = frappe._dict(
|
||||
sysdefaults=frappe._dict(selling_price_list=price_list.name),
|
||||
page_info=frappe._dict(),
|
||||
docs=[],
|
||||
)
|
||||
boot_session(bootinfo)
|
||||
|
||||
self.assertIsNone(bootinfo.sysdefaults.get("selling_price_list"))
|
||||
@@ -32,6 +32,7 @@ from erpnext.manufacturing.doctype.work_order.work_order import get_item_details
|
||||
from erpnext.setup.doctype.brand.brand import get_brand_defaults
|
||||
from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
|
||||
from erpnext.stock.doctype.item.item import get_item_defaults
|
||||
from erpnext.stock.doctype.price_list.price_list import is_price_list_enabled
|
||||
from erpnext.stock.get_item_details import get_default_supplier, get_price_list_rate_for
|
||||
from erpnext.stock.stock_balance import get_indented_qty, update_bin_qty
|
||||
from erpnext.subcontracting.doctype.subcontracting_bom.subcontracting_bom import (
|
||||
@@ -219,14 +220,20 @@ class MaterialRequest(BuyingController):
|
||||
self.reset_default_field_value("set_from_warehouse", "items", "from_warehouse")
|
||||
|
||||
self.validate_pp_qty()
|
||||
self.set_buying_price_list()
|
||||
|
||||
if self.buying_price_list and not frappe.get_value("Price List", self.buying_price_list, "buying"):
|
||||
def set_buying_price_list(self):
|
||||
if not is_valid_buying_price_list(self.buying_price_list):
|
||||
self.buying_price_list = None
|
||||
|
||||
if not self.buying_price_list:
|
||||
buying_price_list = frappe.defaults.get_defaults().buying_price_list
|
||||
if frappe.has_permission("Price List", "read", buying_price_list):
|
||||
self.buying_price_list = buying_price_list
|
||||
if self.buying_price_list:
|
||||
return
|
||||
|
||||
default_price_list = frappe.defaults.get_defaults().buying_price_list
|
||||
if is_valid_buying_price_list(default_price_list) and frappe.has_permission(
|
||||
"Price List", "read", default_price_list
|
||||
):
|
||||
self.buying_price_list = default_price_list
|
||||
|
||||
def on_update(self):
|
||||
if not self.is_new() and self.buying_price_list and self.has_value_changed("buying_price_list"):
|
||||
@@ -488,6 +495,10 @@ class MaterialRequest(BuyingController):
|
||||
doc.db_set("status", doc.status)
|
||||
|
||||
|
||||
def is_valid_buying_price_list(price_list: str | None) -> bool:
|
||||
return is_price_list_enabled(price_list) and bool(frappe.get_value("Price List", price_list, "buying"))
|
||||
|
||||
|
||||
def update_completed_and_requested_qty(stock_entry, method):
|
||||
if stock_entry.doctype == "Stock Entry":
|
||||
material_request_map = {}
|
||||
|
||||
@@ -86,3 +86,7 @@ def get_price_list_details(price_list):
|
||||
frappe.cache().hset("price_list_details", price_list, price_list_details)
|
||||
|
||||
return price_list_details or {}
|
||||
|
||||
|
||||
def is_price_list_enabled(price_list: str | None) -> bool:
|
||||
return bool(price_list) and bool(frappe.get_cached_value("Price List", price_list, "enabled"))
|
||||
|
||||
Reference in New Issue
Block a user