Каталог решений - Программный контроль границы последовательности партионного учета при проведении документов задним числом

Программный контроль границы последовательности партионного учета при проведении документов задним числом

Программный контроль границы последовательности партионного учета при проведении документов задним числом

В наличии

Редактирование и проведение документов задним числом несмотря на обилие корректировочных документов — суровая необходимость, особенно на больших предприятиях. Естественно, что если документ двигает границу последовательности партионного учета, граница устанавливается на этот документ, и для получения актуальных данных требуется восстанавливать последовательность, как правило в монопольном режиме. Вернем границу последовательности программно на её законное место, если движения по партиям документа, проведенного задним числом не изменились.

Категория:

Описание

Приступим…

1. Создадим подписку на событие ПередЗаписью. Подписка нужна для запоминания таблицы движений документа по партиям до проведения. Включим в подписку все документы, входящие в список последовательности партионного учета.

Последовательность ПартионныйУчет

2. Создадим в общем модуле процедуру для подписки. Для хранения таблицы движений документа используем встроенный реквизит документа ДополнительныеСвойства. Информация, помещаемая в эту структуру, хранится всё время «путешествия» объекта по подпискам. Запомним движения по партиям до проведения, а также границу последовательности, которая была на момент проведения документа.

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

Функция ВернутьТаблицуДвиженийПоПартиям(СсылкаНаОбъект) Экспорт
	Запрос = Новый Запрос("ВЫБРАТЬ РАЗРЕШЕННЫЕ
	                      |	ПартииТоваровНаСкладах.Номенклатура,
	                      |	ПартииТоваровНаСкладах.Склад,
	                      |	ПартииТоваровНаСкладах.ХарактеристикаНоменклатуры,
	                      |	ПартииТоваровНаСкладах.СерияНоменклатуры,
	                      |	ПартииТоваровНаСкладах.ДокументОприходования,
	                      |	ПартииТоваровНаСкладах.СтатусПартии,
	                      |	ПартииТоваровНаСкладах.Заказ,
	                      |	ПартииТоваровНаСкладах.Качество,
	                      |	ПартииТоваровНаСкладах.Количество,
	                      |	ПартииТоваровНаСкладах.Стоимость
	                      |ИЗ
	                      |	РегистрНакопления.ПартииТоваровНаСкладах КАК ПартииТоваровНаСкладах
	                      |ГДЕ
	                      |	ПартииТоваровНаСкладах.Регистратор = &Регистратор");
	Запрос.УстановитьПараметр("Регистратор", СсылкаНаОбъект);
	РезультатЗапроса = Запрос.Выполнить();
	Если РезультатЗапроса.Пустой() Тогда
		Возврат Новый ТаблицаЗначений;
	Иначе
		Возврат РезультатЗапроса.Выгрузить();
	КонецЕсли;
КонецФункции

Таблицу движений по партиям получили и запомнили. Теперь надо сравнить с тем, что получилось после проведения. Создаем еще одну подписку на событие ОбработкаПроведения, также включаем туда документы из последовательности партионного учета. Таблицу движения по партиям после проведения также поместим в ДополнительныеСвойства.

Процедура ОбработкаПроведенияДляКонтроляГП(Источник, Отказ, РежимПроведения) Экспорт
    ВыполнитьКонтрольГП(Источник);
КонецПроцедуры

Процедура ВыполнитьКонтрольГП(Источник) Экспорт
    Если Источник.Метаданные().Реквизиты.Найти("ОтражатьВУправленческомУчете") <> Неопределено Тогда
        Если НЕ Источник.ОтражатьВУправленческомУчете Тогда
            Возврат;
        КонецЕсли;
    КонецЕсли;
    Если НЕ Источник.ЭтоНовый() Тогда
        Если Источник.Движения.Найти("ПартииТоваровНаСкладах") <> Неопределено Тогда
            ПартииПослеПроведения = Источник.Движения.ПартииТоваровНаСкладах.Выгрузить();
            Если ПартииПослеПроведения.Количество() = 0 Тогда
                // для части документов партии появляются после записи объекта в базу
                ПартииПослеПроведения = ВернутьТаблицуДвиженийПоПартиям(Источник.Ссылка);
            КонецЕсли;
            Источник.ДополнительныеСвойства.Вставить("ПартииПослеПроведения", ПартииПослеПроведения);
            ОпределитьНеобходимостьВозвращенияГП(Источник);
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Ну и, наконец, анализ необходимости возвращения последовательности.

Функция ОпределитьНеобходимостьВозвращенияГП(Источник) Экспорт
    ДополнительныеСвойства = Источник.ДополнительныеСвойства;
    ГраницаПоследовательностиДокумента = Неопределено;
    ДополнительныеСвойства.Свойство("ГраницаПоследовательности", ГраницаПоследовательностиДокумента);
    Идентичность = УстановитьИдентичностьТаблицДвиженийПоПартиям(ДополнительныеСвойства);
    ГраницаПоследовательностиТекущая = Последовательности.ПартионныйУчет.ПолучитьГраницу();
    Если ГраницаПоследовательностиДокумента <> Неопределено Тогда
        Если Идентичность И ГраницаПоследовательностиТекущая.Дата < ГраницаПоследовательностиДокумента.Дата Тогда
            // если таблицы идентичны, но текущая граница сдвинулась назад - вернем обратно
            Последовательности.ПартионныйУчет.УстановитьГраницу(ГраницаПоследовательностиДокумента);
            ЗаписьЖурналаРегистрации("Контроль ГП", УровеньЖурналаРегистрации.Информация, Источник.Метаданные(), Источник.Ссылка, "Граница последовательности возвращена на " + Строка(ГраницаПоследовательностиДокумента.Дата) + ", документ: " + Строка(ГраницаПоследовательностиДокумента.Ссылка));
        КонецЕсли;
    КонецЕсли;
КонецФункции
 Функция УстановитьИдентичностьТаблицДвиженийПоПартиям(ДополнительныеСвойства) Экспорт
    Идентичность = Ложь;
    ПартииДоПроведения = Неопределено;
    ДополнительныеСвойства.Свойство("ПартииДоПроведения", ПартииДоПроведения);
    ПартииПослеПроведения = Неопределено;
    ДополнительныеСвойства.Свойство("ПартииПослеПроведения", ПартииПослеПроведения);
    Если СравнитьТаблицыЗначений(ПартииДоПроведения, ПартииПослеПроведения) Тогда
        Идентичность = Истина;
    Иначе
        Идентичность = Ложь;
    КонецЕсли;        
    Возврат Идентичность;
КонецФункции

Извлекли из ДополнительныеСвойства таблицы движений до и после, сравнили, определили необходимость возвращения последовательности и вернули при необходимости на место.

Механизм также полезен для ситуаций, когда пользователь открывает документ, проведенный задним числом, и вместо закрытия нажимает ОК. Граница улетает на «закрытый» таким образом документ.

Если еще углубляться в детали, в стандартной конфигурации граница последовательности сбрасывается программно кодом:

	Если мУдалятьДвижения Тогда
		ОбщегоНазначения.УдалитьДвиженияРегистратора(ЭтотОбъект, Отказ);
	КонецЕсли;

То есть при перепроведении независимо ни от чего движения документа очищаются и записываются заново. В более современных продвинутых конфигурациях вроде это уже не так, но на родной переписанной до почти неузнаваемости УТ 10.3 вопрос восстановления границы последовательности потребовал программного решения.

has been added to your cart:
Оформление заказа