init
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
package processor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
||||
"apskel-pos-be/internal/entities"
|
||||
"apskel-pos-be/internal/mappers"
|
||||
"apskel-pos-be/internal/models"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type UserProcessorImpl struct {
|
||||
userRepo UserRepository
|
||||
organizationRepo OrganizationRepository
|
||||
outletRepo OutletRepository
|
||||
}
|
||||
|
||||
func NewUserProcessor(
|
||||
userRepo UserRepository,
|
||||
organizationRepo OrganizationRepository,
|
||||
outletRepo OutletRepository,
|
||||
) *UserProcessorImpl {
|
||||
return &UserProcessorImpl{
|
||||
userRepo: userRepo,
|
||||
organizationRepo: organizationRepo,
|
||||
outletRepo: outletRepo,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *UserProcessorImpl) CreateUser(ctx context.Context, req *models.CreateUserRequest) (*models.UserResponse, error) {
|
||||
_, err := p.organizationRepo.GetByID(ctx, req.OrganizationID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("organization not found: %w", err)
|
||||
}
|
||||
|
||||
if req.OutletID != nil {
|
||||
_, err := p.outletRepo.GetByID(ctx, *req.OutletID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("outlet not found: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
existingUser, err := p.userRepo.GetByEmail(ctx, req.Email)
|
||||
if err == nil && existingUser != nil {
|
||||
return nil, fmt.Errorf("user with email %s already exists", req.Email)
|
||||
}
|
||||
|
||||
passwordHash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to hash password: %w", err)
|
||||
}
|
||||
|
||||
userEntity := mappers.UserCreateRequestToEntity(req, string(passwordHash))
|
||||
|
||||
err = p.userRepo.Create(ctx, userEntity)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create user: %w", err)
|
||||
}
|
||||
|
||||
return mappers.UserEntityToResponse(userEntity), nil
|
||||
}
|
||||
|
||||
func (p *UserProcessorImpl) UpdateUser(ctx context.Context, id uuid.UUID, req *models.UpdateUserRequest) (*models.UserResponse, error) {
|
||||
existingUser, err := p.userRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("user not found: %w", err)
|
||||
}
|
||||
|
||||
if req.Email != nil && *req.Email != existingUser.Email {
|
||||
existingUserByEmail, err := p.userRepo.GetByEmail(ctx, *req.Email)
|
||||
if err == nil && existingUserByEmail != nil && existingUserByEmail.ID != id {
|
||||
return nil, fmt.Errorf("user with email %s already exists", *req.Email)
|
||||
}
|
||||
}
|
||||
|
||||
if req.Name != nil {
|
||||
existingUser.Name = *req.Name
|
||||
}
|
||||
if req.Email != nil {
|
||||
existingUser.Email = *req.Email
|
||||
}
|
||||
if req.Role != nil {
|
||||
existingUser.Role = entities.UserRole(*req.Role)
|
||||
}
|
||||
if req.OutletID != nil {
|
||||
existingUser.OutletID = req.OutletID
|
||||
}
|
||||
if req.IsActive != nil {
|
||||
existingUser.IsActive = *req.IsActive
|
||||
}
|
||||
if req.Permissions != nil {
|
||||
existingUser.Permissions = entities.Permissions(*req.Permissions)
|
||||
}
|
||||
|
||||
err = p.userRepo.Update(ctx, existingUser)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update user: %w", err)
|
||||
}
|
||||
|
||||
return mappers.UserEntityToResponse(existingUser), nil
|
||||
}
|
||||
|
||||
func (p *UserProcessorImpl) DeleteUser(ctx context.Context, id uuid.UUID) error {
|
||||
_, err := p.userRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("user not found: %w", err)
|
||||
}
|
||||
|
||||
err = p.userRepo.Delete(ctx, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete user: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *UserProcessorImpl) GetUserByID(ctx context.Context, id uuid.UUID) (*models.UserResponse, error) {
|
||||
user, err := p.userRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("user not found: %w", err)
|
||||
}
|
||||
|
||||
return mappers.UserEntityToResponse(user), nil
|
||||
}
|
||||
|
||||
func (p *UserProcessorImpl) GetUserByEmail(ctx context.Context, email string) (*models.UserResponse, error) {
|
||||
user, err := p.userRepo.GetByEmail(ctx, email)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("user not found: %w", err)
|
||||
}
|
||||
|
||||
return mappers.UserEntityToResponse(user), nil
|
||||
}
|
||||
|
||||
func (p *UserProcessorImpl) ListUsers(ctx context.Context, organizationID uuid.UUID, page, limit int) ([]models.UserResponse, int, error) {
|
||||
_, err := p.organizationRepo.GetByID(ctx, organizationID)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("organization not found: %w", err)
|
||||
}
|
||||
|
||||
offset := (page - 1) * limit
|
||||
|
||||
filters := map[string]interface{}{
|
||||
"organization_id": organizationID,
|
||||
}
|
||||
|
||||
users, totalCount, err := p.userRepo.List(ctx, filters, limit, offset)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to get users: %w", err)
|
||||
}
|
||||
|
||||
responses := make([]models.UserResponse, len(users))
|
||||
for i, user := range users {
|
||||
response := mappers.UserEntityToResponse(user)
|
||||
if response != nil {
|
||||
responses[i] = *response
|
||||
}
|
||||
}
|
||||
|
||||
return responses, int(totalCount), nil
|
||||
}
|
||||
|
||||
func (p *UserProcessorImpl) GetUserEntityByEmail(ctx context.Context, email string) (*entities.User, error) {
|
||||
user, err := p.userRepo.GetByEmail(ctx, email)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("user not found: %w", err)
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (p *UserProcessorImpl) ChangePassword(ctx context.Context, userID uuid.UUID, req *models.ChangePasswordRequest) error {
|
||||
user, err := p.userRepo.GetByID(ctx, userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("user not found: %w", err)
|
||||
}
|
||||
|
||||
err = bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(req.CurrentPassword))
|
||||
if err != nil {
|
||||
return fmt.Errorf("current password is incorrect")
|
||||
}
|
||||
|
||||
newPasswordHash, err := bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to hash new password: %w", err)
|
||||
}
|
||||
|
||||
err = p.userRepo.UpdatePassword(ctx, userID, string(newPasswordHash))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update password: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *UserProcessorImpl) ActivateUser(ctx context.Context, userID uuid.UUID) error {
|
||||
_, err := p.userRepo.GetByID(ctx, userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("user not found: %w", err)
|
||||
}
|
||||
|
||||
err = p.userRepo.UpdateActiveStatus(ctx, userID, true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to activate user: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *UserProcessorImpl) DeactivateUser(ctx context.Context, userID uuid.UUID) error {
|
||||
_, err := p.userRepo.GetByID(ctx, userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("user not found: %w", err)
|
||||
}
|
||||
|
||||
err = p.userRepo.UpdateActiveStatus(ctx, userID, false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to deactivate user: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user