Автоматизация заполнения документа "Возврат товаров от покупателя" в УТ 10.3

31.08.16

Задачи пользователя - Адаптация типовых решений

Изменение логики заполнения документа "ВозвратТовароОтПокупателя" на основании документа "РеализацияТоваровУслуг".

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

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

		СтрокаТабличнойЧасти.Номенклатура                        = Выборка.Номенклатура;
		СтрокаТабличнойЧасти.Количество                          = кДобавляемых;
		СтрокаТабличнойЧасти.ЕдиницаИзмерения                    = Выборка.ЕдиницаИзмерения;
		СтрокаТабличнойЧасти.ЕдиницаИзмеренияМест                = Выборка.ЕдиницаИзмеренияМест;
		СтрокаТабличнойЧасти.Коэффициент                         = Выборка.Коэффициент;
		СтрокаТабличнойЧасти.СтавкаНДС                           = Выборка.СтавкаНДС;
		СтрокаТабличнойЧасти.ПроцентСкидкиНаценки                = Выборка.ПроцентСкидкиНаценки;
		СтрокаТабличнойЧасти.ПроцентАвтоматическихСкидок         = Выборка.ПроцентАвтоматическихСкидок;
		СтрокаТабличнойЧасти.УсловиеАвтоматическойСкидки         = Выборка.УсловиеАвтоматическойСкидки;
		СтрокаТабличнойЧасти.ЗначениеУсловияАвтоматическойСкидки = Выборка.ЗначениеУсловияАвтоматическойСкидки;
		СтрокаТабличнойЧасти.Качество                            = Выборка.Качество;
		СтрокаТабличнойЧасти.Склад                               = Выборка.Склад;
		СтрокаТабличнойЧасти.Цена                                = Выборка.Цена;
        Если ТипДокументаОснования = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
        	СтрокаТабличнойЧасти.ЗаказПокупателя 	  = ДокументОснование;
		Иначе
            СтрокаТабличнойЧасти.ЗаказПокупателя 	  = Выборка.ЗаказПокупателя;
		КонецЕсли;

		Если ОтКомиссионера Тогда
			
			КолвоПереданных = ?(Выборка.КоличествоОстатокПереданных = NULL, 0, Выборка.КоличествоОстатокПереданных);
			Если КолвоПереданных>0 Тогда
				Сумма = МодульВалютногоУчета.ПересчитатьИзВалютыВВалюту(Выборка.СтоимостьОтданнаяВалОстаток * СтрокаТабличнойЧасти.Количество / КолвоПереданных, 
				                   ДоговорКонтрагента.ВалютаВзаиморасчетов, ВалютаДокумента, КурсВзаиморасчетов, мКурсДокумента,
				                   КратностьВзаиморасчетов, мКратностьДокумента);

				СтрокаТабличнойЧасти.Сумма = Ценообразование.ПересчитатьЦенуПриИзмененииФлаговНалогов(Сумма, 
				                                              Перечисления.СпособыЗаполненияЦен.ПоЦенамНоменклатуры, 
				                                              Истина, УчитыватьНДС, СуммаВключаетНДС, 
				                                              УчетНДС.ПолучитьСтавкуНДС(СтрокаТабличнойЧасти.СтавкаНДС));
				ОбработкаТабличныхЧастей.ПриИзмененииСуммыТабЧасти(СтрокаТабличнойЧасти, ЭтотОбъект, ТекПользователь,,
				                                              ЕстьРеквизитПроцентСкидкиНаценки,ПересчитыватьСкидку,
				                                              ЕстьАвтоматическиеСкидки,"Товары");
			КонецЕсли;
		Иначе

			СтрокаТабличнойЧасти.Цена = Выборка.Цена;

			// Пересчитаем цену в валюту документа (может отличаться от валюты основания).
			Цена = МодульВалютногоУчета.ПересчитатьИзВалютыВВалюту(СтрокаТабличнойЧасти.Цена, Выборка.ВалютаДокумента, ВалютаДокумента, 
			                                                   Выборка.КурсДокумента, мКурсДокумента,
			                                                   Выборка.КратностьДокумента, мКратностьДокумента);

			СтрокаТабличнойЧасти.Цена = Ценообразование.ПересчитатьЦенуПриИзмененииФлаговНалогов(Цена,
										Перечисления.СпособыЗаполненияЦен.ПоЦенамНоменклатуры,
										Выборка.УчитыватьНДС И Выборка.СуммаВключаетНДС,
										УчитыватьНДС, СуммаВключаетНДС,
										УчетНДС.ПолучитьСтавкуНДС(СтрокаТабличнойЧасти.СтавкаНДС));

			ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(СтрокаТабличнойЧасти, ЭтотОбъект);

		КонецЕсли;

		ОбработкаТабличныхЧастей.РассчитатьКоличествоМестТабЧасти(СтрокаТабличнойЧасти, ЭтотОбъект);
		ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(СтрокаТабличнойЧасти, ЭтотОбъект);

		СтрокаТабличнойЧасти.ХарактеристикаНоменклатуры = Выборка.ХарактеристикаНоменклатуры;

		ОбработкаТабличныхЧастей.ЗаполнитьСкладИОрдерТабЧасти(СтрокаТабличнойЧасти, ЭтотОбъект);
		
		Если ОснованиеРеализацияТоваров Тогда

			СтрокаТабличнойЧасти.СерияНоменклатуры      = Выборка.СерияНоменклатуры;
			СтрокаТабличнойЧасти.ДокументПартии         = ДокументОснование;
			СтрокаТабличнойЧасти.ЗаказПокупателя        = Выборка.ЗаказПокупателя;

		КонецЕсли;

		Если ЕстьСоставНабора
		   И Выборка.Комплект Тогда
			СтрокаТабличнойЧасти.КлючСтроки = СтрокаТабличнойЧасти.НомерСтроки;
		КонецЕсли;
	КонецЕсли;
	КонецЦикла;
...

После чего логика заполнения документа ВозвратТоваровОтПокупателя изменилась в лучшую сторону. А именно:

На основании реализации может быть введено несколько возвратов. Логика доработки предусматривает этот вариант и добавляет только те позиции, которые не были возвращены ранее.

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

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

	КонецЕсли;
...

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

обработка заполнения

См. также

Табличная часть в доп. реквизитах и формирование таблиц в шаблоне docx для 1С:ДО 3.0

Адаптация типовых решений Платформа 1С v8.3 1С:Документооборот Россия Платные (руб)

Расширение конфигурации для «1С:Документооборот КОРП», редакция 3.0. позволяет: 1.использовать произвольные табличные части в качестве дополнительных реквизитов к документу; 2 использовать произвольные табличные части в шаблонах в формате docx для автоматического заполнения таблиц.

29400 руб.

29.06.2023    4453    9    4    

18

Расширение для 1С:УНФ. Автоматическое снятие резервов в Заказах покупателей

Логистика, склад и ТМЦ Адаптация типовых решений Платформа 1С v8.3 1С:Управление нашей фирмой 1.6 1С:Управление нашей фирмой 3.0 Россия Управленческий учет Платные (руб)

Чтобы не допустить путаницы с обещаниями клиентам и для четкого контроля исполнения заказов мы используем резервирование товаров. Мы доработали УНФ, чтобы она автоматически отменяла старые резервы и не мешала эффективно продавать.

7200 руб.

02.08.2023    2956    4    0    

19

Создать на основании - своя кнопка (БСП). Проблема двух подменю Создать на основании

БСП (Библиотека стандартных подсистем) Адаптация типовых решений Платформа 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

Понадобилось в подменю "Создать на основании" добавить свою команду, которая открывает обработку. В процессе доработок появилась проблема двух подменю "Создать на основании". В статье о том, как решились проблемы.

01.03.2024    1283    dimanich70    6    

13

Доработка отчета "Связанные документы" (структура подчиненности) для вывода объектов из любого расширения

Адаптация типовых решений Платформа 1С v8.3 1С:Управление торговлей 11 Россия Абонемент ($m)

Доработка типового отчета "Связанные документы" позволяет просто и быстро расширять состав объектов для построения структуры подчиненности документов, используя объекты основной конфигурации и любых расширений.

1 стартмани

27.10.2023    1996    13    avmartynov    10    

43

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2072    21    progmaster    7    

3
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Re:аниматор 338 01.09.16 07:19 Сейчас в теме
Ни чего не запрещает продавцу добавить товар через подбор и указать любое кол-во.
У себя решил эту проблему через контроль возвращаемого товара при проведении документа по регистру накопления "Продажи".
Как известно при проведении возврата кол-во продажи уменьшается.

часть кода

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

Показать
splitter01; +1 Ответить
2. splitter01 3 01.09.16 15:18 Сейчас в теме
(1) Re:аниматор, Верное замечание. На данный момент проблема уже устранена. Но в Вашем предложении не учитываются ранее возвращенные товары. В ближайшее время исправлю публикацию. И еще: в Вашем варианте рассмотрите ситуацию, когда было продано 2 холодильника и 1 пылесос, а в документе возврата указать 2 пылесоса и 1 холодильник.
3. Re:аниматор 338 06.09.16 07:19 Сейчас в теме
(2)
Но в Вашем предложении не учитываются ранее возвращенные товары.


Вообще то учитываются ранее возвращенные товары. Возврат делает записи в регистр "Продажи" со знаком "-", СУММА(ПродажиОбороты.КоличествоОборот) это учтется в суммировании


И еще: в Вашем варианте рассмотрите ситуацию, когда было продано 2 холодильника и 1 пылесос, а в документе возврата указать 2 пылесоса и 1 холодильник.


Разрешит сделать возврат только на 1 холоднильник, т.к. пылесоса продано 1

А для чего рассмотреть данную ситуацию?
4. V.Nikonov 120 09.09.16 19:49 Сейчас в теме
В некоторых конторах, осуществляющих регулярные продажи однотипных товаров, фактически покупатель возвращает товар из неизвестной поставки. Однако для взаиморасчетов действует правило - цена возврата по последней отгрузке (не текущие продажные цены и не Закупочные).
При первичном заполнении документа возврата обычно используется Подбор по справочнику, при этом не заполняются данные по Себестоимости...
Добавил обработку Табличных частей, которая анализировала продажи (с учетом проведенных возвратов) за период (например, 3 мес.). При необходимости разбивала строку на несколько строк под каждую отгрузку (Учет по Заказам и Заказ=Реализация). При необходимости снимались ограничения по Договорам и добавлялся период анализа. Найденные отгрузки использовались как ПартиеОбразующие документы, использовались для определения Цены возвращаемого товара и становилось видны попытки вернуть "НеОтгруженный товар". Возможно отгружались двойники номенклатуры...
Для строк под которые не нашлось отгрузок, подставлялась Плановая себестоимость (Закупочная цена).
Обработка позволяла при необходимости повторить распределение по отгрузкам,предварительно свернув строки по Номенклатуре (очистив документы партий). Дополнительно Обработка печатала отчет по сформированному распределению (практиковалась корректировка "свежих Реализаций").
Кстати, добавил проверку перед записью: наличие нужного товара в заявленных документах партий...
5. white-mount 10.09.16 14:44 Сейчас в теме
Возвратом товаров обычно занимается не продавец, а менеджер, имеющий выше полномочия. Это всегда чп. Либо дефект, либо пересортица - продано не то. Для маленькой фирмы предложенный механизм подходит, для крупной нет.
Оставьте свое сообщение