Selaa lähdekoodia

Begin working on students

Andrea Fazzi 6 vuotta sitten
vanhempi
commit
ad53868718

+ 1 - 1
generator/templates/add_update.tpl

@@ -43,7 +43,7 @@
       {{"{{if .Options.Get \"update\"}}"}}
       <a href="/{{.Models}}/{{"{{.Data.ID}}"}}?{{"{{query \"tpl_layout\" \"base\" \"tpl_content\" "}}"{{.Models}}{{"_show\"}}"}}" class="btn btn-default">Annulla</a>
       {{"{{else}}"}}
-      <a href="/{{.Models}}/?{{"{{query \"tpl_layout\" \"base\" \"tpl_content\" "}}"{{.Models}}"{{"}}"}}" class="btn btn-default">Annulla</a>
+      <a href="/{{.Models}}?{{"{{query \"tpl_layout\" \"base\" \"tpl_content\" "}}"{{.Models}}"{{"}}"}}" class="btn btn-default">Annulla</a>
       {{"{{end}}"}}
     </div>
     

+ 1 - 2
handlers/handlers.go

@@ -51,7 +51,7 @@ var (
 		SigningMethod: jwt.SigningMethodHS256,
 	})
 
-	models = []string{"teachers", "classes", "subjects", "departments", "activities"}
+	models = []string{"teachers", "classes", "subjects", "departments", "activities", "students"}
 )
 
 func (pp PathPattern) RedirectPath(model string, id ...uint) string {
@@ -183,7 +183,6 @@ func get(w http.ResponseWriter, r *http.Request, model string, pattern PathPatte
 func respondWithError(w http.ResponseWriter, r *http.Request, err error) {
 	respFormat := renderer.GetContentFormat(r)
 	w.WriteHeader(http.StatusInternalServerError)
-	// renderer.Render[r.URL.Query().Get("format")](w, r, err)
 	renderer.Render[respFormat](w, r, err)
 }
 

+ 9 - 4
orm/activity.go

@@ -9,13 +9,18 @@ import (
 
 type Activity struct {
 	gorm.Model
-	Class     *Class
-	Teacher   *Teacher
-	Subject   *Subject
+
+	Class   *Class
+	Teacher *Teacher
+	Subject *Subject
+	Student *Student
+
 	ClassID   uint `schema:"class_id"`
 	TeacherID uint `schema:"teacher_id"`
 	SubjectID uint `schema:"subject_id"`
-	Hours     int
+	StudentID uint `schema:"student_id"`
+
+	Hours int
 
 	prevTeacherID uint
 }

+ 21 - 0
orm/mappings.go

@@ -13,6 +13,17 @@ var (
 		"/api/teachers/{id}/update": GetTeacher,
 		"/api/teachers/add/":        GetNothing,
 
+		// Student
+		"/students":             GetStudentsAll,
+		"/students/{id}":        GetStudentAll,
+		"/students/{id}/update": GetStudentForUpdate,
+		"/students/add/":        GetStudentForAdd,
+
+		"/api/students":             GetStudentsAll,
+		"/api/students/{id}":        GetStudentAll,
+		"/api/students/{id}/update": GetStudentForUpdate,
+		"/api/students/add/":        GetStudentForAdd,
+
 		// Classes
 		"/classes":             GetClassesAll,
 		"/classes/{id}":        GetClassAll,
@@ -69,6 +80,16 @@ var (
 		"/api/teachers/{id}/delete": DeleteTeacher,
 		"/api/teachers/add/":        AddTeacher,
 
+		// Student
+		"/students/{id}/update": UpdateStudent,
+		"/students/{id}/delete": DeleteStudent,
+		"/students/add/":        AddStudent,
+
+		"/api/students/add":         AddStudent,
+		"/api/students/{id}/update": UpdateStudent,
+		"/api/students/{id}/delete": DeleteStudent,
+		"/api/students/add/":        AddStudent,
+
 		// Classes
 		"/classes/{id}/update": UpdateClass,
 		"/classes/{id}/delete": DeleteClass,

+ 8 - 6
orm/orm.go

@@ -45,12 +45,6 @@ type Desk struct {
 	Teacher  *Teacher
 }
 
-type Student struct {
-	gorm.Model
-	Credential
-	Class *Class
-}
-
 type GetFn func(map[string]string) (interface{}, error)
 type PostFn func(map[string]string, *http.Request) (IDer, error)
 
@@ -104,3 +98,11 @@ func PostFunc(path string) (PostFn, error) {
 
 	return fn, nil
 }
+
+func GetNothing(args map[string]string) (interface{}, error) {
+	return nil, nil
+}
+
+func PostNothing(args map[string]string, r *http.Request) (IDer, error) {
+	return nil, nil
+}

+ 191 - 0
orm/student.go

@@ -0,0 +1,191 @@
+package orm
+
+import (
+	"fmt"
+	"net/http"
+
+	"github.com/jinzhu/gorm"
+	"gogs.carducci-dante.gov.it/karmen/core/renderer"
+)
+
+type Student struct {
+	gorm.Model
+	Credential
+
+	ClassID uint `schema:"class_id"`
+
+	Class      *Class
+	Teachers   []*Teacher
+	Activities []*Activity
+}
+
+type StudentForUpdate struct {
+	Student    Student
+	AllClasses []*Class
+
+	SelectedClass map[uint]string
+}
+
+type StudentForAdd struct {
+	AllClasses []*Class
+}
+
+var (
+	selectStudentTeachers = `
+SELECT teachers.* FROM activities
+INNER JOIN teachers ON activities.teacher_id=teachers.id
+`
+)
+
+func (s *Student) GetID() uint { return s.ID }
+
+func GetStudent(args map[string]string) (interface{}, error) {
+	var student Student
+	if err := DB().First(&student, args["id"]).Error; err != nil {
+		return nil, err
+	}
+	return &student, nil
+}
+
+func GetStudentAll(args map[string]string) (interface{}, error) {
+	var student Student
+
+	id := args["id"]
+
+	if err := DB().Where("id = ?", id).Find(&student).Error; err != nil {
+		return nil, err
+	}
+
+	// if err := DB().Preload("Student").Preload("Subject").Preload("Class").Where("student_id=?", id).Find(&student.Activities).Error; err != nil {
+	// 	return nil, err
+	// }
+
+	return &student, nil
+}
+
+func GetStudents(args map[string]string) (interface{}, error) {
+	var students []*Student
+	if err := DB().Order("surname,name").Find(&students).Error; err != nil {
+		return nil, err
+	}
+	return students, nil
+}
+
+func GetStudentsAll(args map[string]string) (interface{}, error) {
+	var students []*Student
+	if err := DB().Order("surname,name").Find(&students).Error; err != nil {
+		return nil, err
+	}
+	for _, student := range students {
+		student.GetTeachers()
+	}
+	for _, student := range students {
+		student.GetActivities()
+	}
+	return students, nil
+}
+
+func SaveStudent(student interface{}) (interface{}, error) {
+	if err := DB().Omit("Classes", "Subjects", "Activities").Save(student).Error; err != nil {
+		return nil, err
+	}
+	return student, nil
+}
+
+func UpdateStudent(args map[string]string, r *http.Request) (IDer, error) {
+	student, err := GetStudent(args)
+	if err != nil {
+		return nil, err
+	}
+	err = renderer.Decode(student, r)
+	if err != nil {
+		return nil, err
+	}
+	_, err = SaveStudent(student)
+	if err != nil {
+		return nil, err
+	}
+	student, err = GetStudent(args)
+	if err != nil {
+		return nil, err
+	}
+	return student.(*Student), nil
+}
+
+func AddStudent(args map[string]string, r *http.Request) (IDer, error) {
+	student := new(Student)
+	err := renderer.Decode(student, r)
+	if err != nil {
+		return nil, err
+	}
+	student, err = CreateStudent(student)
+	if err != nil {
+		return nil, err
+	}
+
+	return student, nil
+}
+
+func CreateStudent(student *Student) (*Student, error) {
+	if err := DB().Create(student).Error; err != nil {
+		return nil, err
+	}
+	return student, nil
+}
+
+func DeleteStudent(args map[string]string, r *http.Request) (IDer, error) {
+	student, err := GetStudent(args)
+	if err != nil {
+		return nil, err
+	}
+	if err := DB().Unscoped().Delete(student.(*Student)).Error; err != nil {
+		return nil, err
+	}
+	return student.(*Student), nil
+}
+
+func GetStudentForUpdate(args map[string]string) (interface{}, error) {
+	var data StudentForUpdate
+
+	id := args["id"]
+
+	if err := DB().Preload("Class").First(&data.Student, id).Error; err != nil {
+		return nil, err
+	}
+
+	if err := DB().Find(&data.AllClasses).Error; err != nil {
+		return nil, err
+	}
+
+	data.SelectedClass = make(map[uint]string)
+	data.SelectedClass[data.Student.ClassID] = "selected"
+
+	return data, nil
+}
+
+func GetStudentForAdd(args map[string]string) (interface{}, error) {
+	var data StudentForAdd
+
+	if err := DB().Find(&data.AllClasses).Error; err != nil {
+		return nil, err
+	}
+	return data, nil
+}
+
+func (s *Student) GetTeachers() ([]*Teacher, error) {
+	if err := DB().Raw(selectStudentTeachers, s.ID).Scan(&s.Teachers).Error; err != nil {
+		return nil, err
+	}
+	return s.Teachers, nil
+}
+
+func (s *Student) GetActivities() ([]*Activity, error) {
+	if err := DB().Preload("Student").Preload("Subject").Preload("Class").Where("student_id=?", s.ID).Find(&s.Activities).Error; err != nil {
+		return nil, err
+	}
+	return s.Activities, nil
+}
+
+func (s *Student) CompleteName() string {
+	return fmt.Sprintf("%s %s", s.Name, s.Surname)
+}

+ 0 - 8
orm/teacher.go

@@ -37,14 +37,6 @@ WHERE activities.teacher_id=?`
 
 func (t *Teacher) GetID() uint { return t.ID }
 
-func GetNothing(args map[string]string) (interface{}, error) {
-	return nil, nil
-}
-
-func PostNothing(args map[string]string, r *http.Request) (IDer, error) {
-	return nil, nil
-}
-
 func GetTeacher(args map[string]string) (interface{}, error) {
 	var teacher Teacher
 	if err := DB().First(&teacher, args["id"]).Error; err != nil {

+ 1 - 0
templates/layout/base.html.tpl

@@ -29,6 +29,7 @@
 	    <li><a href="/departments?{{query "tpl_layout" "base" "tpl_content" "departments"}}">Dipartimenti</a></li>
 	    <li><a href="/subjects?{{query "tpl_layout" "base" "tpl_content" "subjects"}}">Materie</a></li>
 	    <li><a href="/classes?{{query "tpl_layout" "base" "tpl_content" "classes"}}">Classi</a></li>
+	    <li><a href="/students?{{query "tpl_layout" "base" "tpl_content" "students"}}">Studenti</a></li>
 	    <li><a href="/activities?{{query "tpl_layout" "base" "tpl_content" "activities"}}">Attività</a></li>
           </ul>
 

+ 41 - 0
templates/students.html.tpl

@@ -0,0 +1,41 @@
+{{ define "content" }}
+
+<div class="container">
+  
+  <div class="karmen-info-header">
+    <div class="row">
+      <div class="col-md-8">
+	<h1>Studenti</h1>
+      </div>
+      <div class="col-md-4">
+	<a href="/students/add/?{{query "tpl_layout" "base" "tpl_content" "students_add_update"}}" class="btn btn-primary pull-right">
+	  <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
+	  Crea nuovo studente
+	</a>
+      </div>
+    </div>
+  </div>
+
+  <div class="input-group" style="margin-bottom: 20px">
+    <span class="input-group-addon" id="search-query"><span class="glyphicon glyphicon-search"></span></span>
+    <input type="text" id="myInput" class="form-control" aria-describedby="search-query">
+  </div>
+  
+  {{if not .Data}}
+  <p>Non c'è alcun elemento da visualizzare</p>
+  {{else}}
+  <div class="list-group" id="myUL">
+    {{range $student := .Data}}
+    <a class="list-group-item clearfix" href="/students/{{$student.ID}}?{{query "tpl_layout" "base" "tpl_content" "students_show"}}">
+      <span class="glyphicon glyphicon-briefcase"></span>
+      {{$student.Name}}
+      <div class="text-right">
+	<small>optional tag goes here</small>
+      </div>
+    </a>
+    {{end}}
+  </div>
+  {{end}}
+</div>
+  
+{{ end }}

+ 76 - 0
templates/students_add_update.html.tpl

@@ -0,0 +1,76 @@
+{{ define "content" }}
+
+<div class="container">
+
+  {{if .Options.Get "update"}}
+  <ol class="breadcrumb">
+    <li><a href="/students?{{query "tpl_layout" "base" "tpl_content" "students"}}">Studente</a></li>
+    <li class="active"><a href="#">Aggiorna studente</a></li>
+  </ol>  
+  {{else}}
+  <ol class="breadcrumb">
+    <li><a href="/students?{{query "tpl_layout" "base" "tpl_content" "students"}}">Studente</a></li>
+    <li class="active"><a href="#">Aggiungi</a></li>
+  </ol>
+  {{end}}
+
+ {{if .Options.Get "update"}}
+  <div class="karmen-info-header">
+    <div class="row">
+      <div class="col-md-8">
+	<h1>Aggiorna studente</h1>
+      </div>
+    </div>
+  </div>
+  
+  {{else}}
+  <h1 class="karmen-info-header">Crea nuovo studente</h1>
+  {{end}}
+
+  {{if .Options.Get "update"}}
+  <form id="form_students_add_update" action="/students/{{.Data.ID}}/update" method="POST" role="form" data-toggle="validator">
+  {{else}}
+  <form id="form_students_add_update" action="/students/add/" method="POST" role="form" data-toggle="validator">
+  {{end}}
+
+    <div class="form-group has-feedback">
+      <label class="control-label" for="student_name">Nome</label>
+      <input type="text" name="Name" class="form-control" id="student_name" placeholder="Nome" {{if .Options.Get "update"}} value="{{.Data.Name}}" {{end}} required>
+    </div>
+
+    <div class="form-group has-feedback">
+      <label class="control-label" for="student_surname">Cognome</label>
+      <input type="text" name="Surname" class="form-control" id="student_surname" placeholder="Cognome" {{if .Options.Get "update"}} value="{{.Data.Surname}}" {{end}} required>
+    </div>
+
+    <div class="form-group">
+      <label class="control-label" for="class_id">Classe</label>
+      <select name="class_id" class="form-control selectpicker" id="class_id" placeholder="Classe" data-live-search="true" form="form_students_add_update" title="Seleziona la classe" data-dropup-auto="false">
+    	<option value="0"></option>
+    	{{range $class := .Data.AllClasses}}
+    	{{if $.Options.Get "update"}}
+    	<option
+    	   value="{{$class.ID}}"
+    	   {{index $.Data.SelectedClass $class.ID}}>{{$class.Name}}
+    	</option>
+    	{{else}}
+    	<option value="{{$class.ID}}">{{$class.Name}}</option>
+    	{{end}}
+    	{{end}}
+      </select>
+    </div>
+
+    <div class="form-group">
+      <button type="submit" class="btn btn-primary">Salva</button>
+      {{if .Options.Get "update"}}
+      <a href="/students/{{.Data.ID}}?{{query "tpl_layout" "base" "tpl_content" "students_show"}}" class="btn btn-default">Annulla</a>
+      {{else}}
+      <a href="/students?{{query "tpl_layout" "base" "tpl_content" "students"}}" class="btn btn-default">Annulla</a>
+      {{end}}
+    </div>
+    
+  </form>
+
+</div>
+
+{{ end }}

+ 61 - 0
templates/students_show.html.tpl

@@ -0,0 +1,61 @@
+{{ define "content" }}
+
+<div class="container">
+
+  <ol class="breadcrumb">
+    <li><a href="/students?{{query "tpl_layout" "base" "tpl_content" "students"}}">students</a></li>
+    <li class="active"><a href="#">{{.Data.Name}}</a></li>
+  </ol>
+
+  <div class="karmen-info-header">
+    <div class="row">
+      <div class="col-md-8">
+	<h1>{{.Data.Surname}} {{.Data.Name}}</h1>
+      </div>
+      <div class="col-md-4">
+
+	<div class="btn-group pull-right" role="group">
+	  <a href="/students/add/?{{query "tpl_layout" "base" "tpl_content" "students_add_update"}}" class="btn btn-success">
+	    <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
+	    Crea
+	  </a>
+
+	  <a href="/students/{{.Data.ID}}/update?{{query "tpl_layout" "base" "tpl_content" "students_add_update" "update" "true"}}"  class="btn btn-primary">
+	    <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
+	    Modifica
+	  </a>
+	  <button href="/students/{{.Data.ID}}/delete"
+		  data-url="/students/{{.Data.ID}}/delete"
+		  class="btn btn-danger karmen-ajax-delete">
+	    <span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
+	    Elimina
+	  </button>
+	</div>
+
+      </div>
+    </div>
+  </div>
+
+  <div class="row">
+    <div class="col-md-12">
+      
+      <h2 class="karmen-relation-header">Docenti dell'allievo</h2>
+      {{if .Data.Teachers}}
+      <div class="list-group" id="materie_list_group">
+    	<a href="/subjects/{{.Data.Subject.ID}}?{{query "tpl_layout" "base" "tpl_content" "subjects_show"}}" class="list-group-item clearfix">
+    	  <span class="glyphicon glyphicon-book"></span>
+    	  {{.Data.Subject.Name}}
+    	</a>
+      </div>
+      {{else}}
+      <p>All'attività non è associata alcuna materia
+    	didattica. Clicca <a href="/activities/update?{{query "tpl_layout" "base" "tpl_content" "activities_add_update"}}">qui</a> per
+    	modificare questa attività didattica.</p>
+      {{end}}
+    </div>
+    
+  </div>
+
+</div>    
+
+{{ end }}