package orm import ( "errors" "fmt" "github.com/jinzhu/gorm" "gogs.carducci-dante.gov.it/karmen/config" ) type Teacher struct { gorm.Model Credential Classes []*Class Subjects []*Subject Activities []*Activity Departments []*Department Issues []*Issue Hours int CurrHours int TheBossId uint } var ( selectDistinctTeachers = ` SELECT teachers.* FROM activities INNER JOIN teachers ON activities.teacher_id=teachers.id ` selectUniqueTeacherClasses = ` SELECT DISTINCT classes.* FROM activities INNER JOIN classes on classes.id=activities.class_id WHERE teacher_id=?` selectUniqueTeacherSubjects = ` SELECT DISTINCT subjects.* FROM activities INNER JOIN subjects on subjects.id=activities.subject_id WHERE activities.teacher_id=?` ) func GetTeacher(id string) (*Teacher, error) { var teacher Teacher if err := DB().Find(&teacher, id).Error; err != nil { return nil, err } if err := DB().Raw(selectUniqueTeacherClasses, id).Scan(&teacher.Classes).Error; err != nil { return nil, err } if err := DB().Raw(selectUniqueTeacherSubjects, id).Scan(&teacher.Subjects).Error; err != nil { return nil, err } if err := DB().Preload("Teacher").Preload("Subject").Where("teacher_id=?", id).Find(&teacher.Activities).Error; err != nil { return nil, err } return &teacher, nil } func GetTeachers() ([]*Teacher, error) { var teachers []*Teacher if err := DB().Order("surname,name").Find(&teachers).Error; err != nil { return nil, err } return teachers, nil } func GetTeachersAll() ([]*Teacher, error) { var teachers []*Teacher if err := DB().Order("surname,name").Find(&teachers).Error; err != nil { return nil, err } for _, teacher := range teachers { teacher.GetClasses() } for _, teacher := range teachers { teacher.GetSubjects() } return teachers, nil } func (t *Teacher) GetClasses() ([]*Class, error) { if err := DB().Raw(selectUniqueTeacherClasses, t.ID).Scan(&t.Classes).Error; err != nil { return nil, err } return t.Classes, nil } func (t *Teacher) GetSubjects() ([]*Subject, error) { if err := DB().Raw(selectUniqueTeacherSubjects, t.ID).Scan(&t.Subjects).Error; err != nil { return nil, err } return t.Subjects, nil } func (t *Teacher) GetActivitiesByClass(id string) ([]*Activity, error) { if err := DB().Preload("Teacher").Where("class_id=? AND teacher_id=?", id, t.ID).Find(&t.Activities).Error; err != nil { return nil, err } return t.Activities, nil } func (t *Teacher) Create(db *gorm.DB, record map[string]interface{}) error { result := new(Teacher) if name := record["name"]; name == nil { return errors.New("Error in creating teacher: field name is empty") } else { result.Name = name.(string) } if surname := record["surname"]; surname == nil { return errors.New("Error in creating teacher: field surname is empty") } else { result.Surname = surname.(string) } db.Create(result) return nil } func (t *Teacher) CalcHours(tx *gorm.DB) { var ( activities []Activity sum int ) if err := tx.Model(t).Related(&activities).Error; err != nil { panic(err) } for _, a := range activities { sum += a.Hours } if err := tx.Model(t).Update("curr_hours", sum).Error; err != nil { panic(err) } } func (t Teacher) GetSubjectsByClassID(classID uint) []Subject { var ( activities []Activity subjects []Subject ) if err := DB().Model(t).Preload("Subject").Related(&activities).Error; err != nil { panic(err) } for _, a := range activities { if a.ClassID == classID { subjects = append(subjects, a.Subject) } } return subjects } func (t *Teacher) IsCoordinator() ([]*Class, error) { var output []*Class classes, err := t.GetClasses() if err != nil { return nil, err } for _, class := range classes { if class.CoordinatorID == t.ID { output = append(output, class) } } return output, nil } func (t *Teacher) IsMinuter() ([]*Class, error) { var output []*Class classes, err := t.GetClasses() if err != nil { return nil, err } for _, class := range classes { if class.MinuterID == t.ID { output = append(output, class) } } return output, nil } func (t *Teacher) IsCoordinatorInClass(className string) bool { var classes []Class if err := DB().Model(t).Where("name = ?", className).Related(&classes, "Classes").Error; err != nil { panic(err) } for _, class := range classes { if class.CoordinatorID == t.ID { return true } } return false } func (t Teacher) HasClass(name string) bool { var classes []Class if err := DB().Model(t).Related(&classes, "Classes").Error; err != nil { panic(err) } for _, class := range classes { if class.Name == name { return true } } return false } func (t Teacher) HasSubject(name string) bool { var subjects []Subject if err := DB().Model(t).Related(&subjects, "Subjects").Error; err != nil { panic(err) } for _, subject := range subjects { if subject.Name == name { return true } } return false } func (t Teacher) HasSubjectInClass(subjectName string, className string) bool { var classes []Class if err := DB().Where("name = ?", className).Find(&classes).Error; err != nil { panic(err) } subjects := t.GetSubjectsByClassID(classes[0].ID) for _, s := range subjects { if s.Name == subjectName { return true } } return false } // func (t *Teacher) CheckForIssues(tx *gorm.DB) { // if t.CurrHours != t.Hours { // var issues []Issue // if err := tx.Where("type = ? and reported = ?", IssueTeacherHours, 1).Model(t).Related(&issues).Error; err != nil { // panic(err) // } // if len(issues) == 0 { // desc := fmt.Sprintf( // "Le ore relative alla cattedra del docente %s %s non coincidono con la somma delle ore delle sue attività (%d/%d)", // t.Surname, t.Name, // t.CurrHours, t.Hours) // issue := Issue{ // Type: IssueTeacherHours, // Description: desc, // Reported: true, // TeacherID: t.ID, // } // if err := tx.Save(&issue).Error; err != nil { // panic(err) // } // } else { // issues[0].Description = fmt.Sprintf( // "Le ore relative alla cattedra del docente %s %s non coincidono con la somma delle ore delle sue attività (%d/%d)", // t.Surname, t.Name, // t.CurrHours, t.Hours) // if err := tx.Save(&issues[0]).Error; err != nil { // panic(err) // } // } // } else { // var issues []Issue // if err := tx.Where("type = ? and reported = ?", IssueTeacherHours, 1).Model(t).Related(&issues).Error; err != nil { // panic(err) // } // if len(issues) > 0 { // if err := tx.Delete(&issues[0]).Error; err != nil { // panic(err) // } // } // } // } func (t *Teacher) generateCredential() error { t.Username = t.GenerateUsername() t.Password = t.GenerateSaltedPassword(t.Username) t.Email = fmt.Sprintf("%s@%s", t.Username, config.Config.Domain) return nil } func (t *Teacher) CheckForIssues(tx *gorm.DB) { // issue := newTeacherMaxHoursIssue(t) // if t.CurrHours != t.Hours { // issue.createIfNotExist(t) // } else { // issue.resetIfExist(t) // } } func (t *Teacher) BeforeCreate(tx *gorm.DB) error { // FIXME: should re-generate only if related columns are modified t.generateCredential() return nil } func (t *Teacher) BeforeUpdate(tx *gorm.DB) error { // FIXME: should re-generate only if related columns are modified t.generateCredential() return nil } // func (t *Teacher) AfterUpdate(tx *gorm.DB) error { // // FIXME: should re-generate only if related columns are modified // t.generateCredential() // // t.CheckForIssues(tx) // return nil // } func (t *Teacher) AfterDelete(tx *gorm.DB) error { var issues []Issue if err := tx.Where("type = ?", IssueTeacherHours).Model(t).Related(&issues).Error; err != nil { panic(err) } if err := tx.Delete(&issues).Error; err != nil { panic(err) } return nil }