updates on the api endpoints on the customer page and more
This commit is contained in:
104
scratch/check_booking_paging.go
Normal file
104
scratch/check_booking_paging.go
Normal file
@@ -0,0 +1,104 @@
|
||||
//go:build ignore
|
||||
|
||||
// Read-only: does the console's page-by-page drain actually see every booking?
|
||||
//
|
||||
// GetAdminBookings runs Offset/Limit with NO ORDER BY. In Postgres that makes
|
||||
// the row order across pages unspecified, so a paged drain can legally return
|
||||
// the same row twice and never return another. This replays the exact 6 pages
|
||||
// the console fetches and compares the union against the table.
|
||||
//
|
||||
// go run scratch/check_booking_paging.go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"sort"
|
||||
|
||||
"doormile/config"
|
||||
"doormile/db"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
const pageSize = 100 // what the server actually returns: min(100, requested)
|
||||
|
||||
type row struct{ Bookingid int }
|
||||
|
||||
func main() {
|
||||
_ = godotenv.Load()
|
||||
cfg := config.Load()
|
||||
db.Connect(cfg)
|
||||
if db.DB == nil {
|
||||
log.Fatal("no DB connection")
|
||||
}
|
||||
|
||||
var total int64
|
||||
db.DB.Raw(`SELECT count(*) FROM pickupbookings`).Scan(&total)
|
||||
pages := int((total + pageSize - 1) / pageSize)
|
||||
fmt.Printf("bookings: %d, pages of %d: %d\n\n", total, pageSize, pages)
|
||||
|
||||
// The truth: every id that exists.
|
||||
var all []row
|
||||
db.DB.Raw(`SELECT bookingid FROM pickupbookings`).Scan(&all)
|
||||
truth := map[int]bool{}
|
||||
for _, r := range all {
|
||||
truth[r.Bookingid] = true
|
||||
}
|
||||
|
||||
// The drain, exactly as the console runs it — unordered Offset/Limit.
|
||||
seen := map[int]int{}
|
||||
for p := 0; p < pages; p++ {
|
||||
var page []row
|
||||
db.DB.Raw(`SELECT bookingid FROM pickupbookings LIMIT ? OFFSET ?`, pageSize, p*pageSize).Scan(&page)
|
||||
for _, r := range page {
|
||||
seen[r.Bookingid]++
|
||||
}
|
||||
fmt.Printf(" page %d: %d rows\n", p+1, len(page))
|
||||
}
|
||||
|
||||
missed := []int{}
|
||||
for id := range truth {
|
||||
if seen[id] == 0 {
|
||||
missed = append(missed, id)
|
||||
}
|
||||
}
|
||||
dupes := []int{}
|
||||
for id, n := range seen {
|
||||
if n > 1 {
|
||||
dupes = append(dupes, id)
|
||||
}
|
||||
}
|
||||
sort.Sort(sort.Reverse(sort.IntSlice(missed)))
|
||||
sort.Sort(sort.Reverse(sort.IntSlice(dupes)))
|
||||
|
||||
fmt.Printf("\nunordered drain saw %d distinct of %d\n", len(seen), len(truth))
|
||||
fmt.Printf(" MISSED %d: %v\n", len(missed), head(missed, 20))
|
||||
fmt.Printf(" DUPLICATED %d: %v\n", len(dupes), head(dupes, 20))
|
||||
|
||||
// The same drain with a deterministic order — the proposed fix.
|
||||
seenOrdered := map[int]int{}
|
||||
for p := 0; p < pages; p++ {
|
||||
var page []row
|
||||
db.DB.Raw(`SELECT bookingid FROM pickupbookings ORDER BY bookingid DESC LIMIT ? OFFSET ?`,
|
||||
pageSize, p*pageSize).Scan(&page)
|
||||
for _, r := range page {
|
||||
seenOrdered[r.Bookingid]++
|
||||
}
|
||||
}
|
||||
missedOrdered := 0
|
||||
for id := range truth {
|
||||
if seenOrdered[id] == 0 {
|
||||
missedOrdered++
|
||||
}
|
||||
}
|
||||
fmt.Printf("\nwith ORDER BY bookingid DESC: saw %d distinct, missed %d\n",
|
||||
len(seenOrdered), missedOrdered)
|
||||
}
|
||||
|
||||
func head(xs []int, n int) []int {
|
||||
if len(xs) > n {
|
||||
return xs[:n]
|
||||
}
|
||||
return xs
|
||||
}
|
||||
71
scratch/check_bookingno.go
Normal file
71
scratch/check_bookingno.go
Normal file
@@ -0,0 +1,71 @@
|
||||
//go:build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"doormile/config"
|
||||
"doormile/db"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_ = godotenv.Load()
|
||||
cfg := config.Load()
|
||||
db.Connect(cfg)
|
||||
if db.DB == nil {
|
||||
log.Fatal("no DB")
|
||||
}
|
||||
|
||||
fmt.Println("=== unique constraints on bookingno / trackingno ===")
|
||||
type c struct{ Conname, Def string }
|
||||
var cs []c
|
||||
db.DB.Raw(`SELECT c.conname, pg_get_constraintdef(c.oid) def
|
||||
FROM pg_constraint c JOIN pg_class t ON t.oid=c.conrelid
|
||||
WHERE t.relname IN ('pickupbookings','consignments') AND c.contype='u'`).Scan(&cs)
|
||||
if len(cs) == 0 {
|
||||
fmt.Println(" NONE — nothing stops a duplicate at the database level")
|
||||
}
|
||||
for _, x := range cs {
|
||||
fmt.Printf(" %s: %s\n", x.Conname, x.Def)
|
||||
}
|
||||
|
||||
fmt.Println("\n=== duplicate booking numbers ===")
|
||||
type d struct {
|
||||
Bookingno string
|
||||
N int64
|
||||
}
|
||||
var ds []d
|
||||
db.DB.Raw(`SELECT bookingno, count(*) n FROM pickupbookings
|
||||
GROUP BY 1 HAVING count(*)>1 ORDER BY n DESC LIMIT 10`).Scan(&ds)
|
||||
fmt.Printf(" %d duplicated\n", len(ds))
|
||||
for _, x := range ds {
|
||||
fmt.Printf(" %s x%d\n", x.Bookingno, x.N)
|
||||
}
|
||||
|
||||
fmt.Println("\n=== all-zero random part (would mean rand.Read failed) ===")
|
||||
var zeros int64
|
||||
db.DB.Raw(`SELECT count(*) FROM pickupbookings WHERE bookingno LIKE 'DM-BK-00000000-%'`).Scan(&zeros)
|
||||
fmt.Printf(" %d\n", zeros)
|
||||
|
||||
fmt.Println("\n=== how many bookings share a timestamp suffix ===")
|
||||
type s struct {
|
||||
Suffix string
|
||||
N int64
|
||||
}
|
||||
var ss []s
|
||||
db.DB.Raw(`SELECT split_part(bookingno,'-',4) suffix, count(*) n
|
||||
FROM pickupbookings GROUP BY 1 ORDER BY n DESC LIMIT 5`).Scan(&ss)
|
||||
for _, x := range ss {
|
||||
fmt.Printf(" suffix %-8s %d bookings\n", x.Suffix, x.N)
|
||||
}
|
||||
|
||||
fmt.Println("\n=== duplicate tracking numbers ===")
|
||||
var td []d
|
||||
db.DB.Raw(`SELECT trackingno bookingno, count(*) n FROM consignments
|
||||
GROUP BY 1 HAVING count(*)>1 LIMIT 5`).Scan(&td)
|
||||
fmt.Printf(" %d duplicated\n", len(td))
|
||||
}
|
||||
115
scratch/check_customer_bookings.go
Normal file
115
scratch/check_customer_bookings.go
Normal file
@@ -0,0 +1,115 @@
|
||||
//go:build ignore
|
||||
|
||||
// Read-only: why a customer-app booking may not reach the console.
|
||||
//
|
||||
// go run scratch/check_customer_bookings.go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"doormile/config"
|
||||
"doormile/db"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_ = godotenv.Load()
|
||||
cfg := config.Load()
|
||||
db.Connect(cfg)
|
||||
if db.DB == nil {
|
||||
log.Fatal("no DB connection")
|
||||
}
|
||||
|
||||
fmt.Println("=== 1. How many bookings exist, by source ===")
|
||||
type srcRow struct {
|
||||
Bookingsource string
|
||||
N int64
|
||||
}
|
||||
var srcs []srcRow
|
||||
db.DB.Raw(`SELECT COALESCE(NULLIF(bookingsource,''),'(blank)') AS bookingsource, count(*) AS n
|
||||
FROM pickupbookings GROUP BY 1 ORDER BY n DESC`).Scan(&srcs)
|
||||
var total int64
|
||||
for _, s := range srcs {
|
||||
fmt.Printf(" %-16s %d\n", s.Bookingsource, s.N)
|
||||
total += s.N
|
||||
}
|
||||
fmt.Printf(" %-16s %d\n", "TOTAL", total)
|
||||
|
||||
fmt.Println("\n=== 2. The 10 newest bookings ===")
|
||||
type bRow struct {
|
||||
Bookingid int
|
||||
Bookingno string
|
||||
Bookingsource string
|
||||
Status string
|
||||
Tenantid *int
|
||||
Pickuplatitude float64
|
||||
Pickuppincode string
|
||||
Createdat string
|
||||
}
|
||||
var newest []bRow
|
||||
db.DB.Raw(`SELECT bookingid, bookingno, bookingsource, status, tenantid,
|
||||
pickuplatitude, pickuppincode, createdat::text
|
||||
FROM pickupbookings ORDER BY bookingid DESC LIMIT 10`).Scan(&newest)
|
||||
for _, b := range newest {
|
||||
tenant := "NULL"
|
||||
if b.Tenantid != nil {
|
||||
tenant = fmt.Sprintf("%d", *b.Tenantid)
|
||||
}
|
||||
fmt.Printf(" #%-6d %-14s src=%-14s status=%-24s tenant=%-5s lat=%-10.4f pin=%-7s %s\n",
|
||||
b.Bookingid, b.Bookingno, b.Bookingsource, b.Status, tenant,
|
||||
b.Pickuplatitude, b.Pickuppincode, b.Createdat)
|
||||
}
|
||||
|
||||
fmt.Println("\n=== 3. Customer-app bookings specifically ===")
|
||||
var appBookings []bRow
|
||||
db.DB.Raw(`SELECT bookingid, bookingno, bookingsource, status, tenantid,
|
||||
pickuplatitude, pickuppincode, createdat::text
|
||||
FROM pickupbookings WHERE bookingsource = 'Customer_App'
|
||||
ORDER BY bookingid DESC LIMIT 10`).Scan(&appBookings)
|
||||
if len(appBookings) == 0 {
|
||||
fmt.Println(" none at all")
|
||||
}
|
||||
for _, b := range appBookings {
|
||||
fmt.Printf(" #%-6d %-14s status=%-24s lat=%-10.4f pin=%-7s %s\n",
|
||||
b.Bookingid, b.Bookingno, b.Status, b.Pickuplatitude, b.Pickuppincode, b.Createdat)
|
||||
}
|
||||
|
||||
fmt.Println("\n=== 4. Customer-app bookings with no pickup coordinates ===")
|
||||
var noCoords int64
|
||||
db.DB.Raw(`SELECT count(*) FROM pickupbookings
|
||||
WHERE bookingsource = 'Customer_App'
|
||||
AND (pickuplatitude = 0 OR pickuplongitude = 0
|
||||
OR pickuplatitude IS NULL OR pickuplongitude IS NULL)`).Scan(&noCoords)
|
||||
fmt.Printf(" %d (these cannot be assigned a rider and fail the console's zone filter)\n", noCoords)
|
||||
|
||||
fmt.Println("\n=== 5. What one page of the console's own query returns ===")
|
||||
// The console drains GET /admin/bookings, which runs no ORDER BY. This is
|
||||
// the same shape: LIMIT/OFFSET with no ordering.
|
||||
var page1, page1again []idRow
|
||||
db.DB.Raw(`SELECT bookingid FROM pickupbookings LIMIT 5 OFFSET 0`).Scan(&page1)
|
||||
db.DB.Raw(`SELECT bookingid FROM pickupbookings LIMIT 5 OFFSET 0`).Scan(&page1again)
|
||||
fmt.Printf(" unordered page 1, call A: %v\n", ids(page1))
|
||||
fmt.Printf(" unordered page 1, call B: %v\n", ids(page1again))
|
||||
|
||||
var lastPage []idRow
|
||||
offset := total - 5
|
||||
if offset < 0 {
|
||||
offset = 0
|
||||
}
|
||||
db.DB.Raw(fmt.Sprintf(`SELECT bookingid FROM pickupbookings LIMIT 5 OFFSET %d`, offset)).Scan(&lastPage)
|
||||
fmt.Printf(" unordered LAST page: %v\n", ids(lastPage))
|
||||
fmt.Println(" (if the newest ids appear only on the last page, a truncated drain never sees them)")
|
||||
}
|
||||
|
||||
type idRow struct{ Bookingid int }
|
||||
|
||||
func ids(rows []idRow) []int {
|
||||
out := make([]int, 0, len(rows))
|
||||
for _, r := range rows {
|
||||
out = append(out, r.Bookingid)
|
||||
}
|
||||
return out
|
||||
}
|
||||
136
scratch/check_handover_schema.go
Normal file
136
scratch/check_handover_schema.go
Normal file
@@ -0,0 +1,136 @@
|
||||
//go:build ignore
|
||||
|
||||
// Read-only verification for the base-handover work. Reads information_schema
|
||||
// and pg_constraint only — no writes, no DDL, no migrations.
|
||||
//
|
||||
// go run scratch/check_handover_schema.go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"doormile/config"
|
||||
"doormile/db"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_ = godotenv.Load()
|
||||
cfg := config.Load()
|
||||
db.Connect(cfg)
|
||||
if db.DB == nil {
|
||||
log.Fatal("no DB connection")
|
||||
}
|
||||
|
||||
fmt.Println("=== 1. New columns (expected ABSENT until AutoMigrate runs) ===")
|
||||
type col struct {
|
||||
Table string
|
||||
Name string
|
||||
}
|
||||
for _, want := range []col{
|
||||
{"pickupbookings", "pickupsourcetype"},
|
||||
{"pickupbookings", "pickuphubid"},
|
||||
{"consignments", "inwardedat"},
|
||||
} {
|
||||
var n int64
|
||||
db.DB.Raw(`SELECT count(*) FROM information_schema.columns
|
||||
WHERE table_name = ? AND column_name = ?`, want.Table, want.Name).Scan(&n)
|
||||
fmt.Printf(" %-16s %-18s present=%v\n", want.Table, want.Name, n > 0)
|
||||
}
|
||||
|
||||
fmt.Println("\n=== 2. CHECK constraints on the tables we write ===")
|
||||
type chk struct {
|
||||
Conname string
|
||||
Def string
|
||||
}
|
||||
var checks []chk
|
||||
db.DB.Raw(`SELECT c.conname, pg_get_constraintdef(c.oid) AS def
|
||||
FROM pg_constraint c JOIN pg_class t ON t.oid = c.conrelid
|
||||
WHERE c.contype = 'c'
|
||||
AND t.relname IN ('consignments','consignmentexceptions','consignmenthistory',
|
||||
'pickupbookings','bookingassignments','milerprofiles')
|
||||
ORDER BY t.relname, c.conname`).Scan(&checks)
|
||||
for _, c := range checks {
|
||||
fmt.Printf(" %s\n %s\n", c.Conname, c.Def)
|
||||
}
|
||||
|
||||
fmt.Println("\n=== 3. Foreign keys on the user/id columns we write ===")
|
||||
type fk struct {
|
||||
Table string
|
||||
Conname string
|
||||
Def string
|
||||
}
|
||||
var fks []fk
|
||||
db.DB.Raw(`SELECT t.relname AS table, c.conname, pg_get_constraintdef(c.oid) AS def
|
||||
FROM pg_constraint c JOIN pg_class t ON t.oid = c.conrelid
|
||||
WHERE c.contype = 'f'
|
||||
AND t.relname IN ('consignmentexceptions','consignmenthistory','consignments',
|
||||
'tripsheets','bookingassignments','pickupbookings')
|
||||
ORDER BY t.relname, c.conname`).Scan(&fks)
|
||||
if len(fks) == 0 {
|
||||
fmt.Println(" (none)")
|
||||
}
|
||||
for _, f := range fks {
|
||||
fmt.Printf(" %-24s %s\n", f.Table, f.Def)
|
||||
}
|
||||
|
||||
fmt.Println("\n=== 4. NOT NULL columns on the tables we insert into ===")
|
||||
type nn struct {
|
||||
Table string
|
||||
Column string
|
||||
Def *string
|
||||
}
|
||||
var nns []nn
|
||||
db.DB.Raw(`SELECT table_name AS table, column_name AS column, column_default AS def
|
||||
FROM information_schema.columns
|
||||
WHERE table_name IN ('consignmentexceptions','consignmenthistory')
|
||||
AND is_nullable = 'NO'
|
||||
ORDER BY table_name, ordinal_position`).Scan(&nns)
|
||||
for _, c := range nns {
|
||||
d := "(no default)"
|
||||
if c.Def != nil {
|
||||
d = *c.Def
|
||||
}
|
||||
fmt.Printf(" %-24s %-20s %s\n", c.Table, c.Column, d)
|
||||
}
|
||||
|
||||
fmt.Println("\n=== 5. Hub master data completeness (request 29) ===")
|
||||
type hubRow struct {
|
||||
Total int64
|
||||
NoAddress int64
|
||||
NoPincode int64
|
||||
NoCoords int64
|
||||
ActiveTotal int64
|
||||
}
|
||||
var h hubRow
|
||||
db.DB.Raw(`SELECT count(*) AS total,
|
||||
count(*) FILTER (WHERE address IS NULL OR address = '') AS no_address,
|
||||
count(*) FILTER (WHERE pincode IS NULL OR pincode = '') AS no_pincode,
|
||||
count(*) FILTER (WHERE latitude IS NULL OR latitude = 0 OR longitude IS NULL OR longitude = 0) AS no_coords,
|
||||
count(*) FILTER (WHERE status = 'Active') AS active_total
|
||||
FROM hubs WHERE deletedat IS NULL`).Scan(&h)
|
||||
fmt.Printf(" hubs=%d active=%d missing_address=%d missing_pincode=%d missing_coords=%d\n",
|
||||
h.Total, h.ActiveTotal, h.NoAddress, h.NoPincode, h.NoCoords)
|
||||
|
||||
fmt.Println("\n=== 6. Consignment status distribution (what is live now) ===")
|
||||
type sc struct {
|
||||
Status string
|
||||
N int64
|
||||
}
|
||||
var scs []sc
|
||||
db.DB.Raw(`SELECT status, count(*) AS n FROM consignments
|
||||
WHERE deletedat IS NULL GROUP BY status ORDER BY n DESC`).Scan(&scs)
|
||||
for _, s := range scs {
|
||||
fmt.Printf(" %-22s %d\n", s.Status, s.N)
|
||||
}
|
||||
|
||||
fmt.Println("\n=== 7. Open assignments on already-converted bookings (the off-duty bug) ===")
|
||||
var stuck int64
|
||||
db.DB.Raw(`SELECT count(*) FROM bookingassignments a
|
||||
JOIN pickupbookings b ON b.bookingid = a.bookingid
|
||||
WHERE a.assignmentstatus IN ('Assigned','Accepted')
|
||||
AND b.status = 'Converted_To_Consignment'`).Scan(&stuck)
|
||||
fmt.Printf(" assignments still open on a converted booking: %d\n", stuck)
|
||||
}
|
||||
62
scratch/check_latest.go
Normal file
62
scratch/check_latest.go
Normal file
@@ -0,0 +1,62 @@
|
||||
//go:build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"doormile/config"
|
||||
"doormile/db"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_ = godotenv.Load()
|
||||
cfg := config.Load()
|
||||
db.Connect(cfg)
|
||||
if db.DB == nil {
|
||||
log.Fatal("no DB")
|
||||
}
|
||||
type b struct {
|
||||
Bookingid int
|
||||
Bookingno string
|
||||
Bookingsource string
|
||||
Status string
|
||||
Tenantid *int
|
||||
Appcustomerid int
|
||||
Pickuppincode string
|
||||
Pickuplatitude float64
|
||||
Createdat string
|
||||
}
|
||||
var rows []b
|
||||
db.DB.Raw(`SELECT bookingid,bookingno,bookingsource,status,tenantid,appcustomerid,
|
||||
pickuppincode,pickuplatitude,createdat::text
|
||||
FROM pickupbookings ORDER BY bookingid DESC LIMIT 12`).Scan(&rows)
|
||||
fmt.Println("=== 12 newest bookings (any source) ===")
|
||||
for _, r := range rows {
|
||||
tn := "NULL"
|
||||
if r.Tenantid != nil {
|
||||
tn = fmt.Sprint(*r.Tenantid)
|
||||
}
|
||||
fmt.Printf(" #%-5d src=%-13q status=%-24s tenant=%-5s cust=%-4d pin=%-7s lat=%.4f %s\n",
|
||||
r.Bookingid, r.Bookingsource, r.Status, tn, r.Appcustomerid,
|
||||
r.Pickuppincode, r.Pickuplatitude, r.Createdat)
|
||||
}
|
||||
|
||||
fmt.Println("\n=== exact distinct bookingsource values (byte-for-byte) ===")
|
||||
type s struct {
|
||||
V string
|
||||
N int64
|
||||
}
|
||||
var ss []s
|
||||
db.DB.Raw(`SELECT '['||bookingsource||']' v, count(*) n FROM pickupbookings GROUP BY 1 ORDER BY n DESC`).Scan(&ss)
|
||||
for _, x := range ss {
|
||||
fmt.Printf(" %-20s %d\n", x.V, x.N)
|
||||
}
|
||||
|
||||
var appTotal int64
|
||||
db.DB.Raw(`SELECT count(*) FROM pickupbookings WHERE bookingsource='Customer_App'`).Scan(&appTotal)
|
||||
fmt.Printf("\nCustomer_App bookings the console page should list: %d\n", appTotal)
|
||||
}
|
||||
37
scratch/check_miler23.go
Normal file
37
scratch/check_miler23.go
Normal file
@@ -0,0 +1,37 @@
|
||||
//go:build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"doormile/config"
|
||||
"doormile/db"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_ = godotenv.Load()
|
||||
cfg := config.Load()
|
||||
db.Connect(cfg)
|
||||
if db.DB == nil {
|
||||
log.Fatal("no DB")
|
||||
}
|
||||
var avail string
|
||||
db.DB.Raw(`SELECT availabilitystatus FROM milerprofiles WHERE userid = 23`).Scan(&avail)
|
||||
fmt.Printf("miler 23 availability: %s\n", avail)
|
||||
|
||||
var open int64
|
||||
db.DB.Raw(`SELECT count(*) FROM bookingassignments ba
|
||||
JOIN pickupbookings b ON b.bookingid = ba.bookingid
|
||||
WHERE ba.mileruserid = 23 AND ba.assignmentstatus IN ('Assigned','Accepted')`).Scan(&open)
|
||||
fmt.Printf("miler 23 open assignments: %d\n", open)
|
||||
|
||||
var onCancelled int64
|
||||
db.DB.Raw(`SELECT count(*) FROM bookingassignments ba
|
||||
JOIN pickupbookings b ON b.bookingid = ba.bookingid
|
||||
WHERE ba.assignmentstatus IN ('Assigned','Accepted') AND b.status = 'Cancelled'`).Scan(&onCancelled)
|
||||
fmt.Printf("\nACROSS ALL RIDERS — open assignments on a CANCELLED booking: %d\n", onCancelled)
|
||||
}
|
||||
38
scratch/check_phone.go
Normal file
38
scratch/check_phone.go
Normal file
@@ -0,0 +1,38 @@
|
||||
//go:build ignore
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"doormile/config"
|
||||
"doormile/db"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_ = godotenv.Load()
|
||||
cfg := config.Load()
|
||||
db.Connect(cfg)
|
||||
if db.DB == nil {
|
||||
log.Fatal("no DB")
|
||||
}
|
||||
type c struct {
|
||||
Appcustomerid int
|
||||
Firstname string
|
||||
Phone string
|
||||
Configid int
|
||||
Status string
|
||||
}
|
||||
var rows []c
|
||||
db.DB.Raw(`SELECT appcustomerid,firstname,phone,configid,status FROM appcustomers
|
||||
WHERE phone IN ('9876543210') OR appcustomerid = 5`).Scan(&rows)
|
||||
if len(rows) == 0 {
|
||||
fmt.Println("no appcustomer with phone 9876543210, and no id 5")
|
||||
}
|
||||
for _, r := range rows {
|
||||
fmt.Printf(" id=%d name=%q phone=%s configid=%d status=%s\n",
|
||||
r.Appcustomerid, r.Firstname, r.Phone, r.Configid, r.Status)
|
||||
}
|
||||
}
|
||||
80
scratch/check_two_bookings.go
Normal file
80
scratch/check_two_bookings.go
Normal file
@@ -0,0 +1,80 @@
|
||||
//go:build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"doormile/config"
|
||||
"doormile/db"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_ = godotenv.Load()
|
||||
cfg := config.Load()
|
||||
db.Connect(cfg)
|
||||
if db.DB == nil {
|
||||
log.Fatal("no DB")
|
||||
}
|
||||
|
||||
type b struct {
|
||||
Bookingid int
|
||||
Bookingno string
|
||||
Status string
|
||||
Createdat string
|
||||
Updatedat string
|
||||
Assignedmileruserid *int
|
||||
Pickuplatitude float64
|
||||
Pickuplongitude float64
|
||||
Pickuppincode string
|
||||
Deliverypincode string
|
||||
Deliveryaddress string
|
||||
Appcustomerid int
|
||||
}
|
||||
var rows []b
|
||||
db.DB.Raw(`SELECT bookingid, bookingno, status, createdat::text, updatedat::text,
|
||||
assignedmileruserid, pickuplatitude, pickuplongitude, pickuppincode,
|
||||
deliverypincode, deliveryaddress, appcustomerid
|
||||
FROM pickupbookings WHERE bookingid IN (546,547,179) ORDER BY bookingid DESC`).Scan(&rows)
|
||||
for _, r := range rows {
|
||||
miler := "none"
|
||||
if r.Assignedmileruserid != nil {
|
||||
miler = fmt.Sprintf("%d", *r.Assignedmileruserid)
|
||||
}
|
||||
fmt.Printf("#%d %s\n status=%s created=%s\n updated=%s miler=%s customer=%d\n pickup=(%.4f,%.4f) %s -> %s drop=%q\n\n",
|
||||
r.Bookingid, r.Bookingno, r.Status, r.Createdat, r.Updatedat, miler,
|
||||
r.Appcustomerid, r.Pickuplatitude, r.Pickuplongitude, r.Pickuppincode,
|
||||
r.Deliverypincode, r.Deliveryaddress)
|
||||
}
|
||||
|
||||
fmt.Println("=== assignments on those bookings ===")
|
||||
type a struct {
|
||||
Bookingid int
|
||||
Assignmentstatus string
|
||||
Assignedat string
|
||||
Remarks string
|
||||
}
|
||||
var as []a
|
||||
db.DB.Raw(`SELECT bookingid, assignmentstatus, assignedat::text, remarks
|
||||
FROM bookingassignments WHERE bookingid IN (546,547,179)`).Scan(&as)
|
||||
if len(as) == 0 {
|
||||
fmt.Println(" none — no rider was ever assigned")
|
||||
}
|
||||
for _, x := range as {
|
||||
fmt.Printf(" booking %d: %s at %s %q\n", x.Bookingid, x.Assignmentstatus, x.Assignedat, x.Remarks)
|
||||
}
|
||||
|
||||
fmt.Println("\n=== how many bookings sit in each status ===")
|
||||
type s struct {
|
||||
Status string
|
||||
N int64
|
||||
}
|
||||
var ss []s
|
||||
db.DB.Raw(`SELECT status, count(*) n FROM pickupbookings GROUP BY 1 ORDER BY n DESC`).Scan(&ss)
|
||||
for _, x := range ss {
|
||||
fmt.Printf(" %-26s %d\n", x.Status, x.N)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user