diff --git a/.gitignore b/.gitignore index 6dc9b747..206a011d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,6 @@ dev-dist tags node_modules crm/public/frontend +frontend/yarn.lock crm/www/crm.html -build \ No newline at end of file +build diff --git a/crm/api/doc.py b/crm/api/doc.py index 7f47b095..fae49446 100644 --- a/crm/api/doc.py +++ b/crm/api/doc.py @@ -89,7 +89,7 @@ def get_filterable_fields(doctype: str): "options": "User", }, {"fieldname": "_user_tags", "fieldtype": "Data", "label": "Tags"}, - {"fieldname": "_liked_by", "fieldtype": "Data", "label": "Liked By"}, + {"fieldname": "_liked_by", "fieldtype": "Data", "label": "Like"}, {"fieldname": "_comments", "fieldtype": "Text", "label": "Comments"}, {"fieldname": "_assign", "fieldtype": "Text", "label": "Assigned To"}, {"fieldname": "creation", "fieldtype": "Datetime", "label": "Created On"}, @@ -108,6 +108,54 @@ def get_filterable_fields(doctype: str): return res + +@frappe.whitelist() +def get_group_by_fields(doctype: str): + allowed_fieldtypes = [ + "Check", + "Data", + "Float", + "Int", + "Currency", + "Dynamic Link", + "Link", + "Select", + "Duration", + "Date", + "Datetime", + ] + + fields = frappe.get_meta(doctype).fields + fields = [field for field in fields if field.fieldtype not in no_value_fields and field.fieldtype in allowed_fieldtypes] + fields = [ + { + "label": _(field.label), + "value": field.fieldname, + } + for field in fields + if field.label and field.fieldname + ] + + standard_fields = [ + {"label": "Name", "value": "name"}, + {"label": "Created On", "value": "creation"}, + {"label": "Last Modified", "value": "modified"}, + {"label": "Modified By", "value": "modified_by"}, + {"label": "Owner", "value": "owner"}, + {"label": "Liked By", "value": "_liked_by"}, + {"label": "Assigned To", "value": "_assign"}, + {"label": "Comments", "value": "_comments"}, + {"label": "Created On", "value": "creation"}, + {"label": "Modified On", "value": "modified"}, + ] + + for field in standard_fields: + field["label"] = _(field["label"]) + fields.append(field) + + return fields + + def get_fields_meta(DocField, doctype, allowed_fieldtypes, restricted_fields): parent = "parent" if DocField._table_name == "tabDocField" else "dt" return ( @@ -159,12 +207,16 @@ def get_list_data( page_length_count=20, columns=None, rows=None, - custom_view_name=None, + view=None, default_filters=None, ): custom_view = False filters = frappe._dict(filters) + custom_view_name = view.get('custom_view_name') if view else None + view_type = view.get('view_type') if view else None + group_by_field = view.get('group_by_field') if view else None + for key in filters: value = filters[key] if isinstance(value, list): @@ -197,8 +249,15 @@ def get_list_data( if not rows: rows = ["name"] - if not custom_view and frappe.db.exists("CRM View Settings", doctype): - list_view_settings = frappe.get_doc("CRM View Settings", doctype) + default_view_filters = { + "dt": doctype, + "type": view_type or 'list', + "is_default": 1, + "user": frappe.session.user, + } + + if not custom_view and frappe.db.exists("CRM View Settings", default_view_filters): + list_view_settings = frappe.get_doc("CRM View Settings", default_view_filters) columns = frappe.parse_json(list_view_settings.columns) rows = frappe.parse_json(list_view_settings.rows) is_default = False @@ -218,6 +277,10 @@ def get_list_data( if column.get("key") == "_liked_by" and column.get("width") == "10rem": column["width"] = "50px" + # check if rows has group_by_field if not add it + if group_by_field and group_by_field not in rows: + rows.append(group_by_field) + data = frappe.get_list( doctype, fields=rows, @@ -251,7 +314,7 @@ def get_list_data( }, {"label": "Assigned To", "type": "Text", "value": "_assign"}, {"label": "Owner", "type": "Link", "value": "owner", "options": "User"}, - {"label": "Liked By", "type": "Data", "value": "_liked_by"}, + {"label": "Like", "type": "Data", "value": "_liked_by"}, ] for field in std_fields: @@ -264,11 +327,43 @@ def get_list_data( if not is_default and custom_view_name: is_default = frappe.db.get_value("CRM View Settings", custom_view_name, "load_default_columns") + if group_by_field and view_type == "group_by": + def get_options(type, options): + if type == "Select": + return [option for option in options.split("\n")] + else: + has_empty_values = any([not d.get(group_by_field) for d in data]) + options = list(set([d.get(group_by_field) for d in data])) + options = [u for u in options if u] + if has_empty_values: + options.append("") + + if order_by and group_by_field in order_by: + order_by_fields = order_by.split(",") + order_by_fields = [(field.split(" ")[0], field.split(" ")[1]) for field in order_by_fields] + if (group_by_field, "asc") in order_by_fields: + options.sort() + elif (group_by_field, "desc") in order_by_fields: + options.sort(reverse=True) + else: + options.sort() + return options + + for field in fields: + if field.get("value") == group_by_field: + group_by_field = { + "label": field.get("label"), + "name": field.get("value"), + "type": field.get("type"), + "options": get_options(field.get("type"), field.get("options")), + } + return { "data": data, "columns": columns, "rows": rows, "fields": fields, + "group_by_field": group_by_field, "page_length": page_length, "page_length_count": page_length_count, "is_default": is_default, diff --git a/crm/fcrm/doctype/crm_view_settings/crm_view_settings.json b/crm/fcrm/doctype/crm_view_settings/crm_view_settings.json index 3da7ac69..de1ed9e8 100644 --- a/crm/fcrm/doctype/crm_view_settings/crm_view_settings.json +++ b/crm/fcrm/doctype/crm_view_settings/crm_view_settings.json @@ -10,6 +10,7 @@ "user", "is_default", "column_break_zacm", + "type", "dt", "route_name", "pinned", @@ -21,7 +22,9 @@ "filters_tab", "filters", "order_by_tab", - "order_by" + "order_by", + "group_by_tab", + "group_by_field" ], "fields": [ { @@ -117,11 +120,28 @@ "fieldname": "icon", "fieldtype": "Data", "label": "Icon" + }, + { + "default": "list", + "fieldname": "type", + "fieldtype": "Select", + "label": "Type", + "options": "list\ngroup_by" + }, + { + "fieldname": "group_by_tab", + "fieldtype": "Tab Break", + "label": "Group By" + }, + { + "fieldname": "group_by_field", + "fieldtype": "Data", + "label": "Group By Field" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-05-20 17:24:18.662389", + "modified": "2024-06-01 16:58:34.952945", "modified_by": "Administrator", "module": "FCRM", "name": "CRM View Settings", diff --git a/crm/fcrm/doctype/crm_view_settings/crm_view_settings.py b/crm/fcrm/doctype/crm_view_settings/crm_view_settings.py index c560b94e..f33f3e7f 100644 --- a/crm/fcrm/doctype/crm_view_settings/crm_view_settings.py +++ b/crm/fcrm/doctype/crm_view_settings/crm_view_settings.py @@ -27,6 +27,7 @@ def create(view): doc = frappe.new_doc("CRM View Settings") doc.name = view.label doc.label = view.label + doc.type = view.type or 'list' doc.icon = view.icon doc.dt = view.doctype doc.user = frappe.session.user @@ -34,6 +35,7 @@ def create(view): doc.load_default_columns = view.load_default_columns or False doc.filters = json.dumps(view.filters) doc.order_by = view.order_by + doc.group_by_field = view.group_by_field doc.columns = json.dumps(view.columns) doc.rows = json.dumps(view.rows) doc.insert() @@ -53,11 +55,13 @@ def update(view): doc = frappe.get_doc("CRM View Settings", view.name) doc.label = view.label + doc.type = view.type or 'list' doc.icon = view.icon doc.route_name = view.route_name or "" doc.load_default_columns = view.load_default_columns or False doc.filters = json.dumps(filters) doc.order_by = view.order_by + doc.group_by_field = view.group_by_field doc.columns = json.dumps(columns) doc.rows = json.dumps(rows) doc.save() @@ -123,28 +127,38 @@ def create_or_update_default_view(view): doc = frappe.db.exists( "CRM View Settings", - {"dt": view.doctype, "is_default": True, "user": frappe.session.user}, + { + "dt": view.doctype, + "type": view.type or 'list', + "is_default": True, + "user": frappe.session.user + }, ) if doc: doc = frappe.get_doc("CRM View Settings", doc) doc.label = view.label + doc.type = view.type or 'list' doc.route_name = view.route_name or "" doc.load_default_columns = view.load_default_columns or False doc.filters = json.dumps(filters) doc.order_by = view.order_by + doc.group_by_field = view.group_by_field doc.columns = json.dumps(columns) doc.rows = json.dumps(rows) doc.save() else: doc = frappe.new_doc("CRM View Settings") - doc.name = view.label or 'List View' - doc.label = view.label or 'List View' + label = 'Group By View' if view.type == 'group_by' else 'List View' + doc.name = view.label or label + doc.label = view.label or label + doc.type = view.type or 'list' doc.dt = view.doctype doc.user = frappe.session.user doc.route_name = view.route_name or "" doc.load_default_columns = view.load_default_columns or False doc.filters = json.dumps(filters) doc.order_by = view.order_by + doc.group_by_field = view.group_by_field doc.columns = json.dumps(columns) doc.rows = json.dumps(rows) doc.is_default = True diff --git a/frappe-ui b/frappe-ui index 1394a12b..d7ad7bd0 160000 --- a/frappe-ui +++ b/frappe-ui @@ -1 +1 @@ -Subproject commit 1394a12b6de105649c8ca5beeead62a38ef1b18e +Subproject commit d7ad7bd0d09f25a446da984e6006479ea218acd0 diff --git a/frontend/index.html b/frontend/index.html index 7145d7ca..351990a3 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -177,14 +177,6 @@
- - - -