Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into deploy
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/main/java/org/kakaoshare/backend/logging/interceptor/LoggingInterceptor.java
  • Loading branch information
YeaChan05 committed Jul 21, 2024
2 parents 3ce3e02 + e9695bd commit e48b994
Show file tree
Hide file tree
Showing 18 changed files with 177 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class CartResponse {
private String optionName;
private String optionDetailName;
private Long totalPrice;
private boolean isSelected;

public static CartResponse from(Cart cart){
Long totalPrice = cart.calculateTotalPrice();
Expand All @@ -38,6 +39,7 @@ public static CartResponse from(Cart cart){
.totalPrice(totalPrice)
.optionName(cart.getOption() != null ? cart.getOption().getName() : null)
.optionDetailName(cart.getOptionDetail() != null ? cart.getOptionDetail().getName() : null)
.isSelected(cart.isSelected())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package org.kakaoshare.backend.domain.funding.controller;

import java.util.List;
import lombok.RequiredArgsConstructor;
import org.kakaoshare.backend.common.dto.PageResponse;

import org.kakaoshare.backend.domain.funding.dto.FundingCheckRequest;
import org.kakaoshare.backend.domain.funding.dto.inquiry.request.FriendFundingInquiryRequest;
import org.kakaoshare.backend.domain.funding.dto.FriendFundingItemRequest;
import org.kakaoshare.backend.domain.funding.dto.FundingCheckRequest;
import org.kakaoshare.backend.domain.funding.dto.FundingResponse;
import org.kakaoshare.backend.domain.funding.dto.ProgressResponse;
import org.kakaoshare.backend.domain.funding.dto.RegisterRequest;
import org.kakaoshare.backend.domain.funding.dto.RegisterResponse;
import org.kakaoshare.backend.domain.funding.dto.inquiry.request.FriendFundingInquiryRequest;
import org.kakaoshare.backend.domain.funding.dto.preview.request.FundingPreviewRequest;
import org.kakaoshare.backend.domain.funding.dto.preview.response.FundingPreviewResponse;
import org.kakaoshare.backend.domain.funding.entity.FundingStatus;
Expand All @@ -24,18 +22,21 @@
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1")
public class FundingController {
private static final int DEFAULT_FUNDING_SIZE = 20;
private static final int DEFAULT_TOP_CONTRIBUTORS_SIZE = 5;

private final FundingService fundingService;
private final FundingDetailService fundingDetailService;
private static final int FUNDING_DEFAULT_SIZE = 20;

@PostMapping("/funding/{productId}")
public ResponseEntity<?> registerFunding(@PathVariable("productId") Long productId,
Expand Down Expand Up @@ -74,7 +75,7 @@ public ResponseEntity<?> getFriendsActiveFundingItems(@LoggedInMember String pro
@GetMapping("/members/funding/products")
public ResponseEntity<?> getMyAllFundingProducts(@LoggedInMember String providerId,
@RequestParam(name = "status", required = false) FundingStatus status,
@PageableDefault(size = FUNDING_DEFAULT_SIZE) final Pageable pageable) {
@PageableDefault(size = DEFAULT_FUNDING_SIZE) final Pageable pageable) {
PageResponse<?> response = fundingService.getMyFilteredFundingProducts(providerId, status, pageable);
return ResponseEntity.ok(response);
}
Expand All @@ -85,14 +86,10 @@ public ResponseEntity<?> preview(@RequestBody final FundingPreviewRequest fundin
return ResponseEntity.ok(fundingPreviewResponse);
}

@GetMapping("/{fundingId}/contributors")
public ResponseEntity<?> getTopContributors(@PathVariable Long fundingId,
@PageableDefault(size = 5) Pageable pageable,
@RequestHeader("Authorization") String accessToken) {

accessToken = accessToken.substring("Bearer ".length());
PageResponse<?> contributors = fundingDetailService.getTopContributors(fundingId, pageable,
accessToken);
return ResponseEntity.ok(contributors);
@GetMapping("/funding/{fundingId}/contributors")
public ResponseEntity<?> getTopContributors(@PathVariable final Long fundingId,
@PageableDefault(size = DEFAULT_TOP_CONTRIBUTORS_SIZE) final Pageable pageable) {
final PageResponse<?> response = fundingDetailService.getTopContributors(fundingId, pageable);
return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.kakaoshare.backend.domain.funding.dto.rank.response;

public record TopContributorResponse(
String profileUrl,
String name,
Double rate
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public boolean attributable() {
}

public boolean isAttributableAmount(final int attributeAmount) {
return getRemainAmount() >= attributeAmount;
return (100 <= attributeAmount && attributeAmount <= getRemainAmount() - 100) || attributeAmount == getRemainAmount();
}

public boolean canceled() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,6 @@ public FundingDetail(final Member member,
this.rate = calculateRate(this.amount);
}

public void increaseAmountAndRate(final Long amount) {
if (amount != null) {
this.rate += calculateRate(amount);
this.amount += amount;
}
}

public void partialCancel(final Long amount) {
this.rate -= calculateRate(amount);
this.amount -= amount;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

@Getter
public enum FundingDetailErrorCode implements ErrorCode {
NOT_FOUND(HttpStatus.NOT_FOUND, "기여한 펀딩 내역을 찾을 수 없습니다.");
NOT_FOUND(HttpStatus.NOT_FOUND, "기여한 펀딩 내역을 찾을 수 없습니다."),
INVALID_CANCEL_AMOUNT(HttpStatus.BAD_REQUEST, "환불 금액은 기여 금액보다 클 수 없습니다.");

private final HttpStatus httpStatus;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.kakaoshare.backend.domain.funding.repository;

import org.kakaoshare.backend.domain.funding.dto.rank.response.TopContributorResponse;
import org.kakaoshare.backend.domain.funding.entity.Funding;
import org.kakaoshare.backend.domain.funding.entity.FundingDetail;
import org.kakaoshare.backend.domain.funding.repository.query.FundingDetailRepositoryCustom;
Expand All @@ -21,7 +22,9 @@ public interface FundingDetailRepository extends JpaRepository<FundingDetail, Lo
"WHERE fd.funding.fundingId =:fundingId")
List<FundingDetail> findAllByFundingId(@Param("fundingId") final Long fundingId);

@Query("SELECT fd FROM FundingDetail fd WHERE fd.funding.fundingId = :fundingId ORDER BY fd.amount DESC")
Page<FundingDetail> findTopContributorsByFundingId(@Param("fundingId") Long fundingId, Pageable pageable);

@Query("SELECT NEW org.kakaoshare.backend.domain.funding.dto.rank.response.TopContributorResponse(fd.member.profileImageUrl, fd.member.name, fd.rate) " +
"FROM FundingDetail fd " +
"LEFT JOIN fd.member m ON m.memberId = fd.member.memberId " +
"WHERE fd.funding.fundingId = :fundingId")
Page<TopContributorResponse> findTopContributorsByFundingId(@Param("fundingId") Long fundingId, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,22 @@
import com.querydsl.core.util.StringUtils;
import lombok.RequiredArgsConstructor;
import org.kakaoshare.backend.common.dto.PageResponse;
import org.kakaoshare.backend.domain.friend.service.KakaoFriendService;
import org.kakaoshare.backend.domain.funding.dto.inquiry.ContributedFundingHistoryDto;
import org.kakaoshare.backend.domain.funding.dto.inquiry.request.ContributedFundingHistoryRequest;
import org.kakaoshare.backend.domain.funding.dto.inquiry.response.ContributedFundingHistoryResponse;
import org.kakaoshare.backend.domain.funding.dto.inquiry.response.FundingContributorResponse;
import org.kakaoshare.backend.domain.funding.entity.FundingDetail;
import org.kakaoshare.backend.domain.funding.dto.rank.response.TopContributorResponse;
import org.kakaoshare.backend.domain.funding.repository.FundingDetailRepository;
import org.kakaoshare.backend.domain.funding.vo.FundingHistoryDate;
import org.kakaoshare.backend.domain.member.dto.oauth.profile.detail.KakaoFriendListDto;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class FundingDetailService {
private final FundingDetailRepository fundingDetailRepository;
private final KakaoFriendService kakaoFriendService;

public PageResponse<?> lookUp(final String providerId,
final ContributedFundingHistoryRequest contributedFundingHistoryRequest,
Expand All @@ -45,36 +38,8 @@ private Page<ContributedFundingHistoryDto> getFundingDetailHistoryDto(final Stri
return fundingDetailRepository.findHistoryByCondition(providerId, date, status, pageable);
}

public PageResponse<?> getTopContributors(Long fundingId, Pageable pageable, String accessToken) {
Page<FundingDetail> fundingDetails = fundingDetailRepository.findTopContributorsByFundingId(fundingId, pageable);

List<KakaoFriendListDto> friendsList = kakaoFriendService.getFriendsList(accessToken);

List<FundingContributorResponse> responses = fundingDetails.stream()
.map(detail -> {
KakaoFriendListDto friendProfile = findFriendProfile(detail.getMember().getProviderId(), friendsList);
return FundingContributorResponse.of(
friendProfile.getProfileThumbnailImage(),
friendProfile.getProfileNickname(),
detail.getAmount(),
calculateContributionPercentage(detail)
);
}).toList();

Page<FundingContributorResponse> contributorResponses = new PageImpl<>(responses, pageable, fundingDetails.getTotalElements());
return PageResponse.from(contributorResponses);
}

private KakaoFriendListDto findFriendProfile(String providerId, List<KakaoFriendListDto> friendsList) {
return friendsList.stream()
.filter(friend -> friend.getId().equals(providerId))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No matching friend found for providerId: " + providerId));
}



private double calculateContributionPercentage(FundingDetail detail) {
return 100.0 * detail.getAmount() / detail.getFunding().getGoalAmount();
public PageResponse<?> getTopContributors(final Long fundingId, final Pageable pageable) {
final Page<TopContributorResponse> page = fundingDetailRepository.findTopContributorsByFundingId(fundingId, pageable);
return PageResponse.from(page);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
import java.util.Objects;
import java.util.function.Function;

import static org.kakaoshare.backend.domain.funding.exception.FundingDetailErrorCode.INVALID_CANCEL_AMOUNT;
import static org.kakaoshare.backend.domain.funding.exception.FundingErrorCode.INVALID_ATTRIBUTE_AMOUNT;
import static org.kakaoshare.backend.domain.funding.exception.FundingErrorCode.INVALID_STATUS;
import static org.kakaoshare.backend.domain.member.exception.MemberErrorCode.NOT_FOUND;
Expand Down Expand Up @@ -170,7 +171,7 @@ public PaymentFundingSuccessResponse approveFunding(final String providerId,
final Funding funding = findFundingById(fundingOrderDetail.fundingId());
final Member member = findMemberByProviderId(providerId);
final Long amount = payment.getTotalPrice();
saveOrReflectFundingDetail(payment, funding, member, amount);
saveFundingDetail(payment, funding, member);
funding.increaseAccumulateAmount(amount);

// TODO: 5/10/24 결제 후 목표 금액 달성 시
Expand Down Expand Up @@ -224,12 +225,19 @@ public void cancelFundingDetail(final String providerId,
final PaymentFundingDetailCancelRequest paymentFundingCancelRequest) {
final Long fundingDetailId = paymentFundingCancelRequest.fundingDetailId();
final FundingDetail fundingDetail = findFundingDetailById(fundingDetailId);
final Long amount = paymentFundingCancelRequest.amount();
validateCancelAmount(fundingDetail, amount);
validateAlreadyCanceled(fundingDetail, FundingDetail::canceled);
validateMemberFundingDetail(providerId, fundingDetail);
final Long amount = paymentFundingCancelRequest.amount();
refundFundingDetails(amount, fundingDetail);
}

private void validateCancelAmount(final FundingDetail fundingDetail, final Long amount) {
if (fundingDetail.getAmount() < amount) {
throw new FundingDetailException(INVALID_CANCEL_AMOUNT);
}
}

private Order findOrderByPaymentId(final Long paymentId) {
return orderRepository.findByPaymentId(paymentId)
.orElseThrow(() -> new OrderException(OrderErrorCode.NOT_FOUND));
Expand Down Expand Up @@ -480,11 +488,8 @@ private FundingDetail findFundingDetailById(final Long fundingDetailId) {
.orElseThrow(() -> new FundingDetailException(FundingDetailErrorCode.NOT_FOUND));
}

private void saveOrReflectFundingDetail(final Payment payment, final Funding funding, final Member member, final Long amount) {
fundingDetailRepository.findByFundingAndMember(funding, member)
.ifPresentOrElse(
fundingDetail -> fundingDetail.increaseAmountAndRate(amount),
() -> fundingDetailRepository.save(new FundingDetail(member, funding, payment))
);
private void saveFundingDetail(final Payment payment, final Funding funding, final Member member) {
final FundingDetail fundingDetail = new FundingDetail(member, funding, payment);
fundingDetailRepository.save(fundingDetail);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(
indexes = {@Index(name = "idx_receipt_option_receipt_id",columnList = "receipt_id",unique = true)}
indexes = {@Index(name = "idx_receipt_option_receipt_id", columnList = "receipt_id", unique = false)}
)
public class ReceiptOption {
public class ReceiptOption extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
package org.kakaoshare.backend.logging.config;

import lombok.RequiredArgsConstructor;
import org.kakaoshare.backend.logging.interceptor.LoggingInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StopWatch;
import org.springframework.web.context.annotation.RequestScope;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class LoggingConfig {
@RequiredArgsConstructor
public class LoggingConfig implements WebMvcConfigurer {
private static final String METRIC_URL_PREFIX = "/actuator";
private static final String FAVICON_URL = "/favicon.ico";

private final LoggingInterceptor loggingInterceptor;

@Bean
@RequestScope
public StopWatch stopWatch() {
return new StopWatch();
}

@Override
public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(loggingInterceptor)
.addPathPatterns("/**")
.excludePathPatterns(METRIC_URL_PREFIX, FAVICON_URL);
}
}
Loading

0 comments on commit e48b994

Please sign in to comment.