Каталог решений - Практическое применение менеджера расчета для расчета зарплаты «на лету» через отчет за произвольное количество месяцев в конфигурации ЗУП 3.1 и ERP

Практическое применение менеджера расчета для расчета зарплаты «на лету» через отчет за произвольное количество месяцев в конфигурации ЗУП 3.1 и ERP

Практическое применение менеджера расчета для расчета зарплаты «на лету» через отчет за произвольное количество месяцев в конфигурации ЗУП 3.1 и ERP

В наличии

Практическое применение менеджера расчета для расчета зарплаты «на лету» через отчет за произвольное количество месяцев в конфигурации ЗУП 3.1 и ERP. Реализовано внешним отчетом, не использует документов. Расчет происходит по организации за выбранный период.

Категория:

Описание

Еще одна статья и пример практического применения менеджера расчета в подсистеме расчета зарплаты конфигураций ЗУП 3.1 и ERP. Ранее уже писал про менеджер расчета в статье Использование менеджера расчета для расчета зарплаты в ЗУП 3.1 и в Программное создание и расчет документов начисления зарплаты в конфигурации ЗУП 3.1 и ERP (по подразделениям). Но чтобы было понятнее, что же это такое, сделал еще один практический пример.

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

В итоге наш отчет выглядит примерно так:

 

 

"Период" — Произвольный период. При расчете дата начала и дата окончания приводятся к началу и окончанию месяца соответственно.

"Организация" и "подразделение" — ключевые параметры, по которым строим отчет.

"Использовать время за предыдущий период" — параметр отвечающий за время. Например в моей развернутой демобазе графики работы за 2022 год расчитаны и расчет зарплаты за этот период не вызывает проблем. А если сместить период на 2023 год, то графиков нет и в формулах расчета начислений НормаДней, НормаЧасов окажутся равными нулю, что вызовет ошибку расчета.

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

А теперь к реализации.

Реализовано через отчет с простой схемой компоновки данных, использующую внешний набор данных.

 

 

Структура вывода СКД — в таблицу, где в колонках у нас выводится месяц и сумма.

 

 

Программный вывод СКД в отчет, думаю, тоже у вас не должен вызывать проблем

  Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
  	
  	СтандартнаяОбработка = Ложь;
  	
  	НастройкиКД = КомпоновщикНастроек.ПолучитьНастройки();
  
  	ПараметрыРасчета = Новый Структура;
  	
  	Организация = ОтчетыКлиентСервер.НайтиПараметр(НастройкиКД,, "Организация").Значение;
  	Период = ОтчетыКлиентСервер.НайтиПараметр(НастройкиКД,, "Период").Значение;
  	ИспользоватьВремяЗаПредыдущийГод = ОтчетыКлиентСервер.НайтиПараметр(НастройкиКД,, "ИспользоватьВремяЗаПредыдущийГод").Значение;
  	
  	ПараметрПодразделение = ОтчетыКлиентСервер.НайтиПараметр(НастройкиКД,, "Подразделение");
  	Если ПараметрПодразделение.Использование Тогда
  		ПараметрыРасчета.Вставить("Подразделение", ПараметрПодразделение.Значение);
  	КонецЕсли;
  	
  	ПараметрыРасчета.Вставить("Организация", Организация);
  	ПараметрыРасчета.Вставить("Период", Период);
  	ПараметрыРасчета.Вставить("ИспользоватьВремяЗаПредыдущийГод", ИспользоватьВремяЗаПредыдущийГод);
  	ДанныеФОТ = ДанныеФОТ(ПараметрыРасчета);
  	
  	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
  	МакетКомпоновки   = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиКД, ДанныеРасшифровки);
  	
  	ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
  	ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, Новый Структура("НаборДанных", ДанныеФОТ), ДанныеРасшифровки, Истина);
  	
  	ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
  	ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
  	
  	ПроцессорВывода.Вывести(ПроцессорКомпоновки);
  	
  КонецПроцедуры
  

Создадим таблицу для СКД

  	ДанныеФОТ = Новый ТаблицаЗначений;
  	ДанныеФОТ.Колонки.Добавить("Сотрудник");	
  	ДанныеФОТ.Колонки.Добавить("ДолжностьПоШтатномуРасписанию");	
  	ДанныеФОТ.Колонки.Добавить("Подразделение");	
  	ДанныеФОТ.Колонки.Добавить("Организация");	
  	ДанныеФОТ.Колонки.Добавить("Начисление");	
  	ДанныеФОТ.Колонки.Добавить("Период");	
  	ДанныеФОТ.Колонки.Добавить("Результат");	
  

Получим сотрудников организации для расчета

  	ПараметрыПолученияСотрудников = КадровыйУчет.ПараметрыПолученияСотрудниковОрганизацийПоСпискуФизическихЛиц();
  	ПараметрыПолученияСотрудников.Организация	= ПараметрыРасчета.Организация;
  	Если ПараметрыРасчета.Свойство("Подразделение") Тогда
  		ПараметрыПолученияСотрудников.Подразделение = ПараметрыРасчета.Подразделение;
  	КонецЕсли;
  	ПараметрыПолученияСотрудников.НачалоПериода		= ПараметрыРасчета.Период.ДатаНачала;
  	ПараметрыПолученияСотрудников.ОкончаниеПериода  = КонецМесяца(ПараметрыРасчета.Период.ДатаОкончания);
  	КадровыйУчетРасширенный.ПрименитьОтборПоФункциональнойОпцииВыполнятьРасчетЗарплатыПоПодразделениям(ПараметрыПолученияСотрудников);
  
  	КадровыйУчет.СоздатьВТСотрудникиОрганизации(Запрос.МенеджерВременныхТаблиц, Истина, ПараметрыПолученияСотрудников);
  
  	Запрос.Текст = 
  		"ВЫБРАТЬ
  		|	Сотрудники.Сотрудник КАК Сотрудник,
  		|	Сотрудники.ФизическоеЛицо КАК ФизическоеЛицо
  		|ИЗ
  		|	ВТСотрудникиОрганизации КАК Сотрудники";
  	
  	Сотрудники = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Сотрудник");
  

 

Теперь инициализируем менеджер расчета

  МенеджерРасчета = СоздатьМенеджерРасчета(ПараметрыРасчета.Период, ПараметрыРасчета.Организация);
  

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

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

  Функция СоздатьМенеджерРасчета(ПериодРасчета, Организация) Экспорт
  	
  	УстановитьПривилегированныйРежим(Истина);
  	Если ЗарплатаКадры.ВыполнятьРасчетЗарплатыБезОптимизации() Тогда
  		МенеджерРасчета = Обработки.МенеджерРасчетаЗарплатыАрхивный.Создать();
  	Иначе
  		МенеджерРасчета = Обработки.МенеджерРасчетаЗарплаты.Создать();
  	КонецЕсли;	
  		
  	УстановитьПривилегированныйРежим(Ложь);
  	
  	МенеджерРасчета.Инициализировать(ПериодРасчета, Организация);
  	
  	Возврат МенеджерРасчета;
  	
  КонецФункции
  

 

Далее все просто. Заполняем настройки менеджера расчета по ранее полученным сотрудникам. С помощью вызова МенеджерРасчета.ЗаполнитьНачислениеЗарплаты заполняем все плановые начисления этих сотрудников

  	МенеджерРасчета.НастройкиРасчета.Сотрудники = Сотрудники;
  	МенеджерРасчета.НастройкиРасчета.РассчитыватьНачисления = Истина;
  	МенеджерРасчета.НастройкиРасчета.ОкончательныйРасчет = Истина;
  	МенеджерРасчета.НастройкиРасчета.РассчитыватьНДФЛ = Ложь;
  
  	МенеджерРасчета.НастройкиНДФЛ.Сотрудники = Сотрудники;
  	МенеджерРасчета.НастройкиНДФЛ.ОкончательныйРасчет = Истина;
  	
  	СотрудникиДляНачислений = МенеджерРасчета.ТаблицаСотрудников();
  	
  	МесяцНачисления = НачалоМесяца(ПараметрыРасчета.Период.ДатаНачала);
  	Пока МесяцНачисления < ПараметрыРасчета.Период.ДатаОкончания Цикл
  		Для Каждого Сотрудник Из Сотрудники Цикл
  			НоваяСтрока = СотрудникиДляНачислений.Добавить();
  			НоваяСтрока.Сотрудник = Сотрудник;
  			НоваяСтрока.ДатаНачала = МесяцНачисления;
  			НоваяСтрока.ДатаОкончания = КонецМесяца(МесяцНачисления);
  		КонецЦикла;
  		МесяцНачисления = ДобавитьМесяц(МесяцНачисления, 1);
  	КонецЦикла;
  		
  	ОтборМенеджераРасчета = МенеджерРасчета.СоздатьОтборы();
  	Если ПараметрыРасчета.Свойство("Подразделение") Тогда
  		ОтборМенеджераРасчета.Подразделение = ПараметрыРасчета.Подразделение;
  	КонецЕсли;
  	
  	МенеджерРасчета.ЗаполнитьНачислениеЗарплаты(СотрудникиДляНачислений, ОтборМенеджераРасчета);
  

И вызываем метод расчета зарплаты

  МенеджерРасчета.РассчитатьЗарплату();

Итоговый результат перекладываем в ранее созданную таблицу для СКД

  	Для Каждого СтрокаНачисления Из МенеджерРасчета.Зарплата.Начисления Цикл
  		НоваяСтрока = ДанныеФОТ.Добавить();
  		ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаНачисления);
  		НоваяСтрока.Период = СтрокаНачисления.ПериодРегистрации;
  	КонецЦикла;	
  

В данном случае в таблице МенеджерРасчета.Зарплата.Начисления у нас все результаты расчета, а так же вспомогательные данные. Т.к. в отчете не использую расшифровок, то показатели у строк начисления нет необходимости сохранять.

 

Как я получаю время за предыдущий период в процедуре ЗаполнитьВремяПоПрошломуПериоду().

Создадим таблицу периодов

  	ЗарплатаКадрыОбщиеНаборыДанных.СоздатьВТПериоды(
  	    Запрос.МенеджерВременныхТаблиц,
  	    НачалоМесяца(ПараметрыРасчета.Период.ДатаНачала),
  	    КонецМесяца(ПараметрыРасчета.Период.ДатаОкончания),
  	    "МЕСЯЦ",
  	    "КонецМесяца",
  	    "ВТМесяцы",
  	    Истина);          
  

Получим промежуточную временную таблицу с сотрудниками и периодами за текущий и прошлый период для анализа

  |ПОМЕСТИТЬ ВТСотрудники
  |ИЗ
  |	ВТСотрудникиОрганизации КАК ВТСотрудникиОрганизации
  |       ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТМесяцы КАК ВТМесяцы
  |       ПО (ИСТИНА)		
  

Время получаем с помощью типового метода

  ПараметрыПолученияДанныхОВремени = УчетРабочегоВремениРасширенный.ПараметрыДляСоздатьВТДанныеУчетаРабочегоВремениСотрудников();
  УчетРабочегоВремениРасширенный.СоздатьВТДанныеУчетаРабочегоВремениСотрудников(Запрос.МенеджерВременныхТаблиц, Истина, ПараметрыПолученияДанныхОВремени);
  

А далее просто проверяем, что если для выбранного сотрудника и периода отсутствует время, то вручную устанавливаем показатели времени за предыдущий период с помощью метода МенеджерРасчета.ДобавитьИзвестноеЗначениеПоказателя()

  ДанныеУчетаРабочегоВремени = Запрос.Выполнить().Выгрузить();
  
  ДанныеУчетаРабочегоВремени.Индексы.Добавить("Сотрудник, Месяц");
  
  Для Каждого СтрокаНачисления Из МенеджерРасчета.Зарплата.Начисления Цикл
  	
  	НайденныеСтроки = ДанныеУчетаРабочегоВремени.НайтиСтроки(Новый Структура("Сотрудник, Месяц", СтрокаНачисления.Сотрудник, СтрокаНачисления.ПериодРегистрации));
  	Если НайденныеСтроки.Количество() = 0 Тогда
  		НайденныеСтроки = ДанныеУчетаРабочегоВремени.НайтиСтроки(
  			Новый Структура("Сотрудник, Месяц", СтрокаНачисления.Сотрудник, ДобавитьМесяц(СтрокаНачисления.ПериодРегистрации, -12)));
  		Если НайденныеСтроки.Количество() Тогда
  			МенеджерРасчета.ДобавитьИзвестноеЗначениеПоказателя(СтрокаНачисления, ПоказательВремяВДнях, НайденныеСтроки[0].Дней);
  			МенеджерРасчета.ДобавитьИзвестноеЗначениеПоказателя(СтрокаНачисления, ПоказательНормаДнейПоГрафикуПолногоРабочегоВремени, НайденныеСтроки[0].НормаДней);
  		КонецЕсли;
  	КонецЕсли;
  	
  КонецЦикла;
  

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

Как всегда уточняю, что все тестировалось в конфигурации Зарплата и управление персоналом КОРП, редакция 3.1 (3.1.20.71) на платформе 1С:Предприятие 8.3 (8.3.20.1613).

 

PS: И наверное просто уже добавлю вне статьи. Коллеги разработчики. Используйте в своих обработках типовые методы подключения внешних обработок. Не нужно изобретать методы как самим инициализировать возвращаемые параметры регистрации обработки. Есть прекрасный метод БСП ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке.

Тут даже документация не нужна, все описание есть в вызываемых методах функций и процедур. Ну и вообще, есть прекрасный документ Система стандартов и методик разработки конфигураций для платформы 1С:Предприятие 8

has been added to your cart:
Оформление заказа