From b099f4f392e4b151f716175acc7cea2f3020f4d5 Mon Sep 17 00:00:00 2001
From: meskio <meskio@sindominio.net>
Date: Wed, 4 Nov 2020 19:51:32 +0100
Subject: [PATCH] Add proxy transactions

---
 api/api.go             |  2 +-
 api/db/transaction.go  | 12 +++++++-----
 api/purchase.go        | 19 +++++++++++--------
 api/purchase_test.go   |  3 +++
 api/topup_test.go      |  4 ++--
 src/ShowTransaction.js | 10 +++++++++-
 6 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/api/api.go b/api/api.go
index d6ef807..44bd57f 100644
--- a/api/api.go
+++ b/api/api.go
@@ -40,7 +40,7 @@ func Init(dbPath string, signKey string, mail *Mail, r *mux.Router) error {
 	r.HandleFunc("/member/{num:[0-9]+}", a.authAdmin(a.UpdateMember)).Methods("PUT")
 	r.HandleFunc("/member/{num:[0-9]+}", a.authAdmin(a.DeleteMember)).Methods("DELETE")
 	r.HandleFunc("/member/{num:[0-9]+}/transactions", a.authAdmin(a.GetMemberTransactions)).Methods("GET")
-	r.HandleFunc("/member/{num:[0-9]+}/purchase", a.authAdmin(a.AddMemberPurchase)).Methods("POST")
+	r.HandleFunc("/member/{num:[0-9]+}/purchase", a.authAdminNum(a.AddMemberPurchase)).Methods("POST")
 
 	r.HandleFunc("/product", a.auth(a.ListProducts)).Methods("GET")
 	r.HandleFunc("/product", a.authAdmin(a.AddProduct)).Methods("POST")
diff --git a/api/db/transaction.go b/api/db/transaction.go
index 151c3df..8b1b83c 100644
--- a/api/db/transaction.go
+++ b/api/db/transaction.go
@@ -17,6 +17,8 @@ type Transaction struct {
 	Date      time.Time `json:"date"`
 	Total     int       `json:"total"`
 	Type      string    `json:"type"`
+	ProxyNum  int       `json:"-" gorm:"column:proxy"`
+	Proxy     *Member   `json:"proxy,omitempty" gorm:"foreignKey:ProxyNum;references:Num"`
 
 	Purchase      []Purchase      `json:"purchase,omitempty"`
 	Topup         *Topup          `json:"topup,omitempty"`
@@ -29,8 +31,6 @@ type Transaction struct {
 type Topup struct {
 	gorm.Model    `json:"-"`
 	TransactionID uint   `json:"-" gorm:"column:transaction"`
-	MemberNum     int    `json:"member" gorm:"column:member"`
-	Member        Member `json:"-" gorm:"foreignKey:MemberNum;references:Num"`
 	Comment       string `json:"comment"`
 }
 
@@ -70,19 +70,20 @@ func (d *DB) GetTransaction(id int) (transaction Transaction, err error) {
 func (d *DB) AddTopup(adminNum int, memberNum int, amount int, comment string) (transaction Transaction, err error) {
 	transaction = Transaction{
 		MemberNum: memberNum,
+		ProxyNum:  adminNum,
 		Date:      time.Now(),
 		Topup: &Topup{
-			MemberNum: adminNum,
-			Comment:   comment,
+			Comment: comment,
 		},
 		Type:  "topup",
 		Total: amount,
 	}
+	log.Println(transaction.ProxyNum)
 	err = createTransaction(d.db, &transaction)
 	return
 }
 
-func (d *DB) AddPurchase(memberNum int, purchase []Purchase) (transaction Transaction, err error) {
+func (d *DB) AddPurchase(adminNum int, memberNum int, purchase []Purchase) (transaction Transaction, err error) {
 	total := 0
 	for i, p := range purchase {
 		var product Product
@@ -104,6 +105,7 @@ func (d *DB) AddPurchase(memberNum int, purchase []Purchase) (transaction Transa
 
 	transaction = Transaction{
 		MemberNum: memberNum,
+		ProxyNum:  adminNum,
 		Date:      time.Now(),
 		Purchase:  purchase,
 		Type:      "purchase",
diff --git a/api/purchase.go b/api/purchase.go
index 932bcab..3a267d1 100644
--- a/api/purchase.go
+++ b/api/purchase.go
@@ -12,6 +12,16 @@ import (
 )
 
 func (a *api) AddPurchase(num int, w http.ResponseWriter, req *http.Request) {
+	a.addPurchase(0, num, w, req)
+}
+
+func (a *api) AddMemberPurchase(adminNum int, w http.ResponseWriter, req *http.Request) {
+	vars := mux.Vars(req)
+	num, _ := strconv.Atoi(vars["num"])
+	a.addPurchase(adminNum, num, w, req)
+}
+
+func (a *api) addPurchase(adminNum int, memberNum int, w http.ResponseWriter, req *http.Request) {
 	var purchase []db.Purchase
 	err := json.NewDecoder(req.Body).Decode(&purchase)
 	if err != nil {
@@ -20,7 +30,7 @@ func (a *api) AddPurchase(num int, w http.ResponseWriter, req *http.Request) {
 		return
 	}
 
-	transaction, err := a.db.AddPurchase(num, purchase)
+	transaction, err := a.db.AddPurchase(adminNum, memberNum, purchase)
 	if err != nil {
 		if errors.Is(err, db.ErrorNotFound) {
 			w.WriteHeader(http.StatusNotAcceptable)
@@ -40,11 +50,4 @@ func (a *api) AddPurchase(num int, w http.ResponseWriter, req *http.Request) {
 		log.Printf("Can't encode added purchase: %v", err)
 		w.WriteHeader(http.StatusInternalServerError)
 	}
-
-}
-
-func (a *api) AddMemberPurchase(w http.ResponseWriter, req *http.Request) {
-	vars := mux.Vars(req)
-	num, _ := strconv.Atoi(vars["num"])
-	a.AddPurchase(num, w, req)
 }
diff --git a/api/purchase_test.go b/api/purchase_test.go
index 322b4ce..d2516f0 100644
--- a/api/purchase_test.go
+++ b/api/purchase_test.go
@@ -90,6 +90,9 @@ func TestMemberPurchase(t *testing.T) {
 	if len(transactions) != 1 {
 		t.Fatal("Wrong number of transactions", len(transactions), transactions)
 	}
+	if transactions[0].Proxy.Num != testMemberAdmin.Num {
+		t.Error("Wrong proxy:", transactions[0].Proxy.Num)
+	}
 	if transactions[0].Total != -testProduct.Price*products[0].Amount {
 		t.Error("Wrong total:", transactions[0].Total)
 	}
diff --git a/api/topup_test.go b/api/topup_test.go
index 3d2eb2b..cf55e36 100644
--- a/api/topup_test.go
+++ b/api/topup_test.go
@@ -34,8 +34,8 @@ func TestTopupAddListMine(t *testing.T) {
 	if transactions[0].Total != 20 {
 		t.Error("Wrong total:", transactions[0].Total)
 	}
-	if transactions[0].Topup.MemberNum != testMemberAdmin.Num {
-		t.Error("Wrong topup member:", transactions[0].Topup.MemberNum)
+	if transactions[0].Proxy.Num != testMemberAdmin.Num {
+		t.Error("Wrong proxy:", transactions[0].Proxy.Num)
 	}
 	if transactions[0].Topup.Comment != "my topup" {
 		t.Error("Wrong topup comment:", transactions[0].Topup.Comment)
diff --git a/src/ShowTransaction.js b/src/ShowTransaction.js
index 8b16b84..6da5dee 100644
--- a/src/ShowTransaction.js
+++ b/src/ShowTransaction.js
@@ -34,7 +34,15 @@ function ShowTransaction() {
             <h3>Total: {printMoney(transaction.total)}€</h3>
           </Col>
           <Col>
-            <p className="text-right">{printDate(transaction.date)}</p>
+            <p className="text-right">
+              {printDate(transaction.date)}
+              {transaction.proxy && (
+                <span>
+                  <br />
+                  por: {transaction.proxy.name}
+                </span>
+              )}
+            </p>
           </Col>
         </Row>
       </Container>
-- 
GitLab