Lorigin

Чиним сортировку по цене, добавляем фильтр по цене

Рекомендуемые сообщения

Lorigin    34

Увидел ОЧЕНЬ бесявый баг, когда сортируешь товар по цене то не учитывается скидки от SPECIAL, а заодно добавим код для фильтрации по цене

catalogcontrollerproductcategory.php

после

if (isset($this->request->get['sort'])) {
   $sort = $this->request->get['sort'];
  } else {
   $sort = 'p.sort_order';
  }
добавляем

if (isset($this->request->get['pmin'])) {
			$pmin = intval($this->request->get['pmin']);
		} else {
			$pmin = '0';
		}
		if (isset($this->request->get['pmax'])) {
			$pmax = intval($this->request->get['pmax']);
		} else {
			$pmax = '0';
		}

после

$data = array(
	'filter_category_id' => $category_id,
добавляем

'pmin'			   => $pmin,
	'pmax'			   => $pmax,

после

$this->data['sort'] = $sort;
добавляем

$this->data['pmin'] = $pmin;
   $this->data['pmax'] = $pmax;

это мы подготовили контролер для обработки мин и макс цены фильтра

теперь правим модель продуктов catalogmodelcatalogproduct.php

работаем только внутри функции getProducts

первый большой sql запрос, у меня был такой:

$sql = "SELECT p.product_id, (SELECT AVG(rating) AS total FROM " . DB_PREFIX . "review r1 WHERE r1.product_id = p.product_id AND r1.status = '1' GROUP BY r1.product_id) AS rating FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id)";
меняем на

$sql = "SELECT p.product_id, if (p.price > ps.price ,ps.price, p.price) as pr , (SELECT AVG(rating) AS total FROM " . DB_PREFIX . "review r1 WHERE r1.product_id = p.product_id AND r1.status = '1' GROUP BY r1.product_id) AS rating FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) LEFT JOIN " . DB_PREFIX . "product_special ps ON (p.product_id = ps.product_id)";

как видите, добавили столбец pr и заджойнили таблицу чтобы его добавить... этот столбец поможет сортировать нормально и делать фильтрацию по цене

после

$sql .= " GROUP BY p.product_id";
вставляем

$having = false;
			if ((!empty($data['pmin']) && $data['pmin']))  {
				$sql .= " HAVING pr >=  '" . (int)$data['pmin'] . "'";
				$having = true;
			}
			if ((!empty($data['pmax']) && $data['pmax']))  {
				if ($having) {
					$sql .= " AND pr <=  '" . (int)$data['pmax'] . "'";
				} else{
					$sql .= " HAVING pr <=  '" . (int)$data['pmax'] . "'";
				}
			}
так как столбец добавленный через where не отфильтровать, поэтому только через having

ну и наконец делаем правильную сортировку

это

if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
	if ($data['sort'] == 'pd.name' || $data['sort'] == 'p.model') {
	 $sql .= " ORDER BY LCASE(" . $data['sort'] . ")";
	} else {
	 $sql .= " ORDER BY " . $data['sort'];
	}
   } else {
	$sql .= " ORDER BY p.sort_order";
   }
меняем на

if (isset($data['sort']) && in_array($data['sort'], $sort_data)) {
	if ($data['sort'] == 'pd.name' || $data['sort'] == 'p.model') {
	 $sql .= " ORDER BY LCASE(" . $data['sort'] . ")";
	} else {
					if ($data['sort'] != 'p.price') { //чтобы не изголяться в контролерах и не менять
						$sql .= " ORDER BY " . $data['sort'];
					} else {
						$sql .= " ORDER BY pr ";
					}
	}
   } else {
	$sql .= " ORDER BY p.sort_order";
   }

Не забываем поправить общий подсчет, это в той же модели, в методе getTotalProducts

В запрос добавляем тот же джоин, после добавления он будет выглядеть так:

$sql = "SELECT COUNT(DISTINCT p.product_id) AS total FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) LEFT JOIN " . DB_PREFIX . "product_special ps ON (p.product_id = ps.product_id)";

и перед

$query = $this->db->query($sql);

добавляем:

if ((!empty($data['pmin']) && $data['pmin']))  {
		    $sql .= "AND (p.price >= '" . (int)$data['pmin'] . "' OR ps.price >=" . (int)$data['pmin'] . " )";
	    }
	    if ((!empty($data['pmax']) && $data['pmax']))  {
		    $sql .= "AND (p.price <= '" . (int)$data['pmax'] . "' OR ps.price <=" . (int)$data['pmax'] . " )";
	    }

