Multi-store roadmap. Let's discuss (UPDATE: done)

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
11 years ago
neiltoncs wrote:
Andrei!! I downloaded the latest changeset (d3e7dd02cde0) and noticed that in IIS 7.5 does not work with the "Managed Pipeline Mode" in "Integrated". Only in "classic". It is shown the error "Request is not available in this context". Maybe it has something to do with the changeset d5c4566baad0 .

More details of the error:

Line 128:            string result = string.Empty;
Line 129:
Line 130:            if (_httpContext == null || _httpContext.Request == null)
Line 131:                return result;
Line 132:

Source File: c:\Users\Nei\web\Nop-teste\Libraries\Nop.Core\WebHelper.cs    Line: 130

Stack Trace:


[HttpException (0x80004005): Request is not available in this context]
   System.Web.HttpContext.get_Request() +9718452
   System.Web.HttpContextWrapper.get_Request() +28
   Nop.Core.WebHelper.ServerVariables(String name) in c:\Users\Nei\web\Nop-teste\Libraries\Nop.Core\WebHelper.cs:130
   Nop.Web.Framework.WebStoreContext.get_CurrentStore() in c:\Users\Nei\web\Nop-teste\Presentation\Nop.Web.Framework\WebStoreContext.cs:37
   Nop.Web.Framework.SettingsSource.<BuildRegistration>b__5(IComponentContext c, IEnumerable`1 p) in c:\Users\Nei\web\Nop-teste\Presentation\Nop.Web.Framework\DependencyRegistrar.cs:338
..............

See this change in WebHelper.cs file. Have a look at method "ServerVariables". Could you please revert it back (try-catch implementation) and test it one more time?
11 years ago
Reverted back. The error disappeared.
11 years ago
Changeset d3e7dd02cde0 compiled fine and ran with the following two warnings.  Was able to set up 2 stores, no problem, in VS2012.

Warning  1  Field 'Nop.Services.Tests.Discounts.DiscountServiceTests._storeContext' is never assigned to, and will always have its default value null  ...\nop300beta\nopcommerce_d3e7dd02cde0\src\Tests\Nop.Services.Tests\Discounts\DiscountServiceTests.cs  29  23  Nop.Services.Tests

Warning  2  The variable 'filterableSpecificationAttributeOptionIds' is assigned but its value is never used  ...\nop300beta\nopcommerce_d3e7dd02cde0\src\Presentation\Nop.Web\Administration\Controllers\ManufacturerController.cs  557  24  Nop.Admin

Running Windows 8 x 64bit
11 years ago
Thanks. Fixed
11 years ago
I am getting these errors while using the update script newest build 66dfda**********

Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '='.
Msg 515, Level 16, State 2, Line 1
Cannot insert the value NULL into column 'LanguageId', table 'iac.dbo.Customer'; column does not allow nulls. UPDATE fails.
The statement has been terminated.
Msg 547, Level 16, State 0, Line 2
The UPDATE statement conflicted with the FOREIGN KEY constraint "Affiliate_AffiliatedCustomers". The conflict occurred in database "iac", table "dbo.Affiliate", column 'Id'.
The statement has been terminated.
Msg 515, Level 16, State 2, Line 2
Cannot insert the value NULL into column 'AffiliateId', table 'iac.dbo.Customer'; column does not allow nulls. UPDATE fails.
The statement has been terminated.
Msg 547, Level 16, State 0, Line 2
The UPDATE statement conflicted with the FOREIGN KEY constraint "Affiliate_AffiliatedOrders". The conflict occurred in database "iac", table "dbo.Affiliate", column 'Id'.
The statement has been terminated.
Msg 515, Level 16, State 2, Line 2
Cannot insert the value NULL into column 'AffiliateId', table 'iac.dbo.Order'; column does not allow nulls. UPDATE fails.
The statement has been terminated.


(0 row(s) affected)
Msg 547, Level 16, State 0, Line 5
The INSERT statement conflicted with the FOREIGN KEY constraint "Affiliate_AffiliatedCustomers". The conflict occurred in database "iac", table "dbo.Affiliate", column 'Id'.
The statement has been terminated.
11 years ago
thrifty34 wrote:
I am getting these errors while using the update script newest build 66dfda**********
[...]

The upgrade script displays these errors if your install has been upgraded from 2.65 or earlier because the Customer to Affiliate foreign key name changed in 2.70 from Affiliate_AffiliatedCustomers to Customer_Affiliate and the Order to Affiliate foreign key name changed from Affiliate_AffiliatedOrders to Order_Affiliate. The 2.70 upgrade script didn't change the names of the foreign keys.

Upgrade script fixed in changeset 80e3252fc205.

---

To fix manually, edit upgradescripts\2.80-the next version\upgrade.sql and add the following after line 1353
IF EXISTS (SELECT 1
           FROM   sysobjects
           WHERE  name = 'Affiliate_AffiliatedCustomers'
           AND parent_obj = Object_id('Customer')
           AND Objectproperty(id,N'IsForeignKey') = 1)
BEGIN
  ALTER TABLE dbo.[Customer]
  DROP CONSTRAINT Affiliate_AffiliatedCustomers
END
GO

and add the following after line 1383
IF EXISTS (SELECT 1
           FROM   sysobjects
           WHERE  name = 'Affiliate_AffiliatedOrders'
           AND parent_obj = Object_id('Order')
           AND Objectproperty(id,N'IsForeignKey') = 1)
BEGIN
  ALTER TABLE dbo.[Order]
  DROP CONSTRAINT Affiliate_AffiliatedOrders
END
GO


Execute the upgrade script.

.
11 years ago
mb wrote:
I am getting these errors while using the update script newest build 66dfda**********
[...]

The upgrade script displays these errors if your install has been upgraded from 2.65 or earlier because the Customer to Affiliate foreign key name changed in 2.70 from Affiliate_AffiliatedCustomers to Customer_Affiliate and the Order to Affiliate foreign key name changed from Affiliate_AffiliatedOrders to Order_Affiliate. The 2.70 upgrade script didn't change the names of the foreign keys.

Upgrade script fixed in changeset 80e3252fc205.

---

To fix manually, edit upgradescripts\2.80-the next version\upgrade.sql and add the following after line 1353
IF EXISTS (SELECT 1
           FROM   sysobjects
           WHERE  name = 'Affiliate_AffiliatedCustomers'
           AND parent_obj = Object_id('Customer')
           AND Objectproperty(id,N'IsForeignKey') = 1)
BEGIN
  ALTER TABLE dbo.[Customer]
  DROP CONSTRAINT Affiliate_AffiliatedCustomers
END
GO

and add the following after line 1383
IF EXISTS (SELECT 1
           FROM   sysobjects
           WHERE  name = 'Affiliate_AffiliatedOrders'
           AND parent_obj = Object_id('Order')
           AND Objectproperty(id,N'IsForeignKey') = 1)
BEGIN
  ALTER TABLE dbo.[Order]
  DROP CONSTRAINT Affiliate_AffiliatedOrders
END
GO


Execute the upgrade script.

.


Thank you.
11 years ago
Hi, Off topic (kind of), but wondering if someone could help please?

I'm trying to have a category based main menu (top nav), along with a drop down menu for each category, showing the sub categories. I managed to do this in 2.8, but for some reason using this multi-store version it's always retuning '0' sub categories?

CatalogController.cs
[ChildActionOnly]
        public ActionResult CategoryMenuNavigation(int currentMenuCategoryId, int currentMenuProductId)
        {
            //get active category
            var activeCategory = _categoryService.GetCategoryById(currentMenuCategoryId);
            if (activeCategory == null && currentMenuProductId > 0)
            {
                var productCategories = _categoryService.GetProductCategoriesByProductId(currentMenuProductId);
                if (productCategories.Count > 0)
                    activeCategory = productCategories[0].Category;
            }
            var activeCategoryId = activeCategory != null ? activeCategory.Id : 0;

            var customerRolesIds = _workContext.CurrentCustomer.CustomerRoles
                .Where(cr => cr.Active).Select(cr => cr.Id).ToList();
            string cacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_MENU_NAVIGATION_MODEL_KEY, _workContext.WorkingLanguage.Id,
                string.Join(",", customerRolesIds), _storeContext.CurrentStore.Id, activeCategoryId);
            var cachedModel = _cacheManager.Get(cacheKey, () =>
            {
                var breadCrumb = activeCategory != null ?
                    GetCategoryBreadCrumb(activeCategory).Select(x => x.Id).ToList()
                    : new List<int>();
                return new CategoryMenuNavigationModel()
                {
                    Categories = PrepareCategoryMenuNavigationModel(0, breadCrumb).ToList()
                };
            }
            );

            //"CurrentCategoryId" property of "CategoryMenuNavigationModel" object depends on the current category or product.
            //We need to clone the cached model (the updated one should not be cached)
            var model = (CategoryMenuNavigationModel)cachedModel.Clone();
            model.CurrentMenuCategoryId = activeCategoryId;

            return PartialView(model);
        }


----------------------


[NonAction]
        protected IList<CategoryMenuNavigationModel.CategoryModel> PrepareCategoryMenuNavigationModel(int rootCategoryId,
        IList<int> breadCrumbIds)
            {
                var result = new List<CategoryMenuNavigationModel.CategoryModel>();
                foreach (var category in _categoryService.GetAllCategoriesByParentCategoryId(rootCategoryId))
                {
                    var categoryModel = new CategoryMenuNavigationModel.CategoryModel()
                    {
                        Id = category.Id,
                        Name = category.GetLocalized(x => x.Name),
                        SeName = category.GetSeName()
                    };

                    //product number for each category
                    if (_catalogSettings.ShowCategoryProductNumber)
                    {
                        var categoryIds = new List<int>();
                        categoryIds.Add(category.Id);
                        //include subcategories
                        if (_catalogSettings.ShowCategoryProductNumberIncludingSubcategories)
                            categoryIds.AddRange(GetChildCategoryIds(category.Id));
                        categoryModel.NumberOfProducts = _productService
                            .SearchProducts(categoryIds: categoryIds,
                            storeId: _storeContext.CurrentStore.Id,
                            pageSize: 1)
                            .TotalCount;
                    }

                    //subcategories
                    for (int i = 0; i <= breadCrumbIds.Count - 1; i++)
                        if (breadCrumbIds[i] == category.Id)
                            categoryModel.SubCategories.AddRange(PrepareCategoryMenuNavigationModel(category.Id, breadCrumbIds));

                    result.Add(categoryModel);
                }

                return result;
            }


----------------------


CategoryMenuNavigationModel.cs
using System;
using System.Collections.Generic;
using Nop.Web.Framework.Mvc;

namespace Nop.Web.Models.Catalog
{
    public partial class CategoryMenuNavigationModel : BaseNopModel, ICloneable
    {
        public CategoryMenuNavigationModel()
        {
            Categories = new List<CategoryModel>();
        }

        public int CurrentMenuCategoryId { get; set; }
        public List<CategoryModel> Categories { get; set; }

        public object Clone()
        {
            //we use a shallow copy (deep clone is not required here)
            return this.MemberwiseClone();
        }

        public class CategoryModel : BaseNopEntityModel
        {
            public CategoryModel()
            {
                SubCategories = new List<CategoryModel>();
            }

            public string Name { get; set; }

            public string SeName { get; set; }

            public int? NumberOfProducts { get; set; }

            public List<CategoryModel> SubCategories { get; set; }
        }
    }
}

----------------------


CategoryMenuNavigation.cshtml
@model CategoryMenuNavigationModel
@using Nop.Web.Models.Catalog;

@functions{
    public bool BreadCrumbContainsCurrentCategoryId(CategoryMenuNavigationModel.CategoryModel category)
    {
        if (Model.CurrentMenuCategoryId == 0)
            return false;

        if (category.Id == Model.CurrentMenuCategoryId)
            return true;

        foreach (var subCategory in category.SubCategories)
        {
            if (BreadCrumbContainsCurrentCategoryId(subCategory))
            {
                return true;
            }
        }

        return false;
    }
}
@helper RenderCategoryLine(CategoryMenuNavigationModel.CategoryModel category)
{
    
    var dropDownClass = "";
    if (category.SubCategories.Count > 0)
    {
        dropDownClass = "hasdropdown";
    }
    <li class="@dropDownClass @(category.Id == Model.CurrentMenuCategoryId ? "active" : "inactive")">
        <a href="@Url.RouteUrl("Category", new { SeName = category.SeName })">@category.Name.ToUpper()</a>
        @{
            
                if (category.SubCategories.Count > 0)
                {
            <div class="dropdown">
                <div class="row">
            <ul class="col_6 col">
                @foreach (var subCategory in category.SubCategories)
                {
                    @RenderSubCategoryLine(subCategory)
                }
            </ul>
            </div>
            </div>
                }
        }
    </li>
}



@helper RenderSubCategoryLine(CategoryMenuNavigationModel.CategoryModel category)
{
    <li class="@(category.Id == Model.CurrentMenuCategoryId ? "active" : "inactive")">
        <a href="@Url.RouteUrl("Category", new { SeName = category.SeName })">@category.Name</a>
    </li>
}


@if (Model.Categories.Count > 0)
{

                foreach (var category in Model.Categories)
                {
                    @RenderCategoryLine(category)
                }
}


----------------------


Menu.cshtml
@model MenuModel
@using Nop.Web.Models.Common;

@{
    //current category ID
    int currentMenuCategoryId = 0;
    if (Url.RequestContext.RouteData.Values["controller"].ToString().Equals("catalog", StringComparison.InvariantCultureIgnoreCase) &&
        Url.RequestContext.RouteData.Values["action"].ToString().Equals("category", StringComparison.InvariantCultureIgnoreCase))
    {
        currentMenuCategoryId = Convert.ToInt32(Url.RequestContext.RouteData.Values["categoryId"].ToString());
    }


    //current manufacturer ID
    int currentMenuManufacturerId = 0;
    if (Url.RequestContext.RouteData.Values["controller"].ToString().Equals("catalog", StringComparison.InvariantCultureIgnoreCase) &&
        Url.RequestContext.RouteData.Values["action"].ToString().Equals("manufacturer", StringComparison.InvariantCultureIgnoreCase))
    {
        currentMenuManufacturerId = Convert.ToInt32(Url.RequestContext.RouteData.Values["manufacturerId"].ToString());
    }


    //current product ID
    int currentMenuProductId = 0;
    if (Url.RequestContext.RouteData.Values["controller"].ToString().Equals("catalog", StringComparison.InvariantCultureIgnoreCase) &&
        Url.RequestContext.RouteData.Values["action"].ToString().Equals("product", StringComparison.InvariantCultureIgnoreCase))
    {
        currentMenuProductId = Convert.ToInt32(Url.RequestContext.RouteData.Values["productId"].ToString());
    }
}

<ul class="top_nav">
    @Html.Widget("header_menu_before")
    @*<li><a href="@Url.RouteUrl("HomePage")">@T("HomePage")</a></li>*@
    
    @Html.Action("CategoryMenuNavigation", "Catalog", new { currentMenuCategoryId = currentMenuCategoryId, currentMenuProductId = currentMenuProductId })

</ul>

----------------------

Any help would be gratefully received!
11 years ago
Never mind, I've managed to get it working :) although I've yet to test it with multiple stores!

Here's the fix:

CatalogController.cs

        [NonAction]
        protected IList<CategoryMenuNavigationModel.CategoryModel> PrepareCategoryMenuNavigationModel(int rootCategoryId)
        {
            var result = new List<CategoryMenuNavigationModel.CategoryModel>();
            foreach (var category in _categoryService.GetAllCategoriesByParentCategoryId(rootCategoryId))
            {
                var categoryModel = new CategoryMenuNavigationModel.CategoryModel()
                {
                    Id = category.Id,
                    Name = category.GetLocalized(x => x.Name),
                    SeName = category.GetSeName()
                };

                //product number for each category
                if (_catalogSettings.ShowCategoryProductNumber)
                {
                    var categoryIds = new List<int>();
                    categoryIds.Add(category.Id);
                    //include subcategories
                    if (_catalogSettings.ShowCategoryProductNumberIncludingSubcategories)
                        categoryIds.AddRange(GetChildCategoryIds(category.Id));
                    categoryModel.NumberOfProducts = _productService
                        .SearchProducts(categoryIds: categoryIds,
                        storeId: _storeContext.CurrentStore.Id,
                        pageSize: 1)
                        .TotalCount;
                }

                //subcategories
                categoryModel.SubCategories.AddRange(PrepareCategoryMenuNavigationModel(category.Id));
                //for (int i = 0; i <= breadCrumbIds.Count - 1; i++)
                //if (breadCrumbIds[i] == category.Id)
                //categoryModel.SubCategories.AddRange(PrepareCategoryMenuNavigationModel(category.Id, breadCrumbIds));

                result.Add(categoryModel);
            }

            return result;
        }


-----------


        [ChildActionOnly]
        public ActionResult CategoryMenuNavigation(int currentMenuCategoryId, int currentMenuProductId)
        {
            //get active category
            var activeCategory = _categoryService.GetCategoryById(currentMenuCategoryId);
            if (activeCategory == null && currentMenuProductId > 0)
            {
                var productCategories = _categoryService.GetProductCategoriesByProductId(currentMenuProductId);
                if (productCategories.Count > 0)
                    activeCategory = productCategories[0].Category;
            }
            var activeCategoryId = activeCategory != null ? activeCategory.Id : 0;



            var customerRolesIds = _workContext.CurrentCustomer.CustomerRoles
                .Where(cr => cr.Active).Select(cr => cr.Id).ToList();
            string cacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_MENU_NAVIGATION_MODEL_KEY, _workContext.WorkingLanguage.Id,
                string.Join(",", customerRolesIds), _storeContext.CurrentStore.Id, activeCategoryId);
            var cachedModel = _cacheManager.Get(cacheKey, () =>
                new CategoryMenuNavigationModel()
                {
                    Categories = PrepareCategoryMenuNavigationModel(0).ToList()
                }
            );

            //"CurrentCategoryId" property of "CategoryMenuNavigationModel" object depends on the current category or product.
            //We need to clone the cached model (the updated one should not be cached)
            var model = (CategoryMenuNavigationModel)cachedModel.Clone();
            model.CurrentMenuCategoryId = activeCategoryId;

            return PartialView(model);
        }
11 years ago
Greeting to all the community.

My first post here and I'm gonna get to the point straight away.

Our latest project is for a network that trades building materials.
This type of business absolutely needs support for multiple warehouses and of course multiple stores, especially in our case where the client spans his business across several countries.

We have already tested the multiple store support from the latest sources which seems to be superb, but we have same objections.
Our client is going to sell the same materials across his network, but he has to slightly modify some parameters of them per country (per shop). First and foremost the price.
So it would be great if we can limit product variants per shop and not the product as a whole. With the current multishop implementation we have to introduce to the system the same products again and again just to slightly modify them for each shop.
Do I miss something, or is there any plans for the above scenario to be supported.

Finally, from this issue:
http://nopcommerce.codeplex.com/workitem/9287
we see there are finally plans to support multiple warehouses on v3. Latest sources have no indications towards this feature.
Is there any possibility to see the feature in the latest sources in the very near future?

Finally, are there any estimations for the v3 release date?

Thanks a lot.
Markopoulos Grigoris
antyxsoft.eu
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.