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