private void AssertCashTransferOperation(CashTransferOperation cashTransferOperation, decimal volume)
 {
     Assert.NotNull(cashTransferOperation);
     Assert.NotEmpty(cashTransferOperation.Id);
     Assert.Equal(cashTransferOperation.BrokerId, BrokerId);
     Assert.Equal(cashTransferOperation.AccountId, AccountId);
     Assert.Equal(cashTransferOperation.FromWalletId, FromWalletId);
     Assert.Equal(cashTransferOperation.ToWalletId, ToWalletId);
     Assert.Equal(cashTransferOperation.AssetId, Btc);
     Assert.Equal(cashTransferOperation.Volume, volume.ToString(CultureInfo.InvariantCulture));
     Assert.Equal(cashTransferOperation.Description, Description);
 }
Exemple #2
0
        /// <summary>
        /// Возвращает сумму находящуюся в перемещении между кассами
        /// </summary>
        public decimal GetCashInTransfering(IUnitOfWork uow)
        {
            CashTransferOperation    cashTransferOperationAlias = null;
            CashTransferDocumentBase cashTransferDocumentAlias  = null;

            return(uow.Session.QueryOver <CashTransferDocumentBase>(() => cashTransferDocumentAlias)
                   .Left.JoinAlias(() => cashTransferDocumentAlias.CashTransferOperation, () => cashTransferOperationAlias)
                   .Where(() => cashTransferDocumentAlias.Status != CashTransferDocumentStatuses.Received)
                   .Where(() => cashTransferDocumentAlias.Status != CashTransferDocumentStatuses.New)
                   .Where(() => cashTransferOperationAlias.ReceiveTime == null)
                   .Select(Projections.Sum <CashTransferOperation>(o => o.TransferedSum))
                   .SingleOrDefault <decimal>());
        }
Exemple #3
0
        public async Task <OperationResponse> CashTransferAsync(string brokerId, CashTransferModel model)
        {
            var wallets = await _accountsClient.Wallet.GetAllAsync(new[] { (long)model.FromWalletId, (long)model.ToWalletId }, brokerId);

            var fromWallet = wallets.SingleOrDefault(x => x.Id == (long)model.FromWalletId);

            var toWallet = wallets.SingleOrDefault(x => x.Id == (long)model.ToWalletId);

            if (fromWallet == null)
            {
                throw new ArgumentException($"Source wallet '{model.FromWalletId}' doesn't exist.");
            }

            if (toWallet == null)
            {
                throw new ArgumentException($"Target wallet '{model.ToWalletId}' doesn't exist.");
            }

            if (!toWallet.IsEnabled)
            {
                throw new ArgumentException($"Target wallet '{model.FromWalletId}' is disabled.");
            }

            if (fromWallet.AccountId != toWallet.AccountId)
            {
                throw new ArgumentException($"Target and source wallets must have the same account id.");
            }

            var request = new CashTransferOperation
            {
                Id           = Guid.NewGuid().ToString(),
                BrokerId     = brokerId,
                AssetId      = model.Asset,
                Volume       = model.Volume.ToString(CultureInfo.InvariantCulture),
                AccountId    = model.AccountId,
                FromWalletId = model.FromWalletId,
                ToWalletId   = model.ToWalletId,
                Description  = model.Description
            };

            var fee = await GetFeeAsync(brokerId, model.Asset, RequestType.Transfer);

            request.Fees.Add(fee);

            var result = await _matchingEngineClient.CashOperations.CashTransferAsync(request);

            return(new OperationResponse(result));
        }
        public override Task <CashTransferOperationResponse> CashTransfer(CashTransferOperation request,
                                                                          ServerCallContext context)
        {
            using var activity = MyTelemetry.StartActivity("CashTransfer");

            activity?.AddTag("operationId", request.Id)
            .AddTag("brokerId", request.BrokerId)
            .AddTag("accountId", request.AccountId)
            .AddTag("fromWalletId", request.FromWalletId)
            .AddTag("toWalletId", request.ToWalletId)
            .AddTag("assetId", request.AssetId)
            .AddTag("volume", request.Volume);

            return(_cashServiceClient.CashTransferAsync(request, cancellationToken: context.CancellationToken)
                   .ResponseAsync);
        }
