85 lines
2.6 KiB
Go
85 lines
2.6 KiB
Go
package controllers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
"doormile/constants"
|
|
"doormile/db"
|
|
"doormile/internal/notify"
|
|
"doormile/models"
|
|
"doormile/utils"
|
|
)
|
|
|
|
// AssignMilerToBooking is the single source of truth for manually assigning a
|
|
// miler to a pickup booking — shared by the admin console (AdminAssignMiler)
|
|
// and the hub console (HubAssignMiler) so both go through identical DB
|
|
// updates, NATS publish, and FCM notify instead of duplicating the logic.
|
|
func AssignMilerToBooking(bookingID, milerUserID int, assignedByUserID *int) (*models.PickupBooking, error) {
|
|
tx := db.DB.Begin()
|
|
|
|
var booking models.PickupBooking
|
|
if err := tx.First(&booking, bookingID).Error; err != nil {
|
|
tx.Rollback()
|
|
return nil, fmt.Errorf("booking not found")
|
|
}
|
|
|
|
booking.Status = constants.BookingMilerAssigned
|
|
booking.Assignedmileruserid = &milerUserID
|
|
booking.Updatedat = time.Now()
|
|
if err := tx.Save(&booking).Error; err != nil {
|
|
tx.Rollback()
|
|
return nil, fmt.Errorf("failed to update booking: %w", err)
|
|
}
|
|
|
|
assignment := models.BookingAssignment{
|
|
Bookingid: booking.Bookingid,
|
|
Mileruserid: milerUserID,
|
|
Assignedbyuserid: assignedByUserID,
|
|
Assignmentstatus: constants.AssignmentAssigned,
|
|
}
|
|
if err := tx.Create(&assignment).Error; err != nil {
|
|
tx.Rollback()
|
|
return nil, fmt.Errorf("failed to create assignment: %w", err)
|
|
}
|
|
|
|
if err := tx.Model(&models.MilerProfile{}).Where("userid = ?", milerUserID).
|
|
Update("availabilitystatus", constants.MilerAssigned).Error; err != nil {
|
|
tx.Rollback()
|
|
return nil, fmt.Errorf("failed to update miler availability: %w", err)
|
|
}
|
|
|
|
tx.Commit()
|
|
|
|
if db.Js != nil {
|
|
payload := map[string]interface{}{
|
|
"booking_id": booking.Bookingid,
|
|
"booking_no": booking.Bookingno,
|
|
"status": booking.Status,
|
|
"miler_id": milerUserID,
|
|
"updated_at": time.Now().UnixMilli(),
|
|
}
|
|
if data, err := json.Marshal(payload); err == nil {
|
|
if _, err := db.Js.Publish("api.v1.bookings.update", data); err != nil {
|
|
utils.Warn("Failed to publish booking.update to NATS", "booking_id", booking.Bookingid, "error", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
var miler models.MilerProfile
|
|
if db.DB.Where("userid = ?", milerUserID).First(&miler).Error == nil && miler.Devicetoken != "" {
|
|
if err := notify.SendToDevice(
|
|
miler.Devicetoken,
|
|
"New Pickup Assigned",
|
|
"New booking assigned — tap to view details",
|
|
map[string]string{"booking_id": fmt.Sprintf("%d", booking.Bookingid)},
|
|
); err != nil {
|
|
utils.Warn("FCM: failed to notify miler on manual assignment",
|
|
"miler_id", milerUserID, "booking_id", booking.Bookingid, "error", err)
|
|
}
|
|
}
|
|
|
|
return &booking, nil
|
|
}
|