This release addresses critical issues in picking, quality control, and reporting workflows, and adds several UX improvements across settings and dashboard pages.
Duplicate Line Item Picking Fix
- Orders with the same product appearing as multiple line items (same SKU/UPC) can now be picked correctly
- Previously, scanning the barcode a second time would show "Already picked" even though the second line item was unpicked
- Each line item is now tracked by a unique pivot ID, ensuring the system distinguishes between duplicate entries
- The server-side pick endpoint uses the pivot ID to update the exact line item, not just the first match
- The order_product sync now correctly distributes picked quantities across duplicate rows instead of overwriting all of them
Unpickable Order Prevention
- Orders with no products or insufficient on_hand inventory are now blocked from entering the picklist
- When auto-assigning the next order, unpickable orders are silently skipped
- When scanning a specific order number, the picker sees a clear error message explaining why the order cannot be picked (e.g., "Order has no products" or "Insufficient on_hand inventory for: SKU-123 (need 5, on_hand 0)")
- Applies to all Picker Mode entry points: start picking, next order, and manual order scan
QC Bundle Scanning Improvements
- The bundle popup now asks "How many bundles?" instead of showing units per pack in the input field
- Example: for a 5-pack with 10 units remaining, the popup defaults to 2 (bundles) instead of 5 (units per pack)
- The entered bundle count is automatically converted to total units on submission, capped at the remaining quantity
- The popup description now reads "Each bundle = X units. Remaining to pack: Y units/single" for clarity
- When scanning a single UPC, the quantity popup now defaults to the picked quantity instead of the ordered quantity
- Fixed the barcode input triggering the scan popup on blur (losing focus) — now only triggers on Enter key or scanner input
Pick Rate Calculation Fix
- Fixed inflated pick rates across all dashboards (Live Insights, Leaderboard, Detailed Performance, Picker Detail)
- Previously, rates were calculated using the gap between first and last pick, which produced wildly inflated numbers (e.g., 2110/hr instead of ~105/hr)
- Live Insights now calculates rate using elapsed time from first pick to current time, with a minimum of 1 hour
- Leaderboard and Detailed Performance now calculate active hours per day and sum them, avoiding overnight gaps inflating the denominator
- Picker Detail page uses the same per-day calculation with a 1-hour minimum per active day
Picker Mode: Cart Display
- The pick page now shows the cart name (or code) alongside the bin when a bin has an associated cart
- Displayed as: bin icon + BIN-001 | cart icon + Cart A
Cart-Bin Management
- Cart edit page redesigned with two-column layout: form on the left, associated bins on the right
- Bins can now be assigned and unassigned directly from the cart edit page
- Slide-over drawer for assigning bins: search available (unassigned) bins, click to assign instantly
- Hover any assigned bin to reveal a remove button with SweetAlert2 confirmation
- Quick stats in header: bin count, created date, last updated
Advanced Filters
- Locations page: added collapsible Advanced Filters with Location Type, Zone (now using proper zone relationship), Occupancy (with/empty), and Below Min Level
- Bins page: added filters for Cart, Status (active/inactive), Cart Assignment (assigned/unassigned), and per-page selector
- Carts page: added filters for Status (active/inactive), Bins (with/without), and per-page selector
- All three pages preserve filter state in pagination links
Order Re-Import Fix
- Fixed re-import from Duoplane not removing items with quantity set to 0 (cancelled line items)
- Items with qty 0 in Duoplane are now properly detached from the order with inventory restored
- Fixed price comparison type mismatch that could skip legitimate price updates
Shipment Sync Fix
- Fixed dashboard pull from Shipstation creating shipments with wrong quantities
- Previously, each shipment was assigned the full order quantity (e.g., 400) instead of the actual shipped quantity per box (e.g., 30)
-
syncShipmentProducts()now uses the shipped quantity from Shipstation's fulfillment data - Order product data is never modified by the dashboard pull — Duoplane remains the source of truth for order items
Dashboard Improvements
- Removed the "Oldest Unassigned Orders" section from the Picking Reports dashboard (and its unnecessary database query)
- Picking Reports now defaults to "Today" instead of the current week when first opened
- Active picker elapsed time now displays in h:m format (e.g., "22h 37m") instead of raw minutes
- Leaderboard and Detailed Performance avg time per order shows h:m format when 60+ minutes
- Order Pipeline section hidden on mobile devices for cleaner layout
- Fixed orders count showing 1 for all pickers in the leaderboard (SQL aggregation bug after pick rate fix)
Bug Fixes
- Fixed LiveInsightsController crash when no fulfillments exist in the last 7 days (round(null) error)
- Fixed stale view cache error on production for picklist-overview (toDateString on string)
Picker Debug Logging
- Added optional browser console logging for the Picker Mode workflow
- Enable via
PICKER_DEBUG_LOG=truein.env - Logs include: page initialization with item table, barcode scan matching, AJAX request/response details, local state updates, location navigation, and error warnings
- Color-coded by category: Scan (green), AJAX (amber), State (indigo), Warn (red)