180 lines
4.9 KiB
Go
180 lines
4.9 KiB
Go
package web
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"gardomatic.kleiax.de/lib/client"
|
|
)
|
|
|
|
type assignmentForm struct {
|
|
CSRFToken string `form:"csrf_token"`
|
|
LocationID int `form:"location_id"`
|
|
Quantity int `form:"quantity"`
|
|
PlantedAt string `form:"planted_at"`
|
|
Notes string `form:"notes"`
|
|
Errors map[string]string
|
|
}
|
|
|
|
func (app *application) plantLocationCreate(w http.ResponseWriter, r *http.Request) {
|
|
app.renderPlantLocationForm(w, r, assignmentForm{Quantity: 1, Errors: map[string]string{}}, http.StatusOK, 0)
|
|
}
|
|
func (app *application) plantLocationEdit(w http.ResponseWriter, r *http.Request) {
|
|
gardenID, err := app.readPathID(r, "gardenID")
|
|
if err != nil {
|
|
app.notFound(w)
|
|
return
|
|
}
|
|
plantID, err := app.readPathID(r, "plantID")
|
|
if err != nil {
|
|
app.notFound(w)
|
|
return
|
|
}
|
|
assignmentID, err := app.readPathID(r, "assignmentID")
|
|
if err != nil {
|
|
app.notFound(w)
|
|
return
|
|
}
|
|
items, _, err := client.FromContext(r.Context()).PlantLocations(r.Context(), gardenID, plantID)
|
|
if err != nil {
|
|
app.handleAPIError(w, r, err)
|
|
return
|
|
}
|
|
form := assignmentForm{Errors: map[string]string{}}
|
|
found := false
|
|
for _, item := range items {
|
|
if item.ID == assignmentID {
|
|
found = true
|
|
form.LocationID = item.LocationID
|
|
form.Quantity = item.Quantity
|
|
form.Notes = item.Notes
|
|
if item.PlantedAt != nil {
|
|
form.PlantedAt = item.PlantedAt.Format("2006-01-02")
|
|
}
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
app.notFound(w)
|
|
return
|
|
}
|
|
app.renderPlantLocationForm(w, r, form, http.StatusOK, assignmentID)
|
|
}
|
|
func (app *application) plantLocationSave(w http.ResponseWriter, r *http.Request) {
|
|
gardenID, err := app.readPathID(r, "gardenID")
|
|
if err != nil {
|
|
app.notFound(w)
|
|
return
|
|
}
|
|
plantID, err := app.readPathID(r, "plantID")
|
|
if err != nil {
|
|
app.notFound(w)
|
|
return
|
|
}
|
|
assignmentID, _ := app.readPathID(r, "assignmentID")
|
|
var form assignmentForm
|
|
if err = app.decodePostForm(r, &form); err != nil {
|
|
app.clientError(w, http.StatusBadRequest)
|
|
return
|
|
}
|
|
form.Notes = strings.TrimSpace(form.Notes)
|
|
form.Errors = map[string]string{}
|
|
if form.LocationID < 1 {
|
|
form.Errors["location_id"] = "Ein Ort ist erforderlich."
|
|
}
|
|
if form.Quantity < 1 {
|
|
form.Errors["quantity"] = "Die Anzahl muss mindestens 1 sein."
|
|
}
|
|
var plantedAt *time.Time
|
|
if form.PlantedAt != "" {
|
|
parsed, parseErr := time.Parse("2006-01-02", form.PlantedAt)
|
|
if parseErr != nil {
|
|
form.Errors["planted_at"] = "Das Datum ist ungültig."
|
|
} else {
|
|
plantedAt = &parsed
|
|
}
|
|
}
|
|
if len(form.Errors) == 0 {
|
|
locationID, quantity, notes := form.LocationID, form.Quantity, form.Notes
|
|
input := client.PlantLocationInput{LocationID: &locationID, Quantity: &quantity, PlantedAt: plantedAt, ClearPlantedAt: plantedAt == nil, Notes: ¬es}
|
|
apiClient := client.FromContext(r.Context())
|
|
if assignmentID > 0 {
|
|
_, _, err = apiClient.UpdatePlantLocation(r.Context(), gardenID, plantID, assignmentID, input)
|
|
} else {
|
|
_, _, err = apiClient.CreatePlantLocation(r.Context(), gardenID, plantID, input)
|
|
}
|
|
if err == nil {
|
|
http.Redirect(w, r, webPath("plants", gardenID), http.StatusSeeOther)
|
|
return
|
|
}
|
|
var apiError *client.APIError
|
|
if errors.As(err, &apiError) && apiError.StatusCode == http.StatusUnprocessableEntity {
|
|
form.Errors = apiError.Validation
|
|
} else {
|
|
app.handleAPIError(w, r, err)
|
|
return
|
|
}
|
|
}
|
|
app.renderPlantLocationForm(w, r, form, http.StatusUnprocessableEntity, assignmentID)
|
|
}
|
|
func (app *application) plantLocationDeletePost(w http.ResponseWriter, r *http.Request) {
|
|
gardenID, err := app.readPathID(r, "gardenID")
|
|
if err != nil {
|
|
app.notFound(w)
|
|
return
|
|
}
|
|
plantID, err := app.readPathID(r, "plantID")
|
|
if err != nil {
|
|
app.notFound(w)
|
|
return
|
|
}
|
|
assignmentID, err := app.readPathID(r, "assignmentID")
|
|
if err != nil {
|
|
app.notFound(w)
|
|
return
|
|
}
|
|
if _, err = client.FromContext(r.Context()).DeletePlantLocation(r.Context(), gardenID, plantID, assignmentID); err != nil {
|
|
app.handleAPIError(w, r, err)
|
|
return
|
|
}
|
|
http.Redirect(w, r, webPath("plants", gardenID), http.StatusSeeOther)
|
|
}
|
|
func (app *application) renderPlantLocationForm(w http.ResponseWriter, r *http.Request, form assignmentForm, status, assignmentID int) {
|
|
gardenID, err := app.readPathID(r, "gardenID")
|
|
if err != nil {
|
|
app.notFound(w)
|
|
return
|
|
}
|
|
plantID, err := app.readPathID(r, "plantID")
|
|
if err != nil {
|
|
app.notFound(w)
|
|
return
|
|
}
|
|
apiClient := client.FromContext(r.Context())
|
|
garden, _, err := apiClient.Garden(r.Context(), gardenID)
|
|
if err != nil {
|
|
app.handleAPIError(w, r, err)
|
|
return
|
|
}
|
|
plant, _, err := apiClient.Plant(r.Context(), gardenID, plantID)
|
|
if err != nil {
|
|
app.handleAPIError(w, r, err)
|
|
return
|
|
}
|
|
locations, _, err := apiClient.Locations(r.Context(), gardenID)
|
|
if err != nil {
|
|
app.handleAPIError(w, r, err)
|
|
return
|
|
}
|
|
data := app.newTemplateData(r)
|
|
data.Garden = &garden
|
|
data.Plants = []client.Plant{plant}
|
|
data.PlantID = plantID
|
|
data.LocationID = assignmentID
|
|
data.Locations = locations
|
|
data.Form = form
|
|
app.render(w, status, "plant_location_form.tmpl", data)
|
|
}
|