diff --git a/Dockerfile b/Dockerfile index 3911f31..130edc5 100755 --- a/Dockerfile +++ b/Dockerfile @@ -19,9 +19,11 @@ COPY . . RUN go mod download && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /server -RUN rm -r themes/* +RUN rm -r themes +RUN mkdir themes RUN git clone --depth 1 https://git.coopgo.io/coopgo-apps/parcoursmob-default-theme themes/default RUN git clone -b spie06 --depth 1 https://git.coopgo.io/coopgo-apps/parcoursmob-default-theme themes/spie06 +RUN git clone -b solidarity-transport-dev --depth 1 https://git.coopgo.io/coopgo-apps/parcoursmob-default-theme themes/solidarity-transport FROM scratch COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ diff --git a/handlers/application/beneficiaries.go b/handlers/application/beneficiaries.go index 425e48f..0d4e343 100755 --- a/handlers/application/beneficiaries.go +++ b/handlers/application/beneficiaries.go @@ -21,14 +21,13 @@ import ( filestorage "git.coopgo.io/coopgo-apps/parcoursmob/utils/storage" agenda "git.coopgo.io/coopgo-platform/agenda/grpcapi" agendastorage "git.coopgo.io/coopgo-platform/agenda/storage" + diagsstorage "git.coopgo.io/coopgo-platform/diags/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" - diags "git.coopgo.io/coopgo-platform/diags/grpcapi" - diagsstorage "git.coopgo.io/coopgo-platform/diags/storage" "github.com/google/uuid" "github.com/gorilla/mux" "github.com/rs/zerolog/log" @@ -108,7 +107,6 @@ func sortByDate(events []Event_Beneficiary) { } func (h *ApplicationHandler) BeneficiariesList(w http.ResponseWriter, r *http.Request) { - accounts, err := h.beneficiaries(r) if err != nil { log.Error().Err(err).Msg("") @@ -157,7 +155,6 @@ func (h *ApplicationHandler) BeneficiaryCreate(w http.ResponseWriter, r *http.Re } resp, err := h.services.GRPC.MobilityAccounts.Register(context.TODO(), request) - if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) @@ -170,7 +167,6 @@ func (h *ApplicationHandler) BeneficiaryCreate(w http.ResponseWriter, r *http.Re } _, err = h.services.GRPC.GroupsManagement.Subscribe(context.TODO(), subscribe) - if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) @@ -275,7 +271,6 @@ func (h *ApplicationHandler) BeneficiaryDisplay(w http.ResponseWriter, r *http.R var status_booking int for _, b := range bookings { - if b.Enddate.After(currentTime) || b.Enddate.Equal(currentTime) { GetVehiculeRequest := &fleets.GetVehicleRequest{ Vehicleid: b.Vehicleid, @@ -314,7 +309,7 @@ func (h *ApplicationHandler) BeneficiaryDisplay(w http.ResponseWriter, r *http.R diag := []diagsstorage.Diag{} - diagsrequest := &diags.GetDiagsRequest{ + /*diagsrequest := &diags.GetDiagsRequest{ Namespaces: []string{"parcoursmob_beneficiaries"}, } @@ -330,8 +325,8 @@ func (h *ApplicationHandler) BeneficiaryDisplay(w http.ResponseWriter, r *http.R if beneficiary, ok := diagData["beneficiary"].(string); ok && beneficiary == beneficiaryID { diag = append(diag, d.ToStorageType()) } - } - + }*/ + groupsrequest := &groupsmanagement.GetGroupsRequest{ Namespaces: []string{"parcoursmob_organizations"}, Member: beneficiaryID, @@ -386,7 +381,6 @@ func (h *ApplicationHandler) BeneficiaryUpdate(w http.ResponseWriter, r *http.Re } resp, err := h.services.GRPC.MobilityAccounts.UpdateData(context.TODO(), request) - if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) @@ -409,8 +403,8 @@ func (h *ApplicationHandler) BeneficiaryUpdate(w http.ResponseWriter, r *http.Re return } - //TODO filter namespaces - //TODO filter groups + // TODO filter namespaces + // TODO filter groups h.Renderer.BeneficiaryUpdate(w, r, resp.Account.ToStorageType()) } @@ -452,7 +446,7 @@ func (h *ApplicationHandler) BeneficiaryDocuments(w http.ResponseWriter, r *http vars := mux.Vars(r) beneficiaryID := vars["beneficiaryid"] - //r.ParseForm() + // r.ParseForm() r.ParseMultipartForm(100 * 1024 * 1024) document_type := r.FormValue("type") @@ -481,7 +475,6 @@ func (h *ApplicationHandler) BeneficiaryDocuments(w http.ResponseWriter, r *http } http.Redirect(w, r, fmt.Sprintf("/app/beneficiaries/%s", beneficiaryID), http.StatusFound) - } func (h *ApplicationHandler) BeneficiaryDocumentDownload(w http.ResponseWriter, r *http.Request) { @@ -504,7 +497,6 @@ func (h *ApplicationHandler) BeneficiaryDocumentDownload(w http.ResponseWriter, } http.Redirect(w, r, fmt.Sprintf("/app/beneficiaries/%s", beneficiaryID), http.StatusFound) - } func filterAccount(r *http.Request, a *mobilityaccounts.Account) bool { @@ -523,7 +515,7 @@ func filterAccount(r *http.Request, a *mobilityaccounts.Account) bool { // func BeneficiariesEventList() func (h *ApplicationHandler) beneficiaries(r *http.Request) ([]mobilityaccountsstorage.Account, error) { - var accounts = []mobilityaccountsstorage.Account{} + accounts := []mobilityaccountsstorage.Account{} g := r.Context().Value(identification.GroupKey) if g == nil { return accounts, errors.New("no group provided") diff --git a/handlers/application/journeys.go b/handlers/application/journeys.go index 2290e1e..117f8a9 100755 --- a/handlers/application/journeys.go +++ b/handlers/application/journeys.go @@ -14,6 +14,7 @@ import ( groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi" groupstorage "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/gorilla/mux" geojson "github.com/paulmach/go.geojson" @@ -23,8 +24,10 @@ import ( "google.golang.org/protobuf/types/known/structpb" ) -var Depart any -var Arrive any +var ( + Depart any + Arrive any +) func (h *ApplicationHandler) JourneysSearch(w http.ResponseWriter, r *http.Request) { r.ParseForm() @@ -33,6 +36,7 @@ func (h *ApplicationHandler) JourneysSearch(w http.ResponseWriter, r *http.Reque carpool_results any vehicle_results []any ) + availableDrivers := []mobilityaccountsstorage.Account{} vehiclech := make(chan []any, 1) navitiaCh := make(chan *navitia.JourneyResults, 1) carpoolCh := make(chan any, 1) @@ -78,7 +82,7 @@ func (h *ApplicationHandler) JourneysSearch(w http.ResponseWriter, r *http.Reque } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// journeysRequest := func() { - //TODO make it a library + // TODO make it a library session, _ := navitia.NewCustom( h.config.GetString("services.navitia.api_key"), "https://api.navitia.io/v1", @@ -94,7 +98,7 @@ func (h *ApplicationHandler) JourneysSearch(w http.ResponseWriter, r *http.Reque From: types.ID(fmt.Sprintf("%f", departuregeo.Geometry.Point[0]) + ";" + fmt.Sprintf("%f", departuregeo.Geometry.Point[1])), To: types.ID(fmt.Sprintf("%f", destinationgeo.Geometry.Point[0]) + ";" + fmt.Sprintf("%f", destinationgeo.Geometry.Point[1])), Date: departuredatetime.Add(-2 * time.Hour), - DateIsArrival: false, //TODO + DateIsArrival: false, // TODO } journeys, err = session.Journeys(context.Background(), request) @@ -104,7 +108,27 @@ func (h *ApplicationHandler) JourneysSearch(w http.ResponseWriter, r *http.Reque // return } navitiaCh <- journeys - + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // SOLIDARITY TRANSPORT + drivers, err := h.services.GetAccountsInNamespace("solidarity_drivers") + if err != nil { + drivers = []mobilityaccountsstorage.Account{} + } + for _, a := range drivers { + if availabilities, ok := a.Data["solidarity_transport_availabilities"].([]any); ok { + for _, availability := range availabilities { + if av, ok := availability.(map[string]any); ok { + day := av["day"].(float64) + starttime := av["start_time"].(string) + endtime := av["end_time"].(string) + if departuretime >= starttime && departuretime <= endtime && departuredatetime.Weekday() == time.Weekday(int(day)) { + availableDrivers = append(availableDrivers, a) + break + } + } + } + } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// //CARPOOL @@ -170,7 +194,7 @@ func (h *ApplicationHandler) JourneysSearch(w http.ResponseWriter, r *http.Reque vehicle_results = <-vehiclech } - h.Renderer.JourneysSearch(w, r, carpool_results, journeys_results, vehicle_results, searched, departuregeo, destinationgeo, departuredate, departuretime) + h.Renderer.JourneysSearch(w, r, carpool_results, journeys_results, vehicle_results, searched, departuregeo, destinationgeo, departuredate, departuretime, availableDrivers) } type GroupsModule []groupstorage.Group @@ -182,7 +206,6 @@ func (a GroupsModule) Less(i, j int) bool { func (a GroupsModule) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (h *ApplicationHandler) GroupsGestion(w http.ResponseWriter, r *http.Request) { - request := &groupsmanagement.GetGroupsRequest{ Namespaces: []string{"parcoursmob_groups_covoiturage"}, } @@ -194,7 +217,7 @@ func (h *ApplicationHandler) GroupsGestion(w http.ResponseWriter, r *http.Reques return } - var groups = []groupstorage.Group{} + groups := []groupstorage.Group{} for _, group := range resp.Groups { g := group.ToStorageType() @@ -208,6 +231,7 @@ func (h *ApplicationHandler) GroupsGestion(w http.ResponseWriter, r *http.Reques h.Renderer.GroupsGestion(w, r, groups, cacheid) } + func filterAcc(r *http.Request, a *mobilityaccounts.Account) bool { searchFilter, ok := r.URL.Query()["search"] @@ -222,7 +246,6 @@ func filterAcc(r *http.Request, a *mobilityaccounts.Account) bool { } func (h *ApplicationHandler) CreateGroup(w http.ResponseWriter, r *http.Request) { - var beneficiary any var ( departurgeo *geojson.Feature @@ -362,7 +385,6 @@ func (h *ApplicationHandler) CreateGroup(w http.ResponseWriter, r *http.Request) } h.Renderer.CreateGroup(w, r, Depart, Arrive, searched, beneficiary, accountsBeneficaire, departurgeo, dstinationgeo) - } func (h *ApplicationHandler) DisplayGroupCovoiturage(w http.ResponseWriter, r *http.Request) { @@ -380,7 +402,7 @@ func (h *ApplicationHandler) DisplayGroupCovoiturage(w http.ResponseWriter, r *h return } - var accounts = []any{} + accounts := []any{} requesst := &mobilityaccounts.GetAccountsBatchRequest{ Accountids: resp.Group.Members, @@ -425,7 +447,6 @@ func (h *ApplicationHandler) DisplayGroupCovoiturage(w http.ResponseWriter, r *h } _, err = h.services.GRPC.GroupsManagement.Subscribe(context.TODO(), subscribe) - if err != nil { log.Error().Err(err).Msg("") w.WriteHeader(http.StatusInternalServerError) @@ -446,7 +467,6 @@ func (h *ApplicationHandler) DisplayGroupCovoiturage(w http.ResponseWriter, r *h } r.ParseForm() dataMap := map[string]any{ - "depart": Depart, "arrive": Arrive, } @@ -569,7 +589,6 @@ func (h *ApplicationHandler) UpdateGroupCovoiturage(w http.ResponseWriter, r *ht return } } - } http.Redirect(w, r, fmt.Sprintf("/app/journeys/groups_covoiturage/create/%s", groupid), http.StatusFound) /* diff --git a/handlers/application/solidarity-transport.go b/handlers/application/solidarity-transport.go new file mode 100644 index 0000000..dcdb23e --- /dev/null +++ b/handlers/application/solidarity-transport.go @@ -0,0 +1,358 @@ +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 +} diff --git a/main.go b/main.go index 9c37c42..ef9df07 100755 --- a/main.go +++ b/main.go @@ -106,6 +106,11 @@ func main() { application.HandleFunc("/members/{adminid}/update", applicationHandler.MemberUpdate) application.HandleFunc("/members/", applicationHandler.MembersList) application.HandleFunc("/journeys/", applicationHandler.JourneysSearch) + application.HandleFunc("/solidarity-transport/", applicationHandler.SolidarityTransportOverview) + application.HandleFunc("/solidarity-transport/drivers/create", applicationHandler.SolidarityTransportCreateDriver) + application.HandleFunc("/solidarity-transport/drivers/{driverid}", applicationHandler.SolidarityTransportDriverDisplay) + application.HandleFunc("/solidarity-transport/drivers/{driverid}/availabilities", applicationHandler.SolidarityTransportAddAvailability) + application.HandleFunc("/solidarity-transport/drivers/{driverid}/availabilities/{availabilityid}/delete", applicationHandler.SolidarityTransportDeleteAvailability) application.HandleFunc("/vehicles/", applicationHandler.VehiclesSearch) application.HandleFunc("/vehicles/bookings/", applicationHandler.VehiclesBookingsList) application.HandleFunc("/vehicles/bookings/{bookingid}", applicationHandler.VehicleBookingDisplay) diff --git a/renderer/journeys.go b/renderer/journeys.go index accf061..7a4ee18 100755 --- a/renderer/journeys.go +++ b/renderer/journeys.go @@ -35,18 +35,19 @@ func (s BeneficiariesCovoiturage) JSONWithLimits(a int, b int) template.JS { return s.JSON() } -func (renderer *Renderer) JourneysSearch(w http.ResponseWriter, r *http.Request, carpools any, transitjourneys any, vehicles []any, searched bool, departure any, destination any, departuredate string, departuretime string) { +func (renderer *Renderer) JourneysSearch(w http.ResponseWriter, r *http.Request, carpools any, transitjourneys any, vehicles []any, searched bool, departure any, destination any, departuredate string, departuretime string, solidarityDrivers any) { files := renderer.ThemeConfig.GetStringSlice("views.journeys.search.files") state := NewState(r, renderer.ThemeConfig, journeysMenu) state.ViewState = map[string]any{ - "searched": searched, - "departuredate": departuredate, - "departuretime": departuretime, - "departure": departure, - "destination": destination, - "journeys": transitjourneys, - "carpools": carpools, - "vehicles": vehicles, + "searched": searched, + "departuredate": departuredate, + "departuretime": departuretime, + "departure": departure, + "destination": destination, + "journeys": transitjourneys, + "carpools": carpools, + "vehicles": vehicles, + "solidarity_drivers": solidarityDrivers, } renderer.Render("journeys", w, r, files, state) @@ -69,6 +70,7 @@ func (s BeneficiariesListstate) JSONWithLimits(a int, b int) template.JS { } return s.JSON() } + func (renderer *Renderer) GroupsGestion(w http.ResponseWriter, r *http.Request, groups []groupstorage.Group, cacheid string) { files := renderer.ThemeConfig.GetStringSlice("views.journeys.list.files") state := NewState(r, renderer.ThemeConfig, journeysMenu) @@ -98,7 +100,6 @@ func (renderer *Renderer) CreateGroup(w http.ResponseWriter, r *http.Request, de viewstate["search"] = map[string]any{ "beneficiary": beneficiary, } - } state.ViewState = viewstate @@ -130,7 +131,6 @@ func (renderer *Renderer) DisplayGroupCovoiturage(w http.ResponseWriter, r *http viewstate["search"] = map[string]any{ "beneficiary": beneficiary, } - } state.ViewState = viewstate @@ -146,5 +146,4 @@ func (renderer *Renderer) UpdateGroupCovoiturage(w http.ResponseWriter, r *http. "memberid": memberid, } renderer.Render("journeys", w, r, files, state) - } diff --git a/renderer/renderer.go b/renderer/renderer.go index 2cc23cf..a9ac641 100755 --- a/renderer/renderer.go +++ b/renderer/renderer.go @@ -4,6 +4,7 @@ import ( "fmt" "html/template" "net/http" + "reflect" "git.coopgo.io/coopgo-apps/parcoursmob/utils/icons" "git.coopgo.io/coopgo-apps/parcoursmob/utils/identification" @@ -37,7 +38,6 @@ func NewRenderer(global *viper.Viper, templates_dir string) *Renderer { } func (renderer *Renderer) Render(name string, w http.ResponseWriter, r *http.Request, files []string, state RenderState) { - genericFiles := renderer.ThemeConfig.GetStringSlice("views.generic.files") prefixed_files := []string{} @@ -61,6 +61,7 @@ func (renderer *Renderer) Render(name string, w http.ResponseWriter, r *http.Req "walkingLength": WalkingLength, "divideFloat64": Divide[float64], "divideInt": Divide[int], + "typeOf": reflect.TypeOf, }, ) t = template.Must(t.ParseFiles(prefixed_files...)) @@ -72,7 +73,6 @@ func (renderer *Renderer) Render(name string, w http.ResponseWriter, r *http.Req } func (renderer *Renderer) RenderNoLayout(name string, w http.ResponseWriter, r *http.Request, files []string, state RenderState) { - prefixed_files := []string{} for _, f := range files { prefixed_files = append(prefixed_files, renderer.templateFile(f)) @@ -90,6 +90,7 @@ func (renderer *Renderer) RenderNoLayout(name string, w http.ResponseWriter, r * "unsescapeHTML": UnescapeHTML, "divideFloat64": Divide[float64], "divideInt": Divide[int], + "typeOf": reflect.TypeOf, }, ) @@ -189,6 +190,15 @@ func NewState(r *http.Request, themeConfig *viper.Viper, menuState string) Rende }) } + if modules["solidarity_transport"] != nil && modules["solidarity_transport"].(bool) { + ls.MenuItems = append(ls.MenuItems, MenuItem{ + Title: "Transport solidaire", + Link: "/app/solidarity-transport/", + Active: menuState == solidarityTransportMenu, + Icon: "tabler-icons:car", + }) + } + if modules["vehicles"] != nil && modules["vehicles"].(bool) { ls.MenuItems = append(ls.MenuItems, MenuItem{ Title: "Véhicules partagés", @@ -223,7 +233,6 @@ func NewState(r *http.Request, themeConfig *viper.Viper, menuState string) Rende Active: menuState == groupMenu, Icon: "hero:outline/group_module", }) - } if modules["support"] != nil && modules["support"].(bool) { @@ -233,7 +242,6 @@ func NewState(r *http.Request, themeConfig *viper.Viper, menuState string) Rende Active: menuState == commentMenu, Icon: "hero:outline/support", }) - } if modules["directory"] != nil && modules["directory"].(bool) { @@ -244,22 +252,23 @@ func NewState(r *http.Request, themeConfig *viper.Viper, menuState string) Rende Icon: "hero:outline/document-text", }) } - if modules["conseillers"] != nil && modules["conseillers"].(bool) { + /*if modules["conseillers"] != nil && modules["conseillers"].(bool) { ls.MenuItems = append(ls.MenuItems, MenuItem{ Title: "Conseillers", Link: "/app/conseillers/", Active: menuState == membersMenu, Icon: "hero:outline/user-group", }) - } - if modules["diags"] != nil && modules["diags"].(bool) { + }*/ + /*if modules["diags"] != nil && modules["diags"].(bool) { ls.MenuItems = append(ls.MenuItems, MenuItem{ Title: "Diagnostics", Link: "/app/diags/", Active: menuState == diagsMenu, Icon: "hero:outline/document-text", }) - } + }*/ + return RenderState{ IconSet: icons.NewIconSet(iconset), Group: group, diff --git a/renderer/solidarity-transport.go b/renderer/solidarity-transport.go new file mode 100644 index 0000000..00e914b --- /dev/null +++ b/renderer/solidarity-transport.go @@ -0,0 +1,38 @@ +package renderer + +import ( + "net/http" + + mobilityaccountsstorage "git.coopgo.io/coopgo-platform/mobility-accounts/storage" +) + +const solidarityTransportMenu = "solidarity_transport" + +func (renderer *Renderer) SolidarityTransportOverview(w http.ResponseWriter, r *http.Request, drivers []mobilityaccountsstorage.Account) { + files := renderer.ThemeConfig.GetStringSlice("views.solidarity_transport.overview.files") + state := NewState(r, renderer.ThemeConfig, solidarityTransportMenu) + state.ViewState = map[string]any{ + "drivers": drivers, + } + + renderer.Render("solidarity transport overview", w, r, files, state) +} + +func (renderer *Renderer) SolidarityTransportCreateDriver(w http.ResponseWriter, r *http.Request) { + files := renderer.ThemeConfig.GetStringSlice("views.solidarity_transport.driver_create.files") + state := NewState(r, renderer.ThemeConfig, solidarityTransportMenu) + state.ViewState = map[string]any{} + + renderer.Render("solidarity transport driver creation", w, r, files, state) +} + +func (renderer *Renderer) SolidarityTransportDriverDisplay(w http.ResponseWriter, r *http.Request, driver mobilityaccountsstorage.Account) { + files := renderer.ThemeConfig.GetStringSlice("views.solidarity_transport.driver_display.files") + state := NewState(r, renderer.ThemeConfig, solidarityTransportMenu) + state.ViewState = map[string]any{ + "driver": driver, + "documents": []any{}, + } + + renderer.Render("solidarity transport driver creation", w, r, files, state) +} diff --git a/services/mobilityaccounts.go b/services/mobilityaccounts.go index 8ead583..57384d6 100755 --- a/services/mobilityaccounts.go +++ b/services/mobilityaccounts.go @@ -74,3 +74,32 @@ func (s *ServicesHandler) GetAccounts() (accounts []storage.Account, err error) return } + +func (s *ServicesHandler) GetAccountsInNamespace(namespace string) (accounts []storage.Account, err error) { + accounts = []storage.Account{} + request := &mobilityaccounts.GetAccountsRequest{ + Namespaces: []string{namespace}, + } + resp, err := s.GRPC.MobilityAccounts.GetAccounts(context.TODO(), request) + + if err == nil { + for _, v := range resp.Accounts { + a := v.ToStorageType() + accounts = append(accounts, a) + } + } + + return +} + +func (s *ServicesHandler) GetAccount(id string) (account storage.Account, err error) { + request := &mobilityaccounts.GetAccountRequest{ + Id: id, + } + resp, err := s.GRPC.MobilityAccounts.GetAccount(context.TODO(), request) + if err != nil { + return storage.Account{}, err + } + + return resp.Account.ToStorageType(), nil +} diff --git a/services/services.go b/services/services.go index f4c8249..50af6bb 100755 --- a/services/services.go +++ b/services/services.go @@ -2,10 +2,11 @@ package services import ( agenda "git.coopgo.io/coopgo-platform/agenda/grpcapi" + diags "git.coopgo.io/coopgo-platform/diags/grpcapi" fleets "git.coopgo.io/coopgo-platform/fleets/grpcapi" groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi" mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi" - diags "git.coopgo.io/coopgo-platform/diags/grpcapi" + "github.com/rs/zerolog/log" "github.com/spf13/viper" ) @@ -18,7 +19,7 @@ type GRPCServices struct { GroupsManagement groupsmanagement.GroupsManagementClient Fleets fleets.FleetsClient Agenda agenda.AgendaClient - Diags diags.DiagsClient + Diags diags.DiagsClient } func NewServicesHandler(cfg *viper.Viper) (*ServicesHandler, error) { @@ -27,32 +28,37 @@ func NewServicesHandler(cfg *viper.Viper) (*ServicesHandler, error) { groupsManagementDial = cfg.GetString("services.grpc.groupsmanagement.dial") fleetsDial = cfg.GetString("services.grpc.fleets.dial") agendaDial = cfg.GetString("services.grpc.agenda.dial") - diagsDial = cfg.GetString("services.grpc.diags.dial") + // diagsDial = cfg.GetString("services.grpc.diags.dial") ) mobilityAccounts, err := NewMobilityAccountService(mobilityAccountsDial) if err != nil { + log.Error().Err(err).Msg("Mobility Accounts service issue") return nil, err } groupsManagement, err := NewGroupsManagementService(groupsManagementDial) + log.Error().Err(err).Msg("Groups mgmt service issue") if err != nil { return nil, err } fleetsSvc, err := NewFleetsService(fleetsDial) + log.Error().Err(err).Msg("Fleets service issue") if err != nil { return nil, err } agendaSvc, err := NewAgendaService(agendaDial) + log.Error().Err(err).Msg("Agenda service issue") if err != nil { return nil, err } - diagsSvc, err := NewDiagsService(diagsDial) - if err != nil { - return nil, err - } + //diagsSvc, err := NewDiagsService(diagsDial) + // log.Error().Err(err).Msg("Mobility Accounts service issue") + //if err != nil { + // return nil, err + //} return &ServicesHandler{ GRPC: GRPCServices{ @@ -60,7 +66,7 @@ func NewServicesHandler(cfg *viper.Viper) (*ServicesHandler, error) { GroupsManagement: groupsManagement, Fleets: fleetsSvc, Agenda: agendaSvc, - Diags: diagsSvc, + // Diags: diagsSvc, }, }, nil } diff --git a/utils/sorting/solidarity-drivers.go b/utils/sorting/solidarity-drivers.go new file mode 100644 index 0000000..287b316 --- /dev/null +++ b/utils/sorting/solidarity-drivers.go @@ -0,0 +1,13 @@ +package sorting + +import ( + mobilityaccountsstorage "git.coopgo.io/coopgo-platform/mobility-accounts/storage" +) + +type SolidarityDriversByName []mobilityaccountsstorage.Account + +func (e SolidarityDriversByName) Len() int { return len(e) } +func (e SolidarityDriversByName) Less(i, j int) bool { + return e[i].Data["first_name"].(string) < e[j].Data["first_name"].(string) +} +func (e SolidarityDriversByName) Swap(i, j int) { e[i], e[j] = e[j], e[i] }