Beispiel #1
0
        private double GetProviderCleaningRate(PackageBaseData package)
        {
            // return .8; // 140.34 / formulaAverageT
            PricingVariables pricingvars = PricingVariables.FromPackageBaseData(package);

            return(pricingvars.GetValue <double>("CleaningRate", 1.0));
        }
Beispiel #2
0
        public void CalculateCustomerData(int customerID, PackageBaseData package, FeeRate fee, PricingModelData modelData, System.Web.WebPages.Html.ModelStateDictionary ModelState)
        {
            /* IMPORTANT: we calculate here the service duration for one session based on some custom variables for housekeeper pricing,
             * final price and fees are calculated in the standard code using the package Duration field, because of that
             * we only update package.Duration here for later complete price calculation */

            // Get customer input
            var nbeds  = Request[String.Format("bedrooms-number[{0}]", package.ID)].AsInt();
            var nbaths = Request[String.Format("bathrooms-number[{0}]", package.ID)].AsInt();
            // get provider rate
            var providerRate = GetProviderCleaningRate(package);
            // Apply formula, changed by the providerRate (variation from the average)
            var duration = ApplyFormula(nbeds, nbaths) * providerRate;
            // Create time object from duration, rounded to quarter-hours (15 minutes blocks)
            var timeDuration = ASP.LcHelpers.RoundTimeToQuarterHour(TimeSpan.FromMinutes(duration), ASP.LcHelpers.RoundingType.Up);

            // Create variables object with the specific data used in this calculation (will be saved later by the normal packages process)
            // Provider values get included in the object, something that is wanted for historic purposes on database.
            PricingVariables pricingvars = PricingVariables.FromPackageBaseData(package);

            pricingvars["BathsNumber"].Value = nbaths;
            pricingvars["BedsNumber"].Value  = nbeds;
            // Change package with the information:
            package.Duration        = timeDuration;
            modelData.ProviderInput = providerRate;
            modelData.CustomerInput = pricingvars;
        }
