customer/internal/service/account/account.go

216 lines
5.8 KiB
Go
Raw Normal View History

2023-05-17 20:27:09 +00:00
package account
import (
"context"
"fmt"
"math"
2023-05-17 20:27:09 +00:00
"go.uber.org/zap"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
)
type accountRepository interface {
FindByUserID(ctx context.Context, id string) (*models.Account, errors.Error)
FindMany(ctx context.Context, page, limit int64) ([]models.Account, errors.Error)
Insert(ctx context.Context, account *models.Account) (*models.Account, errors.Error)
Remove(ctx context.Context, id string) (*models.Account, errors.Error)
Delete(ctx context.Context, id string) (*models.Account, errors.Error)
CountAll(ctx context.Context) (int64, errors.Error)
2023-05-17 20:27:09 +00:00
}
type authClient interface {
GetUser(ctx context.Context, userID string) (*models.User, errors.Error)
}
type Deps struct {
Logger *zap.Logger
Repository accountRepository
AuthClient authClient
}
type Service struct {
logger *zap.Logger
Repository accountRepository
AuthClient authClient
2023-05-17 20:27:09 +00:00
}
func New(deps *Deps) *Service {
return &Service{
logger: deps.Logger,
Repository: deps.Repository,
AuthClient: deps.AuthClient,
2023-05-17 20:27:09 +00:00
}
}
func (receiver *Service) GetAccountByUserID(ctx context.Context, userID string) (*models.Account, errors.Error) {
account, err := receiver.Repository.FindByUserID(ctx, userID)
2023-05-17 20:27:09 +00:00
if err != nil {
receiver.logger.Error("failed to get account by id on <GetAccountByUserID> of <AccountService>",
zap.Error(err.Extract()),
zap.String("userID", userID),
)
return nil, err
}
return account, nil
}
func (receiver *Service) GetAccountsList(ctx context.Context, pagination *models.Pagination) (*models.PaginationResponse[models.Account], errors.Error) {
2023-05-17 20:27:09 +00:00
if pagination == nil {
return nil, errors.New(
fmt.Errorf("pagination is nil on <GetAccountsList> of <AccountService>: %w", errors.ErrInternalError),
errors.ErrInternalError,
)
}
count, err := receiver.Repository.CountAll(ctx)
if err != nil {
receiver.logger.Error("failed to count accounts on <GetAccountsList> of <AccountService>",
zap.Error(err.Extract()),
)
return nil, err
}
if count == 0 {
return &models.PaginationResponse[models.Account]{TotalPages: 0, Records: []models.Account{}}, nil
}
totalPages := int64(math.Ceil(float64(count) / float64(pagination.Limit)))
accounts, err := receiver.Repository.FindMany(ctx, pagination.Page, pagination.Limit)
2023-05-17 20:27:09 +00:00
if err != nil {
receiver.logger.Error("failed to get accounts list on <GetAccountsList> of <AccountService>",
zap.Error(err.Extract()),
zap.Int64("page", pagination.Page),
zap.Int64("limit", pagination.Limit),
)
return nil, err
}
return &models.PaginationResponse[models.Account]{
TotalPages: totalPages,
Records: accounts,
}, nil
2023-05-17 20:27:09 +00:00
}
func (receiver *Service) CreateAccount(ctx context.Context, account *models.Account) (*models.Account, errors.Error) {
findedAccount, err := receiver.GetAccountByUserID(ctx, account.UserID)
if err != nil && err.Type() != errors.ErrNotFound {
receiver.logger.Error("failed to find account on <CreateAccount> of <AccountService>",
zap.Error(err.Extract()),
)
return nil, err
}
if findedAccount != nil {
return nil, errors.New(
fmt.Errorf("failed to create account with <%s> on <CreateAccount> of <AccountService>: %w",
account.UserID,
errors.ErrConflict,
),
errors.ErrConflict,
)
}
createdAccount, err := receiver.Repository.Insert(ctx, account)
2023-05-17 20:27:09 +00:00
if err != nil {
receiver.logger.Error("failed to create account on <CreateAccount> of <AccountService>",
zap.Error(err.Extract()),
zap.Any("account", account),
)
return nil, err
}
return createdAccount, nil
2023-05-17 20:27:09 +00:00
}
/*
CreateAccountByUserID возвращает аккаут по id пользователя
2023-05-17 20:27:09 +00:00
TODO: Дополнить проверку на дефолтное значение Currency.
2023-05-17 20:27:09 +00:00
*/
func (receiver *Service) CreateAccountByUserID(ctx context.Context, userID string) (*models.Account, errors.Error) {
account, err := receiver.GetAccountByUserID(ctx, userID)
if err != nil && err.Type() != errors.ErrNotFound {
receiver.logger.Error("failed to find account on <CreateAccountByUserID> of <AccountService>",
zap.Error(err.Extract()),
)
return nil, err
}
if account != nil {
return nil, errors.New(
fmt.Errorf("failed to create account with <%s> on <CreateAccountByUserID> of <AccountService>: %w",
userID,
errors.ErrConflict,
),
errors.ErrConflict,
)
}
user, err := receiver.AuthClient.GetUser(ctx, userID)
2023-05-17 20:27:09 +00:00
if err != nil {
receiver.logger.Error("failed to get user on <CreateAccountByUserID> of <AccountService>",
zap.Error(err.Extract()),
zap.String("userID", userID),
)
return nil, err
}
createdAccount, err := receiver.Repository.Insert(ctx, &models.Account{
2023-05-17 20:27:09 +00:00
UserID: user.ID,
Cart: make([]string, 0),
Wallet: models.Wallet{
Cash: 0,
Money: 0,
Currency: "",
},
})
if err != nil {
receiver.logger.Error("failed to create account on <CreateAccountByUserID> of <AccountService>",
zap.Error(err.Extract()),
zap.String("userID", userID),
)
return nil, err
}
return createdAccount, nil
2023-05-17 20:27:09 +00:00
}
func (receiver *Service) RemoveAccount(ctx context.Context, userID string) (*models.Account, errors.Error) {
account, err := receiver.Repository.Remove(ctx, userID)
2023-05-17 20:27:09 +00:00
if err != nil {
receiver.logger.Error("failed to remove account on <RemoveAccount> of <AccountService>",
zap.Error(err.Extract()),
zap.String("userID", userID),
)
return nil, err
}
return account, nil
}
func (receiver *Service) DeleteAccount(ctx context.Context, userID string) (*models.Account, errors.Error) {
account, err := receiver.Repository.Delete(ctx, userID)
2023-05-17 20:27:09 +00:00
if err != nil {
receiver.logger.Error("failed to delete account on <DeleteAccount> of <AccountService>",
zap.Error(err.Extract()),
zap.String("userID", userID),
)
return nil, err
}
return account, nil
}