Перейти до вмісту
Пошук в
  • Детальніше...
Шукати результати, які ...
Шукати результати в ...

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


Гість

Recommended Posts

Увидел ОЧЕНЬ бесявый баг, когда сортируешь товар по цене то не учитывается скидки от 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

Надіслати
Поділитися на інших сайтах

Увидел ОЧЕНЬ бесявый баг, когда сортируешь товар по цене то не учитывается скидки от 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

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

Надіслати
Поділитися на інших сайтах

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

http://opencartforum...dpost__p__46219

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

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

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

Надіслати
Поділитися на інших сайтах

Растолковать можешь? Желательно решением этой проблемы на 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"

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

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

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

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

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

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

Надіслати
Поділитися на інших сайтах

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

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

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

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

Надіслати
Поділитися на інших сайтах

Створіть аккаунт або увійдіть для коментування

Ви повинні бути користувачем, щоб залишити коментар

Створити обліковий запис

Зареєструйтеся для отримання облікового запису. Це просто!

Зареєструвати аккаунт

Вхід

Уже зареєстровані? Увійдіть тут.

Вхід зараз
  • Зараз на сторінці   0 користувачів

    • Ні користувачів, які переглядиють цю сторінку

×
×
  • Створити...

Important Information

На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність.