<?php
/**
* @version	$Id: order_items_event_handler.php 13549 2010-05-11 21:03:39Z alex $
* @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 (
				'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;
		}
	}