// Процедура контролирует остаток по данному регистру по переданному документу // и его табличной части. В случае недостатка товаров выставляется флаг отказа и // выдается сообщегние. // // Параметры: // ДокументОбъект - объект проводимого документа, // ИмяТабличнойЧасти - строка, имя табличной части, которая проводится по регистру, // СтруктураШапкиДокумента - структура, содержащая значения "через точку" ссылочных реквизитов по шапке документа, // Отказ - флаг отказа в проведении, // Заголовок - строка, заголовок сообщения об ошибке проведения. // Процедура КонтрольОстатков(ДокументОбъект, ИмяТабличнойЧасти, СтруктураШапкиДокумента, Отказ, Заголовок) Экспорт МетаданныеДокумента = ДокументОбъект.Метаданные(); ИмяДокумента = МетаданныеДокумента.Имя; ИмяТаблицы = ИмяДокумента + "." + СокрЛП(ИмяТабличнойЧасти); Если ТипЗнч(СтруктураШапкиДокумента.Ссылка) = Тип("ДокументСсылка.КорректировкаСерийИХарактеристикТоваров") Тогда ТекстХарактеристикаНоменклатуры = "ХарактеристикаНоменклатурыСтарая"; ТекстСерияНоменклатуры = "СерияНоменклатурыСтарая"; Иначе ТекстХарактеристикаНоменклатуры = "ХарактеристикаНоменклатуры"; ТекстСерияНоменклатуры = "СерияНоменклатуры"; КонецЕсли; ТекстКачество = "Качество"; ЕстьСерия = ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента(ТекстСерияНоменклатуры, МетаданныеДокумента, ИмяТабличнойЧасти); ЕстьХарактеристика = ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента(ТекстХарактеристикаНоменклатуры, МетаданныеДокумента, ИмяТабличнойЧасти); ЕстьДокументРезерва = ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("ДокументРезерва", МетаданныеДокумента, ИмяТабличнойЧасти); ЕстьДокументПередачи = ОбщегоНазначения.ЕстьРеквизитДокумента("ДокументПередачи", МетаданныеДокумента); ЕстьКачество = ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента(ТекстКачество, МетаданныеДокумента, ИмяТабличнойЧасти); ЕстьФлагУказанияСерий = ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("СерияУказываетсяПриОтпускеСоСклада", МетаданныеДокумента, ИмяТабличнойЧасти); ЕстьКоэффициент = ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("Коэффициент", МетаданныеДокумента, ИмяТабличнойЧасти); ЕстьКлючСтроки = ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("КлючСтроки", МетаданныеДокумента, ИмяТабличнойЧасти); ЕстьСкладВТабЧасти = ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("Склад", МетаданныеДокумента, ИмяТабличнойЧасти); ЕстьСоставНабора = Ложь; Если ЕстьКлючСтроки Тогда Если ОбщегоНазначения.ЕстьТабЧастьДокумента("СоставНабора", МетаданныеДокумента) И ДокументОбъект.СоставНабора.Количество() > 0 Тогда ЕстьСоставНабора = Истина; КонецЕсли; КонецЕсли; СтруктураУП = ОбщегоНазначения.ПолучитьПараметрыУчетнойПолитики(СтруктураШапкиДокумента.Ссылка.Дата, Отказ, , "Упр"); КонтролироватьОстатокПоСкладу = СтруктураУП.ВестиУчетПоСкладамВРазрезеОрганизаций; // Текст вложенного запроса, ограничивающего номенклатуру при получении остатков Если ЕстьСоставНабора Тогда ТекстЗапросаСписокНоменклатуры = " |ВЫБРАТЬ РАЗЛИЧНЫЕ | Док.Номенклатура КАК Номенклатура |ИЗ | ( | ВЫБРАТЬ | Док.Номенклатура | ИЗ | Документ." + ИмяТаблицы +" КАК Док | ГДЕ | Док.Ссылка = &ДокументСсылка | И НЕ Док.Номенклатура.Комплект | И Не Док.Номенклатура.Услуга | ОБЪЕДИНИТЬ ВСЕ | | ВЫБРАТЬ | Док.Номенклатура | ИЗ | Документ." + ИмяДокумента + ".СоставНабора КАК Док | ГДЕ | Док.Ссылка = &ДокументСсылка | И НЕ Док.Номенклатура.Комплект | И Не Док.Номенклатура.Услуга | | ) КАК Док |"; ТекстЗапросаРеквизитыДокумента = " | (ВЫБРАТЬ | Док.Ссылка, | Док.Номенклатура, | " + ?(ЕстьКачество, "Док.Качество,", "") + " | " + ?(ЕстьХарактеристика, "Док.ХарактеристикаНоменклатуры,", "") + " | " + ?(ЕстьСерия, "Док.СерияНоменклатуры,", "") + " | " + ?(ЕстьКоэффициент, "Док.Коэффициент,", "") + " | " + ?(ЕстьДокументРезерва, "Док.ДокументРезерва,", "") + " | " + ?(ЕстьСкладВТабЧасти, "Док.Склад,", "") + " | Док.Количество | ИЗ | Документ." + ИмяТаблицы + " КАК Док | ГДЕ | Док.Ссылка = &ДокументСсылка | И НЕ Док.Номенклатура.Комплект | И Не Док.Номенклатура.Услуга | ОБЪЕДИНИТЬ ВСЕ | | ВЫБРАТЬ | Док.Ссылка, | Док.Номенклатура, | " + ?(ЕстьКачество, "Док.Качество,", "") + " | " + ?(ЕстьХарактеристика, "Док.ХарактеристикаНоменклатуры,", "") + " | " + ?(ЕстьСерия, "Док.СерияНоменклатуры,", "") + " | " + ?(ЕстьКоэффициент, "Док.Коэффициент,", "") + " | " + ?(ЕстьДокументРезерва, "Док.ДокументРезерва,", "") + " | " + ?(ЕстьСкладВТабЧасти, "Док.Склад,", "") + " | Док.Количество | ИЗ | (ВЫБРАТЬ | ДокНаб.Ссылка, | ДокНаб.Номенклатура, |"; Если ЕстьКачество Тогда ТекстЗапросаРеквизитыДокумента = ТекстЗапросаРеквизитыДокумента + " | ВЫБОР | КОГДА ДокНаб.Качество = &ПустоеКачество ТОГДА ДокТов.Качество | ИНАЧЕ ДокНаб.Качество | КОНЕЦ КАК Качество, |"; КонецЕсли; ТекстЗапросаРеквизитыДокумента = ТекстЗапросаРеквизитыДокумента + " | " + ?(ЕстьХарактеристика, "ДокНаб.ХарактеристикаНоменклатуры,", "") + " | " + ?(ЕстьСерия, "ДокНаб.СерияНоменклатуры,", "") + " | " + ?(ЕстьКоэффициент, "ДокНаб.ЕдиницаИзмерения.Коэффициент КАК Коэффициент,", "") + " | " + ?(ЕстьДокументРезерва, "ДокТов.ДокументРезерва,", "") + " | " + ?(ЕстьСкладВТабЧасти, "ДокТов.Склад,", "") + " | ДокНаб.Количество * ДокТов.Количество КАК Количество | ИЗ | Документ." + ИмяДокумента + ".СоставНабора КАК ДокНаб | ЛЕВОЕ СОЕДИНЕНИЕ Документ." + ИмяТаблицы + " КАК ДокТов | ПО ДокТов.КлючСтроки = ДокНаб.КлючСтроки | И ДокТов.Ссылка = &ДокументСсылка | ГДЕ | ДокНаб.Ссылка = &ДокументСсылка | И НЕ ДокНаб.Номенклатура.Комплект | И Не ДокНаб.Номенклатура.Услуга | ) КАК Док | | ) КАК Док |"; Иначе ТекстЗапросаСписокНоменклатуры = " |ВЫБРАТЬ РАЗЛИЧНЫЕ | Номенклатура |ИЗ | Документ." + ИмяТаблицы +" |ГДЕ Ссылка = &ДокументСсылка | И НЕ Номенклатура.Комплект | И Не Номенклатура.Услуга |"; ТекстЗапросаРеквизитыДокумента = "( |ВЫБРАТЬ |Док.Номенклатура, "+ ?(ЕстьХарактеристика, "Док."+ТекстХарактеристикаНоменклатуры+", ","")+ ?(ЕстьСерия, "Док."+ТекстСерияНоменклатуры+", ","")+ ?(ЕстьКоэффициент, "Док.Коэффициент, ","")+ ?(ЕстьКачество, "Док.Качество, ","")+ ?(ЕстьДокументРезерва, "Док.ДокументРезерва, ","")+ ?(ЕстьСкладВТабЧасти, "Док.Склад,","") + " |Док.Количество |ИЗ Документ." + ИмяТаблицы + " КАК Док | ГДЕ | Док.Ссылка = &ДокументСсылка | И НЕ Док.Номенклатура.Комплект | И Не Док.Номенклатура.Услуга |) КАК Док |"; КонецЕсли; Запрос = Новый Запрос; ИмяРеквизитаСклад = "Склад"; Если ОбщегоНазначения.ЕстьРеквизитДокумента("СкладОрдер", МетаданныеДокумента) Тогда ИмяРеквизитаСклад = "СкладОрдер"; КонецЕсли; Если КонтролироватьОстатокПоСкладу Тогда Если ЕстьСкладВТабЧасти Тогда ЗапросСклады = новый Запрос; ЗапросСклады.Текст = "Выбрать различные Склад ИЗ Документ."+ИмяТаблицы+" |ГДЕ Ссылка=&ДокументСсылка"; ЗапросСклады.УстановитьПараметр("ДокументСсылка",СтруктураШапкиДокумента.Ссылка); СписокСкладов = ЗапросСклады.Выполнить().Выгрузить().ВыгрузитьКолонку("Склад"); Иначе СписокСкладов = новый СписокЗначений; СписокСкладов.Добавить(СтруктураШапкиДокумента[ИмяРеквизитаСклад]); КонецЕсли; Иначе СписокСкладов = новый СписокЗначений; КонецЕсли; // Установим параметры запроса Запрос.УстановитьПараметр("ДокументСсылка", СтруктураШапкиДокумента.Ссылка); Запрос.УстановитьПараметр("Организация", СтруктураШапкиДокумента.Организация); Запрос.УстановитьПараметр("Склад", СтруктураШапкиДокумента[ИмяРеквизитаСклад]); Запрос.УстановитьПараметр("СписокСкладов", СписокСкладов); Запрос.УстановитьПараметр("ПустаяСерия", Справочники.СерииНоменклатуры.ПустаяСсылка()); Запрос.УстановитьПараметр("ПустоеКачество", Справочники.Качество.ПустаяСсылка()); Запрос.УстановитьПараметр("ПустойКомиссионер", Справочники.Контрагенты.ПустаяСсылка()); Если СтруктураШапкиДокумента.Свойство("Комиссионер") Тогда Запрос.УстановитьПараметр("Комиссионер", СтруктураШапкиДокумента.Комиссионер); Иначе Запрос.УстановитьПараметр("Комиссионер", Справочники.Контрагенты.ПустаяСсылка()); КонецЕсли; Если ЕстьДокументПередачи Тогда Запрос.УстановитьПараметр("ДокументПередачи", СтруктураШапкиДокумента.ДокументПередачи); КонецЕсли; Запрос.Текст = " |ВЫБРАТЬ // Запрос, контролирующий остатки на складах | Док.Номенклатура.Представление КАК НоменклатураПредставление, | Док.Номенклатура.ЕдиницаХраненияОстатков.Представление КАК ЕдиницаХраненияОстатковПредставление," +?(ЕстьДокументРезерва, " |Док.ДокументРезерва КАК ДокументРезерва, ","") +?(ЕстьСкладВТабЧасти, " |Док.Склад КАК Склад,","") + ?(ЕстьХарактеристика, " | Док." + ТекстХарактеристикаНоменклатуры + " КАК ХарактеристикаНоменклатуры," ,"") + ?(ЕстьСерия, " | Док." + ТекстСерияНоменклатуры + " КАК СерияНоменклатуры," ,"") + " | &Комиссионер КАК Комиссионер," + ?(ЕстьКоэффициент, " | СУММА(Док.Количество * Док.Коэффициент /Док.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент) КАК ДокументКоличество,", " | СУММА(Док.Количество) КАК ДокументКоличество,") + " | ЕСТЬNULL(МАКСИМУМ(Остатки.КоличествоОстаток), 0) КАК ОстатокКоличество, | ЕСТЬNULL(МАКСИМУМ(ОстаткиКПередаче.КоличествоОстаток), 0) КАК ОстатокКПередаче, | 0 КАК ОстатокКПередачеПоДокументу |ИЗ | "+ ТекстЗапросаРеквизитыДокумента + " | |ЛЕВОЕ СОЕДИНЕНИЕ | РегистрНакопления.ТоварыОрганизаций.Остатки(,"+ ?(КонтролироватьОстатокПоСкладу , "Склад в (&СписокСкладов) И ","")+" | Номенклатура В (" + ТекстЗапросаСписокНоменклатуры + ") | И Организация = &Организация | И Комиссионер = &Комиссионер | ) КАК Остатки |ПО | Док.Номенклатура = Остатки.Номенклатура " + ?(ЕстьХарактеристика, " | И Док." + ТекстХарактеристикаНоменклатуры + "= Остатки.ХарактеристикаНоменклатуры" ,"") + ?(ЕстьСерия, " | И Док." + ТекстСерияНоменклатуры + " = Остатки.СерияНоменклатуры" ,"") + ?(КонтролироватьОстатокПоСкладу И ЕстьСкладВТабЧасти, " | И Док.Склад = Остатки.Склад" ,"") + ?(ЕстьКачество, " | И Док." + ТекстКачество + " = Остатки.Качество" ,"") + " |ЛЕВОЕ СОЕДИНЕНИЕ | РегистрНакопления.ТоварыКПередачеОрганизаций.Остатки(, | Номенклатура В (" + ТекстЗапросаСписокНоменклатуры + ") | И Организация = &Организация | И &Комиссионер = &ПустойКомиссионер" + ?(ЕстьДокументПередачи, " | И ДокументПередачи <> &ДокументПередачи", "") + " | ) КАК ОстаткиКПередаче |ПО | Док.Номенклатура = ОстаткиКПередаче.Номенклатура " + ?(ЕстьХарактеристика, " | И Док." + ТекстХарактеристикаНоменклатуры + " = ОстаткиКПередаче.ХарактеристикаНоменклатуры" ,"") + ?(ЕстьСерия, " | И Док." + ТекстСерияНоменклатуры + "= ОстаткиКПередаче.СерияНоменклатуры" ,"") + ?(ЕстьКачество, " | И Док." + ТекстКачество + " = ОстаткиКПередаче.Качество" ,"") + ?(ЕстьДокументРезерва, " | И Док.ДокументРезерва <> ОстаткиКПередаче.ДокументПередачи" ,"") + " | |СГРУППИРОВАТЬ ПО | | Док.Номенклатура " + ?(ЕстьХарактеристика, " | , Док." + ТекстХарактеристикаНоменклатуры ,"") + ?(ЕстьСерия, " | , Док." + ТекстСерияНоменклатуры ,"") + ?(ЕстьКачество, " | , Док." + ТекстКачество ,"") + ?(ЕстьДокументРезерва, ", Док.ДокументРезерва","")+ ?(ЕстьСкладВТабЧасти, ", Док.Склад","")+" | |ИМЕЮЩИЕ ЕСТЬNULL(МАКСИМУМ(Остатки.КоличествоОстаток), 0) - ЕСТЬNULL(МАКСИМУМ(ОстаткиКПередаче.КоличествоОстаток), 0) < " + ?(ЕстьКоэффициент, "СУММА(Док.Количество * Док.Коэффициент /Док.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент)", "СУММА(Док.Количество)") + " | |ДЛЯ ИЗМЕНЕНИЯ РегистрНакопления.ТоварыОрганизаций.Остатки // Блокирующие чтение таблицы остатков регистра для разрешения коллизий многопользовательской работы |"; Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл КоличествоКПередачеПоДокументу = 0;//?(Выборка.ОстатокКПередачеПоДокументу = NULL, 0, Выборка.ОстатокКПередачеПоДокументу); СтрокаСообщения = "Остатка по организации " + СтруктураШапкиДокумента.Организация + ?(КонтролироватьОстатокПоСкладу," по складу "+?(ЕстьСкладВТабЧасти,Выборка.Склад,СтруктураШапкиДокумента[ИмяРеквизитаСклад]),"")+ " товара " + УправлениеЗапасами.ПредставлениеНоменклатуры(Выборка.НоменклатураПредставление, ?(ЕстьХарактеристика, Выборка.ХарактеристикаНоменклатуры, ""), ?(ЕстьСерия, Выборка.СерияНоменклатуры,"")) + ?(Не ЗначениеЗаполнено(Выборка.Комиссионер), "", " у комиссионера " + Выборка.Комиссионер) + " недостаточно."; Если НЕ УправлениеПользователями.РазрешеноПревышениеОстаткаТоваровОрганизации(СтруктураШапкиДокумента.Организация) Тогда УправлениеЗапасами.ОшибкаНетОстатка(СтрокаСообщения, Выборка.ОстатокКоличество, Выборка.ДокументКоличество, Выборка.ЕдиницаХраненияОстатковПредставление, Отказ, Заголовок); Иначе СтрокаСообщения = СтрокаСообщения + Символы.ПС + Символы.Таб + "Не хватает " + (Выборка.ДокументКоличество - (Выборка.ОстатокКоличество - (Выборка.ОстатокКПередаче - КоличествоКПередачеПоДокументу))) + " " + Выборка.ЕдиницаХраненияОстатковПредставление + "; Остаток " + Выборка.ОстатокКоличество + " " + Выборка.ЕдиницаХраненияОстатковПредставление + "; Требуется " + Выборка.ДокументКоличество + " " + Выборка.ЕдиницаХраненияОстатковПредставление; ОбщегоНазначения.СообщитьОбОшибке(СтрокаСообщения); КонецЕсли; Сообщить("Зарезервировано под выписанные документы: " + (Выборка.ОстатокКПередаче - КоличествоКПередачеПоДокументу)); КонецЦикла; КонецПроцедуры // КонтрольОстатков()