В типовой конфигурации 1С:ERP Управление предприятием пользователи часто сталкиваются с ситуацией, когда при проведении документа «Заказ клиента» реквизит Дата согласования автоматически перезаписывается текущей датой сервера. При этом любые ручные корректировки даты сбрасываются при последующих перепроведениях или изменениях параметров отгрузки. Разберем подробно, почему платформа работает именно так, почему системное время берется с сервера, и как правильно настроить систему под требования бизнеса без снятия с поддержки.
Проанализируем базовый механизм работы клиент-серверной архитектуры «1С:Предприятия». При выполнении серверного кода платформа намеренно использует системное время сервера с поправкой на часовой пояс сеанса с помощью функции ТекущаяДатаСеанса(). Время локального компьютера пользователя на сервере намеренно игнорируется для обеспечения целостности данных, исключения рассинхронизации между рабочими станциями и защиты от некорректных локальных настроек времени на компьютерах менеджеров.
В типовом коде модуля объекта «Заказ клиента» при смене статуса или сохранении документа выполняется следующая проверка:
// Установим дату согласования, если документ согласован
Если Не ДокументСогласован И Согласован Тогда
ДатаСогласования = ТекущаяДатаСеанса();
КонецЕсли;
Если в алгоритме отсутствует проверка на первичность заполнения даты, то при каждом проведении согласованного документа дата будет повторно инициализироваться текущим моментом времени. Это критично для предприятий, где дата согласования влияет на расчет графика производства, расчет доступности CTP/ATP и смещение контрольных точек этапов производства.
Разберем логику исправления алгоритма. Чтобы дата согласования не перезаписывалась при повторных проведениях документа (например, при уточнении адреса доставки или параметров обеспечения), необходимо добавить проверку на заполненность реквизита ДатаСогласования или проверку статуса проведения документа.
Посмотрим на пример доработки условия перед записью документа:
// Проверяем, было ли поле заполнено ранее
Если Согласован И НЕ ЗначениеЗаполнено(ДатаСогласования) Тогда
ДатаСогласования = ТекущаяДатаСеанса();
КонецЕсли;
Также можно использовать проверку на первичность проведения объекта:
Если НЕ Объект.Проведен И Согласован Тогда
ДатаСогласования = ТекущаяДатаСеанса();
КонецЕсли;
В таком случае дата зафиксируется один раз в момент первого согласования и не будет изменяться при дальнейших корректировках документа.
Чтобы следовать принципу минимальных изменений основной конфигурации и сохранить типовое обновление, применим механизм расширений (CFE). Создадим расширение и перехватим обработчик события перед записью документа или расчетную процедуру модуля объекта.
Разберем по шагам реализацию через аннотацию &ИзменениеИКонтроль или &Вместо:
ЗаказКлиента в структуру расширения конфигурации.ДатаСогласования установим свойство ТолькоПросмотр = Ложь для профилей пользователей с соответствующими правами, если требуется ручной ввод даты.Если в системе от даты согласования зависят расчеты в нескольких документах (например, «Заказ клиента», «Заказ на производство»), целесообразно использовать подписку на событие ПередЗаписью. Это позволит централизованно управлять логикой во всех объектах через отдельный общий модуль.
Посмотрим на пример реализации алгоритма в общем модуле:
Процедура ДокументыПередЗаписьюКонтрольДатыСогласования(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
// Проверяем наличие реквизита у источника
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
Если Источник.Статус = Перечисления.СтатусыЗаказовКлиентов.Согласован Тогда
Если НЕ ЗначениеЗаполнено(Источник.ДатаСогласования) Тогда
Источник.ДатаСогласования = ТекущаяДатаСеанса();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Данное решение позволяет сохранить конфигурацию на полной поддержке поставщика при размещении подписки и модуля в отдельном расширении.
Выясним, какие штатные инструменты ERP позволяют решить задачу фиксации истории дат без изменения программного кода: