using ACG6MvcAdHcApi.DataRepository; using ACG6MvcAdHcApi.Models; using System; using System.Collections.Generic; using System.Data; using System.Threading.Tasks; namespace ACG6MvcAdHcApi.BusinessLayer { /// <summary> /// Works like the Base class for ProductBusinessLayer class. /// ************************************* Do not make changes to this class ************************************* /// ** Put your additional code in the ProductBusinessLayer class under the BusinessLayer folder. ** /// ************************************************************************************************************* /// /// </summary> public partial class ProductBusinessLayer : IProductBusinessLayer { private readonly IProductRepository _productRepository; private readonly ISupplierBusinessLayer _supplierBusinessLayer; private readonly ICategoryBusinessLayer _categoryBusinessLayer; /// <summary> /// constructor /// </summary> public ProductBusinessLayer(IProductRepository productRepository, ISupplierBusinessLayer supplierBusinessLayer, ICategoryBusinessLayer categoryBusinessLayer) { _productRepository = productRepository; _supplierBusinessLayer = supplierBusinessLayer; _categoryBusinessLayer = categoryBusinessLayer; } /// <summary> /// Selects a record by primary key(s) /// </summary> public async Task<Product> SelectByPrimaryKeyAsync(int productID) { DataTable dt = await _productRepository.SelectByPrimaryKeyAsync(productID); // create Product if (dt is not null && dt.Rows.Count > 0) return await this.CreateProductFromDataRowAsync(dt.Rows[0]); return null; } /// <summary> /// Gets the total number of records in the Products table /// </summary> public async Task<int> GetRecordCountAsync() { return await _productRepository.GetRecordCountAsync(); } /// <summary> /// Gets the total number of records in the Products table by SupplierID /// </summary> public async Task<int> GetRecordCountBySupplierIDAsync(int? supplierID) { return await _productRepository.GetRecordCountBySupplierIDAsync(supplierID); } /// <summary> /// Gets the total number of records in the Products table by CategoryID /// </summary> public async Task<int> GetRecordCountByCategoryIDAsync(int? categoryID) { return await _productRepository.GetRecordCountByCategoryIDAsync(categoryID); } /// <summary> /// Gets the total number of records in the Products table based on search parameters /// </summary> public async Task<int> GetRecordCountDynamicWhereAsync(int? productID, string productName, int? supplierID, int? categoryID, string quantityPerUnit, decimal? unitPrice, Int16? unitsInStock, Int16? unitsOnOrder, Int16? reorderLevel, bool? discontinued) { return await _productRepository.GetRecordCountDynamicWhereAsync(productID, productName, supplierID, categoryID, quantityPerUnit, unitPrice, unitsInStock, unitsOnOrder, reorderLevel, discontinued); } /// <summary> /// Selects records as a collection (List) of Product sorted by the sortByExpression. /// </summary> public async Task<List<Product>> SelectSkipAndTakeAsync(int rows, int startRowIndex, string sortByExpression) { sortByExpression = this.GetSortExpression(sortByExpression); DataTable dt = await _productRepository.SelectSkipAndTakeAsync(sortByExpression, startRowIndex, rows); return await this.GetListOfProduct(dt); } /// <summary> /// Selects records by SupplierID as a collection (List) of Product sorted by the sortByExpression starting from the startRowIndex /// </summary> public async Task<List<Product>> SelectSkipAndTakeBySupplierIDAsync(int rows, int startRowIndex, string sortByExpression, int? supplierID) { sortByExpression = this.GetSortExpression(sortByExpression); DataTable dt = await _productRepository.SelectSkipAndTakeBySupplierIDAsync(sortByExpression, startRowIndex, rows, supplierID); return await this.GetListOfProduct(dt); } /// <summary> /// Selects records by CategoryID as a collection (List) of Product sorted by the sortByExpression starting from the startRowIndex /// </summary> public async Task<List<Product>> SelectSkipAndTakeByCategoryIDAsync(int rows, int startRowIndex, string sortByExpression, int? categoryID) { sortByExpression = this.GetSortExpression(sortByExpression); DataTable dt = await _productRepository.SelectSkipAndTakeByCategoryIDAsync(sortByExpression, startRowIndex, rows, categoryID); return await this.GetListOfProduct(dt); } /// <summary> /// Selects records as a collection (List) of Product sorted by the sortByExpression starting from the startRowIndex, based on the search parameters /// </summary> public async Task<List<Product>> SelectSkipAndTakeDynamicWhereAsync(int? productID, string productName, int? supplierID, int? categoryID, string quantityPerUnit, decimal? unitPrice, Int16? unitsInStock, Int16? unitsOnOrder, Int16? reorderLevel, bool? discontinued, int rows, int startRowIndex, string sortByExpression) { sortByExpression = this.GetSortExpression(sortByExpression); DataTable dt = await _productRepository.SelectSkipAndTakeDynamicWhereAsync(productID, productName, supplierID, categoryID, quantityPerUnit, unitPrice, unitsInStock, unitsOnOrder, reorderLevel, discontinued, sortByExpression, startRowIndex, rows); return await this.GetListOfProduct(dt); } /// <summary> /// Selects all records as a collection (List) of Product /// </summary> public async Task<List<Product>> SelectAllAsync() { DataTable dt = await _productRepository.SelectAllAsync(); return await this.GetListOfProduct(dt); } /// <summary> /// Selects all records as a collection (List) of Product sorted by the sort expression /// </summary> public async Task<List<Product>> SelectAllAsync(string sortByExpression) { DataTable dt = await _productRepository.SelectAllAsync(); List<Product> objProductsList = await this.GetListOfProduct(dt); return await this.SortByExpressionAsync(objProductsList, sortByExpression); } /// <summary> /// Selects records based on the passed filters as a collection (List) of Product. /// </summary> public async Task<List<Product>> SelectAllDynamicWhereAsync(int? productID, string productName, int? supplierID, int? categoryID, string quantityPerUnit, decimal? unitPrice, Int16? unitsInStock, Int16? unitsOnOrder, Int16? reorderLevel, bool? discontinued) { DataTable dt = await _productRepository.SelectAllDynamicWhereAsync(productID, productName, supplierID, categoryID, quantityPerUnit, unitPrice, unitsInStock, unitsOnOrder, reorderLevel, discontinued); return await this.GetListOfProduct(dt); } /// <summary> /// Selects records based on the passed filters as a collection (List) of Product sorted by the sort expression. /// </summary> public async Task<List<Product>> SelectAllDynamicWhereAsync(int? productID, string productName, int? supplierID, int? categoryID, string quantityPerUnit, decimal? unitPrice, Int16? unitsInStock, Int16? unitsOnOrder, Int16? reorderLevel, bool? discontinued, string sortByExpression) { DataTable dt = await _productRepository.SelectAllDynamicWhereAsync(productID, productName, supplierID, categoryID, quantityPerUnit, unitPrice, unitsInStock, unitsOnOrder, reorderLevel, discontinued); List<Product> objProductsList = await this.GetListOfProduct(dt); return await this.SortByExpressionAsync(objProductsList, sortByExpression); } /// <summary> /// Selects ProductID and ProductName columns for use with a DropDownList web control, ComboBox, CheckedBoxList, ListView, ListBox, etc /// </summary> public async Task<List<Product>> SelectProductDropDownListDataAsync() { List<Product> objProductsList = null; DataTable dt = await _productRepository.SelectProductDropDownListDataAsync(); // build the list of Products if (dt is not null && dt.Rows.Count > 0) { objProductsList = new(); foreach (DataRow dr in dt.Rows) { Product objProduct = new(); objProduct.ProductID = (int)dr["ProductID"]; if(String.IsNullOrEmpty(dr["ProductName"].ToString())) objProduct.ProductName = String.Empty; else objProduct.ProductName = (string)(dr["ProductName"]); objProductsList.Add(objProduct); } } return objProductsList; } /// <summary> /// Sorts the List<Product >by sort expression /// </summary> public async Task<List<Product>> SortByExpressionAsync(List<Product> objProductsList, string sortExpression) { bool isSortDescending = sortExpression.ToLower().Contains(" desc"); if (isSortDescending) { sortExpression = sortExpression.Replace(" DESC", ""); sortExpression = sortExpression.Replace(" desc", ""); } else { sortExpression = sortExpression.Replace(" ASC", ""); sortExpression = sortExpression.Replace(" asc", ""); } switch (sortExpression) { case "ProductID": await Task.Run(() => objProductsList.Sort(ACG6MvcAdHcApi.BusinessLayer.ProductBusinessLayer.ByProductID)); break; case "ProductName": await Task.Run(() => objProductsList.Sort(ACG6MvcAdHcApi.BusinessLayer.ProductBusinessLayer.ByProductName)); break; case "SupplierID": await Task.Run(() => objProductsList.Sort(ACG6MvcAdHcApi.BusinessLayer.ProductBusinessLayer.BySupplierID)); break; case "CategoryID": await Task.Run(() => objProductsList.Sort(ACG6MvcAdHcApi.BusinessLayer.ProductBusinessLayer.ByCategoryID)); break; case "QuantityPerUnit": await Task.Run(() => objProductsList.Sort(ACG6MvcAdHcApi.BusinessLayer.ProductBusinessLayer.ByQuantityPerUnit)); break; case "UnitPrice": await Task.Run(() => objProductsList.Sort(ACG6MvcAdHcApi.BusinessLayer.ProductBusinessLayer.ByUnitPrice)); break; case "UnitsInStock": await Task.Run(() => objProductsList.Sort(ACG6MvcAdHcApi.BusinessLayer.ProductBusinessLayer.ByUnitsInStock)); break; case "UnitsOnOrder": await Task.Run(() => objProductsList.Sort(ACG6MvcAdHcApi.BusinessLayer.ProductBusinessLayer.ByUnitsOnOrder)); break; case "ReorderLevel": await Task.Run(() => objProductsList.Sort(ACG6MvcAdHcApi.BusinessLayer.ProductBusinessLayer.ByReorderLevel)); break; case "Discontinued": await Task.Run(() => objProductsList.Sort(ACG6MvcAdHcApi.BusinessLayer.ProductBusinessLayer.ByDiscontinued)); break; default: break; } if (isSortDescending) objProductsList.Reverse(); return objProductsList; } /// <summary> /// Inserts a new record /// </summary> public async Task<int> InsertAsync(Product objProduct) { return await _productRepository.InsertAsync(objProduct); } /// <summary> /// Updates a record /// </summary> public async Task UpdateAsync(Product objProduct) => await _productRepository.UpdateAsync(objProduct); /// <summary> /// Deletes a record based on primary key(s) /// </summary> public async Task DeleteAsync(int productID) => await _productRepository.DeleteAsync(productID); /// <summary> /// Deletes multiple records based on primary keys /// </summary> public async Task DeleteMultipleAsync(List<Int32> productIDList) { foreach (var id in productIDList) { await _productRepository.DeleteAsync(id); } } /// <summary> /// Gets the default sort expression when no sort expression is provided /// </summary> private string GetSortExpression(string sortByExpression) { // when no sort expression is provided, ProductID is set as the default in ascending order // for ascending order, "asc" is not needed, so it is removed if (String.IsNullOrEmpty(sortByExpression) || sortByExpression == " asc") sortByExpression = "ProductID"; else if (sortByExpression.Contains(" asc")) sortByExpression = sortByExpression.Replace(" asc", ""); return sortByExpression; } /// <summary> /// Gets a List of Products based on the sql script. /// </summary> /// <param name="sqlParamList">List of SqlParameters</param> /// <param name="sql">The SQL script</param> /// <returns>List of Products</returns> private async Task<List<Product>> GetListOfProduct (DataTable dt) { List<Product> objProductsList = null; // build the list of Products if (dt != null && dt.Rows.Count > 0) { objProductsList = new List<Product>(); foreach (DataRow dr in dt.Rows) { Product objProduct = await this.CreateProductFromDataRowAsync(dr); objProductsList.Add(objProduct); } } return objProductsList; } /// <summary> /// Creates a Product object from Data Row /// </summary> private async Task<Product> CreateProductFromDataRowAsync(DataRow dr) { // instantiate the Product model Product objProduct = new(); // assign values to the model objProduct.ProductID = (int)dr["ProductID"]; objProduct.ProductName = dr["ProductName"].ToString(); if (dr["SupplierID"] != System.DBNull.Value) { int supplierID = (int)dr["SupplierID"]; objProduct.SupplierID = supplierID; objProduct.Supplier = await _supplierBusinessLayer.SelectByPrimaryKeyAsync(supplierID); } else { objProduct.SupplierID = null; objProduct.Supplier = null; } if (dr["CategoryID"] != System.DBNull.Value) { int categoryID = (int)dr["CategoryID"]; objProduct.CategoryID = categoryID; objProduct.Category = await _categoryBusinessLayer.SelectByPrimaryKeyAsync(categoryID); } else { objProduct.CategoryID = null; objProduct.Category = null; } if (dr["QuantityPerUnit"] != System.DBNull.Value) objProduct.QuantityPerUnit = dr["QuantityPerUnit"].ToString(); else objProduct.QuantityPerUnit = null; if (dr["UnitPrice"] != System.DBNull.Value) objProduct.UnitPrice = (decimal)dr["UnitPrice"]; else objProduct.UnitPrice = null; if (dr["UnitsInStock"] != System.DBNull.Value) objProduct.UnitsInStock = (Int16)dr["UnitsInStock"]; else objProduct.UnitsInStock = null; if (dr["UnitsOnOrder"] != System.DBNull.Value) objProduct.UnitsOnOrder = (Int16)dr["UnitsOnOrder"]; else objProduct.UnitsOnOrder = null; if (dr["ReorderLevel"] != System.DBNull.Value) objProduct.ReorderLevel = (Int16)dr["ReorderLevel"]; else objProduct.ReorderLevel = null; objProduct.Discontinued = (bool)dr["Discontinued"]; return objProduct; } /// <summary> /// Compares ProductID used for sorting /// </summary> public static Comparison<Product> ByProductID = delegate(Product x, Product y) { return x.ProductID.CompareTo(y.ProductID); }; /// <summary> /// Compares ProductName used for sorting /// </summary> public static Comparison<Product> ByProductName = delegate(Product x, Product y) { string value1 = x.ProductName ?? String.Empty; string value2 = y.ProductName ?? String.Empty; return value1.CompareTo(value2); }; /// <summary> /// Compares SupplierID used for sorting /// </summary> public static Comparison<Product> BySupplierID = delegate(Product x, Product y) { return Nullable.Compare(x.SupplierID, y.SupplierID); }; /// <summary> /// Compares CategoryID used for sorting /// </summary> public static Comparison<Product> ByCategoryID = delegate(Product x, Product y) { return Nullable.Compare(x.CategoryID, y.CategoryID); }; /// <summary> /// Compares QuantityPerUnit used for sorting /// </summary> public static Comparison<Product> ByQuantityPerUnit = delegate(Product x, Product y) { string value1 = x.QuantityPerUnit ?? String.Empty; string value2 = y.QuantityPerUnit ?? String.Empty; return value1.CompareTo(value2); }; /// <summary> /// Compares UnitPrice used for sorting /// </summary> public static Comparison<Product> ByUnitPrice = delegate(Product x, Product y) { return Nullable.Compare(x.UnitPrice, y.UnitPrice); }; /// <summary> /// Compares UnitsInStock used for sorting /// </summary> public static Comparison<Product> ByUnitsInStock = delegate(Product x, Product y) { return Nullable.Compare(x.UnitsInStock, y.UnitsInStock); }; /// <summary> /// Compares UnitsOnOrder used for sorting /// </summary> public static Comparison<Product> ByUnitsOnOrder = delegate(Product x, Product y) { return Nullable.Compare(x.UnitsOnOrder, y.UnitsOnOrder); }; /// <summary> /// Compares ReorderLevel used for sorting /// </summary> public static Comparison<Product> ByReorderLevel = delegate(Product x, Product y) { return Nullable.Compare(x.ReorderLevel, y.ReorderLevel); }; /// <summary> /// Compares Discontinued used for sorting /// </summary> public static Comparison<Product> ByDiscontinued = delegate(Product x, Product y) { return x.Discontinued.CompareTo(y.Discontinued); }; } }