public void TestDonationTotalReturnsExpectedResult()
        {
            #region Arrange
            var transaction = GetValid(9);
            transaction.Amount = 3m;
            var donationTransaction = new Transaction(transaction.Item);
            donationTransaction.Donation = true;
            donationTransaction.Amount = 10.00m;
            var donationTransaction2 = new Transaction(transaction.Item);
            donationTransaction2.Donation = true;
            donationTransaction2.Amount = 15.00m;
            var donationTransaction3 = new Transaction(transaction.Item);
            donationTransaction3.Donation = false;
            donationTransaction3.Amount = 11.00m;
            transaction.AddChildTransaction(donationTransaction);
            transaction.AddChildTransaction(donationTransaction2);
            transaction.AddChildTransaction(donationTransaction3);
            #endregion Arrange

            #region Act
            var result = transaction.DonationTotal;
            #endregion Act

            #region Assert
            Assert.AreEqual(25, result);
            #endregion Assert
        }
        public void TestChildTransactionsAreCascadedWithSave()
        {
            #region Arrange
            var transaction = GetValid(9);
            transaction.Amount = 5m;
            var donationTransaction = new Transaction(transaction.Item);
            donationTransaction.Donation = true;
            donationTransaction.Amount = 10.00m;
            var donationTransaction2 = new Transaction(transaction.Item);
            donationTransaction2.Donation = true;
            donationTransaction2.Amount = 15.00m;
            transaction.AddChildTransaction(donationTransaction);
            transaction.AddChildTransaction(donationTransaction2);
            Assert.AreEqual(5, TransactionRepository.GetAll().Count);
            #endregion Arrange

            #region Act
            TransactionRepository.DbContext.BeginTransaction();
            TransactionRepository.EnsurePersistent(transaction);
            TransactionRepository.DbContext.CommitTransaction();
            #endregion Act

            #region Assert
            Assert.AreEqual(25.0m, TransactionRepository.GetAll().Where(a => a.ParentTransaction == transaction).Sum(s => s.Amount));
            Assert.AreEqual(8, TransactionRepository.GetAll().Count);
            Assert.IsFalse(transaction.IsTransient());
            Assert.IsTrue(transaction.IsValid());
            #endregion Assert
        }
        public void TestCorrectionAmountSaves()
        {
            #region Arrange
            var transaction = GetValid(9);
            transaction.Amount = 1m;
            var donationTransaction = new Transaction(transaction.Item);
            donationTransaction.Donation = true;
            donationTransaction.Amount = 10.00m;
            var donationTransaction2 = new Transaction(transaction.Item);
            donationTransaction2.Donation = true;
            donationTransaction2.Amount = 15.00m;
            transaction.AddChildTransaction(donationTransaction);
            transaction.AddChildTransaction(donationTransaction2);

            var correction = new Transaction(transaction.Item);
            correction.Donation = false;
            correction.Amount = -15.00m;
            correction.CreatedBy = "Test";
            transaction.AddChildTransaction(correction);
            #endregion Arrange

            #region Act
            TransactionRepository.DbContext.BeginTransaction();
            TransactionRepository.EnsurePersistent(transaction);
            TransactionRepository.DbContext.CommitTransaction();
            #endregion Act

            #region Assert
            Assert.AreEqual(3, TransactionRepository.GetAll().Where(a => a.ParentTransaction == transaction).Count());
            Assert.IsFalse(transaction.IsTransient());
            Assert.IsTrue(transaction.IsValid());
            Assert.AreEqual(-15m, transaction.CorrectionTotal);
            Assert.AreEqual(11m, transaction.Total);
            #endregion Assert
        }
Example #4
0
        /// <summary>
        /// Create a new quantity answer.
        /// </summary>
        /// <param name="transaction"></param>
        /// <param name="questionSet"></param>
        /// <param name="question"></param>
        /// <param name="answer"></param>
        /// <param name="quantityId">Leave null if creating a new quantity sequence</param>
        public QuantityAnswer(Transaction transaction, QuestionSet questionSet, Question question, string answer, Guid? quantityId)
        {
            Transaction = transaction;
            QuestionSet = questionSet;
            Question = question;
            Answer = answer;

            QuantityId = quantityId ?? Guid.NewGuid();
            QuantityIdNotEmpty = false;
        }
Example #5
0
 public virtual void AddChildTransaction(Transaction transaction)
 {
     transaction.ParentTransaction = this;
     transaction.Check = Check;
     transaction.Credit = Credit;
     ChildTransactions.Add(transaction);
 }
        public void TestChildTransactionsWithValidValueSaves()
        {
            #region Arrange
            var transaction = GetValid(9);
            var donationTransaction = new Transaction(transaction.Item);
            donationTransaction.Donation = true;
            donationTransaction.Amount = 10.00m;
            transaction.AddChildTransaction(donationTransaction);
            #endregion Arrange

            #region Act
            TransactionRepository.DbContext.BeginTransaction();
            TransactionRepository.EnsurePersistent(transaction);
            TransactionRepository.DbContext.CommitTransaction();
            #endregion Act

            #region Assert
            Assert.AreEqual(1, TransactionRepository.GetAll().Where(a => a.ParentTransaction == transaction).Count());
            Assert.IsFalse(transaction.IsTransient());
            Assert.IsTrue(transaction.IsValid());
            #endregion Assert
        }
Example #7
0
        /// <summary>
        /// Extract the requested value from the transaction answers
        /// </summary>
        /// <param name="itemReportColumn"></param>
        /// <param name="transaction"></param>
        /// <param name="quantityId"></param>
        /// <returns></returns>
        private static string ExtractValue(ItemReportColumn itemReportColumn, Transaction transaction, Guid? quantityId)
        {
            var result = string.Empty;

            if (itemReportColumn.Transaction)
            {
                var transactionAnswer = transaction.TransactionAnswers.Where(a => a.Question.Name == itemReportColumn.Name && a.QuestionSet == itemReportColumn.QuestionSet).FirstOrDefault();

                if (transactionAnswer != null)
                {
                    result = transactionAnswer.Answer;
                }
            }
            else if (itemReportColumn.Quantity)
            {
                var quantityAnswer = transaction.QuantityAnswers.Where(a => a.QuantityId == quantityId.Value && a.Question.Name == itemReportColumn.Name && a.QuestionSet == itemReportColumn.QuestionSet).FirstOrDefault();

                if (quantityAnswer != null)
                {
                    result = quantityAnswer.Answer;
                }
            }
            else if (itemReportColumn.Property)
            {
                if (itemReportColumn.Name == StaticValues.Report_DonationTotal)
                {
                    result = transaction.DonationTotal.ToString("C");
                }
                else if (itemReportColumn.Name == StaticValues.Report_TransactionNumber)
                {
                    result = transaction.TransactionNumber;
                }
                else if (itemReportColumn.Name == StaticValues.Report_TransactionDate)
                {
                    result = transaction.TransactionDate.ToString();
                }
                else if (itemReportColumn.Name == StaticValues.Report_Active)
                {
                    result = transaction.IsActive.ToString();
                }
                else if(itemReportColumn.Name == StaticValues.Report_AmountTotal)
                {
                    result = transaction.AmountTotal.ToString("C");
                }
                else if (itemReportColumn.Name == StaticValues.Report_Total)
                {
                    result = transaction.Total.ToString("C");
                }
                else if (itemReportColumn.Name == StaticValues.Report_PaymentType)
                {
                    result = transaction.Credit ? "Credit Card" : "Check";
                }
                else if (itemReportColumn.Name == StaticValues.Report_Quantity)
                {
                    result = transaction.Quantity.ToString();
                }
                else if (itemReportColumn.Name == StaticValues.Report_Paid)
                {
                    result = transaction.Paid.ToString();
                }
                else if (itemReportColumn.Name == StaticValues.Report_TotalPaid)
                {
                    result = transaction.TotalPaid.ToString("C");
                }
                else if (itemReportColumn.Name == StaticValues.Report_RefundIssued)
                {
                    result = transaction.RefundIssued.ToString();
                }
                else if (itemReportColumn.Name == StaticValues.Report_RefundAmount)
                {
                    result = transaction.RefundAmount.ToString("C");
                }
                else if (itemReportColumn.Name == StaticValues.Report_Notified)
                {
                    result = transaction.Notified.ToString();
                }
                else if (itemReportColumn.Name == StaticValues.Report_NotifiedDate)
                {
                    result = transaction.NotifiedDate == null ? string.Empty : transaction.NotifiedDate.ToString();
                }
                else if (itemReportColumn.Name == StaticValues.Report_TransactionGuid)
                {
                    if (transaction.Credit) result = string.Format("{0} FID={1}", transaction.TransactionGuid, transaction.FidUsed ?? transaction.Item.TouchnetFID);
                    else result = "n/a";
                }
            }

            if (result != null && itemReportColumn.Format == StaticValues.FormatCapitalize)
            {
                result = UCDArch.Core.Utils.Inflector.Capitalize(result);
            }
            return result;
        }
Example #8
0
        /// <summary>
        /// Sends the confirmation.
        /// </summary>
        /// <param name="repository">The repository.</param>
        /// <param name="transaction">The transaction.</param>
        /// <param name="emailAddress">The email address.</param>
        public void SendConfirmation(IRepository repository, Transaction transaction, string emailAddress)
        {
            Check.Require(transaction != null, "Transaction is required.");
            Check.Require(!string.IsNullOrEmpty(emailAddress), "Email address is required.");

            var body = string.Empty;

            if(transaction.Item != null && transaction.Item.Template != null)
            {
                body = transaction.Item.Template.Text;
            }
            else
            {
                body = repository.OfType<Template>().Queryable.Where(a => a.Default).FirstOrDefault().Text ?? string.Empty;
            }

            if (body.Contains(StaticValues.ConfirmationTemplateDelimiter))
            {
                var delimiter = new string[] { StaticValues.ConfirmationTemplateDelimiter };
                var parse = body.Split(delimiter, StringSplitOptions.None);
                //if(transaction.Paid && transaction.TotalPaid > 0)
                if (transaction.TotalPaid > 0)
                {
                    body = parse[0];
                }
                else
                {
                    body = parse[1];
                }
            }
            string extraSubject;
            if(transaction.TotalPaid > 0)
            {
                if (transaction.Paid)
                {
                    extraSubject = "Payment confirmed";
                }
                else
                {
                    extraSubject = "Payment pending";
                }
            }
            else
            {
                extraSubject = "Order confirmed";
            }

            var subject = extraSubject;
            if (transaction.Item != null && transaction.Item.Name != null)
            {
                subject = transaction.Item.Name.Trim() + ": " + extraSubject;
            }
            //Things to replace in the body:
            //Contact Info:
            //  First Name
            //  Last Name
            //TotalPaid
            //Quantity
            //QuantityName

            var firstName = transaction.TransactionAnswers.Where(a => a.QuestionSet.Name == StaticValues.QuestionSet_ContactInformation && a.Question.Name == StaticValues.Question_FirstName).FirstOrDefault().Answer ??
                            string.Empty;
            var lastName = transaction.TransactionAnswers.Where(a => a.QuestionSet.Name == StaticValues.QuestionSet_ContactInformation && a.Question.Name == StaticValues.Question_LastName).FirstOrDefault().Answer ??
                            string.Empty;
            var totalPaid = transaction.TotalPaid.ToString("C");
            var quantity = transaction.Quantity.ToString();
            var quantityName = string.Empty;
            if (transaction.Item != null)
            {
                quantityName = transaction.Item.QuantityName ?? string.Empty;
            }

            var paymentLog = transaction.PaymentLogs.Where(a => a.Accepted).FirstOrDefault();
            var paymentMethod = string.Empty;
            if(paymentLog != null)
            {
                if(paymentLog.Check)
                {
                    paymentMethod = "Check";
                }
                if (paymentLog.Credit)
                {
                    paymentMethod = "Credit Card";
                }
            }
            var donationThanks = string.Empty;
            if (transaction.DonationTotal > 0 && transaction.Paid)
            {
                donationThanks = string.Format(ScreenText.STR_DonationText, transaction.DonationTotal.ToString("C"));
            }

            body = body.Replace("{FirstName}", firstName);
            body = body.Replace("{LastName}", lastName);
            body = body.Replace("{TotalPaid}", totalPaid);
            body = body.Replace("{Quantity}", quantity);
            body = body.Replace("{QuantityName}", quantityName);
            body = body.Replace("{TransactionNumber}", transaction.TransactionNumber);
            body = body.Replace("{PaymentMethod}", paymentMethod);
            body = body.Replace("{DonationThanks}", donationThanks);
            /*
            Thank you {FirstName} {LastName} for your payment of {TotalPaid}.
            {DonationThanks}
            Your payment by {PaymentMethod} has been accepted.
            You have purchased {Quantity} {QuantityName}.
            Your Transaction number is: {TransactionNumber}
             */

            //MailMessage message = new MailMessage("*****@*****.**", emailAddress,
            //                                     "payment confirmed",
            //                                     "your payment of " + transaction.TotalPaid.ToString("C") +
            //                                     " has been accepted.");

            MailMessage message = new MailMessage("*****@*****.**", emailAddress,
                                                  subject,
                                                  body);
            message.IsBodyHtml = true;

            try
            {
                _emailService.SendEmail(message);
                transaction.Notified = true;
                transaction.NotifiedDate = SystemTime.Now();
                repository.OfType<Transaction>().EnsurePersistent(transaction);
            }
            catch (Exception)
            {

            }
        }
