Inheritance: Suteki.Common.ViewData.ViewDataBase
	    public Order OrderFromCheckoutViewData(CheckoutViewData checkoutViewData, ModelStateDictionary modelState)
	    {
            if (EmailAddressesDoNotMatch(checkoutViewData, modelState)) return null;

            var basket = basketRepository.GetById(checkoutViewData.BasketId);
            userService.CurrentUser.EnsureCanView(basket);

            var order = new Order
            {
                Email = checkoutViewData.Email,
                AdditionalInformation = checkoutViewData.AdditionalInformation,
                ContactMe = checkoutViewData.ContactMe,
                Card = GetCardFromViewData(checkoutViewData, modelState),
                CardContact = GetCardContactFromViewData(checkoutViewData, modelState),
                CreatedDate = DateTime.Now,
                DeliveryContact = GetDeliveryContactFromViewData(checkoutViewData, modelState),
                DispatchedDate = DateTime.Now,
                OrderStatus = OrderStatus.Pending,
                UseCardHolderContact = checkoutViewData.UseCardholderContact,
                PayByTelephone = checkoutViewData.PayByTelephone,
                User = userService.CurrentUser
            };

            AddOrderLinesFromBasket(order, basket);
	        CalcuatePostage(order, basket);
            return order;
        }
 private static bool EmailAddressesDoNotMatch(CheckoutViewData checkoutViewData, ModelStateDictionary modelState)
 {
     if (checkoutViewData.Email != checkoutViewData.EmailConfirm)
     {
         modelState.AddModelError("EmailConfirm", "Email Addresses do not match");
         return true;
     }
     return false;
 }
		public void Index_should_load_order_from_tempdata()
		{
		    var checkoutViewData = new CheckoutViewData();
            controller.TempData["CheckoutViewData"] = checkoutViewData;

			controller.Index(4)
				.ReturnsViewResult()
                .WithModel<CheckoutViewData>()
                .AssertAreSame(checkoutViewData, vd => vd);
		}
		public ActionResult Index(CheckoutViewData checkoutViewData)
		{
		    var order = checkoutService.OrderFromCheckoutViewData(checkoutViewData, ModelState);

			if (ModelState.IsValid)
			{
				orderRepository.SaveOrUpdate(order);
				//we need an explicit Commit in order to obtain the db-generated Order Id
				unitOfWork.Commit();
				return this.RedirectToAction(c => c.Confirm(order.Id));
			}

		    return View("Index", checkoutViewData);
		}
		public ActionResult UpdateCountry(CheckoutViewData checkoutViewData)
		{
			//Ignore any errors - if there are any errors in modelstate then the UnitOfWork will not commit.
			ModelState.Clear(); 

			var basket = basketRepository.GetById(checkoutViewData.BasketId);

		    var country = checkoutViewData.UseCardholderContact
		                      ? checkoutViewData.CardContactCountry
		                      : checkoutViewData.DeliveryContactCountry;
			
            basket.Country = country;
            CurrentOrder = checkoutViewData;
            return this.RedirectToAction(c => c.Index(checkoutViewData.BasketId));
		}
	    public void SetUp()
	    {
            basketRepository = MockRepository.GenerateStub<IRepository<Basket>>();
            encryptionService = MockRepository.GenerateStub<IEncryptionService>();
	        postageService = MockRepository.GenerateStub<IPostageService>();
	        userService = MockRepository.GenerateStub<IUserService>();

            checkoutService = new CheckoutService(basketRepository, encryptionService, postageService, userService);

            checkoutViewData = GetCheckoutViewData();
            basket = CreateBasketWithId(7);
            basketRepository.Stub(r => r.GetById(7)).Return(basket);

            user = new User { Role = Role.Administrator };
	        userService.Stub(u => u.CurrentUser).Return(user);
	    }
		public void IndexWithPost_ShouldCreateANewOrder()
		{
		    var checkoutViewData = new CheckoutViewData();

		    var createdOrder = new Order();
		    Order savedOrder = null;
		    orderRepository.SaveOrUpdateDelegate = entity =>
		    {
		        savedOrder = entity;
		        savedOrder.Id = 4;
		    };

		    checkoutService.Stub(c => c.OrderFromCheckoutViewData(checkoutViewData, controller.ModelState))
                .Return(createdOrder);

		    controller.Index(checkoutViewData)
				.ReturnsRedirectToRouteResult()
				.ToController("Checkout")
				.ToAction("Confirm")
				.WithRouteValue("id", "4");

            savedOrder.ShouldBeTheSameAs(createdOrder);
            controller.ModelState.IsValid.ShouldBeTrue();
		}
        private void VerifyOrderMatchesCheckoutViewData(Order order, CheckoutViewData checkoutViewData)
        {
            order.CardContact.Firstname.ShouldEqual(checkoutViewData.CardContactFirstName);
            order.CardContact.Lastname.ShouldEqual(checkoutViewData.CardContactLastName);
            order.CardContact.Address1.ShouldEqual(checkoutViewData.CardContactAddress1);
            order.CardContact.Address2.ShouldEqual(checkoutViewData.CardContactAddress2);
            order.CardContact.Address3.ShouldEqual(checkoutViewData.CardContactAddress3);
            order.CardContact.Town.ShouldEqual(checkoutViewData.CardContactTown);
            order.CardContact.County.ShouldEqual(checkoutViewData.CardContactCounty);
            order.CardContact.Postcode.ShouldEqual(checkoutViewData.CardContactPostcode);
            order.CardContact.Country.ShouldEqual(checkoutViewData.CardContactCountry);
            order.CardContact.Telephone.ShouldEqual(checkoutViewData.CardContactTelephone);

            order.Email.ShouldEqual(checkoutViewData.Email);

            order.UseCardHolderContact.ShouldEqual(checkoutViewData.UseCardholderContact);

            order.DeliveryContact.Firstname.ShouldEqual(checkoutViewData.DeliveryContactFirstName);
            order.DeliveryContact.Lastname.ShouldEqual(checkoutViewData.DeliveryContactLastName);
            order.DeliveryContact.Address1.ShouldEqual(checkoutViewData.DeliveryContactAddress1);
            order.DeliveryContact.Address2.ShouldEqual(checkoutViewData.DeliveryContactAddress2);
            order.DeliveryContact.Address3.ShouldEqual(checkoutViewData.DeliveryContactAddress3);
            order.DeliveryContact.Town.ShouldEqual(checkoutViewData.DeliveryContactTown);
            order.DeliveryContact.County.ShouldEqual(checkoutViewData.DeliveryContactCounty);
            order.DeliveryContact.Postcode.ShouldEqual(checkoutViewData.DeliveryContactPostcode);
            order.DeliveryContact.Country.ShouldEqual(checkoutViewData.DeliveryContactCountry);
            order.DeliveryContact.Telephone.ShouldEqual(checkoutViewData.DeliveryContactTelephone);

            order.AdditionalInformation.ShouldEqual(checkoutViewData.AdditionalInformation);

            order.Card.CardType.ShouldEqual(checkoutViewData.CardCardType);
            order.Card.Holder.ShouldEqual(checkoutViewData.CardHolder);
            order.Card.Number.ShouldEqual(checkoutViewData.CardNumber);
            order.Card.ExpiryMonth.ShouldEqual(checkoutViewData.CardExpiryMonth);
            order.Card.ExpiryYear.ShouldEqual(checkoutViewData.CardExpiryYear);
            order.Card.StartMonth.ShouldEqual(checkoutViewData.CardStartMonth);
            order.Card.StartYear.ShouldEqual(checkoutViewData.CardStartYear);
            order.Card.IssueNumber.ShouldEqual(checkoutViewData.CardIssueNumber);
            order.Card.SecurityCode.ShouldEqual(checkoutViewData.CardSecurityCode);

            order.PayByTelephone.ShouldEqual(checkoutViewData.PayByTelephone);
            order.ContactMe.ShouldEqual(checkoutViewData.ContactMe);

            order.User.ShouldBeTheSameAs(user);
        }
        private static Contact GetCardContactFromViewData(CheckoutViewData checkoutViewData, ModelStateDictionary modelState)
        {
            var cardContact = new Contact
            {
                Address1 = checkoutViewData.CardContactAddress1,
                Address2 = checkoutViewData.CardContactAddress2,
                Address3 = checkoutViewData.CardContactAddress3,
                Country = checkoutViewData.CardContactCountry,
                County = checkoutViewData.CardContactCounty,
                Firstname = checkoutViewData.CardContactFirstName,
                Lastname = checkoutViewData.CardContactLastName,
                Town = checkoutViewData.CardContactTown,
                Telephone = checkoutViewData.CardContactTelephone,
                Postcode = checkoutViewData.CardContactPostcode
            };

            DataAnnotationsValidator
                .Validate(cardContact)
                .WithPropertyPrefix("CardContact")
                .AndUpdate(modelState);

            return cardContact;
        }
        private Card GetCardFromViewData(CheckoutViewData checkoutViewData, ModelStateDictionary modelState)
        {
            if (checkoutViewData.PayByTelephone) return null;

            var card = new Card
            {
                Holder = checkoutViewData.CardHolder,
                Number = checkoutViewData.CardNumber,
                ExpiryMonth = checkoutViewData.CardExpiryMonth,
                ExpiryYear = checkoutViewData.CardExpiryYear,
                StartMonth = checkoutViewData.CardStartMonth,
                StartYear = checkoutViewData.CardStartYear,
                IssueNumber = checkoutViewData.CardIssueNumber,
                SecurityCode = checkoutViewData.CardSecurityCode,
                CardType = checkoutViewData.CardCardType
            };

            DataAnnotationsValidator
                .Validate(card)
                .WithPropertyPrefix("Card")
                .AndUpdate(modelState);

            // don't attempt to encrypt card if there are any model binding errors.
            if (modelState.IsValid)
            {
                var validator = new Validator
	            {
                    () => encryptionService.EncryptCard(card)
	            };
                validator.Validate(modelState);
            }

            return card;
        }
        private static Contact GetDeliveryContactFromViewData(CheckoutViewData checkoutViewData, ModelStateDictionary modelState)
        {
            if (checkoutViewData.UseCardholderContact) return null;

            var deliveryContact = new Contact
            {
                Address1 = checkoutViewData.DeliveryContactAddress1,
                Address2 = checkoutViewData.DeliveryContactAddress2,
                Address3 = checkoutViewData.DeliveryContactAddress3,
                Country = checkoutViewData.DeliveryContactCountry,
                County = checkoutViewData.DeliveryContactCounty,
                Firstname = checkoutViewData.DeliveryContactFirstName,
                Lastname = checkoutViewData.DeliveryContactLastName,
                Town = checkoutViewData.DeliveryContactTown,
                Telephone = checkoutViewData.DeliveryContactTelephone,
                Postcode = checkoutViewData.DeliveryContactPostcode
            };

            DataAnnotationsValidator
                .Validate(deliveryContact)
                .WithPropertyPrefix("DeliveryContact")
                .AndUpdate(modelState);

            return deliveryContact;
        }
	    public void UpdateCountry_should_update_the_country()
	    {
	        const int basketId = 94;
	        var basket = new Basket();
	        basketRepository.Stub(b => b.GetById(basketId)).Return(basket);

	        var checkoutViewData = new CheckoutViewData
	        {
	            BasketId = basketId,
	            UseCardholderContact = true,
	            CardContactCountry = new Country(),
                DeliveryContactCountry = new Country()
	        };

	        controller.UpdateCountry(checkoutViewData)
	            .ReturnsRedirectToRouteResult()
	            .WithRouteValue("action", "Index");

            basket.Country.ShouldBeTheSameAs(checkoutViewData.CardContactCountry);

            controller.TempData["CheckoutViewData"].ShouldBeTheSameAs(checkoutViewData);
	    }