diff --git a/custom_ui/api/db/addresses.py b/custom_ui/api/db/addresses.py index bb99ff7..5881ba0 100644 --- a/custom_ui/api/db/addresses.py +++ b/custom_ui/api/db/addresses.py @@ -3,6 +3,32 @@ import json from custom_ui.db_utils import build_error_response, build_success_response from custom_ui.services import ClientService, AddressService, ContactService +@frappe.whitelist() +def check_addresses_exist(addresses): + """Check if any of the provided addresses already exist in the system.""" + if isinstance(addresses, str): + addresses = json.loads(addresses) + print(f"DEBUG: check_addresses_exist called with addresses: {addresses}") + existing_addresses = [] + for address in addresses: + filters = { + "doctype": "Address", + "address_line1": address.get("address_line1"), + "city": address.get("city"), + # "state": address.get("state"), + "pincode": address.get("pincode") + } + if address.get("address_line2"): + filters["address_line2"] = address.get("address_line2") + print(f"DEBUG: Checking existence for address with filters: {filters}") + if frappe.db.exists(filters): + print("DEBUG: Address exists:", filters) + existing_addresses.append(address) + else: + print("DEBUG: Address does not exist:", filters) + + return build_success_response(existing_addresses) + @frappe.whitelist() def get_address_by_full_address(full_address): """Get address by full_address, including associated contacts.""" diff --git a/custom_ui/api/db/clients.py b/custom_ui/api/db/clients.py index c1c6194..e89ecbf 100644 --- a/custom_ui/api/db/clients.py +++ b/custom_ui/api/db/clients.py @@ -9,6 +9,25 @@ from custom_ui.services import AddressService, ContactService, ClientService # CLIENT MANAGEMENT API METHODS # =============================================================================== +@frappe.whitelist() +def check_client_exists(client_name): + """Check if a client exists as either a Customer or a Lead. + Additionally, return a list of potential matches based on the client name.""" + print("DEBUG: check_client_exists called with client_name:", client_name) + try: + exact_customer_match = frappe.db.exists("Customer", client_name) + exact_lead_match = frappe.db.exists("Lead", {"custom_customer_name": client_name}) + customer_matches = frappe.get_all("Customer", pluck="name", filters={"name": ["like", f"%{client_name}%"]}) + lead_matches = frappe.get_all("Lead", pluck="custom_customer_name", filters={"custom_customer_name": ["like", f"%{client_name}%"]}) + # remove duplicates from potential matches between customers and leads + + return build_success_response({ + "exact_match": exact_customer_match or exact_lead_match, + "potential_matches": list(set(customer_matches + lead_matches)) + }) + except Exception as e: + return build_error_response(str(e), 500) + @frappe.whitelist() def get_client_status_counts(weekly=False, week_start_date=None, week_end_date=None): """Get counts of clients by status categories with optional weekly filtering.""" @@ -363,15 +382,15 @@ def upsert_client(data): client_doc = check_and_get_client_doc(customer_name) if client_doc: return build_error_response(f"Client with name '{customer_name}' already exists.", 400) - for address in addresses: - if address_exists( - address.get("address_line1"), - address.get("address_line2"), - address.get("city"), - address.get("state"), - address.get("pincode") - ): - return build_error_response("This address already exists. Please use a different address or search for the address to find the associated client.", 400) + # for address in addresses: + # if address_exists( + # address.get("address_line1"), + # address.get("address_line2"), + # address.get("city"), + # address.get("state"), + # address.get("pincode") + # ): + # return build_error_response("This address already exists. Please use a different address or search for the address to find the associated client.", 400) # Handle customer creation/update @@ -444,25 +463,36 @@ def upsert_client(data): # Handle address creation address_docs = [] for address in addresses: + is_billing = True if address.get("is_billing_address") else False is_service = True if address.get("is_service_address") else False - print("#####DEBUG: Creating address with data:", address) - address_doc = AddressService.create_address({ - "address_title": AddressService.build_address_title(customer_name, address), + address_exists = frappe.db.exists("Address", { "address_line1": address.get("address_line1"), "address_line2": address.get("address_line2"), - "address_type": "Billing" if is_billing else "Service", - "custom_billing_address": is_billing, - "is_service_address": is_service, - "is_primary_address": is_billing, "city": address.get("city"), - "state": address.get("state"), - "country": "United States", - "pincode": address.get("pincode"), - "customer_type": "Lead", - "customer_name": client_doc.name, - "companies": [{ "company": data.get("company_name") }] + "pincode": address.get("pincode") }) + address_doc = None + if address_exists: + address_doc = frappe.get_doc("Address", address_exists) + else: + print("#####DEBUG: Creating address with data:", address) + address_doc = AddressService.create_address({ + "address_title": AddressService.build_address_title(customer_name, address), + "address_line1": address.get("address_line1"), + "address_line2": address.get("address_line2"), + "address_type": "Billing" if is_billing else "Service", + "custom_billing_address": is_billing, + "is_service_address": is_service, + "is_primary_address": is_billing, + "city": address.get("city"), + "state": address.get("state"), + "country": "United States", + "pincode": address.get("pincode"), + "customer_type": "Lead", + "customer_name": client_doc.name, + "companies": [{ "company": data.get("company_name") }] + }) AddressService.link_address_to_customer(address_doc, "Lead", client_doc.name) address_doc.reload() if is_billing: diff --git a/custom_ui/api/db/contacts.py b/custom_ui/api/db/contacts.py index d64b26f..adf1c1e 100644 --- a/custom_ui/api/db/contacts.py +++ b/custom_ui/api/db/contacts.py @@ -1,4 +1,23 @@ import frappe +import json +from custom_ui.db_utils import build_error_response, build_success_response + +@frappe.whitelist() +def check_contacts_exist(contacts): + """Check if any of the provided contacts already exist in the system.""" + if isinstance(contacts, str): + contacts = json.loads(contacts) + print(f"DEBUG: check_contacts_exist called with contacts: {contacts}") + existing_contacts = [] + for contact in contacts: + if frappe.db.exists("Contact", { + "first_name": contact.get("first_name"), + "last_name": contact.get("last_name"), + "email_id": contact.get("email"), + "phone": contact.get("phone_number") + }): + existing_contacts.append(contact) + return build_success_response(existing_contacts) def existing_contact_name(first_name: str, last_name: str, email: str, phone: str) -> str: """Check if a contact exists based on provided details.""" diff --git a/frontend/src/api.js b/frontend/src/api.js index 1b3b9e1..a2eb5d1 100644 --- a/frontend/src/api.js +++ b/frontend/src/api.js @@ -56,7 +56,10 @@ const FRAPPE_GET_BID_MEETING_NOTE_FORM_METHOD = "custom_ui.api.db.bid_meetings.g const FRAPPE_GET_ONSITE_MEETINGS_METHOD = "custom_ui.api.db.bid_meetings.get_bid_meetings"; const FRAPPE_SUBMIT_BID_MEETING_NOTE_FORM_METHOD = "custom_ui.api.db.bid_meetings.submit_bid_meeting_note_form"; // Address methods +const FRAPPE_CHECK_ADDRESSES_EXIST_METHOD = "custom_ui.api.db.addresses.check_addresses_exist"; const FRAPPE_GET_ADDRESSES_METHOD = "custom_ui.api.db.addresses.get_addresses"; +// Contact methods +const FRAPPE_CHECK_CONTACTS_EXIST_METHOD = "custom_ui.api.db.contacts.check_contacts_exist"; // Client methods const FRAPPE_UPSERT_CLIENT_METHOD = "custom_ui.api.db.clients.upsert_client"; const FRAPPE_GET_CLIENT_STATUS_COUNTS_METHOD = "custom_ui.api.db.clients.get_client_status_counts"; @@ -64,6 +67,7 @@ const FRAPPE_GET_CLIENT_TABLE_DATA_METHOD = "custom_ui.api.db.clients.get_client const FRAPPE_GET_CLIENT_TABLE_DATA_V2_METHOD = "custom_ui.api.db.clients.get_clients_table_data_v2"; const FRAPPE_GET_CLIENT_METHOD = "custom_ui.api.db.clients.get_client_v2"; const FRAPPE_GET_CLIENT_NAMES_METHOD = "custom_ui.api.db.clients.get_client_names"; +const FRAPPE_CHECK_CLIENT_EXISTS_METHOD = "custom_ui.api.db.clients.check_client_exists"; // Employee methods const FRAPPE_GET_EMPLOYEES_METHOD = "custom_ui.api.db.employees.get_employees"; const FRAPPE_GET_EMPLOYEES_ORGANIZED_METHOD = "custom_ui.api.db.employees.get_employees_organized"; @@ -105,6 +109,10 @@ class Api { // CLIENT METHODS // ============================================================================ + static async checkCustomerExists(clientName) { + return await this.request(FRAPPE_CHECK_CLIENT_EXISTS_METHOD, { clientName }); + } + static async getClientStatusCounts(params = {}) { return await this.request(FRAPPE_GET_CLIENT_STATUS_COUNTS_METHOD, params); } @@ -644,10 +652,22 @@ class Api { return result; } + // ============================================================================ + // CONTACT METHODS + // ============================================================================ + + static async checkContactsExist(contacts) { + return await this.request(FRAPPE_CHECK_CONTACTS_EXIST_METHOD, { contacts }); + } + // ============================================================================ // ADDRESS METHODS // ============================================================================ + static async checkAddressesExist(addresses) { + return await this.request(FRAPPE_CHECK_ADDRESSES_EXIST_METHOD, { addresses }); + } + static async getAddressByFullAddress(fullAddress) { return await this.request("custom_ui.api.db.addresses.get_address_by_full_address", { full_address: fullAddress, diff --git a/frontend/src/components/clientSubPages/AddressInformationForm.vue b/frontend/src/components/clientSubPages/AddressInformationForm.vue index 632979d..ac3f229 100644 --- a/frontend/src/components/clientSubPages/AddressInformationForm.vue +++ b/frontend/src/components/clientSubPages/AddressInformationForm.vue @@ -9,6 +9,7 @@ v-for="(address, index) in localFormData.addresses" :key="index" class="address-item" + :class="{ 'existing-highlight': isExistingAddress(address) }" >
Section coming soon
-Section coming soon
-Section coming soon
+Section coming soon
+