-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
565 additions
and
3 deletions.
There are no files selected for viewing
82 changes: 82 additions & 0 deletions
82
src/main/java/com/bookstore/controller/OrderController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package com.bookstore.controller; | ||
|
||
import com.bookstore.dto.order.OrderCreateDto; | ||
import com.bookstore.dto.order.OrderResponseDto; | ||
import com.bookstore.dto.order.OrderUpdateDto; | ||
import com.bookstore.dto.orderitem.OrderItemResponseDto; | ||
import com.bookstore.model.User; | ||
import com.bookstore.service.OrderService; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import jakarta.validation.Valid; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.security.access.prepost.PreAuthorize; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PatchMapping; | ||
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; | ||
|
||
@Tag(name = "Order management", description = "Endpoints for managing orders") | ||
@RequiredArgsConstructor | ||
@RestController | ||
@RequestMapping(value = "/api/orders") | ||
public class OrderController { | ||
private final OrderService orderService; | ||
|
||
@PostMapping | ||
@PreAuthorize("hasRole('USER')") | ||
@ResponseStatus(HttpStatus.CREATED) | ||
@Operation(summary = "Place an order", | ||
description = "Place an order. Create a new order from shopping cart") | ||
public OrderResponseDto createOrder(Authentication authentication, | ||
@RequestBody @Valid OrderCreateDto orderCreateDto) { | ||
User user = (User) authentication.getPrincipal(); | ||
return orderService.saveOrderFromCart(user.getId(), orderCreateDto); | ||
} | ||
|
||
@GetMapping | ||
@PreAuthorize("hasRole('USER')") | ||
@Operation(summary = "Retrieve user's order history", | ||
description = "User can see all his orders history") | ||
public List<OrderResponseDto> getAllUsersOrders(Authentication authentication, | ||
Pageable pageable) { | ||
User user = (User) authentication.getPrincipal(); | ||
return orderService.getAllUserOrders(user.getId(), pageable); | ||
} | ||
|
||
@GetMapping(value = "/{orderId}/items") | ||
@PreAuthorize("hasRole('USER')") | ||
@Operation(summary = "Retrieve all OrderItems for a specific order", | ||
description = "Retrieve all OrderItems for a specific order") | ||
public List<OrderItemResponseDto> getAllOrderItemsByOrderId(@PathVariable Long orderId, | ||
Pageable pageable) { | ||
return orderService.getAllOrderItemsByOrderId(orderId, pageable); | ||
} | ||
|
||
@GetMapping(value = "/{orderId}/items/{itemId}") | ||
@PreAuthorize("hasRole('USER')") | ||
@Operation(summary = "Retrieve a specific OrderItem within an order", | ||
description = "Retrieve a specific OrderItem within an order") | ||
public OrderItemResponseDto getOrderItemWithinAnOrder(@PathVariable Long orderId, | ||
@PathVariable Long itemId) { | ||
return orderService.getOrderItemWithinAnOrder(orderId, itemId); | ||
} | ||
|
||
@PatchMapping(value = "/{id}") | ||
@PreAuthorize("hasRole('ADMIN')") | ||
@ResponseStatus(HttpStatus.ACCEPTED) | ||
@Operation(summary = "Update order status(for admins)", | ||
description = "Update order status") | ||
public void updateOrderStatus(@PathVariable Long id, | ||
@RequestBody @Valid OrderUpdateDto orderUpdateDto) { | ||
orderService.updateOrderStatus(id, orderUpdateDto); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.bookstore.dto.order; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
import lombok.Data; | ||
|
||
@Data | ||
public class OrderCreateDto { | ||
@NotBlank | ||
private String shippingAddress; | ||
} |
18 changes: 18 additions & 0 deletions
18
src/main/java/com/bookstore/dto/order/OrderResponseDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.bookstore.dto.order; | ||
|
||
import com.bookstore.dto.orderitem.OrderItemResponseDto; | ||
import com.bookstore.model.Order; | ||
import java.math.BigDecimal; | ||
import java.time.LocalDateTime; | ||
import java.util.Set; | ||
import lombok.Data; | ||
|
||
@Data | ||
public class OrderResponseDto { | ||
private Long id; | ||
private Long userId; | ||
private Set<OrderItemResponseDto> orderItems; | ||
private LocalDateTime orderDate; | ||
private BigDecimal total; | ||
private Order.Status status; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.bookstore.dto.order; | ||
|
||
import com.bookstore.model.Order; | ||
import jakarta.validation.constraints.NotNull; | ||
import lombok.Data; | ||
|
||
@Data | ||
public class OrderUpdateDto { | ||
@NotNull | ||
private Order.Status status; | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/com/bookstore/dto/orderitem/OrderItemResponseDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.bookstore.dto.orderitem; | ||
|
||
import lombok.Data; | ||
|
||
@Data | ||
public class OrderItemResponseDto { | ||
private Long id; | ||
private Long bookId; | ||
private int quantity; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.bookstore.mapper; | ||
|
||
import com.bookstore.config.MapperConfig; | ||
import com.bookstore.dto.orderitem.OrderItemResponseDto; | ||
import com.bookstore.model.CartItem; | ||
import com.bookstore.model.OrderItem; | ||
import org.mapstruct.Mapper; | ||
import org.mapstruct.Mapping; | ||
|
||
@Mapper(config = MapperConfig.class) | ||
public interface OrderItemMapper { | ||
@Mapping(target = "bookId", source = "orderItem.book.id") | ||
OrderItemResponseDto toDto(OrderItem orderItem); | ||
|
||
@Mapping(target = "id", ignore = true) | ||
@Mapping(target = "order", ignore = true) | ||
@Mapping(target = "price", source = "cartItem.book.price") | ||
OrderItem cartItemToOrderItem(CartItem cartItem); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.bookstore.mapper; | ||
|
||
import com.bookstore.config.MapperConfig; | ||
import com.bookstore.dto.order.OrderResponseDto; | ||
import com.bookstore.model.Order; | ||
import com.bookstore.model.ShoppingCart; | ||
import java.math.BigDecimal; | ||
import org.mapstruct.AfterMapping; | ||
import org.mapstruct.Mapper; | ||
import org.mapstruct.Mapping; | ||
import org.mapstruct.MappingTarget; | ||
|
||
@Mapper(config = MapperConfig.class, uses = OrderItemMapper.class) | ||
public interface OrderMapper { | ||
@Mapping(target = "orderItems", source = "orderItems") | ||
@Mapping(target = "userId", source = "order.user.id") | ||
OrderResponseDto toDto(Order order); | ||
|
||
@Mapping(target = "id", ignore = true) | ||
@Mapping(target = "total", ignore = true) | ||
@Mapping(target = "status", expression = "java(com.bookstore.model.Order.Status.PENDING)") | ||
@Mapping(target = "orderDate", expression = "java(java.time.LocalDateTime.now())") | ||
Order shoppingCartToOrder(ShoppingCart shoppingCart); | ||
|
||
@AfterMapping | ||
default void setOrderTotal(@MappingTarget Order order, ShoppingCart shoppingCart) { | ||
order.setTotal(getTotal(shoppingCart)); | ||
} | ||
|
||
private BigDecimal getTotal(ShoppingCart shoppingCart) { | ||
return shoppingCart.getCartItems() | ||
.stream() | ||
.map(cartItem -> cartItem.getBook() | ||
.getPrice() | ||
.multiply( | ||
BigDecimal.valueOf(cartItem.getQuantity()) | ||
) | ||
) | ||
.reduce(BigDecimal.ZERO, BigDecimal::add); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package com.bookstore.model; | ||
|
||
import jakarta.persistence.CascadeType; | ||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.EnumType; | ||
import jakarta.persistence.Enumerated; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.JoinColumn; | ||
import jakarta.persistence.ManyToOne; | ||
import jakarta.persistence.OneToMany; | ||
import jakarta.persistence.Table; | ||
import java.math.BigDecimal; | ||
import java.time.LocalDateTime; | ||
import java.util.Set; | ||
import lombok.EqualsAndHashCode; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
import lombok.ToString; | ||
import org.hibernate.annotations.SQLDelete; | ||
import org.hibernate.annotations.Where; | ||
|
||
@Getter | ||
@Setter | ||
@SQLDelete(sql = "UPDATE orders SET is_deleted=true WHERE id=?") | ||
@Where(clause = "is_deleted=false") | ||
@Entity | ||
@EqualsAndHashCode | ||
@Table(name = "orders") | ||
public class Order { | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "user_id", nullable = false) | ||
private User user; | ||
@Enumerated(EnumType.STRING) | ||
@Column(name = "status", nullable = false) | ||
private Status status; | ||
@Column(nullable = false) | ||
private BigDecimal total; | ||
@Column(name = "order_date", nullable = false) | ||
private LocalDateTime orderDate; | ||
@Column(name = "shipping_address", nullable = false) | ||
private String shippingAddress; | ||
@ToString.Exclude | ||
@EqualsAndHashCode.Exclude | ||
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true) | ||
private Set<OrderItem> orderItems; | ||
@Column(name = "is_deleted", nullable = false) | ||
private boolean isDeleted = false; | ||
|
||
public enum Status { | ||
PENDING, | ||
SHIPPABLE, | ||
DELIVERED, | ||
COMPLETED | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package com.bookstore.model; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.JoinColumn; | ||
import jakarta.persistence.ManyToOne; | ||
import jakarta.persistence.Table; | ||
import java.math.BigDecimal; | ||
import lombok.EqualsAndHashCode; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
@Getter | ||
@Setter | ||
@Entity | ||
@EqualsAndHashCode | ||
@Table(name = "order_items") | ||
public class OrderItem { | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "order_id", nullable = false) | ||
private Order order; | ||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "book_id", nullable = false) | ||
private Book book; | ||
@Column(nullable = false) | ||
private int quantity; | ||
@Column(nullable = false) | ||
private BigDecimal price; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
src/main/java/com/bookstore/repository/order/OrderRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.bookstore.repository.order; | ||
|
||
import com.bookstore.model.Order; | ||
import java.util.List; | ||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.data.jpa.repository.EntityGraph; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface OrderRepository extends JpaRepository<Order, Long> { | ||
@EntityGraph(attributePaths = "orderItems") | ||
List<Order> getAllByUserId(Long userId, Pageable pageable); | ||
} |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/bookstore/repository/orderitem/OrderItemRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.bookstore.repository.orderitem; | ||
|
||
import com.bookstore.model.OrderItem; | ||
import java.util.List; | ||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.data.jpa.repository.Query; | ||
|
||
public interface OrderItemRepository extends JpaRepository<OrderItem, Long> { | ||
List<OrderItem> findOrderItemsByOrderId(Long orderId, Pageable pageable); | ||
|
||
@Query(value = "FROM OrderItem oi " | ||
+ "WHERE oi.order.id = :orderId " | ||
+ "AND oi.id = :itemId") | ||
OrderItem findOrderItemByOrderIdAndByItemId(Long orderId, Long itemId); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.bookstore.service; | ||
|
||
import com.bookstore.dto.order.OrderCreateDto; | ||
import com.bookstore.dto.order.OrderResponseDto; | ||
import com.bookstore.dto.order.OrderUpdateDto; | ||
import com.bookstore.dto.orderitem.OrderItemResponseDto; | ||
import java.util.List; | ||
import org.springframework.data.domain.Pageable; | ||
|
||
public interface OrderService { | ||
OrderResponseDto saveOrderFromCart(Long userId, OrderCreateDto orderCreateDto); | ||
|
||
void updateOrderStatus(Long id, OrderUpdateDto orderUpdateDto); | ||
|
||
OrderItemResponseDto getOrderItemWithinAnOrder(Long orderId, Long itemId); | ||
|
||
List<OrderResponseDto> getAllUserOrders(Long userId, Pageable pageable); | ||
|
||
List<OrderItemResponseDto> getAllOrderItemsByOrderId(Long orderId, Pageable pageable); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.