Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ dependencies {

// email
implementation("com.sun.mail:javax.mail:1.6.2")

// test h2 db
testImplementation 'com.h2database:h2'

}

tasks.named('test') {
Expand Down
5 changes: 5 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
pluginManagement {
plugins {
id 'org.jetbrains.kotlin.jvm' version '2.2.0'
}
}
rootProject.name = 'demo'
3 changes: 2 additions & 1 deletion src/main/java/NextLevel/demo/exception/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ public enum ErrorCode {

// project
NOT_CORRECT_TAG_SIZE(HttpStatus.BAD_REQUEST, "04001","invalidated tag input") ,
ERROR_EXPIRED_DATE_CONVERSION(HttpStatus.BAD_REQUEST, "04003","can not convert expired : %s"),
ERROR_EXPIRED_DATE_CONVERSION(HttpStatus.BAD_REQUEST, "04003","can not convert date : %s"),
START_MUST_BEFORE_EXPIRED(HttpStatus.BAD_REQUEST, "04004","start must be before expired"),

// funding
NOT_ENOUGH_POINT(HttpStatus.BAD_REQUEST, "05001","not enough point left:%s, need:%s"),
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/NextLevel/demo/funding/dto/funding dto.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
project 별 funding 정보 dto : my page 메이커
project dto : project total funding dto
project funding dto (기본 정보)
option funding list dto : input ( OptionEntity(with List<OptionFundingEntity (with UserEntity) > ) ) + option 정렬, option funding 날짜 정렬
option dto
List<option funding dto>
List<free funding dto>

project funding dto : project 기본 funding 정보 (총 금액, 총 펀딩 수, ... )
option funding list dto : { option dto, List<option funding dto> }
option dto : option 정보, 금액
option funding dto : user funding Info dto, coupon dto, 금액, 날짜, 갯수
free funding dto : user funding Info, 금액, 날짜

project list with my funding 정보 dto : my page 서포터 (내가 한 펀딩 리스트)
project list dto : project list with funding dto
project list detail dto
List<option funding list dto>
option dto,
option funding dto
free funding dto
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package NextLevel.demo.funding.dto.response;

import NextLevel.demo.funding.entity.FreeFundingEntity;
import NextLevel.demo.user.dto.user.response.UserFundingInfoDto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.time.LocalDateTime;
import java.util.Optional;

@Getter
@Setter
@NoArgsConstructor
public class FreeFundingDto {

private UserFundingInfoDto user;
private Long price;
private LocalDateTime createdAt;

public static FreeFundingDto of(FreeFundingEntity freeFunding) {
if(freeFunding == null) return null;
FreeFundingDto dto = new FreeFundingDto();
dto.user = UserFundingInfoDto.of(freeFunding.getUser());
dto.price = freeFunding.getPrice();
dto.createdAt = freeFunding.getCreatedAt();
return dto;
}

public static FreeFundingDto of(Optional<FreeFundingEntity> freeFunding) {
if(freeFunding == null || freeFunding.isEmpty()) return null;
return FreeFundingDto.of(freeFunding.get());
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package NextLevel.demo.funding.dto.response;

import NextLevel.demo.funding.entity.CouponEntity;
import NextLevel.demo.funding.entity.OptionFundingEntity;
import NextLevel.demo.user.dto.user.response.UserFundingInfoDto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.time.LocalDateTime;

@NoArgsConstructor
@Getter
@Setter
//option funding dto : user funding Info dto, 갯수
public class OptionFundingDto {

private UserFundingInfoDto user;
private ResponseCouponDto coupon;
private LocalDateTime createdAt;
private long price;
private Long count;

public static OptionFundingDto of(OptionFundingEntity optionFunding) {
OptionFundingDto dto = new OptionFundingDto();
dto.user = UserFundingInfoDto.of(optionFunding.getUser());
dto.coupon = ResponseCouponDto.of(optionFunding.getCoupon());
dto.createdAt = optionFunding.getCreatedAt();
dto.count = optionFunding.getCount();
dto.price = ( optionFunding.getOption().getPrice() * dto.count ) - (optionFunding.getCoupon() != null ? optionFunding.getCoupon().getPrice() : 0);
return dto;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package NextLevel.demo.funding.dto.response;

import NextLevel.demo.funding.entity.OptionFundingEntity;
import NextLevel.demo.option.OptionDto;
import NextLevel.demo.option.OptionEntity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;

@NoArgsConstructor
@Getter
@Setter
// option 정보, List<option funding dto>
public class OptionFundingListDto {
private OptionDto option;
private List<OptionFundingDto> optionFunding;

@JsonIgnore
private Long price;

@JsonIgnore
private Long count;

public static OptionFundingListDto of(OptionEntity option){
OptionFundingListDto dto = new OptionFundingListDto();
dto.option = OptionDto.of(option);

//dto.optionFunding = option.getFundings().stream().map(OptionFundingDto::of).toList();
Long price = 0L;
Long count = 0L;
List<OptionFundingDto> optionFundingDtoList = new ArrayList<>();

for(OptionFundingEntity optionFunding : option.getFundings()){
count++;
price += optionFunding.getOption().getPrice() * optionFunding.getCount();
optionFundingDtoList.add(OptionFundingDto.of(optionFunding));
}

dto.optionFunding = optionFundingDtoList;
dto.price = price;
dto.count = count;

return dto;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package NextLevel.demo.funding.dto.response;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
// 기본 funding 정보 (총 금액, 총 funding 수)
public class ProjectFundingDto {
private Long count;
private Long price;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package NextLevel.demo.funding.dto.response;

import NextLevel.demo.funding.entity.FreeFundingEntity;
import NextLevel.demo.option.OptionEntity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;

@Getter
@Setter
@NoArgsConstructor
public class ProjectTotalFundingDto {

private ProjectFundingDto total; // count, price
private List<OptionFundingListDto> optionFunding; // List<OptionEntity> (with OptionFunding, User, Coupon)
private List<FreeFundingDto> freeFunding; // List<FreeFundingEntity>

public static ProjectTotalFundingDto of(List<OptionEntity> optionList, List<FreeFundingEntity> freeFundingList) {
ProjectTotalFundingDto dto = new ProjectTotalFundingDto();

Long count = 0L;
Long price = 0L;
List<OptionFundingListDto> optionFundingList = new ArrayList<>();
for(OptionEntity option : optionList){
OptionFundingListDto listDto = OptionFundingListDto.of(option);
optionFundingList.add(listDto);
count += listDto.getCount();
price += listDto.getPrice();
}

List<FreeFundingDto> freeFundingDtoList = new ArrayList<>();
for(FreeFundingEntity freeFunding : freeFundingList){
FreeFundingDto freeFundingDto = FreeFundingDto.of(freeFunding);
freeFundingDtoList.add(freeFundingDto);
count++;
price += freeFundingDto.getPrice();
}

dto.total = new ProjectFundingDto(count, price);

return dto;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public class ResponseCouponDto {
private Long percent;

public static ResponseCouponDto of(CouponEntity couponEntity) {
if(couponEntity == null)
return null;
ResponseCouponDto dto = new ResponseCouponDto();
dto.id = couponEntity.getId();
dto.name = couponEntity.getName();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package NextLevel.demo.funding.entity;

import NextLevel.demo.BasedEntity;
import NextLevel.demo.project.project.entity.ProjectEntity;
import NextLevel.demo.user.entity.UserEntity;
import jakarta.persistence.*;
Expand All @@ -11,7 +12,7 @@
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
@AllArgsConstructor
public class FreeFundingEntity {
public class FreeFundingEntity extends BasedEntity {

@Id
@GeneratedValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,28 @@
import static NextLevel.demo.funding.entity.QOptionFundingEntity.optionFundingEntity;
import static NextLevel.demo.project.project.entity.QProjectEntity.projectEntity;

import NextLevel.demo.funding.entity.QCouponEntity;
import NextLevel.demo.funding.entity.QFreeFundingEntity;
import NextLevel.demo.funding.entity.QOptionFundingEntity;
import NextLevel.demo.option.QOptionEntity;
import NextLevel.demo.project.project.entity.ProjectEntity;
import NextLevel.demo.project.project.entity.QProjectEntity;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.NumberExpression;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository
@RequiredArgsConstructor
@Slf4j
public class FundingDslRepository {

private final JPAQueryFactory queryFactory;
Expand All @@ -28,6 +38,33 @@ public boolean isFreeFunding(Long projectId, Long userId) {
.fetchOne();
}

public void addFundingData(List<ProjectEntity> projectList, Long userId) {
QProjectEntity project = new QProjectEntity("project");
QOptionEntity option = new QOptionEntity("option");
QOptionFundingEntity optionFunding = new QOptionFundingEntity("optionFunding");
QFreeFundingEntity freeFunding = new QFreeFundingEntity("freeFunding");
QCouponEntity coupon = new QCouponEntity("coupon");

BooleanExpression where = project.id.in(projectList.stream().map(ProjectEntity::getId).toList());
if(userId != null)
where = where.and(optionFunding.user.id.eq(userId).or(optionFunding.isNull())).and(freeFunding.user.id.eq(userId).or(freeFunding.isNull()));

List<ProjectEntity> projectListWithFunding = queryFactory
.select(project)
.from(project)
.leftJoin(project.options, option).fetchJoin()
.leftJoin(option.fundings, optionFunding).fetchJoin()
.leftJoin(optionFunding.coupon).fetchJoin()
.leftJoin(project.freeFundings, freeFunding).fetchJoin()
.where(where)
.fetch();

Map<Long, ProjectEntity> result = new HashMap<>();
projectListWithFunding.forEach(p->result.put(p.getId(), p));

projectList.forEach(p->p.setFundingData(result.get(p.getId())));
}

public Expression<Double> completeRate(QProjectEntity projectEntity) {
QProjectEntity newProjectEntity = new QProjectEntity("projectEntity3");
return queryFactory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ public void optionFunding(@Valid RequestOptionFundingDto dto) {
user.updatePoint(-totalPrice);
}

// 분리 필요!!
// 이미 option1을 구매하면서 coupon1을 사용 -> 이후 option1을 추가 구매 (with other coupon) => error (coupon <> option 1대 1이여야 함!)
// 아니면 언제나 새로운 결제 정보를 db에 저장한다! (이게 좀 더 맞는듯, 갯수 col지우고)
private void updateOptionFunding() {

}

@Transactional
public void freeFunding(@Valid RequestFreeFundingDto dto) {
UserEntity user = userValidateService.getUserInfoWithAccessToken(dto.getUserId());
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/NextLevel/demo/option/OptionController.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class OptionController {

@GetMapping("/public/option/{projectId}")
public ResponseEntity<?> getAllOptions(@PathVariable("projectId") Long projectId) {
List<ResponseOptionDto> dtos = optionService.getAllOptions(projectId);
List<OptionDto> dtos = optionService.getAllOptions(projectId);
return ResponseEntity.ok().body(new SuccessResponse("success", dtos));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
@Getter
@Setter
@NoArgsConstructor
public class ResponseOptionDto {
public class OptionDto {
private Long id;
private Integer price;
private String description;

public static ResponseOptionDto of(OptionEntity entity) {
ResponseOptionDto dto = new ResponseOptionDto();
public static OptionDto of(OptionEntity entity) {
OptionDto dto = new OptionDto();
dto.id =entity.getId();
dto.price = entity.getPrice();
dto.description = entity.getDescription();
Expand Down
1 change: 1 addition & 0 deletions src/main/java/NextLevel/demo/option/OptionEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;

import java.util.List;
import java.util.Set;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
Expand Down
Loading
Loading