public void Ceiling__Produces_Correct_result(string a, string b) { Money18 .Ceiling(Money18.Parse(a)) .Should() .Be(b); }
public void Truncate__Produces_Correct_Result(string a, string b) { Money18 .Truncate(Money18.Parse(a)) .Should() .Be(b); }
public void Money_Should_Be_Deserializable_From_Json() { JsonConvert .DeserializeObject <Money18>("\"10.00000\"") .Should() .Be(Money18.Create(10, 5)); }
public void Round__Scale_Specified__Produces_Correct_Result(string a, string b) { Money18 .Round(Money18.Parse(a), 2) .Should() .Be(b); }
public async Task <TransferToExternalResultModel> TransferAsync(string customerId, string amount) { if (string.IsNullOrEmpty(customerId)) { throw new ArgumentNullException(nameof(customerId)); } if (string.IsNullOrEmpty(amount)) { throw new ArgumentNullException(nameof(amount)); } if (!Money18.TryParse(amount, out var amount18)) { throw new FormatException("Amount is in wrong format"); } var response = await _ccTransfersClient.Api.TransferToExternalAsync( new TransferToExternalRequest { CustomerId = customerId, Amount = amount18 }); if (response.Error != TransferToExternalErrorCodes.None) { _log.Warning("Couldn't transfer to external wallet", context: new { customerId, amount, error = response.Error.ToString() }); } return(_mapper.Map <TransferToExternalResultModel>(response)); }
public override object ConvertFrom( ITypeDescriptorContext context, CultureInfo culture, object value) { return(Money18.Parse((string)value)); }
public async Task <TokensErrorCodes> SyncTotalTokensAsync() { try { var totalTokensFromPbf = (await GetTotalTokensAsync()).TotalTokensAmount; var totalTokensOnTokenGateway = (await GetTotalTokensOnTokenGatewayAsync()).TotalTokensAmount; var totalTokensOnCustomersWallets = totalTokensFromPbf - totalTokensOnTokenGateway; _log.Info($@"Manually synchronized Total Tokens from PBF service. Old value: {_totalTokensAmount}, new value: {totalTokensFromPbf}"); _totalTokensAmount = totalTokensFromPbf; _log.Info($@"Manually synchronized Total Tokens on customer wallets from PBF service. Old value: {_totalTokensInCustomersWallets}, new value: {totalTokensOnCustomersWallets}"); _totalTokensInCustomersWallets = totalTokensOnCustomersWallets; return(TokensErrorCodes.None); } catch { _log.Warning("Not able to get total tokens amount from pbf to Sync value"); return(TokensErrorCodes.PrivateBlockchainFacadeIsNotAvailable); } }
public void CompareTo__Integer_Value_Passed__Returns_Correct_Result() { var money = new Money18(42, 0); (money < 43).Should().BeTrue(); (money > 41).Should().BeTrue(); (money <= 43).Should().BeTrue(); (money >= 41).Should().BeTrue(); (money <= 42).Should().BeTrue(); (money >= 42).Should().BeTrue(); (43 > money).Should().BeTrue(); (41 < money).Should().BeTrue(); (43 >= money).Should().BeTrue(); (41 <= money).Should().BeTrue(); (42 <= money).Should().BeTrue(); (42 >= money).Should().BeTrue(); money .CompareTo(41) .Should() .BePositive(); money .CompareTo(42) .Should() .Be(0); money .CompareTo(43) .Should() .BeNegative(); }
private static Money18 CalculateTotalReward(CampaignDetails result) { var isApproximate = result.RewardType == RewardType.Percentage || result.RewardType == RewardType.ConversionRate; var earnRuleReward = isApproximate && result.ApproximateAward.HasValue ? result.ApproximateAward.Value : result.Reward; if (result.Conditions.Count == 1) { return(earnRuleReward); } Money18 conditionReward = 0m; foreach (var condition in result.Conditions) { var isApproximateCondition = condition.RewardType == RewardType.Percentage || condition.RewardType == RewardType.ConversionRate; var conditionAmount = isApproximateCondition && condition.ApproximateAward.HasValue ? condition.ApproximateAward.Value : condition.ImmediateReward; conditionReward += conditionAmount; } var totalReward = conditionReward; return(totalReward); }
private async Task SendNotificationAsync(string customerId, Money18 amount, Guid campaignId, Guid conditionId, string requestId) { var campaign = await _campaignClient.History.GetEarnRuleByIdAsync(campaignId); if (campaign.ErrorCode != CampaignServiceErrorCodes.None) { _log.Error(message: "An error occurred while getting campaign", context: $"customerId: {customerId}; requestId: {requestId}; campaignId: {campaignId}; error: {campaign.ErrorCode}"); return; } if (conditionId == Guid.Empty) { await _pushNotificationsPublisher.PublishCampaignCompletedAsync(customerId, amount, campaign.Name); } else { var condition = campaign.Conditions.FirstOrDefault(o => o.Id == conditionId.ToString()); if (condition == null) { _log.Error(message: "Campaign does not contains condition", context: $"customerId: {customerId}; requestId: {requestId}; campaignId: {campaignId}; conditionId: {conditionId}"); return; } await _pushNotificationsPublisher.PublishCampaignConditionCompletedAsync(customerId, amount, campaign.Name, condition.TypeDisplayName); } }
public async Task ProcessP2PTransferFailed( string contextId, string transactionHash, string senderCustomerId, string receiverCustomerId, Money18 amount, DateTime timestamp) { var transferContext = await _transfersRepository.GetAsync(contextId); if (transferContext == null) { _log.Error(message: "Context not found for p2p failed transfer", context: new { requestId = contextId, transactionHash, senderCustomerId, receiverCustomerId }); return; } var senderCurrentBalance = await GetCustomerCurrentBalance(senderCustomerId); var receiverEmail = await GetCustomerEmail(receiverCustomerId); var emailNotificationTask = _emailsPublisher.SendP2PFailedForSenderAsync( senderCustomerId, contextId, amount, timestamp, senderCurrentBalance, receiverEmail); var pushNotificationTask = _pushNotificationsPublisher.PublishP2PFailedForSenderAsync(senderCustomerId); await Task.WhenAll(emailNotificationTask, pushNotificationTask); await _transfersRepository.DeleteAsync(contextId); }
private async Task <Money18> CalculateConditionRewardByPercentageAsync(Money18 percentage, ConditionCompletion conditionCompletion, string paymentId = null) { Money18 rewardsAmount = 0; foreach (var completionData in conditionCompletion.Data) { if (paymentId != null && completionData.ContainsKey(paymentId)) { var rewardDictionary = completionData[paymentId]; var paymentDictionary = JsonConvert.DeserializeObject <Dictionary <string, string> >(rewardDictionary); rewardsAmount += Money18.Parse(paymentDictionary[AmountName]); } else if (paymentId == null && completionData != null && completionData.ContainsKey(AmountName)) { rewardsAmount += Money18.Parse(completionData[AmountName]); } } var amountInCurrency = rewardsAmount * (percentage / 100m); return(await GetEligibilityEngineAmountByCondition(conditionCompletion, amountInCurrency)); }
public Money18 CalculateRatioReward(IReadOnlyList <RatioAttribute> conditionRatios, Dictionary <string, string> conditionCompletionRewardDictionary, Money18 conditionReward) { Money18 reward = 0m; var ratiosForBonus = new List <RatioAttribute>(); var savedData = JsonConvert.DeserializeObject <Dictionary <string, string> >(conditionCompletionRewardDictionary.Values.FirstOrDefault()); if (savedData != null) { var purchaseCompletion = Convert.ToDecimal(savedData["PurchaseCompletionPercentage"]); var givenBonusFor = Convert.ToDecimal(savedData["GivenRatioBonusPercent"]); foreach (var ratio in conditionRatios.OrderBy(r => r.Order)) { if (purchaseCompletion >= ratio.Threshold) { //in order not to give two times reward for 10% if (givenBonusFor < ratio.Threshold) { ratiosForBonus.Add(ratio); } } } } foreach (var ratio in ratiosForBonus) { reward += ((Money18)ratio.RewardRatio / 100M) * conditionReward; } return(reward); }
public async Task <SpendRulesListResponseModel> GetSpendRulesAsync([FromQuery] PaginationRequestModel pagination) { var spendRules = await _campaignClient.Mobile.GetSpendRulesAsync(Localization.En, _mapper.Map <BasePaginationRequestModel>(pagination)); var result = _mapper.Map <SpendRulesListResponseModel>(spendRules); foreach (var spendRule in result.SpendRules) { if (spendRule.BusinessVertical != BusinessVertical.Retail) { continue; } var report = await _vouchersClient.Reports.GetSpendRuleVouchersAsync(spendRule.Id); spendRule.StockCount = report.InStock; spendRule.SoldCount = report.Total - report.InStock; var rate = await _eligibilityEngineClient.ConversionRate.GetAmountBySpendRuleAsync( new ConvertAmountBySpendRuleRequest() { Amount = Money18.Create(Math.Abs(spendRule.Price ?? 0)), CustomerId = Guid.Parse(_requestContext.UserId), SpendRuleId = spendRule.Id, FromCurrency = _settingsService.GetBaseCurrencyCode(), ToCurrency = _settingsService.GetTokenName(), } ); spendRule.PriceInToken = rate.Amount.ToDisplayString(); } return(result); }
public async Task HandleAsync(SmartVoucherSoldEvent message) { var partner = await _partnerManagementClient.Partners.GetByIdAsync(message.PartnerId); var customer = (await _customerProfileClient.CustomerProfiles.GetByCustomerIdAsync(message.CustomerId.ToString(), true, true))?.Profile; var campaign = await _smartVouchersClient.CampaignsApi.GetByIdAsync(message.CampaignId); var receiverEmail = partner.Locations.Count == 1 ? partner.Locations.First()?.ContactPerson?.Email : null; await _reportHelper.AddAsync(new TransactionReport { Amount = Money18.Create(message.Amount), Id = message.PaymentRequestId, PartnerId = message.PartnerId.ToString(), Timestamp = message.Timestamp, Vertical = partner.BusinessVertical?.ToString(), Info = message.VoucherShortCode, Currency = message.Currency, TransactionType = TxType, SenderEmail = customer?.Email, SenderName = $"{customer?.FirstName} {customer?.LastName}", CampaignName = campaign?.Name, Status = VoucherStatus, CampaignId = message.CampaignId, PartnerName = partner?.Name, ReceiverName = partner?.Name, ReceiverEmail = receiverEmail, }); }
public void Parse__Value_Correctly_Parsed(string a) { Money18 .Parse(a) .Should() .Be(a); }
public async Task HandleAsync(string privateAddress, Money18 amount, string eventId) { var isDuplicate = await _deduplicationLogRepository.IsDuplicateAsync(eventId); if (isDuplicate) { _log.Warning(message: "Duplicated TransferToExternalCompletedEvent found, processing won't continue further", context: eventId); return; } if (string.IsNullOrEmpty(privateAddress)) { _log.Error(message: "Empty private address in TransferToExternalCompleted"); return; } var customerIdResponse = await _pbfClient.CustomersApi.GetCustomerIdByWalletAddress(privateAddress); if (customerIdResponse.Error != CustomerWalletAddressError.None) { _log.Error(message: "Cannot find CustomerId from wallet address to handle TransferToExternalCompletedEvent", context: new { privateAddress, customerIdResponse.Error }); return; } await _pushNotificationsPublisher.PublishTransferToExternalSucceededAsync(customerIdResponse.CustomerId, amount); }
public async Task <OperationFeesModel> GetOperationFeesAsync() { var operationFees = new OperationFeesModel(); var operationFeesConfig = await _crossChainWalletLinkerClient.ConfigurationApi.GetAllAsync(); foreach (var model in operationFeesConfig) { switch (model.Type) { case ConfigurationItemType.FirstTimeLinkingFee: operationFees.FirstTimeLinkingFee = Money18.Parse(model.Value); break; case ConfigurationItemType.SubsequentLinkingFee: operationFees.SubsequentLinkingFee = Money18.Parse(model.Value); break; default: throw new ArgumentOutOfRangeException(); } } var crossChainTransferFee = await _crossChainTransfersClient.FeesApi.GetTransferToPublicFeeAsync(); operationFees.CrossChainTransferFee = crossChainTransferFee.Fee; return(operationFees); }
public async Task <Money18> GetNextWalletLinkingFeeAsync(Guid customerId) { if (customerId == Guid.Empty) { throw new ArgumentNullException(nameof(customerId)); } var counter = await _counterRepository.GetAsync(customerId.ToString()); var fee = await _configurationItemsRepository.GetAsync((counter?.ApprovalsCounter ?? 0) < 1 ?ConfigurationItemType.FirstTimeLinkingFee : ConfigurationItemType.SubsequentLinkingFee); if (fee == null) { _log.Warning("Wallet linking fee has not been set, please use API to update it"); return(0); } if (!Money18.TryParse(fee.Value, out var result)) { _log.Error(message: "Couldn't parse Money18 from configuration value", context: new { fee = fee.Value }); return(0); } return(result); }
private async Task <Money18> GetCustomerCurrentBalance(string customerId) { Money18 amount = 0; try { var currentBalanceResponse = await _blockchainFacadeClient.CustomersApi.GetBalanceAsync(Guid.Parse(customerId)); if (currentBalanceResponse.Error == CustomerBalanceError.None) { amount = currentBalanceResponse.Total; } else { _log.Error( message: "Cannot process P2P failed transfer notifications cause a customer does not have a wallet", context: customerId); } } catch (ClientApiException e) { _log.Error(e, "Cannot get customer balance when processing p2p failed event", customerId); } return(amount); }
public void IncreaseBurnedAmount(Money18 amount) { lock (_locker) { _todaysBurnedAmount += amount; } }
public void Abs__Produces_Correct_Result(string a, string b) { Money18 .Abs(Money18.Parse(a)) .Should() .Be(b); }
protected override async Task ProcessMessageAsync(TransferToInternalDetectedEvent message) { await _handler.HandleAsync(message.OperationId, message.PrivateAddress, message.PublicAddress, Money18.Parse(message.Amount.ToString()), message.PublicTransferId); _log.Info("Processed TransferToInternalDetectedEvent", message); }
public async Task HandleAsync(SmartVoucherUsedEvent message) { var partner = await _partnerManagementClient.Partners.GetByIdAsync(message.PartnerId); var customer = (await _customerProfileClient.CustomerProfiles.GetByCustomerIdAsync(message.CustomerId.ToString(), true, true))?.Profile; var campaign = await _smartVouchersClient.CampaignsApi.GetByIdAsync(message.CampaignId); await _reportHelper.AddAsync(new TransactionReport() { Amount = Money18.Create(message.Amount), Id = Guid.NewGuid().ToString(), PartnerId = message.PartnerId.ToString(), Timestamp = message.Timestamp, Currency = message.Currency, TransactionType = TxType, CampaignName = campaign?.Name, Status = VoucherStatus, CampaignId = message.CampaignId, Vertical = partner.BusinessVertical?.ToString(), SenderEmail = customer?.Email, SenderName = $"{customer?.FirstName} {customer?.LastName}", PartnerName = partner?.Name, Info = message.VoucherShortCode, }); }
public string FormatAmountToDisplayString(Money18 money18) { var formatInfo = new CultureInfo(_tokenFormatCultureInfo).NumberFormat; return(money18.ToString(_tokenIntegerPartFormat, _tokenNumberDecimalPlaces, formatInfo)); }
public void CompareTo__Decimal_Value_Passed__Returns_Correct_Result() { var money = new Money18(42, 0); (money < 43m).Should().BeTrue(); (money > 41m).Should().BeTrue(); (money <= 43m).Should().BeTrue(); (money >= 41m).Should().BeTrue(); (money <= 42m).Should().BeTrue(); (money >= 42m).Should().BeTrue(); (43m > money).Should().BeTrue(); (41m < money).Should().BeTrue(); (43m >= money).Should().BeTrue(); (41m <= money).Should().BeTrue(); (42m <= money).Should().BeTrue(); (42m >= money).Should().BeTrue(); money .CompareTo(41m) .Should() .BePositive(); money .CompareTo(42m) .Should() .Be(0); money .CompareTo(43m) .Should() .BeNegative(); }
public async Task ProcessP2PTransferDetectedEventAsync( string contextId, string transactionHash, string senderCustomerId, string receiverCustomerId, Money18 amount, DateTime timestamp) { var transferContext = await _transfersRepository.GetAsync(contextId); if (transferContext == null) { _log.Error(message: ContextNotFoundMsg, context: new { requestId = contextId, transactionHash, senderCustomerId, receiverCustomerId }); throw new InvalidOperationException(ContextNotFoundMsg); } await _p2PTransferEventPublisher.PublishAsync(new P2PTransferEvent { Amount = amount, Timestamp = timestamp, SenderCustomerId = senderCustomerId, ReceiverCustomerId = receiverCustomerId, AssetSymbol = transferContext.AssetSymbol, TransactionId = transferContext.OperationId, ExternalOperationId = transferContext.ExternalOperationId }); var senderCurrentBalance = await GetCustomerCurrentBalance(senderCustomerId); var receiverCurrentBalance = await GetCustomerCurrentBalance(receiverCustomerId); var senderCustomerEmail = await GetCustomerEmail(senderCustomerId); var receiverCustomerEmail = await GetCustomerEmail(receiverCustomerId); var senderEmailNotificationTask = _emailsPublisher.SendP2PSucceededForSenderAsync(senderCustomerId, contextId, amount, timestamp, senderCurrentBalance, receiverCustomerEmail); var receiverEmailNotificationTask = _emailsPublisher.SendP2PSucceededForReceiverAsync(receiverCustomerId, contextId, amount, timestamp, receiverCurrentBalance, senderCustomerEmail); var senderPushNotificationTask = _pushNotificationsPublisher.PublishP2PSucceededForSenderAsync(senderCustomerId); var receiverPushNotificationTask = _pushNotificationsPublisher.PublishP2PSucceededForReceiverAsync(receiverCustomerId, amount, senderCustomerEmail); await Task.WhenAll( senderEmailNotificationTask, receiverEmailNotificationTask, senderPushNotificationTask, receiverPushNotificationTask); await _transfersRepository.DeleteAsync(contextId); }
public async Task <CurrencyConverterResponse> ConvertTokensToBaseCurrencyAsync(Money18 amount) { var result = await _currencyConverterClient.Converter.ConvertTokensToBaseCurrencyAsync(amount); return(new CurrencyConverterResponse { Amount = Money18.Create(result.Amount).ToDisplayString() }); }
public BaseConversionRateRequestValidator() { RuleFor(r => r.Amount) .NotNull() .NotEmpty() .Must(r => r != null && Money18.TryParse(r, out var money18) && money18 > 0) .WithMessage("Amount should be valid number greater than 0."); }
private async Task <Money18?> GetCachedValue(string walletAddress) { var value = await _distributedCache.GetStringAsync(GetCacheKey(walletAddress)); return(string.IsNullOrEmpty(value) ? new Money18?() : Money18.Parse(value)); }