Расчет заработной платы
1.5. Регистры расчета
Создадим новый регистр расчета, дадим ему имя НачисленияИУдержания. На вкладке окна настройки регистра расчета Основные зададим еще некоторые параметры, специфичные для регистров расчета, рис. 1.10.
В поле План видов расчета зададим недавно созданный план видов расчета Основной.
Установим флажок Период действия - это означает, что в регистре могут присутствовать виды расчета, для которых может быть задан период действия. После установки этого флажка мы сможем настроить параметры графика.
В поле График нам нужно будет указать регистр сведений, который будет содержать график, используемый при расчете. В нашем случае это регистр РабочиеДниПоГрафику. В поле Значение графика выберем РабочийДень - именно в этом ресурсе регистра сведений будет храниться 1, если день является рабочим. В поле Дата графика выберем измерение регистра Дата.
Установим флаг Базовый период.
Зададим в группе параметров Периодичность параметр Месяц.
Перейдем на вкладку Данные. Зададим здесь следующие параметры, рис. 1.11:
Измерение Сотрудник - тип СправочникСсылка.Сотрудники, флаг Базовое установлен. Будем хранить в этом измерении сотрудника, по которому ведется расчет.
Ресурс Результат - тип Число, длина 10, точность 2. Именно этот ресурс будет содержать вычисленное значение вида расчета, заданного для сотрудника. Результат будет содержать значение в рублях, именно это определило параметры типа данных, использованного для него.
Реквизит ИсходныеДанные - тип число, длина 10, точность 2. В этот реквизит мы будем записывать исходные данные для расчета. Например, для вида расчета Оклад мы запишем сюда исходный размер оклада, для вида расчета Премия - процент, который должен браться от расчетной базы, для вида расчета Удержание - размер удержания в рублях.
Реквизит График - тип СправочникСсылка.ГрафикиРаботы. В этом реквизите будем хранить график, который соответствует сотруднику, для которого мы начисляем заработную плату. В свойстве этого реквизита Связь с графиком установим измерение График регистра сведений Графики работы. Именно благодаря этой настройке мы сможем использовать различные графики работы для разных сотрудников (пятидневка, шестидневка) и при расчете получать правильное количество рабочих дней по каждому графику.
Прежде чем продолжать настройку параметров регистра расчета, нам понадобится создать документ, который будет создавать движения по регистру расчета.
1.6. Документ Начисление зарплаты
Создадим новый документ, дадим ему имя НачислениеЗарплаты. Этот документ должен иметь следующую функциональность:
Перейдем на вкладку Данные окна настройки свойств документа НачислениеЗарплаты, рис. 1.12. Создадим реквизит документа ПериодРегистрации - тип Дата, состав даты - Дата.
Создадим табличную часть НачисленияИУдержания. Создадим в ней следующие реквизиты:
Сотрудник | - тип СправочникСсылка.Сотрудники ; |
ВидРасчета | - тип ПланВидовРасчетаСсылка.Основной ; |
График | - тип СправочникСсылка.ГрафикиРаботы ; |
ИсходныеДанные | - число, длина 10, точность 2; |
ДатаНачала и ДатаОкончания | - Дата, состав даты - Дата. |
Теперь перейдем на вкладку Движения. Запретим оперативное проведение документа, добавим в состав регистров, по которым документ формирует движения, регистр НачисленияИУдержания.
Нажмем на кнопку Конструктор движений. Откроется окно конструктора, рис. 1.13.
При заполнении полей, задающих правила формирования движений мы заполним их следующим образом:
БазовыйПериодНачало и БазовыйПериодКонец в конструкторе мы заполнять не будем. Эти поля нужны нам для вида расчета Премия, поэтому мы заполним их в коде процедуры обработки проведения для данного вида расчета.
Нажмем на кнопку ОК в окне конструктора движений и посмотрим, какой код он сформировал:
Процедура ОбработкаПроведения(Отказ, Режим) //{{__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ // Данный фрагмент построен конструктором. // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!! Для Каждого ТекСтрокаНачисленияИУдержания Из НачисленияИУдержания Цикл // регистр НачисленияИУдержания Движение = Движения.НачисленияИУдержания.Добавить(); Движение.Сторно = Ложь; Движение.ВидРасчета = ТекСтрокаНачисленияИУдержания.ВидРасчета; Движение.ПериодДействияНачало = ТекСтрокаНачисленияИУдержания.ДатаНачала; Движение.ПериодДействияКонец = ТекСтрокаНачисленияИУдержания.ДатаОкончания; Движение.ПериодРегистрации = ПериодРегистрации; Движение.Сотрудник = ТекСтрокаНачисленияИУдержания.Сотрудник; Движение.ИсходныеДанные = ТекСтрокаНачисленияИУдержания.ИсходныеДанные; Движение.График = ТекСтрокаНачисленияИУдержания.График; КонецЦикла; //}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ КонецПроцедуры
Очевидно, что для каждой строки табличной части создается новый элемент коллекции документа Движения.НачисленияИУдержания, после чего заполняются свойства нового элемента.
Модифицируем этот код таким образом, чтобы задать параметры базового периода для вида начисления Премия. Для этого будем проверять вид расчета, присутствующий в обрабатываемой строке, если это - Премия - задаем параметры базового периода. Поместим в цикл обработки строк табличной части такой код:
Если ТекСтрокаНачисленияИУдержания.ВидРасчета= ПланыВидовРасчета.Основной.Премия Тогда Движение.БазовыйПериодНачало=НачалоМесяца(ПериодРегистрации); Движение.БазовыйПериодКонец=КонецМесяца(ПериодРегистрации); КонецЕсли;
Теперь немного изменим ту часть кода, которая задает начало и конец периода действия начисления. В нашем случае лишь один вид начисления нужно "оснастить" периодом действия, который в явном виде будет задавать пользователь. Это - Прогул. У всех остальных период действия будет равняться одному месяцу - начало периода будет совпадать с началом месяца, за который производится начисление заработной платы, конец периода действия будет совпадать с концом месяца. Поэтому мы, для того, чтобы избавить пользователя документа НачислениеЗарплаты от ввода ненужных значений, добавим в наш модуль следующий код, поместив его в цикл обработки строк табличной части:
Если Движение.ВидРасчета=ПланыВидовРасчета.Основной.Прогул Тогда Движение.ПериодДействияНачало = ТекСтрокаНачисленияИУдержания.ДатаНачала; Движение.ПериодДействияКонец = ТекСтрокаНачисленияИУдержания.ДатаОкончания; Иначе Движение.ПериодДействияНачало = НачалоМесяца(ПериодРегистрации); Движение.ПериодДействияКонец = КонецМесяца(ПериодРегистрации); КонецЕсли;
Этот код заменит строки
Движение.ПериодДействияНачало = ТекСтрокаНачисленияИУдержания.ДатаНачала; Движение.ПериодДействияКонец = ТекСтрокаНачисленияИУдержания.ДатаОкончания;
После всех этих действий документ при проведении будет добавлять в регистр расчета данные для расчета. Проверим это. Запустим нашу конфигурацию в режиме 1С:Предприятие, создадим новый документ Начисление зарплаты, заполним его данными и проверим, как эти данные отразились в регистре расчета после проведения документа.
Прежде чем создавать реальный документ по начислению зарплаты, нужно ввести в справочник Графики работы хотя бы пару графиков и заполнить для них регистр Рабочие дни по графику. Заполним этот регистр вручную, например, для пары графиков за один месяц.
На рис. 1.14 вы можете видеть документ, который мы заполнили, и движения в регистре расчета, которые он произвел после проведения, после отработки кода, который мы написали выше.
Если все перенесено верно, а в нашем случае это именно так, мы можем приступать к реализации процедуры расчета. Сделаем это в том же модуле, в котором осуществляется формирование движений.
Сразу хотелось бы отметить, что в существующих конфигурациях обычно применяются несколько другие методы реализации расчетных процедур. В частности, для них характерна следующая последовательность действий. После того, как документ сформировал движения по регистру, происходит запись данных в регистр, после чего управление передается в расчетную процедуру общего модуля с установленным свойством Сервер, что актуально в том случае, если система работает в клиент-серверном режиме. В процедуре, с помощью запроса к таблицам регистра расчета, получают записанные данные и проводят манипуляции с ними. Все эти действия, в итоге, приводят к повышению быстродействия прикладных решений, которые могут использоваться в различных режимах, работать с большими объемами данных. Сущность действия такая же, как в нашем примере, но реализация отличается. Главная цель нашего учебного примера - показать принципы, по которым осуществляется решение расчетных задач, поэтому здесь мы концентрируемся именно на основных принципах, не обращая внимание на оптимальность кода или его быстродействие.
Добавим в процедуру проведения документа команду записи сформированных движений:
Движения.НачисленияИУдержания.Записать();
Эта команда должна следовать за командой закрытия цикла формирования движений.
Добавим в код блок расчета удержания. В соответствии с логикой заданных ранее видов расчета, здесь мы лишь копируем ИсходныеДанные для Удержания в Результат.
Для Каждого Движение из Движения.НачисленияИУдержания Цикл Если Движение.ВидРасчета=ПланыВидовРасчета.Основной.Удержание Тогда Движение.Результат=Движение.ИсходныеДанные; КонецЕсли; КонецЦикла; Движения.НачисленияИУдержания.Записать();
Теперь займемся расчетом оклада.
Для Каждого Движение из Движения.НачисленияИУдержания Цикл Если Движение.ВидРасчета=ПланыВидовРасчета.Основной.Оклад Тогда План = Движение.ПолучитьДанныеГрафика(ВидПериодаРегистраРасчета.ПериодДействия); Факт= Движение.ПолучитьДанныеГрафика(ВидПериодаРегистраРасчета.ФактическийПериодДействия); Движение.Результат= Движение.ИсходныеДанные*Факт[0].РабочийДень/План[0].РабочийДень; КонецЕсли; КонецЦикла; Движения.НачисленияИУдержания.Записать();
Метод ПолучитьДанныеГрафика записи регистра расчета возвращает данные графика в виде таблицы значений, причем, этот метод вызывается с параметром типа ВидПериодаРегистраРасчета. Если вызвать его с видом периода ПериодДействия - будут возвращены данные по графику, отражающие, в нашем случае, полное количество рабочих дней. Вызов метода с видом периода ФактическийПериодДействия возвращает данные с учетом вытесняющих видов расчета.
Запись вида Факт[0] позволяет обратиться к строке таблицы значений. А записью Факт[0].РабочийДень (напомним, РабочийДень - это имя ресурса регистра сведений, который используется как график) мы "вытаскиваем" нужные данные. В нашем случае - количество рабочих дней, отработанных по факту.
В итоге, получив нужные данные, мы проводим следующие манипуляции: делим фактическое количество отработанных дней на плановое и умножаем на размер оклада.
И, наконец, последним этапом нашей расчетной задачи является расчет премии. Его мы реализуем с помощью следующего кода:
Ресурсы=Новый Массив(1); Ресурсы[0]="НачисленияИУдержания.Результат"; Измерения =Новый Структура ("Сотрудник", "НачисленияИУдержания.Сотрудник"); Для Каждого Движение из Движения.НачисленияИУдержания Цикл Если Движение.ВидРасчета=ПланыВидовРасчета.Основной.Премия Тогда ДанныеБазы=Движение.ПолучитьБазу(Ресурсы, Измерения); Движение.Результат=Движение.ИсходныеДанные*ДанныеБазы[0].Результат/100; КонецЕсли; КонецЦикла; Движения.НачисленияИУдержания.Записать();
Для начала мы подготовим параметры для передачи в метод ПолучитьБазу. Это будет массив Ресурсы, который в нашем случае содержит имя ресурса базового регистра расчета в формате "ИмяРегистра.ИмяРесурса". Так же мы готовим структуру Измерения. В структуру мы добавляем новый элемент, имя которого совпадает с именем измерения регистра расчета ( "Сотрудник" ), а значение содержит список измерений (в формате "ИмяРегистра.ИмяИзмерения" ), в нашем случае это одно измерение. Эти данные будут использованы при получении расчетной базы при расчете премии.
В цикле мы записываем в переменную ДанныеБазы результаты выполнения метода ПолучитьБазу для текущей записи регистра расчета (то есть - для вида расчета Премия ). Метод ПолучитьБазу возвращает таблицу значений, строки которой хранят запрошенные при вызове метода данные.
Вспомним, как называется ресурс регистра расчета, в котором хранятся результаты вычислений - это ресурс Результат. Именно по такому имени мы можем обратиться к строке таблицы значений (в нашем случае это одна строка с индексом 0) и получить расчетную базу.
После того, как расчетная база получена, мы рассчитываем размер премии. Так как при заполнении документа подразумевается, что мы вводим процентное значение премии в виде количества процентов (10, 40 и т.д.), то для того, чтобы узнать размер премии, мы должны введенный процентный размер премии разделить на 100 и уже после этого умножать на полученную расчетную базу.
После того, как все вышеперечисленные действия выполнены, мы можем испытать наше решение на практике. Если все выполнено верно - в поле Результат мы получим ожидаемый результат расчета, рис. 1.15.
Теперь в регистре расчета находятся все данные, необходимые для получения итогового размера заработной платы сотрудника. Мы остановимся в разработке "зарплатной" подсистемы нашей конфигурации на данном этапе - при желании вы можете расширять ее возможности, основываясь на уже полученных в ранее изученном курсе знаниях.
В реально существующих конфигурациях на одном из этапов работы проводятся расчеты налоговых платежей, отчислений на социальные нужды. После того, как все расчеты завершены, формируется итоговая сумма к выплате работнику. Для этих целей часто используют возможности регистров накопления, причем, обычно их структура рассчитана на то, чтобы учитывать излишне выплаченную или недовыплаченную заработную плату в прошлых периодах и другие варианты взаиморасчетов с работником. Итоговая сумма выплачивается работнику либо наличными - через кассу, либо - переводом на банковский счет.
1.7. О перерасчетах
Объект конфигурации Регистр расчета может содержать подчиненные объекты - Перерасчеты. Их основная роль заключается в предоставлении разработчику информации о том, какие записи регистра должны быть пересчитаны после изменения других записей. Решение о необходимости перерасчета принимается на основе анализа взаимосвязей видов расчета.
Как мы видели выше, между различными видами расчета возможны достаточно сложные взаимосвязи. Например, у нас есть вид расчета А, базовым видом расчета для которого является вид расчета Б. Запись регистра с видом расчета А должна быть пересчитана в том случае, если изменилась запись с видом расчета Б. Информация, предоставляемая перерасчетами носит уведомительный характер - то есть разработчик должен самостоятельно принять решение о том, нужно ли производить перерасчет.
1.8. Рекомендации по дальнейшему изучению
Понимая принципы работы регистров расчета и планов видов расчета, вы можете продолжить дальнейшее изучение этой темы. Как и в случае с другими механизмами, рекомендуется изучить справочную систему 1С:Предприятие 8 в части описания интересующих вас объектов.
Кроме того, рекомендуется изучить соответствующие части тиражных конфигураций. Эти конфигурации можно и нужно изучать, при необходимости внося изменения в код и в состав объектов конфигурации. Как правило, изначально конфигурации поставляются в закрытом для редактирования виде. Это сделано для того, чтобы даже неподготовленные пользователи могли без проблем обновлять такие конфигурации с помощью периодически выпускаемых комплектов обновлений. Для того, чтобы открыть подобную конфигурацию для редактирования, нужно в Конфигураторе сначала выполнить команду Конфигурация>Открыть конфигурацию - в том случае, если дерево конфигурации не отображается в окне Конфигуратора, такое бывает, когда конфигурация открыта в Конфигураторе впервые. Когда дерево конфигурации отобразится, нужно выполнить команду Конфигурация > Поддержка > Настройка поддержки. В появившемся окне Настройка поддержки, рис. 1.16, нужно нажать на кнопку Включить возможность изменения.
После нажатия на эту кнопку появится окно, рис. 1.17. Ответьте утвердительно на вопрос системы, и конфигурацию можно будет редактировать в учебных (или практических) целях.
Для того, чтобы окончательно снять с поддержки конфигурацию и открыть доступ к редактированию всех ее элементов, следует, после того, как будет включена возможность редактирования конфигурации, нажать на кнопку Снять с поддержки ( рис. 1.16), которая станет активной.
Еще один ценный, постоянно обновляемый источник информации по различным аспектам разработки для 1С:Предприятие - это диски ИТС (Информационно-Технологическое Сопровождение), которые распространяются фирмой 1С по подписке среди зарегистрированных пользователей системы. Если в вашей организации пользуются одной из тиражных конфигураций (бюджетной или хозрасчетной), для получения обновлений организация должна быть подписана на ИТС. Особенно ценны в плане получения дополнительной информации ИТС-диски серии ПРОФ - они, помимо обновлений, содержат множество полезных статей, справочников и других данных.
1.9. Выводы
В этой лекции мы рассмотрели основные принципы работы с планами видов расчета и регистрами расчета. Планы видов расчета содержат списки начислений и удержаний, которые предусмотрены в системе, а так же - описание взаимосвязей начислений и удержаний. Регистры расчета позволяют реализовывать сложные расчеты, в частности, с учетом взаимосвязи и взаимовлияния различных видов расчетов друг на друга.
Наша следующая лекция посвящена разработке справочной системы конфигурации, методам отладки и некоторым дополнительным темам.