Восстановление последовательности документов по зачету аванса




Принцип обмена данными из 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='\

6 Comments

  1. leosoft

    Вот это поподробнее, пожалуйста «так как более поздние проведенные документы влияют на более ранние».

    Чем штатное групповое перепроведение не устраивает?

    Reply
  2. Keath

    (1) Групповое перепроведение документов не разбирает всю цепочку движений по документам расчетов с контрагентами. Она просто еще раз перепроводит документы по их дате по одному от более ранних к более поздним. Точно так же при закрытии месяца ошибки остаются. Для того, чтобы сделать все движения по 3 субконто верными, необходимо всю цепочку документов распровести, а только потом проводить в хронологическом порядке.

    Можно и штатными средствами воспользоваться, но для этого нужно или накладывать много разных отборов, чтобы учесть все возможные типы документов в сочетании с их реквизитами и порядок выставления авансов, или исправлять ошибку глобально, без отборов, но тогда необходимо помнить про зачастую имеющуюся «помойку» в документах, когда рядом с проведенными есть куча всяких черновиков, которые проводить не нужно.

    Обработка же учитывает все это, формируя заново движения только по изначально проведенным документам.

    Reply
  3. Keath

    (3)

    Достаточно запустить групповое перепроведение документов.

    Был не прав. На релизе БП 3.0.68 самые популярные ошибки исправляются.

    Для маленьких организаций гораздо удобнее будет пользоваться типовыми средствами. Но ошибки, которые не хочется исправлять руками, а хочется «одной кнопкой», чаще делают в базах с большим количеством документов.

    А в таких базах, если мы заранее знаем, какая цепочка документов «косячит», ради 10-20 документов запускать перепроведение всех реализаций/поступлений и всех движений по расчетому счету/кассе за месяц или (о, ужас) за квартал может занять много времени и попутно исправить те ошибки, которые другие пользователи на других участках у себя считали верными и нашлепали ручных операций, учитывающих те остатки.

    Естественно, если никто не делает ошибок или база маленькая, то данная обработка будет не нужна.

    Reply
  4. leosoft

    (4) А для этого через справочник открываем контрагента и нажимаем «Документы», отмечаем нужные и препроводим документы конкретного контрагента.

    Reply
  5. Lukich66

    Вы забыли сказать как найти этого самого к/а чтобы его передокументить.

    Автору + за понимание проблем восстановления последовательностей, считаю это недосмотром создателей, вот теперь ч/з 7-10 лет только начинает приходить понимание этой ляпы. УПП,КА там это все еще и в регистрах покупки и реализации- мрак. Штатные «восстановлялки» -тупая последовательная машина на базе в 40г работает 2дня

    Reply
  6. nikolka75

    Обработка просто распроводит и потом проводит документы по счету.

    Это легко сделать в журнале операций.

    В связи с чем цена мне кажется завышенной (.

    К сожалению в моем случае этого (распроведения и проведения) не достаточно.

    Думал что в обработке за 5 старт мани делает что то еще … оказалось что больше ничего нет!

    Reply

Leave a Comment

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