Введение
Уже достаточно много появилось статей, посвященным механизмам конфигурации ЗУП 3.1, но при этом менеджер расчета обделен вниманием. В этой статье я приведу примеры работы с менеджером расчета и некоторым механизмам, связанным с ним.
По сути в конфигурации у нас три расчетных обработки
- РасчетБазыНачисленийУдержаний - формирует базы начислений и удержаний, используемых для расчета
- МенеджерДанныхУчетаВремениСотрудников - формирует данные по времени сотрудников
- МенеджерРасчетаЗарплаты - основной менеджер расчета, который рассчитывает начисления, взносы, ндфл и прочее. Фактически при расчете зарплаты мы видим результат работы этого менеджера.
Инициализировать менеджер можно двумя способами:
При расчете зарплаты за месяц можно использовать типовой метод инициализации
МенеджерРасчета = РасчетЗарплатыРасширенный.СоздатьМенеджерРасчета(МесяцНачисления, Организация);
При нестандартных расчетах нам может понадобится инициализировать его по-своему, вызвав конструктор
МенеджерРасчета = Обработки.МенеджерРасчетаЗарплаты.Создать();
ПериодРасчета = Новый СтандартныйПериод;
ПериодРасчета.ДатаНачала = ДатаНачала ;
ПериодРасчета.ДатаОкончания = ДатаОкончания ;
МенеджерРасчета.Инициализировать(ПериодРасчета, Организация);
Разница в том, что во втором случае мы можем указать произвольный период, например год.
С релиза ЗУП 3.1.10 старый менеджер расчета был переименован в МенеджерРасчетаЗарплатыАрхивный и за его использование отвечает константа "Выполнять расчет зарплаты без оптимизации". Но на дворе 21 год, думаю в ближайших релизах от старых алгоритмов окончательно откажутся.
Основная логика работы с менеджером это
-
Заполнить коллекцию начислений
-
Рассчитать зарплату
-
Перенести результат в форму/документ.
Разберем несколько примеров работы с менеджером расчета. Уточню что для примера я буду рассчитывать только начисления и НДФЛ с вычетами.
Расчет начисления по сотруднику.
Например, у нас на входе для расчета есть сотрудник, начисление и период, за который мы хотим посчитать это начисление.
//Инициализация менеджера расчета
МенеджерРасчета = РасчетЗарплатыРасширенный.СоздатьМенеджерРасчета(МесяцНачисления, Организация);
МенеджерРасчета.НастройкиРасчета.Сотрудники = Сотрудник;
МенеджерРасчета.НастройкиРасчета.РассчитыватьНачисления = Истина;
МенеджерРасчета.НастройкиРасчета.ОкончательныйРасчет = Истина;
МенеджерРасчета.НастройкиРасчета.РассчитыватьНДФЛ = Истина;
МенеджерРасчета.НастройкиНДФЛ.Сотрудники = Сотрудник;
МенеджерРасчета.НастройкиНДФЛ.ОкончательныйРасчет = Истина;
//Инициализация пустой таблицы для начислений
ТаблицаНачислений = МенеджерРасчета.ТаблицаИсходныеДанныеНачисленияЗарплатыПоНачислениям();
//Добавляем в таблицу сотрудника, интервал начисления и период
НовыйИнтервал = ТаблицаНачислений.Добавить();
НовыйИнтервал.Сотрудник = Сотрудник;
НовыйИнтервал.Начисление = Начисление;
НовыйИнтервал.ДатаНачала = МесяцНачисления;
НовыйИнтервал.ДатаОкончания = КонецМесяца(МесяцНачисления);
//Заполняем коллекцию Зарплата.Начисления
МенеджерРасчета.ЗаполнитьНачисленияСотрудникаЗаПериод(Сотрудник, ТаблицаНачислений);
//Расчет
МенеджерРасчета.РассчитатьЗарплату();
//Перенос расчитанных данных в данные формы
ДанныеДляЗаполненияВДанныеФормы(МенеджерРасчета.Зарплата);
В результате в табличной части менеджера расчета Зарплата.Начисления у нас будут результаты расчета по сотруднику, а также все вспомогательные данные, которые использовались при расчете (показатели и их значения, нормы и фактическое время, график работы, подразделение).
В процедуре ДанныеДляЗаполненияВДанныеФормы у меня алгоритмы, для переноса данных менеджера расчета в данные формы. Т.к. этот алгоритм универсальный, я немного о нем расскажу после всех примеров по расчетам.
Расчет начисления по сотруднику, где один из показателей мы указываем самостоятельно.
Код для примера тот же, но для интервала мы указываем известное значение показателя, которое вы можете указать вручную с формы или рассчитать отдельно.
...
НовыйИнтервал.ДатаОкончания = КонецМесяца(МесяцНачисления);
МенеджерРасчета.ДобавитьИзвестноеЗначениеПоказателя(НовыйИнтервал, Показатель, ЗначениеПоказателя);
...
Если в первом примере все показатели рассчитывались в процессе, то в текущем мы заранее подставляем в расчет известное значение показателя.
Расчет всех начислений по сотруднику за месяц
МенеджерРасчета = РасчетЗарплатыРасширенный.СоздатьМенеджерРасчета(МесяцНачисления, Организация);
МенеджерРасчета.НастройкиРасчета.Сотрудники = Сотрудник;
МенеджерРасчета.НастройкиРасчета.РассчитыватьНачисления = Истина;
МенеджерРасчета.НастройкиРасчета.ОкончательныйРасчет = Истина;
МенеджерРасчета.НастройкиРасчета.РассчитыватьНДФЛ = Истина;
МенеджерРасчета.НастройкиНДФЛ.Сотрудники = Сотрудник;
МенеджерРасчета.НастройкиНДФЛ.ОкончательныйРасчет = Истина;
Сотрудники = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Сотрудник);
МенеджерРасчета.НачисленияЗарплатыЗаПериод(Сотрудники, МесяцНачисления, КонецМесяца(МесяцНачисления));
ПериодРасчетаЗарплаты = Новый СтандартныйПериод;
ПериодРасчетаЗарплаты.ДатаНачала = МесяцНачисления;
ПериодРасчетаЗарплаты.ДатаОкончания = КонецМесяца(МесяцНачисления);
СотрудникиДляНачислений = МенеджерРасчета.ТаблицаСотрудников();
МенеджерРасчета.ЗаполнитьНачисленияСотрудникаЗаПериод(Сотрудник, СотрудникиДляНачислений, ПериодРасчетаЗарплаты);
МенеджерРасчета.РассчитатьЗарплату();
ДанныеДляЗаполненияВДанныеФормы(МенеджерРасчета.Зарплата);
Тут мы видим разницу в вызове процедуры ЗаполнитьНачисленияСотрудникаЗаПериод.
Т.е. заранее мы не указываем какие начисления считать, а параметр ПериодРасчетаЗарплаты указывает процедуре, что необходимо выявить начисления сотрудника за месяц.
Расчет всех сотрудников по организации (подразделению)
ПараметрыПолученияСотрудников = КадровыйУчет.ПараметрыПолученияСотрудниковОрганизацийПоСпискуФизическихЛиц();
ПараметрыПолученияСотрудников.Организация = Организация;
ПараметрыПолученияСотрудников.Подразделение = Подразделение;
ПараметрыПолученияСотрудников.НачалоПериода = МесяцНачисления;
ПараметрыПолученияСотрудников.ОкончаниеПериода = КонецМесяца(МесяцНачисления);
КадровыйУчетРасширенный.ПрименитьОтборПоФункциональнойОпцииВыполнятьРасчетЗарплатыПоПодразделениям(ПараметрыПолученияСотрудников);
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
КадровыйУчет.СоздатьВТСотрудникиОрганизации(Запрос.МенеджерВременныхТаблиц, Истина, ПараметрыПолученияСотрудников);
Запрос.Текст =
"ВЫБРАТЬ
| Сотрудники.Сотрудник КАК Сотрудник,
| Сотрудники.ФизическоеЛицо КАК ФизическоеЛицо
|ИЗ
| ВТСотрудникиОрганизации КАК Сотрудники";
Сотрудники = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Сотрудник");
МенеджерРасчета = РасчетЗарплатыРасширенный.СоздатьМенеджерРасчета(МесяцНачисления, Организация);
МенеджерРасчета.НастройкиРасчета.Сотрудники = Сотрудники;
МенеджерРасчета.НастройкиРасчета.РассчитыватьНачисления = Истина;
МенеджерРасчета.НастройкиРасчета.ОкончательныйРасчет = Истина;
МенеджерРасчета.НастройкиРасчета.РассчитыватьНДФЛ = Истина;
МенеджерРасчета.НастройкиНДФЛ.Сотрудники = Сотрудники;
МенеджерРасчета.НастройкиНДФЛ.ОкончательныйРасчет = Истина;
СотрудникиДляНачислений = МенеджерРасчета.ТаблицаСотрудников();
Для Каждого Сотрудник Из Сотрудники Цикл
НоваяСтрока = СотрудникиДляНачислений.Добавить();
НоваяСтрока.Сотрудник = Сотрудник;
НоваяСтрока.ДатаНачала = МесяцНачисления;
НоваяСтрока.ДатаОкончания = КонецМесяца(МесяцНачисления);
КонецЦикла;
ОтборМенеджераРасчета = МенеджерРасчета.СоздатьОтборы();
ОтборМенеджераРасчета.Подразделение = Подразделение;
МенеджерРасчета.ЗаполнитьНачислениеЗарплаты(СотрудникиДляНачислений, ОтборМенеджераРасчета);
МенеджерРасчета.РассчитатьЗарплату();
ДанныеДляЗаполненияВДанныеФормы(МенеджерРасчета.Зарплата);
Если вы уже работали с ЗУП 3.1 или читали описание по программным методам ЗУП, то думаю приведенный пример не вызовет вопросов. Вначале мы получили всех текущих сотрудников организации (а если указали подразделение, то по подразделению), затем передали список менеджеру расчета и инициализировали расчет.
Это базовые примеры работы с менеджером расчета. В зависимости от реализуемых задач, можно задействовать разный функционал менеджера расчета. Рекомендую просто пройтись отладчиком по менеджеру расчета, от метода "РассчитатьЗарплату". Посмотреть по какому принципу разбиваются строки начислений, каким образом рассчитываются показатели, в т.ч. базы для расчета начислений и удержаний.
Перенос результата расчета данные формы
Тут немного стоит рассказать в каком виде хранятся данные в документах и формах.
В менеджере расчета и в табличных частях документов начисления с данными формы практически совпадают. Разница в хранении показателей. В менеджере расчета и в документах показатели хранятся в отдельной ТЧ "Показатели", связанной с начислениями по реквизиту "ИдентификаторСтроки". А вот в формах к таблице начислений программно или вручную добавляются колонки "Показатель1", "Показатель2”… и "ЗначениеПоказателя1", "ЗначениеПоказателя2"…
Соответственно при чтении/открытии документа, а также после расчета данные показателей переносятся в созданные новые колонки. А при записи документа происходит обратный процесс переноса в ТЧ "Показатели".
Исходные требования для реализации примера:
В форме мы хотим видеть результаты начислений с расшифровкой по показателям, указанием отработанного времени. Т.е. все то, что мы привыкли видеть в любом типовом расчетом документе.
Приведу пример кода процедуры ДанныеДляЗаполненияВДанныеФормы, параметром в которую мы передаем результаты расчета для дальнейшего вывода в форму документа/обработки.
ТаблицыНачислений = РасчетЗарплатыРасширенныйФормы.ТаблицыНачисленийФормы();
ТаблицыНачислений.Начисления = Объект.Начисления;
РасчетЗарплатыРасширенныйФормы.РасчетЗарплатыНачисленияВДанныеФормы(ТаблицыНачислений, ДанныеЗаполнения.Начисления, Объект.Организация, Объект.МесяцНачисления);
РасчетЗарплатыРасширенныйФормы.РасчетЗарплатыНДФЛВДанныеФормы(Объект.НДФЛ, Объект.ПримененныеВычетыНаДетейИИмущественные, ДанныеЗаполнения.НДФЛ);
УчетНДФЛФормы.ЗаполнитьВторичныеДанныеТабличныхЧастей(ЭтаФорма);
МассивОписанийТаблицФормы = МассивОписанийТаблицФормы(ЭтаФорма);
ЗарплатаКадрыРасширенный.ВводНачисленийЗаполнитьВторичныеДанныеПоказателей(ЭтаФорма, МассивОписанийТаблицФормы);
ЗарплатаКадрыРасширенный.ПериодНачисленияЗаполнитьИспользованиеПериода(ЭтаФорма, МассивОписанийТаблицФормы);
ЗарплатаКадрыРасширенный.ЗаполнитьДоступностьМестаПолученияДохода(ЭтаФорма, МассивОписанийТаблицФормы);
Т.е. по факту мы используем типовые методы. Но тут своя магия. Чтобы этот код работал, мы должны правильно подготовить данные формы.
Например, в обработчике "ПриСозданииНаСервере" вызвать метод программного создания показателей и их значений в ТЧ Начисления
РасчетЗарплатыРасширенныйФормы.ДокументыВыполненияНачисленийДополнитьФорму(ЭтаФорма, ОписаниеТаблицыНачислений(ЭтаФорма), "Начисления");
А так же у нас должны быть созданы всевозможные служебные процедуры и функции, описывающие наш документ (ОписаниеТаблицыНачислений(), ОписаниеДокумента(), ОписаниеТаблицыНДФЛ(), ОписаниеПанелиВычетыНаСервере(), ОписаниеПанелиВычеты(), КонтролируемыеПоля()).
Думаю, просто нет смысла полностью приводить данный код. К статье прикладываю обработку, в которой реализовано все вышеописанное. С учетом того, что используются только типовые методы, вы можете самостоятельно посмотреть примеры использования на типовых документах.
При некоторой смекалке, можно адаптировать методы модулей РасчетЗарплатыРасширенныйФормы, УчетНДФЛФормы и аналогичные для того, чтобы полностью програмно формировать расчетные документы.
Текущий пример тестировался в ЗУП 3.1.18 и ERP 2.5.7.150