Как программно проверить, оплачен ли документ Заказ клиента в 1С?

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

В процессе разработки дополнительных обработок или расширений для 1С:Управление торговлей 11, ERP 2 или Комплексной автоматизации часто возникает необходимость программно определить статус оплаты «Заказа клиента». Это может потребоваться для автоматического разрешения отгрузки, отправки уведомлений клиенту или формирования управленческой отчетности. Рассмотрим подробнее несколько способов решения этой задачи — от простых запросов к регистрам до использования встроенных механизмов конфигурации.

Способ 1. Использование регистра сведений «Состояния заказов клиентов»

Самый простой и быстрый способ в типовых конфигурациях (таких как УТ 11.4) — обратиться к регистру сведений СостоянияЗаказовКлиентов. Этот регистр хранит агрегированные данные, которые система рассчитывает автоматически. Разберем по шагам, как написать функцию для проверки полной оплаты.

Проанализируем пример кода, который возвращает результат на основе процента оплаты:


Функция ПроверитьОплатуЗаказаПолную(СсылкаНаЗаказ) Экспорт
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	СостоянияЗаказов.ПроцентОплаты КАК ПроцентОплаты
        |ИЗ
        |	РегистрСведений.СостоянияЗаказовКлиентов КАК СостоянияЗаказов
        |ГДЕ
        |	СостоянияЗаказов.Заказ = &СсылкаНаЗаказ";
    
    Запрос.УстановитьПараметр("СсылкаНаЗаказ", СсылкаНаЗаказ);
    
    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();
    
    Если Выборка.Следующий() Тогда
        Возврат (Выборка.ПроцентОплаты = 100);
    КонецЕсли;
    
    Возврат Ложь;
    
КонецФункции

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

Способ 2. Анализ остатков по регистру накопления «Расчеты с клиентами»

Если нам нужна максимальная точность, мы должны обратиться к регистру накопления РасчетыСКлиентами. Этот регистр хранит фактические движения денежных средств и задолженностей. Выясним причину, по которой этот метод считается более надежным: он работает с первичными данными взаиморасчетов.

Посмотрим на пример запроса, который определяет остаток долга по конкретному заказу:


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

При использовании этого метода стоит учитывать настройку «Объект расчетов». В 1С:ERP и УТ 11 расчеты могут вестись не по заказам, а по договорам в целом. Если в договоре указана детализация «По договорам», то в регистре РасчетыСКлиентами поле ЗаказКлиента (или ОбъектРасчетов) будет содержать ссылку на договор. В этом случае проверка по конкретному заказу через остатки регистра может вернуть некорректный результат. Для получения точных данных без написания собственных запросов можно использовать готовую обработку для контроля остатков оплаты и отгрузок по заказам.

Способ 3. Использование стандартного API конфигурации

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

Рассмотрим подробнее, как ее можно вызвать из программного кода:


// Пример получения состояния расчетов
СостояниеРасчетов = Новый Структура("СуммаОплаты, ПроцентОплаты, СуммаДолга");
Документы.ЗаказКлиента.РассчитатьСостояние(ВашаСсылкаНаЗаказ, ВашаСсылкаНаЗаказ.Договор, СостояниеРасчетов);

Если СостояниеРасчетов.ПроцентОплаты >= 100 Тогда
    Сообщить("Заказ полностью оплачен!");
КонецЕсли;

Этот метод хорош тем, что внутри него 1С сама решает, откуда брать данные — из регистров или оперативных расчетов, и как обрабатывать объект расчетов.

Способ 4. Проверка подчиненных документов (оплата на основании)

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

Проанализируем ситуацию, когда оплата идет через документы ПоступлениеБезналичныхДенежныхСредств или ПриходныйКассовыйОрдер:

  1. Оплата считается подтвержденной только в том случае, если документ проведен.
  2. Для безналичных платежей важно наличие флага ПроведеноБанком.
  3. Сумма всех таких документов должна соответствовать сумме документа ЗаказКлиента.

Сложные нюансы взаиморасчетов в 1С

При реализации проверки оплаты важно учитывать архитектурные особенности системы:

Подводя итог, можно сказать: для быстрой проверки в пользовательском интерфейсе достаточно использовать регистр СостоянияЗаказовКлиентов. Однако для критически важных бизнес-алгоритмов (например, автоматическая выдача цифрового товара или разрешение на отгрузку со склада) рекомендуется использовать комбинацию запроса к РасчетыСКлиентами.Остатки и вызова типовой процедуры РассчитатьСостояние.

← На главную