oef/orm/school.go

344 lines
7.9 KiB
Go
Raw Normal View History

2019-12-03 12:21:28 +01:00
package orm
import (
2019-12-03 15:24:01 +01:00
"fmt"
2019-12-03 12:21:28 +01:00
"net/http"
"os"
2019-12-03 12:21:28 +01:00
"strings"
"time"
2019-12-03 12:21:28 +01:00
"git.andreafazzi.eu/andrea/oef/errors"
"git.andreafazzi.eu/andrea/oef/mail"
2019-12-03 12:21:28 +01:00
"git.andreafazzi.eu/andrea/oef/renderer"
"github.com/dchest/captcha"
2019-12-03 12:21:28 +01:00
"github.com/jinzhu/gorm"
)
2020-01-10 12:07:11 +01:00
type RegionID uint
var mailBody = `
Spettabile {{.NameForMail}},
2022-12-07 09:20:46 +01:00
grazie per l'interesse manifestato per i Campionati Italiani di Economia e Finanza.
Di seguito riportiamo le credenziali di accesso tramite le quali potrà gestire le iscrizioni dei suoi studenti alla competizione (Fase Regionale).
username: {{.Username}}
password: {{.Password}}
Per accedere alla pagina di login occorrerà seguire questo link
https://piattaforma.oief.it/
ed inserire le credenziali riportate sopra (si consiglia di effettuare un copia/incolla).
2020-01-27 14:40:34 +01:00
Questa mail è stata generata da un sistema automatico, si prega di non rispondere.
2020-01-27 11:43:56 +01:00
Cordialmente,
2022-12-07 09:20:46 +01:00
Lo Staff dei CEF.
`
2019-12-03 12:21:28 +01:00
type School struct {
gorm.Model
2020-01-27 08:35:37 +01:00
UserModifier
Name string
2019-12-09 11:15:42 +01:00
Address string
Email string
Code string
2019-12-07 08:58:30 +01:00
EmailSentDate time.Time
2019-12-03 12:21:28 +01:00
SchoolContactPersonLastname string
SchoolContactPersonFirstname string
SchoolContactPersonEmail string
SchoolContactPersonTelephoneNumber string
ContestDirectorLastname string
ContestDirectorFirstname string
2022-02-03 16:20:39 +01:00
PreviousParticipantsSelection uint
2019-12-09 11:15:42 +01:00
UserID uint
2020-01-10 12:07:11 +01:00
RegionID RegionID `schema:"region_id"`
2019-12-03 12:21:28 +01:00
2019-12-09 11:15:42 +01:00
Region *Region
2019-12-03 12:21:28 +01:00
User *User
2020-01-28 14:36:31 +01:00
Participants []*Participant
2019-12-09 11:15:42 +01:00
SelectedRegion map[uint]string `gorm:"-"`
AllRegions []*Region `gorm:"-"`
2022-03-15 11:18:52 +01:00
CaptchaID string `gorm:"-" schema:"-"`
CaptchaSolution string `gorm:"-" schema:"-"`
mailSender *mail.MailSender
2019-12-03 12:21:28 +01:00
}
2020-01-10 12:07:11 +01:00
func (id *RegionID) UnmarshalCSV(csv string) error {
*id = RegionID(regionsMap[strings.Title(strings.ToLower(csv))])
return nil
}
2019-12-03 12:21:28 +01:00
func (model *School) GetID() uint { return model.ID }
func (model *School) String() string {
2019-12-03 15:24:01 +01:00
return fmt.Sprintf("%s (%s)", model.Code, model.Name)
2019-12-03 12:21:28 +01:00
}
func (model *School) NameForMail() string {
return fmt.Sprintf("%s (%s)", model.Name, model.Code)
}
func (model *School) Username() string {
2019-12-03 12:21:28 +01:00
return strings.ToUpper(model.Code)
}
func (model *School) Password() string {
return model.User.Password
}
func (model *School) To() string {
return model.Email
}
func (model *School) Cc() string {
return model.SchoolContactPersonEmail
}
2020-01-27 11:43:56 +01:00
func (model *School) SetCreatorID(id uint) {
model.CreatorID = id
}
func (model *School) SetCreatorRole(role string) {
model.CreatorRole = role
}
func (model *School) SetCreatorIP(addr string) {
model.CreatorIP = addr
}
func (model *School) SetUpdaterID(id uint) {
model.UpdaterID = id
}
func (model *School) SetUpdaterRole(role string) {
model.UpdaterRole = role
}
func (model *School) SetUpdaterIP(addr string) {
model.UpdaterIP = addr
}
func (model *School) exists(db *Database) (*User, error) {
2019-12-03 12:21:28 +01:00
var user User
if err := db._db.First(&user, &User{Username: model.Username()}).Error; err != nil && err != gorm.ErrRecordNotFound {
2019-12-03 12:21:28 +01:00
return nil, err
} else if err == gorm.ErrRecordNotFound {
return nil, nil
}
return &user, nil
}
func (model *School) BeforeSave(tx *gorm.DB) error {
var user User
if err := tx.FirstOrCreate(&user, &User{
Username: model.Username(),
2019-12-03 12:21:28 +01:00
Role: "school",
}).Error; err != nil {
return err
}
model.UserID = user.ID
// School code is always uppercase
model.Code = strings.ToUpper(model.Code)
2019-12-03 12:21:28 +01:00
return nil
}
func (model *School) AfterDelete(tx *gorm.DB) error {
if err := tx.Unscoped().Delete(model.User).Error; err != nil {
return err
}
return nil
}
func (model *School) AfterCreate(tx *gorm.DB) error {
if err := tx.Preload("User").First(model).Error; err != nil {
return err
}
if err := model.mailSender.SendSubscriptionMail(model); err != nil {
return err
}
if err := tx.Model(model).Update("email_sent_date", time.Now()).Error; err != nil {
return err
}
return nil
}
func (model *School) Create(db *Database, args map[string]string, w http.ResponseWriter, r *http.Request) (interface{}, error) {
2019-12-03 12:21:28 +01:00
if r.Method == "GET" {
school := new(School)
2019-12-09 11:15:42 +01:00
if err := db._db.Find(&school.AllRegions).Error; err != nil {
2019-12-09 11:15:42 +01:00
return nil, err
}
2019-12-03 12:21:28 +01:00
return school, nil
} else {
if isSubscriber(r) && os.Getenv("OEF_REGRESSION_TEST") != "1" {
if !captcha.VerifyString(r.FormValue("CaptchaID"), r.FormValue("CaptchaSolution")) {
return nil, errors.WrongCaptcha
}
}
2019-12-03 12:21:28 +01:00
school := new(School)
err := renderer.Decode(school, r)
if err != nil {
return nil, err
}
// Check if this user already exists in the users table.
if user, err := school.exists(db); err == nil && user != nil {
if err := db._db.Where("user_id = ?", user.ID).Find(&school).Error; err != nil {
2019-12-03 12:21:28 +01:00
return nil, err
}
2020-01-27 08:35:37 +01:00
return nil, errors.SchoolExists
2019-12-03 12:21:28 +01:00
} else if err != nil {
return nil, err
}
2020-01-27 11:43:56 +01:00
WriteCreator(r, school)
school.mailSender = mail.NewMailSender(db.Config, mailBody)
school, err = CreateSchool(db, school)
2019-12-03 12:21:28 +01:00
if err != nil {
return nil, err
}
return school, nil
}
}
func (model *School) Read(db *Database, args map[string]string, w http.ResponseWriter, r *http.Request) (interface{}, error) {
2019-12-03 12:21:28 +01:00
var school School
id := args["id"]
if isSchool(r) && id != getModelIDFromToken(r) {
return nil, errors.NotAuthorized
}
2020-01-28 14:36:31 +01:00
if err := db._db.
Preload("Participants").
Preload("Participants.Category").
Preload("Region").
Preload("User").
Preload("Creator").
Preload("Updater").
First(&school, id).Error; err != nil {
2019-12-03 12:21:28 +01:00
return nil, err
}
return &school, nil
}
func (model *School) ReadAll(db *Database, args map[string]string, w http.ResponseWriter, r *http.Request) (interface{}, error) {
2019-12-03 12:21:28 +01:00
var schools []*School
2020-01-28 14:36:31 +01:00
if err := db._db.
2020-01-28 15:04:28 +01:00
Preload("Participants").
2020-01-28 14:36:31 +01:00
Preload("Participants.Category").
Preload("Region").
2020-01-28 14:36:31 +01:00
Order("code").
Find(&schools).Error; err != nil {
2019-12-03 12:21:28 +01:00
return nil, err
}
return schools, nil
}
func (model *School) Update(db *Database, args map[string]string, w http.ResponseWriter, r *http.Request) (interface{}, error) {
2019-12-03 12:21:28 +01:00
if r.Method == "GET" {
result, err := model.Read(db, args, w, r)
2019-12-03 12:21:28 +01:00
if err != nil {
return nil, err
}
school := result.(*School)
if err := db._db.Find(&school.AllRegions).Error; err != nil {
2019-12-09 11:15:42 +01:00
return nil, err
}
2019-12-03 12:21:28 +01:00
2019-12-09 11:15:42 +01:00
school.SelectedRegion = make(map[uint]string)
2020-01-10 12:07:11 +01:00
school.SelectedRegion[uint(school.RegionID)] = "selected"
2019-12-03 12:21:28 +01:00
return school, nil
} else {
school, err := model.Read(db, args, w, r)
2019-12-03 12:21:28 +01:00
if err != nil {
return nil, err
}
err = renderer.Decode(school, r)
if err != nil {
return nil, err
}
// Check if the modified school code belong to an existing school.
if user, err := school.(*School).exists(db); err == nil && user != nil {
2019-12-03 12:21:28 +01:00
if user.ID != school.(*School).UserID {
2020-01-27 08:35:37 +01:00
return nil, errors.SchoolExists
2019-12-03 12:21:28 +01:00
}
} else if err != nil {
return nil, err
}
2020-01-27 11:43:56 +01:00
WriteUpdater(r, school.(*School))
2019-12-07 08:58:30 +01:00
_, err = SaveSchool(db, school)
2019-12-03 12:21:28 +01:00
if err != nil {
return nil, err
}
school, err = model.Read(db, args, w, r)
2019-12-03 12:21:28 +01:00
if err != nil {
return nil, err
}
return school.(*School), nil
}
}
func (model *School) Delete(db *Database, args map[string]string, w http.ResponseWriter, r *http.Request) (interface{}, error) {
school, err := model.Read(db, args, w, r)
2019-12-03 12:21:28 +01:00
if err != nil {
return nil, err
}
if err := db._db.Unscoped().Delete(school.(*School)).Error; err != nil {
2019-12-03 12:21:28 +01:00
return nil, err
}
return school.(*School), nil
}
func CreateSchool(db *Database, school *School) (*School, error) {
if err := db._db.Create(school).Error; err != nil {
2019-12-03 12:21:28 +01:00
return nil, err
}
return school, nil
}
func SaveSchool(db *Database, school interface{}) (interface{}, error) {
if err := db._db.Omit("Region", "Creator", "Updater").Save(school).Error; err != nil {
2019-12-03 12:21:28 +01:00
return nil, err
}
return school, nil
}
2019-12-09 14:18:31 +01:00
func (model *School) HasCategory(db *Database, participant *Participant) (bool, error) {
2019-12-09 14:18:31 +01:00
var participants []*Participant
2019-12-09 18:07:43 +01:00
2020-01-28 15:04:28 +01:00
if err := db._db.
Where("category_id = ? AND school_id = ? AND id <> ?", participant.CategoryID, model.ID, participant.ID).
Find(&participants).Error; err != nil {
2019-12-09 14:18:31 +01:00
return false, err
}
return len(participants) > 0, nil
}