public async Task ExecuteAsync(UserId subscriberId, DateTime endTimeExclusive, IKeepAliveHandler keepAliveHandler, List <PaymentProcessingException> errors) { keepAliveHandler.AssertNotNull("keepAliveHandler"); subscriberId.AssertNotNull("subscriberId"); errors.AssertNotNull("errors"); var creators = await this.getCreatorsAndFirstSubscribedDates.ExecuteAsync(subscriberId); var committedAccountBalanceValue = await this.getCommittedAccountBalanceDbStatement.ExecuteAsync(subscriberId); if (committedAccountBalanceValue < 0) { errors.Add(new PaymentProcessingException(string.Format("Committed account balance was {0} for user {1}.", committedAccountBalanceValue, subscriberId), subscriberId, null)); committedAccountBalanceValue = 0m; } var committedAccountBalance = new CommittedAccountBalance(committedAccountBalanceValue); foreach (var creator in creators) { try { await keepAliveHandler.KeepAliveAsync(); var latestCommittedLedgerDate = await this.getLatestCommittedLedgerDate.ExecuteAsync(subscriberId, creator.CreatorId); var startTimeInclusive = latestCommittedLedgerDate ?? PaymentProcessingUtilities.GetPaymentProcessingStartDate(creator.FirstSubscribedDate); if ((endTimeExclusive - startTimeInclusive) <= MinimumProcessingPeriod) { continue; } committedAccountBalance = await this.processPaymentsBetweenSubscriberAndCreator.ExecuteAsync( subscriberId, creator.CreatorId, startTimeInclusive, endTimeExclusive, committedAccountBalance); } catch (Exception t) { errors.Add(new PaymentProcessingException(t, subscriberId, creator.CreatorId)); } } }
public Task<PaymentProcessingResults> ExecuteAsync(PaymentProcessingData data) { using (PaymentsPerformanceLogger.Instance.Log(typeof(ProcessPaymentProcessingData))) { data.AssertNotNull("data"); var subscriberId = data.SubscriberId; var creatorId = data.CreatorId; DateTime startTimeInclusive = data.StartTimeInclusive; DateTime endTimeExclusive = data.EndTimeExclusive; IReadOnlyList<ISnapshot> orderedSnapshots = data.GetOrderedSnapshots(); IReadOnlyList<CreatorPost> posts = data.CreatorPosts; var committedAccountBalance = data.CommittedAccountBalance; var currentStartTimeInclusive = startTimeInclusive; var currentEndTimeExclusive = startTimeInclusive.AddDays(7); // This is the final time at which we can be totally sure if the creator // has posted in the billing week, as the subscriber billing week most likely // doesn't line up with the payment billing week. var committedRecordsEndTimeExclusive = endTimeExclusive.AddDays(-7); var result = new List<PaymentProcessingResult>(); while (currentEndTimeExclusive <= committedRecordsEndTimeExclusive) { // Calculate complete week. var cost = this.subscriberPaymentPipeline.CalculatePayment( orderedSnapshots, posts, subscriberId, creatorId, currentStartTimeInclusive, currentEndTimeExclusive); if (cost.Cost > committedAccountBalance.Amount) { cost = new AggregateCostSummary(committedAccountBalance.Amount); } committedAccountBalance = committedAccountBalance.Subtract(cost.Cost); var creatorPercentageOverride = PaymentProcessingUtilities.GetCreatorPercentageOverride( data.CreatorPercentageOverride, currentEndTimeExclusive); result.Add(new PaymentProcessingResult(currentStartTimeInclusive, currentEndTimeExclusive, cost, creatorPercentageOverride, true)); currentStartTimeInclusive = currentEndTimeExclusive; currentEndTimeExclusive = currentStartTimeInclusive.AddDays(7); } if (currentStartTimeInclusive < endTimeExclusive) { // Calculate uncommitted period. // We calculate without taking into account CreatorPosts, // as we assume they will post until we can be totally sure // know otherwise. var cost = this.subscriberPaymentPipeline.CalculatePayment( orderedSnapshots, null, subscriberId, creatorId, currentStartTimeInclusive, endTimeExclusive); var creatorPercentageOverride = PaymentProcessingUtilities.GetCreatorPercentageOverride( data.CreatorPercentageOverride, endTimeExclusive); result.Add(new PaymentProcessingResult(currentStartTimeInclusive, endTimeExclusive, cost, creatorPercentageOverride, false)); } return Task.FromResult(new PaymentProcessingResults(committedAccountBalance, result)); } }