I need help in adding extra product fields in database.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
13 years ago
I have a website which is based on 1.4v

For my website i wanted to add extra products fields (like Cost Price, MSRP and UPC code) because there was no cost price in 1.4version.

My friend worked on my website and added those fields (created table and did other modification in code and new SPs etc)

So in my website i had a new table "ProductVariant_AdditionalFields"
http://img254.imageshack.us/img254/707/varianttablename.jpg

This is the structure of this table: http://img810.imageshack.us/img810/7601/varianttablestructure.jpg

Now i want to update my website to 1.9v.

My 1.4v database included the extra table and now I have updated my database from 1.4 to 1.9 successfully. So now my updated database is 1.9v along with the extra table (with data in it)

Can anyone help me with step by step process how to do required modifications in the code?
13 years ago
This is stickied in the development forum, it may help:

https://www.nopcommerce.com/boards/t/6370/how-to-extending-nopcommerce.aspx
13 years ago
thank you for the example but it coves something about banner but i want to add extra fields related to product and i am new in asp.net, i would appreciate if anyone can help me with code by taking my situation as example.
13 years ago
Just read the first half.  The second half (about the banner) applies to creating entirely new objects.

In the first half, he shows how to add a stylesheet field to the category object.  If you follow that as a guideline, and just make the logical replacements, it should work.

Whenever he talks about category/categories, you need to replace that with ProductVariant/ProductVarients.

Whenever he talks about the stylesheet field, you need to handle the Cost, MSRP, and UPC fields.

Reread it, and stop at the "Adding a new entity", where he starts talking about the banner, that's not what you're looking for.

Once you get it working, you'll need to do an update to the database to get your old data into the ProductVariant table, once that's done (and tested thoroughly), you can drop the extra table.

Hope that helps.
13 years ago
thank you, iwill try the example and reply back with an answer if i am able to do it successfully or not
13 years ago
ok i am not very good with entity framework so i tried it by referring to the above example and my 1.4 website:

1) As i mentioned above, after i updated my database to 1.8, now my 1.8 database includes that extra table "ProductVariant_AdditionalFields" that includes all the data

2) Now following the above example, i created a folder "Extension" in this location: Libraries\Nop.BusinessLogic\

Now, i added a "ProductVariantAddInfo.cs" file for which here is my code:

//My Customization - START

using System;
using System.Collections.Generic;
using System.Text;
using NopSolutions.NopCommerce.BusinessLogic.Categories;
using NopSolutions.NopCommerce.BusinessLogic.CustomerManagement;
using NopSolutions.NopCommerce.BusinessLogic.Media;
using NopSolutions.NopCommerce.BusinessLogic.Products.Attributes;
using NopSolutions.NopCommerce.BusinessLogic.Promo.Discounts;
using NopSolutions.NopCommerce.BusinessLogic.Tax;
using NopSolutions.NopCommerce.BusinessLogic.Warehouses;


namespace NopSolutions.NopCommerce.BusinessLogic.Products
{
    /// <summary>
    /// Represents a product variant
    /// </summary>
    public partial class ProductVariantAddInfo : BaseEntity
    {
        #region Ctor
        /// <summary>
        /// Creates a new instance of the ProductVariantAddInfo class
        /// </summary>
        public ProductVariantAddInfo()
        {
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the product variant identifier
        /// </summary>
        public int ProductVariantID { get; set; }

        /// <summary>
        /// Gets or sets the product identifier
        /// </summary>
        public int ProductID { get; set; }


        /// <summary>
        /// Gets or sets the MSRP price
        /// </summary>
        public decimal MSRP { get; set; }

        /// <summary>
        /// Gets or sets the UPC
        /// </summary>
        public string UPC { get; set; }

    }
        #endregion
}
//My Customization - END





3) Now i guess i have to add code for "Insert" and "Update" in ProductManager.cs file

Now after public static Product InsertProduct method

After line 490 "return product;"

i added this code:


// My Customization - Start
        /// <summary>
        /// Inserts a product variant
        /// </summary>
        /// <param name="ProductID">The product identifier</param>
          /// <param name="MSRP">MSRP</param>
        /// <param name="UPC">UPC</param>
        /// /// <returns>Product variant</returns>
        public static ProductVariantAddInfo InsertProductVariantAddInfo(int ProductVariantID, int ProductID,
             decimal MSRP, string UPC)
        {
            DBProductVariantAddInfo dbItem = DBProviderManager<DBProductProvider>.Provider.InsertProductVariantAddInfo(
                ProductVariantID, ProductID, MSRP,UPC);
            ProductVariantAddInfo productVariant = DBMapping(dbItem);

            if (ProductManager.CacheEnabled)
            {
                NopRequestCache.RemoveByPattern(PRODUCTS_PATTERN_KEY);
                NopRequestCache.RemoveByPattern(PRODUCTVARIANTS_PATTERN_KEY);
                NopRequestCache.RemoveByPattern(TIERPRICES_PATTERN_KEY);
            }

            return productVariant;
        }
        // My Customization - END


