[fix] filters for calendars frappe/erpnext#9850 (#3686)
* [fix] filters for calendars frappe/erpnext#9850 * [add] tests
This commit is contained in:
parent
45cff1a195
commit
368bbeeb29
6 changed files with 89 additions and 139 deletions
|
|
@ -62,7 +62,6 @@ frappe.ui.form.on('Test Runner', {
|
|||
|
||||
QUnit.done(({ total, failed, passed, runtime }) => {
|
||||
// flag for selenium that test is done
|
||||
$('<div id="frappe-qunit-done"></div>').appendTo($('body'));
|
||||
|
||||
console.log( `Total: ${total}, Failed: ${failed}, Passed: ${passed}, Runtime: ${runtime}` ); // eslint-disable-line
|
||||
|
||||
|
|
@ -72,6 +71,9 @@ frappe.ui.form.on('Test Runner', {
|
|||
console.log('Tests Passed'); // eslint-disable-line
|
||||
}
|
||||
frappe.set_route('Form', 'Test Runner', 'Test Runner');
|
||||
|
||||
$('<div id="frappe-qunit-done"></div>').appendTo($('body'));
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -19,16 +19,8 @@ def update_event(args, field_map):
|
|||
|
||||
def get_event_conditions(doctype, filters=None):
|
||||
"""Returns SQL conditions with user permissions and filters for event queries"""
|
||||
from frappe.desk.reportview import build_match_conditions
|
||||
from frappe.desk.reportview import get_filters_cond
|
||||
if not frappe.has_permission(doctype):
|
||||
frappe.throw(_("Not Permitted"), frappe.PermissionError)
|
||||
|
||||
conditions = build_match_conditions(doctype)
|
||||
conditions = conditions and (" and " + conditions) or ""
|
||||
if filters:
|
||||
filters = json.loads(filters)
|
||||
for key in filters:
|
||||
if filters[key]:
|
||||
conditions += 'and `{0}` = "{1}"'.format(frappe.db.escape(key), frappe.db.escape(filters[key]))
|
||||
|
||||
return conditions
|
||||
return get_filters_cond(doctype, filters, [], with_match_conditions = True)
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ def build_match_conditions(doctype, as_condition=True):
|
|||
else:
|
||||
return match_conditions
|
||||
|
||||
def get_filters_cond(doctype, filters, conditions, ignore_permissions=None):
|
||||
def get_filters_cond(doctype, filters, conditions, ignore_permissions=None, with_match_conditions=False):
|
||||
if filters:
|
||||
flt = filters
|
||||
if isinstance(filters, dict):
|
||||
|
|
@ -350,6 +350,10 @@ def get_filters_cond(doctype, filters, conditions, ignore_permissions=None):
|
|||
query = DatabaseQuery(doctype)
|
||||
query.filters = flt
|
||||
query.conditions = conditions
|
||||
|
||||
if with_match_conditions:
|
||||
query.build_match_conditions()
|
||||
|
||||
query.build_filter_conditions(flt, conditions, ignore_permissions)
|
||||
|
||||
cond = ' and ' + ' and '.join(query.conditions)
|
||||
|
|
|
|||
|
|
@ -113,13 +113,20 @@ frappe.ui.Page = Class.extend({
|
|||
},
|
||||
|
||||
set_action: function(btn, opts) {
|
||||
let me = this;
|
||||
if (opts.icon) {
|
||||
opts.label = this.get_icon_label(opts.icon, opts.label);
|
||||
}
|
||||
|
||||
this.clear_action_of(btn);
|
||||
|
||||
btn.removeClass("hide").prop("disabled", false).html(opts.label).on("click", opts.click);
|
||||
btn.removeClass("hide")
|
||||
.prop("disabled", false)
|
||||
.html(opts.label)
|
||||
.on("click", function() {
|
||||
let response = opts.click.apply(this);
|
||||
me.btn_disable_enable(btn, response);
|
||||
});
|
||||
|
||||
if (opts.working_label) {
|
||||
btn.attr("data-working-label", opts.working_label);
|
||||
|
|
@ -250,31 +257,35 @@ frappe.ui.Page = Class.extend({
|
|||
this.get_inner_group_button(label).find("button").removeClass("btn-default").addClass("btn-primary");
|
||||
},
|
||||
|
||||
btn_disable_enable: function(btn, response) {
|
||||
if (response && response.then) {
|
||||
btn.prop('disabled', true);
|
||||
response.then(() => {
|
||||
btn.prop('disabled', false);
|
||||
})
|
||||
} else if (response && response.always) {
|
||||
btn.prop('disabled', true);
|
||||
response.always(() => {
|
||||
btn.prop('disabled', false);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
add_inner_button: function(label, action, group) {
|
||||
let _action = function() {
|
||||
let btn = $(this);
|
||||
let _ret = action();
|
||||
if (_ret && _ret.then) {
|
||||
// returns a promise
|
||||
btn.attr('disabled', true);
|
||||
_ret.then(() => {
|
||||
btn.attr('disabled', false);
|
||||
})
|
||||
}
|
||||
if (_ret && _ret.always) {
|
||||
// returns frappe.call ($.ajax)
|
||||
btn.attr('disabled', true);
|
||||
_ret.always(() => {
|
||||
btn.attr('disabled', false);
|
||||
});
|
||||
}
|
||||
}
|
||||
let response = action();
|
||||
this.btn_disable_enable(btn, response);
|
||||
};
|
||||
if(group) {
|
||||
var $group = this.get_inner_group_button(group);
|
||||
return $('<li><a>'+label+'</a></li>').on('click', _action).appendTo($group.find(".dropdown-menu"));
|
||||
return $('<li><a>'+label+'</a></li>')
|
||||
.on('click', _action)
|
||||
.appendTo($group.find(".dropdown-menu"));
|
||||
} else {
|
||||
return $('<button class="btn btn-default btn-xs" style="margin-left: 10px;">'+__(label)+'</btn>')
|
||||
.on("click", _action).appendTo(this.inner_toolbar.removeClass("hide"))
|
||||
.on("click", _action)
|
||||
.appendTo(this.inner_toolbar.removeClass("hide"));
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ frappe.views.CalendarView = frappe.views.ListRenderer.extend({
|
|||
doctype: this.doctype,
|
||||
parent: this.wrapper,
|
||||
page: this.list_view.page,
|
||||
filter_vals: this.list_view.filter_list.get_filters()
|
||||
list_view: this.list_view
|
||||
}
|
||||
$.extend(options, frappe.views.calendar[this.doctype]);
|
||||
this.calendar = new frappe.views.Calendar(options);
|
||||
|
|
@ -45,6 +45,7 @@ frappe.views.Calendar = Class.extend({
|
|||
var me = this;
|
||||
|
||||
// add links to other calendars
|
||||
me.page.clear_user_actions();
|
||||
$.each(frappe.boot.calendars, function(i, doctype) {
|
||||
if(frappe.model.can_read(doctype)) {
|
||||
me.page.add_menu_item(__(doctype), function() {
|
||||
|
|
@ -196,19 +197,11 @@ frappe.views.Calendar = Class.extend({
|
|||
}
|
||||
},
|
||||
get_args: function(start, end) {
|
||||
if(this.filter_vals) {
|
||||
var filters = {};
|
||||
this.filter_vals.forEach(function(f) {
|
||||
if(f[2]==="=") {
|
||||
filters[f[1]] = f[3];
|
||||
}
|
||||
});
|
||||
}
|
||||
var args = {
|
||||
doctype: this.doctype,
|
||||
start: this.get_system_datetime(start),
|
||||
end: this.get_system_datetime(end),
|
||||
filters: filters
|
||||
filters: this.list_view.filter_list.get_filters()
|
||||
};
|
||||
return args;
|
||||
},
|
||||
|
|
@ -309,50 +302,5 @@ frappe.views.Calendar = Class.extend({
|
|||
event.start = event.start ? $.fullCalendar.moment(event.start).stripTime() : null;
|
||||
event.end = event.end ? $.fullCalendar.moment(event.end).add(1, "day").stripTime() : null;
|
||||
}
|
||||
},
|
||||
add_filters: function() {
|
||||
var me = this;
|
||||
if(this.filters) {
|
||||
$.each(this.filters, function(i, df) {
|
||||
df.change = function() {
|
||||
me.refresh();
|
||||
};
|
||||
me.page.add_field(df);
|
||||
});
|
||||
}
|
||||
},
|
||||
set_filter: function(doctype, value) {
|
||||
var me = this;
|
||||
if(this.filters) {
|
||||
$.each(this.filters, function(i, df) {
|
||||
if(df.options===value)
|
||||
me.page.fields_dict[df.fieldname].set_input(value);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
},
|
||||
get_filters: function() {
|
||||
var filter_vals = {},
|
||||
me = this;
|
||||
if(this.filters) {
|
||||
$.each(this.filters, function(i, df) {
|
||||
filter_vals[df.fieldname || df.label] =
|
||||
me.page.fields_dict[df.fieldname || df.label].get_value();
|
||||
});
|
||||
}
|
||||
return filter_vals;
|
||||
},
|
||||
set_filters_from_route_options: function() {
|
||||
var me = this;
|
||||
if(frappe.route_options) {
|
||||
$.each(frappe.route_options, function(k, value) {
|
||||
if(me.page.fields_dict[k]) {
|
||||
me.page.fields_dict[k].set_input(value);
|
||||
}
|
||||
})
|
||||
frappe.route_options = null;
|
||||
me.refresh();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,88 +1,81 @@
|
|||
QUnit.module('views');
|
||||
|
||||
QUnit.test("Calendar View Tests", function(assert) {
|
||||
assert.expect(6);
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
let random_text = frappe.utils.get_random(10);
|
||||
let random_text = frappe.utils.get_random(3);
|
||||
let today = frappe.datetime.get_today()+" 16:20:35"; //arbitrary value taken to prevent cases like 12a for 12:00am and 12h to 24h conversion
|
||||
let visible_time = () => {
|
||||
// Method to return the start-time (hours) of the event visible
|
||||
return $('.fc-time').text().split('p')[0]; // 'p' because the arbitrary time is pm
|
||||
// Method to return the start-time (hours) of the event visible
|
||||
return $('.fc-time').text().split('p')[0]; // 'p' because the arbitrary time is pm
|
||||
};
|
||||
let event_title_text = () => {
|
||||
// Method to return the title of the event visible
|
||||
// Method to return the title of the event visible
|
||||
return $('.fc-title:visible').text();
|
||||
};
|
||||
|
||||
frappe.run_serially([
|
||||
// Create an event using the frappe API
|
||||
// create 2 events, one private, one public
|
||||
() => frappe.tests.make("Event", [
|
||||
{subject: random_text},
|
||||
{subject: random_text + ':Pri'},
|
||||
{starts_on: today},
|
||||
{event_type: 'Private'}
|
||||
]),
|
||||
|
||||
|
||||
() => frappe.tests.make("Event", [
|
||||
{subject: random_text + ':Pub'},
|
||||
{starts_on: today},
|
||||
{event_type: 'Public'}
|
||||
]),
|
||||
|
||||
// Goto Calendar view
|
||||
() => frappe.set_route(["List", "Event", "Calendar"]),
|
||||
() => frappe.tests.click_page_head_item("Refresh"),
|
||||
() => {
|
||||
// clear filter
|
||||
$('[data-fieldname="event_type"]').val('').trigger('change');
|
||||
},
|
||||
() => frappe.timeout(2),
|
||||
// Check if event is created
|
||||
() => {
|
||||
// Check if the event exists and if its title matches with the one created
|
||||
assert.ok(event_title_text().includes(random_text), "Event title verified");
|
||||
assert.ok(event_title_text().includes(random_text + ':Pri'),
|
||||
"Event title verified");
|
||||
// Check if time of event created is correct
|
||||
assert.ok(visible_time().includes("4:20"), "Event start time verified");
|
||||
assert.ok(visible_time().includes("4:20"),
|
||||
"Event start time verified");
|
||||
},
|
||||
|
||||
// Delete event
|
||||
// check filter
|
||||
() => {
|
||||
$('[data-fieldname="event_type"]').val('Public').trigger('change');
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
// private event should be hidden
|
||||
assert.notOk(event_title_text().includes(random_text + ':Pri'),
|
||||
"Event title verified");
|
||||
},
|
||||
|
||||
// Delete event
|
||||
// Goto Calendar view
|
||||
() => frappe.set_route(["List", "Event", "Calendar"]),
|
||||
() => frappe.timeout(1),
|
||||
// Open the event to be deleted
|
||||
() => frappe.tests.click_generic_text(random_text),
|
||||
() => frappe.tests.click_page_head_item('Menu'),
|
||||
() => frappe.tests.click_dropdown_item('Delete'),
|
||||
() => frappe.tests.click_page_head_item('Yes'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.tests.click_page_head_item("Refresh"),
|
||||
() => frappe.timeout(1),
|
||||
// Goto Calendar View
|
||||
// delete event
|
||||
() => frappe.tests.click_generic_text(random_text + ':Pub'),
|
||||
() => {
|
||||
frappe.tests.click_page_head_item('Menu');
|
||||
frappe.tests.click_dropdown_item('Delete');
|
||||
},
|
||||
() => frappe.timeout(0.5),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(2),
|
||||
() => frappe.set_route(["List", "Event", "Calendar"]),
|
||||
() => frappe.tests.click_button("Refresh"),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
// Check if all menu items redirect to correct locations
|
||||
// Check if clicking on 'Import' redirects you to ["data-import-tool"]
|
||||
() => frappe.tests.click_page_head_item('Menu'),
|
||||
() => frappe.tests.click_dropdown_item('Import'),
|
||||
() => assert.deepEqual(["data-import-tool"], frappe.get_route(), "Routed to 'data-import-tool' by clicking on 'Import'"),
|
||||
() => frappe.set_route(["List", "Event", "Calendar"]),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
// Check if clicking on 'User Permissions Manager' redirects you to ["user-permissions"]
|
||||
() => frappe.tests.click_page_head_item('Menu'),
|
||||
() => frappe.tests.click_dropdown_item('User Permissions Manager'),
|
||||
() => assert.deepEqual(["user-permissions"], frappe.get_route(), "Routed to 'user-permissions' by clicking on 'User Permissions Manager'"),
|
||||
() => frappe.set_route(["List", "Event", "Calendar"]),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
// Check if clicking on 'Role Permissions Manager' redirects you to ["permission-manager"]
|
||||
() => frappe.tests.click_page_head_item('Menu'),
|
||||
() => frappe.tests.click_dropdown_item('Role Permissions Manager'),
|
||||
() => assert.deepEqual(["permission-manager"], frappe.get_route(), "Routed to 'permission-manager' by clicking on 'Role Permissions Manager'"),
|
||||
() => frappe.set_route(["List", "Event", "Calendar"]),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
// // Check if clicking on 'Customize' redirects you to ["Form", "Customize Form"]
|
||||
// *** ERROR HERE IN FRAPPE: UNCOMMENT THIS ONCE THAT IS RESOLVED *** //
|
||||
// () => frappe.tests.click_page_head_item('Menu'),
|
||||
// () => frappe.tests.click_dropdown_item('Customize'),
|
||||
// () => assert.deepEqual(["Form", "Customize Form"], frappe.get_route(), "Routed to 'Form, Customize Form' by clicking on 'Customize'"),
|
||||
// () => frappe.set_route(["List", "Event", "Calendar"]),
|
||||
// () => frappe.timeout(3),
|
||||
|
||||
// Check if event is deleted
|
||||
() => assert.notOk(event_title_text().includes(random_text), "Event deleted"),
|
||||
|
||||
() => assert.notOk(event_title_text().includes(random_text + ':Pub'),
|
||||
"Event deleted"),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue