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 4 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,27 @@
package com.objectcomputing.checkins.services.feedback_request.DTO;

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

public class CreatorDTO {

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

// Constructors
public CreatorDTO() {}

public CreatorDTO(UUID id) {
this.id = id;
}

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

// Setters
public void setId(UUID id) {
this.id = id;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.objectcomputing.checkins.services.feedback_request.DTO;

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

public class DenierDTO {

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

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

// Constructors
public DenierDTO() {}

public DenierDTO(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
@@ -0,0 +1,54 @@
package com.objectcomputing.checkins.services.feedback_request.DTO;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

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 DenierDTO denier;

@NotNull(message = "Creator cannot be null")
@Valid
private CreatorDTO creator;
thelenw marked this conversation as resolved.
Show resolved Hide resolved

// Constructors
public DenyFeedbackRequestDTO() {}

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

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

public DenierDTO getDenier() {
return denier;
}

public CreatorDTO getCreator() {
return creator;
}

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

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

public void setCreator(CreatorDTO creator) {
this.creator = creator;
}
}
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,10 @@

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.DenierDTO;
import com.objectcomputing.checkins.services.feedback_request.DTO.CreatorDTO;
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 +14,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 +24,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 +41,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 +100,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 +115,67 @@ 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();
DenierDTO denier = body.getDenier();
CreatorDTO creator = body.getCreator();

if (!feedbackRequest.isDenied() && reason != null && !reason.trim().isEmpty()) {
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));
}

return HttpResponse.ok(fromEntity(feedbackRequest));
}

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
}

Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,15 @@ public class FeedbackRequestResponseDTO {
@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;

public FeedbackRequestResponseDTO() {
this.denied = false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.util.List;
import java.util.UUID;

import io.micronaut.http.HttpResponse;

public interface FeedbackRequestServices {
FeedbackRequest save(FeedbackRequest feedbackRequest);

Expand All @@ -14,4 +16,5 @@ public interface FeedbackRequestServices {
FeedbackRequest getById(UUID id);

List<FeedbackRequest> findByValues(UUID creatorId, UUID requesteeId, UUID recipientId, LocalDate oldestDate, UUID reviewPeriodId, UUID templateId, List<UUID> requesteeIds);

}
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,8 @@ private FeedbackRequest getFromDTO(FeedbackRequestUpdateDTO dto) {
feedbackRequest.setStatus(dto.getStatus());
feedbackRequest.setSubmitDate(dto.getSubmitDate());
feedbackRequest.setRecipientId(dto.getRecipientId());

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

Expand Down
Loading
Loading