Example #9
0
        public void SendRefundNotification(User user, Transaction refundTransaction, bool canceled)
        {
            var email = CloudConfigurationManager.GetSetting("EmailForRefunds");
            if(string.IsNullOrWhiteSpace(email))
            {
                email = "*****@*****.**";
            }

            var message = new MailMessage("*****@*****.**", email) { IsBodyHtml = true };
            if(canceled)
            {
                message.Subject = "Registration Refund CANCELED";
            }
            else
            {
                message.Subject = "Registration Refund";
            }

            var fid = string.Empty;
            if (refundTransaction.ParentTransaction.FidUsed != null)
            {
                fid = refundTransaction.ParentTransaction.FidUsed;
            }
            else
            {
                fid = refundTransaction.ParentTransaction.Item.TouchnetFID ?? string.Empty;
            }

            var body = new StringBuilder("Refund Information<br/><br/>");
            body.Append("<b>Refunder</b><br/>");
            body.Append(string.Format("  <b>{0} :</b> {1}<br/>", "Name", user.FullName));
            body.Append(string.Format("  <b>{0} :</b> {1}<br/>", "Email", user.Email));
            body.Append(string.Format("  <b>{0} :</b> {1}<br/>", "Kerb", user.LoginID));
            body.Append("<br/>");
            body.Append("<b>Details</b><br/>");
            body.Append(string.Format("  <b>{0} :</b> {1} FID={2}<br/>", "Touchnet Id", refundTransaction.ParentTransaction.TransactionGuid, fid));
            body.Append(string.Format("  <b>{0} :</b> ${1}<br/>", "Refund Amount", refundTransaction.Amount));
            body.Append(string.Format("  <b>{0} :</b> {1}<br/>", "Date", refundTransaction.TransactionDate));
            body.Append(string.Format("  <b>{0} :</b> {1}<br/>", "Event Name", refundTransaction.Item.Name));
            body.Append(string.Format("  <b>{0} :</b> {1}<br/>", "Event Id", refundTransaction.Item.Id));
            body.Append(string.Format("  <b>{0} :</b> {1}<br/>", "Transaction", refundTransaction.ParentTransaction.TransactionNumber));
            body.Append(string.Format("  <b>{0} :</b> {1}<br/>", "Reason For Refund", refundTransaction.CorrectionReason));

            try
            {
                var contactFirstName = refundTransaction.ParentTransaction.TransactionAnswers.FirstOrDefault(a => a.QuestionSet.Name == StaticValues.QuestionSet_ContactInformation &&
                                                                                                                  a.Question.Name == StaticValues.Question_FirstName).Answer;
                var contactLastName = refundTransaction.ParentTransaction.TransactionAnswers.FirstOrDefault(a => a.QuestionSet.Name == StaticValues.QuestionSet_ContactInformation &&
                                                                                                                 a.Question.Name == StaticValues.Question_LastName).Answer;
                var contactEmail = refundTransaction.ParentTransaction.TransactionAnswers.FirstOrDefault(a => a.QuestionSet.Name == StaticValues.QuestionSet_ContactInformation &&
                                                                                                              a.Question.Name == StaticValues.Question_Email).Answer;
                body.Append("<br/>");
                body.Append("<b>Billing Contact</b><br/>");
                body.Append(string.Format("  <b>{0} :</b> {1}<br/>", "First Name", contactFirstName));
                body.Append(string.Format("  <b>{0} :</b> {1}<br/>", "Last Name", contactLastName));
                body.Append(string.Format("  <b>{0} :</b> {1}<br/>", "Email", contactEmail));
            }
            catch(Exception ex)
            {

            }
            message.Body = body.ToString();

            _emailService.SendEmail(message);
        }
        public void TestUncorrectedDonationTotalWithNegativeDonationWillSumIt()
        {
            #region Arrange
            var transaction = GetValid(9);
            transaction.Amount = 3m;
            var donationTransaction = new Transaction(transaction.Item);
            donationTransaction.Donation = true;
            donationTransaction.Amount = 10.00m;
            var donationTransaction2 = new Transaction(transaction.Item);
            donationTransaction2.Donation = true;
            donationTransaction2.Amount = 15.00m;
            var donationTransaction3 = new Transaction(transaction.Item);
            donationTransaction3.Donation = true;
            donationTransaction3.Amount = 11.00m; //This one really should never happen
            donationTransaction3.CreatedBy = "test";
            transaction.AddChildTransaction(donationTransaction);
            transaction.AddChildTransaction(donationTransaction2);
            transaction.AddChildTransaction(donationTransaction3);
            #endregion Arrange

            #region Act
            var result = transaction.UncorrectedDonationTotal;
            #endregion Act

            #region Assert
            Assert.AreEqual(36, result);
            #endregion Assert
        }
        public void TestRemoveRefundInactivatesActiveRefundAndSaves()
        {
            #region Arrange
            Controller.ControllerContext.HttpContext.Response
                .Expect(a => a.ApplyAppPathModifier(null)).IgnoreArguments()
                .Return("http://sample.com/ItemManagement/Details/2").Repeat.Any();
            Controller.Url = MockRepository.GenerateStub<UrlHelper>(Controller.ControllerContext.RequestContext);
            Controller.ControllerContext.HttpContext = new MockHttpContext(1, new[] { RoleNames.Refunder, RoleNames.Admin });
            ControllerRecordFakes.FakeItems(Items, 2);
            ControllerRecordFakes.FakeUsers(Users, 3);
            ControllerRecordFakes.FakeEditors(Editors, 3);

            Users[0].LoginID = "UserName";
            for (int i = 0; i < 3; i++)
            {
                Editors[i].User = Users[i];
            }
            Items[0].AddEditor(Editors[1]);
            Items[0].AddEditor(Editors[2]);

            Items[1].AddEditor(Editors[0]);
            Items[1].AddEditor(Editors[1]);
            Items[1].AddEditor(Editors[2]);
            var transactions = new List<Transaction>(2);
            transactions.Add(CreateValidEntities.Transaction(1));
            transactions.Add(CreateValidEntities.Transaction(2));
            transactions[0].Item = Items[0];
            transactions[1].Item = Items[1];

            var refund = new Transaction(Items[0]);
            refund.Refunded = true;
            refund.Amount = 0.01m;
            refund.IsActive = true;
            transactions[0].AddChildTransaction(refund);

            ControllerRecordFakes.FakeTransaction(1, TransactionRepository, transactions);
            #endregion Arrange

            #region Act
            var result = Controller.RemoveRefund(1, "", "")
                .AssertHttpRedirect();
            #endregion Act

            #region Assert
            Assert.IsNull(Controller.Message);
            Assert.AreEqual("http://sample.com/ItemManagement/Details/2?Refunds-orderBy=&Refunds-page=1#Refunds", result.Url);
            TransactionRepository.AssertWasCalled(a => a.EnsurePersistent(Arg<Transaction>.Is.Anything));
            var args = (Transaction)TransactionRepository.GetArgumentsForCallsMadeOn(a => a.EnsurePersistent(Arg<Transaction>.Is.Anything))[0][0];
            Assert.IsNotNull(args);
            Assert.AreEqual(1, args.ChildTransactions.Count());
            Assert.IsFalse(args.RefundIssued);
            Assert.AreEqual(0m, args.RefundAmount);
            Assert.IsFalse(args.ChildTransactions.ElementAt(0).IsActive);
            #endregion Assert
        }
        public void TestRefundGetReturnsViewWhenNoActiveRefundExists()
        {
            #region Arrange
            Controller.ControllerContext.HttpContext.Response
                .Expect(a => a.ApplyAppPathModifier(null)).IgnoreArguments()
                .Return("http://sample.com/ItemManagement/Details/2").Repeat.Any();
            Controller.Url = MockRepository.GenerateStub<UrlHelper>(Controller.ControllerContext.RequestContext);
            Controller.ControllerContext.HttpContext = new MockHttpContext(1, new[] { RoleNames.Refunder, RoleNames.Admin });
            ControllerRecordFakes.FakeItems(Items, 2);
            ControllerRecordFakes.FakeUsers(Users, 3);
            ControllerRecordFakes.FakeEditors(Editors, 3);

            Users[0].LoginID = "UserName";
            for (int i = 0; i < 3; i++)
            {
                Editors[i].User = Users[i];
            }
            Items[0].AddEditor(Editors[1]);
            Items[0].AddEditor(Editors[2]);

            //Items[1].AddEditor(Editors[0]); //Try using admin above.
            Items[1].AddEditor(Editors[1]);
            Items[1].AddEditor(Editors[2]);
            var transactions = new List<Transaction>(2);
            transactions.Add(CreateValidEntities.Transaction(1));
            transactions.Add(CreateValidEntities.Transaction(2));
            transactions[0].Item = Items[0];
            transactions[1].Item = Items[1];

            var refund = new Transaction(Items[1]);
            refund.Refunded = true;
            refund.Amount = 0.01m;
            refund.IsActive = false;
            transactions[1].AddChildTransaction(refund);

            SetupDataForPopulateItemTransactionAnswer();
            LoadTransactionAnswers(transactions[1], QuestionSets[0], OpenIdUsers[1]);

            ControllerRecordFakes.FakeTransaction(1, TransactionRepository, transactions);
            #endregion Arrange

            #region Act
            var result = Controller.Refund(2, "", "")
                .AssertViewRendered()
                .WithViewData<EditTransactionViewModel>();
            #endregion Act

            #region Assert
            Assert.IsNull(Controller.Message);
            TransactionRepository.AssertWasNotCalled(a => a.EnsurePersistent(Arg<Transaction>.Is.Anything));
            Assert.AreEqual(" FID=001", result.Fid);
            #endregion Assert
        }
        public void TestRefundGetRedirectsToUrlIfRefundAlreadyExists2()
        {
            #region Arrange
            Controller.ControllerContext.HttpContext.Response
                .Expect(a => a.ApplyAppPathModifier(null)).IgnoreArguments()
                .Return("http://sample.com/ItemManagement/Details/2").Repeat.Any();
            Controller.Url = MockRepository.GenerateStub<UrlHelper>(Controller.ControllerContext.RequestContext);
            Controller.ControllerContext.HttpContext = new MockHttpContext(1, new[] { RoleNames.Refunder, RoleNames.Admin });
            ControllerRecordFakes.FakeItems(Items, 2);
            ControllerRecordFakes.FakeUsers(Users, 3);
            ControllerRecordFakes.FakeEditors(Editors, 3);

            Users[0].LoginID = "UserName";
            for (int i = 0; i < 3; i++)
            {
                Editors[i].User = Users[i];
            }
            Items[0].AddEditor(Editors[1]);
            Items[0].AddEditor(Editors[2]);

            //Items[1].AddEditor(Editors[0]); //Try using admin above.
            Items[1].AddEditor(Editors[1]);
            Items[1].AddEditor(Editors[2]);
            var transactions = new List<Transaction>(2);
            transactions.Add(CreateValidEntities.Transaction(1));
            transactions.Add(CreateValidEntities.Transaction(2));
            transactions[0].Item = Items[0];
            transactions[1].Item = Items[1];

            var refund = new Transaction(Items[1]);
            refund.Refunded = true;
            refund.Amount = 0.01m;
            transactions[1].AddChildTransaction(refund);

            ControllerRecordFakes.FakeTransaction(1, TransactionRepository, transactions);
            #endregion Arrange

            #region Act
            var result = Controller.Refund(2, "", "")
                .AssertHttpRedirect();
            #endregion Act

            #region Assert
            Assert.AreEqual("http://sample.com/ItemManagement/Details/2?Refunds-orderBy=&Refunds-page=1#Refunds", result.Url);
            Assert.AreEqual("Active Refund already exists.", Controller.Message);
            TransactionRepository.AssertWasNotCalled(a => a.EnsurePersistent(Arg<Transaction>.Is.Anything));
            #endregion Assert
        }
        public void TestDetailsRefundReturnsExpectedViewData()
        {
            #region Arrange
            Controller.ControllerContext.HttpContext.Response
                .Expect(a => a.ApplyAppPathModifier(null)).IgnoreArguments()
                .Return("http://sample.com/ItemManagement/Details/2").Repeat.Any();
            Controller.Url = MockRepository.GenerateStub<UrlHelper>(Controller.ControllerContext.RequestContext);
            Controller.ControllerContext.HttpContext = new MockHttpContext(1, new[] { RoleNames.Refunder, RoleNames.Admin });
            ControllerRecordFakes.FakeItems(Items, 2);
            ControllerRecordFakes.FakeUsers(Users, 3);
            ControllerRecordFakes.FakeEditors(Editors, 3);

            Users[0].LoginID = "UserName";
            for (int i = 0; i < 3; i++)
            {
                Editors[i].User = Users[i];
            }
            Items[0].AddEditor(Editors[1]);
            Items[0].AddEditor(Editors[2]);

            Items[1].AddEditor(Editors[0]);
            Items[1].AddEditor(Editors[1]);
            Items[1].AddEditor(Editors[2]);
            var transactions = new List<Transaction>(2);
            transactions.Add(CreateValidEntities.Transaction(1));
            transactions.Add(CreateValidEntities.Transaction(2));
            transactions[0].Item = Items[0];
            transactions[1].Item = Items[1];

            var refund = new Transaction(Items[0]);
            refund.Refunded = true;
            refund.Amount = 0.01m;
            refund.IsActive = true;
            refund.CorrectionReason = "Detail reason here";
            refund.CreatedBy = "NotMe";
            transactions[0].AddChildTransaction(refund);
            transactions[0].Amount = 20m;

            SetupDataForPopulateItemTransactionAnswer();
            LoadTransactionAnswers(transactions[0], QuestionSets[0], OpenIdUsers[1]);

            ControllerRecordFakes.FakeTransaction(1, TransactionRepository, transactions);
            #endregion Arrange

            #region Act
            var result = Controller.DetailsRefund(1, "", "")
                .AssertViewRendered()
                .WithViewData<EditTransactionViewModel>();
            #endregion Act

            #region Assert
            Assert.IsNull(Controller.Message);
            Assert.AreEqual(0.01m, result.RefundAmount);
            Assert.AreEqual("*****@*****.**", result.ContactEmail);
            Assert.AreEqual("FirstName LastName", result.ContactName);
            Assert.AreEqual("Detail reason here", result.CorrectionReason);
            Assert.AreEqual("NotMe", result.CreatedBy);
            Assert.AreEqual(" FID=001", result.Fid);
            #endregion Assert
        }
Example #15
0
        public ActionResult Edit(Transaction transaction, string checkSort, string checkPage)
        {
            ModelState.Clear();
            var transactionToUpdate = Repository.OfType<Transaction>().GetNullableById(transaction.Id);
            if (transactionToUpdate == null)
            {
                Message = NotificationMessages.STR_ObjectNotFound.Replace(NotificationMessages.ObjectType, "Transaction");
                return this.RedirectToAction<ItemManagementController>(a => a.List(null));
            }
            if (transactionToUpdate.Item == null || !Access.HasItemAccess(CurrentUser, transactionToUpdate.Item))
            {
                if (transactionToUpdate.Item == null)
                {
                    Message = NotificationMessages.STR_ObjectNotFound.Replace(NotificationMessages.ObjectType, "Item");
                }
                else
                {
                    Message = NotificationMessages.STR_NoEditorRights.Replace(NotificationMessages.ObjectType, "Item");
                }
                return this.RedirectToAction<ItemManagementController>(a => a.List(null));
            }

            var pageAndSort = ValidateParameters.PageAndSort("ItemDetails", checkSort, checkPage);

            var correctionTransaction = new Transaction(transactionToUpdate.Item);
            correctionTransaction.Amount = transaction.Amount;
            correctionTransaction.CorrectionReason = transaction.CorrectionReason;
            if (correctionTransaction.Amount > 0)
            {
                correctionTransaction.Donation = true;
            }
            else
            {
                correctionTransaction.Donation = false;
            }
            correctionTransaction.CreatedBy = CurrentUser.Identity.Name;

            transactionToUpdate.AddChildTransaction(correctionTransaction);
            //There is a similar check in the payment controller, but with a different message
            if (transactionToUpdate.TotalPaid > transactionToUpdate.Total)
            {
                ModelState.AddModelError("Corrections", "The total of all correction amounts must not exceed the amount already paid.");
            }
            correctionTransaction.TransferValidationMessagesTo(ModelState);//Validate Child as well as parent(next Line)
            transactionToUpdate.TransferValidationMessagesTo(ModelState);

            if (ModelState.IsValid)
            {
                Repository.OfType<Transaction>().EnsurePersistent(transactionToUpdate);
                //return this.RedirectToAction<ItemManagementController>(a => a.Details(transactionToUpdate.Item.Id));
                return
                    Redirect(Url.DetailItemUrl
                    (
                        transactionToUpdate.Item.Id,
                        StaticValues.Tab_Checks,
                        pageAndSort["sort"],
                        pageAndSort["page"])
                    );
            }

            //TODO: We could replace the line below with a rollback to be more consistent.
            transactionToUpdate.ChildTransactions.Remove(correctionTransaction);

            var viewModel = EditTransactionViewModel.Create(Repository, transactionToUpdate);
            viewModel.TransactionValue = transactionToUpdate;
            viewModel.ContactName =
                transactionToUpdate.TransactionAnswers.Where(
                    a =>
                    a.QuestionSet.Name == StaticValues.QuestionSet_ContactInformation &&
                    a.Question.Name == StaticValues.Question_FirstName).FirstOrDefault().Answer;
            viewModel.ContactName = viewModel.ContactName + " " + transactionToUpdate.TransactionAnswers.Where(
                    a =>
                    a.QuestionSet.Name == StaticValues.QuestionSet_ContactInformation &&
                    a.Question.Name == StaticValues.Question_LastName).FirstOrDefault().Answer;
            viewModel.ContactEmail = transactionToUpdate.TransactionAnswers.Where(
                    a =>
                    a.QuestionSet.Name == StaticValues.QuestionSet_ContactInformation &&
                    a.Question.Name == StaticValues.Question_Email).FirstOrDefault().Answer;

            viewModel.Sort = pageAndSort["sort"];
            viewModel.Page = pageAndSort["page"];

            return View(viewModel);
        }
