Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Received Feedback Request: 'Deny' Option #2622

Draft
wants to merge 12 commits into
base: develop
Choose a base branch
from
Draft
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
@@ -0,0 +1,57 @@
package com.objectcomputing.checkins.services.feedback_request.DTO;

import io.micronaut.core.annotation.Introspected;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

@Introspected

public class DenyFeedbackRequestDTO {
thelenw marked this conversation as resolved.
Show resolved Hide resolved

@NotBlank(message = "Reason cannot be blank")
private String reason;

@NotNull(message = "Denier cannot be null")
@Valid
private UserDTO denier;

@NotNull(message = "Creator cannot be null")
@Valid
private UserDTO creator;

// Constructors
public DenyFeedbackRequestDTO() {}

public DenyFeedbackRequestDTO(String reason, UserDTO denier, UserDTO creator) {
this.reason = reason;
this.denier = denier;
this.creator = creator;
}

// Getters
public String getReason() {
return reason;
}

public UserDTO getDenier() {
return denier;
}

public UserDTO getCreator() {
return creator;
}

// Setters
public void setReason(String reason) {
this.reason = reason;
}

public void setDenier(UserDTO denier) {
this.denier = denier;
}

public void setCreator(UserDTO creator) {
this.creator = creator;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.objectcomputing.checkins.services.feedback_request.DTO;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.util.UUID;

import io.micronaut.core.annotation.Introspected;


@Introspected

public class UserDTO {

@NotNull(message = "User ID cannot be null")
private UUID id;

@NotBlank(message = "User name cannot be blank")
private String name;

// Constructors
public UserDTO() {}

// Constructor with only ID (for cases where only ID is required)
public UserDTO(UUID id) {
this.id = id;
}

// Constructor with ID and name (for cases where both ID and name are required)
public UserDTO(UUID id, String name) {
this.id = id;
this.name = name;
}

// Getters
public UUID getId() {
return id;
}

public String getName() {
return name;
}

// Setters
public void setId(UUID id) {
this.id = id;
}

public void setName(String name) {
this.name = name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Null;
import lombok.Getter;
import lombok.Setter;

Expand Down Expand Up @@ -86,6 +87,18 @@ public class FeedbackRequest {
@Schema(description = "the id of the review period in that this request was created for")
private UUID reviewPeriodId;

@Column(name = "denied")
@Nullable
@Schema(description = "Whether the feedback request has been denied")
private boolean denied = false;

@Column(name = "reason")
@Nullable
@Schema(description = "Denial reason")
private String reason;



public FeedbackRequest(UUID creatorId,
UUID requesteeId,
UUID recipientId,
Expand All @@ -94,7 +107,9 @@ public FeedbackRequest(UUID creatorId,
@Nullable LocalDate dueDate,
String status,
@Nullable LocalDate submitDate,
@Nullable UUID reviewPeriodId) {
@Nullable UUID reviewPeriodId,
boolean denied,
@Nullable String reason) {
this.id = null;
this.creatorId = creatorId;
this.requesteeId = requesteeId;
Expand All @@ -105,6 +120,8 @@ public FeedbackRequest(UUID creatorId,
this.status = status;
this.submitDate = submitDate;
this.reviewPeriodId = reviewPeriodId;
this.denied = denied;
this.reason = reason;
}

public FeedbackRequest() {}
Expand All @@ -123,12 +140,14 @@ public boolean equals(Object o) {
&& Objects.equals(dueDate, that.dueDate)
&& Objects.equals(status, that.status)
&& Objects.equals(submitDate, that.submitDate)
&& Objects.equals(reviewPeriodId, that.reviewPeriodId);
&& Objects.equals(reviewPeriodId, that.reviewPeriodId)
&& Objects.equals(denied, that.denied)
&& Objects.equals(reason, that.reason);
}

@Override
public int hashCode() {
return Objects.hash(id, creatorId, recipientId, requesteeId, sendDate, templateId, dueDate, status, submitDate, reviewPeriodId);
return Objects.hash(id, creatorId, recipientId, requesteeId, sendDate, templateId, dueDate, status, submitDate, reviewPeriodId, denied, reason);
}

@Override
Expand All @@ -144,6 +163,8 @@ public String toString() {
", status='" + status +
", submitDate='" + submitDate +
", reviewPeriodId='" + reviewPeriodId +
", denied='" + denied +
", reason='" + reason +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import com.objectcomputing.checkins.services.permissions.Permission;
import com.objectcomputing.checkins.services.permissions.RequiredPermission;
import com.objectcomputing.checkins.services.feedback_request.DTO.DenyFeedbackRequestDTO;
import com.objectcomputing.checkins.services.feedback_request.DTO.UserDTO;
import com.objectcomputing.checkins.services.notification.NotificationService;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.core.convert.format.Format;
import io.micronaut.http.HttpResponse;
Expand All @@ -10,6 +13,7 @@
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Delete;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.PathVariable;
import io.micronaut.http.annotation.Post;
import io.micronaut.http.annotation.Put;
import io.micronaut.http.annotation.Status;
Expand All @@ -19,6 +23,7 @@
import io.micronaut.security.rules.SecurityRule;
import io.micronaut.validation.Validated;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.inject.Inject;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;

Expand All @@ -35,9 +40,12 @@
public class FeedbackRequestController {

private final FeedbackRequestServices feedbackReqServices;
private final NotificationService notificationService;

public FeedbackRequestController(FeedbackRequestServices feedbackReqServices) {
@Inject
public FeedbackRequestController(FeedbackRequestServices feedbackReqServices, NotificationService notificationService) {
this.feedbackReqServices = feedbackReqServices;
this.notificationService = notificationService;
}

/**
Expand Down Expand Up @@ -91,7 +99,7 @@ public void delete(@NotNull UUID id) {
public HttpResponse<FeedbackRequestResponseDTO> getById(UUID id) {
FeedbackRequest savedFeedbackRequest = feedbackReqServices.getById(id);
return savedFeedbackRequest == null ? HttpResponse.notFound() : HttpResponse.ok(fromEntity(savedFeedbackRequest))
.headers(headers -> headers.location(URI.create("/feedback_request" + savedFeedbackRequest.getId())));
.headers(headers -> headers.location(URI.create("/feedback_request/" + savedFeedbackRequest.getId())));
thelenw marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand All @@ -106,13 +114,68 @@ public HttpResponse<FeedbackRequestResponseDTO> getById(UUID id) {
*/
@RequiredPermission(Permission.CAN_VIEW_FEEDBACK_REQUEST)
@Get("/{?creatorId,requesteeId,recipientId,oldestDate,reviewPeriodId,templateId,requesteeIds}")
public List<FeedbackRequestResponseDTO> findByValues(@Nullable UUID creatorId, @Nullable UUID requesteeId, @Nullable UUID recipientId, @Nullable @Format("yyyy-MM-dd") LocalDate oldestDate, @Nullable UUID reviewPeriodId, @Nullable UUID templateId, @Nullable List<UUID> requesteeIds) {
public List<FeedbackRequestResponseDTO> findByValues(
@Nullable UUID creatorId,
@Nullable UUID requesteeId,
@Nullable UUID recipientId,
@Nullable @Format("yyyy-MM-dd") LocalDate oldestDate,
@Nullable UUID reviewPeriodId,
@Nullable UUID templateId,
@Nullable List<UUID> requesteeIds) {
return feedbackReqServices.findByValues(creatorId, requesteeId, recipientId, oldestDate, reviewPeriodId, templateId, requesteeIds)
.stream()
.map(this::fromEntity)
.toList();
}

/**
* Deny a feedback request
*
* @param id {@link UUID} ID of the feedback request to deny
* @param body Request body containing reason, denier, and creator information
* @return {@link FeedbackRequestResponseDTO} with updated denial status
*/
@Post("/{id}/deny")
@RequiredPermission(Permission.CAN_DENY_FEEDBACK_REQUEST)
public HttpResponse<FeedbackRequestResponseDTO> denyFeedbackRequest(
@PathVariable("id") @NotNull UUID id,
@Body @Valid DenyFeedbackRequestDTO body
) {
FeedbackRequest feedbackRequest = feedbackReqServices.getById(id);
if (feedbackRequest == null) {
return HttpResponse.notFound();
}

String reason = body.getReason();
UserDTO denier = body.getDenier();
UserDTO creator = body.getCreator();

if (!feedbackRequest.isDenied() && reason != null && !reason.trim().isEmpty() && denier != null && creator != null) {
FeedbackRequestUpdateDTO dto = new FeedbackRequestUpdateDTO();
dto.setId(feedbackRequest.getId());
dto.setDueDate(feedbackRequest.getDueDate());
dto.setStatus(feedbackRequest.getStatus());
dto.setSubmitDate(feedbackRequest.getSubmitDate());
dto.setRecipientId(feedbackRequest.getRecipientId());
dto.setDenied(true);
dto.setReason(reason);

FeedbackRequest updatedFeedbackRequest = feedbackReqServices.update(dto);

UUID creatorId = creator.getId();
String denierName = denier.getName();
notificationService.sendNotification(
creatorId,
String.format("Your feedback request was denied by %s. Reason: %s", denierName, reason)
);

return HttpResponse.ok(fromEntity(updatedFeedbackRequest));
} else {
return HttpResponse.badRequest();

}
}

private FeedbackRequestResponseDTO fromEntity(FeedbackRequest feedbackRequest) {
FeedbackRequestResponseDTO dto = new FeedbackRequestResponseDTO();
dto.setId(feedbackRequest.getId());
Expand All @@ -125,7 +188,8 @@ private FeedbackRequestResponseDTO fromEntity(FeedbackRequest feedbackRequest) {
dto.setStatus(feedbackRequest.getStatus());
dto.setSubmitDate(feedbackRequest.getSubmitDate());
dto.setReviewPeriodId(feedbackRequest.getReviewPeriodId());

dto.setDenied(feedbackRequest.isDenied());
dto.setReason(feedbackRequest.getReason());
return dto;
}

Expand All @@ -139,6 +203,9 @@ private FeedbackRequest fromDTO(FeedbackRequestCreateDTO dto) {
dto.getDueDate(),
dto.getStatus(),
dto.getSubmitDate(),
dto.getReviewPeriodId());
dto.getReviewPeriodId(),
dto.isDenied(),
dto.getReason()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.micronaut.core.annotation.Nullable;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Null;
import lombok.Getter;
import lombok.Setter;

Expand Down Expand Up @@ -51,5 +52,12 @@ public class FeedbackRequestCreateDTO {
@Schema(description = "the id of the review period in that this request was created for")
private UUID reviewPeriodId;

@Schema(description = "Whether the feedback request has been denied")
private boolean denied = false;

@Nullable
@Schema(description = "Reason for the request being denied")
private String reason;

thelenw marked this conversation as resolved.
Show resolved Hide resolved
}

Loading
Loading