* fix(query): check standard field definitions Signed-off-by: Akhil Narang <me@akhilnarang.dev> * fix(postgres): fix order_by problem in pg * fix(postgres): fix order_by in get_all for _test_connection_query * fix: add check to a proper numeric fallback in _get_ifnull_fallback * test(postgres): fix pg query used in assertion in test_permission_query * fix(postgres): fix order_by in get_all for possible_link * fix(postgres): fix order_by in get_all for set_modules * fix(postgres): fix pg query count * * fix(postgres): fix order_by in get_all for ask_pass_update * fix(postgres): fix order_by statement in search_widget * fix(postgres): fix order_by in get_list for get_stats * test(postgres): normalize_sql for pg queries in test_arithmetic_operators_in_fields * test(postgres): normalize_sql for pg queries in test_field_alias_in_group_by * test(postgres): normalize_sql for pg queries in test_field_alias_permission_check * test(postgres): fix order_by statement in get_all for test_db_keywords_as_fields * test(postgres): fix order_by statement in get_all for test_prepare_select_args * fix(treeview): use 0 instead of false to check since check field is an integer * fix(postgres): fix order_by in get_all for sync_communication * fix(postgres): fix order_by in get_all for get_references_across_doctypes_by_dynamic_link_field * test(postgres): fix order_by in get_all for test_list_summary * fix(postgres): fix order_by in get_all for email queries * test(postgres): use order_by none and update assertion for postgres * fix(postgres): use ILIKE to support case insensitive search in postgres * test(test_query): update pg specific query assert to use ILIKE * test(test_query): update test_nested_filters to use ilike instead for PG * test(postgres): update pg query in assert to test updated qb query * fix(search): update query to be db-agnostic * test(postgres): normalize query for pg in test_build_match_conditions * fix(postgres): suppress ORDER BY when SELECT DISTINCT in query for postgres specific behavior * fix(postgres): suppress ORDER BY when GROUP BY is explicitly asked for pg specific behavior * test(postgres): fix test behavior for pg ORDER BY drop when used with GROUP BY * refactor: reducing noise in code by formatting code * fix(query): use Star() to handle SQL wildcard character * correctly * fix(postgres): display warning for ORDER BY fields that will be dropped --------- Signed-off-by: Akhil Narang <me@akhilnarang.dev> Co-authored-by: Akhil Narang <me@akhilnarang.dev>
89 lines
2.3 KiB
Python
89 lines
2.3 KiB
Python
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
# License: MIT. See LICENSE
|
|
|
|
import frappe
|
|
from frappe import _
|
|
from frappe.query_builder import Field, functions
|
|
|
|
|
|
@frappe.whitelist()
|
|
def get_all_nodes(doctype, label, parent, tree_method, **filters):
|
|
"""Recursively gets all data from tree nodes"""
|
|
|
|
filters.pop("cmd", None)
|
|
filters.pop("data", None)
|
|
|
|
tree_method = frappe.get_attr(tree_method)
|
|
|
|
frappe.is_whitelisted(tree_method)
|
|
|
|
data = tree_method(doctype, parent, **filters)
|
|
out = [dict(parent=label, data=data)]
|
|
|
|
filters.pop("is_root", None)
|
|
to_check = [d.get("value") for d in data if d.get("expandable")]
|
|
|
|
while to_check:
|
|
parent = to_check.pop()
|
|
data = tree_method(doctype, parent, is_root=False, **filters)
|
|
out.append(dict(parent=parent, data=data))
|
|
for d in data:
|
|
if d.get("expandable"):
|
|
to_check.append(d.get("value"))
|
|
|
|
return out
|
|
|
|
|
|
@frappe.whitelist()
|
|
def get_children(doctype, parent="", include_disabled=False, **filters):
|
|
if isinstance(include_disabled, str):
|
|
include_disabled = frappe.sbool(include_disabled)
|
|
return _get_children(doctype, parent, include_disabled=include_disabled)
|
|
|
|
|
|
def _get_children(doctype, parent="", ignore_permissions=False, include_disabled=False):
|
|
parent_field = "parent_" + frappe.scrub(doctype)
|
|
meta = frappe.get_meta(doctype)
|
|
|
|
qb = (
|
|
frappe.qb.from_(doctype)
|
|
.select(
|
|
Field("name").as_("value"),
|
|
Field(meta.get("title_field") or "name").as_("title"),
|
|
Field("is_group").as_("expandable"),
|
|
)
|
|
.where(functions.IfNull(Field(parent_field), "").eq(parent))
|
|
.where(Field("docstatus") < 2)
|
|
)
|
|
|
|
if frappe.db.has_column(doctype, "disabled") and not include_disabled:
|
|
# used 0 instead of `false` since type of check in postgres is smallint
|
|
qb = qb.where(Field("disabled").eq(0))
|
|
# Order by name and execute
|
|
return qb.orderby("name").run(as_dict=True)
|
|
|
|
|
|
@frappe.whitelist()
|
|
def add_node():
|
|
args = make_tree_args(**frappe.form_dict)
|
|
doc = frappe.get_doc(args)
|
|
|
|
doc.save()
|
|
|
|
|
|
def make_tree_args(**kwarg):
|
|
kwarg.pop("cmd", None)
|
|
|
|
doctype = kwarg["doctype"]
|
|
parent_field = "parent_" + frappe.scrub(doctype)
|
|
|
|
if kwarg["is_root"] == "false":
|
|
kwarg["is_root"] = False
|
|
if kwarg["is_root"] == "true":
|
|
kwarg["is_root"] = True
|
|
|
|
parent = kwarg.get("parent") or kwarg.get(parent_field)
|
|
if doctype != parent:
|
|
kwarg.update({parent_field: parent})
|
|
|
|
return frappe._dict(kwarg)
|