123

123




Процедура БронированиеТовара() экспорт

   

   Записать();

   

   Для Каждого ТекСтрокаТовары Из Товары Цикл

      // регистр БронированиеТоваров Приход

      Движение = Движения.БронированиеТоваров.Добавить();

      Движение.ВидДвижения = ВидДвиженияНакопления.Приход;

      Движение.Период = Дата;

      Движение.Номенклатура = ТекСтрокаТовары.Номенклатура;

      Движение.Склад = Склад;

      Движение.КоличествоЗабронированного = ТекСтрокаТовары.Количество;

   КонецЦикла;

   

   Движения.БронированиеТоваров.Записать();

   

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



Процедура ОбработкаПроведенияСредневзвешенный(Отказ, Режим)

   

   Движения.ОстаткиНоменклатуры.Записывать = Истина;

   

   //!!! ОБЕСПЕЧЕНИЕ НЕИЗМЕННОСТИ ДАННЫХ МЕЖДУ РАСЧЕТОМ И ОКОНЧАНИЕМ ПРОВЕДЕНИЯ !!!

   Блокировка = Новый БлокировкаДанных;

   ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");

   ЭлементБлокировки.Режим         = РежимБлокировкиДанных.Исключительный;

   

   ЭлементБлокировки.УстановитьЗначение("Склад", Склад);

   ЭлементБлокировки.ИсточникДанных = Товары.Выгрузить( ,"Номенклатура");

   ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура",  "Номенклатура");

   

   Блокировка.Заблокировать();

   

   //!!! УДАЛЕНИЕ СОБСТВЕННЫХ СТАРЫХ ДВИЖЕНИЙ ПО РЕГИСТРУ ОСТАТКИ НОМЕНКЛАТУРЫ !!!

   Движения.ОстаткиНоменклатуры.Записать();

   

   //!!! ПОЛУЧЕНИЕ ДАННЫХ ТОЛЬКО ПО ТОВАРАМ !!!

   Запрос = Новый Запрос;

   Запрос.Текст =

   "ВЫБРАТЬ

   |   ПродажаТоваровТовары.Номенклатура КАК Номенклатура,

   |   СУММА(ПродажаТоваровТовары.Количество) КАК Количество,

   |   ПродажаТоваровТовары.Ссылка.Склад КАК Склад

   |ПОМЕСТИТЬ ТабДок

   |ИЗ

   |   Документ.ПродажаТоваров.Товары КАК ПродажаТоваровТовары

   |ГДЕ

   |   ПродажаТоваровТовары.Ссылка = &Ссылка

   |   И ПродажаТоваровТовары.Номенклатура.ВидНоменклатуры <> ЗНАЧЕНИЕ(Перечисление.ВидыТоваров.Услуга)

   |

   |СГРУППИРОВАТЬ ПО

   |   ПродажаТоваровТовары.Номенклатура,

   |   ПродажаТоваровТовары.Ссылка.Склад

   |

   |ИНДЕКСИРОВАТЬ ПО

   |   Номенклатура,

   |   Склад

   |;

   |

   |////////////////////////////////////////////////////////////////////////////////

   |ВЫБРАТЬ

   |   ТабДок.Номенклатура,

   |   ТабДок.Количество,

   |   ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток,

   |   ЕСТЬNULL(ОстаткиНоменклатурыОстатки.СуммаОстаток, 0) КАК СуммаОстаток,

   |   ТабДок.Склад

   |ИЗ

   |   ТабДок КАК ТабДок

   |      ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(

   |            &Момент,

   |            (Номенклатура, Склад) В

   |               (ВЫБРАТЬ

   |                  ТабДок.Номенклатура,

   |                  ТабДок.Склад

   |               ИЗ

   |                  ТабДок КАК ТабДок)) КАК ОстаткиНоменклатурыОстатки

   |      ПО ТабДок.Номенклатура = ОстаткиНоменклатурыОстатки.Номенклатура";

   

   Если Режим = РежимПроведенияДокумента.Оперативный Тогда

      Запрос.УстановитьПараметр("Момент", Неопределено);

   Иначе

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

   КонецЕсли;

   Запрос.УстановитьПараметр("Ссылка", Ссылка);

   

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

   

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

   

   Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

      

      // регистр ОстаткиНоменклатуры Расход

      Движение = Движения.ОстаткиНоменклатуры.Добавить();

      Движение.ВидДвижения = ВидДвиженияНакопления.Расход;

      Движение.Период = Дата;

      Движение.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура;

      Движение.Склад = ВыборкаДетальныеЗаписи.Склад;

      Движение.Количество = ВыборкаДетальныеЗаписи.Количество;

      

      // !!! КОНТРОЛЬ ОТРИЦАТЕЛЬНЫХ ОСТАТКОВ СПИСЫВАЕМЫХ ТОВАРОВ !!!

      // !!! ВЫЧИСЛЕНИЕ СЕБЕСТОИМОСТИ СПИСЫВАЕМЫХ ТОВАРОВ!!!

      Если ВыборкаДетальныеЗаписи.КоличествоОстаток < ВыборкаДетальныеЗаписи.Количество Тогда

         Отказ = Истина;

         Сообщение = Новый СообщениеПользователю;

         Нехватка = ВыборкаДетальныеЗаписи.Количество - ВыборкаДетальныеЗаписи.КоличествоОстаток;

         Сообщение.Текст = "В документе N" + Номер +" от "+Дата+" не хватает "+Нехватка+" единиц товара "+ВыборкаДетальныеЗаписи.Номенклатура;

         Сообщение.Сообщить();

      ИначеЕсли ВыборкаДетальныеЗаписи.КоличествоОстаток = ВыборкаДетальныеЗаписи.Количество Тогда

         Движение.Сумма = ВыборкаДетальныеЗаписи.СуммаОстаток;

      ИначеЕсли ВыборкаДетальныеЗаписи.КоличествоОстаток > ВыборкаДетальныеЗаписи.Количество Тогда

         Движение.Сумма = ВыборкаДетальныеЗаписи.СуммаОстаток/ВыборкаДетальныеЗаписи.КоличествоОстаток*ВыборкаДетальныеЗаписи.Количество;

      КонецЕсли;

      

   КонецЦикла;

   

   // регистр Продажи

   Движения.Продажи.Записывать = Истина;

   Для Каждого ТекСтрокаТовары Из Товары Цикл

      Движение = Движения.Продажи.Добавить();

      Движение.Период = Дата;

      Движение.Контрагент = Контрагент;

      Движение.Номенклатура = ТекСтрокаТовары.Номенклатура;

      Движение.Количество = ТекСтрокаТовары.Количество;

      Движение.Сумма = ТекСтрокаТовары.Сумма;

   КонецЦикла;


   

   Движения.Задолженности.Записывать = Истина;

   // регистр Задолженности Приход

   Движение = Движения.Задолженности.Добавить();

   Движение.ВидДвижения = ВидДвиженияНакопления.Приход;

   Движение.Период = Дата;

   Движение.Контрагент = Контрагент;

   Движение.СуммаДолга = СуммаДокумента;

   

   Движения.БронированиеТоваров.Записывать = Истина;

   

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



