Запрет проведения документов в неоперативном режиме УТ 10.3

Опубликовал Дмитрий Никс (aximo) в раздел Программирование - Практика программирования

Предлагаю Вам небольшое решение для запрета проведения документов РТУ в неоперативном / оперативном режимах УТ 10.3.

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

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

У меня получилась проверка из двух действий.

Предлагаю на обсуждение:

Первым делом, я открываю модуль документа "Реализация товаров и услуг" и пишу в нем вот такую функцию (потом, по желанию, ее можно вынести в отдельный общий модуль):

 

Функция ПоискОстатковПоСкладу(Номенклатура, ДатаДокумента, СкладДокумента)

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

КонецФункции

 

Далее, в том же модуле РТУ ищем процедуру "ОбработкаПроведения" и в самом конце ее перед "КонецПроцедуры" добавляем вот такой элементарный код (условие):

	Если Ссылка.Проведен Тогда
		
		ОтменаПроведения = 0;
		ДокРеал = Ссылка.ПолучитьОбъект();
		ТоварыДокумента = ДокРеал.Товары;
		
		Для Каждого Стр ИЗ ТоварыДокумента Цикл
					
				КоличествоНоменлатурыНаСкладе = ПоискОстатковПоСкладу(Стр.Номенклатура, ДокРеал.Дата, ДокРеал.Склад);
				
				СколькоНехватает = КоличествоНоменлатурыНаСкладе - Стр.Количество;
				
				Если СколькоНехватает < 0 Тогда
					ОтменаПроведения = 1;
					Сообщить(Строка(Стр.Номенклатура)+" не хватает "+Строка(СколькоНехватает*(-1)), СтатусСообщения.ОченьВажное);
				КонецЕсли;	
				
		КонецЦикла;
		
		Если ОтменаПроведения = 1 Тогда
		
			ОбработкаУдаленияПроведения(Отказ);
			ДокРеал.Записать(РежимЗаписиДокумента.ОтменаПроведения);
			Сообщить("Отмена проведения документа "+ДокРеал+ Символы.ПС);
			
		КонецЕсли;
		
	КонецЕсли;

 

Еще раз, данное решение работает, писалось мной под определенную задачу. Буду рад, если оно поможет кому. Также хочу услышать ваши мысли по доработке, возможным косяках, альтернативных решениях.

Всем спасибо!

См. также

Добавить вознаграждение
Комментарии
1. Игорь Дремов (Hitcher) 84 29.05.15 08:43 Сейчас в теме
Сходу видятся направления для улучшайзинга:

1. Запрос в цикле. Фу. Моветон. Все нужно делать в одном запросе
2. Номенклатура без характеристик. Разве в УТ 10.3 не ведется учет по характеристикам? И по сериям.
3. Разве в УТ 10.3 склад не может быть в табличной части?
2. Артем Целовальников (slazzy) 32 29.05.15 13:43 Сейчас в теме
Я не буду комментировать отвратительный по своей сути код с кучей ошибок, но что помешало просто добавить новую роль, в которой запрещено неоперативное проведение? Что помешало добавить одну строку в процедуру проведения Отказ = РежимПроведения = РежимПроведенияДокумента.Неоперативный;

Зачем городить этот огород? Зачем проверять остатки, если остатки проверяются по умолчанию? Зачем выполнять отмену проведения?
3. Дмитрий Никс (aximo) 664 29.05.15 15:44 Сейчас в теме
(2) огород городится для того, что добавление роли с запретом неоперативного проведения документа никак не поможет, в случае загрузки документов задним числом и их проведению, если отсутствуют остатки. Стандартная торговля списывает в минус склад - тут списывать в минус склад не получиться - будет запись документа.

Можешь написать более оптимизированный код - напиши здесь
4. Игорь Дремов (Hitcher) 84 30.05.15 10:29 Сейчас в теме
Соглашусь, что косяков много. Даже слишком.
Но сказать где сделано неправильно надо.
Пропустим, что не учитываются зарезервированные товары, Допустим их нет
или что просто нужно проверять остатки .

Рассмотрим как учебный пример. Не претендую на то, что все будет правильно, но вот один из путей :)

1. Проверку перенести в свою подписку "Обработка проведения". Облегчит жизнь при обновлениях
2. Не получать заново объект и тем более не работать с табличной частью "товары", поскольку
количество в табличной части нужно будет приводить к единицам хранения остатков.

Под рукой нет УТ, но поскольку механизм в УТ, УПП и КА вроде одинаковый, то
таблицу можно взять
из
Движения.ТоварыНаСкладах
или
ДополнительныеСвойства.СтруктураТабличныхЧастей.ТаблицаПоТоварам.

Там таблицы уже должны быть приведены в единицам хранения.

3. Проверить опытным путем записаны ли к этому моменту движения по остаткам на складах.

Если записаны, то просто сравнить таблицу левым соединением с остатками на складе
на момент времени Новый Граница(ДатаДокумента, ВидГраницы.Включая).

