customer/internal/service/account/account.go

237 lines
6.2 KiB
Go
Raw Normal View History

2023-05-17 20:27:09 +00:00
package account
import (
"context"
"fmt"
2023-05-19 04:50:40 +00:00
"log"
"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
2023-05-19 04:50:40 +00:00
repository accountRepository
authClient authClient
2023-05-17 20:27:09 +00:00
}
func New(deps *Deps) *Service {
2023-05-19 04:50:40 +00:00
if deps == nil {
log.Panicln("deps is nil on <New (account service)>")
}
if deps.Logger == nil {
log.Panicln("logger is nil on <New (account service)>")
}
if deps.Repository == nil {
log.Panicln("repository is nil on <New (account service)>")
}
if deps.AuthClient == nil {
log.Panicln("auth client is nil on <New (account service)>")
}
2023-05-17 20:27:09 +00:00
return &Service{
logger: deps.Logger,
2023-05-19 04:50:40 +00:00
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) {
2023-05-19 04:50:40 +00:00
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,
)
}
2023-05-19 04:50:40 +00:00
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)))
2023-05-19 04:50:40 +00:00
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,
)
}
2023-05-19 04:50:40 +00:00
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
}
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,
)
}
2023-05-19 04:50:40 +00:00
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
}
2023-05-19 04:50:40 +00:00
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{
2023-06-01 11:38:53 +00:00
Cash: 0,
Money: 0,
Spent: 0,
PurchasesAmount: 0,
Currency: models.InternalCurrencyKey,
},
Name: models.Name{
FirstName: "",
Lastname: "",
Secondname: "",
Orgname: "",
2023-05-17 20:27:09 +00:00
},
2023-06-01 11:38:53 +00:00
Status: models.DefaultAccountStatus,
2023-05-17 20:27:09 +00:00
})
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) {
2023-05-19 04:50:40 +00:00
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) {
2023-05-19 04:50:40 +00:00
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
}