Процедура ОбработкаПроведенияПартионныйУчет(Отказ, Режим)

   

   Движения.ОстаткиНоменклатуры.Записывать = Истина;

   

   //!!! ОБЕСПЕЧЕНИЕ НЕИЗМЕННОСТИ ДАННЫХ МЕЖДУ РАСЧЕТОМ И ОКОНЧАНИЕМ ПРОВЕДЕНИЯ !!!

   Блокировка = Новый БлокировкаДанных;

   ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");

   ЭлементБлокировки.Режим         = РежимБлокировкиДанных.Исключительный;

   

   ЭлементБлокировки.УстановитьЗначение("Склад", Склад);

   ЭлементБлокировки.ИсточникДанных = Товары.Выгрузить( ,"Номенклатура");

   ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура",  "Номенклатура");

   

   Блокировка.Заблокировать();

   

   //!!! УДАЛЕНИЕ СОБСТВЕННЫХ СТАРЫХ ДВИЖЕНИЙ ПО РЕГИСТРУ ОСТАТКИ НОМЕНКЛАТУРЫ !!!

   Движения.ОстаткиНоменклатуры.Записать();

   

   //!!! ПОЛУЧЕНИЕ ДАННЫХ ТОЛЬКО ПО ТОВАРАМ !!!

   Запрос = Новый Запрос;

   Запрос.Текст =

   "ВЫБРАТЬ

   |   ПродажаТоваровТовары.Номенклатура КАК Номенклатура,

   |   ПродажаТоваровТовары.Ссылка.Склад КАК Склад,

   |   СУММА(ПродажаТоваровТовары.Количество) КАК Количество

   |ПОМЕСТИТЬ ТабДок

   |ИЗ

   |   Документ.ПродажаТоваров.Товары КАК ПродажаТоваровТовары

   |ГДЕ

   |   ПродажаТоваровТовары.Ссылка = &Ссылка

   |   И ПродажаТоваровТовары.Номенклатура.ВидНоменклатуры <> ЗНАЧЕНИЕ(Перечисление.ВидыТоваров.Услуга)

   |

   |СГРУППИРОВАТЬ ПО

   |   ПродажаТоваровТовары.Номенклатура,

   |   ПродажаТоваровТовары.Ссылка.Склад

   |

   |ИНДЕКСИРОВАТЬ ПО

   |   Номенклатура,

   |   Склад

   |;

   |

   |////////////////////////////////////////////////////////////////////////////////

   |ВЫБРАТЬ

   |   ТабДок.Номенклатура КАК Номенклатура,

   |   ТабДок.Количество КАК Количество,

   |   ОстаткиНоменклатурыОстатки.Партия,

   |   ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток,

   |   ЕСТЬNULL(ОстаткиНоменклатурыОстатки.СуммаОстаток, 0) КАК СуммаОстаток,

   |   ТабДок.Склад КАК Склад,

   |   ОстаткиНоменклатурыОстатки.Партия.Дата КАК ПартияДата

   |ИЗ

   |   ТабДок КАК ТабДок

   |      ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(

   |            &Момент,

   |            (Номенклатура, Склад) В

   |               (ВЫБРАТЬ

   |                  ТабДок.Номенклатура,

   |                  ТабДок.Склад

   |               ИЗ

   |                  ТабДок КАК ТабДок)) КАК ОстаткиНоменклатурыОстатки

   |      ПО ТабДок.Номенклатура = ОстаткиНоменклатурыОстатки.Номенклатура

   |

   |УПОРЯДОЧИТЬ ПО

   |   Номенклатура,

   |   ПартияДата

   |ИТОГИ

   |   МАКСИМУМ(Количество),

   |   СУММА(КоличествоОстаток),

   |   СУММА(СуммаОстаток),

   |   МАКСИМУМ(Склад)

   |ПО

   |   Номенклатура";

   

   Если Режим = РежимПроведенияДокумента.Оперативный Тогда

      Запрос.УстановитьПараметр("Момент", Неопределено);

   Иначе

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

   КонецЕсли;

   Запрос.УстановитьПараметр("Ссылка", Ссылка);

   

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

   

   ВыборкаНоменклатура = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

   

   Пока ВыборкаНоменклатура.Следующий() Цикл

      

      Если ВыборкаНоменклатура.КоличествоОстаток < ВыборкаНоменклатура.Количество Тогда

         // !!! КОНТРОЛЬ ОТРИЦАТЕЛЬНЫХ ОСТАТКОВ СПИСЫВАЕМЫХ ТОВАРОВ !!!

         

         Отказ = Истина;

         Сообщение = Новый СообщениеПользователю;

         Нехватка = ВыборкаНоменклатура.Количество - ВыборкаНоменклатура.КоличествоОстаток;

         Сообщение.Текст = "В документе N" + Номер +" от "+Дата+" не хватает "+Нехватка+" единиц товара "+ВыборкаНоменклатура.Номенклатура;

         Сообщение.Сообщить();

      Иначе

         // !!! ВЫЧИСЛЕНИЕ СЕБЕСТОИМОСТИ СПИСЫВАЕМЫХ ПАРТИЙ ТОВАРОВ!!!

         

         КоличествоНадоСписать = ВыборкаНоменклатура.Количество;

         

         ВыборкаДетальныеЗаписи = ВыборкаНоменклатура.Выбрать();

         Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

            

            Если ВыборкаДетальныеЗаписи.КоличествоОстаток <= КоличествоНадоСписать Тогда

               

               //списываем всю партию

               КоличествоКСписанию = ВыборкаДетальныеЗаписи.КоличествоОстаток;

               СтоимостьКСписанию = ВыборкаДетальныеЗаписи.СуммаОстаток;

               //уменьшаем количество к списанию

               КоличествоНадоСписать = КоличествоНадоСписать - КоличествоКСписанию;

               

            Иначе

               

               //списываем часть партии

               КоличествоКСписанию = КоличествоНадоСписать;

               Если ВыборкаДетальныеЗаписи.КоличествоОстаток <> 0 Тогда

                  СтоимостьКСписанию = ВыборкаДетальныеЗаписи.СуммаОстаток/ВыборкаДетальныеЗаписи.КоличествоОстаток*КоличествоКСписанию;

               иначе   

                  СтоимостьКСписанию = ВыборкаДетальныеЗаписи.СуммаОстаток;

               КонецЕсли;

               

               //обнуляем количество к списанию

               КоличествоНадоСписать = 0;

               

            КонецЕсли;

            //!!!ФОРМИРУЕМ НАБОР ЗАПИСЕЙ!!!

            Движение = Движения.ОстаткиНоменклатуры.Добавить();

            Движение.ВидДвижения = ВидДвиженияНакопления.Расход;

            Движение.Период = Дата;

            Движение.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура;

            Движение.Склад = Склад;

            Движение.Партия = ВыборкаДетальныеЗаписи.Партия;

            Движение.Количество = КоличествоКСписанию;

            Движение.Сумма = СтоимостьКСписанию;

            

            //проверяем необходимость дальнейшего перебора партий

            Если КоличествоНадоСписать <= 0 Тогда

               Прервать;

            КонецЕсли;

            

         КонецЦикла;

      КонецЕсли;

   КонецЦикла;

   

   Движения.Продажи.Записывать = Истина;

   Для Каждого ТекСтрокаТовары Из Товары Цикл

      // регистр Продажи

      Движение = Движения.Продажи.Добавить();

      Движение.Период = Дата;

      Движение.Контрагент = Контрагент;

      Движение.Номенклатура = ТекСтрокаТовары.Номенклатура;

      Движение.Количество = ТекСтрокаТовары.Количество;

      Движение.Сумма = ТекСтрокаТовары.Сумма;

   КонецЦикла;


   

   Движения.Задолженности.Записывать = Истина;

   // регистр Задолженности Приход

   Движение = Движения.Задолженности.Добавить();

   Движение.ВидДвижения = ВидДвиженияНакопления.Приход;

   Движение.Период = Дата;

   Движение.Контрагент = Контрагент;

   Движение.СуммаДолга = СуммаДокумента;

   

   Движения.БронированиеТоваров.Записывать = Истина;

   

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



