mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-12 14:11:46 +00:00
authorization_control.py used MySQL-only `ifnull()` in its raw rule lookups (invalid on Postgres) and several raw `frappe.db.sql` selects. - Replace every `ifnull(...)` with the portable `coalesce(...)` in the rule-lookup statements that remain raw (they interpolate dynamic conditions and rely on Frappe's Postgres backtick translation). - Convert the user/role based_on lookups in validate_approving_authority and the four value-based lookups in get_value_based_rule to frappe.qb (Coalesce, isin, and a fresh Employee-designation subquery per use). Behaviour is unchanged on MariaDB; the queries now run on Postgres. Adds a test (no test file existed): a not-authorized case that exercises the based_on + coalesce rule lookups (run as a non-admin user, since Administrator implicitly holds every role), and a get_value_based_rule call that exercises all four query-builder lookups. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
100 lines
3.6 KiB
Python
100 lines
3.6 KiB
Python
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
# License: GNU General Public License v3. See license.txt"
|
|
|
|
|
|
import frappe
|
|
from frappe.defaults import get_user_default
|
|
from frappe.utils import cint
|
|
|
|
import erpnext.accounts.utils
|
|
|
|
|
|
def boot_session(bootinfo):
|
|
"""boot session - send website info if guest"""
|
|
|
|
if frappe.session["user"] != "Guest":
|
|
update_page_info(bootinfo)
|
|
|
|
bootinfo.sysdefaults.territory = frappe.get_single_value("Selling Settings", "territory")
|
|
bootinfo.sysdefaults.customer_group = frappe.get_single_value("Selling Settings", "customer_group")
|
|
bootinfo.sysdefaults.use_legacy_js_reactivity = cint(
|
|
frappe.get_single_value("Selling Settings", "use_legacy_js_reactivity")
|
|
)
|
|
bootinfo.sysdefaults.allow_stale = cint(frappe.get_single_value("Accounts Settings", "allow_stale"))
|
|
bootinfo.sysdefaults.over_billing_allowance = frappe.get_single_value(
|
|
"Accounts Settings", "over_billing_allowance"
|
|
)
|
|
|
|
bootinfo.sysdefaults.quotation_valid_till = cint(
|
|
frappe.db.get_single_value("CRM Settings", "default_valid_till")
|
|
)
|
|
|
|
bootinfo.sysdefaults.allow_sales_order_creation_for_expired_quotation = cint(
|
|
frappe.get_single_value("Selling Settings", "allow_sales_order_creation_for_expired_quotation")
|
|
)
|
|
|
|
# if no company, show a dialog box to create a new company
|
|
bootinfo.customer_count = frappe.db.count("Customer")
|
|
|
|
if not bootinfo.customer_count:
|
|
bootinfo.setup_complete = "Yes" if frappe.db.get_all("Company", limit=1) else "No"
|
|
|
|
companies = frappe.get_all(
|
|
"Company",
|
|
fields=[
|
|
"name",
|
|
"default_currency",
|
|
"cost_center",
|
|
"default_selling_terms",
|
|
"default_buying_terms",
|
|
"default_letter_head",
|
|
"default_letter_head_report",
|
|
"default_bank_account",
|
|
"enable_perpetual_inventory",
|
|
"country",
|
|
"exchange_gain_loss_account",
|
|
],
|
|
)
|
|
for company in companies:
|
|
company.doctype = ":Company"
|
|
bootinfo.docs += companies
|
|
|
|
party_account_types = frappe.get_all("Party Type", fields=["name", "account_type"], as_list=True)
|
|
bootinfo.party_account_types = frappe._dict(
|
|
(name, account_type or "") for name, account_type in party_account_types
|
|
)
|
|
fiscal_year = erpnext.accounts.utils.get_fiscal_years(
|
|
frappe.utils.nowdate(), company=get_user_default("company"), raise_on_missing=False
|
|
)
|
|
if fiscal_year:
|
|
bootinfo.current_fiscal_year = fiscal_year[0]
|
|
|
|
bootinfo.sysdefaults.demo_company = frappe.db.get_single_value("Global Defaults", "demo_company")
|
|
bootinfo.sysdefaults.default_ageing_range = frappe.db.get_single_value(
|
|
"Accounts Settings", "default_ageing_range"
|
|
)
|
|
bootinfo.sysdefaults.repost_allowed_doctypes = frappe.get_hooks("repost_allowed_doctypes")
|
|
|
|
|
|
def update_page_info(bootinfo):
|
|
bootinfo.page_info.update(
|
|
{
|
|
"Chart of Accounts": {"title": "Chart of Accounts", "route": "Tree/Account"},
|
|
"Chart of Cost Centers": {"title": "Chart of Cost Centers", "route": "Tree/Cost Center"},
|
|
"Item Group Tree": {"title": "Item Group Tree", "route": "Tree/Item Group"},
|
|
"Customer Group Tree": {"title": "Customer Group Tree", "route": "Tree/Customer Group"},
|
|
"Territory Tree": {"title": "Territory Tree", "route": "Tree/Territory"},
|
|
"Sales Person Tree": {"title": "Sales Person Tree", "route": "Tree/Sales Person"},
|
|
}
|
|
)
|
|
|
|
|
|
def bootinfo(bootinfo):
|
|
if bootinfo.get("user") and bootinfo["user"].get("name"):
|
|
bootinfo["user"]["employee"] = ""
|
|
frappe.session.data.employee = ""
|
|
employee = frappe.db.get_value("Employee", {"user_id": bootinfo["user"]["name"]}, "name")
|
|
if employee:
|
|
bootinfo["user"]["employee"] = employee
|
|
frappe.session.data.employee = employee
|