Работающий механизм контроля рентабельности по документам
Итак, до меня на предприятии другой программист сделал следующее:
- При проведении документа "Реализация Товаров и Услуг", делается проверка на рентабельность документа. Если документ в целом не рентабелен, то выводится сообщение.
В принципе адекватная мера для предприятия, основной деятельностью которого является оказание услуг по доставке. Ежели текущая доставка не рентабельна (изменились цены, условия доставки и др.), то при проведении пользователю об этом сообщается. Пользователь принимает решение об отмене услуги или изменении условий. Кроме того, на предприятии у менеджеров, обслуживающих клиентов есть целый набор отчетов для контроля всех аспектов заказа. Таким образом, сообщения при проведении отсекают ошибки связанные с изменением условий по сделке. Должен сообщить, что после разговора с клиентом, условия сделки могут много раз поменяться. На нее влияет множество факторов:
- Расстояние перевозки. Время перевозки
- Дорожные условия (может измениться погода, тогда изменятся расценки на перевозку)
- Водитель может заболеть и придется нанимать другого водителя
- Транспорт может не пройти осмотр (технические неисправности при осмотре)
- И множество др. факторов
Таким образом, перед проведением программа последний раз проверяет корректность условий и себестоимость. Себестоимость упрощенно считается по регистрам "Продажи себестоимость", по партиям товаров. Таким образом, при изменении поставок цена может поменяться. Рентабельность считается по себестоимости и данным регистра "Продажи". Если себестоимость документа меньше 5% то выводится сообщение.
Такой механизм работал очень просто. В модуле объекта документа "РеализацияТоваровУслуг", в процедуре "ОбработкаПроведения", после записи движений документа был следующий код:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ПродажиОбороты.Номенклатура КАК Номенклатура,
| ПродажиОбороты.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ПродажиОбороты.Регистратор КАК Регистратор,
| ПродажиОбороты.КоличествоОборот КАК Количество,
| ПродажиОбороты.НДСОборот КАК НДС,
| ПродажиОбороты.СтоимостьОборот КАК Стоимость,
| ЕСТЬNULL(ТаблицаРегистраПродажиСебестоимость.СтоимостьОборотБезДоп, 0) КАК Себестоимость,
| 0 КАК Рентабельность
|ИЗ
| РегистрНакопления.Продажи.Обороты(, , Регистратор, {(Организация).* КАК Организация, (Проект).* КАК Проект, (Подразделение).* КАК Подразделение, (Контрагент).* КАК Покупатель, (ДоговорКонтрагента).* КАК ДоговорПокупателя, (Номенклатура).* КАК Номенклатура, (ХарактеристикаНоменклатуры).* КАК ХарактеристикаНоменклатуры, (ЗаказПокупателя).* КАК ЗаказПокупателя}) КАК ПродажиОбороты
| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| ПродажиСебестоимость.Номенклатура КАК Номенклатура,
| ПродажиСебестоимость.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ПродажиСебестоимость.ЗаказПокупателя КАК ЗаказПокупателя,
| ВЫБОР
| КОГДА ПродажиСебестоимость.ДокументДвижения <> НЕОПРЕДЕЛЕНО
| ТОГДА ПродажиСебестоимость.ДокументДвижения
| ИНАЧЕ ПродажиСебестоимость.Регистратор
| КОНЕЦ КАК Регистратор,
| СУММА(ПродажиСебестоимость.Стоимость) КАК СтоимостьОборот,
| СУММА(ПродажиСебестоимость.Стоимость - ЕСТЬNULL(ВложенныйЗапрос.СтоимостьПриход, 0) * ПродажиСебестоимость.Количество) КАК СтоимостьОборотБезДоп
| ИЗ
| РегистрНакопления.ПродажиСебестоимость КАК ПродажиСебестоимость
| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| ПартииТоваровНаСкладахОбороты.ДокументОприходования КАК ДокументОприходования,
| ПартииТоваровНаСкладахОбороты.Номенклатура КАК Номенклатура,
| СУММА(ПартииТоваровНаСкладахОбороты.СтоимостьПриход / ВложенныйЗапрос.КоличествоПриход) КАК СтоимостьПриход,
| ПартииТоваровНаСкладахОбороты.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры
| ИЗ
| РегистрНакопления.ПартииТоваровНаСкладах.Обороты(, , Регистратор, ) КАК ПартииТоваровНаСкладахОбороты
| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| ПартииТоваровНаСкладахОбороты.Номенклатура КАК Номенклатура,
| ПартииТоваровНаСкладахОбороты.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ПартииТоваровНаСкладахОбороты.ДокументОприходования КАК ДокументОприходования,
| СУММА(ПартииТоваровНаСкладахОбороты.КоличествоПриход) КАК КоличествоПриход
| ИЗ
| РегистрНакопления.ПартииТоваровНаСкладах.Обороты(, , Регистратор, ) КАК ПартииТоваровНаСкладахОбороты
| ГДЕ
| ПартииТоваровНаСкладахОбороты.ДокументОприходования = ПартииТоваровНаСкладахОбороты.Регистратор
|
| СГРУППИРОВАТЬ ПО
| ПартииТоваровНаСкладахОбороты.Номенклатура,
| ПартииТоваровНаСкладахОбороты.ХарактеристикаНоменклатуры,
| ПартииТоваровНаСкладахОбороты.ДокументОприходования) КАК ВложенныйЗапрос
| ПО (ВложенныйЗапрос.ДокументОприходования = ПартииТоваровНаСкладахОбороты.ДокументОприходования)
| И (ВложенныйЗапрос.ХарактеристикаНоменклатуры = ПартииТоваровНаСкладахОбороты.ХарактеристикаНоменклатуры)
| И (ВложенныйЗапрос.Номенклатура = ПартииТоваровНаСкладахОбороты.Номенклатура)
| ГДЕ
| ПартииТоваровНаСкладахОбороты.Регистратор ССЫЛКА Документ.ПоступлениеДопРасходов
| И ПартииТоваровНаСкладахОбороты.Регистратор В
| (ВЫБРАТЬ
| ЗначенияСвойствОбъектов.Объект
| ИЗ
| РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
| ГДЕ
| ЗначенияСвойствОбъектов.Свойство.Код = ""000000001""
| И ЗначенияСвойствОбъектов.Значение.Код = ""000000002"")
|
| СГРУППИРОВАТЬ ПО
| ПартииТоваровНаСкладахОбороты.ДокументОприходования,
| ПартииТоваровНаСкладахОбороты.Номенклатура,
| ПартииТоваровНаСкладахОбороты.ХарактеристикаНоменклатуры) КАК ВложенныйЗапрос
| ПО ПродажиСебестоимость.ДокументОприходования = ВложенныйЗапрос.ДокументОприходования
| И ПродажиСебестоимость.Номенклатура = ВложенныйЗапрос.Номенклатура
| И ПродажиСебестоимость.ХарактеристикаНоменклатуры = ВложенныйЗапрос.ХарактеристикаНоменклатуры
| ГДЕ
| ПродажиСебестоимость.Регистратор = &Регистратор
| {ГДЕ
| ПродажиСебестоимость.Проект.* КАК Проект,
| ПродажиСебестоимость.Подразделение.* КАК Подразделение,
| ПродажиСебестоимость.Номенклатура.* КАК Номенклатура,
| ПродажиСебестоимость.ХарактеристикаНоменклатуры.* КАК ХарактеристикаНоменклатуры,
| ПродажиСебестоимость.ЗаказПокупателя.* КАК ЗаказПокупателя}
|
| СГРУППИРОВАТЬ ПО
| ПродажиСебестоимость.Номенклатура,
| ПродажиСебестоимость.ХарактеристикаНоменклатуры,
| ПродажиСебестоимость.ЗаказПокупателя,
| ВЫБОР
| КОГДА ПродажиСебестоимость.ДокументДвижения <> НЕОПРЕДЕЛЕНО
| ТОГДА ПродажиСебестоимость.ДокументДвижения
| ИНАЧЕ ПродажиСебестоимость.Регистратор
| КОНЕЦ) КАК ТаблицаРегистраПродажиСебестоимость
| ПО (ТаблицаРегистраПродажиСебестоимость.Номенклатура = ПродажиОбороты.Номенклатура)
| И (ТаблицаРегистраПродажиСебестоимость.ХарактеристикаНоменклатуры = ПродажиОбороты.ХарактеристикаНоменклатуры)
| И (ТаблицаРегистраПродажиСебестоимость.ЗаказПокупателя = ПродажиОбороты.ЗаказПокупателя)
| И (ТаблицаРегистраПродажиСебестоимость.Регистратор = ПродажиОбороты.Регистратор)
|ГДЕ
| ПродажиОбороты.Регистратор = &Регистратор
|ИТОГИ
| 100 * ВЫБОР
| КОГДА СУММА(Стоимость) <> 0
| ТОГДА (СУММА(Стоимость) - СУММА(Себестоимость)) / СУММА(Стоимость)
| ИНАЧЕ 0
| КОНЕЦ КАК Рентабельность
|ПО
| Регистратор";
Запрос.УстановитьПараметр("Регистратор",Ссылка);
Результат = Запрос.Выполнить().Выбрать();
Если Результат.Количество()>0 тогда
Результат.Следующий();
Если Результат.Рентабельность < 5 тогда
Сообщить("Рентабельность документа не превышает 5%! Текущая рентабельность: "+Строка(Формат(Результат.Рентабельность,"ЧЦ=15; ЧДЦ=2"))+"%!",СтатусСообщения.ОченьВажное);
КонецЕсли;
КонецЕсли;
Обратите внимание что рентабельность в запросе считается непосредственно при подсчете итогов. Это адекватно ускоряет запрос. Сделано очень грамотно!
В чем состоит моя задача?
Необходимо изменить алгоритм так, чтобы при проведении рентабельность считалась по каждой строке текущего документа. Если в определенных строках рентабельность меньше 5%, то выводить сообщение по конкретной строке. Итак, Начнем с запуска режима 1с Предприятие.
Преимущества использования консоли запросов в любой задаче Программиста 1с
В 1с Предприятии запустим обработку "Консоль запросов". консоль позволяет конструировать и отлаживать запросы прямо в режиме 1с Предприятие, без Конфигуратора. Это очень полезно. Любые разработки я начинаю с тестирования данных с помощью запросов. Это позволяет решить сразу несколько задач:
- Получить выборки данных по интересующим меня критериям
- Отладить запрос, сделать его рабочим, выполняющим возложенную задачу
- Быть уверенным в работе запроса, что он получает нужные данные от Базы Данных.
- Быть уверенным, что в базе данных нужные данные содержатся. Бывает так, что запрос работает, а данных для него просто нет. Вот такие ситуации сразу отслеживаются.
- После отладки запроса его можно сразу применить в отчете, модуле, в конфигураторе.
Итак, я хочу посмотреть, количество и данные документов "Реализация Товаров и Услуг", в которых рентабельность меньше 5%. Берем готовый запрос из конфигуратора, из модуля документа.
Получение контрольной выборки документов для тестирования алгоритма.
Помещаем его в обработку "Консоль запросов". В запросе нет параметров, поэтому нет необходимости их устанавливать. Забыл сказать, что запрос из модуля я упростил, убрал условие
|ГДЕ
| ПродажиОбороты.Регистратор = &Регистратор
Итак, смотрим на данные, которые запрос отобрал из БД:
Мы видим, что в выборке, в колонке "Рентабельность", есть строки в которых Рентабельность = 0 и Рентабельность < 0 Хммм. А я хочу увидеть документы, в которых Рентабельность > 0. Для этого я добавил в запрос условие Рентабельность > 0 и посмотрел результат:
Как раз те документы, которые я искал! При проведении таких документов должны выводиться сообщения, по условиям задачи! Таким образом, после изменений в проведении документа, я буду тестировать алгоритм на данных документах! Но надо будет обязательно проверить, что в других документах, где рентабельность > 5% - сообщение не должно выводиться. Ну что-ж, изменим условие запроса и получим выборку для тестирования:
При проведении таких документов, сообщение не должно выводиться.
Внедрение алгоритма в 1с
Итак, в модуле документа "Реализация Товаров и Услуг", заменим существовавший код на следующий:
// Лунегов П.В. +++
// До изменения:
//Запрос.Текст = "ВЫБРАТЬ
//| ПродажиОбороты.Номенклатура КАК Номенклатура,
//| ПродажиОбороты.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
//| ПродажиОбороты.Регистратор КАК Регистратор,
//| ПродажиОбороты.КоличествоОборот КАК Количество,
//| ПродажиОбороты.НДСОборот КАК НДС,
//| ПродажиОбороты.СтоимостьОборот КАК Стоимость,
//| ЕСТЬNULL(ТаблицаРегистраПродажиСебестоимость.СтоимостьОборотБезДоп, 0) КАК Себестоимость,
//| 0 КАК Рентабельность
//|ИЗ
//| РегистрНакопления.Продажи.Обороты(, , Регистратор, {(Организация).* КАК Организация, (Проект).* КАК Проект, (Подразделение).* КАК Подразделение, (Контрагент).* КАК Покупатель, (ДоговорКонтрагента).* КАК ДоговорПокупателя, (Номенклатура).* КАК Номенклатура, (ХарактеристикаНоменклатуры).* КАК ХарактеристикаНоменклатуры, (ЗаказПокупателя).* КАК ЗаказПокупателя}) КАК ПродажиОбороты
//| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
//| ПродажиСебестоимость.Номенклатура КАК Номенклатура,
//| ПродажиСебестоимость.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
//| ПродажиСебестоимость.ЗаказПокупателя КАК ЗаказПокупателя,
//| ВЫБОР
//| КОГДА ПродажиСебестоимость.ДокументДвижения <> НЕОПРЕДЕЛЕНО
//| ТОГДА ПродажиСебестоимость.ДокументДвижения
//| ИНАЧЕ ПродажиСебестоимость.Регистратор
//| КОНЕЦ КАК Регистратор,
//| СУММА(ПродажиСебестоимость.Стоимость) КАК СтоимостьОборот,
//| СУММА(ПродажиСебестоимость.Стоимость - ЕСТЬNULL(ВложенныйЗапрос.СтоимостьПриход, 0) * ПродажиСебестоимость.Количество) КАК СтоимостьОборотБезДоп
//| ИЗ
//| РегистрНакопления.ПродажиСебестоимость КАК ПродажиСебестоимость
//| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
//| ПартииТоваровНаСкладахОбороты.ДокументОприходования КАК ДокументОприходования,
//| ПартииТоваровНаСкладахОбороты.Номенклатура КАК Номенклатура,
//| СУММА(ПартииТоваровНаСкладахОбороты.СтоимостьПриход / ВложенныйЗапрос.КоличествоПриход) КАК СтоимостьПриход,
//| ПартииТоваровНаСкладахОбороты.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры
//| ИЗ
//| РегистрНакопления.ПартииТоваровНаСкладах.Обороты(, , Регистратор, ) КАК ПартииТоваровНаСкладахОбороты
//| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
//| ПартииТоваровНаСкладахОбороты.Номенклатура КАК Номенклатура,
//| ПартииТоваровНаСкладахОбороты.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
//| ПартииТоваровНаСкладахОбороты.ДокументОприходования КАК ДокументОприходования,
//| СУММА(ПартииТоваровНаСкладахОбороты.КоличествоПриход) КАК КоличествоПриход
//| ИЗ
//| РегистрНакопления.ПартииТоваровНаСкладах.Обороты(, , Регистратор, ) КАК ПартииТоваровНаСкладахОбороты
//| ГДЕ
//| ПартииТоваровНаСкладахОбороты.ДокументОприходования = ПартииТоваровНаСкладахОбороты.Регистратор
//|
//| СГРУППИРОВАТЬ ПО
//| ПартииТоваровНаСкладахОбороты.Номенклатура,
//| ПартииТоваровНаСкладахОбороты.ХарактеристикаНоменклатуры,
//| ПартииТоваровНаСкладахОбороты.ДокументОприходования) КАК ВложенныйЗапрос
//| ПО (ВложенныйЗапрос.ДокументОприходования = ПартииТоваровНаСкладахОбороты.ДокументОприходования)
//| И (ВложенныйЗапрос.ХарактеристикаНоменклатуры = ПартииТоваровНаСкладахОбороты.ХарактеристикаНоменклатуры)
//| И (ВложенныйЗапрос.Номенклатура = ПартииТоваровНаСкладахОбороты.Номенклатура)
//| ГДЕ
//| ПартииТоваровНаСкладахОбороты.Регистратор ССЫЛКА Документ.ПоступлениеДопРасходов
//| И ПартииТоваровНаСкладахОбороты.Регистратор В
//| (ВЫБРАТЬ
//| ЗначенияСвойствОбъектов.Объект
//| ИЗ
//| РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
//| ГДЕ
//| ЗначенияСвойствОбъектов.Свойство.Код = ""000000001""
//| И ЗначенияСвойствОбъектов.Значение.Код = ""000000002"")
//|
//| СГРУППИРОВАТЬ ПО
//| ПартииТоваровНаСкладахОбороты.ДокументОприходования,
//| ПартииТоваровНаСкладахОбороты.Номенклатура,
//| ПартииТоваровНаСкладахОбороты.ХарактеристикаНоменклатуры) КАК ВложенныйЗапрос
//| ПО ПродажиСебестоимость.ДокументОприходования = ВложенныйЗапрос.ДокументОприходования
//| И ПродажиСебестоимость.Номенклатура = ВложенныйЗапрос.Номенклатура
//| И ПродажиСебестоимость.ХарактеристикаНоменклатуры = ВложенныйЗапрос.ХарактеристикаНоменклатуры
//| ГДЕ
//| ПродажиСебестоимость.Регистратор = &Регистратор
//| {ГДЕ
//| ПродажиСебестоимость.Проект.* КАК Проект,
//| ПродажиСебестоимость.Подразделение.* КАК Подразделение,
//| ПродажиСебестоимость.Номенклатура.* КАК Номенклатура,
//| ПродажиСебестоимость.ХарактеристикаНоменклатуры.* КАК ХарактеристикаНоменклатуры,
//| ПродажиСебестоимость.ЗаказПокупателя.* КАК ЗаказПокупателя}
//|
//| СГРУППИРОВАТЬ ПО
//| ПродажиСебестоимость.Номенклатура,
//| ПродажиСебестоимость.ХарактеристикаНоменклатуры,
//| ПродажиСебестоимость.ЗаказПокупателя,
//| ВЫБОР
//| КОГДА ПродажиСебестоимость.ДокументДвижения <> НЕОПРЕДЕЛЕНО
//| ТОГДА ПродажиСебестоимость.ДокументДвижения
//| ИНАЧЕ ПродажиСебестоимость.Регистратор
//| КОНЕЦ) КАК ТаблицаРегистраПродажиСебестоимость
//| ПО (ТаблицаРегистраПродажиСебестоимость.Номенклатура = ПродажиОбороты.Номенклатура)
//| И (ТаблицаРегистраПродажиСебестоимость.ХарактеристикаНоменклатуры = ПродажиОбороты.ХарактеристикаНоменклатуры)
//| И (ТаблицаРегистраПродажиСебестоимость.ЗаказПокупателя = ПродажиОбороты.ЗаказПокупателя)
//| И (ТаблицаРегистраПродажиСебестоимость.Регистратор = ПродажиОбороты.Регистратор)
//|ГДЕ
//| ПродажиОбороты.Регистратор = &Регистратор
//|ИТОГИ
//| 100 * ВЫБОР
//| КОГДА СУММА(Стоимость) <> 0
//| ТОГДА (СУММА(Стоимость) - СУММА(Себестоимость)) / СУММА(Стоимость)
//| ИНАЧЕ 0
//| КОНЕЦ КАК Рентабельность
//|ПО
//| Регистратор";
// после изменения:
Запрос.Текст =
"ВЫБРАТЬ
| ПродажиОбороты.Номенклатура КАК Номенклатура,
| ПродажиОбороты.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ПродажиОбороты.Регистратор КАК Регистратор,
| ПродажиОбороты.КоличествоОборот КАК Количество,
| ПродажиОбороты.НДСОборот КАК НДС,
| ПродажиОбороты.СтоимостьОборот КАК Стоимость,
| ЕСТЬNULL(ТаблицаРегистраПродажиСебестоимость.СтоимостьОборотБезДоп, 0) КАК Себестоимость,
| 100 * ВЫБОР
| КОГДА СУММА(ПродажиОбороты.СтоимостьОборот) <> 0
| ТОГДА (СУММА(ПродажиОбороты.СтоимостьОборот) - СУММА(ЕСТЬNULL(ТаблицаРегистраПродажиСебестоимость.СтоимостьОборотБезДоп, 0))) / СУММА(ПродажиОбороты.СтоимостьОборот)
| ИНАЧЕ 0
| КОНЕЦ КАК Рентабельность,
| ПродажиОбороты.Номенклатура.Наименование,
| ПродажиОбороты.Номенклатура.Код,
| ПродажиОбороты.Номенклатура.Артикул
|ИЗ
| РегистрНакопления.Продажи.Обороты(, , Регистратор, {(Организация).* КАК Организация, (Проект).* КАК Проект, (Подразделение).* КАК Подразделение, (Контрагент).* КАК Покупатель, (ДоговорКонтрагента).* КАК ДоговорПокупателя, (Номенклатура).* КАК Номенклатура, (ХарактеристикаНоменклатуры).* КАК ХарактеристикаНоменклатуры, (ЗаказПокупателя).* КАК ЗаказПокупателя}) КАК ПродажиОбороты
| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| ПродажиСебестоимость.Номенклатура КАК Номенклатура,
| ПродажиСебестоимость.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ПродажиСебестоимость.ЗаказПокупателя КАК ЗаказПокупателя,
| ВЫБОР
| КОГДА ПродажиСебестоимость.ДокументДвижения <> НЕОПРЕДЕЛЕНО
| ТОГДА ПродажиСебестоимость.ДокументДвижения
| ИНАЧЕ ПродажиСебестоимость.Регистратор
| КОНЕЦ КАК Регистратор,
| СУММА(ПродажиСебестоимость.Стоимость) КАК СтоимостьОборот,
| СУММА(ПродажиСебестоимость.Стоимость - ЕСТЬNULL(ВложенныйЗапрос.СтоимостьПриход, 0) * ПродажиСебестоимость.Количество) КАК СтоимостьОборотБезДоп
| ИЗ
| РегистрНакопления.ПродажиСебестоимость КАК ПродажиСебестоимость
| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| ПартииТоваровНаСкладахОбороты.ДокументОприходования КАК ДокументОприходования,
| ПартииТоваровНаСкладахОбороты.Номенклатура КАК Номенклатура,
| СУММА(ПартииТоваровНаСкладахОбороты.СтоимостьПриход / ВложенныйЗапрос.КоличествоПриход) КАК СтоимостьПриход,
| ПартииТоваровНаСкладахОбороты.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры
| ИЗ
| РегистрНакопления.ПартииТоваровНаСкладах.Обороты(, , Регистратор, ) КАК ПартииТоваровНаСкладахОбороты
| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| ПартииТоваровНаСкладахОбороты.Номенклатура КАК Номенклатура,
| ПартииТоваровНаСкладахОбороты.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ПартииТоваровНаСкладахОбороты.ДокументОприходования КАК ДокументОприходования,
| СУММА(ПартииТоваровНаСкладахОбороты.КоличествоПриход) КАК КоличествоПриход
| ИЗ
| РегистрНакопления.ПартииТоваровНаСкладах.Обороты(, , Регистратор, ) КАК ПартииТоваровНаСкладахОбороты
| ГДЕ
| ПартииТоваровНаСкладахОбороты.ДокументОприходования = ПартииТоваровНаСкладахОбороты.Регистратор
|
| СГРУППИРОВАТЬ ПО
| ПартииТоваровНаСкладахОбороты.Номенклатура,
| ПартииТоваровНаСкладахОбороты.ХарактеристикаНоменклатуры,
| ПартииТоваровНаСкладахОбороты.ДокументОприходования) КАК ВложенныйЗапрос
| ПО (ВложенныйЗапрос.ДокументОприходования = ПартииТоваровНаСкладахОбороты.ДокументОприходования)
| И (ВложенныйЗапрос.ХарактеристикаНоменклатуры = ПартииТоваровНаСкладахОбороты.ХарактеристикаНоменклатуры)
| И (ВложенныйЗапрос.Номенклатура = ПартииТоваровНаСкладахОбороты.Номенклатура)
| ГДЕ
| ПартииТоваровНаСкладахОбороты.Регистратор ССЫЛКА Документ.ПоступлениеДопРасходов
| И ПартииТоваровНаСкладахОбороты.Регистратор В
| (ВЫБРАТЬ
| ЗначенияСвойствОбъектов.Объект
| ИЗ
| РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
| ГДЕ
| ЗначенияСвойствОбъектов.Свойство.Код = ""000000001""
| И ЗначенияСвойствОбъектов.Значение.Код = ""000000002"")
|
| СГРУППИРОВАТЬ ПО
| ПартииТоваровНаСкладахОбороты.ДокументОприходования,
| ПартииТоваровНаСкладахОбороты.Номенклатура,
| ПартииТоваровНаСкладахОбороты.ХарактеристикаНоменклатуры) КАК ВложенныйЗапрос
| ПО ПродажиСебестоимость.ДокументОприходования = ВложенныйЗапрос.ДокументОприходования
| И ПродажиСебестоимость.Номенклатура = ВложенныйЗапрос.Номенклатура
| И ПродажиСебестоимость.ХарактеристикаНоменклатуры = ВложенныйЗапрос.ХарактеристикаНоменклатуры
| ГДЕ
| ПродажиСебестоимость.Регистратор = &Регистратор
| {ГДЕ
| ПродажиСебестоимость.Проект.* КАК Проект,
| ПродажиСебестоимость.Подразделение.* КАК Подразделение,
| ПродажиСебестоимость.Номенклатура.* КАК Номенклатура,
| ПродажиСебестоимость.ХарактеристикаНоменклатуры.* КАК ХарактеристикаНоменклатуры,
| ПродажиСебестоимость.ЗаказПокупателя.* КАК ЗаказПокупателя}
|
| СГРУППИРОВАТЬ ПО
| ПродажиСебестоимость.Номенклатура,
| ПродажиСебестоимость.ХарактеристикаНоменклатуры,
| ПродажиСебестоимость.ЗаказПокупателя,
| ВЫБОР
| КОГДА ПродажиСебестоимость.ДокументДвижения <> НЕОПРЕДЕЛЕНО
| ТОГДА ПродажиСебестоимость.ДокументДвижения
| ИНАЧЕ ПродажиСебестоимость.Регистратор
| КОНЕЦ) КАК ТаблицаРегистраПродажиСебестоимость
| ПО (ТаблицаРегистраПродажиСебестоимость.Номенклатура = ПродажиОбороты.Номенклатура)
| И (ТаблицаРегистраПродажиСебестоимость.ХарактеристикаНоменклатуры = ПродажиОбороты.ХарактеристикаНоменклатуры)
| И (ТаблицаРегистраПродажиСебестоимость.ЗаказПокупателя = ПродажиОбороты.ЗаказПокупателя)
| И (ТаблицаРегистраПродажиСебестоимость.Регистратор = ПродажиОбороты.Регистратор)
|ГДЕ
| ПродажиОбороты.Регистратор = &Регистратор
|
|СГРУППИРОВАТЬ ПО
| ПродажиОбороты.Номенклатура,
| ПродажиОбороты.ХарактеристикаНоменклатуры,
| ПродажиОбороты.Регистратор,
| ПродажиОбороты.КоличествоОборот,
| ПродажиОбороты.НДСОборот,
| ПродажиОбороты.СтоимостьОборот,
| ЕСТЬNULL(ТаблицаРегистраПродажиСебестоимость.СтоимостьОборотБезДоп, 0),
| ПродажиОбороты.Номенклатура.Наименование";
// Лунегов П.В. ---
Запрос.УстановитьПараметр("Регистратор",Ссылка);
Результат = Запрос.Выполнить().Выбрать();
Если Результат.Количество()>0 тогда
Пока Результат.Следующий() Цикл
//Результат.Следующий();
Если Результат.Рентабельность < 5 тогда
//Сообщить("Рентабельность документа не превышает 5%! Текущая рентабельность: "+Строка(Формат(Результат.Рентабельность,"ЧЦ=15; ЧДЦ=2"))+"%!",СтатусСообщения.ОченьВажное);
Сообщить("Рентабельность по номенклатуре "+Строка(Результат.НоменклатураНаименование)+" (код ="+Строка(Результат.НоменклатураКод)+
", артикул ="+Строка(Результат.НоменклатураАртикул)+") не превышает 5%! Текущая рентабельность: "+Строка(Формат(Результат.Рентабельность,"ЧЦ=15; ЧДЦ=2"))+"%!",СтатусСообщения.ОченьВажное);
КонецЕсли;
КонецЦикла;
КонецЕсли;
После тестирования на контрольной выборке документов, я заключил, что полностью выполнил задачу. Перенес в рабочую базу мои изменения. Клиент остался доволен. На этом пока все, счастливо!