gifts2017

Проверка рентабельности по реализациям при проведении

Опубликовал Петр Лунегов (pvlunegov) в раздел Программирование - Практика программирования

В моей практике программиста 1С встретилась интересная задача. При проведении документа "Реализации Товаров и Услуг" на предприятии проводилась проверка рентабельности в целом по документу. Необходимо делать проверку на рентабельность по каждой строке списка товаров.
Предлагаю вам оценить решение задачи.

 

Работающий механизм контроля рентабельности по документам

  Итак, до меня на предприятии другой программист сделал следующее:

  • При проведении документа "Реализация Товаров и Услуг", делается проверка на рентабельность документа. Если документ в целом не рентабелен, то выводится сообщение.

В принципе адекватная мера для предприятия, основной деятельностью которого является оказание услуг по доставке. Ежели текущая доставка не рентабельна (изменились цены, условия доставки и др.), то при проведении пользователю об этом сообщается. Пользователь принимает решение об отмене услуги или изменении условий. Кроме того, на предприятии у менеджеров, обслуживающих клиентов есть целый набор отчетов для контроля всех аспектов заказа. Таким образом, сообщения при проведении отсекают ошибки связанные с изменением условий по сделке. Должен сообщить, что после разговора с клиентом, условия сделки могут много раз поменяться. На нее влияет множество факторов:

  • Расстояние перевозки. Время перевозки
  • Дорожные условия (может измениться погода, тогда изменятся расценки на перевозку)
  • Водитель может заболеть и придется нанимать другого водителя
  • Транспорт может не пройти осмотр (технические неисправности при осмотре)
  • И множество др. факторов

Таким образом, перед проведением программа последний раз проверяет корректность условий и себестоимость. Себестоимость упрощенно считается по регистрам "Продажи себестоимость", по партиям товаров. Таким образом, при изменении поставок цена может поменяться. Рентабельность считается по себестоимости и данным регистра "Продажи". Если себестоимость документа меньше 5% то выводится сообщение.

1.1. Сообщения-предупреждения о рентабельности при проведении Реализации

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

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

Обратите внимание что рентабельность в запросе считается непосредственно при подсчете итогов. Это адекватно ускоряет запрос. Сделано очень грамотно!  

В чем состоит моя задача?

  Необходимо изменить алгоритм так, чтобы при проведении рентабельность считалась по каждой строке текущего документа. Если в определенных строках рентабельность меньше 5%, то выводить сообщение по конкретной строке. Итак, Начнем с запуска режима 1с Предприятие.  

Преимущества использования консоли запросов в любой задаче Программиста 1с

  В 1с Предприятии запустим обработку "Консоль запросов". консоль позволяет конструировать и отлаживать запросы прямо в режиме 1с Предприятие, без Конфигуратора. Это очень полезно. Любые разработки я начинаю с тестирования данных с помощью запросов. Это позволяет решить сразу несколько задач:

  1. Получить выборки данных по интересующим меня критериям
  2. Отладить запрос, сделать его рабочим, выполняющим возложенную задачу
  3. Быть уверенным в работе запроса, что он получает нужные данные от Базы Данных.
  4. Быть уверенным, что в базе данных нужные данные содержатся. Бывает так, что запрос работает, а данных для него просто нет. Вот такие ситуации сразу отслеживаются.
  5. После отладки запроса его можно сразу применить в отчете, модуле, в конфигураторе.

Итак, я хочу посмотреть, количество и данные документов "Реализация Товаров и Услуг", в которых рентабельность меньше 5%. Берем готовый запрос из конфигуратора, из модуля документа.  

Получение контрольной выборки документов для тестирования алгоритма.

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

|ГДЕ
|	ПродажиОбороты.Регистратор = &Регистратор
 

Итак, смотрим на данные, которые запрос отобрал из БД: 2. Рентабельность по реализациям, меньше 5%   Мы видим, что в выборке, в колонке "Рентабельность", есть строки в которых Рентабельность = 0 и Рентабельность < 0 Хммм. А я хочу увидеть документы, в которых Рентабельность > 0. Для этого я добавил в запрос условие Рентабельность > 0 и посмотрел результат: 2.1. Рентабельность по реализациям, меньше 5%, больше нуля   Как раз те документы, которые я искал! При проведении таких документов должны выводиться сообщения, по условиям задачи! Таким образом, после изменений в проведении документа, я буду тестировать алгоритм на данных документах! Но надо будет обязательно проверить, что в других документах, где рентабельность > 5% - сообщение не должно выводиться. Ну что-ж, изменим условие запроса и получим выборку для тестирования: 2.2. Рентабельность по реализациям, больше 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"))+"%!",СтатусСообщения.ОченьВажное);
						КонецЕсли;
					КонецЦикла;
				КонецЕсли;
 

  После тестирования на контрольной выборке документов, я заключил, что полностью выполнил задачу. Перенес в рабочую базу мои изменения. Клиент остался доволен.   На этом пока все, счастливо!

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Александр Александр (SnowManUU) 11.06.15 09:36
Это удобно если в расчет партий производится в момент проведения документов. У меня на предприятие партии рассчитываются регламентным заданием ночью. А так в целом неплохой вариант решения
2. Maxim Vorobyov (quarion) 08.02.16 22:06
Спасибо! применил на своей базе, теперь менеджеры сразу предупреждены, что так нельзя торговать ))
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа