Index: branches/5.0.x/units/order_items/order_items_event_handler.php
===================================================================
--- branches/5.0.x/units/order_items/order_items_event_handler.php	(revision 13333)
+++ branches/5.0.x/units/order_items/order_items_event_handler.php	(revision 13334)
@@ -1,203 +1,233 @@
 <?php
 /**
 * @version	$Id$
 * @package	In-Commerce
 * @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
 * @license	Commercial License
 * This software is protected by copyright law and international treaties.
 * Unauthorized reproduction or unlicensed usage of the code of this program,
 * or any portion of it may result in severe civil and criminal penalties,
 * and will be prosecuted to the maximum extent possible under the law
 * See http://www.in-portal.org/commercial-license for copyright notices and details.
 */
 
 	defined('FULL_PATH') or die('restricted access!');
 
 	class OrderItemsEventHandler extends kDBEventHandler
 	{
 
 
 		/**
 		 * Allows to override standart permission mapping
 		 *
 		 */
 		function mapPermissions()
 		{
 			parent::mapPermissions();
-			$permissions = Array(
-									'OnSaveItems'	=>	Array('subitem' => 'add|edit'),
-							);
+
+			$permissions = Array (
+				'OnItemBuild' => Array ('subitem' => true),
+				'OnSaveItems' => Array ('subitem' => 'add|edit'),
+			);
+
 			$this->permMapping = array_merge($this->permMapping, $permissions);
 		}
 
 		/**
 		 * Processes item selection from popup item selector
 		 *
 		 * @param kEvent $event
 		 */
 		function OnProcessSelected(&$event)
 		{
 			$object =& $event->getObject( Array('skip_autoload' => true) );
 
 			$selected_ids = $this->Application->GetVar('selected_ids');
 			$product_ids = $selected_ids['p'];
 
 			if ($product_ids) {
 				//after adding Options Selection during adding products to order in admin, selector is in single mode
 				// = allows selecting one item at a time, but we leave this code just in case :)
 				$product_ids = explode(',', $product_ids);
 
 				$product_object =& $this->Application->recallObject('p.-item', null, array('skip_autoload' => true));
 
 				foreach ($product_ids as $product_id) {
 					$product_object->Load($product_id);
 
 					$sql = 'SELECT COUNT(*)
 							FROM ' . $this->Application->getUnitOption('po', 'TableName') . '
 							WHERE (Required = 1) AND (ProductId = ' . $product_id . ')';
 
 					if ( $this->Conn->GetOne($sql) ) {
 						$url_params = Array (
 							$event->Prefix . '_event' => 'OnNew',
 							'p_id' => $product_id,
 							'm_opener' => 's',
 						);
 
 						$this->Application->EventManager->openerStackPush('in-commerce/orders/order_product_edit', $url_params, 'm,ord,p');
 					}
 					else {
 						$orders_h =& $this->Application->recallObject('ord_EventHandler');
 						/* @var $orders_h OrdersEventHandler */
 
 						// 1 for PacakgeNum - temporary solution to overcome splitting into separate sub-orders
 						// of orders with items added through admin when approving them
 						$orders_h->AddItemToOrder($event, $product_id, null, 1);
 					}
 				}
 			}
 
 			$this->finalizePopup($event);
 		}
 
 		/**
 		 * Updates subtotal field in order record.
 		 * Only for "Items" tab in "Orders -> Order Edit" in Admin
 		 *
 		 * @param kEvent $event
 		 */
 		function OnUpdate(&$event)
 		{
 			parent::OnUpdate($event);
 			if ( ($this->Application->GetVar('t') != 'in-commerce/orders/orders_edit_items') ) {
 				return true;
 			}
 
 			$object =& $event->getObject();
 
 			$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
 			if (!$items_info) {
 				return ;
 			}
 
 			$sub_total = $this->getSubTotal($items_info);
 			$return_total = $this->getReturnTotal($items_info);
 
 			$table_info = $object->getLinkedInfo();
 			$main_object =& $this->Application->recallObject($table_info['ParentPrefix']);
 
 			if ($sub_total !== false) {
 				$main_object->SetDBField('SubTotal', $sub_total);
 			}
 
 			$main_object->SetDBField('ReturnTotal', $return_total);
 			$main_object->Update();
 		}
 
 		/**
 		 * Returns subtotal
 		 *
 		 * @param Array $items_info
 		 * @return float
 		 */
 		function getSubTotal($items_info)
 		{
 			$sub_total = 0;
 			foreach ($items_info as $id => $field_values) {
 				if (!array_key_exists('Price', $field_values)) {
 					return false;
 				}
 				$sub_total += $field_values['Quantity'] * $field_values['Price'];
 			}
 
 			return $sub_total;
 		}
 
 		/**
 		 * Returns total returned amount (refund)
 		 *
 		 * @param Array $items_info
 		 * @return float
 		 */
 		function getReturnTotal($items_info)
 		{
 			$return_total = 0;
 			foreach ($items_info as $id => $field_values) {
 				$return_total += $field_values['ReturnAmount'];
 			}
 
 			return $return_total;
 		}
 
 		/**
 		 * Saves selected items
 		 *
 		 * @param kEvent $event
 		 */
 		function OnSaveItems(&$event)
 		{
 			$event->CallSubEvent('OnUpdate');
 			$event->redirect = false;
 			$event->redirect_params = Array('opener'=>'s','pass'=>'all');
 		}
 
 		/**
 		 * Occures after an item has been cloned
 		 * Id of newly created item is passed as event' 'id' param
 		 *
 		 * @param kEvent $event
 		 */
 		function OnAfterClone(&$event)
 		{
 			$id = $event->getEventParam('id');
 			$table = $this->Application->getUnitOption($event->Prefix,'TableName');
 			$id_field = $this->Application->getUnitOption($event->Prefix,'IDField');
 			$sql = 'UPDATE '.$table.' SET QuantityReserved = NULL WHERE '.$id_field.' = '.$id;
 			$this->Conn->Query($sql);
 		}
 
 		function OnAfterItemLoad(&$event)
 		{
 			$object =& $event->getObject();
 			if( $item_info = $object->GetDBField('ItemData') )
 			{
 				$item_info = unserialize($item_info);
 				$object->SetDBField('DiscountType', getArrayValue($item_info, 'DiscountType'));
 				$object->SetDBField('DiscountId', getArrayValue($item_info, 'DiscountId'));
 			}
 		}
 
 		function SetCustomQuery(&$event)
 		{
 			parent::SetCustomQuery($event);
 
 			$object =& $event->getObject();
 
 			$package_num = $event->getEventParam('package_num');
 			if ($package_num) $object->addFilter('package_num', 'PackageNum = '.$package_num);
 
 			$type = $event->getEventParam('product_type');
 			if ($type) {
 				$object->addFilter('product_type', 'p.Type ='.$type);
 			}
 		}
+
+		/**
+		 * Checks, that currently loaded item is allowed for viewing (non permission-based)
+		 *
+		 * @param kEvent $event
+		 * @return bool
+		 */
+		function checkItemStatus(&$event)
+		{
+			if ($this->Application->IsAdmin()) {
+				return true;
+			}
+
+			$object =& $event->getObject();
+			if (!$object->isLoaded()) {
+				return true;
+			}
+
+			$order =& $this->Application->recallObject('ord');
+			/* @var $order kDBItem */
+
+			if ($order->isLoaded() && ($order->GetID() == $object->GetDBField('OrderId'))) {
+				return $order->GetDBField('PortalUserId') == $this->Application->RecallVar('user_id');
+			}
+
+			return false;
+		}
 	}
\ No newline at end of file