diff --git a/src/main/java/dev/example/restaurantManager/controller/MenuController.java b/src/main/java/dev/example/restaurantManager/controller/MenuController.java new file mode 100644 index 0000000..1ef5b56 --- /dev/null +++ b/src/main/java/dev/example/restaurantManager/controller/MenuController.java @@ -0,0 +1,46 @@ +package dev.example.restaurantManager.controller; + +import dev.example.restaurantManager.model.MenuRestaurant; +import dev.example.restaurantManager.model.OrderRestaurant; +import dev.example.restaurantManager.service.MenuService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Date; +import java.util.List; + +@RestController +@RequestMapping("/api/menu") +public class MenuController { + @Autowired + private MenuService menuService; + + + @GetMapping("/allMenus") + public ResponseEntity> getAllMenus( ) { + List menus = menuService.getAllMenus(); + HttpHeaders headers = getCommonHeaders("Get all menus"); + + return menus != null && !menus.isEmpty() + ? new ResponseEntity<>(menus, headers, HttpStatus.OK) + : new ResponseEntity<>(headers, HttpStatus.NOT_FOUND); + } + + private HttpHeaders getCommonHeaders(String description) { + HttpHeaders headers = new HttpHeaders(); + headers.add("desc", description); + headers.add("content-type", "application/json"); + headers.add("date", new Date().toString()); + headers.add("server", "H2 Database"); + headers.add("version", "1.0.0"); + headers.add("menu-count", String.valueOf(menuService.countMenus())); + headers.add("object", "menus"); + return headers; + } + +} diff --git a/src/main/java/dev/example/restaurantManager/controller/OrderController.java b/src/main/java/dev/example/restaurantManager/controller/OrderController.java new file mode 100644 index 0000000..424eacc --- /dev/null +++ b/src/main/java/dev/example/restaurantManager/controller/OrderController.java @@ -0,0 +1,118 @@ +package dev.example.restaurantManager.controller; + +import dev.example.restaurantManager.model.MenuRestaurant; +import dev.example.restaurantManager.model.OrderMenuQty; +import dev.example.restaurantManager.model.OrderRestaurant; +import dev.example.restaurantManager.service.OrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.Date; +import java.util.List; + +@RequestMapping("/api/v1/order") +@RestController +public class OrderController { + + @Autowired + private OrderService orderService; + + // manage request by ResponseEntity with all orders + @GetMapping("/allOrders") + public ResponseEntity> getAllOrders( ) { + List orders = orderService.getAllOrders(); + HttpHeaders headers = getCommonHeaders("Get all orders"); + + return orders != null && !orders.isEmpty() + ? new ResponseEntity<>(orders, headers, HttpStatus.OK) + : new ResponseEntity<>(headers, HttpStatus.NOT_FOUND); + } + + @PostMapping + public ResponseEntity createOrder(@RequestBody OrderRestaurant order) { + OrderRestaurant createdOrder = orderService.createOrder(order); + HttpHeaders headers = getCommonHeaders("Create a new order"); + + return createdOrder != null + ? new ResponseEntity<>(createdOrder, headers, HttpStatus.CREATED) + : new ResponseEntity<>(headers, HttpStatus.BAD_REQUEST); + } + + @PutMapping("/{id}") + public ResponseEntity updateOrder(@PathVariable String id, @RequestBody OrderRestaurant orderDetails) { + OrderRestaurant updatedOrder = orderService.updateOrder(id, orderDetails); + HttpHeaders headers = getCommonHeaders("Update an order"); + + return updatedOrder != null + ? new ResponseEntity<>(updatedOrder, headers, HttpStatus.OK) + : new ResponseEntity<>(headers, HttpStatus.NOT_FOUND); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteOrder(@PathVariable String id) { + boolean deleted = orderService.deleteOrder(id); + HttpHeaders headers = getCommonHeaders("Delete an order"); + headers.add("deleted", String.valueOf(deleted)); + + + return deleted + ? new ResponseEntity<>(headers, HttpStatus.NO_CONTENT) + : new ResponseEntity<>(headers, HttpStatus.NOT_FOUND); + } + + + @PutMapping("/{id}/menus/{menus}") + public ResponseEntity updateOrderAddMenuQty(@PathVariable String id, @RequestBody List menus) { + OrderRestaurant orderUpdated = orderService.addMenus(id,menus); + // OrderRestaurant order = orderService.getOrderById(id); + HttpHeaders headers = getCommonHeaders("Add menu qties to order"); + return orderUpdated != null + ? new ResponseEntity<>(orderUpdated, headers, HttpStatus.OK) + : new ResponseEntity<>(headers, HttpStatus.NOT_FOUND); +// if( orderUpdated==null ){ +// return new ResponseEntity<>(headers, HttpStatus.NOT_FOUND); +// } +// for (MenuRestaurant m : menus) { +// order.addMenu(m); +// } + // OrderRestaurant orderUpdated = orderService.updateOrder(id,order); + + } + + @DeleteMapping("/{id}/menus/{menus}") + public ResponseEntity updateOrderDelMenuQty(@PathVariable String id, @RequestBody List menus) { + OrderRestaurant orderUpdated = orderService.deleteMenus(id,menus); + HttpHeaders headers = getCommonHeaders("Delete menu qties from order"); + return orderUpdated != null + ? new ResponseEntity<>(orderUpdated, headers, HttpStatus.OK) + : new ResponseEntity<>(headers, HttpStatus.NOT_FOUND); + } + + + @GetMapping("/{id}") + public ResponseEntity getOrderById(@PathVariable String id) { + OrderRestaurant order = orderService.getOrderById(id); + HttpHeaders headers = getCommonHeaders("Get an order by Id"); + + return order != null + ? new ResponseEntity<>(order, headers, HttpStatus.OK) + : new ResponseEntity<>(headers, HttpStatus.NOT_FOUND); + } + + private HttpHeaders getCommonHeaders(String description) { + HttpHeaders headers = new HttpHeaders(); + headers.add("desc", description); + headers.add("content-type", "application/json"); + headers.add("date", new Date().toString()); + headers.add("server", "H2 Database"); + headers.add("version", "1.0.0"); + headers.add("order-count", String.valueOf(orderService.countOrders())); + headers.add("object", "orders"); + return headers; + } + + +} diff --git a/src/main/java/dev/example/restaurantManager/controller/PopulateDataController.java b/src/main/java/dev/example/restaurantManager/controller/PopulateDataController.java new file mode 100644 index 0000000..e9b0737 --- /dev/null +++ b/src/main/java/dev/example/restaurantManager/controller/PopulateDataController.java @@ -0,0 +1,24 @@ +package dev.example.restaurantManager.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import dev.example.restaurantManager.utilities.FakeDataLoader; + +@RestController +@RequestMapping("api/v1/populate") +public class PopulateDataController { + + @Autowired + private FakeDataLoader dataLoader; + + @PostMapping("/all") + public ResponseEntity PopulateAllData(){ + dataLoader.createDataAndSave2DBWithoutRelationship(); + String idOrder = dataLoader.createSomeRelations(); + return ResponseEntity.ok("All data populated successfully. Some relationship to order_id="+idOrder); + } + +} diff --git a/src/main/java/dev/example/restaurantManager/model/EatInOrderRestaurant.java b/src/main/java/dev/example/restaurantManager/model/EatInOrderRestaurant.java index 1e2dd12..e39bb04 100644 --- a/src/main/java/dev/example/restaurantManager/model/EatInOrderRestaurant.java +++ b/src/main/java/dev/example/restaurantManager/model/EatInOrderRestaurant.java @@ -1,11 +1,13 @@ package dev.example.restaurantManager.model; import jakarta.persistence.Entity; +import jakarta.persistence.Transient; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.Date; +import java.util.List; import java.util.stream.Collectors; @Data @@ -14,10 +16,18 @@ @Entity public class EatInOrderRestaurant extends OrderRestaurant { + @Transient private ArrayList tableRestaurants = new ArrayList<>(); //private TableRestaurant orderedTableRestaurant; + public EatInOrderRestaurant(String id, Date date, String waiter, int peopleQty, + double totalPayment, boolean paid, List menus, + ArrayList tableRestaurants) { + super(id, date, waiter, peopleQty, totalPayment, paid, menus); + this.tableRestaurants = tableRestaurants; + } + public EatInOrderRestaurant(String id, Date date, String waiter, int peopleQty, double totalPayment, boolean paid, ArrayList menus, ArrayList tableRestaurants) { diff --git a/src/main/java/dev/example/restaurantManager/model/MenuRestaurant.java b/src/main/java/dev/example/restaurantManager/model/MenuRestaurant.java index e916706..18235ba 100644 --- a/src/main/java/dev/example/restaurantManager/model/MenuRestaurant.java +++ b/src/main/java/dev/example/restaurantManager/model/MenuRestaurant.java @@ -1,19 +1,22 @@ package dev.example.restaurantManager.model; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.JsonIgnore; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.Id; -import jakarta.persistence.ManyToMany; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import jakarta.persistence.*; import lombok.*; import java.util.ArrayList; import java.util.List; import java.util.Objects; @Data -@AllArgsConstructor +// @AllArgsConstructor @NoArgsConstructor @Entity +// https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion +@JsonIdentityInfo( + generator = ObjectIdGenerators.PropertyGenerator.class, + property = "id") public class MenuRestaurant { @Id @@ -24,9 +27,20 @@ public class MenuRestaurant { private boolean active; private boolean water; - @JsonIgnore - @ManyToMany(mappedBy = "menus", fetch = FetchType.LAZY) - private List orders = new ArrayList<>(); +// @JsonIgnore +// @ManyToMany(mappedBy = "menus", fetch = FetchType.LAZY) +// private List orders = new ArrayList<>(); + + @OneToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL) + @JoinColumn(name="menu_id") // sin esta anotación se crea la tabla menu_restaurant_menus_qty + private List menusQty; + + + // to execute old tests + public MenuRestaurant(String id, String name, Double price, String content, boolean active, boolean water,ArrayList orders){ + this(id, name, price, content, active, water); + } + public MenuRestaurant(String id, String name, Double price, String content, boolean active, boolean water) { this.id = id; diff --git a/src/main/java/dev/example/restaurantManager/model/OrderMenuQty.java b/src/main/java/dev/example/restaurantManager/model/OrderMenuQty.java new file mode 100644 index 0000000..805529a --- /dev/null +++ b/src/main/java/dev/example/restaurantManager/model/OrderMenuQty.java @@ -0,0 +1,63 @@ +package dev.example.restaurantManager.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.persistence.*; +import lombok.Data; +import org.hibernate.annotations.GenericGenerator; + +import java.util.Objects; + +@Data +@Entity +@Table(name = "ORDER_MENU_QTY") +@IdClass(PK_OrderMenuQty.class) +public class OrderMenuQty { +// @Id +// @GeneratedValue(generator = "UUID") +// @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") +// private String id; + + + @JsonIgnore + @Id + @ManyToOne + @JoinColumn(name="order_id", referencedColumnName="id", nullable = false) + // @JoinColumn(name = "order_id") + private OrderRestaurant order; + + @JsonIgnore + @Id + @ManyToOne + @JoinColumn(name="menu_id", referencedColumnName="id", nullable = false) + // @JoinColumn(name = "menu_id") + private MenuRestaurant menu; + + private int quantity; + + + public PK_OrderMenuQty getId() { + return new PK_OrderMenuQty(order,menu); + } + + public void setId(PK_OrderMenuQty id) { + this.order = id.getOrder(); + this.menu = id.getMenu(); + } + + + @Override + public String toString(){ + return "order_id: " + order.getId() + ", menu_id: " + menu.getId() + ", qty: " + this.quantity; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof OrderMenuQty that)) return false; + // don't check because id it's set in db + // Objects.equals(id, that.id) + return quantity == that.quantity && order.getId().equals(that.order.getId()) && menu.getId().equals(that.menu.getId()); + } + + +} diff --git a/src/main/java/dev/example/restaurantManager/model/OrderRestaurant.java b/src/main/java/dev/example/restaurantManager/model/OrderRestaurant.java index 994b5a4..b1d4d06 100644 --- a/src/main/java/dev/example/restaurantManager/model/OrderRestaurant.java +++ b/src/main/java/dev/example/restaurantManager/model/OrderRestaurant.java @@ -1,12 +1,15 @@ package dev.example.restaurantManager.model; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; +import java.util.*; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import jakarta.persistence.*; import lombok.*; +import dev.example.restaurantManager.utilities.Converter; + @Getter @Setter @AllArgsConstructor @@ -14,6 +17,10 @@ @Entity @Table(name = "ORDER_RESTAURANT") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) +// https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion +@JsonIdentityInfo( + generator = ObjectIdGenerators.PropertyGenerator.class, + property = "id") public class OrderRestaurant { @Id @@ -24,28 +31,124 @@ public class OrderRestaurant { private double totalPayment; private boolean paid; - @JsonIgnore - @ManyToMany(fetch = FetchType.LAZY - , cascade = {CascadeType.PERSIST, CascadeType.MERGE}) - @JoinTable( - name = "ORDER_RESTAURANT_MENU", - joinColumns = @JoinColumn(name = "ORDER_RESTAURANT_FK_ID"), - inverseJoinColumns = @JoinColumn(name = "MENU_RESTAURANT_FK_ID") - ) - private List menus = new ArrayList<>(); - - public List addMenu(MenuRestaurant menu) { - this.menus.add(menu); - menu.getOrders().add(this); - return this.menus; +// @JsonIgnore +// @ManyToMany(fetch = FetchType.EAGER +// , cascade = {CascadeType.PERSIST, CascadeType.MERGE}) +// @JoinTable( +// name = "ORDER_MENU_QUANTITY", +// joinColumns = @JoinColumn(name = "ORDER_ID_FK"), +// inverseJoinColumns = @JoinColumn(name = "MENU_ID_FK") +// ) + @OneToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL) + @JoinColumn(name="order_id") // Sin esta anotación se crea la tabla order_restaurant_menus_qty !!! + private List menusQty; + + public OrderRestaurant(String id, Date date, String waiter, int peopleQty, + double totalPayment, boolean paid, ArrayList menus){ + this.id=id; + this.date=date; + this.waiter=waiter; + this.peopleQty=peopleQty; + this.totalPayment=totalPayment; + this.paid=paid; + this.menusQty = Converter.convertMenus2QtyMenus(this,menus); } - public List removeMenu(MenuRestaurant menu) { - this.menus.remove(menu); - menu.getOrders().remove(this); - return this.menus; + + public List addMenuQty(MenuRestaurant menu, int qty) { + if(this.getMenusQty()==null){ + this.setMenusQty(new ArrayList()); + } + boolean found = false; + for(OrderMenuQty omq: this.getMenusQty()){ + if(omq.getMenu().equals(menu)){ + omq.setQuantity(omq.getQuantity()+qty); + found = true; + break; + } + } + if(!found){ + OrderMenuQty omq = new OrderMenuQty(); + omq.setMenu(menu); + omq.setQuantity(qty); + omq.setOrder(this); + this.getMenusQty().add(omq); + } + return this.getMenusQty(); } + public List addMenu(MenuRestaurant menu) { + if(this.getMenusQty()==null){ + this.setMenusQty(new ArrayList()); + } + boolean found = false; + for(OrderMenuQty omq: this.getMenusQty()){ + if(omq.getMenu().equals(menu)){ + omq.setQuantity(omq.getQuantity()+1); + found = true; + break; + } + } + if(!found){ + OrderMenuQty omq = new OrderMenuQty(); + omq.setMenu(menu); + omq.setQuantity(1); + omq.setOrder(this); + this.getMenusQty().add(omq); + } + return this.getMenusQty(); + } + + public List removeMenuQty(MenuRestaurant menu, int qty) { + if(this.getMenusQty()==null){ + return null; + } + for(OrderMenuQty omq: this.getMenusQty()){ + if(omq.getMenu().equals(menu)){ + int oldQty = omq.getQuantity(); + if (oldQty > qty) { + omq.setQuantity(omq.getQuantity() - qty); + } else{ + this.getMenusQty().remove(omq); + } + break; + } + } + return this.getMenusQty(); + } + + public List removeMenu(MenuRestaurant menu) { + if(this.getMenusQty()==null){ + return null; + } + for(OrderMenuQty omq: this.getMenusQty()){ + if(omq.getMenu().equals(menu)){ + int qty = omq.getQuantity(); + if (qty > 1) { + omq.setQuantity(omq.getQuantity() - 1); + } else{ + this.getMenusQty().remove(omq); + } + break; + } + } + return this.getMenusQty(); + } + + + +// public List addMenu(MenuRestaurant menu) { +// this.menus.add(menu); +// menu.getOrders().add(this); +// return this.menus; +// } +// +// public List removeMenu(MenuRestaurant menu) { +// this.menus.remove(menu); +// menu.getOrders().remove(this); +// return this.menus; +// } + @Override public String toString() { return "OrderRestaurant{" + @@ -55,8 +158,8 @@ public String toString() { ", peopleQty=" + peopleQty + ", totalPayment=" + totalPayment + ", paid=" + paid + - ", menusCount=" + (menus != null ? menus.size() : 0) + - ", menus=" + menus + + ", menusQtyCount=" + (menusQty != null ? menusQty.size() : 0) + + ", menusQty=" + menusQty + '}'; } diff --git a/src/main/java/dev/example/restaurantManager/model/PK_OrderMenuQty.java b/src/main/java/dev/example/restaurantManager/model/PK_OrderMenuQty.java new file mode 100644 index 0000000..7af1772 --- /dev/null +++ b/src/main/java/dev/example/restaurantManager/model/PK_OrderMenuQty.java @@ -0,0 +1,40 @@ +package dev.example.restaurantManager.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; +import java.util.Objects; + +@Getter +@Setter +public class PK_OrderMenuQty implements Serializable { + private OrderRestaurant order; + private MenuRestaurant menu; + + public PK_OrderMenuQty(OrderRestaurant order, MenuRestaurant menu){ + this.order=order; + this.menu=menu; + } + + public PK_OrderMenuQty(){} + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + PK_OrderMenuQty pk = (PK_OrderMenuQty) o; + return order.getId().equals(pk.order.getId()) && + menu.getId().equals(pk.menu.getId()); + } + + @Override + public int hashCode() { + return Objects.hash( order, menu ); + } +} diff --git a/src/main/java/dev/example/restaurantManager/model/ShippingOrderRestaurant.java b/src/main/java/dev/example/restaurantManager/model/ShippingOrderRestaurant.java index 6375dc2..cd63231 100644 --- a/src/main/java/dev/example/restaurantManager/model/ShippingOrderRestaurant.java +++ b/src/main/java/dev/example/restaurantManager/model/ShippingOrderRestaurant.java @@ -1,11 +1,14 @@ package dev.example.restaurantManager.model; +import jakarta.persistence.Entity; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.Date; +import java.util.List; +@Entity @Data @AllArgsConstructor @NoArgsConstructor @@ -15,6 +18,15 @@ public class ShippingOrderRestaurant extends OrderRestaurant { private String city; private String riderName; + public ShippingOrderRestaurant(String id, Date date, String waiter, int peopleQty, + double totalPayment, boolean paid, List menus, + String address, String city, String riderName) { + super(id, date, waiter, peopleQty, totalPayment, paid, menus); + this.address = address; + this.city = city; + this.riderName = riderName; + } + public ShippingOrderRestaurant(String id, Date date, String waiter, int peopleQty, double totalPayment, boolean paid, ArrayList menus, String address, String city, String riderName) { @@ -24,6 +36,7 @@ public ShippingOrderRestaurant(String id, Date date, String waiter, int peopleQt this.riderName = riderName; } + @Override public String toString() { return super.toString() + "\n" + diff --git a/src/main/java/dev/example/restaurantManager/model/TableRestaurant.java b/src/main/java/dev/example/restaurantManager/model/TableRestaurant.java index 2ce3946..41a4757 100644 --- a/src/main/java/dev/example/restaurantManager/model/TableRestaurant.java +++ b/src/main/java/dev/example/restaurantManager/model/TableRestaurant.java @@ -5,6 +5,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.util.ArrayList; +import java.util.List; @Data @AllArgsConstructor @@ -21,10 +22,11 @@ public class TableRestaurant { @OneToMany(mappedBy = "tableRestaurantMapped", cascade = CascadeType.ALL, fetch = FetchType.EAGER) - private ArrayList bookings ; + private List bookings ; // we must create a VERY CONCRETE constructor to RUN the OLD tests public TableRestaurant(String name, String description, int qty, boolean busy) { + this.id = name; this.name = name; this.description = description; this.qty = qty; diff --git a/src/main/java/dev/example/restaurantManager/model/TakeAwayOrder.java b/src/main/java/dev/example/restaurantManager/model/TakeAwayOrder.java index e285789..7385640 100644 --- a/src/main/java/dev/example/restaurantManager/model/TakeAwayOrder.java +++ b/src/main/java/dev/example/restaurantManager/model/TakeAwayOrder.java @@ -6,6 +6,7 @@ import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.Date; +import java.util.List; @Entity @Data @@ -18,6 +19,16 @@ public class TakeAwayOrder extends OrderRestaurant { private Customer customerTakeAway; // Constructor for TakeAwayOrder with the WHOLE DATA fields + public TakeAwayOrder(String id, Date date, String waiter, int peopleQty, + double totalPayment, boolean paid, List menus, + Customer customerTakeAway) { + + // THIS PART is SUPERCLASS + super(id, date, waiter, peopleQty, totalPayment, paid, menus); + // THIS PART is SUBCLASS + this.customerTakeAway = customerTakeAway; + } + public TakeAwayOrder(String id, Date date, String waiter, int peopleQty, double totalPayment, boolean paid, ArrayList menus, Customer customerTakeAway) { diff --git a/src/main/java/dev/example/restaurantManager/repository/OrderMenuQtyRepository.java b/src/main/java/dev/example/restaurantManager/repository/OrderMenuQtyRepository.java new file mode 100644 index 0000000..9b785ce --- /dev/null +++ b/src/main/java/dev/example/restaurantManager/repository/OrderMenuQtyRepository.java @@ -0,0 +1,17 @@ +package dev.example.restaurantManager.repository; + +import dev.example.restaurantManager.model.OrderMenuQty; +import dev.example.restaurantManager.model.PK_OrderMenuQty; +import jakarta.transaction.Transactional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; + +public interface OrderMenuQtyRepository extends JpaRepository { + + @Modifying + @Transactional + @Query("delete from OrderMenuQty omq where omq.id = ?1") + void myDeleteQuery(PK_OrderMenuQty id); + +} diff --git a/src/main/java/dev/example/restaurantManager/repository/ShippingOrderRepository.java b/src/main/java/dev/example/restaurantManager/repository/ShippingOrderRepository.java new file mode 100644 index 0000000..83121f1 --- /dev/null +++ b/src/main/java/dev/example/restaurantManager/repository/ShippingOrderRepository.java @@ -0,0 +1,6 @@ +package dev.example.restaurantManager.repository; + +import dev.example.restaurantManager.model.ShippingOrderRestaurant; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ShippingOrderRepository extends JpaRepository {} diff --git a/src/main/java/dev/example/restaurantManager/service/MenuService.java b/src/main/java/dev/example/restaurantManager/service/MenuService.java new file mode 100644 index 0000000..cb30ea5 --- /dev/null +++ b/src/main/java/dev/example/restaurantManager/service/MenuService.java @@ -0,0 +1,10 @@ +package dev.example.restaurantManager.service; + +import dev.example.restaurantManager.model.MenuRestaurant; + +import java.util.List; + +public interface MenuService { + List getAllMenus(); + long countMenus(); +} diff --git a/src/main/java/dev/example/restaurantManager/service/MenuServiceImpl.java b/src/main/java/dev/example/restaurantManager/service/MenuServiceImpl.java new file mode 100644 index 0000000..33e95b1 --- /dev/null +++ b/src/main/java/dev/example/restaurantManager/service/MenuServiceImpl.java @@ -0,0 +1,25 @@ +package dev.example.restaurantManager.service; + +import dev.example.restaurantManager.model.MenuRestaurant; +import dev.example.restaurantManager.repository.MenuRestaurantRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class MenuServiceImpl implements MenuService{ + @Autowired + MenuRestaurantRepository menuRepository; + + @Override + public List getAllMenus() { + return menuRepository.findAll(); + } + + @Override + public long countMenus() { + return menuRepository.count(); + } + +} diff --git a/src/main/java/dev/example/restaurantManager/service/OrderService.java b/src/main/java/dev/example/restaurantManager/service/OrderService.java new file mode 100644 index 0000000..4be3acc --- /dev/null +++ b/src/main/java/dev/example/restaurantManager/service/OrderService.java @@ -0,0 +1,19 @@ +package dev.example.restaurantManager.service; + +import dev.example.restaurantManager.model.MenuRestaurant; +import dev.example.restaurantManager.model.OrderRestaurant; + +import java.util.List; + +public interface OrderService { + List getAllOrders(); + OrderRestaurant createOrder(OrderRestaurant order); + OrderRestaurant getOrderById(String id); + OrderRestaurant updateOrder(String id, OrderRestaurant orderDetails); + boolean deleteOrder(String id); + long countOrders(); + + + OrderRestaurant addMenus(String idOrder, List menus); + OrderRestaurant deleteMenus(String idOrder, List menus); +} diff --git a/src/main/java/dev/example/restaurantManager/service/OrderServiceImpl.java b/src/main/java/dev/example/restaurantManager/service/OrderServiceImpl.java new file mode 100644 index 0000000..705005e --- /dev/null +++ b/src/main/java/dev/example/restaurantManager/service/OrderServiceImpl.java @@ -0,0 +1,88 @@ +package dev.example.restaurantManager.service; + +import dev.example.restaurantManager.model.MenuRestaurant; +import dev.example.restaurantManager.model.OrderMenuQty; +import dev.example.restaurantManager.model.OrderRestaurant; +import dev.example.restaurantManager.repository.OrderRestaurantRepository; +import dev.example.restaurantManager.utilities.Converter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +import static dev.example.restaurantManager.utilities.Converter.convertMenus2QtyMenus; + +@Service +public class OrderServiceImpl implements OrderService{ + @Autowired + OrderRestaurantRepository orderRepository; + + @Override + public List getAllOrders() { + return orderRepository.findAll(); + } + + @Override + public OrderRestaurant createOrder(OrderRestaurant order) { + return orderRepository.save(order); + } + + @Override + public OrderRestaurant getOrderById(String id) { + return orderRepository.findById(id).orElse(null); + } + + @Override + public OrderRestaurant updateOrder(String id, OrderRestaurant orderDetails) { + // OrderRestaurant order = getOrderById(id); + OrderRestaurant order = orderRepository.getReferenceById(id); + + return orderRepository.save(orderDetails); + } + + @Override + public boolean deleteOrder(String id) { + boolean find = getOrderById(id) != null; + orderRepository.deleteById(id); + return find; + } + + @Override + public long countOrders() { + return orderRepository.count(); + } + + @Override + public OrderRestaurant addMenus(String idOrder, List menus){ + // OrderRestaurant order = orderRepository.findById(idOrder).orElse(null); + OrderRestaurant order = orderRepository.getReferenceById(idOrder); + if( order==null ){ + return null; + } +// for (MenuRestaurant m : menus) { +// order.addMenu(m); +// } + List menusQt = Converter.convertMenus2QtyMenus(order,menus); + for(OrderMenuQty omq:menusQt){ + order.addMenuQty(omq.getMenu(),omq.getQuantity()); + } + return orderRepository.save(order); + } + + @Override + public OrderRestaurant deleteMenus(String idOrder, List menus){ + // OrderRestaurant order = orderRepository.findById(idOrder).orElse(null); + OrderRestaurant order = orderRepository.getReferenceById(idOrder); + if( order==null ){ + return null; + } +// for (MenuRestaurant m : menus) { +// order.removeMenu(m); +// } + List menusQt = Converter.convertMenus2QtyMenus(order,menus); + for(OrderMenuQty omq:menusQt){ + order.removeMenuQty(omq.getMenu(),omq.getQuantity()); + } + return orderRepository.save(order); + } +} diff --git a/src/main/java/dev/example/restaurantManager/utilities/Converter.java b/src/main/java/dev/example/restaurantManager/utilities/Converter.java new file mode 100644 index 0000000..4f7423d --- /dev/null +++ b/src/main/java/dev/example/restaurantManager/utilities/Converter.java @@ -0,0 +1,38 @@ +package dev.example.restaurantManager.utilities; + +import dev.example.restaurantManager.model.MenuRestaurant; +import dev.example.restaurantManager.model.OrderMenuQty; +import dev.example.restaurantManager.model.OrderRestaurant; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Converter { + public static List convertMenus2QtyMenus(OrderRestaurant order, List menus){ + HashMap hashmapMenus = new HashMap<>(); + for(MenuRestaurant m:menus){ + hashmapMenus.put(m,hashmapMenus.getOrDefault(m,0) + 1); + } + List menusNew = new ArrayList<>(); + for(Map.Entry m:hashmapMenus.entrySet()){ + OrderMenuQty omq = new OrderMenuQty(); + omq.setMenu(m.getKey()); + omq.setQuantity(m.getValue()); + omq.setOrder(order); + menusNew.add(omq); + } + return menusNew; + } + + public static List convertQtyMenus2Menus(List menus){ + List menusNew = new ArrayList<>(); + for(OrderMenuQty omq:menus){ + for(int i=0;i menus; + private List orders; + + private Faker faker; + + public List getMenus(){ + return menus; + } + + public List getOrders(){ + return orders; + } + + public Faker getFaker(){ + return faker; + } + + + private void createFakerIfNotExists(){ + if(faker!=null){ + return; + } + + // create always same data + faker = new Faker(new Random(42)); + } + + public void deleteAllData(){ + System.out.println("Delete all data"); + // delete all data + customerRepository.deleteAll(); + tableRepository.deleteAll(); + orderMenuQtyRepository.deleteAll(); + menuRepository.deleteAll(); + shippingOrderRepository.deleteAll(); + } + + public void createDataAndSave2DBWithoutRelationship(){ + createFakerIfNotExists(); + + System.out.println("Before creating data"); + + System.out.println("Before creating Customers"); + // Create sample customers + Customer customer1 = new Customer("C1", "John", "john@email.com", "123-456-7890", 30, false, false); + Customer customer3 = new Customer("C3", "Emily", "emily@email.com", "345-678-9012", 35, false, false); + Customer customer5 = new Customer("C5", "Anna", "anna@email.com", "567-890-1234", 28, false, false); + customerRepository.save(customer1); + customerRepository.save(customer3); + customerRepository.save(customer5); + System.out.println("after creating Customers"); + + // Create sample tables + System.out.println("before creating Tables"); + TableRestaurant table1 = new TableRestaurant("T1", "Window Table", 4, false); + TableRestaurant table2 = new TableRestaurant("T2", "Corner Table", 2, true); + table1.setId("T01"); + table2.setId("T02"); + tableRepository.save(table1); + tableRepository.save(table2); + System.out.println("after creating Tables"); + + + // Create sample menus + System.out.println("before creating Menus"); + MenuRestaurant menu1 = new MenuRestaurant("M01", "Burger Menu", 10.99, "Burger, fries, and drink", true, true); + MenuRestaurant menu2 = new MenuRestaurant("M02","Pizza Menu", 12.99, "Pizza and salad", true, false); + MenuRestaurant menu3 = new MenuRestaurant("M03","Salad Menu", 8.99, "Mixed salad and dressing", true, true); + menus = new ArrayList<>(Arrays.asList(menu1,menu2,menu3)); + menuRepository.save(menu1); + menuRepository.save(menu2); + menuRepository.save(menu3); + System.out.println("after creating Menus"); + + // Create 3 ShippingOrder objects + System.out.println("before creating ShippingOrderRestaurants"); + ShippingOrderRestaurant so1 = new ShippingOrderRestaurant("SO1", new Date(), "John", 2, 0.0, false, (List)null, "123 Main St", "New York", "Mike"); + ShippingOrderRestaurant so2 = new ShippingOrderRestaurant("SO2", new Date(), "Sarah", 1, 0.0, true, (List)null, "456 Elm St", "Los Angeles", "Tom"); + ShippingOrderRestaurant so3 = new ShippingOrderRestaurant("SO3", new Date(), "Emily", 3, 0.0, false, (List)null, "789 Oak St", "Chicago", "Lisa"); + orders = new ArrayList<>(Arrays.asList(so1,so2,so3)); + shippingOrderRepository.save(so1); + shippingOrderRepository.save(so2); + shippingOrderRepository.save(so3); + System.out.println("after creating ShippingOrderRestaurants"); + + System.out.println("after creating data"); + } + + public List getRandomMenuQty(OrderRestaurant orderRestaurant){ + List menusQty = new ArrayList<>(); + for(MenuRestaurant m:menus){ + if (faker.random().nextInt(0,3) == 0){ + continue; + } + OrderMenuQty omq = new OrderMenuQty(); + omq.setOrder(orderRestaurant); + omq.setMenu(m); + omq.setQuantity(faker.random().nextInt(1,5)); + menusQty.add(omq); + } + return menusQty; + } + + public String createSomeRelations(){ + ShippingOrderRestaurant so = shippingOrderRepository.findAll().getFirst(); + String idOrder = so.getId(); + List menusQty = new ArrayList<>(); + for(MenuRestaurant m:menuRepository.findAll()){ + if (faker.random().nextInt(0,3) == 0){ + continue; + } + OrderMenuQty omq = new OrderMenuQty(); + omq.setOrder(so); + omq.setMenu(m); + omq.setQuantity(faker.random().nextInt(1,5)); + menusQty.add(omq); + } + System.out.println("before saving relationship ShippingOrderRestaurant <-> OrderMenusQqy"); + so.setMenusQty(menusQty); + shippingOrderRepository.save(so); + System.out.println("after saving relationship ShippingOrderRestaurant <-> OrderMenusQqy"); + +// ShippingOrderRestaurant so1DB = shippingOrderRepository.findById(idOrder).orElse(null); +// System.out.println(menusQty.size() + "=" + so1DB.getMenusQty().size() ); + + return idOrder; + } + + + public void createSomeRelationsOld(){ + ShippingOrderRestaurant so1 = (ShippingOrderRestaurant) orders.get(0); + List menusQty = getRandomMenuQty(so1); + so1.setMenusQty(menusQty); + System.out.println("before saving relationship ShippingOrderRestaurant <-> OrderMenusQqy"); +// shippingOrderRepository.save(so1); +// System.out.println("after saving relationship ShippingOrderRestaurant <-> OrderMenusQqy"); +// +// +// System.out.println("check saving relationship ShippingOrderRestaurant <-> OrderMenusQqy"); + ShippingOrderRestaurant so1DB = shippingOrderRepository.findById(so1.getId()).orElse(null); + System.out.println(menusQty.size() + "=" + so1DB.getMenusQty().size() ); + } + + +} diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index b773357..cb441a4 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -1,13 +1,20 @@ +# H2 LOCAL DB SERVER +spring.datasource.url=jdbc:h2:/home/jc/Documents/restaurant-db/db +spring.datasource.username=jc +spring.datasource.password= +# https://stackoverflow.com/questions/61189480/spring-boot-jackson-responseentity-no-serializer-found-for-class +# TO AVOID THIS ERROR: +# com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor .... +spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false +# see sql in console +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=true -# H2 LOCAL DB SERVER -spring.datasource.url=jdbc:h2:/home/albert/MyProjects/DataBase/customerdb -spring.datasource.username=albert -spring.datasource.password=1234 # DDL OPTIONS: create-drop, create, update, none, validate -spring.jpa.hibernate.ddl-auto=update +spring.jpa.hibernate.ddl-auto=create # create ? Hibernate first drops existing tables and then creates new tables. # update ? The object model created based on the mappings # (annotations or XML) is compared with the existing schema, diff --git a/src/main/resources/application-memory.properties b/src/main/resources/application-memory.properties index dd79a7c..12d89f6 100644 --- a/src/main/resources/application-memory.properties +++ b/src/main/resources/application-memory.properties @@ -13,4 +13,7 @@ spring.jpa.hibernate.ddl-auto=create-drop # create-drop ? similar to create, with the addition that # Hibernate will drop the database after all operations are completed; # typically used for unit testing -#https://albertprofe.dev/springboot/sblab0-5.html#ddl \ No newline at end of file +#https://albertprofe.dev/springboot/sblab0-5.html#ddl + +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=true \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 56fa3b7..cfb2150 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,7 +1,7 @@ spring.application.name=restaurantManager # application.properties -spring.profiles.active=memory +spring.profiles.active=local diff --git a/src/test/java/dev/example/restaurantManager/OrderMenuQtyTest.java b/src/test/java/dev/example/restaurantManager/OrderMenuQtyTest.java new file mode 100644 index 0000000..33687a3 --- /dev/null +++ b/src/test/java/dev/example/restaurantManager/OrderMenuQtyTest.java @@ -0,0 +1,413 @@ +package dev.example.restaurantManager; + +import dev.example.restaurantManager.model.*; +import dev.example.restaurantManager.repository.*; +import dev.example.restaurantManager.service.OrderService; +import dev.example.restaurantManager.utilities.FakeDataLoader; +import jakarta.persistence.EntityManager; +import jakarta.transaction.Transactional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.*; + +import static org.assertj.core.api.Assertions.assertThat; + + +@SpringBootTest +public class OrderMenuQtyTest { + + @Autowired + EntityManager entityManager; + @Autowired + ShippingOrderRepository shippingOrderRepository; + @Autowired + OrderRestaurantRepository orderRepository; + @Autowired + MenuRestaurantRepository menuRepository; + @Autowired + OrderMenuQtyRepository orderMenuQtyRepository; + @Autowired + OrderService orderService; + + +// List menus; +// List orders; + + @Autowired + FakeDataLoader dataLoader; + + @BeforeEach + public void createDataAndSave2DBWithoutRelationship() { + dataLoader.deleteAllData(); + dataLoader.createDataAndSave2DBWithoutRelationship(); +// menus = dataLoader.getMenus(); +// orders = dataLoader.getOrders(); + } + + public List getRandomMenuQty(OrderRestaurant orderRestaurant){ + List menusQty = new ArrayList<>(); + for(MenuRestaurant m:menuRepository.findAll()){ + if (dataLoader.getFaker().random().nextInt(0,3) == 0){ + continue; + } + OrderMenuQty omq = new OrderMenuQty(); + omq.setOrder(orderRestaurant); + omq.setMenu(m); + omq.setQuantity(dataLoader.getFaker().random().nextInt(1,5)); + menusQty.add(omq); + } + return menusQty; + } + + @Test + // https://stackoverflow.com/questions/11746499/how-to-solve-the-failed-to-lazily-initialize-a-collection-of-role-hibernate-ex + @Transactional // (propagation= Propagation.REQUIRED) + public void createOrderMenuQtyDB() { + List orders = shippingOrderRepository.findAll(); + ShippingOrderRestaurant so1 = orders.get(0); + List menusQty = getRandomMenuQty(so1); + so1.setMenusQty(menusQty); + // save relationship to DB + shippingOrderRepository.save(so1); + + // check if shipping order is in DB + Optional found = shippingOrderRepository.findById(so1.getId()); + assertThat(found).isPresent(); + ShippingOrderRestaurant so1DB = found.get(); + + // check if shipping order has all his menus saved to DB + // this method must be @Transactional because + // menus in order are fetch.LAZY + int nMenus = so1DB.getMenusQty().size(); + for(int i=0;i orders = shippingOrderRepository.findAll(); + ShippingOrderRestaurant so1 = orders.get(1); + List menusQty = getRandomMenuQty(so1); + int nMenus = 0; + int totalQtyMenus = 0; + // every menu qty will be greater than 1 + for(OrderMenuQty q:menusQty){ + if(q.getQuantity()<2){ + q.setQuantity(dataLoader.getFaker().random().nextInt(2,8)); + } + totalQtyMenus += q.getQuantity(); + nMenus += 1; + } + so1.setMenusQty(menusQty); + System.out.println("total menus: " + nMenus); + System.out.println("total qty menus: " + totalQtyMenus); + shippingOrderRepository.save(so1); + + Optional found = shippingOrderRepository.findById(so1.getId()); + assertThat(found).isPresent(); + assertThat(found.get().getId()).isEqualTo(so1.getId()); + assertThat(found.get().getMenusQty().stream() + .count() + ).isEqualTo(nMenus); + assertThat(found.get().getMenusQty().stream() + .mapToInt(omq -> omq.getQuantity()) + .sum() + ).isEqualTo(totalQtyMenus); + + + } + + @Test + @Transactional + public void checkOrderMenuQtyRepository() { + // no relationship is on DB + assertThat(orderMenuQtyRepository.findAll().size()).isEqualTo(0); + + List orders = shippingOrderRepository.findAll(); + ShippingOrderRestaurant so1 = orders.get(2); + List menusQty = getRandomMenuQty(so1); + so1.setMenusQty(menusQty); + // save some relationships + shippingOrderRepository.save(so1); + + + // check relationships are the same that we assign + assertThat(orderMenuQtyRepository.findAll()).containsAll(menusQty); + + } + + @Test + @Transactional + public void checkOrderMenuQtyRepository2() { + // no relationship is on DB + int totalRelationships = 0; + assertThat(orderMenuQtyRepository.findAll().size()).isEqualTo(totalRelationships); + + List orders = shippingOrderRepository.findAll(); + ShippingOrderRestaurant so0 = orders.get(0); + List menusQty0 = getRandomMenuQty(so0); + so0.setMenusQty(menusQty0); + // save some relationships + shippingOrderRepository.save(so0); + totalRelationships += menusQty0.size(); + assertThat(orderMenuQtyRepository.findAll().size()).isEqualTo(totalRelationships); + + + ShippingOrderRestaurant so1 = orders.get(1); + List menusQty1 = new ArrayList<>(); + for(OrderMenuQty omq:menusQty0){ + OrderMenuQty omqNew = new OrderMenuQty(); + omqNew.setOrder(so1); + omqNew.setMenu(omq.getMenu()); + omqNew.setQuantity(omq.getQuantity()); + menusQty1.add(omqNew); + } + so1.setMenusQty(menusQty1); + shippingOrderRepository.save(so1); + totalRelationships += menusQty1.size(); + assertThat(orderMenuQtyRepository.findAll().size()).isEqualTo(totalRelationships); + + ShippingOrderRestaurant so2 = orders.get(2); + List menusQty2 = getRandomMenuQty(so2); + so2.setMenusQty(menusQty2); + shippingOrderRepository.save(so2); + totalRelationships += menusQty2.size(); + assertThat(orderMenuQtyRepository.findAll().size()).isEqualTo(totalRelationships); + } + + @Test + @Transactional + public void createOrderAndDeleteSomeQtyMenus() { + List orders = shippingOrderRepository.findAll(); + ShippingOrderRestaurant so1 = orders.get(0); + List menusQty = getRandomMenuQty(so1); + so1.setMenusQty(menusQty); + int nMenusOriginal = menusQty.size(); + // save some order with some menus + shippingOrderRepository.save(so1); + + + // get order from DB + Optional found = shippingOrderRepository.findById(so1.getId()); + assertThat(found).isPresent(); + // check order from DB is the same as in memory + assertThat(found.get().getId()).isEqualTo(so1.getId()); + ShippingOrderRestaurant soDB = found.get(); + // print menu qty from order + List menus = soDB.getMenusQty(); + int nMenus1 = menus.size(); + System.out.println(menus); + + // delete first menu qty from order and save to DB using + // method removeMenuQty from OrderRestaurant + // and save to DB + // String id = menus.get(0).getId(); + OrderMenuQty omq = menus.get(0); + so1.removeMenuQty(omq.getMenu(),omq.getQuantity()); + shippingOrderRepository.save(so1); + + // load the order from DB + // now should have 1 menu qty less + found = shippingOrderRepository.findById(so1.getId()); + ShippingOrderRestaurant soDB2 = found.get(); + List menus2 = soDB2.getMenusQty(); + int nMenus2 = menus2.size(); + System.out.println(menus2); + List menus3 = orderMenuQtyRepository.findAll(); + assertThat(nMenusOriginal).isEqualTo(nMenus1); + assertThat(nMenusOriginal-1).isEqualTo(nMenus2); + + } + + @Test + @Transactional + public void findByIdInMenuQtyRepository(){ + // get last order + ShippingOrderRestaurant so = shippingOrderRepository.findAll().getLast(); + // get some random QtyMenu + List menusQty = getRandomMenuQty(so); + so.setMenusQty(menusQty); + // save relationships + shippingOrderRepository.save(so); + // print all orders relationships + shippingOrderRepository.findAll().forEach( or -> System.out.println(or.getId() + ": " + or.getMenusQty() )); + + // find from DB first menusQty + OrderMenuQty omqMemory = menusQty.get(0); + Optional foundOmq = orderMenuQtyRepository.findById(omqMemory.getId()); + assertThat(foundOmq).isPresent(); + OrderMenuQty omqDB = foundOmq.get(); + assertThat(omqMemory).isEqualTo(omqDB); + } + + @Test + @Transactional + public void deleteQtyMenusWithOrderRepository() { + System.out.println("TEST deleteQtyMenusWithOrderRepository BEGIN"); + // check no relationship is stored on DB + assertThat(orderMenuQtyRepository.findAll().size()).isEqualTo(0); + + + // get first order + List orders = shippingOrderRepository.findAll(); + ShippingOrderRestaurant so = orders.get(0); + // get some random QtyMenu + List menusQty = getRandomMenuQty(so); + so.setMenusQty(menusQty); + int nMenusOriginal = menusQty.size(); + System.out.println("Printing " + nMenusOriginal + " menu qty from memory"); + menusQty.forEach(System.out::println); + // save relationship of order with some qty menus + orderRepository.save(so); + System.out.println("After shippingOrderRepository.save"); + + // removing one OrderMenuQty with shippingOrderRepository + OrderMenuQty omq = menusQty.get(0); + so.removeMenuQty(omq.getMenu(),omq.getQuantity()); + orderRepository.save(so); + // get order from db to check if OrderMenuQty is removed + Optional found1 = shippingOrderRepository.findById(so.getId()); + assertThat(found1).isPresent(); + assertThat(found1.get().getMenusQty().size()).isEqualTo(nMenusOriginal-1); + // insert back OrderMenuQty + so.addMenuQty(omq.getMenu(),omq.getQuantity()); + orderRepository.save(so); + // and check if OrderMenuQty is added + found1 = shippingOrderRepository.findById(so.getId()); + assertThat(found1).isPresent(); + assertThat(found1.get().getMenusQty().size()).isEqualTo(nMenusOriginal); + + System.out.println("TEST deleteQtyMenusWithOrderRepository END"); + } + + + + + @Test + @Transactional + public void orderRepositoryAndShippingRepository() { + System.out.println("TEST orderRepositoryAndShippingRepository BEGIN"); + System.out.println(shippingOrderRepository.findAll()); + String id = shippingOrderRepository.findAll().get(1).getId(); + System.out.println("id from db=" + id); + String shippingOrderId = "SO2"; + System.out.println("id from db=" + shippingOrderId); + assertThat(id).isEqualTo(shippingOrderId); + Optional optionalSO = shippingOrderRepository.findById(shippingOrderId); + assertThat(optionalSO).isPresent(); + ShippingOrderRestaurant so = optionalSO.get(); + + Optional optionalOR = orderRepository.findById(shippingOrderId); + assertThat(optionalOR).isPresent(); + ShippingOrderRestaurant so2 = (ShippingOrderRestaurant)optionalOR.get(); + assertThat(so).isEqualTo(so2); + System.out.println("TEST orderRepositoryAndShippingRepository END"); + } + + @Test + @Transactional + public void orderServiceAddMenus(){ + System.out.println("TEST orderServiceAddMenus BEGIN"); + // store in memory menus + List menusToAdd = new ArrayList<>(); + HashMap menusNumber = new HashMap<>(); + for(MenuRestaurant m:menuRepository.findAll()){ + int n = dataLoader.getFaker().random().nextInt(2,5); + for(int i=0;i menusQty = getRandomMenuQty(so); + so.setMenusQty(menusQty); + // save relationship of order with some qty menus + shippingOrderRepository.save(so); + int nMenusOriginal = menusQty.size(); + System.out.println("Printing " + nMenusOriginal + " menu qty from memory"); + menusQty.forEach(System.out::println); + + // prepare list of menus to delete + List menusToDelete = new ArrayList<>(); + for(OrderMenuQty omq: so.getMenusQty()){ + for(int i=0;i menusQty = getRandomMenuQty(so); + so.setMenusQty(menusQty); + // save relationships + shippingOrderRepository.save(so); + // print all orders relationships + shippingOrderRepository.findAll().forEach( or -> System.out.println(or.getId() + ": " + or.getMenusQty() )); + + long nOrderMenuQty = menusQty.size(); + System.out.println("total OrderMenuQty: " + nOrderMenuQty); + // find from DB first menusQty + OrderMenuQty omqToDelete = orderMenuQtyRepository.findById(menusQty.get(0).getId()).orElseThrow(); + System.out.println("OrderMenuQty to delete: " + omqToDelete); + System.out.println("Before trying to delete"); + // trying with id -> NOT WORKING + orderMenuQtyRepository.deleteById(omqToDelete.getId()); + // trying with object -> NOT WORKING + orderMenuQtyRepository.delete(omqToDelete); + // flush to DB + orderMenuQtyRepository.flush(); + entityManager.flush(); + entityManager.clear(); + System.out.println("After trying to delete + entityManager.flush(); entityManager.clear();"); + + Optional found = orderMenuQtyRepository.findById(omqToDelete.getId()); + assertThat(found).isNotPresent(); // Fails -> object wasn't deleted + assertThat(orderMenuQtyRepository.count()).isEqualTo(nOrderMenuQty-1); + System.out.println("TEST deleteByIdInMenuQtyRepository END"); + } +} diff --git a/src/test/java/dev/example/restaurantManager/RelationshipsOrderRestaurantTest.java b/src/test/java/dev/example/restaurantManager/RelationshipsOrderRestaurantTest.java index 35e2078..72e21e8 100644 --- a/src/test/java/dev/example/restaurantManager/RelationshipsOrderRestaurantTest.java +++ b/src/test/java/dev/example/restaurantManager/RelationshipsOrderRestaurantTest.java @@ -2,6 +2,7 @@ import dev.example.restaurantManager.model.*; import dev.example.restaurantManager.repository.*; +import dev.example.restaurantManager.utilities.Converter; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; @@ -138,7 +139,7 @@ public void TestCreateOrderMenu () { System.out.println(found.get()); // then assertThat(found).isPresent(); - assertThat(found.get().getMenus().get(0).getName().equals(menuRestaurant1.getName())); + // assertThat(found.get().getMenus().get(0).getName().equals(menuRestaurant1.getName())); } // java.lang.StackOverflowError toString @@ -169,8 +170,8 @@ public void TestCreateOrderMenu_stackOverflow () { //orderRestaurantRepository.save(orderRestaurant3); // set menus to orders and save - menuRestaurant1.getOrders().add(orderRestaurant1); - menuRestaurantRepository.save(menuRestaurant1); +// menuRestaurant1.getOrders().add(orderRestaurant1); +// menuRestaurantRepository.save(menuRestaurant1); // when Optional found = orderRestaurantRepository.findById("O01"); @@ -187,7 +188,7 @@ public void TestCreateOrderMenu_stackOverflow () { // then assertThat(found).isPresent(); - assertThat(found.get().getMenus().get(0).getName().equals(menuRestaurant1.getName())); +// assertThat(found.get().getMenus().get(0).getName().equals(menuRestaurant1.getName())); } // Adding Menus to an Order: Verifies that menus can be added to an order @@ -205,7 +206,7 @@ public void testAddingMenusToOrder() { // Create an order and add menus OrderRestaurant order = new OrderRestaurant("O01", new Date(), "John", 4, - 43.96, true, new ArrayList<>()); + 43.96, true, (List)null); order.addMenu(menuRestaurant1); order.addMenu(menuRestaurant2); order.addMenu(menuRestaurant3); @@ -214,17 +215,23 @@ public void testAddingMenusToOrder() { // Retrieve the order and assert the menus Optional foundOrder = orderRestaurantRepository.findById("O01"); assertThat(foundOrder).isPresent(); - assertThat(foundOrder.get().getMenus()).hasSize(3); + assertThat(foundOrder.get().getMenusQty()).hasSize(3); // Since we've implemented equals() and hashCode() methods based on // the compilation of all fields except for orders. // This avoids potential circular reference issues while still providing a comprehensive comparison of the menu items. + + // we can now use contains() to check if the retrieved menus match the original ones - assertThat(foundOrder.get().getMenus()).contains(menuRestaurant1, menuRestaurant2, menuRestaurant3); +// assertThat(foundOrder.get().getMenus()).contains(menuRestaurant1, menuRestaurant2, menuRestaurant3); + assertThat(Converter.convertQtyMenus2Menus(foundOrder.get().getMenusQty())).contains(menuRestaurant1, menuRestaurant2, menuRestaurant3); + + + // Retrieve the menus and assert the order - assertThat(foundOrder.get().getMenus()) + assertThat(Converter.convertQtyMenus2Menus(foundOrder.get().getMenusQty())) .extracting("id") .containsExactlyInAnyOrder("M01", "M02", "M03"); - assertThat(foundOrder.get().getMenus()) + assertThat(Converter.convertQtyMenus2Menus(foundOrder.get().getMenusQty())) .usingElementComparator(Comparator.comparing(MenuRestaurant::getId)) .containsExactlyInAnyOrder(menuRestaurant1, menuRestaurant2, menuRestaurant3); } @@ -243,7 +250,7 @@ public void testAddingRepeatedMenusToOrder() { // Create an order and add menus OrderRestaurant order = new OrderRestaurant("O01", new Date(), "John", 4, - 43.96, true, new ArrayList<>()); + 43.96, true, (List)null); order.addMenu(menuRestaurant1); order.addMenu(menuRestaurant2); order.addMenu(menuRestaurant2); @@ -255,17 +262,17 @@ public void testAddingRepeatedMenusToOrder() { // Retrieve the order and assert the menus Optional foundOrder = orderRestaurantRepository.findById("O01"); assertThat(foundOrder).isPresent(); - assertThat(foundOrder.get().getMenus()).hasSize(6); + assertThat(foundOrder.get().getMenusQty()).hasSize(3); // Since we've implemented equals() and hashCode() methods based on // the compilation of all fields except for orders. // This avoids potential circular reference issues while still providing a comprehensive comparison of the menu items. // we can now use contains() to check if the retrieved menus match the original ones - assertThat(foundOrder.get().getMenus()).contains(menuRestaurant1, menuRestaurant2, menuRestaurant2, menuRestaurant3, menuRestaurant3, menuRestaurant3); + assertThat(Converter.convertQtyMenus2Menus(foundOrder.get().getMenusQty())).contains(menuRestaurant1, menuRestaurant2, menuRestaurant2, menuRestaurant3, menuRestaurant3, menuRestaurant3); // Retrieve the menus and assert the order - assertThat(foundOrder.get().getMenus()) + assertThat(Converter.convertQtyMenus2Menus(foundOrder.get().getMenusQty())) .extracting("id") - .containsExactlyInAnyOrder("M01", "M02", "M02","M03, M03, M03"); - assertThat(foundOrder.get().getMenus()) + .containsExactlyInAnyOrder("M01", "M02", "M02","M03", "M03", "M03"); + assertThat(Converter.convertQtyMenus2Menus(foundOrder.get().getMenusQty())) .usingElementComparator(Comparator.comparing(MenuRestaurant::getId)) .containsExactlyInAnyOrder(menuRestaurant1, menuRestaurant2, menuRestaurant2, menuRestaurant3, menuRestaurant3, menuRestaurant3 ); } @@ -297,18 +304,19 @@ public void testRemovingMenusFromOrder() { OrderRestaurant updatedOrder = foundOrder.get(); // Let's remove the second menu //updatedOrder.removeMenu(menuRestaurant2); - updatedOrder.removeMenu(updatedOrder.getMenus().get(1)); +// updatedOrder.removeMenu(Converter.convertQtyMenus2Menus(updatedOrder.getMenus()).get(1)); + updatedOrder.removeMenu(menuRestaurant2); orderRestaurantRepository.save(updatedOrder); // Retrieve the updated order and assert the menus Optional updatedOrderOptional = orderRestaurantRepository.findById("O01"); // print the menus - System.out.println("Menus: " + updatedOrderOptional.get().getMenus()); + System.out.println("Menus: " + updatedOrderOptional.get().getMenusQty()); // assert the menus have been removed assertThat(updatedOrderOptional).isPresent(); - assertThat(updatedOrderOptional.get().getMenus()).hasSize(2); - assertThat(updatedOrderOptional.get().getMenus()).contains(menuRestaurant1, menuRestaurant3); - assertThat(updatedOrderOptional.get().getMenus()).doesNotContain(menuRestaurant2); + assertThat(updatedOrderOptional.get().getMenusQty()).hasSize(2); + assertThat(Converter.convertQtyMenus2Menus(updatedOrderOptional.get().getMenusQty())).contains(menuRestaurant1, menuRestaurant3); + assertThat(Converter.convertQtyMenus2Menus(updatedOrderOptional.get().getMenusQty())).doesNotContain(menuRestaurant2); // Retrieve the updated order after deleting the menu System.out.println("List of menus AFTER DELETION:"); @@ -340,10 +348,10 @@ public void testRemovingMenus_NO_Relationship() { menuRestaurantRepository.findAll().forEach(System.out::println); // We CAN NOT delete a menu that has a relationship - /*menuRestaurantRepository.delete(menuRestaurant2); + // menuRestaurantRepository.delete(menuRestaurant2); // Retrieve the updated order after deleting the menu - System.out.println("List of menus AFTER DELETION:"); - menuRestaurantRepository.findAll().forEach(System.out::println);*/ + // System.out.println("List of menus AFTER DELETION:"); + // menuRestaurantRepository.findAll().forEach(System.out::println); @@ -377,17 +385,17 @@ public void testRemovingMenusFromOrder_butNotRelationship() { // Retrieve the updated order and assert the menus Optional updatedOrderOptional = orderRestaurantRepository.findById("O01"); // print the menus - System.out.println("Menus: " + updatedOrderOptional.get().getMenus()); + System.out.println("Menus: " + updatedOrderOptional.get().getMenusQty()); // assert the menus have been removed assertThat(updatedOrderOptional).isPresent(); - assertThat(updatedOrderOptional.get().getMenus()).hasSize(2); + assertThat(updatedOrderOptional.get().getMenusQty()).hasSize(2); } // Cascading Deletion of Menus and Orders: Ensures that the deletion of a menu // or an order correctly cascades to the associated records in the order-menu join table. - /*@Test + @Test public void testCascadingDeletionOfMenusAndOrders() { // Create sample menus and save them MenuRestaurant menuRestaurant1 = new MenuRestaurant("M01", "Burger Menu", 10.99, "Burger, fries, and drink", true, true); @@ -411,9 +419,9 @@ public void testCascadingDeletionOfMenusAndOrders() { orderRestaurantRepository.save(updatedOrder); Optional updatedOrderOptional = orderRestaurantRepository.findById("O01"); assertThat(updatedOrderOptional).isPresent(); - assertThat(updatedOrderOptional.get().getMenus()).hasSize(2); - assertThat(updatedOrderOptional.get().getMenus()).contains(menuRestaurant1, menuRestaurant3); - assertThat(updatedOrderOptional.get().getMenus()).doesNotContain(menuRestaurant2); + assertThat(updatedOrderOptional.get().getMenusQty()).hasSize(2); + assertThat(Converter.convertQtyMenus2Menus(updatedOrderOptional.get().getMenusQty())).contains(menuRestaurant1, menuRestaurant3); + assertThat(Converter.convertQtyMenus2Menus(updatedOrderOptional.get().getMenusQty())).doesNotContain(menuRestaurant2); // Delete the order and verify the cascade deletion of the order-menu association orderRestaurantRepository.delete(order); @@ -423,14 +431,14 @@ public void testCascadingDeletionOfMenusAndOrders() { assertThat(menuRestaurant1Optional).isPresent(); assertThat(menuRestaurant2Optional).isPresent(); assertThat(menuRestaurant3Optional).isPresent(); - assertThat(menuRestaurant1Optional.get().getOrders()).isEmpty(); - assertThat(menuRestaurant2Optional.get().getOrders()).isEmpty(); - assertThat(menuRestaurant3Optional.get().getOrders()).isEmpty(); - }*/ +// assertThat(menuRestaurant1Optional.get().getOrders()).isEmpty(); +// assertThat(menuRestaurant2Optional.get().getOrders()).isEmpty(); +// assertThat(menuRestaurant3Optional.get().getOrders()).isEmpty(); + } // Adding Menus to an EatInOrder: Verifies that menus can be added // to an EatInOrderRestaurant and the association is correctly persisted in the database. - /*@Test + @Test public void testAddingMenusToEatInOrder() { // Create sample menus and save them MenuRestaurant menuRestaurant1 = new MenuRestaurant("M01", "Burger Menu", 10.99, "Burger, fries, and drink", true, true, null); @@ -447,7 +455,7 @@ public void testAddingMenusToEatInOrder() { tableRestaurantRepository.save(table2); // Create an EatInOrder and add menus - EatInOrderRestaurant eatInOrder = new EatInOrderRestaurant("EO1", new Date(), "John", 4, 43.96, true, new ArrayList<>(), new ArrayList<>(Arrays.asList(table1, table2))); + EatInOrderRestaurant eatInOrder = new EatInOrderRestaurant("EO1", new Date(), "John", 4, 43.96, true, (List)null, new ArrayList<>(Arrays.asList(table1, table2))); eatInOrder.addMenu(menuRestaurant1); eatInOrder.addMenu(menuRestaurant2); eatInOrder.addMenu(menuRestaurant3); @@ -456,8 +464,8 @@ public void testAddingMenusToEatInOrder() { // Retrieve the EatInOrder and assert the menus Optional foundOrder = (Optional) eatInOrderRestaurantRepository.findById("EO1"); assertThat(foundOrder).isPresent(); - assertThat(foundOrder.get().getMenus()).hasSize(3); - assertThat(foundOrder.get().getMenus()).contains(menuRestaurant1, menuRestaurant2, menuRestaurant3); + assertThat(foundOrder.get().getMenusQty()).hasSize(3); + assertThat(Converter.convertQtyMenus2Menus(foundOrder.get().getMenusQty())).contains(menuRestaurant1, menuRestaurant2, menuRestaurant3); } // Removing Menus from an EatInOrder: Checks that menus can be removed from an EatInOrder @@ -492,10 +500,12 @@ public void testRemovingMenusFromEatInOrder() { // Retrieve the updated EatInOrder and assert the menus Optional updatedOrderOptional = (Optional) eatInOrderRestaurantRepository.findById("EO1"); assertThat(updatedOrderOptional).isPresent(); - assertThat(updatedOrderOptional.get().getMenus()).hasSize(2); - assertThat(updatedOrderOptional.get().getMenus()).contains(menuRestaurant1, menuRestaurant3); - assertThat(updatedOrderOptional.get().getMenus()).doesNotContain(menuRestaurant2); + assertThat(updatedOrderOptional.get().getMenusQty()).hasSize(2); + assertThat(Converter.convertQtyMenus2Menus(updatedOrderOptional.get().getMenusQty())).contains(menuRestaurant1, menuRestaurant3); + assertThat(Converter.convertQtyMenus2Menus(updatedOrderOptional.get().getMenusQty())).doesNotContain(menuRestaurant2); + + } + - }*/ }