From 1c4bd425d2c25df22535cad642a0cfc94d888524 Mon Sep 17 00:00:00 2001 From: Kirill Date: Thu, 1 Jun 2023 00:28:35 +0300 Subject: [PATCH] feat: actualize models --- internal/models/account.go | 33 ++++++--- internal/models/wallet.go | 12 +++- internal/service/cart/cart.go | 9 ++- internal/service/wallet/wallet.go | 107 ++++++++++++++++++++++++++++-- openapi.yaml | 14 ++-- 5 files changed, 151 insertions(+), 24 deletions(-) diff --git a/internal/models/account.go b/internal/models/account.go index 40db7d3..4b719e1 100644 --- a/internal/models/account.go +++ b/internal/models/account.go @@ -3,12 +3,29 @@ package models import "time" type Account struct { - ID string `json:"id" bson:"_id,omitempty"` - UserID string `json:"userId" bson:"userId"` - Cart []string `json:"cart" bson:"cart"` - Wallet Wallet `json:"wallet" bson:"wallet"` - Deleted bool `json:"deleted" bson:"deleted"` - CreatedAt time.Time `json:"createdAt" bson:"createdAt"` - UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` - DeletedAt *time.Time `json:"deletedAt,omitempty" bson:"deletedAt,omitempty"` + ID string `json:"id" bson:"_id,omitempty"` + UserID string `json:"userId" bson:"userId"` + Cart []string `json:"cart" bson:"cart"` + Wallet Wallet `json:"wallet" bson:"wallet"` + Name Name `json:"name" bson:"name"` + Status AccountStatus `json:"status" bson:"status"` + Deleted bool `json:"deleted" bson:"deleted"` + CreatedAt time.Time `json:"createdAt" bson:"createdAt"` + UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` + DeletedAt *time.Time `json:"deletedAt,omitempty" bson:"deletedAt,omitempty"` } + +type Name struct { + Lastname *string `json:"lastname,omitempty"` + Name *string `json:"name,omitempty"` + Orgname *string `json:"orgname,omitempty"` + Secondname *string `json:"secondname,omitempty"` +} + +type AccountStatus string + +const ( + AccountStatusNko AccountStatus = "nko" + AccountStatusNo AccountStatus = "no" + AccountStatusOrg AccountStatus = "org" +) diff --git a/internal/models/wallet.go b/internal/models/wallet.go index d52d5a0..fb8f4a8 100644 --- a/internal/models/wallet.go +++ b/internal/models/wallet.go @@ -1,8 +1,16 @@ package models +/* +TODO: + +5) актуализировать поле spent при покупке средств +*/ + type Wallet struct { - Cash int64 `json:"cash"` - Currency string `json:"currency"` + Cash int64 `json:"cash" bson:"cash"` + Currency string `json:"currency" bson:"currency"` + Spent int64 `json:"spent" bson:"spent"` + PurchasesAmount int64 `json:"purchasesAmount" bson:"purchasesAmount"` /* Money деньги на счету в копейках. Чтобы при перессчётах не возникало денег из ни откуда. diff --git a/internal/service/cart/cart.go b/internal/service/cart/cart.go index 2484848..6da0d9f 100644 --- a/internal/service/cart/cart.go +++ b/internal/service/cart/cart.go @@ -15,6 +15,8 @@ import ( "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils/transfer" ) +// TODO: добавить интерфейс клиента сервиса оплаты + type accountRepository interface { FindByUserID(ctx context.Context, id string) (*models.Account, errors.Error) AddItemToCart(ctx context.Context, userID, itemID string) (*models.Account, errors.Error) @@ -136,9 +138,9 @@ func (receiver *Service) Pay(ctx context.Context, userID string) errors.Error { response, err := receiver.discountClient.Apply(ctx, &discount.ApplyDiscountRequest{ UserInformation: &discount.UserInformation{ ID: account.UserID, - Type: "", // TODO: Добавить тип - PurchasesAmount: 0, // TODO: Добавить - CartPurchasesAmount: float64(tariffsAmount), // TODO: Перевести в int64 + Type: string(account.Status), + PurchasesAmount: float64(account.Wallet.PurchasesAmount), + CartPurchasesAmount: float64(tariffsAmount), }, Products: transfer.TariffsToProductInformations(tariffs), Date: timestamppb.New(time.Now()), @@ -161,6 +163,7 @@ func (receiver *Service) Pay(ctx context.Context, userID string) errors.Error { ) } + // TODO: изменить метод пополнения на метод вычитания средств с кошелька if _, err := receiver.walletService.ReplenishAccountWallet(ctx, &models.ReplenishAccountWallet{ Cash: -int64(response.Price), Currency: account.Wallet.Currency, diff --git a/internal/service/wallet/wallet.go b/internal/service/wallet/wallet.go index 5940c00..1eb494d 100644 --- a/internal/service/wallet/wallet.go +++ b/internal/service/wallet/wallet.go @@ -95,9 +95,10 @@ func (receiver *Service) ReplenishAccountWallet(ctx context.Context, request *mo if request.Currency == models.InternalCurrencyKey { updatedAccount, changeErr := receiver.repository.ChangeWallet(ctx, account.UserID, &models.Wallet{ - Cash: account.Wallet.Cash + cash, - Money: account.Wallet.Money + request.Cash, - Currency: account.Wallet.Currency, + Cash: account.Wallet.Cash + cash, + Money: account.Wallet.Money + request.Cash, + PurchasesAmount: account.Wallet.PurchasesAmount + request.Cash, + Currency: account.Wallet.Currency, }) if changeErr != nil { receiver.logger.Error("failed to replenish wallet on of ", @@ -128,9 +129,103 @@ func (receiver *Service) ReplenishAccountWallet(ctx context.Context, request *mo } updatedAccount, err := receiver.repository.ChangeWallet(ctx, account.UserID, &models.Wallet{ - Cash: account.Wallet.Cash + cash, - Money: account.Wallet.Money + money, - Currency: account.Wallet.Currency, + Cash: account.Wallet.Cash + cash, + Money: account.Wallet.Money + money, + PurchasesAmount: account.Wallet.PurchasesAmount + money, + Currency: account.Wallet.Currency, + }) + if err != nil { + receiver.logger.Error("failed to replenish wallet on of ", + zap.Error(err.Extract()), + zap.String("Currency", account.Wallet.Currency), + zap.Int64("Money", account.Wallet.Money+request.Cash), + zap.Int64("Cash", account.Wallet.Cash+cash), + zap.Bool("Is currensy equal internal", request.Currency == models.InternalCurrencyKey), + ) + + return nil, err + } + + return updatedAccount, nil +} + +func (receiver *Service) WithdrawAccountWalletMoney(ctx context.Context, money int64) (*models.Account, errors.Error) { + account, err := receiver.repository.FindByUserID(ctx, request.UserID) + if err != nil { + receiver.logger.Error("failed to find account on of ", + zap.Error(err.Extract()), + zap.String("userID", request.UserID), + ) + + return nil, err + } + + if validate.IsStringEmpty(account.Wallet.Currency) { + return nil, errors.New( + fmt.Errorf("currency of account <%s> is empty of ", account.UserID), + errors.ErrInternalError, + ) + } + + cash := request.Cash + + if request.Currency != account.Wallet.Currency { + translatedCash, translateErr := receiver.currencyClient.Translate(ctx, &models.TranslateCurrency{ + Money: request.Cash, + From: request.Currency, + To: account.Wallet.Currency, + }) + if translateErr != nil { + receiver.logger.Error("failed to translate cash on of ", + zap.Error(translateErr.Extract()), + ) + + return nil, translateErr + } + + cash = translatedCash + } + + if request.Currency == models.InternalCurrencyKey { + updatedAccount, changeErr := receiver.repository.ChangeWallet(ctx, account.UserID, &models.Wallet{ + Cash: account.Wallet.Cash + cash, + Money: account.Wallet.Money + request.Cash, + PurchasesAmount: account.Wallet.PurchasesAmount + request.Cash, + Currency: account.Wallet.Currency, + }) + if changeErr != nil { + receiver.logger.Error("failed to replenish wallet on of ", + zap.Error(changeErr.Extract()), + zap.String("Currency", account.Wallet.Currency), + zap.Int64("Money", account.Wallet.Money+request.Cash), + zap.Int64("Cash", account.Wallet.Cash+cash), + zap.Bool("Is currensy equal internal", request.Currency == models.InternalCurrencyKey), + ) + + return nil, changeErr + } + + return updatedAccount, nil + } + + money, err := receiver.currencyClient.Translate(ctx, &models.TranslateCurrency{ + Money: request.Cash, + From: request.Currency, + To: models.InternalCurrencyKey, + }) + if err != nil { + receiver.logger.Error("failed to translate money on of ", + zap.Error(err.Extract()), + ) + + return nil, err + } + + updatedAccount, err := receiver.repository.ChangeWallet(ctx, account.UserID, &models.Wallet{ + Cash: account.Wallet.Cash + cash, + Money: account.Wallet.Money + money, + PurchasesAmount: account.Wallet.PurchasesAmount + money, + Currency: account.Wallet.Currency, }) if err != nil { receiver.logger.Error("failed to replenish wallet on of ", diff --git a/openapi.yaml b/openapi.yaml index 85ca180..f5c5431 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -656,7 +656,7 @@ components: Account: type: object - required: [_id, userId, cart, wallet, deleted, createdAt, updatedAt] + required: [_id, userId, cart, wallet, name, status, deleted, createdAt, updatedAt] properties: _id: type: string @@ -677,7 +677,7 @@ components: $ref: "#/components/schemas/Wallet" status: type: string - enum: ["no", "org", "nko"] + enum: ["no", "org", "nko"] /* TODO: no по дефолту */ deleted: type: boolean example: false @@ -694,7 +694,7 @@ components: Name: type: object properties: - name: + firstname: type: string example: Иван secondname: @@ -709,7 +709,7 @@ components: Wallet: type: object - required: [currency, cash, money] + required: [currency, cash, money, purchasesAmount, spent] properties: currency: description: Текущий курс валюты @@ -720,10 +720,14 @@ components: type: integer format: int64 example: 10701 + purchasesAmount: + type: integer + format: int64 + description: Общая сумма денег, которые внёс пользователь spent: type: integer format: int64 - description: общая сумма потраченных денег за всё время существования аккаунта + description: Общая сумма потраченных денег за всё время существования аккаунта money: type: integer format: int64