package application import ( "context" "encoding/json" "fmt" "net/http" "sort" "strconv" "strings" "time" formvalidators "git.coopgo.io/coopgo-apps/parcoursmob/utils/form-validators" "git.coopgo.io/coopgo-apps/parcoursmob/utils/identification" "git.coopgo.io/coopgo-apps/parcoursmob/utils/sorting" agenda "git.coopgo.io/coopgo-platform/agenda/grpcapi" agendastorage "git.coopgo.io/coopgo-platform/agenda/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" "github.com/gorilla/mux" "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" ) type EventsForm struct { Name string `json:"name" validate:"required"` Type string `json:"type" validate:"required"` Description string `json:"description"` Address any `json:"address,omitempty"` Allday bool `json:"allday"` Startdate *time.Time `json:"startdate"` Enddate *time.Time `json:"enddate"` Starttime string `json:"starttime"` Endtime string `json:"endtime"` MaxSubscribers int `json:"max_subscribers"` } func (h *ApplicationHandler) AgendaHome(w http.ResponseWriter, r *http.Request) { resp, err := h.services.GRPC.Agenda.GetEvents(context.TODO(), &agenda.GetEventsRequest{ Namespaces: []string{"parcoursmob_dispositifs"}, Mindate: timestamppb.New(time.Now().Add(-24 * time.Hour)), }) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } responses := []agendastorage.Event{} groupids := []string{} for _, e := range resp.Events { groupids = append(groupids, e.Owners...) responses = append(responses, e.ToStorageType()) } sort.Sort(sorting.EventsByStartdate(responses)) groupsresp, err := h.services.GRPC.GroupsManagement.GetGroupsBatch(context.TODO(), &groupsmanagement.GetGroupsBatchRequest{ Groupids: groupids, }) groups := map[string]any{} if err == nil { for _, g := range groupsresp.Groups { groups[g.Id] = g.ToStorageType() } } h.Renderer.AgendaHome(w, r, responses, groups) } func (h *ApplicationHandler) AgendaCreateEvent(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { // Get current group g := r.Context().Value(identification.GroupKey) if g == nil { w.WriteHeader(http.StatusBadRequest) return } group := g.(storage.Group) eventForm, err := parseEventsForm(r) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusBadRequest) return } data, _ := structpb.NewStruct(map[string]any{ "address": eventForm.Address, }) request := &agenda.CreateEventRequest{ Event: &agenda.Event{ Namespace: "parcoursmob_dispositifs", Owners: []string{group.ID}, Type: eventForm.Type, Name: eventForm.Name, Description: eventForm.Description, Startdate: timestamppb.New(*eventForm.Startdate), Enddate: timestamppb.New(*eventForm.Enddate), Starttime: eventForm.Starttime, Endtime: eventForm.Endtime, Allday: eventForm.Allday, MaxSubscribers: int64(eventForm.MaxSubscribers), Data: data, Deleted: false, }, } resp, err := h.services.GRPC.Agenda.CreateEvent(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, fmt.Sprintf("/app/agenda/%s", resp.Event.Id), http.StatusFound) return } h.Renderer.AgendaCreateEvent(w, r) } func (h *ApplicationHandler) AgendaDisplayEvent(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) eventid := vars["eventid"] request := &agenda.GetEventRequest{ Id: eventid, } resp, err := h.services.GRPC.Agenda.GetEvent(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } grouprequest := &groupsmanagement.GetGroupRequest{ Id: resp.Event.Owners[0], } groupresp, err := h.services.GRPC.GroupsManagement.GetGroup(context.TODO(), grouprequest) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } subscribers := map[string]any{} accids := []string{} for _, v := range resp.Event.Subscriptions { accids = append(accids, v.Subscriber) } subscriberresp, err := h.services.GRPC.MobilityAccounts.GetAccountsBatch( context.TODO(), &mobilityaccounts.GetAccountsBatchRequest{ Accountids: accids, }, ) if err == nil { for _, sub := range subscriberresp.Accounts { subscribers[sub.Id] = sub.ToStorageType() } } g := r.Context().Value(identification.GroupKey) if g == nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } group := g.(storage.Group) accountids := []string{} for _, m := range group.Members { if !contains(resp.Event.Subscriptions, m) { accountids = append(accountids, m) } } accountresp, err := h.services.GRPC.MobilityAccounts.GetAccountsBatch( context.TODO(), &mobilityaccounts.GetAccountsBatchRequest{ Accountids: accountids, }, ) accounts := []any{} if err == nil { for _, acc := range accountresp.Accounts { accounts = append(accounts, acc) } } h.Renderer.AgendaDisplayEvent(w, r, resp.Event.ToStorageType(), groupresp.Group.ToStorageType(), subscribers, accounts) } func (h *ApplicationHandler) AgendaSubscribeEvent(w http.ResponseWriter, r *http.Request) { current_group, err := h.currentGroup(r) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } current_user_token, current_user_claims, err := h.currentUser(r) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } vars := mux.Vars(r) eventid := vars["eventid"] if err := r.ParseForm(); err != nil { fmt.Println(err) w.WriteHeader(http.StatusBadRequest) return } dis := fmt.Sprint(current_user_claims["first_name"]) + " " + fmt.Sprint(current_user_claims["last_name"]) subscriber := r.FormValue("subscriber") data := map[string]any{ "subscribed_by": map[string]any{ "user": map[string]any{ "id": current_user_token.Subject, "display_name": dis, }, "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 } request := &agenda.SubscribeEventRequest{ Eventid: eventid, Subscriber: subscriber, Data: datapb, } _, err = h.services.GRPC.Agenda.SubscribeEvent(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, fmt.Sprintf("/app/agenda/%s", eventid), http.StatusFound) } func parseEventsForm(r *http.Request) (*EventsForm, error) { if err := r.ParseForm(); err != nil { return nil, err } var startdate *time.Time var enddate *time.Time if r.PostFormValue("startdate") != "" { d, err := time.Parse("2006-01-02", r.PostFormValue("startdate")) if err != nil { return nil, err } startdate = &d } if r.PostFormValue("enddate") != "" { d, err := time.Parse("2006-01-02", r.PostFormValue("enddate")) if err != nil { return nil, err } enddate = &d } max_subscribers, err := strconv.Atoi(r.PostFormValue("max_subscribers")) if err != nil { return nil, err } formData := &EventsForm{ Name: r.PostFormValue("name"), Type: r.PostFormValue("type"), Description: r.PostFormValue("description"), Startdate: startdate, Enddate: enddate, Starttime: r.PostFormValue("starttime"), Endtime: r.PostFormValue("endtime"), MaxSubscribers: max_subscribers, } if r.PostFormValue("allday") == "true" { formData.Allday = true } 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 } return formData, nil } func contains(s []*agenda.Subscription, e string) bool { for _, a := range s { if a.Subscriber == e { return true } } return false } ///////////////////////////////Update Event///////////////////////////////////////// func (h *ApplicationHandler) AgendaUpdateEvent(w http.ResponseWriter, r *http.Request) { adm := strings.Split(r.URL.Path, "/") eventID := adm[3] request := &agenda.GetEventRequest{ Id: eventID, } resp, err := h.services.GRPC.Agenda.GetEvent(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } if r.Method == "POST" { g := r.Context().Value(identification.GroupKey) if g == nil { w.WriteHeader(http.StatusBadRequest) return } group := g.(storage.Group) eventForm, err := parseEventsForm(r) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusBadRequest) return } data, _ := structpb.NewStruct(map[string]any{ "address": eventForm.Address, }) request := &agenda.UpdateEventRequest{ Event: &agenda.Event{ Namespace: "parcoursmob_dispositifs", Id: eventID, Owners: []string{group.ID}, Type: eventForm.Type, Name: eventForm.Name, Description: eventForm.Description, Startdate: timestamppb.New(*eventForm.Startdate), Enddate: timestamppb.New(*eventForm.Enddate), Starttime: eventForm.Starttime, Endtime: eventForm.Endtime, Allday: eventForm.Allday, MaxSubscribers: int64(eventForm.MaxSubscribers), Data: data, Subscriptions: resp.Event.Subscriptions, }, } resp, err := h.services.GRPC.Agenda.UpdateEvent(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, fmt.Sprintf("/app/agenda/%s", resp.Event.Id), http.StatusFound) return } h.Renderer.AgendaUpdateEvent(w, r, resp.Event.ToStorageType()) } func (h *ApplicationHandler) AgendaDeleteEvent(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) eventID := vars["eventid"] request := &agenda.GetEventRequest{ Id: eventID, } resp, err := h.services.GRPC.Agenda.GetEvent(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } if r.Method == "POST" { request := &agenda.UpdateEventRequest{ Event: &agenda.Event{ Namespace: resp.Event.Namespace, Id: resp.Event.Id, Owners: resp.Event.Owners, Type: resp.Event.Type, Name: resp.Event.Name, Description: resp.Event.Description, Startdate: resp.Event.Startdate, Enddate: resp.Event.Enddate, Starttime: resp.Event.Starttime, Endtime: resp.Event.Endtime, Allday: resp.Event.Allday, MaxSubscribers: int64(resp.Event.MaxSubscribers), Data: resp.Event.Data, Subscriptions: resp.Event.Subscriptions, Deleted: true, }, } _, err := h.services.GRPC.Agenda.UpdateEvent(context.TODO(), request) if err != nil { fmt.Println(err) w.WriteHeader(http.StatusInternalServerError) return } http.Redirect(w, r, "/app/agenda/", http.StatusFound) return } h.Renderer.AgendaDeleteEvent(w, r, resp.Event.ToStorageType()) } // func contains[V string](s []V, e V) bool { // for _, a := range s { // if a == e { // return true // } // } // return false // }