Процедура ОбработкаПроведения(Отказ, Режим)

   

   Движения.Задолженности.Записывать = Истина;

   // регистр Задолженности Приход

   Движение = Движения.Задолженности.Добавить();

   Движение.ВидДвижения = ВидДвиженияНакопления.Приход;

   Движение.Период = Дата;

   Движение.Контрагент = Контрагент;

   Движение.СуммаДолга = Дата;

   

   Движения.БронированиеТоваров.Записывать = Истина;

   

   Движения.Продажи.Записывать = Истина;

   Для Каждого ТекСтрокаТовары Из Товары Цикл

      // регистр Продажи

      Движение = Движения.Продажи.Добавить();

      Движение.Период = Дата;

      Движение.Контрагент = Контрагент;

      Движение.Номенклатура = ТекСтрокаТовары.Номенклатура;

      Движение.Количество = ТекСтрокаТовары.Количество;

      Движение.Сумма = ТекСтрокаТовары.Сумма;

   КонецЦикла;

   

   

   //Установка флага последующего при записи наложения блокировки

   Движения.СвободныеОстатки.БлокироватьДляИзменения = Истина;

   

   Движения.СвободныеОстатки.Записывать = Истина;

   //Запрос для определения только товаров документа

   Запрос = Новый Запрос;

   Запрос.Текст =

   "ВЫБРАТЬ

   |   ПродажаТоваровТовары.Номенклатура,

   |   СУММА(ПродажаТоваровТовары.Количество) КАК Количество

   |ИЗ

   |   Документ.ПродажаТоваров.Товары КАК ПродажаТоваровТовары

   |ГДЕ

   |   ПродажаТоваровТовары.Ссылка = &Ссылка

   |   И ПродажаТоваровТовары.Номенклатура.ВидНоменклатуры <> ЗНАЧЕНИЕ(Перечисление.ВидыТоваров.Услуга)

   |

   |СГРУППИРОВАТЬ ПО

   |   ПродажаТоваровТовары.Номенклатура";

   

   Запрос.УстановитьПараметр("Ссылка", Ссылка);

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

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

   

   Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

      

      // регистр СвободныеОстатки Расход

      Движение = Движения.СвободныеОстатки.Добавить();

      Движение.ВидДвижения = ВидДвиженияНакопления.Расход;

      Движение.Период = Дата;

      Движение.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура;

      Движение.Склад = Склад;

      Движение.КоличествоВСвободномОстатке = ВыборкаДетальныеЗаписи.Количество;

   КонецЦикла;

   

   //Подготовим менеджер временных таблиц для заполнения перечня товаров

   //изменившихся свободных остатков в модуле набора записей регистра

   МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

   Движения.СвободныеОстатки.ДополнительныеСвойства.Вставить(

             "МенеджерВременныхТаблицПроведенияПродажиТоваров",

              МенеджерВременныхТаблиц);

            

   СформироватьДвиженияПоРегиструПланированияОказанияУслуг();

   

   //Общая запись всех движений

   Движения.Записать();

   

   //Контроль отрицательных остатков

   Запрос = Новый Запрос;

   Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;

   

   Запрос.Текст =

   "ВЫБРАТЬ

   |   СвободныеОстаткиОстатки.Номенклатура,

   |   СвободныеОстаткиОстатки.КоличествоВСвободномОстаткеОстаток

   |ИЗ

   |   РегистрНакопления.СвободныеОстатки.Остатки(

   |         ,

   |         (Номенклатура, Склад) В

   |            (ВЫБРАТЬ

   |               ТабИзменившихсяТоваров.Номенклатура,

   |               ТабИзменившихсяТоваров.Склад

   |            ИЗ

   |               ТабИзменившихсяТоваров КАК ТабИзменившихсяТоваров)) КАК СвободныеОстаткиОстатки

   |ГДЕ

   |   СвободныеОстаткиОстатки.КоличествоВСвободномОстаткеОстаток < 0";

   

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

   

   Если не Результат.Пустой() Тогда

      Отказ = Истина;

      

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

      

      Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

         

         Сообщение = Новый СообщениеПользователю;

         Нехватка = - ВыборкаДетальныеЗаписи.КоличествоВСвободномОстаткеОстаток;

         Сообщение.Текст = "В документе N" + Номер +" от "+Дата+" не хватает "+Нехватка+" единиц товара "+ВыборкаДетальныеЗаписи.Номенклатура;

         Сообщение.Сообщить();

         

      КонецЦикла;

   КонецЕсли;

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


