Commit graph

91 commits

Author SHA1 Message Date
John Pinkyfloyd
50307efa8d Fix cart item lookup to use orderLineItemId directly
- Add IsDeleted=0 filter to existing item search query
- Add support for OrderLineItemID parameter for direct item targeting
- Fixes duplicate items being created on quantity increment
- Fixes item deletion not working due to finding wrong/deleted records

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 09:25:20 -07:00
John Pinkyfloyd
fc9bbd78be Only keep Quantity=0 for modifiers, not root items 2026-03-09 09:13:55 -07:00
John Pinkyfloyd
029279658d Keep default-checked items with Quantity=0 when deselected
For inverted display: when user deselects a default-checked item, keep it
in cart with Quantity=0 instead of deleting. Cart displays "NO X" for these.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-09 09:11:15 -07:00
John Pinkyfloyd
6ffc77fcaf Revert inverted deselect logic - back to simple delete 2026-03-09 07:34:39 -07:00
John Pinkyfloyd
5e01bcd989 Add error handling to inverted group check 2026-03-08 23:10:48 -07:00
John Pinkyfloyd
503754e248 Keep deselected inverted defaults in cart with Quantity=0
For inverted groups, when user deselects a default item, keep it in cart
with Quantity=0 instead of deleting. This allows cart to display "NO X".

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-08 23:05:44 -07:00
John Pinkyfloyd
f57d249fee Add ParentIsInvertedGroup to cart line items
Child items need to know if their parent group is inverted for proper
display logic (showing "NO X" instead of listing selected items).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-08 23:00:49 -07:00
John Pinkyfloyd
bae4293055 Add IsInvertedGroup to cart line items API response
Required for inverted modifier display (showing "NO X" for removed defaults
instead of listing all selected items).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-08 22:58:54 -07:00
John Pinkyfloyd
446addd66d Fix inverted modifier not removing from cart
When deselecting a modifier (IsSelected=false), Quantity was incorrectly
set to 1 instead of 0, preventing the removal logic from working.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-08 21:24:56 -07:00
John Mizerek
717d60d6e6 Add IsInvertedGroup support for modifier groups
When enabled on a modifier group, KDS and cart only show removed
defaults (e.g., "NO Mustard") instead of listing all selected items.
Useful for groups where all options are checked by default.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 18:14:19 -07:00
John Mizerek
6cdbff129f Add takeaway/pickup order support
- getOrCreateCart: only require ServicePointID for dine-in (OrderTypeID=1)
- get.cfm + items.cfm: return OrderTypes from Businesses table
- saveOrderTypes.cfm: new endpoint to save business order type config
- KDS: add PICKUP/DELIVERY badges on order cards
- Portal: add Order Types toggle card in settings (Dine-In always on, Takeaway toggle)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 10:45:06 -07:00
John Pinkyfloyd
b9755a1e72 Add role-aware cash routing and backend improvements
Staff cash goes to worker payout ledger, admin/manager cash deletes
pending payout and reverses withholding. Add RoleID to myBusinesses
response. Various order and webhook improvements.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 20:04:46 -08:00
John Mizerek
d822fcad5a feat: per-station item completion on KDS
Each station can mark their items done independently. When all
stations are done, the order auto-promotes to Ready (status 3)
and delivery/pickup tasks are created automatically.

- New markStationDone.cfm endpoint for per-station completion
- Extract task creation into shared _createOrderTasks.cfm include
- Add line item StatusID to listForKDS.cfm response
- KDS shows per-station "Mark Station Done" button when filtered
- Done items display with strikethrough and checkmark
- Manager view retains full manual control (no station selected)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 19:19:25 -08:00
John Mizerek
576c90fffd Fix DISTINCT ORDER BY error in KDS station-filtered query
MySQL rejects ORDER BY o.SubmittedOn when SELECT DISTINCT has
DATE_FORMAT(o.SubmittedOn) AS SubmittedOn. Use the alias instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 17:30:44 -08:00
John Mizerek
94b5bbbce1 KDS: per-station line item filtering with expand toggle
Backend returns all line items for every order (removes station
filter from sub-query). Frontend filters by station, showing only
relevant items by default. An expand toggle reveals other stations'
items dimmed at 35% opacity for full order context.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 15:30:59 -08:00
John Mizerek
c65cd8242b Round balance amounts to cents before applying
Prevents sub-cent precision (e.g. $0.883125) from accumulating in
BalanceApplied and payment records. All balance math now rounds to
nearest cent first.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 14:32:54 -08:00
John Mizerek
c580e6ec78 Auto-apply user balance on cash and card orders
Balance from cash change now silently reduces the amount owed on the
next order. For cash: deducted immediately in submitCash, reduces cash
the worker needs to collect (or skips cash task entirely if fully
covered). For card: reduces the Stripe PaymentIntent amount, deducted
in webhook on successful payment. Receipt shows "Balance applied" line.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 14:16:21 -08:00
John Mizerek
96c2ed3fc1 Fix cash payment fee: use real Payfrit platform fee, not 2.25% cash handling fee
submitCash.cfm: Calculate platform fee from subtotal * PayfritFee,
store in Orders.PlatformFee and Payments.PaymentPayfritsCut on submission.

