/// <summary>
        /// Get the availability details for a fixture-package combination
        /// </summary>
        /// <param name="product">The product object</param>
        /// <param name="packageID">Provide the PackageID when product is given</param>
        /// <param name="package">The package details object</param>
        /// <param name="componentList">List of components for selected package</param>
        /// <returns>AvailabilityDetails object containing details of availability for fixture-package combination</returns>
        private AvailabilityDetails getAvailabilityDetails(PackageDetails package, List <ComponentDetails> componentList)
        {
            AvailabilityDetails availabilityDetail = new AvailabilityDetails();
            Availability        av                  = new Availability();
            decimal             minCapacity         = 999;
            decimal             minAvailable        = 999;
            decimal             percentageRemaining = 0;
            string availabilityColour               = string.Empty;
            string availabilityText                 = string.Empty;
            string availabilityCSS                  = string.Empty;
            string stadiumCode          = Environment.Settings.DefaultValues.CorporateStadium;
            string businessunit         = Environment.Settings.BusinessUnit;
            long   seatBasedComponentID = 0;


            // Loop through components and set the package capacity and available units to that of the last available component
            availabilityDetail.SoldOutComponents = string.Empty;
            foreach (ComponentDetails component in componentList)
            {
                if (component.IsSeatComponent)
                {
                    seatBasedComponentID = component.ComponentID;
                    if (component.ComponentType == "A")
                    {
                        availabilityDetail.AvailabilityComponentID = component.ComponentID;
                    }
                    var availableUnits = Environment.Settings.DESettings.IsAgent ? component.AvailableUnitsBUI : component.AvailableUnitsPWS;
                    if (availableUnits < minAvailable)
                    {
                        minAvailable = availableUnits;
                    }
                    if (component.OriginalUnits < minCapacity)
                    {
                        minCapacity = component.OriginalUnits;
                    }
                    if (availableUnits == 0)
                    {
                        //add a comma after the first component description
                        if (availabilityDetail.SoldOutComponents.Length > 0)
                        {
                            availabilityDetail.SoldOutComponents = string.Concat(availabilityDetail.SoldOutComponents, ", ");
                        }
                        availabilityDetail.SoldOutComponents = string.Concat(availabilityDetail.SoldOutComponents, component.ComponentDescription);
                    }
                }
            }

            // If PWS may only be able to sell up to a % of what was originally available (maintained on jwalk web product maint and is Capacity Limit %)
            // If this is set reduce available qty and origianal qty as these were never available for PWS
            if (package.MaxPercentageToSellPWS != 0 && package.MaxPercentageToSellPWS != 0 && !Environment.Settings.DESettings.IsAgent)
            {
                decimal numberPackageUnitsReservedForBoxOffice = Math.Ceiling(minCapacity * (100 - package.MaxPercentageToSellPWS) / 100);
                minAvailable -= numberPackageUnitsReservedForBoxOffice;
                if (minAvailable < 0)
                {
                    minAvailable = 0;
                }
                minCapacity -= numberPackageUnitsReservedForBoxOffice;
                if (minCapacity < 0)
                {
                    minCapacity = 0;
                }
            }

            // We need a component to pass to the backend - if availability defined use that otherwise use a seat based one we found
            if (availabilityDetail.AvailabilityComponentID == 0)
            {
                availabilityDetail.AvailabilityComponentID = seatBasedComponentID;
            }
            availabilityDetail.AvailableUnits = Convert.ToInt16(minAvailable);
            availabilityDetail.OriginalUnits  = Convert.ToInt16(minCapacity);
            if (availabilityDetail.OriginalUnits > 0 && availabilityDetail.AvailableUnits > 0)
            {
                percentageRemaining = ((decimal)availabilityDetail.AvailableUnits / (decimal)availabilityDetail.OriginalUnits) * 100;
            }
            availabilityDetail.PercentageRemaining   = Convert.ToInt16(Math.Round(percentageRemaining, 0));
            availabilityDetail.HaveSoldOutComponents = false;
            if (percentageRemaining == 0)
            {
                availabilityDetail.HaveSoldOutComponents = true;
            }

            //Get the stadium based availability properties
            av.GetAvailabilityProperties(businessunit, ref availabilityText, ref availabilityCSS, ref availabilityColour, availabilityDetail.PercentageRemaining, stadiumCode);
            availabilityDetail.AvailabilityText     = availabilityText;
            availabilityDetail.AvailabilityCSS      = availabilityCSS;
            availabilityDetail.AvailabilityColour   = availabilityColour;
            availabilityDetail.ComponentListDetails = componentList;
            availabilityDetail.Sold      = package.Sold;
            availabilityDetail.Cancelled = package.Cancelled;
            availabilityDetail.Reserved  = package.Reserved;
            return(availabilityDetail);
        }