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

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

Приветствуем вас! При разработке собственных обработок или автоматизации процессов в конфигурации 1С:Управление торговлей 11.4 (а также в сопутствующих решениях ERP 2.x и Комплексная автоматизация 2.x) разработчики часто сталкиваются со следующей проблемой: необходимо сформировать один общий счет на оплату сразу по нескольким заказам клиента. Однако стандартный реквизит ДокументОснование в документе «Счет на оплату клиенту» принимает только одну ссылку на документ-источник.

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

Выясняем причину: почему типовая конфигурация запрещает несколько оснований?

Для начала разберем архитектурную логику построения конфигураций на платформе 1С:Предприятие 8 последних редакций. Если в старых конфигурациях (таких как «Управление торговлей 10.3» или «Бухгалтерия предприятия 3.0») документ «Счет на оплату» — это полноценный документ со своей табличной частью «Товары» (куда можно перенести любые строки из любых заказов), то в УТ 11 / ERP / КА подход принципиально иной.

В современных конфигурациях документ Документ.СчетНаОплатуКлиенту:

  1. Не содержит собственной табличной части «Товары». В нем физически нет списка номенклатуры, цен и скидок.
  2. Содержит только таблицу «Этапы оплаты». В ней фиксируется график платежей, проценты и суммы платежа.
  3. Хранит ссылку на один документ-источник в реквизите ДокументОснование (тип значения — ссылка на один документ: Заказ клиента, Реализация, Отчет комиссионера и т.д.).

Как работает печать счета? Когда пользователь нажимает кнопку «Печать», система берет ссылку из реквизита ДокументОснование, программно обращается к табличной части этого исходного документа-основания (например, к табличной части «Товары» документа «Заказ клиента»), считывает номенклатуру, цены и количество, а затем выводит эти данные на экран. Именно поэтому записать массив заказов в стандартный реквизит физически невозможно — тип данных реквизита строго ссылочный, а не коллекционный.

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

---

Вариант 1. Использование внешней печатной формы (без создания документов в базе)

Если конечная цель менеджеров — просто получить красивую печатную форму счета (в формате PDF, Excel или для отправки на принтер), объединяющую товары из нескольких заказов, то плодить лишние документы в информационной базе нет никакой необходимости. Это самый чистый способ с точки зрения производительности и обновляемости базы.

Мы можем разработать внешнюю печатную форму, которая будет подключаться к списку документов «Заказ клиента». Менеджер сможет выделить несколько заказов в списке, нажать кнопку печати и получить один сводный счет.

Рассмотрим пример программного кода в модуле внешней печатной формы, который обрабатывает массив выбранных документов-оснований и группирует их товарный состав:


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

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

---

Вариант 2. Программное создание «Сводного» заказа

Если бизнес-процесс компании жестко требует создания физического документа «Счет на оплату» в системе (например, для контроля оплат по конкретному документу в казначействе), то лучшим выходом без изменения конфигурации станет создание промежуточного технического (сводного) заказа.

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