complete.cfm: Replace bogus 2.25% cash transaction fee with the real
platform fee (customer fee + business fee = 2 × PayfritFee × subtotal).
Credit full Payfrit revenue to User 0. Record business fee in
PaymentPayfritNetworkFees.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 12:59:22 -08:00
John Mizerek
cb7e3b7fc6 fix: include PaymentFromCreditCard in cash payment INSERT
PaymentFromCreditCard column is NOT NULL with no default value,
causing INSERT to fail silently. Set to 0 for cash payments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 12:44:53 -08:00
John Mizerek
8adac1a242 Fix submitCash.cfm for legacy Payments table columns
Payments table still uses old prefixed names (PaymentID as PK, no UUID
column, no PaymentTip column, required PaymentReceivedByUserID). Updated
INSERT to match actual production schema.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 11:29:40 -08:00
John Mizerek
61949586f5 Fix mismatched cfif/cftry tags in updateStatus.cfm
Extra </cfif> at line 243 had no matching opener. Was hidden by
Lucee's template cache until the Tomcat restart exposed it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 13:01:49 -08:00
John Mizerek
4e0c2ee1bf Remove timezone conversion hacks — MySQL now runs in UTC
All servers (db, dev, biz) migrated to UTC:
- MySQL default-time-zone changed from America/Los_Angeles to +00:00
- All existing datetime data converted from Pacific to UTC
- JVM timezone set to UTC on dev and biz servers
- OS timezone set to UTC on all three servers

Removed CONVERT_TZ hack from listForKDS.cfm — data is natively UTC.
Simplified toISO8601() — no dateConvert needed since data is already UTC.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 12:37:30 -08:00
John Mizerek
4b35c27f75 Fix KDS timestamps: CONVERT_TZ from MySQL local time to UTC
MySQL is in America/Los_Angeles, not UTC. Use CONVERT_TZ to properly
convert to UTC before appending the Z suffix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 12:20:39 -08:00
John Mizerek
4dfdd6ee8b Fix KDS UTC timestamps: format in SQL to bypass Lucee timezone shift
dateTimeFormat() converts to JVM local time before formatting, so
appending 'Z' was wrong. Use DATE_FORMAT in SQL instead since the DB
values are already UTC.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 12:18:37 -08:00
John Mizerek
453188d63f Fix KDS elapsed time by tagging SubmittedOn as UTC
DB stores timestamps in UTC but the API returned them without timezone
info, causing JS to parse them as local time. Append 'Z' suffix so
new Date() correctly interprets them as UTC.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 12:14:47 -08:00
John Mizerek
48fa6e4482 Fix missing UserID in submit.cfm order query
Tab-aware submit references qOrder.UserID but the SELECT didn't include it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:53:17 -08:00
John Mizerek
4c0479db5c Add Open Tabs feature: tab APIs, presence tracking, shared tabs, cron, portal settings
- New api/tabs/ directory with 13 endpoints: open, close, cancel, get, getActive,
  addOrder, increaseAuth, addMember, removeMember, getPresence, approveOrder,
  rejectOrder, pendingOrders
- New api/presence/heartbeat.cfm for beacon-based user presence tracking
- New cron/expireTabs.cfm for idle tab expiry and presence cleanup
- Modified submit.cfm for tab-aware order submission (skip payment, update running total)
- Modified getOrCreateCart.cfm to auto-detect active tab and set TabID on new carts
- Modified webhook.cfm to handle tab capture events (metadata type=tab_close)
- Modified businesses/get.cfm and updateTabs.cfm with new tab config columns
- Updated portal tab settings UI with auth amounts, max members, approval toggle
- Added tab and presence endpoints to Application.cfm public allowlist

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:56:07 -08:00
John Mizerek
9e5770f131 Add toISO8601() helper for UTC date formatting 2026-02-20 11:56:31 -08:00
John Mizerek
43afe9ae8c Prevent duplicate cash tasks for same order
Check for existing active (uncompleted) cash task before creating
a new one. Prevents duplicate "Pay With Cash" tasks if order status
changes are triggered multiple times.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 09:41:58 -08:00
John Mizerek
06c4b99a66 Include ServicePointID when creating delivery tasks
Needed for beacon dwell auto-completion to work.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 19:32:37 -08:00
John Mizerek
2019b9ff43 Use proper task types for delivery/pickup tasks
- Looks up task type by name for the business instead of hardcoding ID
- Dine-in: 'Deliver to Table'
- Takeaway: 'Order Ready for Pickup'
- Delivery: 'Deliver to Address'

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 19:29:47 -08:00
John Mizerek
7caf4d60b0 Fix delivery task creation when other tasks exist for order
The duplicate check was preventing delivery task creation if ANY task
existed for the order (e.g., Cash or Chat tasks). Now only checks for
TaskTypeID=1 (delivery/pickup tasks) to allow proper task creation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 19:24:59 -08:00
John Mizerek
703a283d32 Enable cart recovery API with optional business filter
- getActiveCart now returns existing cart for user
- Optional BusinessID parameter to filter by specific business
- Used by Android app for cart recovery when scanning at a business

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 12:53:57 -08:00
John Pinkyfloyd
eebf231aad Fix column names in submitCash.cfm (PaymentAddedOn, TipAmount) 2026-02-16 11:50:57 -08:00
John Pinkyfloyd
175fdfb2b9 Add submitCash.cfm endpoint for cash payments
Creates Payment record with PaymentPaidInCash and links to order
Sets PaymentStatus = 'pending' and StatusID = 1 (submitted)
2026-02-16 11:49:06 -08:00
John Mizerek
5912784772 Create 'Pay With Cash' task when cash orders reach Final Prep
- Auto-create cash task when order status transitions to 3 (Final Prep)
  and has a pending cash payment (Payments.PaymentPaidInCash > 0)
