Как вывести дату первой оплаты в списке заказов в 1С:Управление торговлей 11

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

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

Различие между плановой и фактической датой оплаты

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

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

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

Вариант 1. Вывод плановой даты через запрос динамического списка

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

Напрямую соединять документ с его табличной частью в динамическом списке нельзя, так как это приведет к дублированию строк (на каждый этап оплаты появится копия строки заказа). Нам нужно использовать группировку. Проанализируем пример запроса:


ВЫБРАТЬ
    ДокументЗаказКлиента.Ссылка КАК Ссылка,
    ДокументЗаказКлиента.Номер КАК Номер,
    ДокументЗаказКлиента.Дата КАК Дата,
    МинимальныеДатыОплаты.ДатаПлатежа КАК ДатаПервойПлановойОплаты
ИЗ
    Документ.ЗаказКлиента КАК ДокументЗаказКлиента
        ЛЕВОЕ СОЕДИНЕНИЕ (
            ВЫБРАТЬ
                Этапы.Ссылка КАК Ссылка,
                МИНИМУМ(Этапы.ДатаПлатежа) КАК ДатаПлатежа
            ИЗ
                Документ.ЗаказКлиента.ЭтапыГрафикаОплаты КАК Этапы
            СГРУППИРОВАТЬ ПО
                Этапы.Ссылка
        ) КАК МинимальныеДатыОплаты
        ПО МинимальныеДатыОплаты.Ссылка = ДокументЗаказКлиента.Ссылка

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

Вариант 2. Вывод фактической даты оплаты через расширение

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

Рассмотрим пошагово алгоритм действий:

  1. Создаем расширение: Добавляем в него документ ЗаказКлиента.
  2. Добавляем реквизит: В расширении добавляем новый реквизит ДатаПервойФактическойОплаты (тип: Дата). Это позволит хранить значение непосредственно в документе, и оно будет доступно для выбора в настройках списка без сложных запросов.
  3. Создаем подписку на события: Нам нужно отслеживать проведение платежных документов (ПоступлениеБезналичныхДенежныхСредств, ПриходныйКассовыйОрдер).
  4. Пишем код заполнения: При проведении оплаты находим заказ-основание и, если реквизит ДатаПервойФактическойОплаты еще не заполнен, записываем туда дату текущего платежа.

Пример кода для обработчика (в модуле расширения):


&После("ОбработкаПроведения")
Процедура Расш1_ЗаполнитьДатуОплаты(Отказ, РежимПроведения)
    Для Каждого СтрокаРасчетов Из ЭтотОбъект.РасшифровкаПлатежа Цикл
        Если ТипЗнч(СтрокаРасчетов.ОбъектОплаты) = Тип("ДокументСсылка.ЗаказКлиента") Тогда
            ЗаказОбъект = СтрокаРасчетов.ОбъектОплаты.ПолучитьОбъект();
            Если ЗаказОбъект.ДатаПервойФактическойОплаты = '00010101' Тогда
                ЗаказОбъект.ДатаПервойФактическойОплаты = ЭтотОбъект.Дата;
                ЗаказОбъект.Записать(РежимЗаписиДокумента.Запись);
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Вариант 3. Использование регистра «Состояния заказов клиентов»

В типовой УТ 11 существует служебный регистр сведений СостоянияЗаказовКлиентов. Система сама обновляет его данные при изменении заказов и оплат. Это наиболее эффективный источник данных для динамических списков.

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

Посмотрим на пример того, как это может выглядеть в запросе динамического списка (фрагмент):


ВЫБРАТЬ
    ДокументЗаказКлиента.Ссылка,
    ДокументЗаказКлиента.Дата,
    ЕСТЬNULL(СостоянияЗаказов.ДатаПервойОплаты, ДАТАВРЕМЯ(1, 1, 1)) КАК ДатаПервойОплаты
ИЗ
    Документ.ЗаказКлиента КАК ДокументЗаказКлиента
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияЗаказовКлиентов КАК СостоянияЗаказов
    ПО СостоянияЗаказов.Заказ = ДокументЗаказКлиента.Ссылка

Важные рекомендации

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

Производительность: Старайтесь избегать вложенных запросов и соединений с большими таблицами движений в динамическом списке. Оптимальный вариант — хранение готовой даты в реквизите документа или в специализированном регистре сведений.

Обновление данных: Если вы решили хранить дату в реквизите заказа, не забудьте написать обработку, которая заполнит это поле для уже существующих документов в базе (старых заказов).

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

Таким образом, для реализации задачи наиболее правильным путем будет использование расширения с добавлением реквизита в ЗаказКлиента и подпиской на проведение платежей. Это обеспечит максимальную скорость работы списка и чистоту типовой конфигурации.

← На главную