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

Альтернативный фильтр товаров в админке


Recommended Posts

Взялся за большое дело: правку admin/controller/catalog/product.php. Для чего: чтобы видеть доп. поля у товара, не тратить время на то, чтобы влезать в его подробное описание, Сделал вывод ID товара и SKU, Товары сортируются по ID и SKU, и, что самое важное, когда начинаем вводить SKU, ajax предлагает варианты.

 

По моей логике - SKU - это номенклатурный номер. Он будет соответствовать полю КОД в 1С УТ в справочнике Номенклатура. Пока же он вводится вручную при добавлении товара.

 

Модель - это vendor code, присвоенный товару или партии товара на заводе-изготовителе.

 

Все чудесно. Добрался до Производителя. Задача аналогичная: сортировка, фильтрация, поиск. Для чего: вывести все товары одного производителя, например. 

 

Тут меня ждал сюрприз ) В БД oc_product хранится manufacturer_id. Сделал сначала вывод этого значения. Все ОК!

Сортировка, фильтрация - все работает. Но помнить ИД производителя - это глупо, а выводить его неинформативно. Чтобы выводился именно производитель, в контроллере добавил это:

foreach ($results as $result) {
// devel add start vendor	
    if(!empty($result['manufacturer_id'])) {	
	  $manufacturer = $this->model_catalog_manufacturer->getManufacturer($result['manufacturer_id']);  
	  $vendor = $manufacturer['name'];}
	  else {
	  $vendor = 'No Name';
	  }	
	  $vendor_id = $result['manufacturer_id'];  
// devel add end
$action = array();

Т.е. для каждого товара в списке, вытащил наименование производителя. Отправил эти данные в др. массив:

      		$this->data['products'][] = array(
// devel add start product_id, sku
				'product_id' => $result['product_id'],
				'sku'        => $result['sku'],
// devel add end
				'name'       => $result['name'],
				'model'      => $result['model'],
// devel add start vendor
				'manufacturer_name'     => $vendor,
				'manufacturer_id'     => $vendor_id,
// devel add end
				'price'      => $result['price'],
				'special'    => $special,
				'image'      => $image,
				'quantity'   => $result['quantity'],
				'status'     => ($result['status'] ? $this->language->get('text_enabled') : $this->language->get('text_disabled')),
				'selected'   => isset($this->request->post['selected']) && in_array($result['product_id'], $this->request->post['selected']),
				'action'     => $action
			);
    	}

и в public function autocomplete() :

				$json[] = array(
// devel add start product_id, sku, Здесь выпадающие значения ajax
					'product_id' => $result['product_id'],
					'sku' => $result['sku'],
// devel add end
					'name'       => strip_tags(html_entity_decode($result['name'], ENT_QUOTES, 'UTF-8')),	
					'model'      => $result['model'],
// devel add start
					'manufacturer_name'     => $vendor,
					'manufacturer_id'     => $vendor_id,
// devel add end					
					'option'     => $option_data,
					'price'      => $result['price']
				);	

Я привожу только часть кода, т.к. правок я внес неимоверное кол-во, Привожу только ту часть, которая на мой взгляд "проблемная". Результат в аттаче.

 

Сортировка по алфавиту работает, При вводе наименования производителя ajax не срабатывает. При вводе ИД производителя ajax предлагает варианты, у которых совпал ид ))) 

 

Задачу нужно разбить на две:

1) вывод наименования производителя (а не его ид) - это реализовано в контроллере

2) ввод наименования производителя.

 

В Модели формируется запрос к p,manufacturer_id, => работать нужно с ИД производителя (аналогично SKU), но ввод и вывод - в виде наименования. С выводом я разобрался. А вот на каком этапе преобразовать то, что вводим с клавиатуры в ИД производителя - не пойму, запутался. По идее, из шаблона получаем ИД производителя, Дальше я сдулся... Прошу гуру помощи!

:

post-7857-0-97861200-1383836774_thumb.png

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


https://opencartforum.com/topic/20746-filtr-tovarov-v-adminke/

расширение позволяет помимо прочего фильтровать товары в админке по производителю, категории.

поиск по искомой подстроке в названии/ модели в любой части слова

расширение не перезаписывает файлы, не использует vQmod, работает на ajax.

говорим "спасибо" автору: @freelancer

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

freelancer спасибо! ))

Много нужных и полезных плюшек создано автором. 

Буду дербанить этот модуль, т.к. мне нужны доп. поля ))

Спасибо afwollis за наводку! На форуме реально трудно что-то найти. Реально, лучше ищется через гугл, который лучше знает, где что на форуме лежит )))) 

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


Однако, js там ужат, что ниосилить )) Бум дальше изобретать деревянный велосипед... Главное - я знаю, что должно быть в конечном итоге. Понимаю, что не совсем правильно делать то, что уже сделано до тебя. Но мне нужно "немного не так", а с js я совсем не знаком. 

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


Извиняюсь за свои "наскальные" рисунки, но от руки быстрее. Хочу привлечь внимание других участников сообщества к вышеозначеному вопросу.

1) Просьба модератора раздела переименовать тему в "Альтернативный фильтр товаров в админке", т.к. по действующему названию совсем неясно, о чем речь.

2) Цель: создание модуля для админ-панели, обладающего следующими возможностями:

 

1) чекбокс

2) изображение товара

3) id товара

4)  sku (номенклатурный номер, артикул)

5) наименование товара

6) модель (он же vendor_code, part_number)

7) производитель (он же vendor)

8) страна происхождения товара 

9) гарантия (xx месяцев)

10) Цена, руб

11) Цена, usd

12) Кол-во (состояние склада)

13) Расположение (какой склад: ближний, дальний, мск и т.п. или пушкина 30, ленина 40 и т.п.)

14) статус

 

 

Выглядит устрашающе, но много реализовать просто, т.к. данные эти вводятся в карточку (в админке) товара при добавлении.

 

 

Этот же список,(новые поля) но в контексте таблиц-полей 

sku: product->sku

производитель: product->manufacturer_id (manufacturer->name)

страна происхождения: отсутствует в БД

гарантия отсутствует в БД

цена usd: можно вынуть из модуля "Валюта по курсу ЦБРФ"

расположение: product->location

 

Чтобы не вводить новую ячейку в таблицу product, можно использовать для вывода страны происхождения товара mpn (что не приветствуется на форуме). Этот вопрос открыт для обсуждения (я надеюсь, что интерес и обсуждения будут)

 

В модуле freelancer-а был реализован вывод и сортировка по категории, в которой содержится товар. Возможно это тоже не лишняя опция. Модуль от freelancera хорош и удобен. Но непонятен, т.к. на js. Просить человека доделывать модуль, который он безвозмездно выложил, под каждую прихоть, считаю неправильным и нетактичным. Но работать нужно. Менеджеру, который держит на трубке клиента нужно ответить на вопросы "где забрать, сколько стоит, китай или китай, какая гарантия и чья". К сожалению, в opencart это не реализовано. В то же время YM эти атрибуты обрабатывает, и покупатель о них спрашивает. Менеджер вынужден либо на сайт производителя бежать, смотреть доп. инфу там, либо по прайсам рыскать, может кто указал. 

 

Ближе к делу. На данный момент реализованы полностью п.1 - п.6. А п.7 реализован частично. Возникла проблема: поиск и сортировка происходят правильно, если вводить не название производителя, а его id )) Ниже мои умозаключения.

Таблица manufacturer:

0d1d996a4a65t.jpg

 

В этой таблице по manufacturer_id узнаем его name

 

По аналогии с ID, SKU я сделал поле Производитель. Однако, вводя в поле наименование производителя (например, abc) - значение abc из формы передается в js (ajax, для подбора вариантов "на лету") и в контроллер. Контроллер присваивает переменной значение abc, и она передается в модель, которая пытается в таблице product найти все товары по полю abc. Такого поля в таблице product нет. Вот наглядно (насколько смог):

4743276f1bdct.jpg

Т.е. получаем ошибку, что логично. Есть несколько путей решения: добавить в таблицу product поле manufacturer (теряем совместимость с оригинальным opencart, имеем проблемы при обновлении). Либо второй вариант - "фильтровать" ввод с клавиатуры, сравнивать его с manufacturer->name и в случае совпадения - выдавать в контроллер его manufacturer_id (это мне не удалось). Далее по аналогии. И на выходе снова преобразовать manufacturer_id в manufacturer->name (и это мне удалось).Наглядно:

6a1a7340e504t.jpg

Все  изменения - в файлах \www\admin\controller\catalog\product.php (контроллер), \www\admin\view\template\catalog]product_list.tpl (шаблон) и \www\admin\model\catalog\prodict.php (модель).

Архив с тем, что уже сделано - в аттаче. Очень надеюсь на участие и помощь коллег, т.к. хочется сделать модуль таким, чтобы можно было его при необходимости, допилить самостоятельно.  

 

product-filter-for-admin-000.zip

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


Жаль, что никто не заинтересовался. Поэтому, продолжаю сам. Разбираю jquery autocomplete. Для понимания функционирования этого плагина, добавил в шаблон и id производителя:

                <td class="center"><?php if ($sort == 'p.manufacturer_name') { ?>                <a href="<?php echo $sort_manufacturer_name; ?>" class="<?php echo strtolower($order); ?>"><?php echo $column_vendor; ?></a>                <?php } else { ?>                <a href="<?php echo $sort_manufacturer_name; ?>"><?php echo $column_vendor; ?></a>                <?php } ?></td>                <td class="center"><?php if ($sort == 'p.manufacturer_id') { ?>                <a href="<?php echo $sort_manufacturer_id; ?>" class="<?php echo strtolower($order); ?>"><?php echo $column_vendor_id; ?></a>                <?php } else { ?>                <a href="<?php echo $sort_manufacturer_id; ?>"><?php echo $column_vendor_id; ?></a>                <?php } ?></td>
              <td class="center"><input style="width:90px;" type="text" name="filter_manufacturer_name" value="<?php echo $filter_manufacturer_name; ?>" /></td>              <td class="center"><input style="width:90px;" type="text" name="filter_manufacturer_id" value="<?php echo $filter_manufacturer_id; ?>" /></td>
              <td class="center"><?php echo $product['manufacturer_name']; ?></td>              <td class="center"><?php echo $product['manufacturer_id']; ?></td>  
	var filter_manufacturer_name = $('input[name=\'filter_manufacturer_name\']').attr('value');		if (filter_manufacturer_name) {		url += '&filter_manufacturer_name=' + encodeURIComponent(filter_manufacturer_name);	}		var filter_manufacturer_id = $('input[name=\'filter_manufacturer_id\']').attr('value');		if (filter_manufacturer_id) {		url += '&filter_manufacturer_id=' + encodeURIComponent(filter_manufacturer_id);	}
