package application import ( "context" "fmt" "io" "net/http" "sort" "strings" "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" 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) VehiclesSearch(w http.ResponseWriter, r *http.Request) { r.ParseForm() var beneficiary mobilityaccountsstorage.Account beneficiarydocuments := []filestorage.FileInfo{} vehicles := []any{} searched := false start := r.FormValue("startdate") end := r.FormValue("enddate") startdate, _ := time.Parse("2006-01-02", start) enddate, _ := time.Parse("2006-01-02", end) if r.FormValue("beneficiaryid") != "" { // Handler form searched = true requestbeneficiary := &mobilityaccounts.GetAccountRequest{ Id: r.FormValue("beneficiaryid"), } respbeneficiary, err := h.services.GRPC.MobilityAccounts.GetAccount(context.TODO(), requestbeneficiary) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } beneficiary = respbeneficiary.Account.ToStorageType() 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) } for _, vehicle := range resp.Vehicles { v := vehicle.ToStorageType() if v.Free(startdate, enddate) { vehicles = append(vehicles, v) } } beneficiarydocuments = h.filestorage.List(filestorage.PREFIX_BENEFICIARIES + "/" + beneficiary.ID) } accounts, err := h.beneficiaries(r) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusBadRequest) return } sort.Sort(sorting.BeneficiariesByName(accounts)) mandatory_documents := h.config.GetStringSlice("modules.fleets.booking_documents.mandatory") file_types_map := h.config.GetStringMapString("storage.files.file_types") h.Renderer.VehiclesSearch(w, r, accounts, searched, vehicles, beneficiary, r.FormValue("startdate"), r.FormValue("enddate"), mandatory_documents, file_types_map, beneficiarydocuments) } func (h ApplicationHandler) Book(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"] beneficiaryid := vars["beneficiaryid"] r.ParseMultipartForm(10 * 1024 * 1024) start := r.FormValue("startdate") end := r.FormValue("enddate") startdate, _ := time.Parse("2006-01-02", start) enddate, _ := time.Parse("2006-01-02", end) data := map[string]any{ "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, Driver: beneficiaryid, Startdate: timestamppb.New(startdate), Enddate: timestamppb.New(enddate), Unavailablefrom: timestamppb.New(startdate), Unavailableto: timestamppb.New(enddate.Add(72 * time.Hour)), Data: datapb, } request := &fleets.CreateBookingRequest{ Booking: booking, } fmt.Println(r.FormFile("doc-identity_proof")) for _, v := range h.config.GetStringSlice("modules.fleets.booking_documents.mandatory") { existing_file := r.FormValue("type-" + v) if existing_file == "" { file, header, err := r.FormFile("doc-" + v) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Document manquant : " + v)) return } defer file.Close() fileid := uuid.NewString() metadata := map[string]string{ "type": v, "name": header.Filename, } if err := h.filestorage.Put(file, filestorage.PREFIX_BOOKINGS, fmt.Sprintf("%s/%s_%s", booking.Id, fileid, header.Filename), header.Size, metadata); err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } } else { path := strings.Split(existing_file, "/") if err := h.filestorage.Copy(existing_file, fmt.Sprintf("%s/%s/%s", filestorage.PREFIX_BOOKINGS, booking.Id, path[len(path)-1])); err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } } } _, 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/bookings/%s", booking.Id), http.StatusFound) } func (h ApplicationHandler) VehicleBookingDisplay(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() 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 } 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.VehicleBookingDisplay(w, r, booking, booking.Vehicle, beneficiaryresp.Account.ToStorageType(), groupresp.Group.ToStorageType(), documents, file_types_map) } func (h ApplicationHandler) VehiclesBookingsList(w http.ResponseWriter, r *http.Request) { request := &fleets.GetBookingsRequest{} resp, err := h.services.GRPC.Fleets.GetBookings(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusNotFound) return } bookings := []any{} for _, b := range resp.Bookings { bookings = append(bookings, b.ToStorageType()) } h.Renderer.VehicleBookingsList(w, r, bookings) } func (h *ApplicationHandler) BookingDocumentDownload(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) bookingid := vars["bookingid"] document := vars["document"] fmt.Println(fmt.Sprintf("%s/%s", bookingid, document)) file, info, err := h.filestorage.Get(filestorage.PREFIX_BOOKINGS, fmt.Sprintf("%s/%s", bookingid, document)) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } w.Header().Set("Content-Type", info.ContentType) if _, err = io.Copy(w, file); err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, fmt.Sprintf("/app/vehicles/bookings/%s", bookingid), http.StatusFound) }