From 1bf3a5534727ca570868943e4cc08607a32bddf0 Mon Sep 17 00:00:00 2001
From: Tucker Siegel <tgsiegel@terpmail.umd.edu>
Date: Sat, 3 Dec 2022 13:11:48 -0500
Subject: [PATCH] allow repeats

---
 controllers/gdd_controller.go     |  5 +++--
 models/gdd.go                     | 25 +++++++++++++++++++++++++
 services/data_download_service.go |  2 +-
 services/forecast_service.go      |  2 +-
 services/gdd_service.go           |  4 ++--
 5 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/controllers/gdd_controller.go b/controllers/gdd_controller.go
index d482652..2c8f298 100644
--- a/controllers/gdd_controller.go
+++ b/controllers/gdd_controller.go
@@ -44,8 +44,9 @@ func GetDailyGdd(c *fiber.Ctx) error {
 // @Param latitude query number true "Latitude to search for"
 // @Param longitude query number true "Longitude to search for"
 // @Param accumulate query boolean true "Accumulate gdd values"
+// @Param repeatYears query number false "number of times to repeat the request. When included with planting date, will extrapolate plantingdate -> end of repeatYears range"
 // @Router /gdd/normals [get]
 func GetNormalGdd(c *fiber.Ctx) error {
-	request := models.BuildGddRequest(c)
-	return c.Status(fiber.StatusOK).JSON(services.GetNormalValues(request))
+	request, repeat := models.BuildNormalsGddRequest(c)
+	return c.Status(fiber.StatusOK).JSON(services.GetNormalValues(request, repeat))
 }
diff --git a/models/gdd.go b/models/gdd.go
index 6359241..7238ef5 100644
--- a/models/gdd.go
+++ b/models/gdd.go
@@ -29,6 +29,15 @@ type GddRequest struct {
 	PlantingDate time.Time `json:"plantingDate"`
 }
 
+type NormalsGddRequest struct {
+	Product      string    `json:"product"`
+	Latitude     float64   `json:"latitude"`
+	Longitude    float64   `json:"longitude"`
+	Accumulate   bool      `json:"accumulate"`
+	PlantingDate time.Time `json:"plantingDate"`
+	RepeatYears  int       `json:"repeatYears"`
+}
+
 func (r GddRequest) Validate() error {
 	return validation.ValidateStruct(&r,
 		// validation.Field(&r.Year, validation.Required, validation.Min(1981), validation.Max(time.Now().Year())),
@@ -88,6 +97,22 @@ var BuildGddRequest = func(c *fiber.Ctx) GddRequest {
 	return rNew
 }
 
+var BuildNormalsGddRequest = func(c *fiber.Ctx) (GddRequest, int) {
+	gddReq := BuildGddRequest(c)
+	repeatYears, errYears := strconv.Atoi(c.Query("repeatYears", "1"))
+
+	if errYears != nil {
+		panic(errors.NewBadRequest(nil).PutDetail("reason", "repeat years must be an integer"))
+	}
+
+	if repeatYears < 1 || repeatYears > 3 {
+		panic(errors.NewBadRequest(nil).PutDetail("reason", "repeat years must be between 1 and 3 inclusive"))
+	}
+
+	return gddReq, repeatYears
+
+}
+
 var BuildYearlessGddRequest = func(c *fiber.Ctx) GddRequest {
 	product := c.Query("product")
 	latitude, errLat := strconv.ParseFloat(c.Query("latitude"), 64)
diff --git a/services/data_download_service.go b/services/data_download_service.go
index 791c125..225cc9b 100644
--- a/services/data_download_service.go
+++ b/services/data_download_service.go
@@ -120,7 +120,7 @@ func getNormals(request models.CSVRequest, dates []time.Time) []float64 {
 		Accumulate:   true,
 	}
 
-	gddValues := GetNormalValues(gddRequest).GddValues
+	gddValues := GetNormalValues(gddRequest, 1).GddValues
 	for len(gddValues) < 365 {
 		gddValues = append(gddValues, math.NaN())
 	}
diff --git a/services/forecast_service.go b/services/forecast_service.go
index e5ff8ef..0bbdc43 100644
--- a/services/forecast_service.go
+++ b/services/forecast_service.go
@@ -239,7 +239,7 @@ func forecast(ctx common.DawnCtx, gddReq models.GddRequest, plantdate time.Time,
 //
 // this function allows normals to "wrap around" to get continuous values
 func comparisonNormals(request models.GddRequest, plantdate time.Time, matches map[string]float64) map[string]time.Time {
-	normals := GetNormalValues(request)
+	normals := GetNormalValues(request, 1)
 	observedValues := normals.GddValues
 	accumulatedGdds := 0.0
 	currentMatch := 0
diff --git a/services/gdd_service.go b/services/gdd_service.go
index 381e559..b6c1aa1 100644
--- a/services/gdd_service.go
+++ b/services/gdd_service.go
@@ -44,7 +44,7 @@ func GetGddValues(ctx common.DawnCtx, request models.GddRequest) models.GddRespo
 	return returnGdds
 }
 
-func GetNormalValues(request models.GddRequest) models.GddResponse {
+func GetNormalValues(request models.GddRequest, repeatYears int) models.GddResponse {
 	product := enums.GetProductFromString(request.Product)
 	gs := persistence.GetLastNormalsYearly(request.BuildLocation())
 	var returnGdds models.GddResponse
@@ -59,7 +59,7 @@ func GetNormalValues(request models.GddRequest) models.GddResponse {
 		sliceDateInt = 0
 	}
 
-	for i := sliceDateInt; i < len(gs[0].MinTemps)*2; i++ { //; i++ {
+	for i := sliceDateInt; i < len(gs[0].MinTemps)*repeatYears; i++ { //; i++ {
 		row := []float64{}
 		idx := i
 		if i >= len(gs[0].MinTemps) {
-- 
GitLab