feat(filters): add filters for the main page

This commit is contained in:
2025-10-06 13:49:27 +03:00
parent bfc6ba496b
commit e7e045b695
65 changed files with 1172 additions and 525 deletions

View File

@@ -11,6 +11,7 @@ abstract class BaseRule
public const CRITERIA_OPTION_NUMBER = 'number';
public const CRITERIA_OPTION_BOOLEAN = 'boolean';
public const CRITERIA_OPTION_PRODUCT_CATEGORIES = 'product_categories';
public const CRITERIA_OPTION_PRODUCT_CATEGORY = 'product_category';
public const CRITERIA_OPTION_PRODUCT_MANUFACTURER = 'product_manufacturer';
public const CRITERIA_OPTION_PRODUCT_ATTRIBUTE = 'product_attribute';
public const CRITERIA_OPTION_PRODUCT_MODEL = 'product_model';

View File

@@ -22,6 +22,7 @@ class Builder
public $joins = [];
public $wheres = [];
public $orders = [];
public $groupBy = [];
public $limit;
public $offset;
public $distinct = false;
@@ -447,4 +448,11 @@ class Builder
return count($join) > 0;
}
public function groupBy(array $columns): Builder
{
$this->groupBy = $columns;
return $this;
}
}

View File

@@ -17,6 +17,7 @@ abstract class Grammar
'orders' => [],
'limit' => [],
'offset' => [],
'groupBy' => [],
];
private function resetCompiled(): void
@@ -29,6 +30,7 @@ abstract class Grammar
'orders' => [],
'limit' => [],
'offset' => [],
'groupBy' => [],
];
}
@@ -194,4 +196,9 @@ abstract class Grammar
return $this->getRawValue($condition['column']) . " $inOperator (" . $inValues . ')';
}
public function compileGroupBy(Builder $builder, array $groupBy): string
{
return 'GROUP BY ' . implode(', ', $groupBy);
}
}

View File

@@ -12,6 +12,7 @@ class TelegramValidateInitDataMiddleware
'testTgMessage',
'manifest',
'webhook',
'health',
];
public function __construct(SignatureValidator $signatureValidator)

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Filters;
use InvalidArgumentException;
use Openguru\OpenCartFramework\CriteriaBuilder\Criterion;
use Openguru\OpenCartFramework\CriteriaBuilder\Rules\BaseRule;
use Openguru\OpenCartFramework\QueryBuilder\Builder;
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;
class ProductCategory extends BaseRule
{
public const NAME = 'RULE_PRODUCT_CATEGORY';
public static function initWithDefaults(): BaseRule
{
return new static(static::NAME, [
'product_category_id' => new Criterion(static::CRITERIA_OPTION_PRODUCT_CATEGORIES, [
'operator' => static::CRITERIA_OPERATOR_CONTAINS,
'value' => null,
])
]);
}
public function apply(Builder $builder, $operand): void
{
/** @var Criterion $criterion */
foreach ($this->criteria as $criterion) {
if ($criterion->type === static::CRITERIA_OPTION_PRODUCT_CATEGORY) {
$operator = $criterion->params['operator'];
$categoryId = $criterion->params['value'];
if (! $categoryId) {
return;
}
$uniqHash = md5(serialize($criterion));
$joinAlias = 'product_category_' . $uniqHash;
if ($builder->hasJoinAlias($joinAlias)) {
return;
}
$builder->join(
db_table('product_to_category') . " AS $joinAlias",
function (JoinClause $join) use ($joinAlias, $categoryId) {
$join
->on('products.product_id', '=', "$joinAlias.product_id")
->where("$joinAlias.category_id", '=', $categoryId);
},
'left'
);
if ($operator === 'contains') {
$builder->whereNotNull("$joinAlias.product_id", $operand);
} elseif ($operator === 'not_contains') {
$builder->whereNull("$joinAlias.product_id", $operand);
} else {
throw new InvalidArgumentException('Invalid operator: ' . $operator);
}
}
}
}
}

View File