Exemple #5
0
        public async Task CashTransfer()
        {
            AccountEntity testAccount1 = (AccountEntity)await this.AccountRepository.TryGetAsync(this.TestAccountId1);

            Assert.NotNull(testAccount1);
            BalanceDTO accountBalance1 = testAccount1.BalancesParsed.Where(b => b.Asset == this.TestAsset1).FirstOrDefault();

            Assert.NotNull(accountBalance1);

            AccountEntity testAccount2 = (AccountEntity)await this.AccountRepository.TryGetAsync(this.TestAccountId2);

            Assert.NotNull(testAccount2);
            BalanceDTO accountBalance2 = testAccount2.BalancesParsed.Where(b => b.Asset == this.TestAsset1).FirstOrDefault();

            Assert.NotNull(accountBalance2);

            //Attempt invalid transfer
            double          badTransferAmount   = accountBalance1.Balance + 0.7;
            string          badTransferId       = Guid.NewGuid().ToString();
            MeResponseModel badTransferResponse = await this.Consumer.Client.TransferAsync(badTransferId, testAccount1.Id, testAccount2.Id, this.TestAsset1, badTransferAmount);

            Assert.NotNull(badTransferResponse);
            Assert.True(badTransferResponse.Status == MeStatusCodes.LowBalance);



            //Transfer from Test acc 1 to Test acc 2
            double          transferAmount   = Math.Round(accountBalance1.Balance / 10, this.AssetPrecission);
            string          transferId       = Guid.NewGuid().ToString();
            MeResponseModel transferResponse = await this.Consumer.Client.TransferAsync(transferId, testAccount1.Id, testAccount2.Id, this.TestAsset1, transferAmount);

            Assert.NotNull(transferResponse);
            Assert.True(transferResponse.Status == MeStatusCodes.Ok);

            CashTransferOperation message = (CashTransferOperation)await this.WaitForRabbitMQ <CashTransferOperation>(o => o.id == transferId);

            Assert.NotNull(message);
            Assert.True(message.asset == this.TestAsset1);
            Assert.True(message.fromClientId == testAccount1.Id);
            Assert.True(message.toClientId == testAccount2.Id);
            if (Double.TryParse(message.volume, NumberStyles.Float, CultureInfo.InvariantCulture, out double parsedMsgAmount))
            {
                Assert.True(parsedMsgAmount == transferAmount);
            }

            CashSwapEntity checkCashSwapOperation = (CashSwapEntity)await this.CashSwapRepository.TryGetAsync(c => c.ExternalId == transferId);

            Assert.True(checkCashSwapOperation.Amount == transferAmount);
            Assert.True(checkCashSwapOperation.AssetId == this.TestAsset1);
            Assert.True(checkCashSwapOperation.FromClientId == testAccount1.Id);
            Assert.True(checkCashSwapOperation.ToClientId == testAccount2.Id);

            AccountEntity checkTestAccount1 = (AccountEntity)await this.AccountRepository.TryGetAsync(this.TestAccountId1);

            BalanceDTO    checkAccountBalance1 = checkTestAccount1.BalancesParsed.Where(b => b.Asset == this.TestAsset1).FirstOrDefault();
            AccountEntity checkTestAccount2    = (AccountEntity)await this.AccountRepository.TryGetAsync(this.TestAccountId2);

            BalanceDTO checkAccountBalance2 = checkTestAccount2.BalancesParsed.Where(b => b.Asset == this.TestAsset1).FirstOrDefault();

            Assert.True(Math.Round(checkAccountBalance1.Balance, this.AssetPrecission) == Math.Round(accountBalance1.Balance - transferAmount, this.AssetPrecission)); // TODO get asset accuracy
            Assert.True(Math.Round(checkAccountBalance2.Balance, this.AssetPrecission) == Math.Round(accountBalance2.Balance + transferAmount, this.AssetPrecission)); // TODO get asset accuracy



            //Transfer same amount from Test acc 2 to Test acc 1
            string          transferBackId       = Guid.NewGuid().ToString();
            MeResponseModel transferBackResponse = await this.Consumer.Client.TransferAsync(transferBackId, testAccount2.Id, testAccount1.Id, this.TestAsset1, transferAmount);

            Assert.NotNull(transferBackResponse);
            Assert.True(transferBackResponse.Status == MeStatusCodes.Ok);

            message = (CashTransferOperation)await this.WaitForRabbitMQ <CashTransferOperation>(o => o.id == transferBackId);

            Assert.NotNull(message);
            Assert.True(message.asset == this.TestAsset1);
            Assert.True(message.fromClientId == testAccount2.Id);
            Assert.True(message.toClientId == testAccount1.Id);
            if (Double.TryParse(message.volume, NumberStyles.Float, CultureInfo.InvariantCulture, out parsedMsgAmount))
            {
                Assert.True(parsedMsgAmount == transferAmount);
            }

            CashSwapEntity checkCashSwapBackOperation = (CashSwapEntity)await this.CashSwapRepository.TryGetAsync(c => c.ExternalId == transferBackId);

            Assert.True(checkCashSwapBackOperation.Amount == transferAmount);
            Assert.True(checkCashSwapBackOperation.AssetId == this.TestAsset1);
            Assert.True(checkCashSwapBackOperation.FromClientId == testAccount2.Id);
            Assert.True(checkCashSwapBackOperation.ToClientId == testAccount1.Id);

            checkTestAccount1 = (AccountEntity)await this.AccountRepository.TryGetAsync(this.TestAccountId1);

            checkAccountBalance1 = checkTestAccount1.BalancesParsed.Where(b => b.Asset == this.TestAsset1).FirstOrDefault();
            checkTestAccount2    = (AccountEntity)await this.AccountRepository.TryGetAsync(this.TestAccountId2);

            checkAccountBalance2 = checkTestAccount2.BalancesParsed.Where(b => b.Asset == this.TestAsset1).FirstOrDefault();

            //balances should be back to their initial state after 2 transfers back and forward
            Assert.True(accountBalance1.Balance == checkAccountBalance1.Balance);
            Assert.True(accountBalance2.Balance == checkAccountBalance2.Balance);
        }
