В процессе работы с клиентами часто возникает необходимость ограничить срок действия выставленного счета на оплату. По умолчанию в программе 1С:Управление торговлей 11.4 (а также в 1С:ERP 2 и 1С:Комплексная автоматизация 2) этот параметр рассчитывается динамически исходя из графиков оплаты или указывается вручную. Однако на практике компании часто хотят жестко задать условие — например, автоматически продлевать срок действия счета на 3 дня от текущей даты или даты оформления документа.
В этой статье мы подробно разберем, как устроен этот механизм в типовом функционале 1С, как изменить его программным путем в модуле менеджера печати, проанализируем возможные риски «быстрых» доработок и рассмотрим архитектурно правильные способы решения этой задачи с использованием БСП (Библиотеки стандартных подсистем).
Прежде чем приступать к изменению исходного кода конфигурации, важно понять, откуда программа берет дату для надписи «Счет действителен до...» в печатной форме:
Если этот вариант не подходит и требуется строго автоматизировать прибавление фиксированного количества дней в печатной форме, перейдем к анализу программного кода.
Рассмотрим ситуацию, когда необходимо изменить дату действия счета непосредственно в момент формирования печатной формы. За генерацию печатного листа отвечает модуль менеджера документа Документ.СчетНаОплатуКлиенту (или соответствующая обработка печати в составе БСП).
Выясним причину, по которой дата выводится именно в текущем формате. В коде за извлечение даты платежа отвечает следующий фрагмент:
Если ТаблицаЭтапыОплаты.Количество = 0 Тогда
ДатаПлатежа = '00010101';
ИначеЕсли ТаблицаЭтапыОплаты.Количество = 1 Тогда
ДатаПлатежа = ТаблицаЭтапыОплаты[0].ДатаПлатежа;
Иначе
ДатаПлатежа = ТаблицаЭтапыОплаты[ТаблицаЭтапыОплаты.Количество-1].ДатаПлатежа;
КонецЕсли;
Как мы видим, если таблица этапов оплаты пуста, переменная ДатаПлатежа принимает значение пустой даты. В противном случае выбирается дата последнего этапа оплаты. Далее формируется текстовая строка для макета:
Если ЗначениеЗаполнено(ДатаПлатежа) Тогда
СтруктураДанныхЗаголовок = Новый Структура;
НадписьСрокДействия = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru='Счет действителен до %1.'"), Формат(ДатаПлатежа, "ДЛФ=D")) + " ";
СтруктураДанныхЗаголовок.Вставить("СрокДействия", НадписьСрокДействия);
ОбластьМакета.Параметры.Заполнить(СтруктураДанныхЗаголовок);
КонецЕсли;
Чтобы автоматически увеличивать срок действия счета на 3 дня, нам нужно модифицировать этот алгоритм. В платформе 1С:Предприятие 8 прибавление чисел к переменной типа Дата происходит в секундах. В одних сутках содержится 86400 секунд (24 часа * 60 минут * 60 секунд). Следовательно, для добавления 3 дней нам нужно прибавить к дате произведение 86400 * 3.
Посмотрим на измененный вариант кода:
Если ТаблицаЭтапыОплаты.Количество = 0 Тогда
ДатаПлатежа = '00010101';
ИначеЕсли ТаблицаЭтапыОплаты.Количество = 1 Тогда
ДатаПлатежа = ТаблицаЭтапыОплаты[0].ДатаПлатежа;
Иначе
ДатаПлатежа = ТаблицаЭтапыОплаты[ТаблицаЭтапыОплаты.Количество-1].ДатаПлатежа;
КонецЕсли;
Если ЗначениеЗаполнено(ДатаПлатежа) Тогда
// Увеличиваем дату платежа на 3 календарных дня
ДатаПлатежа = ДатаПлатежа + 86400 * 3;
СтруктураДанныхЗаголовок = Новый Структура;
НадписьСрокДействия = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru='Счет действителен до %1.'"), Формат(ДатаПлатежа, "ДЛФ=D")) + " ";
СтруктураДанныхЗаголовок.Вставить("СрокДействия", НадписьСрокДействия);
ОбластьМакета.Параметры.Заполнить(СтруктураДанныхЗаголовок);
КонецЕсли;
ТабличныйДокумент.Вывести(ОбластьМакета);
Этот простой способ решает задачу вывода измененной даты на печать, однако он несет в себе скрытые риски для ведения учета.
Перед внедрением решения с жестким прибавлением дней в коде печати, проанализируем последствия для бизнес-логики предприятия:
86400 * 3 увеличивает срок на 3 календарных дня. Если менеджер выставил счет в пятницу в конце рабочего дня, срок его действия истечет в понедельник. У клиента фактически останется всего один рабочий день на проведение оплаты.Чтобы избежать проблемы выходных дней, рекомендуется использовать функции работы с производственными календарями, встроенные в БСП. Например, метод КалендарныеГрафики.ПолучитьДатуЗавершенияСрока позволяет рассчитать дату с учетом только рабочих дней:
КалендарьСсылка = Справочники.ПроизводственныеКалендари.НайтиПоНаименованию("Российская Федерация");
Если ЗначениеЗаполнено(КалендарьСсылка) Тогда
ДатаПлатежа = КалендарныеГрафики.ПолучитьДатуЗавершенияСрока(ДатаПлатежа, 3, КалендарьСсылка);
Иначе
ДатаПлатежа = ДатаПлатежа + 86400 * 3; // Откат к календарным дням, если календарь не заполнен
КонецЕсли;
Часто у начинающих разработчиков возникает вопрос: как передать новые реквизиты из формы документа в печатную форму? В управляемых формах 1С и подсистеме печати БСП действует строгое разделение логики интерфейса и логики формирования данных.
В процедуру печати передается не форма документа со всеми ее элементами, а исключительно массив ссылок — МассивОбъектов. Это сделано для того, чтобы печатную форму можно было сформировать групповым способом прямо из списка документов, не открывая их формы визуально.
Связь данных происходит следующим образом:
МассивОбъектов.Если вам нужно вывести в печатную форму значение, которое пользователь выбирает на форме (например, произвольное число дней отсрочки), добавьте это поле как Дополнительный реквизит документа в режиме «1С:Предприятие» (меню НСИ и администрирование -> Дополнительные реквизиты и сведения). Затем в коде формирования запроса печатной формы считайте этот реквизит из табличной части ДополнительныеРеквизиты вашего документа.
Изменение типовой конфигурации напрямую в коде («снятие с поддержки») существенно усложняет последующие обновления программного продукта. Для обслуживания нескольких баз в такой ситуации удобно использовать автоматическое обновление и архивирование 1С по расписанию. Рассмотрим три безопасных альтернативных метода реализации задачи:
Это самый популярный и безопасный метод. Вы копируете типовой макет и код формирования счета во внешнюю обработку (файл с расширением .epf), вносите туда необходимые изменения даты и регистрируете её в базе через меню НСИ и администрирование -> Печатные формы, отчеты и обработки. При этом конфигурация остается полностью типовой. Для упрощения кастомизации под требования компании можно использовать внешнюю печатную форму счета на оплату с возможностью пользовательской настройки.
В современном стандарте разработки 1С изменения логики вносятся через механизм расширений. Мы можем перехватить процедуру формирования печатных данных, используя аннотацию &После или &Вместо. Это позволит изменять логику заполнения параметров макета, сохраняя возможность автоматического обновления основной конфигурации.
Если бизнес-процессы допускают использование статического текста вместо точной даты (например, формулировка «Счет действителен к оплате в течение 3-х банковских дней с момента выставления»), то программирование вообще не требуется. Достаточно перейти в раздел НСИ и администрирование -> Макеты печатных форм, найти макет счета на оплату, открыть его для редактирования и заменить параметр СрокДействия на фиксированный текст в нужной ячейке.