Как реализовать единоразовую продажу клиенту при превышении лимита долга в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

В торговой деятельности нередко возникает ситуация, когда постоянный контрагент превышает установленный договором лимит по сумме задолженности или по сроку отсрочки платежа, но руководство компании готово пойти навстречу и согласовать ровно одну дополнительную отгрузку. При этом менеджеру необходимо заблокировать возможность любых последующих продаж до момента, пока клиент не погасит долг и не вернется в рамки условий договора.

Рассмотрим, как правильно реализовать подобное ограничение в 1С, проанализируем различные подходы и выясним, какие подводные камни могут возникнуть при параллельной работе пользователей.

Вариант 1. Контроль остатка задолженности до проведения документа

Разберем наиболее простой и изящный алгоритм, который не требует создания новых регистров сведений и реквизитов в документах. Суть метода заключается в правильном анализе момента возникновения превышения.

В типовых проверках система обычно сравнивает сумму (ТекущийДолг + СуммаДокумента) с установленным кредитным лимитом. Если мы хотим разрешить ровно одну отгрузку, которая переведет клиента в статус должника-нарушителя, логику проверки достаточно скорректировать:

  1. В процедуре ОбработкаПроведения документа реализации или заказа рассчитываем фактический долг контрагента на момент ДО проведения текущего документа.
  2. Если исходный долг контрагента меньше или равен установленному кредитному лимиту, проведение разрешается независимо от суммы самого документа. Данный документ становится той самой первой «разовой» отгрузкой сверх лимита.
  3. Если исходный долг контрагента уже строго больше лимита, проведение документа блокируется с выдачей предупреждения менеджеру, так как превышение уже состоялось ранее и лимит разовой отгрузки исчерпан.

Посмотрим на пример логики проверки на встроенном языке:


// В обработке проведения документа реализации
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ВзаиморасчетыОстатки.СуммаВзаиморасчетовОстаток КАК ДолгДоПроведения
    |ИЗ
    |	РегистрНакопления.ВзаиморасчетыСКонтрагентами.Остатки(&МоментВремени, ДоговорКонтрагента = &Договор) КАК ВзаиморасчетыОстатки";

Запрос.УстановитьПараметр("МоментВремени", МоментВремени());
Запрос.УстановитьПараметр("Договор", ДоговорКонтрагента);

Выборка = Запрос.Выполнить().Выбрать();
ТекущийДолг = 0;
Если Выборка.Следующий() Тогда
    ТекущийДолг = Выборка.ДолгДоПроведения;
КонецЕсли;

ЛимитПоДоговору = ДоговорКонтрагента.ДопустимаяСуммаЗадолженности;

// Если на момент ДО проведения долг уже превышен — запрещаем продажу
Если ЛимитПоДоговору > 0 И ТекущийДолг > ЛимитПоДоговору Тогда
    Отказ = Истина;
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = "Превышен лимит задолженности! Разовая отгрузка уже была выполнена ранее.";
    Сообщение.Сообщить();
    Возврат;
КонецЕсли;

Важные нюансы: блокировки данных и конкурентный доступ

Проанализируем техническую проблему, которая возникает при реализации такой логики: если клиент одновременно обслуживается несколькими менеджерами или менеджер открыл и одновременно проводит несколько реализаций (состояние гонки / Race Condition). В этот момент обе транзакции могут прочитать исходный долг, увидеть, что он еще не превышен, и успешно провести обе накладные на крупные суммы.

Чтобы исключить подобное поведение, перед чтением взаиморасчетов обязательно установим управляемую исключительную блокировку данных:


Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ВзаиморасчетыСКонтрагентами");
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
ЭлементБлокировки.УстановитьЗначение("ДоговорКонтрагента", ДоговорКонтрагента);
Блокировка.Заблокировать();

Вариант 2. Использование регистра разовых разрешений

Если бизнес-требования строже и не позволяют проводить накладную на произвольную сумму при первом превышении, рассмотрим вариант с регистром сведений РазрешенияНаОтгрузку. Этот подход решает проблему, когда менеджер в рамках «одной продажи» пытается провести отгрузку на необоснованно большую сумму.

Разберем структуру механизма:

  1. Создается периодический регистр сведений или регистр накопления, в котором уполномоченный сотрудник (руководитель отдела продаж, финансовый контролер) регистрирует разрешение: указывает контрагента, договор, максимальную сумму допустимой отгрузки и срок действия разрешения (например, 24 часа).
  2. В документе отгрузки при проведении проверяется наличие действующего разрешения.
  3. При проведении документа сумма разрешения уменьшается либо регистрируется факт использования. Повторный документ без нового документа-согласования система провести не позволит.

Вариант 3. Флаг согласования с разделением ролей

Рассмотрим еще одну распространенную схему, когда исключение возводится в регламентированный процесс:

  1. В документе реализации добавляется реквизит РазрешитьОтгрузкуСПревышениемЛимита (тип Булево).
  2. Право на редактирование этого реквизита ограничивается отдельной ролью, которая назначается только руководителям.
  3. При проведении проверяется: если лимит превышен, но флаг установлен и пользователь имеет соответствующие права (или документ подписан электронной визой согласования), накладная проводится.
  4. Следующий документ уже не сможет быть проведен рядовым менеджером, пока руководство снова не согласует исключение.

Выбор конкретного варианта зависит от масштаба предприятия: для небольших компаний с высокой автономией менеджеров отлично подходит Вариант 1 без дополнительных регистров, а для крупного оптового бизнеса с жестким комплаенсом предпочтительны Варианты 2 и 3 с контролем сумм и сроков разрешений.

← На главную