Как в 1С:Управление торговлей 11 создать обработку для формирования заказов поставщикам на основании заказов клиентов?

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

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

1. Архитектурные особенности УТ 11, которые важно учитывать

При программной работе с документами в 1С:Управление торговлей 11 необходимо обращать внимание на следующие нюансы структуры метаданных:

  1. Разделение партнеров и контрагентов: В УТ 11 реализован раздельный учет управленческой сущности (Справочник.Партнеры) и юридического лица (Справочник.Контрагенты). Отбор в форме обычно выполняется по партнеру (клиенту), а в шапку создаваемого документа «Заказ поставщику» также подставляются соответствующие партнер и контрагент-поставщик.
  2. Соглашения и договоры: Документ ЗаказПоставщику требует заполнения реквизита Соглашение (если в системе включено их использование). От соглашения зависят валюта взаиморасчетов, порядок налогообложения и график оплаты.
  3. Статусы документов: Если в базе включено использование статусов заказов, новый документ необходимо создавать в начальном статусе (например, Согласован или НеСогласован), иначе документ не будет проведен.
  4. Табличная часть «Товары»: Обязательными полями для заполнения являются Номенклатура, Количество, КоличествоУпаковок, СтавкаНДС, Цена и Сумма. Если ведется учет по характеристикам, обязательно передается и реквизит Характеристика.

2. Реализация отбора заказов клиентов по периоду и контрагенту

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

Для корректного отбора передадим параметры начала и окончания периода, а также ссылку на клиента. Напишем текст серверной процедуры:


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

3. Формирование общего заказа поставщику со сворачиванием товаров

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

Посмотрим на программную реализацию:


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

4. Создание индивидуального заказа поставщику под каждый заказ клиента

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

Разберем код пакетной обработки:


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

5. Рекомендации по развитию функционала

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

  1. Типовая альтернатива: В конфигурации «1С:Управление торговлей 11» существует штатная обработка Формирование заказов по потребностям, которая умеет автоматически рассчитывать дефицит и формировать заказы поставщикам с учетом схем обеспечения («под заказ», «пополнение остатка»).
  2. Обособление потребностей: Если в компании ведется учет под конкретные заказы, в строках табличной части Товары заказа поставщику можно заполнять реквизит Назначение, указывая исходный заказ клиента.
  3. Пересчет сумм: При программном заполнении не срабатывают клиентские события формы (ПриИзменении), поэтому расчет цен, сумм и сумм НДС следует вызывать явно через штатные серверные процедуры общих модулей подсистемы расчета цен УТ 11.
← На главную