понедельник, 2 марта 2015 г.

1c специалист задача 1.23

Условие из сборника:
Компания занимается оптовой торговлей. Поступление товаров отражается документом «Приходная накладная», продажа - «Расходная накладная». Продажа происходит с учетом единиц измерения, т.е. для каждой номенклатурной позиции может быть произвольное количество единиц измерения, например: штука; пачка из 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

Комментариев нет:

Отправить комментарий