public Document(BookingExtraSelection aBookingExtraSelection)
            {





            }
        /// <summary>
        /// There is only one template pattern at the moment - Standard template
        /// </summary>
        /// <param name="anEvent"></param>
        /// <param name="customer"></param>
        /// <param name="documentType"></param>
        /// <param name="booking"></param>
        /// <param name="bes"></param>
        public EventCommandSendEmail(Event anEvent, int EmailTemplateId, Customer customer, Booking booking = null, BookingExtraSelection bes = null)
        {
            this.Event = anEvent;
            this.customer = customer;           
            this.booking = booking;
            this.bes = bes;
            this.EmailTemplateId = EmailTemplateId;

        }
 public EventCommandCreateDocument(Event anEvent, Customer customer, PRCDocument.PRCDocumentType documentType, Booking booking = null, BookingExtraSelection bes = null)
 {
     //inject properties
     this.Event = anEvent;
     this.customer = customer;
     this.documentType = documentType;
     this.booking = booking;
     this.bes = bes;
 }
        public static List<BookingExtra> GetBookingExtrasFromBookingExtraSelection(BookingExtraSelection aBookingExtraSelection)
        {
            List<BookingExtra> aBookingExtra = new List<BookingExtra>();

            PortugalVillasContext _db = new PortugalVillasContext();

            aBookingExtra = _db.BookingExtras.Where(x => x.BookingExtraID == aBookingExtraSelection.BookingExtraID).ToList();

            return aBookingExtra;
        }
        public static string GetBookingExtraPRCReferenceFromID(BookingExtraSelection aBookingExtraSelection)
        {
            BookingExtra aBookingExtra = new BookingExtra();

            PortugalVillasContext _db = new PortugalVillasContext();

            aBookingExtra = _db.BookingExtras.Where(x => x.BookingExtraID == aBookingExtraSelection.BookingExtraID).FirstOrDefault();

            return aBookingExtra.LegacyReference;

        }
        public static BookingExtra GetBookingExtrasFromBookingExtraSelection(BookingExtraSelection aBookingExtraSelection)
        {
            BookingExtra aBookingExtra = new BookingExtra();

            PortugalVillasContext _db = new PortugalVillasContext();

            aBookingExtra = _db.BookingExtras.Where(x => x.BookingExtraID == aBookingExtraSelection.BookingExtraID).FirstOrDefault();

            return aBookingExtra;

        }
        public string GenerateBESReference(BookingExtraSelection bes, BookingExtra extra)
        {
            string reference = "";

          
            reference += extra.LegacyReference;
            reference += "/" + bes.BookingExtraSelectionID;
            reference += "/" + ((DateTime)bes.ExtraRentalDate).ToString("ddMMyyyy").Replace("/", "").Replace("-", "");


            return reference;
        }
        public ActionResult Create(BookingExtraSelection bookingextraselection)
        {
            if (ModelState.IsValid)
            {
                db.BookingExtraSelections.Add(bookingextraselection);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            ViewBag.BookingID = new SelectList(db.Bookings, "BookingID", "BookingPRCReference", bookingextraselection.BookingID);
            ViewBag.BookingExtraID = new SelectList(db.BookingExtras, "BookingExtraID", "LegacyReference", bookingextraselection.BookingExtraID);
            ViewBag.CustomerID = new SelectList(db.Customers, "CustomerID", "Title", bookingextraselection.CustomerID);
            return View(bookingextraselection);
        }
        public int SendEmail(string emailAddress, int emailEnumID, Booking booking = null, BookingExtraSelection bes = null)
        {
            try
            {
                //StandardEmailTemplate template = new StandardEmailTemplate(emailAddress, emailEnumID, customer, booking, bes);
                //template.SendEmail();

                return 0;
            }
            catch (Exception ex)
            {

                throw ex;
            }

        }
        public int SendEmailToCustomer(Customer customer, int EmailTemplateID, Booking booking = null, BookingExtraSelection bes = null)
        {
            try
            {
                StandardEmailTemplate template = new StandardEmailTemplate(customer.EmailAddress, EmailTemplateID, customer, booking, bes);
                template.SendEmail();

                return 0;
            }
            catch (Exception ex)
            {

                throw ex;
            }

        }
        public PRCDocument(Customer customer, PRCDocumentType type, Booking booking = null, BookingExtraSelection  bookingExtraSelection = null)
        {
            this.Type = type;

            this.MainDataTable = new DataTable();
            this.SecondaryDataTable = new DataTable();

            this.CustomerID = customer.CustomerID;
            if(booking != null)
            {
                BookingID = booking.BookingID;
            }
            if(bookingExtraSelection != null)
            {
                this.BookingExtraSelectionID = bookingExtraSelection.BookingExtraSelectionID;
            }

        }
 public EventManagementServiceBookingExtraSelection(BookingExtraSelection bes)
 {
     bes = bes;
 }
        /// <summary>
        /// Sends an email for 1*1 bookings or extrabookings
        /// </summary>
        /// <param name="customer"></param>
        /// <param name="booking"></param>
        /// <param name="bookingExtraSelection"></param>
        public StandardEmailTemplate(string toEmailAddress, int EmailTemplateID, Customer customer, Booking booking = null, BookingExtraSelection bookingExtraSelection = null)
        {

            EmailTemplate theTemplate;
            EmailTemplate Header;
            EmailTemplate Footer;

            using (PortugalVillasContext db = new PortugalVillasContext())
            {
                theTemplate = db.EmailTemplates.Find(EmailTemplateID);
                Header = db.EmailTemplates.Find(1);
                Footer = db.EmailTemplates.Find(2);
            }
            theAsposeMessage = new MailMessage();
            Property property = null;
            BookingExtra bookingExtra = null;

            EmailOutType theMainBody = new EmailOutType();

            //map all passed in object fields
            bool bookingToggle = false;
            bool bookingExtraToggle = false;
            bool combinedServicesToggle = false;


            //gets necessary

            //assign body
            if (booking == null)
            {
                bookingExtraToggle = true;
                bookingExtra = BookingExtra.GetBookingExtraByID(bookingExtraSelection.BookingExtraID);
                //theMainBody = new EmailOutType(EmailOutType.EmailOutEmailType.BookingExtraSelectionConfirm);
            }
            else if (booking != null && bookingExtraSelection == null)
            {
                bookingToggle = true;
                long propertyID = (long)booking.PropertyID;
                property = Property.GetPropertyByID(propertyID);
                //theMainBody = new EmailOutType(EmailOutType.EmailOutEmailType.BookingConfirm);//
            }
            else if (booking != null && bookingExtraSelection != null)
            {
                long propertyID = (long)booking.PropertyID;
                property = Property.GetPropertyByID(propertyID);
                bookingExtra = BookingExtra.GetBookingExtraByID(bookingExtraSelection.BookingExtraID);
                combinedServicesToggle = true;
                //theMainBody = new EmailOutType(EmailOutType.EmailOutEmailType.BookingAndBookingExtraSelectionConfirm);
            }







            //customer
            var customerFullName = customer.FirstName + " " + customer.LastName;

            //bookings and extras

            var prcRef = booking != null ? property.LegacyReference : bookingExtra.LegacyReference;

            string bookingPropertyOrSelectionName = booking != null ? property.PropertyName : bookingExtra.BookingExtraName;
            string bookingStartDate = booking != null ? Convert.ToDateTime(booking.StartDate.ToString()).ToString("dd/MM/yyyy") : Convert.ToDateTime(bookingExtraSelection.ExtraRentalDate.ToString()).ToString("dd/MM/yyyy");
            string bookingEndDate = booking != null ? Convert.ToDateTime(booking.EndDate.ToString()).ToString("dd/MM/yyyy") : new DateTime(1901, 01, 01).ToString("dd/MM/yyyy");
            string numberOfNights = booking != null ? booking.NumberOfNights.ToString() : "0";


            theAsposeMessage.To = customer.EmailAddress;
            theAsposeMessage.From = "*****@*****.**";

            theSMTPClient.Host = "smtp.gmail.com";
            theSMTPClient.Username = LoginEmailAddress;
            theSMTPClient.Password = EmailPassword;
            theSMTPClient.Port = 587;
            theSMTPClient.EnableSsl = true;
            theSMTPClient.SecurityMode = SmtpSslSecurityMode.Explicit;


            //set some email body   
            //set the body
            //subject
            //           
            theAsposeMessage.Subject = theTemplate.EmailSubject;
            theAsposeMessage.HtmlBody = "";

            //get correct email according to emailEnumID


            var temp = "";
            //string merges
            var fullName = customer != null ? customerFullName : "";
            var legacyRef = property != null ? property.LegacyReference : bookingExtra.LegacyReference;
            var bookStart = bookingStartDate != null ? bookingStartDate : "";
            var bookEnd = bookingEndDate != null ? bookingEndDate : "";
            var NoNights = numberOfNights != null ? numberOfNights : "";
            var reference = booking != null ? booking.BookingPRCReference : bookingExtraSelection.BookingExtraPRCReference;
            var bID = booking != null ? booking.BookingID.ToString() : "";
            var besID = bookingExtraSelection != null ? bookingExtraSelection.BookingExtraSelectionID.ToString() : "";
            
            var finalRentalPayment = booking != null ? booking.BookingPrice.ToString() : "";
            var finalRentalPaymentDate = "";
                if(booking != null)
                {
                   finalRentalPaymentDate =  booking.FinalRentalPaymentDueDate != null ? ((DateTime)booking.FinalRentalPaymentDueDate).ToString("dd/MM/yyyy") : "";
                }

            var rentalDeposit = booking != null ? booking.BreakageDeposit.ToString() : "";

            temp = String.Format(theTemplate.EmailTemplateBodyHTML, fullName, legacyRef, bookStart, bookEnd, NoNights, reference, finalRentalPaymentDate, bID, besID, finalRentalPayment, rentalDeposit);

            //booking request optional
            //if (bookingToggle == true && EmailTemplateID == 17)
            //{
            //    temp = String.Format(theTemplate.EmailTemplateBodyHTML, customerFullName, property.LegacyReference, bookingStartDate, bookingEndDate, numberOfNights, bookingExtraSelection.BookingExtraSelectionID);
            //}

            ////booking request forms standard
            //else if (bookingToggle == true // && EmailTemplateID == 3 || EmailTemplateID == 4 || EmailTemplateID == 5 || EmailTemplateID == 6
            //    )
            //{


            //    temp = String.Format(theTemplate.EmailTemplateBodyHTML, customerFullName, property.LegacyReference, booking.BookingPRCReference, ((DateTime)booking.FinalRentalPaymentDueDate).ToString("dd/MM/yyyy"));


            //}


            //else if (bookingExtraToggle == true)
            //{
            //    temp = String.Format(theTemplate.EmailTemplateBodyHTML, customerFullName, prcRef, bookingExtraSelection.BookingExtraSelectionID);

            //}
            //else if (combinedServicesToggle == true)
            //{
            //    temp = String.Format(theTemplate.EmailTemplateBodyHTML, customerFullName, booking.BookingID);

            //}






            //set the body
            var completeEmail = Header.EmailTemplateBodyHTML + temp + Footer.EmailTemplateBodyHTML;

            theAsposeMessage.HtmlBody = completeEmail;


        }
        public bool RemoveBookingExtraSelectionFromListInSession(BookingExtraSelection bookingExtraSelection)
        {

            try
            {


                //if the update's worked, delete the booking from the session, and update the currentBooking

                int? indexerToRemoveListOn = null;
                List<BookingExtraSelection> theExtraBookings = (List<BookingExtraSelection>)Session["Cart_ExtraBookings"];
                int? removeAt = null;

                foreach (var bookingToDelete in theExtraBookings)
                {
                    //if it all matchies, remove that booking
                    if (bookingExtraSelection.BookingExtraID == bookingToDelete.BookingExtraID && bookingExtraSelection.ExtraRentalDate == bookingToDelete.ExtraRentalDate)

                        if (
                            (bookingExtraSelection.ExtraReturnDate != null && bookingExtraSelection.BookingExtraID == bookingToDelete.BookingExtraID)
                            || bookingExtraSelection.ExtraReturnDate == null

                            )

                            indexerToRemoveListOn = theExtraBookings.IndexOf(bookingToDelete);

                    if (indexerToRemoveListOn != null)
                    {
                        removeAt = indexerToRemoveListOn;

                    }


                }

                theExtraBookings.RemoveAt((int)removeAt);
                Session["Cart_ExtraBookings"] = theExtraBookings;

                return true;

            }
            catch (Exception)
            {

                throw;
            }




        }
        /// <summary>
        /// Assigns Price To This Booking Extra Selection
        /// Check how many days for each booking (make sure the rental is done by days and not nights)
        /// Check which season each day falls under (e.g. the price)
        /// Divide that price by the requite amount and add that amount to the running total
        /// 
        /// 
        /// </summary>
        /// 
        public static decimal GetBookingExtraPrice(BookingExtraSelection bes, PortugalVillasContext _db)
        {
            decimal BESPrice = 0.00M; //reset any existing price

            var thisBookingExtraType = BookingExtraSelection.GetBookingExtrasFromBookingExtraSelection(bes);
            var thisBookingExtraTypeID = thisBookingExtraType.BookingExtraTypeID;

            try
            {
                //need to know what type it is - car rental prices by the day, rest have flat fee
                if (thisBookingExtraTypeID == 1)
                {

                    /*Low season Nov - Mar  
                   * Mid season Apr, May and Oct
                   * High Season June and Sept
                   * Peak season July and August
                   * 
                  */

                    
                    decimal runningTotal = 0.00M;

                    List<DateTime> DatesToCalulcuatePriceFor = new List<DateTime>();


                    DateTime CurrentDate = (DateTime)bes.ExtraRentalDate;

                    //we don't add the last day, because it needs to be returned on that day (they don't get charged)

                    while (CurrentDate < bes.ExtraReturnDate)
                    {
                        DatesToCalulcuatePriceFor.Add(CurrentDate);
                        CurrentDate = CurrentDate.AddDays(1);
                    }



                    

                    foreach (var day in DatesToCalulcuatePriceFor)
                    {



                        int monthThatTheRentalIsIn = ((DateTime)day).Month;

                        //check where the start date is - that's the season it's in
                        string SeasonOfRental = bes.GetRentalSeasonFromMonth(monthThatTheRentalIsIn);


                        switch (SeasonOfRental)
                        {
                            case "LowSeason":
                                bes.BESPrice = thisBookingExtraType.LowSeasonPrice;
                                break;
                            case "MidSeason":
                                bes.BESPrice = thisBookingExtraType.MidSeasonPrice;
                                break;
                            case "HighSeason":
                                bes.BESPrice = thisBookingExtraType.HighSeasonPrice;
                                break;
                            case "PeakSeason":
                                bes.BESPrice = thisBookingExtraType.PeakSeasonPrice;
                                break;
                            default:
                                bes.BESPrice = 0.00M;
                                break;

                        }

                        //now get the price per day
                        runningTotal += Convert.ToDecimal(bes.BESPrice / 7);


                    }

                    //all done, assign and exit
                    return Decimal.Round(runningTotal, 2);
                }


                //airport = nothing to do, fixed price

                //end airport

                //wine tours and tours - price is per person and depends on how many people are going
                else if (((new[] { 2, 4 }).Contains(Convert.ToInt32(thisBookingExtraTypeID))))
                {

              
                    int monthThatTheRentalIsIn = ((DateTime)bes.ExtraRentalDate).Month;

                    //check where the start date is - that's the season it's in
                    string SeasonOfRental = bes.GetRentalSeasonFromMonth(monthThatTheRentalIsIn);


                    var noOfPeopleOnThisTour = (bes.NumberOfAdults + bes.NumberOfChildren);


                    //get the list of all types for that and order correctly so lowest is first
                    List<BookingExtra> potentialPrices =
                        _db.BookingExtras.Where(
                            a => a.BookingExtraSubTypeID == thisBookingExtraType.BookingExtraSubTypeID).OrderBy(d => d.MaxPersons).ToList();


                    BookingExtra theCorrectPricing = null;

                    foreach (var potentialPrice in potentialPrices)
                    {
                        //get the minimum no of people left
                        if (noOfPeopleOnThisTour <= potentialPrice.MaxPersons)
                        {
                            theCorrectPricing = potentialPrice;
                            break;
                        }
                    }

                    decimal? individualPrice = 0.00M;

                    //get the correct season
                    switch (SeasonOfRental)
                    {
                        case "LowSeason":
                            individualPrice = theCorrectPricing.LowSeasonPrice;
                            break;
                        case "MidSeason":
                            individualPrice = theCorrectPricing.MidSeasonPrice;
                            break;
                        case "HighSeason":
                            individualPrice = theCorrectPricing.HighSeasonPrice;
                            break;
                        case "PeakSeason":
                            individualPrice = theCorrectPricing.PeakSeasonPrice;
                            break;
                        default:
                            individualPrice = 0.00M;
                            break;

                    }



                    // multiply number of people by price and we have a final price - for tours and wine tours


                    decimal? totalPriceToReturn = 0.00M;

                    if (thisBookingExtraType.BookingExtraTypeID == 2 || thisBookingExtraType.BookingExtraTypeID == 4)
                    {
                        totalPriceToReturn += noOfPeopleOnThisTour * individualPrice;
                    }
                    if (thisBookingExtraType.BookingExtraTypeID == 3)
                    {
                        totalPriceToReturn += individualPrice;
                    }

                    return Decimal.Round((decimal)totalPriceToReturn, 2);

                    //else return the group price (for airport transfers) - do nothing

                }

                    //airport transfers
                 else if (((new[] {3}).Contains(Convert.ToInt32(thisBookingExtraTypeID))))
                 {
                     int monthThatTheRentalIsIn = ((DateTime)bes.ExtraRentalDate).Month;

                     //check where the start date is - that's the season it's in
                     string SeasonOfRental = bes.GetRentalSeasonFromMonth(monthThatTheRentalIsIn);


                     var noOfPeopleOnThisTour = (bes.NumberOfAdults + bes.NumberOfChildren);


                     //get the list of all types for that and order correctly so lowest is first
                     List<BookingExtra> potentialPrices =
                         _db.BookingExtras
                         .Where(x => x.BookingExtraTypeID == thisBookingExtraType.BookingExtraTypeID)
                             .Where(x=>x.AirportPickupLocationID == bes.AirportPickupLocationID)
                             .OrderBy(d => d.MaxPersons).ToList();


                     BookingExtra theCorrectPricing = null;

                     foreach (var potentialPrice in potentialPrices)
                     {
                         //get the minimum no of people left
                         if (noOfPeopleOnThisTour <= potentialPrice.MaxPersons)
                         {
                             theCorrectPricing = potentialPrice;
                             break;
                         }
                     }

                     decimal? totalPriceToReturn = 0.00M;

                     //get the correct season
                     switch (SeasonOfRental)
                     {
                         case "LowSeason":
                             totalPriceToReturn = theCorrectPricing.LowSeasonPrice;
                             break;
                         case "MidSeason":
                             totalPriceToReturn = theCorrectPricing.MidSeasonPrice;
                             break;
                         case "HighSeason":
                             totalPriceToReturn = theCorrectPricing.HighSeasonPrice;
                             break;
                         case "PeakSeason":
                             totalPriceToReturn = theCorrectPricing.PeakSeasonPrice;
                             break;
                         default:
                             totalPriceToReturn = 0.00M;
                             break;

                     }

                     return Decimal.Round((decimal)totalPriceToReturn, 2);
                     
                 }
                //default
                else
                {
                    throw new Exception("Couldn't calculate a price for this BookingExtraSelection!!!");
                }



            }
            catch (Exception ex)
            {

                throw ex;
            }


        }
        public void AddExtraFormBookingToSession(BookingExtraSelection theExtraSelection)
        {
            if(theExtraSelection.BookingExtraID == 0)
            {
                //get the value from the session instead
                  if(Session["theCurrentExtraID"].ToString() != "")
                  {
                      theExtraSelection.BookingExtraID = (int)Session["theCurrentExtraID"];
                  }
                
            }


            //take the ExtraBooking and put it in the session
            try
            {

                //get the booking extra and extra type from the PRC Ref / Type
                /*var test = theExtraSelectionForm["ExtraRentalDate"].ToString();

                ///////////////////
                //// GENERAL ATTRIBUTES - COMMON
                ///////////////////

                //all

                theExtraSelection.ExtraRentalDate = DateTime.ParseExact(theExtraSelectionForm["ExtraRentalDate"].ToString(), "dd/MM/yyyy", CultureInfo.InvariantCulture);
                theExtraSelection.ExtraReturnDate = DateTime.ParseExact(theExtraSelectionForm["ExtraReturnDate"].ToString(), "dd/MM/yyyy", CultureInfo.InvariantCulture);
                
                theExtraSelection.NumberOfChildseats = Convert.ToInt16(theExtraSelectionForm["SpecialRequests"]);


                //cars
                theExtraSelection.SpecialRequests = theExtraSelectionForm["NumberOfChildseats"];
                

                //wine tourcs
                //theExtraSelection.

                //airport transfers
*/

                //tours


                //get any remaining fields
                BookingExtra theExtraType = db.BookingExtras.Find(theExtraSelection.BookingExtraID);
                theExtraSelection.BookingExtra = theExtraType;
                    //need to get PRCRef                             

                //calculate main and addition pricings and bes setup
                try
                {
                    theExtraSelection.BESPrice = BookingExtraSelection.GetBookingExtraPrice(theExtraSelection, db);
                

                    if (theExtraSelection.ExtraReturnDate != null)
                    {
                        theExtraSelection.NumberOfDays =
                            GeneralStaticHelperMethods.CalculateNoofDays(theExtraSelection.ExtraRentalDate,
                                theExtraSelection.ExtraReturnDate);
                    }
                    else
                    {
                        theExtraSelection.NumberOfDays = 1;
                    }

                    //this happens AFTER number of days has been calculated
                    theExtraSelection.BESExtraServicesPrice =
                        BookingExtraSelection.CalculateBookingExtraAdditionalCostsAndAssignToThisBooking(
                            theExtraSelection, db);    
                    
                
                }
                catch (Exception)
                {
                    
                    
                }

                //assign a guid for cart deletion
                theExtraSelection.BookingGuid = new Guid();
                theExtraSelection.BookingGuid = System.Guid.NewGuid();


                //1. Test if there are any bookings in the viewbag currently.
                if (AreThereAnyExtraBookingsInTheSession() > 0)
                {
                    //there are bookings in the viewbag, take the list, add another, put back in the bag
                    List<BookingExtraSelection> theSessionBookings = (List<BookingExtraSelection>)Session["Cart_ExtraBookings"];
                    theSessionBookings.Add(theExtraSelection);
                    Session["Cart_ExtraBookings"] = theSessionBookings;

                }
                else
                {
                    //there are no bookings in the viewbag - add a list of bookings with this CartBooking as the first booking
                    List<BookingExtraSelection> theSessionBookings = new List<BookingExtraSelection>();
                    theSessionBookings.Add(theExtraSelection);
                    Session["Cart_ExtraBookings"] = theSessionBookings;
                }



                string RootURL = Request.Url.Authority;
                RootURL += "/Home/BookCarRental";

                Response.Redirect("http://"+RootURL);



                /////////////
                //then put the extra selection into the ViewBag for later
                /////////////

            }
            catch (Exception ex)
            {
                throw ex;
            }




        }
        private string MergeDocumentWithDatabaseAndReturnFilePath(Customer customer, PRCDocument.PRCDocumentType type, Booking booking = null, BookingExtraSelection bes = null)
        {
            //BOOKING needs to have a propertyID, BES needs to have the ExtraID!!!!


            var db = new PortugalVillasContext();
            var bookPartTable = new DataTable();
            var besPartTable = new DataTable();
            var extraAttributes = new DataTable();

            PRCDocument aDocument = new PRCDocument(type);
            aDocument = InitialSetUpPRCDocument(type);

            //tables for merge

            List<DataTable> tablesForMerge_PreMerge = new List<DataTable>();


            PRCDocumentData theDocumentDataInstance = new PRCDocumentData();

            //PRC
            tablesForMerge_PreMerge.Add(
                theDocumentDataInstance.GetPRCDocumentData(
                    PRCDocumentData.PRCReturnDataTableWrapperTypes.StandardPRCInformation, 1));

            //CUSTOMERS
            tablesForMerge_PreMerge.Add(
                theDocumentDataInstance.GetPRCDocumentData(PRCDocumentData.PRCReturnDataTableWrapperTypes.CustomerByCustomerID,
                    customer.CustomerID)); //works*/
            //CUSTOMER BANK DETAILS
            
            
            
            if (booking != null)
            {
                tablesForMerge_PreMerge.Add(
                theDocumentDataInstance.GetPRCDocumentData(
                    PRCDocumentData.PRCReturnDataTableWrapperTypes.CustomerBankDetailByCustomerID, customer.CustomerID));


                //COMMISSION FOR YEAR            
                var TotalCommisssion = new DataTable();
                TotalCommisssion.Columns.Add("TotalCommissionThisYear");
                TotalCommisssion.Columns.Add("CommissionDateTime");
                DataRow _row = TotalCommisssion.NewRow();
                _row["TotalCommissionThisYear"] = db.Bookings.Where(x => x.PropertyID == booking.PropertyID).Sum(x => x.CommissionAmount);
                _row["CommissionDateTime"] = DateTime.Now.ToShortDateString();
                TotalCommisssion.Rows.Add(_row);

                tablesForMerge_PreMerge.Add(TotalCommisssion);

                //BOOKING
                tablesForMerge_PreMerge.Add(
                    theDocumentDataInstance.GetPRCDocumentData(PRCDocumentData.PRCReturnDataTableWrapperTypes.BookingByBookingID, booking.BookingID));


                //PROPERTY
                tablesForMerge_PreMerge.Add(
                    theDocumentDataInstance.GetPRCDocumentData(PRCDocumentData.PRCReturnDataTableWrapperTypes.PropertyByPropertyID,
                        (long)booking.PropertyID));


                //TOWN
                tablesForMerge_PreMerge.Add(
                    theDocumentDataInstance.GetPRCDocumentData(
                        PRCDocumentData.PRCReturnDataTableWrapperTypes.PropertyTownByPropertyTownID, Convert.ToInt64(db.Properties.Where(x => x.PropertyID == booking.PropertyID).FirstOrDefault().PropertyTownID)));

                //REGION
                tablesForMerge_PreMerge.Add(
                    theDocumentDataInstance.GetPRCDocumentData(
                        PRCDocumentData.PRCReturnDataTableWrapperTypes.PropertyRegionByPropertyRegionID, db.Properties.Where(x => x.PropertyID == booking.PropertyID).FirstOrDefault().PropertyTown.PropertyRegionID));

                //BOOKINGPART
                bookPartTable = theDocumentDataInstance.GetPRCDocumentData(
                    PRCDocumentData.PRCReturnDataTableWrapperTypes.BookingParticipantByBookingID, booking.BookingID);
                bookPartTable.TableName = "BOOKINGPARTTABLE";
                tablesForMerge_PreMerge.Add(bookPartTable);

                if (booking.BookingParentContainerID != null)
                {
                    //PARENT
                    tablesForMerge_PreMerge.Add(
                        theDocumentDataInstance.GetPRCDocumentData(
                            PRCDocumentData.PRCReturnDataTableWrapperTypes.StandardBookingParentContainer,
                            (long)booking.BookingParentContainerID));
                }




                BookingParentContainer bookingParentContainer;

                //PROPERTY OWNER
                tablesForMerge_PreMerge.Add(
              theDocumentDataInstance.GetPRCDocumentData(
                  PRCDocumentData.PRCReturnDataTableWrapperTypes.StandardPropertyOwner, (long)booking.PropertyID));
            }




            if (bes != null)
            {

                //get top level item for same sub type to pull out attributes:
                long? extraIDforAtts = null;

                try
                {
                    extraIDforAtts = db.BookingExtras.Where(x =>
                                    x.TopLevelItem == true)
                                    .Where(y => y.BookingExtraSubTypeID == bes.BookingExtra.BookingExtraSubTypeID)
                                    .FirstOrDefault().BookingExtraID;
                }
                catch (Exception)
                {
                     extraIDforAtts = db.BookingExtras.Where(x =>
                                    x.MaxPersons > 10)
                                    .Where(y => y.BookingExtraSubTypeID == bes.BookingExtra.BookingExtraSubTypeID)
                                    .FirstOrDefault().BookingExtraID;
                    
                }

                //BES
                tablesForMerge_PreMerge.Add(
                    theDocumentDataInstance.GetPRCDocumentData(
                        PRCDocumentData.PRCReturnDataTableWrapperTypes.BookingExtraSelectionByBookingExtraSelectionID, bes.BookingExtraSelectionID));

                //BEST PART (name etc)

                besPartTable = theDocumentDataInstance.GetPRCDocumentData(
                    PRCDocumentData.PRCReturnDataTableWrapperTypes.BookingExtraParticipantByBookingExtraSelectionID,
                    bes.BookingExtraSelectionID);
                besPartTable.TableName = "BESPARTTABLE";

                tablesForMerge_PreMerge.Add(besPartTable);
                //EXTRA
                tablesForMerge_PreMerge.Add(
                    theDocumentDataInstance.GetPRCDocumentData(
                        PRCDocumentData.PRCReturnDataTableWrapperTypes.BookingExtraByBookingExtraID, bes.BookingExtraID));

                //PARENT
                if (bes.BookingParentContainerID != null)
                {
                    tablesForMerge_PreMerge.Add(
                        theDocumentDataInstance.GetPRCDocumentData(
                      PRCDocumentData.PRCReturnDataTableWrapperTypes.StandardBookingParentContainer, (long)bes.BookingParentContainerID));
                }

                //ATTRIBUTES

                if (extraIDforAtts != null)
                {
                    extraAttributes = theDocumentDataInstance.GetPRCDocumentData(
                        PRCDocumentData.PRCReturnDataTableWrapperTypes.BookingExtraAttributesByBookingExtraID,
                        (long)extraIDforAtts);
                    extraAttributes.TableName = "ATTRIBUTETABLE";
                }


                //test if there is a related booking / property IF it's a solo BES event
                if(booking != null)
                {
                    if(bes.BookingParentContainerID != 0)
                    {
                        booking = db.Bookings.Where(x => x.BookingParentContainerID == bes.BookingParentContainerID).FirstOrDefault();

                        //PROPERTY
                        tablesForMerge_PreMerge.Add(
                            theDocumentDataInstance.GetPRCDocumentData(PRCDocumentData.PRCReturnDataTableWrapperTypes.PropertyByPropertyID,
                                (long)booking.PropertyID));


                        //TOWN
                        tablesForMerge_PreMerge.Add(
                            theDocumentDataInstance.GetPRCDocumentData(
                                PRCDocumentData.PRCReturnDataTableWrapperTypes.PropertyTownByPropertyTownID, Convert.ToInt64(db.Properties.Where(x => x.PropertyID == booking.PropertyID).FirstOrDefault().PropertyTownID)));

                        //REGION
                        tablesForMerge_PreMerge.Add(
                            theDocumentDataInstance.GetPRCDocumentData(
                                PRCDocumentData.PRCReturnDataTableWrapperTypes.PropertyRegionByPropertyRegionID, db.Properties.Where(x => x.PropertyID == booking.PropertyID).FirstOrDefault().PropertyTown.PropertyRegionID));

                    }


                }
            }








            List<DataTable> tablesForMerge = new List<DataTable>();

            foreach (var dataTable in tablesForMerge_PreMerge)
            {
                if (dataTable.Rows.Count > 0)
                {

                    DataTable tableToModAndReturn = dataTable.Copy();
                    //clone every table
                    DataTable dtCloned = dataTable.Copy();
                    //change every datetime column to a string

                    //for every dateTime colum, load into new table
                    foreach (DataColumn col in dtCloned.Columns)
                    {
                        var theType = dtCloned.Columns[col.ColumnName].DataType.ToString();

                        if (dtCloned.Columns[col.ColumnName].DataType.ToString() == "DateTime")
                        {
                            //change the type
                            var name = col.ColumnName;
                            var value = "";
                            if (dtCloned.Rows[0][col].ToString().Count() >= 10)
                            {
                                value = /*DateTime.Parse(*/ Convert.ToDateTime(dtCloned.Rows[0][col].ToString()).ToString("dd/MM/yyyy");
                                //).ToString("dd/MM/yyyy");
                            }


                            tableToModAndReturn.Columns.Remove(name);
                            tableToModAndReturn.Columns.Add(new DataColumn
                            {
                                ColumnName = name,
                                DefaultValue = value
                            });
                        }
                    }



                    tablesForMerge.Add(tableToModAndReturn);
                }
            }


            Aspose.Words.Document theDoc = new Aspose.Words.Document(HttpRuntime.AppDomainAppPath + aDocument.ServerDocumentURL);
            //execute the merges            
            foreach (var dataTable in tablesForMerge)
            {
                for (int i = 0; i < dataTable.Rows.Count; i++)
                {
                    theDoc.MailMerge.Execute(dataTable.Rows[i]);
                }
            }

            //N.B The regions in the document need to correspond to the table name for the below merge to work
            theDoc.MailMerge.ExecuteWithRegions(bookPartTable);
            theDoc.MailMerge.ExecuteWithRegions(besPartTable);
            theDoc.MailMerge.ExecuteWithRegions(extraAttributes);

            string filepathAndName = aDocument.SavePath + aDocument.FileName + ".pdf";
            theDoc.Save(aDocument.SavePath + aDocument.FileName + ".pdf");


            db.Dispose();


            return filepathAndName;
        }
        public void TestBookingExtraPrices()
        {
            var bse = new BookingExtraSelection()
            {
                AcceptTC = "true",
                BookingExtraID = 1,
                ExtraRentalDate = new DateTime(2014, 03, 26),
                ExtraReturnDate = new DateTime(2014, 04, 02)

            };



           /* bse.GetBookingExtraPriceAndAssignToThisBookingExtraSelection();*/



        }
        public static decimal CalculateBookingExtraAdditionalCostsAndAssignToThisBooking(BookingExtraSelection bookingExtraSelection, PortugalVillasContext _db)
        {
            /*Extra services
             * 8 = Detours
             * 9 = Child seats
             * 10 = extra luggage
             * 12 = Car rental child seats
             * */

            var serviceChargeInstances = PropertyTypeServicesChargeInstance.GetExtraTypeServicesChargeInstances();


            decimal additionalCost = 0.00M;

            switch (bookingExtraSelection.GetBookingExtraTypeIDFromBookingExtraSelection())
            {
                //specialist only for cars
                // it's PER DAY
                case 1:
                    {
                        additionalCost +=
                            (bookingExtraSelection.NumberOfChildseats *
                            serviceChargeInstances.First(x => x.PropertyTypeServicesID == 12).ServicePriceGBP) * bookingExtraSelection.NumberOfDays ?? 0.00M;

                       
                        break;
                    }
                // it's EACH WAY
                case 2:
                    {
                        additionalCost +=
                            (bookingExtraSelection.NumberOfChildseats *
                            serviceChargeInstances.First(x => x.PropertyTypeServicesID == 9).ServicePriceGBP) * 2 ?? 0.00M;
                        break;
                    }
                // it's EACH WAY
                case 3:
                    {
                        additionalCost +=
                            (bookingExtraSelection.NumberOfChildseats *
                            serviceChargeInstances.First(x => x.PropertyTypeServicesID == 9).ServicePriceGBP) * 2 ?? 0.00M;
                        break;
                    }
                // it's EACH WAY
                case 4:
                    {
                        additionalCost +=
                            (bookingExtraSelection.NumberOfChildseats *
                            serviceChargeInstances.First(x => x.PropertyTypeServicesID == 9).ServicePriceGBP) * 2 ?? 0.00M;
                        break;
                    }
            }


            //calcs across the board
            //detours
            // straight billing
            additionalCost +=
                  (bookingExtraSelection.Detours *
                  serviceChargeInstances.First(x => x.PropertyTypeServicesID == 10).ServicePriceGBP) ?? 0.00M;

            //extra luggage
            // it's EACH WAY
            additionalCost +=
                  (bookingExtraSelection.PiecesOfLuggage *
                  serviceChargeInstances.First(x => x.PropertyTypeServicesID == 8).ServicePriceGBP) * 2 ?? 0.00M;


            return (decimal)additionalCost;
        }
Example #20
0
        /// <summary>
        /// Assigns Price To This Booking Extra Selection
        /// Check how many days for each booking (make sure the rental is done by days and not nights)
        /// Check which season each day falls under (e.g. the price)
        /// Divide that price by the requite amount and add that amount to the running total
        ///
        ///
        /// </summary>
        ///
        public static decimal GetBookingExtraPrice(BookingExtraSelection bes, PortugalVillasContext _db)
        {
            decimal BESPrice = 0.00M; //reset any existing price

            var thisBookingExtraType   = BookingExtraSelection.GetBookingExtrasFromBookingExtraSelection(bes);
            var thisBookingExtraTypeID = thisBookingExtraType.BookingExtraTypeID;

            try
            {
                //need to know what type it is - car rental prices by the day, rest have flat fee
                if (thisBookingExtraTypeID == 1)
                {
                    /*Low season Nov - Mar
                     * Mid season Apr, May and Oct
                     * High Season June and Sept
                     * Peak season July and August
                     *
                     */


                    decimal runningTotal = 0.00M;

                    List <DateTime> DatesToCalulcuatePriceFor = new List <DateTime>();


                    DateTime CurrentDate = (DateTime)bes.ExtraRentalDate;

                    //we don't add the last day, because it needs to be returned on that day (they don't get charged)

                    while (CurrentDate < bes.ExtraReturnDate)
                    {
                        DatesToCalulcuatePriceFor.Add(CurrentDate);
                        CurrentDate = CurrentDate.AddDays(1);
                    }



                    foreach (var day in DatesToCalulcuatePriceFor)
                    {
                        int monthThatTheRentalIsIn = ((DateTime)day).Month;

                        //check where the start date is - that's the season it's in
                        string SeasonOfRental = bes.GetRentalSeasonFromMonth(monthThatTheRentalIsIn);


                        switch (SeasonOfRental)
                        {
                        case "LowSeason":
                            bes.BESPrice = thisBookingExtraType.LowSeasonPrice;
                            break;

                        case "MidSeason":
                            bes.BESPrice = thisBookingExtraType.MidSeasonPrice;
                            break;

                        case "HighSeason":
                            bes.BESPrice = thisBookingExtraType.HighSeasonPrice;
                            break;

                        case "PeakSeason":
                            bes.BESPrice = thisBookingExtraType.PeakSeasonPrice;
                            break;

                        default:
                            bes.BESPrice = 0.00M;
                            break;
                        }

                        //now get the price per day
                        runningTotal += Convert.ToDecimal(bes.BESPrice / 7);
                    }

                    //all done, assign and exit
                    return(Decimal.Round(runningTotal, 2));
                }


                //airport = nothing to do, fixed price

                //end airport

                //wine tours and tours - price is per person and depends on how many people are going
                else if (((new[] { 2, 4 }).Contains(Convert.ToInt32(thisBookingExtraTypeID))))
                {
                    int monthThatTheRentalIsIn = ((DateTime)bes.ExtraRentalDate).Month;

                    //check where the start date is - that's the season it's in
                    string SeasonOfRental = bes.GetRentalSeasonFromMonth(monthThatTheRentalIsIn);


                    var noOfPeopleOnThisTour = (bes.NumberOfAdults + bes.NumberOfChildren);


                    //get the list of all types for that and order correctly so lowest is first
                    List <BookingExtra> potentialPrices =
                        _db.BookingExtras.Where(
                            a => a.BookingExtraSubTypeID == thisBookingExtraType.BookingExtraSubTypeID).OrderBy(d => d.MaxPersons).ToList();


                    BookingExtra theCorrectPricing = null;

                    foreach (var potentialPrice in potentialPrices)
                    {
                        //get the minimum no of people left
                        if (noOfPeopleOnThisTour <= potentialPrice.MaxPersons)
                        {
                            theCorrectPricing = potentialPrice;
                            break;
                        }
                    }

                    decimal?individualPrice = 0.00M;

                    //get the correct season
                    switch (SeasonOfRental)
                    {
                    case "LowSeason":
                        individualPrice = theCorrectPricing.LowSeasonPrice;
                        break;

                    case "MidSeason":
                        individualPrice = theCorrectPricing.MidSeasonPrice;
                        break;

                    case "HighSeason":
                        individualPrice = theCorrectPricing.HighSeasonPrice;
                        break;

                    case "PeakSeason":
                        individualPrice = theCorrectPricing.PeakSeasonPrice;
                        break;

                    default:
                        individualPrice = 0.00M;
                        break;
                    }



                    // multiply number of people by price and we have a final price - for tours and wine tours


                    decimal?totalPriceToReturn = 0.00M;

                    if (thisBookingExtraType.BookingExtraTypeID == 2 || thisBookingExtraType.BookingExtraTypeID == 4)
                    {
                        totalPriceToReturn += noOfPeopleOnThisTour * individualPrice;
                    }
                    if (thisBookingExtraType.BookingExtraTypeID == 3)
                    {
                        totalPriceToReturn += individualPrice;
                    }

                    return(Decimal.Round((decimal)totalPriceToReturn, 2));

                    //else return the group price (for airport transfers) - do nothing
                }

                //airport transfers
                else if (((new[] { 3 }).Contains(Convert.ToInt32(thisBookingExtraTypeID))))
                {
                    int monthThatTheRentalIsIn = ((DateTime)bes.ExtraRentalDate).Month;

                    //check where the start date is - that's the season it's in
                    string SeasonOfRental = bes.GetRentalSeasonFromMonth(monthThatTheRentalIsIn);


                    var noOfPeopleOnThisTour = (bes.NumberOfAdults + bes.NumberOfChildren);


                    //get the list of all types for that and order correctly so lowest is first
                    List <BookingExtra> potentialPrices =
                        _db.BookingExtras
                        .Where(x => x.BookingExtraTypeID == thisBookingExtraType.BookingExtraTypeID)
                        .Where(x => x.AirportPickupLocationID == bes.AirportPickupLocationID)
                        .OrderBy(d => d.MaxPersons).ToList();


                    BookingExtra theCorrectPricing = null;

                    foreach (var potentialPrice in potentialPrices)
                    {
                        //get the minimum no of people left
                        if (noOfPeopleOnThisTour <= potentialPrice.MaxPersons)
                        {
                            theCorrectPricing = potentialPrice;
                            break;
                        }
                    }

                    decimal?totalPriceToReturn = 0.00M;

                    //get the correct season
                    switch (SeasonOfRental)
                    {
                    case "LowSeason":
                        totalPriceToReturn = theCorrectPricing.LowSeasonPrice;
                        break;

                    case "MidSeason":
                        totalPriceToReturn = theCorrectPricing.MidSeasonPrice;
                        break;

                    case "HighSeason":
                        totalPriceToReturn = theCorrectPricing.HighSeasonPrice;
                        break;

                    case "PeakSeason":
                        totalPriceToReturn = theCorrectPricing.PeakSeasonPrice;
                        break;

                    default:
                        totalPriceToReturn = 0.00M;
                        break;
                    }

                    return(Decimal.Round((decimal)totalPriceToReturn, 2));
                }
                //default
                else
                {
                    throw new Exception("Couldn't calculate a price for this BookingExtraSelection!!!");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Example #21
0
 internal static decimal?GetBookingExtraTotalServicesPrice(BookingExtraSelection bookingExtraSelection, PortugalVillasContext db)
 {
     return(bookingExtraSelection.BESPrice + bookingExtraSelection.BESExtraServicesPrice);
 }
Example #22
0
        public static decimal CalculateBookingExtraAdditionalCostsAndAssignToThisBooking(BookingExtraSelection bookingExtraSelection, PortugalVillasContext _db)
        {
            /*Extra services
             * 8 = Detours
             * 9 = Child seats
             * 10 = extra luggage
             * 12 = Car rental child seats
             * */

            var serviceChargeInstances = PropertyTypeServicesChargeInstance.GetExtraTypeServicesChargeInstances();


            decimal additionalCost = 0.00M;

            switch (bookingExtraSelection.GetBookingExtraTypeIDFromBookingExtraSelection())
            {
            //specialist only for cars
            // it's PER DAY
            case 1:
            {
                additionalCost +=
                    (bookingExtraSelection.NumberOfChildseats *
                     serviceChargeInstances.First(x => x.PropertyTypeServicesID == 12).ServicePriceGBP) * bookingExtraSelection.NumberOfDays ?? 0.00M;


                break;
            }

            // it's EACH WAY
            case 2:
            {
                additionalCost +=
                    (bookingExtraSelection.NumberOfChildseats *
                     serviceChargeInstances.First(x => x.PropertyTypeServicesID == 9).ServicePriceGBP) * 2 ?? 0.00M;
                break;
            }

            // it's EACH WAY
            case 3:
            {
                additionalCost +=
                    (bookingExtraSelection.NumberOfChildseats *
                     serviceChargeInstances.First(x => x.PropertyTypeServicesID == 9).ServicePriceGBP) * 2 ?? 0.00M;
                break;
            }

            // it's EACH WAY
            case 4:
            {
                additionalCost +=
                    (bookingExtraSelection.NumberOfChildseats *
                     serviceChargeInstances.First(x => x.PropertyTypeServicesID == 9).ServicePriceGBP) * 2 ?? 0.00M;
                break;
            }
            }


            //calcs across the board
            //detours
            // straight billing
            additionalCost +=
                (bookingExtraSelection.Detours *
                 serviceChargeInstances.First(x => x.PropertyTypeServicesID == 10).ServicePriceGBP) ?? 0.00M;

            //extra luggage
            // it's EACH WAY
            additionalCost +=
                (bookingExtraSelection.PiecesOfLuggage *
                 serviceChargeInstances.First(x => x.PropertyTypeServicesID == 8).ServicePriceGBP) * 2 ?? 0.00M;


            return((decimal)additionalCost);
        }
 public Document(BookingExtraSelection aBookingExtraSelection)
 {
 }
        public BookingExtraSelection CreateBookingExtraSelection(BookingExtraSelection bookingExtraSelection, BookingExtra extra, Customer theCustomer, PortugalVillasContext db)
        {
            bookingExtraSelection.BESCurrencyConversionSymbol = theCustomer.PreferredCurrencySymbol;
            bookingExtraSelection.BESPreferredCurrency = theCustomer.PreferredCurrency;

            var cc = new CurrencyConverterController();


            long? currentBookingTypeID = bookingExtraSelection.GetBookingExtraTypeIDFromBookingExtraSelection();
            bookingExtraSelection.CustomerID = theCustomer.CustomerID;

            //the price already needs to be assigned
            bookingExtraSelection.BESPrice = BookingExtraSelection.GetBookingExtraPrice(bookingExtraSelection, db);
            bookingExtraSelection.BESExtraServicesPrice = BookingExtraSelection.CalculateBookingExtraAdditionalCostsAndAssignToThisBooking(bookingExtraSelection, db);

            bookingExtraSelection.BESTotalServicesPrice = BookingExtraSelection.GetBookingExtraTotalServicesPrice(bookingExtraSelection, db);


            bookingExtraSelection.WhenCreated = DateTime.Now;

            //calc number of guests
            if (bookingExtraSelection.NumberOfGuests == null || bookingExtraSelection.NumberOfGuests == 0)
            {
                bookingExtraSelection.CalculateNoOfGuests();
            }

            //if not UK need to do currency conversion
            if (theCustomer.Country.ToLower() != "united kingdom" && ConfigurationManager.AppSettings["defaultCurrency"] == "GBP")
            {
                var baseCurrency = "GBP";
                var newCurrency = "EUR";

                var exchangeRateFromDB =
                    db.CurrencyExchanges.First(x => x.CurrencyExchangeName == "GBP-EUR");

                try
                {
                    bookingExtraSelection.BESPrice = cc.ConvertCurrency(baseCurrency, newCurrency, (decimal)bookingExtraSelection.BESPrice);
                    bookingExtraSelection.BESCurrencyConversionPrice = bookingExtraSelection.BESPrice;
                    bookingExtraSelection.BESExtraServicesPrice = cc.ConvertCurrency(baseCurrency, newCurrency, (decimal)bookingExtraSelection.BESExtraServicesPrice);
                    bookingExtraSelection.BESTotalServicesPrice = cc.ConvertCurrency(baseCurrency, newCurrency, (decimal)bookingExtraSelection.BESTotalServicesPrice);

                

                    //set exchange rate
                    bookingExtraSelection.BESCurrencyConversionSymbol = exchangeRateFromDB.CurrencyExchangeSymbol;
                    bookingExtraSelection.BESCurrencyExchangeRate = exchangeRateFromDB.CurrencyExchangeRate;
                    bookingExtraSelection.BESPreferredCurrency = "EUR";
                }
                catch (Exception)
                {

                    throw;
                }

            }

            else if (ConfigurationManager.AppSettings["defaultCurrency"] == "USD")
            {
                var baseCurrency = "GBP";
                var newCurrency = "USD";

                var exchangeRateFromDB =
                    db.CurrencyExchanges.First(x => x.CurrencyExchangeName == "GBP-USD");

                try
                {
                    bookingExtraSelection.BESPrice = cc.ConvertCurrency(baseCurrency, newCurrency, (decimal)bookingExtraSelection.BESPrice);
                    bookingExtraSelection.BESCurrencyConversionPrice = bookingExtraSelection.BESPrice;
                    bookingExtraSelection.BESExtraServicesPrice = cc.ConvertCurrency(baseCurrency, newCurrency, (decimal)bookingExtraSelection.BESExtraServicesPrice);
                    bookingExtraSelection.BESTotalServicesPrice = cc.ConvertCurrency(baseCurrency, newCurrency, (decimal)bookingExtraSelection.BESTotalServicesPrice);


                    //set exchange rate
                    bookingExtraSelection.BESCurrencyConversionSymbol = exchangeRateFromDB.CurrencyExchangeSymbol;
                    bookingExtraSelection.BESCurrencyExchangeRate = exchangeRateFromDB.CurrencyExchangeRate;
                    bookingExtraSelection.BESPreferredCurrency = "USD";
                }
                catch (Exception)
                {

                    throw;
                }
            }

            //generate reference
            var refGenService = new ReferenceGenerationService();
            bookingExtraSelection.BookingExtraPRCReference = refGenService.GenerateBESReference(bookingExtraSelection, extra);


            if (ModelState.IsValid)
            {
                db.BookingExtraSelections.Add(bookingExtraSelection);
                if (db.SaveChanges() > 0)
                {
                    //generate reference with ID
                    bookingExtraSelection.BookingExtraPRCReference = refGenService.GenerateBESReference(bookingExtraSelection, extra);

                    db.Entry(bookingExtraSelection).State = EntityState.Modified;
                    db.SaveChanges();
                    return bookingExtraSelection;

                }


            }
            throw new Exception();

        }
        public byte[] CreateDocument(Customer customer, PRCDocument.PRCDocumentType type, Booking booking = null, BookingExtraSelection bes = null)
        {
            try
            {
                PRCDocument aDocument = new PRCDocument(customer, type, booking, bes);

                var filepathAndName = MergeDocumentWithDatabaseAndReturnFilePath(customer, type, booking, bes);

                var documentBytes = System.IO.File.ReadAllBytes(filepathAndName);

                return documentBytes;
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        /// <summary>
        /// Booking Extra Particpant
        /// </summary>
        /// <returns></returns>
        public IEnumerable<BookingExtraParticipant> CreateBookingExtraParticipants(BookingExtraSelection theBookingExtraSelection, IEnumerable<BookingExtraParticipant> participants)
        {


            return participants;
        }
        public Event CreateBESEventViaFactory(long eventTypeID, BookingExtraSelection bes)
        {

            var returnEvent = CreateEventViaFactory(eventTypeID);
            returnEvent.BookingExtraSelectionID = bes.BookingExtraSelectionID;


            return returnEvent;
        }
 internal static decimal? GetBookingExtraTotalServicesPrice(BookingExtraSelection bookingExtraSelection, PortugalVillasContext db)
 {
     return bookingExtraSelection.BESPrice + bookingExtraSelection.BESExtraServicesPrice;
 }
        public void TestNewMailAllTemplates()
        {
            Customer testCust = new Customer();
            testCust.FirstName = "Test";
            testCust.LastName = "Customer";
            testCust.EmailAddress = "*****@*****.**";

            Booking booking = new Booking();
            booking.StartDate = new DateTime(2014, 01, 04);
            booking.EndDate = new DateTime(2014, 01, 10);
            booking.NumberOfNights = 5;
            booking.PropertyID = 220;
            booking.BookingID = 513;


            BookingExtraSelection bes = new BookingExtraSelection();
            bes.ExtraRentalDate = new DateTime(2014, 01, 04);
            bes.ExtraReturnDate = new DateTime(2014, 01, 09);
            bes.BookingExtraID = 1;
            bes.BookingExtraSelectionID = 1; //primary key





            EmailController ec = new EmailController();
            /*var ok = ec.SendEmailToCustomer(testCust, , booking, bes);
            ok = ec.SendEmailToCustomer(testCust, EmailOutType.EmailOutEmailType.BookingConfirm, booking);
            ok = ec.SendEmailToCustomer(testCust, EmailOutType.EmailOutEmailType.BookingExtraSelectionConfirm, null, bes);*/




        }
        public ActionResult AddExtraFormBookingToSession(FormCollection theExtraBooking)
        {
            //take the ExtraBooking and put it in the session
            try
            {
                BookingExtraSelection theExtraSelection = new BookingExtraSelection();

                //get the booking extra and extra type from the PRC Ref / Type

                ///////////////////
                //// GENERAL ATTRIBUTES - COMMON
                ///////////////////

                //identify WHAT the booking is

                if (theExtraBooking["BookingModalPRCReference"] != "" && theExtraBooking["BookingModalPRCReference"] != null)
                {
                    theExtraSelection.BookingExtraPRCReference = theExtraBooking["BookingModalPRCReference"].Trim();
                }

                //start date
                if (theExtraBooking["bookingModalStartDatePicker"] != "" && theExtraBooking["bookingModalStartDatePicker"] != null)
                {
                    theExtraSelection.ExtraRentalDate = DateTime.Parse(theExtraBooking["bookingModalStartDatePicker"]);
                }

                //end date
                if (theExtraBooking["bookingModalEndDatePicker"] != "" && theExtraBooking["bookingModalEndDatePicker"] != null)
                {
                    theExtraSelection.ExtraReturnDate = DateTime.Parse(theExtraBooking["bookingModalEndDatePicker"]);
                }

                //Adults
                if (theExtraBooking["bookingModalNumberOfAdults"] != "" && theExtraBooking["bookingModalNumberOfAdults"] != null)
                {
                       theExtraSelection.NumberOfAdults = Int32.Parse(theExtraBooking["bookingModalNumberOfAdults"]);
                }

                //Children
                if (theExtraBooking["bookingModalNumberOfChildren"] != "" && theExtraBooking["bookingModalNumberOfChildren"] != null)
                {
                    theExtraSelection.NumberOfChildren = Int32.Parse(theExtraBooking["bookingModalNumberOfChildren"]);
                }

                //Infants
                if (theExtraBooking["bookingModalNumberOfInfants"] != "" && theExtraBooking["bookingModalNumberOfInfants"] != null)
                {
                    theExtraSelection.NumberOfInfants = Int32.Parse(theExtraBooking["bookingModalNumberOfInfants"]);
                }

                //child seats
                if (theExtraBooking["bookingModalNumberOfChildSeats"] != "" && theExtraBooking["bookingModalNumberOfChildSeats"] != null && theExtraBooking["bookingModalNumberOfChildSeats"] != "0")
                {
                    theExtraSelection.NumberOfChildseats = Int32.Parse(theExtraBooking["bookingModalNumberOfChildSeats"]);
                }

                ///////////end

                /////////////////
                ////// CARS ///////
                ///////////////////

                //passport number
                if (theExtraBooking["bookingModalPassportNumber"] != "" && theExtraBooking["bookingModalPassportNumber"] != null)
                {
                    theExtraSelection.PassportNumber = theExtraBooking["bookingModalPassportNumber"].ToString();
                }

                //driving licence
                if (theExtraBooking["bookingModalDrivingLicence"] != "" && theExtraBooking["bookingModalDrivingLicence"] != null)
                {
                    theExtraSelection.DrivingLicenceNumber = theExtraBooking["bookingModalDrivingLicence"].ToString();
                }

                ////////////////
                // AIRPORT TRANSFER
                ///////////////

                //pick up location
                if (theExtraBooking["bookingModalPickUpLocation"] != "" && theExtraBooking["bookingModalPickUpLocation"] != null)
                {
                    theExtraSelection.PickupLocation = theExtraBooking["bookingModalPickUpLocation"].ToString();
                }

                //drop off location
                if (theExtraBooking["bookingModalDropOffLocation"] != "" && theExtraBooking["bookingModalDropOffLocation"] != null)
                {
                    theExtraSelection.DropoffLocation = theExtraBooking["bookingModalDropOffLocation"].ToString();
                }

                //arrival fields
                if (theExtraBooking["bookingModalFlightArrivalTerminalNumber"] != "" && theExtraBooking["bookingModalFlightArrivalTerminalNumber"] != null)
                {
                    theExtraSelection.FlightArrivalTerminalNumber = theExtraBooking["bookingModalFlightArrivalTerminalNumber"].ToString();
                }

                if (theExtraBooking["bookingModalFlightArrivalTime"] != "" && theExtraBooking["bookingModalFlightArrivalTime"] != null)
                {
                    theExtraSelection.FlightArrivalTime = theExtraBooking["bookingModalFlightArrivalTime"].ToString();
                }

                //////////////////
                //departure fields
                //////////////////

                if (theExtraBooking["bookingModalFlightDepartureTime"] != "" && theExtraBooking["bookingModalFlightDepartureTime"] != null)
                {
                    theExtraSelection.FlightDepartureTime = theExtraBooking["bookingModalFlightDepartureTime"].ToString();
                }

                if (theExtraBooking["bookingModalFlightDepartureTerminalNumber"] != "" && theExtraBooking["bookingModalFlightDepartureTerminalNumber"] != null)
                {
                    theExtraSelection.FlightArrivalTerminalNumber = theExtraBooking["bookingModalFlightDepartureTerminalNumber"].ToString();
                }

                //get any remaining fields

                //get the BookingExtraID from the parsed reference
                 theExtraSelection.BookingExtraID = BookingExtra.GetBookingExtraIDByPRCReference(theExtraSelection.BookingExtraPRCReference);

                //convert into a cart format
                 //Booking CartBooking = ConvertPropertyFormBookingToCartBooking(theBooking);

                 //1. Test if there are any bookings in the viewbag currently.
                 if (AreThereAnyBookingsInTheSession() > 0)
                 {
                     //there are bookings in the viewbag, take the list, add another, put back in the bag
                     List<BookingExtraSelection> theSessionBookings = (List<BookingExtraSelection>)Session["Cart_ExtraBookings"];
                     theSessionBookings.Add(theExtraSelection);
                     Session["Cart_ExtraBookings"] = theSessionBookings;

                 }
                 else
                 {
                     //there are no bookings in the viewbag - add a list of bookings with this CartBooking as the first booking
                     List<BookingExtraSelection> theSessionBookings = new List<BookingExtraSelection>();
                     theSessionBookings.Add(theExtraSelection);
                     Session["Cart_ExtraBookings"] = theSessionBookings;
                 }

                 return RedirectToAction("BookCarRental", "Home");

                /////////////
                //then put the extra selection into the ViewBag for later
                /////////////

            }

            catch (Exception ex) {
                throw ex;
            }

            finally {
            //do nothing
            }
        }
        public ActionResult DetailGatheringEventChain()
        {
            //create the lists we need 

            Dictionary<BookingDataCollectionEventType.Types, BookingDataCollectionEventType.PRCDataGatheringControllerActionRedirect> DataThatNeedsGetting = CreateListOfFieldsToGatherBasedOnSessionData();

            foreach (var dataRedirect in DataThatNeedsGetting)
            {
                //if it's a booking or an extra, whack it into the session so we know which one we're using and can pull the vars                

                if (dataRedirect.Key == BookingDataCollectionEventType.Types.Booking)
                {

                    Session["CurrentBookingDataGathering"] = new Booking
                    {
                        PropertyID = (long?)dataRedirect.Value.PropertyID,
                        BookingPRCReference = dataRedirect.Value.PRCRef.ToString(),
                        StartDate = dataRedirect.Value.StartDate,
                        EndDate = dataRedirect.Value.EndDate,
                        ExtraLininSet = dataRedirect.Value.NoLinen,
                        SwimmingPoolHeating = dataRedirect.Value.NoSwimmingPool,
                        // SpecialRequests = dataRedirect.Value.SpecialRequests,
                        NoOfTowelsRequested = dataRedirect.Value.NoTowels,
                        BookingPrice = dataRedirect.Value.Price


                    };
                }
                else if (dataRedirect.Key == BookingDataCollectionEventType.Types.BookingExtraSelection)
                {
                    Session["CurrentBookingExtraDataGathering"] = new BookingExtraSelection
                    {
                        BookingExtraPRCReference = dataRedirect.Value.PRCRef.ToString(),
                        ExtraRentalDate = dataRedirect.Value.StartDate,
                        ExtraReturnDate = dataRedirect.Value.EndDate,
                        BookingExtraID = (long)dataRedirect.Value.ExtraTypeID,
                        BESPrice = dataRedirect.Value.Price
                    };

                }

                return RedirectToAction(dataRedirect.Value.Action, dataRedirect.Value.Controller);
            }



            //populate the session items with those lists






            if (DataThatNeedsGetting.Count == 0)
            //we're done
            {
                return View();
            }
            //remove all items from our list that need gathering

            //end


            return RedirectToAction("DetailGatheringEventChain");


        }
        //Returns local filepath and file name of the document
        public string CreateDocumentToFileSystem(Customer customer, PRCDocument.PRCDocumentType type, Booking booking = null, BookingExtraSelection bes = null)
        {
            try
            {
                PRCDocument aDocument = new PRCDocument(customer, type, booking, bes);

                var filepathAndName = MergeDocumentWithDatabaseAndReturnFilePath(customer, type, booking, bes);

                return filepathAndName;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }