diff --git a/custom_ui/api/db.py b/custom_ui/api/db.py index 167a503..6593df3 100644 --- a/custom_ui/api/db.py +++ b/custom_ui/api/db.py @@ -9,7 +9,7 @@ def get_client_status_counts(weekly=False, week_start_date=None, week_end_date=N # Assuming you have a date field to filter by - adjust the field name as needed # Common options: creation, modified, custom_date_field, etc. base_filters["creation"] = ["between", [week_start_date, week_end_date]] - + # Helper function to merge base filters with status filters def get_filters(status_field, status_value): filters = {status_field: status_value} @@ -22,35 +22,35 @@ def get_client_status_counts(weekly=False, week_start_date=None, week_end_date=N "in_progress": frappe.db.count("Address", filters=get_filters("custom_onsite_meeting_scheduled", "In Progress")), "completed": frappe.db.count("Address", filters=get_filters("custom_onsite_meeting_scheduled", "Completed")) } - + estimate_sent_status_counts = { "label": "Estimate Sent", "not_started": frappe.db.count("Address", filters=get_filters("custom_estimate_sent_status", "Not Started")), "in_progress": frappe.db.count("Address", filters=get_filters("custom_estimate_sent_status", "In Progress")), "completed": frappe.db.count("Address", filters=get_filters("custom_estimate_sent_status", "Completed")) } - + job_status_counts = { "label": "Job Status", "not_started": frappe.db.count("Address", filters=get_filters("custom_job_status", "Not Started")), "in_progress": frappe.db.count("Address", filters=get_filters("custom_job_status", "In Progress")), "completed": frappe.db.count("Address", filters=get_filters("custom_job_status", "Completed")) } - + payment_received_status_counts = { "label": "Payment Received", "not_started": frappe.db.count("Address", filters=get_filters("custom_payment_received_status", "Not Started")), "in_progress": frappe.db.count("Address", filters=get_filters("custom_payment_received_status", "In Progress")), "completed": frappe.db.count("Address", filters=get_filters("custom_payment_received_status", "Completed")) } - + status_dicts = [ onsite_meeting_scheduled_status_counts, estimate_sent_status_counts, job_status_counts, payment_received_status_counts ] - + categories = [] for status_dict in status_dicts: category = { @@ -74,7 +74,7 @@ def get_client_status_counts(weekly=False, week_start_date=None, week_end_date=N ] } categories.append(category) - + return categories @frappe.whitelist() @@ -87,7 +87,7 @@ def get_client(client_name): ["custom_address", "=", address.address_title] ]] ]) - + projects = [frappe.get_doc("Project", proj["name"]) for proj in project_names] customer = frappe.get_doc("Customer", customer_name) # get all associated data as needed @@ -96,7 +96,7 @@ def get_client(client_name): "customer": customer, "projects": projects } - + @frappe.whitelist() def get_clients_table_data(options): @@ -115,6 +115,7 @@ def get_clients_table_data(options): # Map frontend field names to backend field names def map_field_name(frontend_field): field_mapping = { + "customerName": "customer_name", "addressTitle": "address_title", "addressName": "address_title", # Legacy support "appointmentScheduledStatus": "address_title", # These are computed fields, sort by address_title @@ -131,6 +132,10 @@ def get_clients_table_data(options): if isinstance(filter_obj, dict) and "value" in filter_obj: if filter_obj["value"] is not None and filter_obj["value"] != "": # Map frontend field names to backend field names + if field_name == "customer_name": + mapped_field_name = "custom_customer_to_bill" + else: + mapped_field_name = field_name # Handle different match modes match_mode = filter_obj.get("matchMode", "contains") @@ -138,16 +143,16 @@ def get_clients_table_data(options): match_mode = match_mode.lower() if match_mode in ("contains", "contains"): - processed_filters[field_name] = ["like", f"%{filter_obj['value']}%"] + processed_filters[mapped_field_name] = ["like", f"%{filter_obj['value']}%"] elif match_mode in ("startswith", "startsWith"): - processed_filters[field_name] = ["like", f"{filter_obj['value']}%"] + processed_filters[mapped_field_name] = ["like", f"{filter_obj['value']}%"] elif match_mode in ("endswith", "endsWith"): - processed_filters[field_name] = ["like", f"%{filter_obj['value']}"] + processed_filters[mapped_field_name] = ["like", f"%{filter_obj['value']}"] elif match_mode in ("equals", "equals"): - processed_filters[field_name] = filter_obj["value"] + processed_filters[mapped_field_name] = filter_obj["value"] else: # Default to contains - processed_filters[field_name] = ["like", f"%{filter_obj['value']}%"] + processed_filters[mapped_field_name] = ["like", f"%{filter_obj['value']}%"] # Process sorting order_by = None @@ -173,17 +178,18 @@ def get_clients_table_data(options): addresses = frappe.db.get_all( "Address", - fields=["name", "address_title", "custom_onsite_meeting_scheduled", "custom_estimate_sent_status", "custom_job_status", "custom_payment_received_status"], + fields=["name", "custom_customer_to_bill", "address_title", "custom_onsite_meeting_scheduled", "custom_estimate_sent_status", "custom_job_status", "custom_payment_received_status"], filters=processed_filters, limit=options["page_size"], start=(options["page"] - 1) * options["page_size"], order_by=order_by ) - + rows = [] for address in addresses: tableRow = {} tableRow["id"] = address["name"] + tableRow["customer_name"] = address["custom_customer_to_bill"] tableRow["address_title"] = address["address_title"] tableRow["appointment_scheduled_status"] = address["custom_onsite_meeting_scheduled"] tableRow["estimate_sent_status"] = address["custom_estimate_sent_status"] diff --git a/frontend/src/components/pages/Clients.vue b/frontend/src/components/pages/Clients.vue index e0272f5..cbc3bda 100644 --- a/frontend/src/components/pages/Clients.vue +++ b/frontend/src/components/pages/Clients.vue @@ -102,12 +102,20 @@ const refreshStatusCounts = async () => { }; const filters = { + customerName: { value: null, matchMode: FilterMatchMode.CONTAINS }, addressTitle: { value: null, matchMode: FilterMatchMode.CONTAINS }, }; const columns = [ { - label: "Name", + label: "Customer Name", + fieldName: "customerName", + type: "text", + sortable: true, + filterable: true + }, + { + label: "Address", fieldName: "addressTitle", type: "text", sortable: true, @@ -131,7 +139,12 @@ const columns = [ type: "status", sortable: true, }, - { label: "Job Status", fieldName: "jobStatus", type: "status", sortable: true }, + { + label: "Job Status", + fieldName: "jobStatus", + type: "status", + sortable: true + }, ]; const tableActions = [ @@ -271,6 +284,8 @@ const handleLazyLoad = async (event) => { // Call API with pagination, filters, and sorting const result = await Api.getPaginatedClientDetails(paginationParams, filters, sorting); + console.log(result); + // Update local state - extract from pagination structure tableData.value = result.data; totalRecords.value = result.pagination.total;