Добавление колонок цены и себестоимости в форму и накладную Акта списания . Розница 3.0

Клиент обратился с доработками по документам. При доработках использовал заготовки, но кое-что пришлось подпилить под новые реалии Розницы 3.0.

Добавление розничной цены и себестоимости в форму документа Акт списания.

В Акт списания попросили добавить колонки розничной цены и себестоимости.

Почему-то в справочнике видов цен не показывается идентификатор для формул:

Пришлось смотреть его через универсальный редактор реквизитов:

В итоге получился такой код доработки формы документа Списание:

&НаСервере
Процедура дор_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
	
	Реквизиты = Новый Массив;
	//Реквизиты.Добавить(Новый РеквизитФормы("дор_ЦенаРозничная", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15,2)), "Объект.Запасы", "Р.Цена", Истина));
	//Реквизиты.Добавить(Новый РеквизитФормы("дор_Себестоимость", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15,2)), "Объект.Запасы", "С-сть", Истина));
	Реквизиты.Добавить(Новый РеквизитФормы("дор_ЦенаРозничная", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15,2)), "Объект.Запасы", "Розничная цена", Истина));
	Реквизиты.Добавить(Новый РеквизитФормы("дор_Себестоимость", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15,2)), "Объект.Запасы", "Себестоимость", Истина));
	ИзменитьРеквизиты(Реквизиты);
	
	Привязка = Элементы.ЗапасыСтранаПроисхождения;
	
	Элемент = ЭтаФорма.Элементы.Вставить("дор_Себестоимость", Тип("ПолеФормы"), Привязка.Родитель, Привязка);
    Элемент.Вид = ВидПоляФормы.ПолеВвода;
    Элемент.ПутьКДанным = "Объект.Запасы.дор_Себестоимость";
	Элемент.Ширина = 8;
	Элемент.АвтоМаксимальнаяШирина = ложь;
	Элемент.РастягиватьПоГоризонтали = ложь;
	Элемент.ТолькоПросмотр = истина;
	
	Элемент = ЭтаФорма.Элементы.Вставить("дор_ЦенаРозничная", Тип("ПолеФормы"), Привязка.Родитель, Привязка);
    Элемент.Вид = ВидПоляФормы.ПолеВвода;
    Элемент.ПутьКДанным = "Объект.Запасы.дор_ЦенаРозничная";
	Элемент.Ширина = 8;
	Элемент.АвтоМаксимальнаяШирина = ложь;
	Элемент.РастягиватьПоГоризонтали = ложь; 
	Элемент.ТолькоПросмотр = истина;
	


КонецПроцедуры                                 

&НаКлиенте
Процедура дор_ПриОткрытииПосле(Отказ)
	ОбновитьДопПоля();
КонецПроцедуры 

&НаКлиенте
Процедура дор_ЗапасыПередНачаломИзмененияПосле(Элемент, Отказ)
	ОбновитьДопПоля(Элементы.Запасы.ТекущаяСтрока);
КонецПроцедуры

&НаКлиенте
Процедура дор_ЗапасыПриОкончанииРедактированияПосле(Элемент, НоваяСтрока, ОтменаРедактирования)
	ОбновитьДопПоля(Элементы.Запасы.ТекущаяСтрока);
КонецПроцедуры

Процедура ОбновитьДопПоля(ТекущаяСтрокаЗапасов = Неопределено) Экспорт
	
	дор_ПолучитьРозничныеЦены(Объект.Дата, ТекущаяСтрокаЗапасов); 
	дор_ПолучитьСебестоимость(Объект.Дата, Объект.Ссылка, ТекущаяСтрокаЗапасов); 

КонецПроцедуры     
	
&НаСервере
Процедура дор_ПолучитьРозничныеЦены(Дата, ИдентификаторСтроки = Неопределено) Экспорт
	ТЗ = дор_Сервер.ПолучитьРозничныеЦены(Объект.Запасы, Дата);
	Для Каждого Строка ИЗ ТЗ Цикл
		Объект.Запасы[Строка.НомерСтроки - 1].дор_ЦенаРозничная = Строка.Значение;
	КонецЦикла;
	
КонецПроцедуры

&НаСервере
Процедура дор_ПолучитьСебестоимость(Дата, Документ, ИдентификаторСтроки = Неопределено) Экспорт
	ТЗ = дор_Сервер.ПолучитьСебестоимость(Объект.Запасы, Дата, Документ);
	Для Каждого Строка ИЗ ТЗ Цикл
		Объект.Запасы[Строка.НомерСтроки - 1].дор_Себестоимость = Строка.Значение;
	КонецЦикла;
КонецПроцедуры


И общий модуль дор_Кэш с повторным использованием переменных на время сеанса:

Функция ВидЦеныРозничная() Экспорт
	Возврат Справочники.ВидыЦен.НайтиПоРеквизиту("ИдентификаторФормул", "Розничные");
КонецФункции

Функция ВидЦеныУчетная() Экспорт
	Возврат Справочники.ВидыЦен.Учетная;
КонецФункции

И общий модуль дор_Сервер:

&НаСервере
Функция ПолучитьРозничныеЦены(Запасы, Дата, ИдентификаторСтроки = Неопределено) Экспорт
	ТЗ = Запасы.Выгрузить(, "НомерСтроки, Номенклатура");
	З = Новый Запрос();
	З.Текст = 
	"ВЫБРАТЬ
	|	Т.НомерСтроки КАК НомерСтроки,
	|	Т.Номенклатура КАК Номенклатура
	|ПОМЕСТИТЬ ТН
	|ИЗ
	|	&ТЗ КАК Т
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	ТН.НомерСтроки КАК НомерСтроки,
	|	ЕСТЬNULL(Т.Цена, 0) КАК Значение
	|ИЗ
	|	ТН КАК ТН
	|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
	|				&Дата,
	|				ВидЦен = &ВидЦен
	|					И Номенклатура В
	|						(ВЫБРАТЬ
	|							ТН.Номенклатура
	|						ИЗ
	|							ТН)) КАК Т
	|		ПО ТН.Номенклатура = Т.Номенклатура";
	З.УстановитьПараметр("Дата", Дата);
	З.УстановитьПараметр("ТЗ", ТЗ);
	З.УстановитьПараметр("ВидЦен", дор_Кэш.ВидЦеныРозничная());
	
	Возврат З.Выполнить().Выгрузить();
	
КонецФункции 

&НаСервере
Функция ПолучитьСебестоимость(Запасы, Дата, Документ, ИдентификаторСтроки = Неопределено) Экспорт
	ТЗ = Запасы.Выгрузить(, "НомерСтроки, Номенклатура");
	З = Новый Запрос();
	З.Текст = 
	"ВЫБРАТЬ
	|	Т.НомерСтроки КАК НомерСтроки,
	|	Т.Номенклатура КАК Номенклатура
	|ПОМЕСТИТЬ ТН
	|ИЗ
	|	&ТЗ КАК Т
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	ТН.НомерСтроки КАК НомерСтроки,
	|	ЕСТЬNULL(Т.Цена, 0) КАК Значение
	|ИЗ
	|	ТН КАК ТН
	|		ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
	|			Т.Номенклатура КАК Номенклатура,
	|			ВЫБОР
	|				КОГДА СУММА(Т.КоличествоОборот) = 0
	|					ТОГДА 0
	|				ИНАЧЕ СУММА(Т.СуммаОборот) / СУММА(Т.КоличествоОборот)
	|			КОНЕЦ КАК Цена
	|		ИЗ
	|			РегистрНакопления.Запасы.Обороты(
	|					&Дата,
	|					&Дата,
	|					Регистратор,
	|					Номенклатура В
	|						(ВЫБРАТЬ
	|							ТН.Номенклатура
	|						ИЗ
	|							ТН)) КАК Т
	|		
	|		СГРУППИРОВАТЬ ПО
	|			Т.Номенклатура) КАК Т
	|		ПО ТН.Номенклатура = Т.Номенклатура";
	З.УстановитьПараметр("Дата", Дата);
	З.УстановитьПараметр("ТЗ", ТЗ);
	З.УстановитьПараметр("Документ", Документ);   
	
	Возврат З.Выполнить().Выгрузить();
	
	
