import frappe @frappe.whitelist() def get_pallets(page=1, page_size=100, sort_field="pallet_number", sort_dir="desc", status_filter="", search=""): page = int(page) page_size = int(page_size) offset = (page - 1) * page_size # Only pallets with dates (filters empty rows) conditions = ["pallet_number IS NOT NULL", "pallet_number != ", "date_reserved IS NOT NULL"] # Junk filter (same as EIM) junk = ["", "0", "0000", "N/A", "TBD", "null"] conditions.append("pallet_number NOT IN ( + , .join(junk) + )") if status_filter: conditions.append("status = {0}".format(frappe.db.escape(status_filter))) if search: conditions.append("pallet_number LIKE %{0}%".format(frappe.db.escape(search))) where_clause = " AND ".join(conditions) # Get total total = frappe.db.sql("""SELECT COUNT(*) FROM tabPallet WHERE {0}""".format(where_clause))[0][0] # Get pallets - convert pallet_number to unsigned int for numeric sort # Use natural sort: convert to int for proper numeric ordering pallets = frappe.db.sql(""" SELECT name, pallet_number, date_reserved, received_date, customer_number, inbound_weight, tester, description, qty_to_sales, weight_to_sales, finish_date, notes, status FROM tabPallet WHERE {0} ORDER BY CAST(pallet_number AS UNSIGNED) {1} LIMIT {2} OFFSET {3} """.format(where_clause, sort_dir, page_size, offset), as_dict=True) return { "pallets": pallets, "total": total, "page": page, "page_size": page_size }