@@ -42,8 +42,7 @@ class ProductPrice extends BaseRule
*/
public function apply(Builder $builder, $operand)
{
$includeSpecials = Arr::get($this->criteria, 'include_specials.value', true);
$includeDiscounts = Arr::get($this->criteria, 'include_discounts.value', false);
$includeSpecials = $this->criteria['include_specials']->params['value'] ?? true;
/** @var Criterion|null $productPriceCriterion */
$productPriceCriterion = $this->criteria['product_price'] ?? null;
@@ -67,10 +66,10 @@ class ProductPrice extends BaseRule
$customerGroupId = config('oc_customer_group_id', 1);
$sub = $builder->newQuery()
$sub2 = $builder->newQuery()
->select([
'ps.product_id',
'ps.price',
'product_id',
new RawExpression("MIN(CONCAT(LPAD(priority, 5, '0'), LPAD(price, 10, '0'))) AS sort_key"),
])
->from(db_table('product_special'), 'ps')
->where("ps.customer_group_id", '=', $customerGroupId)
@@ -80,9 +79,18 @@ class ProductPrice extends BaseRule
AND (ps.date_end = '0000-00-00' OR ps.date_end > NOW())
"
)
->orderBy('ps.priority', 'ASC')
->orderBy('ps.price', 'ASC')
->limit(1);
->groupBy(['product_id']);
$sub = $builder->newQuery()
->select([
'ps1.product_id',
'ps1.price',
])
->from(db_table('product_special'), 'ps1')
->join(new Table($sub2, 'ps2'), function (JoinClause $join) {
$join->on('ps1.product_id', '=', 'ps2.product_id')
->whereRaw("CONCAT(LPAD(ps1.priority, 5, '0'), LPAD(ps1.price, 10, '0')) = ps2.sort_key");
});
$builder->join(new Table($sub, $joinAlias), function (JoinClause $join) use ($joinAlias) {
$join->on('products.product_id', '=', "$joinAlias.product_id");

View File

@@ -0,0 +1,62 @@
<?php
namespace App\Handlers;
use App\Filters\ProductCategory;
use App\Filters\ProductForMainPage;
use App\Filters\ProductPrice;
use Openguru\OpenCartFramework\Http\JsonResponse;
class FiltersHandler
{
public function getFiltersForMainPage(): JsonResponse
{
$filters = [
'operand' => 'AND',
'rules' => [
ProductPrice::NAME => [
'criteria' => [
'product_price' => [
'type' => 'number',
'params' => [
'operator' => 'between',
'value' => [
'from' => 0,
'to' => null,
],
],
],
],
],
ProductForMainPage::NAME => [
'criteria' => [
'product_for_main_page' => [
'type' => 'boolean',
'params' => [
'operator' => 'equals',
'value' => true,
],
],
],
],
ProductCategory::NAME => [
'criteria' => [
'product_category_id' => [
'type' => 'product_category',
'params' => [
'operator' => 'contains',
'value' => null,
],
],
]
],
],
];
return new JsonResponse([
'data' => $filters,
]);
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace App\Handlers;
use Openguru\OpenCartFramework\Http\JsonResponse;
use Openguru\OpenCartFramework\Http\Response;
class HealthCheckHandler
{
public function handle(): JsonResponse
{
return new JsonResponse([
'status' => 'ok',
], Response::HTTP_OK);
}
}

View File

@@ -5,6 +5,7 @@ namespace App\ServiceProviders;
use App\Exceptions\CustomExceptionHandler;
use App\Filters\ProductAttribute;
use App\Filters\ProductCategories;
use App\Filters\ProductCategory;
use App\Filters\ProductForMainPage;
use App\Filters\ProductManufacturer;
use App\Filters\ProductModel;
@@ -64,6 +65,7 @@ class AppServiceProvider extends ServiceProvider
ProductQuantity::NAME => ProductQuantity::class,
ProductStatus::NAME => ProductStatus::class,
ProductForMainPage::NAME => ProductForMainPage::class,
ProductCategory::NAME => ProductCategory::class,
]);
}
}

View File

@@ -59,7 +59,7 @@ class ProductsService
$maxPages = $params['maxPages'] ?? 50;
$filters = $params['filters'] ?? [];
$customerGroupId = (int) $this->oc->config->get('config_customer_group_id');
$customerGroupId = (int) $this->settings->get('oc_customer_group_id');
$specialPriceSql = "(SELECT price
FROM oc_product_special ps
WHERE ps.product_id = products.product_id

View File

@@ -1,16 +1,21 @@
<?php
use App\Handlers\CategoriesHandler;
use App\Handlers\CartHandler;
use App\Handlers\CategoriesHandler;
use App\Handlers\FiltersHandler;
use App\Handlers\HealthCheckHandler;
use App\Handlers\OrderHandler;
use App\Handlers\ProductsHandler;
use App\Handlers\SettingsHandler;
use App\Handlers\TelegramHandler;
return [
'health' => [HealthCheckHandler::class, 'handle'],
'products' => [ProductsHandler::class, 'index'],
'product_show' => [ProductsHandler::class, 'show'],
'storeOrder' => [OrderHandler::class, 'store'],
'filtersForMainPage' => [FiltersHandler::class, 'getFiltersForMainPage'],
'categoriesList' => [CategoriesHandler::class, 'index'],

View File

@@ -498,4 +498,18 @@ class BuilderTest extends TestCase
$this->assertEquals($expected, $query->toRawSql());
}
public function testGroupBy(): void
{
$query = $this->builder->newQuery()
->select(['foo', 'bar'])
->from('table_1')
->groupBy(['foo', 'bar']);
$this->assertEquals(
'SELECT foo, bar FROM table_1 GROUP BY foo, bar',
$query->toRawSql(),
);
}
}

View File

@@ -4,6 +4,7 @@ namespace Tests\Unit;
use App\Filters\ProductAttribute;
use App\Filters\ProductCategories;
use App\Filters\ProductCategory;
use App\Filters\ProductForMainPage;
use App\Filters\ProductManufacturer;
use App\Filters\ProductModel;
@@ -89,6 +90,7 @@ class CriteriaBuilderTest extends TestCase
$rulesRegistry->register(ProductQuantity::NAME, ProductQuantity::class);
$rulesRegistry->register(ProductAttribute::NAME, ProductAttribute::class);
$rulesRegistry->register(ProductForMainPage::NAME, ProductForMainPage::class);
$rulesRegistry->register(ProductCategory::NAME, ProductCategory::class);
$this->builder = $application->get(Builder::class);
$this->criteriaBuilder = $application->get(CriteriaBuilder::class);

View File

@@ -219,4 +219,15 @@ class MySqlGrammarTest extends TestCase
['column' => 'bar', 'as' => null],
]));
}
public function testCompileGroupBy(): void
{
$mock = m::mock(Builder::class);
$mock->groupBy = ['foo', 'bar'];
$this->assertEquals(
'GROUP BY foo, bar',
$this->grammar->compileGroupBy($mock, ['foo', 'bar'])
);
}
}

View File

@@ -0,0 +1,19 @@
{
"operand": "AND",
"rules": {
"RULE_PRODUCT_CATEGORY": {
"criteria": {
"product_category_id": {
"type": "product_category",
"params": {
"operator": "contains",
"value": 58
}
}
},
"__meta": {
"group": "other"
}
}
}
}

View File

@@ -0,0 +1,17 @@
SELECT
products.product_id AS product_id,
products.image AS image,
product_description.name AS name,
products.model AS model,
products.price AS price,
products.quantity AS quantity,
products.status AS STATUS,
products.noindex AS noindex
FROM
oc_product AS products
INNER JOIN oc_product_description AS product_description ON products.product_id = product_description.product_id
AND product_description.language_id = 1
LEFT JOIN oc_product_to_category AS product_category_a46414dc254a7328c63a5de8a760fa8f ON products.product_id = product_category_a46414dc254a7328c63a5de8a760fa8f.product_id
AND product_category_a46414dc254a7328c63a5de8a760fa8f.category_id = 58
WHERE
product_category_a46414dc254a7328c63a5de8a760fa8f.product_id IS NOT NULL

View File

@@ -0,0 +1,19 @@
{
"operand": "AND",
"rules": {
"RULE_PRODUCT_CATEGORY": {
"criteria": {
"product_category_id": {
"type": "product_category",
"params": {
"operator": "not_contains",
"value": 58
}
}
},
"__meta": {
"group": "other"
}
}
}
}

View File

@@ -0,0 +1,17 @@
SELECT
products.product_id AS product_id,
products.image AS image,
product_description.name AS name,
products.model AS model,
products.price AS price,
products.quantity AS quantity,
products.status AS STATUS,
products.noindex AS noindex
FROM
oc_product AS products
INNER JOIN oc_product_description AS product_description ON products.product_id = product_description.product_id
AND product_description.language_id = 1
LEFT JOIN oc_product_to_category AS product_category_fa9affd75942255178dc16d1ec8b424f ON products.product_id = product_category_fa9affd75942255178dc16d1ec8b424f.product_id
AND product_category_fa9affd75942255178dc16d1ec8b424f.category_id = 58
WHERE
product_category_fa9affd75942255178dc16d1ec8b424f.product_id IS NULL

