Advertisement
Guest User

Untitled

a guest
Jul 27th, 2017
415
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 435.22 KB | None | 0 0
  1. <?php
  2.  
  3. class ModelExtensionExchange1c extends Model {
  4.  
  5.     private $STORE_ID       = 0;
  6.     private $LANG_ID        = 0;
  7.     private $FULL_IMPORT    = false;
  8.     private $NOW            = '';
  9.     private $TAB_FIELDS     = array();
  10.     private $ERROR          = "";
  11.     private $ERROR_NO       = '';
  12.  
  13.  
  14.  
  15.     /**
  16.      * ****************************** ОБЩИЕ ФУНКЦИИ ******************************
  17.      */
  18.  
  19.  
  20.     /**
  21.      * Номер текущей версии
  22.      *
  23.      */
  24.     public function version() {
  25.         return "1.6.3.5";
  26.     } // version()
  27.  
  28.  
  29.     /**
  30.      * ver 1
  31.      * update 2017-04-08
  32.      * Пишет ошибку в лог
  33.      * Возвращает текст ошибки
  34.      */
  35.     private function error() {
  36.         $this->log($this->ERROR);
  37.         return $this->ERROR;
  38.     } // error()
  39.  
  40.  
  41.     /**
  42.      * Пишет информацию в файл журнала
  43.      *
  44.      * @param   int             Уровень сообщения
  45.      * @param   string,object   Сообщение или объект
  46.      */
  47.     private function log($message, $level = 1, $line = '') {
  48.         if ($level <= $this->config->get('exchange1c_log_level')) {
  49.  
  50.             $memory_usage = '';
  51.             if ($this->config->get('exchange1c_log_memory_use_view') == 1) {
  52.                 $memory_size = memory_get_usage() / 1024 / 1024;
  53.                 $memory_usage = sprintf("%.3f", $memory_size) . " Mb | ";
  54.             }
  55.  
  56.             if ($this->config->get('exchange1c_log_debug_line_view') == 1) {
  57.                 if (!$line) {
  58.                     list ($di) = debug_backtrace();
  59.                     $line = sprintf("%04s",$di["line"]) . " | ";
  60.                 } else {
  61.                     $line .= " | ";
  62.                 }
  63.             } else {
  64.                 $line = '';
  65.             }
  66.  
  67.             if (is_array($message) || is_object($message)) {
  68.                 $this->log->write($memory_usage . $line);
  69.                 $this->log->write(print_r($message, true));
  70.             } else {
  71.                 $this->log->write($memory_usage . $line . $message);
  72.             }
  73.         }
  74.     } // log()
  75.  
  76.  
  77.     /**
  78.      * Конвертирует XML в массив
  79.      *
  80.      * @param   array               data
  81.      * @param   SimpleXMLElement    XML
  82.      * @return  XML
  83.      */
  84.     function array_to_xml($data, &$xml) {
  85.         foreach($data as $key => $value) {
  86.             if (is_array($value)) {
  87.                 if (!is_numeric($key)) {
  88.                     $subnode = $xml->addChild(preg_replace('/\d/', '', $key));
  89.                     $this->array_to_xml($value, $subnode);
  90.                 }
  91.             }
  92.             else {
  93.                 $xml->addChild($key, $value);
  94.             }
  95.         }
  96.         return $xml;
  97.     } // array_to_xml()
  98.  
  99.  
  100.     /**
  101.      * ver 2
  102.      * update 2017-05-28
  103.      * Очистка лога
  104.      */
  105.     public function clearLog() {
  106.  
  107.         $file = DIR_LOGS . $this->config->get('config_error_filename');
  108.         $handle = fopen($file, 'w+');
  109.         fclose($handle);
  110.  
  111.     } // clearLog()
  112.  
  113.  
  114.     /**
  115.      * Возвращает строку даты
  116.      *
  117.      * @param   string  var
  118.      * @return  string
  119.      */
  120.     function format($var){
  121.         return preg_replace_callback(
  122.             '/\\\u([0-9a-fA-F]{4})/',
  123.             create_function('$match', 'return mb_convert_encoding("&#" . intval($match[1], 16) . ";", "UTF-8", "HTML-ENTITIES");'),
  124.             json_encode($var)
  125.         );
  126.     } // format()
  127.  
  128.  
  129.     /**
  130.      * Выполняет запрос, записывает в лог в режим отладки и возвращает результат
  131.      */
  132.     function query($sql){
  133.  
  134.         if ($this->config->get('exchange1c_log_debug_line_view') == 1) {
  135.             list ($di) = debug_backtrace();
  136.             $line = sprintf("%04s",$di["line"]);
  137.         } else {
  138.             $line = '';
  139.         }
  140.  
  141.         $this->log($sql, 3, $line);
  142.         return $this->db->query($sql);
  143.  
  144.     } // query()
  145.  
  146.  
  147.     /**
  148.      * ver 2
  149.      * update 2017-04-06
  150.      * Проверим файл на стандарт Commerce ML
  151.      */
  152.     private function checkCML($xml) {
  153.  
  154.         if ($xml['ВерсияСхемы']) {
  155.             $this->log("Версия XML: " . (string)$xml['ВерсияСхемы'], 2);
  156.         } else {
  157.             $this->ERROR = "Файл не является стандартом Commerce ML!";
  158.             $this->ERROR_NO = "0101";
  159.             return false;
  160.         }
  161.         return true;
  162.  
  163.     } // checkCML()
  164.  
  165.  
  166.     /**
  167.      * ver 2
  168.      * update 2017-05-28
  169.      * Очищает базу
  170.      */
  171.     public function cleanDB() {
  172.  
  173.         $this->log("Очистка базы данных...",2);
  174.         // Удаляем товары
  175.         $result = "";
  176.  
  177.         $this->log("[i] Очистка таблиц товаров...",2);
  178.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product`');
  179.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_attribute`');
  180.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_description`');
  181.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_discount`');
  182.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_image`');
  183.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_option`');
  184.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_option_value`');
  185.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_related`');
  186.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_reward`');
  187.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_special`');
  188.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_quantity`');
  189.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_1c`');
  190.         $result .=  "Товары\n";
  191.  
  192.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_category`');
  193.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_download`');
  194.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_layout`');
  195.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_store`');
  196.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'option_value_description`');
  197.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'option_description`');
  198.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'option_value`');
  199.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'order_option`');
  200.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'option`');
  201.         $this->query('DELETE FROM `' . DB_PREFIX . 'url_alias` WHERE `query` LIKE "product_id=%"');
  202.         $result .=  "Опции товаров\n";
  203.  
  204.         // Очищает таблицы категорий
  205.         $this->log("Очистка таблиц категорий...",2);
  206.         $this->query('TRUNCATE TABLE ' . DB_PREFIX . 'category');
  207.         $this->query('TRUNCATE TABLE ' . DB_PREFIX . 'category_description');
  208.         $this->query('TRUNCATE TABLE ' . DB_PREFIX . 'category_to_store');
  209.         $this->query('TRUNCATE TABLE ' . DB_PREFIX . 'category_to_layout');
  210.         $this->query('TRUNCATE TABLE ' . DB_PREFIX . 'category_path');
  211.         $this->query('TRUNCATE TABLE ' . DB_PREFIX . 'category_to_1c');
  212.         $this->query('DELETE FROM `' . DB_PREFIX . 'url_alias` WHERE `query` LIKE "category_id=%"');
  213.         $result .=  "Категории\n";
  214.  
  215.         // Очищает таблицы от всех производителей
  216.         $this->log("Очистка таблиц производителей...",2);
  217.         $this->query('TRUNCATE TABLE ' . DB_PREFIX . 'manufacturer');
  218.         $this->query('TRUNCATE TABLE ' . DB_PREFIX . 'manufacturer_to_1c');
  219.         $query = $this->query("SHOW TABLES FROM `" . DB_DATABASE . "` WHERE `Tables_in_" . DB_DATABASE . "` LIKE '" . DB_PREFIX . "manufacturer_description'");
  220.         //$query = $this->db->query("SHOW TABLES FROM " . DB_DATABASE . " LIKE '" . DB_PREFIX . "manufacturer_description'");
  221.         if ($query->num_rows) {
  222.             $this->query('TRUNCATE TABLE ' . DB_PREFIX . 'manufacturer_description');
  223.         }
  224.         $this->query('TRUNCATE TABLE ' . DB_PREFIX . 'manufacturer_to_store');
  225.         $this->query('DELETE FROM `' . DB_PREFIX . 'url_alias` WHERE `query` LIKE "manufacturer_id=%"');
  226.         $result .=  "Производители\n";
  227.  
  228.         // Очищает атрибуты
  229.         $this->log("Очистка таблиц атрибутов...",2);
  230.         $this->query("TRUNCATE TABLE `" . DB_PREFIX . "attribute`");
  231.         $this->query("TRUNCATE TABLE `" . DB_PREFIX . "attribute_description`");
  232.         $this->query("TRUNCATE TABLE `" . DB_PREFIX . "attribute_to_1c`");
  233.         $this->query("TRUNCATE TABLE `" . DB_PREFIX . "attribute_group`");
  234.         $this->query("TRUNCATE TABLE `" . DB_PREFIX . "attribute_group_description`");
  235.         $query = $this->query("SHOW TABLES FROM `" . DB_DATABASE . "` WHERE `Tables_in_" . DB_DATABASE . "` LIKE '" . DB_PREFIX . "attribute_value'");
  236.         if ($query->num_rows) {
  237.             $this->log("Очистка значения атрибутов",2);
  238.             $this->query('TRUNCATE TABLE ' . DB_PREFIX . 'attribute_value');
  239.             $result .=  "Значения атрибутов\n";
  240.         }
  241.         $result .=  "Атрибуты\n";
  242.  
  243.         // Удаляем все цены
  244.         $this->log("Очистка цен...",2);
  245.         $this->query("TRUNCATE TABLE `" . DB_PREFIX . "product_price`");
  246.         $result .=  "Цены товаров\n";
  247.  
  248.         // Удаляем все характеристики
  249.         $this->log("Очистка характеристик...",2);
  250.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_feature`');
  251.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_feature_value`');
  252.         $result .=  "Характеристики\n";
  253.  
  254.         // Удаляем связи с магазинами
  255.         $this->log("Очистка связей с магазинами...",2);
  256.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'store_to_1c`');
  257.         $result .=  "Связи с магазинами\n";
  258.  
  259.         // Удаляем связи с единицами измерений
  260.         $this->log("Очистка связей с единицами измерений...",2);
  261.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'unit_to_1c`');
  262.         $result .=  "Связи с единицами измерений\n";
  263.  
  264.         // Единицы измерений товара
  265.         $query = $this->query("SHOW TABLES FROM `" . DB_DATABASE . "` WHERE `Tables_in_" . DB_DATABASE . "` LIKE '" . DB_PREFIX . "product_unit'");
  266.         if ($query->num_rows) {
  267.             $this->log("Очистка единиц измерений товаров",2);
  268.             $this->query('TRUNCATE TABLE ' . DB_PREFIX . 'product_unit');
  269.             $result .=  "Единицы измерений товаров\n";
  270.         }
  271.  
  272.         // Доработка от SunLit (Skype: strong_forever2000)
  273.         // Удаляем все отзывы
  274.         $this->log("Очистка отзывов...",2);
  275.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'review`');
  276.         $result .=  "Отзывы\n";
  277.  
  278.         if ($this->config->get('exchange1c_flush_log') == 1) {
  279.             $this->clearLog();
  280.         }
  281.  
  282.         return $result;
  283.  
  284.     } // cleanDB()
  285.  
  286.  
  287.     /**
  288.      * Очищает базу
  289.      */
  290.     public function cleanLinks() {
  291.         // Удаляем связи
  292.         $result = "";
  293.  
  294.         $this->log("[i] Очистка таблиц товаров...", 2);
  295.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'product_to_1c`');
  296.         $result .=  "Таблица связей товаров '" . DB_PREFIX . "product_to_1c'\n";
  297.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'category_to_1c`');
  298.         $result .=  "Таблица связей категорий '" . DB_PREFIX . "category_to_1c'\n";
  299.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'manufacturer_to_1c`');
  300.         $result .=  "Таблица связей производителей '" . DB_PREFIX . "manufacturer_to_1c'\n";
  301.         $this->query("TRUNCATE TABLE `" . DB_PREFIX . "attribute_to_1c`");
  302.         $result .=  "Таблица связей атрибутов '" . DB_PREFIX . "attribute_to_1c'\n";
  303.         $this->query('TRUNCATE TABLE `' . DB_PREFIX . 'store_to_1c`');
  304.         $result .=  "Таблица связей с магазинами\n";
  305.  
  306.         return $result;
  307.  
  308.     } // cleanLinks()
  309.  
  310.  
  311.     /**
  312.      * Возвращает информацию о синхронизированных объектов с 1С товарок, категорий, атрибутов
  313.      */
  314.     public function linksInfo() {
  315.  
  316.         $data = array();
  317.         $query = $this->query('SELECT count(*) as num FROM `' . DB_PREFIX . 'product_to_1c`');
  318.         $data['product_to_1c'] = $query->row['num'];
  319.         $query = $this->query('SELECT count(*) as num FROM `' . DB_PREFIX . 'category_to_1c`');
  320.         $data['category_to_1c'] = $query->row['num'];
  321.         $query = $this->query('SELECT count(*) as num FROM `' . DB_PREFIX . 'manufacturer_to_1c`');
  322.         $data['manufacturer_to_1c'] = $query->row['num'];
  323.         $query = $this->query('SELECT count(*) as num FROM `' . DB_PREFIX . 'attribute_to_1c`');
  324.         $data['attribute_to_1c'] = $query->row['num'];
  325.  
  326.         return $data;
  327.  
  328.     } // linksInfo()
  329.  
  330.  
  331.     /**
  332.      * ver 2
  333.      * update 2017-04-05
  334.      * Удаляет все связи с товаром
  335.      */
  336.     public function deleteLinkProduct($product_id) {
  337.  
  338.         $this->log("Удаление связей у товара product_id: " . $product_id, 2);
  339.  
  340.         // Удаляем линк
  341.         if ($product_id){
  342.             $this->query("DELETE FROM `" .  DB_PREFIX . "product_to_1c` WHERE `product_id` = " . (int)$product_id);
  343.             $this->log("Удалена связь с товаром ID - GUID", 2);
  344.         }
  345.  
  346.         $this->load->model('catalog/product');
  347.  
  348.         // Удаляет связи и сами файлы
  349.         $product = $this->model_catalog_product->getProduct($product_id);
  350.         if ($product['image']) {
  351.             // Удаляем только в папке import_files
  352.             if (substr($product['image'], 0, 12) == "import_files") {
  353.                 unlink(DIR_IMAGE . $product['image']);
  354.                 $this->log("Удален файл основной картинки: " . $product['image'], 2);
  355.             }
  356.         }
  357.  
  358.         // Удаляет связи и сами файлы
  359.         $productImages = $this->model_catalog_product->getProductImages($product_id);
  360.         foreach ($productImages as $image) {
  361.             // Удаляем только в папке import_files
  362.             if (substr($image['image'], 0, 12) == "import_files") {
  363.                 unlink(DIR_IMAGE . $image['image']);
  364.                 $this->log("Удален файл дополнительной картинки: " . $image['image'],2);
  365.             }
  366.         }
  367.  
  368.         // Удалим характеристики
  369.         $this->query("DELETE FROM `" .  DB_PREFIX . "product_feature` WHERE `product_id` = " . $product_id);
  370.         $this->query("DELETE FROM `" .  DB_PREFIX . "product_feature_value` WHERE `product_id` = " . $product_id);
  371.         $this->log("Удалены характеристики", 2);
  372.  
  373.         // Удалим остатки
  374.         $this->query("DELETE FROM `" .  DB_PREFIX . "product_quantity` WHERE `product_id` = " . $product_id);
  375.         $this->log("Удалены остатки", 2);
  376.  
  377.         // Удалим единицы измерений
  378.         $this->query("DELETE FROM `" .  DB_PREFIX . "product_unit` WHERE `product_id` = " . $product_id);
  379.         $this->log("Удалены единицы измерения", 2);
  380.  
  381.         // Описания к картинкам
  382.         $this->query("DELETE FROM `" .  DB_PREFIX . "product_image_description` WHERE `product_id` = " . $product_id);
  383.         $this->log("Удалены описания к картинкам", 2);
  384.  
  385.     } // deleteLinkProduct()
  386.  
  387.  
  388.     /**
  389.      * ver 2
  390.      * update 2017-04-05
  391.      * Удаляет все связи у категории
  392.      */
  393.     public function deleteLinkCategory($category_id) {
  394.  
  395.         // Удаляем линк
  396.         if ($category_id){
  397.             $this->query("DELETE FROM `" .  DB_PREFIX . "category_to_1c` WHERE `category_id` = " . (int)$category_id);
  398.             $this->log("Удалена связь у категории category_id: " . $category_id,2);
  399.         }
  400.  
  401.     } //  deleteLinkCategory()
  402.  
  403.  
  404.     /**
  405.      * ver 2
  406.      * update 2017-04-05
  407.      * Удаляет все связи у производителя
  408.      */
  409.     public function deleteLinkManufacturer($manufacturer_id) {
  410.  
  411.         // Удаляем линк
  412.         if ($manufacturer_id){
  413.             $this->query("DELETE FROM `" .  DB_PREFIX . "manufacturer_to_1c` WHERE `manufacturer_id` = " . $manufacturer_id);
  414.             $this->log("Удалена связь у производителя manufacturer_id: " . $manufacturer_id,2);
  415.         }
  416.  
  417.     } //  deleteLinkManufacturer()
  418.  
  419.  
  420.     /**
  421.      * Создает события
  422.      */
  423.     public function setEvents() {
  424.  
  425.         // Установка событий
  426.         $this->load->model('extension/event');
  427.         // Удалим все события
  428.         $this->model_extension_event->deleteEvent('exchange1c');
  429.         // Добавим удаление связей при удалении товара
  430.         $this->model_extension_event->addEvent('exchange1c', 'pre.admin.product.delete', 'module/exchange1c/eventDeleteProduct');
  431.         // Добавим удаление связей при удалении категории
  432.         $this->model_extension_event->addEvent('exchange1c', 'pre.admin.category.delete', 'module/exchange1c/eventDeleteCategory');
  433.         // Добавим удаление связей при удалении Производителя
  434.         $this->model_extension_event->addEvent('exchange1c', 'pre.admin.manufacturer.delete', 'module/exchange1c/eventDeleteManufacturer');
  435.         // Добавим удаление связей при удалении Характеристики
  436.         $this->model_extension_event->addEvent('exchange1c', 'pre.admin.option.delete', 'module/exchange1c/eventDeleteOption');
  437.  
  438.     } // setEvents()
  439.  
  440.  
  441.     /**
  442.      * Получает language_id из code (ru, en, etc)
  443.      * Как ни странно, подходящей функции в API не нашлось
  444.      *
  445.      * @param   string
  446.      * @return  int
  447.      */
  448.     public function getLanguageId($lang) {
  449.  
  450.         if ($this->LANG_ID) {
  451.             return $this->LANG_ID;
  452.         }
  453.         $query = $this->query("SELECT `language_id` FROM `" . DB_PREFIX . "language` WHERE `code` = '" . $this->db->escape($lang) . "'");
  454.         $this->LANG_ID = $query->row['language_id'];
  455.         $this->log("Определен язык language_id: " . $this->LANG_ID, 2);
  456.         return $this->LANG_ID;
  457.  
  458.     } // getLanguageId()
  459.  
  460.  
  461.     /**
  462.      * ver 5
  463.      * update 2017-05-02
  464.      * Проверяет таблицы модуля
  465.      */
  466.     public function checkDB() {
  467.  
  468.         $tables_db = array();
  469.         $query = $this->query("SHOW TABLES FROM `" . DB_DATABASE . "`");
  470.         if ($query->num_rows) {
  471.             foreach ($query->rows as $table) {
  472.                 $tables_db[] = substr(array_shift($table), strlen(DB_PREFIX));
  473.             }
  474.         }
  475.  
  476.         $tables_module = array("product_to_1c","product_quantity","product_price","product_unit","category_to_1c","warehouse","product_feature","product_feature_value","store_to_1c","attribute_to_1c","manufacturer_to_1c","attribute_value","product_image_description");
  477.         $tables_diff = array_diff($tables_module, $tables_db);
  478.  
  479.         if ($tables_diff) {
  480.             $error = "Таблица(ы) " . implode(", ", $tables_diff) . " в базе отсутствует(ют)";
  481.             $this->log($error);
  482.             return $error;
  483.         }
  484.         return "";
  485.  
  486.     } // checkDB()
  487.  
  488.  
  489.     /**
  490.      * ver 2
  491.      * update 2017-04-05
  492.      * Формирует строку запроса при наличии переменной
  493.      */
  494.     private function setStrQuery($field_name, $type) {
  495.  
  496.         switch ($type){
  497.             case 'string':
  498.                 return isset($data[$field_name]) ? ", " . $field_name . " = '" . $this->db->escape($data[$field_name]) . "'" : "";
  499.             case 'int':
  500.                 return isset($data[$field_name]) ? ", " . $field_name . " = " . (int)$data[$field_name] : "";
  501.             case 'float':
  502.                 return isset($data[$field_name]) ? ", " . $field_name . " = " . (float)$data[$field_name] : "";
  503.         }
  504.         return "";
  505.  
  506.     } //setStrQuery()
  507.  
  508.  
  509.     /**
  510.      * Поиск guid товара по ID
  511.      */
  512.     public function getGuidByProductId($product_id) {
  513.  
  514.         $query = $this->query("SELECT `guid` FROM `" . DB_PREFIX . "product_to_1c` WHERE `product_id` = " . $product_id);
  515.         if ($query->num_rows) {
  516.             return $query->row['guid'];
  517.         }
  518.         return '';
  519.  
  520.     } // getGuidByProductId()
  521.  
  522.  
  523.     /**
  524.      * ****************************** ФУНКЦИИ ДЛЯ SEO ******************************
  525.      */
  526.  
  527.  
  528.     /**
  529.      * Устанавливает SEO URL (ЧПУ) для заданного товара
  530.      * @param   inf
  531.      * @param   string
  532.      */
  533.     private function setSeoURL($url_type, $element_id, $element_name) {
  534.  
  535.         // Проверка на одинаковые keyword
  536.         $keyword = $element_name;
  537.  
  538.         // Получим все названия начинающиеся на $element_name
  539.         $keywords = array();
  540.         $query = $this->query("SELECT `url_alias_id`,`keyword` FROM `" . DB_PREFIX . "url_alias` WHERE `query` <> '" . $url_type . "=" . $element_id . "' AND `keyword` LIKE '" . $this->db->escape($keyword) . "%'");
  541.         foreach ($query->rows as $row) {
  542.             $keywords[$row['url_alias_id']] = $row['keyword'];
  543.         }
  544.         // Проверим на дубли
  545.         $key = array_search($keyword, $keywords);
  546.         $num = 0;
  547.         while ($key) {
  548.             // Есть дубли
  549.             $num ++;
  550.             $keyword = $element_name . "-" . (string)$num;
  551.             $key = array_search($keyword, $keywords);
  552.             if ($num > 100) {
  553.                 $this->log("[!] больше 100 дублей!", 2);
  554.                 break;
  555.             }
  556.         }
  557.  
  558.         $query = $this->query("SELECT `url_alias_id`,`keyword` FROM `" . DB_PREFIX . "url_alias` WHERE `query` = '" . $url_type . "=" . $element_id . "'");
  559.         if ($query->num_rows) {
  560.             // Обновляем если только были изменения
  561.             $this->log("Старое keyword: " . $query->row['keyword'] . ", новое: " . $keyword);
  562.             if ($query->row['keyword'] != $keyword) {
  563.                 $this->query("UPDATE `" . DB_PREFIX . "url_alias` SET `keyword` = '" . $this->db->escape($keyword) . "' WHERE `url_alias_id` = " . $query->row['url_alias_id']);
  564.             }
  565.         } else {
  566.             $this->query("INSERT INTO `" . DB_PREFIX . "url_alias` SET `query` = '" . $url_type . "=" . $element_id ."', `keyword` = '" . $this->db->escape($keyword) . "'");
  567.         }
  568.         $this->log("SeoURL сформирован для категории, keyword " . $keyword);
  569.  
  570.     } // setSeoURL()
  571.  
  572.  
  573.     /**
  574.      * Транслиетрирует RUS->ENG
  575.      * @param string $aString
  576.      * @return string type
  577.      */
  578.     private function transString($aString) {
  579.  
  580.         $rus = array(" ", "/", "*", "-", "+", "`", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "+", "[", "]", "{", "}", "~", ";", ":", "'", "\"", "<", ">", ",", ".", "?", "А", "Б", "В", "Г", "Д", "Е", "З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", "У", "Ф", "Х", "Ъ", "Ы", "Ь", "Э", "а", "б", "в", "г", "д", "е", "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ъ", "ы", "ь", "э", "ё",  "ж",  "ц",  "ч",  "ш",  "щ",   "ю",  "я",  "Ё",  "Ж",  "Ц",  "Ч",  "Ш",  "Щ",   "Ю",  "Я");
  581.         $lat = array("-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",  "-", "-", "-", "-", "-", "-", "a", "b", "v", "g", "d", "e", "z", "i", "y", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "f", "h", "",  "i", "",  "e", "a", "b", "v", "g", "d", "e", "z", "i", "j", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "f", "h", "",  "i", "",  "e", "yo", "zh", "ts", "ch", "sh", "sch", "yu", "ya", "yo", "zh", "ts", "ch", "sh", "sch", "yu", "ya");
  582.         $string = str_replace($rus, $lat, $aString);
  583.         while (mb_strpos($string, '--')) {
  584.             $string = str_replace('--', '-', $string);
  585.         }
  586.         $string = strtolower(trim($string, '-'));
  587.         return $string;
  588.  
  589.     } // transString()
  590.  
  591.  
  592.     /**
  593.      * ver 3
  594.      * update 2017-06-12
  595.      * Транслиетрирует RUS->ENG
  596.      * @param string $aString
  597.      * @return string type
  598.      * Автор: Константин Кирилюк
  599.      * url: http://www.chuvyr.ru/2013/11/translit.html
  600.      */
  601.     private function translit($s, $space = '-') {
  602.  
  603.         $s = (string) $s; // преобразуем в строковое значение
  604.         $s = strip_tags($s); // убираем HTML-теги
  605.         $s = str_replace(array('\n', '\r'), ' ', $s); // убираем перевод каретки
  606.         $s = trim($s); // убираем пробелы в начале и конце строки
  607.         $s = function_exists('mb_strtolower') ? mb_strtolower($s) : strtolower($s); // переводим строку в нижний регистр (иногда надо задать локаль)
  608.         $s = strtr($s, array('а'=>'a','б'=>'b','в'=>'v','г'=>'g','д'=>'d','е'=>'e','ё'=>'e','ж'=>'j','з'=>'z','и'=>'i','й'=>'y','к'=>'k','л'=>'l','м'=>'m','н'=>'n','о'=>'o','п'=>'p','р'=>'r','с'=>'s','т'=>'t','у'=>'u','ф'=>'f','х'=>'h','ц'=>'c','ч'=>'ch','ш'=>'sh','щ'=>'shch','ы'=>'y','э'=>'e','ю'=>'yu','я'=>'ya','ъ'=>'','ь'=>''));
  609.         $s = preg_replace('/[^0-9a-z-_ ]/i', '', $s); // очищаем строку от недопустимых символов
  610.         $s = preg_replace('/\s+/', ' ', $s); // удаляем повторяющие пробелы
  611.         $s = str_replace(' ', $space, $s); // заменяем пробелы знаком минус
  612.         return $s; // возвращаем результат
  613.  
  614.     } // translit()
  615.  
  616.  
  617.     /**
  618.      * Получает SEO_URL
  619.      */
  620.     private function getSeoUrl($element, $id, $last_symbol = "") {
  621.  
  622.         $query = $this->query("SELECT `keyword` FROM `" . DB_PREFIX . "url_alias` WHERE `query` = '" . $element . "=" . (string)$id . "'");
  623.         if ($query->num_rows) {
  624.             return $query->row['keyword'] . $last_symbol;
  625.         }
  626.         return "";
  627.  
  628.     } // getSeoUrl()
  629.  
  630.  
  631.     /**
  632.      * ver 2
  633.      * update 2017-04-05
  634.      * Получает название производителя в строку для SEO
  635.      */
  636.     private function getProductManufacturerString($manufacturer_id) {
  637.  
  638.         $name = "";
  639.         if (isset($this->TAB_FIELDS['manufacturer_description']['name'])) {
  640.             $query = $this->query("SELECT `name` FROM `" . DB_PREFIX . "manufacturer_description` WHERE `language_id` = " . $this->LANG_ID . " AND `manufacturer_id` = " . $manufacturer_id);
  641.             if ($query->num_rows) {
  642.                 if ($query->row['name']) {
  643.                     $name = $query->row['name'];
  644.                 }
  645.             }
  646.         }
  647.         if (!$name) {
  648.             $query = $this->query("SELECT `name` FROM `" . DB_PREFIX . "manufacturer` WHERE `manufacturer_id` = " . $manufacturer_id);
  649.             if ($query->num_rows) {
  650.                 if ($query->row['name']) {
  651.                     $name = $query->row['name'];
  652.                 }
  653.             }
  654.         }
  655.         return $name;
  656.  
  657.       } // getProductManufacturerString()
  658.  
  659.  
  660.     /**
  661.      * ver 2
  662.      * update 2017-06-12
  663.      * Получает все категории продукта в строку для SEO
  664.      */
  665.     private function getProductCategoriesString($product_id) {
  666.  
  667.         $categories = array();
  668.  
  669.         $query = $this->query("SELECT `c`.`category_id`, `cd`.`name` FROM `" . DB_PREFIX . "category` `c` LEFT JOIN `" . DB_PREFIX . "category_description` `cd` ON (`c`.`category_id` = `cd`.`category_id`) INNER JOIN `" . DB_PREFIX . "product_to_category` `pc` ON (`pc`.`category_id` = `c`.`category_id`) WHERE `cd`.`language_id` = " . $this->LANG_ID . " AND `pc`.`product_id` = " . $product_id . " ORDER BY `c`.`sort_order`, `cd`.`name` ASC");
  670.         foreach ($query->rows as $category) {
  671.             $categories[] = $category['name'];
  672.         }
  673.         $cat_string = implode(',', $categories);
  674.         return $cat_string;
  675.  
  676.       } // getProductCategoriesString()
  677.  
  678.  
  679.     /**
  680.      * ver 2
  681.      * update 2017-06-12
  682.      * Получает все категории продукта в массив
  683.      * первым в массиме будет главная категория
  684.      */
  685.     private function getProductCategories($product_id, $limit = 0) {
  686.  
  687.         // Ограничение по количеству категорий
  688.         $sql_limit = $limit > 0 ? ' LIMIT ' . $limit : '';
  689.  
  690.         $main_category = isset($this->TAB_FIELDS['product_to_category']['main_category']) ? ",`main_category`" : "";
  691.         $query = $this->query("SELECT `category_id`" . $main_category . " FROM `" . DB_PREFIX . "product_to_category` WHERE `product_id` = " . $product_id . $sql_limit);
  692.         $categories = array();
  693.         foreach ($query->rows as $category) {
  694.             if ($main_category && $category['main_category']) {
  695.                 // главную категорию добавляем в начало массива
  696.                 array_unshift($categories, $category['category_id']);
  697.             } else {
  698.                 $categories[] = $category['category_id'];
  699.             }
  700.         }
  701.         return $categories;
  702.  
  703.     } // getProductCategories()
  704.  
  705.  
  706.     /**
  707.      * ver 2
  708.      * update 2017-04-18
  709.      * Генерит SEO строк. Заменяет паттерны на их значения
  710.      */
  711.     private function seoGenerateString($template, $product_tags, $trans = false, $split = false) {
  712.  
  713.         // Выберем все теги которые используются в шаблоне
  714.         preg_match_all('/\{(\w+)\}/', $template, $matches);
  715.         $values = array();
  716.  
  717.         foreach ($matches[0] as $match) {
  718.             $value = isset($product_tags[$match]) ? $product_tags[$match] : '';
  719.             if ($trans) {
  720.                 $values[] = $this->translit($value);
  721.             } else {
  722.                 $values[] = $value;
  723.             }
  724.         }
  725.         $seo_string = trim(str_replace($matches[0], $values, $template));
  726.         if ($split) {
  727.             $seo_string = $this->getKeywordString($seo_string);
  728.         }
  729.         return $seo_string;
  730.  
  731.     } // seoGenerateString()
  732.  
  733.  
  734.     /**
  735.      * Генерит ключевую строку из строки
  736.      */
  737.     private function getKeywordString($str) {
  738.  
  739.         // Переведем в массив по пробелам
  740.         $s = strip_tags($str); // убираем HTML-теги
  741.         $s = preg_replace("/\s+/", " ", $s); // удаляем повторяющие пробелы
  742.         $s = preg_replace("/\,+/", "", $s); // удаляем повторяющие запятые
  743.         $s = preg_replace("~(&lt;)([^&]+)(&gt;)~isu", "", $s); // удаляем HTML символы
  744.         $s = preg_replace("![^\w\d\s]*!", "", $s); // очищаем строку от недопустимых символов
  745.         $in_obj = explode(' ', $s);
  746.         $out_obj = array();
  747.         foreach ($in_obj as $s) {
  748.             if (function_exists('mb_strlen')) {
  749.                 if (mb_strlen($s) < 3) {
  750.                     // пропускаем слова длиной менее 3 символов
  751.                     continue;
  752.                 }
  753.             }
  754.             $out_obj[] = $s;
  755.         }
  756.         // Удаляем повторяющиеся значения
  757.         $out_obj = array_unique($out_obj);
  758.         $str_out = implode(', ', $out_obj);
  759.  
  760.         return $str_out;
  761.  
  762.     } // getKeywordString()
  763.  
  764.  
  765.     /**
  766.      * Генерит SEO переменные шаблона для товара
  767.      */
  768.     private function seoGenerateProduct(&$data) {
  769.  
  770.         if ($this->config->get('exchange1c_seo_product_mode') == 'disable') {
  771.             return;
  772.         }
  773.         // Товары, Категории
  774.         $seo_fields = array(
  775.             'seo_url'           => array('trans' => true),
  776.             'meta_title'        => array(),
  777.             'meta_description'  => array(),
  778.             'meta_keyword'      => array(),
  779.             'tag'               => array()
  780.         );
  781.         // Сопоставляем значения
  782.         $tags = array(
  783.             '{name}'        => isset($data['name'])             ? $data['name']         : '',
  784.             '{fullname}'    => isset($data['full_name'])        ? $data['full_name']    : $data['name'],
  785.             '{sku}'         => isset($data['sku'])              ? $data['sku']          : '',
  786.             '{model}'       => isset($data['model'])            ? $data['model']        : '',
  787.             '{brand}'       => isset($data['manufacturer_id'])  ? $this->getProductManufacturerString($data['manufacturer_id']) : '',
  788.             '{cats}'        => $this->getProductCategoriesString($data['product_id']),
  789.             '{prod_id}'     => isset($data['product_id'])       ? $data['product_id']   : '',
  790.             '{cat_id}'      => isset($data['category_id'])      ? $data['category_id']  : ''
  791.         );
  792.         if (isset($this->TAB_FIELDS['product_description']['meta_h1'])) {
  793.             $seo_fields['meta_h1'] = array();
  794.         }
  795.         // Получим поля для сравнения
  796.         $fields_list = array();
  797.  
  798.         foreach ($seo_fields as $field=>$param) {
  799.             if ($field == 'seo_url') {
  800.                 continue;
  801.             }
  802.             $fields_list[] = $field;
  803.         }
  804.         $fields = implode($fields_list,', ');
  805.  
  806.         if (!isset($data['name']))
  807.             $fields .= ", name";
  808.         $query = $this->query("SELECT " . $fields . " FROM `" . DB_PREFIX . "product_description` WHERE `product_id` = " . $data['product_id'] . " AND `language_id` = " . $this->LANG_ID);
  809.  
  810.         foreach ($fields_list as $field) {
  811.             $data[$field] = isset($query->row[$field]) ?  $query->row[$field] : "";
  812.         }
  813.  
  814.         if (!isset($data['name']) && isset($query->row['name'])) {
  815.             $data['name'] = $query->row['name'];
  816.             $tags['{name}'] = $data['name'];
  817.         }
  818.  
  819.         // Прочитаем старый SEO URL
  820.         if (isset($seo_fields['seo_url'])) {
  821.             $data['seo_url'] = $this->getSeoUrl("product_id", $data['product_id']);
  822.             $data['seo_url_old'] = $data['seo_url'];
  823.         }
  824.  
  825.         $update = false;
  826.         // Формируем массив с замененными значениями
  827.         foreach ($seo_fields as $field=>$param) {
  828.             $template = '';
  829.             if ($this->config->get('exchange1c_seo_product_'.$field) == 'template') {
  830.                 $template = $this->config->get('exchange1c_seo_product_'.$field.'_template');
  831.  
  832.                 if (!$template) {
  833.                     unset($data[$field]);
  834.                     continue;
  835.                 }
  836.  
  837.                 if ($this->config->get('exchange1c_seo_product_mode') == 'overwrite') {
  838.                     // Перезаписывать
  839.                     $old_value = '';
  840.                     if (isset($data[$field])) {
  841.                         $old_value = $data[$field];
  842.                     }
  843.                     if ($field == 'meta_keyword' || $field == 'tag') {
  844.                         $data[$field] = $this->seoGenerateString($template, $tags, isset($param['trans']), true);
  845.                     } else {
  846.                         $data[$field] = $this->seoGenerateString($template, $tags, isset($param['trans']));
  847.                     }
  848.  
  849.                     // Если поле не изменилось, нет смысла его перезаписывать
  850.                     if ($old_value == $data[$field]) {
  851.                         unset($data[$field]);
  852.                     } else {
  853.                         $update = true;
  854.                         $this->log("Старое значение '".$field."' = '" . $old_value . "'", 2);
  855.                         $this->log("Новое значение '" . $field . "' = '" . $data[$field] . "'", 2);
  856.                     }
  857.  
  858.                 } else {
  859.                     if (!isset($data[$field])) {
  860.                         continue;
  861.                     }
  862.                     // Только если поле пустое
  863.                     $this->log("Старое значение '".$field."' = '" . $data[$field] . "'", 2);
  864.                     if (empty($data[$field])) {
  865.                         $data[$field] = $this->seoGenerateString($template, $tags, isset($param['trans']));
  866.                         $update = true;
  867.                     } else {
  868.                         $this->log("Пропускаем '" . $field . "', т.к. не пустое", 2);
  869.                         unset($data[$field]);
  870.                         continue;
  871.                     }
  872.                 }
  873.             } else {
  874.                 unset($data[$field]);
  875.                 continue;
  876.             }
  877.         }
  878.         if (isset($data['seo_url']) && $data['product_id']) {
  879.             if ($data['seo_url_old'] != $data['seo_url']) {
  880.                 $this->setSeoURL('product_id', $data['product_id'], $data['seo_url']);
  881.             }
  882.         }
  883.         if (isset($data['seo_url_old'])) {
  884.             unset($data['seo_url_old']);
  885.         }
  886.         $this->log("Сформировано SEO для товара product_id: " . $data['product_id']);
  887.         return $update;
  888.  
  889.     } // seoGenerateProduct()
  890.  
  891.  
  892.     /**
  893.      * ver 2
  894.      * update 2017-04-30
  895.      * Генерит SEO переменные шаблона для категории
  896.      */
  897.     private function seoGenerateCategory(&$data) {
  898.  
  899.         if ($this->config->get('exchange1c_seo_category_mode') == 'disable') {
  900.             return false;
  901.         }
  902.  
  903.         // Товары, Категории
  904.         $seo_fields = array(
  905.             'seo_url'           => array('trans' => true),
  906.             'meta_title'        => array(),
  907.             'meta_description'  => array(),
  908.             'meta_keyword'      => array(),
  909.         );
  910.  
  911.         if (isset($this->TAB_FIELDS['category_description']['meta_h1'])) {
  912.             $seo_fields['meta_h1'] = array();
  913.         }
  914.  
  915.         // Получим поля для сравнения
  916.         $fields_list = array();
  917.         foreach ($seo_fields as $field=>$param) {
  918.             if ($field == 'seo_url') {
  919.                 continue;
  920.             }
  921.             $fields_list[] = $field;
  922.         }
  923.         $fields = implode($fields_list,', ');
  924.         $query = $this->query("SELECT " . $fields . " FROM `" . DB_PREFIX . "category_description` WHERE `category_id` = " . $data['category_id'] . " AND `language_id` = " . $this->LANG_ID);
  925.  
  926.         // Если записей вообще небыло, присваиваем пустые
  927.         foreach ($fields_list as $field) {
  928.             $data[$field] = isset($query->row[$field]) ?  $query->row[$field] : "";
  929.         }
  930.  
  931.         // Прочитаем старый SEO URL
  932.         if (isset($seo_fields['seo_url'])) {
  933.             $data['seo_url'] = $this->getSeoUrl("category_id", $data['category_id']);
  934.             $data['seo_url_old'] = $data['seo_url'];
  935.         }
  936.  
  937.         // Сопоставляем значения к тегам
  938.         $tags = array(
  939.             '{cat}'         => isset($data['name'])         ? $data['name']         : '',
  940.             '{cat_id}'      => isset($data['category_id'])  ? $data['category_id']  : ''
  941.         );
  942.  
  943.         $update = false;
  944.         // Формируем массив с замененными значениями
  945.         foreach ($seo_fields as $field=>$param) {
  946.             $template = '';
  947.             if ($this->config->get('exchange1c_seo_category_'.$field) == 'template') {
  948.                 $template = $this->config->get('exchange1c_seo_category_'.$field.'_template');
  949.  
  950.                 if (!$template) {
  951.                     unset($data[$field]);
  952.                     continue;
  953.                 }
  954.  
  955.                 if ($this->config->get('exchange1c_seo_category_mode') == 'overwrite') {
  956.  
  957.                     $old_value = $data[$field];
  958.  
  959.                     // Перезаписывать
  960.                     $data[$field] = $this->seoGenerateString($template, $tags, isset($param['trans']));
  961.  
  962.                     // Если поле не изменилось, нет смысла его перезаписывать
  963.                     if ($old_value == $data[$field]) {
  964.                         unset($data[$field]);
  965.                     } else {
  966.                         $this->log("Поле: '" . $field . "' старое: '" . $old_value . "', новое: " . $data[$field] . "'", 2);
  967.                         $update = true;
  968.                     }
  969.  
  970.                 } else {
  971.                     if (!isset($data[$field])) {
  972.                         continue;
  973.                     }
  974.                     // Только если поле пустое
  975.                     $this->log("Старое значение '" . $field . "' = '" . $data[$field] . "'", 2);
  976.                     if (empty($data[$field])) {
  977.                         $data[$field] = $this->seoGenerateString($template, $tags, isset($param['trans']));
  978.                         $update = true;
  979.                     } else {
  980.                         $this->log("Пропускаем '" . $field . "', т.к. не пустое", 2);
  981.                         unset($data[$field]);
  982.                     }
  983.                 }
  984.  
  985.             } else {
  986.                 unset($data[$field]);
  987.                 continue;
  988.             }
  989.         }
  990.  
  991.         if (isset($data['seo_url']) && $data['category_id']) {
  992.             if ($data['seo_url_old'] != $data['seo_url']) {
  993.                 $this->setSeoURL('category_id', $data['category_id'], $data['seo_url']);
  994.             }
  995.             unset($data['seo_url_old']);
  996.         }
  997.         if (isset($data['seo_url_old'])) {
  998.             unset($data['seo_url_old']);
  999.         }
  1000.  
  1001.         $this->log("Сформировано SEO для категории category_id: " . $data['category_id']);
  1002.         return $update;
  1003.  
  1004.     } // seoGenerateCategory()
  1005.  
  1006.  
  1007.     /**
  1008.      * ver 6
  1009.      * update 2017-05-26
  1010.      * Генерит SEO переменные шаблона для категории
  1011.      */
  1012.     private function seoGenerateManufacturer(&$data) {
  1013.  
  1014.         if ($this->config->get('exchange1c_seo_manufacturer_mode') == 'disable') {
  1015.             return false;
  1016.         }
  1017.  
  1018.         // Производители
  1019.         $seo_fields = array(
  1020.             'seo_url' => array('trans' => true)
  1021.         );
  1022.  
  1023.         if (isset($this->TAB_FIELDS['product_description'])) {
  1024.             if (isset($this->TAB_FIELDS['manufacturer_description']['meta_h1'])) {
  1025.                 $seo_fields['meta_h1'] = array();
  1026.             }
  1027.             if (isset($this->TAB_FIELDS['manufacturer_description']['meta_title'])) {
  1028.                 $seo_fields['meta_title'] = array();
  1029.             }
  1030.             if (isset($this->TAB_FIELDS['manufacturer_description']['meta_description'])) {
  1031.                 $seo_fields['meta_description'] = array();
  1032.             }
  1033.             if (isset($this->TAB_FIELDS['manufacturer_description']['meta_keyword'])) {
  1034.                 $seo_fields['meta_keyword'] = array();
  1035.             }
  1036.             // Получим поля для сравнения
  1037.             $fields_list = array();
  1038.             foreach ($seo_fields as $field => $param) {
  1039.                 if ($field == 'seo_url') {
  1040.                     continue;
  1041.                 }
  1042.                 $fields_list[] = $field;
  1043.             }
  1044.             $fields = implode($fields_list,', ');
  1045.  
  1046.             if (isset($this->TAB_FIELDS['manufacturer_description'])) {
  1047.                 $query = $this->query("SELECT " . $fields . " FROM `" . DB_PREFIX . "manufacturer_description` WHERE `manufacturer_id` = " . $data['manufacturer_id'] . " AND `language_id` = " . $this->LANG_ID);
  1048.                 foreach ($fields_list as $field) {
  1049.                     $data[$field] = isset($query->row[$field]) ?  $query->row[$field] : "";
  1050.                 }
  1051.             }
  1052.         }
  1053.  
  1054.         // Прочитаем старый SEO URL
  1055.         if (isset($seo_fields['seo_url'])) {
  1056.             $data['seo_url'] = $this->getSeoUrl("manufacturer_id", $data['manufacturer_id']);
  1057.             $data['seo_url_old'] = $data['seo_url'];
  1058.         }
  1059.  
  1060.         // Сопоставляем значения к тегам
  1061.         $tags = array(
  1062.             '{brand}'       => isset($data['name'])             ? $data['name']             : '',
  1063.             '{brand_id}'    => isset($data['manufacturer_id'])  ? $data['manufacturer_id']  : ''
  1064.         );
  1065.  
  1066.         $update = false;
  1067.         // Формируем массив с замененными значениями
  1068.         foreach ($seo_fields as $field=>$param) {
  1069.             $template = '';
  1070.             if ($this->config->get('exchange1c_seo_manufacturer_' . $field) == 'template') {
  1071.                 $template = $this->config->get('exchange1c_seo_manufacturer_' . $field . '_template');
  1072.  
  1073.                 if (!$template) {
  1074.                     unset($data[$field]);
  1075.                     continue;
  1076.                 }
  1077.  
  1078.                 if ($this->config->get('exchange1c_seo_manufacturer_mode') == 'overwrite') {
  1079.  
  1080.                     $old_value = $data[$field];
  1081.  
  1082.                     // Перезаписывать
  1083.                     $data[$field] = $this->seoGenerateString($template, $tags, isset($param['trans']));
  1084.  
  1085.                     // Если поле не изменилось, нет смысла его перезаписывать
  1086.                     if ($old_value == $data[$field]) {
  1087.                         unset($data[$field]);
  1088.                     } else {
  1089.                         $this->log("Значение поля:  '" . $field . "', старое:  '" . $old_value . "', новое: " . $data[$field], 2);
  1090.                         $update = true;
  1091.                     }
  1092.  
  1093.                 } else {
  1094.                     if (!isset($data[$field])) {
  1095.                         continue;
  1096.                     }
  1097.                     // Только если поле пустое
  1098.                     $this->log("Старое значение '" . $field . "' = '" . $data[$field] . "'", 2);
  1099.                     if (empty($data[$field])) {
  1100.                         $data[$field] = $this->seoGenerateString($template, $tags, isset($param['trans']));
  1101.                         $update = true;
  1102.                     } else {
  1103.                         $this->log("Пропускаем '" . $field . "', т.к. не пустое", 2);
  1104.                         unset($data[$field]);
  1105.                     }
  1106.                 }
  1107.             } else {
  1108.                 unset($data[$field]);
  1109.                 continue;
  1110.             }
  1111.  
  1112.         }
  1113.  
  1114.         if (isset($data['seo_url']) && $data['manufacturer_id']) {
  1115.             if ($data['seo_url_old'] != $data['seo_url']) {
  1116.                 $this->setSeoURL('manufacturer_id', $data['manufacturer_id'], $data['seo_url']);
  1117.             }
  1118.             unset($data['seo_url_old']);
  1119.         }
  1120.         if (isset($data['seo_url_old'])) {
  1121.             unset($data['seo_url_old']);
  1122.         }
  1123.  
  1124.         if ($update) {
  1125.             $this->log("Сформировано SEO для производителя: " . $data['name']);
  1126.         }
  1127.         return $update;
  1128.  
  1129.     } // seoGenerateManufacturer()
  1130.  
  1131.  
  1132.     /**
  1133.      * ver 2
  1134.      * update 2017-05-03
  1135.      * Генерит SEO переменные шаблона для товара
  1136.      */
  1137.     public function seoGenerate() {
  1138.  
  1139.         $now = date('Y-m-d H:i:s');
  1140.         $result = array('error'=>'','product'=>0,'category'=>0,'manufacturer'=>0);
  1141.  
  1142.         $language_id = $this->getLanguageId($this->config->get('config_language'));
  1143.  
  1144.         // Выбрать все товары, нужны поля:
  1145.         // name, sku, model, manufacturer_id, description, product_id, category_id
  1146.         if (isset($this->TAB_FIELDS['product_description']['meta_h1'])) {
  1147.             $sql = "SELECT `p`.`product_id`, `p`.`sku`, `p`.`model`, `p`.`manufacturer_id`, `pd`.`name`, `pd`.`tag`, `pd`.`meta_title`, `pd`.`meta_description`, `pd`.`meta_keyword`, `pd`.`meta_h1` FROM `" . DB_PREFIX . "product` `p` LEFT JOIN `" . DB_PREFIX . "product_description` `pd` ON (`p`.`product_id` = `pd`.`product_id`) WHERE `pd.`language_id` = " . $language_id;
  1148.             $fields_include = 'name,tag,meta_title,meta_description,meta_keyword,meta_h1';
  1149.         } else {
  1150.             $sql = "SELECT `p`.`product_id`, `p`.`sku`, `p`.`model`, `p`.`manufacturer_id`, `pd`.`name`, `pd`.`tag`, `pd`.`meta_title`, `pd`.`meta_description`, `pd`.`meta_keyword` FROM `" . DB_PREFIX . "product` `p` LEFT JOIN `" . DB_PREFIX . "product_description` `pd` ON (`p`.`product_id` = `pd`.`product_id`) WHERE `pd`.`language_id` = " . $language_id;
  1151.             $fields_include = 'name,tag,meta_title,meta_description,meta_keyword';
  1152.         }
  1153.  
  1154.         $query = $this->query($sql);
  1155.         if ($query->num_rows) {
  1156.             foreach ($query->rows as $data) {
  1157.  
  1158.                 $result['product']++;
  1159.                 $data_old = $data;
  1160.                 $update = $this->seoGenerateProduct($data);
  1161.  
  1162.                 if (!$update) {
  1163.                     continue;
  1164.                 }
  1165.  
  1166.                 // Сравнение
  1167.                 $fields = $this->compareArraysNew($data_old, $data, 'sku,model,manufacturer_id');
  1168.  
  1169.                 // Если есть что обновлять
  1170.                 if ($fields) {
  1171.                     $this->query("UPDATE `" . DB_PREFIX . "product` SET " . $fields . ", `date_modified` = '" . $now . "' WHERE `product_id` = " . $data['product_id']);
  1172.                 }
  1173.  
  1174.                 // Сравнение
  1175.                 $fields = $this->compareArraysNew($data_old, $data, $fields_include);
  1176.  
  1177.                 // Если есть что обновлять
  1178.                 if ($fields) {
  1179.                     $this->query("UPDATE `" . DB_PREFIX . "product_description` SET " . $fields . " WHERE `product_id` = " . $data['product_id'] . " AND `language_id` = " . $language_id);
  1180.                 }
  1181.             }
  1182.         }
  1183.  
  1184.         // Категории
  1185.  
  1186.         // Выбрать все категории, нужны поля:
  1187.         // name, sku, model, manufacturer_id, description, product_id, category_id
  1188.         if (isset($this->TAB_FIELDS['category_description']['meta_h1'])) {
  1189.             $sql = "SELECT `c`.`category_id`, `cd`.`name`, `cd`.`meta_title`, `cd`.`meta_description`, `cd`.`meta_keyword`, `cd`.`meta_h1` FROM `" . DB_PREFIX . "category` `c` LEFT JOIN `" . DB_PREFIX . "category_description` `cd` ON (`c`.`category_id` = `cd`.`category_id`) WHERE `cd`.`language_id` = " . $language_id;
  1190.             $fields_include = 'name,meta_title,meta_description,meta_keyword,meta_h1';
  1191.         } else {
  1192.             $sql = "SELECT `c`.`category_id`, `cd`.`name`, `cd`.`meta_title`, `cd`.`meta_description`, `cd`.`meta_keyword` FROM `" . DB_PREFIX . "category` `c` LEFT JOIN `" . DB_PREFIX . "category_description` `cd` ON (`c`.`category_id` = `cd`.`category_id`) WHERE `cd`.`language_id` = " . $language_id;
  1193.             $fields_include = 'name,meta_title,meta_description,meta_keyword';
  1194.         }
  1195.  
  1196.         $query = $this->query($sql);
  1197.         if ($query->num_rows) {
  1198.             foreach ($query->rows as $data) {
  1199.  
  1200.                 $result['category']++;
  1201.                 $this->seoGenerateCategory($data);
  1202.  
  1203.                 // Сравнение
  1204.                 $fields = $this->compareArraysNew($data_old, $data, $fields_include);
  1205.  
  1206.                 // Если есть что обновлять
  1207.                 if ($fields) {
  1208.                     $this->query("UPDATE `" . DB_PREFIX . "category_description` SET " . $fields . " WHERE `category_id` = " . $data['category_id'] . " AND `language_id` = " . $language_id);
  1209.                     $this->query("UPDATE `" . DB_PREFIX . "category` SET `date_modified` = '" . $now . "' WHERE `category_id` = " . $data['category_id']);
  1210.                 }
  1211.             }
  1212.         }
  1213.  
  1214.         // Производители
  1215.  
  1216.         if (isset($this->TAB_FIELDS['manufacturer_description'])) {
  1217.             // Выбрать все категории, нужны поля:
  1218.             // name, sku, model, manufacturer_id, description, product_id, category_id
  1219.             if (isset($this->TAB_FIELDS['manufacturer_description']['meta_h1'])) {
  1220.                 $sql = "SELECT `m`.`manufacturer_id`, `md`.`name`, `md`.`meta_title`, `md`.`meta_description`, `md`.`meta_keyword`, `md`.`meta_h1` FROM `" . DB_PREFIX . "manufacturer` `m` LEFT JOIN `" . DB_PREFIX . "manufacturer_description` `md` ON (`m`.`manufacturer_id` = `md`.`manufacturer_id`) WHERE `md`.`language_id` = " . $language_id;
  1221.                 $fields_include = 'name,meta_title,meta_description,meta_keyword,meta_h1';
  1222.             } else {
  1223.                 $sql = "SELECT `m`.`manufacturer_id`, `md`.`name`, `md`.`meta_title`, `md`.`meta_description`, `md`.`meta_keyword` FROM `" . DB_PREFIX . "manufacturer` `m` LEFT JOIN `" . DB_PREFIX . "manufacturer_description` `md` ON (`m`.`manufacturer_id` = `md`.`manufacturer_id`) WHERE `md`.`language_id` = " . $language_id;
  1224.                 $fields_include = 'name,meta_title,meta_description,meta_keyword';
  1225.             }
  1226.  
  1227.             $query = $this->query($sql);
  1228.             if ($query->num_rows) {
  1229.                 foreach ($query->rows as $data) {
  1230.  
  1231.                     $result['manufacturer']++;
  1232.  
  1233.                     $data_old = $data;
  1234.                     $update = $this->seoGenerateManufacturer($data);
  1235.  
  1236.                     if (!$update) {
  1237.                         continue;
  1238.                     }
  1239.  
  1240.                     // Сравнение
  1241.                     $fields = $this->compareArraysNew($data_old, $data, $fields_include);
  1242.  
  1243.                     // Если есть что обновлять
  1244.                     if ($fields) {
  1245.                         $this->query("UPDATE `" . DB_PREFIX . "category_description` SET " . $fields . " WHERE `category_id` = " . $data['category_id'] . " AND `language_id` = " . $language_id);
  1246.                         $this->query("UPDATE `" . DB_PREFIX . "category` SET `date_modified` = '" . $now . "' WHERE `category_id` = " . $data['category_id']);
  1247.                     }
  1248.                 }
  1249.             }
  1250.  
  1251.         }
  1252.  
  1253.         return $result;
  1254.  
  1255.     } // seoGenerate()
  1256.  
  1257.  
  1258.     /**
  1259.      * ****************************** ФУНКЦИИ ДЛЯ ЗАГРУЗКИ КАТАЛОГА ******************************
  1260.      */
  1261.  
  1262.     /**
  1263.      * Формирует строку запроса для категории
  1264.      */
  1265.     private function prepareStrQueryCategory($data, $mode = 'set') {
  1266.  
  1267.         $sql = array();
  1268.  
  1269.         if (isset($data['top']))
  1270.             $sql[] = $mode == 'set' ? "`top` = " .          (int)$data['top']                               : "top";
  1271.         if (isset($data['column']))
  1272.             $sql[] = $mode == 'set' ? "`column` = " .       (int)$data['column']                            : "column";
  1273.         if (isset($data['sort_order']))
  1274.             $sql[] = $mode == 'set' ? "`sort_order` = " .   (int)$data['sort_order']                        : "sort_order";
  1275.         if (isset($data['status']))
  1276.             $sql[] = $mode == 'set' ? "`status` = " .       (int)$data['status']                            : "status";
  1277.         if (isset($data['noindex']))
  1278.             $sql[] = $mode == 'set' ? "`noindex` = " .      (int)$data['noindex']                           : "noindex";
  1279.         if (isset($data['parent_id']))
  1280.             $sql[] = $mode == 'set' ? "`parent_id` = " .    (int)$data['parent_id']                         : "parent_id";
  1281.         if (isset($data['image']))
  1282.             $sql[] = $mode == 'set' ? "`image` = '" .       $this->db->escape((string)$data['image']) . "'" : "image";
  1283.  
  1284.         return implode(($mode = 'set' ? ', ' : ' AND '), $sql);
  1285.  
  1286.     } //prepareStrQueryCategory()
  1287.  
  1288.  
  1289.     /**
  1290.      * Формирует строку запроса для описания категорий и товаров
  1291.      */
  1292.     private function prepareStrQueryDescription($data, $mode = 'set') {
  1293.  
  1294.         $sql = array();
  1295.         if (isset($data['name']))
  1296.             $sql[] = $mode == 'set'     ? "`name` = '" .                $this->db->escape($data['name']) . "'"              : "`name`";
  1297.         if (isset($data['description']))
  1298.             $sql[] = $mode == 'set'     ? "`description` = '" .         $this->db->escape($data['description']) . "'"       : "`description`";
  1299.         if (isset($data['meta_title']))
  1300.             $sql[] = $mode == 'set'     ? "`meta_title` = '" .          $this->db->escape($data['meta_title']) . "'"        : "`meta_title`";
  1301.         if (isset($data['meta_h1']))
  1302.             $sql[] = $mode == 'set'     ? "`meta_h1` = '" .             $this->db->escape($data['meta_h1']) . "'"           : "`meta_h1`";
  1303.         if (isset($data['meta_description']))
  1304.             $sql[] = $mode == 'set'     ? "`meta_description` = '" .    $this->db->escape($data['meta_description']) . "'"  : "`meta_description`";
  1305.         if (isset($data['meta_keyword']))
  1306.             $sql[] = $mode == 'set'     ? "`meta_keyword` = '" .        $this->db->escape($data['meta_keyword']) . "'"      : "`meta_keyword`";
  1307.         if (isset($data['tag']))
  1308.             $sql[] = $mode == 'set'     ? "`tag` = '" .                 $this->db->escape($data['tag']) . "'"               : "`tag`";
  1309.  
  1310.         return implode(($mode = 'set' ? ', ' : ' AND '), $sql);
  1311.  
  1312.     } //prepareStrQueryDescription()
  1313.  
  1314.  
  1315.     /**
  1316.      * ver 2
  1317.      * update 2017-04-10
  1318.      * Подготавливает запрос для товара
  1319.      */
  1320.     private function prepareQueryProduct($data, $mode = 'set') {
  1321.  
  1322.         $sql = array();
  1323.         if (isset($data['model']))
  1324.             $sql[] = $mode == 'set'     ? "`model` = '" .               $this->db->escape($data['model']) . "'"             : "`model`";
  1325.         if (isset($data['sku']))
  1326.             $sql[] = $mode == 'set'     ? "`sku` = '" .                 $this->db->escape($data['sku']) . "'"               : "`sku`";
  1327.         if (isset($data['upc']))
  1328.             $sql[] = $mode == 'set'     ? "`upc` = '" .                 $this->db->escape($data['upc']) . "'"               : "`upc`";
  1329.         if (isset($data['ean']))
  1330.             $sql[] = $mode == 'set'     ? "`ean` = '" .                 $this->db->escape($data['ean']) . "'"               : "`ean`";
  1331.         if (isset($data['jan']))
  1332.             $sql[] = $mode == 'set'     ? "`jan` = '" .                 $this->db->escape($data['jan']) . "'"               : "`jan`";
  1333.         if (isset($data['isbn']))
  1334.             $sql[] = $mode == 'set'     ? "`isbn` = '" .                $this->db->escape($data['isbn']) . "'"              : "`isbn`";
  1335.         if (isset($data['mpn']))
  1336.             $sql[] = $mode == 'set'     ? "`mpn` = '" .                 $this->db->escape($data['mpn']) . "'"               : "`mpn`";
  1337.         if (isset($data['location']))
  1338.             $sql[] = $mode == 'set'     ? "`location` = '" .            $this->db->escape($data['location']) . "'"          : "`location`";
  1339.         if (isset($data['quantity']))
  1340.             $sql[] = $mode == 'set'     ? "`quantity` = '" .            (float)$data['quantity'] . "'"                      : "`quantity`";
  1341.         if (isset($data['minimum']))
  1342.             $sql[] = $mode == 'set'     ? "`minimum` = '" .             (float)$data['minimum'] . "'"                       : "`minimum`";
  1343.         if (isset($data['subtract']))
  1344.             $sql[] = $mode == 'set'     ? "`subtract` = '" .            (int)$data['subtract'] . "'"                        : "`subtract`";
  1345.         if (isset($data['stock_status_id']))
  1346.             $sql[] = $mode == 'set'     ? "`stock_status_id` = '" .     (int)$data['stock_status_id'] . "'"                 : "`stock_status_id`";
  1347.         if (isset($data['image']))
  1348.             $sql[] = $mode == 'set'     ? "`image` = '" .               $this->db->escape($data['image']) . "'"             : "`image`";
  1349.         if (isset($data['date_available']))
  1350.             $sql[] = $mode == 'set'     ? "`date_available` = '" .      $this->db->escape($data['date_available']) . "'"    : "`date_available`";
  1351.         if (isset($data['manufacturer_id']))
  1352.             $sql[] = $mode == 'set'     ? "`manufacturer_id` = '" .     (int)$data['manufacturer_id'] . "'"                 : "`manufacturer_id`";
  1353.         if (isset($data['shipping']))
  1354.             $sql[] = $mode == 'set'     ? "`shipping` = '" .            (int)$data['shipping'] . "'"                        : "`shipping`";
  1355.         if (isset($data['price']))
  1356.             $sql[] = $mode == 'set'     ? "`price` = '" .               (float)$data['price'] . "'"                         : "`price`";
  1357.         if (isset($data['points']))
  1358.             $sql[] = $mode == 'set'     ? "`points` = '" .              (int)$data['points'] . "'"                          : "`points`";
  1359.         if (isset($data['length']))
  1360.             $sql[] = $mode == 'set'     ? "`length` = '" .              (float)$data['length'] . "'"                        : "`length`";
  1361.         if (isset($data['width']))
  1362.             $sql[] = $mode == 'set'     ? "`width` = '" .               (float)$data['width'] . "'"                         : "`width`";
  1363.         if (isset($data['weight']))
  1364.             $sql[] = $mode == 'set'     ? "`weight` = '" .              (float)$data['weight'] . "'"                        : "`weight`";
  1365.         if (isset($data['height']))
  1366.             $sql[] = $mode == 'set'     ? "`height` = '" .              (float)$data['height'] . "'"                        : "`height`";
  1367.         if (isset($data['status']))
  1368.             $sql[] = $mode == 'set'     ? "`status` = '" .              (int)$data['status'] . "'"                          : "`status`";
  1369.         if (isset($data['noindex']))
  1370.             $sql[] = $mode == 'set'     ? "`noindex` = '" .             (int)$data['noindex'] . "'"                         : "`noindex`";
  1371.         if (isset($data['tax_class_id']))
  1372.             $sql[] = $mode == 'set'     ? "`tax_class_id` = '" .        (int)$data['tax_class_id'] . "'"                    : "`tax_class_id`";
  1373.         if (isset($data['sort_order']))
  1374.             $sql[] = $mode == 'set'     ? "`sort_order` = '" .          (int)$data['sort_order'] . "'"                      : "`sort_order`";
  1375.         if (isset($data['length_class_id']))
  1376.             $sql[] = $mode == 'set'     ? "`length_class_id` = '" .     (int)$data['length_class_id'] . "'"                 : "`length_class_id`";
  1377.         if (isset($data['weight_class_id']))
  1378.             $sql[] = $mode == 'set'     ? "`weight_class_id` = '" .     (int)$data['weight_class_id'] . "'"                 : "`weight_class_id`";
  1379.  
  1380.         return implode(($mode = 'set' ? ', ' : ' AND '),$sql);
  1381.  
  1382.     } // prepareQueryProduct()
  1383.  
  1384.  
  1385.  
  1386.     /**
  1387.      * Формирует строку запроса для описания производителя
  1388.      */
  1389.     private function prepareStrQueryManufacturerDescription($data) {
  1390.  
  1391.         $sql  = isset($data['description'])         ? ", `description` = '" . $this->db->escape($data['description']) . "'"                 : "";
  1392.         if (isset($this->TAB_FIELDS['manufacturer_description']['name'])) {
  1393.             $sql .= isset($data['name'])                ? ", `name` = '" . $this->db->escape($data['name']) . "'"                           : "";
  1394.         }
  1395.         $sql .= isset($data['meta_description'])    ? ", `meta_description` = '" . $this->db->escape($data['meta_description']) . "'"       : "";
  1396.         $sql .= isset($data['meta_keyword'])        ? ", `meta_keyword` = '" . $this->db->escape($data['meta_keyword']) . "'"               : "";
  1397.         $sql .= isset($data['meta_title'])          ? ", `meta_title` = '" . $this->db->escape($data['meta_title']) . "'"                   : "";
  1398.         $sql .= isset($data['meta_h1'])             ? ", `meta_h1` = '" . $this->db->escape($data['meta_h1']) . "'"                         : "";
  1399.  
  1400.         return $sql;
  1401.  
  1402.     } //prepareStrQueryManufacturerDescription()
  1403.  
  1404.  
  1405.     /**
  1406.      * Сравнивает запрос с массивом данных и формирует список измененных полей
  1407.      */
  1408.     private function compareArrays($query, $data) {
  1409.  
  1410.         // Сравниваем значения полей, если есть изменения, формируем поля для запроса
  1411.         $upd_fields = array();
  1412.         if ($query->num_rows) {
  1413.             foreach($query->row as $key => $row) {
  1414.                 if (!isset($data[$key])) continue;
  1415.                 if ($row <> $data[$key]) {
  1416.                     $upd_fields[] = "`" . $key . "` = '" . $this->db->escape($data[$key]) . "'";
  1417.                     $this->log("[i] Отличается поле '" . $key . "', старое: " . $row . ", новое: " . $data[$key], 2);
  1418.                 }
  1419.             }
  1420.         }
  1421.  
  1422.         return implode(', ', $upd_fields);
  1423.  
  1424.     } // compareArrays()
  1425.  
  1426.  
  1427.     /**
  1428.      * ver 3
  1429.      * update 2017-005-17
  1430.      * Заполняет родительские категории у продукта
  1431.      */
  1432.     public function fillParentsCategories($product_categories) {
  1433.  
  1434.         // Подгружаем только один раз
  1435.         if (empty($product_categories)) {
  1436.             $this->log("fillParentsCategories() - нет категорий, заполнение родительских категорий отменено", 2);
  1437.             return $product_categories;
  1438.         }
  1439.  
  1440.         $this->load->model('catalog/product');
  1441.  
  1442.         foreach ($product_categories as $category_id) {
  1443.             $parents = $this->findParentsCategories($category_id);
  1444.             foreach ($parents as $parent_id) {
  1445.                 $key = array_search($parent_id, $product_categories);
  1446.                 if ($key === false)
  1447.                     $product_categories[] = $parent_id;
  1448.             }
  1449.         }
  1450.  
  1451.         return $product_categories;
  1452.  
  1453.     } // fillParentsCategories()
  1454.  
  1455.  
  1456.     /**
  1457.      * Ищет все родительские категории
  1458.      *
  1459.      * @param   int
  1460.      * @return  array
  1461.      */
  1462.     private function findParentsCategories($category_id) {
  1463.  
  1464.         $result = array();
  1465.         $query = $this->query("SELECT * FROM `" . DB_PREFIX ."category` WHERE `category_id` = " . (int)$category_id);
  1466.         if (isset($query->row['parent_id'])) {
  1467.             if ($query->row['parent_id'] <> 0) {
  1468.                 $result[] = $query->row['parent_id'];
  1469.                 $result = array_merge($result, $this->findParentsCategories($query->row['parent_id']));
  1470.             }
  1471.         }
  1472.         return $result;
  1473.  
  1474.     } // findParentsCategories()
  1475.  
  1476.  
  1477.     /**
  1478.      * Устанавливает в какой магазин загружать данные
  1479.      */
  1480.     private function setStore($classifier_name) {
  1481.  
  1482.         $config_stores = $this->config->get('exchange1c_stores');
  1483.         if (!$config_stores) {
  1484.             $this->STORE_ID = 0;
  1485.             return;
  1486.         }
  1487.  
  1488.         // Если ничего не заполнено - по умолчанию
  1489.         foreach ($config_stores as $key => $config_store) {
  1490.             if ($classifier_name == "Классификатор (" . $config_store['name'] . ")") {
  1491.                 $this->STORE_ID = $config_store['store_id'];
  1492.             }
  1493.         }
  1494.         $this->log("Установлен магазин store_id: " . $this->STORE_ID);
  1495.  
  1496.     } // setStore()
  1497.  
  1498.  
  1499.     /**
  1500.      * Возвращает id по GUID
  1501.      */
  1502.     private function getCategoryIdByGuid($guid) {
  1503.  
  1504.         $query = $this->query("SELECT * FROM `" . DB_PREFIX . "category_to_1c` WHERE `guid` = '" . $this->db->escape($guid) . "'");
  1505.         $category_id = isset($query->row['category_id']) ? $query->row['category_id'] : 0;
  1506.  
  1507.         // Проверим существование такого товара
  1508.         if ($category_id) {
  1509.             $query = $this->query("SELECT `category_id` FROM `" . DB_PREFIX . "category` WHERE `category_id` = " . (int)$category_id);
  1510.             if (!$query->num_rows) {
  1511.  
  1512.                 // Удалим неправильную связь
  1513.                 $this->deleteLinkCategory($category_id);
  1514.                 $category_id = 0;
  1515.             }
  1516.         }
  1517.         return $category_id;
  1518.  
  1519.     } // getCategoryIdByGuid()
  1520.  
  1521.  
  1522.     /**
  1523.      * Возвращает id по коду
  1524.      */
  1525.     private function getCategoryIdByCode($code) {
  1526.  
  1527.         $query = $this->query("SELECT `category_id` FROM `" . DB_PREFIX . "category` WHERE `category_id` = " . (int)$code);
  1528.         if (isset($query->row['category_id'])) {
  1529.             return $query->row['category_id'];
  1530.         } else {
  1531.             return 0;
  1532.         }
  1533.  
  1534.     } // getCategoryIdByCode()
  1535.  
  1536.  
  1537.     /**
  1538.      * Возвращает id по названию и уровню категории
  1539.      */
  1540.     private function getCategoryIdByName($name, $parent_id = 0) {
  1541.  
  1542.         $query = $this->query("SELECT `c`.`category_id` FROM `" . DB_PREFIX . "category` `c` LEFT JOIN `" . DB_PREFIX. "category_description` `cd` ON (`c`.`category_id` = `cd`.`category_id`) WHERE `cd`.`name` = LOWER('" . $this->db->escape(strtolower($name)) . "') AND `cd`.`language_id` = " . $this->LANG_ID . " AND `c`.`parent_id` = " . $parent_id);
  1543.         return $query->num_rows ? $query->row['category_id'] : 0;
  1544.  
  1545.     } // getCategoryIdByName()
  1546.  
  1547.  
  1548.     /**
  1549.      * Возвращает массив id,name категории по GUID
  1550.      */
  1551.     private function getCategoryByGuid($guid) {
  1552.  
  1553.         $query = $this->query("SELECT `c`.`category_id`, `cd`.`name` FROM `" . DB_PREFIX . "category_to_1c` `c` LEFT JOIN `" . DB_PREFIX. "category_description` `cd` ON (`c`.`category_id` = `cd`.`category_id`) WHERE `c`.`guid` = '" . $this->db->escape($guid) . "' AND `cd`.`language_id` = " . $this->LANG_ID);
  1554.         return $query->num_rows ? $query->rows : 0;
  1555.  
  1556.     } // getCategoryByGuid()
  1557.  
  1558.  
  1559.     /**
  1560.      * ver 2
  1561.      * update 2017-05-02
  1562.      * Обновляет описание категории
  1563.      */
  1564.     private function updateCategoryDescription($data) {
  1565.  
  1566.         // Надо ли обновлять
  1567.         $fields = $this->prepareStrQueryDescription($data, 'get');
  1568.         if ($fields) {
  1569.             $query = $this->query("SELECT " . $fields . " FROM `" . DB_PREFIX . "category_description` `cd` LEFT JOIN `" . DB_PREFIX . "category_to_store` `cs` ON (`cd`.`category_id` = `cs`.`category_id`) WHERE `cd`.`category_id` = " . $data['category_id'] . " AND `cd`.`language_id` = " . $this->LANG_ID . " AND `cs`.`store_id` = " . $this->STORE_ID);
  1570.             if (!$query->num_rows) {
  1571.                 $set_fields = $this->prepareStrQueryDescription($data, 'set');
  1572.                 $this->query("INSERT INTO `" . DB_PREFIX . "category_description` SET " . $set_fields . ", `category_id` = " . $data['category_id'] . ", `language_id` = " . $this->LANG_ID);
  1573.             }
  1574.         } else {
  1575.             // Нечего даже обновлять
  1576.             return false;
  1577.         }
  1578.  
  1579.         // Сравнивает запрос с массивом данных и формирует список измененных полей
  1580.         $fields = $this->compareArrays($query, $data);
  1581.  
  1582.         // Если есть расхождения, производим обновление
  1583.         if ($fields) {
  1584.             $this->query("UPDATE `" . DB_PREFIX . "category_description` SET " . $fields . " WHERE `category_id` = " . $data['category_id'] . " AND `language_id` = " . $this->LANG_ID);
  1585.             $this->query("UPDATE `" . DB_PREFIX . "category` SET `date_modified` = '" . $this->NOW . "' WHERE `category_id` = " . $data['category_id']);
  1586.             $this->log("> Обновлены поля категории: '" . $fields . "'", 2);
  1587.             return true;
  1588.         }
  1589.         return false;
  1590.  
  1591.     } // updateCategoryDescription()
  1592.  
  1593.  
  1594.     /**
  1595.      * Добавляет иерархию категории
  1596.      */
  1597.     private function addHierarchical($category_id, $data) {
  1598.  
  1599.         // MySQL Hierarchical Data Closure Table Pattern
  1600.         $level = 0;
  1601.         $query = $this->query("SELECT * FROM `" . DB_PREFIX . "category_path` WHERE `category_id` = " . $data['parent_id'] . " ORDER BY `level` ASC");
  1602.         foreach ($query->rows as $result) {
  1603.             $this->query("INSERT INTO `" . DB_PREFIX . "category_path` SET `category_id` = " . $category_id . ", `path_id` = " . (int)$result['path_id'] . ", `level` = " . $level);
  1604.             $level++;
  1605.         }
  1606.         $this->query("INSERT INTO `" . DB_PREFIX . "category_path` SET `category_id` = " . $category_id . ", `path_id` = " . $category_id . ", `level` = " . $level);
  1607.  
  1608.     } // addHierarchical()
  1609.  
  1610.  
  1611.     /**
  1612.      * Обновляет иерархию категории
  1613.      */
  1614.     private function updateHierarchical($data) {
  1615.  
  1616.         // MySQL Hierarchical Data Closure Table Pattern
  1617.         $query = $this->query("SELECT * FROM `" . DB_PREFIX . "category_path` WHERE `path_id` = " . $data['category_id'] . " ORDER BY `level` ASC");
  1618.  
  1619.         if ($query->rows) {
  1620.             foreach ($query->rows as $category_path) {
  1621.                 // Delete the path below the current one
  1622.                 $this->query("DELETE FROM `" . DB_PREFIX . "category_path` WHERE `category_id` = " . (int)$category_path['category_id'] . " AND `level` < " . (int)$category_path['level']);
  1623.                 $path = array();
  1624.                 // Get the nodes new parents
  1625.                 $query = $this->query("SELECT * FROM `" . DB_PREFIX . "category_path` WHERE `category_id` = " . $data['parent_id'] . " ORDER BY `level` ASC");
  1626.                 foreach ($query->rows as $result) {
  1627.                     $path[] = $result['path_id'];
  1628.                 }
  1629.                 // Get whats left of the nodes current path
  1630.                 $query = $this->query("SELECT * FROM `" . DB_PREFIX . "category_path` WHERE `category_id` = " . $category_path['category_id'] . " ORDER BY `level` ASC");
  1631.                 foreach ($query->rows as $result) {
  1632.                     $path[] = $result['path_id'];
  1633.                 }
  1634.                 // Combine the paths with a new level
  1635.                 $level = 0;
  1636.                 foreach ($path as $path_id) {
  1637.                     $this->query("REPLACE INTO `" . DB_PREFIX . "category_path` SET `category_id` = " . $category_path['category_id'] . ", `path_id` = " . $path_id . ", `level` = " . $level);
  1638.  
  1639.                     $level++;
  1640.                 }
  1641.             }
  1642.         } else {
  1643.             // Delete the path below the current one
  1644.             $this->query("DELETE FROM `" . DB_PREFIX . "category_path` WHERE `category_id` = " . $data['category_id']);
  1645.             // Fix for records with no paths
  1646.             $level = 0;
  1647.             $query = $this->query("SELECT * FROM `" . DB_PREFIX . "category_path` WHERE `category_id` = " . $data['parent_id'] . " ORDER BY `level` ASC");
  1648.             foreach ($query->rows as $result) {
  1649.                 $this->query("INSERT INTO `" . DB_PREFIX . "category_path` SET `category_id` = " . $data['category_id'] . ", `path_id` = " . (int)$result['path_id'] . ", `level` = " . $level);
  1650.  
  1651.                 $level++;
  1652.             }
  1653.             $this->query("REPLACE INTO `" . DB_PREFIX . "category_path` SET `category_id` = " . $data['category_id'] . ", `path_id` = " . $data['category_id'] . ", `level` = " . $level);
  1654.         }
  1655.  
  1656.         $this->log("<== updateHierarchical()", 2);
  1657.  
  1658.     } // updateHierarchical()
  1659.  
  1660.  
  1661.     /**
  1662.      * Обновляет категорию
  1663.      */
  1664.     private function updateCategory($data) {
  1665.  
  1666.         // Читаем старые данные
  1667.         $sql = $this->prepareStrQueryCategory($data, 'get');
  1668.         if ($sql) {
  1669.             $query = $this->query("SELECT " . $sql . " FROM `" . DB_PREFIX . "category` WHERE `category_id` = " . $data['category_id']);
  1670.  
  1671.             // Сравнивает запрос с массивом данных и формирует список измененных полей
  1672.             $fields = $this->compareArrays($query, $data);
  1673.  
  1674.             if ($fields) {
  1675.                 $this->query("UPDATE `" . DB_PREFIX . "category` SET " . $fields . ", `date_modified` = '" . $this->NOW . "' WHERE `category_id` = " . $data['category_id']);
  1676.  
  1677.                 $this->log("Обновлена категория '" . $data['name'] . "'", 2);
  1678.  
  1679.                 // Запись иерархии категорий если были изменения
  1680.                 $this->updateHierarchical($data);
  1681.             }
  1682.         } else {
  1683.             $this->log("Нет данных для обновления категории", 2);
  1684.             return false;
  1685.         }
  1686.  
  1687.         // SEO
  1688.         $this->seoGenerateCategory($data);
  1689.  
  1690.         // Если было обновление описания
  1691.         $this->updateCategoryDescription($data);
  1692.  
  1693.         // Очистка кэша
  1694.         $this->cache->delete('category');
  1695.  
  1696.     } // updateCategory()
  1697.  
  1698.  
  1699.     /**
  1700.      * Добавляет связь категории с ТС
  1701.      */
  1702.     private function insertCategoryLinkToGuid($category_id, $guid) {
  1703.  
  1704.         $this->query("INSERT INTO `" . DB_PREFIX . "category_to_1c` SET `category_id` = " . (int)$category_id . ", `guid` = '" . $this->db->escape($guid) . "'");
  1705.  
  1706.     }
  1707.  
  1708.  
  1709.     /**
  1710.      * Добавляет категорию
  1711.      */
  1712.     private function addCategory($data) {
  1713.  
  1714.         if ($data == false) return 0;
  1715.  
  1716.         $data['status'] = $this->config->get('exchange1c_status_new_category') == 1 ? 1 : 0;
  1717.  
  1718.         $sql = $this->prepareStrQueryCategory($data);
  1719.         if ($this->config->get('exchange1c_synchronize_by_code') == 1) {
  1720.             $query_category_id = isset($data['code']) ? ", `category_id` = " . (int)$data['code'] : "";
  1721.         } else {
  1722.             $query_category_id = "";
  1723.         }
  1724.         $this->query("INSERT INTO `" . DB_PREFIX . "category` SET " . $sql . $query_category_id . ", `date_modified` = '" . $this->NOW . "', `date_added` = '" . $this->NOW . "'");
  1725.         $data['category_id'] = $this->db->getLastId();
  1726.  
  1727.         // Формируем SEO
  1728.         $this->seoGenerateCategory($data);
  1729.  
  1730.         // Подготовим строку запроса для описания категории
  1731.         $fields = $this->prepareStrQueryDescription($data, 'set');
  1732.  
  1733.         if ($fields) {
  1734.             $query = $this->query("SELECT category_id FROM `" . DB_PREFIX . "category_description` WHERE `category_id` = " . $data['category_id'] . " AND `language_id` = " . $this->LANG_ID);
  1735.             if (!$query->num_rows) {
  1736.                 $this->query("INSERT INTO `" . DB_PREFIX . "category_description` SET `category_id` = " . $data['category_id'] . ", `language_id` = " . $this->LANG_ID . ", " . $fields);
  1737.             }
  1738.         }
  1739.  
  1740.         // Запись иерархии категорий для админки
  1741.         $this->addHierarchical($data['category_id'], $data);
  1742.  
  1743.         // Магазин
  1744.         $this->query("INSERT INTO `" . DB_PREFIX . "category_to_store` SET `category_id` = " . $data['category_id'] . ", `store_id` = " . $this->STORE_ID);
  1745.  
  1746.         // Добавим линк
  1747.         $this->insertCategoryLinkToGuid($data['category_id'], $data['guid']);
  1748.  
  1749.         // Чистим кэш
  1750.         $this->cache->delete('category');
  1751.  
  1752.         $this->log("Добавлена категория: '" . $data['name'] . "'");
  1753.  
  1754.         return $data['category_id'];
  1755.  
  1756.     } // addCategory()
  1757.  
  1758.  
  1759.     /**
  1760.      * ver 1
  1761.      * update 2017-04-24
  1762.      * Парсит свойства товарных категорий из XML
  1763.      */
  1764.     private function parseCategoryAttributes($xml, $data, $attributes) {
  1765.  
  1766.         if (!isset($attributes)) {
  1767.             $this->ERROR = "parseCategoryAttributes() - Классификатор не содержит атрибутов";
  1768.             return false;
  1769.         }
  1770.  
  1771.         foreach ($xml->Ид as $attribute) {
  1772.             $guid = (string)$xml->Ид;
  1773.             $this->log("> Свойство, Ид: " . $guid, 2);
  1774.             //if (isset($attributes[$guid])) {
  1775.             //  $this->log($attributes[$guid], 2);
  1776.             //}
  1777.         }
  1778.         return true;
  1779.  
  1780.     } //parseCategoryAttributes()
  1781.  
  1782.  
  1783.     /**
  1784.      * ver 4
  1785.      * update 2017-05-18
  1786.      * Парсит товарные категории из классификатора
  1787.      */
  1788.     private function parseClassifierProductCategories($xml, $parent_id = 0, $classifier) {
  1789.  
  1790.         $this->log($classifier, 2);
  1791.  
  1792.         $result = array();
  1793.         $array = $this->config->get('exchange1c_parse_categories_in_memory');
  1794.  
  1795.         if (!$xml->Категория) {
  1796.             $this->ERROR = "parseClassifierProductCategories() - Элемент с названием 'Категория' не найдена";
  1797.             return false;
  1798.         }
  1799.         foreach ($xml->Категория as $category){
  1800.             $data = array();
  1801.             $data['guid']           = (string)$category->Ид;
  1802.             $data['name']           = (string)$category->Наименование;
  1803.             $data['parent_id']      = $parent_id;
  1804.             $data['status']         = 1;
  1805.             if ($parent_id == 0)
  1806.                 $data['top']        = 1;
  1807.             $data['category_id']    = $this->getCategoryIdByGuid($data['guid']);
  1808.             if (!$data['category_id']) {
  1809.                 $this->addCategory($data);
  1810.             } else {
  1811.                 $this->updateCategory($data);
  1812.             }
  1813.             if ($array == 1) {
  1814.                 $result[$data['guid']] = $data['category_id'];
  1815.             }
  1816.  
  1817.             if ($category->Категории) {
  1818.  
  1819.                 $result1 = $this->parseClassifierProductCategories($category->Категории, $data['category_id'], $classifier);
  1820.                 if ($this->ERROR) return false;
  1821.  
  1822.                 if ($array == 1) {
  1823.                     $result = array_merge($result, $result1);
  1824.                 }
  1825.             }
  1826.  
  1827.             // Свойства для категории
  1828.             if ($category->Свойства && isset($classifier['attributes'])) {
  1829.  
  1830.                 $this->parseCategoryAttributes($category->Свойства, $data, $classifier['attributes']);
  1831.                 if ($this->ERROR) return false;
  1832.  
  1833.             }
  1834.  
  1835.             unset($data);
  1836.         }
  1837.         return $result;
  1838.  
  1839.     } // parseClassifierProductCategories()
  1840.  
  1841.  
  1842.     /**
  1843.      * ver 4
  1844.      * update 2017-04-27
  1845.      * Парсит группы в классификаторе в XML
  1846.      */
  1847.     private function parseClassifierCategories($xml, $parent_id = 0, $classifier) {
  1848.  
  1849.         $result = array();
  1850.         $array = $this->config->get('exchange1c_parse_categories_in_memory');
  1851.  
  1852.         foreach ($xml->Группа as $category) {
  1853.             if (isset($category->Ид) && isset($category->Наименование) ){
  1854.  
  1855.                 $data = array();
  1856.                 $data['guid']           = (string)$category->Ид;
  1857.                 if ($category->Код && $this->config->get('exchange1c_synchronize_by_code') == 1) {
  1858.                     $data['code']       = (int)$category->Код;
  1859.                     $data['category_id'] = $this->getCategoryIdByCode($data['code']);
  1860.                 } else {
  1861.                     $data['category_id']= $this->getCategoryIdByGuid($data['guid']);
  1862.                 }
  1863.                 $data['parent_id']      = $parent_id;
  1864.  
  1865.                 // По умолчанию включена категория
  1866.                 $data['status']         = 1;
  1867.  
  1868.                 // Сортировка категории (по просьбе Val)
  1869.                 if ($category->Сортировка) {
  1870.                     $data['sort_order'] = (int)$category->Сортировка;
  1871.                 }
  1872.  
  1873.                 // Картинка категории (по просьбе Val)
  1874.                 if ($category->Картинка) {
  1875.                     $data['image']      = (string)$category->Картинка;
  1876.                 }
  1877.  
  1878.                 // Если пометка удаления есть, значит будет отключен
  1879.                 if ((string)$category->ПометкаУдаления == 'true') {
  1880.                     $data['status'] = 0;
  1881.                 }
  1882.  
  1883.  
  1884.                 if ($parent_id == 0)
  1885.                     $data['top']        = 1;
  1886.  
  1887.                 // Определяем наименование и порядок, сортировка - число до точки, наименование все что после точки
  1888.                 $data['name'] = (string)$category->Наименование;
  1889.                 $split = $this->splitNameStr($data['name'], false);
  1890.                 if ($split['order']) {
  1891.                     $data['sort_order'] = $split['order'];
  1892.                 }
  1893.                 if ($split['name']) {
  1894.                     $data['name']   = $split['name'];
  1895.                 }
  1896.  
  1897.                 // Свойства для группы
  1898.                 if ($category->ЗначенияСвойств && isset($classifier['attributes'])) {
  1899.                     if (!$this->parseAttributes($category->ЗначенияСвойств, $data, $classifier['attributes'])) {
  1900.                         return false;
  1901.                     }
  1902.                 }
  1903.  
  1904.                 // Обработка свойств
  1905.                 if (isset($data['attributes'])) {
  1906.                     foreach ($data['attributes'] as $attribute) {
  1907.                         if ($attribute['name'] == 'Картинка') {
  1908.                             $data['image'] = "catalog/" . $attribute['value'];
  1909.                             $this->log("Установлена картинка для категории из свойства = " . $data['image']);
  1910.                         } elseif ($attribute['name'] == 'Сортировка') {
  1911.                             $data['sort_order'] = $attribute['value'];
  1912.                             $this->log("Установлена сортировка для категории из свойства = " . $data['sort_order']);
  1913.                         }
  1914.                     }
  1915.                 }
  1916.  
  1917.                 $this->log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 2);
  1918.                 $this->log("КАТЕГОРИЯ: '" . $data['name'] . "', Ид: " . $data['guid'], 2);
  1919.  
  1920.                 // Если не нашли категорию по Ид, пытаемся найти по имени учитывая id родительской категории
  1921.                 if (!$data['category_id']) {
  1922.                     $data['category_id'] = $this->getCategoryIdByName($data['name'], $parent_id);
  1923.                     // Если нашли, добавляем связь
  1924.                     if ($data['category_id'])
  1925.                         $this->insertCategoryLinkToGuid($data['category_id'], $data['guid']);
  1926.                 }
  1927.  
  1928.                 if (!$data['category_id']) {
  1929.                     if ($this->config->get('exchange1c_create_new_category') == 1) {
  1930.                         $data['category_id'] = $this->addCategory($data);
  1931.                     }
  1932.                 } else {
  1933.                     $this->updateCategory($data);
  1934.                 }
  1935.                 if ($array == 1) {
  1936.                     $result[$data['guid']] = $data['category_id'];
  1937.                 }
  1938.             }
  1939.  
  1940.             // Обнуляем остаток у товаров в этой категории
  1941.             if ($this->config->get('exchange1c_flush_quantity') == 'category') {
  1942.                 // Обнуляем остаток только в текущем магазине
  1943.                 $query = $this->query("SELECT `p`.`product_id` FROM `" . DB_PREFIX . "product` `p` LEFT JOIN `" . DB_PREFIX . "product_to_category` `p2c` ON (`p`.`product_id` = `p2c`.`product_id`) LEFT JOIN `" . DB_PREFIX . "product_to_store` `p2s` ON (`p`.`product_id` = `p2s`.`product_id`) WHERE `p2c`.`category_id` = " . $data['category_id'] . " AND `p2s`.`store_id` = " . $this->STORE_ID);
  1944.                 if ($query->num_rows) {
  1945.                     if ($this->config->get('exchange1c_product_disable_if_quantity_zero') == 1) {
  1946.                         $status = ", `status` = 0";
  1947.                     } else {
  1948.                         $status = "";
  1949.                     }
  1950.                     foreach ($query->rows as $row) {
  1951.                         $this->query("UPDATE `" . DB_PREFIX . "product` SET `quantity` = 0 " . $status . " WHERE `product_id` = " . $row['product_id']);
  1952.                         $this->query("UPDATE `" . DB_PREFIX . "product_quantity` SET `quantity` = 0 WHERE `product_id` = " . $row['product_id']);
  1953.                     }
  1954.                 }
  1955.             }
  1956.  
  1957.             if ($category->Группы) {
  1958.                 $result1 = $this->parseClassifierCategories($category->Группы, $data['category_id'], $classifier);
  1959.                 if ($this->ERROR) return false;
  1960.  
  1961.                 if ($array == 1) {
  1962.                     $result = array_merge($result, $result1);
  1963.                 }
  1964.             }
  1965.         }
  1966.         return $result;
  1967.  
  1968.     } // parseClassifierCategories()
  1969.  
  1970.  
  1971.     /**
  1972.      * ******************************************* ОПЦИИ *********************************************
  1973.      */
  1974.  
  1975.  
  1976.     /**
  1977.      * ver 2
  1978.      * update 2017-06-12
  1979.      * Добавляет или получает значение опции по названию
  1980.      */
  1981.     private function setOptionValue($option_id, $value, $sort_order = '', $image = '') {
  1982.  
  1983.         $option_value_id = 0;
  1984.  
  1985.         $data = array();
  1986.         if ($sort_order) {
  1987.             $data['sort_order'] = $sort_order;
  1988.         }
  1989.         if ($image) {
  1990.             $data['image'] = $image;
  1991.         }
  1992.  
  1993.         // Проверим есть ли такое значение
  1994.         $query = $this->query("SELECT `ovd`.`option_value_id`,`ov`.`sort_order`,`ov`.`image` FROM `" . DB_PREFIX . "option_value_description` `ovd` LEFT JOIN `" . DB_PREFIX . "option_value` `ov` ON (`ovd`.`option_value_id` = `ov`.`option_value_id`) WHERE `ovd`.`language_id` = " . $this->LANG_ID . " AND `ovd`.`option_id` = " . $option_id . " AND `ovd`.`name` = '" . $this->db->escape($value) . "'");
  1995.         if ($query->num_rows) {
  1996.             $option_value_id = $query->row['option_value_id'];
  1997.  
  1998.             // Сравнивает запрос с массивом данных и формирует список измененных полей
  1999.             $fields = $this->compareArrays($query, $data);
  2000.  
  2001.             // Если есть расхождения, производим обновление
  2002.             if ($fields) {
  2003.                 $this->query("UPDATE `" . DB_PREFIX . "option_value` SET " . $fields . " WHERE `option_value_id` = " . $option_value_id);
  2004.                 $this->log("Значение опции обновлено: '" . $value . "'");
  2005.             }
  2006.  
  2007.             return $option_value_id;
  2008.         }
  2009.  
  2010.         $sql = $sort_order == "" ? "" : ", `sort_order` = " . (int)$sort_order;
  2011.         $query = $this->query("INSERT INTO `" . DB_PREFIX . "option_value` SET `option_id` = " . $option_id . ", `image` = '" . $this->db->escape($image) . "'" . $sql);
  2012.         $option_value_id = $this->db->getLastId();
  2013.  
  2014.         if ($option_value_id) {
  2015.             $query = $this->query("INSERT INTO `" . DB_PREFIX . "option_value_description` SET `option_id` = " . $option_id . ", `option_value_id` = " . $option_value_id . ", `language_id` = " . $this->LANG_ID . ", `name` = '" . $this->db->escape($value) . "'");
  2016.             $this->log("Значение опции добавлено: '" . $value . "'");
  2017.         }
  2018.  
  2019.         return $option_value_id;
  2020.  
  2021.     } // setOptionValue()
  2022.  
  2023.  
  2024.  
  2025.     /**
  2026.      * Установка опции
  2027.      */
  2028.     private function setOption($name, $type = 'select', $sort_order = 0) {
  2029.  
  2030.         $query = $this->query("SELECT `o`.`option_id`, `o`.`type`, `o`.`sort_order` FROM `" . DB_PREFIX . "option` `o` LEFT JOIN `" . DB_PREFIX . "option_description` `od` ON (`o`.`option_id` = `od`.`option_id`) WHERE `od`.`name` = '" . $this->db->escape($name) . "' AND `od`.`language_id` = " . $this->LANG_ID);
  2031.         if ($query->num_rows) {
  2032.  
  2033.             $option_id = $query->row['option_id'];
  2034.  
  2035.             $fields = array();
  2036.             if ($query->row['type'] <> $type) {
  2037.                 $fields[] = "`type` = '" . $type . "'";
  2038.             }
  2039.  
  2040.             if ($sort_order) {
  2041.                 if ($query->row['sort_order'] <> $sort_order) {
  2042.                     $fields[] = "`sort_order` = " . (int)$sort_order;
  2043.                 }
  2044.             }
  2045.             $fields = implode(', ', $fields);
  2046.             if ($fields) {
  2047.                 $this->query("UPDATE `" . DB_PREFIX . "option` SET " . $fields . " WHERE `option_id` = " . $option_id);
  2048.                 $this->log("Опция обновлена: '" . $name . "'");
  2049.             }
  2050.  
  2051.         } else {
  2052.             // Если опции нет, добавляем
  2053.             $option_id = $this->addOption($name, $type);
  2054.         }
  2055.         return $option_id;
  2056.  
  2057.     } // setOption()
  2058.  
  2059.  
  2060.     /**
  2061.      * **************************************** ОПЦИИ ТОВАРА ******************************************
  2062.      */
  2063.  
  2064.  
  2065.     /**
  2066.      * ver 9
  2067.      * update 2017-04-16
  2068.      * Добавляет или обновляет опции в товаре
  2069.      */
  2070.     private function setProductOptions($options, $product_id, $product_feature_id = 0, $new = false) {
  2071.  
  2072.         if (empty($options)) {
  2073.             $this->ERROR = "setProductOptions() - нет опций";
  2074.             return false;
  2075.         }
  2076.  
  2077. //      if (!$new) {
  2078. //          $old_option = array();
  2079. //          $old_option_value = array();
  2080. //          // Читаем старые опции товара текущей характеристики
  2081. //          $query = $this->query("SELECT `product_option_value_id`,`product_option_id` FROM `" . DB_PREFIX . "product_option_value` WHERE `product_id` = " . $product_id);
  2082. //          foreach ($query->rows as $field) {
  2083. //              $old_option[$field['product_option_id']]                = $field['product_option_id'];
  2084. //              $old_option_value[$field['product_option_value_id']]    = $field['product_option_value_id'];
  2085. //          }
  2086. //          $this->log($old_option, 2);
  2087. //          $this->log($old_option_value, 2);
  2088. //      }
  2089.  
  2090.         foreach ($options as $option_value_id => $option) {
  2091.  
  2092.             // Запишем опции в товар
  2093.             $option['product_option_id'] = $this->setProductOption($option['option_id'], $product_id, 1, $new);
  2094. //          if (!$new) {
  2095. //              $key = array_search($option['product_option_id'], $old_option);
  2096. //              if ($key !== false) {
  2097. //                  unset($old_option[$key]);
  2098. //              }
  2099. //          }
  2100.  
  2101.             // Запишем значения опции в товар
  2102.             $product_option_value_id = $this->setProductOptionValue($option, $product_id, $option_value_id, $new);
  2103. //          if (!$new) {
  2104. //              $key = array_search($product_option_value_id, $old_option_value);
  2105. //              if ($key !== false) {
  2106. //                  unset($old_option_value[$key]);
  2107. //              }
  2108. //          }
  2109.  
  2110.             // Запишем значения значения характеристики
  2111.             $this->setProductFeatureValue($product_feature_id, $product_id, $product_option_value_id, $new);
  2112. //          if (!$new) {
  2113. //              $key = array_search($product_option_value_id, $old_option_value);
  2114. //              if ($key !== false) {
  2115. //                  unset($old_option_value[$key]);
  2116. //              }
  2117. //          }
  2118.  
  2119.         }
  2120.  
  2121. //      if (!$new) {
  2122. //          $this->log($old_option, 2);
  2123. //          $this->log($old_option_value, 2);
  2124. //          // Удалим старые значения опции из характеристики
  2125. //          if (count($old_option)) {
  2126. //              $this->query("DELETE FROM `" . DB_PREFIX . "product_option` WHERE `product_option_id` IN (" . implode(",",$old_option) . ")");
  2127. //          }
  2128. //          if (count($old_option_value)) {
  2129. //              $this->query("DELETE FROM `" . DB_PREFIX . "product_option_value` WHERE `product_option_value_id` IN (" . implode(",",$old_option_value) . ")");
  2130. //          }
  2131. //      }
  2132.  
  2133.         return true;
  2134.  
  2135.     }  // setProductOptions()
  2136.  
  2137.  
  2138.     /**
  2139.      * ver 3
  2140.      * update 2017-04-17
  2141.      * Устанавливает опцию в товар и возвращает ID
  2142.      */
  2143.     private function setProductOption($option_id, $product_id, $required = 1, $new = false) {
  2144.  
  2145.         $product_option_id = 0;
  2146.         if (!$new) {
  2147.             $query = $this->query("SELECT `product_option_id` FROM `" . DB_PREFIX . "product_option` WHERE `product_id` = " . $product_id . " AND `option_id` = " . $option_id);
  2148.             if ($query->num_rows) {
  2149.                 $product_option_id = $query->row['product_option_id'];
  2150.             }
  2151.         }
  2152.         if (!$product_option_id) {
  2153.             $this->query("INSERT INTO `" . DB_PREFIX . "product_option` SET `product_id` = " . $product_id . ", `option_id` = " . $option_id . ", `required` = " . $required);
  2154.             $product_option_id = $this->db->getLastId();
  2155.         }
  2156.         return $product_option_id;
  2157.  
  2158.     } // setProductOption()
  2159.  
  2160.  
  2161.     /**
  2162.      * ver 6
  2163.      * update 2017-04-18
  2164.      * Устанавливаем значение опции в товар
  2165.      */
  2166.     private function setProductOptionValue($option, $product_id, $option_value_id, $new = false) {
  2167.  
  2168.         $product_option_value_id = 0;
  2169.         if (!$new) {
  2170.             $query = $this->query("SELECT `product_option_value_id`,`quantity`,`price_prefix`,`price` FROM `" . DB_PREFIX . "product_option_value` WHERE `product_option_id` = " . $option['product_option_id'] . " AND `product_id` = " . $product_id . " AND `option_id` = " . $option['option_id'] . " AND option_value_id = " . $option_value_id);
  2171.             if ($query->num_rows) {
  2172.                 $product_option_value_id = $query->row['product_option_value_id'];
  2173.             }
  2174.             // изменения
  2175.             $fields = $this->compareArrays($query, $option);
  2176.             if ($fields) {
  2177.                 $this->query("UPDATE `" . DB_PREFIX . "product_option_value` SET " . $fields . " WHERE `product_option_value_id` = " . $product_option_value_id);
  2178.             }
  2179.         }
  2180.         if (!$product_option_value_id) {
  2181.             $this->query("INSERT INTO `" . DB_PREFIX . "product_option_value` SET `product_option_id` = " . $option['product_option_id'] . ", `product_id` = " . $product_id . ", `option_id` = " . $option['option_id'] . ", `option_value_id` = " . $option_value_id . ", quantity = " . (float)$option['quantity'] . ", `subtract` = " . $option['subtract']);
  2182.             $product_option_value_id = $this->db->getLastId();
  2183.         }
  2184.         return $product_option_value_id;
  2185.  
  2186.     } // setProductOptionValue()
  2187.  
  2188.  
  2189.     /**
  2190.      * ************************************ ФУНКЦИИ ДЛЯ РАБОТЫ С ХАРАКТЕРИСТИКАМИ *************************************
  2191.      */
  2192.  
  2193.  
  2194.     /**
  2195.      * ver 10
  2196.      * update 2017-06-14
  2197.      * Создает или возвращает характеристику по Ид
  2198.      * устанавливает цены в таблицу product_price
  2199.      * устанавливает стандартные опции товара
  2200.      * устанавливает остатки характеристики в таблицу product
  2201.      */
  2202.     private function setProductFeature($feature_data, $product_id, $feature_guid, $new = false) {
  2203.  
  2204.         if (!$feature_guid) {
  2205.             $this->ERROR = "setProductFeature() - Не указан Ид характеристики";
  2206.             return false;
  2207.         }
  2208.  
  2209.         $product_feature_id = 0;
  2210.         if (!$new) {
  2211.             $query = $this->query("SELECT `product_feature_id`,`ean`,`name`,`sku` FROM `" . DB_PREFIX . "product_feature` WHERE `guid` = '" . $this->db->escape($feature_guid) . "' AND `product_id` = " . $product_id);
  2212.             if ($query->num_rows) {
  2213.                 $product_feature_id = $query->row['product_feature_id'];
  2214.             }
  2215.             if ($product_feature_id) {
  2216.                 // Сравнивает запрос с массивом данных и формирует список измененных полей
  2217.                 $fields = $this->compareArrays($query, $feature_data);
  2218.  
  2219.                 if ($fields) {
  2220.                     $this->query("UPDATE `" . DB_PREFIX . "product_feature` SET " . $fields . " WHERE `product_feature_id` = " . $product_feature_id);
  2221.                 }
  2222.             }
  2223.         }
  2224.         if (!$product_feature_id) {
  2225.             // добавляем
  2226.             $this->query("INSERT INTO `" . DB_PREFIX . "product_feature` SET `product_id` = " . $product_id . ", `guid` = '" . $this->db->escape($feature_guid) . "'");
  2227.             $product_feature_id = $this->db->getLastId();
  2228.         }
  2229.  
  2230.         // Опции в характеристике
  2231.         if (isset($feature_data['options'])) {
  2232.             $this->setProductOptions($feature_data['options'], $product_id, $product_feature_id, $new);
  2233.         }
  2234.  
  2235.         // Единицы измерения
  2236.         if (isset($feature_data['unit'])) {
  2237.             $this->log($feature_data['unit'], 2);
  2238.             $this->setProductUnit($feature_data['unit'], $product_id, $product_feature_id, $new);
  2239.         }
  2240.  
  2241.         // Цены
  2242.         if (isset($feature_data['prices'])) {
  2243.             $this->setProductFeaturePrices($feature_data['prices'], $product_id, $product_feature_id, $new);
  2244.         }
  2245.  
  2246.         // Остатки по складам
  2247.         if (isset($feature_data['quantities'])) {
  2248.             $this->setProductQuantities($feature_data['quantities'], $product_id, $product_feature_id, $new);
  2249.             if ($this->ERROR) return false;
  2250.         }
  2251.  
  2252.         return $product_feature_id;
  2253.  
  2254.     } // setProductFeature()
  2255.  
  2256.  
  2257.     /**
  2258.      * ver 1
  2259.      * update 2017-04-18
  2260.      * Устанавливаем значение характеристики
  2261.      */
  2262.     private function setProductFeatureValue($product_feature_id, $product_id, $product_option_value_id, $new = false) {
  2263.  
  2264.         if (!$new) {
  2265.             $query = $this->query("SELECT * FROM `" . DB_PREFIX . "product_feature_value` WHERE `product_feature_id` = " . $product_feature_id . " AND `product_id` = " . $product_id . " AND `product_option_value_id` = " . $product_option_value_id);
  2266.             if ($query->num_rows) {
  2267.                 return false;
  2268.             }
  2269.         }
  2270.         $this->query("INSERT INTO `" . DB_PREFIX . "product_feature_value` SET `product_feature_id` = " . $product_feature_id . ", `product_id` = " . $product_id . ", `product_option_value_id` = " . $product_option_value_id);
  2271.         $product_option_value_id = $this->db->getLastId();
  2272.         return true;
  2273.  
  2274.     } // setProductFeatureValue()
  2275.  
  2276.  
  2277.     /**
  2278.      * Находит характеристику товара по GUID
  2279.      */
  2280.     private function getProductFeatureIdByGUID($feature_guid) {
  2281.  
  2282.         // Ищем характеристику по Ид
  2283.         $query = $this->query("SELECT `product_feature_id` FROM `" . DB_PREFIX . "product_feature` WHERE `guid` = '" . $this->db->escape($feature_guid) . "'");
  2284.         if ($query->num_rows) {
  2285.             return $query->row['product_feature_id'];
  2286.         }
  2287.         return 0;
  2288.  
  2289.     } // getProductFeatureIdByGUID()
  2290.  
  2291.  
  2292.     /**
  2293.      * **************************************** ФУНКЦИИ ДЛЯ РАБОТЫ С ТОВАРОМ ******************************************
  2294.      */
  2295.  
  2296.  
  2297.     /**
  2298.      * ver 10
  2299.      * update 2017-06-14
  2300.      * Добавляет товар в базу
  2301.      */
  2302.     private function addProduct(&$data) {
  2303.  
  2304.         $data['status'] = $this->config->get('exchange1c_status_new_product') == 1 ? 1 : 0;
  2305.  
  2306.         // Подготовим список полей по которым есть данные
  2307.         $fields = $this->prepareQueryProduct($data);
  2308.         if ($fields) {
  2309.             if ($this->config->get('exchange1c_synchronize_by_code') == 1) {
  2310.                 $query_product_id = isset($data['code']) ? ", `product_id` = " . (int)$data['code'] : "";
  2311.             } else {
  2312.                 $query_product_id = "";
  2313.             }
  2314.  
  2315.             $this->query("INSERT INTO `" . DB_PREFIX . "product` SET " . $fields . $query_product_id . ", `date_added` = '" . $this->NOW . "', `date_modified` = '" . $this->NOW . "'");
  2316.             $data['product_id'] = $this->db->getLastId();
  2317.         } else {
  2318.             // Если нет данных - выходим
  2319.             $this->ERROR = "addProduct() - нет данных";
  2320.             return false;
  2321.         }
  2322.  
  2323. //      // Полное наименование из 1С в товар
  2324.         if ($this->config->get('exchange1c_import_product_name') == 'fullname' && !empty($data['full_name'])) {
  2325.             if ($data['full_name'])
  2326.                 $data['name'] = $data['full_name'];
  2327.         }
  2328.  
  2329.         // Связь с 1С только по Ид объекта из торговой системы
  2330.         $this->query("INSERT INTO `" . DB_PREFIX . "product_to_1c` SET `product_id` = " . $data['product_id'] . ", `guid` = '" . $this->db->escape($data['product_guid']) . "'");
  2331.  
  2332.         // Устанавливаем магазин
  2333.         $this->query("INSERT INTO `" . DB_PREFIX . "product_to_store` SET `product_id` = " . $data['product_id'] . ", `store_id` = " . $this->STORE_ID);
  2334.  
  2335.         // Записываем атрибуты в товар
  2336.         if (isset($data['attributes'])) {
  2337.             foreach ($data['attributes'] as $attribute) {
  2338.                 $this->query("INSERT INTO `" . DB_PREFIX . "product_attribute` SET `product_id` = " . $data['product_id'] . ", `attribute_id` = " . $attribute['attribute_id'] . ", `language_id` = " . $this->LANG_ID . ", `text` = '" .  $this->db->escape($attribute['value']) . "'");
  2339.             }
  2340.         }
  2341.  
  2342.         // Отзывы парсятся с Яндекса в 1С, а затем на сайт
  2343.         // Доработка от SunLit (Skype: strong_forever2000)
  2344.         // Записываем отзывы в товар
  2345.         if (isset($data['review'])) {
  2346.             $this->setProductReview($data, $data['product_id']);
  2347.             if ($this->ERROR) return false;
  2348.         }
  2349.  
  2350.         // Категории
  2351.         if (isset($data['product_categories'])) {
  2352.             // Заполнение родительских категорий в товаре
  2353.             if ($this->config->get('exchange1c_fill_parent_cats') == 1) {
  2354.                 $data['product_categories'] = $this->fillParentsCategories($data['product_categories']);
  2355.                 if ($this->ERROR) return false;
  2356.             }
  2357.             $this->addProductCategories($data['product_categories'], $data['product_id']);
  2358.             if ($this->ERROR) return false;
  2359.         }
  2360.  
  2361.         // Картинки
  2362.         if (isset($data['images'])) {
  2363.  
  2364.             $this->setProductImages($data['images'], $data['product_id'], true);
  2365.             if ($this->ERROR) return false;
  2366.         }
  2367.  
  2368.         if (isset($data['features'])) {
  2369.  
  2370.             // Несколько характеристик
  2371.             foreach ($data['features'] as $feature_guid => $feature_data) {
  2372.                 $this->setProductFeature($feature_data, $data['product_id'], $feature_guid, true);
  2373.                 if ($this->ERROR) return false;
  2374.             }
  2375.  
  2376.         } elseif ($data['feature_guid']) {
  2377.  
  2378.             // Предложение является одной из характеристик товара
  2379.             $this->setProductFeature($data, $data['product_id'], $data['feature_guid']);
  2380.             if ($this->ERROR) return false;
  2381.  
  2382.         } else {
  2383.  
  2384.             // БЕЗ ХАРАКТЕРИСТИК
  2385.             // Установим единицу измерения
  2386.             $this->setProductUnit($data['unit'], $data['product_id'], 0, true);
  2387.         }
  2388.  
  2389.         // Очистим кэш товаров
  2390.         $this->cache->delete('product');
  2391.         $this->log("Товар добавлен, product_id: " . $data['product_id'],2);
  2392.         return true;
  2393.  
  2394.     } // addProduct()
  2395.  
  2396.  
  2397.     /**
  2398.      * ver 2
  2399.      * update 2017-04-16
  2400.      * Устанавливает товар в магазин который производится загрузка
  2401.      * Если това в этом магазине не найден, то добавляем
  2402.      */
  2403.     private function setProductShop($product_id) {
  2404.  
  2405.         $query = $this->query("SELECT `store_id`  FROM `" . DB_PREFIX . "product_to_store` WHERE `product_id` = " . $product_id . " AND `store_id` = " . $this->STORE_ID);
  2406.         if (!$query->num_rows) {
  2407.             $this->query("INSERT INTO `" . DB_PREFIX . "product_to_store` SET `product_id` = " . $product_id . ", `store_id` = " . $this->STORE_ID);
  2408.             $this->log("> Добавлена привязка товара к магазину store_id: " . $this->STORE_ID,2);
  2409.         }
  2410.  
  2411.     } // setProductShop()
  2412.  
  2413.  
  2414.     /**
  2415.      * ver 5
  2416.      * update 2017-006-17
  2417.      * Устанавливает единицу измерения товара
  2418.      */
  2419.     private function setProductUnit($unit_data, $product_id, $product_feature_id = 0, $new = false) {
  2420.  
  2421.         $this->log("setProductUnit()", 2);
  2422.         $this->log($unit_data,2);
  2423.  
  2424.         $result = array();
  2425.         $product_unit_id = 0;
  2426.         $unit_id = 0;
  2427.  
  2428.         if (!isset($unit_data['unit_id'])) {
  2429.  
  2430.             // Поищем название единицы в классификаторе
  2431.             $where = "";
  2432.             if (isset($unit_data['guid'])) {
  2433.                 $where = " WHERE `guid` = " . $unit_data['guid'];
  2434.             }
  2435.  
  2436.             // Если не указан Ид
  2437.             if (!$where && isset($unit_data['number_code'])) {
  2438.                 $where = " WHERE `number_code` = " . $unit_data['number_code'];
  2439.             }
  2440.  
  2441.             // Если нет Ид и Кода, то ищем по наименованию
  2442.             if (!$where) {
  2443.                 $where = " WHERE `name` = '" . $this->db->escape($unit_data['name']) . "'";
  2444.             }
  2445.  
  2446.             $unit_id = 0;
  2447.             $query = $this->query("SELECT `unit_id` FROM `" . DB_PREFIX . "unit_to_1c`" . $where);
  2448.             if ($query->num_rows) {
  2449.                 $unit_id = $query->row['unit_id'];
  2450.             }
  2451.  
  2452.         } else {
  2453.  
  2454.             $unit_id = $unit_data['unit_id'];
  2455.         }
  2456.  
  2457.         // Если не определена единица из классификатора то создаем ее
  2458.         // Добавим единицу в классификатор
  2459.         if (!$unit_id) {
  2460.             if (!isset($unit_data['number_code'])) {
  2461.                 $unit_split = $this->splitNameStr($unit_data['name']);
  2462.                 $query = $this->query("SELECT `number_code`,`name` FROM `" . DB_PREFIX . "unit` WHERE `rus_name1` = '" . $this->db->escape($unit_split['name']) . "'");
  2463.                 if ($query->num_rows) {
  2464.                     $unit_data['number_code'] = $query->row['number_code'];
  2465.                     if (!isset($unit_data['full_name'])) {
  2466.                         $unit_data['full_name'] = $query->row['name'];
  2467.                     }
  2468.                 }
  2469.             }
  2470.             $number_code = isset($unit_data['number_code']) ? ", `number_code` = " . $unit_data['number_code'] : "";
  2471.             $full_name = isset($unit_data['full_name']) ? ", `full_name` = '" . $this->db->escape($unit_data['full_name']) . "'" : "";
  2472.             $this->query("INSERT INTO `" . DB_PREFIX . "unit_to_1c` SET `name` = '" . $this->db->escape($unit_data['name']) . "'" . $full_name . $number_code);
  2473.             $unit_id = $this->db->getLastId();
  2474.         }
  2475.  
  2476.         if (!$new) {
  2477.  
  2478.             // Прочитаем старые единицы, с указанным коэффициентом у товара может быть только одна единица
  2479.             $query = $this->query("SELECT `product_unit_id` FROM `" . DB_PREFIX . "product_unit` WHERE `product_id` = " . $product_id . " AND `product_feature_id` = " . $product_feature_id . " AND `unit_id` = " . $unit_id . " AND `ratio` = " . $unit_data['ratio']);
  2480.  
  2481.             if ($query->num_rows) {
  2482.                 $product_unit_id = $query->row['product_unit_id'];
  2483.             }
  2484.         }
  2485.  
  2486.         // Добавим единицу в товар
  2487.         if (!$product_unit_id) {
  2488.  
  2489.             $this->query("INSERT INTO `" . DB_PREFIX . "product_unit` SET `product_id` = " . $product_id . ", `product_feature_id` = " . $product_feature_id . ", `unit_id` = " . $unit_id . ", `ratio` = " . $unit_data['ratio']);
  2490.             $product_unit_id = $this->db->getLastId();
  2491.         }
  2492.  
  2493.         $result['product_unit_id'] = $product_unit_id;
  2494.         $result['unit_id'] = $unit_id;
  2495.  
  2496.         return $result;
  2497.  
  2498.     } // setProductUnit()
  2499.  
  2500.  
  2501.     /**
  2502.      * ver 1
  2503.      * update 2017-04-14
  2504.      * Добавляет в товаре категории
  2505.      */
  2506.     private function addProductCategories($product_categories, $product_id) {
  2507.  
  2508.         // если в CMS ведется учет главной категории
  2509.         $main_category = isset($this->TAB_FIELDS['product_to_category']['main_category']);
  2510.  
  2511.         foreach ($product_categories as $index => $category_id) {
  2512.             // старой такой нет категориии
  2513.             $sql  = "INSERT INTO `" . DB_PREFIX . "product_to_category` SET `product_id` = " . $product_id . ", `category_id` = " . $category_id;
  2514.             if ($main_category) {
  2515.                 $sql .= $index == 0 ? ", `main_category` = 1" : ", `main_category` = 0";
  2516.             }
  2517.             $this->query($sql);
  2518.         }
  2519.  
  2520.         $this->log("Категории добавлены в товар");
  2521.         return true;
  2522.  
  2523.     } // addProductCategories()
  2524.  
  2525.  
  2526.     /**
  2527.      * ver 5
  2528.      * update 2017-06-01
  2529.      * Обновляет в товаре категории
  2530.      */
  2531.     private function updateProductCategories($product_categories, $product_id) {
  2532.  
  2533.         // если в CMS ведется учет главной категории
  2534.         $main_category = isset($this->TAB_FIELDS['product_to_category']['main_category']);
  2535.  
  2536.         $field = "";
  2537.         if (isset($this->TAB_FIELDS['product_to_category']['main_category'])) {
  2538.             $field = ", `main_category`";
  2539.             $order_by = " ORDER BY `main_category` DESC";
  2540.         }
  2541.  
  2542.         $old_categories = array();
  2543.         $sql  = "SELECT `category_id`";
  2544.         $sql .= $main_category ? ", `main_category`": "";
  2545.         $sql .= "  FROM `" . DB_PREFIX . "product_to_category` WHERE `product_id` = " . $product_id;
  2546.         $sql .= $main_category ? " ORDER BY `main_category` DESC" : "";
  2547.         $query = $this->query($sql);
  2548.  
  2549.         foreach ($query->rows as $category) {
  2550.             $old_categories[] = $category['category_id'];
  2551.         }
  2552.  
  2553.         foreach ($product_categories as $index => $category_id) {
  2554.             $key = array_search($category_id, $old_categories);
  2555.             if ($key !== false) {
  2556.                 unset($old_categories[$key]);
  2557.                 $this->log("Категория уже есть в товаре, id: " . $category_id, 2);
  2558.             } else {
  2559.                 // старой такой нет категориии
  2560.                 $sql  = "INSERT INTO `" . DB_PREFIX . "product_to_category` SET `product_id` = " . $product_id . ", `category_id` = " . $category_id;
  2561.                 if ($main_category) {
  2562.                     $sql .= $index == 0 ? ", `main_category` = 1" : ", `main_category` = 0";
  2563.                 }
  2564.                 $this->query($sql);
  2565.                 $this->log("Категория добавлена в товар, id: " . $category_id, 2);
  2566.             }
  2567.         }
  2568.  
  2569.         // Если категории товара перезаписывать, тогда удаляем которых нет в торговой системе
  2570.         if ($this->config->get('exchange1c_product_categories') == 'overwrite') {
  2571.             // Старые неиспользуемые категории удаляем
  2572.             if (count($old_categories) > 0) {
  2573.                 $this->query("DELETE FROM `" . DB_PREFIX . "product_to_category` WHERE `product_id` = " . $product_id . " AND `category_id` IN (" . implode(",",$old_categories) . ")");
  2574.                 $this->log("Удалены старые категории товара, id: " . implode(",",$old_categories), 2);
  2575.             }
  2576.         }
  2577.  
  2578.         return true;
  2579.  
  2580.     } // updateProductCategories()
  2581.  
  2582.  
  2583.     /**
  2584.      * ver 2
  2585.      * update 2017-04-14
  2586.      * Отзывы парсятся с Яндекса в 1С, а затем на сайт
  2587.      * Доработка от SunLit (Skype: strong_forever2000)
  2588.      * Устанавливает отзывы в товар из массива
  2589.      */
  2590.     private function setProductReview($data, $product_id) {
  2591.  
  2592.         // Проверяем
  2593.         $product_review = array();
  2594.         $query = $this->query("SELECT `guid` FROM `" . DB_PREFIX . "review` WHERE `product_id` = " . $product_id);
  2595.         foreach ($query->rows as $review) {
  2596.             $product_review[$review['guid']] = "";
  2597.         }
  2598.  
  2599.         foreach ($data['review'] as $property) {
  2600.  
  2601.             if (isset($product_review[$property['id']])) {
  2602.  
  2603.                 $this->log("[i] Отзыв с id: '" . $property['id'] . "' есть в базе сайта. Пропускаем.",2);
  2604.                 unset($product_review[$property['id']]);
  2605.             } else {
  2606.                 // Добавим в товар
  2607.                 $text = '<i class="fa fa-plus-square"></i> ' .$this->db->escape($property['yes']).'<br><i class="fa fa-minus-square"></i> '.$this->db->escape($property['no']).'<br>'.$this->db->escape($property['text']);
  2608.                 $this->query("INSERT INTO `" . DB_PREFIX . "review` SET `guid` = '".$property['id']."',`product_id` = " . $product_id . ", `status` = 1, `author` = '" . $this->db->escape($property['name']) . "', `rating` = " . $property['rate'] . ", `text` = '" .  $text . "', `date_added` = '".$property['date']."'");
  2609.                 $this->log("Отзыв от '" . $this->db->escape($property['name']) . "' записан в товар id: " . $product_id,2);
  2610.             }
  2611.         }
  2612.         $this->log("Отзывы товаров обработаны", 2);
  2613.  
  2614.     } // setProductReview()
  2615.  
  2616.  
  2617.     /**
  2618.      * ver 13
  2619.      * update 2017-06-14
  2620.      * Обновляет товар в базе поля в таблице product
  2621.      * Если есть характеристики, тогда получает общий остаток по уже загруженным характеристикам прибавляет текущий и обновляет в таблице product
  2622.      */
  2623.     private function updateProduct($data) {
  2624.  
  2625.         $this->log($data, 2);
  2626.  
  2627.         // Если товар существует и полная выгрузка, и не является характеристикой
  2628.         // очистка будет происходить даже если из import были прочитаны несколько характеристик, в этом случае старые же не нужны.
  2629.         if ($data['product_id'] && $this->FULL_IMPORT && !$data['feature_guid'])  {
  2630.             $this->cleanProductData($data['product_id']);
  2631.         }
  2632.  
  2633.         //if ($this->config->get('exchange1c_disable_product_full_import') == 1) {
  2634.         //  $this->log("[!] Перед полной загрузкой товар отключается");
  2635.         //  $data['status'] = 0;
  2636.         //}
  2637.  
  2638.         $update = false;
  2639.  
  2640.         // ФИЛЬТР ОБНОВЛЕНИЯ
  2641.         // Наименование товара
  2642.         if (isset($data['name'])) {
  2643.             if ($this->config->get('exchange1c_import_product_name') == 'disable' || $data['name'] == '') {
  2644.                 unset($data['name']);
  2645.                 $this->log("[i] Обновление названия отключено",2);
  2646.             }
  2647.         }
  2648.         // КОНЕЦ ФИЛЬТРА
  2649.  
  2650.         // Записываем атрибуты в товар
  2651.         if (isset($data['attributes'])) {
  2652.             $this->updateProductAttributes($data['attributes'], $data['product_id']);
  2653.             if ($this->ERROR) return false;
  2654.         }
  2655.  
  2656.         // Отзывы парсятся с Яндекса в 1С, а затем на сайт
  2657.         // Доработка от SunLit (Skype: strong_forever2000)
  2658.         // Записываем отзывы в товар
  2659.         if (isset($data['review'])) {
  2660.             $this->setProductReview($data);
  2661.             if ($this->ERROR) return false;
  2662.         }
  2663.  
  2664.         // Категории
  2665.         if (isset($data['product_categories'])) {
  2666.             // Заполнение родительских категорий в товаре
  2667.             if ($this->config->get('exchange1c_fill_parent_cats') == 1) {
  2668.                 $data['product_categories'] = $this->fillParentsCategories($data['product_categories']);
  2669.                 if ($this->ERROR) return false;
  2670.             }
  2671.             $this->updateProductCategories($data['product_categories'], $data['product_id']);
  2672.             if ($this->ERROR) return false;
  2673.         }
  2674.  
  2675.         // Картинки
  2676.         if (isset($data['images'])) {
  2677.             $this->setProductImages($data['images'], $data['product_id']);
  2678.             if ($this->ERROR) return false;
  2679.         }
  2680.  
  2681.         // Предложение является одной характеристикой
  2682.         $product_feature_id = 0;
  2683.         if ($data['feature_guid']) {
  2684.             // Предложение является одной из характеристик товара
  2685.             $product_feature_id = $this->setProductFeature($data, $data['product_id'], $data['feature_guid']);
  2686.             if ($this->ERROR) return false;
  2687.         } else {
  2688.             // В предложении несколько характеристик, обычно там только опции
  2689.             if (isset($data['features'])) {
  2690.                 foreach ($data['features'] as $feature_guid => $feature_data) {
  2691.                     $this->setProductFeature($feature_data, $data['product_id'], $feature_guid);
  2692.                     if ($this->ERROR) return false;
  2693.                 }
  2694.             }
  2695.         }
  2696.  
  2697.         // Остатки товара по складам
  2698.         if (isset($data['quantities'])) {
  2699.             $this->setProductQuantities($data['quantities'], $data['product_id'], $product_feature_id);
  2700.             if ($this->ERROR) return false;
  2701.  
  2702.             // Получим общий остаток товара
  2703.             $quantity_total = $this->getProductQuantityTotal($data['product_id']);
  2704.             if ($quantity_total !== false) {
  2705.                 $this->log("Остаток общий: " . $quantity_total);
  2706.                 $data['quantity'] = $quantity_total;
  2707.  
  2708.                 if ($this->config->get('exchange1c_product_disable_if_quantity_zero') == 1 && $data['quantity'] <= 0) {
  2709.                     $data['status'] = 0;
  2710.                     $this->log("Товар отключен, так как общий остаток товара <= 0");
  2711.                 }
  2712.             }
  2713.  
  2714.             //unset($data['quantities']);
  2715.         }
  2716.  
  2717.         // цены по складам, характеристикам
  2718.         if (isset($data['prices'])) {
  2719.             // Записываем цены в акции или скидки и возвращает цену для записи в товар
  2720.             $data['price'] = $this->setProductPrices($data['prices'], $data['product_id'], $product_feature_id);
  2721.             if ($this->ERROR) return false;
  2722.  
  2723.             // Если это характеристика
  2724.             if ($data['feature_guid']) {
  2725.                 $price = $this->getProductPriceMin($data['product_id']);
  2726.                 if ($price !== false) {
  2727.                     $data['price'] = $price;
  2728.                     $this->log("Основная цена (мин): " . $data['price'], 2);
  2729.                 }
  2730.             }
  2731.             //unset($data['prices']);
  2732.             // Отключим товар если не показывать с нулевой ценой
  2733.             if ($this->config->get('exchange1c_product_disable_if_price_zero') == 1 && $data['price'] <= 0 ) {
  2734.                 $data['status'] = 0;
  2735.                 $this->log("Товар отключен, так как цена <= 0");
  2736.             }
  2737.         }
  2738.  
  2739.         // Полное наименование из 1С в товар
  2740.         if ($this->config->get('exchange1c_import_product_name') == 'fullname' && isset($data['full_name'])) {
  2741.             if ($data['full_name']) {
  2742.                 $data['name'] = $data['full_name'];
  2743.             }
  2744.         }
  2745.  
  2746.         // Читаем только те данные, которые получены из файла
  2747.         $fields = $this->prepareQueryProduct($data, 'get');
  2748.         if ($fields) {
  2749.             $query = $this->query("SELECT " . $fields . "  FROM `" . DB_PREFIX . "product` WHERE `product_id` = " . $data['product_id']);
  2750.         }
  2751.  
  2752.         // Сравнивает запрос с массивом данных и формирует список измененных полей
  2753.         $fields = $this->compareArrays($query, $data);
  2754.  
  2755.         // Если есть что обновлять
  2756.         if ($fields) {
  2757.             $this->query("UPDATE `" . DB_PREFIX . "product` SET " . $fields . ", `date_modified` = '" . $this->NOW . "' WHERE `product_id` = " . $data['product_id']);
  2758.             $this->log("Товар обновлен, product_id = " . $data['product_id'], 2);
  2759.             $update = true;
  2760.         } else {
  2761.             // Обновляем date_modified для того чтобы отключить те товары которые не были в выгрузке при полном обмене
  2762.             if ($this->FULL_IMPORT) {
  2763.                 $this->query("UPDATE `" . DB_PREFIX . "product` SET `date_modified` = '" . $this->NOW . "' WHERE `product_id` = " . $data['product_id']);
  2764.                 $this->log("В товаре обновлено поле date_modified", 2);
  2765.             }
  2766.         }
  2767.  
  2768.         // Устанавливаем магазин
  2769.         $this->setProductShop($data['product_id']);
  2770.  
  2771.         // Очистим кэш товаров
  2772.         $this->cache->delete('product');
  2773.         return $update;
  2774.  
  2775.     } // updateProduct()
  2776.  
  2777.  
  2778.     /**
  2779.      * Устанавливает описание товара в базе для одного языка
  2780.      */
  2781.     private function setProductDescription($data, $new = false) {
  2782.  
  2783.         $this->log("Обновление описания товара");
  2784.  
  2785.         if (!$new) {
  2786.             $select_fields = $this->prepareStrQueryDescription($data, 'get');
  2787.             $update_fields = false;
  2788.             if ($select_fields) {
  2789.                 $query = $this->query("SELECT " . $select_fields . " FROM `" . DB_PREFIX . "product_description` WHERE `product_id` = " . $data['product_id'] . " AND `language_id` = " . $this->LANG_ID);
  2790.                 if ($query->num_rows) {
  2791.                     // Сравнивает запрос с массивом данных и формирует список измененных полей
  2792.                     $update_fields = $this->compareArrays($query, $data);
  2793.                 } else {
  2794.                     $new = true;
  2795.                 }
  2796.             }
  2797.             // Если есть расхождения, производим обновление
  2798.             if ($update_fields) {
  2799.                 $this->query("UPDATE `" . DB_PREFIX . "product_description` SET " . $update_fields . " WHERE `product_id` = " . $data['product_id'] .  " AND `language_id` = " . $this->LANG_ID);
  2800.                 $this->log("Описание товара обновлено, поля: '" . $update_fields . "'",2);
  2801.                 return true;
  2802.             }
  2803.         }
  2804.         if ($new) {
  2805.             $insert_fields = $this->prepareStrQueryDescription($data, 'set');
  2806.             $this->query("INSERT INTO `" . DB_PREFIX . "product_description` SET `product_id` = " . $data['product_id'] . ", `language_id` = " . $this->LANG_ID . ", " . $insert_fields);
  2807.         }
  2808.  
  2809.         return false;
  2810.  
  2811.     } // setProductDescription()
  2812.  
  2813.  
  2814.     /**
  2815.      * Получает product_id по артикулу
  2816.      */
  2817.     private function getProductBySKU($sku) {
  2818.  
  2819.         $query = $this->query("SELECT `product_id` FROM `" . DB_PREFIX . "product` WHERE `sku` = '" . $this->db->escape($sku) . "'");
  2820.         if ($query->num_rows) {
  2821.             $this->log("Найден product_id: " . $query->row['product_id'] . " по артикулу '" . $sku . "'",2);
  2822.             return $query->row['product_id'];
  2823.         }
  2824.         $this->log("Не найден товар по артикулу '" . $sku . "'",2);
  2825.         return 0;
  2826.  
  2827.     } // getProductBySKU()
  2828.  
  2829.  
  2830.     /**
  2831.      * Получает product_id по наименованию товара
  2832.      */
  2833.     private function getProductByName($name) {
  2834.  
  2835.         $query = $this->query("SELECT `pd`.`product_id` FROM `" . DB_PREFIX . "product` `p` LEFT JOIN `" . DB_PREFIX . "product_description` `pd` ON (`p`.`product_id` = `pd`.`product_id`) WHERE `name` = LOWER('" . $this->db->escape(strtolower($name)) . "')");
  2836.         if ($query->num_rows) {
  2837.             $this->log("Найден product_id: " . $query->row['product_id'] . " по названию '" . $name . "'",2);
  2838.             return $query->row['product_id'];
  2839.         }
  2840.         $this->log("Не найден товар по названию '" . $name . "'",2);
  2841.         return 0;
  2842.  
  2843.     } // getProductByName()
  2844.  
  2845.  
  2846.     /**
  2847.      * Получает product_id по наименованию товара
  2848.      */
  2849.     private function getProductByEAN($ean) {
  2850.  
  2851.         $query = $this->query("SELECT `product_id` FROM `" . DB_PREFIX . "product` WHERE `ean` = '" . $ean . "'");
  2852.         if ($query->num_rows) {
  2853.             $this->log("Найден товар по штрихкоду, product_id: " . $query->row['product_id'] . " по штрихкоду '" . $ean . "'",2);
  2854.             return $query->row['product_id'];
  2855.         }
  2856.         $this->log("Не найден товар по штрихкоду '" . $ean . "'",2);
  2857.         return 0;
  2858.  
  2859.     } // getProductByEAN()
  2860.  
  2861.  
  2862.     /**
  2863.      * ver 7
  2864.      * update 2017-06-14
  2865.      * Обновление или добавление товара
  2866.      * вызывается при обработке каталога
  2867.      */
  2868.     private function setProduct(&$data) {
  2869.  
  2870.         // Проверка на ошибки
  2871.         if (empty($data)) {
  2872.             $this->ERROR = "setProduct() - Нет входящих данных";
  2873.             return false;
  2874.         }
  2875.  
  2876.         if (!$data['product_id']) {
  2877.             // Поиск существующего товара
  2878.             if (isset($data['code']) && $this->config->get('exchange1c_synchronize_by_code') == 1) {
  2879.                 // Синхронизация по Коду с 1С
  2880.                 $data['product_id'] = $this->getProductIdByCode($data['code']);
  2881.                 $this->log("Синхронизация товара по Коду: " . $data['code'], 2);
  2882.             }
  2883.         }
  2884.  
  2885.         // Синхронизация по Ид
  2886.         if (!$data['product_id']) {
  2887.             if (!$data['product_guid']) {
  2888.                 $this->ERROR = "setProduct() - Не задан Ид товара из торговой системы";
  2889.                 return false;
  2890.             } else {
  2891.                 $data['product_id'] = $this->getProductIdByGuid($data['product_guid']);
  2892.             }
  2893.         }
  2894.  
  2895.         if (!$data['product_id']) {
  2896.             // Синхронизация по артикулу
  2897.             if ($this->config->get('exchange1c_synchronize_new_product_by') == 'sku') {
  2898.                 if (empty($data['sku'])) {
  2899.                     $this->log("setProduct() - При синхронизации по артикулу, артикул не должен быть пустым! Товар пропущен. Проверьте товар " . $data['name'], 2);
  2900.                     // Пропускаем товар
  2901.                     return false;
  2902.                 }
  2903.                 $data['product_id'] = $this->getProductBySKU($data['sku']);
  2904.             // Синхронизация по наименованию
  2905.             } elseif ($this->config->get('exchange1c_synchronize_new_product_by') == 'name') {
  2906.                 if (empty($data['name'])) {
  2907.                     $this->log("setProduct() - При синхронизации по наименованию, наименование не должно быть пустым! Товар пропущен. Проверьте товар Ид: " . $data['product_guid'], 2);
  2908.                     // Пропускаем товар
  2909.                     return false;
  2910.                 }
  2911.                 $data['product_id'] = $this->getProductByName($data['name']);
  2912.             // Синхронизация по штрихкоду
  2913.             } elseif ($this->config->get('exchange1c_synchronize_new_product_by') == 'ean') {
  2914.                 if (empty($data['ean'])) {
  2915.                     $this->log("setProduct() - При синхронизации по штрихкоду, штрихкод не должен быть пустым! Товар пропущен. Проверьте товар " . $data['name'], 2);
  2916.                     return false;
  2917.                 }
  2918.                 $data['product_id'] = $this->getProductByEan($data['name']);
  2919.             }
  2920.             // Если нашли, создадим связь
  2921.             if ($data['product_id']) {
  2922.                 // Связь с 1С только по Ид объекта из торговой системы
  2923.                 $this->query("INSERT INTO `" . DB_PREFIX . "product_to_1c` SET `product_id` = " . $data['product_id'] . ", `guid` = '" . $this->db->escape($data['product_guid']) . "'");
  2924.             }
  2925.         }
  2926.  
  2927.         $new = false;
  2928.         // Если не найден товар...
  2929.         if (!$data['product_id']) {
  2930.             if ($this->config->get('exchange1c_create_new_product') == 1) {
  2931.                 $new = $this->addProduct($data);
  2932.                 if ($this->ERROR) return false;
  2933.  
  2934.             } else {
  2935.                 $this->log("Отключено добавление новых товаров!");
  2936.             }
  2937.         } else {
  2938.             $this->updateProduct($data);
  2939.             if ($this->ERROR) return false;
  2940.         }
  2941.  
  2942.         // SEO формируем когда известен product_id и товар записан
  2943.         $update = $this->seoGenerateProduct($data);
  2944.         if ($this->ERROR) return false;
  2945.  
  2946.         if ($update || $new) {
  2947.             // Обновляем описание товара после генерации SEO
  2948.             $this->setProductDescription($data, $new);
  2949.         }
  2950.  
  2951.         $this->log("setProduct(): Товар обработан");
  2952.  
  2953.         return true;
  2954.  
  2955.     } // setProduct()
  2956.  
  2957.  
  2958.     /**
  2959.      * Читает реквизиты товара из XML в массив
  2960.      */
  2961.     private function parseRequisite($xml, &$data) {
  2962.  
  2963.         foreach ($xml->ЗначениеРеквизита as $requisite){
  2964.             $name   = (string)$requisite->Наименование;
  2965.             $value  = $requisite->Значение;
  2966.  
  2967.             switch ($name){
  2968.                 case 'Вес':
  2969.                     $data['weight'] = $value ? (float)str_replace(',','.',$value) : 0;
  2970.                     $this->log("> Реквизит: " . $name. " => weight",2);
  2971.                 break;
  2972.                 case 'ТипНоменклатуры':
  2973.                     $data['item_type'] = $value ? (string)$value : '';
  2974.                     $this->log("> Реквизит: " . $name. " => item_type",2);
  2975.                 break;
  2976.                 case 'ВидНоменклатуры':
  2977.                     $data['item_view'] = $value ? (string)$value : '';
  2978.                     $this->log("> Реквизит: " . $name. " => item_view",2);
  2979.                 break;
  2980.                 case 'ОписаниеВФорматеHTML':
  2981.                     if ($value && $this->config->get('exchange1c_import_product_description') == 1) {
  2982.                         $data['description'] =  (string)$value;
  2983.                         $this->log("> Реквизит: " . $name. " => description (HTML format)",2);
  2984.                     }
  2985.                 break;
  2986.                 case 'Полное наименование':
  2987.                     $data['full_name'] = $value ? htmlspecialchars((string)$value) : '';
  2988.                     $this->log("> Реквизит: " . $name. " => full_name",2);
  2989.                 break;
  2990.                 case 'ОписаниеФайла':
  2991.                     $this->parseDescriptionFile((string)$value, $data);
  2992.                     if ($this->ERROR) return false;
  2993.                     $this->log("> Реквизит: " . $name, 2);
  2994.                 break;
  2995.                 case 'Производитель':
  2996.                     // Устанавливаем производителя из свойства только если он не был еще загружен в секции Товар
  2997.                     if ($this->config->get('exchange1c_import_product_manufacturer') == 1) {
  2998.                         if (!isset($data['manufacturer_id'])) {
  2999.                             $data['manufacturer_id'] = $this->setManufacturer($value);
  3000.                             $this->log("> Производитель (из реквизита): '" . $value . "', id: " . $data['manufacturer_id'],2);
  3001.                         }
  3002.                     }
  3003.                 break;
  3004.                 case 'Код':
  3005.                     $this->log("> Реквизит: " . $name. " => " . (string)$value, 2);
  3006.                 break;
  3007.                 default:
  3008.                     $this->log("[!] Неиспользуемый реквизит: " . $name. " = " . (string)$value,2);
  3009.             }
  3010.         }
  3011.  
  3012.     } // parseRequisite()
  3013.  
  3014.  
  3015.     /**
  3016.      * ver 2
  3017.      * update 2017-05-22
  3018.      * Получает путь к картинке и накладывает водяные знаки
  3019.      */
  3020.     private function applyWatermark($filename, $watermark) {
  3021.  
  3022.         $filename_path = DIR_IMAGE . $filename;
  3023.         $watermark_path = DIR_IMAGE . $watermark;
  3024.  
  3025.         if (is_file($filename_path)) {
  3026.  
  3027.             // Создаем объект картинка из водяного знака и получаем информацию о картинке
  3028.             $image = new Image($filename_path);
  3029.             $image->watermark(new Image($watermark_path));
  3030.  
  3031.             // Сохраняем картинку с водяным знаком
  3032.             $image->save($filename_path);
  3033.  
  3034.             return true;
  3035.         }
  3036.         else {
  3037.             return false;
  3038.         }
  3039.  
  3040.     } // applyWatermark()
  3041.  
  3042.  
  3043.     /**
  3044.      * ver 2
  3045.      * update 2017-04-18
  3046.      * Определяет что за файл и принимает дальнейшее действие
  3047.      */
  3048.     private function setFile($filename, $product_id) {
  3049.  
  3050.         $info = pathinfo($filename);
  3051.         if (isset($info['extension'])) {
  3052.  
  3053.             // Если расширение txt - грузим в описание
  3054.             if ($info['extension'] == "txt") {
  3055.                 $description = file_get_contents($filename);
  3056.                 // если не в кодировке UTF-8, переводим
  3057.                 if (!mb_check_encoding($description, 'UTF-8')) {
  3058.                     $description = nl2br(htmlspecialchars(iconv('windows-1251', 'utf-8', $description)));
  3059.                 }
  3060.                 // обновляем только описание
  3061.                 $this->setProductDescription(array('description'    => $description, 'product_id' => $product_id));
  3062.                 $this->log("> Добавлено описание товара из файла: " . $info['basename'],1);
  3063.                 return true;
  3064.             }
  3065.         }
  3066.         return false;
  3067.  
  3068.     } // setFile())
  3069.  
  3070.  
  3071.     /**
  3072.      * ver 3
  3073.      * update 2017-05-19
  3074.      * Накладывает водяной знак на картинку
  3075.      */
  3076.     private function setWatermarkImage($image) {
  3077.  
  3078.         $watermark = $this->config->get('exchange1c_watermark');
  3079.         if (empty($watermark)) {
  3080.             $this->ERROR = "setWatermarkImage() - файл водяных знаков пустой";
  3081.             return false;
  3082.         }
  3083.  
  3084.         if ($this->applyWatermark($image, $watermark)) {
  3085.             $this->log("> Сформирован файл с водяным знаком: " . $image);
  3086.         } else {
  3087.             $this->ERROR = "setWatermarkImage() - Ошибка наложения водяного знака на картинку: '" . $image . "'";
  3088.             return false;
  3089.         }
  3090.  
  3091.         return true;
  3092.  
  3093.     } // setWatermarkImage()
  3094.  
  3095.  
  3096.     /**
  3097.      * ver 9
  3098.      * update 2017-06-03
  3099.      * Устанавливает дополнительные картинки в товаре
  3100.      */
  3101.     private function setProductImages($images_data, $product_id, $new = false) {
  3102.  
  3103.         $old_images = array();
  3104.         if (!$new) {
  3105.             // Прочитаем  все старые картинки
  3106.             $query = $this->query("SELECT `product_image_id`,`image` FROM `" . DB_PREFIX . "product_image` WHERE `product_id` = " . $product_id);
  3107.             foreach ($query->rows as $image) {
  3108.                 $old_images[$image['product_image_id']] = $image['image'];
  3109.             }
  3110.         }
  3111.  
  3112.         foreach ($images_data as $index => $image_data) {
  3113.  
  3114.             $image          = $image_data['file'];
  3115.  
  3116.             if (file_exists(DIR_IMAGE . $image)) {
  3117.                 // Удалим эту картинку в кэше
  3118.                 $image_info = pathinfo(DIR_IMAGE . $image);
  3119.                 $this->deleteCacheImage($image_info);
  3120.             }
  3121.  
  3122.             // Накладываем водяные знаки
  3123.             if ($this->config->get('exchange1c_watermark')) {
  3124.                 $this->setWatermarkImage($image);
  3125.                 if ($this->ERROR) return false;
  3126.             }
  3127.  
  3128.             // Основная картинка
  3129.             if ($index == 0) continue;
  3130.  
  3131.             $description    = $image_data['description'];
  3132.             $this->log("Картинка: " . $image, 2);
  3133.             $this->log("Описание: " . $description, 2);
  3134.  
  3135.             // Установим картинку в товар, т.е. если нет - добавим, если есть возвратим product_image_id
  3136.             $product_image_id = array_search($image, $old_images);
  3137.             if (!$product_image_id) {
  3138.                 $this->query("INSERT INTO `" . DB_PREFIX . "product_image` SET `product_id` = " . $product_id . ", `image` = '" . $this->db->escape($image) . "', `sort_order` = " . $index);
  3139.                 //$product_image_id = $this->db->getLastId();
  3140.                 //$this->query("INSERT INTO `" . DB_PREFIX . "product_image_description` SET `product_id` = " . $product_id . ", `product_image_id` = " . $product_image_id . ", `name` = '" . $this->db->escape($description) . "', `language_id` = " . $this->LANG_ID);
  3141.                 //$this->log("> Картинка дополнительная: '" . $image . "'", 2);
  3142.             } else {
  3143.                 if (!$new) {
  3144.                     unset($old_images[$product_image_id]);
  3145.                 }
  3146.             }
  3147.  
  3148.         } // foreach ($images_data as $index => $image_data)
  3149.  
  3150.         if (!$new && $this->config->get('exchange1c_product_images_import_mode') == 'full') {
  3151.             // Удалим старые неиспользованные картинки
  3152.             $delete_images = array();
  3153.             foreach ($old_images as $product_image_id => $image) {
  3154.                 //$this->log($image, 2);
  3155.                 $delete_images[] = $product_image_id;
  3156.                 if (is_file(DIR_IMAGE . $image)) {
  3157.                     // Также удалим файл с диска
  3158.                     unlink(DIR_IMAGE . $image);
  3159.                     $this->log("> Удалена старая картинка: " . DIR_IMAGE . $image);
  3160.                 }
  3161.             }
  3162.             if (count($delete_images)) {
  3163.                 $this->query("DELETE FROM `" . DB_PREFIX . "product_image` WHERE `product_image_id` IN (" . implode(",",$delete_images) . ")");
  3164.             }
  3165.         }
  3166.  
  3167.     } // setProductImages()
  3168.  
  3169.  
  3170.     /**
  3171.      * ver 3
  3172.      * update 2017-06-04
  3173.      * Удаляет в кэше эту картинку
  3174.      */
  3175.     private function deleteCacheImage($image_info) {
  3176.  
  3177.         if (!$image_info) {
  3178.             // Нечего удалять
  3179.             return false;
  3180.         }
  3181.  
  3182.         // Путь в папке кэш к картинке
  3183.         $path = str_replace(DIR_IMAGE, DIR_IMAGE . "cache/" , $image_info['dirname']);
  3184.  
  3185.         // Откроем папку для чтения
  3186.         $delete_files = array();
  3187.         $dh = @opendir($path);
  3188.  
  3189.         // Если каталог не открывается
  3190.         if (!$dh) {
  3191.             $this->log("Каталог не существует: " . $path);
  3192.             return false;
  3193.         }
  3194.  
  3195.         while(($file = readdir($dh)) !== false) {
  3196.             $find = strstr($file, $image_info['filename']);
  3197.             if ($find != "") {
  3198.                 $delete_files[] = $find;
  3199.             }
  3200.         }
  3201.         closedir($dh);
  3202.  
  3203.         if ($delete_files) {
  3204.             foreach ($delete_files as $filename) {
  3205.                 unlink($path . "/" . $filename);
  3206.                 $this->log("Удалена картинка из кэша: " . $filename);
  3207.             }
  3208.         }
  3209.  
  3210.         return true;
  3211.  
  3212.     } // deleteCacheImage()
  3213.  
  3214.  
  3215.     /**
  3216.      * Читает описание файла из XML в массив
  3217.      */
  3218.     private function parseDescriptionFile($value, &$data) {
  3219.  
  3220.         if (!$value) {
  3221.             $this->ERROR = "Описание пустое";
  3222.             return false;
  3223.         }
  3224.  
  3225.         if (!isset($data['description_files'])) {
  3226.             $data['description_files'] = array();
  3227.         }
  3228.  
  3229.         $value_array    = explode("#", (string)$value);
  3230.         $file           = $value_array[0];
  3231.         $description    = isset($value_array[1]) ? $value_array[1] : '';
  3232.  
  3233.         $data['description_files'][$file] = $description;
  3234.  
  3235.     } // parseDescriptionFile()
  3236.  
  3237.  
  3238.     /**
  3239.      * ver 4
  3240.      * update 2017-05-23
  3241.      * Читает картинки из XML в массив
  3242.      */
  3243.     private function parseImages($xml, $images, $descriptions) {
  3244.  
  3245.         if (!$xml) {
  3246.             $this->ERROR = "parseImages() - Нет картинок в XML";
  3247.             return false;
  3248.         }
  3249.  
  3250.         foreach ($xml as $image) {
  3251.  
  3252.             $image = (string)$image;
  3253.  
  3254.             // Пропускаем файл с пустым именем
  3255.             if (empty($image)) continue;
  3256.  
  3257.             // Пропускаем несуществующие файлы
  3258.             if (!file_exists(DIR_IMAGE . $image)) {
  3259.                 $this->log("parseImages() - файл не существует: " . $image);
  3260.                 continue;
  3261.             }
  3262.  
  3263.             // Обрабатываем только картинки
  3264.             $image_info = @getimagesize(DIR_IMAGE . $image);
  3265.             if ($image_info == NULL) {
  3266.                 $this->log("Это не картинка: " . DIR_IMAGE . $image);
  3267.             };
  3268.  
  3269.             $description = "";
  3270.             if (isset($descriptions[$image])) {
  3271.                 $description = $descriptions[$image];
  3272.             }
  3273.  
  3274.             $this->log("Картинка: " . $image, 2);
  3275.             $this->log("Описание файла: " . $description, 2);
  3276.             $images[] = array(
  3277.                 'file'          => $image,
  3278.                 'description'   => $description
  3279.             );
  3280.  
  3281.         }
  3282.         return $images;
  3283.  
  3284.     } // parseImages()
  3285.  
  3286.  
  3287.     /**
  3288.      * Возвращает id группы для свойств
  3289.      */
  3290.     private function setAttributeGroup($name) {
  3291.  
  3292.         $query = $this->query("SELECT `attribute_group_id` FROM `" . DB_PREFIX . "attribute_group_description` WHERE `name` = '" . $this->db->escape($name) . "'");
  3293.         if ($query->rows) {
  3294.             $this->log("Группа атрибута: '" . $name . "'", 2);
  3295.             return $query->row['attribute_group_id'];
  3296.         }
  3297.  
  3298.         // Добавляем группу
  3299.         $this->query("INSERT INTO `" . DB_PREFIX . "attribute_group` SET `sort_order` = 1");
  3300.  
  3301.         $attribute_group_id = $this->db->getLastId();
  3302.         $this->query("INSERT INTO `" . DB_PREFIX . "attribute_group_description` SET `attribute_group_id` = " . $attribute_group_id . ", `language_id` = " . $this->LANG_ID . ", `name` = '" . $this->db->escape($name) . "'");
  3303.  
  3304.         $this->log("Группа атрибута добавлена: '" . $name . "'", 2);
  3305.         return $attribute_group_id;
  3306.  
  3307.     } // setAttributeGroup()
  3308.  
  3309.  
  3310.     /**
  3311.      * Возвращает id атрибута из базы
  3312.      */
  3313.     private function setAttribute($guid, $attribute_group_id, $name, $sort_order) {
  3314.  
  3315.         // Ищем свойства по 1С Ид
  3316.         $attribute_id = 0;
  3317.         if ($guid && $this->config->get('exchange1c_synchronize_attribute_by') == 'guid') {
  3318.             $query = $this->query("SELECT `attribute_id` FROM `" . DB_PREFIX . "attribute_to_1c` WHERE `guid` = '" . $this->db->escape($guid) . "'");
  3319.             if ($query->num_rows) {
  3320.                 $attribute_id = $query->row['attribute_id'];
  3321.             }
  3322.         } else {
  3323.             // Попытаемся найти по наименованию
  3324.             $query = $this->query("SELECT `a`.`attribute_id` FROM `" . DB_PREFIX . "attribute` `a` LEFT JOIN `" . DB_PREFIX . "attribute_description` `ad` ON (`a`.`attribute_id` = `ad`.`attribute_id`) WHERE `ad`.`language_id` = " . $this->LANG_ID . " AND `ad`.`name` LIKE '" . $this->db->escape($name) . "' AND `a`.`attribute_group_id` = " . $attribute_group_id);
  3325.             if ($query->num_rows) {
  3326.                 $attribute_id = $query->row['attribute_id'];
  3327.             }
  3328.         }
  3329.  
  3330.         // Обновление
  3331.         if ($attribute_id) {
  3332.             $query = $this->query("SELECT `a`.`attribute_group_id`,`ad`.`name` FROM `" . DB_PREFIX . "attribute` `a` LEFT JOIN `" . DB_PREFIX . "attribute_description` `ad` ON (`a`.`attribute_id` = `ad`.`attribute_id`) WHERE `ad`.`language_id` = " . $this->LANG_ID . " AND `a`.`attribute_id` = " . $attribute_id);
  3333.             if ($query->num_rows) {
  3334.                 // Изменилась группа свойства
  3335.                 if ($query->row['attribute_group_id'] <> $attribute_group_id) {
  3336.                     $this->query("UPDATE `" . DB_PREFIX . "attribute` SET `attribute_group_id` = " . (int)$attribute_group_id . " WHERE `attribute_id` = " . $attribute_id);
  3337.                     $this->log("Группа атрибута обновлена: " . $attribute_id, 2);
  3338.                 }
  3339.                 // Изменилось имя
  3340.                 if ($query->row['name'] <> $name) {
  3341.                     $this->query("UPDATE `" . DB_PREFIX . "attribute_description` SET `name` = '" . $this->db->escape($name) . "' WHERE `attribute_id` = " . $attribute_id . " AND `language_id` = " . $this->LANG_ID);
  3342.                     $this->log("Атрибут обновлен: '" . $name . "'", 2);
  3343.                 }
  3344.             }
  3345.  
  3346.             return $attribute_id;
  3347.         }
  3348.  
  3349.         // Добавим в базу характеристику
  3350.         $this->query("INSERT INTO `" . DB_PREFIX . "attribute` SET `attribute_group_id` = " . $attribute_group_id . ", `sort_order` = " . $sort_order);
  3351.         $attribute_id = $this->db->getLastId();
  3352.         $this->query("INSERT INTO `" . DB_PREFIX . "attribute_description` SET `attribute_id` = " . $attribute_id . ", `language_id` = " . $this->LANG_ID . ", `name` = '" . $this->db->escape($name) . "'");
  3353.         $this->log("Атрибут добавлен: '" . $name . "'", 2);
  3354.  
  3355.  
  3356.         if ($this->config->get('exchange1c_synchronize_attribute_by') == 'guid') {
  3357.             // Добавляем ссылку для 1С Ид
  3358.             $this->query("INSERT INTO `" .  DB_PREFIX . "attribute_to_1c` SET `attribute_id` = " . $attribute_id . ", `guid` = '" . $this->db->escape($guid) . "'");
  3359.         }
  3360.  
  3361.         return $attribute_id;
  3362.  
  3363.     } // setAttribute()
  3364.  
  3365.  
  3366.     /**
  3367.      * ver 2
  3368.      * update 2017-04-27
  3369.      * Загружает значения атрибута (Свойства из 1С)
  3370.      */
  3371.     private function parseAttributesValues($xml, $attribute_id = 0) {
  3372.  
  3373.         $data = array();
  3374.         if (!$xml) {
  3375.             return $data;
  3376.         }
  3377.  
  3378.         if ($xml->ПометкаУдаления) {
  3379.             $delete = (string)$xml->ПометкаУдаления == 'true' ? true : false;
  3380.         } else {
  3381.             $delete = false;
  3382.         }
  3383.  
  3384.         if ($xml->ВариантыЗначений) {
  3385.             if ($xml->ВариантыЗначений->Справочник) {
  3386.                 foreach ($xml->ВариантыЗначений->Справочник as $item) {
  3387.                     $value = trim(htmlspecialchars((string)$item->Значение, 2));
  3388.                     $guid = (string)$item->ИдЗначения;
  3389.  
  3390.                     if (!$value) {
  3391.                         continue;
  3392.                     }
  3393.  
  3394.                     $query = $this->query("SELECT `attribute_value_id`,`name` FROM `" . DB_PREFIX . "attribute_value` WHERE `guid` = '" . $this->db->escape($guid) . "'");
  3395.                     if ($query->num_rows) {
  3396.                         if ($delete) {
  3397.                             $this->query("DELETE FROM `" . DB_PREFIX . "attribute_value` WHERE `guid` = '" . $this->db->escape($guid) . "'");
  3398.                             $value_id = 0;
  3399.                             $this->log("Значение атрибута удалено (пометка удаления в ТС): " . $value,2);
  3400.                         } else {
  3401.                             if ($query->row['name'] <> $value) {
  3402.                                 $this->query("UPDATE `" . DB_PREFIX . "attribute_value` SET `name` = '" . $this->db->escape($value) . "' WHERE `attribute_value_id` = " . $query->row['attribute_value_id']);
  3403.                                 $this->log("Значение атрибута обновлено: " . $value, 2);
  3404.                             }
  3405.                             $value_id = $query->row['attribute_value_id'];
  3406.                         }
  3407.  
  3408.                     } else {
  3409.                         if (!$delete) {
  3410.                             if ($attribute_id) {
  3411.                                 $query = $this->query("INSERT INTO `" . DB_PREFIX . "attribute_value` SET `attribute_id` = " . $attribute_id . ", `guid` = '" . $this->db->escape($guid) . "', `name` = '" . $this->db->escape($value) . "'");
  3412.                                 $value_id = $this->db->getlastId();
  3413.                                 $this->log("Значение атрибута добавлено: " . $value, 2);
  3414.                             } else {
  3415.                                 $value_id = 0;
  3416.                             }
  3417.                         } else {
  3418.                             $this->log("Значение атрибута было удалено (помечен на удаление в ТС): " . $value, 2);
  3419.                             $value_id = 0;
  3420.                         }
  3421.                     }
  3422.  
  3423.                     $data[$guid] = array(
  3424.                         'name'      => $value,
  3425.                         'value_id'  => $value_id
  3426.                     );
  3427.  
  3428.                 }
  3429.             }
  3430.         }
  3431.         return $data;
  3432.  
  3433.     } // parseAttributesValues()
  3434.  
  3435.  
  3436.     /**
  3437.      * Загружает атрибуты (Свойства из 1С) в классификаторе
  3438.      */
  3439.     private function parseClassifierAttributes($xml) {
  3440.  
  3441.         $data = array();
  3442.         $sort_order = 0;
  3443.         if ($xml->Свойство) {
  3444.             $properties = $xml->Свойство;
  3445.         } else {
  3446.             $properties = $xml->СвойствоНоменклатуры;
  3447.         }
  3448.  
  3449.         foreach ($properties as $property) {
  3450.  
  3451.             $name       = trim((string)$property->Наименование);
  3452.             $guid       = (string)$property->Ид;
  3453.  
  3454.             // Название группы свойств по умолчанию (в дальнейшем сделать определение в настройках)
  3455.             $group_name = "Свойства";
  3456.  
  3457.             // Определим название группы в название свойства в круглых скобках в конце названия
  3458.             $name_split = $this->splitNameStr($name);
  3459.             //$this->log($name_split, 2);
  3460.             if ($name_split['option']) {
  3461.                 $group_name = $name_split['option'];
  3462.                 $this->log("> Группа свойства: " . $group_name, 2);
  3463.             }
  3464.             $name = $name_split['name'];
  3465.             // Установим группу для свойств
  3466.             $attribute_group_id = $this->setAttributeGroup($group_name);
  3467.  
  3468.             // Использование
  3469.             if ($property->ИспользованиеСвойства) {
  3470.                 $status = (string)$property->ИспользованиеСвойства == 'true' ? 1 : 0;
  3471.             } else {
  3472.                 $status = 1;
  3473.             }
  3474.  
  3475.             // Для товаров
  3476.             if ($property->ДляТоваров) {
  3477.                 $for_product = (string)$property->ДляТоваров == 'true' ? 1 : 0;
  3478.             } else {
  3479.                 $for_product = 1;
  3480.             }
  3481.  
  3482.             // Обязательное
  3483.             if ($property->Обязательное) {
  3484.                 $required = (string)$property->Обязательное == 'true' ? 1 : 0;
  3485.             } else {
  3486.                 $required = 0;
  3487.             }
  3488.  
  3489.             // Множественное
  3490.             if ($property->Множественное) {
  3491.                 $multiple = (string)$property->Множественное == 'true' ? 1 : 0;
  3492.             } else {
  3493.                 $multiple = 0;
  3494.             }
  3495.  
  3496.             if ($property->ДляПредложений) {
  3497.                 // Свойства для характеристик скорее всего
  3498.                 if ((string)$property->ДляПредложений == 'true') {
  3499.                     $this->log("> Свойство '" . $name . "' только для предложений, в атрибуты не будет добавлено", 2);
  3500.                     continue;
  3501.                 }
  3502.             }
  3503.  
  3504.             switch ($name) {
  3505.                 case 'Производитель':
  3506.                     $values = $this->parseAttributesValues($property);
  3507.                     foreach ($values as $manufacturer_guid => $value) {
  3508.                         $this->setManufacturer($value['name'], $manufacturer_guid);
  3509.                     }
  3510.                 //break;
  3511.                 case 'Изготовитель':
  3512.                     $values = $this->parseAttributesValues($property);
  3513.                     foreach ($values as $manufacturer_guid => $value) {
  3514.                         $this->setManufacturer($value['name'], $manufacturer_guid);
  3515.                     }
  3516.                 //break;
  3517.                 default:
  3518.                     $attribute_id = $this->setAttribute($guid, $attribute_group_id, $name, $sort_order);
  3519.                     $values = $this->parseAttributesValues($property, $attribute_id);
  3520.                     $data[$guid] = array(
  3521.                         'name'          => $name,
  3522.                         'attribute_id'  => $attribute_id,
  3523.                         'values'        => $values,
  3524.                         'for_product'   => $for_product,
  3525.                         'status'        => $status,
  3526.                         'required'      => $required,
  3527.                         'multiple'      => $multiple
  3528.                     );
  3529.  
  3530.                     $sort_order ++;
  3531.             }
  3532.  
  3533.         }
  3534.  
  3535.         $this->log("Атрибутов прочитано: " . sizeof($properties), 2);
  3536.         return $data;
  3537.  
  3538.     } // parseClassifierAttributes()
  3539.  
  3540.  
  3541.     /**
  3542.      * Читает свойства из базы данных в массив
  3543.      */
  3544.     private function getAttributes() {
  3545.  
  3546.         $data = array();
  3547.  
  3548.         $query_attribute = $this->query("SELECT `a`.`attribute_id`, `ad`.`name`, `a2c`.`guid` FROM `" . DB_PREFIX . "attribute` `a` LEFT JOIN `" . DB_PREFIX . "attribute_description` `ad` ON (`a`.`attribute_id` = `ad`.`attribute_id`) LEFT JOIN `" . DB_PREFIX . "attribute_to_1c` `a2c` ON (`a`.`attribute_id` = `a2c`.`attribute_id`) WHERE `ad`.`language_id` = " . $this->LANG_ID);
  3549.         if ($query_attribute->num_rows) {
  3550.             foreach ($query_attribute->rows as $row_attribute) {
  3551.  
  3552.                 $attribute_guid = $row_attribute['guid'];
  3553.                 $attribute_id = $row_attribute['attribute_id'];
  3554.                 if (!isset($data[$attribute_guid])) {
  3555.                     $data[$attribute_guid] = array(
  3556.                         'name'          => $row_attribute['name'],
  3557.                         'attribute_id'  => $attribute_id,
  3558.                         'values'        => array()
  3559.                     );
  3560.                 }
  3561.  
  3562.                 $query_value = $this->query("SELECT `attribute_value_id`, `name`, `guid` FROM `" . DB_PREFIX . "attribute_value` WHERE `attribute_id` = " . $attribute_id);
  3563.  
  3564.                 if ($query_value->num_rows) {
  3565.                     foreach ($query_value->rows as $row_value) {
  3566.  
  3567.                         $values = &$data[$attribute_guid]['values'];
  3568.  
  3569.                         $attribute_value_guid = $row_value['guid'];
  3570.                         if (!isset($values[$attribute_value_guid])) {
  3571.                             $values[$attribute_value_guid] = array(
  3572.                                 'name'      => $row_value['name'],
  3573.                                 'value_id'  => $row_value['attribute_value_id']
  3574.                             );
  3575.                         }
  3576.                     }
  3577.                 }
  3578.             }
  3579.         }
  3580.  
  3581.         $this->log("Свойства (атрибуты) получены из БД",2);
  3582.         return $data;
  3583.  
  3584.     }  // getAttributes()
  3585.  
  3586.  
  3587.     /**
  3588.      * ver 2
  3589.      * update 2017-05-26
  3590.      * Читает свойства из объектов (товар, категория) и записывает их в массив
  3591.      */
  3592.     private function parseAttributes($xml, &$data, &$classifier) {
  3593.  
  3594.         $product_attributes = array();
  3595.         $error = "";
  3596.  
  3597.         if (!isset($classifier['attributes'])) {
  3598.             $classifier['attributes'] = $this->getAttributes();
  3599.             if ($this->ERROR) {
  3600.                 return false;
  3601.             }
  3602.         }
  3603.         $attributes = $classifier['attributes'];
  3604.  
  3605.         $attributes_filter = $this->config->get('exchange1c_properties');
  3606.  
  3607.         // Предопределенные названия свойств
  3608.         $predefined_attributes = array(
  3609.             'weight'    => "Вес"
  3610.             ,'width'    => "Ширина"
  3611.             ,'height'   => "Высота"
  3612.             ,'length'   => "Длина"
  3613.             ,'model'    => "Модель"
  3614.             ,'mpn'      => "MPN"
  3615.             ,'sku'      => "Артикул"
  3616.         );
  3617.  
  3618.  
  3619.         foreach ($xml->ЗначенияСвойства as $property) {
  3620.  
  3621.             // Ид объекта в 1С
  3622.             $guid = (string)$property->Ид;
  3623.             $import = true;
  3624.  
  3625.             // Загружаем только те что в классификаторе
  3626.             if (!isset($attributes[$guid])) {
  3627.                 $this->log("[i] Свойство не было загружено в классификаторе, Ид: " . $guid, 2);
  3628.                 continue;
  3629.             }
  3630.  
  3631.             $name   = trim($attributes[$guid]['name']);
  3632.             $value  = trim((string)$property->Значение);
  3633.             $value_id = 0;
  3634.  
  3635.             if ($value) {
  3636.                 if ($attributes[$guid]) {
  3637.                     // агрегатный тип, под value подразумеваем Ид объекта
  3638.                     if (!empty($attributes[$guid]['values'][$value])) {
  3639.                         $values = $attributes[$guid]['values'][$value];
  3640.                         $value = trim($values['name']);
  3641.                         $value_id = $values['value_id'];
  3642.                     }
  3643.                 }
  3644.             }
  3645.  
  3646.             // Фильтруем по таблице свойств
  3647.             $attributes_filter = $this->config->get('exchange1c_properties');
  3648.             if (is_array($attributes_filter)) {
  3649.  
  3650.                 foreach ($attributes_filter as $attr_filter) {
  3651.  
  3652.                     if ($attr_filter['name'] == $name) {
  3653.  
  3654.                         if ($attr_filter['product_field_name'] == '') {
  3655.  
  3656.                             $value = "";
  3657.                             $this->log("Свойство отключено для загрузки в товар: '" . $attr_filter['name'] . "'", 2);
  3658.                             break;
  3659.  
  3660.                         } else {
  3661.  
  3662.                             if (isset($predefined_attributes[$attr_filter['product_field_name']])) {
  3663.                                 $predefined_attributes[$attr_filter['product_field_name']] = $attr_filter['name'];
  3664.  
  3665.                                 // Не надо записывать в атрибуты товара
  3666.                                 if (!isset($attr_filter['import'])) {
  3667.                                     $import = false;
  3668.                                 }
  3669.                             }
  3670.  
  3671.                         } // $attr_filter['product_field_name'] == ''
  3672.  
  3673.                     } // $attr_filter['name'] == $name
  3674.  
  3675.                 } // foreach
  3676.  
  3677.             } // is_array($attributes_filter
  3678.  
  3679.             // Пропускаем с пустыми значениями
  3680.             if (empty($value)) {
  3681.                 $this->log("[i] У свойства '" . $name . "' нет значения, не будет обработано", 2);
  3682.                 continue;
  3683.             }
  3684.  
  3685.             switch ($name) {
  3686.                 case 'Производитель':
  3687.                     // Устанавливаем производителя из свойства только если он не был еще загружен в секции Товар
  3688.                     if ($this->config->get('exchange1c_import_product_manufacturer') == 1) {
  3689.                         if (!isset($data['manufacturer_id'])) {
  3690.                             $data['manufacturer_id'] = $this->setManufacturer($value);
  3691.                             $this->log("> Производитель (из свойства): '" . $value . "', id: " . $data['manufacturer_id'],2);
  3692.                         }
  3693.                     }
  3694.                 break;
  3695.                 case 'Изготовитель':
  3696.                     // Устанавливаем производителя из свойства только если он не был еще загружен в секции Товар
  3697.                     if ($this->config->get('exchange1c_import_product_manufacturer') == 1) {
  3698.                         if (!isset($data['manufacturer_id'])) {
  3699.                             $data['manufacturer_id'] = $this->setManufacturer($value);
  3700.                             $this->log("> Изготовитель (из свойства): '" . $value . "', id: " . $data['manufacturer_id'],2);
  3701.                         }
  3702.                     }
  3703.                 break;
  3704.                 case $predefined_attributes['weight']:
  3705.                     $data['weight'] = round((float)str_replace(',','.',$value), 3);
  3706.                     $this->log("> Вес => weight = ".$data['weight'],2);
  3707.                 break;
  3708.                 case $predefined_attributes['width']:
  3709.                     $data['width'] = round((float)str_replace(',','.',$value), 2);
  3710.                     $this->log("> Ширина => width",2);
  3711.                 break;
  3712.                 case $predefined_attributes['height']:
  3713.                     $data['height'] = round((float)str_replace(',','.',$value), 2);
  3714.                     $this->log("> Высота => height",2);
  3715.                 break;
  3716.                 case $predefined_attributes['length']:
  3717.                     $data['length'] = round((float)str_replace(',','.',$value), 2);
  3718.                     $this->log("> Длина => length",2);
  3719.                 break;
  3720.                 case $predefined_attributes['model']:
  3721.                     $data['model'] = (string)$value;
  3722.                     $this->log("> Модель => model",2);
  3723.                 break;
  3724.                 case $predefined_attributes['sku']:
  3725.                     $data['sku'] = (string)$value;
  3726.                     $this->log("> Артикул => sku",2);
  3727.                 break;
  3728.                 default:
  3729.                     if ($import) {
  3730.                         $product_attributes[$attributes[$guid]['attribute_id']] = array(
  3731.                             'name'          => $name,
  3732.                             'value'         => $value,
  3733.                             'guid'          => $guid,
  3734.                             'value_id'      => $value_id,
  3735.                             'attribute_id'  => $attributes[$guid]['attribute_id']
  3736.                         );
  3737.                         $this->log("Свойство '" . $name . "' = '" . $value . "'",2);
  3738.                     }
  3739.             }
  3740.         } // foreach
  3741.  
  3742.         $data['attributes'] = $product_attributes;
  3743.         $this->log("Свойства товара прочитаны",2);
  3744.         return true;
  3745.  
  3746.     } // parseProductAttributes()
  3747.  
  3748.  
  3749.     /**
  3750.      * ver 4
  3751.      * update 2017-04-16
  3752.      * Обновляет свойства в товар из массива
  3753.      */
  3754.     private function updateProductAttributes($attributes, $product_id) {
  3755.  
  3756.         // Проверяем
  3757.         $product_attributes = array();
  3758.         $query = $this->query("SELECT `attribute_id`,`text` FROM `" . DB_PREFIX . "product_attribute` WHERE `product_id` = " . $product_id . " AND `language_id` = " . $this->LANG_ID);
  3759.         foreach ($query->rows as $attribute) {
  3760.             $product_attributes[$attribute['attribute_id']] = $attribute['text'];
  3761.         }
  3762.  
  3763.         foreach ($attributes as $attribute) {
  3764.             // Проверим есть ли такой атрибут
  3765.  
  3766.             if (isset($product_attributes[$attribute['attribute_id']])) {
  3767.  
  3768.                 // Проверим значение и обновим при необходимости
  3769.                 if ($product_attributes[$attribute['attribute_id']] != $attribute['value']) {
  3770.                     $this->query("UPDATE `" . DB_PREFIX . "product_attribute` SET `text` = '" . $this->db->escape($attribute['value']) . "' WHERE `product_id` = " . $product_id . " AND `attribute_id` = " . $attribute['attribute_id'] . " AND `language_id` = " . $this->LANG_ID);
  3771.                     $this->log("Атрибут товара обновлен'" . $this->db->escape($attribute['name']) . "' = '" . $this->db->escape($attribute['value']) . "' записано в товар id: " . $product_id, 2);
  3772.                 }
  3773.  
  3774.                 unset($product_attributes[$attribute['attribute_id']]);
  3775.             } else {
  3776.                 // Добавим в товар
  3777.                 $this->query("INSERT INTO `" . DB_PREFIX . "product_attribute` SET `product_id` = " . $product_id . ", `attribute_id` = " . $attribute['attribute_id'] . ", `language_id` = " . $this->LANG_ID . ", `text` = '" .  $this->db->escape($attribute['value']) . "'");
  3778.                 $this->log("Атрибут товара добавлен '" . $this->db->escape($attribute['name']) . "' = '" . $this->db->escape($attribute['value']) . "' записано в товар id: " . $product_id, 2);
  3779.             }
  3780.         }
  3781.  
  3782.         // Удалим неиспользованные
  3783.         if (count($product_attributes)) {
  3784.             $delete_attribute = array();
  3785.             foreach ($product_attributes as $attribute_id => $attribute) {
  3786.                 $delete_attribute[] = $attribute_id;
  3787.             }
  3788.             $this->query("DELETE FROM `" . DB_PREFIX . "product_attribute` WHERE `product_id` = " . $product_id . " AND `language_id` = " . $this->LANG_ID . " AND `attribute_id` IN (" . implode(",",$delete_attribute) . ")");
  3789.             $this->log("Старые атрибуты товара удалены", 2);
  3790.         }
  3791.  
  3792.     } // updateProductAttributes()
  3793.  
  3794.  
  3795.     /**
  3796.      * ver 2
  3797.      * update 2017-04-29
  3798.      * Обновляем производителя в базе данных
  3799.      */
  3800.     private function updateManufacturer($data) {
  3801.  
  3802.         $query = $this->query("SELECT `name` FROM `" . DB_PREFIX . "manufacturer` WHERE `manufacturer_id` = " . $data['manufacturer_id']);
  3803.         if ($query->row['name'] <> $data['name']) {
  3804.             // Обновляем
  3805.             $sql  = " `name` = '" . $this->db->escape($data['name']) . "'";
  3806.             $sql .= isset($data['noindex']) ? ", `noindex` = " . $data['noindex'] : "";
  3807.             $this->query("UPDATE `" . DB_PREFIX . "manufacturer` SET " . $sql . " WHERE `manufacturer_id` = " . $data['manufacturer_id']);
  3808.             $this->log("Производитель обновлен: '" . $data['name'] . "'", 2);
  3809.         }
  3810.  
  3811.         if (isset($this->TAB_FIELDS['manufacturer_description'])) {
  3812.  
  3813.             $this->seoGenerateManufacturer($data);
  3814.             $select_name = isset($this->TAB_FIELDS['manufacturer_description']['name']) ? ", `name`" : "";
  3815.             $query = $this->query("SELECT `description`,`meta_title`,`meta_description`,`meta_keyword`" . $select_name . " FROM `" . DB_PREFIX . "manufacturer_description` WHERE `manufacturer_id` = " . $data['manufacturer_id'] . " AND `language_id` = " . $this->LANG_ID);
  3816.  
  3817.             // Сравнивает запрос с массивом данных и формирует список измененных полей
  3818.             $update_fields = $this->compareArrays($query, $data);
  3819.  
  3820.             if ($update_fields) {
  3821.                 $this->query("UPDATE `" . DB_PREFIX . "manufacturer_description` SET " . $update_fields . " WHERE `manufacturer_id` = " . $data['manufacturer_id'] . " AND `language_id` = " . $this->LANG_ID);
  3822.             }
  3823.         }
  3824.         return true;
  3825.  
  3826.     } // updateManufacturer()
  3827.  
  3828.  
  3829.     /**
  3830.      * ver 2
  3831.      * update 2017-04-29
  3832.      * Добавляем производителя
  3833.      */
  3834.     private function addManufacturer(&$manufacturer_data) {
  3835.  
  3836.         $sql = array();
  3837.         if (!isset($this->TAB_FIELDS['manufacturer_description']['name']) && isset($manufacturer_data['name'])) {
  3838.             $sql[] = "`name` = '" . $this->db->escape($manufacturer_data['name']) . "'";
  3839.         }
  3840.         if (isset($manufacturer_data['sort_order'])) {
  3841.             $sql[] = "`sort_order` = " . $manufacturer_data['sort_order'];
  3842.         }
  3843.         if (isset($manufacturer_data['image'])) {
  3844.             $sql[] = "`image` = '" . $this->db->escape($manufacturer_data['image']) . "'";
  3845.         }
  3846.         if (isset($manufacturer_data['noindex'])) {
  3847.             $sql[] = "`noindex` = " . $manufacturer_data['noindex'];
  3848.         }
  3849.         if (!$sql) {
  3850.             $this->log("Производитель не добавлен, так как нет данных!");
  3851.             $this->log($manufacturer_data);
  3852.             return true;
  3853.         }
  3854.  
  3855.         $query = $this->query("INSERT INTO `" . DB_PREFIX . "manufacturer` SET" . implode(", ", $sql));
  3856.  
  3857.         $manufacturer_data['manufacturer_id'] = $this->db->getLastId();
  3858.         $this->seoGenerateManufacturer($manufacturer_data);
  3859.  
  3860.         if (isset($this->TAB_FIELDS['manufacturer_description'])) {
  3861.             $sql = $this->prepareStrQueryManufacturerDescription($manufacturer_data);
  3862.             if ($sql) {
  3863.                 $this->query("INSERT INTO `" . DB_PREFIX . "manufacturer_description` SET `manufacturer_id` = " . $manufacturer_data['manufacturer_id'] . ", `language_id` = " . $this->LANG_ID . $sql);
  3864.             }
  3865.         }
  3866.  
  3867.         // добавляем связь
  3868.         if (isset($manufacturer_data['guid'])) {
  3869.             $this->query("INSERT INTO `" . DB_PREFIX . "manufacturer_to_1c` SET `guid` = '" . $this->db->escape($manufacturer_data['guid']) . "', `manufacturer_id` = " . $manufacturer_data['manufacturer_id']);
  3870.         }
  3871.  
  3872.         $this->query("INSERT INTO `" . DB_PREFIX . "manufacturer_to_store` SET `manufacturer_id` = " . $manufacturer_data['manufacturer_id'] . ", `store_id` = " . $this->STORE_ID);
  3873.         $this->log("Производитель добавлен: '" . $manufacturer_data['name'] . "'");
  3874.  
  3875.     } // addManufacturer()
  3876.  
  3877.  
  3878.     /**
  3879.      * Устанавливаем производителя
  3880.      */
  3881.     private function setManufacturer($name, $manufacturer_guid = '') {
  3882.  
  3883.         $manufacturer_data = array();
  3884.         $manufacturer_data['name']          = (string)$name;
  3885.         $manufacturer_data['description']   = 'Производитель ' . $manufacturer_data['name'];
  3886.         $manufacturer_data['sort_order']    = 1;
  3887.         $manufacturer_data['guid']          = (string)$manufacturer_guid;
  3888.  
  3889.         if (isset($this->FIELDS['manufacturer']['noindex'])) {
  3890.             $manufacturer_data['noindex'] = 1;  // значение по умолчанию
  3891.         }
  3892.  
  3893.         if ($manufacturer_guid) {
  3894.             // Поиск (производителя) изготовителя по 1C Ид
  3895.             $query = $this->query("SELECT mc.manufacturer_id FROM `" . DB_PREFIX . "manufacturer_to_1c` mc LEFT JOIN `" . DB_PREFIX . "manufacturer_to_store` ms ON (mc.manufacturer_id = ms.manufacturer_id) WHERE mc.guid = '" . $this->db->escape($manufacturer_data['guid']) . "' AND ms.store_id = " . $this->STORE_ID);
  3896.         } else {
  3897.             // Поиск по имени
  3898.             $query = $this->query("SELECT m.manufacturer_id FROM `" . DB_PREFIX . "manufacturer` m LEFT JOIN `" . DB_PREFIX . "manufacturer_to_store` ms ON (m.manufacturer_id = ms.manufacturer_id) WHERE m.name LIKE '" . $this->db->escape($manufacturer_data['name']) . "' AND ms.store_id = " . $this->STORE_ID);
  3899.         }
  3900.  
  3901.         if ($query->num_rows) {
  3902.             $manufacturer_data['manufacturer_id'] = $query->row['manufacturer_id'];
  3903.         }
  3904.  
  3905.         if (!isset($manufacturer_data['manufacturer_id'])) {
  3906.             // Создаем
  3907.             $this->addManufacturer($manufacturer_data);
  3908.         } else {
  3909.             // Обновляем
  3910.             $this->updateManufacturer($manufacturer_data);
  3911.         }
  3912.  
  3913.         return $manufacturer_data['manufacturer_id'];
  3914.  
  3915.     } // setManufacturer()
  3916.  
  3917.  
  3918.     /**
  3919.      * ver 2
  3920.      * update 2017-06-13
  3921.      * Обрабатывает единицу измерения товара
  3922.      * Возвращает массив
  3923.      */
  3924.     private function parseProductUnit($xml = null) {
  3925.  
  3926.         $unit_data = array();
  3927.  
  3928.         if (!$xml) {
  3929.             $unit_data['full_name']         = "Штука";
  3930.             $unit_data['name']              = "шт";
  3931.             $unit_data['eng_name']          = "PCE";
  3932.             $unit_data['ratio']             = 1;
  3933.             return $unit_data;
  3934.         }
  3935.  
  3936.         if (isset($xml['Код'])) {
  3937.             $unit_data['number_code'] = (int)$xml['Код'];
  3938.         }
  3939.  
  3940.         if (isset($xml['НаименованиеПолное'])) {
  3941.             $unit_data['full_name'] = htmlspecialchars((string)$xml['НаименованиеПолное']);
  3942.         }
  3943.  
  3944.         // Короткое наименование
  3945.         $unit_data['name'] = (string)$xml;
  3946.  
  3947.         if (isset($xml['МеждународноеСокращение'])) {
  3948.             $unit_data['eng_name'] = (string)$xml['МеждународноеСокращение'];
  3949.         }
  3950.  
  3951.         // Коэффициент пересчета от базовой единицы
  3952.         if ($xml->Пересчет) {
  3953.             $unit_data['ratio'] = (float)$xml->Пересчет->Коэффициент;
  3954.         } else {
  3955.             $unit_data['ratio'] = 1;
  3956.         }
  3957.  
  3958.         $this->log("> Единица измерения: '" . $unit_data['name'] . "', коэффициент: " . $unit_data['ratio']);
  3959.  
  3960.         return $unit_data;
  3961.  
  3962.     } // parseProductUnit()
  3963.  
  3964.  
  3965.     /**
  3966.      * ver 4
  3967.      * update 2017-06-13
  3968.      * Обрабатывает единицы измерения в классификаторе ver. XML >= 2.09
  3969.      * Заполняем справочник единиц которые будут использованы в товарах
  3970.      */
  3971.     private function parseClassifierUnits($xml) {
  3972.  
  3973.         $result = array();
  3974.         $old_units = array();
  3975.  
  3976.         // Прочитаем старые соответствия единиц измерения
  3977.         $query = $this->query("SELECT * FROM `" . DB_PREFIX . "unit_to_1c`");
  3978.         if ($query->num_rows) {
  3979.             foreach ($query->rows as $row) {
  3980.                 $old_units[$query->row['guid']] = array(
  3981.                     'unit_id'       => $query->row['unit_id'],
  3982.                     'name'          => $query->row['name'],
  3983.                     'full_name'     => $query->row['full_name'],
  3984.                     'number_code'   => $query->row['number_code']
  3985.                 );
  3986.             }
  3987.         }
  3988.         $this->log($old_units, 2);
  3989.  
  3990.         foreach ($xml->ЕдиницаИзмерения as $unit) {
  3991.  
  3992.             // Сопоставляет Ид с id единицей измерения CMS
  3993.             $delete         = (string)$unit->ПометкаУдаления == 'false' ? false : true;
  3994.             $unit_guid          = (string)$unit->Ид;
  3995.             $data = array(
  3996.                 'name'              => (string)$unit->НаименованиеКраткое,
  3997.                 'full_name'         => (string)$unit->НаименованиеПолное,
  3998.                 'number_code'       => (string)$unit->Код
  3999.             );
  4000.  
  4001.             // Проверим наличие единицы в базе
  4002.             if (isset($old_units[$unit_guid])) {
  4003.  
  4004.                 $fields = $this->compareArraysNew($old_units[$unit_guid], $data);
  4005.                 if ($fields) {
  4006.                     $this->query("UPDATE `" . DB_PREFIX . "unit_to_1c` SET " . $fields . " WHERE `guid` = " . $unit_guid);
  4007.                 }
  4008.                 // отметим что такую единицу удалять не нужно, за исключением помеченных на удаление
  4009.                 if (!$delete) {
  4010.                     unset($old_units[$unit_guid]);
  4011.                 }
  4012.  
  4013.             } else {
  4014.  
  4015.                 // Добавляем только не помеченные на удаление
  4016.                 if (!$delete) {
  4017.                     $this->query("INSERT INTO `" . DB_PREFIX . "unit_to_1c` SET `name` = '" . $this->db->escape($data['name']) . "', `full_name` = '" . $this->db->escape($data['full_name']) . "', `guid` = '" . $this->db->escape($unit_guid) . "', `number_code` = " . $data['number_code']);
  4018.                     $unit_id = $this->db->getLastId();
  4019.                 }
  4020.             }
  4021.  
  4022.             if ($this->config->get('exchange1c_parse_unit_in_memory') == 1) {
  4023.                 if ($unit_id) {
  4024.                     $result[$unit_guid] = $unit_id;
  4025.                 }
  4026.             }
  4027.         }
  4028.  
  4029.         // удаляем неиспользуемые только при полной выгрузке
  4030.         if ($this->FULL_IMPORT) {
  4031.             // Если есть что удалять
  4032.             if (count($old_units)) {
  4033.                 $delete_units = array();
  4034.                 foreach ($old_units as $old_unit) {
  4035.                     $delete_units[] = $old_unit['unit_id'];
  4036.                 }
  4037.                 $this->query("DELETE FROM `" . DB_PREFIX . "unit_to_1c` WHERE `unit_id` IN (" . implode(',', $delete_units) . ")");
  4038.                 $this->log("Удалены неиспользуемые единицы, unit_id: " . implode(',', $delete_units), 2);
  4039.             }
  4040.         }
  4041.  
  4042.         $this->log("Прочитаны единицы измерения в классификаторе (XML >= 2.09)", 2);
  4043.  
  4044.         return $result;
  4045.  
  4046.     } // parseClassifierUnits()
  4047.  
  4048.  
  4049.     /**
  4050.      * ver 2
  4051.      * update 2017-04-14
  4052.      * Отзывы парсятся с Яндекса в 1С, а затем на сайт
  4053.      * Доработка от SunLit (Skype: strong_forever2000)
  4054.      * Читает отзывы из классификатора и записывает их в массив
  4055.      */
  4056.     private function parseReview($xml) {
  4057.  
  4058.         $product_review = array();
  4059.         foreach ($xml->Отзыв as $property) {
  4060.             $product_review[trim((string)$property->Ид)] = array(
  4061.                 'id'    => trim((string)$property->Ид),
  4062.                 'name'  => trim((string)$property->Имя),
  4063.                 'yes'   => trim((string)$property->Да),
  4064.                 'no'    => trim((string)$property->Нет),
  4065.                 'text'  => trim((string)$property->Текст),
  4066.                 'rate'  => (int)$property->Рейтинг,
  4067.                 'date'  => trim((string)$property->Дата),
  4068.             );
  4069.             $this->log("> " . trim((string)$property->Имя) . "'",2);
  4070.         }
  4071.         $this->log("Отзывы прочитаны",2);
  4072.         return $product_review;
  4073.  
  4074.     } // parseReview()
  4075.  
  4076.  
  4077.     /**
  4078.      * Удаляет старые неиспользуемые картинки
  4079.      * Сканирует все файлы в папке import_files и ищет где они указаны в товаре, иначе удаляет файл
  4080.      */
  4081.     public function cleanOldImages($folder) {
  4082.  
  4083.         $result = array('error' => "", 'num' => 0);
  4084.         if (!file_exists(DIR_IMAGE . $folder)) {
  4085.             $result['error'] = "Папка не существует: /image/" . $folder;
  4086.             return $result;
  4087.         }
  4088.         $dir = dir(DIR_IMAGE . $folder);
  4089.         while ($file = $dir->read()) {
  4090.  
  4091.             if ($file == '.' || $file == '..') {
  4092.                 continue;
  4093.             }
  4094.  
  4095.             $path = $folder . $file;
  4096.  
  4097.             if (file_exists(DIR_IMAGE . $path)) {
  4098.                 if (is_file(DIR_IMAGE . $path)) {
  4099.  
  4100.                     // это файл, проверим его причастность к товару
  4101.                     $query = $this->query("SELECT `product_id`,`image` FROM `" . DB_PREFIX . "product` WHERE `image` LIKE '". $path . "'");
  4102.                     if ($query->num_rows) {
  4103.                         $this->log("> файл: '" . $path . "' принадлежит товару: " . $query->row['product_id'], 2);
  4104.                         continue;
  4105.                     } else {
  4106.                         $this->log("> Не найден в базе, нужно удалить файл: " . $path, 2);
  4107.                         $result_ = @unlink(DIR_IMAGE . $path);
  4108.                         if ($result_) {
  4109.                             $result['num']++;
  4110.                         } else {
  4111.                             $this->log("[!] Ошибка удаления файла: " . $path, 2);
  4112.                             $result['error'] .= "Ошибка удаления файла: " . $path . "\n";
  4113.                             return $result;
  4114.                         }
  4115.                     }
  4116.  
  4117.                 } elseif (is_dir(DIR_IMAGE . $path)) {
  4118.                     $this->cleanOldImages($path . '/', $result['num']);
  4119.                     // Попытка удалить папку, если она не пустая, то произойдет удаление
  4120.                     $result_ = @rmdir(DIR_IMAGE . $path);
  4121.                     if ($result_) {
  4122.                         $this->log("> Удалена пустая папка: " . $path, 2);
  4123.                     }
  4124.                     continue;
  4125.                 }
  4126.             }
  4127.  
  4128.         }
  4129.         return $result;
  4130.  
  4131.     } // cleanOldImages()
  4132.  
  4133.  
  4134.  
  4135.     /**
  4136.      * Отключает все товары, можно сделать опцию удаления ненужных и их связи и так далее
  4137.      */
  4138.     private function cleanProductData($product_id) {
  4139.  
  4140.         if ($this->config->get('exchange1c_clean_options') == 1) {
  4141.             $this->log("[!] Перед полной загрузкой удаляются у товара все характеристики, опции, цены, остатки и единицы измерений");
  4142.             $this->query("DELETE FROM `" . DB_PREFIX . "product_feature` WHERE `product_id` = " . $product_id);
  4143.             $this->query("DELETE FROM `" . DB_PREFIX . "product_feature_value` WHERE `product_id` = " . $product_id);
  4144.             $this->query("DELETE FROM `" . DB_PREFIX . "product_option` WHERE `product_id` = " . $product_id);
  4145.             $this->query("DELETE FROM `" . DB_PREFIX . "product_option_value` WHERE `product_id` = " . $product_id);
  4146.             $this->query("DELETE FROM `" . DB_PREFIX . "product_price` WHERE `product_id` = " . $product_id);
  4147.             $this->query("DELETE FROM `" . DB_PREFIX . "product_quantity` WHERE `product_id` = " . $product_id);
  4148.             $this->query("DELETE FROM `" . DB_PREFIX . "product_unit` WHERE `product_id` = " . $product_id);
  4149.         }
  4150.  
  4151.     } // cleanProductData()
  4152.  
  4153.  
  4154.     /**
  4155.      * ver 2
  4156.      * update 2017-06-13
  4157.      * Удаляет все дубли связей с торговой системой
  4158.      */
  4159.     public function removeDoublesLinks() {
  4160.  
  4161.         $tables = array('attribute','category','manufacturer','product','store');
  4162.         $result = array('error'=>"");
  4163.  
  4164.         // начинаем работать с каждой таблицей
  4165.         foreach ($tables as $table) {
  4166.             $field_id = $table . "_id";
  4167.             $result[$table] = 0;
  4168.             $query = $this->query("SELECT `" . $field_id . "`, `guid`, COUNT(*) as `count` FROM `" . DB_PREFIX . $table . "_to_1c` GROUP BY `" . $field_id . "`,`guid` HAVING COUNT(*)>1 ORDER BY COUNT(*) DESC");
  4169.             if ($query->num_rows) {
  4170.                 $this->log("Есть дубликаты GUID", 2);
  4171.                 $this->log($query, 2);
  4172.                 foreach ($query->rows as $row) {
  4173.                     $limit = (int)$row['count'] - 1;
  4174.                     $result[$table] += $limit;
  4175.                     $this->query("DELETE FROM `" . DB_PREFIX . $table . "_to_1c` WHERE `" . $field_id . "` = " . $row[$field_id] . " AND `guid` = '" . $this->db->escape($row['guid']) . "' LIMIT " . $limit);
  4176.                 }
  4177.             }
  4178.  
  4179.         }
  4180.         $this->log("Дубли ссылок удалены");
  4181.         return $result;
  4182.  
  4183.     } // removeDoublesLinks()
  4184.  
  4185.  
  4186.     /**
  4187.      * ver 2
  4188.      * update 2017-05-23
  4189.      * Возвращает название товара
  4190.      */
  4191.     private function parseProductName($product, &$data) {
  4192.  
  4193.         $name = "";
  4194.  
  4195.         if ($product->ПолноеНаименование) {
  4196.             $data['full_name']      = htmlspecialchars((string)$product->ПолноеНаименование);
  4197.             $this->log("> Найдено полное наименование: '" . $data['full_name'] . "'", 2);
  4198.         }
  4199.  
  4200.         // Название поля наименования
  4201.         $field_name = $this->config->get('exchange1c_import_product_name_field');
  4202.  
  4203.         if ($this->config->get('exchange1c_import_product_name') == "manually") {
  4204.             $name = htmlspecialchars((string)$product->$field_name);
  4205.         } elseif ($this->config->get('exchange1c_import_product_name') == "fullname") {
  4206.             $name = $data['full_name'];
  4207.         }
  4208.         if ($name) {
  4209.             $data['name'] = $name;
  4210.         }
  4211.  
  4212.     } // parseProductName()
  4213.  
  4214.  
  4215.     /**
  4216.      * Возвращает название модели
  4217.      */
  4218.     private function parseProductModel($product, $data) {
  4219.  
  4220.         if ($product->Модель) {
  4221.             return (string)$product->Модель;
  4222.         }
  4223.         return  isset($data['sku']) ? $data['sku'] : $data['product_guid'];
  4224.  
  4225.     } // parseProductModel()
  4226.  
  4227.  
  4228.     /**
  4229.      * Возвращает преобразованный числовой id из Код товара торговой системы
  4230.      */
  4231.     private function parseCode($code) {
  4232.  
  4233.         $out = "";
  4234.         // Пока руки не дошли до преобразования, надо откидывать префикс, а после лидирующие нули
  4235.         $length = mb_strlen($code);
  4236.         $begin = -1;
  4237.         for ($i = 0; $i <= $length; $i++) {
  4238.             $char = mb_substr($code,$i,1);
  4239.             // ищем первую цифру не ноль
  4240.             if ($begin == -1 && is_numeric($char) && $char != '0') {
  4241.                 $begin = $i;
  4242.                 $out = $char;
  4243.             } else {
  4244.                 // начало уже определено, читаем все цифры до конца
  4245.                 if (is_numeric($char)) {
  4246.                     $out .= $char;
  4247.                 }
  4248.             }
  4249.         }
  4250.         return  (int)$out;
  4251.  
  4252.     } // parseCode()
  4253.  
  4254.  
  4255.     /**
  4256.      * Возвращает id производителя
  4257.      */
  4258.     private function getProductManufacturerId($product) {
  4259.  
  4260.         // Читаем изготовителя, добавляем/обновляем его в базу
  4261.         if ($product->Изготовитель) {
  4262.             return $this->setManufacturer($product->Изготовитель->Наименование, $product->Изготовитель->Ид);
  4263.         }
  4264.         // Читаем производителя из поля Бренд <Бренд>Denny Rose</Бренд>
  4265.         if ($product->Бренд) {
  4266.             return $this->setManufacturer($product->Бренд);
  4267.         }
  4268.  
  4269.     } // getProductManufacturerId()
  4270.  
  4271.  
  4272.     /**
  4273.      * ver 2
  4274.      * update 2017-04-26
  4275.      * Возвращает id категорий по GUID
  4276.      */
  4277.     private function parseProductCategories($categories, $classifier_categories = array()) {
  4278.  
  4279.         $result = array();
  4280.         if ($this->config->get('exchange1c_synchronize_by_code') == 1) {
  4281.             foreach ($categories->Код as $category_code) {
  4282.                 $category_id = $this->parseCode($category_code);
  4283.                 if ($category_id) {
  4284.                     $result[] = $category_id;
  4285.                 }
  4286.             }
  4287.             if (count($result)) {
  4288.                 $this->log("Категории прочитаны по Коду",2);
  4289.                 return $result;
  4290.             }
  4291.         }
  4292.         foreach ($categories->Ид as $category_guid) {
  4293.             $guid = (string)$category_guid;
  4294.             if ($classifier_categories) {
  4295.                 // Ищем в массиве
  4296.                 if (isset($classifier_categories[$guid])) {
  4297.                     $category_id = $classifier_categories[$guid];
  4298.                     $this->log("Категория найдена в массиве, category_id = " . $category_id);
  4299.                 }
  4300.             } else {
  4301.                 // Ищем в базе данных
  4302.                 $category_id = $this->getCategoryIdByGuid($guid);
  4303.             }
  4304.             if ($category_id) {
  4305.                 $result[] = $category_id;
  4306.             } else {
  4307.                 $this->log("[!] Категория не найдена по Ид: " . $guid);
  4308.             }
  4309.         }
  4310.         $this->log("Категории товаров прочитаны.",2);
  4311.         return $result;
  4312.  
  4313.     } // parseProductCategories()
  4314.  
  4315.  
  4316.     /**
  4317.      * ver 10
  4318.      * update 2017-06-03
  4319.      * Обрабатывает товары из раздела <Товары> в XML
  4320.      * При порционной выгрузке эта функция запускается при чтении каждого файла
  4321.      * При полной выгрузке у товара очищаются все и загружается по новой.
  4322.      * В формате 2.04 характеристики названия характеристике и их значение для данного товара передается тут
  4323.      * Начиная с версии 1.6.3 читается каждая характеристика по отдельности, так как некоторые системы рвут товары с характеристиками
  4324.      */
  4325.     private function parseProducts($xml, $classifier) {
  4326.  
  4327.         if (!$xml->Товар) {
  4328.             $this->ERROR = "parseProducts() - empty XML";
  4329.             return false;
  4330.         }
  4331.  
  4332.         foreach ($xml->Товар as $product){
  4333.  
  4334.             $data = array();
  4335.  
  4336.             // Получаем Ид товара и характеристики
  4337.             $guid_full = explode("#", (string)$product->Ид);
  4338.             $data['product_guid']   = $guid_full[0];
  4339.             $data['feature_guid']   = isset($guid_full[1]) ? $guid_full[1] : '';
  4340.             $data['product_id']     = 0;
  4341. //          $data['mpn']            = $data['product_guid'];
  4342.             $data['name']           = htmlspecialchars((string)$product->Наименование);
  4343.  
  4344.             // Единица измерения длины товара
  4345.             if ($this->config->get('config_length_class_id')) {
  4346.                 $data['length_class_id']    = $this->config->get('config_length_class_id');
  4347.             }
  4348.  
  4349.             // Единица измерения веса товара
  4350.             if ($this->config->get('config_weight_class_id')) {
  4351.                 $data['weight_class_id']    = $this->config->get('config_weight_class_id');
  4352.             }
  4353.  
  4354.             $this->log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 2);
  4355.             if ($data['feature_guid']) {
  4356.                 $this->log("ТОВАР: Ид: '" . $data['product_guid'] . "', ХАРАКТЕРИСТИКА Ид: '" . $data['feature_guid'] . "'");
  4357.             } else {
  4358.                 $this->log("ТОВАР: Ид: '" . $data['product_guid'] . "'");
  4359.             }
  4360.  
  4361.             // есть ли в предложении характеристики
  4362.             if ($product->ХарактеристикиТовара) {
  4363.                 $result = $this->parseFeatures($product->ХарактеристикиТовара, $data);
  4364.                 if (count($result)) $data['features'] = $result;
  4365.                 if ($this->ERROR) return false;
  4366.             }
  4367.  
  4368.             // Артикул товара или характеристики
  4369.             if ($product->Артикул) {
  4370.                 $data['sku']        = htmlspecialchars((string)$product->Артикул);
  4371.             }
  4372.  
  4373.             // Код товара для прямой синхронизации
  4374.             if ($product->Код) {
  4375.                 $data['code']       = $this->parseCode((string)$product->Код);
  4376.             }
  4377.  
  4378.             // Пометка удаления, товар будет отключен
  4379.             if ((string)$product->ПометкаУдаления == 'true') {
  4380.                 $data['status'] = 0;
  4381.             }
  4382.  
  4383.             // Синхронизация с Яндекс маркет (всегда включено)
  4384.             // В некоторых CMS имеется поле для синхронизаци, например с Yandex
  4385.             if (isset($this->TAB_FIELDS['product']['noindex'])) {
  4386.                 $data['noindex']        = 1; // В некоторых версиях
  4387.             }
  4388.  
  4389.             // Описание товара в текстовом формате, нужна опция если описание в формате HTML
  4390.             if ($product->Описание && $this->config->get('exchange1c_import_product_description') == 1) {
  4391.                 if ($this->config->get('exchange1c_description_html') == 1) {
  4392.                     $data['description']    =  nl2br(htmlspecialchars((string)$product->Описание));
  4393.                 } else {
  4394.                     $data['description']    = (string)$product->Описание;
  4395.                 }
  4396.             }
  4397.  
  4398.             // Реквизиты товара из торговой системы (разные версии CML)
  4399.             if ($product->ЗначениеРеквизита) {
  4400.                 $this->parseRequisite($product, $data);
  4401.                 if ($this->ERROR) {
  4402.                     return false;
  4403.                 }
  4404.  
  4405.             } elseif ($product->ЗначенияРеквизитов) {
  4406.                 // Реквизиты (разные версии CML)
  4407.                 $this->parseRequisite($product->ЗначенияРеквизитов, $data);
  4408.                 if ($this->ERROR) {
  4409.                     return false;
  4410.                 }
  4411.             }
  4412.  
  4413.             // Модель товара
  4414.             // Читается из поля товара "SKU" или из реквизита "Модель" в зависимости от настроек
  4415.             $data['model']  = $this->parseProductModel($product, $data);
  4416.  
  4417.             // Наименование товара или характеристики
  4418.             // Если надо меняет наименование товара из полного или из поля пользователя
  4419.             $this->parseProductName($product, $data);
  4420.             $this->log("> наименование: '" . $data['name'] . "'");
  4421.  
  4422.             // Тип номенклатуры ()читается из реквизитов)
  4423.             // Если фильтр по типу номенклатуры заполнен, то загружаем указанные там типы
  4424.             $exchange1c_parse_only_types_item = $this->config->get('exchange1c_parse_only_types_item');
  4425.             if (isset($data['item_type']) && (!empty($exchange1c_parse_only_types_item))) {
  4426.                 if (mb_stripos($exchange1c_parse_only_types_item, $data['item_type']) === false) {
  4427.                     continue;
  4428.                 }
  4429.             }
  4430.  
  4431.             // Если включено обновление категорий
  4432.             if ($this->config->get('exchange1c_product_categories') != 'disable') {
  4433.  
  4434.                 // Категории товара (Группы в 1С)
  4435.                 if ($product->Группы) {
  4436.                     if (isset($classifier['categories'])) {
  4437.                         $data['product_categories'] = $this->parseProductCategories($product->Группы, $classifier['categories']);
  4438.                     } else {
  4439.                         $data['product_categories'] = $this->parseProductCategories($product->Группы);
  4440.                     }
  4441.                 }
  4442.             }
  4443.  
  4444.             // Если включено обновление производителя
  4445.             if ($this->config->get('exchange1c_import_product_manufacturer') == 1) {
  4446.  
  4447.                 $manufacturer_id = $this->getProductManufacturerId($product);
  4448.  
  4449.                 if ($manufacturer_id) {
  4450.                     $data['manufacturer_id'] = $manufacturer_id;
  4451.                 }
  4452.             }
  4453.  
  4454.             // Статус, только для товара
  4455.             // Статус по-умолчанию при отсутствии товара на складе
  4456.             // Можно реализовать загрузку из свойств
  4457.             if ($this->config->get('exchange1c_default_stock_status')) {
  4458.                 $data['stock_status_id'] = $this->config->get('exchange1c_default_stock_status');
  4459.             }
  4460.  
  4461.             // Свойства, только для товара
  4462.             //if ($product->ЗначенияСвойств && isset($classifier['attributes']))
  4463.             if ($product->ЗначенияСвойств) {
  4464.                 $this->parseAttributes($product->ЗначенияСвойств, $data, $classifier);
  4465.                 if ($this->ERROR) return false;
  4466.             }
  4467.  
  4468.             // КАРТИНКИ
  4469.             // Если включено обновлять картинки
  4470.             if ($this->config->get('exchange1c_product_images_import_mode') != 'disable') {
  4471.  
  4472.                 // Описание файлов
  4473.                 $description = isset($data['description_files']) ? $data['description_files'] : array();
  4474.  
  4475.                 // Картинки, только для товара
  4476.                 if ($product->Картинка) {
  4477.  
  4478.                     $images = isset($data['images']) ? $data['images'] : array();
  4479.                     $data['images'] = $this->parseImages($product->Картинка, $images, $description);
  4480.  
  4481.                     if ($this->ERROR) return false;
  4482.  
  4483.                 } // if ($product->Картинка)
  4484.  
  4485.                 // Картинки, только для товара (CML 2.04)
  4486.                 if ($product->ОсновнаяКартинка) {
  4487.  
  4488.                     $images = isset($data['images']) ? $data['images'] : array();
  4489.                     $data['images'] = $this->parseImages($product->ОсновнаяКартинка, $images, $description);
  4490.  
  4491.                     if ($this->ERROR) return false;
  4492.  
  4493.                     // дополнительные, когда элементы в файле называются <Картинка1>, <Картинка2>...
  4494.                     $cnt = 1;
  4495.                     $var = 'Картинка'.$cnt;
  4496.  
  4497.                     while (!empty($product->$var)) {
  4498.  
  4499.                         $data['images'] = $this->parseImages($product->$var, $data['images'], $description);
  4500.                         if ($this->ERROR) return false;
  4501.  
  4502.                         $cnt++;
  4503.                         $var = 'Картинка'.$cnt;
  4504.                     }
  4505.  
  4506.                 } // if ($product->ОсновнаяКартинка)
  4507.  
  4508.                 // Освобождаем память
  4509.                 unset($description);
  4510.  
  4511.                 // Основная картинка
  4512.                 if (isset($data['images'][0])) {
  4513.                     $data['image'] = $data['images'][0]['file'];
  4514.                 } else {
  4515.                     // если картинки нет подставляем эту
  4516.                     $data['image'] = 'no_image.png';
  4517.                 }
  4518.  
  4519.             } else {
  4520.                 $this->log("[i] Обновление картинок отключено!", 2);
  4521.             }
  4522.  
  4523.             // Штрихкод
  4524.             if ($product->Штрихкод) {
  4525.                 $data['ean'] =  (string)$product->Штрихкод;
  4526.             }
  4527.  
  4528.             // Базовая единица товара
  4529.             if ($product->БазоваяЕдиница) {
  4530.  
  4531.                 // Базовая единица товара
  4532.                 $data['unit'] = $this->parseProductUnit($product->БазоваяЕдиница);
  4533.                 if ($this->ERROR) return false;
  4534.  
  4535.             } // $product->БазоваяЕдиница
  4536.  
  4537.             // Отзывы парсятся с Яндекса в 1С, а затем на сайт
  4538.             // Доработка от SunLit (Skype: strong_forever2000)
  4539.             // Отзывы
  4540.             if ($product->ЗначенияОтзывов) {
  4541.                 $data['review'] = $this->parseReview($data, $product->ЗначенияОтзывов);
  4542.                 if ($this->ERROR) return false;
  4543.             }
  4544.  
  4545.             // Добавляем или обновляем товар в базе
  4546.             $this->setProduct($data);
  4547.             if ($this->ERROR) return false;
  4548.  
  4549.             // Освобождаем память
  4550.             unset($data);
  4551.  
  4552.             // Прерывание обмена
  4553.             if (file_exists(DIR_CACHE . 'exchange1c/break')) {
  4554.                 $this->ERROR = "parseProducts() - file exists 'break'";
  4555.                 return false;
  4556.             }
  4557.         } // foreach
  4558.  
  4559.         // Отключим товары не попавшие в обмен только при полной выгрузке
  4560.         if ($this->config->get('exchange1c_product_not_import_disable') == 1 && $this->FULL_IMPORT) {
  4561.  
  4562.             $products_disable = array();
  4563.             $query = $this->query("SELECT `product_id` FROM `" . DB_PREFIX . "product` WHERE `date_modified` < '" . $this->NOW . "'");
  4564.             $num = 0;
  4565.  
  4566.             // Эта переменная указывает сколько товаров может отключать за один запрос.
  4567.             $num_part = 1000;
  4568.  
  4569.             if ($query->num_rows) {
  4570.  
  4571.                 foreach ($query->rows as $row) {
  4572.                     $products_disable[] = $row['product_id'];
  4573.  
  4574.                     if (count($products_disable) >= $num_part) {
  4575.                         $this->query("UPDATE `" . DB_PREFIX . "product` SET `status` = 0 WHERE `product_id` IN (" . (implode(",",$products_disable)) . ")");
  4576.                         $products_disable = array();
  4577.                         $num += count($products_disable);
  4578.                     }
  4579.                 }
  4580.  
  4581.                 if ($products_disable) {
  4582.                     $this->query("UPDATE `" . DB_PREFIX . "product` SET `status` = 0 WHERE `product_id` IN (" . (implode(",",$products_disable)) . ")");
  4583.                     $num += count($products_disable);
  4584.                 }
  4585.  
  4586.             }
  4587.  
  4588.             $this->log("Отключены товары которых нет в выгрузке: " . $num);
  4589.         }
  4590.  
  4591.         return true;
  4592.  
  4593.     } // parseProducts()
  4594.  
  4595.  
  4596.     /**
  4597.      * ver 4
  4598.      * update 2017-006-09
  4599.      * Разбор каталога
  4600.      */
  4601.     private function parseDirectory($xml, $classifier) {
  4602.  
  4603.         $this->checkFullImport($xml);
  4604.  
  4605.         $directory                  = array();
  4606.         $directory['guid']          = (string)$xml->Ид;
  4607.         $directory['name']          = (string)$xml->Наименование;
  4608.         $directory['classifier_id'] = (string)$xml->ИдКлассификатора;
  4609.         if (isset($classifier['id'])) {
  4610.             if ($directory['classifier_id'] <> $classifier['id']) {
  4611.                 $this->ERROR = "Загружаемый каталог не соответствует классификатору";
  4612.                 return false;
  4613.             }
  4614.         }
  4615.  
  4616.         if ($this->config->get('exchange1c_flush_quantity') == 'all' && $this->FULL_IMPORT) {
  4617.             $this->clearProductsQuantity();
  4618.         }
  4619.  
  4620.         // Если есть товары
  4621.         if ($xml->Товары) {
  4622.             // Загрузка товаров
  4623.             $this->parseProducts($xml->Товары, $classifier);
  4624.             if ($this->ERROR) return false;
  4625.         }
  4626.  
  4627.         return true;
  4628.  
  4629.     } // parseDirectory()
  4630.  
  4631.  
  4632.     /**
  4633.      * ****************************** ФУНКЦИИ ДЛЯ ЗАГРУЗКИ ПРЕДЛОЖЕНИЙ ******************************
  4634.      */
  4635.  
  4636.     /**
  4637.      * Добавляет склад в базу данных
  4638.      */
  4639.     private function addWarehouse($warehouse_guid, $name) {
  4640.  
  4641.         $this->query("INSERT INTO `" . DB_PREFIX . "warehouse` SET `name` = '" . $this->db->escape($name) . "', `guid` = '" . $this->db->escape($warehouse_guid) . "'");
  4642.         $warehouse_id = $this->db->getLastId();
  4643.         $this->log("> Склад добавлен, warehouse_id = " . $warehouse_id, 2);
  4644.         return $warehouse_id;
  4645.  
  4646.     } // addWarehouse()
  4647.  
  4648.  
  4649.     /**
  4650.      * Ищет warehouse_id по GUID
  4651.      */
  4652.     private function getWarehouseByGuid($warehouse_guid) {
  4653.  
  4654.         $query = $this->query('SELECT `warehouse_id` FROM `' . DB_PREFIX . 'warehouse` WHERE `guid` = "' . $this->db->escape($warehouse_guid) . '"');
  4655.         if ($query->num_rows) {
  4656.             return $query->row['warehouse_id'];
  4657.         }
  4658.         $this->log("Склад не найден в базе", 2);
  4659.         return 0;
  4660.  
  4661.     } // getWarehouseByGuid()
  4662.  
  4663.  
  4664.     /**
  4665.      * Возвращает id склада
  4666.      */
  4667.     private function setWarehouse($warehouse_guid, $name) {
  4668.  
  4669.         // Поищем склад по 1С Ид
  4670.         $warehouse_id = $this->getWarehouseByGuid($warehouse_guid);
  4671.         if (!$warehouse_id) {
  4672.             $warehouse_id = $this->addWarehouse($warehouse_guid, $name);
  4673.             $this->log("> Склад добавлен, warehouse_id = " . $warehouse_id,2);
  4674.         }
  4675.         return $warehouse_id;
  4676.  
  4677.     } // setWarehouse()
  4678.  
  4679.  
  4680.     /**
  4681.      * Получает остаток товара по фильтру
  4682.      * ver 2
  4683.      * update 2017-04-05
  4684.      */
  4685.     private function getProductQuantityTotal($product_id) {
  4686.  
  4687.         $query = $this->query("SELECT SUM(`quantity`) as `quantity` FROM `" . DB_PREFIX . "product_quantity` WHERE `product_id` = " . $product_id);
  4688.         if ($query->num_rows) {
  4689.             return (float)$query->row['quantity'];
  4690.         } else {
  4691.             return false;
  4692.         }
  4693.  
  4694.     } // getProductQuantityTotal()
  4695.  
  4696.  
  4697.     /**
  4698.      * ver 2
  4699.      * update 2017-04-05
  4700.      * Получает все цены характеристик товара и возвращает минимальную среди цен которые больше нуля
  4701.      */
  4702.     private function getProductPriceMin($product_id) {
  4703.  
  4704.         $default_customer_group_id = $this->config->get('config_customer_group_id');
  4705.         $query = $this->query("SELECT MIN(`price`) as `price` FROM `" . DB_PREFIX . "product_price` WHERE `product_id` = " . $product_id . " AND `customer_group_id` = " . $default_customer_group_id . " AND `price` > 0");
  4706.         if ($query->num_rows) {
  4707.             return (float)$query->row['price'];
  4708.         } else {
  4709.             return false;
  4710.         }
  4711.  
  4712.     } // getProductPriceMin()
  4713.  
  4714.  
  4715.     /**
  4716.      * Получает остаток товара по фильтру
  4717.      */
  4718.     private function getProductQuantity($product_quantity_filter) {
  4719.  
  4720.         $result = array();
  4721.         $where = "`product_id` = " . $product_quantity_filter['product_id'];
  4722.         $where .= " AND `product_feature_id` = " . (isset($product_quantity_filter['product_feature_id']) ?  $product_quantity_filter['product_feature_id'] : 0);
  4723.         $where .= " AND `warehouse_id` = " . (isset($product_quantity_filter['warehouse_id']) ?  $product_quantity_filter['warehouse_id'] : 0);
  4724.  
  4725.         $query = $this->query("SELECT `product_quantity_id`,`quantity` FROM `" . DB_PREFIX . "product_quantity` WHERE " . $where);
  4726.         if ($query->num_rows) {
  4727.             $result['quantity']             = $query->row['quantity'];
  4728.             $result['product_quantity_id']  = $query->row['product_quantity_id'];
  4729.             return $result;
  4730.         } else {
  4731.             $result['product_quantity_id']  = 0;
  4732.             return $result;
  4733.         }
  4734.  
  4735.     } // getProductQuantity()
  4736.  
  4737.  
  4738.     /**
  4739.      * Добавляет остаток товара по фильтру
  4740.      */
  4741.     private function addProductQuantity($product_quantity_filter, $quantity) {
  4742.  
  4743.         $set = "";
  4744.         foreach ($product_quantity_filter as $field => $value) {
  4745.             $set .= ", `" . $field . "` = " . $value;
  4746.         }
  4747.         $this->query("INSERT INTO `" . DB_PREFIX . "product_quantity` SET `quantity` = '" . (float)$quantity . "'" . $set);
  4748.         $product_quantity_id = $this->db->getLastId();
  4749.         $this->log("> Добавлены остатки в товар, product_quantity_id = " . $product_quantity_id, 2);
  4750.         return $product_quantity_id;
  4751.  
  4752.     } // addProductQuantity()
  4753.  
  4754.  
  4755.     /**
  4756.      * Сравнивает массивы и формирует список измененных полей для запроса
  4757.      */
  4758.     private function compareArraysNew($data1, $data2, $filelds_include = "") {
  4759.  
  4760.         //$result = array_diff_assoc($data1, $data2);
  4761.         //$filelds_include_obj = explode(",", $filelds_include);
  4762.  
  4763.         $upd_fields = array();
  4764.         if (count($data1)) {
  4765.             foreach($data1 as $key => $row) {
  4766.                 if (!isset($data2[$key])) continue;
  4767.                 if (!empty($filelds_include) && strripos($filelds_include, $key) === false) continue;
  4768.                 if ($row <> $data2[$key]) {
  4769.                     $upd_fields[] = "`" . $key . "` = '" . $this->db->escape($data2[$key]) . "'";
  4770.                     $this->log("[i] Отличается поле '" . $key . "', старое: " . $row . ", новое: " . $data2[$key], 2);
  4771.                 } else {
  4772.                     $this->log("Поле '" . $key . "' не имеет отличий", 2);
  4773.                 }
  4774.             }
  4775.         }
  4776.         return implode(', ', $upd_fields);
  4777.  
  4778.     } // compareArraysNew()
  4779.  
  4780.  
  4781.     /**
  4782.      * Ищет совпадение данных в массиве данных, при совпадении значений, возвращает ключ второго массива
  4783.      */
  4784.     private function findMatch($data1, $data_array) {
  4785.  
  4786.         $bestMatch = 0;
  4787.         foreach ($data_array as $key2 => $data2) {
  4788.             $matches = 0;
  4789.             $fields = 0;
  4790.             foreach ($data1 as $key1 => $value) {
  4791.                 if (isset($data2[$key1])) {
  4792.                     $fields++;
  4793.                     if ($data2[$key1] == $value) {
  4794.                         $matches++;
  4795.                     }
  4796.                 }
  4797.             }
  4798.             // у всех найденых полей совпали значения
  4799.             if ($matches == $fields){
  4800.                 return $key2;
  4801.             }
  4802.         }
  4803.         return false;
  4804.  
  4805.     } // findMatch()
  4806.  
  4807.  
  4808.     /**
  4809.      * ver 1
  4810.      * update 2017-04-21
  4811.      * Сбрасывает
  4812.      */
  4813.     private function setProductQuantity($product_quantity_filter, $quantity) {
  4814.  
  4815.         $result = $this->getProductQuantity($product_quantity_filter);
  4816.         if ($result['product_quantity_id']) {
  4817.             // Есть цена
  4818.             if ($result['quantity'] != $quantity) {
  4819.                 $query = $this->query("UPDATE `" . DB_PREFIX . "product_quantity` SET `quantity` = " . $quantity . " WHERE `product_quantity_id` = " . $result['product_quantity_id']);
  4820.             }
  4821.         } else {
  4822.             $this->addProductQuantity($product_quantity_filter, $quantity);
  4823.         }
  4824.  
  4825.     } // setProductQuantity()
  4826.  
  4827.  
  4828.     /**
  4829.      * ver 2
  4830.      * update 2017-04-05
  4831.      * Устанавливает остаток товара
  4832.      */
  4833.     private function clearProductsQuantity() {
  4834.  
  4835.         $this->query("UPDATE `" . DB_PREFIX . "product` `p` LEFT JOIN `" . DB_PREFIX . "product_to_store` `p2s` ON (`p`.`product_id` = `p2s`.`product_id`) SET `p`.`quantity` = 0 WHERE `p2s`.`store_id` = " . $this->STORE_ID);
  4836.  
  4837.     } // setProductQuantity()
  4838.  
  4839.  
  4840.     /**
  4841.      * ver 4
  4842.      * update 2017-05-28
  4843.      * Устанавливает остатки товара и опций
  4844.      */
  4845.     private function setProductQuantities($quantities, $product_id, $product_feature_id = 0, $new = false) {
  4846.  
  4847.         foreach ($quantities as $warehouse_id => $quantity) {
  4848.             $filter = array(
  4849.                 'product_id'            => $product_id,
  4850.                 'warehouse_id'          => $warehouse_id,
  4851.                 'product_feature_id'    => $product_feature_id
  4852.             );
  4853.  
  4854.             // Остатки товара
  4855.             $this->setProductQuantity($filter, $quantity);
  4856.  
  4857.             if (!$warehouse_id) {
  4858.                 // Остатки опций у характеристики
  4859.                 $this->setOptionQuantity($filter, $quantity);
  4860.             }
  4861.  
  4862.             $this->log("Остаток на складе (warehouse_id=" . $warehouse_id . ") = " . $quantity);
  4863.         }
  4864.  
  4865.     } // setProductQuantities()
  4866.  
  4867.  
  4868.     /**
  4869.      * ver 2
  4870.      * update 2017-05-28
  4871.      * Устанавливает остатки опций
  4872.      */
  4873.     private function setOptionQuantity($filter, $quantity, $new = false) {
  4874.  
  4875.         // Получим опции этой характеристики
  4876.         $query = $this->query("SELECT `product_option_value_id` FROM `" . DB_PREFIX . "product_feature_value` WHERE `product_feature_id` = " . $filter['product_feature_id']);
  4877.         if (!$query->num_rows) {
  4878.             return false;
  4879.         }
  4880.  
  4881.         $list_product_option_id = array();
  4882.         foreach ($query->rows as $row) {
  4883.             $list_product_option_id[] = $row['product_option_value_id'];
  4884.         }
  4885.         $list_product_option_id = implode(",", $list_product_option_id);
  4886.  
  4887.         // Устанавливаем у всех опций или одной, как там получится, остаток одинаковый, так как все они относятся к одной характеристике
  4888.         $query = $this->query("UPDATE `" . DB_PREFIX . "product_option_value` SET `quantity` = " . $quantity . " WHERE `product_option_value_id` IN (" . $list_product_option_id . ")");
  4889.  
  4890.         $this->log("Установлен остаток " . $quantity . " у опций " . $list_product_option_id);
  4891.  
  4892.         return true;
  4893.  
  4894.     } // setOptionQuantity()
  4895.  
  4896.  
  4897.     /**
  4898.      * Удаляет склад и все остатки поо нему
  4899.      */
  4900.     private function deleteWarehouse($warehouse_guid) {
  4901.  
  4902.         $warehouse_id = $this->getWarehouseByGuid($warehouse_guid);
  4903.         if ($warehouse_id) {
  4904.             // Удаляем все остатки по этму складу
  4905.             $this->deleteStockWarehouse($warehouse_id);
  4906.             // Удалим остатки по этому складу
  4907.             $this->query("DELETE FROM `" . DB_PREFIX . "product_quantity ` WHERE `warehouse_id` = " . (int)$warehouse_id);
  4908.             // Удаляем склад
  4909.             $this->query("DELETE FROM `" . DB_PREFIX . "warehouse ` WHERE `guid` = '" . $this->db->escape($warehouse_guid) . "'");
  4910.             $this->log("Удален склад, GUID '" . $warehouse_guid . "' и все остатки на нем.",2);
  4911.         }
  4912.  
  4913.     } // deleteWarehouse()
  4914.  
  4915.  
  4916.     /**
  4917.      * ver 2
  4918.      * update 2017-04-26
  4919.      * Загружает список складов из классификатора
  4920.      */
  4921.     private function parseClassifierWarehouses($xml) {
  4922.  
  4923.         $data = array();
  4924.         foreach ($xml->Склад as $warehouse){
  4925.             if (isset($warehouse->Ид) && isset($warehouse->Наименование) ){
  4926.                 $warehouse_guid = (string)$warehouse->Ид;
  4927.                 $name = trim((string)$warehouse->Наименование);
  4928.                 $delete = isset($warehouse->ПометкаУдаления) ? $warehouse->ПометкаУдаления : "false";
  4929.                 if ($delete == "false") {
  4930.                     $data[$warehouse_guid] = array(
  4931.                         'name' => $name
  4932.                     );
  4933.                     $data[$warehouse_guid]['warehouse_id'] = $this->setWarehouse($warehouse_guid, $name);
  4934.                     $this->log("Склад: '" . $name . "', id = " . $data[$warehouse_guid]['warehouse_id'], 2);
  4935.                 } else {
  4936.                     // Удалить склад
  4937.                     $this->log("[!] Склад помечен на удаление в торговой системе и будет удален");
  4938.                     $this->deleteWarehouse($warehouse_guid);
  4939.                 }
  4940.             }
  4941.         }
  4942.         $this->log("Складов в классификаторе: " . count($xml->Склад), 2);
  4943.         return $data;
  4944.  
  4945.     } // parseClassifierWarehouses()
  4946.  
  4947.  
  4948.     /**
  4949.      * ver 3
  4950.      * update 2017-05-23
  4951.      * Загружает остатки по складам
  4952.      * Возвращает остатки по складам
  4953.      * где индекс - это warehouse_id, а значение - это quantity (остаток)
  4954.      */
  4955.     private function parseQuantity($xml, $data) {
  4956.  
  4957.         $data_quantity = array();
  4958.  
  4959.         if (!$xml) {
  4960.             $this->ERROR = "parseQuantity() - нет данных в XML";
  4961.             return false;
  4962.         }
  4963.  
  4964.         // есть секция с остатками, обрабатываем
  4965.         if ($xml->Остаток) {
  4966.             foreach ($xml->Остаток as $quantity) {
  4967.                 // есть секция со складами
  4968.                 if ($quantity->Склад->Ид) {
  4969.                     $warehouse_guid = (string)$quantity->Склад->Ид;
  4970.                     $warehouse_id = $this->getWarehouseByGuid($warehouse_guid);
  4971.                     if (!$warehouse_id) {
  4972.                         $this->ERROR = "parseQuantity() - Склад не найден по Ид '" . $warehouse_guid . "'";
  4973.                         return false;
  4974.                     }
  4975.                 } else {
  4976.                     $warehouse_id = 0;
  4977.                 }
  4978.                 if ($quantity->Склад->Количество) {
  4979.                     $quantity = (float)$quantity->Склад->Количество;
  4980.                 }
  4981.                 $data_quantity[$warehouse_id] = $quantity;
  4982.             }
  4983.  
  4984.             // Если нет складов или общий остаток предложения
  4985.             if ($xml->Остаток->Количество) {
  4986.                 $data_quantity[0] = (float)$xml->Остаток->Количество;
  4987.             }
  4988.  
  4989.         } elseif ($xml->Склад) {
  4990.             foreach ($xml->Склад as $quantity) {
  4991.                 // есть секция со складами
  4992.                 $warehouse_guid = (string)$quantity['ИдСклада'];
  4993.                 if ($warehouse_guid) {
  4994.                     $warehouse_id = $this->getWarehouseByGuid($warehouse_guid);
  4995.                     if (!$warehouse_id) {
  4996.                         $this->ERROR = "parseQuantity() - Склад не найден по Ид '" . $warehouse_guid . "'";
  4997.                         return false;
  4998.                     }
  4999.                 } else {
  5000.                     $this->ERROR = "parseQuantity() - Не указан Ид склада!";
  5001.                     return false;
  5002.                 }
  5003.                 $quantity = (float)$quantity['КоличествоНаСкладе'];
  5004.                 $data_quantity[$warehouse_id] = $quantity;
  5005.             }
  5006.         }
  5007.         return $data_quantity;
  5008.  
  5009.     } // parseQuantity()
  5010.  
  5011.  
  5012.     /**
  5013.      * Возвращает массив данных валюты по id
  5014.      */
  5015.     private function getCurrency($currency_id) {
  5016.  
  5017.         $query = $this->query("SELECT * FROM `" . DB_PREFIX . "currency` WHERE `currency_id` = " . $currency_id);
  5018.         if ($query->num_rows) {
  5019.             return $query->row;
  5020.         }
  5021.         return array();
  5022.  
  5023.     } // getCurrency()
  5024.  
  5025.  
  5026.     /**
  5027.      * Возвращает id валюты по коду
  5028.      */
  5029.     private function getCurrencyId($code) {
  5030.  
  5031.         $query = $this->query("SELECT `currency_id` FROM `" . DB_PREFIX . "currency` WHERE `code` = '" . $this->db->escape($code) . "'");
  5032.         if ($query->num_rows) {
  5033.             $this->log("Валюта, currency_id = " . $query->row['currency_id'], 2);
  5034.             return $query->row['currency_id'];
  5035.         }
  5036.  
  5037.         // Попробуем поискать по символу справа
  5038.         $query = $this->query("SELECT `currency_id` FROM `" . DB_PREFIX . "currency` WHERE `symbol_right` = '" . $this->db->escape($code) . "'");
  5039.         if ($query->num_rows) {
  5040.             $this->log("Валюта, currency_id = " . $query->row['currency_id'], 2);
  5041.             return $query->row['currency_id'];
  5042.         }
  5043.  
  5044.         return 0;
  5045.  
  5046.     } // getCurrencyId()
  5047.  
  5048.  
  5049.     /**
  5050.      * Сохраняет настройки сразу в базу данных
  5051.      */
  5052.     private function configSet($key, $value, $store_id=0) {
  5053.  
  5054.         if (!$this->config->has('exchange1c_'.$key)) {
  5055.             $this->query("INSERT INTO `" . DB_PREFIX . "setting` SET `value` = '" . $value . "', `store_id` = " . $store_id . ", `code` = 'exchange1c', `key` = '" . $key . "'");
  5056.         }
  5057.  
  5058.     } // configSet()
  5059.  
  5060.  
  5061.     /**
  5062.      * Получает список групп покупателей
  5063.      */
  5064.     private function getCustomerGroups() {
  5065.  
  5066.         $query = $this->query("SELECT `customer_group_id` FROM `" . DB_PREFIX. "customer_group` ORDER BY `sort_order`");
  5067.         $data = array();
  5068.         foreach ($query->rows as $row) {
  5069.             $data[] = $row['customer_group_id'];
  5070.         }
  5071.         return $data;
  5072.  
  5073.     } // getCustomerGroups()
  5074.  
  5075.  
  5076.     /**
  5077.      * ver 2
  5078.      * update 2017-06-03
  5079.      * Загружает типы цен автоматически в таблицу которых там нет
  5080.      */
  5081.     private function autoLoadPriceType($xml) {
  5082.  
  5083.         if ($this->config->get('exchange1c_price_import_mode') == 'disable') {
  5084.             $this->log("autoLoadPriceType(): Загрузка типов цен отключена");
  5085.             return array();
  5086.         }
  5087.  
  5088.         $this->log("Автозагрузка цен из XML...", 2);
  5089.         $config_price_type = $this->config->get('exchange1c_price_type');
  5090.  
  5091.         if (empty($config_price_type)) {
  5092.             $config_price_type = array();
  5093.         }
  5094.  
  5095.         $update = false;
  5096.         $default_price = -1;
  5097.  
  5098.         // список групп покупателей
  5099.         $customer_groups = $this->getCustomerGroups();
  5100.  
  5101.         $index = 0;
  5102.         foreach ($xml->ТипЦены as $price_type)  {
  5103.             $name = trim((string)$price_type->Наименование);
  5104.             $delete = isset($price_type->ПометкаУдаления) ? $price_type->ПометкаУдаления : "false";
  5105.             $guid = (string)$price_type->Ид;
  5106.             $priority = 0;
  5107.             $found = -1;
  5108.             foreach ($config_price_type as $key => $cpt) {
  5109.                 if (!empty($cpt['id_cml']) && $cpt['id_cml'] == $guid) {
  5110.                     $this->log("autoLoadPriceType() - Найдена цена по Ид: '" . $guid . "'", 2);
  5111.                     $found = $key;
  5112.                     break;
  5113.                 }
  5114.                 if (strtolower(trim($cpt['keyword'])) == strtolower($name)) {
  5115.                     $this->log("autoLoadPriceType() - Найдена цена по наименованию: '" . $name . "'", 2);
  5116.                     $found = $key;
  5117.                     break;
  5118.                 }
  5119.                 $priority = max($priority, $cpt['priority']);
  5120.             }
  5121.  
  5122.             if ($found >= 0) {
  5123.                 // Если тип цены помечен на удаление, удалим ее из настроек
  5124.                 if ($delete == "true") {
  5125.                     $this->log("autoLoadPriceType() - Тип цены помечен на удаление, не будет загружен и будет удален из настроек");
  5126.                     unset($config_price_type[$found]);
  5127.                     $update = true;
  5128.                 } else {
  5129.                     // Обновим Ид
  5130.                     if ($config_price_type[$found]['guid'] != $guid) {
  5131.                         $config_price_type[$found]['guid'] = $guid;
  5132.                         $update = true;
  5133.                     }
  5134.                 }
  5135.  
  5136.             } else {
  5137.                 // Добавим цену в настройку если он ане помечена на удаление
  5138.                 if ($default_price == -1) {
  5139.                     $table_price = "product";
  5140.                     $default_price = count($config_price_type)+1;
  5141.                 } else {
  5142.                     $table_price = "discount";
  5143.                 }
  5144.                 $customer_group_id = isset($customer_groups[$index]) ? $customer_groups[$index] : $this->config->get('config_customer_group_id');
  5145.                 if ($delete == "false") {
  5146.                     $config_price_type[] = array(
  5147.                         'keyword'               => $name,
  5148.                         'guid'                  => $guid,
  5149.                         'table_price'           => $table_price,
  5150.                         'customer_group_id'     => $customer_group_id,
  5151.                         'quantity'              => 1,
  5152.                         'priority'              => $priority
  5153.                     );
  5154.                     $update = true;
  5155.  
  5156.                 }
  5157.             } // if
  5158.             $index++;
  5159.         } // foreach
  5160.  
  5161.         if ($update) {
  5162.             if ($this->config->get('exchange1c_price_type')) {
  5163.                 $this->query("UPDATE `". DB_PREFIX . "setting` SET `value` = '" . $this->db->escape(json_encode($config_price_type)) . "', `serialized` = 1 WHERE `key` = 'exchange1c_price_type'");
  5164.                 $this->log("autoLoadPriceType() - Цены обновлены в настройках", 2);
  5165.             } else {
  5166.                 $this->query("INSERT `". DB_PREFIX . "setting` SET `value` = '" . $this->db->escape(json_encode($config_price_type)) . "', `serialized` = 1, `code` = 'exchange1c', `key` = 'exchange1c_price_type'");
  5167.                 $this->log("autoLoadPriceType() - Цены добавлены в настройки", 2);
  5168.             }
  5169.         }
  5170.         return $config_price_type;
  5171.  
  5172.     } // autoLoadPriceType()
  5173.  
  5174.  
  5175.     /**
  5176.      * ver 4
  5177.      * update 2017-06-03
  5178.      * Загружает типы цен из классификатора
  5179.      * Обновляет Ид если найдена по наименованию
  5180.      * Сохраняет настройки типов цен
  5181.      */
  5182.     private function parseClassifierPriceType($xml) {
  5183.  
  5184.         // Автозагрузка цен
  5185.         if ($this->config->get('exchange1c_price_types_auto_load') == 1) {
  5186.             $config_price_type = $this->autoLoadPriceType($xml);
  5187.         } else {
  5188.             $config_price_type = $this->config->get('exchange1c_price_type');
  5189.         }
  5190.  
  5191.         $data = array();
  5192.  
  5193.         if (empty($config_price_type)) {
  5194.             $this->ERROR = "parseClassifierPriceType() - В настройках модуля не указаны цены";
  5195.             return false;
  5196.         }
  5197.  
  5198.         // Перебираем все цены из CML
  5199.         foreach ($xml->ТипЦены as $price_type)  {
  5200.             $currency       = isset($price_type->Валюта) ? (string)$price_type->Валюта : "RUB";
  5201.             $guid           = (string)$price_type->Ид;
  5202.             $name           = trim((string)$price_type->Наименование);
  5203.             $code           = $price_type->Код ? $price_type->Код : ($price_type->Валюта ? $price_type->Валюта : '');
  5204.  
  5205.             // Найденный индекс цены в настройках
  5206.             $found = -1;
  5207.  
  5208.             // Перебираем все цены из настроек модуля
  5209.             foreach ($config_price_type as $index => $config_type) {
  5210.  
  5211.                 if ($found >= 0)
  5212.                     break;
  5213.  
  5214.                 if (!empty($config_type['guid']) && $config_type['guid'] == $guid) {
  5215.                     $found = $index;
  5216.                     break;
  5217.                 } elseif (strtolower($name) == strtolower($config_type['keyword'])) {
  5218.                     $found = $index;
  5219.                     break;
  5220.                 }
  5221.  
  5222.             } // foreach ($config_price_type as $config_type)
  5223.  
  5224.             if ($found >= 0) {
  5225.                 if ($code) {
  5226.                     $currency_id                = $this->getCurrencyId($code);
  5227.                 } else {
  5228.                     $currency_id                = $this->getCurrencyId($currency);
  5229.                 }
  5230.                 $data[$guid]                    = $config_type;
  5231.                 $data[$guid]['currency']        = $currency;
  5232.                 $data[$guid]['currency_id']     = $currency_id;
  5233.                 if ($currency_id) {
  5234.                     $currency_data = $this->getCurrency($currency_id);
  5235.                     $rate = $currency_data['value'];
  5236.                     $decimal_place = $currency_data['decimal_place'];
  5237.                 } else {
  5238.                     $rate = 1;
  5239.                     $decimal_place = 2;
  5240.                 }
  5241.                 $data[$guid]['rate']            = $rate;
  5242.                 $data[$guid]['decimal_place'] = $decimal_place;
  5243.                 $this->log('Вид цены: ' . $name,2);
  5244.             } else {
  5245.                 $this->ERROR = "parseClassifierPriceType() - Цена '" . $name . "' не найдена в настройках модуля, Ид = '" . $guid . "'";
  5246.                 return false;
  5247.             }
  5248.  
  5249.         } // foreach ($xml->ТипЦены as $price_type)
  5250.         return $data;
  5251.  
  5252.     } // parseClassifierPriceType()
  5253.  
  5254.  
  5255.     /**
  5256.      * ver 4
  5257.      * update 2017-04-18
  5258.      * Устанавливает цену скидки или акции товара
  5259.      */
  5260.     private function setProductPrice($price_data, $product_id, $new = false) {
  5261.  
  5262.         $price_id = 0;
  5263.         if ($price_data['table_price'] == 'discount') {
  5264.             if (!$new) {
  5265.                 $query = $this->query("SELECT `product_discount_id`,`customer_group_id`,`price`,`quantity`,`priority` FROM `" . DB_PREFIX . "product_discount` WHERE `product_id` = " . $product_id . " AND `customer_group_id` = " . $price_data['customer_group_id'] . " AND `quantity` = " . $price_data['quantity']);
  5266.                 if ($query->num_rows) {
  5267.                     $price_id = $query->row['product_discount_id'];
  5268.                     $update_fields = $this->compareArrays($query, $price_data);
  5269.                     // Если есть расхождения, производим обновление
  5270.                     if ($update_fields) {
  5271.                         $this->query("UPDATE `" . DB_PREFIX . "product_discount` SET " . $update_fields . " WHERE `product_discount_id` = " . $price_id);
  5272.                         $this->log("> Cкидка обновлена: " . $price_data['price'], 2);
  5273.                     }
  5274.                 }
  5275.             }
  5276.             if (!$price_id) {
  5277.                 $this->query("INSERT INTO `" . DB_PREFIX . "product_discount` SET `product_id` = " . $product_id . ", `quantity` = " . $price_data['quantity'] . ", `priority` = " . $price_data['priority'] . ", `customer_group_id` = " . $price_data['customer_group_id'] . ", `price` = '" . (float)$price_data['price'] . "'");
  5278.                 $price_id = $this->db->getLastId();
  5279.                 $this->log("> Cкидка добавлена: " . $price_data['price'], 2);
  5280.             }
  5281.  
  5282.  
  5283.         } elseif ($price_data['table_price'] == 'special') {
  5284.             if (!$new) {
  5285.                 $query = $this->query("SELECT `product_special_id`,`customer_group_id`,`price` FROM `" . DB_PREFIX . "product_special` WHERE `product_id` = " . $product_id . " AND `customer_group_id` = " . $price_data['customer_group_id']);
  5286.                 if ($query->num_rows) {
  5287.                     $price_id = $query->row['product_special_id'];
  5288.                     $update_fields = $this->compareArrays($query, $price_data);
  5289.                     // Если есть расхождения, производим обновление
  5290.                     if ($update_fields) {
  5291.                         $this->query("UPDATE `" . DB_PREFIX . "product_special` SET " . $update_fields . " WHERE `product_special_id` = " . $price_id);
  5292.                         $this->log("> Акция обновлена: " . $price_data['price'], 2);
  5293.                     }
  5294.                 }
  5295.             }
  5296.             if (!$price_id) {
  5297.                 $this->query("INSERT INTO `" . DB_PREFIX . "product_special` SET `product_id` = " . $product_id . ", `priority` = " . $price_data['priority'] . ", `customer_group_id` = " . $price_data['customer_group_id'] . ", `price` = '" . (float)$price_data['price'] . "'");
  5298.                 $update_fields = $this->db->getLastId();
  5299.                 $this->log("> Акция добавлена: " . $price_data['price'], 2);
  5300.             }
  5301.  
  5302.         }
  5303.         return $price_id;
  5304.  
  5305.     } // setProductPrice()
  5306.  
  5307.  
  5308.     /**
  5309.      * ver 8
  5310.      * update 2017-05-07
  5311.      * Устанавливает цены товара
  5312.      */
  5313.     private function setProductPrices($prices_data, $product_id, $product_feature_id = 0, $new = false) {
  5314.  
  5315.         $price = 0;
  5316.  
  5317.         if (!$new) {
  5318.             $old_discount = array();
  5319.             if ($this->FULL_IMPORT && !$product_feature_id) {
  5320.                 if ($this->config->get('exchange1c_clean_prices_full_import') == 1) {
  5321.                     // При полной выгрузке удаляем все старые скидки товара
  5322.                     $this->query("DELETE FROM `" . DB_PREFIX . "product_discount` WHERE `product_id` = " . $product_id);
  5323.                 }
  5324.             } else {
  5325.                 // Читаем старые скидки товара
  5326.                 $query = $this->query("SELECT `product_discount_id` FROM `" . DB_PREFIX . "product_discount` WHERE `product_id` = " . $product_id);
  5327.                 foreach ($query->rows as $row) {
  5328.                     $old_discount[] = $row['product_discount_id'];
  5329.                 }
  5330.             }
  5331.             $old_special = array();
  5332.             if ($this->FULL_IMPORT && !$product_feature_id) {
  5333.                 if ($this->config->get('exchange1c_clean_prices_full_import') == 1) {
  5334.                     // При полной выгрузке удаляем все старые скидки товара
  5335.                     $this->query("DELETE FROM `" . DB_PREFIX . "product_special` WHERE `product_id` = " . $product_id);
  5336.                 }
  5337.             } else {
  5338.                 // Читаем старые акции товара
  5339.                 $query = $this->query("SELECT `product_special_id` FROM `" . DB_PREFIX . "product_special` WHERE `product_id` = " . $product_id);
  5340.                 foreach ($query->rows as $row) {
  5341.                     $old_special[] = $row['product_special_id'];
  5342.                 }
  5343.             }
  5344.         }
  5345.  
  5346.         foreach ($prices_data as $price_data) {
  5347.  
  5348.             if ($price_data['table_price'] == 'product') {
  5349.  
  5350.                 $price = $price_data['price'];
  5351.                 $this->log("> Цена для записи в товар: " . $price . " для одной базовой единицы товара", 2);
  5352.  
  5353.             } else {
  5354.                 // Если есть характеристики, то скидки и акции не пишем
  5355.                 if ($product_feature_id) {
  5356.                     continue;
  5357.                 }
  5358.                 // устанавливает цену скидки или акции в зависимости от настроек
  5359.                 $price_id = $this->setProductPrice($price_data, $product_id, $new);
  5360.                 if ($price_id) {
  5361.                     if ($price_data['table_price'] == 'discount') {
  5362.                         $key = array_search($price_id, $old_discount);
  5363.                         if ($key !== false) {
  5364.                             unset($old_discount[$key]);
  5365.                         }
  5366.                     } elseif ($price_data['table_price'] == 'discount') {
  5367.                         $key = array_search($price_id, $old_special);
  5368.                         if ($key !== false) {
  5369.                             unset($old_special[$key]);
  5370.                         }
  5371.                     }
  5372.                 }
  5373.             }
  5374.         }
  5375.  
  5376.         if (!$new) {
  5377.             if (count($old_discount)) {
  5378.                 $this->query("DELETE FROM `" . DB_PREFIX . "product_discount` WHERE `product_id` = " . $product_id . " AND `product_discount_id` IN (" . implode(",",$old_discount) . ")");
  5379.             }
  5380.             if (count($old_special)) {
  5381.                 $this->query("DELETE FROM `" . DB_PREFIX . "product_special` WHERE `product_id` = " . $product_id . " AND `product_special_id` IN (" . implode(",",$old_special) . ")");
  5382.             }
  5383.         }
  5384.         return $price;
  5385.  
  5386.     } // setProductPrices()
  5387.  
  5388.  
  5389.     /**
  5390.      * ver 9
  5391.      * update 2017-06-19
  5392.      * Устанавливает цены характеристик товара базовой единицы товара
  5393.      * поле action имеет значение:
  5394.      * 0 - без акции и без скидки
  5395.      * 1 - акция (special)
  5396.      * 2 - скидка (discount)
  5397.      */
  5398.     private function setProductFeaturePrices($prices_data, $product_id, $product_feature_id = 0, $new = false) {
  5399.  
  5400.         $old_prices = array();
  5401.         if (!$new) {
  5402.             // Читаем старые цены этой характеристики
  5403.             $query = $this->query("SELECT `product_price_id`,`price`,`customer_group_id`,`action`,`unit_id` FROM `" . DB_PREFIX . "product_price` WHERE `product_feature_id` = " . $product_feature_id . " AND `product_id` = " . $product_id);
  5404.             foreach ($query->rows as $row) {
  5405.  
  5406.                 $old_prices[$row['product_price_id']] = array(
  5407.                     'price'             => $row['price'],
  5408.                     'customer_group_id' => $row['customer_group_id'],
  5409.                     'action'            => $row['action'],
  5410.                     'unit_id'           => $row['unit_id'],
  5411.                 );
  5412.             }
  5413.         }
  5414.  
  5415.         // пробежимся по ценам
  5416.         foreach ($prices_data as $price_guid => $price_data) {
  5417.  
  5418.             if ($price_data['quantity'] != 1) {
  5419.                 continue;
  5420.             }
  5421.  
  5422.             // Если единица у товара не существует в классификаторе, то $unit_id будет 0
  5423.             $unit_id = isset($price_data['unit']['unit_id']) ? $price_data['unit']['unit_id'] : 0;
  5424.  
  5425.             // Тогда $unit_id получаем при записи единицы в товар
  5426.             $result = $this->setProductUnit($price_data['unit'], $product_id, $product_feature_id);
  5427.             if ($result['unit_id']) {
  5428.                 $unit_id = $result['unit_id'];
  5429.             }
  5430.             $this->log($price_data, 2);
  5431.  
  5432.             if ($price_data['table_price'] == 'product') {
  5433.                 $action = 0;
  5434.             } elseif ($price_data['table_price'] == 'special') {
  5435.                 $action = 1;
  5436.             } elseif ($price_data['table_price'] == 'discount') {
  5437.                 $action = 2;
  5438.             }
  5439.  
  5440.             $product_price_id = 0;
  5441.             if (!$new) {
  5442.                 foreach ($old_prices as $product_price_id => $old_price) {
  5443.                     if ($old_price['customer_group_id'] == $price_data['customer_group_id'] && $action == $old_price['action']) {
  5444.                         $sql = array();
  5445.  
  5446.                         // Отличается цена
  5447.                         if ($old_price['price'] != $price_data['price']) {
  5448.                             $sql[] = "`price` = '" . $price_data['price'] . "'";
  5449.                         }
  5450.  
  5451.                         // Отличается единица
  5452.                         if ($old_price['unit_id'] != $unit_id) {
  5453.                             $sql[] = "`unit_id` = " . $unit_id;
  5454.                         }
  5455.  
  5456.                         // Если есть изменения
  5457.                         if ($sql) {
  5458.                             $sql_str = implode(", ",  $sql);
  5459.                             $this->query("UPDATE `" . DB_PREFIX . "product_price` SET " . $sql_str . " WHERE `product_price_id` = " . $product_price_id);
  5460.                             $this->log("> Цена характеристики обновлена: " . $price_data['price']);
  5461.                         }
  5462.                         break;
  5463.                     }
  5464.                     $product_price_id = 0;
  5465.                 }
  5466.  
  5467.                 if ($product_price_id) {
  5468.                     unset($old_prices[$product_price_id]);
  5469.                 }
  5470.             }
  5471.             if (!$product_price_id) {
  5472.                 $query = $this->query("INSERT INTO `" . DB_PREFIX . "product_price` SET `product_id` = " . $product_id . ", `product_feature_id` = " . $product_feature_id . ", `customer_group_id` = " . $price_data['customer_group_id'] . ", `action` = " . $action . ", `price` = '" . (float)$price_data['price'] . "', `unit_id` = " . $unit_id);
  5473.                 $product_price_id = $this->db->getLastId();
  5474.             }
  5475.         }
  5476.  
  5477.         if (!$new) {
  5478.             // Удаляем отсутствующие цены этой характеристики
  5479.             if (count($old_prices)) {
  5480.                 $fields = array();
  5481.                 foreach ($old_prices as $product_price_id => $price_data) {
  5482.                     $fields[] = $product_price_id;
  5483.                 }
  5484.                 $this->query("DELETE FROM `" . DB_PREFIX . "product_price` WHERE `product_price_id` IN (" . implode(",",$fields) . ")");
  5485.             }
  5486.         }
  5487.         return true;
  5488.  
  5489.     } // setProductFeaturePrices()
  5490.  
  5491.  
  5492.     /**
  5493.      * ver 2
  5494.      * update 2017-06-13
  5495.      * Получает по коду его id
  5496.      */
  5497.     private function getUnitId($name) {
  5498.  
  5499.         $query = $this->query("SELECT `number_code` FROM `" . DB_PREFIX . "unit` WHERE `rus_name1` = '" . $this->db->escape($name) . "'");
  5500.         if ($query->num_rows) {
  5501.             return (int)$query->row['number_code'];
  5502.         }
  5503.         return 0;
  5504.  
  5505.     } // getUnitId()
  5506.  
  5507.  
  5508.     /**
  5509.      * ver 2
  5510.      * update 2017-06-20
  5511.      * Получает данные единицы по наиминованию
  5512.      */
  5513.     private function getUnitByName($name) {
  5514.  
  5515.         $query = $this->query("SELECT * FROM `" . DB_PREFIX . "unit_to_1c` WHERE `name` = '" . $this->db->escape($name) . "'");
  5516.         if ($query->num_rows) {
  5517.             return $query->row;
  5518.         }
  5519.         return false;
  5520.  
  5521.     } // getUnitByName()
  5522.  
  5523.  
  5524.     /**
  5525.      * ver 3
  5526.      * update 2017-06-20
  5527.      * Загружает все цены только в одной валюте
  5528.      */
  5529.     private function parsePrice($xml, $data) {
  5530.  
  5531.         if (!$xml) {
  5532.             $this->ERROR = "XML не содержит данных";
  5533.             return false;
  5534.         }
  5535.  
  5536.         // Читаем типы цен из настроек
  5537.         $price_types = $this->config->get('exchange1c_price_type');
  5538.         if (!$price_types) {
  5539.             $this->ERROR = "Настройки цен пустые, настройте типы цен и повторите загрузку!";
  5540.             return false;
  5541.         }
  5542.  
  5543.         // Массив хранения цен
  5544.         $data_prices = array();
  5545.  
  5546.         // Читем цены в том порядке в каком заданы в настройках
  5547.         foreach ($price_types as $config_price_type) {
  5548.  
  5549.             foreach ($xml->Цена as $price_data) {
  5550.                 $guid       = (string)$price_data->ИдТипаЦены;
  5551.  
  5552.                 // Цена
  5553.                 $price  = $price_data->ЦенаЗаЕдиницу ? (float)$price_data->ЦенаЗаЕдиницу : 0;
  5554.  
  5555.                 if ($config_price_type['guid'] != $guid) {
  5556.                     continue;
  5557.                 }
  5558.  
  5559.                 // Курс валюты
  5560.                 //$rate = $price_data->Валюта ? $this->getCurrencyValue((string)$price_data->Валюта) : 1;
  5561.                 // Валюта
  5562.                 // автоматическая конвертация в основную валюту CMS
  5563.                 //if ($this->config->get('exchange1c_currency_convert') == 1) {
  5564.                 //  if ($rate != 1 && $rate > 0) {
  5565.                 //      $price = round((float)$price_data->ЦенаЗаЕдиницу / (float)$rate, $decimal_place);
  5566.                 //  }
  5567.                 //}
  5568.                 //$data_prices[$guid]['rate'] = $rate;
  5569.  
  5570.                 if ($this->config->get('exchange1c_ignore_price_zero') == 1 && $price == 0) {
  5571.                     $this->log("Включена опция при нулевой цене не менять старую");
  5572.                     continue;
  5573.                 }
  5574.  
  5575.                 // Единица измерения цены
  5576.                 $unit_data = array(
  5577.                     'name'      => $price_data->Единица ? (string)$price_data->Единица : 'шт',
  5578.                     'ratio'     => $price_data->Коэффициент ? (float)$price_data->Коэффициент : 1
  5579.                 );
  5580.                 $unit_split = $this->splitNameStr($unit_data['name']);
  5581.  
  5582.                 // Получим единицу из классификатора
  5583.                 //$unit = $this->getUnitByName($unit_split['name']);
  5584.                 $unit = $this->getUnitByName($unit_data['name']);
  5585.                 $this->log($unit, 2);
  5586.                 if ($unit != false) {
  5587.                     if ($unit['number_code']) {
  5588.                         $unit_data['number_code']   = $unit['number_code'] ;
  5589.                     }
  5590.                     if ($unit['guid']) {
  5591.                         $unit_data['guid']  = $unit['guid'] ;
  5592.                     }
  5593.                     $unit_data['name']          = $unit['name'];
  5594.                     $unit_data['full_name1']    = $unit['full_name'];
  5595.                     $unit_data['unit_id']       = $unit['unit_id'];
  5596.                 }
  5597.  
  5598.                 // Копируем данные с настроек
  5599.                 $data_prices[$guid]             = $config_price_type;
  5600.                 $data_prices[$guid]['unit']     = $unit_data;
  5601.                 $data_prices[$guid]['price']    = $price;
  5602.                 $this->log("> Цена: " . $price . " за единицу: " . $unit_data['name'] . ", GUID: " . $guid, 2);
  5603.  
  5604.  
  5605.             } // foreach ($xml->Цена as $price_data)
  5606.         } // foreach ($price_types as $config_price_type)
  5607.  
  5608.         $this->log($data_prices, 2);
  5609.         return $data_prices;
  5610.  
  5611.     } // parsePrices()
  5612.  
  5613.  
  5614.     /**
  5615.      * ====================================== ХАРАКТЕРИСТИКИ ======================================
  5616.      */
  5617.  
  5618.  
  5619.     /**
  5620.      * Добавляет опциию по названию
  5621.      */
  5622.     private function addOption($name, $type='select') {
  5623.  
  5624.         $this->query("INSERT INTO `" . DB_PREFIX . "option` SET `type` = '" . $this->db->escape($type) . "'");
  5625.         $option_id = $this->db->getLastId();
  5626.         $this->query("INSERT INTO `" . DB_PREFIX . "option_description` SET `option_id` = '" . $option_id . "', `language_id` = " . $this->LANG_ID . ", `name` = '" . $this->db->escape($name) . "'");
  5627.  
  5628.         $this->log("Опция добавлена: '" . $name. "'", 2);
  5629.         return $option_id;
  5630.  
  5631.     } // addOption()
  5632.  
  5633.  
  5634.     /**
  5635.      * Получение наименования производителя по manufacturer_id
  5636.      */
  5637.     private function getManufacturerName($manufacturer_id, &$error) {
  5638.  
  5639.         if (!$manufacturer_id) {
  5640.             $error = "Не указан manufacturer_id";
  5641.             return "";
  5642.         }
  5643.         $query = $this->query("SELECT `name` FROM `" . DB_PREFIX . "manufacturer` WHERE `manufacturer_id` = " . $manufacturer_id);
  5644.         $name = isset($query->row['name']) ? $query->row['name'] : "";
  5645.         $this->log("Производитель: '" . $name . "' по id: " . $manufacturer_id, 2);
  5646.         return $name;
  5647.  
  5648.     } // getManufacturerName()
  5649.  
  5650.  
  5651.     /**
  5652.      * Получение product_id по GUID
  5653.      */
  5654.     private function getProductIdByGuid($product_guid) {
  5655.  
  5656.         // Определим product_id
  5657.         $query = $this->query("SELECT `product_id` FROM `" . DB_PREFIX . "product_to_1c` WHERE `guid` = '" . $this->db->escape($product_guid) . "'");
  5658.         $product_id = isset($query->row['product_id']) ? $query->row['product_id'] : 0;
  5659.         // Проверим существование такого товара
  5660.         if ($product_id) {
  5661.             $query = $this->query("SELECT `product_id` FROM `" . DB_PREFIX . "product` WHERE `product_id` = " . (int)$product_id);
  5662.             if (!$query->num_rows) {
  5663.                 // Удалим неправильную связь
  5664.                 $this->query("DELETE FROM `" . DB_PREFIX . "product_to_1c` WHERE `product_id` = " . (int)$product_id);
  5665.                 $product_id = 0;
  5666.             }
  5667.         }
  5668.         if ($product_id) {
  5669.             $this->log("Найден товар по GUID, product_id = " . $product_id);
  5670.         } else {
  5671.             $this->log("Не найден товар по GUID " . $product_guid, 2);
  5672.         }
  5673.         return $product_id;
  5674.  
  5675.     } // getProductIdByGuid()
  5676.  
  5677.  
  5678.     /**
  5679.      * Проверка существования товара по product_id
  5680.      */
  5681.     private function getProductIdByCode($code) {
  5682.  
  5683.         // Определим product_id
  5684.         $query = $this->query("SELECT `product_id` FROM `" . DB_PREFIX . "product` WHERE `product_id` = " . (int)$code);
  5685.         $product_id = isset($query->row['product_id']) ? $query->row['product_id'] : 0;
  5686.  
  5687.         if ($product_id) {
  5688.             $this->log("Найден товар по <Код>, product_id = " . $product_id, 2);
  5689.         } else {
  5690.             $this->log("Не найден товар по <Код> " . $code, 2);
  5691.         }
  5692.  
  5693.         return $product_id;
  5694.  
  5695.     } // getProductIdByCode()
  5696.  
  5697.  
  5698.     /**
  5699.      * Разбивает название по шаблону "[order].[name] [option]"
  5700.      */
  5701.     private function splitNameStr($str, $opt_yes = true) {
  5702.  
  5703.         $str = trim(str_replace(array("\r","\n"),'',$str));
  5704.         $length = mb_strlen($str);
  5705.         $data = array(
  5706.             'order'     => "",
  5707.             'name'      => "",
  5708.             'option'    => ""
  5709.         );
  5710.  
  5711.         $pos_name_start = 0;
  5712.         $pos_opt_end = 0;
  5713.         $pos_opt_start = $length;
  5714.  
  5715.         if ($opt_yes) {
  5716.             // Поищем опцию
  5717.             $level = 0;
  5718.             for ($i = $length; $i > 0; $i--) {
  5719.                 $char = mb_substr($str,$i,1);
  5720.                 if ($char == ")") {
  5721.                     $level++;
  5722.                     if (!$pos_opt_end)
  5723.                         $pos_opt_end = $i;
  5724.                 }
  5725.                 if ($char == "(") {
  5726.                     $level--;
  5727.                     if ($level == 0) {
  5728.                         $pos_opt_start = $i+1;
  5729.                         $data['option'] = mb_substr($str, $pos_opt_start, $pos_opt_end-$pos_opt_start);
  5730.                         $pos_opt_start -= 2;
  5731.                         break;
  5732.                     }
  5733.                 }
  5734.             }
  5735.         }
  5736.  
  5737.         // Поищем порядок сортировки, order (обязательно после цифры должна идти точка а после нее пробел!)
  5738.         $pos_order_end = 0;
  5739.         for ($i = 0; $i < $length; $i++) {
  5740.             if (is_numeric(mb_substr($str,$i,1))) {
  5741.                 $pos_order_end++;
  5742.                 if ($i+1 <= $length && mb_substr($str, $i+1, 1) == ".") {
  5743.                     $data['order'] = (int)mb_substr($str, 0, $pos_order_end);
  5744.                     $pos_name_start = $i+2;
  5745.                 }
  5746.             } else {
  5747.                 // Если первая не цифра, дальше не ищем
  5748.                 break;
  5749.             }
  5750.         }
  5751.  
  5752.         // Наименование
  5753.         $data['name'] = trim(mb_substr($str, $pos_name_start, $pos_opt_start-$pos_name_start));
  5754.         return $data;
  5755.  
  5756.     } // splitNameStr()
  5757.  
  5758.  
  5759.     /**
  5760.      * ver 1
  5761.      * update 2017-06-12
  5762.      * Возвращает строку содержащую только цифры
  5763.      */
  5764.     private function getStringOnlyDigit($str) {
  5765.  
  5766.         $result = '';
  5767.  
  5768.         // Длина строки
  5769.         $length = mb_strlen($str);
  5770.  
  5771.         // Перебираем каждый символ
  5772.         for ($i = 0; $i <= $length; $i++) {
  5773.             if (is_numeric(mb_substr($str, $i, 1))) {
  5774.                 $result .= mb_substr($str, $i, 1);
  5775.             }
  5776.         }
  5777.  
  5778.         return $result;
  5779.  
  5780.     } // getStringOnlyDigit()
  5781.  
  5782.  
  5783.     /**
  5784.      * ver 1
  5785.      * update 2017-06-12
  5786.      * Формирует путь к товару из названий категорий через разделитель
  5787.      */
  5788.     private function getProductPath($product_id, $split = '/') {
  5789.  
  5790.         // Получим одну первую категорию
  5791.         $product_categories = $this->getProductCategories($product_id, 1);
  5792.  
  5793.         // Найдем родительские категории
  5794.         $parent_categories = $this->fillParentsCategories($product_categories);
  5795.  
  5796.         // добавляем к основной родительские
  5797.         $product_categories = array_merge($parent_categories, $parent_categories);
  5798.  
  5799.         // Убираем повторяющиеся
  5800.         $product_categories = array_unique($product_categories);
  5801.  
  5802.         $path = array();
  5803.         // Получим наименования категорий
  5804.         foreach ($product_categories as $category_id) {
  5805.             $query = $this->query("SELECT `name` FROM `" . DB_PREFIX . "category_description` WHERE `category_id` = " . $category_id . " AND `language_id` = " . $this->LANG_ID);
  5806.             if ($query->num_rows) {
  5807.                 array_unshift($path, $this->translit($query->row['name'], '_'));
  5808.             }
  5809.         }
  5810.  
  5811.         return implode($split, $path);
  5812.  
  5813.     } // getProductPath()
  5814.  
  5815.  
  5816.     /**
  5817.      * ver 1
  5818.      * update 2017-06-12
  5819.      * Формирует путь с наименованием картинки к опции
  5820.      */
  5821.     private function setProductOptionImage($data, $name, $value) {
  5822.  
  5823.         // Картинка опции
  5824.         $option_image   = '';
  5825.  
  5826.         // Путь к картинки в дополнительном каталоге
  5827.         if ($this->config->get('exchange1c_product_options_image_folder')) {
  5828.             $option_image .= $this->config->get('exchange1c_product_options_image_folder') . '/';
  5829.         }
  5830.  
  5831.         // Путь к картинке из пути товара до основной категории
  5832.         if ($this->config->get('exchange1c_product_options_image_use_path_product') == 1) {
  5833.             $product_categories = $this->getProductPath($data['product_id']);
  5834.             $option_image .= $product_categories . '/';
  5835.         }
  5836.  
  5837.         // Название товара в транслите
  5838.         $query = $this->query("SELECT `name` FROM `" . DB_PREFIX . "product_description` WHERE `product_id` = " . $data['product_id'] . " AND `language_id` = " . $this->LANG_ID);
  5839.         if ($query->num_rows) {
  5840.             $option_image .= $this->translit($query->row['name'], '_') . '/';
  5841.         }
  5842.  
  5843.         // Префикс названия файла
  5844.         if ($this->config->get('exchange1c_product_options_image_prefix')) {
  5845.             $option_image .=  $this->config->get('exchange1c_product_options_image_prefix');
  5846.         }
  5847.  
  5848.         // Название файла
  5849.         if ($value) {
  5850.  
  5851.             $filename = $value;
  5852.             // Убираем все кроме цифр
  5853.             if ($this->config->get('exchange1c_product_options_image_only_digit')) {
  5854.                 $filename = $this->getStringOnlyDigit($filename);
  5855.             }
  5856.  
  5857.             // Переводим в транслит
  5858.             $filename = $this->translit($filename, '_');
  5859.  
  5860.             // Добавляем к полному пути
  5861.             $option_image .= $filename . '.';
  5862.         }
  5863.  
  5864.         // Расширение файла
  5865.         $ext = 'jpg';
  5866.         if ($this->config->get('exchange1c_product_options_image_ext')) {
  5867.             $ext = $this->config->get('exchange1c_product_options_image_ext');
  5868.         }
  5869.         $option_image .= $ext;
  5870.  
  5871.         // Проверим существование файла
  5872.         if (file_exists(DIR_IMAGE . $option_image)) {
  5873.             return $option_image;
  5874.         }
  5875.  
  5876.         return 'no_image.png';
  5877.  
  5878.     } // setProductOptionImage()
  5879.  
  5880.  
  5881.     /**
  5882.      * ver 7
  5883.      * update 2017-06-12
  5884.      * Разбор характеристики из файла
  5885.      * Читает характеристики из файла(offers.xml или import.xml)
  5886.      * Возвращает массив с элементами [features],[quantity],[price],[error]
  5887.      * если в характеристиках нет остатков и цен, тогда не будет елементов [quantity],[price]
  5888.      */
  5889.     private function parseFeatures($xml, $data) {
  5890.  
  5891.         // массив с данными
  5892.         $features   = array();
  5893.  
  5894.         if (!$xml) {
  5895.             $this->ERROR = "parseFeatures(): в XML нет данных";
  5896.             return false;
  5897.         }
  5898.  
  5899.         if ($xml->ХарактеристикаТовара) {
  5900.  
  5901.             // Остаток характеристики, который будет записываться в опции
  5902.             // Если опций несколько, остаток у них будет одинаковый, так как они будут связанные
  5903.             $quantity = 0;
  5904.  
  5905.             // Остаток без складов или общий
  5906.             if (isset($data['quantity'])) {
  5907.                 $quantity = 0;
  5908.             };
  5909.  
  5910.             // остаток характеристики (при наличии складов по всем складам)
  5911.             if (isset($data['quantities'])) {
  5912.                 $quantity = array_sum($data['quantities']);
  5913.             }
  5914.  
  5915.             // Когда не указан Ид характеристики, значит несколько характеристик
  5916.             // Обычно так указываются в XML 2.07 в файле import_*.xml
  5917.             if (!$data['feature_guid']) {
  5918.  
  5919.                 // ХАРАКТЕРИСТИКИ В СЕКЦИИ <ТОВАР>
  5920.                 $feature_name_obj = array();
  5921.                 $feature_name = "Характеристика";
  5922.  
  5923.                 // Название характеристики нет
  5924.                 foreach ($xml->ХарактеристикаТовара as $product_feature) {
  5925.                     $feature_guid       = (string)$product_feature->Ид;
  5926.                     $option_value       = (string)$product_feature->Значение;
  5927.                     $feature_name_obj[] = $option_value;
  5928.                     $this->log("> прочитана характеристика, Ид: '" . $feature_guid . "', значение: '" . $option_value . "'");
  5929.  
  5930.                     $option_type = $this->config->get('exchange1c_product_options_type') ? $this->config->get('exchange1c_product_options_type') : 'select';
  5931.  
  5932.                     // Ищем опцию и значение опции
  5933.                     $option_id          = $this->setOption("Характеристика", $option_type);
  5934.                     $option_value_id    = $this->setOptionValue($option_id, $option_value);
  5935.  
  5936.                     $options = array();
  5937.                     $options[$option_value_id] = array(
  5938.                         'option_id'         => $option_id,
  5939.                         'subtract'          => $this->config->get('exchange1c_product_options_subtract') == 1 ? 1 : 0,
  5940.                         'quantity'          => 0
  5941.                     );
  5942.                     $features[$feature_guid] = array(
  5943.                         'name'          => $feature_name,
  5944.                         'options'       => $options
  5945.                     );
  5946.                 }
  5947.  
  5948.             } elseif ($this->config->get('exchange1c_product_options_mode') == 'feature') {
  5949.  
  5950.                 // РЕЖИМ "ХАРАКТЕРИСТИКА"
  5951.                 $option_value_obj = array();
  5952.  
  5953.                 foreach ($xml->ХарактеристикаТовара as $feature_option) {
  5954.                     // разбиваем название опции
  5955.                     $option_name_split = $this->splitNameStr(htmlspecialchars(trim((string)$feature_option->Наименование)));
  5956.                     $option_value_split = $this->splitNameStr(htmlspecialchars(trim((string)$feature_option->Значение)));
  5957.                     $option_value_obj[] = $option_value_split['name'];
  5958.                 }
  5959.  
  5960.                 $option_name = $this->config->get('exchange1c_product_feature_name');
  5961.                 if (!$option_name) {
  5962.                     $option_name = 'Варианты';
  5963.                 }
  5964.  
  5965.                 $option_type = $this->config->get('exchange1c_product_options_type') ? $this->config->get('exchange1c_product_options_type') : 'select';
  5966.  
  5967.                 if ($option_type == 'image') {
  5968.                     // Если включена тип опции - изображение
  5969.                     $this->log($data);
  5970.                     //$image = $this->setProductOptionImage();
  5971.                     //$this->log($image);
  5972.                 }
  5973.  
  5974.                 $option_value = implode(", ", $option_value_obj);
  5975.  
  5976.                 $option_id          = $this->setOption($option_name, $option_type);
  5977.                 $option_value_id    = $this->setOptionValue($option_id, $option_value);
  5978.  
  5979.                 $options[$option_value_id]  = array(
  5980.                     'option_id'         => $option_id,
  5981.                     'subtract'          => $this->config->get('exchange1c_product_options_subtract') == 1 ? 1 : 0,
  5982.                     'quantity'          => $quantity
  5983.                 );
  5984.  
  5985.                 $features[$data['feature_guid']]['options'] = $options;
  5986.                 $features[$data['feature_guid']]['name'] = $option_value;
  5987.                 $this->log("Опция: '" . $option_name . "' = '" . $option_value . "'");
  5988.  
  5989.             } elseif ($this->config->get('exchange1c_product_options_mode') == 'certine') {
  5990.  
  5991.                 // Отдельные товары
  5992.                 // НЕ РЕАЛИЗОВАННО
  5993.                 $this->log("parseFeatures(): Режим характеристики как отдельный товар пока не реализован", 2);
  5994.  
  5995.             } elseif ($this->config->get('exchange1c_product_options_mode') == 'related') {
  5996.  
  5997.                 // РЕЖИМ - СВЯЗАННЫЕ ОПЦИИ
  5998.  
  5999.                 foreach ($xml->ХарактеристикаТовара as $feature_option) {
  6000.  
  6001.                     // ЗНАЧЕНИЕ ОПЦИИ
  6002.                     $value_obj = $this->splitNameStr((string)$feature_option->Значение);
  6003.                     $image  = '';
  6004.  
  6005.                     // ОПЦИЯ
  6006.                     $option_obj = $this->splitNameStr((string)$feature_option->Наименование);
  6007.  
  6008.                     // Тип опции установленный из настроек
  6009.                     $option_type = $this->config->get('exchange1c_product_options_type') ? $this->config->get('exchange1c_product_options_type') : 'select';
  6010.  
  6011.                     // Тип по-умолчанию, если не будет переопределен
  6012.                     switch($option_obj['option']) {
  6013.                         case 'select':
  6014.                             $option_type    = "select";
  6015.                             break;
  6016.                         case 'radio':
  6017.                             $option_type    = "radio";
  6018.                             break;
  6019.                         case 'checkbox':
  6020.                             $option_type    = "checkbox";
  6021.                             break;
  6022.                         case 'image':
  6023.                             $option_type    = "image";
  6024.                             $image          = $value_obj['option'] ? "options/" . $value_obj['option'] : "";
  6025.                             break;
  6026.                     }
  6027.  
  6028.                     // Если включена загрузка изображений
  6029.                     if ($this->config->get('exchange1c_product_options_image_load')) {
  6030.                         $image = $this->setProductOptionImage($data, $option_obj['name'], $value_obj['name']);
  6031.                     }
  6032.  
  6033.                     // Если тип опции не зада из торговой системы, задаем из настроек
  6034.                     if (!$option_type) {
  6035.                         $option_type = $this->config->get('exchange1c_product_options_type') ? $this->config->get('exchange1c_product_options_type') : 'select';
  6036.                     }
  6037.  
  6038.                     $option_id          = $this->setOption($option_obj['name'], $option_type, $option_obj['order']);
  6039.                     $option_value_id    = $this->setOptionValue($option_id, $value_obj['name'], $value_obj['order'], $image);
  6040.  
  6041.                     $options[$option_value_id] = array(
  6042.                         'option_guid'           => $feature_option->Ид ? (string)$feature_option->Ид : "",
  6043.                         'subtract'              => $this->config->get('exchange1c_product_options_subtract') == 1 ? 1 : 0,
  6044.                         'option_id'             => $option_id,
  6045.                         'type'                  => $option_type,
  6046.                         'quantity'              => $quantity
  6047.                     );
  6048.  
  6049.                     $this->log("Опция: '" . $option_obj['name'] . "' = '" . $value_obj['name'] . "'");
  6050.                 }
  6051.  
  6052.                 $features[$data['feature_guid']]['options'] = $options;
  6053.             }
  6054.  
  6055.         } else {
  6056.  
  6057.             // нет секции характеристика (XML 2.07, УТ 11.3)
  6058.             // нет секции характеристика (XML 2.03, 2.04 УТ для Украины)
  6059.             $this->log("> нет секции <ХарактеристикаТовара> - обрабатываем как обычный товар", 2);
  6060.         }
  6061.  
  6062.         return $features;
  6063.  
  6064.     } // parseFeature()
  6065.  
  6066.  
  6067.     /**
  6068.      * ver 8
  6069.      * update 2017-06-03
  6070.      * Разбор предложений
  6071.      */
  6072.     private function parseOffers($xml) {
  6073.  
  6074.         if (!$xml->Предложение) {
  6075.             $this->log("[!] Пустое предложение, пропущено");
  6076.             return true;
  6077.         }
  6078.  
  6079.         foreach ($xml->Предложение as $offer) {
  6080.  
  6081.             // Массив для хранения данных об одном предложении товара
  6082.             $data = array();
  6083.  
  6084.             // Получаем Ид товара и характеристики
  6085.             $guid                   = explode("#", (string)$offer->Ид);
  6086.             $data['product_guid']   = $guid[0];
  6087.             $data['feature_guid']   = isset($guid[1]) ? $guid[1] : '';
  6088.  
  6089.             $data['product_id'] = 0;
  6090.  
  6091.             $this->log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -", 2);
  6092.             // Если указан код, ищем товар по коду
  6093.             if ($this->config->get('exchange1c_synchronize_by_code') == 1 && $offer->Код) {
  6094.                 $code   = (int)$offer->Код;
  6095.                 $this->log("> Синхронизация товара по коду: " . $code, 2);
  6096.                 $data['product_id'] = $this->getProductIdByCode($code);
  6097.             }
  6098.  
  6099.             // Пустые предложения игнорируются
  6100.             if (!$data['product_id']) {
  6101.                 if (empty($data['product_guid'])) {
  6102.                     // Проверка на пустое предложение
  6103.                     $this->log("[!] Ид товара пустое, предложение игнорируется!", 2);
  6104.                     continue;
  6105.                 }
  6106.                 // Читаем product_id, если нет товара выходим с ошибкой, значит что-то не так
  6107.                 $data['product_id'] = $this->getProductIdByGuid($data['product_guid']);
  6108.             }
  6109.  
  6110.             // Нет товара, просто пропускаем
  6111.             if (!$data['product_id']) {
  6112.                 $this->log("parseOffers() - Не найден товар в базе по Ид: '" . $data['product_guid'] . "'", 2);
  6113.                 continue;
  6114.             }
  6115.  
  6116.             if ($offer->Наименование) {
  6117.                 $data['feature_name'] = (string)$offer->Наименование;
  6118.             }
  6119.  
  6120.             $this->log("ПРЕДЛОЖЕНИЕ ТОВАРА ИД: " . $data['product_guid'] . ", product_id = " . $data['product_id'], 2);
  6121.             if ($data['feature_guid']) {
  6122.                 $this->log("ХАРАКТЕРИСТИКА ИД: " . $data['feature_guid'], 2);
  6123.             }
  6124.  
  6125.             // Базовая единица измерения товара или характеристики
  6126.             if ($offer->БазоваяЕдиница) {
  6127.                 $data['unit'] = $this->parseProductUnit($offer->БазоваяЕдиница);
  6128.             }
  6129.  
  6130.             // Штрихкод товара или характеристики
  6131.             if ($offer->Штрихкод) {
  6132.                 $data['ean'] = (string)$offer->Штрихкод;
  6133.             }
  6134.  
  6135.             // По-умолчанию статус включаем, дальше по коду будет только отключение.
  6136.             $data['status'] = 1;
  6137.  
  6138.             // ОСТАТКИ (offers, rests)
  6139.             if ($offer->Склад) {
  6140.                 // Остатки характеристики по складам
  6141.                 $result = $this->parseQuantity($offer, $data);
  6142.                 if ($this->ERROR) return false;
  6143.                 if (count($result)) $data['quantities'] = $result;
  6144.  
  6145.             } elseif ($offer->Остатки) {
  6146.                 // остатки характеристики (CML >= 2.09) файл rests_*.xml
  6147.                 $result = $this->parseQuantity($offer->Остатки, $data);
  6148.                 if ($this->ERROR) return false;
  6149.                 if (count($result)) $data['quantities'] = $result;
  6150.  
  6151.             } else {
  6152.                 // Нет складов
  6153.                 // Общий остаток предложения по всем складам
  6154.                 if ($offer->Количество) {
  6155.                     $data['quantities'][0] = (float)$offer->Количество;
  6156.                 }
  6157.             }
  6158.  
  6159.             // Если остатки не указаны, прочитаем остатки
  6160.  
  6161.             // Есть характеристики
  6162.             if ($offer->ХарактеристикиТовара) {
  6163.                 $result = $this->parseFeatures($offer->ХарактеристикиТовара, $data);
  6164.                 if ($this->ERROR) return false;
  6165.                 if (count($result)) {
  6166.                     if ($data['feature_guid']) {
  6167.                         // Когда предложение является одной характеристикой
  6168.                         $data['options'] = $result[$data['feature_guid']]['options'];
  6169.                     } else {
  6170.                         // Когда в предложении несколько характеристик
  6171.                         $data['features'] = $result;
  6172.                     }
  6173.                 }
  6174.             }
  6175.  
  6176.             if ($this->config->get('exchange1c_price_import_mode') != 'disable') {
  6177.                 // Цены товара или характеристики (offers*.xml, prices*.xml)
  6178.                 if ($offer->Цены) {
  6179.                     $result = $this->parsePrice($offer->Цены, $data);
  6180.                     if ($this->ERROR) return false;
  6181.                     if (count($result)) $data['prices'] = $result;
  6182.                 }
  6183.             }
  6184.  
  6185.             unset($result);
  6186.  
  6187.             // Обновляем товар
  6188.             $this->updateProduct($data);
  6189.             if ($this->ERROR) return false;
  6190.  
  6191.             unset($data);
  6192.  
  6193.             // Прерывание процесса загрузки по наличию файла break в папке /system/storage/cache/exchange1c
  6194.             if (file_exists(DIR_CACHE . 'exchange1c/break')) {
  6195.                 $this->ERROR = "parseOffers() - остановлен по наличию файла break";
  6196.                 return false;
  6197.             }
  6198.         } // foreach()
  6199.  
  6200.         return true;
  6201.  
  6202.     } // parseOffers()
  6203.  
  6204.  
  6205.     /**
  6206.      * ver 2
  6207.      * update 2017-04-05
  6208.      * Проверяет на наличие полной выгрузки в каталоге или в предложениях
  6209.      */
  6210.     private function checkFullImport($xml) {
  6211.  
  6212.         if ((string)$xml['СодержитТолькоИзменения'] == "false") {
  6213.             $this->FULL_IMPORT = true;
  6214.             $this->log("[!] Загрузка полная...");
  6215.         } else {
  6216.             if ((string)$xml->СодержитТолькоИзменения == "false") {
  6217.                 $this->FULL_IMPORT = true;
  6218.             } else {
  6219.                 $this->log("[!] Загрузка только изменений...");
  6220.             }
  6221.         }
  6222.  
  6223.     } // checkFullImport()
  6224.  
  6225.  
  6226.     /**
  6227.      * ver 4
  6228.      * update 2017-06-03
  6229.      * Загружает пакет предложений
  6230.      */
  6231.     private function parseOffersPack($xml) {
  6232.  
  6233.         $offers_pack = array();
  6234.         $offers_pack['offers_pack_id']  = (string)$xml->Ид;
  6235.         $offers_pack['name']            = (string)$xml->Наименование;
  6236.         $offers_pack['directory_id']    = (string)$xml->ИдКаталога;
  6237.         $offers_pack['classifier_id']   = (string)$xml->ИдКлассификатора;
  6238.  
  6239.         $this->checkFullImport($xml);
  6240.  
  6241.         // Сопоставленные типы цен
  6242.         if ($this->config->get('exchange1c_price_import_mode') != 'disable') {
  6243.             if ($xml->ТипыЦен) {
  6244.                 $offers_pack['price_types'] = $this->parseClassifierPriceType($xml->ТипыЦен);
  6245.                 if ($this->ERROR) return false;
  6246.             }
  6247.         }
  6248.  
  6249.         // Загрузка складов
  6250.         if ($xml->Склады) {
  6251.             $offers_pack['warehouses'] = $this->parseClassifierWarehouses($xml->Склады);
  6252.             if ($this->ERROR) return false;
  6253.         }
  6254.  
  6255.         // Загружаем предложения
  6256.         if ($xml->Предложения) {
  6257.             $this->parseOffers($xml->Предложения, $offers_pack);
  6258.             if ($this->ERROR) return false;
  6259.         }
  6260.  
  6261.         return true;
  6262.  
  6263.      } // parseOffersPack()
  6264.  
  6265.  
  6266.     /**
  6267.      * ****************************** ФУНКЦИИ ДЛЯ ЗАГРУЗКИ ЗАКАЗОВ ******************************
  6268.      */
  6269.  
  6270.     /**
  6271.      * Меняет статусы заказов
  6272.      *
  6273.      * @param   int     exchange_status
  6274.      * @return  bool
  6275.      */
  6276.     private function sendMail($subject, $message, $order_info) {
  6277.  
  6278.         $this->log("==> sendMail()",2);
  6279.  
  6280.         $mail = new Mail();
  6281.         $mail->protocol = $this->config->get('config_mail_protocol');
  6282.         $mail->parameter = $this->config->get('config_mail_parameter');
  6283.         $mail->smtp_hostname = $this->config->get('config_mail_smtp_hostname');
  6284.         $mail->smtp_username = $this->config->get('config_mail_smtp_username');
  6285.         $mail->smtp_password = html_entity_decode($this->config->get('config_mail_smtp_password'), ENT_QUOTES, 'UTF-8');
  6286.         $mail->smtp_port = $this->config->get('config_mail_smtp_port');
  6287.         $mail->smtp_timeout = $this->config->get('config_mail_smtp_timeout');
  6288.  
  6289.         $mail->setTo($order_info['email']);
  6290.         $mail->setFrom($this->config->get('config_email'));
  6291.         $mail->setSender(html_entity_decode($order_info['store_name'], ENT_QUOTES, 'UTF-8'));
  6292.         $mail->setSubject(html_entity_decode($subject, ENT_QUOTES, 'UTF-8'));
  6293.         $mail->setText($message);
  6294.         //$mail->send();
  6295.         $this->log($mail, 2);
  6296.  
  6297.     } // sendMail()
  6298.  
  6299.  
  6300.     /**
  6301.      * ver 5
  6302.      * update 2017-06-01
  6303.      * Меняет статусы заказов
  6304.      *
  6305.      * @param   int     exchange_status
  6306.      * @return  bool
  6307.      */
  6308.     public function queryOrdersStatus() {
  6309.  
  6310.         // Если статус новый пустой, тогда не меняем, чтобы не породить ошибку
  6311.         $new_status = $this->config->get('exchange1c_order_status_exported');
  6312.         if (!$new_status) {
  6313.             return false;
  6314.         }
  6315.  
  6316.         if ($this->config->get('exchange1c_order_date')) {
  6317.             $from_date = str_replace('T',' ',$this->config->get('exchange1c_order_date')) . ":00";
  6318.         } else {
  6319.             // При первом обмене это поле будет пустым, если не изменено вручную. Для пустого поля зададим начало столетия
  6320.             $from_date = '2001-01-01 00:00:00';
  6321.         }
  6322.         $this->log($from_date , 2);
  6323.  
  6324.         // По текущую дату и время
  6325.         $to_date = date('Y-m-d H:i:s');
  6326.  
  6327.         // Этот запрос будет использовать индексы поля date_modified
  6328.         $query = $this->query("SELECT `order_id`,`order_status_id` FROM `" . DB_PREFIX . "order` WHERE `date_modified` BETWEEN STR_TO_DATE('" . $from_date . "', '%Y-%m-%d %H:%i:%s') AND STR_TO_DATE('" . $to_date . "', '%Y-%m-%d %H:%i:%s')");
  6329.  
  6330.         $this->log("> Поиск заказов за период с: " . $from_date . " по " . $to_date, 2);
  6331.  
  6332.         if ($query->num_rows) {
  6333.  
  6334.             $this->NOW = date('Y-m-d H:i:s');
  6335.  
  6336.             $notify = $this->config->get('exchange1c_order_notify') == 1 ? 1 : 0;
  6337.  
  6338.             foreach ($query->rows as $order_data) {
  6339.  
  6340.                 if ($order_data['order_status_id'] == $new_status) {
  6341.                     $this->log("> Cтатус заказа #" . $order_data['order_id'] . " не менялся.", 2);
  6342.                     continue;
  6343.                 }
  6344.  
  6345.                 // Меняем статус
  6346.                 $query = $this->query("UPDATE `" . DB_PREFIX . "order` SET `order_status_id` = " . (int)$new_status . " WHERE `order_id` = " . (int)$order_data['order_id']);
  6347.                 $this->log("> Изменен статус заказа #" . $order_data['order_id']);
  6348.                 // Добавляем историю в заказ
  6349.                 $query = $this->query("INSERT INTO `" . DB_PREFIX . "order_history` SET `order_id` = " . (int)$order_data['order_id'] . ", `comment` = 'Статус Вашего заказа изменен', `order_status_id` = " . (int)$new_status . ", `notify` = " . $notify . ", `date_added` = '" . $this->NOW . "'");
  6350.                 $this->log("> Добавлена история в заказ (изменен статус) #" . $order_data['order_id'], 2);
  6351.  
  6352.                 // Уведомление
  6353.                 if ($notify) {
  6354.                     $this->log("> Отправка уведомления на почту: " . $order_data['email'], 2);
  6355.                     $this->sendMail('Заказ обновлен', 'Статус Вашего заказа изменен', $order_data);
  6356.                 }
  6357.             }
  6358.         }
  6359.  
  6360.         return true;
  6361.  
  6362.     }  // queryOrdersStatus()
  6363.  
  6364.  
  6365.     /**
  6366.      * Получает название статуса документа на текущем языке
  6367.      *
  6368.      */
  6369.     private function getOrderStatusName($order_staus_id) {
  6370.         if (!$this->LANG_ID) {
  6371.             $this->LANG_ID = $this->getLanguageId($this->config->get('config_language'));
  6372.         }
  6373.         $query = $this->query("SELECT `name` FROM `" . DB_PREFIX . "order_status` WHERE `order_status_id` = " . $order_staus_id . " AND `language_id` = " . $this->LANG_ID);
  6374.         if ($query->num_rows) {
  6375.             return $query->row['name'];
  6376.         }
  6377.         return "";
  6378.     } // getOrderStatusName()
  6379.  
  6380.  
  6381.     /**
  6382.      * Получает название цены из настроек по группе покупателя
  6383.      *
  6384.      */
  6385.     private function getPriceTypeName($customer_group_id) {
  6386.  
  6387.         if (!$customer_group_id)
  6388.             return "";
  6389.  
  6390.         $config_price_type = $this->config->get('exchange1c_price_type');
  6391.         if (!$config_price_type)
  6392.             return "";
  6393.  
  6394.         foreach ($config_price_type as $price_type) {
  6395.             if ($price_type['customer_group_id'] == $customer_group_id)
  6396.                 return $price_type['keyword'];
  6397.         }
  6398.  
  6399.         return "";
  6400.  
  6401.     } // getPriceTypeName()
  6402.  
  6403.  
  6404.     /**
  6405.      * ver 4
  6406.      * update 2017-06-19
  6407.      * Получает GUID характеристики по выбранным опциям
  6408.      */
  6409.     private function getFeatureGUID($product_id, $order_id) {
  6410.  
  6411.         $order_options = $this->model_sale_order->getOrderOptions($order_id, $product_id);
  6412.         $options = array();
  6413.         foreach ($order_options as $order_option) {
  6414.             $options[$order_option['product_option_id']] = $order_option['product_option_value_id'];
  6415.         }
  6416.  
  6417.         $product_feature_id = 0;
  6418.         foreach ($order_options as $order_option) {
  6419.             $query = $this->query("SELECT `product_feature_id` FROM `" . DB_PREFIX . "product_feature_value` WHERE `product_option_value_id` = " . (int)$order_option['product_option_value_id']);
  6420.  
  6421.             if ($query->num_rows) {
  6422.                 if ($product_feature_id) {
  6423.                     if ($product_feature_id != $query->row['product_feature_id']) {
  6424.                         $this->ERROR = "[ОШИБКА] По опциям товара найдено несколько характеристик!";
  6425.                         return false;
  6426.                     }
  6427.                 } else {
  6428.                     $product_feature_id = $query->row['product_feature_id'];
  6429.                 }
  6430.             }
  6431.         }
  6432.  
  6433.         $feature_guid = "";
  6434.         if ($product_feature_id) {
  6435.             // Получаем Ид
  6436.             $query = $this->query("SELECT `guid` FROM `" . DB_PREFIX . "product_feature` WHERE `product_feature_id` = " . (int)$product_feature_id);
  6437.             if ($query->num_rows) {
  6438.                 $feature_guid = $query->row['guid'];
  6439.             }
  6440.         }
  6441.  
  6442.         return $feature_guid;
  6443.  
  6444.     } // getFeatureGUID
  6445.  
  6446.  
  6447.     /** ****************************** ФУНКЦИИ ДЛЯ ВЫГРУЗКИ ЗАКАЗОВ *******************************/
  6448.  
  6449.  
  6450.     /**
  6451.      * ver 1
  6452.      * update 2017-06-02
  6453.      * Формирует адрес с полями и представлением в виде массива
  6454.      */
  6455.     private function setCustomerAddress($order, $mode = 'shipping') {
  6456.  
  6457.         // Соответствие полей в XML и в базе данных
  6458.         $fields = array(
  6459.             'Почтовый индекс'     => 'postcode',
  6460.             'Страна'          => 'country',
  6461.             'Регион'          => 'zone',
  6462.             'Район'                => 'none',
  6463.             'Населенный пункт'   => 'none',
  6464.             'Город'                => 'city',
  6465.             'Улица'                => 'none',
  6466.             'Дом'                => 'none',
  6467.             'Корпус'          => 'none',
  6468.             'Квартира'          => 'none'
  6469.         );
  6470.         //'Представление'  => $order['shipping_postcode'] . ', ' . $order['shipping_zone'] . ', ' . $order['shipping_city'] . ', ' . $order['shipping_address_1'] . ', '.$order['shipping_address_2'],
  6471.  
  6472.         $address = array();
  6473.         $counter = 0;
  6474.  
  6475.         // Представление
  6476.         $arName = array();
  6477.  
  6478.         // Формирование полей
  6479.         foreach ($fields as $type => $field) {
  6480.  
  6481.             if (isset($order[$mode . '_' . $field])) {
  6482.  
  6483.                 // Формируем типы полей
  6484.                 $address['АдресноеПоле' . $counter] = array(
  6485.                     'Тип'        => $type,
  6486.                     'Значение'  => $order[$mode . '_' . $field]
  6487.                 );
  6488.  
  6489.                 // формируем наименование
  6490.                 $arName[] = $order[$mode . '_' . $field];
  6491.  
  6492.             }
  6493.         }
  6494.  
  6495.         $address['Представление'] = implode(', ', $arName);
  6496.  
  6497.         return $address;
  6498.  
  6499.     } // setCustomerAddress()
  6500.  
  6501.  
  6502.     /**
  6503.      * ver 1
  6504.      * update 2017-06-02
  6505.      * Формирует контактные данные контрагента
  6506.      */
  6507.     private function setCustomerContacts($order) {
  6508.         $this->log($order, 2);
  6509.         // Соответствие полей в XML и в базе данных
  6510.         $fields = array(
  6511.             'ТелефонРабочий'  => 'telephone',
  6512.             'Почта'                => 'email'
  6513.         );
  6514.  
  6515.         $contact = array();
  6516.         $counter = 0;
  6517.  
  6518.         // Формирование полей
  6519.         foreach ($fields as $type => $field) {
  6520.  
  6521.             if (isset($order[$field])) {
  6522.  
  6523.                 // Формируем типы полей
  6524.                 $contact['Контакт' . $counter] = array(
  6525.                     'Тип'        => $type,
  6526.                     'Значение'  => $order[$field]
  6527.                 );
  6528.             }
  6529.             $counter++;
  6530.         }
  6531.         return $contact;
  6532.  
  6533.     } // setCustomerContacts()
  6534.  
  6535.  
  6536.     /**
  6537.      * ver 2
  6538.      * update 2017-06-03
  6539.      * Формирует реквизиты документа
  6540.      */
  6541.     private function setDocumentRequisites($order, $document) {
  6542.  
  6543.         $requisites = array();
  6544.         // Счетчик
  6545.         $counter = 0;
  6546.  
  6547.         $requisites['Дата отгрузки']                = $order['date'];
  6548.         $requisites['Статус заказа']                = $this->getOrderStatusName($order['order_status_id']);
  6549.         $requisites['Вид цен']                        = $this->getPriceTypeName($order['customer_group_id']);
  6550.         $requisites['Контрагент']                     = $order['username'];
  6551. //      $requisites['Склад']                       = $this->getWarehouseName($order['warehouse_id']);
  6552. //      $requisites['Организация']                   = 'Наша фирма';
  6553. //      $requisites['Подразделение']               = 'Интернет-магазин';
  6554. //      $requisites['Сумма включает НДС']           = 'true';
  6555. //      $requisites['Договор контрагента']            = 'Основной договор';
  6556. //      $requisites['Метод оплаты']              = 'Заказ по телефону';
  6557.  
  6558.         // Для 1С:Розница
  6559. //      $requisites['ТочкаСамовывоза']               = 'Название магазина';
  6560. //      $requisites['ВидЦенНаименование']             = 'Розничная';
  6561. //      $requisites['СуммаВключаетНДС']             = 'true';
  6562. //      $requisites['НаименованиеСкидки']             = 'Скидка 5%';
  6563. //      $requisites['ПроцентСкидки']               = 5;
  6564. //      $requisites['СуммаСкидки']                   = 1000;
  6565. //      $requisites['СкладНаименование']           = 'Основной склад';
  6566. //      $requisites['ПодразделениеНаименование']   = 'Основное подразделение';
  6567. //      $requisites['Склад']                       = 'Основной склад'
  6568.  
  6569.         $data = array();
  6570.         foreach ($requisites as $name => $value) {
  6571.  
  6572.             // Пропускаем пустые значения
  6573.             if (!$value) continue;
  6574.  
  6575.             $data['ЗначениеРеквизита'.$counter]    = array(
  6576.                 'Наименование'      => $name,
  6577.                 'Значение'          => $value
  6578.             );
  6579.  
  6580.             $counter ++;
  6581.  
  6582.         } // foreach
  6583.  
  6584.         return $data;
  6585.  
  6586.     } // setDocumentRequisites()
  6587.  
  6588.  
  6589.     /**
  6590.      * ver 2
  6591.      * update 2017-06-04
  6592.      * Формирует Контрагента
  6593.      */
  6594.     private function setCustomer(&$order) {
  6595.  
  6596.         $customer = array();
  6597.  
  6598.         if ($this->config->get('exchange1c_order_customer_export') != 1) {
  6599.             return $customer;
  6600.         }
  6601.  
  6602.         // Счетчик
  6603.         $counter = 0;
  6604.  
  6605.         // Обязательные поля покупателя для торговой системы
  6606.         $customer = array(
  6607.             'Ид'                  => $order['customer_id'] . '#' . $order['email'],
  6608.             'Роль'                  => 'Покупатель',
  6609.             'Наименование'          => $order['username'],
  6610.             'ПолноеНаименование'  => $order['username'],
  6611.             'Фамилия'                => $order['payment_lastname'],
  6612.             'Имя'                    => $order['payment_firstname'],
  6613.             'Отчество'              => isset($order['payment_patronymic']) ? $order['payment_patronymic'] : "",
  6614.             'АдресРегистрации'      => $this->setCustomerAddress($order),
  6615.             'Контакты'              => $this->setCustomerContacts($order),
  6616.         );
  6617.         if (isset($order['payment_inn'])) {
  6618.             $customer['ИНН'] = $order['payment_inn'];
  6619.         }
  6620.  
  6621.  
  6622.         // Поля для юр. лица или физ. лица
  6623.         if ($order['payment_company']) {
  6624.  
  6625.             // Если плательщиком является организация
  6626.             $customer['ОфициальноеНаименование']     = isset($order['payment_company'])  ? $order['payment_company'] : "";
  6627.             $customer['ПолноеНаименование']       = isset($order['payment_company'])  ? $order['payment_company'] : "";
  6628.             $customer['ОКПО']                       = isset($order['payment_okpo'])     ? $order['payment_okpo']    : "";
  6629.             $customer['КПП']                         = isset($order['payment_kpp'])      ? $order['payment_kpp']     : "";
  6630.  
  6631.         } else {
  6632.  
  6633.             // Покупатель - физическое лицо
  6634.             $customer['Наименование']               = $order['username'];
  6635.         }
  6636.  
  6637.         return $customer;
  6638.  
  6639.     } // setCustomer()
  6640.  
  6641.  
  6642.     /**
  6643.      * ver 2
  6644.      * update 2017-06-20
  6645.      * Возвращает единицу измерения товара
  6646.      */
  6647.     private function getProductUnit($unit_id, $product_id) {
  6648.  
  6649.         $query = $this->query("SELECT `p`.`ratio`,`u`.`name`,`u`.`number_code`,`u`.`full_name` FROM `" . DB_PREFIX . "product_unit` `p` LEFT JOIN `" . DB_PREFIX . "unit_to_1c` `u` ON (`p`.`unit_id` = `u`.`unit_id`) WHERE `p`.`product_id` = " . $product_id . " AND `u`.`unit_id` = " . $unit_id . " ORDER BY `p`.`ratio`");
  6650.         if ($query->num_rows) {
  6651.             return $query->row;
  6652.         }
  6653.  
  6654.         return false;
  6655.  
  6656.     } // getProductUnit()
  6657.  
  6658.     /**
  6659.      * ver 9
  6660.      * update 2017-06-19
  6661.      * Выгружает заказы в торговую систему
  6662.      */
  6663.     public function queryOrders() {
  6664.  
  6665.         $this->log("==== Выгрузка заказов ====",2);
  6666.  
  6667.         $orders_export = array();
  6668.  
  6669.         // Выгрузка измененных заказов
  6670.         if ($this->config->get('exchange1c_orders_export_modify')) {
  6671.  
  6672.             if ($this->config->get('exchange1c_order_date')) {
  6673.                 $from_date = str_replace('T',' ',$this->config->get('exchange1c_order_date')) . ":00";
  6674.             } else {
  6675.                 // При первом обмене это поле будет пустым, если не изменено вручную. Для пустого поля зададим начало столетия
  6676.                 $from_date = '2001-01-01 00:00:00';
  6677.             }
  6678.             $this->log($from_date , 2);
  6679.  
  6680.             // По текущую дату и время
  6681.             $to_date = date('Y-m-d H:i:s');
  6682.  
  6683.             // Этот запрос будет использовать индексы поля date_modified
  6684.             $query = $this->query("SELECT `order_id`,`order_status_id` FROM `" . DB_PREFIX . "order` WHERE `date_modified` BETWEEN STR_TO_DATE('" . $from_date . "', '%Y-%m-%d %H:%i:%s') AND STR_TO_DATE('" . $to_date . "', '%Y-%m-%d %H:%i:%s')");
  6685.  
  6686.             if ($query->num_rows) {
  6687.                 foreach ($query->rows as $row) {
  6688.                     $orders_export[$row['order_id']] = $row['order_status_id'];
  6689.                 }
  6690.             }
  6691.         }
  6692.  
  6693.         // Выгрузка заказов со статусом
  6694.         if ($this->config->get('exchange1c_order_status_export') != 0) {
  6695.  
  6696.             $query = $this->query("SELECT `order_id`,`order_status_id` FROM `" . DB_PREFIX . "order` WHERE `order_status_id` = " . (int)$this->config->get('exchange1c_order_status_export'));
  6697.  
  6698.             if ($query->num_rows) {
  6699.  
  6700.                 foreach ($query->rows as $row) {
  6701.  
  6702.                     // Пропускаем если такой заказ уже выгружается
  6703.                     if (isset($orders_export[$row['order_id']])) {
  6704.                         continue;
  6705.                     }
  6706.  
  6707.                     $orders_export[$row['order_id']] = $row['order_status_id'];
  6708.                 }
  6709.             }
  6710.         }
  6711.  
  6712.         // Валюта документа
  6713.         $currency = $this->config->get('exchange1c_order_currency') ? $this->config->get('exchange1c_order_currency') : 'руб.';
  6714.  
  6715.         $document = array();
  6716.  
  6717.         if (count($orders_export)) {
  6718.  
  6719.             $document_counter = 0;
  6720.  
  6721.             $this->load->model('customer/customer_group');
  6722.             $this->load->model('sale/order');
  6723.  
  6724.             foreach ($orders_export as $order_id => $order_status_id) {
  6725.  
  6726.                 $order = $this->model_sale_order->getOrder($order_id);
  6727.                 $this->log("> Выгружается заказ #" . $order['order_id']);
  6728.  
  6729.                 $order['date'] = date('Y-m-d', strtotime($order['date_added']));
  6730.                 $order['time'] = date('H:i:s', strtotime($order['date_added']));
  6731.                 $customer_group = $this->model_customer_customer_group->getCustomerGroup($order['customer_group_id']);
  6732.  
  6733.                 // Шапка документа
  6734.                 $document['Документ' . $document_counter] = array(
  6735.                      'Ид'          => $order['order_id']
  6736.                     ,'Номер'       => $order['order_id']
  6737.                     ,'Дата'        => $order['date']
  6738.                     ,'Время'       => $order['time']
  6739.                     ,'Валюта'      => $currency
  6740.                     ,'Курс'        => 1
  6741.                     ,'ХозОперация' => 'Заказ товара'
  6742.                     ,'Роль'        => 'Продавец'
  6743.                     ,'Сумма'       => $order['total']
  6744.                     ,'Комментарий' => $order['comment']
  6745.                     //,'Соглашение'  => $customer_group['name'] // the agreement
  6746.                 );
  6747.  
  6748.                 // Разбирает ФИО в массив, чтобы получить отчество
  6749.                 $username = array();
  6750.                 $fields = array('lastname', 'firstname', 'patronymic');
  6751.  
  6752.                 // Формируем массив ФИО
  6753.                 foreach ($fields as $field) {
  6754.                     if ($order['payment_' . $field]) {
  6755.                         $username[] = $order['payment_' . $field];
  6756.                     }
  6757.                 }
  6758.  
  6759.                 // Собираем полное наименование покупателя, ФИО
  6760.                 $order['username'] = implode(" ", $username);
  6761.  
  6762.                 // ПОКУПАТЕЛЬ (КОНТРАГЕНТ)
  6763.                 $document['Документ' . $document_counter]['Контрагенты']['Контрагент'] = $this->setCustomer($order);
  6764.  
  6765.                 // РЕКВИЗИТЫ ДОКУМЕНТА
  6766.                 $document['Документ' . $document_counter]['ЗначенияРеквизитов'] = $this->setDocumentRequisites($order, $document);
  6767.  
  6768.                 // ТОВАРЫ ДОКУМЕНТА
  6769.                 $products = $this->model_sale_order->getOrderProducts($order_id);
  6770.  
  6771.                 $product_counter = 0;
  6772.                 foreach ($products as $product) {
  6773.                     $product_guid = $this->getGuidByProductId($product['product_id']);
  6774.                     $document['Документ' . $document_counter]['Товары']['Товар' . $product_counter] = array(
  6775.                          'Ид'             => $product_guid
  6776.                         ,'Наименование'   => $product['name']
  6777.                         ,'ЦенаЗаЕдиницу'  => $product['price']
  6778.                         ,'Количество'     => $product['quantity']
  6779.                         ,'Сумма'          => $product['total']
  6780.                         ,'Скидки'         => array('Скидка' => array(
  6781.                             'УчтеноВСумме' => 'false'
  6782.                             ,'Сумма' => 0
  6783.                             )
  6784.                         )
  6785.                         ,'ЗначенияРеквизитов' => array(
  6786.                             'ЗначениеРеквизита' => array(
  6787.                                 'Наименование' => 'ТипНоменклатуры'
  6788.                                 ,'Значение' => 'Товар'
  6789.                             )
  6790.                         )
  6791.                     );
  6792.                     $current_product = &$document['Документ' . $document_counter]['Товары']['Товар' . $product_counter];
  6793.                     // Резервирование товаров
  6794.                     if ($this->config->get('exchange1c_order_reserve_product') == 1) {
  6795.                         $current_product['Резерв'] = $product['quantity'];
  6796.                     }
  6797.  
  6798.                     // Характеристики
  6799.                     $feature_guid = $this->getFeatureGuid($product['order_product_id'], $order_id);
  6800.                     if ($feature_guid) {
  6801.                         $current_product['Ид'] .= "#" . $feature_guid;
  6802.                     }
  6803.  
  6804.                     // Базовая единица
  6805.                     $unit = $this->getProductUnit($product['unit_id'], $product['product_id']);
  6806.                     $this->log($unit, 2);
  6807.                     if ($unit) {
  6808.                         $current_product['БазоваяЕдиница'] = array(
  6809.                             'Код'                    => $unit['number_code'],
  6810.                             'НаименованиеПолное'  => $unit['full_name']
  6811.                         );
  6812.                     } else {
  6813.                         $current_product['БазоваяЕдиница'] = array(
  6814.                             'Код'                    => '796',
  6815.                             'НаименованиеПолное'  => 'Штука'
  6816.                         );
  6817.                     }
  6818.  
  6819.                     $product_counter++;
  6820.                 }
  6821.  
  6822.                 $document_counter++;
  6823.  
  6824.             } // foreach ($query->rows as $orders_data)
  6825.  
  6826.         } // if (count($orders_export))
  6827.  
  6828.         // Формируем заголовок
  6829.         $root = '<?xml version="1.0" encoding="utf-8"?><КоммерческаяИнформация xmlns="urn:1C.ru:commerceml_2" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ВерсияСхемы="2.10" ДатаФормирования="' . date('Y-m-d', time()) . '" />';
  6830.  
  6831.         $root_xml = new SimpleXMLElement($root);
  6832.         $xml = $this->array_to_xml($document, $root_xml);
  6833.  
  6834.         // Проверка на запись файлов в кэш
  6835.         $cache = DIR_CACHE . 'exchange1c/';
  6836.         if (@is_writable($cache)) {
  6837.             // запись заказа в файл
  6838.             $f_order = @fopen($cache . 'orders.xml', 'w');
  6839.             if (!$f_order) {
  6840.                 $this->log("Нет доступа для записи в папку: " . $cache);
  6841.             } else {
  6842.                 fwrite($f_order, $xml->asXML());
  6843.                 fclose($f_order);
  6844.             }
  6845.         } else {
  6846.             $this->log("Папка " . $cache . " не доступна для записи, файл заказов не может быть сохранен!",1);
  6847.         }
  6848.  
  6849.         return $xml->asXML();
  6850.  
  6851.     } // queryOrders()
  6852.  
  6853.  
  6854.     /**
  6855.      * Адрес
  6856.      */
  6857.     private function parseAddress($xml) {
  6858.         if (!$xml) return "";
  6859.         return (string)$xml->Представление;
  6860.     } // parseAddress()
  6861.  
  6862.  
  6863.     /**
  6864.      * Банк
  6865.      */
  6866.     private function parseBank($xml) {
  6867.         if (!$xml) return "";
  6868.         return array(
  6869.             'correspondent_account' => (string)$xml->СчетКорреспондентский,
  6870.             'name'                  => (string)$xml->Наименование,
  6871.             'bic'                   => (string)$xml->БИК,
  6872.             'address'               => $this->parseAddress($xml->Адрес)
  6873.         );
  6874.     } // parseBank()
  6875.  
  6876.  
  6877.     /**
  6878.      * Расчетные счета
  6879.      */
  6880.     private function parseAccount($xml) {
  6881.         if (!$xml) return "";
  6882.         $data = array();
  6883.         foreach ($xml->РасчетныйСчет as $object) {
  6884.             $data[] = array(
  6885.                 'number'    => $object->Номерсчета,
  6886.                 'bank'      => $this->parseBank($object->Банк)
  6887.             );
  6888.         }
  6889.         return $data;
  6890.     } // parseAccount()
  6891.  
  6892.  
  6893.     /**
  6894.      * Владелец
  6895.      */
  6896.     private function parseOwner($xml) {
  6897.         if (!$xml) return "";
  6898.         return array(
  6899.             'id'        => (string)$xml->Ид,
  6900.             'name'      => (string)$xml->Наименование,
  6901.             'fullname'  => (string)$xml->ПолноеНаименование,
  6902.             'inn'       => (string)$xml->ИНН,
  6903.             'account'   => $this->parseAccount($xml->РасчетныеСчета)
  6904.         );
  6905.     } // parseOwner()
  6906.  
  6907.  
  6908.     /**
  6909.      * Возвращает курс валюты
  6910.      */
  6911.     private function getCurrencyValue($code) {
  6912.         $query = $this->query("SELECT `value` FROM `" . DB_PREFIX . "currency` WHERE `code` = '" . $code . "'");
  6913.         if ($query->num_rows) {
  6914.             return $query->row['value'];
  6915.         }
  6916.         return 1;
  6917.     } // getCurrencyValue()
  6918.  
  6919.  
  6920.     /**
  6921.      * ver 3
  6922.      * update 2017-05-30
  6923.      * Возвращает валюту по коду
  6924.      */
  6925.     private function getCurrencyByCode($code) {
  6926.  
  6927.         $data = array();
  6928.  
  6929.         if ($code == "643") {
  6930.  
  6931.             // Это временнон решение
  6932.             $data['currency_id'] = $this->getCurrencyId("RUB");
  6933.             $data['currency_code'] = "RUB";
  6934.             $data['currency_value'] = $this->getCurrencyValue("RUB");
  6935.  
  6936.         } else {
  6937.  
  6938.             $data['currency_id'] = $this->getCurrencyId($code);
  6939.             $data['currency_code'] = $code;
  6940.             $data['currency_value'] = $this->getCurrencyValue($code);
  6941.         }
  6942.  
  6943.         return $data;
  6944.  
  6945.     } // getCurrencyByCode()
  6946.  
  6947.  
  6948.     /**
  6949.      * ver 2
  6950.      * update 2017-04-05
  6951.      * Устанавливает опции заказа в товаре
  6952.      */
  6953.     private function setOrderProductOptions($order_id, $product_id, $order_product_id, $product_feature_id = 0) {
  6954.  
  6955.         // удалим на всякий случай если были
  6956.         $this->query("DELETE FROM `" . DB_PREFIX . "order_option` WHERE `order_product_id` = " . $order_product_id);
  6957.  
  6958.         // если есть, добавим
  6959.         if ($product_feature_id) {
  6960.             $query_feature = $this->query("SELECT `pfv`.`product_option_value_id`,`pf`.`name` FROM `" . DB_PREFIX . "product_feature_value` `pfv` LEFT JOIN `" . DB_PREFIX . "product_feature` `pf` ON (`pfv`.`product_feature_id` = `pf`.`product_feature_id`) WHERE `pfv`.`product_feature_id` = " . $product_feature_id . " AND `pfv`.`product_id` = " . $product_id);
  6961.             $this->log($query_feature,2);
  6962.             foreach ($query_feature->rows as $row_feature) {
  6963.                 $query_options = $this->query("SELECT `pov`.`product_option_id`,`pov`.`product_option_value_id`,`po`.`value`,`o`.`type` FROM `" . DB_PREFIX . "product_option_value` `pov` LEFT JOIN `" . DB_PREFIX . "product_option` `po` ON (`pov`.`product_option_id` = `po`.`product_option_id`) LEFT JOIN `" . DB_PREFIX . "option` `o` ON (`o`.`option_id` = `pov`.`option_id`) WHERE `pov`.`product_option_value_id` = " . $row_feature['product_option_value_id']);
  6964.                 $this->log($query_options,2);
  6965.                 foreach ($query_options->rows as $row_option) {
  6966.                     $this->query("INSERT INTO `" . DB_PREFIX . "order_option` SET `order_id` = " . $order_id . ", `order_product_id` = " . $order_product_id . ", `product_option_id` = " . $row_option['product_option_id'] . ", `product_option_value_id` = " . $row_option['product_option_value_id'] . ", `name` = '" . $this->db->escape($row_option['value']) . "', `value` = '" . $this->db->escape($row_feature['name']) . "', `type` = '" . $row_option['type'] . "'");
  6967.                     $order_option_id = $this->db->getLastId();
  6968.                     $this->log("order_option_id: ".$order_option_id,2);
  6969.                 }
  6970.             }
  6971.         }
  6972.         $this->log("Записаны опции в заказ",2);
  6973.  
  6974.     } // setOrderProductOptions()
  6975.  
  6976.  
  6977.     /**
  6978.      * ver 2
  6979.      * update 2017-04-05
  6980.      * Добавляет товар в заказ
  6981.      */
  6982.     private function addOrderProduct($order_id, $product_id, $price, $quantity, $total, $tax = 0, $reward = 0) {
  6983.  
  6984.         $query = $this->query("SELECT `pd`.`name`,`p`.`model` FROM `" . DB_PREFIX . "product` `p` LEFT JOIN `" . DB_PREFIX . "product_description` `pd` ON (`p`.`product_id` = `pd`.`product_id`) WHERE `p`.`product_id` = " . $product_id);
  6985.         if ($query->num_rows) {
  6986.             $name = $query->row['name'];
  6987.             $model = $query->row['model'];
  6988.  
  6989.             $sql = "";
  6990.             $sql .= ($tax) ? ", `tax` = " . $tax : "";
  6991.             $sql .= ($reward) ? ", `reward` = " . $reward : "";
  6992.             $this->query("INSERT INTO `" . DB_PREFIX . "order_product` SET `product_id` = " . $product_id . ",
  6993.                 `order_id` = " . $order_id . ",
  6994.                 `name` = '" . $this->db->escape($name) . "',
  6995.                 `model` = '" . $this->db->escape($model) . "',
  6996.                 `price` = " . $price . ",
  6997.                 `quantity` = " . $quantity . ",
  6998.                 `total` = " . $total . $sql);
  6999.             return $this->db->getLastId();
  7000.         }
  7001.         return 0;
  7002.         $this->log("Записаны товары в заказ",2);
  7003.  
  7004.     } // addOrderProduct()
  7005.  
  7006.  
  7007.     /**
  7008.      * ver 2
  7009.      * update 2017-04-05
  7010.      * Удаляем товар из заказа со всеми опциями
  7011.      */
  7012.     private function deleteOrderProduct($order_product_id) {
  7013.  
  7014.         $this->query("DELETE FROM `" . DB_PREFIX . "order_product` WHERE `order_product_id` = " . $order_product_id);
  7015.         $this->query("DELETE FROM `" . DB_PREFIX . "order_option` WHERE `order_product_id` = " . $order_product_id);
  7016.         $this->log("Удалены товары и опции в заказе",2);
  7017.  
  7018.     } // deleteOrderProduct()
  7019.  
  7020.  
  7021.     /**
  7022.      * ver 2
  7023.      * update 2017-04-05
  7024.      * Меняет статус заказа
  7025.      */
  7026.     private function getOrderStatusLast($order_id) {
  7027.  
  7028.         $order_status_id = 0;
  7029.         $query = $this->query("SELECT `order_status_id` FROM `" . DB_PREFIX . "order_history` WHERE `order_id` = " . $order_id . " ORDER BY `date_added` DESC LIMIT 1");
  7030.         if ($query->num_rows) {
  7031.             $this->log("<== getOrderStatusLast() return: " . $query->row['order_status_id'],2);
  7032.             $order_status_id = $query->row['order_status_id'];
  7033.         }
  7034.         $this->log("Получен статус заказа = " . $order_status_id, 2);
  7035.         return $order_status_id;
  7036.     }
  7037.  
  7038.  
  7039.     /**
  7040.      * ver 2
  7041.      * update 2017-04-05
  7042.      * Меняет статус заказа
  7043.      */
  7044.     private function changeOrderStatus($order_id, $status_name) {
  7045.  
  7046.         $query = $this->query("SELECT `order_status_id` FROM `" . DB_PREFIX . "order_status` WHERE `language_id` = " . $this->LANG_ID . " AND `name` = '" . $this->db->escape($status_name) . "'");
  7047.         if ($query->num_rows) {
  7048.             $new_order_status_id = $query->row['order_status_id'];
  7049.         } else {
  7050.             $this->ERROR = "changeOrderStatus() - Статус с названием '" . $status_name . "' не найден";
  7051.             return false;
  7052.         }
  7053.         $this->log("[i] Статус id у названия '" . $status_name . "' определен как " . $new_order_status_id,2);
  7054.  
  7055.         // получим старый статус
  7056.         $order_status_id = $this->getOrderStatusLast($order_id);
  7057.         if (!$order_status_id) {
  7058.             $this->ERROR = "changeOrderStatus() - Ошибка получения старого статуса документа!";
  7059.             return 0;
  7060.         }
  7061.  
  7062.         if ($order_status_id == $new_order_status_id) {
  7063.             $this->log("Статус документа не изменился", 2);
  7064.             return true;
  7065.         }
  7066.  
  7067.         // если он изменился, изменим в заказе
  7068.         $this->query("INSERT INTO `" . DB_PREFIX . "order_history` SET `order_id` = " . $order_id . ", `order_status_id` = " . $new_order_status_id . ", `date_added` = '" . $this->NOW . "'");
  7069.  
  7070.         $this->log("Изменен статус документа",2);
  7071.         return true;
  7072.  
  7073.     } // changeOrderStatus()
  7074.  
  7075.  
  7076.     /**
  7077.      * ver 3
  7078.      * update 2017-05-30
  7079.      * Обновляет документ
  7080.      */
  7081.     private function updateDocument($doc, $order, $products) {
  7082.  
  7083.         $order_fields = array();
  7084.         $this->log($doc, 2);
  7085.         $this->log($products, 2);
  7086.  
  7087.         // обновим входящий номер
  7088.         if (!empty($doc['invoice_no'])) {
  7089.             $order_fields['invoice_no'] = $doc['invoice_no'];
  7090.         }
  7091.  
  7092.         // проверим валюту
  7093.         if (!empty($doc['currency'])) {
  7094.             $currency = $this->getCurrencyByCode($doc['currency']);
  7095.             $order_fields['currency_id'] = $currency['currency_id'];
  7096.             $order_fields['currency_code'] = $currency['currency_code'];
  7097.             $order_fields['currency_value'] = $currency['currency_value'];
  7098.         }
  7099.  
  7100.         // проверим сумму
  7101.         if (!empty($doc['total'])) {
  7102.             if ($doc['total'] != $order['total']) {
  7103.                 $order_fields['total'] = $doc['total'];
  7104.                 $this->query("UPDATE `" . DB_PREFIX . "order` SET `total`=" . $order_fields['total'] . " WHERE `order_id` = " . $doc['order_id']);
  7105.         }
  7106.  
  7107.         // статус заказа
  7108.         if (!empty($doc['status'])) {
  7109.             $this->changeOrderStatus($doc['order_id'], $doc['status']);
  7110.             if ($this->ERROR) return false;
  7111.         }
  7112.  
  7113.         $old_products = $products;
  7114.  
  7115.         // проверим товары, порядок должен быть такой же как и в торговой системе
  7116.         if (!empty($doc['products'])) {
  7117.  
  7118.             foreach ($doc['products'] as $key => $doc_product) {
  7119.  
  7120.                 $this->log("Товар: ".$doc_product['name'],2);
  7121.  
  7122.                 $order_product_fields = array();
  7123.                 $order_option_fields = array();
  7124.                 $update = false;
  7125.                 $product_feature_id = isset($doc_product['product_feature_id']) ? $doc_product['product_feature_id'] : 0;
  7126.  
  7127.                 if (isset($products[$key])) {
  7128.                     $product = $products[$key];
  7129.                     $order_product_id = $product['order_product_id'];
  7130.  
  7131.                     unset($old_products[$key]);
  7132.  
  7133.                     // получим характеристику товара в заказе
  7134.                     $old_feature_guid = $this->getFeatureGuid($doc['order_id'], $order_product_id);
  7135.                     $this->log("old_feature_guid: " . $old_feature_guid,2);
  7136.                     $this->log("new_feature_guid: " . $doc_product['product_feature_guid'],2);
  7137.  
  7138.                     // сравним
  7139.                     if ($doc_product['product_id'] == $product['product_id']) {
  7140.  
  7141.                         $update = true;
  7142.  
  7143.                         if ($old_feature_guid != $doc_product['product_feature_guid']) {
  7144.  
  7145.                             // изменить характеристику
  7146.                             $this->setOrderProductOptions($doc['order_id'], $doc_product['product_id'], $order_product_id, $product_feature_id);
  7147.                             if ($this->ERROR) return false;
  7148.                         }
  7149.  
  7150.                         // обновим если менялось количество или цена
  7151.                         if ($product['quantity'] != $doc_product['quantity'] || $product['price'] != $doc_product['price']) {
  7152.                             $order_product_fields[] = "`quantity` = " . $doc_product['quantity'];
  7153.                             $order_product_fields[] = "`price` = " . $doc_product['price'];
  7154.                             $order_product_fields[] = "`total` = " . $doc_product['total'];
  7155.                             //$order_product_fields[] = "`tax` = " . $doc_product['tax'];
  7156.                             //$order_product_fields[] = "`reward` = " . $doc_product['reward'];
  7157.                         }
  7158.                     } else {
  7159.  
  7160.                         // товар отличается, заменить полностью
  7161.                         $order_product_fields[] = "`product_id` = " . $doc_product['product_id'];
  7162.                         $order_product_fields[] = "`name` = '" . $this->db->escape($doc_product['product_id']) . "'";
  7163.                         $order_product_fields[] = "`model` = '" . $this->db->escape($doc_product['model']) . "'";
  7164.                         $order_product_fields[] = "`price` = " . $doc_product['price'];
  7165.                         $order_product_fields[] = "`quantity` = " . $doc_product['quantity'];
  7166.                         $order_product_fields[] = "`total` = " . $doc_product['total'];
  7167.                         $order_product_fields[] = "`tax` = " . $doc_product['tax'];
  7168.                         // бонусные баллы
  7169.                         $order_product_fields[] = "`reward` = " . $doc_product['reward'];
  7170.  
  7171.                         // заменить опции, если есть
  7172.                         // считать опции с характеристики и записать в заказ у товара $order_product_id
  7173.                         $this->setOrderProductOptions($doc['order_id'], $doc_product['product_id'], $order_product_id, $product_feature_id);
  7174.                         if ($this->ERROR) return false;
  7175.  
  7176.                     } // if
  7177.  
  7178.                 } else {
  7179.                     // if (!isset($products[$key]))
  7180.                     // Добавить товар в документ
  7181.                     $order_product_id = $this->addOrderProduct($doc['order_id'], $doc_product['product_id'], $doc_product['price'], $doc_product['quantity'], $doc_product['total']);
  7182.                     if ($this->ERROR) return false;
  7183.  
  7184.                     if ($order_product_id && $product_feature_id) {
  7185.                         // добавлен товар и есть опции
  7186.                         $this->setOrderProductOptions($doc['order_id'], $doc_product['product_id'], $order_product_id, $product_feature_id);
  7187.                         if ($this->ERROR) return false;
  7188.                     }
  7189.  
  7190.                 } // if (isset($products[$key]))
  7191.  
  7192.                 $this->log("update: ".$update,2);
  7193.                 $this->log("fields: ",2);
  7194.                 $this->log($order_product_fields,2);
  7195.  
  7196.                 // если надо обновить поля товара в заказе
  7197.                 if ($order_product_fields) {
  7198.  
  7199.                     $fields = implode(", ", $order_product_fields);
  7200.  
  7201.                     if ($update) {
  7202.                         $this->query("UPDATE `" . DB_PREFIX . "order_product` SET " . $fields . " WHERE `order_product_id` = " . $products[$key]['order_product_id']);
  7203.                         $this->log("Товар '" . $doc_product['name'] . "' обновлен в заказе",2);
  7204.                     } else {
  7205.  
  7206.                     }
  7207.  
  7208.                 } else {
  7209.  
  7210.                     $this->log("Товар '" . $doc_product['name'] . "' в заказе не изменился",2);
  7211.                 }
  7212.             } // foreach
  7213.  
  7214.             foreach ($old_products as $product) {
  7215.                 $this->deleteOrderProduct($product['order_product_id']);
  7216.                 if ($this->ERROR) return false;
  7217.             }
  7218.         } // if
  7219.  
  7220.         $this->log("Документ обновлен",2);
  7221.  
  7222.         return true;
  7223.  
  7224.     } // updateDocument()
  7225.  
  7226.  
  7227.     /**
  7228.      * ver 2
  7229.      * update
  7230.      * Читает их XML реквизиты документа
  7231.      */
  7232.     private function parseDocumentRequisite($xml, &$doc) {
  7233.  
  7234.         foreach ($xml->ЗначениеРеквизита as $requisite) {
  7235.             // обрабатываем только товары
  7236.             $name   = (string)$requisite->Наименование;
  7237.             $value  = (string)$requisite->Значение;
  7238.             $this->log("> Реквизит документа: " . $name. " = " . $value,2);
  7239.             switch ($name){
  7240.                 case 'Номер по 1С':
  7241.                     $doc['invoice_no'] = $value;
  7242.                 break;
  7243.                 case 'Дата по 1С':
  7244.                     $doc['datetime'] = $value;
  7245.                 break;
  7246.                 case 'Проведен':
  7247.                     $doc['posted'] = $value;
  7248.                 break;
  7249.                 case 'Статус заказа':
  7250.                     $doc['status'] = $value;
  7251.                 break;
  7252.                 case 'Номер оплаты по 1С':
  7253.                     $doc['NumPay'] = $value;
  7254.                 break;
  7255.                 case 'Дата оплаты по 1С':
  7256.                     $doc['DataPay'] = $value;
  7257.                 break;
  7258.                 case 'Номер отгрузки по 1С':
  7259.                     $doc['NumSale'] = $value;
  7260.                 break;
  7261.                 case 'Дата отгрузки по 1С':
  7262.                     $doc['DateSale'] = $value;
  7263.                 break;
  7264.                 case 'ПометкаУдаления':
  7265.                     $doc['DeletionMark'] = $value;
  7266.                 break;
  7267.                 case 'Проведен':
  7268.                     $doc['Posted'] = $value;
  7269.                 break;
  7270.                 default:
  7271.             }
  7272.         }
  7273.         $this->log("Реквизиты документа прочитаны",2);
  7274.  
  7275.     } // parseDocumentRequisite()
  7276.  
  7277.     /**
  7278.      * ver 4
  7279.      * update 2017-05-30
  7280.      * Товары документа
  7281.      */
  7282.     private function parseDocumentProducts($xml, &$doc) {
  7283.  
  7284.         if (!$xml) {
  7285.             $this->ERROR = "parseDocumentProducts(): Нет данных в XML";
  7286.             return false;
  7287.         }
  7288.         $this->log($xml, 2);
  7289.         foreach ($xml->Товар as $product) {
  7290.             $guid       = explode("#", (string)$product->Ид);
  7291.             if (!$guid) {
  7292.                 $this->ERROR = "parseDocumentProducts(): не определен GUID товара";
  7293.                 return false;
  7294.             }
  7295.  
  7296.             $data = array();
  7297.  
  7298.             if ($product->Наименование) {
  7299.                 $data['name'] = (string)$product->Наименование;
  7300.             }
  7301.             if (isset($guid[0])) {
  7302.                 $data['product_guid'] = $guid[0];
  7303.                 $data['product_id'] = $this->getProductIdByGuid($data['product_guid']);
  7304.                 if (!$data['product_id']){
  7305.                     $this->ERROR = "parseDocumentProducts(): Товар '" . $data['name'] . "' не найден в базе по Ид '" . $data['product_guid'] . "'";
  7306.                     return false;
  7307.                 }
  7308.             } else {
  7309.                 $this->ERROR = "parseDocumentProducts(): Товар '" . $data['name'] . "' не может быть найден в базе по пустому Ид";
  7310.                 return false;
  7311.             }
  7312.             if (isset($guid[1])) {
  7313.                 $data['product_feature_guid'] = $guid[1];
  7314.                 $data['product_feature_id'] = $this->getProductFeatureIdByGuid($data['product_feature_guid']);
  7315.                 if (!$data['product_feature_id'])
  7316.                     $this->ERROR = "parseDocumentProducts(): Характеристика товара '" . $data['name'] . "' не найдена в базе по Ид '" . $data['product_feature_guid'] . "'";
  7317.                     return false;
  7318.             } else {
  7319.                 $data['product_feature_id'] = 0;
  7320.             }
  7321.             if ($product->Артикул) {
  7322.                 $data['sku'] = (string)$product->Артикул;
  7323.                 $data['model'] = (string)$product->Артикул;
  7324.             }
  7325.             if ($product->БазоваяЕдиница) {
  7326.                 $data['unit0'] = array(
  7327.                     'code'      => $product->БазоваяЕдиница->Наименование['Код'],
  7328.                     'name'      => $product->БазоваяЕдиница->Наименование['НаименованиеПолное'],
  7329.                     'eng'       => $product->БазоваяЕдиница->Наименование['МеждународноеСокращение']
  7330.                 );
  7331.             }
  7332.             if ($product->ЦенаЗаЕдиницу) {
  7333.                 $data['price'] = (float)$product->ЦенаЗаЕдиницу;
  7334.             }
  7335.             if ($product->Количество) {
  7336.                 $data['quantity'] = (float)$product->Количество;
  7337.             }
  7338.             if ($product->Сумма) {
  7339.                 $data['total'] = (float)$product->Сумма;
  7340.                 // налог временно нулевой
  7341.                 $data['tax'] = 0;
  7342.             }
  7343.             if ($product->Единица) {
  7344.                 $data['unit'] = array(
  7345.                     'unit_id'   => $this->getUnitId((string)$product->Единица),
  7346.                     'ratio'     => (string)$product->Коэффициент
  7347.                 );
  7348.  
  7349.             }
  7350.             $doc['products'][] = $data;
  7351.         }
  7352.  
  7353.         $this->log("Товары документа прочитаны", 2);
  7354.         return true;
  7355.  
  7356.     } // parseDocumentProducts()
  7357.  
  7358.  
  7359.     /**
  7360.      * ver 3
  7361.      * update 2017-05-18
  7362.      * Разбор классификатора
  7363.      */
  7364.     private function parseClassifier($xml) {
  7365.  
  7366.         $data = array();
  7367.         $data['guid']           = (string)$xml->Ид;
  7368.         $data['name']           = (string)$xml->Наименование;
  7369.         $this->setStore($data['name']);
  7370.  
  7371.         // Организация
  7372.         if ($xml->Владелец) {
  7373.             $this->log("Организация", 2);
  7374.             $data['owner']          = $this->parseOwner($xml->Владелец);
  7375.             unset($xml->Владелец);
  7376.         }
  7377.  
  7378.         if ($xml->ТипыЦен) {
  7379.             $this->log("Типы цен с классификатора (CML >= v2.09)", 2);
  7380.             $data['price_types'] = $this->parseClassifierPriceType($xml->ТипыЦен);
  7381.             if ($this->ERROR) return false;
  7382.             unset($xml->ТипыЦен);
  7383.         }
  7384.  
  7385.         if ($xml->Склады) {
  7386.             $this->log("Склады из классификатора (CML >= v2.09)", 2);
  7387.             $this->parseClassifierWarehouses($xml->Склады);
  7388.             if ($this->ERROR) return false;
  7389.             unset($xml->Склады);
  7390.         }
  7391.  
  7392.         if ($xml->ЕдиницыИзмерения) {
  7393.  
  7394.             $this->log("Единицы измерений из классификатора (CML >= v2.09)",2);
  7395.             $units = $this->parseClassifierUnits($xml->ЕдиницыИзмерения);
  7396.  
  7397.             if ($this->config->get('exchange1c_parse_unit_in_memory') == 1) {
  7398.                 $data['units'] = $units;
  7399.                 $this->log($units, 2);
  7400.             }
  7401.  
  7402.             if ($this->ERROR) return false;
  7403.             unset($xml->ЕдиницыИзмерения);
  7404.         }
  7405.  
  7406.         if ($xml->Свойства) {
  7407.  
  7408.             $this->log("Атрибуты (Свойства в ТС) из классификатора",2);
  7409.  
  7410.             $data['attributes'] = $this->parseClassifierAttributes($xml->Свойства);
  7411.  
  7412.             if ($this->ERROR) return false;
  7413.             unset($xml->Свойства);
  7414.         }
  7415.  
  7416.         if ($this->config->get('exchange1c_import_categories') == 1) {
  7417.  
  7418.             $categories = array();
  7419.  
  7420.             if ($this->config->get('exchange1c_import_categories_mode') == 'groups') {
  7421.  
  7422.                 // Группы номенклатуры
  7423.                 if ($xml->Группы) {
  7424.  
  7425.                     $categories = $this->parseClassifierCategories($xml->Группы, 0, $data);
  7426.  
  7427.                     if ($this->ERROR) return false;
  7428.  
  7429.                     unset($xml->Группы);
  7430.  
  7431.                     $this->log("Группы товаров из классификатора загружены",2);
  7432.                 }
  7433.  
  7434.             } else {
  7435.  
  7436.                 // Товарные категории
  7437.                 if ($xml->Категории) {
  7438.  
  7439.                     $categories = $this->parseClassifierProductCategories($xml->Категории, 0, $data);
  7440.  
  7441.                     if ($this->ERROR) return false;
  7442.  
  7443.                     unset($xml->Категории);
  7444.  
  7445.                     $this->log("Категории товаров из классификатора загружены",2);
  7446.                 }
  7447.             }
  7448.  
  7449.             if ($this->config->get('exchange1c_parse_categories_in_memory') == 1 && count($categories)) {
  7450.                 $data['categories'] = $categories;
  7451.             }
  7452.  
  7453.         }
  7454.  
  7455.         $this->log("Классификатор загружен", 2);
  7456.         return $data;
  7457.  
  7458.     } // parseClassifier()
  7459.  
  7460.  
  7461.     /**
  7462.      * ver 2
  7463.      * update 2017-05-30
  7464.      * Разбор документа
  7465.      */
  7466.     private function parseDocument($xml) {
  7467.  
  7468.         $order_guid     = (string)$xml->Ид;
  7469.         $order_id       = (string)$xml->Номер;
  7470.  
  7471.         $this->log($xml, 2);
  7472.  
  7473.         $doc = array(
  7474.             'order_id'      => $order_id,
  7475.             'date'          => (string)$xml->Дата,
  7476.             'time'          => (string)$xml->Время,
  7477.             'currency'      => (string)$xml->Валюта,
  7478.             'total'         => (float)$xml->Сумма,
  7479.             'doc_type'      => (string)$xml->ХозОперация,
  7480.             'date_pay'      => (string)$xml->ДатаПлатежа
  7481.         );
  7482.  
  7483.         // Просроченный платеж если date_pay будет меньше текущей
  7484.         if ($doc['date_pay']) {
  7485.             $this->log("По документу просрочена оплата");
  7486.         }
  7487.  
  7488.         $this->parseDocumentProducts($xml->Товары, $doc);
  7489.         if ($this->ERROR) return;
  7490.  
  7491.         $this->parseDocumentRequisite($xml->ЗначенияРеквизитов, $doc);
  7492.  
  7493.         $this->load->model('sale/order');
  7494.         $order = $this->model_sale_order->getOrder($order_id);
  7495.         if ($order) {
  7496.             $products = $this->model_sale_order->getOrderProducts($order_id);
  7497.         } else {
  7498.             return "Заказ #" . $doc['order_id'] . " не найден в базе";
  7499.         }
  7500.  
  7501.         $this->updateDocument($doc, $order, $products);
  7502.         if ($this->ERROR) return;
  7503.  
  7504.         $this->log("[i] Прочитан документ: Заказ #" . $order_id . ", Ид '" . $order_guid . "'");
  7505.  
  7506.         return true;
  7507.  
  7508.     } // parseDocument()
  7509.  
  7510.  
  7511.     /**
  7512.      * ver 3
  7513.      * update 2017-04-16
  7514.      * Импорт файла
  7515.      */
  7516.     public function importFile($importFile, $type) {
  7517.  
  7518.         // Функция будет сама определять что за файл загружается
  7519.         $this->log(">>>>>>>>>>>>>>>>>>>> НАЧАЛО ЗАГРУЗКИ ДАННЫХ <<<<<<<<<<<<<<<<<<<<");
  7520.         $this->log("Доступно памяти: " . sprintf("%.3f", memory_get_peak_usage() / 1024 / 1024) . " Mb",2);
  7521.  
  7522.         // Определим язык
  7523.         $this->getLanguageId($this->config->get('config_language'));
  7524.         $this->log("Язык загрузки по-умолчанию, id: " . $this->LANG_ID, 2);
  7525.  
  7526.         // Записываем единое текущее время обновления для запросов в базе данных
  7527.         $this->NOW = date('Y-m-d H:i:s');
  7528.  
  7529.         // Определение дополнительных полей
  7530.         $this->TAB_FIELDS = $this->config->get('exchange1c_table_fields');
  7531.  
  7532.         // Читаем XML
  7533.         libxml_use_internal_errors(true);
  7534.         $path_parts = pathinfo($importFile);
  7535.         $this->log("Файл: " . $path_parts['basename'], 2);
  7536.         $xml = @simplexml_load_file($importFile);
  7537.         if (!$xml) {
  7538.             $this->ERROR = "Файл не является стандартом XML, подробности в журнале\n";
  7539.             $this->ERROR .= implode("\n", libxml_get_errors());
  7540.             return $this->error();
  7541.         }
  7542.  
  7543.         // Файл стандарта Commerce ML
  7544.         $this->checkCML($xml);
  7545.         if ($this->ERROR) return $this->error();
  7546.  
  7547.         // IMPORT.XML, OFFERS.XML
  7548.         if ($xml->Классификатор) {
  7549.             $this->log(">>>>>>>>>>>>>>>>>>>> ЗАГРУЗКА КЛАССИФИКАТОРА <<<<<<<<<<<<<<<<<<<<",2);
  7550.             $classifier = $this->parseClassifier($xml->Классификатор);
  7551.             if ($this->ERROR) return $this->error();
  7552.             unset($xml->Классификатор);
  7553.         } else {
  7554.             // CML 2.08 + Битрикс
  7555.             $classifier = array();
  7556.         }
  7557.  
  7558.         if ($xml->Каталог) {
  7559.             // Запишем в лог дату и время начала обмена
  7560.  
  7561.             $this->log(">>>>>>>>>>>>>>>>>>>> ЗАГРУЗКА КАТАЛОГА <<<<<<<<<<<<<<<<<<<<",2);
  7562.             if (!isset($classifier)) {
  7563.                 $this->log("[i] Классификатор отсутствует! Все товары будут загружены в магазин по умолчанию!");
  7564.             }
  7565.  
  7566.             $this->parseDirectory($xml->Каталог, $classifier);
  7567.             if ($this->ERROR) return $this->error();
  7568.             unset($xml->Каталог);
  7569.         }
  7570.  
  7571.         // OFFERS.XML
  7572.         if ($xml->ПакетПредложений) {
  7573.             $this->log(">>>>>>>>>>>>>>>>>>>> ЗАГРУЗКА ПАКЕТА ПРЕДЛОЖЕНИЙ <<<<<<<<<<<<<<<<<<<<", 2);
  7574.  
  7575.             // Пакет предложений
  7576.             $this->parseOffersPack($xml->ПакетПредложений);
  7577.             if ($this->ERROR) return $this->error();
  7578.             unset($xml->ПакетПредложений);
  7579.         }
  7580.  
  7581.         // ORDERS.XML
  7582.         if ($xml->Документ) {
  7583.             $this->log(">>>>>>>>>>>>>>>>>>>> ЗАГРУЗКА ДОКУМЕНТОВ <<<<<<<<<<<<<<<<<<<<", 2);
  7584.  
  7585.             $this->clearLog();
  7586.  
  7587.             // Документ (заказ)
  7588.             foreach ($xml->Документ as $doc) {
  7589.                 $this->parseDocument($doc);
  7590.                 if ($this->ERROR) return $this->error();
  7591.             }
  7592.             unset($xml->Документ);
  7593.         }
  7594.         else {
  7595.             $this->log("[i] Не обработанные данные XML", 2);
  7596.             $this->log($xml,2);
  7597.         }
  7598.  
  7599.         $this->log(">>>>>>>>>>>>>>>>>>>> КОНЕЦ ЗАГРУЗКИ ДАННЫХ <<<<<<<<<<<<<<<<<<<<");
  7600.         return "";
  7601.     }
  7602.  
  7603.  
  7604.     /**
  7605.      * ver 5
  7606.      * update 2017-05-26
  7607.      * Определение дополнительных полей и запись их в глобальную переменную типа массив
  7608.      */
  7609.     public function defineTableFields() {
  7610.  
  7611.         $result = array();
  7612.  
  7613.         $this->log("Поиск в базе данных дополнительных полей",2);
  7614.  
  7615.         $tables = array(
  7616.             'manufacturer'              => array('noindex'=>1),
  7617.             'product_to_category'       => array('main_category'=>1),
  7618.             'product_description'       => array('meta_h1'=>''),
  7619.             'category_description'      => array('meta_h1'=>''),
  7620.             'manufacturer_description'  => array('name'=>'','meta_h1'=>'','meta_title'=>'','meta_description'=>'','meta_keyword'=>''),
  7621.             'product'                   => array('noindex'=>1),
  7622.             'order'                     => array('payment_inn'=>'','shipping_inn'=>'','patronymic'=>'','payment_patronymic'=>'','shipping_patronymic'=>''),
  7623.             'customer'                  => array('patronymic'=>''),
  7624.             'cart'                      => array('product_feature_id'=>0,'unit_id'=>0),
  7625.             'attributes_value'          => array(),
  7626.             'attributes_value_to_1c'    => array(),
  7627.             'cart'                      => array('product_feature_id'=>'', 'unit_id'=>''),
  7628.             'product_price'             => array('action'=>'')
  7629.         );
  7630.  
  7631.         foreach ($tables as $table => $fields) {
  7632.  
  7633.             $query = $this->query("SHOW TABLES LIKE '" . DB_PREFIX . $table . "'");
  7634.             if (!$query->num_rows) continue;
  7635.  
  7636.             $result[$table] = array();
  7637.  
  7638.             foreach ($fields as $field => $value) {
  7639.  
  7640.                 $query = $this->query("SHOW COLUMNS FROM `" . DB_PREFIX . $table . "` WHERE `field` = '" . $field . "'");
  7641.                 if (!$query->num_rows) continue;
  7642.  
  7643.                 $result[$table][$field] = $value;
  7644.             }
  7645.         }
  7646.         return $result;
  7647.  
  7648.     } // defineTableFields()
  7649.  
  7650.  
  7651.     /**
  7652.      * ver 1
  7653.      * update 2017-06-12
  7654.      * Устанавливает классификатор единиц измерений
  7655.      */
  7656.     public function installUnits() {
  7657.  
  7658.         // Классификатор единиц измерения
  7659.         $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "unit`");
  7660.         $this->db->query(
  7661.             "CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "unit` (
  7662.                 `unit_id`                   SMALLINT(6)     NOT NULL AUTO_INCREMENT COMMENT 'Счетчик',
  7663.                 `name`                      VARCHAR(255)    NOT NULL                COMMENT 'Наименование единицы измерения',
  7664.                 `number_code`               VARCHAR(5)      NOT NULL                COMMENT 'Код',
  7665.                 `rus_name1`                 VARCHAR(50)     DEFAULT '' NOT NULL     COMMENT 'Условное обозначение национальное',
  7666.                 `eng_name1`                 VARCHAR(50)     DEFAULT '' NOT NULL     COMMENT 'Условное обозначение международное',
  7667.                 `rus_name2`                 VARCHAR(50)     DEFAULT '' NOT NULL     COMMENT 'Кодовое буквенное обозначение национальное',
  7668.                 `eng_name2`                 VARCHAR(50)     DEFAULT '' NOT NULL     COMMENT 'Кодовое буквенное обозначение международное',
  7669.                 `unit_group_id`             TINYINT(4)      NOT NULL                COMMENT 'Группа единиц измерения',
  7670.                 `unit_type_id`              TINYINT(4)      NOT NULL                COMMENT 'Раздел/приложение в которое входит единица измерения',
  7671.                 `visible`                   TINYINT(4)      DEFAULT '1' NOT NULL    COMMENT 'Видимость',
  7672.                 `comment`                   VARCHAR(255)    DEFAULT '' NOT NULL     COMMENT 'Комментарий',
  7673.                 PRIMARY KEY (`unit_id`),
  7674.                 UNIQUE KEY number_code (`number_code`),
  7675.                 KEY unit_group_id (`unit_group_id`),
  7676.                 KEY unit_type_id (`unit_type_id`)
  7677.             ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Общероссийский классификатор единиц измерения ОКЕИ'"
  7678.         );
  7679.  
  7680.         $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "unit_group`");
  7681.         $this->db->query(
  7682.             "CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "unit_group` (
  7683.                 `unit_group_id`             TINYINT(4)      NOT NULL AUTO_INCREMENT COMMENT 'Счетчик',
  7684.                 `name`                      VARCHAR(255)    NOT NULL                COMMENT 'Наименование группы',
  7685.                 PRIMARY KEY (`unit_group_id`)
  7686.             ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Группы единиц измерения'"
  7687.         );
  7688.  
  7689.         $this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "unit_type`");
  7690.         $this->db->query(
  7691.             "CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "unit_type` (
  7692.                 `unit_type_id`          TINYINT(4)          NOT NULL AUTO_INCREMENT COMMENT 'Счетчик',
  7693.                 `name`                  VARCHAR(255)        NOT NULL                COMMENT 'Наименование раздела/приложения',
  7694.                 PRIMARY KEY (`unit_type_id`)
  7695.             ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Разделы/приложения, в которые включены единицы измерения'"
  7696.         );
  7697.  
  7698.         // Загрузка классификатора единиц измерений
  7699.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit_group` (unit_group_id, name) VALUES(6, 'Единицы времени')");
  7700.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit_group` (unit_group_id, name) VALUES(1, 'Единицы длины')");
  7701.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit_group` (unit_group_id, name) VALUES(4, 'Единицы массы')");
  7702.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit_group` (unit_group_id, name) VALUES(3, 'Единицы объема')");
  7703.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit_group` (unit_group_id, name) VALUES(2, 'Единицы площади')");
  7704.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit_group` (unit_group_id, name) VALUES(5, 'Технические единицы')");
  7705.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit_group` (unit_group_id, name) VALUES(7, 'Экономические единицы')");
  7706.  
  7707.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit_type` (unit_type_id, name) VALUES(1, 'Международные единицы измерения, включенные в ЕСКК')");
  7708.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit_type` (unit_type_id, name) VALUES(2, 'Национальные единицы измерения, включенные в ЕСКК')");
  7709.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit_type` (unit_type_id, name) VALUES(3, 'Международные единицы измерения, не включенные в ЕСКК')");
  7710.  
  7711.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(1, 'Миллиметр', '003', 'мм', 'mm', 'ММ', 'MMT', 1, 1, 1, '')");
  7712.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(2, 'Сантиметр', '004', 'см', 'cm', 'СМ', 'CMT', 1, 1, 1, '')");
  7713.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(3, 'Дециметр', '005', 'дм', 'dm', 'ДМ', 'DMT', 1, 1, 1, '')");
  7714.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(4, 'Метр', '006', 'м', 'm', 'М', 'MTR', 1, 1, 1, '')");
  7715.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(5, 'Километр; тысяча метров', '008', 'км; 10^3 м', 'km', 'КМ; ТЫС М', 'KMT', 1, 1, 1, '')");
  7716.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(6, 'Мегаметр; миллион метров', '009', 'Мм; 10^6 м', 'Mm', 'МЕГАМ; МЛН М', 'MAM', 1, 1, 1, '')");
  7717.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(7, 'Дюйм (25,4 мм)', '039', 'дюйм', 'in', 'ДЮЙМ', 'INH', 1, 1, 1, '')");
  7718.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(8, 'Фут (0,3048 м)', '041', 'фут', 'ft', 'ФУТ', 'FOT', 1, 1, 1, '')");
  7719.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(9, 'Ярд (0,9144 м)', '043', 'ярд', 'yd', 'ЯРД', 'YRD', 1, 1, 1, '')");
  7720.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(10, 'Морская миля (1852 м)', '047', 'миля', 'n mile', 'МИЛЬ', 'NMI', 1, 1, 1, '')");
  7721.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(11, 'Квадратный миллиметр', '050', 'мм2', 'mm2', 'ММ2', 'MMK', 2, 1, 1, '')");
  7722.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(12, 'Квадратный сантиметр', '051', 'см2', 'cm2', 'СМ2', 'CMK', 2, 1, 1, '')");
  7723.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(13, 'Квадратный дециметр', '053', 'дм2', 'dm2', 'ДМ2', 'DMK', 2, 1, 1, '')");
  7724.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(14, 'Квадратный метр', '055', 'м2', 'm2', 'М2', 'MTK', 2, 1, 1, '')");
  7725.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(15, 'Тысяча квадратных метров', '058', '10^3 м^2', 'daa', 'ТЫС М2', 'DAA', 2, 1, 1, '')");
  7726.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(16, 'Гектар', '059', 'га', 'ha', 'ГА', 'HAR', 2, 1, 1, '')");
  7727.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(17, 'Квадратный километр', '061', 'км2', 'km2', 'КМ2', 'KMK', 2, 1, 1, '')");
  7728.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(18, 'Квадратный дюйм (645,16 мм2)', '071', 'дюйм2', 'in2', 'ДЮЙМ2', 'INK', 2, 1, 1, '')");
  7729.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(19, 'Квадратный фут (0,092903 м2)', '073', 'фут2', 'ft2', 'ФУТ2', 'FTK', 2, 1, 1, '')");
  7730.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(20, 'Квадратный ярд (0,8361274 м2)', '075', 'ярд2', 'yd2', 'ЯРД2', 'YDK', 2, 1, 1, '')");
  7731.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(21, 'Ар (100 м2)', '109', 'а', 'a', 'АР', 'ARE', 2, 1, 1, '')");
  7732.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(22, 'Кубический миллиметр', '110', 'мм3', 'mm3', 'ММ3', 'MMQ', 3, 1, 1, '')");
  7733.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(23, 'Кубический сантиметр; миллилитр', '111', 'см3; мл', 'cm3; ml', 'СМ3; МЛ', 'CMQ; MLT', 3, 1, 1, '')");
  7734.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(24, 'Литр; кубический дециметр', '112', 'л; дм3', 'I; L; dm^3', 'Л; ДМ3', 'LTR; DMQ', 3, 1, 1, '')");
  7735.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(25, 'Кубический метр', '113', 'м3', 'm3', 'М3', 'MTQ', 3, 1, 1, '')");
  7736.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(26, 'Децилитр', '118', 'дл', 'dl', 'ДЛ', 'DLT', 3, 1, 1, '')");
  7737.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(27, 'Гектолитр', '122', 'гл', 'hl', 'ГЛ', 'HLT', 3, 1, 1, '')");
  7738.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(28, 'Мегалитр', '126', 'Мл', 'Ml', 'МЕГАЛ', 'MAL', 3, 1, 1, '')");
  7739.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(29, 'Кубический дюйм (16387,1 мм3)', '131', 'дюйм3', 'in3', 'ДЮЙМ3', 'INQ', 3, 1, 1, '')");
  7740.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(30, 'Кубический фут (0,02831685 м3)', '132', 'фут3', 'ft3', 'ФУТ3', 'FTQ', 3, 1, 1, '')");
  7741.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(31, 'Кубический ярд (0,764555 м3)', '133', 'ярд3', 'yd3', 'ЯРД3', 'YDQ', 3, 1, 1, '')");
  7742.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(32, 'Миллион кубических метров', '159', '10^6 м3', '10^6 m3', 'МЛН М3', 'HMQ', 3, 1, 1, '')");
  7743.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(33, 'Гектограмм', '160', 'гг', 'hg', 'ГГ', 'HGM', 4, 1, 1, '')");
  7744.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(34, 'Миллиграмм', '161', 'мг', 'mg', 'МГ', 'MGM', 4, 1, 1, '')");
  7745.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(35, 'Метрический карат', '162', 'кар', 'МС', 'КАР', 'CTM', 4, 1, 1, '')");
  7746.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(36, 'Грамм', '163', 'г', 'g', 'Г', 'GRM', 4, 1, 1, '')");
  7747.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(37, 'Килограмм', '166', 'кг', 'kg', 'КГ', 'KGM', 4, 1, 1, '')");
  7748.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(38, 'Тонна; метрическая тонна (1000 кг)', '168', 'т', 't', 'Т', 'TNE', 4, 1, 1, '')");
  7749.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(39, 'Килотонна', '170', '10^3 т', 'kt', 'КТ', 'KTN', 4, 1, 1, '')");
  7750.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(40, 'Сантиграмм', '173', 'сг', 'cg', 'СГ', 'CGM', 4, 1, 1, '')");
  7751.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(41, 'Брутто-регистровая тонна (2,8316 м3)', '181', 'БРТ', '-', 'БРУТТ. РЕГИСТР Т', 'GRT', 4, 1, 1, '')");
  7752.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(42, 'Грузоподъемность в метрических тоннах', '185', 'т грп', '-', 'Т ГРУЗОПОД', 'CCT', 4, 1, 1, '')");
  7753.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(43, 'Центнер (метрический) (100 кг); гектокилограмм; квинтал1 (метрический); децитонна', '206', 'ц', 'q; 10^2 kg', 'Ц', 'DTN', 4, 1, 1, '')");
  7754.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(44, 'Ватт', '212', 'Вт', 'W', 'ВТ', 'WTT', 5, 1, 1, '')");
  7755.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(45, 'Киловатт', '214', 'кВт', 'kW', 'КВТ', 'KWT', 5, 1, 1, '')");
  7756.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(46, 'Мегаватт; тысяча киловатт', '215', 'МВт; 10^3 кВт', 'MW', 'МЕГАВТ; ТЫС КВТ', 'MAW', 5, 1, 1, '')");
  7757.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(47, 'Вольт', '222', 'В', 'V', 'В', 'VLT', 5, 1, 1, '')");
  7758.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(48, 'Киловольт', '223', 'кВ', 'kV', 'КВ', 'KVT', 5, 1, 1, '')");
  7759.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(49, 'Киловольт-ампер', '227', 'кВ.А', 'kV.A', 'КВ.А', 'KVA', 5, 1, 1, '')");
  7760.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(50, 'Мегавольт-ампер (тысяча киловольт-ампер)', '228', 'МВ.А', 'MV.A', 'МЕГАВ.А', 'MVA', 5, 1, 1, '')");
  7761.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(51, 'Киловар', '230', 'квар', 'kVAR', 'КВАР', 'KVR', 5, 1, 1, '')");
  7762.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(52, 'Ватт-час', '243', 'Вт.ч', 'W.h', 'ВТ.Ч', 'WHR', 5, 1, 1, '')");
  7763.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(53, 'Киловатт-час', '245', 'кВт.ч', 'kW.h', 'КВТ.Ч', 'KWH', 5, 1, 1, '')");
  7764.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(54, 'Мегаватт-час; 1000 киловатт-часов', '246', 'МВт.ч; 10^3 кВт.ч', 'МW.h', 'МЕГАВТ.Ч; ТЫС КВТ.Ч', 'MWH', 5, 1, 1, '')");
  7765.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(55, 'Гигаватт-час (миллион киловатт-часов)', '247', 'ГВт.ч', 'GW.h', 'ГИГАВТ.Ч', 'GWH', 5, 1, 1, '')");
  7766.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(56, 'Ампер', '260', 'А', 'A', 'А', 'AMP', 5, 1, 1, '')");
  7767.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(57, 'Ампер-час (3,6 кКл)', '263', 'А.ч', 'A.h', 'А.Ч', 'AMH', 5, 1, 1, '')");
  7768.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(58, 'Тысяча ампер-часов', '264', '10^3 А.ч', '10^3 A.h', 'ТЫС А.Ч', 'TAH', 5, 1, 1, '')");
  7769.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(59, 'Кулон', '270', 'Кл', 'C', 'КЛ', 'COU', 5, 1, 1, '')");
  7770.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(60, 'Джоуль', '271', 'Дж', 'J', 'ДЖ', 'JOU', 5, 1, 1, '')");
  7771.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(61, 'Килоджоуль', '273', 'кДж', 'kJ', 'КДЖ', 'KJO', 5, 1, 1, '')");
  7772.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(62, 'Ом', '274', 'Ом', '<омега>', 'ОМ', 'OHM', 5, 1, 1, '')");
  7773.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(63, 'Градус Цельсия', '280', 'град. C', 'град. C', 'ГРАД ЦЕЛЬС', 'CEL', 5, 1, 1, '')");
  7774.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(64, 'Градус Фаренгейта', '281', 'град. F', 'град. F', 'ГРАД ФАРЕНГ', 'FAN', 5, 1, 1, '')");
  7775.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(65, 'Кандела', '282', 'кд', 'cd', 'КД', 'CDL', 5, 1, 1, '')");
  7776.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(66, 'Люкс', '283', 'лк', 'lx', 'ЛК', 'LUX', 5, 1, 1, '')");
  7777.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(67, 'Люмен', '284', 'лм', 'lm', 'ЛМ', 'LUM', 5, 1, 1, '')");
  7778.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(68, 'Кельвин', '288', 'K', 'K', 'К', 'KEL', 5, 1, 1, '')");
  7779.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(69, 'Ньютон', '289', 'Н', 'N', 'Н', 'NEW', 5, 1, 1, '')");
  7780.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(70, 'Герц', '290', 'Гц', 'Hz', 'ГЦ', 'HTZ', 5, 1, 1, '')");
  7781.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(71, 'Килогерц', '291', 'кГц', 'kHz', 'КГЦ', 'KHZ', 5, 1, 1, '')");
  7782.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(72, 'Мегагерц', '292', 'МГц', 'MHz', 'МЕГАГЦ', 'MHZ', 5, 1, 1, '')");
  7783.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(73, 'Паскаль', '294', 'Па', 'Pa', 'ПА', 'PAL', 5, 1, 1, '')");
  7784.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(74, 'Сименс', '296', 'См', 'S', 'СИ', 'SIE', 5, 1, 1, '')");
  7785.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(75, 'Килопаскаль', '297', 'кПа', 'kPa', 'КПА', 'KPA', 5, 1, 1, '')");
  7786.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(76, 'Мегапаскаль', '298', 'МПа', 'MPa', 'МЕГАПА', 'MPA', 5, 1, 1, '')");
  7787.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(77, 'Физическая атмосфера (101325 Па)', '300', 'атм', 'atm', 'АТМ', 'ATM', 5, 1, 1, '')");
  7788.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(78, 'Техническая атмосфера (98066,5 Па)', '301', 'ат', 'at', 'АТТ', 'ATT', 5, 1, 1, '')");
  7789.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(79, 'Гигабеккерель', '302', 'ГБк', 'GBq', 'ГИГАБК', 'GBQ', 5, 1, 1, '')");
  7790.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(80, 'Милликюри', '304', 'мКи', 'mCi', 'МКИ', 'MCU', 5, 1, 1, '')");
  7791.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(81, 'Кюри', '305', 'Ки', 'Ci', 'КИ', 'CUR', 5, 1, 1, '')");
  7792.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(82, 'Грамм делящихся изотопов', '306', 'г Д/И', 'g fissile isotopes', 'Г ДЕЛЯЩ ИЗОТОП', 'GFI', 5, 1, 1, '')");
  7793.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(83, 'Миллибар', '308', 'мб', 'mbar', 'МБАР', 'MBR', 5, 1, 1, '')");
  7794.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(84, 'Бар', '309', 'бар', 'bar', 'БАР', 'BAR', 5, 1, 1, '')");
  7795.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(85, 'Гектобар', '310', 'гб', 'hbar', 'ГБАР', 'HBA', 5, 1, 1, '')");
  7796.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(86, 'Килобар', '312', 'кб', 'kbar', 'КБАР', 'KBA', 5, 1, 1, '')");
  7797.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(87, 'Фарад', '314', 'Ф', 'F', 'Ф', 'FAR', 5, 1, 1, '')");
  7798.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(88, 'Килограмм на кубический метр', '316', 'кг/м3', 'kg/m3', 'КГ/М3', 'KMQ', 5, 1, 1, '')");
  7799.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(89, 'Беккерель', '323', 'Бк', 'Bq', 'БК', 'BQL', 5, 1, 1, '')");
  7800.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(90, 'Вебер', '324', 'Вб', 'Wb', 'ВБ', 'WEB', 5, 1, 1, '')");
  7801.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(91, 'Узел (миля/ч)', '327', 'уз', 'kn', 'УЗ', 'KNT', 5, 1, 1, '')");
  7802.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(92, 'Метр в секунду', '328', 'м/с', 'm/s', 'М/С', 'MTS', 5, 1, 1, '')");
  7803.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(93, 'Оборот в секунду', '330', 'об/с', 'r/s', 'ОБ/С', 'RPS', 5, 1, 1, '')");
  7804.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(94, 'Оборот в минуту', '331', 'об/мин', 'r/min', 'ОБ/МИН', 'RPM', 5, 1, 1, '')");
  7805.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(95, 'Километр в час', '333', 'км/ч', 'km/h', 'КМ/Ч', 'KMH', 5, 1, 1, '')");
  7806.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(96, 'Метр на секунду в квадрате', '335', 'м/с2', 'm/s2', 'М/С2', 'MSK', 5, 1, 1, '')");
  7807.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(97, 'Кулон на килограмм', '349', 'Кл/кг', 'C/kg', 'КЛ/КГ', 'CKG', 5, 1, 1, '')");
  7808.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(98, 'Секунда', '354', 'с', 's', 'С', 'SEC', 6, 1, 1, '')");
  7809.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(99, 'Минута', '355', 'мин', 'min', 'МИН', 'MIN', 6, 1, 1, '')");
  7810.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(100, 'Час', '356', 'ч', 'h', 'Ч', 'HUR', 6, 1, 1, '')");
  7811.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(101, 'Сутки', '359', 'сут; дн', 'd', 'СУТ; ДН', 'DAY', 6, 1, 1, '')");
  7812.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(102, 'Неделя', '360', 'нед', '-', 'НЕД', 'WEE', 6, 1, 1, '')");
  7813.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(103, 'Декада', '361', 'дек', '-', 'ДЕК', 'DAD', 6, 1, 1, '')");
  7814.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(104, 'Месяц', '362', 'мес', '-', 'МЕС', 'MON', 6, 1, 1, '')");
  7815.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(105, 'Квартал', '364', 'кварт', '-', 'КВАРТ', 'QAN', 6, 1, 1, '')");
  7816.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(106, 'Полугодие', '365', 'полгода', '-', 'ПОЛГОД', 'SAN', 6, 1, 1, '')");
  7817.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(107, 'Год', '366', 'г; лет', 'a', 'ГОД; ЛЕТ', 'ANN', 6, 1, 1, '')");
  7818.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(108, 'Десятилетие', '368', 'деслет', '-', 'ДЕСЛЕТ', 'DEC', 6, 1, 1, '')");
  7819.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(109, 'Килограмм в секунду', '499', 'кг/с', '-', 'КГ/С', 'KGS', 7, 1, 1, '')");
  7820.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(110, 'Тонна пара в час', '533', 'т пар/ч', '-', 'Т ПАР/Ч', 'TSH', 7, 1, 1, '')");
  7821.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(111, 'Кубический метр в секунду', '596', 'м3/с', 'm3/s', 'М3/С', 'MQS', 7, 1, 1, '')");
  7822.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(112, 'Кубический метр в час', '598', 'м3/ч', 'm3/h', 'М3/Ч', 'MQH', 7, 1, 1, '')");
  7823.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(113, 'Тысяча кубических метров в сутки', '599', '10^3 м3/сут', '-', 'ТЫС М3/СУТ', 'TQD', 7, 1, 1, '')");
  7824.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(114, 'Бобина', '616', 'боб', '-', 'БОБ', 'NBB', 7, 1, 1, '')");
  7825.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(115, 'Лист', '625', 'л.', '-', 'ЛИСТ', 'LEF', 7, 1, 1, '')");
  7826.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(116, 'Сто листов', '626', '100 л.', '-', '100 ЛИСТ', 'CLF', 7, 1, 1, '')");
  7827.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(117, 'Тысяча стандартных условных кирпичей', '630', 'тыс станд. усл. кирп', '-', 'ТЫС СТАНД УСЛ КИРП', 'MBE', 7, 1, 1, '')");
  7828.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(118, 'Дюжина (12 шт.)', '641', 'дюжина', 'Doz; 12', 'ДЮЖИНА', 'DZN', 7, 1, 1, '')");
  7829.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(119, 'Изделие', '657', 'изд', '-', 'ИЗД', 'NAR', 7, 1, 1, '')");
  7830.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(120, 'Сто ящиков', '683', '100 ящ.', 'Hbx', '100 ЯЩ', 'HBX', 7, 1, 1, '')");
  7831.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(121, 'Набор', '704', 'набор', '-', 'НАБОР', 'SET', 7, 1, 1, '')");
  7832.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(122, 'Пара (2 шт.)', '715', 'пар', 'pr; 2', 'ПАР', 'NPR', 7, 1, 1, '')");
  7833.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(123, 'Два десятка', '730', '20', '20', '2 ДЕС', 'SCO', 7, 1, 1, '')");
  7834.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(124, 'Десять пар', '732', '10 пар', '-', 'ДЕС ПАР', 'TPR', 7, 1, 1, '')");
  7835.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(125, 'Дюжина пар', '733', 'дюжина пар', '-', 'ДЮЖИНА ПАР', 'DPR', 7, 1, 1, '')");
  7836.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(126, 'Посылка', '734', 'посыл', '-', 'ПОСЫЛ', 'NPL', 7, 1, 1, '')");
  7837.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(127, 'Часть', '735', 'часть', '-', 'ЧАСТЬ', 'NPT', 7, 1, 1, '')");
  7838.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(128, 'Рулон', '736', 'рул', '-', 'РУЛ', 'NPL', 7, 1, 1, '')");
  7839.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(129, 'Дюжина рулонов', '737', 'дюжина рул', '-', 'ДЮЖИНА РУЛ', 'DRL', 7, 1, 1, '')");
  7840.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(130, 'Дюжина штук', '740', 'дюжина шт', '-', 'ДЮЖИНА ШТ', 'DPC', 7, 1, 1, '')");
  7841.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(131, 'Элемент', '745', 'элем', 'CI', 'ЭЛЕМ', 'NCL', 7, 1, 1, '')");
  7842.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(132, 'Упаковка', '778', 'упак', '-', 'УПАК', 'NMP', 7, 1, 1, '')");
  7843.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(133, 'Дюжина упаковок', '780', 'дюжина упак', '-', 'ДЮЖИНА УПАК', 'DZP', 7, 1, 1, '')");
  7844.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(134, 'Сто упаковок', '781', '100 упак', '-', '100 УПАК', 'CNP', 7, 1, 1, '')");
  7845.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(135, 'Штука', '796', 'шт', 'pc; 1', 'ШТ', 'PCE; NMB', 7, 1, 1, '')");
  7846.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(136, 'Сто штук', '797', '100 шт', '100', '100 ШТ', 'CEN', 7, 1, 1, '')");
  7847.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(137, 'Тысяча штук', '798', 'тыс. шт; 1000 шт', '1000', 'ТЫС ШТ', 'MIL', 7, 1, 1, '')");
  7848.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(138, 'Миллион штук', '799', '10^6 шт', '10^6', 'МЛН ШТ', 'MIO', 7, 1, 1, '')");
  7849.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(139, 'Миллиард штук', '800', '10^9 шт', '10^9', 'МЛРД ШТ', 'MLD', 7, 1, 1, '')");
  7850.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(140, 'Биллион штук (Европа); триллион штук', '801', '10^12 шт', '10^12', 'БИЛЛ ШТ (ЕВР); ТРИЛЛ ШТ', 'BIL', 7, 1, 1, '')");
  7851.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(141, 'Квинтильон штук (Европа)', '802', '10^18 шт', '10^18', 'КВИНТ ШТ', 'TRL', 7, 1, 1, '')");
  7852.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(142, 'Крепость спирта по массе', '820', 'креп. спирта по массе', '% mds', 'КРЕП СПИРТ ПО МАССЕ', 'ASM', 7, 1, 1, '')");
  7853.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(143, 'Крепость спирта по объему', '821', 'креп. спирта по объему', '% vol', 'КРЕП СПИРТ ПО ОБЪЕМ', 'ASV', 7, 1, 1, '')");
  7854.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(144, 'Литр чистого (100%) спирта', '831', 'л 100% спирта', '-', 'Л ЧИСТ СПИРТ', 'LPA', 7, 1, 1, '')");
  7855.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(145, 'Гектолитр чистого (100%) спирта', '833', 'Гл 100% спирта', '-', 'ГЛ ЧИСТ СПИРТ', 'HPA', 7, 1, 1, '')");
  7856.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(146, 'Килограмм пероксида водорода', '841', 'кг H2О2', '-', 'КГ ПЕРОКСИД ВОДОРОДА', '-', 7, 1, 1, '')");
  7857.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(147, 'Килограмм 90%-го сухого вещества', '845', 'кг 90% с/в', '-', 'КГ 90 ПРОЦ СУХ ВЕЩ', 'KSD', 7, 1, 1, '')");
  7858.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(148, 'Тонна 90%-го сухого вещества', '847', 'т 90% с/в', '-', 'Т 90 ПРОЦ СУХ ВЕЩ', 'TSD', 7, 1, 1, '')");
  7859.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(149, 'Килограмм оксида калия', '852', 'кг К2О', '-', 'КГ ОКСИД КАЛИЯ', 'KPO', 7, 1, 1, '')");
  7860.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(150, 'Килограмм гидроксида калия', '859', 'кг КОН', '-', 'КГ ГИДРОКСИД КАЛИЯ', 'KPH', 7, 1, 1, '')");
  7861.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(151, 'Килограмм азота', '861', 'кг N', '-', 'КГ АЗОТ', 'KNI', 7, 1, 1, '')");
  7862.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(152, 'Килограмм гидроксида натрия', '863', 'кг NaOH', '-', 'КГ ГИДРОКСИД НАТРИЯ', 'KSH', 7, 1, 1, '')");
  7863.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(153, 'Килограмм пятиокиси фосфора', '865', 'кг Р2О5', '-', 'КГ ПЯТИОКИСЬ ФОСФОРА', 'KPP', 7, 1, 1, '')");
  7864.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(154, 'Килограмм урана', '867', 'кг U', '-', 'КГ УРАН', 'KUR', 7, 1, 1, '')");
  7865.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(155, 'Погонный метр', '018', 'пог. м', '', 'ПОГ М', '', 1, 2, 1, '')");
  7866.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(156, 'Тысяча погонных метров', '019', '10^3 пог. м', '', 'ТЫС ПОГ М', '', 1, 2, 1, '')");
  7867.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(157, 'Условный метр', '020', 'усл. м', '', 'УСЛ М', '', 1, 2, 1, '')");
  7868.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(158, 'Тысяча условных метров', '048', '10^3 усл. м', '', 'ТЫС УСЛ М', '', 1, 2, 1, '')");
  7869.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(159, 'Километр условных труб', '049', 'км усл. труб', '', 'КМ УСЛ ТРУБ', '', 1, 2, 1, '')");
  7870.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(160, 'Тысяча квадратных дециметров', '054', '10^3 дм2', '', 'ТЫС ДМ2', '', 2, 2, 1, '')");
  7871.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(161, 'Миллион квадратных дециметров', '056', '10^6 дм2', '', 'МЛН ДМ2', '', 2, 2, 1, '')");
  7872.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(162, 'Миллион квадратных метров', '057', '10^6 м2', '', 'МЛН М2', '', 2, 2, 1, '')");
  7873.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(163, 'Тысяча гектаров', '060', '10^3 га', '', 'ТЫС ГА', '', 2, 2, 1, '')");
  7874.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(164, 'Условный квадратный метр', '062', 'усл. м2', '', 'УСЛ М2', '', 2, 2, 1, '')");
  7875.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(165, 'Тысяча условных квадратных метров', '063', '10^3 усл. м2', '', 'ТЫС УСЛ М2', '', 2, 2, 1, '')");
  7876.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(166, 'Миллион условных квадратных метров', '064', '10^6 усл. м2', '', 'МЛН УСЛ М2', '', 2, 2, 1, '')");
  7877.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(167, 'Квадратный метр общей площади', '081', 'м2 общ. пл', '', 'М2 ОБЩ ПЛ', '', 2, 2, 1, '')");
  7878.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(168, 'Тысяча квадратных метров общей площади', '082', '10^3 м2 общ. пл', '', 'ТЫС М2 ОБЩ ПЛ', '', 2, 2, 1, '')");
  7879.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(169, 'Миллион квадратных метров общей площади', '083', '10^6 м2 общ. пл', '', 'МЛН М2. ОБЩ ПЛ', '', 2, 2, 1, '')");
  7880.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(170, 'Квадратный метр жилой площади', '084', 'м2 жил. пл', '', 'М2 ЖИЛ ПЛ', '', 2, 2, 1, '')");
  7881.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(171, 'Тысяча квадратных метров жилой площади', '085', '10^3 м2 жил. пл', '', 'ТЫС М2 ЖИЛ ПЛ', '', 2, 2, 1, '')");
  7882.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(172, 'Миллион квадратных метров жилой площади', '086', '10^6 м2 жил. пл', '', 'МЛН М2 ЖИЛ ПЛ', '', 2, 2, 1, '')");
  7883.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(173, 'Квадратный метр учебно-лабораторных зданий', '087', 'м2 уч. лаб. здан', '', 'М2 УЧ.ЛАБ ЗДАН', '', 2, 2, 1, '')");
  7884.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(174, 'Тысяча квадратных метров учебно-лабораторных зданий', '088', '10^3 м2 уч. лаб. здан', '', 'ТЫС М2 УЧ. ЛАБ ЗДАН', '', 2, 2, 1, '')");
  7885.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(175, 'Миллион квадратных метров в двухмиллиметровом исчислении', '089', '10^6 м2 2 мм исч', '', 'МЛН М2 2ММ ИСЧ', '', 2, 2, 1, '')");
  7886.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(176, 'Тысяча кубических метров', '114', '10^3 м3', '', 'ТЫС М3', '', 3, 2, 1, '')");
  7887.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(177, 'Миллиард кубических метров', '115', '10^9 м3', '', 'МЛРД М3', '', 3, 2, 1, '')");
  7888.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(178, 'Декалитр', '116', 'дкл', '', 'ДКЛ', '', 3, 2, 1, '')");
  7889.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(179, 'Тысяча декалитров', '119', '10^3 дкл', '', 'ТЫС ДКЛ', '', 3, 2, 1, '')");
  7890.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(180, 'Миллион декалитров', '120', '10^6 дкл', '', 'МЛН ДКЛ', '', 3, 2, 1, '')");
  7891.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(181, 'Плотный кубический метр', '121', 'плотн. м3', '', 'ПЛОТН М3', '', 3, 2, 1, '')");
  7892.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(182, 'Условный кубический метр', '123', 'усл. м3', '', 'УСЛ М3', '', 3, 2, 1, '')");
  7893.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(183, 'Тысяча условных кубических метров', '124', '10^3 усл. м3', '', 'ТЫС УСЛ М3', '', 3, 2, 1, '')");
  7894.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(184, 'Миллион кубических метров переработки газа', '125', '10^6 м3 перераб. газа', '', 'МЛН М3 ПЕРЕРАБ ГАЗА', '', 3, 2, 1, '')");
  7895.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(185, 'Тысяча плотных кубических метров', '127', '10^3 плотн. м3', '', 'ТЫС ПЛОТН М3', '', 3, 2, 1, '')");
  7896.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(186, 'Тысяча полулитров', '128', '10^3 пол. л', '', 'ТЫС ПОЛ Л', '', 3, 2, 1, '')");
  7897.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(187, 'Миллион полулитров', '129', '10^6 пол. л', '', 'МЛН ПОЛ Л', '', 3, 2, 1, '')");
  7898.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(188, 'Тысяча литров; 1000 литров', '130', '10^3 л; 1000 л', '', 'ТЫС Л', '', 3, 2, 1, '')");
  7899.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(189, 'Тысяча каратов метрических', '165', '10^3 кар', '', 'ТЫС КАР', '', 4, 2, 1, '')");
  7900.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(190, 'Миллион каратов метрических', '167', '10^6 кар', '', 'МЛН КАР', '', 4, 2, 1, '')");
  7901.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(191, 'Тысяча тонн', '169', '10^3 т', '', 'ТЫС Т', '', 4, 2, 1, '')");
  7902.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(192, 'Миллион тонн', '171', '10^6 т', '', 'МЛН Т', '', 4, 2, 1, '')");
  7903.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(193, 'Тонна условного топлива', '172', 'т усл. топл', '', 'Т УСЛ ТОПЛ', '', 4, 2, 1, '')");
  7904.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(194, 'Тысяча тонн условного топлива', '175', '10^3 т усл. топл', '', 'ТЫС Т УСЛ ТОПЛ', '', 4, 2, 1, '')");
  7905.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(195, 'Миллион тонн условного топлива', '176', '10^6 т усл. топл', '', 'МЛН Т УСЛ ТОПЛ', '', 4, 2, 1, '')");
  7906.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(196, 'Тысяча тонн единовременного хранения', '177', '10^3 т единовр. хран', '', 'ТЫС Т ЕДИНОВР ХРАН', '', 4, 2, 1, '')");
  7907.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(197, 'Тысяча тонн переработки', '178', '10^3 т перераб', '', 'ТЫС Т ПЕРЕРАБ', '', 4, 2, 1, '')");
  7908.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(198, 'Условная тонна', '179', 'усл. т', '', 'УСЛ Т', '', 4, 2, 1, '')");
  7909.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(199, 'Тысяча центнеров', '207', '10^3 ц', '', 'ТЫС Ц', '', 4, 2, 1, '')");
  7910.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(200, 'Вольт-ампер', '226', 'В.А', '', 'В.А', '', 5, 2, 1, '')");
  7911.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(201, 'Метр в час', '231', 'м/ч', '', 'М/Ч', '', 5, 2, 1, '')");
  7912.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(202, 'Килокалория', '232', 'ккал', '', 'ККАЛ', '', 5, 2, 1, '')");
  7913.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(203, 'Гигакалория', '233', 'Гкал', '', 'ГИГАКАЛ', '', 5, 2, 1, '')");
  7914.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(204, 'Тысяча гигакалорий', '234', '10^3 Гкал', '', 'ТЫС ГИГАКАЛ', '', 5, 2, 1, '')");
  7915.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(205, 'Миллион гигакалорий', '235', '10^6 Гкал', '', 'МЛН ГИГАКАЛ', '', 5, 2, 1, '')");
  7916.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(206, 'Калория в час', '236', 'кал/ч', '', 'КАЛ/Ч', '', 5, 2, 1, '')");
  7917.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(207, 'Килокалория в час', '237', 'ккал/ч', '', 'ККАЛ/Ч', '', 5, 2, 1, '')");
  7918.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(208, 'Гигакалория в час', '238', 'Гкал/ч', '', 'ГИГАКАЛ/Ч', '', 5, 2, 1, '')");
  7919.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(209, 'Тысяча гигакалорий в час', '239', '10^3 Гкал/ч', '', 'ТЫС ГИГАКАЛ/Ч', '', 5, 2, 1, '')");
  7920.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(210, 'Миллион ампер-часов', '241', '10^6 А.ч', '', 'МЛН А.Ч', '', 5, 2, 1, '')");
  7921.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(211, 'Миллион киловольт-ампер', '242', '10^6 кВ.А', '', 'МЛН КВ.А', '', 5, 2, 1, '')");
  7922.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(212, 'Киловольт-ампер реактивный', '248', 'кВ.А Р', '', 'КВ.А Р', '', 5, 2, 1, '')");
  7923.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(213, 'Миллиард киловатт-часов', '249', '10^9 кВт.ч', '', 'МЛРД КВТ.Ч', '', 5, 2, 1, '')");
  7924.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(214, 'Тысяча киловольт-ампер реактивных', '250', '10^3 кВ.А Р', '', 'ТЫС КВ.А Р', '', 5, 2, 1, '')");
  7925.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(215, 'Лошадиная сила', '251', 'л. с', '', 'ЛС', '', 5, 2, 1, '')");
  7926.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(216, 'Тысяча лошадиных сил', '252', '10^3 л. с', '', 'ТЫС ЛС', '', 5, 2, 1, '')");
  7927.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(217, 'Миллион лошадиных сил', '253', '10^6 л. с', '', 'МЛН ЛС', '', 5, 2, 1, '')");
  7928.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(218, 'Бит', '254', 'бит', '', 'БИТ', '', 5, 2, 1, '')");
  7929.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(219, 'Байт', '255', 'бай', '', 'БАЙТ', '', 5, 2, 1, '')");
  7930.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(220, 'Килобайт', '256', 'кбайт', '', 'КБАЙТ', '', 5, 2, 1, '')");
  7931.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(221, 'Мегабайт', '257', 'Мбайт', '', 'МБАЙТ', '', 5, 2, 1, '')");
  7932.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(222, 'Бод', '258', 'бод', '', 'БОД', '', 5, 2, 1, '')");
  7933.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(223, 'Генри', '287', 'Гн', '', 'ГН', '', 5, 2, 1, '')");
  7934.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(224, 'Тесла', '313', 'Тл', '', 'ТЛ', '', 5, 2, 1, '')");
  7935.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(225, 'Килограмм на квадратный сантиметр', '317', 'кг/см^2', '', 'КГ/СМ2', '', 5, 2, 1, '')");
  7936.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(226, 'Миллиметр водяного столба', '337', 'мм вод. ст', '', 'ММ ВОД СТ', '', 5, 2, 1, '')");
  7937.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(227, 'Миллиметр ртутного столба', '338', 'мм рт. ст', '', 'ММ РТ СТ', '', 5, 2, 1, '')");
  7938.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(228, 'Сантиметр водяного столба', '339', 'см вод. ст', '', 'СМ ВОД СТ', '', 5, 2, 1, '')");
  7939.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(229, 'Микросекунда', '352', 'мкс', '', 'МКС', '', 6, 2, 1, '')");
  7940.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(230, 'Миллисекунда', '353', 'млс', '', 'МЛС', '', 6, 2, 1, '')");
  7941.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(231, 'Рубль', '383', 'руб', '', 'РУБ', '', 7, 2, 1, '')");
  7942.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(232, 'Тысяча рублей', '384', '10^3 руб', '', 'ТЫС РУБ', '', 7, 2, 1, '')");
  7943.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(233, 'Миллион рублей', '385', '10^6 руб', '', 'МЛН РУБ', '', 7, 2, 1, '')");
  7944.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(234, 'Миллиард рублей', '386', '10^9 руб', '', 'МЛРД РУБ', '', 7, 2, 1, '')");
  7945.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(235, 'Триллион рублей', '387', '10^12 руб', '', 'ТРИЛЛ РУБ', '', 7, 2, 1, '')");
  7946.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(236, 'Квадрильон рублей', '388', '10^15 руб', '', 'КВАДР РУБ', '', 7, 2, 1, '')");
  7947.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(237, 'Пассажиро-километр', '414', 'пасс.км', '', 'ПАСС.КМ', '', 7, 2, 1, '')");
  7948.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(238, 'Пассажирское место (пассажирских мест)', '421', 'пасс. мест', '', 'ПАСС МЕСТ', '', 7, 2, 1, '')");
  7949.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(239, 'Тысяча пассажиро-километров', '423', '10^3 пасс.км', '', 'ТЫС ПАСС.КМ', '', 7, 2, 1, '')");
  7950.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(240, 'Миллион пассажиро-километров', '424', '10^6 пасс. км', '', 'МЛН ПАСС.КМ', '', 7, 2, 1, '')");
  7951.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(241, 'Пассажиропоток', '427', 'пасс.поток', '', 'ПАСС.ПОТОК', '', 7, 2, 1, '')");
  7952.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(242, 'Тонно-километр', '449', 'т.км', '', 'Т.КМ', '', 7, 2, 1, '')");
  7953.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(243, 'Тысяча тонно-километров', '450', '10^3 т.км', '', 'ТЫС Т.КМ', '', 7, 2, 1, '')");
  7954.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(244, 'Миллион тонно-километров', '451', '10^6 т. км', '', 'МЛН Т.КМ', '', 7, 2, 1, '')");
  7955.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(245, 'Тысяча наборов', '479', '10^3 набор', '', 'ТЫС НАБОР', '', 7, 2, 1, '')");
  7956.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(246, 'Грамм на киловатт-час', '510', 'г/кВт.ч', '', 'Г/КВТ.Ч', '', 7, 2, 1, '')");
  7957.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(247, 'Килограмм на гигакалорию', '511', 'кг/Гкал', '', 'КГ/ГИГАКАЛ', '', 7, 2, 1, '')");
  7958.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(248, 'Тонно-номер', '512', 'т.ном', '', 'Т.НОМ', '', 7, 2, 1, '')");
  7959.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(249, 'Автотонна', '513', 'авто т', '', 'АВТО Т', '', 7, 2, 1, '')");
  7960.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(250, 'Тонна тяги', '514', 'т.тяги', '', 'Т ТЯГИ', '', 7, 2, 1, '')");
  7961.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(251, 'Дедвейт-тонна', '515', 'дедвейт.т', '', 'ДЕДВЕЙТ.Т', '', 7, 2, 1, '')");
  7962.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(252, 'Тонно-танид', '516', 'т.танид', '', 'Т.ТАНИД', '', 7, 2, 1, '')");
  7963.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(253, 'Человек на квадратный метр', '521', 'чел/м2', '', 'ЧЕЛ/М2', '', 7, 2, 1, '')");
  7964.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(254, 'Человек на квадратный километр', '522', 'чел/км2', '', 'ЧЕЛ/КМ2', '', 7, 2, 1, '')");
  7965.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(255, 'Тонна в час', '534', 'т/ч', '', 'Т/Ч', '', 7, 2, 1, '')");
  7966.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(256, 'Тонна в сутки', '535', 'т/сут', '', 'Т/СУТ', '', 7, 2, 1, '')");
  7967.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(257, 'Тонна в смену', '536', 'т/смен', '', 'Т/СМЕН', '', 7, 2, 1, '')");
  7968.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(258, 'Тысяча тонн в сезон', '537', '10^3 т/сез', '', 'ТЫС Т/СЕЗ', '', 7, 2, 1, '')");
  7969.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(259, 'Тысяча тонн в год', '538', '10^3 т/год', '', 'ТЫС Т/ГОД', '', 7, 2, 1, '')");
  7970.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(260, 'Человеко-час', '539', 'чел.ч', '', 'ЧЕЛ.Ч', '', 7, 2, 1, '')");
  7971.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(261, 'Человеко-день', '540', 'чел.дн', '', 'ЧЕЛ.ДН', '', 7, 2, 1, '')");
  7972.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(262, 'Тысяча человеко-дней', '541', '10^3 чел.дн', '', 'ТЫС ЧЕЛ.ДН', '', 7, 2, 1, '')");
  7973.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(263, 'Тысяча человеко-часов', '542', '10^3 чел.ч', '', 'ТЫС ЧЕЛ.Ч', '', 7, 2, 1, '')");
  7974.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(264, 'Тысяча условных банок в смену', '543', '10^3 усл. банк/ смен', '', 'ТЫС УСЛ БАНК/СМЕН', '', 7, 2, 1, '')");
  7975.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(265, 'Миллион единиц в год', '544', '10^6 ед/год', '', 'МЛН ЕД/ГОД', '', 7, 2, 1, '')");
  7976.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(266, 'Посещение в смену', '545', 'посещ/смен', '', 'ПОСЕЩ/СМЕН', '', 7, 2, 1, '')");
  7977.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(267, 'Тысяча посещений в смену', '546', '10^3 посещ/смен', '', 'ТЫС ПОСЕЩ/ СМЕН', '', 7, 2, 1, '')");
  7978.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(268, 'Пара в смену', '547', 'пар/смен', '', 'ПАР/СМЕН', '', 7, 2, 1, '')");
  7979.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(269, 'Тысяча пар в смену', '548', '10^3 пар/смен', '', 'ТЫС ПАР/СМЕН', '', 7, 2, 1, '')");
  7980.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(270, 'Миллион тонн в год', '550', '10^6 т/год', '', 'МЛН Т/ГОД', '', 7, 2, 1, '')");
  7981.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(271, 'Тонна переработки в сутки', '552', 'т перераб/сут', '', 'Т ПЕРЕРАБ/СУТ', '', 7, 2, 1, '')");
  7982.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(272, 'Тысяча тонн переработки в сутки', '553', '10^3 т перераб/ сут', '', 'ТЫС Т ПЕРЕРАБ/СУТ', '', 7, 2, 1, '')");
  7983.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(273, 'Центнер переработки в сутки', '554', 'ц перераб/сут', '', 'Ц ПЕРЕРАБ/СУТ', '', 7, 2, 1, '')");
  7984.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(274, 'Тысяча центнеров переработки в сутки', '555', '10^3 ц перераб/ сут', '', 'ТЫС Ц ПЕРЕРАБ/СУТ', '', 7, 2, 1, '')");
  7985.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(275, 'Тысяча голов в год', '556', '10^3 гол/год', '', 'ТЫС ГОЛ/ГОД', '', 7, 2, 1, '')");
  7986.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(276, 'Миллион голов в год', '557', '10^6 гол/год', '', 'МЛН ГОЛ/ГОД', '', 7, 2, 1, '')");
  7987.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(277, 'Тысяча птицемест', '558', '10^3 птицемест', '', 'ТЫС ПТИЦЕМЕСТ', '', 7, 2, 1, '')");
  7988.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(278, 'Тысяча кур-несушек', '559', '10^3 кур. несуш', '', 'ТЫС КУР. НЕСУШ', '', 7, 2, 1, '')");
  7989.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(279, 'Минимальная заработная плата', '560', 'мин. заработн. плат', '', 'МИН ЗАРАБОТН ПЛАТ', '', 7, 2, 1, '')");
  7990.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(280, 'Тысяча тонн пара в час', '561', '10^3 т пар/ч', '', 'ТЫС Т ПАР/Ч', '', 7, 2, 1, '')");
  7991.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(281, 'Тысяча прядильных веретен', '562', '10^3 пряд.верет', '', 'ТЫС ПРЯД ВЕРЕТ', '', 7, 2, 1, '')");
  7992.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(282, 'Тысяча прядильных мест', '563', '10^3 пряд.мест', '', 'ТЫС ПРЯД МЕСТ', '', 7, 2, 1, '')");
  7993.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(283, 'Доза', '639', 'доз', '', 'ДОЗ', '', 7, 2, 1, '')");
  7994.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(284, 'Тысяча доз', '640', '10^3 доз', '', 'ТЫС ДОЗ', '', 7, 2, 1, '')");
  7995.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(285, 'Единица', '642', 'ед', '', 'ЕД', '', 7, 2, 1, '')");
  7996.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(286, 'Тысяча единиц', '643', '10^3 ед', '', 'ТЫС ЕД', '', 7, 2, 1, '')");
  7997.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(287, 'Миллион единиц', '644', '10^6 ед', '', 'МЛН ЕД', '', 7, 2, 1, '')");
  7998.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(288, 'Канал', '661', 'канал', '', 'КАНАЛ', '', 7, 2, 1, '')");
  7999.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(289, 'Тысяча комплектов', '673', '10^3 компл', '', 'ТЫС КОМПЛ', '', 7, 2, 1, '')");
  8000.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(290, 'Место', '698', 'мест', '', 'МЕСТ', '', 7, 2, 1, '')");
  8001.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(291, 'Тысяча мест', '699', '10^3 мест', '', 'ТЫС МЕСТ', '', 7, 2, 1, '')");
  8002.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(292, 'Тысяча номеров', '709', '10^3 ном', '', 'ТЫС НОМ', '', 7, 2, 1, '')");
  8003.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(293, 'Тысяча гектаров порций', '724', '10^3 га порц', '', 'ТЫС ГА ПОРЦ', '', 7, 2, 1, '')");
  8004.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(294, 'Тысяча пачек', '729', '10^3 пач', '', 'ТЫС ПАЧ', '', 7, 2, 1, '')");
  8005.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(295, 'Процент', '744', '%', '', 'ПРОЦ', '', 7, 2, 1, '')");
  8006.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(296, 'Промилле (0,1 процента)', '746', 'промилле', '', 'ПРОМИЛЛЕ', '', 7, 2, 1, '')");
  8007.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(297, 'Тысяча рулонов', '751', '10^3 рул', '', 'ТЫС РУЛ', '', 7, 2, 1, '')");
  8008.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(298, 'Тысяча станов', '761', '10^3 стан', '', 'ТЫС СТАН', '', 7, 2, 1, '')");
  8009.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(299, 'Станция', '762', 'станц', '', 'СТАНЦ', '', 7, 2, 1, '')");
  8010.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(300, 'Тысяча тюбиков', '775', '10^3 тюбик', '', 'ТЫС ТЮБИК', '', 7, 2, 1, '')");
  8011.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(301, 'Тысяча условных тубов', '776', '10^3 усл.туб', '', 'ТЫС УСЛ ТУБ', '', 7, 2, 1, '')");
  8012.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(302, 'Миллион упаковок', '779', '10^6 упак', '', 'МЛН УПАК', '', 7, 2, 1, '')");
  8013.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(303, 'Тысяча упаковок', '782', '10^3 упак', '', 'ТЫС УПАК', '', 7, 2, 1, '')");
  8014.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(304, 'Человек', '792', 'чел', '', 'ЧЕЛ', '', 7, 2, 1, '')");
  8015.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(305, 'Тысяча человек', '793', '10^3 чел', '', 'ТЫС ЧЕЛ', '', 7, 2, 1, '')");
  8016.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(306, 'Миллион человек', '794', '10^6 чел', '', 'МЛН ЧЕЛ', '', 7, 2, 1, '')");
  8017.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(307, 'Миллион экземпляров', '808', '10^6 экз', '', 'МЛН ЭКЗ', '', 7, 2, 1, '')");
  8018.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(308, 'Ячейка', '810', 'яч', '', 'ЯЧ', '', 7, 2, 1, '')");
  8019.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(309, 'Ящик', '812', 'ящ', '', 'ЯЩ', '', 7, 2, 1, '')");
  8020.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(310, 'Голова', '836', 'гол', '', 'ГОЛ', '', 7, 2, 1, '')");
  8021.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(311, 'Тысяча пар', '837', '10^3 пар', '', 'ТЫС ПАР', '', 7, 2, 1, '')");
  8022.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(312, 'Миллион пар', '838', '10^6 пар', '', 'МЛН ПАР', '', 7, 2, 1, '')");
  8023.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(313, 'Комплект', '839', 'компл', '', 'КОМПЛ', '', 7, 2, 1, '')");
  8024.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(314, 'Секция', '840', 'секц', '', 'СЕКЦ', '', 7, 2, 1, '')");
  8025.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(315, 'Бутылка', '868', 'бут', '', 'БУТ', '', 7, 2, 1, '')");
  8026.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(316, 'Тысяча бутылок', '869', '10^3 бут', '', 'ТЫС БУТ', '', 7, 2, 1, '')");
  8027.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(317, 'Ампула', '870', 'ампул', '', 'АМПУЛ', '', 7, 2, 1, '')");
  8028.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(318, 'Тысяча ампул', '871', '10^3 ампул', '', 'ТЫС АМПУЛ', '', 7, 2, 1, '')");
  8029.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(319, 'Флакон', '872', 'флак', '', 'ФЛАК', '', 7, 2, 1, '')");
  8030.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(320, 'Тысяча флаконов', '873', '10^3 флак', '', 'ТЫС ФЛАК', '', 7, 2, 1, '')");
  8031.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(321, 'Тысяча тубов', '874', '10^3 туб', '', 'ТЫС ТУБ', '', 7, 2, 1, '')");
  8032.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(322, 'Тысяча коробок', '875', '10^3 кор', '', 'ТЫС КОР', '', 7, 2, 1, '')");
  8033.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(323, 'Условная единица', '876', 'усл. ед', '', 'УСЛ ЕД', '', 7, 2, 1, '')");
  8034.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(324, 'Тысяча условных единиц', '877', '10^3 усл. ед', '', 'ТЫС УСЛ ЕД', '', 7, 2, 1, '')");
  8035.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(325, 'Миллион условных единиц', '878', '10^6 усл. ед', '', 'МЛН УСЛ ЕД', '', 7, 2, 1, '')");
  8036.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(326, 'Условная штука', '879', 'усл. шт', '', 'УСЛ ШТ', '', 7, 2, 1, '')");
  8037.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(327, 'Тысяча условных штук', '880', '10^3 усл. шт', '', 'ТЫС УСЛ ШТ', '', 7, 2, 1, '')");
  8038.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(328, 'Условная банка', '881', 'усл. банк', '', 'УСЛ БАНК', '', 7, 2, 1, '')");
  8039.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(329, 'Тысяча условных банок', '882', '10^3 усл. банк', '', 'ТЫС УСЛ БАНК', '', 7, 2, 1, '')");
  8040.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(330, 'Миллион условных банок', '883', '10^6 усл. банк', '', 'МЛН УСЛ БАНК', '', 7, 2, 1, '')");
  8041.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(331, 'Условный кусок', '884', 'усл. кус', '', 'УСЛ КУС', '', 7, 2, 1, '')");
  8042.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(332, 'Тысяча условных кусков', '885', '10^3 усл. кус', '', 'ТЫС УСЛ КУС', '', 7, 2, 1, '')");
  8043.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(333, 'Миллион условных кусков', '886', '10^6 усл. кус', '', 'МЛН УСЛ КУС', '', 7, 2, 1, '')");
  8044.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(334, 'Условный ящик', '887', 'усл. ящ', '', 'УСЛ ЯЩ', '', 7, 2, 1, '')");
  8045.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(335, 'Тысяча условных ящиков', '888', '10^3 усл. ящ', '', 'ТЫС УСЛ ЯЩ', '', 7, 2, 1, '')");
  8046.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(336, 'Условная катушка', '889', 'усл. кат', '', 'УСЛ КАТ', '', 7, 2, 1, '')");
  8047.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(337, 'Тысяча условных катушек', '890', '10^3 усл. кат', '', 'ТЫС УСЛ КАТ', '', 7, 2, 1, '')");
  8048.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(338, 'Условная плитка', '891', 'усл. плит', '', 'УСЛ ПЛИТ', '', 7, 2, 1, '')");
  8049.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(339, 'Тысяча условных плиток', '892', '10^3 усл. плит', '', 'ТЫС УСЛ ПЛИТ', '', 7, 2, 1, '')");
  8050.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(340, 'Условный кирпич', '893', 'усл. кирп', '', 'УСЛ КИРП', '', 7, 2, 1, '')");
  8051.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(341, 'Тысяча условных кирпичей', '894', '10^3 усл. кирп', '', 'ТЫС УСЛ КИРП', '', 7, 2, 1, '')");
  8052.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(342, 'Миллион условных кирпичей', '895', '10^6 усл. кирп', '', 'МЛН УСЛ КИРП', '', 7, 2, 1, '')");
  8053.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(343, 'Семья', '896', 'семей', '', 'СЕМЕЙ', '', 7, 2, 1, '')");
  8054.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(344, 'Тысяча семей', '897', '10^3 семей', '', 'ТЫС СЕМЕЙ', '', 7, 2, 1, '')");
  8055.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(345, 'Миллион семей', '898', '10^6 семей', '', 'МЛН СЕМЕЙ', '', 7, 2, 1, '')");
  8056.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(346, 'Домохозяйство', '899', 'домхоз', '', 'ДОМХОЗ', '', 7, 2, 1, '')");
  8057.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(347, 'Тысяча домохозяйств', '900', '10^3 домхоз', '', 'ТЫС ДОМХОЗ', '', 7, 2, 1, '')");
  8058.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(348, 'Миллион домохозяйств', '901', '10^6 домхоз', '', 'МЛН ДОМХОЗ', '', 7, 2, 1, '')");
  8059.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(349, 'Ученическое место', '902', 'учен. мест', '', 'УЧЕН МЕСТ', '', 7, 2, 1, '')");
  8060.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(350, 'Тысяча ученических мест', '903', '10^3 учен. мест', '', 'ТЫС УЧЕН МЕСТ', '', 7, 2, 1, '')");
  8061.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(351, 'Рабочее место', '904', 'раб. мест', '', 'РАБ МЕСТ', '', 7, 2, 1, '')");
  8062.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(352, 'Тысяча рабочих мест', '905', '10^3 раб. мест', '', 'ТЫС РАБ МЕСТ', '', 7, 2, 1, '')");
  8063.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(353, 'Посадочное место', '906', 'посад. мест', '', 'ПОСАД МЕСТ', '', 7, 2, 1, '')");
  8064.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(354, 'Тысяча посадочных мест', '907', '10^3 посад. мест', '', 'ТЫС ПОСАД МЕСТ', '', 7, 2, 1, '')");
  8065.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(355, 'Номер', '908', 'ном', '', 'НОМ', '', 7, 2, 1, '')");
  8066.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(356, 'Квартира', '909', 'кварт', '', 'КВАРТ', '', 7, 2, 1, '')");
  8067.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(357, 'Тысяча квартир', '910', '10^3 кварт', '', 'ТЫС КВАРТ', '', 7, 2, 1, '')");
  8068.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(358, 'Койка', '911', 'коек', '', 'КОЕК', '', 7, 2, 1, '')");
  8069.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(359, 'Тысяча коек', '912', '10^3 коек', '', 'ТЫС КОЕК', '', 7, 2, 1, '')");
  8070.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(360, 'Том книжного фонда', '913', 'том книжн. фонд', '', 'ТОМ КНИЖН ФОНД', '', 7, 2, 1, '')");
  8071.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(361, 'Тысяча томов книжного фонда', '914', '10^3 том. книжн. фонд', '', 'ТЫС ТОМ КНИЖН ФОНД', '', 7, 2, 1, '')");
  8072.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(362, 'Условный ремонт', '915', 'усл. рем', '', 'УСЛ РЕМ', '', 7, 2, 1, '')");
  8073.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(363, 'Условный ремонт в год', '916', 'усл. рем/год', '', 'УСЛ РЕМ/ГОД', '', 7, 2, 1, '')");
  8074.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(364, 'Смена', '917', 'смен', '', 'СМЕН', '', 7, 2, 1, '')");
  8075.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(365, 'Лист авторский', '918', 'л. авт', '', 'ЛИСТ АВТ', '', 7, 2, 1, '')");
  8076.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(366, 'Лист печатный', '920', 'л. печ', '', 'ЛИСТ ПЕЧ', '', 7, 2, 1, '')");
  8077.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(367, 'Лист учетно-издательский', '921', 'л. уч.-изд', '', 'ЛИСТ УЧ.ИЗД', '', 7, 2, 1, '')");
  8078.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(368, 'Знак', '922', 'знак', '', 'ЗНАК', '', 7, 2, 1, '')");
  8079.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(369, 'Слово', '923', 'слово', '', 'СЛОВО', '', 7, 2, 1, '')");
  8080.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(370, 'Символ', '924', 'символ', '', 'СИМВОЛ', '', 7, 2, 1, '')");
  8081.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(371, 'Условная труба', '925', 'усл. труб', '', 'УСЛ ТРУБ', '', 7, 2, 1, '')");
  8082.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(372, 'Тысяча пластин', '930', '10^3 пласт', '', 'ТЫС ПЛАСТ', '', 7, 2, 1, '')");
  8083.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(373, 'Миллион доз', '937', '10^6 доз', '', 'МЛН ДОЗ', '', 7, 2, 1, '')");
  8084.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(374, 'Миллион листов-оттисков', '949', '10^6 лист.оттиск', '', 'МЛН ЛИСТ.ОТТИСК', '', 7, 2, 1, '')");
  8085.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(375, 'Вагоно(машино)-день', '950', 'ваг (маш).дн', '', 'ВАГ (МАШ).ДН', '', 7, 2, 1, '')");
  8086.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(376, 'Тысяча вагоно-(машино)-часов', '951', '10^3 ваг (маш).ч', '', 'ТЫС ВАГ (МАШ).Ч', '', 7, 2, 1, '')");
  8087.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(377, 'Тысяча вагоно-(машино)-километров', '952', '10^3 ваг (маш).км', '', 'ТЫС ВАГ (МАШ).КМ', '', 7, 2, 1, '')");
  8088.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(378, 'Тысяча место-километров', '953', '10 ^3мест.км', '', 'ТЫС МЕСТ.КМ', '', 7, 2, 1, '')");
  8089.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(379, 'Вагоно-сутки', '954', 'ваг.сут', '', 'ВАГ.СУТ', '', 7, 2, 1, '')");
  8090.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(380, 'Тысяча поездо-часов', '955', '10^3 поезд.ч', '', 'ТЫС ПОЕЗД.Ч', '', 7, 2, 1, '')");
  8091.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(381, 'Тысяча поездо-километров', '956', '10^3 поезд.км', '', 'ТЫС ПОЕЗД.КМ', '', 7, 2, 1, '')");
  8092.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(382, 'Тысяча тонно-миль', '957', '10^3 т.миль', '', 'ТЫС Т.МИЛЬ', '', 7, 2, 1, '')");
  8093.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(383, 'Тысяча пассажиро-миль', '958', '10^3 пасс.миль', '', 'ТЫС ПАСС.МИЛЬ', '', 7, 2, 1, '')");
  8094.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(384, 'Автомобиле-день', '959', 'автомоб.дн', '', 'АВТОМОБ.ДН', '', 7, 2, 1, '')");
  8095.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(385, 'Тысяча автомобиле-тонно-дней', '960', '10^3 автомоб.т.дн', '', 'ТЫС АВТОМОБ.Т.ДН', '', 7, 2, 1, '')");
  8096.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(386, 'Тысяча автомобиле-часов', '961', '10^3 автомоб.ч', '', 'ТЫС АВТОМОБ.Ч', '', 7, 2, 1, '')");
  8097.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(387, 'Тысяча автомобиле-место-дней', '962', '10^3 автомоб.мест. дн', '', 'ТЫС АВТОМОБ.МЕСТ. ДН', '', 7, 2, 1, '')");
  8098.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(388, 'Приведенный час', '963', 'привед.ч', '', 'ПРИВЕД.Ч', '', 7, 2, 1, '')");
  8099.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(389, 'Самолето-километр', '964', 'самолет.км', '', 'САМОЛЕТ.КМ', '', 7, 2, 1, '')");
  8100.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(390, 'Тысяча километров', '965', '10^3 км', '', 'ТЫС КМ', '', 7, 2, 1, '')");
  8101.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(391, 'Тысяча тоннаже-рейсов', '966', '10^3 тоннаж. рейс', '', 'ТЫС ТОННАЖ. РЕЙС', '', 7, 2, 1, '')");
  8102.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(392, 'Миллион тонно-миль', '967', '10^6 т. миль', '', 'МЛН Т. МИЛЬ', '', 7, 2, 1, '')");
  8103.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(393, 'Миллион пассажиро-миль', '968', '10^6 пасс. миль', '', 'МЛН ПАСС. МИЛЬ', '', 7, 2, 1, '')");
  8104.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(394, 'Миллион тоннаже-миль', '969', '10^6 тоннаж. миль', '', 'МЛН ТОННАЖ. МИЛЬ', '', 7, 2, 1, '')");
  8105.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(395, 'Миллион пассажиро-место-миль', '970', '10^6 пасс. мест. миль', '', 'МЛН ПАСС. МЕСТ. МИЛЬ', '', 7, 2, 1, '')");
  8106.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(396, 'Кормо-день', '971', 'корм. дн', '', 'КОРМ. ДН', '', 7, 2, 1, '')");
  8107.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(397, 'Центнер кормовых единиц', '972', 'ц корм ед', '', 'Ц КОРМ ЕД', '', 7, 2, 1, '')");
  8108.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(398, 'Тысяча автомобиле-километров', '973', '10^3 автомоб. км', '', 'ТЫС АВТОМОБ. КМ', '', 7, 2, 1, '')");
  8109.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(399, 'Тысяча тоннаже-сут', '974', '10^3 тоннаж. сут', '', 'ТЫС ТОННАЖ. СУТ', '', 7, 2, 1, '')");
  8110.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(400, 'Суго-сутки', '975', 'суго. сут.', '', 'СУГО. СУТ', '', 7, 2, 1, '')");
  8111.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(401, 'Штук в 20-футовом эквиваленте (ДФЭ)', '976', 'штук в 20-футовом эквиваленте', '', 'ШТ В 20 ФУТ ЭКВИВ', '', 7, 2, 1, '')");
  8112.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(402, 'Канало-километр', '977', 'канал. км', '', 'КАНАЛ. КМ', '', 7, 2, 1, '')");
  8113.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(403, 'Канало-концы', '978', 'канал. конц', '', 'КАНАЛ. КОНЦ', '', 7, 2, 1, '')");
  8114.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(404, 'Тысяча экземпляров', '979', '10^3 экз', '', 'ТЫС ЭКЗ', '', 7, 2, 1, '')");
  8115.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(405, 'Тысяча долларов', '980', '10^3 доллар', '', 'ТЫС ДОЛЛАР', '', 7, 2, 1, '')");
  8116.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(406, 'Тысяча тонн кормовых единиц', '981', '10^3 корм ед', '', 'ТЫС Т КОРМ ЕД', '', 7, 2, 1, '')");
  8117.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(407, 'Миллион тонн кормовых единиц', '982', '10^6 корм ед', '', 'МЛН Т КОРМ ЕД', '', 7, 2, 1, '')");
  8118.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(408, 'Судо-сутки', '983', 'суд.сут', '', 'СУД.СУТ', '', 7, 2, 1, '')");
  8119.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(409, 'Гектометр', '017', '', 'hm', '', 'HMT', 1, 3, 1, '')");
  8120.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(410, 'Миля (уставная) (1609,344 м)', '045', '', 'mile', '', 'SMI', 1, 3, 1, '')");
  8121.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(411, 'Акр (4840 квадратных ярдов)', '077', '', 'acre', '', 'ACR', 2, 3, 1, '')");
  8122.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(412, 'Квадратная миля', '079', '', 'mile2', '', 'MIK', 2, 3, 1, '')");
  8123.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(413, 'Жидкостная унция СК (28,413 см3)', '135', '', 'fl oz (UK)', '', 'OZI', 3, 3, 1, '')");
  8124.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(414, 'Джилл СК (0,142065 дм3)', '136', '', 'gill (UK)', '', 'GII', 3, 3, 1, '')");
  8125.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(415, 'Пинта СК (0,568262 дм3)', '137', '', 'pt (UK)', '', 'PTI', 3, 3, 1, '')");
  8126.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(416, 'Кварта СК (1,136523 дм3)', '138', '', 'qt (UK)', '', 'QTI', 3, 3, 1, '')");
  8127.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(417, 'Галлон СК (4,546092 дм3)', '139', '', 'gal (UK)', '', 'GLI', 3, 3, 1, '')");
  8128.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(418, 'Бушель СК (36,36874 дм3)', '140', '', 'bu (UK)', '', 'BUI', 3, 3, 1, '')");
  8129.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(419, 'Жидкостная унция США (29,5735 см3)', '141', '', 'fl oz (US)', '', 'OZA', 3, 3, 1, '')");
  8130.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(420, 'Джилл США (11,8294 см3)', '142', '', 'gill (US)', '', 'GIA', 3, 3, 1, '')");
  8131.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(421, 'Жидкостная пинта США (0,473176 дм3)', '143', '', 'liq pt (US)', '', 'PTL', 3, 3, 1, '')");
  8132.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(422, 'Жидкостная кварта США (0,946353 дм3)', '144', '', 'liq qt (US)', '', 'QTL', 3, 3, 1, '')");
  8133.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(423, 'Жидкостный галлон США (3,78541 дм3)', '145', '', 'gal (US)', '', 'GLL', 3, 3, 1, '')");
  8134.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(424, 'Баррель (нефтяной) США (158,987 дм3)', '146', '', 'barrel (US)', '', 'BLL', 3, 3, 1, '')");
  8135.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(425, 'Сухая пинта США (0,55061 дм3)', '147', '', 'dry pt (US)', '', 'PTD', 3, 3, 1, '')");
  8136.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(426, 'Сухая кварта США (1,101221 дм3)', '148', '', 'dry qt (US)', '', 'QTD', 3, 3, 1, '')");
  8137.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(427, 'Сухой галлон США (4,404884 дм3)', '149', '', 'dry gal (US)', '', 'GLD', 3, 3, 1, '')");
  8138.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(428, 'Бушель США (35,2391 дм3)', '150', '', 'bu (US)', '', 'BUA', 3, 3, 1, '')");
  8139.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(429, 'Сухой баррель США (115,627 дм3)', '151', '', 'bbl (US)', '', 'BLD', 3, 3, 1, '')");
  8140.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(430, 'Стандарт', '152', '', '-', '', 'WSD', 3, 3, 1, '')");
  8141.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(431, 'Корд (3,63 м3)', '153', '', '-', '', 'WCD', 3, 3, 1, '')");
  8142.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(432, 'Тысячи бордфутов (2,36 м3)', '154', '', '-', '', 'MBF', 3, 3, 1, '')");
  8143.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(433, 'Нетто-регистровая тонна', '182', '', '-', '', 'NTT', 4, 3, 1, '')");
  8144.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(434, 'Обмерная (фрахтовая) тонна', '183', '', '-', '', 'SHT', 4, 3, 1, '')");
  8145.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(435, 'Водоизмещение', '184', '', '-', '', 'DPT', 4, 3, 1, '')");
  8146.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(436, 'Фунт СК, США (0,45359237 кг)', '186', '', 'lb', '', 'LBR', 4, 3, 1, '')");
  8147.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(437, 'Унция СК, США (28,349523 г)', '187', '', 'oz', '', 'ONZ', 4, 3, 1, '')");
  8148.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(438, 'Драхма СК (1,771745 г)', '188', '', 'dr', '', 'DRI', 4, 3, 1, '')");
  8149.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(439, 'Гран СК, США (64,798910 мг)', '189', '', 'gn', '', 'GRN', 4, 3, 1, '')");
  8150.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(440, 'Стоун СК (6,350293 кг)', '190', '', 'st', '', 'STI', 4, 3, 1, '')");
  8151.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(441, 'Квартер СК (12,700586 кг)', '191', '', 'qtr', '', 'QTR', 4, 3, 1, '')");
  8152.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(442, 'Центал СК (45,359237 кг)', '192', '', '-', '', 'CNT', 4, 3, 1, '')");
  8153.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(443, 'Центнер США (45,3592 кг)', '193', '', 'cwt', '', 'CWA', 4, 3, 1, '')");
  8154.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(444, 'Длинный центнер СК (50,802345 кг)', '194', '', 'cwt (UK)', '', 'CWI', 4, 3, 1, '')");
  8155.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(445, 'Короткая тонна СК, США (0,90718474 т) [2*]', '195', '', 'sht', '', 'STN', 4, 3, 1, '')");
  8156.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(446, 'Длинная тонна СК, США (1,0160469 т) [2*]', '196', '', 'lt', '', 'LTN', 4, 3, 1, '')");
  8157.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(447, 'Скрупул СК, США (1,295982 г)', '197', '', 'scr', '', 'SCR', 4, 3, 1, '')");
  8158.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(448, 'Пеннивейт СК, США (1,555174 г)', '198', '', 'dwt', '', 'DWT', 4, 3, 1, '')");
  8159.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(449, 'Драхма СК (3,887935 г)', '199', '', 'drm', '', 'DRM', 4, 3, 1, '')");
  8160.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(450, 'Драхма США (3,887935 г)', '200', '', '-', '', 'DRA', 4, 3, 1, '')");
  8161.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(451, 'Унция СК, США (31,10348 г); тройская унция', '201', '', 'apoz', '', 'APZ', 4, 3, 1, '')");
  8162.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(452, 'Тройский фунт США (373,242 г)', '202', '', '-', '', 'LBT', 4, 3, 1, '')");
  8163.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(453, 'Эффективная мощность (245,7 ватт)', '213', '', 'B.h.p.', '', 'BHP', 5, 3, 1, '')");
  8164.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(454, 'Британская тепловая единица (1,055 кДж)', '275', '', 'Btu', '', 'BTU', 5, 3, 1, '')");
  8165.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(455, 'Гросс (144 шт.)', '638', '', 'gr; 144', '', 'GRO', 7, 3, 1, '')");
  8166.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(456, 'Большой гросс (12 гроссов)', '731', '', '1728', '', 'GGR', 7, 3, 1, '')");
  8167.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(457, 'Короткий стандарт (7200 единиц)', '738', '', '-', '', 'SST', 7, 3, 1, '')");
  8168.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(458, 'Галлон спирта установленной крепости', '835', '', '-', '', 'PGL', 7, 3, 1, '')");
  8169.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(459, 'Международная единица', '851', '', '-', '', 'NIU', 7, 3, 1, '')");
  8170.         $this->db->query("INSERT INTO `" . DB_PREFIX . "unit` (unit_id, name, number_code, rus_name1, eng_name1, rus_name2, eng_name2, unit_group_id, unit_type_id, visible, comment) VALUES(460, 'Сто международных единиц', '853', '', '-', '', 'HIU', 7, 3, 1, '')");
  8171.  
  8172.     }
  8173.  
  8174.  
  8175.     /**
  8176.      * ver 7
  8177.      * update 2017-05-19
  8178.      * Устанавливает обновления
  8179.      */
  8180.     public function checkUpdates($settings) {
  8181.  
  8182.         $table_fields = $this->defineTableFields();
  8183.         $message = "";
  8184.         if (isset($settings['exchange1c_version'])) {
  8185.             $version = $settings['exchange1c_version'];
  8186.             if ($version == '1.6.3.5') {
  8187.                 $version = $this->update1_6_3_6($version, $message, $table_fields);
  8188.             }
  8189.             if ($version == '1.6.3.6') {
  8190.                 $version = $this->update1_6_3_7($version, $message, $table_fields);
  8191.             }
  8192.             if ($version == '1.6.3.7') {
  8193.                 $version = $this->update1_6_3_8($version, $message, $table_fields);
  8194.             }
  8195.             if ($version == '1.6.3.8') {
  8196.                 $version = $this->update1_6_3_9($version, $message, $table_fields);
  8197.             }
  8198.             if ($version == '1.6.3.9') {
  8199.                 $version = $this->update1_6_3_10($version, $message, $table_fields);
  8200.             }
  8201.             if ($version == '1.6.3.10') {
  8202.                 $version = $this->update1_6_3_11($version, $message, $table_fields);
  8203.             }
  8204.             if ($version == '1.6.3.11') {
  8205.                 $version = $this->update1_6_3_12($version, $message, $table_fields);
  8206.             }
  8207.         }
  8208.         if (!$this->ERROR) {
  8209.             if ($version != $settings['exchange1c_version']) {
  8210.                 $settings['exchange1c_table_fields']    = $this->defineTableFields();
  8211.                 $this->setEvents();
  8212.                 $settings['exchange1c_version'] = $version;
  8213.                 $this->model_setting_setting->editSetting('exchange1c', $settings);
  8214.                 $message .= "<br /><strong>ВНИМАНИЕ! после обновления необходимо проверить все настройки и сохранить!</strong>";
  8215.             }
  8216.         }
  8217.  
  8218.         return array('error'=>$this->ERROR, 'success'=>$message);
  8219.  
  8220.     } // checkUpdates()
  8221.  
  8222.  
  8223.     /**
  8224.      * Устанавливает обновления на версию 1.6.3.6
  8225.      */
  8226.     private function update1_6_3_6($old_version, &$message, $table_fields) {
  8227.  
  8228.         $version = '1.6.3.6';
  8229.         $message .= "Исправлены ошибки (1), доработки (0):<br>";
  8230.         $message .= "1. Ошибка при ручной генерации SEO, если в базе нет таблицы manufacturer_description <br>";
  8231.         $message .= "Обновление с версии " . $old_version . " на версию " . $version ." прошло успешно";
  8232.         return $version;
  8233.  
  8234.     } // update1_6_3_6()
  8235.  
  8236.  
  8237.     /**
  8238.      * Устанавливает обновления на версию 1.6.3.7
  8239.      */
  8240.     private function update1_6_3_7($old_version, &$message, $table_fields) {
  8241.  
  8242.         $version = '1.6.3.7';
  8243.         $message .= "Исправлены ошибки E(3), обновления U(2):<br>";
  8244.         $message .= "E1. Затирание основнлй картинки при отключенном обновлении картинок<br>";
  8245.         $message .= "E2. При синхронизации по полям Артикул, Штрихкод или Наименование при пустом поле теперь не прерывается обмен<br>";
  8246.         $message .= "E3. Если предложение не найдено, обмен теперь не прерывается<br>";
  8247.         $message .= "U1. Добавлена кнопка применить<br>";
  8248.         $message .= "U2. Добавлена настройка - резервировать товары в заказе<br>";
  8249.         $message .= "Обновление с версии " . $old_version . " на версию " . $version ." прошло успешно";
  8250.         return $version;
  8251.  
  8252.     } // update1_6_3_7()
  8253.  
  8254.  
  8255.     /**
  8256.      * Устанавливает обновления на версию 1.6.3.8
  8257.      */
  8258.     private function update1_6_3_8($old_version, &$message, $table_fields) {
  8259.  
  8260.         if (!isset($table_fields['product_price']['action'])) {
  8261.             $result = @$this->query("ALTER TABLE  `" . DB_PREFIX . "product_price` ADD  `action` INT( 1 ) NOT NULL AFTER `customer_group_id`");
  8262.             $message .= ($result ? "Успешно добавлено поле " : "Ошибка при добавлении поля ") . "'action' в таблицу 'product_price'<br />";
  8263.             if (!$result) return $old_version;
  8264.         }
  8265.         // Пересоздадим индекс
  8266.         $result = @$this->db->query("ALTER TABLE  `" . DB_PREFIX . "product_price` DROP INDEX `product_price_key`");
  8267.         $result = @$this->db->query("ALTER TABLE  `" . DB_PREFIX . "product_price` ADD UNIQUE INDEX  `product_price_key` (`product_id`,`product_feature_id`,`customer_group_id`,`action`)");
  8268.         $message .= ($result ? "Успешно пересоздан индекс " : "Ошибка при пересоздании индекса ") . "'product_price_key' в таблице 'product_price'<br />";
  8269.         if (!$result) return $old_version;
  8270.  
  8271.         $version = '1.6.3.8';
  8272.         $message .= "Исправлены ошибки E(1), обновления U(3):<br>";
  8273.         $message .= "E1. Несколько ошибок при выгрузке заказов<br>";
  8274.         $message .= "U1. Добавлено удаление файла перед распаковкой XML из архива<br>";
  8275.         $message .= "U2. Добавлены акция и скидка в цены при загрузке характеристик<br>";
  8276.         $message .= "U3. Добавлены опция отключения очистки акций и скидок при полной выгрузке<br>";
  8277.         $message .= "Обновление с версии " . $old_version . " на версию " . $version ." прошло успешно";
  8278.         return $version;
  8279.  
  8280.     } // update1_6_3_8()
  8281.  
  8282.  
  8283.     /**
  8284.      * Устанавливает обновления на версию 1.6.3.9
  8285.      */
  8286.     private function update1_6_3_9($old_version, &$message, $table_fields) {
  8287.  
  8288.         $version = '1.6.3.9';
  8289.         $message .= "Исправлены ошибки E(4), обновления U(1):<br>";
  8290.         $message .= "E1. При смене статуса заказа после выгрузки заказов в 1С<br>";
  8291.         $message .= "E2. Исправлена ошибка с чтением картинок<br>";
  8292.         $message .= "E3. Исправлена ошибка с наложением водяных знаков<br>";
  8293.         $message .= "E4. Исправлена ошибка в SEO<br>";
  8294.         $message .= "U1. Добавлена запись остатков в опции у характеристик<br>";
  8295.         $message .= "Обновление с версии " . $old_version . " на версию " . $version ." прошло успешно";
  8296.         return $version;
  8297.  
  8298.     } // update1_6_3_9()
  8299.  
  8300.  
  8301.     /**
  8302.      * Устанавливает обновления на версию 1.6.3.10
  8303.      */
  8304.     private function update1_6_3_10($old_version, &$message, $table_fields) {
  8305.  
  8306.         $version = '1.6.3.10';
  8307.         $message .= "Исправлены ошибки E(2), обновления U(3):<br>";
  8308.         $message .= "E1. Исправлена ошибка при загрузке в товар полного наименования из реквизита<br>";
  8309.         $message .= "E2. Исправлена ошибка при чтении остатков без складов (формат Битрикс)<br>";
  8310.         $message .= "U1. Добавлена очистка картинки из кэша, которая загружается<br>";
  8311.         $message .= "U2. Добавлена загрузка определяемых пользователем свойств<br>";
  8312.         $message .= "U3. Объеденены опции очистки остатков в одну<br>";
  8313.         $message .= "Обновление с версии " . $old_version . " на версию " . $version ." прошло успешно";
  8314.  
  8315.         return $version;
  8316.  
  8317.     } // update1_6_3_10()
  8318.  
  8319.  
  8320.     /**
  8321.      * Устанавливает обновления на версию 1.6.3.11
  8322.      */
  8323.     private function update1_6_3_11($old_version, &$message, $table_fields) {
  8324.  
  8325.         $version = '1.6.3.11';
  8326.         $message .= "Изменения в версии теперь смотрите в вкладке Обновления<br />";
  8327.         $message .= "Обновление с версии " . $old_version . " на версию " . $version ." прошло успешно";
  8328.  
  8329.         return $version;
  8330.  
  8331.     } // update1_6_3_11()
  8332.  
  8333.  
  8334.     /**
  8335.      * Упраздняется классификатор единиц измерений
  8336.      * Устанавливает обновления на версию 1.6.3.12
  8337.      */
  8338.     private function update1_6_3_12($old_version, &$message, $table_fields) {
  8339.  
  8340.         $this->installUnits();
  8341.  
  8342.         // Добавим колонку unit_id в таблицу product_price
  8343.         $result = @$this->db->query("SHOW COLUMNS FROM `" . DB_PREFIX . "product_price` WHERE `field` = 'unit_id'");
  8344.         if (!$result) return $old_version;
  8345.  
  8346.         if (!$result->num_rows) {
  8347.             $result = @$this->db->query("ALTER TABLE  `" . DB_PREFIX . "product_price` ADD `unit_id` INT(4) DEFAULT 0");
  8348.         }
  8349.         if (!$result) return $old_version;
  8350.  
  8351.         // Добавим колонку unit_id в таблицу order_product
  8352.         $result = @$this->db->query("SHOW COLUMNS FROM `" . DB_PREFIX . "order_product` WHERE `field` = 'unit_id'");
  8353.         if (!$result) return $old_version;
  8354.  
  8355.         if (!$result->num_rows) {
  8356.             $result = @$this->db->query("ALTER TABLE  `" . DB_PREFIX . "order_product` ADD `unit_id` INT(4) DEFAULT 0 AFTER `quantity`");
  8357.         }
  8358.         if (!$result) return $old_version;
  8359.  
  8360.         //show index from `oc_attribute_value` where `key_name` = 'key_guid'
  8361.         $result = @$this->db->query("SHOW INDEX FROM `" . DB_PREFIX . "attribute_value` WHERE `key_name` = 'key_guid'");
  8362.         if (!$result) return $old_version;
  8363.  
  8364.         if (!$result->num_rows) {
  8365.             //ALTER TABLE  `oc_attribute_value` ADD INDEX `key_guid` (`guid`)
  8366.             $result = @$this->db->query("ALTER TABLE  `" . DB_PREFIX . "attribute_value` ADD INDEX `key_guid` (`guid`)");
  8367.         }
  8368.         if (!$result) return $old_version;
  8369.  
  8370.         // Проверим в необходимости модификации таблицы unit_to_1c
  8371.         $result = @$this->db->query("SHOW COLUMNS FROM `" . DB_PREFIX . "unit_to_1c` WHERE `field` = 'code'");
  8372.         if (!$result) return $old_version;
  8373.  
  8374.         if ($result->num_rows) {
  8375.             $result = @$this->db->query("ALTER TABLE  `" . DB_PREFIX . "unit_to_1c` CHANGE `code` `number_code` INT(4) DEFAULT 0");
  8376.             if (!$result) return $old_version;
  8377.         }
  8378.  
  8379.         $result = @$this->db->query("SHOW COLUMNS FROM `" . DB_PREFIX . "unit_to_1c` WHERE `field` = 'fullname'");
  8380.         if (!$result) return $old_version;
  8381.  
  8382.         if ($result->num_rows) {
  8383.             $result = @$this->db->query("ALTER TABLE  `" . DB_PREFIX . "unit_to_1c` CHANGE `fullname` `full_name` VARCHAR(50) DEFAULT ''");
  8384.             if (!$result) return $old_version;
  8385.         }
  8386.  
  8387.         $result = @$this->db->query("SHOW COLUMNS FROM `" . DB_PREFIX . "unit_to_1c` WHERE `field` = 'eng_name2'");
  8388.         if (!$result) return $old_version;
  8389.  
  8390.         if ($result->num_rows) {
  8391.             $result = @$this->db->query("ALTER TABLE  `" . DB_PREFIX . "unit_to_1c` DROP `eng_name2`");
  8392.             if (!$result) return $old_version;
  8393.         }
  8394.  
  8395.         $result = @$this->db->query("SHOW INDEX FROM `" . DB_PREFIX . "unit_to_1c` WHERE column_name = 'unit_id'");
  8396.         if (!$result->num_rows) {
  8397.             @$this->db->query("ALTER TABLE  `" . DB_PREFIX . "unit_to_1c` ADD  `unit_id` SMALLINT(4) NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`unit_id`)");
  8398.             @$this->db->query("ALTER TABLE  `" . DB_PREFIX . "unit_to_1c` ADD INDEX `key_guid` (`guid`)");
  8399.             @$this->db->query("ALTER TABLE  `" . DB_PREFIX . "unit_to_1c` ADD INDEX `key_name` (`name`)");
  8400.         } else {
  8401.             @$this->db->query("ALTER TABLE  `" . DB_PREFIX . "unit_to_1c` CHANGE  `unit_id`  `unit_id` SMALLINT(4) NOT NULL AUTO_INCREMENT");
  8402.  
  8403.             $result = @$this->db->query("SHOW INDEX FROM `" . DB_PREFIX . "unit_to_1c` WHERE column_name = 'guid'");
  8404.             if ($result->num_rows > 1) {
  8405.                 foreach($result->rows as $row) {
  8406.                     @$this->db->query("ALTER TABLE  `" . DB_PREFIX . "unit_to_1c` DROP INDEX `" . $row['Key_name'] . "`");
  8407.                 }
  8408.                 @$this->db->query("ALTER TABLE  `" . DB_PREFIX . "unit_to_1c` ADD INDEX `key_guid` (`guid`)");
  8409.             }
  8410.  
  8411.             $result = @$this->db->query("SHOW INDEX FROM `" . DB_PREFIX . "unit_to_1c` WHERE column_name = 'name'");
  8412.             if (!$result->num_rows) {
  8413.                 @$this->db->query("ALTER TABLE  `" . DB_PREFIX . "unit_to_1c` ADD INDEX `key_name` (`name`)");
  8414.             }
  8415.         }
  8416.  
  8417.         if (!$result) return $old_version;
  8418.  
  8419.  
  8420.         if ($result) {
  8421.             // После добавления колонки, запишем в нее значения
  8422.             // Подготовим список единиц для обновления
  8423.             $units = array();
  8424.             $query = $this->query("SELECT DISTINCT `unit_id` FROM `" . DB_PREFIX . "product_unit`");
  8425.             if ($query->num_rows) {
  8426.                 $units[] = $query->row['unit_id'];
  8427.             }
  8428.             $this->log($units,2);
  8429.  
  8430.             // Прочитаем названия из классификатора
  8431.             $units_data = array();
  8432.             foreach ($units as $unit_id) {
  8433.                 $query = $this->query("SELECT `number_code`,`rus_name1`,`eng_name1`,`name` FROM `" . DB_PREFIX . "unit` WHERE `unit_id` = " . $unit_id);
  8434.                 if ($query->num_rows) {
  8435.                     $units_data[$unit_id] = array(
  8436.                         'name'          => $query->row['name'],
  8437.                         'number_code'   => $query->row['number_code'],
  8438.                         'rus_name1'     => $query->row['rus_name1'],
  8439.                         'eng_name1'     => $query->row['eng_name1']
  8440.                     );
  8441.                 }
  8442.             }
  8443.  
  8444.             // Удаляем классификатор
  8445.             //$this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "unit`");
  8446.             //$this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "unit_group`");
  8447.             //$this->db->query("DROP TABLE IF EXISTS `" . DB_PREFIX . "unit_type`");
  8448.  
  8449.             if (count($units_data)) {
  8450.  
  8451.                 // Обновляем единицы
  8452.                 foreach ($units_data as $unit_id => $unit) {
  8453.                     $this->query("UPDATE `" . DB_PREFIX . "product_unit` SET `unit_id` = " . $unit['number_code'] . " WHERE `unit_id` = " . $unit_id);
  8454.                 }
  8455.             }
  8456.         }
  8457.  
  8458.         $version = '1.6.3.12';
  8459.         $message .= "Изменения в версии теперь смотрите в вкладке Обновления<br />";
  8460.         $message .= "Обновление с версии " . $old_version . " на версию " . $version ." прошло успешно";
  8461.  
  8462.         return $version;
  8463.  
  8464.     } // update1_6_3_12()
  8465.  
  8466. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement