В процессе оперативной работы торговой компании часто возникает необходимость ограничить отгрузку товаров тем клиентам, которые имеют непогашенную задолженность. В конфигурации 1С:Управление нашей фирмой (УНФ) это можно реализовать несколькими способами: от использования встроенных механизмов до внесения правок в программный код. Рассмотрим подробно каждый из вариантов.
Прежде чем приступать к написанию программного кода, проанализируем возможности современных версий УНФ (начиная с 1.6.20 и выше, включая 3.0). Разработчики предусмотрели встроенный функционал контроля дебиторской задолженности, который позволяет запрещать проведение документов отгрузки.
Разберем по шагам, как активировать этот механизм:
Расходную накладную по клиенту с долгом, система выдаст предупреждение или заблокирует действие в зависимости от настроек прав доступа пользователя.Этот метод является наиболее предпочтительным, так как он не требует изменения конфигурации и корректно работает при обновлениях программы.
Если вы используете старую версию программы или стандартный функционал по каким-то причинам не подходит, рассмотрим ситуацию, возникшую в обсуждении на форуме. Автор пытался самостоятельно написать проверку в модуле объекта документа РасходнаяНакладная в процедуре ПередЗаписью, но столкнулся с ошибкой Переменная не определена (КлиентНаФормеДокумента).
Выясним причину ошибки: в модуле объекта мы работаем с данными самого документа, а не с элементами формы. Поэтому обращаться к реквизиту нужно напрямую по его имени, как он задан в метаданных. Обычно это Контрагент.
Проанализируем исправленный и оптимизированный код для проверки задолженности. Рассмотрим пример, который нужно разместить в модуле объекта:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Проверку запускаем только при проведении документа
Если НЕ РежимПроведения Тогда
Возврат;
КонецЕсли;
// Проверим, не является ли это новым документом, чтобы не блокировать запись
// Или используем проверку только для конкретных условий
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РасчетыСПокупателямиОстатки.СуммаОстаток КАК Долг
|ИЗ
| РегистрНакопления.РасчетыСПокупателями.Остатки(
| &Период,
| Контрагент = &Контрагент
| ) КАК РасчетыСПокупателямиОстатки";
// Используем текущую дату или момент времени
Запрос.УстановитьПараметр("Период", Новый Граница(МоментВремени(), ВидГраницы.Исключая));
Запрос.УстановитьПараметр("Контрагент", Контрагент);
РезультатЗапроса = Запрос.Выполнить();
Если НЕ РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
Если Выборка.Долг > 0 Тогда
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Проведение запрещено! У покупателя числится задолженность: " + Выборка.Долг;
Сообщение.Сообщить();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Что мы изменили в коде по сравнению с исходным вариантом на форуме:
КлиентНаФормеДокумента на Контрагент. Это имя реквизита, доступное в контексте ЭтотОбъект.СуммаОстаток вместо КоличествоОстаток. В регистре взаиморасчетов долги всегда хранятся в денежном выражении.Остатки. Это критически важно для производительности системы, чтобы база не «тормозила» при большом количестве записей.СообщениеПользователю, что является более корректным методом вывода информации в управляемом приложении, чем простой Сообщить.Чтобы не снимать конфигурацию с поддержки, крайне рекомендуем использовать механизм Расширений. Вместо изменения модуля объекта напрямую, мы создадим расширение и добавим туда обработчик. Рассмотрим, как это сделать правильно через &После или &Перед.
Наиболее удачным местом для проверки является обработчик ОбработкаПроверкиЗаполнения. Это стандартный механизм платформы, который срабатывает перед записью и проведением, позволяя пользователю увидеть ошибку в удобном интерфейсе.
Пример кода в расширении:
&НаСервере
&Вместо("ОбработкаПроверкиЗаполнения")
Процедура Расш1_ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
// Вызываем стандартную обработку
ПродолжитьВызов(Отказ, ПроверяемыеРеквизиты);
// Если уже есть ошибки заполнения, прерываемся
Если Отказ Тогда
Возврат;
КонецЕсли;
// Выполняем проверку задолженности (аналогичный запрос, как в Способе 2)
// ... логика запроса ...
Если ЗадолженностьНайдена Тогда
Отказ = Истина;
// Пользователь получит уведомление и документ не будет проведен
КонецЕсли;
КонецПроцедуры
Проанализируем ситуацию, когда менеджеру нужно видеть долг еще до нажатия кнопки «Провести». Для этого можно использовать события формы документа. Посмотрим на метод ПриИзменении для поля Контрагент.
Когда пользователь выбирает клиента, система может мгновенно выполнить запрос к регистру РасчетыСПокупателями и вывести предупреждение (информационную надпись) прямо на форме. Это экономит время и позволяет сразу перенаправить клиента в отдел оплат.
Резюмируем:
Контрагент и ресурсу СуммаОстаток.Таким образом, мы обеспечим надежный контроль дебиторской задолженности и предотвратим несанкционированные отгрузки товаров неплательщикам.