Заполнение документа Премия из Excel в ЗУП 3.1




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

15 Comments

  1. hopter

    Скачал из любопытства, просто потому, что недавно нужно было грузить премию.

    Советую вам больше никогда ни в каком виде в документах связанных с расчетом зарплаты не использовать регистр ТекущиеКадровыеДанныеСотрудников.

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

    Полбеды если у вас нет обособленных подразделений и НДФЛ идет в одну кучу. А если они у вас есть, то вы, подставив неверное подразделение, отправите доход и налог не по адресу, а это уже может быть чревато определенными последствиями с налоговой.

    Можете, например, воспользоваться функцией КадровыеДанныеСотрудников из общего модуля КадровыйУчет, возвращает много интересного.

    Также вы не заполняете некоторые поля, которые не видны пользователю, но которые заполняются при интерактивном вводе данных, соответственно они не попадают в регистры.

    Таких полей в разных документах третьего ЗУПа очень много, последствия их незаполнения могут быть разными.

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

    Ну и почему бы сразу из экселя не грузить, без всяких копирований.

    Ворчать закончил :)))

    Reply
  2. wonderboy

    (1) Спасибо вам за обстоятельное сообщение! 🙂

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

    Про функцию КадровыеДанныеСотрудников знаем, пользуем. 🙂 В данном случае пользователь просил подразделение «которое он видит в списке сотрудников». А этот регистр как раз таки для вывода тек данных в списке сотрудников и предназначен. Будет минутка — добавим версию с подразделением, выданным кадровыми данными.

    А по невидимым полям — они важны для премий, рассчитываемых по формулам. Здесь же загрузка премий «фикс. суммой». Могу конечно что-то упускать но вроде за пол года активного пользования в достаточно большой компании пока вопросов не возникло.

    Reply
  3. wonderboy

    Кстати обособленные подразделения у этой компании есть. Но если сотрудник работает в филиале — филиал будет указан в шапке документа. А если просто в нескольких подразделениях как совместитель — она не подхватит этого сотрудника, т.к. имя будет совпадать.

    Reply
  4. hopter

    (2)

    В данном случае пользователь просил подразделение «которое он видит в списке сотрудников». А этот регистр как раз таки для вывода тек данных в списке сотрудников и предназначен.

    вы заблуждаетесь, в списке сотрудников отражается реальная должность и подразделение на рабочую дату, и она не из этого регистра

    а временные переводы вообще ни пишутся в этот регистр, я могу перевести человека на полгода в новое подразделение, а там по прежнему будет старое

    (3) подразделение в шапке абсолютно ни на что не влияет, кроме интерактивного заполнения, сотрудник в единственном экземпляре, временно переведен в обособленное подразделение со своим кпп и зарегистрированное в другой налоговой, а вы его закинете по старому подразделению

    НДФЛ пойдет неправильно, приплыли

    Reply
  5. OlegAr

    очередная реализация «Я хочу», что мешает бухгалтеру сразу заполнить документ в ЗУПе ?

    Reply
  6. wonderboy

    (4) «вы заблуждаетесь, в списке сотрудников отражается реальная должность и подразделение на рабочую дату»

    специально проверил еще разок — в приложении скрин запроса дин. списка сотрудников (спр. Сотрудники). Может мы про разные списки?

    «подразделение в шапке абсолютно ни на что не влияет, кроме интерактивного заполнения»

    про подразделение в шапке речь не идет. В шапке есть Организация, которая может быть филиалом — а их тоже иногда называют обособленными подразделениями.

    А с временными переводами — да, криво, согласен, обновил файл в публикации, подразделение вытаскивается функцией кадровых данных.

    Reply
  7. wonderboy

    (5) Бывает что список на премирование готовят руководители подразделений, у которых нет доступа в ЗУП. И готовят его в Экселе.

    А так — да, обычно такой диалог получается

    — Так заполните в документе сотрудников и суммы

    — «Нам в Экселе быстрее», «Мы к Экселю привыкли».

    — Так может в Экселе тогда вообще зарплату считать? 🙂

    — В Экселе регл. отчетность не формируется.

    — Ну так забудьте про Эксель, привыкните документы в 1С вводить, дело времени

    — Нет, мы без Экселя никак

    — …

    Reply
  8. hopter

    (6)

    специально проверил еще разок — в приложении скрин запроса дин. списка сотрудников (спр. Сотрудники). Может мы про разные списки?

    смахивает на то, что уже покопались любители этого регистра, либо рудимент какой-то старой конфигурации

    скрин как это выглядит в типовой, там стрелка где у вас вставка из этого регистра и отмечены реальные должность и подразделения

    а из этого три поля всего берутся

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

    (если он конечно в одной базе не ведется учет по нескольким организациям или он ранее увольнялся)

    и то, что она там даже не последняя занимаемая, я вам показал на примере временных перемещений

    т.е. регистр весьма специфический и опираться впрямую на него в подобных случаях нельзя

    «подразделение в шапке абсолютно ни на что не влияет, кроме интерактивного заполнения»

    про подразделение в шапке речь не идет. В шапке есть Организация, которая может быть филиалом — а их тоже иногда называют обособленными подразделениями.

    еще раз, в этой вашей организации/филиале могут быть свои обособленные подразделения с разными кпп и зарегистрированные в разных налоговых

    для вас они все будут в справочнике подразделения и получается, что

    доставая неверное подразделение, в вашем первом варианте, вы приводили к искажению расчетов по ндфл

    да и просто к искажению распределения начислений, когда все начисления в одном подразделении, а премия в другом

    Reply
  9. pentanom

    Простая ситуация: одна организация (не отображается в шавке документа) и все сотрудники в одном подразделении. И ничего не заполняется. Но конфигурация 3.1.8.246. т эля этой конфигурации ?

    Reply
  10. wonderboy

    (10) Проверял в свое время на версиях 3.1.2.212, 3.1.3.136, 3.1.3.156

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

    Reply
  11. pentanom

    (11)

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

    Предполагается ?

    Reply
  12. wonderboy

    (12) по мере возможности

    Reply
  13. pentanom

    (13)Как узнать, что возможность появилась ?

    Reply
  14. wonderboy

    (14) Сообщу здесь, обновлю публикацию

    Reply
  15. pentanom

    (15)

    Сообщу здесь, обновлю публикацию

    Спасибо. Буду ждать.

    Reply

Leave a Comment

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