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