示例#1
0
    /// <summary>
    /// Overrides OnPreInit method.
    /// </summary>
    protected override void OnPreInit(EventArgs e)
    {
        base.OnPreInit(e);

        // Initialize creation of a new variants
        GlobalObjectsKeyName = ECommerceSettings.ALLOW_GLOBAL_PRODUCTS;

        // Check if product belongs to current site
        var product = EditedObject as SKUInfo;

        if (product != null)
        {
            CheckEditedObjectSiteID(product.SKUSiteID);
        }

        mAllCategoriesOptions     = new List <Tuple <OptionCategoryInfo, List <SKUInfo> > >();
        mVariantCategoriesOptions = new List <Tuple <OptionCategoryInfo, List <SKUInfo> > >();

        // Get all enabled product option attribute categories plus option categories used in variants
        DataSet allCategoriesDS = VariantHelper.GetUsedProductOptionCategories(ProductID, OptionCategoryTypeEnum.Attribute);

        // Get all product options categories which are already in variants
        DataSet variantCategoriesDS = VariantHelper.GetProductVariantsCategories(ProductID);

        // Fill categories lists
        FillCategoriesOptions(mAllCategoriesOptions, allCategoriesDS);
        FillCategoriesOptions(mVariantCategoriesOptions, variantCategoriesDS);

        // Pass data to controls
        VariantFilter.ExternalDataSource          = CategorySelector.AllCategoriesOptions = mAllCategoriesOptions.ToDictionary(c => c.Item1, c => c.Item2);;
        CategorySelector.VariantCategoriesOptions = mVariantCategoriesOptions.ToDictionary(c => c.Item1, c => c.Item2);;
    }
示例#2
0
        /// <summary>
        /// Returns an enumerable collection of all variants of the given product.
        /// </summary>
        /// <param name="productId">SKU object identifier of the variant's parent product.</param>
        /// <returns>Collection of product variants. See <see cref="ProductVariant"/> for detailed information.</returns>
        public IEnumerable <ProductVariant> GetByProductId(int productId)
        {
            var variantSKUs = VariantHelper.GetVariants(productId).OnSite(SiteContext.CurrentSiteID).ToList();

            // Create variants with the options
            return(variantSKUs.Select(sku => new ProductVariant(sku.SKUID)));
        }
    /// <summary>
    /// Gets the options with names from external data source or database.
    /// </summary>
    /// <param name="skuIdOfProductWithCategories">Id of product with categories.</param>
    /// <param name="categoryId">The category id.</param>
    private Dictionary <int, string> GetOptionsWithNames(int skuIdOfProductWithCategories, int categoryId)
    {
        Dictionary <int, string> optionsWithName = new Dictionary <int, string>();

        if ((ExternalDataSource != null) && (ExternalDataSource.Count > 0))
        {
            // External data
            OptionCategoryInfo categoryInfo    = ExternalDataSource.Keys.First(k => k.CategoryID == categoryId);
            List <SKUInfo>     externalOptions = ExternalDataSource[categoryInfo];

            foreach (SKUInfo info in externalOptions)
            {
                optionsWithName.Add(info.SKUID, info.SKUName);
            }

            return(optionsWithName);
        }
        else
        {
            InfoDataSet <SKUInfo> dsOptions = VariantHelper.GetEnabledOptionsWithVariantOptions(skuIdOfProductWithCategories, categoryId);

            if (!DataHelper.DataSourceIsEmpty(dsOptions))
            {
                foreach (var option in dsOptions)
                {
                    optionsWithName.Add(option.SKUID, option.SKUName);
                }
            }

            return(optionsWithName);
        }
    }
    /// <summary>
    /// Handles the OnReloadData event of the menuZoneVariants control.
    /// </summary>
    protected void menuMoveToZoneVariants_OnReloadData(object sender, EventArgs e)
    {
        // Check permissions
        if (currentUser == null)
        {
            return;
        }

        if ((DocumentContext.CurrentPageInfo != null) &&
            (DocumentContext.CurrentPageInfo.TemplateInstance != null))
        {
            VariantModeEnum currentVariantMode = VariantModeEnum.None;
            string          targetZoneId       = ValidationHelper.GetString(menuMoveToZoneVariants.Parameter, string.Empty);
            int             pageTemplateId     = DocumentContext.CurrentPageInfo.UsedPageTemplateInfo.PageTemplateId;

            // Get selected zone variant mode
            if ((DocumentContext.CurrentPageInfo != null) &&
                (DocumentContext.CurrentPageInfo.TemplateInstance != null))
            {
                WebPartZoneInstance targetZone = DocumentContext.CurrentPageInfo.TemplateInstance.GetZone(targetZoneId);
                if (targetZone != null)
                {
                    currentVariantMode = targetZone.VariantMode;
                }
            }

            SetColumnNames(currentVariantMode);

            // Get all zone variants of the current web part
            DataTable resultTable = null;
            DataSet   ds          = VariantHelper.GetVariants(currentVariantMode, pageTemplateId, targetZoneId, Guid.Empty, 0);

            if (!DataHelper.DataSourceIsEmpty(ds))
            {
                DataTable table = ds.Tables[0].Copy();
                table.DefaultView.Sort = columnVariantID;

                // Add the original web part as the first item in the variant list
                DataRow originalVariant = table.NewRow();
                originalVariant[columnVariantID]             = 0;
                originalVariant[columnVariantDisplayName]    = ResHelper.GetString("ZoneMenu.OriginalZone", UICulture);
                originalVariant[columnVariantZoneID]         = targetZoneId;
                originalVariant[columnVariantPageTemplateID] = pageTemplateId;
                originalVariant[columnVariantInstanceGUID]   = Guid.Empty;
                table.Rows.InsertAt(originalVariant, 0);

                resultTable = table.DefaultView.ToTable();

                if (DataHelper.DataSourceIsEmpty(resultTable))
                {
                    pnlNoZoneVariants.Visible = true;
                    ltlNoZoneVariants.Text    = ResHelper.GetString("Content.NoPermissions", UICulture);
                }
            }

            repMoveToZoneVariants.DataSource = resultTable;
            repMoveToZoneVariants.DataBind();
        }
    }
 /// <summary>
 /// Hide/rename columns in uniGrid before loading data.
 /// </summary>
 void ugOptions_OnBeforeDataReload()
 {
     // Hide price adjustment if category is used in product variants
     if (VariantHelper.AreCategoriesUsedInVariants(ProductID, new[] { CategoryID }))
     {
         ugOptions.NamedColumns["SKUPrice"].Visible = false;
     }
 }