but i am getting error as DBProductVariantAddInfo cound not be found


4) Now , in UPDATE product, after public static product UpdateProduct method

after line 602 after "return product"

i added this code:


// My Customization - START
        private static ProductVariantAddInfo DBMapping(DBProductVariantAddInfo dbItem)
        {
            if (dbItem == null)
                return null;

            ProductVariantAddInfo item = new ProductVariantAddInfo();
            item.ProductVariantID = dbItem.ProductVariantID;
            item.ProductID = dbItem.ProductID;
            
            
            item.MSRP = dbItem.MSRP;
            item.UPC = dbItem.UPC;
            return item;
        }
        // My Customization - End


But again i am getting error,

please help me in correcting my code and guide me if i have to add anything else other than these two above methods ?

and what about stored procedures ? do i need to add SPs too ? because my updated 1.8v database also includes sps that i added in 1.4 version. Should i delete them ? or no ? Please help !!!
13 years ago
Bump ???
13 years ago
Disclaimer: I know not of what I speak.  I'm just comparing what you've done, to the link I suggested.

First, something that I do know, that may be confusing you.  When you see something like this:
  public partial class ClassName

It means that the class definition can be spread across multiple files.  When you do that, every time you want to add to the class, you need to open it the same way (including the first time).  One reason for starting a class like that, as the fine folks at nop did, is to allow others to extend the class later, should they need to.

This is what you're trying to do now.  Take the already existing class, and add new attributes to it.  That said...

You can just name the file "ProductVariant.cs" (I'm assuming the '.cs.cs' was a typo)

Don't change the name of the class, you want to modify the existing class, not create a new one.
Open with:
  public partial class ProductVariant : BaseEntity

Don't include the ProductVariantID or ProductID properties, they already exist in the class your modifying.


edit: clicked submit by accident, may add more later.

edit2: ok, it's not much later, but I'm adding more.

For the insert/update, you need to work with these methods (_not_ the 'Product' methods):
  public static ProductVariant InsertProductVariant
  public static ProductVariant UpdateProductVariant

For both of those functions, just go down to the end of the parameter list, and add the parameters that are new (decimal msrp, string upc -- keep these lowercase inside the parameter list).

In each of those methods you'll see a block of assigns, just add yours to the bottom of the list:
  productVariant.MSRP = msrp;
  productVariant.UPC = upc;    

Remember, you'll also need to edit the productVariant table itself, to add these fields.  Then you'll want to copy the data from the old table.

You'll also need to update the Entity model: Libraries\Nop.BusinessLogic\Data\NopModel.edmx.
Find the ProductVariant table (pretty much in the middle, just below the Product table), right click on the properties list, and use the 'Add - Scalar Property' option.  

You'll get a generic 'Property' added to the bottom of the list, change it's name, and datatype using the Properties window in the bottom right of Visual Studio.  Once you have them both set up, save the edmx file, and rebuild.

ps: don't forget my first disclaimer, you may think it's wrong, but it's not.

pps: just a reminder, from the tutorial - once you've modified the insert/update methods, you should run a "find all references" on them, and modify those calls as well.
13 years ago
thank you aGorilla,

i am new in asp.net , i would appreciate if you could explain me with steps and code where and what changes to make..
13 years ago
Here is a quick and dirty step-by-step tutorial for adding a new table to nopCommerce 1.8.  I have a video series that is half done and that I keep promising but alas I just haven't had time to finish it.  For brevity sake I will condense this tutorial into more broad concepts.  This will mean the developer will have to read between the lines a bit and rely on good ole' trial and error.  Ok, lets start.

For this example we will be adding a single table called "Widget" with no relationships to any other table.  This is to simplify the tutorial.  I can add a more complex example with relationships and multiple tables in another tutorial.

There are basically 5 steps to this process:

1. Create the Widget table in the db.
2. Create the Widget class.
3. Update the db schema.
4. Update the object context
5. Create new CRUD manager class.

Create Widget Table in DB
1. Open SQL management server or any other editing program and right click the tables tab under your nop db tree and select New Table.
2. Add the following column names and data types.  Be aware of case.
Id-->int-->not null-->mark as identity column
Name-->nvarchar(50)-->not null
Description-->nvarchar(200)-->not null
3. Save table name as "Widget".

Create Widget Class
1. Create new folder in Nop.BusinessLogic called "Widgets".
2. Create new class file called "Widget". The code should like like below

using System;
using System.Collections.Generic;
using System.Text;

namespace NopSolutions.NopCommerce.BusinessLogic.Widgets.Widget
{
    /// <summary>
    /// Represents a widget
    /// </summary>
    public partial class Widget : BaseEntity
    {
        #region Ctor
        /// <summary>
        /// Creates a new instance of the Widget class
        /// </summary>
        public Widget()
        {
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the widget identifier
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// Gets or sets the name
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Gets or sets the description
        /// </summary>
        public string Description { get; set; }

        #endregion
    }
}


Update DB Schema
1. Open NopModel.edmx from Nop.BusinessLogic.Data
2. Right click on any open space in the model diagram and click 'Update Model From Database'.
3. A wizard will pop up and your db connection should already be setup.  If not then set it up. Click no and then Next.
4. A tree view of the nop db will appear.  Open the tables tree and ONLY select the Widget table you created in step 1.  Click Finish.
5. You should now see your table in the edmx diagram.
6. IMPORTANT!! Ensure that your table name and column names match your class names EXACTLY.  You will experience great pain if they are different.

Update Object Context
1. Open NopObjectContext.cs from Nop.BusinessLogic.Data
2. Add a reference (using) to NopSolutions.NopCommerce.BusinessLogic.Widgets.
3. Under the Object sets region add the following code.

/// <summary>
        /// Gets an Widget instance that is used to query, add, modify, and delete objects of the specified entity type.
        /// </summary>
        public ObjectSet<Widget> Widgets
        {
            get
            {
                if ((_widgets == null))
                {
                    _widgets = CreateObjectSet<Widget>();
                }
                return _widgets;
            }
        }
        private ObjectSet<Widget> _widgets;


NOTE: If you don't have intellisense support then you missed something or you need to build the project.

Create New CRUD Manager Class
1. Create a new class file called WidgetManager.cs in Nop.BusinessLogic.Widgets
2. Reference (using) NopSolutions.NopCommerce.BusinessLogic.Data. NOTE: This example does not include caching support.  You will need to determine if this is necessary based on your application needs.
3. Design your CRUD operations to match your application needs.  Here are some examples below.

GET
public static Widget GetWidgetById(int widgetId)
        {
            if (widgetId == 0)
                return null;

            var context = ObjectContextHelper.CurrentObjectContext;
            var query = from w in context.Widgets
                        where w.WidgetId == widgetId
                        select w;
            var widget = query.SingleOrDefault();
            return widget;
        }


INSERT
public static Widget AddWidget(string name, string description)
        {
            name = CommonHelper.EnsureMaximumLength(name, 50);
            desc = CommonHelper.EnsureMaximumLength(value, 200);

            var context = ObjectContextHelper.CurrentObjectContext;

            var widget = context.Widgets.CreateObject();
            widget.Name = name;
            widget.Description = desc;

            context.Settings.AddObject(widget);
            context.SaveChanges();

            return widget;
        }


UPDATE
public static Widget UpdateWidget(string name, string description)
        {
            name = CommonHelper.EnsureMaximumLength(name, 50);
            desc = CommonHelper.EnsureMaximumLength(value, 200);
            
            var widget = GetWidgetById(widgetId);
            if (widget == null)
                 return null;

            var context = ObjectContextHelper.CurrentObjectContext;
            if !(context.IsAttached(widget))
                 context.Widgets.Attach(widget);

            widget.Name = name;
            widget.Description = desc;
            context.SaveChanges();

            return widget;
        }


DELETE
public static void DeleteWidget(int widgetId)
        {
            var widget = GetWidgetById(widgetId);
            if (widget == null)
                return;

            var context = ObjectContextHelper.CurrentObjectContext;
            if (!context.IsAttached(widget))
                context.Settings.Attach(widget);

            context.DeleteObject(widget);
            context.SaveChanges();

        }


Finally.  Build your project and reference the widgets assembly where ever you need to access your widget entity.

A couple of notes:
1.  This is a very simplistic example.  However, if you can get this to work (which you should have no problem doing) you will be able to customize this to meet your needs.
2. Ensure your have followed all of the above steps EXACTLY.  Don't skip over steps that you think you already understand.  This process is more about configuration than convention.
3. This example is specifically for nopCommerce v1.8.  I believe it will work for 1.7 as well.  < 1.7 uses the ADO.Net convention.  For 1.9 the process is similar but instead of manager classes you will need to implement interfaces instead.
4.  Tables that have relationships adds another wrinkle to this process.  It is not difficult but at this time, outside the scope of this tutorial.  
5.  Keep in mind that this tutorial is NOT upgrade ready.  Because we directly modified NopModel.edmx and NopObjectContext.cs, any future upgrade will over write what you have done.  If you have more than one table you are adding or you just want to future proof (although this is not really a concern after 1.9) your application, I would recommend creating a separate data model project for your custom application.  This is not that difficult to achieve.

I think that is it.  I hope this is helpful.  Let me know if anyone finds any errors.

trevor
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.