public  void OrderRepository_CanSave_NewAddress_ForTestUser()
        {
            var add = new Address("testuser", "test", "user", "email",
            "newstreet1", "newstreet2", "newcity",
            "stateprovince", "zip", "country");

            _orderRepository.SaveAddress(add);
            IList<Address> adds = _orderService.GetAddresses("testuser");
            Assert.AreEqual(3,adds.Count);

        }
        public Address VerifyAddress(Address address) {
            
            //using RPC.Geocoder - this is a free service
            Address result = address;

            //http://rpc.geocoder.us/demo.cgi?address=1600+Pennsylvania+Ave%2C+Washington+DC

            string addressArgs;

            if (!String.IsNullOrEmpty(address.Zip)) {
                addressArgs = string.Format("{0},{1}", address.Street1, address.Zip);

            } else {
                addressArgs = string.Format("{0},{1},{2}", address.Street1, address.City, address.StateOrProvince);
            }
            //do the web request and get the reply
            string url = string.Format("{0}?{1}", "http://rpc.geocoder.us/service/csv?address=", addressArgs);
            url = url.Replace(" ", "+").Replace(",", "%2C");


            string webPage;
            WebRequest request = WebRequest.Create(url);
            using (Stream stream = request.GetResponse().GetResponseStream()) {
                StreamReader sr = new StreamReader(stream);
                webPage = sr.ReadToEnd();
                sr.Close();
            }

            //the reply is in CSV Format, like this:
            //38.898748,-77.037684,1600 Pennsylvania Ave NW,Washington,DC,20502

            //if there is no match, then it will send back something like
            //2) oops sorry we can't find

            string[] resultCSV = webPage.Split(',');
            if (resultCSV.Length > 1) {
                result.Latitude = resultCSV[0];
                result.Longitude = resultCSV[1];
                result.Street1 = resultCSV[2];
                result.City = resultCSV[3];
                result.StateOrProvince = resultCSV[4];
                result.Zip = resultCSV[5];
            } else {
                throw new InvalidDataException("Cannot find this address :" + address);

            }
            return result;
        }
        public void Address_ShouldHave_First_Last_Email_Street_Street2_City_State_Zip()
        {
            Address add=new Address("testuser","first","last","email",
                "street1","street2","city","stateprovince","zip","country");

            Assert.AreEqual("testuser", add.UserName);
            Assert.AreEqual("first", add.FirstName);
            Assert.AreEqual("last", add.LastName);
            Assert.AreEqual("email", add.Email);
            Assert.AreEqual("street1", add.Street1);
            Assert.AreEqual("street2", add.Street2);
            Assert.AreEqual("city", add.City);
            Assert.AreEqual("stateprovince", add.StateOrProvince);
            Assert.AreEqual("zip", add.Zip);
            Assert.AreEqual("country", add.Country);
        }
        public TestOrderRepository() {
            _order = _order ?? new Order("TESTORDER", "testuser");
            _orders = new List<Order>();
            _orders.Add(_order);

            //create the items
            _orderItems = new List<OrderItem>();
            _addresses = new List<Address>();
            
            for (int i = 0; i < 2; i++)
            {
                var add = new Address("testuser", "first" + i, "last" + i, "email" + i,
                "street1" + i, "street2" + i, "city" + i,
                "stateprovince" + i, "zip" + i, "country" + i);
                add.IsDefault = i == 1;
                add.ID = i;
                if (!_addresses.Contains(add))
                    _addresses.Add(add);
            }

            TestCatalogRepository catalog = new TestCatalogRepository();

            for (int i = 0; i < 99; i++) {
                Order o = new Order("order" + i, "user" + 1);
                o.ID = Guid.NewGuid();


                for (int x = 1; x <= 5; x++) {
                    OrderItem item = new OrderItem(o.ID, catalog.GetProducts()
                        .Where(y=>y.ID==x).SingleOrDefault());
                    
                    item.Quantity = x == 5 ? 3 : 1;
                    
                    if(item.Quantity==1)
                        item.Quantity = x == 4 ? 2 : 1;

                    _orderItems.Add(item);
                    o.Items.Add(item);
                }

                o.ShippingAddress = GetAddresses().Take(1).Skip(1).SingleOrDefault();
                _orders.Add(o);
            }

        }
        public Address GetOpenIDAddress(Uri claimUri)
        {
            var openid = new OpenIdRelyingParty();
            Address result=new Address();
            if (openid.Response != null)
            {
                // Stage 2: user submitting Identifier
                var fetch = openid.Response.GetExtension<FetchResponse>();
                if (fetch != null)
                {
                    
                    
                    result.Email = GetFetchValue(fetch, "contact/email");
                    result.FirstName = GetFetchValue(fetch, "namePerson/first");
                    result.LastName = GetFetchValue(fetch, "namePerson/last");
                    result.Street1 = GetFetchValue(fetch, "contact/streetaddressLine1/home");
                    result.Street2 = GetFetchValue(fetch, "contact/streetaddressLine2/home");
                    result.City = GetFetchValue(fetch, "contact/city/home");
                    result.StateOrProvince = GetFetchValue(fetch, "contact/city/stateorprovince");
                    result.Country = GetFetchValue(fetch, "contact/country/home");
                    result.Zip = GetFetchValue(fetch, "contact/postalCode/home");

                    result.UserName = openid.Response.ClaimedIdentifier;

                }
            }
            else
            {
                var request=openid.CreateRequest(claimUri.AbsoluteUri);
                var fetch = new FetchRequest();
                fetch.AddAttribute(new AttributeRequest("contact/email"));
                fetch.AddAttribute(new AttributeRequest("namePerson/first"));
                fetch.AddAttribute(new AttributeRequest("namePerson/last"));
                fetch.AddAttribute(new AttributeRequest("contact/streetaddressLine1/home"));
                fetch.AddAttribute(new AttributeRequest("contact/streetaddressLine2/home"));
                fetch.AddAttribute(new AttributeRequest("contact/city/home"));
                fetch.AddAttribute(new AttributeRequest("contact/city/stateorprovince"));
                fetch.AddAttribute(new AttributeRequest("contact/country/home"));
                fetch.AddAttribute(new AttributeRequest("contact/postalCode/home"));
                request.AddExtension(fetch);
                request.RedirectToProvider();
            }
            return result;
        }
        Order GetTestOrder() {
            Order o = _orderService.GetCurrentOrder("testuser");
            o.AddItem(_catalogService.GetProduct(1), 1);
            o.AddItem(_catalogService.GetProduct(2), 1);
            o.AddItem(_catalogService.GetProduct(3), 1);
            o.AddItem(_catalogService.GetProduct(4), 1);

            o.ShippingMethod = _shippingService.CalculateRates(o)[0];
            o.PaymentMethod = new CreditCard("Visa", "testuser", "4586 9748 7358 4049", 10, 2010, "123");

            //add some addresses
            Address add = new Address("Joe", "Joe", "Tonks", "*****@*****.**",
                "1099 Alakea St", "", "Honolulu", "HI", "96813", "US");

            o.ShippingAddress = add;
            o.BillingAddress = add;


            return o;
        }
        public ActionResult Shipping() {

            OrderData data = new OrderData();
            data.CurrentOrder = GetTempOrder();
            
            //default the shipping method
            data.ShippingMethods = _shippingService.CalculateRates(data.CurrentOrder);
            data.CurrentOrder.ShippingMethod = data.ShippingMethods[0];

            //this is for test only
            Address defaultAdd = new Address("testuser", "Jack", "Johnson", "*****@*****.**", "1525 Bernice Street", "", "Honolulu", "HI", "96817", "US");

            string sAddressID = Request.Form["addressid"];
            int addressID = 0;
            if (!String.IsNullOrEmpty(sAddressID)) {
                int.TryParse(sAddressID, out addressID);
                defaultAdd = _orderService.GetAddress(addressID);
                
                //save it
                _orderService.SaveOrder(data.CurrentOrder);

            }


            //new up the shipping address
            data.CurrentOrder.ShippingAddress = defaultAdd;

            //send them somewhere else if there are no items
            if (data.CurrentOrder.Items.Count == 0) {
                return RedirectToAction("Show");
            } else {
                return View(data);
            }

        }
 public  void SaveAddress(Address address)
 {
     if (!_addresses.Contains(address))
         _addresses.Add(address);
 }
        /// <summary>
        /// Handles the IPN Notification from PayPal
        /// </summary>
        /// <returns></returns>
        public ActionResult IPN() {
            _logger.Info("IPN Invoked");

            var formVals = new Dictionary<string, string>();
            formVals.Add("cmd", "_notify-validate");

            string response = GetPayPalResponse(formVals, true);

            if (response == "VERIFIED") {

                string transactionID = Request["txn_id"];
                string sAmountPaid = Request["mc_gross"];
                string orderID = Request["custom"];

                _logger.Info("IPN Verified for order " + orderID);

                //validate the order
                Decimal amountPaid = 0;
                Decimal.TryParse(sAmountPaid, out amountPaid);

                Order order = _orderService.GetOrder(new Guid(orderID));

                //check the amount paid

                if (AmountPaidIsValid(order, amountPaid)) {

                    Address add = new Address();
                    add.FirstName = Request["first_name"];
                    add.LastName = Request["last_name"];
                    add.Email = Request["payer_email"];
                    add.Street1 = Request["address_street"];
                    add.City = Request["address_city"];
                    add.StateOrProvince = Request["address_state"];
                    add.Country = Request["address_country"];
                    add.Zip = Request["address_zip"];
                    add.UserName = order.UserName;


                    order.ShippingAddress = add;
                    order.BillingAddress = order.ShippingAddress;
                    //process it
                    try {
                        _pipeline.AcceptPalPayment(order, transactionID, amountPaid);
                        _logger.Info("IPN Order successfully transacted: " + orderID);
                        return RedirectToAction("Receipt", "Order", new { id = order.ID });
                    }
                    catch (Exception x) {
                        HandleProcessingError(order, x);
                        return View();
                    }
                }
                else {
                    //let fail - this is the IPN so there is no viewer
                }
            }



            return View();
        }
        /// <summary>
        /// Handles the PDT Response from PayPal
        /// </summary>
        /// <returns></returns>
        public ActionResult PDT() {
            _logger.Info("PDT Invoked");
            string transactionID = Request.QueryString["tx"];
            string sAmountPaid = Request.QueryString["amt"];
            string orderID=Request.QueryString["cm"];


            Dictionary<string, string> formVals = new Dictionary<string, string>();
            formVals.Add("cmd", "_notify-synch");
            formVals.Add("at", "JijaVlgNlwzXc5N_Zj53LS-v5EmzqsQGMa6eZcKyXad8hH7dn08ntEZlcAW");
            formVals.Add("tx", transactionID);

            string response = GetPayPalResponse(formVals, true);
            //_logger.Info("PDT Response received: " + response);
            if (response.StartsWith("SUCCESS")) {
                _logger.Info("PDT Response received for order " + orderID);

                //validate the order
                Decimal amountPaid = 0;
                Decimal.TryParse(sAmountPaid, out amountPaid);


                Order order = _orderService.GetOrder(new Guid(orderID));

                if (AmountPaidIsValid(order, amountPaid)) {


                    Address add = new Address();
                    add.FirstName = GetPDTValue(response, "first_name");
                    add.LastName = GetPDTValue(response, "last_name");
                    add.Email = GetPDTValue(response, "payer_email");
                    add.Street1 = GetPDTValue(response, "address_street");
                    add.City = GetPDTValue(response, "address_city");
                    add.StateOrProvince = GetPDTValue(response, "address_state");
                    add.Country = GetPDTValue(response, "address_country");
                    add.Zip = GetPDTValue(response, "address_zip");
                    add.UserName = order.UserName;

                    order.ShippingAddress = add;
                    order.BillingAddress = order.ShippingAddress;

                    //process it
                    try {
                        _pipeline.AcceptPalPayment(order, transactionID, amountPaid);
                        _logger.Info("PDT Order successfully transacted: " + orderID);
                        return RedirectToAction("Receipt", "Order", new { id = order.ID });
                    }
                    catch (Exception x) {
                        HandleProcessingError(order, x);
                        return View();
                    }

                }
                else {
                    //Payment amount is off
                    //this can happen if you have a Gift cert at PayPal
                    //be careful of this!
                    HandleProcessingError(order, new InvalidOperationException("Amount paid (" + amountPaid.ToString("C") + ") was below the order total"));
                    return View();
                }
            }
            else {
                ViewData["message"] = "Your payment was not successful with PayPal";
                return View();
            }
        }
 /// <summary>
 /// Saves an address
 /// </summary>
 public void  SaveAddress(Address add)
 {
     SaveAddress(add);
 }