public async Task <DepositsReport> GetAsync(GetDepositsReport query) { PagedResult <DepositDetails> deposits; if (query.DepositId == null) { deposits = await _depositRepository.BrowseAsync(new GetDeposits { Results = int.MaxValue }); } else { DepositDetails?detailsOfOne = await _depositRepository.GetAsync(query.DepositId); if (detailsOfOne is null) { return(DepositsReport.Empty); } deposits = PagedResult <DepositDetails> .Create(new[] { detailsOfOne }, 1, 1, 1, 1); } if (deposits.Items.Count == 0) { return(DepositsReport.Empty); } if (!deposits.Items.Any() || deposits.Items.Any(d => d is null)) { return(DepositsReport.Empty); } Dictionary <Keccak, DepositDetails> foundDeposits = deposits.Items .Where(d => (query.Provider is null || d.DataAsset.Provider.Address == query.Provider) && (query.AssetId is null || d.DataAsset.Id == query.AssetId)) .ToDictionary(d => d.Id, d => d); if (!foundDeposits.Any()) { return(DepositsReport.Empty); } IEnumerable <Keccak> assetIds = foundDeposits.Select(d => d.Value.DataAsset.Id); IReadOnlyList <DataDeliveryReceiptDetails> receipts = await _receiptRepository.BrowseAsync(query.DepositId, query.AssetId); Dictionary <Keccak, IEnumerable <DataDeliveryReceiptDetails> > depositsReceipts = receipts.Where(r => assetIds.Contains(r.DataAssetId)) .GroupBy(r => r.DepositId).ToDictionary(r => r.Key, r => r.AsEnumerable()); int page = query.Page; if (page <= 0) { page = 1; } int results = query.Results; if (results <= 0) { results = 10; } uint timestamp = (uint)_timestamper.EpochSeconds; int skip = (page - 1) * results; List <DepositReportItem> items = new List <DepositReportItem>(); foreach ((Keccak _, DepositDetails deposit) in foundDeposits.OrderByDescending(d => d.Value.Timestamp).Skip(skip) .Take(results)) { depositsReceipts.TryGetValue(deposit.Id, out IEnumerable <DataDeliveryReceiptDetails>?depositReceipts); bool expired = deposit.IsExpired(timestamp); IEnumerable <DataDeliveryReceiptReportItem>?receiptItems = depositReceipts?.Select(r => new DataDeliveryReceiptReportItem(r.Id, r.Number, r.SessionId, r.ConsumerNodeId, r.Request, r.Receipt, r.Timestamp, r.IsMerged, r.IsClaimed)); PagedResult <ConsumerSession> sessions = await _sessionRepository.BrowseAsync(new GetConsumerSessions { DepositId = deposit.Id, Results = int.MaxValue }); uint consumedUnits = sessions.Items.Any() ? (uint)sessions.Items.Sum(s => s.ConsumedUnits) : 0; items.Add(ToReportItem(deposit, expired, consumedUnits, receiptItems ?? Enumerable.Empty <DataDeliveryReceiptReportItem>())); } (UInt256 total, UInt256 claimed, UInt256 refunded) = CalculateValues(foundDeposits, depositsReceipts); int totalResults = foundDeposits.Count; int totalPages = (int)Math.Ceiling((double)totalResults / query.Results); return(new DepositsReport(total, claimed, refunded, PagedResult <DepositReportItem> .Create(items.OrderByDescending(i => i.Timestamp).ToList(), query.Page, query.Results, totalPages, totalResults))); }
public async Task <DepositsReport> GetAsync(GetDepositsReport query) { var deposits = query.DepositId is null ? await _depositRepository.BrowseAsync(new GetDeposits { Results = int.MaxValue }) : PagedResult <DepositDetails> .Create(new[] { await _depositRepository.GetAsync(query.DepositId) }, 1, 1, 1, 1); if (!deposits.Items.Any() || deposits.Items.Any(d => d is null)) { return(DepositsReport.Empty); } var foundDeposits = deposits.Items .Where(d => (query.Provider is null || d.DataAsset.Provider.Address == query.Provider) && (query.AssetId is null || d.DataAsset.Id == query.AssetId)) .ToDictionary(d => d.Id, d => d); if (!foundDeposits.Any()) { return(DepositsReport.Empty); } var assetIds = foundDeposits.Select(d => d.Value.DataAsset.Id); var receipts = await _receiptRepository.BrowseAsync(query.DepositId, query.AssetId); var depositsReceipts = receipts.Where(r => assetIds.Contains(r.DataAssetId)) .GroupBy(r => r.DepositId).ToDictionary(r => r.Key, r => r.AsEnumerable()); var page = query.Page; if (page <= 0) { page = 1; } var results = query.Results; if (results <= 0) { results = 10; } var timestamp = (uint)_timestamper.EpochSeconds; var skip = (page - 1) * results; var items = new List <DepositReportItem>(); foreach (var(_, deposit) in foundDeposits.OrderByDescending(d => d.Value.Timestamp).Skip(skip) .Take(results)) { depositsReceipts.TryGetValue(deposit.Id, out var depositReceipts); var expired = deposit.IsExpired(timestamp); var receiptItems = depositReceipts?.Select(r => new DataDeliveryReceiptReportItem(r.Id, r.Number, r.SessionId, r.ConsumerNodeId, r.Request, r.Receipt, r.Timestamp, r.IsMerged, r.IsClaimed)); var sessions = await _sessionRepository.BrowseAsync(new GetConsumerSessions { DepositId = deposit.Id, Results = int.MaxValue }); var consumedUnits = sessions.Items.Any() ? (uint)sessions.Items.Sum(s => s.ConsumedUnits) : 0; items.Add(new DepositReportItem(deposit.Id, deposit.DataAsset.Id, deposit.DataAsset.Name, deposit.DataAsset.Provider.Address, deposit.DataAsset.Provider.Name, deposit.Deposit.Value, deposit.Deposit.Units, deposit.Consumer, deposit.Timestamp, deposit.Deposit.ExpiryTime, expired, deposit.Transaction?.Hash, deposit.ConfirmationTimestamp, deposit.Confirmations, deposit.RequiredConfirmations, deposit.Confirmed, deposit.Rejected, deposit.ClaimedRefundTransaction?.Hash, deposit.RefundClaimed, consumedUnits, receiptItems)); } var(total, claimed, refunded) = CalculateValues(foundDeposits, depositsReceipts); var totalResults = foundDeposits.Count; var totalPages = (int)Math.Ceiling((double)totalResults / query.Results); return(new DepositsReport(total, claimed, refunded, PagedResult <DepositReportItem> .Create(items.OrderByDescending(i => i.Timestamp).ToList(), query.Page, query.Results, totalPages, totalResults))); }
public async Task <IDepositNodesHandler> InitAsync(Keccak depositId, uint unpaidSessionUnits = 0) { if (_logger.IsInfo) { _logger.Info($"Initializing deposit: '{depositId}'."); } Consumer?consumer = await _consumerRepository.GetAsync(depositId); if (consumer is null) { if (_logger.IsInfo) { _logger.Info($"Consumer has not been found for deposit: '{depositId}'."); } return(null); } if (_depositNodesHandlers.TryGetValue(depositId, out IDepositNodesHandler? deposit)) { deposit.AddUnpaidUnits(unpaidSessionUnits); deposit.AddUnmergedUnits(unpaidSessionUnits); deposit.AddUnclaimedUnits(unpaidSessionUnits); if (_logger.IsInfo) { _logger.Info($"Updated deposit: '{depositId}'."); } if (_logger.IsInfo) { _logger.Info($"Deposit: '{depositId}' has {deposit.UnpaidUnits} unpaid units, unmerged: {deposit.UnmergedUnits}, unclaimed: {deposit.UnclaimedUnits}, grace: {deposit.GraceUnits}."); } return(deposit); } else { uint purchasedUnits = consumer.DataRequest.Units; UInt256 unitPrice = consumer.DataAsset.UnitPrice; var sessions = await _sessionRepository.BrowseAsync(new GetProviderSessions { DepositId = depositId, Results = int.MaxValue }); var depositReceipts = await _receiptRepository.BrowseAsync(depositId); var receipts = depositReceipts.OrderBy(r => r.Timestamp) .ThenBy(r => r.Request.UnitsRange.To) .ThenByDescending(r => r.Request.UnitsRange.From) .ToArray(); uint consumedUnits = (uint)sessions.Items.Sum(s => s.ConsumedUnits); uint graceUnits = (uint)sessions.Items.Sum(s => s.GraceUnits); uint unpaidUnits = (uint)(sessions.Items.Sum(s => s.UnpaidUnits) - sessions.Items.Sum(s => s.SettledUnits)); ulong latestMergedReceiptTimestamp = receipts.LastOrDefault(r => r.IsMerged)?.Timestamp ?? 0; uint unmergedUnits = (uint)receipts.Where(r => !r.IsClaimed && !r.IsMerged && r.Timestamp >= latestMergedReceiptTimestamp) .Sum(r => r.Request.UnitsRange.To - r.Request.UnitsRange.From + 1); ulong latestClaimedReceiptTimestamp = receipts.LastOrDefault(r => r.IsClaimed)?.Timestamp ?? 0; uint unclaimedUnits = (uint)receipts.Where(r => !r.IsClaimed && !r.IsMerged && r.Timestamp >= latestClaimedReceiptTimestamp) .Sum(r => r.Request.UnitsRange.To - r.Request.UnitsRange.From + 1); var latestReceipts = receipts.Where(r => r.Timestamp >= latestClaimedReceiptTimestamp); uint latestReceiptRequestNumber = receipts.Any() ? receipts.Max(r => r.Number) : 0; var paymentClaimsResult = await _paymentClaimRepository.BrowseAsync(new GetPaymentClaims { DepositId = depositId, Page = 1, Results = int.MaxValue }); PaymentClaim latestPaymentClaim = paymentClaimsResult.Items.OrderBy(c => c.Timestamp) .ThenBy(c => c.UnitsRange.To).LastOrDefault(); deposit = _depositNodesHandlerFactory.CreateInMemory(depositId, consumer.DataRequest.Consumer, consumer.DataAsset.UnitType, consumer.VerificationTimestamp, purchasedUnits, unitPrice, consumedUnits, unpaidUnits, unmergedUnits, unclaimedUnits, graceUnits, consumer.DataRequest.ExpiryTime, latestPaymentClaim, latestReceipts, latestReceiptRequestNumber); _depositNodesHandlers.TryAdd(depositId, deposit); if (_logger.IsInfo) { _logger.Info($"Initialized deposit: '{depositId}'."); } if (_logger.IsInfo) { _logger.Info($"Deposit: '{depositId}' has {deposit.UnpaidUnits} unpaid units, unmerged: {deposit.UnmergedUnits}, unclaimed: {deposit.UnclaimedUnits}, grace: {deposit.GraceUnits}."); } return(deposit); } }