From db5c67e6021b11b40d8deed9cb0c708a0dbbec01 Mon Sep 17 00:00:00 2001 From: stefanokaefer Date: Mon, 11 Feb 2019 15:40:38 -0200 Subject: [PATCH 1/7] base para consulta e migration order -> orders --- pom.xml | 1 + .../mapFood/controller/OrderController.java | 79 ++--- .../groupsix/mapFood/entity/OrderEntity.java | 195 ++++++------- .../mapFood/repository/OrderRepository.java | 29 +- .../mapFood/service/OrderService.java | 207 +++++++------- src/main/resources/application.properties | 28 +- .../db/migration/V15__orderCreation.sql | 140 ++++----- .../validation/OrderValidationTest.java | 270 ------------------ target/classes/META-INF/MANIFEST.MF | 9 - .../maven/com.groupsix/mapFood/pom.properties | 7 - .../maven/com.groupsix/mapFood/pom.xml | 92 ------ target/classes/application.properties | 28 +- .../com/groupsix/mapFood/MapFoodApiApp.class | Bin 735 -> 735 bytes 13 files changed, 363 insertions(+), 722 deletions(-) delete mode 100644 src/test/java/com/groupsix/mapFood/validation/OrderValidationTest.java delete mode 100644 target/classes/META-INF/MANIFEST.MF delete mode 100644 target/classes/META-INF/maven/com.groupsix/mapFood/pom.properties delete mode 100644 target/classes/META-INF/maven/com.groupsix/mapFood/pom.xml diff --git a/pom.xml b/pom.xml index 7e368ba..adab682 100644 --- a/pom.xml +++ b/pom.xml @@ -86,6 +86,7 @@ org.springframework.boot spring-boot-maven-plugin + diff --git a/src/main/java/com/groupsix/mapFood/controller/OrderController.java b/src/main/java/com/groupsix/mapFood/controller/OrderController.java index 7d5614a..4944de7 100644 --- a/src/main/java/com/groupsix/mapFood/controller/OrderController.java +++ b/src/main/java/com/groupsix/mapFood/controller/OrderController.java @@ -1,36 +1,43 @@ -package com.groupsix.mapFood.controller; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.validation.BindingResult; -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 org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; - -import com.groupsix.mapFood.pojo.Order; -import com.groupsix.mapFood.service.OrderService; - -import javax.validation.Valid; - -@RestController -@RequestMapping("/orders") -public class OrderController { - - @Autowired - private OrderService orderService; - - @PostMapping - public ResponseEntity createOrder(final @RequestBody @Valid Order order, BindingResult bindingResult) { - - if (bindingResult.hasErrors()) { - return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).body(bindingResult.getFieldErrors()); - } - try { - return ResponseEntity.status(HttpStatus.CREATED).body(orderService.createOrder(order)); - } catch (Exception e) { - return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).body(e.getMessage()); - } - } -} +package com.groupsix.mapFood.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import com.groupsix.mapFood.pojo.Order; +import com.groupsix.mapFood.service.OrderService; + +import javax.validation.Valid; + +@RestController +@RequestMapping("/orders") +public class OrderController { + + @Autowired + private OrderService orderService; + + @PostMapping + public ResponseEntity createOrder(final @RequestBody @Valid Order order, BindingResult bindingResult) { + + if (bindingResult.hasErrors()) { + return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).body(bindingResult.getFieldErrors()); + } + try { + return ResponseEntity.status(HttpStatus.CREATED).body(orderService.createOrder(order)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).body(e.getMessage()); + } + } + + @GetMapping("/user/{id}") + public ResponseEntity listOrder(@PathVariable Integer id){ + if(orderService.listOrder(id).isEmpty()){ + return ResponseEntity.ok("Nenhum pedido"); + }else{ + return ResponseEntity.ok(orderService.listOrder(id)); + } + + } +} diff --git a/src/main/java/com/groupsix/mapFood/entity/OrderEntity.java b/src/main/java/com/groupsix/mapFood/entity/OrderEntity.java index 1e21e70..18c66ec 100644 --- a/src/main/java/com/groupsix/mapFood/entity/OrderEntity.java +++ b/src/main/java/com/groupsix/mapFood/entity/OrderEntity.java @@ -1,101 +1,94 @@ -package com.groupsix.mapFood.entity; - -import java.sql.Timestamp; -import java.util.List; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; - -@Entity(name = "`order`") -public class OrderEntity { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Integer id; - - @ManyToOne - @JoinColumn(name = "customer_id", nullable = false) - private CustomerEntity customer; - - @ManyToOne - @JoinColumn(name = "restaurant_id", nullable = false) - private RestaurantEntity restaurant; - - @Column(name = "estimated_time_to_delivery") - private Timestamp estimatedTimeToDelivery; - - @Column - private Integer total; - - @OneToMany(mappedBy = "order", targetEntity = OrderItemEntity.class, cascade = CascadeType.ALL) - private List orderItems; - - @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "order") - private OrderDeliveryEntity orderDelivery; - - public OrderDeliveryEntity getOrderDelivery() { - return orderDelivery; - } - - public void setOrderDelivery(OrderDeliveryEntity orderDelivery) { - this.orderDelivery = orderDelivery; - } - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public CustomerEntity getCustomer() { - return customer; - } - - public void setCustomer(CustomerEntity customer) { - this.customer = customer; - } - - public RestaurantEntity getRestaurant() { - return restaurant; - } - - public void setRestaurant(RestaurantEntity restaurant) { - this.restaurant = restaurant; - } - - public Timestamp getEstimatedTimeToDelivery() { - return estimatedTimeToDelivery; - } - - public void setEstimatedTimeToDelivery(Timestamp estimatedTimeToDelivery) { - this.estimatedTimeToDelivery = estimatedTimeToDelivery; - } - - public Integer getTotal() { - return total; - } - - public void setTotal(Integer total) { - this.total = total; - } - - public List getOrderItems() { - return orderItems; - } - - public void setOrderItems(List orderItems) { - this.orderItems = orderItems; - } - -} +package com.groupsix.mapFood.entity; + +import java.sql.Timestamp; +import java.util.List; + +import javax.persistence.*; + +@Entity(name = "orders") + +@Table(name= "orders") + +public class OrderEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @ManyToOne + @JoinColumn(name = "customer_id", nullable = false) + private CustomerEntity customer; + + @ManyToOne + @JoinColumn(name = "restaurant_id", nullable = false) + private RestaurantEntity restaurant; + + @Column(name = "estimated_time_to_delivery") + private Timestamp estimatedTimeToDelivery; + + @Column + private Integer total; + + @OneToMany(mappedBy = "order", targetEntity = OrderItemEntity.class, cascade = CascadeType.ALL) + private List orderItems; + + @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "order") + private OrderDeliveryEntity orderDelivery; + + public OrderDeliveryEntity getOrderDelivery() { + return orderDelivery; + } + + public void setOrderDelivery(OrderDeliveryEntity orderDelivery) { + this.orderDelivery = orderDelivery; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public CustomerEntity getCustomer() { + return customer; + } + + public void setCustomer(CustomerEntity customer) { + this.customer = customer; + } + + public RestaurantEntity getRestaurant() { + return restaurant; + } + + public void setRestaurant(RestaurantEntity restaurant) { + this.restaurant = restaurant; + } + + public Timestamp getEstimatedTimeToDelivery() { + return estimatedTimeToDelivery; + } + + public void setEstimatedTimeToDelivery(Timestamp estimatedTimeToDelivery) { + this.estimatedTimeToDelivery = estimatedTimeToDelivery; + } + + public Integer getTotal() { + return total; + } + + public void setTotal(Integer total) { + this.total = total; + } + + public List getOrderItems() { + return orderItems; + } + + public void setOrderItems(List orderItems) { + this.orderItems = orderItems; + } + +} diff --git a/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java b/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java index ecab2db..4e7cbd4 100644 --- a/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java +++ b/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java @@ -1,11 +1,18 @@ -package com.groupsix.mapFood.repository; - -import org.springframework.data.repository.CrudRepository; -import org.springframework.stereotype.Repository; - -import com.groupsix.mapFood.entity.OrderEntity; - -@Repository -public interface OrderRepository extends CrudRepository { - -} +package com.groupsix.mapFood.repository; + +import com.groupsix.mapFood.pojo.Order; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import com.groupsix.mapFood.entity.OrderEntity; + +import java.util.List; +import java.util.Set; + +@Repository +public interface OrderRepository extends JpaRepository { + + + List findByCustomer_Id(Integer id); +} diff --git a/src/main/java/com/groupsix/mapFood/service/OrderService.java b/src/main/java/com/groupsix/mapFood/service/OrderService.java index fa22348..8dda114 100644 --- a/src/main/java/com/groupsix/mapFood/service/OrderService.java +++ b/src/main/java/com/groupsix/mapFood/service/OrderService.java @@ -1,99 +1,110 @@ -package com.groupsix.mapFood.service; - -import java.sql.Timestamp; -import java.util.List; - -import com.google.maps.model.LatLng; -import com.groupsix.mapFood.entity.*; -import com.groupsix.mapFood.exception.CustomerTooFarException; -import com.groupsix.mapFood.exception.DiferentRestaurantException; -import com.groupsix.mapFood.exception.ItemsPriceException; -import com.groupsix.mapFood.exception.TotalPriceException; -import com.groupsix.mapFood.validation.OrderValidation; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import com.groupsix.mapFood.pojo.Order; -import com.groupsix.mapFood.repository.OrderRepository; -import com.groupsix.mapFood.util.TimestampUtil; - -@Service -public class OrderService { - - @Autowired - private OrderValidation orderValidation; - - @Autowired - private CustomerService customerService; - - @Autowired - private OrderItemService orderItemService; - - @Autowired - private OrderDeliveryService orderDeliveryService; - - @Autowired - private OrderRepository orderRepository; - - @Autowired - private RestaurantService restaurantService; - - @Autowired - private GoogleMapsService googleMapsService; - - public Order createOrder(final Order order) throws TotalPriceException, ItemsPriceException, DiferentRestaurantException, CustomerTooFarException { - orderValidation.verifyTotalOrder(order); - orderValidation.verifyCustomerAndRestaurantDistance(order); - - OrderEntity orderEntity = convertToEntity(order); - - final List orderItemsEntities = orderItemService.getOrderItems(order.getOrderItems(), orderEntity); - - orderValidation.verifyPricesFromItems(orderItemsEntities); - orderValidation.verifyItemsFromSameRestaurant(orderItemsEntities, order); - - orderEntity.setOrderDelivery(orderDeliveryService.create(orderEntity)); - - Timestamp outTime = verifyOutTime(orderEntity.getOrderDelivery().getEstimatedTimeToRestaurant()); - - Timestamp timeToDelivery = estimateTimeToDelivery(orderEntity, outTime); - - System.out.println("Sai do restaurant " + outTime); - System.out.println("Entrega estimada " + timeToDelivery); - System.out.println("\n\n"); - - orderEntity.setEstimatedTimeToDelivery(timeToDelivery); +package com.groupsix.mapFood.service; - orderRepository.save(orderEntity); - return order; - } - - private Timestamp verifyOutTime(Timestamp estimatedTimeToRestaurant) { - long time = System.currentTimeMillis(); - Timestamp tenMinutes = TimestampUtil.addSeconds(600L, new Timestamp(time)); - - if (estimatedTimeToRestaurant.before(tenMinutes)) { - return tenMinutes; - } else { - return estimatedTimeToRestaurant; - } - } - - private Timestamp estimateTimeToDelivery(OrderEntity orderEntity, Timestamp outTime) { - LatLng start = new LatLng(orderEntity.getRestaurant().getLat(), orderEntity.getRestaurant().getLon()); - LatLng end = new LatLng(orderEntity.getCustomer().getLat(), orderEntity.getCustomer().getLon()); - - return TimestampUtil.addSeconds(googleMapsService.timeToReach(start, end), outTime); - } - - public OrderEntity convertToEntity(Order order) { - OrderEntity entity = new OrderEntity(); - entity.setId(order.getId()); - entity.setCustomer(customerService.findById(order.getCustomerId()).get()); - entity.setOrderItems(orderItemService.getOrderItems(order.getOrderItems(), entity)); - entity.setRestaurant(restaurantService.findById(order.getRestaurantId()).get()); - entity.setTotal(order.getTotal()); - return entity; - } - -} +import java.sql.Timestamp; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import com.google.maps.model.LatLng; +import com.groupsix.mapFood.entity.*; +import com.groupsix.mapFood.exception.CustomerTooFarException; +import com.groupsix.mapFood.exception.DiferentRestaurantException; +import com.groupsix.mapFood.exception.ItemsPriceException; +import com.groupsix.mapFood.exception.TotalPriceException; +import com.groupsix.mapFood.factory.OrderFactory; +import com.groupsix.mapFood.validation.OrderValidation; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.groupsix.mapFood.pojo.Order; +import com.groupsix.mapFood.repository.OrderRepository; +import com.groupsix.mapFood.util.TimestampUtil; + +@Service +public class OrderService { + + @Autowired + private OrderValidation orderValidation; + + @Autowired + private CustomerService customerService; + + @Autowired + private OrderItemService orderItemService; + + @Autowired + private OrderDeliveryService orderDeliveryService; + + @Autowired + private OrderRepository orderRepository; + + @Autowired + private RestaurantService restaurantService; + + @Autowired + private GoogleMapsService googleMapsService; + + @Autowired + private OrderFactory orderFactory; + + public Order createOrder(final Order order) throws TotalPriceException, ItemsPriceException, DiferentRestaurantException, CustomerTooFarException { + orderValidation.verifyTotalOrder(order); + orderValidation.verifyCustomerAndRestaurantDistance(order); + + OrderEntity orderEntity = convertToEntity(order); + + final List orderItemsEntities = orderItemService.getOrderItems(order.getOrderItems(), orderEntity); + + orderValidation.verifyPricesFromItems(orderItemsEntities); + orderValidation.verifyItemsFromSameRestaurant(orderItemsEntities, order); + + orderEntity.setOrderDelivery(orderDeliveryService.create(orderEntity)); + + Timestamp outTime = verifyOutTime(orderEntity.getOrderDelivery().getEstimatedTimeToRestaurant()); + + Timestamp timeToDelivery = estimateTimeToDelivery(orderEntity, outTime); + + System.out.println("Sai do restaurant " + outTime); + System.out.println("Entrega estimada " + timeToDelivery); + System.out.println("\n\n"); + + orderEntity.setEstimatedTimeToDelivery(timeToDelivery); + + orderRepository.save(orderEntity); + return order; + } + + private Timestamp verifyOutTime(Timestamp estimatedTimeToRestaurant) { + long time = System.currentTimeMillis(); + Timestamp tenMinutes = TimestampUtil.addSeconds(600L, new Timestamp(time)); + + if (estimatedTimeToRestaurant.before(tenMinutes)) { + return tenMinutes; + } else { + return estimatedTimeToRestaurant; + } + } + + private Timestamp estimateTimeToDelivery(OrderEntity orderEntity, Timestamp outTime) { + LatLng start = new LatLng(orderEntity.getRestaurant().getLat(), orderEntity.getRestaurant().getLon()); + LatLng end = new LatLng(orderEntity.getCustomer().getLat(), orderEntity.getCustomer().getLon()); + + return TimestampUtil.addSeconds(googleMapsService.timeToReach(start, end), outTime); + } + + public OrderEntity convertToEntity(Order order) { + OrderEntity entity = new OrderEntity(); + entity.setId(order.getId()); + entity.setCustomer(customerService.findById(order.getCustomerId()).get()); + entity.setOrderItems(orderItemService.getOrderItems(order.getOrderItems(), entity)); + entity.setRestaurant(restaurantService.findById(order.getRestaurantId()).get()); + entity.setTotal(order.getTotal()); + return entity; + } + + public List listOrder(Integer id) { + return StreamSupport.stream(orderRepository.findByCustomer_Id(id).spliterator(), false).map(orderFactory::getInstance).collect(Collectors.toList()); + + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1ec6c59..9ca21be 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,15 +1,15 @@ -## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) -spring.datasource.url=jdbc:mysql://localhost:3306/mapFood?useSSL=false&useTimezone=true&serverTimezone=UTC&allowPublicKeyRetrieval=true -spring.datasource.username=root -spring.datasource.password= -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -## Hibernate Properties -# The SQL dialect makes Hibernate generate better SQL for the chosen database -spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect - -## This is important -# Hibernate ddl auto (create, create-drop, validate, update) -spring.jpa.hibernate.ddl-auto=validate -logging.level.org.hibernate.SQL=DEBUG -logging.level.org.hibernate.type=TRACE +## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) +spring.datasource.url=jdbc:mysql://localhost:3306/mapFood?useSSL=false&useTimezone=true&serverTimezone=UTC&allowPublicKeyRetrieval=true +spring.datasource.username=root +spring.datasource.password=vertrigo +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +## Hibernate Properties +# The SQL dialect makes Hibernate generate better SQL for the chosen database +spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect + +## This is important +# Hibernate ddl auto (create, create-drop, validate, update) +spring.jpa.hibernate.ddl-auto=validate +logging.level.org.hibernate.SQL=DEBUG +logging.level.org.hibernate.type=TRACE spring.jpa.show-sql=true \ No newline at end of file diff --git a/src/main/resources/db/migration/V15__orderCreation.sql b/src/main/resources/db/migration/V15__orderCreation.sql index b245ff2..7740e35 100644 --- a/src/main/resources/db/migration/V15__orderCreation.sql +++ b/src/main/resources/db/migration/V15__orderCreation.sql @@ -1,70 +1,70 @@ -CREATE TABLE `mapfood`.`order` ( - `id` INT NOT NULL AUTO_INCREMENT, - `customer_id` INT NOT NULL, - `restaurant_id` INT NOT NULL, - `estimated_time_to_delivery` TIMESTAMP NOT NULL, - `total` INT NOT NULL, - PRIMARY KEY (`id`)); - -ALTER TABLE `mapfood`.`order` -ADD INDEX `fk_order_1_idx` (`customer_id` ASC), -ADD INDEX `fk_order_2_idx` (`restaurant_id` ASC); -; -ALTER TABLE `mapfood`.`order` -ADD CONSTRAINT `fk_order_1` - FOREIGN KEY (`customer_id`) - REFERENCES `mapfood`.`customer` (`id`) - ON DELETE NO ACTION - ON UPDATE NO ACTION, -ADD CONSTRAINT `fk_order_2` - FOREIGN KEY (`restaurant_id`) - REFERENCES `mapfood`.`restaurant` (`id`) - ON DELETE NO ACTION - ON UPDATE NO ACTION; - - -CREATE TABLE `mapfood`.`order_item` ( - `id` INT NOT NULL AUTO_INCREMENT, - `order_id` INT NOT NULL, - `product_id` INT NOT NULL, - `quantity` INT NOT NULL, - `name` VARCHAR(200) NOT NULL, - `total` INT NOT NULL, - `item_price` INT NOT NULL, - PRIMARY KEY (`id`), - INDEX `fk_order_item_1_idx` (`order_id` ASC), - INDEX `fk_order_item_2_idx` (`product_id` ASC), - CONSTRAINT `fk_order_item_1` - FOREIGN KEY (`order_id`) - REFERENCES `mapfood`.`order` (`id`) - ON DELETE NO ACTION - ON UPDATE NO ACTION, - CONSTRAINT `fk_order_item_2` - FOREIGN KEY (`product_id`) - REFERENCES `mapfood`.`product` (`id`) - ON DELETE NO ACTION - ON UPDATE NO ACTION); - -CREATE TABLE `mapfood`.`order_delivery` ( - `id` INT NOT NULL AUTO_INCREMENT, - `order_id` INT NOT NULL, - `destination_lat` DOUBLE NOT NULL, - `destination_lon` DOUBLE NOT NULL, - `motoboy_id` INT NULL DEFAULT NULL, - `estimated_time_to_restaurant` TIMESTAMP NOT NULL, - PRIMARY KEY (`id`), - INDEX `fk_order_delivery_1_idx` (`order_id` ASC), - INDEX `fk_order_delivery_2_idx` (`motoboy_id` ASC), - CONSTRAINT `fk_order_delivery_1` - FOREIGN KEY (`order_id`) - REFERENCES `mapfood`.`order` (`id`) - ON DELETE NO ACTION - ON UPDATE NO ACTION, - CONSTRAINT `fk_order_delivery_2` - FOREIGN KEY (`motoboy_id`) - REFERENCES `mapfood`.`motoboy` (`id`) - ON DELETE NO ACTION - ON UPDATE NO ACTION); - -ALTER TABLE `mapfood`.`order_delivery` -CHANGE COLUMN `estimated_time_to_restaurant` `estimated_time_to_restaurant` TIMESTAMP NULL DEFAULT NULL ; +CREATE TABLE `mapfood`.`orders` ( + `id` INT NOT NULL AUTO_INCREMENT, + `customer_id` INT NOT NULL, + `restaurant_id` INT NOT NULL, + `estimated_time_to_delivery` TIMESTAMP NOT NULL, + `total` INT NOT NULL, + PRIMARY KEY (`id`)); + +ALTER TABLE `mapfood`.`orders` +ADD INDEX `fk_orders_1_idx` (`customer_id` ASC), +ADD INDEX `fk_orders_2_idx` (`restaurant_id` ASC); +; +ALTER TABLE `mapfood`.`orders` +ADD CONSTRAINT `fk_orders_1` + FOREIGN KEY (`customer_id`) + REFERENCES `mapfood`.`customer` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, +ADD CONSTRAINT `fk_orders_2` + FOREIGN KEY (`restaurant_id`) + REFERENCES `mapfood`.`restaurant` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION; + + +CREATE TABLE `mapfood`.`order_item` ( + `id` INT NOT NULL AUTO_INCREMENT, + `order_id` INT NOT NULL, + `product_id` INT NOT NULL, + `quantity` INT NOT NULL, + `name` VARCHAR(200) NOT NULL, + `total` INT NOT NULL, + `item_price` INT NOT NULL, + PRIMARY KEY (`id`), + INDEX `fk_order_item_1_idx` (`order_id` ASC), + INDEX `fk_order_item_2_idx` (`product_id` ASC), + CONSTRAINT `fk_order_item_1` + FOREIGN KEY (`order_id`) + REFERENCES `mapfood`.`orders` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_order_item_2` + FOREIGN KEY (`product_id`) + REFERENCES `mapfood`.`product` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION); + +CREATE TABLE `mapfood`.`order_delivery` ( + `id` INT NOT NULL AUTO_INCREMENT, + `order_id` INT NOT NULL, + `destination_lat` DOUBLE NOT NULL, + `destination_lon` DOUBLE NOT NULL, + `motoboy_id` INT NULL DEFAULT NULL, + `estimated_time_to_restaurant` TIMESTAMP NOT NULL, + PRIMARY KEY (`id`), + INDEX `fk_order_delivery_1_idx` (`order_id` ASC), + INDEX `fk_order_delivery_2_idx` (`motoboy_id` ASC), + CONSTRAINT `fk_order_delivery_1` + FOREIGN KEY (`order_id`) + REFERENCES `mapfood`.`orders` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION, + CONSTRAINT `fk_order_delivery_2` + FOREIGN KEY (`motoboy_id`) + REFERENCES `mapfood`.`motoboy` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION); + +ALTER TABLE `mapfood`.`order_delivery` +CHANGE COLUMN `estimated_time_to_restaurant` `estimated_time_to_restaurant` TIMESTAMP NULL DEFAULT NULL ; diff --git a/src/test/java/com/groupsix/mapFood/validation/OrderValidationTest.java b/src/test/java/com/groupsix/mapFood/validation/OrderValidationTest.java deleted file mode 100644 index 1c5b325..0000000 --- a/src/test/java/com/groupsix/mapFood/validation/OrderValidationTest.java +++ /dev/null @@ -1,270 +0,0 @@ -package com.groupsix.mapFood.validation; - -import com.groupsix.mapFood.entity.CustomerEntity; -import com.groupsix.mapFood.entity.OrderItemEntity; -import com.groupsix.mapFood.entity.ProductEntity; -import com.groupsix.mapFood.entity.RestaurantEntity; -import com.groupsix.mapFood.exception.CustomerTooFarException; -import com.groupsix.mapFood.exception.DiferentRestaurantException; -import com.groupsix.mapFood.exception.ItemsPriceException; -import com.groupsix.mapFood.exception.TotalPriceException; -import com.groupsix.mapFood.pojo.Order; -import com.groupsix.mapFood.pojo.OrderItem; -import com.groupsix.mapFood.repository.CustomerRepository; -import com.groupsix.mapFood.repository.RestaurantRepository; -import com.groupsix.mapFood.service.CustomerService; -import com.groupsix.mapFood.service.RestaurantService; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import java.util.ArrayList; -import java.util.List; - -import static junit.framework.TestCase.fail; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class OrderValidationTest { - - @Mock - private CustomerService customerService; - - @Mock - private RestaurantService restaurantService; - - @InjectMocks - private OrderValidation orderValidation; - - @Test - public void testVerifyTotalOrder() { - - Order order = new Order(); - List orderItems = new ArrayList<>(); - OrderItem item1 = new OrderItem(); - OrderItem item2 = new OrderItem(); - - item1.setTotal(200); - item2.setTotal(600); - - orderItems.add(item1); - orderItems.add(item2); - - order.setTotal(800); - order.setOrderItems(orderItems); - - try { - orderValidation.verifyTotalOrder(order); - } catch (TotalPriceException e) { - fail(); - } - } - - @Test - public void testVerifyTotalOrderWithWrongTotal() { - - Order order = new Order(); - List orderItems = new ArrayList<>(); - OrderItem item1 = new OrderItem(); - OrderItem item2 = new OrderItem(); - - item1.setTotal(200); - item2.setTotal(600); - - orderItems.add(item1); - orderItems.add(item2); - - order.setTotal(700); - order.setOrderItems(orderItems); - - try { - orderValidation.verifyTotalOrder(order); - } catch (TotalPriceException e) { - return; - } - fail(); - } - - @Test - public void testVerifyCustomerAndRestaurantDistance() { - - Order order = new Order(); - CustomerEntity customer = new CustomerEntity(); - RestaurantEntity restaurant = new RestaurantEntity(); - - customer.setId(9); - customer.setLon(-0.44); - customer.setLat(0.45); - - restaurant.setId(5); - restaurant.setLon(-0.48); - restaurant.setLat(0.42); - - when(customerService.getCustomer(9)).thenReturn(customer); - when(restaurantService.getRestaurant(5)).thenReturn(restaurant); - - order.setCustomerId(9); - order.setRestaurantId(5); - - try { - orderValidation.verifyCustomerAndRestaurantDistance(order); - } catch (CustomerTooFarException e) { - fail(); - } - } - - @Test - public void testVerifyCustomerTooFarFromTheRestaurant() { - - Order order = new Order(); - CustomerEntity customer = new CustomerEntity(); - RestaurantEntity restaurant = new RestaurantEntity(); - - customer.setId(9); - customer.setLon(-2.44); - customer.setLat(2.45); - - restaurant.setId(5); - restaurant.setLon(-31.48); - restaurant.setLat(31.42); - - when(customerService.getCustomer(9)).thenReturn(customer); - when(restaurantService.getRestaurant(5)).thenReturn(restaurant); - - order.setCustomerId(9); - order.setRestaurantId(5); - - try { - orderValidation.verifyCustomerAndRestaurantDistance(order); - } catch (CustomerTooFarException e) { - return; - } - fail(); - } - - @Test - public void testVerifyPricesFromItems() { - - List orderItemsEntities = new ArrayList<>(); - ProductEntity product1 = new ProductEntity(); - ProductEntity product2 = new ProductEntity(); - OrderItemEntity item1 = new OrderItemEntity(); - OrderItemEntity item2 = new OrderItemEntity(); - - product1.setPrice(50); - product2.setPrice(100); - - item1.setProduct(product1); - item1.setQuantity(3); - item1.setTotal(150); - item2.setProduct(product2); - item2.setQuantity(4); - item2.setTotal(400); - - orderItemsEntities.add(item1); - orderItemsEntities.add(item2); - - try { - orderValidation.verifyPricesFromItems(orderItemsEntities); - } catch (ItemsPriceException e) { - fail(); - } - } - - @Test - public void testVerifyPricesFromItemsWithWrongTotal() { - - List orderItemsEntities = new ArrayList<>(); - ProductEntity product1 = new ProductEntity(); - ProductEntity product2 = new ProductEntity(); - OrderItemEntity item1 = new OrderItemEntity(); - OrderItemEntity item2 = new OrderItemEntity(); - - product1.setPrice(50); - product2.setPrice(100); - - item1.setProduct(product1); - item1.setQuantity(3); - item1.setTotal(200); - item2.setProduct(product2); - item2.setQuantity(4); - item2.setTotal(300); - - orderItemsEntities.add(item1); - orderItemsEntities.add(item2); - - try { - orderValidation.verifyPricesFromItems(orderItemsEntities); - } catch (ItemsPriceException e) { - return; - } - fail(); - } - - @Test - public void testVerifyItemsFromSameRestaurant() { - - Order order = new Order(); - List orderItemsEntities = new ArrayList<>(); - ProductEntity product1 = new ProductEntity(); - ProductEntity product2 = new ProductEntity(); - RestaurantEntity restaurant1 = new RestaurantEntity(); - RestaurantEntity restaurant2 = new RestaurantEntity(); - OrderItemEntity item1 = new OrderItemEntity(); - OrderItemEntity item2 = new OrderItemEntity(); - - order.setRestaurantId(10); - restaurant1.setId(10); - restaurant2.setId(10); - - product1.setRestaurant(restaurant1); - product2.setRestaurant(restaurant2); - - item1.setProduct(product1); - item2.setProduct(product2); - - orderItemsEntities.add(item1); - orderItemsEntities.add(item2); - - try { - orderValidation.verifyItemsFromSameRestaurant(orderItemsEntities, order); - } catch (DiferentRestaurantException e) { - fail(); - } - } - - @Test - public void testVerifyItemsFromSameRestaurantWithDiferentRestaurants() { - - Order order = new Order(); - List orderItemsEntities = new ArrayList<>(); - ProductEntity product1 = new ProductEntity(); - ProductEntity product2 = new ProductEntity(); - RestaurantEntity restaurant1 = new RestaurantEntity(); - RestaurantEntity restaurant2 = new RestaurantEntity(); - OrderItemEntity item1 = new OrderItemEntity(); - OrderItemEntity item2 = new OrderItemEntity(); - - order.setRestaurantId(10); - restaurant1.setId(11); - restaurant2.setId(10); - - product1.setRestaurant(restaurant1); - product2.setRestaurant(restaurant2); - - item1.setProduct(product1); - item2.setProduct(product2); - - orderItemsEntities.add(item1); - orderItemsEntities.add(item2); - - try { - orderValidation.verifyItemsFromSameRestaurant(orderItemsEntities, order); - } catch (DiferentRestaurantException e) { - return; - } - fail(); - } -} diff --git a/target/classes/META-INF/MANIFEST.MF b/target/classes/META-INF/MANIFEST.MF deleted file mode 100644 index 84d0c42..0000000 --- a/target/classes/META-INF/MANIFEST.MF +++ /dev/null @@ -1,9 +0,0 @@ -Manifest-Version: 1.0 -Implementation-Title: mapFood -Implementation-Version: 0.0.1-SNAPSHOT -Built-By: metal -Implementation-Vendor-Id: com.groupsix -Build-Jdk: 1.8.0_201 -Implementation-URL: http://maven.apache.org -Created-By: Maven Integration for Eclipse - diff --git a/target/classes/META-INF/maven/com.groupsix/mapFood/pom.properties b/target/classes/META-INF/maven/com.groupsix/mapFood/pom.properties deleted file mode 100644 index 717020c..0000000 --- a/target/classes/META-INF/maven/com.groupsix/mapFood/pom.properties +++ /dev/null @@ -1,7 +0,0 @@ -#Generated by Maven Integration for Eclipse -#Sat Feb 09 08:39:45 BRST 2019 -version=0.0.1-SNAPSHOT -groupId=com.groupsix -m2e.projectName=mapFood -m2e.projectLocation=C\:\\Users\\metal\\OneDrive\\Documentos\\workspace-spring\\mapFood -artifactId=mapFood diff --git a/target/classes/META-INF/maven/com.groupsix/mapFood/pom.xml b/target/classes/META-INF/maven/com.groupsix/mapFood/pom.xml deleted file mode 100644 index 7e368ba..0000000 --- a/target/classes/META-INF/maven/com.groupsix/mapFood/pom.xml +++ /dev/null @@ -1,92 +0,0 @@ - - 4.0.0 - - com.groupsix - mapFood - 0.0.1-SNAPSHOT - jar - - mapFood - http://maven.apache.org - - - org.springframework.boot - spring-boot-starter-parent - 2.1.1.RELEASE - - - - - junit - junit - test - - - org.springframework.boot - spring-boot-starter-web - - - - org.flywaydb - flyway-core - - - - mysql - mysql-connector-java - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - - org.hibernate.validator - hibernate-validator - - - - - junit - junit - test - - - - - org.mockito - mockito-all - 1.9.5 - test - - - - - com.google.code.gson - gson - - - org.springframework.boot - spring-boot-devtools - - - com.google.maps - google-maps-services - 0.9.1 - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - \ No newline at end of file diff --git a/target/classes/application.properties b/target/classes/application.properties index 1ec6c59..9ca21be 100644 --- a/target/classes/application.properties +++ b/target/classes/application.properties @@ -1,15 +1,15 @@ -## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) -spring.datasource.url=jdbc:mysql://localhost:3306/mapFood?useSSL=false&useTimezone=true&serverTimezone=UTC&allowPublicKeyRetrieval=true -spring.datasource.username=root -spring.datasource.password= -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -## Hibernate Properties -# The SQL dialect makes Hibernate generate better SQL for the chosen database -spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect - -## This is important -# Hibernate ddl auto (create, create-drop, validate, update) -spring.jpa.hibernate.ddl-auto=validate -logging.level.org.hibernate.SQL=DEBUG -logging.level.org.hibernate.type=TRACE +## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) +spring.datasource.url=jdbc:mysql://localhost:3306/mapFood?useSSL=false&useTimezone=true&serverTimezone=UTC&allowPublicKeyRetrieval=true +spring.datasource.username=root +spring.datasource.password=vertrigo +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +## Hibernate Properties +# The SQL dialect makes Hibernate generate better SQL for the chosen database +spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect + +## This is important +# Hibernate ddl auto (create, create-drop, validate, update) +spring.jpa.hibernate.ddl-auto=validate +logging.level.org.hibernate.SQL=DEBUG +logging.level.org.hibernate.type=TRACE spring.jpa.show-sql=true \ No newline at end of file diff --git a/target/classes/com/groupsix/mapFood/MapFoodApiApp.class b/target/classes/com/groupsix/mapFood/MapFoodApiApp.class index 376da8959db5c5ce4956bb925110638e35b7a8c2..2c5e5550e7cbfbb31d44b7f70871abe7336eb9ac 100644 GIT binary patch delta 252 zcmcc5dY{$c)W2Q(7#J8#7-YE^SQtdv8N|34#2F;m86+7Q*laTMGE3|j8JIOR!x$M@ zobyvsCuWpRZem=|%EQ3Qz&4RrT~dmNL7G8^kwG9Uu`E$PCowNw-#;lUHMwNsQ{Bnp zjM;1qiVRE)ER)Td?KMh4-@4;h6g9-73)pvV9;X0kbxd_BiTpxsOiTtJcyD9FIT&cF>MdBAK| zAk7QpaWe2R@B>w`1KDOk8l;Xxh*4_?gFrY!KNnDj0caA)1cVtJ3}Ou8Kye8mW@Q9& RK-NiuNht Date: Mon, 11 Feb 2019 15:42:24 -0200 Subject: [PATCH 2/7] base para relatoiro e migration order -> orders --- .../groupsix/mapFood/factory/OrderFactory.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/main/java/com/groupsix/mapFood/factory/OrderFactory.java diff --git a/src/main/java/com/groupsix/mapFood/factory/OrderFactory.java b/src/main/java/com/groupsix/mapFood/factory/OrderFactory.java new file mode 100644 index 0000000..ee09873 --- /dev/null +++ b/src/main/java/com/groupsix/mapFood/factory/OrderFactory.java @@ -0,0 +1,17 @@ +package com.groupsix.mapFood.factory; + +import com.groupsix.mapFood.entity.OrderEntity; +import com.groupsix.mapFood.pojo.Order; +import org.springframework.stereotype.Component; + +@Component +public class OrderFactory { + + public Order getInstance(OrderEntity orderEntity){ + Order order = new Order(); + order.setId(orderEntity.getId()); + + return order; + + } +} From c485da92e2b6dc70ecce096224fe6e0dbd54a30c Mon Sep 17 00:00:00 2001 From: Stefano Kaefer Date: Tue, 12 Feb 2019 02:23:44 -0200 Subject: [PATCH 3/7] novos relatorios --- .../mapFood/controller/OrderController.java | 23 +++++++++++++++++-- .../mapFood/factory/OrderFactory.java | 7 ++++++ .../java/com/groupsix/mapFood/pojo/Order.java | 4 ++++ .../mapFood/repository/OrderRepository.java | 3 +++ .../mapFood/service/OrderService.java | 18 +++++++++++++++ 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/groupsix/mapFood/controller/OrderController.java b/src/main/java/com/groupsix/mapFood/controller/OrderController.java index 4944de7..dfac6c1 100644 --- a/src/main/java/com/groupsix/mapFood/controller/OrderController.java +++ b/src/main/java/com/groupsix/mapFood/controller/OrderController.java @@ -32,12 +32,31 @@ public ResponseEntity createOrder(final @RequestBody @Valid Order order, Bind } @GetMapping("/user/{id}") - public ResponseEntity listOrder(@PathVariable Integer id){ + public ResponseEntity listUserOrders(@PathVariable Integer id){ if(orderService.listOrder(id).isEmpty()){ - return ResponseEntity.ok("Nenhum pedido"); + return ResponseEntity.ok("Faça seu primeiro pedido!"); }else{ return ResponseEntity.ok(orderService.listOrder(id)); } } + + @GetMapping("/restaurant/{id}") + public ResponseEntity listRestaurantOrders(@PathVariable Integer id){ + if(orderService.listRestaurantOrder(id).isEmpty()){ + return ResponseEntity.ok("Você ainda não tem pedidos :("); + }else{ + return ResponseEntity.ok(orderService.listRestaurantOrder(id)); + } + + } + @GetMapping("/restaurant/report/{id}") + public ResponseEntity listInformations(@PathVariable Integer id){ + if(orderService.informationsRestaurant(id).isEmpty()){ + return ResponseEntity.ok("Você ainda não tem pedidos :("); + }else{ + return ResponseEntity.ok(orderService.informationsRestaurant(id)); + } + + } } diff --git a/src/main/java/com/groupsix/mapFood/factory/OrderFactory.java b/src/main/java/com/groupsix/mapFood/factory/OrderFactory.java index ee09873..b235958 100644 --- a/src/main/java/com/groupsix/mapFood/factory/OrderFactory.java +++ b/src/main/java/com/groupsix/mapFood/factory/OrderFactory.java @@ -4,12 +4,19 @@ import com.groupsix.mapFood.pojo.Order; import org.springframework.stereotype.Component; +import java.util.stream.Collector; +import java.util.stream.Collectors; + @Component public class OrderFactory { public Order getInstance(OrderEntity orderEntity){ Order order = new Order(); order.setId(orderEntity.getId()); + order.setCustomerId(orderEntity.getCustomer().getId()); + order.setRestaurantId(orderEntity.getRestaurant().getId()); + order.setTotal(orderEntity.getTotal()); + return order; diff --git a/src/main/java/com/groupsix/mapFood/pojo/Order.java b/src/main/java/com/groupsix/mapFood/pojo/Order.java index 7be4804..f3d26ff 100644 --- a/src/main/java/com/groupsix/mapFood/pojo/Order.java +++ b/src/main/java/com/groupsix/mapFood/pojo/Order.java @@ -1,5 +1,7 @@ package com.groupsix.mapFood.pojo; +import com.groupsix.mapFood.entity.OrderItemEntity; + import javax.validation.constraints.NotNull; import java.util.List; @@ -54,4 +56,6 @@ public List getOrderItems() { public void setOrderItems(List orderItems) { this.orderItems = orderItems; } + + } diff --git a/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java b/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java index 4e7cbd4..7795752 100644 --- a/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java +++ b/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java @@ -15,4 +15,7 @@ public interface OrderRepository extends JpaRepository { List findByCustomer_Id(Integer id); + + List findByRestaurant_Id(Integer id); + } diff --git a/src/main/java/com/groupsix/mapFood/service/OrderService.java b/src/main/java/com/groupsix/mapFood/service/OrderService.java index 8dda114..e68aafb 100644 --- a/src/main/java/com/groupsix/mapFood/service/OrderService.java +++ b/src/main/java/com/groupsix/mapFood/service/OrderService.java @@ -2,7 +2,10 @@ import java.sql.Timestamp; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -107,4 +110,19 @@ public List listOrder(Integer id) { return StreamSupport.stream(orderRepository.findByCustomer_Id(id).spliterator(), false).map(orderFactory::getInstance).collect(Collectors.toList()); } + + public List listRestaurantOrder(Integer id){ + return StreamSupport.stream(orderRepository.findByRestaurant_Id(id).spliterator(), false).map(orderFactory::getInstance).collect(Collectors.toList()); + } + + public Map informationsRestaurant(Integer id){ + int numeroPedidos = (int) StreamSupport.stream(orderRepository.findByRestaurant_Id(id).spliterator(), false).count(); + int numeroUsuarios = (int) StreamSupport.stream(orderRepository.findByRestaurant_Id(id).spliterator(), false).map(orderFactory::getInstance).collect(Collectors.groupingBy(), Collectors.counting()); + HashMap map = new HashMap<>(); + map.put("numero_pedidos", String.valueOf(numeroPedidos)); + map.put("numero_clientes", "bar"); + map.put("faturamento", "bb"); + return map; + + } } From 61eafdade4eb9861e7378077a122cbc9000e694b Mon Sep 17 00:00:00 2001 From: stefanokaefer Date: Tue, 12 Feb 2019 10:37:21 -0200 Subject: [PATCH 4/7] base para consulta e migration order -> orders --- .../com/groupsix/mapFood/repository/OrderRepository.java | 5 +++++ src/main/java/com/groupsix/mapFood/service/OrderService.java | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java b/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java index 7795752..acdc645 100644 --- a/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java +++ b/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java @@ -2,7 +2,9 @@ import com.groupsix.mapFood.pojo.Order; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import com.groupsix.mapFood.entity.OrderEntity; @@ -17,5 +19,8 @@ public interface OrderRepository extends JpaRepository { List findByCustomer_Id(Integer id); List findByRestaurant_Id(Integer id); + @Query(value = "SELECT DISTINCT(customer_id) FROM orders where restaurant_id = '%id%'", nativeQuery = true) + List countAllCustomer(Integer id); + } diff --git a/src/main/java/com/groupsix/mapFood/service/OrderService.java b/src/main/java/com/groupsix/mapFood/service/OrderService.java index e68aafb..ebcf0ef 100644 --- a/src/main/java/com/groupsix/mapFood/service/OrderService.java +++ b/src/main/java/com/groupsix/mapFood/service/OrderService.java @@ -117,10 +117,10 @@ public List listRestaurantOrder(Integer id){ public Map informationsRestaurant(Integer id){ int numeroPedidos = (int) StreamSupport.stream(orderRepository.findByRestaurant_Id(id).spliterator(), false).count(); - int numeroUsuarios = (int) StreamSupport.stream(orderRepository.findByRestaurant_Id(id).spliterator(), false).map(orderFactory::getInstance).collect(Collectors.groupingBy(), Collectors.counting()); + int numeroUsuarios = (int) StreamSupport.stream(orderRepository.countAllCustomer(id).spliterator(), false).count(); HashMap map = new HashMap<>(); map.put("numero_pedidos", String.valueOf(numeroPedidos)); - map.put("numero_clientes", "bar"); + map.put("numero_clientes", String.valueOf(numeroUsuarios)); map.put("faturamento", "bb"); return map; From cdb1e9c0cfb1bebadfa0cf33ac53dc305661be7d Mon Sep 17 00:00:00 2001 From: stefanokaefer Date: Tue, 12 Feb 2019 11:26:50 -0200 Subject: [PATCH 5/7] base para consulta e migration order -> orders --- .../mapFood/repository/OrderRepository.java | 10 ++++++++-- .../groupsix/mapFood/service/OrderService.java | 15 ++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java b/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java index acdc645..56a7eec 100644 --- a/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java +++ b/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java @@ -19,8 +19,14 @@ public interface OrderRepository extends JpaRepository { List findByCustomer_Id(Integer id); List findByRestaurant_Id(Integer id); - @Query(value = "SELECT DISTINCT(customer_id) FROM orders where restaurant_id = '%id%'", nativeQuery = true) - List countAllCustomer(Integer id); + + @Query(value = "SELECT COUNT(DISTINCT(customer_id)) FROM orders where restaurant_id = ?1", nativeQuery = true) + int countAllCustomer(Integer id); + + @Query(value = "SELECT SUM(total) FROM orders where restaurant_id = ?1", nativeQuery = true) + int countTotalRevenue(Integer id); + + } diff --git a/src/main/java/com/groupsix/mapFood/service/OrderService.java b/src/main/java/com/groupsix/mapFood/service/OrderService.java index ebcf0ef..11550d6 100644 --- a/src/main/java/com/groupsix/mapFood/service/OrderService.java +++ b/src/main/java/com/groupsix/mapFood/service/OrderService.java @@ -116,12 +116,17 @@ public List listRestaurantOrder(Integer id){ } public Map informationsRestaurant(Integer id){ - int numeroPedidos = (int) StreamSupport.stream(orderRepository.findByRestaurant_Id(id).spliterator(), false).count(); - int numeroUsuarios = (int) StreamSupport.stream(orderRepository.countAllCustomer(id).spliterator(), false).count(); + int totalOrders = (int) StreamSupport.stream(orderRepository.findByRestaurant_Id(id).spliterator(), false).count(); + int totalUsers = orderRepository.countAllCustomer(id); + int totalRevenue = orderRepository.countTotalRevenue(id); HashMap map = new HashMap<>(); - map.put("numero_pedidos", String.valueOf(numeroPedidos)); - map.put("numero_clientes", String.valueOf(numeroUsuarios)); - map.put("faturamento", "bb"); + + map.put("numero_pedidos", String.valueOf(totalOrders)); + map.put("numero_clientes", String.valueOf(totalUsers)); + map.put("faturamento", String.valueOf(totalRevenue)); + + + return map; } From 4a22e20f5b49c1bdadc5e1319785386c12362b19 Mon Sep 17 00:00:00 2001 From: stefanokaefer Date: Tue, 12 Feb 2019 12:33:16 -0200 Subject: [PATCH 6/7] all report and order --- pom.xml | 1 - .../com/groupsix/mapFood/MapFoodApiApp.java | 36 ++-- .../mapFood/controller/OrderController.java | 9 - .../groupsix/mapFood/entity/OrderEntity.java | 4 +- .../exception/CustomerTooFarException.java | 4 +- .../DiferentRestaurantException.java | 4 +- .../exception/ItemsPriceException.java | 4 +- .../exception/TotalPriceException.java | 4 +- .../mapFood/factory/OrderFactory.java | 50 ++++-- .../mapFood/pojo/CacheMotoboyOrder.java | 57 ++++++- .../java/com/groupsix/mapFood/pojo/Order.java | 118 +++++++------ .../mapFood/repository/OrderRepository.java | 11 +- .../mapFood/service/CacheService.java | 72 ++++---- .../mapFood/service/OrderDeliveryService.java | 157 ++++++++++++------ .../mapFood/service/OrderItemService.java | 80 +++++---- .../mapFood/service/OrderService.java | 88 +++------- .../groupsix/mapFood/util/TimestampUtil.java | 45 +++-- src/main/resources/application.properties | 2 +- .../db/migration/V15__orderCreation.sql | 2 +- .../controller/OrderControllerTest.java | 150 ++++++++++++----- .../mapFood/service/OrderItemServiceTest.java | 2 +- .../mapFood/service/OrderServiceTest.java | 46 +++-- .../com/groupsix/mapFood/MapFoodApiApp.class | Bin 735 -> 1024 bytes 23 files changed, 566 insertions(+), 380 deletions(-) diff --git a/pom.xml b/pom.xml index adab682..7e368ba 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,6 @@ org.springframework.boot spring-boot-maven-plugin - diff --git a/src/main/java/com/groupsix/mapFood/MapFoodApiApp.java b/src/main/java/com/groupsix/mapFood/MapFoodApiApp.java index 5a8b3d0..d14edf6 100644 --- a/src/main/java/com/groupsix/mapFood/MapFoodApiApp.java +++ b/src/main/java/com/groupsix/mapFood/MapFoodApiApp.java @@ -1,13 +1,23 @@ -package com.groupsix.mapFood; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class MapFoodApiApp { - - public static void main (String[] args) { - SpringApplication.run(MapFoodApiApp.class, args); - } - -} +package com.groupsix.mapFood; + +import java.util.TimeZone; + +import javax.annotation.PostConstruct; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MapFoodApiApp { + + public static void main (String[] args) { + SpringApplication.run(MapFoodApiApp.class, args); + } + + @PostConstruct + void started() { + TimeZone.setDefault(TimeZone.getTimeZone("America/Sao_Paulo")); + } + + +} diff --git a/src/main/java/com/groupsix/mapFood/controller/OrderController.java b/src/main/java/com/groupsix/mapFood/controller/OrderController.java index dfac6c1..c2aff56 100644 --- a/src/main/java/com/groupsix/mapFood/controller/OrderController.java +++ b/src/main/java/com/groupsix/mapFood/controller/OrderController.java @@ -50,13 +50,4 @@ public ResponseEntity listRestaurantOrders(@PathVariable Integer id){ } } - @GetMapping("/restaurant/report/{id}") - public ResponseEntity listInformations(@PathVariable Integer id){ - if(orderService.informationsRestaurant(id).isEmpty()){ - return ResponseEntity.ok("Você ainda não tem pedidos :("); - }else{ - return ResponseEntity.ok(orderService.informationsRestaurant(id)); - } - - } } diff --git a/src/main/java/com/groupsix/mapFood/entity/OrderEntity.java b/src/main/java/com/groupsix/mapFood/entity/OrderEntity.java index 18c66ec..7107eda 100644 --- a/src/main/java/com/groupsix/mapFood/entity/OrderEntity.java +++ b/src/main/java/com/groupsix/mapFood/entity/OrderEntity.java @@ -5,10 +5,8 @@ import javax.persistence.*; -@Entity(name = "orders") - @Table(name= "orders") - +@Entity(name = "orders") public class OrderEntity { @Id diff --git a/src/main/java/com/groupsix/mapFood/exception/CustomerTooFarException.java b/src/main/java/com/groupsix/mapFood/exception/CustomerTooFarException.java index dfc4e3b..5f11935 100644 --- a/src/main/java/com/groupsix/mapFood/exception/CustomerTooFarException.java +++ b/src/main/java/com/groupsix/mapFood/exception/CustomerTooFarException.java @@ -2,7 +2,9 @@ public class CustomerTooFarException extends Exception { - public CustomerTooFarException() { + private static final long serialVersionUID = 1L; + + public CustomerTooFarException() { super("The customer is too far from the restaurant."); } } diff --git a/src/main/java/com/groupsix/mapFood/exception/DiferentRestaurantException.java b/src/main/java/com/groupsix/mapFood/exception/DiferentRestaurantException.java index 913dcce..5842770 100644 --- a/src/main/java/com/groupsix/mapFood/exception/DiferentRestaurantException.java +++ b/src/main/java/com/groupsix/mapFood/exception/DiferentRestaurantException.java @@ -2,7 +2,9 @@ public class DiferentRestaurantException extends Exception { - public DiferentRestaurantException() { + private static final long serialVersionUID = 1L; + + public DiferentRestaurantException() { super("Not all items in the order are from the same restaurant."); } } diff --git a/src/main/java/com/groupsix/mapFood/exception/ItemsPriceException.java b/src/main/java/com/groupsix/mapFood/exception/ItemsPriceException.java index df0b8dd..ebc2369 100644 --- a/src/main/java/com/groupsix/mapFood/exception/ItemsPriceException.java +++ b/src/main/java/com/groupsix/mapFood/exception/ItemsPriceException.java @@ -2,7 +2,9 @@ public class ItemsPriceException extends Exception { - public ItemsPriceException() { + private static final long serialVersionUID = 1L; + + public ItemsPriceException() { super("Quantity of items and individual price does not match item total."); } } diff --git a/src/main/java/com/groupsix/mapFood/exception/TotalPriceException.java b/src/main/java/com/groupsix/mapFood/exception/TotalPriceException.java index 68386d2..b40a10d 100644 --- a/src/main/java/com/groupsix/mapFood/exception/TotalPriceException.java +++ b/src/main/java/com/groupsix/mapFood/exception/TotalPriceException.java @@ -2,7 +2,9 @@ public class TotalPriceException extends Exception { - public TotalPriceException() { + private static final long serialVersionUID = 1L; + + public TotalPriceException() { super("Total sum of items prices does not match order total price."); } } diff --git a/src/main/java/com/groupsix/mapFood/factory/OrderFactory.java b/src/main/java/com/groupsix/mapFood/factory/OrderFactory.java index b235958..667ab03 100644 --- a/src/main/java/com/groupsix/mapFood/factory/OrderFactory.java +++ b/src/main/java/com/groupsix/mapFood/factory/OrderFactory.java @@ -1,24 +1,48 @@ package com.groupsix.mapFood.factory; -import com.groupsix.mapFood.entity.OrderEntity; -import com.groupsix.mapFood.pojo.Order; +import java.util.List; + import org.springframework.stereotype.Component; -import java.util.stream.Collector; -import java.util.stream.Collectors; +import com.groupsix.mapFood.entity.CustomerEntity; +import com.groupsix.mapFood.entity.OrderDeliveryEntity; +import com.groupsix.mapFood.entity.OrderEntity; +import com.groupsix.mapFood.entity.OrderItemEntity; +import com.groupsix.mapFood.entity.RestaurantEntity; +import com.groupsix.mapFood.pojo.Order; @Component public class OrderFactory { - public Order getInstance(OrderEntity orderEntity){ - Order order = new Order(); - order.setId(orderEntity.getId()); - order.setCustomerId(orderEntity.getCustomer().getId()); - order.setRestaurantId(orderEntity.getRestaurant().getId()); - order.setTotal(orderEntity.getTotal()); + public OrderEntity fromDTO(final Order order, List orderItemsEntities, + final OrderDeliveryEntity orderDeliveryEntity, RestaurantEntity restaurantEntity, + CustomerEntity customerEntity) { + final OrderEntity newOrder = new OrderEntity(); + + orderItemsEntities.stream().forEach(o -> { + o.setOrder(newOrder); + }); + + orderDeliveryEntity.setOrder(newOrder); + + newOrder.setRestaurant(restaurantEntity); + newOrder.setCustomer(customerEntity); + newOrder.setOrderItems(orderItemsEntities); + newOrder.setTotal(order.getTotal()); + newOrder.setOrderDelivery(orderDeliveryEntity); + + return newOrder; + } + + public Order getInstance(OrderEntity orderEntity){ + Order order = new Order(); + order.setId(orderEntity.getId()); + order.setCustomerId(orderEntity.getCustomer().getId()); + order.setRestaurantId(orderEntity.getRestaurant().getId()); + order.setTotal(orderEntity.getTotal()); - return order; + return order; - } -} + } +} \ No newline at end of file diff --git a/src/main/java/com/groupsix/mapFood/pojo/CacheMotoboyOrder.java b/src/main/java/com/groupsix/mapFood/pojo/CacheMotoboyOrder.java index 7b49ea9..e2e89b4 100644 --- a/src/main/java/com/groupsix/mapFood/pojo/CacheMotoboyOrder.java +++ b/src/main/java/com/groupsix/mapFood/pojo/CacheMotoboyOrder.java @@ -1,5 +1,52 @@ -package com.groupsix.mapFood.pojo; - -public class CacheMotoboyOrder { - -} +package com.groupsix.mapFood.pojo; + +import java.sql.Timestamp; + +public class CacheMotoboyOrder { + + private Integer id; + private Integer restaurantId; + private CacheDestination cacheDestination; + private Timestamp timeToMotoboyArrivesAtRestaurant; + private Timestamp timeToDelivery; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getRestaurantId() { + return restaurantId; + } + + public void setRestaurantId(Integer restaurantId) { + this.restaurantId = restaurantId; + } + + public CacheDestination getCacheDestination() { + return cacheDestination; + } + + public void setCacheDestination(CacheDestination cacheDestination) { + this.cacheDestination = cacheDestination; + } + + public Timestamp getTimeToMotoboyArrivesAtRestaurant() { + return timeToMotoboyArrivesAtRestaurant; + } + + public void setTimeToMotoboyArrivesAtRestaurant(Timestamp timeToMotoboyArrivesAtRestaurant) { + this.timeToMotoboyArrivesAtRestaurant = timeToMotoboyArrivesAtRestaurant; + } + + public Timestamp getTimeToDelivery() { + return timeToDelivery; + } + + public void setTimeToDelivery(Timestamp timeToDelivery) { + this.timeToDelivery = timeToDelivery; + } +} diff --git a/src/main/java/com/groupsix/mapFood/pojo/Order.java b/src/main/java/com/groupsix/mapFood/pojo/Order.java index f3d26ff..67fefe9 100644 --- a/src/main/java/com/groupsix/mapFood/pojo/Order.java +++ b/src/main/java/com/groupsix/mapFood/pojo/Order.java @@ -1,61 +1,57 @@ -package com.groupsix.mapFood.pojo; - -import com.groupsix.mapFood.entity.OrderItemEntity; - -import javax.validation.constraints.NotNull; -import java.util.List; - -public class Order { - - private Integer id; - @NotNull - private Integer customerId; - @NotNull - private Integer restaurantId; - @NotNull - private Integer total; - @NotNull - private List orderItems; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public Integer getCustomerId() { - return customerId; - } - - public void setCustomerId(Integer customerId) { - this.customerId = customerId; - } - - public Integer getRestaurantId() { - return restaurantId; - } - - public void setRestaurantId(Integer restaurantId) { - this.restaurantId = restaurantId; - } - - public Integer getTotal() { - return total; - } - - public void setTotal(Integer total) { - this.total = total; - } - - public List getOrderItems() { - return orderItems; - } - - public void setOrderItems(List orderItems) { - this.orderItems = orderItems; - } - - -} +package com.groupsix.mapFood.pojo; + +import javax.validation.constraints.NotNull; +import java.util.List; + +public class Order { + + private Integer id; + @NotNull + private Integer customerId; + @NotNull + private Integer restaurantId; + @NotNull + private Integer total; + @NotNull + private List orderItems; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getCustomerId() { + return customerId; + } + + public void setCustomerId(Integer customerId) { + this.customerId = customerId; + } + + public Integer getRestaurantId() { + return restaurantId; + } + + public void setRestaurantId(Integer restaurantId) { + this.restaurantId = restaurantId; + } + + public Integer getTotal() { + return total; + } + + public void setTotal(Integer total) { + this.total = total; + } + + public List getOrderItems() { + return orderItems; + } + + public void setOrderItems(List orderItems) { + this.orderItems = orderItems; + } +} diff --git a/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java b/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java index 56a7eec..02b51fa 100644 --- a/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java +++ b/src/main/java/com/groupsix/mapFood/repository/OrderRepository.java @@ -1,21 +1,15 @@ package com.groupsix.mapFood.repository; -import com.groupsix.mapFood.pojo.Order; -import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; -import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import com.groupsix.mapFood.entity.OrderEntity; import java.util.List; -import java.util.Set; @Repository -public interface OrderRepository extends JpaRepository { - - +public interface OrderRepository extends CrudRepository { List findByCustomer_Id(Integer id); List findByRestaurant_Id(Integer id); @@ -26,7 +20,4 @@ public interface OrderRepository extends JpaRepository { @Query(value = "SELECT SUM(total) FROM orders where restaurant_id = ?1", nativeQuery = true) int countTotalRevenue(Integer id); - - - } diff --git a/src/main/java/com/groupsix/mapFood/service/CacheService.java b/src/main/java/com/groupsix/mapFood/service/CacheService.java index 8410862..906bc8d 100644 --- a/src/main/java/com/groupsix/mapFood/service/CacheService.java +++ b/src/main/java/com/groupsix/mapFood/service/CacheService.java @@ -1,32 +1,40 @@ -package com.groupsix.mapFood.service; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import java.lang.reflect.Type; -import com.google.gson.reflect.TypeToken; - -import com.google.gson.Gson; -import com.groupsix.mapFood.entity.CacheEntity; -import com.groupsix.mapFood.pojo.CacheMotoboy; -import com.groupsix.mapFood.repository.CacheRepository; - - - -@Service -public class CacheService { - - private static final int CACHE_ID = 1; - - @Autowired - private CacheRepository cacheRepository; - - public List getCache() { - CacheEntity entity = cacheRepository.findById(CACHE_ID).get(); - - Type listType = new TypeToken>(){}.getType(); - return new Gson().fromJson(entity.getData(), listType); - } -} +package com.groupsix.mapFood.service; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import java.lang.reflect.Type; +import com.google.gson.reflect.TypeToken; + +import com.google.gson.Gson; +import com.groupsix.mapFood.entity.CacheEntity; +import com.groupsix.mapFood.pojo.CacheMotoboy; +import com.groupsix.mapFood.repository.CacheRepository; + + + +@Service +public class CacheService { + + private static final int CACHE_ID = 1; + + @Autowired + private CacheRepository cacheRepository; + + public List getCache() { + CacheEntity entity = cacheRepository.findById(CACHE_ID).get(); + + Type listType = new TypeToken>(){}.getType(); + return new Gson().fromJson(entity.getData(), listType); + } + + public void updateCache(List cacheMotoboys) { + CacheEntity entity = new CacheEntity(); + entity.setId(CACHE_ID); + entity.setData(new Gson().toJson(cacheMotoboys)); + + cacheRepository.save(entity); + } +} diff --git a/src/main/java/com/groupsix/mapFood/service/OrderDeliveryService.java b/src/main/java/com/groupsix/mapFood/service/OrderDeliveryService.java index e9b9dbe..d2d6cfb 100644 --- a/src/main/java/com/groupsix/mapFood/service/OrderDeliveryService.java +++ b/src/main/java/com/groupsix/mapFood/service/OrderDeliveryService.java @@ -1,54 +1,105 @@ -package com.groupsix.mapFood.service; - -import java.sql.Timestamp; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.google.maps.model.LatLng; -import com.groupsix.mapFood.entity.OrderDeliveryEntity; -import com.groupsix.mapFood.entity.OrderEntity; -import com.groupsix.mapFood.util.TimestampUtil; - -@Service -public class OrderDeliveryService { - - @Autowired - private MotoboyService motoboyService; +package com.groupsix.mapFood.service; + +import java.sql.Timestamp; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.groupsix.mapFood.entity.CustomerEntity; +import com.groupsix.mapFood.entity.MotoboyEntity; +import com.groupsix.mapFood.entity.OrderDeliveryEntity; +import com.groupsix.mapFood.entity.OrderEntity; +import com.groupsix.mapFood.entity.RestaurantEntity; +import com.groupsix.mapFood.pojo.CacheDestination; +import com.groupsix.mapFood.pojo.CacheMotoboy; +import com.groupsix.mapFood.pojo.CacheMotoboyDistance; +import com.groupsix.mapFood.pojo.CacheMotoboyOrder; +import com.groupsix.mapFood.repository.OrderRepository; +import com.groupsix.mapFood.timestamp.CalculateTimestamp; +import com.groupsix.mapFood.util.TimestampUtil; + +@Service +public class OrderDeliveryService { - @Autowired - private GoogleMapsService googleMapsService; - - public OrderDeliveryEntity create(OrderEntity orderEntity) { - OrderDeliveryEntity orderDeliveryEntity = new OrderDeliveryEntity(); - - orderDeliveryEntity.setOrder(orderEntity); - orderDeliveryEntity.setDestinationLat(orderEntity.getCustomer().getLat()); - orderDeliveryEntity.setDestinationLon(orderEntity.getCustomer().getLon()); - - // busca o motoboy mais proximo do restaurant - orderDeliveryEntity.setMotoboy(motoboyService.findNearby( - orderDeliveryEntity.getOrder().getRestaurant().getLat(), - orderDeliveryEntity.getOrder().getRestaurant().getLon()).get(0)); - - Timestamp timeToRestaurant = estimateTimeToRestaurant(orderDeliveryEntity); - - System.out.println("Motoboy: " + orderDeliveryEntity.getMotoboy().getId()); - System.out.println("Solicitado motoboy " + new Timestamp(System.currentTimeMillis())); - System.out.println("Até o restaurant " + timeToRestaurant); - - orderDeliveryEntity.setEstimatedTimeToRestaurant(timeToRestaurant); - - return orderDeliveryEntity; - } - - private Timestamp estimateTimeToRestaurant(OrderDeliveryEntity orderDeliveryEntity) { - LatLng start = new LatLng(orderDeliveryEntity.getMotoboy().getLat(), orderDeliveryEntity.getMotoboy().getLon()); - LatLng end = new LatLng(orderDeliveryEntity.getOrder().getRestaurant().getLat(), orderDeliveryEntity.getOrder().getRestaurant().getLon()); - - long now = System.currentTimeMillis(); - Timestamp time = new Timestamp(now); - - return TimestampUtil.addSeconds(googleMapsService.timeToReach(start, end), time); - } -} + @Autowired + private CacheService cacheService; + + @Autowired + private CalculateTimestamp calculateTimestamp; + + @Autowired + private OrderRepository orderRepository; + + @Autowired + private CacheSearchMotoboyService cacheSearchMotoboyService; + + @Autowired + private TimestampUtil timestampUtil; + + + public OrderDeliveryEntity create(CustomerEntity customerEntity) { + OrderDeliveryEntity orderDeliveryEntity = new OrderDeliveryEntity(); + + orderDeliveryEntity.setDestinationLat(customerEntity.getLat()); + orderDeliveryEntity.setDestinationLon(customerEntity.getLon()); + + return orderDeliveryEntity; + } + + public void searchMotoboy(OrderEntity orderEntity) { + + RestaurantEntity restaurantEntity = orderEntity.getRestaurant(); + List cache = cacheService.getCache(); + CacheMotoboyDistance cachedMotoboy = cacheSearchMotoboyService.getNearestMotoboy(restaurantEntity, cache); + + MotoboyEntity motoboyEntity = new MotoboyEntity(); + motoboyEntity.setId(cachedMotoboy.getCacheMotoboy().getId()); + motoboyEntity.setLat(cachedMotoboy.getCacheMotoboy().getLat()); + motoboyEntity.setLon(cachedMotoboy.getCacheMotoboy().getLon()); + orderEntity.getOrderDelivery().setMotoboy(motoboyEntity); + + orderEntity.getOrderDelivery().setEstimatedTimeToRestaurant(cachedMotoboy.getTimestampArrivesAtRestaurant()); + + Timestamp timeToOrderLeavesTheRestaurant = verifyTimeToOrderLeavesTheRestaurant( + cachedMotoboy.getTimestampArrivesAtRestaurant()); + + Timestamp timeToDelivery = calculateTimestamp.calculateEstimatedTimeToDelivery(orderEntity, + cachedMotoboy.getCacheMotoboy(), timeToOrderLeavesTheRestaurant); + + orderEntity.setEstimatedTimeToDelivery(timeToDelivery); + + CacheMotoboyOrder cacheMotoboyOrder = createCacheMotoboyOrder(orderEntity, restaurantEntity, + cachedMotoboy.getTimestampArrivesAtRestaurant(), timeToDelivery); + + cachedMotoboy.getCacheMotoboy().getOrders().add(cacheMotoboyOrder); + cacheService.updateCache(cache); + + orderRepository.save(orderEntity); + } + + private CacheMotoboyOrder createCacheMotoboyOrder(OrderEntity orderEntity, RestaurantEntity restaurantEntity, + Timestamp timeToMotoboyArriveAtRestaurant, Timestamp timeToDelivery) { + CacheMotoboyOrder cacheMotoboyOrder = new CacheMotoboyOrder(); + cacheMotoboyOrder.setId(orderEntity.getId()); + cacheMotoboyOrder.setRestaurantId(restaurantEntity.getId()); + CacheDestination cacheDestination = new CacheDestination(); + cacheDestination.setLat(orderEntity.getCustomer().getLat()); + cacheDestination.setLon(orderEntity.getCustomer().getLon()); + cacheMotoboyOrder.setCacheDestination(cacheDestination); + cacheMotoboyOrder.setTimeToMotoboyArrivesAtRestaurant(timeToMotoboyArriveAtRestaurant); + cacheMotoboyOrder.setTimeToDelivery(timeToDelivery); + return cacheMotoboyOrder; + } + + private Timestamp verifyTimeToOrderLeavesTheRestaurant(Timestamp estimatedTimeToRestaurant) { + Timestamp tenMinutes = timestampUtil.addTenMinutesFromNow(); + + if (estimatedTimeToRestaurant.before(tenMinutes)) { + return tenMinutes; + } else { + return estimatedTimeToRestaurant; + } + } + +} diff --git a/src/main/java/com/groupsix/mapFood/service/OrderItemService.java b/src/main/java/com/groupsix/mapFood/service/OrderItemService.java index 265d090..3b53464 100644 --- a/src/main/java/com/groupsix/mapFood/service/OrderItemService.java +++ b/src/main/java/com/groupsix/mapFood/service/OrderItemService.java @@ -1,41 +1,39 @@ -package com.groupsix.mapFood.service; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.groupsix.mapFood.entity.OrderEntity; -import com.groupsix.mapFood.entity.OrderItemEntity; -import com.groupsix.mapFood.entity.ProductEntity; -import com.groupsix.mapFood.factory.OrderItemFactory; -import com.groupsix.mapFood.pojo.OrderItem; -import com.groupsix.mapFood.repository.ProductRepository; - -@Service -public class OrderItemService { - - @Autowired - private OrderItemFactory orderItemFactory; - - @Autowired - private ProductRepository productRepository; - - public List getOrderItems(final List orderItems, OrderEntity order) { - - List orderItemsEntities = new ArrayList<>(); - - orderItems.stream().forEach(orderItem -> { - - ProductEntity product = productRepository.getOne(orderItem.getProductId()); - - final OrderItemEntity orderItemEntity = orderItemFactory.fromDTO(orderItem, product); - orderItemEntity.setOrder(order); - orderItemsEntities.add(orderItemEntity); - }); - - return orderItemsEntities; - } - -} +package com.groupsix.mapFood.service; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.groupsix.mapFood.entity.OrderItemEntity; +import com.groupsix.mapFood.entity.ProductEntity; +import com.groupsix.mapFood.factory.OrderItemFactory; +import com.groupsix.mapFood.pojo.OrderItem; +import com.groupsix.mapFood.repository.ProductRepository; + +@Service +public class OrderItemService { + + @Autowired + private OrderItemFactory orderItemFactory; + + @Autowired + private ProductRepository productRepository; + + public List getOrderItems(final List orderItems) { + + List orderItemsEntities = new ArrayList<>(); + + orderItems.stream().forEach(orderItem -> { + + ProductEntity product = productRepository.getOne(orderItem.getProductId()); + + final OrderItemEntity orderItemEntity = orderItemFactory.fromDTO(orderItem, product); + orderItemsEntities.add(orderItemEntity); + }); + + return orderItemsEntities; + } + +} diff --git a/src/main/java/com/groupsix/mapFood/service/OrderService.java b/src/main/java/com/groupsix/mapFood/service/OrderService.java index 11550d6..1122b0b 100644 --- a/src/main/java/com/groupsix/mapFood/service/OrderService.java +++ b/src/main/java/com/groupsix/mapFood/service/OrderService.java @@ -1,15 +1,11 @@ package com.groupsix.mapFood.service; -import java.sql.Timestamp; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.StreamSupport; -import com.google.maps.model.LatLng; import com.groupsix.mapFood.entity.*; import com.groupsix.mapFood.exception.CustomerTooFarException; import com.groupsix.mapFood.exception.DiferentRestaurantException; @@ -22,96 +18,61 @@ import org.springframework.stereotype.Service; import com.groupsix.mapFood.pojo.Order; import com.groupsix.mapFood.repository.OrderRepository; -import com.groupsix.mapFood.util.TimestampUtil; @Service public class OrderService { @Autowired private OrderValidation orderValidation; - + @Autowired private CustomerService customerService; - + @Autowired private OrderItemService orderItemService; - + @Autowired private OrderDeliveryService orderDeliveryService; - + @Autowired private OrderRepository orderRepository; - + @Autowired private RestaurantService restaurantService; - - @Autowired - private GoogleMapsService googleMapsService; @Autowired private OrderFactory orderFactory; - - public Order createOrder(final Order order) throws TotalPriceException, ItemsPriceException, DiferentRestaurantException, CustomerTooFarException { + + public Order createOrder(final Order order) + throws TotalPriceException, ItemsPriceException, DiferentRestaurantException, CustomerTooFarException { orderValidation.verifyTotalOrder(order); orderValidation.verifyCustomerAndRestaurantDistance(order); - OrderEntity orderEntity = convertToEntity(order); - - final List orderItemsEntities = orderItemService.getOrderItems(order.getOrderItems(), orderEntity); + final List orderItemsEntities = orderItemService.getOrderItems(order.getOrderItems()); orderValidation.verifyPricesFromItems(orderItemsEntities); orderValidation.verifyItemsFromSameRestaurant(orderItemsEntities, order); - - orderEntity.setOrderDelivery(orderDeliveryService.create(orderEntity)); - - Timestamp outTime = verifyOutTime(orderEntity.getOrderDelivery().getEstimatedTimeToRestaurant()); - - Timestamp timeToDelivery = estimateTimeToDelivery(orderEntity, outTime); - - System.out.println("Sai do restaurant " + outTime); - System.out.println("Entrega estimada " + timeToDelivery); - System.out.println("\n\n"); - - orderEntity.setEstimatedTimeToDelivery(timeToDelivery); - - orderRepository.save(orderEntity); - return order; - } - - private Timestamp verifyOutTime(Timestamp estimatedTimeToRestaurant) { - long time = System.currentTimeMillis(); - Timestamp tenMinutes = TimestampUtil.addSeconds(600L, new Timestamp(time)); - - if (estimatedTimeToRestaurant.before(tenMinutes)) { - return tenMinutes; - } else { - return estimatedTimeToRestaurant; - } - } - private Timestamp estimateTimeToDelivery(OrderEntity orderEntity, Timestamp outTime) { - LatLng start = new LatLng(orderEntity.getRestaurant().getLat(), orderEntity.getRestaurant().getLon()); - LatLng end = new LatLng(orderEntity.getCustomer().getLat(), orderEntity.getCustomer().getLon()); - - return TimestampUtil.addSeconds(googleMapsService.timeToReach(start, end), outTime); - } - - public OrderEntity convertToEntity(Order order) { - OrderEntity entity = new OrderEntity(); - entity.setId(order.getId()); - entity.setCustomer(customerService.findById(order.getCustomerId()).get()); - entity.setOrderItems(orderItemService.getOrderItems(order.getOrderItems(), entity)); - entity.setRestaurant(restaurantService.findById(order.getRestaurantId()).get()); - entity.setTotal(order.getTotal()); - return entity; + CustomerEntity customerEntity = customerService.findById(order.getCustomerId()).get(); + RestaurantEntity restaurantEntity = restaurantService.findById(order.getRestaurantId()).get(); + OrderDeliveryEntity orderDeliveryEntity = orderDeliveryService.create(customerEntity); + + OrderEntity orderEntity = orderFactory.fromDTO(order, orderItemsEntities, orderDeliveryEntity, restaurantEntity, + customerEntity); + + orderEntity = orderRepository.save(orderEntity); + + orderDeliveryService.searchMotoboy(orderEntity); + + return order; } - public List listOrder(Integer id) { + public List listOrder(Integer id) { return StreamSupport.stream(orderRepository.findByCustomer_Id(id).spliterator(), false).map(orderFactory::getInstance).collect(Collectors.toList()); - } + } - public List listRestaurantOrder(Integer id){ + public List listRestaurantOrder(Integer id){ return StreamSupport.stream(orderRepository.findByRestaurant_Id(id).spliterator(), false).map(orderFactory::getInstance).collect(Collectors.toList()); } @@ -130,4 +91,5 @@ public Map informationsRestaurant(Integer id){ return map; } + } diff --git a/src/main/java/com/groupsix/mapFood/util/TimestampUtil.java b/src/main/java/com/groupsix/mapFood/util/TimestampUtil.java index 073656c..24cb9c6 100644 --- a/src/main/java/com/groupsix/mapFood/util/TimestampUtil.java +++ b/src/main/java/com/groupsix/mapFood/util/TimestampUtil.java @@ -1,14 +1,31 @@ -package com.groupsix.mapFood.util; - -import java.sql.Timestamp; -import java.util.Calendar; - -public class TimestampUtil { - - public static Timestamp addSeconds(Long sec, Timestamp time) { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time.getTime()); - cal.add(Calendar.SECOND, sec.intValue()); - return new Timestamp(cal.getTime().getTime()); - } -} +package com.groupsix.mapFood.util; + +import java.sql.Timestamp; +import java.util.Calendar; + +import org.springframework.stereotype.Component; + +@Component +public class TimestampUtil { + + private static final long TEN_MINUTES = 600L; + + public Timestamp addSeconds(Long sec, Timestamp time) { + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(time.getTime()); + cal.add(Calendar.SECOND, sec.intValue()); + return new Timestamp(cal.getTime().getTime()); + } + + public Timestamp addSecondsFromNow(Long sec) { + + long now = System.currentTimeMillis(); + Timestamp time = new Timestamp(now); + + return addSeconds(sec, time); + } + + public Timestamp addTenMinutesFromNow() { + return addSecondsFromNow(TEN_MINUTES); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 9ca21be..278a59f 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,7 +1,7 @@ ## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) spring.datasource.url=jdbc:mysql://localhost:3306/mapFood?useSSL=false&useTimezone=true&serverTimezone=UTC&allowPublicKeyRetrieval=true spring.datasource.username=root -spring.datasource.password=vertrigo +spring.datasource.password= spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver ## Hibernate Properties # The SQL dialect makes Hibernate generate better SQL for the chosen database diff --git a/src/main/resources/db/migration/V15__orderCreation.sql b/src/main/resources/db/migration/V15__orderCreation.sql index 7740e35..55cb22b 100644 --- a/src/main/resources/db/migration/V15__orderCreation.sql +++ b/src/main/resources/db/migration/V15__orderCreation.sql @@ -44,7 +44,7 @@ CREATE TABLE `mapfood`.`order_item` ( REFERENCES `mapfood`.`product` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION); - + CREATE TABLE `mapfood`.`order_delivery` ( `id` INT NOT NULL AUTO_INCREMENT, `order_id` INT NOT NULL, diff --git a/src/test/java/com/groupsix/mapFood/controller/OrderControllerTest.java b/src/test/java/com/groupsix/mapFood/controller/OrderControllerTest.java index e92d34e..e3d2479 100644 --- a/src/test/java/com/groupsix/mapFood/controller/OrderControllerTest.java +++ b/src/test/java/com/groupsix/mapFood/controller/OrderControllerTest.java @@ -1,44 +1,106 @@ -package com.groupsix.mapFood.controller; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.when; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; - -import com.groupsix.mapFood.pojo.Order; -import com.groupsix.mapFood.service.OrderService; -import org.springframework.validation.BeanPropertyBindingResult; -import org.springframework.validation.BindingResult; - -@RunWith(MockitoJUnitRunner.class) -public class OrderControllerTest { - - @Mock - private OrderService orderService; - - @InjectMocks - private OrderController controller; - - @Test - public void testCreateOrder() { - final Order order = new Order(); - final BindingResult validator = new BeanPropertyBindingResult(order, "order"); - - try { - when(orderService.createOrder(order)).thenReturn(order); - } catch (Exception e) { - e.printStackTrace(); - } - - final ResponseEntity response = controller.createOrder(order, validator); - - assertEquals(HttpStatus.CREATED, response.getStatusCode()); - assertEquals(order, response.getBody()); - } -} +package com.groupsix.mapFood.controller; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import com.groupsix.mapFood.exception.CustomerTooFarException; +import com.groupsix.mapFood.exception.DiferentRestaurantException; +import com.groupsix.mapFood.exception.ItemsPriceException; +import com.groupsix.mapFood.exception.TotalPriceException; +import com.groupsix.mapFood.pojo.Order; +import com.groupsix.mapFood.service.OrderService; +import org.springframework.validation.BindingResult; + +@RunWith(MockitoJUnitRunner.class) +public class OrderControllerTest { + + @Mock + private OrderService orderService; + + @InjectMocks + private OrderController controller; + + @Mock + private BindingResult validator; + + @Test + public void testCreateOrder() throws Exception { + final Order order = new Order(); + + when(orderService.createOrder(order)).thenReturn(order); + when(validator.hasErrors()).thenReturn(false); + + final ResponseEntity response = controller.createOrder(order, validator); + + assertEquals(HttpStatus.CREATED, response.getStatusCode()); + assertEquals(order, response.getBody()); + } + + @Test + public void testCreateOrderWithInvalidData() throws Exception { + final Order order = new Order(); + + when(orderService.createOrder(order)).thenReturn(order); + when(validator.hasErrors()).thenReturn(true); + + final ResponseEntity response = controller.createOrder(order, validator); + + assertEquals(HttpStatus.UNPROCESSABLE_ENTITY, response.getStatusCode()); + } + + @Test + public void testCreateOrderWithInvalidTotalPrice() throws Exception { + final Order order = new Order(); + + when(orderService.createOrder(order)).thenThrow(new TotalPriceException()); + + final ResponseEntity response = controller.createOrder(order, validator); + + assertEquals(HttpStatus.UNPROCESSABLE_ENTITY, response.getStatusCode()); + assertEquals("Total sum of items prices does not match order total price.", response.getBody()); + } + + @Test + public void testCreateOrderWithInvalidItemsPriceException() throws Exception { + final Order order = new Order(); + + when(orderService.createOrder(order)).thenThrow(new ItemsPriceException()); + + final ResponseEntity response = controller.createOrder(order, validator); + + assertEquals(HttpStatus.UNPROCESSABLE_ENTITY, response.getStatusCode()); + assertEquals("Quantity of items and individual price does not match item total.", response.getBody()); + } + + @Test + public void testCreateOrderWithDiferentRestaurantException() throws Exception { + final Order order = new Order(); + + when(orderService.createOrder(order)).thenThrow(new DiferentRestaurantException()); + + final ResponseEntity response = controller.createOrder(order, validator); + + assertEquals(HttpStatus.UNPROCESSABLE_ENTITY, response.getStatusCode()); + assertEquals("Not all items in the order are from the same restaurant.", response.getBody()); + } + + @Test + public void testCreateOrderWithCustomerTooFarException() throws Exception { + final Order order = new Order(); + + when(orderService.createOrder(order)).thenThrow(new CustomerTooFarException()); + + final ResponseEntity response = controller.createOrder(order, validator); + + assertEquals(HttpStatus.UNPROCESSABLE_ENTITY, response.getStatusCode()); + assertEquals("The customer is too far from the restaurant.", response.getBody()); + } +} diff --git a/src/test/java/com/groupsix/mapFood/service/OrderItemServiceTest.java b/src/test/java/com/groupsix/mapFood/service/OrderItemServiceTest.java index f76ae6d..e8ebc97 100644 --- a/src/test/java/com/groupsix/mapFood/service/OrderItemServiceTest.java +++ b/src/test/java/com/groupsix/mapFood/service/OrderItemServiceTest.java @@ -55,7 +55,7 @@ public void testGetOrderItems() { final OrderItemEntity orderItemEntity2 = new OrderItemEntity(); when(orderItemFactory.fromDTO(item2, product2)).thenReturn(orderItemEntity2); - final List orderItemsEntities = service.getOrderItems(orderItems, null); + final List orderItemsEntities = service.getOrderItems(orderItems); assertEquals(2, orderItemsEntities.size()); assertEquals(orderItemEntity1, orderItemsEntities.get(0)); diff --git a/src/test/java/com/groupsix/mapFood/service/OrderServiceTest.java b/src/test/java/com/groupsix/mapFood/service/OrderServiceTest.java index 9041b61..f738a15 100644 --- a/src/test/java/com/groupsix/mapFood/service/OrderServiceTest.java +++ b/src/test/java/com/groupsix/mapFood/service/OrderServiceTest.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import org.junit.Test; import org.junit.runner.RunWith; @@ -13,11 +14,16 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import com.groupsix.mapFood.entity.CustomerEntity; +import com.groupsix.mapFood.entity.OrderDeliveryEntity; import com.groupsix.mapFood.entity.OrderEntity; import com.groupsix.mapFood.entity.OrderItemEntity; +import com.groupsix.mapFood.entity.RestaurantEntity; +import com.groupsix.mapFood.factory.OrderFactory; import com.groupsix.mapFood.pojo.Order; import com.groupsix.mapFood.pojo.OrderItem; import com.groupsix.mapFood.repository.OrderRepository; +import com.groupsix.mapFood.validation.OrderValidation; @RunWith(MockitoJUnitRunner.class) public class OrderServiceTest { @@ -31,32 +37,50 @@ public class OrderServiceTest { @Mock private OrderDeliveryService orderDeliveryService; + @Mock + private CustomerService customerService; + + @Mock + private OrderFactory orderFactory; + + @Mock + private RestaurantService restaurantService; + + @Mock + private OrderValidation orderValidation; + @InjectMocks private OrderService service; @Test - public void testCreateOrder() { + public void testCreateOrder() throws Exception { final Order order = new Order(); order.setCustomerId(5); + order.setRestaurantId(10); final List orderItems = new ArrayList<>(); order.setOrderItems(orderItems); final List orderItemsEntities = new ArrayList<>(); + when(orderItemService.getOrderItems(orderItems)).thenReturn(orderItemsEntities); + + CustomerEntity customerEntity = new CustomerEntity(); + when(customerService.findById(5)).thenReturn(Optional.of(customerEntity)); - when(orderItemService.getOrderItems(orderItems, null)).thenReturn(orderItemsEntities); - // when(orderDeliveryService.getOrderDelivery(5)).thenReturn(orderDeliveryEntity); + RestaurantEntity restaurantEntity = new RestaurantEntity(); + when(restaurantService.findById(10)).thenReturn(Optional.of(restaurantEntity)); + + OrderDeliveryEntity orderDeliveryEntity = new OrderDeliveryEntity(); + when(orderDeliveryService.create(customerEntity)).thenReturn(orderDeliveryEntity); final OrderEntity newOrder = new OrderEntity(); - when(service.convertToEntity(order)).thenReturn(newOrder); - - try { - service.createOrder(order); - } catch (Exception e) { - e.printStackTrace(); - } - + when(orderFactory.fromDTO(order, orderItemsEntities, orderDeliveryEntity, restaurantEntity, customerEntity)).thenReturn(newOrder); + when(orderRepository.save(newOrder)).thenReturn(newOrder); + + service.createOrder(order); + verify(orderRepository, times(1)).save(newOrder); + verify(orderDeliveryService, times(1)).searchMotoboy(newOrder); } } diff --git a/target/classes/com/groupsix/mapFood/MapFoodApiApp.class b/target/classes/com/groupsix/mapFood/MapFoodApiApp.class index 2c5e5550e7cbfbb31d44b7f70871abe7336eb9ac..7c48f680d705af879e484679e305431e7ec42fec 100644 GIT binary patch delta 519 zcmZutyG{Z@6g{&D`(S?Z7B?69)m(E0~f zRuU8a0DEgc!_IgYVvxj1=AOCto_prZe1`87P4ZtSWHOR=wSkSPDB?Vax%g6;G zFJr~eyehIMcw1N({#Q1it6lROers~aaRnE)>zH-d6Z@{?iFT(Us{Tho+O72-Sh}~t ziXjDR@01zFs*VEI7-D-Zt8F*9dC1-KI`1@H8ATliN;=A@^zPZC!4MBFF+0L;nn!la zI&&S1A$nzrQC2GXexf^YGfu2BXr3hwtV>cC45`w8r1CNHkm%*X3W0%)Qq(9j2^nFy z@(lJw2MJM%kwGyEozD7@fbJxwC{;0y8KMQ#TZF;15|=7{gib~R8g)Q?nb;!{1u?{_ zo}eA3{~-X9BsrAZCb2+HjZgFu?jtg$w?mx-Sx^2ER53I)OTEDJ9HE5NAkO2rng)IV De(6*` delta 244 zcmYLD%L&3j6r2}LcC*G`{Kt4O7a<_Ih<7XSXc?BEErgWe$&(^z0X88vUFq0uzHOdJ27m0fq{re0DA7lH{+rSj) Date: Tue, 12 Feb 2019 12:40:41 -0200 Subject: [PATCH 7/7] all report and order --- .../mapFood/controller/ReportController.java | 29 ++ .../mapFood/pojo/CacheDestination.java | 23 ++ .../mapFood/pojo/CacheMotoboyDistance.java | 31 ++ .../service/CacheSearchMotoboyService.java | 92 +++++ .../mapFood/timestamp/CalculateTimestamp.java | 74 ++++ .../groupsix/mapFood/util/DistanceUtil.java | 19 + ...__orderEstimatedTimeToDeliveryNullable.sql | 2 + .../mapFood/factory/OrderFactoryTest.java | 50 +++ .../CacheSearchMotoboyServiceTest.java | 344 ++++++++++++++++++ .../service/OrderDeliveryServiceTest.java | 148 ++++++++ .../timestamp/CalculateTimestampTest.java | 153 ++++++++ .../validation/OrderValidationTest.java | 232 ++++++++++++ 12 files changed, 1197 insertions(+) create mode 100644 src/main/java/com/groupsix/mapFood/controller/ReportController.java create mode 100644 src/main/java/com/groupsix/mapFood/pojo/CacheDestination.java create mode 100644 src/main/java/com/groupsix/mapFood/pojo/CacheMotoboyDistance.java create mode 100644 src/main/java/com/groupsix/mapFood/service/CacheSearchMotoboyService.java create mode 100644 src/main/java/com/groupsix/mapFood/timestamp/CalculateTimestamp.java create mode 100644 src/main/java/com/groupsix/mapFood/util/DistanceUtil.java create mode 100644 src/main/resources/db/migration/V17__orderEstimatedTimeToDeliveryNullable.sql create mode 100644 src/test/java/com/groupsix/mapFood/factory/OrderFactoryTest.java create mode 100644 src/test/java/com/groupsix/mapFood/service/CacheSearchMotoboyServiceTest.java create mode 100644 src/test/java/com/groupsix/mapFood/service/OrderDeliveryServiceTest.java create mode 100644 src/test/java/com/groupsix/mapFood/timestamp/CalculateTimestampTest.java create mode 100644 src/test/java/com/groupsix/mapFood/validation/OrderValidationTest.java diff --git a/src/main/java/com/groupsix/mapFood/controller/ReportController.java b/src/main/java/com/groupsix/mapFood/controller/ReportController.java new file mode 100644 index 0000000..461e14b --- /dev/null +++ b/src/main/java/com/groupsix/mapFood/controller/ReportController.java @@ -0,0 +1,29 @@ +package com.groupsix.mapFood.controller; + + +import com.groupsix.mapFood.service.OrderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/report") +public class ReportController { + + @Autowired + private OrderService orderService; + + @GetMapping("/restaurant/{id}") + public ResponseEntity listInformations(@PathVariable Integer id){ + if(orderService.informationsRestaurant(id).isEmpty()){ + return ResponseEntity.ok("Você ainda não tem pedidos :("); + }else{ + return ResponseEntity.ok(orderService.informationsRestaurant(id)); + } + + } + +} diff --git a/src/main/java/com/groupsix/mapFood/pojo/CacheDestination.java b/src/main/java/com/groupsix/mapFood/pojo/CacheDestination.java new file mode 100644 index 0000000..8b3d03b --- /dev/null +++ b/src/main/java/com/groupsix/mapFood/pojo/CacheDestination.java @@ -0,0 +1,23 @@ +package com.groupsix.mapFood.pojo; + +public class CacheDestination { + + private Double lat; + private Double lon; + + public Double getLat() { + return lat; + } + + public void setLat(Double lat) { + this.lat = lat; + } + + public Double getLon() { + return lon; + } + + public void setLon(Double lon) { + this.lon = lon; + } +} diff --git a/src/main/java/com/groupsix/mapFood/pojo/CacheMotoboyDistance.java b/src/main/java/com/groupsix/mapFood/pojo/CacheMotoboyDistance.java new file mode 100644 index 0000000..55a90fa --- /dev/null +++ b/src/main/java/com/groupsix/mapFood/pojo/CacheMotoboyDistance.java @@ -0,0 +1,31 @@ +package com.groupsix.mapFood.pojo; + +import java.sql.Timestamp; + +public class CacheMotoboyDistance { + + private CacheMotoboy cacheMotoboy; + private Timestamp timestampArrivesAtRestaurant; + + public CacheMotoboy getCacheMotoboy() { + return cacheMotoboy; + } + + public void setCacheMotoboy(CacheMotoboy cacheMotoboy) { + this.cacheMotoboy = cacheMotoboy; + } + + public Timestamp getTimestampArrivesAtRestaurant() { + return timestampArrivesAtRestaurant; + } + + public void setTimestampArrivesAtRestaurant(Timestamp timestampArrivesAtRestaurant) { + this.timestampArrivesAtRestaurant = timestampArrivesAtRestaurant; + } + + public CacheMotoboyDistance(CacheMotoboy cacheMotoboy, Timestamp timestampArrivesAtRestaurant) { + super(); + this.cacheMotoboy = cacheMotoboy; + this.timestampArrivesAtRestaurant = timestampArrivesAtRestaurant; + } +} diff --git a/src/main/java/com/groupsix/mapFood/service/CacheSearchMotoboyService.java b/src/main/java/com/groupsix/mapFood/service/CacheSearchMotoboyService.java new file mode 100644 index 0000000..9c9961a --- /dev/null +++ b/src/main/java/com/groupsix/mapFood/service/CacheSearchMotoboyService.java @@ -0,0 +1,92 @@ +package com.groupsix.mapFood.service; + +import java.sql.Timestamp; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.groupsix.mapFood.entity.RestaurantEntity; +import com.groupsix.mapFood.pojo.CacheMotoboy; +import com.groupsix.mapFood.pojo.CacheMotoboyDistance; +import com.groupsix.mapFood.timestamp.CalculateTimestamp; +import com.groupsix.mapFood.util.DistanceUtil; +import com.groupsix.mapFood.util.TimestampUtil; + +@Service +public class CacheSearchMotoboyService { + + private static final int MAX_ORDERS_PER_MOTOBOY = 5; + private static final int LIMIT_MOTOBOYS_TO_QUERY_IN_GOOGLE = 3; + + @Autowired + private CalculateTimestamp calculateTimestamp; + + @Autowired + private TimestampUtil timestampUtil; + + public CacheMotoboyDistance getNearestMotoboy(RestaurantEntity restaurantEntity, List cache) { + + List cacheMotoboysWithSameRestaurant = searchForMotoboysDeliveringForSameRestaurant( + restaurantEntity, cache); + + if (cacheMotoboysWithSameRestaurant.size() != 0) { + + Timestamp tenMinutes = timestampUtil.addTenMinutesFromNow(); + // Filtro por motoboys que estão entregando no mesmo restaurante com menos de 5 + // pedidos e que + // vai chegar depois do novo pedido ficar pronto + Optional optionalCacheMotoboy = cacheMotoboysWithSameRestaurant.stream() + .filter(c -> c.getOrders().size() < MAX_ORDERS_PER_MOTOBOY + && c.getOrders().get(0).getTimeToMotoboyArrivesAtRestaurant().after(tenMinutes)) + .findFirst(); + if (optionalCacheMotoboy.isPresent()) { + return new CacheMotoboyDistance(optionalCacheMotoboy.get(), + optionalCacheMotoboy.get().getOrders().get(0).getTimeToMotoboyArrivesAtRestaurant()); + } + } + + return getNearestMotoboyWithoutOrders(restaurantEntity, cache, cacheMotoboysWithSameRestaurant); + + } + + private CacheMotoboyDistance getNearestMotoboyWithoutOrders(RestaurantEntity restaurantEntity, + List cache, List cacheMotoboysWithSameRestaurant) { + + // Removo os motoboys com pedido no mesmo restaurante mas que não se aplicaram a + // regra de reusar um motoboy + Stream stream = cacheMotoboysWithSameRestaurant.size() == 0 ? cache.stream() + : cache.stream().filter(c -> !cacheMotoboysWithSameRestaurant.stream().map(c1 -> c1.getId()) + .collect(Collectors.toList()).contains(c.getId())); + + // Removo os motoboys com pedidos de outros restaurantes e pego os três mais + // próximos + Stream nearestMotoboys = stream.filter(c -> c.getOrders().size() == 0) + .sorted((c1, c2) -> Double.compare( + DistanceUtil.distance(c1.getLat(), c1.getLon(), restaurantEntity.getLat(), + restaurantEntity.getLon()), + DistanceUtil.distance(c2.getLat(), c2.getLon(), restaurantEntity.getLat(), + restaurantEntity.getLon()))) + .limit(LIMIT_MOTOBOYS_TO_QUERY_IN_GOOGLE); + + // Dos três mais próximos, eu calculo qual chega mais rápido baseado no Google + // Maps + return nearestMotoboys + .map(m -> new CacheMotoboyDistance(m, + calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m))) + .sorted((m1, m2) -> Long.compare(m1.getTimestampArrivesAtRestaurant().getTime(), + m2.getTimestampArrivesAtRestaurant().getTime())) + .collect(Collectors.toList()).get(0); + } + + private List searchForMotoboysDeliveringForSameRestaurant(RestaurantEntity restaurantEntity, + List cache) { + return cache.stream() + .filter(m -> m.getOrders().size() != 0 + && m.getOrders().get(0).getRestaurantId().equals(restaurantEntity.getId())) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/com/groupsix/mapFood/timestamp/CalculateTimestamp.java b/src/main/java/com/groupsix/mapFood/timestamp/CalculateTimestamp.java new file mode 100644 index 0000000..634335d --- /dev/null +++ b/src/main/java/com/groupsix/mapFood/timestamp/CalculateTimestamp.java @@ -0,0 +1,74 @@ +package com.groupsix.mapFood.timestamp; + +import java.sql.Timestamp; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.maps.model.LatLng; +import com.groupsix.mapFood.entity.CustomerEntity; +import com.groupsix.mapFood.entity.OrderEntity; +import com.groupsix.mapFood.entity.RestaurantEntity; +import com.groupsix.mapFood.pojo.CacheDestination; +import com.groupsix.mapFood.pojo.CacheMotoboy; +import com.groupsix.mapFood.pojo.CacheMotoboyOrder; +import com.groupsix.mapFood.service.GoogleMapsService; +import com.groupsix.mapFood.util.TimestampUtil; + +@Component +public class CalculateTimestamp { + + @Autowired + private GoogleMapsService googleMapsService; + + @Autowired + private TimestampUtil timestampUtil; + + public Timestamp calculateEstimatedTimeToDelivery(OrderEntity orderEntity, CacheMotoboy cachedMotoboy, + Timestamp timeToOrderLeavesTheRestaurant) { + Timestamp timeToDelivery = null; + if (cachedMotoboy.getOrders().size() == 0) { + timeToDelivery = estimateTimeToDelivery(orderEntity, timeToOrderLeavesTheRestaurant); + } else { + CacheMotoboyOrder lastOrderToRestaurant = cachedMotoboy.getOrders() + .get(cachedMotoboy.getOrders().size() - 1); + timeToDelivery = estimateTimeToDeliveryFromOtherCustomer(lastOrderToRestaurant.getCacheDestination(), + orderEntity.getCustomer(), lastOrderToRestaurant.getTimeToDelivery()); + } + return timeToDelivery; + } + + public Timestamp calculateEstimatedTimeMotoboyArrivesAtRestaurant(RestaurantEntity restaurantEntity, + CacheMotoboy cachedMotoboy) { + Timestamp timeToMotoboyArriveAtRestaurant; + if (cachedMotoboy.getOrders().size() != 0) { + timeToMotoboyArriveAtRestaurant = cachedMotoboy.getOrders().get(0).getTimeToMotoboyArrivesAtRestaurant(); + } else { + timeToMotoboyArriveAtRestaurant = estimateTimeToMotoboyArriveAtRestaurant(restaurantEntity, cachedMotoboy); + } + return timeToMotoboyArriveAtRestaurant; + } + + private Timestamp estimateTimeToDelivery(OrderEntity orderEntity, Timestamp outTime) { + LatLng restaurantPosition = new LatLng(orderEntity.getRestaurant().getLat(), + orderEntity.getRestaurant().getLon()); + LatLng customerPosition = new LatLng(orderEntity.getCustomer().getLat(), orderEntity.getCustomer().getLon()); + + return timestampUtil.addSeconds(googleMapsService.timeToReach(restaurantPosition, customerPosition), outTime); + } + + private Timestamp estimateTimeToDeliveryFromOtherCustomer(CacheDestination cacheDestination, + CustomerEntity customerDestination, Timestamp outTime) { + LatLng customerFromLastOrderPosition = new LatLng(cacheDestination.getLat(), cacheDestination.getLon()); + LatLng customerPosition = new LatLng(customerDestination.getLat(), customerDestination.getLon()); + + return timestampUtil.addSeconds(googleMapsService.timeToReach(customerFromLastOrderPosition, customerPosition), outTime); + } + + private Timestamp estimateTimeToMotoboyArriveAtRestaurant(RestaurantEntity restaurantEntity, CacheMotoboy cachedMotoboy) { + LatLng start = new LatLng(cachedMotoboy.getLat(), cachedMotoboy.getLon()); + LatLng end = new LatLng(restaurantEntity.getLat(), restaurantEntity.getLon()); + + return timestampUtil.addSecondsFromNow(googleMapsService.timeToReach(start, end)); + } +} diff --git a/src/main/java/com/groupsix/mapFood/util/DistanceUtil.java b/src/main/java/com/groupsix/mapFood/util/DistanceUtil.java new file mode 100644 index 0000000..dd6ff3e --- /dev/null +++ b/src/main/java/com/groupsix/mapFood/util/DistanceUtil.java @@ -0,0 +1,19 @@ +package com.groupsix.mapFood.util; + +public class DistanceUtil { + + public static Double distance(double lat1, double lon1, double lat2, double lon2) { + Double dist = 0.0; + if ((lat1 == lat2) && (lon1 == lon2)) { + return dist; + } + else { + double theta = lon1 - lon2; + dist = Math.sin(Math.toRadians(lat1)) * Math.sin(Math.toRadians(lat2)) + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.cos(Math.toRadians(theta)); + dist = Math.acos(dist); + dist = Math.toDegrees(dist); + dist = dist * 60 * 1.1515 * 1.609344; + return (dist); + } + } +} diff --git a/src/main/resources/db/migration/V17__orderEstimatedTimeToDeliveryNullable.sql b/src/main/resources/db/migration/V17__orderEstimatedTimeToDeliveryNullable.sql new file mode 100644 index 0000000..69c5cf3 --- /dev/null +++ b/src/main/resources/db/migration/V17__orderEstimatedTimeToDeliveryNullable.sql @@ -0,0 +1,2 @@ +ALTER TABLE `mapfood`.`orders` +CHANGE COLUMN `estimated_time_to_delivery` `estimated_time_to_delivery` TIMESTAMP NULL ; \ No newline at end of file diff --git a/src/test/java/com/groupsix/mapFood/factory/OrderFactoryTest.java b/src/test/java/com/groupsix/mapFood/factory/OrderFactoryTest.java new file mode 100644 index 0000000..3e2061e --- /dev/null +++ b/src/test/java/com/groupsix/mapFood/factory/OrderFactoryTest.java @@ -0,0 +1,50 @@ +package com.groupsix.mapFood.factory; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.groupsix.mapFood.entity.CustomerEntity; +import com.groupsix.mapFood.entity.OrderDeliveryEntity; +import com.groupsix.mapFood.entity.OrderEntity; +import com.groupsix.mapFood.entity.OrderItemEntity; +import com.groupsix.mapFood.entity.RestaurantEntity; +import com.groupsix.mapFood.pojo.Order; + +public class OrderFactoryTest { + + @Test + public void testFromDTO() { + final Order order = new Order(); + order.setRestaurantId(1); + order.setCustomerId(2); + order.setTotal(100); + + final List orderItemsEntities = new ArrayList<>(); + final OrderItemEntity orderItemEntity1 = new OrderItemEntity(); + final OrderItemEntity orderItemEntity2 = new OrderItemEntity(); + orderItemsEntities.add(orderItemEntity1); + orderItemsEntities.add(orderItemEntity2); + + RestaurantEntity restaurantEntity = new RestaurantEntity(); + CustomerEntity customerEntity = new CustomerEntity(); + + final OrderDeliveryEntity orderDeliveryEntity = new OrderDeliveryEntity(); + + final OrderEntity orderEntity = new OrderFactory().fromDTO(order, orderItemsEntities, orderDeliveryEntity, + restaurantEntity, customerEntity); + + assertEquals(100, orderEntity.getTotal().intValue()); + assertEquals(restaurantEntity, orderEntity.getRestaurant()); + assertEquals(customerEntity, orderEntity.getCustomer()); + assertEquals(orderItemsEntities, orderEntity.getOrderItems()); + assertEquals(orderDeliveryEntity, orderEntity.getOrderDelivery()); + + assertEquals(orderEntity, orderDeliveryEntity.getOrder()); + assertEquals(orderEntity, orderItemEntity1.getOrder()); + assertEquals(orderEntity, orderItemEntity2.getOrder()); + } +} diff --git a/src/test/java/com/groupsix/mapFood/service/CacheSearchMotoboyServiceTest.java b/src/test/java/com/groupsix/mapFood/service/CacheSearchMotoboyServiceTest.java new file mode 100644 index 0000000..bd20a01 --- /dev/null +++ b/src/test/java/com/groupsix/mapFood/service/CacheSearchMotoboyServiceTest.java @@ -0,0 +1,344 @@ +package com.groupsix.mapFood.service; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import com.groupsix.mapFood.entity.RestaurantEntity; +import com.groupsix.mapFood.pojo.CacheMotoboy; +import com.groupsix.mapFood.pojo.CacheMotoboyDistance; +import com.groupsix.mapFood.pojo.CacheMotoboyOrder; +import com.groupsix.mapFood.timestamp.CalculateTimestamp; +import com.groupsix.mapFood.util.TimestampUtil; + +@RunWith(MockitoJUnitRunner.class) +public class CacheSearchMotoboyServiceTest { + + @Mock + private CalculateTimestamp calculateTimestamp; + + @Mock + private TimestampUtil timestampUtil; + + @InjectMocks + private CacheSearchMotoboyService service; + + @Test + public void testGetNearestMotoboyWithMotoboyDeliveringToSameRestaurantAndLessThan5Orders() { + + List cache = new ArrayList<>(); + CacheMotoboy m1 = new CacheMotoboy(); + m1.setOrders(new ArrayList<>()); + cache.add(m1); + + CacheMotoboy m2 = new CacheMotoboy(); + m2.setOrders(new ArrayList<>()); + CacheMotoboyOrder motoboyOrder = new CacheMotoboyOrder(); + Timestamp afterTenMinutes = new Timestamp(1000L); + motoboyOrder.setTimeToMotoboyArrivesAtRestaurant(afterTenMinutes); + motoboyOrder.setRestaurantId(1); + m2.getOrders().add(motoboyOrder); + cache.add(m2); + + Timestamp tenMinutes = new Timestamp(600L); + when(timestampUtil.addTenMinutesFromNow()).thenReturn(tenMinutes); + + RestaurantEntity restaurantEntity = new RestaurantEntity(); + restaurantEntity.setId(1); + CacheMotoboyDistance result = service.getNearestMotoboy(restaurantEntity, cache); + + assertEquals(m2, result.getCacheMotoboy()); + assertEquals(afterTenMinutes, result.getTimestampArrivesAtRestaurant()); + + } + + @Test + public void testGetNearestMotoboyWithoutAnyOrderAndDistanceAndTimeAreOrdered() { + + List cache = new ArrayList<>(); + // Terceiro mais próximo + CacheMotoboy m1 = new CacheMotoboy(); + m1.setLat(-30.0255805); + m1.setLon(-51.2013164); + m1.setOrders(new ArrayList<>()); + cache.add(m1); + + // Segundo mais próximo + CacheMotoboy m2 = new CacheMotoboy(); + m2.setLat(-30.0282025); + m2.setLon(-51.2033363); + m2.setOrders(new ArrayList<>()); + cache.add(m2); + + //Motoboy mais próximo + CacheMotoboy m3 = new CacheMotoboy(); + m3.setLat(-30.035264); + m3.setLon(-51.2117427); + m3.setOrders(new ArrayList<>()); + cache.add(m3); + + // Mais longe + CacheMotoboy m4 = new CacheMotoboy(); + m4.setLat(-30.0196725); + m4.setLon(-51.195394); + m4.setOrders(new ArrayList<>()); + cache.add(m4); + + RestaurantEntity restaurantEntity = new RestaurantEntity(); + restaurantEntity.setId(1); + restaurantEntity.setLat(-30.035264); + restaurantEntity.setLon(-51.2117427); + + when(calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m3)).thenReturn(new Timestamp(100L)); + when(calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m2)).thenReturn(new Timestamp(200L)); + when(calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m1)).thenReturn(new Timestamp(300L)); + + CacheMotoboyDistance result = service.getNearestMotoboy(restaurantEntity, cache); + + assertEquals(m3, result.getCacheMotoboy()); + } + + @Test + public void testGetNearestMotoboyWithoutAnyOrderAndDistanceAndTimeAreNotOrdered() { + + List cache = new ArrayList<>(); + // Terceiro mais próximo + CacheMotoboy m1 = new CacheMotoboy(); + m1.setLat(-30.0255805); + m1.setLon(-51.2013164); + m1.setOrders(new ArrayList<>()); + cache.add(m1); + + // Segundo mais próximo + CacheMotoboy m2 = new CacheMotoboy(); + m2.setLat(-30.0282025); + m2.setLon(-51.2033363); + m2.setOrders(new ArrayList<>()); + cache.add(m2); + + //Motoboy mais próximo, mas demora mais para chegar que o segundo + CacheMotoboy m3 = new CacheMotoboy(); + m3.setLat(-30.035264); + m3.setLon(-51.2117427); + m3.setOrders(new ArrayList<>()); + cache.add(m3); + + // Mais longe + CacheMotoboy m4 = new CacheMotoboy(); + m4.setLat(-30.0196725); + m4.setLon(-51.195394); + m4.setOrders(new ArrayList<>()); + cache.add(m4); + + RestaurantEntity restaurantEntity = new RestaurantEntity(); + restaurantEntity.setId(1); + restaurantEntity.setLat(-30.035264); + restaurantEntity.setLon(-51.2117427); + + when(calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m3)).thenReturn(new Timestamp(200L)); + when(calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m2)).thenReturn(new Timestamp(100L)); + when(calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m1)).thenReturn(new Timestamp(300L)); + + CacheMotoboyDistance result = service.getNearestMotoboy(restaurantEntity, cache); + + assertEquals(m2, result.getCacheMotoboy()); + } + + @Test + public void testGetNearestMotoboyWithNearestMotoboyFullOfOrders() { + + List cache = new ArrayList<>(); + // Terceiro mais próximo + CacheMotoboy m1 = new CacheMotoboy(); + m1.setId(1); + m1.setLat(-30.0255805); + m1.setLon(-51.2013164); + m1.setOrders(new ArrayList<>()); + cache.add(m1); + + // Segundo mais próximo + CacheMotoboy m2 = new CacheMotoboy(); + m2.setId(2); + m2.setLat(-30.0282025); + m2.setLon(-51.2033363); + m2.setOrders(new ArrayList<>()); + cache.add(m2); + + //Motoboy mais próximo + CacheMotoboy m3 = new CacheMotoboy(); + m3.setId(3); + m3.setLat(-30.035264); + m3.setLon(-51.2117427); + m3.setOrders(new ArrayList<>()); + CacheMotoboyOrder motoboyOrder = new CacheMotoboyOrder(); + Timestamp afterTenMinutes = new Timestamp(1000L); + motoboyOrder.setTimeToMotoboyArrivesAtRestaurant(afterTenMinutes); + motoboyOrder.setRestaurantId(1); + m3.getOrders().add(motoboyOrder); + m3.getOrders().add(motoboyOrder); + m3.getOrders().add(motoboyOrder); + m3.getOrders().add(motoboyOrder); + m3.getOrders().add(motoboyOrder); + cache.add(m3); + + // Mais longe + CacheMotoboy m4 = new CacheMotoboy(); + m4.setId(4); + m4.setLat(-30.0196725); + m4.setLon(-51.195394); + m4.setOrders(new ArrayList<>()); + cache.add(m4); + + RestaurantEntity restaurantEntity = new RestaurantEntity(); + restaurantEntity.setId(1); + restaurantEntity.setLat(-30.035264); + restaurantEntity.setLon(-51.2117427); + + Timestamp tenMinutes = new Timestamp(600L); + when(timestampUtil.addSecondsFromNow(600L)).thenReturn(tenMinutes); + + when(calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m2)).thenReturn(new Timestamp(200L)); + when(calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m1)).thenReturn(new Timestamp(300L)); + when(calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m4)).thenReturn(new Timestamp(400L)); + + CacheMotoboyDistance result = service.getNearestMotoboy(restaurantEntity, cache); + + assertEquals(m2, result.getCacheMotoboy()); + verify(calculateTimestamp, never()).calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m3); + } + + @Test + public void testGetNearestMotoboyWithNearestMotoboyArrivingBeforeOrderIsReady() { + + List cache = new ArrayList<>(); + // Terceiro mais próximo + CacheMotoboy m1 = new CacheMotoboy(); + m1.setId(1); + m1.setLat(-30.0255805); + m1.setLon(-51.2013164); + m1.setOrders(new ArrayList<>()); + cache.add(m1); + + // Segundo mais próximo + CacheMotoboy m2 = new CacheMotoboy(); + m2.setId(2); + m2.setLat(-30.0282025); + m2.setLon(-51.2033363); + m2.setOrders(new ArrayList<>()); + cache.add(m2); + + //Motoboy mais próximo + CacheMotoboy m3 = new CacheMotoboy(); + m3.setId(3); + m3.setLat(-30.035264); + m3.setLon(-51.2117427); + m3.setOrders(new ArrayList<>()); + CacheMotoboyOrder motoboyOrder = new CacheMotoboyOrder(); + Timestamp beforeTenMinutes = new Timestamp(200L); + motoboyOrder.setTimeToMotoboyArrivesAtRestaurant(beforeTenMinutes); + motoboyOrder.setRestaurantId(2); + m3.getOrders().add(motoboyOrder); + cache.add(m3); + + // Mais longe + CacheMotoboy m4 = new CacheMotoboy(); + m4.setId(4); + m4.setLat(-30.0196725); + m4.setLon(-51.195394); + m4.setOrders(new ArrayList<>()); + cache.add(m4); + + RestaurantEntity restaurantEntity = new RestaurantEntity(); + restaurantEntity.setId(1); + restaurantEntity.setLat(-30.035264); + restaurantEntity.setLon(-51.2117427); + + Timestamp tenMinutes = new Timestamp(600L); + when(timestampUtil.addSecondsFromNow(600L)).thenReturn(tenMinutes); + + when(calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m2)).thenReturn(new Timestamp(200L)); + when(calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m1)).thenReturn(new Timestamp(300L)); + when(calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m4)).thenReturn(new Timestamp(400L)); + + CacheMotoboyDistance result = service.getNearestMotoboy(restaurantEntity, cache); + + assertEquals(m2, result.getCacheMotoboy()); + verify(calculateTimestamp, never()).calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m3); + } + + @Test + public void testGetNearestMotoboyWithNearestMotoboyDeliveringForAnotherRestaurant() { + + List cache = new ArrayList<>(); + // Terceiro mais próximo + CacheMotoboy m1 = new CacheMotoboy(); + m1.setId(1); + m1.setLat(-30.0255805); + m1.setLon(-51.2013164); + m1.setOrders(new ArrayList<>()); + cache.add(m1); + + // Segundo mais próximo + CacheMotoboy m2 = new CacheMotoboy(); + m2.setId(2); + m2.setLat(-30.0282025); + m2.setLon(-51.2033363); + m2.setOrders(new ArrayList<>()); + cache.add(m2); + + //Motoboy mais próximo + CacheMotoboy m3 = new CacheMotoboy(); + m3.setId(3); + m3.setLat(-30.035264); + m3.setLon(-51.2117427); + m3.setOrders(new ArrayList<>()); + CacheMotoboyOrder motoboyOrder = new CacheMotoboyOrder(); + Timestamp beforeTenMinutes = new Timestamp(200L); + motoboyOrder.setTimeToMotoboyArrivesAtRestaurant(beforeTenMinutes); + motoboyOrder.setRestaurantId(1); + m3.getOrders().add(motoboyOrder); + m3.getOrders().add(motoboyOrder); + m3.getOrders().add(motoboyOrder); + m3.getOrders().add(motoboyOrder); + m3.getOrders().add(motoboyOrder); + cache.add(m3); + + // Mais longe + CacheMotoboy m4 = new CacheMotoboy(); + m4.setId(4); + m4.setLat(-30.0196725); + m4.setLon(-51.195394); + m4.setOrders(new ArrayList<>()); + cache.add(m4); + + RestaurantEntity restaurantEntity = new RestaurantEntity(); + restaurantEntity.setId(1); + restaurantEntity.setLat(-30.035264); + restaurantEntity.setLon(-51.2117427); + + Timestamp tenMinutes = new Timestamp(600L); + when(timestampUtil.addSecondsFromNow(600L)).thenReturn(tenMinutes); + + + when(calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m2)).thenReturn(new Timestamp(200L)); + when(calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m1)).thenReturn(new Timestamp(300L)); + when(calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m4)).thenReturn(new Timestamp(400L)); + + CacheMotoboyDistance result = service.getNearestMotoboy(restaurantEntity, cache); + + assertEquals(m2, result.getCacheMotoboy()); + verify(calculateTimestamp, never()).calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurantEntity, m3); + } + +} diff --git a/src/test/java/com/groupsix/mapFood/service/OrderDeliveryServiceTest.java b/src/test/java/com/groupsix/mapFood/service/OrderDeliveryServiceTest.java new file mode 100644 index 0000000..602062f --- /dev/null +++ b/src/test/java/com/groupsix/mapFood/service/OrderDeliveryServiceTest.java @@ -0,0 +1,148 @@ +package com.groupsix.mapFood.service; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import com.groupsix.mapFood.entity.CustomerEntity; +import com.groupsix.mapFood.entity.OrderDeliveryEntity; +import com.groupsix.mapFood.entity.OrderEntity; +import com.groupsix.mapFood.entity.RestaurantEntity; +import com.groupsix.mapFood.pojo.CacheMotoboy; +import com.groupsix.mapFood.pojo.CacheMotoboyDistance; +import com.groupsix.mapFood.repository.OrderRepository; +import com.groupsix.mapFood.timestamp.CalculateTimestamp; +import com.groupsix.mapFood.util.TimestampUtil; + +@RunWith(MockitoJUnitRunner.class) +public class OrderDeliveryServiceTest { + + @Mock + private CacheService cacheService; + + @Mock + private CalculateTimestamp calculateTimestamp; + + @Mock + private OrderRepository orderRepository; + + @Mock + private CacheSearchMotoboyService cacheSearchMotoboyService; + + @Mock + private TimestampUtil timestampUtil; + + @InjectMocks + private OrderDeliveryService service; + + @Test + public void testSearchMotoboyWithMotoboyArrivingBeforeOrderReady() { + OrderEntity order = new OrderEntity(); + OrderDeliveryEntity orderDelivery = new OrderDeliveryEntity(); + order.setOrderDelivery(orderDelivery); + order.setId(10); + + RestaurantEntity restaurant = new RestaurantEntity(); + restaurant.setId(50); + order.setRestaurant(restaurant); + + CustomerEntity customer = new CustomerEntity(); + customer.setLat(3.0); + customer.setLon(4.0); + order.setCustomer(customer); + + List cache = new ArrayList<>(); + when(cacheService.getCache()).thenReturn(cache); + + CacheMotoboy motoboy = new CacheMotoboy(); + motoboy.setId(1); + motoboy.setLat(1.0); + motoboy.setLon(2.0); + motoboy.setOrders(new ArrayList<>()); + + Timestamp timestampArrivesAtRestaurant = new Timestamp(100L); + CacheMotoboyDistance cacheMotoboyDistance = new CacheMotoboyDistance(motoboy, timestampArrivesAtRestaurant); + when(cacheSearchMotoboyService.getNearestMotoboy(restaurant, cache)).thenReturn(cacheMotoboyDistance); + + Timestamp tenMinutes = new Timestamp(600L); + when(timestampUtil.addTenMinutesFromNow()).thenReturn(tenMinutes); + + Timestamp timeToDelivery = new Timestamp(1000L); + when(calculateTimestamp.calculateEstimatedTimeToDelivery(order, motoboy, tenMinutes)).thenReturn(timeToDelivery); + + service.searchMotoboy(order); + + verify(cacheService, times(1)).updateCache(cache); + verify(orderRepository, times(1)).save(order); + + assertEquals(timeToDelivery, order.getEstimatedTimeToDelivery()); + assertEquals(1, motoboy.getOrders().size()); + assertEquals(10, motoboy.getOrders().get(0).getId().intValue()); + assertEquals(50, motoboy.getOrders().get(0).getRestaurantId().intValue()); + assertEquals(new Double(3.0), motoboy.getOrders().get(0).getCacheDestination().getLat()); + assertEquals(new Double(4.0), motoboy.getOrders().get(0).getCacheDestination().getLon()); + assertEquals(timeToDelivery, motoboy.getOrders().get(0).getTimeToDelivery()); + assertEquals(timestampArrivesAtRestaurant, motoboy.getOrders().get(0).getTimeToMotoboyArrivesAtRestaurant()); + } + + @Test + public void testSearchMotoboyWithMotoboyArrivingAfterOrderReady() { + OrderEntity order = new OrderEntity(); + OrderDeliveryEntity orderDelivery = new OrderDeliveryEntity(); + order.setOrderDelivery(orderDelivery); + order.setId(10); + + RestaurantEntity restaurant = new RestaurantEntity(); + restaurant.setId(50); + order.setRestaurant(restaurant); + + CustomerEntity customer = new CustomerEntity(); + customer.setLat(3.0); + customer.setLon(4.0); + order.setCustomer(customer); + + List cache = new ArrayList<>(); + when(cacheService.getCache()).thenReturn(cache); + + CacheMotoboy motoboy = new CacheMotoboy(); + motoboy.setId(1); + motoboy.setLat(1.0); + motoboy.setLon(2.0); + motoboy.setOrders(new ArrayList<>()); + + Timestamp timestampArrivesAtRestaurant = new Timestamp(1000L); + CacheMotoboyDistance cacheMotoboyDistance = new CacheMotoboyDistance(motoboy, timestampArrivesAtRestaurant); + when(cacheSearchMotoboyService.getNearestMotoboy(restaurant, cache)).thenReturn(cacheMotoboyDistance); + + Timestamp tenMinutes = new Timestamp(600L); + when(timestampUtil.addTenMinutesFromNow()).thenReturn(tenMinutes); + + Timestamp timeToDelivery = new Timestamp(1000L); + when(calculateTimestamp.calculateEstimatedTimeToDelivery(order, motoboy, timestampArrivesAtRestaurant)).thenReturn(timeToDelivery); + + service.searchMotoboy(order); + + verify(cacheService, times(1)).updateCache(cache); + verify(orderRepository, times(1)).save(order); + + assertEquals(timeToDelivery, order.getEstimatedTimeToDelivery()); + assertEquals(1, motoboy.getOrders().size()); + assertEquals(10, motoboy.getOrders().get(0).getId().intValue()); + assertEquals(50, motoboy.getOrders().get(0).getRestaurantId().intValue()); + assertEquals(new Double(3.0), motoboy.getOrders().get(0).getCacheDestination().getLat()); + assertEquals(new Double(4.0), motoboy.getOrders().get(0).getCacheDestination().getLon()); + assertEquals(timeToDelivery, motoboy.getOrders().get(0).getTimeToDelivery()); + assertEquals(timestampArrivesAtRestaurant, motoboy.getOrders().get(0).getTimeToMotoboyArrivesAtRestaurant()); + } +} diff --git a/src/test/java/com/groupsix/mapFood/timestamp/CalculateTimestampTest.java b/src/test/java/com/groupsix/mapFood/timestamp/CalculateTimestampTest.java new file mode 100644 index 0000000..baba068 --- /dev/null +++ b/src/test/java/com/groupsix/mapFood/timestamp/CalculateTimestampTest.java @@ -0,0 +1,153 @@ +package com.groupsix.mapFood.timestamp; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +import java.sql.Timestamp; +import java.util.ArrayList; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import com.google.maps.model.LatLng; +import com.groupsix.mapFood.entity.CustomerEntity; +import com.groupsix.mapFood.entity.OrderEntity; +import com.groupsix.mapFood.entity.RestaurantEntity; +import com.groupsix.mapFood.pojo.CacheDestination; +import com.groupsix.mapFood.pojo.CacheMotoboy; +import com.groupsix.mapFood.pojo.CacheMotoboyOrder; +import com.groupsix.mapFood.service.GoogleMapsService; +import com.groupsix.mapFood.util.TimestampUtil; + +@RunWith(MockitoJUnitRunner.class) +public class CalculateTimestampTest { + + @Mock + private GoogleMapsService googleMapsService; + + @Mock + private TimestampUtil timestampUtil; + + @InjectMocks + private CalculateTimestamp calculateTimestamp; + + @Captor + private ArgumentCaptor latLonFrom; + + @Captor + private ArgumentCaptor latLonTo; + + @Test + public void testCalculateEstimatedTimeToDeliveryWithoutOrders() { + + CacheMotoboy motoboy = new CacheMotoboy(); + motoboy.setOrders(new ArrayList<>()); + + Timestamp timeToOrderLeavesTheRestaurant = new Timestamp(100); + + CustomerEntity customer = new CustomerEntity(); + customer.setLat(1.0); + customer.setLon(2.0); + + RestaurantEntity restaurant = new RestaurantEntity(); + restaurant.setLat(3.0); + restaurant.setLon(4.0); + + OrderEntity order = new OrderEntity(); + order.setRestaurant(restaurant); + order.setCustomer(customer); + + when(googleMapsService.timeToReach(latLonFrom.capture(), latLonTo.capture())).thenReturn(100L); + Timestamp timestampToDelivery = new Timestamp(200); + when(timestampUtil.addSeconds(100L, timeToOrderLeavesTheRestaurant)).thenReturn(timestampToDelivery); + + Timestamp result = calculateTimestamp.calculateEstimatedTimeToDelivery(order, motoboy, timeToOrderLeavesTheRestaurant); + assertEquals(timestampToDelivery, result); + assertEquals(new Double(3.0), new Double(latLonFrom.getValue().lat)); + assertEquals(new Double(4.0), new Double(latLonFrom.getValue().lng)); + + assertEquals(new Double(1.0), new Double(latLonTo.getValue().lat)); + assertEquals(new Double(2.0), new Double(latLonTo.getValue().lng)); + } + + @Test + public void testCalculateEstimatedTimeToDeliveryWithOneOrder() { + + CacheMotoboy motoboy = new CacheMotoboy(); + motoboy.setOrders(new ArrayList<>()); + CacheMotoboyOrder cachedOrder = new CacheMotoboyOrder(); + CacheDestination cachedDestination = new CacheDestination(); + cachedDestination.setLat(5.0); + cachedDestination.setLon(6.0); + cachedOrder.setCacheDestination(cachedDestination); + Timestamp timeLastOrderLeavesTheRestaurant = new Timestamp(100); + cachedOrder.setTimeToDelivery(timeLastOrderLeavesTheRestaurant); + motoboy.getOrders().add(cachedOrder); + + Timestamp timeToOrderLeavesTheRestaurant = new Timestamp(100); + + CustomerEntity customer = new CustomerEntity(); + customer.setLat(1.0); + customer.setLon(2.0); + + OrderEntity order = new OrderEntity(); + order.setCustomer(customer); + + when(googleMapsService.timeToReach(latLonFrom.capture(), latLonTo.capture())).thenReturn(100L); + Timestamp timestampToDelivery = new Timestamp(200); + when(timestampUtil.addSeconds(100L, timeLastOrderLeavesTheRestaurant)).thenReturn(timestampToDelivery); + + Timestamp result = calculateTimestamp.calculateEstimatedTimeToDelivery(order, motoboy, timeToOrderLeavesTheRestaurant); + assertEquals(timestampToDelivery, result); + + assertEquals(new Double(5.0), new Double(latLonFrom.getValue().lat)); + assertEquals(new Double(6.0), new Double(latLonFrom.getValue().lng)); + + assertEquals(new Double(1.0), new Double(latLonTo.getValue().lat)); + assertEquals(new Double(2.0), new Double(latLonTo.getValue().lng)); + } + + @Test + public void testCalculateEstimatedTimeMotoboyArrivesAtRestaurantWithoutOrders() { + CacheMotoboy motoboy = new CacheMotoboy(); + motoboy.setLat(1.0); + motoboy.setLon(2.0); + motoboy.setOrders(new ArrayList<>()); + + RestaurantEntity restaurant = new RestaurantEntity(); + restaurant.setLat(3.0); + restaurant.setLon(4.0); + + when(googleMapsService.timeToReach(latLonFrom.capture(), latLonTo.capture())).thenReturn(100L); + Timestamp timestampToDelivery = new Timestamp(200); + when(timestampUtil.addSecondsFromNow(100L)).thenReturn(timestampToDelivery); + + Timestamp result = calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(restaurant, motoboy); + assertEquals(timestampToDelivery, result); + + assertEquals(new Double(1.0), new Double(latLonFrom.getValue().lat)); + assertEquals(new Double(2.0), new Double(latLonFrom.getValue().lng)); + + assertEquals(new Double(3.0), new Double(latLonTo.getValue().lat)); + assertEquals(new Double(4.0), new Double(latLonTo.getValue().lng)); + } + + @Test + public void testCalculateEstimatedTimeMotoboyArrivesAtRestaurantWithOrders() { + CacheMotoboy motoboy = new CacheMotoboy(); + motoboy.setOrders(new ArrayList<>()); + CacheMotoboyOrder cachedOrder = new CacheMotoboyOrder(); + + Timestamp timeMotoboyArrivesArRestaurant = new Timestamp(100); + cachedOrder.setTimeToMotoboyArrivesAtRestaurant(timeMotoboyArrivesArRestaurant); + motoboy.getOrders().add(cachedOrder); + + Timestamp result = calculateTimestamp.calculateEstimatedTimeMotoboyArrivesAtRestaurant(null, motoboy); + assertEquals(timeMotoboyArrivesArRestaurant, result); + } + +} diff --git a/src/test/java/com/groupsix/mapFood/validation/OrderValidationTest.java b/src/test/java/com/groupsix/mapFood/validation/OrderValidationTest.java new file mode 100644 index 0000000..fb45d25 --- /dev/null +++ b/src/test/java/com/groupsix/mapFood/validation/OrderValidationTest.java @@ -0,0 +1,232 @@ +package com.groupsix.mapFood.validation; + +import com.groupsix.mapFood.entity.CustomerEntity; +import com.groupsix.mapFood.entity.OrderItemEntity; +import com.groupsix.mapFood.entity.ProductEntity; +import com.groupsix.mapFood.entity.RestaurantEntity; +import com.groupsix.mapFood.exception.CustomerTooFarException; +import com.groupsix.mapFood.exception.DiferentRestaurantException; +import com.groupsix.mapFood.exception.ItemsPriceException; +import com.groupsix.mapFood.exception.TotalPriceException; +import com.groupsix.mapFood.pojo.Order; +import com.groupsix.mapFood.pojo.OrderItem; +import com.groupsix.mapFood.service.CustomerService; +import com.groupsix.mapFood.service.RestaurantService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class OrderValidationTest { + + @Mock + private CustomerService customerService; + + @Mock + private RestaurantService restaurantService; + + @InjectMocks + private OrderValidation orderValidation; + + @Test + public void testVerifyTotalOrder() throws TotalPriceException { + + Order order = new Order(); + List orderItems = new ArrayList<>(); + OrderItem item1 = new OrderItem(); + OrderItem item2 = new OrderItem(); + + item1.setTotal(200); + item2.setTotal(600); + + orderItems.add(item1); + orderItems.add(item2); + + order.setTotal(800); + order.setOrderItems(orderItems); + + orderValidation.verifyTotalOrder(order); + } + + @Test(expected=TotalPriceException.class) + public void testVerifyTotalOrderWithWrongTotal() throws TotalPriceException { + + Order order = new Order(); + List orderItems = new ArrayList<>(); + OrderItem item1 = new OrderItem(); + OrderItem item2 = new OrderItem(); + + item1.setTotal(200); + item2.setTotal(600); + + orderItems.add(item1); + orderItems.add(item2); + + order.setTotal(700); + order.setOrderItems(orderItems); + + orderValidation.verifyTotalOrder(order); + } + + @Test + public void testVerifyCustomerAndRestaurantDistance() throws CustomerTooFarException { + + Order order = new Order(); + CustomerEntity customer = new CustomerEntity(); + RestaurantEntity restaurant = new RestaurantEntity(); + + customer.setId(9); + customer.setLon(-0.44); + customer.setLat(0.45); + + restaurant.setId(5); + restaurant.setLon(-0.48); + restaurant.setLat(0.42); + + when(customerService.findById(9)).thenReturn(Optional.of(customer)); + when(restaurantService.findById(5)).thenReturn(Optional.of(restaurant)); + + order.setCustomerId(9); + order.setRestaurantId(5); + + orderValidation.verifyCustomerAndRestaurantDistance(order); + } + + @Test(expected=CustomerTooFarException.class) + public void testVerifyCustomerTooFarFromTheRestaurant() throws CustomerTooFarException { + + Order order = new Order(); + CustomerEntity customer = new CustomerEntity(); + RestaurantEntity restaurant = new RestaurantEntity(); + + customer.setId(9); + customer.setLon(-2.44); + customer.setLat(2.45); + + restaurant.setId(5); + restaurant.setLon(-31.48); + restaurant.setLat(31.42); + + when(customerService.findById(9)).thenReturn(Optional.of(customer)); + when(restaurantService.findById(5)).thenReturn(Optional.of(restaurant)); + + order.setCustomerId(9); + order.setRestaurantId(5); + + orderValidation.verifyCustomerAndRestaurantDistance(order); + } + + @Test + public void testVerifyPricesFromItems() throws ItemsPriceException { + + List orderItemsEntities = new ArrayList<>(); + ProductEntity product1 = new ProductEntity(); + ProductEntity product2 = new ProductEntity(); + OrderItemEntity item1 = new OrderItemEntity(); + OrderItemEntity item2 = new OrderItemEntity(); + + product1.setPrice(50); + product2.setPrice(100); + + item1.setProduct(product1); + item1.setQuantity(3); + item1.setTotal(150); + item2.setProduct(product2); + item2.setQuantity(4); + item2.setTotal(400); + + orderItemsEntities.add(item1); + orderItemsEntities.add(item2); + + orderValidation.verifyPricesFromItems(orderItemsEntities); + } + + @Test(expected=ItemsPriceException.class) + public void testVerifyPricesFromItemsWithWrongTotal() throws ItemsPriceException { + + List orderItemsEntities = new ArrayList<>(); + ProductEntity product1 = new ProductEntity(); + ProductEntity product2 = new ProductEntity(); + OrderItemEntity item1 = new OrderItemEntity(); + OrderItemEntity item2 = new OrderItemEntity(); + + product1.setPrice(50); + product2.setPrice(100); + + item1.setProduct(product1); + item1.setQuantity(3); + item1.setTotal(200); + item2.setProduct(product2); + item2.setQuantity(4); + item2.setTotal(300); + + orderItemsEntities.add(item1); + orderItemsEntities.add(item2); + + orderValidation.verifyPricesFromItems(orderItemsEntities); + } + + @Test + public void testVerifyItemsFromSameRestaurant() throws DiferentRestaurantException { + + Order order = new Order(); + List orderItemsEntities = new ArrayList<>(); + ProductEntity product1 = new ProductEntity(); + ProductEntity product2 = new ProductEntity(); + RestaurantEntity restaurant1 = new RestaurantEntity(); + RestaurantEntity restaurant2 = new RestaurantEntity(); + OrderItemEntity item1 = new OrderItemEntity(); + OrderItemEntity item2 = new OrderItemEntity(); + + order.setRestaurantId(10); + restaurant1.setId(10); + restaurant2.setId(10); + + product1.setRestaurant(restaurant1); + product2.setRestaurant(restaurant2); + + item1.setProduct(product1); + item2.setProduct(product2); + + orderItemsEntities.add(item1); + orderItemsEntities.add(item2); + + orderValidation.verifyItemsFromSameRestaurant(orderItemsEntities, order); + } + + @Test(expected=DiferentRestaurantException.class) + public void testVerifyItemsFromSameRestaurantWithDiferentRestaurants() throws DiferentRestaurantException { + + Order order = new Order(); + List orderItemsEntities = new ArrayList<>(); + ProductEntity product1 = new ProductEntity(); + ProductEntity product2 = new ProductEntity(); + RestaurantEntity restaurant1 = new RestaurantEntity(); + RestaurantEntity restaurant2 = new RestaurantEntity(); + OrderItemEntity item1 = new OrderItemEntity(); + OrderItemEntity item2 = new OrderItemEntity(); + + order.setRestaurantId(10); + restaurant1.setId(11); + restaurant2.setId(10); + + product1.setRestaurant(restaurant1); + product2.setRestaurant(restaurant2); + + item1.setProduct(product1); + item2.setProduct(product2); + + orderItemsEntities.add(item1); + orderItemsEntities.add(item2); + + orderValidation.verifyItemsFromSameRestaurant(orderItemsEntities, order); + } +}