feat: per-site reporting, and actually populate the site on a booking

jupiter's getreportsummary took a locationid — per kitchen, per branch. That
was the one report parameter with no Doormile equivalent, and for a food
client with 23 kitchens it is the difference between one number and a usable
report.

  GET /admin/reports?locationid=      narrows every figure to one site
  GET /admin/reports                  now carries a by_location block
  GET /admin/locations/summary        the standalone per-site table

The filter alone would have been useless: pickuplocationid was null on every
booking in the system, because the console sends a kitchen's address rather
than its id. createExpressBooking now resolves the site itself — nearest
stored location within 150m, falling back to an address match, nil when
nothing matches confidently, since a wrong attribution silently moves orders
between kitchens. An explicit pickuplocationid still wins.

Bookings that named no site are reported as their own "Unattributed" row
rather than dropped, so per-site rows add up to the summary total.

Two fixes found while in here:
- the payments join in the per-site query fanned out, counting a booking once
  per payment row; payments are now pre-aggregated per booking
- by_rider was empty for every client login, which reads as "your riders did
  nothing". Riders are tenant-scoped now, so a client sees its own.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Suriya
2026-08-06 12:56:56 +05:30
parent cf488b3d76
commit 0c407e5b27
4 changed files with 342 additions and 23 deletions

View File

@@ -222,6 +222,9 @@ func RegisterRoutes(app *fiber.App, cfg *config.Config) {
adminAuth.Get("/tenants/:id/locations", controllers.GetTenantLocations)
adminAuth.Post("/tenants/:id/locations", controllers.CreateTenantLocation)
adminAuth.Put("/tenantlocations/:id", controllers.UpdateTenantLocation)
// Per-site performance — jupiter's getlocationsummary. Needs ?tenantid= for
// Doormile staff; a client login is already pinned to its own sites.
adminAuth.Get("/locations/summary", controllers.GetLocationSummary)
// Tenant customers
adminAuth.Get("/tenantcustomers", controllers.GetTenantCustomers)