Compare commits
4 commits
3c75ba975e
...
59320f90bb
| Author | SHA1 | Date | |
|---|---|---|---|
| 59320f90bb | |||
|
|
4ca18a514c | ||
| 4401a541eb | |||
| fcd0489982 |
4 changed files with 212 additions and 192 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
import frappe, json
|
import frappe, json
|
||||||
from custom_ui.db_utils import build_error_response, process_query_conditions, build_datatable_dict, get_count_or_filters, build_success_response
|
from custom_ui.db_utils import build_error_response, process_query_conditions, build_datatable_dict, get_count_or_filters, build_success_response, map_lead_client
|
||||||
|
|
||||||
# ===============================================================================
|
# ===============================================================================
|
||||||
# CLIENT MANAGEMENT API METHODS
|
# CLIENT MANAGEMENT API METHODS
|
||||||
|
|
@ -101,49 +101,45 @@ def get_client(client_name):
|
||||||
print("DEBUG: Client not found as Customer. Checking Lead.")
|
print("DEBUG: Client not found as Customer. Checking Lead.")
|
||||||
lead_name = frappe.db.get_all("Lead", pluck="name", filters={"lead_name": client_name})[0]
|
lead_name = frappe.db.get_all("Lead", pluck="name", filters={"lead_name": client_name})[0]
|
||||||
customer = frappe.get_doc("Lead", lead_name)
|
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()}
|
clientData = {**clientData, **customer.as_dict()}
|
||||||
|
if customer.doctype == "Lead":
|
||||||
|
clientData.update(map_lead_client(clientData))
|
||||||
|
links = []
|
||||||
if customer.doctype == "Customer":
|
if customer.doctype == "Customer":
|
||||||
for contact_link in customer.custom_add_contacts:
|
links = (
|
||||||
contact_doc = frappe.get_doc("Contact", contact_link.contact)
|
[{"link_doctype": "Contact", "link_name": row.contact}
|
||||||
clientData["contacts"].append(contact_doc.as_dict())
|
for row in customer.get("custom_add_contacts", [])]
|
||||||
else:
|
+
|
||||||
contact_names = frappe.db.get_all("Contact", pluck="name", filters={"links": ["like", f'%{{"link_doctype": "Lead", "link_name": client_name}}%']})
|
[{"link_doctype": "Address", "link_name": row.address}
|
||||||
for contact_name in contact_names:
|
for row in customer.get("custom_select_address", [])]
|
||||||
contact_doc = frappe.get_doc("Contact", contact_name)
|
)
|
||||||
clientData["contacts"].append(contact_doc.as_dict())
|
|
||||||
|
|
||||||
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:
|
else:
|
||||||
address_names = frappe.db.get_all("Address", pluck="name", filters={"links": ["like", f'%{{"link_doctype": "Lead", "link_name": client_name}}%']})
|
links = frappe.get_all(
|
||||||
for address_name in address_names:
|
"Dynamic Link",
|
||||||
address_doc = frappe.get_doc("Address", address_name)
|
filters={
|
||||||
clientData["addresses"].append(address_doc.as_dict())
|
"link_doctype": "Lead",
|
||||||
|
"link_name": lead_name,
|
||||||
|
"parenttype": ["in", ["Address", "Contact"]],
|
||||||
|
},
|
||||||
|
fields=[
|
||||||
|
"parenttype as link_doctype",
|
||||||
|
"parent as link_name",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
print("DEBUG: Retrieved links from lead:", links)
|
||||||
|
for link in links:
|
||||||
|
print("DEBUG: Processing link:", link)
|
||||||
|
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)
|
return build_success_response(clientData)
|
||||||
except frappe.ValidationError as ve:
|
except frappe.ValidationError as ve:
|
||||||
return build_error_response(str(ve), 400)
|
return build_error_response(str(ve), 400)
|
||||||
|
|
@ -348,6 +344,11 @@ def upsert_client(data):
|
||||||
"phone": contact_doc.phone,
|
"phone": contact_doc.phone,
|
||||||
"role": contact_doc.role
|
"role": contact_doc.role
|
||||||
})
|
})
|
||||||
|
new_client_doc.append("links", {
|
||||||
|
"link_doctype": "Contact",
|
||||||
|
"link_name": contact_doc.name
|
||||||
|
}
|
||||||
|
)
|
||||||
new_client_doc.save(ignore_permissions=True)
|
new_client_doc.save(ignore_permissions=True)
|
||||||
|
|
||||||
# Address -> Customer/Lead
|
# Address -> Customer/Lead
|
||||||
|
|
@ -356,6 +357,8 @@ def upsert_client(data):
|
||||||
"link_doctype": new_client_doc.doctype,
|
"link_doctype": new_client_doc.doctype,
|
||||||
"link_name": new_client_doc.name
|
"link_name": new_client_doc.name
|
||||||
})
|
})
|
||||||
|
if new_client_doc.doctype == "Lead":
|
||||||
|
address_doc.lead_name = new_client_doc.lead_name
|
||||||
|
|
||||||
|
|
||||||
# Address -> Contact
|
# Address -> Contact
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,23 @@ def process_filters(filters):
|
||||||
processed_filters = address_filters
|
processed_filters = address_filters
|
||||||
|
|
||||||
continue # Skip the rest of the loop for address field
|
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"):
|
if match_mode in ("contains", "contains"):
|
||||||
processed_filters[mapped_field_name] = ["like", f"%{filter_obj['value']}%"]
|
processed_filters[mapped_field_name] = ["like", f"%{filter_obj['value']}%"]
|
||||||
elif match_mode in ("startswith", "starts_with"):
|
elif match_mode in ("startswith", "starts_with"):
|
||||||
|
|
@ -143,3 +159,30 @@ def build_full_address(doc):
|
||||||
return f"{first}, {second}"
|
return f"{first}, {second}"
|
||||||
return first or second or ""
|
return first or second or ""
|
||||||
|
|
||||||
|
def map_lead_client(client_data):
|
||||||
|
mappings = {
|
||||||
|
"lead_name": "customer_name",
|
||||||
|
"customer_type": "customer_type",
|
||||||
|
"territory": "territory",
|
||||||
|
"company_name": "company"
|
||||||
|
}
|
||||||
|
for lead_field, client_field in mappings.items():
|
||||||
|
if lead_field in client_data:
|
||||||
|
print(f"DEBUG: Mapping field {lead_field} to {client_field} with value {client_data[lead_field]}")
|
||||||
|
client_data[client_field] = client_data[lead_field]
|
||||||
|
client_data["customer_group"] = "" # Leads don't have customer groups
|
||||||
|
return client_data
|
||||||
|
|
||||||
|
def map_lead_update(client_data):
|
||||||
|
mappings = {
|
||||||
|
"customer_name": "lead_name",
|
||||||
|
"customer_type": "customer_type",
|
||||||
|
"territory": "territory",
|
||||||
|
"company": "company_name"
|
||||||
|
}
|
||||||
|
for client_field, lead_field in mappings.items():
|
||||||
|
if client_field in client_data:
|
||||||
|
print(f"DEBUG: Mapping field {client_field} to {lead_field} with value {client_data[client_field]}")
|
||||||
|
client_data[lead_field] = client_data[client_field]
|
||||||
|
return client_data
|
||||||
|
|
||||||
|
|
@ -132,6 +132,12 @@ def add_custom_fields():
|
||||||
options="Not Started\nIn Progress\nCompleted",
|
options="Not Started\nIn Progress\nCompleted",
|
||||||
default="Not Started",
|
default="Not Started",
|
||||||
insert_after="job_status"
|
insert_after="job_status"
|
||||||
|
),
|
||||||
|
dict(
|
||||||
|
fieldname="lead_name",
|
||||||
|
label="Lead Name",
|
||||||
|
fieldtype="Data",
|
||||||
|
insert_after="custom_customer_to_bill"
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
"Contact": [
|
"Contact": [
|
||||||
|
|
@ -268,11 +274,12 @@ def update_address_fields():
|
||||||
["custom_onsite_meeting_scheduled", "onsite_meeting_scheduled"],
|
["custom_onsite_meeting_scheduled", "onsite_meeting_scheduled"],
|
||||||
["custom_estimate_sent_status", "estimate_sent_status"],
|
["custom_estimate_sent_status", "estimate_sent_status"],
|
||||||
["custom_job_status", "job_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": [
|
"Contact": [
|
||||||
["custom_role", "role"],
|
["custom_role", "role"],
|
||||||
["custom_email", "email"]
|
["custom_email", "email"],
|
||||||
],
|
],
|
||||||
"On-Site Meeting": [
|
"On-Site Meeting": [
|
||||||
["custom_notes", "notes"],
|
["custom_notes", "notes"],
|
||||||
|
|
@ -285,6 +292,9 @@ def update_address_fields():
|
||||||
],
|
],
|
||||||
"Sales Order": [
|
"Sales Order": [
|
||||||
["custom_requires_half_payment", "requires_half_payment"]
|
["custom_requires_half_payment", "requires_half_payment"]
|
||||||
|
],
|
||||||
|
"Lead": [
|
||||||
|
["custom_customer_type", "customer_type"]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,163 +1,127 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="overview-container">
|
<div class="overview-container">
|
||||||
<!-- Form Mode (new=true or edit mode) -->
|
<template v-if="!editMode">
|
||||||
<template v-if="isNew || editMode">
|
<Button
|
||||||
<ClientInformationForm
|
@click="toggleEditMode"
|
||||||
ref="clientInfoRef"
|
icon="pi pi-pencil"
|
||||||
v-model:form-data="formData"
|
label="Edit Information"
|
||||||
:is-submitting="isSubmitting"
|
size="small"
|
||||||
:is-edit-mode="editMode"
|
severity="secondary"
|
||||||
@new-client-toggle="handleNewClientToggle"
|
|
||||||
@customer-selected="handleCustomerSelected"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ContactInformationForm
|
|
||||||
ref="contactInfoRef"
|
|
||||||
v-model:form-data="formData"
|
|
||||||
:is-submitting="isSubmitting"
|
|
||||||
:is-edit-mode="editMode"
|
|
||||||
:is-new-client-locked="isNewClientMode"
|
|
||||||
:available-contacts="availableContacts"
|
|
||||||
@new-contact-toggle="handleNewContactToggle"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<AddressInformationForm
|
|
||||||
v-model:form-data="formData"
|
|
||||||
:is-submitting="isSubmitting"
|
|
||||||
:is-edit-mode="editMode"
|
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<div class="status-cards">
|
||||||
|
<template v-if="isNew || editMode">
|
||||||
|
<template v-if="isNew || editMode">
|
||||||
|
<ClientInformationForm
|
||||||
|
ref="clientInfoRef"
|
||||||
|
:form-data="formData"
|
||||||
|
@update:form-data="formData = $event"
|
||||||
|
:is-submitting="isSubmitting"
|
||||||
|
:is-edit-mode="editMode"
|
||||||
|
@new-client-toggle="handleNewClientToggle"
|
||||||
|
@customer-selected="handleCustomerSelected"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Display Mode (existing client view) -->
|
<ContactInformationForm
|
||||||
<template v-else>
|
ref="contactInfoRef"
|
||||||
<!-- Client Basic Info Card -->
|
:form-data="formData"
|
||||||
<div class="info-card">
|
@update:form-data="formData = $event"
|
||||||
<div class="card-header">
|
:is-submitting="isSubmitting"
|
||||||
<h3>Client Information</h3>
|
:is-edit-mode="editMode"
|
||||||
<Button
|
:is-new-client-locked="isNewClientMode"
|
||||||
@click="toggleEditMode"
|
:available-contacts="availableContacts"
|
||||||
icon="pi pi-pencil"
|
@new-contact-toggle="handleNewContactToggle"
|
||||||
label="Edit"
|
/>
|
||||||
size="small"
|
|
||||||
severity="secondary"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="info-grid">
|
|
||||||
<div class="info-item">
|
|
||||||
<label>Customer Name:</label>
|
|
||||||
<span>{{ clientData?.customerName || "N/A" }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>Customer Type:</label>
|
|
||||||
<span>{{ clientData?.customerType || "N/A" }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>Customer Group:</label>
|
|
||||||
<span>{{ clientData?.customerGroup || "N/A" }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>Territory:</label>
|
|
||||||
<span>{{ clientData?.territory || "N/A" }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Address Info Card -->
|
<AddressInformationForm
|
||||||
<div class="info-card" v-if="selectedAddressData">
|
:form-data="formData"
|
||||||
<h3>Address Information</h3>
|
@update:form-data="formData = $event"
|
||||||
<div class="info-grid">
|
:is-submitting="isSubmitting"
|
||||||
<div class="info-item full-width">
|
:is-edit-mode="editMode"
|
||||||
<label>Address Title:</label>
|
/>
|
||||||
<span>{{ selectedAddressData.addressTitle || "N/A" }}</span>
|
</template>
|
||||||
</div>
|
|
||||||
<div class="info-item full-width">
|
|
||||||
<label>Full Address:</label>
|
|
||||||
<span>{{ fullAddress }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>City:</label>
|
|
||||||
<span>{{ selectedAddressData.city || "N/A" }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>State:</label>
|
|
||||||
<span>{{ selectedAddressData.state || "N/A" }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<label>Zip Code:</label>
|
|
||||||
<span>{{ selectedAddressData.pincode || "N/A" }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Contact Info Card -->
|
<!-- Display Mode (existing client view) -->
|
||||||
<div class="info-card" v-if="selectedAddressData">
|
<template v-else>
|
||||||
<h3>Contact Information</h3>
|
<!-- Address Info Card -->
|
||||||
<template v-if="contactsForAddress.length > 0">
|
<div class="info-card" v-if="selectedAddressData">
|
||||||
<div v-if="contactsForAddress.length > 1" class="contact-selector">
|
<h3>General Information</h3>
|
||||||
<Dropdown
|
|
||||||
v-model="selectedContactIndex"
|
|
||||||
:options="contactOptions"
|
|
||||||
option-label="label"
|
|
||||||
option-value="value"
|
|
||||||
placeholder="Select Contact"
|
|
||||||
class="w-full"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="info-grid">
|
<div class="info-grid">
|
||||||
<div class="info-item">
|
<div class="info-item full-width">
|
||||||
<label>Contact Name:</label>
|
<label>Address Title:</label>
|
||||||
<span>{{ contactFullName }}</span>
|
<span>{{ selectedAddressData.addressTitle || "N/A" }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-item">
|
<div class="info-item full-width">
|
||||||
<label>Phone:</label>
|
<label>Full Address:</label>
|
||||||
<span>{{ primaryContactPhone }}</span>
|
<span>{{ fullAddress }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-item">
|
<div class="info-item full-width">
|
||||||
<label>Email:</label>
|
<label>City:</label>
|
||||||
<span>{{ primaryContactEmail }}</span>
|
<span>{{ selectedAddressData.city || "N/A" }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-item full-width">
|
||||||
|
<label>State:</label>
|
||||||
|
<span>{{ selectedAddressData.state || "N/A" }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-item full-width">
|
||||||
|
<label>Zip Code:</label>
|
||||||
|
<span>{{ selectedAddressData.pincode || "N/A" }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</div>
|
||||||
<template v-else>
|
|
||||||
<p>No contacts available for this address.</p>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- Status Cards (only for existing clients) -->
|
<!-- Client Basic Info Card -->
|
||||||
<div class="status-cards" v-if="!isNew && !editMode && selectedAddressData">
|
<div class="info-card">
|
||||||
<div class="status-card">
|
<h3>Contact Information</h3>
|
||||||
<h4>On-Site Meeting</h4>
|
<template v-if="contactsForAddress.length > 0">
|
||||||
<Button
|
<div class="info-grid">
|
||||||
:label="selectedAddressData.customOnsiteMeetingScheduled || 'Not Started'"
|
<div class="info-item">
|
||||||
:severity="getStatusSeverity(selectedAddressData.customOnsiteMeetingScheduled)"
|
<label>Customer Name:</label>
|
||||||
@click="handleStatusClick('onsite')"
|
<span>{{ clientData?.customerName || "N/A" }}</span>
|
||||||
/>
|
</div>
|
||||||
</div>
|
<div class="info-item">
|
||||||
<div class="status-card">
|
<label>Customer Type:</label>
|
||||||
<h4>Estimate Sent</h4>
|
<span>{{ clientData?.customerType || "N/A" }}</span>
|
||||||
<Button
|
</div>
|
||||||
:label="selectedAddressData.customEstimateSentStatus || 'Not Started'"
|
<div v-if="contactsForAddress.length > 1" class="contact-selector">
|
||||||
:severity="getStatusSeverity(selectedAddressData.customEstimateSentStatus)"
|
<Dropdown
|
||||||
@click="handleStatusClick('estimate')"
|
v-model="selectedContactIndex"
|
||||||
/>
|
:options="contactOptions"
|
||||||
</div>
|
option-label="label"
|
||||||
<div class="status-card">
|
option-value="value"
|
||||||
<h4>Job Status</h4>
|
placeholder="Select Contact"
|
||||||
<Button
|
class="w-full"
|
||||||
:label="selectedAddressData.customJobStatus || 'Not Started'"
|
/>
|
||||||
:severity="getStatusSeverity(selectedAddressData.customJobStatus)"
|
</div>
|
||||||
@click="handleStatusClick('job')"
|
<div class="info-grid">
|
||||||
/>
|
<div class="info-item">
|
||||||
</div>
|
<label>Contact Name:</label>
|
||||||
<div class="status-card">
|
<span>{{ contactFullName }}</span>
|
||||||
<h4>Payment Received</h4>
|
</div>
|
||||||
<Button
|
<div class="info-item">
|
||||||
:label="selectedAddressData.customPaymentReceivedStatus || 'Not Started'"
|
<label>Phone:</label>
|
||||||
:severity="getStatusSeverity(selectedAddressData.customPaymentReceivedStatus)"
|
<span>{{ primaryContactPhone }}</span>
|
||||||
@click="handleStatusClick('payment')"
|
</div>
|
||||||
/>
|
<div class="info-item">
|
||||||
</div>
|
<label>Email:</label>
|
||||||
|
<span>{{ primaryContactEmail }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<label>Customer Group:</label>
|
||||||
|
<span>{{ clientData?.customerGroup || "N/A" }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<label>Territory:</label>
|
||||||
|
<span>{{ clientData?.territory || "N/A" }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<p>No contacts available for this address.</p>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Form Actions -->
|
<!-- Form Actions -->
|
||||||
|
|
@ -684,7 +648,7 @@ const handleCancel = () => {
|
||||||
|
|
||||||
.info-item {
|
.info-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: row;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue