From f243417376ddc7e0600cc05be2c2ec68787d8184 Mon Sep 17 00:00:00 2001 From: mytja Date: Sun, 17 Apr 2022 10:38:55 +0200 Subject: [PATCH] Add certificate of schooling generation - Resolves https://github.com/MeetPlan/MeetPlanFrontend/issues/13 --- httphandlers/interface.go | 1 + httphandlers/testing.go | 26 ++++-- httphandlers/user.go | 162 +++++++++++++++++++++++++++++++++++++- main.go | 1 + 4 files changed, 181 insertions(+), 9 deletions(-) diff --git a/httphandlers/interface.go b/httphandlers/interface.go index c7115d9..faa85bc 100644 --- a/httphandlers/interface.go +++ b/httphandlers/interface.go @@ -22,6 +22,7 @@ type HTTP interface { HasClass(w http.ResponseWriter, r *http.Request) GetUserData(w http.ResponseWriter, r *http.Request) GetAbsencesUser(w http.ResponseWriter, r *http.Request) + CertificateOfSchooling(w http.ResponseWriter, r *http.Request) // testing.go GetSelfTestingTeacher(w http.ResponseWriter, r *http.Request) diff --git a/httphandlers/testing.go b/httphandlers/testing.go index a262c5a..26908ba 100644 --- a/httphandlers/testing.go +++ b/httphandlers/testing.go @@ -1,6 +1,7 @@ package httphandlers import ( + "encoding/json" "fmt" "github.com/MeetPlan/MeetPlanBackend/sql" "github.com/gorilla/mux" @@ -135,6 +136,11 @@ func (server *httpImpl) GetPDFSelfTestingReportStudent(w http.ResponseWriter, r return } + user, err := server.db.GetUser(userId) + if err != nil { + return + } + id, err := strconv.Atoi(mux.Vars(r)["test_id"]) if err != nil { WriteBadRequest(w) @@ -151,6 +157,13 @@ func (server *httpImpl) GetPDFSelfTestingReportStudent(w http.ResponseWriter, r WriteForbiddenJWT(w) return } + } else if jwtData["role"] == "parent" { + var users []int + json.Unmarshal([]byte(user.Users), &users) + if !contains(users, test.UserID) { + WriteForbiddenJWT(w) + return + } } if test.Result == "SE NE TESTIRA" { @@ -167,10 +180,6 @@ func (server *httpImpl) GetPDFSelfTestingReportStudent(w http.ResponseWriter, r return } - // Normalize Slovenian characters - student.Name = strings.Replace(student.Name, "č", "c", -1) - teacher.Name = strings.Replace(teacher.Name, "č", "c", -1) - jwt, err, expiration := sql.GetJWTForTestingResult(test.UserID, test.Result, test.ID, test.Date) if err != nil { return @@ -178,6 +187,9 @@ func (server *httpImpl) GetPDFSelfTestingReportStudent(w http.ResponseWriter, r m := pdf.NewMaroto(consts.Portrait, consts.A4) + m.AddUTF8Font("OpenSans", consts.Normal, "fonts/opensans.ttf") + m.SetDefaultFontFamily("OpenSans") + m.Row(40, func() { m.Col(3, func() { _ = m.Base64Image(MeetPlanLogoBase64, consts.Png, props.Rect{ @@ -213,7 +225,7 @@ func (server *httpImpl) GetPDFSelfTestingReportStudent(w http.ResponseWriter, r m.Text(test.Result, props.Text{Size: 20, Top: 20}) if test.Result == "POZITIVEN" { m.Text( - "Vaš test je bil pozitiven. Samoizolirajte se v cim manjšem možnem casu. To potrdilo vam lahko s podpisom osebe, ki je izvajala testiranje, tudi služi kot dokaz za PCR testiranje.", + "Vaš test je bil pozitiven. Samoizolirajte se v čim manjšem možnem času. To potrdilo vam lahko s podpisom osebe, ki je izvajala testiranje, tudi služi kot dokaz za PCR testiranje.", props.Text{Top: 30}, ) } else if test.Result == "NEVELJAVEN" { @@ -238,7 +250,7 @@ func (server *httpImpl) GetPDFSelfTestingReportStudent(w http.ResponseWriter, r m.Row(60, func() { m.Col(6, func() { - m.Text(fmt.Sprintf(" Enolicni identifikator testiranja: %s", fmt.Sprint(test.ID)), props.Text{ + m.Text(fmt.Sprintf(" Enolični identifikator testiranja: %s", fmt.Sprint(test.ID)), props.Text{ Size: 15, Top: 5, }) @@ -254,7 +266,7 @@ func (server *httpImpl) GetPDFSelfTestingReportStudent(w http.ResponseWriter, r Size: 15, Top: 35, }) - m.Text(fmt.Sprintf(" Enolicni identifikator osebe: %s", fmt.Sprint(student.ID)), props.Text{ + m.Text(fmt.Sprintf(" Enolični identifikator osebe: %s", fmt.Sprint(student.ID)), props.Text{ Size: 15, Top: 45, }) diff --git a/httphandlers/user.go b/httphandlers/user.go index 3293760..e3ec055 100644 --- a/httphandlers/user.go +++ b/httphandlers/user.go @@ -5,6 +5,9 @@ import ( "fmt" "github.com/MeetPlan/MeetPlanBackend/sql" "github.com/gorilla/mux" + "github.com/johnfercher/maroto/pkg/consts" + "github.com/johnfercher/maroto/pkg/pdf" + "github.com/johnfercher/maroto/pkg/props" "net/http" "strconv" "time" @@ -373,8 +376,8 @@ func (server *httpImpl) GetAllClasses(w http.ResponseWriter, r *http.Request) { } server.logger.Debug(students, userId) for n := 0; n < len(students); n++ { - for n := 0; n < len(userId); n++ { - if students[n] == userId[n] && !contains(myClassesInt, students[n]) { + for l := 0; l < len(userId); l++ { + if students[n] == userId[l] && !contains(myClassesInt, students[n]) { user, err := server.db.GetUser(students[n]) if err != nil { return @@ -457,3 +460,158 @@ func (server *httpImpl) HasBirthday(w http.ResponseWriter, r *http.Request) { _, bm, bd := birthday.Date() WriteJSON(w, Response{Data: tm-bm == 0 && td-bd == 0, Success: true}, http.StatusOK) } + +func (server *httpImpl) CertificateOfSchooling(w http.ResponseWriter, r *http.Request) { + jwt, err := sql.CheckJWT(GetAuthorizationJWT(r)) + if err != nil { + WriteForbiddenJWT(w) + return + } + + if jwt["role"] != "admin" { + WriteForbiddenJWT(w) + return + } + + userId, err := strconv.Atoi(mux.Vars(r)["user_id"]) + if err != nil { + WriteBadRequest(w) + return + } + + student, err := server.db.GetUser(userId) + if err != nil { + return + } + if student.Role != "student" { + WriteForbiddenJWT(w) + return + } + + classes, err := server.db.GetClasses() + if err != nil { + return + } + + var classId = -1 + + for i := 0; i < len(classes); i++ { + class := classes[i] + var students []int + err := json.Unmarshal([]byte(class.Students), &students) + if err != nil { + return + } + if contains(students, userId) { + classId = class.ID + break + } + } + + if classId == -1 { + return + } + + class, err := server.db.GetClass(classId) + if err != nil { + return + } + + var students []int + err = json.Unmarshal([]byte(class.Students), &students) + if err != nil { + return + } + if !contains(students, userId) { + WriteForbiddenJWT(w) + return + } + + m := pdf.NewMaroto(consts.Portrait, consts.A4) + + m.AddUTF8Font("OpenSans", consts.Normal, "fonts/opensans.ttf") + m.SetDefaultFontFamily("OpenSans") + + m.Row(40, func() { + + m.Col(3, func() { + _ = m.FileImage("icons/school_logo.png", props.Rect{ + Center: true, + Percent: 80, + }) + }) + + m.ColSpace(1) + + m.Col(4, func() { + m.Text("Potrdilo o šolanju", props.Text{ + Top: 12, + Size: 25, + Extrapolate: true, + }) + m.Text("MeetPlan sistem", props.Text{ + Top: 23, + Size: 13, + Extrapolate: true, + }) + }) + m.ColSpace(1) + + m.Col(3, func() { + _ = m.FileImage("icons/country_coat_of_arms_black.png", props.Rect{ + Center: true, + Percent: 80, + }) + }) + }) + + m.Line(10) + + m.Row(40, func() { + m.Text(fmt.Sprintf( + "Učenec %s, rojen %s, %s, %s, v šolskem letu %s obiskuje %s", + student.Name, student.Birthday, student.CityOfBirth, + student.CountryOfBirth, class.ClassYear, class.Name, + ), props.Text{ + Top: 12, + Size: 11, + Extrapolate: true, + }) + m.Text(fmt.Sprintf("razred %s.", + server.config.SchoolName, + ), props.Text{ + Top: 16, + Size: 11, + Extrapolate: true, + }) + }) + + m.Row(40, func() { + m.ColSpace(1) + m.Col(6, func() { + m.Text("_________________________", props.Text{ + Top: 14, + Size: 15, + }) + m.Text("Ravnatelj2", props.Text{ + Top: 14, + Size: 15, + }) + m.Text("digitalni podpis ravnatelja", props.Text{Top: 20, Size: 9}) + }) + m.Col(3, func() { + m.Text("_________________________", props.Text{ + Top: 14, + Size: 15, + }) + m.Text("podpis ravnatelja", props.Text{Top: 20, Size: 9}) + }) + }) + + output, err := m.Output() + if err != nil { + WriteJSON(w, Response{Error: err.Error(), Success: false}, http.StatusInternalServerError) + return + } + w.Write(output.Bytes()) +} diff --git a/main.go b/main.go index ea12c26..1d88b2d 100644 --- a/main.go +++ b/main.go @@ -63,6 +63,7 @@ func main() { r.HandleFunc("/user/get/homework/{id}", httphandler.GetUserHomework).Methods("GET") r.HandleFunc("/user/get/absences/{id}", httphandler.GetAbsencesUser).Methods("GET") r.HandleFunc("/user/get/ending_certificate/{student_id}", httphandler.PrintCertificateOfEndingClass).Methods("GET") + r.HandleFunc("/user/get/certificate_of_schooling/{user_id}", httphandler.CertificateOfSchooling).Methods("GET") r.HandleFunc("/user/get/unread_messages", httphandler.GetUnreadMessages).Methods("GET") r.HandleFunc("/user/get/absences/{student_id}/excuse/{absence_id}", httphandler.ExcuseAbsence).Methods("PATCH")