10.12.2015

Задача 1.41

Компания занимается оптовой торговлей с иностранными контрагентами. Закупка и продажа товаров может происходить в любой валюте. Поступление товаров отражается документом «Приходная накладная», продажа - «Расходная накладная». Валюта указывается для каждого документа поступления и продажи (валюта реквизит шапки).
При продаже товаров себестоимость рассчитывается как средняя по валюте, причем валюта продажи и валюта себестоимости могут не совпадать. Например, если купили товар за доллары, то продавать его можно за евро. Порядок списания по валютам остается на усмотрение разработчика.
Учет товаров в разрезе складов не ведется.
Необходимо создать отчет по продажам товаров за период, в котором будет отражаться прибыль для каждого товара в валюте закупки и в рублях. Например, куплена 1 шт за 100 евро при курсе 35. Продана была за 250 Долларов при курсе 25 за доллар и 36 за евро. Прибыль рассчитывается как сумма продажи минус себестоимость и составит 250*25 – 100*35 = 2750 руб и 250*25/36-100 = 73,61 евро

table.PNG
Рассмотрим решение данной задачи.




Изменяем документы:

doc.PNG

Далее редактируем регистр "Остаки номенклатуры" и добавляем регистр "Продажи" с видом "Обороты"

reg.PNG

Опишем обработку проведения документа "Приходная"

  

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




Далее - самое главное в данной задаче опишем механизм проведения расходной накладной.

  

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






И в завершении отчет, который выводит содержимое регистра продажи:


  
ВЫБРАТЬ
	ПродажиОбороты.ВалютаПокупки КАК Валюта,
	ПродажиОбороты.Номенклатура,
	ПродажиОбороты.КоличествоОборот КАК Количество,
	ПродажиОбороты.СебестоимостьОборот КАК Себестоимость,
	ПродажиОбороты.ПрибыльВалОборот КАК ПрибыльВал,
	ПродажиОбороты.ПрибыльРубОборот КАК ПрибыльРуб
ИЗ
	РегистрНакопления.Продажи.Обороты КАК ПродажиОбороты



На этом все. Будут вопросы, пожелания - пишите в комментариях.
До скорых встреч в следующих уроках.

Возврат к списку

  • Facebook
  • Вконтакте