diff --git a/src/main/java/com/springm/store/controller/OrderController.java b/src/main/java/com/springm/store/controller/OrderController.java new file mode 100644 index 0000000..e086c5a --- /dev/null +++ b/src/main/java/com/springm/store/controller/OrderController.java @@ -0,0 +1,87 @@ +package com.springm.store.controller; + +import com.springm.store.dto.order.AddShippingAddressDto; +import com.springm.store.dto.order.OrderResponseDto; +import com.springm.store.dto.order.UpdateOrderStatusDto; +import com.springm.store.dto.order.item.OrderItemDto; +import com.springm.store.service.OrderService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +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; + +@Tag(name = "Order management", description = "Endpoints for managing orders") +@RestController +@RequiredArgsConstructor +@RequestMapping("/orders") +public class OrderController { + private final OrderService orderService; + + @PostMapping + @PreAuthorize("hasAnyRole('USER', 'ADMIN')") + @Operation(summary = "Place an order", description = "Place an order") + public ResponseEntity placeOrder( + @RequestBody AddShippingAddressDto shippingAddress + ) { + return new ResponseEntity( + orderService.placeOrder(shippingAddress), + HttpStatus.CREATED + ); + } + + @GetMapping + @PreAuthorize("hasAnyRole('USER', 'ADMIN')") + @Operation(summary = "Receive orders history", description = "Receive orders history") + public ResponseEntity> getOrderHistory() { + return new ResponseEntity>( + orderService.receiveOrderHistory(), + HttpStatus.OK + ); + } + + @PatchMapping("/{id}") + @PreAuthorize("hasRole('ADMIN')") + @Operation( + summary = "Update order status", + description = "Updates order status with specified ID" + ) + public ResponseEntity updateStatus( + @PathVariable Long id, + @RequestBody UpdateOrderStatusDto orderStatusDto + ) { + return new ResponseEntity( + orderService.updateOrderStatus(id, orderStatusDto), + HttpStatus.NO_CONTENT + ); + } + + @GetMapping("/{orderId}/items") + @PreAuthorize("hasAnyRole('USER', 'ADMIN')") + public ResponseEntity> getOrderItems(@PathVariable Long orderId) { + return new ResponseEntity>( + orderService.getItemsByOrderId(orderId), + HttpStatus.OK + ); + } + + @GetMapping("/{orderId}/items/{id}") + @PreAuthorize("hasAnyRole('USER', 'ADMIN')") + public ResponseEntity getOrderItem(@PathVariable Long orderId, + @PathVariable Long id) { + return new ResponseEntity( + orderService.getItemByOrderIdAndItemId(orderId, id), + HttpStatus.OK + ); + } + +} diff --git a/src/main/java/com/springm/store/dto/cart/item/CartItemDto.java b/src/main/java/com/springm/store/dto/cart/item/CartItemDto.java index 7024619..08c983f 100644 --- a/src/main/java/com/springm/store/dto/cart/item/CartItemDto.java +++ b/src/main/java/com/springm/store/dto/cart/item/CartItemDto.java @@ -1,5 +1,6 @@ package com.springm.store.dto.cart.item; +import java.math.BigDecimal; import lombok.Getter; import lombok.Setter; @@ -10,4 +11,5 @@ public class CartItemDto { private Long bookId; private String bookTitle; private int quantity; + private BigDecimal price; } diff --git a/src/main/java/com/springm/store/dto/order/AddShippingAddressDto.java b/src/main/java/com/springm/store/dto/order/AddShippingAddressDto.java new file mode 100644 index 0000000..44b5302 --- /dev/null +++ b/src/main/java/com/springm/store/dto/order/AddShippingAddressDto.java @@ -0,0 +1,12 @@ +package com.springm.store.dto.order; + +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class AddShippingAddressDto { + @NotBlank + private String shippingAddress; +} diff --git a/src/main/java/com/springm/store/dto/order/OrderResponseDto.java b/src/main/java/com/springm/store/dto/order/OrderResponseDto.java new file mode 100644 index 0000000..a6e7c4b --- /dev/null +++ b/src/main/java/com/springm/store/dto/order/OrderResponseDto.java @@ -0,0 +1,20 @@ +package com.springm.store.dto.order; + +import com.springm.store.dto.order.item.OrderItemDto; +import com.springm.store.model.Order; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class OrderResponseDto { + private Long id; + private Long userId; + private LocalDateTime orderDate; + private BigDecimal total; + private Order.Status orderStatus; + private List orderItems; +} diff --git a/src/main/java/com/springm/store/dto/order/UpdateOrderStatusDto.java b/src/main/java/com/springm/store/dto/order/UpdateOrderStatusDto.java new file mode 100644 index 0000000..cbd5187 --- /dev/null +++ b/src/main/java/com/springm/store/dto/order/UpdateOrderStatusDto.java @@ -0,0 +1,13 @@ +package com.springm.store.dto.order; + +import com.springm.store.model.Order; +import com.springm.store.validation.order.Status; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class UpdateOrderStatusDto { + @Status(enumClass = Order.Status.class) + private Order.Status status; +} diff --git a/src/main/java/com/springm/store/dto/order/item/OrderItemDto.java b/src/main/java/com/springm/store/dto/order/item/OrderItemDto.java new file mode 100644 index 0000000..2d99042 --- /dev/null +++ b/src/main/java/com/springm/store/dto/order/item/OrderItemDto.java @@ -0,0 +1,15 @@ +package com.springm.store.dto.order.item; + +import java.math.BigDecimal; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class OrderItemDto { + private Long id; + private Long bookId; + private String bookTitle; + private int quantity; + private BigDecimal price; +} diff --git a/src/main/java/com/springm/store/mapper/OrderItemMapper.java b/src/main/java/com/springm/store/mapper/OrderItemMapper.java new file mode 100644 index 0000000..2581d20 --- /dev/null +++ b/src/main/java/com/springm/store/mapper/OrderItemMapper.java @@ -0,0 +1,24 @@ +package com.springm.store.mapper; + +import com.springm.store.config.MapperConfig; +import com.springm.store.dto.cart.item.CartItemDto; +import com.springm.store.dto.order.item.OrderItemDto; +import com.springm.store.model.OrderItem; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(config = MapperConfig.class) +public interface OrderItemMapper { + + @Mapping(target = "id", ignore = true) + OrderItemDto toDtoFromCart(CartItemDto cartItemDto); + + @Mapping(source = "bookId", target = "book.id") + @Mapping(source = "bookTitle", target = "book.title") + OrderItem toModel(OrderItemDto orderItemDto); + + @Mapping(source = "book.id", target = "bookId") + @Mapping(source = "book.title", target = "bookTitle") + OrderItemDto toDto(OrderItem orderItem); + +} diff --git a/src/main/java/com/springm/store/mapper/OrderMapper.java b/src/main/java/com/springm/store/mapper/OrderMapper.java new file mode 100644 index 0000000..ee4ccd8 --- /dev/null +++ b/src/main/java/com/springm/store/mapper/OrderMapper.java @@ -0,0 +1,17 @@ +package com.springm.store.mapper; + +import com.springm.store.config.MapperConfig; +import com.springm.store.dto.order.OrderResponseDto; +import com.springm.store.model.Order; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(config = MapperConfig.class, uses = OrderItemMapper.class) +public interface OrderMapper { + @Mapping(source = "id", target = "id") + @Mapping(source = "user.id", target = "userId") + @Mapping(source = "status", target = "orderStatus") + @Mapping(source = "orderItems", target = "orderItems") + OrderResponseDto toResponseDto(Order order); + +} diff --git a/src/main/java/com/springm/store/model/CartItem.java b/src/main/java/com/springm/store/model/CartItem.java index b759002..6c47362 100644 --- a/src/main/java/com/springm/store/model/CartItem.java +++ b/src/main/java/com/springm/store/model/CartItem.java @@ -9,6 +9,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; +import java.math.BigDecimal; import lombok.Getter; import lombok.Setter; @@ -32,4 +33,6 @@ public class CartItem { @Column(nullable = false) private int quantity; + @Column(nullable = false) + private BigDecimal price; } diff --git a/src/main/java/com/springm/store/model/Order.java b/src/main/java/com/springm/store/model/Order.java new file mode 100644 index 0000000..d8089b0 --- /dev/null +++ b/src/main/java/com/springm/store/model/Order.java @@ -0,0 +1,66 @@ +package com.springm.store.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.HashSet; +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.SQLRestriction; + +@Entity +@Table(name = "orders") +@SQLDelete(sql = "UPDATE orders SET is_deleted = true WHERE id=?") +@SQLRestriction("is_deleted = false") +@Getter +@Setter +public class Order { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; + + @Column(nullable = false) + @Enumerated(EnumType.STRING) + private Status status; + + @Column(nullable = false) + private BigDecimal total; + + @Column(nullable = false) + private LocalDateTime orderDate; + + @Column(nullable = false) + private String shippingAddress; + + @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true) + @ToString.Exclude + @EqualsAndHashCode.Exclude + private Set orderItems = new HashSet<>(); + + public enum Status { + ORDER_PLACED, + PENDING, + DELIVERED, + COMPLETED + } +} diff --git a/src/main/java/com/springm/store/model/OrderItem.java b/src/main/java/com/springm/store/model/OrderItem.java new file mode 100644 index 0000000..fe65cea --- /dev/null +++ b/src/main/java/com/springm/store/model/OrderItem.java @@ -0,0 +1,38 @@ +package com.springm.store.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.Getter; +import lombok.Setter; + +@Entity +@Table(name = "order_items") +@Getter +@Setter +public class OrderItem { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(optional = false, fetch = FetchType.LAZY) + @JoinColumn(name = "order_id", nullable = false) + private Order order; + + @ManyToOne(optional = false, fetch = FetchType.LAZY) + @JoinColumn(name = "book_id", nullable = false) + private Book book; + + @Column(nullable = false) + private int quantity; + + @Column(nullable = false) + private BigDecimal price; +} diff --git a/src/main/java/com/springm/store/model/ShoppingCart.java b/src/main/java/com/springm/store/model/ShoppingCart.java index 0ca6339..75aa6cd 100644 --- a/src/main/java/com/springm/store/model/ShoppingCart.java +++ b/src/main/java/com/springm/store/model/ShoppingCart.java @@ -36,4 +36,8 @@ public class ShoppingCart { @Column(nullable = false) private boolean isDeleted = false; + + public void clear() { + cartItems.clear(); + } } diff --git a/src/main/java/com/springm/store/repository/cart/ShoppingCartRepository.java b/src/main/java/com/springm/store/repository/cart/ShoppingCartRepository.java index e905ad5..a0292af 100644 --- a/src/main/java/com/springm/store/repository/cart/ShoppingCartRepository.java +++ b/src/main/java/com/springm/store/repository/cart/ShoppingCartRepository.java @@ -1,10 +1,12 @@ package com.springm.store.repository.cart; import com.springm.store.model.ShoppingCart; +import com.springm.store.model.User; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface ShoppingCartRepository extends JpaRepository { Optional findByUserId(Long userId); + Optional findByUser(User user); } diff --git a/src/main/java/com/springm/store/repository/order/OrderRepository.java b/src/main/java/com/springm/store/repository/order/OrderRepository.java new file mode 100644 index 0000000..528cdf3 --- /dev/null +++ b/src/main/java/com/springm/store/repository/order/OrderRepository.java @@ -0,0 +1,10 @@ +package com.springm.store.repository.order; + +import com.springm.store.model.Order; +import com.springm.store.model.User; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface OrderRepository extends JpaRepository { + List findByUser(User user); +} diff --git a/src/main/java/com/springm/store/repository/order/item/OrderItemRepository.java b/src/main/java/com/springm/store/repository/order/item/OrderItemRepository.java new file mode 100644 index 0000000..90b3cc0 --- /dev/null +++ b/src/main/java/com/springm/store/repository/order/item/OrderItemRepository.java @@ -0,0 +1,13 @@ +package com.springm.store.repository.order.item; + +import com.springm.store.model.OrderItem; +import java.util.List; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface OrderItemRepository extends JpaRepository { + List findByOrderId(Long orderId); + + Optional findByOrderIdAndId(Long orderId, Long id); + +} diff --git a/src/main/java/com/springm/store/service/OrderService.java b/src/main/java/com/springm/store/service/OrderService.java new file mode 100644 index 0000000..27cf42e --- /dev/null +++ b/src/main/java/com/springm/store/service/OrderService.java @@ -0,0 +1,19 @@ +package com.springm.store.service; + +import com.springm.store.dto.order.AddShippingAddressDto; +import com.springm.store.dto.order.OrderResponseDto; +import com.springm.store.dto.order.UpdateOrderStatusDto; +import com.springm.store.dto.order.item.OrderItemDto; +import java.util.List; + +public interface OrderService { + OrderResponseDto placeOrder(AddShippingAddressDto shippingAddressDto); + + List receiveOrderHistory(); + + OrderResponseDto updateOrderStatus(Long orderId, UpdateOrderStatusDto orderStatus); + + List getItemsByOrderId(Long orderId); + + OrderItemDto getItemByOrderIdAndItemId(Long orderId, Long itemId); +} diff --git a/src/main/java/com/springm/store/service/impl/OrderServiceImpl.java b/src/main/java/com/springm/store/service/impl/OrderServiceImpl.java new file mode 100644 index 0000000..ae1aa4d --- /dev/null +++ b/src/main/java/com/springm/store/service/impl/OrderServiceImpl.java @@ -0,0 +1,113 @@ +package com.springm.store.service.impl; + +import com.springm.store.dto.order.AddShippingAddressDto; +import com.springm.store.dto.order.OrderResponseDto; +import com.springm.store.dto.order.UpdateOrderStatusDto; +import com.springm.store.dto.order.item.OrderItemDto; +import com.springm.store.exception.EntityNotFoundException; +import com.springm.store.mapper.CartItemMapper; +import com.springm.store.mapper.OrderItemMapper; +import com.springm.store.mapper.OrderMapper; +import com.springm.store.model.Order; +import com.springm.store.model.OrderItem; +import com.springm.store.model.ShoppingCart; +import com.springm.store.model.User; +import com.springm.store.repository.cart.ShoppingCartRepository; +import com.springm.store.repository.order.OrderRepository; +import com.springm.store.repository.order.item.OrderItemRepository; +import com.springm.store.service.OrderService; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +public class OrderServiceImpl implements OrderService { + private final OrderRepository orderRepository; + private final OrderItemRepository orderItemRepository; + private final ShoppingCartRepository shoppingCartRepository; + private final OrderMapper orderMapper; + private final OrderItemMapper orderItemMapper; + private final CartItemMapper cartItemMapper; + private final UserDetailsServiceImpl userDetailsService; + + @Override + public OrderResponseDto placeOrder(AddShippingAddressDto shippingAddressDto) { + User user = userDetailsService.getCurrentUser(); + ShoppingCart cart = shoppingCartRepository.findByUser(user) + .orElseThrow(() -> new EntityNotFoundException( + user.getUsername() + " cart not found!" + )); + + if (cart.getCartItems().isEmpty()) { + throw new IllegalArgumentException("Order can't be empty!"); + } + + Order order = new Order(); + order.setUser(user); + order.setShippingAddress(shippingAddressDto.getShippingAddress()); + order.setOrderDate(LocalDateTime.now()); + order.setStatus(Order.Status.ORDER_PLACED); + + Set orderItems = cart.getCartItems().stream() + .map(cartItemMapper::toDto) + .map(orderItemMapper::toDtoFromCart) + .map(orderItemMapper::toModel) + .peek(item -> item.setOrder(order)) + .collect(Collectors.toSet()); + order.setOrderItems(orderItems); + + cart.clear(); + shoppingCartRepository.save(cart); + + BigDecimal totalPrice = orderItems.stream() + .map(item -> { + BigDecimal price = item.getPrice() != null ? item.getPrice() : BigDecimal.ZERO; + return price.multiply(BigDecimal.valueOf(item.getQuantity())); + }) + .reduce(BigDecimal.ZERO, BigDecimal::add); + order.setTotal(totalPrice); + orderRepository.save(order); + + return orderMapper.toResponseDto(order); + } + + @Override + public List receiveOrderHistory() { + User user = userDetailsService.getCurrentUser(); + return orderRepository.findByUser(user).stream() + .map(orderMapper::toResponseDto) + .toList(); + } + + @Override + public OrderResponseDto updateOrderStatus(Long orderId, UpdateOrderStatusDto orderStatus) { + Order order = orderRepository.findById(orderId) + .orElseThrow(() -> new EntityNotFoundException( + "Order with id " + orderId + " not found!" + )); + order.setStatus(orderStatus.getStatus()); + return orderMapper.toResponseDto(orderRepository.save(order)); + } + + @Override + public List getItemsByOrderId(Long orderId) { + return orderItemRepository.findByOrderId(orderId) + .stream() + .map(orderItemMapper::toDto) + .toList(); + } + + @Override + public OrderItemDto getItemByOrderIdAndItemId(Long orderId, Long itemId) { + return orderItemRepository.findByOrderIdAndId(orderId, itemId) + .map(orderItemMapper::toDto) + .orElseThrow(() -> new EntityNotFoundException("Item not found")); + } +} diff --git a/src/main/java/com/springm/store/service/impl/ShoppingCartServiceImpl.java b/src/main/java/com/springm/store/service/impl/ShoppingCartServiceImpl.java index e5371d9..7a8feac 100644 --- a/src/main/java/com/springm/store/service/impl/ShoppingCartServiceImpl.java +++ b/src/main/java/com/springm/store/service/impl/ShoppingCartServiceImpl.java @@ -56,6 +56,7 @@ public ShoppingCartResponseDto addItem(AddShoppingCartRequestDto requestDto) { } else { CartItem item = new CartItem(); item.setBook(book); + item.setPrice(book.getPrice()); item.setQuantity(requestDto.getQuantity()); item.setShoppingCart(cart); cart.getCartItems().add(item); diff --git a/src/main/java/com/springm/store/service/impl/UserDetailsServiceImpl.java b/src/main/java/com/springm/store/service/impl/UserDetailsServiceImpl.java index 9a0aa40..da4415e 100644 --- a/src/main/java/com/springm/store/service/impl/UserDetailsServiceImpl.java +++ b/src/main/java/com/springm/store/service/impl/UserDetailsServiceImpl.java @@ -1,5 +1,6 @@ package com.springm.store.service.impl; +import com.springm.store.exception.EntityNotFoundException; import com.springm.store.model.User; import com.springm.store.repository.user.UserRepository; import lombok.RequiredArgsConstructor; @@ -33,4 +34,12 @@ public Long getCurrentUserId() { return user.getId(); } + public User getCurrentUser() { + Long userId = getCurrentUserId(); + return userRepository.findById(userId) + .orElseThrow(() -> new EntityNotFoundException( + "User with id " + userId + " not found!" + )); + } + } diff --git a/src/main/java/com/springm/store/validation/order/Status.java b/src/main/java/com/springm/store/validation/order/Status.java new file mode 100644 index 0000000..a24950a --- /dev/null +++ b/src/main/java/com/springm/store/validation/order/Status.java @@ -0,0 +1,22 @@ +package com.springm.store.validation.order; + +import com.springm.store.validation.user.EmailValidator; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Constraint(validatedBy = EmailValidator.class) +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Status { + Class> enumClass(); + + String message() default "Invalid order status!"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/src/main/java/com/springm/store/validation/order/StatusValidator.java b/src/main/java/com/springm/store/validation/order/StatusValidator.java new file mode 100644 index 0000000..b3d9fe1 --- /dev/null +++ b/src/main/java/com/springm/store/validation/order/StatusValidator.java @@ -0,0 +1,26 @@ +package com.springm.store.validation.order; + +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +public class StatusValidator implements ConstraintValidator { + private Set values; + + @Override + public void initialize(Status constraintAnnotation) { + values = Arrays.stream(constraintAnnotation.enumClass().getEnumConstants()) + .map(Enum::name) + .collect(Collectors.toSet()); + } + + @Override + public boolean isValid(String status, + ConstraintValidatorContext constraintValidatorContext + ) { + return status != null && values.contains(status); + } + +} diff --git a/src/main/resources/db/changelog/changes/09-create-cart-items-table.yaml b/src/main/resources/db/changelog/changes/09-create-cart-items-table.yaml index 84b124f..fc08705 100644 --- a/src/main/resources/db/changelog/changes/09-create-cart-items-table.yaml +++ b/src/main/resources/db/changelog/changes/09-create-cart-items-table.yaml @@ -35,3 +35,8 @@ databaseChangeLog: type: INT constraints: nullable: false + - column: + name: price + type: decimal + constraints: + nullable: false \ No newline at end of file diff --git a/src/main/resources/db/changelog/changes/10-create-orders-table.yaml b/src/main/resources/db/changelog/changes/10-create-orders-table.yaml new file mode 100644 index 0000000..7d3029e --- /dev/null +++ b/src/main/resources/db/changelog/changes/10-create-orders-table.yaml @@ -0,0 +1,48 @@ +databaseChangeLog: + - changeSet: + id: create-orders-table + author: jelors + changes: + - createTable: + tableName: orders + columns: + - column: + name: id + type: bigint + autoIncrement: true + constraints: + primaryKey: true + nullable: false + - column: + name: user_id + type: bigint + constraints: + nullable: false + foreignKeyName: fk_orders_user + references: users(id) + - column: + name: status + type: varchar(255) + constraints: + nullable: false + - column: + name: total + type: decimal + constraints: + nullable: false + - column: + name: order_date + type: TIMESTAMP + constraints: + nullable: false + - column: + name: shipping_address + type: varchar(255) + constraints: + nullable: false + - column: + name: is_deleted + type: bit(1) + defaultValueBoolean: false + constraints: + nullable: false diff --git a/src/main/resources/db/changelog/changes/11-create-order-items-table.yaml b/src/main/resources/db/changelog/changes/11-create-order-items-table.yaml new file mode 100644 index 0000000..936b81e --- /dev/null +++ b/src/main/resources/db/changelog/changes/11-create-order-items-table.yaml @@ -0,0 +1,43 @@ +databaseChangeLog: + - changeSet: + id: create-cart-items-table + author: jelors + changes: + - createTable: + tableName: order_items + columns: + - column: + name: id + type: BIGINT + autoIncrement: true + constraints: + primaryKey: true + nullable: false + + - column: + name: order_id + type: BIGINT + constraints: + nullable: false + foreignKeyName: fk_order_items_order + references: orders(id) + + - column: + name: book_id + type: BIGINT + constraints: + nullable: false + foreignKeyName: fk_order_items_book + references: books(id) + + - column: + name: quantity + type: INT + constraints: + nullable: false + + - column: + name: price + type: decimal + constraints: + nullable: false diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index c409fc7..1a705a2 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -14,6 +14,10 @@ databaseChangeLog: - include: file: db/changelog/changes/07-create-books-categories-table.yaml - include: - file: db/changelog/changes/08-create-shopping-carts-table.yaml + file: db/changelog/changes/08-create-shopping-carts-table.yaml - include: - file: db/changelog/changes/09-create-cart-items-table.yaml \ No newline at end of file + file: db/changelog/changes/09-create-cart-items-table.yaml + - include: + file: db/changelog/changes/10-create-orders-table.yaml + - include: + file: db/changelog/changes/11-create-order-items-table.yaml