add query for client details
This commit is contained in:
parent
172927e069
commit
0b280cec8e
@ -92,50 +92,90 @@ def get_client_status_counts(weekly=False, week_start_date=None, week_end_date=N
|
||||
def get_client(client_name):
|
||||
"""Get detailed information for a specific client including address, customer, and projects."""
|
||||
try:
|
||||
address = frappe.get_doc("Address", client_name)
|
||||
customer_name = address.custom_customer_to_bill if address.custom_customer_to_bill else [link.link_name for link in address.links if link.link_doctype == "Customer"][0] if address.links else None
|
||||
if not customer_name:
|
||||
raise Exception(f"No customer linked to address {client_name}. Suggested fix: Ensure the address is linked to a customer via the ERPnext UI.")
|
||||
project_names = frappe.db.get_all("Project", fields=["name"], or_filters=[
|
||||
["custom_installation_address", "=", address.address_title],
|
||||
["custom_address", "=", address.address_title]
|
||||
], limit_page_length=100)
|
||||
# contacts = [] # currently not needed as the customer doctype comes with contacts
|
||||
onsite_meetings = frappe.db.get_all(
|
||||
"On-Site Meeting",
|
||||
fields=["*"],
|
||||
filters={"address": address.address_title}
|
||||
)
|
||||
quotations = frappe.db.get_all(
|
||||
"Quotation",
|
||||
fields=["*"],
|
||||
filters={"custom_installation_address": address.address_title}
|
||||
)
|
||||
sales_orders = []
|
||||
projects = [frappe.get_doc("Project", proj["name"]) for proj in project_names]
|
||||
sales_invoices = []
|
||||
payment_entries = frappe.db.get_all(
|
||||
doctype="Payment Entry",
|
||||
fields=["*"],
|
||||
filters={"party": customer_name})
|
||||
payment_orders = []
|
||||
jobs = []
|
||||
for project in projects:
|
||||
job = []
|
||||
jobs.append(job)
|
||||
customer = frappe.get_doc("Customer", customer_name)
|
||||
# get all associated data as needed
|
||||
return build_success_response({
|
||||
"address": address,
|
||||
"customer": customer,
|
||||
# "contacts": [], # currently not needed as the customer doctype comes with contacts
|
||||
"jobs": jobs,
|
||||
"sales_invoices": sales_invoices,
|
||||
"payment_entries": payment_entries,
|
||||
"sales_orders": sales_orders,
|
||||
"quotations": quotations,
|
||||
"onsite_meetings": onsite_meetings,
|
||||
})
|
||||
clientData = {"addresses": []}
|
||||
customer = frappe.get_doc("Customer", client_name)
|
||||
clientData = {**clientData, **customer.as_dict()}
|
||||
addresses = frappe.db.get_all("Address", fields=["*"], filters={"custom_customer_to_bill": client_name})
|
||||
for address in addresses if addresses else []:
|
||||
addressData = {"jobs": []}
|
||||
addressData = {**addressData, **address}
|
||||
addressData["estimates"] = frappe.db.get_all("Quotation", fields=["*"], filters={"custom_installation_address": address.address_title})
|
||||
addressData["onsite_meetings"] = frappe.db.get_all("On-Site Meeting", fields=["*"], filters={"address": address.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(addressData)
|
||||
return build_success_response(clientData)
|
||||
except frappe.ValidationError as ve:
|
||||
return build_error_response(str(ve), 400)
|
||||
except Exception as e:
|
||||
return build_error_response(str(e), 500)
|
||||
|
||||
|
||||
# address = frappe.get_doc("Address", client_name)
|
||||
# customer_name = address.custom_customer_to_bill if address.custom_customer_to_bill else [link.link_name for link in address.links if link.link_doctype == "Customer"][0] if address.links else None
|
||||
# if not customer_name:
|
||||
# raise Exception(f"No customer linked to address {client_name}. Suggested fix: Ensure the address is linked to a customer via the ERPnext UI.")
|
||||
# project_names = frappe.db.get_all("Project", fields=["name"], or_filters=[
|
||||
# ["custom_installation_address", "=", address.address_title],
|
||||
# ["custom_address", "=", address.address_title]
|
||||
# ], limit_page_length=100)
|
||||
# # contacts = [] # currently not needed as the customer doctype comes with contacts
|
||||
# onsite_meetings = frappe.db.get_all(
|
||||
# "On-Site Meeting",
|
||||
# fields=["*"],
|
||||
# filters={"address": address.address_title}
|
||||
# )
|
||||
# quotations = frappe.db.get_all(
|
||||
# "Quotation",
|
||||
# fields=["*"],
|
||||
# filters={"custom_installation_address": address.address_title}
|
||||
# )
|
||||
# sales_orders = []
|
||||
# projects = [frappe.get_doc("Project", proj["name"]) for proj in project_names]
|
||||
# sales_invoices = []
|
||||
# payment_entries = frappe.db.get_all(
|
||||
# "Payment Entry",
|
||||
# fields=["*"],
|
||||
# filters={"party_type": "Customer"},
|
||||
# or_filters=[
|
||||
# ["party", "=", customer_name],
|
||||
# ["party_name", "=", customer_name]
|
||||
# ])
|
||||
# payment_orders = []
|
||||
# jobs = []
|
||||
# for project in projects:
|
||||
# job = []
|
||||
# jobs.append(job)
|
||||
# customer = frappe.get_doc("Customer", customer_name)
|
||||
# # get all associated data as needed
|
||||
# return build_success_response({
|
||||
# "address": address,
|
||||
# "customer": customer,
|
||||
# # "contacts": [], # currently not needed as the customer doctype comes with contacts
|
||||
# "jobs": jobs,
|
||||
# "sales_invoices": sales_invoices,
|
||||
# "payment_entries": payment_entries,
|
||||
# "sales_orders": sales_orders,
|
||||
# "quotations": quotations,
|
||||
# "onsite_meetings": onsite_meetings,
|
||||
# })
|
||||
except frappe.ValidationError as ve:
|
||||
return build_error_response(str(ve), 400)
|
||||
except Exception as e:
|
||||
|
||||
@ -68,6 +68,7 @@ def process_filters(filters):
|
||||
def process_sorting(sortings):
|
||||
sortings = json.loads(sortings) if isinstance(sortings, str) else sortings
|
||||
order_by = ""
|
||||
print("DEBUG: Original sorting:", sortings)
|
||||
if sortings and len(sortings) > 0:
|
||||
for sorting in sortings:
|
||||
mapped_field = map_field_name(sorting[0].strip())
|
||||
|
||||
@ -2,10 +2,8 @@ import frappe
|
||||
|
||||
def after_insert(doc, method):
|
||||
print(doc.address)
|
||||
frappe.msgprint(f"On-Site Meeting '{doc.name}' has been created. Updating related records...")
|
||||
address_name = frappe.db.get_value("Address", fieldname="name", filters={"address_line1": doc.address})
|
||||
address_doc = frappe.get_doc("Address", address_name)
|
||||
frappe.msgprint(f"Related Address '{address_doc.address_title}' has been retrieved.")
|
||||
address_doc.custom_onsite_meeting_scheduled = "Completed"
|
||||
address_doc.save()
|
||||
frappe.msgprint(f"Related Address '{address_doc.address_title}' has been updated with custom_onsite_meeting_scheduled = 'Completed'.")
|
||||
if doc.address:
|
||||
address_name = frappe.db.get_value("Address", fieldname="name", filters={"address_line1": doc.address})
|
||||
address_doc = frappe.get_doc("Address", address_name)
|
||||
address_doc.custom_onsite_meeting_scheduled = "Completed"
|
||||
address_doc.save()
|
||||
@ -10,10 +10,9 @@ def after_insert(doc, method):
|
||||
|
||||
|
||||
def after_save(doc, method):
|
||||
if doc.custome_sent:
|
||||
address_title = doc.custom_installation_address
|
||||
address_name = frappe.db.get_value("Address", fieldname="name", filters={"address_title": address_title})
|
||||
if address_name:
|
||||
address_doc = frappe.get_doc("Address", address_name)
|
||||
address_doc.custom_quotation_sent = "Completed"
|
||||
address_doc.save()
|
||||
address_title = doc.custom_installation_address
|
||||
address_name = frappe.db.get_value("Address", fieldname="name", filters={"address_title": address_title})
|
||||
if doc.custome_sent and address_name:
|
||||
address_doc = frappe.get_doc("Address", address_name)
|
||||
address_doc.custom_quotation_sent = "Completed"
|
||||
address_doc.save()
|
||||
@ -1,4 +1,5 @@
|
||||
import ApiUtils from "./apiUtils";
|
||||
import { useErrorStore } from "./stores/errors";
|
||||
|
||||
const ZIPPOPOTAMUS_BASE_URL = "https://api.zippopotam.us/us";
|
||||
const FRAPPE_PROXY_METHOD = "custom_ui.api.proxy.request";
|
||||
@ -15,6 +16,7 @@ const FRAPPE_GET_CLIENT_NAMES_METHOD = "custom_ui.api.db.clients.get_client_name
|
||||
|
||||
class Api {
|
||||
static async request(frappeMethod, args = {}) {
|
||||
const errorStore = useErrorStore();
|
||||
args = ApiUtils.toSnakeCaseObject(args);
|
||||
const request = { method: frappeMethod, args };
|
||||
console.log("DEBUG: API - Request Args: ", request);
|
||||
@ -28,6 +30,7 @@ class Api {
|
||||
return response.message.data;
|
||||
} catch (error) {
|
||||
console.error("ERROR: API - Request Error: ", error);
|
||||
errorStore.setApiError("Frappe API", error.message || "API request error");
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@ -112,11 +115,11 @@ class Api {
|
||||
* @param {Object} sorting - Sorting parameters from store (optional)
|
||||
* @returns {Promise<{data: Array, pagination: Object}>}
|
||||
*/
|
||||
static async getPaginatedClientDetails(paginationParams = {}, filters = {}, sorting = []) {
|
||||
static async getPaginatedClientDetails(paginationParams = {}, filters = {}, sortings = []) {
|
||||
const { page = 0, pageSize = 10 } = paginationParams;
|
||||
const result = await this.request(FRAPPE_GET_CLIENT_TABLE_DATA_METHOD, {
|
||||
filters,
|
||||
sorting,
|
||||
sortings,
|
||||
page: page + 1,
|
||||
pageSize,
|
||||
});
|
||||
|
||||
@ -3,7 +3,7 @@ class ApiUtils {
|
||||
console.log("Converting to snake case:", obj);
|
||||
const newObj = Object.entries(obj).reduce((acc, [key, value]) => {
|
||||
const snakeKey = key.replace(/[A-Z]/g, (match) => "_" + match.toLowerCase());
|
||||
if (key === "sorting") {
|
||||
if (key === "sortings") {
|
||||
value = value
|
||||
? value.map((item) => {
|
||||
const [field, order] = item;
|
||||
|
||||
@ -37,10 +37,9 @@ import TabPanel from "primevue/tabpanel";
|
||||
import Api from "../../api";
|
||||
import ApiWithToast from "../../api-toast";
|
||||
import { useLoadingStore } from "../../stores/loading";
|
||||
import { useErrorStore } from "../../stores/errors";
|
||||
|
||||
const loadingStore = useLoadingStore();
|
||||
const errorStore = useErrorStore();
|
||||
|
||||
const clientNames = ref([]);
|
||||
const client = ref({});
|
||||
const { clientName } = defineProps({
|
||||
@ -50,10 +49,10 @@ const { clientName } = defineProps({
|
||||
const getClientNames = async (type) => {
|
||||
loadingStore.setLoading(true);
|
||||
try {
|
||||
const names = await Api.getCustomerNames(type);
|
||||
const names = await Api.getClientNames(type);
|
||||
clientNames.value = names;
|
||||
} catch (error) {
|
||||
errorStore.addError(error.message || "Error fetching client names");
|
||||
console.error("Error fetching client names in Client.vue: ", error.message || error);
|
||||
} finally {
|
||||
loadingStore.setLoading(false);
|
||||
}
|
||||
@ -61,9 +60,14 @@ const getClientNames = async (type) => {
|
||||
|
||||
const getClient = async (name) => {
|
||||
loadingStore.setLoading(true);
|
||||
const clientData = await ApiWithToast.makeApiCall(() => Api.getClient(name));
|
||||
client.value = clientData || {};
|
||||
loadingStore.setLoading(false);
|
||||
try {
|
||||
const clientData = await Api.getClient(name);
|
||||
client.value = clientData || {};
|
||||
} catch (error) {
|
||||
console.error("Error fetching client data in Client.vue: ", error.message || error);
|
||||
} finally {
|
||||
loadingStore.setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
|
||||
@ -165,7 +165,7 @@ const tableActions = [
|
||||
{
|
||||
label: "View Details",
|
||||
action: (rowData) => {
|
||||
router.push(`/clients/${rowData.id}`);
|
||||
router.push(`/clients/${rowData.customerName}`);
|
||||
},
|
||||
type: "button",
|
||||
style: "info",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user