116 lines
2.9 KiB
Go
116 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/pocketbase/dbx"
|
|
"github.com/pocketbase/pocketbase"
|
|
"github.com/pocketbase/pocketbase/apis"
|
|
"github.com/pocketbase/pocketbase/core"
|
|
"github.com/pocketbase/pocketbase/plugins/migratecmd"
|
|
|
|
_ "myapp/migrations"
|
|
)
|
|
|
|
type Entry struct {
|
|
Project string
|
|
Start string
|
|
End string
|
|
}
|
|
|
|
type Project struct {
|
|
Id string
|
|
Identifier string
|
|
Name string
|
|
}
|
|
|
|
func main() {
|
|
app := pocketbase.New()
|
|
migratecmd.MustRegister(app, app.RootCmd, migratecmd.Config{
|
|
Automigrate: false,
|
|
})
|
|
|
|
app.OnServe().BindFunc(func(e *core.ServeEvent) error {
|
|
e.Router.GET("/api/hours/{organisation}/{year}/{month}", func(c *core.RequestEvent) error {
|
|
year := c.Request.PathValue("year")
|
|
month := c.Request.PathValue("month")
|
|
organisation := c.Request.PathValue("organisation")
|
|
|
|
projects := []Project{}
|
|
entries := []Entry{}
|
|
|
|
err := app.DB().
|
|
NewQuery("SELECT * FROM projects WHERE organisation = {:organisation}").
|
|
Bind(dbx.Params{
|
|
"organisation": organisation,
|
|
}).
|
|
All(&projects)
|
|
|
|
if err != nil {
|
|
return c.JSON(http.StatusOK, map[string]any{"hours": nil, "error": err})
|
|
}
|
|
|
|
err = app.DB().
|
|
NewQuery("SELECT * FROM entries WHERE 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,
|
|
}).
|
|
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] = fmt.Sprintf("(%s) %s", e.Identifier, 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})
|
|
}).Bind(apis.RequireAuth())
|
|
|
|
return e.Next()
|
|
})
|
|
|
|
if err := app.Start(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|