From fe91302ff5e5c6851e94c4ea0ed4f4e945fbb395 Mon Sep 17 00:00:00 2001 From: Westech Admin Date: Tue, 19 May 2026 21:28:52 +0000 Subject: [PATCH] Fix 2024 pallet numbering and update pallet-list page --- .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 170 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 177 bytes .../pallet/__pycache__/pallet.cpython-312.pyc | Bin 0 -> 685 bytes westech_r2/page/pallet-list/pallet-list.html | 117 +++++++++++------- westech_r2/page/pallet-list/pallet-list.py | 65 ++++------ 5 files changed, 97 insertions(+), 85 deletions(-) create mode 100644 westech_r2/doctype/__pycache__/__init__.cpython-312.pyc create mode 100644 westech_r2/doctype/pallet/__pycache__/__init__.cpython-312.pyc create mode 100644 westech_r2/doctype/pallet/__pycache__/pallet.cpython-312.pyc diff --git a/westech_r2/doctype/__pycache__/__init__.cpython-312.pyc b/westech_r2/doctype/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25410b84792e7ca24db58b7be55e494b866c1f56 GIT binary patch literal 170 zcmX@j%ge<81P}jlWP#|%AOanHW&w&!XQ*V*Wb|9fP{ah}eFmxd<*A>MpPQ fu*uC&Da}c>D`Ewj%m~EAAjU^#Mn=XWW*`dynj99YQj;#udF4I(YR(%?gFDsQH2y6hCA%B)P!I=FVPBq0Zv0Zqcx z%?swHN&XOs%L|vs33JOZO@a3gR<>%&pb%!gCyYGIz|(}alcXFd6Xs3=DPiJbEf++^ zIOhYeC7ik<$j8|bsN~VGEJ0Yizyql-Ofn1@aG|G=d%Dm`5eYK`9v4JdwHRaS#;)t0 z4g9#sz^^rYpk)sG{Q3~`DE6f+^Y?&ph~j|W`Ws43UX|e2tt>;Yti_IfUPrh{EsrAji z@Vx!3{bJ+I?W4Wd>tF2~r!8b(nM)buX;gi+h4@=U*A!lr?#y1#3NlV%gI - .pallet-table-container { padding: 0; overflow-x: auto; } + .pallet-list-page { font-family: Helvetica Neue, Arial, sans-serif; } + .pallet-list-page h2 { color: #2F5496; margin-bottom: 16px; font-size: 20px; } + .pallet-search-box { margin-bottom: 16px; display: flex; gap: 10px; align-items: center; flex-wrap: wrap; } + .pallet-search-box input, .pallet-search-box select { + padding: 6px 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 13px; + } + .pallet-search-box button { + padding: 6px 14px; border: 1px solid #ddd; border-radius: 4px; cursor: pointer; + font-size: 13px; background: white; + } + .pallet-search-box button.btn-primary { background: #2F5496; color: white; border-color: #2F5496; } + .pallet-search-box button.btn-success { background: #548235; color: white; border-color: #548235; } + .pallet-table-container { padding: 0; overflow-x: auto; background: white; border-radius: 4px; } .pallet-table { width: 100%; border-collapse: collapse; font-size: 13px; } - .pallet-table th { background: #3cc062; color: white; padding: 8px 10px; text-align: left; cursor: pointer; } + .pallet-table th { + background: #2F5496; color: white; padding: 8px 10px; text-align: left; + cursor: pointer; white-space: nowrap; font-weight: 500; + } .pallet-table td { padding: 5px 10px; border-bottom: 1px solid #eee; } .pallet-table tr:hover { background: #f5f5f5; } - .status-received { color: #2196F3; } - .status-sorting { color: #FF9800; } - .status-processing { color: #9C27B0; } - .status-complete { color: #4CAF50; } - .status-shipped { color: #607D8B; } + .pallet-table tr.new-row { background: #FFF9E6 !important; } + .pallet-table a { color: #2F5496; text-decoration: none; font-weight: 600; } + .status-received { color: #2196F3; font-weight: 600; } + .status-sorting { color: #FF9800; font-weight: 600; } + .status-processing { color: #9C27B0; font-weight: 600; } + .status-complete { color: #4CAF50; font-weight: 600; } + .status-shipped { color: #607D8B; font-weight: 600; } + .pallet-pagination { margin-top: 12px; display: flex; gap: 5px; align-items: center; } + .pallet-pagination button { + padding: 5px 12px; border: 1px solid #ddd; background: white; cursor: pointer; + border-radius: 4px; font-size: 13px; color: #2F5496; + } + .pallet-pagination button.active { background: #2F5496; color: white; border-color: #2F5496; } + .pallet-pagination button:disabled { opacity: 0.5; cursor: not-allowed; } + .pallet-count { margin-left: auto; color: #666; font-size: 13px; } - +
+

