package application import ( "context" "encoding/json" "errors" "fmt" "net/http" "reflect" "sort" "time" formvalidators "git.coopgo.io/coopgo-apps/parcoursmob/utils/form-validators" "git.coopgo.io/coopgo-apps/parcoursmob/utils/sorting" mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi" mobilityaccountsstorage "git.coopgo.io/coopgo-platform/mobility-accounts/storage" "github.com/google/uuid" "github.com/gorilla/mux" "github.com/rs/zerolog/log" "google.golang.org/protobuf/types/known/structpb" ) type DriversForm struct { FirstName string `json:"first_name" validate:"required"` LastName string `json:"last_name" validate:"required"` Email string `json:"email" validate:"required,email"` Birthdate *time.Time `json:"birthdate" validate:"required"` PhoneNumber string `json:"phone_number" validate:"required,phoneNumber"` Address any `json:"address,omitempty"` Gender string `json:"gender"` } const ( Sunday = iota Monday Tuesday Wednesday Thursday Friday Saturday ) func (h *ApplicationHandler) SolidarityTransportOverview(w http.ResponseWriter, r *http.Request) { accounts, err := h.solidarityDrivers(r) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusBadRequest) return } sort.Sort(sorting.SolidarityDriversByName(accounts)) // cacheid := uuid.NewString() // h.cache.PutWithTTL(cacheid, accounts, 1*time.Hour) h.Renderer.SolidarityTransportOverview(w, r, accounts) } func (h *ApplicationHandler) SolidarityTransportCreateDriver(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { dataMap, err := parseBeneficiariesForm(r) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusBadRequest) return } data, err := structpb.NewValue(dataMap) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) return } request := &mobilityaccounts.RegisterRequest{ Account: &mobilityaccounts.Account{ Namespace: "solidarity_drivers", Data: data.GetStructValue(), }, } resp, err := h.services.GRPC.MobilityAccounts.Register(context.TODO(), request) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, fmt.Sprintf("/app/solidarity-transport/drivers/%s", resp.Account.Id), http.StatusFound) return } h.Renderer.SolidarityTransportCreateDriver(w, r) } func (h *ApplicationHandler) SolidarityTransportDriverDisplay(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) driverID := vars["driverid"] driver, err := h.services.GetAccount(driverID) if err != nil { log.Error().Err(err).Msg("Issue retrieving driver account") w.WriteHeader(http.StatusInternalServerError) return } h.Renderer.SolidarityTransportDriverDisplay(w, r, driver) } func (h *ApplicationHandler) SolidarityTransportAddAvailability(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { log.Error().Msg("Wrong method") w.WriteHeader(http.StatusMethodNotAllowed) return } if err := r.ParseForm(); err != nil { log.Error().Err(err).Msg("error parsong availabilities form") w.WriteHeader(http.StatusInternalServerError) return } vars := mux.Vars(r) driverID := vars["driverid"] availabilities := []any{} if r.PostFormValue("days.monday") == "on" { a := map[string]any{ "id": uuid.NewString(), "day": Monday, "start_time": r.PostFormValue("starttime"), "end_time": r.PostFormValue("endtime"), } availabilities = append(availabilities, a) } if r.PostFormValue("days.tuesday") == "on" { a := map[string]any{ "id": uuid.NewString(), "day": Tuesday, "start_time": r.PostFormValue("starttime"), "end_time": r.PostFormValue("endtime"), } availabilities = append(availabilities, a) } if r.PostFormValue("days.Wednesday") == "on" { a := map[string]any{ "id": uuid.NewString(), "day": Wednesday, "start_time": r.PostFormValue("starttime"), "end_time": r.PostFormValue("endtime"), } availabilities = append(availabilities, a) } if r.PostFormValue("days.thursday") == "on" { a := map[string]any{ "id": uuid.NewString(), "day": Thursday, "start_time": r.PostFormValue("starttime"), "end_time": r.PostFormValue("endtime"), } availabilities = append(availabilities, a) } if r.PostFormValue("days.friday") == "on" { a := map[string]any{ "id": uuid.NewString(), "day": Friday, "start_time": r.PostFormValue("starttime"), "end_time": r.PostFormValue("endtime"), } availabilities = append(availabilities, a) } if r.PostFormValue("days.saturday") == "on" { a := map[string]any{ "id": uuid.NewString(), "day": Saturday, "start_time": r.PostFormValue("starttime"), "end_time": r.PostFormValue("endtime"), } availabilities = append(availabilities, a) } if r.PostFormValue("days.sunday") == "on" { a := map[string]any{ "id": uuid.NewString(), "day": Sunday, "start_time": r.PostFormValue("starttime"), "end_time": r.PostFormValue("endtime"), } availabilities = append(availabilities, a) } account, err := h.services.GetAccount(driverID) if err != nil { log.Error().Err(err).Msg("driver not found") w.WriteHeader(http.StatusNotFound) return } existing_availabilities, ok := account.Data["solidarity_transport_availabilities"].([]any) if !ok { existing_availabilities = []any{} } for _, av := range availabilities { existing_availabilities = append(existing_availabilities, av) } account.Data["solidarity_transport_availabilities"] = existing_availabilities data, err := structpb.NewValue(account.Data) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) return } request := &mobilityaccounts.UpdateDataRequest{ Account: &mobilityaccounts.Account{ Id: account.ID, Namespace: account.Namespace, Data: data.GetStructValue(), }, } _, err = h.services.GRPC.MobilityAccounts.UpdateData(context.TODO(), request) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, fmt.Sprintf("/app/solidarity-transport/drivers/%s", driverID), http.StatusFound) } func (h *ApplicationHandler) SolidarityTransportDeleteAvailability(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) driverID := vars["driverid"] availabilityID := vars["availabilityid"] account, err := h.services.GetAccount(driverID) if err != nil { log.Error().Err(err).Msg("driver not found") w.WriteHeader(http.StatusNotFound) return } existing_availabilities, ok := account.Data["solidarity_transport_availabilities"].([]any) if !ok { log.Error().Err(errors.New("no availability found")).Msg("no availability") w.WriteHeader(http.StatusNotFound) return } new_availabilities := []any{} for _, av := range existing_availabilities { log.Info().Str("type", reflect.TypeOf(av).Name()).Msg("info on type") if m, ok := av.(map[string]any); ok { if id, ok2 := m["id"].(string); ok2 { if id != availabilityID { new_availabilities = append(new_availabilities, av) } } } } account.Data["solidarity_transport_availabilities"] = new_availabilities data, err := structpb.NewValue(account.Data) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) return } request := &mobilityaccounts.UpdateDataRequest{ Account: &mobilityaccounts.Account{ Id: account.ID, Namespace: account.Namespace, Data: data.GetStructValue(), }, } _, err = h.services.GRPC.MobilityAccounts.UpdateData(context.TODO(), request) if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, fmt.Sprintf("/app/solidarity-transport/drivers/%s", driverID), http.StatusFound) } func parseDriversForm(r *http.Request) (map[string]any, error) { if err := r.ParseForm(); err != nil { return nil, err } var date *time.Time if r.PostFormValue("birthdate") != "" { d, err := time.Parse("2006-01-02", r.PostFormValue("birthdate")) if err != nil { return nil, err } date = &d } formData := DriversForm{ FirstName: r.PostFormValue("first_name"), LastName: r.PostFormValue("last_name"), Email: r.PostFormValue("email"), Birthdate: date, PhoneNumber: r.PostFormValue("phone_number"), Gender: r.PostFormValue("gender"), } if r.PostFormValue("address") != "" { var a any json.Unmarshal([]byte(r.PostFormValue("address")), &a) formData.Address = a } validate := formvalidators.New() if err := validate.Struct(formData); err != nil { return nil, err } d, err := json.Marshal(formData) if err != nil { return nil, err } var dataMap map[string]any err = json.Unmarshal(d, &dataMap) if err != nil { return nil, err } return dataMap, nil } func (h *ApplicationHandler) solidarityDrivers(r *http.Request) ([]mobilityaccountsstorage.Account, error) { accounts := []mobilityaccountsstorage.Account{} request := &mobilityaccounts.GetAccountsRequest{ Namespaces: []string{"solidarity_drivers"}, } resp, err := h.services.GRPC.MobilityAccounts.GetAccounts(context.TODO(), request) if err != nil { return accounts, err } for _, account := range resp.Accounts { if filterAccount(r, account) { a := account.ToStorageType() accounts = append(accounts, a) } } return accounts, err }