-
Tucker Gary Siegel authoredTucker Gary Siegel authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
gdd.go 4.92 KiB
package models
import (
"strconv"
"time"
"gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/config"
"gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/persistence/entities"
"gitlab.cs.umd.edu/dawn/go-backend/dawn-gdd/utils"
validation "github.com/go-ozzo/ozzo-validation"
"github.com/gofiber/fiber/v2"
"github.com/tgs266/dawn-go-common/errors"
)
type GddResponse struct {
Product string `json:"product"`
ClosestLatitude float64 `json:"closest_latitude"`
ClosestLongitude float64 `json:"closest_longitude"`
GddValues []float64 `json:"gdd_values"`
LastDate time.Time `json:"last_date"`
}
type GddRequest struct {
Product string `json:"product"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
Accumulate bool `json:"accumulate"`
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())),
validation.Field(&r.Product, validation.Required, validation.Length(1, 100)),
validation.Field(&r.Latitude, validation.Required, validation.Min(-90.0), validation.Max(90.0)),
validation.Field(&r.Longitude, validation.Required, validation.Min(-180.0), validation.Max(180.0)),
)
}
func (r GddRequest) ValidateNoYear() error {
return validation.ValidateStruct(&r,
validation.Field(&r.Product, validation.Required, validation.Length(1, 100)),
validation.Field(&r.Latitude, validation.Required, validation.Min(-90.0), validation.Max(90.0)),
validation.Field(&r.Longitude, validation.Required, validation.Min(-180.0), validation.Max(180.0)),
)
}
var BuildGddRequest = func(c *fiber.Ctx) GddRequest {
year, errYear := strconv.Atoi(c.Query("year", strconv.Itoa(time.Now().Year())))
product := c.Query("product")
pd := c.Query("plantingDate", utils.GetFirstOfTheYear().Format(time.RFC3339))
latitude, errLat := strconv.ParseFloat(c.Query("latitude"), 64)
longitude, errLon := strconv.ParseFloat(c.Query("longitude"), 64)
accumulate, errBool := strconv.ParseBool(c.Query("accumulate", "false"))
plantingDate, errDate := time.Parse(time.RFC3339, pd)
if errYear != nil || errLat != nil || errLon != nil || errBool != nil {
panic(config.BAD_REQUEST)
}
if errDate != nil {
panic(errors.NewBadRequest(nil).PutDetail("reason", "no planting date provided"))
}
if errDate != nil && pd != "" {
panic(errors.NewBadRequest(nil).PutDetail("reason", "date must be ISO8601 or RFC3339 format"))
}
// provided an override year
// used mostly for doing analog years where we dont provide a date
// if the years are different and the planting date year is this year, we override
if year != plantingDate.Year() && plantingDate.Year() == time.Now().Year() {
plantingDate = utils.GetFirstOfTheYearForYear(year)
}
rNew := GddRequest{
Product: product,
Latitude: latitude,
Longitude: longitude,
Accumulate: accumulate,
PlantingDate: plantingDate,
}
if e := rNew.Validate(); e != nil {
panic(errors.NewBadRequest(e).AddLogDetails(e.Error()))
}
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)
longitude, errLon := strconv.ParseFloat(c.Query("longitude"), 64)
accumulate, errBool := strconv.ParseBool(c.Query("accumulate", "false"))
if errLat != nil || errLon != nil || errBool != nil {
panic(config.BAD_REQUEST)
}
rNew := GddRequest{
Product: product,
Latitude: latitude,
Longitude: longitude,
Accumulate: accumulate,
}
if e := rNew.ValidateNoYear(); e != nil {
panic(errors.NewBadRequest(e).AddLogDetails(e.Error()))
}
return rNew
}
func (r GddRequest) BuildLocation() entities.Location {
l := entities.Location{
Type: "Point",
Coordinates: []float64{r.Longitude, r.Latitude},
}
return l
}
func BuildLocation(lat float64, lng float64) entities.Location {
l := entities.Location{
Type: "Point",
Coordinates: []float64{lng, lat},
}
return l
}