From f62764ae0a52b7ca1e25c052c9b1f75a439ee7a2 Mon Sep 17 00:00:00 2001 From: jakys Date: Wed, 16 Aug 2023 08:13:19 +0000 Subject: [PATCH 01/67] Refactor order --- api/order/create.go | 155 ++++--------- api/order/query.go | 88 ++++---- api/order/update.go | 174 ++++++--------- cmd/order-gateway/run.go | 2 +- go.mod | 5 +- go.sum | 10 +- pkg/const/const.go | 3 +- pkg/order/create.go | 451 ++++++++++++++++++++----------------- pkg/order/handler.go | 286 ++++++++++++++++++++++++ pkg/order/order.go | 122 ---------- pkg/order/query.go | 466 +++++++++++++++++++-------------------- pkg/order/update.go | 202 ++++++++++++----- 12 files changed, 1078 insertions(+), 886 deletions(-) create mode 100644 pkg/order/handler.go delete mode 100644 pkg/order/order.go diff --git a/api/order/create.go b/api/order/create.go index 25f6e94..38b7995 100644 --- a/api/order/create.go +++ b/api/order/create.go @@ -7,128 +7,55 @@ import ( appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/appgood" "github.com/NpoolPlatform/libent-cruder/pkg/cruder" commonpb "github.com/NpoolPlatform/message/npool" + ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" + basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" appgoodpb "github.com/NpoolPlatform/message/npool/good/mgr/v1/appgood" ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" - commontracer "github.com/NpoolPlatform/order-gateway/pkg/tracer" - - constant "github.com/NpoolPlatform/order-gateway/pkg/message/const" order1 "github.com/NpoolPlatform/order-gateway/pkg/order" - "go.opentelemetry.io/otel" - scodes "go.opentelemetry.io/otel/codes" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "github.com/NpoolPlatform/go-service-framework/pkg/logger" npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" - ordermgrpb "github.com/NpoolPlatform/message/npool/order/mgr/v1/order" "github.com/shopspring/decimal" - - "github.com/google/uuid" ) func createOrder(ctx context.Context, in *npool.CreateOrderRequest) (*npool.Order, error) { //nolint - var err error - - _, span := otel.Tracer(constant.ServiceName).Start(ctx, "CreateOrder") - defer span.End() - - defer func() { - if err != nil { - span.SetStatus(scodes.Error, err.Error()) - span.RecordError(err) - } - }() - - if _, err := uuid.Parse(in.GetAppID()); err != nil { - logger.Sugar().Errorw("CreateOrder", "AppID", in.GetAppID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - if _, err := uuid.Parse(in.GetUserID()); err != nil { - logger.Sugar().Errorw("CreateOrder", "UserID", in.GetUserID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - if _, err := uuid.Parse(in.GetGoodID()); err != nil { - logger.Sugar().Errorw("CreateOrder", "GoodID", in.GetGoodID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - units, err := decimal.NewFromString(in.GetUnits()) + handler, err := order1.NewHandler( + ctx, + order1.WithAppID(&in.AppID), + order1.WithUserID(&in.AppID, &in.UserID), + order1.WithGoodID(&in.GoodID), + order1.WithUnits(in.Units), + order1.WithPaymentCoinID(&in.PaymentCoinID), + order1.WithParentOrderID(in.ParentOrderID), + order1.WithOrderType(&in.OrderType), + order1.WithPayWithBalanceAmount(in.GetPayWithBalanceAmount()), + order1.WithFixAmountID(in.FixAmountID), + order1.WithDiscountID(in.DiscountID), + order1.WithSpecialOfferID(in.SpecialOfferID), + order1.WithCouponIDs(in.CouponIDs), + ) if err != nil { - logger.Sugar().Errorw("CreateOrder", "Units", in.GetUnits()) - return nil, status.Error(codes.InvalidArgument, "Units is 0") - } - if units.Cmp(decimal.NewFromInt32(0)) <= 0 { - logger.Sugar().Errorw("CreateOrder", "Units", in.GetUnits()) - return nil, status.Error(codes.InvalidArgument, "Units is 0") - } - if _, err := uuid.Parse(in.GetPaymentCoinID()); err != nil { - logger.Sugar().Errorw("CreateOrder", "PaymentCoinID", in.GetPaymentCoinID(), "error", err) + logger.Sugar().Errorw( + "createOrder", + "In", in, + "Error", err, + ) return nil, status.Error(codes.InvalidArgument, err.Error()) } - if in.ParentOrderID != nil { - if _, err := uuid.Parse(in.GetParentOrderID()); err != nil { - logger.Sugar().Errorw("CreateOrder", "ParentOrderID", in.GetParentOrderID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - } - if in.PayWithBalanceAmount != nil { - amount, err := decimal.NewFromString(in.GetPayWithBalanceAmount()) - if err != nil { - logger.Sugar().Errorw("CreateOrder", "PayWithBalanceAmount", in.GetPayWithBalanceAmount(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - if amount.Cmp(decimal.NewFromInt(0)) < 0 { - logger.Sugar().Errorw("CreateOrder", "PayWithBalanceAmount", in.GetPayWithBalanceAmount()) - return nil, status.Error(codes.InvalidArgument, "PayWithBalanceAmount less than 0") - } - } - if in.FixAmountID != nil { - if _, err := uuid.Parse(in.GetFixAmountID()); err != nil { - logger.Sugar().Errorw("CreateOrder", "FixAmountID", in.GetFixAmountID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - } - if in.DiscountID != nil { - if _, err := uuid.Parse(in.GetDiscountID()); err != nil { - logger.Sugar().Errorw("CreateOrder", "DiscountID", in.GetDiscountID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - } - if in.SpecialOfferID != nil { - if _, err := uuid.Parse(in.GetSpecialOfferID()); err != nil { - logger.Sugar().Errorw("CreateOrder", "SpecialOfferID", in.GetSpecialOfferID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - } - for _, id := range in.GetCouponIDs() { - if _, err := uuid.Parse(id); err != nil { - logger.Sugar().Errorw("CreateOrder", "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - } - span = commontracer.TraceInvoker(span, "order", "gateway", "CreateOrder") - - // Here we may create sub order according to good info, but we only return main order - info, err := order1.CreateOrder(ctx, &order1.OrderCreate{ - AppID: in.GetAppID(), - UserID: in.GetUserID(), - GoodID: in.GetGoodID(), - PaymentCoinID: in.GetPaymentCoinID(), - Units: in.GetUnits(), - ParentOrderID: in.ParentOrderID, - BalanceAmount: in.PayWithBalanceAmount, - FixAmountID: in.FixAmountID, - DiscountID: in.DiscountID, - SpecialOfferID: in.SpecialOfferID, - OrderType: in.GetOrderType(), - CouponIDs: in.CouponIDs, - }) + info, err := handler.UpdateOrder(ctx) if err != nil { - logger.Sugar().Errorw("CreateOrder", "error", err) + logger.Sugar().Errorw( + "createOrder", + "In", in, + "Error", err, + ) return nil, status.Error(codes.Internal, err.Error()) } @@ -167,16 +94,16 @@ func (s *Server) CreateOrder(ctx context.Context, in *npool.CreateOrderRequest) purchaseCountStr, err := ordermwcli.SumOrderUnits( ctx, &ordermwpb.Conds{ - AppID: &commonpb.StringVal{Op: cruder.EQ, Value: in.AppID}, - UserID: &commonpb.StringVal{Op: cruder.EQ, Value: in.UserID}, - GoodID: &commonpb.StringVal{Op: cruder.EQ, Value: in.GoodID}, - States: &commonpb.Uint32SliceVal{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: in.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: in.UserID}, + GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: in.GoodID}, + States: &basetypes.Uint32SliceVal{ Op: cruder.IN, Value: []uint32{ - uint32(ordermgrpb.OrderState_Paid), - uint32(ordermgrpb.OrderState_InService), - uint32(ordermgrpb.OrderState_Expired), - uint32(ordermgrpb.OrderState_WaitPayment), + uint32(ordertypes.OrderState_OrderStatePaid), + uint32(ordertypes.OrderState_OrderStateInService), + uint32(ordertypes.OrderState_OrderStateExpired), + uint32(ordertypes.OrderState_OrderStateWaitPayment), }, }, }, @@ -200,7 +127,7 @@ func (s *Server) CreateOrder(ctx context.Context, in *npool.CreateOrderRequest) return &npool.CreateOrderResponse{}, status.Error(codes.Internal, "too many units") } - in.OrderType = ordermgrpb.OrderType_Normal + in.OrderType = ordertypes.OrderType_Normal ord, err := createOrder(ctx, in) if err != nil { return &npool.CreateOrderResponse{}, err @@ -212,8 +139,8 @@ func (s *Server) CreateOrder(ctx context.Context, in *npool.CreateOrderRequest) func (s *Server) CreateUserOrder(ctx context.Context, in *npool.CreateUserOrderRequest) (*npool.CreateUserOrderResponse, error) { switch in.OrderType { - case ordermgrpb.OrderType_Offline: - case ordermgrpb.OrderType_Airdrop: + case ordertypes.OrderType_Offline: + case ordertypes.OrderType_Airdrop: default: return &npool.CreateUserOrderResponse{}, status.Errorf(codes.InvalidArgument, "order type invalid") } @@ -237,8 +164,8 @@ func (s *Server) CreateUserOrder(ctx context.Context, in *npool.CreateUserOrderR func (s *Server) CreateAppUserOrder(ctx context.Context, in *npool.CreateAppUserOrderRequest) (*npool.CreateAppUserOrderResponse, error) { switch in.OrderType { - case ordermgrpb.OrderType_Offline: - case ordermgrpb.OrderType_Airdrop: + case ordertypes.OrderType_Offline: + case ordertypes.OrderType_Airdrop: default: return &npool.CreateAppUserOrderResponse{}, status.Errorf(codes.InvalidArgument, "order type invalid") } diff --git a/api/order/query.go b/api/order/query.go index ed14d9c..0a004e9 100644 --- a/api/order/query.go +++ b/api/order/query.go @@ -10,30 +10,38 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - - "github.com/google/uuid" ) func (s *Server) GetOrders(ctx context.Context, in *npool.GetOrdersRequest) (*npool.GetOrdersResponse, error) { - if _, err := uuid.Parse(in.GetAppID()); err != nil { - logger.Sugar().Errorw("GetOrders", "AppID", in.GetAppID(), "error", err) - return &npool.GetOrdersResponse{}, status.Error(codes.InvalidArgument, err.Error()) - } - - if _, err := uuid.Parse(in.GetUserID()); err != nil { - logger.Sugar().Errorw("GetOrders", "UserID", in.GetUserID(), "error", err) + handler, err := order1.NewHandler( + ctx, + order1.WithAppID(&in.AppID), + order1.WithUserID(&in.AppID, &in.UserID), + order1.WithOffset(in.GetOffset()), + order1.WithLimit(in.GetLimit()), + ) + if err != nil { + logger.Sugar().Errorw( + "GetOrders", + "In", in, + "Error", err, + ) return &npool.GetOrdersResponse{}, status.Error(codes.InvalidArgument, err.Error()) } - ords, n, err := order1.GetOrders(ctx, in.GetAppID(), in.GetUserID(), in.GetOffset(), in.GetLimit()) + infos, total, err := handler.GetOrders(ctx) if err != nil { - logger.Sugar().Errorw("GetOrders", "error", err) + logger.Sugar().Errorw( + "GetOrders", + "In", in, + "Error", err, + ) return &npool.GetOrdersResponse{}, status.Error(codes.Internal, err.Error()) } return &npool.GetOrdersResponse{ - Infos: ords, - Total: n, + Infos: infos, + Total: total, }, nil } @@ -72,52 +80,52 @@ func (s *Server) GetAppUserOrders(ctx context.Context, in *npool.GetAppUserOrder } func (s *Server) GetOrder(ctx context.Context, in *npool.GetOrderRequest) (*npool.GetOrderResponse, error) { - if _, err := uuid.Parse(in.GetAppID()); err != nil { - logger.Sugar().Errorw("GetOrder", "AppID", in.GetAppID(), "error", err) - return &npool.GetOrderResponse{}, status.Error(codes.InvalidArgument, err.Error()) - } - - if _, err := uuid.Parse(in.GetUserID()); err != nil { - logger.Sugar().Errorw("GetOrder", "UserID", in.GetUserID(), "error", err) - return &npool.GetOrderResponse{}, status.Error(codes.InvalidArgument, err.Error()) - } - - if _, err := uuid.Parse(in.GetID()); err != nil { - logger.Sugar().Errorw("GetOrder", "ID", in.GetID(), "error", err) + handler, err := order1.NewHandler( + ctx, + order1.WithID(&in.ID), + ) + if err != nil { + logger.Sugar().Errorw( + "GetOrder", + "In", in, + "Error", err, + ) return &npool.GetOrderResponse{}, status.Error(codes.InvalidArgument, err.Error()) } - ord, err := order1.GetOrder(ctx, in.GetID()) + info, err := handler.GetOrder(ctx) if err != nil { - logger.Sugar().Errorw("GetOrder", "error", err) + logger.Sugar().Errorw( + "GetOrder", + "In", in, + "Error", err, + ) return &npool.GetOrderResponse{}, status.Error(codes.Internal, err.Error()) } - if ord.AppID != in.GetAppID() || ord.UserID != in.GetUserID() { - logger.Sugar().Errorw("GetOrder", "Order", ord, "error", "permission denied") + if info.AppID != in.GetAppID() || info.UserID != in.GetUserID() { + logger.Sugar().Errorw("GetOrder", "Order", info, "error", "permission denied") return &npool.GetOrderResponse{}, status.Error(codes.PermissionDenied, "permission denied") } return &npool.GetOrderResponse{ - Info: ord, + Info: info, }, nil } func (s *Server) GetAppOrders(ctx context.Context, in *npool.GetAppOrdersRequest) (*npool.GetAppOrdersResponse, error) { - if _, err := uuid.Parse(in.GetAppID()); err != nil { - logger.Sugar().Errorw("GetAppOrders", "AppID", in.GetAppID(), "error", err) - return &npool.GetAppOrdersResponse{}, status.Error(codes.InvalidArgument, err.Error()) - } - - ords, n, err := order1.GetAppOrders(ctx, in.GetAppID(), in.GetOffset(), in.GetLimit()) + resp, err := s.GetOrders(ctx, &npool.GetOrdersRequest{ + AppID: in.GetAppID(), + Offset: in.Offset, + Limit: in.Limit, + }) if err != nil { - logger.Sugar().Errorw("GetAppOrders", "error", err) - return &npool.GetAppOrdersResponse{}, status.Error(codes.Internal, err.Error()) + return &npool.GetAppOrdersResponse{}, err } return &npool.GetAppOrdersResponse{ - Infos: ords, - Total: n, + Infos: resp.Infos, + Total: resp.Total, }, nil } diff --git a/api/order/update.go b/api/order/update.go index 09399ee..1330f6f 100644 --- a/api/order/update.go +++ b/api/order/update.go @@ -11,136 +11,106 @@ import ( "github.com/NpoolPlatform/go-service-framework/pkg/logger" npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" - ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" - - "github.com/google/uuid" ) func (s *Server) UpdateOrder(ctx context.Context, in *npool.UpdateOrderRequest) (*npool.UpdateOrderResponse, error) { - if _, err := uuid.Parse(in.GetAppID()); err != nil { - logger.Sugar().Errorw("UpdateOrder", "AppID", in.GetAppID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - - if _, err := uuid.Parse(in.GetUserID()); err != nil { - logger.Sugar().Errorw("UpdateOrder", "UserID", in.GetUserID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - - if _, err := uuid.Parse(in.GetID()); err != nil { - logger.Sugar().Errorw("UpdateOrder", "ID", in.GetID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - - if _, err := uuid.Parse(in.GetPaymentID()); err != nil { - logger.Sugar().Errorw("UpdateOrder", "PaymentID", in.GetPaymentID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - - if in.Canceled == nil { - logger.Sugar().Errorw("UpdateOrder", "error", "nothing todo") - return nil, status.Error(codes.InvalidArgument, "nothing todo") + handler, err := order1.NewHandler( + ctx, + order1.WithID(&in.ID), + order1.WithAppID(&in.AppID), + order1.WithUserID(&in.AppID, &in.UserID), + order1.WithPaymentID(&in.PaymentID), + order1.WithCanceled(in.Canceled), + order1.WithFromAdmin(false), + ) + if err != nil { + logger.Sugar().Errorw( + "UpdateOrder", + "In", in, + "Error", err, + ) + return &npool.UpdateOrderResponse{}, status.Error(codes.InvalidArgument, err.Error()) } - ord, err := order1.UpdateOrder(ctx, &ordermwpb.OrderReq{ - AppID: &in.AppID, - UserID: &in.UserID, - ID: &in.ID, - PaymentID: &in.PaymentID, - Canceled: in.Canceled, - }, false) + info, err := handler.UpdateOrder(ctx) if err != nil { - logger.Sugar().Errorw("UpdateOrder", "error", err) - return nil, status.Error(codes.Internal, err.Error()) + logger.Sugar().Errorw( + "UpdateOrder", + "In", in, + "Error", err, + ) + return &npool.UpdateOrderResponse{}, status.Error(codes.Internal, err.Error()) } return &npool.UpdateOrderResponse{ - Info: ord, + Info: info, }, nil } func (s *Server) UpdateUserOrder(ctx context.Context, in *npool.UpdateUserOrderRequest) (*npool.UpdateUserOrderResponse, error) { - if _, err := uuid.Parse(in.GetAppID()); err != nil { - logger.Sugar().Errorw("UpdateUserOrder", "AppID", in.GetAppID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - - if _, err := uuid.Parse(in.GetTargetUserID()); err != nil { - logger.Sugar().Errorw("UpdateUserOrder", "UserID", in.GetTargetUserID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - - if _, err := uuid.Parse(in.GetID()); err != nil { - logger.Sugar().Errorw("UpdateUserOrder", "ID", in.GetID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - - if _, err := uuid.Parse(in.GetPaymentID()); err != nil { - logger.Sugar().Errorw("UpdateUserOrder", "PaymentID", in.GetPaymentID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - - if in.Canceled == nil { - logger.Sugar().Errorw("UpdateUserOrder", "error", "nothing todo") - return nil, status.Error(codes.InvalidArgument, "nothing todo") + handler, err := order1.NewHandler( + ctx, + order1.WithID(&in.ID), + order1.WithAppID(&in.AppID), + order1.WithUserID(&in.AppID, &in.TargetUserID), + order1.WithPaymentID(&in.PaymentID), + order1.WithCanceled(in.Canceled), + order1.WithFromAdmin(false), + ) + if err != nil { + logger.Sugar().Errorw( + "UpdateUserOrder", + "In", in, + "Error", err, + ) + return &npool.UpdateUserOrderResponse{}, status.Error(codes.InvalidArgument, err.Error()) } - ord, err := order1.UpdateOrder(ctx, &ordermwpb.OrderReq{ - AppID: &in.AppID, - UserID: &in.TargetUserID, - ID: &in.ID, - PaymentID: &in.PaymentID, - Canceled: in.Canceled, - }, true) + info, err := handler.UpdateOrder(ctx) if err != nil { - logger.Sugar().Errorw("UpdateUserOrder", "error", err) - return nil, status.Error(codes.Internal, "fail update order") + logger.Sugar().Errorw( + "UpdateUserOrder", + "In", in, + "Error", err, + ) + return &npool.UpdateUserOrderResponse{}, status.Error(codes.Internal, err.Error()) } return &npool.UpdateUserOrderResponse{ - Info: ord, + Info: info, }, nil } func (s *Server) UpdateAppUserOrder(ctx context.Context, in *npool.UpdateAppUserOrderRequest) (*npool.UpdateAppUserOrderResponse, error) { - if _, err := uuid.Parse(in.GetTargetUserID()); err != nil { - logger.Sugar().Errorw("UpdateAppUserOrder", "AppID", in.GetTargetUserID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - - if _, err := uuid.Parse(in.GetTargetUserID()); err != nil { - logger.Sugar().Errorw("UpdateAppUserOrder", "UserID", in.GetTargetUserID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - - if _, err := uuid.Parse(in.GetID()); err != nil { - logger.Sugar().Errorw("UpdateAppUserOrder", "ID", in.GetID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - - if _, err := uuid.Parse(in.GetPaymentID()); err != nil { - logger.Sugar().Errorw("UpdateAppUserOrder", "PaymentID", in.GetPaymentID(), "error", err) - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - - if in.Canceled == nil { - logger.Sugar().Errorw("UpdateAppUserOrder", "error", "nothing todo") - return nil, status.Error(codes.InvalidArgument, "nothing todo") + handler, err := order1.NewHandler( + ctx, + order1.WithID(&in.ID), + order1.WithAppID(&in.TargetAppID), + order1.WithUserID(&in.TargetAppID, &in.TargetUserID), + order1.WithPaymentID(&in.PaymentID), + order1.WithCanceled(in.Canceled), + order1.WithFromAdmin(false), + ) + if err != nil { + logger.Sugar().Errorw( + "UpdateAppUserOrder", + "In", in, + "Error", err, + ) + return &npool.UpdateAppUserOrderResponse{}, status.Error(codes.InvalidArgument, err.Error()) } - ord, err := order1.UpdateOrder(ctx, &ordermwpb.OrderReq{ - AppID: &in.TargetAppID, - UserID: &in.TargetUserID, - ID: &in.ID, - PaymentID: &in.PaymentID, - Canceled: in.Canceled, - }, true) + info, err := handler.UpdateOrder(ctx) if err != nil { - logger.Sugar().Errorw("UpdateAppUserOrder", "error", err) - return nil, status.Error(codes.Internal, "fail update order") + logger.Sugar().Errorw( + "UpdateAppUserOrder", + "In", in, + "Error", err, + ) + return &npool.UpdateAppUserOrderResponse{}, status.Error(codes.Internal, err.Error()) } return &npool.UpdateAppUserOrderResponse{ - Info: ord, + Info: info, }, nil } diff --git a/cmd/order-gateway/run.go b/cmd/order-gateway/run.go index 8998fa3..c157c1a 100644 --- a/cmd/order-gateway/run.go +++ b/cmd/order-gateway/run.go @@ -3,7 +3,7 @@ package main import ( "github.com/NpoolPlatform/order-gateway/api" "github.com/NpoolPlatform/order-gateway/pkg/migrator" - "github.com/NpoolPlatform/order-manager/pkg/db" + "github.com/NpoolPlatform/order-middleware/pkg/db" grpc2 "github.com/NpoolPlatform/go-service-framework/pkg/grpc" "github.com/NpoolPlatform/go-service-framework/pkg/logger" diff --git a/go.mod b/go.mod index bbaadeb..5c4f73b 100644 --- a/go.mod +++ b/go.mod @@ -12,9 +12,8 @@ require ( github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230303153851-9f5d1d78921a github.com/NpoolPlatform/libent-cruder v0.0.0-20221109023947-366125b690fb - github.com/NpoolPlatform/message v0.0.0-20230811100148-665aae942dc8 - github.com/NpoolPlatform/order-manager v0.0.0-20230301030435-b03a2a42a69c - github.com/NpoolPlatform/order-middleware v0.0.0-20230309070310-d1b776ed75e8 + github.com/NpoolPlatform/message v0.0.0-20230815040303-b186df0b7f2b + github.com/NpoolPlatform/order-middleware v0.0.0-20230815061732-4d55ec9e8f2a github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/go-resty/resty/v2 v2.7.0 github.com/google/uuid v1.3.0 diff --git a/go.sum b/go.sum index e8ed4fb..5ad6581 100644 --- a/go.sum +++ b/go.sum @@ -68,12 +68,10 @@ github.com/NpoolPlatform/ledger-middleware v0.0.0-20230303153851-9f5d1d78921a h1 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230303153851-9f5d1d78921a/go.mod h1:PHraMn7XFekx4iYzJPJYt8z4NbUY2G7evmNkghxz47o= github.com/NpoolPlatform/libent-cruder v0.0.0-20221109023947-366125b690fb h1:IAQOJ0xQWdJS1BnimNdM6GZMLgTL/FnIa8C8K4xffUA= github.com/NpoolPlatform/libent-cruder v0.0.0-20221109023947-366125b690fb/go.mod h1:zvvqlRwbOdTUauPQ9dFDhDuxa91ILV0CQfVdPBZj+eA= -github.com/NpoolPlatform/message v0.0.0-20230811100148-665aae942dc8 h1:8PqDkY/opP0LRsHttjOcUPwmoKHU1LLea7nFzLYrUdY= -github.com/NpoolPlatform/message v0.0.0-20230811100148-665aae942dc8/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= -github.com/NpoolPlatform/order-manager v0.0.0-20230301030435-b03a2a42a69c h1:l7frtKUbO/71g7h5B4s8Bfcr9ypo3BsqBdevTRtpGb4= -github.com/NpoolPlatform/order-manager v0.0.0-20230301030435-b03a2a42a69c/go.mod h1:PBI+tC76GbzTAQCmkEYtwZOItNdyyZBjE/kGHzgcP8I= -github.com/NpoolPlatform/order-middleware v0.0.0-20230309070310-d1b776ed75e8 h1:eRWk+Okltq00YfDBIhKJIzDFfgcgXxnQOW3P+GD8Dfg= -github.com/NpoolPlatform/order-middleware v0.0.0-20230309070310-d1b776ed75e8/go.mod h1:+2ZsZhQ0wKcVG9ZLuoNmXdkoJBSbtjRTo2GCCqexJYE= +github.com/NpoolPlatform/message v0.0.0-20230815040303-b186df0b7f2b h1:F5AuUHifvGQCpXyacePYocRCSbRXbTLvhdC78ilPuVM= +github.com/NpoolPlatform/message v0.0.0-20230815040303-b186df0b7f2b/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/order-middleware v0.0.0-20230815061732-4d55ec9e8f2a h1:CS1BC6q2NlAQQQG6Unwidj7iDh3vT5C/4jKztFSf3Xg= +github.com/NpoolPlatform/order-middleware v0.0.0-20230815061732-4d55ec9e8f2a/go.mod h1:GYe5QFjM7oS+Ut3owu3PP86kHeI5fMJTVRhOyf9PLCg= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b/go.mod h1:9C9XDi7c0szxcLdJGDDFuo3/KtC74yWiyUM2fR+i0ww= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= diff --git a/pkg/const/const.go b/pkg/const/const.go index f9410c6..7804a25 100644 --- a/pkg/const/const.go +++ b/pkg/const/const.go @@ -1,5 +1,6 @@ package constant const ( - FieldID = "ID" + FieldID = "ID" + DefaultRowLimit = int32(100) ) diff --git a/pkg/order/create.go b/pkg/order/create.go index 971f19b..be2d7cc 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -6,14 +6,9 @@ import ( "time" "github.com/NpoolPlatform/go-service-framework/pkg/logger" - - npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" + "github.com/google/uuid" payaccmwcli "github.com/NpoolPlatform/account-middleware/pkg/client/payment" - appcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/app" - usercli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" - ordercli "github.com/NpoolPlatform/order-manager/pkg/client/order" - paymentcli "github.com/NpoolPlatform/order-manager/pkg/client/payment" goodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good" @@ -21,22 +16,17 @@ import ( coininfocli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin" currvalmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin/currency" appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/appgood" - allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" - ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" sphinxproxycli "github.com/NpoolPlatform/sphinx-proxy/pkg/client" goodmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/good" + paymentmwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/payment" + paymentmwcli "github.com/NpoolPlatform/order-middleware/pkg/client/payment" appcoinmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/app/coin" appgoodpb "github.com/NpoolPlatform/message/npool/good/mgr/v1/appgood" payaccmwpb "github.com/NpoolPlatform/message/npool/account/mw/v1/payment" - inspiretypes "github.com/NpoolPlatform/message/npool/basetypes/inspire/v1" currvalmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin/currency" - allocatedmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/coupon/allocated" - ordermgrpb "github.com/NpoolPlatform/message/npool/order/mgr/v1/order" - paymentmgrpb "github.com/NpoolPlatform/message/npool/order/mgr/v1/payment" - ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" sphinxproxypb "github.com/NpoolPlatform/message/npool/sphinxproxy" accountlock "github.com/NpoolPlatform/account-middleware/pkg/lock" @@ -47,29 +37,23 @@ import ( commonpb "github.com/NpoolPlatform/message/npool" basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" + ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" + ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" + + allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" + inspiretypes "github.com/NpoolPlatform/message/npool/basetypes/inspire/v1" + ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" + allocatedmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/coupon/allocated" + npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" "github.com/shopspring/decimal" ) -type OrderCreate struct { - AppID string - UserID string - GoodID string - GoodStartAt uint32 - GoodDurationDays uint32 - Units string - - PaymentCoinID string - BalanceAmount *string - - ParentOrderID *string - OrderType ordermgrpb.OrderType - - FixAmountID *string - DiscountID *string - SpecialOfferID *string - CouponIDs []string - +type createHandler struct { + *Handler + GoodStartAt uint32 + GoodDurationDays uint32 + BalanceAmount *string paymentCoinName string paymentAmountUSD decimal.Decimal paymentAmountCoin decimal.Decimal @@ -93,24 +77,39 @@ type OrderCreate struct { end uint32 } -func (o *OrderCreate) ValidateInit(ctx context.Context) error { //nolint - app, err := appcli.GetApp(ctx, o.AppID) - if err != nil { - return err +func (h *createHandler) validateInit(ctx context.Context) error { //nolint + if h.AppID == nil { + return fmt.Errorf("invalid appid") } - if app == nil { - return fmt.Errorf("invalid app") + if h.UserID == nil { + return fmt.Errorf("invalid userid") } - - user, err := usercli.GetUser(ctx, o.AppID, o.UserID) + if h.GoodID == nil { + return fmt.Errorf("invalid goodid") + } + if h.Units == "" { + return fmt.Errorf("invalid units") + } + units, err := decimal.NewFromString(h.Units) if err != nil { return err } - if user == nil { - return fmt.Errorf("invalid user") + if units.Cmp(decimal.NewFromInt32(0)) <= 0 { + return fmt.Errorf("units is 0") + } + if h.PaymentCoinID == nil { + return fmt.Errorf("invalid paymentcoinid") + } + if h.CouponIDs != nil { + for _, id := range h.CouponIDs { + if _, err := uuid.Parse(id); err != nil { + logger.Sugar().Errorw("CreateOrder", "error", err) + return fmt.Errorf("invalid couponids") + } + } } - good, err := goodmwcli.GetGood(ctx, o.GoodID) + good, err := goodmwcli.GetGood(ctx, *h.GoodID) if err != nil { return err } @@ -121,11 +120,11 @@ func (o *OrderCreate) ValidateInit(ctx context.Context) error { //nolint ag, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodpb.Conds{ AppID: &commonpb.StringVal{ Op: cruder.EQ, - Value: o.AppID, + Value: *h.AppID, }, GoodID: &commonpb.StringVal{ Op: cruder.EQ, - Value: o.GoodID, + Value: *h.GoodID, }, }) if err != nil { @@ -135,13 +134,13 @@ func (o *OrderCreate) ValidateInit(ctx context.Context) error { //nolint return fmt.Errorf("invalid app good") } - o.GoodStartAt = ag.ServiceStartAt + h.GoodStartAt = ag.ServiceStartAt if ag.ServiceStartAt == 0 { - o.GoodStartAt = good.StartAt + h.GoodStartAt = good.StartAt } - o.GoodDurationDays = uint32(good.DurationDays) + h.GoodDurationDays = uint32(good.DurationDays) gcoin, err := coininfocli.GetCoin(ctx, good.CoinTypeID) if err != nil { @@ -151,7 +150,7 @@ func (o *OrderCreate) ValidateInit(ctx context.Context) error { //nolint return fmt.Errorf("invalid good coin") } - coin, err := coininfocli.GetCoin(ctx, o.PaymentCoinID) + coin, err := coininfocli.GetCoin(ctx, *h.PaymentCoinID) if err != nil { return err } @@ -168,10 +167,10 @@ func (o *OrderCreate) ValidateInit(ctx context.Context) error { //nolint return fmt.Errorf("good coin mismatch payment coin") } - o.paymentCoinName = coin.Name + h.paymentCoinName = coin.Name - if o.ParentOrderID != nil { - order, err := ordercli.GetOrder(ctx, *o.ParentOrderID) + if h.ParentOrderID != nil { + order, err := ordermwcli.GetOrder(ctx, *h.ParentOrderID) if err != nil { return err } @@ -201,60 +200,58 @@ func (o *OrderCreate) ValidateInit(ctx context.Context) error { //nolint const maxUnpaidOrders = 5 - payments, _, err := paymentcli.GetPayments(ctx, &paymentmgrpb.Conds{ - AppID: &commonpb.StringVal{ + payments, _, err := paymentmwcli.GetPayments(ctx, &paymentmwpb.Conds{ + AppID: &basetypes.StringVal{ Op: cruder.EQ, - Value: o.AppID, + Value: *h.AppID, }, - UserID: &commonpb.StringVal{ + UserID: &basetypes.StringVal{ Op: cruder.EQ, - Value: o.UserID, + Value: *h.UserID, }, - State: &commonpb.Uint32Val{ + State: &basetypes.Uint32Val{ Op: cruder.EQ, - Value: uint32(paymentmgrpb.PaymentState_Wait), + Value: uint32(ordertypes.PaymentState_PaymentStateWait), }, }, 0, maxUnpaidOrders) if err != nil { return err } - if len(payments) >= maxUnpaidOrders && o.OrderType == ordermgrpb.OrderType_Normal { + if len(payments) >= maxUnpaidOrders && *h.OrderType == ordertypes.OrderType_Normal { return fmt.Errorf("too many unpaid orders") } - switch o.OrderType { - case ordermgrpb.OrderType_Normal: - case ordermgrpb.OrderType_Offline: - case ordermgrpb.OrderType_Airdrop: + switch *h.OrderType { + case ordertypes.OrderType_Normal: + case ordertypes.OrderType_Offline: + case ordertypes.OrderType_Airdrop: default: return fmt.Errorf("invalid order type") } - // TODO: check app / user banned - return nil } // nolint -func (o *OrderCreate) SetReduction(ctx context.Context) error { - if len(o.CouponIDs) == 0 { +func (h *createHandler) SetReduction(ctx context.Context) error { + if len(h.CouponIDs) == 0 { return nil } coupons, _, err := allocatedmwcli.GetCoupons(ctx, &allocatedmwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: o.AppID}, - UserID: &basetypes.StringVal{Op: cruder.EQ, Value: o.UserID}, - IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: o.CouponIDs}, - }, int32(0), int32(len(o.CouponIDs))) + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: h.CouponIDs}, + }, int32(0), int32(len(h.CouponIDs))) if err != nil { return err } - if len(coupons) != len(o.CouponIDs) { + if len(coupons) != len(h.CouponIDs) { return fmt.Errorf("invalid coupon") } - exist, err := ordercli.ExistOrderConds(ctx, &ordermgrpb.Conds{ - CouponIDs: &commonpb.StringSliceVal{Op: cruder.EQ, Value: o.CouponIDs}, + exist, err := ordermwcli.ExistOrderConds(ctx, &ordermwpb.Conds{ + CouponIDs: &basetypes.StringSliceVal{Op: cruder.EQ, Value: h.CouponIDs}, }) if err != nil { return err @@ -264,7 +261,7 @@ func (o *OrderCreate) SetReduction(ctx context.Context) error { } for _, coup := range coupons { - if !coup.Valid || coup.Expired || coup.AppID != o.AppID || coup.UserID != o.UserID { + if !coup.Valid || coup.Expired || coup.AppID != *h.AppID || coup.UserID != *h.UserID { return fmt.Errorf("invalid coupon") } switch coup.CouponType { @@ -275,7 +272,7 @@ func (o *OrderCreate) SetReduction(ctx context.Context) error { if err != nil { return err } - o.reductionAmount = o.reductionAmount.Add(amount) + h.reductionAmount = h.reductionAmount.Add(amount) case inspiretypes.CouponType_Discount: percent, err := decimal.NewFromString(coup.Denomination) if err != nil { @@ -284,7 +281,7 @@ func (o *OrderCreate) SetReduction(ctx context.Context) error { if percent.Cmp(decimal.NewFromInt(100)) >= 0 { return fmt.Errorf("invalid discount") } - o.reductionPercent = percent + h.reductionPercent = percent default: return fmt.Errorf("unknown coupon type") } @@ -293,19 +290,19 @@ func (o *OrderCreate) SetReduction(ctx context.Context) error { return nil } -func (o *OrderCreate) SetPrice(ctx context.Context) error { - good, err := goodmwcli.GetGood(ctx, o.GoodID) +func (h *createHandler) SetPrice(ctx context.Context) error { + good, err := goodmwcli.GetGood(ctx, *h.GoodID) if err != nil { return err } ag, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodpb.Conds{ AppID: &commonpb.StringVal{ Op: cruder.EQ, - Value: o.AppID, + Value: *h.AppID, }, GoodID: &commonpb.StringVal{ Op: cruder.EQ, - Value: o.GoodID, + Value: *h.GoodID, }, }) if err != nil { @@ -333,7 +330,7 @@ func (o *OrderCreate) SetPrice(ctx context.Context) error { return fmt.Errorf("invalid app good price") } - o.price, err = decimal.NewFromString(ag.Price) + h.price, err = decimal.NewFromString(ag.Price) if err != nil { return err } @@ -346,15 +343,15 @@ func (o *OrderCreate) SetPrice(ctx context.Context) error { if promotionPrice.Cmp(decimal.NewFromInt(0)) <= 0 { return fmt.Errorf("invalid price") } - o.price = promotionPrice + h.price = promotionPrice } return nil } -func (o *OrderCreate) SetCurrency(ctx context.Context) error { +func (h *createHandler) SetCurrency(ctx context.Context) error { curr, err := currvalmwcli.GetCurrencyOnly(ctx, &currvalmwpb.Conds{ - CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: o.PaymentCoinID}, + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, }) if err != nil { return err @@ -376,17 +373,17 @@ func (o *OrderCreate) SetCurrency(ctx context.Context) error { return fmt.Errorf("invalid market value") } - o.liveCurrency = val - o.coinCurrency = val + h.liveCurrency = val + h.coinCurrency = val apc, err := appcoinmwcli.GetCoinOnly(ctx, &appcoinmwpb.Conds{ AppID: &basetypes.StringVal{ Op: cruder.EQ, - Value: o.AppID, + Value: *h.AppID, }, CoinTypeID: &basetypes.StringVal{ Op: cruder.EQ, - Value: o.PaymentCoinID, + Value: *h.PaymentCoinID, }, }) if err != nil { @@ -401,7 +398,7 @@ func (o *OrderCreate) SetCurrency(ctx context.Context) error { return err } if currVal.Cmp(decimal.NewFromInt(0)) > 0 { - o.coinCurrency = currVal + h.coinCurrency = currVal } currVal, err = decimal.NewFromString(apc.MarketValue) @@ -409,66 +406,66 @@ func (o *OrderCreate) SetCurrency(ctx context.Context) error { return err } if currVal.Cmp(decimal.NewFromInt(0)) > 0 { - o.localCurrency = currVal + h.localCurrency = currVal } return nil } -func (o *OrderCreate) SetPaymentAmount(ctx context.Context) error { +func (h *createHandler) SetPaymentAmount(ctx context.Context) error { // TODO: also add sub good order payment amount - units, err := decimal.NewFromString(o.Units) + units, err := decimal.NewFromString(h.Units) if err != nil { return err } - o.paymentAmountUSD = o.price.Mul(units) + h.paymentAmountUSD = h.price.Mul(units) logger.Sugar().Infow( "CreateOrder", - "PaymentAmountUSD", o.paymentAmountUSD, - "ReductionAmount", o.reductionAmount, - "ReductionPercent", o.reductionPercent, + "PaymentAmountUSD", h.paymentAmountUSD, + "ReductionAmount", h.reductionAmount, + "ReductionPercent", h.reductionPercent, ) - o.paymentAmountUSD = o.price.Mul(units). - Sub(o.paymentAmountUSD. - Mul(o.reductionPercent). + h.paymentAmountUSD = h.price.Mul(units). + Sub(h.paymentAmountUSD. + Mul(h.reductionPercent). Div(decimal.NewFromInt(100))) //nolint - o.paymentAmountUSD = o.paymentAmountUSD.Sub(o.reductionAmount) + h.paymentAmountUSD = h.paymentAmountUSD.Sub(h.reductionAmount) - if o.paymentAmountUSD.Cmp(decimal.NewFromInt(0)) < 0 { - o.paymentAmountUSD = decimal.NewFromInt(0) + if h.paymentAmountUSD.Cmp(decimal.NewFromInt(0)) < 0 { + h.paymentAmountUSD = decimal.NewFromInt(0) } const accuracy = 1000000 - o.paymentAmountCoin = o.paymentAmountUSD.Div(o.coinCurrency) - o.paymentAmountCoin = o.paymentAmountCoin.Mul(decimal.NewFromInt(accuracy)) - o.paymentAmountCoin = o.paymentAmountCoin.Ceil() - o.paymentAmountCoin = o.paymentAmountCoin.Div(decimal.NewFromInt(accuracy)) + h.paymentAmountCoin = h.paymentAmountUSD.Div(h.coinCurrency) + h.paymentAmountCoin = h.paymentAmountCoin.Mul(decimal.NewFromInt(accuracy)) + h.paymentAmountCoin = h.paymentAmountCoin.Ceil() + h.paymentAmountCoin = h.paymentAmountCoin.Div(decimal.NewFromInt(accuracy)) - if o.BalanceAmount != nil { - amount, err := decimal.NewFromString(*o.BalanceAmount) + if h.BalanceAmount != nil { + amount, err := decimal.NewFromString(*h.BalanceAmount) if err != nil { return err } - if amount.Cmp(o.paymentAmountCoin) > 0 { - amount = o.paymentAmountCoin + if amount.Cmp(h.paymentAmountCoin) > 0 { + amount = h.paymentAmountCoin amountStr := amount.String() - o.BalanceAmount = &amountStr + h.BalanceAmount = &amountStr } - o.paymentAmountCoin = o.paymentAmountCoin.Sub(amount) + h.paymentAmountCoin = h.paymentAmountCoin.Sub(amount) } return nil } -func (o *OrderCreate) createAddresses(ctx context.Context) error { +func (h *createHandler) createAddresses(ctx context.Context) error { const createCount = 5 successCreated := 0 for i := 0; i < createCount; i++ { - address, err := sphinxproxycli.CreateAddress(ctx, o.paymentCoinName) + address, err := sphinxproxycli.CreateAddress(ctx, h.paymentCoinName) if err != nil { return err } @@ -477,7 +474,7 @@ func (o *OrderCreate) createAddresses(ctx context.Context) error { } _, err = payaccmwcli.CreateAccount(ctx, &payaccmwpb.AccountReq{ - CoinTypeID: &o.PaymentCoinID, + CoinTypeID: h.PaymentCoinID, Address: &address.Address, }) if err != nil { @@ -494,11 +491,11 @@ func (o *OrderCreate) createAddresses(ctx context.Context) error { return nil } -func (o *OrderCreate) peekAddress(ctx context.Context) (*payaccmwpb.Account, error) { +func (h *createHandler) peekAddress(ctx context.Context) (*payaccmwpb.Account, error) { payments, _, err := payaccmwcli.GetAccounts(ctx, &payaccmwpb.Conds{ CoinTypeID: &basetypes.StringVal{ Op: cruder.EQ, - Value: o.PaymentCoinID, + Value: *h.PaymentCoinID, }, Active: &basetypes.BoolVal{ Op: cruder.EQ, @@ -569,27 +566,27 @@ func (o *OrderCreate) peekAddress(ctx context.Context) (*payaccmwpb.Account, err return nil, nil } - o.goodPaymentID = account.ID + h.goodPaymentID = account.ID return account, nil } -func (o *OrderCreate) PeekAddress(ctx context.Context) error { - account, err := o.peekAddress(ctx) +func (h *createHandler) PeekAddress(ctx context.Context) error { + account, err := h.peekAddress(ctx) if err != nil { return err } if account != nil { - o.paymentAddress = account.Address - o.paymentAccountID = account.AccountID + h.paymentAddress = account.Address + h.paymentAccountID = account.AccountID return nil } - if err := o.createAddresses(ctx); err != nil { + if err := h.createAddresses(ctx); err != nil { return err } - account, err = o.peekAddress(ctx) + account, err = h.peekAddress(ctx) if err != nil { return err } @@ -597,32 +594,32 @@ func (o *OrderCreate) PeekAddress(ctx context.Context) error { return fmt.Errorf("fail peek address") } - o.paymentAddress = account.Address - o.paymentAccountID = account.AccountID + h.paymentAddress = account.Address + h.paymentAccountID = account.AccountID return nil } -func (o *OrderCreate) ReleaseAddress(ctx context.Context) error { - if err := accountlock.Lock(o.paymentAccountID); err != nil { +func (h *createHandler) ReleaseAddress(ctx context.Context) error { + if err := accountlock.Lock(h.paymentAccountID); err != nil { return err } locked := false _, err := payaccmwcli.UpdateAccount(ctx, &payaccmwpb.AccountReq{ - ID: &o.goodPaymentID, + ID: &h.goodPaymentID, Locked: &locked, }) - accountlock.Unlock(o.paymentAccountID) //nolint + accountlock.Unlock(h.paymentAccountID) //nolint return err } -func (o *OrderCreate) SetBalance(ctx context.Context) error { +func (h *createHandler) SetBalance(ctx context.Context) error { balance, err := sphinxproxycli.GetBalance(ctx, &sphinxproxypb.GetBalanceRequest{ - Name: o.paymentCoinName, - Address: o.paymentAddress, + Name: h.paymentCoinName, + Address: h.paymentAddress, }) if err != nil { return err @@ -631,20 +628,20 @@ func (o *OrderCreate) SetBalance(ctx context.Context) error { return fmt.Errorf("invalid balance") } - o.paymentAddressStartAmount, err = decimal.NewFromString(balance.BalanceStr) + h.paymentAddressStartAmount, err = decimal.NewFromString(balance.BalanceStr) return err } -func (o *OrderCreate) createSubOrder(ctx context.Context) error { //nolint +func (h *createHandler) createSubOrder(ctx context.Context) error { //nolint // TODO: create sub order according to good's must select sub good return nil } -func (o *OrderCreate) LockStock(ctx context.Context) error { +func (h *createHandler) LockStock(ctx context.Context) error { _, err := goodmwcli.UpdateGood(ctx, &goodmwpb.GoodReq{ - ID: &o.GoodID, - Locked: &o.Units, + ID: h.GoodID, + Locked: &h.Units, }) if err != nil { return err @@ -652,14 +649,14 @@ func (o *OrderCreate) LockStock(ctx context.Context) error { return nil } -func (o *OrderCreate) ReleaseStock(ctx context.Context) error { - units, err := decimal.NewFromString(o.Units) +func (h *createHandler) ReleaseStock(ctx context.Context) error { + units, err := decimal.NewFromString(h.Units) if err != nil { return err } unitsStr := units.Neg().String() _, err = goodmwcli.UpdateGood(ctx, &goodmwpb.GoodReq{ - ID: &o.GoodID, + ID: h.GoodID, Locked: &unitsStr, }) if err != nil { @@ -668,12 +665,12 @@ func (o *OrderCreate) ReleaseStock(ctx context.Context) error { return nil } -func (o *OrderCreate) LockBalance(ctx context.Context) error { - if o.BalanceAmount == nil { +func (h *createHandler) LockBalance(ctx context.Context) error { + if h.BalanceAmount == nil { return nil } - ba, err := decimal.NewFromString(*o.BalanceAmount) + ba, err := decimal.NewFromString(*h.BalanceAmount) if err != nil { return err } @@ -685,15 +682,15 @@ func (o *OrderCreate) LockBalance(ctx context.Context) error { general, err := ledgermgrcli.GetGeneralOnly(ctx, &ledgermgrpb.Conds{ AppID: &commonpb.StringVal{ Op: cruder.EQ, - Value: o.AppID, + Value: *h.AppID, }, UserID: &commonpb.StringVal{ Op: cruder.EQ, - Value: o.UserID, + Value: *h.UserID, }, CoinTypeID: &commonpb.StringVal{ Op: cruder.EQ, - Value: o.PaymentCoinID, + Value: *h.PaymentCoinID, }, }) if err != nil { @@ -712,26 +709,26 @@ func (o *OrderCreate) LockBalance(ctx context.Context) error { return fmt.Errorf("insufficient balance") } - spendableMinus := fmt.Sprintf("-%v", *o.BalanceAmount) + spendableMinus := fmt.Sprintf("-%v", *h.BalanceAmount) _, err = ledgermgrcli.AddGeneral(ctx, &ledgermgrpb.GeneralReq{ ID: &general.ID, AppID: &general.AppID, UserID: &general.UserID, CoinTypeID: &general.CoinTypeID, - Locked: o.BalanceAmount, + Locked: h.BalanceAmount, Spendable: &spendableMinus, }) return err } -func (o *OrderCreate) ReleaseBalance(ctx context.Context) error { - if o.BalanceAmount == nil { +func (h *createHandler) ReleaseBalance(ctx context.Context) error { + if h.BalanceAmount == nil { return nil } - ba, err := decimal.NewFromString(*o.BalanceAmount) + ba, err := decimal.NewFromString(*h.BalanceAmount) if err != nil { return err } @@ -743,15 +740,15 @@ func (o *OrderCreate) ReleaseBalance(ctx context.Context) error { general, err := ledgermgrcli.GetGeneralOnly(ctx, &ledgermgrpb.Conds{ AppID: &commonpb.StringVal{ Op: cruder.EQ, - Value: o.AppID, + Value: *h.AppID, }, UserID: &commonpb.StringVal{ Op: cruder.EQ, - Value: o.UserID, + Value: *h.UserID, }, CoinTypeID: &commonpb.StringVal{ Op: cruder.EQ, - Value: o.PaymentCoinID, + Value: *h.PaymentCoinID, }, }) if err != nil { @@ -761,7 +758,7 @@ func (o *OrderCreate) ReleaseBalance(ctx context.Context) error { return fmt.Errorf("insufficuent funds") } - lockedMinus := fmt.Sprintf("-%v", o.BalanceAmount) + lockedMinus := fmt.Sprintf("-%v", h.BalanceAmount) _, err = ledgermgrcli.AddGeneral(ctx, &ledgermgrpb.GeneralReq{ ID: &general.ID, @@ -769,7 +766,7 @@ func (o *OrderCreate) ReleaseBalance(ctx context.Context) error { UserID: &general.UserID, CoinTypeID: &general.CoinTypeID, Locked: &lockedMinus, - Spendable: o.BalanceAmount, + Spendable: h.BalanceAmount, }) return err @@ -781,69 +778,125 @@ func tomorrowStart() time.Time { return time.Date(y, m, d+1, 0, 0, 0, 0, now.Location()) } -func (o *OrderCreate) Create(ctx context.Context) (*npool.Order, error) { - switch o.OrderType.String() { - case ordermgrpb.OrderType_Normal.String(): - case ordermgrpb.OrderType_Offline.String(): - case ordermgrpb.OrderType_Airdrop.String(): +func (h *createHandler) create(ctx context.Context) (*npool.Order, error) { + switch *h.OrderType { + case ordertypes.OrderType_Normal: + case ordertypes.OrderType_Offline: + case ordertypes.OrderType_Airdrop: default: return nil, fmt.Errorf("invalid order type") } - paymentAmount := o.paymentAmountCoin.String() - startAmount := o.paymentAddressStartAmount.String() - coinCurrency := o.coinCurrency.String() - liveCurrency := o.liveCurrency.String() - localCurrency := o.localCurrency.String() + paymentAmount := h.paymentAmountCoin.String() + startAmount := h.paymentAddressStartAmount.String() + coinCurrency := h.coinCurrency.String() + liveCurrency := h.liveCurrency.String() + localCurrency := h.localCurrency.String() // Top order never pay with parent, only sub order may - o.start = uint32(tomorrowStart().Unix()) - if o.GoodStartAt > o.start { - o.start = o.GoodStartAt + h.start = uint32(tomorrowStart().Unix()) + if h.GoodStartAt > h.start { + h.start = h.GoodStartAt } const secondsPerDay = 24 * 60 * 60 - o.end = o.start + o.GoodDurationDays*secondsPerDay + h.end = h.start + h.GoodDurationDays*secondsPerDay logger.Sugar().Infow( "CreateOrder", - "PaymentAmountUSD", o.paymentAmountUSD, - "PaymentAmountCoin", o.paymentAmountCoin, - "BalanceAmount", o.BalanceAmount, - "ReductionAmount", o.reductionAmount, - "ReductionPercent", o.reductionPercent, - "PaymentAddressStartAmount", o.paymentAddressStartAmount, - "CoinCurrency", o.coinCurrency, - "LiveCurrency", o.liveCurrency, - "LocalCurrency", o.localCurrency, + "PaymentAmountUSD", h.paymentAmountUSD, + "PaymentAmountCoin", h.paymentAmountCoin, + "BalanceAmount", h.BalanceAmount, + "ReductionAmount", h.reductionAmount, + "ReductionPercent", h.reductionPercent, + "PaymentAddressStartAmount", h.paymentAddressStartAmount, + "CoinCurrency", h.coinCurrency, + "LiveCurrency", h.liveCurrency, + "LocalCurrency", h.localCurrency, ) ord, err := ordermwcli.CreateOrder(ctx, &ordermwpb.OrderReq{ - AppID: &o.AppID, - UserID: &o.UserID, - GoodID: &o.GoodID, - Units: &o.Units, - OrderType: &o.OrderType, - ParentOrderID: o.ParentOrderID, - PaymentCoinID: &o.PaymentCoinID, - PayWithBalanceAmount: o.BalanceAmount, - PaymentAccountID: &o.paymentAccountID, + AppID: h.AppID, + UserID: h.UserID, + GoodID: h.GoodID, + Units: &h.Units, + OrderType: h.OrderType, + ParentOrderID: h.ParentOrderID, + PaymentCoinID: h.PaymentCoinID, + PayWithBalanceAmount: h.BalanceAmount, + PaymentAccountID: &h.paymentAccountID, PaymentAmount: &paymentAmount, PaymentAccountStartAmount: &startAmount, PaymentCoinUSDCurrency: &coinCurrency, PaymentLiveUSDCurrency: &liveCurrency, PaymentLocalUSDCurrency: &localCurrency, - FixAmountID: o.FixAmountID, - DiscountID: o.DiscountID, - SpecialOfferID: o.SpecialOfferID, - Start: &o.start, - End: &o.end, - PromotionID: o.promotionID, - CouponIDs: o.CouponIDs, + FixAmountID: h.FixAmountID, + DiscountID: h.DiscountID, + SpecialOfferID: h.SpecialOfferID, + Start: &h.start, + End: &h.end, + PromotionID: h.promotionID, + CouponIDs: h.CouponIDs, }) if err != nil { return nil, err } + h.ID = &ord.ID + + return h.GetOrder(ctx) +} + +func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error) { + handler := &createHandler{ + Handler: h, + } + if err := handler.validateInit(ctx); err != nil { + return nil, err + } + + if err := handler.SetReduction(ctx); err != nil { + return nil, err + } + + if err := handler.SetPrice(ctx); err != nil { + return nil, err + } + + if err := handler.SetCurrency(ctx); err != nil { + return nil, err + } + + if err := handler.SetPaymentAmount(ctx); err != nil { + return nil, err + } + + if err := handler.PeekAddress(ctx); err != nil { + return nil, err + } + + if err := handler.SetBalance(ctx); err != nil { + _ = handler.ReleaseAddress(ctx) + return nil, err + } + + if err := handler.LockStock(ctx); err != nil { + _ = handler.ReleaseAddress(ctx) + return nil, err + } + + if err := handler.LockBalance(ctx); err != nil { + _ = handler.ReleaseAddress(ctx) + _ = handler.ReleaseStock(ctx) + return nil, err + } + + ord, err := handler.create(ctx) + if err != nil { + _ = handler.ReleaseAddress(ctx) + _ = handler.ReleaseStock(ctx) + _ = handler.ReleaseBalance(ctx) + return nil, err + } - return GetOrder(ctx, ord.ID) + return ord, nil } diff --git a/pkg/order/handler.go b/pkg/order/handler.go new file mode 100644 index 0000000..c299b6d --- /dev/null +++ b/pkg/order/handler.go @@ -0,0 +1,286 @@ +package order + +import ( + "context" + "fmt" + + appmwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/app" + appusermwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" + ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" + constant "github.com/NpoolPlatform/order-gateway/pkg/const" + "github.com/shopspring/decimal" + + "github.com/google/uuid" +) + +type Handler struct { + ID *string + AppID *string + UserID *string + GoodID *string + Units string + PaymentCoinID *string + ParentOrderID *string + PayWithBalanceAmount *string + FixAmountID *string + DiscountID *string + SpecialOfferID *string + OrderType *ordertypes.OrderType + CouponIDs []string + Canceled *bool + FromAdmin bool + PaymentID *string + Offset int32 + Limit int32 +} + +func NewHandler(ctx context.Context, options ...func(context.Context, *Handler) error) (*Handler, error) { + handler := &Handler{} + for _, opt := range options { + if err := opt(ctx, handler); err != nil { + return nil, err + } + } + return handler, nil +} + +func WithID(id *string) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if id == nil { + return nil + } + if _, err := uuid.Parse(*id); err != nil { + return err + } + h.ID = id + return nil + } +} + +func WithAppID(appID *string) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if appID == nil { + return nil + } + if _, err := uuid.Parse(*appID); err != nil { + return err + } + exist, err := appmwcli.ExistApp(ctx, *appID) + if err != nil { + return err + } + if !exist { + return fmt.Errorf("invalid app") + } + h.AppID = appID + return nil + } +} + +func WithUserID(appID, userID *string) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if appID == nil || userID == nil { + return nil + } + _, err := uuid.Parse(*userID) + if err != nil { + return err + } + exist, err := appusermwcli.ExistUser(ctx, *appID, *userID) + if err != nil { + return err + } + if !exist { + return fmt.Errorf("invalid user") + } + + h.UserID = userID + return nil + } +} + +func WithGoodID(id *string) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if id == nil { + return nil + } + _, err := uuid.Parse(*id) + if err != nil { + return err + } + h.GoodID = id + return nil + } +} + +func WithPaymentCoinID(id *string) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if id == nil { + return nil + } + _, err := uuid.Parse(*id) + if err != nil { + return err + } + h.PaymentCoinID = id + return nil + } +} + +func WithParentOrderID(id *string) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if id == nil { + return nil + } + _, err := uuid.Parse(*id) + if err != nil { + return err + } + h.ParentOrderID = id + return nil + } +} + +func WithFixAmountID(id *string) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if id == nil { + return nil + } + _, err := uuid.Parse(*id) + if err != nil { + return err + } + h.FixAmountID = id + return nil + } +} + +func WithDiscountID(id *string) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if id == nil { + return nil + } + _, err := uuid.Parse(*id) + if err != nil { + return err + } + h.DiscountID = id + return nil + } +} + +func WithSpecialOfferID(id *string) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if id == nil { + return nil + } + _, err := uuid.Parse(*id) + if err != nil { + return err + } + h.SpecialOfferID = id + return nil + } +} + +func WithUnits(amount string) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + _, err := decimal.NewFromString(amount) + if err != nil { + return err + } + h.Units = amount + return nil + } +} + +func WithPayWithBalanceAmount(amount string) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + _, err := decimal.NewFromString(amount) + if err != nil { + return err + } + h.PayWithBalanceAmount = &amount + return nil + } +} + +func WithCouponIDs(couponIDs []string) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if len(couponIDs) == 0 { + return nil + } + for _, id := range couponIDs { + if _, err := uuid.Parse(id); err != nil { + return err + } + } + h.CouponIDs = couponIDs + return nil + } +} + +func WithCanceled(value *bool) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if value == nil { + return nil + } + h.Canceled = value + return nil + } +} + +func WithFromAdmin(value bool) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + h.FromAdmin = value + return nil + } +} + +func WithPaymentID(id *string) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if id == nil { + return nil + } + _, err := uuid.Parse(*id) + if err != nil { + return err + } + h.PaymentID = id + return nil + } +} + +func WithOrderType(orderType *ordertypes.OrderType) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if orderType == nil { + return nil + } + switch *orderType { + case ordertypes.OrderType_Airdrop: + case ordertypes.OrderType_Offline: + case ordertypes.OrderType_Normal: + default: + return fmt.Errorf("invalid order type") + } + h.OrderType = orderType + return nil + } +} + +func WithOffset(offset int32) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + h.Offset = offset + return nil + } +} + +func WithLimit(limit int32) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if limit == 0 { + limit = constant.DefaultRowLimit + } + h.Limit = limit + return nil + } +} diff --git a/pkg/order/order.go b/pkg/order/order.go deleted file mode 100644 index 053a9dd..0000000 --- a/pkg/order/order.go +++ /dev/null @@ -1,122 +0,0 @@ -package order - -import ( - "context" - "fmt" - - ordermgrpb "github.com/NpoolPlatform/message/npool/order/mgr/v1/order" - ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" - ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" - - npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" -) - -func CreateOrder(ctx context.Context, op *OrderCreate) (info *npool.Order, err error) { - if err := op.ValidateInit(ctx); err != nil { - return nil, err - } - - if err := op.SetReduction(ctx); err != nil { - return nil, err - } - - if err := op.SetPrice(ctx); err != nil { - return nil, err - } - - if err := op.SetCurrency(ctx); err != nil { - return nil, err - } - - if err := op.SetPaymentAmount(ctx); err != nil { - return nil, err - } - - if err := op.PeekAddress(ctx); err != nil { - return nil, err - } - - if err := op.SetBalance(ctx); err != nil { - _ = op.ReleaseAddress(ctx) - return nil, err - } - - if err := op.LockStock(ctx); err != nil { - _ = op.ReleaseAddress(ctx) - return nil, err - } - - if err := op.LockBalance(ctx); err != nil { - _ = op.ReleaseAddress(ctx) - _ = op.ReleaseStock(ctx) - return nil, err - } - - ord, err := op.Create(ctx) - if err != nil { - _ = op.ReleaseAddress(ctx) - _ = op.ReleaseStock(ctx) - _ = op.ReleaseBalance(ctx) - return nil, err - } - - return ord, nil -} - -//nolint:gocyclo -func UpdateOrder(ctx context.Context, in *ordermwpb.OrderReq, fromAdmin bool) (*npool.Order, error) { - ord, err := ordermwcli.GetOrder(ctx, in.GetID()) - if err != nil { - return nil, err - } - if ord == nil { - return nil, fmt.Errorf("invalid order") - } - - if in.GetAppID() != ord.AppID || in.GetUserID() != ord.UserID { - return nil, fmt.Errorf("permission denied") - } - if !in.GetCanceled() { - return GetOrder(ctx, ord.ID) - } - - switch ord.OrderState { - case ordermgrpb.OrderState_WaitPayment: - if fromAdmin && ord.OrderType == ordermgrpb.OrderType_Normal { - return nil, fmt.Errorf("permission denied") - } - ord, err = ordermwcli.UpdateOrder(ctx, in) - if err != nil { - return nil, err - } - return GetOrder(ctx, ord.ID) - case ordermgrpb.OrderState_Paid: - case ordermgrpb.OrderState_InService: - default: - return nil, fmt.Errorf("order state uncancellable") - } - - switch ord.OrderType { - case ordermgrpb.OrderType_Normal: - if err := cancelNormalOrder(ctx, ord); err != nil { - return nil, err - } - case ordermgrpb.OrderType_Offline: - if !fromAdmin { - return nil, fmt.Errorf("permission denied") - } - if err := cancelOfflineOrder(ctx, ord); err != nil { - return nil, err - } - case ordermgrpb.OrderType_Airdrop: - if !fromAdmin { - return nil, fmt.Errorf("permission denied") - } - if err := cancelAirdropOrder(ctx, ord); err != nil { - return nil, err - } - default: - return nil, fmt.Errorf("order type uncancellable") - } - return GetOrder(ctx, ord.ID) -} diff --git a/pkg/order/query.go b/pkg/order/query.go index d72395b..5cd45d6 100644 --- a/pkg/order/query.go +++ b/pkg/order/query.go @@ -37,234 +37,32 @@ import ( "github.com/google/uuid" ) -var invalidID = uuid.UUID{}.String() - -func GetOrder(ctx context.Context, id string) (*npool.Order, error) { //nolint - ord, err := ordercli.GetOrder(ctx, id) - if err != nil { - return nil, err - } - if ord == nil { - return nil, err - } - - o := &npool.Order{ - ID: ord.ID, - AppID: ord.AppID, - UserID: ord.UserID, - GoodID: ord.GoodID, - Units: ord.Units, - - ParentOrderID: ord.ParentOrderID, - ParentOrderGoodID: ord.ParentOrderGoodID, - - PaymentID: ord.PaymentID, - PaymentCoinTypeID: ord.PaymentCoinTypeID, - PaymentCoinUSDCurrency: ord.PaymentCoinUSDCurrency, - PaymentLiveUSDCurrency: ord.PaymentLiveUSDCurrency, - PaymentLocalUSDCurrency: ord.PaymentLocalUSDCurrency, - PaymentAmount: ord.PaymentAmount, - PaymentStartAmount: ord.PaymentStartAmount, - PaymentFinishAmount: ord.PaymentFinishAmount, - PayWithParent: ord.PayWithParent, - PayWithBalanceAmount: ord.PayWithBalanceAmount, - - FixAmountID: ord.FixAmountID, - DiscountID: ord.DiscountID, - SpecialOfferID: ord.SpecialOfferID, - - OrderType: ord.OrderType, - CreatedAt: ord.CreatedAt, - PaidAt: ord.PaidAt, - State: ord.OrderState, - - Start: ord.Start, - End: ord.End, - } - - user, err := usermwcli.GetUser(ctx, ord.AppID, ord.UserID) - if err != nil { - return nil, err - } - - if user == nil { - return nil, fmt.Errorf("invalid user") - } - - o.EmailAddress = user.EmailAddress - o.PhoneNO = user.PhoneNO - - appGood, err := appgoodscli.GetGoodOnly(ctx, &appgoodsmgrpb.Conds{ - AppID: &commonpb.StringVal{ - Op: cruder.EQ, - Value: ord.AppID, - }, - GoodID: &commonpb.StringVal{ - Op: cruder.EQ, - Value: ord.GoodID, - }, - }) - if err != nil { - return nil, err - } - - if appGood == nil { - return nil, fmt.Errorf("invalid app good") - } - - o.GoodName = appGood.GoodName - o.GoodUnit = appGood.Unit - o.GoodServicePeriodDays = uint32(appGood.DurationDays) - o.GoodUnitPrice = appGood.Price - - appGoodPrice, err := decimal.NewFromString(appGood.Price) - if err != nil { - return nil, err - } - units, err := decimal.NewFromString(ord.Units) - if err != nil { - return nil, err - } - o.GoodValue = appGoodPrice.Mul(units).String() - if appGood.PromotionPrice != nil { - appGoodPromotionPrice, err := decimal.NewFromString(*appGood.PromotionPrice) - if err != nil { - return nil, err - } - o.GoodValue = appGoodPromotionPrice.Mul(units).String() - } - - coin, err := coininfocli.GetCoin(ctx, appGood.CoinTypeID) - if err != nil { - return nil, err - } - - if coin == nil { - return nil, fmt.Errorf("invalid good coin") - } - - o.CoinTypeID = appGood.CoinTypeID - o.CoinName = coin.Name - o.CoinLogo = coin.Logo - o.CoinUnit = coin.Unit - o.CoinPresale = coin.Presale - - if ord.PaymentID != invalidID && ord.PaymentID != "" { - coin, err = coininfocli.GetCoin(ctx, ord.PaymentCoinTypeID) - if err != nil { - return nil, err - } - - if coin == nil { - return nil, fmt.Errorf("invalid payment coin") - } - } - - if coin != nil { - o.PaymentCoinName = coin.Name - o.PaymentCoinLogo = coin.Logo - o.PaymentCoinUnit = coin.Unit - } - - account, err := payaccmwcli.GetAccountOnly(ctx, &payaccmwpb.Conds{ - AccountID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: ord.PaymentAccountID, - }, - }) - if err != nil { - return nil, err - } - if account != nil { - o.PaymentAddress = account.Address - } - - coupons, _, err := allocatedmwcli.GetCoupons(ctx, &allocatedmwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: ord.AppID}, - IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: ord.CouponIDs}, - }, int32(0), int32(len(ord.CouponIDs))) - if err != nil { - return nil, err - } - - couponMap := map[string]*allocatedmwpb.Coupon{} - for _, coup := range coupons { - couponMap[coup.ID] = coup - } - - for _, id := range ord.CouponIDs { - coup, ok := couponMap[id] - if !ok { - continue - } - - o.Coupons = append(o.Coupons, &npool.Coupon{ - CouponID: id, - CouponType: coup.CouponType, - CouponName: coup.CouponName, - CouponValue: coup.Denomination, - }) - } - - return o, nil +type queryHandler struct { + *Handler + conds *ordermwpb.Conds + mwOrders []*ordermwpb.Order + orders []*npool.Order } -func GetOrders(ctx context.Context, appID, userID string, offset, limit int32) ([]*npool.Order, uint32, error) { - ords, total, err := ordercli.GetOrders(ctx, &ordermwpb.Conds{ - AppID: &commonpb.StringVal{ - Op: cruder.EQ, - Value: appID, - }, - UserID: &commonpb.StringVal{ - Op: cruder.EQ, - Value: userID, - }, - }, offset, limit) - if err != nil { - return nil, 0, err - } - if len(ords) == 0 { - return []*npool.Order{}, 0, nil - } - - orders, err := expand(ctx, ords, appID) - if err != nil { - return nil, 0, err - } - - return orders, total, nil -} +var invalidID = uuid.UUID{}.String() -func GetAppOrders(ctx context.Context, appID string, offset, limit int32) ([]*npool.Order, uint32, error) { - ords, total, err := ordercli.GetOrders(ctx, &ordermwpb.Conds{ - AppID: &commonpb.StringVal{ - Op: cruder.EQ, - Value: appID, - }, - }, offset, limit) - if err != nil { - return nil, 0, err +func (h *queryHandler) setConds() { + conds := &ordermwpb.Conds{} + if h.AppID != nil { + conds.AppID = &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID} } - if len(ords) == 0 { - return []*npool.Order{}, 0, nil + if h.UserID != nil { + conds.UserID = &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID} } - - orders, err := expand(ctx, ords, appID) - if err != nil { - return nil, 0, err - } - - return orders, total, nil + h.conds = conds } -// nolint -func expand(ctx context.Context, ords []*ordermwpb.Order, appID string) ([]*npool.Order, error) { - if len(ords) == 0 { - return []*npool.Order{}, nil +func (h *queryHandler) expand(ctx context.Context) error { //nolint + if len(h.mwOrders) == 0 { + return nil } - uids := []string{} - for _, ord := range ords { + for _, ord := range h.mwOrders { uids = append(uids, ord.UserID) } @@ -272,10 +70,10 @@ func expand(ctx context.Context, ords []*ordermwpb.Order, appID string) ([]*npoo IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: uids}, }, 0, int32(len(uids))) if err != nil { - return nil, err + return err } if len(users) == 0 { - return nil, fmt.Errorf("invalid users") + return fmt.Errorf("invalid users") } userMap := map[string]*usermwpb.User{} @@ -284,12 +82,12 @@ func expand(ctx context.Context, ords []*ordermwpb.Order, appID string) ([]*npoo } goodIDs := []string{} - for _, val := range ords { + for _, val := range h.mwOrders { goodIDs = append(goodIDs, val.GetGoodID()) } accIDs := []string{} - for _, ord := range ords { + for _, ord := range h.mwOrders { if _, err := uuid.Parse(ord.PaymentAccountID); err != nil { continue } @@ -303,7 +101,7 @@ func expand(ctx context.Context, ords []*ordermwpb.Order, appID string) ([]*npoo }, }, 0, int32(len(accIDs))) if err != nil { - return nil, err + return err } accMap := map[string]*payaccmwpb.Account{} @@ -312,16 +110,16 @@ func expand(ctx context.Context, ords []*ordermwpb.Order, appID string) ([]*npoo } ids := []string{} - for _, ord := range ords { + for _, ord := range h.mwOrders { ids = append(ids, ord.CouponIDs...) } coupons, _, err := allocatedmwcli.GetCoupons(ctx, &allocatedmwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: appID}, + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: ids}, }, int32(0), int32(len(ids))) if err != nil { - return nil, err + return err } couponMap := map[string]*allocatedmwpb.Coupon{} @@ -336,14 +134,14 @@ func expand(ctx context.Context, ords []*ordermwpb.Order, appID string) ([]*npoo }, AppID: &commonpb.StringVal{ Op: cruder.IN, - Value: appID, + Value: *h.AppID, }, }, 0, int32(len(goodIDs))) if err != nil { - return nil, err + return err } - fmt.Printf("goodIDs: %v, appID %v, appGoods %v | %v\n", goodIDs, appID, len(appGoods), appGoods) + fmt.Printf("goodIDs: %v, appID %v, appGoods %v | %v\n", goodIDs, h.AppID, len(appGoods), appGoods) appGoodMap := map[string]*appgoodspb.Good{} for _, appGood := range appGoods { @@ -351,7 +149,7 @@ func expand(ctx context.Context, ords []*ordermwpb.Order, appID string) ([]*npoo } coinTypeIDs := []string{} - for _, val := range ords { + for _, val := range h.mwOrders { if _, err := uuid.Parse(val.PaymentCoinTypeID); err != nil { continue } @@ -367,7 +165,7 @@ func expand(ctx context.Context, ords []*ordermwpb.Order, appID string) ([]*npoo coins, _, err := appcoinmwcli.GetCoins(ctx, &appcoinmwpb.Conds{ AppID: &basetypes.StringVal{ Op: cruder.EQ, - Value: appID, + Value: *h.AppID, }, CoinTypeIDs: &basetypes.StringSliceVal{ Op: cruder.IN, @@ -375,7 +173,7 @@ func expand(ctx context.Context, ords []*ordermwpb.Order, appID string) ([]*npoo }, }, 0, int32(len(coinTypeIDs))) if err != nil { - return nil, err + return err } coinMap := map[string]*appcoinmwpb.Coin{} @@ -385,7 +183,7 @@ func expand(ctx context.Context, ords []*ordermwpb.Order, appID string) ([]*npoo infos := []*npool.Order{} - for _, ord := range ords { + for _, ord := range h.mwOrders { o := &npool.Order{ ID: ord.ID, AppID: ord.AppID, @@ -444,18 +242,18 @@ func expand(ctx context.Context, ords []*ordermwpb.Order, appID string) ([]*npoo appGoodPrice, err := decimal.NewFromString(appGood.Price) if err != nil { - return nil, err + return err } units, err := decimal.NewFromString(ord.Units) if err != nil { - return nil, err + return err } o.GoodValue = appGoodPrice.Mul(units).String() if appGood.PromotionPrice != nil { appGoodPromotionPrice, err := decimal.NewFromString(*appGood.PromotionPrice) if err != nil { - return nil, err + return err } o.GoodValue = appGoodPromotionPrice.Mul(units).String() } @@ -505,6 +303,198 @@ func expand(ctx context.Context, ords []*ordermwpb.Order, appID string) ([]*npoo infos = append(infos, o) } + h.orders = infos + return nil +} + +func (h *Handler) GetOrder(ctx context.Context) (*npool.Order, error) { //nolint + ord, err := ordercli.GetOrder(ctx, *h.ID) + if err != nil { + return nil, err + } + if ord == nil { + return nil, err + } + + o := &npool.Order{ + ID: ord.ID, + AppID: ord.AppID, + UserID: ord.UserID, + GoodID: ord.GoodID, + Units: ord.Units, + + ParentOrderID: ord.ParentOrderID, + ParentOrderGoodID: ord.ParentOrderGoodID, + + PaymentID: ord.PaymentID, + PaymentCoinTypeID: ord.PaymentCoinTypeID, + PaymentCoinUSDCurrency: ord.PaymentCoinUSDCurrency, + PaymentLiveUSDCurrency: ord.PaymentLiveUSDCurrency, + PaymentLocalUSDCurrency: ord.PaymentLocalUSDCurrency, + PaymentAmount: ord.PaymentAmount, + PaymentStartAmount: ord.PaymentStartAmount, + PaymentFinishAmount: ord.PaymentFinishAmount, + PayWithParent: ord.PayWithParent, + PayWithBalanceAmount: ord.PayWithBalanceAmount, + + FixAmountID: ord.FixAmountID, + DiscountID: ord.DiscountID, + SpecialOfferID: ord.SpecialOfferID, + + OrderType: ord.OrderType, + CreatedAt: ord.CreatedAt, + PaidAt: ord.PaidAt, + State: ord.OrderState, + + Start: ord.Start, + End: ord.End, + } + + user, err := usermwcli.GetUser(ctx, ord.AppID, ord.UserID) + if err != nil { + return nil, err + } + + if user == nil { + return nil, fmt.Errorf("invalid user") + } + + o.EmailAddress = user.EmailAddress + o.PhoneNO = user.PhoneNO + + appGood, err := appgoodscli.GetGoodOnly(ctx, &appgoodsmgrpb.Conds{ + AppID: &commonpb.StringVal{ + Op: cruder.EQ, + Value: ord.AppID, + }, + GoodID: &commonpb.StringVal{ + Op: cruder.EQ, + Value: ord.GoodID, + }, + }) + if err != nil { + return nil, err + } + + if appGood == nil { + return nil, fmt.Errorf("invalid app good") + } + + o.GoodName = appGood.GoodName + o.GoodUnit = appGood.Unit + o.GoodServicePeriodDays = uint32(appGood.DurationDays) + o.GoodUnitPrice = appGood.Price + + appGoodPrice, err := decimal.NewFromString(appGood.Price) + if err != nil { + return nil, err + } + units, err := decimal.NewFromString(ord.Units) + if err != nil { + return nil, err + } + o.GoodValue = appGoodPrice.Mul(units).String() + if appGood.PromotionPrice != nil { + appGoodPromotionPrice, err := decimal.NewFromString(*appGood.PromotionPrice) + if err != nil { + return nil, err + } + o.GoodValue = appGoodPromotionPrice.Mul(units).String() + } + + coin, err := coininfocli.GetCoin(ctx, appGood.CoinTypeID) + if err != nil { + return nil, err + } + + if coin == nil { + return nil, fmt.Errorf("invalid good coin") + } + + o.CoinTypeID = appGood.CoinTypeID + o.CoinName = coin.Name + o.CoinLogo = coin.Logo + o.CoinUnit = coin.Unit + o.CoinPresale = coin.Presale + + if ord.PaymentID != invalidID && ord.PaymentID != "" { + coin, err = coininfocli.GetCoin(ctx, ord.PaymentCoinTypeID) + if err != nil { + return nil, err + } + + if coin == nil { + return nil, fmt.Errorf("invalid payment coin") + } + } + + if coin != nil { + o.PaymentCoinName = coin.Name + o.PaymentCoinLogo = coin.Logo + o.PaymentCoinUnit = coin.Unit + } + + account, err := payaccmwcli.GetAccountOnly(ctx, &payaccmwpb.Conds{ + AccountID: &basetypes.StringVal{ + Op: cruder.EQ, + Value: ord.PaymentAccountID, + }, + }) + if err != nil { + return nil, err + } + if account != nil { + o.PaymentAddress = account.Address + } + + coupons, _, err := allocatedmwcli.GetCoupons(ctx, &allocatedmwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: ord.AppID}, + IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: ord.CouponIDs}, + }, int32(0), int32(len(ord.CouponIDs))) + if err != nil { + return nil, err + } + + couponMap := map[string]*allocatedmwpb.Coupon{} + for _, coup := range coupons { + couponMap[coup.ID] = coup + } + + for _, id := range ord.CouponIDs { + coup, ok := couponMap[id] + if !ok { + continue + } + + o.Coupons = append(o.Coupons, &npool.Coupon{ + CouponID: id, + CouponType: coup.CouponType, + CouponName: coup.CouponName, + CouponValue: coup.Denomination, + }) + } + + return o, nil +} + +func (h *Handler) GetOrders(ctx context.Context) ([]*npool.Order, uint32, error) { + handler := &queryHandler{ + Handler: h, + orders: []*npool.Order{}, + } + handler.setConds() + ords, total, err := ordercli.GetOrders(ctx, handler.conds, h.Offset, h.Limit) + if err != nil { + return nil, 0, err + } + if len(ords) == 0 { + return []*npool.Order{}, 0, nil + } + handler.mwOrders = ords + + if err := handler.expand(ctx); err != nil { + return nil, 0, err + } - return infos, nil + return handler.orders, total, nil } diff --git a/pkg/order/update.go b/pkg/order/update.go index 05d9f99..9c037cd 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -12,7 +12,6 @@ import ( "github.com/NpoolPlatform/libent-cruder/pkg/cruder" commonpb "github.com/NpoolPlatform/message/npool" - basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" "github.com/shopspring/decimal" @@ -20,32 +19,38 @@ import ( appgoodmwpb "github.com/NpoolPlatform/message/npool/good/mgr/v1/appgood" goodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good" - achievementmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/achievement" goodmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/good" - ordermgrpb "github.com/NpoolPlatform/message/npool/order/mgr/v1/order" - paymentmgrpb "github.com/NpoolPlatform/message/npool/order/mgr/v1/payment" ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" - statementmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/achievement/statement" - statementmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/achievement/statement" - ledgercli "github.com/NpoolPlatform/ledger-middleware/pkg/client/ledger/v2" ledgerdetailpb "github.com/NpoolPlatform/message/npool/ledger/mgr/v1/ledger/detail" + + achievementmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/achievement" + statementmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/achievement/statement" + ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" + basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" + statementmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/achievement/statement" + npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" ) +type updateHandler struct { + *Handler + ord *ordermwpb.Order +} + //nolint:gocyclo -func validateInit(ctx context.Context, ord *ordermwpb.Order) error { +func (h *updateHandler) validate(ctx context.Context) error { good, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodmwpb.Conds{ AppID: &commonpb.StringVal{ Op: cruder.EQ, - Value: ord.AppID, + Value: h.ord.AppID, }, GoodID: &commonpb.StringVal{ Op: cruder.EQ, - Value: ord.GoodID, + Value: h.ord.GoodID, }, }) if err != nil { @@ -58,7 +63,7 @@ func validateInit(ctx context.Context, ord *ordermwpb.Order) error { _, total, err := miningdetailcli.GetDetails(ctx, &miningdetailpb.Conds{ GoodID: &commonpb.StringVal{ Op: cruder.EQ, - Value: ord.GoodID, + Value: h.ord.GoodID, }, }, 0, 1) if err != nil { @@ -76,27 +81,27 @@ func validateInit(ctx context.Context, ord *ordermwpb.Order) error { case appgoodmwpb.CancelMode_Uncancellable: return fmt.Errorf("app good uncancellable") case appgoodmwpb.CancelMode_CancellableBeforeStart: - switch ord.OrderState { - case ordermgrpb.OrderState_WaitPayment: - case ordermgrpb.OrderState_Paid: + switch h.ord.OrderState { + case ordertypes.OrderState_OrderStateWaitPayment: + case ordertypes.OrderState_OrderStatePaid: default: return fmt.Errorf("order state is uncancellable") } - if uint32(time.Now().Unix()) >= ord.Start-good.CancellableBeforeStart { + if uint32(time.Now().Unix()) >= h.ord.Start-good.CancellableBeforeStart { return fmt.Errorf("cancellable time exceeded") } case appgoodmwpb.CancelMode_CancellableBeforeBenefit: - switch ord.OrderState { - case ordermgrpb.OrderState_WaitPayment: - case ordermgrpb.OrderState_Paid: - case ordermgrpb.OrderState_InService: + switch h.ord.OrderState { + case ordertypes.OrderState_OrderStateWaitPayment: + case ordertypes.OrderState_OrderStatePaid: + case ordertypes.OrderState_OrderStateInService: default: return fmt.Errorf("order state is uncancellable") } - if uint32(time.Now().Unix()) >= ord.Start-good.CancellableBeforeStart && - uint32(time.Now().Unix()) <= ord.Start+good.CancellableBeforeStart { + if uint32(time.Now().Unix()) >= h.ord.Start-good.CancellableBeforeStart && + uint32(time.Now().Unix()) <= h.ord.Start+good.CancellableBeforeStart { return fmt.Errorf("app good uncancellable order start at > cancellable before start") } default: @@ -105,21 +110,21 @@ func validateInit(ctx context.Context, ord *ordermwpb.Order) error { return nil } -func processStock(ctx context.Context, ord *ordermwpb.Order) error { - units, err := decimal.NewFromString(ord.Units) +func (h *updateHandler) processStock(ctx context.Context) error { + units, err := decimal.NewFromString(h.ord.Units) if err != nil { return err } unitsStr := units.Neg().String() stockReq := &goodmwpb.GoodReq{ - ID: &ord.GoodID, + ID: &h.ord.GoodID, } - switch ord.OrderState { - case ordermgrpb.OrderState_Paid: + switch h.ord.OrderState { + case ordertypes.OrderState_OrderStatePaid: stockReq.WaitStart = &unitsStr - case ordermgrpb.OrderState_InService: + case ordertypes.OrderState_OrderStateInService: stockReq.InService = &unitsStr } @@ -130,15 +135,15 @@ func processStock(ctx context.Context, ord *ordermwpb.Order) error { return nil } -func processOrderState(ctx context.Context, ord *ordermwpb.Order) error { +func (h *updateHandler) processOrderState(ctx context.Context) error { cancle := true - state := ordermgrpb.OrderState_Canceled - paymentState := paymentmgrpb.PaymentState_Canceled + state := ordertypes.OrderState_OrderStateCanceled + paymentState := ordertypes.PaymentState_PaymentStateCanceled _, err := ordermwcli.UpdateOrder(ctx, &ordermwpb.OrderReq{ - ID: &ord.ID, + ID: &h.ord.ID, State: &state, PaymentState: &paymentState, - PaymentID: &ord.PaymentID, + PaymentID: &h.ord.PaymentID, Canceled: &cancle, }) if err != nil { @@ -149,7 +154,7 @@ func processOrderState(ctx context.Context, ord *ordermwpb.Order) error { } //nolint:funlen -func processLedger(ctx context.Context, ord *ordermwpb.Order) error { +func (h *updateHandler) processLedger(ctx context.Context) error { offset := int32(0) limit := int32(1000) //nolint detailInfos := []*ledgerdetailpb.DetailReq{} @@ -160,7 +165,7 @@ func processLedger(ctx context.Context, ord *ordermwpb.Order) error { for { infos, _, err := statementmwcli.GetStatements(ctx, &statementmwpb.Conds{ - OrderID: &basetypes.StringVal{Op: cruder.EQ, Value: ord.ID}, + OrderID: &basetypes.StringVal{Op: cruder.EQ, Value: h.ord.ID}, }, offset, limit) if err != nil { return err @@ -199,7 +204,7 @@ func processLedger(ctx context.Context, ord *ordermwpb.Order) error { }, IOExtra: &commonpb.StringVal{ Op: cruder.LIKE, - Value: ord.ID, + Value: h.ord.ID, }, }, 0, 1) if err != nil { @@ -230,12 +235,12 @@ func processLedger(ctx context.Context, ord *ordermwpb.Order) error { } } - paymentAmount, err := decimal.NewFromString(ord.PaymentAmount) + paymentAmount, err := decimal.NewFromString(h.ord.PaymentAmount) if err != nil { return err } - payWithBalanceAmount, err := decimal.NewFromString(ord.PayWithBalanceAmount) + payWithBalanceAmount, err := decimal.NewFromString(h.ord.PayWithBalanceAmount) if err != nil { return err } @@ -244,17 +249,17 @@ func processLedger(ctx context.Context, ord *ordermwpb.Order) error { amount := paymentAmount.Add(payWithBalanceAmount).String() inIoExtra := fmt.Sprintf( `{"AppID":"%v","UserID":"%v","OrderID":"%v","Amount":"%v","Date":"%v"}`, - ord.AppID, - ord.UserID, - ord.ID, + h.ord.AppID, + h.ord.UserID, + h.ord.ID, amount, time.Now(), ) detailInfos = append(detailInfos, &ledgerdetailpb.DetailReq{ - AppID: &ord.AppID, - UserID: &ord.UserID, - CoinTypeID: &ord.PaymentCoinTypeID, + AppID: &h.ord.AppID, + UserID: &h.ord.UserID, + CoinTypeID: &h.ord.PaymentCoinTypeID, IOType: &in, IOSubType: &ioTypeOrder, Amount: &amount, @@ -272,66 +277,143 @@ func processLedger(ctx context.Context, ord *ordermwpb.Order) error { return nil } -func processArchivement(ctx context.Context, ord *ordermwpb.Order) error { - err := achievementmwcli.ExpropriateAchievement(ctx, ord.ID) +func (h *updateHandler) processArchivement(ctx context.Context) error { + err := achievementmwcli.ExpropriateAchievement(ctx, h.ord.ID) if err != nil { return err } return nil } -func cancelAirdropOrder(ctx context.Context, ord *ordermwpb.Order) error { - err := validateInit(ctx, ord) +func (h *updateHandler) cancelAirdropOrder(ctx context.Context) error { + err := h.validate(ctx) if err != nil { return err } - err = processStock(ctx, ord) + err = h.processStock(ctx) if err != nil { return err } // TODO Distributed transactions should be used - return processOrderState(ctx, ord) + return h.processOrderState(ctx) } -func cancelOfflineOrder(ctx context.Context, ord *ordermwpb.Order) error { - err := validateInit(ctx, ord) +func (h *updateHandler) cancelOfflineOrder(ctx context.Context) error { + err := h.validate(ctx) if err != nil { return err } // TODO Distributed transactions should be used - err = processStock(ctx, ord) + err = h.processStock(ctx) if err != nil { return err } - err = processOrderState(ctx, ord) + err = h.processOrderState(ctx) if err != nil { return err } - return processArchivement(ctx, ord) + return h.processArchivement(ctx) } -func cancelNormalOrder(ctx context.Context, ord *ordermwpb.Order) error { - err := validateInit(ctx, ord) +func (h *updateHandler) cancelNormalOrder(ctx context.Context) error { + err := h.validate(ctx) if err != nil { return err } - err = processStock(ctx, ord) + err = h.processStock(ctx) if err != nil { return err } - err = processOrderState(ctx, ord) + err = h.processOrderState(ctx) if err != nil { return err } - err = processLedger(ctx, ord) + err = h.processLedger(ctx) if err != nil { return err } - return processArchivement(ctx, ord) + return h.processArchivement(ctx) +} + +//nolint:gocyclo +func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { + if h.Canceled == nil { + return nil, fmt.Errorf("nothing todo") + } + if h.ID == nil || *h.ID == "" { + return nil, fmt.Errorf("id invalid") + } + + ord, err := ordermwcli.GetOrder(ctx, *h.ID) + if err != nil { + return nil, err + } + if ord == nil { + return nil, fmt.Errorf("invalid order") + } + + if *h.AppID != ord.AppID || *h.UserID != ord.UserID { + return nil, fmt.Errorf("permission denied") + } + if !*h.Canceled { + return h.GetOrder(ctx) + } + + handler := &updateHandler{ + Handler: h, + ord: ord, + } + + switch ord.OrderState { + case ordertypes.OrderState_OrderStateWaitPayment: + if h.FromAdmin && ord.OrderType == ordertypes.OrderType_Normal { + return nil, fmt.Errorf("permission denied") + } + _, err = ordermwcli.UpdateOrder(ctx, &ordermwpb.OrderReq{ + ID: h.ID, + AppID: h.AppID, + UserID: h.UserID, + PaymentID: h.PaymentID, + Canceled: h.Canceled, + }) + if err != nil { + return nil, err + } + return handler.GetOrder(ctx) + case ordertypes.OrderState_OrderStatePaid: + case ordertypes.OrderState_OrderStateInService: + default: + return nil, fmt.Errorf("order state uncancellable") + } + + switch ord.OrderType { + case ordertypes.OrderType_Normal: + if err := handler.cancelNormalOrder(ctx); err != nil { + return nil, err + } + case ordertypes.OrderType_Offline: + if !h.FromAdmin { + return nil, fmt.Errorf("permission denied") + } + if err := handler.cancelOfflineOrder(ctx); err != nil { + return nil, err + } + case ordertypes.OrderType_Airdrop: + if !h.FromAdmin { + return nil, fmt.Errorf("permission denied") + } + if err := handler.cancelAirdropOrder(ctx); err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("order type uncancellable") + } + + return handler.GetOrder(ctx) } From 6793bc4c6364f56705286deb437578bbadb5360a Mon Sep 17 00:00:00 2001 From: jakys Date: Wed, 23 Aug 2023 07:32:49 +0000 Subject: [PATCH 02/67] Fix update commit id --- api/order/create.go | 19 +++---- api/version.go | 6 +-- go.mod | 16 +++--- go.sum | 65 ++++++----------------- pkg/order/create.go | 72 ++++++++++++-------------- pkg/order/query.go | 37 +++++++------ pkg/order/update.go | 114 ++++++++++++++++++++--------------------- pkg/version/version.go | 6 +-- 8 files changed, 146 insertions(+), 189 deletions(-) diff --git a/api/order/create.go b/api/order/create.go index 38b7995..023cb23 100644 --- a/api/order/create.go +++ b/api/order/create.go @@ -4,22 +4,23 @@ package order import ( "context" - appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/appgood" + appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" + appgoodpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good" + "github.com/NpoolPlatform/libent-cruder/pkg/cruder" - commonpb "github.com/NpoolPlatform/message/npool" + ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" - appgoodpb "github.com/NpoolPlatform/message/npool/good/mgr/v1/appgood" - ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" - ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" + npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" + ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" order1 "github.com/NpoolPlatform/order-gateway/pkg/order" + ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "github.com/NpoolPlatform/go-service-framework/pkg/logger" - npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" "github.com/shopspring/decimal" ) @@ -49,7 +50,7 @@ func createOrder(ctx context.Context, in *npool.CreateOrderRequest) (*npool.Orde return nil, status.Error(codes.InvalidArgument, err.Error()) } - info, err := handler.UpdateOrder(ctx) + info, err := handler.CreateOrder(ctx) if err != nil { logger.Sugar().Errorw( "createOrder", @@ -64,11 +65,11 @@ func createOrder(ctx context.Context, in *npool.CreateOrderRequest) (*npool.Orde func (s *Server) CreateOrder(ctx context.Context, in *npool.CreateOrderRequest) (*npool.CreateOrderResponse, error) { ag, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodpb.Conds{ - AppID: &commonpb.StringVal{ + AppID: &basetypes.StringVal{ Op: cruder.EQ, Value: in.AppID, }, - GoodID: &commonpb.StringVal{ + GoodID: &basetypes.StringVal{ Op: cruder.EQ, Value: in.GoodID, }, diff --git a/api/version.go b/api/version.go index 366eeb3..485f984 100644 --- a/api/version.go +++ b/api/version.go @@ -7,18 +7,18 @@ import ( "context" "github.com/NpoolPlatform/go-service-framework/pkg/logger" - npool "github.com/NpoolPlatform/message/npool" + basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" "github.com/NpoolPlatform/order-gateway/pkg/version" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/emptypb" ) -func (s *Server) Version(ctx context.Context, in *emptypb.Empty) (*npool.VersionResponse, error) { +func (s *Server) Version(ctx context.Context, in *emptypb.Empty) (*basetypes.VersionResponse, error) { resp, err := version.Version() if err != nil { logger.Sugar().Errorw("[Version] get service version error: %w", err) - return &npool.VersionResponse{}, status.Error(codes.Internal, "internal server error") + return &basetypes.VersionResponse{}, status.Error(codes.Internal, "internal server error") } return resp, nil } diff --git a/go.mod b/go.mod index 5c4f73b..511cdf2 100644 --- a/go.mod +++ b/go.mod @@ -7,13 +7,13 @@ require ( github.com/NpoolPlatform/appuser-middleware v0.0.0-20230513100509-b19f356ebd4b github.com/NpoolPlatform/basal-middleware v0.0.0-20230518061816-62bd589c0f63 github.com/NpoolPlatform/chain-middleware v0.0.0-20230712041523-2e1d215244e0 - github.com/NpoolPlatform/go-service-framework v0.0.0-20230813055757-23d6ad3123fc - github.com/NpoolPlatform/good-middleware v0.0.0-20230811102318-3badbd5ab606 + github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e + github.com/NpoolPlatform/good-middleware v0.0.0-20230823034851-d6449a27f3e1 github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 - github.com/NpoolPlatform/ledger-middleware v0.0.0-20230303153851-9f5d1d78921a - github.com/NpoolPlatform/libent-cruder v0.0.0-20221109023947-366125b690fb - github.com/NpoolPlatform/message v0.0.0-20230815040303-b186df0b7f2b - github.com/NpoolPlatform/order-middleware v0.0.0-20230815061732-4d55ec9e8f2a + github.com/NpoolPlatform/ledger-middleware v0.0.0-20230823035222-525fd923c4df + github.com/NpoolPlatform/libent-cruder v0.0.0-20230822060122-512da6e5c8bf + github.com/NpoolPlatform/message v0.0.0-20230823033748-9a43fb49ad63 + github.com/NpoolPlatform/order-middleware v0.0.0-20230823034327-d4735e33c3c3 github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/go-resty/resty/v2 v2.7.0 github.com/google/uuid v1.3.0 @@ -53,7 +53,7 @@ require ( github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/inflect v0.19.0 // indirect - github.com/go-redis/redis/v8 v8.11.4 // indirect + github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-sql-driver/mysql v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.5.9 // indirect @@ -79,8 +79,6 @@ require ( github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/oklog/ulid v1.3.1 // indirect - github.com/onsi/ginkgo v1.16.5 // indirect - github.com/onsi/gomega v1.18.1 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect github.com/pkg/errors v0.9.1 // indirect diff --git a/go.sum b/go.sum index 5ad6581..34b04b3 100644 --- a/go.sum +++ b/go.sum @@ -56,22 +56,20 @@ github.com/NpoolPlatform/basal-middleware v0.0.0-20230518061816-62bd589c0f63 h1: github.com/NpoolPlatform/basal-middleware v0.0.0-20230518061816-62bd589c0f63/go.mod h1:3sHDVUUQHRkZsCiBFI6CdCL2HWf3cO7/E2DZU3nHMfE= github.com/NpoolPlatform/chain-middleware v0.0.0-20230712041523-2e1d215244e0 h1:xD+68nDsw/P0rXd1fzr/wip24bkpYzwrXGBFwSvXkbs= github.com/NpoolPlatform/chain-middleware v0.0.0-20230712041523-2e1d215244e0/go.mod h1:ExILdqBVnhspnOZFslJl0vTOc4Qyk78Lni1Kx2F8HGM= -github.com/NpoolPlatform/go-service-framework v0.0.0-20230813055757-23d6ad3123fc h1:SRg92xu81QsUSBDm9/zSUiy9PYTJvNwHxl6Rql9bWz0= -github.com/NpoolPlatform/go-service-framework v0.0.0-20230813055757-23d6ad3123fc/go.mod h1:Kh7DMkWnYOMHxEKq7QfJqbxm1HaUPkhTNN74lfHQxyE= -github.com/NpoolPlatform/good-manager v0.0.0-20230811101821-6d5ad0a7658b h1:jM/g1uu+6WSfJ7DNcQZfMKPaqTU5hxuh/vBuGhBjfyk= -github.com/NpoolPlatform/good-middleware v0.0.0-20230811102318-3badbd5ab606 h1:zCqygWHTusX6EaHc97tm69be75xvzz2hbj4lDB+GFWk= -github.com/NpoolPlatform/good-middleware v0.0.0-20230811102318-3badbd5ab606/go.mod h1:4T2pa46UtwqCbGSKYnTgViBtEoMA8oqWmtJFEKSt9Qc= +github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e h1:17BGexCmCdOOBXKYogP8RNE+pAHRu2N4LKq9znPJ4vc= +github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e/go.mod h1:Kh7DMkWnYOMHxEKq7QfJqbxm1HaUPkhTNN74lfHQxyE= +github.com/NpoolPlatform/good-middleware v0.0.0-20230823034851-d6449a27f3e1 h1:mCP1H+uT1IrlQ+ijrMZsBvRgFUQ/gC5v3+q5HZeLW14= +github.com/NpoolPlatform/good-middleware v0.0.0-20230823034851-d6449a27f3e1/go.mod h1:m0iZ5NxrwNXbkpAvqA/cjWGpzQAc5bPGfcOsPgO7KiQ= github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 h1:5W7RWU/meU1ZkPiUjqKAnyBKsjJ6NZu3dCfc0hgjhRs= github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2/go.mod h1:CCCI+S1AecMrRdRruOgMUxM9JaIXIYVt3DID04TuOoc= -github.com/NpoolPlatform/ledger-manager v0.0.0-20230301112903-ee77b010c928 h1:5iPksUQqw0ZuWOlR5IF48NFSPG2Uik7739AZ2+cQO54= -github.com/NpoolPlatform/ledger-middleware v0.0.0-20230303153851-9f5d1d78921a h1:7XzaJu7d5a1xKSbiv0LntGuTjHSY6x6AYybaNkg9TfE= -github.com/NpoolPlatform/ledger-middleware v0.0.0-20230303153851-9f5d1d78921a/go.mod h1:PHraMn7XFekx4iYzJPJYt8z4NbUY2G7evmNkghxz47o= -github.com/NpoolPlatform/libent-cruder v0.0.0-20221109023947-366125b690fb h1:IAQOJ0xQWdJS1BnimNdM6GZMLgTL/FnIa8C8K4xffUA= -github.com/NpoolPlatform/libent-cruder v0.0.0-20221109023947-366125b690fb/go.mod h1:zvvqlRwbOdTUauPQ9dFDhDuxa91ILV0CQfVdPBZj+eA= -github.com/NpoolPlatform/message v0.0.0-20230815040303-b186df0b7f2b h1:F5AuUHifvGQCpXyacePYocRCSbRXbTLvhdC78ilPuVM= -github.com/NpoolPlatform/message v0.0.0-20230815040303-b186df0b7f2b/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= -github.com/NpoolPlatform/order-middleware v0.0.0-20230815061732-4d55ec9e8f2a h1:CS1BC6q2NlAQQQG6Unwidj7iDh3vT5C/4jKztFSf3Xg= -github.com/NpoolPlatform/order-middleware v0.0.0-20230815061732-4d55ec9e8f2a/go.mod h1:GYe5QFjM7oS+Ut3owu3PP86kHeI5fMJTVRhOyf9PLCg= +github.com/NpoolPlatform/ledger-middleware v0.0.0-20230823035222-525fd923c4df h1:CcrLl1qcJlb3vnwh9RJVF3XXYuG9hsDGFtGzTm8a0po= +github.com/NpoolPlatform/ledger-middleware v0.0.0-20230823035222-525fd923c4df/go.mod h1:TwyLlOBycZhsH5M8bcglXqv/XwLNP2KAnyWWIvLh7Ss= +github.com/NpoolPlatform/libent-cruder v0.0.0-20230822060122-512da6e5c8bf h1:YysNU0GfIyd8iC4KwdZmTIx6TJYairrVrLqu8E9T0yM= +github.com/NpoolPlatform/libent-cruder v0.0.0-20230822060122-512da6e5c8bf/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= +github.com/NpoolPlatform/message v0.0.0-20230823033748-9a43fb49ad63 h1:jo7MG8T8JV7JQBPO8Y6ZVtFhg4LGN0toW5oqdqvePZQ= +github.com/NpoolPlatform/message v0.0.0-20230823033748-9a43fb49ad63/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/order-middleware v0.0.0-20230823034327-d4735e33c3c3 h1:8lVAqIFt2Oy6ZTtcTl5U7sqPLRb+FFU61tFYGfNt2pk= +github.com/NpoolPlatform/order-middleware v0.0.0-20230823034327-d4735e33c3c3/go.mod h1:uMW5wmPcAh2aiffLc2mqR25nPuG3OYZCyYo67RMuhss= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b/go.mod h1:9C9XDi7c0szxcLdJGDDFuo3/KtC74yWiyUM2fR+i0ww= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= @@ -112,7 +110,6 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -141,7 +138,6 @@ github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -173,14 +169,13 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= -github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg= -github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -227,7 +222,6 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -245,7 +239,6 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -312,7 +305,6 @@ github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOn github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/serf v0.9.7 h1:hkdgbqizGQHuU5IPqYM1JdSMV8nKfpuOnZYXssk9muY= github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -377,23 +369,11 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= -github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= @@ -467,7 +447,6 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -479,7 +458,7 @@ github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go v0.0.0-20190204201341-e444a5086c43 h1:nLURyLzmXqqnferXOGs9EA2kbhl/bks8vSyptHCxH34= github.com/ugorji/go v0.0.0-20190204201341-e444a5086c43/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= -github.com/ugorji/go/codec v1.2.8 h1:sgBJS6COt0b/P40VouWKdseidkDgHxYGm0SAglUHfP0= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/urfave/cli/v2 v2.16.3 h1:gHoFIwpPjoyIMbJp/VFd+/vuD0dAgFK4B6DpEMFJfQk= github.com/urfave/cli/v2 v2.16.3/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= @@ -576,7 +555,6 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -600,7 +578,6 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -612,7 +589,6 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= @@ -626,7 +602,6 @@ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -639,7 +614,6 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -651,14 +625,11 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -681,7 +652,6 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -692,7 +662,6 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -757,7 +726,6 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -855,7 +823,6 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= @@ -864,14 +831,12 @@ gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/order/create.go b/pkg/order/create.go index be2d7cc..fc10d4b 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -8,42 +8,41 @@ import ( "github.com/NpoolPlatform/go-service-framework/pkg/logger" "github.com/google/uuid" - payaccmwcli "github.com/NpoolPlatform/account-middleware/pkg/client/payment" + cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" + appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" + appgoodstockmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/stock" goodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good" + appgoodpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good" + appgoodstockmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/stock" appcoinmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/app/coin" coininfocli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin" currvalmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin/currency" - appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/appgood" - sphinxproxycli "github.com/NpoolPlatform/sphinx-proxy/pkg/client" - - goodmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/good" - paymentmwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/payment" - paymentmwcli "github.com/NpoolPlatform/order-middleware/pkg/client/payment" - appcoinmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/app/coin" - appgoodpb "github.com/NpoolPlatform/message/npool/good/mgr/v1/appgood" - - payaccmwpb "github.com/NpoolPlatform/message/npool/account/mw/v1/payment" currvalmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin/currency" + sphinxproxypb "github.com/NpoolPlatform/message/npool/sphinxproxy" + sphinxproxycli "github.com/NpoolPlatform/sphinx-proxy/pkg/client" + payaccmwcli "github.com/NpoolPlatform/account-middleware/pkg/client/payment" accountlock "github.com/NpoolPlatform/account-middleware/pkg/lock" - cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" + payaccmwpb "github.com/NpoolPlatform/message/npool/account/mw/v1/payment" - ledgermgrcli "github.com/NpoolPlatform/ledger-middleware/pkg/client/ledger/v2" - ledgermgrpb "github.com/NpoolPlatform/message/npool/ledger/mgr/v1/ledger/general" + ledgermwcli "github.com/NpoolPlatform/ledger-middleware/pkg/client/ledger" + ledgermwpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger" - commonpb "github.com/NpoolPlatform/message/npool" - basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" + paymentmwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/payment" ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" + paymentmwcli "github.com/NpoolPlatform/order-middleware/pkg/client/payment" allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" + allocatedmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/coupon/allocated" + inspiretypes "github.com/NpoolPlatform/message/npool/basetypes/inspire/v1" ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" - allocatedmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/coupon/allocated" + basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" "github.com/shopspring/decimal" @@ -118,11 +117,11 @@ func (h *createHandler) validateInit(ctx context.Context) error { //nolint } ag, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodpb.Conds{ - AppID: &commonpb.StringVal{ + AppID: &basetypes.StringVal{ Op: cruder.EQ, Value: *h.AppID, }, - GoodID: &commonpb.StringVal{ + GoodID: &basetypes.StringVal{ Op: cruder.EQ, Value: *h.GoodID, }, @@ -296,11 +295,11 @@ func (h *createHandler) SetPrice(ctx context.Context) error { return err } ag, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodpb.Conds{ - AppID: &commonpb.StringVal{ + AppID: &basetypes.StringVal{ Op: cruder.EQ, Value: *h.AppID, }, - GoodID: &commonpb.StringVal{ + GoodID: &basetypes.StringVal{ Op: cruder.EQ, Value: *h.GoodID, }, @@ -639,7 +638,7 @@ func (h *createHandler) createSubOrder(ctx context.Context) error { //nolint } func (h *createHandler) LockStock(ctx context.Context) error { - _, err := goodmwcli.UpdateGood(ctx, &goodmwpb.GoodReq{ + _, err := appgoodstockmwcli.AddStock(ctx, &appgoodstockmwpb.StockReq{ ID: h.GoodID, Locked: &h.Units, }) @@ -650,14 +649,9 @@ func (h *createHandler) LockStock(ctx context.Context) error { } func (h *createHandler) ReleaseStock(ctx context.Context) error { - units, err := decimal.NewFromString(h.Units) - if err != nil { - return err - } - unitsStr := units.Neg().String() - _, err = goodmwcli.UpdateGood(ctx, &goodmwpb.GoodReq{ + _, err := appgoodstockmwcli.SubStock(ctx, &appgoodstockmwpb.StockReq{ ID: h.GoodID, - Locked: &unitsStr, + Locked: &h.Units, }) if err != nil { return err @@ -679,16 +673,16 @@ func (h *createHandler) LockBalance(ctx context.Context) error { return nil } - general, err := ledgermgrcli.GetGeneralOnly(ctx, &ledgermgrpb.Conds{ - AppID: &commonpb.StringVal{ + general, err := ledgermwcli.GetLedgerOnly(ctx, &ledgermwpb.Conds{ + AppID: &basetypes.StringVal{ Op: cruder.EQ, Value: *h.AppID, }, - UserID: &commonpb.StringVal{ + UserID: &basetypes.StringVal{ Op: cruder.EQ, Value: *h.UserID, }, - CoinTypeID: &commonpb.StringVal{ + CoinTypeID: &basetypes.StringVal{ Op: cruder.EQ, Value: *h.PaymentCoinID, }, @@ -711,7 +705,7 @@ func (h *createHandler) LockBalance(ctx context.Context) error { spendableMinus := fmt.Sprintf("-%v", *h.BalanceAmount) - _, err = ledgermgrcli.AddGeneral(ctx, &ledgermgrpb.GeneralReq{ + _, err = ledgermwcli.AddBalance(ctx, &ledgermwpb.LedgerReq{ ID: &general.ID, AppID: &general.AppID, UserID: &general.UserID, @@ -737,16 +731,16 @@ func (h *createHandler) ReleaseBalance(ctx context.Context) error { return nil } - general, err := ledgermgrcli.GetGeneralOnly(ctx, &ledgermgrpb.Conds{ - AppID: &commonpb.StringVal{ + general, err := ledgermwcli.GetLedgerOnly(ctx, &ledgermwpb.Conds{ + AppID: &basetypes.StringVal{ Op: cruder.EQ, Value: *h.AppID, }, - UserID: &commonpb.StringVal{ + UserID: &basetypes.StringVal{ Op: cruder.EQ, Value: *h.UserID, }, - CoinTypeID: &commonpb.StringVal{ + CoinTypeID: &basetypes.StringVal{ Op: cruder.EQ, Value: *h.PaymentCoinID, }, @@ -760,7 +754,7 @@ func (h *createHandler) ReleaseBalance(ctx context.Context) error { lockedMinus := fmt.Sprintf("-%v", h.BalanceAmount) - _, err = ledgermgrcli.AddGeneral(ctx, &ledgermgrpb.GeneralReq{ + _, err = ledgermwcli.SubBalance(ctx, &ledgermwpb.LedgerReq{ ID: &general.ID, AppID: &general.AppID, UserID: &general.UserID, diff --git a/pkg/order/query.go b/pkg/order/query.go index 5cd45d6..eca3139 100644 --- a/pkg/order/query.go +++ b/pkg/order/query.go @@ -8,30 +8,29 @@ import ( "github.com/NpoolPlatform/go-service-framework/pkg/logger" payaccmwcli "github.com/NpoolPlatform/account-middleware/pkg/client/payment" - usermwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" - appcoinmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/app/coin" - coininfocli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin" - allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" - npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" - ordercli "github.com/NpoolPlatform/order-middleware/pkg/client/order" + payaccmwpb "github.com/NpoolPlatform/message/npool/account/mw/v1/payment" + usermwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" usermwpb "github.com/NpoolPlatform/message/npool/appuser/mw/v1/user" - payaccmwpb "github.com/NpoolPlatform/message/npool/account/mw/v1/payment" + appcoinmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/app/coin" + coininfocli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin" appcoinmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/app/coin" + + allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" allocatedmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/coupon/allocated" - ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" - appgoodscli "github.com/NpoolPlatform/good-middleware/pkg/client/appgood" - appgoodspb "github.com/NpoolPlatform/message/npool/good/mw/v1/appgood" + npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" + ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" + ordercli "github.com/NpoolPlatform/order-middleware/pkg/client/order" - appgoodsmgrpb "github.com/NpoolPlatform/message/npool/good/mgr/v1/appgood" + appgoodscli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" + appgoodsmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good" cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" "github.com/shopspring/decimal" - commonpb "github.com/NpoolPlatform/message/npool" basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" "github.com/google/uuid" @@ -127,12 +126,12 @@ func (h *queryHandler) expand(ctx context.Context) error { //nolint couponMap[coup.ID] = coup } - appGoods, _, err := appgoodscli.GetGoods(ctx, &appgoodsmgrpb.Conds{ - GoodIDs: &commonpb.StringSliceVal{ + appGoods, _, err := appgoodscli.GetGoods(ctx, &appgoodsmwpb.Conds{ + GoodIDs: &basetypes.StringSliceVal{ Op: cruder.IN, Value: goodIDs, }, - AppID: &commonpb.StringVal{ + AppID: &basetypes.StringVal{ Op: cruder.IN, Value: *h.AppID, }, @@ -143,7 +142,7 @@ func (h *queryHandler) expand(ctx context.Context) error { //nolint fmt.Printf("goodIDs: %v, appID %v, appGoods %v | %v\n", goodIDs, h.AppID, len(appGoods), appGoods) - appGoodMap := map[string]*appgoodspb.Good{} + appGoodMap := map[string]*appgoodsmwpb.Good{} for _, appGood := range appGoods { appGoodMap[appGood.AppID+appGood.GoodID] = appGood } @@ -362,12 +361,12 @@ func (h *Handler) GetOrder(ctx context.Context) (*npool.Order, error) { //nolint o.EmailAddress = user.EmailAddress o.PhoneNO = user.PhoneNO - appGood, err := appgoodscli.GetGoodOnly(ctx, &appgoodsmgrpb.Conds{ - AppID: &commonpb.StringVal{ + appGood, err := appgoodscli.GetGoodOnly(ctx, &appgoodsmwpb.Conds{ + AppID: &basetypes.StringVal{ Op: cruder.EQ, Value: ord.AppID, }, - GoodID: &commonpb.StringVal{ + GoodID: &basetypes.StringVal{ Op: cruder.EQ, Value: ord.GoodID, }, diff --git a/pkg/order/update.go b/pkg/order/update.go index 9c037cd..0f8b750 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -5,35 +5,33 @@ import ( "fmt" "time" - goodmgrpb "github.com/NpoolPlatform/message/npool/good/mgr/v1/good" - - miningdetailcli "github.com/NpoolPlatform/ledger-middleware/pkg/client/mining/detail" - miningdetailpb "github.com/NpoolPlatform/message/npool/ledger/mgr/v1/mining/detail" - "github.com/NpoolPlatform/libent-cruder/pkg/cruder" - commonpb "github.com/NpoolPlatform/message/npool" - - "github.com/shopspring/decimal" - appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/appgood" - appgoodmwpb "github.com/NpoolPlatform/message/npool/good/mgr/v1/appgood" + goodtypes "github.com/NpoolPlatform/message/npool/basetypes/good/v1" + ledgertypes "github.com/NpoolPlatform/message/npool/basetypes/ledger/v1" + ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" + basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" + appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" + appgoodstockmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/stock" goodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good" - goodmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/good" + appgoodmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good" + appgoodstockmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/stock" + npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" - ledgercli "github.com/NpoolPlatform/ledger-middleware/pkg/client/ledger/v2" - - ledgerdetailpb "github.com/NpoolPlatform/message/npool/ledger/mgr/v1/ledger/detail" + miningdetailcli "github.com/NpoolPlatform/ledger-middleware/pkg/client/good/ledger/statement" + ledgerstatementcli "github.com/NpoolPlatform/ledger-middleware/pkg/client/ledger/statement" + miningdetailpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/good/ledger/statement" + ledgerstatementpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger/statement" achievementmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/achievement" statementmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/achievement/statement" - ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" - basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" statementmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/achievement/statement" - npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" + + "github.com/shopspring/decimal" ) type updateHandler struct { @@ -43,12 +41,12 @@ type updateHandler struct { //nolint:gocyclo func (h *updateHandler) validate(ctx context.Context) error { - good, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodmwpb.Conds{ - AppID: &commonpb.StringVal{ + appgood, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodmwpb.Conds{ + AppID: &basetypes.StringVal{ Op: cruder.EQ, Value: h.ord.AppID, }, - GoodID: &commonpb.StringVal{ + GoodID: &basetypes.StringVal{ Op: cruder.EQ, Value: h.ord.GoodID, }, @@ -56,12 +54,20 @@ func (h *updateHandler) validate(ctx context.Context) error { if err != nil { return err } + if appgood == nil { + return fmt.Errorf("invalid appgood") + } + + good, err := goodmwcli.GetGood(ctx, h.ord.GoodID) + if err != nil { + return err + } if good == nil { return fmt.Errorf("invalid good") } - _, total, err := miningdetailcli.GetDetails(ctx, &miningdetailpb.Conds{ - GoodID: &commonpb.StringVal{ + _, total, err := miningdetailcli.GetGoodStatements(ctx, &miningdetailpb.Conds{ + GoodID: &basetypes.StringVal{ Op: cruder.EQ, Value: h.ord.GoodID, }, @@ -73,14 +79,14 @@ func (h *updateHandler) validate(ctx context.Context) error { return fmt.Errorf("app good have mining detail data uncancellable") } - if good.BenefitState != goodmgrpb.BenefitState_BenefitWait { + if good.RewardState != goodtypes.BenefitState_BenefitWait { return fmt.Errorf("app good uncancellable benefit state not wait") } - switch good.CancelMode { - case appgoodmwpb.CancelMode_Uncancellable: + switch appgood.CancelMode { + case goodtypes.CancelMode_Uncancellable: return fmt.Errorf("app good uncancellable") - case appgoodmwpb.CancelMode_CancellableBeforeStart: + case goodtypes.CancelMode_CancellableBeforeStart: switch h.ord.OrderState { case ordertypes.OrderState_OrderStateWaitPayment: case ordertypes.OrderState_OrderStatePaid: @@ -88,10 +94,10 @@ func (h *updateHandler) validate(ctx context.Context) error { return fmt.Errorf("order state is uncancellable") } - if uint32(time.Now().Unix()) >= h.ord.Start-good.CancellableBeforeStart { + if uint32(time.Now().Unix()) >= h.ord.Start-appgood.CancellableBeforeStart { return fmt.Errorf("cancellable time exceeded") } - case appgoodmwpb.CancelMode_CancellableBeforeBenefit: + case goodtypes.CancelMode_CancellableBeforeBenefit: switch h.ord.OrderState { case ordertypes.OrderState_OrderStateWaitPayment: case ordertypes.OrderState_OrderStatePaid: @@ -100,35 +106,29 @@ func (h *updateHandler) validate(ctx context.Context) error { return fmt.Errorf("order state is uncancellable") } - if uint32(time.Now().Unix()) >= h.ord.Start-good.CancellableBeforeStart && - uint32(time.Now().Unix()) <= h.ord.Start+good.CancellableBeforeStart { + if uint32(time.Now().Unix()) >= h.ord.Start-appgood.CancellableBeforeStart && + uint32(time.Now().Unix()) <= h.ord.Start+appgood.CancellableBeforeStart { return fmt.Errorf("app good uncancellable order start at > cancellable before start") } default: - return fmt.Errorf("unknown CancelMode type %v", good.CancelMode) + return fmt.Errorf("unknown CancelMode type %v", appgood.CancelMode) } return nil } func (h *updateHandler) processStock(ctx context.Context) error { - units, err := decimal.NewFromString(h.ord.Units) - if err != nil { - return err - } - unitsStr := units.Neg().String() - - stockReq := &goodmwpb.GoodReq{ + stockReq := &appgoodstockmwpb.StockReq{ ID: &h.ord.GoodID, } switch h.ord.OrderState { case ordertypes.OrderState_OrderStatePaid: - stockReq.WaitStart = &unitsStr + stockReq.WaitStart = &h.Units case ordertypes.OrderState_OrderStateInService: - stockReq.InService = &unitsStr + stockReq.InService = &h.Units } - _, err = goodmwcli.UpdateGood(ctx, stockReq) + _, err := appgoodstockmwcli.SubStock(ctx, stockReq) if err != nil { return err } @@ -157,11 +157,11 @@ func (h *updateHandler) processOrderState(ctx context.Context) error { func (h *updateHandler) processLedger(ctx context.Context) error { offset := int32(0) limit := int32(1000) //nolint - detailInfos := []*ledgerdetailpb.DetailReq{} - in := ledgerdetailpb.IOType_Incoming - out := ledgerdetailpb.IOType_Outcoming - ioTypeCR := ledgerdetailpb.IOSubType_CommissionRevoke - ioTypeOrder := ledgerdetailpb.IOSubType_OrderRevoke + detailInfos := []*ledgerstatementpb.StatementReq{} + in := ledgertypes.IOType_Incoming + out := ledgertypes.IOType_Outcoming + ioTypeCR := ledgertypes.IOSubType_CommissionRevoke + ioTypeOrder := ledgertypes.IOSubType_OrderRevoke for { infos, _, err := statementmwcli.GetStatements(ctx, &statementmwpb.Conds{ @@ -185,24 +185,24 @@ func (h *updateHandler) processLedger(ctx context.Context) error { continue } - _, total, err := ledgercli.GetDetails(ctx, &ledgerdetailpb.Conds{ - AppID: &commonpb.StringVal{ + _, total, err := ledgerstatementcli.GetStatements(ctx, &ledgerstatementpb.Conds{ + AppID: &basetypes.StringVal{ Op: cruder.EQ, Value: val.AppID, }, - UserID: &commonpb.StringVal{ + UserID: &basetypes.StringVal{ Op: cruder.EQ, Value: val.UserID, }, - IOType: &commonpb.Int32Val{ + IOType: &basetypes.Uint32Val{ Op: cruder.EQ, - Value: int32(in), + Value: uint32(in), }, - IOSubType: &commonpb.Int32Val{ + IOSubType: &basetypes.Uint32Val{ Op: cruder.EQ, - Value: int32(ledgerdetailpb.IOSubType_Commission), + Value: uint32(ledgertypes.IOSubType_Commission), }, - IOExtra: &commonpb.StringVal{ + IOExtra: &basetypes.StringVal{ Op: cruder.LIKE, Value: h.ord.ID, }, @@ -223,7 +223,7 @@ func (h *updateHandler) processLedger(ctx context.Context) error { time.Now(), ) - detailInfos = append(detailInfos, &ledgerdetailpb.DetailReq{ + detailInfos = append(detailInfos, &ledgerstatementpb.StatementReq{ AppID: &val.AppID, UserID: &val.UserID, CoinTypeID: &val.PaymentCoinTypeID, @@ -256,7 +256,7 @@ func (h *updateHandler) processLedger(ctx context.Context) error { time.Now(), ) - detailInfos = append(detailInfos, &ledgerdetailpb.DetailReq{ + detailInfos = append(detailInfos, &ledgerstatementpb.StatementReq{ AppID: &h.ord.AppID, UserID: &h.ord.UserID, CoinTypeID: &h.ord.PaymentCoinTypeID, @@ -268,7 +268,7 @@ func (h *updateHandler) processLedger(ctx context.Context) error { } if len(detailInfos) > 0 { - err = ledgercli.BookKeeping(ctx, detailInfos) + _, err = ledgerstatementcli.CreateStatements(ctx, detailInfos) if err != nil { return err } diff --git a/pkg/version/version.go b/pkg/version/version.go index 4ec879f..5f15794 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -5,16 +5,16 @@ import ( "github.com/NpoolPlatform/go-service-framework/pkg/logger" "github.com/NpoolPlatform/go-service-framework/pkg/version" - npool "github.com/NpoolPlatform/message/npool" + basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" ) -func Version() (*npool.VersionResponse, error) { +func Version() (*basetypes.VersionResponse, error) { info, err := version.GetVersion() if err != nil { logger.Sugar().Errorf("get service version error: %+w", err) return nil, fmt.Errorf("get service version error: %w", err) } - return &npool.VersionResponse{ + return &basetypes.VersionResponse{ Info: info, }, nil } From 6a9311548a214a6d4d1148eefdb8f0f9876bac43 Mon Sep 17 00:00:00 2001 From: jakys Date: Wed, 23 Aug 2023 07:33:20 +0000 Subject: [PATCH 03/67] Add update state migrator --- pkg/migrator/migrator.go | 161 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) diff --git a/pkg/migrator/migrator.go b/pkg/migrator/migrator.go index 1d9e83d..737d986 100644 --- a/pkg/migrator/migrator.go +++ b/pkg/migrator/migrator.go @@ -2,8 +2,169 @@ package migrator import ( "context" + "fmt" + + "github.com/NpoolPlatform/go-service-framework/pkg/config" + "github.com/NpoolPlatform/go-service-framework/pkg/logger" + redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" + ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" + constant1 "github.com/NpoolPlatform/order-gateway/pkg/message/const" + "github.com/NpoolPlatform/order-middleware/pkg/db" + "github.com/NpoolPlatform/order-middleware/pkg/db/ent" + entorder "github.com/NpoolPlatform/order-middleware/pkg/db/ent/order" + entpayment "github.com/NpoolPlatform/order-middleware/pkg/db/ent/payment" +) + +const ( + keyServiceID = "serviceid" ) +func lockKey() string { + serviceID := config.GetStringValueWithNameSpace(constant1.ServiceName, keyServiceID) + return fmt.Sprintf("migrator:%v", serviceID) +} + +//nolint:funlen +func migrateState(ctx context.Context) error { + return db.WithTx(ctx, func(_ctx context.Context, tx *ent.Tx) error { + var err error + OrderStateWaitPayment := "WaitPayment" + OrderStatePaid := "Paid" + OrderStatePaymentTimeout := "PaymentTimeout" + OrderStateCanceled := "Canceled" + OrderStateInService := "InService" + OrderStateExpired := "Expired" + _, err = tx.Order.Update(). + Where( + entorder.StateV1(ordertypes.OrderState_DefaultOrderState.String()), + entorder.State(OrderStateWaitPayment), + ). + SetStateV1(ordertypes.OrderState_OrderStateWaitPayment.String()). + Save(_ctx) + if err != nil { + return err + } + _, err = tx.Order.Update(). + Where( + entorder.StateV1(ordertypes.OrderState_DefaultOrderState.String()), + entorder.State(OrderStatePaid), + ). + SetStateV1(ordertypes.OrderState_OrderStatePaid.String()). + Save(_ctx) + if err != nil { + return err + } + _, err = tx.Order.Update(). + Where( + entorder.StateV1(ordertypes.OrderState_DefaultOrderState.String()), + entorder.State(OrderStatePaymentTimeout), + ). + SetStateV1(ordertypes.OrderState_OrderStatePaymentTimeout.String()). + Save(_ctx) + if err != nil { + return err + } + _, err = tx.Order.Update(). + Where( + entorder.StateV1(ordertypes.OrderState_DefaultOrderState.String()), + entorder.State(OrderStateCanceled), + ). + SetStateV1(ordertypes.OrderState_OrderStateCanceled.String()). + Save(_ctx) + if err != nil { + return err + } + _, err = tx.Order.Update(). + Where( + entorder.StateV1(ordertypes.OrderState_DefaultOrderState.String()), + entorder.State(OrderStateInService), + ). + SetStateV1(ordertypes.OrderState_OrderStateInService.String()). + Save(_ctx) + if err != nil { + return err + } + _, err = tx.Order.Update(). + Where( + entorder.StateV1(ordertypes.OrderState_DefaultOrderState.String()), + entorder.State(OrderStateExpired), + ). + SetStateV1(ordertypes.OrderState_OrderStateExpired.String()). + Save(_ctx) + if err != nil { + return err + } + + PaymentStateWait := "Wait" + PaymentStateDone := "Done" + PaymentStateCanceled := "Canceled" + PaymentStateTimeOut := "TimeOut" + _, err = tx.Payment.Update(). + Where( + entpayment.StateV1(ordertypes.PaymentState_DefaultPaymentState.String()), + entpayment.State(PaymentStateWait), + ). + SetStateV1(ordertypes.PaymentState_PaymentStateWait.String()). + Save(_ctx) + if err != nil { + return err + } + _, err = tx.Payment.Update(). + Where( + entpayment.StateV1(ordertypes.PaymentState_DefaultPaymentState.String()), + entpayment.State(PaymentStateDone), + ). + SetStateV1(ordertypes.PaymentState_PaymentStateDone.String()). + Save(_ctx) + if err != nil { + return err + } + _, err = tx.Payment.Update(). + Where( + entpayment.StateV1(ordertypes.PaymentState_DefaultPaymentState.String()), + entpayment.State(PaymentStateCanceled), + ). + SetStateV1(ordertypes.PaymentState_PaymentStateCanceled.String()). + Save(_ctx) + if err != nil { + return err + } + _, err = tx.Payment.Update(). + Where( + entpayment.StateV1(ordertypes.PaymentState_DefaultPaymentState.String()), + entpayment.State(PaymentStateTimeOut), + ). + SetStateV1(ordertypes.PaymentState_PaymentStateTimeOut.String()). + Save(_ctx) + if err != nil { + return err + } + + return nil + }) +} + func Migrate(ctx context.Context) error { + if err := redis2.TryLock(lockKey(), 0); err != nil { + return err + } + defer func() { + _ = redis2.Unlock(lockKey()) + }() + + logger.Sugar().Infow("Migrate", "Start", "...") + + if err := db.Init(); err != nil { + logger.Sugar().Errorw("Migrate", "error", err) + return err + } + + if err := migrateState(ctx); err != nil { + logger.Sugar().Errorw("Migrate", "error", err) + return err + } + + logger.Sugar().Infow("Migrate", "Done", "success") + return nil } From 50d0d1bb9bdc9a063818e3d0c961b83a83c9bb3f Mon Sep 17 00:00:00 2001 From: jakys Date: Tue, 29 Aug 2023 01:29:47 +0000 Subject: [PATCH 04/67] Refactor order --- api/order/create.go | 97 +----- api/order/query.go | 6 +- api/order/update.go | 30 +- go.mod | 29 +- go.sum | 90 ++++-- pkg/migrator/migrator.go | 129 -------- pkg/order/create.go | 623 ++++++++++++++++++++------------------- pkg/order/handler.go | 172 ++++++----- pkg/order/ordergood.go | 163 ++++++++++ pkg/order/query.go | 410 +++++++++----------------- pkg/order/update.go | 26 +- 11 files changed, 852 insertions(+), 923 deletions(-) create mode 100644 pkg/order/ordergood.go diff --git a/api/order/create.go b/api/order/create.go index 023cb23..3eea8ae 100644 --- a/api/order/create.go +++ b/api/order/create.go @@ -4,42 +4,29 @@ package order import ( "context" - appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" - appgoodpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good" - - "github.com/NpoolPlatform/libent-cruder/pkg/cruder" - ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" - basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" - ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" order1 "github.com/NpoolPlatform/order-gateway/pkg/order" - ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "github.com/NpoolPlatform/go-service-framework/pkg/logger" - - "github.com/shopspring/decimal" ) func createOrder(ctx context.Context, in *npool.CreateOrderRequest) (*npool.Order, error) { //nolint handler, err := order1.NewHandler( ctx, - order1.WithAppID(&in.AppID), - order1.WithUserID(&in.AppID, &in.UserID), - order1.WithGoodID(&in.GoodID), - order1.WithUnits(in.Units), - order1.WithPaymentCoinID(&in.PaymentCoinID), - order1.WithParentOrderID(in.ParentOrderID), - order1.WithOrderType(&in.OrderType), - order1.WithPayWithBalanceAmount(in.GetPayWithBalanceAmount()), - order1.WithFixAmountID(in.FixAmountID), - order1.WithDiscountID(in.DiscountID), - order1.WithSpecialOfferID(in.SpecialOfferID), - order1.WithCouponIDs(in.CouponIDs), + order1.WithAppID(&in.AppID, true), + order1.WithUserID(&in.AppID, &in.UserID, true), + order1.WithGoodID(&in.GoodID, true), + order1.WithUnits(in.Units, true), + order1.WithPaymentCoinID(&in.PaymentCoinID, true), + order1.WithParentOrderID(in.ParentOrderID, false), + order1.WithOrderType(&in.OrderType, true), + order1.WithBalanceAmount(in.GetPayWithBalanceAmount(), false), + order1.WithCouponIDs(in.CouponIDs, false), ) if err != nil { logger.Sugar().Errorw( @@ -64,70 +51,6 @@ func createOrder(ctx context.Context, in *npool.CreateOrderRequest) (*npool.Orde } func (s *Server) CreateOrder(ctx context.Context, in *npool.CreateOrderRequest) (*npool.CreateOrderResponse, error) { - ag, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodpb.Conds{ - AppID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: in.AppID, - }, - GoodID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: in.GoodID, - }, - }) - if err != nil { - return &npool.CreateOrderResponse{}, status.Error(codes.Internal, err.Error()) - } - if ag == nil { - return &npool.CreateOrderResponse{}, status.Error(codes.Internal, "invalid app good") - } - units, err := decimal.NewFromString(in.Units) - if err != nil { - return &npool.CreateOrderResponse{}, status.Error(codes.Internal, err.Error()) - } - if ag.PurchaseLimit > 0 && units.Cmp(decimal.NewFromInt32(ag.PurchaseLimit)) > 0 { - return &npool.CreateOrderResponse{}, status.Error(codes.Internal, "too many units") - } - - if !ag.EnablePurchase { - return &npool.CreateOrderResponse{}, status.Error(codes.Internal, "app good is not enabled purchase") - } - - purchaseCountStr, err := ordermwcli.SumOrderUnits( - ctx, - &ordermwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: in.AppID}, - UserID: &basetypes.StringVal{Op: cruder.EQ, Value: in.UserID}, - GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: in.GoodID}, - States: &basetypes.Uint32SliceVal{ - Op: cruder.IN, - Value: []uint32{ - uint32(ordertypes.OrderState_OrderStatePaid), - uint32(ordertypes.OrderState_OrderStateInService), - uint32(ordertypes.OrderState_OrderStateExpired), - uint32(ordertypes.OrderState_OrderStateWaitPayment), - }, - }, - }, - ) - if err != nil { - return nil, err - } - - purchaseCount, err := decimal.NewFromString(purchaseCountStr) - if err != nil { - return nil, err - } - - userPurchaseLimit, err := decimal.NewFromString(ag.UserPurchaseLimit) - if err != nil { - logger.Sugar().Errorw("ValidateInit", "error", err) - return &npool.CreateOrderResponse{}, status.Error(codes.Internal, err.Error()) - } - - if userPurchaseLimit.Cmp(decimal.NewFromInt(0)) > 0 && purchaseCount.Add(units).Cmp(userPurchaseLimit) > 0 { - return &npool.CreateOrderResponse{}, status.Error(codes.Internal, "too many units") - } - in.OrderType = ordertypes.OrderType_Normal ord, err := createOrder(ctx, in) if err != nil { @@ -150,8 +73,8 @@ func (s *Server) CreateUserOrder(ctx context.Context, in *npool.CreateUserOrderR AppID: in.AppID, UserID: in.TargetUserID, GoodID: in.GoodID, - PaymentCoinID: in.PaymentCoinID, Units: in.Units, + PaymentCoinID: in.PaymentCoinID, ParentOrderID: in.ParentOrderID, OrderType: in.OrderType, }) diff --git a/api/order/query.go b/api/order/query.go index 0a004e9..38534be 100644 --- a/api/order/query.go +++ b/api/order/query.go @@ -15,8 +15,8 @@ import ( func (s *Server) GetOrders(ctx context.Context, in *npool.GetOrdersRequest) (*npool.GetOrdersResponse, error) { handler, err := order1.NewHandler( ctx, - order1.WithAppID(&in.AppID), - order1.WithUserID(&in.AppID, &in.UserID), + order1.WithAppID(&in.AppID, true), + order1.WithUserID(&in.AppID, &in.UserID, false), order1.WithOffset(in.GetOffset()), order1.WithLimit(in.GetLimit()), ) @@ -82,7 +82,7 @@ func (s *Server) GetAppUserOrders(ctx context.Context, in *npool.GetAppUserOrder func (s *Server) GetOrder(ctx context.Context, in *npool.GetOrderRequest) (*npool.GetOrderResponse, error) { handler, err := order1.NewHandler( ctx, - order1.WithID(&in.ID), + order1.WithID(&in.ID, true), ) if err != nil { logger.Sugar().Errorw( diff --git a/api/order/update.go b/api/order/update.go index 1330f6f..818046b 100644 --- a/api/order/update.go +++ b/api/order/update.go @@ -16,11 +16,11 @@ import ( func (s *Server) UpdateOrder(ctx context.Context, in *npool.UpdateOrderRequest) (*npool.UpdateOrderResponse, error) { handler, err := order1.NewHandler( ctx, - order1.WithID(&in.ID), - order1.WithAppID(&in.AppID), - order1.WithUserID(&in.AppID, &in.UserID), - order1.WithPaymentID(&in.PaymentID), - order1.WithCanceled(in.Canceled), + order1.WithID(&in.ID, true), + order1.WithAppID(&in.AppID, true), + order1.WithUserID(&in.AppID, &in.UserID, true), + order1.WithPaymentID(&in.PaymentID, true), + order1.WithCanceled(in.Canceled, true), order1.WithFromAdmin(false), ) if err != nil { @@ -50,11 +50,11 @@ func (s *Server) UpdateOrder(ctx context.Context, in *npool.UpdateOrderRequest) func (s *Server) UpdateUserOrder(ctx context.Context, in *npool.UpdateUserOrderRequest) (*npool.UpdateUserOrderResponse, error) { handler, err := order1.NewHandler( ctx, - order1.WithID(&in.ID), - order1.WithAppID(&in.AppID), - order1.WithUserID(&in.AppID, &in.TargetUserID), - order1.WithPaymentID(&in.PaymentID), - order1.WithCanceled(in.Canceled), + order1.WithID(&in.ID, true), + order1.WithAppID(&in.AppID, true), + order1.WithUserID(&in.AppID, &in.TargetUserID, true), + order1.WithPaymentID(&in.PaymentID, true), + order1.WithCanceled(in.Canceled, true), order1.WithFromAdmin(false), ) if err != nil { @@ -84,11 +84,11 @@ func (s *Server) UpdateUserOrder(ctx context.Context, in *npool.UpdateUserOrderR func (s *Server) UpdateAppUserOrder(ctx context.Context, in *npool.UpdateAppUserOrderRequest) (*npool.UpdateAppUserOrderResponse, error) { handler, err := order1.NewHandler( ctx, - order1.WithID(&in.ID), - order1.WithAppID(&in.TargetAppID), - order1.WithUserID(&in.TargetAppID, &in.TargetUserID), - order1.WithPaymentID(&in.PaymentID), - order1.WithCanceled(in.Canceled), + order1.WithID(&in.ID, true), + order1.WithAppID(&in.TargetAppID, true), + order1.WithUserID(&in.TargetAppID, &in.TargetUserID, true), + order1.WithPaymentID(&in.PaymentID, true), + order1.WithCanceled(in.Canceled, true), order1.WithFromAdmin(false), ) if err != nil { diff --git a/go.mod b/go.mod index 511cdf2..1afef7f 100644 --- a/go.mod +++ b/go.mod @@ -7,14 +7,16 @@ require ( github.com/NpoolPlatform/appuser-middleware v0.0.0-20230513100509-b19f356ebd4b github.com/NpoolPlatform/basal-middleware v0.0.0-20230518061816-62bd589c0f63 github.com/NpoolPlatform/chain-middleware v0.0.0-20230712041523-2e1d215244e0 + github.com/NpoolPlatform/dtm-cluster v0.0.0-20230518062456-3e53bebe90da github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e github.com/NpoolPlatform/good-middleware v0.0.0-20230823034851-d6449a27f3e1 github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 - github.com/NpoolPlatform/ledger-middleware v0.0.0-20230823035222-525fd923c4df - github.com/NpoolPlatform/libent-cruder v0.0.0-20230822060122-512da6e5c8bf - github.com/NpoolPlatform/message v0.0.0-20230823033748-9a43fb49ad63 - github.com/NpoolPlatform/order-middleware v0.0.0-20230823034327-d4735e33c3c3 + github.com/NpoolPlatform/ledger-middleware v0.0.0-20230827161127-ec28b0f14ec0 + github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 + github.com/NpoolPlatform/message v0.0.0-20230828122703-3aa63ff5da47 + github.com/NpoolPlatform/order-middleware v0.0.0-20230828144010-05748d247a78 github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b + github.com/dtm-labs/dtm v1.17.1 github.com/go-resty/resty/v2 v2.7.0 github.com/google/uuid v1.3.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 @@ -46,6 +48,8 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/dtm-labs/dtmdriver v0.0.6 // indirect + github.com/dtm-labs/logger v0.0.2 // indirect github.com/fatih/color v1.13.0 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/go-chassis/go-archaius v1.5.3 // indirect @@ -55,7 +59,9 @@ require ( github.com/go-openapi/inflect v0.19.0 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-sql-driver/mysql v1.6.0 // indirect + github.com/go-stack/stack v1.8.0 // indirect github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect @@ -70,17 +76,19 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl/v2 v2.13.0 // indirect github.com/hashicorp/serf v0.9.7 // indirect + github.com/klauspost/compress v1.15.1 // indirect github.com/lithammer/shortuuid/v3 v3.0.7 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect + github.com/mitchellh/go-wordwrap v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/natefinch/lumberjack v2.0.0+incompatible // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.0.1 // indirect + github.com/pelletier/go-toml/v2 v2.0.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect @@ -95,8 +103,13 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.12.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect + github.com/xdg-go/pbkdf2 v1.0.0 // indirect + github.com/xdg-go/scram v1.0.2 // indirect + github.com/xdg-go/stringprep v1.0.2 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect github.com/zclconf/go-cty v1.8.0 // indirect + go.mongodb.org/mongo-driver v1.9.1 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.31.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.6.3 // indirect go.opentelemetry.io/otel/sdk v1.6.3 // indirect @@ -104,13 +117,15 @@ require ( go.uber.org/multierr v1.8.0 // indirect go.uber.org/ratelimit v0.2.0 // indirect go.uber.org/zap v1.21.0 // indirect + golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect golang.org/x/mod v0.8.0 // indirect golang.org/x/net v0.8.0 // indirect + golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.6.0 // indirect golang.org/x/text v0.8.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect - gopkg.in/ini.v1 v1.66.4 // indirect + gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 34b04b3..4f3021f 100644 --- a/go.sum +++ b/go.sum @@ -44,7 +44,7 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 entgo.io/ent v0.11.2 h1:UM2/BUhF2FfsxPHRxLjQbhqJNaDdVlOwNIAMLs2jyto= entgo.io/ent v0.11.2/go.mod h1:YGHEQnmmIUgtD5b1ICD5vg74dS3npkNnmC5K+0J+IHU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I= +github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= @@ -56,20 +56,22 @@ github.com/NpoolPlatform/basal-middleware v0.0.0-20230518061816-62bd589c0f63 h1: github.com/NpoolPlatform/basal-middleware v0.0.0-20230518061816-62bd589c0f63/go.mod h1:3sHDVUUQHRkZsCiBFI6CdCL2HWf3cO7/E2DZU3nHMfE= github.com/NpoolPlatform/chain-middleware v0.0.0-20230712041523-2e1d215244e0 h1:xD+68nDsw/P0rXd1fzr/wip24bkpYzwrXGBFwSvXkbs= github.com/NpoolPlatform/chain-middleware v0.0.0-20230712041523-2e1d215244e0/go.mod h1:ExILdqBVnhspnOZFslJl0vTOc4Qyk78Lni1Kx2F8HGM= +github.com/NpoolPlatform/dtm-cluster v0.0.0-20230518062456-3e53bebe90da h1:ed2RLOcRnzjDv8Qr6km0xiq1CyoZxBkB5gZrR2spILc= +github.com/NpoolPlatform/dtm-cluster v0.0.0-20230518062456-3e53bebe90da/go.mod h1:I0UKoN/HU1p1RmpCYSramNbGCrd/EM7/fH6zhSUspkM= github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e h1:17BGexCmCdOOBXKYogP8RNE+pAHRu2N4LKq9znPJ4vc= github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e/go.mod h1:Kh7DMkWnYOMHxEKq7QfJqbxm1HaUPkhTNN74lfHQxyE= github.com/NpoolPlatform/good-middleware v0.0.0-20230823034851-d6449a27f3e1 h1:mCP1H+uT1IrlQ+ijrMZsBvRgFUQ/gC5v3+q5HZeLW14= github.com/NpoolPlatform/good-middleware v0.0.0-20230823034851-d6449a27f3e1/go.mod h1:m0iZ5NxrwNXbkpAvqA/cjWGpzQAc5bPGfcOsPgO7KiQ= github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 h1:5W7RWU/meU1ZkPiUjqKAnyBKsjJ6NZu3dCfc0hgjhRs= github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2/go.mod h1:CCCI+S1AecMrRdRruOgMUxM9JaIXIYVt3DID04TuOoc= -github.com/NpoolPlatform/ledger-middleware v0.0.0-20230823035222-525fd923c4df h1:CcrLl1qcJlb3vnwh9RJVF3XXYuG9hsDGFtGzTm8a0po= -github.com/NpoolPlatform/ledger-middleware v0.0.0-20230823035222-525fd923c4df/go.mod h1:TwyLlOBycZhsH5M8bcglXqv/XwLNP2KAnyWWIvLh7Ss= -github.com/NpoolPlatform/libent-cruder v0.0.0-20230822060122-512da6e5c8bf h1:YysNU0GfIyd8iC4KwdZmTIx6TJYairrVrLqu8E9T0yM= -github.com/NpoolPlatform/libent-cruder v0.0.0-20230822060122-512da6e5c8bf/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= -github.com/NpoolPlatform/message v0.0.0-20230823033748-9a43fb49ad63 h1:jo7MG8T8JV7JQBPO8Y6ZVtFhg4LGN0toW5oqdqvePZQ= -github.com/NpoolPlatform/message v0.0.0-20230823033748-9a43fb49ad63/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= -github.com/NpoolPlatform/order-middleware v0.0.0-20230823034327-d4735e33c3c3 h1:8lVAqIFt2Oy6ZTtcTl5U7sqPLRb+FFU61tFYGfNt2pk= -github.com/NpoolPlatform/order-middleware v0.0.0-20230823034327-d4735e33c3c3/go.mod h1:uMW5wmPcAh2aiffLc2mqR25nPuG3OYZCyYo67RMuhss= +github.com/NpoolPlatform/ledger-middleware v0.0.0-20230827161127-ec28b0f14ec0 h1:c3wAy6HooN5Zuqd2I7h5+IU0UoXIiLFREUG+d0fPq18= +github.com/NpoolPlatform/ledger-middleware v0.0.0-20230827161127-ec28b0f14ec0/go.mod h1:MiA18NKwLyyjE6FnrGO+ChFEWbJ02xdwnQMZFtvQ1aQ= +github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB4NuhQxXWeV0Z1qSxgIqbiMYU30dqFGDLtgNTqYbE= +github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= +github.com/NpoolPlatform/message v0.0.0-20230828122703-3aa63ff5da47 h1:DZNPxdGojpxit630EjHVnuCg7YAIr/JWdHt8s1QSoDM= +github.com/NpoolPlatform/message v0.0.0-20230828122703-3aa63ff5da47/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/order-middleware v0.0.0-20230828144010-05748d247a78 h1:nygQPwPf8DR6/pdkBIK3Zc3izJuz9E7XmYZNx5VuFJk= +github.com/NpoolPlatform/order-middleware v0.0.0-20230828144010-05748d247a78/go.mod h1:N/GM1Xme4/Zl2L1mA0nJezPcuF+HAHnamTxAYYmtMss= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b/go.mod h1:9C9XDi7c0szxcLdJGDDFuo3/KtC74yWiyUM2fR+i0ww= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= @@ -130,6 +132,12 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/dtm-labs/dtm v1.17.1 h1:bmTZl68d01qabQV39bUHqiUyrfapIZLfh7/omw9u3gw= +github.com/dtm-labs/dtm v1.17.1/go.mod h1:ZO91Piv1QIqkNIjaygUOcCT5U8DpHta1X1ftJTZBf34= +github.com/dtm-labs/dtmdriver v0.0.6 h1:Iz6xnO+hE2TKDHI2TX4BKCzMtgXYgeQFBEGvvaNhbs8= +github.com/dtm-labs/dtmdriver v0.0.6/go.mod h1:V5E1uFsExb6Do32ezpB8bMX6be+izLhkcboniLP5shU= +github.com/dtm-labs/logger v0.0.2 h1:UQQTjDHnZhSbAHwXO9ISva1/AGO+MW9MjztAIzqJ1Tw= +github.com/dtm-labs/logger v0.0.2/go.mod h1:WgJjaTSJ0WmITqMGEWDiaamrxgMkAH8TmwIhykuGugY= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -141,10 +149,10 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= github.com/go-chassis/cari v0.0.0-20201210041921-7b6fbef2df11/go.mod h1:MgtsEI0AM4Ush6Lyw27z9Gk4nQ/8GWTSXrFzupawWDM= github.com/go-chassis/foundation v0.2.2-0.20201210043510-9f6d3de40234/go.mod h1:2PjwqpVwYEVaAldl5A58a08viH8p27pNeYaiE3ZxOBA= github.com/go-chassis/foundation v0.3.0 h1:jG4BIrK8fXD9jbTtJ5rOLGQZ1pQI/mLnDuVJzToCtos= @@ -169,12 +177,16 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -209,9 +221,12 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -260,8 +275,8 @@ github.com/grpc/grpc-go v1.41.0 h1:mgY4oFjHTV35T076OO8kzb6RYhHR27FFHuka4hP10kA= github.com/grpc/grpc-go v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= github.com/hashicorp/consul/api v1.12.0 h1:k3y1FYv6nuKyNTqj6w9gXOx5r5CfLj/k/euUeBXj1OY= github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= -github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= +github.com/hashicorp/consul/sdk v0.9.0 h1:NGSHAU7X3yDCjo8WBUbNOtD3BSqv8u0vu3+zNxgmxQI= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -275,8 +290,8 @@ github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39E github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -284,12 +299,12 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= @@ -316,6 +331,9 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= +github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -326,6 +344,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8= github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= @@ -355,9 +374,8 @@ github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXx github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= -github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM= -github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -368,7 +386,10 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM= +github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= @@ -380,8 +401,8 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= -github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw= +github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -450,11 +471,14 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI= github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go v0.0.0-20190204201341-e444a5086c43 h1:nLURyLzmXqqnferXOGs9EA2kbhl/bks8vSyptHCxH34= github.com/ugorji/go v0.0.0-20190204201341-e444a5086c43/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= @@ -463,8 +487,16 @@ github.com/urfave/cli/v2 v2.16.3 h1:gHoFIwpPjoyIMbJp/VFd+/vuD0dAgFK4B6DpEMFJfQk= github.com/urfave/cli/v2 v2.16.3/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -472,6 +504,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA= github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= +go.mongodb.org/mongo-driver v1.9.1 h1:m078y9v7sBItkt1aaoe2YlvWEXcD263e1a4E1fBrJ1c= +go.mongodb.org/mongo-driver v1.9.1/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -498,8 +532,8 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= @@ -517,8 +551,11 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -612,6 +649,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -665,6 +704,7 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -688,6 +728,7 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -824,10 +865,9 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4= -gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= +gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/pkg/migrator/migrator.go b/pkg/migrator/migrator.go index 737d986..f75b419 100644 --- a/pkg/migrator/migrator.go +++ b/pkg/migrator/migrator.go @@ -7,12 +7,8 @@ import ( "github.com/NpoolPlatform/go-service-framework/pkg/config" "github.com/NpoolPlatform/go-service-framework/pkg/logger" redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" - ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" constant1 "github.com/NpoolPlatform/order-gateway/pkg/message/const" "github.com/NpoolPlatform/order-middleware/pkg/db" - "github.com/NpoolPlatform/order-middleware/pkg/db/ent" - entorder "github.com/NpoolPlatform/order-middleware/pkg/db/ent/order" - entpayment "github.com/NpoolPlatform/order-middleware/pkg/db/ent/payment" ) const ( @@ -24,126 +20,6 @@ func lockKey() string { return fmt.Sprintf("migrator:%v", serviceID) } -//nolint:funlen -func migrateState(ctx context.Context) error { - return db.WithTx(ctx, func(_ctx context.Context, tx *ent.Tx) error { - var err error - OrderStateWaitPayment := "WaitPayment" - OrderStatePaid := "Paid" - OrderStatePaymentTimeout := "PaymentTimeout" - OrderStateCanceled := "Canceled" - OrderStateInService := "InService" - OrderStateExpired := "Expired" - _, err = tx.Order.Update(). - Where( - entorder.StateV1(ordertypes.OrderState_DefaultOrderState.String()), - entorder.State(OrderStateWaitPayment), - ). - SetStateV1(ordertypes.OrderState_OrderStateWaitPayment.String()). - Save(_ctx) - if err != nil { - return err - } - _, err = tx.Order.Update(). - Where( - entorder.StateV1(ordertypes.OrderState_DefaultOrderState.String()), - entorder.State(OrderStatePaid), - ). - SetStateV1(ordertypes.OrderState_OrderStatePaid.String()). - Save(_ctx) - if err != nil { - return err - } - _, err = tx.Order.Update(). - Where( - entorder.StateV1(ordertypes.OrderState_DefaultOrderState.String()), - entorder.State(OrderStatePaymentTimeout), - ). - SetStateV1(ordertypes.OrderState_OrderStatePaymentTimeout.String()). - Save(_ctx) - if err != nil { - return err - } - _, err = tx.Order.Update(). - Where( - entorder.StateV1(ordertypes.OrderState_DefaultOrderState.String()), - entorder.State(OrderStateCanceled), - ). - SetStateV1(ordertypes.OrderState_OrderStateCanceled.String()). - Save(_ctx) - if err != nil { - return err - } - _, err = tx.Order.Update(). - Where( - entorder.StateV1(ordertypes.OrderState_DefaultOrderState.String()), - entorder.State(OrderStateInService), - ). - SetStateV1(ordertypes.OrderState_OrderStateInService.String()). - Save(_ctx) - if err != nil { - return err - } - _, err = tx.Order.Update(). - Where( - entorder.StateV1(ordertypes.OrderState_DefaultOrderState.String()), - entorder.State(OrderStateExpired), - ). - SetStateV1(ordertypes.OrderState_OrderStateExpired.String()). - Save(_ctx) - if err != nil { - return err - } - - PaymentStateWait := "Wait" - PaymentStateDone := "Done" - PaymentStateCanceled := "Canceled" - PaymentStateTimeOut := "TimeOut" - _, err = tx.Payment.Update(). - Where( - entpayment.StateV1(ordertypes.PaymentState_DefaultPaymentState.String()), - entpayment.State(PaymentStateWait), - ). - SetStateV1(ordertypes.PaymentState_PaymentStateWait.String()). - Save(_ctx) - if err != nil { - return err - } - _, err = tx.Payment.Update(). - Where( - entpayment.StateV1(ordertypes.PaymentState_DefaultPaymentState.String()), - entpayment.State(PaymentStateDone), - ). - SetStateV1(ordertypes.PaymentState_PaymentStateDone.String()). - Save(_ctx) - if err != nil { - return err - } - _, err = tx.Payment.Update(). - Where( - entpayment.StateV1(ordertypes.PaymentState_DefaultPaymentState.String()), - entpayment.State(PaymentStateCanceled), - ). - SetStateV1(ordertypes.PaymentState_PaymentStateCanceled.String()). - Save(_ctx) - if err != nil { - return err - } - _, err = tx.Payment.Update(). - Where( - entpayment.StateV1(ordertypes.PaymentState_DefaultPaymentState.String()), - entpayment.State(PaymentStateTimeOut), - ). - SetStateV1(ordertypes.PaymentState_PaymentStateTimeOut.String()). - Save(_ctx) - if err != nil { - return err - } - - return nil - }) -} - func Migrate(ctx context.Context) error { if err := redis2.TryLock(lockKey(), 0); err != nil { return err @@ -159,11 +35,6 @@ func Migrate(ctx context.Context) error { return err } - if err := migrateState(ctx); err != nil { - logger.Sugar().Errorw("Migrate", "error", err) - return err - } - logger.Sugar().Infow("Migrate", "Done", "success") return nil diff --git a/pkg/order/create.go b/pkg/order/create.go index fc10d4b..4afa256 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -5,15 +5,14 @@ import ( "fmt" "time" + dtmcli "github.com/NpoolPlatform/dtm-cluster/pkg/dtm" "github.com/NpoolPlatform/go-service-framework/pkg/logger" - "github.com/google/uuid" + "github.com/dtm-labs/dtm/client/dtmcli/dtmimp" cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" + ordermwsvcname "github.com/NpoolPlatform/order-middleware/pkg/servicename" - appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" appgoodstockmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/stock" - goodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good" - appgoodpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good" appgoodstockmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/stock" appcoinmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/app/coin" @@ -33,9 +32,7 @@ import ( ledgermwpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger" ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" - paymentmwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/payment" ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" - paymentmwcli "github.com/NpoolPlatform/order-middleware/pkg/client/payment" allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" allocatedmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/coupon/allocated" @@ -50,20 +47,24 @@ import ( type createHandler struct { *Handler - GoodStartAt uint32 - GoodDurationDays uint32 - BalanceAmount *string + orderGood *OrderGood + + discountAmount decimal.Decimal + paymentAmountUSD decimal.Decimal + paymentAmountCoin decimal.Decimal + + promotionID string paymentCoinName string - paymentAmountUSD decimal.Decimal - paymentAmountCoin decimal.Decimal paymentAddress string paymentAddressStartAmount decimal.Decimal goodPaymentID string paymentAccountID string - promotionID *string - - price decimal.Decimal + goodPrices map[string]decimal.Decimal + goodValues map[string]decimal.Decimal + goodValueUSDs map[string]decimal.Decimal + paymentType ordertypes.PaymentType + paymentTransferAmount decimal.Decimal liveCurrency decimal.Decimal localCurrency decimal.Decimal @@ -72,83 +73,11 @@ type createHandler struct { reductionAmount decimal.Decimal reductionPercent decimal.Decimal - start uint32 - end uint32 + startAts map[string]uint32 + endAts map[string]uint32 } -func (h *createHandler) validateInit(ctx context.Context) error { //nolint - if h.AppID == nil { - return fmt.Errorf("invalid appid") - } - if h.UserID == nil { - return fmt.Errorf("invalid userid") - } - if h.GoodID == nil { - return fmt.Errorf("invalid goodid") - } - if h.Units == "" { - return fmt.Errorf("invalid units") - } - units, err := decimal.NewFromString(h.Units) - if err != nil { - return err - } - if units.Cmp(decimal.NewFromInt32(0)) <= 0 { - return fmt.Errorf("units is 0") - } - if h.PaymentCoinID == nil { - return fmt.Errorf("invalid paymentcoinid") - } - if h.CouponIDs != nil { - for _, id := range h.CouponIDs { - if _, err := uuid.Parse(id); err != nil { - logger.Sugar().Errorw("CreateOrder", "error", err) - return fmt.Errorf("invalid couponids") - } - } - } - - good, err := goodmwcli.GetGood(ctx, *h.GoodID) - if err != nil { - return err - } - if good == nil { - return fmt.Errorf("invalid good") - } - - ag, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodpb.Conds{ - AppID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.AppID, - }, - GoodID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.GoodID, - }, - }) - if err != nil { - return err - } - if ag == nil { - return fmt.Errorf("invalid app good") - } - - h.GoodStartAt = ag.ServiceStartAt - - if ag.ServiceStartAt == 0 { - h.GoodStartAt = good.StartAt - } - - h.GoodDurationDays = uint32(good.DurationDays) - - gcoin, err := coininfocli.GetCoin(ctx, good.CoinTypeID) - if err != nil { - return err - } - if gcoin == nil { - return fmt.Errorf("invalid good coin") - } - +func (h *createHandler) validateInit(ctx context.Context) error { coin, err := coininfocli.GetCoin(ctx, *h.PaymentCoinID) if err != nil { return err @@ -162,72 +91,51 @@ func (h *createHandler) validateInit(ctx context.Context) error { //nolint if !coin.ForPay { return fmt.Errorf("coin not for payment") } - if coin.ENV != gcoin.ENV { - return fmt.Errorf("good coin mismatch payment coin") - } - - h.paymentCoinName = coin.Name - if h.ParentOrderID != nil { - order, err := ordermwcli.GetOrder(ctx, *h.ParentOrderID) + for _, goodReq := range h.Goods { + good := h.orderGood.goods[goodReq.GoodID] + gcoin, err := coininfocli.GetCoin(ctx, good.CoinTypeID) if err != nil { return err } - if order == nil { - return fmt.Errorf("invalid parent order") + if gcoin == nil { + return fmt.Errorf("invalid good coin") + } + if coin.ENV != gcoin.ENV { + return fmt.Errorf("good coin mismatch payment coin") } - } - if !ag.Online { - return fmt.Errorf("good offline") + appgood := h.orderGood.appgoods[*h.AppID+*h.GoodID] + goodStartAt := appgood.ServiceStartAt + if appgood.ServiceStartAt == 0 { + goodStartAt = good.StartAt + } + goodDurationDays := uint32(good.DurationDays) + startAt := uint32(tomorrowStart().Unix()) + if goodStartAt > startAt { + startAt = goodStartAt + } + const secondsPerDay = 24 * 60 * 60 + endAt := startAt + goodDurationDays*secondsPerDay + h.startAts[*h.AppID+goodReq.GoodID] = startAt + h.endAts[*h.AppID+goodReq.GoodID] = endAt } - agPrice, err := decimal.NewFromString(ag.Price) - if err != nil { - return err - } - if agPrice.IntPart() <= 0 { - return fmt.Errorf("invalid good price") - } - price, err := decimal.NewFromString(good.Price) - if err != nil { - return err - } - if agPrice.Cmp(price) < 0 { - return fmt.Errorf("invalid app good price") - } + h.paymentCoinName = coin.Name const maxUnpaidOrders = 5 - - payments, _, err := paymentmwcli.GetPayments(ctx, &paymentmwpb.Conds{ - AppID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.AppID, - }, - UserID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.UserID, - }, - State: &basetypes.Uint32Val{ - Op: cruder.EQ, - Value: uint32(ordertypes.PaymentState_PaymentStateWait), - }, + orders, _, err := ordermwcli.GetOrders(ctx, &ordermwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + PaymentState: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(ordertypes.PaymentState_PaymentStateWait)}, }, 0, maxUnpaidOrders) if err != nil { return err } - if len(payments) >= maxUnpaidOrders && *h.OrderType == ordertypes.OrderType_Normal { + if len(orders) >= maxUnpaidOrders && *h.OrderType == ordertypes.OrderType_Normal { return fmt.Errorf("too many unpaid orders") } - switch *h.OrderType { - case ordertypes.OrderType_Normal: - case ordertypes.OrderType_Offline: - case ordertypes.OrderType_Airdrop: - default: - return fmt.Errorf("invalid order type") - } - return nil } @@ -290,59 +198,25 @@ func (h *createHandler) SetReduction(ctx context.Context) error { } func (h *createHandler) SetPrice(ctx context.Context) error { - good, err := goodmwcli.GetGood(ctx, *h.GoodID) - if err != nil { - return err - } - ag, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodpb.Conds{ - AppID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.AppID, - }, - GoodID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.GoodID, - }, - }) - if err != nil { - return err - } - if ag == nil { - return fmt.Errorf("invalid app good") - } - - if !ag.Online { - return fmt.Errorf("good offline") - } - agPrice, err := decimal.NewFromString(ag.Price) - if err != nil { - return err - } - if agPrice.Cmp(decimal.NewFromInt(0)) <= 0 { - return fmt.Errorf("invalid good price") - } - price, err := decimal.NewFromString(good.Price) - if err != nil { - return err - } - if agPrice.Cmp(price) < 0 { - return fmt.Errorf("invalid app good price") - } - - h.price, err = decimal.NewFromString(ag.Price) - if err != nil { - return err - } - - if ag.PromotionPrice != nil { - promotionPrice, err := decimal.NewFromString(ag.GetPromotionPrice()) + for _, goodReq := range h.Goods { + appgood := h.orderGood.appgoods[*h.AppID+goodReq.GoodID] + topmostGood := h.orderGood.topMostGoods[*h.AppID+goodReq.GoodID] + price, err := decimal.NewFromString(appgood.Price) if err != nil { return err } - if promotionPrice.Cmp(decimal.NewFromInt(0)) <= 0 { - return fmt.Errorf("invalid price") + + if topmostGood != nil { + promotionPrice, err := decimal.NewFromString(topmostGood.GetPrice()) + if err != nil { + return err + } + if promotionPrice.Cmp(decimal.NewFromInt(0)) <= 0 { + return fmt.Errorf("invalid price") + } + price = promotionPrice } - h.price = promotionPrice + h.goodPrices[*h.AppID+goodReq.GoodID] = price } return nil @@ -376,14 +250,8 @@ func (h *createHandler) SetCurrency(ctx context.Context) error { h.coinCurrency = val apc, err := appcoinmwcli.GetCoinOnly(ctx, &appcoinmwpb.Conds{ - AppID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.AppID, - }, - CoinTypeID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.PaymentCoinID, - }, + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, }) if err != nil { return err @@ -412,12 +280,26 @@ func (h *createHandler) SetCurrency(ctx context.Context) error { } func (h *createHandler) SetPaymentAmount(ctx context.Context) error { - // TODO: also add sub good order payment amount - units, err := decimal.NewFromString(h.Units) - if err != nil { - return err + const accuracy = 1000000 + totalPaymentAmountUSD := decimal.NewFromInt(0) + for _, goodReq := range h.Goods { + price := h.goodPrices[*h.AppID+goodReq.GoodID] + units, err := decimal.NewFromString(goodReq.Units) + if err != nil { + return err + } + paymentAmountUSD := price.Mul(units) + h.goodValueUSDs[goodReq.GoodID] = paymentAmountUSD + totalPaymentAmountUSD = totalPaymentAmountUSD.Add(paymentAmountUSD) + + goodValue := paymentAmountUSD.Div(h.coinCurrency) + goodValue = goodValue.Mul(decimal.NewFromInt(accuracy)) + goodValue = goodValue.Ceil() + goodValue = goodValue.Div(decimal.NewFromInt(accuracy)) + h.goodValues[goodReq.GoodID] = goodValue } - h.paymentAmountUSD = h.price.Mul(units) + + h.paymentAmountUSD = totalPaymentAmountUSD logger.Sugar().Infow( "CreateOrder", "PaymentAmountUSD", h.paymentAmountUSD, @@ -425,35 +307,34 @@ func (h *createHandler) SetPaymentAmount(ctx context.Context) error { "ReductionPercent", h.reductionPercent, ) - h.paymentAmountUSD = h.price.Mul(units). - Sub(h.paymentAmountUSD. - Mul(h.reductionPercent). - Div(decimal.NewFromInt(100))) //nolint + h.discountAmount = h.paymentAmountUSD. + Mul(h.reductionPercent). + Div(decimal.NewFromInt(100)). //nolint + Add(h.reductionAmount) - h.paymentAmountUSD = h.paymentAmountUSD.Sub(h.reductionAmount) + h.paymentAmountUSD = totalPaymentAmountUSD.Sub(h.discountAmount) if h.paymentAmountUSD.Cmp(decimal.NewFromInt(0)) < 0 { h.paymentAmountUSD = decimal.NewFromInt(0) } - const accuracy = 1000000 - h.paymentAmountCoin = h.paymentAmountUSD.Div(h.coinCurrency) h.paymentAmountCoin = h.paymentAmountCoin.Mul(decimal.NewFromInt(accuracy)) h.paymentAmountCoin = h.paymentAmountCoin.Ceil() h.paymentAmountCoin = h.paymentAmountCoin.Div(decimal.NewFromInt(accuracy)) + h.paymentTransferAmount = h.paymentAmountCoin if h.BalanceAmount != nil { amount, err := decimal.NewFromString(*h.BalanceAmount) if err != nil { return err } - if amount.Cmp(h.paymentAmountCoin) > 0 { - amount = h.paymentAmountCoin + if amount.Cmp(h.paymentTransferAmount) > 0 { + amount = h.paymentTransferAmount amountStr := amount.String() h.BalanceAmount = &amountStr } - h.paymentAmountCoin = h.paymentAmountCoin.Sub(amount) + h.paymentTransferAmount = h.paymentTransferAmount.Sub(amount) } return nil @@ -492,26 +373,11 @@ func (h *createHandler) createAddresses(ctx context.Context) error { func (h *createHandler) peekAddress(ctx context.Context) (*payaccmwpb.Account, error) { payments, _, err := payaccmwcli.GetAccounts(ctx, &payaccmwpb.Conds{ - CoinTypeID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.PaymentCoinID, - }, - Active: &basetypes.BoolVal{ - Op: cruder.EQ, - Value: true, - }, - Locked: &basetypes.BoolVal{ - Op: cruder.EQ, - Value: false, - }, - Blocked: &basetypes.BoolVal{ - Op: cruder.EQ, - Value: false, - }, - AvailableAt: &basetypes.Uint32Val{ - Op: cruder.LTE, - Value: uint32(time.Now().Unix()), - }, + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, + Active: &basetypes.BoolVal{Op: cruder.EQ, Value: true}, + Locked: &basetypes.BoolVal{Op: cruder.EQ, Value: false}, + Blocked: &basetypes.BoolVal{Op: cruder.EQ, Value: false}, + AvailableAt: &basetypes.Uint32Val{Op: cruder.LTE, Value: uint32(time.Now().Unix())}, }, 0, 5) //nolint if err != nil { return nil, err @@ -628,18 +494,31 @@ func (h *createHandler) SetBalance(ctx context.Context) error { } h.paymentAddressStartAmount, err = decimal.NewFromString(balance.BalanceStr) - return err } -func (h *createHandler) createSubOrder(ctx context.Context) error { //nolint - // TODO: create sub order according to good's must select sub good - return nil +func (h *createHandler) withUpdateStock(dispose *dtmcli.SagaDispose) { + for _, goodReq := range h.Goods { + req := &appgoodstockmwpb.StockReq{ + AppID: h.AppID, + GoodID: &goodReq.GoodID, + Locked: &goodReq.Units, + } + dispose.Add( + ordermwsvcname.ServiceDomain, + "good.middleware.app.good1.stock.v1.Middleware/SubStock", + "good.middleware.app.good1.stock.v1.Middleware/AddStock", + &appgoodstockmwpb.AddStockRequest{ + Info: req, + }, + ) + } } func (h *createHandler) LockStock(ctx context.Context) error { _, err := appgoodstockmwcli.AddStock(ctx, &appgoodstockmwpb.StockReq{ - ID: h.GoodID, + AppID: h.AppID, + GoodID: h.GoodID, Locked: &h.Units, }) if err != nil { @@ -650,7 +529,8 @@ func (h *createHandler) LockStock(ctx context.Context) error { func (h *createHandler) ReleaseStock(ctx context.Context) error { _, err := appgoodstockmwcli.SubStock(ctx, &appgoodstockmwpb.StockReq{ - ID: h.GoodID, + AppID: h.AppID, + GoodID: h.GoodID, Locked: &h.Units, }) if err != nil { @@ -674,18 +554,9 @@ func (h *createHandler) LockBalance(ctx context.Context) error { } general, err := ledgermwcli.GetLedgerOnly(ctx, &ledgermwpb.Conds{ - AppID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.AppID, - }, - UserID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.UserID, - }, - CoinTypeID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.PaymentCoinID, - }, + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, }) if err != nil { return err @@ -703,15 +574,13 @@ func (h *createHandler) LockBalance(ctx context.Context) error { return fmt.Errorf("insufficient balance") } - spendableMinus := fmt.Sprintf("-%v", *h.BalanceAmount) - - _, err = ledgermwcli.AddBalance(ctx, &ledgermwpb.LedgerReq{ + _, err = ledgermwcli.SubBalance(ctx, &ledgermwpb.LedgerReq{ ID: &general.ID, AppID: &general.AppID, UserID: &general.UserID, CoinTypeID: &general.CoinTypeID, Locked: h.BalanceAmount, - Spendable: &spendableMinus, + Spendable: h.BalanceAmount, }) return err @@ -732,18 +601,9 @@ func (h *createHandler) ReleaseBalance(ctx context.Context) error { } general, err := ledgermwcli.GetLedgerOnly(ctx, &ledgermwpb.Conds{ - AppID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.AppID, - }, - UserID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.UserID, - }, - CoinTypeID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.PaymentCoinID, - }, + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, }) if err != nil { return err @@ -754,7 +614,7 @@ func (h *createHandler) ReleaseBalance(ctx context.Context) error { lockedMinus := fmt.Sprintf("-%v", h.BalanceAmount) - _, err = ledgermwcli.SubBalance(ctx, &ledgermwpb.LedgerReq{ + _, err = ledgermwcli.AddBalance(ctx, &ledgermwpb.LedgerReq{ ID: &general.ID, AppID: &general.AppID, UserID: &general.UserID, @@ -773,28 +633,27 @@ func tomorrowStart() time.Time { } func (h *createHandler) create(ctx context.Context) (*npool.Order, error) { - switch *h.OrderType { - case ordertypes.OrderType_Normal: - case ordertypes.OrderType_Offline: - case ordertypes.OrderType_Airdrop: - default: - return nil, fmt.Errorf("invalid order type") - } - paymentAmount := h.paymentAmountCoin.String() startAmount := h.paymentAddressStartAmount.String() coinCurrency := h.coinCurrency.String() liveCurrency := h.liveCurrency.String() localCurrency := h.localCurrency.String() + goodValue := h.goodValues[*h.GoodID].String() + goodValueUSD := h.goodValueUSDs[*h.GoodID].String() + discountAmount := h.discountAmount.String() + paymentTransferAmount := h.paymentTransferAmount.String() // Top order never pay with parent, only sub order may - - h.start = uint32(tomorrowStart().Unix()) - if h.GoodStartAt > h.start { - h.start = h.GoodStartAt + topmostGood := h.orderGood.topMostGoods[*h.AppID+*h.GoodID] + if topmostGood != nil { + h.promotionID = topmostGood.TopMostID } - const secondsPerDay = 24 * 60 * 60 - h.end = h.start + h.GoodDurationDays*secondsPerDay + + appgood := h.orderGood.appgoods[*h.AppID+*h.GoodID] + good := h.orderGood.goods[*h.GoodID] + goodDurationDays := uint32(good.DurationDays) + startAt := h.startAts[*h.AppID+*h.GoodID] + endAt := h.endAts[*h.AppID+*h.GoodID] logger.Sugar().Infow( "CreateOrder", @@ -810,27 +669,33 @@ func (h *createHandler) create(ctx context.Context) (*npool.Order, error) { ) ord, err := ordermwcli.CreateOrder(ctx, &ordermwpb.OrderReq{ - AppID: h.AppID, - UserID: h.UserID, - GoodID: h.GoodID, - Units: &h.Units, - OrderType: h.OrderType, - ParentOrderID: h.ParentOrderID, - PaymentCoinID: h.PaymentCoinID, - PayWithBalanceAmount: h.BalanceAmount, - PaymentAccountID: &h.paymentAccountID, - PaymentAmount: &paymentAmount, - PaymentAccountStartAmount: &startAmount, - PaymentCoinUSDCurrency: &coinCurrency, - PaymentLiveUSDCurrency: &liveCurrency, - PaymentLocalUSDCurrency: &localCurrency, - FixAmountID: h.FixAmountID, - DiscountID: h.DiscountID, - SpecialOfferID: h.SpecialOfferID, - Start: &h.start, - End: &h.end, - PromotionID: h.promotionID, - CouponIDs: h.CouponIDs, + AppID: h.AppID, + UserID: h.UserID, + GoodID: h.GoodID, + AppGoodID: &appgood.ID, + ParentOrderID: h.ParentOrderID, + Units: &h.Units, + GoodValue: &goodValue, + GoodValueUSD: &goodValueUSD, + PaymentAmount: &paymentAmount, + DiscountAmount: &discountAmount, + PromotionID: &h.promotionID, + DurationDays: &goodDurationDays, + OrderType: h.OrderType, + InvestmentType: h.InvestmentType, + CouponIDs: h.CouponIDs, + PaymentType: &h.paymentType, + PaymentAccountID: &h.paymentAccountID, + CoinTypeID: &good.CoinTypeID, + PaymentCoinTypeID: h.PaymentCoinID, + PaymentStartAmount: &startAmount, + TransferAmount: &paymentTransferAmount, + BalanceAmount: h.BalanceAmount, + CoinUSDCurrency: &coinCurrency, + LiveCoinUSDCurrency: &liveCurrency, + LocalCoinUSDCurrency: &localCurrency, + StartAt: &startAt, + EndAt: &endAt, }) if err != nil { return nil, err @@ -841,8 +706,13 @@ func (h *createHandler) create(ctx context.Context) (*npool.Order, error) { } func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error) { + orderGood, err := h.ToOrderGood(ctx) + if err != nil { + return nil, err + } handler := &createHandler{ - Handler: h, + Handler: h, + orderGood: orderGood, } if err := handler.validateInit(ctx); err != nil { return nil, err @@ -894,3 +764,154 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error return ord, nil } + +func (h *createHandler) creates(ctx context.Context) ([]*npool.Order, error) { + paymentAmount := h.paymentAmountCoin.String() + startAmount := h.paymentAddressStartAmount.String() + paymentTransferAmount := h.paymentTransferAmount.String() + coinCurrency := h.coinCurrency.String() + liveCurrency := h.liveCurrency.String() + localCurrency := h.localCurrency.String() + discountAmount := h.discountAmount.String() + + orderReqs := []*ordermwpb.OrderReq{} + for _, goodReq := range h.Goods { + goodValue := h.goodValues[goodReq.GoodID].String() + goodValueUSD := h.goodValueUSDs[goodReq.GoodID].String() + // Top order never pay with parent, only sub order may + topmostGood := h.orderGood.topMostGoods[*h.AppID+goodReq.GoodID] + if topmostGood != nil { + h.promotionID = topmostGood.TopMostID + } + + appgood := h.orderGood.appgoods[*h.AppID+goodReq.GoodID] + good := h.orderGood.goods[goodReq.GoodID] + goodDurationDays := uint32(good.DurationDays) + startAt := h.startAts[*h.AppID+goodReq.GoodID] + endAt := h.endAts[*h.AppID+goodReq.GoodID] + + logger.Sugar().Infow( + "CreateOrder", + "PaymentAmountUSD", h.paymentAmountUSD, + "PaymentAmountCoin", h.paymentAmountCoin, + "BalanceAmount", h.BalanceAmount, + "ReductionAmount", h.reductionAmount, + "ReductionPercent", h.reductionPercent, + "PaymentAddressStartAmount", h.paymentAddressStartAmount, + "CoinCurrency", h.coinCurrency, + "LiveCurrency", h.liveCurrency, + "LocalCurrency", h.localCurrency, + ) + orderReq := &ordermwpb.OrderReq{ + AppID: h.AppID, + UserID: h.UserID, + GoodID: h.GoodID, + AppGoodID: &appgood.ID, + ParentOrderID: h.ParentOrderID, + Units: &h.Units, + GoodValue: &goodValue, + GoodValueUSD: &goodValueUSD, + PaymentAmount: &paymentAmount, + DiscountAmount: &discountAmount, + PromotionID: &h.promotionID, + DurationDays: &goodDurationDays, + OrderType: h.OrderType, + InvestmentType: h.InvestmentType, + CouponIDs: h.CouponIDs, + PaymentType: &h.paymentType, + CoinTypeID: &good.CoinTypeID, + PaymentCoinTypeID: h.PaymentCoinID, + TransferAmount: &paymentTransferAmount, + BalanceAmount: h.BalanceAmount, + CoinUSDCurrency: &coinCurrency, + LiveCoinUSDCurrency: &liveCurrency, + LocalCoinUSDCurrency: &localCurrency, + StartAt: &startAt, + EndAt: &endAt, + } + if goodReq.Parent { + orderReq.PaymentAccountID = &h.paymentAccountID + orderReq.PaymentStartAmount = &startAmount + } + orderReqs = append(orderReqs, orderReq) + } + + orders, err := ordermwcli.CreateOrders(ctx, orderReqs) + if err != nil { + return nil, err + } + for key := range orders { + h.IDs = append(h.IDs, orders[key].ID) + } + + infos, _, err := h.GetOrders(ctx) + if err != nil { + return nil, err + } + return infos, nil +} + +func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err error) { + orderGood, err := h.ToOrderGoods(ctx) + if err != nil { + return nil, err + } + handler := &createHandler{ + Handler: h, + orderGood: orderGood, + } + if err := handler.validateInit(ctx); err != nil { + return nil, err + } + + if err := handler.SetReduction(ctx); err != nil { + return nil, err + } + + if err := handler.SetPrice(ctx); err != nil { + return nil, err + } + + if err := handler.SetCurrency(ctx); err != nil { + return nil, err + } + + if err := handler.SetPaymentAmount(ctx); err != nil { + return nil, err + } + + if err := handler.PeekAddress(ctx); err != nil { + return nil, err + } + + if err := handler.SetBalance(ctx); err != nil { + _ = handler.ReleaseAddress(ctx) + return nil, err + } + + sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ + WaitResult: true, + RequestTimeout: handler.RequestTimeoutSeconds, + }) + + handler.withUpdateStock(sagaDispose) + + if err := dtmcli.WithSaga(ctx, sagaDispose); err != nil { + _ = handler.ReleaseAddress(ctx) + return nil, err + } + + if err := handler.LockBalance(ctx); err != nil { + _ = handler.ReleaseAddress(ctx) + return nil, err + } + + orders, err := handler.creates(ctx) + if err != nil { + _ = handler.ReleaseAddress(ctx) + _ = handler.ReleaseBalance(ctx) + return nil, err + } + + return orders, nil +} diff --git a/pkg/order/handler.go b/pkg/order/handler.go index c299b6d..f9fe25c 100644 --- a/pkg/order/handler.go +++ b/pkg/order/handler.go @@ -7,31 +7,34 @@ import ( appmwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/app" appusermwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" + npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" constant "github.com/NpoolPlatform/order-gateway/pkg/const" + ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" "github.com/shopspring/decimal" "github.com/google/uuid" ) type Handler struct { - ID *string - AppID *string - UserID *string - GoodID *string - Units string - PaymentCoinID *string - ParentOrderID *string - PayWithBalanceAmount *string - FixAmountID *string - DiscountID *string - SpecialOfferID *string - OrderType *ordertypes.OrderType - CouponIDs []string - Canceled *bool - FromAdmin bool - PaymentID *string - Offset int32 - Limit int32 + ID *string + AppID *string + UserID *string + GoodID *string + Units string + PaymentCoinID *string + ParentOrderID *string + BalanceAmount *string + OrderType *ordertypes.OrderType + CouponIDs []string + InvestmentType *ordertypes.InvestmentType + Canceled *bool + FromAdmin bool + PaymentID *string + Offset int32 + Limit int32 + Goods []*npool.CreateOrdersRequest_Good + IDs []string + RequestTimeoutSeconds int64 } func NewHandler(ctx context.Context, options ...func(context.Context, *Handler) error) (*Handler, error) { @@ -44,9 +47,12 @@ func NewHandler(ctx context.Context, options ...func(context.Context, *Handler) return handler, nil } -func WithID(id *string) func(context.Context, *Handler) error { +func WithID(id *string, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { if id == nil { + if must { + return fmt.Errorf("invalid id") + } return nil } if _, err := uuid.Parse(*id); err != nil { @@ -57,9 +63,12 @@ func WithID(id *string) func(context.Context, *Handler) error { } } -func WithAppID(appID *string) func(context.Context, *Handler) error { +func WithAppID(appID *string, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { if appID == nil { + if must { + return fmt.Errorf("invalid appid") + } return nil } if _, err := uuid.Parse(*appID); err != nil { @@ -77,9 +86,12 @@ func WithAppID(appID *string) func(context.Context, *Handler) error { } } -func WithUserID(appID, userID *string) func(context.Context, *Handler) error { +func WithUserID(appID, userID *string, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { if appID == nil || userID == nil { + if must { + return fmt.Errorf("invalid userid") + } return nil } _, err := uuid.Parse(*userID) @@ -99,9 +111,12 @@ func WithUserID(appID, userID *string) func(context.Context, *Handler) error { } } -func WithGoodID(id *string) func(context.Context, *Handler) error { +func WithGoodID(id *string, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { if id == nil { + if must { + return fmt.Errorf("invalid goodid") + } return nil } _, err := uuid.Parse(*id) @@ -113,9 +128,12 @@ func WithGoodID(id *string) func(context.Context, *Handler) error { } } -func WithPaymentCoinID(id *string) func(context.Context, *Handler) error { +func WithPaymentCoinID(id *string, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { if id == nil { + if must { + return fmt.Errorf("invalid paymentcoinid") + } return nil } _, err := uuid.Parse(*id) @@ -127,87 +145,64 @@ func WithPaymentCoinID(id *string) func(context.Context, *Handler) error { } } -func WithParentOrderID(id *string) func(context.Context, *Handler) error { +func WithParentOrderID(id *string, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { if id == nil { + if must { + return fmt.Errorf("invalid parentorderid") + } return nil } _, err := uuid.Parse(*id) if err != nil { return err } - h.ParentOrderID = id - return nil - } -} - -func WithFixAmountID(id *string) func(context.Context, *Handler) error { - return func(ctx context.Context, h *Handler) error { - if id == nil { - return nil - } - _, err := uuid.Parse(*id) + exist, err := ordermwcli.ExistOrder(ctx, *h.ParentOrderID) if err != nil { return err } - h.FixAmountID = id - return nil - } -} - -func WithDiscountID(id *string) func(context.Context, *Handler) error { - return func(ctx context.Context, h *Handler) error { - if id == nil { - return nil - } - _, err := uuid.Parse(*id) - if err != nil { - return err + if !exist { + return fmt.Errorf("invalid parentorder") } - h.DiscountID = id + h.ParentOrderID = id return nil } } -func WithSpecialOfferID(id *string) func(context.Context, *Handler) error { +func WithUnits(amount string, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { - if id == nil { - return nil - } - _, err := uuid.Parse(*id) + _amount, err := decimal.NewFromString(amount) if err != nil { return err } - h.SpecialOfferID = id - return nil - } -} - -func WithUnits(amount string) func(context.Context, *Handler) error { - return func(ctx context.Context, h *Handler) error { - _, err := decimal.NewFromString(amount) - if err != nil { - return err + if _amount.Cmp(decimal.NewFromInt32(0)) <= 0 { + return fmt.Errorf("units is 0") } h.Units = amount return nil } } -func WithPayWithBalanceAmount(amount string) func(context.Context, *Handler) error { +func WithBalanceAmount(amount string, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { - _, err := decimal.NewFromString(amount) + _amount, err := decimal.NewFromString(amount) if err != nil { return err } - h.PayWithBalanceAmount = &amount + if _amount.Cmp(decimal.NewFromInt32(0)) <= 0 { + return fmt.Errorf("units is 0") + } + h.BalanceAmount = &amount return nil } } -func WithCouponIDs(couponIDs []string) func(context.Context, *Handler) error { +func WithCouponIDs(couponIDs []string, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { if len(couponIDs) == 0 { + if must { + return fmt.Errorf("invalid couponids") + } return nil } for _, id := range couponIDs { @@ -220,9 +215,31 @@ func WithCouponIDs(couponIDs []string) func(context.Context, *Handler) error { } } -func WithCanceled(value *bool) func(context.Context, *Handler) error { +func WithInvestmentType(investmentType *ordertypes.InvestmentType, must bool) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if investmentType == nil { + if must { + return fmt.Errorf("invalid investmenttype") + } + return nil + } + switch *investmentType { + case ordertypes.InvestmentType_FullPayment: + case ordertypes.InvestmentType_UnionMining: + default: + return fmt.Errorf("invalid investmenttype") + } + h.InvestmentType = investmentType + return nil + } +} + +func WithCanceled(value *bool, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { if value == nil { + if must { + return fmt.Errorf("invalid canceled") + } return nil } h.Canceled = value @@ -237,9 +254,12 @@ func WithFromAdmin(value bool) func(context.Context, *Handler) error { } } -func WithPaymentID(id *string) func(context.Context, *Handler) error { +func WithPaymentID(id *string, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { if id == nil { + if must { + return fmt.Errorf("invalid paymentid") + } return nil } _, err := uuid.Parse(*id) @@ -251,9 +271,12 @@ func WithPaymentID(id *string) func(context.Context, *Handler) error { } } -func WithOrderType(orderType *ordertypes.OrderType) func(context.Context, *Handler) error { +func WithOrderType(orderType *ordertypes.OrderType, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { if orderType == nil { + if must { + return fmt.Errorf("invalid ordertype") + } return nil } switch *orderType { @@ -284,3 +307,10 @@ func WithLimit(limit int32) func(context.Context, *Handler) error { return nil } } + +func WithGoods(goods []*npool.CreateOrdersRequest_Good, must bool) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + h.Goods = goods + return nil + } +} diff --git a/pkg/order/ordergood.go b/pkg/order/ordergood.go new file mode 100644 index 0000000..f1c6e73 --- /dev/null +++ b/pkg/order/ordergood.go @@ -0,0 +1,163 @@ +package order + +import ( + "context" + "fmt" + + cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" + basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" + + coininfocli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin" + appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" + topmostgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/topmost/good" + goodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good" + coinpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin" + appgoodpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good" + topmostgoodpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/topmost/good" + goodpb "github.com/NpoolPlatform/message/npool/good/mw/v1/good" + npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" + + ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" + ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" + ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" + + "github.com/shopspring/decimal" +) + +type OrderGood struct { + goods map[string]*goodpb.Good + appgoods map[string]*appgoodpb.Good + goodCoins map[string]*coinpb.Coin + topMostGoods map[string]*topmostgoodpb.TopMostGood +} + +func (h *Handler) ToOrderGood(ctx context.Context) (*OrderGood, error) { + parent := true + if h.ParentOrderID != nil { + parent = false + } + goodReq := &npool.CreateOrdersRequest_Good{ + GoodID: *h.GoodID, + Units: h.Units, + Parent: parent, + } + h.Goods = append(h.Goods, goodReq) + return h.ToOrderGoods(ctx) +} + +//nolint:funlen,gocyclo +func (h *Handler) ToOrderGoods(ctx context.Context) (*OrderGood, error) { + ordergood := &OrderGood{ + goods: map[string]*goodpb.Good{}, + appgoods: map[string]*appgoodpb.Good{}, + goodCoins: map[string]*coinpb.Coin{}, + topMostGoods: map[string]*topmostgoodpb.TopMostGood{}, + } + for _, goodReq := range h.Goods { + good, err := goodmwcli.GetGood(ctx, goodReq.GoodID) + if err != nil { + return nil, err + } + if good == nil { + return nil, fmt.Errorf("invalid good") + } + ordergood.goods[goodReq.GoodID] = good + + appgood, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: goodReq.GoodID}, + }) + if err != nil { + return nil, err + } + if appgood == nil { + return nil, fmt.Errorf("invalid app good") + } + if !appgood.Online { + return nil, fmt.Errorf("good offline") + } + + agPrice, err := decimal.NewFromString(appgood.Price) + if err != nil { + return nil, err + } + if agPrice.Cmp(decimal.NewFromInt(0)) <= 0 { + return nil, fmt.Errorf("invalid good price") + } + price, err := decimal.NewFromString(good.Price) + if err != nil { + return nil, err + } + if agPrice.Cmp(price) < 0 { + return nil, fmt.Errorf("invalid app good price") + } + + if *h.OrderType == ordertypes.OrderType_Normal { + units, err := decimal.NewFromString(h.Units) + if err != nil { + return nil, err + } + if appgood.PurchaseLimit > 0 && units.Cmp(decimal.NewFromInt32(appgood.PurchaseLimit)) > 0 { + return nil, fmt.Errorf("too many units") + } + if !appgood.EnablePurchase { + return nil, fmt.Errorf("app good is not enabled purchase") + } + purchaseCountStr, err := ordermwcli.SumOrderUnits( + ctx, + &ordermwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.GoodID}, + OrderStates: &basetypes.Uint32SliceVal{ + Op: cruder.IN, + Value: []uint32{ + uint32(ordertypes.OrderState_OrderStatePaid), + uint32(ordertypes.OrderState_OrderStateInService), + uint32(ordertypes.OrderState_OrderStateExpired), + uint32(ordertypes.OrderState_OrderStateWaitPayment), + }, + }, + }, + ) + if err != nil { + return nil, err + } + purchaseCount, err := decimal.NewFromString(purchaseCountStr) + if err != nil { + return nil, err + } + + userPurchaseLimit, err := decimal.NewFromString(appgood.UserPurchaseLimit) + if err != nil { + return nil, err + } + + if userPurchaseLimit.Cmp(decimal.NewFromInt(0)) > 0 && purchaseCount.Add(units).Cmp(userPurchaseLimit) > 0 { + return nil, fmt.Errorf("too many units") + } + } + + goodCoin, err := coininfocli.GetCoin(ctx, good.CoinTypeID) + if err != nil { + return nil, err + } + if goodCoin == nil { + return nil, fmt.Errorf("invalid good coin") + } + ordergood.goodCoins[goodReq.GoodID] = goodCoin + + topMostGood, err := topmostgoodmwcli.GetTopMostGoodOnly(ctx, &topmostgoodpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: goodReq.GoodID}, + }) + if err != nil { + return nil, err + } + if topMostGood != nil { + ordergood.topMostGoods[*h.AppID+goodReq.GoodID] = topMostGood + } + } + + return ordergood, nil +} diff --git a/pkg/order/query.go b/pkg/order/query.go index eca3139..0f0c54a 100644 --- a/pkg/order/query.go +++ b/pkg/order/query.go @@ -1,4 +1,3 @@ -//nolint:dupl package order import ( @@ -14,7 +13,6 @@ import ( usermwpb "github.com/NpoolPlatform/message/npool/appuser/mw/v1/user" appcoinmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/app/coin" - coininfocli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin" appcoinmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/app/coin" allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" @@ -29,8 +27,6 @@ import ( cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" - "github.com/shopspring/decimal" - basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" "github.com/google/uuid" @@ -38,33 +34,22 @@ import ( type queryHandler struct { *Handler - conds *ordermwpb.Conds - mwOrders []*ordermwpb.Order - orders []*npool.Order + orders []*ordermwpb.Order + infos []*npool.Order + users map[string]*usermwpb.User + appGoods map[string]*appgoodsmwpb.Good + accountPayments map[string]*payaccmwpb.Account + coupons map[string]*allocatedmwpb.Coupon + coins map[string]*appcoinmwpb.Coin } var invalidID = uuid.UUID{}.String() -func (h *queryHandler) setConds() { - conds := &ordermwpb.Conds{} - if h.AppID != nil { - conds.AppID = &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID} - } - if h.UserID != nil { - conds.UserID = &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID} - } - h.conds = conds -} - -func (h *queryHandler) expand(ctx context.Context) error { //nolint - if len(h.mwOrders) == 0 { - return nil - } +func (h *queryHandler) getUsers(ctx context.Context) error { uids := []string{} - for _, ord := range h.mwOrders { + for _, ord := range h.orders { uids = append(uids, ord.UserID) } - users, _, err := usermwcli.GetUsers(ctx, &usermwpb.Conds{ IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: uids}, }, 0, int32(len(uids))) @@ -75,18 +60,15 @@ func (h *queryHandler) expand(ctx context.Context) error { //nolint return fmt.Errorf("invalid users") } - userMap := map[string]*usermwpb.User{} for _, user := range users { - userMap[user.ID] = user - } - - goodIDs := []string{} - for _, val := range h.mwOrders { - goodIDs = append(goodIDs, val.GetGoodID()) + h.users[user.ID] = user } + return nil +} +func (h *queryHandler) getAccountPayments(ctx context.Context) error { accIDs := []string{} - for _, ord := range h.mwOrders { + for _, ord := range h.orders { if _, err := uuid.Parse(ord.PaymentAccountID); err != nil { continue } @@ -103,13 +85,15 @@ func (h *queryHandler) expand(ctx context.Context) error { //nolint return err } - accMap := map[string]*payaccmwpb.Account{} for _, acc := range accounts { - accMap[acc.AccountID] = acc + h.accountPayments[acc.AccountID] = acc } + return nil +} +func (h *queryHandler) getCoupons(ctx context.Context) error { ids := []string{} - for _, ord := range h.mwOrders { + for _, ord := range h.orders { ids = append(ids, ord.CouponIDs...) } @@ -121,9 +105,16 @@ func (h *queryHandler) expand(ctx context.Context) error { //nolint return err } - couponMap := map[string]*allocatedmwpb.Coupon{} for _, coup := range coupons { - couponMap[coup.ID] = coup + h.coupons[coup.ID] = coup + } + return nil +} + +func (h *queryHandler) getAppGoods(ctx context.Context) error { + goodIDs := []string{} + for _, val := range h.orders { + goodIDs = append(goodIDs, val.GetGoodID()) } appGoods, _, err := appgoodscli.GetGoods(ctx, &appgoodsmwpb.Conds{ @@ -140,21 +131,21 @@ func (h *queryHandler) expand(ctx context.Context) error { //nolint return err } - fmt.Printf("goodIDs: %v, appID %v, appGoods %v | %v\n", goodIDs, h.AppID, len(appGoods), appGoods) - - appGoodMap := map[string]*appgoodsmwpb.Good{} for _, appGood := range appGoods { - appGoodMap[appGood.AppID+appGood.GoodID] = appGood + h.appGoods[appGood.AppID+appGood.GoodID] = appGood } + return nil +} +func (h *queryHandler) getCoins(ctx context.Context) error { coinTypeIDs := []string{} - for _, val := range h.mwOrders { + for _, val := range h.orders { if _, err := uuid.Parse(val.PaymentCoinTypeID); err != nil { continue } coinTypeIDs = append(coinTypeIDs, val.PaymentCoinTypeID) } - for _, val := range appGoods { + for _, val := range h.appGoods { if _, err := uuid.Parse(val.CoinTypeID); err != nil { continue } @@ -175,124 +166,98 @@ func (h *queryHandler) expand(ctx context.Context) error { //nolint return err } - coinMap := map[string]*appcoinmwpb.Coin{} for _, coin := range coins { - coinMap[coin.CoinTypeID] = coin + h.coins[coin.CoinTypeID] = coin } + return nil +} +func (h *queryHandler) formalize(ctx context.Context) { //nolint infos := []*npool.Order{} - for _, ord := range h.mwOrders { - o := &npool.Order{ - ID: ord.ID, - AppID: ord.AppID, - UserID: ord.UserID, - GoodID: ord.GoodID, - Units: ord.Units, - - ParentOrderID: ord.ParentOrderID, - ParentOrderGoodID: ord.ParentOrderGoodID, - + for _, ord := range h.orders { + info := &npool.Order{ + ID: ord.ID, + AppID: ord.AppID, + UserID: ord.UserID, + GoodID: ord.GoodID, + ParentOrderID: ord.ParentOrderID, + Units: ord.Units, + GoodValue: ord.GoodValue, PaymentID: ord.PaymentID, PaymentCoinTypeID: ord.PaymentCoinTypeID, - PaymentCoinUSDCurrency: ord.PaymentCoinUSDCurrency, - PaymentLiveUSDCurrency: ord.PaymentLiveUSDCurrency, - PaymentLocalUSDCurrency: ord.PaymentLocalUSDCurrency, + PaymentCoinUSDCurrency: ord.CoinUSDCurrency, + PaymentLiveUSDCurrency: ord.LiveCoinUSDCurrency, + PaymentLocalUSDCurrency: ord.LocalCoinUSDCurrency, PaymentAmount: ord.PaymentAmount, PaymentStartAmount: ord.PaymentStartAmount, PaymentFinishAmount: ord.PaymentFinishAmount, - PayWithParent: ord.PayWithParent, - PayWithBalanceAmount: ord.PayWithBalanceAmount, - - FixAmountID: ord.FixAmountID, - DiscountID: ord.DiscountID, - SpecialOfferID: ord.SpecialOfferID, - - OrderType: ord.OrderType, - CreatedAt: ord.CreatedAt, - PaidAt: ord.PaidAt, - State: ord.OrderState, - - Start: ord.Start, - End: ord.End, + PayWithBalanceAmount: ord.BalanceAmount, + OrderType: ord.OrderType, + CreatedAt: ord.CreatedAt, + State: ord.OrderState, + StartAt: ord.StartAt, + EndAt: ord.EndAt, } - user, ok := userMap[ord.UserID] + user, ok := h.users[ord.UserID] if !ok { logger.Sugar().Warnw("expand", "UserID", ord.UserID, "OrderID", ord.ID) } if user != nil { - o.EmailAddress = user.EmailAddress - o.PhoneNO = user.PhoneNO + info.EmailAddress = user.EmailAddress + info.PhoneNO = user.PhoneNO } - appGood, ok := appGoodMap[ord.AppID+ord.GoodID] + appGood, ok := h.appGoods[ord.AppID+ord.GoodID] if !ok { logger.Sugar().Warnw("expand", "AppID", ord.AppID, "GoodID", ord.GoodID) continue } - o.CoinTypeID = appGood.CoinTypeID - o.GoodName = appGood.GoodName - o.GoodUnit = appGood.Unit - o.GoodServicePeriodDays = uint32(appGood.DurationDays) - o.GoodUnitPrice = appGood.Price - - appGoodPrice, err := decimal.NewFromString(appGood.Price) - if err != nil { - return err - } - - units, err := decimal.NewFromString(ord.Units) - if err != nil { - return err - } - o.GoodValue = appGoodPrice.Mul(units).String() - if appGood.PromotionPrice != nil { - appGoodPromotionPrice, err := decimal.NewFromString(*appGood.PromotionPrice) - if err != nil { - return err - } - o.GoodValue = appGoodPromotionPrice.Mul(units).String() - } + info.CoinTypeID = appGood.CoinTypeID + info.GoodName = appGood.GoodName + info.GoodUnit = appGood.Unit + info.GoodServicePeriodDays = uint32(appGood.DurationDays) + info.GoodUnitPrice = appGood.Price - coin, ok := coinMap[o.CoinTypeID] + coin, ok := h.coins[info.CoinTypeID] if !ok { - logger.Sugar().Warnw("expand", "AppID", o.AppID, "CoinTypeID", o.CoinTypeID) + logger.Sugar().Warnw("expand", "AppID", info.AppID, "CoinTypeID", info.CoinTypeID) continue } - o.CoinName = coin.Name - o.CoinLogo = coin.Logo - o.CoinUnit = coin.Unit + info.CoinName = coin.Name + info.CoinLogo = coin.Logo + info.CoinUnit = coin.Unit if ord.PaymentID != invalidID && ord.PaymentID != "" { - coin, ok = coinMap[ord.PaymentCoinTypeID] + coin, ok = h.coins[ord.PaymentCoinTypeID] if !ok { - logger.Sugar().Warnw("expand", "AppID", o.AppID, "PaymentCoinTypeID", o.PaymentCoinTypeID) + logger.Sugar().Warnw("expand", "AppID", info.AppID, "PaymentCoinTypeID", info.PaymentCoinTypeID) continue } } if coin != nil { - o.PaymentCoinName = coin.Name - o.PaymentCoinLogo = coin.Logo - o.PaymentCoinUnit = coin.Unit + info.PaymentCoinName = coin.Name + info.PaymentCoinLogo = coin.Logo + info.PaymentCoinUnit = coin.Unit } - acc, ok := accMap[ord.PaymentAccountID] + acc, ok := h.accountPayments[ord.PaymentAccountID] if ok { - o.PaymentAddress = acc.Address + info.PaymentAddress = acc.Address } for _, id := range ord.CouponIDs { - coup, ok := couponMap[id] + coup, ok := h.coupons[id] if !ok { continue } - o.Coupons = append(o.Coupons, &npool.Coupon{ + info.Coupons = append(info.Coupons, &npool.Coupon{ CouponID: id, CouponType: coup.CouponType, CouponName: coup.CouponName, @@ -300,200 +265,103 @@ func (h *queryHandler) expand(ctx context.Context) error { //nolint }) } - infos = append(infos, o) + infos = append(infos, info) } - h.orders = infos - return nil + h.infos = infos } -func (h *Handler) GetOrder(ctx context.Context) (*npool.Order, error) { //nolint - ord, err := ordercli.GetOrder(ctx, *h.ID) +func (h *Handler) GetOrder(ctx context.Context) (*npool.Order, error) { + order, err := ordercli.GetOrder(ctx, *h.ID) if err != nil { return nil, err } - if ord == nil { + if order == nil { return nil, err } - o := &npool.Order{ - ID: ord.ID, - AppID: ord.AppID, - UserID: ord.UserID, - GoodID: ord.GoodID, - Units: ord.Units, - - ParentOrderID: ord.ParentOrderID, - ParentOrderGoodID: ord.ParentOrderGoodID, - - PaymentID: ord.PaymentID, - PaymentCoinTypeID: ord.PaymentCoinTypeID, - PaymentCoinUSDCurrency: ord.PaymentCoinUSDCurrency, - PaymentLiveUSDCurrency: ord.PaymentLiveUSDCurrency, - PaymentLocalUSDCurrency: ord.PaymentLocalUSDCurrency, - PaymentAmount: ord.PaymentAmount, - PaymentStartAmount: ord.PaymentStartAmount, - PaymentFinishAmount: ord.PaymentFinishAmount, - PayWithParent: ord.PayWithParent, - PayWithBalanceAmount: ord.PayWithBalanceAmount, - - FixAmountID: ord.FixAmountID, - DiscountID: ord.DiscountID, - SpecialOfferID: ord.SpecialOfferID, - - OrderType: ord.OrderType, - CreatedAt: ord.CreatedAt, - PaidAt: ord.PaidAt, - State: ord.OrderState, - - Start: ord.Start, - End: ord.End, - } - - user, err := usermwcli.GetUser(ctx, ord.AppID, ord.UserID) - if err != nil { + handler := &queryHandler{ + Handler: h, + orders: []*ordermwpb.Order{order}, + infos: []*npool.Order{}, + users: map[string]*usermwpb.User{}, + appGoods: map[string]*appgoodsmwpb.Good{}, + accountPayments: map[string]*payaccmwpb.Account{}, + coupons: map[string]*allocatedmwpb.Coupon{}, + coins: map[string]*appcoinmwpb.Coin{}, + } + if err := handler.getUsers(ctx); err != nil { return nil, err } - - if user == nil { - return nil, fmt.Errorf("invalid user") - } - - o.EmailAddress = user.EmailAddress - o.PhoneNO = user.PhoneNO - - appGood, err := appgoodscli.GetGoodOnly(ctx, &appgoodsmwpb.Conds{ - AppID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: ord.AppID, - }, - GoodID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: ord.GoodID, - }, - }) - if err != nil { + if err := handler.getAppGoods(ctx); err != nil { return nil, err } - - if appGood == nil { - return nil, fmt.Errorf("invalid app good") - } - - o.GoodName = appGood.GoodName - o.GoodUnit = appGood.Unit - o.GoodServicePeriodDays = uint32(appGood.DurationDays) - o.GoodUnitPrice = appGood.Price - - appGoodPrice, err := decimal.NewFromString(appGood.Price) - if err != nil { + if err := handler.getAccountPayments(ctx); err != nil { return nil, err } - units, err := decimal.NewFromString(ord.Units) - if err != nil { + if err := handler.getCoupons(ctx); err != nil { return nil, err } - o.GoodValue = appGoodPrice.Mul(units).String() - if appGood.PromotionPrice != nil { - appGoodPromotionPrice, err := decimal.NewFromString(*appGood.PromotionPrice) - if err != nil { - return nil, err - } - o.GoodValue = appGoodPromotionPrice.Mul(units).String() - } - - coin, err := coininfocli.GetCoin(ctx, appGood.CoinTypeID) - if err != nil { + if err := handler.getCoins(ctx); err != nil { return nil, err } - if coin == nil { - return nil, fmt.Errorf("invalid good coin") + handler.formalize(ctx) + if len(handler.infos) == 0 { + return nil, nil } - o.CoinTypeID = appGood.CoinTypeID - o.CoinName = coin.Name - o.CoinLogo = coin.Logo - o.CoinUnit = coin.Unit - o.CoinPresale = coin.Presale - - if ord.PaymentID != invalidID && ord.PaymentID != "" { - coin, err = coininfocli.GetCoin(ctx, ord.PaymentCoinTypeID) - if err != nil { - return nil, err - } - - if coin == nil { - return nil, fmt.Errorf("invalid payment coin") - } - } + return handler.infos[0], nil +} - if coin != nil { - o.PaymentCoinName = coin.Name - o.PaymentCoinLogo = coin.Logo - o.PaymentCoinUnit = coin.Unit +func (h *Handler) GetOrders(ctx context.Context) ([]*npool.Order, uint32, error) { + conds := &ordermwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, } - account, err := payaccmwcli.GetAccountOnly(ctx, &payaccmwpb.Conds{ - AccountID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: ord.PaymentAccountID, - }, - }) - if err != nil { - return nil, err + if h.UserID != nil { + conds.UserID = &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID} } - if account != nil { - o.PaymentAddress = account.Address + if h.IDs != nil && len(h.IDs) != 0 { + conds.IDs = &basetypes.StringSliceVal{Op: cruder.IN, Value: h.IDs} } - - coupons, _, err := allocatedmwcli.GetCoupons(ctx, &allocatedmwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: ord.AppID}, - IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: ord.CouponIDs}, - }, int32(0), int32(len(ord.CouponIDs))) + ords, total, err := ordercli.GetOrders(ctx, conds, h.Offset, h.Limit) if err != nil { - return nil, err - } - - couponMap := map[string]*allocatedmwpb.Coupon{} - for _, coup := range coupons { - couponMap[coup.ID] = coup + return nil, 0, err } - - for _, id := range ord.CouponIDs { - coup, ok := couponMap[id] - if !ok { - continue - } - - o.Coupons = append(o.Coupons, &npool.Coupon{ - CouponID: id, - CouponType: coup.CouponType, - CouponName: coup.CouponName, - CouponValue: coup.Denomination, - }) + if len(ords) == 0 { + return []*npool.Order{}, 0, nil } - return o, nil -} - -func (h *Handler) GetOrders(ctx context.Context) ([]*npool.Order, uint32, error) { handler := &queryHandler{ - Handler: h, - orders: []*npool.Order{}, + Handler: h, + orders: ords, + infos: []*npool.Order{}, + users: map[string]*usermwpb.User{}, + appGoods: map[string]*appgoodsmwpb.Good{}, + accountPayments: map[string]*payaccmwpb.Account{}, + coupons: map[string]*allocatedmwpb.Coupon{}, + coins: map[string]*appcoinmwpb.Coin{}, + } + if err := handler.getUsers(ctx); err != nil { + return nil, 0, err } - handler.setConds() - ords, total, err := ordercli.GetOrders(ctx, handler.conds, h.Offset, h.Limit) - if err != nil { + if err := handler.getAppGoods(ctx); err != nil { return nil, 0, err } - if len(ords) == 0 { - return []*npool.Order{}, 0, nil + if err := handler.getAccountPayments(ctx); err != nil { + return nil, 0, err } - handler.mwOrders = ords - - if err := handler.expand(ctx); err != nil { + if err := handler.getCoupons(ctx); err != nil { + return nil, 0, err + } + if err := handler.getCoins(ctx); err != nil { return nil, 0, err } - return handler.orders, total, nil + handler.formalize(ctx) + if len(handler.infos) == 0 { + return nil, total, nil + } + + return handler.infos, total, nil } diff --git a/pkg/order/update.go b/pkg/order/update.go index 0f8b750..40b2ce2 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -94,7 +94,7 @@ func (h *updateHandler) validate(ctx context.Context) error { return fmt.Errorf("order state is uncancellable") } - if uint32(time.Now().Unix()) >= h.ord.Start-appgood.CancellableBeforeStart { + if uint32(time.Now().Unix()) >= h.ord.StartAt-appgood.CancellableBeforeStart { return fmt.Errorf("cancellable time exceeded") } case goodtypes.CancelMode_CancellableBeforeBenefit: @@ -106,8 +106,8 @@ func (h *updateHandler) validate(ctx context.Context) error { return fmt.Errorf("order state is uncancellable") } - if uint32(time.Now().Unix()) >= h.ord.Start-appgood.CancellableBeforeStart && - uint32(time.Now().Unix()) <= h.ord.Start+appgood.CancellableBeforeStart { + if uint32(time.Now().Unix()) >= h.ord.StartAt-appgood.CancellableBeforeStart && + uint32(time.Now().Unix()) <= h.ord.StartAt+appgood.CancellableBeforeStart { return fmt.Errorf("app good uncancellable order start at > cancellable before start") } default: @@ -140,11 +140,10 @@ func (h *updateHandler) processOrderState(ctx context.Context) error { state := ordertypes.OrderState_OrderStateCanceled paymentState := ordertypes.PaymentState_PaymentStateCanceled _, err := ordermwcli.UpdateOrder(ctx, &ordermwpb.OrderReq{ - ID: &h.ord.ID, - State: &state, - PaymentState: &paymentState, - PaymentID: &h.ord.PaymentID, - Canceled: &cancle, + ID: &h.ord.ID, + OrderState: &state, + PaymentState: &paymentState, + UserSetCanceled: &cancle, }) if err != nil { return err @@ -240,7 +239,7 @@ func (h *updateHandler) processLedger(ctx context.Context) error { return err } - payWithBalanceAmount, err := decimal.NewFromString(h.ord.PayWithBalanceAmount) + payWithBalanceAmount, err := decimal.NewFromString(h.ord.BalanceAmount) if err != nil { return err } @@ -376,11 +375,10 @@ func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { return nil, fmt.Errorf("permission denied") } _, err = ordermwcli.UpdateOrder(ctx, &ordermwpb.OrderReq{ - ID: h.ID, - AppID: h.AppID, - UserID: h.UserID, - PaymentID: h.PaymentID, - Canceled: h.Canceled, + ID: h.ID, + AppID: h.AppID, + UserID: h.UserID, + UserSetCanceled: h.Canceled, }) if err != nil { return nil, err From 8cc54e9f2c7786ad1c426bd3b71eb84b4861b1d3 Mon Sep 17 00:00:00 2001 From: jakys Date: Fri, 1 Sep 2023 09:57:03 +0000 Subject: [PATCH 05/67] Fix update cancel --- api/order/update.go | 10 +++++----- pkg/order/handler.go | 19 ++++++++++++++++--- pkg/order/update.go | 26 +++++++++++++++----------- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/api/order/update.go b/api/order/update.go index 818046b..d302013 100644 --- a/api/order/update.go +++ b/api/order/update.go @@ -20,7 +20,7 @@ func (s *Server) UpdateOrder(ctx context.Context, in *npool.UpdateOrderRequest) order1.WithAppID(&in.AppID, true), order1.WithUserID(&in.AppID, &in.UserID, true), order1.WithPaymentID(&in.PaymentID, true), - order1.WithCanceled(in.Canceled, true), + order1.WithUserSetCanceled(in.Canceled, true), order1.WithFromAdmin(false), ) if err != nil { @@ -54,8 +54,8 @@ func (s *Server) UpdateUserOrder(ctx context.Context, in *npool.UpdateUserOrderR order1.WithAppID(&in.AppID, true), order1.WithUserID(&in.AppID, &in.TargetUserID, true), order1.WithPaymentID(&in.PaymentID, true), - order1.WithCanceled(in.Canceled, true), - order1.WithFromAdmin(false), + order1.WithAdminSetCanceled(in.Canceled, true), + order1.WithFromAdmin(true), ) if err != nil { logger.Sugar().Errorw( @@ -88,8 +88,8 @@ func (s *Server) UpdateAppUserOrder(ctx context.Context, in *npool.UpdateAppUser order1.WithAppID(&in.TargetAppID, true), order1.WithUserID(&in.TargetAppID, &in.TargetUserID, true), order1.WithPaymentID(&in.PaymentID, true), - order1.WithCanceled(in.Canceled, true), - order1.WithFromAdmin(false), + order1.WithAdminSetCanceled(in.Canceled, true), + order1.WithFromAdmin(true), ) if err != nil { logger.Sugar().Errorw( diff --git a/pkg/order/handler.go b/pkg/order/handler.go index f9fe25c..1c7466d 100644 --- a/pkg/order/handler.go +++ b/pkg/order/handler.go @@ -27,7 +27,8 @@ type Handler struct { OrderType *ordertypes.OrderType CouponIDs []string InvestmentType *ordertypes.InvestmentType - Canceled *bool + UserSetCanceled *bool + AdminSetCanceled *bool FromAdmin bool PaymentID *string Offset int32 @@ -234,7 +235,7 @@ func WithInvestmentType(investmentType *ordertypes.InvestmentType, must bool) fu } } -func WithCanceled(value *bool, must bool) func(context.Context, *Handler) error { +func WithUserSetCanceled(value *bool, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { if value == nil { if must { @@ -242,11 +243,23 @@ func WithCanceled(value *bool, must bool) func(context.Context, *Handler) error } return nil } - h.Canceled = value + h.UserSetCanceled = value return nil } } +func WithAdminSetCanceled(value *bool, must bool) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + if value == nil { + if must { + return fmt.Errorf("invalid canceled") + } + return nil + } + h.AdminSetCanceled = value + return nil + } +} func WithFromAdmin(value bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { h.FromAdmin = value diff --git a/pkg/order/update.go b/pkg/order/update.go index 40b2ce2..fdf463b 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -136,14 +136,14 @@ func (h *updateHandler) processStock(ctx context.Context) error { } func (h *updateHandler) processOrderState(ctx context.Context) error { - cancle := true state := ordertypes.OrderState_OrderStateCanceled paymentState := ordertypes.PaymentState_PaymentStateCanceled _, err := ordermwcli.UpdateOrder(ctx, &ordermwpb.OrderReq{ - ID: &h.ord.ID, - OrderState: &state, - PaymentState: &paymentState, - UserSetCanceled: &cancle, + ID: &h.ord.ID, + OrderState: &state, + PaymentState: &paymentState, + UserSetCanceled: h.UserSetCanceled, + AdminSetCanceled: h.AdminSetCanceled, }) if err != nil { return err @@ -342,7 +342,7 @@ func (h *updateHandler) cancelNormalOrder(ctx context.Context) error { //nolint:gocyclo func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { - if h.Canceled == nil { + if h.UserSetCanceled == nil && h.AdminSetCanceled == nil { return nil, fmt.Errorf("nothing todo") } if h.ID == nil || *h.ID == "" { @@ -360,7 +360,10 @@ func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { if *h.AppID != ord.AppID || *h.UserID != ord.UserID { return nil, fmt.Errorf("permission denied") } - if !*h.Canceled { + if h.UserSetCanceled != nil && !*h.UserSetCanceled { + return h.GetOrder(ctx) + } + if h.AdminSetCanceled != nil && !*h.AdminSetCanceled { return h.GetOrder(ctx) } @@ -375,10 +378,11 @@ func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { return nil, fmt.Errorf("permission denied") } _, err = ordermwcli.UpdateOrder(ctx, &ordermwpb.OrderReq{ - ID: h.ID, - AppID: h.AppID, - UserID: h.UserID, - UserSetCanceled: h.Canceled, + ID: h.ID, + AppID: h.AppID, + UserID: h.UserID, + UserSetCanceled: h.UserSetCanceled, + AdminSetCanceled: h.AdminSetCanceled, }) if err != nil { return nil, err From 4b645d0169e0aeec3926aef0d76bd01f3b59c366 Mon Sep 17 00:00:00 2001 From: jakys Date: Fri, 1 Sep 2023 09:57:14 +0000 Subject: [PATCH 06/67] Fix create --- go.mod | 4 +- go.sum | 8 +- pkg/order/create.go | 501 ++++++++++++++++++++------------------------ 3 files changed, 233 insertions(+), 280 deletions(-) diff --git a/go.mod b/go.mod index 1afef7f..7d1a756 100644 --- a/go.mod +++ b/go.mod @@ -13,8 +13,8 @@ require ( github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230827161127-ec28b0f14ec0 github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 - github.com/NpoolPlatform/message v0.0.0-20230828122703-3aa63ff5da47 - github.com/NpoolPlatform/order-middleware v0.0.0-20230828144010-05748d247a78 + github.com/NpoolPlatform/message v0.0.0-20230831065350-7de0d7db7a9e + github.com/NpoolPlatform/order-middleware v0.0.0-20230831084837-3416b99e025c github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/dtm-labs/dtm v1.17.1 github.com/go-resty/resty/v2 v2.7.0 diff --git a/go.sum b/go.sum index 4f3021f..e28dc4f 100644 --- a/go.sum +++ b/go.sum @@ -68,10 +68,10 @@ github.com/NpoolPlatform/ledger-middleware v0.0.0-20230827161127-ec28b0f14ec0 h1 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230827161127-ec28b0f14ec0/go.mod h1:MiA18NKwLyyjE6FnrGO+ChFEWbJ02xdwnQMZFtvQ1aQ= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB4NuhQxXWeV0Z1qSxgIqbiMYU30dqFGDLtgNTqYbE= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= -github.com/NpoolPlatform/message v0.0.0-20230828122703-3aa63ff5da47 h1:DZNPxdGojpxit630EjHVnuCg7YAIr/JWdHt8s1QSoDM= -github.com/NpoolPlatform/message v0.0.0-20230828122703-3aa63ff5da47/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= -github.com/NpoolPlatform/order-middleware v0.0.0-20230828144010-05748d247a78 h1:nygQPwPf8DR6/pdkBIK3Zc3izJuz9E7XmYZNx5VuFJk= -github.com/NpoolPlatform/order-middleware v0.0.0-20230828144010-05748d247a78/go.mod h1:N/GM1Xme4/Zl2L1mA0nJezPcuF+HAHnamTxAYYmtMss= +github.com/NpoolPlatform/message v0.0.0-20230831065350-7de0d7db7a9e h1:Y6S5uevdzkQrCSprUVR9hZwIl9byJ9hvrvjwQ8JLdo4= +github.com/NpoolPlatform/message v0.0.0-20230831065350-7de0d7db7a9e/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/order-middleware v0.0.0-20230831084837-3416b99e025c h1:qbmhOwSVzhbmd3fHrdXjSc5FP7QrJI+bc9+1jSIEh5E= +github.com/NpoolPlatform/order-middleware v0.0.0-20230831084837-3416b99e025c/go.mod h1:k0KDLGY+8iAJtYW2Iwp3nElEfiX/biLp5tjgJxNYPrw= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b/go.mod h1:9C9XDi7c0szxcLdJGDDFuo3/KtC74yWiyUM2fR+i0ww= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= diff --git a/pkg/order/create.go b/pkg/order/create.go index 4afa256..03b5380 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -8,11 +8,11 @@ import ( dtmcli "github.com/NpoolPlatform/dtm-cluster/pkg/dtm" "github.com/NpoolPlatform/go-service-framework/pkg/logger" "github.com/dtm-labs/dtm/client/dtmcli/dtmimp" + "github.com/google/uuid" cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" ordermwsvcname "github.com/NpoolPlatform/order-middleware/pkg/servicename" - appgoodstockmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/stock" appgoodstockmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/stock" appcoinmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/app/coin" @@ -49,32 +49,57 @@ type createHandler struct { *Handler orderGood *OrderGood - discountAmount decimal.Decimal - paymentAmountUSD decimal.Decimal - paymentAmountCoin decimal.Decimal + startAts map[string]uint32 + endAts map[string]uint32 - promotionID string - paymentCoinName string - paymentAddress string - paymentAddressStartAmount decimal.Decimal - goodPaymentID string - paymentAccountID string + reductionAmount decimal.Decimal + reductionPercent decimal.Decimal - goodPrices map[string]decimal.Decimal - goodValues map[string]decimal.Decimal - goodValueUSDs map[string]decimal.Decimal - paymentType ordertypes.PaymentType - paymentTransferAmount decimal.Decimal + goodPrices map[string]decimal.Decimal liveCurrency decimal.Decimal localCurrency decimal.Decimal coinCurrency decimal.Decimal - reductionAmount decimal.Decimal - reductionPercent decimal.Decimal + goodValueCoins map[string]decimal.Decimal + goodValueUSDs map[string]decimal.Decimal + paymentAmountUSD decimal.Decimal + paymentAmountCoin decimal.Decimal + discountAmountCoin decimal.Decimal + paymentTransferAmount decimal.Decimal - startAts map[string]uint32 - endAts map[string]uint32 + paymentCoinName string + paymentAddress string + paymentAddressStartAmount decimal.Decimal + paymentID string + paymentAccountID string + + ledger *ledgermwpb.Ledger +} + +func tomorrowStart() time.Time { + now := time.Now() + y, m, d := now.Date() + return time.Date(y, m, d+1, 0, 0, 0, 0, now.Location()) +} + +func (h *createHandler) paymentType() (*ordertypes.PaymentType, error) { + switch *h.OrderType { + case ordertypes.OrderType_Normal: + if h.BalanceAmount != nil { + if h.paymentTransferAmount.Cmp(decimal.NewFromInt(0)) > 0 { + return ordertypes.PaymentType_PayWithTransferAndBalance.Enum(), nil + } + return ordertypes.PaymentType_PayWithBalanceOnly.Enum(), nil + } + return ordertypes.PaymentType_PayWithTransferOnly.Enum(), nil + case ordertypes.OrderType_Offline: + return ordertypes.PaymentType_PayWithOffline.Enum(), nil + case ordertypes.OrderType_Airdrop: + return ordertypes.PaymentType_PayWithNoPayment.Enum(), nil + default: + return nil, fmt.Errorf("invalid ordertype") + } } func (h *createHandler) validateInit(ctx context.Context) error { @@ -91,6 +116,7 @@ func (h *createHandler) validateInit(ctx context.Context) error { if !coin.ForPay { return fmt.Errorf("coin not for payment") } + h.paymentCoinName = coin.Name for _, goodReq := range h.Goods { good := h.orderGood.goods[goodReq.GoodID] @@ -121,8 +147,6 @@ func (h *createHandler) validateInit(ctx context.Context) error { h.endAts[*h.AppID+goodReq.GoodID] = endAt } - h.paymentCoinName = coin.Name - const maxUnpaidOrders = 5 orders, _, err := ordermwcli.GetOrders(ctx, &ordermwpb.Conds{ AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, @@ -167,6 +191,7 @@ func (h *createHandler) SetReduction(ctx context.Context) error { return fmt.Errorf("coupon already used") } + couponTypeDiscountNum := 0 for _, coup := range coupons { if !coup.Valid || coup.Expired || coup.AppID != *h.AppID || coup.UserID != *h.UserID { return fmt.Errorf("invalid coupon") @@ -181,6 +206,9 @@ func (h *createHandler) SetReduction(ctx context.Context) error { } h.reductionAmount = h.reductionAmount.Add(amount) case inspiretypes.CouponType_Discount: + if couponTypeDiscountNum > 1 { + return fmt.Errorf("invalid discount") + } percent, err := decimal.NewFromString(coup.Denomination) if err != nil { return err @@ -189,6 +217,7 @@ func (h *createHandler) SetReduction(ctx context.Context) error { return fmt.Errorf("invalid discount") } h.reductionPercent = percent + couponTypeDiscountNum++ default: return fmt.Errorf("unknown coupon type") } @@ -279,8 +308,16 @@ func (h *createHandler) SetCurrency(ctx context.Context) error { return nil } -func (h *createHandler) SetPaymentAmount(ctx context.Context) error { +func getAccuracy(coin decimal.Decimal) decimal.Decimal { const accuracy = 1000000 + coin = coin.Mul(decimal.NewFromInt(accuracy)) + coin = coin.Ceil() + coin = coin.Div(decimal.NewFromInt(accuracy)) + return coin +} + +func (h *createHandler) SetPaymentAmount(ctx context.Context) error { + totalPaymentAmountCoin := decimal.NewFromInt(0) totalPaymentAmountUSD := decimal.NewFromInt(0) for _, goodReq := range h.Goods { price := h.goodPrices[*h.AppID+goodReq.GoodID] @@ -289,40 +326,35 @@ func (h *createHandler) SetPaymentAmount(ctx context.Context) error { return err } paymentAmountUSD := price.Mul(units) - h.goodValueUSDs[goodReq.GoodID] = paymentAmountUSD totalPaymentAmountUSD = totalPaymentAmountUSD.Add(paymentAmountUSD) + h.goodValueUSDs[goodReq.GoodID] = paymentAmountUSD - goodValue := paymentAmountUSD.Div(h.coinCurrency) - goodValue = goodValue.Mul(decimal.NewFromInt(accuracy)) - goodValue = goodValue.Ceil() - goodValue = goodValue.Div(decimal.NewFromInt(accuracy)) - h.goodValues[goodReq.GoodID] = goodValue + goodValueCoin := paymentAmountUSD.Div(h.coinCurrency) + goodValueCoin = getAccuracy(goodValueCoin) + totalPaymentAmountCoin = totalPaymentAmountCoin.Add(goodValueCoin) + h.goodValueCoins[goodReq.GoodID] = goodValueCoin } - h.paymentAmountUSD = totalPaymentAmountUSD logger.Sugar().Infow( "CreateOrder", - "PaymentAmountUSD", h.paymentAmountUSD, + "PaymentAmountUSD", totalPaymentAmountUSD, "ReductionAmount", h.reductionAmount, "ReductionPercent", h.reductionPercent, ) - h.discountAmount = h.paymentAmountUSD. + discountAmountUSD := totalPaymentAmountUSD. Mul(h.reductionPercent). Div(decimal.NewFromInt(100)). //nolint Add(h.reductionAmount) - h.paymentAmountUSD = totalPaymentAmountUSD.Sub(h.discountAmount) + h.discountAmountCoin = discountAmountUSD.Div(h.coinCurrency) + h.discountAmountCoin = getAccuracy(h.discountAmountCoin) - if h.paymentAmountUSD.Cmp(decimal.NewFromInt(0)) < 0 { - h.paymentAmountUSD = decimal.NewFromInt(0) + h.paymentAmountCoin = totalPaymentAmountCoin.Sub(h.discountAmountCoin) + if h.paymentAmountCoin.Cmp(decimal.NewFromInt(0)) < 0 { + h.paymentAmountCoin = decimal.NewFromInt(0) } - h.paymentAmountCoin = h.paymentAmountUSD.Div(h.coinCurrency) - h.paymentAmountCoin = h.paymentAmountCoin.Mul(decimal.NewFromInt(accuracy)) - h.paymentAmountCoin = h.paymentAmountCoin.Ceil() - h.paymentAmountCoin = h.paymentAmountCoin.Div(decimal.NewFromInt(accuracy)) - h.paymentTransferAmount = h.paymentAmountCoin if h.BalanceAmount != nil { amount, err := decimal.NewFromString(*h.BalanceAmount) @@ -431,7 +463,7 @@ func (h *createHandler) peekAddress(ctx context.Context) (*payaccmwpb.Account, e return nil, nil } - h.goodPaymentID = account.ID + h.paymentID = account.ID return account, nil } @@ -473,7 +505,7 @@ func (h *createHandler) ReleaseAddress(ctx context.Context) error { locked := false _, err := payaccmwcli.UpdateAccount(ctx, &payaccmwpb.AccountReq{ - ID: &h.goodPaymentID, + ID: &h.paymentID, Locked: &locked, }) @@ -515,31 +547,26 @@ func (h *createHandler) withUpdateStock(dispose *dtmcli.SagaDispose) { } } -func (h *createHandler) LockStock(ctx context.Context) error { - _, err := appgoodstockmwcli.AddStock(ctx, &appgoodstockmwpb.StockReq{ - AppID: h.AppID, - GoodID: h.GoodID, - Locked: &h.Units, - }) - if err != nil { - return err - } - return nil -} - -func (h *createHandler) ReleaseStock(ctx context.Context) error { - _, err := appgoodstockmwcli.SubStock(ctx, &appgoodstockmwpb.StockReq{ - AppID: h.AppID, - GoodID: h.GoodID, - Locked: &h.Units, - }) - if err != nil { - return err +func (h *createHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { + req := &ledgermwpb.LedgerReq{ + ID: &h.ledger.ID, + AppID: h.AppID, + UserID: h.UserID, + CoinTypeID: &h.ledger.CoinTypeID, + Locked: h.BalanceAmount, + Spendable: h.BalanceAmount, } - return nil + dispose.Add( + ordermwsvcname.ServiceDomain, + "ledger.middleware.ledger.v2.Middleware/SubBalance", + "ledger.middleware.ledger.v2.Middleware/AddBalance", + &ledgermwpb.AddBalanceRequest{ + Info: req, + }, + ) } -func (h *createHandler) LockBalance(ctx context.Context) error { +func (h *createHandler) CheckBalance(ctx context.Context) error { if h.BalanceAmount == nil { return nil } @@ -574,135 +601,123 @@ func (h *createHandler) LockBalance(ctx context.Context) error { return fmt.Errorf("insufficient balance") } - _, err = ledgermwcli.SubBalance(ctx, &ledgermwpb.LedgerReq{ - ID: &general.ID, - AppID: &general.AppID, - UserID: &general.UserID, - CoinTypeID: &general.CoinTypeID, - Locked: h.BalanceAmount, - Spendable: h.BalanceAmount, - }) - - return err -} - -func (h *createHandler) ReleaseBalance(ctx context.Context) error { - if h.BalanceAmount == nil { - return nil - } - - ba, err := decimal.NewFromString(*h.BalanceAmount) - if err != nil { - return err - } - - if ba.Cmp(decimal.NewFromInt(0)) <= 0 { - return nil - } - - general, err := ledgermwcli.GetLedgerOnly(ctx, &ledgermwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, - CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, - }) - if err != nil { - return err - } - if general == nil { - return fmt.Errorf("insufficuent funds") - } - - lockedMinus := fmt.Sprintf("-%v", h.BalanceAmount) - - _, err = ledgermwcli.AddBalance(ctx, &ledgermwpb.LedgerReq{ - ID: &general.ID, - AppID: &general.AppID, - UserID: &general.UserID, - CoinTypeID: &general.CoinTypeID, - Locked: &lockedMinus, - Spendable: h.BalanceAmount, - }) - - return err -} + h.ledger = general -func tomorrowStart() time.Time { - now := time.Now() - y, m, d := now.Date() - return time.Date(y, m, d+1, 0, 0, 0, 0, now.Location()) + return nil } -func (h *createHandler) create(ctx context.Context) (*npool.Order, error) { +func (h *createHandler) setCreateReqs(ctx context.Context) ([]*ordermwpb.OrderReq, error) { paymentAmount := h.paymentAmountCoin.String() startAmount := h.paymentAddressStartAmount.String() + paymentTransferAmount := h.paymentTransferAmount.String() coinCurrency := h.coinCurrency.String() liveCurrency := h.liveCurrency.String() localCurrency := h.localCurrency.String() - goodValue := h.goodValues[*h.GoodID].String() - goodValueUSD := h.goodValueUSDs[*h.GoodID].String() - discountAmount := h.discountAmount.String() - paymentTransferAmount := h.paymentTransferAmount.String() - - // Top order never pay with parent, only sub order may - topmostGood := h.orderGood.topMostGoods[*h.AppID+*h.GoodID] - if topmostGood != nil { - h.promotionID = topmostGood.TopMostID + discountAmountCoin := h.discountAmountCoin.String() + childPaymentType := ordertypes.PaymentType_PayWithParentOrder + zeroAmount := "0" + orderID := uuid.NewString() + paymentType, err := h.paymentType() + if err != nil { + return nil, err } - appgood := h.orderGood.appgoods[*h.AppID+*h.GoodID] - good := h.orderGood.goods[*h.GoodID] - goodDurationDays := uint32(good.DurationDays) - startAt := h.startAts[*h.AppID+*h.GoodID] - endAt := h.endAts[*h.AppID+*h.GoodID] + orderReqs := []*ordermwpb.OrderReq{} + for _, goodReq := range h.Goods { + goodValue := h.goodValueCoins[goodReq.GoodID].String() + goodValueUSD := h.goodValueUSDs[goodReq.GoodID].String() + appgood := h.orderGood.appgoods[*h.AppID+goodReq.GoodID] + good := h.orderGood.goods[goodReq.GoodID] + goodDurationDays := uint32(good.DurationDays) + startAt := h.startAts[*h.AppID+goodReq.GoodID] + endAt := h.endAts[*h.AppID+goodReq.GoodID] - logger.Sugar().Infow( - "CreateOrder", - "PaymentAmountUSD", h.paymentAmountUSD, - "PaymentAmountCoin", h.paymentAmountCoin, - "BalanceAmount", h.BalanceAmount, - "ReductionAmount", h.reductionAmount, - "ReductionPercent", h.reductionPercent, - "PaymentAddressStartAmount", h.paymentAddressStartAmount, - "CoinCurrency", h.coinCurrency, - "LiveCurrency", h.liveCurrency, - "LocalCurrency", h.localCurrency, - ) + logger.Sugar().Infow( + "CreateOrder", + "PaymentAmountCoin", h.paymentAmountCoin, + "BalanceAmount", h.BalanceAmount, + "ReductionAmount", h.reductionAmount, + "ReductionPercent", h.reductionPercent, + "PaymentAddressStartAmount", h.paymentAddressStartAmount, + "CoinCurrency", h.coinCurrency, + "LiveCurrency", h.liveCurrency, + "LocalCurrency", h.localCurrency, + ) + orderReq := &ordermwpb.OrderReq{ + AppID: h.AppID, + UserID: h.UserID, + GoodID: &goodReq.GoodID, + AppGoodID: &appgood.ID, + Units: &goodReq.Units, + GoodValue: &goodValue, + GoodValueUSD: &goodValueUSD, + DurationDays: &goodDurationDays, + OrderType: h.OrderType, + InvestmentType: h.InvestmentType, + CoinTypeID: &good.CoinTypeID, + PaymentCoinTypeID: h.PaymentCoinID, + CoinUSDCurrency: &coinCurrency, + LiveCoinUSDCurrency: &liveCurrency, + LocalCoinUSDCurrency: &localCurrency, + StartAt: &startAt, + EndAt: &endAt, + } - ord, err := ordermwcli.CreateOrder(ctx, &ordermwpb.OrderReq{ - AppID: h.AppID, - UserID: h.UserID, - GoodID: h.GoodID, - AppGoodID: &appgood.ID, - ParentOrderID: h.ParentOrderID, - Units: &h.Units, - GoodValue: &goodValue, - GoodValueUSD: &goodValueUSD, - PaymentAmount: &paymentAmount, - DiscountAmount: &discountAmount, - PromotionID: &h.promotionID, - DurationDays: &goodDurationDays, - OrderType: h.OrderType, - InvestmentType: h.InvestmentType, - CouponIDs: h.CouponIDs, - PaymentType: &h.paymentType, - PaymentAccountID: &h.paymentAccountID, - CoinTypeID: &good.CoinTypeID, - PaymentCoinTypeID: h.PaymentCoinID, - PaymentStartAmount: &startAmount, - TransferAmount: &paymentTransferAmount, - BalanceAmount: h.BalanceAmount, - CoinUSDCurrency: &coinCurrency, - LiveCoinUSDCurrency: &liveCurrency, - LocalCoinUSDCurrency: &localCurrency, - StartAt: &startAt, - EndAt: &endAt, - }) - if err != nil { - return nil, err + if !goodReq.Parent && h.ParentOrderID == nil { + id := uuid.NewString() + // batch child order + orderReq.ID = &id + orderReq.ParentOrderID = &orderID + orderReq.PaymentAmount = &zeroAmount + orderReq.DiscountAmount = &zeroAmount + orderReq.PaymentType = &childPaymentType + orderReq.TransferAmount = &zeroAmount + orderReq.BalanceAmount = &zeroAmount + h.IDs = append(h.IDs, id) + } else { + // parent order or single order + orderReq.ID = &orderID + orderReq.ParentOrderID = h.ParentOrderID + orderReq.PaymentAmount = &paymentAmount + orderReq.DiscountAmount = &discountAmountCoin + orderReq.CouponIDs = h.CouponIDs + orderReq.PaymentType = paymentType + orderReq.TransferAmount = &paymentTransferAmount + orderReq.BalanceAmount = h.BalanceAmount + orderReq.PaymentAccountID = &h.paymentAccountID + orderReq.PaymentStartAmount = &startAmount + h.IDs = append(h.IDs, orderID) + } + + topmostGood := h.orderGood.topMostGoods[*h.AppID+goodReq.GoodID] + if topmostGood != nil { + orderReq.PromotionID = &topmostGood.TopMostID + } + orderReqs = append(orderReqs, orderReq) } - h.ID = &ord.ID + return orderReqs, nil +} + +func (h *createHandler) withCreateOrder(dispose *dtmcli.SagaDispose, req *ordermwpb.OrderReq) { + dispose.Add( + ordermwsvcname.ServiceDomain, + "order.middleware.order1.v1.Middleware/CreateOrder", + "", + &ordermwpb.CreateOrderRequest{ + Info: req, + }, + ) +} - return h.GetOrder(ctx) +func (h *createHandler) withCreateOrders(dispose *dtmcli.SagaDispose, reqs []*ordermwpb.OrderReq) { + dispose.Add( + ordermwsvcname.ServiceDomain, + "order.middleware.order1.v1.Middleware/CreateOrders", + "", + &ordermwpb.CreateOrdersRequest{ + Infos: reqs, + }, + ) } func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error) { @@ -743,112 +758,42 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error return nil, err } - if err := handler.LockStock(ctx); err != nil { - _ = handler.ReleaseAddress(ctx) - return nil, err - } - - if err := handler.LockBalance(ctx); err != nil { + if err := handler.CheckBalance(ctx); err != nil { _ = handler.ReleaseAddress(ctx) - _ = handler.ReleaseStock(ctx) return nil, err } - ord, err := handler.create(ctx) + createReqs, err := handler.setCreateReqs(ctx) if err != nil { _ = handler.ReleaseAddress(ctx) - _ = handler.ReleaseStock(ctx) - _ = handler.ReleaseBalance(ctx) return nil, err } - return ord, nil -} - -func (h *createHandler) creates(ctx context.Context) ([]*npool.Order, error) { - paymentAmount := h.paymentAmountCoin.String() - startAmount := h.paymentAddressStartAmount.String() - paymentTransferAmount := h.paymentTransferAmount.String() - coinCurrency := h.coinCurrency.String() - liveCurrency := h.liveCurrency.String() - localCurrency := h.localCurrency.String() - discountAmount := h.discountAmount.String() - - orderReqs := []*ordermwpb.OrderReq{} - for _, goodReq := range h.Goods { - goodValue := h.goodValues[goodReq.GoodID].String() - goodValueUSD := h.goodValueUSDs[goodReq.GoodID].String() - // Top order never pay with parent, only sub order may - topmostGood := h.orderGood.topMostGoods[*h.AppID+goodReq.GoodID] - if topmostGood != nil { - h.promotionID = topmostGood.TopMostID - } - - appgood := h.orderGood.appgoods[*h.AppID+goodReq.GoodID] - good := h.orderGood.goods[goodReq.GoodID] - goodDurationDays := uint32(good.DurationDays) - startAt := h.startAts[*h.AppID+goodReq.GoodID] - endAt := h.endAts[*h.AppID+goodReq.GoodID] + sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ + WaitResult: true, + RequestTimeout: handler.RequestTimeoutSeconds, + }) - logger.Sugar().Infow( - "CreateOrder", - "PaymentAmountUSD", h.paymentAmountUSD, - "PaymentAmountCoin", h.paymentAmountCoin, - "BalanceAmount", h.BalanceAmount, - "ReductionAmount", h.reductionAmount, - "ReductionPercent", h.reductionPercent, - "PaymentAddressStartAmount", h.paymentAddressStartAmount, - "CoinCurrency", h.coinCurrency, - "LiveCurrency", h.liveCurrency, - "LocalCurrency", h.localCurrency, - ) - orderReq := &ordermwpb.OrderReq{ - AppID: h.AppID, - UserID: h.UserID, - GoodID: h.GoodID, - AppGoodID: &appgood.ID, - ParentOrderID: h.ParentOrderID, - Units: &h.Units, - GoodValue: &goodValue, - GoodValueUSD: &goodValueUSD, - PaymentAmount: &paymentAmount, - DiscountAmount: &discountAmount, - PromotionID: &h.promotionID, - DurationDays: &goodDurationDays, - OrderType: h.OrderType, - InvestmentType: h.InvestmentType, - CouponIDs: h.CouponIDs, - PaymentType: &h.paymentType, - CoinTypeID: &good.CoinTypeID, - PaymentCoinTypeID: h.PaymentCoinID, - TransferAmount: &paymentTransferAmount, - BalanceAmount: h.BalanceAmount, - CoinUSDCurrency: &coinCurrency, - LiveCoinUSDCurrency: &liveCurrency, - LocalCoinUSDCurrency: &localCurrency, - StartAt: &startAt, - EndAt: &endAt, - } - if goodReq.Parent { - orderReq.PaymentAccountID = &h.paymentAccountID - orderReq.PaymentStartAmount = &startAmount - } - orderReqs = append(orderReqs, orderReq) + handler.withUpdateStock(sagaDispose) + if h.BalanceAmount != nil { + handler.withUpdateBalance(sagaDispose) } + handler.withCreateOrders(sagaDispose, createReqs) - orders, err := ordermwcli.CreateOrders(ctx, orderReqs) - if err != nil { + if err := dtmcli.WithSaga(ctx, sagaDispose); err != nil { + _ = handler.ReleaseAddress(ctx) return nil, err } - for key := range orders { - h.IDs = append(h.IDs, orders[key].ID) - } - infos, _, err := h.GetOrders(ctx) + orders, _, err := h.GetOrders(ctx) if err != nil { return nil, err } - return infos, nil + if len(orders) == 0 { + return nil, nil + } + + return orders[0], nil } func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err error) { @@ -889,27 +834,35 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e return nil, err } + if err := handler.CheckBalance(ctx); err != nil { + _ = handler.ReleaseAddress(ctx) + return nil, err + } + + createReqs, err := handler.setCreateReqs(ctx) + if err != nil { + _ = handler.ReleaseAddress(ctx) + return nil, err + } + sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ WaitResult: true, RequestTimeout: handler.RequestTimeoutSeconds, }) handler.withUpdateStock(sagaDispose) - - if err := dtmcli.WithSaga(ctx, sagaDispose); err != nil { - _ = handler.ReleaseAddress(ctx) - return nil, err + if h.BalanceAmount != nil { + handler.withUpdateBalance(sagaDispose) } + handler.withCreateOrders(sagaDispose, createReqs) - if err := handler.LockBalance(ctx); err != nil { + if err := dtmcli.WithSaga(ctx, sagaDispose); err != nil { _ = handler.ReleaseAddress(ctx) return nil, err } - orders, err := handler.creates(ctx) + orders, _, err := h.GetOrders(ctx) if err != nil { - _ = handler.ReleaseAddress(ctx) - _ = handler.ReleaseBalance(ctx) return nil, err } From f8c210db058ef1f48945f610442bc8403dabe877 Mon Sep 17 00:00:00 2001 From: jakys Date: Mon, 4 Sep 2023 08:55:42 +0000 Subject: [PATCH 07/67] Fix create --- go.mod | 6 +- go.sum | 12 +- pkg/order/create.go | 280 +++++++++++++++++++++++------------------ pkg/order/ordergood.go | 25 +++- 4 files changed, 189 insertions(+), 134 deletions(-) diff --git a/go.mod b/go.mod index 7d1a756..5c760c4 100644 --- a/go.mod +++ b/go.mod @@ -11,10 +11,10 @@ require ( github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e github.com/NpoolPlatform/good-middleware v0.0.0-20230823034851-d6449a27f3e1 github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 - github.com/NpoolPlatform/ledger-middleware v0.0.0-20230827161127-ec28b0f14ec0 + github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7 github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 - github.com/NpoolPlatform/message v0.0.0-20230831065350-7de0d7db7a9e - github.com/NpoolPlatform/order-middleware v0.0.0-20230831084837-3416b99e025c + github.com/NpoolPlatform/message v0.0.0-20230904073655-1d217e96c6bb + github.com/NpoolPlatform/order-middleware v0.0.0-20230904074503-7a4d8ebbef6b github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/dtm-labs/dtm v1.17.1 github.com/go-resty/resty/v2 v2.7.0 diff --git a/go.sum b/go.sum index e28dc4f..010682b 100644 --- a/go.sum +++ b/go.sum @@ -64,14 +64,14 @@ github.com/NpoolPlatform/good-middleware v0.0.0-20230823034851-d6449a27f3e1 h1:m github.com/NpoolPlatform/good-middleware v0.0.0-20230823034851-d6449a27f3e1/go.mod h1:m0iZ5NxrwNXbkpAvqA/cjWGpzQAc5bPGfcOsPgO7KiQ= github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 h1:5W7RWU/meU1ZkPiUjqKAnyBKsjJ6NZu3dCfc0hgjhRs= github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2/go.mod h1:CCCI+S1AecMrRdRruOgMUxM9JaIXIYVt3DID04TuOoc= -github.com/NpoolPlatform/ledger-middleware v0.0.0-20230827161127-ec28b0f14ec0 h1:c3wAy6HooN5Zuqd2I7h5+IU0UoXIiLFREUG+d0fPq18= -github.com/NpoolPlatform/ledger-middleware v0.0.0-20230827161127-ec28b0f14ec0/go.mod h1:MiA18NKwLyyjE6FnrGO+ChFEWbJ02xdwnQMZFtvQ1aQ= +github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7 h1:ol3ynwtsKf5SdLMEMjLDcas1s51mDPmImDJ9ZXw1Iac= +github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7/go.mod h1:lgAX07sFIVb9LnOJPCt9OMZRVLWqefnk+LBaSaCrWkM= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB4NuhQxXWeV0Z1qSxgIqbiMYU30dqFGDLtgNTqYbE= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= -github.com/NpoolPlatform/message v0.0.0-20230831065350-7de0d7db7a9e h1:Y6S5uevdzkQrCSprUVR9hZwIl9byJ9hvrvjwQ8JLdo4= -github.com/NpoolPlatform/message v0.0.0-20230831065350-7de0d7db7a9e/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= -github.com/NpoolPlatform/order-middleware v0.0.0-20230831084837-3416b99e025c h1:qbmhOwSVzhbmd3fHrdXjSc5FP7QrJI+bc9+1jSIEh5E= -github.com/NpoolPlatform/order-middleware v0.0.0-20230831084837-3416b99e025c/go.mod h1:k0KDLGY+8iAJtYW2Iwp3nElEfiX/biLp5tjgJxNYPrw= +github.com/NpoolPlatform/message v0.0.0-20230904073655-1d217e96c6bb h1:eoGrwFtjDwA4SrVGNcNRLL5nv+3s3j/JT0H3lrOhy1Q= +github.com/NpoolPlatform/message v0.0.0-20230904073655-1d217e96c6bb/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/order-middleware v0.0.0-20230904074503-7a4d8ebbef6b h1:/YT0PSdeeLZ0Xf/U1E2hx2ugHt970xiePLnV+3aNBlE= +github.com/NpoolPlatform/order-middleware v0.0.0-20230904074503-7a4d8ebbef6b/go.mod h1:W56fj2SCk8aRgmPMwUCa0qvz35l2pUEAX5Km5cR+Wl4= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b/go.mod h1:9C9XDi7c0szxcLdJGDDFuo3/KtC74yWiyUM2fR+i0ww= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= diff --git a/pkg/order/create.go b/pkg/order/create.go index 03b5380..fa819c4 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -63,11 +63,12 @@ type createHandler struct { goodValueCoins map[string]decimal.Decimal goodValueUSDs map[string]decimal.Decimal - paymentAmountUSD decimal.Decimal paymentAmountCoin decimal.Decimal discountAmountCoin decimal.Decimal paymentTransferAmount decimal.Decimal + mainPaymentType *ordertypes.PaymentType + paymentCoinName string paymentAddress string paymentAddressStartAmount decimal.Decimal @@ -83,25 +84,6 @@ func tomorrowStart() time.Time { return time.Date(y, m, d+1, 0, 0, 0, 0, now.Location()) } -func (h *createHandler) paymentType() (*ordertypes.PaymentType, error) { - switch *h.OrderType { - case ordertypes.OrderType_Normal: - if h.BalanceAmount != nil { - if h.paymentTransferAmount.Cmp(decimal.NewFromInt(0)) > 0 { - return ordertypes.PaymentType_PayWithTransferAndBalance.Enum(), nil - } - return ordertypes.PaymentType_PayWithBalanceOnly.Enum(), nil - } - return ordertypes.PaymentType_PayWithTransferOnly.Enum(), nil - case ordertypes.OrderType_Offline: - return ordertypes.PaymentType_PayWithOffline.Enum(), nil - case ordertypes.OrderType_Airdrop: - return ordertypes.PaymentType_PayWithNoPayment.Enum(), nil - default: - return nil, fmt.Errorf("invalid ordertype") - } -} - func (h *createHandler) validateInit(ctx context.Context) error { coin, err := coininfocli.GetCoin(ctx, *h.PaymentCoinID) if err != nil { @@ -163,6 +145,32 @@ func (h *createHandler) validateInit(ctx context.Context) error { return nil } +func (h *createHandler) checkGoodRequests() error { + goodRequiredSet := make(map[string]struct{}) + goodSet := make(map[string]struct{}) + for _, goodRequired := range h.orderGood.goodRequireds { + goodRequiredSet[goodRequired.RequiredGoodID] = struct{}{} + } + + for _, goodReq := range h.Goods { + if !goodReq.Parent { + if _, ok := goodRequiredSet[goodReq.GoodID]; !ok { + return fmt.Errorf("invalid goodrequired") + } + goodSet[goodReq.GoodID] = struct{}{} + } + } + + for _, goodRequired := range h.orderGood.goodRequireds { + if goodRequired.Must { + if _, ok := goodSet[goodRequired.RequiredGoodID]; !ok { + return fmt.Errorf("invalid goodrequired must") + } + } + } + return nil +} + // nolint func (h *createHandler) SetReduction(ctx context.Context) error { if len(h.CouponIDs) == 0 { @@ -181,16 +189,6 @@ func (h *createHandler) SetReduction(ctx context.Context) error { return fmt.Errorf("invalid coupon") } - exist, err := ordermwcli.ExistOrderConds(ctx, &ordermwpb.Conds{ - CouponIDs: &basetypes.StringSliceVal{Op: cruder.EQ, Value: h.CouponIDs}, - }) - if err != nil { - return err - } - if exist { - return fmt.Errorf("coupon already used") - } - couponTypeDiscountNum := 0 for _, coup := range coupons { if !coup.Valid || coup.Expired || coup.AppID != *h.AppID || coup.UserID != *h.UserID { @@ -317,7 +315,6 @@ func getAccuracy(coin decimal.Decimal) decimal.Decimal { } func (h *createHandler) SetPaymentAmount(ctx context.Context) error { - totalPaymentAmountCoin := decimal.NewFromInt(0) totalPaymentAmountUSD := decimal.NewFromInt(0) for _, goodReq := range h.Goods { price := h.goodPrices[*h.AppID+goodReq.GoodID] @@ -331,7 +328,7 @@ func (h *createHandler) SetPaymentAmount(ctx context.Context) error { goodValueCoin := paymentAmountUSD.Div(h.coinCurrency) goodValueCoin = getAccuracy(goodValueCoin) - totalPaymentAmountCoin = totalPaymentAmountCoin.Add(goodValueCoin) + h.paymentAmountCoin = h.paymentAmountCoin.Add(goodValueCoin) h.goodValueCoins[goodReq.GoodID] = goodValueCoin } @@ -342,15 +339,22 @@ func (h *createHandler) SetPaymentAmount(ctx context.Context) error { "ReductionPercent", h.reductionPercent, ) - discountAmountUSD := totalPaymentAmountUSD. - Mul(h.reductionPercent). - Div(decimal.NewFromInt(100)). //nolint - Add(h.reductionAmount) + discountAmountUSD := decimal.NewFromInt(0) + if h.reductionPercent != decimal.NewFromInt(0) { + discountAmountUSD = totalPaymentAmountUSD. + Mul(h.reductionPercent). + Div(decimal.NewFromInt(100)) //nolint + } + discountAmountUSD = discountAmountUSD.Add(h.reductionAmount) h.discountAmountCoin = discountAmountUSD.Div(h.coinCurrency) h.discountAmountCoin = getAccuracy(h.discountAmountCoin) - h.paymentAmountCoin = totalPaymentAmountCoin.Sub(h.discountAmountCoin) + if *h.OrderType == ordertypes.OrderType_Airdrop { + h.paymentAmountCoin = decimal.NewFromInt(0) + } + + h.paymentAmountCoin = h.paymentAmountCoin.Sub(h.discountAmountCoin) if h.paymentAmountCoin.Cmp(decimal.NewFromInt(0)) < 0 { h.paymentAmountCoin = decimal.NewFromInt(0) } @@ -372,6 +376,34 @@ func (h *createHandler) SetPaymentAmount(ctx context.Context) error { return nil } +func (h *createHandler) paymentType() (*ordertypes.PaymentType, error) { + switch *h.OrderType { + case ordertypes.OrderType_Normal: + if h.BalanceAmount != nil { + if h.paymentTransferAmount.Cmp(decimal.NewFromInt(0)) > 0 { + return ordertypes.PaymentType_PayWithTransferAndBalance.Enum(), nil + } + return ordertypes.PaymentType_PayWithBalanceOnly.Enum(), nil + } + return ordertypes.PaymentType_PayWithTransferOnly.Enum(), nil + case ordertypes.OrderType_Offline: + return ordertypes.PaymentType_PayWithOffline.Enum(), nil + case ordertypes.OrderType_Airdrop: + return ordertypes.PaymentType_PayWithNoPayment.Enum(), nil + default: + return nil, fmt.Errorf("invalid ordertype") + } +} + +func (h *createHandler) SetPaymentType(ctx context.Context) error { + paymentType, err := h.paymentType() + if err != nil { + return err + } + h.mainPaymentType = paymentType + return nil +} + func (h *createHandler) createAddresses(ctx context.Context) error { const createCount = 5 successCreated := 0 @@ -418,44 +450,25 @@ func (h *createHandler) peekAddress(ctx context.Context) (*payaccmwpb.Account, e var account *payaccmwpb.Account for _, payment := range payments { - if err := accountlock.Lock(payment.AccountID); err != nil { - logger.Sugar().Infow("peekAddress", "payment", payment.Address, "ID", payment.ID, "error", err) - continue - } - info, err := payaccmwcli.GetAccount(ctx, payment.ID) if err != nil { - accountlock.Unlock(payment.AccountID) //nolint logger.Sugar().Infow("peekAddress", "payment", payment.Address, "ID", payment.ID, "error", err) return nil, err } if info.Locked || !info.Active || info.Blocked { - accountlock.Unlock(payment.AccountID) //nolint continue } if info.AvailableAt > uint32(time.Now().Unix()) { - accountlock.Unlock(payment.AccountID) //nolint continue } - - locked := true - lockedBy := basetypes.AccountLockedBy_Payment - - info, err = payaccmwcli.UpdateAccount(ctx, &payaccmwpb.AccountReq{ - ID: &payment.ID, - Locked: &locked, - LockedBy: &lockedBy, - }) - if err != nil { - accountlock.Unlock(payment.AccountID) //nolint - logger.Sugar().Infow("peekAddress", "payment", info.Address, "error", err) - return nil, err + if err := accountlock.Lock(payment.AccountID); err != nil { + logger.Sugar().Infow("peekAddress", "payment", payment.Address, "ID", payment.ID, "error", err) + continue } account = info - accountlock.Unlock(payment.AccountID) //nolint break } @@ -468,6 +481,31 @@ func (h *createHandler) peekAddress(ctx context.Context) (*payaccmwpb.Account, e return account, nil } +func (h *createHandler) withLockPaymentAccount(dispose *dtmcli.SagaDispose) { + switch *h.mainPaymentType { + case ordertypes.PaymentType_PayWithTransferOnly: + fallthrough //nolint + case ordertypes.PaymentType_PayWithTransferAndBalance: + fallthrough //nolint + case ordertypes.PaymentType_PayWithOffline: + locked := true + lockedBy := basetypes.AccountLockedBy_Payment + req := &payaccmwpb.AccountReq{ + ID: &h.paymentID, + Locked: &locked, + LockedBy: &lockedBy, + } + dispose.Add( + ordermwsvcname.ServiceDomain, + "account.middleware.payment.v1.Middleware/UpdateAccount", + "", + &payaccmwpb.UpdateAccountRequest{ + Info: req, + }, + ) + } +} + func (h *createHandler) PeekAddress(ctx context.Context) error { account, err := h.peekAddress(ctx) if err != nil { @@ -497,23 +535,7 @@ func (h *createHandler) PeekAddress(ctx context.Context) error { return nil } -func (h *createHandler) ReleaseAddress(ctx context.Context) error { - if err := accountlock.Lock(h.paymentAccountID); err != nil { - return err - } - - locked := false - - _, err := payaccmwcli.UpdateAccount(ctx, &payaccmwpb.AccountReq{ - ID: &h.paymentID, - Locked: &locked, - }) - - accountlock.Unlock(h.paymentAccountID) //nolint - return err -} - -func (h *createHandler) SetBalance(ctx context.Context) error { +func (h *createHandler) SetAddressBalance(ctx context.Context) error { balance, err := sphinxproxycli.GetBalance(ctx, &sphinxproxypb.GetBalanceRequest{ Name: h.paymentCoinName, Address: h.paymentAddress, @@ -548,6 +570,9 @@ func (h *createHandler) withUpdateStock(dispose *dtmcli.SagaDispose) { } func (h *createHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { + if h.BalanceAmount != nil { + return + } req := &ledgermwpb.LedgerReq{ ID: &h.ledger.ID, AppID: h.AppID, @@ -566,7 +591,7 @@ func (h *createHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { ) } -func (h *createHandler) CheckBalance(ctx context.Context) error { +func (h *createHandler) CheckLedgerBalance(ctx context.Context) error { if h.BalanceAmount == nil { return nil } @@ -606,7 +631,7 @@ func (h *createHandler) CheckBalance(ctx context.Context) error { return nil } -func (h *createHandler) setCreateReqs(ctx context.Context) ([]*ordermwpb.OrderReq, error) { +func (h *createHandler) setCreateReqs() []*ordermwpb.OrderReq { paymentAmount := h.paymentAmountCoin.String() startAmount := h.paymentAddressStartAmount.String() paymentTransferAmount := h.paymentTransferAmount.String() @@ -616,11 +641,7 @@ func (h *createHandler) setCreateReqs(ctx context.Context) ([]*ordermwpb.OrderRe discountAmountCoin := h.discountAmountCoin.String() childPaymentType := ordertypes.PaymentType_PayWithParentOrder zeroAmount := "0" - orderID := uuid.NewString() - paymentType, err := h.paymentType() - if err != nil { - return nil, err - } + mainOrderID := uuid.NewString() orderReqs := []*ordermwpb.OrderReq{} for _, goodReq := range h.Goods { @@ -635,6 +656,7 @@ func (h *createHandler) setCreateReqs(ctx context.Context) ([]*ordermwpb.OrderRe logger.Sugar().Infow( "CreateOrder", "PaymentAmountCoin", h.paymentAmountCoin, + "DiscountAmountCoin", h.discountAmountCoin, "BalanceAmount", h.BalanceAmount, "ReductionAmount", h.reductionAmount, "ReductionPercent", h.reductionPercent, @@ -667,7 +689,7 @@ func (h *createHandler) setCreateReqs(ctx context.Context) ([]*ordermwpb.OrderRe id := uuid.NewString() // batch child order orderReq.ID = &id - orderReq.ParentOrderID = &orderID + orderReq.ParentOrderID = &mainOrderID orderReq.PaymentAmount = &zeroAmount orderReq.DiscountAmount = &zeroAmount orderReq.PaymentType = &childPaymentType @@ -676,17 +698,17 @@ func (h *createHandler) setCreateReqs(ctx context.Context) ([]*ordermwpb.OrderRe h.IDs = append(h.IDs, id) } else { // parent order or single order - orderReq.ID = &orderID + orderReq.ID = &mainOrderID orderReq.ParentOrderID = h.ParentOrderID orderReq.PaymentAmount = &paymentAmount orderReq.DiscountAmount = &discountAmountCoin orderReq.CouponIDs = h.CouponIDs - orderReq.PaymentType = paymentType + orderReq.PaymentType = h.mainPaymentType orderReq.TransferAmount = &paymentTransferAmount orderReq.BalanceAmount = h.BalanceAmount orderReq.PaymentAccountID = &h.paymentAccountID orderReq.PaymentStartAmount = &startAmount - h.IDs = append(h.IDs, orderID) + h.IDs = append(h.IDs, mainOrderID) } topmostGood := h.orderGood.topMostGoods[*h.AppID+goodReq.GoodID] @@ -695,14 +717,14 @@ func (h *createHandler) setCreateReqs(ctx context.Context) ([]*ordermwpb.OrderRe } orderReqs = append(orderReqs, orderReq) } - return orderReqs, nil + return orderReqs } func (h *createHandler) withCreateOrder(dispose *dtmcli.SagaDispose, req *ordermwpb.OrderReq) { dispose.Add( ordermwsvcname.ServiceDomain, "order.middleware.order1.v1.Middleware/CreateOrder", - "", + "order.middleware.order1.v1.Middleware/DeleteOrder", &ordermwpb.CreateOrderRequest{ Info: req, }, @@ -713,13 +735,14 @@ func (h *createHandler) withCreateOrders(dispose *dtmcli.SagaDispose, reqs []*or dispose.Add( ordermwsvcname.ServiceDomain, "order.middleware.order1.v1.Middleware/CreateOrders", - "", + "order.middleware.order1.v1.Middleware/DeleteOrders", &ordermwpb.CreateOrdersRequest{ Infos: reqs, }, ) } +//nolint:gocyclo func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error) { orderGood, err := h.ToOrderGood(ctx) if err != nil { @@ -749,25 +772,32 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error return nil, err } - if err := handler.PeekAddress(ctx); err != nil { + if err := handler.SetPaymentType(ctx); err != nil { return nil, err } - if err := handler.SetBalance(ctx); err != nil { - _ = handler.ReleaseAddress(ctx) - return nil, err + switch *handler.mainPaymentType { + case ordertypes.PaymentType_PayWithTransferOnly: + fallthrough //nolint + case ordertypes.PaymentType_PayWithTransferAndBalance: + fallthrough //nolint + case ordertypes.PaymentType_PayWithOffline: + if err := handler.PeekAddress(ctx); err != nil { + return nil, err + } + defer func() { + accountlock.Unlock(handler.paymentAccountID) //nolint + }() + if err := handler.SetAddressBalance(ctx); err != nil { + return nil, err + } } - if err := handler.CheckBalance(ctx); err != nil { - _ = handler.ReleaseAddress(ctx) + if err := handler.CheckLedgerBalance(ctx); err != nil { return nil, err } - createReqs, err := handler.setCreateReqs(ctx) - if err != nil { - _ = handler.ReleaseAddress(ctx) - return nil, err - } + createReqs := handler.setCreateReqs() sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ WaitResult: true, @@ -775,13 +805,11 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error }) handler.withUpdateStock(sagaDispose) - if h.BalanceAmount != nil { - handler.withUpdateBalance(sagaDispose) - } - handler.withCreateOrders(sagaDispose, createReqs) + handler.withUpdateBalance(sagaDispose) + handler.withCreateOrder(sagaDispose, createReqs[0]) + handler.withLockPaymentAccount(sagaDispose) if err := dtmcli.WithSaga(ctx, sagaDispose); err != nil { - _ = handler.ReleaseAddress(ctx) return nil, err } @@ -796,6 +824,7 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error return orders[0], nil } +//nolint:gocyclo func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err error) { orderGood, err := h.ToOrderGoods(ctx) if err != nil { @@ -809,6 +838,10 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e return nil, err } + if err := handler.checkGoodRequests(); err != nil { + return nil, err + } + if err := handler.SetReduction(ctx); err != nil { return nil, err } @@ -825,25 +858,32 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e return nil, err } - if err := handler.PeekAddress(ctx); err != nil { + if err := handler.SetPaymentType(ctx); err != nil { return nil, err } - if err := handler.SetBalance(ctx); err != nil { - _ = handler.ReleaseAddress(ctx) - return nil, err + switch *handler.mainPaymentType { + case ordertypes.PaymentType_PayWithTransferOnly: + fallthrough //nolint + case ordertypes.PaymentType_PayWithTransferAndBalance: + fallthrough //nolint + case ordertypes.PaymentType_PayWithOffline: + if err := handler.PeekAddress(ctx); err != nil { + return nil, err + } + defer func() { + accountlock.Unlock(handler.paymentAccountID) //nolint + }() + if err := handler.SetAddressBalance(ctx); err != nil { + return nil, err + } } - if err := handler.CheckBalance(ctx); err != nil { - _ = handler.ReleaseAddress(ctx) + if err := handler.CheckLedgerBalance(ctx); err != nil { return nil, err } - createReqs, err := handler.setCreateReqs(ctx) - if err != nil { - _ = handler.ReleaseAddress(ctx) - return nil, err - } + createReqs := handler.setCreateReqs() sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ WaitResult: true, @@ -851,13 +891,11 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e }) handler.withUpdateStock(sagaDispose) - if h.BalanceAmount != nil { - handler.withUpdateBalance(sagaDispose) - } + handler.withUpdateBalance(sagaDispose) handler.withCreateOrders(sagaDispose, createReqs) + handler.withLockPaymentAccount(sagaDispose) if err := dtmcli.WithSaga(ctx, sagaDispose); err != nil { - _ = handler.ReleaseAddress(ctx) return nil, err } diff --git a/pkg/order/ordergood.go b/pkg/order/ordergood.go index f1c6e73..1046671 100644 --- a/pkg/order/ordergood.go +++ b/pkg/order/ordergood.go @@ -11,10 +11,12 @@ import ( appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" topmostgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/topmost/good" goodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good" + goodrequiredmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good/required" coinpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin" appgoodpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good" topmostgoodpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/topmost/good" goodpb "github.com/NpoolPlatform/message/npool/good/mw/v1/good" + goodrequiredpb "github.com/NpoolPlatform/message/npool/good/mw/v1/good/required" npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" @@ -25,10 +27,11 @@ import ( ) type OrderGood struct { - goods map[string]*goodpb.Good - appgoods map[string]*appgoodpb.Good - goodCoins map[string]*coinpb.Coin - topMostGoods map[string]*topmostgoodpb.TopMostGood + goods map[string]*goodpb.Good + appgoods map[string]*appgoodpb.Good + goodCoins map[string]*coinpb.Coin + topMostGoods map[string]*topmostgoodpb.TopMostGood + goodRequireds []*goodrequiredpb.Required } func (h *Handler) ToOrderGood(ctx context.Context) (*OrderGood, error) { @@ -53,7 +56,21 @@ func (h *Handler) ToOrderGoods(ctx context.Context) (*OrderGood, error) { goodCoins: map[string]*coinpb.Coin{}, topMostGoods: map[string]*topmostgoodpb.TopMostGood{}, } + parentGoodNum := 0 for _, goodReq := range h.Goods { + if goodReq.Parent { + parentGoodNum++ + if parentGoodNum != 1 { + return nil, fmt.Errorf("invalid parent") + } + goodRequireds, _, err := goodrequiredmwcli.GetRequireds(ctx, &goodrequiredpb.Conds{ + MainGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: goodReq.GoodID}, + }, 0, 0) + if err != nil { + return nil, err + } + ordergood.goodRequireds = goodRequireds + } good, err := goodmwcli.GetGood(ctx, goodReq.GoodID) if err != nil { return nil, err From b6250507e11e79c48d810c5d99f305f17716d570 Mon Sep 17 00:00:00 2001 From: jakys Date: Mon, 4 Sep 2023 08:55:50 +0000 Subject: [PATCH 08/67] Fix update --- pkg/order/update.go | 227 +++++++++++--------------------------------- 1 file changed, 53 insertions(+), 174 deletions(-) diff --git a/pkg/order/update.go b/pkg/order/update.go index fdf463b..8eeb07d 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -13,21 +13,19 @@ import ( basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" - appgoodstockmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/stock" goodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good" appgoodmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good" - appgoodstockmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/stock" npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" miningdetailcli "github.com/NpoolPlatform/ledger-middleware/pkg/client/good/ledger/statement" + ledgerstatementcli "github.com/NpoolPlatform/ledger-middleware/pkg/client/ledger/statement" miningdetailpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/good/ledger/statement" ledgerstatementpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger/statement" - achievementmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/achievement" statementmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/achievement/statement" statementmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/achievement/statement" @@ -66,7 +64,7 @@ func (h *updateHandler) validate(ctx context.Context) error { return fmt.Errorf("invalid good") } - _, total, err := miningdetailcli.GetGoodStatements(ctx, &miningdetailpb.Conds{ + statements, _, err := miningdetailcli.GetGoodStatements(ctx, &miningdetailpb.Conds{ GoodID: &basetypes.StringVal{ Op: cruder.EQ, Value: h.ord.GoodID, @@ -75,9 +73,6 @@ func (h *updateHandler) validate(ctx context.Context) error { if err != nil { return err } - if total > 0 { - return fmt.Errorf("app good have mining detail data uncancellable") - } if good.RewardState != goodtypes.BenefitState_BenefitWait { return fmt.Errorf("app good uncancellable benefit state not wait") @@ -88,60 +83,41 @@ func (h *updateHandler) validate(ctx context.Context) error { return fmt.Errorf("app good uncancellable") case goodtypes.CancelMode_CancellableBeforeStart: switch h.ord.OrderState { - case ordertypes.OrderState_OrderStateWaitPayment: case ordertypes.OrderState_OrderStatePaid: + case ordertypes.OrderState_OrderStateInService: + return fmt.Errorf("order state is uncancellable") default: return fmt.Errorf("order state is uncancellable") } - - if uint32(time.Now().Unix()) >= h.ord.StartAt-appgood.CancellableBeforeStart { - return fmt.Errorf("cancellable time exceeded") - } case goodtypes.CancelMode_CancellableBeforeBenefit: switch h.ord.OrderState { - case ordertypes.OrderState_OrderStateWaitPayment: case ordertypes.OrderState_OrderStatePaid: case ordertypes.OrderState_OrderStateInService: + if len(statements) > 0 { + lastBenefitDate := statements[0].BenefitDate + const secondsPerDay = 24 * 60 * 60 + checkBenefitStartAt := lastBenefitDate + secondsPerDay - appgood.CancellableBeforeStart + checkBenefitEndAt := lastBenefitDate + secondsPerDay + appgood.CancellableBeforeStart + now := uint32(time.Now().Unix()) + if checkBenefitStartAt <= now && now <= checkBenefitEndAt { + return fmt.Errorf("invalid cancel in during time") + } + } default: return fmt.Errorf("order state is uncancellable") } - - if uint32(time.Now().Unix()) >= h.ord.StartAt-appgood.CancellableBeforeStart && - uint32(time.Now().Unix()) <= h.ord.StartAt+appgood.CancellableBeforeStart { - return fmt.Errorf("app good uncancellable order start at > cancellable before start") - } default: return fmt.Errorf("unknown CancelMode type %v", appgood.CancelMode) } - return nil -} - -func (h *updateHandler) processStock(ctx context.Context) error { - stockReq := &appgoodstockmwpb.StockReq{ - ID: &h.ord.GoodID, - } - - switch h.ord.OrderState { - case ordertypes.OrderState_OrderStatePaid: - stockReq.WaitStart = &h.Units - case ordertypes.OrderState_OrderStateInService: - stockReq.InService = &h.Units - } - _, err := appgoodstockmwcli.SubStock(ctx, stockReq) - if err != nil { - return err - } return nil } -func (h *updateHandler) processOrderState(ctx context.Context) error { - state := ordertypes.OrderState_OrderStateCanceled - paymentState := ordertypes.PaymentState_PaymentStateCanceled +func (h *updateHandler) processCancel(ctx context.Context) error { _, err := ordermwcli.UpdateOrder(ctx, &ordermwpb.OrderReq{ ID: &h.ord.ID, - OrderState: &state, - PaymentState: &paymentState, + AppID: h.AppID, + UserID: h.UserID, UserSetCanceled: h.UserSetCanceled, AdminSetCanceled: h.AdminSetCanceled, }) @@ -152,7 +128,6 @@ func (h *updateHandler) processOrderState(ctx context.Context) error { return nil } -//nolint:funlen func (h *updateHandler) processLedger(ctx context.Context) error { offset := int32(0) limit := int32(1000) //nolint @@ -160,7 +135,6 @@ func (h *updateHandler) processLedger(ctx context.Context) error { in := ledgertypes.IOType_Incoming out := ledgertypes.IOType_Outcoming ioTypeCR := ledgertypes.IOSubType_CommissionRevoke - ioTypeOrder := ledgertypes.IOSubType_OrderRevoke for { infos, _, err := statementmwcli.GetStatements(ctx, &statementmwpb.Conds{ @@ -234,40 +208,8 @@ func (h *updateHandler) processLedger(ctx context.Context) error { } } - paymentAmount, err := decimal.NewFromString(h.ord.PaymentAmount) - if err != nil { - return err - } - - payWithBalanceAmount, err := decimal.NewFromString(h.ord.BalanceAmount) - if err != nil { - return err - } - - if paymentAmount.Add(payWithBalanceAmount).Cmp(decimal.NewFromInt(0)) != 0 { - amount := paymentAmount.Add(payWithBalanceAmount).String() - inIoExtra := fmt.Sprintf( - `{"AppID":"%v","UserID":"%v","OrderID":"%v","Amount":"%v","Date":"%v"}`, - h.ord.AppID, - h.ord.UserID, - h.ord.ID, - amount, - time.Now(), - ) - - detailInfos = append(detailInfos, &ledgerstatementpb.StatementReq{ - AppID: &h.ord.AppID, - UserID: &h.ord.UserID, - CoinTypeID: &h.ord.PaymentCoinTypeID, - IOType: &in, - IOSubType: &ioTypeOrder, - Amount: &amount, - IOExtra: &inIoExtra, - }) - } - if len(detailInfos) > 0 { - _, err = ledgerstatementcli.CreateStatements(ctx, detailInfos) + _, err := ledgerstatementcli.CreateStatements(ctx, detailInfos) if err != nil { return err } @@ -276,78 +218,11 @@ func (h *updateHandler) processLedger(ctx context.Context) error { return nil } -func (h *updateHandler) processArchivement(ctx context.Context) error { - err := achievementmwcli.ExpropriateAchievement(ctx, h.ord.ID) - if err != nil { - return err - } - return nil -} - -func (h *updateHandler) cancelAirdropOrder(ctx context.Context) error { - err := h.validate(ctx) - if err != nil { - return err - } - err = h.processStock(ctx) - if err != nil { - return err - } - // TODO Distributed transactions should be used - return h.processOrderState(ctx) -} - -func (h *updateHandler) cancelOfflineOrder(ctx context.Context) error { - err := h.validate(ctx) - if err != nil { - return err - } - // TODO Distributed transactions should be used - - err = h.processStock(ctx) - if err != nil { - return err - } - err = h.processOrderState(ctx) - if err != nil { - return err - } - - return h.processArchivement(ctx) -} - -func (h *updateHandler) cancelNormalOrder(ctx context.Context) error { - err := h.validate(ctx) - if err != nil { - return err - } - - err = h.processStock(ctx) - if err != nil { - return err - } - - err = h.processOrderState(ctx) - if err != nil { - return err - } - - err = h.processLedger(ctx) - if err != nil { - return err - } - - return h.processArchivement(ctx) -} - -//nolint:gocyclo +//nolint:funlen,gocyclo func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { if h.UserSetCanceled == nil && h.AdminSetCanceled == nil { return nil, fmt.Errorf("nothing todo") } - if h.ID == nil || *h.ID == "" { - return nil, fmt.Errorf("id invalid") - } ord, err := ordermwcli.GetOrder(ctx, *h.ID) if err != nil { @@ -360,6 +235,12 @@ func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { if *h.AppID != ord.AppID || *h.UserID != ord.UserID { return nil, fmt.Errorf("permission denied") } + if h.FromAdmin && h.UserSetCanceled != nil { + return nil, fmt.Errorf("permission denied") + } + if !h.FromAdmin && h.AdminSetCanceled != nil { + return nil, fmt.Errorf("permission denied") + } if h.UserSetCanceled != nil && !*h.UserSetCanceled { return h.GetOrder(ctx) } @@ -372,45 +253,43 @@ func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { ord: ord, } - switch ord.OrderState { - case ordertypes.OrderState_OrderStateWaitPayment: - if h.FromAdmin && ord.OrderType == ordertypes.OrderType_Normal { - return nil, fmt.Errorf("permission denied") - } - _, err = ordermwcli.UpdateOrder(ctx, &ordermwpb.OrderReq{ - ID: h.ID, - AppID: h.AppID, - UserID: h.UserID, - UserSetCanceled: h.UserSetCanceled, - AdminSetCanceled: h.AdminSetCanceled, - }) - if err != nil { - return nil, err - } - return handler.GetOrder(ctx) - case ordertypes.OrderState_OrderStatePaid: - case ordertypes.OrderState_OrderStateInService: - default: - return nil, fmt.Errorf("order state uncancellable") - } - switch ord.OrderType { case ordertypes.OrderType_Normal: - if err := handler.cancelNormalOrder(ctx); err != nil { - return nil, err + switch ord.OrderState { + case ordertypes.OrderState_OrderStateWaitPayment: + fallthrough //nolint + case ordertypes.OrderState_OrderStateCheckPayment: + fallthrough //nolint + case ordertypes.OrderState_OrderStatePaymentTimeout: + if h.FromAdmin { + return nil, fmt.Errorf("permission denied") + } + if err := handler.processCancel(ctx); err != nil { + return nil, err + } + case ordertypes.OrderState_OrderStatePaid: + fallthrough //nolint + case ordertypes.OrderState_OrderStateInService: + if err := handler.validate(ctx); err != nil { + return nil, err + } + if err := handler.processLedger(ctx); err != nil { + return nil, err + } + if err := handler.processCancel(ctx); err != nil { + return nil, err + } } case ordertypes.OrderType_Offline: + fallthrough //nolint + case ordertypes.OrderType_Airdrop: if !h.FromAdmin { return nil, fmt.Errorf("permission denied") } - if err := handler.cancelOfflineOrder(ctx); err != nil { + if err := handler.validate(ctx); err != nil { return nil, err } - case ordertypes.OrderType_Airdrop: - if !h.FromAdmin { - return nil, fmt.Errorf("permission denied") - } - if err := handler.cancelAirdropOrder(ctx); err != nil { + if err := handler.processCancel(ctx); err != nil { return nil, err } default: From af0e6983df2dda34fa27c1dd35fa637ab83a954d Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Mon, 4 Sep 2023 09:16:05 +0000 Subject: [PATCH 09/67] Create order --- pkg/order/create.go | 77 +++++++-------------------------------------- 1 file changed, 12 insertions(+), 65 deletions(-) diff --git a/pkg/order/create.go b/pkg/order/create.go index fa819c4..7cadc71 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -70,12 +70,9 @@ type createHandler struct { mainPaymentType *ordertypes.PaymentType paymentCoinName string - paymentAddress string paymentAddressStartAmount decimal.Decimal - paymentID string - paymentAccountID string - - ledger *ledgermwpb.Ledger + paymentAccount *payaccmwpb.Account + ledger *ledgermwpb.Ledger } func tomorrowStart() time.Time { @@ -452,7 +449,6 @@ func (h *createHandler) peekAddress(ctx context.Context) (*payaccmwpb.Account, e for _, payment := range payments { info, err := payaccmwcli.GetAccount(ctx, payment.ID) if err != nil { - logger.Sugar().Infow("peekAddress", "payment", payment.Address, "ID", payment.ID, "error", err) return nil, err } @@ -463,11 +459,6 @@ func (h *createHandler) peekAddress(ctx context.Context) (*payaccmwpb.Account, e if info.AvailableAt > uint32(time.Now().Unix()) { continue } - if err := accountlock.Lock(payment.AccountID); err != nil { - logger.Sugar().Infow("peekAddress", "payment", payment.Address, "ID", payment.ID, "error", err) - continue - } - account = info break } @@ -560,8 +551,8 @@ func (h *createHandler) withUpdateStock(dispose *dtmcli.SagaDispose) { } dispose.Add( ordermwsvcname.ServiceDomain, - "good.middleware.app.good1.stock.v1.Middleware/SubStock", "good.middleware.app.good1.stock.v1.Middleware/AddStock", + "good.middleware.app.good1.stock.v1.Middleware/SubStock", &appgoodstockmwpb.AddStockRequest{ Info: req, }, @@ -574,11 +565,9 @@ func (h *createHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { return } req := &ledgermwpb.LedgerReq{ - ID: &h.ledger.ID, AppID: h.AppID, UserID: h.UserID, CoinTypeID: &h.ledger.CoinTypeID, - Locked: h.BalanceAmount, Spendable: h.BalanceAmount, } dispose.Add( @@ -591,47 +580,7 @@ func (h *createHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { ) } -func (h *createHandler) CheckLedgerBalance(ctx context.Context) error { - if h.BalanceAmount == nil { - return nil - } - - ba, err := decimal.NewFromString(*h.BalanceAmount) - if err != nil { - return err - } - - if ba.Cmp(decimal.NewFromInt(0)) <= 0 { - return nil - } - - general, err := ledgermwcli.GetLedgerOnly(ctx, &ledgermwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, - CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, - }) - if err != nil { - return err - } - if general == nil { - return fmt.Errorf("insufficient balance") - } - - spendable, err := decimal.NewFromString(general.Spendable) - if err != nil { - return err - } - - if spendable.Cmp(ba) < 0 { - return fmt.Errorf("insufficient balance") - } - - h.ledger = general - - return nil -} - -func (h *createHandler) setCreateReqs() []*ordermwpb.OrderReq { +func (h *createHandler) orderReqs() []*ordermwpb.OrderReq { paymentAmount := h.paymentAmountCoin.String() startAmount := h.paymentAddressStartAmount.String() paymentTransferAmount := h.paymentTransferAmount.String() @@ -782,8 +731,14 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error case ordertypes.PaymentType_PayWithTransferAndBalance: fallthrough //nolint case ordertypes.PaymentType_PayWithOffline: - if err := handler.PeekAddress(ctx); err != nil { - return nil, err + for i := 0; i < 5; i++ { + if err := handler.PeekAddress(ctx); err != nil { + return nil, err + } + if err := accountlock.Lock(payment.AccountID); err != nil { + continue + } + break } defer func() { accountlock.Unlock(handler.paymentAccountID) //nolint @@ -793,10 +748,6 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error } } - if err := handler.CheckLedgerBalance(ctx); err != nil { - return nil, err - } - createReqs := handler.setCreateReqs() sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ @@ -879,10 +830,6 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e } } - if err := handler.CheckLedgerBalance(ctx); err != nil { - return nil, err - } - createReqs := handler.setCreateReqs() sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ From cf66566cdd38b0a5be90fc0e51ce67527a6bfb63 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Mon, 4 Sep 2023 09:27:24 +0000 Subject: [PATCH 10/67] Update order --- pkg/order/update.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pkg/order/update.go b/pkg/order/update.go index 8eeb07d..1c83f62 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -38,7 +38,7 @@ type updateHandler struct { } //nolint:gocyclo -func (h *updateHandler) validate(ctx context.Context) error { +func (h *updateHandler) cancelable(ctx context.Context) error { appgood, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodmwpb.Conds{ AppID: &basetypes.StringVal{ Op: cruder.EQ, @@ -259,14 +259,10 @@ func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { case ordertypes.OrderState_OrderStateWaitPayment: fallthrough //nolint case ordertypes.OrderState_OrderStateCheckPayment: - fallthrough //nolint - case ordertypes.OrderState_OrderStatePaymentTimeout: if h.FromAdmin { return nil, fmt.Errorf("permission denied") } - if err := handler.processCancel(ctx); err != nil { - return nil, err - } + fallthrough //nolint case ordertypes.OrderState_OrderStatePaid: fallthrough //nolint case ordertypes.OrderState_OrderStateInService: From 56a45dff6e058d0bec83b57ead04f7b0c3750b63 Mon Sep 17 00:00:00 2001 From: jakys Date: Mon, 4 Sep 2023 11:44:42 +0000 Subject: [PATCH 11/67] Fix create and update --- pkg/order/create.go | 68 ++++++++++++-------- pkg/order/update.go | 151 ++++++++++++++++++++++---------------------- 2 files changed, 119 insertions(+), 100 deletions(-) diff --git a/pkg/order/create.go b/pkg/order/create.go index 7cadc71..5999c81 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -28,7 +28,6 @@ import ( accountlock "github.com/NpoolPlatform/account-middleware/pkg/lock" payaccmwpb "github.com/NpoolPlatform/message/npool/account/mw/v1/payment" - ledgermwcli "github.com/NpoolPlatform/ledger-middleware/pkg/client/ledger" ledgermwpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger" ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" @@ -42,6 +41,8 @@ import ( basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" + redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" + "github.com/shopspring/decimal" ) @@ -68,11 +69,11 @@ type createHandler struct { paymentTransferAmount decimal.Decimal mainPaymentType *ordertypes.PaymentType + mainOrderID string paymentCoinName string paymentAddressStartAmount decimal.Decimal paymentAccount *payaccmwpb.Account - ledger *ledgermwpb.Ledger } func tomorrowStart() time.Time { @@ -467,7 +468,7 @@ func (h *createHandler) peekAddress(ctx context.Context) (*payaccmwpb.Account, e return nil, nil } - h.paymentID = account.ID + h.paymentAccount = account return account, nil } @@ -482,7 +483,7 @@ func (h *createHandler) withLockPaymentAccount(dispose *dtmcli.SagaDispose) { locked := true lockedBy := basetypes.AccountLockedBy_Payment req := &payaccmwpb.AccountReq{ - ID: &h.paymentID, + ID: &h.paymentAccount.ID, Locked: &locked, LockedBy: &lockedBy, } @@ -503,8 +504,7 @@ func (h *createHandler) PeekAddress(ctx context.Context) error { return err } if account != nil { - h.paymentAddress = account.Address - h.paymentAccountID = account.AccountID + h.paymentAccount = account return nil } @@ -520,16 +520,14 @@ func (h *createHandler) PeekAddress(ctx context.Context) error { return fmt.Errorf("fail peek address") } - h.paymentAddress = account.Address - h.paymentAccountID = account.AccountID - + h.paymentAccount = account return nil } func (h *createHandler) SetAddressBalance(ctx context.Context) error { balance, err := sphinxproxycli.GetBalance(ctx, &sphinxproxypb.GetBalanceRequest{ Name: h.paymentCoinName, - Address: h.paymentAddress, + Address: h.paymentAccount.Address, }) if err != nil { return err @@ -567,7 +565,7 @@ func (h *createHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { req := &ledgermwpb.LedgerReq{ AppID: h.AppID, UserID: h.UserID, - CoinTypeID: &h.ledger.CoinTypeID, + CoinTypeID: &h.paymentAccount.CoinTypeID, Spendable: h.BalanceAmount, } dispose.Add( @@ -590,7 +588,7 @@ func (h *createHandler) orderReqs() []*ordermwpb.OrderReq { discountAmountCoin := h.discountAmountCoin.String() childPaymentType := ordertypes.PaymentType_PayWithParentOrder zeroAmount := "0" - mainOrderID := uuid.NewString() + h.mainOrderID = uuid.NewString() orderReqs := []*ordermwpb.OrderReq{} for _, goodReq := range h.Goods { @@ -638,7 +636,7 @@ func (h *createHandler) orderReqs() []*ordermwpb.OrderReq { id := uuid.NewString() // batch child order orderReq.ID = &id - orderReq.ParentOrderID = &mainOrderID + orderReq.ParentOrderID = &h.mainOrderID orderReq.PaymentAmount = &zeroAmount orderReq.DiscountAmount = &zeroAmount orderReq.PaymentType = &childPaymentType @@ -647,7 +645,7 @@ func (h *createHandler) orderReqs() []*ordermwpb.OrderReq { h.IDs = append(h.IDs, id) } else { // parent order or single order - orderReq.ID = &mainOrderID + orderReq.ID = &h.mainOrderID orderReq.ParentOrderID = h.ParentOrderID orderReq.PaymentAmount = &paymentAmount orderReq.DiscountAmount = &discountAmountCoin @@ -655,9 +653,9 @@ func (h *createHandler) orderReqs() []*ordermwpb.OrderReq { orderReq.PaymentType = h.mainPaymentType orderReq.TransferAmount = &paymentTransferAmount orderReq.BalanceAmount = h.BalanceAmount - orderReq.PaymentAccountID = &h.paymentAccountID + orderReq.PaymentAccountID = &h.paymentAccount.AccountID orderReq.PaymentStartAmount = &startAmount - h.IDs = append(h.IDs, mainOrderID) + h.IDs = append(h.IDs, h.mainOrderID) } topmostGood := h.orderGood.topMostGoods[*h.AppID+goodReq.GoodID] @@ -691,7 +689,7 @@ func (h *createHandler) withCreateOrders(dispose *dtmcli.SagaDispose, reqs []*or ) } -//nolint:gocyclo +//nolint:funlen,gocyclo func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error) { orderGood, err := h.ToOrderGood(ctx) if err != nil { @@ -735,20 +733,27 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error if err := handler.PeekAddress(ctx); err != nil { return nil, err } - if err := accountlock.Lock(payment.AccountID); err != nil { + if err := accountlock.Lock(handler.paymentAccount.AccountID); err != nil { continue } break } defer func() { - accountlock.Unlock(handler.paymentAccountID) //nolint + accountlock.Unlock(handler.paymentAccount.AccountID) //nolint }() if err := handler.SetAddressBalance(ctx); err != nil { return nil, err } } - createReqs := handler.setCreateReqs() + createReqs := handler.orderReqs() + lockKey := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, handler.mainOrderID) + if err := redis2.TryLock(lockKey, 0); err != nil { + return nil, err + } + defer func() { + _ = redis2.Unlock(lockKey) + }() sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ WaitResult: true, @@ -775,7 +780,7 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error return orders[0], nil } -//nolint:gocyclo +//nolint:funlen,gocyclo func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err error) { orderGood, err := h.ToOrderGoods(ctx) if err != nil { @@ -819,18 +824,31 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e case ordertypes.PaymentType_PayWithTransferAndBalance: fallthrough //nolint case ordertypes.PaymentType_PayWithOffline: - if err := handler.PeekAddress(ctx); err != nil { - return nil, err + for i := 0; i < 5; i++ { + if err := handler.PeekAddress(ctx); err != nil { + return nil, err + } + if err := accountlock.Lock(handler.paymentAccount.AccountID); err != nil { + continue + } + break } defer func() { - accountlock.Unlock(handler.paymentAccountID) //nolint + accountlock.Unlock(handler.paymentAccount.AccountID) //nolint }() if err := handler.SetAddressBalance(ctx); err != nil { return nil, err } } - createReqs := handler.setCreateReqs() + createReqs := handler.orderReqs() + lockKey := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, handler.mainOrderID) + if err := redis2.TryLock(lockKey, 0); err != nil { + return nil, err + } + defer func() { + _ = redis2.Unlock(lockKey) + }() sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ WaitResult: true, diff --git a/pkg/order/update.go b/pkg/order/update.go index 1c83f62..152046e 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -5,7 +5,10 @@ import ( "fmt" "time" + dtmcli "github.com/NpoolPlatform/dtm-cluster/pkg/dtm" "github.com/NpoolPlatform/libent-cruder/pkg/cruder" + ordermwsvcname "github.com/NpoolPlatform/order-middleware/pkg/servicename" + "github.com/dtm-labs/dtm/client/dtmcli/dtmimp" goodtypes "github.com/NpoolPlatform/message/npool/basetypes/good/v1" ledgertypes "github.com/NpoolPlatform/message/npool/basetypes/ledger/v1" @@ -20,10 +23,11 @@ import ( ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" - miningdetailcli "github.com/NpoolPlatform/ledger-middleware/pkg/client/good/ledger/statement" + goodledgerstatementcli "github.com/NpoolPlatform/ledger-middleware/pkg/client/good/ledger/statement" ledgerstatementcli "github.com/NpoolPlatform/ledger-middleware/pkg/client/ledger/statement" - miningdetailpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/good/ledger/statement" + goodledgerstatementpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/good/ledger/statement" + ledgermwpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger" ledgerstatementpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger/statement" statementmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/achievement/statement" @@ -34,7 +38,8 @@ import ( type updateHandler struct { *Handler - ord *ordermwpb.Order + ord *ordermwpb.Order + achievementStatements []*statementmwpb.Statement } //nolint:gocyclo @@ -64,7 +69,7 @@ func (h *updateHandler) cancelable(ctx context.Context) error { return fmt.Errorf("invalid good") } - statements, _, err := miningdetailcli.GetGoodStatements(ctx, &miningdetailpb.Conds{ + statements, _, err := goodledgerstatementcli.GetGoodStatements(ctx, &goodledgerstatementpb.Conds{ GoodID: &basetypes.StringVal{ Op: cruder.EQ, Value: h.ord.GoodID, @@ -74,6 +79,15 @@ func (h *updateHandler) cancelable(ctx context.Context) error { return err } + switch h.ord.OrderState { + case ordertypes.OrderState_OrderStateWaitPayment: + case ordertypes.OrderState_OrderStateCheckPayment: + if len(statements) > 0 { + return fmt.Errorf("had statements can not cancel") + } + return nil + } + if good.RewardState != goodtypes.BenefitState_BenefitWait { return fmt.Errorf("app good uncancellable benefit state not wait") } @@ -113,29 +127,10 @@ func (h *updateHandler) cancelable(ctx context.Context) error { return nil } -func (h *updateHandler) processCancel(ctx context.Context) error { - _, err := ordermwcli.UpdateOrder(ctx, &ordermwpb.OrderReq{ - ID: &h.ord.ID, - AppID: h.AppID, - UserID: h.UserID, - UserSetCanceled: h.UserSetCanceled, - AdminSetCanceled: h.AdminSetCanceled, - }) - if err != nil { - return err - } - - return nil -} - -func (h *updateHandler) processLedger(ctx context.Context) error { +func (h *updateHandler) processStatements(ctx context.Context) error { offset := int32(0) limit := int32(1000) //nolint - detailInfos := []*ledgerstatementpb.StatementReq{} in := ledgertypes.IOType_Incoming - out := ledgertypes.IOType_Outcoming - ioTypeCR := ledgertypes.IOSubType_CommissionRevoke - for { infos, _, err := statementmwcli.GetStatements(ctx, &statementmwpb.Conds{ OrderID: &basetypes.StringVal{Op: cruder.EQ, Value: h.ord.ID}, @@ -157,7 +152,6 @@ func (h *updateHandler) processLedger(ctx context.Context) error { if commission.Cmp(decimal.NewFromInt(0)) == 0 { continue } - _, total, err := ledgerstatementcli.GetStatements(ctx, &ledgerstatementpb.Conds{ AppID: &basetypes.StringVal{ Op: cruder.EQ, @@ -186,39 +180,49 @@ func (h *updateHandler) processLedger(ctx context.Context) error { if total == 0 { return fmt.Errorf("commission ledger detail is not exist") } - - inIoExtra := fmt.Sprintf( - `{"AppID":"%v","UserID":"%v","ArchivementDetailID":"%v","Amount":"%v","Date":"%v"}`, - val.AppID, - val.UserID, - val.ID, - val.Commission, - time.Now(), - ) - - detailInfos = append(detailInfos, &ledgerstatementpb.StatementReq{ - AppID: &val.AppID, - UserID: &val.UserID, - CoinTypeID: &val.PaymentCoinTypeID, - IOType: &out, - IOSubType: &ioTypeCR, - Amount: &val.Commission, - IOExtra: &inIoExtra, - }) + h.achievementStatements = append(h.achievementStatements, val) } } - if len(detailInfos) > 0 { - _, err := ledgerstatementcli.CreateStatements(ctx, detailInfos) - if err != nil { - return err + return nil +} + +func (h *updateHandler) withLockCommission(dispose *dtmcli.SagaDispose) { + for _, statement := range h.achievementStatements { + req := &ledgermwpb.LedgerReq{ + AppID: &statement.AppID, + UserID: &statement.UserID, + CoinTypeID: &statement.CoinTypeID, + Spendable: &statement.Commission, } + dispose.Add( + ordermwsvcname.ServiceDomain, + "ledger.middleware.ledger.v2.Middleware/SubBalance", + "ledger.middleware.ledger.v2.Middleware/AddBalance", + &ledgermwpb.AddBalanceRequest{ + Info: req, + }, + ) } +} - return nil +func (h *updateHandler) withProcessCancel(dispose *dtmcli.SagaDispose) { + req := &ordermwpb.OrderReq{ + ID: &h.ord.ID, + UserSetCanceled: h.UserSetCanceled, + AdminSetCanceled: h.AdminSetCanceled, + } + dispose.Add( + ordermwsvcname.ServiceDomain, + "order.middleware.order1.v1.Middleware/SubBalance", + "order.middleware.order1.v1.Middleware/AddBalance", + &ordermwpb.UpdateOrderRequest{ + Info: req, + }, + ) } -//nolint:funlen,gocyclo +//nolint:gocyclo func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { if h.UserSetCanceled == nil && h.AdminSetCanceled == nil { return nil, fmt.Errorf("nothing todo") @@ -235,12 +239,6 @@ func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { if *h.AppID != ord.AppID || *h.UserID != ord.UserID { return nil, fmt.Errorf("permission denied") } - if h.FromAdmin && h.UserSetCanceled != nil { - return nil, fmt.Errorf("permission denied") - } - if !h.FromAdmin && h.AdminSetCanceled != nil { - return nil, fmt.Errorf("permission denied") - } if h.UserSetCanceled != nil && !*h.UserSetCanceled { return h.GetOrder(ctx) } @@ -259,38 +257,41 @@ func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { case ordertypes.OrderState_OrderStateWaitPayment: fallthrough //nolint case ordertypes.OrderState_OrderStateCheckPayment: - if h.FromAdmin { + if h.AdminSetCanceled != nil { return nil, fmt.Errorf("permission denied") } - fallthrough //nolint case ordertypes.OrderState_OrderStatePaid: - fallthrough //nolint case ordertypes.OrderState_OrderStateInService: - if err := handler.validate(ctx); err != nil { - return nil, err - } - if err := handler.processLedger(ctx); err != nil { - return nil, err - } - if err := handler.processCancel(ctx); err != nil { - return nil, err - } } case ordertypes.OrderType_Offline: fallthrough //nolint case ordertypes.OrderType_Airdrop: - if !h.FromAdmin { + if h.AdminSetCanceled == nil { return nil, fmt.Errorf("permission denied") } - if err := handler.validate(ctx); err != nil { - return nil, err - } - if err := handler.processCancel(ctx); err != nil { - return nil, err - } default: return nil, fmt.Errorf("order type uncancellable") } + if err := handler.cancelable(ctx); err != nil { + return nil, err + } + + if err := handler.processStatements(ctx); err != nil { + return nil, err + } + + sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ + WaitResult: true, + RequestTimeout: handler.RequestTimeoutSeconds, + }) + + handler.withLockCommission(sagaDispose) + handler.withProcessCancel(sagaDispose) + + if err := dtmcli.WithSaga(ctx, sagaDispose); err != nil { + return nil, err + } + return handler.GetOrder(ctx) } From 232238b647a6a1e7b0fb3a656adff4de6a2caea3 Mon Sep 17 00:00:00 2001 From: jakys Date: Mon, 4 Sep 2023 12:09:57 +0000 Subject: [PATCH 12/67] Fix update --- pkg/order/update.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/order/update.go b/pkg/order/update.go index 152046e..f6c20d1 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -214,8 +214,8 @@ func (h *updateHandler) withProcessCancel(dispose *dtmcli.SagaDispose) { } dispose.Add( ordermwsvcname.ServiceDomain, - "order.middleware.order1.v1.Middleware/SubBalance", - "order.middleware.order1.v1.Middleware/AddBalance", + "order.middleware.order1.v1.Middleware/UpdateOrder", + "", &ordermwpb.UpdateOrderRequest{ Info: req, }, From 0c1834c224372c35f562ed4f4702580dee1fdc17 Mon Sep 17 00:00:00 2001 From: jakys Date: Mon, 4 Sep 2023 12:44:02 +0000 Subject: [PATCH 13/67] Fix query --- api/order/query.go | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/api/order/query.go b/api/order/query.go index 38534be..af3d96a 100644 --- a/api/order/query.go +++ b/api/order/query.go @@ -83,6 +83,8 @@ func (s *Server) GetOrder(ctx context.Context, in *npool.GetOrderRequest) (*npoo handler, err := order1.NewHandler( ctx, order1.WithID(&in.ID, true), + order1.WithAppID(&in.AppID, true), + order1.WithUserID(&in.AppID, &in.UserID, true), ) if err != nil { logger.Sugar().Errorw( @@ -114,18 +116,34 @@ func (s *Server) GetOrder(ctx context.Context, in *npool.GetOrderRequest) (*npoo } func (s *Server) GetAppOrders(ctx context.Context, in *npool.GetAppOrdersRequest) (*npool.GetAppOrdersResponse, error) { - resp, err := s.GetOrders(ctx, &npool.GetOrdersRequest{ - AppID: in.GetAppID(), - Offset: in.Offset, - Limit: in.Limit, - }) + handler, err := order1.NewHandler( + ctx, + order1.WithAppID(&in.AppID, true), + order1.WithOffset(in.GetOffset()), + order1.WithLimit(in.GetLimit()), + ) if err != nil { - return &npool.GetAppOrdersResponse{}, err + logger.Sugar().Errorw( + "GetAppOrders", + "In", in, + "Error", err, + ) + return &npool.GetAppOrdersResponse{}, status.Error(codes.InvalidArgument, err.Error()) + } + + infos, total, err := handler.GetOrders(ctx) + if err != nil { + logger.Sugar().Errorw( + "GetAppOrders", + "In", in, + "Error", err, + ) + return &npool.GetAppOrdersResponse{}, status.Error(codes.Internal, err.Error()) } return &npool.GetAppOrdersResponse{ - Infos: resp.Infos, - Total: resp.Total, + Infos: infos, + Total: total, }, nil } From c372f9ca2de84df550b169fdbb8c87be20e3ecc1 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Mon, 4 Sep 2023 15:36:55 +0000 Subject: [PATCH 14/67] Add create order --- pkg/order/create.go | 1030 ++++++++++++++++-------------------------- pkg/order/creates.go | 849 ++++++++++++++++++++++++++++++++++ pkg/order/handler.go | 68 ++- 3 files changed, 1273 insertions(+), 674 deletions(-) create mode 100644 pkg/order/creates.go diff --git a/pkg/order/create.go b/pkg/order/create.go index 5999c81..f5756fb 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -5,568 +5,420 @@ import ( "fmt" "time" - dtmcli "github.com/NpoolPlatform/dtm-cluster/pkg/dtm" - "github.com/NpoolPlatform/go-service-framework/pkg/logger" - "github.com/dtm-labs/dtm/client/dtmcli/dtmimp" - "github.com/google/uuid" - - cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" - ordermwsvcname "github.com/NpoolPlatform/order-middleware/pkg/servicename" - - appgoodstockmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/stock" - + payaccmwcli "github.com/NpoolPlatform/account-middleware/pkg/client/payment" + accountlock "github.com/NpoolPlatform/account-middleware/pkg/lock" appcoinmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/app/coin" coininfocli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin" currvalmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin/currency" - appcoinmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/app/coin" - currvalmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin/currency" - - sphinxproxypb "github.com/NpoolPlatform/message/npool/sphinxproxy" - sphinxproxycli "github.com/NpoolPlatform/sphinx-proxy/pkg/client" - - payaccmwcli "github.com/NpoolPlatform/account-middleware/pkg/client/payment" - accountlock "github.com/NpoolPlatform/account-middleware/pkg/lock" - payaccmwpb "github.com/NpoolPlatform/message/npool/account/mw/v1/payment" - - ledgermwpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger" - - ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" - ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" - + dtmcli "github.com/NpoolPlatform/dtm-cluster/pkg/dtm" + "github.com/NpoolPlatform/go-service-framework/pkg/logger" + redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" - allocatedmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/coupon/allocated" - + cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" + payaccmwpb "github.com/NpoolPlatform/message/npool/account/mw/v1/payment" inspiretypes "github.com/NpoolPlatform/message/npool/basetypes/inspire/v1" ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" + appcoinmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/app/coin" + currvalmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin/currency" + appgoodstockmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/stock" + allocatedmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/coupon/allocated" + ledgermwpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger" npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" + ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" + sphinxproxypb "github.com/NpoolPlatform/message/npool/sphinxproxy" + ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" + ordermwsvcname "github.com/NpoolPlatform/order-middleware/pkg/servicename" + sphinxproxycli "github.com/NpoolPlatform/sphinx-proxy/pkg/client" + "github.com/dtm-labs/dtm/client/dtmcli/dtmimp" - redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" - + "github.com/google/uuid" "github.com/shopspring/decimal" ) type createHandler struct { *Handler - orderGood *OrderGood - - startAts map[string]uint32 - endAts map[string]uint32 - - reductionAmount decimal.Decimal - reductionPercent decimal.Decimal - - goodPrices map[string]decimal.Decimal - - liveCurrency decimal.Decimal - localCurrency decimal.Decimal - coinCurrency decimal.Decimal - - goodValueCoins map[string]decimal.Decimal - goodValueUSDs map[string]decimal.Decimal - paymentAmountCoin decimal.Decimal - discountAmountCoin decimal.Decimal - paymentTransferAmount decimal.Decimal - - mainPaymentType *ordertypes.PaymentType - mainOrderID string - - paymentCoinName string - paymentAddressStartAmount decimal.Decimal - paymentAccount *payaccmwpb.Account + user *usermwpb.User + appGood *appgoodmwpb.Good + paymentCoin *appcoinmwpb.Coin + paymentAccount *payaccmwpb.Account + paymentStartAmount decimal.Decimal // TODO + coupons map[string]*allocatedmwpb.Coupon + currency *currencymwpb.Currency + promotion *topmostmwpb.TopMost + goodValueUSDTAmount decimal.Decimal + goodValueCoinAmount decimal.Decimal + paymentCoinAmount decimal.Decimal + reductionUSDTAmount decimal.Decimal + reductionCoinAmount decimal.Decimal + liveCurrencyAmount decimal.Decimal + coinCurrencyAmount decimal.Decimal + localCurrencyAmount decimal.Decimal + balanceCoinAmount decimal.Decimal + transferCoinAmount decimal.Decimal + paymentType types.PaymentType + orderStartAt uint32 // TODO + orderEndAt uint32 // TODO } -func tomorrowStart() time.Time { - now := time.Now() - y, m, d := now.Date() - return time.Date(y, m, d+1, 0, 0, 0, 0, now.Location()) +func (h *createHandler) getUser(ctx context.Context) error { + user, err := usermwcli.GetUser(ctx, *h.AppID, *h.UserID) + if err != nil { + return err + } + if user == nil { + return fmt.Errorf("invalid user") + } + h.user = user + return nil } -func (h *createHandler) validateInit(ctx context.Context) error { - coin, err := coininfocli.GetCoin(ctx, *h.PaymentCoinID) +func (h *creatHandler) getPaymentCoin(ctx context.Context) error { + coin, err := appcoinmwcli.GetCoinOnly(ctx, &appcoinmwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinTypeID}, + }) if err != nil { return err } if coin == nil { - return fmt.Errorf("invalid coin") + return fmt.Errorf("invalid paymentcoin") } - if coin.Presale { - return fmt.Errorf("presale coin won't for payment") + if coin.PreSale { + return fmt.Errorf("invalid paymentcoin") } if !coin.ForPay { - return fmt.Errorf("coin not for payment") + return fmt.Errorf("invalid paymentcoin") } - h.paymentCoinName = coin.Name - - for _, goodReq := range h.Goods { - good := h.orderGood.goods[goodReq.GoodID] - gcoin, err := coininfocli.GetCoin(ctx, good.CoinTypeID) - if err != nil { - return err - } - if gcoin == nil { - return fmt.Errorf("invalid good coin") - } - if coin.ENV != gcoin.ENV { - return fmt.Errorf("good coin mismatch payment coin") - } + h.paymentCoin = coin + return nil +} - appgood := h.orderGood.appgoods[*h.AppID+*h.GoodID] - goodStartAt := appgood.ServiceStartAt - if appgood.ServiceStartAt == 0 { - goodStartAt = good.StartAt - } - goodDurationDays := uint32(good.DurationDays) - startAt := uint32(tomorrowStart().Unix()) - if goodStartAt > startAt { - startAt = goodStartAt - } - const secondsPerDay = 24 * 60 * 60 - endAt := startAt + goodDurationDays*secondsPerDay - h.startAts[*h.AppID+goodReq.GoodID] = startAt - h.endAts[*h.AppID+goodReq.GoodID] = endAt - } - - const maxUnpaidOrders = 5 - orders, _, err := ordermwcli.GetOrders(ctx, &ordermwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, - PaymentState: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(ordertypes.PaymentState_PaymentStateWait)}, - }, 0, maxUnpaidOrders) +func (h *createHandler) getCoupons(ctx context.Context) error { + coupons, _, err := allocatedmwcli.GetCoupons(ctx, &allocatedmwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: h.CouponIDs}, + }, int32(0), int32(len(h.CouponIDs))) if err != nil { return err } - if len(orders) >= maxUnpaidOrders && *h.OrderType == ordertypes.OrderType_Normal { - return fmt.Errorf("too many unpaid orders") + if len(coupons) < len(h.CouponIDs) { + return fmt.Errorf("invalid coupon") + } + for _, coupon := range coupons { + if !coupon.Valid || coupon.Expired { + return fmt.Errorf("invalid coupon") + } + h.coupons[coupon.ID] = coupon } - return nil } -func (h *createHandler) checkGoodRequests() error { - goodRequiredSet := make(map[string]struct{}) - goodSet := make(map[string]struct{}) - for _, goodRequired := range h.orderGood.goodRequireds { - goodRequiredSet[goodRequired.RequiredGoodID] = struct{}{} +func (h *creatHandler) validateDiscountCoupon() error { + discountCoupons := 0 + for _, coupon := range h.coupons { + if coupon.CouponType == inspiretypes.CouponType_Discount { + discountCoupons++ + } } + if discountCoupons > 1 { + return fmt.Errorf("invalid discountcoupon") + } + return nil +} - for _, goodReq := range h.Goods { - if !goodReq.Parent { - if _, ok := goodRequiredSet[goodReq.GoodID]; !ok { - return fmt.Errorf("invalid goodrequired") - } - goodSet[goodReq.GoodID] = struct{}{} - } +func (h *createHandler) getAppGood(ctx context.Context) error { + good, err := appgoodmwcli.GetGood(ctx, *h.AppGoodID) + if err != nil { + return err + } + if good == nil { + return fmt.Errorf("invalid good") } + h.appGood = good + return nil +} - for _, goodRequired := range h.orderGood.goodRequireds { - if goodRequired.Must { - if _, ok := goodSet[goodRequired.RequiredGoodID]; !ok { - return fmt.Errorf("invalid goodrequired must") - } - } +func (h *createHandler) getAppGoodPromotion(ctx context.Context) error { + promotion, err := topmostmwcli.GetTopMostOnly(ctx, &topmostmwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + AppGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppGoodID}, + // TODO: Add topmost type of promotion + // TODO: One good is added to multiple topmost + }) + if err != nil { + return err } + h.promotion = promotion return nil } -// nolint -func (h *createHandler) SetReduction(ctx context.Context) error { - if len(h.CouponIDs) == 0 { +func (h *createHandler) calculateOrderUSDTPrice() error { + units, err := decimal.NewFromString(*h.Units) + if err != nil { + return err + } + amount, err := decimal.NewFromString(h.appGood.Price) + if err != nil { + return err + } + if amount.Cmp(decimal.NewFromInt(0)) <= 0 { + return fmt.Errorf("invalid price") + } + if h.promotion == nil { + h.paymentUSDTAmount = amount.Mul(units) return nil } - - coupons, _, err := allocatedmwcli.GetCoupons(ctx, &allocatedmwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, - IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: h.CouponIDs}, - }, int32(0), int32(len(h.CouponIDs))) + amount, err = decimal.NewFromString(h.promotion.Price) if err != nil { return err } - if len(coupons) != len(h.CouponIDs) { - return fmt.Errorf("invalid coupon") + if amount.Cmp(decimal.NewFromInt(0)) <= 0 { + return fmt.Errorf("invalid price") } + h.paymentUSDTAmount = amount.Mul(units) + return nil +} - couponTypeDiscountNum := 0 - for _, coup := range coupons { - if !coup.Valid || coup.Expired || coup.AppID != *h.AppID || coup.UserID != *h.UserID { - return fmt.Errorf("invalid coupon") - } - switch coup.CouponType { - case inspiretypes.CouponType_FixAmount: - fallthrough //nolint - case inspiretypes.CouponType_SpecialOffer: - amount, err := decimal.NewFromString(coup.Denomination) +func (h *createHandler) calculateDiscountCouponReduction() error { + for _, coupon := range h.coupons { + if coupon.CouponType == inspiretypes.CouponType_Discount { + discount, err := decimal.NewFromString(coupon.Denomination) if err != nil { return err } - h.reductionAmount = h.reductionAmount.Add(amount) - case inspiretypes.CouponType_Discount: - if couponTypeDiscountNum > 1 { - return fmt.Errorf("invalid discount") - } - percent, err := decimal.NewFromString(coup.Denomination) - if err != nil { - return err - } - if percent.Cmp(decimal.NewFromInt(100)) >= 0 { - return fmt.Errorf("invalid discount") - } - h.reductionPercent = percent - couponTypeDiscountNum++ - default: - return fmt.Errorf("unknown coupon type") + h.reductionUSDTAmount = h.reductionUSDTAmount. + Add(h.paymentUSDTAmount.Mul(discount).Div(decimal.NewFromInt(100))) //nolint + return nil } } - - return nil } -func (h *createHandler) SetPrice(ctx context.Context) error { - for _, goodReq := range h.Goods { - appgood := h.orderGood.appgoods[*h.AppID+goodReq.GoodID] - topmostGood := h.orderGood.topMostGoods[*h.AppID+goodReq.GoodID] - price, err := decimal.NewFromString(appgood.Price) - if err != nil { - return err - } - - if topmostGood != nil { - promotionPrice, err := decimal.NewFromString(topmostGood.GetPrice()) +func (h *createHandler) calculateFixAmountCouponReduction() error { + for _, coupon := range h.coupons { + switch coupon.CouponType { + case inspiretypes.CouponType_FixAmount: + fallthrough //nolint + case inspiretypes.CouponType_SpecialOffer: + amount, err := decimal.NewFromString(coupon.Denomination) if err != nil { return err } - if promotionPrice.Cmp(decimal.NewFromInt(0)) <= 0 { - return fmt.Errorf("invalid price") - } - price = promotionPrice + h.reductionUSDTAmount = h.reductionUSDTAmount.Add(amount) } - h.goodPrices[*h.AppID+goodReq.GoodID] = price } - return nil } -func (h *createHandler) SetCurrency(ctx context.Context) error { - curr, err := currvalmwcli.GetCurrencyOnly(ctx, &currvalmwpb.Conds{ - CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, +func (h *createHandler) checkPaymentCoinCurrency(ctx context.Context) error { + currency, err := currencymwcli.GetCurrencyOnly(ctx, ¤cymwpb.Conds{ + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: h.paymentCoin.CoinTypeID}, }) if err != nil { return err } - if curr == nil { - return fmt.Errorf("invalid coin currency") + if currency == nil { + return fmt.Errorf("invalid currency") } - const maxElapsed = uint32(10 * 60) - if curr.UpdatedAt+maxElapsed < uint32(time.Now().Unix()) { + if currency.UpdatedAt+maxElapsed < uint32(time.Now().Unix()) { return fmt.Errorf("stale coin currency") } - - val, err := decimal.NewFromString(curr.MarketValueLow) + amount, err := decimal.NewFromString(currency.MarketValueLow) if err != nil { return err } - if val.Cmp(decimal.NewFromInt(0)) <= 0 { + if amount.Cmp(decimal.NewFromInt(0)) <= 0 { return fmt.Errorf("invalid market value") } - h.liveCurrency = val - h.coinCurrency = val - - apc, err := appcoinmwcli.GetCoinOnly(ctx, &appcoinmwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, - }) - if err != nil { - return err - } - if apc == nil { - return nil - } + h.liveCurrencyAmount = amount + h.coinCurrencyAmount = amount - currVal, err := decimal.NewFromString(apc.SettleValue) + amount, err = decimal.NewFromString(h.paymentCoin.SettleValue) if err != nil { return err } - if currVal.Cmp(decimal.NewFromInt(0)) > 0 { - h.coinCurrency = currVal + if amount.Cmp(decimal.NewFromInt(0)) > 0 { + h.coinCurrency = amount } - currVal, err = decimal.NewFromString(apc.MarketValue) + amount, err = decimal.NewFromString(h.paymentCoin.MarketValue) if err != nil { return err } - if currVal.Cmp(decimal.NewFromInt(0)) > 0 { - h.localCurrency = currVal + if amount.Cmp(decimal.NewFromInt(0)) > 0 { + h.localCurrency = amount } - return nil } -func getAccuracy(coin decimal.Decimal) decimal.Decimal { - const accuracy = 1000000 - coin = coin.Mul(decimal.NewFromInt(accuracy)) - coin = coin.Ceil() - coin = coin.Div(decimal.NewFromInt(accuracy)) - return coin -} - -func (h *createHandler) SetPaymentAmount(ctx context.Context) error { - totalPaymentAmountUSD := decimal.NewFromInt(0) - for _, goodReq := range h.Goods { - price := h.goodPrices[*h.AppID+goodReq.GoodID] - units, err := decimal.NewFromString(goodReq.Units) - if err != nil { - return err - } - paymentAmountUSD := price.Mul(units) - totalPaymentAmountUSD = totalPaymentAmountUSD.Add(paymentAmountUSD) - h.goodValueUSDs[goodReq.GoodID] = paymentAmountUSD - - goodValueCoin := paymentAmountUSD.Div(h.coinCurrency) - goodValueCoin = getAccuracy(goodValueCoin) - h.paymentAmountCoin = h.paymentAmountCoin.Add(goodValueCoin) - h.goodValueCoins[goodReq.GoodID] = goodValueCoin +func (h *createHandler) checkPaymentCoinAmount() error { + amount := h.goodValueUSDTAmount. + Sub(h.reductionUSDTAmount). + Div(h.coinCurrency) + if amount.Cmp(decimal.NewFromInt(0)) <= 0 { + return fmt.Errorf("invalid price") } + h.paymentCoinAmount = amount + h.goodValueCoinAmount = h.goodValueUSDTAmount.Div(h.coinCurrency) + h.reductionCoinAmount = h.reductionUSDTAmount.Div(h.coinCurrency) + return nil +} - logger.Sugar().Infow( - "CreateOrder", - "PaymentAmountUSD", totalPaymentAmountUSD, - "ReductionAmount", h.reductionAmount, - "ReductionPercent", h.reductionPercent, - ) - - discountAmountUSD := decimal.NewFromInt(0) - if h.reductionPercent != decimal.NewFromInt(0) { - discountAmountUSD = totalPaymentAmountUSD. - Mul(h.reductionPercent). - Div(decimal.NewFromInt(100)) //nolint +func (h *createHandler) checkTransferCoinAmount() error { + if h.BalanceAmount == nil { + h.transferCoinAmount = h.paymentCoinAmount + return nil } - discountAmountUSD = discountAmountUSD.Add(h.reductionAmount) - - h.discountAmountCoin = discountAmountUSD.Div(h.coinCurrency) - h.discountAmountCoin = getAccuracy(h.discountAmountCoin) - if *h.OrderType == ordertypes.OrderType_Airdrop { - h.paymentAmountCoin = decimal.NewFromInt(0) + balanceCoinAmount, err := decimal.NewFromString(*h.BalanceAmount) + if err != nil { + return err } - - h.paymentAmountCoin = h.paymentAmountCoin.Sub(h.discountAmountCoin) - if h.paymentAmountCoin.Cmp(decimal.NewFromInt(0)) < 0 { - h.paymentAmountCoin = decimal.NewFromInt(0) + if balanceCoinAmount.Cmp(decimal.NewFromInt(0)) <= 0 { + return fmt.Errorf("invalid balanceamount") } - - h.paymentTransferAmount = h.paymentAmountCoin - if h.BalanceAmount != nil { - amount, err := decimal.NewFromString(*h.BalanceAmount) - if err != nil { - return err - } - if amount.Cmp(h.paymentTransferAmount) > 0 { - amount = h.paymentTransferAmount - amountStr := amount.String() - h.BalanceAmount = &amountStr - } - h.paymentTransferAmount = h.paymentTransferAmount.Sub(amount) + h.balanceCoinAmount = balanceCoinAmount + h.transferCoinAmount = h.paymentCoinAmount.Sub(balanceCoinAmount) + if h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) < 0 { + h.balanceCoinAmount = h.paymentCoinAmount + h.transferCoinAmount = decimal.NewFromInt(0) } - return nil } -func (h *createHandler) paymentType() (*ordertypes.PaymentType, error) { - switch *h.OrderType { - case ordertypes.OrderType_Normal: - if h.BalanceAmount != nil { - if h.paymentTransferAmount.Cmp(decimal.NewFromInt(0)) > 0 { - return ordertypes.PaymentType_PayWithTransferAndBalance.Enum(), nil - } - return ordertypes.PaymentType_PayWithBalanceOnly.Enum(), nil - } - return ordertypes.PaymentType_PayWithTransferOnly.Enum(), nil - case ordertypes.OrderType_Offline: - return ordertypes.PaymentType_PayWithOffline.Enum(), nil - case ordertypes.OrderType_Airdrop: - return ordertypes.PaymentType_PayWithNoPayment.Enum(), nil - default: - return nil, fmt.Errorf("invalid ordertype") +func (h *createHandler) resolvePaymentType() { + if h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 && + h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 { + h.paymentType = types.PaymentType_PaymentTypeNoPayment + return + } + if h.transferCoinAmount.Cmp(h.paymentCoinAmount) == 0 { + h.paymentType = types.PaymentType_PaymentTypeTransferOnly + return + } + if h.balanceCoinAmount.Cmp(h.paymentCoinAmount) == 0 { + h.paymentType = types.PaymentType_PaymentTypeBalanceOnly + return } + h.paymentType = types.PaymentType_PaymentTypeTransferAndBalance } -func (h *createHandler) SetPaymentType(ctx context.Context) error { - paymentType, err := h.paymentType() +func (h *createHandler) peekExistAddress(ctx context.Context) (*payaccmwpb.Account, error) { + const batchAccounts = int32(5) + accounts, _, err := payaccmwcli.GetAccounts(ctx, &payaccmwcli.Conds{ + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: h.PaymentCoin.CoinTypeID}, + Active: &basetypes.BoolVal{Op: cruder.EQ, Value: true}, + Locked: &basetypes.BoolVal{Op: cruder.EQ, Value: false}, + Blocked: &basetypes.BoolVal{Op: cruder.EQ, Value: false}, + AvailableAt: &basetypes.Uint32Val{Op: cruder.LTE, Value: uint32(time.Now().Unix())}, + }, int32(0), batchAccounts) if err != nil { return err } - h.mainPaymentType = paymentType + for _, account := range accounts { + if info.Locked || !info.Active || info.Blocked { + continue + } + if info.AvailableAt > uint32(time.Now().Unix()) { + continue + } + return account + } return nil } -func (h *createHandler) createAddresses(ctx context.Context) error { +func (h *createHandler) peekNewAddress(ctx context.Context) (*payaccmwpb.Account, error) { const createCount = 5 successCreated := 0 for i := 0; i < createCount; i++ { - address, err := sphinxproxycli.CreateAddress(ctx, h.paymentCoinName) + address, err := sphinxproxycli.CreateAddress(ctx, h.paymentCoin.CoinName) if err != nil { return err } if address == nil || address.Address == "" { return fmt.Errorf("invalid address") } - _, err = payaccmwcli.CreateAccount(ctx, &payaccmwpb.AccountReq{ - CoinTypeID: h.PaymentCoinID, + CoinTypeID: h.paymentCoin.CoinTypeID, Address: &address.Address, }) if err != nil { return err } - successCreated++ } - if successCreated == 0 { return fmt.Errorf("fail create addresses") } - return nil + return h.peekExistAddress(ctx) } -func (h *createHandler) peekAddress(ctx context.Context) (*payaccmwpb.Account, error) { - payments, _, err := payaccmwcli.GetAccounts(ctx, &payaccmwpb.Conds{ - CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, - Active: &basetypes.BoolVal{Op: cruder.EQ, Value: true}, - Locked: &basetypes.BoolVal{Op: cruder.EQ, Value: false}, - Blocked: &basetypes.BoolVal{Op: cruder.EQ, Value: false}, - AvailableAt: &basetypes.Uint32Val{Op: cruder.LTE, Value: uint32(time.Now().Unix())}, - }, 0, 5) //nolint - if err != nil { - return nil, err +func (h *createHandler) peekPaymentAddress(ctx context.Context) error { + switch h.paymentType { + case types.PaymentType_PaymentTypeBalanceOnly: + fallthrough //nolint + case types.PaymentType_PaymentTypeNoPayment: + return nil } - var account *payaccmwpb.Account - - for _, payment := range payments { - info, err := payaccmwcli.GetAccount(ctx, payment.ID) + account, err := handler.peekExistAddress(ctx) + if err != nil { + account, err = handler.peekNewAddress(ctx) if err != nil { - return nil, err - } - - if info.Locked || !info.Active || info.Blocked { - continue - } - - if info.AvailableAt > uint32(time.Now().Unix()) { - continue + return err } - account = info - break } - - if account == nil { - return nil, nil - } - h.paymentAccount = account - - return account, nil -} - -func (h *createHandler) withLockPaymentAccount(dispose *dtmcli.SagaDispose) { - switch *h.mainPaymentType { - case ordertypes.PaymentType_PayWithTransferOnly: - fallthrough //nolint - case ordertypes.PaymentType_PayWithTransferAndBalance: - fallthrough //nolint - case ordertypes.PaymentType_PayWithOffline: - locked := true - lockedBy := basetypes.AccountLockedBy_Payment - req := &payaccmwpb.AccountReq{ - ID: &h.paymentAccount.ID, - Locked: &locked, - LockedBy: &lockedBy, - } - dispose.Add( - ordermwsvcname.ServiceDomain, - "account.middleware.payment.v1.Middleware/UpdateAccount", - "", - &payaccmwpb.UpdateAccountRequest{ - Info: req, - }, - ) - } + return nil } -func (h *createHandler) PeekAddress(ctx context.Context) error { - account, err := h.peekAddress(ctx) - if err != nil { - return err - } - if account != nil { - h.paymentAccount = account - return nil - } - - if err := h.createAddresses(ctx); err != nil { - return err - } - - account, err = h.peekAddress(ctx) +func (h *createHandler) recheckPaymentAccount(ctx context.Context) error { + account, err := payaccmwcli.GetAccount(ctx, h.paymentAccount.ID) if err != nil { return err } if account == nil { - return fmt.Errorf("fail peek address") + return fmt.Errorf("invalid account") } - - h.paymentAccount = account - return nil -} - -func (h *createHandler) SetAddressBalance(ctx context.Context) error { - balance, err := sphinxproxycli.GetBalance(ctx, &sphinxproxypb.GetBalanceRequest{ - Name: h.paymentCoinName, - Address: h.paymentAccount.Address, - }) - if err != nil { - return err + if account.Locked || !account.Active || account.Blocked { + return fmt.Errorf("invalid account") } - if balance == nil { - return fmt.Errorf("invalid balance") + if account.AvailableAt > uint32(time.Now().Unix()) { + return fmt.Errorf("invalid account") } - - h.paymentAddressStartAmount, err = decimal.NewFromString(balance.BalanceStr) - return err + return nil } func (h *createHandler) withUpdateStock(dispose *dtmcli.SagaDispose) { - for _, goodReq := range h.Goods { - req := &appgoodstockmwpb.StockReq{ - AppID: h.AppID, - GoodID: &goodReq.GoodID, - Locked: &goodReq.Units, - } - dispose.Add( - ordermwsvcname.ServiceDomain, - "good.middleware.app.good1.stock.v1.Middleware/AddStock", - "good.middleware.app.good1.stock.v1.Middleware/SubStock", - &appgoodstockmwpb.AddStockRequest{ - Info: req, - }, - ) + req := &appgoodstockmwpb.StockReq{ + AppGoodID: h.AppGoodID, + Locked: h.Units, } + dispose.Add( + ordermwsvcname.ServiceDomain, + "good.middleware.app.good1.stock.v1.Middleware/AddStock", + "good.middleware.app.good1.stock.v1.Middleware/SubStock", + &appgoodstockmwpb.AddStockRequest{ + Info: req, + }, + ) } func (h *createHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { - if h.BalanceAmount != nil { + if h.balanceCoinAmount.Cmp(decimal.NewFromInt(0)) <= 0 { return } + + amount := h.balanceCoinAmount.String() req := &ledgermwpb.LedgerReq{ AppID: h.AppID, UserID: h.UserID, - CoinTypeID: &h.paymentAccount.CoinTypeID, - Spendable: h.BalanceAmount, + CoinTypeID: h.PaymentCoinTypeID, + Spendable: &amount, } dispose.Add( ordermwsvcname.ServiceDomain, @@ -578,96 +430,53 @@ func (h *createHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { ) } -func (h *createHandler) orderReqs() []*ordermwpb.OrderReq { - paymentAmount := h.paymentAmountCoin.String() - startAmount := h.paymentAddressStartAmount.String() - paymentTransferAmount := h.paymentTransferAmount.String() - coinCurrency := h.coinCurrency.String() - liveCurrency := h.liveCurrency.String() - localCurrency := h.localCurrency.String() - discountAmountCoin := h.discountAmountCoin.String() - childPaymentType := ordertypes.PaymentType_PayWithParentOrder - zeroAmount := "0" - h.mainOrderID = uuid.NewString() - - orderReqs := []*ordermwpb.OrderReq{} - for _, goodReq := range h.Goods { - goodValue := h.goodValueCoins[goodReq.GoodID].String() - goodValueUSD := h.goodValueUSDs[goodReq.GoodID].String() - appgood := h.orderGood.appgoods[*h.AppID+goodReq.GoodID] - good := h.orderGood.goods[goodReq.GoodID] - goodDurationDays := uint32(good.DurationDays) - startAt := h.startAts[*h.AppID+goodReq.GoodID] - endAt := h.endAts[*h.AppID+goodReq.GoodID] - - logger.Sugar().Infow( - "CreateOrder", - "PaymentAmountCoin", h.paymentAmountCoin, - "DiscountAmountCoin", h.discountAmountCoin, - "BalanceAmount", h.BalanceAmount, - "ReductionAmount", h.reductionAmount, - "ReductionPercent", h.reductionPercent, - "PaymentAddressStartAmount", h.paymentAddressStartAmount, - "CoinCurrency", h.coinCurrency, - "LiveCurrency", h.liveCurrency, - "LocalCurrency", h.localCurrency, - ) - orderReq := &ordermwpb.OrderReq{ - AppID: h.AppID, - UserID: h.UserID, - GoodID: &goodReq.GoodID, - AppGoodID: &appgood.ID, - Units: &goodReq.Units, - GoodValue: &goodValue, - GoodValueUSD: &goodValueUSD, - DurationDays: &goodDurationDays, - OrderType: h.OrderType, - InvestmentType: h.InvestmentType, - CoinTypeID: &good.CoinTypeID, - PaymentCoinTypeID: h.PaymentCoinID, - CoinUSDCurrency: &coinCurrency, - LiveCoinUSDCurrency: &liveCurrency, - LocalCoinUSDCurrency: &localCurrency, - StartAt: &startAt, - EndAt: &endAt, - } - - if !goodReq.Parent && h.ParentOrderID == nil { - id := uuid.NewString() - // batch child order - orderReq.ID = &id - orderReq.ParentOrderID = &h.mainOrderID - orderReq.PaymentAmount = &zeroAmount - orderReq.DiscountAmount = &zeroAmount - orderReq.PaymentType = &childPaymentType - orderReq.TransferAmount = &zeroAmount - orderReq.BalanceAmount = &zeroAmount - h.IDs = append(h.IDs, id) - } else { - // parent order or single order - orderReq.ID = &h.mainOrderID - orderReq.ParentOrderID = h.ParentOrderID - orderReq.PaymentAmount = &paymentAmount - orderReq.DiscountAmount = &discountAmountCoin - orderReq.CouponIDs = h.CouponIDs - orderReq.PaymentType = h.mainPaymentType - orderReq.TransferAmount = &paymentTransferAmount - orderReq.BalanceAmount = h.BalanceAmount - orderReq.PaymentAccountID = &h.paymentAccount.AccountID - orderReq.PaymentStartAmount = &startAmount - h.IDs = append(h.IDs, h.mainOrderID) - } - - topmostGood := h.orderGood.topMostGoods[*h.AppID+goodReq.GoodID] - if topmostGood != nil { - orderReq.PromotionID = &topmostGood.TopMostID - } - orderReqs = append(orderReqs, orderReq) +func (h *createHandler) withCreateOrder(dispose *dtmcli.SagaDispose) { + goodValueCoinAmount := h.goodValueCoinAmount.String() + goodValueUSDTAmount := h.goodValueUSDTAmount.String() + paymentCoinAmount := h.paymentCoinAmount.String() + discountCoinAmount := h.reductionCoinAmount.String() + transferCoinAmount := h.transferCoinAmount.String() + balanceCoinAmount := h.balanceCoinAmount.String() + coinUSDCurrency := h.coinCurrency.String() + localCoinUSDCurrency := h.localCurrency.String() + liveCoinUSDCurrency := h.liveCurrency.String() + + req := &ordermwpb.OrderReq{ + ID: h.ID, + AppID: h.AppID, + UserID: h.UserID, + GoodID: h.GoodID, + AppGoodID: h.AppGoodID, + ParentOrderID: h.ParentOrderID, + Units: h.Units, + GoodValue: &goodValueCoinAmount, + GoodValueUSD: &goodValueUSDTAmount, + PaymentAmount: &paymentCoinAmount, + DiscountAmount: &discountCoinAmount, + DurationDays: &h.appGood.DurationDays, + OrderType: h.OrderType, + InvestmentType: h.InvestmentType, + CouponIDs: h.CouponIDs, + PaymentType: &h.paymentType, + CoinTypeID: &h.appGood.CoinTypeID, + PaymentCoinTypeID: h.PaymentCoinTypeID, + TransferAmount: &transferCoinAmount, + BalanceAmount: &balanceCoinAmount, + CoinUSDCurrency: &coinUSDCurrency, + LocalCoinUSDCurrency: &localCoinUSDCurrency, + LiveCoinUSDCurrency: &liveCoinUSDCurrency, + StartAt: &h.orderStartAt, + EndAt: &h.orderEndAt, + StartMode: &h.appGood.StartMode, + } + if h.promotion != nil { + req.PromotionID = &h.promotion.ID + } + if h.paymentAccount != nil { + req.PaymentAccountID = &h.paymentAccount.AccountID + paymentStartAmount := h.paymentStartAmount.String() + req.PaymentStartAmount = &paymentStartAmount } - return orderReqs -} - -func (h *createHandler) withCreateOrder(dispose *dtmcli.SagaDispose, req *ordermwpb.OrderReq) { dispose.Add( ordermwsvcname.ServiceDomain, "order.middleware.order1.v1.Middleware/CreateOrder", @@ -678,196 +487,141 @@ func (h *createHandler) withCreateOrder(dispose *dtmcli.SagaDispose, req *orderm ) } -func (h *createHandler) withCreateOrders(dispose *dtmcli.SagaDispose, reqs []*ordermwpb.OrderReq) { +func (h *createHandler) withLockPaymentAccount(dispose *dtmcli.SagaDispose) { + if h.paymentAccount == nil { + return + } + + locked := true + lockedBy := basetypes.AccountLockedBy_Payment + req := &payaccmwpb.AccountReq{ + ID: &h.paymentAccount.ID, + Locked: &locked, + LockedBy: &lockedBy, + } dispose.Add( ordermwsvcname.ServiceDomain, - "order.middleware.order1.v1.Middleware/CreateOrders", - "order.middleware.order1.v1.Middleware/DeleteOrders", - &ordermwpb.CreateOrdersRequest{ - Infos: reqs, + "account.middleware.payment.v1.Middleware/UpdateAccount", + "", + &payaccmwpb.UpdateAccountRequest{ + Info: req, }, ) } -//nolint:funlen,gocyclo func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error) { - orderGood, err := h.ToOrderGood(ctx) - if err != nil { - return nil, err - } - handler := &createHandler{ - Handler: h, - orderGood: orderGood, - } - if err := handler.validateInit(ctx); err != nil { - return nil, err - } - - if err := handler.SetReduction(ctx); err != nil { - return nil, err - } + // 1 Check input + // 1.1 Check user + // 1.2 Check app good + // 1.3 Check payment coin + // 1.4 Check parent order (by middleware && handler) + // 1.5 Check coupon ids (by handler) + // 1.6 Check balance (by dtm lock) + // 1.7 Check only one discount coupon + // 2 Calculate reduction + // 2.1 Calculate amount of discount coupon + // 2.2 Calculate amount of fix amount + // 3 Calculate price + // 3.1 Calculate USDT GoodValue - DiscountAmount + // 3.2 Get currency + // 3.3 Calculate payment coin amount + // 4 Peek address + // 4.1 Peek exist address + // 4.2 If fail, create addresses them peek one + // 4.3 Redis lock address + // 4.4 Recheck address lock + // DTM + // 5 Lock balance + // 6 Create order + // 7 Lock address + // 8 Created order notification (by scheduler) + // 9 Order payment notification (by scheduler) + // 10 Payment timeout notification (by scheduler) + // 11 Reward (by scheduler) - if err := handler.SetPrice(ctx); err != nil { - return nil, err - } - - if err := handler.SetCurrency(ctx); err != nil { - return nil, err - } - - if err := handler.SetPaymentAmount(ctx); err != nil { - return nil, err - } - - if err := handler.SetPaymentType(ctx); err != nil { - return nil, err - } - - switch *handler.mainPaymentType { - case ordertypes.PaymentType_PayWithTransferOnly: - fallthrough //nolint - case ordertypes.PaymentType_PayWithTransferAndBalance: - fallthrough //nolint - case ordertypes.PaymentType_PayWithOffline: - for i := 0; i < 5; i++ { - if err := handler.PeekAddress(ctx); err != nil { - return nil, err - } - if err := accountlock.Lock(handler.paymentAccount.AccountID); err != nil { - continue - } - break - } - defer func() { - accountlock.Unlock(handler.paymentAccount.AccountID) //nolint - }() - if err := handler.SetAddressBalance(ctx); err != nil { - return nil, err - } + handler := &createHandler{ + Handler: h, } - - createReqs := handler.orderReqs() - lockKey := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, handler.mainOrderID) - if err := redis2.TryLock(lockKey, 0); err != nil { - return nil, err + if err := handler.getUser(ctx); err != nil { + return err } - defer func() { - _ = redis2.Unlock(lockKey) - }() - - sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ - WaitResult: true, - RequestTimeout: handler.RequestTimeoutSeconds, - }) - - handler.withUpdateStock(sagaDispose) - handler.withUpdateBalance(sagaDispose) - handler.withCreateOrder(sagaDispose, createReqs[0]) - handler.withLockPaymentAccount(sagaDispose) - - if err := dtmcli.WithSaga(ctx, sagaDispose); err != nil { - return nil, err + if err := handler.checkPaymentCoin(ctx); err != nil { + return err } - - orders, _, err := h.GetOrders(ctx) - if err != nil { - return nil, err + if err := handler.getCoupons(ctx); err != nil { + return err } - if len(orders) == 0 { - return nil, nil + if err := handler.validateDiscountCoupon(ctx); err != nil { + return err } - - return orders[0], nil -} - -//nolint:funlen,gocyclo -func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err error) { - orderGood, err := h.ToOrderGoods(ctx) - if err != nil { - return nil, err + if err := handler.getAppGood(ctx); err != nil { + return err } - handler := &createHandler{ - Handler: h, - orderGood: orderGood, + if err := handler.getAppGoodPromotion(ctx); err != nil { + return err } - if err := handler.validateInit(ctx); err != nil { - return nil, err + if err := handler.calculateOrderUSDTPrice(ctx); err != nil { + return err } - - if err := handler.checkGoodRequests(); err != nil { - return nil, err + if err := handler.calculateDiscountCouponReduction(); err != nil { + return err } - - if err := handler.SetReduction(ctx); err != nil { - return nil, err + if err := handler.calculateFixAmountCouponReduction(); err != nil { + return err } - - if err := handler.SetPrice(ctx); err != nil { - return nil, err + if err := handler.checkPaymentCoinCurrency(ctx); err != nil { + return err } - - if err := handler.SetCurrency(ctx); err != nil { - return nil, err + if err := handler.checkPaymentCoinAmount(); err != nil { + return err } - - if err := handler.SetPaymentAmount(ctx); err != nil { - return nil, err + if err := handler.checkTransferCoinAmount(); err != nil { + return err } + handler.resolvePaymentType() - if err := handler.SetPaymentType(ctx); err != nil { - return nil, err + if err := handler.peekPaymentAddress(ctx); err != nil { + return err } - - switch *handler.mainPaymentType { - case ordertypes.PaymentType_PayWithTransferOnly: - fallthrough //nolint - case ordertypes.PaymentType_PayWithTransferAndBalance: - fallthrough //nolint - case ordertypes.PaymentType_PayWithOffline: - for i := 0; i < 5; i++ { - if err := handler.PeekAddress(ctx); err != nil { - return nil, err - } - if err := accountlock.Lock(handler.paymentAccount.AccountID); err != nil { - continue - } - break + if handler.paymentAccount != nil { + if err := accountlock.Lock(handler.paymentAccount.AccountID); err != nil { + return err + } + if err := handler.recheckPaymentAccount(ctx); err != nil { + return err } defer func() { - accountlock.Unlock(handler.paymentAccount.AccountID) //nolint + _ = accountlock.Unlock(handler.paymentAccount.AccountID) }() - if err := handler.SetAddressBalance(ctx); err != nil { - return nil, err - } } - createReqs := handler.orderReqs() - lockKey := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, handler.mainOrderID) - if err := redis2.TryLock(lockKey, 0); err != nil { - return nil, err + id := uuid.NewString() + if h.ID == nil { + h.ID = &id + } + + key := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, id) + if err := redis2.TryLock(key, 0); err != nil { + return err } defer func() { - _ = redis2.Unlock(lockKey) + _ = redis2.Unlock(key) }() + const timeoutSeconds = 10 sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ WaitResult: true, - RequestTimeout: handler.RequestTimeoutSeconds, + RequestTimeout: timeoutSeconds, }) handler.withUpdateStock(sagaDispose) handler.withUpdateBalance(sagaDispose) - handler.withCreateOrders(sagaDispose, createReqs) + handler.withCreateOrder(sagaDispose) handler.withLockPaymentAccount(sagaDispose) if err := dtmcli.WithSaga(ctx, sagaDispose); err != nil { return nil, err } - orders, _, err := h.GetOrders(ctx) - if err != nil { - return nil, err - } - - return orders, nil + return h.GetOrder(ctx) } diff --git a/pkg/order/creates.go b/pkg/order/creates.go new file mode 100644 index 0000000..22fadca --- /dev/null +++ b/pkg/order/creates.go @@ -0,0 +1,849 @@ +package order + +import ( + "context" + "fmt" + "time" + + payaccmwcli "github.com/NpoolPlatform/account-middleware/pkg/client/payment" + accountlock "github.com/NpoolPlatform/account-middleware/pkg/lock" + appcoinmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/app/coin" + coininfocli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin" + currvalmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin/currency" + dtmcli "github.com/NpoolPlatform/dtm-cluster/pkg/dtm" + "github.com/NpoolPlatform/go-service-framework/pkg/logger" + redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" + allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" + cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" + payaccmwpb "github.com/NpoolPlatform/message/npool/account/mw/v1/payment" + inspiretypes "github.com/NpoolPlatform/message/npool/basetypes/inspire/v1" + ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" + basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" + appcoinmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/app/coin" + currvalmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin/currency" + appgoodstockmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/stock" + allocatedmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/coupon/allocated" + ledgermwpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger" + npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" + ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" + sphinxproxypb "github.com/NpoolPlatform/message/npool/sphinxproxy" + ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" + ordermwsvcname "github.com/NpoolPlatform/order-middleware/pkg/servicename" + sphinxproxycli "github.com/NpoolPlatform/sphinx-proxy/pkg/client" + "github.com/dtm-labs/dtm/client/dtmcli/dtmimp" + + "github.com/google/uuid" + "github.com/shopspring/decimal" +) + +type createHandler struct { + *Handler + user *usermwpb.User + appGood []*appgoodmwpb.Good + paymentAccount *payaccmwpb.Account + coupons []*inspiremwpb.Coupon + currency *currencymwpb.Currency +} + +func tomorrowStart() time.Time { + now := time.Now() + y, m, d := now.Date() + return time.Date(y, m, d+1, 0, 0, 0, 0, now.Location()) +} + +func (h *createHandler) validateInit(ctx context.Context) error { + coin, err := coininfocli.GetCoin(ctx, *h.PaymentCoinID) + if err != nil { + return err + } + if coin == nil { + return fmt.Errorf("invalid coin") + } + if coin.Presale { + return fmt.Errorf("presale coin won't for payment") + } + if !coin.ForPay { + return fmt.Errorf("coin not for payment") + } + h.paymentCoinName = coin.Name + + for _, goodReq := range h.Goods { + good := h.orderGood.goods[goodReq.GoodID] + gcoin, err := coininfocli.GetCoin(ctx, good.CoinTypeID) + if err != nil { + return err + } + if gcoin == nil { + return fmt.Errorf("invalid good coin") + } + if coin.ENV != gcoin.ENV { + return fmt.Errorf("good coin mismatch payment coin") + } + + appgood := h.orderGood.appgoods[*h.AppID+*h.GoodID] + goodStartAt := appgood.ServiceStartAt + if appgood.ServiceStartAt == 0 { + goodStartAt = good.StartAt + } + goodDurationDays := uint32(good.DurationDays) + startAt := uint32(tomorrowStart().Unix()) + if goodStartAt > startAt { + startAt = goodStartAt + } + const secondsPerDay = 24 * 60 * 60 + endAt := startAt + goodDurationDays*secondsPerDay + h.startAts[*h.AppID+goodReq.GoodID] = startAt + h.endAts[*h.AppID+goodReq.GoodID] = endAt + } + + const maxUnpaidOrders = 5 + orders, _, err := ordermwcli.GetOrders(ctx, &ordermwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + PaymentState: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(ordertypes.PaymentState_PaymentStateWait)}, + }, 0, maxUnpaidOrders) + if err != nil { + return err + } + if len(orders) >= maxUnpaidOrders && *h.OrderType == ordertypes.OrderType_Normal { + return fmt.Errorf("too many unpaid orders") + } + + return nil +} + +func (h *createHandler) checkGoodRequests() error { + goodRequiredSet := make(map[string]struct{}) + goodSet := make(map[string]struct{}) + for _, goodRequired := range h.orderGood.goodRequireds { + goodRequiredSet[goodRequired.RequiredGoodID] = struct{}{} + } + + for _, goodReq := range h.Goods { + if !goodReq.Parent { + if _, ok := goodRequiredSet[goodReq.GoodID]; !ok { + return fmt.Errorf("invalid goodrequired") + } + goodSet[goodReq.GoodID] = struct{}{} + } + } + + for _, goodRequired := range h.orderGood.goodRequireds { + if goodRequired.Must { + if _, ok := goodSet[goodRequired.RequiredGoodID]; !ok { + return fmt.Errorf("invalid goodrequired must") + } + } + } + return nil +} + +// nolint +func (h *createHandler) SetReduction(ctx context.Context) error { + if len(h.CouponIDs) == 0 { + return nil + } + + coupons, _, err := allocatedmwcli.GetCoupons(ctx, &allocatedmwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: h.CouponIDs}, + }, int32(0), int32(len(h.CouponIDs))) + if err != nil { + return err + } + if len(coupons) != len(h.CouponIDs) { + return fmt.Errorf("invalid coupon") + } + + couponTypeDiscountNum := 0 + for _, coup := range coupons { + if !coup.Valid || coup.Expired || coup.AppID != *h.AppID || coup.UserID != *h.UserID { + return fmt.Errorf("invalid coupon") + } + switch coup.CouponType { + case inspiretypes.CouponType_FixAmount: + fallthrough //nolint + case inspiretypes.CouponType_SpecialOffer: + amount, err := decimal.NewFromString(coup.Denomination) + if err != nil { + return err + } + h.reductionAmount = h.reductionAmount.Add(amount) + case inspiretypes.CouponType_Discount: + if couponTypeDiscountNum > 1 { + return fmt.Errorf("invalid discount") + } + percent, err := decimal.NewFromString(coup.Denomination) + if err != nil { + return err + } + if percent.Cmp(decimal.NewFromInt(100)) >= 0 { + return fmt.Errorf("invalid discount") + } + h.reductionPercent = percent + couponTypeDiscountNum++ + default: + return fmt.Errorf("unknown coupon type") + } + } + + return nil +} + +func (h *createHandler) SetPrice(ctx context.Context) error { + for _, goodReq := range h.Goods { + appgood := h.orderGood.appgoods[*h.AppID+goodReq.GoodID] + topmostGood := h.orderGood.topMostGoods[*h.AppID+goodReq.GoodID] + price, err := decimal.NewFromString(appgood.Price) + if err != nil { + return err + } + + if topmostGood != nil { + promotionPrice, err := decimal.NewFromString(topmostGood.GetPrice()) + if err != nil { + return err + } + if promotionPrice.Cmp(decimal.NewFromInt(0)) <= 0 { + return fmt.Errorf("invalid price") + } + price = promotionPrice + } + h.goodPrices[*h.AppID+goodReq.GoodID] = price + } + + return nil +} + +func (h *createHandler) SetCurrency(ctx context.Context) error { + curr, err := currvalmwcli.GetCurrencyOnly(ctx, &currvalmwpb.Conds{ + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, + }) + if err != nil { + return err + } + if curr == nil { + return fmt.Errorf("invalid coin currency") + } + + const maxElapsed = uint32(10 * 60) + if curr.UpdatedAt+maxElapsed < uint32(time.Now().Unix()) { + return fmt.Errorf("stale coin currency") + } + + val, err := decimal.NewFromString(curr.MarketValueLow) + if err != nil { + return err + } + if val.Cmp(decimal.NewFromInt(0)) <= 0 { + return fmt.Errorf("invalid market value") + } + + h.liveCurrency = val + h.coinCurrency = val + + apc, err := appcoinmwcli.GetCoinOnly(ctx, &appcoinmwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, + }) + if err != nil { + return err + } + if apc == nil { + return nil + } + + currVal, err := decimal.NewFromString(apc.SettleValue) + if err != nil { + return err + } + if currVal.Cmp(decimal.NewFromInt(0)) > 0 { + h.coinCurrency = currVal + } + + currVal, err = decimal.NewFromString(apc.MarketValue) + if err != nil { + return err + } + if currVal.Cmp(decimal.NewFromInt(0)) > 0 { + h.localCurrency = currVal + } + + return nil +} + +func getAccuracy(coin decimal.Decimal) decimal.Decimal { + const accuracy = 1000000 + coin = coin.Mul(decimal.NewFromInt(accuracy)) + coin = coin.Ceil() + coin = coin.Div(decimal.NewFromInt(accuracy)) + return coin +} + +func (h *createHandler) SetPaymentAmount(ctx context.Context) error { + totalPaymentAmountUSD := decimal.NewFromInt(0) + for _, goodReq := range h.Goods { + price := h.goodPrices[*h.AppID+goodReq.GoodID] + units, err := decimal.NewFromString(goodReq.Units) + if err != nil { + return err + } + paymentAmountUSD := price.Mul(units) + totalPaymentAmountUSD = totalPaymentAmountUSD.Add(paymentAmountUSD) + h.goodValueUSDs[goodReq.GoodID] = paymentAmountUSD + + goodValueCoin := paymentAmountUSD.Div(h.coinCurrency) + goodValueCoin = getAccuracy(goodValueCoin) + h.paymentAmountCoin = h.paymentAmountCoin.Add(goodValueCoin) + h.goodValueCoins[goodReq.GoodID] = goodValueCoin + } + + logger.Sugar().Infow( + "CreateOrder", + "PaymentAmountUSD", totalPaymentAmountUSD, + "ReductionAmount", h.reductionAmount, + "ReductionPercent", h.reductionPercent, + ) + + discountAmountUSD := decimal.NewFromInt(0) + if h.reductionPercent != decimal.NewFromInt(0) { + discountAmountUSD = totalPaymentAmountUSD. + Mul(h.reductionPercent). + Div(decimal.NewFromInt(100)) //nolint + } + discountAmountUSD = discountAmountUSD.Add(h.reductionAmount) + + h.discountAmountCoin = discountAmountUSD.Div(h.coinCurrency) + h.discountAmountCoin = getAccuracy(h.discountAmountCoin) + + if *h.OrderType == ordertypes.OrderType_Airdrop { + h.paymentAmountCoin = decimal.NewFromInt(0) + } + + h.paymentAmountCoin = h.paymentAmountCoin.Sub(h.discountAmountCoin) + if h.paymentAmountCoin.Cmp(decimal.NewFromInt(0)) < 0 { + h.paymentAmountCoin = decimal.NewFromInt(0) + } + + h.paymentTransferAmount = h.paymentAmountCoin + if h.BalanceAmount != nil { + amount, err := decimal.NewFromString(*h.BalanceAmount) + if err != nil { + return err + } + if amount.Cmp(h.paymentTransferAmount) > 0 { + amount = h.paymentTransferAmount + amountStr := amount.String() + h.BalanceAmount = &amountStr + } + h.paymentTransferAmount = h.paymentTransferAmount.Sub(amount) + } + + return nil +} + +func (h *createHandler) paymentType() (*ordertypes.PaymentType, error) { + switch *h.OrderType { + case ordertypes.OrderType_Normal: + if h.BalanceAmount != nil { + if h.paymentTransferAmount.Cmp(decimal.NewFromInt(0)) > 0 { + return ordertypes.PaymentType_PayWithTransferAndBalance.Enum(), nil + } + return ordertypes.PaymentType_PayWithBalanceOnly.Enum(), nil + } + return ordertypes.PaymentType_PayWithTransferOnly.Enum(), nil + case ordertypes.OrderType_Offline: + return ordertypes.PaymentType_PayWithOffline.Enum(), nil + case ordertypes.OrderType_Airdrop: + return ordertypes.PaymentType_PayWithNoPayment.Enum(), nil + default: + return nil, fmt.Errorf("invalid ordertype") + } +} + +func (h *createHandler) SetPaymentType(ctx context.Context) error { + paymentType, err := h.paymentType() + if err != nil { + return err + } + h.mainPaymentType = paymentType + return nil +} + +func (h *createHandler) createAddresses(ctx context.Context) error { + const createCount = 5 + successCreated := 0 + + for i := 0; i < createCount; i++ { + address, err := sphinxproxycli.CreateAddress(ctx, h.paymentCoinName) + if err != nil { + return err + } + if address == nil || address.Address == "" { + return fmt.Errorf("invalid address") + } + + _, err = payaccmwcli.CreateAccount(ctx, &payaccmwpb.AccountReq{ + CoinTypeID: h.PaymentCoinID, + Address: &address.Address, + }) + if err != nil { + return err + } + + successCreated++ + } + + if successCreated == 0 { + return fmt.Errorf("fail create addresses") + } + + return nil +} + +func (h *createHandler) peekAddress(ctx context.Context) (*payaccmwpb.Account, error) { + payments, _, err := payaccmwcli.GetAccounts(ctx, &payaccmwpb.Conds{ + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, + Active: &basetypes.BoolVal{Op: cruder.EQ, Value: true}, + Locked: &basetypes.BoolVal{Op: cruder.EQ, Value: false}, + Blocked: &basetypes.BoolVal{Op: cruder.EQ, Value: false}, + AvailableAt: &basetypes.Uint32Val{Op: cruder.LTE, Value: uint32(time.Now().Unix())}, + }, 0, 5) //nolint + if err != nil { + return nil, err + } + + var account *payaccmwpb.Account + + for _, payment := range payments { + info, err := payaccmwcli.GetAccount(ctx, payment.ID) + if err != nil { + return nil, err + } + + if info.Locked || !info.Active || info.Blocked { + continue + } + + if info.AvailableAt > uint32(time.Now().Unix()) { + continue + } + account = info + break + } + + if account == nil { + return nil, nil + } + + h.paymentAccount = account + + return account, nil +} + +func (h *createHandler) withLockPaymentAccount(dispose *dtmcli.SagaDispose) { + switch *h.mainPaymentType { + case ordertypes.PaymentType_PayWithTransferOnly: + fallthrough //nolint + case ordertypes.PaymentType_PayWithTransferAndBalance: + fallthrough //nolint + case ordertypes.PaymentType_PayWithOffline: + locked := true + lockedBy := basetypes.AccountLockedBy_Payment + req := &payaccmwpb.AccountReq{ + ID: &h.paymentAccount.ID, + Locked: &locked, + LockedBy: &lockedBy, + } + dispose.Add( + ordermwsvcname.ServiceDomain, + "account.middleware.payment.v1.Middleware/UpdateAccount", + "", + &payaccmwpb.UpdateAccountRequest{ + Info: req, + }, + ) + } +} + +func (h *createHandler) PeekAddress(ctx context.Context) error { + account, err := h.peekAddress(ctx) + if err != nil { + return err + } + if account != nil { + h.paymentAccount = account + return nil + } + + if err := h.createAddresses(ctx); err != nil { + return err + } + + account, err = h.peekAddress(ctx) + if err != nil { + return err + } + if account == nil { + return fmt.Errorf("fail peek address") + } + + h.paymentAccount = account + return nil +} + +func (h *createHandler) SetAddressBalance(ctx context.Context) error { + balance, err := sphinxproxycli.GetBalance(ctx, &sphinxproxypb.GetBalanceRequest{ + Name: h.paymentCoinName, + Address: h.paymentAccount.Address, + }) + if err != nil { + return err + } + if balance == nil { + return fmt.Errorf("invalid balance") + } + + h.paymentAddressStartAmount, err = decimal.NewFromString(balance.BalanceStr) + return err +} + +func (h *createHandler) withUpdateStock(dispose *dtmcli.SagaDispose) { + for _, goodReq := range h.Goods { + req := &appgoodstockmwpb.StockReq{ + AppID: h.AppID, + GoodID: &goodReq.GoodID, + Locked: &goodReq.Units, + } + dispose.Add( + ordermwsvcname.ServiceDomain, + "good.middleware.app.good1.stock.v1.Middleware/AddStock", + "good.middleware.app.good1.stock.v1.Middleware/SubStock", + &appgoodstockmwpb.AddStockRequest{ + Info: req, + }, + ) + } +} + +func (h *createHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { + if h.BalanceAmount != nil { + return + } + req := &ledgermwpb.LedgerReq{ + AppID: h.AppID, + UserID: h.UserID, + CoinTypeID: &h.paymentAccount.CoinTypeID, + Spendable: h.BalanceAmount, + } + dispose.Add( + ordermwsvcname.ServiceDomain, + "ledger.middleware.ledger.v2.Middleware/SubBalance", + "ledger.middleware.ledger.v2.Middleware/AddBalance", + &ledgermwpb.AddBalanceRequest{ + Info: req, + }, + ) +} + +func (h *createHandler) orderReqs() []*ordermwpb.OrderReq { + paymentAmount := h.paymentAmountCoin.String() + startAmount := h.paymentAddressStartAmount.String() + paymentTransferAmount := h.paymentTransferAmount.String() + coinCurrency := h.coinCurrency.String() + liveCurrency := h.liveCurrency.String() + localCurrency := h.localCurrency.String() + discountAmountCoin := h.discountAmountCoin.String() + childPaymentType := ordertypes.PaymentType_PayWithParentOrder + zeroAmount := "0" + h.mainOrderID = uuid.NewString() + + orderReqs := []*ordermwpb.OrderReq{} + for _, goodReq := range h.Goods { + goodValue := h.goodValueCoins[goodReq.GoodID].String() + goodValueUSD := h.goodValueUSDs[goodReq.GoodID].String() + appgood := h.orderGood.appgoods[*h.AppID+goodReq.GoodID] + good := h.orderGood.goods[goodReq.GoodID] + goodDurationDays := uint32(good.DurationDays) + startAt := h.startAts[*h.AppID+goodReq.GoodID] + endAt := h.endAts[*h.AppID+goodReq.GoodID] + + logger.Sugar().Infow( + "CreateOrder", + "PaymentAmountCoin", h.paymentAmountCoin, + "DiscountAmountCoin", h.discountAmountCoin, + "BalanceAmount", h.BalanceAmount, + "ReductionAmount", h.reductionAmount, + "ReductionPercent", h.reductionPercent, + "PaymentAddressStartAmount", h.paymentAddressStartAmount, + "CoinCurrency", h.coinCurrency, + "LiveCurrency", h.liveCurrency, + "LocalCurrency", h.localCurrency, + ) + orderReq := &ordermwpb.OrderReq{ + AppID: h.AppID, + UserID: h.UserID, + GoodID: &goodReq.GoodID, + AppGoodID: &appgood.ID, + Units: &goodReq.Units, + GoodValue: &goodValue, + GoodValueUSD: &goodValueUSD, + DurationDays: &goodDurationDays, + OrderType: h.OrderType, + InvestmentType: h.InvestmentType, + CoinTypeID: &good.CoinTypeID, + PaymentCoinTypeID: h.PaymentCoinID, + CoinUSDCurrency: &coinCurrency, + LiveCoinUSDCurrency: &liveCurrency, + LocalCoinUSDCurrency: &localCurrency, + StartAt: &startAt, + EndAt: &endAt, + } + + if !goodReq.Parent && h.ParentOrderID == nil { + id := uuid.NewString() + // batch child order + orderReq.ID = &id + orderReq.ParentOrderID = &h.mainOrderID + orderReq.PaymentAmount = &zeroAmount + orderReq.DiscountAmount = &zeroAmount + orderReq.PaymentType = &childPaymentType + orderReq.TransferAmount = &zeroAmount + orderReq.BalanceAmount = &zeroAmount + h.IDs = append(h.IDs, id) + } else { + // parent order or single order + orderReq.ID = &h.mainOrderID + orderReq.ParentOrderID = h.ParentOrderID + orderReq.PaymentAmount = &paymentAmount + orderReq.DiscountAmount = &discountAmountCoin + orderReq.CouponIDs = h.CouponIDs + orderReq.PaymentType = h.mainPaymentType + orderReq.TransferAmount = &paymentTransferAmount + orderReq.BalanceAmount = h.BalanceAmount + orderReq.PaymentAccountID = &h.paymentAccount.AccountID + orderReq.PaymentStartAmount = &startAmount + h.IDs = append(h.IDs, h.mainOrderID) + } + + topmostGood := h.orderGood.topMostGoods[*h.AppID+goodReq.GoodID] + if topmostGood != nil { + orderReq.PromotionID = &topmostGood.TopMostID + } + orderReqs = append(orderReqs, orderReq) + } + return orderReqs +} + +func (h *createHandler) withCreateOrder(dispose *dtmcli.SagaDispose, req *ordermwpb.OrderReq) { + dispose.Add( + ordermwsvcname.ServiceDomain, + "order.middleware.order1.v1.Middleware/CreateOrder", + "order.middleware.order1.v1.Middleware/DeleteOrder", + &ordermwpb.CreateOrderRequest{ + Info: req, + }, + ) +} + +func (h *createHandler) withCreateOrders(dispose *dtmcli.SagaDispose, reqs []*ordermwpb.OrderReq) { + dispose.Add( + ordermwsvcname.ServiceDomain, + "order.middleware.order1.v1.Middleware/CreateOrders", + "order.middleware.order1.v1.Middleware/DeleteOrders", + &ordermwpb.CreateOrdersRequest{ + Infos: reqs, + }, + ) +} + +//nolint:funlen,gocyclo +func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error) { + // 1 Check input + // 1.1 Check user + // 1.2 Check app good + // 1.3 Check payment coin + // 1.4 Check parent order (by middleware && handler) + // 1.5 Check coupon ids (by handler) + // 1.6 Check balance (by dtm lock) + // 1.7 Check only one discount coupon + // 2 Calculate reduction + // 2.1 Calculate amount of discount coupon + // 2.2 Calculate amount of fix amount + // 3 Calculate price + // 3.1 Calculate USDT GoodValue - DiscountAmount + // 3.2 Get currency + // 3.3 Calculate payment coin amount + // 4 Peek address + // 4.1 Peek exist address + // 4.2 If fail, create addresses them peek one + // 4.3 Redis lock address + // 4.4 Recheck address lock + // DTM + // 5 Lock balance + // 6 Create order + // 7 Lock address + + handler := &createHandler{ + Handler: h, + } + if err := handler.getUser(ctx); err != nil { + return err + } + if err := handler.getPaymentCoin(ctx); err != nil { + return err + } + if err := handler.getCoupons(ctx); err != nil { + return err + } + if err := handler.validateDiscountCoupon(ctx); err != nil { + return err + } + if err := handler.calculateDiscountCouponReduction(); err != nil { + return err + } + if err := handler.calculateFixAmountCouponReduction(); err != nil { + return err + } + if err := handler.getAppGood(ctx); err != nil { + return err + } + if err := handler.calculateOrderUSDTPrice(ctx); err != nil { + return err + } + if err := handler.getPaymentCoinCurrency(ctx); err != nil { + return err + } + if err := handler.calculatePaymentCoinAmount(ctx); err != nil { + return err + } + if err := handler.peekExistAddress(ctx); err != nil { + if err := handler.peekNewAddress(ctx); err != nil { + return err + } + } + if err := accountlock.Lock(handler.paymentAccount.AccountID); err != nil { + return err + } + if err := handler.recheckPaymentAccount(ctx); err != nil { + return err + } + defer func() { + _ = accountlock.Unlock(handler.paymentAccount.AccountID) + }() + + id := uuid.NewString() + if h.ID == nil { + h.ID = &id + } + + const timeoutSeconds = 10 + sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ + WaitResult: true, + RequestTimeout: timeoutSeconds, + }) + + handler.withUpdateStock(sagaDispose) + handler.withUpdateBalance(sagaDispose) + handler.withCreateOrder(sagaDispose) + handler.withLockPaymentAccount(sagaDispose) + + if err := dtmcli.WithSaga(ctx, sagaDispose); err != nil { + return nil, err + } + + return h.GetOrder(ctx) +} + +//nolint:funlen,gocyclo +func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err error) { + orderGood, err := h.ToOrderGoods(ctx) + if err != nil { + return nil, err + } + handler := &createHandler{ + Handler: h, + orderGood: orderGood, + } + if err := handler.validateInit(ctx); err != nil { + return nil, err + } + + if err := handler.checkGoodRequests(); err != nil { + return nil, err + } + + if err := handler.SetReduction(ctx); err != nil { + return nil, err + } + + if err := handler.SetPrice(ctx); err != nil { + return nil, err + } + + if err := handler.SetCurrency(ctx); err != nil { + return nil, err + } + + if err := handler.SetPaymentAmount(ctx); err != nil { + return nil, err + } + + if err := handler.SetPaymentType(ctx); err != nil { + return nil, err + } + + switch *handler.mainPaymentType { + case ordertypes.PaymentType_PayWithTransferOnly: + fallthrough //nolint + case ordertypes.PaymentType_PayWithTransferAndBalance: + fallthrough //nolint + case ordertypes.PaymentType_PayWithOffline: + for i := 0; i < 5; i++ { + if err := handler.PeekAddress(ctx); err != nil { + return nil, err + } + if err := accountlock.Lock(handler.paymentAccount.AccountID); err != nil { + continue + } + break + } + defer func() { + accountlock.Unlock(handler.paymentAccount.AccountID) //nolint + }() + if err := handler.SetAddressBalance(ctx); err != nil { + return nil, err + } + } + + createReqs := handler.orderReqs() + lockKey := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, handler.mainOrderID) + if err := redis2.TryLock(lockKey, 0); err != nil { + return nil, err + } + defer func() { + _ = redis2.Unlock(lockKey) + }() + + sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ + WaitResult: true, + RequestTimeout: handler.RequestTimeoutSeconds, + }) + + handler.withUpdateStock(sagaDispose) + handler.withUpdateBalance(sagaDispose) + handler.withCreateOrders(sagaDispose, createReqs) + handler.withLockPaymentAccount(sagaDispose) + + if err := dtmcli.WithSaga(ctx, sagaDispose); err != nil { + return nil, err + } + + orders, _, err := h.GetOrders(ctx) + if err != nil { + return nil, err + } + + return orders, nil +} diff --git a/pkg/order/handler.go b/pkg/order/handler.go index 1c7466d..e4bb422 100644 --- a/pkg/order/handler.go +++ b/pkg/order/handler.go @@ -5,21 +5,24 @@ import ( "fmt" appmwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/app" - appusermwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" + appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" + cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" + basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" + ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" constant "github.com/NpoolPlatform/order-gateway/pkg/const" ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" - "github.com/shopspring/decimal" "github.com/google/uuid" + "github.com/shopspring/decimal" ) type Handler struct { ID *string AppID *string UserID *string - GoodID *string + AppGoodID *string Units string PaymentCoinID *string ParentOrderID *string @@ -29,12 +32,10 @@ type Handler struct { InvestmentType *ordertypes.InvestmentType UserSetCanceled *bool AdminSetCanceled *bool - FromAdmin bool PaymentID *string Offset int32 Limit int32 - Goods []*npool.CreateOrdersRequest_Good - IDs []string + Orders []*npool.CreateOrdersRequest_OrderReq RequestTimeoutSeconds int64 } @@ -72,9 +73,6 @@ func WithAppID(appID *string, must bool) func(context.Context, *Handler) error { } return nil } - if _, err := uuid.Parse(*appID); err != nil { - return err - } exist, err := appmwcli.ExistApp(ctx, *appID) if err != nil { return err @@ -87,9 +85,9 @@ func WithAppID(appID *string, must bool) func(context.Context, *Handler) error { } } -func WithUserID(appID, userID *string, must bool) func(context.Context, *Handler) error { +func WithUserID(userID *string, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { - if appID == nil || userID == nil { + if userID == nil { if must { return fmt.Errorf("invalid userid") } @@ -99,32 +97,27 @@ func WithUserID(appID, userID *string, must bool) func(context.Context, *Handler if err != nil { return err } - exist, err := appusermwcli.ExistUser(ctx, *appID, *userID) - if err != nil { - return err - } - if !exist { - return fmt.Errorf("invalid user") - } - h.UserID = userID return nil } } -func WithGoodID(id *string, must bool) func(context.Context, *Handler) error { +func WithAppGoodID(id *string, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { if id == nil { if must { - return fmt.Errorf("invalid goodid") + return fmt.Errorf("invalid appgoodid") } return nil } - _, err := uuid.Parse(*id) + exist, err := appgoodmwcli.ExistGood(ctx, *id) if err != nil { return err } - h.GoodID = id + if !exist { + return fmt.Errorf("invalid appgood") + } + h.AppGoodID = id return nil } } @@ -211,6 +204,15 @@ func WithCouponIDs(couponIDs []string, must bool) func(context.Context, *Handler return err } } + exist, err := ordermwcli.ExistOrderConds(ctx, &ordermwpb.Conds{ + CouponIDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: couponIDs}, + }) + if err != nil { + return err + } + if exist { + return fmt.Errorf("invalid couponids") + } h.CouponIDs = couponIDs return nil } @@ -260,12 +262,6 @@ func WithAdminSetCanceled(value *bool, must bool) func(context.Context, *Handler return nil } } -func WithFromAdmin(value bool) func(context.Context, *Handler) error { - return func(ctx context.Context, h *Handler) error { - h.FromAdmin = value - return nil - } -} func WithPaymentID(id *string, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { @@ -304,6 +300,13 @@ func WithOrderType(orderType *ordertypes.OrderType, must bool) func(context.Cont } } +func WithOrders(orders []*npool.CreateOrdersRequest_OrderReq, must bool) func(context.Context, *Handler) error { + return func(ctx context.Context, h *Handler) error { + h.Orders = orders + return nil + } +} + func WithOffset(offset int32) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { h.Offset = offset @@ -320,10 +323,3 @@ func WithLimit(limit int32) func(context.Context, *Handler) error { return nil } } - -func WithGoods(goods []*npool.CreateOrdersRequest_Good, must bool) func(context.Context, *Handler) error { - return func(ctx context.Context, h *Handler) error { - h.Goods = goods - return nil - } -} From 4fefdd909acdde94cf71510e15b41206faddd016 Mon Sep 17 00:00:00 2001 From: jakys Date: Tue, 5 Sep 2023 08:23:46 +0000 Subject: [PATCH 15/67] Refactor create --- api/order/create.go | 106 ++-- go.mod | 6 +- go.sum | 12 +- pkg/order/create.go | 300 ++++++++--- pkg/order/creates.go | 1079 ++++++++++++++++++++-------------------- pkg/order/handler.go | 36 +- pkg/order/ordergood.go | 180 ------- 7 files changed, 847 insertions(+), 872 deletions(-) delete mode 100644 pkg/order/ordergood.go diff --git a/api/order/create.go b/api/order/create.go index 3eea8ae..34ec10f 100644 --- a/api/order/create.go +++ b/api/order/create.go @@ -15,49 +15,41 @@ import ( "github.com/NpoolPlatform/go-service-framework/pkg/logger" ) -func createOrder(ctx context.Context, in *npool.CreateOrderRequest) (*npool.Order, error) { //nolint +func (s *Server) CreateOrder(ctx context.Context, in *npool.CreateOrderRequest) (*npool.CreateOrderResponse, error) { + orderType := ordertypes.OrderType_Normal handler, err := order1.NewHandler( ctx, order1.WithAppID(&in.AppID, true), - order1.WithUserID(&in.AppID, &in.UserID, true), - order1.WithGoodID(&in.GoodID, true), + order1.WithUserID(&in.UserID, true), + order1.WithAppGoodID(&in.AppGoodID, true), order1.WithUnits(in.Units, true), order1.WithPaymentCoinID(&in.PaymentCoinID, true), order1.WithParentOrderID(in.ParentOrderID, false), - order1.WithOrderType(&in.OrderType, true), + order1.WithOrderType(&orderType, true), order1.WithBalanceAmount(in.GetPayWithBalanceAmount(), false), order1.WithCouponIDs(in.CouponIDs, false), ) if err != nil { logger.Sugar().Errorw( - "createOrder", + "CreateOrder", "In", in, "Error", err, ) - return nil, status.Error(codes.InvalidArgument, err.Error()) + return &npool.CreateOrderResponse{}, status.Error(codes.InvalidArgument, err.Error()) } info, err := handler.CreateOrder(ctx) if err != nil { logger.Sugar().Errorw( - "createOrder", + "CreateOrder", "In", in, "Error", err, ) - return nil, status.Error(codes.Internal, err.Error()) + return &npool.CreateOrderResponse{}, status.Error(codes.Internal, err.Error()) } - return info, nil -} - -func (s *Server) CreateOrder(ctx context.Context, in *npool.CreateOrderRequest) (*npool.CreateOrderResponse, error) { - in.OrderType = ordertypes.OrderType_Normal - ord, err := createOrder(ctx, in) - if err != nil { - return &npool.CreateOrderResponse{}, err - } return &npool.CreateOrderResponse{ - Info: ord, + Info: info, }, nil } @@ -69,20 +61,37 @@ func (s *Server) CreateUserOrder(ctx context.Context, in *npool.CreateUserOrderR return &npool.CreateUserOrderResponse{}, status.Errorf(codes.InvalidArgument, "order type invalid") } - ord, err := createOrder(ctx, &npool.CreateOrderRequest{ - AppID: in.AppID, - UserID: in.TargetUserID, - GoodID: in.GoodID, - Units: in.Units, - PaymentCoinID: in.PaymentCoinID, - ParentOrderID: in.ParentOrderID, - OrderType: in.OrderType, - }) + handler, err := order1.NewHandler( + ctx, + order1.WithAppID(&in.AppID, true), + order1.WithUserID(&in.TargetUserID, true), + order1.WithAppGoodID(&in.AppGoodID, true), + order1.WithUnits(in.Units, true), + order1.WithPaymentCoinID(&in.PaymentCoinID, true), + order1.WithParentOrderID(in.ParentOrderID, false), + order1.WithOrderType(&in.OrderType, true), + ) + if err != nil { + logger.Sugar().Errorw( + "CreateUserOrder", + "In", in, + "Error", err, + ) + return &npool.CreateUserOrderResponse{}, status.Error(codes.InvalidArgument, err.Error()) + } + + info, err := handler.CreateOrder(ctx) if err != nil { - return &npool.CreateUserOrderResponse{}, err + logger.Sugar().Errorw( + "CreateUserOrder", + "In", in, + "Error", err, + ) + return &npool.CreateUserOrderResponse{}, status.Error(codes.Internal, err.Error()) } + return &npool.CreateUserOrderResponse{ - Info: ord, + Info: info, }, nil } @@ -94,19 +103,36 @@ func (s *Server) CreateAppUserOrder(ctx context.Context, in *npool.CreateAppUser return &npool.CreateAppUserOrderResponse{}, status.Errorf(codes.InvalidArgument, "order type invalid") } - ord, err := createOrder(ctx, &npool.CreateOrderRequest{ - AppID: in.TargetAppID, - UserID: in.TargetUserID, - GoodID: in.GoodID, - PaymentCoinID: in.PaymentCoinID, - Units: in.Units, - ParentOrderID: in.ParentOrderID, - OrderType: in.OrderType, - }) + handler, err := order1.NewHandler( + ctx, + order1.WithAppID(&in.TargetAppID, true), + order1.WithUserID(&in.TargetUserID, true), + order1.WithAppGoodID(&in.AppGoodID, true), + order1.WithUnits(in.Units, true), + order1.WithPaymentCoinID(&in.PaymentCoinID, true), + order1.WithParentOrderID(in.ParentOrderID, false), + order1.WithOrderType(&in.OrderType, true), + ) + if err != nil { + logger.Sugar().Errorw( + "CreateAppUserOrder", + "In", in, + "Error", err, + ) + return &npool.CreateAppUserOrderResponse{}, status.Error(codes.InvalidArgument, err.Error()) + } + + info, err := handler.CreateOrder(ctx) if err != nil { - return &npool.CreateAppUserOrderResponse{}, err + logger.Sugar().Errorw( + "CreateAppUserOrder", + "In", in, + "Error", err, + ) + return &npool.CreateAppUserOrderResponse{}, status.Error(codes.Internal, err.Error()) } + return &npool.CreateAppUserOrderResponse{ - Info: ord, + Info: info, }, nil } diff --git a/go.mod b/go.mod index 5c760c4..896f1c4 100644 --- a/go.mod +++ b/go.mod @@ -9,12 +9,12 @@ require ( github.com/NpoolPlatform/chain-middleware v0.0.0-20230712041523-2e1d215244e0 github.com/NpoolPlatform/dtm-cluster v0.0.0-20230518062456-3e53bebe90da github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e - github.com/NpoolPlatform/good-middleware v0.0.0-20230823034851-d6449a27f3e1 + github.com/NpoolPlatform/good-middleware v0.0.0-20230905075718-a4cefe1bff92 github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7 github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 - github.com/NpoolPlatform/message v0.0.0-20230904073655-1d217e96c6bb - github.com/NpoolPlatform/order-middleware v0.0.0-20230904074503-7a4d8ebbef6b + github.com/NpoolPlatform/message v0.0.0-20230905072308-dd83f725a380 + github.com/NpoolPlatform/order-middleware v0.0.0-20230905020518-f7a7139425b8 github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/dtm-labs/dtm v1.17.1 github.com/go-resty/resty/v2 v2.7.0 diff --git a/go.sum b/go.sum index 010682b..be29a64 100644 --- a/go.sum +++ b/go.sum @@ -60,18 +60,18 @@ github.com/NpoolPlatform/dtm-cluster v0.0.0-20230518062456-3e53bebe90da h1:ed2RL github.com/NpoolPlatform/dtm-cluster v0.0.0-20230518062456-3e53bebe90da/go.mod h1:I0UKoN/HU1p1RmpCYSramNbGCrd/EM7/fH6zhSUspkM= github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e h1:17BGexCmCdOOBXKYogP8RNE+pAHRu2N4LKq9znPJ4vc= github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e/go.mod h1:Kh7DMkWnYOMHxEKq7QfJqbxm1HaUPkhTNN74lfHQxyE= -github.com/NpoolPlatform/good-middleware v0.0.0-20230823034851-d6449a27f3e1 h1:mCP1H+uT1IrlQ+ijrMZsBvRgFUQ/gC5v3+q5HZeLW14= -github.com/NpoolPlatform/good-middleware v0.0.0-20230823034851-d6449a27f3e1/go.mod h1:m0iZ5NxrwNXbkpAvqA/cjWGpzQAc5bPGfcOsPgO7KiQ= +github.com/NpoolPlatform/good-middleware v0.0.0-20230905075718-a4cefe1bff92 h1:C0j0tYpVA+bTubq4QnYltvrdUSoMLAsI2ALBgj/Qgm8= +github.com/NpoolPlatform/good-middleware v0.0.0-20230905075718-a4cefe1bff92/go.mod h1:z9+HCHM/HDJG0fvDbrA3a2DrMXfYgXb/WN/+ezBJIJs= github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 h1:5W7RWU/meU1ZkPiUjqKAnyBKsjJ6NZu3dCfc0hgjhRs= github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2/go.mod h1:CCCI+S1AecMrRdRruOgMUxM9JaIXIYVt3DID04TuOoc= github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7 h1:ol3ynwtsKf5SdLMEMjLDcas1s51mDPmImDJ9ZXw1Iac= github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7/go.mod h1:lgAX07sFIVb9LnOJPCt9OMZRVLWqefnk+LBaSaCrWkM= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB4NuhQxXWeV0Z1qSxgIqbiMYU30dqFGDLtgNTqYbE= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= -github.com/NpoolPlatform/message v0.0.0-20230904073655-1d217e96c6bb h1:eoGrwFtjDwA4SrVGNcNRLL5nv+3s3j/JT0H3lrOhy1Q= -github.com/NpoolPlatform/message v0.0.0-20230904073655-1d217e96c6bb/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= -github.com/NpoolPlatform/order-middleware v0.0.0-20230904074503-7a4d8ebbef6b h1:/YT0PSdeeLZ0Xf/U1E2hx2ugHt970xiePLnV+3aNBlE= -github.com/NpoolPlatform/order-middleware v0.0.0-20230904074503-7a4d8ebbef6b/go.mod h1:W56fj2SCk8aRgmPMwUCa0qvz35l2pUEAX5Km5cR+Wl4= +github.com/NpoolPlatform/message v0.0.0-20230905072308-dd83f725a380 h1:PZfTh2RIj5EPVbiylo2sPCRP2H94GpG3zoHbsKNJ/wc= +github.com/NpoolPlatform/message v0.0.0-20230905072308-dd83f725a380/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/order-middleware v0.0.0-20230905020518-f7a7139425b8 h1:/9r/Ed8TPCOBdw3iqZ21TU0yxZtjuvyzJl92ztfTGU8= +github.com/NpoolPlatform/order-middleware v0.0.0-20230905020518-f7a7139425b8/go.mod h1:tJJvB9QFPn4NYWWsSorvJBc8ur9FlWNAEAM1wCuzPz8= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b/go.mod h1:9C9XDi7c0szxcLdJGDDFuo3/KtC74yWiyUM2fR+i0ww= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= diff --git a/pkg/order/create.go b/pkg/order/create.go index f5756fb..c23fe6b 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -7,21 +7,26 @@ import ( payaccmwcli "github.com/NpoolPlatform/account-middleware/pkg/client/payment" accountlock "github.com/NpoolPlatform/account-middleware/pkg/lock" + usermwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" appcoinmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/app/coin" - coininfocli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin" - currvalmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin/currency" + currencymwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin/currency" dtmcli "github.com/NpoolPlatform/dtm-cluster/pkg/dtm" - "github.com/NpoolPlatform/go-service-framework/pkg/logger" redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" + appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" + topmostmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/topmost/good" allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" payaccmwpb "github.com/NpoolPlatform/message/npool/account/mw/v1/payment" + usermwpb "github.com/NpoolPlatform/message/npool/appuser/mw/v1/user" + goodtypes "github.com/NpoolPlatform/message/npool/basetypes/good/v1" inspiretypes "github.com/NpoolPlatform/message/npool/basetypes/inspire/v1" - ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" + types "github.com/NpoolPlatform/message/npool/basetypes/order/v1" basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" appcoinmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/app/coin" - currvalmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin/currency" + currencymwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin/currency" + appgoodmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good" appgoodstockmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/stock" + topmostmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/topmost/good" allocatedmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/coupon/allocated" ledgermwpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger" npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" @@ -42,10 +47,9 @@ type createHandler struct { appGood *appgoodmwpb.Good paymentCoin *appcoinmwpb.Coin paymentAccount *payaccmwpb.Account - paymentStartAmount decimal.Decimal // TODO + paymentStartAmount decimal.Decimal coupons map[string]*allocatedmwpb.Coupon - currency *currencymwpb.Currency - promotion *topmostmwpb.TopMost + promotion *topmostmwpb.TopMostGood goodValueUSDTAmount decimal.Decimal goodValueCoinAmount decimal.Decimal paymentCoinAmount decimal.Decimal @@ -57,8 +61,9 @@ type createHandler struct { balanceCoinAmount decimal.Decimal transferCoinAmount decimal.Decimal paymentType types.PaymentType - orderStartAt uint32 // TODO - orderEndAt uint32 // TODO + orderStartMode types.OrderStartMode + orderStartAt uint32 + orderEndAt uint32 } func (h *createHandler) getUser(ctx context.Context) error { @@ -73,10 +78,10 @@ func (h *createHandler) getUser(ctx context.Context) error { return nil } -func (h *creatHandler) getPaymentCoin(ctx context.Context) error { +func (h *createHandler) getPaymentCoin(ctx context.Context) error { coin, err := appcoinmwcli.GetCoinOnly(ctx, &appcoinmwpb.Conds{ AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinTypeID}, + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, }) if err != nil { return err @@ -84,7 +89,7 @@ func (h *creatHandler) getPaymentCoin(ctx context.Context) error { if coin == nil { return fmt.Errorf("invalid paymentcoin") } - if coin.PreSale { + if coin.Presale { return fmt.Errorf("invalid paymentcoin") } if !coin.ForPay { @@ -114,7 +119,7 @@ func (h *createHandler) getCoupons(ctx context.Context) error { return nil } -func (h *creatHandler) validateDiscountCoupon() error { +func (h *createHandler) validateDiscountCoupon() error { discountCoupons := 0 for _, coupon := range h.coupons { if coupon.CouponType == inspiretypes.CouponType_Discount { @@ -127,6 +132,24 @@ func (h *creatHandler) validateDiscountCoupon() error { return nil } +//nolint:dupl +func (h *createHandler) checkMaxUnpaidOrders(ctx context.Context) error { + const maxUnpaidOrders = uint32(5) + orderCount, err := ordermwcli.CountOrders(ctx, &ordermwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + PaymentState: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(types.PaymentState_PaymentStateWait)}, + }) + if err != nil { + return err + } + if orderCount >= maxUnpaidOrders && *h.OrderType == types.OrderType_Normal { + return fmt.Errorf("too many unpaid orders") + } + + return nil +} + func (h *createHandler) getAppGood(ctx context.Context) error { good, err := appgoodmwcli.GetGood(ctx, *h.AppGoodID) if err != nil { @@ -139,12 +162,62 @@ func (h *createHandler) getAppGood(ctx context.Context) error { return nil } +func (h *createHandler) checkUnitsLimit(ctx context.Context) error { + if *h.OrderType != types.OrderType_Normal { + return nil + } + units, err := decimal.NewFromString(h.Units) + if err != nil { + return err + } + if h.appGood.PurchaseLimit > 0 && units.Cmp(decimal.NewFromInt32(h.appGood.PurchaseLimit)) > 0 { + return fmt.Errorf("too many units") + } + if !h.appGood.EnablePurchase { + return fmt.Errorf("app good is not enabled purchase") + } + purchaseCountStr, err := ordermwcli.SumOrderUnits( + ctx, + &ordermwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.appGood.GoodID}, + OrderStates: &basetypes.Uint32SliceVal{ + Op: cruder.IN, + Value: []uint32{ + uint32(types.OrderState_OrderStatePaid), + uint32(types.OrderState_OrderStateInService), + uint32(types.OrderState_OrderStateExpired), + uint32(types.OrderState_OrderStateWaitPayment), + }, + }, + }, + ) + if err != nil { + return err + } + purchaseCount, err := decimal.NewFromString(purchaseCountStr) + if err != nil { + return err + } + + userPurchaseLimit, err := decimal.NewFromString(h.appGood.UserPurchaseLimit) + if err != nil { + return err + } + + if userPurchaseLimit.Cmp(decimal.NewFromInt(0)) > 0 && purchaseCount.Add(units).Cmp(userPurchaseLimit) > 0 { + return fmt.Errorf("too many units") + } + + return nil +} + func (h *createHandler) getAppGoodPromotion(ctx context.Context) error { - promotion, err := topmostmwcli.GetTopMostOnly(ctx, &topmostmwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - AppGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppGoodID}, - // TODO: Add topmost type of promotion - // TODO: One good is added to multiple topmost + promotion, err := topmostmwcli.GetTopMostGoodOnly(ctx, &topmostmwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + AppGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppGoodID}, + TopMostType: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(goodtypes.GoodTopMostType_TopMostPromotion)}, }) if err != nil { return err @@ -154,7 +227,7 @@ func (h *createHandler) getAppGoodPromotion(ctx context.Context) error { } func (h *createHandler) calculateOrderUSDTPrice() error { - units, err := decimal.NewFromString(*h.Units) + units, err := decimal.NewFromString(h.Units) if err != nil { return err } @@ -166,7 +239,7 @@ func (h *createHandler) calculateOrderUSDTPrice() error { return fmt.Errorf("invalid price") } if h.promotion == nil { - h.paymentUSDTAmount = amount.Mul(units) + h.goodValueUSDTAmount = amount.Mul(units) return nil } amount, err = decimal.NewFromString(h.promotion.Price) @@ -176,7 +249,7 @@ func (h *createHandler) calculateOrderUSDTPrice() error { if amount.Cmp(decimal.NewFromInt(0)) <= 0 { return fmt.Errorf("invalid price") } - h.paymentUSDTAmount = amount.Mul(units) + h.goodValueUSDTAmount = amount.Mul(units) return nil } @@ -188,10 +261,10 @@ func (h *createHandler) calculateDiscountCouponReduction() error { return err } h.reductionUSDTAmount = h.reductionUSDTAmount. - Add(h.paymentUSDTAmount.Mul(discount).Div(decimal.NewFromInt(100))) //nolint - return nil + Add(h.goodValueUSDTAmount.Mul(discount).Div(decimal.NewFromInt(100))) //nolint } } + return nil } func (h *createHandler) calculateFixAmountCouponReduction() error { @@ -210,6 +283,7 @@ func (h *createHandler) calculateFixAmountCouponReduction() error { return nil } +//nolint:dupl func (h *createHandler) checkPaymentCoinCurrency(ctx context.Context) error { currency, err := currencymwcli.GetCurrencyOnly(ctx, ¤cymwpb.Conds{ CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: h.paymentCoin.CoinTypeID}, @@ -240,7 +314,7 @@ func (h *createHandler) checkPaymentCoinCurrency(ctx context.Context) error { return err } if amount.Cmp(decimal.NewFromInt(0)) > 0 { - h.coinCurrency = amount + h.coinCurrencyAmount = amount } amount, err = decimal.NewFromString(h.paymentCoin.MarketValue) @@ -248,24 +322,35 @@ func (h *createHandler) checkPaymentCoinCurrency(ctx context.Context) error { return err } if amount.Cmp(decimal.NewFromInt(0)) > 0 { - h.localCurrency = amount + h.localCurrencyAmount = amount } return nil } +func (h *createHandler) getAccuracy(amount decimal.Decimal) decimal.Decimal { + const accuracy = 1000000 + amount = amount.Mul(decimal.NewFromInt(accuracy)) + amount = amount.Ceil() + amount = amount.Div(decimal.NewFromInt(accuracy)) + return amount +} + func (h *createHandler) checkPaymentCoinAmount() error { amount := h.goodValueUSDTAmount. Sub(h.reductionUSDTAmount). - Div(h.coinCurrency) + Div(h.coinCurrencyAmount) if amount.Cmp(decimal.NewFromInt(0)) <= 0 { return fmt.Errorf("invalid price") } - h.paymentCoinAmount = amount - h.goodValueCoinAmount = h.goodValueUSDTAmount.Div(h.coinCurrency) - h.reductionCoinAmount = h.reductionUSDTAmount.Div(h.coinCurrency) + h.paymentCoinAmount = h.getAccuracy(amount) + h.goodValueCoinAmount = h.goodValueUSDTAmount.Div(h.coinCurrencyAmount) + h.goodValueCoinAmount = h.getAccuracy(h.goodValueCoinAmount) + h.reductionCoinAmount = h.reductionUSDTAmount.Div(h.coinCurrencyAmount) + h.reductionCoinAmount = h.getAccuracy(h.reductionCoinAmount) return nil } +//nolint:dupl func (h *createHandler) checkTransferCoinAmount() error { if h.BalanceAmount == nil { h.transferCoinAmount = h.paymentCoinAmount @@ -289,44 +374,53 @@ func (h *createHandler) checkTransferCoinAmount() error { } func (h *createHandler) resolvePaymentType() { - if h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 && + if h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 && //nolint h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 { - h.paymentType = types.PaymentType_PaymentTypeNoPayment + h.paymentType = types.PaymentType_PayWithNoPayment return } if h.transferCoinAmount.Cmp(h.paymentCoinAmount) == 0 { - h.paymentType = types.PaymentType_PaymentTypeTransferOnly + h.paymentType = types.PaymentType_PayWithTransferOnly return } if h.balanceCoinAmount.Cmp(h.paymentCoinAmount) == 0 { - h.paymentType = types.PaymentType_PaymentTypeBalanceOnly + h.paymentType = types.PaymentType_PayWithBalanceOnly return } - h.paymentType = types.PaymentType_PaymentTypeTransferAndBalance + h.paymentType = types.PaymentType_PayWithTransferAndBalance } +func (h *createHandler) resolveStartMode() { + if h.appGood.StartMode == goodtypes.GoodStartMode_GoodStartModeTBD { + h.orderStartMode = types.OrderStartMode_OrderStartTBD + return + } + h.orderStartMode = types.OrderStartMode_OrderStartConfirmed +} + +//nolint:dupl func (h *createHandler) peekExistAddress(ctx context.Context) (*payaccmwpb.Account, error) { const batchAccounts = int32(5) - accounts, _, err := payaccmwcli.GetAccounts(ctx, &payaccmwcli.Conds{ - CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: h.PaymentCoin.CoinTypeID}, + accounts, _, err := payaccmwcli.GetAccounts(ctx, &payaccmwpb.Conds{ + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: h.paymentCoin.CoinTypeID}, Active: &basetypes.BoolVal{Op: cruder.EQ, Value: true}, Locked: &basetypes.BoolVal{Op: cruder.EQ, Value: false}, Blocked: &basetypes.BoolVal{Op: cruder.EQ, Value: false}, AvailableAt: &basetypes.Uint32Val{Op: cruder.LTE, Value: uint32(time.Now().Unix())}, }, int32(0), batchAccounts) if err != nil { - return err + return nil, err } for _, account := range accounts { - if info.Locked || !info.Active || info.Blocked { + if account.Locked || !account.Active || account.Blocked { continue } - if info.AvailableAt > uint32(time.Now().Unix()) { + if account.AvailableAt > uint32(time.Now().Unix()) { continue } - return account + return account, nil } - return nil + return nil, fmt.Errorf("invalid address") } func (h *createHandler) peekNewAddress(ctx context.Context) (*payaccmwpb.Account, error) { @@ -336,22 +430,22 @@ func (h *createHandler) peekNewAddress(ctx context.Context) (*payaccmwpb.Account for i := 0; i < createCount; i++ { address, err := sphinxproxycli.CreateAddress(ctx, h.paymentCoin.CoinName) if err != nil { - return err + return nil, err } if address == nil || address.Address == "" { - return fmt.Errorf("invalid address") + return nil, fmt.Errorf("invalid address") } _, err = payaccmwcli.CreateAccount(ctx, &payaccmwpb.AccountReq{ - CoinTypeID: h.paymentCoin.CoinTypeID, + CoinTypeID: &h.paymentCoin.CoinTypeID, Address: &address.Address, }) if err != nil { - return err + return nil, err } successCreated++ } if successCreated == 0 { - return fmt.Errorf("fail create addresses") + return nil, fmt.Errorf("fail create addresses") } return h.peekExistAddress(ctx) @@ -359,15 +453,15 @@ func (h *createHandler) peekNewAddress(ctx context.Context) (*payaccmwpb.Account func (h *createHandler) peekPaymentAddress(ctx context.Context) error { switch h.paymentType { - case types.PaymentType_PaymentTypeBalanceOnly: + case types.PaymentType_PayWithBalanceOnly: fallthrough //nolint - case types.PaymentType_PaymentTypeNoPayment: + case types.PaymentType_PayWithNoPayment: return nil } - account, err := handler.peekExistAddress(ctx) + account, err := h.peekExistAddress(ctx) if err != nil { - account, err = handler.peekNewAddress(ctx) + account, err = h.peekNewAddress(ctx) if err != nil { return err } @@ -393,10 +487,26 @@ func (h *createHandler) recheckPaymentAccount(ctx context.Context) error { return nil } +func (h *createHandler) getPaymentStartAmount(ctx context.Context) error { + balance, err := sphinxproxycli.GetBalance(ctx, &sphinxproxypb.GetBalanceRequest{ + Name: h.paymentCoin.CoinName, + Address: h.paymentAccount.Address, + }) + if err != nil { + return err + } + if balance == nil { + return fmt.Errorf("invalid balance") + } + + h.paymentStartAmount, err = decimal.NewFromString(balance.BalanceStr) + return err +} + func (h *createHandler) withUpdateStock(dispose *dtmcli.SagaDispose) { req := &appgoodstockmwpb.StockReq{ AppGoodID: h.AppGoodID, - Locked: h.Units, + Locked: &h.Units, } dispose.Add( ordermwsvcname.ServiceDomain, @@ -417,7 +527,7 @@ func (h *createHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { req := &ledgermwpb.LedgerReq{ AppID: h.AppID, UserID: h.UserID, - CoinTypeID: h.PaymentCoinTypeID, + CoinTypeID: h.PaymentCoinID, Spendable: &amount, } dispose.Add( @@ -430,6 +540,12 @@ func (h *createHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { ) } +func (h *createHandler) tomorrowStart() time.Time { + now := time.Now() + y, m, d := now.Date() + return time.Date(y, m, d+1, 0, 0, 0, 0, now.Location()) +} + func (h *createHandler) withCreateOrder(dispose *dtmcli.SagaDispose) { goodValueCoinAmount := h.goodValueCoinAmount.String() goodValueUSDTAmount := h.goodValueUSDTAmount.String() @@ -437,29 +553,41 @@ func (h *createHandler) withCreateOrder(dispose *dtmcli.SagaDispose) { discountCoinAmount := h.reductionCoinAmount.String() transferCoinAmount := h.transferCoinAmount.String() balanceCoinAmount := h.balanceCoinAmount.String() - coinUSDCurrency := h.coinCurrency.String() - localCoinUSDCurrency := h.localCurrency.String() - liveCoinUSDCurrency := h.liveCurrency.String() + coinUSDCurrency := h.coinCurrencyAmount.String() + localCoinUSDCurrency := h.localCurrencyAmount.String() + liveCoinUSDCurrency := h.liveCurrencyAmount.String() + + goodStartAt := h.appGood.ServiceStartAt + if h.appGood.ServiceStartAt == 0 { + goodStartAt = h.appGood.StartAt + } + goodDurationDays := uint32(h.appGood.DurationDays) + h.orderStartAt = uint32(h.tomorrowStart().Unix()) + if goodStartAt > h.orderStartAt { + h.orderStartAt = goodStartAt + } + const secondsPerDay = 24 * 60 * 60 + h.orderEndAt = h.orderStartAt + goodDurationDays*secondsPerDay req := &ordermwpb.OrderReq{ ID: h.ID, AppID: h.AppID, UserID: h.UserID, - GoodID: h.GoodID, + GoodID: &h.appGood.GoodID, AppGoodID: h.AppGoodID, ParentOrderID: h.ParentOrderID, - Units: h.Units, + Units: &h.Units, GoodValue: &goodValueCoinAmount, GoodValueUSD: &goodValueUSDTAmount, PaymentAmount: &paymentCoinAmount, DiscountAmount: &discountCoinAmount, - DurationDays: &h.appGood.DurationDays, + DurationDays: &goodDurationDays, OrderType: h.OrderType, InvestmentType: h.InvestmentType, CouponIDs: h.CouponIDs, PaymentType: &h.paymentType, CoinTypeID: &h.appGood.CoinTypeID, - PaymentCoinTypeID: h.PaymentCoinTypeID, + PaymentCoinTypeID: h.PaymentCoinID, TransferAmount: &transferCoinAmount, BalanceAmount: &balanceCoinAmount, CoinUSDCurrency: &coinUSDCurrency, @@ -467,7 +595,7 @@ func (h *createHandler) withCreateOrder(dispose *dtmcli.SagaDispose) { LiveCoinUSDCurrency: &liveCoinUSDCurrency, StartAt: &h.orderStartAt, EndAt: &h.orderEndAt, - StartMode: &h.appGood.StartMode, + StartMode: &h.orderStartMode, } if h.promotion != nil { req.PromotionID = &h.promotion.ID @@ -509,6 +637,7 @@ func (h *createHandler) withLockPaymentAccount(dispose *dtmcli.SagaDispose) { ) } +//nolint:funlen,gocyclo func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error) { // 1 Check input // 1.1 Check user @@ -518,6 +647,7 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error // 1.5 Check coupon ids (by handler) // 1.6 Check balance (by dtm lock) // 1.7 Check only one discount coupon + // 1.8 Check max unpaid orders // 2 Calculate reduction // 2.1 Calculate amount of discount coupon // 2.2 Calculate amount of fix amount @@ -543,56 +673,66 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error Handler: h, } if err := handler.getUser(ctx); err != nil { - return err + return nil, err } - if err := handler.checkPaymentCoin(ctx); err != nil { - return err + if err := handler.getPaymentCoin(ctx); err != nil { + return nil, err } if err := handler.getCoupons(ctx); err != nil { - return err + return nil, err } - if err := handler.validateDiscountCoupon(ctx); err != nil { - return err + if err := handler.validateDiscountCoupon(); err != nil { + return nil, err + } + if err := handler.checkMaxUnpaidOrders(ctx); err != nil { + return nil, err } if err := handler.getAppGood(ctx); err != nil { - return err + return nil, err + } + if err := handler.checkUnitsLimit(ctx); err != nil { + return nil, err } if err := handler.getAppGoodPromotion(ctx); err != nil { - return err + return nil, err } - if err := handler.calculateOrderUSDTPrice(ctx); err != nil { - return err + if err := handler.calculateOrderUSDTPrice(); err != nil { + return nil, err } if err := handler.calculateDiscountCouponReduction(); err != nil { - return err + return nil, err } if err := handler.calculateFixAmountCouponReduction(); err != nil { - return err + return nil, err } if err := handler.checkPaymentCoinCurrency(ctx); err != nil { - return err + return nil, err } if err := handler.checkPaymentCoinAmount(); err != nil { - return err + return nil, err } if err := handler.checkTransferCoinAmount(); err != nil { - return err + return nil, err } handler.resolvePaymentType() + handler.resolveStartMode() if err := handler.peekPaymentAddress(ctx); err != nil { - return err + return nil, err } if handler.paymentAccount != nil { if err := accountlock.Lock(handler.paymentAccount.AccountID); err != nil { - return err + return nil, err } if err := handler.recheckPaymentAccount(ctx); err != nil { - return err + return nil, err } defer func() { _ = accountlock.Unlock(handler.paymentAccount.AccountID) }() + if err := handler.getPaymentStartAmount(ctx); err != nil { + return nil, err + } } id := uuid.NewString() @@ -602,7 +742,7 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error key := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, id) if err := redis2.TryLock(key, 0); err != nil { - return err + return nil, err } defer func() { _ = redis2.Unlock(key) diff --git a/pkg/order/creates.go b/pkg/order/creates.go index 22fadca..3942263 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -7,21 +7,28 @@ import ( payaccmwcli "github.com/NpoolPlatform/account-middleware/pkg/client/payment" accountlock "github.com/NpoolPlatform/account-middleware/pkg/lock" + usermwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" appcoinmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/app/coin" - coininfocli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin" - currvalmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin/currency" + currencymwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin/currency" dtmcli "github.com/NpoolPlatform/dtm-cluster/pkg/dtm" - "github.com/NpoolPlatform/go-service-framework/pkg/logger" redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" + appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" + topmostmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/topmost/good" + goodrequiredmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good/required" allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" payaccmwpb "github.com/NpoolPlatform/message/npool/account/mw/v1/payment" + usermwpb "github.com/NpoolPlatform/message/npool/appuser/mw/v1/user" + goodtypes "github.com/NpoolPlatform/message/npool/basetypes/good/v1" inspiretypes "github.com/NpoolPlatform/message/npool/basetypes/inspire/v1" - ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" + types "github.com/NpoolPlatform/message/npool/basetypes/order/v1" basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" appcoinmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/app/coin" - currvalmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin/currency" + currencymwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin/currency" + appgoodmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good" appgoodstockmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/stock" + topmostmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/topmost/good" + goodrequiredpb "github.com/NpoolPlatform/message/npool/good/mw/v1/good/required" allocatedmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/coupon/allocated" ledgermwpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger" npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" @@ -36,466 +43,481 @@ import ( "github.com/shopspring/decimal" ) -type createHandler struct { +type createsHandler struct { *Handler - user *usermwpb.User - appGood []*appgoodmwpb.Good - paymentAccount *payaccmwpb.Account - coupons []*inspiremwpb.Coupon - currency *currencymwpb.Currency + mainOrderID *string + ids map[string]*string + user *usermwpb.User + appGoods map[string]*appgoodmwpb.Good + goodRequireds []*goodrequiredpb.Required + paymentCoin *appcoinmwpb.Coin + paymentAccount *payaccmwpb.Account + paymentStartAmount decimal.Decimal + coupons map[string]*allocatedmwpb.Coupon + promotions map[string]*topmostmwpb.TopMostGood + paymentUSDTAmount decimal.Decimal + goodValueUSDTAmount map[string]decimal.Decimal + goodValueCoinAmount map[string]decimal.Decimal + paymentCoinAmount decimal.Decimal + reductionUSDTAmount decimal.Decimal + reductionCoinAmount decimal.Decimal + liveCurrencyAmount decimal.Decimal + coinCurrencyAmount decimal.Decimal + localCurrencyAmount decimal.Decimal + balanceCoinAmount decimal.Decimal + transferCoinAmount decimal.Decimal + paymentType types.PaymentType + orderStartMode map[string]types.OrderStartMode + goodDurationDays map[string]uint32 + orderStartAt map[string]uint32 + orderEndAt map[string]uint32 } -func tomorrowStart() time.Time { +func (h *createsHandler) tomorrowStart() time.Time { now := time.Now() y, m, d := now.Date() return time.Date(y, m, d+1, 0, 0, 0, 0, now.Location()) } -func (h *createHandler) validateInit(ctx context.Context) error { - coin, err := coininfocli.GetCoin(ctx, *h.PaymentCoinID) +func (h *createsHandler) getUser(ctx context.Context) error { + user, err := usermwcli.GetUser(ctx, *h.AppID, *h.UserID) + if err != nil { + return err + } + if user == nil { + return fmt.Errorf("invalid user") + } + h.user = user + return nil +} + +func (h *createsHandler) getPaymentCoin(ctx context.Context) error { + coin, err := appcoinmwcli.GetCoinOnly(ctx, &appcoinmwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, + }) if err != nil { return err } if coin == nil { - return fmt.Errorf("invalid coin") + return fmt.Errorf("invalid paymentcoin") } if coin.Presale { - return fmt.Errorf("presale coin won't for payment") + return fmt.Errorf("invalid paymentcoin") } if !coin.ForPay { - return fmt.Errorf("coin not for payment") + return fmt.Errorf("invalid paymentcoin") } - h.paymentCoinName = coin.Name + h.paymentCoin = coin + return nil +} - for _, goodReq := range h.Goods { - good := h.orderGood.goods[goodReq.GoodID] - gcoin, err := coininfocli.GetCoin(ctx, good.CoinTypeID) - if err != nil { - return err - } - if gcoin == nil { - return fmt.Errorf("invalid good coin") - } - if coin.ENV != gcoin.ENV { - return fmt.Errorf("good coin mismatch payment coin") +func (h *createsHandler) getCoupons(ctx context.Context) error { + coupons, _, err := allocatedmwcli.GetCoupons(ctx, &allocatedmwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: h.CouponIDs}, + }, int32(0), int32(len(h.CouponIDs))) + if err != nil { + return err + } + if len(coupons) < len(h.CouponIDs) { + return fmt.Errorf("invalid coupon") + } + for _, coupon := range coupons { + if !coupon.Valid || coupon.Expired { + return fmt.Errorf("invalid coupon") } + h.coupons[coupon.ID] = coupon + } + return nil +} - appgood := h.orderGood.appgoods[*h.AppID+*h.GoodID] - goodStartAt := appgood.ServiceStartAt - if appgood.ServiceStartAt == 0 { - goodStartAt = good.StartAt - } - goodDurationDays := uint32(good.DurationDays) - startAt := uint32(tomorrowStart().Unix()) - if goodStartAt > startAt { - startAt = goodStartAt +func (h *createsHandler) validateDiscountCoupon() error { + discountCoupons := 0 + for _, coupon := range h.coupons { + if coupon.CouponType == inspiretypes.CouponType_Discount { + discountCoupons++ } - const secondsPerDay = 24 * 60 * 60 - endAt := startAt + goodDurationDays*secondsPerDay - h.startAts[*h.AppID+goodReq.GoodID] = startAt - h.endAts[*h.AppID+goodReq.GoodID] = endAt } + if discountCoupons > 1 { + return fmt.Errorf("invalid discountcoupon") + } + return nil +} - const maxUnpaidOrders = 5 - orders, _, err := ordermwcli.GetOrders(ctx, &ordermwpb.Conds{ +//nolint:dupl +func (h *createsHandler) checkMaxUnpaidOrders(ctx context.Context) error { + const maxUnpaidOrders = uint32(5) + orderCount, err := ordermwcli.CountOrders(ctx, &ordermwpb.Conds{ AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, - PaymentState: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(ordertypes.PaymentState_PaymentStateWait)}, - }, 0, maxUnpaidOrders) + PaymentState: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(types.PaymentState_PaymentStateWait)}, + }) if err != nil { return err } - if len(orders) >= maxUnpaidOrders && *h.OrderType == ordertypes.OrderType_Normal { + if orderCount >= maxUnpaidOrders && *h.OrderType == types.OrderType_Normal { return fmt.Errorf("too many unpaid orders") } + return nil +} +func (h *createsHandler) getAppGoods(ctx context.Context) error { + for _, order := range h.Orders { + good, err := appgoodmwcli.GetGood(ctx, order.AppGoodID) + if err != nil { + return err + } + if good == nil { + return fmt.Errorf("invalid good") + } + h.appGoods[order.AppGoodID] = good + } return nil } -func (h *createHandler) checkGoodRequests() error { - goodRequiredSet := make(map[string]struct{}) - goodSet := make(map[string]struct{}) - for _, goodRequired := range h.orderGood.goodRequireds { - goodRequiredSet[goodRequired.RequiredGoodID] = struct{}{} +func (h *createsHandler) checkUnitsLimit(ctx context.Context) error { + if *h.OrderType != types.OrderType_Normal { + return nil } + for _, order := range h.Orders { + appGood := h.appGoods[order.AppGoodID] + units, err := decimal.NewFromString(h.Units) + if err != nil { + return err + } + if appGood.PurchaseLimit > 0 && units.Cmp(decimal.NewFromInt32(appGood.PurchaseLimit)) > 0 { + return fmt.Errorf("too many units") + } + if !appGood.EnablePurchase { + return fmt.Errorf("app good is not enabled purchase") + } + purchaseCountStr, err := ordermwcli.SumOrderUnits( + ctx, + &ordermwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: appGood.GoodID}, + OrderStates: &basetypes.Uint32SliceVal{ + Op: cruder.IN, + Value: []uint32{ + uint32(types.OrderState_OrderStatePaid), + uint32(types.OrderState_OrderStateInService), + uint32(types.OrderState_OrderStateExpired), + uint32(types.OrderState_OrderStateWaitPayment), + }, + }, + }, + ) + if err != nil { + return err + } + purchaseCount, err := decimal.NewFromString(purchaseCountStr) + if err != nil { + return err + } - for _, goodReq := range h.Goods { - if !goodReq.Parent { - if _, ok := goodRequiredSet[goodReq.GoodID]; !ok { - return fmt.Errorf("invalid goodrequired") - } - goodSet[goodReq.GoodID] = struct{}{} + userPurchaseLimit, err := decimal.NewFromString(appGood.UserPurchaseLimit) + if err != nil { + return err } - } - for _, goodRequired := range h.orderGood.goodRequireds { - if goodRequired.Must { - if _, ok := goodSet[goodRequired.RequiredGoodID]; !ok { - return fmt.Errorf("invalid goodrequired must") - } + if userPurchaseLimit.Cmp(decimal.NewFromInt(0)) > 0 && purchaseCount.Add(units).Cmp(userPurchaseLimit) > 0 { + return fmt.Errorf("too many units") } } return nil } -// nolint -func (h *createHandler) SetReduction(ctx context.Context) error { - if len(h.CouponIDs) == 0 { - return nil +func (h *createsHandler) getAppGoodPromotions(ctx context.Context) error { + for _, order := range h.Orders { + promotion, err := topmostmwcli.GetTopMostGoodOnly(ctx, &topmostmwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + AppGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: order.AppGoodID}, + TopMostType: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(goodtypes.GoodTopMostType_TopMostPromotion)}, + }) + if err != nil { + return err + } + h.promotions[order.AppGoodID] = promotion } + return nil +} - coupons, _, err := allocatedmwcli.GetCoupons(ctx, &allocatedmwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, - IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: h.CouponIDs}, - }, int32(0), int32(len(h.CouponIDs))) - if err != nil { - return err - } - if len(coupons) != len(h.CouponIDs) { - return fmt.Errorf("invalid coupon") - } +func (h *createsHandler) getAccuracy(amount decimal.Decimal) decimal.Decimal { + const accuracy = 1000000 + amount = amount.Mul(decimal.NewFromInt(accuracy)) + amount = amount.Ceil() + amount = amount.Div(decimal.NewFromInt(accuracy)) + return amount +} - couponTypeDiscountNum := 0 - for _, coup := range coupons { - if !coup.Valid || coup.Expired || coup.AppID != *h.AppID || coup.UserID != *h.UserID { - return fmt.Errorf("invalid coupon") +func (h *createsHandler) calculateOrderUSDTPrice() error { + for _, order := range h.Orders { + appGood := h.appGoods[order.AppGoodID] + units, err := decimal.NewFromString(order.Units) + if err != nil { + return err } - switch coup.CouponType { - case inspiretypes.CouponType_FixAmount: - fallthrough //nolint - case inspiretypes.CouponType_SpecialOffer: - amount, err := decimal.NewFromString(coup.Denomination) - if err != nil { - return err - } - h.reductionAmount = h.reductionAmount.Add(amount) - case inspiretypes.CouponType_Discount: - if couponTypeDiscountNum > 1 { - return fmt.Errorf("invalid discount") - } - percent, err := decimal.NewFromString(coup.Denomination) - if err != nil { - return err - } - if percent.Cmp(decimal.NewFromInt(100)) >= 0 { - return fmt.Errorf("invalid discount") - } - h.reductionPercent = percent - couponTypeDiscountNum++ - default: - return fmt.Errorf("unknown coupon type") + amount, err := decimal.NewFromString(appGood.Price) + if err != nil { + return err + } + if amount.Cmp(decimal.NewFromInt(0)) <= 0 { + return fmt.Errorf("invalid price") + } + promotion := h.promotions[order.AppGoodID] + if promotion == nil { + h.goodValueUSDTAmount[order.AppGoodID] = amount.Mul(units) + h.paymentUSDTAmount = h.paymentUSDTAmount.Add(h.goodValueUSDTAmount[order.AppGoodID]) + return nil + } + amount, err = decimal.NewFromString(promotion.Price) + if err != nil { + return err + } + if amount.Cmp(decimal.NewFromInt(0)) <= 0 { + return fmt.Errorf("invalid price") } + h.goodValueUSDTAmount[order.AppGoodID] = amount.Mul(units) + h.goodValueCoinAmount[order.AppGoodID] = h.goodValueUSDTAmount[order.AppGoodID].Div(h.coinCurrencyAmount) + h.goodValueCoinAmount[order.AppGoodID] = h.getAccuracy(h.goodValueCoinAmount[order.AppGoodID]) + h.paymentUSDTAmount = h.paymentUSDTAmount.Add(h.goodValueUSDTAmount[order.AppGoodID]) } return nil } -func (h *createHandler) SetPrice(ctx context.Context) error { - for _, goodReq := range h.Goods { - appgood := h.orderGood.appgoods[*h.AppID+goodReq.GoodID] - topmostGood := h.orderGood.topMostGoods[*h.AppID+goodReq.GoodID] - price, err := decimal.NewFromString(appgood.Price) - if err != nil { - return err +func (h *createsHandler) calculateDiscountCouponReduction() error { + for _, coupon := range h.coupons { + if coupon.CouponType == inspiretypes.CouponType_Discount { + discount, err := decimal.NewFromString(coupon.Denomination) + if err != nil { + return err + } + h.reductionUSDTAmount = h.reductionUSDTAmount. + Add(h.paymentUSDTAmount.Mul(discount).Div(decimal.NewFromInt(100))) //nolint } + } + return nil +} - if topmostGood != nil { - promotionPrice, err := decimal.NewFromString(topmostGood.GetPrice()) +func (h *createsHandler) calculateFixAmountCouponReduction() error { + for _, coupon := range h.coupons { + switch coupon.CouponType { + case inspiretypes.CouponType_FixAmount: + fallthrough //nolint + case inspiretypes.CouponType_SpecialOffer: + amount, err := decimal.NewFromString(coupon.Denomination) if err != nil { return err } - if promotionPrice.Cmp(decimal.NewFromInt(0)) <= 0 { - return fmt.Errorf("invalid price") - } - price = promotionPrice + h.reductionUSDTAmount = h.reductionUSDTAmount.Add(amount) } - h.goodPrices[*h.AppID+goodReq.GoodID] = price } - return nil } -func (h *createHandler) SetCurrency(ctx context.Context) error { - curr, err := currvalmwcli.GetCurrencyOnly(ctx, &currvalmwpb.Conds{ - CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, +//nolint:dupl +func (h *createsHandler) checkPaymentCoinCurrency(ctx context.Context) error { + currency, err := currencymwcli.GetCurrencyOnly(ctx, ¤cymwpb.Conds{ + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: h.paymentCoin.CoinTypeID}, }) if err != nil { return err } - if curr == nil { - return fmt.Errorf("invalid coin currency") + if currency == nil { + return fmt.Errorf("invalid currency") } - const maxElapsed = uint32(10 * 60) - if curr.UpdatedAt+maxElapsed < uint32(time.Now().Unix()) { + if currency.UpdatedAt+maxElapsed < uint32(time.Now().Unix()) { return fmt.Errorf("stale coin currency") } - - val, err := decimal.NewFromString(curr.MarketValueLow) + amount, err := decimal.NewFromString(currency.MarketValueLow) if err != nil { return err } - if val.Cmp(decimal.NewFromInt(0)) <= 0 { + if amount.Cmp(decimal.NewFromInt(0)) <= 0 { return fmt.Errorf("invalid market value") } - h.liveCurrency = val - h.coinCurrency = val - - apc, err := appcoinmwcli.GetCoinOnly(ctx, &appcoinmwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, - }) - if err != nil { - return err - } - if apc == nil { - return nil - } + h.liveCurrencyAmount = amount + h.coinCurrencyAmount = amount - currVal, err := decimal.NewFromString(apc.SettleValue) + amount, err = decimal.NewFromString(h.paymentCoin.SettleValue) if err != nil { return err } - if currVal.Cmp(decimal.NewFromInt(0)) > 0 { - h.coinCurrency = currVal + if amount.Cmp(decimal.NewFromInt(0)) > 0 { + h.coinCurrencyAmount = amount } - currVal, err = decimal.NewFromString(apc.MarketValue) + amount, err = decimal.NewFromString(h.paymentCoin.MarketValue) if err != nil { return err } - if currVal.Cmp(decimal.NewFromInt(0)) > 0 { - h.localCurrency = currVal + if amount.Cmp(decimal.NewFromInt(0)) > 0 { + h.localCurrencyAmount = amount } - return nil } -func getAccuracy(coin decimal.Decimal) decimal.Decimal { - const accuracy = 1000000 - coin = coin.Mul(decimal.NewFromInt(accuracy)) - coin = coin.Ceil() - coin = coin.Div(decimal.NewFromInt(accuracy)) - return coin +func (h *createsHandler) checkPaymentCoinAmount() error { + amount := h.paymentUSDTAmount. + Sub(h.reductionUSDTAmount). + Div(h.coinCurrencyAmount) + if amount.Cmp(decimal.NewFromInt(0)) <= 0 { + return fmt.Errorf("invalid price") + } + h.paymentCoinAmount = h.getAccuracy(amount) + h.reductionCoinAmount = h.reductionUSDTAmount.Div(h.coinCurrencyAmount) + h.reductionCoinAmount = h.getAccuracy(h.reductionCoinAmount) + return nil } -func (h *createHandler) SetPaymentAmount(ctx context.Context) error { - totalPaymentAmountUSD := decimal.NewFromInt(0) - for _, goodReq := range h.Goods { - price := h.goodPrices[*h.AppID+goodReq.GoodID] - units, err := decimal.NewFromString(goodReq.Units) - if err != nil { - return err - } - paymentAmountUSD := price.Mul(units) - totalPaymentAmountUSD = totalPaymentAmountUSD.Add(paymentAmountUSD) - h.goodValueUSDs[goodReq.GoodID] = paymentAmountUSD - - goodValueCoin := paymentAmountUSD.Div(h.coinCurrency) - goodValueCoin = getAccuracy(goodValueCoin) - h.paymentAmountCoin = h.paymentAmountCoin.Add(goodValueCoin) - h.goodValueCoins[goodReq.GoodID] = goodValueCoin +//nolint:dupl +func (h *createsHandler) checkTransferCoinAmount() error { + if h.BalanceAmount == nil { + h.transferCoinAmount = h.paymentCoinAmount + return nil } - logger.Sugar().Infow( - "CreateOrder", - "PaymentAmountUSD", totalPaymentAmountUSD, - "ReductionAmount", h.reductionAmount, - "ReductionPercent", h.reductionPercent, - ) - - discountAmountUSD := decimal.NewFromInt(0) - if h.reductionPercent != decimal.NewFromInt(0) { - discountAmountUSD = totalPaymentAmountUSD. - Mul(h.reductionPercent). - Div(decimal.NewFromInt(100)) //nolint + balanceCoinAmount, err := decimal.NewFromString(*h.BalanceAmount) + if err != nil { + return err } - discountAmountUSD = discountAmountUSD.Add(h.reductionAmount) - - h.discountAmountCoin = discountAmountUSD.Div(h.coinCurrency) - h.discountAmountCoin = getAccuracy(h.discountAmountCoin) - - if *h.OrderType == ordertypes.OrderType_Airdrop { - h.paymentAmountCoin = decimal.NewFromInt(0) + if balanceCoinAmount.Cmp(decimal.NewFromInt(0)) <= 0 { + return fmt.Errorf("invalid balanceamount") } - - h.paymentAmountCoin = h.paymentAmountCoin.Sub(h.discountAmountCoin) - if h.paymentAmountCoin.Cmp(decimal.NewFromInt(0)) < 0 { - h.paymentAmountCoin = decimal.NewFromInt(0) + h.balanceCoinAmount = balanceCoinAmount + h.transferCoinAmount = h.paymentCoinAmount.Sub(balanceCoinAmount) + if h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) < 0 { + h.balanceCoinAmount = h.paymentCoinAmount + h.transferCoinAmount = decimal.NewFromInt(0) } + return nil +} - h.paymentTransferAmount = h.paymentAmountCoin - if h.BalanceAmount != nil { - amount, err := decimal.NewFromString(*h.BalanceAmount) - if err != nil { - return err - } - if amount.Cmp(h.paymentTransferAmount) > 0 { - amount = h.paymentTransferAmount - amountStr := amount.String() - h.BalanceAmount = &amountStr - } - h.paymentTransferAmount = h.paymentTransferAmount.Sub(amount) +func (h *createsHandler) resolvePaymentType() { + if h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 && //nolint + h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 { + h.paymentType = types.PaymentType_PayWithNoPayment + return } - - return nil + if h.transferCoinAmount.Cmp(h.paymentCoinAmount) == 0 { + h.paymentType = types.PaymentType_PayWithTransferOnly + return + } + if h.balanceCoinAmount.Cmp(h.paymentCoinAmount) == 0 { + h.paymentType = types.PaymentType_PayWithBalanceOnly + return + } + h.paymentType = types.PaymentType_PayWithTransferAndBalance } -func (h *createHandler) paymentType() (*ordertypes.PaymentType, error) { - switch *h.OrderType { - case ordertypes.OrderType_Normal: - if h.BalanceAmount != nil { - if h.paymentTransferAmount.Cmp(decimal.NewFromInt(0)) > 0 { - return ordertypes.PaymentType_PayWithTransferAndBalance.Enum(), nil - } - return ordertypes.PaymentType_PayWithBalanceOnly.Enum(), nil +func (h *createsHandler) resolveStartMode() { + for _, order := range h.Orders { + appGood := h.appGoods[order.AppGoodID] + if appGood.StartMode == goodtypes.GoodStartMode_GoodStartModeTBD { + h.orderStartMode[order.AppGoodID] = types.OrderStartMode_OrderStartTBD + return } - return ordertypes.PaymentType_PayWithTransferOnly.Enum(), nil - case ordertypes.OrderType_Offline: - return ordertypes.PaymentType_PayWithOffline.Enum(), nil - case ordertypes.OrderType_Airdrop: - return ordertypes.PaymentType_PayWithNoPayment.Enum(), nil - default: - return nil, fmt.Errorf("invalid ordertype") + h.orderStartMode[order.AppGoodID] = types.OrderStartMode_OrderStartConfirmed } } -func (h *createHandler) SetPaymentType(ctx context.Context) error { - paymentType, err := h.paymentType() +//nolint:dupl +func (h *createsHandler) peekExistAddress(ctx context.Context) (*payaccmwpb.Account, error) { + const batchAccounts = int32(5) + accounts, _, err := payaccmwcli.GetAccounts(ctx, &payaccmwpb.Conds{ + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: h.paymentCoin.CoinTypeID}, + Active: &basetypes.BoolVal{Op: cruder.EQ, Value: true}, + Locked: &basetypes.BoolVal{Op: cruder.EQ, Value: false}, + Blocked: &basetypes.BoolVal{Op: cruder.EQ, Value: false}, + AvailableAt: &basetypes.Uint32Val{Op: cruder.LTE, Value: uint32(time.Now().Unix())}, + }, int32(0), batchAccounts) if err != nil { - return err + return nil, err } - h.mainPaymentType = paymentType - return nil + for _, account := range accounts { + if account.Locked || !account.Active || account.Blocked { + continue + } + if account.AvailableAt > uint32(time.Now().Unix()) { + continue + } + return account, nil + } + return nil, fmt.Errorf("invalid address") } -func (h *createHandler) createAddresses(ctx context.Context) error { +func (h *createsHandler) peekNewAddress(ctx context.Context) (*payaccmwpb.Account, error) { const createCount = 5 successCreated := 0 for i := 0; i < createCount; i++ { - address, err := sphinxproxycli.CreateAddress(ctx, h.paymentCoinName) + address, err := sphinxproxycli.CreateAddress(ctx, h.paymentCoin.CoinName) if err != nil { - return err + return nil, err } if address == nil || address.Address == "" { - return fmt.Errorf("invalid address") + return nil, fmt.Errorf("invalid address") } - _, err = payaccmwcli.CreateAccount(ctx, &payaccmwpb.AccountReq{ - CoinTypeID: h.PaymentCoinID, + CoinTypeID: &h.paymentCoin.CoinTypeID, Address: &address.Address, }) if err != nil { - return err + return nil, err } - successCreated++ } - if successCreated == 0 { - return fmt.Errorf("fail create addresses") + return nil, fmt.Errorf("fail create addresses") } - return nil + return h.peekExistAddress(ctx) } -func (h *createHandler) peekAddress(ctx context.Context) (*payaccmwpb.Account, error) { - payments, _, err := payaccmwcli.GetAccounts(ctx, &payaccmwpb.Conds{ - CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.PaymentCoinID}, - Active: &basetypes.BoolVal{Op: cruder.EQ, Value: true}, - Locked: &basetypes.BoolVal{Op: cruder.EQ, Value: false}, - Blocked: &basetypes.BoolVal{Op: cruder.EQ, Value: false}, - AvailableAt: &basetypes.Uint32Val{Op: cruder.LTE, Value: uint32(time.Now().Unix())}, - }, 0, 5) //nolint - if err != nil { - return nil, err +func (h *createsHandler) peekPaymentAddress(ctx context.Context) error { + switch h.paymentType { + case types.PaymentType_PayWithBalanceOnly: + fallthrough //nolint + case types.PaymentType_PayWithNoPayment: + return nil } - var account *payaccmwpb.Account - - for _, payment := range payments { - info, err := payaccmwcli.GetAccount(ctx, payment.ID) + account, err := h.peekExistAddress(ctx) + if err != nil { + account, err = h.peekNewAddress(ctx) if err != nil { - return nil, err - } - - if info.Locked || !info.Active || info.Blocked { - continue - } - - if info.AvailableAt > uint32(time.Now().Unix()) { - continue + return err } - account = info - break - } - - if account == nil { - return nil, nil } - h.paymentAccount = account - - return account, nil -} - -func (h *createHandler) withLockPaymentAccount(dispose *dtmcli.SagaDispose) { - switch *h.mainPaymentType { - case ordertypes.PaymentType_PayWithTransferOnly: - fallthrough //nolint - case ordertypes.PaymentType_PayWithTransferAndBalance: - fallthrough //nolint - case ordertypes.PaymentType_PayWithOffline: - locked := true - lockedBy := basetypes.AccountLockedBy_Payment - req := &payaccmwpb.AccountReq{ - ID: &h.paymentAccount.ID, - Locked: &locked, - LockedBy: &lockedBy, - } - dispose.Add( - ordermwsvcname.ServiceDomain, - "account.middleware.payment.v1.Middleware/UpdateAccount", - "", - &payaccmwpb.UpdateAccountRequest{ - Info: req, - }, - ) - } + return nil } -func (h *createHandler) PeekAddress(ctx context.Context) error { - account, err := h.peekAddress(ctx) +func (h *createsHandler) recheckPaymentAccount(ctx context.Context) error { + account, err := payaccmwcli.GetAccount(ctx, h.paymentAccount.ID) if err != nil { return err } - if account != nil { - h.paymentAccount = account - return nil + if account == nil { + return fmt.Errorf("invalid account") } - - if err := h.createAddresses(ctx); err != nil { - return err + if account.Locked || !account.Active || account.Blocked { + return fmt.Errorf("invalid account") } - - account, err = h.peekAddress(ctx) - if err != nil { - return err + if account.AvailableAt > uint32(time.Now().Unix()) { + return fmt.Errorf("invalid account") } - if account == nil { - return fmt.Errorf("fail peek address") - } - - h.paymentAccount = account return nil } -func (h *createHandler) SetAddressBalance(ctx context.Context) error { +func (h *createsHandler) getPaymentStartAmount(ctx context.Context) error { balance, err := sphinxproxycli.GetBalance(ctx, &sphinxproxypb.GetBalanceRequest{ - Name: h.paymentCoinName, + Name: h.paymentCoin.CoinName, Address: h.paymentAccount.Address, }) if err != nil { @@ -505,16 +527,34 @@ func (h *createHandler) SetAddressBalance(ctx context.Context) error { return fmt.Errorf("invalid balance") } - h.paymentAddressStartAmount, err = decimal.NewFromString(balance.BalanceStr) + h.paymentStartAmount, err = decimal.NewFromString(balance.BalanceStr) return err } -func (h *createHandler) withUpdateStock(dispose *dtmcli.SagaDispose) { - for _, goodReq := range h.Goods { +func (h *createsHandler) checkOrderDuration() { + for _, order := range h.Orders { + appGood := h.appGoods[order.AppGoodID] + goodStartAt := appGood.ServiceStartAt + if appGood.ServiceStartAt == 0 { + goodStartAt = appGood.StartAt + } + goodDurationDays := uint32(appGood.DurationDays) + orderStartAt := uint32(h.tomorrowStart().Unix()) + if goodStartAt > orderStartAt { + orderStartAt = goodStartAt + } + const secondsPerDay = 24 * 60 * 60 + h.orderEndAt[order.AppGoodID] = orderStartAt + goodDurationDays*secondsPerDay + h.orderStartAt[order.AppGoodID] = orderStartAt + h.goodDurationDays[order.AppGoodID] = goodDurationDays + } +} + +func (h *createsHandler) withUpdateStock(dispose *dtmcli.SagaDispose) { + for _, order := range h.Orders { req := &appgoodstockmwpb.StockReq{ - AppID: h.AppID, - GoodID: &goodReq.GoodID, - Locked: &goodReq.Units, + AppGoodID: &order.AppGoodID, + Locked: &h.Units, } dispose.Add( ordermwsvcname.ServiceDomain, @@ -527,15 +567,17 @@ func (h *createHandler) withUpdateStock(dispose *dtmcli.SagaDispose) { } } -func (h *createHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { - if h.BalanceAmount != nil { +func (h *createsHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { + if h.balanceCoinAmount.Cmp(decimal.NewFromInt(0)) <= 0 { return } + + amount := h.balanceCoinAmount.String() req := &ledgermwpb.LedgerReq{ AppID: h.AppID, UserID: h.UserID, - CoinTypeID: &h.paymentAccount.CoinTypeID, - Spendable: h.BalanceAmount, + CoinTypeID: h.PaymentCoinID, + Spendable: &amount, } dispose.Add( ordermwsvcname.ServiceDomain, @@ -547,293 +589,240 @@ func (h *createHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { ) } -func (h *createHandler) orderReqs() []*ordermwpb.OrderReq { - paymentAmount := h.paymentAmountCoin.String() - startAmount := h.paymentAddressStartAmount.String() - paymentTransferAmount := h.paymentTransferAmount.String() - coinCurrency := h.coinCurrency.String() - liveCurrency := h.liveCurrency.String() - localCurrency := h.localCurrency.String() - discountAmountCoin := h.discountAmountCoin.String() - childPaymentType := ordertypes.PaymentType_PayWithParentOrder - zeroAmount := "0" - h.mainOrderID = uuid.NewString() - - orderReqs := []*ordermwpb.OrderReq{} - for _, goodReq := range h.Goods { - goodValue := h.goodValueCoins[goodReq.GoodID].String() - goodValueUSD := h.goodValueUSDs[goodReq.GoodID].String() - appgood := h.orderGood.appgoods[*h.AppID+goodReq.GoodID] - good := h.orderGood.goods[goodReq.GoodID] - goodDurationDays := uint32(good.DurationDays) - startAt := h.startAts[*h.AppID+goodReq.GoodID] - endAt := h.endAts[*h.AppID+goodReq.GoodID] - - logger.Sugar().Infow( - "CreateOrder", - "PaymentAmountCoin", h.paymentAmountCoin, - "DiscountAmountCoin", h.discountAmountCoin, - "BalanceAmount", h.BalanceAmount, - "ReductionAmount", h.reductionAmount, - "ReductionPercent", h.reductionPercent, - "PaymentAddressStartAmount", h.paymentAddressStartAmount, - "CoinCurrency", h.coinCurrency, - "LiveCurrency", h.liveCurrency, - "LocalCurrency", h.localCurrency, - ) - orderReq := &ordermwpb.OrderReq{ +func (h *createsHandler) withCreateOrders(dispose *dtmcli.SagaDispose) { + paymentCoinAmount := h.paymentCoinAmount.String() + discountCoinAmount := h.reductionCoinAmount.String() + transferCoinAmount := h.transferCoinAmount.String() + balanceCoinAmount := h.balanceCoinAmount.String() + coinUSDCurrency := h.coinCurrencyAmount.String() + localCoinUSDCurrency := h.localCurrencyAmount.String() + liveCoinUSDCurrency := h.liveCurrencyAmount.String() + + reqs := []*ordermwpb.OrderReq{} + for _, order := range h.Orders { + goodValueCoinAmount := h.goodValueCoinAmount[order.AppGoodID].String() + goodValueUSDTAmount := h.goodValueUSDTAmount[order.AppGoodID].String() + orderStartAt := h.orderStartAt[order.AppGoodID] + orderEndAt := h.orderEndAt[order.AppGoodID] + startMode := h.orderStartMode[order.AppGoodID] + goodDurationDays := h.goodDurationDays[order.AppGoodID] + + req := &ordermwpb.OrderReq{ + ID: h.ids[order.AppGoodID], AppID: h.AppID, UserID: h.UserID, - GoodID: &goodReq.GoodID, - AppGoodID: &appgood.ID, - Units: &goodReq.Units, - GoodValue: &goodValue, - GoodValueUSD: &goodValueUSD, + GoodID: &h.appGoods[order.AppGoodID].GoodID, + AppGoodID: h.AppGoodID, + Units: &h.Units, + GoodValue: &goodValueCoinAmount, + GoodValueUSD: &goodValueUSDTAmount, DurationDays: &goodDurationDays, OrderType: h.OrderType, InvestmentType: h.InvestmentType, - CoinTypeID: &good.CoinTypeID, + CoinTypeID: &h.appGoods[order.AppGoodID].CoinTypeID, PaymentCoinTypeID: h.PaymentCoinID, - CoinUSDCurrency: &coinCurrency, - LiveCoinUSDCurrency: &liveCurrency, - LocalCoinUSDCurrency: &localCurrency, - StartAt: &startAt, - EndAt: &endAt, - } - - if !goodReq.Parent && h.ParentOrderID == nil { - id := uuid.NewString() - // batch child order - orderReq.ID = &id - orderReq.ParentOrderID = &h.mainOrderID - orderReq.PaymentAmount = &zeroAmount - orderReq.DiscountAmount = &zeroAmount - orderReq.PaymentType = &childPaymentType - orderReq.TransferAmount = &zeroAmount - orderReq.BalanceAmount = &zeroAmount - h.IDs = append(h.IDs, id) + CoinUSDCurrency: &coinUSDCurrency, + LocalCoinUSDCurrency: &localCoinUSDCurrency, + LiveCoinUSDCurrency: &liveCoinUSDCurrency, + StartAt: &orderStartAt, + EndAt: &orderEndAt, + StartMode: &startMode, + } + if h.promotions[order.AppGoodID] != nil { + req.PromotionID = &h.promotions[order.AppGoodID].ID + } + if order.Parent { + req.PaymentAmount = &paymentCoinAmount + req.DiscountAmount = &discountCoinAmount + req.PaymentType = &h.paymentType + req.TransferAmount = &transferCoinAmount + req.BalanceAmount = &balanceCoinAmount + req.CouponIDs = h.CouponIDs + if h.paymentAccount != nil { + req.PaymentAccountID = &h.paymentAccount.AccountID + paymentStartAmount := h.paymentStartAmount.String() + req.PaymentStartAmount = &paymentStartAmount + } } else { - // parent order or single order - orderReq.ID = &h.mainOrderID - orderReq.ParentOrderID = h.ParentOrderID - orderReq.PaymentAmount = &paymentAmount - orderReq.DiscountAmount = &discountAmountCoin - orderReq.CouponIDs = h.CouponIDs - orderReq.PaymentType = h.mainPaymentType - orderReq.TransferAmount = &paymentTransferAmount - orderReq.BalanceAmount = h.BalanceAmount - orderReq.PaymentAccountID = &h.paymentAccount.AccountID - orderReq.PaymentStartAmount = &startAmount - h.IDs = append(h.IDs, h.mainOrderID) - } - - topmostGood := h.orderGood.topMostGoods[*h.AppID+goodReq.GoodID] - if topmostGood != nil { - orderReq.PromotionID = &topmostGood.TopMostID - } - orderReqs = append(orderReqs, orderReq) - } - return orderReqs -} + req.ParentOrderID = h.mainOrderID + childPaymentType := types.PaymentType_PayWithParentOrder + req.PaymentType = &childPaymentType + } + reqs = append(reqs, req) + } -func (h *createHandler) withCreateOrder(dispose *dtmcli.SagaDispose, req *ordermwpb.OrderReq) { dispose.Add( ordermwsvcname.ServiceDomain, - "order.middleware.order1.v1.Middleware/CreateOrder", - "order.middleware.order1.v1.Middleware/DeleteOrder", - &ordermwpb.CreateOrderRequest{ - Info: req, + "order.middleware.order1.v1.Middleware/CreateOrders", + "order.middleware.order1.v1.Middleware/DeleteOrders", + &ordermwpb.CreateOrdersRequest{ + Infos: reqs, }, ) } -func (h *createHandler) withCreateOrders(dispose *dtmcli.SagaDispose, reqs []*ordermwpb.OrderReq) { +func (h *createsHandler) withLockPaymentAccount(dispose *dtmcli.SagaDispose) { + if h.paymentAccount == nil { + return + } + + locked := true + lockedBy := basetypes.AccountLockedBy_Payment + req := &payaccmwpb.AccountReq{ + ID: &h.paymentAccount.ID, + Locked: &locked, + LockedBy: &lockedBy, + } dispose.Add( ordermwsvcname.ServiceDomain, - "order.middleware.order1.v1.Middleware/CreateOrders", - "order.middleware.order1.v1.Middleware/DeleteOrders", - &ordermwpb.CreateOrdersRequest{ - Infos: reqs, + "account.middleware.payment.v1.Middleware/UpdateAccount", + "", + &payaccmwpb.UpdateAccountRequest{ + Info: req, }, ) } +func (h *createsHandler) checkGoodRequests(ctx context.Context) error { + goodSet := make(map[string]struct{}) + for _, order := range h.Orders { + appgood := h.appGoods[order.AppGoodID] + if order.Parent { + goodRequireds, _, err := goodrequiredmwcli.GetRequireds(ctx, &goodrequiredpb.Conds{ + MainGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: appgood.GoodID}, + }, 0, 0) + if err != nil { + return err + } + h.goodRequireds = goodRequireds + continue + } + goodSet[appgood.GoodID] = struct{}{} + } + + requiredSet := make(map[string]struct{}) + for _, goodRequired := range h.goodRequireds { + requiredSet[goodRequired.RequiredGoodID] = struct{}{} + } + + for _, order := range h.Orders { + appgood := h.appGoods[order.AppGoodID] + if order.Parent { + continue + } + if _, ok := requiredSet[appgood.GoodID]; !ok { + return fmt.Errorf("invalid goodrequired") + } + } + + for _, goodRequired := range h.goodRequireds { + if goodRequired.Must { + if _, ok := goodSet[goodRequired.RequiredGoodID]; !ok { + return fmt.Errorf("invalid goodrequired must") + } + } + } + return nil +} + //nolint:funlen,gocyclo -func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error) { - // 1 Check input - // 1.1 Check user - // 1.2 Check app good - // 1.3 Check payment coin - // 1.4 Check parent order (by middleware && handler) - // 1.5 Check coupon ids (by handler) - // 1.6 Check balance (by dtm lock) - // 1.7 Check only one discount coupon - // 2 Calculate reduction - // 2.1 Calculate amount of discount coupon - // 2.2 Calculate amount of fix amount - // 3 Calculate price - // 3.1 Calculate USDT GoodValue - DiscountAmount - // 3.2 Get currency - // 3.3 Calculate payment coin amount - // 4 Peek address - // 4.1 Peek exist address - // 4.2 If fail, create addresses them peek one - // 4.3 Redis lock address - // 4.4 Recheck address lock - // DTM - // 5 Lock balance - // 6 Create order - // 7 Lock address - - handler := &createHandler{ +func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err error) { + handler := &createsHandler{ Handler: h, } if err := handler.getUser(ctx); err != nil { - return err + return nil, err } if err := handler.getPaymentCoin(ctx); err != nil { - return err + return nil, err } if err := handler.getCoupons(ctx); err != nil { - return err - } - if err := handler.validateDiscountCoupon(ctx); err != nil { - return err - } - if err := handler.calculateDiscountCouponReduction(); err != nil { - return err - } - if err := handler.calculateFixAmountCouponReduction(); err != nil { - return err - } - if err := handler.getAppGood(ctx); err != nil { - return err - } - if err := handler.calculateOrderUSDTPrice(ctx); err != nil { - return err - } - if err := handler.getPaymentCoinCurrency(ctx); err != nil { - return err - } - if err := handler.calculatePaymentCoinAmount(ctx); err != nil { - return err - } - if err := handler.peekExistAddress(ctx); err != nil { - if err := handler.peekNewAddress(ctx); err != nil { - return err - } + return nil, err } - if err := accountlock.Lock(handler.paymentAccount.AccountID); err != nil { - return err + if err := handler.validateDiscountCoupon(); err != nil { + return nil, err } - if err := handler.recheckPaymentAccount(ctx); err != nil { - return err + if err := handler.checkMaxUnpaidOrders(ctx); err != nil { + return nil, err } - defer func() { - _ = accountlock.Unlock(handler.paymentAccount.AccountID) - }() - - id := uuid.NewString() - if h.ID == nil { - h.ID = &id + if err := handler.getAppGoods(ctx); err != nil { + return nil, err } - - const timeoutSeconds = 10 - sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ - WaitResult: true, - RequestTimeout: timeoutSeconds, - }) - - handler.withUpdateStock(sagaDispose) - handler.withUpdateBalance(sagaDispose) - handler.withCreateOrder(sagaDispose) - handler.withLockPaymentAccount(sagaDispose) - - if err := dtmcli.WithSaga(ctx, sagaDispose); err != nil { + if err := handler.checkUnitsLimit(ctx); err != nil { return nil, err } - - return h.GetOrder(ctx) -} - -//nolint:funlen,gocyclo -func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err error) { - orderGood, err := h.ToOrderGoods(ctx) - if err != nil { + if err := handler.checkGoodRequests(ctx); err != nil { return nil, err } - handler := &createHandler{ - Handler: h, - orderGood: orderGood, + if err := handler.getAppGoodPromotions(ctx); err != nil { + return nil, err } - if err := handler.validateInit(ctx); err != nil { + if err := handler.calculateOrderUSDTPrice(); err != nil { return nil, err } - - if err := handler.checkGoodRequests(); err != nil { + if err := handler.calculateDiscountCouponReduction(); err != nil { return nil, err } - - if err := handler.SetReduction(ctx); err != nil { + if err := handler.calculateFixAmountCouponReduction(); err != nil { return nil, err } - - if err := handler.SetPrice(ctx); err != nil { + if err := handler.checkPaymentCoinCurrency(ctx); err != nil { return nil, err } - - if err := handler.SetCurrency(ctx); err != nil { + if err := handler.checkPaymentCoinAmount(); err != nil { return nil, err } - - if err := handler.SetPaymentAmount(ctx); err != nil { + if err := handler.checkTransferCoinAmount(); err != nil { return nil, err } + handler.resolvePaymentType() + handler.resolveStartMode() + handler.checkOrderDuration() - if err := handler.SetPaymentType(ctx); err != nil { + if err := handler.peekPaymentAddress(ctx); err != nil { return nil, err } - - switch *handler.mainPaymentType { - case ordertypes.PaymentType_PayWithTransferOnly: - fallthrough //nolint - case ordertypes.PaymentType_PayWithTransferAndBalance: - fallthrough //nolint - case ordertypes.PaymentType_PayWithOffline: - for i := 0; i < 5; i++ { - if err := handler.PeekAddress(ctx); err != nil { - return nil, err - } - if err := accountlock.Lock(handler.paymentAccount.AccountID); err != nil { - continue - } - break + if handler.paymentAccount != nil { + if err := accountlock.Lock(handler.paymentAccount.AccountID); err != nil { + return nil, err + } + if err := handler.recheckPaymentAccount(ctx); err != nil { + return nil, err } defer func() { - accountlock.Unlock(handler.paymentAccount.AccountID) //nolint + _ = accountlock.Unlock(handler.paymentAccount.AccountID) }() - if err := handler.SetAddressBalance(ctx); err != nil { + if err := handler.getPaymentStartAmount(ctx); err != nil { return nil, err } } - createReqs := handler.orderReqs() - lockKey := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, handler.mainOrderID) - if err := redis2.TryLock(lockKey, 0); err != nil { + for _, order := range h.Orders { + id := uuid.NewString() + handler.ids[order.AppGoodID] = &id + if order.Parent { + handler.mainOrderID = &id + } + h.IDs = append(h.IDs, id) + } + + key := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, handler.mainOrderID) + if err := redis2.TryLock(key, 0); err != nil { return nil, err } defer func() { - _ = redis2.Unlock(lockKey) + _ = redis2.Unlock(key) }() + const timeoutSeconds = 10 sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ WaitResult: true, - RequestTimeout: handler.RequestTimeoutSeconds, + RequestTimeout: timeoutSeconds, }) handler.withUpdateStock(sagaDispose) handler.withUpdateBalance(sagaDispose) - handler.withCreateOrders(sagaDispose, createReqs) + handler.withCreateOrders(sagaDispose) handler.withLockPaymentAccount(sagaDispose) if err := dtmcli.WithSaga(ctx, sagaDispose); err != nil { diff --git a/pkg/order/handler.go b/pkg/order/handler.go index e4bb422..6110b8c 100644 --- a/pkg/order/handler.go +++ b/pkg/order/handler.go @@ -19,24 +19,24 @@ import ( ) type Handler struct { - ID *string - AppID *string - UserID *string - AppGoodID *string - Units string - PaymentCoinID *string - ParentOrderID *string - BalanceAmount *string - OrderType *ordertypes.OrderType - CouponIDs []string - InvestmentType *ordertypes.InvestmentType - UserSetCanceled *bool - AdminSetCanceled *bool - PaymentID *string - Offset int32 - Limit int32 - Orders []*npool.CreateOrdersRequest_OrderReq - RequestTimeoutSeconds int64 + ID *string + AppID *string + UserID *string + AppGoodID *string + Units string + PaymentCoinID *string + ParentOrderID *string + BalanceAmount *string + OrderType *ordertypes.OrderType + CouponIDs []string + InvestmentType *ordertypes.InvestmentType + UserSetCanceled *bool + AdminSetCanceled *bool + PaymentID *string + Offset int32 + Limit int32 + Orders []*npool.CreateOrdersRequest_OrderReq + IDs []string } func NewHandler(ctx context.Context, options ...func(context.Context, *Handler) error) (*Handler, error) { diff --git a/pkg/order/ordergood.go b/pkg/order/ordergood.go deleted file mode 100644 index 1046671..0000000 --- a/pkg/order/ordergood.go +++ /dev/null @@ -1,180 +0,0 @@ -package order - -import ( - "context" - "fmt" - - cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" - basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" - - coininfocli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin" - appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" - topmostgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/topmost/good" - goodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good" - goodrequiredmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good/required" - coinpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin" - appgoodpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good" - topmostgoodpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/topmost/good" - goodpb "github.com/NpoolPlatform/message/npool/good/mw/v1/good" - goodrequiredpb "github.com/NpoolPlatform/message/npool/good/mw/v1/good/required" - npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" - - ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" - ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" - ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" - - "github.com/shopspring/decimal" -) - -type OrderGood struct { - goods map[string]*goodpb.Good - appgoods map[string]*appgoodpb.Good - goodCoins map[string]*coinpb.Coin - topMostGoods map[string]*topmostgoodpb.TopMostGood - goodRequireds []*goodrequiredpb.Required -} - -func (h *Handler) ToOrderGood(ctx context.Context) (*OrderGood, error) { - parent := true - if h.ParentOrderID != nil { - parent = false - } - goodReq := &npool.CreateOrdersRequest_Good{ - GoodID: *h.GoodID, - Units: h.Units, - Parent: parent, - } - h.Goods = append(h.Goods, goodReq) - return h.ToOrderGoods(ctx) -} - -//nolint:funlen,gocyclo -func (h *Handler) ToOrderGoods(ctx context.Context) (*OrderGood, error) { - ordergood := &OrderGood{ - goods: map[string]*goodpb.Good{}, - appgoods: map[string]*appgoodpb.Good{}, - goodCoins: map[string]*coinpb.Coin{}, - topMostGoods: map[string]*topmostgoodpb.TopMostGood{}, - } - parentGoodNum := 0 - for _, goodReq := range h.Goods { - if goodReq.Parent { - parentGoodNum++ - if parentGoodNum != 1 { - return nil, fmt.Errorf("invalid parent") - } - goodRequireds, _, err := goodrequiredmwcli.GetRequireds(ctx, &goodrequiredpb.Conds{ - MainGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: goodReq.GoodID}, - }, 0, 0) - if err != nil { - return nil, err - } - ordergood.goodRequireds = goodRequireds - } - good, err := goodmwcli.GetGood(ctx, goodReq.GoodID) - if err != nil { - return nil, err - } - if good == nil { - return nil, fmt.Errorf("invalid good") - } - ordergood.goods[goodReq.GoodID] = good - - appgood, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: goodReq.GoodID}, - }) - if err != nil { - return nil, err - } - if appgood == nil { - return nil, fmt.Errorf("invalid app good") - } - if !appgood.Online { - return nil, fmt.Errorf("good offline") - } - - agPrice, err := decimal.NewFromString(appgood.Price) - if err != nil { - return nil, err - } - if agPrice.Cmp(decimal.NewFromInt(0)) <= 0 { - return nil, fmt.Errorf("invalid good price") - } - price, err := decimal.NewFromString(good.Price) - if err != nil { - return nil, err - } - if agPrice.Cmp(price) < 0 { - return nil, fmt.Errorf("invalid app good price") - } - - if *h.OrderType == ordertypes.OrderType_Normal { - units, err := decimal.NewFromString(h.Units) - if err != nil { - return nil, err - } - if appgood.PurchaseLimit > 0 && units.Cmp(decimal.NewFromInt32(appgood.PurchaseLimit)) > 0 { - return nil, fmt.Errorf("too many units") - } - if !appgood.EnablePurchase { - return nil, fmt.Errorf("app good is not enabled purchase") - } - purchaseCountStr, err := ordermwcli.SumOrderUnits( - ctx, - &ordermwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, - GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.GoodID}, - OrderStates: &basetypes.Uint32SliceVal{ - Op: cruder.IN, - Value: []uint32{ - uint32(ordertypes.OrderState_OrderStatePaid), - uint32(ordertypes.OrderState_OrderStateInService), - uint32(ordertypes.OrderState_OrderStateExpired), - uint32(ordertypes.OrderState_OrderStateWaitPayment), - }, - }, - }, - ) - if err != nil { - return nil, err - } - purchaseCount, err := decimal.NewFromString(purchaseCountStr) - if err != nil { - return nil, err - } - - userPurchaseLimit, err := decimal.NewFromString(appgood.UserPurchaseLimit) - if err != nil { - return nil, err - } - - if userPurchaseLimit.Cmp(decimal.NewFromInt(0)) > 0 && purchaseCount.Add(units).Cmp(userPurchaseLimit) > 0 { - return nil, fmt.Errorf("too many units") - } - } - - goodCoin, err := coininfocli.GetCoin(ctx, good.CoinTypeID) - if err != nil { - return nil, err - } - if goodCoin == nil { - return nil, fmt.Errorf("invalid good coin") - } - ordergood.goodCoins[goodReq.GoodID] = goodCoin - - topMostGood, err := topmostgoodmwcli.GetTopMostGoodOnly(ctx, &topmostgoodpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: goodReq.GoodID}, - }) - if err != nil { - return nil, err - } - if topMostGood != nil { - ordergood.topMostGoods[*h.AppID+goodReq.GoodID] = topMostGood - } - } - - return ordergood, nil -} From d6a66927b64e7663f53b737caefb6d723e5efa3a Mon Sep 17 00:00:00 2001 From: jakys Date: Tue, 5 Sep 2023 08:24:02 +0000 Subject: [PATCH 16/67] Refactor update --- api/order/update.go | 12 +-- pkg/order/update.go | 215 +++++++++++++++++++++++++------------------- 2 files changed, 124 insertions(+), 103 deletions(-) diff --git a/api/order/update.go b/api/order/update.go index d302013..5301328 100644 --- a/api/order/update.go +++ b/api/order/update.go @@ -18,10 +18,8 @@ func (s *Server) UpdateOrder(ctx context.Context, in *npool.UpdateOrderRequest) ctx, order1.WithID(&in.ID, true), order1.WithAppID(&in.AppID, true), - order1.WithUserID(&in.AppID, &in.UserID, true), - order1.WithPaymentID(&in.PaymentID, true), + order1.WithUserID(&in.UserID, true), order1.WithUserSetCanceled(in.Canceled, true), - order1.WithFromAdmin(false), ) if err != nil { logger.Sugar().Errorw( @@ -52,10 +50,8 @@ func (s *Server) UpdateUserOrder(ctx context.Context, in *npool.UpdateUserOrderR ctx, order1.WithID(&in.ID, true), order1.WithAppID(&in.AppID, true), - order1.WithUserID(&in.AppID, &in.TargetUserID, true), - order1.WithPaymentID(&in.PaymentID, true), + order1.WithUserID(&in.TargetUserID, true), order1.WithAdminSetCanceled(in.Canceled, true), - order1.WithFromAdmin(true), ) if err != nil { logger.Sugar().Errorw( @@ -86,10 +82,8 @@ func (s *Server) UpdateAppUserOrder(ctx context.Context, in *npool.UpdateAppUser ctx, order1.WithID(&in.ID, true), order1.WithAppID(&in.TargetAppID, true), - order1.WithUserID(&in.TargetAppID, &in.TargetUserID, true), - order1.WithPaymentID(&in.PaymentID, true), + order1.WithUserID(&in.TargetUserID, true), order1.WithAdminSetCanceled(in.Canceled, true), - order1.WithFromAdmin(true), ) if err != nil { logger.Sugar().Errorw( diff --git a/pkg/order/update.go b/pkg/order/update.go index f6c20d1..4b9f79a 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -30,6 +30,7 @@ import ( ledgermwpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger" ledgerstatementpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger/statement" + usermwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" statementmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/achievement/statement" statementmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/achievement/statement" @@ -38,65 +39,135 @@ import ( type updateHandler struct { *Handler - ord *ordermwpb.Order + order *ordermwpb.Order + appGood *appgoodmwpb.Good achievementStatements []*statementmwpb.Statement } -//nolint:gocyclo -func (h *updateHandler) cancelable(ctx context.Context) error { - appgood, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodmwpb.Conds{ +func (h *updateHandler) checkCancelParam() error { + if h.UserSetCanceled == nil && h.AdminSetCanceled == nil { + return fmt.Errorf("nothing todo") + } + if h.UserSetCanceled != nil && !*h.UserSetCanceled { + return fmt.Errorf("nothing todo") + } + if h.AdminSetCanceled != nil && !*h.AdminSetCanceled { + return fmt.Errorf("nothing todo") + } + return nil +} + +func (h *updateHandler) checkUser(ctx context.Context) error { + user, err := usermwcli.GetUser(ctx, *h.AppID, *h.UserID) + if err != nil { + return err + } + if user == nil { + return fmt.Errorf("invalid user") + } + return nil +} + +func (h *updateHandler) checkOrder(ctx context.Context) error { + order, err := ordermwcli.GetOrder(ctx, *h.ID) + if err != nil { + return err + } + if order == nil { + return fmt.Errorf("invalid order") + } + if *h.AppID != order.AppID || *h.UserID != order.UserID { + return fmt.Errorf("permission denied") + } + h.order = order + return nil +} + +func (h *updateHandler) checkOrderType() error { + switch h.order.OrderType { + case ordertypes.OrderType_Normal: + switch h.order.OrderState { + case ordertypes.OrderState_OrderStateWaitPayment: + fallthrough //nolint + case ordertypes.OrderState_OrderStateCheckPayment: + if h.AdminSetCanceled != nil { + return fmt.Errorf("permission denied") + } + case ordertypes.OrderState_OrderStatePaid: + case ordertypes.OrderState_OrderStateInService: + } + case ordertypes.OrderType_Offline: + fallthrough //nolint + case ordertypes.OrderType_Airdrop: + if h.AdminSetCanceled == nil { + return fmt.Errorf("permission denied") + } + default: + return fmt.Errorf("order type uncancellable") + } + return nil +} + +func (h *updateHandler) getAppGood(ctx context.Context) error { + good, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodmwpb.Conds{ AppID: &basetypes.StringVal{ Op: cruder.EQ, - Value: h.ord.AppID, + Value: h.order.AppID, }, GoodID: &basetypes.StringVal{ Op: cruder.EQ, - Value: h.ord.GoodID, + Value: h.order.GoodID, }, }) if err != nil { return err } - if appgood == nil { + if good == nil { return fmt.Errorf("invalid appgood") } + h.appGood = good + return nil +} - good, err := goodmwcli.GetGood(ctx, h.ord.GoodID) +func (h *updateHandler) checkGood(ctx context.Context) error { + good, err := goodmwcli.GetGood(ctx, h.order.GoodID) if err != nil { return err } if good == nil { return fmt.Errorf("invalid good") } + if good.RewardState != goodtypes.BenefitState_BenefitWait { + return fmt.Errorf("app good uncancellable benefit state not wait") + } + return nil +} - statements, _, err := goodledgerstatementcli.GetGoodStatements(ctx, &goodledgerstatementpb.Conds{ +func (h *updateHandler) checkCancelable(ctx context.Context) error { + goodStatements, _, err := goodledgerstatementcli.GetGoodStatements(ctx, &goodledgerstatementpb.Conds{ GoodID: &basetypes.StringVal{ Op: cruder.EQ, - Value: h.ord.GoodID, + Value: h.order.GoodID, }, }, 0, 1) if err != nil { return err } - switch h.ord.OrderState { + switch h.order.OrderState { case ordertypes.OrderState_OrderStateWaitPayment: case ordertypes.OrderState_OrderStateCheckPayment: - if len(statements) > 0 { + if len(goodStatements) > 0 { return fmt.Errorf("had statements can not cancel") } return nil } - if good.RewardState != goodtypes.BenefitState_BenefitWait { - return fmt.Errorf("app good uncancellable benefit state not wait") - } - - switch appgood.CancelMode { + switch h.appGood.CancelMode { case goodtypes.CancelMode_Uncancellable: return fmt.Errorf("app good uncancellable") case goodtypes.CancelMode_CancellableBeforeStart: - switch h.ord.OrderState { + switch h.order.OrderState { case ordertypes.OrderState_OrderStatePaid: case ordertypes.OrderState_OrderStateInService: return fmt.Errorf("order state is uncancellable") @@ -104,36 +175,36 @@ func (h *updateHandler) cancelable(ctx context.Context) error { return fmt.Errorf("order state is uncancellable") } case goodtypes.CancelMode_CancellableBeforeBenefit: - switch h.ord.OrderState { + switch h.order.OrderState { case ordertypes.OrderState_OrderStatePaid: case ordertypes.OrderState_OrderStateInService: - if len(statements) > 0 { - lastBenefitDate := statements[0].BenefitDate + if len(goodStatements) > 0 { + lastBenefitDate := goodStatements[0].BenefitDate const secondsPerDay = 24 * 60 * 60 - checkBenefitStartAt := lastBenefitDate + secondsPerDay - appgood.CancellableBeforeStart - checkBenefitEndAt := lastBenefitDate + secondsPerDay + appgood.CancellableBeforeStart + checkBenefitStartAt := lastBenefitDate + secondsPerDay - h.appGood.CancellableBeforeStart + checkBenefitEndAt := lastBenefitDate + secondsPerDay + h.appGood.CancellableBeforeStart now := uint32(time.Now().Unix()) if checkBenefitStartAt <= now && now <= checkBenefitEndAt { - return fmt.Errorf("invalid cancel in during time") + return fmt.Errorf("invalid cancel in benefit time") } } default: return fmt.Errorf("order state is uncancellable") } default: - return fmt.Errorf("unknown CancelMode type %v", appgood.CancelMode) + return fmt.Errorf("unknown CancelMode type %v", h.appGood.CancelMode) } return nil } -func (h *updateHandler) processStatements(ctx context.Context) error { +func (h *updateHandler) getCommission(ctx context.Context) error { offset := int32(0) limit := int32(1000) //nolint in := ledgertypes.IOType_Incoming for { infos, _, err := statementmwcli.GetStatements(ctx, &statementmwpb.Conds{ - OrderID: &basetypes.StringVal{Op: cruder.EQ, Value: h.ord.ID}, + OrderID: &basetypes.StringVal{Op: cruder.EQ, Value: h.order.ID}, }, offset, limit) if err != nil { return err @@ -153,26 +224,11 @@ func (h *updateHandler) processStatements(ctx context.Context) error { continue } _, total, err := ledgerstatementcli.GetStatements(ctx, &ledgerstatementpb.Conds{ - AppID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: val.AppID, - }, - UserID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: val.UserID, - }, - IOType: &basetypes.Uint32Val{ - Op: cruder.EQ, - Value: uint32(in), - }, - IOSubType: &basetypes.Uint32Val{ - Op: cruder.EQ, - Value: uint32(ledgertypes.IOSubType_Commission), - }, - IOExtra: &basetypes.StringVal{ - Op: cruder.LIKE, - Value: h.ord.ID, - }, + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: val.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: val.UserID}, + IOType: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(in)}, + IOSubType: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(ledgertypes.IOSubType_Commission)}, + IOExtra: &basetypes.StringVal{Op: cruder.LIKE, Value: h.order.ID}, }, 0, 1) if err != nil { return err @@ -208,7 +264,7 @@ func (h *updateHandler) withLockCommission(dispose *dtmcli.SagaDispose) { func (h *updateHandler) withProcessCancel(dispose *dtmcli.SagaDispose) { req := &ordermwpb.OrderReq{ - ID: &h.ord.ID, + ID: &h.order.ID, UserSetCanceled: h.UserSetCanceled, AdminSetCanceled: h.AdminSetCanceled, } @@ -222,68 +278,39 @@ func (h *updateHandler) withProcessCancel(dispose *dtmcli.SagaDispose) { ) } -//nolint:gocyclo func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { - if h.UserSetCanceled == nil && h.AdminSetCanceled == nil { - return nil, fmt.Errorf("nothing todo") + handler := &updateHandler{ + Handler: h, } - - ord, err := ordermwcli.GetOrder(ctx, *h.ID) - if err != nil { + if err := handler.checkCancelParam(); err != nil { return nil, err } - if ord == nil { - return nil, fmt.Errorf("invalid order") - } - - if *h.AppID != ord.AppID || *h.UserID != ord.UserID { - return nil, fmt.Errorf("permission denied") + if err := handler.checkUser(ctx); err != nil { + return nil, err } - if h.UserSetCanceled != nil && !*h.UserSetCanceled { - return h.GetOrder(ctx) + if err := handler.checkOrder(ctx); err != nil { + return nil, err } - if h.AdminSetCanceled != nil && !*h.AdminSetCanceled { - return h.GetOrder(ctx) + if err := handler.checkOrderType(); err != nil { + return nil, err } - - handler := &updateHandler{ - Handler: h, - ord: ord, + if err := handler.getAppGood(ctx); err != nil { + return nil, err } - - switch ord.OrderType { - case ordertypes.OrderType_Normal: - switch ord.OrderState { - case ordertypes.OrderState_OrderStateWaitPayment: - fallthrough //nolint - case ordertypes.OrderState_OrderStateCheckPayment: - if h.AdminSetCanceled != nil { - return nil, fmt.Errorf("permission denied") - } - case ordertypes.OrderState_OrderStatePaid: - case ordertypes.OrderState_OrderStateInService: - } - case ordertypes.OrderType_Offline: - fallthrough //nolint - case ordertypes.OrderType_Airdrop: - if h.AdminSetCanceled == nil { - return nil, fmt.Errorf("permission denied") - } - default: - return nil, fmt.Errorf("order type uncancellable") + if err := handler.checkGood(ctx); err != nil { + return nil, err } - - if err := handler.cancelable(ctx); err != nil { + if err := handler.checkCancelable(ctx); err != nil { return nil, err } - - if err := handler.processStatements(ctx); err != nil { + if err := handler.getCommission(ctx); err != nil { return nil, err } + const timeoutSeconds = 10 sagaDispose := dtmcli.NewSagaDispose(dtmimp.TransOptions{ WaitResult: true, - RequestTimeout: handler.RequestTimeoutSeconds, + RequestTimeout: timeoutSeconds, }) handler.withLockCommission(sagaDispose) From 438121856af734c6ca890cc5b00a52264ad4aced Mon Sep 17 00:00:00 2001 From: jakys Date: Tue, 5 Sep 2023 08:24:46 +0000 Subject: [PATCH 17/67] Fix query --- api/order/query.go | 4 ++-- pkg/order/query.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/order/query.go b/api/order/query.go index af3d96a..df266c3 100644 --- a/api/order/query.go +++ b/api/order/query.go @@ -16,7 +16,7 @@ func (s *Server) GetOrders(ctx context.Context, in *npool.GetOrdersRequest) (*np handler, err := order1.NewHandler( ctx, order1.WithAppID(&in.AppID, true), - order1.WithUserID(&in.AppID, &in.UserID, false), + order1.WithUserID(&in.UserID, true), order1.WithOffset(in.GetOffset()), order1.WithLimit(in.GetLimit()), ) @@ -84,7 +84,7 @@ func (s *Server) GetOrder(ctx context.Context, in *npool.GetOrderRequest) (*npoo ctx, order1.WithID(&in.ID, true), order1.WithAppID(&in.AppID, true), - order1.WithUserID(&in.AppID, &in.UserID, true), + order1.WithUserID(&in.UserID, true), ) if err != nil { logger.Sugar().Errorw( diff --git a/pkg/order/query.go b/pkg/order/query.go index 0f0c54a..2d4ff3b 100644 --- a/pkg/order/query.go +++ b/pkg/order/query.go @@ -123,7 +123,7 @@ func (h *queryHandler) getAppGoods(ctx context.Context) error { Value: goodIDs, }, AppID: &basetypes.StringVal{ - Op: cruder.IN, + Op: cruder.EQ, Value: *h.AppID, }, }, 0, int32(len(goodIDs))) From f6e14ea9ad00d705dfdd75d3731006baf037e36f Mon Sep 17 00:00:00 2001 From: jakys Date: Tue, 5 Sep 2023 08:30:23 +0000 Subject: [PATCH 18/67] Fix create --- pkg/order/creates.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pkg/order/creates.go b/pkg/order/creates.go index 3942263..8980f2e 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -45,7 +45,6 @@ import ( type createsHandler struct { *Handler - mainOrderID *string ids map[string]*string user *usermwpb.User appGoods map[string]*appgoodmwpb.Good @@ -644,7 +643,7 @@ func (h *createsHandler) withCreateOrders(dispose *dtmcli.SagaDispose) { req.PaymentStartAmount = &paymentStartAmount } } else { - req.ParentOrderID = h.mainOrderID + req.ParentOrderID = h.ParentOrderID childPaymentType := types.PaymentType_PayWithParentOrder req.PaymentType = &childPaymentType } @@ -801,12 +800,12 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e id := uuid.NewString() handler.ids[order.AppGoodID] = &id if order.Parent { - handler.mainOrderID = &id + h.ParentOrderID = &id } h.IDs = append(h.IDs, id) } - key := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, handler.mainOrderID) + key := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, h.ParentOrderID) if err := redis2.TryLock(key, 0); err != nil { return nil, err } From 3c892ad912c0409c387e713edb98726560becd3f Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Tue, 5 Sep 2023 09:56:47 +0000 Subject: [PATCH 19/67] Format code --- pkg/order/create.go | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/pkg/order/create.go b/pkg/order/create.go index c23fe6b..d1c2755 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -11,6 +11,7 @@ import ( appcoinmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/app/coin" currencymwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin/currency" dtmcli "github.com/NpoolPlatform/dtm-cluster/pkg/dtm" + timedef "github.com/NpoolPlatform/go-service-framework/pkg/const/time" redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" topmostmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/topmost/good" @@ -546,6 +547,20 @@ func (h *createHandler) tomorrowStart() time.Time { return time.Date(y, m, d+1, 0, 0, 0, 0, now.Location()) } +func (h *createHandler) resolveStartEnd() { + goodStartAt := h.appGood.ServiceStartAt + if h.appGood.ServiceStartAt == 0 { + goodStartAt = h.appGood.StartAt + } + goodDurationDays := uint32(h.appGood.DurationDays) + h.orderStartAt = uint32(h.tomorrowStart().Unix()) + if goodStartAt > h.orderStartAt { + h.orderStartAt = goodStartAt + } + const secondsPerDay = timedef.SecondsPerDay + h.orderEndAt = h.orderStartAt + goodDurationDays*secondsPerDay +} + func (h *createHandler) withCreateOrder(dispose *dtmcli.SagaDispose) { goodValueCoinAmount := h.goodValueCoinAmount.String() goodValueUSDTAmount := h.goodValueUSDTAmount.String() @@ -556,18 +571,7 @@ func (h *createHandler) withCreateOrder(dispose *dtmcli.SagaDispose) { coinUSDCurrency := h.coinCurrencyAmount.String() localCoinUSDCurrency := h.localCurrencyAmount.String() liveCoinUSDCurrency := h.liveCurrencyAmount.String() - - goodStartAt := h.appGood.ServiceStartAt - if h.appGood.ServiceStartAt == 0 { - goodStartAt = h.appGood.StartAt - } goodDurationDays := uint32(h.appGood.DurationDays) - h.orderStartAt = uint32(h.tomorrowStart().Unix()) - if goodStartAt > h.orderStartAt { - h.orderStartAt = goodStartAt - } - const secondsPerDay = 24 * 60 * 60 - h.orderEndAt = h.orderStartAt + goodDurationDays*secondsPerDay req := &ordermwpb.OrderReq{ ID: h.ID, @@ -716,6 +720,7 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error } handler.resolvePaymentType() handler.resolveStartMode() + handler.resolveStartEnd() if err := handler.peekPaymentAddress(ctx); err != nil { return nil, err From fa2c5da2758c83a5d251e7d23a6f0728f4c034c8 Mon Sep 17 00:00:00 2001 From: jakys Date: Tue, 5 Sep 2023 10:15:56 +0000 Subject: [PATCH 20/67] Fix creates --- pkg/order/creates.go | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/pkg/order/creates.go b/pkg/order/creates.go index 8980f2e..50edf2f 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -67,7 +67,6 @@ type createsHandler struct { transferCoinAmount decimal.Decimal paymentType types.PaymentType orderStartMode map[string]types.OrderStartMode - goodDurationDays map[string]uint32 orderStartAt map[string]uint32 orderEndAt map[string]uint32 } @@ -530,7 +529,7 @@ func (h *createsHandler) getPaymentStartAmount(ctx context.Context) error { return err } -func (h *createsHandler) checkOrderDuration() { +func (h *createsHandler) resolveStartEnd() { for _, order := range h.Orders { appGood := h.appGoods[order.AppGoodID] goodStartAt := appGood.ServiceStartAt @@ -545,7 +544,6 @@ func (h *createsHandler) checkOrderDuration() { const secondsPerDay = 24 * 60 * 60 h.orderEndAt[order.AppGoodID] = orderStartAt + goodDurationDays*secondsPerDay h.orderStartAt[order.AppGoodID] = orderStartAt - h.goodDurationDays[order.AppGoodID] = goodDurationDays } } @@ -604,7 +602,7 @@ func (h *createsHandler) withCreateOrders(dispose *dtmcli.SagaDispose) { orderStartAt := h.orderStartAt[order.AppGoodID] orderEndAt := h.orderEndAt[order.AppGoodID] startMode := h.orderStartMode[order.AppGoodID] - goodDurationDays := h.goodDurationDays[order.AppGoodID] + goodDurationDays := uint32(h.appGoods[order.AppGoodID].DurationDays) req := &ordermwpb.OrderReq{ ID: h.ids[order.AppGoodID], @@ -682,8 +680,7 @@ func (h *createsHandler) withLockPaymentAccount(dispose *dtmcli.SagaDispose) { ) } -func (h *createsHandler) checkGoodRequests(ctx context.Context) error { - goodSet := make(map[string]struct{}) +func (h *createsHandler) getGoodRequests(ctx context.Context) error { for _, order := range h.Orders { appgood := h.appGoods[order.AppGoodID] if order.Parent { @@ -694,11 +691,13 @@ func (h *createsHandler) checkGoodRequests(ctx context.Context) error { return err } h.goodRequireds = goodRequireds - continue + break } - goodSet[appgood.GoodID] = struct{}{} } + return nil +} +func (h *createsHandler) checkGoodsInRequests() error { requiredSet := make(map[string]struct{}) for _, goodRequired := range h.goodRequireds { requiredSet[goodRequired.RequiredGoodID] = struct{}{} @@ -713,7 +712,15 @@ func (h *createsHandler) checkGoodRequests(ctx context.Context) error { return fmt.Errorf("invalid goodrequired") } } + return nil +} +func (h *createsHandler) checkMustRequestsInGoods() error { + goodSet := make(map[string]struct{}) + for _, order := range h.Orders { + appgood := h.appGoods[order.AppGoodID] + goodSet[appgood.GoodID] = struct{}{} + } for _, goodRequired := range h.goodRequireds { if goodRequired.Must { if _, ok := goodSet[goodRequired.RequiredGoodID]; !ok { @@ -750,7 +757,13 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e if err := handler.checkUnitsLimit(ctx); err != nil { return nil, err } - if err := handler.checkGoodRequests(ctx); err != nil { + if err := handler.getGoodRequests(ctx); err != nil { + return nil, err + } + if err := handler.checkGoodsInRequests(); err != nil { + return nil, err + } + if err := handler.checkMustRequestsInGoods(); err != nil { return nil, err } if err := handler.getAppGoodPromotions(ctx); err != nil { @@ -776,7 +789,7 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e } handler.resolvePaymentType() handler.resolveStartMode() - handler.checkOrderDuration() + handler.resolveStartEnd() if err := handler.peekPaymentAddress(ctx); err != nil { return nil, err From 9355dd42b8e0f9ac663321c67e99320663e4e3ff Mon Sep 17 00:00:00 2001 From: jakys Date: Wed, 6 Sep 2023 03:13:17 +0000 Subject: [PATCH 21/67] Fix balance amount --- api/order/create.go | 2 +- pkg/order/handler.go | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/api/order/create.go b/api/order/create.go index 34ec10f..48b0a57 100644 --- a/api/order/create.go +++ b/api/order/create.go @@ -26,7 +26,7 @@ func (s *Server) CreateOrder(ctx context.Context, in *npool.CreateOrderRequest) order1.WithPaymentCoinID(&in.PaymentCoinID, true), order1.WithParentOrderID(in.ParentOrderID, false), order1.WithOrderType(&orderType, true), - order1.WithBalanceAmount(in.GetPayWithBalanceAmount(), false), + order1.WithBalanceAmount(in.PayWithBalanceAmount, false), order1.WithCouponIDs(in.CouponIDs, false), ) if err != nil { diff --git a/pkg/order/handler.go b/pkg/order/handler.go index 6110b8c..0093865 100644 --- a/pkg/order/handler.go +++ b/pkg/order/handler.go @@ -177,16 +177,22 @@ func WithUnits(amount string, must bool) func(context.Context, *Handler) error { } } -func WithBalanceAmount(amount string, must bool) func(context.Context, *Handler) error { +func WithBalanceAmount(amount *string, must bool) func(context.Context, *Handler) error { return func(ctx context.Context, h *Handler) error { - _amount, err := decimal.NewFromString(amount) + if amount == nil { + if must { + return fmt.Errorf("invalid parentorderid") + } + return nil + } + _amount, err := decimal.NewFromString(*amount) if err != nil { return err } if _amount.Cmp(decimal.NewFromInt32(0)) <= 0 { return fmt.Errorf("units is 0") } - h.BalanceAmount = &amount + h.BalanceAmount = amount return nil } } From a0cdce232755164bf81b8b6b758a0ab95106fd16 Mon Sep 17 00:00:00 2001 From: jakys Date: Wed, 6 Sep 2023 08:29:45 +0000 Subject: [PATCH 22/67] Fix create --- api/order/create.go | 3 +++ go.mod | 2 +- go.sum | 4 ++-- pkg/order/create.go | 11 ++++++++--- pkg/order/creates.go | 9 ++++++--- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/api/order/create.go b/api/order/create.go index 48b0a57..295a03d 100644 --- a/api/order/create.go +++ b/api/order/create.go @@ -28,6 +28,7 @@ func (s *Server) CreateOrder(ctx context.Context, in *npool.CreateOrderRequest) order1.WithOrderType(&orderType, true), order1.WithBalanceAmount(in.PayWithBalanceAmount, false), order1.WithCouponIDs(in.CouponIDs, false), + order1.WithInvestmentType(&in.InvestmentType, true), ) if err != nil { logger.Sugar().Errorw( @@ -70,6 +71,7 @@ func (s *Server) CreateUserOrder(ctx context.Context, in *npool.CreateUserOrderR order1.WithPaymentCoinID(&in.PaymentCoinID, true), order1.WithParentOrderID(in.ParentOrderID, false), order1.WithOrderType(&in.OrderType, true), + order1.WithInvestmentType(&in.InvestmentType, true), ) if err != nil { logger.Sugar().Errorw( @@ -112,6 +114,7 @@ func (s *Server) CreateAppUserOrder(ctx context.Context, in *npool.CreateAppUser order1.WithPaymentCoinID(&in.PaymentCoinID, true), order1.WithParentOrderID(in.ParentOrderID, false), order1.WithOrderType(&in.OrderType, true), + order1.WithInvestmentType(&in.InvestmentType, true), ) if err != nil { logger.Sugar().Errorw( diff --git a/go.mod b/go.mod index 896f1c4..a57f566 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/NpoolPlatform/appuser-middleware v0.0.0-20230513100509-b19f356ebd4b github.com/NpoolPlatform/basal-middleware v0.0.0-20230518061816-62bd589c0f63 github.com/NpoolPlatform/chain-middleware v0.0.0-20230712041523-2e1d215244e0 - github.com/NpoolPlatform/dtm-cluster v0.0.0-20230518062456-3e53bebe90da + github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821 github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e github.com/NpoolPlatform/good-middleware v0.0.0-20230905075718-a4cefe1bff92 github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 diff --git a/go.sum b/go.sum index be29a64..c10eb63 100644 --- a/go.sum +++ b/go.sum @@ -56,8 +56,8 @@ github.com/NpoolPlatform/basal-middleware v0.0.0-20230518061816-62bd589c0f63 h1: github.com/NpoolPlatform/basal-middleware v0.0.0-20230518061816-62bd589c0f63/go.mod h1:3sHDVUUQHRkZsCiBFI6CdCL2HWf3cO7/E2DZU3nHMfE= github.com/NpoolPlatform/chain-middleware v0.0.0-20230712041523-2e1d215244e0 h1:xD+68nDsw/P0rXd1fzr/wip24bkpYzwrXGBFwSvXkbs= github.com/NpoolPlatform/chain-middleware v0.0.0-20230712041523-2e1d215244e0/go.mod h1:ExILdqBVnhspnOZFslJl0vTOc4Qyk78Lni1Kx2F8HGM= -github.com/NpoolPlatform/dtm-cluster v0.0.0-20230518062456-3e53bebe90da h1:ed2RLOcRnzjDv8Qr6km0xiq1CyoZxBkB5gZrR2spILc= -github.com/NpoolPlatform/dtm-cluster v0.0.0-20230518062456-3e53bebe90da/go.mod h1:I0UKoN/HU1p1RmpCYSramNbGCrd/EM7/fH6zhSUspkM= +github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821 h1:JEoN8rpjyJOpbXXLhL5J6Fjw+/bOTwMNci6CL7G02zQ= +github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821/go.mod h1:ZBvGIj+zt7VT6WbnIeU/fhiI/dEoNK4JqcXE1EIblpQ= github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e h1:17BGexCmCdOOBXKYogP8RNE+pAHRu2N4LKq9znPJ4vc= github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e/go.mod h1:Kh7DMkWnYOMHxEKq7QfJqbxm1HaUPkhTNN74lfHQxyE= github.com/NpoolPlatform/good-middleware v0.0.0-20230905075718-a4cefe1bff92 h1:C0j0tYpVA+bTubq4QnYltvrdUSoMLAsI2ALBgj/Qgm8= diff --git a/pkg/order/create.go b/pkg/order/create.go index d1c2755..cfd9bd7 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -7,6 +7,7 @@ import ( payaccmwcli "github.com/NpoolPlatform/account-middleware/pkg/client/payment" accountlock "github.com/NpoolPlatform/account-middleware/pkg/lock" + accountmwsvcname "github.com/NpoolPlatform/account-middleware/pkg/servicename" usermwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" appcoinmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/app/coin" currencymwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin/currency" @@ -15,7 +16,9 @@ import ( redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" topmostmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/topmost/good" + goodmwsvcname "github.com/NpoolPlatform/good-middleware/pkg/servicename" allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" + ledgermwsvcname "github.com/NpoolPlatform/ledger-middleware/pkg/servicename" cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" payaccmwpb "github.com/NpoolPlatform/message/npool/account/mw/v1/payment" usermwpb "github.com/NpoolPlatform/message/npool/appuser/mw/v1/user" @@ -506,11 +509,13 @@ func (h *createHandler) getPaymentStartAmount(ctx context.Context) error { func (h *createHandler) withUpdateStock(dispose *dtmcli.SagaDispose) { req := &appgoodstockmwpb.StockReq{ + ID: &h.appGood.AppGoodStockID, + GoodID: &h.appGood.GoodID, AppGoodID: h.AppGoodID, Locked: &h.Units, } dispose.Add( - ordermwsvcname.ServiceDomain, + goodmwsvcname.ServiceDomain, "good.middleware.app.good1.stock.v1.Middleware/AddStock", "good.middleware.app.good1.stock.v1.Middleware/SubStock", &appgoodstockmwpb.AddStockRequest{ @@ -532,7 +537,7 @@ func (h *createHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { Spendable: &amount, } dispose.Add( - ordermwsvcname.ServiceDomain, + ledgermwsvcname.ServiceDomain, "ledger.middleware.ledger.v2.Middleware/SubBalance", "ledger.middleware.ledger.v2.Middleware/AddBalance", &ledgermwpb.AddBalanceRequest{ @@ -632,7 +637,7 @@ func (h *createHandler) withLockPaymentAccount(dispose *dtmcli.SagaDispose) { LockedBy: &lockedBy, } dispose.Add( - ordermwsvcname.ServiceDomain, + accountmwsvcname.ServiceDomain, "account.middleware.payment.v1.Middleware/UpdateAccount", "", &payaccmwpb.UpdateAccountRequest{ diff --git a/pkg/order/creates.go b/pkg/order/creates.go index 50edf2f..33ccf18 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -7,6 +7,7 @@ import ( payaccmwcli "github.com/NpoolPlatform/account-middleware/pkg/client/payment" accountlock "github.com/NpoolPlatform/account-middleware/pkg/lock" + accountmwsvcname "github.com/NpoolPlatform/account-middleware/pkg/servicename" usermwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" appcoinmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/app/coin" currencymwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin/currency" @@ -15,7 +16,9 @@ import ( appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" topmostmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/topmost/good" goodrequiredmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good/required" + goodmwsvcname "github.com/NpoolPlatform/good-middleware/pkg/servicename" allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" + ledgermwsvcname "github.com/NpoolPlatform/ledger-middleware/pkg/servicename" cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" payaccmwpb "github.com/NpoolPlatform/message/npool/account/mw/v1/payment" usermwpb "github.com/NpoolPlatform/message/npool/appuser/mw/v1/user" @@ -554,7 +557,7 @@ func (h *createsHandler) withUpdateStock(dispose *dtmcli.SagaDispose) { Locked: &h.Units, } dispose.Add( - ordermwsvcname.ServiceDomain, + goodmwsvcname.ServiceDomain, "good.middleware.app.good1.stock.v1.Middleware/AddStock", "good.middleware.app.good1.stock.v1.Middleware/SubStock", &appgoodstockmwpb.AddStockRequest{ @@ -577,7 +580,7 @@ func (h *createsHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { Spendable: &amount, } dispose.Add( - ordermwsvcname.ServiceDomain, + ledgermwsvcname.ServiceDomain, "ledger.middleware.ledger.v2.Middleware/SubBalance", "ledger.middleware.ledger.v2.Middleware/AddBalance", &ledgermwpb.AddBalanceRequest{ @@ -671,7 +674,7 @@ func (h *createsHandler) withLockPaymentAccount(dispose *dtmcli.SagaDispose) { LockedBy: &lockedBy, } dispose.Add( - ordermwsvcname.ServiceDomain, + accountmwsvcname.ServiceDomain, "account.middleware.payment.v1.Middleware/UpdateAccount", "", &payaccmwpb.UpdateAccountRequest{ From 8b2eb540245968c86d36ccb2abb60f56aa4a5f67 Mon Sep 17 00:00:00 2001 From: jakys Date: Wed, 6 Sep 2023 12:32:59 +0000 Subject: [PATCH 23/67] Fix create --- api/order/create.go | 37 +++++++++++++++++++++++++++++++++++++ pkg/order/creates.go | 32 +++++++++++++++++++++++--------- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/api/order/create.go b/api/order/create.go index 295a03d..e47977a 100644 --- a/api/order/create.go +++ b/api/order/create.go @@ -139,3 +139,40 @@ func (s *Server) CreateAppUserOrder(ctx context.Context, in *npool.CreateAppUser Info: info, }, nil } + +func (s *Server) CreateOrders(ctx context.Context, in *npool.CreateOrdersRequest) (*npool.CreateOrdersResponse, error) { + orderType := ordertypes.OrderType_Normal + handler, err := order1.NewHandler( + ctx, + order1.WithAppID(&in.AppID, true), + order1.WithUserID(&in.UserID, true), + order1.WithPaymentCoinID(&in.PaymentCoinID, true), + order1.WithOrderType(&orderType, true), + order1.WithBalanceAmount(in.PayWithBalanceAmount, false), + order1.WithCouponIDs(in.CouponIDs, false), + order1.WithInvestmentType(&in.InvestmentType, true), + order1.WithOrders(in.Orders, true), + ) + if err != nil { + logger.Sugar().Errorw( + "CreateOrders", + "In", in, + "Error", err, + ) + return &npool.CreateOrdersResponse{}, status.Error(codes.InvalidArgument, err.Error()) + } + + infos, err := handler.CreateOrders(ctx) + if err != nil { + logger.Sugar().Errorw( + "CreateOrders", + "In", in, + "Error", err, + ) + return &npool.CreateOrdersResponse{}, status.Error(codes.Internal, err.Error()) + } + + return &npool.CreateOrdersResponse{ + Infos: infos, + }, nil +} diff --git a/pkg/order/creates.go b/pkg/order/creates.go index 33ccf18..89a2b90 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -183,7 +183,7 @@ func (h *createsHandler) checkUnitsLimit(ctx context.Context) error { } for _, order := range h.Orders { appGood := h.appGoods[order.AppGoodID] - units, err := decimal.NewFromString(h.Units) + units, err := decimal.NewFromString(order.Units) if err != nil { return err } @@ -270,8 +270,10 @@ func (h *createsHandler) calculateOrderUSDTPrice() error { promotion := h.promotions[order.AppGoodID] if promotion == nil { h.goodValueUSDTAmount[order.AppGoodID] = amount.Mul(units) + h.goodValueCoinAmount[order.AppGoodID] = h.goodValueUSDTAmount[order.AppGoodID].Div(h.coinCurrencyAmount) + h.goodValueCoinAmount[order.AppGoodID] = h.getAccuracy(h.goodValueCoinAmount[order.AppGoodID]) h.paymentUSDTAmount = h.paymentUSDTAmount.Add(h.goodValueUSDTAmount[order.AppGoodID]) - return nil + continue } amount, err = decimal.NewFromString(promotion.Price) if err != nil { @@ -552,9 +554,12 @@ func (h *createsHandler) resolveStartEnd() { func (h *createsHandler) withUpdateStock(dispose *dtmcli.SagaDispose) { for _, order := range h.Orders { + appGood := h.appGoods[order.AppGoodID] req := &appgoodstockmwpb.StockReq{ + ID: &appGood.AppGoodStockID, + GoodID: &appGood.GoodID, AppGoodID: &order.AppGoodID, - Locked: &h.Units, + Locked: &order.Units, } dispose.Add( goodmwsvcname.ServiceDomain, @@ -612,8 +617,8 @@ func (h *createsHandler) withCreateOrders(dispose *dtmcli.SagaDispose) { AppID: h.AppID, UserID: h.UserID, GoodID: &h.appGoods[order.AppGoodID].GoodID, - AppGoodID: h.AppGoodID, - Units: &h.Units, + AppGoodID: &order.AppGoodID, + Units: &order.Units, GoodValue: &goodValueCoinAmount, GoodValueUSD: &goodValueUSDTAmount, DurationDays: &goodDurationDays, @@ -737,7 +742,16 @@ func (h *createsHandler) checkMustRequestsInGoods() error { //nolint:funlen,gocyclo func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err error) { handler := &createsHandler{ - Handler: h, + Handler: h, + ids: map[string]*string{}, + appGoods: map[string]*appgoodmwpb.Good{}, + coupons: map[string]*allocatedmwpb.Coupon{}, + promotions: map[string]*topmostmwpb.TopMostGood{}, + goodValueUSDTAmount: map[string]decimal.Decimal{}, + goodValueCoinAmount: map[string]decimal.Decimal{}, + orderStartMode: map[string]types.OrderStartMode{}, + orderStartAt: map[string]uint32{}, + orderEndAt: map[string]uint32{}, } if err := handler.getUser(ctx); err != nil { return nil, err @@ -772,6 +786,9 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e if err := handler.getAppGoodPromotions(ctx); err != nil { return nil, err } + if err := handler.checkPaymentCoinCurrency(ctx); err != nil { + return nil, err + } if err := handler.calculateOrderUSDTPrice(); err != nil { return nil, err } @@ -781,9 +798,6 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e if err := handler.calculateFixAmountCouponReduction(); err != nil { return nil, err } - if err := handler.checkPaymentCoinCurrency(ctx); err != nil { - return nil, err - } if err := handler.checkPaymentCoinAmount(); err != nil { return nil, err } From 87766897b2220e6953b9365d761d7a4ac6dd4241 Mon Sep 17 00:00:00 2001 From: jakys Date: Wed, 6 Sep 2023 13:25:53 +0000 Subject: [PATCH 24/67] Fix update --- pkg/order/update.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pkg/order/update.go b/pkg/order/update.go index 4b9f79a..c9ecae1 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -79,6 +79,9 @@ func (h *updateHandler) checkOrder(ctx context.Context) error { if *h.AppID != order.AppID || *h.UserID != order.UserID { return fmt.Errorf("permission denied") } + if order.PaymentType == ordertypes.PaymentType_PayWithParentOrder { + return fmt.Errorf("permission denied") + } h.order = order return nil } @@ -95,6 +98,8 @@ func (h *updateHandler) checkOrderType() error { } case ordertypes.OrderState_OrderStatePaid: case ordertypes.OrderState_OrderStateInService: + default: + return fmt.Errorf("orderstate uncancellable") } case ordertypes.OrderType_Offline: fallthrough //nolint @@ -102,6 +107,12 @@ func (h *updateHandler) checkOrderType() error { if h.AdminSetCanceled == nil { return fmt.Errorf("permission denied") } + switch h.order.OrderState { + case ordertypes.OrderState_OrderStatePaid: + case ordertypes.OrderState_OrderStateInService: + default: + return fmt.Errorf("orderstate uncancellable") + } default: return fmt.Errorf("order type uncancellable") } @@ -156,6 +167,7 @@ func (h *updateHandler) checkCancelable(ctx context.Context) error { switch h.order.OrderState { case ordertypes.OrderState_OrderStateWaitPayment: + fallthrough //nolint case ordertypes.OrderState_OrderStateCheckPayment: if len(goodStatements) > 0 { return fmt.Errorf("had statements can not cancel") From 687a195c88056caff6155aedd76e5389c09dad4b Mon Sep 17 00:00:00 2001 From: jakys Date: Wed, 6 Sep 2023 14:59:30 +0000 Subject: [PATCH 25/67] Fix query --- go.mod | 2 +- go.sum | 4 +- pkg/order/query.go | 102 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 88 insertions(+), 20 deletions(-) diff --git a/go.mod b/go.mod index a57f566..c31f8cc 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7 github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 - github.com/NpoolPlatform/message v0.0.0-20230905072308-dd83f725a380 + github.com/NpoolPlatform/message v0.0.0-20230906142354-ac8156431b42 github.com/NpoolPlatform/order-middleware v0.0.0-20230905020518-f7a7139425b8 github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/dtm-labs/dtm v1.17.1 diff --git a/go.sum b/go.sum index c10eb63..67eb1d8 100644 --- a/go.sum +++ b/go.sum @@ -68,8 +68,8 @@ github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7 h1 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7/go.mod h1:lgAX07sFIVb9LnOJPCt9OMZRVLWqefnk+LBaSaCrWkM= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB4NuhQxXWeV0Z1qSxgIqbiMYU30dqFGDLtgNTqYbE= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= -github.com/NpoolPlatform/message v0.0.0-20230905072308-dd83f725a380 h1:PZfTh2RIj5EPVbiylo2sPCRP2H94GpG3zoHbsKNJ/wc= -github.com/NpoolPlatform/message v0.0.0-20230905072308-dd83f725a380/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/message v0.0.0-20230906142354-ac8156431b42 h1:ikWSI7gva1moRxD8dHkVQ/J80L1yNNtlgvahmY+vnX4= +github.com/NpoolPlatform/message v0.0.0-20230906142354-ac8156431b42/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= github.com/NpoolPlatform/order-middleware v0.0.0-20230905020518-f7a7139425b8 h1:/9r/Ed8TPCOBdw3iqZ21TU0yxZtjuvyzJl92ztfTGU8= github.com/NpoolPlatform/order-middleware v0.0.0-20230905020518-f7a7139425b8/go.mod h1:tJJvB9QFPn4NYWWsSorvJBc8ur9FlWNAEAM1wCuzPz8= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= diff --git a/pkg/order/query.go b/pkg/order/query.go index 2d4ff3b..8935b95 100644 --- a/pkg/order/query.go +++ b/pkg/order/query.go @@ -27,6 +27,7 @@ import ( cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" + types "github.com/NpoolPlatform/message/npool/basetypes/order/v1" basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" "github.com/google/uuid" @@ -37,7 +38,9 @@ type queryHandler struct { orders []*ordermwpb.Order infos []*npool.Order users map[string]*usermwpb.User + parentOrders map[string]*ordermwpb.Order appGoods map[string]*appgoodsmwpb.Good + parentAppGoods map[string]*appgoodsmwpb.Good accountPayments map[string]*payaccmwpb.Account coupons map[string]*allocatedmwpb.Coupon coins map[string]*appcoinmwpb.Coin @@ -51,7 +54,8 @@ func (h *queryHandler) getUsers(ctx context.Context) error { uids = append(uids, ord.UserID) } users, _, err := usermwcli.GetUsers(ctx, &usermwpb.Conds{ - IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: uids}, + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: uids}, }, 0, int32(len(uids))) if err != nil { return err @@ -111,6 +115,26 @@ func (h *queryHandler) getCoupons(ctx context.Context) error { return nil } +func (h *queryHandler) getParentOrders(ctx context.Context) error { + ids := []string{} + for _, ord := range h.orders { + if ord.ParentOrderID != uuid.Nil.String() { + ids = append(ids, ord.ParentOrderID) + } + } + orders, _, err := ordercli.GetOrders(ctx, &ordermwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: ids}, + }, h.Offset, h.Limit) + if err != nil { + return err + } + for _, order := range orders { + h.parentOrders[order.ID] = order + } + return nil +} + func (h *queryHandler) getAppGoods(ctx context.Context) error { goodIDs := []string{} for _, val := range h.orders { @@ -118,14 +142,8 @@ func (h *queryHandler) getAppGoods(ctx context.Context) error { } appGoods, _, err := appgoodscli.GetGoods(ctx, &appgoodsmwpb.Conds{ - GoodIDs: &basetypes.StringSliceVal{ - Op: cruder.IN, - Value: goodIDs, - }, - AppID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.AppID, - }, + GoodIDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: goodIDs}, + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, }, 0, int32(len(goodIDs))) if err != nil { return err @@ -137,6 +155,29 @@ func (h *queryHandler) getAppGoods(ctx context.Context) error { return nil } +func (h *queryHandler) getParentAppGoods(ctx context.Context) error { + goodIDs := []string{} + for _, val := range h.parentOrders { + goodIDs = append(goodIDs, val.GetGoodID()) + } + if len(goodIDs) == 0 { + return nil + } + + appGoods, _, err := appgoodscli.GetGoods(ctx, &appgoodsmwpb.Conds{ + GoodIDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: goodIDs}, + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + }, 0, int32(len(goodIDs))) + if err != nil { + return err + } + + for _, appGood := range appGoods { + h.parentAppGoods[appGood.AppID+appGood.GoodID] = appGood + } + return nil +} + func (h *queryHandler) getCoins(ctx context.Context) error { coinTypeIDs := []string{} for _, val := range h.orders { @@ -153,14 +194,8 @@ func (h *queryHandler) getCoins(ctx context.Context) error { } coins, _, err := appcoinmwcli.GetCoins(ctx, &appcoinmwpb.Conds{ - AppID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: *h.AppID, - }, - CoinTypeIDs: &basetypes.StringSliceVal{ - Op: cruder.IN, - Value: coinTypeIDs, - }, + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + CoinTypeIDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: coinTypeIDs}, }, 0, int32(len(coinTypeIDs))) if err != nil { return err @@ -194,10 +229,14 @@ func (h *queryHandler) formalize(ctx context.Context) { //nolint PaymentFinishAmount: ord.PaymentFinishAmount, PayWithBalanceAmount: ord.BalanceAmount, OrderType: ord.OrderType, + PaymentType: ord.PaymentType, CreatedAt: ord.CreatedAt, State: ord.OrderState, StartAt: ord.StartAt, EndAt: ord.EndAt, + InvestmentType: ord.InvestmentType, + LastBenefitAt: ord.LastBenefitAt, + PaidAt: ord.PaidAt, } user, ok := h.users[ord.UserID] @@ -231,6 +270,7 @@ func (h *queryHandler) formalize(ctx context.Context) { //nolint info.CoinName = coin.Name info.CoinLogo = coin.Logo info.CoinUnit = coin.Unit + info.CoinPresale = coin.Presale if ord.PaymentID != invalidID && ord.PaymentID != "" { coin, ok = h.coins[ord.PaymentCoinTypeID] @@ -265,6 +305,21 @@ func (h *queryHandler) formalize(ctx context.Context) { //nolint }) } + if ord.ParentOrderID != uuid.Nil.String() { + porder, ok := h.parentOrders[ord.ParentOrderID] + if ok { + info.ParentOrderGoodID = porder.GoodID + pgood, ok := h.parentAppGoods[ord.AppID+porder.GoodID] + if ok { + info.ParentOrderGoodName = pgood.GoodName + } + } + } + + if ord.PaymentType == types.PaymentType_PayWithParentOrder { + info.PayWithParent = true + } + infos = append(infos, info) } h.infos = infos @@ -292,6 +347,12 @@ func (h *Handler) GetOrder(ctx context.Context) (*npool.Order, error) { if err := handler.getUsers(ctx); err != nil { return nil, err } + if err := handler.getParentOrders(ctx); err != nil { + return nil, err + } + if err := handler.getParentAppGoods(ctx); err != nil { + return nil, err + } if err := handler.getAppGoods(ctx); err != nil { return nil, err } @@ -337,6 +398,7 @@ func (h *Handler) GetOrders(ctx context.Context) ([]*npool.Order, uint32, error) orders: ords, infos: []*npool.Order{}, users: map[string]*usermwpb.User{}, + parentOrders: map[string]*ordermwpb.Order{}, appGoods: map[string]*appgoodsmwpb.Good{}, accountPayments: map[string]*payaccmwpb.Account{}, coupons: map[string]*allocatedmwpb.Coupon{}, @@ -345,6 +407,12 @@ func (h *Handler) GetOrders(ctx context.Context) ([]*npool.Order, uint32, error) if err := handler.getUsers(ctx); err != nil { return nil, 0, err } + if err := handler.getParentOrders(ctx); err != nil { + return nil, 0, err + } + if err := handler.getParentAppGoods(ctx); err != nil { + return nil, 0, err + } if err := handler.getAppGoods(ctx); err != nil { return nil, 0, err } From 0a99cfff5fbd79303ea49d94d3824a5cc390e799 Mon Sep 17 00:00:00 2001 From: jakys Date: Wed, 6 Sep 2023 15:03:12 +0000 Subject: [PATCH 26/67] Fix map --- pkg/order/query.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/order/query.go b/pkg/order/query.go index 8935b95..9e4cb3f 100644 --- a/pkg/order/query.go +++ b/pkg/order/query.go @@ -339,6 +339,7 @@ func (h *Handler) GetOrder(ctx context.Context) (*npool.Order, error) { orders: []*ordermwpb.Order{order}, infos: []*npool.Order{}, users: map[string]*usermwpb.User{}, + parentOrders: map[string]*ordermwpb.Order{}, appGoods: map[string]*appgoodsmwpb.Good{}, accountPayments: map[string]*payaccmwpb.Account{}, coupons: map[string]*allocatedmwpb.Coupon{}, From ba192d0728d87170d11ef90184d53e9e89d413fa Mon Sep 17 00:00:00 2001 From: jakys Date: Thu, 7 Sep 2023 01:06:26 +0000 Subject: [PATCH 27/67] Fix map --- pkg/order/query.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/order/query.go b/pkg/order/query.go index 9e4cb3f..d6ec915 100644 --- a/pkg/order/query.go +++ b/pkg/order/query.go @@ -340,6 +340,7 @@ func (h *Handler) GetOrder(ctx context.Context) (*npool.Order, error) { infos: []*npool.Order{}, users: map[string]*usermwpb.User{}, parentOrders: map[string]*ordermwpb.Order{}, + parentAppGoods: map[string]*appgoodsmwpb.Good{}, appGoods: map[string]*appgoodsmwpb.Good{}, accountPayments: map[string]*payaccmwpb.Account{}, coupons: map[string]*allocatedmwpb.Coupon{}, @@ -400,6 +401,7 @@ func (h *Handler) GetOrders(ctx context.Context) ([]*npool.Order, uint32, error) infos: []*npool.Order{}, users: map[string]*usermwpb.User{}, parentOrders: map[string]*ordermwpb.Order{}, + parentAppGoods: map[string]*appgoodsmwpb.Good{}, appGoods: map[string]*appgoodsmwpb.Good{}, accountPayments: map[string]*payaccmwpb.Account{}, coupons: map[string]*allocatedmwpb.Coupon{}, From 4866c7defe6148b79f0e7d46cf3814e00a5d253b Mon Sep 17 00:00:00 2001 From: jakys Date: Thu, 7 Sep 2023 06:04:18 +0000 Subject: [PATCH 28/67] Fix paymenttype --- pkg/order/create.go | 2 +- pkg/order/creates.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/order/create.go b/pkg/order/create.go index cfd9bd7..4852a18 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -379,7 +379,7 @@ func (h *createHandler) checkTransferCoinAmount() error { func (h *createHandler) resolvePaymentType() { if h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 && //nolint - h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 { + h.balanceCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 { h.paymentType = types.PaymentType_PayWithNoPayment return } diff --git a/pkg/order/creates.go b/pkg/order/creates.go index 89a2b90..eb0678e 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -403,7 +403,7 @@ func (h *createsHandler) checkTransferCoinAmount() error { func (h *createsHandler) resolvePaymentType() { if h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 && //nolint - h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 { + h.balanceCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 { h.paymentType = types.PaymentType_PayWithNoPayment return } From c2cccbce9c3ee85e1e9002d0219bc91467fb1454 Mon Sep 17 00:00:00 2001 From: jakys Date: Fri, 8 Sep 2023 02:08:40 +0000 Subject: [PATCH 29/67] Fix verify --- go.mod | 2 +- go.sum | 4 ++-- pkg/order/create.go | 2 +- pkg/order/creates.go | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index c31f8cc..a4403e4 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7 github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 github.com/NpoolPlatform/message v0.0.0-20230906142354-ac8156431b42 - github.com/NpoolPlatform/order-middleware v0.0.0-20230905020518-f7a7139425b8 + github.com/NpoolPlatform/order-middleware v0.0.0-20230906144118-aa8f4d466b82 github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/dtm-labs/dtm v1.17.1 github.com/go-resty/resty/v2 v2.7.0 diff --git a/go.sum b/go.sum index 67eb1d8..2757074 100644 --- a/go.sum +++ b/go.sum @@ -70,8 +70,8 @@ github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= github.com/NpoolPlatform/message v0.0.0-20230906142354-ac8156431b42 h1:ikWSI7gva1moRxD8dHkVQ/J80L1yNNtlgvahmY+vnX4= github.com/NpoolPlatform/message v0.0.0-20230906142354-ac8156431b42/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= -github.com/NpoolPlatform/order-middleware v0.0.0-20230905020518-f7a7139425b8 h1:/9r/Ed8TPCOBdw3iqZ21TU0yxZtjuvyzJl92ztfTGU8= -github.com/NpoolPlatform/order-middleware v0.0.0-20230905020518-f7a7139425b8/go.mod h1:tJJvB9QFPn4NYWWsSorvJBc8ur9FlWNAEAM1wCuzPz8= +github.com/NpoolPlatform/order-middleware v0.0.0-20230906144118-aa8f4d466b82 h1:DR30MjaFkHisMRthaqrEwhUWt6gh+dBg3lOhM6RGgEo= +github.com/NpoolPlatform/order-middleware v0.0.0-20230906144118-aa8f4d466b82/go.mod h1:ROb85kUnw6ajQ7FjzVCIButLqc3tk8OSQwRCuQNOKk8= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b/go.mod h1:9C9XDi7c0szxcLdJGDDFuo3/KtC74yWiyUM2fR+i0ww= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= diff --git a/pkg/order/create.go b/pkg/order/create.go index 4852a18..de2d9fb 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -378,7 +378,7 @@ func (h *createHandler) checkTransferCoinAmount() error { } func (h *createHandler) resolvePaymentType() { - if h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 && //nolint + if h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 && h.balanceCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 { h.paymentType = types.PaymentType_PayWithNoPayment return diff --git a/pkg/order/creates.go b/pkg/order/creates.go index eb0678e..0b87395 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -402,7 +402,7 @@ func (h *createsHandler) checkTransferCoinAmount() error { } func (h *createsHandler) resolvePaymentType() { - if h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 && //nolint + if h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 && h.balanceCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 { h.paymentType = types.PaymentType_PayWithNoPayment return From 785f9b5bef7a7749378d6b131c33645aaf4fec53 Mon Sep 17 00:00:00 2001 From: jakys Date: Fri, 8 Sep 2023 02:09:33 +0000 Subject: [PATCH 30/67] Add migrator --- pkg/migrator/migrator.go | 257 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 254 insertions(+), 3 deletions(-) diff --git a/pkg/migrator/migrator.go b/pkg/migrator/migrator.go index f75b419..50c093a 100644 --- a/pkg/migrator/migrator.go +++ b/pkg/migrator/migrator.go @@ -7,8 +7,14 @@ import ( "github.com/NpoolPlatform/go-service-framework/pkg/config" "github.com/NpoolPlatform/go-service-framework/pkg/logger" redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" + types "github.com/NpoolPlatform/message/npool/basetypes/order/v1" constant1 "github.com/NpoolPlatform/order-gateway/pkg/message/const" "github.com/NpoolPlatform/order-middleware/pkg/db" + "github.com/NpoolPlatform/order-middleware/pkg/db/ent" + entorder "github.com/NpoolPlatform/order-middleware/pkg/db/ent/order" + entorderstate "github.com/NpoolPlatform/order-middleware/pkg/db/ent/orderstate" + "github.com/google/uuid" + "github.com/shopspring/decimal" ) const ( @@ -20,17 +26,262 @@ func lockKey() string { return fmt.Sprintf("migrator:%v", serviceID) } +var orderStateMap = map[string]*types.OrderState{ + "DefaultState": types.OrderState_DefaultOrderState.Enum(), + "WaitPayment": types.OrderState_OrderStateWaitPayment.Enum(), + "Paid": types.OrderState_OrderStatePaid.Enum(), + "PaymentTimeout": types.OrderState_OrderStatePaymentTimeout.Enum(), + "Canceled": types.OrderState_OrderStateCanceled.Enum(), + "InService": types.OrderState_OrderStateInService.Enum(), + "Expired": types.OrderState_OrderStateExpired.Enum(), +} + +var paymentStateMap = map[string]*types.PaymentState{ + "DefaultState": types.PaymentState_DefaultPaymentState.Enum(), + "Wait": types.PaymentState_PaymentStateWait.Enum(), + "Done": types.PaymentState_PaymentStateDone.Enum(), + "Canceled": types.PaymentState_PaymentStateCanceled.Enum(), + "TimeOut": types.PaymentState_PaymentStateTimeout.Enum(), +} + +func resolveOrderState(oldState string) string { + newState := orderStateMap[oldState] + if newState == nil { + return oldState + } + return newState.String() +} + +func resolvePaymentState(oldState string) string { + newState := paymentStateMap[oldState] + if newState == nil { + return oldState + } + return newState.String() +} + +//nolint:funlen,gocyclo +func migrateOrder(ctx context.Context) error { + return db.WithTx(ctx, func(_ctx context.Context, tx *ent.Tx) error { + var err error + r, err := tx.QueryContext(ctx, "select id,app_id,user_id,good_id,units_v1,start_at,end_at,type,state,last_benefit_at,deleted_at from orders where app_good_id=''") + if err != nil { + return err + } + type od struct { + ID uuid.UUID + AppID uuid.UUID + UserID uuid.UUID + GoodID uuid.UUID + UnitsV1 decimal.Decimal + StartAt uint32 + EndAt uint32 + Type string + State string + LastBenefitAt uint32 + DeletedAt uint32 + } + orders := []*od{} + for r.Next() { + order := &od{} + if err := r.Scan(&order.ID, &order.AppID, &order.UserID, &order.GoodID, &order.UnitsV1, &order.StartAt, &order.EndAt, + &order.Type, &order.State, &order.LastBenefitAt, &order.DeletedAt); err != nil { + return err + } + orders = append(orders, order) + } + if len(orders) == 0 { + return nil + } + + r, err = tx.QueryContext(ctx, "select id,app_id,good_id,price,deleted_at from good_manager.app_goods") + if err != nil { + return err + } + type ag struct { + ID uuid.UUID + AppID uuid.UUID + GoodID uuid.UUID + Price decimal.Decimal + DeletedAt uint32 + } + appgoods := map[uuid.UUID]*ag{} + for r.Next() { + good := &ag{} + if err := r.Scan(&good.ID, &good.AppID, &good.GoodID, &good.Price, &good.DeletedAt); err != nil { + return err + } + appgoods[good.GoodID] = good + } + + r, err = tx.QueryContext(ctx, "select id,coin_type_id,duration_days,deleted_at from good_manager.goods") + if err != nil { + return err + } + type g struct { + ID uuid.UUID + CoinTypeID uuid.UUID + DurationDays uint32 + DeletedAt uint32 + } + goods := map[uuid.UUID]*g{} + for r.Next() { + good := &g{} + if err := r.Scan(&good.ID, &good.CoinTypeID, &good.DurationDays, &good.DeletedAt); err != nil { + return err + } + goods[good.ID] = good + } + + selectOrderText := "select id,app_id,user_id,order_id,amount,pay_with_balance_amount,finish_amount," + + "coin_usd_currency,local_coin_usd_currency,live_coin_usd_currency,coin_info_id,state,chain_transaction_id," + + "user_set_paid,user_set_canceled,updated_at,deleted_at from payments" + r, err = tx.QueryContext(ctx, selectOrderText) + if err != nil { + return err + } + + type p struct { + ID uuid.UUID + AppID uuid.UUID + UserID uuid.UUID + OrderID uuid.UUID + Amount decimal.Decimal + PayWithBalanceAmount decimal.Decimal + FinishAmount decimal.Decimal + CoinUsdCurrency decimal.Decimal + LocalCoinUsdCurrency decimal.Decimal + LiveCoinUsdCurrency decimal.Decimal + CoinInfoID uuid.UUID + State string + ChainTransactionID string + UserSetPaid bool + UserSetCanceled bool + UpdatedAt uint32 + DeletedAt uint32 + } + payments := map[uuid.UUID]*p{} + for r.Next() { + payment := &p{} + if err := r.Scan(&payment.ID, &payment.AppID, &payment.UserID, &payment.OrderID, &payment.Amount, &payment.PayWithBalanceAmount, &payment.FinishAmount, + &payment.CoinUsdCurrency, &payment.LocalCoinUsdCurrency, &payment.LiveCoinUsdCurrency, &payment.CoinInfoID, &payment.State, &payment.ChainTransactionID, + &payment.UserSetPaid, &payment.UserSetCanceled, &payment.UpdatedAt, &payment.DeletedAt); err != nil { + return err + } + payments[payment.OrderID] = payment + } + for _, order := range orders { + appGood, ok := appgoods[order.GoodID] + if !ok { + continue + } + payment, ok := payments[order.ID] + if !ok { + continue + } + good, ok := goods[order.GoodID] + if !ok { + continue + } + // discount_amount + discountAmount := decimal.NewFromInt(0) + // good_valud_usd + goodValueUSD := appGood.Price.Mul(order.UnitsV1) + // good_value + goodValue := goodValueUSD.Div(payment.CoinUsdCurrency) + // payment_amount + paymentAmount := payment.Amount.Add(payment.PayWithBalanceAmount) + + _, err = tx.Order.Update(). + Where( + entorder.ID(order.ID), + ). + SetAppGoodID(appGood.ID). + SetPaymentID(payment.ID). + SetGoodValueUsd(goodValueUSD). + SetGoodValue(goodValue). + SetPaymentAmount(paymentAmount). + SetDurationDays(good.DurationDays). + SetOrderType(order.Type). + SetCoinTypeID(good.CoinTypeID). + SetPaymentCoinTypeID(payment.CoinInfoID). + SetTransferAmount(payment.Amount). + SetBalanceAmount(payment.PayWithBalanceAmount). + SetCoinUsdCurrency(payment.CoinUsdCurrency). + SetLocalCoinUsdCurrency(payment.LocalCoinUsdCurrency). + SetLiveCoinUsdCurrency(payment.LiveCoinUsdCurrency). + SetDiscountAmount(discountAmount). + Save(_ctx) + if err != nil { + return err + } + + // check order state + exist, err := tx.OrderState. + Query(). + Where( + entorderstate.OrderID(order.ID), + ). + ForUpdate(). + Exist(ctx) + if err != nil { + return err + } + if exist { + continue + } + // create orderstates + // order_state + _orderState := resolveOrderState(order.State) + // payment_state + paymentState := resolvePaymentState(payment.State) + // paid_at + paidAt := uint32(0) + if paymentState == types.PaymentState_PaymentStateDone.String() { + paidAt = payment.UpdatedAt + } + + if _, err := tx. + OrderState. + Create(). + SetOrderID(order.ID). + SetOrderState(_orderState). + SetStartAt(order.StartAt). + SetEndAt(order.EndAt). + SetLastBenefitAt(order.LastBenefitAt). + SetUserSetPaid(payment.UserSetPaid). + SetUserSetCanceled(payment.UserSetCanceled). + SetPaymentTransactionID(payment.ChainTransactionID). + SetPaymentFinishAmount(payment.FinishAmount). + SetPaymentState(paymentState). + SetPaidAt(paidAt). + Save(ctx); err != nil { + return err + } + } + + return nil + }) +} + func Migrate(ctx context.Context) error { - if err := redis2.TryLock(lockKey(), 0); err != nil { + var err error + + if err := db.Init(); err != nil { return err } + logger.Sugar().Infow("Migrate order", "Start", "...") defer func() { _ = redis2.Unlock(lockKey()) + logger.Sugar().Infow("Migrate order", "Done", "...", "error", err) }() - logger.Sugar().Infow("Migrate", "Start", "...") + err = redis2.TryLock(lockKey(), 0) + if err != nil { + return err + } - if err := db.Init(); err != nil { + if err := migrateOrder(ctx); err != nil { logger.Sugar().Errorw("Migrate", "error", err) return err } From f7de43511c130aa5f02caecd74a95af05b629c53 Mon Sep 17 00:00:00 2001 From: jakys Date: Fri, 8 Sep 2023 02:49:07 +0000 Subject: [PATCH 31/67] Fix migrator --- pkg/migrator/migrator.go | 419 ++++++++++++++++++++++----------------- 1 file changed, 233 insertions(+), 186 deletions(-) diff --git a/pkg/migrator/migrator.go b/pkg/migrator/migrator.go index 50c093a..1b6210b 100644 --- a/pkg/migrator/migrator.go +++ b/pkg/migrator/migrator.go @@ -61,207 +61,205 @@ func resolvePaymentState(oldState string) string { } //nolint:funlen,gocyclo -func migrateOrder(ctx context.Context) error { - return db.WithTx(ctx, func(_ctx context.Context, tx *ent.Tx) error { - var err error - r, err := tx.QueryContext(ctx, "select id,app_id,user_id,good_id,units_v1,start_at,end_at,type,state,last_benefit_at,deleted_at from orders where app_good_id=''") - if err != nil { +func migrateOrder(ctx context.Context, tx *ent.Tx) error { + var err error + r, err := tx.QueryContext(ctx, "select id,app_id,user_id,good_id,units_v1,start_at,end_at,type,state,last_benefit_at,deleted_at from orders where app_good_id=''") + if err != nil { + return err + } + type od struct { + ID uuid.UUID + AppID uuid.UUID + UserID uuid.UUID + GoodID uuid.UUID + UnitsV1 decimal.Decimal + StartAt uint32 + EndAt uint32 + Type string + State string + LastBenefitAt uint32 + DeletedAt uint32 + } + orders := []*od{} + for r.Next() { + order := &od{} + if err := r.Scan(&order.ID, &order.AppID, &order.UserID, &order.GoodID, &order.UnitsV1, &order.StartAt, &order.EndAt, + &order.Type, &order.State, &order.LastBenefitAt, &order.DeletedAt); err != nil { return err } - type od struct { - ID uuid.UUID - AppID uuid.UUID - UserID uuid.UUID - GoodID uuid.UUID - UnitsV1 decimal.Decimal - StartAt uint32 - EndAt uint32 - Type string - State string - LastBenefitAt uint32 - DeletedAt uint32 - } - orders := []*od{} - for r.Next() { - order := &od{} - if err := r.Scan(&order.ID, &order.AppID, &order.UserID, &order.GoodID, &order.UnitsV1, &order.StartAt, &order.EndAt, - &order.Type, &order.State, &order.LastBenefitAt, &order.DeletedAt); err != nil { - return err - } - orders = append(orders, order) + orders = append(orders, order) + } + if len(orders) == 0 { + return nil + } + + r, err = tx.QueryContext(ctx, "select id,app_id,good_id,price,deleted_at from good_manager.app_goods") + if err != nil { + return err + } + type ag struct { + ID uuid.UUID + AppID uuid.UUID + GoodID uuid.UUID + Price decimal.Decimal + DeletedAt uint32 + } + appgoods := map[uuid.UUID]*ag{} + for r.Next() { + good := &ag{} + if err := r.Scan(&good.ID, &good.AppID, &good.GoodID, &good.Price, &good.DeletedAt); err != nil { + return err } - if len(orders) == 0 { - return nil + appgoods[good.GoodID] = good + } + + r, err = tx.QueryContext(ctx, "select id,coin_type_id,duration_days,deleted_at from good_manager.goods") + if err != nil { + return err + } + type g struct { + ID uuid.UUID + CoinTypeID uuid.UUID + DurationDays uint32 + DeletedAt uint32 + } + goods := map[uuid.UUID]*g{} + for r.Next() { + good := &g{} + if err := r.Scan(&good.ID, &good.CoinTypeID, &good.DurationDays, &good.DeletedAt); err != nil { + return err } + goods[good.ID] = good + } - r, err = tx.QueryContext(ctx, "select id,app_id,good_id,price,deleted_at from good_manager.app_goods") - if err != nil { + selectOrderText := "select id,app_id,user_id,order_id,amount,pay_with_balance_amount,finish_amount," + + "coin_usd_currency,local_coin_usd_currency,live_coin_usd_currency,coin_info_id,state,chain_transaction_id," + + "user_set_paid,user_set_canceled,updated_at,deleted_at from payments" + r, err = tx.QueryContext(ctx, selectOrderText) + if err != nil { + return err + } + + type p struct { + ID uuid.UUID + AppID uuid.UUID + UserID uuid.UUID + OrderID uuid.UUID + Amount decimal.Decimal + PayWithBalanceAmount decimal.Decimal + FinishAmount decimal.Decimal + CoinUsdCurrency decimal.Decimal + LocalCoinUsdCurrency decimal.Decimal + LiveCoinUsdCurrency decimal.Decimal + CoinInfoID uuid.UUID + State string + ChainTransactionID string + UserSetPaid bool + UserSetCanceled bool + UpdatedAt uint32 + DeletedAt uint32 + } + payments := map[uuid.UUID]*p{} + for r.Next() { + payment := &p{} + if err := r.Scan(&payment.ID, &payment.AppID, &payment.UserID, &payment.OrderID, &payment.Amount, &payment.PayWithBalanceAmount, &payment.FinishAmount, + &payment.CoinUsdCurrency, &payment.LocalCoinUsdCurrency, &payment.LiveCoinUsdCurrency, &payment.CoinInfoID, &payment.State, &payment.ChainTransactionID, + &payment.UserSetPaid, &payment.UserSetCanceled, &payment.UpdatedAt, &payment.DeletedAt); err != nil { return err } - type ag struct { - ID uuid.UUID - AppID uuid.UUID - GoodID uuid.UUID - Price decimal.Decimal - DeletedAt uint32 + payments[payment.OrderID] = payment + } + for _, order := range orders { + appGood, ok := appgoods[order.GoodID] + if !ok { + continue + } + payment, ok := payments[order.ID] + if !ok { + continue } - appgoods := map[uuid.UUID]*ag{} - for r.Next() { - good := &ag{} - if err := r.Scan(&good.ID, &good.AppID, &good.GoodID, &good.Price, &good.DeletedAt); err != nil { - return err - } - appgoods[good.GoodID] = good + good, ok := goods[order.GoodID] + if !ok { + continue } + // discount_amount + discountAmount := decimal.NewFromInt(0) + // good_valud_usd + goodValueUSD := appGood.Price.Mul(order.UnitsV1) + // good_value + goodValue := goodValueUSD.Div(payment.CoinUsdCurrency) + // payment_amount + paymentAmount := payment.Amount.Add(payment.PayWithBalanceAmount) - r, err = tx.QueryContext(ctx, "select id,coin_type_id,duration_days,deleted_at from good_manager.goods") + _, err = tx.Order.Update(). + Where( + entorder.ID(order.ID), + ). + SetAppGoodID(appGood.ID). + SetPaymentID(payment.ID). + SetGoodValueUsd(goodValueUSD). + SetGoodValue(goodValue). + SetPaymentAmount(paymentAmount). + SetDurationDays(good.DurationDays). + SetOrderType(order.Type). + SetCoinTypeID(good.CoinTypeID). + SetPaymentCoinTypeID(payment.CoinInfoID). + SetTransferAmount(payment.Amount). + SetBalanceAmount(payment.PayWithBalanceAmount). + SetCoinUsdCurrency(payment.CoinUsdCurrency). + SetLocalCoinUsdCurrency(payment.LocalCoinUsdCurrency). + SetLiveCoinUsdCurrency(payment.LiveCoinUsdCurrency). + SetDiscountAmount(discountAmount). + Save(ctx) if err != nil { return err } - type g struct { - ID uuid.UUID - CoinTypeID uuid.UUID - DurationDays uint32 - DeletedAt uint32 - } - goods := map[uuid.UUID]*g{} - for r.Next() { - good := &g{} - if err := r.Scan(&good.ID, &good.CoinTypeID, &good.DurationDays, &good.DeletedAt); err != nil { - return err - } - goods[good.ID] = good - } - selectOrderText := "select id,app_id,user_id,order_id,amount,pay_with_balance_amount,finish_amount," + - "coin_usd_currency,local_coin_usd_currency,live_coin_usd_currency,coin_info_id,state,chain_transaction_id," + - "user_set_paid,user_set_canceled,updated_at,deleted_at from payments" - r, err = tx.QueryContext(ctx, selectOrderText) + // check order state + exist, err := tx.OrderState. + Query(). + Where( + entorderstate.OrderID(order.ID), + ). + ForUpdate(). + Exist(ctx) if err != nil { return err } - - type p struct { - ID uuid.UUID - AppID uuid.UUID - UserID uuid.UUID - OrderID uuid.UUID - Amount decimal.Decimal - PayWithBalanceAmount decimal.Decimal - FinishAmount decimal.Decimal - CoinUsdCurrency decimal.Decimal - LocalCoinUsdCurrency decimal.Decimal - LiveCoinUsdCurrency decimal.Decimal - CoinInfoID uuid.UUID - State string - ChainTransactionID string - UserSetPaid bool - UserSetCanceled bool - UpdatedAt uint32 - DeletedAt uint32 + if exist { + continue } - payments := map[uuid.UUID]*p{} - for r.Next() { - payment := &p{} - if err := r.Scan(&payment.ID, &payment.AppID, &payment.UserID, &payment.OrderID, &payment.Amount, &payment.PayWithBalanceAmount, &payment.FinishAmount, - &payment.CoinUsdCurrency, &payment.LocalCoinUsdCurrency, &payment.LiveCoinUsdCurrency, &payment.CoinInfoID, &payment.State, &payment.ChainTransactionID, - &payment.UserSetPaid, &payment.UserSetCanceled, &payment.UpdatedAt, &payment.DeletedAt); err != nil { - return err - } - payments[payment.OrderID] = payment + // create orderstates + // order_state + _orderState := resolveOrderState(order.State) + // payment_state + paymentState := resolvePaymentState(payment.State) + // paid_at + paidAt := uint32(0) + if paymentState == types.PaymentState_PaymentStateDone.String() { + paidAt = payment.UpdatedAt } - for _, order := range orders { - appGood, ok := appgoods[order.GoodID] - if !ok { - continue - } - payment, ok := payments[order.ID] - if !ok { - continue - } - good, ok := goods[order.GoodID] - if !ok { - continue - } - // discount_amount - discountAmount := decimal.NewFromInt(0) - // good_valud_usd - goodValueUSD := appGood.Price.Mul(order.UnitsV1) - // good_value - goodValue := goodValueUSD.Div(payment.CoinUsdCurrency) - // payment_amount - paymentAmount := payment.Amount.Add(payment.PayWithBalanceAmount) - - _, err = tx.Order.Update(). - Where( - entorder.ID(order.ID), - ). - SetAppGoodID(appGood.ID). - SetPaymentID(payment.ID). - SetGoodValueUsd(goodValueUSD). - SetGoodValue(goodValue). - SetPaymentAmount(paymentAmount). - SetDurationDays(good.DurationDays). - SetOrderType(order.Type). - SetCoinTypeID(good.CoinTypeID). - SetPaymentCoinTypeID(payment.CoinInfoID). - SetTransferAmount(payment.Amount). - SetBalanceAmount(payment.PayWithBalanceAmount). - SetCoinUsdCurrency(payment.CoinUsdCurrency). - SetLocalCoinUsdCurrency(payment.LocalCoinUsdCurrency). - SetLiveCoinUsdCurrency(payment.LiveCoinUsdCurrency). - SetDiscountAmount(discountAmount). - Save(_ctx) - if err != nil { - return err - } - - // check order state - exist, err := tx.OrderState. - Query(). - Where( - entorderstate.OrderID(order.ID), - ). - ForUpdate(). - Exist(ctx) - if err != nil { - return err - } - if exist { - continue - } - // create orderstates - // order_state - _orderState := resolveOrderState(order.State) - // payment_state - paymentState := resolvePaymentState(payment.State) - // paid_at - paidAt := uint32(0) - if paymentState == types.PaymentState_PaymentStateDone.String() { - paidAt = payment.UpdatedAt - } - if _, err := tx. - OrderState. - Create(). - SetOrderID(order.ID). - SetOrderState(_orderState). - SetStartAt(order.StartAt). - SetEndAt(order.EndAt). - SetLastBenefitAt(order.LastBenefitAt). - SetUserSetPaid(payment.UserSetPaid). - SetUserSetCanceled(payment.UserSetCanceled). - SetPaymentTransactionID(payment.ChainTransactionID). - SetPaymentFinishAmount(payment.FinishAmount). - SetPaymentState(paymentState). - SetPaidAt(paidAt). - Save(ctx); err != nil { - return err - } + if _, err := tx. + OrderState. + Create(). + SetOrderID(order.ID). + SetOrderState(_orderState). + SetStartAt(order.StartAt). + SetEndAt(order.EndAt). + SetLastBenefitAt(order.LastBenefitAt). + SetUserSetPaid(payment.UserSetPaid). + SetUserSetCanceled(payment.UserSetCanceled). + SetPaymentTransactionID(payment.ChainTransactionID). + SetPaymentFinishAmount(payment.FinishAmount). + SetPaymentState(paymentState). + SetPaidAt(paidAt). + Save(ctx); err != nil { + return err } + } - return nil - }) + return nil } func Migrate(ctx context.Context) error { @@ -280,13 +278,62 @@ func Migrate(ctx context.Context) error { if err != nil { return err } + return db.WithTx(ctx, func(_ctx context.Context, tx *ent.Tx) error { + _, err := tx. + ExecContext( + ctx, + "update payments set amount='0' where amount is NULL", + ) + if err != nil { + return err + } + _, err = tx. + ExecContext( + ctx, + "update payments set pay_with_balance_amount='0' where pay_with_balance_amount is NULL", + ) + if err != nil { + return err + } + _, err = tx. + ExecContext( + ctx, + "update payments set finish_amount='0' where finish_amount is NULL", + ) + if err != nil { + return err + } + _, err = tx. + ExecContext( + ctx, + "update payments set coin_usd_currency='0' where coin_usd_currency is NULL", + ) + if err != nil { + return err + } + _, err = tx. + ExecContext( + ctx, + "update payments set local_coin_usd_currency='0' where local_coin_usd_currency is NULL", + ) + if err != nil { + return err + } + _, err = tx. + ExecContext( + ctx, + "update payments set live_coin_usd_currency='0' where live_coin_usd_currency is NULL", + ) + if err != nil { + return err + } - if err := migrateOrder(ctx); err != nil { - logger.Sugar().Errorw("Migrate", "error", err) - return err - } - - logger.Sugar().Infow("Migrate", "Done", "success") + if err := migrateOrder(_ctx, tx); err != nil { + logger.Sugar().Errorw("Migrate", "error", err) + return err + } + logger.Sugar().Infow("Migrate", "Done", "success") - return nil + return nil + }) } From 0958f4a4ab12130439c37f5e80e3e9fbd4bc7eef Mon Sep 17 00:00:00 2001 From: jakys Date: Fri, 8 Sep 2023 04:01:15 +0000 Subject: [PATCH 32/67] Add test desc --- test-command.md | 455 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 455 insertions(+) create mode 100644 test-command.md diff --git a/test-command.md b/test-command.md new file mode 100644 index 0000000..b2c6058 --- /dev/null +++ b/test-command.md @@ -0,0 +1,455 @@ +# Order订单Mock + +## 查找可用设备 + +``` +mysql> select id from good_manager.device_infos where deleted_at=0 limit 3; +``` + +``` ++--------------------------------------+ +| id | ++--------------------------------------+ +| 00b7009e-34b2-4f55-88f8-dea3ac23e421 | +| 00b985d4-faa8-4994-b58a-e42d375f221a | +| 00bd89c7-1792-4182-b8b4-9547cce6de0c | ++--------------------------------------+ +``` + +这里可以选用 id 00b7009e-34b2-4f55-88f8-dea3ac23e421 + + + +## 查找测试币种 + +``` +mysql> select id,coin_type_id,name from chain_manager.app_coins where app_id='ff2c5d50-be56-413e-aba5-9c7ad888a769' and name like '%usdt%'; +``` + +``` ++--------------------------------------+--------------------------------------+------------+ +| id | coin_type_id | name | ++--------------------------------------+--------------------------------------+------------+ +| 4c8fb477-58da-49f5-aa1c-5e72120754c2 | 9ba0bfee-3dcf-4905-a95e-852436af748f | tusdttrc20 | +| 78e493d0-e78c-4efe-b537-32569987ee81 | 9c81fd06-ce50-466b-84e1-568018f00c8c | usdttrc20 | +| 80b846de-f89a-4543-9a37-5448465bbbb0 | 9ba0bfee-3dcf-4905-a95e-852436af748f | tusdttrc20 | +| d936fc39-c3ba-4d0f-aced-88c04bd8fb2e | aaf04c25-2c87-46e7-99d3-56814e40ec61 | tusdterc20 | ++--------------------------------------+--------------------------------------+------------+ +``` + +这里可以选用 coin_type_id 9ba0bfee-3dcf-4905-a95e-852436af748f + + + +## 查找location + +``` +mysql> select id from good_manager.vendor_locations where deleted_at=0 limit 3; +``` + +``` ++--------------------------------------+ +| id | ++--------------------------------------+ +| 001a98f0-ee9f-4d5e-a1f4-f4739221136b | +| 0082cdb6-cb51-4942-8c7d-661b528cc69c | +| 00ed8b24-0722-4188-9ddb-1284d68d56f3 | ++--------------------------------------+ +``` + +这里可以选用 id 001a98f0-ee9f-4d5e-a1f4-f4739221136b + + + +## 创建商品Good + +这里可以指定ID,也可以不指定由程序自动生成,下一步创建appGood的时候需要设置goodID与这里指定或者生成的ID相同 + +``` +grpcurl --plaintext -d '{ + "Info": { + "ID": "1001a09e-34b2-4f55-88f8-dea3ac23e421", + "DeviceInfoID": "00b7009e-34b2-4f55-88f8-dea3ac23e421", + "DurationDays": "365", + "CoinTypeID": "9ba0bfee-3dcf-4905-a95e-852436af748f", + "VendorLocationID": "001a98f0-ee9f-4d5e-a1f4-f4739221136b", + "Price": "10", + "BenefitType": "BenefitTypePlatform", + "GoodType": "PowerRenting", + "Title": "test-20230907-01", + "Unit": "TiB", + "UnitAmount": "1", + "SupportCoinTypeIDs": [ + "9ba0bfee-3dcf-4905-a95e-852436af748f" + ], + "DeliveryAt": "1694149200", + "StartAt": "1693976400", + "StartMode": "GoodStartModeConfirmed", + "TestOnly": true, + "Total": "100", + "BenefitIntervalHours": "24", + "UnitLockDeposit": "10" + } +}' good-middleware:50531 good.middleware.good1.v1.Middleware.CreateGood +``` + + + +## 创建应用绑定商品AppGood + +这里使用appID ff2c5d50-be56-413e-aba5-9c7ad888a769。或者在数据库查找其他的AppID也可以。 + +ID可以指定也可以程序自动生成 + +``` +grpcurl --plaintext -d '{ + "Info": { + "ID": "2001aa50-be56-413e-aba5-9c7ad888a769", + "AppID": "ff2c5d50-be56-413e-aba5-9c7ad888a769", + "GoodID": "1001a09e-34b2-4f55-88f8-dea3ac23e421", + "Online": true, + "Visible": true, + "GoodName": "testbenefit20230906-15", + "Price": "50", + "DisplayIndex": "1", + "PurchaseLimit": "100", + "SaleStartAt": "1693976400", + "SaleEndAt": "1694149200", + "ServiceStartAt": "1693976400", + "Descriptions": "1694149200", + "GoodBanner": "", + "EnablePurchase": true, + "EnableProductPage": true, + "CancelMode": "CancellableBeforeBenefit", + "UserPurchaseLimit": "200", + "DisplayColors": "", + "CancellableBeforeStart": "0", + "ProductPage": "", + "EnableSetCommission": true, + "Posters": "", + "TechnicalFeeRatio": "20", + "ElectricityFeeRatio": "0", + "DisplayNames": "" + } +}' good-middleware:50531 good.middleware.app.good1.v1.Middleware.CreateGood +``` + + + +## 找个有钱的用户 + +``` +mysql> select user_id,spendable from ledger_manager.generals where coin_type_id='9ba0bfee-3dcf-4905-a95e-852436af748f' and app_id='ff2c5d50-be56-413e-aba5-9c7ad888a769' and deleted_at=0 limit 10; +``` + +``` ++--------------------------------------+-----------------------------------+ +| user_id | spendable | ++--------------------------------------+-----------------------------------+ +| fba0bd90-99b2-44e1-88e8-5fdfad2dc9f0 | 0.000000000000000000 | +| 15cf1283-634a-4008-9913-c9a9235316a9 | 20000000000350.294000000000000000 | +| c48cf817-0b54-476f-9962-6379203a562a | 0.000000000000000000 | +| 628db1e7-2fd9-4468-a785-a434ba5849bc | 49995.000000000000000000 | +| 732d2a46-3c71-448f-8f92-067ff11634e1 | 980.000000000000000000 | +| b36df48a-3581-442b-b5ad-83ecf6effcdd | 99506.000000000000000000 | +| 06094f12-0c0c-43d9-ae0a-f34064ce1234 | 280.000000000000000000 | +| 297d7c7c-ea54-4843-8502-2c3b925f2749 | 107.888000000000000000 | +| 8c14fb2f-14f9-4656-84c3-e7ef104e9d58 | 5.000000000000000000 | +| 9bfb1441-7090-4cff-9451-7ada311bf736 | 223.126000000000000000 | ++--------------------------------------+-----------------------------------+ +``` + +这里可以选用 + +有钱的user_id b36df48a-3581-442b-b5ad-83ecf6effcdd + +没钱的user_id 8c14fb2f-14f9-4656-84c3-e7ef104e9d58 + + + +## 创建订单 + +1. 没有用余额支付 + +``` +grpcurl --plaintext -d '{ + "AppID": "ff2c5d50-be56-413e-aba5-9c7ad888a769", + "UserID": "b36df48a-3581-442b-b5ad-83ecf6effcdd", + "AppGoodID": "2001aa50-be56-413e-aba5-9c7ad888a769", + "Units": "10", + "PaymentCoinID": "9ba0bfee-3dcf-4905-a95e-852436af748f", + "InvestmentType": "FullPayment" +}' localhost:50431 order.gateway.order1.v1.Gateway.CreateOrder +``` + +2. 有余额支付 + +``` +grpcurl --plaintext -d '{ + "AppID": "ff2c5d50-be56-413e-aba5-9c7ad888a769", + "UserID": "b36df48a-3581-442b-b5ad-83ecf6effcdd", + "AppGoodID": "2001aa50-be56-413e-aba5-9c7ad888a769", + "Units": "20", + "PaymentCoinID": "9ba0bfee-3dcf-4905-a95e-852436af748f", + "PayWithBalanceAmount": "10000", + "InvestmentType": "FullPayment" +}' localhost:50431 order.gateway.order1.v1.Gateway.CreateOrder +``` + + + + + +## 批量创建订单(父子订单) + +场景描述: + +在good中有一个goodRequired模块,设置了主商品与关联商品的绑定关系,如MainGood是A商品,RequiredGood是B和C商品,其中B商品的must属性为true,则表示在购买A商品时必须购买B商品,而C商品为可选商品,在下单时, 会批量创建order,A商品的order为父订单,B商品的order为子订单,如果C商品也同时购买,则也是且支付金额会汇总到A商品的order中计算 + + + +## 创建一组商品Good + +``` +grpcurl --plaintext -d '{ + "Info": { + "ID": "2001a09e-34b2-4f55-88f8-dea3ac23e421", + "DeviceInfoID": "00b7009e-34b2-4f55-88f8-dea3ac23e421", + "DurationDays": "365", + "CoinTypeID": "9ba0bfee-3dcf-4905-a95e-852436af748f", + "VendorLocationID": "001a98f0-ee9f-4d5e-a1f4-f4739221136b", + "Price": "10", + "BenefitType": "BenefitTypePlatform", + "GoodType": "PowerRenting", + "Title": "test-20230907-21", + "Unit": "TiB", + "UnitAmount": "1", + "SupportCoinTypeIDs": [ + "9ba0bfee-3dcf-4905-a95e-852436af748f" + ], + "DeliveryAt": "1694149200", + "StartAt": "1693976400", + "StartMode": "GoodStartModeConfirmed", + "TestOnly": true, + "Total": "100", + "BenefitIntervalHours": "24", + "UnitLockDeposit": "10" + } +}' good-middleware:50531 good.middleware.good1.v1.Middleware.CreateGood +``` + +``` +grpcurl --plaintext -d '{ + "Info": { + "ID": "2002a09e-34b2-4f55-88f8-dea3ac23e421", + "DeviceInfoID": "00b7009e-34b2-4f55-88f8-dea3ac23e421", + "DurationDays": "365", + "CoinTypeID": "9ba0bfee-3dcf-4905-a95e-852436af748f", + "VendorLocationID": "001a98f0-ee9f-4d5e-a1f4-f4739221136b", + "Price": "10", + "BenefitType": "BenefitTypePlatform", + "GoodType": "PowerRenting", + "Title": "test-20230907-22", + "Unit": "TiB", + "UnitAmount": "1", + "SupportCoinTypeIDs": [ + "9ba0bfee-3dcf-4905-a95e-852436af748f" + ], + "DeliveryAt": "1694149200", + "StartAt": "1693976400", + "StartMode": "GoodStartModeConfirmed", + "TestOnly": true, + "Total": "100", + "BenefitIntervalHours": "24", + "UnitLockDeposit": "10" + } +}' good-middleware:50531 good.middleware.good1.v1.Middleware.CreateGood +``` + +``` +grpcurl --plaintext -d '{ + "Info": { + "ID": "2003a09e-34b2-4f55-88f8-dea3ac23e421", + "DeviceInfoID": "00b7009e-34b2-4f55-88f8-dea3ac23e421", + "DurationDays": "365", + "CoinTypeID": "9ba0bfee-3dcf-4905-a95e-852436af748f", + "VendorLocationID": "001a98f0-ee9f-4d5e-a1f4-f4739221136b", + "Price": "10", + "BenefitType": "BenefitTypePlatform", + "GoodType": "PowerRenting", + "Title": "test-20230907-23", + "Unit": "TiB", + "UnitAmount": "1", + "SupportCoinTypeIDs": [ + "9ba0bfee-3dcf-4905-a95e-852436af748f" + ], + "DeliveryAt": "1694149200", + "StartAt": "1693976400", + "StartMode": "GoodStartModeConfirmed", + "TestOnly": true, + "Total": "100", + "BenefitIntervalHours": "24", + "UnitLockDeposit": "10" + } +}' good-middleware:50531 good.middleware.good1.v1.Middleware.CreateGood +``` + + + +## 创建一组应用绑定商品AppGood + +``` +grpcurl --plaintext -d '{ + "Info": { + "ID": "2201aa50-be56-413e-aba5-9c7ad888a769", + "AppID": "ff2c5d50-be56-413e-aba5-9c7ad888a769", + "GoodID": "2001a09e-34b2-4f55-88f8-dea3ac23e421", + "Online": true, + "Visible": true, + "GoodName": "testbenefit20230906-15", + "Price": "50", + "DisplayIndex": "1", + "PurchaseLimit": "100", + "SaleStartAt": "1693976400", + "SaleEndAt": "1694149200", + "ServiceStartAt": "1693976400", + "Descriptions": "1694149200", + "GoodBanner": "", + "EnablePurchase": true, + "EnableProductPage": true, + "CancelMode": "CancellableBeforeBenefit", + "UserPurchaseLimit": "200", + "DisplayColors": "", + "CancellableBeforeStart": "0", + "ProductPage": "", + "EnableSetCommission": true, + "Posters": "", + "TechnicalFeeRatio": "20", + "ElectricityFeeRatio": "0", + "DisplayNames": "" + } +}' good-middleware:50531 good.middleware.app.good1.v1.Middleware.CreateGood +``` + +``` +grpcurl --plaintext -d '{ + "Info": { + "ID": "2202aa50-be56-413e-aba5-9c7ad888a769", + "AppID": "ff2c5d50-be56-413e-aba5-9c7ad888a769", + "GoodID": "2002a09e-34b2-4f55-88f8-dea3ac23e421", + "Online": true, + "Visible": true, + "GoodName": "testbenefit20230906-15", + "Price": "50", + "DisplayIndex": "1", + "PurchaseLimit": "100", + "SaleStartAt": "1693976400", + "SaleEndAt": "1694149200", + "ServiceStartAt": "1693976400", + "Descriptions": "1694149200", + "GoodBanner": "", + "EnablePurchase": true, + "EnableProductPage": true, + "CancelMode": "CancellableBeforeBenefit", + "UserPurchaseLimit": "200", + "DisplayColors": "", + "CancellableBeforeStart": "0", + "ProductPage": "", + "EnableSetCommission": true, + "Posters": "", + "TechnicalFeeRatio": "20", + "ElectricityFeeRatio": "0", + "DisplayNames": "" + } +}' good-middleware:50531 good.middleware.app.good1.v1.Middleware.CreateGood +``` + +``` +grpcurl --plaintext -d '{ + "Info": { + "ID": "2203aa50-be56-413e-aba5-9c7ad888a769", + "AppID": "ff2c5d50-be56-413e-aba5-9c7ad888a769", + "GoodID": "2003a09e-34b2-4f55-88f8-dea3ac23e421", + "Online": true, + "Visible": true, + "GoodName": "testbenefit20230906-15", + "Price": "50", + "DisplayIndex": "1", + "PurchaseLimit": "100", + "SaleStartAt": "1693976400", + "SaleEndAt": "1694149200", + "ServiceStartAt": "1693976400", + "Descriptions": "1694149200", + "GoodBanner": "", + "EnablePurchase": true, + "EnableProductPage": true, + "CancelMode": "CancellableBeforeBenefit", + "UserPurchaseLimit": "200", + "DisplayColors": "", + "CancellableBeforeStart": "0", + "ProductPage": "", + "EnableSetCommission": true, + "Posters": "", + "TechnicalFeeRatio": "20", + "ElectricityFeeRatio": "0", + "DisplayNames": "" + } +}' good-middleware:50531 good.middleware.app.good1.v1.Middleware.CreateGood +``` + + + +## 创建关联商品 + +这里设置第一个商品为主商品,第二个商品在第一个商品购买时必须同时购买,第三个商品为可选商品 + +``` +grpcurl --plaintext -d '{ + "Info": { + "MainGoodID": "2001a09e-34b2-4f55-88f8-dea3ac23e421", + "RequiredGoodID": "2002a09e-34b2-4f55-88f8-dea3ac23e421", + "Must": true + } +}' localhost:50531 good.middleware.good1.required1.v1.Middleware.CreateRequired +``` + +``` +grpcurl --plaintext -d '{ + "Info": { + "MainGoodID": "2001a09e-34b2-4f55-88f8-dea3ac23e421", + "RequiredGoodID": "2003a09e-34b2-4f55-88f8-dea3ac23e421", + "Must": false + } +}' localhost:50531 good.middleware.good1.required1.v1.Middleware.CreateRequired +``` + + + +## 批量创建订单 + +``` +grpcurl --plaintext -d '{ + "AppID": "ff2c5d50-be56-413e-aba5-9c7ad888a769", + "UserID": "b36df48a-3581-442b-b5ad-83ecf6effcdd", + "PaymentCoinID": "2ab32b87-0696-46f2-92f6-a02c9b39fe4c", + "InvestmentType": "FullPayment", + "Orders": [ + { + "AppGoodID": "2201aa50-be56-413e-aba5-9c7ad888a769", + "Units": "10", + "Parent": true + }, + { + "AppGoodID": "2202aa50-be56-413e-aba5-9c7ad888a769", + "Units": "20", + "Parent": false + }, + { + "AppGoodID": "2203aa50-be56-413e-aba5-9c7ad888a769", + "Units": "20", + "Parent": false + } + ] +}' localhost:50431 order.gateway.order1.v1.Gateway.CreateOrders +``` + From af406855913ea2b3cecb14efc69811ba9318ccab Mon Sep 17 00:00:00 2001 From: jakys Date: Fri, 8 Sep 2023 05:37:31 +0000 Subject: [PATCH 33/67] Fix create --- api/order/query.go | 5 ----- pkg/order/create.go | 21 +++++++++++++++++++++ pkg/order/creates.go | 23 +++++++++++++++++++++++ pkg/order/query.go | 3 +++ 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/api/order/query.go b/api/order/query.go index df266c3..abd3a06 100644 --- a/api/order/query.go +++ b/api/order/query.go @@ -105,11 +105,6 @@ func (s *Server) GetOrder(ctx context.Context, in *npool.GetOrderRequest) (*npoo return &npool.GetOrderResponse{}, status.Error(codes.Internal, err.Error()) } - if info.AppID != in.GetAppID() || info.UserID != in.GetUserID() { - logger.Sugar().Errorw("GetOrder", "Order", info, "error", "permission denied") - return &npool.GetOrderResponse{}, status.Error(codes.PermissionDenied, "permission denied") - } - return &npool.GetOrderResponse{ Info: info, }, nil diff --git a/pkg/order/create.go b/pkg/order/create.go index de2d9fb..c5cac48 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -166,6 +166,24 @@ func (h *createHandler) getAppGood(ctx context.Context) error { return nil } +func (h *createHandler) checkAppGoodCoin(ctx context.Context) error { + goodCoin, err := appcoinmwcli.GetCoinOnly(ctx, &appcoinmwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: h.appGood.CoinTypeID}, + }) + if err != nil { + return err + } + if goodCoin == nil { + return fmt.Errorf("invalid appgood coin") + } + if h.paymentCoin.ENV != goodCoin.ENV { + return fmt.Errorf("good coin mismatch payment coin") + } + + return nil +} + func (h *createHandler) checkUnitsLimit(ctx context.Context) error { if *h.OrderType != types.OrderType_Normal { return nil @@ -699,6 +717,9 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error if err := handler.getAppGood(ctx); err != nil { return nil, err } + if err := handler.checkAppGoodCoin(ctx); err != nil { + return nil, err + } if err := handler.checkUnitsLimit(ctx); err != nil { return nil, err } diff --git a/pkg/order/creates.go b/pkg/order/creates.go index 0b87395..870bbcc 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -177,6 +177,26 @@ func (h *createsHandler) getAppGoods(ctx context.Context) error { return nil } +func (h *createsHandler) checkAppGoodCoin(ctx context.Context) error { + for _, good := range h.appGoods { + goodCoin, err := appcoinmwcli.GetCoinOnly(ctx, &appcoinmwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + CoinTypeID: &basetypes.StringVal{Op: cruder.EQ, Value: good.CoinTypeID}, + }) + if err != nil { + return err + } + if goodCoin == nil { + return fmt.Errorf("invalid appgood coin") + } + if h.paymentCoin.ENV != goodCoin.ENV { + return fmt.Errorf("good coin mismatch payment coin") + } + } + + return nil +} + func (h *createsHandler) checkUnitsLimit(ctx context.Context) error { if *h.OrderType != types.OrderType_Normal { return nil @@ -771,6 +791,9 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e if err := handler.getAppGoods(ctx); err != nil { return nil, err } + if err := handler.checkAppGoodCoin(ctx); err != nil { + return nil, err + } if err := handler.checkUnitsLimit(ctx); err != nil { return nil, err } diff --git a/pkg/order/query.go b/pkg/order/query.go index d6ec915..6a8191e 100644 --- a/pkg/order/query.go +++ b/pkg/order/query.go @@ -333,6 +333,9 @@ func (h *Handler) GetOrder(ctx context.Context) (*npool.Order, error) { if order == nil { return nil, err } + if *h.AppID != order.AppID || *h.UserID != order.UserID { + return nil, fmt.Errorf("permission denied") + } handler := &queryHandler{ Handler: h, From 2f2229a9ce88542446022f03e885c626047afa68 Mon Sep 17 00:00:00 2001 From: jakys Date: Fri, 8 Sep 2023 07:54:01 +0000 Subject: [PATCH 34/67] Add appgoodid --- go.mod | 4 ++-- go.sum | 8 ++++---- pkg/order/query.go | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index a4403e4..d10443c 100644 --- a/go.mod +++ b/go.mod @@ -13,8 +13,8 @@ require ( github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7 github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 - github.com/NpoolPlatform/message v0.0.0-20230906142354-ac8156431b42 - github.com/NpoolPlatform/order-middleware v0.0.0-20230906144118-aa8f4d466b82 + github.com/NpoolPlatform/message v0.0.0-20230908073822-7e02b413acd8 + github.com/NpoolPlatform/order-middleware v0.0.0-20230908075123-fe11e6f59776 github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/dtm-labs/dtm v1.17.1 github.com/go-resty/resty/v2 v2.7.0 diff --git a/go.sum b/go.sum index 2757074..198460a 100644 --- a/go.sum +++ b/go.sum @@ -68,10 +68,10 @@ github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7 h1 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7/go.mod h1:lgAX07sFIVb9LnOJPCt9OMZRVLWqefnk+LBaSaCrWkM= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB4NuhQxXWeV0Z1qSxgIqbiMYU30dqFGDLtgNTqYbE= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= -github.com/NpoolPlatform/message v0.0.0-20230906142354-ac8156431b42 h1:ikWSI7gva1moRxD8dHkVQ/J80L1yNNtlgvahmY+vnX4= -github.com/NpoolPlatform/message v0.0.0-20230906142354-ac8156431b42/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= -github.com/NpoolPlatform/order-middleware v0.0.0-20230906144118-aa8f4d466b82 h1:DR30MjaFkHisMRthaqrEwhUWt6gh+dBg3lOhM6RGgEo= -github.com/NpoolPlatform/order-middleware v0.0.0-20230906144118-aa8f4d466b82/go.mod h1:ROb85kUnw6ajQ7FjzVCIButLqc3tk8OSQwRCuQNOKk8= +github.com/NpoolPlatform/message v0.0.0-20230908073822-7e02b413acd8 h1:yWCMQDN6fMo9QLAPEmyHMkSOerclVR3z5Q7QIGctZxE= +github.com/NpoolPlatform/message v0.0.0-20230908073822-7e02b413acd8/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/order-middleware v0.0.0-20230908075123-fe11e6f59776 h1:VlBC7nUSeURZNdzO6/mHfLPpWYSHH2ONV4vJYBHYxY8= +github.com/NpoolPlatform/order-middleware v0.0.0-20230908075123-fe11e6f59776/go.mod h1:+W0ePEFDyg69uC9oI0mty3AfWzhPCnKyyQSwVtQI4XA= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b/go.mod h1:9C9XDi7c0szxcLdJGDDFuo3/KtC74yWiyUM2fR+i0ww= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= diff --git a/pkg/order/query.go b/pkg/order/query.go index 6a8191e..53512b3 100644 --- a/pkg/order/query.go +++ b/pkg/order/query.go @@ -216,6 +216,7 @@ func (h *queryHandler) formalize(ctx context.Context) { //nolint AppID: ord.AppID, UserID: ord.UserID, GoodID: ord.GoodID, + AppGoodID: ord.AppGoodID, ParentOrderID: ord.ParentOrderID, Units: ord.Units, GoodValue: ord.GoodValue, From 791181bd8c6478e88bebe1e53579126667af43d1 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Fri, 8 Sep 2023 09:00:59 +0000 Subject: [PATCH 35/67] Format code --- pkg/message/const/const.go | 3 --- pkg/migrator/migrator.go | 4 +-- pkg/order/update.go | 47 ++++++++++++---------------------- pkg/servicename/servicename.go | 5 +++- pkg/tracer/tracer.go | 28 -------------------- 5 files changed, 23 insertions(+), 64 deletions(-) delete mode 100644 pkg/message/const/const.go delete mode 100644 pkg/tracer/tracer.go diff --git a/pkg/message/const/const.go b/pkg/message/const/const.go deleted file mode 100644 index ce075be..0000000 --- a/pkg/message/const/const.go +++ /dev/null @@ -1,3 +0,0 @@ -package constant - -const ServiceName = "order-gateway.npool.top" diff --git a/pkg/migrator/migrator.go b/pkg/migrator/migrator.go index 1b6210b..82958aa 100644 --- a/pkg/migrator/migrator.go +++ b/pkg/migrator/migrator.go @@ -8,7 +8,7 @@ import ( "github.com/NpoolPlatform/go-service-framework/pkg/logger" redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" types "github.com/NpoolPlatform/message/npool/basetypes/order/v1" - constant1 "github.com/NpoolPlatform/order-gateway/pkg/message/const" + servicename "github.com/NpoolPlatform/order-gateway/pkg/servicename" "github.com/NpoolPlatform/order-middleware/pkg/db" "github.com/NpoolPlatform/order-middleware/pkg/db/ent" entorder "github.com/NpoolPlatform/order-middleware/pkg/db/ent/order" @@ -22,7 +22,7 @@ const ( ) func lockKey() string { - serviceID := config.GetStringValueWithNameSpace(constant1.ServiceName, keyServiceID) + serviceID := config.GetStringValueWithNameSpace(servicename.ServiceDomain, keyServiceID) return fmt.Sprintf("migrator:%v", serviceID) } diff --git a/pkg/order/update.go b/pkg/order/update.go index c9ecae1..659679e 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -121,14 +121,8 @@ func (h *updateHandler) checkOrderType() error { func (h *updateHandler) getAppGood(ctx context.Context) error { good, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodmwpb.Conds{ - AppID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: h.order.AppID, - }, - GoodID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: h.order.GoodID, - }, + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: h.order.AppID}, + GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.order.GoodID}, }) if err != nil { return err @@ -156,10 +150,7 @@ func (h *updateHandler) checkGood(ctx context.Context) error { func (h *updateHandler) checkCancelable(ctx context.Context) error { goodStatements, _, err := goodledgerstatementcli.GetGoodStatements(ctx, &goodledgerstatementpb.Conds{ - GoodID: &basetypes.StringVal{ - Op: cruder.EQ, - Value: h.order.GoodID, - }, + GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.order.GoodID}, }, 0, 1) if err != nil { return err @@ -169,42 +160,38 @@ func (h *updateHandler) checkCancelable(ctx context.Context) error { case ordertypes.OrderState_OrderStateWaitPayment: fallthrough //nolint case ordertypes.OrderState_OrderStateCheckPayment: - if len(goodStatements) > 0 { - return fmt.Errorf("had statements can not cancel") - } return nil } switch h.appGood.CancelMode { case goodtypes.CancelMode_Uncancellable: - return fmt.Errorf("app good uncancellable") + return fmt.Errorf("permission denied") case goodtypes.CancelMode_CancellableBeforeStart: switch h.order.OrderState { case ordertypes.OrderState_OrderStatePaid: - case ordertypes.OrderState_OrderStateInService: - return fmt.Errorf("order state is uncancellable") default: - return fmt.Errorf("order state is uncancellable") + return fmt.Errorf("permission denied") } case goodtypes.CancelMode_CancellableBeforeBenefit: switch h.order.OrderState { case ordertypes.OrderState_OrderStatePaid: case ordertypes.OrderState_OrderStateInService: - if len(goodStatements) > 0 { - lastBenefitDate := goodStatements[0].BenefitDate - const secondsPerDay = 24 * 60 * 60 - checkBenefitStartAt := lastBenefitDate + secondsPerDay - h.appGood.CancellableBeforeStart - checkBenefitEndAt := lastBenefitDate + secondsPerDay + h.appGood.CancellableBeforeStart - now := uint32(time.Now().Unix()) - if checkBenefitStartAt <= now && now <= checkBenefitEndAt { - return fmt.Errorf("invalid cancel in benefit time") - } + if len(goodStatements) == 0 { + return nil + } + lastBenefitDate := goodStatements[0].BenefitDate + const secondsPerDay = 24 * 60 * 60 + checkBenefitStartAt := lastBenefitDate + secondsPerDay - h.appGood.CancellableBeforeStart + checkBenefitEndAt := lastBenefitDate + secondsPerDay + h.appGood.CancellableBeforeStart + now := uint32(time.Now().Unix()) + if checkBenefitStartAt <= now && now <= checkBenefitEndAt { + return fmt.Errorf("permission denied") } default: - return fmt.Errorf("order state is uncancellable") + return fmt.Errorf("permission denied") } default: - return fmt.Errorf("unknown CancelMode type %v", h.appGood.CancelMode) + return fmt.Errorf("invalid cancelmode %v", h.appGood.CancelMode) } return nil diff --git a/pkg/servicename/servicename.go b/pkg/servicename/servicename.go index 5708991..e1bf8bd 100644 --- a/pkg/servicename/servicename.go +++ b/pkg/servicename/servicename.go @@ -1,3 +1,6 @@ package servicename -const ServiceName = "Order Gateway" +const ( + ServiceName = "Order Gateway" + ServiceDomain = "order-gateway.npool.top" +) diff --git a/pkg/tracer/tracer.go b/pkg/tracer/tracer.go deleted file mode 100644 index 17f7191..0000000 --- a/pkg/tracer/tracer.go +++ /dev/null @@ -1,28 +0,0 @@ -package tracer - -import ( - "fmt" - - servicename "github.com/NpoolPlatform/order-gateway/pkg/servicename" - - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" -) - -func TraceID(span trace.Span, id string) trace.Span { - span.SetAttributes(attribute.String("ID", id)) - return span -} - -func TraceInvoker(span trace.Span, entity, module, invokeName string) trace.Span { - span.AddEvent(fmt.Sprintf("%v.%v.%v.%v", servicename.ServiceName, entity, module, invokeName)) - return span -} - -func TraceOffsetLimit(span trace.Span, offset, limit int) trace.Span { - span.SetAttributes( - attribute.Int("Offset", offset), - attribute.Int("Limit", limit), - ) - return span -} From 5da5b0150800d7b5f3847bf219baf87ffce48a0f Mon Sep 17 00:00:00 2001 From: jakys Date: Fri, 8 Sep 2023 09:13:19 +0000 Subject: [PATCH 36/67] Fix panic --- pkg/order/create.go | 1 + pkg/order/handler.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/order/create.go b/pkg/order/create.go index c5cac48..920e1e0 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -698,6 +698,7 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error handler := &createHandler{ Handler: h, + coupons: map[string]*allocatedmwpb.Coupon{}, } if err := handler.getUser(ctx); err != nil { return nil, err diff --git a/pkg/order/handler.go b/pkg/order/handler.go index 0093865..548de37 100644 --- a/pkg/order/handler.go +++ b/pkg/order/handler.go @@ -151,7 +151,7 @@ func WithParentOrderID(id *string, must bool) func(context.Context, *Handler) er if err != nil { return err } - exist, err := ordermwcli.ExistOrder(ctx, *h.ParentOrderID) + exist, err := ordermwcli.ExistOrder(ctx, *id) if err != nil { return err } From f902bf0faccfb6dbe7133110d30a9025d6c041cb Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Fri, 8 Sep 2023 13:57:24 +0000 Subject: [PATCH 37/67] update create order --- pkg/order/create.go | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/pkg/order/create.go b/pkg/order/create.go index 920e1e0..c228235 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -24,6 +24,7 @@ import ( usermwpb "github.com/NpoolPlatform/message/npool/appuser/mw/v1/user" goodtypes "github.com/NpoolPlatform/message/npool/basetypes/good/v1" inspiretypes "github.com/NpoolPlatform/message/npool/basetypes/inspire/v1" + ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" types "github.com/NpoolPlatform/message/npool/basetypes/order/v1" basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" appcoinmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/app/coin" @@ -198,23 +199,20 @@ func (h *createHandler) checkUnitsLimit(ctx context.Context) error { if !h.appGood.EnablePurchase { return fmt.Errorf("app good is not enabled purchase") } - purchaseCountStr, err := ordermwcli.SumOrderUnits( - ctx, - &ordermwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, - GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.appGood.GoodID}, - OrderStates: &basetypes.Uint32SliceVal{ - Op: cruder.IN, - Value: []uint32{ - uint32(types.OrderState_OrderStatePaid), - uint32(types.OrderState_OrderStateInService), - uint32(types.OrderState_OrderStateExpired), - uint32(types.OrderState_OrderStateWaitPayment), - }, + purchaseCountStr, err := ordermwcli.SumOrderUnits(ctx, &ordermwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.appGood.GoodID}, + OrderStates: &basetypes.Uint32SliceVal{ + Op: cruder.IN, + Value: []uint32{ + uint32(types.OrderState_OrderStatePaid), + uint32(types.OrderState_OrderStateInService), + uint32(types.OrderState_OrderStateExpired), + uint32(types.OrderState_OrderStateWaitPayment), }, }, - ) + }) if err != nil { return err } @@ -396,6 +394,14 @@ func (h *createHandler) checkTransferCoinAmount() error { } func (h *createHandler) resolvePaymentType() { + switch *h.OrderType { + case ordertypes.OrderType_Offline: + h.paymentType = types.PaymentType_PayWithOffline + return + case ordertypes.OrderType_Airdrop: + h.paymentType = types.PaymentType_PayWithNoPayment + return + } if h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 && h.balanceCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 { h.paymentType = types.PaymentType_PayWithNoPayment From 226f387f1e80a0e662cf2ee94c44709c70876b6b Mon Sep 17 00:00:00 2001 From: jakys Date: Fri, 8 Sep 2023 15:47:20 +0000 Subject: [PATCH 38/67] Add lock id --- go.mod | 8 ++++---- go.sum | 8 ++++---- pkg/order/create.go | 15 ++++++++++++--- pkg/order/creates.go | 20 ++++++++++++++++++++ pkg/order/update.go | 39 +++++++++++++++++++++++++++++++++++++-- 5 files changed, 77 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index d10443c..8b4d64c 100644 --- a/go.mod +++ b/go.mod @@ -13,8 +13,8 @@ require ( github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7 github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 - github.com/NpoolPlatform/message v0.0.0-20230908073822-7e02b413acd8 - github.com/NpoolPlatform/order-middleware v0.0.0-20230908075123-fe11e6f59776 + github.com/NpoolPlatform/message v0.0.0-20230908135834-75858428a3cc + github.com/NpoolPlatform/order-middleware v0.0.0-20230908150842-e42cde949673 github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/dtm-labs/dtm v1.17.1 github.com/go-resty/resty/v2 v2.7.0 @@ -23,8 +23,6 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/stretchr/testify v1.8.1 github.com/urfave/cli/v2 v2.16.3 - go.opentelemetry.io/otel v1.10.0 - go.opentelemetry.io/otel/trace v1.10.0 google.golang.org/grpc v1.55.0 google.golang.org/protobuf v1.30.0 ) @@ -111,8 +109,10 @@ require ( github.com/zclconf/go-cty v1.8.0 // indirect go.mongodb.org/mongo-driver v1.9.1 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.31.0 // indirect + go.opentelemetry.io/otel v1.10.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.6.3 // indirect go.opentelemetry.io/otel/sdk v1.6.3 // indirect + go.opentelemetry.io/otel/trace v1.10.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect go.uber.org/ratelimit v0.2.0 // indirect diff --git a/go.sum b/go.sum index 198460a..1e06701 100644 --- a/go.sum +++ b/go.sum @@ -68,10 +68,10 @@ github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7 h1 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7/go.mod h1:lgAX07sFIVb9LnOJPCt9OMZRVLWqefnk+LBaSaCrWkM= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB4NuhQxXWeV0Z1qSxgIqbiMYU30dqFGDLtgNTqYbE= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= -github.com/NpoolPlatform/message v0.0.0-20230908073822-7e02b413acd8 h1:yWCMQDN6fMo9QLAPEmyHMkSOerclVR3z5Q7QIGctZxE= -github.com/NpoolPlatform/message v0.0.0-20230908073822-7e02b413acd8/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= -github.com/NpoolPlatform/order-middleware v0.0.0-20230908075123-fe11e6f59776 h1:VlBC7nUSeURZNdzO6/mHfLPpWYSHH2ONV4vJYBHYxY8= -github.com/NpoolPlatform/order-middleware v0.0.0-20230908075123-fe11e6f59776/go.mod h1:+W0ePEFDyg69uC9oI0mty3AfWzhPCnKyyQSwVtQI4XA= +github.com/NpoolPlatform/message v0.0.0-20230908135834-75858428a3cc h1:/KAPOupIOaDVvQvaVGVNkUgts7qI3AhqHWOmm8kRNKg= +github.com/NpoolPlatform/message v0.0.0-20230908135834-75858428a3cc/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/order-middleware v0.0.0-20230908150842-e42cde949673 h1:K2ynoLI+que/OY1BbqfPO2M3SYXPSdiLow5oWEoZg8g= +github.com/NpoolPlatform/order-middleware v0.0.0-20230908150842-e42cde949673/go.mod h1:3fx7zmHgZJYo5Hi3wgCPr0BYUDTsUjGf4+nVVcGA/RU= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b/go.mod h1:9C9XDi7c0szxcLdJGDDFuo3/KtC74yWiyUM2fR+i0ww= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= diff --git a/pkg/order/create.go b/pkg/order/create.go index c228235..0c57619 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -24,7 +24,6 @@ import ( usermwpb "github.com/NpoolPlatform/message/npool/appuser/mw/v1/user" goodtypes "github.com/NpoolPlatform/message/npool/basetypes/good/v1" inspiretypes "github.com/NpoolPlatform/message/npool/basetypes/inspire/v1" - ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" types "github.com/NpoolPlatform/message/npool/basetypes/order/v1" basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" appcoinmwpb "github.com/NpoolPlatform/message/npool/chain/mw/v1/app/coin" @@ -69,6 +68,8 @@ type createHandler struct { orderStartMode types.OrderStartMode orderStartAt uint32 orderEndAt uint32 + stockLockID *string + balanceLockID *string } func (h *createHandler) getUser(ctx context.Context) error { @@ -395,10 +396,10 @@ func (h *createHandler) checkTransferCoinAmount() error { func (h *createHandler) resolvePaymentType() { switch *h.OrderType { - case ordertypes.OrderType_Offline: + case types.OrderType_Offline: h.paymentType = types.PaymentType_PayWithOffline return - case ordertypes.OrderType_Airdrop: + case types.OrderType_Airdrop: h.paymentType = types.PaymentType_PayWithNoPayment return } @@ -537,6 +538,7 @@ func (h *createHandler) withUpdateStock(dispose *dtmcli.SagaDispose) { GoodID: &h.appGood.GoodID, AppGoodID: h.AppGoodID, Locked: &h.Units, + LockID: h.stockLockID, } dispose.Add( goodmwsvcname.ServiceDomain, @@ -559,6 +561,7 @@ func (h *createHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { UserID: h.UserID, CoinTypeID: h.PaymentCoinID, Spendable: &amount, + LockID: h.balanceLockID, } dispose.Add( ledgermwsvcname.ServiceDomain, @@ -629,6 +632,8 @@ func (h *createHandler) withCreateOrder(dispose *dtmcli.SagaDispose) { StartAt: &h.orderStartAt, EndAt: &h.orderEndAt, StartMode: &h.orderStartMode, + AppGoodStockLockID: h.stockLockID, + LedgerLockID: h.balanceLockID, } if h.promotion != nil { req.PromotionID = &h.promotion.ID @@ -771,12 +776,16 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error if err := handler.getPaymentStartAmount(ctx); err != nil { return nil, err } + id := uuid.NewString() + handler.balanceLockID = &id } id := uuid.NewString() if h.ID == nil { h.ID = &id } + id = uuid.NewString() + handler.stockLockID = &id key := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, id) if err := redis2.TryLock(key, 0); err != nil { diff --git a/pkg/order/creates.go b/pkg/order/creates.go index 870bbcc..136f337 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -72,6 +72,8 @@ type createsHandler struct { orderStartMode map[string]types.OrderStartMode orderStartAt map[string]uint32 orderEndAt map[string]uint32 + stockLockIDs map[string]*string + balanceLockID *string } func (h *createsHandler) tomorrowStart() time.Time { @@ -422,6 +424,14 @@ func (h *createsHandler) checkTransferCoinAmount() error { } func (h *createsHandler) resolvePaymentType() { + switch *h.OrderType { + case types.OrderType_Offline: + h.paymentType = types.PaymentType_PayWithOffline + return + case types.OrderType_Airdrop: + h.paymentType = types.PaymentType_PayWithNoPayment + return + } if h.transferCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 && h.balanceCoinAmount.Cmp(decimal.NewFromInt(0)) == 0 { h.paymentType = types.PaymentType_PayWithNoPayment @@ -580,6 +590,7 @@ func (h *createsHandler) withUpdateStock(dispose *dtmcli.SagaDispose) { GoodID: &appGood.GoodID, AppGoodID: &order.AppGoodID, Locked: &order.Units, + LockID: h.stockLockIDs[order.AppGoodID], } dispose.Add( goodmwsvcname.ServiceDomain, @@ -603,6 +614,7 @@ func (h *createsHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { UserID: h.UserID, CoinTypeID: h.PaymentCoinID, Spendable: &amount, + Locked: h.balanceLockID, } dispose.Add( ledgermwsvcname.ServiceDomain, @@ -652,6 +664,7 @@ func (h *createsHandler) withCreateOrders(dispose *dtmcli.SagaDispose) { StartAt: &orderStartAt, EndAt: &orderEndAt, StartMode: &startMode, + AppGoodStockLockID: h.stockLockIDs[order.AppGoodID], } if h.promotions[order.AppGoodID] != nil { req.PromotionID = &h.promotions[order.AppGoodID].ID @@ -667,6 +680,7 @@ func (h *createsHandler) withCreateOrders(dispose *dtmcli.SagaDispose) { req.PaymentAccountID = &h.paymentAccount.AccountID paymentStartAmount := h.paymentStartAmount.String() req.PaymentStartAmount = &paymentStartAmount + req.LedgerLockID = h.balanceLockID } } else { req.ParentOrderID = h.ParentOrderID @@ -772,6 +786,7 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e orderStartMode: map[string]types.OrderStartMode{}, orderStartAt: map[string]uint32{}, orderEndAt: map[string]uint32{}, + stockLockIDs: map[string]*string{}, } if err := handler.getUser(ctx); err != nil { return nil, err @@ -847,6 +862,8 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e if err := handler.getPaymentStartAmount(ctx); err != nil { return nil, err } + id := uuid.NewString() + handler.balanceLockID = &id } for _, order := range h.Orders { @@ -856,6 +873,9 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e h.ParentOrderID = &id } h.IDs = append(h.IDs, id) + + id = uuid.NewString() + handler.stockLockIDs[order.AppGoodID] = &id } key := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, h.ParentOrderID) diff --git a/pkg/order/update.go b/pkg/order/update.go index 659679e..fe117c1 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -6,9 +6,11 @@ import ( "time" dtmcli "github.com/NpoolPlatform/dtm-cluster/pkg/dtm" + ledgermwsvcname "github.com/NpoolPlatform/ledger-middleware/pkg/servicename" "github.com/NpoolPlatform/libent-cruder/pkg/cruder" ordermwsvcname "github.com/NpoolPlatform/order-middleware/pkg/servicename" "github.com/dtm-labs/dtm/client/dtmcli/dtmimp" + "github.com/google/uuid" goodtypes "github.com/NpoolPlatform/message/npool/basetypes/good/v1" ledgertypes "github.com/NpoolPlatform/message/npool/basetypes/ledger/v1" @@ -30,6 +32,8 @@ import ( ledgermwpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger" ledgerstatementpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger/statement" + orderlockmwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order/orderlock" + usermwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" statementmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/achievement/statement" statementmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/achievement/statement" @@ -42,6 +46,7 @@ type updateHandler struct { order *ordermwpb.Order appGood *appgoodmwpb.Good achievementStatements []*statementmwpb.Statement + commissionLockIDs map[string]*string } func (h *updateHandler) checkCancelParam() error { @@ -236,12 +241,39 @@ func (h *updateHandler) getCommission(ctx context.Context) error { return fmt.Errorf("commission ledger detail is not exist") } h.achievementStatements = append(h.achievementStatements, val) + id := uuid.NewString() + h.commissionLockIDs[val.ID] = &id } } return nil } +func (h *updateHandler) withCreateCommissionLockIDs(dispose *dtmcli.SagaDispose) { + if len(h.achievementStatements) == 0 { + return + } + reqs := []*orderlockmwpb.OrderLockReq{} + for _, statement := range h.achievementStatements { + req := &orderlockmwpb.OrderLockReq{ + ID: h.commissionLockIDs[statement.ID], + AppID: &statement.AppID, + UserID: &statement.UserID, + OrderID: h.ID, + LockType: ordertypes.OrderLockType_LockCommission.Enum(), + } + reqs = append(reqs, req) + } + dispose.Add( + ordermwsvcname.ServiceDomain, + "order.middleware.order1.orderlock.v1.Middleware/CreateOrderLocks", + "order.middleware.order1.orderlock.v1.Middleware/DeleteOrderLocks", + &orderlockmwpb.CreateOrderLocksRequest{ + Infos: reqs, + }, + ) +} + func (h *updateHandler) withLockCommission(dispose *dtmcli.SagaDispose) { for _, statement := range h.achievementStatements { req := &ledgermwpb.LedgerReq{ @@ -249,9 +281,10 @@ func (h *updateHandler) withLockCommission(dispose *dtmcli.SagaDispose) { UserID: &statement.UserID, CoinTypeID: &statement.CoinTypeID, Spendable: &statement.Commission, + LockID: h.commissionLockIDs[statement.ID], } dispose.Add( - ordermwsvcname.ServiceDomain, + ledgermwsvcname.ServiceDomain, "ledger.middleware.ledger.v2.Middleware/SubBalance", "ledger.middleware.ledger.v2.Middleware/AddBalance", &ledgermwpb.AddBalanceRequest{ @@ -279,7 +312,8 @@ func (h *updateHandler) withProcessCancel(dispose *dtmcli.SagaDispose) { func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { handler := &updateHandler{ - Handler: h, + Handler: h, + commissionLockIDs: map[string]*string{}, } if err := handler.checkCancelParam(); err != nil { return nil, err @@ -312,6 +346,7 @@ func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { RequestTimeout: timeoutSeconds, }) + handler.withCreateCommissionLockIDs(sagaDispose) handler.withLockCommission(sagaDispose) handler.withProcessCancel(sagaDispose) From d6f9328f9907506c5fdc428bbe4da8f643e14890 Mon Sep 17 00:00:00 2001 From: jakys Date: Fri, 8 Sep 2023 16:10:53 +0000 Subject: [PATCH 39/67] Fix create --- pkg/order/create.go | 6 ++++-- pkg/order/creates.go | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pkg/order/create.go b/pkg/order/create.go index 0c57619..b5fa846 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -776,8 +776,6 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error if err := handler.getPaymentStartAmount(ctx); err != nil { return nil, err } - id := uuid.NewString() - handler.balanceLockID = &id } id := uuid.NewString() @@ -786,6 +784,10 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error } id = uuid.NewString() handler.stockLockID = &id + if handler.balanceCoinAmount.Cmp(decimal.NewFromInt(0)) <= 0 { + id := uuid.NewString() + handler.balanceLockID = &id + } key := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, id) if err := redis2.TryLock(key, 0); err != nil { diff --git a/pkg/order/creates.go b/pkg/order/creates.go index 136f337..d0a187f 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -862,8 +862,6 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e if err := handler.getPaymentStartAmount(ctx); err != nil { return nil, err } - id := uuid.NewString() - handler.balanceLockID = &id } for _, order := range h.Orders { @@ -877,6 +875,10 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e id = uuid.NewString() handler.stockLockIDs[order.AppGoodID] = &id } + if handler.balanceCoinAmount.Cmp(decimal.NewFromInt(0)) <= 0 { + id := uuid.NewString() + handler.balanceLockID = &id + } key := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, h.ParentOrderID) if err := redis2.TryLock(key, 0); err != nil { From 8ca84abb04b1275801657847485f08b4213fa74b Mon Sep 17 00:00:00 2001 From: jakys Date: Fri, 8 Sep 2023 16:55:57 +0000 Subject: [PATCH 40/67] Update commit id --- go.mod | 12 ++++++------ go.sum | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 8b4d64c..6ae7936 100644 --- a/go.mod +++ b/go.mod @@ -3,18 +3,18 @@ module github.com/NpoolPlatform/order-gateway go 1.17 require ( - github.com/NpoolPlatform/account-middleware v0.0.0-20230712122024-60dc0bb4c0c0 + github.com/NpoolPlatform/account-middleware v0.0.0-20230908122122-cd58a2b8c771 github.com/NpoolPlatform/appuser-middleware v0.0.0-20230513100509-b19f356ebd4b github.com/NpoolPlatform/basal-middleware v0.0.0-20230518061816-62bd589c0f63 - github.com/NpoolPlatform/chain-middleware v0.0.0-20230712041523-2e1d215244e0 + github.com/NpoolPlatform/chain-middleware v0.0.0-20230906092012-a63f3a7b0b54 github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821 github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e - github.com/NpoolPlatform/good-middleware v0.0.0-20230905075718-a4cefe1bff92 - github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 - github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7 + github.com/NpoolPlatform/good-middleware v0.0.0-20230908123355-e4a2233e306b + github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2 + github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 github.com/NpoolPlatform/message v0.0.0-20230908135834-75858428a3cc - github.com/NpoolPlatform/order-middleware v0.0.0-20230908150842-e42cde949673 + github.com/NpoolPlatform/order-middleware v0.0.0-20230908163651-e341753c1fc8 github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/dtm-labs/dtm v1.17.1 github.com/go-resty/resty/v2 v2.7.0 diff --git a/go.sum b/go.sum index 1e06701..9fcb132 100644 --- a/go.sum +++ b/go.sum @@ -48,30 +48,30 @@ github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/NpoolPlatform/account-middleware v0.0.0-20230712122024-60dc0bb4c0c0 h1:uSAdSnM/KVzZfp4IV8rqON8378Rp/WuPAMvww6SAY6A= -github.com/NpoolPlatform/account-middleware v0.0.0-20230712122024-60dc0bb4c0c0/go.mod h1:CTzC/l+jBsshdpZgIxDUgYKM0nszn6L/n/iKh1UL/M8= +github.com/NpoolPlatform/account-middleware v0.0.0-20230908122122-cd58a2b8c771 h1:aB0saOO9lXIHlu+g36mxRMTW8WeqHpyBsSxZmtQJgAk= +github.com/NpoolPlatform/account-middleware v0.0.0-20230908122122-cd58a2b8c771/go.mod h1:5Labnj7w3bY+FKWSDGu/bRasE2obtkfSbYlcrvYJaaI= github.com/NpoolPlatform/appuser-middleware v0.0.0-20230513100509-b19f356ebd4b h1:YmlmVjzJLebnrNl9dtFiJ6bfgqoH++uFe91esScPanE= github.com/NpoolPlatform/appuser-middleware v0.0.0-20230513100509-b19f356ebd4b/go.mod h1:BzT48sEK4KSO6Gy8VJQa5rOuO5JpXib/cmLGHWt4Aqc= github.com/NpoolPlatform/basal-middleware v0.0.0-20230518061816-62bd589c0f63 h1:wQ+crGIMDqv7919i5slVz8liCjBhCZz8xZxHWC3N8uA= github.com/NpoolPlatform/basal-middleware v0.0.0-20230518061816-62bd589c0f63/go.mod h1:3sHDVUUQHRkZsCiBFI6CdCL2HWf3cO7/E2DZU3nHMfE= -github.com/NpoolPlatform/chain-middleware v0.0.0-20230712041523-2e1d215244e0 h1:xD+68nDsw/P0rXd1fzr/wip24bkpYzwrXGBFwSvXkbs= -github.com/NpoolPlatform/chain-middleware v0.0.0-20230712041523-2e1d215244e0/go.mod h1:ExILdqBVnhspnOZFslJl0vTOc4Qyk78Lni1Kx2F8HGM= +github.com/NpoolPlatform/chain-middleware v0.0.0-20230906092012-a63f3a7b0b54 h1:wnYxTar4XI8M+c7ECl52S9emUwiSDdf/etIlLcMv5L4= +github.com/NpoolPlatform/chain-middleware v0.0.0-20230906092012-a63f3a7b0b54/go.mod h1:y3bX+6Yt8cz5s6aQypnqbQzttbwVTOuhK++LU1OBvxA= github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821 h1:JEoN8rpjyJOpbXXLhL5J6Fjw+/bOTwMNci6CL7G02zQ= github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821/go.mod h1:ZBvGIj+zt7VT6WbnIeU/fhiI/dEoNK4JqcXE1EIblpQ= github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e h1:17BGexCmCdOOBXKYogP8RNE+pAHRu2N4LKq9znPJ4vc= github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e/go.mod h1:Kh7DMkWnYOMHxEKq7QfJqbxm1HaUPkhTNN74lfHQxyE= -github.com/NpoolPlatform/good-middleware v0.0.0-20230905075718-a4cefe1bff92 h1:C0j0tYpVA+bTubq4QnYltvrdUSoMLAsI2ALBgj/Qgm8= -github.com/NpoolPlatform/good-middleware v0.0.0-20230905075718-a4cefe1bff92/go.mod h1:z9+HCHM/HDJG0fvDbrA3a2DrMXfYgXb/WN/+ezBJIJs= -github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2 h1:5W7RWU/meU1ZkPiUjqKAnyBKsjJ6NZu3dCfc0hgjhRs= -github.com/NpoolPlatform/inspire-middleware v0.0.0-20230811101104-636b885293d2/go.mod h1:CCCI+S1AecMrRdRruOgMUxM9JaIXIYVt3DID04TuOoc= -github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7 h1:ol3ynwtsKf5SdLMEMjLDcas1s51mDPmImDJ9ZXw1Iac= -github.com/NpoolPlatform/ledger-middleware v0.0.0-20230904073215-11b88e0a0ea7/go.mod h1:lgAX07sFIVb9LnOJPCt9OMZRVLWqefnk+LBaSaCrWkM= +github.com/NpoolPlatform/good-middleware v0.0.0-20230908123355-e4a2233e306b h1:lhqocEijsl91RaayJaouDH8J55kdoloQNmKW/bFB+DA= +github.com/NpoolPlatform/good-middleware v0.0.0-20230908123355-e4a2233e306b/go.mod h1:mkTS2pNQhZjEZ/P6CDrD/Xn6cJsv404TWVjtOvvbFDM= +github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2 h1:gFrEiTDDu+F1F9XfrCyOjf+iVwpDRGddCaFxFNPHnp4= +github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2/go.mod h1:r8yyPbydrlL5MXMDT90qgqx/Y6mkCFEfOPdjxNavhJQ= +github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 h1:tv2Ze+8CzrUvfN4/I57fn3Z6KHJwSTZNi3NsFG78G9Q= +github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1/go.mod h1:t484//GSJFuy3Flc9puq2MJ628QotxoqA8Gy1Cou0W4= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB4NuhQxXWeV0Z1qSxgIqbiMYU30dqFGDLtgNTqYbE= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= github.com/NpoolPlatform/message v0.0.0-20230908135834-75858428a3cc h1:/KAPOupIOaDVvQvaVGVNkUgts7qI3AhqHWOmm8kRNKg= github.com/NpoolPlatform/message v0.0.0-20230908135834-75858428a3cc/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= -github.com/NpoolPlatform/order-middleware v0.0.0-20230908150842-e42cde949673 h1:K2ynoLI+que/OY1BbqfPO2M3SYXPSdiLow5oWEoZg8g= -github.com/NpoolPlatform/order-middleware v0.0.0-20230908150842-e42cde949673/go.mod h1:3fx7zmHgZJYo5Hi3wgCPr0BYUDTsUjGf4+nVVcGA/RU= +github.com/NpoolPlatform/order-middleware v0.0.0-20230908163651-e341753c1fc8 h1:xHMr7iEyiwMTKxLe/tEZgIsztJ6yVdAWCLfHwd2Fe30= +github.com/NpoolPlatform/order-middleware v0.0.0-20230908163651-e341753c1fc8/go.mod h1:3fx7zmHgZJYo5Hi3wgCPr0BYUDTsUjGf4+nVVcGA/RU= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b/go.mod h1:9C9XDi7c0szxcLdJGDDFuo3/KtC74yWiyUM2fR+i0ww= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= From e6aa27d78651cff42d3eae7a9ef6796a4bc26c27 Mon Sep 17 00:00:00 2001 From: jakys Date: Fri, 8 Sep 2023 17:06:12 +0000 Subject: [PATCH 41/67] Add transferamount --- go.mod | 4 ++-- go.sum | 8 ++++---- pkg/order/query.go | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 6ae7936..a9ce7a1 100644 --- a/go.mod +++ b/go.mod @@ -13,8 +13,8 @@ require ( github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 - github.com/NpoolPlatform/message v0.0.0-20230908135834-75858428a3cc - github.com/NpoolPlatform/order-middleware v0.0.0-20230908163651-e341753c1fc8 + github.com/NpoolPlatform/message v0.0.0-20230908170250-6063a3722b70 + github.com/NpoolPlatform/order-middleware v0.0.0-20230908170451-ffbcce45da8b github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/dtm-labs/dtm v1.17.1 github.com/go-resty/resty/v2 v2.7.0 diff --git a/go.sum b/go.sum index 9fcb132..9c9d5e6 100644 --- a/go.sum +++ b/go.sum @@ -68,10 +68,10 @@ github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 h1 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1/go.mod h1:t484//GSJFuy3Flc9puq2MJ628QotxoqA8Gy1Cou0W4= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB4NuhQxXWeV0Z1qSxgIqbiMYU30dqFGDLtgNTqYbE= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= -github.com/NpoolPlatform/message v0.0.0-20230908135834-75858428a3cc h1:/KAPOupIOaDVvQvaVGVNkUgts7qI3AhqHWOmm8kRNKg= -github.com/NpoolPlatform/message v0.0.0-20230908135834-75858428a3cc/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= -github.com/NpoolPlatform/order-middleware v0.0.0-20230908163651-e341753c1fc8 h1:xHMr7iEyiwMTKxLe/tEZgIsztJ6yVdAWCLfHwd2Fe30= -github.com/NpoolPlatform/order-middleware v0.0.0-20230908163651-e341753c1fc8/go.mod h1:3fx7zmHgZJYo5Hi3wgCPr0BYUDTsUjGf4+nVVcGA/RU= +github.com/NpoolPlatform/message v0.0.0-20230908170250-6063a3722b70 h1:JzRJbaI+wPS/tAi9MCiPOCIcvfVE1Zm5Ng/zHvVGbCM= +github.com/NpoolPlatform/message v0.0.0-20230908170250-6063a3722b70/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/order-middleware v0.0.0-20230908170451-ffbcce45da8b h1:W/SaTmeFGmU8aCWyH8hDvQyTMb+XLI+oO1WABnHMqiU= +github.com/NpoolPlatform/order-middleware v0.0.0-20230908170451-ffbcce45da8b/go.mod h1:DLqs5/NTMeLI3EBq8ivyIO9HHQ7zNHegtw5vFb3GUKU= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b/go.mod h1:9C9XDi7c0szxcLdJGDDFuo3/KtC74yWiyUM2fR+i0ww= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= diff --git a/pkg/order/query.go b/pkg/order/query.go index 53512b3..e36c071 100644 --- a/pkg/order/query.go +++ b/pkg/order/query.go @@ -229,6 +229,7 @@ func (h *queryHandler) formalize(ctx context.Context) { //nolint PaymentStartAmount: ord.PaymentStartAmount, PaymentFinishAmount: ord.PaymentFinishAmount, PayWithBalanceAmount: ord.BalanceAmount, + TransferAmount: ord.TransferAmount, OrderType: ord.OrderType, PaymentType: ord.PaymentType, CreatedAt: ord.CreatedAt, From ef869f219320d71beeb43bc5373c4a880f99dae9 Mon Sep 17 00:00:00 2001 From: jakys Date: Sat, 9 Sep 2023 04:09:26 +0000 Subject: [PATCH 42/67] Add coupon limit check --- pkg/order/creates.go | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/pkg/order/creates.go b/pkg/order/creates.go index d0a187f..f81fd2b 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -8,6 +8,7 @@ import ( payaccmwcli "github.com/NpoolPlatform/account-middleware/pkg/client/payment" accountlock "github.com/NpoolPlatform/account-middleware/pkg/lock" accountmwsvcname "github.com/NpoolPlatform/account-middleware/pkg/servicename" + appmwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/app" usermwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" appcoinmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/app/coin" currencymwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin/currency" @@ -21,6 +22,7 @@ import ( ledgermwsvcname "github.com/NpoolPlatform/ledger-middleware/pkg/servicename" cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" payaccmwpb "github.com/NpoolPlatform/message/npool/account/mw/v1/payment" + appmwpb "github.com/NpoolPlatform/message/npool/appuser/mw/v1/app" usermwpb "github.com/NpoolPlatform/message/npool/appuser/mw/v1/user" goodtypes "github.com/NpoolPlatform/message/npool/basetypes/good/v1" inspiretypes "github.com/NpoolPlatform/message/npool/basetypes/inspire/v1" @@ -49,6 +51,7 @@ import ( type createsHandler struct { *Handler ids map[string]*string + app *appmwpb.App user *usermwpb.User appGoods map[string]*appgoodmwpb.Good goodRequireds []*goodrequiredpb.Required @@ -82,6 +85,18 @@ func (h *createsHandler) tomorrowStart() time.Time { return time.Date(y, m, d+1, 0, 0, 0, 0, now.Location()) } +func (h *createsHandler) getApp(ctx context.Context) error { + app, err := appmwcli.GetApp(ctx, *h.AppID) + if err != nil { + return err + } + if app == nil { + return fmt.Errorf("invalid app") + } + h.app = app + return nil +} + func (h *createsHandler) getUser(ctx context.Context) error { user, err := usermwcli.GetUser(ctx, *h.AppID, *h.UserID) if err != nil { @@ -137,14 +152,24 @@ func (h *createsHandler) getCoupons(ctx context.Context) error { func (h *createsHandler) validateDiscountCoupon() error { discountCoupons := 0 + fixAmountCoupons := uint32(0) + specialOfferCoupons := uint32(0) for _, coupon := range h.coupons { - if coupon.CouponType == inspiretypes.CouponType_Discount { + switch coupon.CouponType { + case inspiretypes.CouponType_Discount: discountCoupons++ + case inspiretypes.CouponType_FixAmount: + fixAmountCoupons++ + case inspiretypes.CouponType_SpecialOffer: + specialOfferCoupons++ } } if discountCoupons > 1 { return fmt.Errorf("invalid discountcoupon") } + if fixAmountCoupons > h.app.MaxTypedCouponsPerOrder || specialOfferCoupons > h.app.MaxTypedCouponsPerOrder { + return fmt.Errorf("invalid fixamountcoupon") + } return nil } @@ -788,6 +813,9 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e orderEndAt: map[string]uint32{}, stockLockIDs: map[string]*string{}, } + if err := handler.getApp(ctx); err != nil { + return nil, err + } if err := handler.getUser(ctx); err != nil { return nil, err } From 22ad6330487d79c86ddc2ca4b93f68f7ba85afaf Mon Sep 17 00:00:00 2001 From: jakys Date: Sat, 9 Sep 2023 04:09:50 +0000 Subject: [PATCH 43/67] Add goodrequired check --- pkg/order/create.go | 105 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/pkg/order/create.go b/pkg/order/create.go index b5fa846..59ebbbf 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -8,6 +8,7 @@ import ( payaccmwcli "github.com/NpoolPlatform/account-middleware/pkg/client/payment" accountlock "github.com/NpoolPlatform/account-middleware/pkg/lock" accountmwsvcname "github.com/NpoolPlatform/account-middleware/pkg/servicename" + appmwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/app" usermwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" appcoinmwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/app/coin" currencymwcli "github.com/NpoolPlatform/chain-middleware/pkg/client/coin/currency" @@ -16,11 +17,13 @@ import ( redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" topmostmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/topmost/good" + goodrequiredmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good/required" goodmwsvcname "github.com/NpoolPlatform/good-middleware/pkg/servicename" allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" ledgermwsvcname "github.com/NpoolPlatform/ledger-middleware/pkg/servicename" cruder "github.com/NpoolPlatform/libent-cruder/pkg/cruder" payaccmwpb "github.com/NpoolPlatform/message/npool/account/mw/v1/payment" + appmwpb "github.com/NpoolPlatform/message/npool/appuser/mw/v1/app" usermwpb "github.com/NpoolPlatform/message/npool/appuser/mw/v1/user" goodtypes "github.com/NpoolPlatform/message/npool/basetypes/good/v1" inspiretypes "github.com/NpoolPlatform/message/npool/basetypes/inspire/v1" @@ -31,6 +34,7 @@ import ( appgoodmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good" appgoodstockmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/stock" topmostmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/topmost/good" + goodrequiredpb "github.com/NpoolPlatform/message/npool/good/mw/v1/good/required" allocatedmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/coupon/allocated" ledgermwpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger" npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" @@ -47,8 +51,10 @@ import ( type createHandler struct { *Handler + app *appmwpb.App user *usermwpb.User appGood *appgoodmwpb.Good + parentOrder *ordermwpb.Order paymentCoin *appcoinmwpb.Coin paymentAccount *payaccmwpb.Account paymentStartAmount decimal.Decimal @@ -84,6 +90,18 @@ func (h *createHandler) getUser(ctx context.Context) error { return nil } +func (h *createHandler) getApp(ctx context.Context) error { + app, err := appmwcli.GetApp(ctx, *h.AppID) + if err != nil { + return err + } + if app == nil { + return fmt.Errorf("invalid app") + } + h.app = app + return nil +} + func (h *createHandler) getPaymentCoin(ctx context.Context) error { coin, err := appcoinmwcli.GetCoinOnly(ctx, &appcoinmwpb.Conds{ AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, @@ -127,14 +145,24 @@ func (h *createHandler) getCoupons(ctx context.Context) error { func (h *createHandler) validateDiscountCoupon() error { discountCoupons := 0 + fixAmountCoupons := uint32(0) + specialOfferCoupons := uint32(0) for _, coupon := range h.coupons { - if coupon.CouponType == inspiretypes.CouponType_Discount { + switch coupon.CouponType { + case inspiretypes.CouponType_Discount: discountCoupons++ + case inspiretypes.CouponType_FixAmount: + fixAmountCoupons++ + case inspiretypes.CouponType_SpecialOffer: + specialOfferCoupons++ } } if discountCoupons > 1 { return fmt.Errorf("invalid discountcoupon") } + if fixAmountCoupons > h.app.MaxTypedCouponsPerOrder || specialOfferCoupons > h.app.MaxTypedCouponsPerOrder { + return fmt.Errorf("invalid fixamountcoupon") + } return nil } @@ -234,6 +262,69 @@ func (h *createHandler) checkUnitsLimit(ctx context.Context) error { return nil } +func (h *createHandler) getParentOrder(ctx context.Context) error { + if h.ParentOrderID == nil { + return nil + } + order, err := ordermwcli.GetOrder(ctx, *h.ParentOrderID) + if err != nil { + return err + } + if order == nil { + return fmt.Errorf("invalid parentorderid") + } + h.parentOrder = order + return nil +} + +func (h *createHandler) checkParentOrderGoodRequired(ctx context.Context) error { + if h.ParentOrderID == nil { + return nil + } + goodRequired, err := goodrequiredmwcli.GetRequiredOnly(ctx, &goodrequiredpb.Conds{ + MainGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.parentOrder.GoodID}, + RequiredGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.appGood.GoodID}, + }) + if err != nil { + return err + } + if goodRequired == nil { + return fmt.Errorf("invalid goodrequired") + } + return nil +} + +func (h *createHandler) checkGoodRequests(ctx context.Context) error { + if h.ParentOrderID != nil { + return nil + } + goodRequireds, _, err := goodrequiredmwcli.GetRequireds(ctx, &goodrequiredpb.Conds{ + MainGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.appGood.GoodID}, + }, 0, 0) + if err != nil { + return err + } + if len(goodRequireds) == 0 { + goodRequireds, _, err = goodrequiredmwcli.GetRequireds(ctx, &goodrequiredpb.Conds{ + RequiredGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.appGood.GoodID}, + }, 0, 1) + if err != nil { + return err + } + if len(goodRequireds) > 0 { + return fmt.Errorf("parentorderid is empty") + } + return nil + } + + for _, goodRequired := range goodRequireds { + if goodRequired.Must { + return fmt.Errorf("invalid must goodrequired") + } + } + return nil +} + func (h *createHandler) getAppGoodPromotion(ctx context.Context) error { promotion, err := topmostmwcli.GetTopMostGoodOnly(ctx, &topmostmwpb.Conds{ AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, @@ -711,6 +802,9 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error Handler: h, coupons: map[string]*allocatedmwpb.Coupon{}, } + if err := handler.getApp(ctx); err != nil { + return nil, err + } if err := handler.getUser(ctx); err != nil { return nil, err } @@ -735,6 +829,15 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error if err := handler.checkUnitsLimit(ctx); err != nil { return nil, err } + if err := handler.getParentOrder(ctx); err != nil { + return nil, err + } + if err := handler.checkParentOrderGoodRequired(ctx); err != nil { + return nil, err + } + if err := handler.checkGoodRequests(ctx); err != nil { + return nil, err + } if err := handler.getAppGoodPromotion(ctx); err != nil { return nil, err } From ed5e53b900dbc5fef6db6321a7c82e9ca2d7d73e Mon Sep 17 00:00:00 2001 From: jakys Date: Sat, 9 Sep 2023 07:27:06 +0000 Subject: [PATCH 44/67] Fix goodrequest check --- pkg/order/create.go | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/pkg/order/create.go b/pkg/order/create.go index 59ebbbf..898cf20 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -294,7 +294,7 @@ func (h *createHandler) checkParentOrderGoodRequired(ctx context.Context) error return nil } -func (h *createHandler) checkGoodRequests(ctx context.Context) error { +func (h *createHandler) checkGoodRequestMust(ctx context.Context) error { if h.ParentOrderID != nil { return nil } @@ -304,19 +304,6 @@ func (h *createHandler) checkGoodRequests(ctx context.Context) error { if err != nil { return err } - if len(goodRequireds) == 0 { - goodRequireds, _, err = goodrequiredmwcli.GetRequireds(ctx, &goodrequiredpb.Conds{ - RequiredGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.appGood.GoodID}, - }, 0, 1) - if err != nil { - return err - } - if len(goodRequireds) > 0 { - return fmt.Errorf("parentorderid is empty") - } - return nil - } - for _, goodRequired := range goodRequireds { if goodRequired.Must { return fmt.Errorf("invalid must goodrequired") @@ -325,6 +312,24 @@ func (h *createHandler) checkGoodRequests(ctx context.Context) error { return nil } +func (h *createHandler) checkGoodRequest(ctx context.Context) error { + if h.ParentOrderID != nil { + return nil + } + + goodRequireds, _, err := goodrequiredmwcli.GetRequireds(ctx, &goodrequiredpb.Conds{ + RequiredGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.appGood.GoodID}, + }, 0, 1) + if err != nil { + return err + } + if len(goodRequireds) > 0 { + return fmt.Errorf("parentorderid is empty") + } + + return nil +} + func (h *createHandler) getAppGoodPromotion(ctx context.Context) error { promotion, err := topmostmwcli.GetTopMostGoodOnly(ctx, &topmostmwpb.Conds{ AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, @@ -835,7 +840,10 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error if err := handler.checkParentOrderGoodRequired(ctx); err != nil { return nil, err } - if err := handler.checkGoodRequests(ctx); err != nil { + if err := handler.checkGoodRequestMust(ctx); err != nil { + return nil, err + } + if err := handler.checkGoodRequest(ctx); err != nil { return nil, err } if err := handler.getAppGoodPromotion(ctx); err != nil { From d45adf4657c0d638e87541857a8cf75c3198eb1e Mon Sep 17 00:00:00 2001 From: root Date: Sat, 9 Sep 2023 08:02:48 +0000 Subject: [PATCH 45/67] fix update --- pkg/order/update.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pkg/order/update.go b/pkg/order/update.go index fe117c1..4842cdd 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -6,6 +6,7 @@ import ( "time" dtmcli "github.com/NpoolPlatform/dtm-cluster/pkg/dtm" + "github.com/NpoolPlatform/go-service-framework/pkg/logger" ledgermwsvcname "github.com/NpoolPlatform/ledger-middleware/pkg/servicename" "github.com/NpoolPlatform/libent-cruder/pkg/cruder" ordermwsvcname "github.com/NpoolPlatform/order-middleware/pkg/servicename" @@ -125,10 +126,7 @@ func (h *updateHandler) checkOrderType() error { } func (h *updateHandler) getAppGood(ctx context.Context) error { - good, err := appgoodmwcli.GetGoodOnly(ctx, &appgoodmwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: h.order.AppID}, - GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.order.GoodID}, - }) + good, err := appgoodmwcli.GetGood(ctx, h.order.AppGoodID) if err != nil { return err } @@ -147,8 +145,11 @@ func (h *updateHandler) checkGood(ctx context.Context) error { if good == nil { return fmt.Errorf("invalid good") } - if good.RewardState != goodtypes.BenefitState_BenefitWait { - return fmt.Errorf("app good uncancellable benefit state not wait") + switch good.RewardState { + case goodtypes.BenefitState_BenefitWait: + case goodtypes.BenefitState_BenefitCheckWait: + default: + return fmt.Errorf("permission denied") } return nil } From f8771c0c8ed14961fe8e191409aade93376dae62 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 9 Sep 2023 08:04:39 +0000 Subject: [PATCH 46/67] fix update --- pkg/order/update.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/order/update.go b/pkg/order/update.go index 4842cdd..9345ea4 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -6,7 +6,6 @@ import ( "time" dtmcli "github.com/NpoolPlatform/dtm-cluster/pkg/dtm" - "github.com/NpoolPlatform/go-service-framework/pkg/logger" ledgermwsvcname "github.com/NpoolPlatform/ledger-middleware/pkg/servicename" "github.com/NpoolPlatform/libent-cruder/pkg/cruder" ordermwsvcname "github.com/NpoolPlatform/order-middleware/pkg/servicename" From 906ade88a81eb794430e03658be824ff461054b9 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Sat, 9 Sep 2023 13:32:14 +0000 Subject: [PATCH 47/67] Do not allow cancel again --- pkg/order/update.go | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/pkg/order/update.go b/pkg/order/update.go index fe117c1..5842d0a 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -5,39 +5,33 @@ import ( "fmt" "time" - dtmcli "github.com/NpoolPlatform/dtm-cluster/pkg/dtm" + usermwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" + appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" + goodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good" + statementmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/achievement/statement" + goodledgerstatementcli "github.com/NpoolPlatform/ledger-middleware/pkg/client/good/ledger/statement" + ledgerstatementcli "github.com/NpoolPlatform/ledger-middleware/pkg/client/ledger/statement" ledgermwsvcname "github.com/NpoolPlatform/ledger-middleware/pkg/servicename" "github.com/NpoolPlatform/libent-cruder/pkg/cruder" - ordermwsvcname "github.com/NpoolPlatform/order-middleware/pkg/servicename" - "github.com/dtm-labs/dtm/client/dtmcli/dtmimp" - "github.com/google/uuid" - goodtypes "github.com/NpoolPlatform/message/npool/basetypes/good/v1" ledgertypes "github.com/NpoolPlatform/message/npool/basetypes/ledger/v1" ordertypes "github.com/NpoolPlatform/message/npool/basetypes/order/v1" basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" - - appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" - goodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good" appgoodmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good" - - npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" - ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" - ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" - - goodledgerstatementcli "github.com/NpoolPlatform/ledger-middleware/pkg/client/good/ledger/statement" - - ledgerstatementcli "github.com/NpoolPlatform/ledger-middleware/pkg/client/ledger/statement" + statementmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/achievement/statement" goodledgerstatementpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/good/ledger/statement" ledgermwpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger" ledgerstatementpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger/statement" - + npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" + ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" orderlockmwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order/orderlock" + ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" + ordermwsvcname "github.com/NpoolPlatform/order-middleware/pkg/servicename" - usermwcli "github.com/NpoolPlatform/appuser-middleware/pkg/client/user" - statementmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/achievement/statement" - statementmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/achievement/statement" + dtmcli "github.com/NpoolPlatform/dtm-cluster/pkg/dtm" + "github.com/dtm-labs/dtm/client/dtmcli/dtmimp" + "github.com/google/uuid" "github.com/shopspring/decimal" ) @@ -59,6 +53,9 @@ func (h *updateHandler) checkCancelParam() error { if h.AdminSetCanceled != nil && !*h.AdminSetCanceled { return fmt.Errorf("nothing todo") } + if h.order.AdminSetCanceled || h.order.UserSetCanceled { + return fmt.Errorf("permission denied") + } return nil } @@ -315,15 +312,15 @@ func (h *Handler) UpdateOrder(ctx context.Context) (*npool.Order, error) { Handler: h, commissionLockIDs: map[string]*string{}, } - if err := handler.checkCancelParam(); err != nil { - return nil, err - } if err := handler.checkUser(ctx); err != nil { return nil, err } if err := handler.checkOrder(ctx); err != nil { return nil, err } + if err := handler.checkCancelParam(); err != nil { + return nil, err + } if err := handler.checkOrderType(); err != nil { return nil, err } From 1b11a25ef30a8cf93cc65342ea53f68fadf989b6 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Sun, 10 Sep 2023 09:16:52 +0000 Subject: [PATCH 48/67] Update good middleware --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- pkg/order/update.go | 5 ----- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index a9ce7a1..a4680af 100644 --- a/go.mod +++ b/go.mod @@ -5,16 +5,16 @@ go 1.17 require ( github.com/NpoolPlatform/account-middleware v0.0.0-20230908122122-cd58a2b8c771 github.com/NpoolPlatform/appuser-middleware v0.0.0-20230513100509-b19f356ebd4b - github.com/NpoolPlatform/basal-middleware v0.0.0-20230518061816-62bd589c0f63 + github.com/NpoolPlatform/basal-middleware v0.0.0-20230908131959-b37594a23afd github.com/NpoolPlatform/chain-middleware v0.0.0-20230906092012-a63f3a7b0b54 github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821 github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e - github.com/NpoolPlatform/good-middleware v0.0.0-20230908123355-e4a2233e306b + github.com/NpoolPlatform/good-middleware v0.0.0-20230910065023-298572ba5a77 github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 - github.com/NpoolPlatform/message v0.0.0-20230908170250-6063a3722b70 - github.com/NpoolPlatform/order-middleware v0.0.0-20230908170451-ffbcce45da8b + github.com/NpoolPlatform/message v0.0.0-20230910084107-20b881ec2c83 + github.com/NpoolPlatform/order-middleware v0.0.0-20230910084334-a36daf34001f github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/dtm-labs/dtm v1.17.1 github.com/go-resty/resty/v2 v2.7.0 diff --git a/go.sum b/go.sum index 9c9d5e6..9a6bc6b 100644 --- a/go.sum +++ b/go.sum @@ -52,26 +52,26 @@ github.com/NpoolPlatform/account-middleware v0.0.0-20230908122122-cd58a2b8c771 h github.com/NpoolPlatform/account-middleware v0.0.0-20230908122122-cd58a2b8c771/go.mod h1:5Labnj7w3bY+FKWSDGu/bRasE2obtkfSbYlcrvYJaaI= github.com/NpoolPlatform/appuser-middleware v0.0.0-20230513100509-b19f356ebd4b h1:YmlmVjzJLebnrNl9dtFiJ6bfgqoH++uFe91esScPanE= github.com/NpoolPlatform/appuser-middleware v0.0.0-20230513100509-b19f356ebd4b/go.mod h1:BzT48sEK4KSO6Gy8VJQa5rOuO5JpXib/cmLGHWt4Aqc= -github.com/NpoolPlatform/basal-middleware v0.0.0-20230518061816-62bd589c0f63 h1:wQ+crGIMDqv7919i5slVz8liCjBhCZz8xZxHWC3N8uA= -github.com/NpoolPlatform/basal-middleware v0.0.0-20230518061816-62bd589c0f63/go.mod h1:3sHDVUUQHRkZsCiBFI6CdCL2HWf3cO7/E2DZU3nHMfE= +github.com/NpoolPlatform/basal-middleware v0.0.0-20230908131959-b37594a23afd h1:lAg78Zw3w8WbcJ+D9mMO0SdVPAzePNYL33Cqc9l4PP8= +github.com/NpoolPlatform/basal-middleware v0.0.0-20230908131959-b37594a23afd/go.mod h1:XN8xmZjgdG3M4NvPAx4eadIVok/LUJ76DlnQyXOy38M= github.com/NpoolPlatform/chain-middleware v0.0.0-20230906092012-a63f3a7b0b54 h1:wnYxTar4XI8M+c7ECl52S9emUwiSDdf/etIlLcMv5L4= github.com/NpoolPlatform/chain-middleware v0.0.0-20230906092012-a63f3a7b0b54/go.mod h1:y3bX+6Yt8cz5s6aQypnqbQzttbwVTOuhK++LU1OBvxA= github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821 h1:JEoN8rpjyJOpbXXLhL5J6Fjw+/bOTwMNci6CL7G02zQ= github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821/go.mod h1:ZBvGIj+zt7VT6WbnIeU/fhiI/dEoNK4JqcXE1EIblpQ= github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e h1:17BGexCmCdOOBXKYogP8RNE+pAHRu2N4LKq9znPJ4vc= github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e/go.mod h1:Kh7DMkWnYOMHxEKq7QfJqbxm1HaUPkhTNN74lfHQxyE= -github.com/NpoolPlatform/good-middleware v0.0.0-20230908123355-e4a2233e306b h1:lhqocEijsl91RaayJaouDH8J55kdoloQNmKW/bFB+DA= -github.com/NpoolPlatform/good-middleware v0.0.0-20230908123355-e4a2233e306b/go.mod h1:mkTS2pNQhZjEZ/P6CDrD/Xn6cJsv404TWVjtOvvbFDM= +github.com/NpoolPlatform/good-middleware v0.0.0-20230910065023-298572ba5a77 h1:0L1GcpIks4L7KaD4Fdb6gnZjBHziNKMwYb2q0yZ01lg= +github.com/NpoolPlatform/good-middleware v0.0.0-20230910065023-298572ba5a77/go.mod h1:PaLlBl1fmKHfpzLOXFblfaaosElBa7XXRYaZYv7Lu0Y= github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2 h1:gFrEiTDDu+F1F9XfrCyOjf+iVwpDRGddCaFxFNPHnp4= github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2/go.mod h1:r8yyPbydrlL5MXMDT90qgqx/Y6mkCFEfOPdjxNavhJQ= github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 h1:tv2Ze+8CzrUvfN4/I57fn3Z6KHJwSTZNi3NsFG78G9Q= github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1/go.mod h1:t484//GSJFuy3Flc9puq2MJ628QotxoqA8Gy1Cou0W4= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB4NuhQxXWeV0Z1qSxgIqbiMYU30dqFGDLtgNTqYbE= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= -github.com/NpoolPlatform/message v0.0.0-20230908170250-6063a3722b70 h1:JzRJbaI+wPS/tAi9MCiPOCIcvfVE1Zm5Ng/zHvVGbCM= -github.com/NpoolPlatform/message v0.0.0-20230908170250-6063a3722b70/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= -github.com/NpoolPlatform/order-middleware v0.0.0-20230908170451-ffbcce45da8b h1:W/SaTmeFGmU8aCWyH8hDvQyTMb+XLI+oO1WABnHMqiU= -github.com/NpoolPlatform/order-middleware v0.0.0-20230908170451-ffbcce45da8b/go.mod h1:DLqs5/NTMeLI3EBq8ivyIO9HHQ7zNHegtw5vFb3GUKU= +github.com/NpoolPlatform/message v0.0.0-20230910084107-20b881ec2c83 h1:jzgG9DtFrh5BJ7PQASgq9zRt8d0zFk3hR0jPgSRFIJY= +github.com/NpoolPlatform/message v0.0.0-20230910084107-20b881ec2c83/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/order-middleware v0.0.0-20230910084334-a36daf34001f h1:+gVM4RAJbTuvf33Yhh+yMQLX/ElasCFB4X5Pfli1d5c= +github.com/NpoolPlatform/order-middleware v0.0.0-20230910084334-a36daf34001f/go.mod h1:JuuoEDzZCP1oFXI6aosXytD85iz7w3pUs+geEkjvaWQ= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b/go.mod h1:9C9XDi7c0szxcLdJGDDFuo3/KtC74yWiyUM2fR+i0ww= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= diff --git a/pkg/order/update.go b/pkg/order/update.go index b6793d8..d24f41e 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -93,8 +93,6 @@ func (h *updateHandler) checkOrderType() error { case ordertypes.OrderType_Normal: switch h.order.OrderState { case ordertypes.OrderState_OrderStateWaitPayment: - fallthrough //nolint - case ordertypes.OrderState_OrderStateCheckPayment: if h.AdminSetCanceled != nil { return fmt.Errorf("permission denied") } @@ -143,7 +141,6 @@ func (h *updateHandler) checkGood(ctx context.Context) error { } switch good.RewardState { case goodtypes.BenefitState_BenefitWait: - case goodtypes.BenefitState_BenefitCheckWait: default: return fmt.Errorf("permission denied") } @@ -160,8 +157,6 @@ func (h *updateHandler) checkCancelable(ctx context.Context) error { switch h.order.OrderState { case ordertypes.OrderState_OrderStateWaitPayment: - fallthrough //nolint - case ordertypes.OrderState_OrderStateCheckPayment: return nil } From 5e8ce7bb0b98eb4a9d70905acd63b1321d1cf1dc Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Sun, 10 Sep 2023 11:44:51 +0000 Subject: [PATCH 49/67] Avoid create order of deleted good --- go.mod | 4 ++-- go.sum | 8 ++++---- pkg/order/create.go | 21 +++++++++++++++++++++ pkg/order/update.go | 3 +++ 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index a4680af..a62e5c9 100644 --- a/go.mod +++ b/go.mod @@ -13,8 +13,8 @@ require ( github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 - github.com/NpoolPlatform/message v0.0.0-20230910084107-20b881ec2c83 - github.com/NpoolPlatform/order-middleware v0.0.0-20230910084334-a36daf34001f + github.com/NpoolPlatform/message v0.0.0-20230910104610-f9bf310924c8 + github.com/NpoolPlatform/order-middleware v0.0.0-20230910111152-0dc718973845 github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/dtm-labs/dtm v1.17.1 github.com/go-resty/resty/v2 v2.7.0 diff --git a/go.sum b/go.sum index 9a6bc6b..ff059c2 100644 --- a/go.sum +++ b/go.sum @@ -68,10 +68,10 @@ github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 h1 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1/go.mod h1:t484//GSJFuy3Flc9puq2MJ628QotxoqA8Gy1Cou0W4= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB4NuhQxXWeV0Z1qSxgIqbiMYU30dqFGDLtgNTqYbE= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= -github.com/NpoolPlatform/message v0.0.0-20230910084107-20b881ec2c83 h1:jzgG9DtFrh5BJ7PQASgq9zRt8d0zFk3hR0jPgSRFIJY= -github.com/NpoolPlatform/message v0.0.0-20230910084107-20b881ec2c83/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= -github.com/NpoolPlatform/order-middleware v0.0.0-20230910084334-a36daf34001f h1:+gVM4RAJbTuvf33Yhh+yMQLX/ElasCFB4X5Pfli1d5c= -github.com/NpoolPlatform/order-middleware v0.0.0-20230910084334-a36daf34001f/go.mod h1:JuuoEDzZCP1oFXI6aosXytD85iz7w3pUs+geEkjvaWQ= +github.com/NpoolPlatform/message v0.0.0-20230910104610-f9bf310924c8 h1:F42xoYze8aqR9XHHWj3SfbYCEVSWKUqcpaSAF8zpc54= +github.com/NpoolPlatform/message v0.0.0-20230910104610-f9bf310924c8/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/order-middleware v0.0.0-20230910111152-0dc718973845 h1:RsnoFXjSwG4hV2Op/c8088ylbYZ8NknlUTs2+oVLg2c= +github.com/NpoolPlatform/order-middleware v0.0.0-20230910111152-0dc718973845/go.mod h1:sou8KMb443BSROjGWE+CrIGF9k1Uv0draCpkj9jE+Ls= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b/go.mod h1:9C9XDi7c0szxcLdJGDDFuo3/KtC74yWiyUM2fR+i0ww= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= diff --git a/pkg/order/create.go b/pkg/order/create.go index 898cf20..2fa58d6 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -17,6 +17,7 @@ import ( redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" topmostmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/topmost/good" + goodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good" goodrequiredmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good/required" goodmwsvcname "github.com/NpoolPlatform/good-middleware/pkg/servicename" allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" @@ -172,6 +173,7 @@ func (h *createHandler) checkMaxUnpaidOrders(ctx context.Context) error { orderCount, err := ordermwcli.CountOrders(ctx, &ordermwpb.Conds{ AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + OrderType: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(types.OrderType_Normal)}, PaymentState: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(types.PaymentState_PaymentStateWait)}, }) if err != nil { @@ -196,6 +198,22 @@ func (h *createHandler) getAppGood(ctx context.Context) error { return nil } +func (h *createHandler) checkGood(ctx context.Context) error { + good, err := goodmwcli.GetGood(ctx, h.appGood.GoodID) + if err != nil { + return err + } + if good == nil { + return fmt.Errorf("invalid good") + } + switch good.RewardState { + case goodtypes.BenefitState_BenefitWait: + default: + return fmt.Errorf("permission denied") + } + return nil +} + func (h *createHandler) checkAppGoodCoin(ctx context.Context) error { goodCoin, err := appcoinmwcli.GetCoinOnly(ctx, &appcoinmwpb.Conds{ AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, @@ -828,6 +846,9 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error if err := handler.getAppGood(ctx); err != nil { return nil, err } + if err := handler.checkGood(ctx); err != nil { + return nil, err + } if err := handler.checkAppGoodCoin(ctx); err != nil { return nil, err } diff --git a/pkg/order/update.go b/pkg/order/update.go index d24f41e..ae8b83e 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -127,6 +127,9 @@ func (h *updateHandler) getAppGood(ctx context.Context) error { if good == nil { return fmt.Errorf("invalid appgood") } + if good.AppID != *h.AppID || good.GoodID != h.order.GoodID { + return fmt.Errorf("invalid appgood") + } h.appGood = good return nil } From 4c5f324af3c11cbcea29db6c5f3f75568c7efbdc Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Sun, 10 Sep 2023 11:51:09 +0000 Subject: [PATCH 50/67] Add user set canceled --- go.mod | 2 +- go.sum | 4 ++-- pkg/order/query.go | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a62e5c9..d335dcb 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 - github.com/NpoolPlatform/message v0.0.0-20230910104610-f9bf310924c8 + github.com/NpoolPlatform/message v0.0.0-20230910114939-93fab576f50a github.com/NpoolPlatform/order-middleware v0.0.0-20230910111152-0dc718973845 github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/dtm-labs/dtm v1.17.1 diff --git a/go.sum b/go.sum index ff059c2..121e0aa 100644 --- a/go.sum +++ b/go.sum @@ -68,8 +68,8 @@ github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 h1 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1/go.mod h1:t484//GSJFuy3Flc9puq2MJ628QotxoqA8Gy1Cou0W4= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB4NuhQxXWeV0Z1qSxgIqbiMYU30dqFGDLtgNTqYbE= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= -github.com/NpoolPlatform/message v0.0.0-20230910104610-f9bf310924c8 h1:F42xoYze8aqR9XHHWj3SfbYCEVSWKUqcpaSAF8zpc54= -github.com/NpoolPlatform/message v0.0.0-20230910104610-f9bf310924c8/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/message v0.0.0-20230910114939-93fab576f50a h1:TDB0pOYgbmGY7Ka1HU5A+Q/Sv2QNJCnG/7GP/RtiGb8= +github.com/NpoolPlatform/message v0.0.0-20230910114939-93fab576f50a/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= github.com/NpoolPlatform/order-middleware v0.0.0-20230910111152-0dc718973845 h1:RsnoFXjSwG4hV2Op/c8088ylbYZ8NknlUTs2+oVLg2c= github.com/NpoolPlatform/order-middleware v0.0.0-20230910111152-0dc718973845/go.mod h1:sou8KMb443BSROjGWE+CrIGF9k1Uv0draCpkj9jE+Ls= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= diff --git a/pkg/order/query.go b/pkg/order/query.go index e36c071..02fea94 100644 --- a/pkg/order/query.go +++ b/pkg/order/query.go @@ -220,6 +220,8 @@ func (h *queryHandler) formalize(ctx context.Context) { //nolint ParentOrderID: ord.ParentOrderID, Units: ord.Units, GoodValue: ord.GoodValue, + UserSetCanceled: ord.UserSetCanceled, + AdminSetCanceled: ord.AdminSetCanceled, PaymentID: ord.PaymentID, PaymentCoinTypeID: ord.PaymentCoinTypeID, PaymentCoinUSDCurrency: ord.CoinUSDCurrency, From 39ee18be2187394c3a8956aff39398bf6058f493 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Sun, 10 Sep 2023 12:11:33 +0000 Subject: [PATCH 51/67] Correct invalid good --- pkg/order/create.go | 21 ++++++-------- pkg/order/creates.go | 66 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 19 deletions(-) diff --git a/pkg/order/create.go b/pkg/order/create.go index 2fa58d6..96c395c 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -206,11 +206,6 @@ func (h *createHandler) checkGood(ctx context.Context) error { if good == nil { return fmt.Errorf("invalid good") } - switch good.RewardState { - case goodtypes.BenefitState_BenefitWait: - default: - return fmt.Errorf("permission denied") - } return nil } @@ -910,18 +905,18 @@ func (h *Handler) CreateOrder(ctx context.Context) (info *npool.Order, err error } } - id := uuid.NewString() + id1 := uuid.NewString() if h.ID == nil { - h.ID = &id + h.ID = &id1 } - id = uuid.NewString() - handler.stockLockID = &id - if handler.balanceCoinAmount.Cmp(decimal.NewFromInt(0)) <= 0 { - id := uuid.NewString() - handler.balanceLockID = &id + id2 := uuid.NewString() + handler.stockLockID = &id2 + if handler.balanceCoinAmount.Cmp(decimal.NewFromInt(0)) > 0 { + id3 := uuid.NewString() + handler.balanceLockID = &id3 } - key := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, id) + key := fmt.Sprintf("%v:%v:%v:%v", basetypes.Prefix_PrefixCreateOrder, *h.AppID, *h.UserID, id1) if err := redis2.TryLock(key, 0); err != nil { return nil, err } diff --git a/pkg/order/creates.go b/pkg/order/creates.go index f81fd2b..1f338b7 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -16,6 +16,7 @@ import ( redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" appgoodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good" topmostmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/app/good/topmost/good" + goodmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good" goodrequiredmwcli "github.com/NpoolPlatform/good-middleware/pkg/client/good/required" goodmwsvcname "github.com/NpoolPlatform/good-middleware/pkg/servicename" allocatedmwcli "github.com/NpoolPlatform/inspire-middleware/pkg/client/coupon/allocated" @@ -33,6 +34,7 @@ import ( appgoodmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good" appgoodstockmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/stock" topmostmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/app/good/topmost/good" + goodmwpb "github.com/NpoolPlatform/message/npool/good/mw/v1/good" goodrequiredpb "github.com/NpoolPlatform/message/npool/good/mw/v1/good/required" allocatedmwpb "github.com/NpoolPlatform/message/npool/inspire/mw/v1/coupon/allocated" ledgermwpb "github.com/NpoolPlatform/message/npool/ledger/mw/v2/ledger" @@ -54,6 +56,9 @@ type createsHandler struct { app *appmwpb.App user *usermwpb.User appGoods map[string]*appgoodmwpb.Good + goods map[string]*goodmwpb.Good + parentAppGood *appgoodmwpb.Good + parentGood *goodmwpb.Good goodRequireds []*goodrequiredpb.Required paymentCoin *appcoinmwpb.Coin paymentAccount *payaccmwpb.Account @@ -191,15 +196,61 @@ func (h *createsHandler) checkMaxUnpaidOrders(ctx context.Context) error { } func (h *createsHandler) getAppGoods(ctx context.Context) error { + var appGoodIDs []string + var parentAppGoodID string for _, order := range h.Orders { - good, err := appgoodmwcli.GetGood(ctx, order.AppGoodID) - if err != nil { - return err + appGoodIDs = append(appGoodIDs, order.AppGoodID) + if order.Parent { + parentAppGoodID = order.AppGoodID } - if good == nil { - return fmt.Errorf("invalid good") + } + goods, _, err := appgoodmwcli.GetGoods(ctx, &appgoodmwpb.Conds{ + IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: appGoodIDs}, + }, int32(0), int32(len(appGoodIDs))) + if err != nil { + return err + } + if len(goods) < len(appGoodIDs) { + return fmt.Errorf("invalid appgoods") + } + for _, good := range goods { + h.appGoods[good.ID] = good + if good.ID == parentAppGoodID { + h.parentAppGood = good } - h.appGoods[order.AppGoodID] = good + } + if h.parentAppGood == nil { + return fmt.Errorf("invalid parent appgood") + } + return nil +} + +func (h *createsHandler) getGoods(ctx context.Context) error { + var goodIDs []string + var parentGoodID string + for _, appGood := range h.appGoods { + goodIDs = append(goodIDs, appGood.GoodID) + if appGood.ID == h.parentAppGood.ID { + parentGoodID = appGood.GoodID + } + } + goods, _, err := goodmwcli.GetGoods(ctx, &goodmwpb.Conds{ + IDs: &basetypes.StringSliceVal{Op: cruder.IN, Value: goodIDs}, + }, int32(0), int32(len(goodIDs))) + if err != nil { + return err + } + if len(goods) < len(goodIDs) { + return fmt.Errorf("invalid goods") + } + for _, good := range goods { + h.goods[good.ID] = good + if good.ID == parentGoodID { + h.parentGood = good + } + } + if h.parentGood == nil { + return fmt.Errorf("invalid parent good") } return nil } @@ -834,6 +885,9 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e if err := handler.getAppGoods(ctx); err != nil { return nil, err } + if err := handler.getGoods(ctx); err != nil { + return nil, err + } if err := handler.checkAppGoodCoin(ctx); err != nil { return nil, err } From 37348af6357295f89ce89080a96b1eb6a89b4769 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Mon, 11 Sep 2023 02:29:05 +0000 Subject: [PATCH 52/67] add orderstate --- go.mod | 2 +- go.sum | 4 ++-- pkg/order/query.go | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index d335dcb..850e451 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 - github.com/NpoolPlatform/message v0.0.0-20230910114939-93fab576f50a + github.com/NpoolPlatform/message v0.0.0-20230911022549-8cfbdcf1d22d github.com/NpoolPlatform/order-middleware v0.0.0-20230910111152-0dc718973845 github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/dtm-labs/dtm v1.17.1 diff --git a/go.sum b/go.sum index 121e0aa..d4601a7 100644 --- a/go.sum +++ b/go.sum @@ -68,8 +68,8 @@ github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 h1 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1/go.mod h1:t484//GSJFuy3Flc9puq2MJ628QotxoqA8Gy1Cou0W4= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB4NuhQxXWeV0Z1qSxgIqbiMYU30dqFGDLtgNTqYbE= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= -github.com/NpoolPlatform/message v0.0.0-20230910114939-93fab576f50a h1:TDB0pOYgbmGY7Ka1HU5A+Q/Sv2QNJCnG/7GP/RtiGb8= -github.com/NpoolPlatform/message v0.0.0-20230910114939-93fab576f50a/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/message v0.0.0-20230911022549-8cfbdcf1d22d h1:jbVRZ1oLrCUaJl6qO23z9/XlAn2Vyf8in/lzX75aOhA= +github.com/NpoolPlatform/message v0.0.0-20230911022549-8cfbdcf1d22d/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= github.com/NpoolPlatform/order-middleware v0.0.0-20230910111152-0dc718973845 h1:RsnoFXjSwG4hV2Op/c8088ylbYZ8NknlUTs2+oVLg2c= github.com/NpoolPlatform/order-middleware v0.0.0-20230910111152-0dc718973845/go.mod h1:sou8KMb443BSROjGWE+CrIGF9k1Uv0draCpkj9jE+Ls= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= diff --git a/pkg/order/query.go b/pkg/order/query.go index 02fea94..1328262 100644 --- a/pkg/order/query.go +++ b/pkg/order/query.go @@ -233,9 +233,11 @@ func (h *queryHandler) formalize(ctx context.Context) { //nolint PayWithBalanceAmount: ord.BalanceAmount, TransferAmount: ord.TransferAmount, OrderType: ord.OrderType, + OrderState: ord.OrderState, + CancelState: ord.CancelState, PaymentType: ord.PaymentType, + PaymentState: ord.PaymentState, CreatedAt: ord.CreatedAt, - State: ord.OrderState, StartAt: ord.StartAt, EndAt: ord.EndAt, InvestmentType: ord.InvestmentType, From 91678b0f9ec6b40093f31190d555349b59e9f009 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Mon, 11 Sep 2023 03:42:56 +0000 Subject: [PATCH 53/67] update create order --- pkg/order/create.go | 16 ++++------------ pkg/order/creates.go | 16 ++++------------ 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/pkg/order/create.go b/pkg/order/create.go index 96c395c..fe5b115 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -242,18 +242,10 @@ func (h *createHandler) checkUnitsLimit(ctx context.Context) error { return fmt.Errorf("app good is not enabled purchase") } purchaseCountStr, err := ordermwcli.SumOrderUnits(ctx, &ordermwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, - GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.appGood.GoodID}, - OrderStates: &basetypes.Uint32SliceVal{ - Op: cruder.IN, - Value: []uint32{ - uint32(types.OrderState_OrderStatePaid), - uint32(types.OrderState_OrderStateInService), - uint32(types.OrderState_OrderStateExpired), - uint32(types.OrderState_OrderStateWaitPayment), - }, - }, + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.appGood.GoodID}, + OrderState: &basetypes.Uint32Val{Op: cruder.NEQ, Value: uint32(types.OrderState_OrderStateCanceled)}, }) if err != nil { return err diff --git a/pkg/order/creates.go b/pkg/order/creates.go index 1f338b7..9e6d691 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -294,18 +294,10 @@ func (h *createsHandler) checkUnitsLimit(ctx context.Context) error { purchaseCountStr, err := ordermwcli.SumOrderUnits( ctx, &ordermwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, - GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: appGood.GoodID}, - OrderStates: &basetypes.Uint32SliceVal{ - Op: cruder.IN, - Value: []uint32{ - uint32(types.OrderState_OrderStatePaid), - uint32(types.OrderState_OrderStateInService), - uint32(types.OrderState_OrderStateExpired), - uint32(types.OrderState_OrderStateWaitPayment), - }, - }, + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: appGood.GoodID}, + OrderState: &basetypes.Uint32Val{Op: cruder.NEQ, Value: uint32(types.OrderState_OrderStateCanceled)}, }, ) if err != nil { From 1069fbcf947498700abe168bddfd2373014ff138 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Mon, 11 Sep 2023 05:20:19 +0000 Subject: [PATCH 54/67] Update good commit --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 850e451..b3bf5ea 100644 --- a/go.mod +++ b/go.mod @@ -9,11 +9,11 @@ require ( github.com/NpoolPlatform/chain-middleware v0.0.0-20230906092012-a63f3a7b0b54 github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821 github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e - github.com/NpoolPlatform/good-middleware v0.0.0-20230910065023-298572ba5a77 + github.com/NpoolPlatform/good-middleware v0.0.0-20230911050119-fa126024fa1f github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 - github.com/NpoolPlatform/message v0.0.0-20230911022549-8cfbdcf1d22d + github.com/NpoolPlatform/message v0.0.0-20230911023910-b5e4f88e2e29 github.com/NpoolPlatform/order-middleware v0.0.0-20230910111152-0dc718973845 github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b github.com/dtm-labs/dtm v1.17.1 diff --git a/go.sum b/go.sum index d4601a7..888ba72 100644 --- a/go.sum +++ b/go.sum @@ -60,16 +60,16 @@ github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821 h1:JEoN8 github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821/go.mod h1:ZBvGIj+zt7VT6WbnIeU/fhiI/dEoNK4JqcXE1EIblpQ= github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e h1:17BGexCmCdOOBXKYogP8RNE+pAHRu2N4LKq9znPJ4vc= github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e/go.mod h1:Kh7DMkWnYOMHxEKq7QfJqbxm1HaUPkhTNN74lfHQxyE= -github.com/NpoolPlatform/good-middleware v0.0.0-20230910065023-298572ba5a77 h1:0L1GcpIks4L7KaD4Fdb6gnZjBHziNKMwYb2q0yZ01lg= -github.com/NpoolPlatform/good-middleware v0.0.0-20230910065023-298572ba5a77/go.mod h1:PaLlBl1fmKHfpzLOXFblfaaosElBa7XXRYaZYv7Lu0Y= +github.com/NpoolPlatform/good-middleware v0.0.0-20230911050119-fa126024fa1f h1:HxmxEV+CBKT9MBfIxZ0CPHIZrOkp29+SbOLXe6nC17k= +github.com/NpoolPlatform/good-middleware v0.0.0-20230911050119-fa126024fa1f/go.mod h1:pVVsqViUGbt+kvawrTgGeRu0xLRshVSlKlDwvxg/ipI= github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2 h1:gFrEiTDDu+F1F9XfrCyOjf+iVwpDRGddCaFxFNPHnp4= github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2/go.mod h1:r8yyPbydrlL5MXMDT90qgqx/Y6mkCFEfOPdjxNavhJQ= github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 h1:tv2Ze+8CzrUvfN4/I57fn3Z6KHJwSTZNi3NsFG78G9Q= github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1/go.mod h1:t484//GSJFuy3Flc9puq2MJ628QotxoqA8Gy1Cou0W4= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB4NuhQxXWeV0Z1qSxgIqbiMYU30dqFGDLtgNTqYbE= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= -github.com/NpoolPlatform/message v0.0.0-20230911022549-8cfbdcf1d22d h1:jbVRZ1oLrCUaJl6qO23z9/XlAn2Vyf8in/lzX75aOhA= -github.com/NpoolPlatform/message v0.0.0-20230911022549-8cfbdcf1d22d/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/message v0.0.0-20230911023910-b5e4f88e2e29 h1:SJAyxSsmP1kKpUCn44X2lrA48fmnNNBtFu/dFNGGSPM= +github.com/NpoolPlatform/message v0.0.0-20230911023910-b5e4f88e2e29/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= github.com/NpoolPlatform/order-middleware v0.0.0-20230910111152-0dc718973845 h1:RsnoFXjSwG4hV2Op/c8088ylbYZ8NknlUTs2+oVLg2c= github.com/NpoolPlatform/order-middleware v0.0.0-20230910111152-0dc718973845/go.mod h1:sou8KMb443BSROjGWE+CrIGF9k1Uv0draCpkj9jE+Ls= github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= From 139b8130f06a1c765159385cc055fa3126e34d01 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Mon, 11 Sep 2023 11:12:53 +0000 Subject: [PATCH 55/67] Migration amount --- pkg/migrator/migrator.go | 48 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/pkg/migrator/migrator.go b/pkg/migrator/migrator.go index 82958aa..88f3f22 100644 --- a/pkg/migrator/migrator.go +++ b/pkg/migrator/migrator.go @@ -327,6 +327,54 @@ func Migrate(ctx context.Context) error { if err != nil { return err } + _, err = tx. + ExecContext( + ctx, + "update orders set good_value_usd='0' where good_value_usd is NULL", + ) + if err != nil { + return err + } + _, err = tx. + ExecContext( + ctx, + "update orders set transfer_amount='0' where transfer_amount is NULL", + ) + if err != nil { + return err + } + _, err = tx. + ExecContext( + ctx, + "update orders set balance_amount='0' where balance_amount is NULL", + ) + if err != nil { + return err + } + _, err = tx. + ExecContext( + ctx, + "update orders set coin_usd_currency='0' where coin_usd_currency is NULL", + ) + if err != nil { + return err + } + _, err = tx. + ExecContext( + ctx, + "update orders set live_coin_usd_currency='0' where live_coin_usd_currency is NULL", + ) + if err != nil { + return err + } + _, err = tx. + ExecContext( + ctx, + "update orders set local_coin_usd_currency='0' where local_coin_usd_currency is NULL", + ) + if err != nil { + return err + } if err := migrateOrder(_ctx, tx); err != nil { logger.Sugar().Errorw("Migrate", "error", err) From 3d310877f8bdc96ed4ddc184a1601b77edf30a7b Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Mon, 11 Sep 2023 12:57:44 +0000 Subject: [PATCH 56/67] Pass lint --- pkg/order/create.go | 2 +- pkg/order/creates.go | 2 +- pkg/order/update.go | 11 ++++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pkg/order/create.go b/pkg/order/create.go index fe5b115..00b7bb7 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -1,3 +1,4 @@ +//nolint:dupl package order import ( @@ -167,7 +168,6 @@ func (h *createHandler) validateDiscountCoupon() error { return nil } -//nolint:dupl func (h *createHandler) checkMaxUnpaidOrders(ctx context.Context) error { const maxUnpaidOrders = uint32(5) orderCount, err := ordermwcli.CountOrders(ctx, &ordermwpb.Conds{ diff --git a/pkg/order/creates.go b/pkg/order/creates.go index 9e6d691..a836840 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -1,3 +1,4 @@ +//nolint:dupl package order import ( @@ -178,7 +179,6 @@ func (h *createsHandler) validateDiscountCoupon() error { return nil } -//nolint:dupl func (h *createsHandler) checkMaxUnpaidOrders(ctx context.Context) error { const maxUnpaidOrders = uint32(5) orderCount, err := ordermwcli.CountOrders(ctx, &ordermwpb.Conds{ diff --git a/pkg/order/update.go b/pkg/order/update.go index ae8b83e..1546594 100644 --- a/pkg/order/update.go +++ b/pkg/order/update.go @@ -151,6 +151,12 @@ func (h *updateHandler) checkGood(ctx context.Context) error { } func (h *updateHandler) checkCancelable(ctx context.Context) error { + switch h.order.OrderState { + case ordertypes.OrderState_OrderStateWaitPayment: + return nil + default: + } + goodStatements, _, err := goodledgerstatementcli.GetGoodStatements(ctx, &goodledgerstatementpb.Conds{ GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.order.GoodID}, }, 0, 1) @@ -158,11 +164,6 @@ func (h *updateHandler) checkCancelable(ctx context.Context) error { return err } - switch h.order.OrderState { - case ordertypes.OrderState_OrderStateWaitPayment: - return nil - } - switch h.appGood.CancelMode { case goodtypes.CancelMode_Uncancellable: return fmt.Errorf("permission denied") From 9853287849c899fe0f33493d676e5f91c4ea5622 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Mon, 11 Sep 2023 13:07:59 +0000 Subject: [PATCH 57/67] Pass lint --- pkg/migrator/migrator.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/migrator/migrator.go b/pkg/migrator/migrator.go index 88f3f22..280c58a 100644 --- a/pkg/migrator/migrator.go +++ b/pkg/migrator/migrator.go @@ -262,6 +262,7 @@ func migrateOrder(ctx context.Context, tx *ent.Tx) error { return nil } +//nolint:funlen func Migrate(ctx context.Context) error { var err error From 2edbcf5df127d9e0d7091d544478ecd2134bccb7 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Mon, 11 Sep 2023 13:09:09 +0000 Subject: [PATCH 58/67] Pass lint --- pkg/migrator/migrator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/migrator/migrator.go b/pkg/migrator/migrator.go index 280c58a..e278dbb 100644 --- a/pkg/migrator/migrator.go +++ b/pkg/migrator/migrator.go @@ -262,7 +262,7 @@ func migrateOrder(ctx context.Context, tx *ent.Tx) error { return nil } -//nolint:funlen +//nolint:funlen,gocyclo func Migrate(ctx context.Context) error { var err error From fc4c36e48cfcd4b0f19b2103b03c284f78904105 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Tue, 12 Sep 2023 01:55:58 +0000 Subject: [PATCH 59/67] Correct required good check for orders --- pkg/order/creates.go | 73 ++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/pkg/order/creates.go b/pkg/order/creates.go index a836840..923d7e7 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -42,6 +42,7 @@ import ( npool "github.com/NpoolPlatform/message/npool/order/gw/v1/order" ordermwpb "github.com/NpoolPlatform/message/npool/order/mw/v1/order" sphinxproxypb "github.com/NpoolPlatform/message/npool/sphinxproxy" + constant "github.com/NpoolPlatform/order-gateway/pkg/const" ordermwcli "github.com/NpoolPlatform/order-middleware/pkg/client/order" ordermwsvcname "github.com/NpoolPlatform/order-middleware/pkg/servicename" sphinxproxycli "github.com/NpoolPlatform/sphinx-proxy/pkg/client" @@ -60,7 +61,7 @@ type createsHandler struct { goods map[string]*goodmwpb.Good parentAppGood *appgoodmwpb.Good parentGood *goodmwpb.Good - goodRequireds []*goodrequiredpb.Required + requiredGoods map[string]*goodrequiredpb.Required paymentCoin *appcoinmwpb.Coin paymentAccount *payaccmwpb.Account paymentStartAmount decimal.Decimal @@ -197,10 +198,13 @@ func (h *createsHandler) checkMaxUnpaidOrders(ctx context.Context) error { func (h *createsHandler) getAppGoods(ctx context.Context) error { var appGoodIDs []string - var parentAppGoodID string + parentAppGoodID := uuid.Nil.String() for _, order := range h.Orders { appGoodIDs = append(appGoodIDs, order.AppGoodID) if order.Parent { + if parentAppGoodID != uuid.Nil.String() { + return fmt.Errorf("too many parents") + } parentAppGoodID = order.AppGoodID } } @@ -790,52 +794,53 @@ func (h *createsHandler) withLockPaymentAccount(dispose *dtmcli.SagaDispose) { ) } -func (h *createsHandler) getGoodRequests(ctx context.Context) error { - for _, order := range h.Orders { - appgood := h.appGoods[order.AppGoodID] - if order.Parent { - goodRequireds, _, err := goodrequiredmwcli.GetRequireds(ctx, &goodrequiredpb.Conds{ - MainGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: appgood.GoodID}, - }, 0, 0) - if err != nil { - return err - } - h.goodRequireds = goodRequireds +func (h *createsHandler) getRequiredGoods(ctx context.Context) error { + offset := int32(0) + limit := constant.DefaultRowLimit + + for { + goods, _, err := goodrequiredmwcli.GetRequireds(ctx, &goodrequiredpb.Conds{ + MainGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.parentAppGood.GoodID}, + }, offset, limit) + if err != nil { + return err + } + if len(goods) == 0 { break } + for _, good := range goods { + h.requiredGoods[good.RequiredGoodID] = good + } + offset += limit } return nil } -func (h *createsHandler) checkGoodsInRequests() error { - requiredSet := make(map[string]struct{}) - for _, goodRequired := range h.goodRequireds { - requiredSet[goodRequired.RequiredGoodID] = struct{}{} - } - +func (h *createsHandler) validateOrderGoods() error { for _, order := range h.Orders { - appgood := h.appGoods[order.AppGoodID] if order.Parent { continue } - if _, ok := requiredSet[appgood.GoodID]; !ok { - return fmt.Errorf("invalid goodrequired") + appgood := h.appGoods[order.AppGoodID] + if _, ok := h.requiredGoods[appgood.GoodID]; !ok { + return fmt.Errorf("invalid requiredgood") } } return nil } -func (h *createsHandler) checkMustRequestsInGoods() error { - goodSet := make(map[string]struct{}) +func (h *createsHandler) validateRequiredGoods() error { + orderGoodIDs := map[string]struct{}{} for _, order := range h.Orders { appgood := h.appGoods[order.AppGoodID] - goodSet[appgood.GoodID] = struct{}{} + orderGoodIDs[appgood.GoodID] = struct{}{} } - for _, goodRequired := range h.goodRequireds { - if goodRequired.Must { - if _, ok := goodSet[goodRequired.RequiredGoodID]; !ok { - return fmt.Errorf("invalid goodrequired must") - } + for _, good := range h.requiredGoods { + if !good.Must { + continue + } + if _, ok := orderGoodIDs[good.RequiredGoodID]; !ok { + return fmt.Errorf("miss requiredgood") } } return nil @@ -847,6 +852,8 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e Handler: h, ids: map[string]*string{}, appGoods: map[string]*appgoodmwpb.Good{}, + goods: map[string]*goodmwpb.Good{}, + requiredGoods: map[string]*goodrequiredpb.Required{}, coupons: map[string]*allocatedmwpb.Coupon{}, promotions: map[string]*topmostmwpb.TopMostGood{}, goodValueUSDTAmount: map[string]decimal.Decimal{}, @@ -886,13 +893,13 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e if err := handler.checkUnitsLimit(ctx); err != nil { return nil, err } - if err := handler.getGoodRequests(ctx); err != nil { + if err := handler.getRequiredGoods(ctx); err != nil { return nil, err } - if err := handler.checkGoodsInRequests(); err != nil { + if err := handler.validateOrderGoods(); err != nil { return nil, err } - if err := handler.checkMustRequestsInGoods(); err != nil { + if err := handler.validateRequiredGoods(); err != nil { return nil, err } if err := handler.getAppGoodPromotions(ctx); err != nil { From 5c51ce7c942268af19c521edd1f406d35ed21802 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Tue, 12 Sep 2023 02:05:36 +0000 Subject: [PATCH 60/67] Correct lock id --- pkg/order/creates.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pkg/order/creates.go b/pkg/order/creates.go index 923d7e7..6c66dae 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -686,7 +686,7 @@ func (h *createsHandler) withUpdateBalance(dispose *dtmcli.SagaDispose) { UserID: h.UserID, CoinTypeID: h.PaymentCoinID, Spendable: &amount, - Locked: h.balanceLockID, + LockID: h.balanceLockID, } dispose.Add( ledgermwsvcname.ServiceDomain, @@ -748,11 +748,11 @@ func (h *createsHandler) withCreateOrders(dispose *dtmcli.SagaDispose) { req.TransferAmount = &transferCoinAmount req.BalanceAmount = &balanceCoinAmount req.CouponIDs = h.CouponIDs + req.LedgerLockID = h.balanceLockID if h.paymentAccount != nil { req.PaymentAccountID = &h.paymentAccount.AccountID paymentStartAmount := h.paymentStartAmount.String() req.PaymentStartAmount = &paymentStartAmount - req.LedgerLockID = h.balanceLockID } } else { req.ParentOrderID = h.ParentOrderID @@ -946,17 +946,17 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e } for _, order := range h.Orders { - id := uuid.NewString() - handler.ids[order.AppGoodID] = &id + id1 := uuid.NewString() + handler.ids[order.AppGoodID] = &id1 if order.Parent { - h.ParentOrderID = &id + h.ParentOrderID = &id1 } - h.IDs = append(h.IDs, id) + h.IDs = append(h.IDs, id1) - id = uuid.NewString() - handler.stockLockIDs[order.AppGoodID] = &id + id2 := uuid.NewString() + handler.stockLockIDs[order.AppGoodID] = &id2 } - if handler.balanceCoinAmount.Cmp(decimal.NewFromInt(0)) <= 0 { + if handler.balanceCoinAmount.Cmp(decimal.NewFromInt(0)) > 0 { id := uuid.NewString() handler.balanceLockID = &id } From 5ac11001749e193eb8c343b267ff06f471427677 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Tue, 12 Sep 2023 09:29:16 +0000 Subject: [PATCH 61/67] Correct unpaid limitation --- pkg/order/create.go | 1 + pkg/order/creates.go | 2 ++ 2 files changed, 3 insertions(+) diff --git a/pkg/order/create.go b/pkg/order/create.go index 00b7bb7..f19ee87 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -173,6 +173,7 @@ func (h *createHandler) checkMaxUnpaidOrders(ctx context.Context) error { orderCount, err := ordermwcli.CountOrders(ctx, &ordermwpb.Conds{ AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + AppGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppGoodID}, OrderType: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(types.OrderType_Normal)}, PaymentState: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(types.PaymentState_PaymentStateWait)}, }) diff --git a/pkg/order/creates.go b/pkg/order/creates.go index 6c66dae..3a4edce 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -185,6 +185,8 @@ func (h *createsHandler) checkMaxUnpaidOrders(ctx context.Context) error { orderCount, err := ordermwcli.CountOrders(ctx, &ordermwpb.Conds{ AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + AppGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppGoodID}, + OrderType: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(types.OrderType_Normal)}, PaymentState: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(types.PaymentState_PaymentStateWait)}, }) if err != nil { From 75905f8c26b8bbf79760df59ac91e74bfdb67407 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Tue, 12 Sep 2023 09:30:39 +0000 Subject: [PATCH 62/67] Correct purchase limit --- pkg/order/create.go | 2 +- pkg/order/creates.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/order/create.go b/pkg/order/create.go index f19ee87..d11d06b 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -245,7 +245,7 @@ func (h *createHandler) checkUnitsLimit(ctx context.Context) error { purchaseCountStr, err := ordermwcli.SumOrderUnits(ctx, &ordermwpb.Conds{ AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, - GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.appGood.GoodID}, + AppGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppGoodID}, OrderState: &basetypes.Uint32Val{Op: cruder.NEQ, Value: uint32(types.OrderState_OrderStateCanceled)}, }) if err != nil { diff --git a/pkg/order/creates.go b/pkg/order/creates.go index 3a4edce..b05c937 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -302,7 +302,7 @@ func (h *createsHandler) checkUnitsLimit(ctx context.Context) error { &ordermwpb.Conds{ AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, - GoodID: &basetypes.StringVal{Op: cruder.EQ, Value: appGood.GoodID}, + AppGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppGoodID}, OrderState: &basetypes.Uint32Val{Op: cruder.NEQ, Value: uint32(types.OrderState_OrderStateCanceled)}, }, ) From f633c4bf12964343e6092481c6ffb5b36e1737fb Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Tue, 12 Sep 2023 10:32:48 +0000 Subject: [PATCH 63/67] Set pay with transfer and balance --- pkg/migrator/migrator.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/migrator/migrator.go b/pkg/migrator/migrator.go index e278dbb..0649de4 100644 --- a/pkg/migrator/migrator.go +++ b/pkg/migrator/migrator.go @@ -204,6 +204,7 @@ func migrateOrder(ctx context.Context, tx *ent.Tx) error { SetOrderType(order.Type). SetCoinTypeID(good.CoinTypeID). SetPaymentCoinTypeID(payment.CoinInfoID). + SetPaymentType(types.PaymentType_PayWithTransferAndBalance.String()). SetTransferAmount(payment.Amount). SetBalanceAmount(payment.PayWithBalanceAmount). SetCoinUsdCurrency(payment.CoinUsdCurrency). From a04db7702ce0ae956d25fc320a27b9c71ff42ec6 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 13 Sep 2023 12:37:35 +0000 Subject: [PATCH 64/67] Correct app good id --- cmd/order-gateway/run.go | 61 ++++++++++++++----------- go.mod | 2 +- go.sum | 4 +- pkg/order/create.go | 2 +- pkg/order/creates.go | 97 ++++++++++++++++++++++------------------ 5 files changed, 93 insertions(+), 73 deletions(-) diff --git a/cmd/order-gateway/run.go b/cmd/order-gateway/run.go index c157c1a..d5ebe2e 100644 --- a/cmd/order-gateway/run.go +++ b/cmd/order-gateway/run.go @@ -1,46 +1,58 @@ package main import ( + "context" + + apicli "github.com/NpoolPlatform/basal-middleware/pkg/client/api" + "github.com/NpoolPlatform/go-service-framework/pkg/action" + "github.com/NpoolPlatform/go-service-framework/pkg/logger" "github.com/NpoolPlatform/order-gateway/api" "github.com/NpoolPlatform/order-gateway/pkg/migrator" "github.com/NpoolPlatform/order-middleware/pkg/db" - - grpc2 "github.com/NpoolPlatform/go-service-framework/pkg/grpc" - "github.com/NpoolPlatform/go-service-framework/pkg/logger" - - apicli "github.com/NpoolPlatform/basal-middleware/pkg/client/api" - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" - cli "github.com/urfave/cli/v2" - "google.golang.org/grpc" ) -// const MsgInterval = 3 * time.Second - var runCmd = &cli.Command{ Name: "run", Aliases: []string{"s"}, Usage: "Run the daemon", Action: func(c *cli.Context) error { - if err := db.Init(); err != nil { - return err - } - if err := migrator.Migrate(c.Context); err != nil { - return err - } - - go func() { - if err := grpc2.RunGRPC(rpcRegister); err != nil { - logger.Sugar().Errorf("fail to run grpc server: %v", err) - } - }() - - return grpc2.RunGRPCGateWay(rpcGatewayRegister) + return action.Run( + c.Context, + run, + rpcRegister, + rpcGatewayRegister, + watch, + ) }, } +func run(ctx context.Context) error { + if err := db.Init(); err != nil { + return err + } + if err := migrator.Migrate(ctx); err != nil { + return err + } + return nil +} + +func shutdown(ctx context.Context) { + <-ctx.Done() + logger.Sugar().Infow( + "Watch", + "State", "Done", + "Error", ctx.Err(), + ) +} + +func watch(ctx context.Context, cancel context.CancelFunc) error { + go shutdown(ctx) + return nil +} + func rpcRegister(server grpc.ServiceRegistrar) error { api.Register(server) @@ -56,6 +68,5 @@ func rpcGatewayRegister(mux *runtime.ServeMux, endpoint string, opts []grpc.Dial } _ = apicli.Register(mux) - return nil } diff --git a/go.mod b/go.mod index b3bf5ea..023ac0b 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/NpoolPlatform/basal-middleware v0.0.0-20230908131959-b37594a23afd github.com/NpoolPlatform/chain-middleware v0.0.0-20230906092012-a63f3a7b0b54 github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821 - github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e + github.com/NpoolPlatform/go-service-framework v0.0.0-20230913101807-3934219c0456 github.com/NpoolPlatform/good-middleware v0.0.0-20230911050119-fa126024fa1f github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2 github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 diff --git a/go.sum b/go.sum index 888ba72..231e92f 100644 --- a/go.sum +++ b/go.sum @@ -58,8 +58,8 @@ github.com/NpoolPlatform/chain-middleware v0.0.0-20230906092012-a63f3a7b0b54 h1: github.com/NpoolPlatform/chain-middleware v0.0.0-20230906092012-a63f3a7b0b54/go.mod h1:y3bX+6Yt8cz5s6aQypnqbQzttbwVTOuhK++LU1OBvxA= github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821 h1:JEoN8rpjyJOpbXXLhL5J6Fjw+/bOTwMNci6CL7G02zQ= github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821/go.mod h1:ZBvGIj+zt7VT6WbnIeU/fhiI/dEoNK4JqcXE1EIblpQ= -github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e h1:17BGexCmCdOOBXKYogP8RNE+pAHRu2N4LKq9znPJ4vc= -github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e/go.mod h1:Kh7DMkWnYOMHxEKq7QfJqbxm1HaUPkhTNN74lfHQxyE= +github.com/NpoolPlatform/go-service-framework v0.0.0-20230913101807-3934219c0456 h1:8wnhwmXEsEwXoHEKXsZby2U2a53kiuoByOXGPT8K+Qs= +github.com/NpoolPlatform/go-service-framework v0.0.0-20230913101807-3934219c0456/go.mod h1:Kh7DMkWnYOMHxEKq7QfJqbxm1HaUPkhTNN74lfHQxyE= github.com/NpoolPlatform/good-middleware v0.0.0-20230911050119-fa126024fa1f h1:HxmxEV+CBKT9MBfIxZ0CPHIZrOkp29+SbOLXe6nC17k= github.com/NpoolPlatform/good-middleware v0.0.0-20230911050119-fa126024fa1f/go.mod h1:pVVsqViUGbt+kvawrTgGeRu0xLRshVSlKlDwvxg/ipI= github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2 h1:gFrEiTDDu+F1F9XfrCyOjf+iVwpDRGddCaFxFNPHnp4= diff --git a/pkg/order/create.go b/pkg/order/create.go index d11d06b..c14dfa8 100644 --- a/pkg/order/create.go +++ b/pkg/order/create.go @@ -169,7 +169,7 @@ func (h *createHandler) validateDiscountCoupon() error { } func (h *createHandler) checkMaxUnpaidOrders(ctx context.Context) error { - const maxUnpaidOrders = uint32(5) + const maxUnpaidOrders = uint32(10000) orderCount, err := ordermwcli.CountOrders(ctx, &ordermwpb.Conds{ AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, diff --git a/pkg/order/creates.go b/pkg/order/creates.go index b05c937..7fe8eaa 100644 --- a/pkg/order/creates.go +++ b/pkg/order/creates.go @@ -84,6 +84,7 @@ type createsHandler struct { orderEndAt map[string]uint32 stockLockIDs map[string]*string balanceLockID *string + parentOrder *npool.CreateOrdersRequest_OrderReq } func (h *createsHandler) tomorrowStart() time.Time { @@ -185,7 +186,7 @@ func (h *createsHandler) checkMaxUnpaidOrders(ctx context.Context) error { orderCount, err := ordermwcli.CountOrders(ctx, &ordermwpb.Conds{ AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, - AppGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppGoodID}, + AppGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: h.parentAppGood.ID}, OrderType: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(types.OrderType_Normal)}, PaymentState: &basetypes.Uint32Val{Op: cruder.EQ, Value: uint32(types.PaymentState_PaymentStateWait)}, }) @@ -198,7 +199,7 @@ func (h *createsHandler) checkMaxUnpaidOrders(ctx context.Context) error { return nil } -func (h *createsHandler) getAppGoods(ctx context.Context) error { +func (h *createsHandler) checkAppGoods(ctx context.Context) error { var appGoodIDs []string parentAppGoodID := uuid.Nil.String() for _, order := range h.Orders { @@ -220,6 +221,9 @@ func (h *createsHandler) getAppGoods(ctx context.Context) error { return fmt.Errorf("invalid appgoods") } for _, good := range goods { + if !good.EnablePurchase { + return fmt.Errorf("appgood is not enabled purchase") + } h.appGoods[good.ID] = good if good.ID == parentAppGoodID { h.parentAppGood = good @@ -231,7 +235,7 @@ func (h *createsHandler) getAppGoods(ctx context.Context) error { return nil } -func (h *createsHandler) getGoods(ctx context.Context) error { +func (h *createsHandler) checkGoods(ctx context.Context) error { var goodIDs []string var parentGoodID string for _, appGood := range h.appGoods { @@ -281,47 +285,50 @@ func (h *createsHandler) checkAppGoodCoin(ctx context.Context) error { return nil } +func (h *createsHandler) checkParentOrder() error { + for _, order := range h.Orders { + if order.Parent { + h.parentOrder = order + return nil + } + } + if h.parentOrder == nil { + return fmt.Errorf("invalid parent order") + } + return nil +} + func (h *createsHandler) checkUnitsLimit(ctx context.Context) error { if *h.OrderType != types.OrderType_Normal { return nil } - for _, order := range h.Orders { - appGood := h.appGoods[order.AppGoodID] - units, err := decimal.NewFromString(order.Units) - if err != nil { - return err - } - if appGood.PurchaseLimit > 0 && units.Cmp(decimal.NewFromInt32(appGood.PurchaseLimit)) > 0 { - return fmt.Errorf("too many units") - } - if !appGood.EnablePurchase { - return fmt.Errorf("app good is not enabled purchase") - } - purchaseCountStr, err := ordermwcli.SumOrderUnits( - ctx, - &ordermwpb.Conds{ - AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, - UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, - AppGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppGoodID}, - OrderState: &basetypes.Uint32Val{Op: cruder.NEQ, Value: uint32(types.OrderState_OrderStateCanceled)}, - }, - ) - if err != nil { - return err - } - purchaseCount, err := decimal.NewFromString(purchaseCountStr) - if err != nil { - return err - } - - userPurchaseLimit, err := decimal.NewFromString(appGood.UserPurchaseLimit) - if err != nil { - return err - } - - if userPurchaseLimit.Cmp(decimal.NewFromInt(0)) > 0 && purchaseCount.Add(units).Cmp(userPurchaseLimit) > 0 { - return fmt.Errorf("too many units") - } + appGood := h.parentAppGood + units, err := decimal.NewFromString(h.parentOrder.Units) + if err != nil { + return err + } + if appGood.PurchaseLimit > 0 && units.Cmp(decimal.NewFromInt32(appGood.PurchaseLimit)) > 0 { + return fmt.Errorf("too many units") + } + purchaseCountStr, err := ordermwcli.SumOrderUnits(ctx, &ordermwpb.Conds{ + AppID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.AppID}, + UserID: &basetypes.StringVal{Op: cruder.EQ, Value: *h.UserID}, + AppGoodID: &basetypes.StringVal{Op: cruder.EQ, Value: appGood.ID}, + OrderState: &basetypes.Uint32Val{Op: cruder.NEQ, Value: uint32(types.OrderState_OrderStateCanceled)}, + }) + if err != nil { + return err + } + purchaseCount, err := decimal.NewFromString(purchaseCountStr) + if err != nil { + return err + } + userPurchaseLimit, err := decimal.NewFromString(appGood.UserPurchaseLimit) + if err != nil { + return err + } + if userPurchaseLimit.Cmp(decimal.NewFromInt(0)) > 0 && purchaseCount.Add(units).Cmp(userPurchaseLimit) > 0 { + return fmt.Errorf("too many units") } return nil } @@ -880,18 +887,21 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e if err := handler.validateDiscountCoupon(); err != nil { return nil, err } - if err := handler.checkMaxUnpaidOrders(ctx); err != nil { + if err := handler.checkAppGoods(ctx); err != nil { return nil, err } - if err := handler.getAppGoods(ctx); err != nil { + if err := handler.checkGoods(ctx); err != nil { return nil, err } - if err := handler.getGoods(ctx); err != nil { + if err := handler.checkMaxUnpaidOrders(ctx); err != nil { return nil, err } if err := handler.checkAppGoodCoin(ctx); err != nil { return nil, err } + if err := handler.checkParentOrder(); err != nil { + return nil, err + } if err := handler.checkUnitsLimit(ctx); err != nil { return nil, err } @@ -954,7 +964,6 @@ func (h *Handler) CreateOrders(ctx context.Context) (infos []*npool.Order, err e h.ParentOrderID = &id1 } h.IDs = append(h.IDs, id1) - id2 := uuid.NewString() handler.stockLockIDs[order.AppGoodID] = &id2 } From 2bbb23e94a2bdb9ca89f5300f366ec505a93ba50 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 13 Sep 2023 12:51:24 +0000 Subject: [PATCH 65/67] fix log --- pkg/order/handler.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/order/handler.go b/pkg/order/handler.go index 548de37..c4ae6c4 100644 --- a/pkg/order/handler.go +++ b/pkg/order/handler.go @@ -170,7 +170,7 @@ func WithUnits(amount string, must bool) func(context.Context, *Handler) error { return err } if _amount.Cmp(decimal.NewFromInt32(0)) <= 0 { - return fmt.Errorf("units is 0") + return fmt.Errorf("invalid units") } h.Units = amount return nil @@ -181,7 +181,7 @@ func WithBalanceAmount(amount *string, must bool) func(context.Context, *Handler return func(ctx context.Context, h *Handler) error { if amount == nil { if must { - return fmt.Errorf("invalid parentorderid") + return fmt.Errorf("invalid balanceamount") } return nil } @@ -190,7 +190,7 @@ func WithBalanceAmount(amount *string, must bool) func(context.Context, *Handler return err } if _amount.Cmp(decimal.NewFromInt32(0)) <= 0 { - return fmt.Errorf("units is 0") + return fmt.Errorf("invalid balanceamount") } h.BalanceAmount = amount return nil From 0248d9e1c3c1790acd3e59b6399d121c1bb027f2 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Thu, 14 Sep 2023 03:46:59 +0000 Subject: [PATCH 66/67] Update commit --- cmd/order-gateway/run.go | 63 +++++++++++--------- go.mod | 56 +++++++++--------- go.sum | 123 ++++++++++++++++++--------------------- 3 files changed, 120 insertions(+), 122 deletions(-) diff --git a/cmd/order-gateway/run.go b/cmd/order-gateway/run.go index c157c1a..f288b87 100644 --- a/cmd/order-gateway/run.go +++ b/cmd/order-gateway/run.go @@ -1,46 +1,56 @@ package main import ( - "github.com/NpoolPlatform/order-gateway/api" - "github.com/NpoolPlatform/order-gateway/pkg/migrator" - "github.com/NpoolPlatform/order-middleware/pkg/db" - - grpc2 "github.com/NpoolPlatform/go-service-framework/pkg/grpc" - "github.com/NpoolPlatform/go-service-framework/pkg/logger" + "context" apicli "github.com/NpoolPlatform/basal-middleware/pkg/client/api" - + "github.com/NpoolPlatform/go-service-framework/pkg/action" + "github.com/NpoolPlatform/go-service-framework/pkg/logger" + "github.com/NpoolPlatform/order-gateway/api" + "github.com/NpoolPlatform/order-gateway/pkg/migrator" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" - cli "github.com/urfave/cli/v2" - "google.golang.org/grpc" ) -// const MsgInterval = 3 * time.Second - var runCmd = &cli.Command{ Name: "run", Aliases: []string{"s"}, Usage: "Run the daemon", Action: func(c *cli.Context) error { - if err := db.Init(); err != nil { - return err - } - if err := migrator.Migrate(c.Context); err != nil { - return err - } - - go func() { - if err := grpc2.RunGRPC(rpcRegister); err != nil { - logger.Sugar().Errorf("fail to run grpc server: %v", err) - } - }() - - return grpc2.RunGRPCGateWay(rpcGatewayRegister) + err := action.Run( + c.Context, + run, + rpcRegister, + rpcGatewayRegister, + watch, + ) + + return err }, } +func run(ctx context.Context) error { + if err := migrator.Migrate(ctx); err != nil { + return err + } + return nil +} + +func shutdown(ctx context.Context) { + <-ctx.Done() + logger.Sugar().Infow( + "Watch", + "State", "Done", + "Error", ctx.Err(), + ) +} + +func watch(ctx context.Context, cancel context.CancelFunc) error { + go shutdown(ctx) + return nil +} + func rpcRegister(server grpc.ServiceRegistrar) error { api.Register(server) @@ -54,8 +64,5 @@ func rpcGatewayRegister(mux *runtime.ServeMux, endpoint string, opts []grpc.Dial if err != nil { return err } - - _ = apicli.Register(mux) - return nil } diff --git a/go.mod b/go.mod index b3bf5ea..f1f2e82 100644 --- a/go.mod +++ b/go.mod @@ -3,33 +3,33 @@ module github.com/NpoolPlatform/order-gateway go 1.17 require ( - github.com/NpoolPlatform/account-middleware v0.0.0-20230908122122-cd58a2b8c771 - github.com/NpoolPlatform/appuser-middleware v0.0.0-20230513100509-b19f356ebd4b - github.com/NpoolPlatform/basal-middleware v0.0.0-20230908131959-b37594a23afd - github.com/NpoolPlatform/chain-middleware v0.0.0-20230906092012-a63f3a7b0b54 + github.com/NpoolPlatform/account-middleware v0.0.0-20230913133754-4faeebde91e8 + github.com/NpoolPlatform/appuser-middleware v0.0.0-20230913142320-746bdc6ca127 + github.com/NpoolPlatform/basal-middleware v0.0.0-20230913134752-d45f93a3a60c + github.com/NpoolPlatform/chain-middleware v0.0.0-20230913142438-2e5786e6ca7e github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821 - github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e - github.com/NpoolPlatform/good-middleware v0.0.0-20230911050119-fa126024fa1f - github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2 - github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 + github.com/NpoolPlatform/go-service-framework v0.0.0-20230913101807-3934219c0456 + github.com/NpoolPlatform/good-middleware v0.0.0-20230913132908-c12992db53da + github.com/NpoolPlatform/inspire-middleware v0.0.0-20230913112606-d48a3cb95447 + github.com/NpoolPlatform/ledger-middleware v0.0.0-20230913131713-3f2e2a885752 github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 - github.com/NpoolPlatform/message v0.0.0-20230911023910-b5e4f88e2e29 - github.com/NpoolPlatform/order-middleware v0.0.0-20230910111152-0dc718973845 - github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b + github.com/NpoolPlatform/message v0.0.0-20230914023737-ac5d6d2a3a03 + github.com/NpoolPlatform/order-middleware v0.0.0-20230913130356-4fe8c6fe2907 + github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230914031406-667706c33172 github.com/dtm-labs/dtm v1.17.1 github.com/go-resty/resty/v2 v2.7.0 github.com/google/uuid v1.3.0 - github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 github.com/shopspring/decimal v1.3.1 - github.com/stretchr/testify v1.8.1 - github.com/urfave/cli/v2 v2.16.3 + github.com/stretchr/testify v1.8.3 + github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa google.golang.org/grpc v1.55.0 google.golang.org/protobuf v1.30.0 ) require ( - ariga.io/atlas v0.7.2-0.20220927111110-867ee0cca56a // indirect - entgo.io/ent v0.11.3 // indirect + ariga.io/atlas v0.10.0 // indirect + entgo.io/ent v0.12.0 // indirect github.com/Shonminh/apollo-client v0.4.0 // indirect github.com/ThreeDotsLabs/watermill v1.2.0 // indirect github.com/ThreeDotsLabs/watermill-amqp/v2 v2.0.7 // indirect @@ -49,15 +49,15 @@ require ( github.com/dtm-labs/dtmdriver v0.0.6 // indirect github.com/dtm-labs/logger v0.0.2 // indirect github.com/fatih/color v1.13.0 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-chassis/go-archaius v1.5.3 // indirect github.com/go-chassis/openlog v1.1.3 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/inflect v0.19.0 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect - github.com/go-sql-driver/mysql v1.6.0 // indirect - github.com/go-stack/stack v1.8.0 // indirect + github.com/go-sql-driver/mysql v1.7.0 // indirect + github.com/go-stack/stack v1.8.1 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/go-cmp v0.5.9 // indirect @@ -74,11 +74,11 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl/v2 v2.13.0 // indirect github.com/hashicorp/serf v0.9.7 // indirect - github.com/klauspost/compress v1.15.1 // indirect + github.com/klauspost/compress v1.15.15 // indirect github.com/lithammer/shortuuid/v3 v3.0.7 // indirect github.com/magiconair/properties v1.8.6 // indirect - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect @@ -91,11 +91,11 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.39.0 // indirect + github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rabbitmq/amqp091-go v1.2.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/spf13/afero v1.8.2 // indirect + github.com/spf13/afero v1.9.2 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect @@ -113,12 +113,12 @@ require ( go.opentelemetry.io/otel/exporters/jaeger v1.6.3 // indirect go.opentelemetry.io/otel/sdk v1.6.3 // indirect go.opentelemetry.io/otel/trace v1.10.0 // indirect - go.uber.org/atomic v1.9.0 // indirect + go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.8.0 // indirect go.uber.org/ratelimit v0.2.0 // indirect - go.uber.org/zap v1.21.0 // indirect - golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect - golang.org/x/mod v0.8.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/crypto v0.4.0 // indirect + golang.org/x/mod v0.9.0 // indirect golang.org/x/net v0.8.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.6.0 // indirect diff --git a/go.sum b/go.sum index 888ba72..baf60f8 100644 --- a/go.sum +++ b/go.sum @@ -48,32 +48,32 @@ github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/NpoolPlatform/account-middleware v0.0.0-20230908122122-cd58a2b8c771 h1:aB0saOO9lXIHlu+g36mxRMTW8WeqHpyBsSxZmtQJgAk= -github.com/NpoolPlatform/account-middleware v0.0.0-20230908122122-cd58a2b8c771/go.mod h1:5Labnj7w3bY+FKWSDGu/bRasE2obtkfSbYlcrvYJaaI= -github.com/NpoolPlatform/appuser-middleware v0.0.0-20230513100509-b19f356ebd4b h1:YmlmVjzJLebnrNl9dtFiJ6bfgqoH++uFe91esScPanE= -github.com/NpoolPlatform/appuser-middleware v0.0.0-20230513100509-b19f356ebd4b/go.mod h1:BzT48sEK4KSO6Gy8VJQa5rOuO5JpXib/cmLGHWt4Aqc= -github.com/NpoolPlatform/basal-middleware v0.0.0-20230908131959-b37594a23afd h1:lAg78Zw3w8WbcJ+D9mMO0SdVPAzePNYL33Cqc9l4PP8= -github.com/NpoolPlatform/basal-middleware v0.0.0-20230908131959-b37594a23afd/go.mod h1:XN8xmZjgdG3M4NvPAx4eadIVok/LUJ76DlnQyXOy38M= -github.com/NpoolPlatform/chain-middleware v0.0.0-20230906092012-a63f3a7b0b54 h1:wnYxTar4XI8M+c7ECl52S9emUwiSDdf/etIlLcMv5L4= -github.com/NpoolPlatform/chain-middleware v0.0.0-20230906092012-a63f3a7b0b54/go.mod h1:y3bX+6Yt8cz5s6aQypnqbQzttbwVTOuhK++LU1OBvxA= +github.com/NpoolPlatform/account-middleware v0.0.0-20230913133754-4faeebde91e8 h1:5SPtfrqT6Cgzn4CHmEzWeF1j9lvBQNwxycgpaS+MghA= +github.com/NpoolPlatform/account-middleware v0.0.0-20230913133754-4faeebde91e8/go.mod h1:3uNhYewYAvxRpJyvTL1BsFDOkQFB57lqezvy2V1HyXg= +github.com/NpoolPlatform/appuser-middleware v0.0.0-20230913142320-746bdc6ca127 h1:RnpE6UEI1vZ3XT6jZewRi9WlHAGkM4ctc7cMMzt8heY= +github.com/NpoolPlatform/appuser-middleware v0.0.0-20230913142320-746bdc6ca127/go.mod h1:a41S7hLGr5+QhtJXRtXMjVTbxdYSj6OMRweIDNpvVK4= +github.com/NpoolPlatform/basal-middleware v0.0.0-20230913134752-d45f93a3a60c h1:PAjvDSqQWZWyK1+AhdKJXC/W4dUO54o/lhRVLePhxHM= +github.com/NpoolPlatform/basal-middleware v0.0.0-20230913134752-d45f93a3a60c/go.mod h1:9CZGZ/CFOtUQBsScxw2RDyOeJmYzBqRCa7hxpdDGNJg= +github.com/NpoolPlatform/chain-middleware v0.0.0-20230913142438-2e5786e6ca7e h1:aM0ashXyQrRC4ERdEvk1xpAvNfDk/FGMWUIG8LyvfNM= +github.com/NpoolPlatform/chain-middleware v0.0.0-20230913142438-2e5786e6ca7e/go.mod h1:bgm0T7Pa5Wn+bDa15ihsgKmrAL+7LJ3v44G2LmA1UHM= github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821 h1:JEoN8rpjyJOpbXXLhL5J6Fjw+/bOTwMNci6CL7G02zQ= github.com/NpoolPlatform/dtm-cluster v0.0.0-20230901092100-75e025eff821/go.mod h1:ZBvGIj+zt7VT6WbnIeU/fhiI/dEoNK4JqcXE1EIblpQ= -github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e h1:17BGexCmCdOOBXKYogP8RNE+pAHRu2N4LKq9znPJ4vc= -github.com/NpoolPlatform/go-service-framework v0.0.0-20230814035104-e1466b5c157e/go.mod h1:Kh7DMkWnYOMHxEKq7QfJqbxm1HaUPkhTNN74lfHQxyE= -github.com/NpoolPlatform/good-middleware v0.0.0-20230911050119-fa126024fa1f h1:HxmxEV+CBKT9MBfIxZ0CPHIZrOkp29+SbOLXe6nC17k= -github.com/NpoolPlatform/good-middleware v0.0.0-20230911050119-fa126024fa1f/go.mod h1:pVVsqViUGbt+kvawrTgGeRu0xLRshVSlKlDwvxg/ipI= -github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2 h1:gFrEiTDDu+F1F9XfrCyOjf+iVwpDRGddCaFxFNPHnp4= -github.com/NpoolPlatform/inspire-middleware v0.0.0-20230907035923-c90b50a84df2/go.mod h1:r8yyPbydrlL5MXMDT90qgqx/Y6mkCFEfOPdjxNavhJQ= -github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1 h1:tv2Ze+8CzrUvfN4/I57fn3Z6KHJwSTZNi3NsFG78G9Q= -github.com/NpoolPlatform/ledger-middleware v0.0.0-20230908093825-dace2fee13a1/go.mod h1:t484//GSJFuy3Flc9puq2MJ628QotxoqA8Gy1Cou0W4= +github.com/NpoolPlatform/go-service-framework v0.0.0-20230913101807-3934219c0456 h1:8wnhwmXEsEwXoHEKXsZby2U2a53kiuoByOXGPT8K+Qs= +github.com/NpoolPlatform/go-service-framework v0.0.0-20230913101807-3934219c0456/go.mod h1:Kh7DMkWnYOMHxEKq7QfJqbxm1HaUPkhTNN74lfHQxyE= +github.com/NpoolPlatform/good-middleware v0.0.0-20230913132908-c12992db53da h1:/IFx5/2uzVm5eZ2UzOI5OOdiWDKFwOanu/iIyyGT9kU= +github.com/NpoolPlatform/good-middleware v0.0.0-20230913132908-c12992db53da/go.mod h1:G1N0kJW/x0//wlTvwmyvU7htm+RhRJoJiDXE39wq7Bg= +github.com/NpoolPlatform/inspire-middleware v0.0.0-20230913112606-d48a3cb95447 h1:5snp26AxupkcNQev8bzVgjL1vIV++6sGoxSdMO9ooYY= +github.com/NpoolPlatform/inspire-middleware v0.0.0-20230913112606-d48a3cb95447/go.mod h1:eTMv1XiJptV8MSrYDhJb/ucfzbtf1j8ozEc648jQF4g= +github.com/NpoolPlatform/ledger-middleware v0.0.0-20230913131713-3f2e2a885752 h1:P0IouWSGB10HpHZvNxCOdy6Zo+ow0bX4nLu5OQjxHbg= +github.com/NpoolPlatform/ledger-middleware v0.0.0-20230913131713-3f2e2a885752/go.mod h1:YY7TTNnKu6Z3faYdzFOh86WgAn1rn429QBxoq5w6pws= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99 h1:boB4NuhQxXWeV0Z1qSxgIqbiMYU30dqFGDLtgNTqYbE= github.com/NpoolPlatform/libent-cruder v0.0.0-20230825073905-d23e4d838f99/go.mod h1:1B4hvnPiGavpCYaEjW5H6xDz+UizFdRTIRBtNIGbx5s= -github.com/NpoolPlatform/message v0.0.0-20230911023910-b5e4f88e2e29 h1:SJAyxSsmP1kKpUCn44X2lrA48fmnNNBtFu/dFNGGSPM= -github.com/NpoolPlatform/message v0.0.0-20230911023910-b5e4f88e2e29/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= -github.com/NpoolPlatform/order-middleware v0.0.0-20230910111152-0dc718973845 h1:RsnoFXjSwG4hV2Op/c8088ylbYZ8NknlUTs2+oVLg2c= -github.com/NpoolPlatform/order-middleware v0.0.0-20230910111152-0dc718973845/go.mod h1:sou8KMb443BSROjGWE+CrIGF9k1Uv0draCpkj9jE+Ls= -github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b h1:Ks5kNee/mPcBnjdBugi/VC1mdcsWxETagVL3a+0e3v0= -github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230216075025-a90a86bfd19b/go.mod h1:9C9XDi7c0szxcLdJGDDFuo3/KtC74yWiyUM2fR+i0ww= +github.com/NpoolPlatform/message v0.0.0-20230914023737-ac5d6d2a3a03 h1:AGqo8LT/8oJQarf5Ty5r10S6rWyAymMmXP+bCRrlyAQ= +github.com/NpoolPlatform/message v0.0.0-20230914023737-ac5d6d2a3a03/go.mod h1:PxJpF0vSSOke+NJskbRBRQ2fK2K3SRe8zaEja+GxSHk= +github.com/NpoolPlatform/order-middleware v0.0.0-20230913130356-4fe8c6fe2907 h1:2RR/IfclN5MQXm0qBbdirzCzO0lX9zIhblnVokB5VTo= +github.com/NpoolPlatform/order-middleware v0.0.0-20230913130356-4fe8c6fe2907/go.mod h1:KDdg70LakIg5hVE/TQawKgah/RTsfaXktaLvRmSyLHY= +github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230914031406-667706c33172 h1:KtveFZ/OM590xdZPb9o8hCSCaMtUaKIbbLvLOVK6s3E= +github.com/NpoolPlatform/sphinx-proxy v0.0.0-20230914031406-667706c33172/go.mod h1:syx+ZVgI1N7fbonzzjC6Or2m9/loF4yyBksM64x8Ugs= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shonminh/apollo-client v0.4.0 h1:AXGp4wOahrEKjheMXehgsG9B8dEfLQHttRLHeEefvus= @@ -100,7 +100,6 @@ github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -146,8 +145,8 @@ github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= @@ -184,10 +183,11 @@ github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -269,8 +269,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 h1:gDLXvp5S9izjldquuoAhDzccbskOL6tDC5jMSyx3zxE= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2/go.mod h1:7pdNwVWBBHGiCxa9lAszqCJMbfTISJ7oMftp8+UGV08= github.com/grpc/grpc-go v1.41.0 h1:mgY4oFjHTV35T076OO8kzb6RYhHR27FFHuka4hP10kA= github.com/grpc/grpc-go v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= github.com/hashicorp/consul/api v1.12.0 h1:k3y1FYv6nuKyNTqj6w9gXOx5r5CfLj/k/euUeBXj1OY= @@ -332,8 +332,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= -github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= +github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -353,17 +353,18 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -425,8 +426,8 @@ github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvq github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= -github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -449,8 +450,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= -github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= +github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= +github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= @@ -462,9 +463,7 @@ github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -472,9 +471,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI= github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= @@ -483,8 +481,8 @@ github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqri github.com/ugorji/go v0.0.0-20190204201341-e444a5086c43 h1:nLURyLzmXqqnferXOGs9EA2kbhl/bks8vSyptHCxH34= github.com/ugorji/go v0.0.0-20190204201341-e444a5086c43/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/urfave/cli/v2 v2.16.3 h1:gHoFIwpPjoyIMbJp/VFd+/vuD0dAgFK4B6DpEMFJfQk= -github.com/urfave/cli/v2 v2.16.3/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= +github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= +github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= @@ -501,7 +499,6 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA= github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= go.mongodb.org/mongo-driver v1.9.1 h1:m078y9v7sBItkt1aaoe2YlvWEXcD263e1a4E1fBrJ1c= @@ -530,20 +527,18 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/ratelimit v0.1.0/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y= go.uber.org/ratelimit v0.2.0 h1:UQE2Bgi7p2B85uP5dC2bbRtig0C+OeNRnNEafLjsLPA= go.uber.org/ratelimit v0.2.0/go.mod h1:YYBV4e4naJvhpitQrWJu1vCpgB7CboMe0qhltKt6mUg= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= -go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -554,8 +549,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= +golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -588,9 +583,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -624,7 +618,6 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= @@ -638,7 +631,7 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8= +golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -697,11 +690,10 @@ golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -771,8 +763,7 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 55aacca52d0d82de582aa03a1f389afae12c17d5 Mon Sep 17 00:00:00 2001 From: Zhao KK Date: Thu, 14 Sep 2023 03:52:52 +0000 Subject: [PATCH 67/67] Correct --- cmd/order-gateway/run.go | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/cmd/order-gateway/run.go b/cmd/order-gateway/run.go index 02234da..5ea706b 100644 --- a/cmd/order-gateway/run.go +++ b/cmd/order-gateway/run.go @@ -8,10 +8,6 @@ import ( "github.com/NpoolPlatform/go-service-framework/pkg/logger" "github.com/NpoolPlatform/order-gateway/api" "github.com/NpoolPlatform/order-gateway/pkg/migrator" -<<<<<<< HEAD -======= - "github.com/NpoolPlatform/order-middleware/pkg/db" ->>>>>>> 2bbb23e94a2bdb9ca89f5300f366ec505a93ba50 "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" cli "github.com/urfave/cli/v2" "google.golang.org/grpc" @@ -22,32 +18,19 @@ var runCmd = &cli.Command{ Aliases: []string{"s"}, Usage: "Run the daemon", Action: func(c *cli.Context) error { -<<<<<<< HEAD err := action.Run( -======= - return action.Run( ->>>>>>> 2bbb23e94a2bdb9ca89f5300f366ec505a93ba50 c.Context, run, rpcRegister, rpcGatewayRegister, watch, ) -<<<<<<< HEAD return err -======= ->>>>>>> 2bbb23e94a2bdb9ca89f5300f366ec505a93ba50 }, } func run(ctx context.Context) error { -<<<<<<< HEAD -======= - if err := db.Init(); err != nil { - return err - } ->>>>>>> 2bbb23e94a2bdb9ca89f5300f366ec505a93ba50 if err := migrator.Migrate(ctx); err != nil { return err } @@ -81,10 +64,7 @@ func rpcGatewayRegister(mux *runtime.ServeMux, endpoint string, opts []grpc.Dial if err != nil { return err } -<<<<<<< HEAD -======= _ = apicli.Register(mux) ->>>>>>> 2bbb23e94a2bdb9ca89f5300f366ec505a93ba50 return nil }