From 13f22aabbd2f118abe93cf55d8d0bbd2d7d49001 Mon Sep 17 00:00:00 2001 From: Andrea Fazzi Date: Mon, 9 Dec 2019 14:18:31 +0100 Subject: [PATCH] Add support for custom error templates --- errors/errors.go | 17 ++++++++++-- i18n/i18n.go | 3 +++ main.go | 4 +++ orm/participant.go | 33 ++++++++++++++++++++++-- orm/school.go | 10 +++++++ renderer/renderer.go | 22 ++++++++++++---- templates/error_category_exists.html.tpl | 11 ++++++++ templates/participants.html.tpl | 4 ++- templates/participants_show.html.tpl | 4 ++- templates/schools_add_update.html.tpl | 14 +++++++++- templates/schools_show.html.tpl | 4 +++ 11 files changed, 114 insertions(+), 12 deletions(-) create mode 100644 templates/error_category_exists.html.tpl diff --git a/errors/errors.go b/errors/errors.go index 584aae79..c9f12026 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -6,7 +6,20 @@ import ( "git.andreafazzi.eu/andrea/oef/i18n" ) +type Error struct { + TemplateName string + Err error +} + +func (e *Error) Error() string { + return e.Err.Error() +} + var ( - RecordExists = errors.New("Record already exists!") - NotAuthorized = errors.New(i18n.Authorization["notAuthorized"]["it"]) + RecordExists = errors.New("Record already exists!") + NotAuthorized = errors.New(i18n.Authorization["notAuthorized"]["it"]) + CategoryExists = &Error{ + TemplateName: "error_category_exists", + Err: errors.New(i18n.FlashMessages["categoryExists"]["it"]), + } ) diff --git a/i18n/i18n.go b/i18n/i18n.go index ef0b1606..05a08166 100644 --- a/i18n/i18n.go +++ b/i18n/i18n.go @@ -8,6 +8,9 @@ var ( "schoolExists": map[string]string{ "it": "Una scuola con questo codice meccanografico è già presente nella base dati!", }, + "categoryExists": map[string]string{ + "it": "Un partecipante della stessa categoria è già stato iscritto dalla scuola.", + }, "notAuthorized": map[string]string{ "it": "L'utente non dispone delle autorizzazioni necessarie a visualizzare questa pagina.", }, diff --git a/main.go b/main.go index 9cb4eaa8..a375ee21 100644 --- a/main.go +++ b/main.go @@ -34,6 +34,7 @@ var ( &orm.Response{}, &orm.User{}, &orm.Category{}, + &orm.Region{}, } ) @@ -74,6 +75,9 @@ func main() { log.Println("Eventually write categories on DB...") orm.CreateCategories() + log.Println("Eventually write regions on DB...") + orm.CreateRegions() + log.Println("Map models <-> handlers") if err := orm.MapHandlers(models); err != nil { panic(err) diff --git a/orm/participant.go b/orm/participant.go index 38ea04f7..9272cea8 100644 --- a/orm/participant.go +++ b/orm/participant.go @@ -149,6 +149,7 @@ func (model *Participant) Create(args map[string]string, w http.ResponseWriter, return nil, err } + // Check if participant exists if user, err := participant.exists(); err == nil && user != nil { if err := DB().Where("user_id = ?", user.ID).Find(&participant).Error; err != nil { return nil, err @@ -162,8 +163,7 @@ func (model *Participant) Create(args map[string]string, w http.ResponseWriter, return nil, err } - participant.UserModifierCreate = NewUserModifierCreate(r) - + // If user has "school" role get school id from token if isSchool(r) { schoolID, err := strconv.Atoi(getUserIDFromToken(r)) if err != nil { @@ -171,6 +171,22 @@ func (model *Participant) Create(args map[string]string, w http.ResponseWriter, } participant.SchoolID = uint(schoolID) } + + // Check if a participant of the same category exists + var school School + if err := DB().First(&school, participant.SchoolID).Error; err != nil { + return nil, err + } + hasCategory, err := school.HasCategory(participant) + if err != nil { + return nil, err + } + if hasCategory { + return nil, errors.CategoryExists + } + + participant.UserModifierCreate = NewUserModifierCreate(r) + participant, err = CreateParticipant(participant) if err != nil { return nil, err @@ -284,6 +300,19 @@ func (model *Participant) Update(args map[string]string, w http.ResponseWriter, return nil, err } + // Check if a participant of the same category exists + var school School + if err := DB().First(&school, participant.(*Participant).SchoolID).Error; err != nil { + return nil, err + } + hasCategory, err := school.HasCategory(participant.(*Participant)) + if err != nil { + return nil, err + } + if hasCategory { + return nil, errors.CategoryExists + } + if err := DB().Where(participant.(*Participant).ContestIDs).Find(&participant.(*Participant).Contests).Error; err != nil { return nil, err } diff --git a/orm/school.go b/orm/school.go index 30f0ffe9..bc018392 100644 --- a/orm/school.go +++ b/orm/school.go @@ -2,6 +2,7 @@ package orm import ( "fmt" + "log" "net/http" "strings" "time" @@ -248,3 +249,12 @@ func SaveSchool(school interface{}) (interface{}, error) { } return school, nil } + +func (model *School) HasCategory(participant *Participant) (bool, error) { + var participants []*Participant + log.Println(model) + if err := DB().Where("category_id = ? AND school_id = ? AND id <> ?", participant.CategoryID, model.ID, participant.ID).Find(&participants).Error; err != nil { + return false, err + } + return len(participants) > 0, nil +} diff --git a/renderer/renderer.go b/renderer/renderer.go index d570097b..105f970d 100644 --- a/renderer/renderer.go +++ b/renderer/renderer.go @@ -9,6 +9,7 @@ import ( "log" "git.andreafazzi.eu/andrea/oef/config" + "git.andreafazzi.eu/andrea/oef/errors" "github.com/gorilla/sessions" "mime" "net/http" @@ -228,12 +229,23 @@ func Use(r Renderer) { } func (rend *HTMLRenderer) writeError(w http.ResponseWriter, r *http.Request, data interface{}) { - t, ok := rend.templates["error"] - if !ok { - panic(fmt.Errorf("Error template not found! Can't proceed, sorry.")) - } + var t *template.Template - log.Println(data.(*htmlTemplateData).Data.(error)) + err, ok := data.(*htmlTemplateData).Data.(*errors.Error) + if ok { + t, ok = rend.templates[err.TemplateName] + if !ok { + panic(fmt.Errorf("Error template not found! Can't proceed, sorry.")) + } + + } else { + + t, ok = rend.templates["error"] + if !ok { + panic(fmt.Errorf("Error template not found! Can't proceed, sorry.")) + } + log.Println(data.(*htmlTemplateData).Data.(error)) + } w.Header().Set("Content-Type", "text/html; charset=utf-8") e := t.ExecuteTemplate(w, "base", data) diff --git a/templates/error_category_exists.html.tpl b/templates/error_category_exists.html.tpl new file mode 100644 index 00000000..81cc52af --- /dev/null +++ b/templates/error_category_exists.html.tpl @@ -0,0 +1,11 @@ +{{ define "content" }} +
+

Errore

+

+ Si è verificato un errore durante la creazione o l'aggiornamento di un partecipante: {{.Data}} +

+

+ Clicca {{all "Participant"|anchor "qui"}} per tornare all'elenco dei partecipanti. +

+
+{{ end }} diff --git a/templates/participants.html.tpl b/templates/participants.html.tpl index 93880b06..3cd62a11 100644 --- a/templates/participants.html.tpl +++ b/templates/participants.html.tpl @@ -45,7 +45,8 @@ {{end}} - + + {{if $isSchool}} {{if eq (len .Data) 2}}
@@ -55,6 +56,7 @@
{{end}} + {{end}} diff --git a/templates/participants_show.html.tpl b/templates/participants_show.html.tpl index 939ff3a8..5abd9253 100644 --- a/templates/participants_show.html.tpl +++ b/templates/participants_show.html.tpl @@ -15,6 +15,8 @@
{{.Data.User.Username}}
Password
{{.Data.User.Password}}
+
Categoria
+
{{.Data.Category}}
{{if $creatorUser:=.Data.CreatedBy}}
Creato da
{{$creatorUser.Username}}[{{$creatorUser.Role}}] {{$.Data.CreatedAt|prettyDateTime}}
@@ -45,6 +47,7 @@ + {{if $isAdmin}}
@@ -60,7 +63,6 @@
- {{if $isAdmin}}
diff --git a/templates/schools_add_update.html.tpl b/templates/schools_add_update.html.tpl index d7619f9b..2551a554 100644 --- a/templates/schools_add_update.html.tpl +++ b/templates/schools_add_update.html.tpl @@ -63,7 +63,19 @@ {{end}} {{template "input" dict "options" ($codeOptions|yaml) "value" (.Data|field "Code") "update" $update}} - + + {{$options := ` { name: "Address",id: "school_address",label: "Indirizzo dell'istituto",placeholder: "Inserire via, numero civico e città",type: "text",required: "true"} `}} + {{template "input" dict "options" ($options|yaml) "value" (.Data|field "Address") "update" $update}} + + {{$options := ` + name: "region_id" + id: "region_id" + label: "Regione" + title: "Seleziona la regione" + required: "true" + `}} + {{template "select" dict "options" ($options|yaml) "data" (.Data|field "AllRegions") "selected" (.Data|field "SelectedRegion") "update" $update "form" $form}} + {{$options := ` { name: "Email",id: "school_email",label: "Indirizzo email",placeholder: "Inserire l'indirizzo di posta istituzionale",type: "email",required: "true"} `}} {{template "input" dict "options" ($options|yaml) "value" (.Data|field "Email") "update" $update}} diff --git a/templates/schools_show.html.tpl b/templates/schools_show.html.tpl index 698e3d93..694a7d89 100644 --- a/templates/schools_show.html.tpl +++ b/templates/schools_show.html.tpl @@ -41,6 +41,10 @@
{{.Data.Name}}
Codice meccanografico
{{.Data.Code}}
+
Indirizzo
+
{{.Data.Address}}
+
Regione
+
{{.Data.Region}}
Email
{{.Data.Email}}
{{if .Data.EmailSentDate}}