Как исправить проблему с расчетом автоматических скидок при проведении документов в 1С:Управление торговлей 11.4?

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

При переходе на новые релизы конфигурации «1С:Управление торговлей» редакции 11.4 (начиная с ветки 11.4.6 и выше) многие пользователи и разработчики столкнулись с неожиданным изменением поведения системы. Автоматические скидки, которые ранее без проблем рассчитывались «на лету» непосредственно в момент проведения документов (например, в релизе 11.4.2.132), перестали вычисляться автоматически. Вместо этого система требует от пользователя ручного нажатия кнопки или выдает ошибку при попытке программного проведения.

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

Выясняем причину: почему изменилось поведение системы?

Для того чтобы понять суть проблемы, проанализируем архитектурные изменения, которые внедрили разработчики фирмы 1С. В старых релизах конфигурации процесс расчета автоматических скидок происходил внутри транзакции проведения документа. Это казалось удобным, так как гарантировало актуальность цен и скидок на момент записи данных в регистры.

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

  1. Длительные блокировки таблиц базы данных. Пока выполнялся расчет и проводилась транзакция, другие пользователи не могли записать или провести свои документы, содержащие те же товарные позиции или контрагентов.
  2. Взаимные блокировки (Deadlocks). При одновременной работе десятков менеджеров система регулярно блокировала транзакции, возвращая критические ошибки СУБД.
  3. Медленная работа системы в целом. Проведение даже небольшого заказа покупателя или реализации могло занимать до нескольких десятков секунд.

Для решения этих проблем разработчики 1С приняли решение вынести расчет автоматических скидок из процедуры проведения. Теперь система требует, чтобы скидки были рассчитаны до начала транзакции проведения, непосредственно в интерактивной форме документа.

Анализ ошибки 000049594 и ее последствия для обменов

Несмотря на то, что архитектурно это решение было правильным и существенно снизило количество блокировок базы данных, его первоначальная реализация вызвала массу сбоев в реальной работе предприятий. Данная проблема официально зарегистрирована в багтрекинге фирмы 1С под номером 000049594.

Суть ошибки заключается в том, что при попытке программного проведения документа (без открытия формы) система блокировала запись, выдавая предупреждение о том, что автоматические скидки не рассчитаны. Это полностью парализовало работу следующих механизмов:

  1. Интеграция с интернет-магазинами (Bitrix, OpenCart и др.). Заказы, поступающие с сайта, создаются в системе программно через фоновые задания. Так как формы документа в этот момент физически не существует, скидки не рассчитывались, и документ не проводился.
  2. Электронный документооборот (EDI и ЭДО). Документы, созданные на основе входящих электронных пакетов, падали с ошибками проведения.
  3. Групповое перепроведение документов. Стандартные обработки группового перепроведения или восстановления последовательности не могли обработать документы, требуя интерактивного вмешательства пользователя.

Давайте рассмотрим, как решать эту проблему в зависимости от вашей роли: обычного пользователя или разработчика 1С.

Решение для обычных пользователей в интерактивном режиме

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

  1. Заполните табличную часть документа товарами, укажите цены и согласуйте все условия сделки.
  2. Перед тем как нажимать кнопку проведения, обратите внимание на командную панель табличной части «Товары». Найдите кнопку «Цены и скидки».
  3. Нажмите на эту кнопку и в выпадающем меню выберите пункт «Рассчитать скидки (наценки)».
  4. Убедитесь, что в колонках автоматических скидок появились рассчитанные значения, а итоговая сумма документа скорректировалась.
  5. После этого нажмите кнопку «Провести и закрыть» или «Провести». Документ запишется без выдачи предупреждений.

В некоторых релизах системы при попытке проведения недосчитанного документа может появляться интерактивное диалоговое окно с вопросом: «В документе не рассчитаны автоматические скидки. Рассчитать и продолжить проведение?». В таком случае пользователю достаточно нажать кнопку «Да» для завершения операции.

Решение для разработчиков: программный расчет скидок

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

Для программного расчета скидок в конфигурациях на базе ERP и УТ 11 используется специальный общий модуль СкидкиНаценкиСервер. Ниже приведен пример кода, который необходимо вставить в вашу обработку загрузки или создания документов перед их проведением:


// Создаем или получаем объект документа (например, Заказ клиента)
ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();

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

В этом примере функция СкидкиНаценкиСервер.ПараметрыРасчетаСкидокНаценок() подготавливает структуру необходимых параметров, а процедура СкидкиНаценкиСервер.РассчитатьСкидкиНаценки() непосредственно модифицирует объект документа, рассчитывая скидки по всем действующим в системе правилам и заполняя соответствующие реквизиты табличной части.

Альтернативное решение: обход проверки проведения

Рассмотрим еще одну ситуацию. Что делать, если вам нужно срочно провести документы программно (например, при переносе остатков или обновлении исторических данных), но рассчитывать скидки заново не нужно (или они уже были жестко зафиксированы ранее)? В таком случае можно использовать специальный механизм обхода проверки через дополнительные свойства объекта.

При проведении документа система проверяет флаг готовности скидок. Мы можем принудительно передать в параметры проведения информацию о том, что скидки уже считаются рассчитанными. Для этого используется добавление специального ключа в коллекцию ДополнительныеСвойства объекта документа:


// Получаем объект документа для изменения
ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();

// Передаем свойство, отключающее проверку расчета скидок
ДокументОбъект.ДополнительныеСвойства.Вставить("СкидкиРассчитаны", Истина);

// Проводим документ без вызова тяжелых процедур расчета
Попытка
    ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
Исключение
    Сообщить("Не удалось провести документ: " + ОписаниеОшибки());
КонецПопытки;

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

Рекомендации по обновлению и настройке системы

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

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

Мы подробно проанализировали особенности работы с автоматическими скидками в конфигурации «1С:Управление торговлей» редакции 11.4. Теперь вы знаете, какими причинами руководствовались разработчики при изменении архитектуры программы, как правильно выполнять расчет в ручном режиме и как обойти ограничения при программном проведении документов в ваших интеграционных решениях.

← На главную