/// <summary>
        /// Get domain name with any "www" prefix removed
        /// </summary>
        protected override string GetDomainName(ItemData domainItem)
        {
            var baseDomainName = base.GetDomainName(domainItem);
            var domainName = baseDomainName.StartsWith("www")
                ? baseDomainName.Remove(0, 4)
                : baseDomainName;

            return domainName;
        }
        /// <summary>
        /// Use "CsLinuxWebsite" for connected packages that are allowed to have website, otherwise the default "CsDomainParking"
        /// </summary>
        protected override string GetAtomiaService(ItemData connectedItem)
        {
            if (IsHostingPackageWithWebsitesAllowed(connectedItem))
            {
                return "CsLinuxWebsite";
            }

            return DefaultAtomiaService;
        }
        /// <summary>
        /// Add extended item
        /// </summary>
        public void AddItemData(ItemData item)
        {
            if (itemData == null)
            {
                throw new ArgumentNullException("item");
            }

            itemData.Add(item);
        }
        /// <summary>
        /// Add ExtraServiceProperties from HostingPackages that are allowed to have website provisioned.
        /// </summary>
        protected override string GetAtomiaServiceExtraProperties(ItemData connectedItem)
        {
            if (IsHostingPackageWithWebsitesAllowed(connectedItem))
            {
                return base.GetAtomiaServiceExtraProperties(connectedItem);
            }

            return String.Empty;
        }
        /// <summary>
        /// Get matching item if it exists in order already. 
        /// Must match all of the following: article number, renewal period and "DomainName" custom attributes if it exists.
        /// </summary>
        /// <param name="order">The order to check</param>
        /// <param name="item">The item to check for match in order</param>
        /// <returns>The matching order item or null</returns>
        protected PublicOrderItem ExistingOrderItem(PublicOrder order, ItemData item)
        {
            PublicOrderItem existingOrderItem = null;
            var domainAttr = item.CartItem.CustomAttributes.FirstOrDefault(ca => ca.Name == "DomainName");

            if (domainAttr != null)
            {
                existingOrderItem = order.OrderItems.FirstOrDefault(orderItem =>
                    orderItem.ItemNumber == item.ArticleNumber &&
                    orderItem.RenewalPeriodId == item.RenewalPeriodId &&
                    orderItem.CustomData.Any(x => x.Name == "DomainName" && x.Value == domainAttr.Value));
            }
            else
            {
                existingOrderItem = order.OrderItems.FirstOrDefault(orderItem =>
                    orderItem.ItemNumber == item.ArticleNumber &&
                    orderItem.RenewalPeriodId == item.RenewalPeriodId);
            }

            return existingOrderItem;
        }
        /// <summary>
        /// Get domain name to add as custom attribute on the order item.
        /// </summary>
        protected virtual string GetDomainName(ItemData domainItem)
        {
            var domainNameAttr = domainItem.CartItem.CustomAttributes.FirstOrDefault(ca => ca.Name == "DomainName");

            if (domainNameAttr == null)
            {
                throw new InvalidOperationException("Domain registration cart item must have CustomAttribute \"DomainName\".");
            }

            var domainName = Normalize(domainNameAttr.Value);

            return domainName;
        }
 /// <summary>
 /// Helper method to check if HostingPackage product is allowed to have website provisioned by default.
 /// </summary>
 protected bool IsHostingPackageWithWebsitesAllowed(ItemData connectedItem)
 {
     return (connectedItem.Categories.Select(c => c.Name).Contains("HostingPackage") &&
             !connectedItem.Product.CustomAttributes.Any(ca => ca.Name == "nowebsites" && ca.Value.ToLowerInvariant() == "true"));
 }
 /// <summary>
 /// Get any custom attributes needed on the domain order item apart from AtomiaService and AtomiaServiceExtraProperties
 /// </summary>
 /// <param name="domainItem"></param>
 /// <returns></returns>
 protected virtual IEnumerable<PublicOrderItemProperty> GetExtraCustomData(ItemData domainItem)
 {
     return new List<PublicOrderItemProperty>();
 }
        /// <summary>
        /// Get any AtomiaServiceExtraProperties needed to provision connected item.
        /// </summary>
        /// <remarks>Added as custom attribute on domain order item</remarks>
        protected virtual string GetAtomiaServiceExtraProperties(ItemData connectedItem)
        {
            var extraProperties = String.Empty;

            if (connectedItem != null)
            {
                var extraPropertiesAttr = connectedItem.Product.CustomAttributes.FirstOrDefault(ca => ca.Name == "atomiaserviceextraproperties");
                if (extraPropertiesAttr != null)
                {
                    extraProperties = extraPropertiesAttr.Value;
                }
            }

            return extraProperties;
        }
 /// <summary>
 /// Get the service that should be used to provision any items connected to the domain item's domain name.
 /// </summary>
 /// <remarks>Added as custom attribute on domain order item</remarks>
 protected virtual string GetAtomiaService(ItemData connectedItem)
 {
     return DefaultAtomiaService;
 }
        /// <summary>
        /// Get any other items, like packages, that are connected to the domain item's domain name.
        /// </summary>
        protected virtual ItemData GetConnectedItem(IEnumerable<ItemData> allItems, ItemData domainItem, string domainName)
        {
            var connectedItem = allItems.FirstOrDefault(other =>
                    other.ArticleNumber != domainItem.ArticleNumber &&
                    other.CartItem.CustomAttributes.Any(ca => ca.Name == "DomainName" && ca.Value == domainName));

            return connectedItem;
        }
 /// <summary>
 /// Add custom attribute with authcode
 /// </summary>
 protected override IEnumerable<PublicOrderItemProperty> GetExtraCustomData(ItemData domainItem)
 {
     // TODO: Add authcode
     return base.GetExtraCustomData(domainItem);
 }
 /// <summary>
 /// Check if a matching item exists in order already.
 /// </summary>
 /// <param name="order">The order to check</param>
 /// <param name="item">The item to match</param>
 /// <returns>true if item matches, false otherwise</returns>
 protected bool OrderItemsContain(PublicOrder order, ItemData item)
 {
     return ExistingOrderItem(order, item) != null;
 }