From d075cc0815fcda0d82ce373134e15e390bc5cda4 Mon Sep 17 00:00:00 2001 From: anirudh Date: Sat, 21 Oct 2023 20:57:52 +0530 Subject: [PATCH] feat(meeting): :sparkles: get upcoming user meetings --- controllers/meeting.controller.go | 15 ++++++++++++ mocks/meeting.service_mocks.go | 13 +++++++++++ models/meeting.model.go | 5 ++++ routers/index.go | 21 +++++++++-------- services/meeting.service.go | 38 +++++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 10 deletions(-) diff --git a/controllers/meeting.controller.go b/controllers/meeting.controller.go index 41db58d..e60dd74 100644 --- a/controllers/meeting.controller.go +++ b/controllers/meeting.controller.go @@ -259,3 +259,18 @@ func (mc *MeetingController) GetAttendanceForMeeting(c *gin.Context) { c.JSON(http.StatusOK, attendance) } + +// UpcomingUserMeetings retrieves upcoming meetings for a user. +func (mc *MeetingController) UpcomingUserMeetings(c *gin.Context) { + currentUser, _ := c.Get("user") + userID := currentUser.(*models.User).ID + + // Call the meeting service to get upcoming meetings + meetings, err := mc.meetingService.UpcomingUserMeetings(userID) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Failed to get upcoming meetings", "error": err.Error()}) + return + } + + c.JSON(http.StatusOK, meetings) +} diff --git a/mocks/meeting.service_mocks.go b/mocks/meeting.service_mocks.go index d2106ee..51a6890 100644 --- a/mocks/meeting.service_mocks.go +++ b/mocks/meeting.service_mocks.go @@ -105,6 +105,14 @@ func (m *MockMeetingService) GetAttendanceForMeeting(meetingID, teamID uint) ([] return ret0, ret1 } +// UpcomingUserMeetings mocks the UpcomingUserMeetings method. +func (m *MockMeetingService) UpcomingUserMeetings(userID uint) ([]models.UserUpcomingMeetingsListResponse, error) { + ret := m.ctrl.Call(m, "UpcomingUserMeetings", userID) + ret0, _ := ret[0].([]models.UserUpcomingMeetingsListResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + // MockMeetingServiceMockRecorder is a mock recorder for MockMeetingService. type MockMeetingServiceMockRecorder struct { mock *MockMeetingService @@ -158,3 +166,8 @@ func (mr *MockMeetingServiceMockRecorder) MarkAttendanceForUserInMeeting(userID, func (mr *MockMeetingServiceMockRecorder) GetAttendanceForMeeting(meetingID, teamID uint) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAttendanceForMeeting", reflect.TypeOf((*MockMeetingService)(nil).GetAttendanceForMeeting), meetingID, teamID) } + +// UpcomingUserMeetings mocks the UpcomingUserMeetings method. +func (mr *MockMeetingServiceMockRecorder) UpcomingUserMeetings(userID uint) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpcomingUserMeetings", reflect.TypeOf((*MockMeetingService)(nil).UpcomingUserMeetings), userID) +} diff --git a/models/meeting.model.go b/models/meeting.model.go index f43fa37..04c27a0 100644 --- a/models/meeting.model.go +++ b/models/meeting.model.go @@ -77,3 +77,8 @@ type MeetingAttendanceListResponse struct { OnTime bool User User } + +type UserUpcomingMeetingsListResponse struct { + Meeting Meeting + Team Team +} diff --git a/routers/index.go b/routers/index.go index a736817..107c740 100644 --- a/routers/index.go +++ b/routers/index.go @@ -19,10 +19,16 @@ func RegisterRoutes(route *gin.Engine) { v1 := route.Group("/v1") + meetingRepo := repository.NewMeetingRepository() + meetingService := services.NewMeetingService(meetingRepo) + meetingController := controllers.NewMeetingController(meetingService) + + userController := controllers.NewUserController() + + teamController := controllers.NewTeamController() + auth := v1.Group("/auth") // Create an /auth/ group { - userController := controllers.NewUserController() // Create an instance of the UserController - // Define the user registration route auth.POST("/register", userController.RegisterUser) @@ -62,8 +68,6 @@ func RegisterRoutes(route *gin.Engine) { user := v1.Group("/user") { - userController := controllers.NewUserController() - // Get my details user.GET("/me", middleware.BaseAuthMiddleware(), userController.GetMyDetails) @@ -73,14 +77,15 @@ func RegisterRoutes(route *gin.Engine) { // Get my teams, query ?role=member/admin/super_admin user.GET("/me/teams", middleware.BaseAuthMiddleware(), userController.GetMyTeams) + // Get my upcoming meetings + user.GET("/me/meetings", middleware.BaseAuthMiddleware(), meetingController.UpcomingUserMeetings) + // Get my team requests, query ?status=accepted/rejected/pending user.GET("/me/requests", middleware.BaseAuthMiddleware(), userController.GetMyRequests) } team := v1.Group("/team") { - teamController := controllers.NewTeamController() - // Get all unprotected teams team.GET("/", middleware.BaseAuthMiddleware(), teamController.GetUnprotectedTeams) @@ -123,10 +128,6 @@ func RegisterRoutes(route *gin.Engine) { // handover superadmin to another member team.PATCH("/:teamID/handover", middleware.BaseAuthMiddleware(), middleware.AuthorizeSuperAdmin(), teamController.HandoverTeamSuperAdmin) - meetingRepo := repository.NewMeetingRepository() - meetingService := services.NewMeetingService(meetingRepo) - meetingController := controllers.NewMeetingController(meetingService) - // /:teamID/meetings to create one, by super admin team.POST("/:teamID/meetings", middleware.BaseAuthMiddleware(), middleware.AuthorizeSuperAdmin(), meetingController.CreateMeeting) diff --git a/services/meeting.service.go b/services/meeting.service.go index eea08a1..f4f5f7c 100644 --- a/services/meeting.service.go +++ b/services/meeting.service.go @@ -30,6 +30,7 @@ type MeetingServiceInterface interface { DeleteMeetingByID(meetingID uint, teamid uint) error MarkAttendanceForUserInMeeting(userID, meetingID uint, attendanceTime time.Time, teamid uint) (bool, error) GetAttendanceForMeeting(meetingID, teamID uint) ([]models.MeetingAttendanceListResponse, error) + UpcomingUserMeetings(userID uint) ([]models.UserUpcomingMeetingsListResponse, error) } // CreateMeeting creates a new meeting in the database. @@ -293,4 +294,41 @@ func (ms *MeetingService) GetAttendanceForMeeting(meetingID, teamID uint) ([]mod return attendanceResponse, nil } +// UpcomingUserMeetings retrieves all upcoming meetings for a user. +func (ms *MeetingService) UpcomingUserMeetings(userID uint) ([]models.UserUpcomingMeetingsListResponse, error) { + // Get all teams for the user + teamMemberRepo := repository.NewTeamMemberRepository() + teamRepo := repository.NewTeamRepository() + teams, err := teamMemberRepo.GetTeamMembersByUserID(userID) + if err != nil { + return nil, err + } + + // Get all meetings for each team, overall ascending order by start time + var meetings []models.UserUpcomingMeetingsListResponse + for _, team := range teams { + teamMeetings, err := ms.GetMeetingsByTeamID(team.TeamID, "upcoming", "asc") + if err != nil { + return nil, err + } + teamDetails, err := teamRepo.GetTeamByID(team.TeamID) + if err != nil { + return nil, err + } + for _, meeting := range teamMeetings { + meetings = append(meetings, models.UserUpcomingMeetingsListResponse{ + Meeting: meeting, + Team: teamDetails, + }) + } + } + + // order meetings by start time + sort.Slice(meetings, func(i, j int) bool { + return meetings[i].Meeting.StartTime.Before(meetings[j].Meeting.StartTime) + }) + + return meetings, nil +} + // GetMeetingStatsByMeetingID retrieves meeting stats for a given meeting ID. Stats: total attendance, on time attendance, late attendance.