UserService.java
/**
* TFG 75.678 - TFG Desarrollo web 2020 e-Learning for Schools
* Copyright (C) 2020 Eduardo Rodriguez Carro
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.uoc.tfg.sel.service;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.uoc.tfg.sel.repository.EventJobRepository;
import org.uoc.tfg.sel.repository.UserRepository;
import org.uoc.tfg.sel.repository.UserTypeRepository;
import org.uoc.tfg.sel.repository.model.EventJob;
import org.uoc.tfg.sel.repository.model.User;
import org.uoc.tfg.sel.repository.model.UserType;
import org.uoc.tfg.sel.validation.ValidationException;
import org.uoc.tfg.sel.validation.ValidatorUtils;
import org.uoc.tfg.sel.web.model.ErrorCodes;
import org.uoc.tfg.sel.web.model.ModelUtils;
/**
* Servicio de usuarios.
*
* @author Eduardo Rodriguez Carro
*/
@Service
public class UserService {
/** The Constant logger. */
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
/** The specialist type. */
@Value("${user.type.specialist:3}")
private Integer specialistType;
/** The tutor type. */
@Value("${user.type.tutor:2}")
private Integer tutorType;
/** The student type. */
@Value("${user.type.student:5}")
private Integer studentType;
/** The student type. */
@Value("${user.type.legalTutor:4}")
private Integer legalTutorType;
/** The user repository. */
@Autowired
private UserRepository userRepository;
/** The user type repository. */
@Autowired
private UserTypeRepository userTypeRepository;
@Autowired
private EventJobRepository eventJobRepository;
/**
* Gets the user all.
*
* @return the user all
*/
@Transactional(readOnly = true)
public List<User> getUserAll() {
Iterable<User> usersIt = userRepository.findAll();
List<User> users = new ArrayList<>();
usersIt.forEach(u-> {users.add(u);});
return users;
}
/**
* Gets the user by id.
*
* @param id the id
* @return the user by id
*/
@Cacheable( value = "userCache",key = "#id", unless = "#result == null")
@Transactional(readOnly = true)
public User getUserById(Integer id) {
Optional<User> user = userRepository.findById(id);
if (user.isPresent()) {
return user.get();
}
return null;
}
/**
* Gets the user students.
*
* @return the user students
*/
@Transactional(readOnly = true)
public List<User> getUserStudents() {
UserType type = new UserType();
type.setId(studentType);
List<User> users = userRepository.findByTypeAndActive(type,true);
for(User user: users) {
if (user.getLegalTutor() != null) {
logger.debug("User {} is assigned at {}",user.getId(), user.getLegalTutor().getId());
}
}
return users;
}
/**
* Gets the user tutor.
*
* @return the user tutor
*/
@Transactional(readOnly = true)
public List<User> getUserTutor() {
UserType type = new UserType();
type.setId(tutorType);
return userRepository.findByTypeAndActive(type,true);
}
/**
* Gets the user teachers.
*
* @return the user teachers
*/
@Transactional(readOnly = true)
public List<User> getUserTeachers() {
Iterable<User> users1 = userRepository.findByTypeAndActive(new UserType(tutorType),true);
Iterable<User> users2 = userRepository.findByTypeAndActive(new UserType(specialistType),true);
List<User> users = new ArrayList<>();
users1.forEach( (u) -> {users.add(u);});
users2.forEach( (u) -> {users.add(u);});
return users;
}
/**
* Gets the user types.
*
* @return the user types
*/
@Cacheable( value = "userTypeCache", unless = "#result == null")
@Transactional(readOnly = true)
public List<UserType> getUserTypes() {
return ServiceUtils.iterableToList(userTypeRepository.findAll());
}
/**
* Save.
*
* @param user the user
* @return the user
*/
@Transactional(readOnly = false)
public User save(User user) {
// Si es nuevo debe tener password y tipo
if(user.getId() == null) {
ValidatorUtils.assertIsNonNull("User password",user.getPassword());
ValidatorUtils.assertIsNonNull("UserType",user.getType());
ValidatorUtils.assertIsNonNull("UserType id",user.getType().getId());
}
// Si tiene tipo este tiene que existir
if ( user.getType() != null) {
// Hemos de anadir el type real
Optional<UserType> typeOptional = userTypeRepository.findById(user.getType().getId());
if(typeOptional.isPresent()) {
UserType type = typeOptional.get();
user.setType(type);
}else {
ValidationException.throwIt(ErrorCodes.VALIDATION, "Type operation does not exists");
}
}
// Si es una edicion recuperamos el objeto original para que JPA pueda detectar que cambia a la hora
// de generar la update correspondiente o si por el contrario no se requiere actualizar nada
// Tambien validamos asi que el usuario a editar existe
if(user.getId() != null) {
Optional<User> userToUpdateOptional = userRepository.findById(user.getId());
if(userToUpdateOptional.isPresent()) {
User userToUpdate = userToUpdateOptional.get();
ModelUtils.copyObjectWithOutNulls(user, userToUpdate);
userRepository.save(userToUpdate);
}else {
ValidationException.throwIt(ErrorCodes.VALIDATION, "No user to edit");
}
}else {
userRepository.save(user);
}
return user;
}
/**
* Delete.
*
* @param id the id
*/
@Transactional(readOnly = false)
public void delete(Integer id) {
userRepository.deleteById(id);
}
/**
* Save user relations.
*
* @param tutor the tutor
* @param users the users
*/
@Transactional(readOnly = false)
public void saveUserRelations(Integer tutor,List<Integer> users) {
for(Integer user: users) {
userRepository.updateRelation(tutor, user);
}
}
/**
* Gets the students by class.
*
* @param classId the class id
* @return the students by class
*/
@Transactional(readOnly = true)
public List<User> getStudentsByClass(Integer classId){
return userRepository.getStudentsByClass(classId);
}
/**
* Gets the students by course.
*
* @param courseId the course id
* @return the students by course
*/
@Transactional(readOnly = true)
public List<User> getStudentsByCourse(Integer courseId){
return userRepository.getStudentsByCourse(courseId);
}
/**
* Gets the students by course.
*
* @param user the user
* @return the students by course
*/
@Transactional(readOnly = true)
public List<User> getRecipients(User user){
// XXX Alumnos solo listado de profesores -> en sus clases
// XXX Profesores solo alumnos y Tutores legales -> de sus clases
// XXX Padres solo profesores -> de las clases de sus alumnos
Integer userType = user.getType().getId();
List<User> users = new ArrayList<>();
if (userType == legalTutorType || userType == studentType) {
// Todos los profesores
Iterable<User> users1 = userRepository.findByTypeAndActive(new UserType(tutorType),true);
Iterable<User> users2 = userRepository.findByTypeAndActive(new UserType(specialistType),true);
users1.forEach( (u) -> {users.add(u);});
users2.forEach( (u) -> {users.add(u);});
} else if (userType == tutorType || userType == specialistType) {
// Todos los alumnos y tutores legales
// Todos los profesores
Iterable<User> users1 = userRepository.findByTypeAndActive(new UserType(studentType),true);
Iterable<User> users2 = userRepository.findByTypeAndActive(new UserType(legalTutorType),true);
users1.forEach( (u) -> {users.add(u);});
users2.forEach( (u) -> {users.add(u);});
}
return users;
}
/**
* User jobs report.
*
* @param user the user
* @return the list
*/
@Transactional(readOnly = true)
public List<EventJob> userJobsReport(User user){
List<EventJob> jobReports = new ArrayList<>();
List<User> users = userRepository.findByLegalTutor(user);
if(users !=null) {
for (User student : users) {
List<EventJob> jobs = eventJobRepository.findByStudent(student);
jobReports.addAll(jobs);
}
}
return jobReports;
}
}