Files
bibliomane/internal/routes/userbookputupdate.go
2025-10-29 22:38:38 +01:00

81 lines
2.0 KiB
Go

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,
}
}