示例#6
0
 /// <summary>
 /// Returns a collection of option categories used in a product's variants.
 /// </summary>
 /// <param name="productId">SKU identifier of the variant's parent product.</param>
 /// <returns>Collection of option categories used in a product's variants. See <see cref="OptionCategoryInfo"/> for detailed information.</returns>
 public IEnumerable <OptionCategoryInfo> GetVariantOptionCategories(int productId)
 {
     return(repositoryCacheHelper.CacheObjects(() =>
     {
         // Get a list of option categories
         return VariantHelper.GetProductVariantsCategories(productId);
     }, $"{nameof(VariantRepository)}|{nameof(GetVariantOptionCategories)}|{productId}"));
 }
    /// <summary>
    /// Updates price of variants in asynchronous control.
    /// </summary>
    /// <param name="newPrice">New price of variant</param>
    protected void UpdatePrice(double newPrice)
    {
        try
        {
            SKUInfo variantInfo = null;

            // Use special action contexts to turn off unnecessary actions
            using (ECommerceActionContext eCommerceContext = new ECommerceActionContext())
            {
                eCommerceContext.TouchParent            = false;
                eCommerceContext.SetLowestPriceToParent = false;

                // Update all variants
                if ((WhatEnum)ValidationHelper.GetInteger(drpWhat.SelectedIndex, -1) == WhatEnum.AllVariants)
                {
                    var variants = VariantHelper.GetVariants(ProductID);

                    foreach (var variant in variants)
                    {
                        variantInfo = variant;
                        UpdateVariant(variantInfo, newPrice);
                    }
                }
                // Update selected variants
                else
                {
                    var variantsToUpdate = ugVariants.SelectedItems;

                    foreach (var variantId in variantsToUpdate)
                    {
                        variantInfo = SKUInfoProvider.GetSKUInfo(ValidationHelper.GetInteger(variantId, 0));

                        // Do not allow modify variants of other product
                        if ((variantInfo != null) && (variantInfo.SKUParentSKUID != ProductID))
                        {
                            variantInfo = null;
                        }

                        if (variantInfo != null)
                        {
                            UpdateVariant(variantInfo, newPrice);
                        }
                    }
                }
            }

            // Save variant to update parent SKULastModified a SKUPrice properties
            if (variantInfo != null)
            {
                variantInfo.Generalized.SetObject();
            }
        }
        catch (Exception ex)
        {
            CurrentError = GetString("com.product.updatepriceerror");
            EventLogProvider.LogException("Update price bulk action", "UPDATEVARIANT", ex);
        }
    }
示例#8
0
        /// <summary>
        /// Returns a variant for the given parent product which consists of the specified options.
        /// If multiple variants use the given subset of options, one of them is returned (based on setting of the database engine).
        /// </summary>
        /// <param name="productId">SKU identifier of the variant's parent product.</param>
        /// <param name="optionIds">Collection of the variant's product options.</param>
        /// <returns><see cref="ProductVariant"/> object representing a product variant assembled from the specified information. Returns <c>null</c> if such variant does not exist.</returns>
        public ProductVariant GetByProductIdAndOptions(int productId, IEnumerable <int> optionIds)
        {
            var variantSKU = VariantHelper.GetProductVariant(productId, new ProductAttributeSet(optionIds));

            if (variantSKU == null)
            {
                return(null);
            }

            return(new ProductVariant(variantSKU.SKUID));
        }
    /// <summary>
    /// Handles the OnReloadData event of the menuWebPartCPVariants control.
    /// </summary>
    protected void menuWebPartCPVariants_OnReloadData(object sender, EventArgs e)
    {
        // Check permissions
        if ((MembershipContext.AuthenticatedUser == null) ||
            (!MembershipContext.AuthenticatedUser.IsAuthorizedPerResource("CMS.ContentPersonalization", "Read")))
        {
            return;
        }

        string parameters = ValidationHelper.GetString(menuWebPartCPVariants.Parameter, string.Empty);

        string[] items = parameters.Split(new char[] { ',' }, 7);

        if ((items == null) || (items.Length < 4))
        {
            return;
        }

        string zoneId       = ValidationHelper.GetString(items[0], string.Empty);
        string webpartName  = ValidationHelper.GetString(items[1], string.Empty);
        string aliasPath    = ValidationHelper.GetString(items[2], string.Empty);
        Guid   instanceGuid = ValidationHelper.GetGuid(items[3], Guid.Empty);

        isZone = (instanceGuid == Guid.Empty);

        if ((DocumentContext.CurrentPageInfo != null) &&
            (DocumentContext.CurrentPageInfo.TemplateInstance != null))
        {
            int templateId = DocumentContext.CurrentPageInfo.UsedPageTemplateInfo.PageTemplateId;

            DataSet   ds          = VariantHelper.GetVariants(VariantModeEnum.ContentPersonalization, templateId, zoneId, instanceGuid, 0);
            DataTable resultTable = null;

            if (!DataHelper.DataSourceIsEmpty(ds))
            {
                DataTable table = ds.Tables[0].Copy();
                table.DefaultView.Sort = columnVariantID;

                // Add the original web part as the first item in the variant list
                DataRow originalVariant = table.NewRow();
                originalVariant[columnVariantID]             = 0;
                originalVariant[columnVariantDisplayName]    = ResHelper.GetString(isZone ? "ZoneMenu.OriginalZone" : "WebPartMenu.OriginalWebPart");
                originalVariant[columnVariantZoneID]         = zoneId;
                originalVariant[columnVariantPageTemplateID] = templateId;
                originalVariant[columnVariantInstanceGUID]   = instanceGuid;
                table.Rows.InsertAt(originalVariant, 0);

                resultTable = table.DefaultView.ToTable();
            }

            repWebPartCPVariants.DataSource = resultTable;
            repWebPartCPVariants.DataBind();
        }
    }
    /// <summary>
    /// Handles the OnReloadData event of the menuWebPartVariants control.
    /// </summary>
    protected void menuZoneMVTVariants_OnReloadData(object sender, EventArgs e)
    {
        // Check permissions
        if ((currentUser == null) ||
            (!currentUser.IsAuthorizedPerResource("CMS.MVTest", "Read")))
        {
            return;
        }

        SetColumnNames(VariantModeEnum.MVT);

        string zoneId = ValidationHelper.GetString(menuZoneMVTVariants.Parameter, string.Empty);

        if ((DocumentContext.CurrentPageInfo != null) &&
            (DocumentContext.CurrentPageInfo.TemplateInstance != null))
        {
            int templateId = DocumentContext.CurrentPageInfo.UsedPageTemplateInfo.PageTemplateId;

            // Get all MVT zone variants of the current web part
            DataSet   ds          = VariantHelper.GetVariants(VariantModeEnum.MVT, templateId, zoneId, Guid.Empty, 0);
            DataTable resultTable = null;

            if (!DataHelper.DataSourceIsEmpty(ds))
            {
                DataTable table = ds.Tables[0].Copy();
                table.DefaultView.Sort = columnVariantID;

                // Add the original web part as the first item in the variant list
                DataRow originalVariant = table.NewRow();
                originalVariant[columnVariantID]             = 0;
                originalVariant[columnVariantDisplayName]    = ResHelper.GetString("WebPartMenu.OriginalWebPart", UICulture);
                originalVariant[columnVariantZoneID]         = zoneId;
                originalVariant[columnVariantPageTemplateID] = templateId;
                originalVariant[columnVariantInstanceGUID]   = Guid.Empty;
                table.Rows.InsertAt(originalVariant, 0);

                resultTable = table.DefaultView.ToTable();

                if (DataHelper.DataSourceIsEmpty(resultTable))
                {
                    pnlNoZoneMVTVariants.Visible = true;
                    lblNoZoneMVTVariants.Text    = ResHelper.GetString("Content.NoPermissions", UICulture);
                }
            }
            else
            {
                pnlNoZoneMVTVariants.Visible = true;
            }

            repZoneMVTVariants.DataSource = resultTable;
            repZoneMVTVariants.DataBind();
        }
    }
    /// <summary>
    /// Gets all options used in variant.
    /// </summary>
    /// <returns>Collection of option Ids used in variants.</returns>
    private List <string> GetOptionIdsUsedInVariant()
    {
        var optionsInCategory = SKUInfoProvider.GetSKUOptions(optionSKUCategoryInfo.CategoryID, false).Column("SKUID");
        var optionsInVariants = VariantOptionInfo.Provider.Get()
                                .WhereIn("VariantSKUID", VariantHelper.GetVariants(ProductID).Column("SKUID"))
                                .Column("OptionSKUID");


        // Check if some variant was created from the option
        return(optionsInCategory.WhereIn("SKUID", optionsInVariants).ToList()
               .Select(o => o.SKUID.ToString())
               .ToList());
    }
