Files
Gardomatic/internal/api/application_settings.go
T
kleiax 904d14b64c
CI / test (push) Canceled after 0s
Initial commit
2026-09-12 22:22:17 +02:00

101 lines
3.0 KiB
Go

package api
import (
"net/http"
"strings"
"time"
"gardomatic.kleiax.de/internal/platform/validate"
"gardomatic.kleiax.de/internal/storage"
)
type applicationSettingsInput struct {
LifecycleStatusEnabled *bool `json:"lifecycle_status_enabled"`
LifecycleRemovalMonth *int `json:"lifecycle_removal_month"`
LifecycleRemovalDay *int `json:"lifecycle_removal_day"`
Timezone *string `json:"timezone"`
}
func (input applicationSettingsInput) apply(settings *storage.ApplicationSettings) {
if input.LifecycleStatusEnabled != nil {
settings.LifecycleStatusEnabled = *input.LifecycleStatusEnabled
}
if input.LifecycleRemovalMonth != nil {
settings.LifecycleRemovalMonth = *input.LifecycleRemovalMonth
}
if input.LifecycleRemovalDay != nil {
settings.LifecycleRemovalDay = *input.LifecycleRemovalDay
}
if input.Timezone != nil {
settings.Timezone = strings.TrimSpace(*input.Timezone)
}
}
func (app *application) showAdminApplicationSettingsHandler(w http.ResponseWriter, r *http.Request) {
settings, err := app.models.ApplicationSettings.Get()
if err != nil {
app.respondToEntityModelError(w, r, err)
return
}
if err := app.writeJSON(w, http.StatusOK, envelope{"settings": settings}, nil); err != nil {
app.serverErrorResponse(w, r, err)
}
}
func (app *application) updateAdminApplicationSettingsHandler(w http.ResponseWriter, r *http.Request) {
settings, err := app.models.ApplicationSettings.Get()
if err != nil {
app.respondToEntityModelError(w, r, err)
return
}
var input applicationSettingsInput
if err := app.readJSON(w, r, &input); err != nil {
app.badRequestResponse(w, r, err)
return
}
input.apply(&settings)
v := validate.New()
storage.ValidateApplicationSettings(v, settings)
if !v.Valid() {
app.failedValidationResponse(w, r, v.Errors)
return
}
settings, err = app.models.ApplicationSettings.Update(settings)
if err != nil {
app.respondToEntityModelError(w, r, err)
return
}
if err := app.writeJSON(w, http.StatusOK, envelope{"settings": settings}, nil); err != nil {
app.serverErrorResponse(w, r, err)
}
}
func (app *application) runLifecycleMaintenance(now time.Time) error {
if app.models.ApplicationSettings == nil {
return nil
}
settings, err := app.models.ApplicationSettings.Get()
if err != nil || !settings.LifecycleStatusEnabled {
return err
}
location, err := time.LoadLocation(settings.Timezone)
if err != nil {
return err
}
localNow := now.In(location)
lastDay := time.Date(localNow.Year(), time.Month(settings.LifecycleRemovalMonth)+1, 0, 0, 0, 0, 0, location).Day()
day := settings.LifecycleRemovalDay
if day > lastDay {
day = lastDay
}
cutoff := time.Date(localNow.Year(), time.Month(settings.LifecycleRemovalMonth), day, 0, 0, 0, 0, location)
if localNow.Before(cutoff) {
return nil
}
count, err := app.models.ApplicationSettings.RemoveExpiredPlants(cutoff, settings.LifecycleRemovalMonth, day)
if err == nil && count > 0 {
app.logger.Info("removed plants which reached their configured lifecycle", "count", count, "cutoff", cutoff.Format("2006-01-02"))
}
return err
}