При программном создании элементов справочника ДоговорыКонтрагентов в конфигурациях «1С:Управление торговлей 11», «1С:Комплексная автоматизация» или «1С:ERP Управление предприятием» разработчики часто сталкиваются с ситуацией: договор успешно создается и записывается, однако при попытке провести документ с этим договором движения формируются не по всем регистрам накопления или документ вовсе не проводит взаиморасчеты и складской учет. Разберем по шагам, почему это происходит и как правильно создавать договоры кодом.
Проанализируем архитектуру конфигураций на платформе «1С:Предприятие 8.3». При интерактивном создании договора в форме срабатывает множество событий, которые заполняют значения по умолчанию, зависящие от настроек подсистем и вида договора. При программном вызове метода СоздатьЭлемент() логика формы не отрабатывает, из-за чего ключевые учетные реквизиты остаются пустыми:
ВариантОформленияЗакупок (или ВариантОформленияПродаж): если это поле не заполнено, механизмы проведения документов поступления/реализации не могут определить сценарий оформления складских и финансовых операций, из-за чего блокируются движения по товарным и взаиморасчетным регистрам.Контрагент: в УТ 11 разделены управленческая сущность (Партнер) и юридическое лицо (Контрагент). Отсутствие ссылки на контрагента ломает аналитику взаиморасчетов и регламентированный учет.ГруппаФинансовогоУчета (ГФУ расчетов): определяет счета расчетов и настройки отражения в учете.ХозяйственнаяОперация / ТипДоговора: без правильного типа договора модуль проведения не может применить нужные алгоритмы контроля.Рассмотрим наиболее надежный способ создания договора. Чтобы объект заполнился всеми предопределенными значениями по умолчанию, необходимо передать структуру параметров в процедуру Заполнить(). Это вызовет событие ОбработкаЗаполнения в модуле объекта справочника ДоговорыКонтрагентов.
Посмотрим на пример правильного создания договора:
&НаСервере
Функция СоздатьДоговорСПоставщиком(Партнер, Контрагент, Организация, ВалютаВзаиморасчетов)
// Подготавливаем структуру данных для стандартного обработчика
ДанныеЗаполнения = Новый Структура;
ДанныеЗаполнения.Вставить("Партнер", Партнер);
ДанныеЗаполнения.Вставить("Контрагент", Контрагент);
ДанныеЗаполнения.Вставить("Организация", Организация);
ДанныеЗаполнения.Вставить("ТипДоговора", Перечисления.ТипыДоговоров.СПоставщиком);
НовыйДоговор = Справочники.ДоговорыКонтрагентов.СоздатьЭлемент();
// Вызываем системное заполнение реквизитов по умолчанию
НовыйДоговор.Заполнить(ДанныеЗаполнения);
// Дозаполняем индивидуальные параметры
НовыйДоговор.Наименование = "Основной договор с поставщиком";
НовыйДоговор.Статус = Перечисления.СтатусыДоговоровКонтрагентов.Действует;
НовыйДоговор.ПорядокРасчетов = Перечисления.ПорядокРасчетов.ПоНакладным;
НовыйДоговор.ВалютаВзаиморасчетов = ВалютаВзаиморасчетов;
// Явно указываем варианты оформления, если они не заполнились автоматически
НовыйДоговор.ВариантОформленияЗакупок = Перечисления.ВариантыОформленияЗакупок.НакладнаяИлиЗаказИлиАкт;
НовыйДоговор.ВариантПриемкиТоваров = Перечисления.ВариантыПриемкиТоваров.РазделенаТолькоПоНакладным;
НовыйДоговор.Записать();
Возврат НовыйДоговор.Ссылка;
КонецФункции
Если в конфигурации требуется задать все реквизиты вручную без вызова Заполнить(), проанализируем обязательный состав полей, критичных для регистров движений:
&НаСервере
Функция СоздатьДоговорВручную(Партнер, Контрагент, Организация, ТипДоговора)
Элм = Справочники.ДоговорыКонтрагентов.СоздатьЭлемент();
// Аналитика партнер - контрагент
Элм.Партнер = Партнер;
Элм.Контрагент = Контрагент;
Элм.Организация = Организация;
Элм.ТипДоговора = ТипДоговора;
Элм.Наименование = "Основной Договор";
Элм.Статус = Перечисления.СтатусыДоговоровКонтрагентов.Действует;
Элм.ВалютаВзаиморасчетов = Константы.ВалютаРегламентированногоУчета.Получить();
// Параметры взаиморасчетов и логистики
Элм.ПорядокРасчетов = Перечисления.ПорядокРасчетов.ПоНакладным;
Элм.ПорядокОплаты = Перечисления.ПорядокОплатыПоСоглашениям.РасчетыВРубляхОплатаВРублях;
// КРИТИЧЕСКИ ВАЖНЫЕ РЕКВИЗИТЫ ДЛЯ ПРОВЕДЕНИЯ:
Элм.ВариантОформленияЗакупок = Перечисления.ВариантыОформленияЗакупок.НакладнаяИлиЗаказИлиАкт;
Элм.ВариантПриемкиТоваров = Перечисления.ВариантыПриемкиТоваров.РазделенаТолькоПоНакладным;
Элм.СпособДоставки = Перечисления.СпособыДоставки.ОпределяетсяВРаспоряжении;
Элм.Записать();
Возврат Элм.Ссылка;
КонецФункции
Выясним еще одну частую проблему: некорректный поиск существующего договора перед созданием нового. Если в запросе не проверять реквизит Контрагент, тип договора, пометку удаления и статус, функция может вернуть чужой или закрытый договор.
Разберем пример правильного запроса для поиска действующего договора:
&НаСервере
Функция НайтиСуществующийДоговор(Партнер, Контрагент, Организация, ТипДоговора)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ДоговорыКонтрагентов.Ссылка КАК Ссылка
|ИЗ
| Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
|ГДЕ
| НЕ ДоговорыКонтрагентов.ПометкаУдаления
| И ДоговорыКонтрагентов.Организация = &Организация
| И ДоговорыКонтрагентов.Партнер = &Партнер
| И ДоговорыКонтрагентов.Контрагент = &Контрагент
| И ДоговорыКонтрагентов.ТипДоговора = &ТипДоговора
| И ДоговорыКонтрагентов.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыДоговоровКонтрагентов.Действует)";
Запрос.УстановитьПараметр("Организация", Организация);
Запрос.УстановитьПараметр("Партнер", Партнер);
Запрос.УстановитьПараметр("Контрагент", Контрагент);
Запрос.УстановитьПараметр("ТипДоговора", ТипДоговора);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.Ссылка;
КонецЕсли;
Возврат Справочники.ДоговорыКонтрагентов.ПустаяСсылка();
КонецФункции
Рекомендация: если после создания договора документы продолжают проводиться без движений по отдельным регистрам, откройте созданный договор в режиме предприятия, нажмите кнопку Записать и закрыть и проверьте, какие поля система попросит заполнить обязательно. Это позволит быстро выявить недостающие аналитики, настроенные в конкретной информационной базе.