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