ソースを参照

Merge branch 'master' into groups

Andrea Fazzi 5 年 前
コミット
3b1b8b91a3

+ 34 - 0
compose/karmen/ldap/bootstrap/ldif/foo.org.ldif

@@ -21,6 +21,13 @@ member: cn=John DOE,ou=People,dc=foo,dc=org
 objectclass: groupOfNames
 objectclass: top
 
+dn: cn=Coordinatori Dipartimenti,ou=Mailing Lists,ou=Groups,dc=foo,dc=org
+changetype: add
+cn: Coordinatori Dipartimenti
+member: cn=John DOE,ou=People,dc=foo,dc=org
+objectclass: groupOfNames
+objectclass: top
+
 dn: cn=LINGUE STRANIERE,ou=Mailing Lists,ou=Groups,dc=foo,dc=org
 changetype: add
 cn: LINGUE STRANIERE
@@ -44,6 +51,33 @@ gidNumber: 6000
 objectclass: posixGroup
 objectclass: top
 
+dn: ou=Segreterie,ou=Groups,dc=foo,dc=org
+changetype: add
+ou: Segreterie
+objectclass: organizationalUnit
+objectclass: top
+
+dn: cn=Segreteria didattica,ou=Segreterie,ou=Groups,dc=foo,dc=org
+changetype: add
+cn: Segreteria didattica
+gidNumber: 6007
+objectclass: posixGroup
+objectclass: top
+
+dn: cn=Segreteria del personale,ou=Segreterie,ou=Groups,dc=foo,dc=org
+changetype: add
+cn: Segreteria del personale
+gidNumber: 6008
+objectclass: posixGroup
+objectclass: top
+
+dn: cn=Coordinatori Dipartimenti,ou=Groups,dc=foo,dc=org
+changetype: add
+cn: Coordinatori Dipartimenti
+gidNumber: 6005
+objectclass: posixGroup
+objectclass: top
+
 dn: cn=Administratives,ou=Groups,dc=foo,dc=org
 changetype: add
 cn: Administratives

+ 3 - 0
config/config.go

@@ -88,6 +88,9 @@ type ConfigT struct {
 		AdministrativesGroup string `yaml:"administratives_group"`
 
 		TeachersML string `yaml:"teachers_ml"`
+
+		DepartmentsCoordinatorsGroup string `yaml:"departments_coordinators_group"`
+		DepartmentsCoordinatorsML    string `yaml:"departments_coordinators_ml"`
 	}
 }
 

+ 33 - 8
cron/sync/sync.go