View File

@@ -13,25 +13,38 @@ FROM
AND product_description.language_id = 1
LEFT JOIN (
SELECT
ps.product_id,
ps.price
ps1.product_id,
ps1.price
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT
1
oc_product_special AS ps1
INNER JOIN (
SELECT
product_id,
MIN(
CONCAT(
LPAD(priority, 5, '0'),
LPAD(price, 10, '0')
)
) AS sort_key
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
GROUP BY
product_id
) AS ps2 ON ps1.product_id = ps2.product_id
AND CONCAT(
LPAD(ps1.priority, 5, '0'),
LPAD(ps1.price, 10, '0')
) = ps2.sort_key
) AS product_specials_4bf5415bae7c037731801559d0410697 ON products.product_id = product_specials_4bf5415bae7c037731801559d0410697.product_id
WHERE
COALESCE(

View File

@@ -13,25 +13,38 @@ FROM
AND product_description.language_id = 1
LEFT JOIN (
SELECT
ps.product_id,
ps.price
ps1.product_id,
ps1.price
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT
1
oc_product_special AS ps1
INNER JOIN (
SELECT
product_id,
MIN(
CONCAT(
LPAD(priority, 5, '0'),
LPAD(price, 10, '0')
)
) AS sort_key
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
GROUP BY
product_id
) AS ps2 ON ps1.product_id = ps2.product_id
AND CONCAT(
LPAD(ps1.priority, 5, '0'),
LPAD(ps1.price, 10, '0')
) = ps2.sort_key
) AS product_specials_f1ca65a396fc2e41a23a3661b84d1519 ON products.product_id = product_specials_f1ca65a396fc2e41a23a3661b84d1519.product_id
WHERE
COALESCE(

View File

@@ -13,25 +13,38 @@ FROM
AND product_description.language_id = 1
LEFT JOIN (
SELECT
ps.product_id,
ps.price
ps1.product_id,
ps1.price
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT
1
oc_product_special AS ps1
INNER JOIN (
SELECT
product_id,
MIN(
CONCAT(
LPAD(priority, 5, '0'),
LPAD(price, 10, '0')
)
) AS sort_key
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
GROUP BY
product_id
) AS ps2 ON ps1.product_id = ps2.product_id
AND CONCAT(
LPAD(ps1.priority, 5, '0'),
LPAD(ps1.price, 10, '0')
) = ps2.sort_key
) AS product_specials_f0c4ece67502916e844720b12abc54a9 ON products.product_id = product_specials_f0c4ece67502916e844720b12abc54a9.product_id
WHERE
COALESCE(

View File

@@ -13,25 +13,38 @@ FROM
AND product_description.language_id = 1
LEFT JOIN (
SELECT
ps.product_id,
ps.price
ps1.product_id,
ps1.price
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT
1
oc_product_special AS ps1
INNER JOIN (
SELECT
product_id,
MIN(
CONCAT(
LPAD(priority, 5, '0'),
LPAD(price, 10, '0')
)
) AS sort_key
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
GROUP BY
product_id
) AS ps2 ON ps1.product_id = ps2.product_id
AND CONCAT(
LPAD(ps1.priority, 5, '0'),
LPAD(ps1.price, 10, '0')
) = ps2.sort_key
) AS product_specials_5173bd7b8335ab5a9f4e37227d0c317f ON products.product_id = product_specials_5173bd7b8335ab5a9f4e37227d0c317f.product_id
WHERE
COALESCE(

View File

@@ -13,25 +13,38 @@ FROM
AND product_description.language_id = 1
LEFT JOIN (
SELECT
ps.product_id,
ps.price
ps1.product_id,
ps1.price
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT
1
oc_product_special AS ps1
INNER JOIN (
SELECT
product_id,
MIN(
CONCAT(
LPAD(priority, 5, '0'),
LPAD(price, 10, '0')
)
) AS sort_key
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
GROUP BY
product_id
) AS ps2 ON ps1.product_id = ps2.product_id
AND CONCAT(
LPAD(ps1.priority, 5, '0'),
LPAD(ps1.price, 10, '0')
) = ps2.sort_key
) AS product_specials_7b934dfdfc5b809270875934c10acc06 ON products.product_id = product_specials_7b934dfdfc5b809270875934c10acc06.product_id
WHERE
COALESCE(

View File

@@ -13,25 +13,38 @@ FROM
AND product_description.language_id = 1
LEFT JOIN (
SELECT
ps.product_id,
ps.price
ps1.product_id,
ps1.price
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT
1
oc_product_special AS ps1
INNER JOIN (
SELECT
product_id,
MIN(
CONCAT(
LPAD(priority, 5, '0'),
LPAD(price, 10, '0')
)
) AS sort_key
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
GROUP BY
product_id
) AS ps2 ON ps1.product_id = ps2.product_id
AND CONCAT(
LPAD(ps1.priority, 5, '0'),
LPAD(ps1.price, 10, '0')
) = ps2.sort_key
) AS product_specials_51a33d8bcfeece60de797c18e3800075 ON products.product_id = product_specials_51a33d8bcfeece60de797c18e3800075.product_id
WHERE
COALESCE(

View File

@@ -13,25 +13,38 @@ FROM
AND product_description.language_id = 1
LEFT JOIN (
SELECT
ps.product_id,
ps.price
ps1.product_id,
ps1.price
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT
1
oc_product_special AS ps1
INNER JOIN (
SELECT
product_id,
MIN(
CONCAT(
LPAD(priority, 5, '0'),
LPAD(price, 10, '0')
)
) AS sort_key
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
GROUP BY
product_id
) AS ps2 ON ps1.product_id = ps2.product_id
AND CONCAT(
LPAD(ps1.priority, 5, '0'),
LPAD(ps1.price, 10, '0')
) = ps2.sort_key
) AS product_specials_7de8997be994ada47d62cdfe2b7369c9 ON products.product_id = product_specials_7de8997be994ada47d62cdfe2b7369c9.product_id
WHERE
COALESCE(

View File

@@ -13,25 +13,38 @@ FROM
AND product_description.language_id = 1
LEFT JOIN (
SELECT
ps.product_id,
ps.price
ps1.product_id,
ps1.price
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT
1
oc_product_special AS ps1
INNER JOIN (
SELECT
product_id,
MIN(
CONCAT(
LPAD(priority, 5, '0'),
LPAD(price, 10, '0')
)
) AS sort_key
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
GROUP BY
product_id
) AS ps2 ON ps1.product_id = ps2.product_id
AND CONCAT(
LPAD(ps1.priority, 5, '0'),
LPAD(ps1.price, 10, '0')
) = ps2.sort_key
) AS product_specials_78ccac1dc1d86997e6eac0613f2eb5f3 ON products.product_id = product_specials_78ccac1dc1d86997e6eac0613f2eb5f3.product_id
WHERE
COALESCE(

View File

@@ -13,25 +13,38 @@ FROM
AND product_description.language_id = 1
LEFT JOIN (
SELECT
ps.product_id,
ps.price
ps1.product_id,
ps1.price
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT
1
oc_product_special AS ps1
INNER JOIN (
SELECT
product_id,
MIN(
CONCAT(
LPAD(priority, 5, '0'),
LPAD(price, 10, '0')
)
) AS sort_key
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
GROUP BY
product_id
) AS ps2 ON ps1.product_id = ps2.product_id
AND CONCAT(
LPAD(ps1.priority, 5, '0'),
LPAD(ps1.price, 10, '0')
) = ps2.sort_key
) AS product_specials_5816f1e65a3d296a26635f070d0439bc ON products.product_id = product_specials_5816f1e65a3d296a26635f070d0439bc.product_id
WHERE
COALESCE(

View File

@@ -13,25 +13,38 @@ FROM
AND product_description.language_id = 1
LEFT JOIN (
SELECT
ps.product_id,
ps.price
ps1.product_id,
ps1.price
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT
1
oc_product_special AS ps1
INNER JOIN (
SELECT
product_id,
MIN(
CONCAT(
LPAD(priority, 5, '0'),
LPAD(price, 10, '0')
)
) AS sort_key
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
GROUP BY
product_id
) AS ps2 ON ps1.product_id = ps2.product_id
AND CONCAT(
LPAD(ps1.priority, 5, '0'),
LPAD(ps1.price, 10, '0')
) = ps2.sort_key
) AS product_specials_51a33d8bcfeece60de797c18e3800075 ON products.product_id = product_specials_51a33d8bcfeece60de797c18e3800075.product_id
WHERE
COALESCE(

View File

@@ -13,25 +13,38 @@ FROM
AND product_description.language_id = 1
LEFT JOIN (
SELECT
ps.product_id,
ps.price
ps1.product_id,
ps1.price
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT
1
oc_product_special AS ps1
INNER JOIN (
SELECT
product_id,
MIN(
CONCAT(
LPAD(priority, 5, '0'),
LPAD(price, 10, '0')
)
) AS sort_key
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
GROUP BY
product_id
) AS ps2 ON ps1.product_id = ps2.product_id
AND CONCAT(
LPAD(ps1.priority, 5, '0'),
LPAD(ps1.price, 10, '0')
) = ps2.sort_key
) AS product_specials_51a33d8bcfeece60de797c18e3800075 ON products.product_id = product_specials_51a33d8bcfeece60de797c18e3800075.product_id
WHERE
COALESCE(

View File

@@ -13,25 +13,38 @@ FROM
AND product_description.language_id = 1
LEFT JOIN (
SELECT
ps.product_id,
ps.price
ps1.product_id,
ps1.price
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT
1
oc_product_special AS ps1
INNER JOIN (
SELECT
product_id,
MIN(
CONCAT(
LPAD(priority, 5, '0'),
LPAD(price, 10, '0')
)
) AS sort_key
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
GROUP BY
product_id
) AS ps2 ON ps1.product_id = ps2.product_id
AND CONCAT(
LPAD(ps1.priority, 5, '0'),
LPAD(ps1.price, 10, '0')
) = ps2.sort_key
) AS product_specials_cf0f856fa900f18f5c8c0a57357532f5 ON products.product_id = product_specials_cf0f856fa900f18f5c8c0a57357532f5.product_id
WHERE
COALESCE(

View File

@@ -13,25 +13,38 @@ FROM
AND product_description.language_id = 1
LEFT JOIN (
SELECT
ps.product_id,
ps.price
ps1.product_id,
ps1.price
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT
1
oc_product_special AS ps1
INNER JOIN (
SELECT
product_id,
MIN(
CONCAT(
LPAD(priority, 5, '0'),
LPAD(price, 10, '0')
)
) AS sort_key
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
GROUP BY
product_id
) AS ps2 ON ps1.product_id = ps2.product_id
AND CONCAT(
LPAD(ps1.priority, 5, '0'),
LPAD(ps1.price, 10, '0')
) = ps2.sort_key
) AS product_specials_08e0a0248dc92591ae55fdd966728ba0 ON products.product_id = product_specials_08e0a0248dc92591ae55fdd966728ba0.product_id
WHERE
COALESCE(

View File

@@ -13,25 +13,38 @@ FROM
AND product_description.language_id = 1
LEFT JOIN (
SELECT
ps.product_id,
ps.price
ps1.product_id,
ps1.price
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
ORDER BY
ps.priority ASC,
ps.price ASC
LIMIT
1
oc_product_special AS ps1
INNER JOIN (
SELECT
product_id,
MIN(
CONCAT(
LPAD(priority, 5, '0'),
LPAD(price, 10, '0')
)
) AS sort_key
FROM
oc_product_special AS ps
WHERE
ps.customer_group_id = 1
AND (
ps.date_start = '0000-00-00'
OR ps.date_start < NOW()
)
AND (
ps.date_end = '0000-00-00'
OR ps.date_end > NOW()
)
GROUP BY
product_id
) AS ps2 ON ps1.product_id = ps2.product_id
AND CONCAT(
LPAD(ps1.priority, 5, '0'),
LPAD(ps1.price, 10, '0')
) = ps2.sort_key
) AS product_specials_47d71067324729b89b13414a6ea869e0 ON products.product_id = product_specials_47d71067324729b89b13414a6ea869e0.product_id
WHERE
COALESCE(

View File

@@ -0,0 +1,25 @@
{
"operand": "AND",
"rules": {
"RULE_PRODUCT_PRICE": {
"criteria": {
"product_price": {
"type": "number",
"params": {
"operator": "equals",
"value": {
"from": 100,
"to": null
}
}
},
"include_specials": {
"type": "boolean",
"params": {
"value": false
}
}
}
}
}
}

View File

@@ -0,0 +1,15 @@
SELECT
products.product_id AS product_id,
products.image AS image,
product_description.name AS name,
products.model AS model,
products.price AS price,
products.quantity AS quantity,
products.status AS STATUS,
products.noindex AS noindex
FROM
oc_product AS products
INNER JOIN oc_product_description AS product_description ON products.product_id = product_description.product_id
AND product_description.language_id = 1
WHERE
products.price = 100