Example #16
0
        public ActionResult Checkout(int id, string referenceIdHidden, int quantity, decimal? donation, decimal? displayAmount, string paymentType, string restrictedKey, string coupon, QuestionAnswerParameter[] transactionAnswers, QuestionAnswerParameter[] quantityAnswers, bool captchaValid)
        {
            // if the arrays are null create new blank ones
            if (transactionAnswers==null) transactionAnswers = new QuestionAnswerParameter[0];
            if (quantityAnswers==null) quantityAnswers = new QuestionAnswerParameter[0];

            #region DB Queries
            // get the item
            var item = Repository.OfType<Item>().GetNullableById(id);

            // get all the questions in 1 queries
            var questionIds = transactionAnswers.Select(b => b.QuestionId).ToList().Union(quantityAnswers.Select(c => c.QuestionId).ToList()).ToArray();
            var allQuestions = Repository.OfType<Question>().Queryable.Where(a => questionIds.Contains(a.Id)).ToList();

            if(!string.IsNullOrWhiteSpace(referenceIdHidden))
            {
                var refId = allQuestions.FirstOrDefault(a => a.Name == "Reference Id");
                if(refId != null)
                {
                    if(transactionAnswers.Any(a => a.QuestionId == refId.Id && string.IsNullOrWhiteSpace(a.Answer)))
                    {
                        transactionAnswers.First(a => a.QuestionId == refId.Id && string.IsNullOrWhiteSpace(a.Answer)).Answer = referenceIdHidden;
                    }
                }
            }

            // get the coupon
            var coup = Repository.OfType<Coupon>().Queryable.Where(a => a.Code == coupon && a.Item == item && a.IsActive).FirstOrDefault();
            #endregion

            // invalid item, or not available for registration
            if (item == null)
            {
                Message = NotificationMessages.STR_ObjectNotFound.Replace(NotificationMessages.ObjectType, "Item");
                return this.RedirectToAction<HomeController>(a => a.Index());
            }
            if (!Access.HasItemAccess(CurrentUser, item)) //Allow editors to over ride and register for things
            {
                if (!item.IsAvailableForReg)
                {
                    Message = NotificationMessages.STR_NotAvailable.Replace(NotificationMessages.ObjectType, "Item");
                    return this.RedirectToAction<HomeController>(a => a.Index());
                }
            }

            if (!captchaValid)
            {
                ModelState.AddModelError("Captcha", "Captcha values are not valid.");
            }

            if(quantity < 1 )
            {
                ModelState.AddModelError("Quantity", "Quantity must be at least 1");
            }

            var transaction = new Transaction(item);

            var questionCount = 0;
            foreach (var itemQuestionSet in item.QuestionSets.Where(a => a.QuantityLevel))
            {
                questionCount += itemQuestionSet.QuestionSet.Questions.Count;
            }
            if (questionCount * quantity != quantityAnswers.Count())
            {
                ModelState.AddModelError("Quantity Level", "The number of answers does not match the number of Quantity Level questions.");
            }

            // fill the openid user if they are openid validated
            if (HttpContext.Request.IsOpenId())
            {
                // doesn't matter if it's null, just assign what we have
                transaction.OpenIDUser = _openIdUserRepository.GetNullableById(CurrentUser.Identity.Name);
            }

            // deal with selected payment type
            if (paymentType == StaticValues.CreditCard)
            {
                transaction.Credit = true;
                transaction.Check = false;
            }
            else if (paymentType == StaticValues.Check)
            {
                transaction.Check = true;
                transaction.Credit = false;
            }

            // deal with the amount
            var amount = item.CostPerItem*quantity; // get the initial amount
            decimal discount = 0.0m;                // used to calculate total discount
            decimal couponAmount = 0.0m;            // used to display individual discount of one coupon
            // get the email
            if (coup != null)
            {
                // calculate the coupon discount
                var emailQ = allQuestions.Where(a => a.Name == StaticValues.Question_Email && a.QuestionSet.Name == StaticValues.QuestionSet_ContactInformation).FirstOrDefault();
                if (emailQ != null)
                {
                    // get the answer
                    var answer = transactionAnswers.Where(a => a.QuestionId == emailQ.Id).FirstOrDefault();
                    discount = coup.UseCoupon(answer != null ? answer.Answer : null, quantity);
                }
                else
                {
                    discount = coup.UseCoupon(null, quantity);
                }

                // if coupon is used set display value
                if(discount == 0)
                {
                    ModelState.AddModelError("Coupon", NotificationMessages.STR_Coupon_could_not_be_used);
                    transaction.Coupon = null;
                }
                else
                {
                    couponAmount = coup.DiscountAmount;
                    // record the coupon usage to this transaction
                    transaction.Coupon = coup;
                }

            }
            transaction.Amount = amount - discount;
            transaction.Quantity = quantity;

            // deal with the transaction answers
            foreach (var qa in transactionAnswers)
            {
                var question = allQuestions.Where(a => a.Id == qa.QuestionId).FirstOrDefault();

                // if question is null just drop it
                if (question != null)
                {
                    //var answer = question.QuestionType.Name != QuestionTypeText.STR_CheckboxList
                    //                 ? qa.Answer
                    //                 : (qa.CblAnswer != null ? string.Join(", ", qa.CblAnswer) : string.Empty);
                    var answer = CleanUpAnswer(question.QuestionType.Name, qa, question.ValidationClasses);

                    // validate each of the validators
                    foreach (var validator in question.Validators)
                    {
                        string message;
                        if (!Validate(validator, answer, question.Name, out message))
                        {
                            ModelState.AddModelError("Transaction Question", message);
                        }
                    }

                    var qanswer = new TransactionAnswer(transaction, question.QuestionSet, question, answer);
                    transaction.AddTransactionAnswer(qanswer);
                }
                //TODO: consider writing this to a log or something
            }

            // deal with quantity level answers
            for (var i = 0; i < quantity; i++)
            {
                // generate the unique id for each quantity
                var quantityId = Guid.NewGuid();

                foreach (var qa in quantityAnswers.Where(a => a.QuantityIndex == i))
                {
                    var question = allQuestions.Where(a => a.Id == qa.QuestionId).FirstOrDefault();
                    // if question is null just drop it
                    if (question != null)
                    {
                        //var answer = question.QuestionType.Name != QuestionTypeText.STR_CheckboxList
                        //                 ? qa.Answer
                        //                 : (qa.CblAnswer != null ? string.Join(", ", qa.CblAnswer) : string.Empty);

                        var answer = CleanUpAnswer(question.QuestionType.Name, qa, question.ValidationClasses);

                        var fieldName = string.Format("The answer for question \"{0}\" for {1} {2}", question.Name, item.QuantityName, (i + 1));

                        // validate each of the validators
                        foreach (var validator in question.Validators)
                        {
                            string message;
                            if (!Validate(validator, answer, fieldName, out message))
                            {
                                ModelState.AddModelError("Quantity Question", message);
                            }
                        }

                        var qanswer = new QuantityAnswer(transaction, question.QuestionSet, question, answer,
                                                         quantityId);
                        transaction.AddQuantityAnswer(qanswer);
                    }
                }
            }

            // deal with donation
            if (donation.HasValue && donation.Value > 0.0m)
            {
                var donationTransaction = new Transaction(item);
                donationTransaction.Donation = true;
                donationTransaction.Amount = donation.Value;

                transaction.AddChildTransaction(donationTransaction);
            }

            // check to see if it's a restricted item
            if (!string.IsNullOrEmpty(item.RestrictedKey) && item.RestrictedKey != restrictedKey)
            {
                ModelState.AddModelError("Restricted Key", "The item is restricted please enter the passphrase.");
            }

            if (!Access.HasItemAccess(CurrentUser, item)) //Allow editors to over ride and register for things
            {
                // do a final check to make sure the inventory is there
                if (item.Sold + quantity > item.Quantity)
                {
                    ModelState.AddModelError("Quantity", "There is not enough inventory to complete your order.");
                }
            }
            //if (transaction.Total == 0 && transaction.Credit)
            //{
            //    ModelState.AddModelError("Payment Method", "Please select check payment type when amount is zero.");
            //}
            if(transaction.Total == 0)
            {
                transaction.Credit = false;
                transaction.Check = true;
            }
            if (transaction.Total != displayAmount)
            {
                ModelState.AddModelError("Total", "We are sorry, the total amount displayed on the form did not match the total we calculated.");
            }

            MvcValidationAdapter.TransferValidationMessagesTo(ModelState, transaction.ValidationResults());

            if (ModelState.IsValid)
            {
                // create the new transaction
                Repository.OfType<Transaction>().EnsurePersistent(transaction);

                if(transaction.Paid && transaction.Check)
                {
                    if(transaction.Item.CostPerItem == 0.0m || couponAmount > 0.0m)
                    {
                        //Ok, it is paid because the amount is zero, and it is because a coupon was used or the cost was zero
                        try
                        {
                            //If the tranascation is not evicted, it doesn't refresh from the database and the transaction number is null.
                            var saveId = transaction.Id;
                            NHibernateSessionManager.Instance.GetSession().Evict(transaction);
                            transaction = Repository.OfType<Transaction>().GetNullableById(saveId);
                            // attempt to get the contact information question set and retrieve email address
                            var question = transaction.TransactionAnswers.Where(a => a.QuestionSet.Name == StaticValues.QuestionSet_ContactInformation && a.Question.Name == StaticValues.Question_Email).FirstOrDefault();
                            if (question != null)
                            {
                                // send an email to the user
                                _notificationProvider.SendConfirmation(Repository, transaction, question.Answer);
                            }
                        }
                        catch (Exception)
                        {

                        }
                    }
                }

                var updatedItem = Repository.OfType<Item>().GetNullableById(transaction.Item.Id);
                if (updatedItem != null)
                {
                    //For whatever reason, if you are logged in with your CAES user, the item is updated,
                    //if you are logged in with open id (google), item is not updated.
                    var transactionQuantity = transaction.Quantity;
                    if (updatedItem.Transactions.Contains(transaction))
                    {
                        transactionQuantity = 0;
                    }
                    if (updatedItem.Quantity - (updatedItem.Sold + transactionQuantity) <= 10)
                    {
                        _notificationProvider.SendLowQuantityWarning(Repository, updatedItem, transactionQuantity);
                    }

                }
                // redirect to confirmation and let the user decide payment or not
                return this.RedirectToAction(a => a.Confirmation(transaction.Id));
            }

            var viewModel = ItemDetailViewModel.Create(Repository, _openIdUserRepository, item, CurrentUser.Identity.Name, referenceIdHidden, null, null);
            viewModel.Quantity = quantity;
            viewModel.Answers = PopulateItemTransactionAnswer(transactionAnswers, quantityAnswers);
            viewModel.CreditPayment = (paymentType == StaticValues.CreditCard);
            viewModel.CheckPayment = (paymentType == StaticValues.Check);
            viewModel.TotalAmountToRedisplay = transaction.Total;
            viewModel.CouponAmountToDisplay = couponAmount;
            viewModel.CouponTotalDiscountToDisplay = discount;
            return View(viewModel);
        }