Beispiel #3
0
        public void SaveProviderData(PackageBaseData package, Database db)
        {
            var provTime = Request["provider-average-time"].AsFloat();
            var provRate = provTime / ApplyFormula();
            // Save rate on DB
            PricingVariables provars = PricingVariables.FromPackageBaseData(package);

            provars["CleaningRate"].Value = provRate;
            provars.Save();
        }
        public void CalculateCustomerData(int customerID, PackageBaseData package, FeeRate fee, PricingModelData modelData, System.Web.WebPages.Html.ModelStateDictionary ModelState)
        {
            /* IMPORTANT: we set here the service duration for one session based on the customer value (from the form),
             * update the hourly-price from provider variable value
             * and the hourly-surcharge based on the variables.
             * Final price and fees are calculated in the standard code using the package Duration field and HourlySurcharge field, because of that
             * the final price is not calculated here. */

            // TOREVIEW: Needs input data validation with ModelState and check ModelState.IsValid at LcPricingModel?

            // Getting variables
            PricingVariables pricingvars     = PricingVariables.FromPackageBaseData(package);
            TimeSpan         timeDuration    = TimeSpan.Zero;
            decimal          hourlySurcharge = 0;

            // Iterating customer variables:
            foreach (var pvar in pricingvars)
            {
                if (pvar.Value.Def.IsCustomerVariable)
                {
                    // Setting value from the form
                    pvar.Value.Value = LcUtils.GetTypedValue(Request[String.Format("{0}[{1}]", pvar.Key, package.ID)], null, pvar.Value.Def.DataType);
                    // For the 'Hours:2' customer variable, we get it form the form and set the duration with it.
                    if (pvar.Key == "Hours")
                    {
                        // Create time object from duration, rounded to quarter-hours (15 minutes blocks)
                        var duration = pvar.Value.GetValue <double>(0);
                        timeDuration = ASP.LcHelpers.RoundTimeToQuarterHour(TimeSpan.FromHours(duration), ASP.LcHelpers.RoundingType.Up);
                    }
                    else
                    {
                        // For other variables, we calculate it using the general formula and its added to the hourly surcharge
                        // Get the provider var, we need its values.
                        var provar = pricingvars.GetCalculateWithVariableFor(pvar.Value);
                        // General formula for 1 hour: (CustomerValueInputVariable - ProviderNumberIncludedVariable) * ProviderPriceVariable
                        // EXCEPT when CustomerValueInputVariable is equal or less than ProviderNumberIncludedVariable, then is 0
                        decimal amount = 0;
                        if (pvar.Value.GetValue <decimal>(0) > (provar.ProviderNumberIncluded ?? 0))
                        {
                            amount = (pvar.Value.GetValue <decimal>(0) - (provar.ProviderNumberIncluded ?? 0)) * provar.GetValue <decimal>(0);
                        }
                        // Add to the hourly surcharge
                        hourlySurcharge += amount;
                    }
                }
            }

            // Update package data:
            package.Duration        = timeDuration;
            package.HourlySurcharge = hourlySurcharge;
            modelData.CustomerInput = pricingvars;
        }
        public bool ValidateProviderData(PackageBaseData package, System.Web.WebPages.Html.ModelStateDictionary modelState)
        {
            var valid = true;
            PricingVariables provars = PricingVariables.FromPackageBaseData(package);

            foreach (var provar in provars)
            {
                if (provar.Value.Def.IsProviderVariable)
                {
                    // Validation: Emit error if there is not a value or is not of the desired type
                    if (String.IsNullOrWhiteSpace(Request[provar.Key + "-value"]))
                    {
                        modelState.AddError(provar.Key + "-value", LcRessources.RequiredField(provar.Value.Def.VariableLabel));
                        valid = false;
                    }
                    else if (!LcUtils.ValidateType(Request[provar.Key + "-value"], provar.Value.Def.DataType))
                    {
                        modelState.AddError(provar.Key + "-value", LcRessources.InvalidFieldValue(provar.Value.Def.VariableLabel));
                        valid = false;
                    }
                    // NO Validation: Detect pricing variable 'hourly rate' to copy the value to the standard field on package
                    // PricingVariableID:1 'hourly rate' for all positions and pricings.
                    // We need to do this data change on validation because the 'save' part happen after the package being saved (for good reasons)
                    if (provar.Value.PricingVariableID == 1)
                    {
                        package.PriceRate     = Request[provar.Key + "-value"].AsDecimal();
                        package.PriceRateUnit = "hour";
                    }
                    // Validation: Check the optional variable value properties (number, min, max)
                    if (!String.IsNullOrWhiteSpace(Request[provar.Key + "-numberincluded"]) &&
                        !Request[provar.Key + "-numberincluded"].IsDecimal())
                    {
                        modelState.AddError(provar.Key + "-numberincluded", String.Format("Invalid number for included '{0}'", provar.Value.Def.VariableNameSingular));
                        valid = false;
                    }
                    if (!String.IsNullOrWhiteSpace(Request[provar.Key + "-minnumberallowed"]) &&
                        !Request[provar.Key + "-minnumberallowed"].IsDecimal())
                    {
                        modelState.AddError(provar.Key + "-minnumberallowed", String.Format("Invalid number for '{0}'", provar.Value.Def.MinNumberAllowedLabel));
                        valid = false;
                    }
                    if (!String.IsNullOrWhiteSpace(Request[provar.Key + "-maxnumberallowed"]) &&
                        !Request[provar.Key + "-maxnumberallowed"].IsDecimal())
                    {
                        modelState.AddError(provar.Key + "-maxnumberallowed", String.Format("Invalid number for '{0}'", provar.Value.Def.MaxNumberAllowedLabel));
                        valid = false;
                    }
                }
            }
            return(valid);
        }
        /// <summary>
        /// Get variables given a package object that enables this to automatically get variables
        /// for a new package (when ID is 0) or the values for the existing package on other case.
        /// </summary>
        /// <param name="package">The package information used to discover what variables and values retrieve.</param>
        /// <returns></returns>
        public static PricingVariables FromPackageBaseData(PackageBaseData package)
        {
            PricingVariables provars;

            if (package.ID == 0)
            {
                provars = PricingVariables.ForNewProviderPackage(package.ProviderUserID, 0, package.PositionID, package.PricingTypeID);
            }
            else
            {
                provars = PricingVariables.FromUpdatedProviderPackage(package.ProviderUserID, package.ID, package.PositionID, package.PricingTypeID);
            }
            return(provars);
        }
        public void SaveProviderData(PackageBaseData package, Database db)
        {
            PricingVariables provars = PricingVariables.FromPackageBaseData(package);

            // Get values from for per variable
            foreach (var provar in provars)
            {
                if (provar.Value.Def.IsProviderVariable)
                {
                    // Value
                    provar.Value.Value = LcUtils.GetTypedValue(Request[provar.Key + "-value"], null, provar.Value.Def.DataType);
                    // Number Included
                    provar.Value.ProviderNumberIncluded = LcUtils.GetTypedValue <decimal>(Request[provar.Key + "-numberincluded"], 0);
                    // Min/Max allowed
                    provar.Value.ProviderMinNumberAllowed = LcUtils.GetTypedValue <decimal>(Request[provar.Key + "-minnumberallowed"], 0);
                    provar.Value.ProviderMaxNumberAllowed = LcUtils.GetTypedValue <decimal>(Request[provar.Key + "-maxnumberallowed"], 0);
                }
            }
            provars.Save();
        }