示例#12
0
        public IList <ProductAttribute> GetByProductId(int productId, bool onlyVariantSpecific = false)
        {
            var q = Repository.Where(x => x.ProductId == productId)
                    .Join <AvailableAttribute>("AvailableAttributeId", "Id", joinType: JoinType.LeftOuter)
                    //.Join<Product>("ProductId", "Id")
                    .Join <ProductAttributeValue>("Id", "ProductAttributeId", SourceColumn.Parent,
                                                  joinType: JoinType.LeftOuter)
                    .Join <AvailableAttributeValue>("AvailableAttributeValueId", "Id", joinType: JoinType.LeftOuter);


            //should we restrict to only variant specific attributes
            if (onlyVariantSpecific)
            {
                var allowedInputTypes = VariantHelper.GetVariantSpecificFieldTypes();
                Expression <Func <ProductAttribute, bool> > variantWhere =
                    attribute => allowedInputTypes.Contains(attribute.InputFieldType);
                q.Where(variantWhere);
            }


            return(q
                   .Relate(RelationTypes.OneToMany <ProductAttribute, ProductAttributeValue>())
                   .Relate <AvailableAttributeValue>((productAttribute, availableAttributeValue) =>
            {
                if (productAttribute.Tag == null)
                {
                    productAttribute.Tag = new List <AvailableAttributeValue>();
                }

                var attributeList = (List <AvailableAttributeValue>)productAttribute.Tag;
                if (!attributeList.Contains(availableAttributeValue))
                {
                    attributeList.Add(availableAttributeValue);
                }

                var pav = productAttribute.ProductAttributeValues.FirstOrDefault(
                    x => x.AvailableAttributeValueId == availableAttributeValue.Id);
                if (pav != null)
                {
                    pav.AvailableAttributeValue = availableAttributeValue;
                }
            })
                   .Relate <AvailableAttribute>((productAttribute, availableAttribute) =>
            {
                availableAttribute.AvailableAttributeValues = (List <AvailableAttributeValue>)productAttribute.Tag;
                productAttribute.AvailableAttribute = availableAttribute;
            })
                   .OrderBy(x => x.DisplayOrder)
                   .SelectNested()
                   .ToList());
        }
示例#13
0
        private IEnumerable <SKUInfo> GetOptions(int skuID, int categoryID, ISKUInfoProvider skuInfoProvider)
        {
            // Get all variant's options
            var variantOptionIDs = VariantOptionInfo.Provider.Get()
                                   .WhereIn("VariantSKUID", VariantHelper.GetVariants(skuID).Column("SKUID"))
                                   .Column("OptionSKUID");

            var variantOptionsList = skuInfoProvider.Get()
                                     .WhereIn("SKUID", variantOptionIDs)
                                     .OrderBy("SKUOrder")
                                     .ToList();

            // Create option categories with selectable variant options
            return(variantOptionsList.Where(o => o.SKUOptionCategoryID == categoryID));
        }
    /// <summary>
    /// Gets the categories with names from external data source or database.
    /// </summary>
    /// <param name="skuIdOfProductWithCategories">Id of product with categories.</param>
    private Dictionary <int, string> GetCategoriesWithNames(int skuIdOfProductWithCategories)
    {
        Dictionary <int, string> categoriesWithName = new Dictionary <int, string>();

        if ((ExternalDataSource != null) && (ExternalDataSource.Count > 0))
        {
            // External data
            foreach (OptionCategoryInfo info in ExternalDataSource.Keys)
            {
                // Use category live site display name in case it is available, otherwise category display name
                categoriesWithName.Add(info.CategoryID, info.CategoryTitle);
            }

            return(categoriesWithName);
        }
        // Load data from DB
        DataSet dsOptionCategories;

        // If ShowOnlyUsedCategories is true, dataset will contain only already used categories in variants
        if (ShowOnlyUsedCategories)
        {
            dsOptionCategories = VariantHelper.GetProductVariantsCategories(skuIdOfProductWithCategories);
        }
        else
        {
            dsOptionCategories = OptionCategoryInfoProvider.GetProductOptionCategories(skuIdOfProductWithCategories, true, OptionCategoryTypeEnum.Attribute);
        }

        if (DataHelper.DataSourceIsEmpty(dsOptionCategories))
        {
            return(categoriesWithName);
        }

        foreach (DataRow catDr in dsOptionCategories.Tables[0].Rows)
        {
            int    categoryId   = ValidationHelper.GetInteger(catDr["CategoryID"], 0);
            string categoryName = ValidationHelper.GetString(catDr["CategoryLiveSiteDisplayName"], String.Empty);

            if (string.IsNullOrEmpty(categoryName))
            {
                categoryName = ValidationHelper.GetString(catDr["CategoryDisplayName"], String.Empty);
            }

            categoriesWithName.Add(categoryId, categoryName);
        }

        return(categoriesWithName);
    }
