Дефектура для "Торговля и склад 9.2"




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

36 Comments

  1. valent

    Если ДатаДок > ПоследняяЗакупка Тогда

    {…1П ДЕФЕКТУРА.ERT(168)}: Операции сравнения на больше-меньше допустимы только над значениями совпадающих базовых типов (число, строка, дата)

    Reply
  2. valent

    1П ДЕФЕКТУРА.ERT(203)}: Поле агрегатного объекта не обнаружено (КоличествоКонОст)

    Reply
  3. ELENAB

    отчет не функционирует

    Reply
  4. wolfsoft

    Сейчас посмотрю.

    Reply
  5. wolfsoft

    2 ELENAB: Не все так плохо 🙂

    2 valent:

    Первая ошибка: связана с тем, что я не предусмотрел вариант, когда в партии не указан приходный документ. Видимо у вас метод расчета себестоимости «по среднему»?

    Вторая ошибка: тоже моя ошибка, всегда формировал отчет при условии, что дата остатков совпадает с датой конца периода анализа, поэтому просмотрел эту ошибку. Исправлено.

    Пожалуйста проверьте.

    Спасибо всем, кто принял и принимает участие в тестировании моих разработок.

    Жду новых комментариев!

    Reply
  6. Starik

    «Дамы и Господа! Не забываем «плюсовать» рейтинг и оставлять комментарии! В противном случае — при несоответствии рейтинга количеству скачиваний — доступ к обработке будет ограничен.»

    А какое реальное соответствие рейтинга и количество скачиваний?

    А то я вот тоже подумываю закрыть доступ к обработкам!?

    Reply
  7. wolfsoft

    2 Starik: «А какое реальное соответствие рейтинга и количество скачиваний?»

    :))) Да кто ж его знает?

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

    Reply
  8. так посмотрел я отчетик прикольный понравился, неплохо былобы добавить еще и разбивку по складам.

    и еще почемуто в поставщике вместо справочника контрагентов поподаешь в виды свойств.

    )))

    Reply
  9. wolfsoft

    Упс! При исправлении прошлой ошибки внес новую 🙂 Исправил 🙂

    Уважаемые, пожалуйста скачайте новую версию отчета. Предыдущая версия ВРЕТ!

    Сорри 🙂



    Pan Klyaxa: «и еще почемуто в поставщике вместо справочника контрагентов поподаешь в виды свойств»

    Отчет-то делал для себя, поэтому отбор по «основному свойству номенклатуры» назвал «поставщик», т.к. у меня основное свойство номенклатуры — поставщик товара.

    Reply
  10. wolfsoft

    А вот с разбивкой по складам — увы. Отчет строится по регистру «Партии», а в нем нет измерения «склад». Если МОЛ реально не используется в учете, то можно вместо склада использовать МОЛ, присвоив каждому складу своего уникального МОЛ. Тогда отбор по МОЛ будет аналогичен отбору по складу.

    Reply
  11. valent

    Если б еще колонку добавить «Количество дней продажи», которая бы показывала на какое количество дней продаж хватает существующих остатков…. )

    Reply
  12. valent

    И еще:

    А можно как-то получить реальное количество дней продаж в заданном периоде?

    Reply
  13. wolfsoft

    2 valent:

    про колонку «Количество дней продажи» — хорошая идея, сделаю 🙂

    а вот про «реальное количество дней продаж в заданном периоде» — не очень понял, что под этим подразумевается?

    Reply
  14. wolfsoft

    2 valent:

    Добавлено 🙂

    Reply
  15. valent

    про колонку «реальное количество дней продаж в заданном периоде» вопрос снимается здесь.

    Просто интересно, можно ли получить реальное количество дней продажи, т.е. для примера: если за 30 дней анализируемого периода продажи были только 1, 5, 10 (всего 3 дня).

    Reply
  16. wolfsoft

    2 valent:

    Теперь понятно, имеете ввиду количество тех дней, в которые непосредственно были продажи товара. Можно, конечно, а практический смысл?

    Reply
  17. valent

    2 wolfsoft:

    проследить востребованность товара.

    А по регистру продаж аналогичный отчет не получится?

    Reply
  18. wolfsoft

    2 valent:

    По поводу востребованности товара: мне думается, что это не очень подходящий показатель, хотя… может ты и прав, может кому-то нужен этот показатель. Подумаю, наверное добавлю.

    По поводу регистра «Продажи» — в принципе, можно, но есть ряд моментов:

    1. там только обороты, определить дейстительное количество дней, которое товар был в продаже, не получится — нет остатков, хотя можно брать из запроса по регистру остатков;

    2. нет информации о дате закупки;

    3. нет отбора по МОЛ.

    Reply
  19. wolfsoft

    Блин, старею 🙂

    Окончательно исправил ошибку, которую внес при «исправлении прошлой ошибки».

    Уважаемые, пожалуйста скачайте новую версию отчета.

    Сорри 🙂

    Reply
  20. lordmb

    А все можно было бы построить на одном запросе к регистрам ОстаткиТМЦ. Будет быстрее.

    «//{{ЗАПРОС(Сформировать)

    |Период с ВыбНачПериода по ВыбКонПериода;

    |Обрабатывать НеПомеченныеНаУдаление;

    |Без итогов;

    |Номенклатура = Регистр.ОстаткиТМЦ.Номенклатура;

    |Количество = Регистр.ОстаткиТМЦ.Количество;

    |Внутреннее = Регистр.ОстаткиТМЦ.Внутреннее;

    |Функция КоличествоНачОст = НачОст(Количество);

    |Функция КоличествоРасход = Расход(Количество);

    |Функция КоличествоКонОст = КонОст(Количество);

    |Группировка Номенклатура без упорядочивания без групп;

    |Группировка День;

    |Условие(Внутреннее<>1);

    Reply
  21. wolfsoft

    Вы, извините, глупость сморозили 😉 Сами-то подумайте, отчет еще раз посмотрите, попробуйте, используя свой запрос, получить такой же отчет. Думаю, быстро сами все поймете 🙂

    Reply
  22. wolfsoft

    2 lordmb: Не претендую на самое оптимальное решение, наверняка можно как-то оптимизировать, но точно не так, как Вы предложили 🙂

    Reply
  23. lordmb

    to: wolfsoft

    Глупость — не глупость, но я надеялся, не надо будет разжевывать мою мысль. 🙂

    И на моей работе мой отчет используется (и выполняется в разы быстрее твоего) 🙂

    До твоего отчета мне надо добавить пару мелочей, но суть-то таже самая:

    Среднесуточные продажи = продажи/кол-во дней наличия.

    У тебя

    Если (ОстатокКолво > 0) или (Запрос.КоличествоПриход > 0) Тогда

    ДнейВПродаже = ДнейВПродаже + 1;

    КонецЕсли;

    У меня ДнейВПродаже вычисляется методами ТаблицыЗначений:

    ТЗ.НоваяКолонка(«КолвоДней»);

    ТЗ.Заполнить(1,,,»КолвоДней»);

    ТЗ.Свернуть(«Номенклатура»,»КоличествоРасход,КолвоДней,КоличествоКонОст»);

    Короче, думай про меня как хочешь.

    Reply
  24. wolfsoft

    2 lordmb: Спасибо, за ап 🙂

    По твоей мысли, которую ты не хочешь разжевывать, мои вопросы, которые мне бы тоже не хотелось разжевывать, так как они очевидны:

    1. Как твоим ОДНИМ запросом получить отчет, когда, например, анализируем продажи за сентябрь-октябрь 2006 года, а остатки берем текущие на 24-11-2006?

    2. Как твой запрос учитывает возвраты?

    3. Как твоим запросом получить выручку?

    4. Как твоим запросом получить дату и документ последней закупки и последней продажи?

    И т.д. и т.п.

    Если это называется — «пара мелочей» — то не вижу смысла продолжать обсуждение.

    Reply
  25. wolfsoft

    2 lordmb: И еще добавлю, я не хотел Вас оскорбить или обидеть, и я не думаю о Вас плохо 🙂 Нормальный процесс обсуждения 🙂 В принципе, можно подумать про свертку (Ваш предыдущий пост), но в моем случае это скорее всего не ускорит работу, потому что обход группировки все равно делать надо… А основные «тормоза» в отчете появились именно после добавления тех мелочей, которые я перечислил ниже, до этого он работал намного быстрее.

    Reply
  26. yuva

    Посмотрим-понюхаем-пощупаем….

    Reply
  27. Irishka

    Обработка просто СУПЕР ! То что нужно, большинству работников занимающихся заявками для поставщиков , я лишь добавила вывод цены товаров не учавствовший в продажах, и все идеально !

    Огромное спасибо !!!!!

    Reply
  28. wolfsoft

    Обновлено. Исправлен небольшой глюк при расчете количества дней продажи.

    Reply
  29. VV

    А добавить Иришкины <<вывод цены товаров не учавствовший в продажах>>? Плохая мысль?

    Reply
  30. wolfsoft

    2 VV: В моей работе мне это не нужно. Обратитесь к Иришке 😉

    Reply
  31. chev

    Здорово. Чуть-чуть «подкручу» и все будет хорошо. Ставлю «плюс»

    Reply
  32. wolfsoft

    Будут вопросы, благодарности прошу к нам на сайт.

    Reply
  33. gugal

    >>В противном случае — при несоответствии рейтинга количеству скачиваний — доступ к обработке будет ограничен.

    А что, если я скачал, а оказалась фигня, то я тоже должен «+» ставить?

    Reply
  34. validat

    Полезная обработка. Буду на её основе учиться программировать в 1С.

    Reply
  35. stat.81

    Классная обработка

    Reply
  36. Иваныч

    Я пошел другим путём.Проанализировав по каждой розничной точке сколько чего продается за неделю, поставил минимальный остаток товара на каждую номенклатурную позицию. И заявку делаю согласно минимального остатка по конкретной розничной точке. А если на сезонную закупку (зимние тех. жидкости для автомобилей, например) уже рассчитываю из предыдущей сезонной продажи. Хотя торговля — такой процесс, что предсказать бывает сложно: 2 года назад закупил стеклооомыватель, что и к лету остался, а в прошлую зиму еще и дозаказывали такое же количество 2 раза.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *