Условие из сборника:
Компания занимается оптовой торговлей. Поступление товаров отражается документом «Приходная накладная», продажа - «Расходная накладная». Продажа происходит с учетом единиц измерения, т.е. для каждой номенклатурной позиции может быть произвольное количество единиц измерения, например: штука; пачка из 10 штук; контейнер из 500 штук и т.д. Если в накладной будет указана продажа 3-х пачек, то должны быть списаны 30 штук. Кроме того, в расходной накладной могут также быть указаны услуги (например, доставка). И товары и услуги необходимо указывать в одной табличной части. Учет товаров ведется в разрезе складов. При проведении расходной накладной необходимо в первую очередь контролировать хватает ли товара вообще. Если нет – выдавать соответствующее предупреждение с указанием количества нехватки и не позволять проводить документ. Списание себестоимости товаров должно быть организовано только по складам, указанным для него в табличной части документа. Себестоимость товара рассчитывается как средняя по складу. Поступление товара происходит на один выбранный пользователем в документе «Приходная накладная» склад. Необходимо построить отчет по анализу продаж товаров за период. Прибыль рассчитывается:
Решение:
1) Ранее уже встречались задачи на тему единиц измерения. Реализуем тем же способом,через регистр сведений с измерениями "Номенклатура" и "Единица измерения". и ресурсом "количество".
Добавляем справочник "склады".
Потребуется 2 регистра "Остатки номенклатуры" и оборотный регистр "Продажи".
2) Переходим к приходной накладной. Добавляем в шапку "Склад" и плавно переходим к обработке проведения.
Процедура ОбработкаПроведения(Отказ, Режим)
Движения.ОстаткиНоменклатуры.Записывать = Истина;
Запрос = Новый("Запрос");
Запрос.Текст = "ВЫБРАТЬ
| КоэффициентыЕИ.ЕИ,
| ВЫБОР
| КОГДА КоэффициентыЕИ.Количество ЕСТЬ NULL
| ТОГДА ПриходнаяНакладнаяСписокНоменклатуры.Количество
| ИНАЧЕ ПриходнаяНакладнаяСписокНоменклатуры.Количество * КоэффициентыЕИ.Количество
| КОНЕЦ КАК Количество,
| ПриходнаяНакладнаяСписокНоменклатуры.Ссылка.Склад,
| ПриходнаяНакладнаяСписокНоменклатуры.Ссылка.Дата КАК Период,
| ПриходнаяНакладнаяСписокНоменклатуры.Сумма,
| ПриходнаяНакладнаяСписокНоменклатуры.Номенклатура
|ИЗ
| Документ.ПриходнаяНакладная.СписокНоменклатуры КАК ПриходнаяНакладнаяСписокНоменклатуры
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КоэффициентыЕИ КАК КоэффициентыЕИ
| ПО ПриходнаяНакладнаяСписокНоменклатуры.Номенклатура = КоэффициентыЕИ.Номенклатура
| И ПриходнаяНакладнаяСписокНоменклатуры.ЕдиницаИзмерения = КоэффициентыЕИ.ЕИ
|ГДЕ
| ПриходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка
| И ПриходнаяНакладнаяСписокНоменклатуры.Номенклатура.ТипТовара <> &ТипТовара";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Запрос.УстановитьПараметр("ТипТовара", Перечисления.ТипТовара.Услуга);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Движение = Движения.ОстаткиНоменклатуры.ДобавитьПриход();
ЗаполнитьЗначенияСвойств(Движение,Выборка);
КонецЦикла;
КонецПроцедуры
3) Плавно переходим к расходной накладной. Особенностью задачи является то, что склад является реквизитом табличной части.
Довольно странное требование вывести сообщение о нехватке итогового количества. Зачем??? ведь все- равно списываем с конкретного склада и себестоимость по рассчитываем по складу.
Но да ладно надо значит надо. Реализуем и это. Для этого необходимо будем таблицу документа связать с 2-мя виртуальными таблицами (по складу и по всем складам).
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
//1 Очистка движений
Движения.ОстаткиНоменклатуры.Записывать = Истина;
Движения.ОстаткиНоменклатуры.Очистить();
Движения.ОстаткиНоменклатуры.Записать();
Движения.Продажи.Записывать = Истина;
// Блокировка
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");
Блокировка.Заблокировать();
//Запрос
Запрос = Новый("Запрос");
Запрос.Текст = "ВЫБРАТЬ
| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура КАК Номенклатура,
| СУММА(ВЫБОР
| КОГДА КоэффициентыЕИ.Количество ЕСТЬ NULL
| ТОГДА РасходнаяНакладнаяСписокНоменклатуры.Количество
| ИНАЧЕ РасходнаяНакладнаяСписокНоменклатуры.Количество * КоэффициентыЕИ.Количество
| КОНЕЦ) КАК Количество,
| СУММА(РасходнаяНакладнаяСписокНоменклатуры.Сумма) КАК Сумма,
| РасходнаяНакладнаяСписокНоменклатуры.Склад
|ПОМЕСТИТЬ ДокТЧ
|ИЗ
| Документ.РасходнаяНакладная.СписокНоменклатуры КАК РасходнаяНакладнаяСписокНоменклатуры
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КоэффициентыЕИ КАК КоэффициентыЕИ
| ПО РасходнаяНакладнаяСписокНоменклатуры.Номенклатура = КоэффициентыЕИ.Номенклатура
| И РасходнаяНакладнаяСписокНоменклатуры.ЕдиницаИзмерения = КоэффициентыЕИ.ЕИ
|ГДЕ
| РасходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка
| И РасходнаяНакладнаяСписокНоменклатуры.Номенклатура.ТипТовара <> &ТипТовара
|
|СГРУППИРОВАТЬ ПО
| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура,
| РасходнаяНакладнаяСписокНоменклатуры.Склад
|
|ИНДЕКСИРОВАТЬ ПО
| Номенклатура
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ДокТЧ.Номенклатура КАК Номенклатура,
| ДокТЧ.Количество КАК КолДок,
| ДокТЧ.Сумма КАК СумДок,
| ЕСТЬNULL(ОстаткиСклад.КоличествоОстаток, 0) КАК КолСклад,
| ЕСТЬNULL(ОстаткиСклад.СуммаОстаток, 0) КАК СумСклад,
| ЕСТЬNULL(ОстаткиВсего.КоличествоОстаток, 0) КАК ВсегоКол,
| ДокТЧ.Склад
|ИЗ
| ДокТЧ КАК ДокТЧ
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(
| &ТочкаИтогов,
| (Номенклатура, Склад) В
| (ВЫБРАТЬ
| ДокТЧ.Номенклатура,
| ДокТЧ.Склад
| ИЗ
| ДокТЧ КАК ДокТЧ)) КАК ОстаткиСклад
| ПО ДокТЧ.Склад = ОстаткиСклад.Склад
| И ДокТЧ.Номенклатура = ОстаткиСклад.Номенклатура
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(
| &ТочкаИтогов,
| Номенклатура В
| (ВЫБРАТЬ
| ДокТЧ.Номенклатура
| ИЗ
| ДокТЧ)) КАК ОстаткиВсего
| ПО ДокТЧ.Номенклатура = ОстаткиВсего.Номенклатура";
Запрос.УстановитьПараметр("Ссылка",Ссылка);
Запрос.УстановитьПараметр("ТипТовара",Перечисления.ТипТовара.Услуга);
Если РежимПроведения = РежимПроведенияДокумента.Оперативный Тогда
ТочкаИтогов=Неопределено;
Иначе
ТочкаИтогов = Новый Граница(МоментВремени(),ВидГраницы.Исключая);
КонецЕсли;
Запрос.УстановитьПараметр("ТочкаИтогов", ТочкаИтогов);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если Выборка.ВсегоКол < Выборка.КолДок Тогда
Отказ = Истина;
Сообщение = Новый("СообщениеПользователю");
Сообщение.Текст ="Недостаточно товара по всем складам "+ Выборка.Номенклатура +" надо еще " +(Выборка.КолДок - Выборка.ВсегоКол);
Сообщение.Сообщить();
Продолжить;
Иначе
Если Выборка.КолСклад < Выборка.КолДок Тогда
Отказ = Истина;
Сообщение = Новый("СообщениеПользователю");
Сообщение.Текст ="Недостаточно товара на выбранном складе"+ Выборка.Номенклатура +" надо еще " +(Выборка.КолДок - Выборка.КолСклад);
Сообщение.Сообщить();
Иначе
Движение = Движения.ОстаткиНоменклатуры.ДобавитьРасход();
Движение.Период = Дата;
Движение.Номенклатура =Выборка.Номенклатура ;
Движение.Склад = Выборка.Склад;
Движение.Количество = Выборка.КолДок;
Если Выборка.КолСклад <> 0 Тогда
Себестоимость= Выборка.КолДок * Выборка.СумСклад/Выборка.КолСклад;
Иначе
Себестоимость =0;
КонецЕсли;
Движение.Сумма = Себестоимость;
// продажи
Движение = Движения.Продажи.Добавить();
Движение.Период = Дата;
Движение.Номенклатура =Выборка.Номенклатура ;
Движение.Количество = Выборка.КолДок;
Движение.Себестоимость = Себестоимость;
Движение.СуммаПродажи = Выборка.СумДок;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
4) Делаем отчет. Он аналогичен отчету из задачи 1.21.
Скачать решение задачи 1.23
Компания занимается оптовой торговлей. Поступление товаров отражается документом «Приходная накладная», продажа - «Расходная накладная». Продажа происходит с учетом единиц измерения, т.е. для каждой номенклатурной позиции может быть произвольное количество единиц измерения, например: штука; пачка из 10 штук; контейнер из 500 штук и т.д. Если в накладной будет указана продажа 3-х пачек, то должны быть списаны 30 штук. Кроме того, в расходной накладной могут также быть указаны услуги (например, доставка). И товары и услуги необходимо указывать в одной табличной части. Учет товаров ведется в разрезе складов. При проведении расходной накладной необходимо в первую очередь контролировать хватает ли товара вообще. Если нет – выдавать соответствующее предупреждение с указанием количества нехватки и не позволять проводить документ. Списание себестоимости товаров должно быть организовано только по складам, указанным для него в табличной части документа. Себестоимость товара рассчитывается как средняя по складу. Поступление товара происходит на один выбранный пользователем в документе «Приходная накладная» склад. Необходимо построить отчет по анализу продаж товаров за период. Прибыль рассчитывается:
1) Ранее уже встречались задачи на тему единиц измерения. Реализуем тем же способом,через регистр сведений с измерениями "Номенклатура" и "Единица измерения". и ресурсом "количество".
Добавляем справочник "склады".
Потребуется 2 регистра "Остатки номенклатуры" и оборотный регистр "Продажи".
2) Переходим к приходной накладной. Добавляем в шапку "Склад" и плавно переходим к обработке проведения.
Процедура ОбработкаПроведения(Отказ, Режим)
Движения.ОстаткиНоменклатуры.Записывать = Истина;
Запрос = Новый("Запрос");
Запрос.Текст = "ВЫБРАТЬ
| КоэффициентыЕИ.ЕИ,
| ВЫБОР
| КОГДА КоэффициентыЕИ.Количество ЕСТЬ NULL
| ТОГДА ПриходнаяНакладнаяСписокНоменклатуры.Количество
| ИНАЧЕ ПриходнаяНакладнаяСписокНоменклатуры.Количество * КоэффициентыЕИ.Количество
| КОНЕЦ КАК Количество,
| ПриходнаяНакладнаяСписокНоменклатуры.Ссылка.Склад,
| ПриходнаяНакладнаяСписокНоменклатуры.Ссылка.Дата КАК Период,
| ПриходнаяНакладнаяСписокНоменклатуры.Сумма,
| ПриходнаяНакладнаяСписокНоменклатуры.Номенклатура
|ИЗ
| Документ.ПриходнаяНакладная.СписокНоменклатуры КАК ПриходнаяНакладнаяСписокНоменклатуры
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КоэффициентыЕИ КАК КоэффициентыЕИ
| ПО ПриходнаяНакладнаяСписокНоменклатуры.Номенклатура = КоэффициентыЕИ.Номенклатура
| И ПриходнаяНакладнаяСписокНоменклатуры.ЕдиницаИзмерения = КоэффициентыЕИ.ЕИ
|ГДЕ
| ПриходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка
| И ПриходнаяНакладнаяСписокНоменклатуры.Номенклатура.ТипТовара <> &ТипТовара";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Запрос.УстановитьПараметр("ТипТовара", Перечисления.ТипТовара.Услуга);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Движение = Движения.ОстаткиНоменклатуры.ДобавитьПриход();
ЗаполнитьЗначенияСвойств(Движение,Выборка);
КонецЦикла;
КонецПроцедуры
Довольно странное требование вывести сообщение о нехватке итогового количества. Зачем??? ведь все- равно списываем с конкретного склада и себестоимость по рассчитываем по складу.
Но да ладно надо значит надо. Реализуем и это. Для этого необходимо будем таблицу документа связать с 2-мя виртуальными таблицами (по складу и по всем складам).
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
//1 Очистка движений
Движения.ОстаткиНоменклатуры.Записывать = Истина;
Движения.ОстаткиНоменклатуры.Очистить();
Движения.ОстаткиНоменклатуры.Записать();
Движения.Продажи.Записывать = Истина;
// Блокировка
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");
Блокировка.Заблокировать();
//Запрос
Запрос = Новый("Запрос");
Запрос.Текст = "ВЫБРАТЬ
| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура КАК Номенклатура,
| СУММА(ВЫБОР
| КОГДА КоэффициентыЕИ.Количество ЕСТЬ NULL
| ТОГДА РасходнаяНакладнаяСписокНоменклатуры.Количество
| ИНАЧЕ РасходнаяНакладнаяСписокНоменклатуры.Количество * КоэффициентыЕИ.Количество
| КОНЕЦ) КАК Количество,
| СУММА(РасходнаяНакладнаяСписокНоменклатуры.Сумма) КАК Сумма,
| РасходнаяНакладнаяСписокНоменклатуры.Склад
|ПОМЕСТИТЬ ДокТЧ
|ИЗ
| Документ.РасходнаяНакладная.СписокНоменклатуры КАК РасходнаяНакладнаяСписокНоменклатуры
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КоэффициентыЕИ КАК КоэффициентыЕИ
| ПО РасходнаяНакладнаяСписокНоменклатуры.Номенклатура = КоэффициентыЕИ.Номенклатура
| И РасходнаяНакладнаяСписокНоменклатуры.ЕдиницаИзмерения = КоэффициентыЕИ.ЕИ
|ГДЕ
| РасходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка
| И РасходнаяНакладнаяСписокНоменклатуры.Номенклатура.ТипТовара <> &ТипТовара
|
|СГРУППИРОВАТЬ ПО
| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура,
| РасходнаяНакладнаяСписокНоменклатуры.Склад
|
|ИНДЕКСИРОВАТЬ ПО
| Номенклатура
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ДокТЧ.Номенклатура КАК Номенклатура,
| ДокТЧ.Количество КАК КолДок,
| ДокТЧ.Сумма КАК СумДок,
| ЕСТЬNULL(ОстаткиСклад.КоличествоОстаток, 0) КАК КолСклад,
| ЕСТЬNULL(ОстаткиСклад.СуммаОстаток, 0) КАК СумСклад,
| ЕСТЬNULL(ОстаткиВсего.КоличествоОстаток, 0) КАК ВсегоКол,
| ДокТЧ.Склад
|ИЗ
| ДокТЧ КАК ДокТЧ
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(
| &ТочкаИтогов,
| (Номенклатура, Склад) В
| (ВЫБРАТЬ
| ДокТЧ.Номенклатура,
| ДокТЧ.Склад
| ИЗ
| ДокТЧ КАК ДокТЧ)) КАК ОстаткиСклад
| ПО ДокТЧ.Склад = ОстаткиСклад.Склад
| И ДокТЧ.Номенклатура = ОстаткиСклад.Номенклатура
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(
| &ТочкаИтогов,
| Номенклатура В
| (ВЫБРАТЬ
| ДокТЧ.Номенклатура
| ИЗ
| ДокТЧ)) КАК ОстаткиВсего
| ПО ДокТЧ.Номенклатура = ОстаткиВсего.Номенклатура";
Запрос.УстановитьПараметр("Ссылка",Ссылка);
Запрос.УстановитьПараметр("ТипТовара",Перечисления.ТипТовара.Услуга);
Если РежимПроведения = РежимПроведенияДокумента.Оперативный Тогда
ТочкаИтогов=Неопределено;
Иначе
ТочкаИтогов = Новый Граница(МоментВремени(),ВидГраницы.Исключая);
КонецЕсли;
Запрос.УстановитьПараметр("ТочкаИтогов", ТочкаИтогов);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если Выборка.ВсегоКол < Выборка.КолДок Тогда
Отказ = Истина;
Сообщение = Новый("СообщениеПользователю");
Сообщение.Текст ="Недостаточно товара по всем складам "+ Выборка.Номенклатура +" надо еще " +(Выборка.КолДок - Выборка.ВсегоКол);
Сообщение.Сообщить();
Продолжить;
Иначе
Если Выборка.КолСклад < Выборка.КолДок Тогда
Отказ = Истина;
Сообщение = Новый("СообщениеПользователю");
Сообщение.Текст ="Недостаточно товара на выбранном складе"+ Выборка.Номенклатура +" надо еще " +(Выборка.КолДок - Выборка.КолСклад);
Сообщение.Сообщить();
Иначе
Движение = Движения.ОстаткиНоменклатуры.ДобавитьРасход();
Движение.Период = Дата;
Движение.Номенклатура =Выборка.Номенклатура ;
Движение.Склад = Выборка.Склад;
Движение.Количество = Выборка.КолДок;
Если Выборка.КолСклад <> 0 Тогда
Себестоимость= Выборка.КолДок * Выборка.СумСклад/Выборка.КолСклад;
Иначе
Себестоимость =0;
КонецЕсли;
Движение.Сумма = Себестоимость;
// продажи
Движение = Движения.Продажи.Добавить();
Движение.Период = Дата;
Движение.Номенклатура =Выборка.Номенклатура ;
Движение.Количество = Выборка.КолДок;
Движение.Себестоимость = Себестоимость;
Движение.СуммаПродажи = Выборка.СумДок;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
4) Делаем отчет. Он аналогичен отчету из задачи 1.21.
Скачать решение задачи 1.23
Комментариев нет:
Отправить комментарий