Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] 점주 주문 리스트 조회 #94

Merged
merged 27 commits into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f3eba0f
[chore] .gitkeep 제거
kimhyun5u Aug 16, 2024
43e039f
[test] OrderRepositoryTest 구현
kimhyun5u Aug 16, 2024
049b831
[feat] OrderRepository 구현
kimhyun5u Aug 16, 2024
0696119
[feat] RetrieveOrderListService 구현
kimhyun5u Aug 16, 2024
3fedac7
[test] RetrieveOrderListServiceTest 구현
kimhyun5u Aug 16, 2024
233d752
[feat] RetrieveOrderListCommand 구현
kimhyun5u Aug 16, 2024
d655a6e
[test] OrderApiControllerTest 구현
kimhyun5u Aug 16, 2024
b07e940
[feat] OrderApiController 구현
kimhyun5u Aug 16, 2024
1a75f86
[feat] RetrieveOrderListResponse 구현
kimhyun5u Aug 16, 2024
e469672
[feat] OrderExceptionHandler 구현
kimhyun5u Aug 16, 2024
80bf9b0
[chore] OrderApiControllerTest 수정
kimhyun5u Aug 16, 2024
edb8b57
[merge] remote-tracking branch 'origin/main' into feature/85_kimhyun5…
kimhyun5u Aug 17, 2024
98b6fd0
[merge] origin/main into feature/85_kimhyun5u_점주-주문-리스트-조회
kimhyun5u Aug 17, 2024
e1216ed
[feat] OrderDTO 구현
kimhyun5u Aug 17, 2024
38b80b1
[feat] OrderItem 수정
kimhyun5u Aug 17, 2024
41a7a8a
[feat] Order 수정
kimhyun5u Aug 17, 2024
6dc5942
[test] OrderApiControllerTest 수정
kimhyun5u Aug 17, 2024
2aa42bb
[feat] VendorFixture 추가
kimhyun5u Aug 17, 2024
01e81ba
[feat] TestOrderDTO 구현
kimhyun5u Aug 17, 2024
20161ab
[feat] StoreFixture 구현
kimhyun5u Aug 17, 2024
3c3032f
[feat] StoreAddress 수정
kimhyun5u Aug 17, 2024
ebcc576
[feat] OrderDTO 생성으로 인한 수정
kimhyun5u Aug 17, 2024
f72d9b7
[merge] remote-tracking branch 'origin/main' into feature/85_kimhyun5…
kimhyun5u Aug 17, 2024
6be0374
[feat] OrderDTO 수정
kimhyun5u Aug 17, 2024
25f085a
[merge] remote-tracking branch 'origin/main' into feature/85_kimhyun5…
kimhyun5u Aug 18, 2024
a6a0975
[fix] OrderDTO 수정
kimhyun5u Aug 18, 2024
94cd2e6
[fix] OrderRepositoryTest 수정
kimhyun5u Aug 18, 2024
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
8 changes: 8 additions & 0 deletions src/main/java/camp/woowak/lab/order/domain/Order.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ public Long getId() {
return id;
}

public Customer getRequester() {
return requester;
}

public Store getStore() {
return store;
}

public List<OrderItem> getOrderItems() {
return orderItems;
}
Expand Down
6 changes: 2 additions & 4 deletions src/main/java/camp/woowak/lab/order/domain/vo/OrderItem.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package camp.woowak.lab.order.domain.vo;

import jakarta.persistence.Embeddable;
import lombok.Getter;

