21 янв. 2017 г., 18:10

Трудности с импортом остатков из xml (модуль modimporter)

Доброго времени! Сразу скажу, в php не силен. Возникла трудность с задачей, прощу направить. Модуль, как я понял, позволяет импортировать в базу сайта информацию выгруженную из 1с. В выгруженном файле есть остатки — «Количество». Находятся на уровне с ценами. Для примера:
<Предложение> <Ид>ab43f47d-b47a-11e6-9504-406186caa5f1<Ид/> <Артикул/> <Наименование>Кондитерское изделие фигурное Дед Мороз 60г<Наименование/> <БазоваяЕдиница Код="796" НаименованиеПолное="Штука" МеждународноеСокращение="PCE"> <Пересчет> <Единица>796<Единица/> <Коэффициент>1<Коэффициент/> <Пересчет/> <БазоваяЕдиница/> <Цены> <Цена> <Представление> 57 RUB за шт<Представление/> <ИдТипаЦены>70f63c69-5c82-11e6-8eb6-406186caa5f1<ИдТипаЦены/> <ЦенаЗаЕдиницу>57<ЦенаЗаЕдиницу/> <Валюта>RUB<Валюта/> <Коэффициент>1<Коэффициент/> <Цена/> <Цены/> <Количество>27<Количество/> <Склад ИдСклада="456684b4-0cd2-4157-a228-4ed059397969" КоличествоНаСкладе="27"/> <Предложение/>
В процессоре модуля есть метод StepImportCreatePrices() в классе console.class.php Так вот изначально метод, видимо, добавляет только цены, хотя, перед методом есть коментарий "// Создаем цены и остатки" Во всяком случае кусок метода выглядит вот так:
$prices = current((array)$raw_data['Цены']); //['Цена'] $data = array( "price" => !empty($prices['ЦенаЗаЕдиницу']) ? $prices['ЦенаЗаЕдиницу'] : 0, );
попробовал аналогично сделать с остатками:
$prices = current((array)$raw_data['Цены']); //['Цена'] $amount = current($raw_data['Количество']); $data = array( "price" => !empty($prices['ЦенаЗаЕдиницу']) ? $prices['ЦенаЗаЕдиницу'] : 0, "amount" => !empty($raw_data['Количество']) ? $raw_data['Количество'] : 0 );
Но это не сработало. Причем в процессе экспериментов возникло ощущение, что, возможно, в запросе с апдейтом строки amount совсем отсутствует (формирование самого запроса найти не смог пока).
Подскажите, пожалуйста, куда стоит копать, может я вообще не в том месте ищу, остатки не берутся из файла совсем или не ту переменную использовать пытаюсь? Никак не удается самому разобраться в работе модуля.
Зачастую импорт приходится доделывать, поскольку у разных клиентов форматы файлов могут отличаться. В принципе, то, что Вы показали, верно и должно прописаться. Только я бы немного поправил:
$prices = current((array)$raw_data['Цены']); $amount = current($raw_data['Количество']); $data = array( "price"=>!empty($prices['ЦенаЗаЕдиницу']) ? $prices['ЦенаЗаЕдиницу'] : 0, "amount" => !empty($amount) ? $amount : 0 );
При отладке очень помогает скрипт запуска импорта из консоли. Доходите до нужного шага, и в функции, которая его обрабатывает, в месте, где получаете данные, прописываете что-то типа
print_r($data); exit;
Это поможет увидеть, какие данные Вы получаете из xml. Также вывод можно сделать после записи в объект или после вызова процессора.
Спасибо!
А подскажите… глупый, наверное, вопрос… как правильно вызвать модуль импорта из консоли? Были мысли ее как-то использовать, но я не знаю, как верно вызвать нужный модуль.
Есть скрипт:
'; ini_set('display_errors', 1); $modx->switchContext('web'); $modx->setLogLevel(3); $modx->setLogTarget('HTML'); $namespace = 'modimporter'; // Неймспейс комопонента // Добавить веб-сессию текущего пользователя // Если вы не авторизованы во фронте, можете получить // в результате выполнения сообщение Доступ запрещён! // $modx->user->addSessionContext('web'); // Удалить веб-сессию текущего пользователя // $modx->user->removeSessionContext('web'); // Сбросить сессию компонента // $_SESSION["SM_1C_IMPORT"] = array(); // Вывести данные сессии компонента // print_r($_SESSION["SM_1C_IMPORT"]); // print_r($_SESSION["SM_1C_IMPORT"]); // unset($_SESSION["modImporter"]); $params = array( // "step" => "SDFsdf", // "debug" => false, // "mode" => "checkauth", // "modimporter_step" => "modimporter_checkauth", // "modimporter_step" => "modimporter_console_init", // "modimporter_step" => "modimporter_drop_tmp_tables", // "modimporter_step" => "modimporter_create_tmp_tables", // "modimporter_step" => "modimporter_write_tmp_xlsx_shared_strings", // "modimporter_step" => "modimporter_write_tmp_categories", "modimporter_step" => "modimporter_write_tmp_data", // "modimporter_step" => "modimporter_import_data", // "modimporter_step" => "modimporter_import_update_categories", // "modimporter_step" => "modimporter_import_update_categories", // "modimporter_step" => "modimporter_import_create_categories", // "modimporter_step" => "modimporter_import_update_goods", // "modimporter_step" => "modimporter_import_create_goods", // "modimporter_step" => "modimporter_import_flush_prices", // "modimporter_step" => "modimporter_import_create_prices", // "filename" => "import.xml", // "username" => "admin", // "password" => "wefwef", "outputCharset" => "utf-8", ); // $_SERVER['PHP_AUTH_USER'] = 'admin'; // $_SERVER['PHP_AUTH_PW'] = 'admin'; if(!$response = $modx->runProcessor('modimporter/import/console', $params , array( 'processors_path' => $modx->getObject('modNamespace', $namespace)->getCorePath().'processors/', ))){ print "Не удалось выполнить процессор"; return; } $memory = round(memory_get_usage(true)/1024/1024, 4).' Mb'; print "
Memory: {$memory}
"; $totalTime= (microtime(true) - $modx->startTime); $queryTime= $modx->queryTime; $queryTime= sprintf("%2.4f s", $queryTime); $queries= isset ($modx->executedQueries) ? $modx->executedQueries : 0; $totalTime= sprintf("%2.4f s", $totalTime); $phpTime= $totalTime - $queryTime; $phpTime= sprintf("%2.4f s", $phpTime); print "
TotalTime: {$totalTime}
"; print_r($response->getResponse()); // $objects = $response->getObject(); // foreach($objects as $object){ // }
Спасибо большое. Наконец вернулся к задаче и с Вашей помощью удалось дойти до следующей «мертвой точки».
Данные верно попадают куда надо в переменных, кроме запроса. Запрос с ценой формируется в коде так:
$q2 = $this->modx->newQuery('modResource'); $q2->command('update'); $q2->set($data); $q2->where(array( "id" => $tmp_object->resource_id, ));
и формируется честно, например:
UPDATE `modx_site_content` SET `price` = 19 WHERE `modx_site_content`.`id` = 37216
а вот как только я пытаюсь, даже не добавить в дату, а заменить price на «amount» или хотя бы «test» запрос перестает нормально формироваться:
UPDATE `modx_site_content` WHERE `modx_site_content`.`id` = 21043
Насколько удалось понять — при формировании запроса (так и не нашел конкретное место, честно говоря) происходит что-то вроде проверки валидности наименования (price, amount и тд). И наименования полей к типу modResource (с указанием таблицы без префикса: site_content) прописаны в паре файлов xml и описаны в файлах php. Но ключевая проблема, что как раз таки где все это описано, конкретно описание «price» так и не удалось обнаружить во всем ядре. Не могли бы Вы подсказать в каком направлении можно дальше подумать, а то идеи кончились. Может, например, известно, где может быть описано данное поле (ptice), что бы оно как-то обрабатывалось при формировании sql?

Добавить комментарий