$('input[name=\'filter_manufacturer_name\']').autocomplete({	delay: 500,	source: function(request, response) {		$.ajax({			url: 'index.php?route=catalog/product/autocomplete&token=<?php echo $token; ?>&filter_manufacturer_name=' +  encodeURIComponent(request.term),			dataType: 'json',			success: function(json) {						response($.map(json, function(item) {				//alert(item.manufacturer_name);				//alert(item.manufacturer_id);					return {						label: item.manufacturer_name,						value: item.product_id											}				}));			}		});	}, 	select: function(event, ui) {		$('input[name=\'filter_manufacturer_name\']').val(ui.item.label);								return false;	},	focus: function(event, ui) {      	return false;   	}});$('input[name=\'filter_manufacturer_id\']').autocomplete({	delay: 500,	source: function(request, response) {		$.ajax({			url: 'index.php?route=catalog/product/autocomplete&token=<?php echo $token; ?>&filter_manufacturer_id=' +  encodeURIComponent(request.term),			dataType: 'json',			success: function(json) {						response($.map(json, function(item) {				//alert(item.manufacturer_name);				//alert(item.manufacturer_id);					return {						label: item.manufacturer_id,						value: item.product_id					}				}));			}		});	}, 	select: function(event, ui) {		$('input[name=\'filter_manufacturer_id\']').val(ui.item.label);								return false;	},	focus: function(event, ui) {      	return false;   	}});

В контроллер добавлены: 1) В insert(), update(). delete() и copy()

			if (isset($this->request->get['filter_manufacturer_name'])) {				$url .= '&filter_manufacturer_name=' . urlencode(html_entity_decode($this->request->get['filter_manufacturer_name'], ENT_QUOTES, 'UTF-8'));			}			if (isset($this->request->get['filter_manufacturer_id'])) {				$url .= '&filter_manufacturer_id=' . urlencode(html_entity_decode($this->request->get['filter_manufacturer_id'], ENT_QUOTES, 'UTF-8'));			}
			if (isset($this->request->get['filter_manufacturer_name'])) {				$url .= '&filter_manufacturer_name=' . urlencode(html_entity_decode($this->request->get['filter_manufacturer_name'], ENT_QUOTES, 'UTF-8'));			}			if (isset($this->request->get['filter_manufacturer_id'])) {				$url .= '&filter_manufacturer_id=' . urlencode(html_entity_decode($this->request->get['filter_manufacturer_id'], ENT_QUOTES, 'UTF-8'));			}
			if (isset($this->request->get['filter_manufacturer_name'])) {				$url .= '&filter_manufacturer_name=' . urlencode(html_entity_decode($this->request->get['filter_manufacturer_name'], ENT_QUOTES, 'UTF-8'));			}			if (isset($this->request->get['filter_manufacturer_id'])) {				$url .= '&filter_manufacturer_id=' . urlencode(html_entity_decode($this->request->get['filter_manufacturer_id'], ENT_QUOTES, 'UTF-8'));			}
			if (isset($this->request->get['filter_manufacturer_name'])) {				$url .= '&filter_manufacturer_name=' . urlencode(html_entity_decode($this->request->get['filter_manufacturer_name'], ENT_QUOTES, 'UTF-8'));			}			if (isset($this->request->get['filter_manufacturer_id'])) {				$url .= '&filter_manufacturer_id=' . urlencode(html_entity_decode($this->request->get['filter_manufacturer_id'], ENT_QUOTES, 'UTF-8'));			}

В getList():

		$this->load->model('catalog/manufacturer');	
		if (isset($this->request->get['filter_manufacturer_name'])) {			$filter_manufacturer_name = $this->request->get['filter_manufacturer_name'];		} else {			$filter_manufacturer_name = null;		}		if (isset($this->request->get['filter_manufacturer_id'])) {			$filter_manufacturer_id = $this->request->get['filter_manufacturer_id'];		} else {			$filter_manufacturer_id = null;		}
		if (isset($this->request->get['filter_manufacturer_name'])) {			$url .= '&filter_manufacturer_name=' . $this->request->get['filter_manufacturer_name'];		}		if (isset($this->request->get['filter_manufacturer_id'])) {			$url .= '&filter_manufacturer_id=' . $this->request->get['filter_manufacturer_id'];		}

Часть контроллера привожу полностью, чтбы понятно было, что это за кусок кода (та же grtList())

		$this->data['insert'] = $this->url->link('catalog/product/insert', 'token=' . $this->session->data['token'] . $url, 'SSL');		$this->data['copy'] = $this->url->link('catalog/product/copy', 'token=' . $this->session->data['token'] . $url, 'SSL');			$this->data['delete'] = $this->url->link('catalog/product/delete', 'token=' . $this->session->data['token'] . $url, 'SSL');    			$this->data['products'] = array();		$data = array(			'filter_product_id'	  => $filter_product_id,			'filter_sku'	    => $filter_sku,				'filter_name'	    => $filter_name, 			'filter_model'	  => $filter_model,                                                'filter_manufacturer_name'	  => $filter_manufacturer_name,					'filter_manufacturer_id'	  => $filter_manufacturer_id,						'filter_price'	  => $filter_price,			'filter_quantity' => $filter_quantity,			'filter_status'   => $filter_status,			'sort'            => $sort,			'order'           => $order,			'start'           => ($page - 1) * $this->config->get('config_admin_limit'),			'limit'           => $this->config->get('config_admin_limit')		);				$this->load->model('tool/image');		    $product_total = $this->model_catalog_product->getTotalProducts($data);					$results = $this->model_catalog_product->getProducts($data);		foreach ($results as $result) {	    if(!empty($result['manufacturer_id'])) {		  $manufacturer = $this->model_catalog_manufacturer->getManufacturer($result['manufacturer_id']);  	  $vendor = $manufacturer['name'];}	  else {	  $vendor = 'No Name';	  }		  $vendor_id = $result['manufacturer_id'];  			$action = array();						$action[] = array(				'text' => $this->language->get('text_edit'),				'href' => $this->url->link('catalog/product/update', 'token=' . $this->session->data['token'] . '&product_id=' . $result['product_id'] . $url, 'SSL')			);						if ($result['image'] && file_exists(DIR_IMAGE . $result['image'])) {				$image = $this->model_tool_image->resize($result['image'], 40, 40);			} else {				$image = $this->model_tool_image->resize('no_image.jpg', 40, 40);			}				$special = false;						$product_specials = $this->model_catalog_product->getProductSpecials($result['product_id']);					foreach ($product_specials  as $product_special) {				if (($product_special['date_start'] == '0000-00-00' || $product_special['date_start'] < date('Y-m-d')) && ($product_special['date_end'] == '0000-00-00' || $product_special['date_end'] > date('Y-m-d'))) {					$special = $product_special['price'];								break;				}								}	      		$this->data['products'][] = array(				'product_id' => $result['product_id'],				'sku'        => $result['sku'],				'name'       => $result['name'],				'model'      => $result['model'],				'manufacturer_name'     => $vendor,				'manufacturer_id'     => $vendor_id,				'price'      => $result['price'],				'special'    => $special,				'image'      => $image,				'quantity'   => $result['quantity'],				'status'     => ($result['status'] ? $this->language->get('text_enabled') : $this->language->get('text_disabled')),				'selected'   => isset($this->request->post['selected']) && in_array($result['product_id'], $this->request->post['selected']),				'action'     => $action			);    	}
    $this->data['column_vendor'] = $this->language->get('column_vendor');    $this->data['column_vendor_id'] = $this->language->get('column_vendor_id');
    if (isset($this->request->get['filter_manufacturer_name'])) {			$url .= '&filter_manufacturer_name=' . urlencode(html_entity_decode($this->request->get['filter_manufacturer_name'], ENT_QUOTES, 'UTF-8'));		}		if (isset($this->request->get['filter_manufacturer_id'])) {			$url .= '&filter_manufacturer_id=' . urlencode(html_entity_decode($this->request->get['filter_manufacturer_id'], ENT_QUOTES, 'UTF-8'));		}
    $this->data['sort_manufacturer_name'] = $this->url->link('catalog/product', 'token=' . $this->session->data['token'] . '&sort=p.manufacturer_name' . $url, 'SSL');     $this->data['sort_manufacturer_id'] = $this->url->link('catalog/product', 'token=' . $this->session->data['token'] . '&sort=p.manufacturer_id' . $url, 'SSL');
    if (isset($this->request->get['filter_manufacturer_name'])) {			$url .= '&filter_manufacturer_name=' . urlencode(html_entity_decode($this->request->get['filter_manufacturer_name'], ENT_QUOTES, 'UTF-8'));		}		if (isset($this->request->get['filter_manufacturer_id'])) {			$url .= '&filter_manufacturer_id=' . urlencode(html_entity_decode($this->request->get['filter_manufacturer_id'], ENT_QUOTES, 'UTF-8'));		}
    $this->data['filter_manufacturer_name'] = $filter_manufacturer_name;    $this->data['filter_manufacturer_id'] = $filter_manufacturer_id;

В getForm():

		if (isset($this->request->get['filter_manufacturer_name'])) {			$url .= '&filter_manufacturer_name=' . urlencode(html_entity_decode($this->request->get['filter_manufacturer_name'], ENT_QUOTES, 'UTF-8'));		}		if (isset($this->request->get['filter_manufacturer_id'])) {			$url .= '&filter_manufacturer_id=' . urlencode(html_entity_decode($this->request->get['filter_manufacturer_id'], ENT_QUOTES, 'UTF-8'));		}

В autocomplete():

if (isset($this->request->get['filter_product_id']) || isset($this->request->get['filter_sku']) || isset($this->request->get['filter_name']) || isset($this->request->get['filter_model']) || isset($this->request->get['filter_manufacturer_name']) || isset($this->request->get['filter_manufacturer_id']) || isset($this->request->get['filter_category_id'])) {			$this->load->model('catalog/product');			$this->load->model('catalog/option');			$this->load->model('catalog/manufacturer');	
			if (isset($this->request->get['filter_manufacturer_name'])) {			$filter_manufacturer_name = $this->request->get['filter_manufacturer_name'];			} else {				$filter_manufacturer_name = '';			}			if (isset($this->request->get['filter_manufacturer_id'])) {			$filter_manufacturer_id = $this->request->get['filter_manufacturer_id'];			} else {				$filter_manufacturer_id = '';			}
			$data = array(				'filter_product_id'  => $filter_product_id,				'filter_sku'  => $filter_sku,							'filter_name'  => $filter_name,				'filter_model' => $filter_model,								'filter_manufacturer_name' => $filter_manufacturer_name,				'filter_manufacturer_id' => $filter_manufacturer_id,								'start'        => 0,				'limit'        => $limit			);
$results = $this->model_catalog_product->getProducts($data);			foreach ($results as $result) {    if(!empty($result['manufacturer_id'])) {		  $manufacturer = $this->model_catalog_manufacturer->getManufacturer($result['manufacturer_id']);	  $vendor = $manufacturer['name'];}	  else {	  $vendor = 'No Name';  }				$option_data = array();
$json[] = array(					'product_id' => $result['product_id'],					'sku' => $result['sku'],					'name'       => strip_tags(html_entity_decode($result['name'], ENT_QUOTES, 'UTF-8')),						'model'      => $result['model'],					'manufacturer_name'     => $vendor,					'manufacturer_id'     => $result['manufacturer_id'],									'option'     => $option_data,					'price'      => $result['price']				);

Результат виден на картинке: при выборе любого символа в качестве первой буквы наименования производителя - выводятся все(!) производители. Почему так? Сортировка по manufacturer_name выдает ошибку (ну это понятно, запрос формируется с manufacturer_name, который в product_id отсутствует).

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


Пардонте, вот результат: 

Кто-то может подсказку из зала дать? Уже снится, как autocomplete передает term и возвращает response  :-D

oc6.jpg

post-7857-0-17331300-1384192436_thumb.jpg

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


Я специально alert-ы оставил в комментах. Я когда проверял автокомплит, алерты эти выкидывали ровно то, что видно на картинке, а именно - всех произыодителей, поочередно выводя их имя и ид. 

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


Как-то я модель упустил из виду... 

		if (!empty($data['filter_manufacturer_id'])) {			$sql .= " AND p.manufacturer_id LIKE '" . $this->db->escape($data['filter_manufacturer_id']) . "%'";		}		if (!empty($data['filter_manufacturer_name'])) {			$sql .= " AND p.manufacturer_name LIKE '" . $this->db->escape($data['filter_manufacturer_name']) . "%'";		}

Жаль, что тема интереса не вызвала... Приходится шишки набивать.

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


  • 4 weeks later...

Говоря прямо, если возник спрос на такой фильтр, значит это не просто прихоть, а необходимость. И совсем его хоронить не буду. Просто переключился на другие вопросы. Ноябрь - да, последнее пока что изменение. Недоделанным осталась сортировка по производителю: autocomplete выводит весь список производителей, вместо нужного. Тема отложена, т.к. занят формой регистрации. Это фронтенд, он требует большего внимания. 

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


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

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

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

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

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

Вхід

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

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

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

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

Important Information

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