diff --git a/frappe/model/db_query.py b/frappe/model/db_query.py index 26075f4daa..d0db452ae7 100644 --- a/frappe/model/db_query.py +++ b/frappe/model/db_query.py @@ -308,15 +308,7 @@ class DatabaseQuery(object): if f.operator.lower() == 'between' and \ (f.fieldname in ('creation', 'modified') or (df and (df.fieldtype=="Date" or df.fieldtype=="Datetime"))): - from_date = None - to_date = None - if f.value and isinstance(f.value, (list, tuple)): - if len(f.value) >= 1: from_date = f.value[0] - if len(f.value) >= 2: to_date = f.value[1] - - value = "'%s' AND '%s'" % ( - add_to_date(get_datetime(from_date),days=-1).strftime("%Y-%m-%d %H:%M:%S.%f"), - get_datetime(to_date).strftime("%Y-%m-%d %H:%M:%S.%f")) + value = get_between_date_filter(f.value) fallback = "'0000-00-00 00:00:00'" elif df and df.fieldtype=="Date": @@ -584,7 +576,56 @@ 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): + #check if filters contains only parent doctype + only_parent_doctype = True + if isinstance(filters, list): - filters = frappe.utils.make_filter_dict(filters) + for flt in filters: + if doctype not in flt: + only_parent_doctype = False + if 'Between' in flt: + flt[3] = get_between_date_filter(flt[3]) + + return only_parent_doctype + +def get_between_date_filter(value): + from_date = None + to_date = None + + if value and isinstance(value, (list, tuple)): + if len(value) >= 1: from_date = value[0] + if len(value) >= 2: to_date = value[1] + + data = "'%s' AND '%s'" % ( + add_to_date(get_datetime(from_date),days=-1).strftime("%Y-%m-%d %H:%M:%S.%f"), + get_datetime(to_date).strftime("%Y-%m-%d %H:%M:%S.%f")) - return frappe.db.count(doctype, filters=filters) + return data diff --git a/frappe/public/js/frappe/list/list_renderer.js b/frappe/public/js/frappe/list/list_renderer.js index 7a831b6606..d7faf78331 100644 --- a/frappe/public/js/frappe/list/list_renderer.js +++ b/frappe/public/js/frappe/list/list_renderer.js @@ -368,7 +368,7 @@ frappe.views.ListRenderer = Class.extend({ filters: this.list_view.get_filters_args() } }).then(r => { - const count = r.message; + const count = r.message ? r.message : current_count; const $html = $(`${current_count} of ${count}`); $html.css({ diff --git a/frappe/tests/ui/test_list_count.js b/frappe/tests/ui/test_list_count.js new file mode 100644 index 0000000000..0261555840 --- /dev/null +++ b/frappe/tests/ui/test_list_count.js @@ -0,0 +1,34 @@ +QUnit.module('Setup'); + +QUnit.test("Test List Count", function(assert) { + assert.expect(3); + const done = assert.async(); + + frappe.run_serially([ + () => frappe.set_route('List', 'DocType'), + () => frappe.timeout(0.5), + () => { + let count = $('.list-row-right').text().split(' ')[0]; + assert.equal(cur_list.data.length, count, "Correct Count"); + }, + + () => frappe.timeout(1), + () => cur_list.filter_list.add_filter('Doctype', 'module', '=', 'Desk'), + () => frappe.click_button('Refresh'), + () => { + let count = $('.list-row-right').text().split(' ')[0]; + assert.equal(cur_list.data.length, count, "Correct Count"); + }, + + () => cur_list.filter_list.clear_filters(), + () => frappe.timeout(1), + () => { + cur_list.filter_list.push_new_filter('DocField', 'fieldname', 'like', 'owner'); + frappe.click_button('Apply'); + let count = $('.list-row-right').text().split(' ')[0]; + assert.equal(cur_list.data.length, count, "Correct Count"); + }, + + done + ]); +}); \ No newline at end of file diff --git a/frappe/tests/ui/tests.txt b/frappe/tests/ui/tests.txt index 076d1a515b..7ed6e80be6 100644 --- a/frappe/tests/ui/tests.txt +++ b/frappe/tests/ui/tests.txt @@ -17,3 +17,4 @@ frappe/tests/ui/test_control_html.js frappe/tests/ui/test_control_geolocation.js frappe/core/doctype/role_profile/test_role_profile.js frappe/core/doctype/user/test_user_with_role_profile.js +frappe/tests/ui/test_list_count.js