ну собственно фильтрацию по цене делается через параметры pmin и pmax ну это уже сами в своем интерфейсе реализовывайте

пример

http://menspro.ru/pr...alkogolnie-igri

а тут адекватно отсортировало скидку и задан фильт на минимальную цену

http://menspro.ru/pr...er=ASC&pmin=650

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
noVe    152

Спасибо. Пригодится :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Lorigin    34

Добавил изменения в метод getTotalProducts

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
freelancer    1 411

Увидел ОЧЕНЬ бесявый баг, когда сортируешь товар по цене то не учитывается скидки от SPECIAL, а заодно добавим код для фильтрации по цене

...

как видите, добавили столбец pr и заджойнили таблицу чтобы его добавить... этот столбец поможет сортировать нормально и делать фильтрацию по цене

...

в корне неверный подход, не учитывает приоритет, дату и группу

https://opencartforum.com/topic/7234-%d1%81%d0%be%d1%80%d1%82%d0%b8%d1%80%d0%be%d0%b2%d0%ba%d0%b0-%d1%82%d0%be%d0%b2%d0%b0%d1%80%d0%be%d0%b2-%d0%bf%d0%be-%d1%86%d0%b5%d0%bd%d0%b5-%d1%81-%d1%83%d1%87%d0%b5%d1%82%d0%be%d0%bc-%d1%81%d0%ba%d0%b8%d0%b4%d0%be%d0%ba/page__view__findpost__p__46219

посмотрите этот пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Lorigin    34

в корне неверный подход, не учитывает приоритет, дату и группу

http://opencartforum...dpost__p__46219

посмотрите этот пост

Растолковать можешь? Желательно решением этой проблемы на 1.5.3.1

Относительно применения к бизнесу, врятли в категории будет куча товаров с одинаковым ценником, и обозначенный баг будет только в случае сортировки товаров с одинаковым ценником, что кажется бывает крайне редко (ну даже если и будет два товара с одинаковым ценником стоять в "неправильной" последовательность - мир не рухнет)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
freelancer    1 411

Растолковать можешь? Желательно решением этой проблемы на 1.5.3.1

для 1.5.3 решение аналогичное если понять суть

суть в этой строчке

"coalesce((SELECT price FROM " . DB_PREFIX . "product_special ps WHERE ps.product_id = p.product_id AND customer_group_id = '" .
(int)$customer_group_id . "' AND ((date_start = '0000-00-00' OR date_start < NOW()) AND (date_end = '0000-00-00' OR date_end > NOW()))
ORDER BY priority ASC, price ASC LIMIT 1), p.price) as s_price"

Относительно применения к бизнесу, врятли в категории будет куча товаров с одинаковым ценником, и обозначенный баг будет только в случае сортировки товаров с одинаковым ценником, что кажется бывает крайне редко (ну даже если и будет два товара с одинаковым ценником стоять в "неправильной" последовательность - мир не рухнет)

речь о товарах с одинаковым ценником не идёт вовсе. спец цена для товара выбирается с учетом всех этих полей, который ты игноришь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Lorigin    34

для 1.5.3 решение аналогичное если понять суть

суть в этой строчке

речь о товарах с одинаковым ценником не идёт вовсе. спец цена для товара выбирается с учетом всех этих полей, который ты игноришь.

ооооо... точно, мы просто не используем дату и приоритет, я вообще про это забыл.. спасибо, приоритет у нас везде 0 и дата такаяже )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
ingenerks    295

ооооо... точно, мы просто не используем дату и приоритет, я вообще про это забыл.. спасибо, приоритет у нас везде 0 и дата такаяже )

Исправте как должен выглядеть правильно код, я так понимаю в шапке не совсем все было правильно! Спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Lorigin    34

Мне некогда тестировать правильность, в getProducts я поменял - запрос с доп условиями в два раза медленнее... так как я сейчас не планирую использовать веременные диапазоны (это сложно интегрировать будет с тем же моимскладом), то не вижу смысла тормозить себе..

а по поводу getTotalProducts надо тестить, на сколько я понимаю добавить условий в джойн просто не получится..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти


  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу