***************************************************************************************************
Step 1: Add your new database tables in SQL Server (Hint: use the field name Id for an incremental integer primary key)
***************************************************************************************************
***************************************************************************************************
Step 2: Install the Entity Framework Reverse Engineering Power Tool
(See: http://visualstudiogallery.msdn.microsoft.com/72a60b14-1581-4b9b-89f2-846072eff19d)
***************************************************************************************************
***************************************************************************************************
Step 3: Create a new C# Console project in Visual Studio 2010
Create all your class entities and mappings by Right Clicking on the project you created, selecting Entity Framework and Reverse Engineering Code First.
(Hint: I couldn't get it to work for the database on my Web Host's server unless Persist Security Info=True)
***************************************************************************************************
***************************************************************************************************
Step 4: Open up your nopCommmerce Application and start adding files from top to bottom starting with Nop.Core
Libraries\Nop.Core:
Domains:
Create a new folder under Domains (Ex. CalendarEvent)
Add a class under the new folder (Ex. CalendarEvent.cs)
Replace the top of the class with:
using System;
using System.Collections.Generic;
using Nop.Core;
using Nop.Core.Domain.Localization;
Change class CalendarEvent to public partial class CalendarEvent : BaseEntity, ILocalizedEntity
add the line private ICollection<Nop.Core.Domain.CalendarEvent.CalendarEvent> _calendarEvents;
Copy in the set and gets created in the project that used the Entity Framework Reverse Engineer tool (Found in the Entities Folder) from Step 3.
Comment Out the Primary key (ex.: // public int Id { get; set; })
For the rest of the get and sets, replace the word public with public virtual
Add the following at the end:
///// <summary>
///// Gets or sets the CalendarEvents
///// </summary>
public virtual ICollection<Nop.Core.Domain.CalendarEvent.CalendarEvent> CalendarEvents
{
get { return _calendarEvents ?? (_calendarEvents = new List<Nop.Core.Domain.CalendarEvent.CalendarEvent>()); }
protected set { _calendarEvents = value; }
}
Add another class called CalendarEventSortingEnums.
You can remove the usings at the top
Change class CalendarEventSortingEnums to public enum CalendarEventSortingEnums
Enter in a few enums for primary sorting purposes
Example:
eventStartDateSort = 0,
ticketsGoOnSaleStartSort = 5,
eventTitleSort = 10,
Don't ask me why the last one has a comma, it just does
***************************************************************************************************
***************************************************************************************************
Step 5: Libraries\Nop.Data
Mappings:
Create a new folder under Domains (Ex. CalendarEvent)
Add a class under the new folder (Ex. CalendarEventMap.cs)
Replace the top usings with:
using System.Data.Entity.ModelConfiguration;
using Nop.Core.Domain.CalendarEvent;
Change class CalendarEventMap to public partial class CalendarEventMap : EntityTypeConfiguration<Nop.Core.Domain.CalendarEvent.CalendarEvent>
Copy in all that t. stuff created in the project that used the Entity Framework Reverse Engineer tool (Found in the Mapping Folder) from Step 3.
Copy in all that t. stuff starting with:
public CalendarEventMap()
{
// Primary Key
this.HasKey(t => t.EventId);
***************************************************************************************************
***************************************************************************************************
Step 6: Libraries\Nop.Services
Create a new Folder (Ex.: CalendarEvent)
Add a class under the new folder (Ex. CalendarEventService.cs)
Replace the usings with something like:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using Nop.Core;
using Nop.Core.Caching;
using Nop.Core.Data;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.CalendarEvent;
using Nop.Core.Domain.Common;
using Nop.Core.Domain.Localization;
using Nop.Core.Domain.Orders;
using Nop.Core.Events;
using Nop.Data;
using Nop.Services.Localization;
using Nop.Services.Messages;
change class CalendarEventService to public partial class CalendarEventService : ICalendarEventService
This one is kind of tricky and too wordy to list the changes. I am afriad you will have to go solo on this one. You will have to duplicate by copying and pasting and tweaking some of the other services code such as the Manufactuer Service. Also, you will have to create the ICalendarEventService before you get rid of the errors when you create the CalendarEventService.
***************************************************************************************************
***************************************************************************************************
Step 7: Nop.Web:
I know I have been going from Top to bottom so far but I start jumping around at this point. It is probably better to create the Model classes before you create the Mapping Extensions.
Models:
Create a new Folder (Ex.: CalendarEvent)
Add a class under the new folder (Ex. CalendarEventModel.cs)
Replace the Usings at the top with:
using System.Collections.Generic;
using Nop.Web.Framework.Mvc;
using Nop.Web.Models.Media;
Replace public class CalendarEventModel with public class CalendarEventModel : BaseNopEntityModel
Add:
public CalendarEventModel()
{
//PictureModel = new PictureModel();
//FeaturedProducts = new List<ProductModel>();
//Products = new List<ProductModel>();
//PagingFilteringContext = new CatalogPagingFilteringModel();
}
Note that I copied in some code of possible related tables that I commented out. This is a good reference for when you start relating
your new tables to each other
Copy in the set and gets created in the project that used the Entity Framework Reverse Engineer tool (Found in the Entities Folder) from Step 3.
Comment out the first get set referring to the primary key Id
Note: I have date fields so I added using System; because I was getting an error with public Nullable<System.DateTime>
Example:
//public int Id { get; set; }
public string EventStatus { get; set; }
public string EventTitle { get; set; }
public string EventBody { get; set; }
public string EventDirections { get; set; }
public Nullable<System.DateTime> EventStartDate { get; set; }
public Nullable<System.DateTime> EventEndDate { get; set; }
public Nullable<int> SortOrder { get; set; }
...
At the bottom of the class, add:
//public PictureModel PictureModel { get; set; }
public CalendarEventPagingFilteringModel PagingFilteringContext { get; set; }
//public IList<ProductModel> FeaturedProducts { get; set; }
//public IList<ProductModel> Products { get; set; }
Next, we have to create CalendarEventPagingFilterModel to get rid of the error we just created.
Add the class CalendarEventPagingFilterModel
Replace the Usings with:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web.Mvc;
using Nop.Core;
using Nop.Core.Domain.CalendarEvent;
using Nop.Services.CalendarEvent;
using Nop.Services.Localization;
using Nop.Web.Framework;
using Nop.Web.Framework.Mvc;
using Nop.Web.Framework.UI.Paging;
Replace public class CalendarEventPagingFilteringModel with public class CalendarEventPagingFilteringModel : BasePageableModel
You will have to add nested classes (see other PagingFilterModel classes as examples) but at least enter the following:
#region Constructors
public CalendarEventPagingFilteringModel()
{
this.AvailableSortOptions = new List<SelectListItem>();
this.AvailableViewModes = new List<SelectListItem>();
this.PageSizeOptions = new List<SelectListItem>();
}
#endregion
#region Properties
public bool AllowCalendarEventSorting { get; set; }
public IList<SelectListItem> AvailableSortOptions { get; set; }
public bool AllowCalendarEventViewModeChanging { get; set; }
public IList<SelectListItem> AvailableViewModes { get; set; }
public bool AllowCustomersToSelectPageSize { get; set; }
public IList<SelectListItem> PageSizeOptions { get; set; }
/// <summary>
/// Order by
/// </summary>
[NopResourceDisplayName("CalendarEvent.OrderBy")]
public int OrderBy { get; set; }
/// <summary>
/// CalendarEvent sorting
/// </summary>
[NopResourceDisplayName("CalendarEvent.ViewMode")]
public string ViewMode { get; set; }
#endregion
Hint: NopResourceDisplayName
Add the Class SearchModel.cs
Replace the Usings with:
using System.Collections.Generic;
using System.Web.Mvc;
using Nop.Web.Framework;
using Nop.Web.Framework.Mvc;
Replace public class SearchModel with public class SearchModel : BaseNopModel
Add:
public SearchModel()
{
PagingFilteringContext = new SearchPagingFilteringModel();
CalendarEvents = new List<CalendarEventModel>();
this.AvailableCalendarEvents = new List<SelectListItem>();
//this.AvailableManufacturers = new List<SelectListItem>();
}
public string Warning { get; set; }
public bool NoResults { get; set; }
/// <summary>
/// Query string
/// </summary>
[NopResourceDisplayName("Search.SearchTerm")]
[AllowHtml]
public string Q { get; set; }
/// <summary>
/// ID
/// </summary>
[NopResourceDisplayName("Search.Id")]
public int Id { get; set; }
/// <summary>
/// FLAnnualBusinesses ID
/// </summary>
//[NopResourceDisplayName("Search.FLAnnualBusinessesId")]
//public int FLAnnualBusinessesid { get; set; }
//[NopResourceDisplayName("Search.Id")]
//public int Id { get; set; }
/*
/// <summary>
/// Manufacturer ID
/// </summary>
[NopResourceDisplayName("Search.Manufacturer")]
public int Mid { get; set; }
/// <summary>
/// Price - From
/// </summary>
[AllowHtml]
public string Pf { get; set; }
/// <summary>
/// Price - To
/// </summary>
[AllowHtml]
public string Pt { get; set; }
/// <summary>
/// A value indicating whether to search in descriptions
/// </summary>
[NopResourceDisplayName("Search.SearchInDescriptions")]
public bool Sid { get; set; }
/// <summary>
/// A value indicating whether to search in descriptions
/// </summary>
* */
[NopResourceDisplayName("Search.AdvancedSearch")]
public bool As { get; set; }
public IList<SelectListItem> AvailableCalendarEvents { get; set; }
//public IList<SelectListItem> AvailableManufacturers { get; set; }
public SearchPagingFilteringModel PagingFilteringContext { get; set; }
public IList<CalendarEventModel> CalendarEvents { get; set; }
We still have an error with SearchPagingFilteringModel
Add the class SearchPagingFilteringModel
using Nop.Web.Framework.UI.Paging;
namespace Nop.Web.Models.CalendarEvent
{
public class SearchPagingFilteringModel : BasePageableModel
{
}
}
We should have no errors at this point
***************************************************************************************************
***************************************************************************************************
Step 8: Nop.Web:
Extensions:
Open up MappingExtensions.cs
Add using Nop.Web.Models.CalendarEvent;
This part is a little bit of a pain. Use your Find and Replace skills to add the following for each field in the table:
//CalendarEvent
public static CalendarEventModel ToModel(this CalendarEventModel entity)
{
if (entity == null)
return null;
//Name = entity.GetLocalized(x => x.Name),
// Description = entity.GetLocalized(x => x.Description),
// MetaKeywords = entity.GetLocalized(x => x.MetaKeywords),
// MetaDescription = entity.GetLocalized(x => x.MetaDescription),
// MetaTitle = entity.GetLocalized(x => x.MetaTitle),
// SeName = entity.GetSeName(),
var model = new CalendarEventModel()
{
Id = entity.Id,
EventStatus = entity.EventStatus,
EventTitle = entity.EventTitle,
EventBody = entity.EventBody,
EventDirections = entity.EventDirections,
EventStartDate = entity.EventStartDate,
EventEndDate = entity.EventEndDate,
SortOrder = entity.SortOrder,
TicketsGoOnSaleStart = entity.TicketsGoOnSaleStart,
TicketsGoOnSaleEnd = entity.TicketsGoOnSaleEnd,
FeatureEventStart = entity.FeatureEventStart,
FeatureEventEnd = entity.FeatureEventEnd,
MainSKU = entity.MainSKU,
MainURL = entity.MainURL,
MainPDFURL = entity.MainPDFURL,
MainRegistrationURL = entity.MainRegistrationURL,
MainVenueId = entity.MainVenueId,
MainArtistId = entity.MainArtistId,
MainInfoContactId = entity.MainInfoContactId,
MainInfoContact = entity.MainInfoContact,
MainInfoTo = entity.MainInfoTo,
MainInfoCC = entity.MainInfoCC,
MainInfoBCC = entity.MainInfoBCC,
MainBillingContactId = entity.MainBillingContactId,
MainBillingContact = entity.MainBillingContact,
MainBillingTo = entity.MainBillingTo,
MainBillingCC = entity.MainBillingCC,
MainBillingBCC = entity.MainBillingBCC,
Tags = entity.Tags,
OpenToPublic = entity.OpenToPublic,
NoLongerAvailableMessage = entity.NoLongerAvailableMessage,
CreatedOnUtc = entity.CreatedOnUtc,
CreatedBy = entity.CreatedBy,
UpdatedOnUtc = entity.UpdatedOnUtc,
UpdatedBy = entity.UpdatedBy,
};
return model;
}
***************************************************************************************************
***************************************************************************************************
Step 9: Nop.Web
Infrastructure/RouteProvider.cs
Add the following:
//CalendarEvent
// LJD 03/30/2012
routes.MapLocalizedRoute("CalendarEventList",
"CalendarEvent/all/",
new { controller = "CalendarEvent", action = "CalendarEventAll" },
new[] { "Nop.Web.Controllers" });
routes.MapLocalizedRoute("CalendarEvent",
"m/{Id}/{SeName}",
new { controller = "CalendarEvent", action = "CalendarEvent", SeName = UrlParameter.Optional },
new { Id = @"\d+" },
new[] { "Nop.Web.Controllers" });
***************************************************************************************************
***************************************************************************************************
Step 10: Nop.Web.Framework
Open up DependencyRegistrar.cs
Add using Nop.Services.CalendarEvent;
Add builder.RegisterType<CalendarEventService>().As<ICalendarEventService>().InstancePerHttpRequest();
***************************************************************************************************
***************************************************************************************************
Step 11: Nop.Web\Administration\
Adding the Administration Model:
Right Click on the Models folder in Nop.Administration and add a new folder called CalendarEvent
Add a new class called CalendarEventModel
Also too wordy to go through what to put into the class. Look at another Administration Model Class as a guide to creating this Model
Add CalendarEventListModel.cs
Change the Usings to:
using System.Collections.Generic;
using System.Web.Mvc;
using Nop.Web.Framework;
using Nop.Web.Framework.Mvc;
using Telerik.Web.Mvc;
Change public class CalendarEventListModel To public class CalendarEventListModel : BaseNopModel
Add:
public CalendarEventListModel()
{
//AvailableCategories = new List<SelectListItem>();
}
public GridModel<CalendarEventModel> CalendarEvents { get; set; }
[NopResourceDisplayName("Admin.CalendarEvent.List.SearchCalendarEventeventTitle")]
[AllowHtml]
public string SearcheventTitle { get; set; }
[NopResourceDisplayName("Admin.CalendarEvent.List.SearchCalendarEventeventStartDate")]
[AllowHtml]
public string SearcheventStartDate { get; set; }
[NopResourceDisplayName("Admin.CalendarEvent.List.SearchCalendarEventticketsGoOnSaleStart")]
[AllowHtml]
public string SearchticketsGoOnSaleStart { get; set; }
***************************************************************************************************
***************************************************************************************************
Step 12: Nop.Web\Administration\
Adding the Administration Validator:
Right Click ont the Validators folder in Nop.Administration and add a new folder called CalendarEvent
Add a new class called CalendarEventValidator
Add the following:
using FluentValidation;
using Nop.Admin.Models.CalendarEvent;
using Nop.Services.Localization;
namespace Nop.Admin.Validators.CalendarEvent
{
public class CalendarEventValidator : AbstractValidator<CalendarEventModel>
{
public CalendarEventValidator(ILocalizationService localizationService)
{
RuleFor(x => x.eventTitle).NotNull().WithMessage(localizationService.GetResource("Admin.CalendarEvent.Fields.eventTitle.Required"));
}
}
}
Hint: The LocaleStringResource Table is where you add the records for your strings
***************************************************************************************************
***************************************************************************************************
Step 14: Nop.Web\Administration\
Open Views\MappingExtensions.cs
Add:
using Nop.Admin.Models.CalendarEvent;
using Nop.Core.Domain.CalendarEvent;
using Nop.Services.CalendarEvent;
Add:
#region CalendarEvent
public static CalendarEventModel ToModel(this CalendarEvent entity)
{
return Mapper.Map<CalendarEvent, CalendarEventModel>(entity);
}
public static CalendarEvent ToEntity(this CalendarEventModel model)
{
return Mapper.Map<CalendarEventModel, CalendarEvent>(model);
}
public static CalendarEvent ToEntity(this CalendarEventModel model, CalendarEvent destination)
{
return Mapper.Map(model, destination);
}
#endregion
***************************************************************************************************
***************************************************************************************************
Step 15: Nop.Web\Administration\
Adding the Administration Controller:
Right Click on the Controllers Folder in Nop.Admin and add a new Controller
Call it CalendarEventController.cs
Replace the Usings with:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Nop.Admin.Models.Catalog;
using Nop.Admin.Models.CalendarEvent;
using Nop.Core;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.CalendarEvent;
using Nop.Core.Domain.Common;
using Nop.Services.Catalog;
using Nop.Services.CalendarEvent;
using Nop.Services.ExportImport;
using Nop.Services.Localization;
using Nop.Services.Logging;
using Nop.Services.Media;
using Nop.Services.Security;
using Nop.Web.Framework.Controllers;
using Nop.Web.Framework.Mvc;
using Telerik.Web.Mvc;
Change public class CalendarEventController : Controller to
[AdminAuthorize]
public class CalendarEventController : BaseNopController
Again, much too wordy to detail the rest.
Look at other controllers to finish this Controller Class
Now you can start working on your views for your front end for this table.
Again, look at other views within NopCommerce for the basic layout.
***************************************************************************************************