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 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());
        }