/// <summary>
        /// Creates the interest in building from the user to the current
        /// listing.
        /// </summary>
        /// <param name="username">The username.</param>
        /// <param name="listingId">The listing id.</param>
        /// <returns>
        /// A status of whether or not the interest was created.
        /// </returns>
        public Status <UserInterest> CreateInterestInBuilding(string username, long listingId, string message)
        {
            if (listingId == 0)
            {
                return(Status.ValidationError <UserInterest>(null, "listingId", "listingId is required"));
            }

            if (string.IsNullOrWhiteSpace(username))
            {
                return(Status.ValidationError <UserInterest>(null, "username", "username is required"));
            }

            using (var context = new RentlerContext())
            {
                try
                {
                    User user = (from u in context.Users
                                 where u.Username == username
                                 select u).SingleOrDefault();

                    if (user == null)
                    {
                        return(Status.NotFound <UserInterest>());
                    }

                    UserInterest newInterest = new UserInterest()
                    {
                        BuildingId = listingId,
                        UserId     = user.UserId,
                        Message    = message
                    };

                    context.UserInterests.Add(newInterest);
                    context.SaveChanges();

                    // loads the building, which generated this interest, into newInterest
                    context.Entry(newInterest).Reference(e => e.Building).Load();

                    // notify landlord of interest
                    // TODO: if we are unable to send this email we need a way to allow the user
                    // to re-notify the Landlord without requiring them to continue to create
                    // interests
                    EmailListingInterestedModel model = new EmailListingInterestedModel(newInterest);
                    mailer.Interested(model);

                    return(Status.OK <UserInterest>(newInterest));
                }
                catch (Exception ex)
                {
                    // log exception
                    return(Status.Error <UserInterest>("System was unable to create interest", null));
                }
            }
        }
        /// <summary>
        /// Verifies a user for correct login
        /// </summary>
        /// <param name="username">The username.</param>
        /// <param name="password">The password.</param>
        /// <returns>
        /// Status result with the working user if successful.
        /// </returns>
        public Status <User> LoginUser(string username, string password)
        {
            if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
            {
                return(Status.ValidationError <User>(null, "UserName", "The username or password is incorrect"));
            }

            string hashedPassword = FormsAuthentication.HashPasswordForStoringInConfigFile(password, "SHA1");

            using (var context = new RentlerContext())
            {
                // find rentler user
                var user = (from u in context.Users
                            where u.Email == username ||
                            u.Username == username
                            select u).FirstOrDefault();

                // user not found, need a user record
                if (user == null)
                {
                    return(Status.ValidationError <User>(null, "UserName", "The username or password is incorrect"));
                }

                // user has rentler password and it matched
                if (user.PasswordHash == hashedPassword)
                {
                    return(Status.OK <User>(user));
                }

                // no password match on rentler user
                // don't worry though, could still be an affiliate user
                context.Entry(user).Reference("AffiliateUser").Load();

                // make sure the user has an affiliate user
                // make sure the affiliate user has a password to check
                //"$A" denotes a "Mode A" Ksl Md5 hashing algorithm
                if (user.AffiliateUser != null &&
                    user.AffiliateUser.PasswordHash != null &&
                    user.AffiliateUser.PasswordHash.StartsWith("$A"))
                {
                    if (CheckKslPassword(password, user.AffiliateUser.PasswordHash))
                    {
                        return(Status.OK <User>(user));
                    }
                }

                return(Status.ValidationError <User>(null, "Password", "The username or password is incorrect"));
            }
        }
