<?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='\
симпатичный отчет!
Держи 5
Основная проблема таких отчетов — низкая скорость работы на больших объемах данных (причем скорость падает экспоненциально с возрастом базы).
Насколько я понимаю, причина в том, что все они основаны на выборке таблицы регистраторов из виртуальной таблицы оборотов регистра «Взаиморасчеты с контрагентами».А поскольку нижнюю границу начала выборки определить нельзя (выбирать приходится от Р.Х.), то на каждую сумму остатка приходится выбирать по 2-3 тысячи строк (если обороты с контрагентами интенсивные).
В результате, например, подобные отчеты на базе УПП/УТ 3- летнего возраста формируются у меня уже минут по 15-20 (по 18-20 сек на контрагента).
И что-то все попытки оптимизации пока никуда не ведут особо.
(3) den_valley,
не понял вас. 15 минут по 20 секунд на контрагента получаем 45 контрагентов. по 45 контрагентам медленно формируются запросы по документам… как-то не верится. У меня на данный момент в базе 387 контрагентов по которым есть хоть какая-то задолженность в том числе с 2010 года. Отчет формируется: до вывода в отчет 25 секунд, вывод в отчет еще 7 секунд. Менеджеры формируют отчет только по «своим» контрагентам (RLS) соответственно у них еще быстрее формируется.
(4) V1V,
Ну не на всех контрагентах запрос так долго работает.
18-20 секунд выдает на 6375 записях (тестовый контрагент есть у меня один)
А так, при запуске подобного отчета в ротацию год назад время работы было 5 минут.
Сейчас 15-20.
Количество активных договоров около 1500.
И у меня отчет по ПКЗ (хотя принцип выборки, увы, тот же), потому формирует один человек по всей базе.
И выхода то особо нет, или использовать регистр «Взаиморасчеты по документам»(или ему подобные) со своими проблемами, или считать ПДЗ/ПКЗ по ФИФО расчетным методом (с потерей производительности).
Мониторю различные ресурсы в надежде найти «третий вариант», но возможно его просто не существует в природе.
(5) den_valley,
Третий вариант — это например регламентное задание, которое будет заполнять регистр, а отчет соответственно строится уже по готовому регистру. Задание запускается всякий раз при изменении в регистре взаиморасчетов. Такой вариант я рассматривал когда платформа стояла 8.1. При переходе на 8.2 проблема отпала.
Такой вариант реализован в УТ 11.
Не подходит по причине того, что регламентное задние задает блокировку транзакций и не позволяет проводит документы оперативно (отдел снабжения не может работать с поставщиками).
Следовательно днем, в рабочее время, запуск его проблематичен….
А ночью результат его работы никому не нужен 🙂
P.S. И скорость работы регл. задания сопоставима со скоростью работы отчета, только отчет работу не блокирует.
(7) den_valley, я имел в виду отдельный регистр. при изменении регистра взаиморасчеты с контрагентами, ну или при проведении документов, являющихся регистраторами в этом регистре, запускаем фоновое задание, которое пересчитывает наш регистр. т.к. это отдельный процесс и запись в регистр идет только им, то мешать этот расчет никому не будет. на счет скорости вы возможно правы, все зависит от того сколько человек используют отчет, в моем случае дебиторку смотрят 30 человек. Если бы у меня были проблемы с быстродействием, то я бы выбрал этот вариант. Но для одного-двух людей я бы точно оставил как есть и не стал бы ничего менять.
Не работает Фильтр контрагентов «Не в группе из списка»
(3) Вот тут оптимизации есть по скоростиhttp://infostart.ru/public/117647/
Выборка начинается не от Р.Х., а от последней «нулевой» задолженности.
(5) Еще вариант сделать регистр сведений (не накопления — будет медленно писаться в него) и распределение отгрузок и оплат хранить там. Я использую у одного клиента такой вариант, т.к. нужны сложные отчеты по задолженности (например, просроченная задолженность по дням в течение месяца). Недостаток: информация в регистре сведений обновляется периодически регламентным заданием.
Надо попробывать
(9) sobeyko2008, не только этот. отбор строится программно. туда вставлены те отборы, которыми люди пользуются, остальные никому не нужны были. переменная ТекстВидСравнения в строке 91 модуля формы. там все формирование отбора, можете добавить при необходимости те что вам нужны
Почему вы считаете что люди не пользуются этим отбором? Ну вот ни хочу я видеть задолженность по контрагентам: Сотрудники, рекламщики, откатчики и т.д. и как с этим быть?
мне к сожалению ни о чем не говорит… я не программист…
(14) sobeyko2008, те у кого работает этот отчет — не пользуются. про всех на свете людей я не говорил. отчет используют менеджеры по продажам, а они видят только «своих» контрагентов. Да и откуда у других будет дебиторка? типа мы сотруднику что-то продали, а он нам не заплатил?
А если например так получилось что Покупатель и он же поставщик и рассчитался он со мной товаром. То отчет всеравно показывает что он нам должен.
тогда вы сделаете корректировку долга и перенесете задолженность с одного договора на другой (смотрите методологию) и отчет все покажет правильно.
спасибо!пригодился
(5) den_valley, можете попробовать вариант, предложенный в публикации«Неоплаченные долги при распределении оплаты по правилу ФИФО одним запросом и намного быстрее, чем Вы думали» . Там используется принципиально другой подход, позволяющий получить нужный результат гораздо быстрее. Речь идет не о минутах, а секундах. Конфигурацию менять не нужно.
реквизит «число дней задолженности» в договоре появляется только при включении галочки — по документам расчетов с контрагентами, затем галочка —
контролировать число дней задолженности.
автор заявляет что отчет будет указывать просрочку и без этого.
я не прав?
(21) Нет под рукой релиза торговли 10.3. На память уже тоже не помню последовательность галочек. Ничего не могу по этому поводу сказать. Сорри. Давно это было
Здесь будет работать?
Управление торговым предприятием для Казахстана, редакция 2.0
спасибо! очень интересная статья/разработка!