Реестр начисленных пособий за счет ФСС для программы "Зарплата и управление персоналом 2.5"




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

31 Comments

  1. gutentag

    > Отчет позволяет анализировать долю пособий выплачиваемую за счет средств ФСС и за счет работодателя (выводятся в отдельных колонках).

    Отчет в днях не делает разбивку — данные по дням не совпадают с печатной формой «оборота больничного листка» — для ОСНО, а УСН -подойдет.

    ———

    На всякий случай, на СКД, есть похожий отчет http://infostart.ru/projects/2608/ и еще отчет http://infostart.ru/projects/2363/

    Reply
  2. director04

    (1) согласен, но жаль, что ограничиваются только больничными листами

    Reply
  3. director04

    (1). Отчет в днях не делает разбивку — данные по дням не совпадают с печатной формой «оборота больничного листка»

    ___________________________________________________

    Отчет работает по регистрам расчета «ОсновныеНачисленияРаботниковОрганизаций» и «ДополнительныеНачисленияРаботниковОрганизаций» … Смотрите причину там.

    PS: Если хотим видеть разбивку по работодателю или нет — учавствует ригистр «ЕСНОсновныеНачисления» и «ЕСНДополнительныеНачисления»

    Reply
  4. gutentag

    (4) И как это сделать в вашем отчете?

    Вы можете выложить отчет с «настройками по дням» ?

    Reply
  5. director04

    (4) В настройках выбрать группировку строк «Период регистрации» (можно использовать дополнение по дням), можно не использовать.

    Reply
  6. WiseSnake

    (2) Мой отчет http://infostart.ru/projects/2608/ не ограничивается только больничными, кстати да надо поправить описание…

    Reply
  7. Mickl

    Прежний отчет не работал при Спец режимах,

    а как этот?

    Reply
  8. director04

    (7) если воспроизведется — поправлю

    Reply
  9. director04

    (6) да действительно, при близком рассмотрении отчет довольно удачный. Я бы порекомендовал поправить режимы настройки отчета — рядовому пользователю это как китайская грамота. Тем более что в ЗУП есть универсальные механизмы.

    Reply
  10. Sushka

    Отчет просто замечательный!!!

    Есть ошибка при выборе конца периода (но она легко исправляется)

    И какие еще группировки нужны можно легко добавить (мне нужно было разделить совместителй от основных работников)

    Reply
  11. director04

    (10) Спасибо, Танечка…

    Reply
  12. volna

    Отчет, что надо. Спасибо. Бухгалтера довольны.

    Reply
  13. director04

    Исправлена ошибка по выбору конца периода.

    Reply
  14. AndrejNMU

    Отчет нужный только добавить бы колонку дни .

    за счет рабдателя два , если не попадает под выходной

    хотелось бы видеть один или два дня

    Reply
  15. volna

    Спасибо за доработку.

    Reply
  16. Ochkarito

    В случае нескольких больничных листов (или больничный и продолжение больничного), при группировке по Регистратору, некорректно расчитываются суммы в колонках За счета работодателя и За счет ФСС. В частности построчно пишутся общие суммы.

    Reply
  17. director04

    (16) Хорошо, проверю. Буд признателен если вышлите скрин с ошибкой. Вот адрес: valera2010@corpcentre.ru

    Reply
  18. Ochkarito

    Выслал.

    Reply
  19. director04

    (18) Уже выслал решение. Если результат будет верным — выложу для общего пользования.

    Reply
  20. Ochkarito

    Ага, спасибо. По данным на которых тестировал, вроде бы все верно.

    Reply
  21. Alex Y

    Спасибо за отчет.

    Маленькое «но». Если есть «Пособие по уходу за ребёнком до 1.5 лет», то не попадает ни в «за счет работодателя», ни в «За счет ФСС».

    Reply
  22. director04

    (21) Да, на сколько помню, такое требование выставляли наши расчетчики. Если считаете неверным, то можете свободно удалить данное условие из запросов. (Код открыт)

    Reply
  23. Alex Y

    (22) Посмотрел код. Расхождение в условии:

    И (ВТ_Начисления.Регистратор = ВТ_ОтраженияВУчете.Регистратор)

    Для больничных всё сходиться. Для пособий

    первый регистратор из РегистрРасчета.ОсновныеНачисленияРаботниковОрганизаций — это начисление зарплаты.

    а второй регистратор из РегистрРасчета.ЕСНОсновныеНачисления = Начисление страховых взносов.

    Пока не знаю, как их совместить.

    Reply
  24. director04

    (23) Писал отчет давно, щас не до него… Попробуйте в соединении вот так:

    ВЫБОР

    КОГДА Регистратор ССЫЛКА Документ.НачислениеСбольничных

    ТОГДА …….

    КОГДА Регистратор ССЫЛКА Документ……

    ТОГДА …..

    КОНЕЦ

    или что то типа этого

    Reply
  25. Alex Y

    (24) Я выкрутился таким образом в последнем запросе через РегистрНакопления.ПособияПоУходуЗаРебенкомДоПолутораЛет:

    ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ

    ВТ_Начисления.Организация КАК Организация,

    ВТ_Начисления.ВидРасчета КАК ВидРасчета,

    ВТ_Начисления.ФизЛицо КАК ФизЛицо,

    ВТ_Начисления.ПериодРегистрации,

    СУММА(ВТ_Начисления.Результат) КАК СуммаНачисления,

    ВТ_ОтраженияВУчете.ЗаСчетРаботодателя,

    МАКСИМУМ(ЕСТЬNULL(ВТ_ОтраженияВУчете.ЗаСчетФСС, 0) + ЕСТЬNULL(ПособияПоУходуЗаРебенкомДоПолутораЛетОбороты.СуммаВсегоОборот, 0))

    КАК ЗаСчетФСС,

    СУММА(ВТ_Начисления.ОплаченоДнейЧасов) КАК ОплаченоДнейЧасов,

    ВТ_Начисления.Регистратор,

    ВТ_ОтраженияВУчете.Регистратор КАК РегистраторВОтражении,

    ВТ_Начисления.ПодразделениеОрганизации

    ИЗ

    ВТ_Начисления КАК ВТ_Начисления

    ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ОтраженияВУчете КАК ВТ_ОтраженияВУчете

    ПО ВТ_Начисления.Организация = ВТ_ОтраженияВУчете.Организация

    И ВТ_Начисления.ФизЛицо = ВТ_ОтраженияВУчете.ФизЛицо

    И ВТ_Начисления.ПериодРегистрации = ВТ_ОтраженияВУчете.ПериодРегистрации

    И ВТ_Начисления.ВидРасчета = ВТ_ОтраженияВУчете.ВидРасчета

    И ВТ_Начисления.Сотрудник = ВТ_ОтраженияВУчете.Сотрудник

    И ВТ_Начисления.Регистратор = ВТ_ОтраженияВУчете.Регистратор

    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ПособияПоУходуЗаРебенкомДоПолутораЛет.Обороты КАК ПособияПоУходуЗаРебенкомДоПолутораЛетОбороты

    ПО ВТ_Начисления.Организация = ПособияПоУходуЗаРебенкомДоПолутораЛетОбороты.Организация

    И ВТ_Начисления.ФизЛицо = ПособияПоУходуЗаРебенкомДоПолутораЛетОбороты.ФизЛицо

    СГРУППИРОВАТЬ ПО

    ВТ_Начисления.Организация,

    ВТ_Начисления.ФизЛицо,

    ВТ_Начисления.ВидРасчета,

    ВТ_ОтраженияВУчете.ЗаСчетРаботодателя,

    ВТ_Начисления.Регистратор,

    ВТ_Начисления.ПериодРегистрации,

    ВТ_ОтраженияВУчете.Регистратор,

    ВТ_Начисления.ПодразделениеОрганизации

    Reply
  26. director04

    (25) Сенькс, посмотрю, поправлю

    Reply
  27. director04

    (25) Обороты регистра «ПособияПоУходуЗаРебенкомДоПолутораЛетОбороты» нужно брать в отдельном запросе, сохранять во временной таблице, а затем уже соединять с таблицей «ВТ_Начисления». Ну и соответственно, следовало бы оптимизировать запрос по виртуальной таблице (методом ограничения основной выборки, результатами таблицы «ВТ_Начисления»)

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

    В остальном можно оставить так.

    Reply
  28. director04

    (25) Спасибо, выложил версию с учетом ваших замечаний.

    Reply
  29. Alex Y

    Столкнулся с интересной особенностью:

    Запускаю запрос под консолью — всё замечательно.

    Запускаю его из под Запроса в обработке :

    Второй Левый как будто соединяется не с ВТ_Начисления, а с ВТ_ОтраженияВУчете, и ВТ_УходЗаРебенком.СуммаВсегоОборот умножается на соответствующее количество строк.

    Беру текст запроса. Явно копирую его в консоль, запускаю — все работает нормально.

    Не смог побороть ситуацию, пока не избавился от всех полей группировки, кроме Организация и ФизЛицо и после этого сделал соединение с ВТ_УходЗаРебенком.

    Т.е. пришлось вначале соединять ВТ_Начисления и ВТ_ОтраженияВУчете, группировать их по Организации и ФизЛицу и лишь потом соединять с Пособиями.

    Платформа 8.2.11.236

    Reply
  30. director04

    (29) Видимо это проявление того самого «Декартового соединения» то есть многого ко многим. Когда убираете всю иную аналитику, позиции по обеим выборкам соединяются однозначно. Более конкретно смотреть надо по базе

    Reply
  31. stel1985@mail.ru

    Спасибо за обработку

    Reply

Leave a Comment

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