Exemple #3
0
        public Status <Order> ProcessOrder(
            string username, int orderId, UserCreditCard card, bool saveCard)
        {
            bool isNewCard = card.UserCreditCardId == 0;

            if (isNewCard)
            {
                // we're adding the new card regardless but we don't know if its valid
                // if the user requested to save it we will make it active after the payment
                // is successful, otherwise it will remain inactive
                card.IsDeleted = true;

                var cardResult = AddUserCreditCard(username, card);

                if (cardResult.StatusCode != 200)
                {
                    var orderStatus = GetOrderForCheckout(username, orderId);

                    orderStatus.StatusCode = 500;
                    orderStatus.Errors     = new ValidationResult[] {
                        new ValidationResult("An unexpected failure occurred: payment was not processed", new string[] { "Order" })
                    };

                    return(orderStatus);
                }
            }
            else
            {
                //get the card
                var storedCard = GetUserCreditCard(username, card.UserCreditCardId);

                if (storedCard == null)
                {
                    var orderStatus = GetOrderForCheckout(username, orderId);

                    orderStatus.StatusCode = 500;
                    orderStatus.Errors     = new ValidationResult[] {
                        new ValidationResult("Failed to locate credit card on file: payment was not processed", new string[] { "Order" })
                    };

                    return(orderStatus);
                }

                //update the billing address if anything changed
                if (storedCard.Address1 != card.Address1 ||
                    storedCard.Address2 != card.Address2 ||
                    storedCard.City != card.City ||
                    storedCard.FirstName != card.FirstName ||
                    storedCard.LastName != card.LastName ||
                    storedCard.State != card.State ||
                    storedCard.Zip != card.Zip)
                {
                    storedCard.Address1  = card.Address1;
                    storedCard.Address2  = card.Address2;
                    storedCard.City      = card.City;
                    storedCard.FirstName = card.FirstName;
                    storedCard.LastName  = card.LastName;
                    storedCard.State     = card.State;
                    storedCard.Zip       = card.Zip;

                    var updateStatus = UpdateUserCreditCard(username, storedCard);

                    if (updateStatus.StatusCode != 200)
                    {
                        var orderStatus = GetOrderForCheckout(username, orderId);

                        orderStatus.StatusCode = 500;
                        orderStatus.Errors     = new ValidationResult[] {
                            new ValidationResult("Failed to update card address: payment was not processed", new string[] { "Order" })
                        };

                        return(orderStatus);
                    }
                }

                card = storedCard;
            }

            //grab the order
            var order = GetOrderForCheckout(username, orderId);

            //attach the credit card to the order for our records
            order.Result.UserCreditCardId = card.UserCreditCardId;

            if (order.StatusCode != 200)
            {
                return(order);
            }

            //let's pay for stuff!

            CardPaymentResult result;

            if (App.StorePricing == "Penny")
            {
                result = manager.AuthorizeCreditCardPayment(card, 0.01m);
            }
            else
            {
                result = manager.AuthorizeCreditCardPayment(card, order.Result.OrderTotal);
            }

            //did it work?
            if (result.Approved)
            {
                order.Result.OrderStatus = OrderStatus.Succeeded;
            }
            else
            {
                order.StatusCode = 500;

                // the payment method used is not valid so it should not be attached to
                // the order. Clear it here and the change will be persisted later
                order.Result.UserCreditCardId = null;

                //gateway might be down
                if (result.ServiceUnavailable)
                {
                    order.Result.OrderStatus = OrderStatus.ServiceUnavailable;
                    order.Errors             = new ValidationResult[] {
                        new ValidationResult("Payment service is unavailable. Please try again later.", new string[] { "Order" })
                    };
                }
                //or it was declined
                else
                {
                    order.Result.OrderStatus = OrderStatus.CardDeclined;
                    order.Errors             = new ValidationResult[] {
                        new ValidationResult("Credit Card was declined", new string[] { "Order" })
                    };
                }
            }

            //update the order status
            using (var context = new RentlerContext())
            {
                var toUpdate = (from o in context.Orders
                                .Include("Building")
                                where o.OrderId == order.Result.OrderId
                                select o).SingleOrDefault();

                toUpdate.OrderStatus      = order.Result.OrderStatus;
                toUpdate.UserCreditCardId = order.Result.UserCreditCardId;

                //remove temporary order if we're good
                if (order.Result.OrderStatus == OrderStatus.Succeeded)
                {
                    toUpdate.Building.TemporaryOrderId = null;

                    // allow credit card to be used again if requested
                    if (isNewCard && saveCard)
                    {
                        context.Entry(toUpdate).Reference(o => o.UserCreditCard).Load();
                        toUpdate.UserCreditCard.IsDeleted = false;
                    }
                }

                context.SaveChanges();
            }

            // send receipt only if order was successful
            if (order.Result.OrderStatus == OrderStatus.Succeeded)
            {
                //send a receipt
                EmailOrderReceiptModel model = new EmailOrderReceiptModel()
                {
                    To         = order.Result.User.Email,
                    Name       = string.Format("{0} {1}", order.Result.User.FirstName, order.Result.User.LastName),
                    BuildingId = (order.Result.BuildingId.HasValue) ? order.Result.BuildingId.Value : 0,
                    OrderItems = order.Result.OrderItems.ToList(),
                    OrderTotal = order.Result.OrderTotal
                };
                mailer.Receipt(model);
            }

            return(order);
        }