package handlers import ( "net/http" "time" "github.com/breakpilot/school-service/internal/models" "github.com/gin-gonic/gin" ) // Attendance Handlers // CreateAttendance creates an attendance record func (h *Handler) CreateAttendance(c *gin.Context) { var req models.CreateAttendanceRequest if err := c.ShouldBindJSON(&req); err != nil { respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error()) return } attendance, err := h.gradebookService.CreateAttendance(c.Request.Context(), &req) if err != nil { respondError(c, http.StatusInternalServerError, "Failed to create attendance: "+err.Error()) return } respondCreated(c, attendance) } // GetClassAttendance returns attendance for a class func (h *Handler) GetClassAttendance(c *gin.Context) { classID := c.Param("classId") startDateStr := c.Query("start_date") endDateStr := c.Query("end_date") var startDate, endDate *time.Time if startDateStr != "" { t, err := time.Parse("2006-01-02", startDateStr) if err == nil { startDate = &t } } if endDateStr != "" { t, err := time.Parse("2006-01-02", endDateStr) if err == nil { endDate = &t } } attendance, err := h.gradebookService.GetClassAttendance(c.Request.Context(), classID, startDate, endDate) if err != nil { respondError(c, http.StatusInternalServerError, "Failed to get attendance: "+err.Error()) return } respondSuccess(c, attendance) } // GetStudentAttendance returns attendance for a student func (h *Handler) GetStudentAttendance(c *gin.Context) { studentID := c.Param("studentId") attendance, err := h.gradebookService.GetStudentAttendance(c.Request.Context(), studentID) if err != nil { respondError(c, http.StatusInternalServerError, "Failed to get attendance: "+err.Error()) return } respondSuccess(c, attendance) } // DeleteAttendance deletes an attendance record func (h *Handler) DeleteAttendance(c *gin.Context) { attendanceID := c.Param("id") if err := h.gradebookService.DeleteAttendance(c.Request.Context(), attendanceID); err != nil { respondError(c, http.StatusInternalServerError, "Failed to delete attendance: "+err.Error()) return } c.JSON(http.StatusOK, gin.H{"message": "Attendance deleted"}) } // BulkCreateAttendance creates attendance for multiple students func (h *Handler) BulkCreateAttendance(c *gin.Context) { classID := c.Param("classId") var req struct { Date string `json:"date" binding:"required"` Records []struct { StudentID string `json:"student_id" binding:"required"` Status models.AttendanceStatus `json:"status" binding:"required"` Periods int `json:"periods"` Reason string `json:"reason"` } `json:"records" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error()) return } records := make([]struct { StudentID string Status models.AttendanceStatus Periods int Reason string }, len(req.Records)) for i, r := range req.Records { records[i] = struct { StudentID string Status models.AttendanceStatus Periods int Reason string }{ StudentID: r.StudentID, Status: r.Status, Periods: r.Periods, Reason: r.Reason, } } if err := h.gradebookService.BulkCreateAttendance(c.Request.Context(), classID, req.Date, records); err != nil { respondError(c, http.StatusInternalServerError, "Failed to create attendance: "+err.Error()) return } c.JSON(http.StatusOK, gin.H{"message": "Attendance created"}) } // Gradebook Entry Handlers // CreateGradebookEntry creates a gradebook entry func (h *Handler) CreateGradebookEntry(c *gin.Context) { var req models.CreateGradebookEntryRequest if err := c.ShouldBindJSON(&req); err != nil { respondError(c, http.StatusBadRequest, "Invalid request: "+err.Error()) return } entry, err := h.gradebookService.CreateGradebookEntry(c.Request.Context(), &req) if err != nil { respondError(c, http.StatusInternalServerError, "Failed to create entry: "+err.Error()) return } respondCreated(c, entry) } // GetGradebookEntries returns entries for a class func (h *Handler) GetGradebookEntries(c *gin.Context) { classID := c.Param("classId") entryTypeStr := c.Query("entry_type") startDateStr := c.Query("start_date") endDateStr := c.Query("end_date") var entryType *string if entryTypeStr != "" { entryType = &entryTypeStr } var startDate, endDate *time.Time if startDateStr != "" { t, err := time.Parse("2006-01-02", startDateStr) if err == nil { startDate = &t } } if endDateStr != "" { t, err := time.Parse("2006-01-02", endDateStr) if err == nil { endDate = &t } } entries, err := h.gradebookService.GetGradebookEntries(c.Request.Context(), classID, entryType, startDate, endDate) if err != nil { respondError(c, http.StatusInternalServerError, "Failed to get entries: "+err.Error()) return } respondSuccess(c, entries) } // GetStudentEntries returns gradebook entries for a student func (h *Handler) GetStudentEntries(c *gin.Context) { studentID := c.Param("studentId") entries, err := h.gradebookService.GetStudentEntries(c.Request.Context(), studentID) if err != nil { respondError(c, http.StatusInternalServerError, "Failed to get entries: "+err.Error()) return } respondSuccess(c, entries) } // DeleteGradebookEntry deletes a gradebook entry func (h *Handler) DeleteGradebookEntry(c *gin.Context) { entryID := c.Param("id") if err := h.gradebookService.DeleteGradebookEntry(c.Request.Context(), entryID); err != nil { respondError(c, http.StatusInternalServerError, "Failed to delete entry: "+err.Error()) return } c.JSON(http.StatusOK, gin.H{"message": "Entry deleted"}) }