Сверка НДФЛ для ЗУП




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

16 Comments

  1. petrov_al

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

    Reply
  2. Sergey1CSpb

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

    А что значит не делать одинаковыми? В данном случае, как раз из-за неодинаковости все и происходит.

    Например, начислили компенсацию сотруднику 5-го числа — начислился НДФЛ. Далее рассчитали з/п 31-го числа и еще раз начислился этот же НДФЛ. Ввиду того, что ошибку проглядели — удвоенный НДФЛ успешно перечислился в бюджет. И ряд сотрудников недополучили деньги. Допускаю, что ошибку давно исправили. Но для исключения таких «сюрпризов» в будущем я своим настоятельно рекомендую раз в месяц ее запускать! И самому спокойнее.

    По видимому, petrov_al, мы говорим о разных ошибках.

    Reply
  3. Amras
    Reply
  4. Amras

    И еще… дату начала лучше ставить на начало года (т.к. в некоторых месяцах могут идти корректировки доходов и перерасчет НДФЛ. Тем самым запрос соберет полный доход, включая текущий период и произведет более корректный расчет).

    Проблема данного запроса в нерезидентах и прочих отчислений по ставке 35% (мат.выгода). Но при желании все можно допилить 🙂

    Reply
  5. Sergey1CSpb

    (4) Amras,

    Да, насчет начала года — мысль действительно хорошая.

    35% и нерезидентов у нас, тьфу-тьфу, нет — поэтому и не писал.

    Можно Вас попросить прокомментировать «более детальный запрос». Он дополнительно учитывает скидки и вычеты, или что-то еще?

    Reply
  6. Amras

    (5)

    Добавляет:

    1. Вычеты стандартные

    2. Вычеты имущественные

    3. Скидка (код 503), например с материальной помощи (4000 рублей не облагаемая сумма)

    — Данные поля в компоновке необходимо прописать в выражении (если придерживаться данного отчета):

    (Доход-БезНДФЛ-Скидка-СтандартныйВычет-ИмущественныйВычет)*0.13

    (Доход-БезНДФЛ-Скидка-СтандартныйВычет-ИмущественныйВычет)*0.13-НДФЛ

    Но можно было бы и в самом запросе это учесть (ну да не будем отходить от того, что уже написано).

    — Закинем в ресурсы данные поля (для итогов)

    — Немного бы подправить период в параметрах (Имя: Период / Заголовок: Период / Тип: СтандартныйПериод) — Ограничение Ложь

    — Даты в поле выражение: &Период.ДатаНачала и КонецПериода(&Период.ДатаОкончания,»День») — Ограничение Истина

    Немного подправить условное оформление для «Цвет текста». Необязательно создавать множество полей, можно пойти через группу ИЛИ и в нее добавить «Дельту» для 1 и «Дельту» для -1. Хотя это уже марафет 🙂

    Reply
  7. Amras

    И есть одна ошибка при сборке начислений (из-за чего я группировку поставил) — на запрос с основными начислениями стоит без дублей. А в документе может возникнуть такая картина:

    — Оплата больничных листов = 3 228,56

    — Оплата больничных листов = 3 228,56

    — Оплата больничных листов за счет работодателя = 3 228,56

    Тем самым отсечение дублей, нам удалит одну из строк «Оплата больничных листов = 3 228,56» — и мы получим искажение в расчете.

    Либо группируем расчеты, либо убираем флажок в объединение на второй запрос (Основные начисления).

    Reply
  8. gucci76

    Я использую отчет «Анализ налогов и взносов» — в нем написал свой вариант отчета, используя Пользовательское поле.

    Reply
  9. makas

    (8) gucci76,

    Я использую отчет «Анализ налогов и взносов» — в нем написал свой вариант отчета, используя Пользовательское поле.

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

    Reply
  10. gucci76

    Какой код?

    Я же не дописывал отчет. Через «ключик» свой вариант отчета сделал

    PS Только не для коммерческого использования )))

    Reply
  11. gucci76

    Хотя если использовать типовые возможности надо сравнивать Начислено в учете НДФЛ и начислено в своде по зарплате

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

    Reply
  12. tvg258

    Работает неверно. Не берет стандартные вычеты.

    Reply
  13. Sergey1CSpb

    (12) tvg258, Совершенно верно. В описании указано «Конечно, в отчете не рассмотрено множество нюансов, когда «формула * 0,13» не работает, например не учтены некоторые вычеты.»

    Рекомендую использовать «Детальную сверку» http://infostart.ru/public/196144/

    Там вычеты учтены.

    Reply
  14. tvg258

    Стандартные вычеты на детей, почему бы их не включить?

    Reply
  15. tvg258

    Спасибо. Попробую отчет по сслыке

    Reply
  16. Sergey1CSpb

    (15) tvg258, Да, взгляните тот отчет. Если там проблема не исчезнет, готов обсудить. Но, насколько я помню, с «детскими» вычетами там проблем не было.

    Reply

Leave a Comment

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