package application import ( "context" "encoding/json" "fmt" "net/http" "sort" "time" "git.coopgo.io/coopgo-apps/parcoursmob/utils/identification" "git.coopgo.io/coopgo-apps/parcoursmob/utils/sorting" filestorage "git.coopgo.io/coopgo-apps/parcoursmob/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/coreos/go-oidc" "github.com/google/uuid" "github.com/gorilla/mux" "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" ) func (h *ApplicationHandler) VehiclesManagementOverview(w http.ResponseWriter, r *http.Request) { //Get Vehicles request := &fleets.GetVehiclesRequest{ Namespaces: []string{"parcoursmob"}, } resp, err := h.services.GRPC.Fleets.GetVehicles(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) } vehicles := []fleetsstorage.Vehicle{} bookings := []fleetsstorage.Booking{} vehicles_map := map[string]fleetsstorage.Vehicle{} for _, vehicle := range resp.Vehicles { if filterVehicle(r, vehicle) { v := vehicle.ToStorageType() vehicles = append(vehicles, v) vehicles_map[v.ID] = v for _, b := range v.Bookings { if b.Status() != fleetsstorage.StatusOld { bookings = append(bookings, b) } } } } sort.Sort(sorting.VehiclesByLicencePlate(vehicles)) sort.Sort(sorting.BookingsByStartdate(bookings)) h.Renderer.VehiclesManagementOverview(w, r, vehicles, vehicles_map, bookings) } func (h *ApplicationHandler) VehiclesManagementBookingsList(w http.ResponseWriter, r *http.Request) { //Get Vehicles request := &fleets.GetVehiclesRequest{ Namespaces: []string{"parcoursmob"}, } resp, err := h.services.GRPC.Fleets.GetVehicles(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) } bookings := []fleetsstorage.Booking{} vehicles_map := map[string]fleetsstorage.Vehicle{} for _, vehicle := range resp.Vehicles { if filterVehicle(r, vehicle) { v := vehicle.ToStorageType() vehicles_map[v.ID] = v bookings = append(bookings, v.Bookings...) } } sort.Sort(sorting.BookingsByStartdate(bookings)) cacheid := uuid.NewString() h.cache.PutWithTTL(cacheid, bookings, 1*time.Hour) h.Renderer.VehiclesManagementBookingsList(w, r, vehicles_map, bookings, cacheid) } func (h *ApplicationHandler) VehiclesFleetAdd(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { g := r.Context().Value(identification.GroupKey) if g == nil { w.WriteHeader(http.StatusBadRequest) return } group := g.(storage.Group) if err := r.ParseForm(); err != nil { fmt.Println(err) w.WriteHeader(http.StatusBadRequest) return } dataMap := map[string]any{} if v := r.FormValue("name"); v != "" { dataMap["name"] = v } if v := r.FormValue("address"); v != "" { var address map[string]any err := json.Unmarshal([]byte(v), &address) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } dataMap["address"] = address } if v := r.FormValue("informations"); v != "" { dataMap["informations"] = v } if v := r.FormValue("licence_plate"); v != "" { dataMap["licence_plate"] = v } if v := r.FormValue("automatic"); v != "" { fmt.Println(v) dataMap["automatic"] = (v == "on") } data, err := structpb.NewValue(dataMap) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } vehicle := &fleets.Vehicle{ Id: uuid.NewString(), Namespace: "parcoursmob", Type: r.FormValue("type"), Administrators: []string{group.ID}, Data: data.GetStructValue(), } request := &fleets.AddVehicleRequest{ Vehicle: vehicle, } _, err = h.services.GRPC.Fleets.AddVehicle(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, fmt.Sprintf("/app/vehicles-management/fleet/%s", vehicle.Id), http.StatusFound) return } vehicles_types := h.config.GetStringSlice("modules.fleets.vehicle_types") h.Renderer.VehiclesFleetAdd(w, r, vehicles_types) } func (h *ApplicationHandler) VehiclesFleetDisplay(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) vehicleid := vars["vehicleid"] request := &fleets.GetVehicleRequest{ Vehicleid: vehicleid, } resp, err := h.services.GRPC.Fleets.GetVehicle(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } h.Renderer.VehiclesFleetDisplay(w, r, resp.Vehicle.ToStorageType()) } func (h *ApplicationHandler) VehiclesFleetUpdate(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) vehicleid := vars["vehicleid"] if r.Method == "POST" { w.WriteHeader(http.StatusNotFound) return } request := &fleets.GetVehicleRequest{ Vehicleid: vehicleid, } resp, err := h.services.GRPC.Fleets.GetVehicle(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } h.Renderer.VehiclesFleetUpdate(w, r, resp.Vehicle.ToStorageType()) } func filterVehicle(r *http.Request, v *fleets.Vehicle) bool { g := r.Context().Value(identification.GroupKey) if g == nil { return false } group := g.(storage.Group) for _, n := range v.Administrators { if n == group.ID { return true } } return false } func (h ApplicationHandler) VehicleManagementBookingDisplay(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) bookingid := vars["bookingid"] request := &fleets.GetBookingRequest{ Bookingid: bookingid, } resp, err := h.services.GRPC.Fleets.GetBooking(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } booking := resp.Booking.ToStorageType() if r.Method == "POST" { r.ParseForm() newbooking := resp.Booking startdate := r.FormValue("startdate") 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) } } enddate := r.FormValue("enddate") 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)) } } unavailablefrom := r.FormValue("unavailablefrom") if unavailablefrom != "" { newunavailablefrom, _ := time.Parse("2006-01-02", unavailablefrom) newbooking.Unavailablefrom = timestamppb.New(newunavailablefrom) } unavailableto := r.FormValue("unavailableto") 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(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } booking = newbooking.ToStorageType() } beneficiary := mobilityaccountsstorage.Account{} if booking.Driver != "" { beneficiaryrequest := &mobilityaccounts.GetAccountRequest{ Id: booking.Driver, } beneficiaryresp, err := h.services.GRPC.MobilityAccounts.GetAccount(context.TODO(), beneficiaryrequest) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } beneficiary = beneficiaryresp.Account.ToStorageType() } grouprequest := &groupsmanagement.GetGroupRequest{ Id: booking.Vehicle.Administrators[0], } groupresp, err := h.services.GRPC.GroupsManagement.GetGroup(context.TODO(), grouprequest) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } documents := h.filestorage.List(filestorage.PREFIX_BOOKINGS + "/" + bookingid) file_types_map := h.config.GetStringMapString("storage.files.file_types") h.Renderer.VehicleManagementBookingDisplay(w, r, booking, booking.Vehicle, beneficiary, groupresp.Group.ToStorageType(), documents, file_types_map) } func (h ApplicationHandler) VehiclesFleetMakeUnavailable(w http.ResponseWriter, r *http.Request) { // Get Group g := r.Context().Value(identification.GroupKey) if g == nil { fmt.Println("no current group") w.WriteHeader(http.StatusInternalServerError) return } current_group := g.(storage.Group) // Get current user ID u := r.Context().Value(identification.IdtokenKey) if u == nil { fmt.Println("no current user") w.WriteHeader(http.StatusInternalServerError) return } current_user_token := u.(*oidc.IDToken) // Get current user claims c := r.Context().Value(identification.ClaimsKey) if c == nil { fmt.Println("no current user claims") w.WriteHeader(http.StatusInternalServerError) return } current_user_claims := c.(map[string]any) vars := mux.Vars(r) vehicleid := vars["vehicleid"] r.ParseForm() start := r.FormValue("unavailablefrom") end := r.FormValue("unavailableto") comment := r.FormValue("comment") unavailablefrom, _ := time.Parse("2006-01-02", start) unavailableto, _ := time.Parse("2006-01-02", end) data := map[string]any{ "comment": comment, "administrator_unavailability": true, "booked_by": map[string]any{ "user": map[string]any{ "id": current_user_token.Subject, "display_name": current_user_claims["display_name"], }, "group": map[string]any{ "id": current_group.ID, "name": current_group.Data["name"], }, }, } datapb, err := structpb.NewStruct(data) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } booking := &fleets.Booking{ Id: uuid.NewString(), Vehicleid: vehicleid, Unavailablefrom: timestamppb.New(unavailablefrom), Unavailableto: timestamppb.New(unavailableto), Data: datapb, } request := &fleets.CreateBookingRequest{ Booking: booking, } _, err = h.services.GRPC.Fleets.CreateBooking(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusBadRequest) return } http.Redirect(w, r, fmt.Sprintf("/app/vehicles-management/fleet/%s", vehicleid), http.StatusFound) }