hour-tracker/back-end/main.go

121 lines
3.1 KiB
Go

package main
import (
"fmt"
"log"
"net/http"
"time"
"github.com/labstack/echo/v5"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/apis"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/models"
)
type Entry struct {
Project string
Start string
End string
}
type Project struct {
Id string
Name string
}
func main() {
app := pocketbase.New()
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
e.Router.GET("/hours/:organisation/:year/:month", func(c echo.Context) error {
year := c.PathParam("year")
month := c.PathParam("month")
organisation := c.PathParam("organisation")
projects := []Project{}
entries := []Entry{}
record, _ := c.Get(apis.ContextAuthRecordKey).(*models.Record)
if record == nil {
return c.JSON(http.StatusOK, map[string]any{"hours": 0, "error": "not logged in"})
}
err := app.Dao().DB().
NewQuery("SELECT * FROM projects WHERE organisation = {:organisation}").
Bind(dbx.Params{
"start": fmt.Sprintf("%s-%s-01 00:00:00.000Z", year, month),
"end": fmt.Sprintf("%s-%s-31 23:59:59.999Z", year, month),
"organisation": organisation,
"user": record.Id,
}).
All(&projects)
if err != nil {
return c.JSON(http.StatusOK, map[string]any{"hours": nil, "error": err})
}
err = app.Dao().DB().
NewQuery("SELECT * FROM entries WHERE user = {:user} AND start >= {:start} AND end <= {:end} AND end != '' AND project IN (SELECT id FROM projects WHERE organisation = {:organisation})").
Bind(dbx.Params{
"start": fmt.Sprintf("%s-%s-01 00:00:00.000Z", year, month),
"end": fmt.Sprintf("%s-%s-31 23:59:59.999Z", year, month),
"organisation": organisation,
"user": record.Id,
}).
All(&entries)
if err != nil {
return c.JSON(http.StatusOK, map[string]any{"hours": nil, "error": err})
}
var projects_map map[string]string
projects_map = make(map[string]string)
for _, e := range projects {
projects_map[e.Id] = e.Name
}
var hours map[string]float64
hours = make(map[string]float64)
for _, e := range entries {
start, err := time.Parse("2006-01-02 15:04:05.000Z", e.Start)
if err != nil {
return c.JSON(http.StatusOK, map[string]any{"hours": nil, "error": fmt.Sprintf("time.Parse(%s)", e.Start)})
}
end, err := time.Parse("2006-01-02 15:04:05.000Z", e.End)
if err != nil {
return c.JSON(http.StatusOK, map[string]any{"hours": nil, "error": fmt.Sprintf("time.Parse(%s)", e.End)})
}
var entry_hours = end.Sub(start).Hours()
project, project_exists := projects_map[e.Project]
if !project_exists {
return c.JSON(http.StatusOK, map[string]any{"hours": nil, "error": fmt.Sprintf("time.Parse(%s)", e.End)})
}
if value, total_entry_exists := hours[project]; total_entry_exists {
hours[project] = value + entry_hours
} else {
hours[project] = entry_hours
}
}
return c.JSON(http.StatusOK, map[string]any{"hours": hours, "error": nil})
})
return nil
})
if err := app.Start(); err != nil {
log.Fatal(err)
}
}