Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
22 ноя 2024, 01:03

расчитывает остатки без учета текущего документа....

Автор Андрей Тимофеев, 03 авг 2016, 17:50

0 Пользователей и 1 гость просматривают эту тему.

Андрей Тимофеев



Процедура ОбработкаПроведения(Отказ, Режим)
   //{{__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
   // Данный фрагмент построен конструктором.
   // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

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

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

cska-fanat-kz

не может быть.
остатки актуальные берутся.
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

vitasw

Цитата: cska-fanat-kz от 03 авг 2016, 17:55не может быть.
Чет вы заработались. При "удалять движения автоматически" - всегда без учета текущего документа.

cska-fanat-kz

Цитата: vitasw от 04 авг 2016, 08:26
Цитата: cska-fanat-kz от 03 авг 2016, 17:55не может быть.
Чет вы заработались. При "удалять движения автоматически" - всегда без учета текущего документа.

а это?
Цитата: Андрей Тимофеев от 03 авг 2016, 17:50КонецЦикла;
   
   Движения.Записать();
   
   
   Если Режим = РежимПроведенияДокумента.Оперативный Тогда

в начале обработки проведения движения пусть и потерлись, но потом они явно записываются...
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

LexaK

и вообще идиотизм какой-то! все перевернуто с ног на голову
какой дурак придумал,
сначала сделать проводки, сформировать и записать движения, а потом уже проверить остатки и если они отрицательные все откатить!!! :ehtwj:

все нормальные проведения делают наоборот
1.Сначала выполняются все нужные проверки, проверяются остатки и т.д. выводятся информационные сообщения и ВСЕ, дальше документ не проводится!
2.если проверки прошли сделать движения

поэтому совет Андрей Тимофеев,

если это оперативное проведение, сделайте сначала проверку количества остатков.
если их не хватает, выдайте сообщение, выйдите из проведения.

если все ОК, сделайте проводки.

если помогло нажмите: Спасибо!

vitasw

Цитата: LexaK от 04 авг 2016, 09:41какой дурак придумал, сначала сделать проводки, сформировать и записать движения, а потом уже проверить остатки и если они отрицательные все откатить

:D вообще-то это официальные рекомендации 1С.
Именно так и рекомендуется делать, когда это возможно. Вначале пишутся движения, а затем проверяются остатки. - это оптимистическая модель проведения, т.е. в процентном отношении число удачных проведений будет больше чем число откатов. + время выполнения такого проведения в общем случае будет меньше чем традиционная схема проведения.
Другое дело, что в данном случае организация проведения выполнена неправильно.



Добавлено: 04 авг 2016, 10:35


Цитата: cska-fanat-kz от 04 авг 2016, 09:25в начале обработки проведения движения пусть и потерлись, но потом они явно записываются...

Упс, согласен.

cska-fanat-kz

LexaK, в сети были статейки, почему новый подход лучше...
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

LexaK

cska-fanat-kz,
не пойму где логика

Вариант с постпроверкой

1.Делаем движения - т1
2.выполняем проверку - т2
3.откат транзакции - т3

если условие не прошло, сумма действий = т1 + т2 + т3

Вариант с предпроверкой

1.выполняем проверку - т2
2.Делаем движения - т1

если условие не прошло, сумма действий = т2

где здесь оптимальность первого варианта? :dfbsdfbsdf:

если помогло нажмите: Спасибо!

cska-fanat-kz

LexaK, читал про это довольно давно и если честно лень по-новой искать статью.
ровно как и некогда вступать в полемику ;)
Получил помощь - скажи СПАСИБО.
Разобрался сам - расскажи другим.

vitasw

Цитата: LexaK от 04 авг 2016, 11:26cska-fanat-kz,
не пойму где логика

Вариант с постпроверкой

1.Делаем движения - т1
2.выполняем проверку - т2
3.откат транзакции - т3

если условие не прошло, сумма действий = т1 + т2 + т3

Вариант с предпроверкой

1.выполняем проверку - т2
2.Делаем движения - т1

если условие не прошло, сумма действий = т2

где здесь оптимальность первого варианта?
Некорректное описание.

хоть я этого перца терпеьь не могу, но.. : http://1c.chistov.pro/2010/06/1-82.html

Теги:

Похожие темы (5)

Рейтинг@Mail.ru

Поиск