diff --git a/custom_ui/api/db/clients.py b/custom_ui/api/db/clients.py index 760d998..717790b 100644 --- a/custom_ui/api/db/clients.py +++ b/custom_ui/api/db/clients.py @@ -101,49 +101,35 @@ def get_client(client_name): print("DEBUG: Client not found as Customer. Checking Lead.") lead_name = frappe.db.get_all("Lead", pluck="name", filters={"lead_name": client_name})[0] customer = frappe.get_doc("Lead", lead_name) + if not customer: + return build_error_response(f"Client '{client_name}' not found as Customer or Lead.", 404) + print("DEBUG: Retrieved customer/lead document:", customer.as_dict()) clientData = {**clientData, **customer.as_dict()} + links = [] if customer.doctype == "Customer": - for contact_link in customer.custom_add_contacts: - contact_doc = frappe.get_doc("Contact", contact_link.contact) - clientData["contacts"].append(contact_doc.as_dict()) + links = customer.get("custom_add_contacts", []) + customer.get("custom_select_address", []) else: - contact_names = frappe.db.get_all("Contact", pluck="name", filters={"links": ["like", f'%{{"link_doctype": "Lead", "link_name": client_name}}%']}) - for contact_name in contact_names: - contact_doc = frappe.get_doc("Contact", contact_name) - clientData["contacts"].append(contact_doc.as_dict()) + links = frappe.get_all( + "Dynamic Link", + filters={ + "link_doctype": "Lead", + "link_name": lead_name, + "parenttype": ["in", ["Address", "Contact"]], + }, + fields=[ + "parenttype as link_doctype", + "parent as link_name", + ] + ) - if customer.doctype == "Customer": - for address_link in customer.custom_select_address: - address_doc = frappe.get_doc("Address", address_link.address_name) - # # addressData = {"jobs": [], "contacts": []} - # addressData = {**addressData, **address_doc.as_dict()} - # addressData["estimates"] = frappe.db.get_all("Quotation", fields=["*"], filters={"custom_installation_address": address_doc.address_title}) - # addressData["onsite_meetings"] = frappe.db.get_all("On-Site Meeting", fields=["*"], filters={"address": address_doc.address_title}) - # jobs = frappe.db.get_all("Project", fields=["*"], or_filters=[ - # ["custom_installation_address", "=", address.address_title], - # ["custom_address", "=", address.address_title] - # ]) - # for job in jobs if jobs else []: - # jobData = {} - # jobData = {**jobData, **job} - # jobData["sales_invoices"] = frappe.db.get_all("Sales Invoice", fields=["*"], filters={"project": job.name}) - # jobData["payment_entries"] = frappe.db.get_all( - # "Payment Entry", - # fields=["*"], - # filters={"party_type": "Customer"}, - # or_filters=[ - # ["party", "=", client_name], - # ["party_name", "=", client_name] - # ]) - # jobData["sales_orders"] = frappe.db.get_all("Sales Order", fields=["*"], filters={"project": job.name}) - # jobData["tasks"] = frappe.db.get_all("Task", fields=["*"], filters={"project": job.name}) - # addressData["jobs"].append(jobData) - clientData["addresses"].append(address_doc.as_dict()) - else: - address_names = frappe.db.get_all("Address", pluck="name", filters={"links": ["like", f'%{{"link_doctype": "Lead", "link_name": client_name}}%']}) - for address_name in address_names: - address_doc = frappe.get_doc("Address", address_name) - clientData["addresses"].append(address_doc.as_dict()) + print("DEBUG: Retrieved links from lead:", links) + for link in links: + linked_doc = frappe.get_doc(link.link_doctype, link.link_name) + if link.link_doctype == "Contact": + clientData["contacts"].append(linked_doc.as_dict()) + elif link.link_doctype == "Address": + clientData["addresses"].append(linked_doc.as_dict()) + # TODO: Continue getting other linked docs like jobs, invoices, etc. return build_success_response(clientData) except frappe.ValidationError as ve: return build_error_response(str(ve), 400) @@ -348,6 +334,11 @@ def upsert_client(data): "phone": contact_doc.phone, "role": contact_doc.role }) + new_client_doc.append("links", { + "link_doctype": "Contact", + "link_name": contact_doc.name + } + ) new_client_doc.save(ignore_permissions=True) # Address -> Customer/Lead @@ -356,7 +347,9 @@ def upsert_client(data): "link_doctype": new_client_doc.doctype, "link_name": new_client_doc.name }) - + if new_client_doc.doctype == "Lead": + address_doc.lead_name = new_client_doc.lead_name + # Address -> Contact print("#####DEBUG: Linking address to contacts.") diff --git a/custom_ui/db_utils.py b/custom_ui/db_utils.py index d29913b..aa35bd6 100644 --- a/custom_ui/db_utils.py +++ b/custom_ui/db_utils.py @@ -50,7 +50,23 @@ def process_filters(filters): processed_filters = address_filters continue # Skip the rest of the loop for address field + customer_name_fields = ["custom_customer_to_bill", "lead_name"] if field_name == "customer_name" else [] + if customer_name_fields: + customer_name_filters = [] + for cust_field in customer_name_fields: + if match_mode in ("contains", "contains"): + customer_name_filters.append([cust_field, "like", f"%{filter_obj['value']}%"]) + elif match_mode in ("startswith", "starts_with"): + customer_name_filters.append([cust_field, "like", f"{filter_obj['value']}%"]) + elif match_mode in ("endswith", "ends_with"): + customer_name_filters.append([cust_field, "like", f"%{filter_obj['value']}"]) + elif match_mode in ("equals", "equals"): + customer_name_filters.append([cust_field, "=", filter_obj["value"]]) + else: + customer_name_filters.append([cust_field, "like", f"%{filter_obj['value']}%"]) + processed_filters = customer_name_filters + continue # Skip the rest of the loop for customer_name field if match_mode in ("contains", "contains"): processed_filters[mapped_field_name] = ["like", f"%{filter_obj['value']}%"] elif match_mode in ("startswith", "starts_with"): diff --git a/custom_ui/install.py b/custom_ui/install.py index eaf8bf3..190e5d6 100644 --- a/custom_ui/install.py +++ b/custom_ui/install.py @@ -132,6 +132,12 @@ def add_custom_fields(): options="Not Started\nIn Progress\nCompleted", default="Not Started", insert_after="job_status" + ), + dict( + fieldname="lead_name", + label="Lead Name", + fieldtype="Data", + insert_after="custom_customer_to_bill" ) ], "Contact": [ @@ -268,11 +274,12 @@ def update_address_fields(): ["custom_onsite_meeting_scheduled", "onsite_meeting_scheduled"], ["custom_estimate_sent_status", "estimate_sent_status"], ["custom_job_status", "job_status"], - ["custom_payment_received_status", "payment_received_status"] + ["custom_payment_received_status", "payment_received_status",], + ["custom_lead_name", "lead_name"] ], "Contact": [ ["custom_role", "role"], - ["custom_email", "email"] + ["custom_email", "email"], ], "On-Site Meeting": [ ["custom_notes", "notes"], @@ -285,6 +292,9 @@ def update_address_fields(): ], "Sales Order": [ ["custom_requires_half_payment", "requires_half_payment"] + ], + "Lead": [ + ["custom_customer_type", "customer_type"] ] }