diff --git a/src/gomazon/handler/auth.go b/src/gomazon/handler/auth.go index ea186d391c8f0cbfbc4a5b02a0a7293f214afa97..3d162f927c20bd251988ff05db1daf0bb176b897 100644 --- a/src/gomazon/handler/auth.go +++ b/src/gomazon/handler/auth.go @@ -9,35 +9,36 @@ import ( "gitlab.reutlingen-university.de/albrecht/gomazon/service" ) -// Handler-Funktion zum Generieren eines Admin-JWT-Tokens +// Handler-Function to generate Admin-JWT-Tokens func GenerateAdminTokenHandler(c *gin.Context) { - // Benutzername und isAdmin aus dem Request-Body erhalten + // Username and isAdmin of the Request-Body var requestBody struct { Username string `json:"username"` IsAdmin bool `json:"isAdmin"` } + //Bind Body with requestBody struct if err := c.ShouldBindJSON(&requestBody); err != nil { log.Errorf("Invalid request body for authentication") c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"}) return } - // Überprüfen, ob der Benutzername vorhanden ist + // Check username if requestBody.Username == "" { log.Errorf("Invalid username for authentication") c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid username"}) return } - // Überprüfen, ob isAdmin gesetzt ist + // Check isAdmin if _, ok := interface{}(requestBody.IsAdmin).(bool); !ok { log.Errorf("Invalid isAdmin flag for authentication") c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid isAdmin value"}) return } - // JWT-Token für den Benutzer generieren + // Generate JWT-Token expiration := time.Now().Add(30 * time.Minute) token, err := service.GenerateAdminJWTToken(requestBody.Username, requestBody.IsAdmin, expiration) if err != nil { diff --git a/src/gomazon/handler/bank.go b/src/gomazon/handler/bank.go index 6dde9c63b59ee5439f2e6eee8a363ebd2ab6dd2f..169b1dd92663b577f30ef1e5d4b8801010fdbb3f 100644 --- a/src/gomazon/handler/bank.go +++ b/src/gomazon/handler/bank.go @@ -13,8 +13,9 @@ type BankAccountHandler struct { BankAccountService *service.BankAccountService } -// Bankkonto erstellen +// Generate Bankaccount func (h *BankAccountHandler) CreateBankAccount(c *gin.Context) { + //Get informations of Auth-String tokenString := c.GetHeader("Authorization") username, _, err := service.ExtractTokenData(tokenString) if err != nil { @@ -22,6 +23,7 @@ func (h *BankAccountHandler) CreateBankAccount(c *gin.Context) { return } + //Generate Account object var bankAccount model.BankAccount if err := c.ShouldBindJSON(&bankAccount); err != nil { log.Errorf("ShouldBindJSON in CreateBankAccount failed") @@ -30,6 +32,7 @@ func (h *BankAccountHandler) CreateBankAccount(c *gin.Context) { } bankAccount.Username = username + //Create Account with object createdAccount, err := h.BankAccountService.CreateBankAccount(bankAccount) if err != nil { log.Errorf("Creation of the bank account failed") @@ -40,23 +43,28 @@ func (h *BankAccountHandler) CreateBankAccount(c *gin.Context) { c.JSON(http.StatusCreated, createdAccount) } +// Banktransfer func (h *BankAccountHandler) UpdateBankAccount(c *gin.Context) { + //Get information of Auth-String tokenString := c.GetHeader("Authorization") username, _, err := service.ExtractTokenData(tokenString) if err != nil { log.Errorf("Extraction of JWT-Token failed") } + //Body var withdrawalData struct { Amount float64 `json:"amount" binding:"required"` } + //Generate Object if err := c.ShouldBindJSON(&withdrawalData); err != nil { log.Errorf("ShouldBindJSON in UpdateBankAccount failed") c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } + //Update Bankbalance updatedAccount, err := h.BankAccountService.UpdateBankAccount(username, withdrawalData.Amount) if err != nil { log.Errorf("Account update from User '%v' failed", updatedAccount.Username) diff --git a/src/gomazon/handler/bewertung.go b/src/gomazon/handler/bewertung.go index 4d6095ed135ca6bc22f5e39ba3aeb84a8ec6ed1c..5e035313517cb55be424f08e34f5ca4895d370eb 100644 --- a/src/gomazon/handler/bewertung.go +++ b/src/gomazon/handler/bewertung.go @@ -15,13 +15,15 @@ type RatingHandler struct { ProductService *service.ProductService } +// Create Rating func (h *RatingHandler) CreateRating(c *gin.Context) { + //Get username from Auth-String tokenString := c.GetHeader("Authorization") username, _, err := service.ExtractTokenData(tokenString) if err != nil { log.Errorf("Extraction of JWT-Token failed") } - // Product-ID aus dem URL-Parameter extrahieren + // Extract ProductID from URL ProductID, err := strconv.Atoi(c.Param("id")) if err != nil { log.Errorf("Invalid ID for a product") @@ -29,7 +31,7 @@ func (h *RatingHandler) CreateRating(c *gin.Context) { return } - // Ratingsdaten aus dem Request-Body lesen + // Get Information from Body var Rating *model.Rating if err := c.ShouldBindJSON(&Rating); err != nil { log.Errorf("ShouldBindJSON in CreateRating failed") @@ -37,9 +39,16 @@ func (h *RatingHandler) CreateRating(c *gin.Context) { return } + // Check if Rating is in [0;5] + if Rating.Rating < 0 || Rating.Rating > 5 { + log.Errorf("Rating %v is not in [0;5]", Rating.Rating) + c.JSON(http.StatusBadRequest, gin.H{"error": "Rating is not in [0;5]"}) + return + } + Rating.Username = username - // Rating erstellen + // Create Rating err = h.RatingService.CreateRating(uint(ProductID), Rating) if err != nil { log.Errorf("Creation of Rating failed") @@ -50,9 +59,10 @@ func (h *RatingHandler) CreateRating(c *gin.Context) { c.JSON(http.StatusOK, Rating) } +// Delete Rating func (h *RatingHandler) DeleteRating(c *gin.Context) { - // Product-ID und Ratings-ID aus den URL-Parametern extrahieren + // Extract Rating-ID from URL RatingID, err := strconv.Atoi(c.Param("id")) if err != nil { log.Errorf("Invalid Rating ID") @@ -60,6 +70,7 @@ func (h *RatingHandler) DeleteRating(c *gin.Context) { return } + // Get Rating by ID Rating, err := h.ProductService.GetRatingByID(uint(RatingID)) if err != nil { log.Errorf("Invalid Rating ID") @@ -67,14 +78,16 @@ func (h *RatingHandler) DeleteRating(c *gin.Context) { return } + // Get information from Auth-String tokenString := c.GetHeader("Authorization") username, admin, err := service.ExtractTokenData(tokenString) if err != nil { log.Errorf("Extraction of JWT-Token failed") } + // Check if User is Admin or owner of the Rating if admin || (Rating.Username == username) { - // Rating löschen + // Delete Rating err = h.RatingService.DeleteRating(uint(RatingID)) if err != nil { log.Error("Could not delete Rating") @@ -91,6 +104,7 @@ func (h *RatingHandler) DeleteRating(c *gin.Context) { } } +// Get all Ratings func (h *RatingHandler) ReadRatings(c *gin.Context) { Products, err := h.RatingService.ProductService.ReadRatings() if err != nil { diff --git a/src/gomazon/handler/produkt.go b/src/gomazon/handler/produkt.go index 8a75d1ac2f8befb7a674101fb21f8ebfea926c24..3ed05009f2275d2999eba0b56d53b31a102e8764 100644 --- a/src/gomazon/handler/produkt.go +++ b/src/gomazon/handler/produkt.go @@ -12,12 +12,15 @@ import ( type ProductHandler struct { ProductService *service.ProductService + RatingService *service.RatingService } +// Create Product func (h *ProductHandler) CreateProduct(c *gin.Context) { + //Get information from Auth-String tokenString := c.GetHeader("Authorization") username, admin, err := service.ExtractTokenData(tokenString) - if !admin { + if !admin { // Check if user is admin c.JSON(http.StatusBadRequest, gin.H{"error": "not authorized"}) log.Errorf("%v is not an admin", username) return @@ -29,7 +32,7 @@ func (h *ProductHandler) CreateProduct(c *gin.Context) { var Product model.Product - // Die Productinformationen aus dem Request-Body binden + // Bind information from Body if err := c.ShouldBindJSON(&Product); err != nil { log.Errorf("ShouldBindJSON in CreateProduct failed") c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) @@ -37,7 +40,7 @@ func (h *ProductHandler) CreateProduct(c *gin.Context) { } Product.Totalrating = 0.0 - // Das Product über den ProductService erstellen + // Create Product createdProduct, err := h.ProductService.CreateProduct(Product) if err != nil { log.Errorf("Creation of product failed") @@ -48,6 +51,7 @@ func (h *ProductHandler) CreateProduct(c *gin.Context) { c.JSON(http.StatusOK, createdProduct) } +// Get all Products func (h *ProductHandler) ReadProducts(c *gin.Context) { Products, err := h.ProductService.ReadProducts() if err != nil { @@ -59,10 +63,12 @@ func (h *ProductHandler) ReadProducts(c *gin.Context) { c.JSON(http.StatusOK, Products) } +// Update single Product func (h *ProductHandler) UpdateProduct(c *gin.Context) { + // Get information from Auth-String tokenString := c.GetHeader("Authorization") username, admin, err := service.ExtractTokenData(tokenString) - if !admin { + if !admin { //Check if user is an admin c.JSON(http.StatusBadRequest, gin.H{"error": "not authorized"}) log.Errorf("%v is not an admin", username) return @@ -72,6 +78,7 @@ func (h *ProductHandler) UpdateProduct(c *gin.Context) { return } + // Get ProductId from URL id, err := strconv.Atoi(c.Param("id")) if err != nil { log.Error("Invalid ID") @@ -79,6 +86,7 @@ func (h *ProductHandler) UpdateProduct(c *gin.Context) { return } + //Bind Bondy-informations to an object var Product model.Product if err := c.ShouldBindJSON(&Product); err != nil { log.Error("ShouldBindJSON in UpdateProduct failed") @@ -96,10 +104,12 @@ func (h *ProductHandler) UpdateProduct(c *gin.Context) { c.JSON(http.StatusOK, updatedProduct) } +// Delete Product func (h *ProductHandler) DeleteProduct(c *gin.Context) { + // Get informations from Auth-String tokenString := c.GetHeader("Authorization") username, admin, err := service.ExtractTokenData(tokenString) - if !admin { + if !admin { // Check if user is an admin c.JSON(http.StatusBadRequest, gin.H{"error": "not authorized"}) log.Errorf("%v is not an admin", username) return @@ -109,6 +119,7 @@ func (h *ProductHandler) DeleteProduct(c *gin.Context) { return } + // Get Productid from URL id, err := strconv.Atoi(c.Param("id")) if err != nil { log.Error("Invalid ID") @@ -122,11 +133,19 @@ func (h *ProductHandler) DeleteProduct(c *gin.Context) { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } + + err = h.RatingService.DeleteRatingsForProduct(uint(id)) + if err != nil { + log.Error(err.Error()) + } + log.Info("Product successfully removed") c.JSON(http.StatusOK, gin.H{"message": "Product successfully removed"}) } +// Get single Product func (h *ProductHandler) GetProductByID(c *gin.Context) { + //get ProductId from URL id, err := strconv.Atoi(c.Param("id")) if err != nil { log.Error("Invalid ID") diff --git a/src/gomazon/handler/warenkorb.go b/src/gomazon/handler/warenkorb.go index 066a826bd494450892f9a56c946d3002b3982278..1cc82f85b72bbd3e86f3da4ca1614d1609133251 100644 --- a/src/gomazon/handler/warenkorb.go +++ b/src/gomazon/handler/warenkorb.go @@ -15,8 +15,9 @@ type ShoppingCartHandler struct { BankAccountService *service.BankAccountService } -// ShoppingCart erstellen +// Create ShoppingCart func (h *ShoppingCartHandler) CreateShoppingCart(c *gin.Context) { + //Get information from Auth-String tokenString := c.GetHeader("Authorization") username, _, err := service.ExtractTokenData(tokenString) if err != nil { @@ -41,8 +42,9 @@ func (h *ShoppingCartHandler) CreateShoppingCart(c *gin.Context) { c.JSON(http.StatusCreated, createdShoppingCart) } -// Einzelnes Product zum ShoppingCart hinzufügen +// Add Product func (h *ShoppingCartHandler) AddProductToShoppingCart(c *gin.Context) { + // Get information from Auth-String tokenString := c.GetHeader("Authorization") username, _, err := service.ExtractTokenData(tokenString) if err != nil { @@ -50,6 +52,7 @@ func (h *ShoppingCartHandler) AddProductToShoppingCart(c *gin.Context) { return } + //Get product id from url ProductID, err := strconv.Atoi(c.Param("id")) if err != nil { log.Error("Invalid Product ID") @@ -61,6 +64,7 @@ func (h *ShoppingCartHandler) AddProductToShoppingCart(c *gin.Context) { Amount int `json:"amount" binding:"required"` } + //bind information from body if err := c.ShouldBindJSON(&addProductData); err != nil { log.Error("ShouldBindJSON in AddProductToShoppingCart failed") c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) @@ -78,14 +82,14 @@ func (h *ShoppingCartHandler) AddProductToShoppingCart(c *gin.Context) { } // Bezahlfunktion für den ShoppingCart -func (h *ShoppingCartHandler) Bezahlen(c *gin.Context) { +func (h *ShoppingCartHandler) TransferMoney(c *gin.Context) { tokenString := c.GetHeader("Authorization") username, _, err := service.ExtractTokenData(tokenString) if err != nil { log.Errorf(err.Error()) } - err = h.ShoppingCartService.Bezahlen(username) + err = h.ShoppingCartService.TransferMoney(username) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return diff --git a/src/gomazon/main.go b/src/gomazon/main.go index 698192c4412a7e4508397863305f0b28f0900241..4306b4a809131381590a4297330d73fc5937e1a4 100644 --- a/src/gomazon/main.go +++ b/src/gomazon/main.go @@ -9,13 +9,13 @@ import ( func main() { router := gin.Default() - // Service erstellen + // create Service ProductService := &service.ProductService{} RatingService := &service.RatingService{} bankAccountService := &service.BankAccountService{} ShoppingCartService := &service.ShoppingCartService{} - // Handler erstellen und den Service zuweisen + // create Handler ProductHandler := &handler.ProductHandler{ProductService: ProductService} RatingHandler := &handler.RatingHandler{RatingService: RatingService} bankAccountHandler := &handler.BankAccountHandler{BankAccountService: bankAccountService} @@ -26,29 +26,28 @@ func main() { handler.Health(c.Writer, c.Request) }) - ////Non-Admin-Funktionen router.GET("/createJWT", handler.GenerateAdminTokenHandler) //generate jwt-token //Products - router.POST("/products", ProductHandler.CreateProduct) //neues Product (Admin only) + router.POST("/products", ProductHandler.CreateProduct) //new Product (Admin only) router.PUT("/products/:id", ProductHandler.UpdateProduct) //update Product (Admin only) router.DELETE("/products/:id", ProductHandler.DeleteProduct) //Delete Product (Admin only) - router.GET("/products", ProductHandler.ReadProducts) //alle Products - router.GET("/products/:id", ProductHandler.GetProductByID) //einzelnes Product + router.GET("/products", ProductHandler.ReadProducts) //all Products + router.GET("/products/:id", ProductHandler.GetProductByID) //single Product //Rating - router.POST("/products/:id/rating", RatingHandler.CreateRating) //neue Rating - router.DELETE("/ratings/:id", RatingHandler.DeleteRating) //Delete Rating (Admin only (oder eigene)) - router.GET("/ratings", RatingHandler.ReadRatings) //alle Ratings + router.POST("/products/:id/rating", RatingHandler.CreateRating) //new Rating + router.DELETE("/ratings/:id", RatingHandler.DeleteRating) //Delete Rating (Admin only (or own Rating)) + router.GET("/ratings", RatingHandler.ReadRatings) //all Ratings - //Bankkonto - router.POST("/bankaccounts", bankAccountHandler.CreateBankAccount) // neues Konto - router.PUT("/bankaccounts", bankAccountHandler.UpdateBankAccount) // Überweisung + //Bankaccount + router.POST("/bankaccounts", bankAccountHandler.CreateBankAccount) // new Bankaccount + router.PUT("/bankaccounts", bankAccountHandler.UpdateBankAccount) // Transfer //ShoppingCart - router.POST("/ShoppingCart", ShoppingCartHandler.CreateShoppingCart) //neuer ShoppingCart - router.POST("/ShoppingCart/Product/:id", ShoppingCartHandler.AddProductToShoppingCart) //Product hinzufügen - router.POST("/ShoppingCart/bezahlen", ShoppingCartHandler.Bezahlen) //bezahlen + router.POST("/ShoppingCart", ShoppingCartHandler.CreateShoppingCart) //new ShoppingCart + router.POST("/ShoppingCart/Product/:id", ShoppingCartHandler.AddProductToShoppingCart) //add Product + router.POST("/ShoppingCart/pay", ShoppingCartHandler.TransferMoney) //pay router.Run(":8080") } diff --git a/src/gomazon/service/auth.go b/src/gomazon/service/auth.go index 5df43f9253f5c9832cf3cce7330953ee61d4c0a4..0195efb5088c7ad2cfd66e59fe1117b914870693 100644 --- a/src/gomazon/service/auth.go +++ b/src/gomazon/service/auth.go @@ -28,10 +28,10 @@ func GenerateAdminJWTToken(username string, isAdmin bool, expiration time.Time) return tokenString, nil } -// Funktion zum Extrahieren von Informationen aus dem JWT-Token +// Extract Token func ExtractTokenData(tokenString string) (string, bool, error) { tokenString = strings.TrimPrefix(tokenString, "Bearer ") - // Token parsen + // Parse Token token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { return []byte("key-replacement"), nil }) @@ -40,7 +40,7 @@ func ExtractTokenData(tokenString string) (string, bool, error) { return "", false, err } - // Überprüfen, ob das Token gültig ist + // Check if token is valid if !token.Valid { log.Error("invalid token") return "", false, fmt.Errorf("invalid token") @@ -57,14 +57,14 @@ func ExtractTokenData(tokenString string) (string, bool, error) { return "", false, fmt.Errorf("invalid token claims") } - // Claims aus dem Token extrahieren + // Extract claims claims, ok := token.Claims.(jwt.MapClaims) if !ok { log.Error("Invalid token claims") return "", false, fmt.Errorf("invalid token claims") } - // Benutzername und isAdmin aus den Claims erhalten + // check username and isAdmin username, ok := claims["username"].(string) if !ok { log.Error("Invalid Username claim") diff --git a/src/gomazon/service/bank.go b/src/gomazon/service/bank.go index 50a330ea2098b9ea76b9b32876dafff3a194deae..7d4c4b631fc112328935aa9a0e8b7624a5a2672f 100644 --- a/src/gomazon/service/bank.go +++ b/src/gomazon/service/bank.go @@ -12,9 +12,9 @@ import ( type BankAccountService struct{} -// Bankkonto erstellen +// Generate Bankaccount func (s *BankAccountService) CreateBankAccount(bankAccount model.BankAccount) (*model.BankAccount, error) { - // Überprüfen, ob der Benutzername bereits vorhanden ist + //Check if user has already a Bankaccount existingAccount := &model.BankAccount{} result := db.DB.Where("username = ?", bankAccount.Username).First(existingAccount) if result.Error == nil { @@ -23,7 +23,6 @@ func (s *BankAccountService) CreateBankAccount(bankAccount model.BankAccount) (* return nil, result.Error } - // Hier den Code für die Datenbankoperation zum Erstellen des Bankkontos einfügen result = db.DB.Create(&bankAccount) if result.Error != nil { log.Error("Could not create Bankaccount") @@ -33,8 +32,9 @@ func (s *BankAccountService) CreateBankAccount(bankAccount model.BankAccount) (* return &bankAccount, nil } +// Banktransfer func (s *BankAccountService) UpdateBankAccount(username string, amount float64) (*model.BankAccount, error) { - // Bankkonto des Benutzernamens finden + // Get account for user bankAccount := &model.BankAccount{} result := db.DB.Where("username = ?", username).First(bankAccount) if result.Error != nil { @@ -44,16 +44,15 @@ func (s *BankAccountService) UpdateBankAccount(username string, amount float64) return nil, result.Error } - // Überprüfen, ob der Betrag zu einem negativen Kontostand führen würde + // Check if the amount would result in a negative account balance if amount < 0 && bankAccount.Balance+amount < 0 { log.Error("Withdrawal amount exceeds the balance on the bank account") return nil, fmt.Errorf("withdrawal amount exceeds the balance on the bank account") } - // Einzahlung oder Abhebung vom Bankkonto durchführen + // Make a deposit or withdrawal from the bank account bankAccount.Balance += amount - // Bankkonto in einer einzelnen Datenbankoperation speichern result = db.DB.Save(bankAccount) if result.Error != nil { log.Error("Could not save changes of Bankaccount") @@ -63,6 +62,7 @@ func (s *BankAccountService) UpdateBankAccount(username string, amount float64) return bankAccount, nil } +// Get an account by username func (s *BankAccountService) GetBankAccountByUsername(username string) (*model.BankAccount, error) { bankAccount := &model.BankAccount{} result := db.DB.Where("username = ?", username).First(bankAccount) diff --git a/src/gomazon/service/bewertung.go b/src/gomazon/service/bewertung.go index 8a78251c4910542df87fda82d37a3f398313360a..e0b7a53f09e96b45e57856956196f249dd09f873 100644 --- a/src/gomazon/service/bewertung.go +++ b/src/gomazon/service/bewertung.go @@ -10,6 +10,7 @@ type RatingService struct { ProductService *ProductService } +// Create Rating func (s *RatingService) CreateRating(ProductID uint, Rating *model.Rating) error { Rating.ProductId = ProductID @@ -24,6 +25,7 @@ func (s *RatingService) CreateRating(ProductID uint, Rating *model.Rating) error log.Errorf("Error in CreateRating: GetProductByID failed") return nil } + // Recalculate Rating for this product err = RecalculateTotalratingForProduct(Product) if err != nil { log.Errorf("Recalculation failed") @@ -36,10 +38,11 @@ func (s *RatingService) CreateRating(ProductID uint, Rating *model.Rating) error return nil } +// Delete Rating func (s *RatingService) DeleteRating(RatingID uint) error { Rating, err := s.ProductService.GetRatingByID(RatingID) if err != nil { - log.Errorf("failed to get Product: %v", err) + log.Errorf("failed to get Rating: %v", err) return nil } @@ -49,10 +52,24 @@ func (s *RatingService) DeleteRating(RatingID uint) error { return result.Error } + product, err := s.ProductService.GetProductByID(Rating.ProductId) + if err != nil { + log.Errorf("failed to get Product: %v", err) + return nil + } + + // Recalculate + err = RecalculateTotalratingForProduct(product) + if err != nil { + log.Errorf("Recalculation failed") + return nil + } + log.Info("Successfully deleted Rating") return nil } +// Get single Rating func (s *ProductService) GetRatingByID(id uint) (*model.Rating, error) { var Rating model.Rating @@ -66,6 +83,7 @@ func (s *ProductService) GetRatingByID(id uint) (*model.Rating, error) { return &Rating, nil } +// Get all Ratings func (s *ProductService) ReadRatings() ([]model.Rating, error) { var Ratings []model.Rating @@ -75,15 +93,15 @@ func (s *ProductService) ReadRatings() ([]model.Rating, error) { return nil, result.Error } - log.Info("Loaded all Ratings") return Ratings, nil } +// Function for the Product-Rating calculation func RecalculateTotalratingForProduct(Product *model.Product) error { - // Totalrating zurücksetzen + // Resetting Totalrating Product.Totalrating = 0.0 - // Ratings für das Product aus der Datenbank abrufen + // Get all Ratings with specific productid for calculation var Ratings []model.Rating err := db.DB.Where("Product_id = ?", Product.ID).Find(&Ratings).Error if err != nil { @@ -91,6 +109,7 @@ func RecalculateTotalratingForProduct(Product *model.Product) error { return err } + // generate Mean numRatings := len(Ratings) if numRatings > 0 { totalRating := 0 @@ -100,7 +119,6 @@ func RecalculateTotalratingForProduct(Product *model.Product) error { Product.Totalrating = float64(totalRating) / float64(numRatings) } - // Product in der Datenbank aktualisieren err = db.DB.Save(Product).Error if err != nil { log.Error("Could not save Product") @@ -110,3 +128,25 @@ func RecalculateTotalratingForProduct(Product *model.Product) error { log.Infof("Successfully recalculated Product %v", Product.ID) return nil } + +// If a Product will be deleted, all Ratings of this Product will be deleted +// (Workarount, weil die Ratings nicht dem Slice übergeben werden) +func (s *RatingService) DeleteRatingsForProduct(productID uint) error { + // Get all Ratings from Product + var ratings []model.Rating + err := db.DB.Where("product_id = ?", productID).Find(&ratings).Error + if err != nil { + return err + } + + if len(ratings) == 0 { + return nil + } + // Delete + err = db.DB.Delete(&ratings).Error + if err != nil { + return err + } + log.Infof("All Ratings deleted für Product %v", productID) + return nil +} diff --git a/src/gomazon/service/produkt.go b/src/gomazon/service/produkt.go index c39840450634a152809165bc21f17c4528a3de65..48a0b553e1e85d18a68ff71d6fbce9643dce6406 100644 --- a/src/gomazon/service/produkt.go +++ b/src/gomazon/service/produkt.go @@ -8,6 +8,7 @@ import ( type ProductService struct{} +// Create Product func (s *ProductService) CreateProduct(Product model.Product) (*model.Product, error) { result := db.DB.Create(&Product) if result.Error != nil { @@ -18,6 +19,7 @@ func (s *ProductService) CreateProduct(Product model.Product) (*model.Product, e return &Product, nil } +// Get all Products func (s *ProductService) ReadProducts() ([]model.Product, error) { var Products []model.Product @@ -30,6 +32,7 @@ func (s *ProductService) ReadProducts() ([]model.Product, error) { return Products, nil } +// Update Product func (s *ProductService) UpdateProduct(id uint, ProductChanges model.Product) (*model.Product, error) { Product, err := s.GetProductByID(id) if err != nil { @@ -50,6 +53,7 @@ func (s *ProductService) UpdateProduct(id uint, ProductChanges model.Product) (* return Product, nil } +// Delete Product func (s *ProductService) DeleteProduct(id uint) error { Product, err := s.GetProductByID(id) if err != nil { @@ -65,6 +69,7 @@ func (s *ProductService) DeleteProduct(id uint) error { return nil } +// Get single Product func (s *ProductService) GetProductByID(id uint) (*model.Product, error) { var Product model.Product diff --git a/src/gomazon/service/warenkorb.go b/src/gomazon/service/warenkorb.go index 5ce348c460ef2be49613b6133b773fba09ec5252..0c1a70baff3ce08e17e9fcfc0f5484c607dfc78c 100644 --- a/src/gomazon/service/warenkorb.go +++ b/src/gomazon/service/warenkorb.go @@ -13,9 +13,9 @@ type ShoppingCartService struct { BankAccountService *BankAccountService } -// ShoppingCart erstellen +// Generate ShoppingCart (or get existing ShoppingCart) func (s *ShoppingCartService) CreateShoppingCart(ShoppingCart model.ShoppingCart) (*model.ShoppingCart, error) { - // Überprüfen, ob der ShoppingCart für den Benutzernamen bereits vorhanden ist + // Check if user has already a shoppingcart existingShoppingCart := &model.ShoppingCart{} result := db.DB.Where("username = ?", ShoppingCart.Username).First(existingShoppingCart) if result.Error == nil { @@ -24,7 +24,6 @@ func (s *ShoppingCartService) CreateShoppingCart(ShoppingCart model.ShoppingCart return nil, result.Error } - // Hier den Code für die Datenbankoperation zum Erstellen des ShoppingCarts einfügen result = db.DB.Create(&ShoppingCart) if result.Error != nil { log.Error("Could not create ShoppingCart") @@ -35,8 +34,9 @@ func (s *ShoppingCartService) CreateShoppingCart(ShoppingCart model.ShoppingCart return &ShoppingCart, nil } -// Einzelnes Product zum ShoppingCart hinzufügen +// Add single Product to ShoppingCart func (s *ShoppingCartService) AddProductToShoppingCart(username string, ProductID uint, amount int) (*model.ShoppingCart, error) { + //Get ShoppingCart ShoppingCart := &model.ShoppingCart{} result := db.DB.Preload("Positionen").Where("username = ?", username).First(ShoppingCart) if result.Error != nil { @@ -44,6 +44,7 @@ func (s *ShoppingCartService) AddProductToShoppingCart(username string, ProductI return nil, result.Error } + // Get product information Product := &model.Product{} result = db.DB.First(Product, ProductID) if result.Error != nil { @@ -51,6 +52,7 @@ func (s *ShoppingCartService) AddProductToShoppingCart(username string, ProductI return nil, result.Error } + // Generate total Price gesPrice := Product.Price * float64(amount) position := model.Position{ @@ -60,6 +62,7 @@ func (s *ShoppingCartService) AddProductToShoppingCart(username string, ProductI Totalprice: gesPrice, } + // Add position to shoppingcart ShoppingCart.Positionen = append(ShoppingCart.Positionen, position) ShoppingCart.Totalprice += position.Totalprice @@ -73,8 +76,9 @@ func (s *ShoppingCartService) AddProductToShoppingCart(username string, ProductI return ShoppingCart, nil } -// Bezahlfunktion für den ShoppingCart -func (s *ShoppingCartService) Bezahlen(username string) error { +// Tansfer Money +func (s *ShoppingCartService) TransferMoney(username string) error { + // Get shoppingcart from user ShoppingCart := &model.ShoppingCart{} result := db.DB.Preload("Positionen").Where("username = ?", username).First(ShoppingCart) if result.Error != nil { @@ -82,25 +86,26 @@ func (s *ShoppingCartService) Bezahlen(username string) error { return result.Error } + // Get Bankacc from user bankAccount, err := s.BankAccountService.GetBankAccountByUsername(username) if err != nil { return err } - // Überprüfen, ob das Bankkonto ausreichend Guthaben hat - if bankAccount.Balance < ShoppingCart.Totalprice { + // Check if Balance ge Totalprice + if bankAccount.Balance <= ShoppingCart.Totalprice { log.Error("Not enough balance in the bank account") return errors.New("not enough balance in the bank account") } - // Banküberweisung durchführen + // Transfer Money _, err = s.BankAccountService.UpdateBankAccount(username, -ShoppingCart.Totalprice) if err != nil { log.Error("UpdateBankAccount failed") return err } - // Einträge im ShoppingCart zurücksetzen + // Set Shoppingcart to default for i := range ShoppingCart.Positionen { ShoppingCart.Positionen[i].Amount = 0 }