gifts2017

Индексация в период отпуска

Опубликовал Илья Ильин (scientist) в раздел Программирование - Практика программирования

Если индексация прошла до начала отпуска, то документ "Начисление отпуска работникам организаций" производит расчет верно. Если индексация произошла в период отпуска, то индексация не учитывается. Расчетчики попросили, чтобы в период до индексации средний заработок рассчитывался без учета индексации, а после - с индексацией. На форуме 8-ки написано, что данный вопрос можно решить только редактированием конфигурации.

Предыдущая версия публикации некорректно отрабатывала ситуации, когда есть дополнительный отпуск, но нет основного. Данная ошибка устранена.

Предлагаю свой вариант решения проблемы.

Необходимо в процедуру Рассчитать() модуля документа "Начисление отпуска работникам организаций", перед комментарием

// перепишем записи основных начислений в документ

вставить следующий код:

 

//определим была ли индексация в период основного отпуска
ЗапросИндексация = Новый Запрос;
ЗапросИндексация.УстановитьПараметр("Организация", Ссылка.Организация);
ЗапросИндексация.УстановитьПараметр("Сотрудник", Ссылка.Сотрудник);
ЗапросИндексация.УстановитьПараметр("ДатаНачалаОсновногоОтпуска", Ссылка.ДатаНачалаСобытия);
ЗапросИндексация.УстановитьПараметр("ДатаОкончанияОсновногоОтпуска", Ссылка.ДатаОкончанияОсновногоОтпуска);
//
ЗапросИндексация.УстановитьПараметр("ДатаНачалаДополнительногоОтпуска", Ссылка.ДатаНачалаДополнительногоОтпуска);
//
ЗапросИндексация.УстановитьПараметр("ДатаОкончанияДопОтпуска", Ссылка.ДатаОкончанияДополнительногоОтпуска);
ЗапросИндексация.Текст = "ВЫБРАТЬ
                                 |    КоэффициентИндексацииЗаработка.Период КАК Период,
                                 |    КоэффициентИндексацииЗаработка.Сотрудник,
                                 |    КоэффициентИндексацииЗаработка.Организация,
                                 |    КоэффициентИндексацииЗаработка.Коэффициент
                                 |ИЗ
                                 |    РегистрСведений.КоэффициентИндексацииЗаработка КАК КоэффициентИндексацииЗаработка
                                 |ГДЕ
                                 |    КоэффициентИндексацииЗаработка.Организация = &Организация
                                 |    И КоэффициентИндексацииЗаработка.Сотрудник = &Сотрудник
                                 |    И (КоэффициентИндексацииЗаработка.Период > &ДатаНачалаОсновногоОтпуска
                                 |                И КоэффициентИндексацииЗаработка.Период                                  |            ИЛИ КоэффициентИндексацииЗаработка.Период >= &ДатаНачалаДополнительногоОтпуска
                                 |                И КоэффициентИндексацииЗаработка.Период                                  |
                                 |УПОРЯДОЧИТЬ ПО
                                 |    Период";
ВыборкаИндексация = ЗапросИндексация.Выполнить().Выбрать();
   
Если ВыборкаИндексация.Следующий() Тогда
    ТЗСреднийСИндексацией = НаборРасчетСреднего.Выгрузить();
       
    //меняем коэффициенты индексации в индексируемых видах расчета
    Для Каждого СтрокаСреднего Из ТЗСреднийСИндексацией Цикл
        Если СтрокаСреднего.ВидРасчета = ПланыВидовРасчета.СреднийЗаработок.ПоГодовойПремииИндексируемые ИЛИ
            СтрокаСреднего.ВидРасчета = ПланыВидовРасчета.СреднийЗаработок.ПоЗаработкуИндексируемые ИЛИ
            СтрокаСреднего.ВидРасчета = ПланыВидовРасчета.СреднийЗаработок.ПоПремиямИндексируемые Тогда
                   
            МесяцИндексации = Месяц(ВыборкаИндексация.Период);
            ГодИндексации = Год(ВыборкаИндексация.Период);
            МесяцТекущегоПериода = Месяц(СтрокаСреднего.БазовыйПериодНачало);
            ГодТекущегоПериода = Год(СтрокаСреднего.БазовыйПериодНачало);
                   
            //индексация действует только на предшествующие 12 месяцев
            Если (ГодИндексации * 12 + МесяцИндексации - 1) - (ГодТекущегоПериода * 12 + МесяцТекущегоПериода - 1)                 СтрокаСреднего.КоэффициентИндексации = СтрокаСреднего.КоэффициентИндексации * ВыборкаИндексация.Коэффициент;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
       
    //определим размер среднего заработка с учетом индексации
    ЗапросСреднийЗаработок = Новый Запрос;
    ЗапросСреднийЗаработок.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
   
    ПоПремиям = Новый Массив(2);
    ПоПремиям[0] = ПланыВидовРасчета.СреднийЗаработок.ПоПремиямИндексируемые;
    ПоПремиям[1] = ПланыВидовРасчета.СреднийЗаработок.ПоГодовойПремииИндексируемые;
    ПоФиксПремиямНеИндексируемые = Новый Массив(2);
    ПоФиксПремиямНеИндексируемые[0] = ПланыВидовРасчета.СреднийЗаработок.ПоФиксГодовойПремииНеИндексируемые;
    ПоФиксПремиямНеИндексируемые[1] = ПланыВидовРасчета.СреднийЗаработок.ПоФиксПремиямНеИндексируемые;
   
    ЗапросСреднийЗаработок.УстановитьПараметр("ПоПремиям",                        ПоПремиям);  // Премии полностью учитываемые, индексируемые
    ЗапросСреднийЗаработок.УстановитьПараметр("ПоФиксПремиямНеИндексируемые",    ПоФиксПремиямНеИндексируемые); // Премии учитываемые частично, не индексируемые
    ЗапросСреднийЗаработок.УстановитьПараметр("ТаблицаСреднего",                ТЗСреднийСИндексацией);
    ЗапросСреднийЗаработок.УстановитьПараметр("ПериодРасчетаСреднегоЗаработка",    12);
    ЗапросСреднийЗаработок.УстановитьПараметр("Начало",                            Ссылка.ПериодРасчетаСреднегоЗаработкаНачало); 
    ЗапросСреднийЗаработок.УстановитьПараметр("Окончание",                        КонецДня(Ссылка.ПериодРасчетаСреднегоЗаработкаОкончание)); 
   
    ЗапросСреднийЗаработок.Текст =
            "ВЫБРАТЬ
            |    РасчетСреднегоЗаработка.ВидРасчета,
            |    РасчетСреднегоЗаработка.Результат,
            |    РасчетСреднегоЗаработка.ОтработаноДней,
            |    РасчетСреднегоЗаработка.НормаПоПятидневке,
            |    РасчетСреднегоЗаработка.ОтработаноПоПятидневке,
            |    РасчетСреднегоЗаработка.ЧислоМесяцев,
            |    РасчетСреднегоЗаработка.КоэффициентИндексации,
            |    РасчетСреднегоЗаработка.БазовыйПериодНачало,
            |    РасчетСреднегоЗаработка.БазовыйПериодКонец
            |ПОМЕСТИТЬ ВТРасчетСреднегоЗаработка
            |ИЗ
            |    &ТаблицаСреднего КАК РасчетСреднегоЗаработка";
    ЗапросСреднийЗаработок.Выполнить();
           
    ЗапросСреднийЗаработок.Текст =
            "ВЫБРАТЬ
            |    СУММА(ВЫБОР
            |            КОГДА РасчетСреднегоЗаработка.ВидРасчета = ЗНАЧЕНИЕ(ПланВидовРасчета.СреднийЗаработок.ПоЗаработкуИндексируемые)
            |                ТОГДА РасчетСреднегоЗаработка.Результат * ВЫБОР
            |                        КОГДА РасчетСреднегоЗаработка.КоэффициентИндексации < 1
            |                            ТОГДА 1
            |                        ИНАЧЕ РасчетСреднегоЗаработка.КоэффициентИндексации
            |                    КОНЕЦ
            |            КОГДА РасчетСреднегоЗаработка.ВидРасчета = ЗНАЧЕНИЕ(ПланВидовРасчета.СреднийЗаработок.ПоЗаработкуНеИндексируемые)
            |                ТОГДА РасчетСреднегоЗаработка.Результат
            |            КОГДА РасчетСреднегоЗаработка.ЧислоМесяцев = 0
            |                ТОГДА 0
            |            ИНАЧЕ ВЫБОР
            |                    КОГДА РасчетСреднегоЗаработка.ВидРасчета В (&ПоПремиям)
            |                        ТОГДА РасчетСреднегоЗаработка.Результат * ВЫБОР
            |                                КОГДА РасчетСреднегоЗаработка.КоэффициентИндексации < 1
            |                                    ТОГДА 1
            |                                ИНАЧЕ РасчетСреднегоЗаработка.КоэффициентИндексации
            |                            КОНЕЦ
            |                    КОГДА РасчетСреднегоЗаработка.ВидРасчета В (&ПоФиксПремиямНеИндексируемые)
            |                        ТОГДА РасчетСреднегоЗаработка.Результат * ВЫБОР
            |                                КОГДА РасчетСреднегоЗаработка.НормаПоПятидневке = 0
            |                                    ТОГДА 0
            |                                ИНАЧЕ РасчетСреднегоЗаработка.ОтработаноПоПятидневке / РасчетСреднегоЗаработка.НормаПоПятидневке
            |                            КОНЕЦ
            |                    ИНАЧЕ РасчетСреднегоЗаработка.Результат
            |                КОНЕЦ * ВЫБОР
            |                    КОГДА РасчетСреднегоЗаработка.ЧислоМесяцев > &ПериодРасчетаСреднегоЗаработка
            |                        ТОГДА &ПериодРасчетаСреднегоЗаработка / РасчетСреднегоЗаработка.ЧислоМесяцев
            |                    ИНАЧЕ 1
            |                КОНЕЦ
            |        КОНЕЦ) КАК СреднийЗаработок,
            |    СУММА(ВЫБОР
            |            КОГДА РасчетСреднегоЗаработка.ВидРасчета = ЗНАЧЕНИЕ(ПланВидовРасчета.СреднийЗаработок.ПоЗаработкуИндексируемые)
            |                    ИЛИ РасчетСреднегоЗаработка.ВидРасчета = ЗНАЧЕНИЕ(ПланВидовРасчета.СреднийЗаработок.ПоЗаработкуНеИндексируемые)
            |                ТОГДА РасчетСреднегоЗаработка.ОтработаноДней
            |            ИНАЧЕ 0
            |        КОНЕЦ) КАК ОтработаноДней
            |ИЗ
            |    ВТРасчетСреднегоЗаработка КАК РасчетСреднегоЗаработка
            |ГДЕ
            |    РасчетСреднегоЗаработка.БазовыйПериодНачало МЕЖДУ &Начало И &Окончание";   
    ВыборкаСреднийЗаработок = ЗапросСреднийЗаработок.Выполнить().Выбрать();
   
    Если ВыборкаСреднийЗаработок.Следующий()
    Тогда
        СреднедневнойЗаработок = ?(Не ЗначениеЗаполнено(ВыборкаСреднийЗаработок.ОтработаноДней), 0, Окр(ВыборкаСреднийЗаработок.СреднийЗаработок / ВыборкаСреднийЗаработок.ОтработаноДней,2));
    Иначе
        СреднедневнойЗаработок = 0;
    КонецЕсли;
       
    //пересчитаем начисления отпускных, к которым должна быть применена индексация
    Для Каждого СтрокаНачисления Из НаборОсновныеНачисления Цикл
        Если НЕ СтрокаНачисления.Сторно И СтрокаНачисления.ПериодДействияНачало >= ВыборкаИндексация.Период Тогда
            СтрокаНачисления.ДополнительныеДанные = СреднедневнойЗаработок;
            СтрокаНачисления.Результат = СреднедневнойЗаработок * СтрокаНачисления.ОплаченоДнейЧасов;
        КонецЕсли;
    КонецЦикла;
           
КонецЕсли;

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Vladimir (Boroda) 19.11.11 12:32
Спасибо! Попробуем этот вариант расчёта. Обычно мы просто вручную пересчитывали отпуск сотрудникам, уже гуляющим, и выплачивали разницу.
А после этой автоматизации, очевидно, надо просто пересчитать отпуск этим ребятам, и разница определится сама?
2. Илья Ильин (scientist) 19.11.11 12:51
Не забудьте только ввести документ "Индексация заработка". Тогда перерасчет должен пройти правильно.
3. Vladimir (Boroda) 19.11.11 14:20
(2) Ну, это ж естественно! Но, кстати, он и так введётся после индексации в Кадровом перемещении". Так что останется только пересчитать.
4. Илья Ильин (scientist) 19.11.11 20:36
Зачем через кадровое перемещение вводить? У вас индексация не в начале месяца идет?
5. Андрей Важдаев (delta) 23.11.11 07:20
Спасибо огромное!!! Вот расчетчики обрадуются!!!
6. Тамара Горбачева (GTV) 23.11.11 08:21
Очень полезно и своевременно! Спасибо!
7. d ryabov (ryabov_d) 28.12.11 11:15
а в других расчетах по среднему, например командировках или льготных днях родителей, такую правку тоже надо делать?
8. Илья Ильин (scientist) 29.12.11 08:17
Для командировок тоже надо будет редактировать конфигурацию.
9. Екатерина Шушина (Katish7) 20.06.12 06:57
Это что за код такой:

//индексация действует только на предшествующие 12 месяцев
Если (ГодИндексации * 12 + МесяцИндексации - 1) - (ГодТекущегоПериода * 12 + МесяцТекущегоПериода - 1) СтрокаСреднего.КоэффициентИндексации = СтрокаСреднего.КоэффициентИндексации * ВыборкаИндексация.Коэффициент;
КонецЕсли;

???
10. Илья Ильин (scientist) 27.06.12 14:30
Вы видите искаженный кусок кода. На самом деле он выглядит так:

Если (ГодИндексации * 12 + МесяцИндексации - 1) - (ГодТекущегоПериода * 12 + МесяцТекущегоПериода - 1) <= 12 Тогда
СтрокаСреднего.КоэффициентИндексации = СтрокаСреднего.КоэффициентИндексации * ВыборкаИндексация.Коэффициент;
КонецЕсли;

Т.е. если человек взял отпуск с 29 марта, то период среднего будет март прошлого года по февраль нынешнего. Если 1 апреля т.г. прошла индексация, то она должна примениться только к периодам начиная с апреля прошлого года.


P.S. Это моя первая публикация здесь, в следующий раз положу код в текстовый файл.
11. Ирина (lissa707) 21.11.12 00:26
Пробовала добавить код в документ Начисление отпуска...Что-то много разных ошибок выдаёт. Так-как не профессионал - грешу на себя, в первую очередь.
Вот одна из них, выпала уже при отладке-пробовала перерасчитать начисленный отпуск.

{Документ.НачислениеОтпускаРаботникамОрганизаций.МодульОбъекта(248)}: Ошибка при вызове метода контекста (Выполнить)
ВыборкаИндексация = ЗапросИндексация.Выполнить().Выбрать();
по причине:
по причине:
{(12, 16)}: Неверные параметры "И"
И <<?>>КоэффициентИндексацииЗаработка.Период

Уважаемый автор, подскажите!!!!
12. Илья Ильин (scientist) 21.11.12 11:30
Можно скриншот окна конфигуратора, в котором виден проблемный запрос?
13. Илья Ильин (scientist) 21.11.12 13:08
(11) lissa707, скорее всего у вас неверно набран текст указанного запроса. между "И" и "КоэффициентИндексацииЗаработка.Период" должен быть только пробел. а у вас, скорее всего, поставлен еще "&"
14. Ирина (lissa707) 21.11.12 22:33
Да нет, "&" там нет. Код копировала с публикации, не набирала. Скрин приложила.
Прикрепленные файлы:
Документ.rtf
15. Илья Ильин (scientist) 22.11.12 09:49
(14) lissa707, текст запроса должен быть таким:

ЗапросИндексация.Текст = "ВЫБРАТЬ
| КоэффициентИндексацииЗаработка.Период КАК Период,
| КоэффициентИндексацииЗаработка.Сотрудник,
| КоэффициентИндексацииЗаработка.Организация,
| КоэффициентИндексацииЗаработка.Коэффициент
|ИЗ
| РегистрСведений.КоэффициентИндексацииЗаработка КАК КоэффициентИндексацииЗаработка
|ГДЕ
| КоэффициентИндексацииЗаработка.Организация = &Организация
| И КоэффициентИндексацииЗаработка.Сотрудник = &Сотрудник
| И (КоэффициентИндексацииЗаработка.Период > &ДатаНачалаОсновногоОтпуска
| И КоэффициентИндексацииЗаработка.Период <= &ДатаОкончанияОсновногоОтпуска
| ИЛИ КоэффициентИндексацииЗаработка.Период >= &ДатаНачалаДополнительногоОтпуска
| И КоэффициентИндексацииЗаработка.Период <= &ДатаОкончанияДопОтпуска)
|
|УПОРЯДОЧИТЬ ПО
| Период";
16. Ирина (lissa707) 28.11.12 11:01
(15) scientist, а можно весь код в текстовый файл положить? может там еще что-то потерялось?
17. Ирина (lissa707) 28.11.12 11:16
А вообще, все получилось. Большое спасибо!
18. Михаил (bme) 12.09.13 16:30
Большое спасибо! Статья до сих пор актуальная :)
19. NetKat (NetKat) 23.09.13 10:05
Спасибо, помого!. Доработка не учитывает двойной индексации, например у сотрудника отпуск с 05.08. 2013 по 01.10.2013 был начислен в августе. Коэф. индексации с 01.09.2013 =1,14, коэф. индексации с 01.10.13 =1,065. Период отпуска с 05.08.2013 по 31.08.13 должен посчитаться без индексации, период с 01.09.13 по 30.09.13 с коэф= 1,14, а один день 01.10.13 должен посчитаться с коэф. индексации=1,065*1,14=1,2141. При такой настройке период с с 01.09.13 по 01.10.13 посчитается с коэф=1,14.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа