package db import ( "strconv" "strings" "time" "server/internal/models" "gorm.io/gorm" ) func scheduleDayIndex(t time.Time) int { wd := t.Weekday() if wd == time.Sunday { return 6 } return int(wd) - 1 } func parseTimeMinutes(tStr string) int { parts := strings.Split(tStr, ":") if len(parts) != 2 { return 0 } hours, _ := strconv.Atoi(parts[0]) mins, _ := strconv.Atoi(parts[1]) return hours*60 + mins } func studentClassIDs(db *gorm.DB, studentRkID int64) []int64 { var classRkIDs []int64 _ = db.Model(&models.ClassStudent{}). Where("student_rk_id = ?", studentRkID). Pluck("class_rk_id", &classRkIDs).Error return classRkIDs } // FindActiveClassAndPeriodForStudent trả về lớp + ca đang trong khung giờ học. func FindActiveClassAndPeriodForStudent(db *gorm.DB, studentRkID int64) (int64, int) { classRkIDs := studentClassIDs(db, studentRkID) if len(classRkIDs) == 0 { return 0, 0 } var schedules []models.ClassSchedule if err := db.Where("class_rk_id IN ? AND is_active = ?", classRkIDs, true).Find(&schedules).Error; err != nil || len(schedules) == 0 { return classRkIDs[0], 1 } now := time.Now() day := scheduleDayIndex(now) currMin := now.Hour()*60 + now.Minute() for _, s := range schedules { if s.DayOfWeek != day { continue } startMin := parseTimeMinutes(s.StartTime) endMin := parseTimeMinutes(s.EndTime) if currMin >= startMin && currMin <= endMin { period := s.Period if period < 1 { period = 1 } return s.ClassRkID, period } } return classRkIDs[0], 1 } func FindActiveClassForStudent(db *gorm.DB, studentRkID int64) int64 { classID, _ := FindActiveClassAndPeriodForStudent(db, studentRkID) return classID } // ResolveSessionPeriodForDate lấy ca theo ngày (dùng khi xem nhật ký quá khứ). func ResolveSessionPeriodForDate(db *gorm.DB, classRkID int64, date string, period int) int { if period > 0 { return period } day, err := time.Parse("2006-01-02", date) if err != nil { return 1 } var slots []models.ClassSchedule if err := db.Where("class_rk_id = ? AND day_of_week = ? AND is_active = ?", classRkID, scheduleDayIndex(day), true). Order("period asc, start_time asc").Find(&slots).Error; err != nil || len(slots) == 0 { return 1 } if slots[0].Period > 0 { return slots[0].Period } return 1 }