lot of new functionalities
This commit is contained in:
600
core/application/vehicles-management.go
Executable file
600
core/application/vehicles-management.go
Executable file
@@ -0,0 +1,600 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"git.coopgo.io/coopgo-apps/parcoursmob/core/utils/identification"
|
||||
"git.coopgo.io/coopgo-apps/parcoursmob/core/utils/sorting"
|
||||
filestorage "git.coopgo.io/coopgo-apps/parcoursmob/core/utils/storage"
|
||||
fleets "git.coopgo.io/coopgo-platform/fleets/grpcapi"
|
||||
fleetsstorage "git.coopgo.io/coopgo-platform/fleets/storage"
|
||||
groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi"
|
||||
"git.coopgo.io/coopgo-platform/groups-management/storage"
|
||||
mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
|
||||
mobilityaccountsstorage "git.coopgo.io/coopgo-platform/mobility-accounts/storage"
|
||||
"github.com/google/uuid"
|
||||
"github.com/rs/zerolog/log"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
type VehiclesManagementOverviewResult struct {
|
||||
Vehicles []fleetsstorage.Vehicle
|
||||
VehiclesMap map[string]fleetsstorage.Vehicle
|
||||
DriversMap map[string]mobilityaccountsstorage.Account
|
||||
Bookings []fleetsstorage.Booking
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) GetVehiclesManagementOverview(ctx context.Context, groupID string) (*VehiclesManagementOverviewResult, error) {
|
||||
request := &fleets.GetVehiclesRequest{
|
||||
Namespaces: []string{"parcoursmob"},
|
||||
}
|
||||
resp, err := h.services.GRPC.Fleets.GetVehicles(ctx, request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get vehicles: %w", err)
|
||||
}
|
||||
|
||||
vehicles := []fleetsstorage.Vehicle{}
|
||||
bookings := []fleetsstorage.Booking{}
|
||||
vehiclesMap := map[string]fleetsstorage.Vehicle{}
|
||||
|
||||
for _, vehicle := range resp.Vehicles {
|
||||
if h.filterVehicleByGroup(vehicle, groupID) {
|
||||
v := vehicle.ToStorageType()
|
||||
vehicleBookings := []fleetsstorage.Booking{}
|
||||
for _, b := range v.Bookings {
|
||||
log.Debug().Any("booking", b).Msg("debug")
|
||||
if b.Status() != fleetsstorage.StatusOld {
|
||||
if !b.Deleted {
|
||||
bookings = append(bookings, b)
|
||||
}
|
||||
}
|
||||
if b.Unavailableto.After(time.Now()) {
|
||||
vehicleBookings = append(vehicleBookings, b)
|
||||
}
|
||||
}
|
||||
v.Bookings = vehicleBookings
|
||||
vehicles = append(vehicles, v)
|
||||
vehiclesMap[v.ID] = v
|
||||
}
|
||||
}
|
||||
|
||||
driversMap, _ := h.services.GetBeneficiariesMap()
|
||||
|
||||
sort.Sort(sorting.VehiclesByLicencePlate(vehicles))
|
||||
sort.Sort(sorting.BookingsByStartdate(bookings))
|
||||
|
||||
return &VehiclesManagementOverviewResult{
|
||||
Vehicles: vehicles,
|
||||
VehiclesMap: vehiclesMap,
|
||||
DriversMap: driversMap,
|
||||
Bookings: bookings,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) filterVehicleByGroup(v *fleets.Vehicle, groupID string) bool {
|
||||
if groupID == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, n := range v.Administrators {
|
||||
if n == groupID {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type VehiclesManagementBookingsListResult struct {
|
||||
VehiclesMap map[string]fleetsstorage.Vehicle
|
||||
DriversMap map[string]mobilityaccountsstorage.Account
|
||||
Bookings []fleetsstorage.Booking
|
||||
CacheID string
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) GetVehiclesManagementBookingsList(ctx context.Context, groupID, status, startDate, endDate string) (*VehiclesManagementBookingsListResult, error) {
|
||||
request := &fleets.GetVehiclesRequest{
|
||||
Namespaces: []string{"parcoursmob"},
|
||||
IncludeDeleted: true,
|
||||
}
|
||||
resp, err := h.services.GRPC.Fleets.GetVehicles(ctx, request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get vehicles: %w", err)
|
||||
}
|
||||
|
||||
bookings := []fleetsstorage.Booking{}
|
||||
vehiclesMap := map[string]fleetsstorage.Vehicle{}
|
||||
|
||||
// Parse start date filter
|
||||
var startdate time.Time
|
||||
if startDate != "" {
|
||||
if parsed, err := time.Parse("2006-01-02", startDate); err == nil {
|
||||
startdate = parsed
|
||||
}
|
||||
}
|
||||
|
||||
// Parse end date filter
|
||||
var enddate time.Time
|
||||
if endDate != "" {
|
||||
if parsed, err := time.Parse("2006-01-02", endDate); err == nil {
|
||||
enddate = parsed.Add(24 * time.Hour) // End of day
|
||||
}
|
||||
}
|
||||
|
||||
for _, vehicle := range resp.Vehicles {
|
||||
if h.filterVehicleByGroup(vehicle, groupID) {
|
||||
v := vehicle.ToStorageType()
|
||||
vehiclesMap[v.ID] = v
|
||||
for _, b := range v.Bookings {
|
||||
if v, ok := b.Data["administrator_unavailability"].(bool); !ok || !v {
|
||||
// Apply status filter
|
||||
if status != "" {
|
||||
bookingStatus := b.Status()
|
||||
statusInt := 0
|
||||
|
||||
if b.Deleted {
|
||||
statusInt = -2 // Use -2 for cancelled to distinguish from terminated
|
||||
} else {
|
||||
statusInt = bookingStatus
|
||||
}
|
||||
|
||||
// Map status string to int
|
||||
var filterStatusInt int
|
||||
switch status {
|
||||
case "FORTHCOMING":
|
||||
filterStatusInt = 1
|
||||
case "ONGOING":
|
||||
filterStatusInt = 0
|
||||
case "TERMINATED":
|
||||
filterStatusInt = -1
|
||||
case "CANCELLED":
|
||||
filterStatusInt = -2
|
||||
default:
|
||||
filterStatusInt = 999 // Invalid status, won't match anything
|
||||
}
|
||||
|
||||
if statusInt != filterStatusInt {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Apply date filter (on startdate)
|
||||
if !startdate.IsZero() && b.Startdate.Before(startdate) {
|
||||
continue
|
||||
}
|
||||
if !enddate.IsZero() && b.Startdate.After(enddate) {
|
||||
continue
|
||||
}
|
||||
|
||||
bookings = append(bookings, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sort.Sort(sorting.BookingsByStartdate(bookings))
|
||||
|
||||
cacheID := uuid.NewString()
|
||||
h.cache.PutWithTTL(cacheID, bookings, 1*time.Hour)
|
||||
|
||||
driversMap, _ := h.services.GetBeneficiariesMap()
|
||||
|
||||
return &VehiclesManagementBookingsListResult{
|
||||
VehiclesMap: vehiclesMap,
|
||||
DriversMap: driversMap,
|
||||
Bookings: bookings,
|
||||
CacheID: cacheID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) CreateVehicle(ctx context.Context, name, vehicleType, informations, licencePlate, kilometers string, automatic bool, address map[string]any, otherProperties map[string]any) (string, error) {
|
||||
g := ctx.Value(identification.GroupKey)
|
||||
if g == nil {
|
||||
return "", fmt.Errorf("no group found in context")
|
||||
}
|
||||
group := g.(storage.Group)
|
||||
|
||||
dataMap := map[string]any{}
|
||||
if name != "" {
|
||||
dataMap["name"] = name
|
||||
}
|
||||
if address != nil {
|
||||
dataMap["address"] = address
|
||||
}
|
||||
if informations != "" {
|
||||
dataMap["informations"] = informations
|
||||
}
|
||||
if licencePlate != "" {
|
||||
dataMap["licence_plate"] = licencePlate
|
||||
}
|
||||
dataMap["automatic"] = automatic
|
||||
if kilometers != "" {
|
||||
dataMap["kilometers"] = kilometers
|
||||
}
|
||||
// Add other properties
|
||||
for key, value := range otherProperties {
|
||||
dataMap[key] = value
|
||||
}
|
||||
|
||||
data, err := structpb.NewValue(dataMap)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create data struct: %w", err)
|
||||
}
|
||||
|
||||
vehicle := &fleets.Vehicle{
|
||||
Id: uuid.NewString(),
|
||||
Namespace: "parcoursmob",
|
||||
Type: vehicleType,
|
||||
Administrators: []string{group.ID},
|
||||
Data: data.GetStructValue(),
|
||||
}
|
||||
|
||||
request := &fleets.AddVehicleRequest{
|
||||
Vehicle: vehicle,
|
||||
}
|
||||
|
||||
_, err = h.services.GRPC.Fleets.AddVehicle(ctx, request)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to add vehicle: %w", err)
|
||||
}
|
||||
|
||||
return vehicle.Id, nil
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) GetVehicleTypes(ctx context.Context) ([]string, error) {
|
||||
return h.config.GetStringSlice("modules.fleets.vehicle_types"), nil
|
||||
}
|
||||
|
||||
type VehicleDisplayResult struct {
|
||||
Vehicle fleetsstorage.Vehicle
|
||||
Beneficiaries map[string]mobilityaccountsstorage.Account
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) GetVehicleDisplay(ctx context.Context, vehicleID string) (*VehicleDisplayResult, error) {
|
||||
request := &fleets.GetVehicleRequest{
|
||||
Vehicleid: vehicleID,
|
||||
}
|
||||
|
||||
resp, err := h.services.GRPC.Fleets.GetVehicle(ctx, request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get vehicle: %w", err)
|
||||
}
|
||||
|
||||
beneficiaries, err := h.services.GetBeneficiariesMap()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get beneficiaries: %w", err)
|
||||
}
|
||||
|
||||
vehicle := resp.Vehicle.ToStorageType()
|
||||
|
||||
// Sort bookings by start date (most recent first)
|
||||
sort.Slice(vehicle.Bookings, func(i, j int) bool {
|
||||
return vehicle.Bookings[i].Startdate.After(vehicle.Bookings[j].Startdate)
|
||||
})
|
||||
|
||||
return &VehicleDisplayResult{
|
||||
Vehicle: vehicle,
|
||||
Beneficiaries: beneficiaries,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) UpdateBooking(ctx context.Context, bookingID, startdate, enddate, unavailablefrom, unavailableto string) error {
|
||||
booking, err := h.services.GetBooking(bookingID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get booking: %w", err)
|
||||
}
|
||||
|
||||
newbooking, _ := fleets.BookingFromStorageType(&booking)
|
||||
|
||||
if startdate != "" {
|
||||
newstartdate, _ := time.Parse("2006-01-02", startdate)
|
||||
newbooking.Startdate = timestamppb.New(newstartdate)
|
||||
|
||||
if newstartdate.Before(newbooking.Unavailablefrom.AsTime()) {
|
||||
newbooking.Unavailablefrom = timestamppb.New(newstartdate)
|
||||
}
|
||||
}
|
||||
|
||||
if enddate != "" {
|
||||
newenddate, _ := time.Parse("2006-01-02", enddate)
|
||||
newbooking.Enddate = timestamppb.New(newenddate)
|
||||
|
||||
if newenddate.After(newbooking.Unavailableto.AsTime()) || newenddate.Equal(newbooking.Unavailableto.AsTime()) {
|
||||
newbooking.Unavailableto = timestamppb.New(newenddate.Add(24 * time.Hour))
|
||||
}
|
||||
}
|
||||
|
||||
if unavailablefrom != "" {
|
||||
newunavailablefrom, _ := time.Parse("2006-01-02", unavailablefrom)
|
||||
newbooking.Unavailablefrom = timestamppb.New(newunavailablefrom)
|
||||
}
|
||||
|
||||
if unavailableto != "" {
|
||||
newunavailableto, _ := time.Parse("2006-01-02", unavailableto)
|
||||
newbooking.Unavailableto = timestamppb.New(newunavailableto)
|
||||
}
|
||||
|
||||
request := &fleets.UpdateBookingRequest{
|
||||
Booking: newbooking,
|
||||
}
|
||||
|
||||
_, err = h.services.GRPC.Fleets.UpdateBooking(ctx, request)
|
||||
return err
|
||||
}
|
||||
|
||||
type BookingDisplayResult struct {
|
||||
Booking fleetsstorage.Booking
|
||||
Vehicle fleetsstorage.Vehicle
|
||||
Beneficiary mobilityaccountsstorage.Account
|
||||
Group storage.Group
|
||||
Documents []filestorage.FileInfo
|
||||
FileTypesMap map[string]string
|
||||
Alternatives []any
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) GetBookingDisplay(ctx context.Context, bookingID string) (*BookingDisplayResult, error) {
|
||||
booking, err := h.services.GetBooking(bookingID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get booking: %w", err)
|
||||
}
|
||||
|
||||
beneficiary := mobilityaccountsstorage.Account{}
|
||||
if booking.Driver != "" {
|
||||
beneficiaryrequest := &mobilityaccounts.GetAccountRequest{
|
||||
Id: booking.Driver,
|
||||
}
|
||||
|
||||
beneficiaryresp, err := h.services.GRPC.MobilityAccounts.GetAccount(ctx, beneficiaryrequest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get beneficiary: %w", err)
|
||||
}
|
||||
beneficiary = beneficiaryresp.Account.ToStorageType()
|
||||
}
|
||||
|
||||
grouprequest := &groupsmanagement.GetGroupRequest{
|
||||
Id: booking.Vehicle.Administrators[0],
|
||||
}
|
||||
|
||||
groupresp, err := h.services.GRPC.GroupsManagement.GetGroup(ctx, grouprequest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get group: %w", err)
|
||||
}
|
||||
|
||||
alternativerequest := &fleets.GetVehiclesRequest{
|
||||
Namespaces: []string{"parcoursmob"},
|
||||
Types: []string{booking.Vehicle.Type},
|
||||
Administrators: booking.Vehicle.Administrators,
|
||||
AvailabilityFrom: timestamppb.New(booking.Startdate),
|
||||
AvailabilityTo: timestamppb.New(booking.Enddate.Add(24 * time.Hour)),
|
||||
}
|
||||
|
||||
alternativeresp, err := h.services.GRPC.Fleets.GetVehicles(ctx, alternativerequest)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to get alternative vehicles")
|
||||
}
|
||||
|
||||
alternatives := []any{}
|
||||
for _, a := range alternativeresp.Vehicles {
|
||||
alternatives = append(alternatives, a.ToStorageType())
|
||||
}
|
||||
|
||||
documents := h.filestorage.List(filestorage.PREFIX_BOOKINGS + "/" + bookingID)
|
||||
fileTypesMap := h.config.GetStringMapString("storage.files.file_types")
|
||||
|
||||
return &BookingDisplayResult{
|
||||
Booking: booking,
|
||||
Vehicle: booking.Vehicle,
|
||||
Beneficiary: beneficiary,
|
||||
Group: groupresp.Group.ToStorageType(),
|
||||
Documents: documents,
|
||||
FileTypesMap: fileTypesMap,
|
||||
Alternatives: alternatives,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) ChangeBookingVehicle(ctx context.Context, bookingID, newVehicleID string) error {
|
||||
booking, err := h.services.GetBooking(bookingID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get booking: %w", err)
|
||||
}
|
||||
|
||||
booking.Vehicleid = newVehicleID
|
||||
b, _ := fleets.BookingFromStorageType(&booking)
|
||||
|
||||
request := &fleets.UpdateBookingRequest{
|
||||
Booking: b,
|
||||
}
|
||||
|
||||
_, err = h.services.GRPC.Fleets.UpdateBooking(ctx, request)
|
||||
return err
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) MakeVehicleUnavailable(ctx context.Context, vehicleID, unavailablefrom, unavailableto, comment, currentUserID string, currentUserClaims map[string]any) error {
|
||||
g := ctx.Value(identification.GroupKey)
|
||||
if g == nil {
|
||||
return fmt.Errorf("no group found in context")
|
||||
}
|
||||
currentGroup := g.(storage.Group)
|
||||
|
||||
unavailablefromTime, _ := time.Parse("2006-01-02", unavailablefrom)
|
||||
unavailabletoTime, _ := time.Parse("2006-01-02", unavailableto)
|
||||
|
||||
data := map[string]any{
|
||||
"comment": comment,
|
||||
"administrator_unavailability": true,
|
||||
"booked_by": map[string]any{
|
||||
"user": map[string]any{
|
||||
"id": currentUserID,
|
||||
"display_name": currentUserClaims["display_name"],
|
||||
},
|
||||
"group": map[string]any{
|
||||
"id": currentGroup.ID,
|
||||
"name": currentGroup.Data["name"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
datapb, err := structpb.NewStruct(data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create data struct: %w", err)
|
||||
}
|
||||
|
||||
booking := &fleets.Booking{
|
||||
Id: uuid.NewString(),
|
||||
Vehicleid: vehicleID,
|
||||
Unavailablefrom: timestamppb.New(unavailablefromTime),
|
||||
Unavailableto: timestamppb.New(unavailabletoTime),
|
||||
Data: datapb,
|
||||
}
|
||||
|
||||
request := &fleets.CreateBookingRequest{
|
||||
Booking: booking,
|
||||
}
|
||||
|
||||
_, err = h.services.GRPC.Fleets.CreateBooking(ctx, request)
|
||||
return err
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) DeleteBooking(ctx context.Context, bookingID string) error {
|
||||
request := &fleets.DeleteBookingRequest{
|
||||
Id: bookingID,
|
||||
}
|
||||
|
||||
_, err := h.services.GRPC.Fleets.DeleteBooking(ctx, request)
|
||||
return err
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) GetBookingForUnbooking(ctx context.Context, bookingID string) (fleetsstorage.Booking, error) {
|
||||
request := &fleets.GetBookingRequest{
|
||||
Bookingid: bookingID,
|
||||
}
|
||||
|
||||
resp, err := h.services.GRPC.Fleets.GetBooking(ctx, request)
|
||||
if err != nil {
|
||||
return fleetsstorage.Booking{}, fmt.Errorf("failed to get booking: %w", err)
|
||||
}
|
||||
|
||||
return resp.Booking.ToStorageType(), nil
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) UnbookVehicle(ctx context.Context, bookingID, motif, currentUserID string, currentUserClaims map[string]any, currentGroup any) error {
|
||||
group := currentGroup.(storage.Group)
|
||||
|
||||
// Prepare deletion metadata (microservice will add deleted_at automatically)
|
||||
deletionMetadata := map[string]any{
|
||||
"deleted_by": map[string]any{
|
||||
"user": map[string]any{
|
||||
"id": currentUserID,
|
||||
"display_name": currentUserClaims["first_name"].(string) + " " + currentUserClaims["last_name"].(string),
|
||||
"email": currentUserClaims["email"],
|
||||
},
|
||||
"group": map[string]any{
|
||||
"id": group.ID,
|
||||
"name": group.Data["name"],
|
||||
},
|
||||
},
|
||||
"reason": motif,
|
||||
}
|
||||
|
||||
deletionMetadataPb, err := structpb.NewStruct(deletionMetadata)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create deletion metadata: %w", err)
|
||||
}
|
||||
|
||||
// Use the microservice's delete endpoint with metadata
|
||||
deleteRequest := &fleets.DeleteBookingRequest{
|
||||
Id: bookingID,
|
||||
DeletionMetadata: deletionMetadataPb,
|
||||
}
|
||||
|
||||
_, err = h.services.GRPC.Fleets.DeleteBooking(ctx, deleteRequest)
|
||||
return err
|
||||
}
|
||||
|
||||
type VehicleForUpdateResult struct {
|
||||
Vehicle fleetsstorage.Vehicle
|
||||
VehicleTypes []string
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) GetVehicleForUpdate(ctx context.Context, vehicleID string) (*VehicleForUpdateResult, error) {
|
||||
request := &fleets.GetVehicleRequest{
|
||||
Vehicleid: vehicleID,
|
||||
}
|
||||
|
||||
resp, err := h.services.GRPC.Fleets.GetVehicle(ctx, request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get vehicle: %w", err)
|
||||
}
|
||||
|
||||
vehicleTypes := h.config.GetStringSlice("modules.fleets.vehicle_types")
|
||||
|
||||
return &VehicleForUpdateResult{
|
||||
Vehicle: resp.Vehicle.ToStorageType(),
|
||||
VehicleTypes: vehicleTypes,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) UpdateVehicle(ctx context.Context, vehicleID, name, vehicleType, informations, licencePlate, kilometers string, automatic bool, address map[string]any, otherProperties map[string]any) (string, error) {
|
||||
getRequest := &fleets.GetVehicleRequest{
|
||||
Vehicleid: vehicleID,
|
||||
}
|
||||
|
||||
resp, err := h.services.GRPC.Fleets.GetVehicle(ctx, getRequest)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get vehicle: %w", err)
|
||||
}
|
||||
|
||||
// Start with existing data to preserve all fields
|
||||
dataMap := resp.Vehicle.Data.AsMap()
|
||||
if dataMap == nil {
|
||||
dataMap = map[string]any{}
|
||||
}
|
||||
|
||||
// Update with new values
|
||||
if name != "" {
|
||||
dataMap["name"] = name
|
||||
}
|
||||
if address != nil {
|
||||
dataMap["address"] = address
|
||||
}
|
||||
if informations != "" {
|
||||
dataMap["informations"] = informations
|
||||
}
|
||||
if licencePlate != "" {
|
||||
dataMap["licence_plate"] = licencePlate
|
||||
}
|
||||
if kilometers != "" {
|
||||
dataMap["kilometers"] = kilometers
|
||||
}
|
||||
dataMap["automatic"] = automatic
|
||||
// Add other properties
|
||||
for key, value := range otherProperties {
|
||||
dataMap[key] = value
|
||||
}
|
||||
|
||||
data, err := structpb.NewValue(dataMap)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create data struct: %w", err)
|
||||
}
|
||||
|
||||
updateRequest := &fleets.UpdateVehicleRequest{
|
||||
Vehicle: &fleets.Vehicle{
|
||||
Id: vehicleID,
|
||||
Namespace: resp.Vehicle.Namespace,
|
||||
Type: vehicleType,
|
||||
Administrators: resp.Vehicle.Administrators,
|
||||
Data: data.GetStructValue(),
|
||||
},
|
||||
}
|
||||
|
||||
updateResp, err := h.services.GRPC.Fleets.UpdateVehicle(ctx, updateRequest)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to update vehicle: %w", err)
|
||||
}
|
||||
|
||||
return updateResp.Vehicle.Id, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user