Exemple #6
0
 async Task <CashTransferOperationResponse> ICashServiceClient.CashTransferAsync(CashTransferOperation request, CancellationToken cancellationToken)
 {
     return(await CashTransferAsync(request, cancellationToken : cancellationToken));
 }
Exemple #7
0
 CashTransferOperationResponse ICashServiceClient.CashTransfer(CashTransferOperation request, CancellationToken cancellationToken)
 {
     return(CashTransfer(request, cancellationToken: cancellationToken));
 }
Exemple #8
0
        private async Task ProcessMessageAsync(CashTransferEvent item)
        {
            var id = item.Header.MessageId ?? item.Header.RequestId;

            try
            {
                IPaymentTransaction paymentTransaction = null;

                for (int i = 0; i < 3; i++)
                {
                    paymentTransaction = await _paymentTransactionsRepository.GetByIdForClientAsync(id, item.CashTransfer.ToWalletId);

                    if (paymentTransaction != null)
                    {
                        break;
                    }
                    await Task.Delay(2000 *(i + 1));
                }

                double volume = double.Parse(item.CashTransfer.Volume);

                if (item.CashTransfer.Fees != null)
                {
                    foreach (var fee in item.CashTransfer.Fees)
                    {
                        if (string.IsNullOrWhiteSpace(fee.Transfer?.Volume))
                        {
                            continue;
                        }

                        volume -= double.Parse(fee.Transfer.Volume);
                    }
                }

                if (paymentTransaction == null || paymentTransaction.PaymentSystem != CashInPaymentSystem.Swift)
                {
                    var cashOp = new CashOperation
                    {
                        Id       = id,
                        ClientId = item.CashTransfer.ToWalletId,
                        Asset    = item.CashTransfer.AssetId,
                        Volume   = volume,
                        DateTime = item.Header.Timestamp,
                    };

                    await _cashOperationsCollector.AddDataItemAsync(cashOp);
                }
                else
                {
                    var transfer = new CashTransferOperation
                    {
                        Id           = id,
                        FromClientId = item.CashTransfer.FromWalletId,
                        ToClientId   = item.CashTransfer.ToWalletId,
                        Asset        = item.CashTransfer.AssetId,
                        Volume       = volume,
                        DateTime     = item.Header.Timestamp,
                    };
                    await _cashTransfersCollector.AddDataItemAsync(transfer);
                }
            }
            catch (Exception exc)
            {
                _log.Error(exc, context: item);
            }
        }
Exemple #9
0
 public async Task <Response> CashTransferAsync(CashTransferOperation request, CancellationToken cancellationToken = default)
 {
     return(await _client.CashTransferAsync(request, cancellationToken : cancellationToken));
 }
Exemple #10
0
 public Task <CashTransferOperationResponse> CashTransferAsync(CashTransferOperation request, CancellationToken cancellationToken = new CancellationToken())
 {
     throw new System.NotImplementedException();
 }