Когда в Price.ua, в который я экспортировал товары через модуль яндекс-маркета у меня полбюджета съели переходы на дешевые товары, конверсия от которых не перекрывала стоимость этих переходов, возникла задача выключать из выдачи в фид неконкурентные по цене, или по иным параметрам товары. За два часа работы напильником вот что вышло.
Так как движок мне достался уже с большим кол-вом допилов и изменений. Привожу последовательность действий с детальным описанием. Файлы выкладывать бесполезно - ибо пиленные.
ШАГ 0 - САМЫЙ ГЛАВНЫЙ
СДЕЛАЙТЕ БЕКАПЫ РЕДАКТИРУЕМЫХ ФАЙЛОВ!
Шаг 1. Нам необходимо добавить в базе данных ключ по которому будет определятся отображение товара в ленте.
Заходим в базу и добавляем в таблицу oc_product поле xml_status.
для этого логинимся в mysql и выполняем команду
ALTER TABLE `oc_product` ADD `xml_status` TINYINT( 1 ) DEFAULT '1' NOT NULL
Шаг 2. Открываем admin\catalog\model\catalog\product.php
Находим
Public function addProduct($data) {
$this->db->query("INSERT INTO " . DB_PREFIX . "product (model, sku, location, quantity, minimum, subtract, stock_status_id, date_available, manufacturer_id, shipping, price, cost, weight, weight_class_id, length, width, height, length_class_id, status, tax_class_id, sort_order, date_added, main_category_id) VALUES ('" . $this->db->escape($data['model']) . "', '" . $this->db->escape($data['sku']) . "', '" . $this->db->escape($data['location']) . "', '" . (int)$data['quantity'] . "', '" . (int)$data['minimum'] . "', '" . (int)$data['subtract'] . "', '" . (int)$data['stock_status_id'] . "', '" . $this->db->escape($data['date_available']) . "', '" . (int)$data['manufacturer_id'] . "', '" . (int)$data['shipping'] . "', '" . (float)$data['price'] . "', '" . (float)$data['cost'] . "', '" . (float)$data['weight'] . "', '" . (int)$data['weight_class_id'] . "', '" . (float)$data['length'] . "', '" . (float)$data['width'] . "', '" . (float)$data['height'] . "', '" . (int)$data['length_class_id'] . "', '" . (int)$data['status'] . "', '" . (int)$data['tax_class_id'] . "', '" . (int)$data['sort_order'] . "', NOW(), " . ((int)$data['main_category_id'] > 0 ? (int)$data['main_category_id'] : 'NULL') . ")");
Меняем на:
Public function addProduct($data) {
$this->db->query("INSERT INTO " . DB_PREFIX . "product (model, sku, location, quantity, minimum, subtract, stock_status_id, date_available, manufacturer_id, shipping, price, cost, weight, weight_class_id, length, width, height, length_class_id, status, tax_class_id, sort_order, date_added, main_category_id) VALUES ('" . $this->db->escape($data['model']) . "', '" . $this->db->escape($data['sku']) . "', '" . $this->db->escape($data['location']) . "', '" . (int)$data['quantity'] . "', '" . (int)$data['minimum'] . "', '" . (int)$data['subtract'] . "', '" . (int)$data['stock_status_id'] . "', '" . $this->db->escape($data['date_available']) . "', '" . (int)$data['manufacturer_id'] . "', '" . (int)$data['shipping'] . "', '" . (float)$data['price'] . "', '" . (float)$data['cost'] . "', '" . (float)$data['weight'] . "', '" . (int)$data['weight_class_id'] . "', '" . (float)$data['length'] . "', '" . (float)$data['width'] . "', '" . (float)$data['height'] . "', '" . (int)$data['length_class_id'] . "', '" . (int)$data['status'] . "', '" . (int)$data['tax_class_id'] . "', '" . (int)$data['sort_order'] . "', NOW(), " . ((int)$data['main_category_id'] > 0 ? (int)$data['main_category_id'] : 'NULL') . ",'1'". ")");
Идем дальше, находим
$this->db->query("UPDATE " . DB_PREFIX . "product SET model = '" . $this->db->escape($data['model']) . "', sku = '" . $this->db->escape($data['sku']) . "', location = '" . $this->db->escape($data['location']) . "', quantity = '" . (int)$data['quantity'] . "', minimum = '" . (int)$data['minimum'] . "', subtract = '" . (int)$data['subtract'] . "', stock_status_id = '" . (int)$data['stock_status_id'] . "', date_available = '" . $this->db->escape($data['date_available']) . "', manufacturer_id = '" . (int)$data['manufacturer_id'] . "', shipping = '" . (int)$data['shipping'] . "', price = '" . (float)$data['price'] . "', cost = '" . (float)$data['cost'] . "', weight = '" . (float)$data['weight'] . "', weight_class_id = '" . (int)$data['weight_class_id'] . "', length = '" . (float)$data['length'] . "', width = '" . (float)$data['width'] . "', height = '" . (float)$data['height'] . "', length_class_id = '" . (int)$data['length_class_id'] . "', status = '" . (int)$data['status'] . "', tax_class_id = '" . (int)$data['tax_class_id'] . "', sort_order = '" . (int)$data['sort_order'] . "', date_modified = NOW(), main_category_id = " . ((int)$data['main_category_id'] > 0 ? (int)$data['main_category_id'] : 'NULL') . " WHERE product_id = '" . (int)$product_id . "'");
Меняем на
public function editProduct($product_id, $data) {
$this->db->query("UPDATE " . DB_PREFIX . "product SET model = '" . $this->db->escape($data['model']) . "', sku = '" . $this->db->escape($data['sku']) . "', location = '" . $this->db->escape($data['location']) . "', quantity = '" . (int)$data['quantity'] . "', minimum = '" . (int)$data['minimum'] . "', subtract = '" . (int)$data['subtract'] . "', stock_status_id = '" . (int)$data['stock_status_id'] . "', date_available = '" . $this->db->escape($data['date_available']) . "', manufacturer_id = '" . (int)$data['manufacturer_id'] . "', shipping = '" . (int)$data['shipping'] . "', price = '" . (float)$data['price'] . "', cost = '" . (float)$data['cost'] . "', weight = '" . (float)$data['weight'] . "', weight_class_id = '" . (int)$data['weight_class_id'] . "', length = '" . (float)$data['length'] . "', width = '" . (float)$data['width'] . "', height = '" . (float)$data['height'] . "', length_class_id = '" . (int)$data['length_class_id'] . "', status = '" . (int)$data['status'] . "', tax_class_id = '" . (int)$data['tax_class_id']. "', xml_status = '" . (int)$data['xml_status'] . "', sort_order = '" . (int)$data['sort_order'] . "', date_modified = NOW(), main_category_id = " . ((int)$data['main_category_id'] > 0 ? (int)$data['main_category_id'] : 'NULL') . " WHERE product_id = '" . (int)$product_id . "'");
Идем еще дальше в районе строки 305 находим: $data['status'] = '0';
дописываем после: $data['xml_status'] = '1';
Спускаемся еще ниже находим функцию public function changeStatusProducts($products, $status) {
После нее добавляем точно такую же, только для статуса XML.
public function changeXMLStatusProducts($products, $xml_status) {
function check_int($a) { return (int)$a; }
$arr_products = array_map('check_int', $products);
$products = implode("' OR product_id = '", $arr_products);
$this->db->query("UPDATE " . DB_PREFIX . "product SET xml_status = '" . (int)(bool)$xml_status . "' WHERE product_id = '" . $products . "'");
}
C Моделью закончено.
Шаг 3. Открываем admin\controller\catalog\product.php
Теперь переходим к контроллеру.
Находим
$this->data['products'][] = array(
'product_id' => $result['product_id'],
'name' => $result['name'],
'model' => $result['model'],
'price' => $result['price'],
'special' => $special['price'],
'image' => $image,
'quantity' => $result['quantity'],
'status' => ($result['status'] ? $this->language->get('text_enabled') : $this->language->get('text_disabled')),
Добавляем после:
'xml_status' => ($result['status'] ? $this->language->get('text_enabled') : $this->language->get('text_disabled')),
Копируем вот это:
if (isset($this->request->post['status'])) {
$this->data['status'] = $this->request->post['status'];
} else if (isset($product_info)) {
$this->data['status'] = $product_info['status'];
} else {
$this->data['status'] = 1;
}
Меняя на:
if (isset($this->request->post['xml_status'])) {
$this->data['xml_status'] = $this->request->post['xml_status'];
} else if (isset($product_info)) {
$this->data['xml_status'] = $product_info['xml_status'];
} else {
$this->data['xml_status'] = 1;
}
Шаг 4.
Теперь переходим к шаблону карточки товара.
admin\view\template\catalog\product_form.tpl
и после
<tr>
<td><?php echo $entry_status; ?></td>
<td><select name="status">
<?php if ($status) { ?>
<option value="1" selected="selected"><?php echo $text_enabled; ?></option>
<option value="0"><?php echo $text_disabled; ?></option>
<?php } else { ?>
<option value="1"><?php echo $text_enabled; ?></option>
<option value="0" selected="selected"><?php echo $text_disabled; ?></option>
<?php } ?>
</select></td>
</tr>
Добавляем
<tr>
<td><?php echo 'xml_status' ?></td>
<td><select name="xml_status">
<?php if ($xml_status) { ?>
<option value="1" selected="selected"><?php echo $text_enabled; ?></option>
<option value="0"><?php echo $text_disabled; ?></option>
<?php } else { ?>
<option value="1"><?php echo $text_enabled; ?></option>
<option value="0" selected="selected"><?php echo $text_disabled; ?></option>
<?php } ?>
</select></td>
</tr>
В силу врожденной лени мне было неохота еще делать дописку в языковой файл, но если кто хочет, может поменять
<td><?php echo 'xml_status' ?></td> на <td><?php echo $xml_status; ?></td>, добавив соответствующую строку в языковом файле!
И последний штрих идем в \catalog\model\export\
Открываем yandex_market.php и добавляем условие проверки статуса вывода товара в ленте.
Меняя всю функцию getProduct на
public function getProduct($in_stock = true, $vendor_required = true) {
$query = $this->db->query("SELECT p.*, pd.name, pd.description, m.name AS manufacturer, IFNULL(p.main_category_id, p2c.category_id) AS category_id FROM " . DB_PREFIX . "product p JOIN " . DB_PREFIX . "product_to_category AS p2c ON (p.product_id = p2c.product_id) " . ($vendor_required ? '' : 'LEFT ') . "JOIN " . DB_PREFIX . "manufacturer m ON (p.manufacturer_id = m.manufacturer_id) 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) WHERE p2s.store_id = '" . (int)$this->config->get('config_store_id') . "' AND pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND p.date_available <= NOW() AND p.status = '1' AND p.xml_status = '1' " . ($in_stock ? " AND p.quantity > '0'" : '') . " GROUP BY p.product_id");
Потом можно зайти в базу и sql-запросами быренько поставить массово статусы
например вот так
UPDATE `oc_product` SET `xml_status`=1
UPDATE `oc_product` SET `xml_status`=0 WHERE `price`<300
Выключаем все товары, цена которых ниже 300
или выключить все товары определенной категории
UPDATE `oc_product` SET `xml_status`=0 WHERE `main_category_id`=1
в планах сделать дописку, чтобы это можно было делать на-лету из админки. Но, так как, дописка нужна была в экстренном порядке и полностью на сегодня реализует необходимые мне функции пока руки не дошли.
Необессудьте за сумбурность, по всем вопросам пишите в личку.