From 606b639211e460906c4e2ec295a7815a6af91c0a Mon Sep 17 00:00:00 2001 From: meskio <meskio@sindominio.net> Date: Tue, 6 Oct 2020 07:46:51 +0200 Subject: [PATCH] Use 'normal' products for orders --- api/api.go | 4 +-- api/member_test.go | 2 +- api/order.go | 89 +++++++++++++++++++++++++--------------------- api/order_test.go | 23 ++++++------ 4 files changed, 62 insertions(+), 56 deletions(-) diff --git a/api/api.go b/api/api.go index 6d87d7e..e072e36 100644 --- a/api/api.go +++ b/api/api.go @@ -20,7 +20,7 @@ func initDB(dbPath string) (*gorm.DB, error) { } db.AutoMigrate(&Member{}, &Product{}, &Purchase{}, &Topup{}, &Transaction{}, - &OrderPurchase{}, &OrderProduct{}, &Order{}) + &OrderPurchase{}, &Order{}) return db, err } @@ -62,7 +62,7 @@ func Init(dbPath string, signKey string, r *mux.Router) error { r.HandleFunc("/order", a.auth(a.ListOrders)).Methods("GET") r.HandleFunc("/order", a.authNum(a.AddOrder)).Methods("POST") - r.HandleFunc("/order/{id:[0-9]+}", a.auth(a.GetOrder)).Methods("GET") + r.HandleFunc("/order/{id:[0-9]+}", a.authNum(a.GetOrder)).Methods("GET") r.HandleFunc("/order/active", a.auth(a.ListActiveOrders)).Methods("GET") r.HandleFunc("/order/purchase", a.authNum(a.AddOrderPurchase)).Methods("POST") // TODO: r.HandleFunc("/order/purchase", a.authNum(a.UpdateOrderPurchase)).Methods("PUT") diff --git a/api/member_test.go b/api/member_test.go index b58cfe1..2712ab4 100644 --- a/api/member_test.go +++ b/api/member_test.go @@ -28,7 +28,7 @@ var testMemberAdmin = struct { Name: "bar", Email: "bar@example.com", Role: "admin", - Balance: 5000, + Balance: 15000, }, Password: "password", } diff --git a/api/order.go b/api/order.go index a9c25b6..59b82e6 100644 --- a/api/order.go +++ b/api/order.go @@ -20,25 +20,20 @@ type Order struct { Deadline time.Time `json:"deadline"` Active bool `json:"active" gorm:"index"` - Products []OrderProduct `json:"products"` - TransactionID *uint `json:"transaction" gorm:"column:transaction"` -} - -type OrderProduct struct { - gorm.Model - Name string `json:"name"` - Price int `json:"price"` - OrderID uint `json:"-"` - - Purchases []OrderPurchase `json:"purchases"` + Products []Product `json:"products" gorm:"many2many:order_products;References:Code;JoinReferences:ProductCode"` + Purchases []OrderPurchase `json:"purchases"` + TransactionID *uint `json:"-" gorm:"column:transaction"` } type OrderPurchase struct { - gorm.Model - OrderProductID uint `json:"product_id"` - OrderProduct Order `json:"product"` - TransactionID uint `json:"-"` - Ammount int `json:"ammount"` + gorm.Model `json:"-"` + TransactionID uint `json:"-"` + ProductCode int `json:"product_code"` + Product *Product `json:"product" gorm:"foreignKey:ProductCode;references:Code"` + OrderID uint `json:"order_id"` + Order *Order `json:"-"` + Price int `json:"price"` + Ammount int `json:"ammount"` } func (a *api) refundOrders() { @@ -54,7 +49,7 @@ func (a *api) deactivateOrders() { now := time.Now() t := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local) err := a.db.Where("active = ? AND deadline < ?", true, t). - Preload("Products.Purchases"). + Preload("Purchases"). Find(&orders).Error if err != nil { log.Println("Error refunding orders:", err) @@ -62,13 +57,9 @@ func (a *api) deactivateOrders() { } for _, order := range orders { - log.Println("Refund order", order.Name) - total := 0 - for _, product := range order.Products { - for _, purchase := range product.Purchases { - total += product.Price * purchase.Ammount - } + for _, purchase := range order.Purchases { + total += purchase.Price * purchase.Ammount } transaction := Transaction{ @@ -93,6 +84,8 @@ func (a *api) deactivateOrders() { log.Printf("Can't create refund: %v\n%v", err, order) continue } + + log.Println("Refund order", order.Name, total) } } @@ -106,8 +99,7 @@ func (a *api) ListActiveOrders(w http.ResponseWriter, req *http.Request) { func (a *api) listOrders(active bool, w http.ResponseWriter, req *http.Request) { var orders []Order - query := a.db.Preload("Products.Purchases"). - Preload(clause.Associations) + query := a.db.Preload(clause.Associations) if active { query = query.Where("active = ?", true) } @@ -127,11 +119,10 @@ func (a *api) listOrders(active bool, w http.ResponseWriter, req *http.Request) } } -func (a *api) GetOrder(w http.ResponseWriter, req *http.Request) { +func (a *api) GetOrder(num int, w http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) var order Order - err := a.db.Preload("Products.Purchases"). - Preload(clause.Associations). + err := a.db.Preload(clause.Associations). First(&order, vars["id"]).Error if err != nil { if err.Error() == "record not found" { @@ -142,10 +133,29 @@ func (a *api) GetOrder(w http.ResponseWriter, req *http.Request) { w.WriteHeader(http.StatusInternalServerError) return } + var body struct { + Order Order `json:"order"` + Transaction *Transaction `json:"transaction"` + } + body.Order = order + + var transaction Transaction + err = a.db.Joins("OrderPurchase"). + Where("member = ? AND type = 'order' AND order_purchases.order_id = ?", num, order.ID). + Find(&transaction).Error + if err != nil { + if err.Error() != "record not found" { + log.Printf("Can't get order transaction %s: %v", vars["id"], err) + w.WriteHeader(http.StatusInternalServerError) + return + } + } else { + body.Transaction = &transaction + } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - err = json.NewEncoder(w).Encode(order) + err = json.NewEncoder(w).Encode(body) if err != nil { log.Printf("Can't encode order: %v", err) w.WriteHeader(http.StatusInternalServerError) @@ -196,15 +206,11 @@ func (a *api) AddOrderPurchase(num int, w http.ResponseWriter, req *http.Request } var order Order - err = a.db.Where("id = (?)", - a.db.Table("order_products"). - Where("id = ?", purchase[0].OrderProductID). - Select("order_id")). - Preload("Products"). - First(&order).Error + err = a.db.Preload("Products"). + First(&order, purchase[0].OrderID).Error if err != nil { - log.Printf("Can't get order from product %d: %v", purchase[0].OrderProductID, err) - w.WriteHeader(http.StatusNotAcceptable) + log.Printf("Can't get order %d: %v", purchase[0].OrderID, err) + w.WriteHeader(http.StatusInternalServerError) return } if !order.Active { @@ -214,19 +220,20 @@ func (a *api) AddOrderPurchase(num int, w http.ResponseWriter, req *http.Request } total := 0 - for _, p := range purchase { + for i, p := range purchase { found := false for _, product := range order.Products { - if product.ID == p.OrderProductID { + if product.Code == p.ProductCode { total += product.Price * p.Ammount + purchase[i].Price = product.Price found = true break } } if !found { - log.Printf("Order purchase product %d not in order: %v", p.OrderProductID, purchase) - w.WriteHeader(http.StatusNotAcceptable) + log.Printf("Order purchase product %d not in order: %v", p.ProductCode, purchase) + w.WriteHeader(http.StatusBadRequest) return } } diff --git a/api/order_test.go b/api/order_test.go index 29887a5..da66d14 100644 --- a/api/order_test.go +++ b/api/order_test.go @@ -11,11 +11,8 @@ var testOrder = Order{ Name: "huevos", Description: "huevos frescos", Deadline: time.Now().Add(24 * time.Hour), - Products: []OrderProduct{ - { - Name: "huevos", - Price: 234, - }, + Products: []Product{ + testProduct, }, } @@ -40,7 +37,7 @@ func TestOrderAddList(t *testing.T) { if len(orders[0].Products) != 1 { t.Fatal("Wrong number of products", len(orders[0].Products), orders[0].Products) } - if orders[0].Products[0].Price != testOrder.Products[0].Price { + if orders[0].Products[0].Price != testProduct.Price { t.Error("Wrong product price:", orders[0].Products[0].Price) } } @@ -79,8 +76,9 @@ func TestOrderPurchase(t *testing.T) { purchase := []OrderPurchase{ { - OrderProductID: orders[0].Products[0].ID, - Ammount: 3, + ProductCode: testProduct.Code, + Ammount: 3, + OrderID: orders[0].ID, }, } resp = tapi.do("POST", "/order/purchase", purchase, nil) @@ -96,7 +94,7 @@ func TestOrderPurchase(t *testing.T) { if len(transactions) != 1 { t.Fatal("Wrong number of transactions", len(orders), orders) } - total := 3 * testOrder.Products[0].Price + total := 3 * testProduct.Price if transactions[0].Total != -total { t.Fatal("Wrong total", transactions[0].Total) } @@ -173,8 +171,9 @@ func TestOrderDeactivation(t *testing.T) { purchase := []OrderPurchase{ { - OrderProductID: orders[0].Products[0].ID, - Ammount: 3, + ProductCode: testProduct.Code, + Ammount: 3, + OrderID: orders[0].ID, }, } resp = tapi.doAdmin("POST", "/order/purchase", purchase, nil) @@ -198,7 +197,7 @@ func TestOrderDeactivation(t *testing.T) { t.Fatal("I found some orders") } - total := 3 * testOrder.Products[0].Price + total := 3 * testProduct.Price var transactions []Transaction resp = tapi.do("GET", "/transaction/mine", nil, &transactions) -- GitLab