using Newtonsoft.Json; using Microsoft.AspNetCore.Mvc; using System; using System.Linq; using MyAppApi; using MyAppApi.BusinessLayer; using MyAppApi.Models; using MyAppApi.ViewModels; using MyAppApi.Domain; using System.Net.Http; using System.Collections.Generic; using System.Threading.Tasks; namespace MyApp.Controllers { /// <summary> /// Works like the Base class for ProductController class. /// ************************************* Do not make changes to this class ************************************* /// ** Put your additional code in the ProductController class under the Controller folder. ** /// ************************************************************************************************************* /// </summary> public partial class ProductController : Controller { private Product _product; private ProductViewModel _productViewModel; private ProductForeachViewModel _productForEachViewModel; // constructor public ProductController(Product product, ProductViewModel productViewModel, ProductForeachViewModel productForeachViewModel) { _product = product; _productViewModel = productViewModel; _productForEachViewModel = productForeachViewModel; } #region actions used by their respective views /// <summary> /// GET: /Product/ /// Gets the view used by the Index razor view /// </summary> public IActionResult Index() { // return view return View(); } /// <summary> /// GET: /Product/Add /// Gets the view model used by the Add razor view /// </summary> public async Task<IActionResult> Add(string urlReferrer = null) { // return the view model return await this.GetAddViewModelAsync(urlReferrer); } /// <summary> /// POST: /Product/Add /// Posts values from the Add razor view /// </summary> [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Add(ProductViewModel viewModel, string returnUrl) { return await this.ValidateAndSave(CrudOperation.Add, viewModel, returnUrl); } /// <summary> /// GET: /Product/Update/* /// Gets the view model used by the Update razor view /// </summary> public async Task<IActionResult> Update(int id, string urlReferrer = null) { // return view model return await this.GetUpdateViewModelAsync(id, urlReferrer); } /// <summary> /// POST: /Product/Update/# /// Posts values from the Update razor view /// </summary> [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Update(int id, ProductViewModel viewModel, string returnUrl) { if (ModelState.IsValid) return await this.ValidateAndSave(CrudOperation.Update, viewModel, returnUrl, id); // if we got this far, something failed, redisplay form return await this.GetUpdateViewModelAsync(id, returnUrl); } /// <summary> /// GET: /Details/Details/# /// Gets the view model used by the Details razor view /// </summary> public async Task<IActionResult> Details(int id, string urlReferrer) { // fill the model by primary key await this.FillModelByPrimaryKeyAsync(id); // set and return the view model _productViewModel = await this.GetViewModelAsync("Details", "Product", urlReferrer, _product, CrudOperation.None); return View(_productViewModel); } /// <summary> /// GET: /Product/ListCrudRedirect/ /// Gets the view used by the ListCrudRedirect razor view /// </summary> public IActionResult ListCrudRedirect() { // return view return View(); } /// <summary> /// GET: /Product/ListReadOnly/ /// Gets the view used by the ListReadOnly razor view /// </summary> public IActionResult ListReadOnly() { // return view return View(); } /// <summary> /// GET: /Product/ListCrud/ /// Gets the view model used by the ListCrud razor view /// </summary> public async Task<IActionResult> ListCrud() { // return view model _productViewModel = await this.GetViewModelAsync("ListCrud"); return View(_productViewModel); } /// <summary> /// POST: /Product/ListCrud /// Posts values from the ListCrud /// </summary> [HttpPost] public async Task<IActionResult> ListCrud(string inputSubmit, string serializedData) { // deserialize serializedData _product = JsonConvert.DeserializeObject<Product>(serializedData); // assign a value to the view model's Product (Model) property _productViewModel.Product = _product; if (ModelState.IsValid) { CrudOperation operation = CrudOperation.Add; if (inputSubmit == "Update") operation = CrudOperation.Update; try { // add a new record or update an existing record await AddEditProductAsync(_productViewModel, operation, true); } catch(Exception ex) { ModelState.AddModelError("", ex.Message); } } return Json(true); } /// <summary> /// GET: /Product/ListTotals/ /// Gets the view used by the ListTotals razor view /// </summary> public IActionResult ListTotals() { // return view return View(); } /// <summary> /// GET: /Product/ListSearch/ /// Gets the view model used by the ListSearch razor view /// </summary> public async Task<IActionResult> ListSearch() { // return view model _productViewModel = await this.GetViewModelAsync("ListSearch"); return View(_productViewModel); } /// <summary> /// GET: /Product/ListScrollLoad/ /// Gets the view used by the ListScrollLoad razor view /// </summary> public IActionResult ListScrollLoad() { // return view return View(); } /// <summary> /// GET: /Product/ListInline/ /// Gets the view model used by the ListInline razor view /// </summary> public async Task<IActionResult> ListInline() { // return view model _productViewModel = await this.GetViewModelAsync("ListInline"); return View(_productViewModel); } /// <summary> /// POST: /Product/ListInlineAdd /// Posts the values from the ListInlineAdd /// </summary> [HttpPost] public async Task<IActionResult> ListInlineAdd([FromBody]string modelString) { return await this.ListInlineAddOrUpdate(modelString, CrudOperation.Add); } /// <summary> /// POST: /Product/ListInlineUpdate /// Posts the values from the ListInlineUpdate /// </summary> [HttpPost] public async Task<IActionResult> ListInlineUpdate([FromBody]string modelString) { return await this.ListInlineAddOrUpdate(modelString, CrudOperation.Update); } /// <summary> /// GET: /Product/ListForeach /// Gets the view model used by the ListForeach razor view /// </summary> public async Task<IActionResult> ListForeach(string sidx, string sord, int? page) { // get the default number of rows to show int rows = Functions.GetGridNumberOfRows(); // the numberOfPagesToShow is used to show the "< First..." link in the razor view int numberOfPagesToShow = Functions.GetGridNumberOfPagesToShow(); // when page is null, set it to 1 int currentPage = page is null ? 1 : Convert.ToInt32(page); // get the total number of records string responseBody1 = await Functions.HttpClientGetAsync("ProductApi/GetRecordCount/"); int totalRecords = JsonConvert.DeserializeObject<int>(responseBody1); // get the index where to start retrieving records from and the total pages (int startRowIndex, int totalPages) = Functions.GetStartRowIndexAndTotalPages(currentPage, rows, totalRecords); // get records based on filters List<Product> objProductsList = null; string responseBody2 = await Functions.HttpClientGetAsync("ProductApi/SelectSkipAndTake/?rows=" + rows + "&page=" + currentPage + "&sidx=" + sidx + "&sord=" + sord); // make sure responseBody2 is not empty before deserialization if(!String.IsNullOrEmpty(responseBody2)) objProductsList = JsonConvert.DeserializeObject<List<Product>>(responseBody2); // 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"} }; // assign values to the view model _productForEachViewModel.ProductData = objProductsList; _productForEachViewModel.ProductFieldNames = fieldNames; _productForEachViewModel.TotalPages = totalPages; _productForEachViewModel.CurrentPage = currentPage; _productForEachViewModel.FieldToSort = String.IsNullOrEmpty(sidx) ? "ProductID" : sidx; _productForEachViewModel.FieldSortOrder = String.IsNullOrEmpty(sord) ? "asc" : sord; _productForEachViewModel.FieldToSortWithOrder = String.IsNullOrEmpty(sidx) ? "ProductID" : (sidx + " " + sord).Trim(); _productForEachViewModel.NumberOfPagesToShow = numberOfPagesToShow; _productForEachViewModel.StartPage = Functions.GetPagerStartPage(currentPage, numberOfPagesToShow); _productForEachViewModel.EndPage = Functions.GetPagerEndPage(_productForEachViewModel.StartPage, numberOfPagesToShow, totalPages); // return the view model return View(_productForEachViewModel); } /// <summary> /// GET: /Product/ListMasterDetailGridBySupplierID/ /// Gets the view used by the ListMasterDetailGridBySupplierID razor view /// </summary> public IActionResult ListMasterDetailGridBySupplierID() { // return view return View(); } /// <summary> /// GET: /Product/ListMasterDetailGridByCategoryID/ /// Gets the view used by the ListMasterDetailGridByCategoryID razor view /// </summary> public IActionResult ListMasterDetailGridByCategoryID() { // return view return View(); } /// <summary> /// GET: /Product/ListMasterDetailSubGridBySupplierID/ /// Gets the view used by the ListMasterDetailSubGridBySupplierID razor view /// </summary> public IActionResult ListMasterDetailSubGridBySupplierID() { // return view return View(); } /// <summary> /// GET: /Product/ListMasterDetailSubGridByCategoryID/ /// Gets the view used by the ListMasterDetailSubGridByCategoryID razor view /// </summary> public IActionResult ListMasterDetailSubGridByCategoryID() { // return view return View(); } /// <summary> /// GET: /Product/ListMultipleDelete/ /// Gets the view used by the ListMultipleDelete razor view /// </summary> public IActionResult ListMultipleDelete() { // return view return View(); } /// <summary> /// GET: /Product/ListGroupedBySupplierID/ /// Gets the view used by the ListGroupedBySupplierID razor view /// </summary> public IActionResult ListGroupedBySupplierID() { // return view return View(); } /// <summary> /// GET: /Product/ListGroupedByCategoryID/ /// Gets the view used by the ListGroupedByCategoryID razor view /// </summary> public IActionResult ListGroupedByCategoryID() { // return view return View(); } /// <summary> /// GET: /Product/ListTotalsGroupedBySupplierID/ /// Gets the view used by the ListTotalsGroupedBySupplierID razor view /// </summary> public IActionResult ListTotalsGroupedBySupplierID() { // return view return View(); } /// <summary> /// GET: /Product/ListTotalsGroupedByCategoryID/ /// Gets the view used by the ListTotalsGroupedByCategoryID razor view /// </summary> public IActionResult ListTotalsGroupedByCategoryID() { // return view return View(); } /// <summary> /// Gets the view used by the ListBySupplierID razor view /// </summary> public async Task<IActionResult> ListBySupplierID() { // get records List<Supplier> objSuppliersList = null; string responseBody = await Functions.HttpClientGetAsync("SupplierApi/SelectSupplierDropDownListData/"); // make sure responseBody is not empty before deserialization if(!String.IsNullOrEmpty(responseBody)) objSuppliersList = JsonConvert.DeserializeObject<List<Supplier>>(responseBody); // assign values to the view model _productViewModel.SupplierDropDownListData = objSuppliersList; // return the view model return View(_productViewModel); } /// <summary> /// Gets the view used by the ListByCategoryID razor view /// </summary> public async Task<IActionResult> ListByCategoryID() { // get records List<Category> objCategoriesList = null; string responseBody = await Functions.HttpClientGetAsync("CategoryApi/SelectCategoryDropDownListData/"); // make sure responseBody is not empty before deserialization if(!String.IsNullOrEmpty(responseBody)) objCategoriesList = JsonConvert.DeserializeObject<List<Category>>(responseBody); // assign values to the view model _productViewModel.CategoryDropDownListData = objCategoriesList; // return the view model return View(_productViewModel); } /// <summary> /// GET: /Product/Unbound /// Gets the view model used by the Unbound razor view /// </summary> public async Task<IActionResult> Unbound() { // set and return the view model _productViewModel = await this.GetViewModelAsync("Unbound", "Product", "/Home", null, CrudOperation.None, false, false); return View(_productViewModel); } /// <summary> /// POST: /Product/Unbound /// Post values fromy the Unbound razor view /// </summary> [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Unbound(ProductViewModel viewModel, string returnUrl) { if (ModelState.IsValid) { // do something here before redirecting if (Url.IsLocalUrl(returnUrl)) return Redirect(returnUrl); else return RedirectToAction("Index", "Home"); } // if we got this far, something failed, redisplay form _productViewModel = await this.GetViewModelAsync("Unbound", "Product", "/Home", null, CrudOperation.None, false, false); return View(_productViewModel); } #endregion #region public methods /// <summary> /// POST: /Product/Delete/# /// Deletes a record based on the id(s) /// </summary> [HttpPost] public async Task<IActionResult> Delete(int id) { // delete data via web api HttpResponseMessage response = await Functions.HttpClientDeleteAsync("ProductApi/Delete/?id=" + id); // check the status of the httpclient delete operation if (response != null) { if (response.IsSuccessStatusCode) return Json(true); else return BadRequest(response.ReasonPhrase); } return BadRequest(); } /// <summary> /// POST: /Product/DeleteMultiple/ids /// Deletes multiple records based on the comma-delimited ids /// </summary> [HttpPost] public async Task<IActionResult> DeleteMultiple(string ids) { // delete multiple items via web api HttpResponseMessage response = await Functions.HttpClientDeleteAsync("ProductApi/DeleteMultiple?ids=" + ids); // check the status of the httpclient delete multiple operation if (response != null) { if (response.IsSuccessStatusCode) return Json(true); else return BadRequest(response.ReasonPhrase); } return BadRequest(); } #endregion #region private methods /// <summary> /// Gets the view model used by the Add razor view /// </summary> private async Task<IActionResult> GetAddViewModelAsync(string returnUrl = null) { // set the return url to /ListCrudRedirect when the returnUrl paramater is empty string url = String.IsNullOrEmpty(returnUrl) ? "/Product/ListCrudRedirect" : returnUrl; // set and return the view model _productViewModel = await this.GetViewModelAsync("Add", "Product", url, null, CrudOperation.Add); return View(_productViewModel); } /// <summary> /// Gets the view model used by the Update razor view /// </summary> private async Task<IActionResult> GetUpdateViewModelAsync(int id, string urlReferrer) { // fill the model by primary key await this.FillModelByPrimaryKeyAsync(id); // set and return the view model _productViewModel = await this.GetViewModelAsync("Update", "Product", urlReferrer, _product, CrudOperation.Update); return View(_productViewModel); } /// <summary> /// Used when adding a new record or updating an existing record /// </summary> /// <param name="viewModel">ProductViewModel</param> /// <param name="operation">Operation to Add a new record or Update an existing record</param> /// <param name="isForListInlineOrListCrud">Used by the razor Views with ListInline or ListCrud when true</param> /// <returns>Task of IActionResult</returns> private async Task<IActionResult> AddEditProductAsync(ProductViewModel viewModel, CrudOperation operation, bool isForListInlineOrListCrud = false) { Product model = viewModel.Product; // serialize the model to json string serializedModel = JsonConvert.SerializeObject(model); // web api url for Add string webApiUrl = "ProductApi/Insert?isForListInlineOrListCrud=" + isForListInlineOrListCrud; // web api url for Update if (operation == CrudOperation.Update) webApiUrl = "ProductApi/Update?isForListInlineOrListCrud=" + isForListInlineOrListCrud; // post data via web api HttpResponseMessage response = await Functions.HttpClientPostAsync(webApiUrl, serializedModel); // check the status of the httpclient post operation if (response != null) { if (response.IsSuccessStatusCode) return Ok(); else return BadRequest(response.ReasonPhrase); } return BadRequest(); } /// <summary> /// Gets the view model based on the actionName /// </summary> private async Task<ProductViewModel> GetViewModelAsync(string actionName, string controllerName = "Product", string returnUrl = null, Product objProduct = null, CrudOperation operation = CrudOperation.None, bool isFillSupplierDdl = true, bool isFillCategoryDdl = true) { // assign values to the view model _productViewModel.Product = objProduct; _productViewModel.Operation = operation; _productViewModel.ViewControllerName = controllerName; _productViewModel.ViewActionName = actionName; _productViewModel.ViewReturnUrl = returnUrl; if(isFillSupplierDdl) _productViewModel.SupplierDropDownListData = await this.GetSupplierDropDownListDataAsync(); else _productViewModel.SupplierDropDownListData = null; if(isFillCategoryDdl) _productViewModel.CategoryDropDownListData = await this.GetCategoryDropDownListDataAsync(); else _productViewModel.CategoryDropDownListData = null; // return the view model return _productViewModel; } /// <summary> /// Validates the Add or Update operation and Saves the data when valid and no errors. /// </summary> /// <param name="operation">Add or Update only. CrudOperation.None is not permitted</param> /// <param name="productViewModel">The View Model</param> /// <param name="returnUrl">Url to return to after the operation</param> /// <param name="id">Optional. But required when operation = CrudOperation.Update</param> /// <returns>View Model as IActionResult</returns> private async Task<IActionResult> ValidateAndSave(CrudOperation operation, ProductViewModel productViewModel, string returnUrl, int? id = null) { if (operation == CrudOperation.None) throw new ArgumentException("operation = CrudOperation.None is not valid for the ValidateAndSave method."); if (ModelState.IsValid) { try { // add or update record await this.AddEditProductAsync(productViewModel, operation); if (Url.IsLocalUrl(returnUrl)) return Redirect(returnUrl); else return RedirectToAction("ListCrudRedirect", "Product"); } catch (Exception ex) { if (ex.InnerException != null) ModelState.AddModelError("", ex.InnerException.Message); else ModelState.AddModelError("", ex.Message); } } // if we got this far, something failed, redisplay form if (operation == CrudOperation.Add) return await GetAddViewModelAsync(returnUrl); else return await this.GetUpdateViewModelAsync(id.Value, returnUrl); } /// <summary> /// Fills the Product model information by primary key /// </summary> private async Task FillModelByPrimaryKeyAsync(int productID) { // select a record by primary key(s) string responseBody = await Functions.HttpClientGetAsync("ProductApi/SelectByPrimaryKey/?id=" + productID); Product objProduct = JsonConvert.DeserializeObject<Product>(responseBody); // assign values to the model _product.ProductID = objProduct.ProductID; _product.ProductName = objProduct.ProductName; _product.SupplierID = objProduct.SupplierID; _product.CategoryID = objProduct.CategoryID; _product.QuantityPerUnit = objProduct.QuantityPerUnit; _product.UnitPrice = objProduct.UnitPrice; if(objProduct.UnitsInStock.HasValue) _product.UnitsInStockHidden = objProduct.UnitsInStock.ToString(); if(objProduct.UnitsOnOrder.HasValue) _product.UnitsOnOrderHidden = objProduct.UnitsOnOrder.ToString(); if(objProduct.ReorderLevel.HasValue) _product.ReorderLevelHidden = objProduct.ReorderLevel.ToString(); _product.Discontinued = objProduct.Discontinued; } /// <summary> /// Selects records as a collection (List) of MyAppApi.Models.Supplier /// Retrieves a collection (List) of two colums per row, normally the Primary Key column and another column for use in a drop down list /// </summary> private async Task<List<MyAppApi.Models.Supplier>> GetSupplierDropDownListDataAsync() { // get records string responseBody = await Functions.HttpClientGetAsync("SupplierApi/SelectSupplierDropDownListData/"); List<MyAppApi.Models.Supplier> objSuppliersList = JsonConvert.DeserializeObject<List<MyAppApi.Models.Supplier>>(responseBody); return objSuppliersList; } /// <summary> /// Selects records as a collection (List) of MyAppApi.Models.Category /// Retrieves a collection (List) of two colums per row, normally the Primary Key column and another column for use in a drop down list /// </summary> private async Task<List<MyAppApi.Models.Category>> GetCategoryDropDownListDataAsync() { // get records string responseBody = await Functions.HttpClientGetAsync("CategoryApi/SelectCategoryDropDownListData/"); List<MyAppApi.Models.Category> objCategoriesList = JsonConvert.DeserializeObject<List<MyAppApi.Models.Category>>(responseBody); return objCategoriesList; } /// <summary> /// Deserializes the modelString and then Adds a New Record or Updates and existing record. /// This method is used by ListInlineAdd or ListInlineUpdate. /// </summary> private async Task<IActionResult> ListInlineAddOrUpdate(string modelString, CrudOperation operation) { // deserialize modelString _productViewModel.Product = JsonConvert.DeserializeObject<Product>("{" + modelString + "}"); // add new record or update existing record await this.AddEditProductAsync(_productViewModel, operation, true); return Json(true); } /// <summary> /// Gets json-formatted data based on the List of Products for use by the jqgrid. /// </summary> /// <param name="objProductsList">List of Products</param> /// <param name="totalPages">Total number of pages</param> /// <param name="page">Current page the grid is on</param> /// <param name="totalRecords">Total number of records</param> /// <returns>List of Products in Json format</returns> private JsonResult GetJsonData(List<Product> objProductsList, int totalPages, int page, int totalRecords) { // return a null in json for use by the jqgrid if (objProductsList is null) return Json("{ total = 0, page = 0, records = 0, rows = null }"); // create a serialized json object for use by the jqgrid var jsonData = new { total = totalPages, page, records = totalRecords, rows = ( from objProduct in objProductsList select new { id = objProduct.ProductID, cell = new string[] { objProduct.ProductID.ToString(), objProduct.ProductName, objProduct.SupplierID.HasValue ? objProduct.SupplierID.Value.ToString() : "", objProduct.CategoryID.HasValue ? objProduct.CategoryID.Value.ToString() : "", objProduct.QuantityPerUnit, objProduct.UnitPrice.HasValue ? objProduct.UnitPrice.Value.ToString() : "", objProduct.UnitsInStock.HasValue ? objProduct.UnitsInStock.Value.ToString() : "", objProduct.UnitsOnOrder.HasValue ? objProduct.UnitsOnOrder.Value.ToString() : "", objProduct.ReorderLevel.HasValue ? objProduct.ReorderLevel.Value.ToString() : "", objProduct.Discontinued.ToString() } }).ToArray() }; return Json(jsonData); } /// <summary> /// Gets json-formatted data based on the List of Products for use by the jqgrid. /// </summary> /// <param name="objProductsList">List of Products</param> /// <param name="totalPages">Total number of pages</param> /// <param name="page">Current page the grid is on</param> /// <param name="totalRecords">Total number of records</param> /// <returns>List of Products in Json format</returns> private JsonResult GetJsonDataGroupedBySupplierID(List<Product> objProductsList, int totalPages, int page, int totalRecords) { // return a null in json for use by the jqgrid if (objProductsList is null) return Json("{ total = 0, page = 0, records = 0, rows = null }"); // create a serialized json object for use by the jqgrid var jsonData = new { total = totalPages, page, records = totalRecords, rows = ( from objProduct in objProductsList select new { id = objProduct.ProductID, cell = new string[] { objProduct.ProductID.ToString(), objProduct.ProductName, objProduct.SupplierID.HasValue ? objProduct.SupplierID.Value.ToString() : "", objProduct.CategoryID.HasValue ? objProduct.CategoryID.Value.ToString() : "", objProduct.QuantityPerUnit, objProduct.UnitPrice.HasValue ? objProduct.UnitPrice.Value.ToString() : "", objProduct.UnitsInStock.HasValue ? objProduct.UnitsInStock.Value.ToString() : "", objProduct.UnitsOnOrder.HasValue ? objProduct.UnitsOnOrder.Value.ToString() : "", objProduct.ReorderLevel.HasValue ? objProduct.ReorderLevel.Value.ToString() : "", objProduct.Discontinued.ToString(), objProduct.SupplierID is null ? "" : objProduct.Supplier.CompanyName } }).ToArray() }; return Json(jsonData); } /// <summary> /// Gets json-formatted data based on the List of Products for use by the jqgrid. /// </summary> /// <param name="objProductsList">List of Products</param> /// <param name="totalPages">Total number of pages</param> /// <param name="page">Current page the grid is on</param> /// <param name="totalRecords">Total number of records</param> /// <returns>List of Products in Json format</returns> private JsonResult GetJsonDataGroupedByCategoryID(List<Product> objProductsList, int totalPages, int page, int totalRecords) { // return a null in json for use by the jqgrid if (objProductsList is null) return Json("{ total = 0, page = 0, records = 0, rows = null }"); // create a serialized json object for use by the jqgrid var jsonData = new { total = totalPages, page, records = totalRecords, rows = ( from objProduct in objProductsList select new { id = objProduct.ProductID, cell = new string[] { objProduct.ProductID.ToString(), objProduct.ProductName, objProduct.SupplierID.HasValue ? objProduct.SupplierID.Value.ToString() : "", objProduct.CategoryID.HasValue ? objProduct.CategoryID.Value.ToString() : "", objProduct.QuantityPerUnit, objProduct.UnitPrice.HasValue ? objProduct.UnitPrice.Value.ToString() : "", objProduct.UnitsInStock.HasValue ? objProduct.UnitsInStock.Value.ToString() : "", objProduct.UnitsOnOrder.HasValue ? objProduct.UnitsOnOrder.Value.ToString() : "", objProduct.ReorderLevel.HasValue ? objProduct.ReorderLevel.Value.ToString() : "", objProduct.Discontinued.ToString(), objProduct.CategoryID is null ? "" : objProduct.Category.CategoryName } }).ToArray() }; return Json(jsonData); } #endregion #region methods that return data in json format used by the jqgrid /// <summary> /// GET: /Product/GridData /// Gets the json needed by the jqgrid for use by the GridData /// </summary> public async Task<IActionResult> GridData(string sidx, string sord, int page, int rows) { // get the total number of records string responseBody1 = await Functions.HttpClientGetAsync("ProductApi/GetRecordCount/"); int totalRecords = JsonConvert.DeserializeObject<int>(responseBody1); // get the index where to start retrieving records from and the total number of pages (int startRowIndex, int totalPages) = Functions.GetStartRowIndexAndTotalPages(page, rows, totalRecords); // get records List<Product> objProductsList = null; string responseBody2 = await Functions.HttpClientGetAsync("ProductApi/SelectSkipAndTake/?rows=" + rows + "&page=" + page + "&sidx=" + sidx + "&sord=" + sord); // make sure responseBody2 is not empty before deserialization if(!String.IsNullOrEmpty(responseBody2)) objProductsList = JsonConvert.DeserializeObject<List<Product>>(responseBody2); // return json data for use by the jqgrid return this.GetJsonData(objProductsList, totalPages, page, totalRecords); } /// <summary> /// GET: /Product/GridDataWithFilters /// Gets the json needed by the jqgrid for use by the GridDataWithFilters /// </summary> public async Task<IActionResult> GridDataWithFilters(string _search, string nd, int rows, int page, string sidx, string sord, string filters = "") { 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; if (!String.IsNullOrEmpty(filters)) { // deserialize filters and get values being searched var jsonResult = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(filters); foreach (var rule in jsonResult["rules"]) { if (rule["field"].Value.ToLower() == "productid") productID = Convert.ToInt32(rule["data"].Value); if (rule["field"].Value.ToLower() == "productname") productName = rule["data"].Value; if (rule["field"].Value.ToLower() == "supplierid") supplierID = Convert.ToInt32(rule["data"].Value); if (rule["field"].Value.ToLower() == "categoryid") categoryID = Convert.ToInt32(rule["data"].Value); if (rule["field"].Value.ToLower() == "quantityperunit") quantityPerUnit = rule["data"].Value; if (rule["field"].Value.ToLower() == "unitprice") unitPrice = Convert.ToDecimal(rule["data"].Value); if (rule["field"].Value.ToLower() == "unitsinstock") unitsInStock = Convert.ToInt16(rule["data"].Value); if (rule["field"].Value.ToLower() == "unitsonorder") unitsOnOrder = Convert.ToInt16(rule["data"].Value); if (rule["field"].Value.ToLower() == "reorderlevel") reorderLevel = Convert.ToInt16(rule["data"].Value); if (rule["field"].Value.ToLower() == "discontinued") discontinued = Convert.ToBoolean(rule["data"].Value); } // sometimes jqgrid assigns a -1 to numeric fields when no value is assigned // instead of assigning a null, we'll correct this here if (productID == -1) productID = null; if (supplierID == -1) supplierID = null; if (categoryID == -1) categoryID = null; if (unitPrice == -1) unitPrice = null; if (unitsInStock == -1) unitsInStock = null; if (unitsOnOrder == -1) unitsOnOrder = null; if (reorderLevel == -1) reorderLevel = null; } // get the total number of records based on filters int totalRecords = 0; string responseBody1 = await Functions.HttpClientGetAsync("ProductApi/GetRecordCountDynamicWhere/?productID=" + productID + "&productName=" + productName + "&supplierID=" + supplierID + "&categoryID=" + categoryID + "&quantityPerUnit=" + quantityPerUnit + "&unitPrice=" + unitPrice + "&unitsInStock=" + unitsInStock + "&unitsOnOrder=" + unitsOnOrder + "&reorderLevel=" + reorderLevel + "&discontinued=" + discontinued); totalRecords = JsonConvert.DeserializeObject<int>(responseBody1); // get the index where to start retrieving records from and the total pages (int startRowIndex, int totalPages) = Functions.GetStartRowIndexAndTotalPages(page, rows, totalRecords); // get records based on filters List<Product> objProductsList = null; string responseBody2 = await Functions.HttpClientGetAsync("ProductApi/SelectSkipAndTakeDynamicWhere/?productID=" + productID + "&productName=" + productName + "&supplierID=" + supplierID + "&categoryID=" + categoryID + "&quantityPerUnit=" + quantityPerUnit + "&unitPrice=" + unitPrice + "&unitsInStock=" + unitsInStock + "&unitsOnOrder=" + unitsOnOrder + "&reorderLevel=" + reorderLevel + "&discontinued=" + discontinued + "&rows=" + rows + "&startRowIndex=" + startRowIndex + "&sortByExpression=" + sidx + " " + sord); // make sure responseBody2 is not empty before deserialization if(!String.IsNullOrEmpty(responseBody2)) objProductsList = JsonConvert.DeserializeObject<List<Product>>(responseBody2); // return json data for use by the jqgrid return this.GetJsonData(objProductsList, totalPages, page, totalRecords); } /// <summary> /// GET: /Product/GridDataWithTotals /// Gets the json needed by the jqgrid for use by the GridDataWithTotals /// </summary> public async Task<IActionResult> GridDataWithTotals(string sidx, string sord, int page, int rows) { // get the total number of records string responseBody1 = await Functions.HttpClientGetAsync("ProductApi/GetRecordCount/"); int totalRecords = JsonConvert.DeserializeObject<int>(responseBody1); // get the index where to start retrieving records from and the total number of pages (int startRowIndex, int totalPages) = Functions.GetStartRowIndexAndTotalPages(page, rows, totalRecords); // get records List<Product> objProductsList = null; string responseBody2 = await Functions.HttpClientGetAsync("ProductApi/SelectSkipAndTake/?rows=" + rows + "&page=" + page + "&sidx=" + sidx + "&sord=" + sord); // make sure responseBody2 is not empty before deserialization if(!String.IsNullOrEmpty(responseBody2)) objProductsList = JsonConvert.DeserializeObject<List<Product>>(responseBody2); // return json data for use by the jqgrid return this.GetJsonData(objProductsList, totalPages, page, totalRecords); } /// <summary> /// GET: /Product/GridDataGroupedBySupplierID /// Gets the json needed by the jqgrid for use by the GridDataGroupedBySupplierID /// </summary> public async Task<IActionResult> GridDataGroupedBySupplierID(string sidx, string sord, int page, int rows) { // using a groupBy field in the jqgrid passes that field // along with the field to sort, remove the groupBy field string groupBy = "CompanyName asc, "; sidx = sidx.Replace(groupBy, ""); // get the total number of records string responseBody1 = await Functions.HttpClientGetAsync("ProductApi/GetRecordCount/"); int totalRecords = JsonConvert.DeserializeObject<int>(responseBody1); // get the index where to start retrieving records from and the total number of pages (int startRowIndex, int totalPages) = Functions.GetStartRowIndexAndTotalPages(page, rows, totalRecords); // get records List<Product> objProductsList = null; string responseBody2 = await Functions.HttpClientGetAsync("ProductApi/SelectSkipAndTake/?rows=" + rows + "&page=" + page + "&sidx=" + sidx + "&sord=" + sord); // make sure responseBody2 is not empty before deserialization if(!String.IsNullOrEmpty(responseBody2)) objProductsList = JsonConvert.DeserializeObject<List<Product>>(responseBody2); // return json data for use by the jqgrid return this.GetJsonDataGroupedBySupplierID(objProductsList, totalPages, page, totalRecords); } /// <summary> /// GET: /Product/GridDataGroupedByCategoryID /// Gets the json needed by the jqgrid for use by the GridDataGroupedByCategoryID /// </summary> public async Task<IActionResult> GridDataGroupedByCategoryID(string sidx, string sord, int page, int rows) { // using a groupBy field in the jqgrid passes that field // along with the field to sort, remove the groupBy field string groupBy = "CategoryName asc, "; sidx = sidx.Replace(groupBy, ""); // get the total number of records string responseBody1 = await Functions.HttpClientGetAsync("ProductApi/GetRecordCount/"); int totalRecords = JsonConvert.DeserializeObject<int>(responseBody1); // get the index where to start retrieving records from and the total number of pages (int startRowIndex, int totalPages) = Functions.GetStartRowIndexAndTotalPages(page, rows, totalRecords); // get records List<Product> objProductsList = null; string responseBody2 = await Functions.HttpClientGetAsync("ProductApi/SelectSkipAndTake/?rows=" + rows + "&page=" + page + "&sidx=" + sidx + "&sord=" + sord); // make sure responseBody2 is not empty before deserialization if(!String.IsNullOrEmpty(responseBody2)) objProductsList = JsonConvert.DeserializeObject<List<Product>>(responseBody2); // return json data for use by the jqgrid return this.GetJsonDataGroupedByCategoryID(objProductsList, totalPages, page, totalRecords); } /// <summary> /// GET: /Product/GridDataTotalsGroupedBySupplierID /// Gets the json needed by the jqgrid for use by the GridDataTotalsGroupedBySupplierID /// </summary> public async Task<IActionResult> GridDataTotalsGroupedBySupplierID(string sidx, string sord, int page, int rows) { // using a groupBy field in the jqgrid passes that field // along with the field to sort, remove the groupBy field string groupBy = "CompanyName asc, "; sidx = sidx.Replace(groupBy, ""); // get the total number of records string responseBody1 = await Functions.HttpClientGetAsync("ProductApi/GetRecordCount/"); int totalRecords = JsonConvert.DeserializeObject<int>(responseBody1); // get the index where to start retrieving records from and the total number of pages (int startRowIndex, int totalPages) = Functions.GetStartRowIndexAndTotalPages(page, rows, totalRecords); // get records List<Product> objProductsList = null; string responseBody2 = await Functions.HttpClientGetAsync("ProductApi/SelectSkipAndTake/?rows=" + rows + "&page=" + page + "&sidx=" + sidx + "&sord=" + sord); // make sure responseBody2 is not empty before deserialization if(!String.IsNullOrEmpty(responseBody2)) objProductsList = JsonConvert.DeserializeObject<List<Product>>(responseBody2); // return json data for use by the jqgrid return this.GetJsonDataGroupedBySupplierID(objProductsList, totalPages, page, totalRecords); } /// <summary> /// GET: /Product/GridDataTotalsGroupedByCategoryID /// Gets the json needed by the jqgrid for use by the GridDataTotalsGroupedByCategoryID /// </summary> public async Task<IActionResult> GridDataTotalsGroupedByCategoryID(string sidx, string sord, int page, int rows) { // using a groupBy field in the jqgrid passes that field // along with the field to sort, remove the groupBy field string groupBy = "CategoryName asc, "; sidx = sidx.Replace(groupBy, ""); // get the total number of records string responseBody1 = await Functions.HttpClientGetAsync("ProductApi/GetRecordCount/"); int totalRecords = JsonConvert.DeserializeObject<int>(responseBody1); // get the index where to start retrieving records from and the total number of pages (int startRowIndex, int totalPages) = Functions.GetStartRowIndexAndTotalPages(page, rows, totalRecords); // get records List<Product> objProductsList = null; string responseBody2 = await Functions.HttpClientGetAsync("ProductApi/SelectSkipAndTake/?rows=" + rows + "&page=" + page + "&sidx=" + sidx + "&sord=" + sord); // make sure responseBody2 is not empty before deserialization if(!String.IsNullOrEmpty(responseBody2)) objProductsList = JsonConvert.DeserializeObject<List<Product>>(responseBody2); // return json data for use by the jqgrid return this.GetJsonDataGroupedByCategoryID(objProductsList, totalPages, page, totalRecords); } /// <summary> /// GET: /Product/GridDataBySupplierID /// Gets the json needed by the jqgrid for use by the GridDataBySupplierID /// </summary> public async Task<IActionResult> GridDataBySupplierID(string sidx, string sord, int page, int rows, int? supplierID) { // get the total number of records string responseBody1 = await Functions.HttpClientGetAsync("ProductApi/GetRecordCountBySupplierID/?id=" + supplierID); int totalRecords = JsonConvert.DeserializeObject<int>(responseBody1); // get the index where to start retrieving records from and the total number of pages (int startRowIndex, int totalPages) = Functions.GetStartRowIndexAndTotalPages(page, rows, totalRecords); // get records List<Product> objProductsList = null; string responseBody2 = await Functions.HttpClientGetAsync("ProductApi/SelectSkipAndTakeBySupplierID/?rows=" + rows + "&page=" + page + "&sidx=" + sidx + "&sord=" + sord + "&supplierID=" + supplierID); // make sure responseBody2 is not empty before deserialization if(!String.IsNullOrEmpty(responseBody2)) objProductsList = JsonConvert.DeserializeObject<List<Product>>(responseBody2); // return json data for use by the jqgrid return this.GetJsonData(objProductsList, totalPages, page, totalRecords); } /// <summary> /// GET: /Product/GridDataByCategoryID /// Gets the json needed by the jqgrid for use by the GridDataByCategoryID /// </summary> public async Task<IActionResult> GridDataByCategoryID(string sidx, string sord, int page, int rows, int? categoryID) { // get the total number of records string responseBody1 = await Functions.HttpClientGetAsync("ProductApi/GetRecordCountByCategoryID/?id=" + categoryID); int totalRecords = JsonConvert.DeserializeObject<int>(responseBody1); // get the index where to start retrieving records from and the total number of pages (int startRowIndex, int totalPages) = Functions.GetStartRowIndexAndTotalPages(page, rows, totalRecords); // get records List<Product> objProductsList = null; string responseBody2 = await Functions.HttpClientGetAsync("ProductApi/SelectSkipAndTakeByCategoryID/?rows=" + rows + "&page=" + page + "&sidx=" + sidx + "&sord=" + sord + "&categoryID=" + categoryID); // make sure responseBody2 is not empty before deserialization if(!String.IsNullOrEmpty(responseBody2)) objProductsList = JsonConvert.DeserializeObject<List<Product>>(responseBody2); // return json data for use by the jqgrid return this.GetJsonData(objProductsList, totalPages, page, totalRecords); } #endregion } }