update filter functionality

This commit is contained in:
Casey 2025-11-04 09:09:56 -06:00
parent 464c62d1e5
commit 9431a0502a
10 changed files with 2362 additions and 220 deletions

View file

@ -23,73 +23,174 @@ class Api {
}
}
static async getClientDetails(forTable = true) {
const data = [];
const addresses = await this.getDocsList("Address", ["*"]);
for (const addr of addresses) {
const clientDetail = {};
static async getClientDetails(options = {}) {
const {
forTable = true,
page = 0,
pageSize = 10,
filters = {},
sortField = null,
sortOrder = null,
searchTerm = null,
} = options;
const customer = await this.getDetailedDoc(
"Customer",
addr["custom_customer_to_bill"],
console.log("DEBUG: API - getClientDetails called with options:", options);
// Build filters for the Address query
let addressFilters = {};
// Add search functionality across multiple fields
if (searchTerm) {
// Note: This is a simplified version. You might want to implement
// full-text search on the backend for better performance
addressFilters.address_line1 = ["like", `%${searchTerm}%`];
}
// Add any custom filters
Object.keys(filters).forEach((key) => {
if (filters[key] && filters[key].value) {
// Map frontend filter names to backend field names if needed
switch (key) {
case "fullName":
// This will need special handling since fullName is constructed
// For now, we'll search in address_line1 or city
addressFilters.address_line1 = ["like", `%${filters[key].value}%`];
break;
// Add other filter mappings as needed
}
}
});
try {
// Get total count first for pagination
const totalCount = await this.getDocCount("Address", addressFilters);
// Get paginated addresses
const addresses = await this.getDocsList(
"Address",
["*"],
addressFilters,
page,
pageSize,
);
const quotations = await this.getDocsList("Quotation", [], {
custom_installation_address: addr["name"],
});
const quoteDetails =
quotations.length > 0
? await this.getDetailedDoc("Quotation", quotations[0]["name"])
: null;
const data = [];
const processedData = [];
const jobs = await this.getDocsList("Project", [], {
project_template: "SNW Install",
custom_installation_address: addr["name"],
});
const jobDetails =
jobs.length > 0 ? await this.getDetailedDoc("Project", jobs[0]["name"]) : null;
// Process each address to build client details
for (const addr of addresses) {
try {
const clientDetail = {};
clientDetail.customer = customer;
clientDetail.address = addr;
clientDetail.estimate = quoteDetails;
clientDetail.job = jobDetails;
const customer = await this.getDetailedDoc(
"Customer",
addr["custom_customer_to_bill"],
);
const totalPaid = quoteDetails
? quoteDetails.payment_schedule
? quoteDetails.payment_schedule.reduce(
(sum, payment) => sum + (payment.paid_amount || 0),
0,
)
: 0
: 0;
const tableRow = {
fullName: `${customer.customer_name} - ${addr.address_line1}, ${addr.city} ${addr.state}`,
appointmentStatus: "not started",
estimateStatus: quoteDetails
? quoteDetails.custom_response == "Accepted"
? "completed"
: "in progress"
: "not started",
paymentStatus: quoteDetails
? totalPaid < quoteDetails.grand_total
? "in progress"
: "completed"
: "not started",
jobStatus: jobDetails
? jobDetails.status === "Completed"
? "completed"
: "in progress"
: "not started",
};
if (forTable) {
data.push(tableRow);
} else {
data.push(clientDetail);
const quotations = await this.getDocsList("Quotation", [], {
custom_installation_address: addr["name"],
});
const quoteDetails =
quotations.length > 0
? await this.getDetailedDoc("Quotation", quotations[0]["name"])
: null;
const jobs = await this.getDocsList("Project", [], {
project_template: "SNW Install",
custom_installation_address: addr["name"],
});
const jobDetails =
jobs.length > 0
? await this.getDetailedDoc("Project", jobs[0]["name"])
: null;
clientDetail.customer = customer;
clientDetail.address = addr;
clientDetail.estimate = quoteDetails;
clientDetail.job = jobDetails;
const totalPaid = quoteDetails
? quoteDetails.payment_schedule
? quoteDetails.payment_schedule.reduce(
(sum, payment) => sum + (payment.paid_amount || 0),
0,
)
: 0
: 0;
const tableRow = {
id: addr.name, // Add unique ID for DataTable
fullName: `${customer.customer_name} - ${addr.address_line1}, ${addr.city} ${addr.state}`,
appointmentStatus: "not started",
estimateStatus: quoteDetails
? quoteDetails.custom_response == "Accepted"
? "completed"
: "in progress"
: "not started",
paymentStatus: quoteDetails
? totalPaid < quoteDetails.grand_total
? "in progress"
: "completed"
: "not started",
jobStatus: jobDetails
? jobDetails.status === "Completed"
? "completed"
: "in progress"
: "not started",
};
if (forTable) {
data.push(tableRow);
} else {
data.push(clientDetail);
}
processedData.push(clientDetail);
} catch (error) {
console.error(`Error processing address ${addr.name}:`, error);
// Continue with other addresses even if one fails
}
}
// Apply client-side sorting if needed (better to do on server)
if (sortField && forTable) {
data.sort((a, b) => {
const aValue = a[sortField] || "";
const bValue = b[sortField] || "";
const comparison = aValue.localeCompare(bValue);
return sortOrder === -1 ? -comparison : comparison;
});
}
// Apply client-side filtering for constructed fields like fullName
let filteredData = data;
if (filters.fullName && filters.fullName.value && forTable) {
const searchValue = filters.fullName.value.toLowerCase();
filteredData = data.filter((item) =>
item.fullName.toLowerCase().includes(searchValue),
);
}
console.log("DEBUG: API - Fetched Client Details:", {
total: totalCount,
page: page,
pageSize: pageSize,
returned: filteredData.length,
});
// Return paginated response with metadata
return {
data: filteredData,
pagination: {
page: page,
pageSize: pageSize,
total: totalCount,
totalPages: Math.ceil(totalCount / pageSize),
},
};
} catch (error) {
console.error("DEBUG: API - Error fetching client details:", error);
throw error;
}
// const data = DataUtils.dummyClientData;
console.log("DEBUG: API - Fetched Client Details: ", data);
return data;
}
static async getJobDetails() {
@ -125,6 +226,32 @@ class Api {
return data;
}
/**
* Get paginated client data with filtering and sorting
* @param {Object} paginationParams - Pagination parameters from store
* @param {Object} filters - Filter parameters from store
* @returns {Promise<{data: Array, totalRecords: number}>}
*/
static async getPaginatedClientDetails(paginationParams = {}, filters = {}) {
const { page = 0, pageSize = 10, sortField = null, sortOrder = null } = paginationParams;
const options = {
forTable: true,
page,
pageSize,
filters,
sortField,
sortOrder,
};
const result = await this.getClientDetails(options);
return {
data: result.data,
totalRecords: result.pagination.total,
};
}
/**
* Fetch a list of documents from a specific doctype.
*