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