|
@@ -108,6 +108,49 @@ def get_query(**params):
|
|
|
def normalize_query(query: FormsDict, allow: Iterable[str] = None):
|
|
|
return get_query(**get_filter(query, allow=allow))
|
|
|
|
|
|
+def get_option_groups(data, filter_data, k, g, _type):
|
|
|
+ in_chart = data['$/unit'].apply(lambda x: (x or False) and True)
|
|
|
+ groups = sorted(set(data[g] if g is not None else []))
|
|
|
+ groups.append(None)
|
|
|
+ if _type == "exclude":
|
|
|
+ prefix = "!"
|
|
|
+ else:
|
|
|
+ prefix = ""
|
|
|
+
|
|
|
+ for group in groups:
|
|
|
+ selected = []
|
|
|
+ unselected = []
|
|
|
+ if group is None:
|
|
|
+ if _type == "include":
|
|
|
+ selected.extend(filter_data[k][0] - (set(data[in_chart][k] if g is not None else set())))
|
|
|
+ unselected.extend(((set(data[in_chart][k]) if g is None else set()) | filter_data[k][1]) - filter_data[k][0])
|
|
|
+ else:
|
|
|
+ selected.extend(filter_data[k][1])
|
|
|
+ unselected.extend((
|
|
|
+ set(data[in_chart][k]) if g is None else set()
|
|
|
+ ) | (
|
|
|
+ filter_data[k][0] - set(data[in_chart][k]) - filter_data[k][1]
|
|
|
+ ))
|
|
|
+ else:
|
|
|
+ if _type == "include":
|
|
|
+ selected.extend(filter_data[k][0] & set(data[in_chart & (data[g].apply(lambda x,axis=None: x == group))][k]))
|
|
|
+ unselected.extend(set(data[in_chart & (data[g].apply(lambda x,axis=None: x == group))][k]) - filter_data[k][0])
|
|
|
+ else:
|
|
|
+ unselected.extend(set(data[in_chart & (data[g].apply(lambda x,axis=None: x == group))][k]))
|
|
|
+ assert set(selected) - set(unselected) == set(selected), f"{set(selected)} {set(unselected)}"
|
|
|
+
|
|
|
+ yield {
|
|
|
+ "name": group,
|
|
|
+ "options": sorted(map(lambda x: {
|
|
|
+ "selected": x[0],
|
|
|
+ "value": f"{prefix}{x[1]}",
|
|
|
+ "display": x[1]
|
|
|
+ }, chain(
|
|
|
+ map(lambda x: (True, x), set(selected)),
|
|
|
+ map(lambda x: (False, x), set(unselected)),
|
|
|
+ )), key=lambda x: x["display"] if "display" in x else x["value"])
|
|
|
+ }
|
|
|
+
|
|
|
def get_form(action, method, filter_data, data):
|
|
|
keys = sorted(filter(lambda x: x not in ('unit', 'tag'), filter_data), key=lambda x: {
|
|
|
'product': 0,
|
|
@@ -115,49 +158,20 @@ def get_form(action, method, filter_data, data):
|
|
|
'group': 2,
|
|
|
}[x])
|
|
|
in_chart = data['$/unit'].apply(lambda x: (x or False) and True)
|
|
|
- group = data[in_chart].groupby([
|
|
|
- k for k in keys
|
|
|
- ]).size().reset_index()[[
|
|
|
- k for k in keys
|
|
|
- ]]
|
|
|
return template(
|
|
|
'app/rest/templates/form',
|
|
|
action=action,
|
|
|
method=method,
|
|
|
- header=[
|
|
|
- template(
|
|
|
- 'app/rest/templates/filter-heading',
|
|
|
- fname=k,
|
|
|
- first=(idx == 0),
|
|
|
- ) for idx, k in enumerate(keys)
|
|
|
- ],
|
|
|
**{
|
|
|
k: {
|
|
|
"name": k,
|
|
|
"_include": {
|
|
|
- "options": sorted(map(lambda x: {
|
|
|
- "selected": x[0],
|
|
|
- "value": x[1],
|
|
|
- }, chain(
|
|
|
- map(lambda x: (True, x), filter_data[k][0]),
|
|
|
- map(lambda x: (False, x), set([
|
|
|
- x[k] for _, x in group.iterrows()
|
|
|
- ]) - filter_data[k][0])
|
|
|
- )), key=lambda x: x["display"] if "display" in x else x["value"])
|
|
|
+ "option_groups": get_option_groups(data, filter_data, k, g, "include"),
|
|
|
},
|
|
|
"_exclude": {
|
|
|
- "options": sorted(map(lambda x: {
|
|
|
- "selected": x[0],
|
|
|
- "value": f"!{x[1]}",
|
|
|
- "display": x[1]
|
|
|
- }, chain(
|
|
|
- map(lambda x: (True, x), filter_data[k][1]),
|
|
|
- map(lambda x: (False, x), set([
|
|
|
- x[k] for _, x in group.iterrows()
|
|
|
- ]) - filter_data[k][1])
|
|
|
- )), key=lambda x: x["display"] if "display" in x else x["value"])
|
|
|
+ "option_groups": get_option_groups(data, filter_data, k, g, "exclude"),
|
|
|
}
|
|
|
- } for k in keys
|
|
|
+ } for k, g in zip(keys, [*keys[1:], None])
|
|
|
},
|
|
|
tags={
|
|
|
"name": "tag",
|
|
@@ -167,7 +181,17 @@ def get_form(action, method, filter_data, data):
|
|
|
"value": x[1],
|
|
|
},chain(
|
|
|
map(lambda x: (True, x), filter_data['tag'][0]),
|
|
|
- map(lambda x: (False, x), set(chain(*data[in_chart]['tags'])) - filter_data['tag'][0])
|
|
|
+ map(lambda x: (False, x), (set(chain(*data[in_chart]['tags'])) | filter_data['tag'][1]) - filter_data['tag'][0])
|
|
|
+ )), key=lambda x: x["display"] if "display" in x else x["value"])
|
|
|
+ },
|
|
|
+ "_exclude": {
|
|
|
+ "options": sorted(map(lambda x: {
|
|
|
+ "selected": x[0],
|
|
|
+ "value": f"!{x[1]}",
|
|
|
+ "display": x[1]
|
|
|
+ },chain(
|
|
|
+ map(lambda x: (True, x), filter_data['tag'][0]),
|
|
|
+ map(lambda x: (False, x), (set(chain(*data[in_chart]['tags'])) | filter_data['tag'][0]) - filter_data['tag'][1])
|
|
|
)), key=lambda x: x["display"] if "display" in x else x["value"])
|
|
|
}
|
|
|
},
|