GWM
@ -1,7 +1,7 @@
|
||||
[
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "_T",
|
||||
"CROP": "TOM",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
@ -12,12 +12,12 @@
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "21.6"
|
||||
"Value": "39.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "_T",
|
||||
"CROP": "TOM",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
@ -28,12 +28,12 @@
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "19.3"
|
||||
"Value": "27.4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "_T",
|
||||
"CROP": "TOM",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
@ -44,7 +44,583 @@
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "16.98945461"
|
||||
"Value": "26.47654791"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "EGG",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2020",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "63.8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "EGG",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2021",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "47.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "EGG",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2022",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "46.81231254"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "SQU",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2020",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "75.5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "SQU",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2021",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "78.6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "SQU",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2022",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "75.8811408"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "CUC",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2020",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "93.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "CUC",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2021",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "87.8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "CUC",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2022",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "85.30071041"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "WAT",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2020",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "1.8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "WAT",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2021",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "1.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "WAT",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2022",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "1.152487385"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "MEL",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2020",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "30.7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "MEL",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2021",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "12.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "MEL",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2022",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "9.008599616"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "PEP",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2020",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "15.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "PEP",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2021",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "15.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "PEP",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2022",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "13.39919274"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "OKR",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2020",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "18.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "OKR",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2021",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "11.5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "OKR",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2022",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "8.805405537"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "POT",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2020",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "0.5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "POT",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2021",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "0.9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "POT",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2022",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "0.52456682"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "LEA",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2020",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "41.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "LEA",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2021",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "55.8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "LEA",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2022",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "38.7830202"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "ONI",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2020",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "1.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "ONI",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2021",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "ONI",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2022",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "2.241648166"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "PUM",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2020",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "6.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "PUM",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2021",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "4.5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "PUM",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2022",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "6.247409254"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "LET",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2020",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "1.4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "LET",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2021",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "0.6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ObsKey": {
|
||||
"CROP": "LET",
|
||||
"CROP_TYPE": "SF",
|
||||
"CROP_UNIT": "QUANTITY",
|
||||
"FREQ": "A",
|
||||
"MEASURE": "TRADE",
|
||||
"REF_AREA": "AE",
|
||||
"SOURCE_DETAIL": "FCSACROP",
|
||||
"TIME_PERIOD": "2022",
|
||||
"UNIT_MEASURE": "PERCENT"
|
||||
},
|
||||
"ObsValue": {
|
||||
"Value": "0.652853161"
|
||||
}
|
||||
}
|
||||
]
|
||||
103
main.go
@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
@ -448,6 +449,15 @@ func filterDynamicChartData(chartData []map[string]interface{}, keyToFilter, val
|
||||
return filteredData
|
||||
}
|
||||
|
||||
func generateToken() string {
|
||||
bytes := make([]byte, 32)
|
||||
_, err := rand.Read(bytes)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return hex.EncodeToString(bytes)
|
||||
}
|
||||
|
||||
var app *pocketbase.PocketBase
|
||||
|
||||
func main() {
|
||||
@ -571,6 +581,99 @@ func main() {
|
||||
return c.File("pb_public/confirm_password_reset.html")
|
||||
})
|
||||
|
||||
e.Router.GET("/api/auth/request-password-reset", func(c echo.Context) error {
|
||||
email := c.QueryParam("email")
|
||||
if email == "" {
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{"error": "Email is required"})
|
||||
}
|
||||
|
||||
// Find user by email
|
||||
user, err := app.Dao().FindFirstRecordByData("users", "email", email)
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusNotFound, map[string]string{"error": "User not found"})
|
||||
}
|
||||
name := user.GetString("name")
|
||||
// Generate token
|
||||
token := generateToken()
|
||||
expiration := time.Now().Add(30 * time.Minute).UTC()
|
||||
|
||||
// Store token in the database
|
||||
user.Set("pw_reset_token", token)
|
||||
user.Set("pw_reset_token_expiry", expiration)
|
||||
|
||||
if err := app.Dao().SaveRecord(user); err != nil {
|
||||
return c.JSON(http.StatusInternalServerError, map[string]string{"error": "Failed to update user record"})
|
||||
}
|
||||
|
||||
// Send email
|
||||
subject := "Reset your FCSC password"
|
||||
resetURL := fmt.Sprintf("%s/api/auth/reset-password?token=%s", baseUrl, token)
|
||||
body := fmt.Sprintf(`
|
||||
<p>Hello,</p>
|
||||
<p>Click on the link below to reset your password.</p>
|
||||
<p>
|
||||
<a href="%s" target="_blank" rel="noopener" style="color: blue; text-decoration: underline;">Reset password</a>
|
||||
</p>
|
||||
<p><i>If you didn't ask to reset your password, you can ignore this email.</i></p>
|
||||
<p>
|
||||
Thanks,<br/>
|
||||
Your App Team<br/>
|
||||
</p>
|
||||
`, resetURL)
|
||||
|
||||
// Create the email message
|
||||
message := &mailer.Message{
|
||||
From: mail.Address{
|
||||
Name: "FCSC",
|
||||
Address: app.Settings().Meta.SenderAddress,
|
||||
},
|
||||
To: []mail.Address{
|
||||
{
|
||||
Name: name,
|
||||
Address: email,
|
||||
},
|
||||
},
|
||||
Subject: subject,
|
||||
HTML: body,
|
||||
}
|
||||
|
||||
// Send the email
|
||||
err = app.NewMailClient().Send(message)
|
||||
if err != nil {
|
||||
log.Printf("Failed to send verification email to user: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, map[string]string{"message": "Reset link sent to your email"})
|
||||
})
|
||||
|
||||
e.Router.GET("/api/auth/reset-password", func(c echo.Context) error {
|
||||
token := c.QueryParam("token")
|
||||
if token == "" {
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{"error": "Token is required"})
|
||||
}
|
||||
|
||||
// Find user with the token
|
||||
user, err := app.Dao().FindFirstRecordByData("users", "pw_reset_token", token)
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusUnauthorized, map[string]string{"error": "Invalid token"})
|
||||
}
|
||||
|
||||
// Convert PocketBase `types.DateTime` to `time.Time`
|
||||
expiryTime := user.GetDateTime("pw_reset_token_expiry").Time()
|
||||
log.Printf("expiryTime : '%v'", expiryTime)
|
||||
log.Printf("time.Now : '%v'", time.Now().UTC())
|
||||
if expiryTime.Before(time.Now().UTC()) {
|
||||
return c.File("pb_public/token_expired.html")
|
||||
// return c.JSON(http.StatusUnauthorized, map[string]string{"error": "Token expired"})
|
||||
}
|
||||
|
||||
// return c.JSON(http.StatusOK, map[string]string{"message": "Token is valid"})
|
||||
|
||||
// Serve the reset page
|
||||
return c.File("pb_public/confirm_password_reset.html")
|
||||
})
|
||||
|
||||
e.Router.GET("/api/login_success", func(c echo.Context) error {
|
||||
|
||||
userID := c.QueryParam("id")
|
||||
|
||||
BIN
pb_data/data.db
BIN
pb_data/logs.db
|
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"QtQNpYi5me0OVZxMW9h2Zg=="}
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"uiU2k7ZNxToo4t8GzxMZpg=="}
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"Bd8Ei+2GWlcr7qQbIw2nBA=="}
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"p4keTgIQ5xOAU8VuKT5dcw=="}
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"07ogwztZgxRY87I+T3YS6w=="}
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"uiU2k7ZNxToo4t8GzxMZpg=="}
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"d+BsCUhtU7PtTiNIG3YEzg=="}
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"uiU2k7ZNxToo4t8GzxMZpg=="}
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"QtQNpYi5me0OVZxMW9h2Zg=="}
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"Bd8Ei+2GWlcr7qQbIw2nBA=="}
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"w0Nm4f4pCYaIpDpuEhQVHg=="}
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"JemDzB+TNQLWrDLe1lxu6g=="}
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"w0Nm4f4pCYaIpDpuEhQVHg=="}
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"JemDzB+TNQLWrDLe1lxu6g=="}
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":{"original-filename":"male.png"},"md5":"gq2puo4WHB/p8O/dYe6AZA=="}
|
||||
|
After Width: | Height: | Size: 8.0 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"Ua07BI7xJGVJ7eVStoTK3g=="}
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"uiU2k7ZNxToo4t8GzxMZpg=="}
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":{"original-filename":"kpi_icon_population.png"},"md5":"BPQklAKzE1awhyRzVAam6A=="}
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"r8v3ja0ZOKOy5aQ9I7h7CQ=="}
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"QtQNpYi5me0OVZxMW9h2Zg=="}
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":{"original-filename":"female.png"},"md5":"LHr3qNvXccxDzGNR1QwAiA=="}
|
||||
|
After Width: | Height: | Size: 7.5 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"6qNv8XkjaWR5lPp91glyrw=="}
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"uiU2k7ZNxToo4t8GzxMZpg=="}
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"QtQNpYi5me0OVZxMW9h2Zg=="}
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"d+BsCUhtU7PtTiNIG3YEzg=="}
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"srBd6fWEm86XwUV6j55geA=="}
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"p4keTgIQ5xOAU8VuKT5dcw=="}
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"mccsVPwG7Fogdc5/VZLFKg=="}
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"mccsVPwG7Fogdc5/VZLFKg=="}
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"mccsVPwG7Fogdc5/VZLFKg=="}
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"uiU2k7ZNxToo4t8GzxMZpg=="}
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"PMmkMsIDsFA+XGvZjuhYhA=="}
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"srBd6fWEm86XwUV6j55geA=="}
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"uiU2k7ZNxToo4t8GzxMZpg=="}
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
@ -0,0 +1 @@
|
||||
{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"image/png","user.metadata":null,"md5":"srBd6fWEm86XwUV6j55geA=="}
|
||||
52
pb_public/token_expired.html
Normal file
@ -0,0 +1,52 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Token Expired</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f8f9fa;
|
||||
text-align: center;
|
||||
padding: 50px;
|
||||
}
|
||||
.container {
|
||||
max-width: 400px;
|
||||
margin: auto;
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
h1 {
|
||||
color: #d9534f;
|
||||
}
|
||||
p {
|
||||
color: #6c757d;
|
||||
}
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 10px 20px;
|
||||
margin-top: 20px;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
background-color: #007bff;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.btn:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<h1>Token Expired</h1>
|
||||
<p>Sorry, the reset link has expired.</p>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -24,15 +24,20 @@ type GroupByAndSum struct {
|
||||
GetTop int `json:"get_top"`
|
||||
Conversion int `json:"conversion"`
|
||||
}
|
||||
type CountCalculation struct {
|
||||
Key string `json:"key"`
|
||||
GetCountOf string `json:"get_count_of"`
|
||||
}
|
||||
type CardCalculationRequest struct {
|
||||
Formula string `json:"formula"`
|
||||
RecordCount string `json:"record_count"`
|
||||
RecodeIndex string `json:"record_index"`
|
||||
RecordKey string `json:"record_key"`
|
||||
AdditionalRecordKey string `json:"additional_record_key"`
|
||||
NumberFormat string `json:"number_format"`
|
||||
Conversion string `json:"conversion"`
|
||||
GroupByAndSum GroupByAndSum `json:"groupby_and_sum"`
|
||||
Formula string `json:"formula"`
|
||||
RecordCount string `json:"record_count"`
|
||||
RecodeIndex string `json:"record_index"`
|
||||
RecordKey string `json:"record_key"`
|
||||
AdditionalRecordKey string `json:"additional_record_key"`
|
||||
NumberFormat string `json:"number_format"`
|
||||
Conversion string `json:"conversion"`
|
||||
GroupByAndSum GroupByAndSum `json:"groupby_and_sum"`
|
||||
CountCalculation CountCalculation `json:"count_calculation"`
|
||||
}
|
||||
|
||||
func CardCalculation(data []Observation, req CardCalculationRequest) (map[string]string, error) {
|
||||
@ -43,13 +48,24 @@ func CardCalculation(data []Observation, req CardCalculationRequest) (map[string
|
||||
|
||||
var selectedData []Observation
|
||||
if req.RecodeIndex != "" {
|
||||
// Convert RecodeIndex to an integer
|
||||
index, err := strconv.Atoi(req.RecodeIndex)
|
||||
if err != nil || index < 0 || index >= len(data) {
|
||||
// return nil, errors.New("invalid record index")
|
||||
selectedData = []Observation{}
|
||||
|
||||
if req.RecodeIndex == "last" {
|
||||
index := len(data)
|
||||
if index < 0 || index >= len(data) {
|
||||
selectedData = []Observation{}
|
||||
} else {
|
||||
selectedData = []Observation{data[index]}
|
||||
}
|
||||
|
||||
} else {
|
||||
selectedData = []Observation{data[index]}
|
||||
// Convert RecodeIndex to an integer
|
||||
index, err := strconv.Atoi(req.RecodeIndex)
|
||||
if err != nil || index < 0 || index >= len(data) {
|
||||
selectedData = []Observation{}
|
||||
} else {
|
||||
selectedData = []Observation{data[index]}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -132,6 +148,32 @@ func CardCalculation(data []Observation, req CardCalculationRequest) (map[string
|
||||
} else {
|
||||
fmt.Println("No observations returned from CalculateGroupedSum")
|
||||
}
|
||||
case "count_calculation":
|
||||
countCalculationReq := req.CountCalculation
|
||||
|
||||
var cardCountCalculationRequest CountCalculation
|
||||
|
||||
jsonData, err := json.Marshal(countCalculationReq)
|
||||
if err != nil {
|
||||
fmt.Println("Error:", err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(jsonData, &cardCountCalculationRequest)
|
||||
if err != nil {
|
||||
fmt.Println("Error:", err)
|
||||
}
|
||||
|
||||
selectedData, err = CalculateCount(selectedData, cardCountCalculationRequest)
|
||||
if err != nil {
|
||||
fmt.Println("Error:", err)
|
||||
}
|
||||
|
||||
if len(selectedData) > 0 {
|
||||
result = float64(len(selectedData))
|
||||
selectedData = selectedData[:1]
|
||||
} else {
|
||||
fmt.Println("No observations returned from CalculateGroupedSum")
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, errors.New("invalid formula")
|
||||
@ -200,17 +242,26 @@ func average(data []Observation) float64 {
|
||||
}
|
||||
|
||||
func highest(data []Observation) float64 {
|
||||
if len(data) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
max := getFloatValue(data[0].ObsValue.Value)
|
||||
for _, obs := range data {
|
||||
for _, obs := range data[1:] {
|
||||
val := getFloatValue(obs.ObsValue.Value)
|
||||
if val > max {
|
||||
max = val
|
||||
}
|
||||
}
|
||||
return max
|
||||
|
||||
}
|
||||
|
||||
func lowest(data []Observation) float64 {
|
||||
if len(data) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
min := getFloatValue(data[0].ObsValue.Value)
|
||||
for _, obs := range data {
|
||||
val := getFloatValue(obs.ObsValue.Value)
|
||||
@ -315,7 +366,7 @@ func applyConversion(value float64, conversion string, numberFormat string) stri
|
||||
case "%":
|
||||
return formatNumber(value, "%")
|
||||
default:
|
||||
return formatNumber(value, "")
|
||||
return formatNumber(value, conversion)
|
||||
}
|
||||
}
|
||||
|
||||
@ -357,7 +408,23 @@ func extractRecordKeyValue(data []Observation, key string, additionalkey string,
|
||||
}
|
||||
return val1
|
||||
}
|
||||
case "count_calculation":
|
||||
for _, obs := range data {
|
||||
|
||||
if val, exists := obs.ObsKey[key]; exists {
|
||||
|
||||
// Check if additionalkey exists in obs.ObsKey
|
||||
if val2, exists2 := obs.ObsKey[additionalkey]; exists2 {
|
||||
|
||||
return val + " - " + val2
|
||||
} else {
|
||||
return val
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@ -658,3 +725,43 @@ func FilterByMultipleKeys(data []Observation, filters []Filter) ([]Observation,
|
||||
|
||||
return filteredData, nil
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- Count Calculation -------------------------------------------------
|
||||
|
||||
func CalculateCount(observations []Observation, request CountCalculation) ([]Observation, error) {
|
||||
|
||||
if request.GetCountOf == "highest" || request.GetCountOf == "lowest" {
|
||||
var extremeValue int
|
||||
var filteredObservations []Observation
|
||||
first := true
|
||||
isHighest := request.GetCountOf == "highest"
|
||||
|
||||
for _, obs := range observations {
|
||||
if valStr, exists := obs.ObsKey[request.Key]; exists {
|
||||
val, err := strconv.Atoi(valStr)
|
||||
if err != nil {
|
||||
continue // Skip if conversion fails
|
||||
}
|
||||
|
||||
if first || (isHighest && val > extremeValue) || (!isHighest && val < extremeValue) {
|
||||
extremeValue = val
|
||||
first = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter observations that match the extreme value
|
||||
for _, obs := range observations {
|
||||
if valStr, exists := obs.ObsKey[request.Key]; exists {
|
||||
val, err := strconv.Atoi(valStr)
|
||||
if err == nil && val == extremeValue {
|
||||
filteredObservations = append(filteredObservations, obs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return filteredObservations, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unsupported get_count_of value: %s", request.GetCountOf)
|
||||
}
|
||||
|
||||