- Task includes OrderID so Android can display OrderTotal
- Task title includes service point name when available
- Fix duplicate task check: was WHERE ID = ?, now WHERE OrderID = ?

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 11:27:16 -08:00
John Pinkyfloyd
a2be30b952 Add UUID to getDetail.cfm response for receipt link
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-09 18:54:02 -08:00
John Pinkyfloyd
d2985e193a Fix submit.cfm: remove ServicePoints join that was causing column name errors 2026-02-09 16:32:00 -08:00
John Pinkyfloyd
add65346c9 Fix submit.cfm: correct column names for OrderLineItems and ServicePoints queries 2026-02-09 15:58:13 -08:00
John Pinkyfloyd
1787671239 Add PayfritFee to cart API responses 2026-02-09 15:42:57 -08:00
John Mizerek
a318b8668f Fix cart/tax issues and add menu item thumbnails
- uploadItemPhoto: Add EXIF orientation fix, generate thumb/medium/full sizes
- getActiveCart: Disable old cart lookup (always returns no cart)
- getOrCreateCart: Always create fresh cart instead of reusing old ones
- getCart: Add IsDeleted filter, calculate subtotal/tax/total server-side
- getDetail: Remove default 8.25% tax rate (business must configure)
- menu-builder: Add lightbox for full-size images, use thumbnail URLs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 14:22:54 -08:00
John Mizerek
30c175bafe Add TaxRate to cart and menu API responses
- getCart.cfm: Include TaxRate from Businesses table
- getOrCreateCart.cfm: Include TaxRate from Businesses table
- items.cfm: Include TaxRate in menu response for cart calculation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 14:31:26 -08:00
John Mizerek
e40e87efe0 Allow child businesses to use parent service points without grant
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 11:58:44 -08:00
John Mizerek
8c247eb000 KDS: Dark minimal theme matching HUD, fix updateStatus column names
- Redesign KDS with HUD-matching dark theme (pure black background)
- Header styling identical to HUD: position, font, clock format
- Status indicator moved to bottom-right corner like HUD
- Remove business ID config - now uses portal localStorage only
- Keep station toggle functionality
- Fix updateStatus.cfm: use correct column names for dev DB
  (sp.Name instead of sp.ServicePointName, sp.ID instead of sp.ServicePointID)
- Use relative API URL instead of hardcoded production URL

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 17:45:11 -08:00
John Mizerek
31a89018f5 Launch prep: fix menu builder, payment flow, comment out pre-launch features
- Fix menu builder dropdown showing empty names (return MenuName instead of Name)
- Add default menu selection (setDefault action, DefaultMenuID in getForBuilder)
- Fix createPaymentIntent column names for dev schema (ID, StripeAccountID, etc.)
- Fix menu-builder favicon and remove redundant business label
- Comment out Tabs/Running Checks feature for launch (HTML + JS)
- Comment out Service Point Marketing/Grants feature for launch (HTML + JS)
- Add testMarkPaid.cfm for testing orders without Stripe webhooks
- Task API updates for worker payout ledger integration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 10:18:33 -08:00
John Mizerek
e21a7f7266 Remove DeliveryMultiplier from Businesses query (column no longer exists)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 11:11:34 -08:00
John Mizerek
152ac572c7 Add detailed error message to getOrCreateCart for debugging
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 11:07:03 -08:00
John
16a3b7c9a3 Replace queryExecute with queryTimed across all endpoints for perf tracking
Converts 200+ endpoint files to use queryTimed() wrapper which tracks
DB query count and execution time. Restores perf dashboard files that
were accidentally moved to _scripts/. Includes portal UI updates.
2026-02-02 00:28:37 -08:00
John Mizerek
f52d14bb7e Add Service Point Sharing infrastructure
Grant-based system allowing businesses to share service points with
other businesses. Includes grant CRUD API, time/eligibility/economics
policies, enforcement at cart creation and order submit, Stripe payment
routing for owner fees, and portal UI for managing grants.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 21:34:03 -08:00
John Mizerek
89f339a9fd Fix order history and active cart API response keys
- Replace tt_OrderTypes JOIN with CASE statement (table casing on Linux)
- Fix key mismatches: Name->BusinessName, UUID->OrderUUID, StatusID->OrderStatusID

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:12:03 -08:00