You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
quartermaster/pkg/api/items/views.go

204 lines
6.1 KiB

package items
import (
"encoding/json"
"net/http"
"strconv"
"github.com/dustinpianalto/errors"
"github.com/dustinpianalto/quartermaster"
"github.com/dustinpianalto/quartermaster/pkg/services"
"github.com/gorilla/mux"
)
type addItemRequest struct {
Location quartermaster.Location `json:"location"`
quartermaster.Item
}
type itemsResponse struct {
Count int `json:"count"`
*quartermaster.Item
}
func items(w *http.ResponseWriter, r *http.Request, user *quartermaster.User) error {
const method errors.Method = "items"
if r.Method == "POST" {
err := addItem(w, r, user)
if err != nil {
return errors.E(method, "there was a problem adding the item", err)
}
} else if r.Method == "GET" {
err := getItems(w, r, user)
if err != nil {
return errors.E(method, "there was a problem getting items", err)
}
} else {
return errors.E(method, errors.Malformed, "http method not allowed")
}
return nil
}
func addItem(w *http.ResponseWriter, r *http.Request, user *quartermaster.User) error {
const method errors.Method = "items/addItem"
var ir addItemRequest
err := json.NewDecoder(r.Body).Decode(&ir)
if err != nil {
return errors.E(method, errors.Malformed, "failed to decode item request", err)
}
if ir.Name == "" || ir.Description == "" || ir.Size == 0.0 || ir.Barcode == "" {
return errors.E(method, errors.Malformed, "name, description, and size, and barcode are requred")
}
i, err := services.ItemService.AddItem(&ir.Item, &ir.Location, user)
if err != nil {
return errors.E(method, errors.Internal, "error adding item to location", err)
}
iJson, err := json.Marshal(i)
if err != nil {
return errors.E(method, errors.Internal, "error marshalling item", err)
}
(*w).Header().Set("Content-Type", "application/json")
(*w).WriteHeader(http.StatusCreated)
(*w).Write(iJson)
return nil
}
func getItems(w *http.ResponseWriter, r *http.Request, user *quartermaster.User) error {
const method errors.Method = "items/getItems"
var l *quartermaster.Location
err := json.NewDecoder(r.Body).Decode(&l)
if err != nil {
return errors.E(method, errors.Malformed, "failed to decode location", err)
}
if l.ID == 0 {
return errors.E(method, errors.Malformed, "id is required")
}
items, err := services.LocationService.GetItems(l, user)
if err != nil {
return errors.E(method, "problem getting items", err)
}
var itemsResp []itemsResponse
for i, c := range items {
itemsResp = append(itemsResp, itemsResponse{Count: c, Item: i})
}
itemsJson, err := json.Marshal(itemsResp)
if err != nil {
return errors.E(method, errors.Internal, "error marshalling items", err)
}
(*w).Header().Set("Content-Type", "application/json")
(*w).WriteHeader(http.StatusOK)
(*w).Write(itemsJson)
return nil
}
func getItemByBarcode(w *http.ResponseWriter, r *http.Request, user *quartermaster.User) error {
const method errors.Method = "items/getItemByBarcode"
params := mux.Vars(r)
barcodeString := params["barcode"]
item, err := services.ItemService.GetItemByBarcode(barcodeString, user)
if err != nil {
return errors.E(method, "problem getting items", err)
}
if item != nil {
itemJson, err := json.Marshal(item)
if err != nil {
return errors.E(method, errors.Internal, "error marshalling items", err)
}
(*w).Header().Set("Content-Type", "application/json")
(*w).WriteHeader(http.StatusOK)
(*w).Write(itemJson)
} else {
(*w).Header().Set("Content-Type", "application/json")
(*w).WriteHeader(http.StatusNotFound)
}
return nil
}
func moveItem(w *http.ResponseWriter, r *http.Request, user *quartermaster.User) error {
const method errors.Method = "items/moveItem"
params := mux.Vars(r)
itemID, err := strconv.Atoi(params["id"])
if err != nil {
return errors.E(method, errors.Malformed, "id must be a valid number")
}
var req map[string]int
err = json.NewDecoder(r.Body).Decode(&req)
if err != nil {
return errors.E(method, errors.Malformed, "failed to decode request", err)
}
if _, ok := req["old_id"]; !ok {
return errors.E(method, errors.Malformed, "old_id is required")
}
if _, ok := req["new_id"]; !ok {
return errors.E(method, errors.Malformed, "new_id is required")
}
item := &quartermaster.Item{
ID: itemID,
}
old := &quartermaster.Location{
ID: req["old_id"],
}
new := &quartermaster.Location{
ID: req["new_id"],
}
err = services.ItemService.MoveItem(item, old, new, user)
if err != nil {
return errors.E(method, errors.Internal, "error moving item", err)
}
(*w).WriteHeader(http.StatusOK)
return nil
}
func removeItem(w *http.ResponseWriter, r *http.Request, user *quartermaster.User) error {
const method errors.Method = "items/removeItem"
params := mux.Vars(r)
itemID, err := strconv.Atoi(params["id"])
if err != nil {
return errors.E(method, errors.Malformed, "id must be a valid number")
}
var req map[string]int
err = json.NewDecoder(r.Body).Decode(&req)
if err != nil {
return errors.E(method, errors.Malformed, "failed to decode request", err)
}
if _, ok := req["location_id"]; !ok {
return errors.E(method, errors.Malformed, "location_id is required")
}
item := &quartermaster.Item{
ID: itemID,
}
location := &quartermaster.Location{
ID: req["location_id"],
}
err = services.ItemService.RemoveItem(item, location, user)
if err != nil {
return errors.E(method, errors.Internal, "error removing item", err)
}
(*w).WriteHeader(http.StatusOK)
return nil
}
func getLocationCount(w *http.ResponseWriter, r *http.Request, user *quartermaster.User) error {
const method errors.Method = "items/getLocationCount"
params := mux.Vars(r)
itemID, err := strconv.Atoi(params["id"])
if err != nil {
return errors.E(method, errors.Malformed, "id must be a valid number", err)
}
i := &quartermaster.Item{
ID: itemID,
}
locations, err := services.ItemService.GetItemLocations(i, user)
if err != nil {
return errors.E(method, errors.Internal, "error getting locations", err)
}
locationsJson, err := json.Marshal(locations)
if err != nil {
return errors.E(method, errors.Internal, "error marshalling locations", err)
}
(*w).Header().Set("Content-Type", "application/json")
(*w).WriteHeader(http.StatusOK)
(*w).Write(locationsJson)
return nil
}