📦 Pallet List

-
- - - - - - - - - - - - - - - - - - - - - -
Pallet #Date ReservedRec. DateCustomer #CompanyLbsWhoItemsQTY SaleLbs SaleFinish DateStatusNotes
Loading...
-
+ -
+
+ + + + + + + + + + + + + + + + + + + + +
Pallet # ⇅Date Reserved ⇅Rec. Date ⇅Customer # ⇅Lbs ⇅Who ⇅Items Tested ⇅QTY Sale ⇅Lbs Sale ⇅Finish Date ⇅StatusNotes
Loading...
+
+ +
+
diff --git a/westech_r2/page/pallet-list/pallet-list.py b/westech_r2/page/pallet-list/pallet-list.py index 64730c5..82aa5e7 100644 --- a/westech_r2/page/pallet-list/pallet-list.py +++ b/westech_r2/page/pallet-list/pallet-list.py @@ -1,50 +1,40 @@ import frappe -import json @frappe.whitelist() def get_pallets(page=1, page_size=100, sort_field="pallet_number", sort_dir="desc", status_filter="", search=""): - """Fetch pallets from ERPNext with filters.""" page = int(page) page_size = int(page_size) offset = (page - 1) * page_size - # Base filters - filters = [ - ["Pallet", "pallet_number", "is", "set"], - ["Pallet", "date_reserved", "is", "set"], - ] + # 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: - filters.append(["Pallet", "status", "=", status_filter]) + conditions.append("status = {0}".format(frappe.db.escape(status_filter))) if search: - filters.append(["Pallet", "pallet_number", "like", f"%{search}%"]) + conditions.append("pallet_number LIKE %{0}%".format(frappe.db.escape(search))) - fields = [ - "name", "pallet_number", "date_reserved", "received_date", - "customer_number", "company_name", "inbound_weight", "tester", - "description", "qty_to_sales", "weight_to_sales", "finish_date", "notes", "status" - ] + where_clause = " AND ".join(conditions) - order_by = f"{sort_field} {sort_dir}" + # Get total + total = frappe.db.sql("""SELECT COUNT(*) FROM tabPallet WHERE {0}""".format(where_clause))[0][0] - # Get total count - count_result = frappe.get_list( - "Pallet", - filters=filters, - fields=["count(*) as total"], - as_list=True - ) - total = count_result[0][0] if count_result else 0 - - # Get pallets - pallets = frappe.get_list( - "Pallet", - filters=filters, - fields=fields, - order_by=order_by, - limit_page_length=page_size, - limit_start=offset - ) + # 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, @@ -52,12 +42,3 @@ def get_pallets(page=1, page_size=100, sort_field="pallet_number", sort_dir="des "page": page, "page_size": page_size } - -@frappe.whitelist() -def update_pallet(docname, field, value): - """Update a single field on a Pallet.""" - pallet = frappe.get_doc("Pallet", docname) - pallet.set(field, value) - pallet.save(ignore_permissions=True) - frappe.db.commit() - return {"status": "ok", "message": f"Updated {field}"}