| 
			
			 | 
		#1 | 
| 
			
			 MCTS 
		
			
	 | 
	
	
	
		
		
			
			
			Поведение equal() метода в классе RunOn Server v3.0 SP4
			 
			
			Дано: 
		
		
		
		
		
		
			Трёхуровневая Аксапта v3.0 SP4 Класс WMSOrderTransSplit - разбиение строк в методе run() есть проверка: X++: select firstonly forupdate WMSOrderTransCopy index hint OrderIdx where WMSOrderTransCopy.orderId == WMSOrderTrans.orderId && WMSOrderTransCopy.itemId == WMSOrderTrans.itemId && WMSOrderTransCopy.recId == WMSOrderTrans.recId; if (!WMSOrderTransCopy || !bufCmp(WMSOrderTransCopy, WMSOrderTrans)) throw error("@SYS18447"); !WMSOrderTransCopy - не удалил ли пользователь строку перед разбиением !bufCmp(WMSOrderTransCopy, WMSOrderTrans) - не изменил ли пользователь строку перед разбиением Так вот bufCmp(...) в случае RunOn Server работает некорректно, а именно возвращает false, когда строка не была изменена. Иными словами - строка пришедшая в класс, и строка взятая в качестве эталона, для метода equal() понимаются как разные. Изменяя же свойство класса RunOn на Called from, метод equal() работает правильно. Как вариант, !bufCmp(WMSOrderTransCopy, WMSOrderTrans) можно попытаться заменить на WMSOrderTransCopy.xml() != WMSOrderTrans.xml() ![]() Причём такое поведение equal() характерно не только для таблицы WMSOrderTrans, но и для для других таблиц. 
				__________________ 
		
		
		
		
	![]() В глухомани, в лесу Несмотря на красу Дни проводит Лиса Патрикевна. Я никак не пойму Отчего, почему Не пускают куму На деревню  | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: Logger (1). | |
| 
			
			 | 
		#2 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Исправлено в KR3. 
		
		
		
		
		
		
		
	Возможно работает и в более ранних версиях (в SP3 не работает) Мне кажется не стоит менять место выполнения всего класса на клиент - лучше вынести кусок кода в статический метод с модификатором Client  | 
| 
	
 | 
| 
			
			 | 
		#3 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			А еще лучше так 
		
		
		
		
		
		
		
	X++: client // Для SP3 // в KR3 уже исправлено поведение xRecord.equal(), // так что можно будет закомментить // [url=http://axforum.info/forums/showthread.php?p=153124#post153124]Поведение equal() метода в классе RunOn Server v3.0 SP4[/url] // pkoz 15.11.2007 static boolean bufCmp(Common b1,Common b2) { ; return b1.equal(b2); }  | 
| 
	
 | 
| 
			
			 | 
		#4 | 
| 
			
			 MCTS 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Там ещё в том методе бок есть 
		
		
		
		
		
		
			Вспомнить не могу А может кто-нибудь текст этого метода run() опубликовать? 
				__________________ 
		
		
		
		
	![]() В глухомани, в лесу Несмотря на красу Дни проводит Лиса Патрикевна. Я никак не пойму Отчего, почему Не пускают куму На деревню  | 
| 
	
 | 
| 
			
			 | 
		#5 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 X++: public void run() { WMSOrderTrans WMSOrderTransCopy; setPrefix(WMSOrderTransSplit::description()); try { ttsbegin; if (!this.validate()) throw error("@SYS18447"); select firstonly forupdate WMSOrderTransCopy index hint OrderIdx where WMSOrderTransCopy.orderId == WMSOrderTrans.orderId && WMSOrderTransCopy.itemId == WMSOrderTrans.itemId && WMSOrderTransCopy.recId == WMSOrderTrans.recId; if (!WMSOrderTransCopy || !bufCmp(WMSOrderTransCopy, WMSOrderTrans)) throw error("@SYS18447"); WMSOrderTrans.split(splitQty); ttscommit; } catch (Exception::Deadlock) { retry; } }  | 
| 
	
 | 
| 
			
			 | 
		#6 | 
| 
			
			 MCTS 
		
			
	 | 
	
	
	
		
		
		
		 
			
			А можно ещё метод WMSOrderTrans.split()
		 
		
		
		
		
		
		
			
				__________________ 
		
		
		
		
	![]() В глухомани, в лесу Несмотря на красу Дни проводит Лиса Патрикевна. Я никак не пойму Отчего, почему Не пускают куму На деревню  | 
| 
	
 | 
| 
			
			 | 
		#7 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 X++: public server WMSOrderTrans split(InventQty splitQty) { WMSOrderTrans WMSOrderTrans; ; if ((splitQty <= 0) || (splitQty >= this.qty)) throw(error("@SYS25644")); ttsbegin; WMSOrderTrans.data(this); WMSOrderTrans.qty = splitQty; WMSOrderTrans.expectedExpeditionTime = this.expectedExpeditionTime * splitQty / this.qty; WMSOrderTrans.volume = this.volume * splitQty / this.qty; this.qty -= splitQty; this.expectedExpeditionTime -= WMSOrderTrans.expectedExpeditionTime; this.volume -= WMSOrderTrans.volume; this.doUpdate(); WMSOrderTrans.doInsert(); ttscommit; return WMSOrderTrans; }  | 
| 
	
 | 
| 
			
			 | 
		#8 | 
| 
			
			 MCTS 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Спасибо Logger за публикацию кода. 
		
		
		
		
		
		
			Итак, ошибка (а скорее это описка) следующая: в методе WMSOrderTransSplit.run() вместо WMSOrderTrans.split(splitQty); должно быть WMSOrderTransCopy.split(splitQty); Так вот эта описка себя вроде бы как и не проявляет, и я бы не обратил на это внимания, если бы не столкнулся с запуском этого класса в цикле(стояла передо мной такая задача). Так вот, тогда класс отрабатывал корректно только в первый вызов. Исследование показало, что надо разбивать экземпляр WMSOrderTransCopy, а не WMSOrderTrans. Что касается того, где выполняется класс. У класса WMSOrderTransSplit есть класс-"близнец" WMSPickingLineCancel. Их архитектура во многом схожа. У WMSPickingLineCancel свойство RunOn стоит в Called from. 
				__________________ 
		
		
		
		
	![]() В глухомани, в лесу Несмотря на красу Дни проводит Лиса Патрикевна. Я никак не пойму Отчего, почему Не пускают куму На деревню  | 
| 
	
 | 
| Теги | 
| ax3.0 | 
| 
	
	 | 
	
		
  |