Конфигурация: Trade (10.3.29.1) (http://v8.1c.ru/trade/), версия: 8.3.11.2867, обычные формы.
Добрый день. Подскажите пожалуйста в следующем. Мне нужно создать обработку, с помощью которой я смогу создавать документы оприходования товара на основе не проведённого документа возврат от покупателей. То есть получать позиции и количество из документа возврат от покупателей плюс нужно рассчитать себе стоимость. То есть есть реализация проведённая, есть её не проведённый возврат. Нужно вместо возврат создать документ оприходования. Товар из регистра партии товаров на складах списывается через реализацию по принципу FIFO. Документ возврат от покупателей возвращает товар немного иначе, последний товар который был списан из реализации будет первым в возврате (ну и остальные партии по такому же принципу). То есть оприходование должно записывать партии в такой же очерёдности как документ возврат от покупателей. Подскажите, как реализовать.
Небольшие наработки:

```1c
    ВЫБРАТЬ
    ВозвратТоваровОтПокупателяТовары.Номенклатура КАК Номенклатура,
    ВозвратТоваровОтПокупателяТовары.ДокументПартии КАК Реализация
    ПОМЕСТИТЬ ЗапросПоВозврату
    ИЗ
    Документ.ВозвратТоваровОтПокупателя.Товары КАК ВозвратТоваровОтПокупателяТовары
    ГДЕ
    ВозвратТоваровОтПокупателяТовары.Ссылка = &ДокументВозврата
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ЗапросПоВозврату.Номенклатура КАК Номенклатура,
    ПартииТоваровНаСкладах.Количество КАК Количество,
    ПартииТоваровНаСкладах.Стоимость КАК Стоимость,
    ПартииТоваровНаСкладах.ДокументОприходования КАК ДокументОприходования
    ИЗ
    ЗапросПоВозврату КАК ЗапросПоВозврату
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ПартииТоваровНаСкладах КАК ПартииТоваровНаСкладах
    ПО ЗапросПоВозврату.Номенклатура = ПартииТоваровНаСкладах.Номенклатура
    И ЗапросПоВозврату.Реализация = ПартииТоваровНаСкладах.Регистратор

    УПОРЯДОЧИТЬ ПО
    ДокументОприходования
```

Тестовый пример результата запроса:
Результат запроса
---
Моё решение:

```1c
    Процедура КнопкаВыполнитьНажатие(Кнопка)

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    | ВозвратТоваровОтПокупателяТовары.Номенклатура КАК Номенклатура,
    | ВозвратТоваровОтПокупателяТовары.ДокументПартии КАК Реализация,
    | ВозвратТоваровОтПокупателяТовары.ЕдиницаИзмерения КАК ЕдиницаИзмерения
    |ПОМЕСТИТЬ ЗапросПоВозврату
    |ИЗ
    | Документ.ВозвратТоваровОтПокупателя.Товары КАК ВозвратТоваровОтПокупателяТовары
    |ГДЕ
    | ВозвратТоваровОтПокупателяТовары.Ссылка = &ДокументВозврата
    |;
    |
    |////////////////////////////////////////////////////////////­////////////////////
    |ВЫБРАТЬ
    | ЗапросПоВозврату.Номенклатура КАК Номенклатура,
    | ПартииТоваровНаСкладах.Количество КАК Количество,
    | ЗапросПоВозврату.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
    | ПартииТоваровНаСкладах.Стоимость КАК Стоимость,
    | ПартииТоваровНаСкладах.Склад КАК Склад
    |ИЗ
    | ЗапросПоВозврату КАК ЗапросПоВозврату
    | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ПартииТоваровНаСкладах КАК ПартииТоваровНаСкладах
    | ПО ЗапросПоВозврату.Номенклатура = ПартииТоваровНаСкладах.Номенклатура
    | И ЗапросПоВозврату.Реализация = ПартииТоваровНаСкладах.Регистратор
    |
    |УПОРЯДОЧИТЬ ПО
    | Номенклатура,
    | ПартииТоваровНаСкладах.ДокументОприходования УБЫВ
    |АВТОУПОРЯДОЧИВАНИЕ";

    Запрос.УстановитьПараметр("ДокументВозврата", ДокументВозврата);

    ВыборкаВыгрузка = Запрос.Выполнить().Выгрузить();

    НовыйДокумент = Документы.ОприходованиеТоваров.СоздатьДокумент();

    Для каждого СтрокаДокументаВозврата Из ДокументВозврата.Товары Цикл

    Массив = ВыборкаВыгрузка.НайтиСтроки(Новый Структура("Номенклатура", СтрокаДокументаВозврата.Номенклатура));
    НеобходимоеКоличество = СтрокаДокументаВозврата.Количество;

    Для каждого СтрокаМассива Из Массив Цикл

    ТабличнаяЧасть = НовыйДокумент.Товары.Добавить();
    ТабличнаяЧасть.Номенклатура = СтрокаМассива.Номенклатура;
    ТабличнаяЧасть.ЕдиницаИзмерения = СтрокаМассива.ЕдиницаИзмерения;
    ТабличнаяЧасть.Коэффициент = 1;

    Если НеобходимоеКоличество > СтрокаМассива.Количество Тогда
    НеобходимоеКоличество = НеобходимоеКоличество - СтрокаМассива.Количество;
    ТабличнаяЧасть.Количество = СтрокаМассива.Количество;
    ТабличнаяЧасть.Цена = СтрокаМассива.Стоимость / СтрокаМассива.Количество;
    ТабличнаяЧасть.Сумма = СтрокаМассива.Стоимость;
    Иначе
    ТабличнаяЧасть.Количество = НеобходимоеКоличество;
    ТабличнаяЧасть.Цена = СтрокаМассива.Стоимость / СтрокаМассива.Количество;
    ТабличнаяЧасть.Сумма = ТабличнаяЧасть.Количество * ТабличнаяЧасть.Цена;
    НеобходимоеКоличество = 0;
    Прервать;
    КонецЕсли;

    КонецЦикла;

    КонецЦикла;

    НовыйДокумент.Товары.Свернуть("Номенклатура, ЕдиницаИзмерения, Коэффициент, Цена, Сумма, Качество", "Количество");
    НовыйДокумент.Дата = ТекущаяДата();
    НовыйДокумент.Склад = СтрокаДокументаВозврата.Склад;
    НовыйДокумент.ОтражатьВУправленческомУчете = Истина;
    НовыйДокумент.Организация = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(ПараметрыСеанса.ТекущийПользователь, "ОсновнаяОрганизация");
    НовыйДокумент.Записать();

    КонецПроцедуры
```
---
Ну да все правильно!
То что продали, а возврат на основании реализации, то и оприходывайте обратно, без всяких пересчетов, те-же партия и цена
---
Не проведённый возврат не имеет движений в регистрах. Поэтому я не могу посмотреть как партии товаров возвращаются.
---
Непроведенный возврат ссылается на проведенную Реализацию
(не понятно, а что мешает все по возврату сделать - проводки оприходвания?)
---
можно провести возврат, скопировать его движения, отменить проведение...
---
Не проведенный возврат ссылается на проведенную Реализацию
Верно, я об этом писал в шапке.

(не понятно, а что мешает все по возврату сделать - проводки оприходования?)
Ну есть свои нюансы, которые требуют функционала, который я описал в шапке.
---
Нужно вместо возврат создать документ оприходования.
а какой документ собираетесь использовать вместо возврата?

могут подойти Корректировка или Операция, просто отсторнируйте проводки Реализации на вернутое количество,
и товар вернете и остатки по реализации всегда под рукой будут (что бы нельзя было вернуть больше чем продано)
---
Нужно как то сделать грамотный отбор после запроса,в котором будут сравниваться строки одной таблицы (возвраты) и другой (партий). Ну и одновременно высчитывать нужное количество из таблицы партий в таблицу возвратов.

```1c
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    | ВозвратТоваровОтПокупателяТовары.Номенклатура КАК Номенклатура,
    | ВозвратТоваровОтПокупателяТовары.Количество КАК Количество,
    | ВозвратТоваровОтПокупателяТовары.ДокументПартии КАК Реализация,
    | ВозвратТоваровОтПокупателяТовары.Склад КАК Склад,
    | ВозвратТоваровОтПокупателяТовары.ЕдиницаИзмерения КАК ЕдиницаИзмерения
    |ПОМЕСТИТЬ ЗапросПоВозврату
    |ИЗ
    | Документ.ВозвратТоваровОтПокупателя.Товары КАК ВозвратТоваровОтПокупателяТовары
    |ГДЕ
    | ВозвратТоваровОтПокупателяТовары.Ссылка = &ДокументВозврата
    |;
    |
    |////////////////////////////////////////////////////////////­////////////////////
    |ВЫБРАТЬ
    | ЗапросПоВозврату.Номенклатура КАК Номенклатура,
    | ЗапросПоВозврату.Количество КАК КоличествоНоменклатурыВозврата,
    | ПартииТоваровНаСкладах.Количество КАК Количество,
    | ЗапросПоВозврату.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
    | ПартииТоваровНаСкладах.Стоимость КАК Стоимость,
    | ЗапросПоВозврату.Склад КАК Склад
    |ИЗ
    | ЗапросПоВозврату КАК ЗапросПоВозврату
    | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ПартииТоваровНаСкладах КАК ПартииТоваровНаСкладах
    | ПО ЗапросПоВозврату.Номенклатура = ПартииТоваровНаСкладах.Номенклатура
    | И ЗапросПоВозврату.Реализация = ПартииТоваровНаСкладах.Регистратор
    |
    |УПОРЯДОЧИТЬ ПО
    | Номенклатура,
    | ПартииТоваровНаСкладах.ДокументОприходования УБЫВ
    |АВТОУПОРЯДОЧИВАНИЕ";

    Запрос.УстановитьПараметр("ДокументВозврата", ДокументВозврата);
    Выборка = Запрос.Выполнить().Выбрать();

    ТЗНоменклатурыВозврата = ДокументВозврата.Товары.Выгрузить();

    Отбор = Новый Структура();
    Отбор.Вставить("Номенклатура", Выборка.Номенклатура);
    Строка = ТЗНоменклатурыВозврата.НайтиСтроки(Отбор);
```
---
Моё решение:

```1c
    Процедура КнопкаВыполнитьНажатие(Кнопка)

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    | ВозвратТоваровОтПокупателяТовары.Номенклатура КАК Номенклатура,
    | ВозвратТоваровОтПокупателяТовары.ДокументПартии КАК Реализация,
    | ВозвратТоваровОтПокупателяТовары.ЕдиницаИзмерения КАК ЕдиницаИзмерения
    |ПОМЕСТИТЬ ЗапросПоВозврату
    |ИЗ
    | Документ.ВозвратТоваровОтПокупателя.Товары КАК ВозвратТоваровОтПокупателяТовары
    |ГДЕ
    | ВозвратТоваровОтПокупателяТовары.Ссылка = &ДокументВозврата
    |;
    |
    |////////////////////////////////////////////////////////////­////////////////////
    |ВЫБРАТЬ
    | ЗапросПоВозврату.Номенклатура КАК Номенклатура,
    | ПартииТоваровНаСкладах.Количество КАК Количество,
    | ЗапросПоВозврату.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
    | ПартииТоваровНаСкладах.Стоимость КАК Стоимость,
    | ПартииТоваровНаСкладах.Склад КАК Склад
    |ИЗ
    | ЗапросПоВозврату КАК ЗапросПоВозврату
    | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ПартииТоваровНаСкладах КАК ПартииТоваровНаСкладах
    | ПО ЗапросПоВозврату.Номенклатура = ПартииТоваровНаСкладах.Номенклатура
    | И ЗапросПоВозврату.Реализация = ПартииТоваровНаСкладах.Регистратор
    |
    |УПОРЯДОЧИТЬ ПО
    | Номенклатура,
    | ПартииТоваровНаСкладах.ДокументОприходования УБЫВ
    |АВТОУПОРЯДОЧИВАНИЕ";

    Запрос.УстановитьПараметр("ДокументВозврата", ДокументВозврата);

    ВыборкаВыгрузка = Запрос.Выполнить().Выгрузить();

    НовыйДокумент = Документы.ОприходованиеТоваров.СоздатьДокумент();

    Для каждого СтрокаДокументаВозврата Из ДокументВозврата.Товары Цикл

    Массив = ВыборкаВыгрузка.НайтиСтроки(Новый Структура("Номенклатура", СтрокаДокументаВозврата.Номенклатура));
    НеобходимоеКоличество = СтрокаДокументаВозврата.Количество;

    Для каждого СтрокаМассива Из Массив Цикл

    ТабличнаяЧасть = НовыйДокумент.Товары.Добавить();
    ТабличнаяЧасть.Номенклатура = СтрокаМассива.Номенклатура;
    ТабличнаяЧасть.ЕдиницаИзмерения = СтрокаМассива.ЕдиницаИзмерения;
    ТабличнаяЧасть.Коэффициент = 1;

    Если НеобходимоеКоличество > СтрокаМассива.Количество Тогда
    НеобходимоеКоличество = НеобходимоеКоличество - СтрокаМассива.Количество;
    ТабличнаяЧасть.Количество = СтрокаМассива.Количество;
    ТабличнаяЧасть.Цена = СтрокаМассива.Стоимость / СтрокаМассива.Количество;
    ТабличнаяЧасть.Сумма = СтрокаМассива.Стоимость;
    Иначе
    ТабличнаяЧасть.Количество = НеобходимоеКоличество;
    ТабличнаяЧасть.Цена = СтрокаМассива.Стоимость / СтрокаМассива.Количество;
    ТабличнаяЧасть.Сумма = ТабличнаяЧасть.Количество * ТабличнаяЧасть.Цена;
    НеобходимоеКоличество = 0;
    Прервать;
    КонецЕсли;

    КонецЦикла;

    КонецЦикла;

    НовыйДокумент.Товары.Свернуть("Номенклатура, ЕдиницаИзмерения, Коэффициент, Цена, Сумма, Качество", "Количество");
    НовыйДокумент.Дата = ТекущаяДата();
    НовыйДокумент.Склад = СтрокаДокументаВозврата.Склад;
    НовыйДокумент.ОтражатьВУправленческомУчете = Истина;
    НовыйДокумент.Организация = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(ПараметрыСеанса.ТекущийПользователь, "ОсновнаяОрганизация");
    НовыйДокумент.Записать();

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