Skip to content

Commit

Permalink
Merge pull request #10 from RostyslavOnysh/orderBranch
Browse files Browse the repository at this point in the history
10-Implement-Order-branch
  • Loading branch information
RostyslavOnysh authored Oct 6, 2023
2 parents cb84fa4 + c7179ed commit 8b64f9d
Show file tree
Hide file tree
Showing 29 changed files with 811 additions and 6 deletions.
17 changes: 15 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@
<artifactId>jjwt-jackson</artifactId>
<version>${jjvt.version}</version>
</dependency>
<!-- Log4j -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
Expand All @@ -133,7 +132,21 @@
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.20.0</version>
</dependency>
<!-- Log4j -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package spring.boot.bookstore.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import java.util.List;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.data.domain.Pageable;
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.RestController;
import spring.boot.bookstore.dto.order.OrderRequestDto;
import spring.boot.bookstore.dto.order.OrderResponseDto;
import spring.boot.bookstore.dto.order.OrderUpdateDto;
import spring.boot.bookstore.dto.orderitem.OrderItemResponseDto;
import spring.boot.bookstore.model.Order;
import spring.boot.bookstore.model.User;
import spring.boot.bookstore.service.order.OrderService;

@RequiredArgsConstructor
@RestController
@RequestMapping("/orders")
@Tag(name = "Order Controller management", description = "Endpoints for managing users orders")
public class OrderController {
private static final Logger logger = LogManager.getLogger(OrderController.class);
private final OrderService orderService;

@PostMapping
@Operation(summary = "Place order", description = "place order")
public OrderResponseDto create(Authentication authentication,
@RequestBody
@Valid OrderRequestDto orderRequestDto) {
User user = (User) authentication.getPrincipal();
logger.info("Placing a new Order.");
return orderService.create(user.getId(), orderRequestDto);
}

@Operation(summary = "Get all users order history", description = "Get all users order history")
@GetMapping
public List<OrderResponseDto> findAll(Authentication authentication, Pageable pageable) {
User user = (User) authentication.getPrincipal();
logger.info("Find all Orders.");
return orderService.findAllOrders(user.getId(), pageable);
}

@Operation(summary = "update order", description = "update order status")
@PatchMapping("/{id}")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public OrderResponseDto updateOrderStatus(@PathVariable Long id,
@RequestBody OrderUpdateDto orderUpdateDto) {
logger.info("updating Order Status by id." + id);
return orderService.updateOrderStatus(id, Order.Status
.valueOf(String.valueOf(orderUpdateDto.getStatus())));
}

@Operation(summary = "Find all order Items", description = "Find all order Items")
@GetMapping("/{orderId}/items")
@PreAuthorize("hasRole('USER')")
public Set<OrderItemResponseDto> findAllOrderItems(@PathVariable Long orderId) {
logger.info("find All Order Items using id" + orderId);
return orderService.findAllOrderItems(orderId);
}

@Operation(summary = "Find order item by ID ", description = "Find order item by ID ")
@GetMapping("/{orderId}/items/{itemId}")
@PreAuthorize("hasRole('USER')")
public OrderItemResponseDto findOrderItemById(@PathVariable Long orderId,
@PathVariable Long itemId) {
logger.info("find Order Item By Id" + orderId + "and here Item id : " + itemId);
return orderService.findOrderItemById(orderId, itemId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package spring.boot.bookstore.dto.order;

import lombok.Data;

@Data
public class OrderRequestDto {
private String shippingAddress;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package spring.boot.bookstore.dto.order;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Set;
import lombok.Data;
import spring.boot.bookstore.dto.orderitem.OrderItemResponseDto;

@Data
public class OrderResponseDto {
private Long id;
private Long userId;
private Set<OrderItemResponseDto> orderItems;
private LocalDateTime orderTime;
private BigDecimal totalPrice;
private String status;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package spring.boot.bookstore.dto.order;

import lombok.Data;
import spring.boot.bookstore.model.Order;

@Data
public class OrderUpdateDto {
private Order.Status status;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package spring.boot.bookstore.dto.orderitem;

import lombok.Data;

@Data
public class OrderItemResponseDto {
private Long id;
private Long bookId;
private int quantity;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package spring.boot.bookstore.exception;

public class MessageSenderException extends RuntimeException {
public MessageSenderException(String message, Throwable cause) {
super(message, cause);
}
}
14 changes: 14 additions & 0 deletions src/main/java/spring/boot/bookstore/mapper/OrderItemMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package spring.boot.bookstore.mapper;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import spring.boot.bookstore.config.MapperConfig;
import spring.boot.bookstore.dto.orderitem.OrderItemResponseDto;
import spring.boot.bookstore.model.OrderItem;

@Mapper(config = MapperConfig.class)
public interface OrderItemMapper {
@Mappings({@Mapping(target = "bookId", source = "book.id")})
OrderItemResponseDto toDto(OrderItem orderItem);
}
16 changes: 16 additions & 0 deletions src/main/java/spring/boot/bookstore/mapper/OrderMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package spring.boot.bookstore.mapper;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import spring.boot.bookstore.config.MapperConfig;
import spring.boot.bookstore.dto.order.OrderResponseDto;
import spring.boot.bookstore.model.Order;

@Mapper(config = MapperConfig.class, uses = OrderItemMapper.class)
public interface OrderMapper {
@Mappings({@Mapping(target = "userId", source = "user.id"),
@Mapping(source = "orderDate", target = "orderTime")})
@Mapping(source = "total", target = "totalPrice")
OrderResponseDto toDto(Order order);
}
56 changes: 56 additions & 0 deletions src/main/java/spring/boot/bookstore/model/Order.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package spring.boot.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.Getter;
import lombok.Setter;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;

@Entity
@Getter
@Setter
@SQLDelete(sql = "UPDATE orders SET is_deleted = true WHERE id = ?")
@Where(clause = "is_deleted = false")
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "users_id",nullable = false)
private User user;
@Enumerated(EnumType.STRING)
@Column(name = "status", nullable = false)
private Status status;
@Column(name = "total", nullable = false)
private BigDecimal total;
@Column(name = "order_date",nullable = false)
private LocalDateTime orderDate;
@Column(name = "shipping_address", nullable = false)
private String shippingAddress;
@OneToMany(mappedBy = "order",cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<OrderItem> orderItems;
@Column(name = "is_deleted", nullable = false)
private boolean isDeleted = false;

public enum Status {
COMPLETED,
PENDING,
DELIVERED
}
}
44 changes: 44 additions & 0 deletions src/main/java/spring/boot/bookstore/model/OrderItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package spring.boot.bookstore.model;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
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.Getter;
import lombok.Setter;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;

@Entity
@Getter
@Setter
@SQLDelete(sql = "UPDATE order_items SET is_deleted = true WHERE id = ? ")
@Where(clause = "is_deleted = false")
@Table(name = "order_items")
public class OrderItem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "order_id", nullable = false)
private Order order;
@ManyToOne
@JoinColumn(name = "book_id", nullable = false)
private Book book;
@Column(name = "quantity", nullable = false)
private int quantity;
@Column(name = "price", nullable = false)
private BigDecimal price;
@Column(name = "is_deleted", nullable = false)
private boolean isDeleted = false;
@Enumerated(EnumType.STRING)
@Column(name = "status", nullable = false)
private Order.Status status;
}
3 changes: 2 additions & 1 deletion src/main/java/spring/boot/bookstore/model/ShoppingCart.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
Expand Down Expand Up @@ -33,7 +34,7 @@ public class ShoppingCart {
@OneToOne
@JoinColumn(name = "user_id", nullable = false)
private User user;
@ManyToMany
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "shopping_cart_items",
joinColumns = @JoinColumn(name = "shopping_cart_id"),
inverseJoinColumns = @JoinColumn(name = "cart_items_id"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,4 @@ List<Book> findBookByCategoriesId(@Param("categoryId") Long categoryId,

@Query("FROM Book b INNER JOIN FETCH b.categories")
List<Book> findAllWithCategories(Pageable pageable);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package spring.boot.bookstore.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import spring.boot.bookstore.model.OrderItem;

@Repository
public interface OrderItemRepository extends JpaRepository<OrderItem, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package spring.boot.bookstore.repository;

import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import spring.boot.bookstore.model.Order;

@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
@Query("SELECT o FROM Order o LEFT JOIN FETCH o.orderItems"
+ " LEFT JOIN FETCH o.user u WHERE u.id = :userId")
List<Order> findAllOrders(long userId);

@EntityGraph(attributePaths = "orderItems")
Optional<Order> findById(Long id);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package spring.boot.bookstore.repository.shoppingcart;

import java.util.Optional;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import spring.boot.bookstore.model.ShoppingCart;

@Repository
public interface ShoppingCartRepository extends JpaRepository<ShoppingCart, Long> {
Optional<ShoppingCart> getUserById(Long id);

@EntityGraph(attributePaths = "cartItems")
Optional<ShoppingCart> findById(Long id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package spring.boot.bookstore.service.emailsender;

import spring.boot.bookstore.model.Order;

public interface EmailService {
void sendStatusChangeEmail(String userEmail, Order.Status newStatus);
}
Loading

0 comments on commit 8b64f9d

Please sign in to comment.