* fix(utils): add type hints to whitelisted methods * fix(desktop): add type hints to whitelisted methods * fix(listview): add type hints to whitelisted methods * fix(access_log): add type hints to whitelisted methods * fix(setup_wizard): add type hints to whitelisted methods * fix(notification_settings): add type hints to whitelisted methods * fix(calendar): add type hints to whitelisted methods * fix(notifications): add type hints to whitelisted methods * fix(query_report): add type hints to whitelisted methods * fix(load): add type hints to whitelisted methods * fix(save): add type hints to whitelisted methods * fix(user): add type hints to whitelisted methods * fix: correct Document import * fix(list_view_settings): add type hints to whitelisted methods * fix(reportview): add type hints to whitelisted methods * fix(treeview): add type hints to whitelisted methods * fix(linked_with): add type hints to whitelisted methods * fix(bulk_update): add type hints to whitelisted methods * fix(assign_to): add type hints to whitelisted methods * fix(workspace): add type hints to whitelisted methods * fix(kanban_board): add type hints to whitelisted methods * fix(event): add type hints to whitelisted methods * fix(email): add type hints to whitelisted methods * fix(exporter): add type hints to whitelisted methods * fix(permission_manager): add type hints to whitelisted methods * fix(dashboard_chart): add type hints to whitelisted methods * fix(number_card): add type hints to whitelisted methods * fix(tag): add type hints to whitelisted methods * fix: add hook to force type hints on all whitelisted endpoints * fix: target_doc can be dict/json string * fix: doc can be dict/json string * fix(tests): add type hints to whitelisted methods in test * fix: tree method is optional * test: Fix test api types * chore: drop dead code * fix: document can be int * fix: Number card input can be document As utils in some other API calls * fix: Always use session user The only usage of this API that makes sense. --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Ankush Menat <ankush@frappe.io>
102 lines
2.6 KiB
Python
102 lines
2.6 KiB
Python
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
|
|
# License: MIT. See LICENSE
|
|
|
|
from typing import Any
|
|
|
|
import frappe
|
|
from frappe.model import is_default_field
|
|
from frappe.query_builder import Order
|
|
from frappe.query_builder.functions import Count
|
|
from frappe.query_builder.terms import SubQuery
|
|
from frappe.query_builder.utils import DocType
|
|
|
|
|
|
@frappe.whitelist()
|
|
def get_list_settings(doctype: str):
|
|
try:
|
|
return frappe.get_cached_doc("List View Settings", doctype)
|
|
except frappe.DoesNotExistError:
|
|
frappe.clear_messages()
|
|
|
|
|
|
@frappe.whitelist()
|
|
def set_list_settings(doctype: str, values: str | dict[str, Any]):
|
|
try:
|
|
doc = frappe.get_doc("List View Settings", doctype)
|
|
except frappe.DoesNotExistError:
|
|
doc = frappe.new_doc("List View Settings")
|
|
doc.name = doctype
|
|
frappe.clear_messages()
|
|
doc.update(frappe.parse_json(values))
|
|
doc.save()
|
|
|
|
|
|
@frappe.whitelist()
|
|
def get_group_by_count(doctype: str, current_filters: str, field: str) -> list[dict]:
|
|
current_filters = frappe.parse_json(current_filters)
|
|
|
|
if field == "assigned_to":
|
|
ToDo = DocType("ToDo")
|
|
User = DocType("User")
|
|
count = Count("*").as_("count")
|
|
filtered_records = frappe.qb.get_query(
|
|
doctype,
|
|
filters=current_filters,
|
|
fields=["name"],
|
|
ignore_permissions=False,
|
|
)
|
|
|
|
return (
|
|
frappe.qb.from_(ToDo)
|
|
.from_(User)
|
|
.select(ToDo.allocated_to.as_("name"), count)
|
|
.where(
|
|
(ToDo.status != "Cancelled")
|
|
& (ToDo.allocated_to == User.name)
|
|
& (User.user_type == "System User")
|
|
& (ToDo.reference_name.isin(SubQuery(filtered_records)))
|
|
)
|
|
.groupby(ToDo.allocated_to)
|
|
.orderby(count, order=Order.desc)
|
|
.limit(50)
|
|
.run(as_dict=True)
|
|
)
|
|
|
|
meta = frappe.get_meta(doctype)
|
|
|
|
if not meta.has_field(field) and not is_default_field(field):
|
|
raise ValueError("Field does not belong to doctype")
|
|
|
|
data = frappe.get_list(
|
|
doctype,
|
|
filters=current_filters,
|
|
group_by=field,
|
|
fields=[{"COUNT": "*", "as": "count"}, f"{field} as name"],
|
|
order_by="count desc",
|
|
limit=1000,
|
|
)
|
|
|
|
if field == "owner":
|
|
owner_idx = None
|
|
|
|
for idx, item in enumerate(data):
|
|
if item.name == frappe.session.user:
|
|
owner_idx = idx
|
|
break
|
|
|
|
if owner_idx:
|
|
data = [data.pop(owner_idx), *data[0:49]]
|
|
else:
|
|
data = data[0:50]
|
|
else:
|
|
data = data[0:50]
|
|
|
|
# Add in title if it's a link field and `show_title_field_in_link` is set
|
|
if (field_meta := meta.get_field(field)) and field_meta.fieldtype == "Link":
|
|
link_meta = frappe.get_meta(field_meta.options)
|
|
if link_meta.show_title_field_in_link:
|
|
title_field = link_meta.get_title_field()
|
|
for item in data:
|
|
item.title = frappe.get_value(field_meta.options, item.name, title_field)
|
|
|
|
return data
|