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