158 lines
4.2 KiB
Go
158 lines
4.2 KiB
Go
package api
|
|
|
|
import (
|
|
"fmt"
|
|
"gardomatic.kleiax.de/internal/platform/validate"
|
|
"gardomatic.kleiax.de/internal/storage"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
type careInstructionInput struct {
|
|
Text *string `json:"text"`
|
|
Status *string `json:"status"`
|
|
}
|
|
|
|
func (i careInstructionInput) apply(v *storage.CareInstruction) {
|
|
if i.Text != nil {
|
|
v.Text = strings.TrimSpace(*i.Text)
|
|
}
|
|
if i.Status != nil {
|
|
v.Status = *i.Status
|
|
}
|
|
}
|
|
func (app *application) validateCareInstruction(w http.ResponseWriter, r *http.Request, item storage.CareInstruction) bool {
|
|
v := validate.New()
|
|
storage.ValidateCareInstruction(v, item)
|
|
if !v.Valid() {
|
|
app.failedValidationResponse(w, r, v.Errors)
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
func (app *application) listCareInstructionsHandler(w http.ResponseWriter, r *http.Request) {
|
|
g, _ := app.readGardenIDParam(r)
|
|
s, e := app.readIDParam(r)
|
|
if e != nil {
|
|
app.notFoundResponse(w, r)
|
|
return
|
|
}
|
|
items, e := app.models.CareInstructions.GetAllForSpecies(g, s)
|
|
if e != nil {
|
|
app.respondToEntityModelError(w, r, e)
|
|
return
|
|
}
|
|
if e = app.writeJSON(w, http.StatusOK, envelope{"care_instructions": items}, nil); e != nil {
|
|
app.serverErrorResponse(w, r, e)
|
|
}
|
|
}
|
|
func (app *application) createCareInstructionHandler(w http.ResponseWriter, r *http.Request) {
|
|
g, _ := app.readGardenIDParam(r)
|
|
s, e := app.readIDParam(r)
|
|
if e != nil {
|
|
app.notFoundResponse(w, r)
|
|
return
|
|
}
|
|
if !app.canWriteCareInstructions(w, r, g, s) {
|
|
return
|
|
}
|
|
var input careInstructionInput
|
|
if e = app.readJSON(w, r, &input); e != nil {
|
|
app.badRequestResponse(w, r, e)
|
|
return
|
|
}
|
|
u, _ := app.contextGetAuthenticatedUser(r)
|
|
item := storage.CareInstruction{SpeciesID: s, Status: "untested", CreatedBy: u.ID, UpdatedBy: u.ID}
|
|
input.apply(&item)
|
|
if !app.validateCareInstruction(w, r, item) {
|
|
return
|
|
}
|
|
item, e = app.models.CareInstructions.Insert(item)
|
|
if e != nil {
|
|
app.respondToEntityModelError(w, r, e)
|
|
return
|
|
}
|
|
h := make(http.Header)
|
|
h.Set("Location", fmt.Sprintf("/v1/gardens/%d/species/%d/care-instructions/%d", g, s, item.ID))
|
|
_ = app.writeJSON(w, http.StatusCreated, envelope{"care_instruction": item}, h)
|
|
}
|
|
func (app *application) updateCareInstructionHandler(w http.ResponseWriter, r *http.Request) {
|
|
g, _ := app.readGardenIDParam(r)
|
|
s, e := app.readIDParam(r)
|
|
if e != nil {
|
|
app.notFoundResponse(w, r)
|
|
return
|
|
}
|
|
if !app.canWriteCareInstructions(w, r, g, s) {
|
|
return
|
|
}
|
|
id, e := app.readNamedIDParam(r, "instructionID")
|
|
if e != nil {
|
|
app.notFoundResponse(w, r)
|
|
return
|
|
}
|
|
item, e := app.models.CareInstructions.Get(g, s, id)
|
|
if e != nil {
|
|
app.respondToEntityModelError(w, r, e)
|
|
return
|
|
}
|
|
var input careInstructionInput
|
|
if e = app.readJSON(w, r, &input); e != nil {
|
|
app.badRequestResponse(w, r, e)
|
|
return
|
|
}
|
|
input.apply(&item)
|
|
u, _ := app.contextGetAuthenticatedUser(r)
|
|
item.UpdatedBy = u.ID
|
|
if !app.validateCareInstruction(w, r, item) {
|
|
return
|
|
}
|
|
item, e = app.models.CareInstructions.Update(g, item)
|
|
if e != nil {
|
|
app.respondToEntityModelError(w, r, e)
|
|
return
|
|
}
|
|
_ = app.writeJSON(w, http.StatusOK, envelope{"care_instruction": item}, nil)
|
|
}
|
|
func (app *application) deleteCareInstructionHandler(w http.ResponseWriter, r *http.Request) {
|
|
g, _ := app.readGardenIDParam(r)
|
|
s, e := app.readIDParam(r)
|
|
if e != nil {
|
|
app.notFoundResponse(w, r)
|
|
return
|
|
}
|
|
if !app.canWriteCareInstructions(w, r, g, s) {
|
|
return
|
|
}
|
|
id, e := app.readNamedIDParam(r, "instructionID")
|
|
if e != nil {
|
|
app.notFoundResponse(w, r)
|
|
return
|
|
}
|
|
if e = app.models.CareInstructions.Delete(g, s, id); e != nil {
|
|
app.respondToEntityModelError(w, r, e)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|
|
|
|
func (app *application) canWriteCareInstructions(w http.ResponseWriter, r *http.Request, gardenID, speciesID int) bool {
|
|
species, err := app.models.Species.Get(gardenID, speciesID)
|
|
if err != nil {
|
|
app.respondToEntityModelError(w, r, err)
|
|
return false
|
|
}
|
|
member, _ := app.contextGetGardenMember(r)
|
|
user, _ := app.contextGetAuthenticatedUser(r)
|
|
if species.GardenID == nil {
|
|
if !user.Can(storage.ApplicationPermissionGlobalSpeciesWrite) {
|
|
app.permissionDeniedResponse(w, r)
|
|
return false
|
|
}
|
|
} else if !member.Can(storage.GardenPermissionSpeciesWrite) {
|
|
app.permissionDeniedResponse(w, r)
|
|
return false
|
|
}
|
|
return true
|
|
}
|