Skip to content

Commit

Permalink
refactor: develop 업데이트 merge
Browse files Browse the repository at this point in the history
  • Loading branch information
parksey committed Nov 13, 2023
2 parents 7922976 + b5f9a45 commit e7f451f
Show file tree
Hide file tree
Showing 19 changed files with 5,109 additions and 1,016 deletions.
44 changes: 41 additions & 3 deletions src/docs/asciidoc/coupon.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

쿠폰에 대해 생성/삭제/조회/발급/사용 기능을 제공합니다.

---

=== 쿠폰 생성

관리자가 쿠폰을 생성합니다.
Expand All @@ -16,7 +18,9 @@ include::{snippets}/admins/coupons/http-request.adoc[]

include::{snippets}/admins/coupons/http-response.adoc[]

=== 쿠폰 삭제 (진행 중)
---

=== 쿠폰 삭제

관리자가 쿠폰 ID와 일치하는 쿠폰을 삭제합니다.

Expand All @@ -30,16 +34,50 @@ include::{snippets}/admins/coupons/couponId/http-request.adoc[]

include::{snippets}/admins/coupons/couponId/http-response.adoc[]

=== 쿠폰 조회 (진행 중)
---

=== 특정 쿠폰 조회

관리자 혹은 사용자가 특정 ID와 일치하는 쿠폰을 조회합니다.

==== 요청

include::{snippets}/coupons/couponId/http-request.adoc[]

[discrete]
==== 응답

include::{snippets}/coupons/couponId/http-response.adoc[]

---

관리자 혹은 사용자가 쿠폰들을 조회합니다.
=== 상태에 따른 쿠폰들을 조회

관리자 혹은 사용자가 날짜 상태에 따라 쿠폰들을 조회합니다.

==== 요청

include::{snippets}/coupons/search/http-request.adoc[]

[discrete]
==== 응답

include::{snippets}/coupons/search/http-response.adoc[]

---

=== 특정 사용자의 쿠폰 보관함을 조회

사용자가 자신의 보관함에 있는 쿠폰들을 조회합니다.

---

=== 쿠폰 발급 (진행 중)

사용자가 발급 가능한 쿠폰을 선착순으로 발급 받습니다.

---

=== 쿠폰 사용 (진행 중)

사용자가 자신의 보관함에 있는 쿠폰들을 사용합니다.
21 changes: 21 additions & 0 deletions src/main/java/com/moabam/api/application/CouponService.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package com.moabam.api.application;

import java.time.LocalDateTime;
import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.moabam.api.domain.entity.Coupon;
import com.moabam.api.domain.repository.CouponRepository;
import com.moabam.api.domain.repository.CouponSearchRepository;
import com.moabam.api.dto.CouponMapper;
import com.moabam.api.dto.CouponResponse;
import com.moabam.api.dto.CouponSearchRequest;
import com.moabam.api.dto.CreateCouponRequest;
import com.moabam.global.error.exception.BadRequestException;
import com.moabam.global.error.exception.ConflictException;
Expand All @@ -22,6 +26,7 @@
public class CouponService {

private final CouponRepository couponRepository;
private final CouponSearchRepository couponSearchRepository;

@Transactional
public void createCoupon(Long adminId, CreateCouponRequest request) {
Expand All @@ -39,6 +44,22 @@ public void deleteCoupon(Long adminId, Long couponId) {
couponRepository.delete(coupon);
}

public CouponResponse getCouponById(Long couponId) {
Coupon coupon = couponSearchRepository.findById(couponId)
.orElseThrow(() -> new NotFoundException(ErrorMessage.NOT_FOUND_COUPON));

return CouponMapper.toDto(coupon);
}

public List<CouponResponse> getCoupons(CouponSearchRequest request) {
LocalDateTime now = LocalDateTime.now();
List<Coupon> coupons = couponSearchRepository.findAllByStatus(now, request);

return coupons.stream()
.map(CouponMapper::toDto)
.toList();
}

private void validateConflictCouponName(String name) {
if (couponRepository.existsByName(name)) {
throw new ConflictException(ErrorMessage.CONFLICT_COUPON_NAME);
Expand Down
19 changes: 14 additions & 5 deletions src/main/java/com/moabam/api/domain/entity/Coupon.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.moabam.api.domain.entity;

import static com.moabam.global.common.util.GlobalConstant.*;
import static com.moabam.global.error.model.ErrorMessage.*;
import static java.util.Objects.*;

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

import org.hibernate.annotations.ColumnDefault;

Expand Down Expand Up @@ -42,12 +44,13 @@ public class Coupon extends BaseTimeEntity {
@Column(name = "point", nullable = false)
private int point;

@ColumnDefault("''")
@Column(name = "description", length = 50)
private String description;

@Enumerated(value = EnumType.STRING)
@Column(name = "type", nullable = false)
private CouponType type;
@Column(name = "coupon_type", nullable = false)
private CouponType couponType;

@ColumnDefault("1")
@Column(name = "stock", nullable = false)
Expand All @@ -59,16 +62,17 @@ public class Coupon extends BaseTimeEntity {
@Column(name = "end_at", nullable = false)
private LocalDateTime endAt;

// TODO : 관리자 테이블 생기면 관리자 테이블이랑 다대일 관계 맺을 예정
@Column(name = "admin_id", updatable = false, nullable = false)
private Long adminId;

@Builder
private Coupon(String name, int point, String description, CouponType type, int stock, LocalDateTime startAt,
private Coupon(String name, int point, String description, CouponType couponType, int stock, LocalDateTime startAt,
LocalDateTime endAt, Long adminId) {
this.name = requireNonNull(name);
this.point = validatePoint(point);
this.description = description;
this.type = requireNonNull(type);
this.description = Optional.ofNullable(description).orElse(BLANK);
this.couponType = requireNonNull(couponType);
this.stock = validateStock(stock);
this.startAt = requireNonNull(startAt);
this.endAt = requireNonNull(endAt);
Expand All @@ -90,4 +94,9 @@ private int validateStock(int stock) {

return stock;
}

@Override
public String toString() {
return "Coupon{startAt=" + startAt + ", endAt=" + endAt + '}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.moabam.api.domain.repository;

import static com.moabam.api.domain.entity.QCoupon.*;

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

import org.springframework.stereotype.Repository;

import com.moabam.api.domain.entity.Coupon;
import com.moabam.api.dto.CouponSearchRequest;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQueryFactory;

import lombok.RequiredArgsConstructor;

@Repository
@RequiredArgsConstructor
public class CouponSearchRepository {

private final JPAQueryFactory jpaQueryFactory;

public Optional<Coupon> findById(Long couponId) {
return Optional.ofNullable(
jpaQueryFactory.selectFrom(coupon)
.where(coupon.id.eq(couponId))
.fetchOne()
);
}

public List<Coupon> findAllByStatus(LocalDateTime now, CouponSearchRequest request) {
return jpaQueryFactory.selectFrom(coupon)
.where(filterCouponStatus(now, request))
.fetch();
}

private BooleanExpression filterCouponStatus(LocalDateTime now, CouponSearchRequest request) {
if (request.couponOngoing() && request.couponNotStarted() && request.couponEnded()) {
return null;
}

// 시작 전이거나 진행 중인 쿠폰들을 조회하고 싶은 경우
if (request.couponOngoing() && request.couponNotStarted()) {
return (coupon.startAt.gt(now))
.or(coupon.startAt.loe(now).and(coupon.endAt.goe(now)));
}

// 종료 됐거나 진행 중인 쿠폰들을 조회하고 싶은 경우
if (request.couponOngoing() && request.couponEnded()) {
return (coupon.endAt.lt(now))
.or(coupon.startAt.loe(now).and(coupon.endAt.goe(now)));
}

// 진행 중이 아니고, 시작 전이거나, 종료된 쿠폰들을 조회하고 싶은 경우
if (request.couponNotStarted() && request.couponEnded()) {
return coupon.startAt.gt(now)
.or(coupon.endAt.lt(now));
}

// 진행 중인 쿠폰들을 조회하고 싶은 경우
if (request.couponOngoing()) {
return coupon.startAt.loe(now)
.and(coupon.endAt.goe(now));
}

// 시작 적인 쿠폰들을 조회하고 싶은 경우
if (request.couponNotStarted()) {
return coupon.startAt.gt(now);
}

// 종료된 쿠폰들을 조회하고 싶은 경우
if (request.couponEnded()) {
return coupon.endAt.lt(now);
}

return Expressions.FALSE;
}
}
17 changes: 16 additions & 1 deletion src/main/java/com/moabam/api/dto/CouponMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,27 @@ public static Coupon toEntity(Long adminId, CreateCouponRequest request) {
return Coupon.builder()
.name(request.name())
.description(request.description())
.type(CouponType.from(request.type()))
.couponType(CouponType.from(request.couponType()))
.point(request.point())
.stock(request.stock())
.startAt(request.startAt())
.endAt(request.endAt())
.adminId(adminId)
.build();
}

// TODO : Admin Table 생성 시, 관리자 명 추가할 예정
public static CouponResponse toDto(Coupon coupon) {
return CouponResponse.builder()
.couponId(coupon.getId())
.couponAdminName(coupon.getAdminId() + "admin")
.name(coupon.getName())
.description(coupon.getDescription())
.point(coupon.getPoint())
.stock(coupon.getStock())
.couponType(coupon.getCouponType())
.startAt(coupon.getStartAt())
.endAt(coupon.getEndAt())
.build();
}
}
25 changes: 25 additions & 0 deletions src/main/java/com/moabam/api/dto/CouponResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.moabam.api.dto;

import java.time.LocalDateTime;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.moabam.api.domain.entity.enums.CouponType;

import lombok.Builder;

@Builder
public record CouponResponse(
Long couponId,
String couponAdminName,
String name,
String description,
int point,
int stock,
CouponType couponType,
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm")
LocalDateTime startAt,
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm")
LocalDateTime endAt
) {

}
12 changes: 12 additions & 0 deletions src/main/java/com/moabam/api/dto/CouponSearchRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.moabam.api.dto;

import lombok.Builder;

@Builder
public record CouponSearchRequest(
boolean couponOngoing,
boolean couponNotStarted,
boolean couponEnded
) {

}
2 changes: 1 addition & 1 deletion src/main/java/com/moabam/api/dto/CreateCouponRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
public record CreateCouponRequest(
@NotBlank(message = "쿠폰명이 입력되지 않았거나 20자를 넘었습니다.") @Length(max = 20) String name,
@Length(max = 50, message = "쿠폰 간단 소개는 최대 50자까지 가능합니다.") String description,
@NotBlank(message = "쿠폰 종류를 입력해주세요.") String type,
@NotBlank(message = "쿠폰 종류를 입력해주세요.") String couponType,
@Min(value = 1, message = "벌레 수 혹은 할인 금액은 1 이상이어야 합니다.") int point,
@Min(value = 1, message = "쿠폰 재고는 1 이상이어야 합니다.") int stock,
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm")
Expand Down
26 changes: 21 additions & 5 deletions src/main/java/com/moabam/api/presentation/CouponController.java
Original file line number Diff line number Diff line change
@@ -1,35 +1,51 @@
package com.moabam.api.presentation;

import java.util.List;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.moabam.api.application.CouponService;
import com.moabam.api.dto.CouponResponse;
import com.moabam.api.dto.CouponSearchRequest;
import com.moabam.api.dto.CreateCouponRequest;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@RequestMapping("/admins")
public class CouponController {

private final CouponService couponService;

@PostMapping("/coupons")
@PostMapping("/admins/coupons")
@ResponseStatus(HttpStatus.CREATED)
public void createCoupon(@RequestBody CreateCouponRequest request) {
public void createCoupon(@Valid @RequestBody CreateCouponRequest request) {
couponService.createCoupon(1L, request);
}

@DeleteMapping("/coupons/{couponId}")
@DeleteMapping("/admins/coupons/{couponId}")
@ResponseStatus(HttpStatus.OK)
public void deleteCoupon(@PathVariable Long couponId) {
couponService.deleteCoupon(1L, couponId);
}

@GetMapping("/coupons/{couponId}")
@ResponseStatus(HttpStatus.OK)
public CouponResponse getCouponById(@PathVariable Long couponId) {
return couponService.getCouponById(couponId);
}

@PostMapping("/coupons/search")
@ResponseStatus(HttpStatus.OK)
public List<CouponResponse> getCoupons(@Valid @RequestBody CouponSearchRequest request) {
return couponService.getCoupons(request);
}
}
Loading

0 comments on commit e7f451f

Please sign in to comment.