Задача
Заказчик решил переходить на ЗУП 3.0 (ранее учёт вёлся не в 1С). Основное условие - полный перенос кадровой истории по сотрудникам (работающим на текущий момент) для отражения в Т-2 (в части касающейся текущей задачи это отпуска).
А как же это реализовать?
Ввести остатки отпусков при переходе или переносе данных возможно двумя способами:
- документ "Ввод начальных остатков отпусков"
- документ "Данные на начало эксплуатации"
Т.к. мы по задаче переносим кадровую историю, включающую данные по предоставленным ранее отпускам, то наш единственный выбор "Ввод начальных остатков отпусков". Но тут оказалась проблема: если в программе введены данные по фактическим отпускам ранее даты ввода остатков (а у нас как раз такой случай), то ввести остатки не получится! [это задача №1]
Остаток по виду отпуска на определённую дату в общем случае есть разность данных регистра сведений "Заработанные права на отпуска" и регистра накопления "Фактические отпуска", но для верного расчёта остатков в нашем случае необходимо отбросить данные фактических отпусков ранее "глобальной" даты начала ведения учёта в программе (заработанные отпуска автоматически скорректируются документом "Ввод начальных остатков отпусков" на дату ввода). [это задача №2]
Ну и напоследок необходимо верно отображать отчёты по отпускам: печатная форма "Справка по отпускам сотрудника" и отчёт "Остатки отпусков". [это задача №3]
Задача №1
Данная корректировка потребуется только на момент ввода документов "Ввод начальных остатков отпусков".
Для отключения проверки на наличие ранее введенных фактических отпусков необходимо закомментировать участок кода процедуры ПередЗаписью в модуле набора записей регистра сведений "Начальные остатки отпусков"
Процедура ПередЗаписью(Отказ, Замещение)
Если ЗарплатаКадры.ОтключитьБизнесЛогикуПриЗаписи(ЭтотОбъект) Тогда
Возврат;
КонецЕсли;
УстановитьПривилегированныйРежим(Истина);
//// проверка на наличие ранее введенных фактических отпусков
//Регистратор = ЭтотОбъект.Отбор.Регистратор.Значение;
//Если ТипЗнч(Регистратор) = Тип("ДокументСсылка.ВводНачальныхОстатковОтпусков") Тогда
// ТаблицаСотрудниковИОтпусков = ЭтотОбъект.Выгрузить(,"Сотрудник,ВидЕжегодногоОтпуска,ДатаОстатка");
// Если (ТаблицаСотрудниковИОтпусков.Количество() > 0) И (СуществуютДвиженияФактическихОтпусковРанее(ТаблицаСотрудниковИОтпусков)) Тогда
//
// ТекстОшибки = НСтр("ru = 'Нельзя вводить остатки датой более поздней, чем зарегистрированные в системе отпуска.'");
//
// ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстОшибки, , , , Отказ);
//
// КонецЕсли;
//
//КонецЕсли;
УдалитьЗаписиЗаработанныхОтпусков(ЭтотОбъект);
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры
Задача №2
"Глобальная дата" - что в конкретном случае это будет такое, следует решать исходя из обстоятельств. В нашем случае это была дата начала года (все данные мы переносили на 1-ое января), а кому-то может потребоваться и "плавающая" дата. Мы же отделались добавлением экспортной (она нам потребуется в задаче №3) функции ПолучитьДатуНачалаВеденияУчета в общем модуле "ОстаткиОтпусков":
Функция ПолучитьДатуНачалаВеденияУчета() Экспорт
Возврат Дата("20150101000000");
КонецФункции
Помимо этого, были внесены изменения в функцию ИсходныеДанныеДляРасчетаОстатков (корректировка запроса):
|ИЗ
| ВТТаблицаДанных КАК ТаблицаДанных
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ФактическиеОтпуска КАК ФактическиеОтпуска
| ЛЕВОЕ СОЕДИНЕНИЕ ВТДатаНачальныхОстатковПоВидамОтпусков КАК ДатаНачальныхОстатков
| ПО ФактическиеОтпуска.Сотрудник = ДатаНачальныхОстатков.Сотрудник
| И ФактическиеОтпуска.ВидЕжегодногоОтпуска = ДатаНачальныхОстатков.ВидЕжегодногоОтпуска
// Необходимый функционал в рамках задачи по учету остатков отпусков: отбросим фактические отпуска, введённые ранее даты начала учета в ЗУП
//| И ФактическиеОтпуска.Период < ДатаНачальныхОстатков.ДатаНачальногоОстатка
| И ФактическиеОтпуска.Период < &НачалоУчетаЗУП
//
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТКадровыеДанныеСотрудников КАК ТекущиеКадровыеДанныеСотрудников
| ПО ФактическиеОтпуска.Сотрудник = ТекущиеКадровыеДанныеСотрудников.Сотрудник
| ПО ТаблицаДанных.Сотрудник = ФактическиеОтпуска.Сотрудник
Задача №3
Оказалось, что печатная форма самостоятельно рассчитывает данные по остаткам отпусков, тогда как отчёт целиком строится на данных ранее озвученных регистров по описанной схеме. В реализации на помощь пришёл механизм БСП :-)
Печатная форма "Справка по отпускам сотрудника" заработает после внесения вышеописанных изменений, но в нашем случае Заказчик пожелал видеть данную справку в "старом" формате (изначально перекочевавшем из ЗУП 2.5, но впоследствии изменённом в ЗУП 3.0). Также добавили возможность формирования справки на рабочую дату (удобно для сверки данных на определённый момент в прошлом или будущем периодах).
Основные доработки коснулись отчёта "Остатки отпусков": по аналогии с кодом запроса в функции из общего модуля "ОстаткиОтпусков" (ранее по тексту) был добавлен фильтр на фактические отпуска ранее даты начала учёта.
Эти печатную форму и отчёт приложу для тех, у кого могут возникнуть затруднения в самостоятельной реализации.
Послесловие
Я не стал описывать механизм загрузки остатков в документ "Ввод начальных остатков отпусков" (у нас он был реализован в виде внешней обработки, читающей данные из заранее подготовленных файлов Excel по определённому алгоритму) - реализацию каждый придумает сам. Уточню только, что может быть несколько документов ввода остатков на разные даты и разные виды отпусков (ведь бывает ситуация, когда имеются остатки за разные периоды, но я бы порекомендовал по возможности свести всё на один конкретный период).
Описанный механизм вполне может быть использован для "быстрой" корректировки (без разбирательств в причинах) остатков отпусков по всем сотрудникам (т.к. использует "глобальную" дату).
Также регулярно советую смотреть в типовой отчёт "ОстаткиОтпусков" и актуализировать модифицированный (уже были исправления ошибок от 1С в данном отчёте).
Данный механизм успешно был применён и пока работает (но не исключаю, что однажды 1С что-то изменят и всё сломается).