Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import pl.edu.agh.project_manager.security.UserPrincipal;
import pl.edu.agh.project_manager.service.notification.NotificationService;

import java.util.Map;
import java.util.UUID;

@RestController
Expand All @@ -31,6 +32,12 @@ public ResponseEntity<SseEmitter> streamNotifications(@AuthenticationPrincipal U
return ResponseEntity.ok(emitter);
}

@GetMapping("/unread-count")
public ResponseEntity<Map<String, Integer>> getUnreadCount(@AuthenticationPrincipal UserPrincipal userPrincipal) {
int count = notificationService.getUnreadCount(userPrincipal.userId());
return ResponseEntity.ok(Map.of("count", count));
}

@GetMapping
public ResponseEntity<PagedResponse<NotificationResponse>> getUserNotifications(
@RequestParam(defaultValue = "true") boolean unreadOnly,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@

public record AssignmentAcceptedEvent(
UUID assignmentId,
User recipient, String
message
User recipient,
String projectName,
String employeeFullName
) implements NotificationEvent {

@Override
Expand All @@ -20,4 +21,12 @@ public UUID referenceId() {
public NotificationType type() {
return NotificationType.ASSIGNMENT_ACCEPTED;
}

@Override
public String buildMessage() {
if (employeeFullName != null) {
return "Zaakceptowano przypisanie pracownika " + employeeFullName + " do projektu " + projectName;
}
return "Zostałeś dodany do projektu: " + projectName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
public record AssignmentRejectedEvent(
UUID assignmentId,
User recipient,
String message
String employeeName,
String projectName
) implements NotificationEvent {

@Override
Expand All @@ -20,4 +21,9 @@ public UUID referenceId() {
public NotificationType type() {
return NotificationType.ASSIGNMENT_REJECTED;
}

@Override
public String buildMessage() {
return "Odrzucono przypisanie pracownika " + employeeName + " do projektu " + projectName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
public record AssignmentRequestedEvent(
UUID assignmentId,
User recipient,
String message
String projectName,
String employeeFullName
) implements NotificationEvent {

@Override
Expand All @@ -20,4 +21,9 @@ public UUID referenceId() {
public NotificationType type() {
return NotificationType.ASSIGNMENT_REQUESTED;
}

@Override
public String buildMessage() {
return "Kierownik projektu " + projectName + " prosi o alokację pracownika " + employeeFullName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

public interface NotificationEvent {
User recipient();
String message();
UUID referenceId();
NotificationType type();
String buildMessage();
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import pl.edu.agh.project_manager.domain.entity.user.User;
import pl.edu.agh.project_manager.domain.enums.NotificationType;

import java.util.List;
import java.util.UUID;

public record QualificationAcceptedEvent(
UUID qualificationId,
User recipient,
String message
List<String> skills
) implements NotificationEvent {

@Override
Expand All @@ -20,4 +21,9 @@ public UUID referenceId() {
public NotificationType type() {
return NotificationType.QUALIFICATION_ACCEPTED;
}

@Override
public String buildMessage() {
return "Zatwierdzono Twoje kwalifikacje: " + String.join(", ", skills);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import pl.edu.agh.project_manager.domain.entity.user.User;
import pl.edu.agh.project_manager.domain.enums.NotificationType;

import java.util.List;
import java.util.UUID;

public record QualificationRejectedEvent(
UUID qualificationId,
User recipient,
String message
List<String> skills
) implements NotificationEvent {

@Override
Expand All @@ -20,4 +21,9 @@ public UUID referenceId() {
public NotificationType type() {
return NotificationType.QUALIFICATION_REJECTED;
}

@Override
public String buildMessage() {
return "Odrzucono wnioski o kwalifikacje: " + String.join(", ", skills);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
import pl.edu.agh.project_manager.domain.entity.user.User;
import pl.edu.agh.project_manager.domain.enums.NotificationType;

import java.util.List;
import java.util.UUID;

public record QualificationRequestedEvent(
UUID qualificationId,
User recipient,
String message
String employeeFullName,
List<String> skills
) implements NotificationEvent {

@Override
Expand All @@ -20,4 +22,9 @@ public UUID referenceId() {
public NotificationType type() {
return NotificationType.QUALIFICATION_REQUESTED;
}

@Override
public String buildMessage() {
return employeeFullName + " zgłasza nowe umiejętności: " + String.join(", ", skills);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@
public record SystemNewEmployeeEvent(
UUID employeeId,
User recipient,
String message
String employeeFullName
) implements NotificationEvent {

@Override
public UUID referenceId() {
return employeeId;
}
public UUID referenceId() { return employeeId; }

@Override
public NotificationType type() { return NotificationType.SYSTEM_NEW_EMPLOYEE; }

@Override
public NotificationType type() {
return NotificationType.SYSTEM_NEW_EMPLOYEE;
public String buildMessage() {
return String.format("Nowy pracownik %s aktywował swoje konto i dołączył do Twojego zespołu.", employeeFullName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public interface NotificationRepository extends JpaRepository<Notification, UUID

Page<Notification> findAllByRecipientIdAndIsReadFalseOrderByCreatedAtDesc(UUID recipientId, Pageable pageable);

Integer countAllByRecipientIdAndIsReadFalse(UUID recipientId);

@Modifying(clearAutomatically = true, flushAutomatically = true)
@Query("UPDATE Notification n SET n.isRead = true WHERE n.recipient.id = :userId AND n.isRead = false")
void markAllAsReadByUserId(@Param("userId") UUID userId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package pl.edu.agh.project_manager.service.approval;

import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pl.edu.agh.project_manager.controller.dto.approvals.QualificationDetailsResponse;
Expand All @@ -11,20 +12,24 @@
import pl.edu.agh.project_manager.domain.entity.user.Skill;
import pl.edu.agh.project_manager.domain.entity.user.User;
import pl.edu.agh.project_manager.domain.enums.QualificationStatus;
import pl.edu.agh.project_manager.domain.event.NotificationEvent;
import pl.edu.agh.project_manager.domain.event.QualificationAcceptedEvent;
import pl.edu.agh.project_manager.domain.event.QualificationRejectedEvent;
import pl.edu.agh.project_manager.domain.exception.ApiErrorCode;
import pl.edu.agh.project_manager.domain.exception.ApplicationException;
import pl.edu.agh.project_manager.repository.user.QualificationRepository;
import pl.edu.agh.project_manager.repository.user.UserRepository;
import pl.edu.agh.project_manager.service.notification.NotificationSender;

import java.util.List;
import java.util.UUID;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class QualificationManagementService {
private final QualificationRepository qualificationRepository;
private final UserRepository userRepository;
private final ApplicationEventPublisher eventPublisher;

@Transactional(readOnly = true)
public List<QualificationRequestResponse> getRecordsForManager(UUID managerId) {
Expand Down Expand Up @@ -62,16 +67,43 @@ public void updateRequests(UUID managerId, List<QualificationUpdateRequest> requ
throw new ApplicationException(ApiErrorCode.QUALIFICATION_OWNER_NOT_SUBORDINATE);
}

Map<User, List<String>> acceptedSkillsByUser = new HashMap<>();
Map<User, List<String>> rejectedSkillsByUser = new HashMap<>();
Comment thread
mtrznadel24 marked this conversation as resolved.

for (Qualification qualification : allowedQualifications) {
validateWaitingStatus(qualification);

User owner = qualification.getUser();
var action = activeRequestsMap.get(qualification.getId()).action();
String skillName = qualification.getSkill().getName();

switch (action) {
case QualificationUpdateAction.ACCEPT -> qualification.accept();
case QualificationUpdateAction.REJECT -> qualification.reject();
case ACCEPT -> {
qualification.accept();
acceptedSkillsByUser.computeIfAbsent(owner, k -> new ArrayList<>()).add(skillName);
}
case REJECT -> {
qualification.reject();
rejectedSkillsByUser.computeIfAbsent(owner, k -> new ArrayList<>()).add(skillName);
}
}
}

acceptedSkillsByUser.forEach((user, skills) -> {
eventPublisher.publishEvent(new QualificationAcceptedEvent(
user.getId(),
user,
skills
));
});

rejectedSkillsByUser.forEach((user, skills) -> {
eventPublisher.publishEvent(new QualificationRejectedEvent(
user.getId(),
user,
skills
));
});
}

@Transactional(readOnly = true)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package pl.edu.agh.project_manager.service.auth;

import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
Expand All @@ -11,7 +12,9 @@
import org.springframework.transaction.annotation.Transactional;
import pl.edu.agh.project_manager.domain.entity.user.ActivationToken;
import pl.edu.agh.project_manager.domain.entity.user.User;
import pl.edu.agh.project_manager.domain.enums.UserRole;
import pl.edu.agh.project_manager.domain.enums.UserStatus;
import pl.edu.agh.project_manager.domain.event.SystemNewEmployeeEvent;
import pl.edu.agh.project_manager.domain.exception.ApiErrorCode;
import pl.edu.agh.project_manager.domain.exception.ApplicationException;
import pl.edu.agh.project_manager.repository.user.ActivationTokenRepository;
Expand All @@ -34,6 +37,7 @@ public class AuthService {
private final JwtService jwtService;
private final AuthenticationManager authenticationManager;
private final UserDetailsService userDetailsService;
private final ApplicationEventPublisher eventPublisher;

@Transactional
public TokenPair register(RegisterCommand command) {
Expand All @@ -56,6 +60,14 @@ public TokenPair register(RegisterCommand command) {

tokenRepository.delete(activationToken);

if (user.getUserRole() == UserRole.COMMON && user.getSupervisor() != null) {
eventPublisher.publishEvent(new SystemNewEmployeeEvent(
user.getId(),
user.getSupervisor(),
user.getFullName()
));
}

UserDetails userDetails = new UserPrincipal(
user.getId(),
user.getEmail(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class NotificationService {
@TransactionalEventListener
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void onNotificationEvent(NotificationEvent event) {
create(event.recipient(), event.type(), event.message(), event.referenceId());
create(event.recipient(), event.type(), event.buildMessage(), event.referenceId());
}

private void create(User recipient, NotificationType type, String message, UUID referenceId) {
Expand All @@ -51,6 +51,11 @@ private void create(User recipient, NotificationType type, String message, UUID
notificationSender.send(response, recipient.getId());
}

@Transactional(readOnly = true)
public Integer getUnreadCount(UUID userId) {
return notificationRepository.countAllByRecipientIdAndIsReadFalse(userId);
}

@Transactional(readOnly = true)
public PagedResponse<NotificationResponse> getNotificationsForUser(UUID userId, int page, int size, boolean unreadOnly) {
Pageable pageable = PageRequest.of(page, size);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ public AssignmentResponse createAssignment(UUID projectId, AssignmentCommand com
eventPublisher.publishEvent(new AssignmentRequestedEvent(
savedAssignment.getId(),
user.getSupervisor(),
"Kierownik projektu " + project.getTitle() + " prosi o alokację pracownika " + user.getFullName()
project.getTitle(),
user.getFullName()
));
}

Expand Down Expand Up @@ -123,9 +124,17 @@ public void acceptAssignment(UUID assignmentId) {
}

eventPublisher.publishEvent(new AssignmentAcceptedEvent(
assignment.getId(),
project.getId(),
project.getProjectManager(),
"Zaakceptowano przypisanie pracownika " + user.getFullName() + " do projektu " + project.getTitle()
project.getTitle(),
user.getFullName()
));

eventPublisher.publishEvent(new AssignmentAcceptedEvent(
project.getId(),
user,
project.getTitle(),
null
));
}

Expand All @@ -138,9 +147,10 @@ public void rejectAssignment(UUID assignmentId) {
assignment.setStatus(AssignmentStatus.REJECTED);

eventPublisher.publishEvent(new AssignmentRejectedEvent(
assignment.getId(),
assignment.getProject().getId(),
assignment.getProject().getProjectManager(),
"Odrzucono przypisanie pracownika " + assignment.getUser().getName() + " do projektu " + assignment.getProject().getTitle()
assignment.getUser().getName(),
assignment.getProject().getTitle()
));
}

Expand Down
Loading
Loading