using Nop.Core; using Nop.Core.Caching; using Nop.Core.Domain.Catalog; using Nop.Core.Domain.Customers; using Nop.Core.Domain.Discounts; using Nop.Data; using Nop.Services.Customers; using Nop.Services.Discounts; using Nop.Services.Security; using Nop.Services.Stores; namespace Nop.Services.Catalog; /// /// Manufacturer service /// public partial class ManufacturerService : IManufacturerService { #region Fields protected readonly CatalogSettings _catalogSettings; protected readonly IAclService _aclService; protected readonly ICategoryService _categoryService; protected readonly ICustomerService _customerService; protected readonly IRepository _discountManufacturerMappingRepository; protected readonly IRepository _manufacturerRepository; protected readonly IRepository _productRepository; protected readonly IRepository _productManufacturerRepository; protected readonly IRepository _productCategoryRepository; protected readonly IStaticCacheManager _staticCacheManager; protected readonly IStoreContext _storeContext; protected readonly IStoreMappingService _storeMappingService; protected readonly IWorkContext _workContext; #endregion #region Ctor public ManufacturerService(CatalogSettings catalogSettings, IAclService aclService, ICategoryService categoryService, ICustomerService customerService, IRepository discountManufacturerMappingRepository, IRepository manufacturerRepository, IRepository productRepository, IRepository productManufacturerRepository, IRepository productCategoryRepository, IStaticCacheManager staticCacheManager, IStoreContext storeContext, IStoreMappingService storeMappingService, IWorkContext workContext) { _catalogSettings = catalogSettings; _aclService = aclService; _categoryService = categoryService; _customerService = customerService; _discountManufacturerMappingRepository = discountManufacturerMappingRepository; _manufacturerRepository = manufacturerRepository; _productRepository = productRepository; _productManufacturerRepository = productManufacturerRepository; _productCategoryRepository = productCategoryRepository; _staticCacheManager = staticCacheManager; _storeContext = storeContext; _storeMappingService = storeMappingService; _workContext = workContext; } #endregion #region Methods /// /// Clean up manufacturer references for a specified discount /// /// Discount /// A task that represents the asynchronous operation public virtual async Task ClearDiscountManufacturerMappingAsync(Discount discount) { ArgumentNullException.ThrowIfNull(discount); var mappings = _discountManufacturerMappingRepository.Table.Where(dcm => dcm.DiscountId == discount.Id); await _discountManufacturerMappingRepository.DeleteAsync(await mappings.ToListAsync()); } /// /// Deletes a manufacturer /// /// Manufacturer /// A task that represents the asynchronous operation public virtual async Task DeleteManufacturerAsync(Manufacturer manufacturer) { await _manufacturerRepository.DeleteAsync(manufacturer); } /// /// Delete manufacturers /// /// Manufacturers /// A task that represents the asynchronous operation public virtual async Task DeleteManufacturersAsync(IList manufacturers) { await _manufacturerRepository.DeleteAsync(manufacturers); } /// /// Gets all manufacturers /// /// Manufacturer name /// Store identifier; 0 if you want to get all records /// Page index /// Page size /// A value indicating whether to show hidden records /// /// null - process "Published" property according to "showHidden" parameter /// true - load only "Published" products /// false - load only "Unpublished" products /// /// /// A task that represents the asynchronous operation /// The task result contains the manufacturers /// public virtual async Task> GetAllManufacturersAsync(string manufacturerName = "", int storeId = 0, int pageIndex = 0, int pageSize = int.MaxValue, bool showHidden = false, bool? overridePublished = null) { return await _manufacturerRepository.GetAllPagedAsync(async query => { if (!showHidden) query = query.Where(m => m.Published); else if (overridePublished.HasValue) query = query.Where(m => m.Published == overridePublished.Value); if (!showHidden || storeId > 0) { //apply store mapping constraints query = await _storeMappingService.ApplyStoreMapping(query, storeId); } if (!showHidden) { //apply ACL constraints var customer = await _workContext.GetCurrentCustomerAsync(); query = await _aclService.ApplyAcl(query, customer); } query = query.Where(m => !m.Deleted); if (!string.IsNullOrWhiteSpace(manufacturerName)) query = query.Where(m => m.Name.Contains(manufacturerName)); return query.OrderBy(m => m.DisplayOrder).ThenBy(m => m.Id); }, pageIndex, pageSize); } /// /// Get manufacturer identifiers to which a discount is applied /// /// Discount /// Customer /// /// A task that represents the asynchronous operation /// The task result contains the manufacturer identifiers /// public virtual async Task> GetAppliedManufacturerIdsAsync(Discount discount, Customer customer) { ArgumentNullException.ThrowIfNull(discount); var cacheKey = _staticCacheManager.PrepareKeyForDefaultCache(NopDiscountDefaults.ManufacturerIdsByDiscountCacheKey, discount, await _customerService.GetCustomerRoleIdsAsync(customer), await _storeContext.GetCurrentStoreAsync()); var query = _discountManufacturerMappingRepository.Table.Where(dmm => dmm.DiscountId == discount.Id) .Select(dmm => dmm.EntityId); var result = await _staticCacheManager.GetAsync(cacheKey, async () => await query.ToListAsync()); return result; } /// /// Gets a manufacturer /// /// Manufacturer identifier /// /// A task that represents the asynchronous operation /// The task result contains the manufacturer /// public virtual async Task GetManufacturerByIdAsync(int manufacturerId) { return await _manufacturerRepository.GetByIdAsync(manufacturerId, cache => default); } /// /// Get manufacturers for which a discount is applied /// /// Discount identifier; pass null to load all records /// A value indicating whether to load deleted manufacturers /// Page index /// Page size /// /// A task that represents the asynchronous operation /// The task result contains the list of manufacturers /// public virtual async Task> GetManufacturersWithAppliedDiscountAsync(int? discountId = null, bool showHidden = false, int pageIndex = 0, int pageSize = int.MaxValue) { var manufacturers = _manufacturerRepository.Table; if (discountId.HasValue) manufacturers = from manufacturer in manufacturers join dmm in _discountManufacturerMappingRepository.Table on manufacturer.Id equals dmm.EntityId where dmm.DiscountId == discountId.Value select manufacturer; if (!showHidden) manufacturers = manufacturers.Where(manufacturer => !manufacturer.Deleted); manufacturers = manufacturers.OrderBy(manufacturer => manufacturer.DisplayOrder).ThenBy(manufacturer => manufacturer.Id); return await manufacturers.ToPagedListAsync(pageIndex, pageSize); } /// /// Gets the manufacturers by category identifier /// /// Category identifier /// /// A task that represents the asynchronous operation /// The task result contains the manufacturers /// public virtual async Task> GetManufacturersByCategoryIdAsync(int categoryId) { if (categoryId <= 0) return new List(); // get available products in category var productsQuery = from p in _productRepository.Table where !p.Deleted && p.Published && (p.ParentGroupedProductId == 0 || p.VisibleIndividually) && (!p.AvailableStartDateTimeUtc.HasValue || p.AvailableStartDateTimeUtc <= DateTime.UtcNow) && (!p.AvailableEndDateTimeUtc.HasValue || p.AvailableEndDateTimeUtc >= DateTime.UtcNow) select p; var store = await _storeContext.GetCurrentStoreAsync(); var customer = await _workContext.GetCurrentCustomerAsync(); var customerRoleIds = await _customerService.GetCustomerRoleIdsAsync(customer); //apply store mapping constraints productsQuery = await _storeMappingService.ApplyStoreMapping(productsQuery, store.Id); //apply ACL constraints productsQuery = await _aclService.ApplyAcl(productsQuery, customerRoleIds); var subCategoryIds = _catalogSettings.ShowProductsFromSubcategories ? await _categoryService.GetChildCategoryIdsAsync(categoryId, store.Id) : null; var productCategoryQuery = from pc in _productCategoryRepository.Table where (pc.CategoryId == categoryId || (_catalogSettings.ShowProductsFromSubcategories && subCategoryIds.Contains(pc.CategoryId))) && (_catalogSettings.IncludeFeaturedProductsInNormalLists || !pc.IsFeaturedProduct) select pc; var manufacturerQuery = from m in _manufacturerRepository.Table where !m.Deleted && m.Published select m; //apply store mapping constraints manufacturerQuery = await _storeMappingService.ApplyStoreMapping(manufacturerQuery, store.Id); //apply ACL constraints manufacturerQuery = await _aclService.ApplyAcl(manufacturerQuery, customerRoleIds); // get manufacturers of the products var manufacturersQuery = from m in manufacturerQuery join pm in _productManufacturerRepository.Table on m.Id equals pm.ManufacturerId join p in productsQuery on pm.ProductId equals p.Id join pc in productCategoryQuery on p.Id equals pc.ProductId orderby m.DisplayOrder, m.Name select m; var key = _staticCacheManager .PrepareKeyForDefaultCache(NopCatalogDefaults.ManufacturersByCategoryCacheKey, categoryId, store, customerRoleIds); return await _staticCacheManager.GetAsync(key, async () => await manufacturersQuery.Distinct().ToListAsync()); } /// /// Gets manufacturers by identifier /// /// manufacturer identifiers /// /// A task that represents the asynchronous operation /// The task result contains the manufacturers /// public virtual async Task> GetManufacturersByIdsAsync(int[] manufacturerIds) { return await _manufacturerRepository.GetByIdsAsync(manufacturerIds, includeDeleted: false); } /// /// Inserts a manufacturer /// /// Manufacturer /// A task that represents the asynchronous operation public virtual async Task InsertManufacturerAsync(Manufacturer manufacturer) { await _manufacturerRepository.InsertAsync(manufacturer); } /// /// Updates the manufacturer /// /// Manufacturer /// A task that represents the asynchronous operation public virtual async Task UpdateManufacturerAsync(Manufacturer manufacturer) { await _manufacturerRepository.UpdateAsync(manufacturer); } /// /// Deletes a product manufacturer mapping /// /// Product manufacturer mapping /// A task that represents the asynchronous operation public virtual async Task DeleteProductManufacturerAsync(ProductManufacturer productManufacturer) { await _productManufacturerRepository.DeleteAsync(productManufacturer); } /// /// Gets product manufacturer collection /// /// Manufacturer identifier /// Page index /// Page size /// A value indicating whether to show hidden records /// /// A task that represents the asynchronous operation /// The task result contains the product manufacturer collection /// public virtual async Task> GetProductManufacturersByManufacturerIdAsync(int manufacturerId, int pageIndex = 0, int pageSize = int.MaxValue, bool showHidden = false) { if (manufacturerId == 0) return new PagedList(new List(), pageIndex, pageSize); var query = from pm in _productManufacturerRepository.Table join p in _productRepository.Table on pm.ProductId equals p.Id where pm.ManufacturerId == manufacturerId && !p.Deleted orderby pm.DisplayOrder, pm.Id select pm; if (!showHidden) { var manufacturersQuery = _manufacturerRepository.Table.Where(m => m.Published); //apply store mapping constraints var store = await _storeContext.GetCurrentStoreAsync(); manufacturersQuery = await _storeMappingService.ApplyStoreMapping(manufacturersQuery, store.Id); //apply ACL constraints var customer = await _workContext.GetCurrentCustomerAsync(); manufacturersQuery = await _aclService.ApplyAcl(manufacturersQuery, customer); query = query.Where(pm => manufacturersQuery.Any(m => m.Id == pm.ManufacturerId)); } return await query.ToPagedListAsync(pageIndex, pageSize); } /// /// Gets a product manufacturer mapping collection /// /// Product identifier /// A value indicating whether to show hidden records /// /// A task that represents the asynchronous operation /// The task result contains the product manufacturer mapping collection /// public virtual async Task> GetProductManufacturersByProductIdAsync(int productId, bool showHidden = false) { if (productId == 0) return new List(); var store = await _storeContext.GetCurrentStoreAsync(); var customer = await _workContext.GetCurrentCustomerAsync(); var customerRoleIds = await _customerService.GetCustomerRoleIdsAsync(customer); var key = _staticCacheManager .PrepareKeyForDefaultCache(NopCatalogDefaults.ProductManufacturersByProductCacheKey, productId, showHidden, customerRoleIds, store); var query = from pm in _productManufacturerRepository.Table join m in _manufacturerRepository.Table on pm.ManufacturerId equals m.Id where pm.ProductId == productId && !m.Deleted orderby pm.DisplayOrder, pm.Id select pm; if (!showHidden) { var manufacturersQuery = _manufacturerRepository.Table.Where(m => m.Published); //apply store mapping constraints manufacturersQuery = await _storeMappingService.ApplyStoreMapping(manufacturersQuery, store.Id); //apply ACL constraints manufacturersQuery = await _aclService.ApplyAcl(manufacturersQuery, customerRoleIds); query = query.Where(pm => manufacturersQuery.Any(m => m.Id == pm.ManufacturerId)); } return await _staticCacheManager.GetAsync(key, query.ToList); } /// /// Gets a product manufacturer mapping /// /// Product manufacturer mapping identifier /// /// A task that represents the asynchronous operation /// The task result contains the product manufacturer mapping /// public virtual async Task GetProductManufacturerByIdAsync(int productManufacturerId) { return await _productManufacturerRepository.GetByIdAsync(productManufacturerId, cache => default); } /// /// Inserts a product manufacturer mapping /// /// Product manufacturer mapping /// A task that represents the asynchronous operation public virtual async Task InsertProductManufacturerAsync(ProductManufacturer productManufacturer) { await _productManufacturerRepository.InsertAsync(productManufacturer); } /// /// Updates the product manufacturer mapping /// /// Product manufacturer mapping /// A task that represents the asynchronous operation public virtual async Task UpdateProductManufacturerAsync(ProductManufacturer productManufacturer) { await _productManufacturerRepository.UpdateAsync(productManufacturer); } /// /// Get manufacturer IDs for products /// /// Products IDs /// /// A task that represents the asynchronous operation /// The task result contains the manufacturer IDs for products /// public virtual async Task> GetProductManufacturerIdsAsync(int[] productIds) { var query = _productManufacturerRepository.Table; return (await query.Where(p => productIds.Contains(p.ProductId)) .Select(p => new { p.ProductId, p.ManufacturerId }) .ToListAsync()) .GroupBy(a => a.ProductId) .ToDictionary(items => items.Key, items => items.Select(a => a.ManufacturerId).ToArray()); } /// /// Returns a list of names of not existing manufacturers /// /// The names and/or IDs of the manufacturers to check /// /// A task that represents the asynchronous operation /// The task result contains the list of names and/or IDs not existing manufacturers /// public virtual async Task GetNotExistingManufacturersAsync(string[] manufacturerIdsNames) { ArgumentNullException.ThrowIfNull(manufacturerIdsNames); var query = _manufacturerRepository.Table;//.Where(m => !m.Deleted); var queryFilter = manufacturerIdsNames.Distinct().ToArray(); //filtering by name var filter = await query.Select(m => m.Name).Where(m => queryFilter.Contains(m)).ToListAsync(); queryFilter = queryFilter.Except(filter).ToArray(); //if some names not found if (!queryFilter.Any()) return queryFilter.ToArray(); //filtering by IDs filter = await query.Select(c => c.Id.ToString()) .Where(c => queryFilter.Contains(c)) .ToListAsync(); return queryFilter.Except(filter).ToArray(); } /// /// Returns a ProductManufacturer that has the specified values /// /// Source /// Product identifier /// Manufacturer identifier /// A ProductManufacturer that has the specified values; otherwise null public virtual ProductManufacturer FindProductManufacturer(IList source, int productId, int manufacturerId) { foreach (var productManufacturer in source) if (productManufacturer.ProductId == productId && productManufacturer.ManufacturerId == manufacturerId) return productManufacturer; return null; } /// /// Get a discount-manufacturer mapping record /// /// Manufacturer identifier /// Discount identifier /// /// A task that represents the asynchronous operation /// The task result contains the result /// public async Task GetDiscountAppliedToManufacturerAsync(int manufacturerId, int discountId) { return await _discountManufacturerMappingRepository.Table .FirstOrDefaultAsync(dcm => dcm.EntityId == manufacturerId && dcm.DiscountId == discountId); } /// /// Inserts a discount-manufacturer mapping record /// /// Discount-manufacturer mapping /// A task that represents the asynchronous operation public async Task InsertDiscountManufacturerMappingAsync(DiscountManufacturerMapping discountManufacturerMapping) { await _discountManufacturerMappingRepository.InsertAsync(discountManufacturerMapping); } /// /// Deletes a discount-manufacturer mapping record /// /// Discount-manufacturer mapping /// A task that represents the asynchronous operation public async Task DeleteDiscountManufacturerMappingAsync(DiscountManufacturerMapping discountManufacturerMapping) { await _discountManufacturerMappingRepository.DeleteAsync(discountManufacturerMapping); } #endregion }