Skip to content

Commit

Permalink
Merge pull request #44 from daithihearn/date-logic
Browse files Browse the repository at this point in the history
refactor: simplifying date logic
  • Loading branch information
daithihearn authored Oct 19, 2023
2 parents 2e4627b + 8f32e70 commit 93801b4
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PORT=8080
LOGGING_LEVEL=INFO
MONGODB_URI=mongodb://localhost:27017,localhost:27018,localhost:27019/electicity-prices
MONGODB_URI=mongodb://localhost:27017,localhost:27018,localhost:27019/electricity-prices
SPRING_PROFILES_ACTIVE=price-sync
SYNC_START_DATE=2023-01-01
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.14.1
1.15.0
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
help:
@egrep -h '\s#@\s' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?#@ "}; {printf "\033[36m %-30s\033[0m %s\n", $$1, $$2}'

build-local: #@ Build local
./gradlew clean build
build-image: #@ Build docker image
docker build -t electricity-prices . --load
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ie.daithi.electricityprices.utils.*
import org.apache.logging.log4j.LogManager
import org.springframework.context.MessageSource
import org.springframework.stereotype.Service
import java.time.LocalDate
import java.time.LocalDateTime
import java.util.*
import kotlin.math.roundToInt
Expand All @@ -27,7 +28,7 @@ class AlexSkillService(private val priceService: PriceService, private val messa
}

// Today's price and rating
val thirtyDayAverage = priceService.getThirtyDayAverage()
val thirtyDayAverage = priceService.getThirtyDayAverage(now.toLocalDate())
responses.add(getTodayRating(now, pricesToday, thirtyDayAverage, locale))

