customer/internal/interface/controller/rest/wallet/wallet.go

149 lines
5.1 KiB
Go
Raw Normal View History

2023-05-22 12:43:15 +00:00
package wallet
import (
"context"
"fmt"
"log"
"net/http"
"github.com/labstack/echo/v4"
"go.uber.org/zap"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils"
2023-05-22 12:43:15 +00:00
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils/echotools"
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/validate"
)
type walletService interface {
ReplenishAccountWallet(context.Context, *models.ReplenishAccountWallet) (*models.Account, errors.Error)
ChangeCurrency(ctx context.Context, userID string, currency models.CurrencyKey) (*models.Account, errors.Error)
}
type paymentService interface {
GetPaymentLink(context.Context, *models.RequestPaymentLink) (string, errors.Error)
}
2023-05-22 12:43:15 +00:00
type Deps struct {
Logger *zap.Logger
WalletService walletService
PaymentService paymentService
2023-05-22 12:43:15 +00:00
}
type Controller struct {
logger *zap.Logger
walletService walletService
paymentService paymentService
2023-05-22 12:43:15 +00:00
}
func New(deps Deps) *Controller {
2023-05-22 12:43:15 +00:00
if deps.Logger == nil {
log.Panicln("logger is nil on <New (wallet controller)>")
}
if deps.WalletService == nil {
log.Panicln("wallet service is nil on <New (wallet controller)>")
}
if deps.PaymentService == nil {
log.Panicln("payment service is nil on <New (wallet controller)>")
}
2023-05-22 12:43:15 +00:00
return &Controller{
logger: deps.Logger,
walletService: deps.WalletService,
paymentService: deps.PaymentService,
2023-05-22 12:43:15 +00:00
}
}
func (receiver *Controller) PutMoney(ctx echo.Context) error {
2023-06-13 12:32:08 +00:00
// TODO: Добавить валидацию Currency. Чтобы ключи стран были в определённом формате: ISO-4217.
2023-05-22 12:43:15 +00:00
request, bindErr := echotools.Bind[models.ReplenishAccountWallet](ctx)
if bindErr != nil {
receiver.logger.Error("failed to bind body on <PutMoney> of <WalletController>", zap.Error(bindErr))
return echotools.ResponseError(ctx, errors.New(
fmt.Errorf("failed to parse body on <PutMoney> of <WalletController>: %w", bindErr),
errors.ErrInvalidArgs,
))
}
account, err := receiver.walletService.ReplenishAccountWallet(ctx.Request().Context(), request)
if err != nil {
receiver.logger.Error("failed to put money on <PutMoney> of <WalletController>", zap.Error(err.Extract()))
return echotools.ResponseError(ctx, err)
}
return ctx.JSON(http.StatusOK, account)
}
func (receiver *Controller) ChangeCurrency(ctx echo.Context) error {
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
if !ok {
receiver.logger.Error("failed to convert jwt payload to string on <ChangeCurrency> of <WallerController>")
return echotools.ResponseError(ctx, errors.New(
fmt.Errorf("failed to convert jwt payload to string: %s", userID),
errors.ErrInvalidArgs,
))
}
request, bindErr := echotools.Bind[models.ChangeCurrency](ctx)
if bindErr != nil {
receiver.logger.Error("failed to bind body on <ChangeCurrency> of <WalletController>", zap.Error(bindErr))
return echotools.ResponseError(ctx, errors.New(
fmt.Errorf("failed to parse body on <ChangeCurrency> of <WalletController>: %w", bindErr),
errors.ErrInvalidArgs,
))
}
if validate.IsStringEmpty(request.Currency) {
return echotools.ResponseError(ctx, errors.New(
fmt.Errorf("empty currency key on <ChangeCurrency> of <WalletController>: %w", errors.ErrInvalidArgs),
errors.ErrInvalidArgs,
))
}
account, err := receiver.walletService.ChangeCurrency(ctx.Request().Context(), userID, request.Currency)
if err != nil {
receiver.logger.Error("failed to put money on <ChangeCurrency> of <WalletController>", zap.Error(err.Extract()))
return echotools.ResponseError(ctx, err)
}
return ctx.JSON(http.StatusOK, account)
}
func (receiver *Controller) GetPaymentLink(ctx echo.Context) error {
userID, ok := ctx.Get(models.AuthJWTDecodedUserIDKey).(string)
if !ok {
receiver.logger.Error("failed to convert jwt payload to string on <GetPaymentLink> of <WallerController>")
return echotools.ResponseError(ctx, errors.New(
fmt.Errorf("failed to convert jwt payload to string: %s", userID),
errors.ErrInvalidArgs,
))
}
request, bindErr := echotools.Bind[models.RequestPaymentLink](ctx)
if bindErr != nil {
receiver.logger.Error("failed to bind body on <GetPaymentLink> of <WalletController>", zap.Error(bindErr))
return echotools.ResponseError(ctx, errors.New(
fmt.Errorf("failed to parse body on <GetPaymentLink> of <WalletController>: %w", bindErr),
errors.ErrInvalidArgs,
))
}
if validateErr := utils.ValidateGetPaymentLinkRequest(request); validateErr != nil {
receiver.logger.Error("failed to validate body on <GetPaymentLink> of <WalletController>", zap.Error(validateErr))
return echotools.ResponseError(ctx, validateErr)
}
link, err := receiver.paymentService.GetPaymentLink(ctx.Request().Context(), request)
if err != nil {
receiver.logger.Error("failed to get payment link on <GetPaymentLink> of <WalletController>", zap.Error(err))
return echotools.ResponseError(ctx, err)
}
return ctx.JSON(http.StatusOK, &models.RequestPaymentLinkResponse{Link: link})
}