КонецФункции


Результат выглядит так:

Нюанс со списаниями на основании инвентаризации

В процессе выяснилось, что можно создавать списание на основе инвентаризации. Но если указать в инвентаризации свои цены для списания:

То по движениям видно, что списание списывает все равно по средней себестоимости:

Т.е. Розница не позволяет задать свою цену списания себестоимости, она позволяет менять цены в инвентаризации только для того, чтобы списывать эту стоимость с материально-ответственных лиц.

Сумма в документе списания выводится в таком случае из документа инвентаризации и отличается от себестоимости:

Добавление розничной цены и себестоимости в печатную форму

Также колонки розничной цены и себестоимости клиент попросил добавить в печатную форму акта списания.

Пришлось запустить в режиме отладки, чтобы посмотреть, как формируется печатная форма:

Доработка происходит в процедуре УправлениеПечатью.ДанныеИсточников.

Тут разработчики 1С меня порадовали. Они наконец-то отделили код от содержимого и теперь данные в печать передают в виде соответствия соответствий. Туда можно добавить свои поля и все будет работать.

Открыл макет формы списания товаров:

Добавил туда свои поля:

Поля можно указать с требуемым форматированием:

[Формат([Запасы.дор_ЦенаРозничная], «ЧЦ=15; ЧДЦ=2»)]
[Формат([Запасы.дор_СуммаРозничная], «ЧЦ=15; ЧДЦ=2»)] [Формат([Запасы.дор_ЦенаСебестоимости], «ЧЦ=15; ЧДЦ=2»)] [Формат([Запасы.дор_СуммаСебестоимости], «ЧЦ=15; ЧДЦ=2»)]

При добавлении полей мы можем использовать уже ранее написанную функцию получения розничной цены и себестоимости. Получается такой элегантный код:


&Вместо("ДанныеИсточников")
Функция дор_ДанныеИсточников(Параметры)
	// Вставить содержимое метода.
	Результат = ПродолжитьВызов(Параметры);
	
	Для Каждого Ссылка Из Параметры.ИсточникиДанных Цикл
		Если ТипЗнч(Ссылка) = Тип("ДокументСсылка.СписаниеЗапасов") Тогда
			Строки = Результат[Ссылка]["Запасы"];
			
			ТЗ = дор_Сервер.ПолучитьРозничныеЦены(Ссылка.Запасы, Ссылка.Дата);
			Для Каждого Строка ИЗ ТЗ Цикл
				Цена = Строка.Значение;
				Соо = Строки[Строка.НомерСтроки];
				Соо.Вставить("дор_ЦенаСебестоимости", Цена);
				Соо.Вставить("дор_СуммаСебестоимости", Цена * Соо["Количество"]);
			КонецЦикла;

			ТЗ = дор_Сервер.ПолучитьСебестоимость(Ссылка.Запасы, Ссылка.Дата, Ссылка);
			Для Каждого Строка ИЗ ТЗ Цикл
				Цена = Строка.Значение;
				Соо = Строки[Строка.НомерСтроки];
				Соо.Вставить("дор_ЦенаРозничная", Цена);
				Соо.Вставить("дор_СуммаРозничная", Цена * Соо["Количество"]);
			КонецЦикла;

		КонецЕсли;
	КонецЦикла;

	Возврат Результат;
КонецФункции

Результат выглядит так:

Добавление колонки артикула в форму инвентаризации

Также клиент попросил вывести артикул в форму инвентаризации.

Тут совсем все просто, расширяем форму документа инвентаризации:


&НаСервере
Процедура дор_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка) 
	
	Привязка = Элементы.ЗапасыХарактеристика;
	
	Элемент = ЭтаФорма.Элементы.Вставить("дор_Артикул", Тип("ПолеФормы"), Привязка.Родитель, Привязка);
    Элемент.Вид = ВидПоляФормы.ПолеВвода;
    Элемент.ПутьКДанным = "Объект.Запасы.Номенклатура.Артикул";
	Элемент.Ширина = 12;
	Элемент.АвтоМаксимальнаяШирина = ложь;
	Элемент.РастягиватьПоГоризонтали = ложь;
	Элемент.ТолькоПросмотр = истина;

