using System;
using System.Text;
using System.Linq;
using System.Web.Mvc;
using Northwind;
using Northwind.BusinessObject;
using NorthwindCS.Models;
using NorthwindCS.ViewModels;
using NorthwindCS.Domain;
using System.Collections.Generic;
using System.Configuration;
using System.Text.RegularExpressions;
 
namespace NorthwindCS.Controllers.Base
{ 
     /// <summary>
     /// Base class for ProductsController.  Do not make changes to this class,
     /// instead, put additional code in the ProductsController class 
     /// </summary>
     public class ProductsControllerBase : Controller
     { 
 
         /// <summary>
         /// GET: /Products/
         /// </summary>
         public ActionResult Index()
         {
             return View();
         }
 
         /// <summary>
         /// GET: /Products/Add
         /// </summary>
         public ActionResult Add()
         {
             return GetAddViewModel();
         }
 
         /// <summary>
         /// POST: /Products/Add
         /// </summary>
         [HttpPost]
         [ValidateAntiForgeryToken]
         public ActionResult Add(ProductsViewModel viewModel, string returnUrl)
         {
             if (ModelState.IsValid)
             {
                 try
                 {
                     // add new record
                     AddEditProducts(viewModel, CrudOperation.Add);
 
                     if (Url.IsLocalUrl(returnUrl))
                         return Redirect(returnUrl);
                     else
                         return RedirectToAction("Index");
                 }
                 catch(Exception ex)
                 {
                     ModelState.AddModelError("", ex.Message);
                 }
             }
 
             // if we got this far, something failed, redisplay form
             return GetAddViewModel();
         }
 
         private ActionResult GetAddViewModel()
         {
             ProductsViewModel viewModel = new ProductsViewModel();
             viewModel.ProductsModel = null;
             viewModel.Operation = CrudOperation.Add;
             viewModel.ViewControllerName = "Products";
             viewModel.ViewActionName = "Add";
             viewModel.SuppliersDropDownListData = Suppliers.SelectSuppliersDropDownListData();
             viewModel.CategoriesDropDownListData = Categories.SelectCategoriesDropDownListData();
 
             if (Request.UrlReferrer != null)
                 viewModel.ViewReturnUrl = Request.UrlReferrer.PathAndQuery;
             else
                 viewModel.ViewReturnUrl = "Index";
 
             return View(viewModel);
         }
 
         /// <summary>
         /// GET: /Products/Update/5
         /// </summary>
         public ActionResult Update(int id)
         {
             return GetUpdateViewModel(id);
         }
 
         /// <summary>
         /// POST: /Products/Update/5
         /// </summary>
         [HttpPost]
         [ValidateAntiForgeryToken]
         public ActionResult Update(int id, ProductsViewModel viewModel, string returnUrl)
         {
             if (ModelState.IsValid)
             {
                 try
                 {
                     // update record
                     AddEditProducts(viewModel, CrudOperation.Update);
 
                     if (Url.IsLocalUrl(returnUrl))
                         return Redirect(returnUrl);
                     else
                         return RedirectToAction("Index");
                 }
                 catch(Exception ex)
                 {
                     ModelState.AddModelError("", ex.Message);
                 }
             }
 
             // if we got this far, something failed, redisplay form
             return GetUpdateViewModel(id);
         }
 
         public ActionResult GetUpdateViewModel(int id)
         {
             // select a record by primary key(s)
             Products objProducts = Products.SelectByPrimaryKey(id);
 
             // assign values to the model
             Models.ProductsModel model = new Models.ProductsModel();
             model.ProductID = objProducts.ProductID;
             model.ProductName = objProducts.ProductName;
             model.SupplierID = objProducts.SupplierID;
             model.CategoryID = objProducts.CategoryID;
             model.QuantityPerUnit = objProducts.QuantityPerUnit;
             model.UnitPrice = objProducts.UnitPrice;
             model.UnitsInStock = objProducts.UnitsInStock;
             model.UnitsOnOrder = objProducts.UnitsOnOrder;
             model.ReorderLevel = objProducts.ReorderLevel;
             model.Discontinued = objProducts.Discontinued;
 
             // assign values to the view model
             ProductsViewModel viewModel = new ProductsViewModel();
             viewModel.ProductsModel = model;
             viewModel.Operation = CrudOperation.Update;
             viewModel.ViewControllerName = "Products";
             viewModel.ViewActionName = "Update";
             viewModel.SuppliersDropDownListData = Suppliers.SelectSuppliersDropDownListData();
             viewModel.CategoriesDropDownListData = Categories.SelectCategoriesDropDownListData();
 
             if (Request.UrlReferrer != null)
                 viewModel.ViewReturnUrl = Request.UrlReferrer.PathAndQuery;
             else
                 viewModel.ViewReturnUrl = "Index";
 
             return View(viewModel);
         }
 
         /// <summary>
         /// POST: /Products/Delete/5
         /// </summary>
         [HttpPost]
         public ActionResult Delete(int id, ProductsViewModel viewModel, string returnUrl)
         {
             Products.Delete(id);
             return Json(true);
         }
 
         /// <summary>
         /// GET: /Products/Details/5
         /// </summary>
         public ActionResult Details(int id)
         {
             // select a record by primary key(s)
             Products objProducts = Products.SelectByPrimaryKey(id);
 
             // assign values to the model
             Models.ProductsModel model = new Models.ProductsModel();
             model.ProductID = objProducts.ProductID;
             model.ProductName = objProducts.ProductName;
             model.SupplierID = objProducts.SupplierID;
             model.CategoryID = objProducts.CategoryID;
             model.QuantityPerUnit = objProducts.QuantityPerUnit;
             model.UnitPrice = objProducts.UnitPrice;
             model.UnitsInStock = objProducts.UnitsInStock;
             model.UnitsOnOrder = objProducts.UnitsOnOrder;
             model.ReorderLevel = objProducts.ReorderLevel;
             model.Discontinued = objProducts.Discontinued;
 
             // assign values to the view model
             ProductsViewModel viewModel = new ProductsViewModel();
             viewModel.ProductsModel = model;
             viewModel.SuppliersDropDownListData = Suppliers.SelectSuppliersDropDownListData();
             viewModel.CategoriesDropDownListData = Categories.SelectCategoriesDropDownListData();
 
             if (Request.UrlReferrer != null)
                 viewModel.ViewReturnUrl = Request.UrlReferrer.PathAndQuery;
             else
                 viewModel.ViewReturnUrl = "Index";
 
             return View(viewModel);
         }
 
         /// <summary>
         /// GET: /Products/ListCrudRedirect
         /// </summary>
         public ActionResult ListCrudRedirect()
         {
             return View();
         }
 
         /// <summary>
         /// GET: /Products/ListReadOnly
         /// </summary>
         public ActionResult ListReadOnly()
         {
             return View();
         }
 
         /// <summary>
         /// GET: /Products/ListCrud
         /// </summary>
         public ActionResult ListCrud()
         {
             return View(GetViewModel());
         }
 
         /// <summary>
         /// POST: /Products/ListCrud
         /// </summary>
         [HttpPost]
         [ValidateAntiForgeryToken]
         public ActionResult ListCrud(string inputSubmit, ProductsViewModel viewModel)
         {
             if (ModelState.IsValid)
             {
                 CrudOperation operation = CrudOperation.Add;
 
                 if (inputSubmit == "Update")
                     operation = CrudOperation.Update;
 
                 try
                 {
                     AddEditProducts(viewModel, operation);
                 }
                 catch(Exception ex)
                 {
                     ModelState.AddModelError("", ex.Message);
                 }
             }
 
             return View(GetViewModel());
         }
 
         /// <summary>
         /// GET: /Products/ListTotals
         /// </summary>
         public ActionResult ListTotals()
         {
             return View();
         }
 
         /// <summary>
         /// GET: /Products/ListSearch
         /// </summary>
         public ActionResult ListSearch()
         {
             return View(GetViewModel());
         }
 
         /// <summary>
         /// GET: /Products/ListScrollLoad
         /// </summary>
         public ActionResult ListScrollLoad()
         {
             return View();
         }
 
         /// <summary>
         /// GET: /Products/ListInline
         /// </summary>
         public ActionResult ListInline()
         {
             return View(GetViewModel());
         }
 
         /// <summary>
         /// POST: /Products/ListInlineAdd
         /// </summary>
         [HttpPost]
         public ActionResult ListInlineAdd(Models.ProductsModel model)
         {
             ProductsViewModel viewModel = new ProductsViewModel();
             viewModel.ProductsModel = model;
 
             AddEditProducts(viewModel, CrudOperation.Add);
             return Json(""JsonRequestBehavior.AllowGet);
         }
 
         /// <summary>
         /// POST: /Products/ListInlineUpdate
         /// </summary>
         [HttpPost]
         public ActionResult ListInlineUpdate(Models.ProductsModel model)
         {
             ProductsViewModel viewModel = new ProductsViewModel();
             viewModel.ProductsModel = model;
 
             AddEditProducts(viewModel, CrudOperation.Update);
             return Json(""JsonRequestBehavior.AllowGet);
         }
 
         /// <summary>
         /// GET: /Products/ListForeach
         /// </summary>
         public ActionResult ListForeach(string sidx, string sord, int? page)
         {
             int rows = Convert.ToInt32(ConfigurationManager.AppSettings["GridNumberOfRows"]);
             int numberOfPagesToShow = Convert.ToInt32(ConfigurationManager.AppSettings["GridNumberOfPagesToShow"]);
             int currentPage = page == null ? 1 : Convert.ToInt32(page);
             int startRowIndex = (currentPage * rows) - rows;
             int totalRecords = Products.GetRecordCount();
             int totalPages = (int)Math.Ceiling((float)totalRecords / (float)rows);
             ProductsCollection objProductsCol = Products.SelectSkipAndTake(rows, startRowIndex, sidx + " " + sord);
 
             // fields and titles
             string[,] fieldNames = new string[,] {
                 {"ProductID""Product ID"},
                 {"ProductName""Product Name"},
                 {"SupplierID""Supplier ID"},
                 {"CategoryID""Category ID"},
                 {"QuantityPerUnit""Quantity Per Unit"},
                 {"UnitPrice""Unit Price"},
                 {"UnitsInStock""Units In Stock"},
                 {"UnitsOnOrder""Units On Order"},
                 {"ReorderLevel""Reorder Level"},
                 {"Discontinued""Discontinued"}
             };
 
             // view model
             ProductsForeachViewModel viewModel = new ProductsForeachViewModel();
             viewModel.ProductsData = objProductsCol;
             viewModel.ProductsFieldNames = fieldNames;
             viewModel.TotalPages = totalPages;
             viewModel.CurrentPage = currentPage;
             viewModel.FieldToSort = String.IsNullOrEmpty(sidx) ? "ProductID" : sidx;
             viewModel.FieldSortOrder = String.IsNullOrEmpty(sord) ? "asc" : sord;
             viewModel.FieldToSortWithOrder = String.IsNullOrEmpty(sidx) ? "ProductID" : (sidx + " " + sord).Trim();
             viewModel.NumberOfPagesToShow = numberOfPagesToShow;
             viewModel.StartPage = Functions.GetPagerStartPage(currentPage, numberOfPagesToShow, totalPages);
             viewModel.EndPage = Functions.GetPagerEndPage(viewModel.StartPage, currentPage, numberOfPagesToShow, totalPages);
 
             return View(viewModel);
         }
 
         /// <summary>
         /// GET: /Products/ListMasterDetailGridBySupplierID
         /// </summary>
         public ActionResult ListMasterDetailGridBySupplierID()
         {
             return View();
         }
 
         /// <summary>
         /// GET: /Products/ListMasterDetailGridByCategoryID
         /// </summary>
         public ActionResult ListMasterDetailGridByCategoryID()
         {
             return View();
         }
 
         /// <summary>
         /// GET: /Products/ListMasterDetailSubGridBySupplierID
         /// </summary>
         public ActionResult ListMasterDetailSubGridBySupplierID()
         {
             return View();
         }
 
         /// <summary>
         /// GET: /Products/ListMasterDetailSubGridByCategoryID
         /// </summary>
         public ActionResult ListMasterDetailSubGridByCategoryID()
         {
             return View();
         }
 
         /// <summary>
         /// GET: /Products/Unbound
         /// </summary>
         public ActionResult Unbound()
         {
             return View(GetUnboundViewModel());
         }
 
         /// <summary>
         /// POST: /Products/Unbound
         /// </summary>
         [HttpPost]
         [ValidateAntiForgeryToken]
         public ActionResult Unbound(ProductsViewModel viewModel, string returnUrl)
         {
             if (ModelState.IsValid)
             {
                 // do something here before redirecting
 
                 if (Url.IsLocalUrl(returnUrl))
                     return Redirect(returnUrl);
                 else
                     return RedirectToAction("/");
             }
 
             // if we got this far, something failed, redisplay form
             return View(GetUnboundViewModel());
         }
 
         private ProductsViewModel GetUnboundViewModel()
         {
             ProductsViewModel viewModel = new ProductsViewModel();
             viewModel.ProductsModel = null;
             viewModel.ViewControllerName = "Products";
 
             if (Request.UrlReferrer != null)
                 viewModel.ViewReturnUrl = Request.UrlReferrer.PathAndQuery;
             else
                 viewModel.ViewReturnUrl = "/";
 
             return viewModel;
         }
 
         /// <summary>
         /// GET: /Products/AddEditProducts
         /// </summary>
         private void AddEditProducts(ProductsViewModel viewModel, CrudOperation operation)
         {
             Models.ProductsModel model = viewModel.ProductsModel;
             Products objProducts;
 
             if (operation == CrudOperation.Add)
                objProducts = new Products();
             else
                objProducts = Products.SelectByPrimaryKey(model.ProductID);
 
             objProducts.ProductID = model.ProductID;
             objProducts.ProductName = model.ProductName;
             objProducts.SupplierID = model.SupplierID;
             objProducts.CategoryID = model.CategoryID;
             objProducts.QuantityPerUnit = model.QuantityPerUnit;
             objProducts.UnitPrice = model.UnitPrice;
             objProducts.UnitsInStock = model.UnitsInStock;
             objProducts.UnitsOnOrder = model.UnitsOnOrder;
             objProducts.ReorderLevel = model.ReorderLevel;
             objProducts.Discontinued = model.Discontinued;
 
             if (operation == CrudOperation.Add)
                objProducts.Insert();
             else
                objProducts.Update();
         }
 
         private ProductsViewModel GetViewModel()
         {
             ProductsViewModel viewModel = new ProductsViewModel();
             viewModel.ProductsModel = null;
             viewModel.SuppliersDropDownListData = Suppliers.SelectSuppliersDropDownListData();
             viewModel.CategoriesDropDownListData = Categories.SelectCategoriesDropDownListData();
 
             return viewModel;
         }
 
         private ProductsCollection GetFilteredData(string sidx, string sord, string filters, out int totalRecords, int rows, int startRowIndex, string sortExpression)
         {
             if (!String.IsNullOrEmpty(filters))
             {
                 if (filters.Contains("field") && filters.Contains("op") && filters.Contains("data"))
                 {
                     filters = filters.Replace("{\"groupOp\":\"AND\",\"rules\":[{""");
                     filters = filters.Replace("}]}""");
 
                     string[] filterArray = Regex.Split(filters, "},{");
                     List<string> fieldName = new List<string>();
                     List<string> data = new List<string>();
                     int ctr = 0;
                     int? productID = null;
                     string productName = String.Empty;
                     int? supplierID = null;
                     int? categoryID = null;
                     string quantityPerUnit = String.Empty;
                     decimal? unitPrice = null;
                     Int16? unitsInStock = null;
                     Int16? unitsOnOrder = null;
                     Int16? reorderLevel = null;
                     bool? discontinued = null;
 
                     foreach (string filter in filterArray)
                     {
                         string[] fieldsArray = Regex.Split(filter, ",");
                         fieldName.Add(fieldsArray[0].Replace("\"field\":""").Replace("\"""").ToLower().Trim());
                         data.Add(fieldsArray[2].Replace("\"data\":""").Replace("\"""").ToLower().Trim());
                     }
 
                     foreach (string item in fieldName)
                     {
                         if (item == "productid")
                             productID = Convert.ToInt32(data[ctr]);
 
                         if (item == "productname")
                             productName = data[ctr];
 
                         if (item == "supplierid")
                             supplierID = Convert.ToInt32(data[ctr]);
 
                         if (item == "categoryid")
                             categoryID = Convert.ToInt32(data[ctr]);
 
                         if (item == "quantityperunit")
                             quantityPerUnit = data[ctr];
 
                         if (item == "unitprice")
                             unitPrice = Convert.ToDecimal(data[ctr]);
 
                         if (item == "unitsinstock")
                             unitsInStock = Convert.ToInt16(data[ctr]);
 
                         if (item == "unitsonorder")
                             unitsOnOrder = Convert.ToInt16(data[ctr]);
 
                         if (item == "reorderlevel")
                             reorderLevel = Convert.ToInt16(data[ctr]);
 
                         if (item == "discontinued")
                             discontinued = Convert.ToBoolean(data[ctr]);
 
                         ctr++;
                     }
 
                     totalRecords = Products.GetRecordCountDynamicWhere(productID, productName, supplierID, categoryID, quantityPerUnit, unitPrice, unitsInStock, unitsOnOrder, reorderLevel, discontinued);
                     return Products.SelectSkipAndTakeDynamicWhere(productID, productName, supplierID, categoryID, quantityPerUnit, unitPrice, unitsInStock, unitsOnOrder, reorderLevel, discontinued, rows, startRowIndex, sortExpression);
                 }
             }
 
             totalRecords = Products.GetRecordCount();
             return Products.SelectSkipAndTake(rows, startRowIndex, sortExpression);
         }
 
         /// <summary>
         /// GET: /Products/GridData
         /// </summary>
         public ActionResult GridData(string sidx, string sord, int page, int rows)
         {
             int totalRecords = 0;
             int startRowIndex = (page * rows) - rows;
             ProductsCollection objProductsCol = Products.SelectSkipAndTake(rows, startRowIndex, out totalRecords, sidx + " " + sord);
             int totalPages = (int)Math.Ceiling((float)totalRecords / (float)rows);
 
             var jsonData = new
             {
                 total = totalPages,
                 page,
                 records = totalRecords,
                 rows = (
                     from objProducts in objProductsCol
                     select new
                     {
                         id = objProducts.ProductID,
                         cell = new string[] { 
                             objProducts.ProductID.ToString(),
                             objProducts.ProductName,
                             objProducts.SupplierID.HasValue ? objProducts.SupplierID.Value.ToString() : "",
                             objProducts.CategoryID.HasValue ? objProducts.CategoryID.Value.ToString() : "",
                             objProducts.QuantityPerUnit,
                             objProducts.UnitPrice.HasValue ? objProducts.UnitPrice.Value.ToString() : "",
                             objProducts.UnitsInStock.HasValue ? objProducts.UnitsInStock.Value.ToString() : "",
                             objProducts.UnitsOnOrder.HasValue ? objProducts.UnitsOnOrder.Value.ToString() : "",
                             objProducts.ReorderLevel.HasValue ? objProducts.ReorderLevel.Value.ToString() : "",
                             objProducts.Discontinued.ToString()
                         }
                     }).ToArray()
             };
 
             return Json(jsonData, JsonRequestBehavior.AllowGet);
         }
 
         /// <summary>
         /// GET: /Products/GridDataWithFilters
         /// </summary>
         public ActionResult GridDataWithFilters(string sidx, string sord, int page, int rows, string filters)
         {
             int totalRecords = 0;
             int startRowIndex = (page * rows) - rows;
             ProductsCollection objProductsCol = this.GetFilteredData(sidx, sord, filters, out totalRecords, rows, startRowIndex, sidx + " " + sord);
             int totalPages = (int)Math.Ceiling((float)totalRecords / (float)rows);
 
             if (objProductsCol == null)
                 return Json("{ total = 0, page = 0, records = 0, rows = null }"JsonRequestBehavior.AllowGet);
 
             var jsonData = new
             {
                 total = totalPages,
                 page,
                 records = totalRecords,
                 rows = (
                     from objProducts in objProductsCol
                     select new
                     {
                         id = objProducts.ProductID,
                         cell = new string[] { 
                             objProducts.ProductID.ToString(),
                             objProducts.ProductName,
                             objProducts.SupplierID.HasValue ? objProducts.SupplierID.Value.ToString() : "",
                             objProducts.CategoryID.HasValue ? objProducts.CategoryID.Value.ToString() : "",
                             objProducts.QuantityPerUnit,
                             objProducts.UnitPrice.HasValue ? objProducts.UnitPrice.Value.ToString() : "",
                             objProducts.UnitsInStock.HasValue ? objProducts.UnitsInStock.Value.ToString() : "",
                             objProducts.UnitsOnOrder.HasValue ? objProducts.UnitsOnOrder.Value.ToString() : "",
                             objProducts.ReorderLevel.HasValue ? objProducts.ReorderLevel.Value.ToString() : "",
                             objProducts.Discontinued.ToString()
                         }
                     }).ToArray()
             };
 
             return Json(jsonData, JsonRequestBehavior.AllowGet);
         }
 
         /// <summary>
         /// GET: /Products/GridDataWithTotals
         /// </summary>
         public ActionResult GridDataWithTotals(string sidx, string sord, int page, int rows)
         {
             int totalRecords = 0;
             int startRowIndex = (page * rows) - rows;
             ProductsCollection objProductsCol = Products.SelectSkipAndTake(rows, startRowIndex, out totalRecords, sidx + " " + sord);
             int totalPages = (int)Math.Ceiling((float)totalRecords / (float)rows);
 
             var jsonData = new
             {
                 total = totalPages,
                 page,
                 records = totalRecords,
                 userdata = new
                 {
                     UnitPrice = objProductsCol.Select(p => p.UnitPrice).Sum().ToString()
                 },
                 rows = (
                     from objProducts in objProductsCol
                     select new
                     {
                         id = objProducts.ProductID,
                         cell = new string[] { 
                             objProducts.ProductID.ToString(),
                             objProducts.ProductName,
                             objProducts.SupplierID.HasValue ? objProducts.SupplierID.Value.ToString() : "",
                             objProducts.CategoryID.HasValue ? objProducts.CategoryID.Value.ToString() : "",
                             objProducts.QuantityPerUnit,
                             objProducts.UnitPrice.HasValue ? objProducts.UnitPrice.Value.ToString() : "",
                             objProducts.UnitsInStock.HasValue ? objProducts.UnitsInStock.Value.ToString() : "",
                             objProducts.UnitsOnOrder.HasValue ? objProducts.UnitsOnOrder.Value.ToString() : "",
                             objProducts.ReorderLevel.HasValue ? objProducts.ReorderLevel.Value.ToString() : "",
                             objProducts.Discontinued.ToString()
                         }
                     }).ToArray()
             };
 
             return Json(jsonData, JsonRequestBehavior.AllowGet);
         }
 
         /// <summary>
         /// GET: /Products/ListGroupedBySupplierID
         /// </summary>
         public ActionResult ListGroupedBySupplierID()
         {
             return View();
         }
 
         /// <summary>
         /// GET: /Products/GridDataGroupedBySupplierID
         /// </summary>
         public ActionResult GridDataGroupedBySupplierID(string sidx, string sord, int page, int rows)
         {
             // using a groupField in the jqgrid passes that field
             // along with the field to sort, remove the groupField
             string groupBy = "CompanyName asc, ";
             sidx = sidx.Replace(groupBy, "");
 
             int totalRecords = 0;
             int startRowIndex = (page * rows) - rows;
             ProductsCollection objProductsCol = Products.SelectSkipAndTake(rows, startRowIndex, out totalRecords, sidx + " " + sord);
             int totalPages = (int)Math.Ceiling((float)totalRecords / (float)rows);
 
             var jsonData = new
             {
                 total = totalPages,
                 page,
                 records = totalRecords,
                 rows = (
                     from objProducts in objProductsCol
                     select new
                     {
                         id = objProducts.ProductID,
                         cell = new string[] { 
                             objProducts.ProductID.ToString(),
                             objProducts.ProductName,
                             objProducts.SupplierID.HasValue ? objProducts.SupplierID.Value.ToString() : "",
                             objProducts.CategoryID.HasValue ? objProducts.CategoryID.Value.ToString() : "",
                             objProducts.QuantityPerUnit,
                             objProducts.UnitPrice.HasValue ? objProducts.UnitPrice.Value.ToString() : "",
                             objProducts.UnitsInStock.HasValue ? objProducts.UnitsInStock.Value.ToString() : "",
                             objProducts.UnitsOnOrder.HasValue ? objProducts.UnitsOnOrder.Value.ToString() : "",
                             objProducts.ReorderLevel.HasValue ? objProducts.ReorderLevel.Value.ToString() : "",
                             objProducts.Discontinued.ToString(),
                             objProducts.SupplierID == null ? "" : objProducts.Suppliers.Value.CompanyName
 
                         }
                     }).ToArray()
             };
 
             return Json(jsonData, JsonRequestBehavior.AllowGet);
         }
 
         /// <summary>
         /// GET: /Products/ListGroupedByCategoryID
         /// </summary>
         public ActionResult ListGroupedByCategoryID()
         {
             return View();
         }
 
         /// <summary>
         /// GET: /Products/GridDataGroupedByCategoryID
         /// </summary>
         public ActionResult GridDataGroupedByCategoryID(string sidx, string sord, int page, int rows)
         {
             // using a groupField in the jqgrid passes that field
             // along with the field to sort, remove the groupField
             string groupBy = "CategoryName asc, ";
             sidx = sidx.Replace(groupBy, "");
 
             int totalRecords = 0;
             int startRowIndex = (page * rows) - rows;
             ProductsCollection objProductsCol = Products.SelectSkipAndTake(rows, startRowIndex, out totalRecords, sidx + " " + sord);
             int totalPages = (int)Math.Ceiling((float)totalRecords / (float)rows);
 
             var jsonData = new
             {
                 total = totalPages,
                 page,
                 records = totalRecords,
                 rows = (
                     from objProducts in objProductsCol
                     select new
                     {
                         id = objProducts.ProductID,
                         cell = new string[] { 
                             objProducts.ProductID.ToString(),
                             objProducts.ProductName,
                             objProducts.SupplierID.HasValue ? objProducts.SupplierID.Value.ToString() : "",
                             objProducts.CategoryID.HasValue ? objProducts.CategoryID.Value.ToString() : "",
                             objProducts.QuantityPerUnit,
                             objProducts.UnitPrice.HasValue ? objProducts.UnitPrice.Value.ToString() : "",
                             objProducts.UnitsInStock.HasValue ? objProducts.UnitsInStock.Value.ToString() : "",
                             objProducts.UnitsOnOrder.HasValue ? objProducts.UnitsOnOrder.Value.ToString() : "",
                             objProducts.ReorderLevel.HasValue ? objProducts.ReorderLevel.Value.ToString() : "",
                             objProducts.Discontinued.ToString(),
                             objProducts.CategoryID == null ? "" : objProducts.Categories.Value.CategoryName
 
                         }
                     }).ToArray()
             };
 
             return Json(jsonData, JsonRequestBehavior.AllowGet);
         }
 
         /// <summary>
         /// GET: /Products/ListTotalsGroupedBySupplierID
         /// </summary>
         public ActionResult ListTotalsGroupedBySupplierID()
         {
             return View();
         }
 
         /// <summary>
         /// GET: /Products/GridDataTotalsGroupedBySupplierID
         /// </summary>
         public ActionResult GridDataTotalsGroupedBySupplierID(string sidx, string sord, int page, int rows)
         {
             // using a groupField in the jqgrid passes that field
             // along with the field to sort, remove the groupField
             string groupBy = "CompanyName asc, ";
             sidx = sidx.Replace(groupBy, "");
 
             int totalRecords = 0;
             int startRowIndex = (page * rows) - rows;
             ProductsCollection objProductsCol = Products.SelectSkipAndTake(rows, startRowIndex, out totalRecords, sidx + " " + sord);
             int totalPages = (int)Math.Ceiling((float)totalRecords / (float)rows);
 
             var jsonData = new
             {
                 total = totalPages,
                 page,
                 records = totalRecords,
                 rows = (
                     from objProducts in objProductsCol
                     select new
                     {
                         id = objProducts.ProductID,
                         cell = new string[] { 
                             objProducts.ProductID.ToString(),
                             objProducts.ProductName,
                             objProducts.SupplierID.HasValue ? objProducts.SupplierID.Value.ToString() : "",
                             objProducts.CategoryID.HasValue ? objProducts.CategoryID.Value.ToString() : "",
                             objProducts.QuantityPerUnit,
                             objProducts.UnitPrice.HasValue ? objProducts.UnitPrice.Value.ToString() : "",
                             objProducts.UnitsInStock.HasValue ? objProducts.UnitsInStock.Value.ToString() : "",
                             objProducts.UnitsOnOrder.HasValue ? objProducts.UnitsOnOrder.Value.ToString() : "",
                             objProducts.ReorderLevel.HasValue ? objProducts.ReorderLevel.Value.ToString() : "",
                             objProducts.Discontinued.ToString(),
                             objProducts.SupplierID == null ? "" : objProducts.Suppliers.Value.CompanyName
 
                         }
                     }).ToArray()
             };
 
             return Json(jsonData, JsonRequestBehavior.AllowGet);
         }
 
         /// <summary>
         /// GET: /Products/ListTotalsGroupedByCategoryID
         /// </summary>
         public ActionResult ListTotalsGroupedByCategoryID()
         {
             return View();
         }
 
         /// <summary>
         /// GET: /Products/GridDataTotalsGroupedByCategoryID
         /// </summary>
         public ActionResult GridDataTotalsGroupedByCategoryID(string sidx, string sord, int page, int rows)
         {
             // using a groupField in the jqgrid passes that field
             // along with the field to sort, remove the groupField
             string groupBy = "CategoryName asc, ";
             sidx = sidx.Replace(groupBy, "");
 
             int totalRecords = 0;
             int startRowIndex = (page * rows) - rows;
             ProductsCollection objProductsCol = Products.SelectSkipAndTake(rows, startRowIndex, out totalRecords, sidx + " " + sord);
             int totalPages = (int)Math.Ceiling((float)totalRecords / (float)rows);
 
             var jsonData = new
             {
                 total = totalPages,
                 page,
                 records = totalRecords,
                 rows = (
                     from objProducts in objProductsCol
                     select new
                     {
                         id = objProducts.ProductID,
                         cell = new string[] { 
                             objProducts.ProductID.ToString(),
                             objProducts.ProductName,
                             objProducts.SupplierID.HasValue ? objProducts.SupplierID.Value.ToString() : "",
                             objProducts.CategoryID.HasValue ? objProducts.CategoryID.Value.ToString() : "",
                             objProducts.QuantityPerUnit,
                             objProducts.UnitPrice.HasValue ? objProducts.UnitPrice.Value.ToString() : "",
                             objProducts.UnitsInStock.HasValue ? objProducts.UnitsInStock.Value.ToString() : "",
                             objProducts.UnitsOnOrder.HasValue ? objProducts.UnitsOnOrder.Value.ToString() : "",
                             objProducts.ReorderLevel.HasValue ? objProducts.ReorderLevel.Value.ToString() : "",
                             objProducts.Discontinued.ToString(),
                             objProducts.CategoryID == null ? "" : objProducts.Categories.Value.CategoryName
 
                         }
                     }).ToArray()
             };
 
             return Json(jsonData, JsonRequestBehavior.AllowGet);
         }
     } 
}