Процедура СоздатьСводныйСчетНаОснованииНесколькихЗаказов(МассивЗаказов)
    
    // 1. Создаем новый сводный заказ клиента
    СводныйЗаказ = Документы.ЗаказКлиента.СоздатьДокумент();
    СводныйЗаказ.Дата = ТекущаяДата();
    
    // Заполняем основные реквизиты из первого заказа в массиве
    ПервыйЗаказ = МассивЗаказов[0];
    ЗаполнитьЗначенияСвойств(СводныйЗаказ, ПервыйЗаказ, "Партнер, Контрагент, Организация, Соглашение, Валюта, Договор");
    
    СводныйЗаказ.Комментарий = "Сводный заказ, созданный автоматически на основании нескольких документов.";
    
    // 2. Переносим товары из всех выбранных заказов
    Для Каждого ТекущийЗаказ Из МассивЗаказов Цикл
        Для Каждого СтрокаТовара Из ТекущийЗаказ.Товары Цикл
            НоваяСтрока = СводныйЗаказ.Товары.Добавить();
            ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТовара);
        КонецЦикла;
    EndЦикл;
    
    // Рассчитываем итоговые суммы документа
    // (Рекомендуется использовать типовые процедуры пересчета из модуля менеджера Заказа Клиента)
    
    Попытка
        СводныйЗаказ.Записать(РежимЗаписиДокумента.Проведение);
        
        // 3. Создаем счет на оплату на основании созданного сводного заказа
        НовСчет = Документы.СчетНаОплатуКлиенту.СоздатьДокумент();
        НовСчет.Дата = ТекущаяДата();
        НовСчет.ДокументОснование = СводныйЗаказ.Ссылка;
        
        // Заполняем реквизиты счета по умолчанию
        ЗаполнитьЗначенияСвойств(НовСчет, СводныйЗаказ, "Партнер, Контрагент, Организация, Соглашение, Договор");
        
        // Заполняем этапы оплаты (график берем из сводного заказа)
        // ... Код заполнения этапов оплаты ...
        
        НовСчет.Записать(РежимЗаписиДокумента.Запись);
        
        Сообщить("Сводный счет успешно создан на основании технического заказа: " + СводныйЗаказ.Ссылка);
    Исключение
        Сообщить("Ошибка при создании сводного счета: " + ОписаниеОшибки(), СтатусСообщения.Важное);
    КонецПопытки;
    
КонецПроцедуры

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

---

Вариант 3. Доработка через расширение конфигурации (без снятия с поддержки)

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

Проанализируем алгоритм такой доработки:

  1. Создаем новое расширение конфигурации.
  2. Добавляем в расширение документ СчетНаОплатуКлиенту.
  3. Добавляем в этот документ новую табличную часть — назовем ее ДокументыОснования с единственным реквизитом Документ (тип ссылки на документы заказов).
  4. Добавляем в расширение общую форму или форму документа и выводим эту табличную часть на экран.
  5. Через механизм &Вместо переопределяем процедуру печати счета в модуле менеджера документа. Нам нужно изменить запрос получения данных для печати, чтобы он собирал товары не из одного реквизита ДокументОснование, а из документов, перечисленных в нашей новой табличной части.

Посмотрим на пример измененного запроса в модуле менеджера для сбора данных из ТЧ расширения:


&Вместо("ПодготовитьДанныеДляПечатиСчетов")
Функция Расш1_ПодготовитьДанныеДляПечатиСчетов(МассивСчетов)
    // В этой функции мы пишем запрос, который обращается к нашей новой ТЧ ДокументыОснования
    // и выбирает товары из всех привязанных заказов.
    // ...
КонецФункции

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

---

Вариант 4. Выставление счета по Договору с контрагентом

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

Для реализации этого сценария выполните следующие шаги:

  1. Убедитесь, что в карточке договора с клиентом в разделе «Расчеты» установлен порядок расчетов «По договорам».
  2. При создании счета на оплату выберите в реквизите ДокументОснование ссылку на этот Договор.
  3. При проведении оплаты и отгрузки все заказы в рамках этого договора будут закрываться общим сальдо по договору.

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

---

Вариант 5. Типовое объединение через документ Реализации (постоплата)

Если по вашему бизнес-процессу счет выставляется клиенту уже после фактической сборки или отгрузки товаров со склада (постоплата), в программе есть замечательный готовый инструмент:

  1. Перейдите в меню НСИ и администрирование — Настройка разделов — Продажи — Оптовые продажи и убедитесь, что включена опция «Реализация по нескольким заказам».
  2. В рабочем месте менеджера выделите в списке несколько заказов одного клиента (важно, чтобы у них совпадали организация, контрагент, соглашение и валюта).
  3. Нажмите кнопку Оформить — Реализация товаров и услуг. Система автоматически объединит все товары из выбранных заказов в один документ реализации.
  4. На основании созданной общей реализации в один клик введите один стандартный Счет на оплату.

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

Резюме

Мы подробно проанализировали проблему записи нескольких заказов в основание счета в 1С:УТ 11.4. Из-за отсутствия собственной табличной части товаров в документе счета сделать это «в лоб» невозможно. Выбирайте наиболее подходящий вам вариант решения:

← На главную