diff --git a/application/pom.xml b/application/pom.xml
index 6487922..1b736da 100644
--- a/application/pom.xml
+++ b/application/pom.xml
@@ -11,15 +11,15 @@
com.techivw
web-price
- 1.0-RELEASE
-
+ 1.1-RELEASE
+ ../pom.xml
com.techivw
domain
- 1.0-RELEASE
+ 1.1-RELEASE
diff --git a/application/src/main/java/com/techivw/webprice/application/ports/out/PriceRepositoryPort.java b/application/src/main/java/com/techivw/webprice/application/ports/out/PriceRepositoryPort.java
index b785a12..6e75ca5 100644
--- a/application/src/main/java/com/techivw/webprice/application/ports/out/PriceRepositoryPort.java
+++ b/application/src/main/java/com/techivw/webprice/application/ports/out/PriceRepositoryPort.java
@@ -2,11 +2,9 @@ package com.techivw.webprice.application.ports.out;
import com.techivw.webprice.domain.Price;
-import java.time.LocalDateTime;
-import java.util.Optional;
+import java.util.List;
public interface PriceRepositoryPort {
- Optional findHighestPriorityPriceByDateTimeAndProductIdAndBrandId(LocalDateTime dateTime, Long productId, Long brandId);
-
+ List findPricesByProductIdAndBrandId(Long productId, Long brandId);
}
diff --git a/application/src/main/java/com/techivw/webprice/application/services/PriceService.java b/application/src/main/java/com/techivw/webprice/application/services/PriceService.java
index eee1d41..ae5ae4d 100644
--- a/application/src/main/java/com/techivw/webprice/application/services/PriceService.java
+++ b/application/src/main/java/com/techivw/webprice/application/services/PriceService.java
@@ -8,6 +8,9 @@ import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Optional;
@Service
@AllArgsConstructor
@@ -17,8 +20,14 @@ public class PriceService implements PriceServicePort {
@Override
public Price getPriceWithHighestPriorityByDateTimeAndProductIdAndBrandId(LocalDateTime dateTime, Long productId, Long brandId) {
- return priceRepositoryPort.findHighestPriorityPriceByDateTimeAndProductIdAndBrandId(dateTime, productId, brandId)
- .orElseThrow(() ->
+
+ List prices = priceRepositoryPort.findPricesByProductIdAndBrandId(productId, brandId);
+
+ Optional maxPriorityPrice = prices.stream()
+ .filter(price -> !dateTime.isBefore(price.getStartDate()) && !dateTime.isAfter(price.getEndDate()))
+ .max(Comparator.comparing(Price::getPriority));
+
+ return maxPriorityPrice.orElseThrow(() ->
new NotFoundException(String.format(
"Price for product %d of brand %d not found for date %s", productId, brandId, dateTime)));
}
diff --git a/application/src/test/java/com/techivw/webprice/application/services/PriceServiceTest.java b/application/src/test/java/com/techivw/webprice/application/services/PriceServiceTest.java
index 2a61a80..7952aa7 100644
--- a/application/src/test/java/com/techivw/webprice/application/services/PriceServiceTest.java
+++ b/application/src/test/java/com/techivw/webprice/application/services/PriceServiceTest.java
@@ -7,7 +7,9 @@ import com.techivw.webprice.domain.Price;
import java.math.BigDecimal;
import java.time.LocalDateTime;
-import java.util.Optional;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -38,31 +40,55 @@ class PriceServiceTest {
@Test
void shouldReturnPriceWhenPriceExists() {
- Price expectedPrice = createPrice();
- when(priceRepositoryPort.findHighestPriorityPriceByDateTimeAndProductIdAndBrandId(
- eq(TEST_DATE), eq(TEST_PRODUCT_ID), eq(TEST_BRAND_ID)))
- .thenReturn(Optional.of(expectedPrice));
+ Price lowPriorityPrice = createPrice(0);
+ Price highPriorityPrice = createPrice(2);
+ List prices = Arrays.asList(lowPriorityPrice, highPriorityPrice);
+
+ when(priceRepositoryPort.findPricesByProductIdAndBrandId(
+ eq(TEST_PRODUCT_ID), eq(TEST_BRAND_ID)))
+ .thenReturn(prices);
Price result = priceService.getPriceWithHighestPriorityByDateTimeAndProductIdAndBrandId(
TEST_DATE, TEST_PRODUCT_ID, TEST_BRAND_ID);
assertNotNull(result);
- assertEquals(expectedPrice.getProductId(), result.getProductId());
- assertEquals(expectedPrice.getPrice(), result.getPrice());
+ assertEquals(highPriorityPrice, result);
}
@Test
- void shouldThrowNotFoundExceptionWhenPriceDoesNotExist() {
- when(priceRepositoryPort.findHighestPriorityPriceByDateTimeAndProductIdAndBrandId(
- any(LocalDateTime.class), anyLong(), anyLong()))
- .thenReturn(Optional.empty());
+ void shouldThrowNotFoundExceptionWhenPriceListIsEmpty() {
+ when(priceRepositoryPort.findPricesByProductIdAndBrandId(
+ eq(TEST_PRODUCT_ID), eq(TEST_BRAND_ID)))
+ .thenReturn(Collections.emptyList());
assertThrows(NotFoundException.class, () ->
priceService.getPriceWithHighestPriorityByDateTimeAndProductIdAndBrandId(
TEST_DATE, TEST_PRODUCT_ID, TEST_BRAND_ID));
}
- private Price createPrice() {
+ @Test
+ void shouldThrowNotFoundExceptionWhenNoPriceInDateRange() {
+ Price price = Price.builder()
+ .brandId(TEST_BRAND_ID)
+ .productId(TEST_PRODUCT_ID)
+ .startDate(TEST_DATE.plusDays(1))
+ .endDate(TEST_DATE.plusDays(2))
+ .priceList(1L)
+ .price(BigDecimal.valueOf(35.50))
+ .priority(1)
+ .currency("EUR")
+ .build();
+
+ when(priceRepositoryPort.findPricesByProductIdAndBrandId(
+ eq(TEST_PRODUCT_ID), eq(TEST_BRAND_ID)))
+ .thenReturn(Collections.singletonList(price));
+
+ assertThrows(NotFoundException.class, () ->
+ priceService.getPriceWithHighestPriorityByDateTimeAndProductIdAndBrandId(
+ TEST_DATE, TEST_PRODUCT_ID, TEST_BRAND_ID));
+ }
+
+ private Price createPrice(int priority) {
return Price.builder()
.brandId(TEST_BRAND_ID)
.productId(TEST_PRODUCT_ID)
@@ -70,7 +96,7 @@ class PriceServiceTest {
.endDate(TEST_DATE.plusDays(1))
.priceList(1L)
.price(BigDecimal.valueOf(35.50))
- .priority(1)
+ .priority(priority)
.currency("EUR")
.build();
}
diff --git a/boot/pom.xml b/boot/pom.xml
index a27a6b9..de1276e 100644
--- a/boot/pom.xml
+++ b/boot/pom.xml
@@ -7,8 +7,8 @@
com.techivw
web-price
- 1.0-RELEASE
-
+ 1.1-RELEASE
+ ../pom.xml
boot
@@ -20,22 +20,22 @@
com.techivw
domain
- 1.0-RELEASE
+ 1.1-RELEASE
com.techivw
application
- 1.0-RELEASE
+ 1.1-RELEASE
com.techivw
rest-api
- 1.0-RELEASE
+ 1.1-RELEASE
com.techivw
sql-repository
- 1.0-RELEASE
+ 1.1-RELEASE
diff --git a/boot/src/main/resources/application.properties b/boot/src/main/resources/application.properties
index 1da086d..29f2bd1 100644
--- a/boot/src/main/resources/application.properties
+++ b/boot/src/main/resources/application.properties
@@ -13,5 +13,6 @@ spring.h2.console.path=/h2-console
# Flyway
spring.flyway.enabled=true
-spring.flyway.locations=filesystem:infrastructure/out/sql-repository/sql/migration
-spring.flyway.baseline-on-migrate=true
\ No newline at end of file
+spring.flyway.locations=filesystem:../infrastructure/out/sql-repository/src/main/resources/sql/migration
+spring.flyway.baseline-on-migrate=true
+spring.flyway.fail-on-missing-locations=true
\ No newline at end of file
diff --git a/domain/pom.xml b/domain/pom.xml
index ab35c2d..6f92192 100644
--- a/domain/pom.xml
+++ b/domain/pom.xml
@@ -11,6 +11,6 @@
com.techivw
web-price
- 1.0-RELEASE
+ 1.1-RELEASE
diff --git a/infrastructure/in/rest-api/pom.xml b/infrastructure/in/rest-api/pom.xml
index 5826199..cc3fa87 100644
--- a/infrastructure/in/rest-api/pom.xml
+++ b/infrastructure/in/rest-api/pom.xml
@@ -7,7 +7,7 @@
com.techivw
web-price
- 1.0-RELEASE
+ 1.1-RELEASE
../../../pom.xml
@@ -19,12 +19,12 @@
com.techivw
domain
- 1.0-RELEASE
+ 1.1-RELEASE
com.techivw
application
- 1.0-RELEASE
+ 1.1-RELEASE
diff --git a/infrastructure/in/rest-api/src/main/java/com/techivw/webprice/infrastructure/in/controllers/handlers/AdapterExceptionHandler.java b/infrastructure/in/rest-api/src/main/java/com/techivw/webprice/infrastructure/in/controllers/handlers/AdapterExceptionHandler.java
index 50b1daa..9cf0ec0 100644
--- a/infrastructure/in/rest-api/src/main/java/com/techivw/webprice/infrastructure/in/controllers/handlers/AdapterExceptionHandler.java
+++ b/infrastructure/in/rest-api/src/main/java/com/techivw/webprice/infrastructure/in/controllers/handlers/AdapterExceptionHandler.java
@@ -2,13 +2,16 @@ package com.techivw.webprice.infrastructure.in.controllers.handlers;
import com.techivw.webprice.application.exceptions.NotFoundException;
import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
+import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.NOT_FOUND;
@RestControllerAdvice
@@ -24,4 +27,27 @@ public class AdapterExceptionHandler {
return new ResponseEntity<>(body, NOT_FOUND);
}
+
+ @ExceptionHandler(MissingServletRequestParameterException.class)
+ public ResponseEntity