Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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 @@ -39,6 +39,11 @@ public Kudos create(@Body @Valid KudosCreateDTO kudos) {
}

@Put
public Kudos update(@Body @Valid KudosUpdateDTO kudos) {
return kudosServices.update(kudos);
}

@Put("/approve")
public Kudos approve(@Body @Valid Kudos kudos) {
return kudosServices.approve(kudos);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ public interface KudosServices {

Kudos save(KudosCreateDTO kudos);

Kudos update(KudosUpdateDTO kudos);

Kudos approve(Kudos kudos);

List<KudosResponseDTO> getRecent();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.objectcomputing.checkins.services.kudos;

import com.objectcomputing.checkins.exceptions.PermissionException;
import com.objectcomputing.checkins.services.permissions.Permission;
import com.objectcomputing.checkins.services.permissions.RequiredPermission;
import com.objectcomputing.checkins.configuration.CheckInsConfiguration;
Expand Down Expand Up @@ -37,6 +38,8 @@
import java.util.List;
import java.util.UUID;
import java.util.Set;
import java.util.HashSet;
import java.util.stream.Collectors;

import static com.objectcomputing.checkins.services.validate.PermissionsValidation.NOT_AUTHORIZED_MSG;

Expand Down Expand Up @@ -118,6 +121,12 @@ public Kudos save(KudosCreateDTO kudosDTO) {
kudosRecipientServices.save(kudosRecipient);
}

if (!savedKudos.getPubliclyVisible()) {
// Private kudos do not need to be approved by another party.
savedKudos.setDateApproved(LocalDate.now());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously we didn't require any approved date for non-public kudos, so we didn't set one. I'm guessing something has shifted somewhere in the logic such that we need this date now? If so, then we might need to make a migration to add these dates to existing private kudos.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will have to look to see if anything changed anywhere to see why private kudos weren't being displayed.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found the root of the problem.

    private List<KudosResponseDTO> findAllToMember(UUID memberId) {
        UUID currentUserId = currentUserServices.getCurrentUser().getId();

        if (!currentUserId.equals(memberId) &&
            !hasAdministerKudosPermission()) {
            throw new PermissionException("You are not authorized to retrieve the kudos another user has received");
        }

        List<KudosRecipient> kudosRecipients = kudosRecipientRepository.findByMemberId(memberId);

        List<KudosResponseDTO> kudosList = new ArrayList<>();

        kudosRecipients.forEach(kudosRecipient -> {
            UUID kudosId = kudosRecipient.getKudosId();
            Kudos relatedKudos = kudosRepository.findById(kudosId).orElseThrow(() ->
                    new NotFoundException(KUDOS_DOES_NOT_EXIST_MSG.formatted(kudosId)));

            if (relatedKudos.getDateApproved() != null) {
                kudosList.add(constructKudosResponseDTO(relatedKudos));
            }
        });

        return kudosList;
    }

When we retrieve all of the received kudos, we are requiring an approved date. According to git, it's been like this for 3 years. I will undo my date changes and fix this method (and some display stuff too).

savedKudos = kudosRepository.update(savedKudos);
}

sendNotification(savedKudos, NotificationType.creation);
return savedKudos;
}
Expand All @@ -140,6 +149,74 @@ public Kudos approve(Kudos kudos) {
return updated;
}

@Override
public Kudos update(KudosUpdateDTO kudos) {
// Find the corresponding kudos and make sure we have permission.
final UUID kudosId = kudos.getId();
final Kudos existingKudos =
kudosRepository.findById(kudosId).orElseThrow(() ->
new BadArgException(KUDOS_DOES_NOT_EXIST_MSG.formatted(kudosId)));

final MemberProfile currentUser = currentUserServices.getCurrentUser();
if (!currentUser.getId().equals(existingKudos.getSenderId()) &&
!hasAdministerKudosPermission()) {
throw new PermissionException(NOT_AUTHORIZED_MSG);
}

if (kudos.getRecipientMembers() == null ||
kudos.getRecipientMembers().isEmpty()) {
throw new BadArgException(
"Kudos must contain at least one recipient");
}

// Begin modifying the existing kudos to reflect desired changes.
existingKudos.setMessage(kudos.getMessage());

boolean existingPublic = existingKudos.getPubliclyVisible();
boolean proposedPublic = kudos.getPubliclyVisible();
if (existingPublic && !proposedPublic) {
// TODO: Somehow find and remove the Slack Kudos that the Check-Ins
// Integration posted.
existingKudos.setDateApproved(LocalDate.now());
} else if (!existingPublic && proposedPublic) {
// Clear the date approved when going from private to public.
existingKudos.setDateApproved(null);
}

existingKudos.setPubliclyVisible(kudos.getPubliclyVisible());

List<KudosRecipient> recipients = kudosRecipientRepository
.findByKudosId(kudosId);
Set<UUID> proposed = kudos.getRecipientMembers()
.stream()
.map(r -> r.getId())
.collect(Collectors.toSet());
boolean different = (recipients.size() != proposed.size());
if (!different) {
Set<UUID> existing = recipients.stream()
.map(r -> r.getMemberId())
.collect(Collectors.toSet());
different = !existing.equals(proposed);
}

// First, update the Kudos so that we only change recipients if they
// are different and we were able to update the Kudos.
final Kudos updated = kudosRepository.update(existingKudos);

// Change recipients, if necessary.
if (different) {
updateRecipients(updated, recipients, proposed);
}

// The kudos has been updated. Send notification to admin, if going
// from private to public.
if (!existingPublic && proposedPublic) {
sendNotification(updated, NotificationType.creation);
}

return updated;
}

@Override
public KudosResponseDTO getById(UUID id) {

Expand Down Expand Up @@ -172,11 +249,16 @@ public KudosResponseDTO getById(UUID id) {
}

@Override
@RequiredPermission(Permission.CAN_ADMINISTER_KUDOS)
public void delete(UUID id) {
Kudos kudos = kudosRepository.findById(id).orElseThrow(() ->
new NotFoundException(KUDOS_DOES_NOT_EXIST_MSG.formatted(id)));

MemberProfile currentUser = currentUserServices.getCurrentUser();
if (!currentUser.getId().equals(kudos.getSenderId()) &&
!hasAdministerKudosPermission()) {
throw new PermissionException(NOT_AUTHORIZED_MSG);
}

// Delete all KudosRecipients associated with this kudos
List<KudosRecipient> recipients = kudosRecipientServices.getAllByKudosId(kudos.getId());
kudosRecipientRepository.deleteAll(recipients);
Expand Down Expand Up @@ -387,4 +469,26 @@ private void slackApprovedKudos(Kudos kudos) {
private boolean hasAdministerKudosPermission() {
return currentUserServices.hasPermission(Permission.CAN_ADMINISTER_KUDOS);
}

private void updateRecipients(Kudos updated,
List<KudosRecipient> recipients,
Set<UUID> proposed) {
// Add the new recipients.
Set<UUID> existing = recipients.stream()
.map(r -> r.getMemberId())
.collect(Collectors.toSet());
for (UUID id : proposed) {
if (!existing.contains(id)) {
kudosRecipientServices.save(
new KudosRecipient(updated.getId(), id));
}
}

// Remove any that are no longer designated as recipients.
for (KudosRecipient recipient : recipients) {
if (!proposed.contains(recipient.getMemberId())) {
kudosRecipientRepository.delete(recipient);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.objectcomputing.checkins.services.kudos;

import com.objectcomputing.checkins.services.memberprofile.MemberProfile;
import io.micronaut.core.annotation.Introspected;
import io.micronaut.core.annotation.Nullable;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

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

@Getter
@Setter
@AllArgsConstructor
@Introspected
public class KudosUpdateDTO {
@NotNull
private UUID id;

@NotBlank
private String message;

@Nullable
private Boolean publiclyVisible;

@NotNull
private List<MemberProfile> recipientMembers;
}
Loading