Filtering Issue Fixed

This commit is contained in:
Devansh 2021-12-01 12:42:18 +05:30
parent cf188cb5b9
commit 683ef6329a
1 changed files with 138 additions and 124 deletions

View File

@ -3,26 +3,26 @@
namespace Webkul\Product\Repositories;
use Exception;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
use Webkul\Checkout\Facades\Cart;
use Webkul\Product\Models\Product;
use Illuminate\Pagination\Paginator;
use Webkul\Core\Eloquent\Repository;
use Illuminate\Support\Facades\Event;
use Webkul\Attribute\Models\Attribute;
use Webkul\Product\Models\ProductFlat;
use Illuminate\Support\Facades\Storage;
use Illuminate\Container\Container as App;
use Illuminate\Pagination\LengthAwarePaginator;
use Webkul\Product\Models\ProductAttributeValueProxy;
use Webkul\Attribute\Repositories\AttributeRepository;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Webkul\Attribute\Models\Attribute;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Checkout\Facades\Cart;
use Webkul\Core\Eloquent\Repository;
use Webkul\Product\Models\Product;
use Webkul\Product\Models\ProductAttributeValueProxy;
use Webkul\Product\Models\ProductFlat;
class ProductRepository extends Repository
{
/**
* AttributeRepository object
* Attribute repository instance,
*
* @var \Webkul\Attribute\Repositories\AttributeRepository
*/
@ -39,26 +39,26 @@ class ProductRepository extends Repository
public function __construct(
AttributeRepository $attributeRepository,
App $app
)
{
) {
$this->attributeRepository = $attributeRepository;
parent::__construct($app);
}
/**
* Specify Model class name
* Specify model class name.
*
* @return string
*/
function model()
public function model()
{
return 'Webkul\Product\Contracts\Product';
return \Webkul\Product\Contracts\Product::class;
}
/**
* @param array $data
* Create product.
*
* @param array $data
* @return \Webkul\Product\Contracts\Product
*/
public function create(array $data)
@ -75,13 +75,14 @@ class ProductRepository extends Repository
}
/**
* @param array $data
* @param int $id
* @param string $attribute
* Update product.
*
* @param array $data
* @param int $id
* @param string $attribute
* @return \Webkul\Product\Contracts\Product
*/
public function update(array $data, $id, $attribute = "id")
public function update(array $data, $id, $attribute = 'id')
{
Event::dispatch('catalog.product.update.before', $id);
@ -99,8 +100,9 @@ class ProductRepository extends Repository
}
/**
* @param int $id
* Delete product.
*
* @param int $id
* @return void
*/
public function delete($id)
@ -112,15 +114,15 @@ class ProductRepository extends Repository
Event::dispatch('catalog.product.delete.after', $id);
}
/**
* @param int $categoryId
/**
* Get product related to category.
*
* @param int $categoryId
* @return \Illuminate\Support\Collection
*/
public function getProductsRelatedToCategory($categoryId = null)
{
$qb = $this->model
->leftJoin('product_categories', 'products.id', '=', 'product_categories.product_id');
$qb = $this->model->leftJoin('product_categories', 'products.id', '=', 'product_categories.product_id');
if ($categoryId) {
$qb->where('product_categories.category_id', $categoryId);
@ -130,8 +132,41 @@ class ProductRepository extends Repository
}
/**
* @param string $categoryId
* Check out of stock items. This method needed `variants` alias in
* the `product_flat` query.
*
* @param Webkul\Product\Models\ProductFlat $query
* @return Illuminate\Database\Eloquent\Builder
*/
public function checkOutOfStockItem($query)
{
return $query
->leftJoin('products as ps', 'product_flat.product_id', '=', 'ps.id')
->leftJoin('product_inventories as pv', 'product_flat.product_id', '=', 'pv.product_id')
->where(function ($qb) {
return $qb
/* for grouped, downloadable, bundle and booking product */
->orWhereIn('ps.type', ['grouped', 'downloadable', 'bundle', 'booking'])
/* for simple and virtual product */
->orWhere(function ($qb) {
return $qb->whereIn('ps.type', ['simple', 'virtual'])->where('pv.qty', '>', 0);
})
/* for configurable product */
->orWhere(function ($qb) {
return $qb->where('ps.type', 'configurable')->where(function ($qb) {
return $qb
->selectRaw('SUM(' . DB::getTablePrefix() . 'product_inventories.qty)')
->from('product_flat')
->leftJoin('product_inventories', 'product_inventories.product_id', '=', 'product_flat.product_id');
}, '>', 0);
});
});
}
/**
* Get all products.
*
* @param string $categoryId
* @return \Illuminate\Support\Collection
*/
public function getAll($categoryId = null)
@ -155,9 +190,8 @@ class ProductRepository extends Repository
$qb = $query->distinct()
->select('product_flat.*')
->join('product_flat as variants', 'product_flat.id', '=', DB::raw('COALESCE(' . DB::getTablePrefix() . 'variants.parent_id, ' . DB::getTablePrefix() . 'variants.id)'))
->leftJoin('product_categories', 'product_categories.product_id', '=', 'product_flat.product_id')
->leftJoin('product_attribute_values', 'product_attribute_values.product_id', '=', 'variants.product_id')
->leftJoin('product_attribute_values', 'product_attribute_values.product_id', '=', 'product_flat.product_id')
->where('product_flat.channel', $channel)
->where('product_flat.locale', $locale)
->whereNotNull('product_flat.url_key');
@ -182,12 +216,10 @@ class ProductRepository extends Repository
$qb->where('product_flat.name', 'like', '%' . urldecode($params['search']) . '%');
}
/* added for api as per the documentation */
if (isset($params['name'])) {
$qb->where('product_flat.name', 'like', '%' . urldecode($params['name']) . '%');
}
/* added for api as per the documentation */
if (isset($params['url_key'])) {
$qb->where('product_flat.url_key', 'like', '%' . urldecode($params['url_key']) . '%');
}
@ -227,25 +259,25 @@ class ProductRepository extends Repository
}
$qb
->leftJoin('catalog_rule_product_prices', 'catalog_rule_product_prices.product_id', '=', 'variants.product_id')
->leftJoin('product_customer_group_prices', 'product_customer_group_prices.product_id', '=', 'variants.product_id')
->leftJoin('catalog_rule_product_prices', 'catalog_rule_product_prices.product_id', '=', 'product_flat.product_id')
->leftJoin('product_customer_group_prices', 'product_customer_group_prices.product_id', '=', 'product_flat.product_id')
->where(function ($qb) use ($priceRange, $customerGroupId) {
$qb->where(function ($qb) use ($priceRange){
$qb->where(function ($qb) use ($priceRange) {
$qb
->where('variants.min_price', '>=', core()->convertToBasePrice($priceRange[0]))
->where('variants.min_price', '<=', core()->convertToBasePrice(end($priceRange)));
->where('product_flat.min_price', '>=', core()->convertToBasePrice($priceRange[0]))
->where('product_flat.min_price', '<=', core()->convertToBasePrice(end($priceRange)));
})
->orWhere(function ($qb) use ($priceRange) {
$qb
->where('catalog_rule_product_prices.price', '>=', core()->convertToBasePrice($priceRange[0]))
->where('catalog_rule_product_prices.price', '<=', core()->convertToBasePrice(end($priceRange)));
})
->orWhere(function ($qb) use ($priceRange, $customerGroupId) {
$qb
->where('product_customer_group_prices.value', '>=', core()->convertToBasePrice($priceRange[0]))
->where('product_customer_group_prices.value', '<=', core()->convertToBasePrice(end($priceRange)))
->where('product_customer_group_prices.customer_group_id', '=', $customerGroupId);
});
->orWhere(function ($qb) use ($priceRange) {
$qb
->where('catalog_rule_product_prices.price', '>=', core()->convertToBasePrice($priceRange[0]))
->where('catalog_rule_product_prices.price', '<=', core()->convertToBasePrice(end($priceRange)));
})
->orWhere(function ($qb) use ($priceRange, $customerGroupId) {
$qb
->where('product_customer_group_prices.value', '>=', core()->convertToBasePrice($priceRange[0]))
->where('product_customer_group_prices.value', '<=', core()->convertToBasePrice(end($priceRange)))
->where('product_customer_group_prices.customer_group_id', '=', $customerGroupId);
});
});
}
}
@ -291,7 +323,7 @@ class ProductRepository extends Repository
# this is key! if a product has been filtered down to the same number of attributes that we filtered on,
# we know that it has matched all of the requested filters.
$qb->groupBy('variants.id');
$qb->groupBy('product_flat.id');
$qb->havingRaw('COUNT(*) = ' . count($attributeFilters));
}
@ -325,11 +357,10 @@ class ProductRepository extends Repository
}
/**
* Retrive product from slug
*
* @param string $slug
* @param string $columns
* Retrive product from slug.
*
* @param string $slug
* @param string $columns
* @return \Webkul\Product\Contracts\Product
*/
public function findBySlugOrFail($slug, $columns = null)
@ -350,10 +381,9 @@ class ProductRepository extends Repository
}
/**
* Retrieve product from slug without throwing an exception (might return null)
*
* @param string $slug
* Retrieve product from slug without throwing an exception.
*
* @param string $slug
* @return \Webkul\Product\Contracts\ProductFlat
*/
public function findBySlug($slug)
@ -366,7 +396,7 @@ class ProductRepository extends Repository
}
/**
* Returns newly added product
* Returns newly added product.
*
* @return \Illuminate\Support\Collection
*/
@ -393,7 +423,7 @@ class ProductRepository extends Repository
}
/**
* Returns featured product
* Returns featured product.
*
* @return \Illuminate\Support\Collection
*/
@ -420,10 +450,9 @@ class ProductRepository extends Repository
}
/**
* Search Product by Attribute
*
* @param string $term
* Search product by attribute.
*
* @param string $term
* @return \Illuminate\Support\Collection
*/
public function searchProductByAttribute($term)
@ -440,8 +469,8 @@ class ProductRepository extends Repository
$searchDriver->setSettings([
'attributesForFaceting' => [
"searchable(locale)",
"searchable(channel)",
'searchable(locale)',
'searchable(channel)',
],
]);
@ -468,7 +497,6 @@ class ProductRepository extends Repository
$query = $query->distinct()
->addSelect('product_flat.*')
->join('product_flat as variants', 'product_flat.id', '=', DB::raw('COALESCE(' . DB::getTablePrefix() . 'variants.parent_id, ' . DB::getTablePrefix() . 'variants.id)'))
->where('product_flat.channel', $channel)
->where('product_flat.locale', $locale)
->whereNotNull('product_flat.url_key');
@ -495,10 +523,9 @@ class ProductRepository extends Repository
}
/**
* Returns product's super attribute with options
*
* @param \Webkul\Product\Contracts\Product $product
* Returns product's super attribute with options.
*
* @param \Webkul\Product\Contracts\Product $product
* @return \Illuminate\Support\Collection
*/
public function getSuperAttributes($product)
@ -522,10 +549,9 @@ class ProductRepository extends Repository
}
/**
* Search simple products for grouped product association
*
* @param string $term
* Search simple products for grouped product association.
*
* @param string $term
* @return \Illuminate\Support\Collection
*/
public function searchSimpleProducts($term)
@ -552,7 +578,7 @@ class ProductRepository extends Repository
*
* Always make the copy is inactive so the admin is able to configure it before setting it live.
*
* @param int $sourceProductId the id of the product that should be copied
* @param int $sourceProductId (The id of the product that should be copied.)
*/
public function copy(Product $originalProduct): Product
{
@ -584,7 +610,7 @@ class ProductRepository extends Repository
}
/**
* Get default sort by option
* Get default sort by option.
*
* @return array
*/
@ -598,12 +624,11 @@ class ProductRepository extends Repository
}
/**
* Check sort attribute and generate query
*
* @param object $query
* @param string $sort
* @param string $direction
* Check sort attribute and generate query.
*
* @param object $query
* @param string $sort
* @param string $direction
* @return object
*/
private function checkSortAttributeAndGenerateQuery($query, $sort, $direction)
@ -624,6 +649,12 @@ class ProductRepository extends Repository
return $query;
}
/**
* Fill original product.
*
* @param \Webkul\Product\Models\Product $sourceProduct
* @return void
*/
private function fillOriginalProduct(Product &$sourceProduct): void
{
$sourceProduct
@ -635,16 +666,17 @@ class ProductRepository extends Repository
}
/**
* @param $originalProduct
* Persist copied product.
*
* @return mixed
* @param $originalProduct
* @return \Webkul\Product\Models\Product
*/
private function persistCopiedProduct($originalProduct): Product
{
$copiedProduct = $originalProduct
->replicate()
->fill([
// the sku and url_key needs to be unique and should be entered again newly by the admin:
// the sku and url_key needs to be unique and should be entered again newly by the admin
'sku' => 'temporary-sku-' . substr(md5(microtime()), 0, 6),
]);
@ -653,10 +685,12 @@ class ProductRepository extends Repository
return $copiedProduct;
}
/**
* Gather the ids of the necessary product attributes.
*
* Throw an Exception if one of these 'basic' attributes are missing for some reason.
*
* @return array
*/
private function gatherAttributeIds(): array
{
@ -669,6 +703,13 @@ class ProductRepository extends Repository
return $ids;
}
/**
* Persist attribute values.
*
* @param \Webkul\Product\Models\Product $originalProduct
* @param \Webkul\Product\Models\Product $copiedProduct
* @return void
*/
private function persistAttributeValues(Product $originalProduct, Product $copiedProduct): void
{
$attributeIds = $this->gatherAttributeIds();
@ -749,8 +790,11 @@ class ProductRepository extends Repository
}
/**
* @param $originalProduct
* @param $copiedProduct
* Persist relations.
*
* @param $originalProduct
* @param $copiedProduct
* @return void
*/
private function persistRelations($originalProduct, $copiedProduct): void
{
@ -822,15 +866,18 @@ class ProductRepository extends Repository
}
/**
* @object $data
* @object $copiedProduct
* @object $copiedProductImageVideo
* Copy product image video.
*
* @param $data
* @param $copiedProduct
* @param $copiedProductImageVideo
* @return void
*/
private function copyProductImageVideo($data, $copiedProduct, $copiedProductImageVideo): void
{
$path = explode("/", $data->path);
$path = explode('/', $data->path);
$path = 'product/' . $copiedProduct->id .'/'. end($path);
$path = 'product/' . $copiedProduct->id . '/' . end($path);
$copiedProductImageVideo->path = $path;
@ -840,37 +887,4 @@ class ProductRepository extends Repository
Storage::copy($data->path, $copiedProductImageVideo->path);
}
/**
* Check out of stock items. This method needed `variants` alias in
* the `product_flat` query.
*
* @param Webkul\Product\Models\ProductFlat $query
* @return Illuminate\Database\Eloquent\Builder
*/
public function checkOutOfStockItem($query)
{
return $query
->leftJoin('products as ps', 'product_flat.product_id', '=', 'ps.id')
->leftJoin('product_inventories as pv', 'product_flat.product_id', '=', 'pv.product_id')
->where(function ($qb) {
return $qb
/* for grouped, downloadable, bundle and booking product */
->orWhereIn('ps.type', ['grouped', 'downloadable', 'bundle', 'booking'])
/* for simple and virtual product */
->orWhere(function ($qb) {
return $qb->whereIn('ps.type', ['simple', 'virtual'])->where('pv.qty', '>', 0);
})
/* for configurable product */
->orWhere(function ($qb) {
return $qb->where('ps.type', 'configurable')->where(function ($qb) {
return $qb
->selectRaw('SUM(' . DB::getTablePrefix() . 'product_inventories.qty)')
->from('product_flat')
->leftJoin('product_inventories', 'product_inventories.product_id', '=', 'product_flat.product_id')
->whereRaw(DB::getTablePrefix() . 'product_flat.parent_id = variants.id');
}, '>', 0);
});
});
}
}
}