Skip to content
Snippets Groups Projects
Commit 4f058ca1 authored by meskio's avatar meskio :tent:
Browse files

Delete orders

parent 1fe9a34f
Branches
No related tags found
No related merge requests found
...@@ -57,6 +57,7 @@ func Init(dbPath string, signKey string, mail *Mail, r *mux.Router) error { ...@@ -57,6 +57,7 @@ func Init(dbPath string, signKey string, mail *Mail, r *mux.Router) error {
r.HandleFunc("/order", a.auth(a.ListOrders)).Methods("GET") r.HandleFunc("/order", a.auth(a.ListOrders)).Methods("GET")
r.HandleFunc("/order", a.authNum(a.AddOrder)).Methods("POST") r.HandleFunc("/order", a.authNum(a.AddOrder)).Methods("POST")
r.HandleFunc("/order/{id:[0-9]+}", a.authNum(a.GetOrder)).Methods("GET") r.HandleFunc("/order/{id:[0-9]+}", a.authNum(a.GetOrder)).Methods("GET")
r.HandleFunc("/order/{id:[0-9]+}", a.authNumRole(a.DeleteOrder)).Methods("DELETE")
r.HandleFunc("/order/active", a.auth(a.ListActiveOrders)).Methods("GET") r.HandleFunc("/order/active", a.auth(a.ListActiveOrders)).Methods("GET")
r.HandleFunc("/order/{id:[0-9]+}/purchase", a.authNum(a.AddOrderPurchase)).Methods("POST") r.HandleFunc("/order/{id:[0-9]+}/purchase", a.authNum(a.AddOrderPurchase)).Methods("POST")
return nil return nil
......
...@@ -48,10 +48,13 @@ func (d *DB) GetOrder(memberNum int, id int) (order Order, transaction Transacti ...@@ -48,10 +48,13 @@ func (d *DB) GetOrder(memberNum int, id int) (order Order, transaction Transacti
Preload("Transactions.OrderPurchase"). Preload("Transactions.OrderPurchase").
Preload("Transactions.Member"). Preload("Transactions.Member").
First(&order, id).Error First(&order, id).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
err = ErrorNotFound err = ErrorNotFound
return return
} }
return
}
err = d.db.Where("member = ? AND type = 'order' AND order_id = ?", memberNum, id). err = d.db.Where("member = ? AND type = 'order' AND order_id = ?", memberNum, id).
Preload("OrderPurchase.Product"). Preload("OrderPurchase.Product").
Find(&transaction).Error Find(&transaction).Error
...@@ -62,6 +65,48 @@ func (d *DB) AddOrder(order *Order) error { ...@@ -62,6 +65,48 @@ func (d *DB) AddOrder(order *Order) error {
return d.db.Create(&order).Error return d.db.Create(&order).Error
} }
func (d *DB) DeleteOrder(memberNum int, id int) error {
var order Order
err := d.db.Preload(clause.Associations).
Preload("Transactions.OrderPurchase").
Preload("Transactions.Member").
First(&order, id).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return ErrorNotFound
}
return err
}
if memberNum != 0 && order.MemberNum != memberNum {
return ErrorInvalidRequest
}
return d.db.Transaction(func(tx *gorm.DB) error {
if order.TransactionID != nil {
var transaction Transaction
err = tx.First(&transaction, order.TransactionID).Error
if err != nil {
return err
}
order.Transactions = append(order.Transactions, transaction)
}
for _, transaction := range order.Transactions {
err := updateMemberBalance(tx, transaction.MemberNum, -transaction.Total)
if err != nil {
return err
}
err = tx.Select("OrderPurchase").Delete(&transaction).Error
if err != nil {
return err
}
}
return tx.Delete(&order).Error
})
}
func (d *DB) AddOrderPurchase(memberNum int, orderID int, purchase []OrderPurchase) (transaction Transaction, err error) { func (d *DB) AddOrderPurchase(memberNum int, orderID int, purchase []OrderPurchase) (transaction Transaction, err error) {
order, transaction, err := d.GetOrder(memberNum, orderID) order, transaction, err := d.GetOrder(memberNum, orderID)
if err != nil { if err != nil {
......
...@@ -20,8 +20,8 @@ type Transaction struct { ...@@ -20,8 +20,8 @@ type Transaction struct {
Purchase []Purchase `json:"purchase,omitempty"` Purchase []Purchase `json:"purchase,omitempty"`
Topup *Topup `json:"topup,omitempty"` Topup *Topup `json:"topup,omitempty"`
OrderPurchase []OrderPurchase `json:"order_purchase,omitempty" gorm:"foreignKey:TransactionID"` OrderPurchase []OrderPurchase `json:"order_purchase,omitempty" gorm:"foreignKey:TransactionID;constraint:OnDelete:CASCADE"`
Order *Order `json:"order,omitempty"` Order *Order `json:"order,omitempty" gorm:"constraint:OnDelete:CASCADE"`
OrderID *uint `json:"-"` OrderID *uint `json:"-"`
Refund *Order `json:"refund,omitempty" gorm:"foreignKey:TransactionID"` Refund *Order `json:"refund,omitempty" gorm:"foreignKey:TransactionID"`
} }
......
...@@ -86,6 +86,29 @@ func (a *api) GetOrder(num int, w http.ResponseWriter, req *http.Request) { ...@@ -86,6 +86,29 @@ func (a *api) GetOrder(num int, w http.ResponseWriter, req *http.Request) {
} }
} }
func (a *api) DeleteOrder(num int, role string, w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
id, _ := strconv.Atoi(vars["id"])
if role == "admin" {
num = 0
}
err := a.db.DeleteOrder(num, id)
if err != nil {
if errors.Is(err, db.ErrorNotFound) {
w.WriteHeader(http.StatusNotFound)
return
}
if errors.Is(err, db.ErrorInvalidRequest) {
w.WriteHeader(http.StatusUnauthorized)
return
}
log.Printf("Can't get order %s: %v", vars["id"], err)
w.WriteHeader(http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
}
func (a *api) AddOrder(num int, w http.ResponseWriter, req *http.Request) { func (a *api) AddOrder(num int, w http.ResponseWriter, req *http.Request) {
var order db.Order var order db.Order
err := json.NewDecoder(req.Body).Decode(&order) err := json.NewDecoder(req.Body).Decode(&order)
......
...@@ -66,6 +66,85 @@ func TestOrderActive(t *testing.T) { ...@@ -66,6 +66,85 @@ func TestOrderActive(t *testing.T) {
} }
} }
func TestOrderDelete(t *testing.T) {
tapi := newTestAPI(t)
defer tapi.close()
tapi.addTestMember()
order := testOrder
order.Deadline = time.Now().Add(-24 * time.Hour)
resp := tapi.do("POST", "/order", order, nil)
if resp.StatusCode != http.StatusCreated {
t.Fatal("Can't create order:", resp.Status)
}
var orders []db.Order
resp = tapi.do("GET", "/order", nil, &orders)
if resp.StatusCode != http.StatusOK {
t.Fatal("Can't get orders:", resp.Status)
}
purchase := []db.OrderPurchase{
{
ProductCode: testProduct.Code,
Amount: 3,
},
}
resp = tapi.doAdmin("POST", fmt.Sprintf("/order/%d/purchase", orders[0].ID), purchase, nil)
if resp.StatusCode != http.StatusCreated {
t.Fatal("Can't create order purchase:", resp.Status)
}
dbPath := path.Join(tapi.testPath, "test.db")
database, err := db.Init(dbPath)
if err != nil {
t.Fatal("Can't initialize the db:", err)
}
orders = database.DeactivateOrders()
if len(orders) != 1 {
t.Error("Deactivated wrong orders:", orders)
}
resp = tapi.do("DELETE", fmt.Sprintf("/order/%d", orders[0].ID), nil, nil)
if resp.StatusCode != http.StatusOK {
t.Fatal("Can't delete order:", resp.Status)
}
resp = tapi.do("GET", "/order", nil, &orders)
if resp.StatusCode != http.StatusOK {
t.Fatal("Can't get orders:", resp.Status)
}
if len(orders) != 0 {
t.Error("The order didn't get removed", orders)
}
var transactions []db.Transaction
resp = tapi.doAdmin("GET", "/transaction", nil, &transactions)
if resp.StatusCode != http.StatusOK {
t.Fatal("Can't get orders:", resp.Status)
}
if len(transactions) != 0 {
t.Error("The transactions didn't get removed", transactions)
}
var member db.Member
resp = tapi.doAdmin("GET", fmt.Sprintf("/member/%d", testMember.Num), nil, &member)
if resp.StatusCode != http.StatusOK {
t.Fatal("Can't get orders:", resp.Status)
}
if member.Balance != testMember.Balance {
t.Error("Wrong balance on test member:", member.Balance)
}
resp = tapi.doAdmin("GET", fmt.Sprintf("/member/%d", testMemberAdmin.Num), nil, &member)
if resp.StatusCode != http.StatusOK {
t.Fatal("Can't get orders:", resp.Status)
}
if member.Balance != testMemberAdmin.Balance {
t.Error("Wrong balance on admin member:", member.Balance)
}
}
func TestOrderPurchase(t *testing.T) { func TestOrderPurchase(t *testing.T) {
tapi := newTestAPI(t) tapi := newTestAPI(t)
defer tapi.close() defer tapi.close()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment