|
Контроль отрицательных остатков (номенклатура с аналогами) | ☑ | ||
---|---|---|---|---|
0
rooffy
19.06.18
✎
16:04
|
Доброго дня.
Делаю тестовое задание, столкнулся с проблемой. Условия примерно такие: номенклатура ведется с аналогами, при нехватке основной номенклатуры списываются аналоги начиная с самого дешевого. Партионный учет по ФИФО. Сделал через 2 запроса, понимаю, что неоптимально, но в один не смог сделать. В первом запросе по максимуму списывается основная номенклатура по партиям, во втором аналоги, отсортированные по цене. Так вот, если в расходной накладной например 2 номенклатуры с одним аналогом, то при попытке списать вторую остатки показывает те же, что и на начало списание первой, в результате списывается в минус. Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | РасходнаяНакладнаяСписокНоменклатуры.Номенклатура КАК Номенклатура, | СУММА(РасходнаяНакладнаяСписокНоменклатуры.Количество) КАК Количество, | СУММА(РасходнаяНакладнаяСписокНоменклатуры.Сумма) КАК Сумма |ПОМЕСТИТЬ ВремТаб |ИЗ | Документ.РасходнаяНакладная.СписокНоменклатуры КАК РасходнаяНакладнаяСписокНоменклатуры |ГДЕ | РасходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка | |СГРУППИРОВАТЬ ПО | РасходнаяНакладнаяСписокНоменклатуры.Номенклатура | |ИНДЕКСИРОВАТЬ ПО | Номенклатура |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | ВремТаб.Номенклатура КАК Номенклатура, | ВремТаб.Количество КАК КоличествоВДокументе, | ВремТаб.Сумма КАК СуммаВДокументе, | ОстаткиНоменклатурыОстатки.Партия, | ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток, | ЕСТЬNULL(ОстаткиНоменклатурыОстатки.СуммаОстаток, 0) КАК СуммаОстаток |ИЗ | ВремТаб КАК ВремТаб | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки( | &МоментВремени, | Номенклатура В | (ВЫБРАТЬ | ВремТаб.Номенклатура | ИЗ | ВремТаб КАК ВремТаб)) КАК ОстаткиНоменклатурыОстатки | ПО ВремТаб.Номенклатура = ОстаткиНоменклатурыОстатки.Номенклатура | |УПОРЯДОЧИТЬ ПО | ОстаткиНоменклатурыОстатки.Партия.МоментВремени ВОЗР |ИТОГИ | МАКСИМУМ(КоличествоВДокументе), | МАКСИМУМ(СуммаВДокументе), | СУММА(КоличествоОстаток), | СУММА(СуммаОстаток) |ПО | Номенклатура"; Запрос.УстановитьПараметр("МоментВремени", Новый Граница(МоментВремени(),ВидГраницы.Исключая )); Запрос.УстановитьПараметр("Ссылка",Ссылка); ВыборкаНоменклатура = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам); Пока ВыборкаНоменклатура.Следующий() Цикл ОсталосьСписать = ВыборкаНоменклатура.КоличествоВДокументе; ВыборкаДетЗаписи = ВыборкаНоменклатура.Выбрать(); Пока ВыборкаДетЗаписи.Следующий() И ОсталосьСписать <> 0 Цикл Если ВыборкаДетЗаписи.КоличествоОстаток > 0 Тогда //Движения по регистрам Продажи и Остатки ОсталосьСписать = ОсталосьСписать - КСписанию; КонецЕсли; Номенклатура = ВыборкаДетЗаписи.Номенклатура; СуммаВДокументе = ВыборкаДетЗаписи.СуммаВДокументе; КонецЦикла; Если ОсталосьСписать>0 Тогда Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Аналоги.Аналог КАК Номенклатура, | ОстаткиНоменклатурыОстатки.Партия, | ОстаткиНоменклатурыОстатки.СуммаОстаток / ОстаткиНоменклатурыОстатки.КоличествоОстаток КАК Цена, | ОстаткиНоменклатурыОстатки.КоличествоОстаток, | ОстаткиНоменклатурыОстатки.СуммаОстаток |ИЗ | РегистрСведений.Аналоги КАК Аналоги | ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(&МоментВремени) КАК ОстаткиНоменклатурыОстатки | ПО Аналоги.Аналог = ОстаткиНоменклатурыОстатки.Номенклатура |ГДЕ | Аналоги.Номенклатура = &Номенклатура | И ОстаткиНоменклатурыОстатки.Склад = &Склад | |УПОРЯДОЧИТЬ ПО | Цена"; Запрос.УстановитьПараметр("Склад",Склад); Запрос.УстановитьПараметр("Номенклатура",Номенклатура); Запрос.УстановитьПараметр("МоментВремени",Новый Граница(МоментВремени(),ВидГраницы.Исключая)); ВыборкаАналоги = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам); ВыборкаАналогиТаб = Запрос.Выполнить().Выгрузить(); Пока ВыборкаАналоги.Следующий() И ОсталосьСписать <> 0 Цикл Если ВыборкаАналоги.КоличествоОстаток > 0 Тогда //Движения по регистрам Продажи и Остатки ОсталосьСписать = ОсталосьСписать - КСписанию; КонецЕсли; КонецЦикла; Если ОсталосьСписать>0 Тогда Отказ = Истина; КонецЕсли; |
|||
1
DrShad
19.06.18
✎
16:14
|
запрос в цикле это мощно
погугли ФИФО в запросе |
|||
2
FIXXXL
19.06.18
✎
16:16
|
запрос в цикле, да еще и количество неправильно...
сделай хотя бы пакетный из основного состава плюс остатки аналогов остатки аналогов выгрузи в ТЗ, добавь поле ТекущийОстаток, в который пиши остаток после "проходов", ну и юзай эту ТЗ, а не запрос в цикле, всё нагрузка меньше ну или почитай про новый подход, когда движения пишутся, а потом читаются расхождения вот эти расхождения вторым запросом прогоняй таким же образом через аналоги |
|||
3
FIXXXL
19.06.18
✎
16:22
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |