public async Task <ReadOnlyCollection <FundingSourcePaymentEvent> > ProcessReceiverTransferPayment(ProcessUnableToFundTransferFundingSourcePayment message) { if (!message.AccountId.HasValue) { throw new InvalidOperationException($"Invalid ProcessUnableToFundTransferFundingSourcePayment event. No account id populated on message. Event id: {message.EventId}"); } paymentLogger.LogDebug($"Converting the unable to fund transfer payment to a levy payment. Event id: {message.EventId}, account id: {message.AccountId}, job id: {message.JobId}"); var requiredPayment = mapper.Map <CalculatedRequiredLevyAmount>(message); paymentLogger.LogVerbose("Mapped ProcessUnableToFundTransferFundingSourcePayment to CalculatedRequiredLevyAmount"); var payments = new List <FundingSourcePaymentEvent>(); var monthEndStartedCacheItem = await monthEndCache.TryGet(CacheKeys.MonthEndCacheKey); if (!monthEndStartedCacheItem.HasValue || !monthEndStartedCacheItem.Value) { paymentLogger.LogDebug("Month end has not been started yet so adding the payment to the cache."); await AddRequiredPayment(requiredPayment); } else { var levyAccountCacheItem = await levyAccountCache.TryGet(CacheKeys.LevyBalanceKey, CancellationToken.None) .ConfigureAwait(false); if (!levyAccountCacheItem.HasValue) { throw new InvalidOperationException($"The last levy account balance has not been stored in the reliable for account: {message.AccountId}"); } levyBalanceService.Initialise(levyAccountCacheItem.Value.Balance, levyAccountCacheItem.Value.TransferAllowance); paymentLogger.LogDebug("Service has finished month end processing so now generating the payments for the ProcessUnableToFundTransferFundingSourcePayment event."); payments.AddRange(CreateFundingSourcePaymentsForRequiredPayment(requiredPayment, message.AccountId.Value, message.JobId)); var remainingBalance = mapper.Map <LevyAccountModel>(levyAccountCacheItem.Value); remainingBalance.Balance = levyBalanceService.RemainingBalance; remainingBalance.TransferAllowance = levyBalanceService.RemainingTransferAllowance; await levyAccountCache.AddOrReplace(CacheKeys.LevyBalanceKey, remainingBalance); } paymentLogger.LogInfo($"Finished processing the ProcessUnableToFundTransferFundingSourcePayment. Event id: {message.EventId}, account id: {message.AccountId}, job id: {message.JobId}"); return(payments.AsReadOnly()); }
public async Task <ReadOnlyCollection <FundingSourcePaymentEvent> > HandleMonthEnd(long employerAccountId, long jobId, CollectionPeriod collectionPeriod) { var levyAccount = await levyFundingSourceRepository.GetLevyAccount(employerAccountId); levyBalanceService.Initialise(levyAccount.Balance, levyAccount.TransferAllowance); var orderedRequiredLevyPayments = await GetOrderedCalculatedRequiredLevyAmounts(employerAccountId, collectionPeriod).ConfigureAwait(false); logger.LogDebug($"Processing {orderedRequiredLevyPayments.Count} required payments, levy balance {levyAccount.Balance}, account {employerAccountId}, job id {jobId}"); var fundingSourceEvents = new List <FundingSourcePaymentEvent>(); fundingSourceEvents.AddRange(orderedRequiredLevyPayments.SelectMany(payment => fundingSourcePaymentEventBuilder.BuildFundingSourcePaymentsForRequiredPayment(payment, employerAccountId, jobId))); logger.LogDebug($"Created {fundingSourceEvents.Count} payments - {GetFundsDebugString(fundingSourceEvents)}, account {employerAccountId}, job id {jobId}"); levyAccount.Balance = levyBalanceService.RemainingBalance; levyAccount.TransferAllowance = levyBalanceService.RemainingTransferAllowance; await levyAccountCache.AddOrReplace(CacheKeys.LevyBalanceKey, levyAccount); logger.LogInfo($"Finished generating levy and/or co-invested payments for the account: {employerAccountId}, number of payments: {fundingSourceEvents.Count}."); return(fundingSourceEvents.AsReadOnly()); }