@@ -204,14 +204,14 @@ func (syncJob *SyncJob) SyncUsers(ldapClient *karmen_ldap.Client, karmenClient *
 
 			err = ldapClient.AddUser(user)
 			if err != nil {
-				return nil, err
+				return nil, fmt.Errorf("An error occurred for user %s: %v", user.CompleteName(), err)
 			}
 
 			if user.GetRegenerate() {
 				if syncJob.conf.Sync.SendMail && user.GetAltEmail() != "" {
 					err = syncJob.sendMail(user, mailTpl)
 					if err != nil {
-						return nil, err
+						return nil, fmt.Errorf("An error occurred for user %s: %v", user.CompleteName(), err)
 					}
 				}
 
@@ -219,7 +219,7 @@ func (syncJob *SyncJob) SyncUsers(ldapClient *karmen_ldap.Client, karmenClient *
 
 				err = karmenClient.UpdateUser(user)
 				if err != nil {
-					return nil, err
+					return nil, fmt.Errorf("An error occurred for user %s: %v", user.CompleteName(), err)
 				}
 
 			}
@@ -231,7 +231,7 @@ func (syncJob *SyncJob) SyncUsers(ldapClient *karmen_ldap.Client, karmenClient *
 		for _, entry := range result.Removed {
 			err := ldapClient.DeleteByDN(entry)
 			if err != nil {
-				return nil, err
+				return nil, fmt.Errorf("An error occurred for entry %s: %v", entry, err)
 			}
 		}
 
@@ -241,7 +241,7 @@ func (syncJob *SyncJob) SyncUsers(ldapClient *karmen_ldap.Client, karmenClient *
 			if user.GetRegenerate() {
 				password, err := password.Generate(8, 2, 0, false, true)
 				if err != nil {
-					return nil, err
+					return nil, fmt.Errorf("An error occurred for user %s: %v", user.CompleteName(), err)
 				}
 
 				user.SetPlainPassword(password)
@@ -249,7 +249,7 @@ func (syncJob *SyncJob) SyncUsers(ldapClient *karmen_ldap.Client, karmenClient *
 				if syncJob.conf.Sync.SendMail && user.GetAltEmail() != "" {
 					err = syncJob.sendMail(user, mailTpl)
 					if err != nil {
-						return nil, err
+						return nil, fmt.Errorf("An error occurred for user %s: %v", user.CompleteName(), err)
 					}
 				}
 
@@ -257,11 +257,11 @@ func (syncJob *SyncJob) SyncUsers(ldapClient *karmen_ldap.Client, karmenClient *
 
 				err = karmenClient.UpdateUser(user)
 				if err != nil {
-					return nil, err
+					return nil, fmt.Errorf("An error occurred for user %s: %v", user.CompleteName(), err)
 				}
 				err = ldapClient.UpdateUserPassword(user)
 				if err != nil {
-					return nil, err
+					return nil, fmt.Errorf("An error occurred for user %s: %v", user.CompleteName(), err)
 
 				}
 			}
@@ -395,7 +395,12 @@ func (syncJob *SyncJob) Run() {
 		log.Println(result)
 	}
 
+	departmentsCoordinators := make([]orm.User, 0)
+
 	for _, department := range departments {
+
+		departmentsCoordinators = append(departmentsCoordinators, &department.Coordinator)
+
 		users := make([]orm.User, 0)
 		for _, teacher := range department.Teachers {
 			users = append(users, teacher)
@@ -414,6 +419,26 @@ func (syncJob *SyncJob) Run() {
 		}
 	}
 
+	// Departments Coordinator
+
+	log.Println("Sync Departments Coordinators...")
+
+	for _, c := range departmentsCoordinators {
+		log.Println("Coordinatore dipartimento", c.CompleteName())
+	}
+
+	if result, err := syncJob.SyncGroup(ldapClient, departmentsCoordinators, syncJob.conf.Sync.DepartmentsCoordinatorsGroup); err != nil {
+		panic(err)
+	} else {
+		log.Println(result)
+	}
+
+	if result, err := syncJob.SyncGroup(ldapClient, departmentsCoordinators, syncJob.conf.Sync.DepartmentsCoordinatorsML); err != nil {
+		panic(err)
+	} else {
+		log.Println(result)
+	}
+
 	administratives, err := karmenClient.GetAdministratives()
 	if err != nil {
 		log.Println(err)

+ 3 - 1
orm/activity.go

@@ -18,6 +18,8 @@ type Activity struct {
 	Subject       *Subject
 	Student       *Student
 
+	GroupActivity bool
+
 	ClassID         uint `schema:"class_id"`
 	TeacherID       uint `schema:"teacher_id"`
 	SupplyTeacherID uint `schema:"supply_teacher_id"`
@@ -66,7 +68,7 @@ func GetActivityAll(args map[string]string) (interface{}, error) {
 
 	id := args["id"]
 
-	if err := DB().Preload("Teacher").Preload("Subject").Preload("Class").First(&activity, id).Error; err != nil {
+	if err := DB().Preload("Student").Preload("Teacher").Preload("Subject").Preload("Class").First(&activity, id).Error; err != nil {
 		return nil, err
 	}
 	return &activity, nil

+ 5 - 0
orm/credential.go

@@ -30,6 +30,7 @@ type Credential struct {
 
 	Regenerate bool `schema:"Regenerate" sql:"default: false"`
 	Exclude    bool
+	NotInvited bool
 
 	LdapDNFmt string
 }
@@ -77,6 +78,10 @@ func (c *Credential) GetExclude() bool {
 	return c.Exclude
 }
 
+func (c *Credential) IsInvited() bool {
+	return !c.NotInvited
+}
+
 func (c *Credential) GetRegenerate() bool {
 	return c.Regenerate
 }

+ 1 - 1
orm/department.go

@@ -89,7 +89,7 @@ func GetDepartments(args map[string]string) (interface{}, error) {
 
 func GetDepartmentsAll(args map[string]string) (interface{}, error) {
 	var departments []*Department
-	if err := DB().Order("name").Find(&departments).Error; err != nil {
+	if err := DB().Preload("Coordinator").Order("name").Find(&departments).Error; err != nil {
 		return nil, err
 	}
 	for _, department := range departments {

+ 3 - 1
orm/subject.go

@@ -17,7 +17,9 @@ WHERE subject_id=?
 type Subject struct {
 	gorm.Model
 
-	Name         string
+	Name  string
+	Alias string
+
 	DepartmentID uint `schema:"department_id"`
 
 	Teachers   []*Teacher

+ 16 - 1
orm/teacher.go

@@ -22,6 +22,9 @@ type Teacher struct {
 	Departments []*Department
 	Groups      []*Group `gorm:"many2many:group_teachers"`
 
+	Coordinator []*Class
+	Minuter     []*Class
+
 	SubjectsByClass map[uint][]*Subject `gorm:"-"`
 
 	Hours       int
@@ -116,6 +119,7 @@ func GetTeacherAll(args map[string]string) (interface{}, error) {
 	}
 
 	teacher.IsCoordinator, teacher.IsMinuter = len(coordClasses) > 0, len(minuterClasses) > 0
+	teacher.Coordinator, teacher.Minuter = coordClasses, minuterClasses
 
 	return &teacher, nil
 }
@@ -156,6 +160,17 @@ func GetTeachersAll(args map[string]string) (interface{}, error) {
 			teacher.SubjectsByClass[c.ID] = subjects
 		}
 
+		coordClasses, err := teacher.CoordinatorClasses()
+		if err != nil {
+			return nil, err
+		}
+
+		minuterClasses, err := teacher.MinuterClasses()
+		if err != nil {
+			return nil, err
+		}
+
+		teacher.Coordinator, teacher.Minuter = coordClasses, minuterClasses
 	}
 
 	return teachers, nil
@@ -282,7 +297,7 @@ func (t *Teacher) GetStudents() ([]*Student, error) {
 }
 
 func (t *Teacher) GetActivities() ([]*Activity, error) {
-	if err := DB().Preload("SupplyTeacher").Preload("Teacher").Preload("Subject").Preload("Class").Where("teacher_id=? OR supply_teacher_id=?", t.ID, t.ID).Find(&t.Activities).Error; err != nil {
+	if err := DB().Preload("SupplyTeacher").Preload("Teacher").Preload("Subject").Preload("Class").Preload("Student").Where("teacher_id=? OR supply_teacher_id=?", t.ID, t.ID).Find(&t.Activities).Error; err != nil {
 		return nil, err
 	}
 	return t.Activities, nil

+ 13 - 0
templates/activities_add_update.html.tpl

@@ -130,11 +130,24 @@
       </select>
     </div>
 
+
     <div class="form-group">
       <label class="control-label" for="hours">Numero di ore</label>
       <input class="form-control" min="0" type="number" name="hours" id="hours" {{if .Options.Get "update"}}value="{{.Data.Activity.Hours}}"{{end}} required>
     </div>
 
+    
+    <div class="form-group">
+      <div class="form-check">
+        <input type="checkbox" name="GroupActivity" class="form-check-input" id="activity_group_activity" {{if .Options.Get "update"}}{{if .Data.Activity.GroupActivity}}checked{{end}}{{end}}>
+        <label class="form-check-label" for="activity_group_activity">Attività di gruppo</label>
+        <small id="activity_group_help_box" class="form-text text-muted">
+          Spuntare la casella sopra nel caso di attività che coinvolgono più studenti contemporaneamente.
+        </small>
+      </div>
+    </div>
+
+
     <div class="form-group">
       <button type="submit" class="btn btn-primary">Salva</button>
       {{if .Options.Get "update"}}

+ 21 - 0
templates/activities_show.html.tpl

@@ -104,6 +104,27 @@
     </div>
   </div>
 
+  <div class="row">
+    <div class="col-md-12">
+      
+      <h2 class="karmen-relation-header">Studente</h2>
+      {{if .Data.Student}}
+      <div class="list-group" id="classes_list_group">
+	<a href="/teachers/{{.Data.Student.ID}}?{{query "tpl_layout" "base" "tpl_content" "students_show"}}" class="list-group-item list-group-item-action">
+	  <span class="fa fa-user"></span>
+	  {{.Data.Student.Surname}} {{.Data.Student.Name}}
+	</a>
+      </div>
+      
+      {{else}}
+
+      <p>All'attività non è associato alcuno studente. Clicca <a href="/activities/update?{{query "base" "activities_add_update"}}">qui</a> per modificare questa attività didattica.</p>
+     
+      {{end}}
+      
+    </div>
+  </div>
+
 
 </div>    
 

+ 7 - 0
templates/administratives_add_update.html.tpl

@@ -69,6 +69,13 @@
 	</div>
       </div>
     </div>
+    <div class="col">
+      <div class="form-check">
+	<input type="checkbox" name="NotInvited" class="form-check-input" id="administrative_not_invited" {{if .Options.Get "update"}}{{if .Data.Administrative.NotInvited}}checked{{end}}{{end}}>
+	<label class="form-check-label has-feedback" for="administrative_not_invited">Escludere dagli inviti</label>
+      </div>
+    </div>
+
     
     <div class="form-row">
       <div class="col">

+ 6 - 1
templates/subjects_add_update.html.tpl

@@ -35,7 +35,12 @@
       <label class="control-label" for="subject_name">Nome</label>
       <input type="text" name="Name" class="form-control" id="subject_name" placeholder="Nome" {{if .Options.Get "update"}} value="{{.Data.Subject.Name}}" {{end}} required>
     </div>
-    
+
+    <div class="form-group">
+      <label class="control-label" for="subject_alias">Nome alternativo</label>
+      <input type="text" name="Alias" class="form-control" id="subject_alias" placeholder="Nome alternativo" {{if .Options.Get "update"}} value="{{.Data.Subject.Alias}}" {{end}} required>
+    </div>
+
     <div class="form-group">
       <label class="control-label" for="department_id">Dipartimento</label>
       <select name="department_id" class="form-control selectpicker" id="department_id" placeholder="Dipartimento" data-live-search="true" form="form_subjects_add_update" title="Seleziona il nome del dipartimento" data-dropup-auto="false">

+ 7 - 0
templates/teachers_add_update.html.tpl

@@ -62,6 +62,13 @@
 	  <label class="form-check-label has-feedback" for="teacher_exclude">Escludere dalle utenze</label>
 	</div>
       </div>
+      <div class="col">
+	<div class="form-check">
+	  <input type="checkbox" name="NotInvited" class="form-check-input" id="teacher_not_invited" {{if .Options.Get "update"}}{{if .Data.NotInvited}}checked{{end}}{{end}}>
+	  <label class="form-check-label has-feedback" for="teacher_not_invited">Escludere dagli inviti</label>
+	</div>
+      </div>
+
 
     </div>