Естественно связав по всем измерениям РН "Товары на складах"

Если нет, то вычесть из остатков на складе
на момент времени Новый Граница(ДатаДокумента, ВидГраницы.Исключая)

количество из полученных таблиц.

Все это можно сделать в одном запросе.






5. Олег Шалимов (CaSH_2004) 341 30.05.15 21:11 Сейчас в теме
Ну какая статья такой же будет и коммент :) долго оформлять после всего прочитанного

Я прочел и чуть не упал со смеху, это ужас если люди так программируют и еще выкладывают "предлагаю Вам ..."!
Не нужно таких предложений.
Ошибки начинаются уже с самого названия темы: "Запрет проведения ... ", а дальше видим что никакой не запрет, а контроль с непонятной отменой проведения!!!
в 1,2,4 все верно сказано.
Почти в КАЖДОЙ!!! строке ошибки логического плана:
Если Ссылка.Проведен Тогда - зачем проверка то?
ОтменаПроведения = 0; - почему Числовое, а не Булево?
ДокРеал = Ссылка.ПолучитьОбъект(); - зачем получать объект?
Для Каждого Стр ИЗ ТоварыДокумента Цикл - почему без запроса?
КоличествоНоменлатурыНаСкладе = ПоискОстатковПоСкладу(Стр.Номенклатура, ДокРеал.Дата, ДокРеал.Склад); - это вообще УЖОС 8-( как можно крутить в цикле запрос и при этом выкладывать как рабочее решение? крутите себе на здоровье, только не учите этому никого иначе у вас клиентов заберут или с работы попрут
СколькоНехватает = КоличествоНоменлатурыНаСкладе - Стр.Количество; - зачем в 2 строки? когда переменная КоличествоНоменлатурыНаСкладе используется 1 раз?
ОбработкаУдаленияПроведения(Отказ); - это вообще не нужно если проверка делается до!!! проведения я уж не говорю что "ищем процедуру "ОбработкаПроведения" " вообще не нужно делать, проверки все делаются ПередЗаписью, иначе у вас 10 000 доков будут проводится не 1 минуту, а целый час а то и день.
ДокРеал.Записать(РежимЗаписиДокумента.ОтменаПроведения); - от этого бы я упал если бы не сидел на стуле
Сообщить("Отмена проведения документа "+ДокРеал+ Символы.ПС); - тут все становится ясно про уроень программирования - ПС в конце это для чего?

В общем ошибок нет только в написании операторов, в остальном просьба все НИКТО НЕ ДЕЛАЙТЕ НИЧЕГО ПОДОБНОГО
если не умеете программировать и логически мыслить лучше не показывайте этого, в идеале лучше вообще не занимайтесь этим, но идеал вряд ли достжим.

Вот из-за таких нас 1С-ков и считают недопрограммистами.
6. Sergey evillit (evillit) 01.06.15 11:13 Сейчас в теме
СколькоНехватает = КоличествоНоменлатурыНаСкладе - Стр.Количество;

Если СколькоНехватает < 0 Тогда


Нужно 1 шт, на складе 1 шт.
СколькоНехватает = 1 - 1 = 0 и далее по условию

И это помимо всего выше сказанного....
7. flu floody (flu) 03.06.15 09:04 Сейчас в теме
Соглашусь, что код ужасен.
Если очень хочется проверять остатки (Хотя зачем их проверять при неоперативном проведении? Уже сотни копий сломаны об этот вопрос), не проще включить этот самый контроль остатков в самой УТ? Там ведь так и написано "Если Неоперативно, то НеПроверяем"..
8. данила (danila_inf) 03.06.15 09:21 Сейчас в теме
Слишком много вылили на парня...))
Код действительно можно много где улучшить.. Но я так понимаю ты для этого и написал - чтобы тебе подсказали "где и как".
Пиши дальше.. учись и если получиться сделай вывод - лучше одно классное решение чем 10 сделанных поспешно или непроверенных.
В модуле объекта тебе доступен сам объект так что Ссылка.Проведен не надо делать.. это вызовет излишнее обращение к СУБД.
К объекту обратись через ЭтотОбъект.. не нужно его получить заново - это затратная операция.
9. Вадим Никонов (V.Nikonov) 113 04.06.15 09:29 Сейчас в теме
(3) aximo, Исправлении Реализации задним числом легко образуются МИНУСА по другим документам (позже по Периоду)...
Если правка задним числом нужна ля исправления ошибок учета...то в таком случае часто приходится править сразу несколько документов... И единственный корректный контроль возможен только за Оперативным остатком! Причем контроль надо производить о ВСМ измерениям Регистра! При обнаружении Оперативных Минусов - Предупреждать (а может и запрещать некоторым некоторые документы проводить) !
10. Василий Коровин (vasyak319) 122 04.06.15 09:44 Сейчас в теме
А я не верю, что автор серьёзно. По-моему, он просто тролль: "А напишу-ка я адову жесть и посмотрю, как остальные срач устроят".