示例#15
0
    /// <summary>
    /// Gets all options used in variant.
    /// </summary>
    /// <returns>Collection of option Ids used in variants.</returns>
    private List <string> GetOptionIdsUsedInVariant()
    {
        var options        = SKUInfoProvider.GetSKUOptions(optionSKUCategoryInfo.CategoryID, false);
        var variantOptions = new List <string>();

        // Check if some variant was created from the option
        foreach (var option in options)
        {
            if (VariantHelper.VariantExists(ProductID, new ProductAttributeSet(option.SKUID), false))
            {
                variantOptions.Add(option.SKUID.ToString());
            }
        }

        return(variantOptions);
    }
示例#16
0
    /// <summary>
    /// Creates category with variant attributes.
    /// </summary>
    /// <param name="optionsList">Product options</param>
    private void SetVariantAttributes(List <SKUInfo> optionsList)
    {
        // Get attributes category index - just before representing category
        var attrPos = editForm.FormInformation.ItemsList.FindIndex(f =>
                                                                   (f is FormCategoryInfo) && ((FormCategoryInfo)f).CategoryName.EqualsCSafe("com.sku.representingcategory"));


        // Create attributes category
        var attCategory = new FormCategoryInfo()
        {
            CategoryName = "Attributes",
            IsDummy      = true,
        };

        attCategory.SetPropertyValue(FormCategoryPropertyEnum.Caption, HTMLHelper.HTMLEncode(GetString("com.variant.attributes")));
        editForm.FormInformation.AddFormItem(attCategory, attrPos++);

        // Get variant categories
        var variantCategories = VariantHelper.GetProductVariantsCategories(ProductID, false);

        foreach (var category in variantCategories)
        {
            var option = optionsList.FirstOrDefault(o => o.SKUOptionCategoryID == category.CategoryID);

            if (option != null)
            {
                FormFieldInfo ffOption = new FormFieldInfo
                {
                    Name         = category.CategoryName,
                    AllowEmpty   = true,
                    Size         = 400,
                    FieldType    = FormFieldControlTypeEnum.LabelControl,
                    DataType     = FieldDataType.Text,
                    IsDummyField = true,
                };

                ffOption.SetPropertyValue(FormFieldPropertyEnum.DefaultValue, HTMLHelper.HTMLEncode(ResHelper.LocalizeString(option.SKUName)));

                // Show category live site display name instead of category display name in case it is available
                ffOption.SetPropertyValue(FormFieldPropertyEnum.FieldCaption, HTMLHelper.HTMLEncode(ResHelper.LocalizeString(category.CategoryTitle)));

                //Insert field to the form on specified position
                editForm.FormInformation.AddFormItem(ffOption, attrPos++);
            }
        }
    }
示例#17
0
    /// <summary>
    /// Sets current layout.
    /// </summary>
    protected void SetCurrentLayout(bool saveToWebPartInstance)
    {
        if ((webPart != null) && (LayoutCodeName != "|new|"))
        {
            if (saveToWebPartInstance)
            {
                if (LayoutCodeName == "|default|")
                {
                    webPart.SetValue("WebPartLayout", "");
                }
                else
                {
                    webPart.SetValue("WebPartLayout", LayoutCodeName);
                }

                bool isWebPartVariant = (variantId > 0) || (zoneVariantId > 0) || isNewVariant;
                if (!isWebPartVariant)
                {
                    // Update page template
                    PageTemplateInfoProvider.SetPageTemplateInfo(pti);
                }
                else
                {
                    // Save the variant properties
                    if ((webPart != null) &&
                        (webPart.ParentZone != null) &&
                        (webPart.ParentZone.ParentTemplateInstance != null) &&
                        (webPart.ParentZone.ParentTemplateInstance.ParentPageTemplate != null))
                    {
                        XmlNode xmlWebParts = (zoneVariantId > 0) ? webPart.ParentZone.GetXmlNode() : webPart.GetXmlNode();

                        VariantHelper.SetVariantWebParts(webPart.VariantMode, (zoneVariantId > 0) ? zoneVariantId : variantId, xmlWebParts);

                        // The variants are cached -> Reload
                        webPart.ParentZone.ParentTemplateInstance.LoadVariants(true, VariantModeEnum.None);
                    }
                }
            }

            string parameters = aliasPath + "/" + zoneId + "/" + webpartId;
            string cacheName  = "CMSVirtualWebParts|" + parameters.ToLowerCSafe().TrimStart('/');

            CacheHelper.Remove(cacheName);
        }
    }
示例#18
0
        // Displaying product variants on MVC sites
        private object DummyEcommerceMethod4()
        {
            int productId = 0;
            IEnumerable <int> optionIds = new List <int>()
            {
                1, 2, 3
            };

            //DocSection:VariantFromOptionIds
            // Retrieves a product variant from a given product ID and a collection of option IDs
            var variantSKU = VariantHelper.GetProductVariant(productId, new ProductAttributeSet(optionIds));

            if (variantSKU == null)
            {
                return(null);
            }

            return(variantSKU);
            //EndDocSection:VariantFromOptionIds
        }
    /// <summary>
    /// Removes category bindings assigned to SKU.
    /// </summary>
    /// <param name="categoryIDs">ID of categories which should be removed</param>
    /// <returns>Returns true if some category binding was removed.</returns>
    private bool RemoveSKUCategoryBindings(IEnumerable <int> categoryIDs)
    {
        var ids = categoryIDs.ToList();

        var variantCategoryIDs = VariantHelper.GetProductVariantsCategoryIDs(ProductID);

        var categoryIDsToRemove = ids.Except(variantCategoryIDs).ToList();

        foreach (var id in categoryIDsToRemove)
        {
            ProductHelper.RemoveOptionCategory(ProductID, id);
        }

        // Categories are already used in variants -> they cannot be removed
        if (ids.Except(categoryIDsToRemove).Any())
        {
            ShowWarning(GetString("com.optioncategory.remove"));
        }

        return(categoryIDsToRemove.Any());
    }
