Задача:
Документ ПоступлениеТоваров при проведении делает движения по 2 регистрам:
- приход по регистру накопления ТоварыНаСкладах
- расход по регистру накопления ЗаказыПоставщикам
Запись в регистр накопления ТоварыНаСкладах делается в рублях (Сумма) и в долларах (СуммаВал). Курс берется на дату партии.
Документ может содержать в табличной части Товары тысячи строк с различными партиями.
Ниже представлена обработка проведения документа ПоступлениеТоваров.
Необходимо указать на ошибки и неоптимальные решения в процедуре проведения.
ВНИМАНИЕ, ТУТ ЗАЛОЖЕНО БОЛЕЕ 20 ОШИБОК И НЕОПТИМАЛЬНЫХ РЕШЕНИЙ, необходимо найти минимум 15.
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Товары.Номенклатура КАК Номенклатура,
| Товары.Партия КАК Партия,
| Товары.Количество КАК Количество,
| Товары.Сумма КАК Сумма,
| Заказы.КоличествоОстаток КАК КоличествоОстаток
|ИЗ
| Документ.ПоступлениеТоваров.Товары КАК Товары
|ЛЕВОЕ СОЕДИНЕНИЕ
|РегистрНакопления.ЗаказыПоставщикам.Остатки(&Период, Контрагент = &Контрагент) КАК Заказы
| ПО Товары.Номенклатура = Заказы.Номенклатура
| И Товары.Партия = Заказы.Партия
|ГДЕ
| Товары.Ссылка = &Ссылка
| И (Заказы.Номенклатура, Заказы.Партия) В
| (ВЫБРАТЬ
| Товары.Номенклатура,
| Товары.Партия
| ИЗ
| Документ. ПоступлениеТоваров.Товары КАК Товары
| ГДЕ
| Товары.Ссылка = &Ссылка)
|ИТОГИ
| СУММА(Количество),
| СУММА(Сумма),
| СУММА(КоличествоОстаток)
|ПО
| Номенклатура,
| Партия";
ВыборкаНоменклатура = Запрос.Выполнить().Выбрать();
Пока ВыборкаНоменклатура.Следующий() Цикл
Если ВыборкаНоменклатура.Количество > ВыборкаНоменклатура.КоличествоОстаток Тогда
Сообщить("Количество в поступлении "
+ВыборкаНоменклатура.Количество
+ " " + ВыборкаНоменклатура.Номенклатура.ЕдиницаИзмерения
+ " превышает остаток по заказам "
+ВыборкаНоменклатура.КоличествоОстаток
+ " " + ВыборкаНоменклатура.Номенклатура.ЕдиницаИзмерения);
Иначе
ВыборкаПартия = ВыборкаНоменклатура.Выбрать();
Пока ВыборкаПартия.Следующий() Цикл
СуммаВал = СуммаВал
+ РегистрыСведений.КурсыВалют.ПолучитьПоследнее(
ВыборкаПартия.Партия.Дата
,Новый Структура("Валюта", Справочники.Валюты.НайтиПоНаименованию(«USD»)));
Движение = РегистрыНакопления.ЗаказыПоставщикам.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
Движение.Период = Дата;
Движение.Номенклатура = ВыборкаПартия.Номенклатура;
Движение.Количество = ВыборкаПартия.Количество;
КонецЦикла;
Движение = Движения.ТоварыНаСкладах.Добавить();
Движение.Период = Дата;
Движение.Номенклатура = ВыборкаНоменклатура.Номенклатура;
Движение.Количество = ВыборкаНоменклатура.Количество;
Движение.Сумма = ВыборкаНоменклатура.Сумма;
Движение.СуммаВал = СуммаВал;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Ответы:
- Нет удаления старых движений документа.
- Старые движения удаляем, если дата дока сдвинута вперед.
- Нет установки флага для записи движений в конце транзакции.
- Нет наложения управляемой блокировки.
- Для минимизации времени блокировки запрос при помощи МенеджерВременныхТаблиц необходимо разбить на 2: а) получение ланных документа б) Получение остатков.
- Нет установки параметров запроса.
- В параметре на &период вирт. Таблицы «Остатки» следует использовать МоментВремени.
- В случае оперативного поведения параметр «МоментВремени» следует установить в Неопределено.
- Условие при выборке остатков на (Номенклатуру, Партию) следует делать в параметрах виртуальной таблицы.
- «РегистрыСведений.КурсыВалют.ПолучитьПоследнее(» - запрос в цикле. Курс нужно получать в запросе по таблице документа через макс период партии.
- Первый запрос следует сгруппировать по номенклатуре, партии.
- Итоги не нужны.
- Т.к. остатка в регистре может не быть, поле «Заказы.КоличествоОстаток» следует обернуть в ЕстьNUll
- При выборке запроса не указан параметр «ОбходРезультатаЗапроса.ПоГруппировкам».(хотя идет именно по группировкам).
- Обход по группировкам не нужен.
- В случае превышения "Количество в поступлении" над остатком заказов, списания заказов по данной номенклатуре не происходит, что не логично: либо списываем что есть, либо не проводим документ.
- «ВыборкаПартия.Партия.Дата» - чтение всего объекта «через точку». При необходимости работы с полем дата его нужно добавить в запрос.
- «ВыборкаНоменклатура.Номенклатура.ЕдиницаИзмерения» - аналогично.
- «СуммаВал = СуммаВал + РегистрыСведений.КурсыВалют.ПолучитьПоследнее(» - странный алгоритм. Для вычисления валютной суммы вероятно стоит умножать Сумму в рублях на курс.
- +19 переменная СуммаВал не задана.
- «ЗаказыПоставщикам.Добавить();» - лучше использовать «ДобавитьРасход()»
- Не указан ВидДвижения при добавлении дв-ний ТоварыНаСкладах.
- При списании «ЗаказыПоставщикам» не задается партия.