package repositories import ( "gorm.io/gorm" "GoMembership/internal/database" "gorm.io/gorm/clause" "GoMembership/internal/models" "GoMembership/pkg/errors" "GoMembership/pkg/logger" ) type UserRepositoryInterface interface { CreateUser(user *models.User) (uint, error) UpdateUser(user *models.User) (*models.User, error) GetUsers(where map[string]interface{}) (*[]models.User, error) GetUserByEmail(email string) (*models.User, error) IsVerified(userID *uint) (bool, error) GetVerificationOfToken(token *string, verificationType *string) (*models.Verification, error) SetVerificationToken(verification *models.Verification) (token string, err error) DeleteVerification(id uint, verificationType string) error DeleteUser(id uint) error SetUserStatus(id uint, status uint) error } type UserRepository struct{} func (ur *UserRepository) DeleteUser(id uint) error { return database.DB.Delete(&models.User{}, "id = ?", id).Error } func PasswordExists(userID *uint) (bool, error) { var user models.User result := database.DB.Select("password").First(&user, userID) if result.Error != nil { return false, result.Error } return user.Password != "", nil } func (ur *UserRepository) CreateUser(user *models.User) (uint, error) { result := database.DB.Create(user) if result.Error != nil { logger.Error.Printf("Create User error: %#v", result.Error) return 0, result.Error } return user.ID, nil } func (ur *UserRepository) UpdateUser(user *models.User) (*models.User, error) { if user == nil { return nil, errors.ErrNoData } err := database.DB.Transaction(func(tx *gorm.DB) error { // Check if the user exists in the database var existingUser models.User if err := tx.Preload(clause.Associations). Preload("Membership"). Preload("Membership.SubscriptionModel"). Preload("Licence"). Preload("Licence.Categories"). First(&existingUser, user.ID).Error; err != nil { return err } // Update the user's main fields result := tx.Session(&gorm.Session{FullSaveAssociations: true}).Omit("Password").Updates(user) if result.Error != nil { return result.Error } if result.RowsAffected == 0 { return errors.ErrNoRowsAffected } if user.Password != "" { if err := tx.Model(&models.User{}). Where("id = ?", user.ID). Update("Password", user.Password).Error; err != nil { return err } } // Update the Membership if provided if user.Membership.ID != 0 { if err := tx.Model(&existingUser.Membership).Updates(user.Membership).Error; err != nil { return err } } // Replace categories if Licence and Categories are provided if user.Licence != nil { if err := tx.Model(&user.Licence).Association("Categories").Replace(user.Licence.Categories); err != nil { return err } } return nil }) if err != nil { return nil, err } var updatedUser models.User if err := database.DB.Preload("Licence.Categories"). Preload("Membership"). First(&updatedUser, user.ID).Error; err != nil { return nil, err } return &updatedUser, nil } func (ur *UserRepository) GetUsers(where map[string]interface{}) (*[]models.User, error) { var users []models.User result := database.DB. Preload(clause.Associations). Preload("Membership.SubscriptionModel"). Preload("Licence.Categories"). Where(where).Find(&users) if result.Error != nil { if result.Error == gorm.ErrRecordNotFound { return nil, gorm.ErrRecordNotFound } return nil, result.Error } return &users, nil } func GetUserByID(userID *uint) (*models.User, error) { var user models.User result := database.DB. Preload(clause.Associations). Preload("Membership"). Preload("Membership.SubscriptionModel"). Preload("Licence.Categories"). First(&user, userID) if result.Error != nil { if result.Error == gorm.ErrRecordNotFound { return nil, gorm.ErrRecordNotFound } return nil, result.Error } return &user, nil } func (ur *UserRepository) GetUserByEmail(email string) (*models.User, error) { var user models.User result := database.DB.Where("email = ?", email).First(&user) if result.Error != nil { if result.Error == gorm.ErrRecordNotFound { return nil, gorm.ErrRecordNotFound } return nil, result.Error } return &user, nil }