From 0c0a9d04962502ad4921861b740a2307705893ef Mon Sep 17 00:00:00 2001 From: Arnaud Delcasse Date: Tue, 17 Jan 2023 08:31:07 +0100 Subject: [PATCH] Admin stat vehicles --- handlers/application/administration.go | 27 ++++++++++ handlers/application/beneficiaries.go | 1 + .../{conseillers.go => members.go} | 8 +-- handlers/application/vehicles.go | 51 ++++++------------- handlers/auth/disconnect.go | 13 +++++ main.go | 9 ++-- renderer/conseillers.go | 24 --------- renderer/members.go | 24 +++++++++ renderer/renderer.go | 2 +- renderer/vehicles.go | 6 ++- services/fleets.go | 14 +++++ services/groupsmanagement.go | 17 +++++++ 12 files changed, 124 insertions(+), 72 deletions(-) rename handlers/application/{conseillers.go => members.go} (89%) create mode 100644 handlers/auth/disconnect.go delete mode 100644 renderer/conseillers.go create mode 100644 renderer/members.go diff --git a/handlers/application/administration.go b/handlers/application/administration.go index 1e3596d..7c38415 100644 --- a/handlers/application/administration.go +++ b/handlers/application/administration.go @@ -11,6 +11,8 @@ import ( "time" "git.coopgo.io/coopgo-apps/parcoursmob/utils/sorting" + fleets "git.coopgo.io/coopgo-platform/fleets/grpcapi" + "git.coopgo.io/coopgo-platform/fleets/storage" groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi" groupstorage "git.coopgo.io/coopgo-platform/groups-management/storage" accounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi" @@ -331,6 +333,31 @@ func (h *ApplicationHandler) AdministrationGroupInviteMember(w http.ResponseWrit return } +func (h ApplicationHandler) AdminStatVehicles(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 := []storage.Booking{} + + for _, b := range resp.Bookings { + booking := b.ToStorageType() + bookings = append(bookings, booking) + } + + sort.Sort(sorting.BookingsByStartdate(bookings)) + + vehicles, _ := h.services.GetVehiclesMap() + groups, _ := h.services.GetGroupsMap() + + h.Renderer.VehicleBookingsList(w, r, bookings, vehicles, groups) +} + func (h *ApplicationHandler) members() ([]*accounts.Account, error) { resp, err := h.services.GRPC.MobilityAccounts.GetAccounts(context.TODO(), &accounts.GetAccountsRequest{ Namespaces: []string{"parcoursmob"}, diff --git a/handlers/application/beneficiaries.go b/handlers/application/beneficiaries.go index 584645d..460140c 100644 --- a/handlers/application/beneficiaries.go +++ b/handlers/application/beneficiaries.go @@ -61,6 +61,7 @@ func (h *ApplicationHandler) BeneficiariesList(w http.ResponseWriter, r *http.Re func (h *ApplicationHandler) BeneficiaryCreate(w http.ResponseWriter, r *http.Request) { g := r.Context().Value(identification.GroupKey) if g == nil { + fmt.Println("Create beneficiary : could not find group") w.WriteHeader(http.StatusBadRequest) return } diff --git a/handlers/application/conseillers.go b/handlers/application/members.go similarity index 89% rename from handlers/application/conseillers.go rename to handlers/application/members.go index 8d8ec42..586b4e4 100644 --- a/handlers/application/conseillers.go +++ b/handlers/application/members.go @@ -21,7 +21,7 @@ type UserForm struct { Gender string `json:"gender"` } -func (h *ApplicationHandler) ConseillerDisplay(w http.ResponseWriter, r *http.Request) { +func (h *ApplicationHandler) MemberDisplay(w http.ResponseWriter, r *http.Request) { adm := strings.Split(r.URL.Path, "/") adminid := adm[3] @@ -37,10 +37,10 @@ func (h *ApplicationHandler) ConseillerDisplay(w http.ResponseWriter, r *http.Re return } - h.Renderer.ConseillerDisplay(w, r, resp.Account.ToStorageType()) + h.Renderer.MemberDisplay(w, r, resp.Account.ToStorageType()) } -func (h *ApplicationHandler) ConseillerUpdate(w http.ResponseWriter, r *http.Request) { +func (h *ApplicationHandler) MemberUpdate(w http.ResponseWriter, r *http.Request) { adm := strings.Split(r.URL.Path, "/") userID := adm[3] @@ -92,7 +92,7 @@ func (h *ApplicationHandler) ConseillerUpdate(w http.ResponseWriter, r *http.Req return } - h.Renderer.ConseillerUpdate(w, r, resp.Account.ToStorageType()) + h.Renderer.MemberUpdate(w, r, resp.Account.ToStorageType()) } func parseUserForm(r *http.Request) (map[string]any, error) { diff --git a/handlers/application/vehicles.go b/handlers/application/vehicles.go index 2deddad..eec2147 100644 --- a/handlers/application/vehicles.go +++ b/handlers/application/vehicles.go @@ -136,14 +136,7 @@ func (h ApplicationHandler) VehiclesSearch(w http.ResponseWriter, r *http.Reques } 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) + fmt.Println("Book") current_group, err := h.currentGroup(r) if err != nil { fmt.Println(err) @@ -151,24 +144,6 @@ func (h ApplicationHandler) Book(w http.ResponseWriter, r *http.Request) { return } - // 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) - current_user_token, current_user_claims, err := h.currentUser(r) if err != nil { fmt.Println(err) @@ -191,7 +166,7 @@ func (h ApplicationHandler) Book(w http.ResponseWriter, r *http.Request) { return } - r.ParseMultipartForm(10 * 1024 * 1024) + r.ParseMultipartForm(100 * 1024 * 1024) start := r.FormValue("startdate") end := r.FormValue("enddate") @@ -203,7 +178,7 @@ func (h ApplicationHandler) Book(w http.ResponseWriter, r *http.Request) { "booked_by": map[string]any{ "user": map[string]any{ "id": current_user_token.Subject, - "display_name": current_user_claims["display_name"], + "display_name": fmt.Sprintf("%s %s", current_user_claims["first_name"], current_user_claims["last_name"]), }, "group": map[string]any{ "id": current_group.ID, @@ -233,7 +208,6 @@ func (h ApplicationHandler) Book(w http.ResponseWriter, r *http.Request) { 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 == "" { @@ -282,9 +256,11 @@ func (h ApplicationHandler) Book(w http.ResponseWriter, r *http.Request) { fmt.Println(err) } else { for _, m := range members { - h.emailing.Send("fleets.bookings.creation_admin_alert", m.Data["email"].(string), map[string]string{ - "bookingid": booking.Id, - }) + if email, ok := m.Data["email"].(string); ok { + h.emailing.Send("fleets.bookings.creation_admin_alert", email, map[string]string{ + "bookingid": booking.Id, + }) + } } } @@ -314,9 +290,9 @@ func (h ApplicationHandler) VehicleBookingDisplay(w http.ResponseWriter, r *http beneficiaryresp, err := h.services.GRPC.MobilityAccounts.GetAccount(context.TODO(), beneficiaryrequest) if err != nil { - fmt.Println(err) - w.WriteHeader(http.StatusInternalServerError) - return + beneficiaryresp = &mobilityaccounts.GetAccountResponse{ + Account: &mobilityaccounts.Account{}, + } } grouprequest := &groupsmanagement.GetGroupRequest{ @@ -370,7 +346,10 @@ func (h ApplicationHandler) VehiclesBookingsList(w http.ResponseWriter, r *http. sort.Sort(sorting.BookingsByStartdate(bookings)) - h.Renderer.VehicleBookingsList(w, r, bookings) + vehicles, _ := h.services.GetVehiclesMap() + groups, _ := h.services.GetGroupsMap() + + h.Renderer.VehicleBookingsList(w, r, bookings, vehicles, groups) } func (h *ApplicationHandler) BookingDocumentDownload(w http.ResponseWriter, r *http.Request) { diff --git a/handlers/auth/disconnect.go b/handlers/auth/disconnect.go new file mode 100644 index 0000000..be3cc25 --- /dev/null +++ b/handlers/auth/disconnect.go @@ -0,0 +1,13 @@ +package auth + +import "net/http" + +func (h *AuthHandler) Disconnect(w http.ResponseWriter, r *http.Request) { + session, err := h.idp.SessionsStore.Get(r, "parcoursmob_session") + if err == nil { + session.Options.MaxAge = -1 + session.Save(r, w) + } + + http.Redirect(w, r, "/", http.StatusOK) +} diff --git a/main.go b/main.go index d4ef44f..154930a 100644 --- a/main.go +++ b/main.go @@ -61,6 +61,7 @@ func main() { r.PathPrefix("/public/").Handler(http.StripPrefix("/public/", http.FileServer(http.Dir(templates_public_dir)))) r.HandleFunc("/auth/onboarding", authHandler.Onboarding) + r.HandleFunc("/auth/disconnect", authHandler.Disconnect) r.HandleFunc("/auth/lost-password", authHandler.LostPasswordInit) r.HandleFunc("/auth/lost-password/recover", authHandler.LostPasswordRecover) r.HandleFunc("/auth/groups/", authHandler.Groups) @@ -84,6 +85,8 @@ func main() { application.HandleFunc("/beneficiaries/{beneficiaryid}/documents/{document}", applicationHandler.BeneficiaryDocumentDownload) application.HandleFunc("/beneficiaries/{beneficiaryid}/picture", applicationHandler.BeneficiaryPicture) application.HandleFunc("/members/{beneficiaryid}/picture", applicationHandler.BeneficiaryPicture) + application.HandleFunc("/members/{adminid}", applicationHandler.MemberDisplay) + application.HandleFunc("/members/{adminid}/update", applicationHandler.MemberUpdate) application.HandleFunc("/journeys/", applicationHandler.JourneysSearch) application.HandleFunc("/vehicles/", applicationHandler.VehiclesSearch) application.HandleFunc("/vehicles/bookings/", applicationHandler.VehiclesBookingsList) @@ -132,11 +135,7 @@ func main() { appAdmin.HandleFunc("/groups/{groupid}", applicationHandler.AdministrationGroupDisplay) appAdmin.HandleFunc("/groups/{groupid}/invite-admin", applicationHandler.AdministrationGroupInviteAdmin) appAdmin.HandleFunc("/groups/{groupid}/invite-member", applicationHandler.AdministrationGroupInviteMember) - - ///////////////////////////code page profile of admin /////////////////////////// - application.HandleFunc("/profile/{adminid}", applicationHandler.ConseillerDisplay) - application.HandleFunc("/profile/{adminid}/update", applicationHandler.ConseillerUpdate) - //TODO Secure with Middleware checking for modules + appAdmin.HandleFunc("/stats/vehicles", applicationHandler.AdminStatVehicles) fmt.Println("-> HTTP server listening on", address) diff --git a/renderer/conseillers.go b/renderer/conseillers.go deleted file mode 100644 index cdf6c1b..0000000 --- a/renderer/conseillers.go +++ /dev/null @@ -1,24 +0,0 @@ -package renderer - -import ( - "net/http" -) - -const conseillersMenu = "conseillers" - -func (renderer *Renderer) ConseillerDisplay(w http.ResponseWriter, r *http.Request, admins any) { - files := renderer.ThemeConfig.GetStringSlice("views.conseillers.display.files") - - state := NewState(r, renderer.ThemeConfig, conseillersMenu) - state.ViewState = map[string]any{ - "admins": admins, - } - renderer.Render("conseillers_list", w, r, files, state) -} - -func (renderer *Renderer) ConseillerUpdate(w http.ResponseWriter, r *http.Request, user any) { - files := renderer.ThemeConfig.GetStringSlice("views.conseillers.update.files") - state := NewState(r, renderer.ThemeConfig, conseillersMenu) - state.ViewState = user - renderer.Render("conseillers_update", w, r, files, state) -} diff --git a/renderer/members.go b/renderer/members.go new file mode 100644 index 0000000..a95bc72 --- /dev/null +++ b/renderer/members.go @@ -0,0 +1,24 @@ +package renderer + +import ( + "net/http" +) + +const membersMenu = "members" + +func (renderer *Renderer) MemberDisplay(w http.ResponseWriter, r *http.Request, admins any) { + files := renderer.ThemeConfig.GetStringSlice("views.members.display.files") + + state := NewState(r, renderer.ThemeConfig, membersMenu) + state.ViewState = map[string]any{ + "admins": admins, + } + renderer.Render("members_list", w, r, files, state) +} + +func (renderer *Renderer) MemberUpdate(w http.ResponseWriter, r *http.Request, user any) { + files := renderer.ThemeConfig.GetStringSlice("views.members.update.files") + state := NewState(r, renderer.ThemeConfig, membersMenu) + state.ViewState = user + renderer.Render("members_update", w, r, files, state) +} diff --git a/renderer/renderer.go b/renderer/renderer.go index c3d8141..013c422 100644 --- a/renderer/renderer.go +++ b/renderer/renderer.go @@ -244,7 +244,7 @@ func NewState(r *http.Request, themeConfig *viper.Viper, menuState string) Rende ls.MenuItems = append(ls.MenuItems, MenuItem{ Title: "Conseillers", Link: "/app/conseillers/", - Active: menuState == conseillersMenu, + Active: menuState == membersMenu, Icon: "hero:outline/user-group", }) } diff --git a/renderer/vehicles.go b/renderer/vehicles.go index ff78304..9f9ad11 100644 --- a/renderer/vehicles.go +++ b/renderer/vehicles.go @@ -67,11 +67,13 @@ func (renderer *Renderer) VehicleBookingDisplay(w http.ResponseWriter, r *http.R renderer.Render("vehicles search", w, r, files, state) } -func (renderer *Renderer) VehicleBookingsList(w http.ResponseWriter, r *http.Request, bookings []storage.Booking) { +func (renderer *Renderer) VehicleBookingsList(w http.ResponseWriter, r *http.Request, bookings []storage.Booking, vehiclesMap any, groupsMap any) { files := renderer.ThemeConfig.GetStringSlice("views.vehicles.bookings_list.files") state := NewState(r, renderer.ThemeConfig, vehiclesMenu) state.ViewState = map[string]any{ - "bookings": bookings, + "bookings": bookings, + "vehicles_map": vehiclesMap, + "groups_map": groupsMap, } renderer.Render("vehicles search", w, r, files, state) diff --git a/services/fleets.go b/services/fleets.go index 4e0b6cf..f0b9d89 100644 --- a/services/fleets.go +++ b/services/fleets.go @@ -52,3 +52,17 @@ func (s *ServicesHandler) GetBookings() (bookings []storage.Booking, err error) return } + +func (s *ServicesHandler) GetVehiclesMap() (vehicles map[string]storage.Vehicle, err error) { + vehicles = map[string]storage.Vehicle{} + + request := &fleets.GetVehiclesRequest{} + resp, err := s.GRPC.Fleets.GetVehicles(context.TODO(), request) + if err == nil { + for _, vehicle := range resp.Vehicles { + vehicles[vehicle.Id] = vehicle.ToStorageType() + } + } + + return +} diff --git a/services/groupsmanagement.go b/services/groupsmanagement.go index f5bf047..74a6736 100644 --- a/services/groupsmanagement.go +++ b/services/groupsmanagement.go @@ -1,7 +1,10 @@ package services import ( + "context" + groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi" + "git.coopgo.io/coopgo-platform/groups-management/storage" "google.golang.org/grpc" ) @@ -21,3 +24,17 @@ func NewGroupsManagementService(groupsManagementDial string) (*GroupsManagementS GroupsManagementClient: client, }, nil } + +func (s *ServicesHandler) GetGroupsMap() (groups map[string]storage.Group, err error) { + groups = map[string]storage.Group{} + + request := &groupsmanagement.GetGroupsRequest{} + resp, err := s.GRPC.GroupsManagement.GetGroups(context.TODO(), request) + if err == nil { + for _, group := range resp.Groups { + groups[group.Id] = group.ToStorageType() + } + } + + return +}