Skip to content

Commit

Permalink
Fix/#135 group pray edge case (#136)
Browse files Browse the repository at this point in the history
* feat: 모임 전용 기도제목 목록 조회 기능 구현 (이미 모임에 있는지 확인 가능)

* refactor: queryDsl 코드 수정

* refactor: 모임 기도 불러오는 기능 GroupPrayController로 이동

* add: 이미 존재하는 모임기도를 요청할 경우 예외처리

* chore: 주석 문구 수정
  • Loading branch information
dong2ast authored Feb 18, 2024
1 parent 7eec90e commit 6439a3f
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 71 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
package com.uspray.uspray.DTO.pray.response;

import com.querydsl.core.annotations.QueryProjection;
import com.uspray.uspray.domain.Pray;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDate;
import javax.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.Data;

@Getter
@AllArgsConstructor
@Builder
@Data
@Schema(description = "기도제목 응답 DTO")
public class PrayResponseDto {

Expand Down Expand Up @@ -41,6 +38,23 @@ public class PrayResponseDto {
@Schema(description = "기도제목 공유 여부", example = "true")
private Boolean isShared;

@Schema(description = "모임 기도제목 존재 여부", example = "false")
private Boolean inGroup;

@QueryProjection
public PrayResponseDto(Long prayId, String content, String name, LocalDate deadline,
Long categoryId, String categoryName, LocalDate lastPray, Boolean isShared) {
this.prayId = prayId;
this.content = content;
this.name = name;
this.deadline = deadline;
this.categoryId = categoryId;
this.categoryName = categoryName;
this.isPrayedToday = lastPray.isEqual(LocalDate.now());
this.isShared = isShared;
this.inGroup = false;
}


public static PrayResponseDto of(Pray pray) {
return new PrayResponseDto(
Expand All @@ -50,7 +64,7 @@ public static PrayResponseDto of(Pray pray) {
pray.getDeadline(),
pray.getCategory().getId(),
pray.getCategory().getName(),
pray.getLastPrayedAt().isEqual(LocalDate.now()),
pray.getLastPrayedAt(),
pray.getIsShared());
}

Expand All @@ -62,7 +76,7 @@ public static PrayResponseDto shared(Pray pray, Pray originPray) {
pray.getDeadline(),
pray.getCategory().getId(),
pray.getCategory().getName(),
pray.getLastPrayedAt().isEqual(LocalDate.now()),
pray.getLastPrayedAt(),
pray.getIsShared());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import com.uspray.uspray.DTO.grouppray.GroupPrayRequestDto;
import com.uspray.uspray.DTO.grouppray.GroupPrayResponseDto;
import com.uspray.uspray.DTO.grouppray.ScrapRequestDto;
import com.uspray.uspray.DTO.pray.PrayListResponseDto;
import com.uspray.uspray.DTO.pray.request.PrayToGroupPrayDto;
import com.uspray.uspray.DTO.pray.response.PrayResponseDto;
import com.uspray.uspray.exception.SuccessStatus;
import com.uspray.uspray.service.GroupPrayFacade;
import com.uspray.uspray.service.GroupPrayService;
Expand All @@ -15,6 +18,7 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.User;
Expand All @@ -36,6 +40,35 @@ public class GroupPrayController {
private final GroupPrayService groupPrayService;
private final GroupPrayFacade groupPrayFacade;

@Operation(summary = "[모임 전용] 기도제목 목록 조회")
@ApiResponse(
responseCode = "200",
description = "기도제목 목록 반환",
content = @Content(schema = @Schema(implementation = PrayResponseDto.class)))
@GetMapping
public ApiResponseDto<List<PrayListResponseDto>> getPrayList(
@Parameter(hidden = true) @AuthenticationPrincipal User user,
@Parameter(description = "기도제목 종류(personal, shared)", required = true, example = "personal") String prayType,
@Parameter(example = "1") Long groupId
) {
return ApiResponseDto.success(SuccessStatus.GET_PRAY_LIST_SUCCESS,
groupPrayFacade.getPrayList(user.getUsername(), prayType, groupId));
}

@Operation(summary = "모임 기도제목으로 불러오기")
@ApiResponse(
responseCode = "200",
description = "모임 기도제목으로 불러오기",
content = @Content(schema = @Schema(implementation = PrayResponseDto.class)))
@PostMapping("/pray-to-grouppray")
public ApiResponseDto<?> prayToGroupPray(
@RequestBody PrayToGroupPrayDto prayToGroupPrayDto,
@Parameter(hidden = true) @AuthenticationPrincipal User user
) {
groupPrayFacade.prayToGroupPray(prayToGroupPrayDto, user.getUsername());
return ApiResponseDto.success(SuccessStatus.PRAY_TO_GROUP_PRAY_SUCCESS);
}

@Operation(summary = "모임 기도제목 생성")
@PostMapping
@ApiResponse(
Expand Down
19 changes: 2 additions & 17 deletions src/main/java/com/uspray/uspray/controller/PrayController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.uspray.uspray.DTO.ApiResponseDto;
import com.uspray.uspray.DTO.pray.PrayListResponseDto;
import com.uspray.uspray.DTO.pray.request.PrayRequestDto;
import com.uspray.uspray.DTO.pray.request.PrayToGroupPrayDto;
import com.uspray.uspray.DTO.pray.request.PrayUpdateRequestDto;
import com.uspray.uspray.DTO.pray.response.PrayResponseDto;
import com.uspray.uspray.exception.SuccessStatus;
Expand Down Expand Up @@ -48,7 +47,7 @@ public class PrayController {
responseCode = "200",
description = "기도제목 목록 반환",
content = @Content(schema = @Schema(implementation = PrayResponseDto.class)))
@GetMapping()
@GetMapping
public ApiResponseDto<List<PrayListResponseDto>> getPrayList(
@Parameter(hidden = true) @AuthenticationPrincipal User user,
@Parameter(description = "기도제목 종류(personal, shared)", required = true, example = "personal") String prayType
Expand All @@ -71,7 +70,7 @@ public ApiResponseDto<PrayResponseDto> getPrayDetail(
prayService.getPrayDetail(prayId, user.getUsername()));
}

@PostMapping()
@PostMapping
@ApiResponse(
responseCode = "201",
description = "기도제목 생성",
Expand Down Expand Up @@ -154,18 +153,4 @@ public ApiResponseDto<List<PrayListResponseDto>> cancelPray(
return ApiResponseDto.success(SuccessStatus.CANCEL_PRAY_SUCCESS,
prayFacade.cancelPray(prayId, user.getUsername()));
}

@Operation(summary = "모임 기도제목으로 불러오기")
@ApiResponse(
responseCode = "200",
description = "모임 기도제목으로 불러오기",
content = @Content(schema = @Schema(implementation = PrayResponseDto.class)))
@PostMapping("/pray-to-grouppray")
public ApiResponseDto<?> prayToGroupPray(
@RequestBody PrayToGroupPrayDto prayToGroupPrayDto,
@Parameter(hidden = true) @AuthenticationPrincipal User user
) {
prayFacade.prayToGroupPray(prayToGroupPrayDto, user.getUsername());
return ApiResponseDto.success(SuccessStatus.PRAY_TO_GROUP_PRAY_SUCCESS);
}
}
5 changes: 5 additions & 0 deletions src/main/java/com/uspray/uspray/exception/ErrorStatus.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ public enum ErrorStatus {
GROUP_MEMBER_NOT_FOUND_EXCEPTION(HttpStatus.NOT_FOUND, "해당 멤버를 모임에서 찾을 수 없습니다."),
NOT_FOUND_GROUP_MEMBER_EXCEPTION(HttpStatus.NOT_FOUND, "존재하지 않는 모임 회원입니다."),

/**
* 409 NOT CONFLICT
*/
ALREADY_EXIST_GROUP_PRAY_EXCEPTION(HttpStatus.CONFLICT, "이미 존재하는 모임 기도제목입니다."),

/**
* 500 INTERNAL SERVER ERROR
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@
import java.util.List;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface GroupPrayRepository extends JpaRepository<GroupPray, Long>{

@EntityGraph(attributePaths = {"author"})
List<GroupPray> findGroupPraysByGroup(Group group);

@Query("select g.originPray.id from GroupPray g where g.group.id = :groupId")
List<Long> getOriginPrayIdByGroupId(@Param("groupId") Long groupId);

default GroupPray getGroupPrayById(Long id) {
return this.findById(id).orElseThrow(
() -> new NotFoundException(ErrorStatus.NOT_FOUND_GROUP_PRAY_EXCEPTION,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@
public interface CategoryRepositoryCustom {

List<PrayListResponseDto> findAllWithOrderAndType(String username, String prayType);

List<PrayListResponseDto> findAllWithOrderAndType(String username, String prayType, List<Long> prayIds);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.uspray.uspray.DTO.pray.PrayListResponseDto;
import com.uspray.uspray.DTO.pray.response.PrayResponseDto;
import com.uspray.uspray.DTO.pray.response.QPrayResponseDto;
import com.uspray.uspray.domain.Category;
import com.uspray.uspray.domain.Pray;
import java.util.ArrayList;
Expand Down Expand Up @@ -50,4 +51,43 @@ public List<PrayListResponseDto> findAllWithOrderAndType(String username, String
}
return prayListResponseDtos;
}

@Override
public List<PrayListResponseDto> findAllWithOrderAndType(String username, String prayType,
List<Long> prayIds) {
List<Category> categories = queryFactory
.selectFrom(category)
.where(category.member.userId.eq(username))
.where(category.categoryType.stringValue().likeIgnoreCase(prayType))
.orderBy(category.order.asc())
.fetch();

// 각 카테고리 별로 PrayResponseDto 목록 가져오기
List<PrayListResponseDto> prayListResponseDtos = new ArrayList<>();
for (Category cat : categories) {
List<PrayResponseDto> prayResponseDtos = queryFactory
.select(new QPrayResponseDto(
pray.id,
pray.content,
pray.member.name,
pray.deadline,
pray.category.id,
pray.category.name,
pray.lastPrayedAt,
pray.isShared
))
.from(pray)
.where(pray.category.id.eq(cat.getId())
.and(pray.member.userId.eq(username))
.and(pray.prayType.stringValue().likeIgnoreCase(prayType)))
.fetch();

prayResponseDtos.stream().filter(p -> prayIds.contains(p.getPrayId())).forEach(p -> p.setInGroup(true));

prayListResponseDtos.add(
new PrayListResponseDto(cat.getId(), cat.getName(), cat.getColor(),
prayResponseDtos));
}
return prayListResponseDtos;
}
}
54 changes: 54 additions & 0 deletions src/main/java/com/uspray/uspray/service/GroupPrayFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.uspray.uspray.DTO.grouppray.GroupPrayRequestDto;
import com.uspray.uspray.DTO.grouppray.GroupPrayResponseDto;
import com.uspray.uspray.DTO.grouppray.ScrapRequestDto;
import com.uspray.uspray.DTO.pray.PrayListResponseDto;
import com.uspray.uspray.DTO.pray.request.PrayToGroupPrayDto;
import com.uspray.uspray.Enums.PrayType;
import com.uspray.uspray.domain.Category;
import com.uspray.uspray.domain.Group;
Expand All @@ -12,6 +14,8 @@
import com.uspray.uspray.domain.Member;
import com.uspray.uspray.domain.Pray;
import com.uspray.uspray.domain.ScrapAndHeart;
import com.uspray.uspray.exception.ErrorStatus;
import com.uspray.uspray.exception.model.CustomException;
import com.uspray.uspray.infrastructure.CategoryRepository;
import com.uspray.uspray.infrastructure.GroupMemberRepository;
import com.uspray.uspray.infrastructure.GroupPrayRepository;
Expand Down Expand Up @@ -42,6 +46,56 @@ public class GroupPrayFacade {
private final PrayRepository prayRepository;
private final GroupRepository groupRepository;

@Transactional
public void prayToGroupPray(PrayToGroupPrayDto prayToGroupPrayDto, String userId) {
Member member = memberRepository.getMemberByUserId(userId);
Group group = groupRepository.getGroupById(prayToGroupPrayDto.getGroupId());

List<Long> existIds = group.getGroupPrayList().stream().map(gp -> gp.getOriginPray().getId())
.collect(Collectors.toList());

if (existIds.retainAll(prayToGroupPrayDto.getPrayId())) {
throw new CustomException(ErrorStatus.ALREADY_EXIST_GROUP_PRAY_EXCEPTION,
ErrorStatus.ALREADY_EXIST_GROUP_PRAY_EXCEPTION.getMessage());
}

List<Pray> mainPray = prayRepository.findAllByIdIn(prayToGroupPrayDto.getPrayId());
List<Pray> targetPray = prayRepository.findAllByOriginPrayIdIn(
prayToGroupPrayDto.getPrayId());

for (Pray p : mainPray) {
GroupPray groupPray = GroupPray.builder()
.group(group)
.author(member)
.content(p.getContent())
.deadline(p.getDeadline())
.build();
p.setGroupPray(groupPray);
groupPrayRepository.save(groupPray);

ScrapAndHeart scrapAndHeart = ScrapAndHeart.builder()
.groupPray(groupPray)
.member(member)
.build();
scrapAndHeartRepository.save(scrapAndHeart);

for (Pray TP : targetPray) {
ScrapAndHeart targetScrapAndHeart = ScrapAndHeart.builder()
.groupPray(groupPray)
.member(TP.getMember())
.build();
targetScrapAndHeart.scrapPray(TP);
scrapAndHeartRepository.save(targetScrapAndHeart);
}
}
}

public List<PrayListResponseDto> getPrayList(String username, String prayType, Long groupId) {
List<Long> prayIds = groupPrayRepository.getOriginPrayIdByGroupId(groupId);
return categoryRepository.findAllWithOrderAndType(username, prayType, prayIds);
}


@Transactional
public void createGroupPray(GroupPrayRequestDto groupPrayRequestDto, String userId) {
Member author = memberRepository.getMemberByUserId(userId);
Expand Down
Loading

0 comments on commit 6439a3f

Please sign in to comment.