/// <summary> /// HELPER return and log error /// </summary> /// <param name="text"></param> /// <returns></returns> public AlzaAdminDTO ErrorDTO(string text) { Guid errNo = Guid.NewGuid(); _logger.LogError(errNo + " - " + text); return(AlzaAdminDTO.Error(errNo, "someString")); }
/// <summary> /// HELPER return and log error /// </summary> /// <param name="text"></param> /// <returns></returns> public AlzaAdminDTO ExceptionDTO(Exception e) { Guid errNo = Guid.NewGuid(); _logger.LogError(errNo + " - " + e.Message + Environment.NewLine + e.StackTrace); return(AlzaAdminDTO.Error(errNo, e.Message + Environment.NewLine + e.StackTrace)); }
/// <summary> /// Get a product with reviews and ratings /// </summary> /// <param name="id">Product id</param> /// <returns>DTO of Product with Reviews and Average rating</returns> public AlzaAdminDTO <ProductBO> GetProduct(int id) { try { //gets the base product with no reviews and ratings var baseProduct = _productRepository.GetProduct(id); //if the product was not found, it cannot be joined with any ratings if (ReferenceEquals(baseProduct, null)) { return(AlzaAdminDTO <ProductBO> .Data(null)); } //average rating of the product var avRating = _productRatingRepository.GetRating(id); //get product reviews and users who submitted the reviews var reviews = _reviewRepository.GetReviews().Where(r => r.ProductId == id).ToList(); var users = _userProfileRepository.GetAllProfiles().Where(p => reviews.Select(r => r.UserId).Contains(p.Id)); reviews = reviews.Join(users, r => r.UserId, p => p.Id, (r, p) => { r.User = p; return(r); }).OrderBy(r => r.Date).ToList(); var product = new ProductBO(baseProduct, avRating, reviews); return(AlzaAdminDTO <ProductBO> .Data(product)); } catch (Exception e) { return(AlzaAdminDTO <ProductBO> .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/**********************************************/ /* HELPERS */ /**********************************************/ /// </// <summary> /// HELPER return and log error /// </summary> /// <param name="text"></param> /// <returns></returns> public AlzaAdminDTO Error(string text) { Guid errNo = Guid.NewGuid(); _logger.LogCritical(errNo + " - " + text); return(AlzaAdminDTO.Error(errNo, "SomeText")); }
/// <summary> /// Adds an item to a cart /// </summary> /// <param name="visitorId">Id of the Visitor</param> /// <param name="userId">Id of the user</param> /// <param name="productId">Product identifier</param> /// <param name="amount">Product amount</param> /// <returns>DTO of the cart</returns> public AlzaAdminDTO <List <CartItem> > AddToCart(string visitorId, int?userId, int productId, int amount = 1) { try { var currentCartItem = _cartItemRepository.GetCartItem(visitorId, productId); if (currentCartItem != null) { currentCartItem.Amount += amount; _cartItemRepository.UpdateCartItem(currentCartItem); } else { var cartItem = new CartItem { VisitorId = visitorId, Amount = amount, ProductId = productId, UserId = userId }; _cartItemRepository.AddCartItem(cartItem); } return(GetCart(visitorId)); } catch (Exception e) { return(AlzaAdminDTO <List <CartItem> > .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/// <summary> /// This method returns products with applied filtering that can be displayed on the front page. /// </summary> /// <param name="parameter">Specifies the nature of the front page items, orders the products by this parameter.</param> /// <param name="type">Specifies whether the sorting is ascending or descending</param> /// <param name="count">Specifies how many items should be returned</param> /// <param name="categoryId">Specifies the category of the front page products.</param> /// <param name="timeOffset">Limits the age in days of products (by addition time).</param> /// <returns></returns> public AlzaAdminDTO <List <ProductBO> > GetFrontPage(FrontPageParameter parameter, SortType type, int count, int categoryId, int?timeOffset = null) { try { return(AlzaAdminDTO <List <ProductBO> > .Data(_filteringRepository.GetProducts(parameter, type, count, categoryId, timeOffset).ToList())); } catch (Exception e) { return(AlzaAdminDTO <List <ProductBO> > .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/// <summary> /// This method returns a filtered page of products. The product filtering occurs on the database side. /// </summary> /// <param name="parameters">Filtering parameters</param> /// <returns>A filtered page of products</returns> public AlzaAdminDTO <QueryResultWrapper> GetPageADO(QueryParametersWrapper parameters) { try { return(AlzaAdminDTO <QueryResultWrapper> .Data(_filteringRepository.FilterProducts(parameters))); } catch (Exception e) { return(AlzaAdminDTO <QueryResultWrapper> .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/// <summary> /// Enables to update an already submitted review. /// </summary> /// <param name="review">Review to update with</param> /// <returns>Updated review</returns> public AlzaAdminDTO <Review> UpdateReview(Review review) { try { return(AlzaAdminDTO <Review> .Data(_reviewRepository.UpdateReview(review))); } catch (Exception e) { return(AlzaAdminDTO <Review> .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/// <summary> /// Gets a front page preset that can be applied to the method GetFrontPage. /// </summary> /// <param name="id">Id of the preset</param> /// <returns>DTO of the preset item</returns> public AlzaAdminDTO <FrontPageItem> GetFrontPageItem(int id) { try { return(AlzaAdminDTO <FrontPageItem> .Data(_frontPageRepository.GetFrontPageItem(id))); } catch (Exception e) { return(AlzaAdminDTO <FrontPageItem> .Error(e.Message)); } }
/// <summary> /// Gets all payments /// </summary> /// <returns>DTO of payments</returns> public AlzaAdminDTO <List <Payment> > GetPayments() { try { var payments = _paymentRepository.GetPayments().ToList(); return(AlzaAdminDTO <List <Payment> > .Data(payments)); } catch (Exception e) { return(AlzaAdminDTO <List <Payment> > .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/// <summary> /// Gets a payment by id /// </summary> /// <param name="id">Payment id</param> /// <returns>DTO of the payment</returns> public AlzaAdminDTO <Payment> GetPayment(int id) { try { var payment = _paymentRepository.GetPayment(id); return(AlzaAdminDTO <Payment> .Data(payment)); } catch (Exception e) { return(AlzaAdminDTO <Payment> .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/// <summary> /// Adds a new order item /// </summary> /// <param name="item">Item to be added</param> /// <returns>DTO of the order item</returns> public AlzaAdminDTO <OrderItem> AddOrderItem(OrderItem item) { try { var orderItem = _orderItemRepository.AddOrderItem(item); return(AlzaAdminDTO <OrderItem> .Data(orderItem)); } catch (Exception e) { return(AlzaAdminDTO <OrderItem> .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/****************************************/ /* GET COUNTRY BY ID */ /****************************************/ /// <summary> /// Provides a country with a specified id /// </summary> /// <param name="id">Country id</param> /// <returns>DTO containing the country with matching id</returns> public AlzaAdminDTO <Country> GetCountry(int id) { try { var result = _countryRepos.GetCountry(id); return(AlzaAdminDTO <Country> .Data(result)); } catch (Exception e) { return(AlzaAdminDTO <Country> .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/// <summary> /// Gets all shippings /// </summary> /// <returns>Shippings</returns> public AlzaAdminDTO <List <Shipping> > GetShippings() { try { var shippings = _shippingRepository.GetShippings().ToList(); return(AlzaAdminDTO <List <Shipping> > .Data(shippings)); } catch (Exception e) { return(AlzaAdminDTO <List <Shipping> > .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/// <summary> /// Gets all front page presets marked as active. /// </summary> /// <returns>DTO of active Front page items</returns> public AlzaAdminDTO <List <FrontPageItem> > GetActivePageItems() { try { var result = _frontPageRepository.GetFrontPageItems().Where(fi => fi.Active == true).ToList(); return(AlzaAdminDTO <List <FrontPageItem> > .Data(result)); } catch (Exception e) { return(AlzaAdminDTO <List <FrontPageItem> > .Error(e.Message)); } }
/// <summary> /// Gets a shipping by id /// </summary> /// <param name="id">Shipping id</param> /// <returns>DTO of the shipping</returns> public AlzaAdminDTO <Shipping> GetShipping(int id) { try { var shipping = _shippingRepository.GetShipping(id); return(AlzaAdminDTO <Shipping> .Data(shipping)); } catch (Exception e) { return(AlzaAdminDTO <Shipping> .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/// <summary> /// Deletes an item from the cart. /// </summary> /// <param name="visitorId">Id of the item owner</param> /// <param name="productId">Product id</param> /// <returns>DTO of the cart</returns> public AlzaAdminDTO <List <CartItem> > RemoveCartItem(string visitorId, int productId) { try { _cartItemRepository.DeleteCartItem(visitorId, productId); var result = _cartItemRepository.GetCartItems().Where(ci => ci.VisitorId == visitorId).ToList(); return(AlzaAdminDTO <List <CartItem> > .Data(result)); } catch (Exception e) { return(AlzaAdminDTO <List <CartItem> > .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/// <summary> /// Gets a review of a product by a specific user. /// </summary> /// <param name="userId">Id of the user who submitted the review</param> /// <param name="productId">Id of the reviewed product</param> /// <returns>DTO of the review</returns> public AlzaAdminDTO <Review> GetReview(int userId, int productId) { try { var result = _reviewRepository.GetReview(userId, productId); result.User = _userProfileRepository.GetProfile(result.UserId); return(AlzaAdminDTO <Review> .Data(result)); } catch (Exception e) { return(AlzaAdminDTO <Review> .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
//ToDo validate input data (UserProfile properties, index uniqueness,...) /****************************************/ /* GET USER PROFILE */ /****************************************/ /// <summary> /// Provides a UserProfile in DTO.data whose Id property matches the id parameter. /// </summary> /// <param name="id">User id</param> /// <returns>Returns matching UserProfile in DTO data</returns> public AlzaAdminDTO <UserProfile> GetUserProfile(int id) { try { var result = _userRepos.GetProfile(id); return(AlzaAdminDTO <UserProfile> .Data(result)); } catch (Exception e) { return(AlzaAdminDTO <UserProfile> .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/****************************************/ /* GET ALL COUNTRIES */ /****************************************/ /// <summary> /// Provides a list of all countries /// </summary> /// <returns>DTO containing a list of all available countries</returns> public AlzaAdminDTO <ICollection <Country> > GetAllCountries() { try { var result = _countryRepos.GetCountries().ToList(); return(AlzaAdminDTO <ICollection <Country> > .Data(result)); } catch (Exception e) { return(AlzaAdminDTO <ICollection <Country> > .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/// <summary> /// HELPER return and log error /// </summary> /// <param name="text"></param> /// <returns></returns> public AlzaAdminDTO InvalidIdentityResultDTO(IdentityResult result) { Guid errNo = Guid.NewGuid(); StringBuilder res = new StringBuilder(); foreach (var error in result.Errors) { res.AppendLine(error.Description); } _logger.LogError(errNo + " - " + res.ToString()); return(AlzaAdminDTO.Error(errNo, res.ToString())); }
/// <summary> /// Gets a dictionary of indexed front page slots which contain front page items currently assigned to it. /// </summary> /// <returns>DTO of a dictionary containing all FrontPageSlots</returns> public AlzaAdminDTO <Dictionary <int, FrontPageSlot> > GetPageSlots() { try { var result = _frontPageRepository.GetSlotItems().ToDictionary(si => si.SlotId); return(AlzaAdminDTO <Dictionary <int, FrontPageSlot> > .Data(result)); } catch (Exception e) { return(AlzaAdminDTO <Dictionary <int, FrontPageSlot> > .Error(e.Message)); } }
/// <summary> /// Merges an anonymous cart with an existing user cart. If there are any items in the user cart, it is possible to delete them or leave them intact. /// </summary> /// <param name="visitorId">Id of the visitor who owns the cart.</param> /// <param name="userId">Id of the user who should receive the visitor cart</param> /// <param name="delete">Specifies whether the old user cart items should be deleted or not</param> /// <returns>DTO of the merged cart</returns> public AlzaAdminDTO <List <CartItem> > TransformCart(string visitorId, int userId, bool delete) { try { //the old items should be deleted if (delete) { var oldCartItems = _cartItemRepository.GetCartItems().Where(ci => ci.UserId == userId).ToList(); foreach (var item in oldCartItems) { _cartItemRepository.DeleteCartItem(item.VisitorId, item.ProductId); } } //gets the visitor cart var currentCart = _cartItemRepository.GetCartItems().Where(ci => ci.VisitorId == visitorId).ToList(); foreach (var item in currentCart) { CartItem existingItem = null; //if we want to keep the items, the amount might need to be updated for the same product if (!delete) { existingItem = _cartItemRepository.GetCartItems().FirstOrDefault(ci => ci.UserId == userId && ci.ProductId == item.ProductId); } if (existingItem != null) { //adding the amounts existingItem.Amount += item.Amount; _cartItemRepository.UpdateCartItem(existingItem); } else { item.VisitorId = userId.ToString(); item.UserId = userId; _cartItemRepository.AddCartItem(item); } //the old cart needs to be deleted afterwards _cartItemRepository.DeleteCartItem(visitorId, item.ProductId); } //the new cart var result = _cartItemRepository.GetCartItems().Where(ci => ci.UserId == userId).ToList(); return(AlzaAdminDTO <List <CartItem> > .Data(result)); } catch (Exception e) { return(AlzaAdminDTO <List <CartItem> > .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/// <summary> /// Gets a cart by user id /// </summary> /// <param name="userId">Id of the user</param> /// <returns>DTO of cart</returns> public AlzaAdminDTO <List <CartItem> > GetCart(int userId) { try { Expression <Func <CartItem, bool> > selector = ci => ci.UserId == userId; List <CartItem> completeCart = GetCartItems(selector); return(AlzaAdminDTO <List <CartItem> > .Data(completeCart)); } catch (Exception e) { return(AlzaAdminDTO <List <CartItem> > .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/// <summary> /// Gets an order by id /// </summary> /// <param name="orderId">Id of the order</param> /// <returns>DTO of the order</returns> public AlzaAdminDTO <Order> GetOrder(int orderId) { try { var order = _orderRepository.GetOrder(orderId); //Might be slow-ish var products = _productRepository.GetAllProducts().Where(p => order.OrderItems.Select(oi => oi.ProductId).Contains(p.Id)).Select(p => new ProductBO(p, null, null)); order.OrderItems = order.OrderItems.Join(products, oi => oi.ProductId, p => p.Id, (oi, p) => { oi.Product = p; return(oi); }).ToList(); return(AlzaAdminDTO <Order> .Data(order)); } catch (Exception e) { return(AlzaAdminDTO <Order> .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/****************************************/ /* UPDATE USER PROFILE */ /****************************************/ /// <summary> /// Updates a UserProfile /// </summary> /// <param name="profile">Updated User profile</param> /// <returns>Updated profile in DTO.data</returns> public AlzaAdminDTO <UserProfile> UpdateUserProfile(UserProfile profile) { try { if (GetUserProfile(profile.Id).isEmpty) { throw new Exception("Invalid user id."); } var result = _userRepos.UpdateProfile(profile); return(AlzaAdminDTO <UserProfile> .Data(result)); } catch (Exception e) { return(AlzaAdminDTO <UserProfile> .Error(e.Message)); } }
/****************************************/ /* ADD USER PROFILE */ /****************************************/ /// <summary> /// Adds a UserProfile to the database /// </summary> /// <param name="userProfile">UserProfile to be added into the database</param> /// <returns>A DTO object containing the UserProfile in its Data property</returns> public AlzaAdminDTO <UserProfile> AddUserProfile(UserProfile userProfile) { try { if (!GetUserProfile(userProfile.Id).isEmpty) { throw new Exception("User with the same id already exists."); } var result = _userRepos.AddUserProfile(userProfile); return(AlzaAdminDTO <UserProfile> .Data(result)); } catch (Exception e) { return(AlzaAdminDTO <UserProfile> .Error(e.Message)); } }
/// <summary> /// Adds a new order to the database /// </summary> /// <param name="order">Order to be added</param> /// <param name="visitorId">Visitor id of the corresponding cart</param> /// <returns>DTO of the order</returns> public AlzaAdminDTO <Order> AddOrder(Order order, string visitorId) { try { //todo check tolist var cartProductId = _cartItemRepository.GetCartItems().Where(ci => ci.VisitorId == visitorId).Select(ci => ci.ProductId).ToList(); order.StateId = 1; //default orderState is the first one var createdOrder = _orderRepository.AddOrder(order); foreach (var productId in cartProductId) { _cartItemRepository.DeleteCartItem(visitorId, productId); } return(AlzaAdminDTO <Order> .Data(createdOrder)); } catch (Exception e) { return(AlzaAdminDTO <Order> .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/// <summary> /// Gets all orders of a user /// </summary> /// <param name="userId">Id of the user</param> /// <returns>Dto of all user orders</returns> public AlzaAdminDTO <List <Order> > GetUserOrders(int userId) { try { //might be even more slow-ish and should be maybe redone in sql (again) /*Stopwatch watch = new Stopwatch(); * watch.Start();*/ var orders = _orderRepository.GetOrders().Where(o => o.UserId == userId).ToList(); var orderItems = _orderItemRepository.GetOrderItems().Where(oi => orders.Select(o => o.Id).Contains(oi.OrderId)).ToList(); var orderStates = _orderStateRepository.GetOrderStates(); var pids = orderItems.Select(oi => oi.ProductId).ToList(); var products = _productRepository.GetAllProducts().Where(p => pids.Contains(p.Id)).ToList(); var ratings = _productRatingRepository.GetRatings().Where(r => products.Select(p => p.Id).Contains(r.ProductId)); var prodsWithRating = products.Join(ratings, p => p.Id, r => r.ProductId, (p, r) => { return(new ProductBO(p, r, null)); }); var itemsProducts = orderItems.Join(prodsWithRating, oi => oi.ProductId, p => p.Id, (oi, p) => { oi.Product = p; return(oi); }).ToList(); //var orderWithItems = orders.Join(itemsProducts, o => o.Id, ip=> ip.OrderId, (o, ip) => { o.OrderItems.Add(ip); return o; }).ToList(); orders = orders.Join(orderStates, o => o.StateId, os => os.Id, (o, os) => { o.OrderState = os; return(o); }).OrderByDescending(o => o.Date).ToList(); /*watch.Stop(); * Debug.WriteLine($"GetUserOrders lasted {watch.Elapsed}");*/ return(AlzaAdminDTO <List <Order> > .Data(orders)); } catch (Exception e) { return(AlzaAdminDTO <List <Order> > .Error(e.Message + Environment.NewLine + e.StackTrace)); } }
/// <summary> /// Gets a page of product with applied filtering. The filtering occurs on the server side. /// </summary> /// <param name="parameters">Filter parameters</param> /// <returns>Page of products</returns> public AlzaAdminDTO <QueryResultWrapper> GetPage(QueryParametersWrapper parameters) { try { //get all children of the specified category var childCategoriesId = _categoryRelationshipRepository.GetAllRelationships().Where(c => c.Id == parameters.CategoryId).Select(c => c.ChildId); //get all products IQueryable <ProductBase> query = _productRepository.GetAllProducts(); //return only products which belong in these categories query = query.Where(p => childCategoriesId.Contains(p.CategoryId)); decimal minPrice = decimal.MaxValue; decimal maxPrice = 0; QueryResultWrapper result = new QueryResultWrapper(); HashSet <Language> languages = new HashSet <Language>(); HashSet <Publisher> publishers = new HashSet <Publisher>(); HashSet <Format> formats = new HashSet <Format>(); HashSet <Author> authors = new HashSet <Author>(); //specifying filter options correspondingly foreach (ProductBase product in query) { minPrice = product.Price < minPrice ? product.Price : minPrice; maxPrice = product.Price > maxPrice ? product.Price : maxPrice; languages.Add(product.Language); publishers.Add(product.Publisher); formats.Add(product.Format); foreach (Author author in product.Book.AuthorsBooks.Select(ab => ab.Author)) { authors.Add(author); } } result.MinPrice = minPrice; result.MaxPrice = maxPrice; result.Authors = authors.OrderBy(a => a.Surname).ToList(); result.Languages = languages.OrderBy(l => l.Name).ToList(); result.Publishers = publishers.OrderBy(p => p.Name).ToList(); result.Formats = formats.OrderBy(f => f.Name).ToList(); //filtering if (parameters.MinPrice != null) { query = query.Where(p => p.Price >= parameters.MinPrice); } if (parameters.MaxPrice != null) { query = query.Where(p => p.Price <= parameters.MaxPrice); } if (parameters.Languages != null) { query = query.Where(p => parameters.Languages.Contains(p.LanguageId)); } if (parameters.Publishers != null) { query = query.Where(p => parameters.Publishers.Contains(p.PublisherId)); } if (parameters.Formats != null) { query = query.Where(p => parameters.Formats.Contains(p.FormatId)); } if (parameters.Authors != null) { query = query.Where(p => p.Book.AuthorsBooks.Select(ab => ab.Author).Select(a => a.AuthorId).Intersect(parameters.Authors).Count() > 0); } //Add average ratings List <int> pIds = query.Select(p => p.Id).ToList(); IQueryable <ProductRating> ratings = _productRatingRepository.GetRatings().Where(pr => pIds.Contains(pr.ProductId)); var products = query.Join(ratings, q => q.Id, r => r.ProductId, (p, r) => new { product = p, rating = r }).Select(x => new ProductBO(x.product, x.rating, null)); //sort Func <ProductBO, IComparable> sortingParameter; switch (parameters.SortingParameter) { case Enums.SortingParameter.Price: sortingParameter = p => p.Price; break; case Enums.SortingParameter.Rating: sortingParameter = p => p.AverageRating; break; case Enums.SortingParameter.Date: sortingParameter = p => p.DateAdded; break; case Enums.SortingParameter.Name: sortingParameter = p => p.Name; break; default: sortingParameter = p => p.AverageRating; break; } switch (parameters.SortingType) { case Enums.SortType.Asc: products = products.OrderBy(sortingParameter).AsQueryable(); break; case Enums.SortType.Desc: products = products.OrderByDescending(sortingParameter).AsQueryable(); break; default: break; } //return a "page" result.ResultCount = products.Count(); products = products.Skip((parameters.PageNum - 1) * parameters.PageSize).Take(parameters.PageSize); result.Products = products.ToList(); return(AlzaAdminDTO <QueryResultWrapper> .Data(result)); } catch (Exception e) { return(AlzaAdminDTO <QueryResultWrapper> .Error(e.Message + Environment.NewLine + e.StackTrace)); } }