hub apis
This commit is contained in:
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"doormile/constants"
|
||||
@@ -74,7 +73,7 @@ func AssignCRMMiler(bookingID int) {
|
||||
// Returns (false, err) on hard errors (booking missing, DB failure).
|
||||
func tryAssign(bookingID int) (bool, error) {
|
||||
var booking models.PickupBooking
|
||||
if err := db.DB.First(&booking, bookingID).Error; err != nil {
|
||||
if err := db.DB.Preload("Parcels").Preload("ServiceOptions").First(&booking, bookingID).Error; err != nil {
|
||||
return false, fmt.Errorf("load booking: %w", err)
|
||||
}
|
||||
|
||||
@@ -100,12 +99,12 @@ func tryAssign(bookingID int) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
candidate, found := pickBestMiler(nearby)
|
||||
candidate, agentDecisionID, found := selectMilerWithAI(&booking, nearby)
|
||||
if !found {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if err := commitAssignment(&booking, candidate); err != nil {
|
||||
if err := commitAssignment(&booking, candidate, agentDecisionID); err != nil {
|
||||
return false, fmt.Errorf("commit: %w", err)
|
||||
}
|
||||
|
||||
@@ -140,58 +139,9 @@ func queryNearbyMilers(lat, lon float64) ([]redis.GeoLocation, error) {
|
||||
return locs, nil
|
||||
}
|
||||
|
||||
// pickBestMiler filters the nearby list for eligibility, then returns the candidate
|
||||
// with the lowest score. score = distance_km*1.0 + active_bookings*2.0 - rating*0.5
|
||||
func pickBestMiler(nearby []redis.GeoLocation) (*milerCandidate, bool) {
|
||||
var best *milerCandidate
|
||||
bestScore := 1e18
|
||||
|
||||
for _, loc := range nearby {
|
||||
milerUserID, err := strconv.Atoi(loc.Name)
|
||||
if err != nil {
|
||||
utils.Warn("CRMAssignment: skipping non-numeric GEO member", "name", loc.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
var profile models.MilerProfile
|
||||
if err := db.DB.Where("userid = ?", milerUserID).First(&profile).Error; err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if profile.Availabilitystatus != constants.MilerAvailable {
|
||||
continue
|
||||
}
|
||||
|
||||
var activeCount int64
|
||||
db.DB.Model(&models.BookingAssignment{}).
|
||||
Where("mileruserid = ? AND assignmentstatus IN ?", milerUserID, []string{
|
||||
constants.AssignmentAssigned,
|
||||
constants.AssignmentAccepted,
|
||||
}).
|
||||
Count(&activeCount)
|
||||
|
||||
if activeCount >= maxActive {
|
||||
continue
|
||||
}
|
||||
|
||||
score := loc.Dist*1.0 + float64(activeCount)*2.0 - profile.Rating*0.5
|
||||
|
||||
if score < bestScore {
|
||||
bestScore = score
|
||||
best = &milerCandidate{
|
||||
profile: profile,
|
||||
distanceKm: loc.Dist,
|
||||
activeBookings: activeCount,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return best, best != nil
|
||||
}
|
||||
|
||||
// commitAssignment writes the BookingAssignment row, updates the booking and the
|
||||
// miler's availability status in a single transaction, then publishes to NATS.
|
||||
func commitAssignment(booking *models.PickupBooking, candidate *milerCandidate) error {
|
||||
func commitAssignment(booking *models.PickupBooking, candidate *milerCandidate, agentDecisionID *uint64) error {
|
||||
milerUserID := candidate.profile.Userid
|
||||
|
||||
tx := db.DB.Begin()
|
||||
@@ -201,6 +151,7 @@ func commitAssignment(booking *models.PickupBooking, candidate *milerCandidate)
|
||||
Mileruserid: milerUserID,
|
||||
Assignmentstatus: constants.AssignmentAssigned,
|
||||
Assignedat: time.Now(),
|
||||
AgentDecisionID: agentDecisionID,
|
||||
}
|
||||
if err := tx.Create(&assignment).Error; err != nil {
|
||||
tx.Rollback()
|
||||
@@ -231,7 +182,7 @@ func commitAssignment(booking *models.PickupBooking, candidate *milerCandidate)
|
||||
"miler_id", milerUserID,
|
||||
"distance_km", candidate.distanceKm,
|
||||
"active_bookings", candidate.activeBookings,
|
||||
"score", candidate.distanceKm*1.0+float64(candidate.activeBookings)*2.0-candidate.profile.Rating*0.5,
|
||||
"agent_decision_id", agentDecisionID,
|
||||
)
|
||||
|
||||
publishAssignment(booking, milerUserID)
|
||||
|
||||
Reference in New Issue
Block a user