public async Task Save(Guid notificationId, DateTime date, decimal amount, string comments) { if (date > SystemTime.UtcNow.Date) { throw new InvalidOperationException( string.Format("Refund date cannot be in the future for notification {0}", notificationId)); } var totalPaid = await transactionCalculator.TotalPaid(notificationId); if (amount > totalPaid) { throw new InvalidOperationException( string.Format("Refund amount cannot exceed total amount paid for notification {0}", notificationId)); } var firstPayment = (await transactionRepository.GetTransactions(notificationId)) .OrderBy(x => x.Date) .FirstOrDefault(x => x.Credit != null); if (firstPayment == null) { throw new InvalidOperationException( string.Format("Can't make a refund for notification {0} when no payments have been made", notificationId)); } if (date < firstPayment.Date) { throw new InvalidOperationException( string.Format("Refund date cannot be before the first payment date for notification {0}", notificationId)); } var transaction = ImportNotificationTransaction.RefundRecord(notificationId, date, amount, comments); var balance = await transactionCalculator.Balance(transaction.NotificationId) - transaction.Credit.GetValueOrDefault() + transaction.Debit.GetValueOrDefault(); var transactions = (await transactionRepository.GetTransactions(transaction.NotificationId)).ToList(); transactions.Add(transaction); var paymentDate = CalculatePaymentReceivedDate(transactions, balance); await UpdatePaymentReceivedDate(paymentDate, notificationId); transactionRepository.Add(transaction); }
public async Task Save_PaymentFullyReceived_SetsReceivedDate() { var transactionDate = new DateTime(2018, 1, 1); A.CallTo(() => importNotificationTransactionCalculator.Balance(notificationId)) .Returns(1000); A.CallTo(() => importNotificationTransactionRepository.GetTransactions(notificationId)) .Returns(new List <ImportNotificationTransaction>() { CreateNotificationTransaction(1000, transactionDate) }); await transaction.Save(notificationId, transactionDate, 1000, PaymentMethod.Card, null, null); Assert.Equal(assessment.Dates.PaymentReceivedDate, transactionDate); }
public ImportNotificationTransactionCalculatorTests() { chargeCalculator = A.Fake<IImportNotificationChargeCalculator>(); repository = A.Fake<IImportNotificationTransactionRepository>(); transactionCalculator = new ImportNotificationTransactionCalculator(repository, chargeCalculator); A.CallTo(() => repository.GetTransactions(A<Guid>.Ignored)).Returns(transactions); A.CallTo(() => chargeCalculator.GetValue(A<Guid>.Ignored)).Returns(TotalCredits); }
public ImportNotificationTransactionCalculatorTests() { chargeCalculator = A.Fake <IImportNotificationChargeCalculator>(); repository = A.Fake <IImportNotificationTransactionRepository>(); transactionCalculator = new ImportNotificationTransactionCalculator(repository, chargeCalculator); A.CallTo(() => repository.GetTransactions(A <Guid> .Ignored)).Returns(transactions); A.CallTo(() => chargeCalculator.GetValue(A <Guid> .Ignored)).Returns(TotalCredits); }
public async Task CantRefundWhenNoPaymentsMade() { A.CallTo(() => transactionRepository.GetTransactions(notificationId)) .Returns(new ImportNotificationTransaction[] { }); Func <Task> testCode = () => refundTransaction.Save(notificationId, new DateTime(2015, 12, 2), 99, "comment"); await Assert.ThrowsAsync <InvalidOperationException>(testCode); }
public async Task Save(Guid notificationId, DateTime date, decimal amount, PaymentMethod paymentMethod, string receiptNumber, string comments) { var transaction = ImportNotificationTransaction.PaymentRecord(notificationId, date, amount, paymentMethod, receiptNumber, comments); var balance = await transactionCalculator.Balance(transaction.NotificationId) - transaction.Credit.GetValueOrDefault() + transaction.Debit.GetValueOrDefault(); var transactions = (await transactionRepository.GetTransactions(transaction.NotificationId)).ToList(); transactions.Add(transaction); var paymentDate = CalculatePaymentReceivedDate(transactions, balance); await UpdatePaymentReceivedDate(paymentDate, notificationId); transactionRepository.Add(transaction); }
public async Task HandleAsync(ImportNotificationSubmittedEvent @event) { var isFullyPaid = await transactionCalculator.PaymentIsNowFullyReceived(@event.Assessment.NotificationApplicationId, 0); if (isFullyPaid && @event.Assessment.Status == ImportNotificationStatus.AwaitingPayment) { var transactions = await transactionRepository.GetTransactions(@event.Assessment.NotificationApplicationId); @event.Assessment.PaymentComplete(transactions.OrderBy(t => t.Date).Select(t => t.Date).Last()); } await context.SaveChangesAsync(); }
public ImportRefundTransactionTests() { transactionRepository = A.Fake<IImportNotificationTransactionRepository>(); transactionCalculator = A.Fake<IImportNotificationTransactionCalculator>(); refundTransaction = new ImportRefundTransaction(transactionRepository, transactionCalculator); notificationId = new Guid("DB476D01-2870-4322-8284-520B34D9667B"); A.CallTo(() => transactionCalculator.TotalPaid(notificationId)).Returns(100); A.CallTo(() => transactionRepository.GetTransactions(notificationId)) .Returns(new[] { ImportNotificationTransaction.PaymentRecord(notificationId, new DateTime(2015, 12, 1), 100, PaymentMethod.Cheque, "12345", "comments"), }); SystemTime.Freeze(new DateTime(2016, 1, 1)); }
public async Task <AccountOverviewData> HandleAsync(GetImportNotificationAccountOverview message) { var assessment = await notificationAssessmentRepository.GetByNotification(message.ImportNotificationId); var charge = await chargeCalculator.GetValue(message.ImportNotificationId); var transactions = await transactionRepository.GetTransactions(message.ImportNotificationId); var totalPaid = await transactionCalculator.TotalPaid(message.ImportNotificationId); return(new AccountOverviewData { TotalCharge = charge, TotalPaid = totalPaid, Transactions = transactions.Select(t => mapper.Map <TransactionRecordData>(t)).ToArray(), PaymentReceived = assessment.Dates.PaymentReceivedDate }); }
public ImportRefundTransactionTests() { transactionRepository = A.Fake <IImportNotificationTransactionRepository>(); transactionCalculator = A.Fake <IImportNotificationTransactionCalculator>(); assessmentRepository = A.Fake <IImportNotificationAssessmentRepository>(); refundTransaction = new ImportRefundTransaction(transactionRepository, transactionCalculator, assessmentRepository); notificationId = new Guid("DB476D01-2870-4322-8284-520B34D9667B"); A.CallTo(() => transactionCalculator.TotalPaid(notificationId)).Returns(100); A.CallTo(() => transactionRepository.GetTransactions(notificationId)) .Returns(new[] { ImportNotificationTransaction.PaymentRecord(notificationId, new DateTime(2015, 12, 1), 100, PaymentMethod.Cheque, "12345", "comments"), }); var assessment = new ImportNotificationAssessment(notificationId); A.CallTo(() => assessmentRepository.GetByNotification(notificationId)) .Returns(assessment); SystemTime.Freeze(new DateTime(2016, 1, 1)); }
public async Task <decimal> TotalPaid(Guid importNotificationId) { var transactions = (await transactionRepository.GetTransactions(importNotificationId)).ToArray(); return(TotalCredits(transactions) - TotalDebits(transactions)); }
public async Task <IList <TransactionRecordData> > HandleAsync(GetImportNotificationTransactions message) { var transactions = await repository.GetTransactions(message.NotificationId); return(transactions.Select(t => mapper.Map <TransactionRecordData>(t)).ToList()); }