В конфигурации «1С:Бухгалтерия предприятия 3.0» в карточке справочника Договоры предусмотрено поле Срок действия. Однако по умолчанию система не блокирует проведение первичных документов (реализаций, поступлений, счетов и т. д.), если дата документа превышает указанный в договоре срок окончания. Разберем, как реализовать подобную проверку штатно и с помощью механизмов доработки.
Прежде чем переходить к написанию программного кода, проанализируем базовые механизмы системы. Если задача состоит в том, чтобы пользователи не могли выбирать завершенные договоры в новых операциях, доработка конфигурации может не потребоваться.
В карточке договора контрагента предусмотрен реквизит Договор закрыт. При установке этого флага договор автоматически исключается из списков выбора в документах. Для контроля истекших сроков можно использовать стандартные отчеты по справочнику Договоры с настройкой фильтрации по полю Срок действия.
Если необходимо жестко запретить запись или проведение документов с просроченными договорами без снимания типовой конфигурации с поддержки, наилучшим решением станет использование подписки на событие. Рассмотрим вариант проверки в обработчике ПередЗаписью или ОбработкаПроведения.
При проверке срока действия договора необходимо учесть важную деталь: пустая дата в 1С инициализируется как Дата(1,1,1,0,0,0). Чтобы документы по бессрочным договорам или договорам без указанного срока продолжали проводиться, обязательно добавляем условие проверки заполненности реквизита.
Посмотрим на пример процедуры обработки в общем модуле:
Процедура ПроверитьСрокДействияДоговораПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
// Пропускаем загрузку данных, чтобы не ломать обмены и ЭДО
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Проверяем наличие реквизита ДоговорКонтрагента в метаданных документа
Если Источник.Метаданные().Реквизиты.Найти("ДоговорКонтрагента") = Неопределено Тогда
Возврат;
КонецЕсли;
Договор = Источник.ДоговорКонтрагента;
// Если договор не выбран или срок действия не заполнен — пропускаем
Если Не ЗначениеЗаполнено(Договор) Или Не ЗначениеЗаполнено(Договор.СрокДействия) Тогда
Возврат;
КонецЕсли;
// Сравниваем дату документа с датой окончания договора
Если НачалоДня(Источник.Дата) > Договор.СрокДействия Тогда
Отказ = Истина;
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
СтрШаблон("Срок действия договора '%1' истек (%2). Проведение документа невозможно!",
Договор, Формат(Договор.СрокДействия, "ДФ=dd.MM.yyyy"))
);
КонецЕсли;
КонецПроцедуры
Проанализируем применение расширений 1С для решения этой задачи. Использование расширений позволяет сохранить типовую конфигурацию на полной поддержке и упрощает последующие обновления.
ПередЗаписью для требуемых типов документов (например, ДокументОбъект.РеализацияТоваровУслуг, ДокументОбъект.ПоступлениеТоваровУслуг и др.).ПриИзменении полей ДоговорКонтрагента и Дата подключаем серверную процедуру проверки.Выясним основные риски и особенности работы с датами и объектами платформы 1С:
СрокДействия обычно хранит только дату (время 00:00:00). Дата документа содержит время. При прямом сравнении Договор.СрокДействия < Источник.Дата документ, созданный в день окончания договора (например, в 14:00), система ошибочно посчитает просроченным. Используйте функцию НачалоДня() для даты документа.Источник.ДоговорКонтрагента.СрокДействия создает неявный SQL-запрос. В высоконагруженных системах целесообразно использовать функции БСП, например ОбщегоНазначения.ЗначенияРеквизитовОбъекта(), для считывания значения реквизита.Источник.ОбменДанными.Загрузка, чтобы блокировка проведения не нарушила автоматический импорт документов из внешних систем или электронного документооборота (ЭДО).