@@ -14,7 +14,7 @@ import os, sys, importlib, inspect, json | |||||
from .exceptions import * | from .exceptions import * | ||||
from .utils.jinja import get_jenv, get_template, render_template, get_email_from_template | from .utils.jinja import get_jenv, get_template, render_template, get_email_from_template | ||||
__version__ = '10.0.5' | |||||
__version__ = '10.0.6' | |||||
__title__ = "Frappe Framework" | __title__ = "Frappe Framework" | ||||
local = Local() | local = Local() | ||||
@@ -34,7 +34,7 @@ def import_data(data_import): | |||||
frappe.publish_realtime("data_import_progress", {"progress": "0", | frappe.publish_realtime("data_import_progress", {"progress": "0", | ||||
"data_import": data_import, "reload": True}, user=frappe.session.user) | "data_import": data_import, "reload": True}, user=frappe.session.user) | ||||
enqueue(upload, queue='default', timeout=6000, event='data_import', | enqueue(upload, queue='default', timeout=6000, event='data_import', | ||||
data_import_doc=data_import, from_data_import="Yes", validate_template=False) | |||||
data_import_doc=data_import, from_data_import="Yes", user=frappe.session.user) | |||||
def import_doc(path, overwrite=False, ignore_links=False, ignore_insert=False, | def import_doc(path, overwrite=False, ignore_links=False, ignore_insert=False, | ||||
@@ -34,9 +34,13 @@ def get_data_keys(): | |||||
@frappe.whitelist() | @frappe.whitelist() | ||||
def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, no_email=True, overwrite=None, | def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, no_email=True, overwrite=None, | ||||
update_only = None, ignore_links=False, pre_process=None, via_console=False, from_data_import="No", | update_only = None, ignore_links=False, pre_process=None, via_console=False, from_data_import="No", | ||||
skip_errors = True, data_import_doc=None, validate_template=False): | |||||
skip_errors = True, data_import_doc=None, validate_template=False, user=None): | |||||
"""upload data""" | """upload data""" | ||||
# for translations | |||||
if user: | |||||
frappe.set_user_lang(user) | |||||
if data_import_doc and isinstance(data_import_doc, string_types): | if data_import_doc and isinstance(data_import_doc, string_types): | ||||
data_import_doc = frappe.get_doc("Data Import", data_import_doc) | data_import_doc = frappe.get_doc("Data Import", data_import_doc) | ||||
if data_import_doc and from_data_import == "Yes": | if data_import_doc and from_data_import == "Yes": | ||||
@@ -72,7 +76,6 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, | |||||
frappe.throw(_("Please do not change the rows above {0}").format(get_data_keys_definition().data_separator)) | frappe.throw(_("Please do not change the rows above {0}").format(get_data_keys_definition().data_separator)) | ||||
def check_data_length(): | def check_data_length(): | ||||
max_rows = 5000 | |||||
if not data: | if not data: | ||||
frappe.throw(_("No data found in the file. Please reattach the new file with data.")) | frappe.throw(_("No data found in the file. Please reattach the new file with data.")) | ||||
@@ -50,11 +50,13 @@ def get_form_params(): | |||||
for field in fields: | for field in fields: | ||||
key = field.split(" as ")[0] | key = field.split(" as ")[0] | ||||
if key.startswith('count('): continue | |||||
if "." in key: | if "." in key: | ||||
parenttype, fieldname = key.split(".")[0][4:-1], key.split(".")[1].strip("`") | parenttype, fieldname = key.split(".")[0][4:-1], key.split(".")[1].strip("`") | ||||
else: | else: | ||||
parenttype = data.doctype | parenttype = data.doctype | ||||
fieldname = fieldname.strip("`") | |||||
fieldname = field.strip("`") | |||||
df = frappe.get_meta(parenttype).get_field(fieldname) | df = frappe.get_meta(parenttype).get_field(fieldname) | ||||
@@ -67,6 +67,9 @@ def make_tree_args(**kwarg): | |||||
parent_field = 'parent_' + doctype.lower().replace(' ', '_') | parent_field = 'parent_' + doctype.lower().replace(' ', '_') | ||||
name_field = kwarg.get('name_field', doctype.lower().replace(' ', '_') + '_name') | name_field = kwarg.get('name_field', doctype.lower().replace(' ', '_') + '_name') | ||||
if kwarg['is_root'] == 'false': kwarg['is_root'] = False | |||||
if kwarg['is_root'] == 'true': kwarg['is_root'] = True | |||||
kwarg.update({ | kwarg.update({ | ||||
name_field: kwarg[name_field], | name_field: kwarg[name_field], | ||||
parent_field: kwarg.get("parent") or kwarg.get(parent_field) | parent_field: kwarg.get("parent") or kwarg.get(parent_field) | ||||
@@ -185,8 +185,8 @@ class DatabaseQuery(object): | |||||
# add tables from fields | # add tables from fields | ||||
if self.fields: | if self.fields: | ||||
for f in self.fields: | for f in self.fields: | ||||
if ( not ("tab" in f and "." in f) ) or ("locate(" in f): continue | |||||
if ( not ("tab" in f and "." in f) ) or ("locate(" in f) or ("count(" in f): | |||||
continue | |||||
table_name = f.split('.')[0] | table_name = f.split('.')[0] | ||||
if table_name.lower().startswith('group_concat('): | if table_name.lower().startswith('group_concat('): | ||||
@@ -571,38 +571,6 @@ def get_list(doctype, *args, **kwargs): | |||||
kwargs.pop('cmd', None) | kwargs.pop('cmd', None) | ||||
return DatabaseQuery(doctype).execute(None, *args, **kwargs) | return DatabaseQuery(doctype).execute(None, *args, **kwargs) | ||||
@frappe.whitelist() | |||||
def get_count(doctype, filters=None): | |||||
if filters: | |||||
filters = json.loads(filters) | |||||
if is_parent_only_filter(doctype, filters): | |||||
if isinstance(filters, list): | |||||
filters = frappe.utils.make_filter_dict(filters) | |||||
return frappe.db.count(doctype, filters=filters) | |||||
else: | |||||
# If filters contain child table as well as parent doctype - Join | |||||
tables, conditions = ['`tab{0}`'.format(doctype)], [] | |||||
for f in filters: | |||||
fieldname = '`tab{0}`.{1}'.format(f[0], f[1]) | |||||
table = '`tab{0}`'.format(f[0]) | |||||
if table not in tables: | |||||
tables.append(table) | |||||
conditions.append('{fieldname} {operator} "{value}"'.format(fieldname=fieldname, | |||||
operator=f[2], value=f[3])) | |||||
if doctype != f[0]: | |||||
join_condition = '`tab{child_doctype}`.parent =`tab{doctype}`.name'.format(child_doctype=f[0], doctype=doctype) | |||||
if join_condition not in conditions: | |||||
conditions.append(join_condition) | |||||
return frappe.db.sql_list("""select count(*) from {0} | |||||
where {1}""".format(','.join(tables), ' and '.join(conditions)), debug=0) | |||||
def is_parent_only_filter(doctype, filters): | def is_parent_only_filter(doctype, filters): | ||||
#check if filters contains only parent doctype | #check if filters contains only parent doctype | ||||
only_parent_doctype = True | only_parent_doctype = True | ||||
@@ -57,19 +57,20 @@ def export_customizations(module, doctype, sync_on_migrate=0, with_permissions=0 | |||||
custom['custom_perms'] = frappe.get_all('Custom DocPerm', | custom['custom_perms'] = frappe.get_all('Custom DocPerm', | ||||
fields='*', filters={'parent': doctype}) | fields='*', filters={'parent': doctype}) | ||||
# add custom fields and property setters for all child tables | |||||
# also update the custom fields and property setters for all child tables | |||||
for d in frappe.get_meta(doctype).get_table_fields(): | for d in frappe.get_meta(doctype).get_table_fields(): | ||||
add(d.options) | |||||
export_customizations(module, d.options, sync_on_migrate, with_permissions) | |||||
folder_path = os.path.join(get_module_path(module), 'custom') | |||||
if not os.path.exists(folder_path): | |||||
os.makedirs(folder_path) | |||||
if custom["custom_fields"] or custom["property_setters"] or custom["custom_perms"]: | |||||
folder_path = os.path.join(get_module_path(module), 'custom') | |||||
if not os.path.exists(folder_path): | |||||
os.makedirs(folder_path) | |||||
path = os.path.join(folder_path, scrub(doctype)+ '.json') | |||||
with open(path, 'w') as f: | |||||
f.write(frappe.as_json(custom)) | |||||
path = os.path.join(folder_path, scrub(doctype)+ '.json') | |||||
with open(path, 'w') as f: | |||||
f.write(frappe.as_json(custom)) | |||||
frappe.msgprint(_('Customizations exported to {0}').format(path)) | |||||
frappe.msgprint(_('Customizations for <b>{0}</b> exported to:<br>{1}').format(doctype,path)) | |||||
def sync_customizations(app=None): | def sync_customizations(app=None): | ||||
'''Sync custom fields and property setters from custom folder in each app module''' | '''Sync custom fields and property setters from custom folder in each app module''' | ||||
@@ -89,10 +90,10 @@ def sync_customizations(app=None): | |||||
data = json.loads(f.read()) | data = json.loads(f.read()) | ||||
if data.get('sync_on_migrate'): | if data.get('sync_on_migrate'): | ||||
sync_customizations_for_doctype(data) | |||||
sync_customizations_for_doctype(data, folder) | |||||
def sync_customizations_for_doctype(data): | |||||
def sync_customizations_for_doctype(data, folder): | |||||
'''Sync doctype customzations for a particular data set''' | '''Sync doctype customzations for a particular data set''' | ||||
from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype | from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype | ||||
@@ -101,13 +102,21 @@ def sync_customizations_for_doctype(data): | |||||
def sync(key, custom_doctype, doctype_fieldname): | def sync(key, custom_doctype, doctype_fieldname): | ||||
doctypes = list(set(map(lambda row: row.get(doctype_fieldname), data[key]))) | doctypes = list(set(map(lambda row: row.get(doctype_fieldname), data[key]))) | ||||
frappe.db.sql('delete from `tab{0}` where `{1}` in ({2})'.format( | |||||
custom_doctype, doctype_fieldname, ",".join(["'%s'" % dt for dt in doctypes]))) | |||||
for d in data[key]: | |||||
d['doctype'] = custom_doctype | |||||
doc = frappe.get_doc(d) | |||||
doc.db_insert() | |||||
# sync single doctype exculding the child doctype | |||||
def sync_single_doctype(doc_type): | |||||
frappe.db.sql('delete from `tab{0}` where `{1}` =%s'.format( | |||||
custom_doctype, doctype_fieldname), doc_type) | |||||
for d in data[key]: | |||||
if d.get(doctype_fieldname) == doc_type: | |||||
d['doctype'] = custom_doctype | |||||
doc = frappe.get_doc(d) | |||||
doc.db_insert() | |||||
for doc_type in doctypes: | |||||
# only sync the parent doctype and child doctype if there isn't any other child table json file | |||||
if doc_type == doctype or not os.path.exists(os.path.join(folder, frappe.scrub(doc_type)+".json")): | |||||
sync_single_doctype(doc_type) | |||||
if data['custom_fields']: | if data['custom_fields']: | ||||
sync('custom_fields', 'Custom Field', 'dt') | sync('custom_fields', 'Custom Field', 'dt') | ||||
@@ -364,13 +364,14 @@ frappe.views.ListRenderer = Class.extend({ | |||||
const current_count = this.list_view.data.length; | const current_count = this.list_view.data.length; | ||||
frappe.call({ | frappe.call({ | ||||
method: 'frappe.model.db_query.get_count', | |||||
method: 'frappe.desk.reportview.get', | |||||
args: { | args: { | ||||
doctype: this.doctype, | doctype: this.doctype, | ||||
filters: this.list_view.get_filters_args() | |||||
filters: this.list_view.get_filters_args(), | |||||
fields: ['count(`tab' + this.doctype + '`.name) as total_count'] | |||||
} | } | ||||
}).then(r => { | }).then(r => { | ||||
const count = r.message || current_count; | |||||
const count = r.message.values[0][0] || current_count; | |||||
const str = __('{0} of {1}', [current_count, count]); | const str = __('{0} of {1}', [current_count, count]); | ||||
const $html = $(`<span>${str}</span>`); | const $html = $(`<span>${str}</span>`); | ||||
@@ -253,6 +253,13 @@ frappe.views.TreeView = Class.extend({ | |||||
v.parent = node.label; | v.parent = node.label; | ||||
v.doctype = me.doctype; | v.doctype = me.doctype; | ||||
if(node.is_root){ | |||||
v['is_root'] = node.is_root; | |||||
} | |||||
else{ | |||||
v['is_root'] = false; | |||||
} | |||||
$.extend(args, v) | $.extend(args, v) | ||||
return frappe.call({ | return frappe.call({ | ||||
method: me.opts.add_tree_node || "frappe.desk.treeview.add_node", | method: me.opts.add_tree_node || "frappe.desk.treeview.add_node", | ||||