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);
 }
Beispiel #4
0
 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);
 }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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
            });
        }
Beispiel #10
0
        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));
        }
Beispiel #11
0
        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());
        }