вторник, 27 января 2015 г.

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

Условие задачи из сборника:

Товар на складе размещается в ячейках. При поступлении на склад каждый
товар помещается в отдельную ячейку, которая однозначно определяется своим
рядом и стеллажом. При продаже товара определяется способ отгрузки: сразу или
с доставкой. Если товар отгружается сразу, то чтобы быстрее осуществить
продажу в первую очередь должен отпускаться ближайший товар. Если же
производится доставка товара, то тогда должен списываться товар, до которого
неудобнее всего добираться.
Критерием удобства отгрузки (расстояние) служит сумма номера ряда и
номера стеллажа.
После проведения расходной накладной должна формироваться печатная
форма, в которой будет указано, из каких ячеек должен быть получен товар.


Решение задачи :

Изменим регистр "ОстаткиНоменклатуры":
Измерения:
Номенклатура
Ряд (число)
Стеллаж (число)
Ресурсы:
Количество:
Документ "Приходная накладная".
Так как учет себестоимости вести не нужно заменим рекизиты ТЧ "Цена" и "Сумма" на "ряд" и "стеллаж".
Потребуется незамысловатая обработка проведения с группировкой по номенклатуре, ряду и стеллажу на случай ввода дублей строк.


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


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

Переходим к "Расходной накладной".
Потребуется завести новое перечисление "СпособОтгрузки" с 2-мя значениями "Сразу" и "С доставкой". Реквизит этого типа добавим в документ РН. Так как для печатной формы потребуется цена и сумма, то реализуем пересчет ТЧ.

&НаКлиенте
Процедура СписокНоменклатурыКоличествоПриИзменении(Элемент)
Пересчет();
КонецПроцедуры
&НаКлиенте
Процедура СписокНоменклатурыЦенаПриИзменении(Элемент)
Пересчет()
КонецПроцедуры

&НаКлиенте
Процедура Пересчет()
ТекДанные = Элементы.СписокНоменклатуры.ТекущиеДанные;
ТекДанные.сумма = ТекДанные.Количество * ТекДанные.Цена;
КонецПроцедуры

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

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
СуммаПоДокументу = СписокНоменклатуры.Итог("сумма");
КонецПроцедуры

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


По условию задачи отчетов строить не требуется,но нужно при проведении вывести макет.
Так как макет вывести можно только на клиенте, то подходящим вариантом показался вызов из процедуры "после записи" с проверкой на проведенность документа
&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
Если Объект.Проведен Тогда
ТабДок =Новый("ТабличныйДокумент"); 
Печать(ТабДок) ;
ТабДок.ОтображатьСетку = Ложь;
ТабДок.Защита = Ложь;
ТабДок.ТолькоПросмотр = Ложь;
ТабДок.ОтображатьЗаголовки = Ложь;
ТабДок.Показать();
КонецЕсли;
КонецПроцедуры

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

&НаСервере
Процедура Печать(ТабДок);
Макет = Документы.РасходнаяНакладная.ПолучитьМакет("Макет");
ОбластьЗаголовок=Макет.ПолучитьОбласть("Заголовок");
ОбластьСтрока=Макет.ПолучитьОбласть("Строка");
ОбластьЗаголовок.Параметры.ссылка = "Расходная накладная № "+Объект.Номер +" от "+Формат(Объект.Дата,"ДФ=dd.MM.yyyy");
ТабДок.Вывести(ОбластьЗаголовок);
Запрос = Новый("Запрос");
Запрос.Текст ="ВЫБРАТЬ
| ОстаткиНоменклатуры.Регистратор,
| ОстаткиНоменклатуры.НомерСтроки,
| ОстаткиНоменклатуры.Стеллаж ,
| ОстаткиНоменклатуры.Ряд ,
| ОстаткиНоменклатуры.Количество,
| РасходнаяНакладнаяСписокНоменклатуры.Цена,
| ОстаткиНоменклатуры.Номенклатура как товар
|ИЗ
| РегистрНакопления.ОстаткиНоменклатуры КАК ОстаткиНоменклатуры
| ЛЕВОЕ СОЕДИНЕНИЕ Документ.РасходнаяНакладная.СписокНоменклатуры КАК РасходнаяНакладнаяСписокНоменклатуры
| ПО ОстаткиНоменклатуры.Номенклатура = РасходнаяНакладнаяСписокНоменклатуры.Номенклатура
|ГДЕ
| ОстаткиНоменклатуры.Регистратор = &Ссылка
| И РасходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка";
Запрос.Параметры.Вставить("Ссылка", Объект.Ссылка);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ОбластьСтрока.Параметры.Заполнить(Выборка);
ОбластьСтрока.Параметры.Сумма  = Выборка.Количество * Выборка.Цена;
ОбластьСтрока.Параметры.Стеллаж = "Ст №" + Выборка.стеллаж ;
ОбластьСтрока.Параметры.Ячейка = "Яч." + Выборка.стеллаж +"/"+ Выборка.Ряд;
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;

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




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

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