// Get next good 3-hour period
Expand All @@ -50,7 +51,7 @@ class AlexSkillService(private val priceService: PriceService, private val messa
fun getTodayRating(
dateTime: LocalDateTime = LocalDateTime.now(),
pricesToday: List<Price> = priceService.getPrices(dateTime.toLocalDate()),
thirtyDayAverage: Double = priceService.getThirtyDayAverage(),
thirtyDayAverage: Double = priceService.getThirtyDayAverage(dateTime.toLocalDate()),
locale: Locale
): String {
val dailyAverage = calculateAverage(pricesToday)
Expand All @@ -73,7 +74,7 @@ class AlexSkillService(private val priceService: PriceService, private val messa
fun getTomorrowRating(
dateTime: LocalDateTime = LocalDateTime.now().plusDays(1),
pricesTomorrow: List<Price> = priceService.getPrices(dateTime.toLocalDate()),
thirtyDayAverage: Double = priceService.getThirtyDayAverage(),
thirtyDayAverage: Double = priceService.getThirtyDayAverage(dateTime.toLocalDate()),
locale: Locale
): Pair<String, Boolean> {

Expand Down Expand Up @@ -217,7 +218,7 @@ class AlexSkillService(private val priceService: PriceService, private val messa
fun getNextCheapPeriod(
dateTime: LocalDateTime = LocalDateTime.now(),
pricesToday: List<Price> = priceService.getPrices(dateTime.toLocalDate()),
thirtyDayAverage: Double = priceService.getThirtyDayAverage(),
thirtyDayAverage: Double = priceService.getThirtyDayAverage(dateTime.toLocalDate()),
locale: Locale
): String {
val cheapPeriods = getCheapPeriods(pricesToday, thirtyDayAverage)
Expand Down Expand Up @@ -256,7 +257,7 @@ class AlexSkillService(private val priceService: PriceService, private val messa
fun getNextExpensivePeriod(
dateTime: LocalDateTime = LocalDateTime.now(),
pricesToday: List<Price> = priceService.getPrices(dateTime.toLocalDate()),
thirtyDayAverage: Double = priceService.getThirtyDayAverage(),
thirtyDayAverage: Double = priceService.getThirtyDayAverage(dateTime.toLocalDate()),
locale: Locale
): String {
val expensivePeriods =
Expand Down Expand Up @@ -307,7 +308,7 @@ class AlexSkillService(private val priceService: PriceService, private val messa
}

fun getThirtyDayAverage(
thirtyDayAverage: Double = priceService.getThirtyDayAverage(), locale: Locale
thirtyDayAverage: Double = priceService.getThirtyDayAverage(LocalDate.now()), locale: Locale
): String {
val thirtyDayAverageRounded = thirtyDayAverage.times(100).roundToInt()

Expand Down
40 changes: 23 additions & 17 deletions src/main/kotlin/ie/daithi/electricityprices/service/PriceService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,32 @@ class PriceService(

private val logger = LogManager.getLogger(this::class.simpleName)

fun getTodayPrices(): List<Price> {
logger.info("Getting today's prices")
val now = LocalDate.now()
return getPrices(now)
}

fun getPrices(date: LocalDate): List<Price> {
logger.info("Getting prices for $date")
val startDate = date.atStartOfDay().minusSeconds(1)
val endDate = date.plusDays(1).atStartOfDay().minusSeconds(1)
return priceRepo.dateTimeBetween(startDate, endDate)
val start = date.atStartOfDay().minusSeconds(1)
val end = date.plusDays(1).atStartOfDay().minusSeconds(1)
return getPrices(start, end)
}

fun getPrices(start: String?, end: String?): List<Price> {
val today = LocalDate.now()
val startDate = (start?.let { LocalDate.parse(it, dateFormatter) } ?: today).atStartOfDay().minusSeconds(1)
val endDate =
(end?.let { LocalDate.parse(it, dateFormatter) } ?: today).plusDays(1).atStartOfDay().minusSeconds(1)
fun getPrices(start: LocalDateTime, end: LocalDateTime): List<Price> {
logger.info("Getting prices between $start and $end")
return priceRepo.dateTimeBetween(start, end)
}

logger.info("Getting prices between $startDate and $endDate")
return priceRepo.dateTimeBetween(startDate, endDate)
fun getTodayPriceInfo(): DailyPriceInfo {
return getDailyPriceInfo(LocalDate.now())
}

fun getDailyPriceInfo(dateStr: String?): DailyPriceInfo? {
val date = dateStr?.let { LocalDate.parse(it, dateFormatter) } ?: LocalDate.now()
val prices = getPrices(start = dateStr, end = dateStr)
if (prices.isEmpty()) return null
val thirtyDayAverage: Double = getThirtyDayAverage(date.atStartOfDay())
fun getDailyPriceInfo(date: LocalDate): DailyPriceInfo {
val prices = getPrices(date)
if (prices.isEmpty()) throw DataNotAvailableYetException("Data is not available yet for $date")
val thirtyDayAverage: Double = getThirtyDayAverage(date)
val cheapestPeriods = getCheapPeriods(prices, thirtyDayAverage)
val expensivePeriods = getExpensivePeriods(prices, thirtyDayAverage)

Expand Down Expand Up @@ -97,8 +101,10 @@ class PriceService(
}
}

fun getThirtyDayAverage(date: LocalDateTime? = LocalDateTime.now()): Double {
return getPrices(start = date?.toLocalDate()?.minusDays(30)?.format(dateFormatter), end = null)
fun getThirtyDayAverage(date: LocalDate): Double {
val start = date.atStartOfDay().minusSeconds(30)
val end = date.plusDays(1).atStartOfDay().minusSeconds(1)
return getPrices(start, end)
.map { it.price }.average()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ie.daithi.electricityprices.exceptions.UnprocessableEntityException
import ie.daithi.electricityprices.model.DailyPriceInfo
import ie.daithi.electricityprices.model.Price
import ie.daithi.electricityprices.service.PriceService
import ie.daithi.electricityprices.utils.dateFormatter
import ie.daithi.electricityprices.web.validaton.ValidDateDay
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
Expand All @@ -18,6 +19,7 @@ import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.http.HttpStatus
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import java.time.LocalDate

@Validated
@RestController
Expand All @@ -30,23 +32,14 @@ class PriceController(
@GetMapping("/price")
@ResponseStatus(value = HttpStatus.OK)
@Operation(
summary = "Get price info", description = "Returns price info within the range provided. " +
"If no start date is provided the default is the start of the current day. If no end date is " +
"provided the default is the end of today. Dates should be given in a string form yyyy-MM-dd"
summary = "Get price info", description = "Returns price info for the day provided. If no day is provided it " +
"defaults to today. The day should be given in a string form yyyy-MM-dd"
)
@Parameter(
`in` = ParameterIn.QUERY,
name = "start",
schema = Schema(type = "string", pattern = "\\d{4}-\\d{2}-\\d{2}"),
description = "Start date for query (defaults to today)",
required = false,
example = "2023-08-30"
)
@Parameter(
`in` = ParameterIn.QUERY,
name = "end",
name = "date",
schema = Schema(type = "string", pattern = "\\d{4}-\\d{2}-\\d{2}"),
description = "End date for query (defaults to today)",
description = "The date to query (defaults to today)",
required = false,
example = "2023-08-30"
)
Expand Down Expand Up @@ -74,10 +67,10 @@ class PriceController(
)
@ResponseBody
fun getPrices(
@ValidDateDay @RequestParam(required = false) start: String?,
@ValidDateDay @RequestParam(required = false) end: String?
@ValidDateDay @RequestParam(required = false) date: String?,
): List<Price> {
return priceSerice.getPrices(start, end)
date ?: return priceSerice.getTodayPrices()
return priceSerice.getPrices(LocalDate.parse(date, dateFormatter))
}

@GetMapping("/price/dailyinfo")
Expand Down Expand Up @@ -135,6 +128,7 @@ class PriceController(
)
@ResponseBody
fun getDailyPriceInfo(@ValidDateDay @RequestParam(required = false) date: String?): DailyPriceInfo {
return priceSerice.getDailyPriceInfo(date) ?: throw DataNotAvailableYetException("No data available for $date")
date ?: return priceSerice.getTodayPriceInfo()
return priceSerice.getDailyPriceInfo(LocalDate.parse(date, dateFormatter))
}
}
6 changes: 5 additions & 1 deletion src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ spring:
profiles:
active:
${SPRING_PROFILES_ACTIVE:prod}
jackson.default-property-inclusion: non_null
jackson:
default-property-inclusion: non_null
serialization:
WRITE_DATES_AS_TIMESTAMPS: false
WRITE_DATES_WITH_ZONE_ID: true
mvc.pathmatch.matching-strategy: ant_path_matcher
data.mongodb.uri: ${MONGODB_URI:mongodb://localhost:27017/electricity-prices}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ class PriceServiceTest {

@Test
fun `getPrices - start and end`() {
val start = "2023-08-25"
val end = "2023-08-26"
val start = LocalDateTime.of(2023, 8, 24, 23, 59, 59)
val end = LocalDateTime.of(2023, 8, 26, 23, 59, 59)
val mockResponse: List<Price> = listOf(Price(LocalDateTime.now(), 1.0))

// Mocking the method
Expand All @@ -60,8 +60,8 @@ class PriceServiceTest {
// Verify the call to dateTimeBetween with specific arguments
verify {
priceRepo.dateTimeBetween(
LocalDate.parse(start, dateFormatter).atStartOfDay().minusSeconds(1),
LocalDate.parse(end, dateFormatter).plusDays(1).atStartOfDay().minusSeconds(1)
start,
end
)
}

Expand Down

0 comments on commit 93801b4

Please sign in to comment.