diff --git a/custom_ui/api/db/clients.py b/custom_ui/api/db/clients.py
index 1f88aee..5c9ff5a 100644
--- a/custom_ui/api/db/clients.py
+++ b/custom_ui/api/db/clients.py
@@ -136,67 +136,67 @@ def get_client(client_name):
@frappe.whitelist()
def get_clients_table_data(filters={}, sortings=[], page=1, page_size=10):
"""Get paginated client table data with filtering and sorting support."""
- try:
+ # try:
- print("DEBUG: Raw client table query received:", {
- "filters": filters,
- "sortings": sortings,
- "page": page,
- "page_size": page_size
- })
+ # print("DEBUG: Raw client table query received:", {
+ # "filters": filters,
+ # "sortings": sortings,
+ # "page": page,
+ # "page_size": page_size
+ # })
- processed_filters, processed_sortings, is_or, page, page_size = process_query_conditions(filters, sortings, page, page_size)
- print("DEBUG: Processed filters:", processed_filters)
- print("DEBUG: Processed sortings:", processed_sortings)
- # Handle count with proper OR filter support
- if is_or:
- count = frappe.db.sql(*get_count_or_filters("Address", processed_filters))[0][0]
- else:
- count = frappe.db.count("Address", filters=processed_filters)
+ # processed_filters, processed_sortings, is_or, page, page_size = process_query_conditions(filters, sortings, page, page_size)
+ # print("DEBUG: Processed filters:", processed_filters)
+ # print("DEBUG: Processed sortings:", processed_sortings)
+ # # Handle count with proper OR filter support
+ # if is_or:
+ # count = frappe.db.sql(*get_count_or_filters("Address", processed_filters))[0][0]
+ # else:
+ # count = frappe.db.count("Address", filters=processed_filters)
- print("DEBUG: Count of addresses matching filters:", count)
+ # print("DEBUG: Count of addresses matching filters:", count)
- address_names = frappe.db.get_all(
- "Address",
- fields=["name"],
- filters=processed_filters if not is_or else None,
- or_filters=processed_filters if is_or else None,
- limit=page_size,
- start=(page - 1) * page_size,
- order_by=processed_sortings
- )
+ # address_names = frappe.db.get_all(
+ # "Address",
+ # fields=["name"],
+ # filters=processed_filters if not is_or else None,
+ # or_filters=processed_filters if is_or else None,
+ # limit=page_size,
+ # start=(page - 1) * page_size,
+ # order_by=processed_sortings
+ # )
- addresses = [frappe.get_doc("Address", addr["name"]).as_dict() for addr in address_names]
- tableRows = []
- for address in addresses:
- tableRow = {}
- links = address.links
- customer_links = [link for link in links if link.link_doctype == "Customer"] if links else None
- customer_name = address.get("custom_customer_to_bill")
- if not customer_name and not customer_links:
- print("DEBUG: No customer links found and no customer to bill.")
- customer_name = "N/A"
- elif not customer_name and customer_links:
- print("DEBUG: No customer to bill. Customer links found:", customer_links)
- customer_name = customer_links[0].link_name
- tableRow["id"] = address["name"]
- tableRow["customer_name"] = customer_name
- tableRow["address"] = (
- f"{address['address_line1']}"
- f"{' ' + address['address_line2'] if address['address_line2'] else ''} "
- f"{address['city']}, {address['state']} {address['pincode']}"
- )
- tableRow["appointment_scheduled_status"] = address.custom_onsite_meeting_scheduled
- tableRow["estimate_sent_status"] = address.custom_estimate_sent_status
- tableRow["job_status"] = address.custom_job_status
- tableRow["payment_received_status"] = address.custom_payment_received_status
- tableRows.append(tableRow)
- tableDataDict = build_datatable_dict(data=tableRows, count=count, page=page, page_size=page_size)
- return build_success_response(tableDataDict)
- except frappe.ValidationError as ve:
- return build_error_response(str(ve), 400)
- except Exception as e:
- return build_error_response(str(e), 500)
+ # addresses = [frappe.get_doc("Address", addr["name"]).as_dict() for addr in address_names]
+ # tableRows = []
+ # for address in addresses:
+ # tableRow = {}
+ # links = address.links
+ # customer_links = [link for link in links if link.link_doctype == "Customer"] if links else None
+ # customer_name = address.get("custom_customer_to_bill")
+ # if not customer_name and not customer_links:
+ # print("DEBUG: No customer links found and no customer to bill.")
+ # customer_name = "N/A"
+ # elif not customer_name and customer_links:
+ # print("DEBUG: No customer to bill. Customer links found:", customer_links)
+ # customer_name = customer_links[0].link_name
+ # tableRow["id"] = address["name"]
+ # tableRow["customer_name"] = customer_name
+ # tableRow["address"] = (
+ # f"{address['address_line1']}"
+ # f"{' ' + address['address_line2'] if address['address_line2'] else ''} "
+ # f"{address['city']}, {address['state']} {address['pincode']}"
+ # )
+ # tableRow["appointment_scheduled_status"] = address.custom_onsite_meeting_scheduled
+ # tableRow["estimate_sent_status"] = address.custom_estimate_sent_status
+ # tableRow["job_status"] = address.custom_job_status
+ # tableRow["payment_received_status"] = address.custom_payment_received_status
+ # tableRows.append(tableRow)
+ # tableDataDict = build_datatable_dict(data=tableRows, count=count, page=page, page_size=page_size)
+ # return build_success_response(tableDataDict)
+ # except frappe.ValidationError as ve:
+ # return build_error_response(str(ve), 400)
+ # except Exception as e:
+ # return build_error_response(str(e), 500)
@frappe.whitelist()
@@ -207,27 +207,37 @@ def upsert_client(data):
# Handle customer creation/update
print("#####DEBUG: Upsert client data received:", data)
+
print("#####DEBUG: Checking for existing customer with name:", data.get("customer_name"))
customer = frappe.db.exists("Customer", {"customer_name": data.get("customer_name")})
+
if not customer:
- new_lead_data = {"doctype": "Lead"}
+ print("#####DEBUG: No existing customer found. Checking for existing lead")
+ customer = frappe.db.exists("Lead", {"lead_name": data.get("customer_name")})
+ else:
+ print("#####DEBUG: Existing customer found:", customer)
+
+ if not customer:
+ print("#####DEBUG: No existing lead found. Creating new lead.")
is_individual = data.get("customer_type") == "Individual"
+
primary_contact = next((c for c in data.get("contacts", []) if c.get("is_primary")), None)
if not primary_contact:
return build_error_response("Primary contact information is required to create a new customer.", 400)
- if is_individual:
- # Grab the contact that has is_primary true
- new_lead_data["first_name"] = primary_contact.get("first_name")
- new_lead_data["last_name"] = primary_contact.get("last_name")
- else:
- new_lead_data["company_name"] = data.get("customer_name")
- new_lead_data["email_id"] = primary_contact.get("email")
- new_lead_data["phone"] = primary_contact.get("phone_number")
- new_client_doc = frappe.get_doc({
- "doctype": "Lead",
- "customer_name": data.get("customer_name"),
- "customer_type": data.get("customer_type")
- }).insert(ignore_permissions=True)
+ print("#####DEBUG: Primary contact found:", primary_contact)
+
+ new_lead_data = {
+ "doctype": "Lead",
+ "lead_name": data.get("customer_name"),
+ "first_name": primary_contact.get("first_name"),
+ "last_name": primary_contact.get("last_name"),
+ "email_id": primary_contact.get("email"),
+ "phone": primary_contact.get("phone_number"),
+ "customer_type": data.get("customer_type"),
+ "company": data.get("company")
+ }
+ print("#####DEBUG: New lead data prepared:", new_lead_data)
+ new_client_doc = frappe.get_doc(new_lead_data).insert(ignore_permissions=True)
else:
new_client_doc = frappe.get_doc("Customer", data.get("customer_name"))
print(f"#####DEBUG: {new_client_doc.doctype}:", new_client_doc.as_dict())
@@ -265,6 +275,7 @@ def upsert_client(data):
contact_data = json.loads(contact_data)
print("#####DEBUG: Processing contact data:", contact_data)
contact_exists = frappe.db.exists("Contact", {"email_id": contact_data.get("email"), "phone": contact_data.get("phone_number")})
+ print("Contact exists check:", contact_exists)
if not contact_exists:
contact_doc = frappe.get_doc({
"doctype": "Contact",
@@ -288,7 +299,7 @@ def upsert_client(data):
}).insert(ignore_permissions=True)
print("Created new contact:", contact_doc.as_dict())
else:
- contact_doc = frappe.get_doc("Contact", {"email_id": data.get("email")})
+ contact_doc = frappe.get_doc("Contact", {"email_id": contact_data.get("email"), "phone": contact_data.get("phone_number")})
print("Contact already exists:", contact_doc.as_dict())
contact_docs.append(contact_doc)
diff --git a/custom_ui/install.py b/custom_ui/install.py
index 4608a1e..eaf8bf3 100644
--- a/custom_ui/install.py
+++ b/custom_ui/install.py
@@ -1,5 +1,6 @@
import os
import subprocess
+import sys
import frappe
from .utils import create_module
@@ -70,6 +71,15 @@ def add_custom_fields():
print("\nš§ Adding custom fields to Address doctype...")
custom_fields = {
+ "Lead": [
+ dict(
+ fieldname="customer_type",
+ label="Customer Type",
+ fieldtype="Select",
+ options="Individual\nCompany\nPartnership",
+ insert_after="lead_name"
+ )
+ ],
"Address": [
dict(
fieldname="full_address",
@@ -315,21 +325,29 @@ def update_address_fields():
filled_length = int(bar_length * index // total_addresses)
bar = 'ā' * filled_length + 'ā' * (bar_length - filled_length)
- # Print a three-line, refreshing progress block to avoid terminal wrap
+ # Print a three-line, refreshing progress block without adding new lines each loop
progress_line = f"š Progress: [{bar}] {progress_percentage:3d}% ({index}/{total_addresses})"
counters_line = f" Fields updated: {total_field_updates} | Addresses updated: {addresses_updated}"
detail_line = f" Processing: {name[:40]}..."
if index == 1:
- # Save cursor position at the start of the progress block
- print("\033[s", end='')
+ # First render: write the three lines
+ sys.stdout.write(
+ f"\r\033[K{progress_line}\n"
+ f"\033[K{counters_line}\n"
+ f"\033[K{detail_line}"
+ )
else:
- # Restore to the saved cursor position to rewrite the three-line block
- print("\033[u", end='')
+ # Move cursor up 3 lines, then rewrite each line in place
+ sys.stdout.write("\033[2F")
+ sys.stdout.write(f"\r\033[K{progress_line}\n")
+ sys.stdout.write(f"\033[K{counters_line}\n")
+ sys.stdout.write(f"\033[K{detail_line}")
- print(f"\r\033[K{progress_line}")
- print(f"\r\033[K{counters_line}")
- print(f"\r\033[K{detail_line}", end='' if index != total_addresses else '\n', flush=True)
+ if index == total_addresses:
+ sys.stdout.write("\n")
+
+ sys.stdout.flush()
should_update = False
address = frappe.get_doc("Address", name)
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index afbda38..9908ed4 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -1,7 +1,6 @@
@@ -41,7 +41,7 @@ const fontSize = computed(() => {
}
.company-select {
- width: 170px;
+ width: 100%;
}
:deep(.p-select) {
diff --git a/frontend/src/components/SideBar.vue b/frontend/src/components/SideBar.vue
index c18f739..4f5e0d2 100644
--- a/frontend/src/components/SideBar.vue
+++ b/frontend/src/components/SideBar.vue
@@ -3,6 +3,7 @@ import { ref, nextTick } from "vue";
import { useRouter } from "vue-router";
import { useModalStore } from "@/stores/modal";
import { useNotificationStore } from "@/stores/notifications-primevue"
+import CompanySelector from "./CompanySelector.vue";
import {
Home,
Community,
@@ -153,6 +154,9 @@ const handleCategoryClick = (category) => {