Skip to content

Commit

Permalink
✨ Feature/#83 - 4.8 나의 온기 조회 API 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
dongkyeomjang committed Nov 22, 2024
1 parent 44324da commit d24e54c
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 9 deletions.
5 changes: 5 additions & 0 deletions http/onjung/OnjungControllerHttpRequest.http
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,8 @@ Content-Type: application/json
{
"donation_amount": {{onjung.API_4_7.donation_amount}}
}

### 4.8 나의 온기 조회하기
// @no-log
GET {{host_url}}/api/v1/users/onjungs/overviews
Authorization: Bearer {{access_token}}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@
import com.daon.onjung.account.domain.User;
import com.daon.onjung.core.dto.SelfValidating;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Getter;

@Getter
public class ReadUserOverviewsResponseDto extends SelfValidating<ReadUserOverviewsResponseDto> {

@NotNull(message = "user_name은 null이 될 수 없습니다.")
@JsonProperty("user_name")
private final String userName;

@NotNull(message = "profile_img_url은 null이 될 수 없습니다.")
@JsonProperty("profile_img_url")
private final String profileImgUrl;

Expand All @@ -22,6 +25,7 @@ public ReadUserOverviewsResponseDto(
) {
this.userName = userName;
this.profileImgUrl = profileImgUrl;
this.validateSelf();
}

public static ReadUserOverviewsResponseDto fromEntity(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package com.daon.onjung.account.application.dto.response;

import com.daon.onjung.account.domain.User;
import com.daon.onjung.core.dto.SelfValidating;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Getter;

@Getter
public class UpdateUserNotificationAllowedResponseDto {
public class UpdateUserNotificationAllowedResponseDto extends SelfValidating<UpdateUserNotificationAllowedResponseDto> {

@NotNull(message = "notification_allowed은 null이 될 수 없습니다.")
@JsonProperty("notification_allowed")
private final Boolean notificationAllowed;

Expand All @@ -16,6 +19,7 @@ public UpdateUserNotificationAllowedResponseDto(
Boolean notificationAllowed
) {
this.notificationAllowed = notificationAllowed;
this.validateSelf();
}

public static UpdateUserNotificationAllowedResponseDto fromEntity(User user) {
Expand Down
14 changes: 12 additions & 2 deletions src/main/java/com/daon/onjung/core/utility/DateTimeUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,10 @@ public static String convertLocalDateTimeToCustomDateTime(LocalDateTime dateTime
/**
* 나의 식권 조회 시간 포맷팅: "yyyy.MM.dd"
*
* @param date LocalDateTime
* @param date LocalDate
* @return String
*/
public static String convertLocalDateTimeToDotSeparatedDateTime(LocalDate date) {
public static String convertLocalDateToDotSeparatedDateTime(LocalDate date) {
return date.format(DotSeparatedDateFormatter);
}

Expand All @@ -214,6 +214,16 @@ public static LocalDate convertDotSeparatedToLocalDate(String date) {
return LocalDate.parse(date, DotSeparatedDateFormatter);
}

/**
* 나의 온기 조회 시간 포맷팅: "yyyy.MM.dd"
*
* @param dateTime LocalDate
* @return String
*/
public static String convertLocalDateTimeToDotSeparatedDateTime(LocalDateTime dateTime) {
return dateTime.format(DotSeparatedDateFormatter);
}


/**
* 날짜 문자열을 특정 포맷으로 변환
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public static TicketDto fromEntity(Ticket ticket, Store store) {
return TicketDto.builder()
.id(ticket.getId())
.storeInfo(StoreInfoDto.fromEntity(store))
.expirationDate(DateTimeUtil.convertLocalDateTimeToDotSeparatedDateTime(ticket.getExpirationDate()))
.expirationDate(DateTimeUtil.convertLocalDateToDotSeparatedDateTime(ticket.getExpirationDate()))
.ticketPrice(ticket.getTicketPrice())
.isValidate(ticket.getIsValidate())
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import com.daon.onjung.event.domain.event.EventScheduled;
import com.daon.onjung.event.domain.service.EventService;
import com.daon.onjung.event.domain.service.TicketService;
import com.daon.onjung.event.domain.type.EStatus;
import com.daon.onjung.event.repository.mysql.EventRepository;
import com.daon.onjung.event.repository.mysql.TicketRepository;
import com.daon.onjung.onjung.repository.mysql.DonationRepository;
Expand Down Expand Up @@ -177,7 +176,7 @@ public void execute(Long eventId) {
store.getCategory().toString(),
store.getOcrStoreAddress(),
store.getLogoImgUrl(),
DateTimeUtil.convertLocalDateTimeToDotSeparatedDateTime(ticket.getExpirationDate())
DateTimeUtil.convertLocalDateToDotSeparatedDateTime(ticket.getExpirationDate())
);
restClientUtil.sendPostMethod(url, headers, firebaseRequestBody);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
import com.daon.onjung.onjung.application.dto.response.ReadOnjungBriefResponseDto;
import com.daon.onjung.onjung.application.dto.response.ReadOnjungCountResponseDto;
import com.daon.onjung.onjung.application.dto.response.ReadOnjungSummaryResponseDto;
import com.daon.onjung.onjung.application.dto.response.ReadUserOnjungOverviewResponseDto;
import com.daon.onjung.onjung.application.usecase.ReadOnjungBriefUseCase;
import com.daon.onjung.onjung.application.usecase.ReadOnjungCountUseCase;
import com.daon.onjung.onjung.application.usecase.ReadOnjungSummaryUseCase;
import com.daon.onjung.onjung.application.usecase.ReadUserOnjungOverviewUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
Expand All @@ -21,6 +23,7 @@ public class OnjungQueryV1Controller {
private final ReadOnjungSummaryUseCase readOnjungSummaryUseCase;
private final ReadOnjungCountUseCase readOnjungCountUseCase;
private final ReadOnjungBriefUseCase readOnjungBriefUseCase;
private final ReadUserOnjungOverviewUseCase readUserOnjungOverviewUseCase;

/**
* 4.1 전체 온기 통계 조회하기
Expand Down Expand Up @@ -49,4 +52,14 @@ public ResponseDto<ReadOnjungBriefResponseDto> readOnjungBrief(
) {
return ResponseDto.ok(readOnjungBriefUseCase.execute(accountId));
}

/**
* 4.8 나의 온기 조회
*/
@GetMapping("/api/v1/users/onjungs/overviews")
public ResponseDto<ReadUserOnjungOverviewResponseDto> readUserOnjungOverview(
@AccountID UUID accountId
) {
return ResponseDto.ok(readUserOnjungOverviewUseCase.execute(accountId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.daon.onjung.onjung.application.dto.response;

import com.daon.onjung.core.dto.SelfValidating;
import com.daon.onjung.core.exception.error.ErrorCode;
import com.daon.onjung.core.exception.type.CommonException;
import com.daon.onjung.core.utility.DateTimeUtil;
import com.daon.onjung.onjung.domain.Donation;
import com.daon.onjung.onjung.domain.Receipt;
import com.daon.onjung.onjung.domain.Share;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Getter;

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

@Getter
public class ReadUserOnjungOverviewResponseDto extends SelfValidating<ReadUserOnjungOverviewResponseDto> {

@JsonProperty("store_list")
@NotNull(message = "store_list는 null일 수 없습니다.")
private final List<StoreDto> storeList;

@Builder
public ReadUserOnjungOverviewResponseDto(List<StoreDto> storeList) {
this.storeList = storeList;
this.validateSelf();
}

@Getter
public static class StoreDto extends SelfValidating<StoreDto> {

@JsonProperty("onjung_type")
@NotNull(message = "onjung_type은 null일 수 없습니다.")
private final String onjungType;

@JsonProperty("store_name")
@NotNull(message = "store_name은 null일 수 없습니다.")
private final String storeName;

@JsonProperty("store_title")
@NotNull(message = "store_title은 null일 수 없습니다.")
private final String storeTitle;

@JsonProperty("amount")
@NotNull(message = "amount는 null일 수 없습니다.")
private final Integer amount;

@JsonProperty("date")
@NotNull(message = "date는 null일 수 없습니다.")
private final String date;

@Builder
public StoreDto(String onjungType, String storeName, String storeTitle, Integer amount, String date) {
this.onjungType = onjungType;
this.storeName = storeName;
this.storeTitle = storeTitle;
this.amount = amount;
this.date = date;
this.validateSelf();
}

public static StoreDto of(String onjungType, String storeName, String storeTitle, Integer amount, String date) {
return StoreDto.builder()
.onjungType(onjungType)
.storeName(storeName)
.storeTitle(storeTitle)
.amount(amount)
.date(date)
.build();
}
}

public static ReadUserOnjungOverviewResponseDto of(List<Object> sortedEntities) {

List<StoreDto> storeList = sortedEntities.stream()
.map(entity -> {
if (entity instanceof Donation donation) {
return StoreDto.of(
"DONATION",
donation.getStore().getName(),
donation.getStore().getTitle(),
donation.getDonationAmount(),
DateTimeUtil.convertLocalDateTimeToDotSeparatedDateTime(donation.getCreatedAt())
);
} else if (entity instanceof Receipt receipt) {
return StoreDto.of(
"RECEIPT",
receipt.getStore().getName(),
receipt.getStore().getTitle(),
receipt.getPaymentAmount(),
DateTimeUtil.convertLocalDateTimeToDotSeparatedDateTime(receipt.getCreatedAt())
);
} else if (entity instanceof Share share) {
return StoreDto.of(
"SHARE",
share.getStore().getName(),
share.getStore().getTitle(),
share.getCount() * 100,
DateTimeUtil.convertLocalDateTimeToDotSeparatedDateTime(share.getCreatedAt().atStartOfDay())
);
}
throw new CommonException(ErrorCode.INVALID_ARGUMENT);
})
.collect(Collectors.toList());

return ReadUserOnjungOverviewResponseDto.builder()
.storeList(storeList)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.daon.onjung.onjung.application.service;

import com.daon.onjung.account.domain.User;
import com.daon.onjung.account.repository.mysql.UserRepository;
import com.daon.onjung.core.exception.error.ErrorCode;
import com.daon.onjung.core.exception.type.CommonException;
import com.daon.onjung.onjung.application.dto.response.ReadUserOnjungOverviewResponseDto;
import com.daon.onjung.onjung.application.usecase.ReadUserOnjungOverviewUseCase;
import com.daon.onjung.onjung.domain.Donation;
import com.daon.onjung.onjung.domain.Onjung;
import com.daon.onjung.onjung.domain.Receipt;
import com.daon.onjung.onjung.domain.Share;
import com.daon.onjung.onjung.domain.service.OnjungService;
import com.daon.onjung.onjung.repository.mysql.DonationRepository;
import com.daon.onjung.onjung.repository.mysql.ReceiptRepository;
import com.daon.onjung.onjung.repository.mysql.ShareRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
@RequiredArgsConstructor
public class ReadUserOnjungOverviewService implements ReadUserOnjungOverviewUseCase {

private final UserRepository userRepository;
private final DonationRepository donationRepository;
private final ShareRepository shareRepository;
private final ReceiptRepository receiptRepository;

private final OnjungService onjungService;

@Override
@Transactional(readOnly = true)
public ReadUserOnjungOverviewResponseDto execute(
UUID accountId) {

// 유저 조회
User user = userRepository.findById(accountId)
.orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_RESOURCE));

// 유저의 동참, 공유, 영수증 인증 조회
List<Donation> donations = donationRepository.findAllByUser(user);
List<Share> shares = shareRepository.findAllByUser(user);
List<Receipt> receipts = receiptRepository.findAllByUser(user);

Onjung onjung = onjungService.createOnjung(donations, receipts, shares);

// 생성 시간 기준으로 정렬
List<Object> sortedOnjungByCreatedAt = onjungService.sortOnjungByCreatedAt(onjung);

return ReadUserOnjungOverviewResponseDto.of(sortedOnjungByCreatedAt);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.daon.onjung.onjung.application.usecase;

import com.daon.onjung.core.annotation.bean.UseCase;
import com.daon.onjung.onjung.application.dto.response.ReadUserOnjungOverviewResponseDto;

import java.util.UUID;

@UseCase
public interface ReadUserOnjungOverviewUseCase {

ReadUserOnjungOverviewResponseDto execute(UUID accountId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

import com.daon.onjung.account.domain.Store;
import com.daon.onjung.account.domain.User;
import com.daon.onjung.core.exception.error.ErrorCode;
import com.daon.onjung.core.exception.type.CommonException;
import com.daon.onjung.onjung.domain.Donation;
import com.daon.onjung.onjung.domain.Onjung;
import com.daon.onjung.onjung.domain.Receipt;
import com.daon.onjung.onjung.domain.Share;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;

@Service
Expand Down Expand Up @@ -87,4 +87,25 @@ public Integer calculateTotalOnjungAmount(Onjung onjung) {
})
.reduce(0, Integer::sum);
}

// 온정 객체를 받아서 생성일 기준으로 정렬
public List<Object> sortOnjungByCreatedAt(Onjung onjung) {
List<Object> allEntities = new ArrayList<>();
allEntities.addAll(onjung.getDonations());
allEntities.addAll(onjung.getReceipts());
allEntities.addAll(onjung.getShares());

return allEntities.stream()
.sorted(Comparator.comparing(entity -> {
if (entity instanceof Donation) {
return ((Donation) entity).getCreatedAt();
} else if (entity instanceof Receipt) {
return ((Receipt) entity).getCreatedAt();
} else if (entity instanceof Share) {
return ((Share) entity).getCreatedAt().atStartOfDay();
}
throw new CommonException(ErrorCode.INVALID_ARGUMENT);
}))
.collect(Collectors.toList());
}
}

0 comments on commit d24e54c

Please sign in to comment.