Something to put in this function i believe:
public virtual async Task<IPagedList<Product>> SearchProductsAsync(
int pageIndex = 0,
int pageSize = int.MaxValue,
IList<int> categoryIds = null,
IList<int> manufacturerIds = null,
int storeId = 0,
int vendorId = 0,
int warehouseId = 0,
ProductType? productType = null,
bool visibleIndividuallyOnly = false,
bool excludeFeaturedProducts = false,
decimal? priceMin = null,
decimal? priceMax = null,
int productTagId = 0,
string keywords = null,
bool searchDescriptions = false,
bool searchManufacturerPartNumber = true,
bool searchSku = true,
bool searchProductTags = false,
int languageId = 0,
IList<SpecificationAttributeOption> filteredSpecOptions = null,
ProductSortingEnum orderBy = ProductSortingEnum.Position,
bool showHidden = false,
bool? overridePublished = null)
{
//some databases don't support int.MaxValue
if (pageSize == int.MaxValue)
pageSize = int.MaxValue - 1;
string ktype = _webHelper.QueryString<string>("ktype");
string nodeID = _webHelper.QueryString<string>("nodeid");
List<string> partnumbers = new List<string>();
if (ktype != null && nodeID != null)
{
partnumbers = await loadPartsForCar_Cat(ktype, nodeID);
}
var productsQuery = _productRepository.Table;
if (!showHidden)
productsQuery = productsQuery.Where(p => p.Published);
else if (overridePublished.HasValue)
productsQuery = productsQuery.Where(p => p.Published == overridePublished.Value);
//apply store mapping constraints
productsQuery = await _storeMappingService.ApplyStoreMapping(productsQuery, storeId);
//**********************************************************************************************
// Something like below
if (partnumbers.Count > 0)
{
productsQuery = productsQuery.Where(p => p.ManufacturerPartNumber.Contains(partnumbers.Any()));
}
//***********************************************
//apply ACL constraints
if (!showHidden)
{
var customer = await _workContext.GetCurrentCustomerAsync();
productsQuery = await _aclService.ApplyAcl(productsQuery, customer);
}
productsQuery =
from p in productsQuery
where !p.Deleted &&
(!visibleIndividuallyOnly || p.VisibleIndividually) &&
(vendorId == 0 || p.VendorId == vendorId) &&
(
warehouseId == 0 ||
(
!p.UseMultipleWarehouses ? p.WarehouseId == warehouseId :
_productWarehouseInventoryRepository.Table.Any(pwi => pwi.WarehouseId == warehouseId && pwi.ProductId == p.Id)
)
) &&
(productType == null || p.ProductTypeId == (int)productType) &&
(showHidden ||
DateTime.UtcNow >= (p.AvailableStartDateTimeUtc ?? DateTime.MinValue) &&
DateTime.UtcNow <= (p.AvailableEndDateTimeUtc ?? DateTime.MaxValue)
) &&
(priceMin == null || p.Price >= priceMin) &&
(priceMax == null || p.Price <= priceMax)
select p;
if (!string.IsNullOrEmpty(keywords))
{
var langs = await _languageService.GetAllLanguagesAsync(showHidden: true);
//Set a flag which will to points need to search in localized properties. If showHidden doesn't set to true should be at least two published languages.
var searchLocalizedValue = languageId > 0 && langs.Count >= 2 && (showHidden || langs.Count(l => l.Published) >= 2);
IQueryable<int> productsByKeywords;
productsByKeywords =
from p in _productRepository.Table
where p.Name.Contains(keywords) ||
(searchDescriptions &&
(p.ShortDescription.Contains(keywords) || p.FullDescription.Contains(keywords))) ||
(searchManufacturerPartNumber && p.ManufacturerPartNumber == keywords) ||
(searchSku && p.Sku == keywords)
select p.Id;
if (searchLocalizedValue)
{
productsByKeywords = productsByKeywords.Union(
from lp in _localizedPropertyRepository.Table
let checkName = lp.LocaleKey == nameof(Product.Name) &&
lp.LocaleValue.Contains(keywords)
let checkShortDesc = searchDescriptions &&
lp.LocaleKey == nameof(Product.ShortDescription) &&
lp.LocaleValue.Contains(keywords)
where
lp.LocaleKeyGroup == nameof(Product) && lp.LanguageId == languageId && (checkName || checkShortDesc)
select lp.EntityId);
}
//search by SKU for ProductAttributeCombination
if (searchSku)
{
productsByKeywords = productsByKeywords.Union(
from pac in _productAttributeCombinationRepository.Table
where pac.Sku == keywords
select pac.ProductId);
}
if (searchProductTags)
{
productsByKeywords = productsByKeywords.Union(
from pptm in _productTagMappingRepository.Table
join pt in _productTagRepository.Table on pptm.ProductTagId equals pt.Id
where pt.Name.Contains(keywords)
select pptm.ProductId
);
if (searchLocalizedValue)
{
productsByKeywords = productsByKeywords.Union(
from pptm in _productTagMappingRepository.Table
join lp in _localizedPropertyRepository.Table on pptm.ProductTagId equals lp.EntityId
where lp.LocaleKeyGroup == nameof(ProductTag) &&
lp.LocaleKey == nameof(ProductTag.Name) &&
lp.LocaleValue.Contains(keywords) &&
lp.LanguageId == languageId
select pptm.ProductId);
}
}
productsQuery =
from p in productsQuery
join pbk in productsByKeywords on p.Id equals pbk
select p;
}
if (categoryIds is not null)
{
if (categoryIds.Contains(0))
categoryIds.Remove(0);
if (categoryIds.Any())
{
var productCategoryQuery =
from pc in _productCategoryRepository.Table
where (!excludeFeaturedProducts || !pc.IsFeaturedProduct) &&
categoryIds.Contains(pc.CategoryId)
group pc by pc.ProductId into pc
select new {
ProductId = pc.Key,
DisplayOrder = pc.First().DisplayOrder
};
productsQuery =
from p in productsQuery
join pc in productCategoryQuery on p.Id equals pc.ProductId
orderby pc.DisplayOrder, p.Name
select p;
}
}
if (manufacturerIds is not null)
{
if (manufacturerIds.Contains(0))
manufacturerIds.Remove(0);
if (manufacturerIds.Any())
{
var productManufacturerQuery =
from pm in _productManufacturerRepository.Table
where (!excludeFeaturedProducts || !pm.IsFeaturedProduct) &&
manufacturerIds.Contains(pm.ManufacturerId)
group pm by pm.ProductId into pm
select new {
ProductId = pm.Key,
DisplayOrder = pm.First().DisplayOrder
};
productsQuery =
from p in productsQuery
join pm in productManufacturerQuery on p.Id equals pm.ProductId
orderby pm.DisplayOrder, p.Name
select p;
}
}
if (productTagId > 0)
{
productsQuery =
from p in productsQuery
join ptm in _productTagMappingRepository.Table on p.Id equals ptm.ProductId
where ptm.ProductTagId == productTagId
select p;
}
if (filteredSpecOptions?.Count > 0)
{
var specificationAttributeIds = filteredSpecOptions
.Select(sao => sao.SpecificationAttributeId)
.Distinct();
foreach (var specificationAttributeId in specificationAttributeIds)
{
var optionIdsBySpecificationAttribute = filteredSpecOptions
.Where(o => o.SpecificationAttributeId == specificationAttributeId)
.Select(o => o.Id);
var productSpecificationQuery =
from psa in _productSpecificationAttributeRepository.Table
where psa.AllowFiltering && optionIdsBySpecificationAttribute.Contains(psa.SpecificationAttributeOptionId)
select psa;
productsQuery =
from p in productsQuery
where productSpecificationQuery.Any(pc => pc.ProductId == p.Id)
select p;
}
}
return await productsQuery.OrderBy(_localizedPropertyRepository, await _workContext.GetWorkingLanguageAsync(), orderBy).ToPagedListAsync(pageIndex, pageSize);
}
Just need the write piece of code / place where it works in all conditions.