Процедура СформироватьДвиженияПоРегиструПланированияОказанияУслуг()

   Движения.ПланированиеОказаниеУслуг.Записывать = Истина;

   

   //!!! ДВИЖЕНИЯ НАДО ДЕЛАТЬ ТОЛЬКО ДЛЯ УСЛУГ!!!

   Запрос = Новый Запрос;

   Запрос.Текст =

      "ВЫБРАТЬ

      |   ПродажаТоваровТовары.Номенклатура

      |ИЗ

      |   Документ.ПродажаТоваров.Товары КАК ПродажаТоваровТовары

      |ГДЕ

      |   ПродажаТоваровТовары.Ссылка = &Ссылка

      |   И ПродажаТоваровТовары.Номенклатура.ВидНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ВидыТоваров.Услуга)

      |

      |СГРУППИРОВАТЬ ПО

      |   ПродажаТоваровТовары.Номенклатура";


   Запрос.УстановитьПараметр("Ссылка", Ссылка);


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


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


   Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

      Движение = Движения.ПланированиеОказаниеУслуг.Добавить();

      Движение.Период = Дата;

      Движение.Услуга = ВыборкаДетальныеЗаписи.Номенклатура;

      Движение.Контрагент = Контрагент;

      Движение.ДокументОснование = Ссылка;

   КонецЦикла;


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