Merge pull request #6824 from netchampfaris/feat-is-set-is-not-set
feat: New filter type "Is Set", "Is Not Set"
This commit is contained in:
commit
5af8d4d1bb
5 changed files with 43 additions and 19 deletions
|
|
@ -409,6 +409,19 @@ class DatabaseQuery(object):
|
|||
value = get_time(f.value).strftime("%H:%M:%S.%f")
|
||||
fallback = "'00:00:00'"
|
||||
|
||||
elif f.operator.lower() == "is":
|
||||
if f.value == 'set':
|
||||
f.operator = '!='
|
||||
elif f.value == 'not set':
|
||||
f.operator = '='
|
||||
|
||||
value = ""
|
||||
fallback = '""'
|
||||
can_be_null = True
|
||||
|
||||
if 'ifnull' not in column_name:
|
||||
column_name = 'ifnull({}, {})'.format(column_name, fallback)
|
||||
|
||||
elif f.operator.lower() in ("like", "not like") or (isinstance(f.value, string_types) and
|
||||
(not df or df.fieldtype not in ["Float", "Int", "Currency", "Percent", "Check"])):
|
||||
value = "" if f.value==None else f.value
|
||||
|
|
@ -417,7 +430,6 @@ class DatabaseQuery(object):
|
|||
if f.operator.lower() in ("like", "not like") and isinstance(value, string_types):
|
||||
# because "like" uses backslash (\) for escaping
|
||||
value = value.replace("\\", "\\\\").replace("%", "%%")
|
||||
|
||||
else:
|
||||
value = flt(f.value)
|
||||
fallback = 0
|
||||
|
|
|
|||
|
|
@ -3,21 +3,9 @@
|
|||
<div class="fieldname-select-area col-sm-4 form-group ui-front"></div>
|
||||
<div class="col-sm-2 form-group">
|
||||
<select class="condition form-control">
|
||||
<option value="=">{%= __("Equals") %}</option>
|
||||
<option value="like">{%= __("Like") %}</option>
|
||||
<option value="in">{%= __("In") %}</option>
|
||||
<option value="not in">{%= __("Not In") %}</option>
|
||||
<option value="!=">{%= __("Not Equals") %}</option>
|
||||
<option value="not like">{%= __("Not Like") %}</option>
|
||||
<option value=">">{%= __(">") %}</option>
|
||||
<option value="<">{%= __("<") %}</option>
|
||||
<option value=">=">{%= __(">=") %}</option>
|
||||
<option value="<=">{%= __("<=") %}</option>
|
||||
<option value="Between">{%= __("Between") %}</option>
|
||||
<option value="descendants of">{%= __("Descendants Of") %}</option>
|
||||
<option value="not descendants of">{%= __("Not Descendants Of") %}</option>
|
||||
<option value="ancestors of">{%= __("Ancestors Of") %}</option>
|
||||
<option value="not ancestors of">{%= __("Not Ancestors Of") %}</option>
|
||||
{% for condition in conditions %}
|
||||
<option value="{{condition[0]}}">{{ condition[1] }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-sm-6 col-xs-12">
|
||||
|
|
|
|||
|
|
@ -13,13 +13,16 @@ frappe.ui.Filter = class {
|
|||
["not like", __("Not Like")],
|
||||
["in", __("In")],
|
||||
["not in", __("Not In")],
|
||||
["is", __("Is")],
|
||||
[">", ">"],
|
||||
["<", "<"],
|
||||
[">=", ">="],
|
||||
["<=", "<="],
|
||||
["Between", __("Between")],
|
||||
["descendants of", __("Descendants Of")],
|
||||
["ancestors of", __("Ancestors Of")]
|
||||
["not descendants of", __("Not Descendants Of")],
|
||||
["ancestors of", __("Ancestors Of")],
|
||||
["not ancestors of", __("Not Ancestors Of")]
|
||||
];
|
||||
this.invalid_condition_map = {
|
||||
Date: ['like', 'not like'],
|
||||
|
|
@ -37,7 +40,9 @@ frappe.ui.Filter = class {
|
|||
}
|
||||
|
||||
make() {
|
||||
this.filter_edit_area = $(frappe.render_template("edit_filter", {}))
|
||||
this.filter_edit_area = $(frappe.render_template("edit_filter", {
|
||||
conditions: this.conditions
|
||||
}))
|
||||
.appendTo(this.parent.find('.filter-edit-area'));
|
||||
}
|
||||
|
||||
|
|
@ -397,5 +402,12 @@ frappe.ui.filter_utils = {
|
|||
if(condition == "Between" && (df.fieldtype == 'Date' || df.fieldtype == 'Datetime')){
|
||||
df.fieldtype = 'DateRange';
|
||||
}
|
||||
if (condition === 'is') {
|
||||
df.fieldtype = 'Select';
|
||||
df.options = [
|
||||
{ label: __('Set'), value: 'set' },
|
||||
{ label: __('Not Set'), value: 'not set' },
|
||||
];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -336,6 +336,17 @@ class TestReportview(unittest.TestCase):
|
|||
self.assertTrue(len(frappe.get_all('File', {'name': ('not ancestors of', 'Home')})) == len(frappe.get_all('File')))
|
||||
|
||||
|
||||
def test_is_set_is_not_set(self):
|
||||
res = DatabaseQuery("DocType").execute(filters={"autoname": ["is", "not set"]})
|
||||
self.assertTrue({'name': 'Integration Request'} in res)
|
||||
self.assertTrue({'name': 'User'} in res)
|
||||
self.assertFalse({'name': 'Blogger'} in res)
|
||||
|
||||
res = DatabaseQuery("DocType").execute(filters={"autoname": ["is", "set"]})
|
||||
self.assertTrue({'name': 'DocField'} in res)
|
||||
self.assertTrue({'name': 'Prepared Report'} in res)
|
||||
self.assertFalse({'name': 'Property Setter'} in res)
|
||||
|
||||
|
||||
def create_event(subject="_Test Event", starts_on=None):
|
||||
""" create a test event """
|
||||
|
|
|
|||
|
|
@ -835,7 +835,8 @@ def get_filter(doctype, f):
|
|||
f.operator = "="
|
||||
|
||||
valid_operators = ("=", "!=", ">", "<", ">=", "<=", "like", "not like", "in", "not in",
|
||||
"between", "descendants of", "ancestors of", "not descendants of", "not ancestors of")
|
||||
"between", "descendants of", "ancestors of", "not descendants of", "not ancestors of", "is")
|
||||
|
||||
if f.operator.lower() not in valid_operators:
|
||||
frappe.throw(frappe._("Operator must be one of {0}").format(", ".join(valid_operators)))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue