package health import ( "fmt" "sync" "time" "github.com/eternal-flame-AD/yoake/internal/db" "github.com/eternal-flame-AD/yoake/internal/echoerror" "github.com/eternal-flame-AD/yoake/internal/util" "github.com/labstack/echo/v4" ) func RESTComplianceLogGet(database db.DB) func(c echo.Context) error { return func(c echo.Context) error { filterKeyname := c.Param("med") from := c.QueryParam("from") to := c.QueryParam("to") if to == "" { to = time.Now().Format("2006-01-02") } if from == "" { from = time.Now().AddDate(0, 0, -30).Format("2006-01-02") } fromTime, err := time.Parse("2006-01-02", from) if err != nil { return echoerror.NewHttp(400, err) } toTime, err := time.Parse("2006-01-02", to) if err != nil { return echoerror.NewHttp(400, err) } period := util.NewDateRange(fromTime, toTime) if days := period.Days(); days > 180 { return echoerror.NewHttp(400, fmt.Errorf("invalid date range: %v", period)) } logs, err := DBMedComplianceLogGet(database, period) if db.IsNotFound(err) || logs == nil { return c.JSON(200, ComplianceLogList{}) } else if err != nil { return echoerror.NewHttp(500, err) } if filterKeyname != "" { filtered := make(ComplianceLogList, 0, len(logs)) for _, log := range logs { if log.MedKeyname == filterKeyname { filtered = append(filtered, log) } } logs = filtered } return c.JSON(200, logs) } } func RESTComplianceLogPost(db db.DB, writeMutex *sync.Mutex) echo.HandlerFunc { return func(c echo.Context) error { var input ComplianceLog if err := c.Bind(&input); err != nil { return echoerror.NewHttp(400, err) } if input.Actual.Time.IsZero() { return echoerror.NewHttp(400, fmt.Errorf("invalid date")) } writeMutex.Lock() defer writeMutex.Unlock() meds, err := DBMedListGet(db) if err != nil { return echoerror.NewHttp(500, err) } var dir *Direction for _, med := range meds { d := med if med.KeyName() == input.MedKeyname { dir = &d } else if med.Name == input.MedKeyname { input.MedKeyname = med.KeyName() dir = &d } } if dir == nil { return echoerror.NewHttp(404, fmt.Errorf("med not found")) } if err := DBMedComplianceLogSetOne(db, *dir, &input); err != nil { return err } if input.Actual.Dose <= 0 { return c.NoContent(204) } return c.JSON(200, input) } } func RESTComplianceLogProjectMed(db db.DB) func(c echo.Context) error { return func(c echo.Context) error { keyName := c.Param("med") meds, err := DBMedListGet(db) if err != nil { return echoerror.NewHttp(500, err) } var dir *Direction for _, med := range meds { if med.KeyName() == keyName { d := med dir = &d } } if dir == nil { return echoerror.NewHttp(404, fmt.Errorf("med not found")) } complianceLog, err := DBMedComplianceLogGet(db, util.DateRangeAround(time.Now(), 1)) if err != nil { return echoerror.NewHttp(500, err) } return c.JSON(200, complianceLog.ProjectNextDose(*dir)) } }