public ActionResult GetAddtionalDetails(AddonDetailsDTO objAddons)
        {
            try
            {
                if (objAddons == null)
                {
                    return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
                }

                //Builds Reservation obj from objAddons param
                Reservation tempReservation = new Reservation
                {
                    Arrival          = objAddons.CheckIn,
                    Depature         = objAddons.CheckOut,
                    NoOfGuests       = objAddons.NoOfGuests,
                    RoomId           = objAddons.RoomId,
                    Room             = context.Rooms.Find(objAddons.RoomId),
                    UserId           = objAddons.UserId,
                    ApplicationUsers = context.Users.Find(objAddons.UserId),
                    BoardTypeId      = objAddons.BoardTypeId,
                    BoardType        = context.BoardTypes.Find(objAddons.BoardTypeId),
                };

                //Checks to see if there was any selected extras and adds them if so
                if (objAddons.SelectedExtra != null)
                {
                    foreach (int id in objAddons.SelectedExtra)
                    {
                        tempReservation.Extras.Add(context.Extras.Where(x => x.Id == id).FirstOrDefault());
                    }
                }

                //Buillds PaymentDetails object using Reservation Functions
                PaymentDetails objPaymentDTO = new PaymentDetails
                {
                    RoomCosts         = tempReservation.calculateRoomCosts(objAddons.Days),
                    BoardCosts        = tempReservation.CalculateBoardCosts(objAddons.Days),
                    BookingExtrasCost = tempReservation.CalculateBookingExtraCosts(objAddons.Days),
                    TotalCost         = tempReservation.CalculateBookingBill(objAddons.Days),
                    DepositToPay      = tempReservation.CalculateDepositAmount(objAddons.Days),
                };

                tempReservation.TotalBill = tempReservation.CalculateBookingBill(objAddons.Days);
                tempReservation.Deposit   = tempReservation.CalculateDepositAmount(objAddons.Days);


                Session["objAddon"] = objAddons;

                return(View("PaymentBill", objPaymentDTO));
            }
            catch (Exception ex)
            {
                this.AddNotification("", NotificationType.ERROR);
                ViewBag.Error = ("Error: " + Convert.ToString(ex));
                return(View("~/Views/Shared/Error.cshtml"));
            }
        }
        public ActionResult create(FormCollection collection)
        {
            try
            {
                var             obj     = Session["objAddon"] as AddonDetailsDTO;
                var             gateway = config.GetGateway();
                Decimal         amount;
                ApplicationUser user = context.Users.Find(User.Identity.GetUserId());

                //Setting up the new reservation that will be created
                Reservation newReservation = new Reservation
                {
                    Arrival    = obj.CheckIn,
                    Depature   = obj.CheckOut,
                    NoOfGuests = obj.NoOfGuests,
                    RoomId     = obj.RoomId,
                    Room       = context.Rooms.Find(obj.RoomId),

                    UserId           = obj.UserId,
                    ApplicationUsers = context.Users.Find(obj.UserId),
                    BoardTypeId      = obj.BoardTypeId,
                    BoardType        = context.BoardTypes.Find(obj.BoardTypeId),
                };

                if (obj.SelectedExtra != null)
                {
                    foreach (int id in obj.SelectedExtra)
                    {
                        newReservation.Extras.Add(context.Extras.Where(x => x.Id == id).FirstOrDefault());
                    }
                }


                newReservation.TotalBill = newReservation.CalculateBookingBill(obj.Days);
                newReservation.Deposit   = newReservation.CalculateDepositAmount(obj.Days);

                //Getting amount user to pay
                try
                {
                    amount = newReservation.Deposit;
                }
                catch (FormatException ex)
                {
                    ViewBag.Error = ("Error: " + Convert.ToString(ex));
                    return(View("~/Views/Shared/Error.cshtml"));
                }


                //Uses the users Id to retreive them if they have booked before
                var UserRequest = new CustomerSearchRequest().
                                  Id.Is(user.Id);
                ResourceCollection <Customer> Usercollection = gateway.Customer.Search(UserRequest);



                //Gets nonce for braintrees and makes transaction requests
                var nonce   = collection["payment_method_nonce"];
                var request = new TransactionRequest();



                //makes the correct type of request depending if a user has booked a room before or not
                if (Usercollection.Ids.Any())
                {
                    request = new TransactionRequest
                    {
                        Amount             = amount,
                        PaymentMethodNonce = nonce,
                        CustomerId         = user.Id, //user has booked before and uses their ID
                        Options            = new TransactionOptionsRequest
                        {
                            SubmitForSettlement = true,
                            StoreInVault        = true
                        }
                    };
                }
                else
                {
                    request = new TransactionRequest
                    {
                        Amount             = amount,
                        PaymentMethodNonce = nonce,
                        Customer           = new CustomerRequest //Adds customer since they have not booked before
                        {
                            FirstName = user.FirstName,
                            LastName  = user.LastName,
                            Email     = user.Email,
                            Phone     = user.PhoneNumber,
                            Id        = user.Id
                        },
                        BillingAddress = new AddressRequest
                        {
                            FirstName       = user.FirstName,
                            LastName        = user.LastName,
                            StreetAddress   = user.AddressFirstLine,
                            ExtendedAddress = user.Street,
                            Locality        = user.City,
                            PostalCode      = user.PostCode
                        },
                        Options = new TransactionOptionsRequest
                        {
                            SubmitForSettlement = true,
                            StoreInVault        = true
                        }
                    };
                }



                //Inisiates the sale
                Result <Transaction> result = gateway.Transaction.Sale(request);

                if (result.IsSuccess())
                {
                    this.AddNotification("Booked!", NotificationType.SUCCESS);
                    //Sets how much is left to pay, saves the reservation and context then returns sucess
                    newReservation.LeftToPay = (newReservation.TotalBill - newReservation.Deposit);
                    context.Reservations.Add(newReservation);
                    EmailDetails(newReservation).Wait();
                    context.SaveChanges();
                    return(View("Success"));
                }
                else if (result.Transaction != null)
                {
                    this.AddNotification("Payment rejected!", NotificationType.ERROR);
                    //Shows the client that their payment method has failed
                    ViewBag.Error = "Payment method has failed. Please Start Again";
                    return(View("~/Views/Shared/Error.cshtml"));
                }

                else
                {
                    //Handles all other errors
                    string errorMessages = "";
                    foreach (ValidationError error in result.Errors.DeepAll())
                    {
                        errorMessages += "Error: " + (int)error.Code + " - " + error.Message + "\n";
                    }
                    ViewBag.Error = errorMessages;
                    return(View("~/Views/Shared/Error.cshtml"));
                }
            }
            catch (Exception e)
            {
                this.AddNotification("", NotificationType.ERROR);
                ViewBag.Error = ("Error: " + Convert.ToString(e));
                return(View("~/Views/Shared/Error.cshtml"));
            }
        }