From 8f5bb64dc3ffc66dfed4f5aa07d3696ffd7761a9 Mon Sep 17 00:00:00 2001
From: Sercan Yesildal <sercan.yesildal@gmail.com>
Date: Sun, 7 May 2023 11:24:33 +0200
Subject: [PATCH] handler and services added

---
 src/myaktion/handler/campaign.go | 58 +++++++++++++++++++++++++++++---
 src/myaktion/handler/donation.go | 41 ++++++++++++++++++++++
 src/myaktion/main.go             | 15 +++++++--
 src/myaktion/service/campaign.go | 51 ++++++++++++++++++++++++----
 src/myaktion/service/donation.go | 22 ++++++++++++
 5 files changed, 174 insertions(+), 13 deletions(-)
 create mode 100644 src/myaktion/handler/donation.go
 create mode 100644 src/myaktion/service/donation.go

diff --git a/src/myaktion/handler/campaign.go b/src/myaktion/handler/campaign.go
index 6117d87..bc0ceeb 100644
--- a/src/myaktion/handler/campaign.go
+++ b/src/myaktion/handler/campaign.go
@@ -19,6 +19,36 @@ func getCampaign(r *http.Request) (*model.Campaign, error) {
 	return &campaign, nil
 }
 
+func CreateCampaign(w http.ResponseWriter, r *http.Request) {
+	var campaign *model.Campaign
+	campaign, err := getCampaign(r)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusBadRequest)
+		return
+	}
+	if err := service.CreateCampaign(campaign); err != nil {
+		log.Errorf("Error calling service CreateCampaign: %v", err)
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	sendJson(w, campaign)
+}
+
+func GetCampaign(w http.ResponseWriter, r *http.Request) {
+	id, err := getId(r)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusBadRequest)
+		return
+	}
+	campaign, err := service.GetCampaign(id)
+	if err != nil {
+		log.Errorf("Error retrieving campaign with ID %d: %v", id, err)
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	sendJson(w, campaign)
+}
+
 func GetCampaigns(w http.ResponseWriter, _ *http.Request) {
 	campaigns, err := service.GetCampaigns()
 	if err != nil {
@@ -29,17 +59,37 @@ func GetCampaigns(w http.ResponseWriter, _ *http.Request) {
 	sendJson(w, campaigns)
 }
 
-func CreateCampaign(w http.ResponseWriter, r *http.Request) {
-	var campaign *model.Campaign
+func UpdateCampaign(w http.ResponseWriter, r *http.Request) {
+	id, err := getId(r)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusBadRequest)
+		return
+	}
 	campaign, err := getCampaign(r)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusBadRequest)
 		return
 	}