示例#20
0
        //EndDocSection:DisplayProduct

        //DocSection:DisplayVariant
        /// <summary>
        /// Displays product detail page of a product or product variant specified by the GUID of the product's or variant's page.
        /// </summary>
        /// <param name="guid">Node GUID of the product's (variant's) page.</param>
        /// <param name="productAlias">Node alias of the product's (variant's) page.</param>
        public ActionResult Detail(Guid guid, string productAlias)
        {
            // Gets the product from the connected Kentico database
            SKUTreeNode product = GetProduct(guid);

            // If the product is not found or if it is not allowed for sale, redirects to error 404
            if ((product == null) || !product.SKU.SKUEnabled)
            {
                return(HttpNotFound());
            }

            // Redirects if the specified page alias does not match
            if (!string.IsNullOrEmpty(productAlias) && !product.NodeAlias.Equals(productAlias, StringComparison.InvariantCultureIgnoreCase))
            {
                return(RedirectToActionPermanent("Detail", new { guid = product.NodeGUID, productAlias = product.NodeAlias }));
            }

            // Gets all product variants of the product
            List <ProductVariant> variants = VariantHelper.GetVariants(product.NodeSKUID).OnSite(SiteContext.CurrentSiteID).ToList()
                                             .Select(sku => new ProductVariant(sku.SKUID))
                                             .OrderBy(v => v.Variant.SKUPrice).ToList();

            // Selects the first product variant
            ProductVariant selectedVariant = variants.FirstOrDefault();

            // Calculates the price of the product or the variant
            ShoppingCartInfo cart = shoppingService.GetCurrentShoppingCart();

            SKUInfo selectedProduct = selectedVariant != null ? selectedVariant.Variant : product.SKU;

            ProductCatalogPrices priceDetail = calculatorFactory
                                               .GetCalculator(cart.ShoppingCartSiteID)
                                               .GetPrices(selectedProduct, Enumerable.Empty <SKUInfo>(), cart);

            // Initializes the view model of the product or product variant
            ProductViewModel viewModel = new ProductViewModel(product, priceDetail, variants, selectedVariant?.Variant?.SKUID ?? 0);

            // Displays the product detail page
            return(View(viewModel));
        }
    /// <summary>
    /// Hide/rename columns in uniGrid before loading data.
    /// </summary>
    private void grid_OnBeforeDataReload()
    {
        switch (categoryObj.CategoryType)
        {
        case OptionCategoryTypeEnum.Attribute:
        case OptionCategoryTypeEnum.Text:
            ugOptions.NamedColumns["SKUName"].HeaderText        = GetString("unigrid.productoptions.OptionName");
            ugOptions.NamedColumns["SKUNumber"].Visible         = false;
            ugOptions.NamedColumns["SKUDepartment"].Visible     = false;
            ugOptions.NamedColumns["SKUAvailableItems"].Visible = false;
            break;
        }

        // Hide price adjustment if category is used in product variants
        if (parentProductId > 0)
        {
            if (VariantHelper.AreCategoriesUsedInVariants(QueryHelper.GetInteger("productId", 0), new[] { categoryObj.CategoryID }))
            {
                ugOptions.NamedColumns["SKUPrice"].Visible = false;
            }
        }
    }
示例#22
0
    /// <summary>
    /// Generates variants, builds UniGrid and binds data to it.
    /// </summary>
    private void SetupVariants(bool regenerate = true)
    {
        // Do not setup variants, when callback is requesting page
        if (RequestHelper.IsCallback())
        {
            return;
        }

        // Limit maximum variants count
        const int maxVariantsCount = 1000;

        if (VariantHelper.GetAllPossibleVariantsCount(ProductID, CategorySelector.SelectedCategories.Keys) > maxVariantsCount)
        {
            ShowWarning(GetString("com.variants.variantlimit"));
            return;
        }

        if (regenerate)
        {
            // Generate Variants
            mGeneratedVariants = GenerateVariants();
            ExistingItems      = null;
        }

        // Set UniGrid columns and other properties
        VariantGrid.GridColumns.Columns         = mColumnDefinitions;
        VariantGrid.GridOptions.DisplayFilter   = false;
        VariantGrid.GridOptions.ShowSelection   = true;
        VariantGrid.GridOptions.SelectionColumn = "RowNumber";

        var existingItems = ExistingItems;

        VariantGrid.SelectedItems = ((existingItems != null) && (existingItems.Count > 0)) ? existingItems : VariantGrid.SelectedItems;

        // Bind data to UniGrid
        VariantGrid.DataSource = mGeneratedVariants;
        VariantGrid.ReloadData();
    }
示例#23
0
        /// <summary>
        /// Returns an enumerable collection of all variants of the given product.
        /// </summary>
        /// <param name="productId">SKU object identifier of the variant's parent product.</param>
        /// <returns>Collection of product variants. See <see cref="Variant"/> for detailed information.</returns>
        public IEnumerable <Variant> GetByProductId(int productId)
        {
            var variantSKUs = VariantHelper.GetVariants(productId).OnSite(SiteID).ToList();

            // Get the used option IDs for the variants
            var variantOptions = VariantOptionInfoProvider.GetVariantOptions()
                                 .WhereIn("VariantSKUID", variantSKUs.Select(s => s.SKUID).ToList())
                                 .ToList();

            // Pre-load option SKUs for the variants
            var options = SKUInfoProvider.GetSKUs()
                          .WhereIn("SKUID", variantOptions.Select(v => v.OptionSKUID).ToList())
                          .ToList();

            // Create variants with the options
            return(variantSKUs.Select(sku => new Variant(
                                          sku,
                                          new ProductAttributeSet(variantOptions
                                                                  .Where(o => o.VariantSKUID == sku.SKUID)
                                                                  .Select(o => options.First(s => s.SKUID == o.OptionSKUID))
                                                                  .ToArray())
                                          )));
        }
示例#24
0
        /// <summary>
        /// Returns a collection of option categories used in a product's variants.
        /// </summary>
        /// <param name="productId">SKU identifier of the variant's parent product.</param>
        /// <returns>Collection of option categories used in a product's variants. See <see cref="ProductOptionCategory"/> for detailed information.</returns>
        public IEnumerable <ProductOptionCategory> GetVariantOptionCategories(int productId)
        {
            // Get a list of option categories
            var optionCategoriesList = VariantHelper.GetProductVariantsCategories(productId).ToList();

            // Get all variant's options
            var variantOptionIDs = VariantOptionInfoProvider.GetVariantOptions()
                                   .WhereIn("VariantSKUID", VariantHelper.GetVariants(productId).Column("SKUID"))
                                   .Column("OptionSKUID");

            var variantOptionsList = SKUInfoProvider.GetSKUs()
                                     .WhereIn("SKUID", variantOptionIDs)
                                     .OrderBy("SKUOrder")
                                     .ToList();

            // Create option categories with selectable variant options
            return(optionCategoriesList.Select(cat =>
                                               new ProductOptionCategory(
                                                   cat,
                                                   variantOptionsList.Where(o => o.SKUOptionCategoryID == cat.CategoryID)
                                                   )
                                               ));
        }
示例#25
0
    /// <summary>
    /// Removes category bindings assigned to SKU.
    /// </summary>
    /// <param name="categoryIDs">ID of categories which should be removed</param>
    /// <returns>Returns true if some category binding was removed.</returns>
    private bool RemoveSKUCategoryBindings(IEnumerable <int> categoryIDs)
    {
        var ids = categoryIDs.ToList();

        // GetProductVariantsCategories create a complex query with join included -> column must be defined with table name prefix
        // Convert query to list before calling Select, otherwise there will be ambiguous column CategoryID
        var variantCategoryIDs = VariantHelper.GetProductVariantsCategories(ProductID, false).Column("COM_OptionCategory.CategoryID").ToList().Select(category => category.CategoryID).ToList();

        var categoryIDsToRemove = ids.Except(variantCategoryIDs).ToList();

        foreach (var id in categoryIDsToRemove)
        {
            ProductHelper.RemoveOptionCategory(ProductID, id);
        }

        // Categories are already used in variants -> they cannot be removed
        if (ids.Except(categoryIDsToRemove).Any())
        {
            ShowWarning(GetString("com.optioncategory.remove"));
        }

        return(categoryIDsToRemove.Any());
    }
示例#26
0
        //EndDocSection:DisplayProduct


        //DocSection:DisplayVariant
        /// <summary>
        /// Displays product detail page of a product or product variant.
        /// </summary>
        public ActionResult Detail()
        {
            // Gets the product from the connected Xperience database
            SKUTreeNode product = GetProduct();

            // If the product is not found or if it is not allowed for sale, redirects to error 404
            if ((product == null) || !product.SKU.SKUEnabled)
            {
                return(NotFound());
            }

            // Gets all product variants of the product
            List <ProductVariant> variants = VariantHelper
                                             .GetVariants(product.NodeSKUID)
                                             .OnSite(siteService.CurrentSite.SiteID).ToList()
                                             .Select(sku => new ProductVariant(sku.SKUID))
                                             .OrderBy(v => v.Variant.SKUPrice).ToList();

            // Selects the first product variant
            ProductVariant selectedVariant = variants.FirstOrDefault();

            // Calculates the price of the product or the variant
            ShoppingCartInfo cart = shoppingService.GetCurrentShoppingCart();

            SKUInfo selectedProduct = selectedVariant != null ? selectedVariant.Variant : product.SKU;

            ProductCatalogPrices priceDetail = priceCalculatorFactory
                                               .GetCalculator(cart.ShoppingCartSiteID)
                                               .GetPrices(selectedProduct, Enumerable.Empty <SKUInfo>(), cart);

            // Initializes the view model of the product or product variant
            ProductViewModel viewModel = new ProductViewModel(product, priceDetail, variants, selectedVariant?.Variant?.SKUID ?? 0);

            // Displays the product detail page
            return(View(viewModel));
        }
示例#27
0
    /// <summary>
    /// Saves webpart properties.
    /// </summary>
    public bool Save()
    {
        // Check MVT/CP security
        if (VariantID > 0)
        {
            // Check OnlineMarketing permissions.
            if (!CheckPermissions("Manage"))
            {
                ShowError(GetString("general.modifynotallowed"));
                return(false);
            }
        }

        // Save the data
        if ((pi != null) && (pti != null) && (templateInstance != null) && SaveForm(form))
        {
            if (SynchronizationHelper.IsCheckedOutByOtherUser(pti))
            {
                string   userName = null;
                UserInfo ui       = UserInfoProvider.GetUserInfo(pti.Generalized.IsCheckedOutByUserID);
                if (ui != null)
                {
                    userName = HTMLHelper.HTMLEncode(ui.GetFormattedUserName(IsLiveSite));
                }

                ShowError(string.Format(GetString("ObjectEditMenu.CheckedOutByAnotherUser"), pti.TypeInfo.ObjectType, pti.DisplayName, userName));
                return(false);
            }

            // Add web part if new
            if (IsNewWebPart)
            {
                int webpartId = ValidationHelper.GetInteger(WebPartID, 0);

                // Ensure layout zone flag
                if (QueryHelper.GetBoolean("layoutzone", false))
                {
                    WebPartZoneInstance zone = pti.TemplateInstance.EnsureZone(ZoneID);
                    zone.LayoutZone = true;
                }

                webPartInstance = PortalHelper.AddNewWebPart(webpartId, ZoneID, false, ZoneVariantID, Position, templateInstance);

                // Set default layout
                if (wpi.WebPartParentID > 0)
                {
                    WebPartLayoutInfo wpli = WebPartLayoutInfoProvider.GetDefaultLayout(wpi.WebPartID);
                    if (wpli != null)
                    {
                        webPartInstance.SetValue("WebPartLayout", wpli.WebPartLayoutCodeName);
                    }
                }
            }

            webPartInstance.XMLVersion = 1;
            if (IsNewVariant)
            {
                webPartInstance             = webPartInstance.Clone();
                webPartInstance.VariantMode = VariantModeFunctions.GetVariantModeEnum(QueryHelper.GetString("variantmode", String.Empty).ToLowerInvariant());
            }

            // Get basic form's data row and update web part
            SaveFormToWebPart(form);

            // Set new position if set
            if (PositionLeft > 0)
            {
                webPartInstance.SetValue("PositionLeft", PositionLeft);
            }
            if (PositionTop > 0)
            {
                webPartInstance.SetValue("PositionTop", PositionTop);
            }

            bool isWebPartVariant = (VariantID > 0) || (ZoneVariantID > 0) || IsNewVariant;
            if (!isWebPartVariant)
            {
                // Save the changes
                CMSPortalManager.SaveTemplateChanges(pi, templateInstance, WidgetZoneTypeEnum.None, ViewModeEnum.Design, tree);
            }
            else
            {
                Hashtable varProperties = WindowHelper.GetItem("variantProperties") as Hashtable;
                // Save changes to the web part variant
                VariantHelper.SaveWebPartVariantChanges(webPartInstance, VariantID, ZoneVariantID, VariantMode, varProperties);
            }

            // Reload the form (because of macro values set only by JS)
            form.ReloadData();

            // Clear the cached web part
            CacheHelper.TouchKey("webpartinstance|" + InstanceGUID.ToString().ToLowerInvariant());

            ShowChangesSaved();

            return(true);
        }

        if (webPartInstance?.ParentZone?.ParentTemplateInstance != null)
        {
            // Reload the zone/web part variants when saving of the form fails
            webPartInstance.ParentZone.ParentTemplateInstance.LoadVariants(true, VariantModeEnum.None);
        }

        return(false);
    }
