Внешний отчет Форма П-4 (НЗ) — Приказ Росстата от 29.08.2013 № 349




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2026-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='\

75 Comments

  1. chmv

    А выгрузка есть? Если есть — как ее подсоединить?

    Reply ↓
  2. kaufman

    (1) chmv, выгрузки пока нет

    Reply ↓
  3. b-dm

    А почему он за квартал или за месяц ? Когда будет за год ?

    Reply ↓
  4. kaufman

    (3) b-dm, с 2013 года данная форма сдается поквартально

    Reply ↓
  5. b-dm

    А почему ф макетах только форма за 1 кв.2013 года ? В том смысле что с этого времени форма не менялась ?)

    Reply ↓
  6. b-dm

    После регистрации в ЗУП он у меня почему то перечеркнутый в Регл.отчетах. Его оттуда вообще надо вызывать ?:

    Reply ↓
  7. b-dm

    И еще вопросец — пожелание: можно сделать разделение по подразделениям ?:

    Reply ↓
  8. kaufman

    (5) b-dm,

    1) А почему ф макетах только форма за 1 кв.2013 года ? В том смысле что с этого времени форма не менялась ?) — с 1 января 2013 года форма отчета не менялась (одинаковая для всех кварталов)

    2) После регистрации в ЗУП он у меня почему то перечеркнутый в Регл.отчетах. Его оттуда вообще надо вызывать ?:

    Для того, чтобы подключить НОВЫЙ внешний отчет необходимо:

    1) открыть форму списка справочника «Регламентированные отчеты»

    (меню «Операции — Справочник — Регламентированые отчеты»);

    2) в папке «Отчетность прочая» добавить новый элемент.

    3) в форме элемента необходимо установить переключатель

    «Использовать:» в положение «Файл», в качестве файла выбрать

    соответствующий внешний отчет;

    4) нажать кнопку «ОК».

    3) Вы имеете ввиду обособленные подразделения, стоящие на отдельном балансе?

    Reply ↓
  9. KotorVB

    Никак не пойму, есть выгрузка или её нет?

    Reply ↓
  10. kaufman

    (9) KotorVB, выгрузки нет

    Reply ↓
  11. b-dm

    (8) да , именно по обособленным подразделениям ? Если сделаете, будет прекрасный и удобный отчет на все случаи жизни, очень выручите)

    Reply ↓
  12. b-dm

    А так в принцип отчет неплохой, но ОП сдают его каждый своё.

    Reply ↓
  13. mikhailovaew

    (8)

    с 1 января 2013 года форма отчета не менялась

    Форма N П-4 (НЗ) утрачивает силу с отчета за I квартал 2014 года в связи с изданием Приказа Росстата от 29.08.2013 N 349, которым с этого же срока вводится новая форма N П-4 (НЗ).

    http://www.consultant.ru/document/cons_doc_LAW_157157/

    © КонсультантПлюс, 1992-2014

    Вы планируете вносить изменения в отчет в связи с вводом новой формы?

    Reply ↓
  14. mikhailovaew

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

    Reply ↓
  15. chmv

    Да хотелось бы новый макет получить. Заранее спасибо

    Reply ↓
  16. chmv

    Заранее спасибо

    Reply ↓
  17. kaufman

    (13) mikhailovaew, спасибо за оперативное отслеживание законодательства. Постараюсь в ближайшее время подготовить новый отчет

    Reply ↓
  18. kaufman

    (16) chmv, подготавливаю новый отчет

    Reply ↓
  19. kaufman

    (14) mikhailovaew, не только косметические. В строках 16 и 17 теперь указываются соответственно «Численность женщин, находящихся в отпуске по уходу за ребенком до достижения им возраста 1,5 лет» и «Численность женщин, находящихся в отпуске по уходу за ребенком в возрасте от 1,5 до 3 лет».

    А «Численность работников, выполнявших временные и сезонные работы, работы временного характера и общественные работы 1» (в предыдущей редакции строка 16) убрали совсем

    Reply ↓
  20. kaufman

    Отчет обновлен:

    1. Изменен номер приказа

    2. Строках 16 — «Численность женщин, находящихся в отпуске по уходу за ребенком до достижения им возраста 1,5 лет» — заполняется количеством женщин, находящимся в отпуске по уходу за ребенком (возраст ребенка не учитывается — в ЗУПе пока нет разделения состояний сотрудников в зависимости от возраста ребенка)

    3. Строках 17 — «Численность женщин, находящихся в отпуске по уходу за ребенком в возрасте от 1,5 до 3 лет» — автоматическое заполнение не предусмотрено

    Готовлю редакцию отчета с выделением обособленных подразделений

    Reply ↓
  21. chmv

    А выгрузка поменялась?

    Reply ↓
  22. kaufman

    (21) chmv, да, выгрузка тоже стала нового формата. Надо будет поработать над ее созданием в ЗУПе.

    Reply ↓
  23. kaufman

    (21) chmv, добавлена выгрузка отчета. Чтобы отчет выгрузился, не забывайте указывать ФИО и должность ответственного лица

    Reply ↓
  24. b-dm

    (23) а по обособленным подразделениям теперь можно заполнять/выгружать ?)

    Reply ↓
  25. kaufman

    (24) b-dm, пока нет. Напишу, когда будет готово.

    Reply ↓
  26. b-dm

    (25) ок, буду признателен 🙂 ориентировочные сроки есть ?)

    и еще вопрос не по теме: не собираетесь, не писали форму П-; ?) Они обычно парой ходят, как раз ищу подобный рабочий вариант, был бы признателен за наводку. Т.к. те что есть на ИС либо устарели, либо не работает заполнение 🙂

    Reply ↓
  27. kaufman

    (26) b-dm, П-; — это П-4?

    Reply ↓
  28. b-dm

    (27) да,именно она. П-4 🙂

    Reply ↓
  29. kaufman

    (28) b-dm, понятно. Надо будет посмотреть эту форму. 🙂 По поводу П4-НЗ постараюсь сделать сегодня

    Reply ↓
  30. b-dm

    (29) — ок, с нетерпением жду 🙂 вечером посмотрю, может быть уже выложите 🙂

    Reply ↓
  31. b-dm

    Скачал. пробую запустить, пишет ошибку :){ВнешнийОтчет.РегламентированныйОтчетСтатистикаФормаП4НЗ.МодульОбъекта(417)}: Ошибка при вызове метода контекста (Область)

    мФормаОтчета.Область(КлючЗначение.Ключ).Значение = КлючЗначение.Значение;

    по причине:

    Область не найдена: П0001000101

    Reply ↓
  32. b-dm

    понял, эта ошибка возникает если выбрать 2013 год

    Reply ↓
  33. b-dm

    я так понял по подразделениям пока что не пашет 🙂

    Reply ↓
  34. kaufman

    (32) b-dm, ошибка исправлена для формирования отчета за 2014.

    Также в отчет добавлена возможность выбора обособленного подразделения

    Reply ↓
  35. b-dm

    (34) — спасибо огромное 🙂

    Reply ↓
  36. chmv

    Выгрузка есть?

    Reply ↓
  37. kaufman

    (36) chmv, посмотрите ответ 23, выгрузка есть за 2014 год нового формата

    Reply ↓
  38. kaufman

    Добавлено автоматическое заполнение строк 16 и 17 — «Численность женщин, находящихся в отпуске по уходу за ребенком до достижения им возраста 1,5 лет» и «Численность женщин, находящихся в отпуске по уходу за ребенком в возрасте от 1,5 до 3 лет».

    Reply ↓
  39. b-dm

    (38) -не знаю как вы этого добились по отпускам по уходу но спасибо большое 🙂

    Reply ↓
  40. Старый

    Спасибо. Отчет полезный

    Reply ↓
  41. mikhailovaew

    Прежде всего хочу поблагодарить автора за полезный отчет и за его сопровождение.

    Есть замечания по расчету строки 15:

    во-первых, в запросе нужно вынести проверку соответствия подразделению из условий виртуальной таблицы в секцию ГДЕ, иначе завышает численность (приплюсовывает всех сотрудников, когда-либо работавших в подразделении)

    во-вторых, отбор по виду занятости должен включать внутренних совместителей (у Вас вместо них — внешние).

    Эти замечания справедливы и для расчета всех прочих «численностей» (строки 01-12): условие на подразделение должно быть в секции ГДЕ, а в саму численность включаются сотрудники по основному месту работы и внутренние совместители.

    Reply ↓
  42. mikhailovaew

    Вообще отбор по подразделению следует серьезно переработать.

    Например, в функции ПолучитьКоличествоСотрудниковИмевшихОтпускаБезСохраненияЗП условие вида «Сотрудник.ПодразделениеОрганизации В ИЕРАРХИИ (&ОбособленноеПодразделение)» некорректно, поскольку здесь проверяется соответствие отбору подразделения из трудового договора вместо актуального подразделения сотрудника.

    Reply ↓
  43. mikhailovaew

    Еще неправильно формируется численность в строке 05: неправомерно попадают сотрудники, у которых отпуск закончился датой, предшествующей отчетному периоду. Дело в том, что ПериодЗавершения в регистре СостояниеРаботников на день больше, чем «Дата по» в документе, это нужно учесть в запросе.

    Reply ↓
  44. b-dm

    (43) mikhailovaew, может сами и подправите? и выложите здесь ?)))

    Reply ↓
  45. mikhailovaew

    Не работает выгрузка (ЗУП 2.5.80.1), выдает ошибку:

    {Документ.ВыгрузкаРегламентированныхОтчетов.Форма.ФормаДокумента.Форма(3002)}: Значение не является значением объектного типа (КодИМНС)

    КодИМНС = ПервыйДок.КодИМНС;

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

    Reply ↓
  46. mikhailovaew

    (44) правлю много, плюс собираюсь добавить отбор по КПП. Насчет выкладывать — подумаю. Если руки дойдут, оформлю как отдельную публикацию. У меня еще П-4 есть доработанная (тоже с отбором по КПП, плюс среднесписочная берется из встроенного отчета).

    Reply ↓
  47. kaufman

    (46) mikhailovaew, спасибо большое за такой тест отчета. В нашей организации нет обособленных подразделений, поэтому очень важно знать как отчет отрабатывается у других. Сегодня постараюсь исправить все недоработки

    Reply ↓
  48. kaufman

    (45) mikhailovaew, у меня выгружается отчет без ошибок: Для организации «ООО» сохранены настройки выгрузки стат. отчетности в формате ПО «Заполнение форм статистической отчетности», версии 2.4.4!Для изменения формата выгрузки перейдите в форму настроек журнала «Регламентированная и финансовая отчетность».

    Какая у Вас стоит версия выгрузки?

    Reply ↓
  49. mikhailovaew

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

    Reply ↓
  50. mikhailovaew

    Еще подвал не соответствует новой форме (нет e-mail), соответственно, выгрузка тоже.

    В выгрузку не попадает строка 17 (потому что формат выгрузки устаревший).

    Reply ↓
  51. kaufman

    (50) mikhailovaew, выгрузка формата 1.3, но почему то использовалась схема 2013, а не 2014 года. Исправлено. Строка 17 теперь попадает.

    Reply ↓
  52. mikhailovaew

    (51) Спасибо за оперативность! Вижу, и по обособленным подразделениям есть изменения)

    А e-mail должен попадать в выгрузку? а то он на форме есть, в выгрузке нет…

    Reply ↓
  53. kaufman

    (52) mikhailovaew, по схеме 2014 года нет электронной почты. Есть только

    Руководитель организации (ФИО) — &ОргДиректор

    Должностное лицо, ответственное за составление формы (должность) — &ОргДолжностьИсп

    Должностное лицо, ответственное за составление формы (ФИО)- &ОргИсполнитель

    Контактный телефон — &ОргТелефонИсп

    Reply ↓
  54. mikhailovaew

    Кстати, по обособленным… Все-таки не идеально считает.

    У Вас для определения численности в строках 05 и 16-17 подразделение сотрудника определяется по реквизиту ТекущееПодразделениеОрганизации. Это не совсем корректно: нужно делать соединение с регистром РаботникиОрганизаций (при расчете отпусков за свой счет — на дату каждого отпуска) и брать актуальное подразделение, т.к. в противном случае не учитываются перемещения.

    Reply ↓
  55. kaufman

    (56) mikhailovaew, ТекущееПодразделениеОрганизации — это и есть актуальное подразделение. Распишите подробный пример для теста

    Reply ↓
  56. mikhailovaew

    Еще результаты тестов:

    1. В принятые не попадают внутренние совместители.

    2. В уволенные попадают те, кто был когда-то принят в указанное подразделение, а уволен уже из другого (используется Сотрудник.ПодразделениеОрганизации).

    3. В расшифровке не совпадает количество по неполному времени строка 02 (меньше, чем в отчете) и по женщинам строки 16-17 (больше, чем в отчете).

    Reply ↓
  57. mikhailovaew

    (57)

    ТекущееПодразделениеОрганизации — это и есть актуальное подразделение

    Не совсем так.

    Допустим, сотрудник в первом квартале работал в подразделении Основное, а в апреле был переведен во Вспомогательное (и ТекущееПодразделениеОрганизации приняло значение Вспомогательное). Но в отчет за первый квартал его отпуска за свой счет должны попадать по подразделению Основное, то есть «актуальность» подразделения должна определяться не на дату самого последнего перемещения, а на дату отпуска. Это не совсем элементарная задача, тут требуется запрос с определением состояния на каждую дату события (яркий пример подобных запросов — определения актуальной цены на дату продажи).

    Reply ↓
  58. kaufman

    (58) mikhailovaew,

    1. Согласно указаниям в строке 06 указывается численность принятых работников СПИСОЧНОГО состава. Согласно чему туда должны попадать внешние?

    Reply ↓
  59. kaufman

    2. Согласна

    Reply ↓
  60. mikhailovaew

    (60) комментарий уже исправлен: ну конечно же, ВНУТРЕННИЕ ) а у Вас только основное место работы, внутренних не включили )

    Reply ↓
  61. mikhailovaew

    еще раз спасибо за поддержку отчета и за оперативность изменений.

    Пойду домой, пока солнышко светит )

    Reply ↓
  62. kaufman

    (63) mikhailovaew, тестируйте пока без проверки актуальности подразделений (если отчет формируется за 1 квартал, а во 2 квартале подразделение изменилось, то берется пока новое)

    Reply ↓
  63. Nata

    Спасибо за отчет. Очень нужен

    Reply ↓
  64. otrazhenie

    а когда можно ожидать новую версию?

    Reply ↓
  65. kaufman

    (66) otrazhenie, после моего отпуска! Всем хороших солнечных дней! 🙂

    Reply ↓
  66. otrazhenie

    Хорошо Вам отдохнуть!

    а после отпуска можно будет увидеть форму 407?

    Reply ↓
  67. Диадох

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

    Берется реквизит ПодразделениеОрганизации из среза регистра. Но в регистре есть ещё реквизит ПодразделениеОрганизацииЗавершения, и если заполнен реквизит ПериодЗавершения, и он меньше, чем дата среза регистра, то брать нужно именно ПодразделениеОрганизацииЗавершения, а не ПодразделениеОрганизации.

    Кроме этого, в инструкции по заполнению написано:

    При заполнении строк 01 — 05 следует учитывать следующее. Если работник в течение отчетного квартала работал, например, неполное рабочее время сначала по инициативе работодателя, затем по соглашению между работником и работодателем, а в конце квартала находился в отпуске без сохранения заработной платы, то он показывается один раз по строке 01 или 02 или 05, исходя из причины его работы неполное рабочее время или нахождения в отпуске без сохранения заработной платы большую часть времени в квартале.

    В 1С конечно нет всех этих данных, можно получить только строки 02 и 05, но даже при этом нужно сделать хотя бы так, чтобы один и тот же человек не попал в обе строки отчета. Например сделать выборку для строки 02 по людям, а по строке 05 уже проверять, не входит ли сотрудник в строку 02. Если входит, то не включать в строку отпусков.

    Reply ↓
  68. Диадох

    Ещё один момент:

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

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

    Reply ↓
  69. Диадох

    При подсчете женщин, находящихся в отпуске по уходу, есть ошибка:

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

    Reply ↓
  70. Диадох

    Строка 13 — численность на конец квартала. В инструкции к заполнению формы написано:

    «В строку 13 не включаются работники, для которых последним днем работы в организации являлось последнее число отчетного квартала. Эти работники учитываются в строке 08.»

    У Вас в обработке такие попадают в строку 13, т.к. на последний день месяца они в регистре ещё работающие. Тут нужно проверить, нет ли врегистре записи от 1-го числа с признаком «увольнение». Если есть, то таких не включать

    Reply ↓
  71. chmv

    Кстати отбор по КПП не очень интересен, интереснее по ОКМТО

    Reply ↓
  72. chmv

    Если можно пришлите пожалуйста на chmv20005@mail.ru Еще раз.

    Последнюю версию

    Reply ↓
  73. mzelensky

    Отлично, то что надо…а то сток левака перебрали уже

    Reply ↓
  74. 3762515

    А на УПП 1.3 взлетит?

    Reply ↓
  75. spkbazi

    Ошибка инициализации модуля: ВнешнийОтчет.РегламентированныйОтчетСтатистикаФормаП4.МодульОбъекта

    по причине:

    {ВнешнийОтчет.РегламентированныйОтчетСтатистикаФормаП4.МодульОбъекта(948)}: Метод объекта не обнаружен (ПолучитьОписаниеТиповСтроки)

    Reply ↓

Leave a Comment

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