From bede955956413534626b2a78ee1bce2de665e68d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9E=AC=ED=98=81?= Date: Tue, 19 Nov 2024 11:31:22 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=9E=A5=EB=B0=94=EA=B5=AC=EB=8B=88=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?(#41)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../order/application/OrderService.java | 68 +++++++++++++++++++ .../jangburich/domain/order/domain/Cart.java | 26 +++++++ .../domain/repository/CartRepository.java | 14 ++++ .../domain/repository/OrdersRepository.java | 9 +++ .../order/dto/request/AddCartRequest.java | 8 +++ .../order/presentation/OrderController.java | 33 +++++++++ .../StoreQueryDslRepositoryImpl.java | 10 ++- 7 files changed, 166 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/jangburich/domain/order/application/OrderService.java create mode 100644 src/main/java/com/jangburich/domain/order/domain/repository/CartRepository.java create mode 100644 src/main/java/com/jangburich/domain/order/domain/repository/OrdersRepository.java create mode 100644 src/main/java/com/jangburich/domain/order/dto/request/AddCartRequest.java create mode 100644 src/main/java/com/jangburich/domain/order/presentation/OrderController.java diff --git a/src/main/java/com/jangburich/domain/order/application/OrderService.java b/src/main/java/com/jangburich/domain/order/application/OrderService.java new file mode 100644 index 0000000..f547aeb --- /dev/null +++ b/src/main/java/com/jangburich/domain/order/application/OrderService.java @@ -0,0 +1,68 @@ +package com.jangburich.domain.order.application; + +import com.jangburich.domain.menu.domain.Menu; +import com.jangburich.domain.menu.domain.repository.MenuRepository; +import com.jangburich.domain.order.domain.Cart; +import com.jangburich.domain.order.domain.repository.CartRepository; +import com.jangburich.domain.order.domain.repository.OrdersRepository; +import com.jangburich.domain.order.dto.request.AddCartRequest; +import com.jangburich.domain.store.domain.Store; +import com.jangburich.domain.store.domain.repository.StoreRepository; +import com.jangburich.domain.user.domain.User; +import com.jangburich.domain.user.domain.repository.UserRepository; +import com.jangburich.global.payload.Message; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class OrderService { + + private final CartRepository cartRepository; + private final UserRepository userRepository; + private final MenuRepository menuRepository; + private final StoreRepository storeRepository; + + @Transactional + public Message addCart(String userProviderId, AddCartRequest addCartRequest) { + User user = userRepository.findByProviderId(userProviderId) + .orElseThrow(() -> new NullPointerException()); + + Menu menu = menuRepository.findById(addCartRequest.menuId()) + .orElseThrow(() -> new IllegalArgumentException("등록된 메뉴를 찾을 수 없습니다.")); + + System.out.println("menu.getId() = " + menu.getId()); + System.out.println("user.getUserId() = " + user.getUserId()); + + Optional optionalCart = cartRepository.findByUserIdAndMenuId(user.getUserId(), menu.getId()); + + Store store = storeRepository.findById(addCartRequest.storeId()) + .orElseThrow(() -> new IllegalArgumentException("유효하지 않은 가게 id 입니다.")); + + if (optionalCart.isPresent()) { + Cart existingCart = optionalCart.get(); + existingCart.updateQuantity(addCartRequest.quantity()); + + return Message.builder() + .message("장바구니에 상품을 추가했습니다.") + .build(); + } + + Cart newCart = Cart.builder() + .quantity(addCartRequest.quantity()) + .menu(menu) + .user(user) + .store(store) + .orders(null) + .build(); + + cartRepository.save(newCart); + + return Message.builder() + .message("장바구니에 상품을 추가했습니다.") + .build(); + } +} diff --git a/src/main/java/com/jangburich/domain/order/domain/Cart.java b/src/main/java/com/jangburich/domain/order/domain/Cart.java index 014f63d..0be2f63 100644 --- a/src/main/java/com/jangburich/domain/order/domain/Cart.java +++ b/src/main/java/com/jangburich/domain/order/domain/Cart.java @@ -2,6 +2,8 @@ import com.jangburich.domain.common.BaseEntity; import com.jangburich.domain.menu.domain.Menu; +import com.jangburich.domain.store.domain.Store; +import com.jangburich.domain.user.domain.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -10,7 +12,9 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import java.util.List; import lombok.AccessLevel; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -34,4 +38,26 @@ public class Cart extends BaseEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "menu_id") private Menu menu; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "store_id") + private Store store; + + + @Builder + public Cart(Integer quantity, Orders orders, Menu menu, User user, Store store) { + this.quantity = quantity; + this.orders = orders; + this.menu = menu; + this.user = user; + this.store = store; + } + + public void updateQuantity(int quantity) { + this.quantity += quantity; + } } diff --git a/src/main/java/com/jangburich/domain/order/domain/repository/CartRepository.java b/src/main/java/com/jangburich/domain/order/domain/repository/CartRepository.java new file mode 100644 index 0000000..51cd8a7 --- /dev/null +++ b/src/main/java/com/jangburich/domain/order/domain/repository/CartRepository.java @@ -0,0 +1,14 @@ +package com.jangburich.domain.order.domain.repository; + +import com.jangburich.domain.order.domain.Cart; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface CartRepository extends JpaRepository { + @Query("SELECT c FROM Cart c WHERE c.user.userId = :userId AND c.menu.id = :menuId") + Optional findByUserIdAndMenuId(@Param("userId") Long userId, @Param("menuId") Long menuId); +} diff --git a/src/main/java/com/jangburich/domain/order/domain/repository/OrdersRepository.java b/src/main/java/com/jangburich/domain/order/domain/repository/OrdersRepository.java new file mode 100644 index 0000000..b1e47b8 --- /dev/null +++ b/src/main/java/com/jangburich/domain/order/domain/repository/OrdersRepository.java @@ -0,0 +1,9 @@ +package com.jangburich.domain.order.domain.repository; + +import com.jangburich.domain.order.domain.Orders; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface OrdersRepository extends JpaRepository { +} diff --git a/src/main/java/com/jangburich/domain/order/dto/request/AddCartRequest.java b/src/main/java/com/jangburich/domain/order/dto/request/AddCartRequest.java new file mode 100644 index 0000000..0f9e71b --- /dev/null +++ b/src/main/java/com/jangburich/domain/order/dto/request/AddCartRequest.java @@ -0,0 +1,8 @@ +package com.jangburich.domain.order.dto.request; + +public record AddCartRequest( + Long storeId, + Long menuId, + int quantity +) { +} \ No newline at end of file diff --git a/src/main/java/com/jangburich/domain/order/presentation/OrderController.java b/src/main/java/com/jangburich/domain/order/presentation/OrderController.java new file mode 100644 index 0000000..e403e6a --- /dev/null +++ b/src/main/java/com/jangburich/domain/order/presentation/OrderController.java @@ -0,0 +1,33 @@ +package com.jangburich.domain.order.presentation; + +import com.jangburich.domain.order.application.OrderService; +import com.jangburich.domain.order.dto.request.AddCartRequest; +import com.jangburich.global.payload.Message; +import com.jangburich.global.payload.ResponseCustom; +import com.jangburich.utils.parser.AuthenticationParser; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.Authentication; +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.RestController; + +@Tag(name = "Order", description = "Order API") +@RestController +@RequiredArgsConstructor +@RequestMapping("/orders") +public class OrderController { + + private final OrderService orderService; + + @Operation(summary = "장바구니 담기", description = "장바구니에 물건과 수량을 담습니다.") + @PostMapping("/cart") + public ResponseCustom addCart( + Authentication authentication, + @RequestBody AddCartRequest addCartRequest + ) { + return ResponseCustom.OK(orderService.addCart(AuthenticationParser.parseUserId(authentication), addCartRequest)); + } +} diff --git a/src/main/java/com/jangburich/domain/store/domain/repository/StoreQueryDslRepositoryImpl.java b/src/main/java/com/jangburich/domain/store/domain/repository/StoreQueryDslRepositoryImpl.java index 30ef5c1..03f15e6 100644 --- a/src/main/java/com/jangburich/domain/store/domain/repository/StoreQueryDslRepositoryImpl.java +++ b/src/main/java/com/jangburich/domain/store/domain/repository/StoreQueryDslRepositoryImpl.java @@ -34,13 +34,15 @@ public Page findStoresByCategory(Long userId, Integer sear double myCurrentLat = storeSearchCondition.lat(); double myCurrentLon = storeSearchCondition.lon(); + BooleanExpression categoryCondition = isAllCategory(category); + List results = queryFactory .select(new QSearchStoresResponse(store.id, store.name, Expressions.FALSE, store.category, Expressions.constant(1.0), Expressions.constant("open"), store.closeTime.stringValue(), store.contactNumber, store.representativeImage)) .from(store) .where( - store.category.eq(category), + categoryCondition, withinSearchRadius(myCurrentLat, myCurrentLon, searchRadius, store.latitude, store.longitude) ) .orderBy(store.id.desc()) @@ -52,7 +54,7 @@ public Page findStoresByCategory(Long userId, Integer sear .select(store.count()) .from(store) .where( - store.category.eq(category), + categoryCondition, withinSearchRadius(myCurrentLat, myCurrentLon, searchRadius, store.latitude, store.longitude) ); @@ -93,6 +95,10 @@ public Page findStores(Long userId, String keyword, return PageableExecutionUtils.getPage(results, pageable, () -> countQuery.fetch().size()); } + private BooleanExpression isAllCategory(Category category) { + return category == Category.ALL ? Expressions.TRUE : store.category.eq(category); + } + // TO DO private BooleanExpression isStoreCurrentlyOpen(String openTime, String closeTime) { DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");