@Getter
@Embeddable
public class OrderItem {
private Long menuId;
Expand All @@ -18,8 +20,4 @@ public OrderItem(Long menuId, long price, int quantity) {
this.quantity = quantity;
this.totalPrice = price * quantity;
}

public long getTotalPrice() {
return totalPrice;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
package camp.woowak.lab.order.repository;

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

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import camp.woowak.lab.order.domain.Order;

public interface OrderRepository extends JpaRepository<Order, Long> {
@Query("SELECT o FROM Order o JOIN FETCH o.store s WHERE s.owner.id = :vendorId")
List<Order> findAllByOwner(UUID vendorId);

@Query("SELECT o FROM Order o JOIN FETCH o.store s WHERE s.id = :storeId AND s.owner.id = :vendorId")
List<Order> findByStore(Long storeId, UUID vendorId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package camp.woowak.lab.order.service;

import java.util.List;

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

import camp.woowak.lab.order.repository.OrderRepository;
import camp.woowak.lab.order.service.command.RetrieveOrderListCommand;
import camp.woowak.lab.order.service.dto.OrderDTO;
import camp.woowak.lab.store.domain.Store;
import camp.woowak.lab.store.exception.NotEqualsOwnerException;
import camp.woowak.lab.store.exception.NotFoundStoreException;
import camp.woowak.lab.store.repository.StoreRepository;

@Service
@Transactional(readOnly = true)
public class RetrieveOrderListService {
private final OrderRepository orderRepository;
private final StoreRepository storeRepository;

public RetrieveOrderListService(OrderRepository orderRepository, StoreRepository storeRepository) {
this.orderRepository = orderRepository;
this.storeRepository = storeRepository;
}

public List<OrderDTO> retrieveOrderListOfVendorStores(RetrieveOrderListCommand command) {
// 점주 매장 주문 조회 권한 검증은 필요없다.
return orderRepository.findAllByOwner(command.vendorId()).stream().map(OrderDTO::new).toList();
}

/**
*
* @throws NotFoundStoreException 매장이 존재하지 않을 경우
* @throws NotEqualsOwnerException 매장의 주인이 아닐 경우
*/
public List<OrderDTO> retrieveOrderListOfStore(RetrieveOrderListCommand command) {
// 점주 매장 주문 조회 권한 검증
// 점주가 소유한 매장인지 확인
Store targetStore = storeRepository.findById(command.storeId())
.orElseThrow(() -> new NotFoundStoreException("해당 매장이 존재하지 않습니다."));

if (!targetStore.isOwnedBy(command.vendorId())) {
throw new NotEqualsOwnerException(command.vendorId() + "는 " + targetStore.getId() + " 매장의 주인이 아닙니다.");
}

return orderRepository.findByStore(command.storeId(), command.vendorId()).stream().map(OrderDTO::new).toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package camp.woowak.lab.order.service.command;

import java.util.UUID;

public record RetrieveOrderListCommand(Long storeId, UUID vendorId) {
Dr-KoKo marked this conversation as resolved.
Show resolved Hide resolved
public RetrieveOrderListCommand(UUID vendorId) {
this(null, vendorId);
}
}
79 changes: 79 additions & 0 deletions src/main/java/camp/woowak/lab/order/service/dto/OrderDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package camp.woowak.lab.order.service.dto;

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

import camp.woowak.lab.customer.domain.Customer;
import camp.woowak.lab.order.domain.Order;
import camp.woowak.lab.order.domain.vo.OrderItem;
import camp.woowak.lab.store.domain.Store;
import lombok.Getter;

@Getter
public class OrderDTO {
private final Long id;
private final RequesterDTO requester;
private final StoreDTO store;
private final List<OrderItemDTO> orderItems;

public OrderDTO(Long id, RequesterDTO requester, StoreDTO store, List<OrderItemDTO> orderItems) {
this.id = id;
this.requester = requester;
this.store = store;
this.orderItems = orderItems;
}

public OrderDTO(Order order) {
this.id = order.getId();
this.requester = new RequesterDTO(order.getRequester());
this.store = new StoreDTO(order.getStore());
this.orderItems = order.getOrderItems().stream().map(OrderItemDTO::new).toList();
}

@Getter
public static class RequesterDTO {
private final UUID id;
private final String name;
private final String email;
private final String phone;

public RequesterDTO(Customer customer) {
this.id = customer.getId();
this.name = customer.getName();
this.email = customer.getEmail();
this.phone = customer.getPhone();
}
}

@Getter
public static class OrderItemDTO {
private final Long menuId;
private final long price;
private final int quantity;
private final long totalPrice;

public OrderItemDTO(OrderItem orderItem) {
this.menuId = orderItem.getMenuId();
this.price = orderItem.getPrice();
this.quantity = orderItem.getQuantity();
this.totalPrice = orderItem.getTotalPrice();
}
}

@Getter
public static class StoreDTO {
private final Long id;
private final String name;
private final String ownerName;
private final String address;
private final String phoneNumber;

public StoreDTO(Store store) {
this.id = store.getId();
this.name = store.getName();
this.ownerName = store.getOwner().getName();
this.address = store.getStoreAddress().getDistrict();
this.phoneNumber = store.getPhoneNumber();
}
}
}
3 changes: 1 addition & 2 deletions src/main/java/camp/woowak/lab/store/domain/Store.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -32,7 +31,7 @@ public class Store {
@JoinColumn(name = "vendor_id", nullable = false)
private Vendor owner;

@OneToOne
@ManyToOne
@JoinColumn(name = "store_category_id", nullable = false)
private StoreCategory storeCategory;

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/camp/woowak/lab/store/domain/StoreAddress.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Embeddable
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class StoreAddress {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,46 @@
package camp.woowak.lab.web.api.order;

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

import camp.woowak.lab.order.service.OrderCreationService;
import camp.woowak.lab.order.service.RetrieveOrderListService;
import camp.woowak.lab.order.service.command.OrderCreationCommand;
import camp.woowak.lab.order.service.command.RetrieveOrderListCommand;
import camp.woowak.lab.web.authentication.LoginCustomer;
import camp.woowak.lab.web.authentication.LoginVendor;
import camp.woowak.lab.web.authentication.annotation.AuthenticationPrincipal;
import camp.woowak.lab.web.dto.response.order.OrderCreationResponse;
import camp.woowak.lab.web.dto.response.order.RetrieveOrderListResponse;
import lombok.extern.slf4j.Slf4j;

@RestController
@Slf4j
public class OrderApiController {
private final OrderCreationService orderCreationService;
private final RetrieveOrderListService retrieveOrderListService;

public OrderApiController(OrderCreationService orderCreationService) {
public OrderApiController(OrderCreationService orderCreationService,
RetrieveOrderListService retrieveOrderListService) {
this.orderCreationService = orderCreationService;
this.retrieveOrderListService = retrieveOrderListService;
}

@GetMapping("/orders")
public RetrieveOrderListResponse retrieveOrderList(@AuthenticationPrincipal LoginVendor loginVendor) {
RetrieveOrderListCommand command = new RetrieveOrderListCommand(loginVendor.getId());
return new RetrieveOrderListResponse(retrieveOrderListService.retrieveOrderListOfVendorStores(command));
}

@GetMapping("/orders/stores/{storeId}")
public RetrieveOrderListResponse retrieveOrderListByStore(@AuthenticationPrincipal LoginVendor loginVendor,
@PathVariable(name = "storeId") Long storeId) {
RetrieveOrderListCommand command = new RetrieveOrderListCommand(storeId, loginVendor.getId());
return new RetrieveOrderListResponse(retrieveOrderListService.retrieveOrderListOfStore(command));
}

@PostMapping("/orders")
Expand All @@ -28,5 +50,6 @@ public OrderCreationResponse order(@AuthenticationPrincipal LoginCustomer loginC
Long createdId = orderCreationService.create(command);
log.info("Created order for customer {} with id {}", loginCustomer.getId(), createdId);
return new OrderCreationResponse(createdId);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package camp.woowak.lab.web.api.order;

import org.springframework.http.HttpStatus;
import org.springframework.http.ProblemDetail;
import org.springframework.web.bind.annotation.ExceptionHandler;

import camp.woowak.lab.common.advice.DomainExceptionHandler;
import camp.woowak.lab.common.exception.HttpStatusException;
import camp.woowak.lab.store.exception.NotEqualsOwnerException;
import camp.woowak.lab.store.exception.NotFoundStoreException;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@DomainExceptionHandler(basePackageClasses = OrderApiController.class)
public class OrderExceptionHandler {
@ExceptionHandler(value = NotFoundStoreException.class)
public ProblemDetail handleNotFoundStoreException(NotFoundStoreException e) {
log.error("Not Found", e);
return getProblemDetail(HttpStatus.NOT_FOUND, e);
}

@ExceptionHandler(value = NotEqualsOwnerException.class)
public ProblemDetail handleNotEqualsOwnerException(NotEqualsOwnerException e) {
log.error("Not Equals Owner", e);
return getProblemDetail(HttpStatus.UNAUTHORIZED, e);
}

private ProblemDetail getProblemDetail(HttpStatus status, HttpStatusException e) {
return ProblemDetail.forStatusAndDetail(status, e.errorCode().getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package camp.woowak.lab.web.dto.response.order;

import java.util.List;

import camp.woowak.lab.order.service.dto.OrderDTO;

public record RetrieveOrderListResponse(List<OrderDTO> orders) {
}
2 changes: 1 addition & 1 deletion src/test/java/camp/woowak/lab/cart/domain/CartTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class CartTest implements CartFixture {
private List<CartItem> cartItemList;
private Cart cart;
private Menu menu;
private int minPrice = 8000;
private final int minPrice = 8000;
private Store store;
private Vendor vendor;

Expand Down
15 changes: 15 additions & 0 deletions src/test/java/camp/woowak/lab/fixture/StoreFixture.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package camp.woowak.lab.fixture;

import java.time.LocalDate;

import camp.woowak.lab.store.TestStore;
import camp.woowak.lab.store.domain.StoreCategory;
import camp.woowak.lab.vendor.domain.Vendor;

public interface StoreFixture {
default TestStore createTestStore(Long id, Vendor owner) {
return new TestStore(id
, owner, new StoreCategory("양식"), "3K1K 가게", "송파", "02-1234-5678", 5000,
LocalDate.now().atTime(6, 0), LocalDate.now().atTime(23, 0));
}
}
8 changes: 8 additions & 0 deletions src/test/java/camp/woowak/lab/fixture/VendorFixture.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import java.util.UUID;

import camp.woowak.lab.payaccount.domain.PayAccount;
import camp.woowak.lab.payaccount.domain.TestPayAccount;
import camp.woowak.lab.vendor.TestVendor;
import camp.woowak.lab.vendor.domain.Vendor;
import camp.woowak.lab.web.authentication.NoOpPasswordEncoder;
import camp.woowak.lab.web.authentication.PasswordEncoder;

public interface VendorFixture {
Expand All @@ -22,4 +24,10 @@ default Vendor createVendor(PayAccount payAccount, PasswordEncoder passwordEncod
return new Vendor("vendorName", "[email protected]", "vendorPassword", "010-0000-0000", payAccount,
passwordEncoder);
}

default TestVendor createTestVendor() {
return new TestVendor(UUID.randomUUID(), "vendorName", "[email protected]", "vendorPassword",
"010-0000-0000", new TestPayAccount(1L),
new NoOpPasswordEncoder());
}
}
Loading