1 package com.pentila.entSavoie.synchroLdap.impl;
3 import java.text.SimpleDateFormat;
4 import java.util.ArrayList;
6 import java.util.HashMap;
7 import java.util.HashSet;
12 import com.liferay.contacts.util.OrganizationConstants;
13 import com.liferay.portal.kernel.json.JSONFactoryUtil;
14 import com.liferay.portal.kernel.log.Log;
15 import com.liferay.portal.kernel.log.LogFactoryUtil;
16 import com.liferay.portal.model.Organization;
17 import com.liferay.portal.model.User;
18 import com.liferay.portal.service.UserLocalServiceUtil;
19 import com.pentila.entSavoie.groupAdmin.service.GroupAdminLocalServiceUtil;
20 import com.pentila.entSavoie.internalMessaging.ThreadSendMessage;
21 import com.pentila.entSavoie.synchroLdap.impl.SynchronizationManager.RoleEnum;
22 import com.pentila.entSavoie.utils.ENTMainUtilsLocalServiceUtil;
23 import com.pentila.entSavoie.utils.ENTOrganizationsUtil;
26 * Class used to generate a full report on the synchronization process
27 * @author Cedric Lecarpentier
30 public class SynchronizationReport {
32 private static long companyId;
34 // User synchronization
35 private static int userSyncTime;
38 private static int nbCreatedUsers;
39 private static Map<Long, List<User>> studentCreationMap;
40 private static Map<Long, List<User>> parentCreationMap;
41 private static Map<Long, List<User>> teacherCreationMap;
42 private static Map<Long, List<User>> otherCreationMap;
45 private static int nbDeactivatedUsers;
46 private static Map<Long, List<User>> studentDeactivationMap;
47 private static Map<Long, List<User>> parentDeactivationMap;
48 private static Map<Long, List<User>> teacherDeactivationMap;
49 private static Map<Long, List<User>> otherDeactivationMap;
52 private static int nbReactivatedUsers;
53 private static Map<Long, List<User>> studentReactivationMap;
54 private static Map<Long, List<User>> parentReactivationMap;
55 private static Map<Long, List<User>> teacherReactivationMap;
56 private static Map<Long, List<User>> otherReactivationMap;
58 // Group synchronization
59 private static int groupSyncTime;
60 private static int nbCreatedGroups;
61 private static int nbEmptyGroups;
62 private static int nbExpiredUsers;
65 private static int studentMembershipTime;
66 private static int nbStudentCreatedMemberships;
67 private static int nbStudentRemovedMemberships;
68 private static Map<Long, Map<Long, List<String>>> studentMembershipCreationMap;
69 private static Map<Long, Map<Long, List<String>>> studentMembershipRemovalMap;
71 // For each school id, the list of students entering the school
72 private static Map<Long, List<User>> studentIncommingSchoolMap;
74 // For each school id, the list of students leaving the school
75 private static Map<Long, List<User>> studentLeavingSchoolMap;
79 private static int parentMembershipTime;
80 private static int nbParentCreatedMemberships;
81 private static int nbParentRemovedMemberships;
84 private static int teacherMembershipTime;
85 private static int nbTeacherCreatedMemberships;
86 private static int nbTeacherRemovedMemberships;
87 private static Map<Long, Map<Long, List<String>>> teacherMembershipCreationMap;
88 private static Map<Long, Map<Long, List<String>>> teacherMembershipRemovalMap;
90 // For each school id, the list of teachers entering the school
91 private static Map<Long, List<User>> teacherIncommingSchoolMap;
93 // For each school id, the list of teachers leaving the school
94 private static Map<Long, List<User>> teacherLeavingSchoolMap;
96 // Other profiles membership
97 private static int otherMembershipTime;
98 private static int nbOtherCreatedMemberships;
99 private static int nbOtherRemovedMemberships;
101 // For each school id, the list of other users entering the school
102 private static Map<Long, List<User>> otherIncommingSchoolMap;
104 // For each school id, the list of other users leaving the school
105 private static Map<Long, List<User>> otherLeavingSchoolMap;
109 private static Map<Long, List<Long>> childParentsMap;
113 * Generate the report at the end of the synchronization process
116 public static String generateSynchroReport() {
118 String tab = " ";
121 report += "<b>User synchronization</b> took "+userSyncTime+" minutes: </br>";
122 report += tab + "Number of created users : " + nbCreatedUsers + "</br>";
123 report += tab + "Number of reactivated users : " + nbReactivatedUsers + "</br>";
124 report += tab + "Number of deactivated users : " + nbDeactivatedUsers + "</br></br>";
126 report += "<b>Group synchronization</b> took "+groupSyncTime+" minutes: </br>";
127 report += tab + "Number of created groups : " + nbCreatedGroups + "</br>";
128 report += tab + "Number of empty groups : " + nbEmptyGroups + "</br>";
129 report += tab + "Number of expired users : " + nbExpiredUsers + "</br></br>";
131 report += "<b>Student membership synchronization</b> took "+studentMembershipTime+" minutes: </br>";
132 report += tab + "Number of created memberships for students : " + nbStudentCreatedMemberships + "</br>";
133 report += tab + "Number of removed memberships for students : " + nbStudentRemovedMemberships + "</br></br>";
135 report += "<b>Parent membership synchronization</b> took "+parentMembershipTime+" minutes: </br>";
136 report += tab + "Number of created memberships for parents : " + nbParentCreatedMemberships + "</br>";
137 report += tab + "Number of removed memberships for parents : " + nbParentRemovedMemberships + "</br></br>";
139 report += "<b>Teacher membership synchronization</b> took "+teacherMembershipTime+" minutes: </br>";
140 report += tab + "Number of created memberships for teachers : " + nbTeacherCreatedMemberships + "</br>";
141 report += tab + "Number of removed memberships for teachers : " + nbTeacherRemovedMemberships + "</br></br>";
143 report += "<b>Other profiles membership synchronization</b> took "+otherMembershipTime+" minutes: </br>";
144 report += tab + "Number of created memberships for other profiles : " + nbOtherCreatedMemberships + "</br>";
145 report += tab + "Number of removed memberships for other profiles : " + nbOtherRemovedMemberships + "</br>";
151 * Notify the creation of a user
152 * @param school : the user school
153 * @param student : the student
155 public static void notifyCreation(Organization school, User user, RoleEnum roleEnum) {
159 case STUDENT_ROLE : addUserToMap(school, user, studentCreationMap); _log.info("notifyCreation student "+user.getFullName() + " for school "+school.getName()); break;
160 case PARENT_ROLE : addUserToMap(school, user, parentCreationMap); _log.info("notifyCreation parent "+user.getFullName() + " for school "+school.getName()); break;
161 case TEACHER_ROLE : addUserToMap(school, user, teacherCreationMap); _log.info("notifyCreation teacher "+user.getFullName() + " for school "+school.getName()); break;
162 case OTHER_ROLE : addUserToMap(school, user, otherCreationMap); _log.info("notifyCreation other "+user.getFullName() + " for school "+school.getName()); break;
168 * Notify the reactivation of a user
169 * @param school : the user school
170 * @param student : the student
172 public static void notifyReactivation(Organization school, User user, RoleEnum roleEnum) {
174 nbReactivatedUsers++;
176 case STUDENT_ROLE : addUserToMap(school, user, studentReactivationMap); _log.info("notifyReactivation student "+user.getFullName()); break;
177 case PARENT_ROLE : addUserToMap(school, user, parentReactivationMap); _log.info("notifyReactivation parent "+user.getFullName()); break;
178 case TEACHER_ROLE : addUserToMap(school, user, teacherReactivationMap); _log.info("notifyReactivation teacher "+user.getFullName()); break;
179 case OTHER_ROLE : addUserToMap(school, user, otherReactivationMap); _log.info("notifyReactivation other "+user.getFullName()); break;
184 * Notify the deactivation of a user
185 * @param school : the user school
186 * @param user : the user
188 public static void notifyDeactivation(Organization school, User user, RoleEnum roleEnum) {
190 nbDeactivatedUsers++;
192 case STUDENT_ROLE : addUserToMap(school, user, studentDeactivationMap); _log.info("notifyDeactivation student "+user.getFullName()); break;
193 case PARENT_ROLE : addUserToMap(school, user, parentDeactivationMap); _log.info("notifyDeactivation parent "+user.getFullName()); break;
194 case TEACHER_ROLE : addUserToMap(school, user, teacherDeactivationMap); _log.info("notifyDeactivation teacher "+user.getFullName()); break;
195 case OTHER_ROLE : addUserToMap(school, user, otherDeactivationMap); _log.info("notifyDeactivation other "+user.getFullName()); break;
202 * Method that adds a user to the corresponding map
207 private static void addUserToMap(Organization school, User user, Map<Long, List<User>> map) {
209 if (school != null) {
210 if (map.containsKey(school.getOrganizationId())) {
211 map.get(school.getOrganizationId()).add(user);
213 List<User> userList = new ArrayList<User>();
215 map.put(school.getOrganizationId(), userList);
221 * Method that adds a student to the corresponding map
224 * @param schoolMap schoolId - userId - List of classGroup names
226 private static void addUserToClassMap(Organization school, User user, Organization classGroup, Map<Long, Map<Long, List<String>>> schoolMap) {
228 if (school != null) {
230 // Build group/class name
231 String classGroupName = classGroup.getName().substring(school.getName().length() + 3);
233 // Skip ' - Parents', '- Personnel' and '- Enseignants' organizations
234 if (classGroup.getName().endsWith(OrganizationConstants.ORG_SUFFIX_PARENTS) || classGroup.getName().endsWith(OrganizationConstants.ORG_SUFFIX_TEACHERS) || classGroup.getName().endsWith(OrganizationConstants.ORG_SUFFIX_PERSONNELS)) {
238 Map<Long, List<String>> userMap;
239 if (schoolMap.containsKey(school.getOrganizationId())) {
240 userMap = schoolMap.get(school.getOrganizationId());
242 userMap = new HashMap<Long, List<String>>();
245 if (userMap.containsKey(user.getUserId())) {
246 // Avoid duplicate classes (for example classic class + same class as main teacher)
247 if (!userMap.get(user.getUserId()).contains(classGroupName)) {
248 userMap.get(user.getUserId()).add(classGroupName);
251 List<String> classGroupList = new ArrayList<String>();
252 classGroupList.add(classGroupName);
253 userMap.put(user.getUserId(), classGroupList);
255 schoolMap.put(school.getOrganizationId(), userMap);
262 * Notify the creation of a student membership from a classGroup
263 * @param school : the student school
264 * @param student : the student
265 * @param classGroup : the organizationId of the class or group
267 public static void notifyStudentMembershipCreation(User student, Organization classGroup) {
269 nbStudentCreatedMemberships++;
271 Organization parentOrg = classGroup.getParentOrganization();
272 if (parentOrg.getParentOrganizationId() == 0) {
273 _log.info("notifyStudentMembershipCreation : ClassGroup "+classGroup.getName()+" is a school : adding it to studentIncommingSchoolMap");
274 // classGroup is a school, then its parent is the root org, and then we add the teacher to the 'incoming' list for this school
275 if (studentIncommingSchoolMap.containsKey(classGroup.getOrganizationId())) {
276 studentIncommingSchoolMap.get(classGroup.getOrganizationId()).add(student);
277 _log.info("notifyStudentMembershipCreation : ClassGroup "+classGroup.getName()+" is a school : adding it to studentIncommingSchoolMap1 : "+classGroup.getOrganizationId()+" / "+student.getFullName());
279 List<User> userList = new ArrayList<User>();
280 userList.add(student);
281 studentIncommingSchoolMap.put(classGroup.getOrganizationId(), userList);
282 _log.info("notifyStudentMembershipCreation : ClassGroup "+classGroup.getName()+" is a school : adding it to studentIncommingSchoolMap2 : "+classGroup.getOrganizationId()+" / "+student.getFullName());
285 // classGroup is a class or a group, then its parent is the school
286 _log.info("notifyStudentMembershipCreation : ClassGroup "+classGroup.getName()+" is a class/group");
287 addUserToClassMap(parentOrg, student, classGroup, studentMembershipCreationMap);
289 } catch (Exception e) {
290 _log.error("Error when notifying student membership creation from org "+classGroup.getName(), e);
297 * Notify the removal of a given student from a classGroup
298 * @param student : the student
299 * @param classGroup : the organizationId of the class or group
301 public static void notifyStudentMembershipRemoval(User student, Organization classGroup) {
303 nbStudentRemovedMemberships++;
305 Organization parentOrg = classGroup.getParentOrganization();
306 if (parentOrg.getParentOrganizationId() == 0) {
307 _log.info("notifyStudentMembershipRemoval : ClassGroup "+classGroup.getName()+" is a school : adding it to studentLeavingSchoolMap");
308 // classGroup is a school, then its parent is the root org, and then we add the student to the 'incoming' list for this school
309 if (studentLeavingSchoolMap.containsKey(classGroup.getOrganizationId())) {
310 studentLeavingSchoolMap.get(classGroup.getOrganizationId()).add(student);
311 _log.info("notifyStudentMembershipRemoval : ClassGroup "+classGroup.getName()+" is a school : adding it to studentLeavingSchoolMap1 : "+classGroup.getOrganizationId()+" / "+student.getFullName());
313 List<User> userList = new ArrayList<User>();
314 userList.add(student);
315 studentLeavingSchoolMap.put(classGroup.getOrganizationId(), userList);
316 _log.info("notifyStudentMembershipRemoval : ClassGroup "+classGroup.getName()+" is a school : adding it to studentLeavingSchoolMap2 : "+classGroup.getOrganizationId()+" / "+student.getFullName());
319 // classGroup is a class or a group, then its parent is the school
320 _log.info("notifyStudentMembershipRemoval : ClassGroup "+classGroup.getName()+" is a class/group");
321 addUserToClassMap(parentOrg, student, classGroup, studentMembershipRemovalMap);
323 } catch (Exception e) {
324 _log.error("Error when notifying student membership removal from org "+classGroup.getName(), e);
329 * Notify the creation of a teacher membership from a classGroup
330 * @param student : the teacher
331 * @param classGroup : the organizationId of the class or group
333 public static void notifyTeacherMembershipCreation(User teacher, Organization classGroup) {
335 nbTeacherCreatedMemberships++;
337 Organization parentOrg = classGroup.getParentOrganization();
338 if (parentOrg.getParentOrganizationId() == 0) {
339 _log.debug("notifyTeacherMembershipCreation : ClassGroup "+classGroup.getName()+" is a school : adding it to teacherIncommingSchoolMap");
340 // classGroup is a school, then its parent is the root org, and then we add the teacher to the 'incoming' list for this school
341 if (teacherIncommingSchoolMap.containsKey(classGroup.getOrganizationId())) {
342 teacherIncommingSchoolMap.get(classGroup.getOrganizationId()).add(teacher);
343 _log.debug("notifyTeacherMembershipCreation : ClassGroup "+classGroup.getName()+" is a school : adding it to teacherIncommingSchoolMap1 : "+classGroup.getOrganizationId()+" / "+teacher.getFullName());
345 List<User> userList = new ArrayList<User>();
346 userList.add(teacher);
347 teacherIncommingSchoolMap.put(classGroup.getOrganizationId(), userList);
348 _log.debug("notifyTeacherMembershipCreation : ClassGroup "+classGroup.getName()+" is a school : adding it to teacherIncommingSchoolMap2 : "+classGroup.getOrganizationId()+" / "+teacher.getFullName());
351 // classGroup is a class or a group, then its parent is the school
352 _log.debug("notifyTeacherMembershipCreation : ClassGroup "+classGroup.getName()+" is a class/group");
353 addUserToClassMap(parentOrg, teacher, classGroup, teacherMembershipCreationMap);
355 } catch (Exception e) {
356 _log.error("Error when notifying teacher membership creation into org "+classGroup.getName(), e);
363 * Notify the removal of a given teacher from a classGroup
364 * @param student : the teacher
365 * @param classGroup : the organizationId of the class or group
367 public static void notifyTeacherMembershipRemoval(User teacher, Organization classGroup) {
369 nbTeacherRemovedMemberships++;
371 Organization parentOrg = classGroup.getParentOrganization();
372 if (parentOrg.getParentOrganizationId() == 0) {
373 // classGroup is a school, then its parent is the root org, and then we add the teacher to the 'leaving' list for this school
374 _log.info("notifyTeacherMembershipRemoval : ClassGroup "+classGroup.getName()+" is a school : adding it to teacherLeavingSchoolMap");
375 if (teacherLeavingSchoolMap.containsKey(classGroup.getOrganizationId())) {
376 teacherLeavingSchoolMap.get(classGroup.getOrganizationId()).add(teacher);
377 _log.info("notifyTeacherMembershipRemoval : ClassGroup "+classGroup.getName()+" is a school : adding it to teacherLeavingSchoolMap1 : "+classGroup.getOrganizationId()+" / "+teacher.getFullName());
379 List<User> userList = new ArrayList<User>();
380 userList.add(teacher);
381 teacherLeavingSchoolMap.put(classGroup.getOrganizationId(), userList);
382 _log.info("notifyTeacherMembershipRemoval : ClassGroup "+classGroup.getName()+" is a school : adding it to teacherLeavingSchoolMap2 : "+classGroup.getOrganizationId()+" / "+teacher.getFullName());
385 // classGroup is a class or a group, then its parent is the school
386 _log.info("notifyTeacherMembershipRemoval : ClassGroup "+classGroup.getName()+" is a class/group");
387 addUserToClassMap(parentOrg, teacher, classGroup, teacherMembershipRemovalMap);
389 } catch (Exception e) {
390 _log.error("Error when notifying teacher membership removal from org "+classGroup.getName(), e);
395 * Notify the creation of a user membership from a classGroup
396 * @param student : the user
397 * @param classGroup : the organizationId of the class or group
399 public static void notifyOtherMembershipCreation(User user, Organization classGroup) {
401 nbOtherCreatedMemberships++;
403 Organization parentOrg = classGroup.getParentOrganization();
404 if (parentOrg.getParentOrganizationId() == 0) {
405 // classGroup is a school, then its parent is the root org, and then we add the user to the 'incomming' list for this school
406 _log.info("notifyOtherMembershipCreation : ClassGroup "+classGroup.getName()+" is a school : adding it to otherIncommingSchoolMap");
407 if (otherIncommingSchoolMap.containsKey(classGroup.getOrganizationId())) {
408 otherIncommingSchoolMap.get(classGroup.getOrganizationId()).add(user);
410 List<User> userList = new ArrayList<User>();
412 otherIncommingSchoolMap.put(classGroup.getOrganizationId(), userList);
415 // classGroup is a school-level organization => do nothing
416 _log.info("notifyOtherMembershipCreation : ClassGroup "+classGroup.getName()+" is a school-level organization => do nothing");
418 } catch (Exception e) {
419 _log.error("Error when notifying other membership removal from org "+classGroup.getName(), e);
425 * Notify the removal of a given user from a classGroup
426 * @param user : the user
427 * @param classGroup : the organizationId of the class or group
429 public static void notifyOtherMembershipRemoval(User user, Organization classGroup) {
431 nbOtherRemovedMemberships++;
433 Organization parentOrg = classGroup.getParentOrganization();
434 if (parentOrg.getParentOrganizationId() == 0) {
435 // classGroup is a school, then its parent is the root org, and then we add the user to the 'leaving' list for this school
436 _log.info("notifyOtherMembershipRemoval : ClassGroup "+classGroup.getName()+" is a school : adding it to otherLeavingSchoolMap");
437 if (otherLeavingSchoolMap.containsKey(classGroup.getOrganizationId())) {
438 otherLeavingSchoolMap.get(classGroup.getOrganizationId()).add(user);
440 List<User> userList = new ArrayList<User>();
442 otherLeavingSchoolMap.put(classGroup.getOrganizationId(), userList);
445 // classGroup is a school-level organization => do nothing
446 _log.info("notifyOtherMembershipRemoval : ClassGroup "+classGroup.getName()+" is a school-level organization => do nothing");
448 } catch (Exception e) {
449 _log.error("Error when notifying parent membership removal from org "+classGroup.getName(), e);
455 * Entry point for the report generation for school managers
457 public static void generateReportForSchoolManagers() {
460 // Technical team user
461 Long defaultSender = ENTMainUtilsLocalServiceUtil.getEntConfirmationSenderId(companyId);
462 User admin = UserLocalServiceUtil.getUser(defaultSender);
463 String today = new SimpleDateFormat("dd/MM/yyyy").format(new Date());
465 //ResourceBundle messages = ResourceBundle.getBundle("content.Language", admin.getLocale());
467 // Get the school list
468 Organization rootOrg = ENTOrganizationsUtil.getOrCreateRootOrg(companyId);
470 // Loop over the map schools
471 for (Organization school : rootOrg.getSuborganizations()) {
473 if (!isEvolutionInSchool(school.getOrganizationId())) {
474 _log.info("No evolution to notice in school "+school.getName()+" => no report email sent");
478 // Get the list of school managers
479 List<User> schoolManagerList = getSchoolManagers(school);
481 Set<Long> recipientList = new HashSet<Long>();
482 for (User schoolManager : schoolManagerList) {
483 recipientList.add(schoolManager.getUserId());
486 // Build message subject and content
487 String reportSubject = "Rapport de synchronisation AAF du "+today;
489 String reportContent =
491 " div.notification-container {width: 96%;border-radius: 5px 5px 5px 5px;border: 2px solid #8b9ea8;} " +
492 " div.notification-header {height: 17px;padding: 8px;font-size: 16px;color: #fff;background:#8b9ea8} " +
493 " .notification-content {margin: 8px;padding: 5px;font-family: \"Open sans\"}" +
495 "<div class='notification-container'>"+
496 " <div class='notification-header'>Rapport de synchronisation</div>" +
497 " <p class='notification-content'>Bonjour,</p>" +
498 " <p class='notification-content'>" +
499 " Voici le rapport détaillé de la synchronisation des données AAF " +
500 "(Annuaire académique fédérateur) issues de vos bases STSWeb et " +
501 "Siècle à la date du " + today +
504 reportContent += generateStudentAndParentReport(school);
505 reportContent += generateTeacherReport(school);
506 reportContent += generateOtherReport(school);
507 reportContent += "</div>";
509 _log.info("Sending message for school "+school.getName()+" : report="+reportContent);
510 ThreadSendMessage message = new ThreadSendMessage(admin, recipientList, reportSubject, reportContent, JSONFactoryUtil.createJSONArray(), true, false);
514 } catch (Exception e) {
515 _log.error("Error when sending report to school managers ", e);
521 * Returns a list of recipeints for a given school : school managers + local admins
525 private static List<User> getSchoolManagers(Organization school) {
527 List<User> schoolManagerList = new ArrayList<User>();
529 List<Organization> userOrgList = new ArrayList<Organization>();
530 userOrgList.add(school);
533 List<User> localAdminList = GroupAdminLocalServiceUtil.getGroupAdminsFromEtab(userOrgList, companyId);
534 if (localAdminList != null) {
535 for (User adminUser : localAdminList) {
536 _log.info("Found local admin for school "+school.getName()+" : "+adminUser.getFullName());
537 schoolManagerList.add(adminUser);
540 _log.error("The retrieved local admin list is null for school "+school.getName());
542 return schoolManagerList;
547 * Generate the report for students
551 private static String generateStudentAndParentReport(Organization school) {
552 String studentReport = "";
556 if (isStudentEvolution(school.getOrganizationId())) {
558 _log.info("there is student evolution");
559 studentReport += "<p class='notification-content'>";
560 studentReport += "<b>Elèves et responsables</b></br>";
562 // Incomming students
563 if (isStudentIncoming(school.getOrganizationId())) {
564 _log.info("there is student incomming");
565 List<User> incomingStudents = getIncommingStudents(school);
567 studentReport += "Entrées: ";
568 studentReport += SynchronizationUtils.printAsString(incomingStudents);
569 studentReport += "</br>";
574 List<Long> leavingStudentList = new ArrayList<Long>();
575 if (isStudentLeaving(school.getOrganizationId())) {
576 _log.info("there is student leaving");
577 List<User> leavingStudents = getLeavingStudents(school);
578 for (User leavingStudent : leavingStudents) {
579 leavingStudentList.add(leavingStudent.getUserId());
581 studentReport += "Sorties: ";
582 studentReport += SynchronizationUtils.printAsString(leavingStudents);
584 studentReport += "</br>";
588 if (isStudentMembershipEvolution(school.getOrganizationId())) {
590 studentReport += "Mouvements dans les classes et groupes (hors sorties de l'établissement):</br>";
592 studentReport += "<table border=\"1\" style=\"width:100%\">";
593 studentReport += "<tr>";
594 studentReport += "<th>Elève</th>";
595 studentReport += "<th>Responsables</th>";
596 studentReport += "<th>Groupes et classes intégrés</th>";
597 studentReport += "<th>Groupes et classes quittés</th>";
598 studentReport += "</tr>";
600 List<Long> processedStudentList = new ArrayList<Long>();
602 // For each student : added memberships
603 if (isStudentMembershipCreation(school.getOrganizationId())) {
604 Map<Long, List<String>> studentMap = studentMembershipCreationMap.get(school.getOrganizationId());
605 if (studentMap != null && studentMap.keySet().size() > 0) {
606 for (Long studentId : studentMap.keySet()) {
607 processedStudentList.add(studentId);
609 User student = UserLocalServiceUtil.getUser(studentId);
611 // Get removed memberships for this student
612 List<String> leftGroups = new ArrayList<String>();
613 if (isStudentMembershipRemoval(school.getOrganizationId()) && studentMembershipRemovalMap.get(school.getOrganizationId()).containsKey(studentId)) {
614 leftGroups = studentMembershipRemovalMap.get(school.getOrganizationId()).get(studentId);
617 studentReport += "<tr>";
618 studentReport += "<td>" + student.getFullName() + "</td><td>"+getParentNames(student)+"</td><td>"+getGroupClassNames(studentMap.get(studentId)) + "</td><td>"+getGroupClassNames(leftGroups)+"</td>";
619 studentReport += "</tr>";
620 } catch (Exception e) {
621 _log.error("Error when generating report for student "+studentId);
627 // Now print students that have only removed memberships
628 if (isStudentMembershipRemoval(school.getOrganizationId())) {
629 Map<Long, List<String>> studentMap = studentMembershipRemovalMap.get(school.getOrganizationId());
630 if (studentMap != null && studentMap.keySet().size() > 0) {
631 for (Long studentId : studentMap.keySet()) {
632 // Do not print students already processed for membership creation and also students that are leaving the school
633 if (processedStudentList.contains(studentId) || leavingStudentList.contains(studentId)) {
637 User student = UserLocalServiceUtil.getUser(studentId);
639 studentReport += "<tr>";
640 studentReport += "<td>" + student.getFullName() + "</td><td>"+getParentNames(student)+"</td><td></td><td>"+getGroupClassNames(studentMap.get(studentId)) + "</td>";
641 studentReport += "</tr>";
642 } catch (Exception e) {
643 _log.error("Error when generating report for student "+studentId);
649 studentReport += "</table>";
652 studentReport += "</br>Remarque : les responsables légaux ne quittent pas l'établissement si au moins un des enfants de la fratrie est encore inscrit.</br>";
653 studentReport += "</p>";
656 } catch (Exception e) {
657 _log.error("Error when generating student report for school "+school.getName());
659 return studentReport;
664 * Generate report for all other people
668 private static String generateTeacherReport(Organization school) {
670 String teacherReport = "";
673 if (isTeacherEvolution(school.getOrganizationId())) {
675 _log.info("there is teacher evolution");
676 teacherReport += "<p class='notification-content'>";
677 teacherReport += "<b>Enseignants</b></br>";
679 // Created and reactivated teachers
680 if (isTeacherIncoming(school.getOrganizationId())) {
681 _log.info("Teachers are incomming");
682 List<User> incomingTeachers = getIncommingTeachers(school);
683 teacherReport += "Entrées: ";
684 teacherReport += SynchronizationUtils.printAsString(incomingTeachers) + "</br>";
688 // Deactivated teachers
689 List<Long> leavingTeacherList = new ArrayList<Long>();
690 if (isTeacherLeaving(school.getOrganizationId())) {
691 _log.info("Teachers are leaving");
692 List<User> leavingTeachers = getLeavingTeachers(school);
693 for (User leavingTeacher : leavingTeachers) {
694 leavingTeacherList.add(leavingTeacher.getUserId());
697 teacherReport += "Sorties: ";
698 teacherReport += SynchronizationUtils.printAsString(leavingTeachers) + "</br></br>";
702 if (isTeacherMembershipEvolution(school.getOrganizationId())) {
704 teacherReport += "Les mouvements d'enseignants sont les suivants:</br>";
706 teacherReport += "<table border=\"1\" style=\"width:100%\">";
707 teacherReport += "<tr>";
708 teacherReport += "<th>Enseignant</th>";
709 teacherReport += "<th>Groupes et classes nouvellement affectés</th>";
710 teacherReport += "<th>Groupes et classes quittés</th>";
711 teacherReport += "</tr>";
713 List<Long> processedTeacherList = new ArrayList<Long>();
715 // For each teacher : added memberships
716 if (isTeacherMembershipCreation(school.getOrganizationId())) {
717 Map<Long, List<String>> teacherMap = teacherMembershipCreationMap.get(school.getOrganizationId());
718 if (teacherMap != null && teacherMap.keySet().size() > 0) {
719 for (Long teacherId : teacherMap.keySet()) {
720 processedTeacherList.add(teacherId);
722 User teacher = UserLocalServiceUtil.getUser(teacherId);
724 // Get removed memberships for this teacher
725 List<String> leftGroups = new ArrayList<String>();
726 if (isTeacherMembershipRemoval(school.getOrganizationId())) {
727 if (teacherMembershipRemovalMap.get(school.getOrganizationId()).containsKey(teacherId)) {
728 leftGroups = teacherMembershipRemovalMap.get(school.getOrganizationId()).get(teacherId);
732 teacherReport += "<tr>";
733 //HtmlUtil.escape(html);
734 teacherReport += "<td>" + teacher.getFullName() + "</td><td>"+getGroupClassNames(teacherMap.get(teacherId)) + "</td><td>"+getGroupClassNames(leftGroups)+"</td>";
735 teacherReport += "</tr>";
736 } catch (Exception e) {
737 _log.error("Error when generating report for teacher "+teacherId);
743 // Add removed teacher memberships
744 if (isTeacherMembershipRemoval(school.getOrganizationId())) {
745 Map<Long, List<String>> teacherMap = teacherMembershipRemovalMap.get(school.getOrganizationId());
746 if (teacherMap != null && teacherMap.keySet().size() > 0) {
747 for (Long teacherId : teacherMap.keySet()) {
748 // Skip teachers that leave the school or that have been processed in the 'incomming' previous loop
749 if (leavingTeacherList.contains(teacherId) || processedTeacherList.contains(teacherId)) {
750 _log.info("Already processed teacher "+teacherId);
754 User teacher = UserLocalServiceUtil.getUser(teacherId);
756 teacherReport += "<tr>";
757 //HtmlUtil.escape(html);
758 teacherReport += "<td>" + teacher.getFullName() + "</td><td></td><td>"+getGroupClassNames(teacherMap.get(teacherId))+"</td>";
759 teacherReport += "</tr>";
760 } catch (Exception e) {
761 _log.error("Error when generating report for teacher "+teacherId);
766 teacherReport += "</table>";
767 teacherReport += "</p>";
770 } catch (Exception e) {
771 _log.error("Error when generating teacher report for school "+school.getName());
773 return teacherReport;
777 * Generate report for all other people
781 private static String generateOtherReport(Organization school) {
782 String otherReport = "";
785 if (isOtherEvolution(school.getOrganizationId())) {
786 _log.info("generateOtherReport : is other evolution");
787 otherReport += "<p class='notification-content'>";
788 otherReport += "<b>Personnels</b></br>";
790 // Created and reactivated users + created memberships
791 if (isOtherIncoming(school.getOrganizationId())) {
792 _log.info("generateOtherReport : is other incomming");
793 List<User> incomingOthers = getIncommingOthers(school);
795 otherReport += "Entrées: ";
796 otherReport += SynchronizationUtils.printAsString(incomingOthers);
797 otherReport += "</br>";
801 // Deactivated users + removed memberships
802 if (isOtherLeaving(school.getOrganizationId())) {
803 _log.info("generateOtherReport : is other leaving");
804 List<User> leavingOthers = getLeavingOthers(school);
806 otherReport += "Sorties: ";
807 otherReport += SynchronizationUtils.printAsString(leavingOthers);
808 otherReport += "</br>";
810 otherReport += "</br>";
811 otherReport += "</p>";
814 } catch (Exception e) {
815 _log.error("Error when generating other report for school "+school.getName());
822 * Returns the list of students incomming in the given school
826 private static List<User> getIncommingStudents(Organization school) {
828 List<User> incomingStudents = new ArrayList<User>();
829 if (studentCreationMap.get(school.getOrganizationId()) != null) {
830 _log.info("getIncommingStudents : "+studentCreationMap.get(school.getOrganizationId()).size()+" newly created students for school "+school.getName());
831 incomingStudents.addAll(studentCreationMap.get(school.getOrganizationId()));
833 if (studentReactivationMap.get(school.getOrganizationId()) != null) {
834 _log.info("getIncommingStudents : "+studentReactivationMap.get(school.getOrganizationId()).size()+" reactivated students for school "+school.getName());
835 incomingStudents.addAll(studentReactivationMap.get(school.getOrganizationId()));
837 if (studentIncommingSchoolMap.get(school.getOrganizationId()) != null) {
838 _log.info("getIncommingStudents : "+studentIncommingSchoolMap.get(school.getOrganizationId()).size()+" incomming students for school "+school.getName());
839 incomingStudents.addAll(studentIncommingSchoolMap.get(school.getOrganizationId()));
842 _log.info("getIncommingStudents : total of "+incomingStudents.size()+" incomming students for school "+school.getName());
843 return SynchronizationUtils.unique(incomingStudents);
847 * Returns the list of students leaving the given school
851 private static List<User> getLeavingStudents(Organization school) {
853 List<User> leavingStudents = new ArrayList<User>();
854 if (studentDeactivationMap.get(school.getOrganizationId()) != null) {
855 _log.info("getLeavingStudents : "+studentDeactivationMap.get(school.getOrganizationId()).size()+" deactivated students for school "+school.getName());
856 leavingStudents.addAll(studentDeactivationMap.get(school.getOrganizationId()));
858 if (studentLeavingSchoolMap.get(school.getOrganizationId()) != null) {
859 leavingStudents.addAll(studentLeavingSchoolMap.get(school.getOrganizationId()));
860 _log.info("getLeavingStudents : "+studentLeavingSchoolMap.get(school.getOrganizationId()).size()+" leaving students for school "+school.getName());
862 _log.info("getLeavingStudents : total of "+leavingStudents.size()+" leaving students for school "+school.getName());
863 return SynchronizationUtils.unique(leavingStudents);
868 * Returns the list of teachers incomming in the given school
872 private static List<User> getIncommingTeachers(Organization school) {
874 List<User> incomingTeachers = new ArrayList<User>();
875 if (teacherCreationMap.get(school.getOrganizationId()) != null) {
876 _log.info("getIncommingTeachers : "+teacherCreationMap.get(school.getOrganizationId()).size()+" newly created teachers for school "+school.getName());
877 incomingTeachers.addAll(teacherCreationMap.get(school.getOrganizationId()));
879 if (teacherReactivationMap.get(school.getOrganizationId()) != null) {
880 _log.info("getIncommingTeachers : "+teacherReactivationMap.get(school.getOrganizationId()).size()+" reactivated teachers for school "+school.getName());
881 incomingTeachers.addAll(teacherReactivationMap.get(school.getOrganizationId()));
883 if (teacherIncommingSchoolMap.get(school.getOrganizationId()) != null) {
884 _log.info("getIncommingTeachers : "+teacherIncommingSchoolMap.get(school.getOrganizationId()).size()+" incomming teachers for school "+school.getName());
885 incomingTeachers.addAll(teacherIncommingSchoolMap.get(school.getOrganizationId()));
888 _log.info("getIncommingTeachers : total of "+incomingTeachers.size()+" incomming teachers for school "+school.getName());
889 return SynchronizationUtils.unique(incomingTeachers);
893 * Returns the list of teachers leaving the given school
897 private static List<User> getLeavingTeachers(Organization school) {
899 List<User> leavingTeachers = new ArrayList<User>();
900 if (teacherDeactivationMap.get(school.getOrganizationId()) != null) {
901 _log.info("getLeavingTeachers : "+teacherDeactivationMap.get(school.getOrganizationId()).size()+" deactivated teachers for school "+school.getName());
902 leavingTeachers.addAll(teacherDeactivationMap.get(school.getOrganizationId()));
904 if (teacherLeavingSchoolMap.get(school.getOrganizationId()) != null) {
905 leavingTeachers.addAll(teacherLeavingSchoolMap.get(school.getOrganizationId()));
906 _log.info("getLeavingTeachers : "+teacherLeavingSchoolMap.get(school.getOrganizationId()).size()+" leaving teachers for school "+school.getName());
908 _log.info("getLeavingTeachers : total of "+leavingTeachers.size()+" leaving teachers for school "+school.getName());
909 return SynchronizationUtils.unique(leavingTeachers);
913 * Returns the list of incomming other users in the given school
917 private static List<User> getIncommingOthers(Organization school) {
919 List<User> incomingOthers = new ArrayList<User>();
920 if (otherCreationMap.get(school.getOrganizationId()) != null) {
921 incomingOthers.addAll(otherCreationMap.get(school.getOrganizationId()));
923 if (otherReactivationMap.get(school.getOrganizationId()) != null) {
924 incomingOthers.addAll(otherReactivationMap.get(school.getOrganizationId()));
926 if (otherIncommingSchoolMap.get(school.getOrganizationId()) != null) {
927 incomingOthers.addAll(otherIncommingSchoolMap.get(school.getOrganizationId()));
929 _log.info("getIncommingOthers returns "+incomingOthers.size()+" users for school "+school.getName());
930 return SynchronizationUtils.unique(incomingOthers);
934 * Returns the list of leaving other users in the given school
938 private static List<User> getLeavingOthers(Organization school) {
940 List<User> leavingOthers = new ArrayList<User>();
941 if (otherDeactivationMap.get(school.getOrganizationId()) != null) {
942 leavingOthers.addAll(otherDeactivationMap.get(school.getOrganizationId()));
944 if (otherLeavingSchoolMap.get(school.getOrganizationId()) != null) {
945 leavingOthers.addAll(otherLeavingSchoolMap.get(school.getOrganizationId()));
947 _log.info("getLeavingOthers returns "+leavingOthers.size()+" users for school "+school.getName());
948 return SynchronizationUtils.unique(leavingOthers);
953 * Register a child with one of its parent
957 public static void addChildParentLink(User child, User parent) {
959 if (childParentsMap.containsKey(child.getUserId())) {
960 // Add parent if not present
961 if (!childParentsMap.get(child.getUserId()).contains(parent.getUserId())) {
962 childParentsMap.get(child.getUserId()).add(parent.getUserId());
965 List<Long> parentList = new ArrayList<Long>();
966 parentList.add(parent.getUserId());
967 childParentsMap.put(child.getUserId(), parentList);
973 * Returns a string that concatenates the list of student's parents
977 private static String getParentNames(User child) {
978 String parentNames = "";
979 if (childParentsMap.containsKey(child.getUserId())) {
980 List<Long> parentUserIds = childParentsMap.get(child.getUserId());
981 if (parentUserIds != null && parentUserIds.size() > 0) {
982 for (int idx = 0 ; idx < parentUserIds.size() ; idx++) {
983 Long parentId = parentUserIds.get(idx);
985 User parent = UserLocalServiceUtil.getUser(parentId);
986 parentNames += parent.getFullName();
987 if (idx != parentUserIds.size() - 1) {
990 } catch (Exception e) {
991 _log.error("Error when getting parent with id "+parentId);
995 _log.error("Error : child "+child.getFullName()+" should have parents linked to");
998 _log.error("Error : child "+child.getFullName()+" should have parents linked to");
1004 private static String getGroupClassNames(List<String> groupClassList) {
1007 for (int idx = 0 ; idx < groupClassList.size() ; idx++) {
1008 String groupClassName = groupClassList.get(idx);
1009 res += groupClassName;
1010 if (idx != groupClassList.size() - 1) {
1018 * Return true if there is at least 1 modification amongst students, parents, teachers and other users
1022 private static boolean isEvolutionInSchool (Long schoolId) {
1024 return isStudentEvolution(schoolId) || isTeacherEvolution(schoolId) || isOtherEvolution(schoolId);
1029 * Return true if there is at least 1 modification amongst students and parents
1033 private static boolean isStudentEvolution(Long schoolId) {
1034 return isStudentIncoming(schoolId) || isStudentLeaving(schoolId) || isStudentMembershipEvolution(schoolId);
1037 private static boolean isStudentIncoming(Long schoolId) {
1038 return ((studentCreationMap.get(schoolId) != null && studentCreationMap.get(schoolId).size() > 0)
1039 || (studentReactivationMap.get(schoolId) != null && studentReactivationMap.get(schoolId).size() > 0)
1040 || (studentIncommingSchoolMap.get(schoolId) != null && studentIncommingSchoolMap.get(schoolId).size() > 0));
1043 private static boolean isStudentLeaving(Long schoolId) {
1044 return ((studentDeactivationMap.get(schoolId) != null && studentDeactivationMap.get(schoolId).size() > 0)
1045 || (studentLeavingSchoolMap.get(schoolId) != null && studentLeavingSchoolMap.get(schoolId).size() > 0));
1048 private static boolean isStudentMembershipEvolution(Long schoolId) {
1049 return isStudentMembershipCreation(schoolId) || isStudentMembershipRemoval(schoolId);
1052 private static boolean isStudentMembershipCreation(Long schoolId) {
1053 return (studentMembershipCreationMap.get(schoolId) != null && studentMembershipCreationMap.get(schoolId).size() > 0);
1056 private static boolean isStudentMembershipRemoval(Long schoolId) {
1057 return (studentMembershipRemovalMap.get(schoolId) != null && studentMembershipRemovalMap.get(schoolId).size() > 0);
1061 * Return true if there is at least 1 modification amongst teachers
1065 private static boolean isTeacherEvolution(Long schoolId) {
1066 return isTeacherIncoming(schoolId) || isTeacherLeaving(schoolId) || isTeacherMembershipEvolution(schoolId);
1069 private static boolean isTeacherIncoming(Long schoolId) {
1070 return ((teacherCreationMap.get(schoolId) != null && teacherCreationMap.get(schoolId).size() > 0)
1071 || (teacherReactivationMap.get(schoolId) != null && teacherReactivationMap.get(schoolId).size() > 0)
1072 || (teacherIncommingSchoolMap.get(schoolId) != null && teacherIncommingSchoolMap.get(schoolId).size() > 0));
1075 private static boolean isTeacherLeaving(Long schoolId) {
1076 return ((teacherDeactivationMap.get(schoolId) != null && teacherDeactivationMap.get(schoolId).size() > 0)
1077 || (teacherLeavingSchoolMap.get(schoolId) != null && teacherLeavingSchoolMap.get(schoolId).size() > 0));
1080 private static boolean isTeacherMembershipEvolution(Long schoolId) {
1081 return isTeacherMembershipCreation(schoolId) || isTeacherMembershipRemoval(schoolId);
1084 private static boolean isTeacherMembershipCreation(Long schoolId) {
1085 return (teacherMembershipCreationMap.get(schoolId) != null && teacherMembershipCreationMap.get(schoolId).size() > 0);
1088 private static boolean isTeacherMembershipRemoval(Long schoolId) {
1089 return (teacherMembershipRemovalMap.get(schoolId) != null && teacherMembershipRemovalMap.get(schoolId).size() > 0);
1094 * Return true if there is at least 1 modification amongst other users
1098 private static boolean isOtherEvolution(Long schoolId) {
1100 return isOtherIncoming(schoolId) || isOtherLeaving(schoolId);
1104 private static boolean isOtherIncoming(Long schoolId) {
1105 return ((otherCreationMap.get(schoolId) != null && otherCreationMap.get(schoolId).size() > 0)
1106 || (otherReactivationMap.get(schoolId) != null && otherReactivationMap.get(schoolId).size() > 0)
1107 || (otherIncommingSchoolMap.get(schoolId) != null && otherIncommingSchoolMap.get(schoolId).size() > 0));
1110 private static boolean isOtherLeaving(Long schoolId) {
1111 return ((otherDeactivationMap.get(schoolId) != null && otherDeactivationMap.get(schoolId).size() > 0)
1112 || (otherLeavingSchoolMap.get(schoolId) != null && otherLeavingSchoolMap.get(schoolId).size() > 0));
1117 public static void addEmptyGroup() {
1121 public static void addExpiredUser() {
1125 public static void setUserSyncTime(int time) {
1126 userSyncTime = time;
1129 public static void setGroupSyncTime(int time) {
1130 groupSyncTime = time;
1133 public static void setStudentMembershipTime(int time) {
1134 studentMembershipTime = time;
1137 public static void setParentMembershipTime(int time) {
1138 parentMembershipTime = time;
1141 public static void setTeacherMembershipTime(int time) {
1142 teacherMembershipTime = time;
1145 public static void setOtherMembershipTime(int time) {
1146 otherMembershipTime = time;
1150 public static void initReport(long _companyId) {
1152 companyId = _companyId;
1161 studentCreationMap = new HashMap<Long, List<User>>();
1162 parentCreationMap = new HashMap<Long, List<User>>();
1163 teacherCreationMap = new HashMap<Long, List<User>>();
1164 otherCreationMap = new HashMap<Long, List<User>>();
1167 nbReactivatedUsers = 0;
1168 studentReactivationMap = new HashMap<Long, List<User>>();
1169 parentReactivationMap = new HashMap<Long, List<User>>();
1170 teacherReactivationMap = new HashMap<Long, List<User>>();
1171 otherReactivationMap = new HashMap<Long, List<User>>();
1174 nbDeactivatedUsers = 0;
1175 studentDeactivationMap = new HashMap<Long, List<User>>();
1176 parentDeactivationMap = new HashMap<Long, List<User>>();
1177 teacherDeactivationMap = new HashMap<Long, List<User>>();
1178 otherDeactivationMap = new HashMap<Long, List<User>>();
1182 nbCreatedGroups = 0;
1186 // Student memberships
1187 studentMembershipTime = 0;
1188 nbStudentCreatedMemberships = 0;
1189 nbStudentRemovedMemberships = 0;
1190 studentMembershipCreationMap = new HashMap<Long, Map<Long, List<String>>>();
1191 studentMembershipRemovalMap = new HashMap<Long, Map<Long, List<String>>>();
1192 studentIncommingSchoolMap = new HashMap<Long, List<User>>();
1193 studentLeavingSchoolMap = new HashMap<Long, List<User>>();
1195 // Parent memberships
1196 parentMembershipTime = 0;
1197 nbParentCreatedMemberships = 0;
1198 nbParentRemovedMemberships = 0;
1200 // Teacher memberships
1201 teacherMembershipTime = 0;
1202 nbTeacherCreatedMemberships = 0;
1203 nbTeacherRemovedMemberships = 0;
1204 teacherMembershipCreationMap = new HashMap<Long, Map<Long, List<String>>>();
1205 teacherMembershipRemovalMap = new HashMap<Long, Map<Long, List<String>>>();
1206 teacherIncommingSchoolMap = new HashMap<Long, List<User>>();
1207 teacherLeavingSchoolMap = new HashMap<Long, List<User>>();
1209 // Other memberships
1210 otherMembershipTime = 0;
1211 nbOtherCreatedMemberships = 0;
1212 nbOtherRemovedMemberships = 0;
1213 otherIncommingSchoolMap = new HashMap<Long, List<User>>();
1214 otherLeavingSchoolMap = new HashMap<Long, List<User>>();
1216 childParentsMap = new HashMap<Long, List<Long>>();
1219 private static Log _log = LogFactoryUtil.getLog(SynchronizationReport.class);