示例#28
0
    /// <summary>
    /// Loads the web part form.
    /// </summary>
    protected void LoadForm()
    {
        // Load settings
        if (!string.IsNullOrEmpty(Request.Form[hdnIsNewWebPart.UniqueID]))
        {
            IsNewWebPart = ValidationHelper.GetBoolean(Request.Form[hdnIsNewWebPart.UniqueID], false);
        }
        if (!string.IsNullOrEmpty(Request.Form[hdnInstanceGUID.UniqueID]))
        {
            InstanceGUID = ValidationHelper.GetGuid(Request.Form[hdnInstanceGUID.UniqueID], Guid.Empty);
        }

        // Indicates whether the new variant should be chosen when closing this dialog
        selectNewVariant = IsNewVariant;

        // Try to find the web part variant in the database and set its VariantID
        if (IsNewVariant)
        {
            Hashtable varProperties = WindowHelper.GetItem("variantProperties") as Hashtable;
            if (varProperties != null)
            {
                // Get the variant code name from the WindowHelper
                string variantName = ValidationHelper.GetString(varProperties["codename"], string.Empty);

                // Check if the variant exists in the database
                int variantIdFromDB = VariantHelper.GetVariantID(VariantMode, PageTemplateID, variantName, true);

                // Set the variant id from the database
                if (variantIdFromDB > 0)
                {
                    VariantID    = variantIdFromDB;
                    IsNewVariant = false;
                }
            }
        }

        if (!String.IsNullOrEmpty(WebPartID))
        {
            // Get the page info
            pi = CMSWebPartPropertiesPage.GetPageInfo(AliasPath, PageTemplateID, CultureCode);

            if (pi == null)
            {
                ShowError(GetString("general.pagenotfound"));
                pnlExport.Visible = false;
                return;
            }

            // Get template
            pti = pi.UsedPageTemplateInfo;

            // Get template instance
            templateInstance = pti.TemplateInstance;

            if (!IsNewWebPart)
            {
                // Standard zone
                webPartInstance = templateInstance.GetWebPart(InstanceGUID, WebPartID);

                // If the web part not found, try to find it among the MVT/CP variants
                if (webPartInstance == null)
                {
                    // MVT/CP variant

                    // Clone templateInstance to avoid caching of the temporary template instance loaded with CP/MVT variants
                    var tempTemplateInstance = templateInstance.Clone();
                    tempTemplateInstance.LoadVariants(false, VariantModeEnum.None);

                    webPartInstance = tempTemplateInstance.GetWebPart(InstanceGUID, -1);

                    // Set the VariantMode according to the selected web part/zone variant
                    if (webPartInstance?.ParentZone != null)
                    {
                        VariantMode = (webPartInstance.VariantMode != VariantModeEnum.None) ? webPartInstance.VariantMode : webPartInstance.ParentZone.VariantMode;
                    }
                    else
                    {
                        VariantMode = VariantModeEnum.None;
                    }
                }
                else
                {
                    // Ensure that the ZoneVariantID is not set when the web part was found in a regular zone
                    ZoneVariantID = 0;
                }

                if ((VariantID > 0) && webPartInstance?.PartInstanceVariants != null)
                {
                    // Check OnlineMarketing permissions.
                    if (CheckPermissions("Read"))
                    {
                        webPartInstance = webPartInstance.FindVariant(VariantID);
                    }
                    else
                    {
                        // Not authorized for OnlineMarketing - Manage.
                        RedirectToInformation(String.Format(GetString("general.permissionresource"), "Read", (VariantMode == VariantModeEnum.ContentPersonalization) ? "CMS.ContentPersonalization" : "CMS.MVTest"));
                    }
                }

                if (webPartInstance == null)
                {
                    UIContext.EditedObject = null;
                    return;
                }
            }

            // Keep xml version
            if (webPartInstance != null)
            {
                xmlVersion = webPartInstance.XMLVersion;
            }

            // Get the form info
            FormInfo fi = GetWebPartFormInfo();

            // Get the form definition
            if (fi != null)
            {
                fi.ContextResolver.Settings.RelatedObject = templateInstance;
                form.AllowMacroEditing = true;

                // Get data row with required columns
                DataRow dr = fi.GetDataRow();

                if (IsNewWebPart || (xmlVersion > 0))
                {
                    fi.LoadDefaultValues(dr);
                }

                // Load values from existing web part
                LoadDataRowFromWebPart(dr, webPartInstance, fi);

                // Set a unique WebPartControlID for the new variant
                if (IsNewVariant || IsNewWebPart)
                {
                    dr["WebPartControlID"] = GetUniqueWebPartId();
                }

                // Init the form
                InitForm(form, dr, fi);

                DisplayExportPropertiesButton();
            }
            else
            {
                UIContext.EditedObject = null;
            }
        }
    }
    protected void uniSelector_OnSelectionChanged(object sender, EventArgs e)
    {
        var cu = MembershipContext.AuthenticatedUser;

        // Check permissions
        if ((cu == null) || (!cu.IsAuthorizedPerResource(ModuleName.ECOMMERCE, EcommercePermissions.ECOMMERCE_MODIFY) && !cu.IsAuthorizedPerResource(ModuleName.ECOMMERCE, EcommercePermissions.PRODUCTS_MODIFY)))
        {
            RedirectToAccessDenied(ModuleName.ECOMMERCE, "EcommerceModify OR ModifyProducts");
        }
        else
        {
            string newValues   = ValidationHelper.GetString(uniSelector.Value, null);
            string addItems    = DataHelper.GetNewItemsInList(UniSelectorData, newValues);
            string removeItems = DataHelper.GetNewItemsInList(newValues, UniSelectorData);

            // Add SKU to Option Category
            if (!String.IsNullOrEmpty(addItems))
            {
                string[] newItems = addItems.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string item in newItems)
                {
                    SKUOptionCategoryInfoProvider.AddOptionCategoryToSKU(categoryId, ValidationHelper.GetInteger(item, 0));
                }

                // Show message
                ShowChangesSaved();
            }

            // Remove SKU from Option Category
            if (!String.IsNullOrEmpty(removeItems))
            {
                string[]      productIds     = removeItems.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                bool          displayWarning = false;
                StringBuilder ids            = new StringBuilder();

                // Check if category is not used in variants of product
                foreach (string skuID in productIds)
                {
                    int productId = ValidationHelper.GetInteger(skuID, 0);

                    // Inform user that removing of product is not possible
                    if (VariantHelper.AreCategoriesUsedInVariants(productId, new int[] { categoryId }))
                    {
                        displayWarning = true;
                        ids.Append(";" + skuID);
                    }
                    else
                    {
                        ProductHelper.RemoveOptionCategory(productId, categoryId);
                    }
                }

                if (displayWarning)
                {
                    // Display items which cannot be removed in the selector
                    uniSelector.Value += ids.ToString();
                    ShowWarning(GetString("com.optioncategory.removeproduct"));
                }
                else
                {
                    ShowChangesSaved();
                }
            }
        }

        PreloadUniSelector(true);
    }
    /// <summary>
    /// Saves widget properties.
    /// </summary>
    public bool Save()
    {
        if (VariantID > 0)
        {
            // Check MVT/CP security
            if (!CheckPermissions("Manage"))
            {
                DisplayError("general.modifynotallowed");
                return(false);
            }
        }

        // Save the data
        if ((CurrentPageInfo != null) && (mTemplateInstance != null) && SaveForm(formCustom))
        {
            ViewModeEnum viewMode = PortalContext.ViewMode;

            // Check manage permission for non-livesite version
            if (!viewMode.IsLiveSite() && viewMode != ViewModeEnum.DashboardWidgets && viewMode != ViewModeEnum.UserWidgets)
            {
                if (CurrentUser.IsAuthorizedPerDocument(CurrentPageInfo.NodeID, CurrentPageInfo.ClassName, NodePermissionsEnum.Modify) != AuthorizationResultEnum.Allowed)
                {
                    DisplayError("general.modifynotallowed");
                    return(false);
                }

                // Check design permissions
                if (PortalContext.IsDesignMode(viewMode, false) && !PortalContext.CurrentUserIsDesigner)
                {
                    RedirectToAccessDenied("CMS.Design", "Design");
                }
            }

            PageTemplateInfo pti = mTemplateInstance.ParentPageTemplate;
            if (PortalContext.IsDesignMode(viewMode) && SynchronizationHelper.IsCheckedOutByOtherUser(pti))
            {
                string   userName = null;
                UserInfo ui       = UserInfoProvider.GetUserInfo(pti.Generalized.IsCheckedOutByUserID);
                if (ui != null)
                {
                    userName = HTMLHelper.HTMLEncode(ui.GetFormattedUserName(IsLiveSite));
                }

                DisplayError(string.Format(GetString("ObjectEditMenu.CheckedOutByAnotherUser"), pti.TypeInfo.ObjectType, pti.DisplayName, userName));
                return(false);
            }

            // Get the zone
            mWebPartZoneInstance = mTemplateInstance.EnsureZone(ZoneId);

            if (mWebPartZoneInstance != null)
            {
                mWebPartZoneInstance.WidgetZoneType = ZoneType;

                // Add new widget
                if (IsNewWidget)
                {
                    bool isLayoutZone = (QueryHelper.GetBoolean("layoutzone", false));
                    int  widgetID     = ValidationHelper.GetInteger(WidgetId, 0);

                    // Create new widget instance
                    mWidgetInstance = PortalHelper.AddNewWidget(widgetID, ZoneId, ZoneType, isLayoutZone, mTemplateInstance);
                }

                // Ensure handling of the currently edited object (if not exists -> redirect)
                UIContext.EditedObject = mWidgetInstance;

                mWidgetInstance.XMLVersion = 1;
                if (IsNewVariant)
                {
                    mWidgetInstance = mWidgetInstance.Clone();

                    // Check whether the editor widgets have been already customized
                    if (CurrentPageInfo.DocumentTemplateInstance.WebPartZones.Count == 0)
                    {
                        // There are no customized editor widgets yet => copy the default editor widgets from the page template under the document (to enable customization)

                        // Save to the document as editor admin changes
                        TreeNode node = DocumentHelper.GetDocument(CurrentPageInfo.DocumentID, mTreeProvider);

                        // Extract and set the document web parts
                        node.SetValue("DocumentWebParts", mTemplateInstance.GetZonesXML(WidgetZoneTypeEnum.Editor));

                        // Save the document
                        DocumentHelper.UpdateDocument(node, mTreeProvider);
                    }
                }

                bool isLayoutWidget = ((mWebPartInfo != null) && ((WebPartTypeEnum)mWebPartInfo.WebPartType == WebPartTypeEnum.Layout));

                // Get basicform's datarow and update widget
                SaveFormToWidget(formCustom, mTemplateInstance, isLayoutWidget);

                // Ensure unique id for new widget variant or layout widget
                if (IsNewVariant || (isLayoutWidget && IsNewWidget))
                {
                    string controlId = GetUniqueWidgetId(mWidgetInfo.WidgetName);

                    if (!string.IsNullOrEmpty(controlId))
                    {
                        mWidgetInstance.ControlID = controlId;
                    }
                    else
                    {
                        DisplayError("Unable to generate unique widget id.");
                        return(false);
                    }
                }

                // Allow set dashboard in design mode
                if ((ZoneType == WidgetZoneTypeEnum.Dashboard) && String.IsNullOrEmpty(PortalContext.DashboardName))
                {
                    viewMode = ViewModeEnum.Design;
                    PortalContext.SetViewMode(ViewModeEnum.Design);
                }

                bool isWidgetVariant = (VariantID > 0) || IsNewVariant;
                if (!isWidgetVariant)
                {
                    // Save the changes
                    if ((viewMode.IsEdit(true) || viewMode.IsEditLive()) && (ZoneType == WidgetZoneTypeEnum.Editor))
                    {
                        if (DocumentManager.AllowSave)
                        {
                            // Store the editor widgets in the temporary interlayer
                            PortalContext.SaveEditorWidgets(CurrentPageInfo.DocumentID, mTemplateInstance.GetZonesXML(WidgetZoneTypeEnum.Editor));
                        }
                    }
                    else
                    {
                        // Save the changes
                        CMSPortalManager.SaveTemplateChanges(CurrentPageInfo, mTemplateInstance, ZoneType, viewMode, mTreeProvider);
                    }
                }
                else if ((viewMode.IsEdit()) && (ZoneType == WidgetZoneTypeEnum.Editor))
                {
                    Hashtable properties = WindowHelper.GetItem("variantProperties") as Hashtable;

                    VariantHelper.SaveWebPartVariantChanges(mWidgetInstance, VariantID, 0, VariantMode, properties);

                    // Log widget variant synchronization
                    TreeNode node = DocumentHelper.GetDocument(CurrentPageInfo.DocumentID, mTreeProvider);
                    DocumentSynchronizationHelper.LogDocumentChange(node, TaskTypeEnum.UpdateDocument, mTreeProvider);
                }
            }

            // Reload the form (because of macro values set only by JS)
            formCustom.ReloadData();

            // Display info message
            ShowChangesSaved();

            // Clear the cached web part
            CacheHelper.TouchKey("webpartinstance|" + InstanceGUID.ToString().ToLowerCSafe());

            return(true);
        }

        return(false);
    }