package com.exadel.controller; import com.exadel.dto.*; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import com.exadel.model.entity.events.Event; import com.exadel.repository.TrainingFeedbackRepository; import com.exadel.service.events.UserFeedbackEventService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.exadel.model.entity.ParticipationStatus; import com.exadel.model.entity.events.TrainingEvent; import com.exadel.model.entity.events.TrainingFeedbackEvent; import com.exadel.model.entity.feedback.TrainingFeedback; import com.exadel.model.entity.training.*; import com.exadel.model.entity.user.ExternalVisitor; import com.exadel.model.entity.user.User; import com.exadel.model.entity.user.UserRole; import com.exadel.service.*; import com.exadel.service.events.TrainingEventService; import com.exadel.service.events.TrainingFeedbackEventService; import com.exadel.service.impl.EmailMessages; import com.exadel.service.impl.SmtpMailSender; import com.exadel.util.UserUtil; import org.springframework.web.context.request.async.DeferredResult; import javax.crypto.Cipher; @RestController @RequestMapping("/training") public class TrainingPageController { @Autowired private TrainingFeedbackService trainingFeedbackService; @Autowired private EntryService entryService; @Autowired private TrainingService trainingService; @Autowired private RatingService ratingService; @Autowired private UserService userService; @Autowired private TrainingEventService trainingEventService; @Autowired private TrainingFeedbackEventService trainingFeedbackEventService; @Autowired private UserFeedbackEventService userFeedbackEventService; @Autowired private SmtpMailSender smtpMailSender; @Autowired private EmailMessages emailMessages; @Autowired private ParticipationService participationService; @Autowired private ReserveService reserveService; @PreAuthorize("hasAnyRole('0','1','2')") @RequestMapping(value = "/info", method = RequestMethod.GET) public TrainingDTO getTrainingInfo(@RequestParam String trainingId) { return new TrainingDTO(trainingService.getTrainingById(trainingId)); } @PreAuthorize("hasAnyRole('0','1','2')") @RequestMapping(value = "/trainer", method = RequestMethod.GET) public UserDTO getTrainer(@RequestParam String trainingId) { Training training = trainingService.getTrainingById(trainingId); return new UserDTO(training.getTrainer()); } @PreAuthorize("@trainerControlBean.isTrainer(#trainingId) or hasRole('0')") @RequestMapping(value = "/participants", method = RequestMethod.GET) public List<UserDTO> getParticipants(@RequestParam String trainingId) { Training training = trainingService.getTrainingById(trainingId); List<UserDTO> userDTOs = new ArrayList<>(); for (User user : training.getParticipants()) { userDTOs.add(new UserDTO(user)); } return userDTOs; } @PreAuthorize("hasAnyRole('0','1','2')") @RequestMapping(value = "/check_participation", method = RequestMethod.GET) public ParticipationStatus checkParticipation(@RequestParam String userId, @RequestParam String trainingId) { return trainingService.checkParticipation(userId, trainingId); } @RequestMapping(value = "/participation", method = RequestMethod.GET) public List<ParticipationDTO> getParticipationTime(@RequestParam String trainingId) { Training training = trainingService.getTrainingById(trainingId); List<Participation> participations = participationService.getAllParticipationsByTrainingId(training.getId()); List<ParticipationDTO> participationDTOs = new ArrayList<>(); for (Participation participation : participations) { participationDTOs.add(new ParticipationDTO(participation)); } return participationDTOs; } @RequestMapping(value = "/waitList", method = RequestMethod.GET) public List<UserDTO> getWaitList(@RequestParam String trainingId) { List<Reserve> reserves = reserveService.getAllReservesByTrainingId(Long.parseLong(trainingId)); List<UserDTO> userDTOs = new ArrayList<>(); for (Reserve reserve : reserves) { userDTOs.add(new UserDTO(userService.getUserById(reserve.getReservist().getId()))); } return userDTOs; } @PreAuthorize("hasAnyRole('0','1')") @RequestMapping(value = "/register", method = RequestMethod.POST) public synchronized ParticipationStatus register(@RequestParam String userId, @RequestParam String trainingId) { Training training = trainingService.getTrainingById(trainingId); User visitor = userService.getUserById(userId); List<User> participants = training.getParticipants(); int participantsCount = participants.size(); participantsCount -= participationService.countCompletedParticipants(training.getId()); if (participantsCount < training.getMembersCountMax() && reserveService.getNextReserveByTrainingId(training.getId()) == null) { participationService.addParticipation(new Participation(visitor, training, new Date(), null)); smtpMailSender.send(userService.getUserById(userId).getEmail(), "Registration", emailMessages.register(visitor, entryService.findNextEntryByTrainingId(new Date(), Long.parseLong(trainingId)), ParticipationStatus.MEMBER)); return ParticipationStatus.MEMBER; } else { Reserve reservist = new Reserve(training, visitor); reserveService.addReserve(reservist); smtpMailSender.send(userService.getUserById(userId).getEmail(), "Registration", emailMessages.register(visitor, entryService.findNextEntryByTrainingId(new Date(), Long.parseLong(trainingId)), ParticipationStatus.RESERVE)); return ParticipationStatus.RESERVE; } } @PreAuthorize("@userControlBean.isMyAccount(#userId) and hasAnyRole('0','1','2') and @visitControlBean.isStarted(#trainingId)") @RequestMapping(value = "/unregister", method = RequestMethod.POST) public synchronized void unregister(@RequestParam String userId, @RequestParam String trainingId) { Training training = trainingService.getTrainingById(trainingId); User visitor = userService.getUserById(userId); if (training.isParticipant(visitor.getId())) { Participation participation = participationService.getParticipationByTrainingAndUserId(training.getId(), visitor.getId()); List<Entry> entries = training.getEntries(); if (training.isRepeated() && new Date().after(entries.get(0).getBeginTime())) { participation.setEndDay(new Date()); } else { participationService.deleteParticipation(participation.getId()); } Reserve reserve = reserveService.getNextReserveByTrainingId(training.getId()); if (reserve != null) { smtpMailSender.send(reserve.getReservist().getEmail(), "Training", emailMessages.becomeMember(reserve.getReservist(), entryService.findNextEntryByTrainingId(new Date(), training.getId()))); } } else if (training.isReservist(visitor.getId())) { Reserve reserve = reserveService.getReserveByTrainingIdAndUserId(training.getId(), visitor.getId()); training.getReserves().remove(reserve); reserveService.deleteReserve(reserve); } } @RequestMapping(value = "/cancel_participation", method = RequestMethod.POST) public synchronized String cancelParticipation(@RequestParam String userId, @RequestParam String trainingId) { String trainingID = EmailMessages.doCrypto(Cipher.DECRYPT_MODE, trainingId); String userID = EmailMessages.doCrypto(Cipher.DECRYPT_MODE, userId); unregister(userID, trainingID); return "You have canceled participation"; } @RequestMapping(value = "/confirm_participation", method = RequestMethod.POST) public synchronized String becomeMember(@RequestParam String userId, @RequestParam String trainingId) { String trainingID = EmailMessages.doCrypto(Cipher.DECRYPT_MODE, trainingId); String userID = EmailMessages.doCrypto(Cipher.DECRYPT_MODE, userId); Training training = trainingService.getTrainingById(trainingID); Reserve reserve = reserveService.getReserveByTrainingIdAndUserId(Long.parseLong(trainingID), Long.parseLong(userID)); if (training.getParticipants().size() < training.getMembersCountMax()) { User visitor = reserve.getReservist(); training.getReserves().remove(reserve); reserveService.deleteReserve(reserve.getId()); participationService.addParticipation(new Participation(visitor, training, new Date(), null)); smtpMailSender.send(userService.getUserById(userID).getEmail(), "Registration", emailMessages.register(visitor, entryService.findNextEntryByTrainingId(new Date(), Long.parseLong(trainingID)), ParticipationStatus.MEMBER)); return "Congratulations! You have become a participant of training."; } else{ smtpMailSender.send(userService.getUserById(userID).getEmail(), "Registration", emailMessages.register(reserve.getReservist(), entryService.findNextEntryByTrainingId(new Date(), Long.parseLong(trainingID)), ParticipationStatus.RESERVE)); return "Unfortunately, all the seats on training are occupied, so you added to reserve."; } } public List<EventDTO> getEvents() { List<EventDTO> list = new ArrayList<>(); List<Event> events = new ArrayList<>(); events.addAll(trainingEventService.getUnwatchedEvents()); events.addAll(trainingFeedbackEventService.getUnwatchedEvents()); events.addAll(userFeedbackEventService.getUnwatchedEvents()); for (Event event : events) { list.add(event.toEventDTO()); } return list; } @PreAuthorize("hasRole('0')") @RequestMapping(value = "/register_visitor", method = RequestMethod.POST) public void registerByAdmin(@RequestParam String userId, @RequestParam String trainingId) { register(userId, trainingId); } @PreAuthorize("hasRole('0')") @RequestMapping(value = "/register_new_visitor", method = RequestMethod.POST) public void registerNewExternalByAdmin(@RequestBody UserDTO visitorDTO, @RequestParam String trainingId) { User user = new ExternalVisitor(visitorDTO); user = userService.addUser(user); register(String.valueOf(user.getId()), trainingId); } @PreAuthorize("hasAnyRole('0','1','2')") @RequestMapping(value = "/feedbacks", method = RequestMethod.GET) public List<TrainingFeedbackDTO> getFeedbacks(@RequestParam String trainingId) { Training training = trainingService.getTrainingById(trainingId); List<TrainingFeedback> feedbacks = (List<TrainingFeedback>) trainingFeedbackService.getTrainingFeedbacksByTrainingId(training.getId()); List<TrainingFeedbackDTO> feedbackDTOs = new ArrayList<>(); for (TrainingFeedback feedback : feedbacks) { feedbackDTOs.add(new TrainingFeedbackDTO(feedback)); } return feedbackDTOs; } @PreAuthorize("@visitControlBean.isVisiting(#feedbackDTO) and hasAnyRole('0','1','2')") @RequestMapping(value = "/newFeedback", method = RequestMethod.POST) public TrainingDTO createFeedback(@RequestBody TrainingFeedbackDTO feedbackDTO) { TrainingFeedback feedback = new TrainingFeedback(feedbackDTO); feedback.setTraining(trainingService.getTrainingById(String.valueOf(feedbackDTO.getTrainingId()))); long id = trainingFeedbackService.addTrainingFeedback(feedback); feedbackDTO.setId(id); trainingFeedbackEventService.addEvent(new TrainingFeedbackEvent(feedbackDTO)); for (Map.Entry<DeferredResult<List<EventDTO>>, Integer> entry : EventController.eventRequests.entrySet()) { entry.getKey().setResult(getEvents()); } ratingService.addRating(new Rating(feedback.getTraining(), feedback.getFeedbacker())); Training training = feedback.getTraining(); training.addRating(feedback.getEffectiveness()); trainingService.updateTraining(training); return new TrainingDTO(training); } @PreAuthorize("hasRole('0')") @RequestMapping(value = "/feedbacks", method = RequestMethod.DELETE) //called only by ADMIN public void deleteFeedback(@RequestParam String feedbackId) { TrainingFeedback feedback = trainingFeedbackService.getTrainingFeedbackById(Long.parseLong(feedbackId)).get(); trainingFeedbackEventService.deleteByTrainingFeedbackId(Long.parseLong(feedbackId)); trainingFeedbackService.deleteById(Long.parseLong(feedbackId)); smtpMailSender.send(feedback.getFeedbacker().getEmail(), "Feedbacks", emailMessages.deleteFeedback(feedback)); } @PreAuthorize("hasAnyRole('0','1','2')") @RequestMapping(value = "/entry", method = RequestMethod.GET) public Entry getEntry(@RequestParam String entryId) { long id = Long.parseLong(entryId); Entry entry = entryService.getEntryById(id); System.out.println(entry); return entry; } @PreAuthorize("@trainerControlBean.isTrainer(#trainingDTO) or hasRole('0')") @RequestMapping(method = RequestMethod.PUT) public void modifyTraining(@RequestBody TrainingDTO trainingDTO) { Training training = trainingService.getTrainingById(trainingDTO.getId()); training.updateTraining(trainingDTO); if (UserUtil.hasRole(0)) { smtpMailSender.sendToUsers(training.getParticipants(), "Trainings", emailMessages.modifyTraining(training)); } else { training.setStatus(TrainingStatus.DRAFTED); trainingEventService.addEvent(new TrainingEvent(trainingDTO)); smtpMailSender.sendToUsers(userService.getUsersByRole(UserRole.ADMIN), "Changes in trainings", trainingDTO.getEventDescription()); for (Map.Entry<DeferredResult<List<EventDTO>>, Integer> entry : EventController.eventRequests.entrySet()) { entry.getKey().setResult(getEvents()); } } trainingService.updateTraining(training); } @PreAuthorize("@trainerControlBean.isTrainer(#trainingId) or hasRole('0')") @RequestMapping(method = RequestMethod.DELETE) public void cancelTraining(@RequestParam String trainingId) { Training training = trainingService.getTrainingById(trainingId); training.setStatus(TrainingStatus.CANCELLED); if (UserUtil.hasRole(0)) { trainingService.cancelById(training.getId()); smtpMailSender.sendToUsers(training.getParticipants(), "Trainings", emailMessages.deleteTraining(training)); } else { TrainingDTO trainingDTO = new TrainingDTO(training); trainingDTO.setEventDescription(emailMessages.deleteTrainingToAdmin(training)); trainingEventService.addEvent(new TrainingEvent(trainingDTO)); smtpMailSender.sendToUsers(userService.getUsersByRole(UserRole.ADMIN), "Changes in trainings", emailMessages.deleteTrainingToAdmin(training)); for (Map.Entry<DeferredResult<List<EventDTO>>, Integer> entry : EventController.eventRequests.entrySet()) { entry.getKey().setResult(getEvents()); } } } @PreAuthorize("hasRole('0')") @RequestMapping(value = "/userFeedback", method = RequestMethod.POST) public void askUserFeedback(@RequestParam String userId, @RequestParam String trainingId) { User user = userService.getUserById(userId); Training training = trainingService.getTrainingById(trainingId); smtpMailSender.send(training.getTrainer().getEmail(), "Feedback", emailMessages.askFeedback(training, user)); } @Autowired TrainingFeedbackRepository trainingFeedbackRepository; @RequestMapping("/byFeedback") public TrainingDTO getTrainingId(@RequestParam String id) { TrainingFeedback feedback=trainingFeedbackRepository.findById(Long.parseLong(id)); TrainingDTO trainingDTO = new TrainingDTO(feedback.getTraining()); return trainingDTO; } }