Beispiel #8
0
        public string GetCustomerHtml(int customerID, PackageBaseData package, FeeRate fee)
        {
            // get provider rate
            var providerRate = GetProviderCleaningRate(package);
            // Get HourlyRate for client-side calculation, and fees
            var price      = new Price(package.PriceRate ?? 0M, fee, 1);
            var hourlyFee  = price.FeePrice;
            var hourlyRate = price.TotalPrice;

            var s = new StringBuilder();

            s.AppendFormat("<div class='housekeeper-pricing' data-formula-a='{0}' data-formula-b='{1}' data-formula-c='{2}' data-hourly-rate='{3}' data-hourly-fee='{4}' data-provider-rate='{5}'>", formulaA, formulaB, formulaC, hourlyRate, hourlyFee, providerRate);
            s.Append(@"<div>Help us determine an accurate 
                <span class='has-tooltip' title='You and your provider will review this estimate and finalize before the work begins.'>
                price estimate</span></div>");

            s.AppendFormat(@"<div data-slider-value='3' data-slider-step='1' data-slider-stype='housekeeper' class='housekeeper-pricing-bedrooms customer-slider'><label>Bedrooms: <input name='bedrooms-number[{0}]' type='text' /></label></div>", package.ID);
            s.AppendFormat(@"<div data-slider-value='3' data-slider-step='1' data-slider-stype='housekeeper' class='housekeeper-pricing-bathrooms customer-slider'><label>Bathrooms: <input name='bathrooms-number[{0}]' type='text' /></label></div>", package.ID);
            s.Append("</div>");

            return(s.ToString());
        }
Beispiel #9
0
        public string GetProviderHtml(PackageBaseData package)
        {
            var s = new StringBuilder();

            // Get saved value for provider average-ratio
            var ratio = GetProviderCleaningRate(package);
            // Calculate time for the ratio
            var time = ratio * ApplyFormula();

            s.AppendFormat("<div class='housekeeper-pricing' data-slider-value='{0}' data-slider-step='{1}' data-slider-stype='housekeeper'>", ApplyFormula(), sliderStep);
            s.AppendFormat("<div class='label'>Average time to {0} clean a 2 bedroom/2 bathroom home: <span class='note has-tooltip' title='We use this to help us determine an accurate estimate. You and the client will review the estimate and finalize before you begin the work.'>Why are we asking this?</span></div>", type);
            s.AppendFormat(@"<div class='input'><input name='provider-average-time' type='text' value='{0}' />
                    <div class='provider-average-time'>
			            <div class='provider-average-time-slider'></div>
			            <label class='below-average-label'>Below average</label>
			            <label class='average-label'>Average</label>
			            <label class='above-average-label'>Above average</label>
		            </div>
                </div>", time);
            s.Append("<div class='preview'><span class='time'></span> (approximately)</div>");
            s.Append("</div>");

            return(s.ToString());
        }
Beispiel #10
0
 public string GetPackageViewHtml(PackageBaseData package, Dictionary <string, LcPricingModel.FeeRate> feesSet, bool forEmail = false)
 {
     // Nothing specific is required for housekeeper on the view
     return("");
 }
Beispiel #11
0
 public bool ValidateProviderData(PackageBaseData package, System.Web.WebPages.Html.ModelStateDictionary modelState)
 {
     return(Request["provider-average-time"].AsFloat() > 0);
 }
        public string GetCustomerHtml(int customerID, PackageBaseData package, FeeRate fee)
        {
            // Get variables
            PricingVariables provars = PricingVariables.FromPackageBaseData(package);

            // Update vars with customers values from its last estimate/booking?
            PricingVariables.UpdateWithLastCustomerValues(provars, customerID);

            var sv = new StringBuilder();

            // Iterating customer variables:
            foreach (var custvar in provars)
            {
                if (custvar.Value.Def.IsCustomerVariable)
                {
                    var    calculateWithVar = provars.GetCalculateWithVariableFor(custvar.Value);
                    var    provPrice        = new Price(calculateWithVar.GetValue <decimal>(0), fee, 1);
                    string footNoteFormat   = calculateWithVar.PricingVariableID == 1 ? "Base rate is {0:C} per hour" : "Add {0:C} per hour is for each additional {2}";
                    // If package already include an amount, notify it
                    if ((calculateWithVar.ProviderNumberIncluded ?? 0) > 0)
                    {
                        footNoteFormat = "Includes {1:#,##0.##} {3}--add {0:C}/hr for each add'l {2}";
                    }
                    string sliderFootnote = String.Format(footNoteFormat, provPrice.TotalPrice,
                                                          calculateWithVar.ProviderNumberIncluded, calculateWithVar.Def.VariableNameSingular,
                                                          calculateWithVar.Def.VariableNamePlural);

                    // We set the customer value as
                    // - the posted-form value,
                    // - else the db saved value (it works when variables get updated with its last estimate/booking values)
                    // - else the ProviderNumberIncluded for the var
                    // - else defaulted to zero:
                    var custValue = Request[String.Format("{1}[{0}]", package.ID, EncodeForHtml(custvar.Key))]
                                    .AsDecimal(custvar.Value.GetValue <decimal>(calculateWithVar.ProviderNumberIncluded ?? 0));

                    if (custvar.Key == "Hours")
                    {
                        sv.AppendFormat("<div class='customer-list' data-prov-value='{2}' data-slider-stype='hourly' data-slider-footnote='{3}'><label><span class='has-tooltip' title='{1}'>{0}</span>: {4}</div>",
                                        EncodeForHtml(custvar.Value.Def.VariableLabel),
                                        EncodeForHtml(custvar.Value.Def.VariableLabelPopUp),
                                        provPrice.BasePrice, // Gives to html the price without fees, that are calculated client-side
                                        EncodeForHtml(sliderFootnote),
                                        LcUtils.BuildHtmlSelect(
                                            String.Format("{1}[{0}]", package.ID, EncodeForHtml(custvar.Key)),
                                            custValue,
                                            LcUtils.GenerateKeyValueRange <string, object>(
                                                calculateWithVar.ProviderMinNumberAllowed ?? 0,
                                                (calculateWithVar.ProviderMaxNumberAllowed ?? 100) + .5M,
                                                .5M,
                                                custvar.Value.Def.VariableNameSingular,
                                                custvar.Value.Def.VariableNamePlural
                                                )
                                            )
                                        );
                    }
                    else
                    {
                        sv.AppendFormat(@"
                        <div class='customer-slider' data-prov-value='{2}'
                            data-slider-value='{5}' data-slider-step='{6}' data-slider-footnote='{7}' data-slider-stype='hourly'
                            data-slider-min='{8}' data-slider-max='{9}' data-slider-number-included='{10}' data-slider-labels-layout='{11}' data-slider-autosize='true'>
                        <label><span class='has-tooltip' title='{4}'>{3}</span>: <input name='{1}[{0}]' type='text' value='{5}' /></label></div>"
                                        , package.ID
                                        , EncodeForHtml(custvar.Key)
                                        , provPrice.BasePrice // Gives to html the price without fees, that are calculated client-side
                                        , EncodeForHtml(custvar.Value.Def.VariableLabel)
                                        , EncodeForHtml(custvar.Value.Def.VariableLabelPopUp)
                                        , custValue
                                        // slider step fixed to 1 for most cases, or .5 for Hours
                                        , custvar.Value.PricingVariableID == 2 ? .5 : 1
                                        , EncodeForHtml(sliderFootnote)
                                        , calculateWithVar.ProviderMinNumberAllowed
                                        , calculateWithVar.ProviderMaxNumberAllowed
                                        , calculateWithVar.ProviderNumberIncluded
                                        // special labels for Hours
                                        , custvar.Key == "Hours" ? "hours" : "standard");
                    }
                }
            }

            // Create html
            var h = new StringBuilder();

            h.AppendFormat("<div class='hourly-pricing' data-fee-rate='{0}' data-fixed-fee-amount='{1}'>", fee.Percentage, fee.Currency);
            h.Append(sv);
            h.Append("</div>");

            return(h.ToString());
        }
        public string GetPackageViewHtml(PackageBaseData package, Dictionary <string, LcPricingModel.FeeRate> feesSet, bool forEmail = false)
        {
            // NOTE: It follows the same base code than GetProviderHtml but replacing form elements by div/span and appling fees when customer

            // Get variables
            PricingVariables provars = PricingVariables.FromPackageBaseData(package);

            // Create html for form elements, variables values organized per sections
            var hValues       = new StringBuilder();
            var hSurcharges   = new StringBuilder();
            var hIncludes     = new StringBuilder();
            var hRestrictions = new StringBuilder();

            // Iterating provider variables:
            foreach (var provar in provars)
            {
                // A listing view of *the package* only shows provider variables for any user, since there is no customer values!
                if (provar.Value.Def.IsProviderVariable)
                {
                    // Showing the variable value.
                    // Avoid the 'hourly-rate' variable value, thats is showed already in a special way
                    // by the standard package code (using the copy at pak.PriceRate)
                    if (provar.Key != "HourlyRate")
                    {
                        // Provider variables *value*s are ever a price: if we have a feesSet, then
                        // we must apply fees because the view require show prices with fees (mostly when is
                        // the user who see the package, as in booking and public profile).
                        // To variables, we apply ever the standard fees, there is no chance for the flat ones.
                        // We follow the convention for hourly prices (since this are too per hour): 1 decimal position
                        var valuePrice = feesSet == null
                                         // Without fees, we apply a fee-rate of 0, and rounding to 1 decimal
                            ? new Price(provar.Value.GetValue <decimal>(0), 0, 1)
                                         // With fees, we apply that, rounding ever to 1 decimal
                            : new Price(provar.Value.GetValue <decimal>(0), feesSet["standard:customer"], 1);

                        if (!String.IsNullOrEmpty(provar.Value.Def.HourlySurchargeLabel))
                        {
                            hSurcharges.AppendFormat("<li>{1:c} {0}</li>",
                                                     EncodeForHtml(provar.Value.Def.HourlySurchargeLabel),
                                                     valuePrice.TotalPrice);
                        }
                        else
                        {
                            // Is not a surcharge, is a value
                            hValues.AppendFormat("<li>{0}: {1:c}</li>",
                                                 EncodeForHtml(provar.Value.Def.VariableLabel),
                                                 valuePrice.TotalPrice);
                        }
                    }
                    // Number Included
                    if (!String.IsNullOrEmpty(provar.Value.Def.NumberIncludedLabel) &&
                        provar.Value.ProviderNumberIncluded.HasValue &&
                        provar.Value.ProviderNumberIncluded.Value > 0)
                    {
                        hIncludes.AppendFormat("<li>{0} {1:#,##0.##} {2}</li>",
                                               EncodeForHtml(provar.Value.Def.NumberIncludedLabel),
                                               provar.Value.ProviderNumberIncluded.Value,
                                               provar.Value.ProviderNumberIncluded.Value != 1
                            ? EncodeForHtml(provar.Value.Def.VariableNamePlural)
                            : EncodeForHtml(provar.Value.Def.VariableNameSingular));
                    }
                    // Minimum number
                    if (!String.IsNullOrEmpty(provar.Value.Def.MinNumberAllowedLabel) &&
                        provar.Value.ProviderMinNumberAllowed.HasValue)
                    {
                        hRestrictions.AppendFormat("<li>{0} {1:#,##0.##} {2}</li>",
                                                   EncodeForHtml(provar.Value.Def.MinNumberAllowedLabel),
                                                   provar.Value.ProviderMinNumberAllowed,
                                                   provar.Value.ProviderMinNumberAllowed.Value != 1
                            ? EncodeForHtml(provar.Value.Def.VariableNamePlural)
                            : EncodeForHtml(provar.Value.Def.VariableNameSingular));
                    }
                    // Maximum number
                    if (!String.IsNullOrEmpty(provar.Value.Def.MaxNumberAllowedLabel) &&
                        provar.Value.ProviderMaxNumberAllowed.HasValue)
                    {
                        hRestrictions.AppendFormat("<li>{0} {1:#,##0.##} {2}</li>",
                                                   EncodeForHtml(provar.Value.Def.MaxNumberAllowedLabel),
                                                   provar.Value.ProviderMaxNumberAllowed,
                                                   provar.Value.ProviderMaxNumberAllowed.Value != 1
                            ? EncodeForHtml(provar.Value.Def.VariableNamePlural)
                            : EncodeForHtml(provar.Value.Def.VariableNameSingular));
                    }
                }
            }

            // Creating HTML
            var s = new StringBuilder();

            s.Append("<div class='hourly-pricing'>");
            if (hValues.Length > 0)
            {
                s.AppendFormat("<ul class='var-values' style='{0}'>", forEmail ? ASP.LcEmailTemplateHelper.ClassUlOl(false) : "");
                s.Append(hValues);
                s.Append("</ul>");
            }
            if (hIncludes.Length > 0)
            {
                s.AppendFormat("<h5 class='w-ProviderPackage-sectionTitle' style='{0}'>Includes:</h5>", forEmail ? ASP.LcEmailTemplateHelper.ClassH5() : "");
                s.AppendFormat("<ul class='var-includes' style='{0}'>", forEmail ? ASP.LcEmailTemplateHelper.ClassUlOl(false) : "");
                s.Append(hIncludes);
                s.Append("</ul>");
            }
            if (hSurcharges.Length > 0)
            {
                s.AppendFormat("<h5 class='w-ProviderPackage-sectionTitle' style='{0}'>Hourly surcharge(s):</h5>", forEmail ? ASP.LcEmailTemplateHelper.ClassH5() : "");
                s.AppendFormat("<ul class='var-surcharges' style='{0}'>", forEmail ? ASP.LcEmailTemplateHelper.ClassUlOl(false) : "");
                s.Append(hSurcharges);
                s.Append("</ul>");
            }
            if (hRestrictions.Length > 0)
            {
                s.AppendFormat("<h5 class='w-ProviderPackage-sectionTitle' style='{0}'>Booking restrictions:</h5>", forEmail ? ASP.LcEmailTemplateHelper.ClassH5() : "");
                s.AppendFormat("<ul class='var-restrictions' style='{0}'>", forEmail ? ASP.LcEmailTemplateHelper.ClassUlOl(false) : "");
                s.Append(hRestrictions);
                s.Append("</ul>");
            }
            s.Append("</div>");

            return(s.ToString());
        }
        public string GetProviderHtml(PackageBaseData package)
        {
            // Get variables
            PricingVariables provars = PricingVariables.FromPackageBaseData(package);

            // Create html for form elements, variables values organized per sections
            var hValues       = new StringBuilder();
            var hSurcharges   = new StringBuilder();
            var hIncludes     = new StringBuilder();
            var hRestrictions = new StringBuilder();

            // Iterating provider variables:
            foreach (var provar in provars)
            {
                if (provar.Value.Def.IsProviderVariable)
                {
                    if (!String.IsNullOrEmpty(provar.Value.Def.HourlySurchargeLabel))
                    {
                        hSurcharges.AppendFormat("<li><label>$ <input type='text' name='{1}-value' value='{3}' /> <span class='has-tooltip' title='{2}'>{0}</span></label></li>",
                                                 EncodeForHtml(provar.Value.Def.HourlySurchargeLabel),
                                                 EncodeForHtml(provar.Value.Def.InternalName), //==Key
                                                 EncodeForHtml(provar.Value.Def.VariableLabelPopUp),
                                                 Request[provar.Key + "-value"] ?? provar.Value.Value);
                    }
                    else
                    {
                        // Is not a surcharge, is a value
                        hValues.AppendFormat("<li><label><span class='has-tooltip' title='{2}'>{0}</span>: $ <input type='text' name='{1}-value' value='{3}' /></label></li>",
                                             EncodeForHtml(provar.Value.Def.VariableLabel),
                                             EncodeForHtml(provar.Value.Def.InternalName), //==Key
                                             EncodeForHtml(provar.Value.Def.VariableLabelPopUp),
                                             Request[provar.Key + "-value"] ?? provar.Value.Value);
                    }
                    if (!String.IsNullOrEmpty(provar.Value.Def.NumberIncludedLabel))
                    {
                        hIncludes.AppendFormat("<li><label>{0} <input type='text' name='{1}-numberincluded' value='{3}' /> <span class='has-tooltip' title='{2}'>{4}/{5}</span></label></li>",
                                               EncodeForHtml(provar.Value.Def.NumberIncludedLabel),
                                               EncodeForHtml(provar.Value.Def.InternalName), //==Key
                                               EncodeForHtml(provar.Value.Def.NumberIncludedLabelPopUp),
                                               (object)(Request[provar.Key + "-numberincluded"]) ?? provar.Value.ProviderNumberIncluded,
                                               EncodeForHtml(provar.Value.Def.VariableNameSingular),
                                               EncodeForHtml(provar.Value.Def.VariableNamePlural));
                    }
                    // Get min-max values list if available
                    var minMaxValuesList = String.IsNullOrWhiteSpace(provar.Value.Def.MinMaxValuesList)
                        ? null
                        : provar.Value.Def.GenerateMinMaxValuesCollection();
                    if (!String.IsNullOrEmpty(provar.Value.Def.MinNumberAllowedLabel))
                    {
                        string formControlHtml = "",
                               name            = provar.Key + "-minnumberallowed"; //==Value.Def.InternalName
                        var selectedValue      = (object)(Request[provar.Key + "-minnumberallowed"]) ?? provar.Value.ProviderMinNumberAllowed;

                        if (minMaxValuesList != null)
                        {
                            formControlHtml = LcUtils.BuildHtmlSelect(
                                name,
                                selectedValue,
                                minMaxValuesList);
                        }
                        else
                        {
                            formControlHtml = LcUtils.BuildHtmlInput(
                                name,
                                selectedValue);
                        }

                        hRestrictions.AppendFormat("<li><label><span class='has-tooltip' title='{2}'>{0}</span> {1}</label></li>",
                                                   EncodeForHtml(provar.Value.Def.MinNumberAllowedLabel),
                                                   formControlHtml,
                                                   EncodeForHtml(provar.Value.Def.MinNumberAllowedLabelPopUp));
                    }
                    if (!String.IsNullOrEmpty(provar.Value.Def.MaxNumberAllowedLabel))
                    {
                        string formControlHtml = "",
                               name            = provar.Key + "-maxnumberallowed"; //==Value.Def.InternalName
                        var selectedValue      = (object)(Request[provar.Key + "-maxnumberallowed"])
                                                 ?? provar.Value.ProviderMaxNumberAllowed
                                                 // Special default value for Max Hours #425
                                                 ?? (provar.Key == "HourlyRate" ? 8 : 0);
                        if (minMaxValuesList != null)
                        {
                            formControlHtml = LcUtils.BuildHtmlSelect(
                                name,
                                selectedValue,
                                minMaxValuesList);
                        }
                        else
                        {
                            formControlHtml = LcUtils.BuildHtmlInput(
                                name,
                                selectedValue);
                        }

                        hRestrictions.AppendFormat("<li><label><span class='has-tooltip' title='{2}'>{0}</span> {1}</label></li>",
                                                   EncodeForHtml(provar.Value.Def.MaxNumberAllowedLabel),
                                                   formControlHtml,
                                                   EncodeForHtml(provar.Value.Def.MaxNumberAllowedLabelPopUp));
                    }
                }
            }

            // Creating HTML
            var s = new StringBuilder();

            s.Append("<div class='hourly-pricing'>");
            if (hValues.Length > 0)
            {
                s.Append("<ul class='var-values'>");
                s.Append(hValues);
                s.Append("</ul>");
            }
            if (hIncludes.Length > 0)
            {
                s.Append("<h5>Includes:</h5>");
                s.Append("<ul class='var-includes'>");
                s.Append(hIncludes);
                s.Append("</ul>");
            }
            if (hSurcharges.Length > 0)
            {
                s.Append("<h5>Hourly surcharge(s):</h5>");
                s.Append("<ul class='var-surcharges'>");
                s.Append(hSurcharges);
                s.Append("</ul>");
            }
            if (hRestrictions.Length > 0)
            {
                s.Append("<h5>Booking restrictions:</h5>");
                s.Append("<ul class='var-restrictions'>");
                s.Append(hRestrictions);
                s.Append("</ul>");
            }
            s.Append("</div>");

            return(s.ToString());
        }