feat: miler delivery-leg fixes — consignmentid, auto route sequencing, admin consignment status
Miler app P0 + contract gaps found in the live audit: - GET /miler/bookings now returns consignmentid + consignmentstatus on every row (nullable), so the app can call deliver/skip/start-delivery straight from the list. /miler/assignments is the active-only queue, so this is the authoritative fix for stops that have moved onto the delivery leg. - GET /miler/bookings now returns sequencedat per row: non-null means the console/optimizer fixed this stop's order and the app follows step exactly; null means no route assigned and the app may fall back to nearest-first. - Route sequencing (internal/routing) now runs automatically after every assignment — customer auto-assign, express auto-assign, manual assign, and accept — via SequenceMilerStopsAsync (fire-and-forget, no-op below two active stops). Previously only hub batch-assign sequenced, so most riders saw step=0. - GET /admin/bookings now surfaces the live consignmentstatus alongside the frozen booking status, so a Converted_To_Consignment booking can still show Out_for_Delivery / Delivered instead of a generic "Active". Two-step hyperlocal flow (Arrived_At_Pickup, Collected_By_Miler, start-delivery) stays gated behind MILER_COLLECTED_STATE_ENABLED (default off) until the app ships; consignmentid/status, GET /miler/consignments/:id, stable error codes and Idempotency-Key handling are unconditional and safe on the current app. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WRaFH5hMRqmUQvVPQsyjZD
This commit is contained in:
@@ -2086,6 +2086,32 @@ func GetAdminBookings(c *fiber.Ctx) error {
|
||||
return utils.Internal(c, "failed to fetch bookings")
|
||||
}
|
||||
|
||||
// Surface the live consignment status next to the booking. Once a booking is
|
||||
// picked up its own status stops moving (it sits at Converted_To_Consignment),
|
||||
// while the parcel keeps advancing on the consignment — Out_for_Delivery,
|
||||
// Delivered. Without this the console can only show the frozen booking status
|
||||
// and a collected order reads as a generic "Active". Batched: one IN query for
|
||||
// the whole page, not one per row.
|
||||
consignmentIDs := make([]int, 0, len(bookings))
|
||||
for _, b := range bookings {
|
||||
if b.Consignmentid != nil {
|
||||
consignmentIDs = append(consignmentIDs, *b.Consignmentid)
|
||||
}
|
||||
}
|
||||
if len(consignmentIDs) > 0 {
|
||||
var consignments []models.Consignment
|
||||
db.DB.Select("consignmentid, status").Where("consignmentid IN ?", consignmentIDs).Find(&consignments)
|
||||
statusByConsignment := make(map[int]string, len(consignments))
|
||||
for _, cn := range consignments {
|
||||
statusByConsignment[cn.Consignmentid] = cn.Status
|
||||
}
|
||||
for i := range bookings {
|
||||
if bookings[i].Consignmentid != nil {
|
||||
bookings[i].Consignmentstatus = statusByConsignment[*bookings[i].Consignmentid]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pages := int(math.Ceil(float64(total) / float64(pagesize)))
|
||||
|
||||
return c.JSON(fiber.Map{
|
||||
|
||||
Reference in New Issue
Block a user