Cant use number card with virtual doctype

Hi everyone, I have got error about virtual doctype when I use number card, programming show this:


Detail:
Traceback (most recent call last):
File “apps/frappe/frappe/app.py”, line 114, in application
response = frappe.api.handle(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File “apps/frappe/frappe/api/init.py”, line 49, in handle
data = endpoint(**arguments)
^^^^^^^^^^^^^^^^^^^^^
File “apps/frappe/frappe/api/v1.py”, line 36, in handle_rpc_call
return frappe.handler.handle()
^^^^^^^^^^^^^^^^^^^^^^^
File “apps/frappe/frappe/handler.py”, line 49, in handle
data = execute_cmd(cmd)
^^^^^^^^^^^^^^^^
File “apps/frappe/frappe/handler.py”, line 85, in execute_cmd
return frappe.call(method, **frappe.form_dict)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “apps/frappe/frappe/init.py”, line 1768, in call
return fn(*args, **newargs)
^^^^^^^^^^^^^^^^^^^^
File “apps/frappe/frappe/utils/typing_validations.py”, line 31, in wrapper
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File “apps/frappe/frappe/desk/doctype/number_card/number_card.py”, line 157, in get_result
number = res[0][“result”] if res else 0
~~~~~~^^^^^^^^^^
KeyError: ‘result’

Hi, I found solution, Virtual Doctype does not automatically return the format that the Get_Number_card function needs, you can check out and add it to virtual doctype python file:

def apply_fields(data, fields):
		result_data = [ ]
		for field in fields:
			result = {}
			if "count(*)" in field:
				result["result"] = len(data)
			elif field.startswith("sum") or field.startswith("avg") or field.startswith("min") or field.startswith("max"):
				field_name = field.split("(")[1].split(")")[0]
				result["result"] = calculate_aggregate(data, field_name, field.split("(")[0])
			result_data.append(result)

		return result_data

	def calculate_aggregate(data, field_name, function):
		values = [doc[field_name] for name, doc in data.items() if field_name in doc]
		if function == "sum":
			return sum(values)
		elif function == "avg":
			return sum(values) / len(values) if values else 0
		elif function == "min":
			return min(values) if values else 0
		elif function == "max":
			return max(values) if values else 0
		return 0
@staticmethod
	def get_list(args):
		fields = args.get("fields", ["*"])
		data = get_current_data()
		if len(fields) == 1:
			field = fields[0]
			if "count(*)" in field or field.startswith("sum") or field.startswith("avg") or field.startswith("min") or field.startswith("max"):
				data = apply_fields(data, fields)
				print("Data Result: ", data)
				return data

1 Like

Thanks @SKDragon18 for bringing the solution!

1 Like