package routes import ( "errors" "net/http" "strconv" "git.artlef.fr/PersonalLibraryManager/internal/appcontext" "git.artlef.fr/PersonalLibraryManager/internal/model" "git.artlef.fr/PersonalLibraryManager/internal/myvalidator" "github.com/gin-gonic/gin" "gorm.io/gorm" ) type userbookPutUpdate struct { Read bool `json:"read"` Rating int `json:"rating" binding:"min=0,max=10"` } func PutUserBookHandler(ac appcontext.AppContext) { bookId64, err := strconv.ParseUint(ac.C.Param("id"), 10, 64) bookId := uint(bookId64) if err != nil { ac.C.JSON(http.StatusBadRequest, gin.H{"error": err}) return } err = myvalidator.ValidateId(ac.Db, bookId, &model.Book{}) if err != nil { myvalidator.ReturnErrorsAsJsonResponse(&ac, err) return } var userbook userbookPutUpdate err = ac.C.ShouldBindJSON(&userbook) if err != nil { myvalidator.ReturnErrorsAsJsonResponse(&ac, err) return } user, fetchUserErr := ac.GetAuthenticatedUser() if fetchUserErr != nil { myvalidator.ReturnErrorsAsJsonResponse(&ac, err) return } //a rating of 0 means no rating // if there is a rating, read is forced to true userbook.Read = userbook.Read || userbook.Rating > 0 var userbookDb model.UserBook res := ac.Db.Where("user_id = ? AND book_id = ?", user.ID, bookId).First(&userbookDb) err = res.Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { userbookDb = userBookWsToDb(userbook, bookId, &user) err = ac.Db.Save(&userbookDb).Error if err != nil { myvalidator.ReturnErrorsAsJsonResponse(&ac, err) return } } else { myvalidator.ReturnErrorsAsJsonResponse(&ac, err) return } } else { userbookDb.Read = userbook.Read if userbook.Rating > 0 { userbookDb.Rating = userbook.Rating } ac.Db.Save(&userbookDb) } ac.C.String(http.StatusOK, "Success") } func userBookWsToDb(ub userbookPutUpdate, bookId uint, user *model.User) model.UserBook { return model.UserBook{ UserID: user.ID, BookID: bookId, Read: ub.Read, Rating: ub.Rating, } }