-	if err := service.CreateCampaign(campaign); err != nil {
-		log.Errorf("Error calling service CreateCampaign: %v", err)
+	campaign, err = service.UpdateCampaign(id, campaign)
+	if err != nil {
+		log.Errorf("Error updating campaign with ID dd: %v", id, err)
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
 	sendJson(w, campaign)
 }
+
+func DeleteCampaign(w http.ResponseWriter, r *http.Request) {
+	id, err := getId(r)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusBadRequest)
+		return
+	}
+	err = service.DeleteCampaign(id)
+	if err != nil {
+		log.Errorf("Failure deleting campaign with ID %d: %v", id, err)
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	sendJson(w, result{Success: "True"})
+}
diff --git a/src/myaktion/handler/donation.go b/src/myaktion/handler/donation.go
new file mode 100644
index 0000000..b10e307
--- /dev/null
+++ b/src/myaktion/handler/donation.go
@@ -0,0 +1,41 @@
+package handler
+
+import (
+	"encoding/json"
+	"net/http"
+
+	log "github.com/sirupsen/logrus"
+	"gitlab.reutlingen-university.de/yesildas/myaktion-go/src/myaktion/model"
+	"gitlab.reutlingen-university.de/yesildas/myaktion-go/src/myaktion/service"
+)
+
+func getDonation(r *http.Request) (*model.Donation, error) {
+	var donation model.Donation
+	err := json.NewDecoder(r.Body).Decode(&donation)
+	if err != nil {
+		log.Errorf("Can't serialize request body to donation struct: %v", err)
+		return nil, err
+	}
+
+	return &donation, nil
+}
+
+func AddDonation(w http.ResponseWriter, r *http.Request) {
+	id, err := getId(r)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusBadRequest)
+		return
+	}
+	donation, err := getDonation(r)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusBadRequest)
+		return
+	}
+	err = service.AddDonation(id, donation)
+	if err != nil {
+		log.Errorf("Error adding donation to campaign with ID %d: %v", id, err)
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	sendJson(w, donation)
+}
diff --git a/src/myaktion/main.go b/src/myaktion/main.go
index 28e090a..da694a2 100644
--- a/src/myaktion/main.go
+++ b/src/myaktion/main.go
@@ -9,6 +9,7 @@ import (
 	log "github.com/sirupsen/logrus"
 	"gitlab.reutlingen-university.de/yesildas/myaktion-go/src/myaktion/handler"
 	"gitlab.reutlingen-university.de/yesildas/myaktion-go/src/myaktion/model"
+	"gitlab.reutlingen-university.de/yesildas/myaktion-go/src/myaktion/service"
 )
 
 func init() {
@@ -24,7 +25,7 @@ func init() {
 	log.SetLevel(level)
 }
 
-func main() {
+func loadSampleData() {
 	campaign := model.Campaign{
 		Name:               "Spenden für eine bessere Note",
 		OrganizerName:      "Geheimnisvolle Ente",
@@ -50,12 +51,22 @@ func main() {
 		Status: model.IN_PROCESS,
 	})
 
+	service.CreateCampaign(&campaign)
+}
+
+func main() {
+	loadSampleData()
 	port := 8000
 	log.Infof("Starting MyAktion API server on port %v.\n", port)
 	router := mux.NewRouter()
 	router.HandleFunc("/health", handler.Health).Methods("GET")
 	router.HandleFunc("/campaigns", handler.GetCampaigns).Methods("GET")
-	router.HandleFunc("/campaign", handler.CreateCampaign).Methods("POST")
+	router.HandleFunc("/campaigns", handler.CreateCampaign).Methods("POST")
+	router.HandleFunc("/campaigns/{id}", handler.GetCampaign).Methods("GET")
+	router.HandleFunc("/campaigns/{id}", handler.UpdateCampaign).Methods("PUT")
+	router.HandleFunc("/campaigns/{id}", handler.DeleteCampaign).Methods("DELETE")
+	router.HandleFunc("/campaigns/{id}/donation", handler.AddDonation).Methods("POST")
+
 	if err := http.ListenAndServe(fmt.Sprintf(":%v", port), router); err != nil {
 		log.Fatal(err)
 	}
diff --git a/src/myaktion/service/campaign.go b/src/myaktion/service/campaign.go
index d4274a3..510712b 100644
--- a/src/myaktion/service/campaign.go
+++ b/src/myaktion/service/campaign.go
@@ -1,6 +1,8 @@
 package service
 
 import (
+	"fmt"
+
 	log "github.com/sirupsen/logrus"
 
 	"gitlab.reutlingen-university.de/yesildas/myaktion-go/src/myaktion/model"
@@ -15,6 +17,27 @@ func init() {
 	campaignStore = make(map[uint]*model.Campaign)
 }
 
+func CreateCampaign(campaign *model.Campaign) error {
+	campaign.ID = actCampaignId
+	campaignStore[actCampaignId] = campaign
+	actCampaignId += 1
+	log.Infof("Successfully stored new campaign with ID %v in database.", campaign.ID)
+	log.Tracef("Stored: %v", campaign)
+
+	return nil
+}
+
+func GetCampaign(id uint) (*model.Campaign, error) {
+	if campaign, ok := campaignStore[id]; !ok {
+		log.Info("Campaign with ID %d not found.", id)
+		return nil, fmt.Errorf("campaign with id %d not found", id)
+	} else {
+		log.Infof("Successfully retrieved campaign with ID %v.", campaign.ID)
+		log.Tracef("Retrieved: ", *campaign)
+		return campaign, nil
+	}
+}
+
 func GetCampaigns() ([]model.Campaign, error) {
 	var campaigns []model.Campaign
 	for _, campaign := range campaignStore {
@@ -26,12 +49,26 @@ func GetCampaigns() ([]model.Campaign, error) {
 	return campaigns, nil
 }
 
-func CreateCampaign(campaign *model.Campaign) error {
-	campaign.ID = actCampaignId
-	campaignStore[actCampaignId] = campaign
-	actCampaignId += 1
-	log.Infof("Successfully stored new campaign with ID %v in database.", campaign.ID)
-	log.Tracef("Stored: %v", campaign)
+func UpdateCampaign(id uint, campaign *model.Campaign) (*model.Campaign, error) {
+	if storeCampaign, ok := campaignStore[id]; !ok {
+		log.Info("Campaign with ID %d not found.", id)
+		return nil, fmt.Errorf("campaign with id %d not found", id)
+	} else {
+		*storeCampaign = *campaign
+		storeCampaign.ID = id
+		log.Infof("Successfully updated campaign with ID %d.", id)
+		log.Tracef("Updated: %v", storeCampaign)
+		return storeCampaign, nil
+	}
+}
 
-	return nil
+func DeleteCampaign(id uint) error {
+	if campaign, ok := campaignStore[id]; !ok {
+		log.Info("Campaign with ID %d not found.", id)
+		return fmt.Errorf("campaign with id %d not found", id)
+	} else {
+		delete(campaignStore, id)
+		log.Infof("Successfully deleted campaign with ID %v.", campaign.ID)
+		return nil
+	}
 }
diff --git a/src/myaktion/service/donation.go b/src/myaktion/service/donation.go
new file mode 100644
index 0000000..5a7bb09
--- /dev/null
+++ b/src/myaktion/service/donation.go
@@ -0,0 +1,22 @@
+package service
+
+import (
+	"fmt"
+
+	log "github.com/sirupsen/logrus"
+	"gitlab.reutlingen-university.de/yesildas/myaktion-go/src/myaktion/model"
+)
+
+func AddDonation(campaignId uint, donation *model.Donation) error {
+	campaign, err := GetCampaign(campaignId)
+	if err != nil {
+		log.Info("Campaign with ID %d not found.", campaignId)
+		return fmt.Errorf("campaign with id %d not found", campaignId)
+	}
+	if campaign.Donations == nil {
+		campaign.Donations = []model.Donation{}
+	}
+	campaign.Donations = append(campaign.Donations, *donation)
+
+	return nil
+}
-- 
GitLab