generated from PenaSide/GolangTemplate
ci: set broker ip
This commit is contained in:
parent
84efe70936
commit
6b648c4f48
28
.env.test
28
.env.test
@ -1,25 +1,25 @@
|
||||
# HTTP settings
|
||||
HTTP_HOST=0.0.0.0
|
||||
HTTP_PORT=8080
|
||||
HTTP_PORT=8082
|
||||
|
||||
# MONGO settings
|
||||
MONGO_HOST=localhost
|
||||
GRPC_HOST=0.0.0.0
|
||||
GRPC_PORT=9082
|
||||
GRPC_DOMEN=customer-app:9082
|
||||
|
||||
MONGO_HOST=mongo
|
||||
MONGO_PORT=27017
|
||||
MONGO_USER=test
|
||||
MONGO_PASSWORD=test
|
||||
MONGO_AUTH=admin
|
||||
MONGO_DB_NAME=admin
|
||||
MONGO_AUTH=admin
|
||||
|
||||
# Auth Microservice settings
|
||||
AUTH_MICROSERVICE_USER_URL=http://localhost:8000/user
|
||||
AUTH_MICROSERVICE_USER_URL=http://pena-auth-service:8000/user
|
||||
HUBADMIN_MICROSERVICE_TARIFF_URL=http://hub-admin-service:8010/tariff
|
||||
CURRENCY_MICROSERVICE_TRANSLATE_URL=http://cbrf-service:8020/translate
|
||||
DISCOUNT_MICROSERVICE_GRPC_HOST=discount-service:9040
|
||||
PAYMENT_MICROSERVICE_GRPC_HOST=treasurer-service:9085
|
||||
|
||||
# Hub Admin Microservice settings
|
||||
HUBADMIN_MICROSERVICE_TARIFF_URL=http://localhost:8001/tariff
|
||||
|
||||
# Currency Microservice settings
|
||||
CURRENCY_MICROSERVICE_TRANSLATE_URL=http://localhost:8002/change
|
||||
|
||||
# Admin
|
||||
KAFKA_BROKERS=localhost:8080,localhost:1111
|
||||
KAFKA_TOPIC_TARIFF=tariff
|
||||
|
||||
# JWT settings
|
||||
JWT_ISSUER="pena-auth-service"
|
||||
|
@ -34,6 +34,9 @@ PAYMENT_MICROSERVICE_GRPC_HOST - хост микросервиса payment (GRPC
|
||||
JWT_PUBLIC_KEY - публичный ключ для верификации jwt токена
|
||||
JWT_ISSUER - издатель токена
|
||||
JWT_AUDIENCE - аудитория, которая может верифицировать токен
|
||||
|
||||
KAFKA_BROKERS - массив брокеров (localhost:8888,localhost:1111)
|
||||
KAFKA_TOPIC_TARIFF - название топика для сообщений тарифа
|
||||
```
|
||||
|
||||
## Полезные ссылки:
|
||||
|
@ -1,26 +1,3 @@
|
||||
# HTTP settings
|
||||
HTTP_HOST=0.0.0.0
|
||||
HTTP_PORT=8080
|
||||
|
||||
# MONGO settings
|
||||
MONGO_HOST=localhost
|
||||
MONGO_PORT=27017
|
||||
MONGO_USER=test
|
||||
MONGO_PASSWORD=test
|
||||
MONGO_AUTH=admin
|
||||
MONGO_DB_NAME=admin
|
||||
|
||||
# Auth Microservice settings
|
||||
AUTH_MICROSERVICE_USER_URL=http://localhost:8000/user
|
||||
|
||||
# Hub Admin Microservice settings
|
||||
HUBADMIN_MICROSERVICE_TARIFF_URL=http://localhost:8001/tariff
|
||||
|
||||
# Currency Microservice settings
|
||||
CURRENCY_MICROSERVICE_TRANSLATE_URL=http://localhost:8002/change
|
||||
|
||||
# Admin
|
||||
|
||||
# JWT settings
|
||||
JWT_ISSUER="pena-auth-service"
|
||||
JWT_AUDIENCE="pena"
|
||||
|
@ -25,6 +25,9 @@ services:
|
||||
- MONGO_DB_NAME=admin
|
||||
- MONGO_AUTH=admin
|
||||
|
||||
- KAFKA_BROKERS=localhost:8080,localhost:1111
|
||||
- KAFKA_TOPIC_TARIFF=tariff
|
||||
|
||||
- JWT_ISSUER=pena-auth-service
|
||||
- JWT_AUDIENCE=pena
|
||||
|
||||
|
@ -21,6 +21,9 @@ services:
|
||||
- MONGO_DB_NAME=customer
|
||||
- MONGO_AUTH=customer
|
||||
|
||||
- KAFKA_BROKERS=10.6.0.11:9092
|
||||
- KAFKA_TOPIC_TARIFF=tariffs
|
||||
|
||||
- AUTH_MICROSERVICE_USER_URL=https://admin.pena.digital/user
|
||||
- HUBADMIN_MICROSERVICE_TARIFF_URL=https://admin.pena.digital/strator/tariff
|
||||
- CURRENCY_MICROSERVICE_TRANSLATE_URL=http://10.6.0.11:3131/change
|
||||
|
4
go.mod
4
go.mod
@ -12,6 +12,8 @@ require (
|
||||
github.com/labstack/echo/v4 v4.10.2
|
||||
github.com/sethvargo/go-envconfig v0.9.0
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/twmb/franz-go v1.13.6
|
||||
github.com/twmb/franz-go/pkg/kadm v1.8.1
|
||||
go.mongodb.org/mongo-driver v1.11.4
|
||||
go.uber.org/zap v1.24.0
|
||||
google.golang.org/genproto v0.0.0-20230223222841-637eb2293923
|
||||
@ -42,8 +44,10 @@ require (
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.4 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.17 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/twmb/franz-go/pkg/kmsg v1.4.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
|
8
go.sum
8
go.sum
@ -106,6 +106,8 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJ
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/perimeterx/marshmallow v1.1.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw=
|
||||
github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
|
||||
github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
|
||||
github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@ -135,6 +137,12 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/twmb/franz-go v1.13.6 h1:DRh06Hy3GthZuA+fQhDo+IMV+QUZHQfS2TIiWf/rCw8=
|
||||
github.com/twmb/franz-go v1.13.6/go.mod h1:jm/FtYxmhxDTN0gNSb26XaJY0irdSVcsckLiR5tQNMk=
|
||||
github.com/twmb/franz-go/pkg/kadm v1.8.1 h1:SrzL855I7gQTGdMtOYGTHhebs7TPgPN29FPtjusqwlE=
|
||||
github.com/twmb/franz-go/pkg/kadm v1.8.1/go.mod h1:qUSM7pxoMCU1UNu5H4USE64ODcVmeG9LS96mysv1nu8=
|
||||
github.com/twmb/franz-go/pkg/kmsg v1.4.0 h1:tbp9hxU6m8qZhQTlpGiaIJOm4BXix5lsuEZ7K00dF0s=
|
||||
github.com/twmb/franz-go/pkg/kmsg v1.4.0/go.mod h1:SxG/xJKhgPu25SamAq0rrucfp7lbzCpEXOC+vH/ELrY=
|
||||
github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo=
|
||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/twmb/franz-go/pkg/kgo"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/initialize"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/swagger"
|
||||
@ -15,6 +16,7 @@ import (
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/server"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/closer"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/kafka"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/mongo"
|
||||
)
|
||||
|
||||
@ -30,10 +32,16 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
|
||||
}
|
||||
}()
|
||||
|
||||
closer := closer.New()
|
||||
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer cancel()
|
||||
|
||||
closer := closer.New()
|
||||
if err := kafka.Initialize(ctx, config.Service.Kafka.Brokers, []string{
|
||||
config.Service.Kafka.Tariff.Topic,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mongoDB, err := mongo.Connect(ctx, &mongo.ConnectDeps{
|
||||
Configuration: &config.Database,
|
||||
@ -43,6 +51,21 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
|
||||
return fmt.Errorf("failed connection to db: %w", err)
|
||||
}
|
||||
|
||||
kafkaTariffClient, err := kgo.NewClient(
|
||||
kgo.SeedBrokers(config.Service.Kafka.Brokers...),
|
||||
kgo.ConsumeResetOffset(kgo.NewOffset().AtStart()),
|
||||
kgo.DefaultProduceTopic(config.Service.Kafka.Tariff.Topic),
|
||||
kgo.ConsumeTopics(config.Service.Kafka.Tariff.Topic),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
brokers := initialize.NewBrokers(initialize.BrokersDeps{
|
||||
Logger: logger,
|
||||
TariffClient: kafkaTariffClient,
|
||||
})
|
||||
|
||||
clients := initialize.NewClients(initialize.ClientsDeps{
|
||||
Logger: logger,
|
||||
AuthURL: &config.Service.AuthMicroservice.URL,
|
||||
@ -62,6 +85,7 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
|
||||
Repositories: repositories,
|
||||
Clients: clients,
|
||||
ConfigurationGRPC: &config.GRPC,
|
||||
Brokers: brokers,
|
||||
})
|
||||
|
||||
controllers := initialize.NewControllers(initialize.ControllersDeps{
|
||||
@ -99,6 +123,7 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
|
||||
closer.Add(mongoDB.Client().Disconnect)
|
||||
closer.Add(serverHTTP.Stop)
|
||||
closer.Add(serverGRPC.Stop)
|
||||
closer.Add(closer.Wrap(kafkaTariffClient.Close))
|
||||
|
||||
<-ctx.Done()
|
||||
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/twmb/franz-go/pkg/kgo"
|
||||
"go.mongodb.org/mongo-driver/mongo/integration/mtest"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/initialize"
|
||||
@ -31,11 +32,17 @@ func TestNewAPI(t *testing.T) {
|
||||
PaymentServiceConfiguration: &models.PaymentMicroserviceConfiguration{HostGRPC: "host"},
|
||||
})
|
||||
|
||||
brokers := initialize.NewBrokers(initialize.BrokersDeps{
|
||||
Logger: logger,
|
||||
TariffClient: &kgo.Client{},
|
||||
})
|
||||
|
||||
services := initialize.NewServices(initialize.ServicesDeps{
|
||||
Logger: logger,
|
||||
Repositories: repositories,
|
||||
Clients: clients,
|
||||
ConfigurationGRPC: &models.ConfigurationGRPC{Domen: "domen"},
|
||||
Brokers: brokers,
|
||||
})
|
||||
|
||||
controllers := initialize.NewControllers(initialize.ControllersDeps{
|
||||
|
30
internal/initialize/brokers.go
Normal file
30
internal/initialize/brokers.go
Normal file
@ -0,0 +1,30 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"github.com/twmb/franz-go/pkg/kgo"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/broker/tariff"
|
||||
)
|
||||
|
||||
type BrokersDeps struct {
|
||||
Logger *zap.Logger
|
||||
TariffClient *kgo.Client
|
||||
}
|
||||
|
||||
type Brokers struct {
|
||||
TariffConsumer *tariff.Consumer
|
||||
TariffProducer *tariff.Producer
|
||||
}
|
||||
|
||||
func NewBrokers(deps BrokersDeps) *Brokers {
|
||||
return &Brokers{
|
||||
TariffConsumer: tariff.NewConsumer(tariff.ConsumerDeps{
|
||||
Logger: deps.Logger,
|
||||
Client: deps.TariffClient,
|
||||
}),
|
||||
TariffProducer: tariff.NewProducer(tariff.ProducerDeps{
|
||||
Logger: deps.Logger,
|
||||
Client: deps.TariffClient,
|
||||
}),
|
||||
}
|
||||
}
|
27
internal/initialize/brokers_test.go
Normal file
27
internal/initialize/brokers_test.go
Normal file
@ -0,0 +1,27 @@
|
||||
package initialize_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/twmb/franz-go/pkg/kgo"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/initialize"
|
||||
)
|
||||
|
||||
func TestNewBrokers(t *testing.T) {
|
||||
t.Run("Брокеры должны успешно инициализироваться", func(t *testing.T) {
|
||||
logger := zap.New(zap.L().Core())
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
brokers := initialize.NewBrokers(initialize.BrokersDeps{
|
||||
Logger: logger,
|
||||
TariffClient: &kgo.Client{},
|
||||
})
|
||||
|
||||
assert.NotNil(t, brokers)
|
||||
assert.NotNil(t, brokers.TariffConsumer)
|
||||
assert.NotNil(t, brokers.TariffProducer)
|
||||
})
|
||||
})
|
||||
}
|
@ -9,6 +9,8 @@ import (
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/env"
|
||||
)
|
||||
|
||||
// TODO: обработать возможность читать конфиги ещё по json
|
||||
|
||||
func Configuration(path string) (*models.Config, error) {
|
||||
config, err := env.Parse[models.Config](path)
|
||||
if err != nil {
|
||||
|
@ -74,6 +74,10 @@ func setDefaultTestingENV(t *testing.T) *models.Config {
|
||||
AuthMicroservice: models.AuthMicroserviceConfiguration{
|
||||
URL: defaultAuthURL,
|
||||
},
|
||||
Kafka: models.KafkaConfiguration{
|
||||
Tariff: models.TariffKafkaConfiguration{Topic: "topic"},
|
||||
Brokers: []string{"localhost:8080", "localhost:8081"},
|
||||
},
|
||||
HubadminMicroservice: models.HubadminMicroserviceConfiguration{
|
||||
URL: defaultHubAdminURL,
|
||||
},
|
||||
@ -114,6 +118,9 @@ func setDefaultTestingENV(t *testing.T) *models.Config {
|
||||
t.Setenv("JWT_ISSUER", defaultConfiguration.Service.JWT.Issuer)
|
||||
t.Setenv("JWT_AUDIENCE", defaultConfiguration.Service.JWT.Audience)
|
||||
|
||||
t.Setenv("KAFKA_BROKERS", "localhost:8080,localhost:8081")
|
||||
t.Setenv("KAFKA_TOPIC_TARIFF", defaultConfiguration.Service.Kafka.Tariff.Topic)
|
||||
|
||||
t.Setenv("AUTH_MICROSERVICE_USER_URL", defaultConfiguration.Service.AuthMicroservice.URL.User)
|
||||
t.Setenv("HUBADMIN_MICROSERVICE_TARIFF_URL", defaultConfiguration.Service.HubadminMicroservice.URL.Tariff)
|
||||
t.Setenv("CURRENCY_MICROSERVICE_TRANSLATE_URL", defaultConfiguration.Service.CurrencyMicroservice.URL.Translate)
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/twmb/franz-go/pkg/kgo"
|
||||
"go.mongodb.org/mongo-driver/mongo/integration/mtest"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/initialize"
|
||||
@ -31,10 +32,16 @@ func TestNewControllers(t *testing.T) {
|
||||
MongoDB: t.Client.Database("test"),
|
||||
})
|
||||
|
||||
brokers := initialize.NewBrokers(initialize.BrokersDeps{
|
||||
Logger: logger,
|
||||
TariffClient: &kgo.Client{},
|
||||
})
|
||||
|
||||
services := initialize.NewServices(initialize.ServicesDeps{
|
||||
Logger: logger,
|
||||
Clients: clients,
|
||||
Repositories: repositories,
|
||||
Brokers: brokers,
|
||||
ConfigurationGRPC: &models.ConfigurationGRPC{Domen: "http://test:8080"},
|
||||
})
|
||||
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/account"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/broker/tariff"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/callback"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/cart"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/currency"
|
||||
@ -16,6 +17,7 @@ type ServicesDeps struct {
|
||||
Logger *zap.Logger
|
||||
Repositories *Repositories
|
||||
Clients *Clients
|
||||
Brokers *Brokers
|
||||
ConfigurationGRPC *models.ConfigurationGRPC
|
||||
}
|
||||
|
||||
@ -27,6 +29,7 @@ type Services struct {
|
||||
WalletService *wallet.Service
|
||||
PaymentService *payment.Service
|
||||
PaymentCallbackService *callback.PaymentCallbackService
|
||||
TariffBrokerService *tariff.Service
|
||||
}
|
||||
|
||||
func NewServices(deps ServicesDeps) *Services {
|
||||
@ -42,6 +45,12 @@ func NewServices(deps ServicesDeps) *Services {
|
||||
HistoryService: historyService,
|
||||
})
|
||||
|
||||
tariffBrokerService := tariff.New(tariff.Deps{
|
||||
Logger: deps.Logger,
|
||||
Consumer: deps.Brokers.TariffConsumer,
|
||||
Producer: deps.Brokers.TariffProducer,
|
||||
})
|
||||
|
||||
return &Services{
|
||||
WalletService: walletService,
|
||||
HistoryService: historyService,
|
||||
@ -55,12 +64,13 @@ func NewServices(deps ServicesDeps) *Services {
|
||||
Repository: deps.Repositories.CurrencyRepository,
|
||||
}),
|
||||
CartService: cart.New(cart.Deps{
|
||||
Logger: deps.Logger,
|
||||
Repository: deps.Repositories.AccountRepository,
|
||||
HubadminClient: deps.Clients.HubadminClient,
|
||||
DiscountClient: deps.Clients.DiscountClient,
|
||||
WalletService: walletService,
|
||||
HistoryService: historyService,
|
||||
Logger: deps.Logger,
|
||||
Repository: deps.Repositories.AccountRepository,
|
||||
HubadminClient: deps.Clients.HubadminClient,
|
||||
DiscountClient: deps.Clients.DiscountClient,
|
||||
WalletService: walletService,
|
||||
HistoryService: historyService,
|
||||
TariffBrokerService: tariffBrokerService,
|
||||
}),
|
||||
PaymentService: payment.New(payment.Deps{
|
||||
Logger: deps.Logger,
|
||||
@ -74,5 +84,6 @@ func NewServices(deps ServicesDeps) *Services {
|
||||
WalletService: walletService,
|
||||
HistoryService: historyService,
|
||||
}),
|
||||
TariffBrokerService: tariffBrokerService,
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/twmb/franz-go/pkg/kgo"
|
||||
"go.mongodb.org/mongo-driver/mongo/integration/mtest"
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/initialize"
|
||||
@ -26,6 +27,11 @@ func TestNewServices(t *testing.T) {
|
||||
PaymentServiceConfiguration: &models.PaymentMicroserviceConfiguration{HostGRPC: "host"},
|
||||
})
|
||||
|
||||
brokers := initialize.NewBrokers(initialize.BrokersDeps{
|
||||
Logger: logger,
|
||||
TariffClient: &kgo.Client{},
|
||||
})
|
||||
|
||||
repositories := initialize.NewRepositories(initialize.RepositoriesDeps{
|
||||
Logger: logger,
|
||||
MongoDB: t.Client.Database("test"),
|
||||
@ -35,6 +41,7 @@ func TestNewServices(t *testing.T) {
|
||||
Logger: logger,
|
||||
Clients: clients,
|
||||
Repositories: repositories,
|
||||
Brokers: brokers,
|
||||
ConfigurationGRPC: &models.ConfigurationGRPC{Domen: "http://test:8080"},
|
||||
})
|
||||
|
||||
@ -46,6 +53,7 @@ func TestNewServices(t *testing.T) {
|
||||
assert.NotNil(t, services.WalletService)
|
||||
assert.NotNil(t, services.PaymentService)
|
||||
assert.NotNil(t, services.PaymentCallbackService)
|
||||
assert.NotNil(t, services.TariffBrokerService)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
65
internal/interface/broker/tariff/consumer.go
Normal file
65
internal/interface/broker/tariff/consumer.go
Normal file
@ -0,0 +1,65 @@
|
||||
package tariff
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/twmb/franz-go/pkg/kgo"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/broker"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils/transfer"
|
||||
)
|
||||
|
||||
type ConsumerDeps struct {
|
||||
Logger *zap.Logger
|
||||
Client *kgo.Client
|
||||
}
|
||||
|
||||
type Consumer struct {
|
||||
logger *zap.Logger
|
||||
client *kgo.Client
|
||||
}
|
||||
|
||||
func NewConsumer(deps ConsumerDeps) *Consumer {
|
||||
if deps.Logger == nil {
|
||||
log.Panicln("logger is nil on <NewTariffConsumer>")
|
||||
}
|
||||
|
||||
if deps.Client == nil {
|
||||
log.Panicln("Kafka client is nil on <NewTariffConsumer>")
|
||||
}
|
||||
|
||||
return &Consumer{
|
||||
logger: deps.Logger,
|
||||
client: deps.Client,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *Consumer) FetchPrivileges(ctx context.Context) []models.Privilege {
|
||||
fetches := receiver.client.PollFetches(ctx)
|
||||
iter := fetches.RecordIter()
|
||||
|
||||
tariffs := make([]models.Tariff, 0)
|
||||
privileges := make([]models.Privilege, 0)
|
||||
|
||||
for !iter.Done() {
|
||||
record := iter.Next()
|
||||
tariff := broker.TariffMessage{}
|
||||
|
||||
if err := proto.Unmarshal(record.Value, &tariff); err != nil {
|
||||
receiver.logger.Error(fmt.Sprintf("error decoding message: %v\n", err))
|
||||
continue
|
||||
}
|
||||
|
||||
tariffs = append(tariffs, *transfer.TariffMessageProtoToTariffModel(&tariff))
|
||||
}
|
||||
|
||||
for _, tariff := range tariffs {
|
||||
privileges = append(privileges, tariff.Privileges...)
|
||||
}
|
||||
|
||||
return privileges
|
||||
}
|
61
internal/interface/broker/tariff/producer.go
Normal file
61
internal/interface/broker/tariff/producer.go
Normal file
@ -0,0 +1,61 @@
|
||||
package tariff
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/twmb/franz-go/pkg/kgo"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"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/transfer"
|
||||
)
|
||||
|
||||
type ProducerDeps struct {
|
||||
Logger *zap.Logger
|
||||
Client *kgo.Client
|
||||
Topic string
|
||||
}
|
||||
|
||||
type Producer struct {
|
||||
logger *zap.Logger
|
||||
client *kgo.Client
|
||||
topic string
|
||||
}
|
||||
|
||||
func NewProducer(deps ProducerDeps) *Producer {
|
||||
if deps.Logger == nil {
|
||||
log.Panicln("logger is nil on <NewTariffProducer>")
|
||||
}
|
||||
|
||||
if deps.Client == nil {
|
||||
log.Panicln("Kafka client is nil on <NewTariffProducer>")
|
||||
}
|
||||
|
||||
return &Producer{
|
||||
logger: deps.Logger,
|
||||
client: deps.Client,
|
||||
topic: deps.Topic,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *Producer) Send(ctx context.Context, userID string, tariff *models.Tariff) errors.Error {
|
||||
bytes, err := proto.Marshal(transfer.TariffModelToProtoMessage(userID, tariff))
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to marshal tariff model on <Send> of <TariffProducer>")
|
||||
return errors.New(fmt.Errorf("failed to marshal tariff: %w", err), errors.ErrInternalError)
|
||||
}
|
||||
|
||||
responses := receiver.client.ProduceSync(ctx, &kgo.Record{Value: bytes})
|
||||
|
||||
for _, response := range responses {
|
||||
if response.Err != nil {
|
||||
receiver.logger.Error("failed to send tariff on <Send> of <TariffProducer>", zap.Error(response.Err))
|
||||
return errors.New(fmt.Errorf("failed to send tariff: %w", response.Err), errors.ErrInternalError)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -17,7 +17,7 @@ import (
|
||||
type cartService interface {
|
||||
Remove(ctx context.Context, userID, itemID string) ([]string, errors.Error)
|
||||
Add(context.Context, *models.AddItemToCart) ([]string, errors.Error)
|
||||
Pay(ctx context.Context, token, userID string) (link string, err errors.Error)
|
||||
Pay(ctx context.Context, token, userID string) errors.Error
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
@ -114,15 +114,10 @@ func (receiver *Controller) Pay(ctx echo.Context) error {
|
||||
return errors.HTTP(ctx, errors.NewWithMessage("failed to convert access token payload to string", errors.ErrInvalidArgs))
|
||||
}
|
||||
|
||||
link, err := receiver.cartService.Pay(ctx.Request().Context(), token, userID)
|
||||
if err != nil {
|
||||
if err := receiver.cartService.Pay(ctx.Request().Context(), token, userID); err != nil {
|
||||
receiver.logger.Error("failed to pay cart on <Pay> of <CartController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
if !validate.IsStringEmpty(link) {
|
||||
return ctx.Redirect(http.StatusTemporaryRedirect, link)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, true)
|
||||
}
|
||||
|
@ -32,6 +32,16 @@ type ServiceConfiguration struct {
|
||||
DiscountMicroservice DiscountMicroserviceConfiguration
|
||||
PaymentMicroservice PaymentMicroserviceConfiguration
|
||||
JWT JWTConfiguration
|
||||
Kafka KafkaConfiguration
|
||||
}
|
||||
|
||||
type KafkaConfiguration struct {
|
||||
Tariff TariffKafkaConfiguration `json:"tariff"`
|
||||
Brokers []string `json:"brokers" env:"KAFKA_BROKERS,required"`
|
||||
}
|
||||
|
||||
type TariffKafkaConfiguration struct {
|
||||
Topic string `json:"topic" env:"KAFKA_TOPIC_TARIFF,required"`
|
||||
}
|
||||
|
||||
type JWTConfiguration struct {
|
||||
|
@ -3,15 +3,15 @@ package models
|
||||
import "time"
|
||||
|
||||
type Tariff struct {
|
||||
ID string `json:"_id"`
|
||||
Name string `json:"name"`
|
||||
Price int64 `json:"price"`
|
||||
IsCustom bool `json:"isCustom"`
|
||||
Privileges map[string]Privilege `json:"privileges"`
|
||||
Deleted bool `json:"isDeleted"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
DeletedAt *time.Time `json:"deletedAt,omitempty"`
|
||||
ID string `json:"_id"`
|
||||
Name string `json:"name"`
|
||||
Price int64 `json:"price"`
|
||||
IsCustom bool `json:"isCustom"`
|
||||
Privileges []Privilege `json:"privileges"`
|
||||
Deleted bool `json:"isDeleted"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
DeletedAt *time.Time `json:"deletedAt,omitempty"`
|
||||
}
|
||||
|
||||
type Privilege struct {
|
||||
|
247
internal/proto/broker/models.pb.go
Normal file
247
internal/proto/broker/models.pb.go
Normal file
@ -0,0 +1,247 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc (unknown)
|
||||
// source: broker/models.proto
|
||||
|
||||
package broker
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type PrivilegeMessage struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
PrivilegeID string `protobuf:"bytes,1,opt,name=PrivilegeID,proto3" json:"PrivilegeID,omitempty"`
|
||||
ServiceKey string `protobuf:"bytes,2,opt,name=ServiceKey,proto3" json:"ServiceKey,omitempty"`
|
||||
Type string `protobuf:"bytes,3,opt,name=Type,proto3" json:"Type,omitempty"`
|
||||
Value string `protobuf:"bytes,4,opt,name=Value,proto3" json:"Value,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PrivilegeMessage) Reset() {
|
||||
*x = PrivilegeMessage{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_broker_models_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PrivilegeMessage) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PrivilegeMessage) ProtoMessage() {}
|
||||
|
||||
func (x *PrivilegeMessage) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_broker_models_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PrivilegeMessage.ProtoReflect.Descriptor instead.
|
||||
func (*PrivilegeMessage) Descriptor() ([]byte, []int) {
|
||||
return file_broker_models_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *PrivilegeMessage) GetPrivilegeID() string {
|
||||
if x != nil {
|
||||
return x.PrivilegeID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PrivilegeMessage) GetServiceKey() string {
|
||||
if x != nil {
|
||||
return x.ServiceKey
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PrivilegeMessage) GetType() string {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PrivilegeMessage) GetValue() string {
|
||||
if x != nil {
|
||||
return x.Value
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type TariffMessage struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Privileges []*PrivilegeMessage `protobuf:"bytes,1,rep,name=Privileges,proto3" json:"Privileges,omitempty"`
|
||||
UserID string `protobuf:"bytes,2,opt,name=UserID,proto3" json:"UserID,omitempty"`
|
||||
}
|
||||
|
||||
func (x *TariffMessage) Reset() {
|
||||
*x = TariffMessage{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_broker_models_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *TariffMessage) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*TariffMessage) ProtoMessage() {}
|
||||
|
||||
func (x *TariffMessage) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_broker_models_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use TariffMessage.ProtoReflect.Descriptor instead.
|
||||
func (*TariffMessage) Descriptor() ([]byte, []int) {
|
||||
return file_broker_models_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *TariffMessage) GetPrivileges() []*PrivilegeMessage {
|
||||
if x != nil {
|
||||
return x.Privileges
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *TariffMessage) GetUserID() string {
|
||||
if x != nil {
|
||||
return x.UserID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_broker_models_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_broker_models_proto_rawDesc = []byte{
|
||||
0x0a, 0x13, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x22, 0x7e, 0x0a,
|
||||
0x10, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
||||
0x65, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x49, 0x44,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67,
|
||||
0x65, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4b, 0x65,
|
||||
0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x4b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x61, 0x0a,
|
||||
0x0d, 0x54, 0x61, 0x72, 0x69, 0x66, 0x66, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x38,
|
||||
0x0a, 0x0a, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x69, 0x76,
|
||||
0x69, 0x6c, 0x65, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0a, 0x50, 0x72,
|
||||
0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x55, 0x73, 0x65, 0x72,
|
||||
0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x55, 0x73, 0x65, 0x72, 0x49, 0x44,
|
||||
0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_broker_models_proto_rawDescOnce sync.Once
|
||||
file_broker_models_proto_rawDescData = file_broker_models_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_broker_models_proto_rawDescGZIP() []byte {
|
||||
file_broker_models_proto_rawDescOnce.Do(func() {
|
||||
file_broker_models_proto_rawDescData = protoimpl.X.CompressGZIP(file_broker_models_proto_rawDescData)
|
||||
})
|
||||
return file_broker_models_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_broker_models_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_broker_models_proto_goTypes = []interface{}{
|
||||
(*PrivilegeMessage)(nil), // 0: broker.PrivilegeMessage
|
||||
(*TariffMessage)(nil), // 1: broker.TariffMessage
|
||||
}
|
||||
var file_broker_models_proto_depIdxs = []int32{
|
||||
0, // 0: broker.TariffMessage.Privileges:type_name -> broker.PrivilegeMessage
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_broker_models_proto_init() }
|
||||
func file_broker_models_proto_init() {
|
||||
if File_broker_models_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_broker_models_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PrivilegeMessage); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_broker_models_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*TariffMessage); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_broker_models_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_broker_models_proto_goTypes,
|
||||
DependencyIndexes: file_broker_models_proto_depIdxs,
|
||||
MessageInfos: file_broker_models_proto_msgTypes,
|
||||
}.Build()
|
||||
File_broker_models_proto = out.File
|
||||
file_broker_models_proto_rawDesc = nil
|
||||
file_broker_models_proto_goTypes = nil
|
||||
file_broker_models_proto_depIdxs = nil
|
||||
}
|
@ -83,6 +83,7 @@ type DiscountOptional struct {
|
||||
Description *string `protobuf:"bytes,4,opt,name=Description,proto3,oneof" json:"Description,omitempty"`
|
||||
Condition *DiscountCondition `protobuf:"bytes,5,opt,name=Condition,proto3,oneof" json:"Condition,omitempty"`
|
||||
Target *DiscountCalculationTarget `protobuf:"bytes,6,opt,name=Target,proto3,oneof" json:"Target,omitempty"`
|
||||
Deprecated *bool `protobuf:"varint,7,opt,name=Deprecated,proto3,oneof" json:"Deprecated,omitempty"`
|
||||
}
|
||||
|
||||
func (x *DiscountOptional) Reset() {
|
||||
@ -159,6 +160,13 @@ func (x *DiscountOptional) GetTarget() *DiscountCalculationTarget {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *DiscountOptional) GetDeprecated() bool {
|
||||
if x != nil && x.Deprecated != nil {
|
||||
return *x.Deprecated
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type Discounts struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@ -397,12 +405,12 @@ type DiscountCondition struct {
|
||||
User *string `protobuf:"bytes,2,opt,name=User,proto3,oneof" json:"User,omitempty"`
|
||||
UserType *string `protobuf:"bytes,3,opt,name=UserType,proto3,oneof" json:"UserType,omitempty"`
|
||||
Coupon *string `protobuf:"bytes,4,opt,name=Coupon,proto3,oneof" json:"Coupon,omitempty"`
|
||||
PurchasesAmount *float64 `protobuf:"fixed64,5,opt,name=PurchasesAmount,proto3,oneof" json:"PurchasesAmount,omitempty"`
|
||||
CartPurchasesAmount *float64 `protobuf:"fixed64,6,opt,name=CartPurchasesAmount,proto3,oneof" json:"CartPurchasesAmount,omitempty"`
|
||||
PurchasesAmount *uint64 `protobuf:"varint,5,opt,name=PurchasesAmount,proto3,oneof" json:"PurchasesAmount,omitempty"`
|
||||
CartPurchasesAmount *uint64 `protobuf:"varint,6,opt,name=CartPurchasesAmount,proto3,oneof" json:"CartPurchasesAmount,omitempty"`
|
||||
Product *string `protobuf:"bytes,7,opt,name=Product,proto3,oneof" json:"Product,omitempty"`
|
||||
Term *uint64 `protobuf:"varint,8,opt,name=Term,proto3,oneof" json:"Term,omitempty"`
|
||||
Usage *uint64 `protobuf:"varint,9,opt,name=Usage,proto3,oneof" json:"Usage,omitempty"`
|
||||
PriceFrom *float64 `protobuf:"fixed64,10,opt,name=PriceFrom,proto3,oneof" json:"PriceFrom,omitempty"`
|
||||
PriceFrom *uint64 `protobuf:"varint,10,opt,name=PriceFrom,proto3,oneof" json:"PriceFrom,omitempty"`
|
||||
Group *string `protobuf:"bytes,11,opt,name=Group,proto3,oneof" json:"Group,omitempty"`
|
||||
}
|
||||
|
||||
@ -466,14 +474,14 @@ func (x *DiscountCondition) GetCoupon() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *DiscountCondition) GetPurchasesAmount() float64 {
|
||||
func (x *DiscountCondition) GetPurchasesAmount() uint64 {
|
||||
if x != nil && x.PurchasesAmount != nil {
|
||||
return *x.PurchasesAmount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *DiscountCondition) GetCartPurchasesAmount() float64 {
|
||||
func (x *DiscountCondition) GetCartPurchasesAmount() uint64 {
|
||||
if x != nil && x.CartPurchasesAmount != nil {
|
||||
return *x.CartPurchasesAmount
|
||||
}
|
||||
@ -501,7 +509,7 @@ func (x *DiscountCondition) GetUsage() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *DiscountCondition) GetPriceFrom() float64 {
|
||||
func (x *DiscountCondition) GetPriceFrom() uint64 {
|
||||
if x != nil && x.PriceFrom != nil {
|
||||
return *x.PriceFrom
|
||||
}
|
||||
@ -638,10 +646,10 @@ type UserInformation struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
Type string `protobuf:"bytes,2,opt,name=Type,proto3" json:"Type,omitempty"`
|
||||
PurchasesAmount float64 `protobuf:"fixed64,3,opt,name=PurchasesAmount,proto3" json:"PurchasesAmount,omitempty"`
|
||||
CartPurchasesAmount float64 `protobuf:"fixed64,4,opt,name=CartPurchasesAmount,proto3" json:"CartPurchasesAmount,omitempty"`
|
||||
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
Type string `protobuf:"bytes,2,opt,name=Type,proto3" json:"Type,omitempty"`
|
||||
PurchasesAmount uint64 `protobuf:"varint,3,opt,name=PurchasesAmount,proto3" json:"PurchasesAmount,omitempty"`
|
||||
CartPurchasesAmount uint64 `protobuf:"varint,4,opt,name=CartPurchasesAmount,proto3" json:"CartPurchasesAmount,omitempty"`
|
||||
}
|
||||
|
||||
func (x *UserInformation) Reset() {
|
||||
@ -690,14 +698,14 @@ func (x *UserInformation) GetType() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *UserInformation) GetPurchasesAmount() float64 {
|
||||
func (x *UserInformation) GetPurchasesAmount() uint64 {
|
||||
if x != nil {
|
||||
return x.PurchasesAmount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *UserInformation) GetCartPurchasesAmount() float64 {
|
||||
func (x *UserInformation) GetCartPurchasesAmount() uint64 {
|
||||
if x != nil {
|
||||
return x.CartPurchasesAmount
|
||||
}
|
||||
@ -710,7 +718,7 @@ type ProductInformation struct {
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
Price float64 `protobuf:"fixed64,2,opt,name=Price,proto3" json:"Price,omitempty"`
|
||||
Price uint64 `protobuf:"varint,2,opt,name=Price,proto3" json:"Price,omitempty"`
|
||||
Term *uint64 `protobuf:"varint,3,opt,name=Term,proto3,oneof" json:"Term,omitempty"`
|
||||
Usage *uint64 `protobuf:"varint,4,opt,name=Usage,proto3,oneof" json:"Usage,omitempty"`
|
||||
Group *string `protobuf:"bytes,5,opt,name=Group,proto3,oneof" json:"Group,omitempty"`
|
||||
@ -755,7 +763,7 @@ func (x *ProductInformation) GetID() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ProductInformation) GetPrice() float64 {
|
||||
func (x *ProductInformation) GetPrice() uint64 {
|
||||
if x != nil {
|
||||
return x.Price
|
||||
}
|
||||
@ -796,7 +804,7 @@ var file_discount_discount_model_proto_rawDesc = []byte{
|
||||
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1a, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f,
|
||||
0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x22, 0xbb, 0x02, 0x0a, 0x10, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x70,
|
||||
0x6f, 0x22, 0xef, 0x02, 0x0a, 0x10, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x70,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x17, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12,
|
||||
@ -812,123 +820,126 @@ var file_discount_discount_model_proto_rawDesc = []byte{
|
||||
0x0b, 0x32, 0x23, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x48, 0x04, 0x52, 0x06, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74,
|
||||
0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x08, 0x0a, 0x06,
|
||||
0x5f, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x44, 0x65, 0x73, 0x63, 0x72,
|
||||
0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x43, 0x6f, 0x6e, 0x64, 0x69,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22,
|
||||
0x3d, 0x0a, 0x09, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x09,
|
||||
0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x12, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x52, 0x09, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0xa5,
|
||||
0x02, 0x0a, 0x08, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49,
|
||||
0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e,
|
||||
0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05,
|
||||
0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63,
|
||||
0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x64, 0x69,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x64, 0x69, 0x73,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f,
|
||||
0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x06, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69,
|
||||
0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12,
|
||||
0x25, 0x0a, 0x05, 0x41, 0x75, 0x64, 0x69, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f,
|
||||
0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x52,
|
||||
0x05, 0x41, 0x75, 0x64, 0x69, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63,
|
||||
0x61, 0x74, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x44, 0x65, 0x70, 0x72,
|
||||
0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x22, 0x9b, 0x02, 0x0a, 0x19, 0x44, 0x69, 0x73, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61,
|
||||
0x72, 0x67, 0x65, 0x74, 0x12, 0x33, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73,
|
||||
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52,
|
||||
0x08, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x46, 0x61, 0x63,
|
||||
0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x46, 0x61, 0x63, 0x74, 0x6f,
|
||||
0x72, 0x12, 0x3c, 0x0a, 0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x48, 0x00, 0x52,
|
||||
0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x88, 0x01, 0x01, 0x12,
|
||||
0x25, 0x0a, 0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x72,
|
||||
0x6f, 0x75, 0x70, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x4f, 0x76, 0x65, 0x72, 0x68, 0x65,
|
||||
0x6c, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x48, 0x02, 0x52, 0x08, 0x4f, 0x76, 0x65, 0x72,
|
||||
0x68, 0x65, 0x6c, 0x6d, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x54, 0x61, 0x72, 0x67,
|
||||
0x65, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x54, 0x61, 0x72, 0x67,
|
||||
0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x4f, 0x76, 0x65, 0x72,
|
||||
0x68, 0x65, 0x6c, 0x6d, 0x22, 0xa8, 0x04, 0x0a, 0x11, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x06, 0x50, 0x65,
|
||||
0x72, 0x69, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x64, 0x69, 0x73,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x43, 0x6f, 0x6e, 0x64,
|
||||
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x06, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x88,
|
||||
0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x48, 0x01, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x55,
|
||||
0x73, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52,
|
||||
0x08, 0x55, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06,
|
||||
0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x06,
|
||||
0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x2d, 0x0a, 0x0f, 0x50, 0x75, 0x72,
|
||||
0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x01, 0x48, 0x04, 0x52, 0x0f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41,
|
||||
0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x35, 0x0a, 0x13, 0x43, 0x61, 0x72, 0x74,
|
||||
0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x01, 0x48, 0x05, 0x52, 0x13, 0x43, 0x61, 0x72, 0x74, 0x50, 0x75, 0x72,
|
||||
0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12,
|
||||
0x1d, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
|
||||
0x48, 0x06, 0x52, 0x07, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x88, 0x01, 0x01, 0x12, 0x17,
|
||||
0x0a, 0x04, 0x54, 0x65, 0x72, 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x48, 0x07, 0x52, 0x04,
|
||||
0x54, 0x65, 0x72, 0x6d, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x55, 0x73, 0x61, 0x67, 0x65,
|
||||
0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x48, 0x08, 0x52, 0x05, 0x55, 0x73, 0x61, 0x67, 0x65, 0x88,
|
||||
0x01, 0x01, 0x12, 0x21, 0x0a, 0x09, 0x50, 0x72, 0x69, 0x63, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x18,
|
||||
0x0a, 0x20, 0x01, 0x28, 0x01, 0x48, 0x09, 0x52, 0x09, 0x50, 0x72, 0x69, 0x63, 0x65, 0x46, 0x72,
|
||||
0x6f, 0x6d, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x0b,
|
||||
0x20, 0x01, 0x28, 0x09, 0x48, 0x0a, 0x52, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x88, 0x01, 0x01,
|
||||
0x42, 0x09, 0x0a, 0x07, 0x5f, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x5f,
|
||||
0x55, 0x73, 0x65, 0x72, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x55, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70,
|
||||
0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x42, 0x12, 0x0a, 0x10,
|
||||
0x5f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x42, 0x16, 0x0a, 0x14, 0x5f, 0x43, 0x61, 0x72, 0x74, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73,
|
||||
0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x50, 0x72, 0x6f,
|
||||
0x64, 0x75, 0x63, 0x74, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x54, 0x65, 0x72, 0x6d, 0x42, 0x08, 0x0a,
|
||||
0x06, 0x5f, 0x55, 0x73, 0x61, 0x67, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x50, 0x72, 0x69, 0x63,
|
||||
0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22,
|
||||
0x65, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74,
|
||||
0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44,
|
||||
0x12, 0x16, 0x0a, 0x06, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01,
|
||||
0x52, 0x06, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x08, 0x4f, 0x76, 0x65, 0x72,
|
||||
0x68, 0x65, 0x6c, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, 0x4f, 0x76,
|
||||
0x65, 0x72, 0x68, 0x65, 0x6c, 0x6d, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x4f, 0x76,
|
||||
0x65, 0x72, 0x68, 0x65, 0x6c, 0x6d, 0x22, 0x6d, 0x0a, 0x0f, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64,
|
||||
0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x04, 0x46, 0x72, 0x6f,
|
||||
0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
|
||||
0x61, 0x6d, 0x70, 0x52, 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x2a, 0x0a, 0x02, 0x54, 0x6f, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
|
||||
0x70, 0x52, 0x02, 0x54, 0x6f, 0x22, 0x91, 0x01, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e,
|
||||
0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a,
|
||||
0x88, 0x01, 0x01, 0x12, 0x23, 0x0a, 0x0a, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65,
|
||||
0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x48, 0x05, 0x52, 0x0a, 0x44, 0x65, 0x70, 0x72, 0x65,
|
||||
0x63, 0x61, 0x74, 0x65, 0x64, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x4e, 0x61, 0x6d,
|
||||
0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x42, 0x0e, 0x0a, 0x0c, 0x5f,
|
||||
0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0c, 0x0a, 0x0a, 0x5f,
|
||||
0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x54, 0x61,
|
||||
0x72, 0x67, 0x65, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61,
|
||||
0x74, 0x65, 0x64, 0x22, 0x3d, 0x0a, 0x09, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73,
|
||||
0x12, 0x30, 0x0a, 0x09, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44,
|
||||
0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x09, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x73, 0x22, 0xa5, 0x02, 0x0a, 0x08, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12,
|
||||
0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e,
|
||||
0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x0d, 0x52, 0x05, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73,
|
||||
0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
|
||||
0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x09, 0x43,
|
||||
0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b,
|
||||
0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x43, 0x6f, 0x6e,
|
||||
0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x06, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x54, 0x61, 0x72,
|
||||
0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x05, 0x41, 0x75, 0x64, 0x69, 0x74, 0x18, 0x07, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x41, 0x75,
|
||||
0x64, 0x69, 0x74, 0x52, 0x05, 0x41, 0x75, 0x64, 0x69, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x44, 0x65,
|
||||
0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a,
|
||||
0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x22, 0x9b, 0x02, 0x0a, 0x19, 0x44,
|
||||
0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x33, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x64,
|
||||
0x75, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x64, 0x69, 0x73,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x54, 0x61, 0x72,
|
||||
0x67, 0x65, 0x74, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x12, 0x16, 0x0a,
|
||||
0x06, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x46,
|
||||
0x61, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x3c, 0x0a, 0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53,
|
||||
0x63, 0x6f, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x64, 0x69, 0x73,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x63, 0x6f, 0x70,
|
||||
0x65, 0x48, 0x00, 0x52, 0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65,
|
||||
0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x72, 0x6f,
|
||||
0x75, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0b, 0x54, 0x61, 0x72, 0x67,
|
||||
0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x4f, 0x76,
|
||||
0x65, 0x72, 0x68, 0x65, 0x6c, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x48, 0x02, 0x52, 0x08,
|
||||
0x4f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x6c, 0x6d, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f,
|
||||
0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x42, 0x0e, 0x0a, 0x0c, 0x5f,
|
||||
0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x42, 0x0b, 0x0a, 0x09, 0x5f,
|
||||
0x4f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x6c, 0x6d, 0x22, 0xa8, 0x04, 0x0a, 0x11, 0x44, 0x69, 0x73,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36,
|
||||
0x0a, 0x06, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
|
||||
0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64,
|
||||
0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x06, 0x50, 0x65, 0x72,
|
||||
0x69, 0x6f, 0x64, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12,
|
||||
0x1f, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x09, 0x48, 0x02, 0x52, 0x08, 0x55, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x88, 0x01, 0x01,
|
||||
0x12, 0x1b, 0x0a, 0x06, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
|
||||
0x48, 0x03, 0x52, 0x06, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x2d, 0x0a,
|
||||
0x0f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65,
|
||||
0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x13, 0x43, 0x61, 0x72, 0x74, 0x50,
|
||||
0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x01, 0x52, 0x13, 0x43, 0x61, 0x72, 0x74, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61,
|
||||
0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xa6, 0x01, 0x0a, 0x12, 0x50, 0x72,
|
||||
0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52,
|
||||
0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x17, 0x0a, 0x04, 0x54, 0x65, 0x72, 0x6d, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x04, 0x54, 0x65, 0x72, 0x6d, 0x88, 0x01, 0x01, 0x12,
|
||||
0x19, 0x0a, 0x05, 0x55, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x01,
|
||||
0x52, 0x05, 0x55, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x47, 0x72,
|
||||
0x6f, 0x75, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x05, 0x47, 0x72, 0x6f,
|
||||
0x75, 0x70, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x54, 0x65, 0x72, 0x6d, 0x42, 0x08,
|
||||
0x0a, 0x06, 0x5f, 0x55, 0x73, 0x61, 0x67, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x47, 0x72, 0x6f,
|
||||
0x75, 0x70, 0x2a, 0x2b, 0x0a, 0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x63, 0x6f, 0x70,
|
||||
0x65, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x75, 0x6d, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x72,
|
||||
0x6f, 0x75, 0x70, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x61, 0x63, 0x68, 0x10, 0x02, 0x42,
|
||||
0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x48, 0x04, 0x52, 0x0f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61,
|
||||
0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x35, 0x0a, 0x13,
|
||||
0x43, 0x61, 0x72, 0x74, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x48, 0x05, 0x52, 0x13, 0x43, 0x61, 0x72,
|
||||
0x74, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x18, 0x07,
|
||||
0x20, 0x01, 0x28, 0x09, 0x48, 0x06, 0x52, 0x07, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x88,
|
||||
0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x54, 0x65, 0x72, 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04,
|
||||
0x48, 0x07, 0x52, 0x04, 0x54, 0x65, 0x72, 0x6d, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x55,
|
||||
0x73, 0x61, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x48, 0x08, 0x52, 0x05, 0x55, 0x73,
|
||||
0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x21, 0x0a, 0x09, 0x50, 0x72, 0x69, 0x63, 0x65, 0x46,
|
||||
0x72, 0x6f, 0x6d, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x48, 0x09, 0x52, 0x09, 0x50, 0x72, 0x69,
|
||||
0x63, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x47, 0x72, 0x6f,
|
||||
0x75, 0x70, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x48, 0x0a, 0x52, 0x05, 0x47, 0x72, 0x6f, 0x75,
|
||||
0x70, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x42,
|
||||
0x07, 0x0a, 0x05, 0x5f, 0x55, 0x73, 0x65, 0x72, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x55, 0x73, 0x65,
|
||||
0x72, 0x54, 0x79, 0x70, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e,
|
||||
0x42, 0x12, 0x0a, 0x10, 0x5f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x43, 0x61, 0x72, 0x74, 0x50, 0x75, 0x72,
|
||||
0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x0a, 0x0a, 0x08,
|
||||
0x5f, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x54, 0x65, 0x72,
|
||||
0x6d, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x55, 0x73, 0x61, 0x67, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x5f,
|
||||
0x50, 0x72, 0x69, 0x63, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x47, 0x72,
|
||||
0x6f, 0x75, 0x70, 0x22, 0x65, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x54, 0x61,
|
||||
0x72, 0x67, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x02, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1f, 0x0a, 0x08,
|
||||
0x4f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x6c, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00,
|
||||
0x52, 0x08, 0x4f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x6c, 0x6d, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a,
|
||||
0x09, 0x5f, 0x4f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x6c, 0x6d, 0x22, 0x6d, 0x0a, 0x0f, 0x50, 0x65,
|
||||
0x72, 0x69, 0x6f, 0x64, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a,
|
||||
0x04, 0x46, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x2a, 0x0a,
|
||||
0x02, 0x54, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x02, 0x54, 0x6f, 0x22, 0x91, 0x01, 0x0a, 0x0f, 0x55, 0x73,
|
||||
0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a,
|
||||
0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70,
|
||||
0x65, 0x12, 0x28, 0x0a, 0x0f, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x50, 0x75, 0x72, 0x63,
|
||||
0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x13, 0x43,
|
||||
0x61, 0x72, 0x74, 0x50, 0x75, 0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x43, 0x61, 0x72, 0x74, 0x50, 0x75,
|
||||
0x72, 0x63, 0x68, 0x61, 0x73, 0x65, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xa6, 0x01,
|
||||
0x0a, 0x12, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x02, 0x49, 0x44, 0x12, 0x14, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x04, 0x52, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x17, 0x0a, 0x04, 0x54, 0x65,
|
||||
0x72, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x04, 0x54, 0x65, 0x72, 0x6d,
|
||||
0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x55, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x04, 0x48, 0x01, 0x52, 0x05, 0x55, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x19,
|
||||
0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52,
|
||||
0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x54, 0x65,
|
||||
0x72, 0x6d, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x55, 0x73, 0x61, 0x67, 0x65, 0x42, 0x08, 0x0a, 0x06,
|
||||
0x5f, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2a, 0x2b, 0x0a, 0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74,
|
||||
0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x75, 0x6d, 0x10, 0x00, 0x12, 0x09,
|
||||
0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x61, 0x63,
|
||||
0x68, 0x10, 0x02, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -146,7 +146,7 @@ type ApplyDiscountResponse struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Price float64 `protobuf:"fixed64,1,opt,name=Price,proto3" json:"Price,omitempty"`
|
||||
Price uint64 `protobuf:"varint,1,opt,name=Price,proto3" json:"Price,omitempty"`
|
||||
AppliedDiscounts []*Discount `protobuf:"bytes,2,rep,name=AppliedDiscounts,proto3" json:"AppliedDiscounts,omitempty"`
|
||||
}
|
||||
|
||||
@ -182,7 +182,7 @@ func (*ApplyDiscountResponse) Descriptor() ([]byte, []int) {
|
||||
return file_discount_service_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *ApplyDiscountResponse) GetPrice() float64 {
|
||||
func (x *ApplyDiscountResponse) GetPrice() uint64 {
|
||||
if x != nil {
|
||||
return x.Price
|
||||
}
|
||||
@ -307,7 +307,7 @@ var file_discount_service_proto_rawDesc = []byte{
|
||||
0x00, 0x52, 0x06, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07,
|
||||
0x5f, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x22, 0x6d, 0x0a, 0x15, 0x41, 0x70, 0x70, 0x6c, 0x79,
|
||||
0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52,
|
||||
0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x3e, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x65,
|
||||
0x64, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x12, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63,
|
||||
@ -327,44 +327,44 @@ var file_discount_service_proto_rawDesc = []byte{
|
||||
0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x63, 0x75,
|
||||
0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x54, 0x61,
|
||||
0x72, 0x67, 0x65, 0x74, 0x32, 0x80, 0x07, 0x0a, 0x0f, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x41,
|
||||
0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x52, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x41,
|
||||
0x6c, 0x6c, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
|
||||
0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44,
|
||||
0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f,
|
||||
0x12, 0x0d, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x61, 0x6c, 0x6c, 0x12,
|
||||
0x66, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x73, 0x12, 0x20, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x47,
|
||||
0x65, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x15, 0x12, 0x13, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x75, 0x73,
|
||||
0x65, 0x72, 0x2f, 0x7b, 0x49, 0x44, 0x7d, 0x12, 0x69, 0x0a, 0x12, 0x44, 0x65, 0x74, 0x65, 0x72,
|
||||
0x6d, 0x69, 0x6e, 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x1e, 0x2e,
|
||||
0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x44, 0x69,
|
||||
0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e,
|
||||
0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x73, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f,
|
||||
0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69,
|
||||
0x6e, 0x65, 0x12, 0x6d, 0x0a, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x44, 0x69, 0x73, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x73, 0x12, 0x1e, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e,
|
||||
0x41, 0x70, 0x70, 0x6c, 0x79, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e,
|
||||
0x41, 0x70, 0x70, 0x6c, 0x79, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x3a, 0x01, 0x2a,
|
||||
0x22, 0x0f, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x61, 0x70, 0x70, 0x6c,
|
||||
0x79, 0x12, 0x5f, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x42, 0x79, 0x49, 0x44, 0x12, 0x20, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e,
|
||||
0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x44, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x10, 0x12, 0x0e, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x7b, 0x49,
|
||||
0x44, 0x7d, 0x12, 0x58, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x63,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e,
|
||||
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x11, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
||||
0x0b, 0x22, 0x09, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x5c, 0x0a, 0x0f,
|
||||
0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c,
|
||||
0x12, 0x0a, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x66, 0x0a, 0x10,
|
||||
0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73,
|
||||
0x12, 0x20, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x44,
|
||||
0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x13, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69,
|
||||
0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12,
|
||||
0x13, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f,
|
||||
0x7b, 0x49, 0x44, 0x7d, 0x12, 0x69, 0x0a, 0x12, 0x44, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e,
|
||||
0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x1e, 0x2e, 0x64, 0x69, 0x73,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x44, 0x69, 0x73, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x64, 0x69, 0x73,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22,
|
||||
0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x64, 0x69, 0x73,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x12,
|
||||
0x6d, 0x0a, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x73, 0x12, 0x1e, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x41, 0x70, 0x70,
|
||||
0x6c, 0x79, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x1f, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x41, 0x70, 0x70,
|
||||
0x6c, 0x79, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x3a, 0x01, 0x2a, 0x22, 0x0f, 0x2f,
|
||||
0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x12, 0x5f,
|
||||
0x0a, 0x0f, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x79, 0x49,
|
||||
0x44, 0x12, 0x20, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44,
|
||||
0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12,
|
||||
0x0e, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x7b, 0x49, 0x44, 0x7d, 0x12,
|
||||
0x5b, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x12, 0x1f, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x43, 0x72, 0x65,
|
||||
0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69,
|
||||
0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x3a, 0x01,
|
||||
0x2a, 0x22, 0x09, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x5c, 0x0a, 0x0f,
|
||||
0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12,
|
||||
0x1a, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x1a, 0x12, 0x2e, 0x64, 0x69,
|
||||
|
90
internal/service/broker/tariff/tariff.go
Normal file
90
internal/service/broker/tariff/tariff.go
Normal file
@ -0,0 +1,90 @@
|
||||
package tariff
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"sync"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
)
|
||||
|
||||
type consumer interface {
|
||||
FetchPrivileges(context.Context) []models.Privilege
|
||||
}
|
||||
|
||||
type producer interface {
|
||||
Send(ctx context.Context, userID string, tariff *models.Tariff) errors.Error
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
Consumer consumer
|
||||
Producer producer
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
logger *zap.Logger
|
||||
consumer consumer
|
||||
producer producer
|
||||
}
|
||||
|
||||
func New(deps Deps) *Service {
|
||||
if deps.Logger == nil {
|
||||
log.Panicln("logger is nil on <NewTariffBrokerService>")
|
||||
}
|
||||
|
||||
if deps.Consumer == nil {
|
||||
log.Panicln("Consumer is nil on <NewTariffBrokerService>")
|
||||
}
|
||||
|
||||
if deps.Producer == nil {
|
||||
log.Panicln("Producer is nil on <NewTariffBrokerService>")
|
||||
}
|
||||
|
||||
return &Service{
|
||||
logger: deps.Logger,
|
||||
consumer: deps.Consumer,
|
||||
producer: deps.Producer,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *Service) Send(ctx context.Context, userID string, tariff *models.Tariff) errors.Error {
|
||||
if tariff == nil {
|
||||
receiver.logger.Error("tarif is nil on <Send> of <TariffBrokerService>")
|
||||
return errors.NewWithMessage("tariff is nil", errors.ErrInvalidArgs)
|
||||
}
|
||||
|
||||
if err := receiver.producer.Send(ctx, userID, tariff); err != nil {
|
||||
receiver.logger.Error("failed to send tariff on <Send> of <TariffBrokerService>", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *Service) SendMany(ctx context.Context, userID string, tariffs []models.Tariff) []errors.Error {
|
||||
sendErrors := make([]errors.Error, 0)
|
||||
waitGroup := sync.WaitGroup{}
|
||||
|
||||
for _, tariff := range tariffs {
|
||||
waitGroup.Add(1)
|
||||
|
||||
go func(currentTariff models.Tariff) {
|
||||
defer waitGroup.Done()
|
||||
|
||||
if err := receiver.Send(ctx, userID, ¤tTariff); err != nil {
|
||||
sendErrors = append(sendErrors, err)
|
||||
}
|
||||
}(tariff)
|
||||
}
|
||||
|
||||
waitGroup.Wait()
|
||||
|
||||
return sendErrors
|
||||
}
|
||||
|
||||
func (receiver *Service) Read(ctx context.Context) []models.Privilege {
|
||||
return receiver.consumer.FetchPrivileges(ctx)
|
||||
}
|
@ -40,22 +40,28 @@ type historyService interface {
|
||||
CreateHistory(ctx context.Context, history *models.History) (*models.History, errors.Error)
|
||||
}
|
||||
|
||||
type tariffBrokerService interface {
|
||||
SendMany(ctx context.Context, userID string, tariffs []models.Tariff) []errors.Error
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
Repository accountRepository
|
||||
HubadminClient hubadminClient
|
||||
DiscountClient discountClient
|
||||
WalletService walletService
|
||||
HistoryService historyService
|
||||
Logger *zap.Logger
|
||||
Repository accountRepository
|
||||
HubadminClient hubadminClient
|
||||
DiscountClient discountClient
|
||||
WalletService walletService
|
||||
HistoryService historyService
|
||||
TariffBrokerService tariffBrokerService
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
logger *zap.Logger
|
||||
repository accountRepository
|
||||
hubadminClient hubadminClient
|
||||
discountClient discountClient
|
||||
walletService walletService
|
||||
historyService historyService
|
||||
logger *zap.Logger
|
||||
repository accountRepository
|
||||
hubadminClient hubadminClient
|
||||
discountClient discountClient
|
||||
walletService walletService
|
||||
historyService historyService
|
||||
tariffBrokerService tariffBrokerService
|
||||
}
|
||||
|
||||
func New(deps Deps) *Service {
|
||||
@ -83,13 +89,18 @@ func New(deps Deps) *Service {
|
||||
log.Panicln("HistoryService is nil on <New (cart service)>")
|
||||
}
|
||||
|
||||
if deps.TariffBrokerService == nil {
|
||||
log.Panicln("TariffBrokerService is nil on <New (cart service)>")
|
||||
}
|
||||
|
||||
return &Service{
|
||||
logger: deps.Logger,
|
||||
repository: deps.Repository,
|
||||
hubadminClient: deps.HubadminClient,
|
||||
discountClient: deps.DiscountClient,
|
||||
walletService: deps.WalletService,
|
||||
historyService: deps.HistoryService,
|
||||
logger: deps.Logger,
|
||||
repository: deps.Repository,
|
||||
hubadminClient: deps.HubadminClient,
|
||||
discountClient: deps.DiscountClient,
|
||||
walletService: deps.WalletService,
|
||||
historyService: deps.HistoryService,
|
||||
tariffBrokerService: deps.TariffBrokerService,
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,41 +142,39 @@ func (receiver *Service) Add(ctx context.Context, request *models.AddItemToCart)
|
||||
return account.Cart, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) Pay(ctx context.Context, accessToken string, userID string) (string, errors.Error) {
|
||||
func (receiver *Service) Pay(ctx context.Context, accessToken string, userID string) errors.Error {
|
||||
account, err := receiver.repository.FindByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to find account on <Pay> of <CartService>", zap.String("userID", userID), zap.Error(err))
|
||||
return "", err
|
||||
return err
|
||||
}
|
||||
|
||||
tariffs, err := receiver.hubadminClient.GetTariffs(ctx, accessToken, account.Cart)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get tarrifs on <Pay> of <CartService>", zap.Strings("cart", account.Cart), zap.Error(err))
|
||||
return "", err
|
||||
return err
|
||||
}
|
||||
|
||||
tariffsAmount := utils.CalculateCartPurchasesAmount(tariffs)
|
||||
|
||||
// TODO: убрать все конвертеры чисел: float64, int64
|
||||
|
||||
response, err := receiver.discountClient.Apply(ctx, &discount.ApplyDiscountRequest{
|
||||
UserInformation: &discount.UserInformation{
|
||||
ID: account.UserID,
|
||||
Type: string(account.Status),
|
||||
PurchasesAmount: float64(account.Wallet.PurchasesAmount),
|
||||
CartPurchasesAmount: float64(tariffsAmount),
|
||||
PurchasesAmount: uint64(account.Wallet.PurchasesAmount),
|
||||
CartPurchasesAmount: uint64(tariffsAmount),
|
||||
},
|
||||
Products: transfer.TariffsToProductInformations(tariffs),
|
||||
Date: timestamppb.New(time.Now()),
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to discount on <Pay> of <CartService>", zap.Error(err))
|
||||
return "", err
|
||||
return err
|
||||
}
|
||||
|
||||
if account.Wallet.Money < int64(response.Price) {
|
||||
receiver.logger.Error("insufficient funds on <Pay> of <CartService>")
|
||||
return "", errors.New(fmt.Errorf("insufficient funds: %d", int64(response.Price)-account.Wallet.Money), errors.ErrInsufficientFunds)
|
||||
return errors.New(fmt.Errorf("insufficient funds: %d", int64(response.Price)-account.Wallet.Money), errors.ErrInsufficientFunds)
|
||||
}
|
||||
|
||||
if _, err := receiver.walletService.WithdrawAccountWalletMoney(ctx, &models.WithdrawAccountWallet{
|
||||
@ -173,7 +182,7 @@ func (receiver *Service) Pay(ctx context.Context, accessToken string, userID str
|
||||
Account: account,
|
||||
}); err != nil {
|
||||
receiver.logger.Error("failed to withdraw money on <Pay> of <CartService>", zap.Error(err))
|
||||
return "", err
|
||||
return err
|
||||
}
|
||||
|
||||
if _, historyErr := receiver.historyService.CreateHistory(ctx, &models.History{
|
||||
@ -184,10 +193,20 @@ func (receiver *Service) Pay(ctx context.Context, accessToken string, userID str
|
||||
receiver.logger.Error("failed to insert history on <Pay> of <CartService>", zap.Error(historyErr))
|
||||
}
|
||||
|
||||
if _, err := receiver.repository.ClearCart(ctx, account.UserID); err != nil {
|
||||
receiver.logger.Error("failed to clear cart on <Pay> of <CartService>", zap.Error(err))
|
||||
return "", err
|
||||
// TODO: обработать ошибки при отправке сообщений
|
||||
|
||||
if sendErrors := receiver.tariffBrokerService.SendMany(ctx, account.UserID, tariffs); len(sendErrors) > 0 {
|
||||
for _, err := range sendErrors {
|
||||
receiver.logger.Error("failed to send tariffs to broker on <Pay> of <CartService>", zap.Error(err))
|
||||
}
|
||||
|
||||
return errors.NewWithMessage("failed to send tariffs to broker", errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return "", nil
|
||||
if _, err := receiver.repository.ClearCart(ctx, account.UserID); err != nil {
|
||||
receiver.logger.Error("failed to clear cart on <Pay> of <CartService>", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -80,10 +80,7 @@ func (receiver *Service) ReplenishAccountWallet(ctx context.Context, request *mo
|
||||
To: request.Account.Wallet.Currency,
|
||||
})
|
||||
if translateErr != nil {
|
||||
receiver.logger.Error("failed to translate cash on <ReplenishAccountWallet> of <WalletService>",
|
||||
zap.Error(translateErr),
|
||||
)
|
||||
|
||||
receiver.logger.Error("failed to translate cash on <ReplenishAccountWallet> of <WalletService>", zap.Error(translateErr))
|
||||
return nil, translateErr
|
||||
}
|
||||
|
||||
@ -127,10 +124,7 @@ func (receiver *Service) ReplenishAccountWallet(ctx context.Context, request *mo
|
||||
To: models.InternalCurrencyKey,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to translate money on <ReplenishAccountWallet> of <WalletService>",
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
receiver.logger.Error("failed to translate money on <ReplenishAccountWallet> of <WalletService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -179,10 +173,7 @@ func (receiver *Service) WithdrawAccountWalletMoney(ctx context.Context, request
|
||||
To: request.Account.Wallet.Currency,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to translate money on <WithdrawAccountWalletMoney> of <WalletService>",
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
receiver.logger.Error("failed to translate money on <WithdrawAccountWalletMoney> of <WalletService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -225,10 +216,7 @@ func (receiver *Service) ChangeCurrency(ctx context.Context, userID string, curr
|
||||
To: currency,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to translate currency on <ChangeCurrency> of <WalletService>",
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
receiver.logger.Error("failed to translate currency on <ChangeCurrency> of <WalletService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -238,10 +226,7 @@ func (receiver *Service) ChangeCurrency(ctx context.Context, userID string, curr
|
||||
Money: account.Wallet.Money,
|
||||
})
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to update wallet on <ChangeCurrency> of <WalletService>",
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
receiver.logger.Error("failed to update wallet on <ChangeCurrency> of <WalletService>", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
53
internal/utils/transfer/privilege.go
Normal file
53
internal/utils/transfer/privilege.go
Normal file
@ -0,0 +1,53 @@
|
||||
package transfer
|
||||
|
||||
import (
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/broker"
|
||||
)
|
||||
|
||||
func PrivilegeProtoToModel(privilege *broker.PrivilegeMessage) *models.Privilege {
|
||||
if privilege == nil {
|
||||
return &models.Privilege{}
|
||||
}
|
||||
|
||||
return &models.Privilege{
|
||||
PrivilegeID: privilege.GetPrivilegeID(),
|
||||
ServiceKey: privilege.GetServiceKey(),
|
||||
Type: privilege.GetType(),
|
||||
Value: privilege.GetValue(),
|
||||
}
|
||||
}
|
||||
|
||||
func PrivilegeArrayProtoToModel(privileges []*broker.PrivilegeMessage) []models.Privilege {
|
||||
privilegesModel := make([]models.Privilege, len(privileges))
|
||||
|
||||
for index, privilege := range privileges {
|
||||
privilegesModel[index] = *PrivilegeProtoToModel(privilege)
|
||||
}
|
||||
|
||||
return privilegesModel
|
||||
}
|
||||
|
||||
func PrivilegeModelToProto(privilege *models.Privilege) *broker.PrivilegeMessage {
|
||||
if privilege == nil {
|
||||
return &broker.PrivilegeMessage{}
|
||||
}
|
||||
|
||||
return &broker.PrivilegeMessage{
|
||||
PrivilegeID: privilege.PrivilegeID,
|
||||
ServiceKey: privilege.ServiceKey,
|
||||
Type: privilege.Type,
|
||||
Value: privilege.Value,
|
||||
}
|
||||
}
|
||||
|
||||
func PrivilegeArrayModelToProto(privileges []models.Privilege) []*broker.PrivilegeMessage {
|
||||
privilegesProto := make([]*broker.PrivilegeMessage, len(privileges))
|
||||
|
||||
for index, privilege := range privileges {
|
||||
privilegeCopy := privilege
|
||||
privilegesProto[index] = PrivilegeModelToProto(&privilegeCopy)
|
||||
}
|
||||
|
||||
return privilegesProto
|
||||
}
|
112
internal/utils/transfer/privilege_test.go
Normal file
112
internal/utils/transfer/privilege_test.go
Normal file
@ -0,0 +1,112 @@
|
||||
package transfer_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/broker"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils/transfer"
|
||||
)
|
||||
|
||||
func TestPrivilegeModelToProto(t *testing.T) {
|
||||
t.Run("Успешный перевод модели привелегии в прото", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
&broker.PrivilegeMessage{
|
||||
PrivilegeID: "12",
|
||||
ServiceKey: "key-1",
|
||||
Type: "type",
|
||||
Value: "12",
|
||||
},
|
||||
transfer.PrivilegeModelToProto(&models.Privilege{
|
||||
ID: "1",
|
||||
Name: "name",
|
||||
PrivilegeID: "12",
|
||||
ServiceKey: "key-1",
|
||||
Description: "description",
|
||||
Type: "type",
|
||||
Value: "12",
|
||||
Price: 20,
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Успешный перевод nil модели привелегии в прото", func(t *testing.T) {
|
||||
assert.Equal(t, &broker.PrivilegeMessage{}, transfer.PrivilegeModelToProto(nil))
|
||||
})
|
||||
}
|
||||
|
||||
func TestPrivilegeArrayModelToProto(t *testing.T) {
|
||||
t.Run("Успешный перевод массива модели привелегий в массив прото", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
[]*broker.PrivilegeMessage{
|
||||
{
|
||||
PrivilegeID: "12",
|
||||
ServiceKey: "key-1",
|
||||
Type: "type",
|
||||
Value: "12",
|
||||
},
|
||||
},
|
||||
transfer.PrivilegeArrayModelToProto([]models.Privilege{
|
||||
{
|
||||
ID: "1",
|
||||
Name: "name",
|
||||
PrivilegeID: "12",
|
||||
ServiceKey: "key-1",
|
||||
Description: "description",
|
||||
Type: "type",
|
||||
Value: "12",
|
||||
Price: 20,
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPrivilegeProtoToModel(t *testing.T) {
|
||||
t.Run("Успешный перевод прото привелегии в модель", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
&models.Privilege{
|
||||
PrivilegeID: "12",
|
||||
ServiceKey: "key-1",
|
||||
Type: "type",
|
||||
Value: "12",
|
||||
},
|
||||
transfer.PrivilegeProtoToModel(&broker.PrivilegeMessage{
|
||||
PrivilegeID: "12",
|
||||
ServiceKey: "key-1",
|
||||
Type: "type",
|
||||
Value: "12",
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Успешный перевод nil прото привелегии в модель", func(t *testing.T) {
|
||||
assert.Equal(t, &models.Privilege{}, transfer.PrivilegeProtoToModel(nil))
|
||||
})
|
||||
}
|
||||
|
||||
func TestPrivilegeArrayProtoToModel(t *testing.T) {
|
||||
t.Run("Успешный перевод массива прото привелегий в массив моделей", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
[]models.Privilege{
|
||||
{
|
||||
PrivilegeID: "12",
|
||||
ServiceKey: "key-1",
|
||||
Type: "type",
|
||||
Value: "12",
|
||||
},
|
||||
{},
|
||||
},
|
||||
transfer.PrivilegeArrayProtoToModel([]*broker.PrivilegeMessage{
|
||||
{
|
||||
PrivilegeID: "12",
|
||||
ServiceKey: "key-1",
|
||||
Type: "type",
|
||||
Value: "12",
|
||||
},
|
||||
nil,
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
@ -2,6 +2,7 @@ package transfer
|
||||
|
||||
import (
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/broker"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/discount"
|
||||
)
|
||||
|
||||
@ -18,6 +19,25 @@ func TariffsToProductInformations(tarrifs []models.Tariff) []*discount.ProductIn
|
||||
func TariffToProductInformation(tarrif models.Tariff) *discount.ProductInformation {
|
||||
return &discount.ProductInformation{
|
||||
ID: tarrif.ID,
|
||||
Price: float64(tarrif.Price),
|
||||
Price: uint64(tarrif.Price),
|
||||
}
|
||||
}
|
||||
|
||||
func TariffMessageProtoToTariffModel(tariff *broker.TariffMessage) *models.Tariff {
|
||||
if tariff == nil {
|
||||
return &models.Tariff{}
|
||||
}
|
||||
|
||||
return &models.Tariff{Privileges: PrivilegeArrayProtoToModel(tariff.Privileges)}
|
||||
}
|
||||
|
||||
func TariffModelToProtoMessage(userID string, tariffModel *models.Tariff) *broker.TariffMessage {
|
||||
if tariffModel == nil {
|
||||
return &broker.TariffMessage{}
|
||||
}
|
||||
|
||||
return &broker.TariffMessage{
|
||||
UserID: userID,
|
||||
Privileges: PrivilegeArrayModelToProto(tariffModel.Privileges),
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/broker"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/discount"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils/transfer"
|
||||
)
|
||||
@ -23,3 +24,82 @@ func TestTariffsToProductInformations(t *testing.T) {
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTariffToProductInformation(t *testing.T) {
|
||||
t.Run("Успешный перевод модели тарифа в информацию о продукте", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
&discount.ProductInformation{
|
||||
ID: "1",
|
||||
Price: 20,
|
||||
},
|
||||
transfer.TariffToProductInformation(models.Tariff{
|
||||
ID: "1",
|
||||
Price: 20,
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTariffMessageProtoToTariffModel(t *testing.T) {
|
||||
t.Run("Успешный перевод прото сообщения тарифа в модель", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
&models.Tariff{
|
||||
Privileges: []models.Privilege{
|
||||
{
|
||||
PrivilegeID: "12",
|
||||
ServiceKey: "key-1",
|
||||
Type: "type",
|
||||
Value: "12",
|
||||
},
|
||||
},
|
||||
},
|
||||
transfer.TariffMessageProtoToTariffModel(&broker.TariffMessage{
|
||||
UserID: "11",
|
||||
Privileges: []*broker.PrivilegeMessage{
|
||||
{
|
||||
PrivilegeID: "12",
|
||||
ServiceKey: "key-1",
|
||||
Type: "type",
|
||||
Value: "12",
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Успешный перевод nil прото сообщения тарифа в модель", func(t *testing.T) {
|
||||
assert.Equal(t, &models.Tariff{}, transfer.TariffMessageProtoToTariffModel(nil))
|
||||
})
|
||||
}
|
||||
|
||||
func TestTariffModelToProtoMessage(t *testing.T) {
|
||||
t.Run("Успешный перевод модели тарифа в прото сообщение", func(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
&broker.TariffMessage{
|
||||
UserID: "1",
|
||||
Privileges: []*broker.PrivilegeMessage{
|
||||
{
|
||||
PrivilegeID: "12",
|
||||
ServiceKey: "key-1",
|
||||
Type: "type",
|
||||
Value: "12",
|
||||
},
|
||||
},
|
||||
},
|
||||
transfer.TariffModelToProtoMessage("1", &models.Tariff{
|
||||
Privileges: []models.Privilege{
|
||||
{
|
||||
PrivilegeID: "12",
|
||||
ServiceKey: "key-1",
|
||||
Type: "type",
|
||||
Value: "12",
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Успешный перевод nil модели тарифа в прото сообщение", func(t *testing.T) {
|
||||
assert.Equal(t, &broker.TariffMessage{}, transfer.TariffModelToProtoMessage("1", nil))
|
||||
})
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
)
|
||||
|
||||
type Callback func(ctx context.Context) error
|
||||
type EasyCallback func()
|
||||
|
||||
type Closer struct {
|
||||
mutex sync.Mutex
|
||||
@ -48,3 +49,15 @@ func (receiver *Closer) Close(ctx context.Context) error {
|
||||
return fmt.Errorf("shutdown cancelled: %v", ctx.Err())
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *Closer) Wrap(callback EasyCallback) Callback {
|
||||
return Wrap(callback)
|
||||
}
|
||||
|
||||
func Wrap(callback EasyCallback) Callback {
|
||||
return func(_ context.Context) error {
|
||||
callback()
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
83
pkg/kafka/kafka.go
Normal file
83
pkg/kafka/kafka.go
Normal file
@ -0,0 +1,83 @@
|
||||
package kafka
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/twmb/franz-go/pkg/kadm"
|
||||
"github.com/twmb/franz-go/pkg/kgo"
|
||||
)
|
||||
|
||||
type Deps struct {
|
||||
Client *kadm.Client
|
||||
}
|
||||
|
||||
type Kafka struct {
|
||||
client *kadm.Client
|
||||
}
|
||||
|
||||
func New(deps Deps) *Kafka {
|
||||
return &Kafka{client: deps.Client}
|
||||
}
|
||||
|
||||
func (receiver *Kafka) TopicExists(ctx context.Context, topic string) (bool, error) {
|
||||
topicsMetadata, err := receiver.client.ListTopics(ctx)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, metadata := range topicsMetadata {
|
||||
if metadata.Topic == topic {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (receiver *Kafka) CreateTopic(ctx context.Context, topic string) error {
|
||||
responses, err := receiver.client.CreateTopics(ctx, 1, 1, nil, topic)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, response := range responses {
|
||||
if response.Err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Initialize topics in brokers if not exist. Client connection closes self.
|
||||
func Initialize(ctx context.Context, brokers, topics []string) error {
|
||||
lastInitializeErr := error(nil)
|
||||
|
||||
kafkaAdminClient, err := kgo.NewClient(kgo.SeedBrokers(brokers...))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer kafkaAdminClient.Close()
|
||||
|
||||
kafka := New(Deps{Client: kadm.NewClient(kafkaAdminClient)})
|
||||
|
||||
for _, topic := range topics {
|
||||
isExist, err := kafka.TopicExists(ctx, topic)
|
||||
if err != nil {
|
||||
lastInitializeErr = err
|
||||
continue
|
||||
}
|
||||
|
||||
if isExist {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := kafka.CreateTopic(ctx, topic); err != nil {
|
||||
lastInitializeErr = fmt.Errorf("failed to create topic <%s> on <Initialize> of <BrokerService>", topic)
|
||||
}
|
||||
}
|
||||
|
||||
return lastInitializeErr
|
||||
}
|
17
proto/broker/models.proto
Normal file
17
proto/broker/models.proto
Normal file
@ -0,0 +1,17 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package broker;
|
||||
|
||||
option go_package = "./broker";
|
||||
|
||||
message PrivilegeMessage {
|
||||
string PrivilegeID = 1;
|
||||
string ServiceKey = 2;
|
||||
string Type = 3;
|
||||
string Value = 4;
|
||||
}
|
||||
|
||||
message TariffMessage {
|
||||
repeated PrivilegeMessage Privileges = 1;
|
||||
string UserID = 2;
|
||||
}
|
@ -1,17 +1,17 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package discount;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
|
||||
option go_package = "./discount";
|
||||
|
||||
message Audit {
|
||||
google.protobuf.Timestamp UpdatedAt = 1;
|
||||
google.protobuf.Timestamp CreatedAt = 2;
|
||||
optional google.protobuf.Timestamp DeletedAt = 3;
|
||||
bool Deleted = 4;
|
||||
}
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package discount;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
|
||||
option go_package = "./discount";
|
||||
|
||||
message Audit {
|
||||
google.protobuf.Timestamp UpdatedAt = 1;
|
||||
google.protobuf.Timestamp CreatedAt = 2;
|
||||
optional google.protobuf.Timestamp DeletedAt = 3;
|
||||
bool Deleted = 4;
|
||||
}
|
||||
|
||||
|
@ -1,88 +1,89 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package discount;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
import "discount/audit.model.proto";
|
||||
|
||||
option go_package = "./discount";
|
||||
|
||||
message DiscountOptional {
|
||||
string ID = 1;
|
||||
optional string Name = 2;
|
||||
optional uint32 Layer = 3;
|
||||
optional string Description = 4;
|
||||
optional DiscountCondition Condition = 5;
|
||||
optional DiscountCalculationTarget Target = 6;
|
||||
}
|
||||
|
||||
message Discounts {
|
||||
repeated Discount Discounts = 1;
|
||||
}
|
||||
|
||||
message Discount {
|
||||
string ID = 1;
|
||||
string Name = 2;
|
||||
uint32 Layer = 3;
|
||||
string Description = 4;
|
||||
DiscountCondition Condition = 5;
|
||||
DiscountCalculationTarget Target = 6;
|
||||
Audit Audit = 7;
|
||||
bool Deprecated = 8;
|
||||
}
|
||||
|
||||
message DiscountCalculationTarget {
|
||||
repeated ProductTarget Products = 1;
|
||||
double Factor = 2;
|
||||
optional TargetScope TargetScope = 3;
|
||||
optional string TargetGroup = 4;
|
||||
optional bool Overhelm = 5;
|
||||
}
|
||||
|
||||
message DiscountCondition {
|
||||
optional PeriodCondition Period = 1;
|
||||
optional string User = 2;
|
||||
optional string UserType = 3;
|
||||
optional string Coupon = 4;
|
||||
optional double PurchasesAmount = 5;
|
||||
optional double CartPurchasesAmount = 6;
|
||||
optional string Product = 7;
|
||||
optional uint64 Term = 8;
|
||||
optional uint64 Usage = 9;
|
||||
optional double PriceFrom = 10;
|
||||
optional string Group = 11;
|
||||
}
|
||||
|
||||
message ProductTarget {
|
||||
string ID = 1;
|
||||
double Factor = 2;
|
||||
optional bool Overhelm = 3;
|
||||
}
|
||||
|
||||
message PeriodCondition {
|
||||
google.protobuf.Timestamp From = 1;
|
||||
google.protobuf.Timestamp To = 2;
|
||||
}
|
||||
|
||||
message UserInformation {
|
||||
string ID = 1;
|
||||
string Type = 2;
|
||||
double PurchasesAmount = 3;
|
||||
double CartPurchasesAmount = 4;
|
||||
}
|
||||
|
||||
message ProductInformation {
|
||||
string ID = 1;
|
||||
double Price = 2;
|
||||
optional uint64 Term = 3;
|
||||
optional uint64 Usage = 4;
|
||||
optional string Group = 5;
|
||||
}
|
||||
|
||||
enum TargetScope {
|
||||
Sum = 0;
|
||||
Group = 1;
|
||||
Each = 2;
|
||||
syntax = "proto3";
|
||||
|
||||
package discount;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
import "discount/audit.model.proto";
|
||||
|
||||
option go_package = "./discount";
|
||||
|
||||
message DiscountOptional {
|
||||
string ID = 1;
|
||||
optional string Name = 2;
|
||||
optional uint32 Layer = 3;
|
||||
optional string Description = 4;
|
||||
optional DiscountCondition Condition = 5;
|
||||
optional DiscountCalculationTarget Target = 6;
|
||||
optional bool Deprecated = 7;
|
||||
}
|
||||
|
||||
message Discounts {
|
||||
repeated Discount Discounts = 1;
|
||||
}
|
||||
|
||||
message Discount {
|
||||
string ID = 1;
|
||||
string Name = 2;
|
||||
uint32 Layer = 3;
|
||||
string Description = 4;
|
||||
DiscountCondition Condition = 5;
|
||||
DiscountCalculationTarget Target = 6;
|
||||
Audit Audit = 7;
|
||||
bool Deprecated = 8;
|
||||
}
|
||||
|
||||
message DiscountCalculationTarget {
|
||||
repeated ProductTarget Products = 1;
|
||||
double Factor = 2;
|
||||
optional TargetScope TargetScope = 3;
|
||||
optional string TargetGroup = 4;
|
||||
optional bool Overhelm = 5;
|
||||
}
|
||||
|
||||
message DiscountCondition {
|
||||
optional PeriodCondition Period = 1;
|
||||
optional string User = 2;
|
||||
optional string UserType = 3;
|
||||
optional string Coupon = 4;
|
||||
optional uint64 PurchasesAmount = 5;
|
||||
optional uint64 CartPurchasesAmount = 6;
|
||||
optional string Product = 7;
|
||||
optional uint64 Term = 8;
|
||||
optional uint64 Usage = 9;
|
||||
optional uint64 PriceFrom = 10;
|
||||
optional string Group = 11;
|
||||
}
|
||||
|
||||
message ProductTarget {
|
||||
string ID = 1;
|
||||
double Factor = 2;
|
||||
optional bool Overhelm = 3;
|
||||
}
|
||||
|
||||
message PeriodCondition {
|
||||
google.protobuf.Timestamp From = 1;
|
||||
google.protobuf.Timestamp To = 2;
|
||||
}
|
||||
|
||||
message UserInformation {
|
||||
string ID = 1;
|
||||
string Type = 2;
|
||||
uint64 PurchasesAmount = 3;
|
||||
uint64 CartPurchasesAmount = 4;
|
||||
}
|
||||
|
||||
message ProductInformation {
|
||||
string ID = 1;
|
||||
uint64 Price = 2;
|
||||
optional uint64 Term = 3;
|
||||
optional uint64 Usage = 4;
|
||||
optional string Group = 5;
|
||||
}
|
||||
|
||||
enum TargetScope {
|
||||
Sum = 0;
|
||||
Group = 1;
|
||||
Each = 2;
|
||||
}
|
@ -1,94 +1,95 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package discount;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
import "discount/discount.model.proto";
|
||||
|
||||
option go_package = "./discount";
|
||||
|
||||
service DiscountService {
|
||||
rpc GetAllDiscounts(google.protobuf.Empty) returns (Discounts) {
|
||||
option (google.api.http) = {
|
||||
get: "/discount/all"
|
||||
};
|
||||
}
|
||||
|
||||
rpc GetUserDiscounts(GetDiscountByIDRequest) returns (Discounts) {
|
||||
option (google.api.http) = {
|
||||
get: "/discount/user/{ID}"
|
||||
};
|
||||
}
|
||||
|
||||
rpc DetermineDiscounts(ApplyDiscountRequest) returns (Discounts) {
|
||||
option (google.api.http) = {
|
||||
post: "/discount/determine"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
rpc ApplyDiscounts(ApplyDiscountRequest) returns (ApplyDiscountResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/discount/apply"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
rpc GetDiscountByID(GetDiscountByIDRequest) returns (Discount) {
|
||||
option (google.api.http) = {
|
||||
get: "/discount/{ID}"
|
||||
};
|
||||
}
|
||||
|
||||
rpc CreateDiscount(CreateDiscountRequest) returns (Discount) {
|
||||
option (google.api.http) = {
|
||||
post: "/discount"
|
||||
};
|
||||
}
|
||||
|
||||
rpc ReplaceDiscount(DiscountOptional) returns (Discount) {
|
||||
option (google.api.http) = {
|
||||
put: "/discount/{ID}"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
rpc UpdateDiscount(DiscountOptional) returns (Discount) {
|
||||
option (google.api.http) = {
|
||||
patch: "/discount/{ID}"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
rpc DeleteDiscount(GetDiscountByIDRequest) returns (Discount) {
|
||||
option (google.api.http) = {
|
||||
delete: "/discount/{ID}"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
message GetDiscountByIDRequest {
|
||||
string ID = 1;
|
||||
}
|
||||
|
||||
message ApplyDiscountRequest {
|
||||
UserInformation UserInformation = 1;
|
||||
repeated ProductInformation Products = 2;
|
||||
google.protobuf.Timestamp Date = 3;
|
||||
optional string Coupon = 4;
|
||||
}
|
||||
|
||||
message ApplyDiscountResponse {
|
||||
double Price = 1;
|
||||
repeated Discount AppliedDiscounts = 2;
|
||||
}
|
||||
|
||||
message CreateDiscountRequest {
|
||||
string Name = 1;
|
||||
uint32 Layer = 2;
|
||||
string Description = 3;
|
||||
DiscountCondition Condition = 4;
|
||||
DiscountCalculationTarget Target = 5;
|
||||
}
|
||||
syntax = "proto3";
|
||||
|
||||
package discount;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
import "discount/discount.model.proto";
|
||||
|
||||
option go_package = "./discount";
|
||||
|
||||
service DiscountService {
|
||||
rpc GetAllDiscounts(google.protobuf.Empty) returns (Discounts) {
|
||||
option (google.api.http) = {
|
||||
get: "/discounts"
|
||||
};
|
||||
}
|
||||
|
||||
rpc GetUserDiscounts(GetDiscountByIDRequest) returns (Discounts) {
|
||||
option (google.api.http) = {
|
||||
get: "/discount/user/{ID}"
|
||||
};
|
||||
}
|
||||
|
||||
rpc DetermineDiscounts(ApplyDiscountRequest) returns (Discounts) {
|
||||
option (google.api.http) = {
|
||||
post: "/discount/determine"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
rpc ApplyDiscounts(ApplyDiscountRequest) returns (ApplyDiscountResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/discount/apply"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
rpc GetDiscountByID(GetDiscountByIDRequest) returns (Discount) {
|
||||
option (google.api.http) = {
|
||||
get: "/discount/{ID}"
|
||||
};
|
||||
}
|
||||
|
||||
rpc CreateDiscount(CreateDiscountRequest) returns (Discount) {
|
||||
option (google.api.http) = {
|
||||
post: "/discount"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
rpc ReplaceDiscount(DiscountOptional) returns (Discount) {
|
||||
option (google.api.http) = {
|
||||
put: "/discount/{ID}"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
rpc UpdateDiscount(DiscountOptional) returns (Discount) {
|
||||
option (google.api.http) = {
|
||||
patch: "/discount/{ID}"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
rpc DeleteDiscount(GetDiscountByIDRequest) returns (Discount) {
|
||||
option (google.api.http) = {
|
||||
delete: "/discount/{ID}"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
message GetDiscountByIDRequest {
|
||||
string ID = 1;
|
||||
}
|
||||
|
||||
message ApplyDiscountRequest {
|
||||
UserInformation UserInformation = 1;
|
||||
repeated ProductInformation Products = 2;
|
||||
google.protobuf.Timestamp Date = 3;
|
||||
optional string Coupon = 4;
|
||||
}
|
||||
|
||||
message ApplyDiscountResponse {
|
||||
uint64 Price = 1;
|
||||
repeated Discount AppliedDiscounts = 2;
|
||||
}
|
||||
|
||||
message CreateDiscountRequest {
|
||||
string Name = 1;
|
||||
uint32 Layer = 2;
|
||||
string Description = 3;
|
||||
DiscountCondition Condition = 4;
|
||||
DiscountCalculationTarget Target = 5;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user