package api import ( "encoding/json" "errors" "log" "net/http" "github.com/gorilla/mux" "gorm.io/gorm" ) type Product struct { gorm.Model `json:"-"` Code int `json:"code" gorm:"unique;index"` Name string `json:"name" gorm:"unique;index"` Price int `json:"price"` Stock int `json:"stock"` } func (a *api) AddProduct(w http.ResponseWriter, req *http.Request) { var product Product err := json.NewDecoder(req.Body).Decode(&product) if err != nil { log.Printf("Can't create product: %v", err) w.WriteHeader(http.StatusInternalServerError) return } err = a.db.Create(&product).Error if err != nil { log.Printf("Can't create product: %v\n%v", err, product) w.WriteHeader(http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) err = json.NewEncoder(w).Encode(product) if err != nil { log.Printf("Can't encode added product: %v", err) w.WriteHeader(http.StatusInternalServerError) return } } func (a *api) ListProducts(w http.ResponseWriter, req *http.Request) { var products []Product err := a.db.Find(&products).Error if err != nil { log.Printf("Can't list products: %v", err) w.WriteHeader(http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) err = json.NewEncoder(w).Encode(products) if err != nil { log.Printf("Can't encode products: %v", err) w.WriteHeader(http.StatusInternalServerError) return } } func (a *api) GetProduct(w http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) var product Product err := a.db.Where("code = ?", vars["code"]).First(&product).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { w.WriteHeader(http.StatusNotFound) return } log.Printf("Can't get product %s: %v", vars["code"], err) w.WriteHeader(http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) err = json.NewEncoder(w).Encode(product) if err != nil { log.Printf("Can't encode product: %v", err) w.WriteHeader(http.StatusInternalServerError) return } } func (a *api) DeleteProduct(w http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) err := a.db.Where("code = ?", vars["code"]).Delete(&Product{}).Error if err != nil { log.Printf("Can't delete product %s: %v", vars["code"], err) w.WriteHeader(http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) } func (a *api) UpdateProduct(w http.ResponseWriter, req *http.Request) { var product Product err := json.NewDecoder(req.Body).Decode(&product) if err != nil { log.Printf("Can't decode memeber: %v", err) w.WriteHeader(http.StatusInternalServerError) return } vars := mux.Vars(req) var dbProduct Product err = a.db.Where("code = ?", vars["code"]).First(&dbProduct).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { w.WriteHeader(http.StatusNotFound) return } log.Printf("Can't get product %s: %v", vars["code"], err) w.WriteHeader(http.StatusInternalServerError) return } if product.Code != 0 { dbProduct.Code = product.Code } if product.Name != "" { dbProduct.Name = product.Name } if product.Price >= 0 { dbProduct.Price = product.Price } if product.Stock >= 0 { dbProduct.Stock = product.Stock } err = a.db.Save(&dbProduct).Error if err != nil { log.Printf("Can't update product %s: %v %v", vars["code"], err, product) w.WriteHeader(http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) err = json.NewEncoder(w).Encode(dbProduct) if err != nil { log.Printf("Can't encode updated product: %v", err) w.WriteHeader(http.StatusInternalServerError) return } }