КонецПроцедуры

UPD: Добавление организации и итогов по документу

А вот потом клиенту понадобилось добавить организацию в шапку и итог по подвалу.

Анализ модуля УправлениеПечатью.ОбластиМакета показал, что 1С очень интересно определяет области, которые относятся к табличным частям — если в полях именованой области строки есть имена табличной части (например Запасы.Номенклатура), то считается, что эта область строк относится к этой табличной части. Расшифровка первой ячейки именованой области — это условие вывода области, может быть не заполнено.

А вот Организацию не удалось протащить, пришлось прописывать ее в коде.

В итоге макет стал выглядеть так:

В Условие_3 прописал такое же условие вывода как и в Условие_1.

Поля итогов прописал так:

[Формат([Количество], «ЧЦ=’15’; ЧДЦ=»»)]
[Формат([дор_СуммаСебестоимости], «ЧЦ=15; ЧДЦ=2»)]
[Формат([дор_СуммаРозничная], «ЧЦ=15; ЧДЦ=2»)]

При выводе на печать выглядит так:

В коде также добавил проверки типов, потому что этот код вызывается и при редактировании макета (т.к. там используется документ-образец), из-за ошибок заполнения макет не открывался на редактирование.

Код по выводу на печать стал таким:


&Вместо("ДанныеИсточников")
Функция дор_ДанныеИсточников(Параметры)
	// Вставить содержимое метода.
	Результат = ПродолжитьВызов(Параметры);
	
	
	Для Каждого Ссылка Из Параметры.ИсточникиДанных Цикл
		Если ТипЗнч(Ссылка) = Тип("ДокументСсылка.СписаниеЗапасов") Тогда

			Попытка      
				Результат[Ссылка].Вставить("Организация", Ссылка.Организация);
			Исключение
			КонецПопытки;
			
			Строки = Результат[Ссылка]["Запасы"];
			
			//Вызывается из макета
			Если Строки = Неопределено Тогда Продолжить; КонецЕсли; 
			
			ТЗ = дор_Сервер.ПолучитьСебестоимость(Ссылка.Запасы, Ссылка.Дата, Ссылка);
			Количество = 0;  
			дор_СуммаСебестоимости = 0;
			дор_СуммаРозничная = 0;
			Для Каждого Строка ИЗ ТЗ Цикл
				Цена = Строка.Значение;       
				Соо = Строки[Строка.НомерСтроки];           
				Если Соо["Количество"] = Неопределено Тогда
					Продолжить;
				КонецЕсли;
				Количество = Количество + Соо["Количество"]; 
				Соо.Вставить("дор_ЦенаСебестоимости", Цена);
				
				Соо.Вставить("дор_СуммаСебестоимости", Цена * Соо["Количество"]);				
				дор_СуммаСебестоимости = дор_СуммаСебестоимости + Соо["дор_СуммаСебестоимости"];
			КонецЦикла;

			ТЗ = дор_Сервер.ПолучитьРозничныеЦены(Ссылка.Запасы, Ссылка.Дата);
			Для Каждого Строка ИЗ ТЗ Цикл
				Цена = Строка.Значение;
				Соо = Строки[Строка.НомерСтроки];
				Если Соо["Количество"] = Неопределено Тогда
					Продолжить;
				КонецЕсли;
				Соо.Вставить("дор_ЦенаРозничная", Цена);
				Соо.Вставить("дор_СуммаРозничная", Цена * Соо["Количество"]);
				дор_СуммаРозничная = дор_СуммаРозничная + Соо["дор_СуммаРозничная"];
			КонецЦикла;
			
			Попытка      
				Результат[Ссылка].Вставить("Количество", Количество);
				Результат[Ссылка].Вставить("дор_СуммаСебестоимости", дор_СуммаСебестоимости);
				Результат[Ссылка].Вставить("дор_СуммаРозничная", дор_СуммаРозничная);
			Исключение
			КонецПопытки;
			
		КонецЕсли;
	КонецЦикла;

	Возврат Результат;
КонецФункции

Среда: Розница 3.0.5.145 Платформа: 8.3.23.1912 Объем: 2 час

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Читайте также:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *